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: [PATCHv5] Add cycle-spacing command. Date: Mon, 28 Jan 2013 14:51:28 +0100 Message-ID: NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1359382912 25695 80.91.229.3 (28 Jan 2013 14:21:52 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 28 Jan 2013 14:21:52 +0000 (UTC) To: "Stephen J. Turnbull" , emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Jan 28 15:22:12 2013 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 1Tzpb8-0001Cp-KV for ged-emacs-devel@m.gmane.org; Mon, 28 Jan 2013 15:22:10 +0100 Original-Received: from localhost ([::1]:38645 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tzpaq-0006pQ-QR for ged-emacs-devel@m.gmane.org; Mon, 28 Jan 2013 09:21:52 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:56851) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tzpal-0006oK-Ad for emacs-devel@gnu.org; Mon, 28 Jan 2013 09:21:50 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TzpaZ-0007KM-Nt for emacs-devel@gnu.org; Mon, 28 Jan 2013 09:21:47 -0500 Original-Received: from mail-wg0-f50.google.com ([74.125.82.50]:41380) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TzpaZ-0007JT-Dc for emacs-devel@gnu.org; Mon, 28 Jan 2013 09:21:35 -0500 Original-Received: by mail-wg0-f50.google.com with SMTP id es5so1784657wgb.5 for ; Mon, 28 Jan 2013 06:21:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:subject:date:message-id:x-mailer; bh=JR4VcxMn3Ur74kW3B15mevSi8L1mE9FRs+UTK8hDLCM=; b=LGfDbACzcfv+9xfFqQOQ8u1dHzbKPSSwcOBs6QHazzM1RCkYLmxKIG7ldhDAZ7o1/0 a2OGD8joV4KRc6imWtahfxwRHs22jSSVCqKI45qhnMbLsJzIZdv+jTSQFc4kH4jqMjiA Whu868523/YvasOLYLm/nLNtU440E1IP48ThPCpfi8QLKVd6OchZkfi3n6WcKYn58jlZ q+E/BR37olLabCDvaI8Sb9vhi7yvyPg/5VzaQ8Dka2Yt3nc5lV4XwKB6WJ7Cma8I0dt4 9lAdN4dm+vo4CDF05ypqjH1epHZvLRadu87i38Yr7Tp8iHHupx8vHR0eALZNPEuUGkPt Wb+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:subject:date:message-id:x-mailer :x-gm-message-state; bh=JR4VcxMn3Ur74kW3B15mevSi8L1mE9FRs+UTK8hDLCM=; b=Eax88XLi7jCDlisJbDv7lEXdrXqGLMNs0AeOIWnUzxSOU192ECbGuUIsL4QrSebCRE YB0pU5IsCcoSh080WDk4sTxsUXIAgDakF0tXizB4u8NWe6LqEqi9W5fTeuD1R4jFRqtm WumpvRI7R5WpifCnTNF4lK8dKVd1rriHVA0QLJLaJFZK4wGvNY3c+AUkBS3HV/jSW1iY OQV4d7SUw9BayjgJmLjn9zXKHzeIdEKVgPPswAO8VN39UsKZMKu+ab2LN8e5pqACKS/L 5rgqsfL1bGPRIAZrq4v5LI+/xd0l3+XdmTQGLoAk4FxAgdFTh9X8E9U/85NvA5IUaLXS 5gSw== X-Received: by 10.194.94.37 with SMTP id cz5mr12676202wjb.49.1359381096469; Mon, 28 Jan 2013 05:51:36 -0800 (PST) Original-Received: from mpn-glaptop.corp.google.com ([2620:0:105f:5:6dde:7ebc:bc02:2f33]) by mx.google.com with ESMTPS id gz3sm12210452wib.2.2013.01.28.05.51.34 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 28 Jan 2013 05:51:35 -0800 (PST) X-Mailer: git-send-email 1.8.1 X-Gm-Message-State: ALoCoQkZD/VOTmS+SGtVwpbezOpQWyZ1JU6eyi+X4spC2AIYdRilKDOyvy8rXKwmJR84ESMNxY0PnNxll4qBn0xCkSVD6XnX0OdwHBwz+Fkn3zcj5DSZd5eds5vUUnmJdQeZ+dNfu3Me8b0MqRaGreVtyAaQvCHB3xA9BOcgHqAjGuKJQFIKEQCpFQXhRblH6aG7VSsTc80/ X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 74.125.82.50 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:156707 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. --- > Michal Nazarewicz writes: >> +** 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. On Sat, Jan 26 2013, "Stephen J. Turnbull" wrote: > Typo: "use leave". You probably meant just "leave". > >> +If SINGLE-SHOT is non-nil, will only perform the first step. In >> +other words, it will work just like `just-on-space' command." > > Typo: I think you mean "`just-one-space' command." Thanks, both fixed. etc/NEWS | 5 ++++ lisp/ChangeLog | 4 +++ lisp/simple.el | 86 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 3e8bd3e..500e303 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -157,6 +157,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 +leave different number of spaces. + ** Tramp +++ *** New connection method "adb", which allows to access Android diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 17a4a99..0ac59ff 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-01-26 Michal Nazarewicz + + * simple.el: Add cycle-spacing command. + 2013-01-25 Alan Mackenzie AWK Mode: Fix indentation bug at top level. Bug #12274. diff --git a/lisp/simple.el b/lisp/simple.el index 847c07a..273dc16 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 \"^\" denoting 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-one-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 (i 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 (_ 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.