It’s been a while since I posted here – not because I have nothing to write about (after all, the world is full of interesting stuff!), but because of lack of time. Today I decided to share a little Elisp hack. I’m tired of pressing
C-x C-b RET to switch between two buffers I’m working on (and I don’t want to have two windows open very often on a small netbook). Also, I’m tired of accidentally hitting
C-z (OK, that does not happen very often, but still –
C-z is basically useless, especially that
C-x C-z does the same). Anyway, I decided to do something about it. Here’s what I have now in my
(define-prefix-command 'ctl-z-map) (global-set-key (kbd "C-z") 'ctl-z-map) (global-set-key (kbd "C-z C-c") 'compile) (global-set-key (kbd "C-z C-b") 'switch-bury-or-kill-buffer) (defun switch-bury-or-kill-buffer (&optional aggr) "With no argument, switch (but unlike C-x C-b, without the need to confirm). With C-u, bury current buffer. With double C-u, kill it (unless it's modified)." (interactive "P") (cond ((eq aggr nil) (switch-to-buffer (other-buffer))) ((equal aggr '(4)) (bury-buffer)) ((equal aggr '(16)) (kill-buffer-if-not-modified (current-buffer)))))
(BTW, this also binds
C-z C-c.) Now I can press
C-z C-b to switch to the
other-buffer (so basically, I can easily cycle between the last two buffers),
C-u C-z C-b to bury the current buffer (very useful, especially when clocking in Org-mode, for instance), and
C-u C-u C-z C-b to kill the current buffer (but only if it’s not modified).
Note also that I had a problem with naming the argument to
switch-bury-or-kill-buffer. Finally, I decided that “
aggr” (as in “aggressiveness”) is a good idea: the least aggressive variant (no prefix argument) just punches the current buffer a bit, so that it falls behind the next one; the more aggressive one punches it stronger, so that it falls at the end of the buffer list; and the strongest one just kills it.
In his excellent introduction to Magit, Mickey Petersen does a great job of explaining basics of Magit workflow. If you haven’t heard of Magit, it is a fantastic frontend to the Git DVCS, written on top of the Emacs environment. The entry point to Magit, which is
magit-status, is not bound to any key by default, so after switching to Git and Magit, I bound it to (previously undefined)
C-x g. But when I was reading Mickey’s article, one thing struck me. Mickey says that
If you’re a user of Emacs VC then you must know that, frustratingly, Magit makes no effort to integrate itself into Emacs’s VC (Version Control) abstraction layer.
That’s right – and it’s a pity. Since before using Git I used Mercurial a lot (and I still do), and even earlier I used RCS (yes, I know, I know; but in fact, for single-user, single-directory and often single-file LaTeX projects, RCS does its job just fine), I did use Emacs’ VC a lot. And now, with Magit,
C-x v v is useless for me in Git repos. I don’t want to rebind it to
magit-status, since I have a lot of Hg repos I still use, and I need
vc-next-action for them, I put this in my
(defun magit-status-or-vc-next-action (arg) (interactive "P") (if (eq (vc-deduce-backend) 'Git) (magit-status default-directory) (vc-next-action arg))) (global-set-key "\C-xvv" 'magit-status-or-vc-next-action)
Of course, I lose the possibility of using
magit-status with prefix arguments with this simple setup, but it’s not a problem for me; for switching between projects, I’m fine with
C-x C-f (and Ido), and for setting up a new repo,
M-! git init is good enough for me. So now I have a single entry point to both VCs I use.
Of course, this is rather simplistic. And maybe it’s not that good idea, to; maybe it would be better to use Emacs’ VC for simple Git/Hg actions, and use e.g.
C-x g for
monky-status depending on the VC used (I have yet to try Monky). I’ll try different things, and time will tell.
Sometimes I wish AUCTeX had a function similar to
search-forward, but looking only at math mode and skipping everything outside it. Well, here it is. Note: this is a very simplistic implementation, since if the given string appears between the point and end of the buffer, but only in text mode, it will jump there anyway. I’ll probably make it behave better someday, but since it is rather a quick hack, I’ll leave it this way for now. (Also, an isearch switch to look only at math or text mode would be nice. I’ll definitely look into it, too.)
(defun TeX-search-forward-math-mode (string) "Search forward for STRING, but only in (La)TeX math mode. Crude implementation: if found in text mode, but not math mode, it will move the point there." (interactive "MSearch in math mode: ") (while (progn (search-forward string) (not (texmathp)))))
What is especially nice about this is that it took me about 5 minutes to put this together, and more than half of that time was checking the
interactive syntax (again…). This is what “extensibility” means: not only it is possible to extend Emacs’ capabilities, but it is easy and fast to do so.
A non-math version (as well as regex-searching analogues) are left as easy exercises for the reader.)
(Więcej means More in Polish; click it to see older entries.)