Approaching Productivity

2010-03-13 22:29:01

Time is scarce these days - and with no prospect of any extraordinary reduction in the number of tasks I need to work on my level of productivity. Here are some thoughts on getting more out of Emacs.



Preface

Productivity is many things, starting with the way we think, through the habits we end up adapting, to the tools we use. Many years of software development has made clear to me the effect of having a good IDE and I have thus defined 3 factors which greatly improve productivity and 3 factors which inhibit it.

The three factors which make you more productive:

Emacs Emacs Emacs

The three factors which slow you down:

Vim Vim Vim

A question which came up recently in #clojure was exactly that of editors, is Emacs the only way to go ? Answer: I'm not sure. Vim-Clojure is pretty powerful, but oddly enough it only works with Vim. For NetBeans we have Enclojure, which broke during installation of the latest version from Github, but I have previously had luck installing earlier versions. And finally there's talk of an IntelliJ plugin called LaClojure which looks very promising as well - If you're not approaching Clojure from an Emacs background, try out those 2 if Emacs is too big a mouthful.


Emacs

Emacs has a great pull on developers using all languages and it's no different for the Clojurian. Emacs has editing capabilities which aid producitivty quite a bit, but its primary pull comes from its vast integration capabilities with other systems. Here are a few key components of my setup:


Color-Themes

Normally there's not a lot to say about this - You have a number of themes to pick from, select one you like and thats it. Except for me its not. I use htmlize whenever I post code on this blog, meaning I mark a region in my blog, hit M-x blog and the code is converted to colored HTML which is then sent to my clipboard. That means when I change color-themes, the blog changes looks. Earlier today etate pasted a home-grown theme on #clojure which I immediately adopted:

(defun color-theme-dark-bliss ()
  ""
  (interactive)
  (color-theme-install
   '(color-theme-dark-bliss
     ((foreground-color . "#eeeeee")
      (background-color . "#001122")
      (background-mode . dark)
      (cursor-color . "#ccffcc"))
     (bold ((t (:bold t))))
     (bold-italic ((t (:italic t :bold t))))
     (default ((t (nil))))

     (font-lock-builtin-face ((t (:foreground "#f0f0aa"))))
     (font-lock-comment-face ((t (:italic t :foreground "#aaccaa"))))
     (font-lock-delimiter-face ((t (:foreground "#aaccaa"))))
     (font-lock-constant-face ((t (:bold t :foreground "#ffaa88"))))
     (font-lock-doc-string-face ((t (:foreground "#eeccaa"))))
     (font-lock-doc-face ((t (:foreground "#eeccaa"))))
     (font-lock-reference-face ((t (:foreground "#aa99cc"))))
     (font-lock-function-name-face ((t (:foreground "#ffbb66"))))
     (font-lock-keyword-face ((t (:foreground "#ccffaa"))))
     (font-lock-preprocessor-face ((t (:foreground "#aaffee"))))
     (font-lock-string-face ((t (:foreground "#bbbbff")))))))

Call that function from anywhere in your .emacs and you're set.


ERC

I've gone back and forth on this a lot, but today I've decided that having your IRC contacts directly in your buffers make sense, so I thought I'd share. To get started, grap ERC and add this to your .emacs:

