From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Bill Atkins Newsgroups: gmane.emacs.devel Subject: Keybindings and minor modes Date: Thu, 29 Dec 2005 10:52:00 -0500 Message-ID: <66b7e34b0512290752r5588df25t9ef2b5e615e17f5e@mail.gmail.com> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: sea.gmane.org 1135873106 23598 80.91.229.2 (29 Dec 2005 16:18:26 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 29 Dec 2005 16:18:26 +0000 (UTC) Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 29 17:18:18 2005 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1Es0Tk-0001kL-Rw for ged-emacs-devel@m.gmane.org; Thu, 29 Dec 2005 17:18:13 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Es0Ug-0001Ud-Ay for ged-emacs-devel@m.gmane.org; Thu, 29 Dec 2005 11:19:10 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Es05r-0003Xb-S6 for emacs-devel@gnu.org; Thu, 29 Dec 2005 10:53:32 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Es05n-0003WF-JO for emacs-devel@gnu.org; Thu, 29 Dec 2005 10:53:31 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Es05n-0003W9-77 for emacs-devel@gnu.org; Thu, 29 Dec 2005 10:53:27 -0500 Original-Received: from [64.233.184.197] (helo=wproxy.gmail.com) by monty-python.gnu.org with esmtp (Exim 4.34) id 1Es069-0006b7-Vx for emacs-devel@gnu.org; Thu, 29 Dec 2005 10:53:50 -0500 Original-Received: by wproxy.gmail.com with SMTP id i22so1448555wra for ; Thu, 29 Dec 2005 07:52:01 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:sender:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=Y5YKybpu+y10MwZiJOJpDBuisPVx2YatwDdASQJaU4nvT3Wf3NTNLnqeYeqBYgL/UzO312A+5esa4Q/0Q0VkXHoPDlso84WCz0DgsR2qkZo6zb1/9P0npyEaQTAF/JdjhbdY422At6s9WBwyXgiaoAd9piY+phO+tIrv/NfFb70= Original-Received: by 10.65.84.4 with SMTP id m4mr2902828qbl; Thu, 29 Dec 2005 07:52:00 -0800 (PST) Original-Received: by 10.65.176.8 with HTTP; Thu, 29 Dec 2005 07:52:00 -0800 (PST) Original-To: emacs-devel@gnu.org Content-Disposition: inline X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:48491 Archived-At: I apologize if this is the wrong place to post this, but it seemed like the most appropriate list. I'd like to bind a command to tab in a minor mode I'm writing, but I'd also like to preserve any command that might have been attached to that key before making my binding (such as indentation). In other words, I'd like to add functionality to an existing keybinding without completely overwriting the binding. The solution I came up with was to simply store the currently bound command in a buffer-local variable whenever the minor mode is invoked. Then the keys are bound to functions that provide my additional functionality and then funcall the old bindings. This works, but I wonder if there isn't a cleaner way to pass a keychord event on to the next handler. The code I have now is pretty ugly, since a key bound to self-insert-command has to be handled separately so that self-insert-command will get an argument of 0. I've attached my code below in case it's useful. Thanks, Bill Atkins -- ;; ehinter.el - echo lambda-lists when editing emacs lisp code (defvar ehinter--old-space) (defvar ehinter--old-tab) (defvar ehinter--old-ret) (make-variable-buffer-local 'ehinter--old-space) (make-variable-buffer-local 'ehinter--old-tab) (make-variable-buffer-local 'ehinter--old-ret) (defvar ehinter-mode-map (let ((keymap (make-sparse-keymap))) (define-key keymap " " 'ehinter--space-cmd) (define-key keymap "\t" 'ehinter--tab-cmd) (define-key keymap "\C-m" 'ehinter--ret-cmd) keymap) "Keymap for the Elisp Hinter minor mode") (define-minor-mode ehinter-mode "A minor mode that echoes an arglist for whatever Elisp function is being called at point. \\{ehinter-mode-map}" :lighter " EHinter" :init-value nil (setq ehinter--old-space (ehinter--old-binding " ")) (setq ehinter--old-tab (ehinter--old-binding "\t")) (setq ehinter--old-ret (ehinter--old-binding "\C-m"))) (defun ehinter--old-binding (key) (or (lookup-key (current-local-map) key) (lookup-key (current-global-map) key))) (defun ehinter--invoke-binding (binding) (if (eq binding 'self-insert-command) (self-insert-command 1) (funcall binding))) (defun ehinter--space-cmd () (interactive) (ehinter-hint) (ehinter--invoke-binding ehinter--old-space)) (defun ehinter--ret-cmd () (interactive) (ehinter-hint) (ehinter--invoke-binding ehinter--old-ret)) (defun ehinter--tab-cmd () (interactive) (ehinter-hint) (ehinter--invoke-binding ehinter--old-tab)) (defun ehinter-hint () (interactive) (when (and (function-called-at-point) (condition-case () (symbol-function (function-called-at-point)= ) (void-function nil))) (message "%s" (lambda-list (function-called-at-point)))) (self-insert-command 0)) (defun strip-ends (str) (substring str 1 (1- (length str)))) (defun lambda-list (func) (let ((fn (symbol-function func))) (cond ((and (consp fn) (eq (car-safe fn) 'lambda)) (prin1-to-string (cons func (second fn)))) ((and (consp fn) (eq (car-safe fn) 'macro)) (prin1-to-string (cons func (svref (cdr fn) 0)))) ((subrp fn) (strip-ends (downcase (prin1-to-string (first (help-split-fundoc (documentation func) func)))))) (t (error "%s" (type-of func)))))) -- Bill Atkins