Comment définir un popup / menu personnalisé dans vimrc

19

Attribuer chaque fonction utile à une touche fonctionne bien pour les outils fréquemment utilisés, mais il y a certaines opérations que j'utilise si rarement, que je préférerais les affecter à un menu contextuel défini dans mon vimrc.

J'ai vu des plugins comme CtrlP ouvrir une liste contextuelle, cela devrait donc être possible.

Ma question est donc:

Comment définir un menu contextuel personnalisé pouvant exécuter différentes commandes?


Remarque: cela devrait également fonctionner dans un terminal.

Quelque chose comme le plugin CtrlP ou dmenu sur X11 serait idéal, où vous pouvez affiner les options au fur et à mesure que vous tapez, mais un autre type de menu serait également utile.

ideasman42
la source

Réponses:

11

Faire cela hors de la boîte nécessiterait beaucoup de travail, mais je pense que vous pouvez faire quelque chose d'assez simple en utilisant le plugin Unite.vim . Il fournit une interface d'intégration pour créer des menus à partir de diverses sources. (En fait, certains ont même remplacé CtrlP par Unite .) Cet exemple dans la documentation Unite (ou jetez un œil à :help g:unite_source_menu_menus, une fois que vous avez installé Unite) explique comment créer un menu de base des commandes.

Suite à cette documentation, j'ai trouvé un exemple simple qui propose un menu de commandes. À des fins de démonstration, je l'ai configuré avec des commandes pour ouvrir NERDTree (à partir du plug-in NERDTree), montrant un blâme (à partir du plugin fugitive.vim) et saluant les TODO dans un projet (à l'aide du intégré :grep). J'ai défini un mappage pour ouvrir le menu avec <Leader>c.

# Initialize Unite's global list of menus
if !exists('g:unite_source_menu_menus')
    let g:unite_source_menu_menus = {}
endif

# Create an entry for our new menu of commands
let g:unite_source_menu_menus.my_commands = {
\    'description': 'My Commands'
\ }

# Define the function that maps our command labels to the commands they execute
function! g:unite_source_menu_menus.my_commands.map(key, value)
    return {
    \   'word': a:key,
    \   'kind': 'command',
    \   'action__command': a:value
    \ }
endfunction

# Define our list of [Label, Command] pairs
let g:unite_source_menu_menus.my_commands.command_candidates = [
\   ['Open/Close NERDTree', 'NERDTreeToggle'],
\   ['Git Blame', 'Gblame'],
\   ['Grep for TODOs', 'grep TODO']
\ ]

# Create a mapping to open our menu
nnoremap <Leader>c :<C-U>Unite menu:my_commands -start-insert -ignorecase<CR>

Vous pouvez copier ceci dans votre vimrc, et modifier la liste des commandes définies par le tableau g:unite_source_menu_menus.my_commands.command_candidates. Chaque élément du tableau est un tableau du formulaire [Label, Command].

Dans mon exemple, my_commandsétait un nom que j'ai choisi pour identifier mon menu. Vous pouvez utiliser n'importe quel nom que vous souhaitez.

J'espère que cela t'aides!

EDIT: Ajout -start-insertet -ignorecaseoptions à la cartographie pour faire démarrer le menu en mode rétrécissement (comme une recherche floue).

tommcdo
la source