Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

Saturday, October 30, 2010

Emacs and ReSharper keybindings in Visual Studio

Since committing to Emacs as the text editor to supplement my primary (integrated) development environment, Visual Studio, Emacs has become an indispensable part of my computing life. I run it on any machine I use on a regular basis and sorely miss it when it's not there. It has lived up to its long standing reputation as an extremely powerful text editor that it is more than just a text editor.

I use Visual Studio for C# and .NET coding and Emacs for everything else. Emacs functions as my shell environment (via Eshell with a major assist from Cygwin) when working with file systems local or otherwise. Emacs is where writing and editing Python files, shell scripts, config files, todo lists (with org-mode), notes, and other tasks too trivial to list all take place.

Parsing log files, interacting with source control, and connecting to and running queries on SQL Server have found their way into my Emacs sessions. Also, since editing JavaScript code using Visual Studio 2005 was as mundane and constraining as using Notepad, with no intellisense and no ReSharper magic, Emacs became a more nurturing environment for manipulating JS code. (At least until making the upgrade to Visual Studio 2010 where JavaScript support is vastly improved thereby displacing Emacs in this one activity.)

When using Visual Studio for day-to-day coding sessions in C#, Emacs style keybindings are a must for me. While not as precise as Vim, they do provide me with greater control over the text than the default keybinding most others use in VS or in any other modern, popular IDE or text editor.

ReSharper is what chiefly keeps me relying on Visual Studio to do .NET development. This robust and powerful commercial plug-in for Visual Studio has refactoring and navigation features that are not just superb but they give such control over the code and source files analogous to the power Emacs grants its user with text manipulation.

Initially, adopting Emacs key strokes for Visual Studio was not going to be easy without allowing peaceful co-existence with ReSharper's own extensive list of keyboard shortcuts. Conflicts were inevitable. (These conflicts and how to smoothly resolve them will be covered in more detail.)

Prior to the release of VS2010, the native Emacs keyboard scheme in VS2005 sufficed for coding. To enable it, select on the menu
Tools -> Options -> Environment -> Keyboard -> Apply the following additional keyboard mapping scheme -> Emacs
It provides most of the basic motions and text editing commands found in Emacs ranging from deleting all characters from the cursor to the end of the current line via C-k to moving between words using M-f and M-b. Thus, it gave me the same comforting, familiar experience as coding in Emacs itself.

Unfortunately, upon learning VS2010 would no longer support Emacs keybindings, I needed to find a suitable alternative when upgrading to it from VS2005 (and skipping over Emacs-enabled VS2008). I briefly considered learning VIM either by trying out ViEmu, a commercial VIM emulator for VS, or VsVim, a similar but free extension for VS2010. Fortunately, sanity prevailed and I decided to use XKeymacs, a utility app that applies Emacs style keybindings to any Windows application or program whether it be Word, Outlook, Notepad, Windows Explorer, or cmd.exe. I'd already been using XKeymacs for some time for those other places that I cannot (easily) reach with Emacs itself including composing emails and editing text in web browsers (although I've had some luck with the Firefox add-in, It's All Text!). XKeymacs is far from perfect but works reasonably well.

After using XKeymacs in VS2010 for a bit, I realized that it did a better job than the old native version in VS2005. While XKeymacs has its problems, the built-in Emacs VS keybindings were relatively worse and more aggravating to use in comparison. (Again this will be dissected in more detail.)

