• Posts
  • RSS
  • ◂◂RSS
  • Contact

  • Shortcuts in Emacs

    January 21st, 2016
    emacs, tech  [html]
    When I chose a text editor, nearly fifteen years ago, I chose emacs because I liked the idea of using something that was deeply customizable. While I didn't intend to start using that customization immediately, it seemed to me like it would be much more future-proof to learn something flexible. I've never actually used this very much, but a couple weeks ago I wrote a new mode for the first time, so I thought I'd write that up.

    I keep my calendar as an html table, and every so often I go over it to move activities that have happened to the past. One could automate this completely, but I I like having an opportunity to review things and make fixes. So about five years ago I wrote a little function:

    (defun move-to-past ()
      (interactive)
      (setq debug-on-error t)
      (search-forward "<tr>")
          (beginning-of-line)
          (let ((mtp-killed-text
                 (delete-and-extract-region
                  (point)
                  (progn (forward-line 5)
                         (point)))))
            (find-file "~/jtk/past.html")
            (beginning-of-buffer)
            (search-forward "<tr>")
                  (beginning-of-line)
                  (insert mtp-killed-text)))
    

    This was easier than what I used to do: manually finding the line, pressing ctrl+k ten times, opening past.html, finding the right line, pressing ctrl+y. But it was still kind of annoying: I needed to type meta-x then move-to-p[tab][enter], and do this for each entry I was moving. It wasn't so annoying that I couldn't stand it, but it was irritating enough that I often put off moving things from future.html to past.html for months at a time.

    I wanted to make this easier to invoke, so that I could just press a simple keyboard shortcut and move the entry to the past. I had set shortcut keys before, like:

    (global-set-key "\C-xg" 'goto-line)
    

    This means I can type ctrl+g 53 and jump to line 53, which is great. Except this is a global shortcut, and if I set a nice short shortcut for move-to-past that would get in the way when I was in other contexts. I needed to make something that only applied to future.html, so I defined a new mode:

    (define-derived-mode procsched-future-mode
                         html-mode
                         "ProcScheduleFuture")
    

    So far, all this does is create procsched-future-mode, which is just an alias for the mode for editing html.

    Next we can define a shortcut that applies only to this mode:

    (define-key procsched-future-mode-map
                "\C-p" 'move-to-past)
    

    Now if I'm in procsched-future-mode and press ctrl+p, it will trigger move-to-past.

    Manually enabling procsched-future-mode mode is annoying, though, so I can set it to enable automatically for files named future.html:

    (add-to-list 'auto-mode-alist
                 '("future\\.html\\'"
                   .
                   procsched-future-mode))
    

    Now whenever I'm in a context when I would want to press ctrl+p for move-to-past it will just work, but ctrl+p is still available for other uses in other contexts.

    We can go a step farther, and define a few more useful things, so we can easily delete entries or switch back from past to future after moving something:

    (defun delete-event ()
      (interactive)
      (setq debug-on-error t)
      (search-forward "<tr>")
          (beginning-of-line)
          (delete-and-extract-region
           (point)
           (progn (forward-line 5)
                  (point))))
    
    (defun switch-to-future ()
      (interactive)
      (setq debug-on-error t)
      (switch-to-buffer "future.html"))
    
    (define-derived-mode procsched-past-mode
                         html-mode
                         "ProcSchedulePast")
    
    (define-key procsched-future-mode-map
                "\C-o" 'delete-event)
    
    (define-key procsched-past-mode-map
                "\C-p" 'switch-to-future)
    
    (add-to-list 'auto-mode-alist
                 '("past\\.html\\'"
                   .
                   procsched-past-mode))
    

    Now I can press ctrl+p to move something to past, then ctrl+p again to move back to future. Or I can press ctrl+o to delete the event if it didn't actually happen.

    This has made updating future a lot easier, and I've been doing a better job of updating it more often.

    Comment via: google plus, facebook, r/emacs

    Recent posts on blogs I like:

    Streaming the Biden Infrastructure Plan

    I streamed my thoughts about the Biden infrastructure plan, and unlike previous streams, I uploaded this to YouTube. I go into more details (and more tangents) on video, but, some key points: Out of the nearly $600 billion in the current proposal that is …

    via Pedestrian Observations April 11, 2021

    Collections: Clothing, How Did They Make it? Part IVb: Cloth Money

    This is the second half of the fourth part of our four part (I, II, III, IVa) look at the production of textiles, particularly wool and linen, in the pre-modern world. Last time, we looked at commercial textile workers and the finishing processes for text…

    via A Collection of Unmitigated Pedantry April 9, 2021

    Notes from “Don’t Shoot the Dog”

    I just finished Karen Pryor’s “Don’t Shoot the Dog: the New Art of Teaching and Training.” Partly because a friend points out that it’s not on Audible and therefore she can’t possibly read it, here are the notes I took and some thoughts. It’s a quick, eas…

    via The whole sky April 2, 2021

    more     (via openring)


  • Posts
  • RSS
  • ◂◂RSS
  • Contact