Currently `IRB::Color.colorize` and `IRB::Color.colorize_code`
refer `$stdin.tty?` internally.
This patch adds `colorable` keyword option which overrides it.
https://github.com/ruby/irb/commit/402e3f1907
The incompatible interface is not helpful, again if you want to use it
as a standalone library, falling it back to PP.
Original PP.pp also ends with `out << "\n"`.
https://github.com/ruby/irb/commit/4c74c7d84c
If a nested object is passed to #pp, it may be sometimes passed to the #text
method as an object without being stringified.
This is fixed on the Ruby main repository;
433a3be86a
but it was a bug of Ripper so still needs this workaround for using irb
as a gem on Ruby 3.0.0 or earlier.
Co-authored-by: k0kubun <takashikkbn@gmail.com>
https://github.com/ruby/irb/commit/8d13df22ee
* lib/irb/color.rb (IRB::Color.scan): ignore "incomplete end of
input" error only, to colorize invalid characters, e.g., control
characters, and invalid symbols, as errors.
Let's say we are in progress to write `"foo"`:
```
irb> "fo
```
at this moment, nothing is wrong.
It would be just a normal way to write `"foo"`.
Prior to this commit, the `fo` part was warned because of
5b64d7ac6e. But I think warning such a
normal input is not valuable for users.
However, we'd like to warn `:@1` or `@@1` which is also a syntax error.
Then this commit switches the syntax highlight based on whether the
input text is finished or not. When it's not finished yet, it does not
warn compile_error.
The reason why we were checking lexer state in addition to token was
that we do not want to colorize local variable, method call, etc., while
they share the :on_ident token with a name of method definition which
should be colored as blue.
It means that we're concerned about the lexer state only for :on_ident.
Thus we can skip checking lexer state for non-:on_ident tokens. This
refactoring is based on that idea.
Also, now we manage Ripper's lexer state as Integer (use `|` if you
need to check multiple states). It should be faster than using Array of
Integer because #any? block call is not needed.
Symbol color was made blue as a workaround because it was hard to
distinguish `foo`s in `:foo` and `def foo; end` (both are :on_ident).
But I wanted to make it yellow like pry.
`:Struct` had the same problem in :on_const. Because the :on_const was
also blue (but underlined and bold), it was not a big issue.
While they're not so problematic since we got a workaround, we also had
a more serious issue for highlighting a symbol like `:"a#{b}c"`.
The first half was considered as Symbol and the last half was considered
as String, because the colorizer did not have a state like a parser.
To approach the last issue, I introduced `IRB::Color::SymbolState` which
is a thin state manager knowing only "the token is Symbol or not". Having
this module magically solves the first two problems as well. So now we
can highlight Symbol as yellow in the perfect manner.