32
33
;; - Use go--old-completion-list-style when using a plain list as the
33
34
;; collection for completing-read
35
;; - Use go--kill-whole-line instead of kill-whole-line (called
36
;; kill-entire-line in XEmacs)
38
36
;; - Use go--position-bytes instead of position-bytes
39
37
(defmacro go--xemacs-p ()
40
38
`(featurep 'xemacs))
42
(defalias 'go--kill-whole-line
43
(if (fboundp 'kill-whole-line)
47
40
;; Delete the current line without putting it in the kill-ring.
48
41
(defun go--delete-whole-line (&optional arg)
49
;; Emacs uses both kill-region and kill-new, Xemacs only uses
50
;; kill-region. In both cases we turn them into operations that do
51
;; not modify the kill ring. This solution does depend on the
52
;; implementation of kill-line, but it's the only viable solution
53
;; that does not require to write kill-line from scratch.
54
(flet ((kill-region (beg end)
55
(delete-region beg end))
57
(go--kill-whole-line arg)))
42
;; Derived from `kill-whole-line'.
43
;; ARG is defined as for that function.
47
(save-excursion (forward-visible-line 0) (eobp)))
48
(signal 'end-of-buffer nil))
51
(save-excursion (end-of-visible-line) (bobp)))
52
(signal 'beginning-of-buffer nil))
54
(delete-region (progn (forward-visible-line 0) (point))
55
(progn (end-of-visible-line) (point))))
57
(delete-region (progn (end-of-visible-line) (point))
58
(progn (forward-visible-line (1+ arg))
63
(delete-region (progn (forward-visible-line 0) (point))
64
(progn (forward-visible-line arg) (point))))))
59
66
;; declare-function is an empty macro that only byte-compile cares
60
67
;; about. Wrap in always false if to satisfy Emacsen without that
63
70
(declare-function go--position-bytes "go-mode" (point)))
64
72
;; XEmacs unfortunately does not offer position-bytes. We can fall
65
73
;; back to just using (point), but it will be incorrect as soon as
66
74
;; multibyte characters are being used.
178
(defcustom go-other-file-alist
179
'(("_test\\.go\\'" (".go"))
180
("\\.go\\'" ("_test.go")))
181
"See the documentation of `ff-other-file-alist' for details."
182
:type '(repeat (list regexp (choice (repeat string) function)))
170
185
(defface go-coverage-untracked
171
186
'((t (:foreground "#505050")))
172
187
"Coverage color of untracked code."
249
264
"Syntax table for Go mode.")
251
266
(defun go--build-font-lock-keywords ()
252
;; we cannot use 'symbols in regexp-opt because emacs <24 doesn't
267
;; we cannot use 'symbols in regexp-opt because GNU Emacs <24
268
;; doesn't understand that
255
270
`((,(go--regexp-enclose-in-symbol (regexp-opt go-mode-keywords t)) . font-lock-keyword-face)
256
(,(go--regexp-enclose-in-symbol (regexp-opt go-builtins t)) . font-lock-builtin-face)
271
(,(concat "\\(" (go--regexp-enclose-in-symbol (regexp-opt go-builtins t)) "\\)[[:space:]]*(") 1 font-lock-builtin-face)
257
272
(,(go--regexp-enclose-in-symbol (regexp-opt go-constants t)) . font-lock-constant-face)
258
273
(,go-func-regexp 1 font-lock-function-name-face)) ;; function (not method) name
260
275
(if go-fontify-function-calls
261
276
`((,(concat "\\(" go-identifier-regexp "\\)[[:space:]]*(") 1 font-lock-function-name-face) ;; function call/method name
262
277
(,(concat "[^[:word:][:multibyte:]](\\(" go-identifier-regexp "\\))[[:space:]]*(") 1 font-lock-function-name-face)) ;; bracketed function call
263
`((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
278
`((,go-func-meth-regexp 2 font-lock-function-name-face))) ;; method name
266
(,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]*\\([^[:space:]]+\\)") 1 font-lock-type-face) ;; types
267
(,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]*" go-identifier-regexp "[[:space:]]*" go-type-name-regexp) 1 font-lock-type-face) ;; types
281
("\\(`[^`]*`\\)" 1 font-lock-multiline) ;; raw string literal, needed for font-lock-syntactic-keywords
282
(,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]+\\([^[:space:]]+\\)") 1 font-lock-type-face) ;; types
283
(,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]+" go-identifier-regexp "[[:space:]]*" go-type-name-regexp) 1 font-lock-type-face) ;; types
268
284
(,(concat "[^[:word:][:multibyte:]]\\[\\([[:digit:]]+\\|\\.\\.\\.\\)?\\]" go-type-name-regexp) 2 font-lock-type-face) ;; Arrays/slices
269
285
(,(concat "\\(" go-identifier-regexp "\\)" "{") 1 font-lock-type-face)
270
286
(,(concat (go--regexp-enclose-in-symbol "map") "\\[[^]]+\\]" go-type-name-regexp) 1 font-lock-type-face) ;; map value type
281
297
(,(concat "^[[:space:]]*\\(" go-label-regexp "\\)[[:space:]]*:\\(\\S.\\|$\\)") 1 font-lock-constant-face) ;; Labels and compound literal fields
282
298
(,(concat (go--regexp-enclose-in-symbol "\\(goto\\|break\\|continue\\)") "[[:space:]]*\\(" go-label-regexp "\\)") 2 font-lock-constant-face)))) ;; labels in goto/break/continue
300
(defconst go--font-lock-syntactic-keywords
301
;; Override syntax property of raw string literal contents, so that
302
;; backslashes have no special meaning in ``. Used in Emacs 23 or older.
303
'((go--match-raw-string-literal
305
(2 (15 . nil)) ;; 15 = "generic string"
284
308
(defvar go-mode-map
285
309
(let ((m (make-sparse-keymap)))
286
310
(define-key m "}" #'go-mode-insert-and-indent)
376
(defun go--match-raw-string-literal (end)
377
"Search for a raw string literal. Set point to the end of the
378
occurence found on success. Returns nil on failure."
379
(when (search-forward "`" end t)
380
(goto-char (match-beginning 0))
381
(if (go-in-string-or-comment-p)
382
(progn (goto-char (match-end 0))
383
(go--match-raw-string-literal end))
384
(when (looking-at "\\(`\\)\\([^`]*\\)\\(`\\)")
385
(goto-char (match-end 0))
352
388
(defun go-previous-line-has-dangling-op-p ()
353
389
"Returns non-nil if the current line is a continuation line."
354
390
(let* ((cur-line (line-number-at-pos))
450
486
(goto-char (- (point-max) pos))))))
452
488
(defun go-beginning-of-defun (&optional count)
453
(unless count (setq count 1))
454
(let ((first t) failure)
489
(setq count (or count 1))
455
492
(dotimes (i (abs count))
456
493
(while (and (not failure)
457
494
(or first (go-in-string-or-comment-p)))
513
550
If you want to automatically run `gofmt' before saving a file,
514
551
add the following hook to your emacs configuration:
516
\(add-hook 'before-save-hook 'gofmt-before-save)
553
\(add-hook 'before-save-hook #'gofmt-before-save)
518
555
If you want to use `godef-jump' instead of etags (or similar),
519
556
consider binding godef-jump to `M-.', which is the default key
532
569
on-the-fly syntax checking, auto-completion and snippets, it is
533
570
recommended that you look at goflymake
534
571
\(https://github.com/dougm/goflymake), gocode
535
\(https://github.com/nsf/gocode) and yasnippet-go
572
\(https://github.com/nsf/gocode), go-eldoc
573
\(github.com/syohex/emacs-go-eldoc) and yasnippet-go
536
574
\(https://github.com/dominikh/yasnippet-go)"
554
592
(set (make-local-variable 'parse-sexp-lookup-properties) t)
555
593
(if (boundp 'syntax-propertize-function)
556
(set (make-local-variable 'syntax-propertize-function) #'go-propertize-syntax))
594
(set (make-local-variable 'syntax-propertize-function) #'go-propertize-syntax)
595
(set (make-local-variable 'font-lock-syntactic-keywords)
596
go--font-lock-syntactic-keywords)
597
(set (make-local-variable 'font-lock-multiline) t))
558
599
(set (make-local-variable 'go-dangling-cache) (make-hash-table :test 'eql))
559
600
(add-hook 'before-change-functions (lambda (x y) (setq go-dangling-cache (make-hash-table :test 'eql))) t t)
602
;; ff-find-other-file
603
(setq ff-other-file-alist 'go-other-file-alist)
562
605
(setq imenu-generic-expression
563
606
'(("type" "^type *\\([^ \t\n\r\f]*\\)" 1)
993
1036
(file-truename (buffer-file-name (go--coverage-origin-buffer)))
995
(number-to-string (go--position-bytes (point))))
1038
(number-to-string (go--position-bytes point)))
996
1039
(with-current-buffer outbuf
997
1040
(split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")))))
1108
1151
(start-line start-column end-line end-column num count)
1109
1152
(mapcar #'string-to-number rest)
1111
(when (and (string= (file-name-nondirectory file) file-name))
1154
(when (string= (file-name-nondirectory file) file-name)
1112
1155
(if (> count max-count)
1113
1156
(setq max-count count))
1114
1157
(push (make-go--covered :start-line start-line