On Do 20 Sep 2012 16:18:57 CST, Christian Brabandt wrote:
On Thu, September 20, 2012 09:30, Fermat618 wrote:
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.
Programmatically, you can get the previous filetype, by recording each
filetype (e.g. this should work to always see the previous filetype):
let g:filetype_stack = []
au FileType * echo get(g:filetype_stack, -1, '') |
\ call add(g:filetype_stack, expand("<amatch>"))
and then in your plugin check g:filetype_stack[-1] or -2 (depending on
whether your Filetype autocommand is called before or after the above
filetype autocommand).
BTW: I would not mix different filetype settings in one single plugin,
but put each filetype specific plugin below a separate
~/.vim/ftplugin/<filetype>.vim (where <filetype> stands for your
actual filetype, as you probably guessed) see also :h filetype-plugin
Here is what I do, in my csv filetype plugin:
https://github.com/chrisbra/csv.vim/blob/master/ftplugin/csv.vim#L247
regards,
Christian
Thanks. These code work fine.
augroup context_menu
autocmd BufEnter * :py3 handle_menu_add()
autocmd BufLeave * :py3 handle_menu_remove()
autocmd FileType * call <SID>recodeFiletype()
function! s:recodeFiletype()
if !exists('b:context_menu_current_filetype')
let b:context_menu_current_filetype = &filetype
else
let b:context_menu_privious_filetype =
b:context_menu_current_filetype
let b:context_menu_current_filetype = &filetype
endif
endfunction
autocmd FileType * :py3 handle_filetype_change()
augroup END
I am just to build a mechanism that is absent from vim currently. Not to
mixture different filetype settings together. Now one command is enough
to add a context menu, and I will not care about those details when I
want to add context menu for new filetypes.
In fact, I put the
:py3 register_filetype_menu('python', VimMenu('Python.Run', xxx ))
in ftplugin/python.vim other than in my ~/.vimrc
Attachments are the code I finally get. Put those files in
~/.vim/autoload and add
call context_menu#init()
in ~/.vimrc. Then use
:py3 register_filetype_menu(filetype, VimMenu(menu, mapping))
to add a context menu for a filetype. (python3 support is required)
Hope that will help.
--
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
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()
autocmd FileType * call <SID>recodeFiletype()
function! s:recodeFiletype()
if !exists('b:context_menu_current_filetype')
let b:context_menu_current_filetype = &filetype
else
let b:context_menu_privious_filetype =
b:context_menu_current_filetype
let b:context_menu_current_filetype = &filetype
endif
endfunction
autocmd FileType * :py3 handle_filetype_change()
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_menu(filetype):
return FILETYPE_MENU.get(filetype, [])
def handle_menu_remove(filetype=None):
if filetype is None:
filetype = get_current_filetype()
for menu in get_menu(filetype):
menu.remove(force=True)
def handle_menu_add(filetype=None):
if filetype is None:
filetype = get_current_filetype()
for menu in get_menu(filetype):
menu.add()
def handle_filetype_change():
try:
from vim3.core import vimcall
except ImportError:
def vimcall(x, y):
return vim.eval('%s("%s")' % (x, y))
if vimcall('exists', 'b:context_menu_privious_filetype') == '1':
handle_menu_remove(vim.eval('b:context_menu_privious_filetype'))
if vimcall('exists', 'b:context_menu_current_filetype') == '1':
handle_menu_add(vim.eval('b:context_menu_current_filetype'))
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)