From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: A simple implementation of context-sensitive keys Date: Wed, 10 Sep 2008 12:57:56 +0200 Message-ID: <87hc8o6zez.fsf@thinkpad.tsdh.de> References: <87y72079mg.fsf@thinkpad.tsdh.de> <48C7A31A.3000500@gmail.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1221045380 12011 80.91.229.12 (10 Sep 2008 11:16:20 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 10 Sep 2008 11:16:20 +0000 (UTC) Cc: "Lennart Borgman \(gmail\)" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Sep 10 13:17:15 2008 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1KdNhC-0003fx-Et for ged-emacs-devel@m.gmane.org; Wed, 10 Sep 2008 13:17:14 +0200 Original-Received: from localhost ([127.0.0.1]:36598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KdNg7-00083U-3Y for ged-emacs-devel@m.gmane.org; Wed, 10 Sep 2008 07:16:07 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KdNQc-000137-Rv for emacs-devel@gnu.org; Wed, 10 Sep 2008 07:00:07 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KdNQa-00011N-Rw for emacs-devel@gnu.org; Wed, 10 Sep 2008 07:00:05 -0400 Original-Received: from [199.232.76.173] (port=45246 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KdNQZ-00010t-Oj for emacs-devel@gnu.org; Wed, 10 Sep 2008 07:00:04 -0400 Original-Received: from deliver.uni-koblenz.de ([141.26.64.15]:29532) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KdNQZ-0003ri-34 for emacs-devel@gnu.org; Wed, 10 Sep 2008 07:00:03 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by deliver.uni-koblenz.de (Postfix) with ESMTP id DD3BE7854985; Wed, 10 Sep 2008 12:59:59 +0200 (CEST) Original-Received: from deliver.uni-koblenz.de ([127.0.0.1]) by localhost (deliver.uni-koblenz.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 15385-01; Wed, 10 Sep 2008 12:59:58 +0200 (CEST) X-CHKRCPT: Envelopesender vrfy tassilo@member.fsf.org Original-Received: from thinkpad.tsdh.de (dhcp188.uni-koblenz.de [141.26.71.188]) by deliver.uni-koblenz.de (Postfix) with ESMTP id 9C21F7800773; Wed, 10 Sep 2008 12:59:58 +0200 (CEST) Mail-Copies-To: never Mail-Followup-To: emacs-devel@gnu.org, "Lennart Borgman \(gmail\)" In-Reply-To: <48C7A31A.3000500@gmail.com> (Lennart Borgman's message of "Wed, 10 Sep 2008 12:36:10 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) X-Virus-Scanned: amavisd-new at uni-koblenz.de X-detected-kernel: by monty-python.gnu.org: Linux 2.6, seldom 2.4 (older, 4) 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:103758 Archived-At: "Lennart Borgman (gmail)" writes: Hi Lennart, > I think there are a number of packages out there doing quite similar > things: smart-tab, tabkey2, hippi-expand. I know, and I think it's bad that each and every package tries to reinvent the wheel, so I propose a more general approach. Here's an improved version which gets rid of the cl dependency. IMO this could be added to emacs. --8<---------------cut here---------------start------------->8--- (defmacro define-context-key (mode key predicate function) "Bind KEY in MODE's map to a command which calls FUNCTION if PREDICATE is non-nil. If PREDICATE doesn't match and KEY is normally bound in MODE, the corresponding default command will be executed. If KEY isn't normally bound in MODE, MODE will be disabled temporally (to prevent an infinite recursion) and the function which is then bound to KEY will be called." (let* ((keymap (intern (concat (symbol-name mode) "-map"))) (default-fun (lookup-key (symbol-value keymap) (eval key)))) `(define-key ,keymap ,key (lambda () (interactive) (if (funcall (quote ,predicate)) (call-interactively (quote ,function)) (if (quote ,default-fun) (call-interactively (quote ,default-fun)) (let (,mode) (call-interactively (key-binding ,key))))))))) --8<---------------cut here---------------end--------------->8--- Multiple calls operate cumulative, so something like this works beautiful. --8<---------------cut here---------------start------------->8--- (defun outline-context-p () (save-excursion (goto-char (line-beginning-position)) (looking-at outline-regexp))) (define-context-key outline-minor-mode (kbd "TAB") outline-context-p outline-toggle-children) (define-context-key outline-minor-mode (kbd "TAB") eolp self-insert-command) --8<---------------cut here---------------end--------------->8--- Bye, Tassilo -- One time, at band camp, Chuck Norris ate a percussionist.