From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Frank Fischer Newsgroups: gmane.emacs.devel Subject: Eshell: copy output of visual commands Date: Sat, 17 Aug 2013 10:07:24 +0200 Message-ID: <20130817100724.620cd7c7@mawo> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1376727625 15990 80.91.229.3 (17 Aug 2013 08:20:25 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 17 Aug 2013 08:20:25 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Aug 17 10:20:26 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VAbkH-0002aB-H2 for ged-emacs-devel@m.gmane.org; Sat, 17 Aug 2013 10:20:25 +0200 Original-Received: from localhost ([::1]:34926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAbkH-0007Kf-3I for ged-emacs-devel@m.gmane.org; Sat, 17 Aug 2013 04:20:25 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39576) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAbk6-0007Jh-DB for emacs-devel@gnu.org; Sat, 17 Aug 2013 04:20:22 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VAbjy-0007zC-Ux for emacs-devel@gnu.org; Sat, 17 Aug 2013 04:20:14 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:57952) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAbjy-0007xe-LC for emacs-devel@gnu.org; Sat, 17 Aug 2013 04:20:06 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1VAbjw-0002JH-4V for emacs-devel@gnu.org; Sat, 17 Aug 2013 10:20:04 +0200 Original-Received: from i59f6b3a7.versanet.de ([89.246.179.167]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 17 Aug 2013 10:20:04 +0200 Original-Received: from frank-fischer by i59f6b3a7.versanet.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 17 Aug 2013 10:20:04 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 101 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: i59f6b3a7.versanet.de X-Newsreader: Claws Mail 3.9.1 (GTK+ 2.24.17; x86_64-pc-linux-gnu) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:162836 Archived-At: I want to use certain commands from eshell that have colourized output. Because eshell is not a full terminal emulator it relies on ansi-term to execute these commands. However, when the command has finished the ansi-term buffer is deleted. Hence, if a "visual" commands does not wait for user input but just prints something to the screen and then exits immediately, its output is lost (e.g. I use mercurial with colourized output declared as visual commands, but commands like "hg log" just print something to the screen and then exit). The idea is to copy the final output of the commands, i.e. the content of the terminal buffer after the command has finished, back to the eshell buffer. This gives eshell a behaviour quite close to standard terminal emulators in these situations. For those who are interested, I use the following modifications of eshell (the changed lines are marked): ``` (defadvice eshell-exec-visual (around fifr (&rest args) activate) "Store insertion point for result of visual command." (let* (eshell-interpreter-alist (interp (eshell-find-interpreter (car args))) (program (car interp)) (args (eshell-flatten-list (eshell-stringify-list (append (cdr interp) (cdr args))))) (term-buf (generate-new-buffer (concat "*" (file-name-nondirectory program) "*"))) (eshell-buf (current-buffer))) (save-current-buffer (switch-to-buffer term-buf) (term-mode) (set (make-local-variable 'term-term-name) eshell-term-name) (make-local-variable 'eshell-parent-buffer) (setq eshell-parent-buffer eshell-buf) ;; CHANGED (make-local-variable 'eshell-visual-point) (setq eshell-visual-point (with-current-buffer eshell-buf (set-marker (make-marker) (1- (point))))) ;; CHANGED (term-exec term-buf program program nil args) (let ((proc (get-buffer-process term-buf))) (if (and proc (eq 'run (process-status proc))) (set-process-sentinel proc 'eshell-term-sentinel) (error "Failed to invoke visual command"))) (term-char-mode) (if eshell-escape-control-x (term-set-escape-char ?\C-x)))) nil) (defun fifr/eshell-copy-visual-output (shell-buf proc-buf) "Copy result of visual command back to the shell buffer." (and (buffer-live-p shell-buf) (buffer-live-p proc-buf) (prog1 t (let ((txt (with-current-buffer proc-buf (buffer-substring (point-min) (point-max)))) (mrk (with-current-buffer proc-buf eshell-visual-point))) ;; Remove useless empty lines at the end (save-match-data (setq txt (substring txt 0 (string-match "^[[:space:]\n]*\\'"txt)))) (with-current-buffer shell-buf (save-excursion (goto-char (1+ mrk)) (set-marker mrk nil) (insert txt))))))) (defadvice eshell-term-sentinel (around fifr (proc string) activate) "Maybe copy the content of the term buffer back to the shell buffer." (let ((proc-buf (process-buffer proc))) (when (and proc-buf (buffer-live-p proc-buf) (not (eq 'run (process-status proc))) (= (process-exit-status proc) 0)) (if (eq (current-buffer) proc-buf) (let ((buf (and (boundp 'eshell-parent-buffer) eshell-parent-buffer (buffer-live-p eshell-parent-buffer) eshell-parent-buffer))) (if buf (switch-to-buffer buf)))) ;; CHANGED (if (with-current-buffer proc-buf (fifr/eshell-copy-visual-output eshell-parent-buffer proc-buf)) (kill-buffer proc-buf) (with-current-buffer proc-buf (switch-to-buffer proc-buf) (local-set-key "q" #'(lambda () (interactive) (kill-buffer (current-buffer))))))))) ;; CHANGED ``` Best regards, Frank