为compilation-buffer增加输入功能
Emacs的 compile
命令是一个未被充分利用的工具. 它允许你运行任意的构建工具并且为多种编程语言提供错误高亮与快速掉转到错误的功能. 但是许多的Emacs使用者依然习惯于切换到终端下运行make,lein test以及bundle exec. 然而 compile
命令有一个限制,那就是compilation buffer并不是真正的shell,因此若正在运行的命令需要用户输入额外信息(即使是简单的y/n确认),也没有办法输入这些信息.
幸运的是,为其增加输入功能并不复杂. 下面的代码片段定义了两个命令. 第一个命令会提示你输入要输入的信息,然后将你的输入附上回车符,一起传递到低层的终端上, 该命令用于提示输入时或在REPL循环中. 第二个命令只是简单的传递我们按下得键, 主要用于回答y/n问题,或者使用 C-d
或 C-j
快速退出REPL.
(defun endless/send-input (input &optional nl) "Send INPUT to the current process. Interactively also sends a terminating newline." (interactive "MInput: \nd") (let ((string (concat input (if nl "\n")))) ;; This is just for visual feedback. (let ((inhibit-read-only t)) (insert-before-markers string)) ;; This is the important part. (process-send-string (get-buffer-process (current-buffer)) string))) (defun endless/send-self () "Send the pressed key to the current process." (interactive) (endless/send-input (apply #'string (append (this-command-keys-vector) nil)))) (define-key compilation-mode-map (kbd "C-c i") #'endless/send-input) (dolist (key '("\C-d" "\C-j" "y" "n")) (define-key compilation-mode-map key #'endless/send-self))
几年来我一直忽略这个缺陷(This is something I’ve run into for years), 但是最终,我还是决定修正它,因为它使得当我的代码中包含binding.pry(它会产生一个REPL)时,无法在compilation buffer中运行Ruby的rspec命令. 现在我可以通过先按下 C-c i
来与REPL交互,也可以使用 C-d
快速退出这个REPL. 若你也遇到与我一样的情况,你还需要在你的 .pryrc
文件中设置下面选项.pryrc file.
Pry.config.pager = false if ENV["INSIDE_EMACS"]