Search code examples
emacskey-bindingsgud

How to bind C-x SPC locally to gud mode in Emacs 25


Similar to How to change GUD breakpoint keybinding to the old one but I would like to bind CTRL+x followed by SPACE to be gud-break.

What I have working (well it is a hack; keep reading) is:

  (define-key ctl-x-map " " 'gud-break)

but ctl-x-map is a global variable akin to the global map. And in fact, if I switch to another C++ buffer and type C-h k C-x SPC I get:

C-x SPC runs the command gud-break (found in global-map), which is an interactive compiled Lisp function.

It is bound to C-x SPC, C-x C-a C-b.

(gud-break ARG)

Set breakpoint at current line.

which means the global definition across all buffers is what was changed, which is not correct AFAIK.

Is there a way to "insert" or somehow affect the local key map for C-x, which I believe is gud-mode-map, because I want that binding to not be global for all C++ buffers. E.g., the global binding for CTRL+x followed by SPACE is rectangle-mark-mode.

Yes I realize the standard binding is C-x C-a C-b for gud-break, but that is asking for RSI.

Update #1

Since I need the local key map for gud-mode-map, this needs to be active only when I'm running a debugger. In my case, this is in C++ mode buffers, but my understanding is that gud-mode-map becomes active in those C++ mode buffers only during the debug session, and is removed from the key bindings when gud mode is finished.

Update #2

This did not work:

(define-key gud-mode-map [(control x ?\ )] 'gud-break) ;; <-- gave "Two bases given in one event" error too.
(define-key gud-mode-map (kbd "C-x SPC") 'gud-break) ;; <-- this does not work either.

Update #3

As an experiment, I commented out my define-key bindings in my hook I add to gud-gdb-mode-hook, reran gdb, then switched to the gud buffer (not the C++ source file) and typed C-h k C-x SPC I get this:

C-x SPC runs the command gud-break (found in gud-mode-map), which is
an interactive Lisp closure.

It is bound to <menu-bar> <debug> <break>, C-x SPC, C-c C-b, C-x C-a
C-b.

(gud-break ARG)

Set breakpoint at current line.

But then when I switch over to the C++ buffer that should also have the same bindings inserted temporarily (while gud mode is active), and then do the same thing I get this instead:

C-x SPC runs the command rectangle-mark-mode (found in global-map),
which is an interactive autoloaded compiled Lisp function in
'rect.el'.

It is bound to C-x SPC.

(rectangle-mark-mode &optional ARG)

Toggle the region as rectangular.
Activates the region if needed.  Only lasts until the region is deactivated.

Switching back to the gud buffer, and typing C-h m shows this:

Debugger mode defined in 'gud.el':
Major mode for interacting with an inferior debugger process.

   You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx,
M-x perldb, M-x xdb, or M-x jdb.  Each entry point finishes by executing a
hook; 'gdb-mode-hook', 'sdb-mode-hook', 'dbx-mode-hook',
'perldb-mode-hook', 'xdb-mode-hook', or 'jdb-mode-hook' respectively.

After startup, the following commands are available in both the GUD
interaction buffer and any source buffer GUD visits due to a breakpoint stop
or step operation:

C-x SPC sets a breakpoint at the current file and line.  In the
GUD buffer, the current file and line are those of the last breakpoint or
step.  In a source buffer, they are the buffer's file and current line.

...

Notice the reference to C-x SPC above. It is as if they intended to bind C-x SPC but it did not work, or something is preventing it from being bound properly in that buffer when gud mode is entered.


Solution

  • I've chosen to give up on this altogether. using C-x SPC in the buffer is problematic anyhow. I noticed that the C-x C-a prefix that is used for the gud bindings are left in the C++ buffer even after gud finishes, so the gud mode is not cleaning up after itself anyhow.