#!/usr/bin/env ruby # frozen_string_literal: true require "optparse" original_args = ARGV.dup options = {} parser = OptionParser.new do |opts| opts.banner = "Usage: ruby-lsp [options]" opts.on("--version", "Print ruby-lsp version") do require "ruby-lsp" puts RubyLsp::VERSION exit(0) end opts.on("--debug", "Launch the Ruby LSP with a debugger attached") do options[:debug] = true end opts.on( "--branch [BRANCH]", "Launch the Ruby LSP using the specified branch rather than the release version", ) do |branch| options[:branch] = branch end opts.on("-h", "--help", "Print this help") do puts opts.help puts puts "See https://shopify.github.io/ruby-lsp/ for more information" exit(0) end end begin parser.parse! rescue OptionParser::InvalidOption => e warn(e) warn("") warn(parser.help) exit(1) end # When we're running without bundler, then we need to make sure the custom bundle is fully configured and re-execute # using `BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle exec ruby-lsp` so that we have access to the gems that are a part of # the application's bundle if ENV["BUNDLE_GEMFILE"].nil? require_relative "../lib/ruby_lsp/setup_bundler" begin bundle_gemfile, bundle_path, bundle_app_config = RubyLsp::SetupBundler.new(Dir.pwd, branch: options[:branch]).setup! rescue RubyLsp::SetupBundler::BundleNotLocked warn("Project contains a Gemfile, but no Gemfile.lock. Run `bundle install` to lock gems and restart the server") exit(78) end env = { "BUNDLE_GEMFILE" => bundle_gemfile } env["BUNDLE_PATH"] = bundle_path if bundle_path env["BUNDLE_APP_CONFIG"] = bundle_app_config if bundle_app_config exit exec(env, "bundle exec ruby-lsp #{original_args.join(" ")}") end require "sorbet-runtime" begin T::Configuration.default_checked_level = :never # Suppresses call validation errors T::Configuration.call_validation_error_handler = ->(*) {} # Suppresses errors caused by T.cast, T.let, T.must, etc. T::Configuration.inline_type_error_handler = ->(*) {} # Suppresses errors caused by incorrect parameter ordering T::Configuration.sig_validation_error_handler = ->(*) {} rescue # Need this rescue so that if another gem has # already set the checked level by the time we # get to it, we don't fail outright. nil end require_relative "../lib/ruby_lsp/internal" if options[:debug] if ["x64-mingw-ucrt", "x64-mingw32"].include?(RUBY_PLATFORM) puts "Debugging is not supported on Windows" exit 1 end sockets_dir = "/tmp/ruby-lsp-debug-sockets" Dir.mkdir(sockets_dir) unless Dir.exist?(sockets_dir) # ruby-debug-ENV["USER"] is an implicit naming pattern in ruby/debug # if it's not present, rdbg will not find the socket socket_identifier = "ruby-debug-#{ENV["USER"]}-#{File.basename(Dir.pwd)}.sock" ENV["RUBY_DEBUG_SOCK_PATH"] = "#{sockets_dir}/#{socket_identifier}" begin require "debug/open_nonstop" rescue LoadError warn("You need to install the debug gem to use the --debug flag") end end RubyLsp::Server.new.start