[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/go-mode 5186c83 491/495: Support basic indenting in multil
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/go-mode 5186c83 491/495: Support basic indenting in multiline comments. |
Date: |
Sat, 7 Aug 2021 09:06:15 -0400 (EDT) |
branch: elpa/go-mode
commit 5186c83e5691932d208fafedf9a1a5ade369eb24
Author: Muir Manders <muir@mnd.rs>
Commit: Peter Sanford <psanford@sanford.io>
Support basic indenting in multiline comments.
This commit changes a few things to get indenting working in multiline
comments:
1. Make go-indentation-at-point return something when inside multiline
comments. It basically guesses an indent based on the previous line
or start of comment, along with a special case to line up all the
"*" if you are making comment art. I didn't think it was worth it
to support all of gofmt's multiline comment behavior.
2. Don't ignore comments in go-mode-indent-line.
3. Tweak go-mode-indent-line to not uses tabs when indenting beyond
the "/*" in multiline comments. If you use tabs, gofmt ends up
changing things around in unexpected ways.
4. Tweak our electric indent function to trigger completion after
newline within comments, and after typing the closing "*/".
Fixes #369.
Closes: #370 [via git-merge-pr]
---
go-mode.el | 135 +++++++++++++++++----
test/go-indentation-test.el | 73 +++++++++++
.../indentation_tests/multiline_comment.go | 43 +++++++
3 files changed, 230 insertions(+), 21 deletions(-)
diff --git a/go-mode.el b/go-mode.el
index 835dc18..21719a9 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -873,7 +873,80 @@ The return value is the position of the opening paren."
(point)))))
(defun go-indentation-at-point ()
- "Return the appropriate indentation for the current line.
+ "Return the appropriate indentation for the current line."
+ (save-excursion
+ (beginning-of-line)
+
+ (if (go-in-comment-p)
+ (go--multiline-comment-indent)
+ (go--indentation-at-point))))
+
+(defun go--multiline-comment-indent ()
+ "Return the appropriate indent inside multiline comment.
+
+Assumes point is at beginning of line within comment. This
+function has basic logic to indent as you add new lines to a
+multiline comment, and to line up all the `*' if each line starts
+with `*'. The gofmt behavior for multiline comments is
+suprisingly complex and strange/buggy, so we just aim to do
+something simple rather than encode all the subtle behavior."
+ (let* (;; Indent of current line.
+ (indent (current-indentation))
+ ;; Indent of opening "/*".
+ start-indent
+ ;; Default indent to use based on preceding context.
+ natural-indent
+ ;; Non-nil means keep existing indent and give up calculating indent.
+ give-up
+ ;; Whether all comment lines (except first) begin with "*".
+ (all-star t))
+
+ (save-excursion
+ (go-goto-beginning-of-string-or-comment)
+
+ (setq start-indent (current-indentation))
+
+ ;; If other stuff precedes start of multiline comment, give up.
+ (setq give-up (/= (current-column) start-indent))
+
+ ;; Skip "/*".
+ (forward-char 2)
+
+ (skip-syntax-forward " ")
+
+ (if (not (eolp))
+ ;; If we aren't at EOL, we have content on the first line.
+ ;; Base our natural indent on that.
+ (setq natural-indent (current-column))
+ ;; Otherwise default to 1 space beyond "/*".
+ (setq natural-indent (+ start-indent 3)))
+
+ (let (done)
+ (while (not done)
+ (setq done (or (looking-at ".*\\*/") (not (zerop (forward-line)))))
+ (setq all-star (and all-star (looking-at "[[:space:]]*\\*"))))))
+
+ ;; If previous line has comment content, use its indent as our
+ ;; natural indent.
+ (save-excursion
+ (when (zerop (forward-line -1))
+ (beginning-of-line)
+ (when (and (go-in-comment-p) (> (current-indentation) 0))
+ (setq natural-indent (current-indentation)))))
+
+ (cond
+ (give-up indent)
+
+ (all-star (1+ start-indent))
+
+ ;; Closing "*/" with no preceding content always lines up with "/*".
+ ((looking-at "[[:space:]]*\\*/") start-indent)
+
+ ;; If the line is already indented, leave it.
+ (t (if (zerop indent) natural-indent indent)))))
+
+(defun go--indentation-at-point ()
+ "Return the appropriate indentation for the current non-comment line.
This function works by walking a line's characters backwards. When it
encounters a closing paren or brace it bounces to the corresponding
@@ -1242,14 +1315,14 @@ INDENT is the normal indent of this line, i.e. that of
the case body."
(defun go-mode-indent-line ()
(interactive)
(let (indent
- shift-amt
;; case sensitively match "case", "default", etc.
(case-fold-search nil)
(pos (- (point-max) (point)))
(point (point))
- (beg (line-beginning-position)))
+ (beg (line-beginning-position))
+ (non-tab-indents 0))
(back-to-indentation)
- (if (go-in-string-or-comment-p)
+ (if (go-in-string-p)
(goto-char point)
(setq indent (go-indentation-at-point))
(when (or
@@ -1263,11 +1336,22 @@ INDENT is the normal indent of this line, i.e. that of
the case body."
;; comment attached above a "case" statement
(go--case-comment-p indent))
(cl-decf indent tab-width))
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- nil
+
+ ;; Don't do anything if current indent is correct.
+ (when (/= indent (current-column))
+ ;; Don't use tabs for indenting beyond "/*" in multiline
+ ;; comments. They don't play well with gofmt.
+ (when (go-in-comment-p)
+ (save-excursion
+ (go-goto-beginning-of-string-or-comment)
+ (when (> indent (current-indentation))
+ (setq non-tab-indents (- indent (current-indentation)))
+ (setq indent (current-indentation)))))
+
(delete-region beg (point))
- (indent-to indent))
+ (indent-to indent)
+ (insert-char ? non-tab-indents))
+
;; If initial point was within line's indentation,
;; position after the indentation. Else stay at same point in text.
(if (> (- (point-max) pos) (point))
@@ -1692,19 +1776,28 @@ This is intended to be called from
`before-change-functions'."
(setq go-dangling-cache (make-hash-table :test 'eql)))
(defun go--electric-indent-function (inserted-char)
- (cond
- ;; Indent after starting a "//" or "/*" comment.
- ;; This is handy for comments above "case" statements.
- ((or (eq inserted-char ?/) (eq inserted-char ?*))
- (when (eq (char-before (1- (point))) ?/)
- 'do-indent))
-
- ((eq inserted-char ? )
- (and
- (eq (char-before (- (point) 1)) ?e)
- (eq (char-before (- (point) 2)) ?s)
- (eq (char-before (- (point) 3)) ?a)
- (eq (char-before (- (point) 4)) ?c)))))
+ (let ((prev (char-before (1- (point)))))
+ (cond
+ ;; Indent after starting/ending a comment. This is handy for
+ ;; comments above "case" statements and closing multiline
+ ;; comments.
+ ((or
+ (and (eq inserted-char ?/) (eq prev ?/))
+ (and (eq inserted-char ?/) (eq prev ?*))
+ (and (eq inserted-char ?*) (eq prev ?/)))
+ 'do-indent)
+
+ ((eq inserted-char ? )
+ (and
+ (eq prev ?e)
+ (eq (char-before (- (point) 2)) ?s)
+ (eq (char-before (- (point) 3)) ?a)
+ (eq (char-before (- (point) 4)) ?c)))
+
+ ;; Trick electric-indent-mode into indenting inside multiline
+ ;; comments.
+ ((and (eq inserted-char ?\n) (go-in-comment-p))
+ 'do-indent))))
(defun go--comment-region (beg end &optional arg)
"Switch to block comment when commenting a partial line."
diff --git a/test/go-indentation-test.el b/test/go-indentation-test.el
index 8ed95f7..8f5d9bc 100644
--- a/test/go-indentation-test.el
+++ b/test/go-indentation-test.el
@@ -49,3 +49,76 @@ var foo = 123 +
789
"
))
+
+(ert-deftest go--indent-multiline-comment ()
+ (go--should-indent
+ "
+{
+ /*
+a
+ */
+}
+"
+
+ "
+{
+ /*
+ a
+ */
+}
+")
+
+ (go--should-indent
+ "
+{
+ /* LISTEN
+a
+ */
+}
+"
+
+ "
+{
+ /* LISTEN
+ a
+ */
+}
+")
+
+ (go--should-indent
+ "
+{
+ /* c
+ c
+c
+ */
+}
+"
+
+ "
+{
+ /* c
+ c
+ c
+ */
+}
+")
+
+ (go--should-indent
+ "
+{
+ /* cool
+ * cat
+ *
+ */
+}
+"
+
+ "
+{
+ /* cool
+ * cat
+ *
+ */
+}
+"))
diff --git a/test/testdata/indentation_tests/multiline_comment.go
b/test/testdata/indentation_tests/multiline_comment.go
index 002f60c..5ccdf7e 100644
--- a/test/testdata/indentation_tests/multiline_comment.go
+++ b/test/testdata/indentation_tests/multiline_comment.go
@@ -9,3 +9,46 @@ func main() {
// code
}
}
+
+func _() {
+ /* foo
+ * bar
+ */
+
+ /* abc
+ 123
+ def
+ lol
+ */
+
+ /*
+ abc
+ - def
+ */
+
+ /*
+ hello
+ there */
+
+ /*
+ hello
+ there */
+
+ /*
+ foo
+ */
+
+ /*
+ foo
+ */
+
+ /*
+ foo
+ */
+
+ /* foo
+ asd
+ asd
+ asd
+ */
+}
- [nongnu] elpa/go-mode 6a64cbf 439/495: Fix indentation for composite literal keys., (continued)
- [nongnu] elpa/go-mode 6a64cbf 439/495: Fix indentation for composite literal keys., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode fb1272c 441/495: indent: fix performance in giant comments, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode c020e2c 456/495: Fontify type names in more places., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 2a1584f 454/495: Readme: add note recommending goimports, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 57becfb 460/495: Fontify type names in interface declarations, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode cf53daa 459/495: Fix indentation in naked blocks., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode f872781 466/495: Fontify variable names., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode acec0aa 471/495: Fix Content-Type for https://play.golang.org/share, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode cad6d0a 472/495: Fix fontification performance issue, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 1fbe6a8 490/495: Fix comment filling at start of buffer., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 5186c83 491/495: Support basic indenting in multiline comments.,
ELPA Syncer <=
- [nongnu] elpa/go-mode c576513 494/495: Fix fontification of multiplicand after index expr., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 49a5380 493/495: Trivial fix of docstring and comment spelling typos., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 584628e 148/495: instead of killing lines, delete them, to avoid manipulating the kill ring, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode a82c165 221/495: fix the license, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 27068bb 222/495: provide configuration option for how to display coverage buffer, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 86ed568 235/495: add link to `defgroup'., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode a9b9871 247/495: Use view-mode in godoc-mode, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode dce210f 250/495: Bump version to 1.3.1, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 8baa836 251/495: Don't break fontification when limiting point, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode dccb56c 256/495: go-unused-imports-lines: only compile the current file, ELPA Syncer, 2021/08/07