From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.bugs Subject: bug#18729: [PATCH] subr.el (set-key): New macro making creating new bindings more concise. Date: Wed, 15 Oct 2014 09:48:49 +0200 Organization: Google Inc Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1413359425 23720 80.91.229.3 (15 Oct 2014 07:50:25 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 15 Oct 2014 07:50:25 +0000 (UTC) To: 18729@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Oct 15 09:50:18 2014 Return-path: Envelope-to: geb-bug-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 1XeJLc-0006Ee-Uv for geb-bug-gnu-emacs@m.gmane.org; Wed, 15 Oct 2014 09:50:17 +0200 Original-Received: from localhost ([::1]:42540 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJLc-0002NV-LD for geb-bug-gnu-emacs@m.gmane.org; Wed, 15 Oct 2014 03:50:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37948) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJLU-0002Kl-8q for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:50:13 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XeJLQ-0004XK-2z for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:50:08 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:52265) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJLP-0004X1-WA for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:50:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1XeJLO-0001Zz-PK for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:50:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Michal Nazarewicz Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 15 Oct 2014 07:50:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 18729 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.14133593545996 (code B ref -1); Wed, 15 Oct 2014 07:50:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 15 Oct 2014 07:49:14 +0000 Original-Received: from localhost ([127.0.0.1]:43829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1XeJKb-0001Yd-Ga for submit@debbugs.gnu.org; Wed, 15 Oct 2014 03:49:14 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:36010) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1XeJKY-0001YU-4x for submit@debbugs.gnu.org; Wed, 15 Oct 2014 03:49:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XeJKT-0004BQ-6l for submit@debbugs.gnu.org; Wed, 15 Oct 2014 03:49:09 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:42527) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJKT-0004BJ-2g for submit@debbugs.gnu.org; Wed, 15 Oct 2014 03:49:05 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJKO-000277-7p for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:49:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XeJKJ-00048O-Db for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:49:00 -0400 Original-Received: from mail-wi0-x234.google.com ([2a00:1450:400c:c05::234]:35826) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XeJKJ-00047z-2Q for bug-gnu-emacs@gnu.org; Wed, 15 Oct 2014 03:48:55 -0400 Original-Received: by mail-wi0-f180.google.com with SMTP id em10so1073482wid.13 for ; Wed, 15 Oct 2014 00:48:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:subject:organization:user-agent:face:date:message-id :mime-version:content-type; bh=LUUHPjufHz3UCHfSBFsHq9C9+eqixICTyGINq7BtNws=; b=NkO10w9lm4wTardG/LGs6s6PkIGBo3QR3W3snwbDEQc2zgjS57IR36pK3px2edj7Ti tpY2JTAPL9bfLk9D/AkM/pZQcKqfjei35TkUsEnym93gyCt3ctRkMU3ACHNCLW5s7eFH 7Uhq4DVaVWMHikE8QXHZZd9UWeMHQ5dx1d8BTeS16HCKmhZKE5F6gyy+wVGsHc0jQ7Yx 98eKaRP7yR+vhGt5i6JCvLsi7y3BGL1qrkwk9W89WGEbCio4Ak6vo/mnebCY65sNns1W l6uPn1WzmZCmhW5AuQtXj8rA/22StJ63Pw8A7uSDbfAL3l/ujwQXVUL86fWsMxcLqMdk GtGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:subject:organization:user-agent :face:date:message-id:mime-version:content-type; bh=LUUHPjufHz3UCHfSBFsHq9C9+eqixICTyGINq7BtNws=; b=gdeN2RpwqK7nV/QbRgG9W7e+uJccIsdSwRNB/+/5IIsbve2/SfL2/uwh5UIyyeASfD xiWXZ1p11YYSBNpfky0C5WIVvOj01x+eFiC4k82g7ixJVgyNiC56kJza7StPH5nQoLZ5 yVgsb/9JzRTLQ7mTSGwxFv5JlEiaPrrpaqyKzGzEraWfRLciYHjhnaxlzjhPdi6VywgF gy+C+iJZcCM/PxPZe2Hp49PTQ2ubJ2IS7X6rSYFXSFJQVKvi3tWSosNfXXQQbIT34/fM UvKzDJTZcuNrtF3swL691mWkuSxAoOxQ61h/q2jKiHo2q0zz424neWEDffMphhzvkRXp ShEg== X-Gm-Message-State: ALoCoQkaNsKlfw6wkUq2CF/WcOuHBsffcFwXNPQ7EmaAX4izUusLCJR5pnbayTPDOUpTBDOZzCKl X-Received: by 10.194.200.10 with SMTP id jo10mr10175089wjc.11.1413359333455; Wed, 15 Oct 2014 00:48:53 -0700 (PDT) Original-Received: from mpn-glaptop.roam.corp.google.com ([62.156.150.204]) by mx.google.com with ESMTPSA id w10sm22837775wje.10.2014.10.15.00.48.50 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 15 Oct 2014 00:48:51 -0700 (PDT) User-Agent: Notmuch/0.17+15~gb65ca8e (http://notmuchmail.org) Emacs/24.4.50.1 (x86_64-unknown-linux-gnu) X-Face: PbkBB1w#)bOqd`iCe"Ds{e+!C7`pkC9a|f)Qo^BMQvy\q5x3?vDQJeN(DS?|-^$uMti[3D*#^_Ts"pU$jBQLq~Ud6iNwAw_r_o_4]|JO?]}P_}Nc&"p#D(ZgUb4uCNPe7~a[DbPG0T~!&c.y$Ur,=N4RT>]dNpd; KFrfMCylc}gc??'U2j,!8%xdD Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAJFBMVEWbfGlUPDDHgE57V0jUupKjgIObY0PLrom9mH4dFRK4gmjPs41MxjOgAAACQElEQVQ4jW3TMWvbQBQHcBk1xE6WyALX1069oZBMlq+ouUwpEQQ6uRjttkWP4CmBgGM0BQLBdPFZYPsyFUo6uEtKDQ7oy/U96XR2Ux8ehH/89Z6enqxBcS7Lg81jmSuujrfCZcLI/TYYvbGj+jbgFpHJ/bqQAUISj8iLyu4LuFHJTosxsucO4jSDNE0Hq3hwK/ceQ5sx97b8LcUDsILfk+ovHkOIsMbBfg43VuQ5Ln9YAGCkUdKJoXR9EclFBhixy3EGVz1K6eEkhxCAkeMMnqoAhAKwhoUJkDrCqvbecaYINlFKSRS1i12VKH1XpUd4qxL876EkMcDvHj3s5RBajHHMlA5iK32e0C7VgG0RlzFPvoYHZLRmAC0BmNcBruhkE0KsMsbEc62ZwUJDxWUdMsMhVqovoT96i/DnX/ASvz/6hbCabELLk/6FF/8PNpPCGqcZTGFcBhhAaZZDbQPaAB3+KrWWy2XgbYDNIinkdWAFcCpraDE/knwe5DBqGmgzESl1p2E4MWAz0VUPgYYzmfWb9yS4vCvgsxJriNTHoIBz5YteBvg+VGISQWUqhMiByPIPpygeDBE6elD973xWwKkEiHZAHKjhuPsFnBuArrzxtakRcISv+XMIPl4aGBUJm8Emk7qBYU8IlgNEIpiJhk/No24jHwkKTFHDWfPniR 4iw5vJaw2nzSjfq2zffcE/GDjRC2dn0J0XwPAbDL84TvaFCJEU4Oml9pRyEUhR3Cl2t01AoEjRbs0sYugp14/4X5n4pU4EHHnMAAAAAElFTkSuQmCC X-PGP: 50751FF4 X-PGP-FP: AC1F 5F5C D418 88F8 CC84 5858 2060 4012 5075 1FF4 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:94523 --- lisp/ChangeLog | 6 +++++ lisp/subr.el | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) I found this macro very convenient for my configuration file, so perhaps it's a good match for inclusion in Emacs? It handles the majority of uses of diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6916143..a5c4632 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2014-10-15 Michal Nazarewicz + + * subr.el (set-key): New macro making creating new bindings more + concise and thus somehow easier/faster to type in user + configuration file. + 2014-10-15 Eli Zaretskii * emacs-lisp/tabulated-list.el (tabulated-list-mode): Force diff --git a/lisp/subr.el b/lisp/subr.el index 585f936..9b1ceb3 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -836,6 +836,79 @@ cases is shared with all other buffers in the same major mode." (signal 'wrong-type-argument (list 'arrayp key))) (define-key map key command))) +(defun set-key--current-local-map () + "Return current local map creating one if not set yet." + (or (current-local-map) + (let ((map (make-sparse-keymap))) + (use-local-map map) + map))) + +(defmacro set-key (keymap key &rest def) + "(set-key [KEYMAP] KEY . DEF) + +In KEYMAP, define key sequence KEY as DEF. + +KEYMAP can be :global (to mean global keymap, the default), :local (to mean +the local keymap) or an unquoted symbol (to mean a keymap in given variable). + +KEY is anything `define-key' accepts as a key except that if KEYMAP was not +given, KEY cannot be an unquoted symbol, i.e.: + (let ((key \"a\")) + (set-key key self-insert-command) ; will *not* work + (set-key :global key self-insert-command)) ; will work + +If DEF is a single unquoted symbol it will be quoted, otherwise if it is +a single non-cons value it will not be quoted, otherwise it will be processed +as a lambda (see below). Thus the following do what one might expect: + (set-key \"a\" self-insert-command) + ;; same as (global-set-key \"a\" 'self-insert-command) + (set-key \"\\C-h\" [(backspace)]) + ;; same as (global-set-key \"\\C-h\" [(backspace)]) + (set-key \"\\C-d\" ()) + ;; same as (global-set-key \"\\C-h\" ()) +However, the following will not work: + (let ((callback 'self-insert-command)) + (set-key \"a\" callback)) + ;; same as (global-set-key \"a\" 'callback) + +If DEF is a cons value its format is: + ([:args ARGS INTERACTIVE] . BODY) +and results in the following lambda: + (lambda ARGS (interactive INTERACTIVE) . BODY) +or if :args is not given (at which point DEF == BODY): + (lambda () (interactive) . BODY) +For example: + (set-key \"\\C-B\" (goto-char (- (point) 2))) + ;; same as (global-set-key \"\\C-B\" + ;; (lambda () (interactive) (goto-char (- (point) 2)))) + (set-key \"\\C-B\" :args (n) \"P\" (goto-char (- (point) (* 2 n)))) + ;; same as (global-set-key \"\\C-B\" + ;; (lambda (n) (interactive \"P\") + ;; (goto-char (- (point) (* 2 n))))) + +This macro is not a replacement for `define-key', `global-set-key' or +`local-set-key', since it is not capable of dealing with some forms of DEFs +that those functions accept. Instead it is meant as a helper to use in user +configuration file to make setting up bindings more concise especially when +lambdas are used." + (setq keymap (cond ((eq :local keymap) '(set-key--current-local-map)) + ((eq :global keymap) '(current-global-map)) + ((symbolp keymap) keymap) + (t + (setq def (cons key def) key keymap) ; shift args + '(current-global-map)))) + (unless def + (error "DEF argument missing")) + (list + 'define-key keymap key + (cond ((or (cdr def) (consp (car def))) + (let ((args (if (eq :args (car def)) (cadr def))) + (interactive (if (eq :args (car def)) (list (car (cddr def))))) + (body (if (eq :args (car def)) (cdr (cddr def)) def))) + `(function (lambda ,args (interactive . ,interactive) ,@body)))) + ((symbolp (car def)) (list 'quote (car def))) + ((car def))))) + (defun global-unset-key (key) "Remove global binding of KEY. KEY is a string or vector representing a sequence of keystrokes."