You may remap the m
with custom function:
let s:marks={}
function s:SetMark()
let m=getchar()
if type(m)==type(0)
let m=nr2char(m)
endif
if m=~#'^[a-zA-Z]$'
if has_key(s:marks, m)
throw "Mark ".m."is arleady set"
endif
let s:marks[m]=1
endif
return "m".m
endfunction
nnoremap <expr> m <SID>SetMark()
This function will prevent you from remapping mark. That is how it works:
- We define a dictionary, which keys contain already set marks (actually we could use a list, but dictionary should be a bit faster).
- We define a function that:
- Pick next symbol. As
getchar
may return either a string or a character number, we must convert it back to string.
- Checks whether we are going to set a mark (you can have mark with name
a
, but not with name %
). If you try to set mark %
, it would be ignored by vim, so no need to keep useless keys. And no need to prevent you from using m'
, m[
and m]
since we cannot prevent redefining them by vim itself.
- Checks whether mark in question was already set by this function, throws a error if it was.
- Returns text
mC
, where C
is your mark name.
- We define a mapping that uses this function returned value as
{rhs}
.
Note that this will not prevent somebody from redefining this mark by normal!
(but not normal
without a bang) command, nnoremap
(but not nmap
) mapping or something similar.
UPDATE: Modified version of s:SetMark:
function s:SetMark()
let m=getchar()
if type(m)==type(0)
let m=nr2char(m)
endif
if m=~#'^[A-Z]$'
let pos=getpos("'".m)
if pos[1]
echohl Error
echon "Mark ".m." is arleady set. Overwrite?"
echohl None
let c=getchar()
if type(c)==type(0)
let c=nr2char(c)
endif
echo
if c!=?'y'
return "<C-l>"
endif
endif
endif
return "m".m
endfunction
nnoremap <special><expr> m <SID>SetMark()