do_thing(x, y, x); do_other_thing(a, b, c);
to_the_death(j, k, l); to_the_pain(wfb);
do_thing(c, f, e); do_other_thing(t, t, q);
#etc for maybe a dozen lines.
? And what IDE wouldn't make that pretty from the get go? And why would you have more than one instance of something like two functions needing positions switched when that could've been refactored out? Very artificial example, and even still doesn't demonstrate the strength of Emacs over somethink like Visual Studio.This particular example was inspired by a lexical definitions file, which is a series of regular expressions with code attached to each one. Here's a sample from my actual code:
"!" {lexer_debug(yytext, SIMPLEOP_BANG); yylval.ptnode = lex_leaf(SIMPLEOP_BANG, NULL); return SIMPLEOP_BANG;}
"%" {lexer_debug(yytext, SIMPLEOP_REMAINDER); yylval.ptnode = lex_leaf(SIMPLEOP_REMAINDER, NULL); return SIMPLEOP_REMAINDER;}
What this says is that when the lexer encounters an exclamation point, it first calls a debug function with the text it found and the associated token enum. Then, it creates a leaf node and assigns the result to yylval.ptnode, then it returns the token enum. I have 66 different definitions in the file. Each one passes unique arguments to the various functions. It is difficult to compress the code much further than this. There is very little to be gained by combining everything into one function. Some of the tokens (braces and constants, in particular) have additional code that must be run. If I tried to refactor, I'd have to create a new conditional framework to account for the special cases (either a switch or function pointers since this is C). That would increase logical complexity (the lexer already did the comparison, why do it again?), incur performance overhead for no good reason, and ultimately would not gain me much in the long term.
My original code had the debug function and the leaf function backwards. I needed to fix that. I had two options. I could refactor the whole damn thing and debug the result (which would include 6 special cases), or I could spend 60 seconds recording a keyboard macro and 10 to execute it 60 times. Option two is simply not an option in Visual Studio.
Another example:
Suppose you're using python and have a whole bunch of functions to wrap in classes. The one drawback of 'the whitespace thing' is that if you try to use tabbing to do this it's easy to make a few mistakes and screw up your block structure. It's better to just insert X spaces at the beginning of each line. I made a macro to do exactly this, and can easily bind it to F8 whenever I need to use it. I use F7 and F8 as my utility keys, for functions I don't use all the time but need to be fast when I do use them. I'll probably eventually write a function that will let me cycle the behavior of my function keys sort of like the ability bar in World of Warcraft. That's basically what minor modes are for already (though I don't know how to use them yet).
The information you have visible on the screen and easily accessible in a keypress or two is also critical to thinking quickly and efficiently. Yegge once mentioned that he had the perl documentation as emacs .info pages, meaning it probably takes him a few seconds to find a number of frequently used resources. That means he'll probably be better at leveraging standard functions than someone who uses Google. I find the split-screen function in emacs far superior than trying to have multiple windows windows open and arranged on the screen.
One way that emacs is superior to Visual Studio is the keyboard macro facility. I frequently find that I need to make some minor correction that needs to be repeated a few times. Either it's too small a change to be worth refactoring completely using language abstractions or a clunky macro system like MS word, or too complicated to be suitable for copy/paste or find/replace. In a lesser editor, you build up a subconscious resistance to making small corrections like that, so even though you may not be typing furiously all the time, the weaknesses of the editor still affect the way you think and the solutions you're willing to use.
start macro(C-[), search to semicolon(C-s, ;), kill to end of line(C-k), move to beginning of the line(C-a), yank killbuffer(C-y), move to beginning of line(C-a), move down, end macro(C-]).
This is a quick macro that moves everything after the semicolon to the beginning of the line, and can be repeated for consecutive lines as often as necessary. Suppose you had a section of code that looked like this:
Suppose you need to swap the position of the functions on each line, such that "do_other_thing" comes before "do_thing" and "to_the_pain" comes before "to_the_death."Without a keyboard macro facility like the one in emacs, you're stuck jumping around using copy-paste. It will probably take a few minutes, and when you're done you'll have probably lost your train of thought. So even though it may have had a small effect on the lines of code you produced within a given 5-10 minute period, it may significantly affect the trajectory of the entire session. After you get used to emacs, using a macro like this is as easy as typing a line of code.
Visual Studio has its advantages. It has a terrific runtime debugger, for example, and is great for visualizing data structures. But it's worth talking about, and Yegge has some great insights.