无论如何(内部或通过插件)是否可以防止标记被覆盖? 我的意思是一种方式,所以如果它已经被使用你就不能设置标记(我特别考虑全局标记)。
我正在考虑在我的vimrc或会话中添加它们,但我更愿意采用其他方式。
请勿向我发送脚本来执行此操作。我可以自己做,如果VIM中有隐藏的方法可以做到这一点,或者我自己必须编写脚本,那么我的问题就更多了。答案显然不是。
非常感谢那些已经发给我脚本的人。我将使用它们来编写我自己的(因为发送的脚本不是我想要的)
答案 0 :(得分:5)
您可以使用自定义功能重新映射m
:
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()
此功能将阻止您重新映射标记。这就是它的工作原理:
getchar
可能返回字符串或字符编号,因此我们必须将其转换回字符串。a
的标记,但不能使用名称%
标记)。如果你试图设置标记%
,它将被vim忽略,所以不需要保留无用的密钥。并且无需阻止您使用m'
,m[
和m]
,因为我们无法阻止您通过vim本身重新定义它们。mC
,其中C
是您的商标名称。{rhs}
的映射。请注意,这不会阻止某人通过normal!
(但不是normal
没有爆炸)命令重新定义此标记,nnoremap
(但不是nmap
)映射或类似的东西。
更新: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()
答案 1 :(得分:3)
您可以在运行特定命令时阻止更改标记。请参阅:lockmarks。
没有办法阻止它们被覆盖,但您可以使用要求使用标记的功能,通知您是否已使用该标记,并提示输入其他标记。
fun! SetMark()
let mark = ''
while mark == ''
call inputsave()
let mark = input('Mark to set (Enter to cancel)? ')
call inputrestore()
if mark == ''
return
endif
if mark !~# '^[A-Z]$'
echohl Error
echo "Invalid mark name. Must be a capital letter."
echohl None
let mark = ''
continue
endif
let pos = getpos("'" . mark)
if pos[1] != 0 " Used mark
let fname = fnamemodify(bufname(pos[0]), ':~:.')
call inputsave()
let yn = input('Mark already set for ' . fname . '. Overwrite? (y/n) ')
call inputrestore()
if yn !~? '^y'
let mark = ''
endif
endif
endwhile
exe 'normal m' . mark
endfun
nnoremap <F2> :call SetMark()<CR>