Skip to content

WIP: Server addons #438

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

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo"
gem "tzinfo-data"
end

gem "ruby-lsp", github: "Shopify/ruby-lsp", branch: "andyw8/add-entries-for"
31 changes: 16 additions & 15 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ GIT
rdoc (6.6.3.1)
psych (>= 4.0.0)

GIT
remote: https://github.com/Shopify/ruby-lsp.git
revision: 67727d218fa1bd483e6642494f950760fd3af917
branch: andyw8/add-entries-for
specs:
ruby-lsp (0.17.17)
language_server-protocol (~> 3.17.0)
prism (>= 0.29.0, < 0.31)
rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782)

PATH
remote: .
specs:
Expand Down Expand Up @@ -146,8 +157,6 @@ GEM
nio4r (2.7.3)
nokogiri (1.16.5-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.5-x64-mingw-ucrt)
racc (~> 1.4)
nokogiri (1.16.5-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.5-x86_64-linux)
Expand Down Expand Up @@ -202,7 +211,7 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.2.1)
rbi (0.1.13)
rbi (0.1.14)
prism (>= 0.18.0, < 1.0.0)
sorbet-runtime (>= 0.5.9204)
rbs (3.5.2)
Expand Down Expand Up @@ -234,11 +243,6 @@ GEM
rubocop (~> 1.51)
rubocop-sorbet (0.8.3)
rubocop (>= 0.90.0)
ruby-lsp (0.17.12)
language_server-protocol (~> 3.17.0)
prism (>= 0.29.0, < 0.31)
rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
sorbet (0.5.11406)
Expand All @@ -249,22 +253,21 @@ GEM
sorbet-static-and-runtime (0.5.11406)
sorbet (= 0.5.11406)
sorbet-runtime (= 0.5.11406)
spoom (1.3.0)
spoom (1.3.2)
erubi (>= 1.10.0)
prism (>= 0.19.0)
sorbet-static-and-runtime (>= 0.5.10187)
thor (>= 0.19.2)
sqlite3 (1.7.3-arm64-darwin)
sqlite3 (1.7.3-x64-mingw-ucrt)
sqlite3 (1.7.3-x86_64-darwin)
sqlite3 (1.7.3-x86_64-linux)
stringio (3.1.0)
strscan (3.1.0)
tapioca (0.13.3)
tapioca (0.16.0)
bundler (>= 2.2.25)
netrc (>= 0.11.0)
parallel (>= 1.21.0)
rbi (>= 0.1.4, < 0.2)
rbi (>= 0.1.14, < 0.2)
sorbet-static-and-runtime (>= 0.5.11087)
spoom (>= 1.2.0)
thor (>= 1.2.0)
Expand All @@ -273,8 +276,6 @@ GEM
timeout (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2024.1)
tzinfo (>= 1.0.0)
unicode-display_width (2.5.0)
webmock (3.23.1)
addressable (>= 2.8.0)
Expand All @@ -292,7 +293,6 @@ GEM

PLATFORMS
arm64-darwin
x64-mingw-ucrt
x86_64-darwin
x86_64-linux

Expand All @@ -307,6 +307,7 @@ DEPENDENCIES
rubocop-rake (~> 0.6.0)
rubocop-shopify (~> 2.15)
rubocop-sorbet (~> 0.8)
ruby-lsp!
ruby-lsp-rails!
sorbet-static-and-runtime
sqlite3 (< 2)
Expand Down
50 changes: 48 additions & 2 deletions lib/ruby_lsp/ruby_lsp_rails/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,30 @@

module RubyLsp
module Rails
class InvalidAddonError < RuntimeError
end

class Server
class << self
def require_server_addon(gem_name)
require "ruby_lsp/#{gem_name}/addon"
Object.const_get("RubyLsp::#{gem_name.classify}::Addon") # rubocop:disable Sorbet/ConstantsFromStrings
Copy link
Contributor Author

@andyw8 andyw8 Aug 27, 2024

Choose a reason for hiding this comment

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

This assumes a naming convention such that foo_bar would have an addon named RubyLsp::FooBar::Addon.

rescue LoadError, NameError
raise InvalidAddonError, "Failed to load addon '#{gem_name}'"
end
end

VOID = Object.new

def initialize
$stdin.sync = true
$stdout.sync = true
$stderr.sync = true
$stdin.binmode
$stdout.binmode
$stderr.binmode
@running = true
@addons = {}
end

def start
Expand All @@ -41,6 +56,39 @@ def start
end

def execute(request, params)
if request.include?(".")
execute_for_addon(request, params)
else
execute_for_ruby_lsp_rails(request, params)
end
end

private

def execute_for_addon(request, params)
addon, command = request.split(".")

unless addon.present? && command.present?
return { error: "Invalid request format: #{request}" }
end

begin
@addons[addon.to_sym] ||= self.class.require_server_addon(addon).new
rescue InvalidAddonError
return { error: "Addon '#{addon}' setup failed" }
end

# TODO: Verify error is seen
unless @addons[addon.to_sym]
return { error: "Loading addon '#{addon}' failed" }
end

addon = @addons.fetch(addon.to_sym)
addon.send(command, params)
VOID
end

def execute_for_ruby_lsp_rails(request, params)
case request
when "shutdown"
@running = false
Expand All @@ -63,8 +111,6 @@ def execute(request, params)
{ error: e.full_message(highlight: false) }
end

private

def resolve_route_info(requirements)
if requirements[:controller]
requirements[:controller] = requirements.fetch(:controller).underscore.delete_suffix("_controller")
Expand Down
Loading
Loading