From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: phillip.lord@russet.org.uk (Phillip Lord) Newsgroups: gmane.emacs.devel Subject: Re: A vision for multiple major modes: some design notes Date: Fri, 22 Apr 2016 13:45:48 +0100 Message-ID: <871t5xstfn.fsf@russet.org.uk> References: <20160420194450.GA3457@acm.fritz.box> <87vb3blxux.fsf@russet.org.uk> <20160421091437.GB1775@acm.fritz.box> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1461329212 19674 80.91.229.3 (22 Apr 2016 12:46:52 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 22 Apr 2016 12:46:52 +0000 (UTC) Cc: emacs-devel@gnu.org, Dmitry Gutov To: Alan Mackenzie Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Apr 22 14:46:40 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 1ataTn-0005Nt-MJ for ged-emacs-devel@m.gmane.org; Fri, 22 Apr 2016 14:46:39 +0200 Original-Received: from localhost ([::1]:60856 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ataTn-00025G-5L for ged-emacs-devel@m.gmane.org; Fri, 22 Apr 2016 08:46:39 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47004) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ataTi-00022n-RE for emacs-devel@gnu.org; Fri, 22 Apr 2016 08:46:36 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ataTf-0001F1-Iv for emacs-devel@gnu.org; Fri, 22 Apr 2016 08:46:34 -0400 Original-Received: from cloud103.planethippo.com ([31.216.48.48]:60014) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ataTf-00013B-6T for emacs-devel@gnu.org; Fri, 22 Apr 2016 08:46:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=russet.org.uk; s=default; h=Content-Type:MIME-Version:Message-ID: In-Reply-To:Date:References:Subject:Cc:To:From; bh=ReAVoa+j1cjsi3R2wEKnnzi+OAgTcwcdFDagZ5L6jSA=; b=jtAsLyyoBxn2VW8DyJNp/SSODZ rwDJ9IHOvbjOLFN8QhmoS83wrDVmEW83apWOvQtfnzh9OzneNeQSIJkzLnO3GT4IzYPG0lC3m+q5z A61xsuS0QLyd+wV9RvPbROZY5VIk/e+cJAUyuMjCdVPvMZyVIMOIJ9AxI5XvPMCV3tKVTbYZRCBfh ck3wgDoIKoxE1lvfjnQE2+QTNTNV3oouyWkruFL4YwjctvRgS1aerJQafMtG2UMYwGBSwbNaBOT5x 4p9o/Tlu0R99+vbWOXFrE0+3EEJ4nQBQa4aGBAHQYcC1x/RQjmP7Xiqrc4YD4P6yaVcBY4bQR9U6O 3w78pCvA==; Original-Received: from janus-nat-128-240-225-60.ncl.ac.uk ([128.240.225.60]:33518 helo=russet.org.uk) by cloud103.planethippo.com with esmtpsa (TLSv1.2:DHE-RSA-AES128-SHA:128) (Exim 4.86_1) (envelope-from ) id 1ataSz-002TAd-7p; Fri, 22 Apr 2016 13:45:49 +0100 In-Reply-To: <20160421091437.GB1775@acm.fritz.box> (Alan Mackenzie's message of "Thu, 21 Apr 2016 09:14:37 +0000") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.92 (gnu/linux) X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - cloud103.planethippo.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - russet.org.uk X-Get-Message-Sender-Via: cloud103.planethippo.com: authenticated_id: phillip.lord@russet.org.uk X-Authenticated-Sender: cloud103.planethippo.com: phillip.lord@russet.org.uk X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 31.216.48.48 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 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" Xref: news.gmane.org gmane.emacs.devel:203171 Archived-At: Alan Mackenzie writes: >> When you say "complementary" do you mean alternative or simultaneous? >> I.e. will an island always be enclosed by syntax markers and always have >> a text property. Or can it have either? > > Sorry, that wasn't very clear. It would always have both. The text > property would enable the code for chain local variables quickly to > determine the current chain. The syntactic markers would enable > efficient scanning by parse-partial-sexp, etc. > >> I'm still not understanding how the chain of islands is set up. Is this >> entirely the super modes responsibility? > > Yes, it would be entirely for the super mode to do. There would be a > set of functions to do this, for example: > > (defun create-island-chain (beg end major-mode ...) ...) (where BEG > and END would be the bounds of the first island in the chain). > > (defun add-island-to-chain (chain beg end ...) ...) (which would > delimit (BEG END) as an island, and link it into CHAIN) > > There would also be functions for removing islands from a chain, etc. I > should really have put this into the notes. Thanks! I think that you would need some good utility functions, and call backs to support this though. Say, I have a mode with some syntactic markers identifing islands. Who has the job of checking that the islands are still the same? I had this problem with "lentic" -- and it's hard work. You need to hook into the various change functions, and sometimes rescan the entire buffer. Using the change functions is a PITA anyway, and easy to get wrong. And, avoiding scanning the whole buffer after every change is good to avoid. Font-lock avoids this, for instance, by getting core Emacs to tell each mode when to re-fontifify different regions. I think you would need something similar. >> Also, how will the regexp engine work when it spans an island? I ask >> because, if we use the regexp engine to match delimiters, the which >> syntax do we use, if there are multiple modes in the buffer. > > I imagine that the island-start/end syntactic markers would normally be > set by the super mode as syntax-table text properties. These always > take priority over whatever the current syntax table would say. These > markers would be considered to be in the enclosing scope, not part of > the island they define. > > The current syntax table would always be that of the island the current > position was in. I suppose there is potential for an island to be > recognised as such in the "enclosing scope", but not in the island > itself. This could be mitigated against by warning super mode > programmers to use island-start/end syntaxes ONLY in syntax-table text > properties. > > The actual matching of an island to "\\s-" would be delegated to the > syntax code (as is currently done for "\\s?" expressions). I am worried about syntax codes in general. Say, we have a syntax like #+begin_src lisp #+end_src Whether "_" is a symbol constituent or not is mode specific. Say, we have a buffer with mixed org-mode and lisp. The regexp we need to identify #+end_src will depend on the mode of the buffer that #+end_src is in. That is the point of course. But, if you are using #+end_src to delineate islands in the first place, then what mode the text is in rather indeterminate -- you cannot guarantee that the islands are in the correct place yet, because this is why you are looking for #+end_src markers. So, you have to build a regexp which does not use char classes which differ between modes. For this to work, I think, you need to be able to say to regexp functions "ignore islands". Binding "in-islands" to nil might work I guess. > >> > o - An island might be represented by a C or Lisp structure, it might not >> > (not yet decided). This structure would hold the containing chain, >> > markers pointing to the start and end of the chain, and the previous and >> > next islands in the chain. >> > >> > (v) Syntax, etc. >> > o - Two new syntax classes, "open island" and "close island" will be >> > introduced. These will be designated by the characters "{" and "}". Their >> > "matching character" slots will contain the island's chain. There will be >> > an extra flag "chain" (denoted by "i") indicating whether there is a >> > previous/next island in the chain. >> > o - `scan-lists', `scan-sexps', etc. will treat a "foreign" island as >> > whitespace, much as they do comments. They will also treat as whitespace >> > the gap between two islands in a chain. > >> Difficult to say, but this might produce some counter intuitive >> behaviour. So, for example, consider some text like so: > >> === Example > >> (here is some lisp) > > >> ;; This is a long and tedious piece of documentation in my lisp program. >> (here is some more lisp) > > >> === End Example > >> Now moving backward a paragraph will have a significant difference in >> behaviour -- on the "(" of "here is some more lisp", we move to "(here >> is some lisp), while on the char before, we move the "This is a long". >> Good, bad, expected? Don't know. > > Assuming that the comment is set up as an island inside the lisp code > (which might not be the Right Thing to do) .... > > As a user action, moving back that paragraph would move from "(here is > some more lisp)" to ";; This is a long ....", since `in-islands' would > be nil during command processing. > > As part of a program's parsing, `in-islands' would be bound to non-nil, > and backward-paragraph would move from "(here is some more lisp)" to > "(here is some lisp)". > > This is the intended processing. > > [ .... ] > >> > (vii) Variables. >> > o - Island chain local variable bindings will come into existence. These >> > bindings depend on the island point is in. There will be lower level >> > routines that will have "position" parameters as an alternative to using >> > point. >> > o - All variables which are currently buffer local will become chain local >> > except for those whose symbols are given a non-nil `entire-buffer' >> > property. There will be no new functions like >> > `make-chain-local-variable'. > >> What is the default-value of a chain local variable, if the variable is >> also buffer-local? > > This would be the (global) default value of the variable. It would not > be the buffer-local value. The intention is that the buffer-local value > is the value for the portions of the buffer which are not in any > islands. > >> Will we need functions for setting all chains in a certain mode in a >> single buffer? > > I'm not sure what you mean, here. Does "in a certain mode" mean "INTO a > certain mode"? Oh. Say I have a buffer, half in clojure mode, half in markdown mode. I start cider which connects to a REPL. Currently, cider sets a buffer-local variable called something like "cider-connected-to-repl-p" to "t" to indicate the connection. But, now, we have an island local variable instead. But, surely, if one island is connected to a repl, then all the others should be as well. > If so, setting a major or minor mode in a chain will be > able to be done by putting point inside a pertinent island and calling > the mode function. Maybe a new function `mapchains' could be useful. Yep, that sort of idea. Phil