From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Daniel Colascione Newsgroups: gmane.emacs.devel Subject: RFC: DWIM for killing *shell* and a more process-query-on-exit Date: Sat, 28 Mar 2015 22:58:17 -0700 Message-ID: <55179479.2030109@dancol.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="3wPN9lodAVWw0Tuhn3CsSOwKI9WoqlEg5" X-Trace: ger.gmane.org 1427608723 30264 80.91.229.3 (29 Mar 2015 05:58:43 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 29 Mar 2015 05:58:43 +0000 (UTC) To: Emacs developers Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Mar 29 07:58:42 2015 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 1Yc6F0-0004aI-Io for ged-emacs-devel@m.gmane.org; Sun, 29 Mar 2015 07:58:34 +0200 Original-Received: from localhost ([::1]:56085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yc6Ez-0003RH-PF for ged-emacs-devel@m.gmane.org; Sun, 29 Mar 2015 01:58:33 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41351) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yc6Ev-0003R2-Hs for emacs-devel@gnu.org; Sun, 29 Mar 2015 01:58:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yc6Et-0002tz-UX for emacs-devel@gnu.org; Sun, 29 Mar 2015 01:58:29 -0400 Original-Received: from dancol.org ([2600:3c01::f03c:91ff:fedf:adf3]:54327) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yc6Et-0002tk-GN for emacs-devel@gnu.org; Sun, 29 Mar 2015 01:58:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=dancol.org; s=x; h=Content-Type:Subject:To:MIME-Version:From:Date:Message-ID; bh=p2MThmjc+jWIGnE1Yr/nCRalgdrtuG5XbS6RPnKuZn0=; b=ez6VMtw6FjG79JyJ4C6tvX3jqeI9b4FSWdCi++jrAWQ3Giyji5dOVgEvH93amuipnTONx8pCGRmJbnwm01AXjkDVlYPCU+IReEvi8R2I078JS6oyfRW9UL/NtKMdkjWvaEPncpbpwUmsT5Monr3M7af4sDNObu1FRWgM8NZXycr6P64YeBo7AGaDoNR1YvuJSwG/Ki1OYHZg8RaFFSdCuZ1+KyhMgqXfH7QtT5B0lyTrZDsuleIenjCP0hYbcLlqGj5waRuoqO6xZY8kZtGG24Bnau9KxM/Q09hs5M1m7kVds6rIYH89Gv3kxmq3qdEDEKNTMvVktUr9gEjBBQEbSQ==; Original-Received: from [2601:8:b240:1c1::2b1] by dancol.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1Yc6Ek-0005eh-S7 for emacs-devel@gnu.org; Sat, 28 Mar 2015 22:58:18 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2600:3c01::f03c:91ff:fedf:adf3 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:184500 Archived-At: This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --3wPN9lodAVWw0Tuhn3CsSOwKI9WoqlEg5 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Some terminal emulators ask for confirmation when closing a window only when that window hosts a foreground process group different from the one originally launched. This feature seems useful for Emacs too. This patch 1) obsoletes the {set-,}process-query-on-exit-flag, 2) adds a more flexible mechanism that replaces the flag with a function, and 3) makes shell-mode use this mechanism to dynamically decide whether it's worth asking the user to kill a process. What do you think about the mechanism and about changing the default behavior? diff --git a/lisp/shell.el b/lisp/shell.el index f71d140..6eb409a 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -309,6 +309,19 @@ for Shell mode only." (const :tag "on" t)) :group 'shell) +(defcustom shell-ask-when-killing-buffer 'when-running-job + "When should shell ask for confirmation when killing a buffer? +`t' means to always ask before killing a live process. `nil' +means to always kill without prompting. `when-running-job' means +to ask for confirmation only when killing a shell process +running a child --- that is, only when `process-running-child-p' +returns non-nil." + :type '(choice + (const :tag "never" nil) + (const :tag "when running a subprocess" 'when-running-job) + (other :tag "always" t)) + :group 'shell) + (defvar shell-dirstack nil "List of directories saved by pushd in this buffer's shell. Thus, this does not include the shell's current directory.") @@ -645,6 +658,13 @@ Sentinels will always get the two parameters PROCESS and EVENT." (with-current-buffer buf (insert (format "\nProcess %s %s\n" process event)))))) +(defun shell--check-query-on-exit (process) + "Return whether we should ask user before killing PROCESS." + (cond ((not shell-ask-when-killing-buffer) nil) + ((eq shell-ask-when-killing-buffer 'when-running-job) + (process-running-child-p process)) + (t t))) + ;;;###autoload (defun shell (&optional buffer) "Run an inferior shell, with I/O through BUFFER (which defaults to `*shell*'). @@ -732,7 +752,10 @@ Otherwise, one argument `-i' is passed to the shell.= (if (file-exists-p startfile) startfile) (if (and xargs-name (boundp xargs-name)) (symbol-value xargs-name) - '("-i"))) + '("-i"))) + (set-process-query-on-exit + (get-buffer-process (current-buffer)) + 'shell--check-query-on-exit) (shell-mode))) buffer) diff --git a/lisp/subr.el b/lisp/subr.el index 163a1c4..a3e0511 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1953,9 +1953,23 @@ process." ;; compatibility +(defun process-query-on-exit-flag (process) + "Return whether it is safe to kill PROCESS without asking user. +Return the result of `process-query-on-exit', unless that result +is a function. In that case, call the function and return +its result." + (let ((query-on-exit (process-query-on-exit process))) + (if (functionp query-on-exit) + (funcall query-on-exit process) + query-on-exit))) + +(define-obsolete-function-alias + 'set-process-query-on-exit-flag + 'set-process-query-on-exit "25.1") + (make-obsolete 'process-kill-without-query - "use `process-query-on-exit-flag' or `set-process-query-on-exit-flag'."= + "use `process-query-on-exit' or `set-process-query-on-exit'." "22.1") (defun process-kill-without-query (process &optional _flag) "Say no query needed if PROCESS is running when Emacs is exited. diff --git a/src/process.c b/src/process.c index 2800fa5..9b2ad11 100644 --- a/src/process.c +++ b/src/process.c @@ -703,6 +703,7 @@ make_process (Lisp_Object name) p =3D allocate_process (); /* Initialize Lisp data. Note that allocate_process initializes all Lisp data to nil, so do it only for slots which should not be nil. = */ + p->query_on_exit =3D Qt; pset_status (p, Qrun); pset_mark (p, Fmake_marker ()); @@ -1156,28 +1157,31 @@ This function returns FLAG. */) return flag; } -DEFUN ("set-process-query-on-exit-flag", - Fset_process_query_on_exit_flag, Sset_process_query_on_exit_flag,= +DEFUN ("set-process-query-on-exit", + Fset_process_query_on_exit, Sset_process_query_on_exit, 2, 2, 0, - doc: /* Specify if query is needed for PROCESS when Emacs is exit= ed. -If the second argument FLAG is non-nil, Emacs will query the user before= -exiting or killing a buffer if PROCESS is running. This function -returns FLAG. */) + doc: /* Specify if query is needed for PROCESS when Emacs is +exited. If the second argument FLAG is non-nil, Emacs will query the +user before exiting or killing a buffer if PROCESS is running. +This function returns FLAG. If FLAG is actually a function, Emacs +calls it with a single argument, the process, to decide whether the +process can be killed without user interaction. This function should +execute quickly and not interact with the user. */) (register Lisp_Object process, Lisp_Object flag) { CHECK_PROCESS (process); - XPROCESS (process)->kill_without_query =3D NILP (flag); + XPROCESS (process)->query_on_exit =3D flag; return flag; } -DEFUN ("process-query-on-exit-flag", - Fprocess_query_on_exit_flag, Sprocess_query_on_exit_flag, +DEFUN ("process-query-on-exit", + Fprocess_query_on_exit, Sprocess_query_on_exit, 1, 1, 0, - doc: /* Return the current value of query-on-exit flag for PROCESS. */) + doc: /* Return the current query-on-exit value for PROCESS. */) (register Lisp_Object process) { CHECK_PROCESS (process); - return (XPROCESS (process)->kill_without_query ? Qnil : Qt); + return XPROCESS (process)->query_on_exit; } DEFUN ("process-contact", Fprocess_contact, Sprocess_contact, @@ -1449,7 +1453,7 @@ usage: (make-process &rest ARGS) */) pset_command (XPROCESS (proc), Fcopy_sequence (command)); if (tem =3D Fplist_get (contact, QCnoquery), !NILP (tem)) - XPROCESS (proc)->kill_without_query =3D 1; + XPROCESS (proc)->query_on_exit =3D tem; if (tem =3D Fplist_get (contact, QCstop), !NILP (tem)) pset_command (XPROCESS (proc), Qt); @@ -2653,7 +2657,7 @@ usage: (make-serial-process &rest ARGS) */) pset_filter (p, Fplist_get (contact, QCfilter)); pset_log (p, Qnil); if (tem =3D Fplist_get (contact, QCnoquery), !NILP (tem)) - p->kill_without_query =3D 1; + p->query_on_exit =3D tem; if (tem =3D Fplist_get (contact, QCstop), !NILP (tem)) pset_command (p, Qt); eassert (! p->pty_flag); @@ -3433,7 +3437,7 @@ usage: (make-network-process &rest ARGS) */) pset_filter (p, filter); pset_log (p, Fplist_get (contact, QClog)); if (tem =3D Fplist_get (contact, QCnoquery), !NILP (tem)) - p->kill_without_query =3D 1; + p->query_on_exit =3D tem; if ((tem =3D Fplist_get (contact, QCstop), !NILP (tem))) pset_command (p, Qt); p->pid =3D 0; @@ -7444,8 +7448,8 @@ The variable takes effect when `start-process' is called. */); defsubr (&Sprocess_sentinel); defsubr (&Sset_process_window_size); defsubr (&Sset_process_inherit_coding_system_flag); - defsubr (&Sset_process_query_on_exit_flag); - defsubr (&Sprocess_query_on_exit_flag); + defsubr (&Sset_process_query_on_exit); + defsubr (&Sprocess_query_on_exit); defsubr (&Sprocess_contact); defsubr (&Sprocess_plist); defsubr (&Sset_process_plist); diff --git a/src/process.h b/src/process.h index 36979dc..4ba2fb6 100644 --- a/src/process.h +++ b/src/process.h @@ -105,6 +105,9 @@ struct Lisp_Process Lisp_Object gnutls_cred_type; #endif + /* Value of the process query-on-exit flag or function. */ + Lisp_Object query_on_exit; + /* After this point, there are no Lisp_Objects any more. */ /* alloc.c assumes that `pid' is the first such non-Lisp slot. */ @@ -139,9 +142,6 @@ struct Lisp_Process unsigned int adaptive_read_buffering : 2; /* Skip reading this process on next read. */ bool_bf read_output_skip : 1; - /* True means kill silently if Emacs is exited. - This is the inverse of the `query-on-exit' flag. */ - bool_bf kill_without_query : 1; /* True if communicating through a pty. */ bool_bf pty_flag : 1; /* Flag to set coding-system of the process buffer from the --3wPN9lodAVWw0Tuhn3CsSOwKI9WoqlEg5 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCAAGBQJVF5R5AAoJEN4WImmbpWBlPMMP/jQ5Hg44m76o/7QdafuryCLu xjCVgh2DbuEXxPl6rOEHLG8V34y1nIP80ezNLJx9i3ilZtjo0nDn4sXG5Z1cPkJa qJHNg5JxkT6bbglUhBdkr6h+REXBQo7gPbR8ZUQbSyDXCEOIolXfkwFiyR8IVnmu FToOA30F6cHQXRbIyh3VDr3MXZvPtL5WonH2b+b6eLKbJ3fPx6RzaD2kfAaE+Lmb 7ssCrUEKzwLF6p4x4o94OiXEh/yNeqtOcL7njlDp6w+9ErP0hqzTZpuGKnHzaGVy fvRvAmGRt5sL/Xd1lnZbaHLQ/MyYUho5KQr+e/l+WIGqNja7mnU5pHeFHO2BspiZ whmxeaZxLFlMGFGEowTWex1s1tTUCk47yLj1CyjTRMi74MshfJdVeJw+l2aexTCc ZPYhDxepGCddjFcaKeo/4lqPp0mesfXBxVqH762ruFGAczOWRw41R5HphzikelEL S0SeuNN9kbwgcOdefIyi2gi49ybSwm16Vytna5fTimXVlX0/rHLyTF9jNOMGljry hnrFy0x//Xog72SicXwZUR9sSHzxetO5O+w5uXFHpCFbfhewZtZgAHo1HtuJaIui mL4Mr71hc4rxPUrJTOG9e6S9mlcL9Nr6eORCFqTXbGK0VLjYPA6OCi8bUlyU9Qlo KWh4NzugLceRPTr99bRw =YGSM -----END PGP SIGNATURE----- --3wPN9lodAVWw0Tuhn3CsSOwKI9WoqlEg5--