Emacs and Unity Every Day

As I may have mentioned before, I like using Emacs. When working on Fable we were of course entirely based around the glorious Visual Studio, since the XBox and the 360 required it, and I started out using Emacs largely for editing Python and Lua code; we used those languages for various tools and scripting duties and Visual Studio at the time didn’t have very good support for ‘other’ languages. Gradually I drifted into using org-mode, then into eshell, and eventually I got to the point where I started missing certain features in other editors. Yes, even the glorious Visual Studio.

These days I’m working on a Mac, using Unity. I tried to use MonoDevelop but found it to be slow and clunky, and not being able to view two files at the same time was very frustrating. Eventually I switched entirely over to using Emacs. It wasn’t easy at first, and I still lament the lack of a decent autocompletion system, but in general I’m very happy with the workflow.

You don’t spend numerous years using Emacs without picking up a few customisations and I thought it would be worth documenting a few of the ones I use most often. If anyone finds it useful, I might dip further into the recesses of my dotemacs file.

So, here we go; Emacs things that I use every day.

Evil mode
evil-mode is a fabulous vi emulation layer in Emacs. I’m pretty new to it, and I originally turned to it in a last ditch attempt to cope with some RSI issues I’d been developing (at this point I have probably bought pretty much every ergonomic keyboard in existence). I’m not sure if it helps the RSI, but it has certainly helped my coding speed. A side benefit is that, while Emacs is incredibly flexible, it’s very easy to run out of keybindings for all your custom functionality. Evil-mode and it’s modal system largely makes that problem go away.

Ace jump
Inspired, I believe, by a vim plugin called from Easy Motion, ace-jump allows you to jump to any character on screen in (usually) 3 keypresses. It’s a little difficult to explain how, so I’ll skip straight to a demo of it in action. I hit space (my personal activation key in evil-mode), select a character to jump to (in this case ‘p’). Ace-jump highlights every ‘p’ there is and gives it a unique letter. I choose the one I want (in this case ‘n’) the character jumps to the correct location.
acejump_anim2

In that particular example, I’m jumping to any character on the screen which can create alot of hits, but there are other ways to call it which only highlight characters at the beginning of words.

It’s looks a bit mental at first, but once you’ve used it there’s no going back.

Mark Multiple
Another toughie to describe in text, mark-multiple allows you to select a section of text and then select further matching sections and edit them all simultaneously. If you’ve ever used Sublime Text you’ll be familiar with it. Here’s an example:

mm_anim2

Here I hit v to select the terminating semi-colon, M-j to select further semicolons below, c to change the selection, and then type in the new code. There are other ways to achieve the same thing, of course, but mark-multiple is nice and tactile.

Helm

This used to be called ‘Anything’, and it’s essentially a generic quick jump system for Emacs, and it’s easily extended. For example, I have a simple custom project management system to allow me to easily compile projects, select which files go into a tags file, etc, and I use Helm to select files anywhere in my project, regardless of whether or not they are already open. Again, a simple example should suffice:

helm_anim2

In this I hit C-x f to trigger the helm file finder, and type in part of the file I’m looking for. It shows files in my project, recently accessed files, open buffers; once I’ve narrowed down the selection enough I can then select using the cursor keys and hit enter to select the file.

Yasnippet
Alot of coding is repetitive stuff, and TextMate’s ‘snippets’ innovation was a great way of tackling some of the more tedious bits. The canonical Emacs implementation, yasnippet expands on that, allowing you to create very some very sophisticated code templates. Previously I’ve struggled to get it in my workflow – remembering the exact trigger phrase for an expansion never worked for me, and autocompletion often got in the way. I’ve recently discovered that you can trigger a snippet manually, however, and then use fuzzy-matching via ido┬áto choose the right snippet. Example below:

yasnippet_anim2

In this example I’m hitting C-c s to trigger yasnippet, typing ‘fore’ to find the foreach expansion and hitting enter – it creates the skeleton and then I tab through the editable sections, filling them in as I go, with the last tab placing me in the braces. When you’re spending all day writing classes with conditions and loops and methods, this can be a big time saver.

