From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.devel Subject: [PATCHv2] Add cycle-spacing command. Date: Mon, 10 Dec 2012 15:57:45 +0100 Message-ID: References: NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1355151512 4874 80.91.229.3 (10 Dec 2012 14:58:32 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 10 Dec 2012 14:58:32 +0000 (UTC) To: emacs-devel@gnu.org, Drew Adams Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Dec 10 15:58:46 2012 Return-path: Envelope-to: ged-emacs-devel@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 1Ti4oc-0005qg-Ou for ged-emacs-devel@m.gmane.org; Mon, 10 Dec 2012 15:58:42 +0100 Original-Received: from localhost ([::1]:58897 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ti4oQ-0000Xi-8Q for ged-emacs-devel@m.gmane.org; Mon, 10 Dec 2012 09:58:30 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:45841) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ti4oH-0000XG-Ky for emacs-devel@gnu.org; Mon, 10 Dec 2012 09:58:28 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ti4oE-0001lD-S1 for emacs-devel@gnu.org; Mon, 10 Dec 2012 09:58:21 -0500 Original-Received: from mail-ee0-f41.google.com ([74.125.83.41]:58091) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ti4oE-0001k4-HW for emacs-devel@gnu.org; Mon, 10 Dec 2012 09:58:18 -0500 Original-Received: by mail-ee0-f41.google.com with SMTP id d41so1806077eek.0 for ; Mon, 10 Dec 2012 06:58:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references; bh=ayU/o+Q2QyyDFggPJI6kiYyHubPjKRfp5xRPJg7q4Lg=; b=IFjc3O/aTfAlpqHr1vR2h5JzeHylIuzJPZSDKNA41MeIHf2V07Bl3iw0v/OezaFxE3 nP20riCy77tj7T9hlgEjtHshzyM9GocgLHQ5Iy1YiZYHa49VQz2Yq6w4ydd3UapnuzcC QXAhqe/gatORVdrZcZ/LFNCf3Vi0oxMG8uywfZ9eJfoyi2FuQGILrrR2Eys1Z99Dq0LN tTaPZ4y34L6GBvR5n02h3EVDH/dmQuLaHWEodkuJwxkJmZOHLFSzVYa96M9ReBTzv1Fb PYhYJfs5l+P33vohTvUBRK/lmMPS7KMipOG0LhnD6r+L7QbZ48rxEJAjiA87j37dA3so Jebg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=ayU/o+Q2QyyDFggPJI6kiYyHubPjKRfp5xRPJg7q4Lg=; b=DN1RdjznhGR44iTizTv6EZ7sgHaiACNk5aJEGMlPNSPpy7O19i4zIEIUIll1ovZrAk ITTN+QRFQKiBoSdZZp80gVg81lmcAwcwrWch7Pi2qdNALR+4jo6uyiXyTeyo5+RCLUQ3 CKgDlBgIMfRB75CGKb2+oW8ckt2pngSW/wZ62Bcu95HyRp5eG8S7OyTBfr7Qdk3+qVqI VgOzR/npqZaZ2FLm3Vx7z+kvb4Rl23YenMn6tRCeCX/Cm2n8weYWpEmwsfn68meSNjh1 jqMFY3UzaU7hvK4lTHEAlieXPSJBHWoolSuBZEyWD2z4DIAljgf2uAFSY+H+uehVMGxR jELQ== Original-Received: by 10.14.194.4 with SMTP id l4mr50216917een.42.1355151496597; Mon, 10 Dec 2012 06:58:16 -0800 (PST) Original-Received: from mpn-glaptop.corp.google.com ([2620:0:105f:5:f482:2cad:d2bf:6a29]) by mx.google.com with ESMTPS id 44sm44015731eek.0.2012.12.10.06.58.14 (version=SSLv3 cipher=OTHER); Mon, 10 Dec 2012 06:58:15 -0800 (PST) X-Mailer: git-send-email 1.7.7.3 In-Reply-To: X-Gm-Message-State: ALoCoQlHZ8Gt9BfAA+2W69kfCRYSX7LnXC1XG3F64k/2gRLvqCZmNEMwXCV98i8B+aWfAliTEeyBHjsb8zX9VOpaLgolJHNv5QsnkpYVjaiYRuSUmhBrj0U9HLzpJgDmSR38C7OpLtdtfgzC4iLTnJXtrYFmVYvC+OKjEdWqle/zwRgTrSqs1Tw47WOeSUkjwSwftU29puTFQxxX85Oz0iHRF5U+KUh9dg== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 74.125.83.41 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:155433 Archived-At: From: Michal Nazarewicz This commit adds a cycle-spacing command which is, in a sense, generalisation of the just-on-space command. When run continuously, it cycles between having only one space, having no spaces and original spacing. --- etc/NEWS | 5 +++ lisp/ChangeLog | 4 ++ lisp/simple.el | 86 ++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 15 deletions(-) v2: changed name to cycle-spacing diff --git a/etc/NEWS b/etc/NEWS index 77e7e47..8112573 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -92,6 +92,11 @@ when its arg ADJACENT is non-nil (when called interactively with C-u C-u) it works like the utility `uniq'. Otherwise by default it deletes duplicate lines everywhere in the region without regard to adjacency. +** New `cycle-spacing' command allows cycling between having just one +space, no spaces, or reverting to the original spacing. Like +`just-one-space' command it can handle or ignore newlines and use +leave different number of spaces. + ** Tramp +++ *** New connection method "adb", which allows to access Android diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7f05613..7ac779a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2012-12-10 Michal Nazarewicz + + * simple.el: Add cycle-spacing command. + 2012-12-10 Eli Zaretskii * subr.el (w32notify-handle-event): New function. diff --git a/lisp/simple.el b/lisp/simple.el index 78b7657..dcb8cf7 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -742,25 +742,81 @@ If BACKWARD-ONLY is non-nil, only delete them before point." (skip-chars-backward " \t") (constrain-to-field nil orig-pos))))) +(defvar cycle-spacing--context nil + "Store context used in consecutive calls to `cycle-spacing' command. +The first time this function is run, it saves the original point +position and original spacing around the point in this +variable.") + +(defun cycle-spacing (&optional n preserve-nl-back single-shot) + "Manipulate spaces around the point in a smart way. + +When run as an interactive command, the first time it's called +in a sequence, deletes all spaces and tabs around point leaving +one (or N spaces). If this does not change content of the +buffer, skips to the second step: + +When run for the second time in a sequence, deletes all the +spaces it has previously inserted. + +When run for the third time, returns the whitespace and point in +a state encountered when it had been run for the first time. + +For example, if buffer contains \"foo ^ bar\" with \"^\" donating the +point, calling `cycle-spacing' command will replace two spaces with +a single space, calling it again immediately after, will remove all +spaces, and calling it for the third time will bring two spaces back +together. + +If N is negative, delete newlines as well. However, if +PRESERVE-NL-BACK is t new line characters prior to the point +won't be removed. + +If SINGLE-SHOT is non-nil, will only perform the first step. In +other words, it will work just like `just-on-space' command." + (interactive "*p") + (let ((orig-pos (point)) + (skip-characters (if (and n (< n 0)) " \t\n\r" " \t")) + (n (abs (or n 1)))) + (skip-chars-backward (if preserve-nl-back " \t" skip-characters)) + (constrain-to-field nil orig-pos) + (cond + ;; Command run for the first time or single-shot is non-nil + ((or single-shot + (not (equal last-command this-command)) + (not cycle-spacing--context)) + (let* ((start (point)) + (n (- n (skip-chars-forward " " (+ n (point))))) + (mid (point)) + (end (progn + (skip-chars-forward skip-characters) + (constrain-to-field nil orig-pos t)))) + (setq cycle-spacing--context ;; Save for later + ;; Special handling for case where there was no space at all + (unless (= start end) + (cons orig-pos (buffer-substring start (point))))) + ;; If this run causes no change in buffer content, delete all spaces, + ;; otherwise delete all excees spaces. + (delete-region (if (and (not single-shot) (zerop n) (= mid end)) + start mid) end) + (dotimes (_ n) + (insert ?\s)))) + + ;; Command run for the second time + ((not (equal orig-pos (point))) + (delete-region (point) orig-pos)) + + ;; Command run for the third time + (t + (insert (cdr cycle-spacing--context)) + (goto-char (car cycle-spacing--context)) + (setq cycle-spacing--context nil))))) + (defun just-one-space (&optional n) "Delete all spaces and tabs around point, leaving one space (or N spaces). If N is negative, delete newlines as well, leaving -N spaces." (interactive "*p") - (unless n (setq n 1)) - (let ((orig-pos (point)) - (skip-characters (if (< n 0) " \t\n\r" " \t")) - (n (abs n))) - (skip-chars-backward skip-characters) - (constrain-to-field nil orig-pos) - (dotimes (i n) - (if (= (following-char) ?\s) - (forward-char 1) - (insert ?\s))) - (delete-region - (point) - (progn - (skip-chars-forward skip-characters) - (constrain-to-field nil orig-pos t))))) + (cycle-spacing n nil t)) (defun beginning-of-buffer (&optional arg) "Move point to the beginning of the buffer. -- 1.7.7.3