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?

1
  • 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? Commented Sep 29, 2016 at 9:17

2 Answers 2

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.

5
  • dunno why, it just write ":x" in the file when I type Shift+; and then x
    – cdnszip
    Commented Sep 29, 2016 at 9:04
  • do you know how to actually use it since I'm just writing :x in the file
    – cdnszip
    Commented Sep 29, 2016 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 ? Commented Sep 29, 2016 at 9:10
  • it seems to be, ok
    – cdnszip
    Commented Sep 29, 2016 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. Commented Sep 29, 2016 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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