Handling Windows

A while ago I wrote about abo-abo's application of Hydra to switching windows. It was an idea apparently inspired by Sacha Chua's use of his def-rep-command to switch windows but went further to handle many chores involving windows and buffers. I had also recently written about John Kitchin's use of Helm to do the same sort of thing, and remarked that I really liked both methods but couldn't make up my mind as to which to implement.

Abo-abo's method seemed easier to implement so I decided to try it on an experimental basis. If I didn't like it, I could always try Kitchin's method instead. My version is almost the same as abo-abo's except I use x and y for vertical and horizontal splits and I added magit-status.

I've been using it for a couple of weeks and really like it. It definitely gives Emacs a further Lisp Machine feel. The Lisp Machine had a SELECT key that was used to initiate window operations and hydra-window has the same feel. It's really convenient how I can perform several operations in a row with one hydra invocation. For example, I can switch to another window, load an existing buffer or bookmarked file and switch back to the original window almost instantaneously.

I find that I now use bookmarks all the time whereas before I seldom did. It's so easy: invoke hydra-window, press 【m】, and then one other letter to bring up the file. A lot of my work flow involves the same set of files so this really speeds things up. It's faster, even, than just keeping the files open and switching to them with ido. I made this work better by stealing another idea from abo-abo and upgrading to bookmark+ and arranging to have distinct starting letters (or in some case 2 letters) for the bookmark names. That, with headlong-bookmark-jump means I can select a file with a single letter or two. I also added book marks to call Ibuffer and open Irreal in my browser.

It's startling what a different feel using this set up gives my Emacs workflow. Things just seem faster and smoother. The only problem I haven't resolved is how to invoke hydra-window. Currently【F1】, 【F10】, and【y y】 are all bound to hydra-window. I'm trying to determine what the best sequence to simulate the SELECT key is. I like【F1】 but dired+ steals it. I could probably remap that after dired+ is loaded but I'm finding 【F10】 more natural. I'll probably keep experimenting with different bindings for a while.

A final benefit is completely unexpected. For some reason, I have stopped fretting so much over open buffers.

This entry was posted in General and tagged . Bookmark the permalink.
  • glucas

    On what key to use.. I'm a big fan of using the function keys as prefixes, and binding common commands to double-taps of those keys. In practice I find that the difference between hitting and just is negligible, but the first approach leaves a lot of other bindings available. Even sequences like or are really easy to get under your fingers.

  • abo-abo

    I've got the same problem as you: I just can't bring myself to bind hydra-window/body to ";-n" since I'm just so used to ace-window being there. All the good bindings are taken.

    As for the function keys, I think F5, F8 and F9 are the best ones.

    • jcs

      I like hydra-window so much that I've given up calling ace-window directly. I had it bound to C-x o so any of the function keys is better. I used to use F11 but Emacs 24.4 stole that for full screen. I've been using F10 and have pretty much gotten used to that. Maybe F9 would be better. Perhaps I'll try it.

      In any event, thanks for hydra. It's definitely improved my life.

  • Damien Cassou

    Thanks for the post. Could you please give us what you came up with?

    • jcs

      You're asking about how I invoke hydra-window/body? I've pretty much settled on F10 but may try F9 as suggested by abo-abo.

      • Damien Cassou

        Sorry, no. I was asking about the definition of your hydra.

        • jcs

          Oh, OK. It's pretty much like abo-abo's but here it is:


          (defhydra hydra-window (:color red)
          "window"
          ("h" windmove-left)
          ("j" windmove-down)
          ("k" windmove-up)
          ("l" windmove-right)
          ("x" (lambda ()
          (interactive)
          (split-window-right)
          (windmove-right))
          "vert")
          ("y" (lambda ()
          (interactive)
          (split-window-below)
          (windmove-down))
          "horz")
          ("o" delete-other-windows "one" :color blue)
          ("a" ace-window "ace")
          ("s" ace-swap-window "swap")
          ("d" ace-delete-window "del")
          ("i" ace-maximize-window "ace-one" :color blue)
          ("b" ido-switch-buffer "buf")
          ("m" headlong-bookmark-jump "bmk")
          ("g" magit-status "magit" :color blue)
          ("q" nil "cancel"))