eshell 如何得到parse之前所有的参数?

(defun eshell/pp2 (&rest r) (pp r))

(defun eshell/pp3 (&rest r)
  (mapconcat #'(lambda (o) (if (stringp o) o (prin1-to-string o))) r " "))
$-> pp2 "a" 1 a1 -b "c d" d\ e
(#("a" 0 1
   (escaped t))
 1 "a1" "-b"
 #("c d" 0 3
   (escaped t))
 #("d e" 1 2
   (escaped t)))
$-> pp3 "a" 1 a1 -b "c d" d\ e 
a 1 a1 -b c d d e

总是丢失了斜杠和引号信息。如何做才能:

(defun eshell/pp4 (&rest r) (do-something)) ;; <- 需要处理参数
$-> pp3 "a" 1 a1 -b "c d" d\ e 
"a" 1 a1 -b "c d" d\ e 
### 得到全部的输入

需求:把所有的输入转发到另外的程序执行,并且完全使用它的语法。 如

$-> z echo "123"
### 调用 zsh 的 echo "123" (保留引号和斜杠)

你已经把斜杠 (\) 用来 Escape 随后的空格了,这是 Shell 的常识,比如以下两种调用,echo 收到的参数一样:

$ echo hello\ world
$ echo "hello world"

至于你的问题,或许可以试试

(defun eshell/foo (&rest r)
  (save-excursion
    ;; 假设命令行只有一行
    (previous-line)
    ;; 跳过 Eshell Prompt
    (eshell-bol)
    ;; 打印整个命令行(包括命令和参数)
    (message "%s" (buffer-substring (point) (line-end-position)))))

测试

Welcome to the Emacs shell

~ λ foo "a" 1 a1 -b "c d" d\ e
foo "a" 1 a1 -b "c d" d\ e
~ λ 

另外值得注意的是,Eshell 的命令行参数处理可以通过 eshell-parse-argument-hook 来扩展,不过我不确定它在这里是否适合。

1 个赞