Skip to content

Commit 17a87f1

Browse files
committed
Given a prefix, let the user choose which import to use.
This also simplifies the import before sorting, so we use the correct import in more cases.
1 parent 2e8657e commit 17a87f1

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

pyimport.el

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,21 @@ To terminate the loop early, throw 'break."
100100
(insert line "\n")))))
101101

102102
(defun pyimport--import-simplify (line symbol)
103-
"Given LINE 'from foo import bar, baz', simplify it to 'from foo import baz', where
104-
baz is SYMBOL."
103+
"Given LINE 'from foo import bar, baz', and SYMBOL 'baz', simplify to
104+
'from foo import baz'.
105+
106+
Preserves pyimport text properties on LINE."
105107
;; TODO: simplify "from foo import bar, baz as biz" -> "from foo import baz as biz"
106-
(cond ((string-match "from .* import .* as .*" line)
107-
line)
108-
((s-starts-with-p "from " line)
109-
(let ((parts (s-split " " line)))
110-
(format "from %s import %s" (nth 1 parts) symbol)))
111-
(t
112-
line)))
108+
(let ((simplified
109+
(cond ((string-match "from .* import .* as .*" line)
110+
line)
111+
((s-starts-with-p "from " line)
112+
(let ((parts (s-split " " line)))
113+
(format "from %s import %s" (nth 1 parts) symbol)))
114+
(t
115+
line))))
116+
(propertize simplified 'pyimport-path
117+
(get-text-property 0 'pyimport-path line))))
113118

114119
(defun pyimport--buffers-in-mode (mode)
115120
"Return a list of all the buffers with major mode MODE."
@@ -118,10 +123,12 @@ baz is SYMBOL."
118123
(buffer-list)))
119124

120125
;;;###autoload
121-
(defun pyimport-insert-missing ()
126+
(defun pyimport-insert-missing (prefix)
122127
"Try to insert an import for the symbol at point.
123-
Dumb: just scans open Python buffers."
124-
(interactive)
128+
If called with a prefix, choose which import to use.
129+
130+
This is a simple heuristic: we just look for imports in all open Python buffers."
131+
(interactive "p")
125132
(let ((symbol (thing-at-point 'symbol))
126133
(matching-lines nil)
127134
(case-fold-search nil))
@@ -135,15 +142,21 @@ Dumb: just scans open Python buffers."
135142
(when (string-match (rx-to-string `(seq symbol-start ,symbol symbol-end)) line)
136143
(push line matching-lines))))
137144

145+
;; Simplify imports so we don't show irrelevant symbols.
146+
(setq matching-lines
147+
(--map (pyimport--import-simplify it symbol) matching-lines))
148+
138149
;; Sort by string length, because the shortest string is usually best.
139150
(setq matching-lines
140151
(--sort (< (length it) (length other)) matching-lines))
141152

142153
(if matching-lines
143-
(let* ((example-line (-first-item matching-lines))
144-
(line (pyimport--import-simplify example-line symbol)))
154+
(let ((line
155+
(if prefix
156+
(completing-read "Choose import: " matching-lines)
157+
(-first-item matching-lines))))
145158
(pyimport--insert-import line)
146-
(message "%s (from %s)" line (get-text-property 0 'pyimport-path example-line)))
159+
(message "%s (from %s)" line (get-text-property 0 'pyimport-path line)))
147160
(user-error "No matches found for %s" symbol))))
148161

149162
(defun pyimport--extract-unused-var (flycheck-message)

0 commit comments

Comments
 (0)