From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Yuri Khan Newsgroups: gmane.emacs.help Subject: Re: Gud keybindings Date: Mon, 18 Aug 2014 16:27:57 +0700 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1408354101 18622 80.91.229.3 (18 Aug 2014 09:28:21 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 18 Aug 2014 09:28:21 +0000 (UTC) To: "help-gnu-emacs@gnu.org" Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Aug 18 11:28:15 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XJJEc-0000MK-V2 for geh-help-gnu-emacs@m.gmane.org; Mon, 18 Aug 2014 11:28:15 +0200 Original-Received: from localhost ([::1]:42576 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XJJEc-00031e-J2 for geh-help-gnu-emacs@m.gmane.org; Mon, 18 Aug 2014 05:28:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34726) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XJJEO-00031G-LZ for help-gnu-emacs@gnu.org; Mon, 18 Aug 2014 05:28:01 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XJJEN-0001q9-Em for help-gnu-emacs@gnu.org; Mon, 18 Aug 2014 05:28:00 -0400 Original-Received: from mail-ig0-x233.google.com ([2607:f8b0:4001:c05::233]:34201) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XJJEN-0001q2-7j for help-gnu-emacs@gnu.org; Mon, 18 Aug 2014 05:27:59 -0400 Original-Received: by mail-ig0-f179.google.com with SMTP id h18so7197874igc.12 for ; Mon, 18 Aug 2014 02:27:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:content-type:content-transfer-encoding; bh=1CCUxmiAVnqSXtlxRgZROaq9SmgPCjBj0H2tvf8v33U=; b=be+iXT2hvUgZ+8noqCud7Nwce6KOEy7rJJ1JA5sN68FccrueH4pD+ldVqbtb8tOgm/ KzZvRaPBuUfUliao24PItIpIF34X4FMM0OIlcA3JGV5HjKgjHch9+Q/vuxibzb3Tas+e S7k93dP4hqH5ZLjkgpFni3JOu1UOtF5XtN7rh7uUg72htoSG/aCeA1JMz2qgCWNdzYUF eG/14LU2b74EYCbuyvpaZJfzXuc1aLDZilCmluldVw+igW2qOAAE2vBTtfHehKXt5kkz OBHMQbUDNrFyLMR5s0F00qyitmCsTY+WygtgA9rYAnZoB3U8ocJeWSq31GS0Q24JSPAE UoIw== X-Received: by 10.42.199.197 with SMTP id et5mr5121588icb.56.1408354078054; Mon, 18 Aug 2014 02:27:58 -0700 (PDT) Original-Received: by 10.107.6.30 with HTTP; Mon, 18 Aug 2014 02:27:57 -0700 (PDT) In-Reply-To: X-Google-Sender-Auth: y0NG2MbRjyKaFEI361vxJQN8o90 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c05::233 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:99260 Archived-At: On Wed, Aug 13, 2014 at 12:30 PM, Yuri Khan 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=E2=80=99s 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=E2=80=99ll 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=E2=80=99t 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 =E2=80=9Cfind-file-hook=E2=80=9D so that buffers ;; opened while debugging start out with our mode enabled=E2=80=A6 (defun yk-gud--started () (add-hook 'find-file-hook 'yk-gud--find-file)) ;; =E2=80=A6 if needed. The variable =E2=80=9Cgdb-source-file-list=E2=80=9D= 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, =E2=80=9Cgdb-mode-hook=E2=80=9D runs before =E2=80=9Cgdb-= source-file-list=E2=80=9D ;; is populated, so we have to resort to an advice. ;; =E2=80=9Cgdb-init-buffer=E2=80=9D sets up source buffers so that clickin= g ;; in the fringe sets and deletes breakpoints, so it=E2=80=99s 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=E2=80=99s 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 =E2=80=9Cgdb-reset=E2=80=9D. (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)