Skip to content

Commit

Permalink
Merge branch 'main' into definition-support-for-autoloaded-constants
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Jul 31, 2024
2 parents 8ef9674 + 4afb033 commit 0106252
Show file tree
Hide file tree
Showing 118 changed files with 6,894 additions and 1,903 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ updates:
- "Shopify/ruby-dev-exp"
ignore:
- dependency-name: "@types/vscode"
- dependency-name: "eslint"
versions: [">= 0.9.0"] # blocked by https://github.com/Shopify/web-configs/issues/425
groups:
minor-and-patch:
update-types:
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ jobs:
run: bundle exec rake

- name: Run index troubleshooting tool
run: bundle exec ruby-lsp-doctor
run: bundle exec ruby-lsp --doctor
lint_node:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Node
env:
DISABLE_V8_COMPILE_CACHE: "1"
uses: actions/setup-node@v4
with:
node-version: "18"
node-version: "20.9"
cache: "yarn"
cache-dependency-path: "vscode"

Expand All @@ -78,8 +80,10 @@ jobs:

- name: Set up Node
uses: actions/setup-node@v4
env:
DISABLE_V8_COMPILE_CACHE: 1
with:
node-version: "18"
node-version: "20.9"
cache: "yarn"
cache-dependency-path: "vscode"

Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/indexing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI (indexing)

on:
push:
paths:
- 'Gemfile.lock'
- 'lib/ruby_indexer/**'
pull_request:
paths:
- 'Gemfile.lock'
- 'lib/ruby_indexer/**'

jobs:
indexing_sanity_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: Index Top 100 Ruby gems
run: bundle exec rake index:topgems
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/setup-node@v4
name: Use Node.js 18.x
with:
node-version: "18"
node-version: "20.9"
cache: "yarn"
cache-dependency-path: "vscode"

Expand Down Expand Up @@ -115,7 +115,7 @@ jobs:
const changelog = releases
.filter((release) => release.tag_name.startsWith("vscode-ruby-lsp") && (includePrereleases || !release.prerelease))
.map((release) => `# ${release.tag_name}\n${release.body}\n`)
.map((release) => `${release.body}\n`)
.join("\n");
fs.writeFileSync("vscode/CHANGELOG.md", changelog);
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/require_labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
pull_request_review:
types: [submitted]
pull_request:
types: [labeled, unlabeled]
types: [labeled, unlabeled, synchronize]

jobs:
check-labels:
Expand Down
2 changes: 0 additions & 2 deletions .index.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1
3.3.4
89 changes: 87 additions & 2 deletions DESIGN_AND_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ If you require more accuracy in your editor, consider adopting a type system and
This applies to multiple language server features such as go to definition, hover, completion and automated refactors.
Consider the following examples:

> [!NOTE] not all of the examples below are supported at the moment and this is not an exhaustive list. Please check the
long term roadmap to see what’s planned
> [!NOTE]
> Not all of the examples below are supported at the moment and this is not an exhaustive list.
> Please check the long term roadmap to see what’s planned
```ruby
# Cases where we can provide a satisfactory experience without a type system
Expand Down Expand Up @@ -199,6 +200,7 @@ Interested in contributing? Check out the issues tagged with [help-wanted] or [g
- Explore allowing addons to add support for arbitrary file types
- Allow the Ruby LSP to connect to a typechecker addon to improve accuracy
- Make the Ruby LSP’s default functionality act as a fallback for the more accurate typechecker results
- Introduce a mechanism for addons to be automatically detected without needing user configuration

[Ruby on Rails Community survey]: https://rails-hosting.com/2022/#ruby-rails-version-updates
[Sorbet]: https://sorbet.org/
Expand All @@ -218,3 +220,86 @@ Interested in contributing? Check out the issues tagged with [help-wanted] or [g
[Explore speeding up indexing by caching the index for gems]: https://github.com/Shopify/ruby-lsp/issues/1009
[Add range formatting support for formatters that do support it]: https://github.com/Shopify/ruby-lsp/issues/203
[Add ERB support]: https://github.com/Shopify/ruby-lsp/issues/1055

## Guessed types

Guessed types is an experimental feature where the Ruby LSP attempts to identify the type of a receiver based on its
identifier name. For example:

```ruby
# The receiver identifier here is `user` and so the Ruby LSP will assign to it the `User` type if that class exists
user.name

