Merge pull request #142 from tsukimizake/master
Update emacs integration, and some bug fix
This commit is contained in:
commit
6be4bfba95
|
@ -1,31 +1,40 @@
|
||||||
#Emacs Integration
|
#Emacs Integration
|
||||||
|
|
||||||
##Requirements
|
##Requirements
|
||||||
* You must have the [auto-complete](https://github.com/auto-complete/auto-complete) package, and [yasnippet](https://github.com/capitaomorte/yasnippet) package is recommended.
|
* You must have the [auto-complete](https://github.com/auto-complete/auto-complete) package.
|
||||||
|
And [yasnippet](https://github.com/capitaomorte/yasnippet) package is recommended.
|
||||||
* Make sure dcd-client and dcd-server is in your exec-path. Otherwise, please set the variable ```dcd-exectutable``` and ```dcd-server-executable``` using ```M-x customize```.
|
* Make sure dcd-client and dcd-server is in your exec-path. Otherwise, please set the variable ```dcd-exectutable``` and ```dcd-server-executable``` using ```M-x customize```.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
* First, follow the Setup section in the root README.
|
* First, follow the Setup section in the root README.
|
||||||
* Second, add the following to your .emacs. With this setting, dcd-server starts automatically when you open file in d-mode.
|
* Second, add the following to your .emacs. With this setting, dcd-server starts automatically when you open file in d-mode.
|
||||||
|
|
||||||
```
|
```
|
||||||
;;; ac-dcd
|
;;; ac-dcd
|
||||||
(add-to-list 'load-path "path_to_ac-dcd.el")
|
(add-to-list 'load-path "path_to_ac-dcd.el")
|
||||||
(require 'ac-dcd)
|
(require 'ac-dcd)
|
||||||
(add-to-list 'ac-modes 'd-mode)
|
(add-to-list 'ac-modes 'd-mode)
|
||||||
(defun ac-d-mode-setup ()
|
|
||||||
(ac-dcd-maybe-start-server)
|
|
||||||
(add-to-list 'ac-sources 'ac-source-dcd)
|
|
||||||
(auto-complete-mode t))
|
|
||||||
(add-hook 'd-mode-hook 'ac-d-mode-setup)
|
|
||||||
|
|
||||||
(define-key d-mode-map (kbd "C-c C-h") 'ac-dcd-popup-ddoc-at-point) ;of course, you can change this keybind.
|
(add-hook 'd-mode-hook
|
||||||
|
'(lambda () "set up ac-dcd"
|
||||||
|
(ac-dcd-maybe-start-server)
|
||||||
|
(add-to-list 'ac-sources 'ac-source-dcd)))
|
||||||
|
|
||||||
|
(define-key d-mode-map (kbd "C-c ?") 'ac-dcd-popup-ddoc-at-point)
|
||||||
|
(define-key d-mode-map (kbd "C-c .") 'ac-dcd-goto-definition)
|
||||||
|
(define-key d-mode-map (kbd "C-c ,") 'ac-dcd-goto-def-pop-marker)
|
||||||
```
|
```
|
||||||
|
|
||||||
* Third, set import path using ```M-x customize-variable RET ac-dcd-flags```.
|
* Third, set import path using ```M-x customize-variable RET ac-dcd-flags```.
|
||||||
* When something is wrong, please check variables with ```M-x customize-apropos RET ac-dcd``` and restart server with ```M-x ac-dcd-init-server```.
|
* When something is wrong, please check variables with ```M-x customize-apropos RET ac-dcd``` and restart server with ```M-x ac-dcd-init-server```.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
* Dlang source for auto-complete
|
||||||
|
* Function calltip expansion with yasnippet
|
||||||
|
* Show ddoc with ```C-c ?```
|
||||||
|
* Goto definition with ```C-c .```
|
||||||
|
* After goto definition, you can pop to previous position with ```C-c ,```
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
* goto definition
|
* Better error handling
|
||||||
* Multi byte character support (Need help!)
|
* Multi byte character support (Need help!)
|
||||||
* and so on...
|
|
||||||
|
|
|
@ -274,9 +274,9 @@ When the symbol is not a function, returns nothing"
|
||||||
\\1 is function return type (if exists) and name, and \\2 is args.")
|
\\1 is function return type (if exists) and name, and \\2 is args.")
|
||||||
|
|
||||||
(defsubst ac-dcd-remove-function-return-type (s)
|
(defsubst ac-dcd-remove-function-return-type (s)
|
||||||
"Remove return type of function."
|
"Remove return type of the function."
|
||||||
(let ((sl (split-string s)))
|
(let ((sl (split-string s)))
|
||||||
(if (string-match "(" (car sl)) ; filter calltip candidate which has no return type. e.g. std.regex.match
|
(if (string-match "(" (car sl)) ;
|
||||||
s
|
s
|
||||||
(mapconcat 'identity (cdr sl) " ")
|
(mapconcat 'identity (cdr sl) " ")
|
||||||
)))
|
)))
|
||||||
|
@ -312,7 +312,7 @@ This function should be called at *dcd-output* buf."
|
||||||
yasstr)
|
yasstr)
|
||||||
(setq kill-ring (cdr kill-ring)); clean up kill-ring
|
(setq kill-ring (cdr kill-ring)); clean up kill-ring
|
||||||
|
|
||||||
;remove parenthesis
|
;;remove parenthesis
|
||||||
(setq str (substring str 1 (- (length str) 1)))
|
(setq str (substring str 1 (- (length str) 1)))
|
||||||
|
|
||||||
(setq yasstr
|
(setq yasstr
|
||||||
|
@ -342,6 +342,7 @@ This function should be called at *dcd-output* buf."
|
||||||
(defun ac-dcd-get-ddoc (pos)
|
(defun ac-dcd-get-ddoc (pos)
|
||||||
"Get document with `dcd-client --doc'. `POS' is cursor position.
|
"Get document with `dcd-client --doc'. `POS' is cursor position.
|
||||||
TODO:reformat it."
|
TODO:reformat it."
|
||||||
|
(save-buffer)
|
||||||
(let ((args
|
(let ((args
|
||||||
(append
|
(append
|
||||||
(ac-dcd-build-complete-args (ac-dcd-cursor-position))
|
(ac-dcd-build-complete-args (ac-dcd-cursor-position))
|
||||||
|
@ -370,9 +371,88 @@ TODO:reformat it."
|
||||||
(when (or(string= doc "")
|
(when (or(string= doc "")
|
||||||
(string= doc "\n\n\n") ;when symbol has no doc
|
(string= doc "\n\n\n") ;when symbol has no doc
|
||||||
)
|
)
|
||||||
(message "No document for the symbol at point!"))))
|
(message "No document for the symbol at point!"))
|
||||||
|
(popup-tip doc)))
|
||||||
|
|
||||||
|
|
||||||
|
;; goto definition
|
||||||
|
;; thanks to jedi.el by Takafumi Arakaki
|
||||||
|
|
||||||
|
(defcustom ac-dcd-goto-definition-marker-ring-length 16
|
||||||
|
"Length of marker ring to store `ac-dcd-goto-definition' call positions."
|
||||||
|
:group 'auto-complete)
|
||||||
|
|
||||||
|
(defvar ac-dcd-goto-definition-marker-ring
|
||||||
|
(make-ring ac-dcd-goto-definition-marker-ring-length)
|
||||||
|
"Ring that stores ac-dcd-goto-symbol-declaration.")
|
||||||
|
|
||||||
|
(defsubst ac-dcd-goto-def-push-marker ()
|
||||||
|
"Push marker at point to goto-def ring."
|
||||||
|
(ring-insert ac-dcd-goto-definition-marker-ring (point-marker)))
|
||||||
|
|
||||||
|
(defun ac-dcd-goto-def-pop-marker ()
|
||||||
|
"Goto the point where `ac-dcd-goto-definition' was last called."
|
||||||
|
(interactive)
|
||||||
|
(if (ring-empty-p ac-dcd-goto-definition-marker-ring)
|
||||||
|
(error "Marker ring is empty. Can't pop.")
|
||||||
|
(let ((marker (ring-remove ac-dcd-goto-definition-marker-ring 0)))
|
||||||
|
(switch-to-buffer (or (marker-buffer marker)
|
||||||
|
(error "Buffer has been deleted")))
|
||||||
|
(goto-char (marker-position marker))
|
||||||
|
;; Cleanup the marker so as to avoid them piling up.
|
||||||
|
(set-marker marker nil nil))))
|
||||||
|
|
||||||
|
(defun ac-dcd-goto-definition ()
|
||||||
|
"Goto declaration of symbol at point."
|
||||||
|
(interactive)
|
||||||
|
(save-buffer)
|
||||||
|
(ac-dcd-call-process-for-symbol-declaration (point))
|
||||||
|
(let* ((data (ac-dcd-parse-output-for-get-symbol-declaration))
|
||||||
|
(file (car data))
|
||||||
|
(offset (cdr data)))
|
||||||
|
(if (equal data '(nil . nil))
|
||||||
|
(message "Not found")
|
||||||
|
(progn
|
||||||
|
(ac-dcd-goto-def-push-marker)
|
||||||
|
(if (string= file "stdin") ; When the declaration is in the current file
|
||||||
|
(progn
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-char (string-to-number offset)))
|
||||||
|
(progn
|
||||||
|
(find-file file)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-char (string-to-number offset))))))))
|
||||||
|
|
||||||
|
;; utilities for goto-definition
|
||||||
|
|
||||||
|
(defun ac-dcd-call-process-for-symbol-declaration (pos)
|
||||||
|
"Get location of symbol declaration with `dcd-client --symbolLocation'.
|
||||||
|
`POS' is cursor position."
|
||||||
|
(let ((args
|
||||||
|
(append
|
||||||
|
(ac-dcd-build-complete-args (ac-dcd-cursor-position))
|
||||||
|
'("--symbolLocation")
|
||||||
|
(list (buffer-file-name))))
|
||||||
|
(buf (get-buffer-create "*dcd-output*")))
|
||||||
|
(with-current-buffer
|
||||||
|
buf (erase-buffer)
|
||||||
|
(apply 'call-process ac-dcd-executable nil buf nil args))
|
||||||
|
(let ((output (with-current-buffer buf (buffer-string))))
|
||||||
|
output)))
|
||||||
|
|
||||||
|
(defun ac-dcd-parse-output-for-get-symbol-declaration ()
|
||||||
|
"Parse output of `ac-dcd-get-symbol-declaration'.
|
||||||
|
output is just like following.\n
|
||||||
|
`(cons \"PATH_TO_IMPORT/import/std/stdio.d\" \"63946\")'"
|
||||||
|
(let ((buf (get-buffer-create "*dcd-output*")))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (not (string= "Not found\n" (buffer-string)))
|
||||||
|
(progn (re-search-forward (rx (submatch (* nonl)) "\t" (submatch (* nonl)) "\n"))
|
||||||
|
(cons (match-string 1) (match-string 2)))
|
||||||
|
(cons nil nil)))
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
(provide 'ac-dcd)
|
(provide 'ac-dcd)
|
||||||
;;; ac-dcd.el ends here
|
;;; ac-dcd.el ends here
|
||||||
|
|
Loading…
Reference in New Issue