Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pry *rails* buffer company not stopping completion after dot #96

Closed
sandric opened this issue Nov 26, 2016 · 28 comments
Closed

Pry *rails* buffer company not stopping completion after dot #96

sandric opened this issue Nov 26, 2016 · 28 comments

Comments

@sandric
Copy link

sandric commented Nov 26, 2016

If I run robe-mode in .rb file everything works fine, but in *rails* buffer with pry running because of autocompletion everything works very long. The problem is as I understand is that in .rb files if you chain methods via dots, every time it meets that separator - robe stops autocompletion.
My settings (setq company-minimum-prefix-length 3), so in files everything works smoothly, but looks like that parameter works only for line starting in *rails* but not understanding dots. I don't know if thats inf-ruby issue, but looks like that appears only in buffer created via robe-start.

Update: I just tried to enable via M-x robe-mode in pry rails buffer and now looks like it works as needed! Is it my fault and that buffer should have enabled robe-mode?

@dgutov
Copy link
Owner

dgutov commented Nov 27, 2016

You aren't really supposed to use robe-mode in REPL buffers, it will give you suboptimal results.

The inf-ruby-mode completion function (built-in, and automatically used by company-capf) at least can take advantage of the known types of the local variables. So at least the first method completion, if we're talking about a method chain, should be accurate.

What does M-x company-diag say in one of your *rails* buffers, in the context you initiate completion in?

@dgutov
Copy link
Owner

dgutov commented Dec 4, 2016

@sandric Ping?

@sandric
Copy link
Author

sandric commented Dec 5, 2016

@dgutov Yes, here's my output:

Emacs 25.1.50.1 (x86_64-apple-darwin15.3.0) of 2016-02-29 on sandric-mac.Dlink
Company 0.9.0

company-backends: (company-bbdb company-nxml company-css company-eclim company-semantic company-clang company-xcode company-cmake company-capf company-files
              (company-dabbrev-code company-gtags company-etags company-keywords)
              company-oddmuse company-dabbrev)

Used backend: company-capf
Prefix: ""
Completions:
  #("expand" 0 1 (face (completions-first-difference font-lock-function-name-face)) 1 6 (face font-

and long long list lasts forever.

@dgutov
Copy link
Owner

dgutov commented Dec 5, 2016

So if I understand you correctly, the complaint is that completion takes a lot of time, pegs CPU to 100%, and doesn't take dots into account.

The last one is a consequence of what completion code in e.g. irb/completion expects as input. We could do something about that, though.

Now, to clarify, does this also happen in any project that uses Pry, no matter how small? Or it that only a problem with certain projects you have at work?

@dgutov
Copy link
Owner

dgutov commented Dec 5, 2016

If the answer to my last question is yes, try evaluating this in one such project:

class Module
   alias_method :__name__, :name
end

ObjectSpace.each_object(Module).select { |m| m.__name__.nil? }.count

I have a project like that at work, and the return value here is 15000+. Which is a problem because Module#name is relatively slow for anonymous modules.

UPDATE: Or not. Simply having this many anonymous modules doesn't cause the delay. Investigating.
UPDATE 2: Scratch the first update.

@dgutov
Copy link
Owner

dgutov commented Dec 14, 2016

You can follow pry/pry#1540 and pry/pry#1588.

@dgutov
Copy link
Owner

dgutov commented Sep 20, 2017

@sandric inf-ruby completion should finally be fast with pry 0.11.0. Could you test?

@sandric
Copy link
Author

sandric commented Jan 19, 2018

@dgutov sorry for not reaching out before. Using 0.11.3 and being on much slower computer I can see this behavior only on very big datasets - such as common object, like Integer, followed by dot. Active Record models on other side is working beautifully, so I think issue can be closed already.

But if there's a way to somehow limit autocompletion to all classes but basic, because they have very big autocompletions amount, it would be perfect in my case. Or other way around that still can work for those cases - add setting like company-minimum-prefix-length so that autocompletions triggered only after say three characters. It works in robe mode, but for some reason company in inf-ruby ignores that setting and start to search autocompletions right away. My workaround for now is that when I'm in inf-ruby robe console mode, I enabling robe-mode. I know that is pretty stupid and have not much sense, but its the only way I can escape 5 seconds hangs when I press dot after some expression that is basic class instance.

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

common object, like Integer, followed by dot. Active Record models on other side is working beautifully

Hmm. Do you mean to say that Integer has more methods than ActiveRecord::Base? And by a lot?

for some reason company in inf-ruby ignores that setting and start to search autocompletions right away

Yeah, it aims to provide that "completion after dot" behavior, since it often works okay. Not so in robe-mode.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

