nonsequitur / inf-ruby

218 stars 69 forks source link

Rails console hangs with downward-pointing triangle #159

Closed chrisbouchard closed 2 years ago

chrisbouchard commented 2 years ago

I know this is an old issue, but I'm running into it and I've tried the fix listed in the README. When I run inf-ruby-console-auto (or in my original case, try to use Robe), the console hangs. It shows the first two lines of output from Rails, but instead of a prompt just shows a blue, downward-pointing triangle. I can type but the console is unresponsive.

Is there any chance this is a new bug? Or have I just missed something in my setup?

Screenshot from 2022-02-15 22-07-17

$ ruby --version
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
$ bin/rails --version
Rails 6.1.3.2
$ bin/rails console -- --version
Running via Spring preloader in process 17046
Loading development environment (Rails 6.1.3.2)
irb 1.3.5 (2021-04-03)
$ cat ~/.irbrc
IRB.conf[:USE_MULTILINE] = false if ENV['INSIDE_EMACS']
$ emacs --version
GNU Emacs 27.2
Copyright (C) 2021 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
(pkg-info-package-version "inf-ruby")
20220203.153
chrisbouchard commented 2 years ago

Just tried updating a couple things, and I still run into this with

$ ruby --version
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
$ bin/rails --version
Rails 6.1.4.6
$ bin/rails console -- --version
Running via Spring preloader in process 71796
Loading development environment (Rails 6.1.4.6)
irb 1.3.5 (2021-04-03)
dgutov commented 2 years ago

Hi!

Any chance you started the console outside of Emacs first (after which Spring has cached its environment), and then started it inside Emacs?

You can try removing Spring (at least for the duration of troubleshooting) and then repeating the attempt.

If that fails, can you try stepping through inf-ruby-console-rails and see whether the inf-ruby--irb-needs-nomultiline-p returns t?

dgutov commented 2 years ago

To step through the function, move to its definition with M-x find-function, then press C-u C-M-x (to edebug-defun).

Then repeat the usual scenario in Emacs, you should land in the interactive debugging at the beginning of that function. Step through it by repeatedly pressing SPC.

To undo instrumentation, press C-M-x when within the function definition again (but without C-u).

chrisbouchard commented 2 years ago

I've removed Spring as a dependency, and confirmed that both bin/rails console and inf-ruby-console-auto start up without the Spring message. I've also debugged the inf-ruby-console-rails function as requested and can confirm that inf-ruby--irb-needs-nomultiline-p returns true and the -- --no-multiline part is being included in the command. However, the issue persists.

dgutov commented 2 years ago

That's odd.

I have just tried this in a newly created Rails project, and it worked fine (no triangle).

Rails 6.1.4.6, Ruby 3.0.2, IRB 1.3.5.

More importantly, you're also saying you have IRB.conf[:USE_MULTILINE] = false if ENV['INSIDE_EMACS'] inside ~/.irbrc. That should solve the problem by itself (and it does, in my testing), even if I comment our the respective code in inf-ruby-console-rails.

There might be something in your project that counteracts this setting.

Try creating a new Rails project. Does it exhibit the same problem?

Also try Ruby 3.0.2 maybe (I don't have the time to compile a different version ATM), but the chances of that helping are really slim.

chrisbouchard commented 2 years ago

No luck on my end, I'm afaid. I've upgraded to the latest Ruby and Rails — 3.1.1 and 7.0.2.2, respectively. I've created two brand new Rails projects:

In both new projects I still get the blue triangle when I run inf-ruby-console-auto. :slightly_frowning_face:

I've doubly verified that the console is getting the --multiline flag.

$ pgrep -af rails
31311 /home/chris/.homesick/repos/rbenv/versions/3.1.1/bin/ruby bin/rails console -e development -- --nomultiline

And I've double-checked that my .irbrc file has the workaround.

$ cat ~/.irbrc
IRB.conf[:USE_MULTILINE] = false if ENV['INSIDE_EMACS']

Here are the new package versions in case it matters.

$ ruby --version
ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux]
$ bin/rails --version
Rails 7.0.2.2
$ bin/rails console -- --version
Loading development environment (Rails 7.0.2.2)
irb 1.4.1 (2021-12-25)
chrisbouchard commented 2 years ago

