all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Gud keybindings
@ 2014-08-13  5:30 Yuri Khan
  2014-08-18  9:27 ` Yuri Khan
       [not found] ` <mailman.7183.1408354083.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 8+ messages in thread
From: Yuri Khan @ 2014-08-13  5:30 UTC (permalink / raw)
  To: help-gnu-emacs@gnu.org

Hello list,

I am trying to debug C++ programs using Emacs, Gud and GDB. This
involves setting breakpoints, stepping through and over function
calls, and examining variables.

By executing (gdb-many-windows) I can see the usual six Gud windows:
GDB interaction, variables, source, in/output, stack, and breakpoints.

I can focus the source buffer and navigate the source. In the source
buffer, I can use such keybindings as C-x C-a C-b to set a breakpoint,
and C-x C-a C-n to run until the next line.

This set of keybindings strikes me as very unintuitive and
inefficient. As a user coming from a different IDE, I would like such
keys as Ctrl+F2 to set a breakpoint, F7/F8 for “step” and “next”, and
Ctrl+F9 for “continue”. Or as a user familiar with console GDB, I
might like to press “b”, “s”, “n” and “c” in the source window to
invoke those same actions, but now they just act as
self-insert-command.

My two questions are:

* Surely I am not the first user who wants easy debugging keys? What
existing solutions are there? Or does everybody just (global-set-key
(kbd "f8") 'gud-next)?

* What would I need to do if I wanted to implement single-letter key
bindings for Gud commands? Define a minor mode with an appropriate
keymap that sets buffer-read-only when enabled and restores it when
disabled? How do I arrange for this mode to be enabled when visiting
any source buffer if and only if Gud is active?



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
       [not found] <mailman.7049.1407907858.1147.help-gnu-emacs@gnu.org>
@ 2014-08-13 19:14 ` Emanuel Berg
  2014-08-14  3:48   ` Yuri Khan
       [not found]   ` <mailman.7092.1407988122.1147.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 8+ messages in thread
From: Emanuel Berg @ 2014-08-13 19:14 UTC (permalink / raw)
  To: help-gnu-emacs

Yuri Khan <yuri.v.khan@gmail.com> writes:

> * What would I need to do if I wanted to implement
> single-letter key bindings for Gud commands? Define a
> minor mode with an appropriate keymap that sets
> buffer-read-only when enabled and restores it when
> disabled? How do I arrange for this mode to be
> enabled when visiting any source buffer if and only
> if Gud is active?

For what modes do you want it?

For one or but a few, how about binding the self-insert
keys to either self-insert, or, if buffer-read-only (or
`Gud-alive-p' if such a predicate exists - otherwise
write it). I don't think that'll be too slow/much work
for just a couple of keys.

If it is, you can write a defun, we-are-debugging which
rebinds the keys, and correspondingly no-bugs-left to
reset. You can automatize this second part like, if a
non-debug key is pressed, it is not only self-inserted,
it also disables the debugging keys.

Check out this minor-mode - it works just like that.
Enable it to get new keys. Disable it to get back to
normal. Or do something that makes sense normally, but
not with the minor-mode on - that gets implemented
"normally", and disables the minor mode as well.
Straight Ghostbusters!

For Emacs:
http://user.it.uu.se/~embe8573/conf/emacs-init/caps.el

Same thing, for zsh:
http://user.it.uu.se/~embe8573/conf/.zsh/caps

> I am trying to debug C++ programs using Emacs, Gud
> and GDB. This involves setting breakpoints, stepping
> through and over function calls, and examining
> variables.

Yeah, you got GDB to work with C++ on Linux? I asked
about it on gnu.gdb.bug and it seems the post is
archived here:

http://www.archivum.info/gnu.gdb.bug/2013-09/00000/C++-linux-gate.so.1-'set-solib-search-path'-and-'set-sysroot'.html

