Share your Emacs and VIM tricks.


Caine

Hardcore Member
Joined
Jun 5, 2008
Messages
4,136
Location
Netherlands
A while ago I decided to install EVIL - the Extensible VI Layer package in Emacs. This package adds the modal editing features of VIM on top of the Emacs platform such that you can use the combination of both.

I am not a real VIM user myself, but I've heard from others that the majority of commonly used VIM functionality is available nowadays. Your mileage may vary, but often things work differently in only minor ways.

So, why make this switch? It does not make sense to me to not use the best tool available. I have come to believe that of these two editors, VIM is the better text-editor if we focus primarily on precision manipulation of text, whereas Emacs is by far the better platform of the two. As such, I started on the road to learn more VIM. I think it would be much more interesting to share the tips and tricks of both editors and learn from eachother instead of fighting a holy war about which one is best.

So, my first tip for Emacs & VIM users is to install Emacs and Evil. Fire up an emacs 24.x environment and open (C-x C-f) your ~/.emacs file. Add some repositories by typing the following

(require 'package)
(add-to-list 'package-archives
'("marmalade" .
"http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
(package-initialize)
Either reboot Emacs or execute these lines and type (this opens Emacs built-in package manager): M-x package-list-packagesSearch for evil (C-s) and type i followed by x. Now evil should be installed.

If you are an Emacs user instead of a VIM user you might want to purge VIMs insertion mode to make it behave as emacs in insertion mode. Add the following lines:

(evil-mode)
(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map
(read-kbd-macro evil-toggle-key) 'evil-emacs-state)
(define-key evil-insert-state-map
(kbd "ESC") 'evil-normal-state)
Now C-z will toggle Emacs/VIM mode (Emacs mode is a mode which completely behaves as regular Emacs).ESC will go to normal mode and insert mode is a regular emacs (which means you rarily need to switch to Emacs mode :D ).

Another Emacs tip

Learn emacs dired! Dired (C-x d) is a textual file manager which allows you to navigate and manipulate your filesystem in a textual mode.

Some cool tricks:

  • C-x C-q toggles read-only mode in Emacs. When used from a dired buffer you can edit filenames as if you are just changinga text-file (VIM block selection and Emacs replace-regexp are very useful here for mass-renaming). You can then commit these changes to disk by using C-c C-c.
  • Keyboard macros work across buffers in Emacs. Combining this with dired you can easily execute keyboard macros across multiple files. Powerful stuff :D
  • Use M-x find-dired and M-x find-name-dired to open a dired buffer with the output of the find command.
  • <edit>Some corrections</edit>
 
Last edited by a moderator:
I switched to vim from emacs years ago when emacs took too long to start up (in its default config, admittedly) and ate too much memory if I had more than a few windows open. I guess on modern hardware it's not as much of a difference, but I still like that vi or vim is available on most systems from the smallest to the biggest without messing about with packages (ignoring Windows boxes and probably macs too).


I don't know that I use vim features especially extensively. Just the normal editing, cw to edit words, :tabnew for tabs, . for repeat, :map for setting up macros if you need to set up something more complex to repeat (and aren't familiar enough with sed to knock out a regexp with no errors in reliably). Er, that's pretty much it I reckon.
 
OP seems to put a respectable effort in the decision.

:)

My Emacs tricks:

Jumping through the text

C-x r <SPC> awill create a register identified by the key a (you can use any key instead 'a').

Code:
C-x r j a
will make the cursor/carret jump to the previously saved position.
Useful for identation (and enums and lots of places in coding tasks)

C-x r kkills the text delimited by the rectangle made of the two points in the selection area.

Code:
C-x r t
replaces the text in the rectangle by whatever you type next, in the minibuffer.
Madness

Code:
C-t
will... humm... just put the cursor in the middle of a word and see for yourself.

Code:
M-t
is the same as above, but for words.
 
Oh, in Vim you can do the following similarly:


Marking text: ma (or any other letter) to mark your place, 'a to jump back to it


Indentation: &gt;&gt; will indent the current line according to your current indentation preferences, and


Edit: Gah, angle brackets ate my post!
 
Last edited by a moderator:
Saved the following from my history:

Indentation: >> will indent the current line according to your current indentation preferences, and << will do the opposite. I've just discovered you can do 5>> to indent the next five lines, and if you want to do it to a selectable block of text, hit ctrl-v to enter visual mode, select your area and use the appropriate indentation command. I don't use visual mode much though.

Madness: I don't have emacs installed on any of my systems, but a google suggests that C-t is transpose letters (just xp in Vi - delete char, paste) and M-t is transpose words (dwwP in Vi - delete word, move a word forward, paste before current char, except at the end of the line, where Emacs apparently does something different).

Of course why you should use vim instead of vi is it's undo command. You can 'u' as many times as memory allows in Vim in case you get any of the above wrong, while old Vi just alternates between one level of undo and none. I'm sure emacs has an equivalent, but I'll leave that to the reader.

Setting your indentation preferences can be a bit of an arcane art in Vim. It defaults to an 8 space tab, which I find it much to much in most OO languages, where you end up half way across the page before you can enter any code. You can adjust how wide your tabs are using :set ts= (e.g. :set ts=4 to render every tab character as four spaces). I prefer actual spaces though, for compatibility, and here's my portable .vimrc file, annotated:

syntax on # Turn on syntax highlighting

set expandtab # Expand tabs to spaces automatically

set shiftwidth=4 # Make >> and << move the line four columns (max)

set softtabstop=4 # Make the tab key move four columns (max)

set autoindent # Continue indentation on new lines automatically

Of course, in vim you can enter :help shiftwidth to get help on that topic and find out what it really does (then do :bd - buffer delete - to close the help window).
 
Indentation: >> will indent the current line according to your current indentation preferences, and
Well... Emacs support automatic identation. It's just a matter of pressing tab.

I just used identation as an example. Rectangles operations are a generic useful concept. You can, for instance, comment the code, uncomment it, add a new prefix to a bunch of enums, ...
 
Of course, and Vim does automatic indentation for you automatically, provided you set the option.   But I don't mean this to be a vim versus emacs pissing match - just your post reminded me of some other things you can do in vim.  I have every respect for emacs, I just don't use it personally.
 
Of course, and Vim does automatic indentation for you automatically, provided you set the option.   But I don't mean this to be a vim versus emacs pissing match - just your post reminded me of some other things you can do in vim.  I have every respect for emacs, I just don't use it personally.
You're kind of respectful.

=P

I didn't mean as a competition either, but I got the wrong impression that you misunderstood (thanks to my lack of good explanation) about my little trick (working with rectangles).
 
Oh, and what I tend to use instead of rectangle/visual mode in Vim is ranges.  Ranges take the form ':<start>,<end><op>', so for example if I want to cut out a function so I can paste it elsewhere, I generally:

1. Go to the first line of the function

2. Set a marker ('ma')

3. Go to the first line after the function

4. :'a,.d (from marker a to the current line [dot - .], delete)

Ranges are also useful when using regular expressions - e.g. substutions like this one to replace foo with bar on all lines:

:%s/foo/bar/g

The percent symbol (%) is a special range that means all lines, and everything after s is the regular expression, with a g flag to make it replace multiple instances on the same line.  You could just as easily write :'a,.s/foo/bar/g to replace all instances of foo with bar in the lines between marker a and here (inclusive).

Really, emacs and vim are like foreign languages compared to each other.

Edit: Seems I had misunderstood indentation slightly.  Seems the indent command is just >, but you double it '>>' to do it immediately on the current line, just as you do 'dd' to cut the current line immediately.  So I guess it's more proper to do '>5>' than '5>>' though in practice both seem to work.  So to indent a range from marker a to marker b you do ":'a,'b>" .
 
Last edited by a moderator:
An interesting piece of synergy between emacs and evil functionality.

Emacs allows arbitrary elisp expressions to be used in regular expression replacement (including complete elisp functions and/or programs).

The syntax for this is \,<expr>.

The evil team neatly incorporated this functionality in their definition of VIM substitution commands.

E.g. consider the following expression which substitutes integer numbers in a buffer by their duplicated value:

%s/\([0-9]+\)/\,(* 2 (string-to-int \1))/g
While typing the command, Emacs neatly highlights what you are matching (blue) and what it will be subtituted by (red) such that you can visually verify:
21e82w.png


In Lisp a function f(2, 3) is written as (f 2 3) So, the replacement expression here (* 2 (string-to-int \1)) would be written as 2 * string-to-int(\1) in more conventional non-lispy notation.

Naturally, \1 is the text matched by the regular expression [0-9]+

This expression can even refer to the org-mode code block execution function which currently allows you to write the replacement expression or program in (a combination of) the following languages: ABC, Asymptote, Awk, C, C++, Calc, Clojure, CSS, D, Ditaa, Dot, Emacs Lisp, Eukleides, Fomus, Fortran, Gnuplot, Groovy, Haskell, J, Java, Javascript, Julia, LaTeX, Ledger, Lilypond, Lisp, Make, Mathomatic, Matlab, Maxima, Mscgen, Objective Caml, Octave, Org, OZ, Perl, Picolisp, PlantUML, Python, R, Ruby, Sass, Scala, Scheme, Shen, shell, SQL, SQLite and Tcl.
 
In my original post I talked about Emacs the platform. In this post I want to elaborate on that as I believe it to be fundamental to reach a proper understanding of Emacs and for contrasting Emacs to VI(M).

Apologies for the incoming wall of text.

The platform Emacs consists roughly of the following components

  • An ELisp interpreter. An runtime, language and standard library for running programs written in Emacs Lisp
  • An editor. A collection of cross-program commands and bindings to manipulate text.
  • A collection of Elisp Programs. These are referred to as Major-modes.
  • A collection of Plugins which extend the editor and sometimes the programs. These are referred to as Minor-modes
The default library of Emacs is geared towards manipulating text and as such most major modes are programs for editing text. In the sense of the UNIX philosophy you could say that the Emacs platform implements a generic, textual front-end for arbitrary tools and applications. The major benefit which Emacs brings to this is structure, standards and synergy between these applications.
So, how does Emacs realize this? Let's dive a bit deeper into the platform.

In Emacs everything is a function. E.g. hitting the key a in most textual (major) modes will call the function self-insert-command which inserts the character that triggered it into a buffer. Each major-mode (i.e. each program) defines a keymap which dictates what function to call whenever a key (combination) is input.

Some conventions to understand Emacs key-bindings:

  • C-c <letter> is reserved for users (both upper and lower case)
  • F5 - F8 without modifier are reserved for users
  • C-c followed by a control character or digit is reserved for major modes
  • C-c followed by any of { } < > : ; is reserved for major modes
  • C-c followed by other punctuation is reserved for minor modes
  • More details at gnu.org
The remainder of all the keybindings belong the Emacs editor.I suspect that many people who opt for VI(M) over Emacs, do so because of the editor. There is also the argument of startup-time and memory-usage against the interpreter/programs but in comparison to a full fledged IDE this is becoming less important. The Emacs Daemon/Client infrastructure tackles startup time quite elegantly.

Whenever you install EVIL-mode it is this editor which you are replacing. In fact, EVIL-mode is implemented as a minor-mode (i.e. a plugin) which simply breaks above conventions (which is why the Emacs-mode is added beside the regular VI(M) normal, insert and visual modes).

I am not an expert in VI(M), but what makes VI(M) unique is mainly the editor. The core feature of VI(M) is a grammar which describes sentences for manipulating text. In fact, experienced VIMmers can say they have conversations with their text editor forming sentences such as "delete 3 words". The Emacs editor is not nearly as orthogonal and consists more of a bunch of commands though naturally there is a lot of overlap.

Vimscript is an attempt at creating more of a platform around VIM as well, though in comparison to ELisp it is clunky and it seems to be mostly succesfull in creating the equivalent of the Emacs minor-modes, i.e. plugins. VI(M) users rightfully consider their tool to be an editor (a very unique and fantastic one, in my opinion).

In conclusion, whereas Emacs is quite far ahead as a platform, the VI(M) editor has a lot to offer and augmenting or replacing the Emacs editor with the VI(M) language has a lot of benefits.

In this thread I hope to explore both these tools and grasp the synergy between Emacs and VIM.
 
Last edited by a moderator:
Yes, the way Emacs is an editor built on Lisp which still exposes the Lisp functionality is a significant part of its power, and at the same time the reason why it doesn't tend to appear as a default install in many OSes.


Your example above of doing arithmetic inside Emacs is the sort of thing I don't think you can do directly in Vim. You can call external programs from Vim and replace the buffer with its stdout, so perhaps you could split it on spaces, push that through expr and then recombine the lines in the way you want, but to be honest most of the time I'd just create a python script in a new buffer and run that from Vim. Something like:


import sys


for line in sys.stdin:


nums=line.split()


for num in nums:


print num+str(int(num)*2),


Save it as 'doubly.py' then to run that from Vim, switch back to your initial buffer and use the filter command (!) on a range, such as the entire file:


:%!python double.py


That's not as neat as emacs, and doesn't give you the neat coloured output, and as it currently stands eats newlines, cos my python is a bit of a hack, but in some ways reusing external tools and piping the output through is a more unixy way of doing things.


Actually, as part of writing this post it occurred to me that Vim may have a python plugin, and indeed, :help python shows that it does. That would stop me having to write out an external script and delete it later, but otherwise for such a simple example, doesn't seem to gain me much.


Edit: IP Board seems to have eaten my indentation, so you'll need to add those back into the python if you want to use it.
 
Last edited by a moderator:
Promoting Emacs is also a great way to get flamed by Linus, though mentioning C++ or indenting using spaces works even better :)
 
Some neat refactoring tricks

  • Use M-x occur to list all lines which match a certain regular expression in the current buffer.A prefix argument can be used (e.g. M-3 M-x occur) to display the surrounding lines around each line that matches (in this example 3 lines before and after).

    In the occur-buffer which displays the matches type M-x occur-edit-mode to make the buffer writeable. Any changes made now will affect the original buffer as well.

    To stop editing type M-x occur-cease-edit or use the default keybinding C-c C-c.

    If you want to match a regexp in multiple files you can use M-x multi-occur which lets you specify buffers manually or M-x multi-occur-in-matching-buffers which lets you specify buffers by regular expression. Again, the same editing functionality applies.
  • Use iedit-mode (default binding C-;) to select all instances of the words under your cursor. Changing this word will apply to all instances at once.Very useful for renaming variables. Beware, iedit is textual only, it does not know what is a variable and what is something else. It might substitute more than you intended.

    Also works in occur-mode :D
  • Use narrowing to limit what part of the buffer is shown and affected by changes you make. C-x n n narrows to your region (i.e. selection), C-x n w widens to the original buffer and C-x n d narrows to the current defun (i.e. the one containing your cursor).A defun is normally a lisp function definition, but each major mode can override what a defun means. So in python it is a python function, in C it is a C function and so on.

    This is very nice in combination with iedit mentioned in the previous point. E.g. to rename all instances of a variable in a specific function only.
 
Last edited by a moderator:
I've used Emacs on and off for more than 20 years. I still find new neat tricks. Amazing :)
 
In Vim you can highlight all matches of a regexp simply using /, e.g. I often use it to see all tabs using '/\t'. You can cycle through all hits using n and p. As with all commands, you can prefix it with a range (':start,end') to limit its effectiveness.


I don't know a way to do live editing of words. I usually set up a regexp for the word (e.g. '/foo') then edit it with 'cw' (escape to end editing), then hit 'n' to find the next instance of that word and hit dot (.) to repeat the edit (or just n again if you matched something you don't want to change. After doing it all I can redo the regexp to make sure I got all instances. You can do a blanket change of everything using a replacing rexexp ('/foo/bar/g') but I like to see exactly what's going on, so I tend to spend a little more time over it.


It's another case where emacs or vim aren't really better than each other, they just have a different way of getting the same result. I can't say which is better - for me I've been using Vi for so long that the commands are second nature, so it's quick and easy for me.
 
Back
Top