[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/haskell-tng-mode 599d4f0 283/385: import symbol at point
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/haskell-tng-mode 599d4f0 283/385: import symbol at point |
Date: |
Tue, 5 Oct 2021 23:59:49 -0400 (EDT) |
branch: elpa/haskell-tng-mode
commit 599d4f0e9d1dbae34d58a7ea6d966cf796c3ea1e
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>
import symbol at point
---
README.md | 2 +-
haskell-tng-extra.el | 12 +++++++++--
haskell-tng-hsinspect.el | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
haskell-tng-util.el | 18 +++++++++++++++++
4 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index a778405..6435488 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ You must install `hsinspect` for every version of `ghc` that
you plan to use, e.
```
rm -f ~/.cabal/bin/hsinspect
for V in 8.4.4 8.6.5 ; do
- cabal v2-install hsinspect-0.0.6 -w ghc-$V -O2 &&
+ cabal v2-install hsinspect-0.0.7 -w ghc-$V -O2 &&
mv -f ~/.cabal/bin/hsinspect ~/.cabal/bin/hsinspect-ghc-$V
done
```
diff --git a/haskell-tng-extra.el b/haskell-tng-extra.el
index 48fe0da..5f7d5ac 100644
--- a/haskell-tng-extra.el
+++ b/haskell-tng-extra.el
@@ -93,9 +93,17 @@ When in a comment and called with a prefix, the comment will
be completed."
;;;###autoload
(defun haskell-tng-goto-imports ()
"Hack to jump to imports"
- ;; TODO imenu navigation will replace this
(interactive)
- (re-search-backward (rx line-start "import" word-end)))
+ (goto-char (point-min))
+ (re-search-forward (rx line-start "import" word-end))
+ (forward-line 0))
+
+;;;###autoload
+(defun haskell-tng-import-module (module)
+ "Adds an unqualified wildcard import."
+ ;; TODO autocomplete on available imports
+ (interactive "s")
+ (haskell-tng--import-symbol module nil nil))
;;;###autoload
(defun haskell-tng-current-module ()
diff --git a/haskell-tng-hsinspect.el b/haskell-tng-hsinspect.el
index 202fd95..45332a2 100644
--- a/haskell-tng-hsinspect.el
+++ b/haskell-tng-hsinspect.el
@@ -20,6 +20,7 @@
;; centric.
(require 'haskell-tng-compile)
+(require 'haskell-tng-util)
;;;###autoload
(defun haskell-tng-fqn-at-point ()
@@ -37,6 +38,46 @@ name of the symbol at point in the minibuffer."
(error "hsinspect is not available")
(message "<not imported>"))))
+;;;###autoload
+(defun haskell-tng-import-symbol-at-point ()
+ "Import the symbol at point"
+ ;; TODO import FQN as qualified module
+ ;; TODO prefix + FQN should mean use unqualified `as' import
+ ;; TODO prefix + unqualified should mean to import entire module
+ ;; TODO shortlist for FQN imports (no need to calc the index)
+ (interactive)
+ (when-let* ((index (haskell-tng--hsinspect-index))
+ (sym (haskell-tng--hsinspect-symbol-at-point)))
+ (message "Seaching for '%s' in %s modules" sym (length index))
+ (when-let ((hits (haskell-tng--hsinspect-import-candidates index sym)))
+ ;; TODO special case one hit
+ (when-let* ((entries (mapcar 'car hits)) ;; TODO include function name
+ (selected (popup-menu* entries))
+ (hit (seq-find (lambda (el) (equal (car el) selected))
hits)))
+ (haskell-tng--import-symbol (car hit) nil (cdr hit))))))
+
+(defun haskell-tng--hsinspect-import-candidates (index sym)
+ "Return a list of (module . symbol)"
+ ;; TODO threading/do syntax
+ ;; TODO alist variable binding like RecordWildcards
+ (seq-mapcat
+ (lambda (pkg-entry)
+ (let ((modules (alist-get 'modules pkg-entry))
+ (unitid (alist-get 'unitid pkg-entry)))
+ ;; (message "UNITID= %s" unitid)
+ (seq-mapcat
+ (lambda (module-entry)
+ (let ((module (alist-get 'module module-entry))
+ (ids (alist-get 'ids module-entry)))
+ ;;(message "MODULE= %s" module)
+ (seq-mapcat
+ (lambda (entry)
+ (let ((name (alist-get 'name entry)))
+ (when (equal name sym) `(,(cons module name)))))
+ ids)))
+ modules)))
+ index))
+
(defun haskell-tng--hsinspect-symbol-at-point ()
"A `symbol-at-point' that includes FQN parts."
(buffer-substring-no-properties
@@ -87,6 +128,17 @@ t means the process failed.")
(setq haskell-tng--hsinspect-imports
(haskell-tng--hsinspect "imports" buffer-file-name))))
+;; TODO this can be more efficiently cached alongside the .ghc.flags file, not
per source file
+;; (it's also fast to load so maybe persist it in a cache dir and check
timestamps)
+(defvar-local haskell-tng--hsinspect-index nil)
+(defun haskell-tng--hsinspect-index (&optional lookup-only)
+ (if (or lookup-only haskell-tng--hsinspect-index)
+ (unless (eq t haskell-tng--hsinspect-index)
+ haskell-tng--hsinspect-index)
+ (setq haskell-tng--hsinspect-index t) ;; avoid races
+ (setq haskell-tng--hsinspect-index
+ (haskell-tng--hsinspect "index"))))
+
(defun haskell-tng--hsinspect (&rest params)
(ignore-errors (kill-buffer "*hsinspect*"))
(when-let ((ghcflags (haskell-tng--hsinspect-ghcflags))
diff --git a/haskell-tng-util.el b/haskell-tng-util.el
index 041cec6..fb9a367 100644
--- a/haskell-tng-util.el
+++ b/haskell-tng-util.el
@@ -70,5 +70,23 @@ and taking a regexp."
(while (not (setq ,res ,test)) ,@body)
,res)))
+(defun haskell-tng--import-symbol (module as sym)
+ "Adds an import for MODULE."
+ ;; TODO outsource to `hsimport' when it does de-duping and formatting.
+ (save-excursion
+ (haskell-tng-goto-imports)
+ (insert
+ "import "
+ (cond
+ ((and (null as) (null sym))
+ module)
+ ((null as)
+ (concat module " (" sym ")"))
+ ((eq t as)
+ (concat "qualified " module))
+ (t
+ (concat "qualified " module " as " as)))
+ "\n")))
+
(provide 'haskell-tng-util)
;;; haskell-tng-util.el ends here
- [nongnu] elpa/haskell-tng-mode 4f40db3 218/385: fast-tags is stack compatible by default, (continued)
- [nongnu] elpa/haskell-tng-mode 4f40db3 218/385: fast-tags is stack compatible by default, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 59640ce 234/385: cleanups thanks to MELPA review, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 35d3830 306/385: cache improvements, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode c0b1b6b 301/385: change the compile-always-ask default, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 907c8fa 153/385: ImplicitParams indentation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ca00f1f 183/385: thot, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 611711a 208/385: address melpa review, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 89c5c80 223/385: improve smartparens workaround, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode e270647 228/385: more robust calls to hsinspect, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ad5967b 236/385: simpler installation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 599d4f0 283/385: import symbol at point,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode 9b334f7 275/385: ghcflags, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode f221f95 173/385: introduce types and constraints to the grammar, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ae1d399 268/385: backslashes are only keywords when used in lambdas, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 1d74d5f 279/385: backslash bughunting, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 499c77f 261/385: abbrev-mode support, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode e2e3490 382/385: hide-show supports BOILERPLATE START ... BOILERPLATE END, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode a34e796 368/385: improve debugging, ELPA Syncer, 2021/10/06