emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/swift-mode 62cf880 437/496: Update electric indent inside


From: ELPA Syncer
Subject: [nongnu] elpa/swift-mode 62cf880 437/496: Update electric indent inside multiline comments
Date: Sun, 29 Aug 2021 11:34:23 -0400 (EDT)

branch: elpa/swift-mode
commit 62cf880cff5ced0faca42f500c562528cbd3356b
Author: taku0 <mxxouy6x3m_github@tatapa.org>
Commit: taku0 <mxxouy6x3m_github@tatapa.org>

    Update electric indent inside multiline comments
    
    More consistent behavior between `swift-mode:indent-new-comment-line`,
    `swift-mode:post-self-insert`, and `swift-mode:indent-line`.
    
    Automatically insert a line break before the closing delimiter of multiline
    comment.
---
 swift-mode-indent.el | 280 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 201 insertions(+), 79 deletions(-)

diff --git a/swift-mode-indent.el b/swift-mode-indent.el
index cfdce81..e70c899 100644
--- a/swift-mode-indent.el
+++ b/swift-mode-indent.el
@@ -84,6 +84,12 @@
   :group 'swift
   :safe 'booleanp)
 
+(defcustom swift-mode:break-line-before-comment-close t
+  "If non-nil, break line before the closing delimiter of multiline comments."
+  :type 'boolean
+  :group 'swift
+  :safe 'booleanp)
+
 (defcustom swift-mode:highlight-anchor nil
   "Highlight anchor point for indentation if non-nil.
 
@@ -172,22 +178,55 @@ declaration and its offset is `swift-mode:basic-offset'."
 (defun swift-mode:calculate-indent-of-multiline-comment ()
   "Return the indentation of the current line inside a multiline comment."
   (back-to-indentation)
-  (let ((comment-beginning-position (nth 8 (syntax-ppss))))
+  (let ((comment-beginning-position (nth 8 (syntax-ppss)))
+        (starts-with-asterisk (eq (char-after) ?*)))
     (forward-line -1)
     (back-to-indentation)
-    (if (<= (point) comment-beginning-position)
-        ;; The cursor was on the 2nd line of the comment, so aligns with
-        ;; the asterisk of the comment starter.
-        (progn
-          (goto-char comment-beginning-position)
-          (forward-char)
-          (swift-mode:indentation (point) 0))
-      ;; The cursor was on the 3rd or following lines of the comment, so aligns
-      ;; with a non-empty preceding line.
-      (if (eolp)
-          ;; The cursor is on an empty line, so seeks a non-empty-line.
-          (swift-mode:calculate-indent-of-multiline-comment)
-        (swift-mode:indentation (point) 0)))))
+    (cond
+     ((<= (point) comment-beginning-position)
+      ;; The cursor was on the 2nd line of the comment.
+      (goto-char comment-beginning-position)
+      (forward-char)
+      ;; If there are extra characters or spaces after asterisks, aligns with
+      ;; the first non-space character or end of line.  Otherwise, aligns with
+      ;; the first asterisk.
+      (when (and
+             (looking-at "\\**[^*\n]+")
+             (not (and swift-mode:prepend-asterisk-to-comment-line
+                       starts-with-asterisk)))
+        (skip-chars-forward "*")
+        (skip-syntax-forward " "))
+      (swift-mode:indentation (point) 0))
+
+     ;; The cursor was on the 3rd or following lines of the comment.
+
+     ((= (save-excursion
+           (forward-line)
+           (back-to-indentation)
+           (point))
+         (save-excursion
+           (goto-char comment-beginning-position)
+           (if (forward-comment 1)
+               (progn
+                 (backward-char)
+                 (skip-chars-backward "*")
+                 (point))
+             -1)))
+      ;; Before the closing delimiter.  Aligns with the first asterisk of the
+      ;; opening delimiter.
+      (goto-char comment-beginning-position)
+      (forward-char)
+      (swift-mode:indentation (point) 0))
+
+     ;; Otherwise, aligns with a non-empty preceding line.
+
+     ((and (bolp) (eolp))
+      ;; The previous line is empty, so seeks a non-empty-line.
+      (swift-mode:calculate-indent-of-multiline-comment))
+
+     (t
+      ;; The previous line is not empty, so aligns to this line.
+      (swift-mode:indentation (point) 0)))))
 
 (defun swift-mode:calculate-indent-of-multiline-string ()
   "Return the indentation of the current line inside a multiline string."
@@ -213,7 +252,7 @@ declaration and its offset is `swift-mode:basic-offset'."
              swift-mode:multiline-statement-offset))
         ;; The cursor was on the 3rd or following lines of the comment, so
         ;; aligns with a non-empty preceding line.
