abo-abo / lispy

Short and sweet LISP editing
http://oremacs.com/lispy/
1.2k stars 130 forks source link

Multiline not working with comments in Clojure #599

Closed markgdawson closed 2 years ago

markgdawson commented 3 years ago

Formatting the following clojure code with M (multiline):

  {:one {:two "hi", :three ["four" {:five "size", :seven "eight", :nine "ten"}]}}

produces:

{:one {:two "hi"
         , :three
         ["four"
          {:five "size"
           , :seven
           "eight" ,
           :nine "ten"}]}}

The commas (which are whitespace) appear at the start of the line. I would have expected them to appear at the end of the previous line.

After some digging, I suspect the issue could be in lispy--read. Running lispy-read on the code above (in clojure-mode) produces:

(ly-raw clojure-map
        ((ly-raw clojure-symbol ":one")
         (ly-raw clojure-map
                 ((ly-raw clojure-symbol ":two")
                  (ly-raw string "\"hi\"")
                  (ly-raw clojure-symbol ",")
                  (ly-raw clojure-symbol ":three")
                  [(ly-raw string "\"four\"")
                   (ly-raw clojure-symbol ",")
                   (ly-raw clojure-map
                           ((ly-raw clojure-symbol ":five")
                            (ly-raw string "\"size\"")
                            (ly-raw clojure-symbol ",")
                            (ly-raw clojure-symbol ":seven")
                            (ly-raw string "\"eight\"")
                            (ly-raw clojure-symbol ",")
                            (ly-raw clojure-symbol ":nine")
                            (ly-raw string "\"ten\"")))]))))

I note that there is a clojure-comma type in the lispy-read function. Should this be used instead of clojure-symbol?

Running (lispy--read ",") returns (ly-raw clojure-symbol ",").

It seemed that this behaviour changed in commit 8bad03705362794876081b44802ad0932faa4f30, where a comma was added for Hy. Prior to that commit, lispy-read would return (ly-raw clojure-commas ",") for commas in clojure.

However, unfortunately, attempting to revert this commit causes other issues for me. I get the traceback below from applying multiline to the example above. And I'm not sure how I can fix this.

