2

I'm trying to start using eshell in place of bash within emacs, but I rely heavily on bash functions that I have written over the years. I'd like to configure eshell to invoke bash whenever a "command not found" condition occurs, in case the command in question is implemented as a bash function.

There is a variable tantalizingly named eshell-alternate-command-hook that sounds like it is made to order, but my lack of elisp skill is interfering with my success I think.

This is my best effort:

(add-hook 'eshell-alternate-command-hook 'invoke-bash t t)
(defun invoke-bash (command args)
  (throw 'eshell-replace-command
     (list "bash -c" command args)))

But when I test it, it doesn't work:

c:/temp $ lsd
Wrong number of arguments: (lambda (command args) (throw (quote eshell-replace-command) (list "bash -c" command args))), 1
c:/temp $ 
N.N.
  • 8,336
  • 12
  • 54
  • 94
wytten
  • 2,800
  • 1
  • 21
  • 38

2 Answers2

2

This is what I eventually came up with:

(defun invoke-bash (command)
(progn 
  (setq invoke-bash-cmd (concat "bash -c \"" command " " (mapconcat 'identity eshell-last-arguments " ") "\""))
  (message invoke-bash-cmd)
  (throw 'eshell-replace-command
     (eshell-parse-command invoke-bash-cmd))))
wytten
  • 2,800
  • 1
  • 21
  • 38
  • try something like this: https://gist.github.com/1903146, although I hadn't tried it – Alex Ott Feb 24 '12 at 19:28
  • Thanks, I see that progn is vestigial and not necessary, although it didn't seem to work when I used 'let' instead of 'setq'. (Maybe I did somthing wrong) – wytten Feb 25 '12 at 16:55
  • strange that `let` doesn't work for you. primary purpose of `let` is creation of variables in local context. In your code, because `invoke-bash-cmd` isn't declared in local context, it will be global variable – Alex Ott Feb 26 '12 at 11:45
0

I'm not eshell guru, but in the place where this hook is used, I see that it receives only one argument - command, that you trying to execute, so your code could look like

(add-hook 'eshell-alternate-command-hook 'invoke-bash)
(defun invoke-bash (command)
  (throw 'eshell-replace-command
     (list "bash -c" command)))

but it doesn't work, because you need to return elisp function, not name of command (according to documentation). If you want to run bash, then you need to return string with full path to it, but I hadn't found how to pass additional arguments to bash. Maybe you can find more in corresponding section on Emacs Wiki?

Alex Ott
  • 80,552
  • 8
  • 87
  • 132
  • That helped; I've gotten further but am stuck again: `(defun invoke-bash (command) (throw 'eshell-replace-command (eshell-parse-command (concat "bash -c " command eshell-last-arguments)))) ` If the argument is "pom.xml" I get the message 'Wrong type argument: characterp, "pom.xml"' so I feel like I'm close now. – wytten Feb 24 '12 at 13:23