Subject: bug#15874: 24.3.50; exit! not properly font-locked in ruby-mode

From: Dmitry Gutov <[email-masked]>
Date: Fri, 06 Dec 2013 04:44:49 +0200

Stefan Monnier <[email-masked]> writes:

> The advantage is that it would also fix the sexp-movement operations.

Two birds with one stone, yes.

> I don't see why we'd need lookbehind.

Not mandatory, just good for performance, AFAICT. Instead of maching all
identifiers that look like methods and then finding out that most of
them don't end with ? or ! anyway, it would be faster to scan the buffer
for ? or !, and then look a bit back and see if the text before such a
character resembles a method name.

> We can use a regexp like "\\(?:\\sw\\|\\s_\\)\\([!?]\\)" and then place
> the syntax-table property on the ? (or !) character.

Yes, something like that.

> I'd rather do something a bit more generic, then, like a \\S which can
> take a set of syntaxes to exclude.  Or maybe extend the [:foo:]
> character classes to allow [:sw:], [:s_:], etc... so we could do
> [^[:sw:][:s_:]].

That looks good, but, like you mentioned later, if we had a dedicated
backslash-sequence, it could also transparently handle the EOB case.  I
guess, the question is, would it see much use. `regexp-opt' seems to be
the primary use case to me.

> It's not that big of a deal, tho.  I doubt this would ever appear as
> a noticeable slowdown.

That may be true. 

> But you said that ! and ? are only allowed in method names.  So somehow
> Ruby's parser/lexer distinguishes the two cases.  Would a reference to
> a variable "foo?" simply always be parsed as "a reference to variable
> foo?"  which would later trigger an error because there's no such
> variable (because there can't be any such variable)?

Eh, I guess whenever it sees ? or ! at the end of the identifier, the
parser goes with the assumption that it is a method call, because
otherwise it would be a syntax error.

IOW, we only have to worry about @instance and $global variables.

irb(main):022:0* def a
irb(main):023:1> 42
irb(main):024:1> end
=> nil
irb(main):025:0> a?1:2
SyntaxError: (irb):25: syntax error, unexpected ':', expecting $end
a?1:2
    ^
	from /home/gutov/.rbenv/versions/1.9.3-p429/bin/irb:12:in `<main>'
irb(main):026:0> a = 5
=> 5
irb(main):027:0> a?3:4
SyntaxError: (irb):27: syntax error, unexpected ':', expecting $end
a?3:4
    ^
	from /home/gutov/.rbenv/versions/1.9.3-p429/bin/irb:12:in `<main>'
irb(main):028:0> $abc?
irb(main):029:0* 2
SyntaxError: (irb):29: syntax error, unexpected $end, expecting ':'
	from /home/gutov/.rbenv/versions/1.9.3-p429/bin/irb:12:in `<main>'
irb(main):030:0> $abc = 6
=> 6
irb(main):031:0> $abc?1:2
=> 1