如何获取当前正在执行的vim脚本的路径

发布于 2024-10-17 02:45:04 字数 388 浏览 6 评论 0原文

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

myplugin/plugin.vim
myplugin/plugin_helpers.py

我想从plugin.vim导入plugin_helpers(使用vim python支持),所以我相信我首先需要将我的插件的目录放在python的sys.path上。

我如何(在 vimscript 中)获取当前正在执行的脚本的路径?在Python中,这是__file__。在 ruby​​ 中,它是 __FILE__。我通过谷歌搜索找不到类似 vim 的东西,可以吗?

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

In my vim plugin, I have two files:

myplugin/plugin.vim
myplugin/plugin_helpers.py

I would like to import plugin_helpers from plugin.vim (using the vim python support), so I believe I first need to put the directory of my plugin on python's sys.path.

How can I (in vimscript) get the path to the currently executing script? In python, this is __file__. In ruby, it's __FILE__. I couldn't find anything similar for vim by googling, can it be done?

Note: I am not looking for the currently edited file ("%:p" and friends).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉墨 2024-10-24 02:45:04
" 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 存储库中脚本的符号链接。

" 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')

I use that last one often because my ~/.vimrc is a symbolic link to a script in a git repository.

念﹏祤嫣 2024-10-24 02:45:04

找到了:

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

Found it:

let s:current_file=expand("<sfile>")
北城挽邺 2024-10-24 02:45:04

值得一提的是,上述解决方案只能在函数之外工作。

这不会给出预期的结果:

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

It is worth mentioning that the above solution will only work outside of a function.

This will not give the desired result:

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

But this will:

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

Here's a full solution to OP's original question:

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
白云悠悠 2024-10-24 02:45:04

如果您确实想获取函数内的脚本路径(这就是我想要的),您仍然可以使用 的第二个语义,或其等效的 < expand() 内的;stack>

 ; ...
              执行遗留函数时,被替换为调用
              堆栈,与  一样
              ...
                                                   :<堆栈> <堆栈>
   <堆栈>替换为调用堆栈,使用
              函数行的“function {function-name}[{lnum}]”
              和“script {file-name}[{lnum}]”作为脚本行,以及
              项目之间用“..”表示。例如:
              “函数{函数名1}[{lnum}]..{函数名2}[{lnum}]”
              如果没有调用堆栈,您会收到错误 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\+\]

然后您可以在任何脚本内 SourceLocal 来获取与其相关的另一个脚本。

) 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 来获取与其相关的另一个脚本。

If you really want to get the script path inside a function (which is what I'd like to), you can still use <sfile>'s second semantic, or its equivalent <stack> inside expand().

   <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 .

However you possibly don't want to use it in a plugin, as you can use autoload functions in plugin, using this relative#path#to#plugin#root#script notation.

I use this for sourcing purpose:

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\+\]

Then you can SourceLocal inside any script to source another script relative to it.

) 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>)

Then you can SourceLocal inside any script to source another script relative to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文