# Similarly, the receiver identifier here is `post` and so the LSP searches for the `Post` class
@post.like!
```

> [!IMPORTANT]
> The goal of this experiment is to understand if we can get better accuracy for the code that you already
> have. The hypothesis is that a reasonable amount of code already uses patterns like the ones in the example and, in
> those cases, we can achieve nicer results.
>
> However, identifiers are not the ideal medium for proper type annotations. It would not be possible to express anything
> complex, such as unions, intersections or generics. Additionally, it is very trivial to fool the type guessing by simply
> naming a variable with a type name that doesn't match its actual type.
```ruby
pathname = something_that_returns_an_integer
# This will show methods available in `Pathname`, despite the variable being an Integer
pathname.a
```

We do not recommend renaming methods, instance variables or local variables for the sole purpose of getting better
accuracy - readibility should always come first. For example:

```ruby
# It would not be a good idea to name every string "string" for the sake of getting better accuracy.
# Using descriptive names will outweight the benefits of the more accurate editor experience

# don't
string = something.other_thing

# do
title = something.other_thing
name = foo
```

That said, this feature can also be used for quickly exploring methods available in classes. Simply type the lower case
name of the class and completion can show the methods available.

```ruby
# Any class name as an identifier
pathname.a
integer.a
file.a
```

To guess types, the Ruby LSP will first try to resolve a constant based on the receiver identifier and current nesting.
If that does not identify any valid types, then it will fallback to matching based on the first match for the
unqualified type name. For example:

```ruby
module Admin
class User
end

# Will match to `Admin::User` because the `user` reference is inside the `Admin` namespace
user.a
end

module Blog
class User
end

# Will match to `Blog::User` because the `user` reference is inside the `Blog` namespace
user.a
end

# Will match to the first class that has the unqualified name of `User`. This may return `Admin::User` or `Blog::User`
# randomly
user.a
```

This is an experimental feature and can only be accessed if `initializationOptions.experimentalFeaturesEnabled` is
`true` (the `"rubyLsp.enableExperimentalFeatures": true` setting for VS Code users). If you have feedback about this
experiment, please let us know in a GitHub issue.
73 changes: 49 additions & 24 deletions EDITORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@ Code, use the official [Ruby LSP extension](https://marketplace.visualstudio.com
If you need to select particular features to enable or disable, see
[`vscode/package.json`](vscode/package.json) for the full list.

**IMPORTANT NOTE FOR ALL EDITORS**

The command to launch the language server might depend on which editor and version manager combination you are using.
In order to work properly, the Ruby LSP must be launched with the Ruby version being used by the project you are working
on and with the correct Bundler environment set.

If you normally launch your editor from the terminal in a shell session where the Ruby environment is already activated,
then you can probably just use `ruby-lsp` as the command.

If you're seeing issues related to not finding the right gems or not being able to locate the `ruby-lsp` executable,
then you may need to ensure that the environment is properly configured by the version manager before you try to run the
`ruby-lsp` executable. How to do this will depend on which version manager you use. Here are some examples:

If your version manager exposes a command to run an executable within the context of the current Ruby, use that:

- `mise x -- ruby-lsp`
- `shadowenv exec -- ruby-lsp`

If your version manager creates gem executable shims that perform the automatic version switching, then use those:

- `~/.rbenv/shims/ruby-lsp`
- `~/.asdf/shims/ruby-lsp`

If your version manager doesn't provide either of those, then activate the environment and run the executable:

- `chruby $(cat .ruby-version) && ruby-lsp`

These strategies will ensure that the `ruby-lsp` executable is invoked with the correct Ruby version, `GEM_HOME` and
`GEM_PATH`, which are necessary for proper integration with your project.

<!-- When adding a new editor to the list, either link directly to a website containing the instructions or link to a
new H2 header in this file containing the instructions. -->

Expand Down Expand Up @@ -112,29 +142,8 @@ require("lspconfig").ruby_lsp.setup({

## LazyVim LSP

For LazyVim, you can add the ruby-lsp by creating a file in your plugins folder (`~/.config/nvim/lua/plugins/ruby_lsp.lua`) and adding the following:

```lua
-- ~/.config/nvim/lua/plugins/ruby_lsp.lua

