[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/haskell-tng-mode b46dbd1 305/385: refactoring of the cache
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/haskell-tng-mode b46dbd1 305/385: refactoring of the cache for more reuse later |
Date: |
Tue, 5 Oct 2021 23:59:53 -0400 (EDT) |
branch: elpa/haskell-tng-mode
commit b46dbd1084f6a7410ba43f8050f234a20396e0f3
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>
refactoring of the cache for more reuse later
---
haskell-tng-extra-company.el | 2 +-
haskell-tng-hsinspect.el | 69 +++++++++-----------------------------------
haskell-tng-util.el | 58 +++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 57 deletions(-)
diff --git a/haskell-tng-extra-company.el b/haskell-tng-extra-company.el
index 8dc1f7d..54304d1 100644
--- a/haskell-tng-extra-company.el
+++ b/haskell-tng-extra-company.el
@@ -54,7 +54,7 @@
;;(message "TNG asked with %S" arg)
(seq-mapcat
(lambda (names) (all-completions arg (seq-map #'cdr names)))
- (haskell-tng--hsinspect-imports nil nil)))
+ (haskell-tng--hsinspect-imports 'no-work nil)))
('sorted t)
('duplicates t)
;; TODO 'meta return the FQN
diff --git a/haskell-tng-hsinspect.el b/haskell-tng-hsinspect.el
index a3a46b4..c6b638b 100644
--- a/haskell-tng-hsinspect.el
+++ b/haskell-tng-hsinspect.el
@@ -15,7 +15,6 @@
;; with pre-canned data.
(require 'subr-x)
-(require 'xdg)
;; Popups are not supported in stock Emacs so an extension is necessary:
;; https://emacs.stackexchange.com/questions/53373
@@ -37,7 +36,7 @@ A prefix argument ensures that caches are flushes."
(if-let* ((sym (haskell-tng--hsinspect-symbol-at-point))
(found (seq-find
(lambda (names) (member sym (seq-map #'cdr names)))
- (haskell-tng--hsinspect-imports 'allow-work alt))))
+ (haskell-tng--hsinspect-imports nil alt))))
;; TODO multiple hits
;; TODO feedback when hsinspect is broken
(popup-tip (format "%s" (cdar (last found))))
@@ -122,12 +121,13 @@ A prefix argument ensures that caches are flushes."
(defvar-local haskell-tng--hsinspect-imports nil
"Cache for the last `imports' call for this buffer.
t means the process failed.")
-(defun haskell-tng--hsinspect-imports (allow-work flush-cache)
- (haskell-tng--hsinspect-cached-cmd
- 'haskell-tng--hsinspect-imports
- (concat buffer-file-name "." "imports")
+(defun haskell-tng--hsinspect-imports (no-work flush-cache)
+ (haskell-tng--hsinspect-cached
+ #'haskell-tng--hsinspect
`("imports" ,buffer-file-name)
- allow-work
+ 'haskell-tng--hsinspect-imports
+ (concat "hsinspect-0.0.7" buffer-file-name "." "imports")
+ no-work
flush-cache))
(defvar-local haskell-tng--hsinspect-index nil
@@ -136,58 +136,15 @@ t means the process failed.")
(defun haskell-tng--hsinspect-index (flush-cache)
(when-let (ghcflags-dir
(locate-dominating-file default-directory ".ghc.flags"))
- (haskell-tng--hsinspect-cached-cmd
- 'haskell-tng--hsinspect-index
- (concat (expand-file-name ghcflags-dir) ".index")
+ (haskell-tng--hsinspect-cached
+ #'haskell-tng--hsinspect
'("index")
- t
+ 'haskell-tng--hsinspect-index
+ (concat "hsinspect-0.0.7" (expand-file-name ghcflags-dir) "index")
+ nil
flush-cache)))
-(defun haskell-tng--hsinspect-cached-cmd (buffer-local-cache
- disk-cache
- args
- allow-work flush-cache)
- (when flush-cache
- (set buffer-local-cache nil))
- (when (not (symbol-value buffer-local-cache))
- (let ((cache-file-name
- (concat
- (xdg-cache-home) "/"
- "hsinspect-0.0.7/"
- disk-cache)))
- ;; user is responsible for flushing caches.
- (when (and flush-cache (file-exists-p cache-file-name))
- (delete-file cache-file-name))
- (if (file-exists-p cache-file-name)
- (set
- buffer-local-cache
- (progn
- ;; TODO decide if we want to keep this check, it's mostly for
debugging
- (if (or
- (buffer-modified-p)
- (time-less-p
- (file-attribute-modification-time (file-attributes
cache-file-name))
- (file-attribute-modification-time (file-attributes
buffer-file-name))))
- (message "loading hsinspect cache older than the current
buffer")
- (message "loading hsinspect cache"))
- (with-temp-buffer
- (insert-file-contents cache-file-name)
- (goto-char (point-min))
- (ignore-errors (read (current-buffer))))))
- (unless (or (not allow-work)
- (eq t (symbol-value buffer-local-cache)))
- (set buffer-local-cache t)
- (set buffer-local-cache (apply #'haskell-tng--hsinspect args))
- (let ((cache (symbol-value buffer-local-cache)))
- (unless (eq t cache)
- (with-temp-file cache-file-name
- (make-directory (file-name-directory cache-file-name) t)
- (prin1 cache (current-buffer)))))))))
-
- (when (not (eq t (symbol-value buffer-local-cache)))
- (symbol-value buffer-local-cache)))
-
-;; TODO cache per project (or package at least)
+;; FIXME use a cache
(defvar-local haskell-tng--hsinspect-exe nil)
(defvar haskell-tng--hsinspect-which-hsinspect
"cabal exec -v0 which -- hsinspect")
diff --git a/haskell-tng-util.el b/haskell-tng-util.el
index 96bd3f0..d7f93a8 100644
--- a/haskell-tng-util.el
+++ b/haskell-tng-util.el
@@ -12,6 +12,7 @@
;; TODO move things to single use sites (twas premature abstraction!)
(require 'subr-x)
+(require 'xdg)
(defun haskell-tng--util-paren-close (&optional pos)
"The next `)', if it closes `POS's paren depth."
@@ -94,5 +95,62 @@ and taking a regexp."
(concat "qualified " module " as " as)))
"\n")))
+;; TODO needs a unit test
+;; TODO a macro that expands out the local variable
+(defun haskell-tng--hsinspect-cached
+ (fn args local disk &optional no-work flush-cache)
+ "A two-tier cache over a FN that takes ARGS.
+The caller is responsible for flushing the cache.
+
+If the LOCAL reference contains a cache of a previous call, it is
+returned immediately.
+
+If DISK expands to a file that exists in the cache directory, it
+is read as an s-expression, saved to LOCAL, and returned.
+
+Otherwise FN is called with ARGS and saved to both LOCAL and
+DISK.
+
+Errors are not cached, nil return values are cached.
+
+NO-WORK skips FN and only queries the caches.
+
+FLUSH-CACHE forces both LOCAL and DISK to be invalidated."
+ (when flush-cache
+ (set local nil))
+ (when (not (symbol-value local))
+ (let ((cache-file-name
+ (concat (xdg-cache-home) "/" disk)))
+ (when (and flush-cache (file-exists-p cache-file-name))
+ (delete-file cache-file-name))
+ (if (file-exists-p cache-file-name)
+ (set
+ local
+ (progn
+ ;; TODO remove this check, it's just for debugging
+ (if (or
+ (buffer-modified-p)
+ (time-less-p
+ (file-attribute-modification-time (file-attributes
cache-file-name))
+ (file-attribute-modification-time (file-attributes
buffer-file-name))))
+ (message "loading %S cache older than the current buffer"
(car args))
+ (message "loading %S cache" (car args)))
+ (with-temp-buffer
+ (insert-file-contents cache-file-name)
+ (goto-char (point-min))
+ (ignore-errors (read (current-buffer))))))
+ (unless (or no-work
+ (eq 'cached-nil (symbol-value local)))
+ (set local 'cached-nil)
+ (set local (apply fn args))
+ (unless local (set local 'cached-nil))
+ (let ((cache (symbol-value local)))
+ (with-temp-file cache-file-name
+ (make-directory (file-name-directory cache-file-name)
'create-parents)
+ (prin1 cache (current-buffer))))))))
+
+ (when (not (eq 'cached-nil (symbol-value local)))
+ (symbol-value local)))
+
(provide 'haskell-tng-util)
;;; haskell-tng-util.el ends here
- [nongnu] elpa/haskell-tng-mode f59c9ee 259/385: fix indentation of short type signatures, (continued)
- [nongnu] elpa/haskell-tng-mode f59c9ee 259/385: fix indentation of short type signatures, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode dbbe488 265/385: abbrevs don't fire in comments / strings, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode f56bd2a 256/385: prefer optimised hsinspect builds, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode e84970b 263/385: rename -contrib to -extra, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode af443a1 269/385: fix a name clash in the tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cce466c 271/385: hsinspect now has a compiler plugin, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode d0cd9b9 252/385: documenting an annoying indentation bug, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode afbac7c 300/385: missing import, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 7060573 286/385: moar work to do here, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 89db192 289/385: more thots, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode b46dbd1 305/385: refactoring of the cache for more reuse later,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode ff76e07 304/385: cache the index command, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 2653ce7 312/385: checks on the hsinspect binary, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode da20f0d 314/385: note about limitations on nixos, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 52d984a 324/385: fix cache typo, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ae8ebbc 320/385: thots, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode aca98c2 333/385: simplify import-symbol-at-point logic, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 1e3c465 329/385: import types and data constructors, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3ab7495 342/385: thots, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ef3cea6 340/385: thots, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode a14a2c2 332/385: allow dir locals for the -as lookups, ELPA Syncer, 2021/10/06