2010-06-30

console apps in emacs with multi-term

multi-term

updated Whenever it makes sense, I try to use emacs for my computer-based activities; surely, programs like The Gimp or a graphical web browser cannot yet be replace by emacs, but I'm making progress. I like the ways emacs gives me to automate and speed-up my tasks; I get some return-on-time-investment.

2010 or not, I still spend quite a bit of time on the console. So why not do that from within emacs? There different ways to run shells within emacs.

The simplest one is shell (i.e,, M-x shell), which starts a simple shell, which does not support which does not support 'graphical' console applications, such as mutt, mc, htop.

Then there are term and ansi-term (M-x ansi-term) that do support such applications, which ansi-term supporting colors as well (it seems to have become the default for term in recent emacs versions).

Another one is the nifty EShell (included with emacs), which is not just a (simple) terminal, but also a full shell environment, and has integration with other things in emacs. It's nice, but has some of the limitations that shell has - you cannot run 'graphical' applications; also, I don't really need a shell, as I am quite happy with zsh (zed shell) already, which is more powerful, and I prefer a shell that works both inside and outside emacs.

For all these reasons, I am using MultiTerm, which has 'graphical' support that ansi-term has, but adds a nice extra, namely support for multiple terminals within emacs. I'm not fully up to date with the exact difference in the terminal support between the two, but I haven't had any problems so far.

You can install multi-term (put it in your load-path), and add the following to your .emacs:

(autoload 'multi-term "multi-term" nil t)
(autoload 'multi-term-next "multi-term" nil t)

(setq multi-term-program "/bin/bash")   ;; use bash
;; (setq multi-term-program "/bin/zsh") ;; or use zsh...

;; only needed if you use autopair
(add-hook 'term-mode-hook
  #'(lambda () (setq autopair-dont-activate t)))


(global-set-key (kbd "C-c t") 'multi-term-next)
(global-set-key (kbd "C-c T") 'multi-term) ;; create a new one

With this, C-c t will jump through your multi-term buffers (create a new one if it doesn not exist yet), while C-c T unconditionally creates a new terminal.

2010-06-17

automatic pairing of brackets and quotes

Some text-editors, notably TextMate for MacOS, have a nice feature where inserting a opening ( will automatically insert the closing ), and put the cursor in between them (and does same for [], {}, and various quote-marks).

Not surprisingly, there are some implementations for emacs as well; the best one I have found so far is called autopair, which was written by João Távora. It usually does things just right. Do things 'just right' is essential for such a tool; even small annoyances can disturb your flow. Autopair tries to do whatever makes the most sense for a given mode (programming language etc.), but it can be tuned as well.

After installation, you can automatically activate it for all modes with (in your .emacs):

(require 'autopair)
(autopair-global-mode 1)

Now, evaluate this or restart emacs, and enjoy the autopairing-magic!

Except for autopairing, autopair also takes care of autocleaning; that is, if I press ( it turns that into () (the pairing part), and if I press Backspace then, it removes the whole () (the cleaning part). This makes things much less annoying if you type a pair by accident. Autopairing is the kind of thing that can get annoying quickly if it does not things exactly right – and autopair succeeds!

Another nice trick it offers is autowrapping – that is, I select a word, press ", and automatically it's turned into "word". To enable that, you need to add the following:

(setq autopair-autowrap t)

Note: you might want to see the notes below about delete-selection-mode and cua-mode.

Anyway, autopair with autowrap makes for a really smooth editing experience, I love it! There are two small issues for me though. First, when the cursor in front of some non-whitespace, I'd like autopairing not to happen, and second, somehow I can't seem to get "-autopairing to work in org-mode; of course, that could be my own fault. These things might be tunable; I haven't tried very hard yet.

delete-selection-mode

Important to mention here is that autopair is (by default) not fully compatible with delete-selection-mode. As you may know, that is the mode that causes emacs to replace the current selection with a character typed, similar to what most other programs do. I think many people have it enabled in their .emacs with something like:

(delete-selection-mode 1)

If you want to keep on using that together with autopair, add the following to your .emacs:

(put 'autopair-insert-opening 'delete-selection t)
(put 'autopair-skip-close-maybe 'delete-selection t)
(put 'autopair-insert-or-skip-quote 'delete-selection t)
(put 'autopair-extra-insert-opening 'delete-selection t)
(put 'autopair-extra-skip-close-maybe 'delete-selection t)
(put 'autopair-backspace 'delete-selection 'supersede)
(put 'autopair-newline 'delete-selection t)

But, not that that still won't give you the autowrap behavior mentioned above. For that, we can use cua-mode.

cua-mode

We discussed CUA-mode before, focusing on its nice rectangle-editing features. But CUA-mode can also be an alternative for delete-selection-mode, and it goes together more nicely with autopair; so, instead of delete-selection-mode and the put's, add the following to your .emacs:

(setq cua-enable-cua-keys nil)           ;; don't add C-x,C-c,C-v
(cua-mode t)                             ;; for rectangles, CUA is nice

See the linked CUA-mode article for the 'why' of that first line. With this change, autopair should be working smoothly, including autowrap.

further customization

As I have hinted at, autopair can be tuned for different modes, and can differentiate between it's behaviour in literal strings, code, comments etc. The default are usually sane, but if you're interested, have a look at the documentation, in particular autopair-extra-pairs and the More tricks-section in the documentation.

2010-06-10

worldcup games in your org-mode agenda

A significant part of the world population will be watching the Football World Cup in South-Africa this month. For people who use org-mode to organize their lives, find the schedule of all the games in this message I sent to the org-mode mailing list.

In order to have the games show up in your agenda, make sure the file is in your org-agenda-files. If needed, you could add it with something like in your org-mode settings:

(add-to-list 'org-agenda-files "~/org/fifa-worldcup-2010.org")

One small issue with the schedule is that it use the South-African times, and there is no automatic way to adjust times for the local time zone. As a work-around, Juan Pechiar provided the following function which makes it easy to update all org-timestamps in a file:

(defun uphours (n)
  "update all timestamps n hours"
  (interactive "nAdd hours: ")
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "[[<]" nil t)
      (when (org-at-timestamp-p t)
        (org-timestamp-change n 'hour)
        ))))

Evaluate this function (in emacs, put your cursor after the last ")"), then press C-x C-e. After that, you can go to the file with the world cup schedule, and give an M-x uphours, provide the offset for your timezone, compare to South-African time (positive or negative).