all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
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)



  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

* 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.
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.