我听说过很多关于Vim的事,包括优点和缺点。 (作为一名开发人员)使用Vim确实应该比使用其他任何编辑器都要快。 我用Vim来做一些基本的事情,我用Vim最多只能减少10倍的效率。

当你谈论速度时,只有两件事你应该关心(你可能不够关心,但你应该关心):

左右交替使用的 用手是最快的方法 键盘。 永远不要碰鼠标 第二种方法是尽可能快。 你要花很长时间才能移动你的手, 抓住鼠标,移动它,把它带来 回到键盘上(你经常这样做 看看键盘,确保你 将你的手正确地回到正确的位置)

下面的两个例子说明了为什么我使用Vim效率低得多。

复制/剪切和粘贴。我一直都这么做。在所有当代编辑器中,你用左手按Shift键,用右手移动光标来选择文本。然后按Ctrl+C复制,移动光标,按Ctrl+V粘贴。

Vim的情况很糟糕:

Yy复制一行(你几乎不需要整行!) [number xx]yy复制xx行到缓冲区。但你永远不知道你是否选择了你想要的。我经常要做[number xx]dd然后u来撤销!

另一个例子吗?搜索和替换。

在PSPad中:按Ctrl+f,然后输入你想要搜索的内容,然后按Enter。 在Vim: /中,然后输入你想要搜索的内容,然后如果有一些特殊字符,在每个特殊字符前放\,然后按Enter。

Vim的一切都是这样的:似乎我不知道如何正确处理它。

注:我已经读了Vim小抄:)

我的问题是:

与当代编辑器相比,您使用Vim的哪些方式使您的工作效率更高?


当前回答

视觉模式

As several other people have said, visual mode is the answer to your copy/cut & paste problem. Vim gives you 'v', 'V', and C-v. Lower case 'v' in vim is essentially the same as the shift key in notepad. The nice thing is that you don't have to hold it down. You can use any movement technique to navigate efficiently to the starting (or ending) point of your selection. Then hit 'v', and use efficient movement techniques again to navigate to the other end of your selection. Then 'd' or 'y' allows you to cut or copy that selection.

与Jim Dennis描述的vi中的剪切/复制/粘贴相比,vim的可视模式的优势在于,您不必获得完全正确的位置。有时,使用一个快速的移动来达到你想要去的地方的大致位置,然后用其他动作来完善它,比想出一个更复杂的单一移动命令更有效,它可以让你确切地到达你想要去的地方。

以这种方式广泛使用可视化模式的缺点是,它可能会成为您一直使用的拐杖,阻碍您学习新的vi(m)命令,而这些命令可能会让您更有效地做事。但是,如果您非常积极主动地学习vi(m)的新方面,那么这可能不会对您产生太大影响。

我还要再次强调,视觉线条和视觉块模式可以让你在相同的主题上产生非常强大的变化,尤其是视觉块模式。

关于键盘的有效使用

I also disagree with your assertion that alternating hands is the fastest way to use the keyboard. It has an element of truth in it. Speaking very generally, repeated use of the same thing is slow. This most significant example of this principle is that consecutive keystrokes typed with the same finger are very slow. Your assertion probably stems from the natural tendency to use the s/finger/hand/ transformation on this pattern. To some extent it's correct, but at the extremely high end of the efficiency spectrum it's incorrect.

随便问问钢琴家就知道了。问他们是用手交替演奏几个音符,还是用一只手连续的手指按顺序演奏更快。输入4个按键的最快方法不是双手交替,而是用同一只手的4个手指按升序或降序输入(称之为“运行”)。一旦你考虑过这种可能性,这应该是不言而喻的。

更困难的问题是为此进行优化。优化键盘上的绝对距离非常简单。Vim做到了这一点。在“运行”级别上进行优化要困难得多,但是vi(m)与它的模态编辑相比,任何非模态方法(嗯哼,emacs)都更有可能做到这一点。

在Emacs

为了避免emacs狂热者因为最后的插入式评论而完全忽视我的整篇文章,我觉得我必须描述一下emacs和vim宗教之间的根本区别。我从来没有在编辑大战中说过,我可能不会再这样做了,但我从来没有听过有人这样描述它们的区别,所以就这样吧。区别在于以下权衡:

Vim为您提供无与伦比的原始文本编辑效率 Emacs为您提供了无与伦比的自定义和编程编辑器的能力

盲目的vim狂热者会声称vim有脚本语言。但它是一种晦涩的、专为编辑器设计的语言。Emacs有Lisp!足够的说。如果您不理解最后两句话的重要性,或者希望学习足够多的函数式编程和Lisp知识来理解它们,那么您应该使用vim。

