Vim - 覆盖插件范围功能

时间:2018-03-23 06:07:49

标签: vim

我在 Vim 中插件,我不喜欢其中的单个功能的行为。但是打开拉取请求并不是一个案例,而是更多的扩展请求 我知道只要新定义出现在前一个定义之后,就可以通过使用bang作为后缀来覆盖函数。但是,如果将此方法限定为插件中的脚本,我该怎么做呢? 我无法在_Vim_s帮助中找到提示,也无法通过请求搜索引擎。任何人都知道这个话题,至少他可以说它只是可能。

一个简短的例子:
插件/自动加载/ plugin.vim

  ...
  function! s:foo() {
       // behavior I would like to adjust
  }
  ...

的〜/ .vimrc

  function! foo() {
       // the "correct" behavior
  }


谢谢你的帮助!

2 个答案:

答案 0 :(得分:4)

实际上这是可能的。但正如@romainl所说,你最好向插件维护者推荐你的补丁或者要求变换点。

关于如何。

首先,您需要确定此自动加载插件的脚本编号。假设:scriptname表示它是210.为了自动执行此操作,我的库插件中有一个lh#askvim#scriptid()函数来完成工作 - 请参阅答案末尾的当前定义。

然后,要覆盖s:foo()函数,您需要为

提供新定义
function! <SNR>210_Foo()
   new definition
endfunction

(我刚用vim 8.0-1157测试过它)

IOW,我们可以覆盖脚本本地函数。但是,我还没有找到如何在不引用其s:字典的情况下覆盖脚本局部变量。

lh#askvim#scriptid()目前的定义如下

" Function: lh#askvim#execute(command) {{{3
" @since Version 4.0.0
if exists('*execute')
  function! lh#askvim#execute(command) abort
    return split(execute(a:command), "\n")
  endfunction
else
  function! lh#askvim#execute(command) abort
    return s:beware_running_through_client_server ? [] : split(lh#askvim#exe(a:command), "\n")
  endfunction
endif

" Function: lh#askvim#scriptnames() {{{3
function! lh#askvim#scriptnames() abort
  let scripts = lh#askvim#execute('scriptnames')
  let s:scripts = map(copy(scripts), 'split(v:val, "\\v:=\\s+")')
  call lh#list#map_on(s:scripts, 1, 'fnamemodify(v:val, ":p")')
  return s:scripts
endfunction

" Function: lh#askvim#scriptid(name) {{{3
function! lh#askvim#scriptid(name, ...) abort
  let last_change = get(a:, 1, 0)
  if last_change || !exists('s:scripts')
    call lh#askvim#scriptnames()
  endif
  let matches = filter(copy(s:scripts), 'v:val[1] =~ a:name')
  if len(matches) > 1
    throw "Too many scripts match `".a:name."`: ".string(matches)
  elseif empty(matches)
    if last_change
      throw "No script match `".a:name."`"
    else
      return lh#askvim#scriptid(a:name, 1)
    endif
  endif
  return matches[0][0]
endfunction

答案 1 :(得分:2)

这是不可能的。

s:foo()的范围限定为它所属的脚本(请参阅:help s:),因此无法从其他任何位置访问它。

  1. 叉子。
  2. 对您的前叉进行所需的更改。
  3. 使用叉子代替原件。
  4. 考虑提交拉取请求。