Thursday, September 20, 2012

Re: FileTypePre autocmd

exec "py3file" fnameescape(expand("<sfile>:p:h")."/context_menu.py")
function! context_menu#init()
augroup context_menu
autocmd BufEnter * :py3 handle_menu_add()
autocmd BufLeave * :py3 handle_menu_remove()
augroup END
endfunction
#!/usr/bin/python3


def vim_cmd_quote(s):
return s.replace(' ', r'\ ')


def build_vim_cmd(*args):
return ' '.join(map(vim_cmd_quote, args))


class VimMenu(object):
"A vim menu"

def __init__(self, name, rhs, mode='a', priority="500", silent=True):
self._name = name
self._rhs = rhs
self._mode = mode
self._priority = priority
self._silent = silent

modes = {'a': ['anoremenu', 'aunmenu'],
'n': ['nnoremenu', 'nunmenu'],
'i': ['inoremenu', 'iunmenu'],
'v': ['vnoremenu', 'vunmenu'],
'c': ['cnoremenu', 'cunmenu'],
'o': ['onoremenu', 'ounmenu'],
}

def add(self):
cmd = build_vim_cmd('silent',
VimMenu.modes[self._mode][0],
'<silent>' if self._silent else '',
self._priority,
self._name
) + ' ' + self._rhs
print(cmd)
vim.command(cmd)

def remove(self, force=False):
if force:
cmd = build_vim_cmd('silent!', VimMenu.modes[self._mode][1], self._name)
else:
cmd = build_vim_cmd('silent', VimMenu.modes[self._mode][1], self._name)
vim.command(cmd)


class VimPopUpMenu(VimMenu):
"Vim PopUp Menu"
def __init__(self, name, rhs, mode='a', priority="56", silent=False):
super(VimPopUpMenu, self).__init__(
'PopUp.'+name, rhs, mode, '1.'+priority, silent)


def get_current_filetype():
return vim.eval('&filetype')


def get_current_menu():
return FILETYPE_MENU.get(get_current_filetype(), [])


def handle_menu_remove():
if not vim.eval("has('gui_athena')"):
return
for menu in get_current_menu():
menu.remove(force=True)


def handle_menu_add():
if not vim.eval("has('gui_athena')"):
return
for menu in get_current_menu():
menu.add()


FILETYPE_MENU = {
'fortran': [VimMenu('Fortran.Run', ':!./%:r<CR>'),
VimMenu('Fortran.Compile This File', ':!gfortran % -o %:r<CR>'),
VimPopUpMenu('Align ::', ':Align ::<CR>', mode='v')
],
'c': [VimMenu('C.Run', ':!./%:r<CR>'),
VimPopUpMenu('comment', ':s/^/!/<CR>', mode='v')]
}

def register_filetype_menu(filetype, menu):
if isinstance(menu, VimMenu):
if filetype in FILETYPE_MENU:
FILETYPE_MENU[filetype].append(menu)
else:
FILETYPE_MENU[filetype] = [menu]
else:
for m in menu:
register_filetype_menu(filetype, m)
On Do 20 Sep 2012 13:51:24 CST, Christian Brabandt wrote:
> On Thu, September 20, 2012 06:14, Fermat 618 wrote:
>> Thanks, but actually what I want to do is not about a specific filetype,
>> but all types.
>>
>> I used BufEnter and BufLeave event autocmd to handle filetype specific
>> menus
>> add and remove, but that failed when I set a buffer to another filetype.
>> The
>> autotocmd should be executed in a context that the filetype is the old
>> one.
>>
>> I read the $VIMRUNTIME/ftplugin.vim where the b:undo_ftplugin take
>> effects, but
>> that is also trigger by the FileType event, where the old context is left.
>> Therefore event if I add my clean up code to b:undo_ftplugin, (which is
>> not
>> that esay), it will not work.
>
> I don't understand. Why can't you simply use something like this:
> :let b:undo_ftplugin .= '| amenu disable MyMenu'
>
> Why do you need the old filetype?
>
> regards,
> Christian
>

I wrote a small plugin in python to handle filetype specific menu auto
add and auto remove.

As long as I put

py3 register_filetype_menu('python', VimMenu('Python.Foo', ':call
bar()<CR>'))

in my .vimrc file, a menu 'Python' will and will only appear when my
current buffer is
has 'python' filetype, which means, e.g., when I leave a python buffer
and
enter a C buffer, Python menu whill disappear and a C menu will appear.

autocmd BufEnter * :py3 handle_menu_add()
autocmd BufLeave * :py3 handle_menu_remove()

The above autocmd are what I used. handle_menu_add() function will
detect the current filetype and get the menu informations of that
filetype which I stored with register_filetype_menu() function, then add
those menus.

There should be enough information of what filetype I'm leaving and what
I'm entering, to remove old menus and add new menus.

This fails when resetting the filetype of a buffer, because I don't know
how to get the previous filetype of the buffer.

best regards,
Fermat

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: