* Brave new mark-defun (and a testing tool) @ 2017-02-08 6:01 Marcin Borkowski 2017-02-12 7:09 ` John Wiegley 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-08 6:01 UTC (permalink / raw) To: Emacs developers Hi all, after several months of on-and-off work on bug#21072, I have implemented two (hopefully) nice features. One is an (almost) completely new version of mark-defun, which I hope works much better than the previous one: --8<---------------cut here---------------start------------->8--- (defun in-comment-line-p () "Return non-nil if the point is in a comment line." ;; See http://lists.gnu.org/archive/html/help-gnu-emacs/2016-08/msg00141.html (save-excursion (forward-line 0) (unless (looking-at "^\\s-*$") (< (line-end-position) (let ((ppss (syntax-ppss))) (when (nth 4 ppss) (goto-char (nth 8 ppss))) (forward-comment (point-max)) (point)))))) (defun beginning-of-defun-comments (&optional arg) "Move to the beginning of ARGth defun, including comments." (interactive "^p") (unless arg (setq arg 1)) (beginning-of-defun arg) (let (nbobp) (while (progn (setq nbobp (zerop (forward-line -1))) (and (in-comment-line-p) nbobp))) (when nbobp (forward-line 1)))) (defun mark-defun (&optional arg) "Put mark at end of this defun, point at beginning. The defun marked is the one that contains point or follows point. With positive ARG, mark this and that many next defuns; with negative ARG, change the direction of marking. If the mark is active, it marks the next or previous defun(s) after the one(s) already marked." (interactive "p") (setq arg (or arg 1)) ;; There is no `mark-defun-back' function - see ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-11/msg00079.html ;; for explanation (when (eq last-command 'mark-defun-back) (setq arg (- arg))) (when (< arg 0) (setq this-command 'mark-defun-back)) (cond ((use-region-p) (if (>= arg 0) (set-mark (save-excursion (goto-char (mark)) ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed (dotimes (_ignore arg) (end-of-defun)) (point))) (beginning-of-defun-comments (- arg)))) (t (let ((opoint (point)) beg end) (push-mark opoint) ;; Try first in this order for the sake of languages with nested ;; functions where several can end at the same place as with the ;; offside rule, e.g. Python. (beginning-of-defun-comments) (setq beg (point)) (end-of-defun) (setq end (point)) (when (or (and (<= (point) opoint) (> arg 0)) (= beg (point-min))) ; we were before the first defun! ;; beginning-of-defun moved back one defun so we got the wrong ;; one. If ARG < 0, however, we actually want to go back. (goto-char opoint) (end-of-defun) (setq end (point)) (beginning-of-defun-comments) (setq beg (point))) (goto-char beg) (cond ((> arg 0) ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed (dotimes (_ignore arg) (end-of-defun)) (setq end (point)) (push-mark end nil t) (goto-char beg)) (t (goto-char beg) (unless (= arg -1) ; beginning-of-defun behaves ; strange with zero arg - see ; https://lists.gnu.org/archive/html/bug-gnu-emacs/2017-02/msg00196.html (beginning-of-defun (1- (- arg)))) (push-mark end nil t)))))) (let (nbobp) (while (progn (setq nbobp (zerop (forward-line -1))) (and (looking-at "^\\s-*$") nbobp))) (when nbobp (forward-line 1)))) --8<---------------cut here---------------end--------------->8--- Aside from that, I spent a considerable time writing ERT tests for that function, and to that end I developed the macro below. It's main goal is to be able to specify contents of a test buffer together with a set of named positions in that buffer, so that we can test commands that move the point and/or mark around easily. --8<---------------cut here---------------start------------->8--- (defvar elisp-test-point-marker-regex "=!\\([a-zA-Z0-9-]+\\)=" "A regexp matching placeholders for point position for `elisp-tests-with-temp-buffer'.") ;; Copied and heavily modified from `python-tests-with-temp-buffer' (defmacro elisp-tests-with-temp-buffer (contents &rest body) "Create an `emacs-lisp-mode' enabled temp buffer with CONTENTS. BODY is the code to be executed within the temp buffer. Point is always located at the beginning of buffer. Special markers of the form =!NAME= in CONTENTS are removed, and a for each one a variable called NAME is bound to the position of such a marker." (declare (indent 1) (debug t)) `(with-temp-buffer (emacs-lisp-mode) (insert ,contents) (goto-char (point-min)) (while (re-search-forward elisp-test-point-marker-regex nil t) (delete-region (match-beginning 0) (match-end 0))) (goto-char (point-min)) ,(let (marker-list) (with-temp-buffer (insert (cond ((symbolp contents) (symbol-value contents)) (t contents))) (goto-char (point-min)) (while (re-search-forward elisp-test-point-marker-regex nil t) (push (list (intern (match-string-no-properties 1)) (match-beginning 0)) marker-list) (delete-region (match-beginning 0) (match-end 0)))) `(let ,marker-list ,@body)))) --8<---------------cut here---------------end--------------->8--- Here's how you can use it: --8<---------------cut here---------------start------------->8--- (defvar mark-defun-test-buffer ";; Comment header =!before-1= \(defun func-1 (arg) =!inside-1=\"docstring\" body) =!after-1==!before-2= ;; Comment before a defun \(d=!inside-2=efun func-2 (arg) \"docstring\" body) =!after-2==!before-3= \(defun func-3 (arg) \"docstring\"=!inside-3= body) =!after-3==!before-4=(defun func-4 (arg) \"docstring\"=!inside-4= body) =!after-4= ;; end " "Test buffer for `mark-defun'.") (ert-deftest mark-defun-no-arg-region-inactive () "Test `mark-defun' with no prefix argument and inactive region." (setq last-command nil) (elisp-tests-with-temp-buffer mark-defun-test-buffer ;; mark-defun inside a defun, with comments and an empty line ;; before (goto-char inside-1) (mark-defun) (should (= (point) before-1)) (should (= (mark) after-1)) ;; mark-defun inside a defun with comments before (deactivate-mark) (goto-char inside-2) (mark-defun) (should (= (point) before-2)) (should (= (mark) after-2)) ;; mark-defun inside a defun with empty line before (deactivate-mark) (goto-char inside-3) (mark-defun) (should (= (point) before-3)) (should (= (mark) after-3)) ;; mark-defun inside a defun with another one right before (deactivate-mark) (goto-char inside-4) (mark-defun) (should (= (point) before-4)) (should (= (mark) after-4)) ;; mark-defun between a comment and a defun (deactivate-mark) (goto-char before-1) (mark-defun) (should (= (point) before-1)) (should (= (mark) after-1)) ;; mark-defun between defuns (deactivate-mark) (goto-char before-3) (mark-defun) (should (= (point) before-3)) (should (= (mark) after-3)) ;; mark-defun in comment right before the defun (deactivate-mark) (goto-char before-2) (mark-defun) (should (= (point) before-2)) (should (= (mark) after-2)))) --8<---------------cut here---------------end--------------->8--- WDYT? -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-08 6:01 Brave new mark-defun (and a testing tool) Marcin Borkowski @ 2017-02-12 7:09 ` John Wiegley 2017-02-12 10:10 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: John Wiegley @ 2017-02-12 7:09 UTC (permalink / raw) To: Marcin Borkowski; +Cc: Emacs developers >>>>> "MB" == Marcin Borkowski <mbork@mbork.pl> writes: MB> after several months of on-and-off work on bug#21072, I have implemented MB> two (hopefully) nice features. One is an (almost) completely new MB> version of mark-defun, which I hope works much better than the previous MB> one: Can you clarify in what ways it is better? Reading through the text you attached did not make it obvious to me... Thanks, -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-12 7:09 ` John Wiegley @ 2017-02-12 10:10 ` Marcin Borkowski 2017-02-12 10:13 ` Marcin Borkowski 2017-02-12 21:29 ` John Wiegley 0 siblings, 2 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-02-12 10:10 UTC (permalink / raw) To: John Wiegley; +Cc: Emacs developers On 2017-02-12, at 08:09, John Wiegley <jwiegley@gmail.com> wrote: >>>>>> "MB" == Marcin Borkowski <mbork@mbork.pl> writes: > > MB> after several months of on-and-off work on bug#21072, I have implemented > MB> two (hopefully) nice features. One is an (almost) completely new > MB> version of mark-defun, which I hope works much better than the previous > MB> one: > > Can you clarify in what ways it is better? Reading through the text you > attached did not make it obvious to me... Well, sorry for that - all details are in the quite extensive thread about bug 21072. Here's a short summary of what "my" mark-defun tries to accomplish (I hope my memory serves me well here...) in case you have better things to do than reading through tens of old messages;-). 0. In order to test mark-defun more easily, I introduced the elisp-tests-with-temp-buffer macro. It accepts a string (or a string-valued variable) and runs the rest of its body in an Elisp buffer with that very string, with the exception that you can put special "markers" in that string (by default, of the form "=!name="), these markers are deleted from the temp buffer, and variables called "name" etc. are then bound to markers pointing at these positions. I would very much like some experienced Elisp hackers to look at it - I'm not sure it is entirely correct/elegant. 1. mark-defun is now extensively tested - it comes with a suite of about two dozen ert tests. 2. Bug#21072 is fixed - mark-defun between defuns marks the following defun, as its docstring and the manual say. 3. Both positive and negative arguments work correctly when the region is inactive (i.e., the right number of defuns are marked, either after or before the point). Both Drew and me (in the mentioned discussion) agreed that this is better than the allow-extend argument used now (which is probably quite useless anyway). 4. When the region is active, mark-defun selects one more defun (assuming that the region contains one or more defuns already - this is not checked), or abs(N) more defuns with an argument. With negative argument, the direction of selecting defuns is reversed (for the sake of following mark-defun commands). > Thanks, You're welcome, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-12 10:10 ` Marcin Borkowski @ 2017-02-12 10:13 ` Marcin Borkowski 2017-02-12 21:29 ` John Wiegley 1 sibling, 0 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-02-12 10:13 UTC (permalink / raw) To: John Wiegley; +Cc: Emacs developers Hey, one more thing. On 2017-02-12, at 11:10, Marcin Borkowski <mbork@mbork.pl> wrote: > On 2017-02-12, at 08:09, John Wiegley <jwiegley@gmail.com> wrote: > >> Can you clarify in what ways it is better? Reading through the text you >> attached did not make it obvious to me... Here's a fragment from one of Drew's messages from the thread I mentioned in my previous message. --8<---------------cut here---------------start------------->8--- What might be better? 1. At least consistency wrt which defun gets selected, when betweeen defuns. The doc suggests a general rule (the next defun), but that is not always respected. 2. Something consistent also wrt a comment before the defun that will be selected. 3. It could be good for a numeric prefix arg to select that many defuns. 4. It could be good for a negative prefix arg to select in the opposite direction. This is the main improvement I'd like to see. E.g. `M-- C-M-h' selects the previous defun; `M-2 C-M-h' selects the two previous defuns. Someone should play around and dream up something useful. Wrt #2, I'm not sure what the best approach might be. --8<---------------cut here---------------end--------------->8--- 5. I decided to mark the comment together with the defun if there is no empty line between the comment and the defun and leave it unmarked otherwise. I guess this is the most sensible approach I could think of. Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-12 10:10 ` Marcin Borkowski 2017-02-12 10:13 ` Marcin Borkowski @ 2017-02-12 21:29 ` John Wiegley 2017-02-13 11:00 ` Marcin Borkowski 1 sibling, 1 reply; 29+ messages in thread From: John Wiegley @ 2017-02-12 21:29 UTC (permalink / raw) To: Marcin Borkowski; +Cc: Emacs developers >>>>> Marcin Borkowski <mbork@mbork.pl> writes: > mark-defun is now extensively tested - it comes with a suite of about two > dozen ert tests. Well, you've sold me there. :) -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-12 21:29 ` John Wiegley @ 2017-02-13 11:00 ` Marcin Borkowski 2017-02-13 15:16 ` Dmitry Gutov 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-13 11:00 UTC (permalink / raw) To: John Wiegley; +Cc: Emacs developers On 2017-02-12, at 22:29, John Wiegley <jwiegley@gmail.com> wrote: >>>>>> Marcin Borkowski <mbork@mbork.pl> writes: > >> mark-defun is now extensively tested - it comes with a suite of about two >> dozen ert tests. > > Well, you've sold me there. :) Well, don't make fun of a humble mathematician. :-) I figured that if I'm going to heavily change something as fundamental as mark-defun, I'd better be sure I didn't break anything. (In fact, as Drew pointed out, I /did/ break a few things - my earlier tests did not cover enough cases. Hopefully it's better now...) Also, I only tested it in Elisp mode. That's a potential problem... Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-13 11:00 ` Marcin Borkowski @ 2017-02-13 15:16 ` Dmitry Gutov 2017-02-13 15:58 ` Marcin Borkowski 2017-02-13 19:00 ` John Wiegley 0 siblings, 2 replies; 29+ messages in thread From: Dmitry Gutov @ 2017-02-13 15:16 UTC (permalink / raw) To: Marcin Borkowski, John Wiegley; +Cc: Emacs developers On 13.02.2017 13:00, Marcin Borkowski wrote: >>> mark-defun is now extensively tested - it comes with a suite of about two >>> dozen ert tests. >> >> Well, you've sold me there. :) > > Well, don't make fun of a humble mathematician. :-) I'd rather interpret John as being entirely serious. :) Tests are good. > Also, I only tested it in Elisp mode. That's a potential problem... I'm not a frequent user of mark-defun, so I can miss edge cases, but I see the improvement. Thanks! Tested in emacs-lisp-mode and ruby-mode. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-13 15:16 ` Dmitry Gutov @ 2017-02-13 15:58 ` Marcin Borkowski 2017-02-13 19:00 ` John Wiegley 1 sibling, 0 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-02-13 15:58 UTC (permalink / raw) To: Dmitry Gutov; +Cc: John Wiegley, Emacs developers On 2017-02-13, at 16:16, Dmitry Gutov <dgutov@yandex.ru> wrote: > On 13.02.2017 13:00, Marcin Borkowski wrote: > >>>> mark-defun is now extensively tested - it comes with a suite of about two >>>> dozen ert tests. >>> >>> Well, you've sold me there. :) >> >> Well, don't make fun of a humble mathematician. :-) > > I'd rather interpret John as being entirely serious. :) Tests are good. I'm not sure either way. That's why I put a smiley in my response, too;-). >> Also, I only tested it in Elisp mode. That's a potential problem... > > I'm not a frequent user of mark-defun, so I can miss edge cases, but I > see the improvement. Thanks! > > Tested in emacs-lisp-mode and ruby-mode. Thanks a lot. Python might be especially problematic (see comments in code for why). Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Brave new mark-defun (and a testing tool) 2017-02-13 15:16 ` Dmitry Gutov 2017-02-13 15:58 ` Marcin Borkowski @ 2017-02-13 19:00 ` John Wiegley 2017-02-14 10:45 ` bug#21072: " Marcin Borkowski 1 sibling, 1 reply; 29+ messages in thread From: John Wiegley @ 2017-02-13 19:00 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Emacs developers >>>>> Dmitry Gutov <dgutov@yandex.ru> writes: > I'd rather interpret John as being entirely serious. :) Tests are good. Dmitry is quite right; any patch that comes with a battery of new tests is already a huge plus in my book. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-02-13 19:00 ` John Wiegley @ 2017-02-14 10:45 ` Marcin Borkowski 2017-02-14 13:02 ` Dmitry Gutov 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-14 10:45 UTC (permalink / raw) To: John Wiegley; +Cc: Dmitry Gutov, 21072, Emacs developers [-- Attachment #1: Type: text/plain, Size: 539 bytes --] On 2017-02-13, at 20:00, John Wiegley <jwiegley@gmail.com> wrote: >>>>>> Dmitry Gutov <dgutov@yandex.ru> writes: > >> I'd rather interpret John as being entirely serious. :) Tests are good. > > Dmitry is quite right; any patch that comes with a battery of new tests is > already a huge plus in my book. Thanks - as I said, I was a bit unsure;-). Here's my proposed contribution, formatted as two patches. The first one introduces the testing machinery; the second one introduces mark-defun and its tests. WDYT? -- Marcin Borkowski [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-elisp-tests-with-temp-buffer-a-new-testing-macro.patch --] [-- Type: text/x-diff, Size: 2634 bytes --] From 0723e6a7c51bf3924e393e713f3509160d1782a6 Mon Sep 17 00:00:00 2001 From: Marcin Borkowski <mbork@mbork.pl> Date: Tue, 14 Feb 2017 11:30:36 +0100 Subject: [PATCH] Add elisp-tests-with-temp-buffer, a new testing macro * test/lisp/progmodes/elisp-mode-tests.el (elisp-test-point-marker-regex) New variable. (elisp-tests-with-temp-buffer): New macro to help test functions moving the point and/or mark. --- test/lisp/progmodes/elisp-mode-tests.el | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index 93c428b2d2..a00f6b1b43 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -2,6 +2,7 @@ ;; Copyright (C) 2015-2017 Free Software Foundation, Inc. +;; Author: Marcin Borkowski <mbork@mbork.pl> ;; Author: Dmitry Gutov <dgutov@yandex.ru> ;; Author: Stephen Leake <stephen_leake@member.fsf.org> @@ -672,5 +673,43 @@ xref-elisp-overloadable-separate-default (insert "?\\N{HEAVY CHECK MARK}") (should (equal (elisp--preceding-sexp) ?\N{HEAVY CHECK MARK})))) +;;; Helpers + +(defvar elisp-test-point-marker-regex "=!\\([a-zA-Z0-9-]+\\)=" + "A regexp matching placeholders for point position for +`elisp-tests-with-temp-buffer'.") + +;; Copied and heavily modified from `python-tests-with-temp-buffer' +(defmacro elisp-tests-with-temp-buffer (contents &rest body) + "Create an `emacs-lisp-mode' enabled temp buffer with CONTENTS. +BODY is the code to be executed within the temp buffer. Point is +always located at the beginning of buffer. Special markers of +the form =!NAME= in CONTENTS are removed, and a for each one +a variable called NAME is bound to the position of such +a marker." + (declare (indent 1) (debug t)) + `(with-temp-buffer + (emacs-lisp-mode) + (insert ,contents) + (goto-char (point-min)) + (while (re-search-forward elisp-test-point-marker-regex nil t) + (delete-region (match-beginning 0) + (match-end 0))) + (goto-char (point-min)) + ,(let (marker-list) + (with-temp-buffer + (insert (cond ((symbolp contents) + (symbol-value contents)) + (t contents))) + (goto-char (point-min)) + (while (re-search-forward elisp-test-point-marker-regex nil t) + (push (list (intern (match-string-no-properties 1)) + (match-beginning 0)) + marker-list) + (delete-region (match-beginning 0) + (match-end 0)))) + `(let ,marker-list + ,@body)))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here -- 2.11.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Fix-bug-21072-and-rework-mark-defun.patch --] [-- Type: text/x-diff, Size: 13840 bytes --] From 962f0c653891a4faf2e8db638defbc8096f9d3f1 Mon Sep 17 00:00:00 2001 From: Marcin Borkowski <mbork@mbork.pl> Date: Tue, 14 Feb 2017 11:37:08 +0100 Subject: [PATCH] Fix bug#21072 and rework `mark-defun' * test/lisp/progmodes/elisp-mode-tests.el (mark-defun-test-buffer): New variable (mark-defun-no-arg-region-inactive) (mark-defun-no-arg-region-active) (mark-defun-arg-region-active) (mark-defun-pos-arg-region-inactive) (mark-defun-neg-arg-region-inactive, mark-defun-bob): Add tests for the new `mark-defun' * lisp/emacs-lisp/lisp.el (in-comment-line-p): New function (beginning-of-defun-comments): New function (mark-defun): Fix bug#21072, also rewrite large parts of `mark-defun' to accept a numerical prefix argument --- lisp/emacs-lisp/lisp.el | 130 ++++++++++++----- test/lisp/progmodes/elisp-mode-tests.el | 245 ++++++++++++++++++++++++++++++++ 2 files changed, 337 insertions(+), 38 deletions(-) diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 0172e3af26..664691e629 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -398,6 +398,32 @@ beginning-of-defun-raw (goto-char (if arg-+ve floor ceiling)) nil)))))))) +(defun in-comment-line-p () + "Return non-nil if the point is in a comment line." +;; See http://lists.gnu.org/archive/html/help-gnu-emacs/2016-08/msg00141.html + (save-excursion + (forward-line 0) + (unless (looking-at "^\\s-*$") + (< (line-end-position) + (let ((ppss (syntax-ppss))) + (when (nth 4 ppss) + (goto-char (nth 8 ppss))) + (forward-comment (point-max)) + (point)))))) + +(defun beginning-of-defun-comments (&optional arg) + "Move to the beginning of ARGth defun, including comments." + (interactive "^p") + (unless arg (setq arg 1)) + (beginning-of-defun arg) + (let (nbobp) + (while (progn + (setq nbobp (zerop (forward-line -1))) + (and (in-comment-line-p) + nbobp))) + (when nbobp + (forward-line 1)))) + (defvar end-of-defun-function (lambda () (forward-sexp 1)) "Function for `end-of-defun' to call. @@ -478,48 +504,76 @@ end-of-defun (funcall end-of-defun-function) (funcall skip))))) -(defun mark-defun (&optional allow-extend) +(defun mark-defun (&optional arg) "Put mark at end of this defun, point at beginning. The defun marked is the one that contains point or follows point. +With positive ARG, mark this and that many next defuns; with negative +ARG, change the direction of marking. -Interactively, if this command is repeated -or (in Transient Mark mode) if the mark is active, -it marks the next defun after the ones already marked." +If the mark is active, it marks the next or previous defun(s) after +the one(s) already marked." (interactive "p") - (cond ((and allow-extend - (or (and (eq last-command this-command) (mark t)) - (and transient-mark-mode mark-active))) - (set-mark - (save-excursion - (goto-char (mark)) - (end-of-defun) - (point)))) - (t - (let ((opoint (point)) - beg end) - (push-mark opoint) - ;; Try first in this order for the sake of languages with nested - ;; functions where several can end at the same place as with - ;; the offside rule, e.g. Python. - (beginning-of-defun) - (setq beg (point)) - (end-of-defun) - (setq end (point)) - (while (looking-at "^\n") - (forward-line 1)) - (if (> (point) opoint) - (progn - ;; We got the right defun. - (push-mark beg nil t) - (goto-char end) - (exchange-point-and-mark)) - ;; beginning-of-defun moved back one defun - ;; so we got the wrong one. - (goto-char opoint) - (end-of-defun) - (push-mark (point) nil t) - (beginning-of-defun)) - (re-search-backward "^\n" (- (point) 1) t))))) + (setq arg (or arg 1)) + ;; There is no `mark-defun-back' function - see + ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-11/msg00079.html + ;; for explanation + (when (eq last-command 'mark-defun-back) + (setq arg (- arg))) + (when (< arg 0) + (setq this-command 'mark-defun-back)) + (cond ((use-region-p) + (if (>= arg 0) + (set-mark + (save-excursion + (goto-char (mark)) + ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed + (dotimes (_ignore arg) + (end-of-defun)) + (point))) + (beginning-of-defun-comments (- arg)))) + (t + (let ((opoint (point)) + beg end) + (push-mark opoint) + ;; Try first in this order for the sake of languages with nested + ;; functions where several can end at the same place as with the + ;; offside rule, e.g. Python. + (beginning-of-defun-comments) + (setq beg (point)) + (end-of-defun) + (setq end (point)) + (when (or (and (<= (point) opoint) + (> arg 0)) + (= beg (point-min))) ; we were before the first defun! + ;; beginning-of-defun moved back one defun so we got the wrong + ;; one. If ARG < 0, however, we actually want to go back. + (goto-char opoint) + (end-of-defun) + (setq end (point)) + (beginning-of-defun-comments) + (setq beg (point))) + (goto-char beg) + (cond ((> arg 0) + ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed + (dotimes (_ignore arg) + (end-of-defun)) + (setq end (point)) + (push-mark end nil t) + (goto-char beg)) + (t + (goto-char beg) + (unless (= arg -1) ; beginning-of-defun behaves + ; strange with zero arg - see + ; https://lists.gnu.org/archive/html/bug-gnu-emacs/2017-02/msg00196.html + (beginning-of-defun (1- (- arg)))) + (push-mark end nil t)))))) + (let (nbobp) + (while (progn + (setq nbobp (zerop (forward-line -1))) + (and (looking-at "^\\s-*$") + nbobp))) + (when nbobp + (forward-line 1)))) (defvar narrow-to-defun-include-comments nil "If non-nil, `narrow-to-defun' will also show comments preceding the defun.") diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index a00f6b1b43..2366e337df 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -711,5 +711,250 @@ elisp-tests-with-temp-buffer `(let ,marker-list ,@body)))) +;;; mark-defun + +(defvar mark-defun-test-buffer + ";; Comment header +=!before-1= +\(defun func-1 (arg) + =!inside-1=\"docstring\" + body) +=!after-1==!before-2= +;; Comment before a defun +\(d=!inside-2=efun func-2 (arg) + \"docstring\" + body) +=!after-2==!before-3= +\(defun func-3 (arg) + \"docstring\"=!inside-3= + body) +=!after-3==!before-4=(defun func-4 (arg) + \"docstring\"=!inside-4= + body) +=!after-4= +;; end +" + "Test buffer for `mark-defun'.") + +(ert-deftest mark-defun-no-arg-region-inactive () + "Test `mark-defun' with no prefix argument and inactive +region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun inside a defun, with comments and an empty line + ;; before + (goto-char inside-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun inside a defun with comments before + (deactivate-mark) + (goto-char inside-2) + (mark-defun) + (should (= (point) before-2)) + (should (= (mark) after-2)) + ;; mark-defun inside a defun with empty line before + (deactivate-mark) + (goto-char inside-3) + (mark-defun) + (should (= (point) before-3)) + (should (= (mark) after-3)) + ;; mark-defun inside a defun with another one right before + (deactivate-mark) + (goto-char inside-4) + (mark-defun) + (should (= (point) before-4)) + (should (= (mark) after-4)) + ;; mark-defun between a comment and a defun + (deactivate-mark) + (goto-char before-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun) + (should (= (point) before-3)) + (should (= (mark) after-3)) + ;; mark-defun in comment right before the defun + (deactivate-mark) + (goto-char before-2) + (mark-defun) + (should (= (point) before-2)) + (should (= (mark) after-2)))) + +(ert-deftest mark-defun-no-arg-region-active () + "Test `mark-defun' with no prefix argument and active +region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun when a defun is marked + (goto-char before-1) + (set-mark after-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun when two defuns are marked + (deactivate-mark) + (goto-char before-1) + (set-mark after-2) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-arg-region-active () + "Test `mark-defun' with a prefix arg and active region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with positive arg when a defun is marked + (goto-char before-1) + (set-mark after-1) + (mark-defun 2) + (should (= (point) before-1)) + (should (= (mark) after-3)) + ;; mark-defun with arg=-1 when a defun is marked + (goto-char before-2) + (set-mark after-2) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun with arg=-2 when a defun is marked + (goto-char before-3) + (set-mark after-3) + (mark-defun -2) + (should (= (point) before-1)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-pos-arg-region-inactive () + "Test `mark-defun' with positive argument and inactive + region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with positive arg inside a defun + (goto-char inside-1) + (mark-defun 2) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun with positive arg between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun 2) + (should (= (point) before-3)) + (should (= (mark) after-4)) + ;; mark-defun with positive arg in a comment + (deactivate-mark) + (goto-char before-2) + (mark-defun 2) + (should (= (point) before-2)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-neg-arg-region-inactive () + "Test `mark-defun' with negative argument and inactive + region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with arg=-1 inside a defun + (goto-char inside-1) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun with arg=-1 between defuns + (deactivate-mark) + (goto-char after-2) + (mark-defun -1) + (should (= (point) before-2)) + (should (= (mark) after-2)) + ;; mark-defun with arg=-1 in a comment + ;; (this is probably not an optimal behavior...) + (deactivate-mark) + (goto-char before-2) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun with arg=-2 inside a defun + (deactivate-mark) + (goto-char inside-4) + (mark-defun -2) + (should (= (point) before-3)) + (should (= (mark) after-4)) + ;; mark-defun with arg=-2 between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun -2) + (should (= (point) before-1)) + (should (= (mark) after-2))) + (elisp-tests-with-temp-buffer ; test case submitted by Drew Adams + "(defun a () + nil) +=!before-b=(defun b () +=!in-b= nil) +=!after-b=;;;; +\(defun c () + nil) +" + (setq last-command nil) + (goto-char in-b) + (mark-defun -1) + (should (= (point) before-b)) + (should (= (mark) after-b)))) + +(ert-deftest mark-defun-bob () + "Test `mark-defun' at the beginning of buffer." + ;; Bob, comment, newline, defun + (setq last-command nil) + (elisp-tests-with-temp-buffer + ";; Comment at the bob +=!before= +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, newline, comment, defun + (elisp-tests-with-temp-buffer + "=!before= +;; Comment before the defun +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, comment, defun + (elisp-tests-with-temp-buffer + "=!before=;; Comment at the bob before the defun +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, newline, comment, newline, defun + (elisp-tests-with-temp-buffer + " +;; Comment before the defun +=!before= +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after)))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here -- 2.11.0 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-14 10:45 ` bug#21072: " Marcin Borkowski @ 2017-02-14 13:02 ` Dmitry Gutov 2017-02-14 19:06 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Dmitry Gutov @ 2017-02-14 13:02 UTC (permalink / raw) To: Marcin Borkowski, John Wiegley; +Cc: 21072, Emacs developers On 14.02.2017 12:45, Marcin Borkowski wrote: > +(defun in-comment-line-p () This needs a different name. Something like beginning-of-defun--in-comment-line-p might be a good choice. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-14 13:02 ` Dmitry Gutov @ 2017-02-14 19:06 ` Marcin Borkowski 2017-02-14 19:25 ` Stefan Monnier 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-14 19:06 UTC (permalink / raw) To: Dmitry Gutov; +Cc: John Wiegley, 21072, Emacs developers On 2017-02-14, at 14:02, Dmitry Gutov <dgutov@yandex.ru> wrote: > On 14.02.2017 12:45, Marcin Borkowski wrote: >> +(defun in-comment-line-p () > > This needs a different name. > > Something like beginning-of-defun--in-comment-line-p might be a good choice. Why? It seems to me that it may be of general use. Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-14 19:06 ` Marcin Borkowski @ 2017-02-14 19:25 ` Stefan Monnier 2017-02-15 6:45 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Stefan Monnier @ 2017-02-14 19:25 UTC (permalink / raw) To: emacs-devel > Why? It seems to me that it may be of general use. If you want it to be general, it'll have to be better defined. What is a "comment line"? Stefan ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-14 19:25 ` Stefan Monnier @ 2017-02-15 6:45 ` Marcin Borkowski 2017-02-15 7:56 ` Stefan Monnier 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-15 6:45 UTC (permalink / raw) To: Stefan Monnier; +Cc: 21072, emacs-devel On 2017-02-14, at 20:25, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> Why? It seems to me that it may be of general use. > > If you want it to be general, it'll have to be better defined. > What is a "comment line"? A line containing only a comment (possibly after whitespace). I guess the docstring could benefit from explaining this. Thanks, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-15 6:45 ` Marcin Borkowski @ 2017-02-15 7:56 ` Stefan Monnier 2017-02-15 19:18 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Stefan Monnier @ 2017-02-15 7:56 UTC (permalink / raw) To: Marcin Borkowski; +Cc: 21072, emacs-devel >>> Why? It seems to me that it may be of general use. >> If you want it to be general, it'll have to be better defined. >> What is a "comment line"? > A line containing only a comment (possibly after whitespace). Is a line (using C syntax) like: /* blablabla considered as a "comment line"? What about the likely next line: blablabla */ ? How about blablabla on a line between the previous two (i.e. within a comment)? Regardless of the answer you give above, I'm wondering in which kind of circumstance we'd want to test if we're on "a line containing only a comment". Stefan ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-02-15 7:56 ` Stefan Monnier @ 2017-02-15 19:18 ` Marcin Borkowski 2017-02-15 19:27 ` Stefan Monnier 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-15 19:18 UTC (permalink / raw) To: Stefan Monnier; +Cc: 21072, emacs-devel On 2017-02-15, at 08:56, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >>>> Why? It seems to me that it may be of general use. >>> If you want it to be general, it'll have to be better defined. >>> What is a "comment line"? >> A line containing only a comment (possibly after whitespace). > > Is a line (using C syntax) like: > > /* blablabla > > considered as a "comment line"? Yes. > What about the likely next line: > > blablabla */ Yes. > > ? > How about > > blablabla > > on a line between the previous two (i.e. within a comment)? Yes. (However, I found a minor bug: an empty line, even between a line "/*" and another with "*/" is _not_ considered a comment line by my function. I'll try to fix it. > Regardless of the answer you give above, I'm wondering in which kind of > circumstance we'd want to test if we're on "a line containing only > a comment". You will be surprised, then, that I actually did use a very similar function in completely another circumstance: a command that counts source lines of code in a region, and excludes lines containing only whitespace, comments and docstrings. (Never mind the discussion about whether SLOC is meaningful in any sense;-).) Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-15 19:18 ` Marcin Borkowski @ 2017-02-15 19:27 ` Stefan Monnier 2017-02-16 4:40 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Stefan Monnier @ 2017-02-15 19:27 UTC (permalink / raw) To: Marcin Borkowski; +Cc: 21072, emacs-devel >> Regardless of the answer you give above, I'm wondering in which kind of >> circumstance we'd want to test if we're on "a line containing only >> a comment". > You will be surprised, then, that I actually did use a very similar > function in completely another circumstance: a command that counts > source lines of code in a region, and excludes lines containing only > whitespace, comments and docstrings. (Never mind the discussion about > whether SLOC is meaningful in any sense;-).) My point is that it's not very frequent to need this exact definition of a "comment line" and that there are various other possible definitions one might need in other circumstances. So at the very least, the doc should clarify which definition of "comment line" it uses. Stefan ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-15 19:27 ` Stefan Monnier @ 2017-02-16 4:40 ` Marcin Borkowski 2017-02-16 13:22 ` Stefan Monnier 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-02-16 4:40 UTC (permalink / raw) To: Stefan Monnier; +Cc: 21072, emacs-devel On 2017-02-15, at 20:27, Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: >>> Regardless of the answer you give above, I'm wondering in which kind of >>> circumstance we'd want to test if we're on "a line containing only >>> a comment". >> You will be surprised, then, that I actually did use a very similar >> function in completely another circumstance: a command that counts >> source lines of code in a region, and excludes lines containing only >> whitespace, comments and docstrings. (Never mind the discussion about >> whether SLOC is meaningful in any sense;-).) > > My point is that it's not very frequent to need this exact definition of > a "comment line" and that there are various other possible definitions > one might need in other circumstances. > So at the very least, the doc should clarify which definition of > "comment line" it uses. Understood. Do you have then any better idea for the name of this function? beginning-of-defun--incomment-line-p seems to specific, in-comment-line-p _may_ be indeed too general. (I'll make the docstring more precise, of course.) Thank you all for looking at the patch, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-02-16 4:40 ` Marcin Borkowski @ 2017-02-16 13:22 ` Stefan Monnier 2017-02-17 8:54 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Stefan Monnier @ 2017-02-16 13:22 UTC (permalink / raw) To: Marcin Borkowski; +Cc: 21072, emacs-devel > Understood. Do you have then any better idea for the name of this > function? beginning-of-defun--incomment-line-p seems to specific, > in-comment-line-p _may_ be indeed too general. I'll let someone else decide if it deserves a "non-prefixed" name, but as for the name after the potential prefix, I think focusing on "comment" is the wrong idea. Maybe `insignificant-line-p`? Or `emptyish-line-p`? Stefan ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-02-16 13:22 ` Stefan Monnier @ 2017-02-17 8:54 ` Marcin Borkowski 2017-03-07 16:46 ` Eli Zaretskii 2017-03-07 16:50 ` Dmitry Gutov 0 siblings, 2 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-02-17 8:54 UTC (permalink / raw) To: Stefan Monnier; +Cc: 21072, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1007 bytes --] On 2017-02-16, at 14:22, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> Understood. Do you have then any better idea for the name of this >> function? beginning-of-defun--incomment-line-p seems to specific, >> in-comment-line-p _may_ be indeed too general. > > I'll let someone else decide if it deserves a "non-prefixed" name, but > as for the name after the potential prefix, I think focusing on > "comment" is the wrong idea. Maybe `insignificant-line-p`? Or `emptyish-line-p`? OK, so I have renamed it and expanded the docstring. I attach a corrected patch (the second one, the first one is the same as before). Is there anything else I can do before we may apply this patch and consider bug#21072 fixed? (Notice that three places could be still corrected: two when bug#24427 is fixed and possibly another one when the strange behavior of (beginning-of-defun 0) is fixed - I will officially file a bug about it later. But these apparently will have to wait.) Best, -- Marcin Borkowski [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0002-Fix-bug-21072-and-rework-mark-defun.patch --] [-- Type: text/x-diff, Size: 13922 bytes --] From 618217607d0bfc7ed8d4090afabea040088a0951 Mon Sep 17 00:00:00 2001 From: Marcin Borkowski <mbork@mbork.pl> Date: Tue, 14 Feb 2017 11:37:08 +0100 Subject: [PATCH] Fix bug#21072 and rework `mark-defun' * test/lisp/progmodes/elisp-mode-tests.el (mark-defun-test-buffer): New variable (mark-defun-no-arg-region-inactive) (mark-defun-no-arg-region-active) (mark-defun-arg-region-active) (mark-defun-pos-arg-region-inactive) (mark-defun-neg-arg-region-inactive, mark-defun-bob): Add tests for the new `mark-defun' * lisp/emacs-lisp/lisp.el (in-emptyish-line-p): New function (beginning-of-defun-comments): New function (mark-defun): Fix bug#21072, also rewrite large parts of `mark-defun' to accept a numerical prefix argument --- lisp/emacs-lisp/lisp.el | 132 ++++++++++++----- test/lisp/progmodes/elisp-mode-tests.el | 245 ++++++++++++++++++++++++++++++++ 2 files changed, 339 insertions(+), 38 deletions(-) diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 0172e3af26..28b136eba4 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -398,6 +398,34 @@ beginning-of-defun-raw (goto-char (if arg-+ve floor ceiling)) nil)))))))) +(defun in-emptyish-line-p () + "Return non-nil if the point is in an \"emptyish\" line. +This means a line that consists entirely of comments and/or +whitespace." +;; See http://lists.gnu.org/archive/html/help-gnu-emacs/2016-08/msg00141.html + (save-excursion + (forward-line 0) + (< (line-end-position) + (let ((ppss (syntax-ppss))) + (when (nth 4 ppss) + (goto-char (nth 8 ppss))) + (forward-comment (point-max)) + (point))))) + +(defun beginning-of-defun-comments (&optional arg) + "Move to the beginning of ARGth defun, including comments." + (interactive "^p") + (unless arg (setq arg 1)) + (beginning-of-defun arg) + (let (nbobp) + (while (progn + (setq nbobp (zerop (forward-line -1))) + (and (not (looking-at "^\\s-*$")) + (in-emptyish-line-p) + nbobp))) + (when nbobp + (forward-line 1)))) + (defvar end-of-defun-function (lambda () (forward-sexp 1)) "Function for `end-of-defun' to call. @@ -478,48 +506,76 @@ end-of-defun (funcall end-of-defun-function) (funcall skip))))) -(defun mark-defun (&optional allow-extend) +(defun mark-defun (&optional arg) "Put mark at end of this defun, point at beginning. The defun marked is the one that contains point or follows point. +With positive ARG, mark this and that many next defuns; with negative +ARG, change the direction of marking. -Interactively, if this command is repeated -or (in Transient Mark mode) if the mark is active, -it marks the next defun after the ones already marked." +If the mark is active, it marks the next or previous defun(s) after +the one(s) already marked." (interactive "p") - (cond ((and allow-extend - (or (and (eq last-command this-command) (mark t)) - (and transient-mark-mode mark-active))) - (set-mark - (save-excursion - (goto-char (mark)) - (end-of-defun) - (point)))) - (t - (let ((opoint (point)) - beg end) - (push-mark opoint) - ;; Try first in this order for the sake of languages with nested - ;; functions where several can end at the same place as with - ;; the offside rule, e.g. Python. - (beginning-of-defun) - (setq beg (point)) - (end-of-defun) - (setq end (point)) - (while (looking-at "^\n") - (forward-line 1)) - (if (> (point) opoint) - (progn - ;; We got the right defun. - (push-mark beg nil t) - (goto-char end) - (exchange-point-and-mark)) - ;; beginning-of-defun moved back one defun - ;; so we got the wrong one. - (goto-char opoint) - (end-of-defun) - (push-mark (point) nil t) - (beginning-of-defun)) - (re-search-backward "^\n" (- (point) 1) t))))) + (setq arg (or arg 1)) + ;; There is no `mark-defun-back' function - see + ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-11/msg00079.html + ;; for explanation + (when (eq last-command 'mark-defun-back) + (setq arg (- arg))) + (when (< arg 0) + (setq this-command 'mark-defun-back)) + (cond ((use-region-p) + (if (>= arg 0) + (set-mark + (save-excursion + (goto-char (mark)) + ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed + (dotimes (_ignore arg) + (end-of-defun)) + (point))) + (beginning-of-defun-comments (- arg)))) + (t + (let ((opoint (point)) + beg end) + (push-mark opoint) + ;; Try first in this order for the sake of languages with nested + ;; functions where several can end at the same place as with the + ;; offside rule, e.g. Python. + (beginning-of-defun-comments) + (setq beg (point)) + (end-of-defun) + (setq end (point)) + (when (or (and (<= (point) opoint) + (> arg 0)) + (= beg (point-min))) ; we were before the first defun! + ;; beginning-of-defun moved back one defun so we got the wrong + ;; one. If ARG < 0, however, we actually want to go back. + (goto-char opoint) + (end-of-defun) + (setq end (point)) + (beginning-of-defun-comments) + (setq beg (point))) + (goto-char beg) + (cond ((> arg 0) + ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed + (dotimes (_ignore arg) + (end-of-defun)) + (setq end (point)) + (push-mark end nil t) + (goto-char beg)) + (t + (goto-char beg) + (unless (= arg -1) ; beginning-of-defun behaves + ; strange with zero arg - see + ; https://lists.gnu.org/archive/html/bug-gnu-emacs/2017-02/msg00196.html + (beginning-of-defun (1- (- arg)))) + (push-mark end nil t)))))) + (let (nbobp) + (while (progn + (setq nbobp (zerop (forward-line -1))) + (and (looking-at "^\\s-*$") + nbobp))) + (when nbobp + (forward-line 1)))) (defvar narrow-to-defun-include-comments nil "If non-nil, `narrow-to-defun' will also show comments preceding the defun.") diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index a00f6b1b43..2366e337df 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -711,5 +711,250 @@ elisp-tests-with-temp-buffer `(let ,marker-list ,@body)))) +;;; mark-defun + +(defvar mark-defun-test-buffer + ";; Comment header +=!before-1= +\(defun func-1 (arg) + =!inside-1=\"docstring\" + body) +=!after-1==!before-2= +;; Comment before a defun +\(d=!inside-2=efun func-2 (arg) + \"docstring\" + body) +=!after-2==!before-3= +\(defun func-3 (arg) + \"docstring\"=!inside-3= + body) +=!after-3==!before-4=(defun func-4 (arg) + \"docstring\"=!inside-4= + body) +=!after-4= +;; end +" + "Test buffer for `mark-defun'.") + +(ert-deftest mark-defun-no-arg-region-inactive () + "Test `mark-defun' with no prefix argument and inactive +region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun inside a defun, with comments and an empty line + ;; before + (goto-char inside-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun inside a defun with comments before + (deactivate-mark) + (goto-char inside-2) + (mark-defun) + (should (= (point) before-2)) + (should (= (mark) after-2)) + ;; mark-defun inside a defun with empty line before + (deactivate-mark) + (goto-char inside-3) + (mark-defun) + (should (= (point) before-3)) + (should (= (mark) after-3)) + ;; mark-defun inside a defun with another one right before + (deactivate-mark) + (goto-char inside-4) + (mark-defun) + (should (= (point) before-4)) + (should (= (mark) after-4)) + ;; mark-defun between a comment and a defun + (deactivate-mark) + (goto-char before-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun) + (should (= (point) before-3)) + (should (= (mark) after-3)) + ;; mark-defun in comment right before the defun + (deactivate-mark) + (goto-char before-2) + (mark-defun) + (should (= (point) before-2)) + (should (= (mark) after-2)))) + +(ert-deftest mark-defun-no-arg-region-active () + "Test `mark-defun' with no prefix argument and active +region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun when a defun is marked + (goto-char before-1) + (set-mark after-1) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun when two defuns are marked + (deactivate-mark) + (goto-char before-1) + (set-mark after-2) + (mark-defun) + (should (= (point) before-1)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-arg-region-active () + "Test `mark-defun' with a prefix arg and active region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with positive arg when a defun is marked + (goto-char before-1) + (set-mark after-1) + (mark-defun 2) + (should (= (point) before-1)) + (should (= (mark) after-3)) + ;; mark-defun with arg=-1 when a defun is marked + (goto-char before-2) + (set-mark after-2) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun with arg=-2 when a defun is marked + (goto-char before-3) + (set-mark after-3) + (mark-defun -2) + (should (= (point) before-1)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-pos-arg-region-inactive () + "Test `mark-defun' with positive argument and inactive + region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with positive arg inside a defun + (goto-char inside-1) + (mark-defun 2) + (should (= (point) before-1)) + (should (= (mark) after-2)) + ;; mark-defun with positive arg between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun 2) + (should (= (point) before-3)) + (should (= (mark) after-4)) + ;; mark-defun with positive arg in a comment + (deactivate-mark) + (goto-char before-2) + (mark-defun 2) + (should (= (point) before-2)) + (should (= (mark) after-3)))) + +(ert-deftest mark-defun-neg-arg-region-inactive () + "Test `mark-defun' with negative argument and inactive + region." + (setq last-command nil) + (elisp-tests-with-temp-buffer + mark-defun-test-buffer + ;; mark-defun with arg=-1 inside a defun + (goto-char inside-1) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun with arg=-1 between defuns + (deactivate-mark) + (goto-char after-2) + (mark-defun -1) + (should (= (point) before-2)) + (should (= (mark) after-2)) + ;; mark-defun with arg=-1 in a comment + ;; (this is probably not an optimal behavior...) + (deactivate-mark) + (goto-char before-2) + (mark-defun -1) + (should (= (point) before-1)) + (should (= (mark) after-1)) + ;; mark-defun with arg=-2 inside a defun + (deactivate-mark) + (goto-char inside-4) + (mark-defun -2) + (should (= (point) before-3)) + (should (= (mark) after-4)) + ;; mark-defun with arg=-2 between defuns + (deactivate-mark) + (goto-char before-3) + (mark-defun -2) + (should (= (point) before-1)) + (should (= (mark) after-2))) + (elisp-tests-with-temp-buffer ; test case submitted by Drew Adams + "(defun a () + nil) +=!before-b=(defun b () +=!in-b= nil) +=!after-b=;;;; +\(defun c () + nil) +" + (setq last-command nil) + (goto-char in-b) + (mark-defun -1) + (should (= (point) before-b)) + (should (= (mark) after-b)))) + +(ert-deftest mark-defun-bob () + "Test `mark-defun' at the beginning of buffer." + ;; Bob, comment, newline, defun + (setq last-command nil) + (elisp-tests-with-temp-buffer + ";; Comment at the bob +=!before= +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, newline, comment, defun + (elisp-tests-with-temp-buffer + "=!before= +;; Comment before the defun +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, comment, defun + (elisp-tests-with-temp-buffer + "=!before=;; Comment at the bob before the defun +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after))) + ;; Bob, newline, comment, newline, defun + (elisp-tests-with-temp-buffer + " +;; Comment before the defun +=!before= +\(defun func (arg)=!inside= + \"docstring\" + body) +=!after=" + (goto-char inside) + (mark-defun) + (should (= (point) before)) + (should (= (mark) after)))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here -- 2.11.1 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-02-17 8:54 ` Marcin Borkowski @ 2017-03-07 16:46 ` Eli Zaretskii 2017-03-29 6:34 ` Marcin Borkowski 2017-03-07 16:50 ` Dmitry Gutov 1 sibling, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2017-03-07 16:46 UTC (permalink / raw) To: Marcin Borkowski; +Cc: emacs-devel, monnier, 21072 > From: Marcin Borkowski <mbork@mbork.pl> > Date: Fri, 17 Feb 2017 09:54:51 +0100 > Cc: 21072@debbugs.gnu.org, emacs-devel@gnu.org > > OK, so I have renamed it and expanded the docstring. I attach > a corrected patch (the second one, the first one is the same as before). > > Is there anything else I can do before we may apply this patch and > consider bug#21072 fixed? Thanks, this looks good, but please move the tests to lisp-tests.el, to keep our conventions wrt test names. Then this could go in. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-03-07 16:46 ` Eli Zaretskii @ 2017-03-29 6:34 ` Marcin Borkowski 2017-03-31 11:18 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-03-29 6:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, monnier, 21072 On 2017-03-07, at 17:46, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Marcin Borkowski <mbork@mbork.pl> >> Date: Fri, 17 Feb 2017 09:54:51 +0100 >> Cc: 21072@debbugs.gnu.org, emacs-devel@gnu.org >> >> OK, so I have renamed it and expanded the docstring. I attach >> a corrected patch (the second one, the first one is the same as before). >> >> Is there anything else I can do before we may apply this patch and >> consider bug#21072 fixed? > > Thanks, this looks good, but please move the tests to lisp-tests.el, > to keep our conventions wrt test names. > > Then this could go in. I just pushed it to a branch, forgetting about this email. I'll fix it and report back. For now, I deleted the branch I pushed; I'll pish it again as soon as I correct this. Thanks, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-03-29 6:34 ` Marcin Borkowski @ 2017-03-31 11:18 ` Marcin Borkowski 2017-04-02 22:56 ` npostavs 0 siblings, 1 reply; 29+ messages in thread From: Marcin Borkowski @ 2017-03-31 11:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 21072, monnier, emacs-devel On 2017-03-29, at 08:34, Marcin Borkowski <mbork@mbork.pl> wrote: > On 2017-03-07, at 17:46, Eli Zaretskii <eliz@gnu.org> wrote: > >>> From: Marcin Borkowski <mbork@mbork.pl> >>> Date: Fri, 17 Feb 2017 09:54:51 +0100 >>> Cc: 21072@debbugs.gnu.org, emacs-devel@gnu.org >>> >>> OK, so I have renamed it and expanded the docstring. I attach >>> a corrected patch (the second one, the first one is the same as before). >>> >>> Is there anything else I can do before we may apply this patch and >>> consider bug#21072 fixed? >> >> Thanks, this looks good, but please move the tests to lisp-tests.el, >> to keep our conventions wrt test names. >> >> Then this could go in. > > I just pushed it to a branch, forgetting about this email. I'll fix it > and report back. For now, I deleted the branch I pushed; I'll pish it > again as soon as I correct this. OK, I pushed the branch "fix-bug-21072". Can anyone confirm that it's ok and either merge it into master or tell me that I can do it? Best, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-03-31 11:18 ` Marcin Borkowski @ 2017-04-02 22:56 ` npostavs 2017-04-07 8:25 ` Marcin Borkowski 0 siblings, 1 reply; 29+ messages in thread From: npostavs @ 2017-04-02 22:56 UTC (permalink / raw) To: Marcin Borkowski; +Cc: Eli Zaretskii, 21072, monnier, emacs-devel Marcin Borkowski <mbork@mbork.pl> writes: > > OK, I pushed the branch "fix-bug-21072". Can anyone confirm that it's > ok and either merge it into master or tell me that I can do it? > \f > +** New macro 'elisp-tests-with-temp-buffer' > +which helps writing tests for functions that should change buffers in > +specific ways or manipulate point or mark positions. > + > +--- I don't this should be documented in NEWS since the macro is being added to a test file, so it's not part of Emacs' libraries. Also, the format of the NEWS entry is wrong in the same way as the next one (see below). > +With a prefix argument, it marks that many defuns or extends the > +region by the appropriate number of defuns. With negative prefix > +argument it marks defuns in the opposite direction and also changes > +the direction of selecting for subsequent uses of @code{mark-defun}. This doesn't say what exactly happens with zero as argument. The code seems to do something odd. Perhaps it should just be a user-error instead? Or maybe just a nop. > modified etc/NEWS > @@ -363,6 +363,15 @@ words where first character is upper rather than title case, e.g., > "DŽungla" instead of "Džungla". > > \f > +** New behavior of 'mark-defun' implemented > +Prefix argument selects that many (or that many more) defuns. > +Negative prefix arg flips the direction of selection. Also, > +'mark-defun' between defuns correctly selects N following defuns (or > +-N previous for negative arguments). Finally, comments preceding the > +defun are selected unless they are separated from the defun by a blank > +line. > + > ++++ > * Changes in Specialized Modes and Packages in Emacs 26.1 > This entry should go before the page separator, and the "+++" should go on the line just above the entry, not after it. > +(defun beginning-of-defun-comments (&optional arg) > + (let (nbobp) > + (while (progn > + (setq nbobp (zerop (forward-line -1))) > + (and (not (looking-at "^\\s-*$")) > + (beginning-of-defun--in-emptyish-line-p) > + nbobp))) > + (when nbobp > + (forward-line 1)))) The looking-at call is redundant, right? Anyway, can't that all be replaced by just (forward-comment (- (point))) (unless (bolp) (forward-line 1)) > +(defun mark-defun (&optional arg) > + (let (nbobp) > + (while (progn > + (setq nbobp (zerop (forward-line -1))) > + (and (looking-at "^\\s-*$") > + nbobp))) > + (when nbobp > + (forward-line 1)))) I think this can be just (skip-chars-backward "[:space:]\n") (unless (bolp) (forward-line 1)) ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-04-02 22:56 ` npostavs @ 2017-04-07 8:25 ` Marcin Borkowski 0 siblings, 0 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-04-07 8:25 UTC (permalink / raw) To: npostavs; +Cc: emacs-devel, 21072, monnier Hey, and thanks for your feedback! My answers to particular points are below. On 2017-04-03, at 00:56, npostavs@users.sourceforge.net wrote: > Marcin Borkowski <mbork@mbork.pl> writes: > >> >> OK, I pushed the branch "fix-bug-21072". Can anyone confirm that it's >> ok and either merge it into master or tell me that I can do it? > >> \f >> +** New macro 'elisp-tests-with-temp-buffer' >> +which helps writing tests for functions that should change buffers in >> +specific ways or manipulate point or mark positions. >> + >> +--- > > I don't this should be documented in NEWS since the macro is being added > to a test file, so it's not part of Emacs' libraries. Also, the format > of the NEWS entry is wrong in the same way as the next one (see below). I deleted that from etc/NEWS. >> +With a prefix argument, it marks that many defuns or extends the >> +region by the appropriate number of defuns. With negative prefix >> +argument it marks defuns in the opposite direction and also changes >> +the direction of selecting for subsequent uses of @code{mark-defun}. > > This doesn't say what exactly happens with zero as argument. The code > seems to do something odd. Perhaps it should just be a user-error > instead? Or maybe just a nop. Good catch. I guess a no-op is fine. >> modified etc/NEWS >> @@ -363,6 +363,15 @@ words where first character is upper rather than title case, e.g., >> "DŽungla" instead of "Džungla". >> >> \f >> +** New behavior of 'mark-defun' implemented >> +Prefix argument selects that many (or that many more) defuns. >> +Negative prefix arg flips the direction of selection. Also, >> +'mark-defun' between defuns correctly selects N following defuns (or >> +-N previous for negative arguments). Finally, comments preceding the >> +defun are selected unless they are separated from the defun by a blank >> +line. >> + >> ++++ >> * Changes in Specialized Modes and Packages in Emacs 26.1 >> > > This entry should go before the page separator, and the "+++" should go > on the line just above the entry, not after it. That one I do not understand. This means that "+++" goes essentially _to the previous entry_, which doesn't seem to make sense (especially when viewing NEWS folded, which I assume everyone does, right?). >> +(defun beginning-of-defun-comments (&optional arg) > >> + (let (nbobp) >> + (while (progn >> + (setq nbobp (zerop (forward-line -1))) >> + (and (not (looking-at "^\\s-*$")) >> + (beginning-of-defun--in-emptyish-line-p) >> + nbobp))) >> + (when nbobp >> + (forward-line 1)))) > > > The looking-at call is redundant, right? Anyway, can't that all be Hm. Probably yes, although this seems to be not very well documented in `forward-comment's docs. > replaced by just > > (forward-comment (- (point))) > (unless (bolp) > (forward-line 1)) My tests say no. Consider these contents of a buffer: --8<---------------cut here---------------start------------->8--- ;; Comment at the bob (defun func (arg) "docstring" body) --8<---------------cut here---------------end--------------->8--- Put the point inside the defun and call mark-defun. Your version marks the comment at the beginning, mine doesn't. >> +(defun mark-defun (&optional arg) > >> + (let (nbobp) >> + (while (progn >> + (setq nbobp (zerop (forward-line -1))) >> + (and (looking-at "^\\s-*$") >> + nbobp))) >> + (when nbobp >> + (forward-line 1)))) > > I think this can be just > > (skip-chars-backward "[:space:]\n") > (unless (bolp) > (forward-line 1)) This OTOH does pass my tests, though I guess it would be clearer to replace (bolp) with (bobp) in the above code (if I understand correctly, in this situation they should be equivalent). WDYT? Thanks a lot, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-02-17 8:54 ` Marcin Borkowski 2017-03-07 16:46 ` Eli Zaretskii @ 2017-03-07 16:50 ` Dmitry Gutov 2017-03-07 16:53 ` Eli Zaretskii 2017-03-29 6:30 ` Marcin Borkowski 1 sibling, 2 replies; 29+ messages in thread From: Dmitry Gutov @ 2017-03-07 16:50 UTC (permalink / raw) To: Marcin Borkowski, Stefan Monnier; +Cc: 21072, emacs-devel On 17.02.2017 10:54, Marcin Borkowski wrote: > +(defun in-emptyish-line-p () In case you were wondering, I'm still not sure this is a valuable addition to our public API. But if Eli says it's okay, then it's probably okay. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: bug#21072: Brave new mark-defun (and a testing tool) 2017-03-07 16:50 ` Dmitry Gutov @ 2017-03-07 16:53 ` Eli Zaretskii 2017-03-29 6:30 ` Marcin Borkowski 2017-03-29 6:30 ` Marcin Borkowski 1 sibling, 1 reply; 29+ messages in thread From: Eli Zaretskii @ 2017-03-07 16:53 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel, monnier, 21072 > From: Dmitry Gutov <dgutov@yandex.ru> > Date: Tue, 7 Mar 2017 18:50:33 +0200 > Cc: 21072@debbugs.gnu.org, emacs-devel@gnu.org > > On 17.02.2017 10:54, Marcin Borkowski wrote: > > +(defun in-emptyish-line-p () > > In case you were wondering, I'm still not sure this is a valuable > addition to our public API. > > But if Eli says it's okay, then it's probably okay. I don't really have an opinion, but perhaps it would be better to make it an internal function for now, indeed. ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-03-07 16:53 ` Eli Zaretskii @ 2017-03-29 6:30 ` Marcin Borkowski 0 siblings, 0 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-03-29 6:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Dmitry Gutov, 21072, monnier, emacs-devel On 2017-03-07, at 17:53, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Dmitry Gutov <dgutov@yandex.ru> >> Date: Tue, 7 Mar 2017 18:50:33 +0200 >> Cc: 21072@debbugs.gnu.org, emacs-devel@gnu.org >> >> On 17.02.2017 10:54, Marcin Borkowski wrote: >> > +(defun in-emptyish-line-p () >> >> In case you were wondering, I'm still not sure this is a valuable >> addition to our public API. >> >> But if Eli says it's okay, then it's probably okay. > > I don't really have an opinion, but perhaps it would be better to make > it an internal function for now, indeed. Yep, that's what I did. -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#21072: Brave new mark-defun (and a testing tool) 2017-03-07 16:50 ` Dmitry Gutov 2017-03-07 16:53 ` Eli Zaretskii @ 2017-03-29 6:30 ` Marcin Borkowski 1 sibling, 0 replies; 29+ messages in thread From: Marcin Borkowski @ 2017-03-29 6:30 UTC (permalink / raw) To: Dmitry Gutov; +Cc: 21072, Stefan Monnier, emacs-devel On 2017-03-07, at 17:50, Dmitry Gutov <dgutov@yandex.ru> wrote: > On 17.02.2017 10:54, Marcin Borkowski wrote: >> +(defun in-emptyish-line-p () > > In case you were wondering, I'm still not sure this is a valuable > addition to our public API. Well, I renamed it anyway. Thanks, -- Marcin Borkowski ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2017-04-07 8:25 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-08 6:01 Brave new mark-defun (and a testing tool) Marcin Borkowski 2017-02-12 7:09 ` John Wiegley 2017-02-12 10:10 ` Marcin Borkowski 2017-02-12 10:13 ` Marcin Borkowski 2017-02-12 21:29 ` John Wiegley 2017-02-13 11:00 ` Marcin Borkowski 2017-02-13 15:16 ` Dmitry Gutov 2017-02-13 15:58 ` Marcin Borkowski 2017-02-13 19:00 ` John Wiegley 2017-02-14 10:45 ` bug#21072: " Marcin Borkowski 2017-02-14 13:02 ` Dmitry Gutov 2017-02-14 19:06 ` Marcin Borkowski 2017-02-14 19:25 ` Stefan Monnier 2017-02-15 6:45 ` Marcin Borkowski 2017-02-15 7:56 ` Stefan Monnier 2017-02-15 19:18 ` Marcin Borkowski 2017-02-15 19:27 ` Stefan Monnier 2017-02-16 4:40 ` Marcin Borkowski 2017-02-16 13:22 ` Stefan Monnier 2017-02-17 8:54 ` Marcin Borkowski 2017-03-07 16:46 ` Eli Zaretskii 2017-03-29 6:34 ` Marcin Borkowski 2017-03-31 11:18 ` Marcin Borkowski 2017-04-02 22:56 ` npostavs 2017-04-07 8:25 ` Marcin Borkowski 2017-03-07 16:50 ` Dmitry Gutov 2017-03-07 16:53 ` Eli Zaretskii 2017-03-29 6:30 ` Marcin Borkowski 2017-03-29 6:30 ` Marcin Borkowski
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).