Oh! But I just tried inf-ruby and that used my global Ruby 3.0.2 and it worked. So maybe something did break in Ruby 3.0.3+.

dgutov commented 2 years ago

The next step would be to see whether any of the loaded gems modify [:USE_MULTILINE] as well.

But if you have a sample project ready which exhibits the problem, please zip it up and attach to this conversation, I'll take a look.

dgutov commented 2 years ago

But I just tried inf-ruby and that used my global Ruby 3.0.2 and it worked.

M-x inf-ruby-console-auto also worked?

chrisbouchard commented 2 years ago

I'm testing that now. Just had to do some rbenv juggling to install Rails.

chrisbouchard commented 2 years ago

Yes, inf-ruby-console-auto also works with 3.0.2! So something's not working in 3.0.1, 3.0.3, and 3.1.x, as far as I can tell. But I'm happy to stick with 3.0.2 for now.

dgutov commented 2 years ago

Interesting. I'll check it out, thanks.

To be sure, you can still upload that sample project: after all, the problem could be a combination of Ruby 3.0.3's behavior and something in the project configuration.

chrisbouchard commented 2 years ago

Ok, will do. :+1:

One other thing — I'm just baffled because I can't see any meaningful difference between the irb sessions in 3.1.1 and 3.0.2.

test-rails-3.1.1$ bin/rails console -- --nomultiline
irb(main):001:0> puts 'Hello'
Hello
=> nil
irb(main):002:0>
test-rails-3.0.2$ bin/rails console -- --nomultiline
irb(main):001:0> puts 'Hello'
Hello
=> nil
irb(main):002:0>

Same prompt, same ANSI coloring (just the nil in cyan, the rest default). Neither is using the new syntax highlighting or code completion.

chrisbouchard commented 2 years ago

The two test projects I've been using:

dgutov commented 2 years ago

Just a quick question: does adding --nosingleline and/or --noreadline help things?

I.e.

