mirror of
https://github.com/golang/go
synced 2024-11-25 06:07:58 -07:00
Update Emacs go-mode for new semicolon rule.
Fixes #415. R=rsc CC=golang-dev https://golang.org/cl/183104
This commit is contained in:
parent
cfbee34a27
commit
6712cf365b
@ -59,21 +59,22 @@
|
|||||||
st)
|
st)
|
||||||
"Syntax table for Go mode.")
|
"Syntax table for Go mode.")
|
||||||
|
|
||||||
|
(defvar go-mode-keywords
|
||||||
|
'("break" "default" "func" "interface" "select"
|
||||||
|
"case" "defer" "go" "map" "struct"
|
||||||
|
"chan" "else" "goto" "package" "switch"
|
||||||
|
"const" "fallthrough" "if" "range" "type"
|
||||||
|
"continue" "for" "import" "return" "var")
|
||||||
|
"All keywords in the Go language. Used for font locking and
|
||||||
|
some syntax analysis.")
|
||||||
|
|
||||||
(defvar go-mode-font-lock-keywords
|
(defvar go-mode-font-lock-keywords
|
||||||
(let ((keywords '("import" "package"
|
(let ((builtins '("cap" "close" "closed" "len" "make" "new"
|
||||||
"var" "const" "type" "func"
|
|
||||||
"struct" "interface"
|
|
||||||
"chan" "map"
|
|
||||||
"if" "else" "for" "switch" "select"
|
|
||||||
"range" "case" "default"
|
|
||||||
"return" "continue" "break" "fallthrough" "goto"
|
|
||||||
"go" "defer"))
|
|
||||||
(builtins '("cap" "close" "closed" "len" "make" "new"
|
|
||||||
"panic" "panicln" "print" "println"))
|
"panic" "panicln" "print" "println"))
|
||||||
(constants '("nil" "true" "false" "iota"))
|
(constants '("nil" "true" "false" "iota"))
|
||||||
(type-name "\\s *\\(?:[*(]\\s *\\)*\\(?:\\w+\\s *\\.\\s *\\)?\\(\\w+\\)")
|
(type-name "\\s *\\(?:[*(]\\s *\\)*\\(?:\\w+\\s *\\.\\s *\\)?\\(\\w+\\)")
|
||||||
)
|
)
|
||||||
`((,(regexp-opt keywords 'words) . font-lock-keyword-face)
|
`((,(regexp-opt go-mode-keywords 'words) . font-lock-keyword-face)
|
||||||
(,(regexp-opt builtins 'words) . font-lock-builtin-face)
|
(,(regexp-opt builtins 'words) . font-lock-builtin-face)
|
||||||
(,(regexp-opt constants 'words) . font-lock-constant-face)
|
(,(regexp-opt constants 'words) . font-lock-constant-face)
|
||||||
;; Function names in declarations
|
;; Function names in declarations
|
||||||
@ -312,6 +313,37 @@ encountered the close character."
|
|||||||
;; Indentation
|
;; Indentation
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
(defvar go-mode-non-terminating-keywords-regexp
|
||||||
|
(let* ((kws go-mode-keywords)
|
||||||
|
(kws (remove "break" kws))
|
||||||
|
(kws (remove "continue" kws))
|
||||||
|
(kws (remove "fallthrough" kws))
|
||||||
|
(kws (remove "return" kws)))
|
||||||
|
(regexp-opt kws 'words))
|
||||||
|
"Regular expression matching all Go keywords that *do not*
|
||||||
|
implicitly terminate a statement.")
|
||||||
|
|
||||||
|
(defun go-mode-semicolon-p ()
|
||||||
|
"True iff point immediately follows either an explicit or
|
||||||
|
implicit semicolon. Point should immediately follow the last
|
||||||
|
token on the line."
|
||||||
|
|
||||||
|
;; #Semicolons
|
||||||
|
(case (char-before)
|
||||||
|
((?\;) t)
|
||||||
|
;; String literal
|
||||||
|
((?' ?\" ?`) t)
|
||||||
|
;; One of the operators and delimiters ++, --, ), ], or }
|
||||||
|
((?+) (eq (char-before (1- (point))) ?+))
|
||||||
|
((?-) (eq (char-before (1- (point))) ?-))
|
||||||
|
((?\) ?\] ?\}) t)
|
||||||
|
;; An identifier or one of the keywords break, continue,
|
||||||
|
;; fallthrough, or return or a numeric literal
|
||||||
|
(otherwise
|
||||||
|
(save-excursion
|
||||||
|
(when (/= (skip-chars-backward "[:word:]_") 0)
|
||||||
|
(not (looking-at go-mode-non-terminating-keywords-regexp)))))))
|
||||||
|
|
||||||
(defun go-mode-indentation ()
|
(defun go-mode-indentation ()
|
||||||
"Compute the ideal indentation level of the current line.
|
"Compute the ideal indentation level of the current line.
|
||||||
|
|
||||||
@ -335,25 +367,14 @@ indented one level."
|
|||||||
;; Inside a multi-line string. Don't mess with indentation.
|
;; Inside a multi-line string. Don't mess with indentation.
|
||||||
nil)
|
nil)
|
||||||
(cs
|
(cs
|
||||||
;; Inside a multi-line comment
|
;; Inside a general comment
|
||||||
(goto-char (car cs))
|
(goto-char (car cs))
|
||||||
(forward-char 1)
|
(forward-char 1)
|
||||||
(current-column))
|
(current-column))
|
||||||
((not (go-mode-nesting))
|
|
||||||
;; Top-level
|
|
||||||
(if (or (eolp)
|
|
||||||
(looking-at "\\<\\(import\\|package\\|const\\|var\\|type\\|func\\)\\>")
|
|
||||||
(looking-at "//\\|/\\*"))
|
|
||||||
0
|
|
||||||
;; Continuation line
|
|
||||||
;; XXX If you start typing a new continuation line, nothing
|
|
||||||
;; will cause it to be indented.
|
|
||||||
tab-width))
|
|
||||||
(t
|
(t
|
||||||
;; Neither top-level nor in a multi-line string or comment
|
;; Not in a multi-line string or comment
|
||||||
(let ((indent 0)
|
(let ((indent 0)
|
||||||
(inside-indenting-paren nil)
|
(inside-indenting-paren nil))
|
||||||
(current-line-closes-scope nil))
|
|
||||||
;; Count every enclosing brace, plus parens that follow
|
;; Count every enclosing brace, plus parens that follow
|
||||||
;; import, const, var, or type and indent according to
|
;; import, const, var, or type and indent according to
|
||||||
;; depth. This simple rule does quite well, but also has a
|
;; depth. This simple rule does quite well, but also has a
|
||||||
@ -377,28 +398,21 @@ indented one level."
|
|||||||
(setq inside-indenting-paren t)))))
|
(setq inside-indenting-paren t)))))
|
||||||
(setq first nil))))
|
(setq first nil))))
|
||||||
|
|
||||||
(setq current-line-closes-scope
|
|
||||||
(case (char-after)
|
|
||||||
((?\} ?\)) t)
|
|
||||||
(t nil)))
|
|
||||||
|
|
||||||
;; case, default, and labels are outdented 1 level
|
;; case, default, and labels are outdented 1 level
|
||||||
(when (looking-at "\\<case\\>\\|\\<default\\>\\|\\w+\\s *:\\(\\S.\\|$\\)")
|
(when (looking-at "\\<case\\>\\|\\<default\\>\\|\\w+\\s *:\\(\\S.\\|$\\)")
|
||||||
(decf indent tab-width)
|
(decf indent tab-width))
|
||||||
;; Lines with case, default, etc. also "close" the previous line's
|
|
||||||
;; scope, even when there is no semicolon. Don't treat them as
|
|
||||||
;; continuation lines.
|
|
||||||
(setq current-line-closes-scope t))
|
|
||||||
|
|
||||||
;; Continuation lines are indented 1 level
|
;; Continuation lines are indented 1 level
|
||||||
(forward-comment (- (buffer-size)))
|
(forward-comment (- (buffer-size)))
|
||||||
(when (case (char-before)
|
(when (case (char-before)
|
||||||
((?\{ ?\} ?\; ?:)
|
((nil ?\{ ?:)
|
||||||
;; Not a continuation line
|
;; At the beginning of a block or the statement
|
||||||
|
;; following a label.
|
||||||
nil)
|
nil)
|
||||||
((?\()
|
((?\()
|
||||||
;; Usually a continuation line, unless this paren
|
;; Usually a continuation line in an expression,
|
||||||
;; counted towards our indentation already
|
;; unless this paren is part of a factored
|
||||||
|
;; declaration.
|
||||||
(not inside-indenting-paren))
|
(not inside-indenting-paren))
|
||||||
((?,)
|
((?,)
|
||||||
;; Could be inside a literal. We're a little
|
;; Could be inside a literal. We're a little
|
||||||
@ -411,10 +425,12 @@ indented one level."
|
|||||||
(and depth
|
(and depth
|
||||||
(not (eq (char-after (caar depth)) ?\{)))))
|
(not (eq (char-after (caar depth)) ?\{)))))
|
||||||
(t
|
(t
|
||||||
;; Except when the current line closes the previous line's
|
;; We're in the middle of a block. Did the
|
||||||
;; scope, anything else is a continuation line.
|
;; previous line end with an implicit or explicit
|
||||||
(not current-line-closes-scope)))
|
;; semicolon?
|
||||||
|
(not (go-mode-semicolon-p))))
|
||||||
(incf indent tab-width))
|
(incf indent tab-width))
|
||||||
|
|
||||||
(max indent 0)))))))
|
(max indent 0)))))))
|
||||||
|
|
||||||
(defun go-mode-indent-line ()
|
(defun go-mode-indent-line ()
|
||||||
|
Loading…
Reference in New Issue
Block a user