3

Due to some issues with the Programmer Dvorak implementation on my operating system and the desire to make a couple of small tweaks to the layout, I'm trying to implement the remapping entirely in vim (I don't type enough punctuation in any other editor to make this a limitation). I added noremap, inoremap, and cnoremap commands to a Vimscript file, e.g.:

inoremap 1 &
inoremap ! %
inoremap 2 [
inoremap 3 {
inoremap 4 }
[...]

When I source this file I can type perfectly in insert mode, and normal mode commands work as expected as well. However, characterwise search with f, F, t, or T unfortunately doesn't respect these mappings, it uses my system keyboard layout. This is probably to be expected from the method I've used, but is there any way to get around this?

Edit to add: The same problem occurs in single-character replace with r.

1 Answer 1

3

From :help language-mapping:

                    *language-mapping*
":lmap" defines a mapping that applies to:
- Insert mode
- Command-line mode
- when entering a search pattern
- the argument of the commands that accept a text character, such as "r" and
  "f"
- for the input() line

It seems :lmap is a good way to define a mapping which would be used in insert mode and command-line mode, as well as affect the argument of the commands f and r.

You could use it like this:

lnoremap 1 &
lnoremap ! %
lnoremap 2 [
lnoremap 3 {
lnoremap 4 }

These mappings will be used only if the value of the option 'iminsert' is 1. By default its value is 0 or 2, and it's local to the current buffer. To toggle the value, you can hit <C-^> in insert mode.

To see if the :lmap mappings are on or off, you could add an indicator in your statusline such as:
set stl+=lmap:%{&imi==1?'on':'off'}

To enable the :lmap mappings by default without having to hit <C-^>, you could add set imi=1 in your vimrc. Or you could install an autocmd which would set its value depending on some circumstances. See here for an example where the :lmap mappings are enabled everywhere except in insert mode.

3
  • Works great for those, but then it doesn't work for specifying text objects? I guess the symbols in text objects are technically commands and not literal characters, but there's obviously supposed to be a resemblance. I think at this point I'd rather not remap all the commands in normal mode as well (even though I was thinking about that earlier), but maybe that will end up being the best option. Apr 10, 2016 at 15:20
  • omap works for, say d(, but not for da(. Apr 10, 2016 at 15:21
  • 1
    @SorenBjornstad Maybe you could define 3 different objects: (, i( and a(. I don't know which key you want to use for (, but let's say it's 5. Then, you could write: onoremap 5 (, onoremap a5 a( and onoremap i5 i(. If you don't want to repeat these 3 mappings for similar objects ((, {, [) you could write a for loop which would iterate over the items of a list containing the latter and define the 3 mappings for each. Note that to delete the text inside/around parentheses you can use b instead of (: dib or dab. Same thing with B for curly braces: diB or daB. Apr 10, 2016 at 15:47

Your Answer

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

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