From: Yuri Khan <yuri.v.khan@gmail.com>
To: "help-gnu-emacs@gnu.org" <help-gnu-emacs@gnu.org>
Subject: Re: Gud keybindings
Date: Mon, 18 Aug 2014 16:27:57 +0700 [thread overview]
Message-ID: <CAP_d_8V+xzvc=MYpTGY3_YXpzU_i6m1Lp8YESuZT7HRQFUwNYQ@mail.gmail.com> (raw)
In-Reply-To: <CAP_d_8VSwQFVsMYpniAMebyQdjgbhg0S5MpqxCZcSaYw9rCG3Q@mail.gmail.com>
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)
next prev parent reply other threads:[~2014-08-18 9:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-13 5:30 Gud keybindings Yuri Khan
2014-08-18 9:27 ` Yuri Khan [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAP_d_8V+xzvc=MYpTGY3_YXpzU_i6m1Lp8YESuZT7HRQFUwNYQ@mail.gmail.com' \
--to=yuri.v.khan@gmail.com \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).