如何在vim中删除当前文件?

100

我如何在vim中从磁盘上删除当前打开的文件?最好也能关闭缓冲区。

我看到你可以使用NERDTree,但我不使用这个插件。

7个回答

118

使用外部工具,如rm(1)是可以的,但Vim也有自己的delete()函数来删除文件。这样做的好处是可移植性更强。

:call delete(expand('%'))

另一种表达方式是:call delete(@%),它使用了%(当前文件)寄存器(由@accolade提示)。

要完全清除当前缓冲区,包括磁盘上的文件和Vim缓冲区,添加:bdelete命令:

:call delete(expand('%')) | bdelete!

你可能希望根据自己的喜好进行映射。


8
谢谢!在 .vimrc 中,下面这行映射好像是可用的:nnoremap rm :call delete(expand('%')) \| bdelete!<CR>。你可能想在回答中加入这个内容。 - fotanus
15
这个映射不是最理想的。我们不希望破坏 r 命令!更好的做法是在你的映射前加上 <Leader>... 前缀。 - glts
4
:call delete(@%)|q! 是一个缩写命令(如果你不想把它映射成快捷键)。它的作用是删除当前缓冲区的所有内容,并退出 Vim 编辑器。这个缓冲区会一直保留在 :ls 列表中,可以通过 :b 命令重新打开,但是它将不会保留之前的文件内容,只会保留文件名和缓冲区选项。 - Aaron Thoma
2
@accolade,我喜欢你的技巧,但你需要使用:call delete(@%)|bd!并使用:ls!:b来恢复。 - Bart Louwers
2
数据危险警告!仅使用%(在vim术语中为“文件名”的文件路径,可能是相对的,例如仅文件名)而不是%:p(绝对文件路径),如果您忘记了:cd到那里,您会有一定的风险删除另一个目录中同名的文件。因此,我强烈建议您使用expand('%:p')而不是@%expand('%'),如果您无论如何都要映射它。 - Aaron Thoma
显示剩余5条评论

106

请查看使用Vim命令删除文件。其中的评论部分应该有你要找的内容:

基本上,Rm会删除当前文件;RM会一次性删除当前文件并退出缓冲区(不保存)。

或者,您可以直接发出一个shell命令来删除当前文件:

:!rm %

1
这是一件非常简单的事情,我几乎不敢相信我需要为此创建一个脚本。谢谢。 - fotanus
3
使用 !rm % 删除文件时,是否有方法可以避免 Vim 回到缓冲区时出现警告? - fotanus
1
带有一些特殊字符的文件名可能会导致该命令无法正常工作,例如如果文件名为20130711-contacts #285.vcf,其中包含空格,则会显示“rm: cannot remove `20130711-contacts': No such file or directory”。 - Saeed
4
@saeed144,如果文件名中有空格(或其他你不希望在命令行被解释的字符),你需要用引号将文件名(%)括起来: !rm“%” - David Cain
13
数据危险警告!使用仅带有“%”(在vim术语中为“文件名”)的文件路径(可能是相对路径,例如仅为文件名),而不是绝对文件路径“%:p”,如果你忘记了你已经使用了:cd 到另一个目录,就会产生删除另一个目录中同名文件的风险。因此,如果你打算进行映射,我强烈建议使用“%:p”而不是“%”。 - Aaron Thoma

26
有时即使是针对简单问题,插件也可以是一种有吸引力的解决方案。在这种情况下,我们很幸运,因为全能的 Tim Pope 创建了 eunuch.vim

用它自己的话来说,eunuch.vim 提供了:

Vim 对需要 UNIX shell 命令的增强。同时删除或重命名缓冲区和底层文件。将 findlocate 加载到快速修复列表中。等等。

太完美了。它具备我们所需的功能,如果我们使用UNIX系统还有一些额外的工具。

你要查找的命令是:

:Remove!

如果需要频繁使用,请重新映射它,例如::nnoremap <Leader>rm :Remove!<CR>


我一直在寻找不使用插件的方法,所以我会接受你的其他答案。这个插件看起来不错 :-) - fotanus
1
如果你需要使用vim的方式来进行mvmkdirfind等操作,那么这个插件非常方便。强烈推荐。 - Ehtesh Choudhury

6

我喜欢在vim中能够删除文件,但我也很担心会意外删除重要的工作,因为某种原因,这些工作还没有被版本控制。我发现将@glts和@accolade之前的信息与这个答案结合起来,可以学习如何使用confirm命令在退出vim之前提示。

将它们组合在一起,我在我的~/.vimrc中添加了一个函数,这个函数在删除文件和关闭缓冲区之前会弹出提示,并将它映射到一个键组合上:

nnoremap <Leader>d. :call DeleteFileAndCloseBuffer()

fun! DeleteFileAndCloseBuffer()
  let choice = confirm("Delete file and close buffer?", "&Do it!\n&Nonono", 1)
  if choice == 1 | call delete(expand('%:p')) | q! | endif
endfun

如果您比我少一个键入字符时的偏执,您可以在第一行附加<CR>
nnoremap <Leader>d. :call DeleteFileAndCloseBuffer()<CR>

只需按一次回车即可。


1
我强烈建议在脚本中使用expand('%:p')而不是@%。虽然我很高兴你采纳了我的提示,但在脚本中,简洁性的好处微乎其微。更重要的是:%:p将文件名扩展为完整的绝对路径(它可能已经是或者不是)。只使用,如果你忘记了你的:cd,你会有一点点风险删除另一个目录中同名的文件。 - Aaron Thoma
1
谢谢指出!我已经相应地更新了我的答案。 - joelostblom
我猜你可以在删除文件之前将其复制到某个目录中,然后每隔x周从那个目录中清理文件? - emilBeBri

0
你可以通过以下两个步骤完成:
  1. 另存为新文件

    :w 新文件名

  2. 删除旧文件

    ! rm 旧文件名


0

这可能是一个不受欢迎的观点,但您的文件树浏览器(Netrw/NerdTree)将是删除文件最简单、最安全的方式。即使 OP 没有使用 NerdTree,内置插件 Netrw 也能很好地工作。


0

在Lua中使用确认提示:

local function confirm_and_delete_buffer()
  local confirm = vim.fn.confirm("Delete buffer and file?", "&Yes\n&No", 2)

  if confirm == 1 then
    os.remove(vim.fn.expand "%")
    vim.api.nvim_buf_delete(0, { force = true })
  end
end

我将其映射到<leader>df,但你们可以按照自己的意愿进行操作。


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