Indent multi-line output from mirrors

* yasnippet.el (yas--indent-region): Adapted and redesigned from
`yas--indent-according-to-mode'
(yas--indent-according-to-mode): Deleted.
(yas--indent): Use `yas--indent-region'.
(yas--real-line-beginning): Deleted.
(yas--update-mirrors): Always re-place active field overlay if it
exists.  Pass the snippet to `yas--mirror-update-display'.
(yas--mirror-update-display): Indent the mirror text after
inserting the reflection.
This commit is contained in:
João Távora 2016-03-04 17:34:40 +00:00 committed by Noam Postavsky
parent eeb4b62efb
commit eca2f995c1

View File

@ -3869,8 +3869,9 @@ Meant to be called in a narrowed buffer, does various passes"
(goto-char parse-start) (goto-char parse-start)
(yas--indent snippet))) (yas--indent snippet)))
(defun yas--indent-according-to-mode (snippet-markers) (defun yas--indent-region (from to snippet)
"Indent current line according to mode, preserving SNIPPET-MARKERS." "Indent the lines between FROM and TO with `indent-according-to-mode'.
The SNIPPET's markers are preserved."
;;; Apropos indenting problems.... ;;; Apropos indenting problems....
;; ;;
;; `indent-according-to-mode' uses whatever `indent-line-function' ;; `indent-according-to-mode' uses whatever `indent-line-function'
@ -3883,54 +3884,50 @@ Meant to be called in a narrowed buffer, does various passes"
;; `front-advance' property set to nil. ;; `front-advance' property set to nil.
;; ;;
;; This is why I have these `trouble-markers', they are the ones at ;; This is why I have these `trouble-markers', they are the ones at
;; they are the ones at the first non-whitespace char at the line ;; the first non-whitespace char at the line. After indentation
;; (i.e. at `yas--real-line-beginning'. After indentation takes place ;; takes place we should be at the correct to restore them. All
;; we should be at the correct to restore them to. All other ;; other non-trouble-markers should have been *pushed* and don't
;; non-trouble-markers have been *pushed* and don't need special ;; need special attention.
;; attention. (let* ((snippet-markers (yas--collect-snippet-markers snippet))
;; (to (set-marker (make-marker) to)))
(goto-char (yas--real-line-beginning)) (save-excursion
(let ((trouble-markers (remove-if-not #'(lambda (marker) (goto-char from)
(= marker (point))) (save-restriction
snippet-markers))) (widen)
(save-restriction (cl-loop do
(widen) (back-to-indentation)
(condition-case _ (let ((trouble-markers ; The markers at (point).
(indent-according-to-mode) (cl-remove (point) snippet-markers :test #'/=)))
(error (yas--message 3 "Warning: `yas--indent-according-to-mode' having problems running %s" indent-line-function) (unwind-protect
nil))) (indent-according-to-mode)
(mapc #'(lambda (marker) (dolist (marker trouble-markers)
(set-marker marker (point))) (set-marker marker (point)))))
trouble-markers))) while (and (zerop (forward-line 1))
(< (point) to)))))))
(defvar yas--indent-original-column nil) (defvar yas--indent-original-column nil)
(defun yas--indent (snippet) (defun yas--indent (snippet)
(let ((snippet-markers (yas--collect-snippet-markers snippet))) ;; Look for those `$>'.
;; Look for those $> (save-excursion
(save-excursion (while (re-search-forward "$>" nil t)
(while (re-search-forward "$>" nil t) (delete-region (match-beginning 0) (match-end 0))
(delete-region (match-beginning 0) (match-end 0)) (unless (eq yas-indent-line 'auto)
(when (not (eq yas-indent-line 'auto)) (yas--indent-region (line-beginning-position)
(yas--indent-according-to-mode snippet-markers)))) (line-end-position)
;; Now do stuff for 'fixed and 'auto snippet))))
(save-excursion ;; Now do stuff for `fixed' and `auto'.
(cond ((eq yas-indent-line 'fixed) (save-excursion
(while (and (zerop (forward-line)) (cond ((eq yas-indent-line 'fixed)
(zerop (current-column))) (while (and (zerop (forward-line))
(indent-to-column yas--indent-original-column))) (zerop (current-column)))
((eq yas-indent-line 'auto) (indent-to-column yas--indent-original-column)))
(let ((end (set-marker (make-marker) (point-max))) ((eq yas-indent-line 'auto)
(indent-first-line-p yas-also-auto-indent-first-line)) (let ((end (set-marker (make-marker) (point-max))))
(while (and (zerop (if indent-first-line-p (unless yas-also-auto-indent-first-line
(prog1 (forward-line 1))
(forward-line 0) (yas--indent-region (line-beginning-position)
(setq indent-first-line-p nil)) (point-max)
(forward-line 1))) snippet))))))
(not (eobp))
(<= (point) end))
(yas--indent-according-to-mode snippet-markers))))
(t
nil)))))
(defun yas--collect-snippet-markers (snippet) (defun yas--collect-snippet-markers (snippet)
"Make a list of all the markers used by SNIPPET." "Make a list of all the markers used by SNIPPET."
@ -3947,15 +3944,6 @@ Meant to be called in a narrowed buffer, does various passes"
(push (yas--exit-marker snippet-exit) markers))) (push (yas--exit-marker snippet-exit) markers)))
markers)) markers))
(defun yas--real-line-beginning ()
(let ((c (char-after (line-beginning-position)))
(n (line-beginning-position)))
(while (or (eql c ?\ )
(eql c ?\t))
(cl-incf n)
(setq c (char-after n)))
n))
(defun yas--escape-string (escaped) (defun yas--escape-string (escaped)
(concat "YASESCAPE" (format "%d" escaped) "PROTECTGUARD")) (concat "YASESCAPE" (format "%d" escaped) "PROTECTGUARD"))
@ -4200,43 +4188,42 @@ When multiple expressions are found, only the last one counts."
(save-restriction (save-restriction
(widen) (widen)
(save-excursion (save-excursion
(dolist (field-and-mirror (dolist (field-and-mirror
(sort (sort
;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...) ;; make a list of ((F1 . M1) (F1 . M2) (F2 . M3) (F2 . M4) ...)
;; where F is the field that M is mirroring ;; where F is the field that M is mirroring
;; ;;
(cl-mapcan #'(lambda (field) (cl-mapcan #'(lambda (field)
(mapcar #'(lambda (mirror) (mapcar #'(lambda (mirror)
(cons field mirror)) (cons field mirror))
(yas--field-mirrors field))) (yas--field-mirrors field)))
(yas--snippet-fields snippet)) (yas--snippet-fields snippet))
;; then sort this list so that entries with mirrors with parent ;; then sort this list so that entries with mirrors with parent
;; fields appear before. This was important for fixing #290, and ;; fields appear before. This was important for fixing #290, and
;; luckily also handles the case where a mirror in a field causes ;; luckily also handles the case where a mirror in a field causes
;; another mirror to need reupdating ;; another mirror to need reupdating
;; ;;
#'(lambda (field-and-mirror1 field-and-mirror2) #'(lambda (field-and-mirror1 field-and-mirror2)
(> (yas--calculate-mirror-depth (cdr field-and-mirror1)) (> (yas--calculate-mirror-depth (cdr field-and-mirror1))
(yas--calculate-mirror-depth (cdr field-and-mirror2)))))) (yas--calculate-mirror-depth (cdr field-and-mirror2))))))
(let* ((field (car field-and-mirror)) (let* ((field (car field-and-mirror))
(mirror (cdr field-and-mirror)) (mirror (cdr field-and-mirror))
(parent-field (yas--mirror-parent-field mirror))) (parent-field (yas--mirror-parent-field mirror)))
;; before updating a mirror with a parent-field, maybe advance ;; before updating a mirror with a parent-field, maybe advance
;; its start (#290) ;; its start (#290)
;; ;;
(when parent-field (when parent-field
(yas--advance-start-maybe mirror (yas--fom-start parent-field))) (yas--advance-start-maybe mirror (yas--fom-start parent-field)))
;; update this mirror ;; update this mirror
;; ;;
(yas--mirror-update-display mirror field) (yas--mirror-update-display mirror field snippet)
;; `yas--place-overlays' is needed if the active field and ;; `yas--place-overlays' is needed since the active field and
;; protected overlays have been changed because of insertions ;; protected overlays might have been changed because of insertions
;; in `yas--mirror-update-display' ;; in `yas--mirror-update-display'.
;; (let ((active-field (yas--snippet-active-field snippet)))
(when (eq field (yas--snippet-active-field snippet)) (when active-field (yas--place-overlays snippet active-field))))))))
(yas--place-overlays snippet field)))))))
(defun yas--mirror-update-display (mirror field) (defun yas--mirror-update-display (mirror field snippet)
"Update MIRROR according to FIELD (and mirror transform)." "Update MIRROR according to FIELD (and mirror transform)."
(let* ((mirror-parent-field (yas--mirror-parent-field mirror)) (let* ((mirror-parent-field (yas--mirror-parent-field mirror))
@ -4255,7 +4242,11 @@ When multiple expressions are found, only the last one counts."
(set-marker (yas--mirror-end mirror) (point)) (set-marker (yas--mirror-end mirror) (point))
(yas--advance-start-maybe (yas--mirror-next mirror) (point)) (yas--advance-start-maybe (yas--mirror-next mirror) (point))
;; super-special advance ;; super-special advance
(yas--advance-end-of-parents-maybe mirror-parent-field (point)))))) (yas--advance-end-of-parents-maybe mirror-parent-field (point)))
(let ((yas--inhibit-overlay-hooks t))
(yas--indent-region (yas--mirror-start mirror)
(yas--mirror-end mirror)
snippet)))))
(defun yas--field-update-display (field) (defun yas--field-update-display (field)
"Much like `yas--mirror-update-display', but for fields." "Much like `yas--mirror-update-display', but for fields."