-
Notifications
You must be signed in to change notification settings - Fork 1
/
auto-complete-golang.el
140 lines (112 loc) · 4.46 KB
/
auto-complete-golang.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
;;; -*- coding: utf-8; mode: emacs-lisp; -*-
;;; auto-complete-golang.el -- auto-complete.el source for golang.
;; Copyright (C) 2012 tabi
;; Author: tabi <[email protected]>
;; Keywords: autocomplete, golang
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Auto Completion source for golang. need gocode.
;;; Requirement:
;; * yasnippet.el
;;; Installation:
;; drop requirements and this file into a directory in your `load-path',
;; and put these lines into your .emacs file.
;; (require 'auto-complete-golang)
;; (add-hook 'go-mode-hook '(lambda ()
;; (add-to-list 'ac-sources 'ac-source-golang)))
(require 'auto-complete)
(defcustom ac-golang-gocode
(executable-find "gocode")
"*Location of gocode executable"
:group 'auto-complete
:type 'file)
(defcustom ac-golang-gocode-flags
nil
"*gocode extra flags"
:group 'auto-complete)
(defvar ac-golang-debug t)
(defun ac-golang-log (m)
(if (not ac-golang-debug)
m
(message "[log]%s" m)
m))
(defface ac-golang-candidate-face
'((t (:background "SteelBlue4" :foreground "white")))
"Face for clang candidate"
:group 'auto-complete)
(defface ac-golang-selection-face
'((t (:background "black" :foreground "white")))
"Face for the clang selected candidate."
:group 'auto-complete)
(defun ac-golang-build-complete-args (pos)
(append '("-f=emacs" "autocomplete")
ac-golang-gocode-flags
(list (int-to-string pos))))
(defconst ac-golang-candidate-pattern
"^\\([^\s\n,]*\\),,\\(.*$\\)")
(defun ac-golang-parse-output ()
(goto-char (point-min))
(let (lst name summary)
(while (re-search-forward ac-golang-candidate-pattern nil t)
(setq name (match-string-no-properties 1))
(setq summary (match-string-no-properties 2))
(ac-golang-log (format "name:%s summary:%s" name summary))
(push (propertize name 'summary summary) lst))
(reverse lst)))
(defun ac-golang-invoke-complete (args)
(if (not ac-golang-gocode)
(message "gocode cannot find! please install.")
(ac-golang-log (format "execute %s %s" ac-golang-gocode args))
(let ((buf (get-buffer-create "*gocode-output*"))
res)
(with-current-buffer buf (erase-buffer))
(setq res
(apply 'call-process-region (point-min) (point-max) ac-golang-gocode nil buf nil args))
(with-current-buffer buf
(if (not (eq 0 res))
(message "gocode failed with error %d: %s" res args) ;; handle error
(ac-golang-log (format "%s" (buffer-string)))
(ac-golang-log (ac-golang-parse-output))
)))))
(defun ac-golang-candidate ()
(ac-golang-log "start get candidates..")
(save-restriction
(widen)
(ac-golang-invoke-complete
(ac-golang-build-complete-args (- (point) (length ac-prefix))))))
(defun ac-golang-action ()
(let* ((sel (cdr ac-last-completion))
(summary (get-text-property 0 'summary sel)))
(ac-golang-log (format "selected summary : %s" summary))
(cond ((featurep 'yasnippet)
(when (string-match "^func(\\([^(]+\\))" summary)
(let ((arg (match-string 1 summary))
(snp ""))
(setq snp
(mapconcat (lambda (s)
(concat "${" (replace-regexp-in-string "\\(^[ \t\n\r]+\\|[ \t\n\r]+$\\)" "" s) "}"))
(split-string arg",")
", "))
(ac-golang-log (format "arg: %s snp: %s" arg snp))
(yas/expand-snippet (concat "(" snp ")")))))
(t
(message "yasnippet not installed!!")))))
(ac-define-source golang
'((candidates . ac-golang-candidate)
(candidate-face . ac-golang-candidate-face)
(selection-face . ac-golang-selection-face)
(requires . 2)
(action . ac-golang-action)
(cache)
(symbol . "g")
))
(provide 'auto-complete-golang)