Eshell Aliases, Prompt, And Colors

Do you use #Emacs to run shells or terminal emulators? Well, you should. With vterm you have a fast alternative to the builtin ansi-term. And if you prefer shells, you’ve got EShell and Shell Mode. And don’t forget serial-term for embedded programming. — Mickey Petersen (@mickeynp) on Twitter, July 18, 2022.

Eshell Aliases

An excellent post from Mickey Petersen, a famous Emacs guru and the author of Mastering Emacs reminded me to share my eshell configuration.

There are 2 ways to configure eshell aliases. Elsa Gonsiorowski uses a special configuration file ~/.emacs.d/eshell/alias while Howard Abrams prefers to put his eshell alias settings to .emacs or init.el. Personally, I prefer the former approach.

Here is my ~/.emacs.d/eshell/alias.

alias ll ls -AFGhl --color=always $1
alias ff find-file $1
alias e find-file-other-window $1
alias d dired $1
alias gd magit-diff-unstaged
alias gds magit-diff-staged
alias gg git log --color --graph --oneline --abbrev-commit --decorate --all --date=short --pretty=format:"%C(cyan)%h %C(yellow)%ad %C(bold green)%d %C(reset)%s"

Most of these aliases are obvious, e.g. ll prints extended directory listing, ff somefile opens somefile for editing in the same window, e somefile uses other window to edit somefile, d opens the dired buffer in the same window, etc. The last one prints the colorized one-line git log as shown below.

Eshell Prompt

The prompt you can see on the screenshot above is borrowed from the Reddit post with some colors optimized for the Solarized Dark theme.

(setq eshell-prompt-function
      (lambda ()
        (concat
         (propertize "┌─[" 'face `(:foreground "#2aa198"))
         (propertize (user-login-name) 'face `(:foreground "#dc322f"))
         (propertize "@" 'face `(:foreground "#2aa198"))
         (propertize (system-name) 'face `(:foreground "#268bd2"))
         (propertize "]──[" 'face `(:foreground "#2aa198"))
         (propertize (format-time-string "%H:%M" (current-time)) 'face `(:foreground "#b58900"))
         (propertize "]──[" 'face `(:foreground "#2aa198"))
         (propertize (concat (eshell/pwd)) 'face `(:foreground "#93a1a1"))
         (propertize "]\n" 'face `(:foreground "#2aa198"))
         (propertize "└─>" 'face `(:foreground "#2aa198"))
         (propertize (if venv-current-name (concat " (" venv-current-name ")")  "") 'face `(:foreground "#00dc00"))
         (propertize (if (= (user-uid) 0) " # " " $ ") 'face `(:foreground "#2aa198"))
         )))

In addition to the username, the current time, and the current directory it also shows the current Python virtual environment name (in green).

Eshell Colors

The often cited issue with eshell is the lack of color output even if it is explicitly specified in a command (e.g. ls --color=always).

Adding this to your ~/.emacs (or init.el) DOES NOT solve the problem:

(setenv "TERM" "xterm-256color")

THIS DOES solve the problem with color output in eshell:

(add-hook 'eshell-mode-hook (lambda () (setenv "TERM" "xterm-256color")))

Though to get the current directory listing in eshell I prefer to use the eshell alias d (equivalent to d .), see the list of aliases above.

More on Emacs' eshell can be found here, thanks again, Mickey.