Whether you use XKeymacs or the built-in Emacs VS keybindings, I recommend configuring ReSharper to use the "Visual Studio Scheme" and not the "ReSharper 2.x/IDEA scheme" provided in the default install. At first, I did learn and used the (IntelliJ) IDEA scheme when I started with ReSharper mainly because I thought that if I ever were to use the IDEA IDE then the transition would be easier. But, prematurely optimizing for something that might never happen is something to be avoided not just when developing software (if I find myself needing to code in Java I'd probably use Eclipse with Emacs keybindings or Emacs itself).

Choosing the VS scheme over ReSharper's allows for Emacs keybindings to have precedence over the ReSharper keyboard shortcuts whenever possible. The rationale is that Emacs keybindings are far more ubiquitous than ReSharper's. Resharper is limited to Visual Studio (and the aforementioned IntelliJ) while Emacs key shortcuts can be found on a multitude of OS platforms, IDEs, text editors, and shell consoles. It is best to stick with the consistency and prevalence of Emacs style key chords rather than with ones from a niche commercial add-on tool.

Using the Visual Studio scheme for ReSharper does cause problems when working with other team members who use the other ReSharper/IDEA scheme. It's bad enough Emacs keybindings are annoying for someone who sits at my machine and it has not been turned off by the time they type their first character ("Hey, can't I copy? Is Ctrl+C broken? Oh yeah, I forgot, you are using those goofy Emacs keys.").

What's worse (with deeper implications) is when another teammate, knowing a different set of ReSharper shortcuts than I do, attempts to specify a command for me to run. This is likely to occur when pair programming or during code reviews. For example, they might say type Ctrl + n to find the 'Foo' class they recently refactored and it disrupts the flow before we finally figure out that they meant for me to run 'Go to Type' which I know as Ctrl + t. It's like we're speaking to each other in a foreign language. Not good for fostering fluid team collaboration and communication. (This tooling gap occurs with shell commands too since I am fond of using bash on Windows via Cygwin while others are cmd.exe wizards. Typing 'ls' in cmd.exe instead of 'dir' gets odd looks at times.)

Shortly after switching to XKeymacs in VS, a new Emacs Emulation extension for VS2010 was announced that more or less brings back the same old Emacs keyboard scheme from VS2005 (and Visual Studio 2008.) With this new Emacs extension, I was hoping some of the problems that irritated me in the old one which were subsequently magnified when switching to XKeymacs were fixed. But, with the exception of a few things, these annoyances are either still there or behave worse in some cases.

Reasons why I prefer XKeymacs over the VS Emacs keybindings in VS2005 and VS2010:
  • Tabbing and indenting works sanely.
  • Auto formatting works consistently. For example, curly braces line up properly and blocks of code are smartly indented after hitting ENTER. This is not how it behaves in either VS2005 or VS2010 Emacs scheme.
  • DELETE button works by simply pressing it and not requiring to also hit CTRL. Seems blasphemous to care about a key that is not fundamental to Emacs and contradicts my efforts to map the keys faithfully but it's dead simple functionality that should work for any Windows application even if ported from another OS platform. Another nicety of XKeymacs is after selecting text, it supports C-d to delete the entire text not just with the conventional kill command C-w. With VS Emacs, you are limited to just C-w. Granted this is how it also functions in Emacs but it is a nice feature that I would not mind if Emacs supported too out-of-the-box (without requiring adding an Elisp command to remap the key in your .emacs file).
  • Able to overwrite selected text simply by typing and not killing it first (this is the same issue as in the previous item). For example, ReSharper's live templates such as the 'if-statement' code snippet highlights text as contextual placeholders to type custom variable names and values. VS Emacs bindings requires cutting the text via C-w before writing any new text. XKeymacs allows you to just start typing away without that extra step.
  • Copying/yanking text from other applications to VS works as expected (especially from Emacs itself). I never figured out how to get it to work properly in VS2005 Emacs scheme. I suspect the source of the problem was perhaps VS maintaining its own internal kill ring (clipboard) that did not interact well with the Windows clipboard. Sometimes hitting ESC before pasting would help but even that was not reliable. Far worse, VS2010 does not support any copy and paste from external applications (for example, try copying some text from Notepad and then do C-y in VS. You'll see nothing is pasted other than the last yank/kill from within VS)
  • ReSharper's Multiple Entries Clipboard works. It was buggy with the Emacs emulation in VS2005 and in VS2010 it does not work at all.
  • Not limited to just the text editor but able to use XKeymacs everywhere in Visual Studio such as in dialog boxes (e.g. ReSharper's Rename and Find/Replace features), in ReSharper's Navigation and Search features (e.g. in 'Go To Type' and 'View Recent Files'), in other window panes (e.g. the Immediate Window and Solution Explorer) and in textboxes on the menubar (e.g. the extended command-line).
  • Can navigate quickly in Intellisense's dropdown list using C-p and C-n in lieu of the arrows keys (although hitting CTRL for some reason makes the list of values transparent)
  • Does not disable the graphical menu of all open files and window panes when typing CTRL + TAB. It is completely gone from both VS2005 and VS2010 when using VS Emacs scheme.
Despite all of this praise, XKeymacs has a few faults. On occasion it can behave flakey requiring either resetting or closing and then re-running the XKeymacs exe. Another problem is sometimes the ALT key will trigger the file menu instead of (or in addition to) the normal key command.

Regardless, these peculiarities are not enough to keep me from using XKeymacs. However, I use the VS Emacs scheme as fallback whenever XKeymacs acts unbearably goofy. Switching between the two "modes" is fairly quick in my enviroment. XKeymacs has the key command C-q that toggles between disabling and enabling it. In addition, I have created and defined a VS macro that can toggle between the Emacs scheme and the "Default" VS scheme via the key command M-q which I bound to the macro. By combining these two commands, hitting C-q M-q (or M-q C-q) allows me to go back and forth when necessary.

Speaking of macros both XKeymacs and VS Emacs scheme support recording and running macros via the same keys commands used in Emacs proper:
C-x (  recording a macro
    C-x )  stop recording a macro
    C-x e  run the macro
XKeymacs' macro feature works in places you would not expect including applications like Notepad, Outlook, and Word. VS Emacs scheme's macro key chords are hooked into Visual Studio's built-in macro functionality. Discovering both to have support was a surprise to me. I use macros in Emacs quite often. It's great to have this powerful functionality with the same key commands I'm already familiar with.

However, I limit the use of XKeymacs' macros to the simplest of text editing scenarios before turning to alternatives. Sometimes it does behave strangely at which time I might switch over to using VS's macros via Emacs scheme which tends to be a bit more smooth. For more complex editing situations, I'll just open the file in Emacs itself for heavy duty text manipulation.

Configuring Keybindings in Visual Studio

Now follows a list of conflicts and missing keybindings and how best to resolve them. I will include not just how XKeymacs can be configured in VS with ReSharper but also the built-in Emacs VS schemes for both VS2005 and VS2010 (I assume this applies for VS2008 but no guarantees since I've never used it and can not confirm it can be configured the same.)

All key combinations are presented in the traditional Emacs style and format. Specifically, "C-" for "CTRL" and "M-" for "ALT". For example, 'Kill to end of line' is shown as
C-k
instead of
CTRL + k
Also, SHIFT will correspond to the capitalized version of a character such as
C-K
instead of
SHIFT + CTRL + k
To change any key settings in VS go to:
Tools -> Options -> Keyboard 
This is where you'll configure keyboard shortcuts. Generally, you should set the value for 'Use new shortcut in:' to be "Text Editor" (and, if necessary, "HTML Editor") since it overrides any other commands with the same pre-existing key shortcuts that are set to be "Global". If no other commands are using the keybindings (this is evident if any values appear in 'Shortcut currently used by:' dropdown list after pressing the desired keys in 'Press shortcut keys:') then it's safe to just use "Global".

Configuring Keybindings in XKeymacs

When configuring XKeymacs, make certain to select 'devenv.exe' as the specific setting and not the 'Default' value setting. Initially opening XKeymacs' properties always reverts to 'Default' so it is easy to overlook this.

To configure XKeymacs:
In Windows System Tray -> right-click XKeymacs icon (or double-click will automatically open 'Properties) ->
 Properties -> from dropdown list at top of screen, select 'Microsoft Visual Studio .NET (devenv.exe) ->
 select 'Use Specific Setting'
For the 'devenv.exe' setting, I recommend removing all extraneous key commands that serve as duplicates for the basic Emacs commands. These alternate key strokes might include an extra 'SHIFT' (or 'ALT') key press which could override existing non-Emacs VS commands. For example, the command 'forward-char' is typically just C-f but in XKeymacs it can also be called by Shift + Ctrl + f. (In VS, this command is belongs to 'Find All Files' which I use frequently. I'd rather keep it unchanged since I don't need another (more cumbersome) way to move forward one character.

To remove these key commands:
In XKeymacs -> Properties -> change combobox from "Default" to "Microsoft Visual Studio .NET (devenv.exe)" -> Change from 'Use Default Setting' to 'Use Specific Setting' ->
Click 'Advanced' tab -> under 'Category' select "Motion" -> under 'Commands' select "foward-char" -> 
under 'Current keys' select "Ctrl+Shift+B" -> click 'Remove' button
Repeat this for all other commands found under the categories:
  • Search
  • Motion
  • Killing and Deleting
  • Other
Commands that have two or more key bindings associated with them should have their key shortcuts using SHIFT removed. There are a lot of them. Once removed, it should free up some default shortcuts for other VS and ReSharper commands that use the same keys.


Delete Next Character: C-d

XKeymacs Mode:

XKeymacs' command C-d overrides ReSharper's Duplicate Line or Selection command. Instead, set
ReSharper.ReSharper_DuplicateText
to use:
C-D
As mentioned, make sure that XKeymacs is configured to no longer use SHIFT for killing forward characters thus making this available for ReSharper's duplicate text command.

While forward character delete is consistent with Emacs, backward character delete is not only bound to the expected BACKSPACE button as in Emacs, but also bound to C-h. I tend to forget that this exists in XKeymacs since in Emacs proper it is bound to 'Help'. C-h is a better fit for backward delete rather than the infrequently called Help command since it keeps your fingers on home row.

VS Emacs Scheme:

When first hitting C-d and then prompted with 'ReSharper Shortcut Conflict' dialog box, I selected "Use Visual Studio commands" but this does not automatically bind to the 'delete next character' command. The reason is that C-d is reserved for other commands in VS including the family of Debug.* commands. Looking at the documented list of VS Emacs shortcuts, C-Delete is what is expected to be used. This is not consistent with Emacs.

Therefore, manually set the following VS command (using "Text Editor" and not "Global" setting)
Edit.Delete 
to
C-d
Then follow the same steps as XKeymacs mode for reassigning ReSharper's duplicate text command.


Move to the end of the line: C-e

XKeymacs Mode:

Some conflicts with existing ReSharper bindings including 'Insert Live' template, 'Surround With' template, and Code Cleanup. Some of these I use regularly and some I don't. Here are two I do use:

Bind 'Surround With' template command
ReSharper.ReSharper_SurroundWith
to
C-M-j  
The above keybindings is borrowed from the ReSharper 2.x/IDEA scheme.

Bind 'Code Cleanup' command
ReSharper.ReSharper_CleanupCode
to
M-j
The above keybinding is not based on anything other than to be consistent with the previous 'Surround With' command.

VS Emacs Scheme:

When hitting
C-e
you'll be prompted by ReSharper to select which scheme to use whether default VS or ReSharper's (IDEA). Select VS scheme and not ReSharper's. This should be sufficient but make sure that:
Edit.EmacsLineEnd
is bound to
C-e   


Kill region: C-w

XKeymacs Mode:

N/A. Works as expected.

VS Emacs Scheme:

Bind the VS command:
Edit.Cut
to
C-w
Oddly, this standard keybinding of Emacs is not part of the VS Emacs emulation. As an alternative, it recommends using Shift + DELETE. Meanwhile, C-w is bound to Edit.SelectCurrentWord which I thought was ReSharper's similar function but it is actually the native one for VS.

I recommend removing the binding from Edit.SelectCurrentWord and just use ReSharper's equivalent version, 'Extend selection', which already works with C-M-Right Arrow (and conversely 'Shrink Selection' set to C-M-Left Arrow).


Delete (kill) from cursor (point) to end of line: C-k

XKeymacs Mode:

N/A. Works as expected.

VS Emacs Scheme:

Bind the VS command:
Edit.EmacsDeleteToEOL
to
C-k
No (apparent) conflict with ReSharper, but for some reason did not seem bound at all even though according to the list of VS Emacs key shortcuts it should be. Instead, it is by default bound to a whole class of commands such as Edit.CommentSelection.


Tab and Indentation: C-i

XKeymacs Mode:

This works as expected. Hitting ENTER automatically indents the next line to match the previous line.

XKeymacs does not support C-j which inserts newline and indents but it does support C-m which is an alternate to ENTER and only inserts newline. C-m works the same as ENTER in Visual Studio meaning it does smart indenting too and has the advantage that it is easier to hit than ENTER. Regardless, I also bound C-j to Edit.Breakline to use for consistency and convenience.

VS Emacs Scheme:

This is the messy. Tabbing and indenting is one of the weakest and most confusing areas of the VS Emacs scheme. It does not behave how you would expect including interfering with smart indentation.

In both VS2005 and VS2010 Emacs schemes, if you write a line of code and then hit ENTER, the new line will not automatically indent. Instead, ENTER takes the point (cursor) to the first column of the line. You have to hit TAB again to get it to indent. Otherwise, after you start typing some new code, hitting ";" will automatically indent the line to match the preceding one. Both options are not optimal.

Instead, you need to get in the habit of using C-j. This key command is bound to Edit.EmacsBreakLineIndent' which will insert a new line and indent the line correctly.

Hitting TAB on an existing line with text behaves strangely. In VS2010, it toggles tabbing if already tabbed. In VS2005, it does nothing- the line remains unchanged. Once a line is indented, you cannot further indent the line by pressing TAB in either versions of Visual Studio.

To address this issue, I originally bound:
Edit.IncreaseLineIndent 
to
C-M-TAB  
and
Edit.DescreaseLineIndent 
to
Shift-C-M-TAB  
This was really helpful in JS files in VS2005 since no smart indent supported.

However, I then saw this suggested solution to inject additional tabs by using:
C-q TAB
It relies on the Emacs' quoted insert text functionality that VS Emacs scheme also supports via Edit.EmacsQuotedInsert which is bound to C-q.

Unfortunately, C-q conflicts with XKeymacs key command to enable and disable itself which I use fairly heavily. Therefore, I assigned C-Q to Edit.EmacsQuotedInsert and removed the extra keybind from XKeymacs.
XKeymacs -> Under Categories "Other" -> under 'Commands' select "Enable or Disable XKeymacs" -> under 'Current Keys' select Ctrl+ Shift + Q -> click 'Remove'

Finally, for completeness on all-things-tabbing, I thought I could bind
C-i
to
Edit.Indent
but that is reserved by 'Incremental Search' in the default, non-Emacs scheme. I just left it "as is" since it is convenient to have when pair programming with Emacs keybindings turned off.


Delete spaces and tabs around point M-\

XKeymacs Mode:

Bind the VS command:
Edit.DeleteHorizontalWhiteSpace
to
M-\
XKeymacs does not support this command but I use it all the time in Emacs. However, it conflicts with ReSharper's 'Go to File Member'. Therefore I re-mapped
ReSharper.ReSharper_GotoFileMember
to
M-|
VS Emacs Scheme:

Follow the same steps as described for XKeymacs mode.


Expand the word in the buffer before point as a dynamic abbrev: M-/

XKeymacs Mode:

Does not support this command so bind Visual Studio Intellisense/AutoComplete command:
Edit.CompleteWord
to
M-/
VS Emacs Scheme:

N/A. Works as expected.


Running commands by name: M-x

XKeymacs Mode:

XKeymacs supports the keybinding M-x for running external commands in cmd.exe shell, but I never found much use for it since it is awkward to use with no visual feedback of what you just ran.

Therefore, I removed from 'devenv.exe' settings:
In XKeymacs -> under 'Category' select "Other" -> under 'Commands' select 'execute-extended-command' -> under 'Current keys' select "Meta-X" -> click 'Remove' button
Then bind the VS command:
Tools.GoToCommandLine
to
M-x

I use this VS command line feature frequently particularly for TFS source control commands such as
  • File.TfsCompare
  • File.TfsUndoCheckout
  • File.TfsHistory

and to call other commands from the Application Menu such as
  • Tools.Options
  • Tools.AttachProcess
  • File.CopyFullPath (pasting in other applications like emacs itself)
  • bl (alias for Debug.Breakpoints)
  • callstack
  • View.BookmarkWindow (precedes ReSharper 5.0 bookmark)
VS Emacs Scheme:

N/A. Works as expected.


Incremental search forward: C-s

XKeymacs Mode:

Works as expected hooking into VS's
Edit.IncrementalSearch
although not sure how it is automatically bound to it. It is a different command than the traditional 'Find/Replace' command that XKeymacs usually uses in most other Windows application. Regardless, one less thing to bind manually.

VS Emacs Scheme:

N/A. Works as expected.


Incremental search backward: C-r

XKeymacs Mode:

N/A. Works unexpectedly just as incremental search forward.

VS Emacs Scheme:

This is not bound to C-r although C-s is bound to search forward. Instead, the default key shortcut is C-I which is awkward to use when toggling with incremental search forward (C-s). Therefore, mapped the VS command:
Edit.ReverseIncrementalSearch
to
C-r
C-r conflicts with numerous ReSharper refactor mode commands particularly all of the refactoring commands. However, since I tend to use C-R to get list of contextual refactorings and never was in the habit of calling individual refactoring commands, remapping C-r is preferable.


Scroll the selected window so that the current line is the center-most text line: C-l

XKeymacs Mode:

XKeymacs does support this command but it does not work properly in VS. Instead of centering the screen on the current line, it keeps moving the screen one line down.

Therefore, I mapped the following the VS command:
Edit.ScrollLineCenter
to
C-l
and then removed the C-l keybinding from XKeymacs 'devenv.exe' setting by:
XKeymacs -> Advanced -> under 'Category' select "Motion" -> under 'Commands' select "recenter" -> under 'Current keys:' select "Ctrl + L" -> click 'Remove' button
VS Emacs Scheme:

N/A. Works as expected.


Tranpose character: C-t

XKeymacs Mode:

One of the rare circumstances where I chose ReSharper's default key shortcut and ignoring an existing Emacs keybinding. I removed XKeymacs binding of C-t by going into its settings and configuring:
XKeymacs -> Advanced -> under 'Category' select "Killing and Deleting" -> under 'Commands' select "transpose-chars" -> under 'Current keys:' select "Ctrl + T" -> click 'Remove' button
I hardly encounter situations where I need to transpose single characters (although words and lines are more common.) On the other hand, I use Resharper's 'Go to Type' command all the time so I make an exception to keep C-t assigned to it.

Make certain the VS command:
Resharper.Resharper_GoToType
is bound to
C-t
VS Emacs Scheme:

Follow the same steps as described for XKeymacs mode.


Numeric Argument: C--

XKeymacs Mode:

The VS command for navigating backwards is another situation where a VS keybinding wins over an existing Emacs' keybinding:
View.NavigateBackward
is already bound to
C--
However, this conflicts with XKeymacs command 'numeric argument -' for passing negative arguments related to the C-u repetition counts. I never use this and if I do then I would call it via M--. So, kept it unchanged in VS and removed the conflict from XKeymacs 'devenv.exe' settings:
XKeymacs -> Advanced -> under 'Category' select "Other" -> under 'Commands' select "numeric argument -" -> under 'Current keys:' select "Ctrl + -" -> click 'Remove' button
The 'cycle through mark ring' command in Emacs, C-x C-SPC, reminded me of the VS command, View.NavigateBackward. Although not quite the same as VS's feature, it is similar enough for me to also bind these keybindings for consistency.

To do this, find the .xkeymacs config file in the XKeymacs directory.
...\xkeymacs347\etc\English (United States).xkeymacs
Add the line:
(fset 'cycle-mark-ring "\Ctrl+-")
Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab -> Category 'Original Command' -> 
you should now see the new command, 'cycle-mark-ring', previously added in the config file in the list of commands. To continue:
Under 'Press new shortcut key:' -> check 'Ctrl-X' -> in text field below it, press 'Ctrl-SPACEBAR' -> click 'Assign' -> 'Current keys:' list should now include 'Ctrl-X Ctrl-Space'.
Now in VS, along with C--, C-x C-SPC will also run the navigate backward command when XKeymacs is enabled.

I initially tried to bind to C-u C-SPC but XKeymacs limits prefixing commands with C-x. However, this is for the best since C-x C-SPC is more appropriate because it cycles through all buffers just as the View.NavigateBackward command navigates through all open documents in Visual Studio. That other command only cycles through ones in the current buffer.

I generally stick to using C-- since it is less awkward to type and it is consistent and more fluid to use when switching back and forth with View.NavigateForward which is C-_ (a.k.a. Shift+Ctrl+ -)

VS Emacs Scheme:

Follow same steps as XKeymacs mode.


Undo: C-_

XKeymacs Mode:

The complimentary VS command to previous item 'navigate backward' is of 'navigate forward'
View.NavigateForward
is bound to
C-_

This keybinding conflicts with one of the three existing XKeymacs commands for 'Undo'. Since I always use C-/ for Undo then removed that unnecessary conflicting keybinding:
XKeymacs -> Advanced -> under 'Category' select "Error Recovery" -> under 'Commands' select "undo" -> under 'Current keys:' select "Ctrl + Shift + -" -> click 'Remove' button
VS Emacs Scheme:

A conflict exists since under the VS Emacs scheme
Edit.Undo
is bound to
C-_
Again, since Edit.Undo is also bound to C-/ which is what I only use then remove that binding from the Emacs scheme.


Delete blank lines: C-x C-o

XKeymacs Mode:

This is not supported in XKeymacs but Visual Studio does have this command. It behaves slightly different in VS than in Emacs. In VS, it removes all blanks lines from the cursor and below. Any blank lines above the current blank lines will be ignored. To remove those, you need to call the delete blank lines command again. In Emacs, the equivalent command removes all of the blank lines below and above but leaves the current blank line. To get rid of this line, you need to repeat the same command again.

Now, to use the C-x C-o keybindings requires reconfiguring XKeymacs. First, assign in VS:
Edit.DeleteBlankLines
to
M-o
I would have preferred using C-x C-o but C-x is the common command for Edit.Cut and rather not mess with it to leave it available when pair programming. Therefore, arbitrarily chose M-o as an alternative.

In XKeymacs, you can map key commands to custom ones to use while running XKeymacs.

Find the .xkeymacs config file in the XKeymacs directory. For example, mine is found under Program Files:
C:\Program Files\xkeymacs\xkeymacs347\etc\English (United States).xkeymacs
Add the line:
(fset 'delete-blank-lines "\Alt+o")
Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab -> Category 'Original Command' -> 
you should now see the new command, 'delete-blank-lines', previously added in the config file in the list of commands. To continue:
Under 'Press new shortcut key:' -> check 'Ctrl-X' -> in text field below it, press 'Ctrl-o' -> click 'Assign'
'Current keys:' list should now include 'Ctrl-X Ctrl-O'. Now in VS, C-x C-o will run delete blank lines command (as well as M-o the original bindings in VS) when XKeymacs is enabled.

VS Emacs Scheme:

N/A. Works as expected.


Split the selected window into two windows, one above the other: C-x 2

XKeymacs Mode:

As with the previous item, XKeymacs does not support this but VS does have this command. However, just like before, I'm unable (or unwilling) to bind to C-x 1 since it interferes with Edit.Cut (C-x) in non-Emacs mode. Therefore, need to map the binding in XKeymacs.

First, in VS make sure:
Window.Split
is bound to
Ctrl + F6
Then in XKeymacs config file, '.xkeymacs':
...\xkeymacs347\etc\English (United States).xkeymacs
add line:
(fset 'split-window-vertically [?\Ctrl+f6])
Then configure XKeymacs
Properties -> select 'devenv.exe' -> 'Advanced' tab -> under Category 'Original Command' -> 
should now see new command, 'split-window-vertically', in the list of commands
Under 'Press new shortcut key:', check 'Ctrl-X' -> in text field below it, press '2' -> click 'Assign' 
'Current keys:' list should now include 'Ctrl-X 2'. Now in VS, C-x 2 will run 'window split' command (as well as Ctrl + F6 the original bindings in VS).

Although I don't use splitting windows that often, it is useful on those rare occasions when I need to view one part of a file while editing another part of that same file.

VS Emacs Scheme:

N/A. Works as expected.


Remove other windows (remove split): C-x 1

XKeymacs Mode:

Continuing from the previous item, we need a way to remove the split window too. In VS, the same command 'Windows.Split' that initially splits the window also removes it. It toggles the two states.

Follow all of the same steps as descibed in the previous item for window split specifically adding the new mapping in .xkeymacs config file.

Now go back into XKeymacs to add an additional keybinding for the same 'window split' command:
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab -> Category 'Original Command' -> 
should now see (new) command, 'split-window-vertically', in the list of commands
under 'Press new shortcut key:, check 'Ctrl-X' -> in text field below it, press '1' -> click 'Assign' -> 
'Current keys:' list should now include 'Ctrl-X 1' along with 'Ctrl-X 2' added previously. Now in VS, C-x 1 will run 'window split' command (as well as Ctrl + F6 the original bindings in VS) to remove the window split.

VS Emacs Scheme:

N/A. Works as expected.


Select another window: C-x o

XKeymacs Mode:

This command is available once a window for a file has been split (see the two previous items). It allows one to move the cursor and focus back and forth between the two views.

In VS, check to see if
Window.NextSplitPane
is assign to
F6
If not, then set it as F6.

Then in XKeymacs config file, '.xkeymacs':
...\xkeymacs347\etc\English (United States).xkeymacs
add line:
(fset 'other-window [f6])

Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab  -> under Category 'Original Command',
should now see new command, 'other-window', in the list of commands
Under 'Press new shortcut key:', check 'Ctrl-X' -> in text field below it, press 'o' -> click 'Assign'
'Current keys:' list should now include 'Ctrl-X o'. Now in VS with XKeymacs, C-x o will run 'next split pane' command (as well as F6 the original keybinding in VS)

VS Emacs Scheme:

N/A. Works as expected.


Go to line: M-g g

XKeymacs Mode:

In VS, check to see if:
Edit.GoTo
is assign to
C-g
If not, then set it as C-g.

Then in XKeymacs config file, '.xkeymacs':
...\xkeymacs347\etc\English (United States).xkeymacs
add line:
(fset 'goto-line "\Ctrl+g")
Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab  -> under Category 'Original Command'  ->
should now see new command, 'goto-line', in the list of commands
Under 'Press new shortcut key:' -> in text field below it, press 'Alt + g' -> click 'Assign'
'Current keys:' list should now include 'Meta + G'.

However, sometimes this keybinding does not always work. Therefore, assign an alternate keybinding. Go back to
'Press new shortcut key:'  -> in text field below it, press 'Ctrl+Alt+g' -> click 'Assign'
'Current keys:' list should now include 'Ctrl+Meta+G' along with 'Meta+G' added previously.

In VS, C-g or C-M-g will run 'goto line' command.

VS Emacs Scheme:

N/A. Works as expected.


Delete from beginning of line to point: M-0 C-k

XKeymacs Mode:

N/A. Works as expected.

VS Emacs Scheme:

M-0 C-k kills from point (cursor) to the beginning of the current line. It is the opposite command of C-k which kills from point to the end of line. Unlike XKeymacs, the equivalent VS command, Edit.DeleteToBOL, removes all text to the start of the line which includes the non-blank spaces.

In VS assign:
Edit.DeleteToBOL
to
M-0 C-k


Open line above: C-M-Enter

XKeymacs Mode:

Emacs does not have a single command to insert a newline above the current line. To perform this requires calling multiple commands: C-a C-o. However, VS has a command, Edit.LineOpenAbove, that inserts a newline above regardless of your location on the current line. This behavior is reminiscent of VIM's 'O' command.

In VS assign:
Edit.LineOpenAbove 
to
C-M-Enter
VS also has the command, Edit.LineOpenBelow, that inserts a newline below the current one. It is automatically bound to Shift + Ctrl + Enter. This is similar to Emacs' C-o command but does not drag the rest of the text after the point down to the newline. Instead, this behaves like the 'o' command in VIM. Unfortunately, although a handy shorter command, I rarely use this VS command since I am accustomed to doing C-e C-m to achieve the same functionality.

VS Emacs Scheme:

Follow the same steps as XKeymacs mode.


Swap point and mark: C-x C-x

XKeymacs Mode:

Suprisingly, XKeymacs does not support this command. Therefore, in Visual Studio assign the keybindings to the equivalent 'swap anchor' command:
Edit.SwapAnchor
to
C-k C-a 
Then in XKeymacs config file, '.xkeymacs':
...\xkeymacs347\etc\English (United States).xkeymacs
add line:
(fset 'exchange-point-and-mark "\Ctrl+k\Ctrl+a")
Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab  -> under Category 'Original Command'  ->
should now see new command, 'exchange-point-and-mark', in the list of commands
Under 'Press new shortcut key:', check 'Ctrl-X' -> in text field below it, press 'C-x' -> click 'Assign'
'Current keys:' list should now include 'Ctrl-X Ctrl-X'.

VS Emacs Scheme:

N/A. Works as expected.


List buffer: C-x C-b

XKeymacs Mode:
The ReSharper command 'View Recent Files' (C-,) reminded me of Emacs' list-buffers command. Therefore, thought I might bind Emacs' key shortcuts to it too.

In XKeymacs config file, '.xkeymacs':
...\xkeymacs347\etc\English (United States).xkeymacs
add line:
(fset 'list-buffers "\Ctrl+,")
Then configure
XKeymacs Properties -> select 'devenv.exe' -> 'Advanced' tab  -> under Category 'Original Command'  ->
should now see new command, 'list-buffers', in the list of commands
Under 'Press new shortcut key:', check 'Ctrl-X' -> in text field below it, press 'C-b' -> click 'Assign'
'Current keys:' list should now include 'Ctrl-X Ctrl-B'.

This is helpful to those who first learned Emacs before using ReSharper. I still generally use C-, since it is more convenient and I've been using that ReSharper command shortcut for a long time. However, nice to have alternatives there for consistency.

VS Emacs Scheme:

Follow same steps as XKeymacs mode.


Back to indentation: M-m

XKeymacs Mode:

Although C-a does a reliable of job of moving from anywhere on the current line to the first indention (i.e. first non-space character on the line), I am in the habit of using M-m to do that in Emacs. For example, I use it frequently when coding in Python using Emacs (indentation being core to the Python language) so mapping the equivalent VS command to M-m provides further consistency for me.

In VS, assign:
Edit.LineStartAfterIndentation
to
M-m
VS Emacs Scheme:

Unlike XKeymacs, C-a does not move the point to the start of the first (non-blank) character in the line but instead moves it to the beginning of the line. Therefore, binding M-m to Edit.LineStartAfterIndentation is extremely useful. So, follow the steps described in XKeymacs mode.


Join Lines: M-^

XKeymacs Mode:

XKeymacs does not have this command nor does Visual Studio. I hadn't really gave much thought about it until answering this question, does Visual Studio 2010 not have a “join lines” keyboard shortcut?, on StackOverflow. Truthfully, I don't find myself needed this when coding in C# with ReSharper but now that I made the effort to create a macro then it will now be included as part of my general keybindings configuration.

Essentially create a macro named something like "JoinLines" and I recommend using the code from my original answer since it behaves more like the Emacs version. The subsequent updated answer for joining lines follows more of the VIM equivalent.

Once the VS macro is created then assign the keybindings:
Tools -> Options -> Environment -> Keyboard -> in text field for 'Show commands containing:', type "JoinLines" and the new macro command should display. 
then assign this command to
M-^ 
This approach opens the door to creating other VS macros for missing commands in VS and are found in Emacs. Currently, join lines is one so I need to keep this mind next time when I need to port over some Emacs function to VS.

VS Emacs Scheme:

Follow same steps as XKeymacs mode.

Sunday, November 30, 2008

Speak to me...Interpreting C#

I came across A C# REPL (in Clojure) which discusses a means by which to interact with and run C# code via an interactive command-line by using Clojure and IKVM.NET . Now, Clojure I have heard of (a Lisp implementation that runs on the JVM) but this is my first time hearing about IKVM.NET (which I now know to be a .NET implementation for JVM). The post describes how combining these two technologies gives you the potential of working with a static language like C# in a way that is quite common in the world of dynamic languages such as Python, Ruby, Boo, etc.

Having an interactive code interpreter is a huge productivity boost. It allows you to easily run and test your code as you write and modify it while not needing to pay the dreaded compilation tax which can disrupt your development flow. This dramatically tightens and shortens the feedback loop on how well your code works ranging from whether it is behaving as intended for meeting spec requirements to much more quickly identifying any runtime bugs than you would using a development process common to traditionally compiled static languages. (As an aside, these are generally the same reasons that are given for creating and maintaining automated unit tests. Same goal but different methods.)

Not sure how well this C#/Clojure/IKVM.NET approach works or how well it realistically performs (typically, interpreted languages are slower). What is certain is that this unusual implementation requires the use of the very foreign-looking Lisp parentheses. I will openly admit as someone who does not program in Lisp it strikes me as kind of strange to use and see parentheses with C# but aside from this peculiar syntactical idiosyncrasy the general concept of REPL with C# overshadows even this oddity. This quote sums up its overall appeal in the world of C#:

A REPL is a Read-Eval-Print Loop, which is a fancy way of saying "an interactive programming command line". It's like the immediate window in the Visual Studio debugger on steroids, and its absence is one of the increasing number of things that makes C# painful to use as I gain proficiency in more advanced languages.

This is precisely how I felt when I initially started to learn and use Python. Suddenly, coding in C# with Visual Studio certainly seems to now be relatively more restrictive. Similarly, whenever I have had to touch any VBA code (yes, that does happen from time to time) I customarily inhabit the VB Editor's Immediate Window (IW) pushing its limits by attempting to use it in a manner that is similar to how I code in Python.

For example, in the VB language, not only is it not required to declare the data type of a variable but it is even unnecessary to explicitly declare the variables themselves (usually this is done using the 'Dim' keyword but this can be avoided by quite simply not including the 'Option Explicit' statement). Subsequently, the first time a value is assigned to a variable, the variable will automatically and implicitly be defined on the stack just like it does in Python. As a result, you can somewhat attain that same level of interaction with code in VB (via IW) as you would in Python (via its standard interpreter) potentially gaining the productivity benefits of writing less code in contrast to strongly typed languages.

My increased reliance of the Immediate Window also extends to Visual Studio when coding in C# but it requires more work and syntax overhead versus IW in the old VB Editor. Overall, it is not quite the same experience as in Python. Regardless, as I have previously written, frequent use of the VB Editor's IW led me to lean heavily on the one in Visual Studio whenever coding in C#. Prior to that, I had somewhat forgotten it even existed. In fact, in VS 2005, the IW sometimes is missing and difficult to view when not in debug mode (this is allegedly also true for VS 2008). This is discouraging as it probably contributes to most .NET developers not favoring its use in more situations.

While I have seen other attempts at providing an interactive console for C# the following are ones I have noted to possibly try out in the very near future:
I am extremely curious if (and hopeful that) Microsoft will provide an improved implementation for VS's IW when the more dynamic C# 4.0 becomes mainstream. (How long before we have an official C#Script? It worked for VB and VBScript.)

Saturday, September 13, 2008

Who needs a good text editor? I write perfect code

The first time I read Pragmatic Programmer (a future classic) it strongly emphasized that programmers choose one good text editor and learn it well. This got me thinking about how important a good text editor is if you write code for a living. I am of the school of thought that code is design. I want to increase the speed by which I write code so as to match my thoughts. Code is the concrete extensions of my thoughts on how to implement software. This means that code should be easy to manipulate and thereby be malleable and fluid in nature. Therefore, it makes perfect sense to me why the book discusses the virtues of using a good editor.

At the time of my first reading PP, my text editors were Visual Studio (the default IDE for .NET developers such as myself) along with the plain vanilla Notepad. Inspired by PP, I went on to use Notepad2 and then eventually moved on to the more robust and extensible Notepad++. However, I recently re-read PP because it is one of those book you need to keep referring back to make certain you are headed down the right path as a programmer. (Also, you tend to miss out on tidbits of good info due to faulty memory.) This time around I noted that one of the text editors they recommended was Emacs.

What is Emacs (and VI)?

After researching about Emacs, I immediately got the impression that this is one of the text editors that serious, hardcore programmers, may, I dare say, hackers use. If you want to become one of those (or at least aspire to) then you might as well use what those individuals use because they obviously must know something, right? Emacs has been around since the 1970's making it one of the oldest text editors with active development still current as of today (2008). So, once again, something must be good about it, right?

I noticed that another editor was consistently being referenced on most things I read about Emacs. That other text editor was VI (or VIM). Not surprisingly, just like a lot of things in the world of programming a long running rivalry exists between Emacs and VI. Now, unlike Emacs, I was, surprisingly, already familiar with VI since I had learned to use it in a technical class I took early in my career. Guess what? At the time, I hated it.

My dislike for VI centered on the fact that I was weaned on more modern text editors such as Notepad and other Windows applications that using VI felt so foreign to me. I could not understand how anyone could even be efficient with a tool such as VI. Why couldn't I simply use the arrows keys, delete key, etc.? Why must I memorize and use some other combination of keys? In addition, the mode switching also confused me which entails the fact that editing text was not quite the same as reading it.

VI reminded me too much of a word processing program I had used in the late 80's on my home PC (a Tandy if I recall). This made me view VI as being a relic that should no longer be needed in the modern world. Also, at the time (and prior to that) I hated having to learn and memorize command names and was not fully enamored with text-only, console-like environments (Microsoft did a really good job of making me dependent on GUIs and my mouse).

Of course, I no longer hold any of what I now consider to be quite ridiculous and silly attitude and opinions regarding VI. I have completely repented and now understand how deeply wrong I was. Hey, what do you expect from a newbie programmer back then?

Choosing a New Text Editor

Now, which one do I use? Emacs or VI? Truthfully, I really don't know. Just like most things each have their pros and cons.

However, I made my choice and decided to learn to use Emacs. I was swayed by the fact that Emacs as compared with VI has (1) so much more features (although might never use them all ;-) ) and (2) it is extensible. One long running criticism of Emacs (particularly from the VI community) was that it is very slow to load up and run (due to it using its own dialect of Lisp, an interpreted language and, as we all know, interpreted languages tend to be slower than compiled ones). Well, fortunately with modern systems this is no longer the case whatsoever (if anything more modern IDEs like Visual Studio are slow in comparison to Emacs)

Probably the most difficult thing to using Emacs at first will be the same reason why I originally did not like VI: learning all of its essential commands. But now it's different because I want to learn it because I fully understand it's rewards. It will indeed be tough at first but, from what I read, once you do (at least the basic ones) your productivity should start to increase. To me it will be no different than when I first started learning the fantastic Visual Studio add-in, ReSharper, a refactoring tool. With Re#, I made the very deliberate effort to learn the keyboard commands instead of relying on the mouse in order to code faster. Typically, this is now a very common approach I take with most new development tools and applications that I start to use. Learn to use as many key commands as possible.

One quick mention regarding setting up Emacs on Windows. If you want Emacs to be truly installed on your PC (meaning adding it to the Windows registry, adding a shortcut to your start menu, etc.) then I recommend running the file 'addpm.exe' found in the bin folder from the zipped file for Emacs . This is completely optional and you can obviously run and use Emacs without it. However, it does help to integrate it a bit more with your Windows environment.

Emacs and Visual Studio

The book "Pragmatic Programmer" seems to imply that a text editor should be your main IDE. However, primarily being a .NET developer my primary IDE is, of course, Visual Studio. Therefore, I can not truly have Emacs as my primary. If I did, I'd miss out on some the features built into VS such as Intellisense. But, my main problem is really missing out on the sheer power of ReSharper.

But, wait, not all is lost. Believe it or not, as it turns out, Visual Studio actually natively supports changing your key bindings to use Emacs! Now, I potentially might have the best of all worlds: VS + Re# + Emacs. Although VS does not obviously have all of Emacs' features, at least, I can continue to use and develop my Emac specific editing skills. Who knows? Since one of Emacs' greatest assets is extensibility it maybe possible to add some of the Re# features lacking into Emacs itself. (This would imply my learning ELisp but doubt it :-)) Perhaps some add-ins for Emacs already exist and I just have to find them.

It turns out that Emacs is not the only thing that can be supported by VS. In addition, I recall reading earlier this year how Jean-Paul S. Boodhoo started using VI with Visual Studio. (He also has some more recent posts on his experiences particularly VI with ReSharper) This was an early indication to me that perhaps maybe I was wrong about my opinion regarding VI and that it was, at the time, a very "green" programmer like myself just not understanding the power of a development tool and the inefficiencies of relying on a mouse. Perhaps down the road I might give VI a try as well.

I will certainly have future postings on my experiences with Emacs. In the meantime, I have to make sure to avoid "Emacs Pinky".