16

We have a few modes in Vim. The most commonly used are: Normal (=Command), Insert, and Command-line, but also some sub-modes, like: Replace, Visual-line (V) or Visual-block (Ctrl+v).

Does Vim support the creation of some user-defined submode? How to make a simple mode that inherits from the existing one?

Let's consider "Insert-snake mode" which inherits from Insert mode and has some specific rules. One of these rules should be to replace space with _ character.

Mega Bang
  • 199
  • 11
Mesco
  • 466
  • 6
  • 12
  • 7
    No, but you're asking the wrong question. You've jumped to an idea for a solution to a problem and are asking if Vim supports that solution. You should instead be stating the real problem--replacing space with _ in certain situations--and asking how that might be solved with the capabilities that Vim does have. – garyjohn Jan 14 '17 at 15:47
  • 7
    No. I was interested in creating submodes in general. If someone wants solve a problem asking for it -- the way you propose would be right. But this question is about a submodule concept. If the concept is confused -- add answer and explain why. Some users may think in similar way, a they will be grateful for your explanation. – Mesco Jan 16 '17 at 09:49

2 Answers2

11

While I deeply agree with @garyjohn comment, the solution could interest some other users.

You can use the plugin vim-submode: it allows to create a mode that you enter by a keypress, where some keys execute some commands and that you can leave with another keypress.

For example for a while I've been using the following code to handle navigation, resize, moving and splitting windows. (Then I realized that <c-w> is pretty good and I don't need a submode)

Note that I'm not sure it is possible to have a mode inheriting the settings of another one.

" Create a submode to handle windows
" The submode is entered whith <Leader>k and exited with <Leader>
call submode#enter_with('WindowsMode', 'n', '', '<Leader>k', ':echo "windows mode"<CR>')
call submode#leave_with('WindowsMode', 'n', '', '<Leader>')
" Change of windows with hjkl
call submode#map('WindowsMode', 'n', '', 'j', '<C-w>j')
call submode#map('WindowsMode', 'n', '', 'k', '<C-w>k')
call submode#map('WindowsMode', 'n', '', 'h', '<C-w>h')
call submode#map('WindowsMode', 'n', '', 'l', '<C-w>l')
" Resize windows with <C-yuio> (interesting on azerty keyboards)
call submode#map('WindowsMode', 'n', '', 'u', '<C-w>-')
call submode#map('WindowsMode', 'n', '', 'i', '<C-w>+')
call submode#map('WindowsMode', 'n', '', 'y', '<C-w><')
call submode#map('WindowsMode', 'n', '', 'o', '<C-w>>')
" Move windows with <C-hjkl>
call submode#map('WindowsMode', 'n', '', '<C-j>', '<C-w>J')
call submode#map('WindowsMode', 'n', '', '<C-k>', '<C-w>K')
call submode#map('WindowsMode', 'n', '', '<C-h>', '<C-w>H')
call submode#map('WindowsMode', 'n', '', '<C-l>', '<C-w>L')
" close a window with c
call submode#map('WindowsMode', 'n', '', 'c', '<C-w>c')
" split windows with / and !
call submode#map('WindowsMode', 'n', '', '/', '<C-w>s')
call submode#map('WindowsMode', 'n', '', '!', '<C-w>v')

let g:submode_keep_leaving_key = 0
let g:submode_timeout = 0
statox
  • 49,782
  • 19
  • 148
  • 225
10

The best you can do is something like:

fun! ToggleW00tMode()
    if !exists('b:w00t')
        let b:w00t=1
    else
        unlet b:w00t
    endif

    return ""
endfun

inoremap <C-w> <C-r>=ToggleW00tMode()<Cr>

" Do something different depending on the value of b:w00t
inoremap <expr> o exists('b:w00t') ? '0' : 'o'

This will simple toggle the b:w00t variable to go into w00tmode, and remaps o to change the behaviour.

You could also add something to the statusline to indicate if w00tmode is enabled (but you can't change the INSERT text.


In my vimrc I do something similar to make typing "smart quotes" a bit easier.

Martin Tournoij
  • 62,054
  • 25
  • 192
  • 271