6

I have swapped my number keys with their symbols, because the symbols occur much more frequently than numbers in many programming languages, like C or Haskell. You can see my key-swap function in my .vimrc file.

For the sake of examples, say 9 and ( are swapped.

There is one part I'm stumped in though. I currently use map, imap and cmap to cover most cases. However, some commands, like f aren't covered. For example, f followed by 9 doesn't do f(.

I know that lmap takes care of this, and that's true. However, using lmap (in conjunction with iminsert=1) creates another problem: macros stop working.

For example, take the following line:

Stuff 9 other ( things

And the following key strokes: q q f 9 x q

While recording this macro, effectively f(x is executed, which is the intended behavior. However, if I run this macro again (for example undo and rerun on same line, or just on another similar line), then what actually gets executed is f9x. Using "qp I can see that the macro has recorded f9x, which is fine, but it means that when playing the macro, the mapping is not taking into effect.

Note that I don't have this problem with / for example. As in, I can do (in a macro) / 9 to get /( with the macro recording /9 and when I replay the macro I correctly see /( being executed.

So, what's wrong here? Why do macros respect the mapping with / but not with f, and how can I get them to work correctly?


P.S. Possibly relevant information: I use *noremap not *map themselves.

6
  • 1
    You need omap to change operator pending mode.
    – Tumbler41
    Commented Jan 4, 2017 at 15:51
  • @Tumbler41 According to :h map-modes, :map is supposed to cover :omap.
    – Shahbaz
    Commented Jan 4, 2017 at 16:20
  • In :h f it states that it should use :lmap mappings, which would make sense why yours isn't working. However, I tried to use :lmap and it wasn't working for me.
    – Tumbler41
    Commented Jan 4, 2017 at 16:32
  • @Tumbler41, did you try :set iminsert=1? I learned that from here
    – Shahbaz
    Commented Jan 4, 2017 at 16:34
  • Ah! Good catch. Seems like you need to use both :lmap and iminsert=1.
    – Tumbler41
    Commented Jan 4, 2017 at 16:37

1 Answer 1

1

Though it's not elegant, you could define mappings for combinations of the f family and numbers/symbols. For example,

nnoremap f1 f!
nnoremap f! f1

To extend the function you used in your .vimrc, you could do something like this:

function Swap_keys(a, b, do)
  if a:do
    for prefix in ['', 'f', 't', 'F', 'T']
      exe 'noremap' prefix.a:a prefix.a:b
      exe 'noremap' prefix.a:b prefix.a:a
    endfor
    exe 'inoremap' a:a a:b
    exe 'inoremap' a:b a:a
    exe 'cnoremap' a:a a:b
    exe 'cnoremap' a:b a:a
  else
    for prefix in ['', 'f', 't', 'F', 'T']
      exe 'noremap' prefix.a:a prefix.a:a
      exe 'noremap' prefix.a:b prefix.a:b
    endfor
    exe 'inoremap' a:a a:a
    exe 'inoremap' a:b a:b
    exe 'cnoremap' a:a a:a
    exe 'cnoremap' a:b a:b
  endif
endfunction
1
  • Awesome! Works on every test case on the top of my head
    – Shahbaz
    Commented Mar 7, 2018 at 21:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.