-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscala-quick-import.el
95 lines (84 loc) · 4.15 KB
/
scala-quick-import.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
;;; scala-quick-import.el --- Support for importing types at point
;; Copyright (c) 2017 Josef Vlach
;; Homepage: https://github.com/VlachJosef/scala-quick-import
;; Package-Version: 0.1
;;; Commentary:
;;
;; TODO
;;
;;; Code:
(require 's)
(require 'ag)
(require 'ido)
(require 'ensime)
(require 'projectile)
(defun scala-quick-import:normalize-import (import)
(let* ((normalized (s-replace " " "" (s-collapse-whitespace (s-trim-left import))))
(prefix-and-class-list (s-split "{" normalized)))
(pcase prefix-and-class-list
(`(,n . nil) (cons import nil)) ;; return input as is
(`(,prefix ,m . nil)
(let* ((class-list (s-split "," (s-replace "}" "" m)))
(value))
(dolist (element class-list value)
(setq value (cons (concat prefix element) value)))))
(_ nil)))) ; input is broken, it is not valid scala import, let's return empty list
(defun scala-quick-import:normalize-and-sort (input search-term)
(let ((all-imports (apply #'append (mapcar 'scala-quick-import:normalize-import input))))
(sort (cl-remove-if-not (lambda (import) (string-match (format "\\.%s$" search-term) import)) all-imports) 'string<)))
(defun scala-quick-import:search-import (search-term)
"Use ag to search lines in project starting with keyword import and containing text `search-term'
By default all import clauses are normalized, meaning that any import including `import selector clause'
enclosed in braces is broken down into its own import clause.
Prefix arguments:
no arg - normalize
C-u - normalize and copy current import to kill ring
C-- - don't normalize
C-- C-u - don't normalize and copy current import to kill ring"
(interactive
(list (read-from-minibuffer
(projectile-prepend-project-name "Ag search for import: ")
(projectile-symbol-or-selection-at-point))))
(unless (and (executable-find "ag") (executable-find "sort") (executable-find "uniq"))
(error "Commands 'ag', 'sort' and 'uniq' are required to use this command"))
(scala-quick-import:search-import-body
search-term
(lambda ()
(shell-command-to-string (format "ag --nonumbers --noheading --nofilename --nobreak --ignore-case -- 'import.*%s' %s | sort | uniq" search-term (projectile-project-root))))))
(defun scala-quick-import:search-import-body (search-term-unescaped run-ag-fn)
(let ((search-term (replace-quote search-term-unescaped))
(identity2 (lambda (input search-term) input))
(normalization-function)
(copy-to-kill-ring))
(pcase current-prefix-arg
(`nil (setq normalization-function `scala-quick-import:normalize-and-sort)
(setq copy-to-kill-ring nil) `identity2)
(`- (setq normalization-function (lambda (input search-term) input))
(setq copy-to-kill-ring nil))
(`(,n . nil) (if (< 0 n)
(progn (setq normalization-function `scala-quick-import:normalize-and-sort)
(setq copy-to-kill-ring t))
(progn (setq normalization-function `identity2)
(setq copy-to-kill-ring t)))))
(let* ((res-raw (funcall run-ag-fn))
(lines (split-string (s-replace "import " "" (s-trim res-raw)) "\n"))
(import (let ((x (funcall normalization-function lines search-term)))
(pcase (delete-dups x)
(`nil nil)
(`(,n . nil) n)
(_ (ido-completing-read "Select an import: " x))))))
(if copy-to-kill-ring
(progn (kill-new (format "import %s" import))
(message "%s added to kill ring" import))
(if (eq nil import)
(message "No import found for %s" search-term)
(if (scala-quick-import:is-import-present search-term)
(message "Import %s already present in a current buffer." import)
(ensime-insert-import import)
(message "import %s inserted succesfully." import)))))))
(defun scala-quick-import:is-import-present (search-term)
(save-excursion
(goto-char (point-min))
(re-search-forward (format "^import .*[.{, ]%s[ ,}\r\n]" search-term) nil t 1)))
(provide 'scala-quick-import)
;;; scala-quick-import.el ends here