-        (if (eolp)
+        (if (and (bolp) (eolp))
             ;; The cursor is on an empty line, so seeks a non-empty-line.
             (swift-mode:calculate-indent-of-multiline-string)
           (swift-mode:indentation (point) 0))))))
@@ -1527,15 +1566,14 @@ Return nil otherwise."
   "Skips forward whitespaces and newlines."
   (skip-syntax-forward " >"))
 
-(defun swift-mode:incomplete-comment-p ()
-  "Return t if the point is inside an incomplete comment.
+(defun swift-mode:incomplete-comment-p (chunk)
+  "Return t if the CHUNK is incomplete comment.
 
 Return nil otherwise."
-  (let ((chunk (swift-mode:chunk-after)))
-    (and (swift-mode:chunk:comment-p chunk)
-         (save-excursion
-           (goto-char (swift-mode:chunk:start chunk))
-           (not (forward-comment 1))))))
+  (and (swift-mode:chunk:comment-p chunk)
+       (save-excursion
+         (goto-char (swift-mode:chunk:start chunk))
+         (not (forward-comment 1)))))
 
 (defun swift-mode:indent-new-comment-line (&optional soft)
   "Break the line at the point and indent the new line.
@@ -1550,12 +1588,13 @@ See `indent-new-comment-line' for SOFT."
     (if soft (insert-and-inherit ?\n) (newline 1))
     (delete-horizontal-space)
 
+    ;; Inserts a prefix and indents the line.
     (cond
      ((not (swift-mode:chunk:comment-p chunk))
       (indent-according-to-mode))
 
      ((swift-mode:chunk:single-line-comment-p chunk)
-      (insert-before-markers-and-inherit
+      (insert-and-inherit
        (save-excursion
          (goto-char comment-beginning-position)
          (looking-at "/+\\s *")
@@ -1563,7 +1602,7 @@ See `indent-new-comment-line' for SOFT."
       (indent-according-to-mode))
 
      ((not comment-multi-line)
-      (insert-before-markers-and-inherit
+      (insert-and-inherit
        (save-excursion
          (goto-char comment-beginning-position)
          (looking-at "/\\*+\\s *")
@@ -1573,33 +1612,98 @@ See `indent-new-comment-line' for SOFT."
         (forward-line 0)
         (backward-char)
         (delete-horizontal-space)
-        (insert-before-markers-and-inherit " */"))
+        (insert-and-inherit " */"))
       (indent-according-to-mode))
 
+     (t
+      (swift-mode:format-multiline-comment-line-after-newline chunk soft)))
+
+    ;; Cleans up the previous line.
+    (save-excursion
+      (forward-line 0)
+      (backward-char)
+      (delete-horizontal-space))))
+
+(defun swift-mode:format-multiline-comment-line-after-newline (chunk soft)
+  "Insert prefix and indent current line in multiline comment.
+
+The point is assumed inside multiline comment and just after newline.
+
+The closing delimiter is also inserted and/or formatted depending on custom
+variables `swift-mode:auto-close-multiline-comment' and
+`swift-mode:break-line-before-comment-close'.
+
+CHUNK is the comment chunk.
+
+See `indent-new-comment-line' for SOFT."
+  (let ((comment-beginning-position (swift-mode:chunk:start chunk)))
+    (cond
      ((save-excursion
         (forward-line -1)
         (<= (point) comment-beginning-position))
       ;; The cursor was on the 2nd line of the comment.
-      ;; Uses default prefix.
-      (when swift-mode:prepend-asterisk-to-comment-line
-        (insert-before-markers-and-inherit "*")
-        (when swift-mode:insert-space-after-asterisk-in-comment
-          (insert-before-markers-and-inherit " ")))
+
+      ;; If the comment have only one line, delete a space after asterisk.
+      ;;
+      ;; Example:
+      ;; /** aaa */
+      ;; ↓
+      ;; /**
+      ;;  aaa
+      ;;  */
+      ;;
+      ;; /** aaa
+      ;;  */
+      ;; ↓
+      ;; /**
+      ;;     aaa
+      ;;  */
+      (when (= (line-beginning-position)
+               (save-excursion
+                 (goto-char comment-beginning-position)
+                 (forward-comment 1)
+                 (line-beginning-position)))
+        (save-excursion
+          (goto-char comment-beginning-position)
+          (forward-char)
+          (skip-chars-forward "*")
+          (when (looking-at " [ \t]*$")
+            (delete-char 1))))
+
+      ;; If the point is just before the closing delimiter, breaks the line.
+      (when (and swift-mode:break-line-before-comment-close
+                 (= (point)
+                    (save-excursion
+                      (goto-char comment-beginning-position)
+                      (if (forward-comment 1)
+                          (progn
+                            (backward-char)
+                            (skip-chars-backward "*")
+                            (point))
+                        -1))))
+        (save-excursion
+          (if soft (insert-and-inherit ?\n) (newline 1))
+          (indent-according-to-mode)))
+
+      ;; Invokes `swift-mode:indent-line`
       (indent-according-to-mode)
-      (insert-before-markers-and-inherit
-       (save-excursion
-         (goto-char comment-beginning-position)
-         (forward-char 1)
-         (looking-at "\\**\\(\\s *\\)")
-         (let ((prefix (match-string-no-properties 0)))
-           (if (= (length (match-string-no-properties 1)) 0)
-               ""
-             (substring
-              (replace-regexp-in-string "\\*" " " prefix)
-              (if swift-mode:prepend-asterisk-to-comment-line
-                  (if swift-mode:insert-space-after-asterisk-in-comment 2 1)
-                0)
-              (length prefix)))))))
+
+      ;; Inserts or replaces a space to an asterisk.
+      (when swift-mode:prepend-asterisk-to-comment-line
+        (let ((columns-from-end (- (line-end-position) (point))))
+          (move-to-column
+           (save-excursion
+             (goto-char comment-beginning-position)
+             (forward-char)
+             (current-column)))
+          (insert-and-inherit "*")
+          (when (eq (char-after) ?\s)
+            (delete-char 1))
+          (when (and
+                 swift-mode:insert-space-after-asterisk-in-comment
+                 (not (eq (char-after) ?\s)))
+            (insert-and-inherit " "))
+          (goto-char (- (line-end-position) columns-from-end)))))
 
      ;; The cursor was on the 3nd or following lines of
      ;; the comment.
@@ -1611,39 +1715,34 @@ See `indent-new-comment-line' for SOFT."
          (forward-line -1)
          (looking-at "\\s *\\(\\*+\\s *\\)")))
       ;; The previous line has a prefix.  Uses it.
-      (insert-before-markers-and-inherit (match-string-no-properties 1))
-      (indent-according-to-mode))
-
-     ((save-excursion
-        (forward-line -1)
-        (looking-at "$"))
-      ;; The previous line is empty.  Uses the default indentation.
+      (insert-and-inherit (match-string-no-properties 1))
       (indent-according-to-mode))
 
      (t
-      ;; Uses the prefix of the previous line.
-      (insert-before-markers-and-inherit
-       (save-excursion
-         (forward-line -1)
-         (looking-at "\\s *")
-         (match-string-no-properties 0)))))
-
-    ;; Cleans up the previous line.
-    (save-excursion
-      (forward-line 0)
-      (backward-char)
-      (delete-horizontal-space))
+      ;; Uses the default indentation.
+      (indent-according-to-mode)))
 
     ;; Closes incomplete multiline comment.
     (when (and swift-mode:auto-close-multiline-comment
-               (swift-mode:chunk:multiline-comment-p chunk)
-               (swift-mode:incomplete-comment-p))
+               (swift-mode:incomplete-comment-p chunk))
       (save-excursion
         (end-of-line)
         (when comment-multi-line
           (if soft (insert-and-inherit ?\n) (newline 1)))
         (insert-and-inherit "*/")
-        (indent-according-to-mode)))))
+        (indent-according-to-mode)))
+
+    ;; Make sure the closing delimiter is on its own line.
+    (when swift-mode:break-line-before-comment-close
+      (save-excursion
+        (goto-char comment-beginning-position)
+        (when (forward-comment 1)
+          (backward-char)
+          (skip-chars-backward "*")
+          (skip-syntax-backward " ")
+          (when (not (bolp))
+            (if soft (insert-and-inherit ?\n) (newline 1))
+            (indent-according-to-mode)))))))
 
 (defun swift-mode:post-self-insert ()
   "Miscellaneous logic for electric indentation."
@@ -1656,21 +1755,24 @@ See `indent-new-comment-line' for SOFT."
      (swift-mode:chunk:comment-p (swift-mode:chunk-after))
      (save-excursion (backward-char) (skip-syntax-backward " ") (bolp)))
     (when swift-mode:insert-space-after-asterisk-in-comment
-      (insert-before-markers-and-inherit " "))
-    (indent-according-to-mode))
+      (insert-and-inherit " "))
+    (when electric-indent-mode
+      (indent-according-to-mode)))
 
    ;; Fixes "* /" at the end of a multiline comment to "*/".
    ((and
-     (= last-command-event ?/)
      swift-mode:fix-comment-close
-     (swift-mode:chunk:comment-p (swift-mode:chunk-after))
-     (save-excursion
-       (let ((pos (point)))
-         (forward-line 0)
-         (and
-          (looking-at "^\\s *\\*\\s +/")
-          (eq (match-end 0) pos)
-          (swift-mode:incomplete-comment-p)))))
+     (= last-command-event ?/)
+     (let ((chunk (swift-mode:chunk-after))
+           (pos (point)))
+       (and
+        (swift-mode:chunk:comment-p chunk)
+        (save-excursion
+          (forward-line 0)
+          (and
+           (looking-at "^\\s *\\*\\s +/")
+           (eq (match-end 0) pos)
+           (swift-mode:incomplete-comment-p chunk))))))
     (backward-char)
     (delete-horizontal-space)
     (forward-char))
