17 August 2013 2:25 AM (emacs | eshell | elisp | config)
One of the "tricks" that I have learned to use when working with
terminals is using C-d
to close them, or when working on a TTY
logout. It somehow grew to the extent that if I can't use it, I get
annoyed, like with eshell
.
I have customized ansi-term
to immediately close its buffer after the
shell quits. This makes it very easy to start an ansi-term
, which I've
bound to C-c t
, run a quick command (perhaps make
, or similar), C-d
,
and I'm out. I want that for my eshell
too.
There are a few conditions that I want met before the buffer is killed, though.
Since
eshell
is an Emacs mode like any other,C-d
is usually used
to forward-kill characters, I don't want to lose this.I only want it to quit when the line of input is empty.
The following piece of code make sure these conditions are met.
It interactively calls
delete-char
, which keeps keybindings like
C-4 C-d
to delete 4 characters working.It catches the error condition which is signaled whenever
delete-char
can't do it's job (like when there's nothing left to
delete in the buffer).It checks to make sure that the signaled error is the
end-of-buffer
error. I don't want to kill the buffer if I try to delete more
characters than are in the buffer because I feel that could cause
irritating surprises.It checks of the cursor is at the
eshell
prompt. This, combined
with only responding to theend-of-buffer
error, makes sure we're
on an empty line and not just at the end of the input. Sometimes
keys are pressed at the wrong time and I don't want to have to
re-type a command just because I was being an idiot.If the right conditions aren't met, signal the error again so I can
see what's going on.
(defun eshell-C-d () "Either call `delete-char' interactively or quit." (interactive) (condition-case err (call-interactively #'delete-char) (error (if (and (eq (car err) 'end-of-buffer) (looking-back eshell-prompt-regexp)) (kill-buffer) (signal (car err) (cdr err))))))
I then bind this to C-d
in eshell.
(add-hook 'eshell-mode-hook (lambda () (local-set-key (kbd "C-d") #'eshell-C-d)))