--- Begin Message ---
Subject: |
24.3.94; c++-mode bad indentation after programmatic insert with locally changed syntax table |
Date: |
Sat, 25 Oct 2014 21:25:43 +0700 |
I think the following should be harmless. Why does it result in broken
indentation?
1. Open in c++-mode buffer with following contents:
int main(int argc, char** argv) {
fgets(0, 1, 2);
}
2. Add an empty line after the semicolon, move cursor there, and
evaluate this:
(with-syntax-table (make-char-table 'syntax-table nil)
(modify-syntax-entry ?\( "(")
(modify-syntax-entry ?\) ")")
(modify-syntax-entry ?< "(")
(modify-syntax-entry ?> ")")
(insert "fgets(0, 1, 2)"))
3. Press `;', see the indentation of the current line change, and
include (erroneously) two extra spaces:
int main(int argc, char** argv) {
fgets(0, 1, 2);
fgets(0, 1, 2);
}
Originally: https://github.com/company-mode/company-mode/issues/212
In GNU Emacs 24.3.94.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.8)
of 2014-10-06 on axl
Repository revision: 117555 address@hidden
Windowing system distributor `The X.Org Foundation', version 11.0.11501000
System Description: Ubuntu 14.04.1 LTS
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#18826: 24.3.94; c++-mode bad indentation after programmatic insert with locally changed syntax table |
Date: |
Sun, 26 Oct 2014 22:09:25 +0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 |
On 10/26/2014 06:24 AM, Alan Mackenzie wrote:
Because the syntax table change is temporary and its effect should be
limited to my code?
It's no so limited. The before-change-functions and after-change-functions
hooks will be run with that syntax table active. This is not good.
I see, thanks. Somehow, I figured that those hooks would run before or
after the current command, whereas they're triggered right near any code
that makes changes to the buffer. Question answered, closing.
On the other hand, you're doing some pretty unusual things with this. If
`c-in-sws' and `c-is-sws' were added in syntax-propertize-function
(which is called on-demand), this conflict wouldn't have manifested.
OK. Can I suggest an alternative? In C++ (and Java) Modes, the template
(generic) delimiters are marked with syntax-table text properties.
Unfortunately, at the moment this is done as part of font-locking, so
isn't done until you display. However, if you put "(sit-for 0)" into
your code after inserting "< ... >", this will cause a redisplay,
allowing subsequent code to use the text properties, and a backward-sexp
will then work.
Sounds like it should be performed during `syntax-propertize' instead.
Even if you don't like this idea now, I suspect it'll happen eventually
anyway, if only for consistency with other major modes.
In that sense, the `sit-for' suggestion is not future-proof. So I'll try
only changing the syntax table around specific functions that don't
modify the buffer text, but just move point, since that was the actual goal.
In the medium future (several weeks away), I'm hoping to fix CC Mode so
that the text properties are applied to < ... > on an after-change
function rather than at redisplay.
Hmm. My current workaround is to use a temporary syntax table that
inherits from c++-mode-syntax-table (but has angle brackets in the
'paren' class). Sounds like it might also create a conflict, if maybe a
more subtle one.
--- End Message ---