diff --git a/elisp/eshell-starship.el b/elisp/eshell-starship.el index 6447341..66b6ca7 100644 --- a/elisp/eshell-starship.el +++ b/elisp/eshell-starship.el @@ -12,8 +12,11 @@ This should be an alist of (name function). The macro `eshell-starship-defmodule' can help modify this list.") +(defvar eshell-starship--module-cache (make-hash-table :test 'eq) + "Hash table to hold module cache for eshell-starship.") + (cl-defmacro eshell-starship-defmodule (name &key pred files dirs exts icon color - allow-remote action) + allow-remote action reload-on) "Define an eshell-starship module called NAME. The module will be added to `eshell-starship-modules'. :PRED - a function that should return t if the module should be run @@ -24,10 +27,12 @@ The module will be added to `eshell-starship-modules'. :ICON - this is the string to print before the modules text :COLOR - the color to print the modules text in :ALLOW-REMOTE - weather to allow the module to run on remote machines - :ACTION - a function that will return the module text, or nil" + :ACTION - a function that will return the module text, or nil + :RELOAD-ON - when to re-run the module. Can be one of `'cwd' or `'always' + (same as nil)" (declare (indent defun)) `(setf (alist-get ',name eshell-starship-modules) - ,(list 'list pred files dirs exts icon color allow-remote action))) + ,(list 'list pred files dirs exts icon color allow-remote action reload-on))) (cl-defmacro eshell-starship-find-version-function (command pattern &rest format) @@ -48,6 +53,7 @@ arguments to pass to `concat' to format the output." :icon "C" :color "green yellow" :allow-remote nil + :reload-on 'cwd :action (eshell-starship-find-version-function ("cc" "-v") "^\\([-a-zA-Z]+\\) version \\([0-9]+\\.[0-9]+\\.[0-9]+\\)" @@ -58,11 +64,19 @@ arguments to pass to `concat' to format the output." :icon "󰔶" :color "blue" :allow-remote nil + :reload-on 'cwd :action (eshell-starship-find-version-function ("cmake" "--version") "cmake version \\([0-9]+\\.[0-9]+\\.[0-9]+\\)" "v" (match-string 1))) +(defun eshell-starship--cwd-clear-caches () + "Clear caches that should be cleared on cwd for eshell-starship." + (dolist (module eshell-starship-modules) + (if-let ((reload-on (nth 9 module)) + ((eq reload-on 'cwd))) + (puthash (car module) nil eshell-starship--module-cache)))) + (defun eshell-starship--exts-exist-p (&rest exts) "Test if any files with EXTS at the end of their name exist in default dir." (catch 'found @@ -89,16 +103,21 @@ arguments to pass to `concat' to format the output." (defun eshell-starship--execute-modules () "Execute all the modules in `eshell-starship-modules'." (cl-loop - for (_ pred files dirs exts icon color allow-remote action) + for (name pred files dirs exts icon color allow-remote action reload-on) in eshell-starship-modules when (and (or allow-remote (not (file-remote-p default-directory))) (or (and files (apply 'eshell-starship--files-exist-p files)) (and dirs (apply' eshell-starship--dirs-exist-p dirs)) (and exts (apply' eshell-starship--exts-exist-p exts)) (and pred (funcall pred)))) - concat (if-let (result (funcall action)) - (concat " via " (propertize (concat icon " " result) - 'face `(:foreground ,color)))))) + concat (if-let (cache-val (gethash name eshell-starship--module-cache)) + cache-val + (if-let ((result (funcall action)) + (mod-string (concat " via " (propertize (concat icon " " result) + 'face `(:foreground ,color))))) + (unless (or (not reload-on) (eq reload-on 'always)) + (puthash name mod-string eshell-starship--module-cache)) + result)))) (defun eshell-starship--replace-home-with-tilda (path) "If PATH beings with $HOME (the environment variable), replace it with ~." @@ -336,6 +355,9 @@ END-TIME is the time when the command finished executing." (defvar-local ehsell-starship--restore-state nil "State of various variables set by `eshell-starship-prompt-mode'.") +;;;###autoload +(add-hook 'eshell-directory-change-hook #'eshell-starship--cwd-clear-caches) + ;;;###autoload (define-minor-mode eshell-starship-prompt-mode "Minor mode to make eshell prompts look like starship (https://starship.rs)."