tomasyany
tomasyany

Reputation: 1242

Function already exists VIM

I have defined a function in my /.vim/ftplugin/python.vim file. The problem is that every time I open a .py file, I get the E122: Function MyFunction already exists, add ! to replace it.

I know that if I add ! then it will override the function (which is not a problem), but that means that it will replace it everytime, and it is a useless (and not very clean) supplementary action.

I guess that the problem come from the Python configuration file being sourced again and again every time I open a new .py file.

How can I tell VIM to source only once?

Upvotes: 1

Views: 2727

Answers (3)

SergioAraujo
SergioAraujo

Reputation: 11830

If you use ultisnips plugin would be great to have a snippet like:

snippet guard "add guard to functions" b
if !exists('*`!p
try:
    func_name = re.search('\S+\s+(\S+)\(', snip.v.text.splitlines()[0]).group(1)
except AttributeError:
    func_name = ''
snip.rv = func_name
`')
    ${VISUAL}
endif
${0:jump here <C-j>}
endsnippet

It allow us to select a function with vip, trigger the guard snippet and fix any function with no effort. In the post quoted you can see a complete explanation about the code above

It came from a discussion on vim @stackexchange. Actually I already knew about !exists thing, so I was trying to create a snippet to make my snippets smarter.

Upvotes: 0

FDinoff
FDinoff

Reputation: 31469

I would recommend putting the function in an autoload directory. (Read :help autoload it does a very good job explaining how this works). The quick version is below.

Edit the file ~/.vim/autoload/ftplugin/python.vim and add your function there. Everything after the autoload is part of the function signiture. (Instead of / use # between directories and leave off the .vim for the filename directory(s)#file#FunctionName)

function ftplugin#python#MyFunction()
    ...
endfunction

This function will automatically be loaded by vim the first time it is used.

Inside the filetype plugin you would just create the necessary mappings and commands.

command -buffer MyFunction call ftplugin#python#MyFunction()
nnoremap <buffer> <leader>m :call ftplugin#python#MyFunction()<CR>

and the function will automatically be loaded when it is called the first time. And other buffer that loads the ftplugin won't run into the redefinition problem.

Upvotes: 4

VanLaser
VanLaser

Reputation: 1164

One way: define a variable at the end of the file, check for its existence at the beginning (similar to a c include guard):

if exists('g:my_python')
  finish
endif

fun MyFunction
  ...
endfun

" ... other stuff

let g:my_python = 1

Another way (if all you have is this function): check directly for the existence of its definition:

if !exists('*MyFunction')
  fun MyFunction
    ...
  endfun
endif

Upvotes: 2

Related Questions