From 3bdd8402a180623e77b13224807bb8f16df499f4 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 13 Jun 2013 18:48:19 +0000 Subject: Rework paredit-semicolon and add some tests for it. --- paredit.el | 52 ++++++++++++++++++++++++++++++---------------------- test.el | 28 +++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/paredit.el b/paredit.el index fc86311..1f1a2c7 100644 --- a/paredit.el +++ b/paredit.el @@ -1055,29 +1055,37 @@ If a list begins on the line after the point but ends on a different (insert (make-string (or n 1) ?\; )))))) (defun paredit-semicolon-find-line-break-point () - (let ((line-break-point nil) - (eol (point-at-eol))) - (and (not (eolp)) ;Implies (not (eobp)). + (and (not (eolp)) ;Implies (not (eobp)). + (let ((eol (point-at-eol))) (save-excursion - (paredit-handle-sexp-errors - (progn - (while - (progn - (setq line-break-point (point)) - (forward-sexp) - (and (eq eol (point-at-eol)) - (not (eobp))))) - (backward-sexp) - (and (eq eol (point-at-eol)) - ;; Don't break the line if the end of the last - ;; S-expression is at the end of the buffer. - (progn (forward-sexp) (not (eobp))))) - ;; If we hit the end of an expression, but the closing - ;; delimiter is on another line, don't break the line. - (save-excursion - (paredit-skip-whitespace t (point-at-eol)) - (not (or (eolp) (eq (char-after) ?\; )))))) - line-break-point))) + (catch 'exit + (while t + (let ((line-break-point (point))) + (cond ((paredit-handle-sexp-errors (progn (forward-sexp) t) + nil) + ;; Successfully advanced by an S-expression. + ;; If that S-expression started on this line + ;; and ended on another one, break here. + (cond ((not (eq eol (point-at-eol))) + (throw 'exit + (and (save-excursion + (backward-sexp) + (eq eol (point-at-eol))) + line-break-point))) + ((eobp) + (throw 'exit nil)))) + ((save-excursion + (paredit-skip-whitespace t (point-at-eol)) + (or (eolp) (eobp) (eq (char-after) ?\;))) + ;; Can't move further, but there's no closing + ;; delimiter we're about to clobber -- either + ;; it's on the next line or we're at the end of + ;; the buffer. Don't break the line. + (throw 'exit nil)) + (t + ;; Can't move because we hit a delimiter at the + ;; end of this line. Break here. + (throw 'exit line-break-point)))))))))) (defun paredit-semicolon-with-line-break (line-break-point n) (let ((line-break-marker (make-marker))) diff --git a/test.el b/test.el index eb7ef04..66d22ed 100644 --- a/test.el +++ b/test.el @@ -221,7 +221,33 @@ Four arguments: the paredit command, the text of the buffer "(define (square x)\n (* |x x))"))) (paredit-test 'paredit-semicolon - '(("#\\|(" ";|#\\("))) + '(("|" ";|") + ("|foo" ";|foo") + ("f|oo" "f;|oo") + ("fo|o" "fo;|o") + ("foo|" "foo;|") + ("|(foo bar)" ";|(foo bar)") + ("(|foo bar)" "(;|foo bar\n )") + ("(f|oo bar)" "(f;|oo bar\n )") + ("(fo|o bar)" "(fo;|o bar\n )") + ("(foo| bar)" "(foo;| bar\n )") + ("(foo |bar)" "(foo ;|bar\n )") + ("(foo b|ar)" "(foo b;|ar\n )") + ("(foo ba|r)" "(foo ba;|r\n )") + ("(foo bar|)" "(foo bar;|\n )") + ("(foo bar)|" "(foo bar);|") + ("|(foo\n bar)" ";|\n(foo\n bar)") + ("(|foo\n bar)" "(;|foo\n bar)") + ("(f|oo\n bar)" "(f;|oo\n bar)") + ("(fo|o\n bar)" "(fo;|o\n bar)") + ("(foo|\n bar)" "(foo;|\n bar)") + ("(foo\n| bar)" "(foo\n;| bar\n )") + ("(foo\n |bar)" "(foo\n ;|bar\n )") + ("(foo\n b|ar)" "(foo\n b;|ar\n )") + ("(foo\n ba|r)" "(foo\n ba;|r\n )") + ("(foo\n bar|)" "(foo\n bar;|\n )") + ("(foo\n bar)|" "(foo\n bar);|") + ("#\\|(" ";|#\\("))) (paredit-test 'paredit-comment-dwim '(("\"foo|bar;baz\" ;quux" -- cgit v1.2.1