Debugger entered--Lisp error: (args-out-of-range #<buffer  *temp*> 0 28)
  delete-region(0 28)
  (cond ((eql type 'newline) (delete-region beg (point)) (delete-char (- (skip-chars-backward " "))) (insert "\n")) ((memql type '(string comment symbol float quasiquote)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'comma-symbol) (delete-region beg (point)) (insert "\\,")) ((eql type 'ignore) (delete-region beg (point)) (backward-delete-char 1)) ((eql type 'raw) (delete-region beg (point)) (prin1 (cons 'ly-raw (cdr (cdr sxp))) (current-buffer)) (backward-list) (forward-char 7)) ((eql type 'quote) (delete-region beg (point)) (insert "'") (let ((it (car (cdr (cdr sxp))))) (if it (prin1 it (current-buffer)) (insert "()"))) (goto-char beg)) ((eql type 'empty) (delete-region beg (point)) (insert "()")) ((eql type 'char) (delete-region beg (point)) (insert "?" (car (cdr (cdr sxp))))) ((memql type '(clojure-char)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((memql type '(clojure-commas)) (delete-region (1- beg) (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'clojure-symbol) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'lisp-char) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'lisp-macro) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((memql type '(clojure-gensym clojure-keyword)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'function) (delete-region beg (point)) (insert (format "#'%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-dot) (delete-region beg (point)) (insert ".")) ((eql type 'clojure-lambda) (delete-region beg (point)) (insert (format "#%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-set) (delete-region beg (point)) (insert (format "#{%s}" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-map) (delete-region beg (point)) (insert (format "{%s}" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-object) (delete-region beg (point)) (insert (format "#object[%s]" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'splice) (delete-region beg (point)) (insert (nth 2 sxp) (lispy--splice-to-str (car (nthcdr 4 sxp))) (nth 3 sxp)) (goto-char beg)) ((eql type 'clojure-deref-map) (delete-region beg (point)) (insert (format "@{%s}" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-deref-vector) (delete-region beg (point)) (insert (format "@[%s]" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-deref-list) (delete-region beg (point)) (insert (format "@(%s)" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-reader-conditional-splice) (delete-region beg (point)) (insert (format "#?@(%s)" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-reader-conditional) (delete-region beg (point)) (insert (format "#?(%s)" (lispy--splice-to-str (car (cdr (cdr sxp)))))) (goto-char beg)) ((eql type 'clojure-reader-comment) (delete-region beg (point)) (insert (format "#_%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-comma) (delete-region beg (point)) (delete-horizontal-space) (insert ", ")) ((eql type 'racket-true) (delete-region beg (point)) (insert "#t")) ((eql type 'racket-false) (delete-region beg (point)) (insert "#f")) ((eql type 'racket-option) (delete-region beg (point)) (insert (format "#:%S" (car (cdr (cdr sxp)))))) ((eql type 'angle) (delete-region beg (point)) (insert (format "#<%s>" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'reference) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type '\`) (if (> (length sxp) 3) (progn (goto-char beg) (insert "`") (delete-region (+ (point) 1) (+ (point) 11))) (delete-region beg (point)) (insert "`") (prin1 (car (cdr (cdr sxp))) (current-buffer))) (goto-char beg)) ((eql type '\,) (delete-region beg (point)) (insert ",") (prin1 (car (cdr (cdr sxp))) (current-buffer)) (goto-char beg)) ((eql type 'comma-splice) (delete-region beg (point)) (insert ",@") (prin1 (car (cdr (cdr sxp))) (current-buffer)) (goto-char beg)) ((eql type 'dot) (delete-region beg (point)) (insert ".")) (t (goto-char (1+ beg))))
  (while (and (re-search-forward "(ly-raw" nil t) (setq beg (match-beginning 0))) (goto-char beg) (setq sxp (condition-case nil (progn (read (current-buffer))) (error nil))) (setq type (car (cdr sxp))) (cond ((eql type 'newline) (delete-region beg (point)) (delete-char (- (skip-chars-backward " "))) (insert "\n")) ((memql type '(string comment symbol float quasiquote)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'comma-symbol) (delete-region beg (point)) (insert "\\,")) ((eql type 'ignore) (delete-region beg (point)) (backward-delete-char 1)) ((eql type 'raw) (delete-region beg (point)) (prin1 (cons 'ly-raw (cdr (cdr sxp))) (current-buffer)) (backward-list) (forward-char 7)) ((eql type 'quote) (delete-region beg (point)) (insert "'") (let ((it (car (cdr ...)))) (if it (prin1 it (current-buffer)) (insert "()"))) (goto-char beg)) ((eql type 'empty) (delete-region beg (point)) (insert "()")) ((eql type 'char) (delete-region beg (point)) (insert "?" (car (cdr (cdr sxp))))) ((memql type '(clojure-char)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((memql type '(clojure-commas)) (delete-region (1- beg) (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'clojure-symbol) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'lisp-char) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'lisp-macro) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((memql type '(clojure-gensym clojure-keyword)) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type 'function) (delete-region beg (point)) (insert (format "#'%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-dot) (delete-region beg (point)) (insert ".")) ((eql type 'clojure-lambda) (delete-region beg (point)) (insert (format "#%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-set) (delete-region beg (point)) (insert (format "#{%s}" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-map) (delete-region beg (point)) (insert (format "{%s}" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-object) (delete-region beg (point)) (insert (format "#object[%s]" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'splice) (delete-region beg (point)) (insert (nth 2 sxp) (lispy--splice-to-str (car (nthcdr 4 sxp))) (nth 3 sxp)) (goto-char beg)) ((eql type 'clojure-deref-map) (delete-region beg (point)) (insert (format "@{%s}" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-deref-vector) (delete-region beg (point)) (insert (format "@[%s]" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-deref-list) (delete-region beg (point)) (insert (format "@(%s)" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-reader-conditional-splice) (delete-region beg (point)) (insert (format "#?@(%s)" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-reader-conditional) (delete-region beg (point)) (insert (format "#?(%s)" (lispy--splice-to-str (car (cdr ...))))) (goto-char beg)) ((eql type 'clojure-reader-comment) (delete-region beg (point)) (insert (format "#_%S" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'clojure-comma) (delete-region beg (point)) (delete-horizontal-space) (insert ", ")) ((eql type 'racket-true) (delete-region beg (point)) (insert "#t")) ((eql type 'racket-false) (delete-region beg (point)) (insert "#f")) ((eql type 'racket-option) (delete-region beg (point)) (insert (format "#:%S" (car (cdr (cdr sxp)))))) ((eql type 'angle) (delete-region beg (point)) (insert (format "#<%s>" (car (cdr (cdr sxp))))) (goto-char beg)) ((eql type 'reference) (delete-region beg (point)) (insert (car (cdr (cdr sxp))))) ((eql type '\`) (if (> (length sxp) 3) (progn (goto-char beg) (insert "`") (delete-region (+ (point) 1) (+ (point) 11))) (delete-region beg (point)) (insert "`") (prin1 (car (cdr (cdr sxp))) (current-buffer))) (goto-char beg)) ((eql type '\,) (delete-region beg (point)) (insert ",") (prin1 (car (cdr (cdr sxp))) (current-buffer)) (goto-char beg)) ((eql type 'comma-splice) (delete-region beg (point)) (insert ",@") (prin1 (car (cdr (cdr sxp))) (current-buffer)) (goto-char beg)) ((eql type 'dot) (delete-region beg (point)) (insert ".")) (t (goto-char (1+ beg)))))
  (save-restriction (narrow-to-region start-pt (point)) (goto-char (point-min)) (while (and (re-search-forward "(ly-raw" nil t) (setq beg (match-beginning 0))) (goto-char beg) (setq sxp (condition-case nil (progn (read (current-buffer))) (error nil))) (setq type (car (cdr sxp))) (cond ((eql type 'newline) (delete-region beg (point)) (delete-char (- (skip-chars-backward " "))) (insert "\n")) ((memql type '(string comment symbol float quasiquote)) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'comma-symbol) (delete-region beg (point)) (insert "\\,")) ((eql type 'ignore) (delete-region beg (point)) (backward-delete-char 1)) ((eql type 'raw) (delete-region beg (point)) (prin1 (cons 'ly-raw (cdr ...)) (current-buffer)) (backward-list) (forward-char 7)) ((eql type 'quote) (delete-region beg (point)) (insert "'") (let ((it ...)) (if it (prin1 it ...) (insert "()"))) (goto-char beg)) ((eql type 'empty) (delete-region beg (point)) (insert "()")) ((eql type 'char) (delete-region beg (point)) (insert "?" (car (cdr ...)))) ((memql type '(clojure-char)) (delete-region beg (point)) (insert (car (cdr ...)))) ((memql type '(clojure-commas)) (delete-region (1- beg) (point)) (insert (car (cdr ...)))) ((eql type 'clojure-symbol) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'lisp-char) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'lisp-macro) (delete-region beg (point)) (insert (car (cdr ...)))) ((memql type '(clojure-gensym clojure-keyword)) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'function) (delete-region beg (point)) (insert (format "#'%S" (car ...))) (goto-char beg)) ((eql type 'clojure-dot) (delete-region beg (point)) (insert ".")) ((eql type 'clojure-lambda) (delete-region beg (point)) (insert (format "#%S" (car ...))) (goto-char beg)) ((eql type 'clojure-set) (delete-region beg (point)) (insert (format "#{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-map) (delete-region beg (point)) (insert (format "{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-object) (delete-region beg (point)) (insert (format "#object[%s]" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'splice) (delete-region beg (point)) (insert (nth 2 sxp) (lispy--splice-to-str (car ...)) (nth 3 sxp)) (goto-char beg)) ((eql type 'clojure-deref-map) (delete-region beg (point)) (insert (format "@{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-deref-vector) (delete-region beg (point)) (insert (format "@[%s]" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-deref-list) (delete-region beg (point)) (insert (format "@(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-conditional-splice) (delete-region beg (point)) (insert (format "#?@(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-conditional) (delete-region beg (point)) (insert (format "#?(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-comment) (delete-region beg (point)) (insert (format "#_%S" (car ...))) (goto-char beg)) ((eql type 'clojure-comma) (delete-region beg (point)) (delete-horizontal-space) (insert ", ")) ((eql type 'racket-true) (delete-region beg (point)) (insert "#t")) ((eql type 'racket-false) (delete-region beg (point)) (insert "#f")) ((eql type 'racket-option) (delete-region beg (point)) (insert (format "#:%S" (car ...)))) ((eql type 'angle) (delete-region beg (point)) (insert (format "#<%s>" (car ...))) (goto-char beg)) ((eql type 'reference) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type '\`) (if (> (length sxp) 3) (progn (goto-char beg) (insert "`") (delete-region ... ...)) (delete-region beg (point)) (insert "`") (prin1 (car ...) (current-buffer))) (goto-char beg)) ((eql type '\,) (delete-region beg (point)) (insert ",") (prin1 (car (cdr ...)) (current-buffer)) (goto-char beg)) ((eql type 'comma-splice) (delete-region beg (point)) (insert ",@") (prin1 (car (cdr ...)) (current-buffer)) (goto-char beg)) ((eql type 'dot) (delete-region beg (point)) (insert ".")) (t (goto-char (1+ beg))))) (goto-char (point-min)) (while (re-search-forward "\\(?:\\s_\\|\\sw\\)\\(\\\\\\?\\)" nil t) (replace-match "?" t t nil 1)) (goto-char (point-min)) (while (re-search-forward "\\sw\\(\\\\\\.\\)" nil t) (if (let ((save-match-data-internal (match-data))) (unwind-protect (progn (lispy--in-string-p)) (set-match-data save-match-data-internal 'evaporate))) nil (replace-match "." nil nil nil 1))) (goto-char (point-min)) (while (re-search-forward "[0-9]+\\(\\\\#\\)" nil t) (replace-match "#" nil t nil 1)) (if lispy-do-fill (progn (goto-char (point-min)) (while (re-search-forward " " nil t) (cond ((lispy--in-string-p)) ((lispy--in-comment-p) (fill-paragraph) (goto-char ...)) ((> ... fill-column) (newline-and-indent)))))) (goto-char (point-max)) (widen))
  (let ((start-pt (point)) beg sxp type) (prin1 expr (current-buffer)) (save-restriction (narrow-to-region start-pt (point)) (goto-char (point-min)) (while (and (re-search-forward "(ly-raw" nil t) (setq beg (match-beginning 0))) (goto-char beg) (setq sxp (condition-case nil (progn (read (current-buffer))) (error nil))) (setq type (car (cdr sxp))) (cond ((eql type 'newline) (delete-region beg (point)) (delete-char (- (skip-chars-backward " "))) (insert "\n")) ((memql type '(string comment symbol float quasiquote)) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'comma-symbol) (delete-region beg (point)) (insert "\\,")) ((eql type 'ignore) (delete-region beg (point)) (backward-delete-char 1)) ((eql type 'raw) (delete-region beg (point)) (prin1 (cons 'ly-raw (cdr ...)) (current-buffer)) (backward-list) (forward-char 7)) ((eql type 'quote) (delete-region beg (point)) (insert "'") (let ((it ...)) (if it (prin1 it ...) (insert "()"))) (goto-char beg)) ((eql type 'empty) (delete-region beg (point)) (insert "()")) ((eql type 'char) (delete-region beg (point)) (insert "?" (car (cdr ...)))) ((memql type '(clojure-char)) (delete-region beg (point)) (insert (car (cdr ...)))) ((memql type '(clojure-commas)) (delete-region (1- beg) (point)) (insert (car (cdr ...)))) ((eql type 'clojure-symbol) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'lisp-char) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'lisp-macro) (delete-region beg (point)) (insert (car (cdr ...)))) ((memql type '(clojure-gensym clojure-keyword)) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type 'function) (delete-region beg (point)) (insert (format "#'%S" (car ...))) (goto-char beg)) ((eql type 'clojure-dot) (delete-region beg (point)) (insert ".")) ((eql type 'clojure-lambda) (delete-region beg (point)) (insert (format "#%S" (car ...))) (goto-char beg)) ((eql type 'clojure-set) (delete-region beg (point)) (insert (format "#{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-map) (delete-region beg (point)) (insert (format "{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-object) (delete-region beg (point)) (insert (format "#object[%s]" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'splice) (delete-region beg (point)) (insert (nth 2 sxp) (lispy--splice-to-str (car ...)) (nth 3 sxp)) (goto-char beg)) ((eql type 'clojure-deref-map) (delete-region beg (point)) (insert (format "@{%s}" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-deref-vector) (delete-region beg (point)) (insert (format "@[%s]" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-deref-list) (delete-region beg (point)) (insert (format "@(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-conditional-splice) (delete-region beg (point)) (insert (format "#?@(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-conditional) (delete-region beg (point)) (insert (format "#?(%s)" (lispy--splice-to-str ...))) (goto-char beg)) ((eql type 'clojure-reader-comment) (delete-region beg (point)) (insert (format "#_%S" (car ...))) (goto-char beg)) ((eql type 'clojure-comma) (delete-region beg (point)) (delete-horizontal-space) (insert ", ")) ((eql type 'racket-true) (delete-region beg (point)) (insert "#t")) ((eql type 'racket-false) (delete-region beg (point)) (insert "#f")) ((eql type 'racket-option) (delete-region beg (point)) (insert (format "#:%S" (car ...)))) ((eql type 'angle) (delete-region beg (point)) (insert (format "#<%s>" (car ...))) (goto-char beg)) ((eql type 'reference) (delete-region beg (point)) (insert (car (cdr ...)))) ((eql type '\`) (if (> (length sxp) 3) (progn (goto-char beg) (insert "`") (delete-region ... ...)) (delete-region beg (point)) (insert "`") (prin1 (car ...) (current-buffer))) (goto-char beg)) ((eql type '\,) (delete-region beg (point)) (insert ",") (prin1 (car (cdr ...)) (current-buffer)) (goto-char beg)) ((eql type 'comma-splice) (delete-region beg (point)) (insert ",@") (prin1 (car (cdr ...)) (current-buffer)) (goto-char beg)) ((eql type 'dot) (delete-region beg (point)) (insert ".")) (t (goto-char (1+ beg))))) (goto-char (point-min)) (while (re-search-forward "\\(?:\\s_\\|\\sw\\)\\(\\\\\\?\\)" nil t) (replace-match "?" t t nil 1)) (goto-char (point-min)) (while (re-search-forward "\\sw\\(\\\\\\.\\)" nil t) (if (let ((save-match-data-internal (match-data))) (unwind-protect (progn (lispy--in-string-p)) (set-match-data save-match-data-internal 'evaporate))) nil (replace-match "." nil nil nil 1))) (goto-char (point-min)) (while (re-search-forward "[0-9]+\\(\\\\#\\)" nil t) (replace-match "#" nil t nil 1)) (if lispy-do-fill (progn (goto-char (point-min)) (while (re-search-forward " " nil t) (cond ((lispy--in-string-p)) ((lispy--in-comment-p) (fill-paragraph) (goto-char ...)) ((> ... fill-column) (newline-and-indent)))))) (goto-char (point-max)) (widen)))
  lispy--insert((ly-raw clojure-commas ","))
  (let ((lisp-indent-function lif)) (lispy--insert expr))
  (progn (funcall mode) (let ((--dotimes-limit-- offset) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((_i --dotimes-counter--)) (insert 32)) (setq --dotimes-counter-- (1+ --dotimes-counter--)))) (let ((lisp-indent-function lif)) (lispy--insert expr)) (buffer-substring-no-properties (+ (point-min) offset) (point-max)))
  (unwind-protect (progn (funcall mode) (let ((--dotimes-limit-- offset) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((_i --dotimes-counter--)) (insert 32)) (setq --dotimes-counter-- (1+ --dotimes-counter--)))) (let ((lisp-indent-function lif)) (lispy--insert expr)) (buffer-substring-no-properties (+ (point-min) offset) (point-max))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (funcall mode) (let ((--dotimes-limit-- offset) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((_i --dotimes-counter--)) (insert 32)) (setq --dotimes-counter-- (1+ --dotimes-counter--)))) (let ((lisp-indent-function lif)) (lispy--insert expr)) (buffer-substring-no-properties (+ (point-min) offset) (point-max))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*" t))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (funcall mode) (let ((--dotimes-limit-- offset) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let (...) (insert 32)) (setq --dotimes-counter-- (1+ --dotimes-counter--)))) (let ((lisp-indent-function lif)) (lispy--insert expr)) (buffer-substring-no-properties (+ (point-min) offset) (point-max))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (let ((lif lisp-indent-function)) (let ((temp-buffer (generate-new-buffer " *temp*" t))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (funcall mode) (let ((--dotimes-limit-- offset) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ... ...) (setq --dotimes-counter-- ...))) (let ((lisp-indent-function lif)) (lispy--insert expr)) (buffer-substring-no-properties (+ (point-min) offset) (point-max))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))
  lispy--prin1-to-string((ly-raw clojure-commas ",") 0 emacs-lisp-mode)
markgdawson commented 2 years ago

I've created a PR #606 which does seem to fix the behavior. There are a few elements to this:

  1. The regular expression in lispy--read was causing commas to be read as clojure-symbol as opposed to clojure-commas.
  2. There was a bug in printing clojure-commas. The printing tries to delete the space before the comma (which is desirable), but when printing just a comma in isolation, this is before the start of the buffer. That causes the trace above.
  3. Multiline wasn't aware of this treating commas in a special way. I've implemented lispy--slurp-whitespace, which "slurps" whitespace between lists. and added an optional argument to lispy-interleave to slurp whitespace. Then added this optional argument under lispy-multiline-1 to cause lispy-interleave to slurp whitespace.
markgdawson commented 2 years ago

Note however that this would break the fix implemented in https://github.com/abo-abo/lispy/issues/537 (again)

I don't know the best way to fix this for Hy. But I'm not sure that the proposed fix of adding , to the regexp, breaking clojure-commas, is the optimal approach.

cstby commented 2 years ago

Would this also fix lispy-kill deleting more than the current line if the line ends in a comma?

abo-abo commented 2 years ago

@cstby I've fixed lispy-kill. Thanks for the report.

cstby commented 2 years ago

Any time. Thank you for the fix, and for all your work on this wonderful package.