1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:14:40 -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:
Austin Clements 2010-01-05 16:50:36 -08:00 committed by Russ Cox
parent cfbee34a27
commit 6712cf365b

View File

@ -59,21 +59,22 @@
st)
"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
(let ((keywords '("import" "package"
"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"
(let ((builtins '("cap" "close" "closed" "len" "make" "new"
"panic" "panicln" "print" "println"))
(constants '("nil" "true" "false" "iota"))
(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 constants 'words) . font-lock-constant-face)
;; Function names in declarations
@ -312,6 +313,37 @@ encountered the close character."
;; 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 ()
"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.
nil)
(cs
;; Inside a multi-line comment
;; Inside a general comment
(goto-char (car cs))
(forward-char 1)
(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
;; Neither top-level nor in a multi-line string or comment
;; Not in a multi-line string or comment
(let ((indent 0)
(inside-indenting-paren nil)
(current-line-closes-scope nil))
(inside-indenting-paren nil))
;; Count every enclosing brace, plus parens that follow
;; import, const, var, or type and indent according to
;; depth. This simple rule does quite well, but also has a
@ -377,28 +398,21 @@ indented one level."
(setq inside-indenting-paren t)))))
(setq first nil))))
(setq current-line-closes-scope
(case (char-after)
((?\} ?\)) t)
(t nil)))
;; case, default, and labels are outdented 1 level
(when (looking-at "\\<case\\>\\|\\<default\\>\\|\\w+\\s *:\\(\\S.\\|$\\)")
(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))
(decf indent tab-width))
;; Continuation lines are indented 1 level
(forward-comment (- (buffer-size)))
(when (case (char-before)
((?\{ ?\} ?\; ?:)
;; Not a continuation line
((nil ?\{ ?:)
;; At the beginning of a block or the statement
;; following a label.
nil)
((?\()
;; Usually a continuation line, unless this paren
;; counted towards our indentation already
;; Usually a continuation line in an expression,
;; unless this paren is part of a factored
;; declaration.
(not inside-indenting-paren))
((?,)
;; Could be inside a literal. We're a little
@ -411,10 +425,12 @@ indented one level."
(and depth
(not (eq (char-after (caar depth)) ?\{)))))
(t
;; Except when the current line closes the previous line's
;; scope, anything else is a continuation line.
(not current-line-closes-scope)))
;; We're in the middle of a block. Did the
;; previous line end with an implicit or explicit
;; semicolon?
(not (go-mode-semicolon-p))))
(incf indent tab-width))
(max indent 0)))))))
(defun go-mode-indent-line ()