【问题标题】:Renaming the current file in Vim在 Vim 中重命名当前文件
【发布时间】:2010-11-15 08:56:06
【问题描述】:

我应该如何在 Vim 中重命名当前文件?

例如:

  • 我正在编辑person.html_erb_spec.rb
  • 我想把它重命名为person.haml_spec.rb
  • 我想继续编辑person.haml_spec.rb

我将如何优雅地做到这一点?

【问题讨论】:

    标签: vim vi


    【解决方案1】:

    :h rename() 是迄今为止最简单、最干净的方法。 就叫吧 :call rename("oldname", "newnane")

    【讨论】:

      【解决方案2】:

      有一个little plugin 可以让你做到这一点。

      【讨论】:

      • :Rename 会将文件从其位置移动到 CWD,因此请确保先设置 CWD 或在新文件名前加上正确的子目录。
      • This updated version of Rename.vim 正确处理 CWD - 始终将文件保存在原始目录中。
      • @AaronMahan 我已经修复了 Rename2.vim(忽略更智能但更复杂的 DelvarWorld 版本)以允许路径中的空格并在此处分叉:github.com/aehlke/vim-rename3 随意提交拉取请求以获得更智能功能!
      • @Stabledog Microsoft,显然。 Program Files (x86)。任何时候需要使用此目录时都需要用引号括起来。这是呃,很多。
      • @JackHasaKeyboard:+10。 “Program Files (x86)”赢得了历史上“缺少符号链接的操作系统中最糟糕的目录名称”。 :)
      【解决方案3】:
      :!mv % %:h/new_name
      

      注册%包含当前文件的名称。'%:h'显示包含当前文件的目录'head',例如:%:hreturns /abc/def当你的文件完整路径是abc/def/my.txt时

      【讨论】:

        【解决方案4】:

        要在不使用插件的情况下重命名现有文件,您应该使用命令

        :Explore
        

        此命令允许您浏览.directory 中的文件,删除或重命名它们。你应该在资源管理器中导航到必要的文件而不是输入R 命令,这将允许你重命名文件名

        【讨论】:

          【解决方案5】:

          我正在使用 NERDTree 插件:

          :NERDTreeFind
          

          然后按m

          要重命名,您可以选择(m)ove the current node 并更改文件名。还有删除、复制、移动等选项...

          【讨论】:

          • 你知道吗,这是我这些天重命名东西的主要方式
          • 这个真的很好用。绝对推荐。
          • 喜欢这个主意。这将是我现在主要的更改文件名的方法。
          【解决方案6】:

          简短、安全、无插件:

          :sav new_name
          :!rm <C-R>#  // or !del <C-R># for windows
          

          control + R, # 将在按下 之前立即展开为 alternate-file(当前窗口中先前编辑的路径)输入。这使我们能够查看我们要删除的确切内容。 在这种情况下使用管道| 是不 安全的,因为如果sav 因任何原因失败,# 仍将指向另一个地方(或不指向任何地方)。这意味着!rm # 或delete(expand(#)) 可能会删除完全不同的文件! 因此,请仔细手工操作或使用好的脚本(这里的许多答案中都提到了它们)。

          教育

          ...或者尝试自己构建一个函数/命令/脚本。从简单的开始:

          command! -nargs=1 Rename saveas <args> | call delete(expand('#')) | bd #
          

          在 vimrc 重新加载后,只需输入 :Rename new_filename。 这个命令有什么问题?

          安全测试 1::Rename 没有参数是什么意思?

          是的,它会删除隐藏在“#”中的文件!

          解决方案:您可以使用例如。条件或try 这样的声明:

          command! -nargs=1 Rename try | saveas <args> | call delete(expand('#')) | bd # | endtry
          

          安全测试 1: :Rename(不带参数)会抛出错误:

          E471:需要参数

          安全测试 2: 如果名称与之前的名称相同怎么办?

          安全测试 3: 如果文件的位置与您的实际位置不同怎么办?

          自己解决。 为了可读性,你可以这样写:

          function! s:localscript_name(name):
            try
              execute 'saveas ' . a:name
              ...
            endtry
          endfunction
          command! -nargs=1 Rename call s:localscript_name(<f-args>)
          

          笔记

          • !rm # 比 !rm old_name 好 -> 你不需要记住旧名字

          • !rm &lt;C-R&gt;# 比 !rm # 手动操作时要好 -> 你会看到你实际删除的内容(安全原因)

          • !rm 通常不是很安全...mv 到垃圾站比较好

          • call delete(expand('#')) 优于 shell 命令(与操作系统无关),但键入时间较长且无法使用 control + R

          • try | code1 | code2 | tryend -> 当code1出错时,不要运行code2

          • :sav(或:saveas)等同于:f new_name | w - 请参阅file_f - 并保留撤消历史记录

          • expand('%:p') 提供您所在位置的完整路径 (%) 或备用文件的位置 (#)

          【讨论】:

            【解决方案7】:

            如果文件已保存:

            :!mv {file location} {new file location}
            :e {new file location}
            

            示例:

            :!mv src/test/scala/myFile.scala src/test/scala/myNewFile.scala
            :e src/test/scala/myNewFile.scala
            

            权限要求:

            :!sudo mv src/test/scala/myFile.scala src/test/scala/myNewFile.scala
            

            另存为:

            :!mv {file location} {save_as file location}
            :w
            :e {save_as file location} 
            


            适用于 Windows 未验证

            :!move {file location} {new file location}
            :e {new file location}
            

            【讨论】:

            • 你至少可以解释为什么你不赞成这个答案。
            • 我没有投反对票,但这不是最快的解决方案,尽管它是我的后备解决方案。
            【解决方案8】:

            你也可以用 netrw 来做

            explorer命令在打开文件所在目录打开netrw

            :E
            

            将光标移到要重命名的文件上:

            R
            

            输入新名称,按回车,按 y。

            【讨论】:

            • 太棒了!我什至不知道 netrw。
            【解决方案9】:

            :sav newfile | !rm #

            请注意,它不会从缓冲区列表中删除旧文件。如果这对您很重要,您可以改用以下内容:

            :sav newfile | bd# | !rm #

            【讨论】:

              【解决方案10】:

              另一种方法是只使用 netrw,它是 vim 的原生部分。

              :e path/to/whatever/folder/
              

              然后有删除、重命名等选项。

              这是一个键盘映射,用于打开 netrw 到您正在编辑的文件所在的文件夹:

              map <leader>e :e <C-R>=expand("%:p:h") . '/'<CR><CR>
              

              【讨论】:

                【解决方案11】:

                Tim Pope 有一个名为 vim-eunuch 的明显更大的插件,其中包括重命名功能以及其他一些好东西(删除、查找、全部保存、chmod、sudo 编辑……)。

                在 vim-eunuch 中重命名文件:

                :Move filename.ext

                与 rename.vim 相比:

                :rename[!] filename.ext

                节省了几次击键:)

                【讨论】:

                • 而且它确实还有一些其他非常有用的功能!
                【解决方案12】:

                Vim 确实有一个rename 函数,但不幸的是它没有保留历史记录。

                在不丢失历史记录的情况下重命名文件的最简单的与操作系统无关的方法是:

                :saveas new_file_name
                :call delete(expand('#:p'))
                

                expand('#:p') 返回旧文件的完整路径。

                如果您还想从缓冲区列表中删除旧文件,请使用:bd #。

                或者创建一个插件

                如果要使用快速命令重命名文件,请在 ~/.vim/plugin 下添加一个新文件,内容如下:

                function! s:rename_file(new_file_path)
                  execute 'saveas ' . a:new_file_path
                  call delete(expand('#:p'))
                  bd #
                endfunction
                
                command! -nargs=1 -complete=file Rename call <SID>rename_file(<f-args>)
                

                命令Rename 将帮助您快速重命名文件。

                【讨论】:

                • :call delete('#') 比较容易写。
                【解决方案13】:

                Gary Bernhardt’s .vimrc 中有一个函数可以处理这个问题。

                function! RenameFile()
                let old_name = expand('%')
                let new_name = input('New file name: ', expand('%'), 'file')
                if new_name != '' && new_name != old_name
                    exec ':saveas ' . new_name
                    exec ':silent !rm ' . old_name
                    redraw!
                endif
                endfunction
                map <leader>n :call RenameFile()<cr>
                

                【讨论】:

                • 你喜欢的都给我投反对票。至少我可以重命名文件。
                • 这是一个很好的答案,不需要额外的插件。
                【解决方案14】:

                这个怎么样(根据 Jake 的建议改进):

                :exe "!mv % newfilename" | e newfilename
                

                【讨论】:

                • 嗯,我应该澄清一下它昨天在 MacVim 上工作,但我被 sshed 到服务器并今天尝试它,第二个命令似乎没有被视为冒号命令......跨度>
                • 实际上现在它也不能在 MacVim 上运行。回到绘图板! :)
                • 应该是:exe "!mv % newfilename" | e newfilename
                • 谢谢杰克,这比我的解决方案好一点。已更新。
                【解决方案15】:

                如果你使用 git 并且已经有 tpope 的插件 fugitive.vim 那么简单:

                :Gmove newname
                

                这将:

                1. 重命名磁盘上的文件。
                2. 在 git repo 中重命名文件。
                3. 将文件重新加载到当前缓冲区中。
                4. 保留撤消历史记录。

                如果您的文件尚未添加到 git 存储库,请先添加它:

                :Gwrite
                

                【讨论】:

                • 眼泪夺眶而出。完美的答案!
                • 我牺牲了两只山羊来纪念这个答案!但我有一个小问题,因为你必须从工作树的根目录输入路径;在任何项目中,这通常会变得相当冗长。有解决办法吗?
                • 太好了!我一直在寻找逃犯可以做的新事情。
                • @xxor:如 Mesco 的回答中所述,您可以使用 Ctrl+R % 插入当前文件名,然后可以对其进行编辑。
                • 在这里合并几个 cmets::Gmove 需要新文件名的相对路径。一个很好的方法是输入:Gmove &lt;ctrl-r&gt;%,它会附加当前的路径/文件名。
                【解决方案16】:

                为此,我会推荐来自 tpope 的 eunuch 的 :Rename。

                它还包括许多其他方便的命令。

                Rename 命令目前在其中定义如下(检查 repo 是否有任何更新!):

                command! -bar -nargs=1 -bang -complete=file Rename :
                  \ let s:file = expand('%:p') |
                  \ setlocal modified |
                  \ keepalt saveas<bang> <args> |
                  \ if s:file !=# expand('%:p') |
                  \   call delete(s:file) |
                  \ endif |
                  \ unlet s:file
                

                【讨论】:

                  【解决方案17】:

                  这个小脚本并不完美(您必须按额外的回车键),但它可以完成工作。

                  function Rename()
                    let new_file_name = input('New filename: ')
                    let full_path_current_file = expand("%:p")
                    let new_full_path = expand("%:p:h")."/".new_file_name
                    bd    
                    execute "!mv ".full_path_current_file." ".new_full_path
                    execute "e ".new_full_path
                  endfunction                                                                                                                                                                                                                                 
                  
                  command! Rename :call Rename()
                  nmap RN :Rename<CR>
                  

                  【讨论】:

                    【解决方案18】:
                    • 在编辑时写入文件 - :w newname - 以创建副本。
                    • 开始编辑新副本 - :e#。
                    • (可选)删除旧副本 - :!rm oldname。

                    在 Windows 上,可选的第 3 步略有变化:

                    • (可选)删除旧的 Windows 副本 - :!del oldname。

                    【讨论】:

                    • 我一直使用这种方法,但是,缺点是你丢失了你的撤销树 - 所以你不能在 :e 之前撤销任何东西
                    • 不错。显然 Ctrl-6 与 :e# 的作用相同
                    • 恕我直言,更直接的方法是 1) 重命名当前缓冲区 :f newname 2) 保存它 :w 3) (可选)!rm oldname。这样做的好处是可以保留您的撤消历史记录。
                    • :saveas 在这方面更好,@rampion -- 并且按照@kynan 所写的方式行事。
                    • # 在:e# 中代表什么?
                    【解决方案19】:

                    你也可以使用 :f 后跟 :w

                    【讨论】:

                    • 这不会删除旧文件。
                    【解决方案20】:
                    sav person.haml_spec.rb | call delete(expand('#'))
                    

                    【讨论】:

                    • 不错!不知道call delete(expand('#'))
                    【解决方案21】:

                    该命令名为:saveas,但不幸的是它不会删除您的旧文件,您必须手动执行此操作。请参阅:help saveas 了解更多信息。

                    编辑:

                    大多数 vim 安装都有一个集成的文件浏览器,您可以将其用于此类操作。在命令模式下尝试:Explore(我实际上会将其映射到功能键,它非常很方便)。例如,您可以使用R 重命名文件或使用D 删除它们。但是在资源管理器中按&lt;F1&gt; 会让您获得更好的概览。

                    【讨论】:

                    • 与其他通常无法移动文件的编辑器相比,我认为这并不尴尬。相反,您必须转到您选择的文件管理器,重命名文件,然后返回到您的编辑器。如果幸运的话,如果没有收到文件名更改通知,则必须退出并重新启动编辑器。
                    • 您可能还喜欢 :Sex(split explore 的简写 :-))
                    • 另外,:e 将在当前窗格中打开探索。不如 :Sex 令人兴奋,但更高效 ;)。
                    • 对于勇敢的人来说,垂直的 :Sex 是 :Vex。
                    • @Josh :E 对我有用,:e 它对我不起作用。我使用 :e 在同一窗口中编辑其他文件。
                    【解决方案22】:

                    我不知道这是否是“最简单”的方法,但假设你已经保存了你的文件 (:w) 我会调用 shell (:sh) 并执行一个简单的 cp foo foo.bak 去返回编辑器使用 Ctrl-D/Exit。 vi 编辑器命令的有用列表on this link

                    【讨论】:

                    • 这将复制文件,而不是重命名它。
                    • 啊 - 我误读了“我想继续编辑 person.haml_spec.rb” 我的错!
                    • 我想你可以:! cp foo foo.new 然后 :e foo.new ?
                    猜你喜欢
                    • 2011-05-05
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-08-23
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多