@@ -1678,9 +1780,29 @@ See `indent-new-comment-line' for SOFT."
    ;; Indents electrically when ")" is inserted at bol as the end of a string
    ;; interpolation.
    ((and
+     electric-indent-mode
      (= last-command-event ?\))
-     (save-excursion (backward-char) (skip-syntax-backward " ") (bolp)))
-    (indent-according-to-mode))))
+     (save-excursion (backward-char) (skip-syntax-backward " ") (bolp))
+     (= (swift-mode:chunk:start (swift-mode:chunk-after)) (1- (point))))
+    (indent-according-to-mode))
+
+   ;; Indents electrically after newline inside strings and comments.
+   ;; Unlike `electric-indent-mode', the previous line is not indented.
+   ((and
+     electric-indent-mode
+     (= last-command-event ?\n))
+    (let ((chunk (swift-mode:chunk-after)))
+      (if (swift-mode:chunk:multiline-comment-p chunk)
+          (progn
+            (delete-horizontal-space)
+            (swift-mode:format-multiline-comment-line-after-newline
+             chunk
+             (not use-hard-newlines)))
+        (indent-according-to-mode)))
+    (save-excursion
+      (forward-line 0)
+      (backward-char)
+      (delete-horizontal-space)))))
 
 (defun swift-mode:highlight-anchor (indentation)
   "Highlight the anchor point of the INDENTATION."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]