From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: A vision for multiple major modes [was: Re: [Emacs-diffs] widen-limits c331b66:] Date: Tue, 29 Mar 2016 00:07:20 +0000 Message-ID: <20160329000720.GC5095@acm.fritz.box> References: <87twjyp21k.fsf@gmail.com> <56F242E0.7060004@online.de> <877fgtpfrw.fsf@gmail.com> <20160323211605.GA5324@acm.fritz.box> <20160324183835.GB2721@acm.fritz.box> <20160327120919.GA2682@acm.fritz.box> <8d18ba1e-8252-1e6b-2bea-3a0e5e68b052@yandex.ru> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1459209888 7786 80.91.229.3 (29 Mar 2016 00:04:48 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 29 Mar 2016 00:04:48 +0000 (UTC) Cc: Vitalie Spinu , Andreas =?iso-8859-1?Q?R=F6hler?= , emacs-devel@gnu.org, Stefan Monnier , Eli Zaretskii , Drew Adams To: Dmitry Gutov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Mar 29 02:04:39 2016 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 1akh9C-0000Ir-R9 for ged-emacs-devel@m.gmane.org; Tue, 29 Mar 2016 02:04:39 +0200 Original-Received: from localhost ([::1]:43723 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akh9B-0000pV-Vm for ged-emacs-devel@m.gmane.org; Mon, 28 Mar 2016 20:04:37 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54713) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akh97-0000pM-MO for emacs-devel@gnu.org; Mon, 28 Mar 2016 20:04:35 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1akh95-00056B-Hr for emacs-devel@gnu.org; Mon, 28 Mar 2016 20:04:33 -0400 Original-Received: from mail.muc.de ([193.149.48.3]:27616) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akh95-00054m-9D for emacs-devel@gnu.org; Mon, 28 Mar 2016 20:04:31 -0400 Original-Received: (qmail 14425 invoked by uid 3782); 29 Mar 2016 00:04:28 -0000 Original-Received: from acm.muc.de (p548A556F.dip0.t-ipconnect.de [84.138.85.111]) by colin.muc.de (tmda-ofmipd) with ESMTP; Tue, 29 Mar 2016 02:04:26 +0200 Original-Received: (qmail 14914 invoked by uid 1000); 29 Mar 2016 00:07:20 -0000 Content-Disposition: inline In-Reply-To: <8d18ba1e-8252-1e6b-2bea-3a0e5e68b052@yandex.ru> User-Agent: Mutt/1.5.24 (2015-08-30) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x X-Received-From: 193.149.48.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:202371 Archived-At: Hello, Dmitry. On Mon, Mar 28, 2016 at 01:59:21AM +0300, Dmitry Gutov wrote: > On 03/27/2016 03:09 PM, Alan Mackenzie wrote: > > I can't really see a proof of concept happening. Either the thing is > > implemented or it's not. There's hardly a half way point. > "Full implementation" would work, too. But it would still be considered > a prototype. Point is, we can't really decide whether we'll end up using > it, before trying it for a while. Of course. > >>> That will require more investigation. But syntax based searching and > >>> regexp based searching will certainly be amongst them. > I don't think that's enough. E.g. (goto-char (match-end n)) is a common > idiom for syntax highlighting and indentation code. Yes, but that match is going to be in the same island, or at the very least, in the chain of islands containing the current one. > >> [island-affected primitives] > > looking-at? Probably. > > char-after? No. > > syntax-after? No. (This works only on a single char, hence must be in a > > single island, it can't span two.) > > forward-char? Maybe. In fact, there's a good argument for not moving > > forward when `forward-char' hits an island boundary. > Being confined to the current island is not what I had in mind. If > that's the idea of how such primitives would work, I don't really see a > lot of benefit over using narrowing around all those calls. Are you thinking more that `forward-char' should move from the end of an island to the beginning of the next island in a chain? > >> Speaking of the last one, will the buffer positions, as visible to the > >> submode code, be renumerated, or will they have gaps? > > It would retain the global buffer position, for consistency with the rest > > of Emacs. For example, in narrowed buffers, the position relative to > > point-min is never used. > True. I'm more worried about gaps. But they could be treated like > whitespace, I suppose. For example, by `forward-char'? What primitives were you thinking of, here? > >> Depending on your answer to the previous question, even simply inserting > >> text inside one of the preceding islands might make syntax-ppss-cache > >> out of date in the current island. > > That could probably be solved by making positions in that cache relative > > to the beginning of the island, and things like that. I think you'd want > > to make `syntax-propertize--done' island local, too. > Right. So then, some yet-unknown body of code has to become > island-aware, and the improvement is not that seamless anymore. The way I see it, the super modes would have to be totally aware of the island mechanism, but the major modes would be largely, it not totally, unaware of it. `syntax-ppss' seems more part of the super mode mechanism. > >>> It wouldn't use any high level facility like post-command-hook. The > >>> mechanism would be more like a buffer local variable, entirely handled > >>> by the C level, so that such a binding would simply exist. > >> You didn't answer my question, though. When will the bindings apply? > > Sorry, an island local binding would be current when point is within that > > island. Or, perhaps there could be some variable which would be set to a > > position to do this job. > What if var has an island-local binding? And my function has this: > (setq var 1) > (goto-char xx) ; where xx is in a different island > will its value change mid-program? What if xx is in the same island? > Will the value change then? A different island local binding would become current, so yes its value would thereby change. Much like if var had a buffer local binding, and you do (set-buffer "foo"), the value of var you'd just set would no longer be in the current binding. if xx is in the same island, the binding just setq'd would remain the same. > I don't think either should be true. Then, the "adequate" model would > amount to changing them in post-command-hook anyway. What sort of variables are you thinking about here? [ Some time later:] Could it be that it might be better to have "island chain local" variables rather than merely "island local" ones? So that the three ruby lines in your example below would be three islands in a chain, and would thus all share a set of "island chain local" bindings rather than each line having its own binding? > >> I don't know if we'd need the island-beginning/island-end accessors in > >> your proposal. > > I think we would. (narrow-to-region (point-min) (point-max)) is a null > > operation. If the major mode has narrowed, and needs to set point-min to > > "1", it will need to know the island-beginning, somehow. > What if it just calls widen? That also sets point-max, which would specifically not be wanted. > They [ super modes ]'d still have to maintain the island boundaries. > And the lists of variables to set island-locally, or mode-locally, or > chunk-locally. That constitutes the majority of the related code > already. Yes. How could it be otherwise? But with sharp tools, the work could be easier. > > It would not be necessary to use widening and narrowing to > > restrict indentation/fontification code to an island. > So making it seem, to the Lisp code, like the multiple related islands > don't have anything (for some definition of "anything") between them is > not a priority? By "related", I think you mean the same thing I meaan by "chained" - the three ruby mode lines enclosed in <%...%> in your example below, would be chained together by the super mode. By "anything between them", I take it you mean certain primitives (still to be pinned down precisely) would make it look like the successive islands in a chain followed on from eachother without "anything between them". We could make it a priority. > That would be the high point of the "islands" idea from my perspective. > But having only some primitives affected would likely break this use > case. > Here's an example of ERB code Vitalie brought up recently: > <% if foo %> > <%= bar(boo) %> > <% end %> > The parts of the buffer between %'s would be Ruby islands. The > suggestion was to use the value returned by the indentation function in > the second island (second line) to indent the "real" buffer contents. The question seems to be, are we indenting in the super mode or in each island? The answer seems to be you'd want to indent in the super mode here, I think. > But: neither of the islands contains a newline. If they are combined in > the most straightforward way, the Ruby line will be 'if foo bar(boo)', > and its indentation would be not what we're looking for. I think the > current ways to look for a newline, > (progn (skip-syntax-backward " ") > (eq (char-before ?\n)) > or > (looking-at "\\s-$") > will fail to work. Also note that neither of the two islands in this > example contains the newline in question. Two? Don't you mean three, here? Is this a minor mistake in your counting or am I missing something important because I don't grok ruby? > To sum up, hard examples are hard. And yet, the new feature should make > some use cases possible that were impossible before, not just allow for > easier island-local variables. > > I don't think having islands start at position 1 is a good idea. But > > having the relevant primitives skip the gaps between chained islands, and > > stop at an island boundary when not chained, when `restrict-to-island' is > > non-nil, would be a central idea. > The "not chained" idea would require some explanation. For example, islands in a shell script which were individual AWK scripts would not be chained together. But the three (?two) lines of ruby in the example above would be chained together. I think we need to work this out more precisely. For example, in the three ruby line scenario above, is there any variable you can think of for which it would be advantageous to have a binding for each island rather than a shared binding for the set of three (?two)? I'm kind of envisioning successive `forward-char's moving from the end of "<% if foo %>" to the beginning of "<%= bar(boo) %>", or even from the end of "if foo" to the beginning of "bar(boo)". How does this sound? Or am I talking total rubbish? (It's getting late). -- Alan Mackenzie (Nuremberg, Germany).