Emacs: override major mode key-map with general - emacs

I have a list of keybindings that I want to use in all modes. However, in the simplified example below, I get the error Error (use-package): general/:config: Key sequence SPC x starts with non-prefix key SPC.
(use-package paradox
:ensure t
:defer t
:config
(setq paradox-spinner-type 'progress-bar)
paradox-execute-asynchronously t))
(defun add-general-bindings ()
(general-define-key
:states '(normal visual insert emacs motion)
:prefix "SPC"
:non-normal-prefix "C-SPC"
"x" 'counsel-M-x
"SPC" 'avy-goto-char-2
"/" 'swiper))
(add-hook 'paradox-menu-mode-hook 'add-general-bindings)
I though it might be because I did not unbind SPC for the paradox-menu-mode, but if adding
(general-unbind
:states '(normal visual emacs motion)
"SPC")
to the top of add-general-bindings the error still persists. is this the wrong approach to override keybindings of a major mode with the general package?

Related

How to change GUD breakpoint keybinding to the old one

Currently, I am using GUD in the newest version of Emacs. The keybinding has changed since the old Emacs. Now it is "\C-x \C-a \C-b" for setting a breakpoint but it was \C-[space].
I was wondering if there is anyway to change the keybinding to the old format? (For some reason I cannot change my Emacs version)
I am using Emacs 24.5
Here is my .emacs file:
;; .emacs
;;; uncomment this line to disable loading of "default.el" at startup
;; (setq inhibit-default-init t)
;; turn on font-lock mode
(when (fboundp 'global-font-lock-mode)
(global-font-lock-mode t))
;; enable visual feedback on selections
;(setq transient-mark-mode t)
;; default to better frame titles
(setq frame-title-format
(concat "%b - emacs#" (system-name)))
;; default to unified diffs
(setq diff-switches "-u")
;; always end a file with a newline
;(setq require-final-newline 'query)
;; Show main source buffer when using gdb
(setq gdb-show-main t)
;; Show all debugging frames in GDB
(setq gdb-many-windows t)
;; see buffer list on the same frame
(global-set-key "\C-x\C-b" 'buffer-menu)
;; old keybinding for breakoint in GUD
(require 'gud)
(define-key gud-mode-map "\C-x SPC" 'gud-break)
Changing your Emacs version should not be necessary. Try this:
(require 'gud)
(define-key gud-mode-map (kbd "C-SPC") 'gud-break)
This will allow you to trigger gud-break with C-SPC. If you are not talking about the gud-break command, replace it with the command you are referring too.
Generally, the answer to the question "can I change this keybinding?" is always "yes" in Emacs.
Somehow I was able to fix it with this:
(require 'gud)
(global-set-key [24 32] (quote gud-break))

Why can't I use "C-," to bind keys in org-mode?

I've used keybindings that start with "C-," in many other major modes and they all work. But it does not seem to work in org-mode (I tried to bind "C-, C-d" to org-deadline).
This is how I bind keys:
(add-hook 'org-mode-hook
(lambda ()
(local-set-key (kbd "C-, C-d") 'org-deadline)))
It looks like if I change it to
(add-hook 'org-mode-hook
(lambda ()
(local-set-key "\C-cp" 'org-deadline)))
then the binding works. However, it is still unclear to me how to bind "C-, C-d". And the first way of binding works in other major modes (Latex, Python, etc...) I use.
local-set-key in this context will attempt to bind a key sequence in org-mode-map, and there is already a non-prefix binding for C-, in that keymap, so you can't then create a binding in the same keymap which treats C-, as a prefix.
n.b. You can ask Emacs what C-, is bound to by typing C-h k C-, in an org-mode buffer.
You can remove the default binding using:
(eval-after-load "org" '(define-key org-mode-map (kbd "C-,") nil))
(after which you would be able to execute your original code.)

Emacs global-set-key in find-file

In my init.el file I have this:
(global-set-key "\M-n" (lambda () (interactive) (insert "~")))
This allows me to use Alt-n on my Mac to produce the ~ character. It works fine in buffers etc. but when I try to use it in find-file I get
"End of history no default available".
C-h k reveals that M-n actually calls:
(lambda nil (interactive) (insert "~"))
Why doesn't this work with find-file?
Global key bindings are overridden by local (i.e., major-mode) key bindings, which are overridden by minor-mode bindings, which are overridden by... IOW, there are lots of levels of key binding.
In this case, your global binding is overridden by a minibuffer keymap binding.
In the minibuffer completion keymaps, which are local maps, M-n is bound to next-history-element. If you want M-n in such a map to be bound to something else, then you need to bind it. For example:
(define-key minibuffer-local-completion-map "\M-n" 'your-command)
There are several minibuffer completion keymaps, depending on your Emacs version. The two main ones are minibuffer-local-completion-map and minibuffer-local-must-match-map.

Emacs can't reset Ctrl-d key behaviour

I wanted to change the behaviour of Ctrl-d key. So it will delete a word backward. I created a function:
(defun backward-delete-word (arg)
"Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
(interactive "p")
(delete-region (point) (progn (backward-word arg) (point))))
Then inserted this into emacs.d:
(global-set-key (kbd "\C-d") 'backward-delete-word)
It works in fundamental-mode, but in php-mode it just removes the next character. When I click
Ctrl-h k Ctrl-d
Emacs gives this:
C-d runs the command c-electric-delete-forward, which is an
interactive compiled Lisp function in `cc-cmds.el'.
It is bound to C-d.
(c-electric-delete-forward ARG)
Somehow, it was reset to another function. How to find out, where it was reset and make it work with my function instead?
I don't have php-mode so I can't say for sure, but the binding is likely overriden in php-mode-map (which, as a major mode map, has higher precedence than the global map).
You can check by using C-h b to list all available key bindings and look for C-d or c-electric-delete-forward in the output buffer to see in which keymap the binding is defined.
Assuming php-mode-map overrides the C-d binding, you can disable it using
(define-key php-mode-map (kbd "C-d") nil)

Conflicting keyboard shortcuts in two Emacs minor modes

I have an ErgoEmacs minor mode turned on globally, which defines many custom keyboard shortcuts for basic editing. However when I open any lisp file, slime-mode turns on automatically and overrides M-p and M-n with its own commands. However I want M-p and M-n to be always defined by ergoemacs-mode. How do I set up order in which minor modes load and define keybindings? Or how do I raise ergoemacs-mode keybindings priority?
How do I set up order in which minor modes load and define keybindings? Or how do I raise ergoemacs-mode keybindings priority?
I think you need to ensure that ErgoEmacs appears before slime-mode in the variable minor-mode-map-alist. There's probably a much better way, but the code below should achieve this. Let me know if it does what you want.
(require 'cl)
(add-hook
'slime-mode-hook
(lambda ()
(let ((elem (first
(remove-if-not
(lambda (item) (equal 'ergoemacs-mode (car item)))
minor-mode-map-alist))))
(setq minor-mode-map-alist (remove elem minor-mode-map-alist))
(add-to-list 'minor-mode-map-alist elem))))
Maybe a simpler solution is to remove Slime's bindings:
(add-hook 'slime-mode-hook
(lambda ()
(define-key slime-mode-map [?\M-p] nil)
(define-key slime-mode-map [?\M-n] nil)))
Beware: guarantedd 100% untested, the variable's name might be different from slime-mode-map (and it probably will only exist after loading slime-mode).