如何向Slime REPL输入缓冲区写入字符串?Common Lisp Shell问题
问题:Common Lisp Shell实现元命令占位符输入编辑功能
需求说明
我正在用Common Lisp编写一款Shell程序,读取用户输入的命令并执行后返回输出。当用户输入元命令时,希望在输入缓冲区写入占位符,让用户可直接按回车执行该命令,或像编辑自身输入内容一样编辑它。
当前实现代码
(defun eval-print (command-executor command) (format t "~a~%" (funcall command-executor command))) (defun cmd-exec-local (command) "Execute a command in the local shell" (trim (uiop:run-program command :output :string))) (defun shell (command-executor &optional placeholder) "Simulate a REPL" (progn (if placeholder (format t ">>> ~a" placeholder) ; 这里尝试显示占位符 (format t ">>> ")) (let ((command (read-line))) ; 检查用户是否输入元命令,否则执行输入内容 (cond ((string= "@exit" command) (format t "Bye!~%")) ; 退出Shell ((string= "@bashrev" command) (shell command-executor *bash-rev*)) ; Bash反向Shell ((string= "@info" command) (shell command-executor "whoami")) ; 系统信息 (t (eval-print command-executor command) (shell command-executor)))))) ; 执行命令
问题现象
运行时占位符仅输出到标准输出,无法被read-line读取,按回车也不会执行;手动输入的命令则正常:
PENTESTING> (shell #'cmd-exec-local) >>> @info >>> whoami ; 这只是输出到标准输出,按回车无任何执行 >>> whoami ; 用户手动输入的内容,按回车可正常得到结果 kali >>> @exit Bye!
解决方案
问题核心是format t仅将文本输出到终端,并未写入输入缓冲区,read-line只会读取用户实际输入的内容。要实现编辑占位符的功能,需使用终端控制库操作输入行,推荐使用cl-readline(Common Lisp版GNU Readline绑定)。
步骤1:安装cl-readline
通过Quicklisp安装:
(ql:quickload :cl-readline)
步骤2:修改代码使用cl-readline替代read-line
利用rl:read-line函数,它支持预填充初始文本(占位符),用户可直接编辑或按回车执行:
(defun eval-print (command-executor command) (format t "~a~%" (funcall command-executor command))) (defun cmd-exec-local (command) "Execute a command in the local shell" (trim (uiop:run-program command :output :string))) (defun shell (command-executor &optional placeholder) "Simulate a REPL with editable placeholder support" (let ((command (rl:read-line :prompt (if placeholder ">>> " ">>> ") :initial-text (or placeholder "")))) (cond ((string= "@exit" command) (format t "Bye!~%")) ((string= "@bashrev" command) (shell command-executor *bash-rev*)) ((string= "@info" command) (shell command-executor "whoami")) (t (eval-print command-executor command) (shell command-executor)))))
说明
rl:read-line的:initial-text参数会将占位符文本填充到输入行,用户可直接编辑或按回车提交。- 该方案依赖GNU Readline的终端控制能力,能实现类似Bash的输入编辑体验,包括光标移动、文本修改等。
- 若无需完整Readline功能,直接操作终端输入缓冲区需依赖系统特定API(如Unix的
tcsetattr),实现复杂且跨平台性差,使用cl-readline是更简洁的选择。
内容的提问来源于stack exchange,提问作者Antonio Solana
相关产品推荐
相关产品推荐

