aboutsummaryrefslogtreecommitdiffstats
path: root/oni-eshell.el
diff options
context:
space:
mode:
Diffstat (limited to 'oni-eshell.el')
-rw-r--r--oni-eshell.el106
1 files changed, 87 insertions, 19 deletions
diff --git a/oni-eshell.el b/oni-eshell.el
index 1dfb744..7a0e0c2 100644
--- a/oni-eshell.el
+++ b/oni-eshell.el
@@ -4,7 +4,7 @@
;; Author: Tom Willemse <tom@ryuslash.org>
;; Keywords: local
-;; Version: 2022.1127.221317
+;; Version: 2023.0414.233822
;; Package-Requires: (eshell-fringe-status esh-autosuggest xterm-color eshell-syntax-highlighting)
;; This program is free software; you can redistribute it and/or modify
@@ -81,34 +81,26 @@
(eshell/cd (file-name-directory (buffer-file-name (get-buffer buffer-name))))
(eshell-reset))
-(defun oni-eshell-shorten-directories (path)
- "Shorten PATH to a list of unique shortened directory names."
- (let* ((directories (split-string path "/" t))
- (new-path
- (string-join
- (mapcar (lambda (d)
- (let ((name (substring d 0 1))
- (length 1))
- (while (cl-find-if (lambda (s) (and (not (string= s d))
- (string-prefix-p name s)))
- directories)
- (setq name (substring d 0 (cl-incf length))))
- name))
- directories) "/")))
- (if (string-prefix-p "~" new-path)
- new-path
- (concat "/" new-path))))
-
(defun oni-eshell-disable-beacon-on-scroll ()
"Disable ‘beacon-blink-when-window-scrolls’ in the current buffer."
(setq-local beacon-blink-when-window-scrolls nil))
+(defun oni-eshell-change-font ()
+ "Remap the default font to the one I use for terminals."
+ (face-remap-add-relative 'default :family "Classic Console Neue"))
+
+(defun oni-eshell-set-page-delimiter ()
+ "Change the page delimiter so that it matches the prompt for easy navigation."
+ (setq-local page-delimiter eshell-prompt-regexp))
+
(add-hook 'eshell-before-prompt-hook #'oni-eshell--set-xterm-variables)
(add-hook 'eshell-first-time-mode-hook #'oni-eshell--expand-keymap)
(add-hook 'eshell-load-hook #'oni-eshell--disable-ansi-color-handling)
(add-hook 'eshell-load-hook #'oni-eshell--enable-truncating-buffers)
(add-hook 'eshell-load-hook #'oni-eshell--enable-xterm-filter)
+(add-hook 'eshell-mode-hook #'oni-eshell-change-font)
(add-hook 'eshell-mode-hook #'oni-eshell-disable-beacon-on-scroll)
+(add-hook 'eshell-mode-hook #'oni-eshell-set-page-delimiter)
(add-hook 'eshell-mode-hook 'esh-autosuggest-mode)
(add-hook 'eshell-mode-hook 'eshell-syntax-highlighting-mode)
(add-hook 'eshell-mode-hook 'goto-address-mode)
@@ -126,5 +118,81 @@
(slot . 0)
(window-height . 0.33)))
+;;; Eshell prompt
+
+(defun oni-eshell-shortest-unique-directory (current-path directory)
+ "Find the shortest unique substring of DIRECTORY.
+DIRECTORY should be a directory that exists within CURRENT-PATH."
+ (catch 'result
+ (dotimes (i (length directory))
+ (let* ((current-directory (substring directory 0 (1+ i)))
+ (dir-rx (rx string-start
+ (literal current-directory)
+ (zero-or-more any)))
+ (matches (directory-files current-path nil dir-rx)))
+ (when (= (length matches) 1)
+ (throw 'result current-directory))))))
+
+(defun oni-eshell-shorten-directory (directory)
+ "Shorten DIRECTORY to the shortest unique names of each directory."
+ (let ((current-path "/")
+ (current-short-path "/")
+ (home (concat (getenv "HOME") "/"))
+ (components (string-split (expand-file-name directory) "/" t)))
+ (dolist (dir components current-short-path)
+ (let* ((shortened (propertize (oni-eshell-shortest-unique-directory current-path dir)
+ 'help-echo dir))
+ (new-path (format "%s%s/" current-path dir))
+ (new-short-path (if (string= new-path home)
+ "~/"
+ (format "%s%s/" current-short-path shortened))))
+ (setq current-path new-path
+ current-short-path new-short-path)))))
+
+(defun oni-eshell-show-perforce-info-p ()
+ "Predicate to indicate whether or not powershell info should be shown."
+ (locate-dominating-file "." ".p4config"))
+
+(defun oni-eshell-perforce-workspace ()
+ "Function returning the current Perforce workspace."
+ (car (map-elt (mapcar (lambda (str) (split-string str ": "))
+ (split-string (shell-command-to-string "p4 info -s") "\n"))
+ "Client name")))
+
+(defun oni-eshell-perforce-root ()
+ "Function returning the root directory of the current Perforce workspace."
+ (string-replace
+ "\\"
+ "/"
+ (car (map-elt (mapcar (lambda (str) (split-string str ": "))
+ (split-string (shell-command-to-string "p4 info") "\n"))
+ "Client root"))))
+
+(defun oni-eshell-perforce-stream ()
+ "Function returning the current Perforce stream."
+ (string-trim-right (shell-command-to-string "p4 switch")))
+
+(defun oni-eshell-prompt-function ()
+ "Construct a prompt string for Eshell."
+ (let* ((perforcep (oni-eshell-show-perforce-info-p))
+ (pwd (eshell/pwd))
+ (dir (if perforcep
+ (concat (propertize (oni-eshell-perforce-workspace)
+ 'face '((foreground-color . "#ca3cad90828e")))
+ ":"
+ (let ((relative-path (string-remove-prefix (oni-eshell-perforce-root) pwd)))
+ (if (string= relative-path "") "/" relative-path)))
+ (oni-eshell-shorten-directory pwd)))
+ (stream (if perforcep (concat " ("
+ (propertize (oni-eshell-perforce-stream)
+ 'face '((foreground-color . "#90e4ca3c828e")))
+ ")")
+ "")))
+ (concat dir
+ stream
+ (if (= (user-uid) 0) " # " " $ "))))
+
+(setq eshell-prompt-function #'oni-eshell-prompt-function)
+
(provide 'oni-eshell)
;;; oni-eshell.el ends here