@dgutov Oh, no, not integer, sorry. I'm not sure what class that actually is, I can reproduce that by inserting dot after ActiveRecord instance that is got via chaining. So, for example, if you have AR model User, inserting this User., spawns completion instantly, whereas inserting User.first. hangs for about 5 seconds. If you instead instantiate instance into variable, user = User.first, and then user., completions appear without any latch. So I suggest its some common AR model class that was not instantieted at the moment when completion starts.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

In any case, is there any possible way to somehow make company-minimum-prefix-length work in inf-ruby mode?

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

whereas inserting User.first. hangs for about 5 seconds

Ah, so it's the exact case I've worked on speeding up: "we don't know what type it is, so let's show all methods from all classes". 😞 Does completion work for you at all in such cases, in terminal Pry?

is there any possible way to somehow make company-minimum-prefix-length work in inf-ruby mode?

Yes, totally possible. I'd like to investigate the above problem first, though.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

Does completion work for you at all in such cases, in terminal Pry?

In terminal pry I see almost no latch, like half a second maybe.

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

OK, but there are a lot of completions there? How many does it say?

@sandric
Copy link
Author

sandric commented Jan 19, 2018

@dgutov 10694 in my case.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

@dgutov and completions for the same completion but on previously instantieted variable is about 100.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

Which is quite a reduction))

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

Yup: Pry doesn't evaluate the intermediate steps of the chain (for safety, they might have side-effects).

@sandric
Copy link
Author

sandric commented Jan 19, 2018

Yes, but where does that number coming from anyway? I mean User. spawns 663 completions, user = User.first; user. not even showing number, its < 100, but User.first. - 10694.

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

From

          ObjectSpace.each_object(Module){|m|
            next if (to_ignore.include?(m) rescue true)
            # jruby doesn't always provide #instance_methods() on each
            # object.
            if m.respond_to?(:instance_methods)
              candidates.merge m.instance_methods(false).collect(&:to_s)
            end
          }

:)

@dgutov
Copy link
Owner

dgutov commented Jan 19, 2018

Anyway, let me see where the bottleneck in inf-ruby can be. Maybe just Emacs's slow processing of output. Then a user option is the obvious way to go.

@sandric
Copy link
Author

sandric commented Jan 19, 2018

ok. Thanks a lot for all your effort by the way!)

dgutov added a commit to nonsequitur/inf-ruby that referenced this issue Jan 22, 2018
Spanning from the last dot, not from the beginning of expression.

To work better with company-minimum-prefix-length,
dgutov/robe#96 (comment).
@dgutov
Copy link
Owner

dgutov commented Jan 22, 2018

Done. This removes automatic completion after dot, though. I'll look into re-adding a smarter version of it.

@sandric
Copy link
Author

sandric commented Jan 22, 2018

Cool. But for me the problem now moved from delay after inserting point to delay after third character. Sorry...

@dgutov
Copy link
Owner

dgutov commented Jan 22, 2018

Are you sure you're using the new Pry there?

I've tried it in a work project, the number of methods is ~30000 (right after dot), and the completion after 3 characters is pretty much instantaneous. Completion right after dot takes ~1 second.

Does that happen only for some specific prefixes, maybe?

@sandric
Copy link
Author

sandric commented Jan 24, 2018

Oh, I wrong again, I missed out that for some reason I got not pry session in robe-start *rails* buffer, but irb, it spawns with those first lines in it:

Running via Spring preloader in process 15596
Loading development environment (Rails 5.1.4)
irb(main):001:0> => "robe on 34359"
irb(main):002:0> 

If I enter pry command in it, and try to complete after prefix on third chained method call, I got much better timing, smth like .2 - .3 seconds comparing to around 1-2 seconds on raw irb console, and all that on very old machine, without ssd and i3 processor, so I think issue should be closed. I just don't understand why does robe-start not seeing my pry gem, I starting it on development environment, and I have that in my Gemfile:

group :development do
  #...
  gem 'pry'
  gem 'pry-doc'
  gem 'pry-byebug'
end

@dgutov
Copy link
Owner

dgutov commented Jan 24, 2018

not pry session in robe-start rails buffer, but irb

That makes sense: I haven't submitted the performance improvements to IRB yet.

after prefix on third chained method call, I got much better timing, smth like .2 - .3 seconds

After a dot and three characters? That still sounds too long, but there's not much else I can do here without extra investigation on your part. Let me know if you find where the bottleneck is.

I just don't understand why does robe-start not seeing my pry gem

That's easy: robe-start calls rails console, to get the Rails environment loaded, with loads paths and everything. And for Rails to use Pry right away, I think you need pry-rails.

@dgutov dgutov closed this as completed Jan 24, 2018
@dgutov
Copy link
Owner

dgutov commented Jan 26, 2018

ruby/ruby#1798

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants