1

I find when I am using emacs in certain modes that configurations made in my init.el files do not apply anymore. E.g. I have my keybinds set up so that tab is used for indentation, § for snippet completion and ~ for auto-complete completion. In c-mode and python-mode this works fine. However when I attempt to use this in vhdl-mode these commands don't all work. § still works for snippet completion but tab is now used to indentation and autocompletion and rather than bringing up a nice menu of the auto-complete options it merely cycles through the options as I press tab. How can I correct this behaviour? I assume it is set in a seperate init file for that particular mode, in the same way as my snippet and autocompletion don't work in latex-mode for example.

It's particularly problematic because I want to use tab to indent a block of code and it starts auto-completing if I type tab in the middle of a line of text.

0

1 Answer 1

2

Emacs keybindings are hierarchical. Global keybindings are masked by major-mode keybindings, and major-mode keybindings are masked by minor-mode keybindings. When you set global keybindings in your init.el, they work as long as they don't conflict with any active major or minor modes.

In your case, vhdl-mode is binding tab to whatever function it uses for indentation/completion.

How to avoid such conflicts? It's a bit tricky, but you have a few options:

C-c LETTER bindings

By convention (usually, but not always, followed), keybindings of the form C-c <letter> are reserved for users. That means if you bind something to C-c x (or any other single letter in place of x):

 (global-set-key (kbd "C-c x") 'my-favorite-function)

it shouldn't have any conflicts with major or minor modes.

F5-F9

Similarly, functions keys 5-9 are reserved for users:

 (global-set-key (kbd "<f5>") 'another-cool-function)

Define a new prefix-key

Define a new prefix key to give yourself your own personal area for key bindings:

(define-prefix-command 'my-keymap)
(global-set-key (kbd "<f5>") my-keymap)
(define-key my-keymap "a" 'function-one) 
(define-key my-keymap "b" 'function-two) 

You can use any key you like for your new prefix key. As long as you use a key that doesn't conflict with a major or minor mode, this gives you a nice way to increase your personal key binding space.

Personally, I use M-<space> as my prefix key. This means I lose access to the function it is normally bound to, which is just-one-space. But I add it to the prefix so I can get it back with one extra key-press:

(define-prefix-command 'tws-keymap)
(global-set-key "\M- " tws-keymap)
(define-key tws-keymap " " 'just-one-space) 
(define-key tws-keymap "i" 'toggle-window-split) 
...

In theory, if I use a mode that rebinds M-<space>, it will mess up my prefix-map. However, I haven't run into that problem yet.

Define a new minor mode

You can also create your own minor mode just to hold your keybindings, which will prevent any major-modes from hiding them. That's a bit more involved to include here, but it's an option if you know (or want to learn) more elisp.

6
  • It seems that something else is going on in my case. I have followed your advice and set autocomplete to be bound to C-c ~ this worked in C mode but when I opened a file in VHDL mode and typed the command I got the message "C-c ~ is undefined". It seems that maybe the init.el file is never being called for this mode or commands are being unset somehow. There is also the issue that the popup menu doesn't appear: In C mode it looks like so: !emacs autocomplete popup. In VHDL mode I get no such popup menu Dec 21, 2016 at 11:11
  • How are you binding C-c ~? If it's a global binding, it should always be defined, even if it sometimes gets masked by bindings for a mode.
    – Tyler
    Dec 21, 2016 at 14:40
  • I've kind of fixed my issue by using company-mode instead of auto-complete which seems to work in VHDL-mode but I'd still like to sort out this issue if possible. I have been setting it like so: Dec 21, 2016 at 18:13
  • (require 'auto-complete-config) (ac-config-default) (define-key ac-mode-map (kbd "TAB") nil) (define-key ac-mode-map (kbd "TAB") nil) (define-key ac-completing-map [tab] nil) (ac-set-trigger-key "C-c ~") ;; sets the auto-complete key Dec 21, 2016 at 18:17
  • ac-set-trigger-key sets the key binding for the ac-mode-map. That means it's only available when auto-complete mode is active. auto-complete is only active for modes that are listed in the variable ac-modes. So you need to add (add-to-list 'ac-modes 'vhdl-mode) to your config
    – Tyler
    Dec 21, 2016 at 20:58

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