As a naive attempt, try this:
inoremap a;o año
inoremap e;e eñe
const s:LHS = ['a;o', 'e;e']
let s:MAPSAVE = []
for s:key in s:LHS
let s:MAPSAVE += [maparg(s:key, 'i', v:false, v:true)]
endfor
lockvar! s:MAPSAVE
unlet! s:key
let s:mappingsEnabled = v:true
inoremap <expr> <c-s> <sid>ToggleMappings()
fu s:ToggleMappings()
let i = 0
for key in s:LHS
if s:mappingsEnabled
exe 'silent! iunmap ' .. key
else
call mapset('i', v:false, s:MAPSAVE[i])
endif
let i += 1
endfor
let s:mappingsEnabled = !s:mappingsEnabled
return "\<Ignore>"
endfu
Make sure to include all the left-hand-sides of your mappings in the list constant s:LHS
:
const s:LHS = ['a;o', 'e;e']
^----------^
You'll need at least the patch 8.2.0807 to be able to invoke the mapset()
function which can restore a mapping based on the info given by maparg()
.
You might also need the patches 8.2.0852 and 8.2.0856 to be able to map something to C-s
:
For more info, see:
For something more reliable, try to create the directory ~/.vim/import
. Inside the latter, create the file map.vim
. Inside the latter, write this code:
vim9script
export def MapSave(argkeys: any, mode = '', wantlocal = false): list<dict<any>>
if type(argkeys) != v:t_list && type(argkeys) != v:t_string
return []
endif
var keys: list<string> = type(argkeys) == v:t_list ? argkeys : [argkeys]
var save: list<dict<any>> = []
for key in keys
for m in mode == '' ? [''] : split(mode, '\zs')
var maparg: dict<any> = Maparg(key, m, wantlocal)
save += [maparg]
endfor
endfor
return save
enddef
export def MapRestore(save: list<dict<any>>)
if empty(save)
return
endif
for maparg in save
if NotInRightBuffer(maparg) | continue | endif
if has_key(maparg, 'unmapped')
var cmd: string = GetMappingCmd(maparg)
exe 'sil! ' .. cmd .. ' ' .. (maparg.buffer ? ' <buffer> ' : '') .. maparg.lhs
else
for mode in split(maparg.mode, '\zs')
maparg->deepcopy()->extend({mode: mode})->Reinstall()
endfor
endif
endfor
enddef
def Maparg(name: string, mode: string, wantlocal: bool): dict<any>
var maparg: dict<any> = maparg(name, mode, false, true)
if empty(maparg) || wantlocal && !Islocal(maparg)
maparg = {
unmapped: true,
lhs: name,
mode: mode == '' ? ' ' : mode,
buffer: wantlocal,
}
elseif !wantlocal && Islocal(maparg)
exe mode .. 'unmap <buffer> ' .. name
var local_maparg: dict<any> = deepcopy(maparg)->extend({bufnr: bufnr('%')})
maparg = Maparg(name, mode, false)
MapRestore([local_maparg])
else
extend(maparg, {
lhs: name,
rhs: maparg(name, mode)->escape('|'),
})
endif
if Islocal(maparg)
extend(maparg, {bufnr: bufnr('%')})
endif
return maparg
enddef
def Reinstall(maparg: dict<any>)
var cmd: string = GetMappingCmd(maparg)
exe cmd
.. ' '
.. (maparg.buffer ? ' <buffer> ' : '')
.. (maparg.expr ? ' <expr> ' : '')
.. (maparg.nowait ? ' <nowait> ' : '')
.. (maparg.silent ? ' <silent> ' : '')
.. (maparg.script ? ' <script> ' : '')
.. maparg.lhs
.. ' '
.. maparg.rhs
enddef
def Islocal(maparg: dict<any>): bool
return get(maparg, 'buffer', false)
enddef
def NotInRightBuffer(maparg: dict<any>): bool
return Islocal(maparg) && bufnr('%') != get(maparg, 'bufnr', false)
enddef
def GetMappingCmd(maparg: dict<any>): string
var cmd: string
if has_key(maparg, 'unmapped')
if maparg.mode == '!'
cmd = 'unmap!'
else
cmd = maparg.mode .. 'unmap'
endif
else
if maparg.mode == '!'
cmd = maparg.noremap ? 'noremap!' : 'map!'
else
cmd = maparg.mode
cmd ..= maparg.noremap ? 'noremap' : 'map'
endif
endif
return cmd
enddef
This will provide 2 functions: MapSave()
and MapRestore()
. As their name suggests, they can save and restore a list of mappings. They can be imported from anywhere; a legacy Vim script, or a Vim9 script. In particular, they can be imported from your vimrc, regardless of how it's written:
import {MapSave, MapRestore} from 'map.vim'
If your vimrc is written in legacy Vim script, you can use these functions like this for a list of global mappings:
" save the mappings
let s:my_global_mappings = s:MapSave(['key1', 'key2', ...], 'i')
^
insert mode
" do something which removes or alters the mappings
" ...
" restore the mappings
call s:MapRestore(s:my_global_mappings)
And for a list of local mappings:
" save the mappings
let s:my_local_mappings = s:MapSave(['key1', 'key2', ...], 'n', v:true)
│ │
│ └ save local mappings
└ normal mode
" do something which removes or alters the mappings
" ...
" restore the mappings
call s:MapRestore(s:my_local_mappings)
If your vimrc is written in Vim9 script, and you want to save and restore global mappings:
# save the mappings
var my_global_mappings = MapSave(['key1', 'key2', ...], 'i')
^
insert mode
# do something which removes or alters the mappings
# ...
# restore the mappings
MapRestore(my_global_mappings)
For local mappings:
# save the mappings
var my_local_mappings = MapSave(['key1', 'key2', ...], 'n', true)
│ │
│ └ save local mappings
└ normal mode
# do something which removes or alters the mappings
# ...
# restore the mappings
MapRestore(my_local_mappings)
Assuming your vimrc is written in Vim script legacy, here's how you could use these functions for your particular issue :
import {MapSave, MapRestore} from 'map.vim'
inoremap a;o año
inoremap e;e eñe
const s:LHS = ['a;o', 'e;e']
const s:SAVE = s:MapSave(s:LHS, 'i')
let s:mappingsEnabled = v:true
inoremap <expr> <c-s> <sid>ToggleMappings()
fu s:ToggleMappings()
if s:mappingsEnabled
for key in s:LHS
exe 'silent! iunmap ' .. key
endfor
else
call s:MapRestore(s:SAVE)
endif
let s:mappingsEnabled = !s:mappingsEnabled
return "\<Ignore>"
endfu
And if your vimrc is written in Vim9 script:
import {MapSave, MapRestore} from 'map.vim'
inoremap a;o año
inoremap e;e eñe
const LHS = ['a;o', 'e;e']
const SAVE = MapSave(LHS, 'i')
var mappingsEnabled = true
inoremap <expr> <c-s> <sid>ToggleMappings()
def ToggleMappings(): string
if mappingsEnabled
for key in LHS
exe 'silent! iunmap ' .. key
endfor
else
MapRestore(SAVE)
endif
mappingsEnabled = !mappingsEnabled
return "\<Ignore>"
enddef
This will require a recent Vim version; at least 8.2.2015. It works on 8.2.2159.
For more info, see:
:help digraphs
,:help i_CTRL-K
). I could write about those, but if you'd rather have the toggle mapping I have an idea or two as well.