Merge pull request #156 from snosov1/fork-dub-imports
Add ac-dcd-add-imports function
This commit is contained in:
commit
ae46655c54
|
@ -1,47 +1,59 @@
|
|||
#Emacs Integration
|
||||
# Emacs Integration
|
||||
|
||||
##Requirements
|
||||
* You must have the [auto-complete](https://github.com/auto-complete/auto-complete) package.
|
||||
And, [yasnippet](https://github.com/capitaomorte/yasnippet) and [popwin](https://github.com/m2ym/popwin-el) 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```.
|
||||
## Requirements
|
||||
|
||||
* You must have the
|
||||
[auto-complete](https://github.com/auto-complete/auto-complete) package. Also,
|
||||
[yasnippet](https://github.com/capitaomorte/yasnippet) and
|
||||
[popwin](https://github.com/m2ym/popwin-el) are recommended.
|
||||
* Make sure `dcd-client` and `dcd-server` are in your exec-path. Otherwise,
|
||||
please set the variables `dcd-exectutable` and `dcd-server-executable` using
|
||||
`M-x customize`.
|
||||
|
||||
## Setup
|
||||
* 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. (Of course, you should edit ```path_to_ac-dcd.el``` to suit your enviroment.)
|
||||
|
||||
```
|
||||
;;; ac-dcd
|
||||
(add-to-list 'load-path "path_to_ac-dcd.el")
|
||||
(require 'ac-dcd)
|
||||
* Follow the Setup section in the root README.
|
||||
* Add the following to your .emacs. With this setting, dcd-server starts
|
||||
automatically when you open file in d-mode. (Of course, you should edit
|
||||
`path_to_ac-dcd.el` to suit your environment.)
|
||||
|
||||
(add-hook 'd-mode-hook
|
||||
'(lambda () "set up ac-dcd"
|
||||
(auto-complete-mode t)
|
||||
(yas-minor-mode-on)
|
||||
(ac-dcd-maybe-start-server)
|
||||
(add-to-list 'ac-sources 'ac-source-dcd)))
|
||||
;;; ac-dcd
|
||||
(add-to-list 'load-path "path_to_ac-dcd.el")
|
||||
(require 'ac-dcd)
|
||||
|
||||
(define-key d-mode-map (kbd "C-c ?") 'ac-dcd-show-ddoc-with-buffer)
|
||||
(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)
|
||||
(add-hook 'd-mode-hook
|
||||
'(lambda () "set up ac-dcd"
|
||||
(auto-complete-mode t)
|
||||
(yas-minor-mode-on)
|
||||
(ac-dcd-maybe-start-server)
|
||||
(add-to-list 'ac-sources 'ac-source-dcd)))
|
||||
|
||||
(when (featurep 'popwin)
|
||||
(add-to-list 'popwin:special-display-config
|
||||
`(,ac-dcd-error-buffer-name :noselect t))
|
||||
(add-to-list 'popwin:special-display-config
|
||||
`(,ac-dcd-document-buffer-name :position right :width 80)))
|
||||
(define-key d-mode-map (kbd "C-c ?") 'ac-dcd-show-ddoc-with-buffer)
|
||||
(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)
|
||||
|
||||
```
|
||||
(when (featurep 'popwin)
|
||||
(add-to-list 'popwin:special-display-config
|
||||
`(,ac-dcd-error-buffer-name :noselect t))
|
||||
(add-to-list 'popwin:special-display-config
|
||||
`(,ac-dcd-document-buffer-name :position right :width 80)))
|
||||
|
||||
* 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```.
|
||||
* You can set import paths using `M-x customize-variable RET ac-dcd-flags`.
|
||||
* Alternatively, if you're using [DUB](http://code.dlang.org/) to manage your
|
||||
project, you can use `M-x ac-dcd-add-imports` to add import paths of the
|
||||
current project automatically.
|
||||
* 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 ,```
|
||||
* Show ddoc with `C-c ?`
|
||||
* Goto definition with `C-c .`
|
||||
* After goto definition, you can pop to previous position with `C-c ,`
|
||||
|
||||
## TODO
|
||||
* Multi byte character support (Need help!)
|
||||
|
||||
* UTF-8 support is in place. However, UTF-16 and UTF-32 may not work correctly.
|
||||
(Need help!)
|
||||
|
|
|
@ -527,6 +527,86 @@ output is just like following.\n
|
|||
(cons nil nil)))
|
||||
))
|
||||
|
||||
(defun ac-dcd-parent-directory (dir)
|
||||
"Returns parent directory of dir"
|
||||
(when dir
|
||||
(file-name-directory (directory-file-name (expand-file-name dir)))))
|
||||
|
||||
(defun ac-dcd-search-file-up (name &optional path)
|
||||
"Searches for file `name' in parent directories recursively"
|
||||
(let* ((tags-file-name (concat path name))
|
||||
(parent (ac-dcd-parent-directory path))
|
||||
(path (or path default-directory))
|
||||
)
|
||||
(cond
|
||||
((file-exists-p tags-file-name) tags-file-name)
|
||||
((string= parent path) nil)
|
||||
(t (ac-dcd-search-file-up name parent)))))
|
||||
|
||||
(defun ac-dcd-find-imports-dub ()
|
||||
"Extract import flags from \"dub describe\" output."
|
||||
(let ((dub-root-dir (ac-dcd-parent-directory
|
||||
(or (ac-dcd-search-file-up "dub.json" default-directory)
|
||||
(ac-dcd-search-file-up "package.json" default-directory))))
|
||||
(dub-executable "dub"))
|
||||
|
||||
(when dub-root-dir
|
||||
(with-temp-buffer
|
||||
(let ((default-directory dub-root-dir))
|
||||
(call-process dub-executable nil (current-buffer) nil "describe"))
|
||||
(require 'json)
|
||||
(let* ((json-object-type 'hash-table)
|
||||
(describe-hash (json-read-from-string (buffer-string)))
|
||||
(packages-array (gethash "packages" describe-hash))
|
||||
(imports-list '()))
|
||||
(mapcar
|
||||
(lambda (package)
|
||||
(let ((package-path (gethash "path" package))
|
||||
(import-paths-array (gethash "importPaths" package)))
|
||||
(mapcar
|
||||
(lambda (import-path)
|
||||
(add-to-list 'imports-list
|
||||
(concat "-I" package-path import-path)))
|
||||
import-paths-array)))
|
||||
packages-array)
|
||||
imports-list)))))
|
||||
|
||||
(defun ac-dcd-find-imports-std ()
|
||||
"Extract import flags from dmd.conf file."
|
||||
(require 'cl)
|
||||
(let ((dmd-conf-filename
|
||||
(find-if 'file-exists-p
|
||||
(list
|
||||
;; TODO: the first directory to look into should be dmd's current
|
||||
;; working dir
|
||||
(concat (getenv "HOME") "/dmd.conf")
|
||||
(concat (ac-dcd-parent-directory (executable-find "dmd")) "dmd.conf")
|
||||
"/etc/dmd.conf"))))
|
||||
|
||||
;; TODO: this extracting procedure is pretty rough, it just searches for
|
||||
;; the first occurrence of the DFLAGS
|
||||
(save-window-excursion
|
||||
(with-temp-buffer
|
||||
(find-file dmd-conf-filename)
|
||||
(goto-char (point-min))
|
||||
(search-forward "\nDFLAGS")
|
||||
(skip-chars-forward " =")
|
||||
(let ((flags-list (split-string (buffer-substring-no-properties
|
||||
(point) (line-end-position)))))
|
||||
(remove-if-not '(lambda (s)
|
||||
(string-prefix-p "-I" s))
|
||||
flags-list))))))
|
||||
|
||||
(defun ac-dcd-add-imports ()
|
||||
"Send import flags of the current DUB project to dcd-server.
|
||||
|
||||
The root of the project is determined by the \"closest\" dub.json
|
||||
or package.json file."
|
||||
(interactive)
|
||||
(ac-dcd-call-process ""
|
||||
(append
|
||||
(ac-dcd-find-imports-std)
|
||||
(ac-dcd-find-imports-dub))))
|
||||
|
||||
(provide 'ac-dcd)
|
||||
;;; ac-dcd.el ends here
|
||||
|
|
Loading…
Reference in New Issue