如何获取当前正在执行的vimscript的路径

yc0p9oo0  于 2022-11-11  发布在  其他
关注(0)|答案(4)|浏览(105)

在我的vim插件中,我有两个文件:

myplugin/plugin.vim
myplugin/plugin_helpers.py

我想从plugin.vim导入plugin_helpers(使用vim的python支持),所以我认为我首先需要把我的插件的目录放在python的sys.path上。
我如何(在vimscript中)得到当前正在执行的脚本的路径?在python中,这是__file__。在ruby中,这是__FILE__。我在google中找不到任何类似于vim的东西,这能做到吗?

**注意:**我不查找当前 * 编辑 * 的文件(“%:p”和朋友)。

voj3qocg

voj3qocg1#

" Relative path of script file:
let s:path = expand('<sfile>')

" Absolute path of script file:
let s:path = expand('<sfile>:p')

" Absolute path of script file with symbolic links resolved:
let s:path = resolve(expand('<sfile>:p'))

" Folder in which script resides: (not safe for symlinks)
let s:path = expand('<sfile>:p:h')

" If you're using a symlink to your script, but your resources are in
" the same directory as the actual script, you'll need to do this:
"   1: Get the absolute path of the script
"   2: Resolve all symbolic links
"   3: Get the folder of the resolved absolute file
let s:path = fnamemodify(resolve(expand('<sfile>:p')), ':h')

我经常使用最后一个,因为我~/.vimrc是一个指向git存储库中脚本的符号链接。

r9f1avp5

r9f1avp52#

找到了:

let s:current_file=expand("<sfile>")
avkwfej4

avkwfej43#

值得一提的是,上述解决方案只会在函数之外工作。
这将不会给予所需的结果:

function! MyFunction()
let s:current_file=expand('<sfile>:p:h')
echom s:current_file
endfunction

但这将:

let s:current_file=expand('<sfile>')
function! MyFunction()
echom s:current_file
endfunction

以下是OP最初问题的完整解决方案:

let s:path = expand('<sfile>:p:h')

function! MyPythonFunction()
import sys
import os
script_path = vim.eval('s:path')

lib_path = os.path.join(script_path, '.') 
sys.path.insert(0, lib_path)                                       

import vim
import plugin_helpers
plugin_helpers.do_some_cool_stuff_here()
vim.command("badd %(result)s" % {'result':plugin_helpers.get_result()})

EOF
endfunction
imzjd6km

imzjd6km4#

如果你真的想在一个函数中得到脚本路径(这也是我想做的),你仍然可以使用<sfile>的第二个语义,或者在expand()中使用它的等价物<stack>

<sfile>    ...
              When executing a legacy function, is replaced with the call
              stack, as with <stack>
              ...
                                                   :<stack> <stack>
   <stack>    is replaced with the call stack, using
              "function {function-name}[{lnum}]" for a function line
              and "script {file-name}[{lnum}]" for a script line, and
              ".." in between items.  E.g.:
              "function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
              If there is no call stack you get error E489 .

但是你可能不想在插件中使用它,因为你可以在插件中使用自动加载函数,使用relative#path#to#plugin#root#script符号。
我将此用于采购目的:

function! s:SourceLocal(script)
  let l:callstack = expand("<stack>")
  let l:list = split(l:callstack, '\.\.')
  " list[-1] is SourceLocal function itself
  " list[-2] is the calling script
  let l:script_name = matchstr(l:list[-2], '^\(script \)\=\zs.\+\ze\[\d\+\]$')
  let l:script_path = fnamemodify(l:script_name, ":p:h")
  " l:script_path is the path where the script calling this function resides
  execute printf("source %s/%s", l:script_path, a:script)
endfunction

command! -nargs=1 SourceLocal :call s:SourceLocal(<f-args>)

然后,您可以在任何脚本内SourceLocal来源化另一个相对于它的脚本。

相关问题