2

Let's say I have a file called .alias in my $HOME directory with the following content:

alias "my-first-alias"="ls -lha"
alias "my-second-alias="echo 'Hello World'"

I know that if put the line source "$HOME/.alias" in both my .bashrc and .zshrc files I'll be able to create aliases on these shells at the same time in a single file, just so I don't have to manually copy one alias that I have just created in .bashrc to .zshrc...

So far everything is fine... The problem starts with eshell, its alias syntax is different, the last two aliases in eshell syntax would be the following:

alias my-first-alias 'ls -lha'
alias my-second-alias 'echo "Hello World"'

Since its syntax is different I can't just source my .alias file for eshell, I wouldn't like to manually translate my aliases for the eshell syntax all the times that I create a new alias. Is there any standard way of solving problems like this on emacs? Or should I be thinking about how to create a script that will translate my bash aliases to eshell aliases for sourcing it?

1 Answer 1

2

If you go over to EshellAlias on EmacsWiki, there are many solutions to this problem. The one by Edgar Vincent that's currently at the very bottom of the page is the most concise and elegant solution so far.

  (defun eshell-load-bash-aliases ()
    "Read Bash aliases and add them to the list of eshell aliases."
    ;; Bash needs to be run - temporarily - interactively
    ;; in order to get the list of aliases.
      (with-temp-buffer
        (call-process "bash" nil '(t nil) nil "-ci" "alias")
        (goto-char (point-min))
        (while (re-search-forward "alias \\(.+\\)='\\(.+\\)'$" nil t)
          (eshell/alias (match-string 1) (match-string 2)))))

  ;; We only want Bash aliases to be loaded when Eshell loads its own aliases,
  ;; rather than every time `eshell-mode' is enabled.
  (add-hook 'eshell-alias-load-hook 'eshell-load-bash-aliases)

It reads the output of bash -ci alias and loops through them to run eshell/alias on each alias it finds. It should implicitly load your $HOME/.alias file.

The function eshell/alias in the eshell-laod-bash-aliases above writes the list of aliases to the file eshell-aliases-file after each addition of one alias.
That may take long for long alias lists. The following version writes the list only after processing all aliases from bash.

(require 'cl-lib)

(defun eshell-load-bash-aliases ()
  "Read Bash aliases and add them to the list of eshell aliases."
  ;; Bash needs to be run - temporarily - interactively
  ;; in order to get the list of aliases.
  (with-temp-buffer
    (call-process "bash" nil '(t nil) nil "-ci" "alias")
    (goto-char (point-min))
    (cl-letf (((symbol-function 'eshell-write-aliases-list) #'ignore))
      (while (re-search-forward "alias \\(.+\\)='\\(.+\\)'$" nil t)
        (eshell/alias (match-string 1) (match-string 2))))
    (eshell-write-aliases-list)))

;; We only want Bash aliases to be loaded when Eshell loads its own aliases,
;; rather than every time `eshell-mode' is enabled.
(add-hook 'eshell-alias-load-hook 'eshell-load-bash-aliases)
6
  • 1
    Thanks! Even though it worked fine it seems that emacs loads this function on the run all the times that I open eshell for the first time on emacs... Since I have a lot of aliases this solution is slow for my case (it takes around 40 seconds to start)... I'm not sure if there's a workaround with a elisp solution. But I've realized the bash solution on the page from your link works immediately... Probably writing a bash script that watches changes on my .alias file and rewrites a second .alias_eshell file works better for me.
    – raylight
    Commented Nov 2, 2022 at 5:57
  • Just out of curiosity, how many aliases do you have? 40 seconds is a long time just to load aliases.
    – g-gundam
    Commented Nov 2, 2022 at 7:06
  • 1
    Well, it's an old file with aliases and I don't really know all of them by heart. But there are 131 aliases. I've also tested with an empty .alias file and in this case this solution works immediately. Apparently, 131 is a huge number for elisp, I'm not sure if it's only that though...
    – raylight
    Commented Nov 2, 2022 at 7:18
  • 1
    @raylight Please, try again with the modified version at the bottom of this answer.
    – Tobias
    Commented Nov 3, 2022 at 5:12
  • @Tobias Thank you for that speed optimization.
    – g-gundam
    Commented Nov 3, 2022 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.