(Wow, that's a long URL.)

For whatever reason the reply I got isn't available,
but he said something to the effect "that's a bug,
report it". But I take it GDB is written in C so
nothing would have stopped me from using it to debug
itself...

-- 
underground experts united


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
  2014-08-13 19:14 ` Emanuel Berg
@ 2014-08-14  3:48   ` Yuri Khan
       [not found]   ` <mailman.7092.1407988122.1147.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 8+ messages in thread
From: Yuri Khan @ 2014-08-14  3:48 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs@gnu.org

On Thu, Aug 14, 2014 at 2:14 AM, Emanuel Berg <embe8573@student.uu.se> wrote:
> Yuri Khan <yuri.v.khan@gmail.com> writes:
>
>> * What would I need to do if I wanted to implement
>> single-letter key bindings for Gud commands? Define a
>> minor mode with an appropriate keymap that sets
>> buffer-read-only when enabled and restores it when
>> disabled? How do I arrange for this mode to be
>> enabled when visiting any source buffer if and only
>> if Gud is active?
>
> For what modes do you want it?

Major modes, you mean? Ideally, this is not dependent on mode but on
whether the buffer visits a file that is a source of the program
currently being debugged. (Which might involve C++, plain C, and any
other languages that are compiled to standard .o files with
gdb-compatible debug info.) I think I would settle for just all
c++-mode buffers while Gud is active, but this has to include both
buffers that were opened before Gud is started and new buffers spawned
while debugging.

> For one or but a few, how about binding the self-insert
> keys to either self-insert, or, if buffer-read-only (or
> `Gud-alive-p' if such a predicate exists - otherwise
> write it). I don't think that'll be too slow/much work
> for just a couple of keys.

That would work but is inelegant. Here in C++ world, we don’t pay for
what we don’t use — having each keypress of “s” check if Gud is active
runs very much counter to that principle.

> If it is, you can write a defun, we-are-debugging which
> rebinds the keys, and correspondingly no-bugs-left to
> reset. You can automatize this second part like, if a
> non-debug key is pressed, it is not only self-inserted,
> it also disables the debugging keys.

This equates to a global minor mode, doesn’t it?

And no, I don’t want to get out of debugging if I inadvertently press
an editing key. Editing sources of the program being debugged can
cause much confusion.


>> I am trying to debug C++ programs using Emacs, Gud
>> and GDB. This involves setting breakpoints, stepping
>> through and over function calls, and examining
>> variables.
>
> Yeah, you got GDB to work with C++ on Linux? I asked
> about it on gnu.gdb.bug and it seems the post is
> archived here:

For me, it has always worked out of the box (except that printing
standard containers is not pretty, and evaluating any expressions that
involve inlineable functions may fail because their code is optimized
out of the binary).



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
       [not found]   ` <mailman.7092.1407988122.1147.help-gnu-emacs@gnu.org>
@ 2014-08-14 21:13     ` Emanuel Berg
  0 siblings, 0 replies; 8+ messages in thread
From: Emanuel Berg @ 2014-08-14 21:13 UTC (permalink / raw)
  To: help-gnu-emacs

Yuri Khan <yuri.v.khan@gmail.com> writes:

> That would work but is inelegant. Here in C++ world,
> we don't pay for what we don't use — having each
> keypress of "s" check if Gud is active runs very much
> counter to that principle.

I think it is very fast both to setup and to use. Try
it yourself. Here, I've set it up globally - it would
be better to have it but for the desired modes. And
that can be automatized as well: you setup a defun to
do the changes, and then you send that defun a keymap
argument to specify what mode should be affected. Put a
bunch of those in a list and iterate it, sending the
elements to the defun one by one.

(defvar some-mode nil)
(setq some-mode t)

(global-set-key
 "s"
 (lambda () (interactive) (if some-mode (message "do mode thing")
                            (insert ?s) )))

