BUG: ruby-mode.el : '/=' operator breaks following indentation

J

Jeremy Henty

Using emacs 21.4, ruby-mode.el from Ruby 1.8.5 (byte-compiled), if I
open a file with the following code ...

def foo
x /= y
bar
end

....move the cursor to the word "bar" and press Tab, nothing happens!
If I replace "/=" with "*=" then Tab fixes the indentation as I'd
expect.

Any suggestions for debugging this? I've hacked elisp a few times but
major mode definitions are beyond my experience.

Regards,

Jeremy Henty
 
G

George Ogata

Using emacs 21.4, ruby-mode.el from Ruby 1.8.5 (byte-compiled), if I
open a file with the following code ...

def foo
x /= y
bar
end

...move the cursor to the word "bar" and press Tab, nothing happens!
If I replace "/=" with "*=" then Tab fixes the indentation as I'd
expect.

Any suggestions for debugging this? I've hacked elisp a few times but
major mode definitions are beyond my experience.

The issue is probably that it's treating the "/=" as the beginning of
a multiline regexp. A common fix for these sorts of "mistaken
delimiters" is to put a comment at the end of the line containing a
closing delimiter:

def foo
x /= y #/
bar
end

Not ideal, but it might get you by.

BTW, there's a newer ruby-mode.el in the ruby CVS repository. It
still doesn't fix this, although the behavior is slightly different
(it doesn't indent the "bar" at all, as if in a multiline string).

G.
 
G

George Ogata

11/30/06 said:
BTW, there's a newer ruby-mode.el in the ruby CVS repository. It
still doesn't fix this, although the behavior is slightly different
(it doesn't indent the "bar" at all, as if in a multiline string).

Oops, I misread. It sounds like it is the same behavior. Still, it
might be a newer version.
 
J

Jeremy Henty

The issue is probably that it's treating the "/=" as the beginning
of a multiline regexp. A common fix for these sorts of "mistaken
delimiters" is to put a comment at the end of the line containing a
closing delimiter:

def foo
x /= y #/
bar
end

Thanks, that works. A slightly better fix is to add a ';' as well to
convince the major mode that the statement has ended, otherwise it
adds extra indentation to the next line.

def foo
x /= y # / ;
bar
end

I wonder how the Ruby parser decides that /= is an operator and not
the start of a regexp?

Regards,

Jeremy Henty
 
G

George Ogata

Thanks, that works. A slightly better fix is to add a ';' as well to
convince the major mode that the statement has ended, otherwise it
adds extra indentation to the next line.

def foo
x /= y # / ;
bar
end

Hmm, my ruby-mode doesn't seem to need the ';'. I'm using the CVS
HEAD version with XEmacs 21.4.19.
I wonder how the Ruby parser decides that /= is an operator and not
the start of a regexp?

It's just the way the grammar is defined. For it to be a regexp,
you'd need parens on the call to #x.

g@crash:~$ cat test.rb
x /=/
g@crash:~$ ruby test.rb
test.rb:1: unterminated string meets end of file
test.rb:1: parse error, unexpected tSTRING_END, expecting
tSTRING_CONTENT or tREGEXP_END or tSTRING_DBEG or tSTRING_DVAR
g@crash:~$ cat test2.rb
x(/=/)
g@crash:~$ ruby test2.rb
test2.rb:1: undefined method `x' for main:Object (NoMethodError)
g@crash:~$ ruby -v
ruby 1.8.4 (2005-12-24) [i686-linux]

The ruby-mode parser is much simpler than the one the ruby interpreter
uses. For a start, it's not based on a proper grammar. I don't
suppose someone's tried to use semantic [1] or something to produce
something a little more robust?

[1] http://www.xemacs.org/Documentation/packages/html/semantic.html
 
J

Jeremy Henty

Hmm, my ruby-mode doesn't seem to need the ';'. I'm using the CVS
HEAD version with XEmacs 21.4.19.

Mine definitely does need it. I'm using stock Ruby 1.8.5 and GNU
Emacs 21.4 .
It's just the way the grammar is defined.

"Mommy, why is the sky blue?" "Hush child, it's just the way the
physics is defined." :)
For it to be a regexp, you'd need parens on the call to #x.

Hmm, so after an identifier the parser tries to parse an infix
operator trying to parse an expression, whereas after an open paren
there can't be an infix operator so it parses "/=" as the start of a
regexp? If so, I wonder how easy it would be to fix the emacs major
mode to do the same thing?

Thanks for your help.

Regards,

Jeremy Henty
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top