all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: phillip.lord@russet.org.uk (Phillip Lord)
To: Alan Mackenzie <acm@muc.de>
Cc: emacs-devel@gnu.org, Dmitry Gutov <dgutov@yandex.ru>
Subject: Re: A vision for multiple major modes: some design notes
Date: Fri, 22 Apr 2016 13:45:48 +0100	[thread overview]
Message-ID: <871t5xstfn.fsf@russet.org.uk> (raw)
In-Reply-To: <20160421091437.GB1775@acm.fritz.box> (Alan Mackenzie's message of "Thu, 21 Apr 2016 09:14:37 +0000")

Alan Mackenzie <acm@muc.de> 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



  reply	other threads:[~2016-04-22 12:45 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-20 19:44 A vision for multiple major modes: some design notes Alan Mackenzie
2016-04-20 21:06 ` Drew Adams
2016-04-20 23:00   ` Drew Adams
2016-04-21 12:43   ` Alan Mackenzie
2016-04-21 14:24     ` Stefan Monnier
2016-04-23  2:20       ` zhanghj
2016-04-23 22:36       ` Dmitry Gutov
2016-04-21 16:05     ` Drew Adams
2016-04-21 16:31       ` Eli Zaretskii
     [not found]     ` <<64f1d39a-dfd0-44ca-86c1-b4d6104b5702@default>
     [not found]       ` <<83oa926i0e.fsf@gnu.org>
2016-04-21 16:59         ` Drew Adams
2016-04-21 19:55           ` Eli Zaretskii
     [not found]     ` <<<64f1d39a-dfd0-44ca-86c1-b4d6104b5702@default>
     [not found]       ` <<<83oa926i0e.fsf@gnu.org>
     [not found]         ` <<791d74d1-2b1d-4304-8e7e-d6c31af7aa41@default>
     [not found]           ` <<83eg9y68jy.fsf@gnu.org>
2016-04-21 20:26             ` Drew Adams
2016-04-20 22:27 ` Phillip Lord
2016-04-21  9:14   ` Alan Mackenzie
2016-04-22 12:45     ` Phillip Lord [this message]
2016-04-21 14:17 ` Eli Zaretskii
2016-04-21 21:33   ` Alan Mackenzie
2016-04-21 22:01     ` Drew Adams
2016-04-22  8:13       ` Alan Mackenzie
2016-04-22 17:04         ` Drew Adams
2016-04-22  9:04     ` Eli Zaretskii
2016-06-13 21:17     ` John Wiegley
2016-06-14 13:13       ` Alan Mackenzie
2016-06-14 16:27         ` John Wiegley
2016-04-21 22:19   ` Alan Mackenzie
2016-04-22  8:48     ` Eli Zaretskii
2016-04-22 22:35       ` Alan Mackenzie
2016-04-23  7:39         ` Eli Zaretskii
2016-04-23 17:02           ` Alan Mackenzie
2016-04-23 18:12             ` Eli Zaretskii
2016-04-23 18:26               ` Dmitry Gutov
2016-04-23 21:08               ` Alan Mackenzie
2016-04-24  6:29                 ` Eli Zaretskii
2016-04-24 16:57                   ` Alan Mackenzie
2016-04-24 19:59                     ` Eli Zaretskii
2016-04-25  6:49                       ` Andreas Röhler
2016-04-22 13:42     ` Andy Moreton
2016-04-23 17:14       ` Alan Mackenzie
2016-04-22 14:33 ` Dmitry Gutov
2016-04-22 18:58 ` Richard Stallman
2016-04-22 20:22   ` Alan Mackenzie
2016-04-23 12:27     ` Andreas Röhler
2016-04-23 12:38     ` Richard Stallman
2016-04-23 17:31       ` Alan Mackenzie
2016-04-24  9:22         ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871t5xstfn.fsf@russet.org.uk \
    --to=phillip.lord@russet.org.uk \
    --cc=acm@muc.de \
    --cc=dgutov@yandex.ru \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.