Flymake
Something you may have noticed in one or two of the examples above is that I get syntax errors highlighted on the fly. This is the magic of flymake, which continually compiles the project in the background. I’ve got it hooked up with and a script to compile the Unity project, and it makes for a very smooth Unity coding experience. Errors underline in red as you type, the error message shows up in the minibuffer when you move the cursor into position, and it disappears when you fix it. Hardly revolutionary, but a nice productivity boost. It also seems to catch more genuine issues than the ‘on-the-fly’ error checker built into MonoDevelop, which is nice.

Shaderlab mode
Shaderlab-mode is a custom mode for editing shaders for Unity. It’s relatively basic, but it handles syntax colouring and indentation, which is all I really care about.

Wrapping it up
The upshot of this is that I spend 90% of my day in Emacs – from the start of the day when I check my todo.org list of tasks, to the edit-compile cycle for csharp, to editing shaders; I rarely leave Emacs, and when I do it’s usually just to tab on over to Unity to test out my changes.

I believe all of these extensions are available via ELPA, in marmalade or milkbox. Regardless, pulling it all together can take a little time, so I thought it might be worth sharing the details of how that’s done in my config. I’ve cobbled alot of this from various places on the intermawebs, notably http://dnquark.com/blog/2012/02/emacs-evil-ecumenicalism” title=”here”>here and here.


