From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Christopher Monsanto Newsgroups: gmane.emacs.devel Subject: Re: replacing process sentinels and filters with hooks Date: Mon, 1 Oct 2012 12:53:08 -0400 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: ger.gmane.org 1349110793 19609 80.91.229.3 (1 Oct 2012 16:59:53 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 1 Oct 2012 16:59:53 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 01 18:59:58 2012 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 1TIjLN-0005m7-Tn for ged-emacs-devel@m.gmane.org; Mon, 01 Oct 2012 18:59:46 +0200 Original-Received: from localhost ([::1]:52708 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIjFt-0005NT-6N for ged-emacs-devel@m.gmane.org; Mon, 01 Oct 2012 12:54:05 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:34385) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIjFk-0005N5-Iw for emacs-devel@gnu.org; Mon, 01 Oct 2012 12:54:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TIjFe-0001rn-C9 for emacs-devel@gnu.org; Mon, 01 Oct 2012 12:53:56 -0400 Original-Received: from mail-we0-f169.google.com ([74.125.82.169]:40287) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TIjFe-0001rV-2o for emacs-devel@gnu.org; Mon, 01 Oct 2012 12:53:50 -0400 Original-Received: by weyu3 with SMTP id u3so3345683wey.0 for ; Mon, 01 Oct 2012 09:53:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:x-gm-message-state; bh=MgCbXpPV0RbxHoLEnAyGLcWG6pmSnYHekDKPdP12Vcg=; b=ak+IOweqGl4nLqob2zZ804Tk1iIDSTTC77vcQTA6nQfBlNcfVsCCrQ1Ac6zraCshD1 IcP3vwpKFAIHhRP2goRlAu/n1OADDqbHLKwqr2RnrhJHwyl/eGRzKXLLv1lrJj8U1Azt CRxj0nz18ROCoOr1xgmJeUsFaQnAq16mV7g4xoCIDCX8OrLE2ggK6IC79HMG89V2uqZF j7HHdt2uiylOWs3o1+yi79vXcizMQPmu0qXitVErFQIjF+1RaeyicNjeFUq6vhwG3FZx 5e/Plr4Aw4pDI5LyrHqz8nFmk7oxHlFfxMbqbKuOb5GGc+XUw16nxeXlXOBtB94JU/Ep Ui4A== Original-Received: by 10.180.73.76 with SMTP id j12mr15945934wiv.11.1349110429015; Mon, 01 Oct 2012 09:53:49 -0700 (PDT) Original-Received: by 10.223.96.15 with HTTP; Mon, 1 Oct 2012 09:53:08 -0700 (PDT) In-Reply-To: X-Gm-Message-State: ALoCoQlt8MEcRyOf8CBe/3sXP/n2ZZthCbw9OQNSJ4X6ZXMFKQFTKPchC3lfjb7E9g0UIHaNG1Gz X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 74.125.82.169 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:153858 Archived-At: My mistake, I don't think I posted this response to the list. Sorry for double message, Stefan. On Mon, Oct 1, 2012 at 11:34 AM, Stefan Monnier wrote: >> 1) Process filters and sentinels do not fit in with the rest of the >> Emacs API. In every other API that I can think of that involves a user >> callback, the hooks API is used. > > Hooks are used normally for un-planned interaction between two > unrelated packages. OTOH process sentinels and filters are typically > tightly linked to their process, the package that creates the process > being usually the same that provides the sentinels and filters. > 3) It's hard for more than one interested party to interact with a process. > > Indeed, tho it's rarely needed. Concrete examples would be useful for > this discussion. This is not my experience working with the shell and comint packages. For instance, comint has its own hook, comint-input-filter-functions, for doing exactly what this proposal suggests (sans sentinels). This hook for example lets shell check for cd/pushd when doing directory tracking. shell is lucky that comint doesn't use a sentinel, because it sometimes steals the process sentinel to save the shell history on exit. If comint adds its own sentinel (which isn't too unreasonable, considering that comint creates the process) then shell's code is broken; the two will fight with each other. And shell does *assume* comint doesn't use a sentinel, because it doesn't setup any code to call "the next sentinel". Perhaps that's not such a big deal, because both modes are in the Emacs tree, and we can just fix that. What *is* a big deal is that it would break anyone else's code to add such a sentinel to comint. There is no way either to add a "comint-sentinel-functions" because there is no way comint can guarantee that its sentinel is running (due to assumptions like the one shell mode made). In other words, it's really nasty that having or not having a sentinel/filter is apart of the API of your program. One could say "it's a best practice to always remember the last sentinel". And I would respond, "well, if it is a best practice, then why doesn't the API use hooks?" For another example, I wrote a package similar to popwin (https://github.com/m2ym/popwin-el) that uses the shell. On a key press, I can open a temporary shell in a small popped window, which is pretty handy. It is also pretty handy that when I exit the shell (by typing exit in bash) the shell window is destroyed. But I can't know if I have exited unless I have a sentinel. And I have to share the sentinel with shell-write-history-on-exit. > Just would work as well. I disagree. Ideally I'd like to use pcase to check the three alternatives; to do this, I either have to ensure that the (input ...) case is last, or I have to use a more complicated pattern involving (pred stringp). And with the proposed API, you do have to check--you cannot simply just assume that your argument is a string. So let's make it as easy as possible to check. > So your proposal can be decomposed in 3 parts: > ... > - provide a standard way to combine sentinels and filters, which is to > run them in sequence (for sentinels, it might be a fine default, but > for filters, it might be more useful for each filter to be able to > affect the passed to the next filter). I'll add that this can be useful for any hook that takes arguments. I think it is a bad idea to consider process callback functions special. If it is useful behavior to modify callback arguments, then let us be consistent and give that ability to any type of callback, not just processes. > I agree the third part is a good change (tho not terribly important). I'm interested in gradually improving the existing Emacs API. To me, it is very important. And since I have volunteered to do all of the work (and probably won't volunteer on things that others find important, as there are many important things to be done) it won't eat up any of your time, unless you decide to review a patch. In which case I would be very grateful of your time! :) > I'm not sure the first is useful since in my experience sentinels and > filters do different things anyway. I personally think it is cleaner to have them together, but if others disagree there is probably a reason for it :) This is not an essential part of my proposal. > As for the second, maybe a better path is to try and provide generic > `add-function' and `remove-function' that can operate on any > generalized-variable that holds a function. So you could do > > (add-function (process-filter proc) #'toto) > > which would set proc's filter to a new function that runs the old > function (if any) and runs toto as well. And then `remove-function' > would reset the sentinel to its original value. Why have a different way of doing things? One of the reasons I like my proposal is that it unifies concepts and adds more consistency to the API. The slogan: "If you want have a callback, use the hook API." Since there is no way for filters and sentinels to guarantee order (just like hooks) I think the best route is to just add the ability for a hook to modify the arguments that are passed to the next hook. Although I am not too convinced that this is important, comint-input-filter-functions doesn't do this. > run-hooks takes symbols as arguments. It was just an example, I am a busy person and I think I got the gist of what I was saying across. But I'll add (off-topic) that there seems to be no reason for run-hooks to take a symbol as an argument. The C code just immediately dereferences it.