diff --git a/inf-ruby.el b/inf-ruby.el
index a3f5245..d898044 100755
--- a/inf-ruby.el
+++ b/inf-ruby.el
@@ -1066,7 +1066,7 @@ automatically."
              ;; Note: this only has effect in Rails < 5.0 or >= 5.1.4
              ;; https://github.com/rails/rails/pull/29010
              (when (inf-ruby--irb-needs-nomultiline-p)
-               " -- --nomultiline"))
+               " -- --nomultiline --nosingleline --noreadline"))
      "rails")))

 (defun inf-ruby-console-rails-env ()

Press C-M-x to re-evaluate the definition after editing.

chrisbouchard commented 2 years ago

I'll just mention one other thing that I hope isn't relevant. My system ruby is 3.0.2 (Fedora 35). I've been using rbenv for all my development — even for 3.0.2 — so I don't need root to install packages. That's why inf-ruby used 3.0.2 when I ran it outside any project directory. When I ran inf-ruby-console-auto, Rails used ruby 3.0.2 installed via rbenv. So it works either way, but I'm just noticing that it breaks in any version that doesn't match my system ruby.

chrisbouchard commented 2 years ago

Yes, adding all those flags seems to fix the issue. I get an irb prompt in inf-ruby-console-auto even in 3.1.1. :tada:

dgutov commented 2 years ago

FWIW, I also use rbenv. And Ubuntu 20.04.

Yes, adding all those flags seems to fix the issue. I get an irb prompt in inf-ruby-console-auto even in 3.1.1.

Nice. Please try removing each of them in turn to see which of the flags was necessary. Maybe both, but that's doubtful.

chrisbouchard commented 2 years ago

It looks like --nomultiline --noreadline does it for me, at least enough to get past the blue triangle to a prompt, even without ~/.irbrc. :+1:

Edit to add: --nomultiline --nosingleline also seems to work.

dgutov commented 2 years ago

Ah, what I missed is that --nosingleline and --noreadline are basically the same option now, and both disable the use of Readline module.

So it's probably dependent on how Ruby was compiled rather on a particular version used. And I couldn't repro this with Ruby 3.0.3 now.

If you have any further interest in finding out the reason, evaluating the following should help: IRB.CurrentContext.io

Here, it prints ReadlineInputMethod with ext/readline 8.0 inside my Emacs, in inf-ruby, so apparently it's able to work inside Emacs at least with my particular configuration.

Try running bin/rails console -- --nomultiline outside Emacs and evaluating the same expression. Perhaps it will print a different version of readline or some substitute.

Either way, it seems adding --nosingleline (or --noreadline for backward compat) in several places inside inf-ruby seems like a good idea. But it would be nice to document the particular reasons.

chrisbouchard commented 2 years ago

I see you've already closed this issue, but I got a chance to try out what you suggested with IRB.CurrentContext.io and thought I'd share my results.

Both my rails test projects (ruby 3.0.2 and 3.1.1) report the same.

$ bin/rails console -- --nomultiline
Loading development environment (Rails 7.0.2.2)
irb(main):001:0> IRB.CurrentContext.io
=> ReadlineInputMethod with Reline 0.3.1
irb(main):002:0> 

Even irb reports that inside of a rails project, because rbenv is picking up the version in the .ruby-version file and using that installed version rather than the system version.

Outside of a rails project, irb reports differently.

$ irb --nomultiline
irb(main):001:0> IRB.CurrentContext.io
=> ReadlineInputMethod with ext/readline 8.1
irb(main):002:0>

And for the record, when run with --noreadline (or --nosingleline) I get different results yet.

$ irb --nomultiline --noreadline
irb(main):001:0> IRB.CurrentContext.io
=> StdioInputMethod
irb(main):002:0>
$ bin/rails console -- --nomultiline --noreadline
Loading development environment (Rails 7.0.2.2)
irb(main):001:0> IRB.CurrentContext.io
=> StdioInputMethod

Here I also get the same results when using the system ruby.

So it does seem to be about system vs. rbenv, at least for picking the input method. inf-ruby works fine with ReadlineInputMethod with ext/readline 8.1 (and of course StdioInputMethod) but does not work with ReadlineInputMethod with Reline 0.3.1 regardless of ruby version.

From some quick research, it looks like additional install-time arguments are needed to make rbenv use the system readline library. I'm curious to give that a try and see if I get different results.

Edit: I installed readline-devel in Fedora and now rbenv install picks up and uses the system readline. Once it does, inf-ruby-console-auto works with just --nomultiline.

dgutov commented 2 years ago

I see you've already closed this issue, but I got a chance to try out what you suggested with IRB.CurrentContext.io and thought I'd share my results.

Thanks! Now we know that it is indeed the lack of Readline that caused the problem, and Reline's incompatibility with running inside Emacs.

Edit: I installed readline-devel in Fedora and now rbenv install picks up and uses the system readline. Once it does, inf-ruby-console-auto works with just --nomultiline.

That's what I wanted to say: as long as the -dev package is installed (in my distro), rbenv install doesn't require any extra arguments. That blog post is a little old, so no surprise that it's off in some details.

And the system Ruby is different because it's been compiled on another computer already, so it doesn't depend on the -dev[el] package.

ErikSchierboom commented 2 years ago

Passing -- --noreadline to rails console worked like a charm! Thanks a lot.

dgutov commented 2 years ago

FWIW, using Ruby built without libreadline might still not be a good idea.

If your project is large enough, completion can be slow with rb-readline: https://github.com/dgutov/robe/issues/139