prompt
This commit is contained in:
parent
3302b9a14d
commit
42b80cd9a3
|
@ -192,3 +192,158 @@ Scrolling through the output and searching for results that can be copied to the
|
|||
*Note:* We can’t add it to the list until after we start our first
|
||||
eshell session, so we just add it to the =eshell-pred-load-hook=
|
||||
which is sufficient.
|
||||
** Special Prompt
|
||||
|
||||
Following [[http://blog.liangzan.net/blog/2012/12/12/customizing-your-emacs-eshell-prompt/][these instructions]], we build a better prompt with the Git
|
||||
branch in it (Of course, it matches my Bash prompt). First, we need
|
||||
a function that returns a string with the Git branch in it,
|
||||
e.g. ":master"
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun curr-dir-git-branch-string (pwd)
|
||||
"Returns current git branch as a string, or the empty string if
|
||||
PWD is not in a git repo (or the git command is not found)."
|
||||
(interactive)
|
||||
(when (and (not (file-remote-p pwd))
|
||||
(eshell-search-path "git")
|
||||
(locate-dominating-file pwd ".git"))
|
||||
(let* ((git-url (shell-command-to-string "git config --get remote.origin.url"))
|
||||
(git-repo (file-name-base (s-trim git-url)))
|
||||
(git-output (shell-command-to-string (concat "git rev-parse --abbrev-ref HEAD")))
|
||||
(git-branch (s-trim git-output))
|
||||
(git-icon "\xe0a0")
|
||||
(git-icon2 (propertize "\xf020" 'face `(:family "octicons"))))
|
||||
(concat git-repo " " git-icon2 " " git-branch))))
|
||||
#+END_SRC
|
||||
|
||||
The function takes the current directory passed in via =pwd= and
|
||||
replaces the =$HOME= part with a tilde. I'm sure this function
|
||||
already exists in the eshell source, but I didn't find it...
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun pwd-replace-home (pwd)
|
||||
"Replace home in PWD with tilde (~) character."
|
||||
(interactive)
|
||||
(let* ((home (expand-file-name (getenv "HOME")))
|
||||
(home-len (length home)))
|
||||
(if (and
|
||||
(>= (length pwd) home-len)
|
||||
(equal home (substring pwd 0 home-len)))
|
||||
(concat "~" (substring pwd home-len))
|
||||
pwd)))
|
||||
#+END_SRC
|
||||
|
||||
Make the directory name be shorter...by replacing all directory
|
||||
names with just its first names. However, we leave the last two to
|
||||
be the full names. Why yes, I did steal this.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun pwd-shorten-dirs (pwd)
|
||||
"Shorten all directory names in PWD except the last two."
|
||||
(let ((p-lst (split-string pwd "/")))
|
||||
(if (> (length p-lst) 2)
|
||||
(concat
|
||||
(mapconcat (lambda (elm) (if (zerop (length elm)) ""
|
||||
(substring elm 0 1)))
|
||||
(butlast p-lst 2)
|
||||
"/")
|
||||
"/"
|
||||
(mapconcat (lambda (elm) elm)
|
||||
(last p-lst 2)
|
||||
"/"))
|
||||
pwd))) ;; Otherwise, we just return the PWD
|
||||
#+END_SRC
|
||||
|
||||
Break up the directory into a "parent" and a "base":
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun split-directory-prompt (directory)
|
||||
(if (string-match-p ".*/.*" directory)
|
||||
(list (file-name-directory directory) (file-name-base directory))
|
||||
(list "" directory)))
|
||||
#+END_SRC
|
||||
|
||||
Using virtual environments for certain languages is helpful to know,
|
||||
especially since I change them based on the directory.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ruby-prompt ()
|
||||
"Returns a string (may be empty) based on the current Ruby Virtual Environment."
|
||||
(let* ((executable "~/.rvm/bin/rvm-prompt")
|
||||
(command (concat executable "v g")))
|
||||
(when (file-exists-p executable)
|
||||
(let* ((results (shell-command-to-string executable))
|
||||
(cleaned (string-trim results))
|
||||
(gem (propertize "\xe92b" 'face `(:family "alltheicons"))))
|
||||
(when (and cleaned (not (equal cleaned "")))
|
||||
(s-replace "ruby-" gem cleaned))))))
|
||||
|
||||
(defun python-prompt ()
|
||||
"Returns a string (may be empty) based on the current Python
|
||||
Virtual Environment. Assuming the M-x command: `pyenv-mode-set'
|
||||
has been called."
|
||||
(when (fboundp #'pyenv-mode-version)
|
||||
(let ((venv (pyenv-mode-version)))
|
||||
(when venv
|
||||
(concat
|
||||
(propertize "\xe928" 'face `(:family "alltheicons"))
|
||||
(pyenv-mode-version))))))
|
||||
#+END_SRC
|
||||
|
||||
Now tie it all together with a prompt function can color each of the
|
||||
prompts components.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun eshell/eshell-local-prompt-function ()
|
||||
"A prompt for eshell that works locally (in that is assumes
|
||||
that it could run certain commands) in order to make a prettier,
|
||||
more-helpful local prompt."
|
||||
(interactive)
|
||||
(let* ((pwd (eshell/pwd))
|
||||
(directory (split-directory-prompt
|
||||
(pwd-shorten-dirs
|
||||
(pwd-replace-home pwd))))
|
||||
(parent (car directory))
|
||||
(name (cadr directory))
|
||||
(branch (curr-dir-git-branch-string pwd))
|
||||
(ruby (when (not (file-remote-p pwd)) (ruby-prompt)))
|
||||
(python (when (not (file-remote-p pwd)) (python-prompt)))
|
||||
|
||||
(dark-env (eq 'dark (frame-parameter nil 'background-mode)))
|
||||
(for-bars `(:weight bold))
|
||||
(for-parent (if dark-env `(:foreground "dark orange") `(:foreground "blue")))
|
||||
(for-dir (if dark-env `(:foreground "orange" :weight bold)
|
||||
`(:foreground "blue" :weight bold)))
|
||||
(for-git `(:foreground "green"))
|
||||
(for-ruby `(:foreground "red"))
|
||||
(for-python `(:foreground "#5555FF")))
|
||||
|
||||
(concat
|
||||
(propertize "⟣─ " 'face for-bars)
|
||||
(propertize parent 'face for-parent)
|
||||
(propertize name 'face for-dir)
|
||||
(when branch
|
||||
(concat (propertize " ── " 'face for-bars)
|
||||
(propertize branch 'face for-git)))
|
||||
(when ruby
|
||||
(concat (propertize " ── " 'face for-bars)
|
||||
(propertize ruby 'face for-ruby)))
|
||||
(when python
|
||||
(concat (propertize " ── " 'face for-bars)
|
||||
(propertize python 'face for-python)))
|
||||
(propertize "\n" 'face for-bars)
|
||||
(propertize (if (= (user-uid) 0) " #" " $") 'face `(:weight ultra-bold))
|
||||
;; (propertize " └→" 'face (if (= (user-uid) 0) `(:weight ultra-bold :foreground "red") `(:weight ultra-bold)))
|
||||
(propertize " " 'face `(:weight bold)))))
|
||||
|
||||
(setq-default eshell-prompt-function #'eshell/eshell-local-prompt-function)
|
||||
#+END_SRC
|
||||
|
||||
Turn off the default prompt, otherwise, it won't use ours:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq eshell-highlight-prompt nil)
|
||||
#+END_SRC
|
||||
|
||||
Here is the result:
|
||||
[[http://imgur.com/nkpwII0.png]]
|
||||
|
|
Loading…
Reference in New Issue