我正在构建一个自定义vimrc来改善我的工作流程,我真的很喜欢设置一个集中目录来保存所有备份,交换和撤消文件的想法,如下所示:
" === BACKUP SETTINGS ===
" turn backup ON
set backup
set backupdir=~/.vim/backup//
" === SWAP FILES ===
" turn swap files ON
set swapfile
set directory=~/.vim/swap//
" === UNDO FILES ===
" turn undofiles ON
set undofile
set undodir=~/.vim/undo//
双尾斜线应该导致文件名扩展,其中生成的备份/交换/撤消文件名将是完整路径,%
替换每/
,类似{{1 }}
一切都适用于交换和撤消文件,但备份拒绝工作,生成文件格式为%home%username%path%to%your%file.ext
而没有完整路径扩展,这意味着当我编辑两个具有相同名称的文件时,备份第一个丢失(由第二个覆盖)。
有没有人对这个问题有所了解?
答案 0 :(得分:11)
'backupdir'
选项似乎不支持将完整绝对路径转换为文件名(路径分隔符使用%
),例如'directory'
和'undodir'
做。 :help 'backupdir'
下至少没有提到任何内容。
由于这是不一致的,并且我看到了您的用例,您应该在vim_dev mailing list提交请求。实际上,(veeery long)补丁队列(:help todo.txt
)中已经存在这样的补丁:
7 The 'directory' option supports changing path separators to "%" to make
file names unique, also support this for 'backupdir'. (Mikolaj Machowski)
Patch by Christian Brabandt, 2010 Oct 21.
请在vim_dev mailing list上游说,优先筹集它!
答案 1 :(得分:6)
有些时候已经过去了,似乎这个bug不会很快修复。 @DragonRock提出的建议是一个很好的建议,但遗漏了一个关键点,即:生成的备份应该是文件当前版本的副本, BEFORE 覆盖。所以我使用了自动命令的基本思想,但是在将更改提交到磁盘之前,使用不同的事件BufWritePre
将文件的副本复制到备份目标。
这是最终解决方案,与我们对破损功能的期望完全相同(仅适用于Linux):
" === BACKUP SETTINGS ===
" turn backup OFF
" Normally we would want to have it turned on. See bug and workaround below.
" OBS: It's a known-bug that backupdir is not supporting
" the correct double slash filename expansion
" see: https://code.google.com/p/vim/issues/detail?id=179
set nobackup
" set a centralized backup directory
set backupdir=~/.vim/backup//
" This is the workaround for the backup filename expansion problem.
autocmd BufWritePre * :call SaveBackups()
function! SaveBackups()
if expand('%:p') =~ &backupskip | return | endif
" If this is a newly created file, don't try to create a backup
if !filereadable(@%) | return | endif
for l:backupdir in split(&backupdir, ',')
:call SaveBackup(l:backupdir)
endfor
endfunction
function! SaveBackup(backupdir)
let l:filename = expand('%:p')
if a:backupdir =~ '//$'
let l:backup = escape(substitute(l:filename, '/', '%', 'g') . &backupext, '%')
else
let l:backup = escape(expand('%') . &backupext, '%')
endif
let l:backup_path = a:backupdir . l:backup
:silent! execute '!cp ' . resolve(l:filename) . ' ' . l:backup_path
endfunction
请注意,为了清楚起见,自动命令被提取到专用功能。 set nobackup
也很重要,否则会生成重复的备份(一个名称正确,一个名称不正确)。
它会按预期跳过与backupskip
匹配的备份,支持多个备份目标并附加backupext
(文件扩展名,对搜索很有用)。
如果当前保存的缓冲区是全新的(或者换句话说,如果您直接使用vim创建新文件),它也会跳过。尝试创建一个空的备份文件没有意义,实际上,它会抛出一个错误,因为该文件仍然没有被复制。感谢Yahya的@ suggestion!
silent!
指令通过回显备份创建或失败来阻止备份操作干扰文件保存操作的正常流程(否则保存本身可能会失败)。
答案 2 :(得分:3)
我添加这个答案,因为我发现它真的很令人沮丧。
这可能是一种解决方法,直到Vim将路径转换功能添加到backupdir
。我所做的是将以下行添加到.vimrc
:
autocmd BufWritePost * :execute ':w! ' ."$HOME/.vim/backups/" . substitute(escape(substitute(expand('%:p'), "/", "%", "g"), "%"), ' ', '\\ ', 'g')
基本上,每次保存文件时,它都会在$HOME/.vim/backups
中保存副本。
答案 3 :(得分:2)
从Vim 8.1.0251开始,在路径末尾使用backupdir
和//
可以正常工作。
issue在2018年8月8日由提交b782ba475a3f8f2b0be99dda164ba4545347f60f(补丁8.1.0251:'backupdir'不支持使用完整路径)修复。
(对于neovim用户:问题也已经fixed)。
答案 4 :(得分:1)
除了VictorSchröder的答案之外,我建议使用这个自动命令:
autocmd BufWritePre * if filereadable(@%) | :call SaveBackups() | endif
除非这样,否则如果您直接使用vim打开新文件,它将无效。保存空备份没有意义......