(global-set-key "s" 'self-insert-command) ; reset

>> If it is, you can write a defun, we-are-debugging
>> which rebinds the keys, and correspondingly
>> no-bugs-left to reset. You can automatize this
>> second part like, if a non-debug key is pressed, it
>> is not only self-inserted, it also disables the
>> debugging keys.
>
> This equates to a global minor mode, doesn’t it?

The example I provided is a minor mode, yes, but you
don't need to do it like that. You can have a defun
that changes the keys (using the current map) and then
another defun that resets them. But - why not make it a
minor mode to get a lighter, proper documentation, and
all?

-- 
underground experts united


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
  2014-08-13  5:30 Gud keybindings Yuri Khan
@ 2014-08-18  9:27 ` Yuri Khan
  2014-08-19  1:49   ` Stefan Monnier
       [not found] ` <mailman.7183.1408354083.1147.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 8+ messages in thread
From: Yuri Khan @ 2014-08-18  9:27 UTC (permalink / raw)
  To: help-gnu-emacs@gnu.org

On Wed, Aug 13, 2014 at 12:30 PM, Yuri Khan <yuri.v.khan@gmail.com> wrote:

> * What would I need to do if I wanted to implement single-letter key
> bindings for Gud commands? Define a minor mode with an appropriate
> keymap that sets buffer-read-only when enabled and restores it when
> disabled? How do I arrange for this mode to be enabled when visiting
> any source buffer if and only if Gud is active?

Here’s what I tentatively ended up with. I was unable to solve all
issues using only documented APIs and had to advise a couple of
functions. If anybody can suggest improvements, I’ll be grateful.

;; Define a keymap with commonly used Gud commands.
;; This is likely to evolve.
(defvar yk-gud-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "b" 'gud-break)
    (define-key map "c" 'gud-cont)
    (define-key map "d" 'gud-down)
    (define-key map "f" 'gud-finish)
    (define-key map "n" 'gud-next)
    (define-key map "s" 'gud-step)
    (define-key map "u" 'gud-up)
    (define-key map "v" 'gdb-display-locals-buffer)
    (define-key map "j" 'gud-jump)
    (define-key map "l" 'gud-refresh)
    (define-key map "p" 'gud-print)
    (define-key map "." 'gud-until)
    (define-key map "<" 'gud-up)
    (define-key map ">" 'gud-down)
    (define-key map "t" 'gud-tbreak)
    map))

;; Define a buffer-local minor mode using the above keymap.
(define-minor-mode yk-gud-mode nil
  :lighter " Gud"
  :keymap yk-gud-mode-map
  (if yk-gud-mode (yk-gud-mode--enable) (yk-gud-mode--disable)))

;; When the mode is enabled, remember the read-only status
;; of the buffer, and lock it down.
(defun yk-gud-mode--enable ()
  (set (make-local-variable 'yk-gud-read-only) buffer-read-only)
  (setq buffer-read-only t))

;; Restore the read-only status when disabling. (Can’t unlock it
;; unconditionally as some sources come from /usr/include and other
;; read-only locations.)
(defun yk-gud-mode--disable ()
  (when (local-variable-p 'yk-gud-read-only)
    (setq buffer-read-only yk-gud-read-only)))

;; This solves the immediate problem of uncomfortable keybindings.
;; Now we want it to be automatically enable for all source buffers.
;; Gud has a hook that runs when debugging is started.
(add-hook 'gdb-mode-hook 'yk-gud--started)

;; In this hook, we set up “find-file-hook” so that buffers
;; opened while debugging start out with our mode enabled…
(defun yk-gud--started ()
  (add-hook 'find-file-hook 'yk-gud--find-file))

;; … if needed. The variable “gdb-source-file-list” contains
;; the list of file paths that Gud considers to be sources of
;; the program. We use it to determine whether to enable our mode.
(defun yk-gud--find-file ()
  (when (member (buffer-file-name) gdb-source-file-list)
    (yk-gud-mode)))

;; The other half of the startup issue is enabling the mode
;; for buffers that are already open by the time Gud is started.
;; Unfortunately, “gdb-mode-hook” runs before “gdb-source-file-list”
;; is populated, so we have to resort to an advice.
;; “gdb-init-buffer” sets up source buffers so that clicking
;; in the fringe sets and deletes breakpoints, so it’s a good place
;; for us too.
(defadvice gdb-init-buffer (after yk-gdb-init-buffer ())
  (yk-gud-mode))
(ad-activate 'gdb-init-buffer)

;; Now, there’s another problem. When we exit the debugger, files
;; remain locked. We need to disable our mode. Gud does not have
;; a suitable hook, so we advice “gdb-reset”.
(defadvice gdb-reset (after yk-gdb-reset ())
  (yk-gud--disable-all))
(ad-activate 'gdb-reset)

(defun yk-gud--disable-all ()
  (dolist (buffer (buffer-list))
    (with-current-buffer buffer
      (yk-gud-mode 0))))

;; And a further annoyance: the state of our minor mode is stored
;; in the desktop file, while the state of Gud is not. So if we exit
;; Emacs in the middle of debugging and then restart it, the source
;; buffers end up read-only for no valid reason.
;; It was easiest to just disable the mode for all buffers after
;; the desktop is loaded.
(add-hook 'desktop-after-read-hook 'yk-gud--disable-all)



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
       [not found] ` <mailman.7183.1408354083.1147.help-gnu-emacs@gnu.org>
@ 2014-08-18 22:56   ` Emanuel Berg
  0 siblings, 0 replies; 8+ messages in thread
From: Emanuel Berg @ 2014-08-18 22:56 UTC (permalink / raw)
  To: help-gnu-emacs

Yuri Khan <yuri.v.khan@gmail.com> writes:

> I was unable to solve all issues using only
> documented APIs and had to advise a couple of
> functions.

When/if you are 95% or so happy with how it works, why
not make it a package? You can distribute it with
[M]ELPA or just have it a package anyway. Because it
seems it solves a general problem that involves Emacs,
C++, and GDB - which isn't that radical, is it?

Making it a package is easy. It is just a header, and a
footer, and turning those comments into docstrings, and
you're done. Perhaps half-an-hour or so, depending on
how pedantic you are.

You can use this. It'll report what is missing.

(defun check-pack-style ()
  (interactive)
  (checkdoc-current-buffer t) ) ; TAKE-NOTES (report all errors)

-- 
underground experts united


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
  2014-08-18  9:27 ` Yuri Khan
@ 2014-08-19  1:49   ` Stefan Monnier
  2014-08-19  5:03     ` Yuri Khan
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2014-08-19  1:49 UTC (permalink / raw)
  To: help-gnu-emacs

> I was unable to solve all issues using only documented APIs and had to
> advise a couple of functions.

We generally consider this as a bug.  So please M-x report-emacs-bug,
explaining the functionality/hook that you failed to find.

Note that the issue you're trying to solve with Gud key-bindings is an
issue that we also want to solve in Emacs (especially since in
Emacs-24.4, C-x SPC is not bound to gud-break any more).  It's just not
easy to solve in general:
- if you use M-x gud-gdb instead of M-x gdb, then gdb-source-file-list
  doesn't exist).
- I pretty much always have a Gud buffer open (when I'm done debugging,
  I generally don't kill the buffer, because I know I'll get back to it
  soon for something else).


        Stefan




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Gud keybindings
  2014-08-19  1:49   ` Stefan Monnier
@ 2014-08-19  5:03     ` Yuri Khan
  0 siblings, 0 replies; 8+ messages in thread
From: Yuri Khan @ 2014-08-19  5:03 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs@gnu.org

On Tue, Aug 19, 2014 at 8:49 AM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>> I was unable to solve all issues using only documented APIs and had to
>> advise a couple of functions.
>
> We generally consider this as a bug.  So please M-x report-emacs-bug,
> explaining the functionality/hook that you failed to find.

18294.

> Note that the issue you're trying to solve with Gud key-bindings is an
> issue that we also want to solve in Emacs (especially since in
> Emacs-24.4, C-x SPC is not bound to gud-break any more).  It's just not
> easy to solve in general:
> - if you use M-x gud-gdb instead of M-x gdb, then gdb-source-file-list
>   doesn't exist).

This turns out unimportant, for two reasons:

* Advising “gdb-init-buffer” is sufficient to turn on the mode in both
existing source buffers and source buffers created during debugging; I
don’t even have to hook “find-file-hook”.

* Using “gud-gdb”, “gdb-init-buffer” is never called at all, and
clicking in the fringe does not set breakpoints. This is
understandable because gud-gdb supports concurrent debugging sessions
and it’s kind of hard to decide which debugger instance the breakpoint
goes to. In the same way, pressing a debugger control key while in a
source buffer should effect an action in one of the debuggers, but
which one?

Due to the latter issue being hard, I am inclined to leave gud-gdb
unsupported by now.

> - I pretty much always have a Gud buffer open (when I'm done debugging,
>   I generally don't kill the buffer, because I know I'll get back to it
>   soon for something else).

Killing the Gud interaction buffer is not necessary. “gdb-reset” runs
when the “quit” command is executed in gdb. (Not when the program
under debugger finishes: Gud assumes you’re still debugging.)

With the default keybindings, it is possible to leave a debugging
session open, edit some files, recompile, re-run and continue
debugging. In my model, though, an active debugging session prevents
source files from being edited (because it hijacks single-letter
keystrokes to control the debugger). Anyway, one could manually toggle
the mode off if needed.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-08-19  5:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-13  5:30 Gud keybindings Yuri Khan
2014-08-18  9:27 ` Yuri Khan
2014-08-19  1:49   ` Stefan Monnier
2014-08-19  5:03     ` Yuri Khan
     [not found] ` <mailman.7183.1408354083.1147.help-gnu-emacs@gnu.org>
2014-08-18 22:56   ` Emanuel Berg
     [not found] <mailman.7049.1407907858.1147.help-gnu-emacs@gnu.org>
2014-08-13 19:14 ` Emanuel Berg
2014-08-14  3:48   ` Yuri Khan
     [not found]   ` <mailman.7092.1407988122.1147.help-gnu-emacs@gnu.org>
2014-08-14 21:13     ` Emanuel Berg

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.