(add-to-list 'load-path "~/.emacs.d/erc")
(require 'erc)

That will load the basic functionality. Then to set up ERC to track your nickname(s) do something like this:

;; Only track my nick(s)
(defadvice erc-track-find-face (around erc-track-find-face-promote-query activate)
  (if (erc-query-buffer-p)
      (setq ad-return-value (intern "erc-current-nick-face"))
    ad-do-it))

(setq erc-keywords '("Lau" "lau" "ljensen"))

(setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
                                "324" "329" "332" "333" "353" "477"))

That will also keep ERC from annoying you with JOINS/PARTS. Then as a little something extra, I added OSD notifications for all you Ubuntu users:

;; Use libnotify

(defun clean-message (s)
  (setq s (replace-regexp-in-string "'" "'"
  (replace-regexp-in-string "\"" """
  (replace-regexp-in-string "&" "&"
  (replace-regexp-in-string "<" "&lt;"
  (replace-regexp-in-string ">" "&gt;" s)))))))

(defun call-libnotify (matched-type nick msg)
  (let* ((cmsg  (split-string (clean-message msg)))
        (nick   (first (split-string nick "!")))
        (msg    (mapconcat 'identity (rest cmsg) " ")))
    (shell-command-to-string
     (format "notify-send -u critical '%s says:' '%s'" nick msg))))

(add-hook 'erc-text-matched-hook 'call-libnotify)

So now when somebody highlights you, you'll get something like this:

While chatting, people throw many links which don't exactly follow the http://www.dom.com syntax, so to agressively identify those links and make them clickable, add:

;; Be overly eager to identify URLs

 (setq erc-button-url-regexp
      "\\([-a-zA-Z0-9_=!?#$@~`%&*+\\/:;,]+\\.\\)+[-a-zA-Z0-9_=!?#$@~`%&*+\\/:;,]*[-a-zA-Z0-9\\/]")

I looted that from EmacsWiki and it seems to work, although I'd hate to debug it.

;; Enable logging

(setq erc-log-channels-directory "~/.erc/logs/")
(setq erc-save-buffer-on-part t)
(defadvice save-buffers-kill-emacs (before save-logs (arg) activate)
(save-some-buffers t (lambda () (when (eq major-mode 'erc-mode) t))))

That'll make sure you get everything logged correctly, so all we need to do now, is launch ship:

;; Launch

(setq erc-autojoin-channels-alist
      '(("freenode.net" "#clojure")))

(erc-select :server "irc.freenode.net" :port 6667 :nick "yournick")

There we go! Now you have Rich Hickey and the gang right in your favorite IDE and you can copy/paste snippets directly from #clojure to your REPL - Hows that for productive? If you really want to get going with ERC, make sure you stop by the EmacsWiki entry, especially the logging can be improved I think.


More?

If I had more time to blog about Emacs extensions, Org-Mode would be at the top of my list. Its a very powerful mode which lets to integrate task planning seamlessly with the rest of your business in Emacs, I recommend you check it out.

Regarding Raynes' quote, we were discussing meta-programming, namely macros in Ruby and seemed to be the case that Ruby macros are so far from Lisp macros, that claiming a connection is a stretch - any Rubyists who can elaborate on why Ruby is called a "Lisp chainsaw" ?

Avital Oliver
2010-03-14 02:59:57
Paredit for Emacs is a must-have! 

If you want to restructure a deeply nested function you're bound to mismatch parenthesis and find it hard to get your code working again... With Paredit you directly manipulate the tree structure of your code. It aways keeps parenthesis balanced (it actually doesn't allow you to remove a closing parenthesis!)

http://www.emacswiki.org/emacs/ParEdit
Scott
2010-03-14 07:03:08
Hey Lau,

Glad to see another post.

I think your "vim vim vim" comment is lacking a clearer sign of kidding, such as a smiley face :)

LaClojure has been out for a while, and there's also counterclockwise for Eclipse. Both are actually quite good.

There are probably more color themes for vim than for emacs. I believe in some ways it also has better editing commands (like scrolling by front of word or end of word, obviously programmable in emacs but probably non-existent in 99% of .emacs files).

I liked your ERC configs, especially the notifications on Ubuntu. The biggest problem I have w/ ERC is that it's nice to run an IRC client on a remote shell account in screen that will stay connected throughout laptop suspends, machine switching, and network outages, and I think ERC loses its advantages when running in a remote terminal session instead of my main local graphical Emacs.
Anders Olme
2010-03-14 08:38:40
Never done much in emacs myself ( use mostly vim ) . But Im in search of a new editor since I cant get vim to format hmlt code that contains css and javascript correctly ( eclipse will do it right but it feels abit heavy for this type of job ). Is there a good html formatter for emacs that works on both windows and mac?

//olme
Lau
2010-03-14 08:54:07
@Avital: I have no problem writing Lisp w/o paredit - in fact I love it ! :)

@Scott: I think a smiley in the Vim section would take away from the seriousness of the matter.... Just kidding :)

You can still run ERC remotely, though I agree that anything Emacs is best leveraged locally.

@Anders: Is there a good (???) for Emacs which works on Windows and Emacs? The answer is <strong>Yes</strong>! Anything you want to test should take only a few minutes, install Emacs and open the type of file you want to edit. Html support is built-in but modes like Clojure/Ruby/Haskell modes need to be installed manually or via <a href="http://tromey.com/elpa/install.html" rel="nofollow">ELPA</a>.
Anders Olme
2010-03-14 09:34:37
Mm just tried my html file which contains both html, css and javascript but M-x indent-region  put all code at the right most column ( bit better than vim which freaks out completly ). Guess it is not kosher to mix all in one file but im trying to learn javascript so thats why all are in the same file.

code looks like this:



#throbber-container {
border: 1px solid lime;
height: 16px;
width: 16px;
}

div.throbber img {
background-color: lime;
}

#div {
background-color: lime;
height: 32px;
width: 32px;
}









Anders Olme
2010-03-14 09:35:37
Ah all html codes got stripped out in this one and only the css where left :)

//olme
Nurullah Akkaya
2010-03-14 12:00:43
@anders, by default emacs does not allow multiple major modes for the same buffer, there are however extensions that change major modes as you scroll the file, you can check out, http://www.emacswiki.org/emacs/MultipleModes
danlei
2010-03-15 04:42:38
Thanks for mentioning gist integration, I wasn't aware of gist.el. Very nice.

I second Avital's suggestion to check out paredit, even if you don't suffer from mismatched parenthesis (neither did I), it's pretty nice for navigating and editing. It really takes some time to get used to and really benefit from it, though.
Laurent Petit
2010-03-15 10:05:13
Hello Lau,

Except if you've done a thourough (as in "scientific") study of the subject, please
s/The three factors which make you more productive/The three factors which make me more productive/
and
s/The three factors which make me less productive/The three factors which make me less productive/

This is a matter of intellectual honesty !

Oh, and BTW, how come you forgot to mention Eclipse as a platform? You know, there is a bunch of users still using it today :-).
(ok, I'm biaised since I've taken the task of writing the clojure plugin for it :-) ).

And BTW (2), shameless plugin: the long awaited auto-indentation feature in ccw (please do not laugh at me for not having produced it already -time is scarced- :-) ), is around the corner.
Laurent Petit
2010-03-15 10:06:24
OK, I'll s/// myself:
s/shameless plugin/shameless plug/ 

:-)
Lau
2010-03-15 10:30:52
@Laurent: People, don't make too much of the Emacs Vs Vim dispute, its just a matter of Vim being a text viewer where you can enter the special 'insert mode' to actually write code, and Emacs on the other hand being geared for coding. :)

Regarding my lack of mention of your plugin is entirely my fault and I'll remedy ASAP, sorry! I'm sure that you've cooked up something great.

/Lau
Sean Devlin
2010-03-18 15:49:24
Okay, here's a question.  How do I get the coloring of clojure-mode to work in my inferior lisp buffer?  I'd love to have my repl auto-highlight.
Lau
2010-03-18 16:55:17
Sean did I read you right? You wanted highlighting in *inferior-lisp* and not the slime repl ?
Ruben Berenguel
2010-03-30 13:11:38
I'm glad I found your blog through the functional fluid dynamics post. I always love to find more emacs advocates out there ;)
jeekl
2010-03-30 13:52:42
@Scott: I have an IRC bouncer (znc, http://en.znc.in/wiki/ZNC) set up that connects to all my IRC-channels, then from any client I want, I can connect to my bouncer, which will keep me connect, and give me all the history that has happened since I last connected, from anywhere. This means I can connect to my bounxer from ERC and just be right back where I left off.