return {
{
"neovim/nvim-lspconfig",
---@class PluginLspOpts
opts = {
---@type lspconfig.options
servers = {
-- disable solargraph from auto running when you open ruby files
solargraph = {
autostart = false
},
-- ruby_lsp will be automatically installed with mason and loaded with lspconfig
ruby_lsp = {},
},
},
},
}
```
[As of v12.33.0](https://github.com/LazyVim/LazyVim/pull/3652), Ruby LSP is the default LSP for Ruby and no configuration should be needed, other
than ensuring your Ruby version manager is set up as described above.

## Sublime Text LSP

Expand Down Expand Up @@ -174,4 +183,20 @@ You can use the Ruby LSP with RubyMine (or IntelliJ IDEA Ultimate) through the f

Note that there might be overlapping functionality when using it with RubyMine, given that the IDE provides similar features as the ones coming from the Ruby LSP.

[Ruby LSP plugin](https://plugins.jetbrains.com/plugin/24413-ruby-lsp)
[Ruby LSP plugin](https://plugins.jetbrains.com/plugin/24413-ruby-lsp)

# Indexing Configuration

To configure indexing, pass a JSON hash as part of the initialization options for your editor, for example:

```json
{
"indexing": {
"excludedPatterns": ["**/test/**.rb"],
"includedPatterns": ["**/bin/**"],
"excludedGems": ["rubocop", "rubocop-performance"],
"includedPatterns": ["rake"],
"excludedMagicComments": ["compiled:true"]
}
}
```
22 changes: 11 additions & 11 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ GIT
PATH
remote: .
specs:
ruby-lsp (0.17.4)
ruby-lsp (0.17.11)
language_server-protocol (~> 3.17.0)
prism (>= 0.29.0, < 0.31)
rbs (>= 3, < 4)
Expand Down Expand Up @@ -61,8 +61,8 @@ GEM
regexp_parser (2.9.2)
reline (0.5.0)
io-console (~> 0.5)
rexml (3.2.8)
strscan (>= 3.0.9)
rexml (3.3.2)
strscan
rubocop (1.64.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
Expand Down Expand Up @@ -95,14 +95,14 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
sorbet (0.5.11406)
sorbet-static (= 0.5.11406)
sorbet-runtime (0.5.11406)
sorbet-static (0.5.11406-universal-darwin)
sorbet-static (0.5.11406-x86_64-linux)
sorbet-static-and-runtime (0.5.11406)
sorbet (= 0.5.11406)
sorbet-runtime (= 0.5.11406)
sorbet (0.5.11481)
sorbet-static (= 0.5.11481)
sorbet-runtime (0.5.11481)
sorbet-static (0.5.11481-universal-darwin)
sorbet-static (0.5.11481-x86_64-linux)
sorbet-static-and-runtime (0.5.11481)
sorbet (= 0.5.11481)
sorbet-runtime (= 0.5.11481)
spoom (1.3.0)
erubi (>= 1.10.0)
prism (>= 0.19.0)
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The Ruby LSP features include
- Completion for classes, modules, constants and require paths
- Fuzzy search classes, modules and constants anywhere in the project and its dependencies (workspace symbol)

Adding method support for definition, completion, hover and workspace symbol is partially supported, but not yet complete. Follow progress in https://github.com/Shopify/ruby-lsp/issues/899
As of July 2024, Ruby LSP has received significant enhancements to its code navigation features. For an in-depth look at these improvements, including video demonstrations, check out this [article](https://railsatscale.com/2024-07-18-mastering-ruby-code-navigation-major-enhancements-in-ruby-lsp-2024/). Despite these advancements, we plan to continue enhancing its code navigation support even further. You can follow our progress on this [GitHub issue](https://github.com/Shopify/ruby-lsp/issues/899).

See complete information about features [here](https://shopify.github.io/ruby-lsp/RubyLsp/Requests.html).

Expand Down Expand Up @@ -78,7 +78,12 @@ default gems, except for
- Gems that only appear under the `:development` group
- All Ruby files under `test/**/*.rb`

By creating a `.index.yml` file, these configurations can be overridden and tuned. Note that indexing dependent behavior, such as definition, hover, completion or workspace symbol will be impacted by the configurations placed here.
This behaviour can be overridden and tuned. Learn how to configure it [for VS Code](vscode/README.md#Indexing-Configuration) or [for other editors](EDITORS.md#Indexing-Configuration).

Note that indexing-dependent behavior, such as definition, hover, completion or workspace symbol will be impacted by
the configuration changes.

The older approach of using a `.index.yml` file has been deprecated and will be removed in a future release.

```yaml
# Exclude files based on a given pattern. Often used to exclude test files or fixtures
Expand Down Expand Up @@ -109,6 +114,10 @@ features. This is the mechanism that powers addons like
- [Ruby LSP RSpec](https://github.com/st0012/ruby-lsp-rspec)
- [Ruby LSP rubyfmt](https://github.com/jscharf/ruby-lsp-rubyfmt)
Additionally, some tools may include a Ruby LSP addon directly, like
- [Standard Ruby (from v1.39.1)](https://github.com/standardrb/standard/wiki/IDE:-vscode#using-ruby-lsp)
Other community driven addons can be found in [rubygems](https://rubygems.org/search?query=name%3A+ruby-lsp) by
searching for the `ruby-lsp` prefix.

Expand Down
Loading

0 comments on commit 0106252

Please sign in to comment.