spacemacs/layers/+lang/ensime/funcs.el
2017-03-19 12:40:36 -04:00

127 lines
4.2 KiB
EmacsLisp

;;; funcs.el --- Ensime Layer functions File for Spacemacs
;;
;; Copyright (c) 2012-2017 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3
;;; Ensime
(autoload 'ensime-config-find-file "ensime-config")
(autoload 'ensime-config-find "ensime-config")
(autoload 'projectile-project-p "projectile")
(defun ensime/init (mode &optional enable-eldoc auto-start)
(let ((hook (intern (format "%S-hook" mode)))
(jump-handlers (intern (format "spacemacs-jump-handlers-%S" mode))))
(spacemacs/register-repl 'ensime 'ensime-inf-switch "ensime")
(when enable-eldoc
(add-hook 'ensime-mode-hook 'ensime/enable-eldoc))
(add-hook hook 'ensime/configure-flyspell)
(add-hook hook 'ensime/configure)
(when auto-start
(add-hook mode 'ensime/maybe-start))
(add-to-list jump-handlers 'ensime-edit-definition)))
(defun ensime/configure ()
"Ensure the file exists before starting `ensime-mode'."
(cond
((and (buffer-file-name) (file-exists-p (buffer-file-name)))
(ensime-mode +1))
((buffer-file-name)
(add-hook 'after-save-hook (lambda () (ensime-mode +1)) nil t))))
(defun ensime/maybe-start ()
(when (buffer-file-name)
(let ((ensime-buffer (ensime/buffer-for-file (buffer-file-name)))
(file (ensime-config-find-file (buffer-file-name)))
(is-source-file (s-matches? (rx (or "/src/" "/test/")) (buffer-file-name))))
(when (and is-source-file (null ensime-buffer))
(noflet ((ensime-config-find (&rest _) file))
(save-window-excursion
(ensime)))))))
(defun ensime/buffer-for-file (file)
"Find the Ensime server buffer corresponding to FILE."
(let ((default-directory (file-name-directory file)))
(-when-let (project-name (projectile-project-p))
(--first (-when-let (bufname (buffer-name it))
(and (s-contains? "inferior-ensime-server" bufname)
(s-contains? (file-name-nondirectory project-name) bufname)))
(buffer-list)))))
(defun ensime/enable-eldoc ()
(setq-local eldoc-documentation-function
(lambda ()
(when (ensime-connected-p)
(ensime-print-type-at-point))))
(eldoc-mode +1))
(defun spacemacs/ensime-refactor-accept ()
(interactive)
(funcall continue-refactor)
(ensime-popup-buffer-quit-function))
(defun spacemacs/ensime-refactor-cancel ()
(interactive)
(funcall cancel-refactor)
(ensime-popup-buffer-quit-function))
;;; Interactive commands
(defun spacemacs/scala-join-line ()
"Adapt `scala-indent:join-line' to behave more like evil's line join.
`scala-indent:join-line' acts like the vanilla `join-line',
joining the current line with the previous one. The vimmy way is
to join the current line with the next.
Try to move to the subsequent line and then join. Then manually move
point to the position of the join."
(interactive)
(let (join-pos)
(save-excursion
(goto-char (line-end-position))
(unless (eobp)
(forward-line)
(call-interactively 'scala-indent:join-line)
(setq join-pos (point))))
(when join-pos
(goto-char join-pos))))
(defun ensime/completing-dot ()
"Insert a period and show company completions."
(interactive "*")
(when (s-matches? (rx (+ (not space)))
(buffer-substring (line-beginning-position) (point)))
(delete-horizontal-space t))
(company-abort)
(insert ".")
(company-complete))
;;; Flyspell
(defun ensime/flyspell-verify ()
"Prevent common flyspell false positives in scala-mode."
(and (flyspell-generic-progmode-verify)
(not (s-matches? (rx bol (* space) "package") (current-line)))))
(defun ensime/configure-flyspell ()
(setq-local flyspell-generic-check-word-predicate 'ensime/flyspell-verify))
(defun ensime/yank-type-at-point ()
"Yank to kill ring and print short type name at point to the minibuffer."
(interactive)
(ensime-type-at-point t nil))
(defun ensime/yank-type-at-point-full-name ()
"Yank to kill ring and print full type name at point to the minibuffer."
(interactive)
(ensime-type-at-point t t))