在VIM中锁定标记

mb1*_*b14 2 vim

无论如何(内部或通过插件),以防止标记被覆盖?我的意思是一种方式,所以你不能设置一个标记,如果它已经被使用(我特别考虑全局标记).

我想在我的vimrc或会话中添加它们,但我更喜欢另一种方式.

更新

不要给我发一个脚本来做.我可以做我自己,我的问题是更多的,如果有在VIM一个隐藏的方式做到这一点,或者如果我不得不写一个脚本自己.答案显然不是.

非常感谢那些已经发给我脚本的人.我会用它们来写我自己的(因为发送的脚本不是我想要的)

ZyX*_*ZyX 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()
Run Code Online (Sandbox Code Playgroud)

此功能将阻止您重新映射标记.这就是它的工作原理:

  1. 我们定义一个字典,其中的键包含已设置的标记(实际上我们可以使用列表,但字典应该更快一些).
  2. 我们定义一个函数:
    1. 选择下一个符号.由于getchar可能返回字符串或字符编号,我们必须将其转换回字符串.
    2. 检查我们是否要设置标记(您可以使用名称标记a,但不能使用名称标记%).如果你试图设置标记%,它将被vim忽略,所以不需要保留无用的密钥.没必要阻止你使用m',m[而且m]因为我们无法阻止VIM自身重新定义它们.
    3. 检查此函数是否已设置有问题的标记,如果是,则抛出错误.
    4. 返回文本mC,C您的标记名称在哪里.
  3. 我们定义一个使用此函数返回值的映射{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()
Run Code Online (Sandbox Code Playgroud)