Running Ping in Emacs

Last year I wrote about my delight in discoverying the Emacs Net Utilities. It's nice to be able to run a quick ping, traceroute, or even some of the other network utilities right from Emacs. I've found, however, that there is a psychological barrier to using them. When you do a ping (or whatever) it opens a new window and leaves it and the corresponding buffer hanging around until you clean them up. That's not much of a barrier, of course, but it is enough that I found myself using the terminal instead. Silly, I know, but there it is.

Of course, this is Emacs so I can have it my way. I decided to run ping and traceroute alone in the frame using the strategy suggested by Magnar Sveen for Magit. I wanted to see the output and then be able to press 【q】 to destroy the buffer and restore the previous window configuration. It's hard to see, I know, how this is much easier than simply typing 【Ctrl+x k】 to cleanup but it seems like it is to me and you do end up with everything the way it was before you started, which may or may not be true of just killing the window.

It's a bit trickier than for magit because there's no quit function: ping just runs and then leaves the buffer in place. Also, there's no convenient keymap to hook into. My first try was to wait on a keypress using read-key with a prompt of "Press any key to continue" but that was too ugly. For one thing, you couldn't temporarily switch away from the buffer or doing anything else requiring keyboard input.

I finally settled on establishing a temporary keymap where 【q】 causes a separate function to be called that kills the buffer and restores the old configuration. Once I figured out what I wanted to do, the code was pretty simple:

(defun net-utils-restore-windows ()
  "Restore windows and clean up after ping."
  (interactive)
  (kill-buffer (current-buffer))
  (jump-to-register :net-utils-fullscreen))

(defadvice net-utils-run-program (around net-utils-big-page activate)
  (window-configuration-to-register :net-utils-fullscreen)
  (let ((buf ad-do-it))
    (switch-to-buffer buf)
    (delete-other-windows)
    (set-temporary-overlay-map
      (let ((map (make-sparse-keymap)))
        (define-key map (kbd "q") 'net-utils-restore-windows)
        map))
    (message "Type \"q\" to restore other windows.")))

This only works with ping and traceroute because the other network utility functions call a different display routine. I could do essentially the same thing for them but I virtually never use them so I didn't bother.

This isn't a big thing, of course, but it does reduce my workflow friction a bit so it's a win for me. And, of course, it demonstrates once again how flexible and extensible Emacs is.

This entry was posted in Programming and tagged , . Bookmark the permalink.