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

Fix command-t on when using RVM #262

Closed
wants to merge 3 commits into from
Closed

Conversation

ssgelm
Copy link
Contributor

@ssgelm ssgelm commented Jan 2, 2017

This should fix the various issues that have been reported when using RVM with a different version locally than the system version. Command-T still needs to be compiled with the system ruby but this prevents the error that occurs when opening vim.

Specifically I believe this fixes #175 and #76.

Sorry for the double pull requests, I realized #261 had an incorrect author on the commit so I created this pull request in its stead.

@wincent
Copy link
Owner

wincent commented Jan 2, 2017

Thanks for this. Can you explain a little bit about how/why this fixes things?

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 3, 2017

For sure. There is a bug that exists at least with ruby 2.2.1 running with RVM on Debian Jessie that causes the following error when running :CommandT:

Error detected while processing vim/plugged/command-t/autoload/commandt.vim:
line  183:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
Error detected while processing function commandt#FileFinder:
line    2:
NoMethodError: undefined method `show_file_finder' for nil:NilClass

In short, the issue happens because ruby runs using some of RVM's gem monkeypatching which causes a Gem::Ext::BuildError instead of a LoadError. Given that this only catches a second type of exception I believe that the change it low risk. The worst case would be that the plugin would not crash when it otherwise should but I can't imagine a scenario in which that would occur. Anecdotally, we have been running with this patch for about a year and a half with zero issues.

@wincent
Copy link
Owner

wincent commented Jan 8, 2017

Cool, thanks for the explanation. Before we merge this, I think we need to modify it so that it works in environments that aren't monkey-patched. For example, on my system Ruby, Gem::Ext::BuildError is not defined, so applying this patch would be a breaking change. We probably need a check with const_defined? of some sort.

@wincent
Copy link
Owner

wincent commented Jan 8, 2017

Ha, I take it back. Ruby doesn't work the way I think it should.

begin
rescue Gem::Ext::RandomGarbage
end

Works.

@wincent wincent closed this in 7f9c806 Jan 8, 2017
@wincent
Copy link
Owner

wincent commented Jan 8, 2017

Actually, we're going to have to try again. Had to revert this because it was blowing up for me in Ruby 2.3.3-p222 (commit).

@wincent wincent reopened this Jan 8, 2017
@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

That's unfortunate. I'll see what I can do to fix it.

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

@wincent I pushed a new commit that fixes this as far as I can tell. I didn't squash the commits but I am happy to if you'd prefer that.

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

Actually, this now doesn't fix the problem for some reason. ☹️ Back to the drawing board!

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

@wincent OK, now I believe it's fixed. Turns out Gem::Ext::BuildError isn't defined until rubygems/ext is autoloaded so I needed to require it before I could check if it's defined.

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

For what it's worth, I believe that e710003 is what broke it. Ruby stops evaluating the constants once it matches one so in the original code when LoadError is hit it doesn't matter whether Gem::Ext::BuildError is defined. Having said that I think that this new commit is a more robust way of handling it anyway.

For example:

2.3.3 :001 > begin
2.3.3 :002 >   require 'asdf'
2.3.3 :003?>   rescue LoadError, RandomOtherError
2.3.3 :004?>     puts 'worked'
2.3.3 :005?>   end
worked
 => nil
2.3.3 :006 > begin
2.3.3 :007 >   require 'asdf'
2.3.3 :008?>   rescue RandomOtherError, LoadError
2.3.3 :009?>     puts 'worked'
2.3.3 :010?>   end
NameError: uninitialized constant RandomOtherError
Did you mean?  RangeError
	from (irb):9:in `rescue in irb_binding'
	from (irb):7

@wincent
Copy link
Owner

wincent commented Jan 8, 2017

Sigh, well that is subtle. I had tested both:

begin
  rescue Gem::Ext::RandomGarbage
end

And:

begin
  raise 'something'
rescue RuntimeError, RandomCrap
  puts 'rescued'
end

which also worked...

So much for the principle of least surprise. I was already surprised when the first example worked, but when the second one worked but this one doesn't that's pretty surprising indeed:

begin
  raise 'something'
rescue RandomCrap, RuntimeError
  puts 'rescued'
end

Sorry for the churn. I'll pull in your new fix.

@wincent
Copy link
Owner

wincent commented Jan 8, 2017

Hm, so thinking about this, I am not so keen on the idea of pulling in RubyGems, which could slow down startup. (Nowhere else in Command-T references RubyGems, nor does it depend on it.)

This would obviously be a code-smell, but could we avoid this with something like this:

begin
  # ...
rescue Exception => e
  if LoadError === e || e.class.to_s === 'Gem::Ext::BuildError'
    # ...
  else
    raise
  end
end

(I even put a code-smell inside the code-smell, by doing the exception-to-string conversion.)

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 8, 2017

Yeah, that would work. Do you think it is at least cleaner to do something like the following?

begin
  # ...
rescue Exception => e
  EXCEPTIONS = [LoadError]
  EXCEPTIONS << Gem::Ext::BuildError if defined?(Gem::Ext::BuildError)
  if EXCEPTIONS.include? e.class
    # ...
  else
    raise
  end
end

@wincent
Copy link
Owner

wincent commented Jan 9, 2017

Yeah that looks ok, I think.

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 9, 2017

OK, change is made. Did you want me to squash these commits?

@wincent
Copy link
Owner

wincent commented Jan 9, 2017

Thanks. No need to squash.

@ssgelm
Copy link
Contributor Author

ssgelm commented Jan 21, 2017

Does this look ok to merge now?

@wincent wincent changed the base branch from master to main June 7, 2021 22:34
@wincent
Copy link
Owner

wincent commented Aug 26, 2022

Given the big rewrite for v6.0.x, older PRs will need to be re-rolled against main and target the new version, so I'm closing this one out. Feedback issue for 6.0.x is here:

@wincent wincent closed this Aug 26, 2022
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

Successfully merging this pull request may close these issues.

Crash unless "rvm use system"
2 participants