emacs狂热者会声称emacs有viper模式,因此它是vim的超集。但毒蛇模式不是标准模式。我的理解是大多数emacs用户都不使用viper模式。因为它不是默认的,所以大多数emacs用户可能并没有真正认识到模态范例的好处。

在我看来,这些差异是正交的。我相信vim和emacs的优点都是有效的。这意味着终极编辑器还不存在。emacs可能是最容易构建最终编辑器的平台。但是模式编辑在emacs思想中并不是根深蒂固的。emacs社区在未来可能会朝着这个方向发展,但这似乎不太可能。

因此,如果你想提高原始编辑效率,请使用vim。如果您需要编写脚本和编辑器编程的终极环境,请使用emacs。如果您希望两者兼得,并强调可编程性,请使用带有viper模式的emacs(或编写自己的模式)。如果你想两全其美,那你现在就不走运了。

其他回答

有大量的vim技巧,但到目前为止,我真正喜欢的是Ctrl+A,因为我碰巧在处理一些硬编码数组索引的st**d代码。

提高编辑速度的第三个标准是所需的击键次数。我得说这比你的其他两个更重要。在vim中,几乎所有的操作都比我熟悉的任何其他编辑器需要更少的按键。

You mention that you are having trouble with cut & paste, but it sounds like you need more experience with general motion commands in vim. yank 3 words: y3w yank from the cursor to the next semi-colon: yf; yank to the next occurrence of your most recent search: yn All of those are much faster than trying to navigate with a mouse while holding down a modifier key. Also, as seen in some of the examples in CMS's response, vim's motion commands are highly optimized for efficient navigation in C and C++ source code.

至于“如何使用vim使我更有效率?”,我希望答案是“高效”。

花30分钟做vim教程(在终端运行vimtutor而不是vim)。您将学习基本的动作和一些击键,这将使您使用vim至少与使用之前使用的文本编辑器一样高效。在那之后,好吧,再读一遍吉姆·丹尼斯的回答:)

在将以下内容映射为一个简单的组合键后,以下内容对我来说非常有用:

在浏览文件路径时跳转到文件中

gf

获取现有文件的完整路径名

:r!echo %:p

获取现有文件的目录

:r!echo %:p:h

运行代码:

:!ruby %:p

ruby的缩写:

ab if_do if end<esc>bi<cr><esc>xhxO
ab if_else if end<esc>bi<cr><esc>xhxO else<esc>bhxA<cr> <esc>k$O
ab meth def method<cr>end<esc>k<esc>:s/method/
ab klas class KlassName<cr>end<esc>k<esc>:s/KlassName/
ab mod module ModName<cr>end<esc>k<esc>:s/ModName/

运行当前程序:

   map ,rby :w!<cr>:!ruby %:p<cr>

检查当前程序的语法:

   map ,c :w!<cr>:!ruby -c %:p<cr>

运行当前规格程序的所有规格:

   map ,s :w!<cr>:!rspec %:p<cr>

把它打开:

   map ,i :w!<cr>:!irb<cr>

rspec缩写:

   ab shared_examples shared_examples_for "behavior here" do<cr>end
   ab shared_behavior describe "description here" do<cr>  before :each do<cr>end<cr>it_should_behave_like "behavior here"<cr><bs>end<cr>
   ab describe_do describe "description here" do<cr>end
   ab context_do describe "description here" do<cr>end
   ab it_do it "description here" do<cr>end
   ab before_each before :each do<cr>end<cr>

rails的缩写:

用户认证:

     ab userc <esc>:r $VIMRUNTIME/Templates/Ruby/c-users.rb<cr>
     ab userv <esc>:r $VIMRUNTIME/Templates/Ruby/v-users.erb<cr>
     ab userm <esc>:r $VIMRUNTIME/Templates/Ruby/m-users.rb<cr>

在firefox中打开可视化选择的url:

"function
   function open_url_in_firefox:(copy_text)
     let g:open_url_in_firefox="silent !open -a \"firefox\" \"".a:copy_text."\""
     exe g:open_url_in_firefox
   endfunction

"abbreviations
   map ,d :call open_url_in_firefox:(expand("%:p"))<cr>
   map go y:call open_url_in_firefox:(@0)<cr> 

Rspec:运行包含当前行的规范:

"function
   function run_single_rspec_test:(the_test)
     let g:rake_spec="!rspec ".a:the_test.":".line(".")
     exe g:rake_spec
   endfunction

