diff --git a/Cask b/Cask index 41f913f8d..4665106ea 100644 --- a/Cask +++ b/Cask @@ -69,6 +69,7 @@ (depends-on "yaml-mode") (depends-on "markdown-mode") (depends-on "glsl-mode") +(depends-on "go-mode" :git "https://github.com/dominikh/go-mode.el") (depends-on "tern") (depends-on "tern-auto-complete") diff --git a/elisp/go-autocomplete.el b/elisp/go-autocomplete.el new file mode 100644 index 000000000..9ff104a0b --- /dev/null +++ b/elisp/go-autocomplete.el @@ -0,0 +1,151 @@ +;;; go-autocomplete.el --- auto-complete-mode backend for go-mode + +;; Copyright (C) 2010 + +;; Author: Mikhail Kuryshev +;; Keywords: languages +;; Package-Requires: ((auto-complete "1.4.0")) + +;; 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 . + +;;; Commentary: + +;; Ensure that go-autocomplete in your load-path and add to your ~/.emacs +;; following line: +;; +;; (require 'go-autocomplete) + +;; Also you could setup any combination (for example M-TAB) +;; for invoking auto-complete: +;; +;; (require 'auto-complete-config) +;; (define-key ac-mode-map (kbd "M-TAB") 'auto-complete) + +;;; Code: + +(eval-when-compile + (require 'cl) + (require 'auto-complete)) + +;; Close gocode daemon at exit unless it was already running +(eval-after-load "go-mode" + '(progn + (let* ((user (or (getenv "USER") "all")) + (sock (format (concat temporary-file-directory "gocode-daemon.%s") user))) + (unless (file-exists-p sock) + (add-hook 'kill-emacs-hook #'(lambda () + (ignore-errors + (call-process "gocode" nil nil nil "close")))))))) + +;(defvar go-reserved-keywords +; '("break" "case" "chan" "const" "continue" "default" "defer" "else" +; "fallthrough" "for" "func" "go" "goto" "if" "import" "interface" +; "map" "package" "range" "return" "select" "struct" "switch" "type" "var") +; "Go reserved keywords.") + +(defun ac-comphist-sort (db collection prefix &optional threshold) +;; redefine to disable sorting + (let (result + (n 0) + (total 0) + (cur 0)) + (setq result (mapcar (lambda (a) + (when (and cur threshold) + (if (>= cur (* total threshold)) + (setq cur nil) + (incf n) + (incf cur (cdr a)))) + (car a)) + (mapcar (lambda (string) + (let ((score (ac-comphist-score db string prefix))) + (incf total score) + (cons string score))) + collection))) + (if threshold + (cons n result) + result))) + +(defun ac-go-invoke-autocomplete () + (let ((temp-buffer (generate-new-buffer "*gocode*"))) + (unwind-protect + (progn + (call-process-region (point-min) + (point-max) + "gocode" + nil + temp-buffer + nil + "-f=emacs" + "autocomplete" + (or (buffer-file-name) "") + (concat "c" (int-to-string (- (point) 1)))) + (with-current-buffer temp-buffer (buffer-string))) + (kill-buffer temp-buffer)))) + +(defun ac-go-format-autocomplete (buffer-contents) + (sort + (split-string buffer-contents "\n" t) + (lambda (a b) (string< (downcase a) + (downcase b))))) + +(defun ac-go-get-candidates (strings) + (let ((prop (lambda (entry) + (let ((name (nth 0 entry)) + (summary (nth 1 entry))) + (propertize name + 'summary summary)))) + (split (lambda (strings) + (mapcar (lambda (str) + (split-string str ",," t)) + strings)))) + (mapcar prop (funcall split strings)))) + +(defun ac-go-action () + (let ((item (cdr ac-last-completion))) + (if (stringp item) + (message "%s" (get-text-property 0 'summary item))))) + +(defun ac-go-document (item) + (if (stringp item) + (let ((s (get-text-property 0 'summary item))) + (message "%s" s) + nil))) + +(defun ac-go-candidates () + (ac-go-get-candidates (ac-go-format-autocomplete (ac-go-invoke-autocomplete)))) + +(defun ac-go-prefix () + (or (ac-prefix-symbol) + (let ((c (char-before))) + (when (eq ?\. c) + (point))))) + +(ac-define-source go + '((candidates . ac-go-candidates) + (candidate-face . ac-candidate-face) + (selection-face . ac-selection-face) + (document . ac-go-document) + (action . ac-go-action) + (prefix . ac-go-prefix) + (requires . 0) + (cache) + (symbol . "g"))) + +(add-to-list 'ac-modes 'go-mode) + +(add-hook 'go-mode-hook #'(lambda () + (add-to-list 'ac-sources 'ac-source-go))) + +(provide 'go-autocomplete) +;;; go-autocomplete.el ends here diff --git a/init/mod-dev.el b/init/mod-dev.el index 450f66003..aa9671743 100644 --- a/init/mod-dev.el +++ b/init/mod-dev.el @@ -70,5 +70,11 @@ (my/setup-run-code ruby-mode-map "ruby") (nmap ruby-mode-map "gd" 'rsense-jump-to-definition))) +(use-package go-mode + :mode "\\.go\\'" + :interpreter "go" + :init + (require 'go-autocomplete)) + ;; (provide 'mod-dev)