0

I'm trying to use global-set-key to bind commands ":x" as save and close, just like the way vim do. Right now I'm doing:

(global-set-key (kbd "S-; x") (lambda() (kbd "C-x C-s") (kill-emacs)))

But when I type Shift+: and then x, it just write :x in the documents instead of really doing save and close. Wondering what should be the right form?

  • Make that (kbd ": x"). But that would only work if ":" was a prefix key. Either pressing : inserts : or it waits for you to type the next character, it can't do both. Are you using a vi emulation interface? Which one? – Gilles Sep 29 '16 at 9:17
5

There is a function that does this already:

(save-buffers-kill-emacs &optional ARG)

Offer to save each buffer, then kill this Emacs process. With prefix ARG, silently save all file-visiting buffers without asking.

You can call it interactively with C-u M-x save-buffers-kill-emacs and all files are saved without asking you and emacs quits, problem solved!

Your keybinding didn't work for two reasons:

  1. (kbd "S-;") is not shifted ";" (i.e., ":"), it is ";" with the Super bit on. To bind to ":" just use ":" like this - (kbd ":")
  2. ":" is not a prefix key, so you can't use it in a chain (kbd ": x") without further changes. Either you need to define a prefix-map and bind it to ":" (see below), or investigate some other approach.

So, to get a save-all-and-quit bound to a key, the easiest solution is probably:

(global-set-key (kbd "C-c x") 
    (lambda () 
        (interactive) 
        (save-buffers-kill-emacs t)))

Here the function is bound to C-c x, but you can change it to anything else.

If you really want to use ":" as a prefix, you'd do something like this:

(define-prefix-command 'my-keymap)
(global-set-key ":" my-keymap)

;; define kill-emacs:
(define-key my-keymap "x" (lambda () 
        (interactive) 
        (save-buffers-kill-emacs t)))

Now, of course, you've lost use of the : key for entering the ":" character. You can get it back by adding it to your keymap:

(define-key my-keymap ":" 'self-insert-command)

Now entering : x will save all buffers and kill emacs, and : : will enter a ":".

1

This should do the trick. Just add this to your .emacs and bind it to a key and you're done

(defun save-all-and-quit ()
  (interactive)
  (save-some-buffers t)
  (kill-emacs))

This is considering you want to save all buffers without prompting interactively for yes or no for all the unsaved buffers.

  • dunno why, it just write ":x" in the file when I type Shift+; and then x – cdnszip Sep 29 '16 at 9:04
  • do you know how to actually use it since I'm just writing :x in the file – cdnszip Sep 29 '16 at 9:09
  • Ah sorry, it looks like we can't use shift as a modifier key since it automatically inserts characters after it. Oh well. I guess you could use some other key binding for the function I wrote ? How about super key ? – Chakravarthy Raghunandan Sep 29 '16 at 9:10
  • it seems to be, ok – cdnszip Sep 29 '16 at 9:16
  • If you really want to use shift-; x to close emacs, I've no idea how to set it up to work that way. Maybe someone who knows more elisp can help you with that. – Chakravarthy Raghunandan Sep 29 '16 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.