"abbreviations
   map ,s :call run_single_rspec_test:(expand("%:p"))<cr>

Rspec-rails:包含当前行的运行规范:

"function
   function run_single_rails_rspec_test:(the_test)
     let g:rake_spec="!rake spec SPEC=\"".a:the_test.":".line(".")."\""
     exe g:rake_spec
   endfunction

"abbreviations
   map ,r :call run_single_rails_rspec_test:(expand("%:p"))<cr>

Rspec-rails:运行规范包含当前行调试:

"function
   function run_spec_containing_current_line_with_debugging:(the_test)
     let g:rake_spec="!rake spec SPEC=\"".a:the_test.":".line(".")." -d\""
     exe g:rake_spec
   endfunction

"abbreviations
   map ,p :call run_spec_containing_current_line_with_debugging:(expand("%:p")) <cr>

html

"abbreviations

  "ab htm <html><cr><tab><head><cr></head><cr><body><cr></body><cr><bs><bs></html>
   ab template_html <script type = 'text/template' id = 'templateIdHere'></script>
   ab script_i <script src=''></script>
   ab script_m <script><cr></script>
   ab Tpage <esc>:r ~/.vim/templates/pageContainer.html<cr>
   ab Ttable <esc>:r ~/.vim/templates/listTable.html<cr>

"function to render common html template

   function html:() 
     call feedkeys( "i", 't' )
     call feedkeys("<html>\<cr>  <head>\<cr></head>\<cr><body>\<cr> ", 't')
     call feedkeys( "\<esc>", 't' )
     call feedkeys( "i", 't' )
     call include_js:()
     call feedkeys("\<bs>\<bs></body>\<cr> \<esc>hxhxi</html>", 't')
   endfunction

javascript

"jasmine.js
  "abbreviations
   ab describe_js describe('description here', function(){<cr>});
   ab context_js context('context here', function(){<cr>});
   ab it_js it('expectation here', function(){<cr>});
   ab expect_js expect().toEqual();
   ab before_js beforeEach(function(){<cr>});
   ab after_js afterEach(function(){<cr>});

"function abbreviations

   ab fun1 function(){}<esc>i<cr><esc>ko
   ab fun2 x=function(){};<esc>hi<cr>
   ab fun3 var x=function(){<cr>};

"method for rendering inclusion of common js files

   function include_js:()
     let includes_0  = "  <link   type = 'text\/css' rel = 'stylesheet' href = '\/Users\/johnjimenez\/common\/stylesheets\/jasmine-1.1.0\/jasmine.css'\/>"
     let includes_1  = "  <link   type = 'text\/css' rel = 'stylesheet' href = '\/Users\/johnjimenez\/common\/stylesheets\/screen.css'\/>"
     let includes_2  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jquery-1.7.2\/jquery-1.7.2.js'><\/script>"
     let includes_3  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/underscore\/underscore.js'><\/script>"
     let includes_4  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/backbone-0.9.2\/backbone.js'><\/script>"
     let includes_5  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jasmine-1.1.0\/jasmine.js'><\/script>"
     let includes_6  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jasmine-1.1.0\/jasmine-html.js'><\/script>"
     let includes_7  = "<script>"
     let includes_8  = "  describe('default page', function(){ "
     let includes_9  = "it('should have an html tag', function(){ "
     let includes_10 = "  expect( $( 'head' ).html() ).not.toMatch(\/^[\\s\\t\\n]*$\/);"
     let includes_11  = "});"
     let includes_12 = "});"
     let includes_13 = "$(function(){"
     let includes_14 = "jasmine.getEnv().addReporter( new jasmine.TrivialReporter() );"
     let includes_15 = "jasmine.getEnv().execute();"
     let includes_16 = "});"
     let includes_17 = "\<bs>\<bs><\/script>"

     let j = 0

     while j < 18
       let entry = 'includes_' . j
       call feedkeys( {entry}, 't' )
       call feedkeys( "\<cr>", 't' )
       let j = j + 1
     endwhile

   endfunction

"jquery

  "abbreviations

     ab docr $(document).ready(function(){});
     ab jqfun $(<cr>function(){<cr>}<cr>);

gi

转到上次编辑的位置(如果你进行了一些搜索,然后想要返回编辑,这非常有用)

^P和^N

完成上一个(^P)或下一个(^N)文本。

^O和^I

转到前一个(^O -“O”为旧)位置或下一个(^I -“I”靠近“O”)位置。 当你执行搜索、编辑文件等时,你可以通过这些“跳转”向前和向后导航。