From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.bugs Subject: bug#22679: 25.0.91; ibuffer-do-shell-command-pipe truncate output Date: Wed, 24 Aug 2016 00:08:57 +0900 (JST) Message-ID: References: <7oa66k9es.fsf@fencepost.gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset=US-ASCII X-Trace: blaine.gmane.org 1471965029 11663 195.159.176.226 (23 Aug 2016 15:10:29 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 23 Aug 2016 15:10:29 +0000 (UTC) User-Agent: Alpine 2.20 (DEB 67 2015-01-07) Cc: Tino Calancha , 22679@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Aug 23 17:10:19 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bcDLH-0002Lc-EF for geb-bug-gnu-emacs@m.gmane.org; Tue, 23 Aug 2016 17:10:19 +0200 Original-Received: from localhost ([::1]:47017 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcDLE-0005ZE-O0 for geb-bug-gnu-emacs@m.gmane.org; Tue, 23 Aug 2016 11:10:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52784) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcDL5-0005VF-Pd for bug-gnu-emacs@gnu.org; Tue, 23 Aug 2016 11:10:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bcDL0-00067j-JJ for bug-gnu-emacs@gnu.org; Tue, 23 Aug 2016 11:10:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:40345) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcDL0-00067f-Et for bug-gnu-emacs@gnu.org; Tue, 23 Aug 2016 11:10:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1bcDL0-0003IB-B1 for bug-gnu-emacs@gnu.org; Tue, 23 Aug 2016 11:10:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Tino Calancha Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 23 Aug 2016 15:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 22679 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 22679-submit@debbugs.gnu.org id=B22679.147196495812596 (code B ref 22679); Tue, 23 Aug 2016 15:10:02 +0000 Original-Received: (at 22679) by debbugs.gnu.org; 23 Aug 2016 15:09:18 +0000 Original-Received: from localhost ([127.0.0.1]:38057 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bcDKD-0003Gz-Sr for submit@debbugs.gnu.org; Tue, 23 Aug 2016 11:09:18 -0400 Original-Received: from mail-pf0-f194.google.com ([209.85.192.194]:32841) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bcDK8-0003Gd-Am for 22679@debbugs.gnu.org; Tue, 23 Aug 2016 11:09:12 -0400 Original-Received: by mail-pf0-f194.google.com with SMTP id i6so8455196pfe.0 for <22679@debbugs.gnu.org>; Tue, 23 Aug 2016 08:09:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:date:to:cc:subject:in-reply-to:message-id:references :user-agent:mime-version; bh=hjff9df3hzByiK9ZjH7SKTGt+93IJAJ5XjF8qX31XeU=; b=HfzuugdqPzwbe6P+9piz7UetyzE14rttWHT86KHZI11V+CPAEW2n1p0WCejsyEnWxQ ZamIPM5T1bcsa+/CRXeLqqA3HZ2SjQUY1FkfzbU1zA5vKaBIPAAijehPT00iCqmXLfcv 4Wtq6zCZrRGa+U1A4U9XDaSfOCkAVdG274ngsW0+BTmTJfukpL7CQlJcIk6l5bepyQRu 5/nMsa4itQmnfK0+AydKy01YieeZiy3ACuAON3+UJ/kEvlSSCfEoNiQ33aqScWKEAIIR cuI9CkHryPgRh4g/Vq+0CbLBmpIAvVdsMc7zSwnUWaqYE2kBS+qbFVmdAt0NsxnJ8eyV qpLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:date:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version; bh=hjff9df3hzByiK9ZjH7SKTGt+93IJAJ5XjF8qX31XeU=; b=iulli5TTRE7Wz5Sk73WFozWCxFyoSIy3+rk2TfQsHNQnGRj5YV457hFz2UXpYGGjgS XOGSDmJX6VorfKuasKJBq557MoTjKQb6C/9qLlWl4PGeOO0mH6n1h0FWKWvAjmZcsPpY jQA9CHSkan+8F9okrVnZV/eZNfvrTr8gDT1h9yqdeKS+TIv1N33qfCgO04G5dawNLei7 3/i3fpf5XjEC8A8wdpxAgaBbeMx8DllPml1QocYgCuDzq0xZA9poDqK09JniUWlkEF5k U7gfqQQf7k/CN5VKhqIKJeKfCrB1ygD0bAaQeqOhCQL5FOOFZYkJUviKR5ctsApThL6v EA1A== X-Gm-Message-State: AEkoouuf+DKOjyW64lLE90IcaWJRH8lHG8+f6iBKaTUOnOuiKIS8QPRdWLEOXePTfQaVjw== X-Received: by 10.98.22.212 with SMTP id 203mr54477668pfw.74.1471964942395; Tue, 23 Aug 2016 08:09:02 -0700 (PDT) Original-Received: from calancha-pc ([240f:6e:c00e:1:6875:2e94:598b:96cb]) by smtp.gmail.com with ESMTPSA id xx7sm6585242pac.3.2016.08.23.08.08.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Aug 2016 08:09:01 -0700 (PDT) X-Google-Original-From: Tino Calancha X-X-Sender: calancha@calancha-pc In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:122547 Archived-At: On Mon, 22 Aug 2016, Stefan Monnier wrote: > I understand. I do not suggest to improve shell-command. > I suggest instead to extract from shell-command a new Elisp function > which includes the part of shell-command that you need, and then rewrite > shell-command by making it use the new function. > > So shell-command would still work exactly as before, but its > implementation would now be spread over 2 functions, the inner one of > which would be useful to other Elisp libraries such as ibuffer. Thank you Stefan, i understand now. Its a good idea. See the patch below. > Hmm... I now see this new variable. It has several problems indeed. > The "set the point" part is weird and I'm not sure it makes much sense > to fold it this way into the same var as the "don-t erase" part. If you could write a few lines with yor main concerns about this option here: http://lists.gnu.org/archive/html/emacs-devel/2016-07/msg00610.html i guess it might encourage others to give their opinion helping to decide if we keep the option, discard it, or implement it in a better way. > Here, for example, I'd expect maybe something like > > (new-shell-command-on-region > (point-min) (point-max) command)) > > Maybe with one or two new additional args. Or maybe > > (let ((out-buf (get-buffer-create shell-command-buffer-name))) > (with-current-buffer out-buf (goto-char (point-max))) > (call-shell-on-region (point-min) (point-max) > out-buf command))) I have called the new function: call-shell-region in analogy with call-process-region; but call-shell-on-region seems a little more descriptive. How should i call it? Do you thing the call-shell-region discussion should move to emacs-devel list? > I think we should first aim at a simple and clean fix, yes. Following patch, concerning just the lisp/ibuf-ext, (the call-shell-command part eventually should go to a separated commit) looks quite simple (compared with my first patch in this report): ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >From 9ba85fdf3c5543e87a7b1905b2404a334891581f Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Tue, 23 Aug 2016 23:46:37 +0900 Subject: [PATCH] call-shell-region: New defun Fix Bug#22679 * lisp/subr.el (call-shell-region): New defun; execute a command in an inferior shell with the buffer region as input. * lisp/ibuf-ext.el (shell-command-pipe, shell-command-pipe-replace): Use it (Bug#22679). * lisp/simple.el (shell-command-on-region): Idem. * lisp/ibuf-ext.el (shell-command-file): Use call-process-shell-command instead of shell-command. If FILE, the file that the buffer object is visiting, exists and the buffer object is up-to-date, then use FILE instead of creating a temporary file (Bug#22679). * doc/lispref/processes.texi: Document call-shell-region in the manual. ;* etc/NEWS: Add entry for this new function. --- doc/lispref/processes.texi | 20 +++++++++++++------- etc/NEWS | 4 ++++ lisp/ibuf-ext.el | 33 +++++++++++++++++++-------------- lisp/simple.el | 36 +++++++++++++++--------------------- lisp/subr.el | 22 ++++++++++++++++++++++ 5 files changed, 73 insertions(+), 42 deletions(-) diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index cd12012..e043578 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -492,20 +492,17 @@ Synchronous Processes @end smallexample For example, the @code{shell-command-on-region} command uses -@code{call-process-region} in a manner similar to this: +@code{call-shell-region} in a manner similar to this: @smallexample @group -(call-process-region +(call-shell-region start end - shell-file-name ; @r{name of program} + command ; @r{shell command} nil ; @r{do not delete region} - buffer ; @r{send output to @code{buffer}} - nil ; @r{no redisplay during output} - "-c" command) ; @r{arguments for the shell} + buffer) ; @r{send output to @code{buffer}} @end group @end smallexample -@c It actually uses shell-command-switch, but no need to mention that here. @end defun @defun call-process-shell-command command &optional infile destination display @@ -525,6 +522,15 @@ Synchronous Processes supported, but strongly discouraged. @end defun +@defun call-shell-region start end command &optional delete destination +This function sends the text from @var{start} to @var{end} as +standard input to an inferior shell running @var{command}. This function +is similar than @code{call-process-region}, with process being a shell. +The arguments @code{delete}, @code{destination} and the return value +are like in @code{call-process-region}. +Note that this funtion doesn't accept additional arguments. +@end defun + @defun shell-command-to-string command This function executes @var{command} (a string) as a shell command, then returns the command's output as a string. diff --git a/etc/NEWS b/etc/NEWS index 494a091..d30d1fa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -56,6 +56,10 @@ affected by this, as SGI stopped supporting IRIX in December 2013. * Changes in Emacs 25.2 +++ +** The new funtion 'call-shell-region' executes a command in an +inferior shell with the buffer region as input. + ++++ ** The new user option 'shell-command-not-erase-buffer' controls if the output buffer is erased between shell commands; if non-nil, the output buffer is not erased; this variable also controls where diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index f93957e..a34c264 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -352,8 +352,10 @@ shell-command-pipe (:interactive "sPipe to shell command: " :opstring "Shell command executed on" :modifier-p nil) - (shell-command-on-region - (point-min) (point-max) command)) + (let ((out-buf (get-buffer-create "*Shell Command Output*"))) + (with-current-buffer out-buf (goto-char (point-max))) + (call-shell-region (point-min) (point-max) + command nil out-buf))) ;;;###autoload (autoload 'ibuffer-do-shell-command-pipe-replace "ibuf-ext") (define-ibuffer-op shell-command-pipe-replace (command) @@ -364,8 +366,8 @@ shell-command-pipe-replace :dangerous t :modifier-p t) (with-current-buffer buf - (shell-command-on-region (point-min) (point-max) - command nil t))) + (call-shell-region (point-min) (point-max) + command 'delete buf))) ;;;###autoload (autoload 'ibuffer-do-shell-command-file "ibuf-ext") (define-ibuffer-op shell-command-file (command) @@ -373,16 +375,19 @@ shell-command-file (:interactive "sShell command on buffer's file: " :opstring "Shell command executed on" :modifier-p nil) - (shell-command (concat command " " - (shell-quote-argument - (or buffer-file-name - (let ((file - (make-temp-file - (substring - (buffer-name) 0 - (min 10 (length (buffer-name))))))) - (write-region nil nil file nil 0) - file)))))) + (let ((file (and (not (buffer-modified-p)) + buffer-file-name)) + (out-buf (get-buffer-create "*Shell Command Output*"))) + (when (or (null file) (not (file-exists-p file))) + (setq file + (make-temp-file + (substring + (buffer-name) 0 + (min 10 (length (buffer-name)))))) + (write-region nil nil file nil 0)) + (with-current-buffer out-buf (goto-char (point-max))) + (call-process-shell-command (format "%s %s" command file) + nil out-buf nil))) ;;;###autoload (autoload 'ibuffer-do-eval "ibuf-ext") (define-ibuffer-op eval (form) diff --git a/lisp/simple.el b/lisp/simple.el index 51b24bb..dbfaae3 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3651,10 +3651,7 @@ shell-command-on-region output) (with-temp-buffer (insert input) - (call-process-region (point-min) (point-max) - shell-file-name t t - nil shell-command-switch - command) + (call-shell-region (point-min) (point-max) command 'delete t) (setq output (split-string (buffer-string) "\n"))) (goto-char start) (funcall region-insert-function output)) @@ -3667,11 +3664,10 @@ shell-command-on-region (goto-char start) (and replace (push-mark (point) 'nomsg)) (setq exit-status - (call-process-region start end shell-file-name replace - (if error-file - (list t error-file) - t) - nil shell-command-switch command)) + (call-shell-region start end command replace + (if error-file + (list t error-file) + t))) ;; It is rude to delete a buffer which the command is not using. ;; (let ((shell-buffer (get-buffer "*Shell Command Output*"))) ;; (and shell-buffer (not (eq shell-buffer (current-buffer))) @@ -3694,13 +3690,12 @@ shell-command-on-region (delete-region (max start end) (point-max)) (delete-region (point-min) (min start end)) (setq exit-status - (call-process-region (point-min) (point-max) - shell-file-name t - (if error-file - (list t error-file) - t) - nil shell-command-switch - command))) + (call-shell-region (point-min) (point-max) + command 'delete + (if error-file + (list t error-file) + t) + ))) ;; Clear the output buffer, then run the command with ;; output there. (let ((directory default-directory)) @@ -3709,11 +3704,10 @@ shell-command-on-region (setq default-directory directory)) (shell-command--save-pos-or-erase))) (setq exit-status - (call-process-region start end shell-file-name nil - (if error-file - (list buffer error-file) - buffer) - nil shell-command-switch command))) + (call-shell-region start end command nil + (if error-file + (list buffer error-file) + buffer)))) ;; Report the output. (with-current-buffer buffer (setq mode-line-process diff --git a/lisp/subr.el b/lisp/subr.el index 8ab1178..a33f997 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3078,6 +3078,28 @@ process-file-shell-command infile buffer display (if (file-remote-p default-directory) "-c" shell-command-switch) (mapconcat 'identity (cons command args) " "))) + +(defun call-shell-region (start end command &optional delete buffer) +"Send text from START to END as input to an inferior shell running COMMAND. +Delete the text if fourth arg DELETE is non-nil. + +Insert output in BUFFER before point; t means current buffer; nil for + BUFFER means discard it; 0 means discard and don't wait; and `(:file + FILE)', where FILE is a file name string, means that it should be + written to that file (if the file already exists it is overwritten). +BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, +REAL-BUFFER says what to do with standard output, as above, +while STDERR-FILE says what to do with standard error in the child. +STDERR-FILE may be nil (discard standard error output), +t (mix it with ordinary output), or a file name string. + +If BUFFER is 0, `call-shell-region' returns immediately with value nil. +Otherwise it waits for COMMAND to terminate +and returns a numeric exit status or a signal description string. +If you quit, the process is killed with SIGINT, or SIGKILL if you quit again." +(call-process-region start end + shell-file-name delete buffer nil + shell-command-switch command)) ;;;; Lisp macros to do various things temporarily. -- 2.8.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; In GNU Emacs 25.1.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.20.7) of 2016-08-23 built on calancha-pc Repository revision: f345fdd7e64064194a9235406971f62b9da09ae2 Tino