强制Vim的mksession使用相对路径?

7
我正在尝试使用相对路径保存Vim会话中打开的文件。使用sessionoptions中的cur_dir,文件路径将相对于当前目录而言,但是会话文件包含cd /path/to/base/directory命令:
...
cd /path/to/base
badd +0 relpath1/file
badd +0 relpath2/file
...

如果在sessionoptions中不使用curdir,则cd命令将消失,但文件路径将是绝对路径:

badd +0 /path/to/base/relpath1/file
badd +0 /path/to/base/relpath2/file

有没有一种方法可以使用相对路径,而不是插件或编写脚本,只针对创建会话时的当前目录呢?这样会话文件将只有以下内容:
badd +0 relpath1/file
badd +0 relpath2/file

我的终极目标是拥有一个会话文件,可以随意复制,例如从SVN检出到另一个目录。

4个回答

6

据我所知,如果不设置包装函数,您无法这样做。

例如,可以使用以下内容设置包装函数:

function! MakeSession()
  let b:sessiondir = getcwd()
  let b:filename = b:sessiondir . '/session.vim'
  exe "mksession! " . b:filename
  exe "edit! " . b:filename
  exe "g:^cd :d"
  exe "x" 
endfunction

你能解释一下 g:^cd :d 吗?我还是无法让它正常工作。我发现这行代码很关键,但不知道它的作用。谢谢。 - John Chain
嗨@JohnChain,没问题。这是一个“ex”模式命令,它会在每一行开头匹配正则表达式“cd”的情况下全局执行行删除(d)。 - Zsolt Botykai
该函数不保存多个标签页,并且在存在多个垂直分割时,也会关闭活动标签页中的一个分割。 - Igor Stoppa

-1

我遇到了同样的问题,通过以下函数解决了它,这个函数受到了Zsolt Botykai的解决方案和John Chain的解决方案的启发。 此外,我定义了一个宏来执行这个函数,以减少按键次数。

function! MakeSession() 
    let cwd = getcwd()
    let filename = cwd . '/.vim'
    exe "mksession! " . filename
    exe "tabedit! " . filename
    exe "silent g:^cd :d"
    exe "silent g:^lcd :d"
    "exe "silent %s:\V" . cwd . "/::ge"
    " ^ Don’t work because getcwd() expand the ~ while mksession does not !
    exe "silent %s?\\v \\~=/.+/? ?g"
    " ^ backslash need to be protected
    exe "x"
endfunction

nnoremap <leader>mks :call MakeSession()<cr>

主要区别在于删除完整路径的正则表达式。 这是必需的,因为getcwd会扩展家目录的~,但mksession不会(在Mac OS上)。

此函数不保存多个标签页。 - Igor Stoppa
是的,我刚刚重新检查了一下!(Vim 8.2 和 sessionoptions = blank,buffers,curdir,folds,tabpages,winsize - lavalade

-1

我在Botykai的答案基础上进行了修改,添加了一行代码以全局删除绝对路径。

function! MakeSession()
  let b:sessiondir = getcwd()
  let b:filename = b:sessiondir . '/_vimsession'
  exe "mksession! " . b:filename
  exe "edit! " . b:filename
  " Delete the line start with 'cd ...'
  exe "g:^cd :d"
  " Vim complains about b:sessiondir being undefined. So I use getcwd() directly
  " exe "%s:" . b:sessiondir . "::g". Use ':' to avoid path escape
  exe "%s:" . getcwd() . "/::g"
  " Save with 'x'
  exe "x"
endfunction

如果有人能够改进上面的函数,将其缩小到仅以badd开头的行,那么这将更好。

此函数不保存多个标签页。 - Igor Stoppa

-1
当使用curdir代替sesdir时,解决方案会更简单(参见:help sessionoptions),因为绝对路径仅在会话文件中出现一次(cd path)。因此,MakeSession函数更小(我将会话文件称为.vim):
function! MakeSession()
    exe "mksession! .vim"
    exe "tabedit! .vim"
    exe "silent g:^cd :d"
    exe "x"
endfunction

nnoremap <leader>mks :call MakeSession()<cr>

选择会话文件的名称(执行::call MakeNamedSession('foo')):

function! MakeNamedSession(arg)
    let radical = a:arg
    exe "mksession! " . radical . ".vim"
    exe "tabedit! " . radical . ".vim"
    exe "silent g:^cd :d"
    exe "x"
endfunction

此函数无法保存多个标签页。 - Igor Stoppa
是的,它确实可以。我每天都在使用它(我刚刚重新检查了一下)!(Vim 8.2 和 sessionoptions = blank,buffers,curdir,folds,tabpages,winsize - lavalade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接