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

Split TypeCompletion to a gem #772

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ gem "test-unit"
gem "test-unit-ruby-core"
gem "debug", github: "ruby/debug"

if RUBY_VERSION >= "3.0.0"
gem "rbs"
gem "prism", ">= 0.18.0"
if RUBY_VERSION >= "3.0.0" && !is_truffleruby
gem "repl_type_completor"
end
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,26 +237,26 @@ However, there are also some limitations to be aware of:

## Type Based Completion

IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletion` that uses type analysis.
IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletor` that uses type analysis.

### How to Enable IRB::TypeCompletion
### How to Enable IRB::TypeCompletor

To enable IRB::TypeCompletion, run IRB with `--type-completor` option
To enable IRB::TypeCompletor, run IRB with `--type-completor` option
```
$ irb --type-completor
```
Or write the code below to IRB's rc-file.
```ruby
IRB.conf[:COMPLETOR] = :type # default is :regexp
```
You also need `gem prism` and `gem rbs` to use this feature.
You also need `gem repl_type_completor` to use this feature.

To check if it's enabled, type `irb_info` into IRB and see the `Completion` section.
```
irb(main):001> irb_info
...
# Enabled
Completion: Autocomplete, TypeCompletion::Completor(Prism: 0.17.1, RBS: 3.3.0)
Completion: Autocomplete, ReplTypeCompletor: 0.1.0, Prism: 0.18.0, RBS: 3.3.0
# Not enabled
Completion: Autocomplete, RegexpCompletor
...
Expand All @@ -265,7 +265,7 @@ If you have `sig/` directory or `rbs_collection.lock.yaml` in current directory,

### Advantage over Default IRB::RegexpCompletor

IRB::TypeCompletion can autocomplete chained methods, block parameters and more if type information is available.
IRB::TypeCompletor can autocomplete chained methods, block parameters and more if type information is available.
These are some examples IRB::RegexpCompletor cannot complete.

```ruby
Expand All @@ -287,11 +287,11 @@ As a trade-off, completion calculation takes more time than IRB::RegexpCompletor

### Difference between Steep's Completion

Compared with Steep, IRB::TypeCompletion has some difference and limitations.
Compared with Steep, IRB::TypeCompletor has some difference and limitations.
```ruby
[0, 'a'].sample.
# Steep completes intersection of Integer methods and String methods
# IRB::TypeCompletion completes both Integer and String methods
# IRB::TypeCompletor completes both Integer and String methods
```

Some features like type narrowing is not implemented.
Expand All @@ -301,7 +301,7 @@ def f(arg = [0, 'a'].sample)
arg. # Completes both Integer and String methods
```

Unlike other static type checker, IRB::TypeCompletion uses runtime information to provide better completion.
Unlike other static type checker, IRB::TypeCompletor uses runtime information to provide better completion.
```ruby
irb(main):001> a = [1]
=> [1]
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ desc "Run each irb test file in isolation."
task :test_in_isolation do
failed = false

FileList["test/irb/test_*.rb", "test/irb/type_completion/test_*.rb"].each do |test_file|
FileList["test/irb/**/test_*.rb"].each do |test_file|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I forgot to change this in #794 🤦‍♂️

ENV["TEST"] = test_file
begin
Rake::Task["test"].execute
Expand Down
21 changes: 21 additions & 0 deletions lib/irb/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,27 @@ def retrieve_files_to_require_relative_from_current_dir
end
end

class TypeCompletor < BaseCompletor # :nodoc:
def initialize(context)
@context = context
end

def inspect
ReplTypeCompletor.info
end

def completion_candidates(preposing, target, _postposing, bind:)
result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
return [] unless result
result.completion_candidates.map { target + _1 }
end

def doc_namespace(preposing, matched, _postposing, bind:)
result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
result&.doc_namespace('')
end
end

class RegexpCompletor < BaseCompletor # :nodoc:
using Module.new {
refine ::Binding do
Expand Down
22 changes: 9 additions & 13 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,22 @@ def initialize(irb, workspace = nil, input_method = nil)
RegexpCompletor.new
end

TYPE_COMPLETION_REQUIRED_PRISM_VERSION = '0.18.0'

private def build_type_completor
unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') && RUBY_ENGINE != 'truffleruby'
warn 'TypeCompletion requires RUBY_VERSION >= 3.0.0'
if RUBY_ENGINE == 'truffleruby'
# Avoid SynatxError. truffleruby does not support endless method definition yet.
warn 'TypeCompletor is not supported on TruffleRuby yet'
return
end

begin
require 'prism'
require 'repl_type_completor'
rescue LoadError => e
warn "TypeCompletion requires Prism: #{e.message}"
warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
return
end
unless Gem::Version.new(Prism::VERSION) >= Gem::Version.new(TYPE_COMPLETION_REQUIRED_PRISM_VERSION)
warn "TypeCompletion requires Prism::VERSION >= #{TYPE_COMPLETION_REQUIRED_PRISM_VERSION}"
return
end
require 'irb/type_completion/completor'
TypeCompletion::Types.preload_in_thread
TypeCompletion::Completor.new

ReplTypeCompletor.preload_rbs
TypeCompletor.new(self)
end

def save_history=(val)
Expand Down
241 changes: 0 additions & 241 deletions lib/irb/type_completion/completor.rb

This file was deleted.

Loading
Loading