(require 'evil)

;;This gives you all the normal Emacs editing commands when in insert-mode
;;This eases the transition somewhat.
(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 [escape] ‘evil-normal-state)

;;Not sure why, but semicolon started misbehaving for me when in insert mode.
(define-key evil-insert-state-map (kbd “;”) ‘self-insert-command)

;;Make evil-mode up/down operate in screen lines instead of logical lines
(define-key evil-normal-state-map (kbd “j”) ‘evil-next-visual-line)
(define-key evil-normal-state-map (kbd “k”) ‘evil-previous-visual-line)

;;Exit insert mode by pressing j and then k quickly
(setq key-chord-two-keys-delay 0.2)
(key-chord-define evil-insert-state-map “jk” ‘evil-normal-state)
(key-chord-mode 1)

;;If you work in camelCase or use underscored_names, this is very helpful
(evil-define-motion evil-little-word (count)
:type exclusive
(let ((case-fold-search nil))
(forward-char)
(search-forward-regexp “[_A-Z]\\|\\W” nil t)
(backward-char)))

(evil-define-motion evil-little-word-backward (count)
:type exclusive
(let ((case-fold-search nil))
(backward-char)
(search-backward-regexp “[_A-Z]\\|\\W” nil t)))

(define-key evil-normal-state-map (kbd “, b”) ‘evil-little-word-backward)
(define-key evil-normal-state-map (kbd “, w”) ‘evil-little-word)
(define-key evil-operator-state-map (kbd “, w”) ‘evil-little-word)
(define-key evil-operator-state-map (kbd “, b”) ‘evil-little-word-backward)

;;Not sure why this isn’t the default – it is in vim – but this makes C-u to go up half a page
(define-key evil-normal-state-map (kbd “C-u”) ‘evil-scroll-up)

;;Allow quick manual triggering of snippets
(define-key evil-normal-state-map (kbd “C-c s”) ‘yas-insert-snippet)
(define-key evil-insert-state-map (kbd “C-c s”) ‘yas-insert-snippet)

;;Toggle comments
(define-key evil-visual-state-map (kbd “, c”) ‘whole-line-or-region-comment-dwim)
(define-key evil-normal-state-map (kbd “, c”) ‘whole-line-or-region-comment-dwim)

;;Easy access to the mark multiple library when in visual-mode
(define-key evil-visual-state-map (kbd “M-j”) ‘mark-next-like-this)
(define-key evil-visual-state-map (kbd “M-k”) ‘mark-previous-like-this)

;;Ace jump stuff. Honestly, I just use Space 99% of the time
(define-key evil-normal-state-map (kbd “SPC”) ‘ace-jump-char-mode)
(define-key evil-normal-state-map (kbd “, , w”) ‘ace-jump-word-mode)
(define-key evil-normal-state-map (kbd “, , c”) ‘ace-jump-char-mode)
(define-key evil-normal-state-map (kbd “, , l”) ‘ace-jump-line-mode)

(define-key evil-operator-state-map (kbd “, , c”) ‘ace-jump-char-mode)
(define-key evil-operator-state-map (kbd “, , l”) ‘ace-jump-line-mode)

;;Personally I like ace-jump to be limited to the window I’m working in
(setq ace-jump-mode-scope ‘window)

;; Remap org-mode meta keys for convenience
(mapcar (lambda (state)
(evil-declare-key state org-mode-map
(kbd “M-l”) ‘org-metaright
(kbd “M-h”) ‘org-metaleft
(kbd “M-k”) ‘org-metaup
(kbd “M-j”) ‘org-metadown
(kbd “M-L”) ‘org-shiftmetaright
(kbd “M-H”) ‘org-shiftmetaleft
(kbd “M-K”) ‘org-shiftmetaup
(kbd “M-J”) ‘org-shiftmetadown))
‘(normal insert))

(evil-mode)

Most of that should be self explanatory with the comments. One thing to mention is that this makes use of the excellent keychord.el and comment-dwim both also available via ELPA repository. Keychord allows you to combine arbitrary keypresses into triggers, and it’s what allows the ‘jk’ trick above. There’s lots of other stuff I use too – org, nav, bm, window-number, winner – and lots of personal customisations, but I’ll leave those for another day.

The main thing I really miss is proper ‘correct’ autocompletion for C#, which Visual Studio spoiled me with for years. Someone has created a plugin for Sublime, called CompleteSharp, which uses a standalone commandline program to load up your assemblies and provide completion information, and I’m sorely tempted to write some Emacs hooks for it. If only I had the time…

About these ads

11 thoughts on “Emacs and Unity Every Day

  1. Pascal

    Hello. Nice. I am now using Emacs for the last half year, trying everything there is. Not “understanding” a.k.a. seeing use for Helm though I used it a little. LOVING Emacs + keychords and yasnippets, and using own macros and what not, I mostly use Emacs for LaTeX and R (and noob at elisp).
    I personally don’t use Ace Jump (though I have it), I linked it to “dv” keychord, but I never use it. I sometimes use my inbuilt laptop mouse. You can only use Ace on the stuff that’s on the screen so I think on a laptop there is no gain there. If you look for something specific you’d just C-s to it. If I want to be on a position I’d move to it or mouse to it. Oh and in case you just have mark-multiple, try to look for expand-region, that one is great as well.
    Now I would be interested in also including the “must haves” from Vim, where should I start?

    Reply
    1. Pascal

      Wanted to expand on how I use mark-multiple and expand-region together. C-’ makes the region bigger, C-” (which is C-S-’) makes the region smaller. Then I have C-. to move to the next item, and C-, to the previous item. You can then start typing over them, or, if you want multiple cursors, I use C->. Personally some of my nicest combinations. Another nice thing is to have a keyboard macro to “xk” where it inserts the code for the last keyboard macro at point, named. I use “qx” to close emacs without asking for save, I use “jj” to send things to the R buffer, I use “hf” to output a PDF in AuCTeX (first saves, then output). Oh and I use “qs” to save the bookmark in and use “qg” to go back to last bookmark. very useful :)

      Reply
      1. bbbscarter Post author

        Ah yes, I would very definitely use expand-region if I weren’t using evil-mode; manipulating stuff by semantic units is such a wonderful idea, I often wonder why it’s not a more core part of Emacs. I even ended writing something myself, based off textobjects.el before shifting over to evil.

        I should also add that mark-multiple has now been superseded by multiple-cursors, written by the same (clearly very smart) chap.

    2. bbbscarter Post author

      Hi Pascal. Thanks!

      I think, for me at least, ace-jump is useful because I treat it the same way as a mouse click, with paging up/down being like the mouse scroll wheel. Usually I don’t know quite what it is that I want until I see it, so I C-u/C-d to page up/down, and then space- when I see what I want. It keeps your hands on the keyboard, which is the main advantage for me.

      I don’t think I use a tenth of Helm’s functionality. I literally use it as a project file quick jump and that’s about it. But, as quick jump, it’s perfect.

      As for Vim, I’ve played around with that a little bit recently. Easymotion, Nerdtree, Ctrl-p and vundle were quick favourites. Ultimately, though, once I found that evil-mode brought vim bindings to Emacs I found it easier to stick with that.

      Thanks!

      Simon

      Reply
  2. Pascal

    Interesting. Based on your blog I wrote a small mode for Emacs, only simple stuff, but it could possibly be some kind of “vim” concept. Maybe you could tell me what would be nice additions for this mode; also to help me understand Vim better (and possible gains in that department). The way I see it is that it seems very fluent because of 1 hit keystrokes. I am not used to the whole modal idea, but I tried to use it.
    Maybe could you take a look at my mode? I called it Navi-mode, since it’s supposed to some kind of Vim normal mode.

    Notable: For incremental search, ido-find-file, ido-switch-buffer, zap-to-character, ace-jump it kicks you out of the “Navi-mode”, allowing you to type.
    All these things still allow us to use all Emacs functionality while shortcutting everything for navigation and editing (still need to add a bunch of things for paragraphs). I linked the mode-trigger to the keychord ” ii “, since this was very convenient.

    Could you give it a try?

    (require ‘navi) in .emacs,
    (key-chord-define-global “ii” ‘Navi-mode) also somewhere.

    https://dl.dropbox.com/u/57478751/navi.el

    Please let me know and tell me what awesomeness is missing that Vim could bring!

    Kind regards,
    Pascal

    P.S. I also use multiple-cursors, but most of the time you don’t need it. I got it bound to C-> though.

    Reply
    1. Pascal

      Oh and I put SPC to be the ace-jump-mode. In case you didn’t notice, in that mode it’s not possible to type :)
      My plans to add are:
      1) Put word under cursor into register “N” for some key.
      2) Put paragraph under cursor into register “N”.
      3) Output register “N” at point.
      This way it doesn’t conflict with the kill-ring.
      Thoughts?

      Reply
  3. SimonG

    Hi Simon,
    Any hints on how to persuade flymake to build a unity c# project on OSX would be well appreciated (I admit, I’ve not looked/tried at all – found your blog post whilst googling for the same).

    Cheers – another Simon

    Reply
    1. SimonG

      Come to think of it, hints might be too much trouble – happy to try and decode whatever elisp you have if that’s easier – I’m well aware that too many years of emacs can make for lots of dependencies in personal configs making ‘em hard to share.

      Reply
      1. bbbscarter Post author

        Sure!
        It actually wasn’t too hard, though I’m not sure I did it ‘correctly’. The main work was:
        - In csharp-mode.el, hacking the compile command so I could override it myself.
        - Also csharp-mode.el, hacking in a mono-compatible error parser regexp.
        - Making my Unity build python script handle flymake passing in a temporary source file, and excluding the ‘original’.

        I might do a blog post on it in the near future, but in the meantime feel free to lob me your email address and I can send you what I have.

        These days the only thing I miss is accurate code completion, so if you have any ideas… :)

        Simon

      2. SimonG

        Cheers Simon, that’d be greatly appreciated. I’m struggling to spot a private way to actually contact you directly with my address – am I missing something obvious? The email details associated with this and my other couple of posts are valid, if WordPress lets you get at that?

        No ideas on code completion (yet), I’m just bumbling along with a random mixture of dabbrev-expand, hippie-expand and my crumbling grey matter.

      3. bbbscarter Post author

        Ah, yes, I don’t think I’d done a particularly good job of setting up my wordpress account. There should be plenty of options now!

        I’m quite fond of company-mode myself, and I’ve worked out a way of getting all of Unity’s API pumped into ctags, but the lack of proper scoping makes it a bit… noisy. I’ve been playing around with the idea of porting Complete-Sharp from Sublime Text to emacs, but I have had the time yet…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s