From 39efc3d5ba9868d1fe57f2d0cd6f4d944b7f1ae0 Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Fri, 20 Dec 2024 20:22:23 -0800 Subject: [PATCH] Add more eshell-starship modules --- elisp/eshell-starship.el | 115 ++++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/elisp/eshell-starship.el b/elisp/eshell-starship.el index 203a29a..12ccd73 100644 --- a/elisp/eshell-starship.el +++ b/elisp/eshell-starship.el @@ -12,9 +12,12 @@ 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) +(defvar-local eshell-starship--module-cache nil "Hash table to hold module cache for eshell-starship.") +(defvar-local eshell-starship--files-name-cache nil + "Cache of file names last time eshell-starship checked.") + (cl-defmacro eshell-starship-defmodule (name &key pred files dirs exts icon color allow-remote action reload-on) "Define an eshell-starship module called NAME. @@ -28,11 +31,12 @@ The module will be added to `eshell-starship-modules'. :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 - :RELOAD-ON - when to re-run the module. Can be one of `'cwd' or `'always' - (same as nil)" + :RELOAD-ON - when to re-run the module. List of \\='cwd, \\='files, + \\='always, or \\='never (same as nil)" (declare (indent defun)) `(setf (alist-get ',name eshell-starship-modules) - ,(list 'list pred files dirs exts icon color allow-remote action reload-on))) + (list ,pred ,files ,dirs ,exts ,icon ,color ,allow-remote ,action + (ensure-list ,reload-on)))) (cl-defmacro eshell-starship-find-version-function (command pattern &rest format) @@ -59,6 +63,18 @@ arguments to pass to `concat' to format the output." "^\\([-a-zA-Z]+\\) version \\([0-9]+\\.[0-9]+\\.[0-9]+\\)" "v" (match-string 2) "-" (match-string 1))) +(eshell-starship-defmodule rust + :exts '("rs") + :files '("Cargo.toml") + :icon "🦀" + :color "red" + :allow-remote nil + :reload-on 'cwd + :action (eshell-starship-find-version-function + ("rustc" "--version") + "^rustc \\([0-9]+\\.[0-9]+\\.[0-9]+\\)" + "v" (match-string 1))) + (eshell-starship-defmodule cmake :files '("CMakeLists.txt" "CMakeCache.txt") :icon "󰔶" @@ -70,12 +86,59 @@ arguments to pass to `concat' to format the output." "cmake version \\([0-9]+\\.[0-9]+\\.[0-9]+\\)" "v" (match-string 1))) +(require 'inf-lisp nil t) +(when (featurep 'inf-lisp) + (eshell-starship-defmodule common-lisp + :exts '("asd" "lisp") + :icon "" + :color "green" + :allow-remote nil + :reload-on 'cwd + :action (eshell-starship-find-version-function + (inferior-lisp-program "--version") + "[a-zA-Z]+ [0-9.]+" + (match-string 0)))) + +(eshell-starship-defmodule elisp + :exts '("el" "elc" "eln") + :icon "" + :color "dark orchid" + :allow-remote nil + :reload-on 'never + :action (lambda () + emacs-version)) + +(eshell-starship-defmodule java + :exts '("java" "class" "gradle" "jar" "clj" "cljc") + :files '("pom.xml" "build.gradle.kts" "build.sbt" ".java-version" "deps.edn" + "project.clj" "build.boot" ".sdkmanrc") + :icon "☕" + :color "dark red" + :allow-remote nil + :reload-on 'cwd + :action (eshell-starship-find-version-function + ("java" "-version") + "version \"\\([0-9]+\\)\"" + "v" (match-string 1))) + +(defun eshell-starship--clear-caches (&rest flags) + "Clear each cache entry with a \\=:reload-on of FLAGS." + (cl-loop for module in eshell-starship-modules + for reload-on = (cl-tenth module) + when (cl-intersection reload-on flags) + do (remhash (cl-first module) eshell-starship--module-cache))) + (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)))) + (eshell-starship--clear-caches 'cwd 'files)) + +(defun eshell-starship--maybe-files-clear-caches () + "Clear caches that should be claered if files changed. +This will only clear the caches if the files actually changed." + (let ((files (cons 'set (directory-files default-directory)))) + (unless (equal files eshell-starship--files-name-cache) + (setq eshell-starship--files-name-cache files) + (eshell-starship--clear-caches 'files)))) (defun eshell-starship--exts-exist-p (&rest exts) "Test if any files with EXTS at the end of their name exist in default dir." @@ -115,7 +178,7 @@ arguments to pass to `concat' to format the output." (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)) + (unless (member 'always reload-on) (puthash name mod-string eshell-starship--module-cache)) result)))) @@ -302,8 +365,6 @@ For example, a revert. If there is no current operation, return nil." "Command run before each eshell program to record the time." (setq eshell-starship--last-start-time (current-time))) -(add-hook 'eshell-pre-command-hook #'eshell-starship--timer-pre-cmd) - (defun eshell-starship--prompt-format-span (span) "Format SPAN as \"XhXms\"." (let* ((hours (/ span 3600)) @@ -330,6 +391,7 @@ END-TIME is the time when the command finished executing." (defun eshell-starship--prompt-function () "Function for `eshell-prompt-function'." + (eshell-starship--maybe-files-clear-caches) (let* ((end-time (current-time)) (dir (eshell-starship--get-current-dir)) (prompt (concat @@ -352,11 +414,28 @@ END-TIME is the time when the command finished executing." (setq eshell-starship--last-start-time nil) prompt)) -(defvar-local ehsell-starship--restore-state nil +(defvar-local eshell-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) +(defun eshell-starship--enable () + "Enable eshell-starship." + (setq-local eshell-starship--restore-state + (buffer-local-set-state eshell-prompt-function + 'eshell-starship--prompt-function + eshell-prompt-regexp "^❯ " + eshell-highlight-prompt nil) + eshell-starship--module-cache (make-hash-table :test 'eq)) + (add-hook 'eshell-pre-command-hook #'eshell-starship--timer-pre-cmd nil t) + (add-hook 'eshell-directory-change-hook #'eshell-starship--cwd-clear-caches + nil t)) + +(defun eshell-starship--disable () + "Disable eshell-starship." + (setq-local eshell-starship--module-cache nil) + (buffer-local-restore-state eshell-starship--restore-state) + (remove-hook 'eshell-pre-command-hook #'eshell-starship--timer-pre-cmd t) + (remove-hook 'eshell-directory-change-hook #'eshell-starship--cwd-clear-caches + t)) ;;;###autoload (define-minor-mode eshell-starship-prompt-mode @@ -365,12 +444,8 @@ END-TIME is the time when the command finished executing." :init-value nil :interactive (eshell-mode) (if eshell-starship-prompt-mode - (setq-local eshell-starship--restore-state - (buffer-local-set-state eshell-prompt-function - 'eshell-starship--prompt-function - eshell-prompt-regexp "^❯ " - eshell-highlight-prompt nil)) - (buffer-local-restore-state eshell-starship--restore-state))) + (eshell-starship--enable) + (eshell-starship--disable))) (provide 'eshell-starship) ;;; eshell-starship.el ends here