From c8890af8d42c821e41c81eeda6d861fcffcbdadc Mon Sep 17 00:00:00 2001 From: Leo Correa Date: Sun, 20 Jul 2025 12:13:33 +0200 Subject: [PATCH] Add initialization_options to Sorbet LSP linter (#4954) * Add initialization_options to Sorbet LSP linter Using a predefined object will ensure that Sorbet always receives an object instead of an array. LSP defines the initializationOptions as anything. Unfortunately Sorbet is too strict and raises an error when anything other than an object is passed which causes the linter to fail * Document empty objects will prevent Sorbet from properly initializing --- ale_linters/ruby/sorbet.vim | 5 +++-- doc/ale-ruby.txt | 17 +++++++++++++++++ test/linter/test_sorbet.vader | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ale_linters/ruby/sorbet.vim b/ale_linters/ruby/sorbet.vim index c67e20cc..abe758bb 100644 --- a/ale_linters/ruby/sorbet.vim +++ b/ale_linters/ruby/sorbet.vim @@ -1,6 +1,7 @@ call ale#Set('ruby_sorbet_executable', 'srb') call ale#Set('ruby_sorbet_options', '') call ale#Set('ruby_sorbet_enable_watchman', 0) +call ale#Set('ruby_sorbet_initialization_options', { 'highlightUntyped': v:false }) function! ale_linters#ruby#sorbet#GetCommand(buffer) abort let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') @@ -21,6 +22,6 @@ call ale#linter#Define('ruby', { \ 'language': 'ruby', \ 'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')}, \ 'command': function('ale_linters#ruby#sorbet#GetCommand'), -\ 'project_root': function('ale#ruby#FindProjectRoot') +\ 'project_root': function('ale#ruby#FindProjectRoot'), +\ 'initialization_options': {b -> ale#Var(b, 'ruby_sorbet_initialization_options')} \}) - diff --git a/doc/ale-ruby.txt b/doc/ale-ruby.txt index 517317bd..57f17dd5 100644 --- a/doc/ale-ruby.txt +++ b/doc/ale-ruby.txt @@ -267,6 +267,23 @@ g:ale_ruby_sorbet_enable_watchman to files from outside of vim. Defaults to disable watchman because it requires watchman to be installed separately from sorbet. + *ale-options.ruby_sorbet_initialization_options* + *g:ale_ruby_sorbet_initialization_options* + *b:ale_ruby_sorbet_initialization_options* +ruby_sorbet_initialization_options +g:ale_ruby_sorbet_initialization_options + Type: |Dictionary| + Default: `{ 'highlightUntyped': v:false }` + + This variable can be changed to modify initialization options provided to + the Sorbet language server. By default, a minimal object with defaults is + provided to ensure proper LSP initialization. + + Setting this variable to a an empty object will cause sorbet LSP to + fail during initialization. + + See https://sorbet.org/docs/lsp#initialize-request for available options. + =============================================================================== standardrb *ale-ruby-standardrb* diff --git a/test/linter/test_sorbet.vader b/test/linter/test_sorbet.vader index fe758635..7b7ce643 100644 --- a/test/linter/test_sorbet.vader +++ b/test/linter/test_sorbet.vader @@ -6,6 +6,7 @@ Before: let g:ale_ruby_sorbet_executable = 'srb' let g:ale_ruby_sorbet_options = '' let g:ale_ruby_sorbet_enable_watchman = 0 + let g:ale_ruby_sorbet_initialization_options = { 'highlightUntyped': v:false } After: call ale#assert#TearDownLinterTest() @@ -32,3 +33,11 @@ Execute(Setting bundle appends 'exec srb tc'): AssertLinter 'path to/bundle', ale#Escape('path to/bundle') \ . ' exec srb' \ . ' tc --lsp --disable-watchman' + +Execute(Should use predetermined initialization_options by default): + AssertLSPOptions { 'highlightUntyped': v:false } + +Execute(Should be able to set custom initialization_options): + let g:ale_ruby_sorbet_initialization_options = {'enableTypedFalse': v:true} + + AssertLSPOptions {'enableTypedFalse': v:true}