ruby_language_server 0.3.16 → 0.3.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.txt +7 -0
- data/Gemfile.lock +61 -57
- data/Makefile +5 -0
- data/README.md +10 -7
- data/lib/config/initializers/active_record.rb +4 -5
- data/lib/db/schema.rb +58 -36
- data/lib/ruby_language_server/code_file.rb +6 -6
- data/lib/ruby_language_server/completion.rb +1 -9
- data/lib/ruby_language_server/good_cop.rb +4 -2
- data/lib/ruby_language_server/io.rb +12 -6
- data/lib/ruby_language_server/location.rb +1 -1
- data/lib/ruby_language_server/logger.rb +2 -3
- data/lib/ruby_language_server/project_manager.rb +25 -17
- data/lib/ruby_language_server/scope_data/scope.rb +20 -4
- data/lib/ruby_language_server/scope_data/variable.rb +4 -4
- data/lib/ruby_language_server/scope_parser.rb +15 -47
- data/lib/ruby_language_server/server.rb +2 -2
- data/lib/ruby_language_server/version.rb +1 -1
- data/ruby_language_server.gemspec +11 -9
- metadata +41 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b9331721f750df7c683c22e8afb8591e002cdc779ba2b99fd94566f7d34e11e
|
4
|
+
data.tar.gz: a9865c1ca41b3860d4651f477ea4f0595c917e5730a01b135c5aee75e8d62da6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c48ba51bcd0f863a4df9003d482c9e7e7891a5788bb247f30d0306fd5f5171d45bc93687c4d78f429ec49a78c2b769e3ec9a20c50b3c2ed39a0315314df4001
|
7
|
+
data.tar.gz: 6035b4ab5245d9f5abbc20a5c59595b22540fef7fd3747bda92aa52f84c53affec76cb9d8d595245846a3a9e1d1a6b8b1c19b1d36b35952ba37e9862fb496d4d
|
data/CHANGELOG.txt
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby_language_server (0.3.
|
5
|
-
activerecord (~>
|
4
|
+
ruby_language_server (0.3.17)
|
5
|
+
activerecord (~> 7.0)
|
6
6
|
amatch
|
7
7
|
bundler
|
8
8
|
etc
|
9
9
|
fuzzy_match
|
10
10
|
json
|
11
|
-
rubocop
|
11
|
+
rubocop (> 1.38.0)
|
12
|
+
rubocop-ast (> 1.32.0)
|
12
13
|
rubocop-performance
|
13
14
|
rubocop-rspec
|
14
|
-
sqlite3
|
15
|
+
sqlite3 (< 1.5.0)
|
15
16
|
|
16
17
|
GEM
|
17
18
|
remote: https://rubygems.org/
|
18
19
|
specs:
|
19
|
-
activemodel (
|
20
|
-
activesupport (=
|
21
|
-
activerecord (
|
22
|
-
activemodel (=
|
23
|
-
activesupport (=
|
24
|
-
activesupport (
|
20
|
+
activemodel (7.0.7.2)
|
21
|
+
activesupport (= 7.0.7.2)
|
22
|
+
activerecord (7.0.7.2)
|
23
|
+
activemodel (= 7.0.7.2)
|
24
|
+
activesupport (= 7.0.7.2)
|
25
|
+
activesupport (7.0.7.2)
|
25
26
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
26
27
|
i18n (>= 1.6, < 2)
|
27
28
|
minitest (>= 5.1)
|
28
29
|
tzinfo (~> 2.0)
|
29
|
-
|
30
|
-
amatch (0.4.0)
|
30
|
+
amatch (0.4.1)
|
31
31
|
mize
|
32
32
|
tins (~> 1.0)
|
33
33
|
ansi (1.5.0)
|
@@ -35,37 +35,37 @@ GEM
|
|
35
35
|
builder (3.2.4)
|
36
36
|
byebug (11.1.3)
|
37
37
|
coderay (1.1.3)
|
38
|
-
concurrent-ruby (1.
|
39
|
-
etc (1.
|
40
|
-
ffi (1.15.
|
41
|
-
formatador (
|
38
|
+
concurrent-ruby (1.2.2)
|
39
|
+
etc (1.3.0)
|
40
|
+
ffi (1.15.5)
|
41
|
+
formatador (1.1.0)
|
42
42
|
fuzzy_match (2.1.0)
|
43
|
-
guard (2.
|
43
|
+
guard (2.18.0)
|
44
44
|
formatador (>= 0.2.4)
|
45
45
|
listen (>= 2.7, < 4.0)
|
46
46
|
lumberjack (>= 1.0.12, < 2.0)
|
47
47
|
nenv (~> 0.1)
|
48
48
|
notiffany (~> 0.0)
|
49
|
-
pry (>= 0.
|
49
|
+
pry (>= 0.13.0)
|
50
50
|
shellany (~> 0.0)
|
51
51
|
thor (>= 0.18.1)
|
52
52
|
guard-compat (1.2.1)
|
53
53
|
guard-minitest (2.4.6)
|
54
54
|
guard-compat (~> 1.2)
|
55
55
|
minitest (>= 3.0)
|
56
|
-
guard-rubocop (1.
|
56
|
+
guard-rubocop (1.5.0)
|
57
57
|
guard (~> 2.0)
|
58
58
|
rubocop (< 2.0)
|
59
|
-
i18n (1.
|
59
|
+
i18n (1.14.1)
|
60
60
|
concurrent-ruby (~> 1.0)
|
61
|
-
json (2.
|
62
|
-
listen (3.
|
61
|
+
json (2.6.2)
|
62
|
+
listen (3.7.1)
|
63
63
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
64
64
|
rb-inotify (~> 0.9, >= 0.9.10)
|
65
65
|
lumberjack (1.2.8)
|
66
66
|
method_source (1.0.0)
|
67
|
-
minitest (5.
|
68
|
-
minitest-reporters (1.
|
67
|
+
minitest (5.16.3)
|
68
|
+
minitest-reporters (1.5.0)
|
69
69
|
ansi
|
70
70
|
builder
|
71
71
|
minitest (>= 5.0)
|
@@ -76,70 +76,74 @@ GEM
|
|
76
76
|
notiffany (0.1.3)
|
77
77
|
nenv (~> 0.1)
|
78
78
|
shellany (~> 0.0)
|
79
|
-
parallel (1.
|
80
|
-
parser (3.
|
79
|
+
parallel (1.22.1)
|
80
|
+
parser (3.3.4.2)
|
81
81
|
ast (~> 2.4.1)
|
82
|
+
racc
|
82
83
|
protocol (2.0.0)
|
83
84
|
ruby_parser (~> 3.0)
|
84
|
-
pry (0.
|
85
|
+
pry (0.14.1)
|
85
86
|
coderay (~> 1.1)
|
86
87
|
method_source (~> 1.0)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
rake (13.0.3)
|
92
|
-
rb-fsevent (0.10.4)
|
88
|
+
racc (1.8.1)
|
89
|
+
rainbow (3.1.1)
|
90
|
+
rake (13.0.6)
|
91
|
+
rb-fsevent (0.11.2)
|
93
92
|
rb-inotify (0.10.1)
|
94
93
|
ffi (~> 1.0)
|
95
|
-
regexp_parser (2.
|
94
|
+
regexp_parser (2.6.0)
|
96
95
|
rexml (3.2.5)
|
97
|
-
rubocop (1.
|
96
|
+
rubocop (1.42.0)
|
97
|
+
json (~> 2.3)
|
98
98
|
parallel (~> 1.10)
|
99
|
-
parser (>= 3.
|
99
|
+
parser (>= 3.1.2.1)
|
100
100
|
rainbow (>= 2.2.2, < 4.0)
|
101
101
|
regexp_parser (>= 1.8, < 3.0)
|
102
|
-
rexml
|
103
|
-
rubocop-ast (>= 1.
|
102
|
+
rexml (>= 3.2.5, < 4.0)
|
103
|
+
rubocop-ast (>= 1.24.1, < 2.0)
|
104
104
|
ruby-progressbar (~> 1.7)
|
105
105
|
unicode-display_width (>= 1.4.0, < 3.0)
|
106
|
-
rubocop-ast (1.
|
107
|
-
parser (>=
|
108
|
-
rubocop-
|
106
|
+
rubocop-ast (1.32.1)
|
107
|
+
parser (>= 3.3.1.0)
|
108
|
+
rubocop-minitest (0.34.5)
|
109
|
+
rubocop (>= 1.39, < 2.0)
|
110
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
111
|
+
rubocop-performance (1.19.1)
|
109
112
|
rubocop (>= 1.7.0, < 2.0)
|
110
113
|
rubocop-ast (>= 0.4.0)
|
111
|
-
rubocop-
|
114
|
+
rubocop-rake (0.6.0)
|
112
115
|
rubocop (~> 1.0)
|
113
|
-
|
116
|
+
rubocop-rspec (3.0.0)
|
117
|
+
rubocop (~> 1.40)
|
114
118
|
ruby-progressbar (1.11.0)
|
115
|
-
ruby_parser (3.
|
116
|
-
sexp_processor (~> 4.
|
117
|
-
sexp_processor (4.
|
119
|
+
ruby_parser (3.19.1)
|
120
|
+
sexp_processor (~> 4.16)
|
121
|
+
sexp_processor (4.16.1)
|
118
122
|
shellany (0.0.1)
|
119
|
-
sqlite3 (1.4.
|
123
|
+
sqlite3 (1.4.4)
|
120
124
|
sync (0.5.0)
|
121
|
-
thor (1.1
|
122
|
-
tins (1.
|
125
|
+
thor (1.2.1)
|
126
|
+
tins (1.31.1)
|
123
127
|
sync
|
124
|
-
tzinfo (2.0.
|
128
|
+
tzinfo (2.0.6)
|
125
129
|
concurrent-ruby (~> 1.0)
|
126
|
-
unicode-display_width (2.
|
127
|
-
zeitwerk (2.4.2)
|
130
|
+
unicode-display_width (2.3.0)
|
128
131
|
|
129
132
|
PLATFORMS
|
130
|
-
|
133
|
+
aarch64-linux-musl
|
134
|
+
x86_64-linux
|
131
135
|
|
132
136
|
DEPENDENCIES
|
137
|
+
byebug
|
133
138
|
guard
|
134
139
|
guard-minitest
|
135
140
|
guard-rubocop
|
136
141
|
minitest
|
137
142
|
minitest-reporters
|
138
|
-
pry
|
139
|
-
pry-byebug
|
140
143
|
rake
|
144
|
+
rubocop-minitest
|
145
|
+
rubocop-rake
|
141
146
|
ruby_language_server!
|
142
|
-
sexp_processor
|
143
147
|
|
144
148
|
BUNDLED WITH
|
145
|
-
2.
|
149
|
+
2.3.25
|
data/Makefile
CHANGED
@@ -39,3 +39,8 @@ gem: image
|
|
39
39
|
# Requires rubygems be installed on host
|
40
40
|
gem_release: gem
|
41
41
|
docker run -it --rm $(LOCAL_LINK) $(PROJECT_NAME) gem push $(PROJECT_NAME)*.gem
|
42
|
+
|
43
|
+
publish_cross_platform_image:
|
44
|
+
(docker buildx ls | grep mybuilder) || docker buildx create --name mybuilder
|
45
|
+
docker buildx use mybuilder
|
46
|
+
docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t kwerle/$(PROJECT_NAME) .
|
data/README.md
CHANGED
@@ -31,17 +31,17 @@ You probably want to use one of the developed integrations:
|
|
31
31
|
|
32
32
|
# Development
|
33
33
|
|
34
|
+
Master branch is for releases. Develop branch is for ongoing development. Fork off develop;
|
35
|
+
I'll merge to master for releases.
|
36
|
+
|
34
37
|
Clone. I love git [HubFlow](https://datasift.github.io/gitflow/).
|
35
38
|
|
36
39
|
Check out the [Makefile](Makefile). You are going to want to do
|
37
40
|
`make guard` in one window and `make continuous_development` in another.
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
* CMD-ALT-i will show debugging info
|
43
|
-
|
44
|
-
Write tests and guard will run them. Make changes and reload the window. Test them out.
|
42
|
+
I use vscode with the "Ruby Language Server" extension install. I edit the settings to use
|
43
|
+
the docker image local_ruby_language_server. Quitting and restarting vscode to load the next
|
44
|
+
iteration.
|
45
45
|
|
46
46
|
# Similar
|
47
47
|
|
@@ -50,12 +50,15 @@ Write tests and guard will run them. Make changes and reload the window. Test
|
|
50
50
|
|
51
51
|
# Release instructions to self
|
52
52
|
|
53
|
-
|
53
|
+
For gem release
|
54
54
|
* bump version in [version.rb](lib/ruby_language_server/version.rb) file and [Gemfile.lock](Gemfile.lock)
|
55
55
|
* [CHANGELOG.txt](CHANGELOG.txt)
|
56
56
|
* merge to master, etc
|
57
57
|
* `make gem_release`
|
58
58
|
|
59
|
+
For docker release
|
60
|
+
* `make publish_cross_platform_image`
|
61
|
+
|
59
62
|
# Authors
|
60
63
|
|
61
64
|
* [Kurt Werle](kurt@CircleW.org)
|
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
ActiveRecord::Base.establish_connection(
|
4
4
|
adapter: 'sqlite3',
|
5
|
-
database: '
|
6
|
-
|
7
|
-
|
8
|
-
checkout_timeout: 30.seconds # does not seem to help
|
5
|
+
database: '/database',
|
6
|
+
pool: 5,
|
7
|
+
timeout: 30.seconds # does not seem to help
|
9
8
|
)
|
10
9
|
|
11
10
|
database = ActiveRecord::Base.connection.instance_variable_get :@connection
|
@@ -21,7 +20,7 @@ database.enable_load_extension(0)
|
|
21
20
|
if ENV['LOG_LEVEL'] == 'DEBUG'
|
22
21
|
begin
|
23
22
|
warn('Turning on active record logging to active_record.log')
|
24
|
-
ActiveRecord::Base.logger = Logger.new(File.open('active_record.log', 'w'))
|
23
|
+
ActiveRecord::Base.logger = Logger.new(File.open('/active_record.log', 'w'))
|
25
24
|
rescue Exception => e
|
26
25
|
ActiveRecord::Base.logger = Logger.new($stderr)
|
27
26
|
ActiveRecord::Base.logger.error(e)
|
data/lib/db/schema.rb
CHANGED
@@ -1,44 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Schema
|
4
|
+
class << self
|
5
|
+
def load
|
6
|
+
ActiveRecord::Schema.define do
|
7
|
+
def write(*args)
|
8
|
+
RubyLanguageServer.logger.debug(args)
|
9
|
+
end
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
create_table :scopes, force: true do |t|
|
12
|
+
t.references :code_file
|
13
|
+
t.integer :parent_id
|
14
|
+
t.integer :top_line # first line
|
15
|
+
t.integer :bottom_line # last line
|
16
|
+
t.integer :column
|
17
|
+
t.string :name, default: ''
|
18
|
+
t.string :superclass_name
|
19
|
+
t.string :path
|
20
|
+
t.string :class_type, null: false
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
create_table :variables, force: true do |t|
|
25
|
-
t.references :code_file
|
26
|
-
t.references :scope
|
27
|
-
t.integer :line
|
28
|
-
t.integer :column
|
29
|
-
t.string :name
|
30
|
-
t.string :path
|
31
|
-
t.string :variable_type
|
32
|
-
end
|
23
|
+
add_index :scopes, :name
|
24
|
+
add_index :scopes, :path
|
25
|
+
add_index :scopes, :code_file
|
33
26
|
|
34
|
-
|
35
|
-
|
27
|
+
create_table :variables, force: true do |t|
|
28
|
+
t.references :code_file
|
29
|
+
t.references :scope
|
30
|
+
t.integer :line
|
31
|
+
t.integer :column
|
32
|
+
t.string :name
|
33
|
+
t.string :path
|
34
|
+
t.string :variable_type
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
add_index :variables, :name
|
38
|
+
add_index :variables, :code_file
|
39
|
+
|
40
|
+
create_table :code_files, force: true do |t|
|
41
|
+
t.string :uri
|
42
|
+
t.boolean :refresh_root_scope, default: true
|
43
|
+
t.text :text
|
44
|
+
end
|
42
45
|
|
43
|
-
|
46
|
+
add_index :code_files, :uri
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# If we dive in using a console attached to a running container we do NOT want to reset all the table data!
|
51
|
+
# Which it seems like sqlite is happy to do?
|
52
|
+
# So we utter some arcane sqlite code to find the existing tables if there are any.
|
53
|
+
def already_initialized
|
54
|
+
response = ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query "SELECT name FROM sqlite_master WHERE type='table'" }
|
55
|
+
response.rows.flatten.member?('code_files')
|
56
|
+
rescue ExceptionName
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize_if_needed
|
61
|
+
load unless already_initialized
|
62
|
+
end
|
63
|
+
end
|
44
64
|
end
|
65
|
+
|
66
|
+
Schema.initialize_if_needed
|
@@ -20,7 +20,7 @@ module RubyLanguageServer
|
|
20
20
|
def self.build(uri, text)
|
21
21
|
RubyLanguageServer.logger.debug("CodeFile initialize #{uri}")
|
22
22
|
|
23
|
-
create!(uri
|
23
|
+
create!(uri:, text:)
|
24
24
|
end
|
25
25
|
|
26
26
|
SYMBOL_KIND = {
|
@@ -70,7 +70,7 @@ module RubyLanguageServer
|
|
70
70
|
kind = 9 if scope.name == 'initialize' # Magical special case
|
71
71
|
scope_hash = {
|
72
72
|
name: scope.name,
|
73
|
-
kind
|
73
|
+
kind:,
|
74
74
|
location: Location.hash(uri, scope.top_line)
|
75
75
|
}
|
76
76
|
container_name = ancestor_scope_name(scope)
|
@@ -80,7 +80,7 @@ module RubyLanguageServer
|
|
80
80
|
tags += variables.constant_variables.reload.map do |variable|
|
81
81
|
name = variable.name
|
82
82
|
{
|
83
|
-
name
|
83
|
+
name:,
|
84
84
|
kind: SYMBOL_KIND[:constant],
|
85
85
|
location: Location.hash(uri, variable.line - 1),
|
86
86
|
containerName: variable.scope.name
|
@@ -108,7 +108,7 @@ module RubyLanguageServer
|
|
108
108
|
update(text: new_text, refresh_root_scope: true)
|
109
109
|
end
|
110
110
|
|
111
|
-
def refresh_scopes_if_needed
|
111
|
+
def refresh_scopes_if_needed(shallow: false)
|
112
112
|
return unless refresh_root_scope
|
113
113
|
|
114
114
|
RubyLanguageServer.logger.debug("Asking about root_scope for #{uri}")
|
@@ -117,7 +117,7 @@ module RubyLanguageServer
|
|
117
117
|
self.class.transaction do
|
118
118
|
scopes.clear
|
119
119
|
variables.clear
|
120
|
-
new_root = ScopeParser.new(text).root_scope
|
120
|
+
new_root = ScopeParser.new(text, shallow).root_scope
|
121
121
|
RubyLanguageServer.logger.debug("new_root.children #{new_root.children.as_json}") if new_root&.children
|
122
122
|
raise ActiveRecord::Rollback if new_root.nil? || new_root.children.blank?
|
123
123
|
|
@@ -132,7 +132,7 @@ module RubyLanguageServer
|
|
132
132
|
def context_at_location(position)
|
133
133
|
lines = text.split("\n")
|
134
134
|
line = lines[position.line]
|
135
|
-
return [] if line.nil? || line.strip.
|
135
|
+
return [] if line.nil? || line.strip.empty?
|
136
136
|
|
137
137
|
LineContext.for(line, position.character)
|
138
138
|
end
|
@@ -47,7 +47,7 @@ module RubyLanguageServer
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def scopes_with_name(name, scopes)
|
50
|
-
return scopes.where(name:
|
50
|
+
return scopes.where(name:) if scopes.respond_to?(:where)
|
51
51
|
|
52
52
|
scopes.select { |scope| scope.name == name }
|
53
53
|
end
|
@@ -80,14 +80,6 @@ module RubyLanguageServer
|
|
80
80
|
def scope_completions(word, scopes)
|
81
81
|
return module_completions(word) if word.match?(/\A[A-Z][a-z]/)
|
82
82
|
|
83
|
-
# scope_ids = scopes.map(&:id)
|
84
|
-
# word_scopes = scopes.to_a + RubyLanguageServer::ScopeData::Scope.where(parent_id: scope_ids)
|
85
|
-
# scope_words = word_scopes.select(&:named_scope?).sort_by(&:depth).map { |scope| [scope.name, scope] }
|
86
|
-
# variable_words = RubyLanguageServer::ScopeData::Variable.where(scope_id: scope_ids).map { |variable| [variable.name, variable.scope] }
|
87
|
-
# words = (scope_words + variable_words).to_h
|
88
|
-
# good_words = FuzzyMatch.new(words.keys, threshold: 0.01).find_all(word).slice(0..10) || []
|
89
|
-
# words = good_words.each_with_object({}) { |w, hash| hash[w] = {depth: words[w].depth, type: words[w].class_type} }.to_h
|
90
|
-
|
91
83
|
scope_ids = scopes.map(&:id)
|
92
84
|
word_scopes = scopes.to_a + RubyLanguageServer::ScopeData::Scope.where(parent_id: scope_ids).closest_to(word).limit(5)
|
93
85
|
scope_words = word_scopes.select(&:named_scope?).sort_by(&:depth).map { |scope| [scope.name, scope] }
|
@@ -102,7 +102,7 @@ module RubyLanguageServer
|
|
102
102
|
if excluded_file?(filename)
|
103
103
|
[]
|
104
104
|
else
|
105
|
-
ruby_version =
|
105
|
+
ruby_version = 3.1
|
106
106
|
processed_source = RuboCop::ProcessedSource.new(text, ruby_version, filename)
|
107
107
|
offenses = inspect_file(processed_source)
|
108
108
|
offenses.compact.flatten.reject(&:blank?) # reject blank because some are `false`
|
@@ -136,13 +136,15 @@ module RubyLanguageServer
|
|
136
136
|
|
137
137
|
class << self
|
138
138
|
def instance
|
139
|
+
return @instance if @instance
|
140
|
+
|
139
141
|
@config_path ||= config_path
|
140
142
|
config_path_timestamp = File.mtime(@config_path)
|
141
143
|
if @cached_config_path_timestamp.nil? || @cached_config_path_timestamp < config_path_timestamp
|
142
144
|
@cached_config_path_timestamp = config_path_timestamp
|
143
145
|
@instance = new(@config_path)
|
144
146
|
else
|
145
|
-
@instance
|
147
|
+
@instance = new
|
146
148
|
end
|
147
149
|
rescue StandardError => e
|
148
150
|
@instance = new(@config_path, e.to_s)
|
@@ -24,7 +24,7 @@ module RubyLanguageServer
|
|
24
24
|
def return_response(id, response, io = $stdout)
|
25
25
|
full_response = {
|
26
26
|
jsonrpc: '2.0',
|
27
|
-
id
|
27
|
+
id:,
|
28
28
|
result: response
|
29
29
|
}
|
30
30
|
response_body = JSON.unparse(full_response)
|
@@ -39,7 +39,7 @@ module RubyLanguageServer
|
|
39
39
|
full_response = {
|
40
40
|
jsonrpc: '2.0',
|
41
41
|
method: message,
|
42
|
-
params:
|
42
|
+
params:
|
43
43
|
}
|
44
44
|
body = JSON.unparse(full_response)
|
45
45
|
RubyLanguageServer.logger.info "send_notification body: #{body}"
|
@@ -58,11 +58,17 @@ module RubyLanguageServer
|
|
58
58
|
params = request_json['params']
|
59
59
|
method_name = "on_#{method_name.gsub(/[^\w]/, '_')}"
|
60
60
|
if @server.respond_to? method_name
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
response = ActiveRecord::Base.connection_pool.with_connection do
|
62
|
+
retries = 3
|
63
|
+
begin
|
64
|
+
@server.send(method_name, params)
|
65
|
+
rescue StandardError => e
|
66
|
+
RubyLanguageServer.logger.warn("Error updating: #{e}\n#{e.backtrace * "\n"}")
|
67
|
+
sleep 5
|
68
|
+
retries -= 1
|
69
|
+
retry unless retries <= 0
|
70
|
+
end
|
64
71
|
end
|
65
|
-
RubyLanguageServer.logger.debug 'UNLocking io'
|
66
72
|
exit(true) if response == 'EXIT'
|
67
73
|
[id, response]
|
68
74
|
else
|
@@ -3,12 +3,11 @@
|
|
3
3
|
require 'logger'
|
4
4
|
|
5
5
|
module RubyLanguageServer
|
6
|
-
level_name = ENV.fetch('LOG_LEVEL', 'error').upcase
|
7
|
-
# level_name = 'DEBUG'
|
6
|
+
level_name = ENV.fetch('LOG_LEVEL', 'error').upcase || 'DEBUG'
|
8
7
|
level = Logger::Severity.const_get(level_name)
|
9
8
|
class << self
|
10
9
|
attr_accessor :logger
|
11
10
|
end
|
12
|
-
@logger = ::Logger.new($stderr, level:
|
11
|
+
@logger = ::Logger.new($stderr, level:)
|
13
12
|
@logger.log(level, "Logger started at level #{level_name} -> #{level}")
|
14
13
|
end
|
@@ -22,7 +22,7 @@ module RubyLanguageServer
|
|
22
22
|
def root_path
|
23
23
|
# I'm torn about this. Should this be set in the Server? Or is this right.
|
24
24
|
# Rather than worry too much, I'll just do this here and change it later if it feels wrong.
|
25
|
-
path = ENV
|
25
|
+
path = ENV.fetch('RUBY_LANGUAGE_SERVER_PROJECT_ROOT') { @_root_path }
|
26
26
|
return path if path.nil?
|
27
27
|
|
28
28
|
path.end_with?(File::SEPARATOR) ? path : "#{path}#{File::SEPARATOR}"
|
@@ -179,28 +179,36 @@ module RubyLanguageServer
|
|
179
179
|
# data?: any
|
180
180
|
# }
|
181
181
|
|
182
|
-
def scan_all_project_files
|
182
|
+
def scan_all_project_files
|
183
183
|
project_ruby_files = Dir.glob("#{self.class.root_path}**/*.rb")
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
184
|
+
RubyLanguageServer.logger.debug('Threading up!')
|
185
|
+
root_uri = @root_uri
|
186
|
+
root_uri += '/' unless root_uri.end_with? '/'
|
187
|
+
# Using fork because this is run in a docker container that has fork.
|
188
|
+
# If you want to run this on some platform without fork, fork the code and PR it :-)
|
189
|
+
fork_id = fork do
|
188
190
|
project_ruby_files.each do |container_path|
|
189
|
-
# Let's not preload spec/test or vendor - yet..
|
190
|
-
next if container_path.match?(
|
191
|
+
# Let's not preload spec/test files or vendor - yet..
|
192
|
+
next if container_path.match?(/(spec\.rb|test\.rb|vendor)/)
|
191
193
|
|
192
194
|
text = File.read(container_path)
|
193
195
|
relative_path = container_path.delete_prefix(self.class.root_path)
|
194
196
|
host_uri = root_uri + relative_path
|
195
|
-
RubyLanguageServer.logger.debug
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
197
|
+
RubyLanguageServer.logger.debug("Threading #{host_uri}")
|
198
|
+
begin
|
199
|
+
ActiveRecord::Base.connection_pool.with_connection do |_connection|
|
200
|
+
update_document_content(host_uri, text)
|
201
|
+
code_file_for_uri(host_uri).refresh_scopes_if_needed(shallow: true)
|
202
|
+
end
|
203
|
+
rescue StandardError => e
|
204
|
+
RubyLanguageServer.logger.warn("Error updating: #{e}\n#{e.backtrace * "\n"}")
|
205
|
+
sleep 5
|
206
|
+
retry
|
200
207
|
end
|
201
|
-
RubyLanguageServer.logger.debug "Unlocking scan for #{container_path}"
|
202
208
|
end
|
203
209
|
end
|
210
|
+
RubyLanguageServer.logger.debug("Forked process id to look at other files: #{fork_id}")
|
211
|
+
Process.detach(fork_id)
|
204
212
|
end
|
205
213
|
|
206
214
|
# returns diagnostic info (if possible)
|
@@ -218,7 +226,7 @@ module RubyLanguageServer
|
|
218
226
|
# Maybe we should be sharing this GoodCop across instances
|
219
227
|
RubyLanguageServer.logger.debug("updated_diagnostics_for_codefile: #{code_file.uri}")
|
220
228
|
project_relative_filename = filename_relative_to_project(code_file.uri)
|
221
|
-
code_file.diagnostics = GoodCop.instance
|
229
|
+
code_file.diagnostics = GoodCop.instance&.diagnostics(code_file.text, project_relative_filename)
|
222
230
|
RubyLanguageServer.logger.debug("code_file.diagnostics: #{code_file.diagnostics}")
|
223
231
|
code_file.diagnostics
|
224
232
|
end
|
@@ -261,8 +269,8 @@ module RubyLanguageServer
|
|
261
269
|
end
|
262
270
|
|
263
271
|
def project_definitions_for(name)
|
264
|
-
scopes = RubyLanguageServer::ScopeData::Scope.where(name:
|
265
|
-
variables = RubyLanguageServer::ScopeData::Variable.constant_variables.where(name:
|
272
|
+
scopes = RubyLanguageServer::ScopeData::Scope.where(name:)
|
273
|
+
variables = RubyLanguageServer::ScopeData::Variable.constant_variables.where(name:)
|
266
274
|
(scopes + variables).reject { |scope| scope.code_file.nil? }.map do |scope|
|
267
275
|
Location.hash(scope.code_file.uri, scope.top_line, 1)
|
268
276
|
end
|
@@ -12,6 +12,8 @@ module RubyLanguageServer
|
|
12
12
|
belongs_to :parent, class_name: 'Scope', optional: true
|
13
13
|
has_many :children, class_name: 'Scope', foreign_key: :parent_id
|
14
14
|
|
15
|
+
validate :bottom_line_ge_top_line, unless: :root_scope?
|
16
|
+
|
15
17
|
scope :method_scopes, -> { where(class_type: TYPE_METHOD) }
|
16
18
|
scope :for_line, ->(line) { where('top_line <= ? AND bottom_line >= ?', line, line).or(where(parent_id: nil)) }
|
17
19
|
scope :by_path_length, -> { order(Arel.sql('length(path) DESC')) }
|
@@ -25,10 +27,10 @@ module RubyLanguageServer
|
|
25
27
|
def self.build(parent = nil, type = TYPE_ROOT, name = '', top_line = 1, column = 1)
|
26
28
|
full_name = [parent ? parent.full_name : nil, name].compact.join(JoinHash[type])
|
27
29
|
create!(
|
28
|
-
parent
|
29
|
-
top_line
|
30
|
-
column
|
31
|
-
name
|
30
|
+
parent:,
|
31
|
+
top_line:,
|
32
|
+
column:,
|
33
|
+
name:,
|
32
34
|
path: full_name,
|
33
35
|
class_type: type
|
34
36
|
)
|
@@ -77,11 +79,25 @@ module RubyLanguageServer
|
|
77
79
|
[TYPE_MODULE, TYPE_CLASS, TYPE_METHOD, TYPE_VARIABLE].include?(class_type)
|
78
80
|
end
|
79
81
|
|
82
|
+
# Called from ScopeParser when a peer of this block starts - because we don't have an end notifier.
|
83
|
+
# So we do some reasonable cleanup here.
|
84
|
+
def close(line)
|
85
|
+
return destroy! if block_scope? && variables.none?
|
86
|
+
|
87
|
+
self.top_line ||= variables.map(&:top_line).min
|
88
|
+
self.bottom_line = [bottom_line, line].compact.min
|
89
|
+
save!
|
90
|
+
end
|
91
|
+
|
80
92
|
private
|
81
93
|
|
82
94
|
def scope_parts
|
83
95
|
path&.split(/#{JoinHash.values.reject(&:blank?).uniq.join('|')}/)
|
84
96
|
end
|
97
|
+
|
98
|
+
def bottom_line_ge_top_line
|
99
|
+
errors.add(:bottom_line, 'must be greater than or equal to top line') if bottom_line && top_line && bottom_line < top_line
|
100
|
+
end
|
85
101
|
end
|
86
102
|
end
|
87
103
|
end
|
@@ -15,10 +15,10 @@ module RubyLanguageServer
|
|
15
15
|
def self.build(scope, name, line = 1, column = 1, type = TYPE_VARIABLE)
|
16
16
|
path = [scope.full_name, name].join(JoinHash[TYPE_VARIABLE])
|
17
17
|
create!(
|
18
|
-
line
|
19
|
-
column
|
20
|
-
name
|
21
|
-
path
|
18
|
+
line:,
|
19
|
+
column:,
|
20
|
+
name:,
|
21
|
+
path:,
|
22
22
|
variable_type: type
|
23
23
|
)
|
24
24
|
end
|
@@ -17,9 +17,10 @@ module RubyLanguageServer
|
|
17
17
|
include ScopeParserCommands::RubyCommands
|
18
18
|
attr_reader :sexp, :lines, :current_scope
|
19
19
|
|
20
|
-
def initialize(sexp, lines = 1)
|
20
|
+
def initialize(sexp, lines = 1, shallow = false)
|
21
21
|
@sexp = sexp
|
22
22
|
@lines = lines
|
23
|
+
@shallow = shallow
|
23
24
|
@root_scope = nil
|
24
25
|
end
|
25
26
|
|
@@ -226,38 +227,6 @@ module RubyLanguageServer
|
|
226
227
|
end
|
227
228
|
|
228
229
|
[:def_with_access, klass, method_name, access, line]
|
229
|
-
# when 'scope', 'named_scope'
|
230
|
-
# [:rails_def, :scope, args[1][0], line]
|
231
|
-
# when /^attr_(accessor|reader|writer)$/
|
232
|
-
# gen_reader = Regexp.last_match(1) != 'writer'
|
233
|
-
# gen_writer = Regexp.last_match(1) != 'reader'
|
234
|
-
# args[1..-1].each_with_object([]) do |arg, gen|
|
235
|
-
# gen << [:def, arg[0], line] if gen_reader
|
236
|
-
# gen << [:def, "#{arg[0]}=", line] if gen_writer
|
237
|
-
# end
|
238
|
-
# when 'has_many', 'has_and_belongs_to_many'
|
239
|
-
# a = args[1][0]
|
240
|
-
# kind = name.to_sym
|
241
|
-
# gen = []
|
242
|
-
# unless a.is_a?(Enumerable) && !a.is_a?(String)
|
243
|
-
# a = a.to_s
|
244
|
-
# gen << [:rails_def, kind, a, line]
|
245
|
-
# gen << [:rails_def, kind, "#{a}=", line]
|
246
|
-
# if (sing = a.chomp('s')) != a
|
247
|
-
# # poor man's singularize
|
248
|
-
# gen << [:rails_def, kind, "#{sing}_ids", line]
|
249
|
-
# gen << [:rails_def, kind, "#{sing}_ids=", line]
|
250
|
-
# end
|
251
|
-
# end
|
252
|
-
# gen
|
253
|
-
# when 'belongs_to', 'has_one'
|
254
|
-
# a = args[1][0]
|
255
|
-
# unless a.is_a?(Enumerable) && !a.is_a?(String)
|
256
|
-
# kind = name.to_sym
|
257
|
-
# %W[#{a} #{a}= build_#{a} create_#{a} create_#{a}!].inject([]) do |all, ident|
|
258
|
-
# all << [:rails_def, kind, ident, line]
|
259
|
-
# end
|
260
|
-
# end
|
261
230
|
end
|
262
231
|
end
|
263
232
|
end
|
@@ -265,19 +234,17 @@ module RubyLanguageServer
|
|
265
234
|
private
|
266
235
|
|
267
236
|
def add_variable(name, line, column, scope = @current_scope)
|
268
|
-
|
269
|
-
|
270
|
-
|
237
|
+
return if @shallow
|
238
|
+
|
239
|
+
newvar = scope.variables.where(name:).first_or_create!(
|
240
|
+
line:,
|
241
|
+
column:,
|
271
242
|
code_file: scope.code_file
|
272
243
|
)
|
273
244
|
if scope.top_line.blank?
|
274
245
|
scope.top_line = line
|
275
246
|
scope.save!
|
276
247
|
end
|
277
|
-
# new_variable = ScopeData::Variable.build(scope, name, line, column)
|
278
|
-
# # blocks don't declare their first line in the parser
|
279
|
-
# scope.top_line ||= line
|
280
|
-
# scope.variables << new_variable unless scope.has_variable_or_constant?(new_variable)
|
281
248
|
newvar
|
282
249
|
end
|
283
250
|
|
@@ -295,7 +262,11 @@ module RubyLanguageServer
|
|
295
262
|
def add_scope(args, rest, type)
|
296
263
|
(_, name, (line, column)) = args
|
297
264
|
scope = push_scope(type, name, line, column)
|
298
|
-
|
265
|
+
if type == ScopeData::Scope::TYPE_METHOD && @shallow
|
266
|
+
process([])
|
267
|
+
else
|
268
|
+
process(rest)
|
269
|
+
end
|
299
270
|
pop_scope
|
300
271
|
scope
|
301
272
|
end
|
@@ -316,10 +287,7 @@ module RubyLanguageServer
|
|
316
287
|
# The notion is that when you start the next scope, all the previous peers and unclosed descendents of the previous peer should be closed.
|
317
288
|
def close_sibling_scopes(line)
|
318
289
|
parent_scope = @current_scope
|
319
|
-
parent_scope&.descendants&.each
|
320
|
-
scope.bottom_line = [scope.bottom_line, line - 1].compact.min
|
321
|
-
scope.save!
|
322
|
-
end
|
290
|
+
parent_scope&.descendants&.each { |scope| scope.close(line) }
|
323
291
|
end
|
324
292
|
|
325
293
|
def pop_scope
|
@@ -333,14 +301,14 @@ module RubyLanguageServer
|
|
333
301
|
class ScopeParser < Ripper
|
334
302
|
attr_reader :root_scope
|
335
303
|
|
336
|
-
def initialize(text)
|
304
|
+
def initialize(text, shallow = false)
|
337
305
|
text ||= '' # empty is the same as nil - but it doesn't crash
|
338
306
|
begin
|
339
307
|
sexp = self.class.sexp(text)
|
340
308
|
rescue TypeError => e
|
341
309
|
RubyLanguageServer.logger.error("Exception in sexp: #{e} for text: #{text}")
|
342
310
|
end
|
343
|
-
processor = SEXPProcessor.new(sexp, text.split("\n").length)
|
311
|
+
processor = SEXPProcessor.new(sexp, text.split("\n").length, shallow)
|
344
312
|
@root_scope = processor.root_scope
|
345
313
|
end
|
346
314
|
end
|
@@ -17,7 +17,7 @@ module RubyLanguageServer
|
|
17
17
|
root_path = params['rootPath']
|
18
18
|
root_uri = params['rootUri']
|
19
19
|
@project_manager = ProjectManager.new(root_path, root_uri)
|
20
|
-
@project_manager.scan_all_project_files
|
20
|
+
@project_manager.scan_all_project_files
|
21
21
|
gem_string = ENV.fetch('ADDITIONAL_GEMS', nil)
|
22
22
|
gem_array = (gem_string.split(',').compact.map(&:strip).reject { |string| string == '' } if gem_string && !gem_string.empty?)
|
23
23
|
@project_manager.install_additional_gems(gem_array)
|
@@ -85,7 +85,7 @@ module RubyLanguageServer
|
|
85
85
|
|
86
86
|
def send_diagnostics(uri, text)
|
87
87
|
hash = @project_manager.update_document_content(uri, text)
|
88
|
-
io.send_notification('textDocument/publishDiagnostics', uri
|
88
|
+
io.send_notification('textDocument/publishDiagnostics', uri:, diagnostics: hash)
|
89
89
|
end
|
90
90
|
|
91
91
|
def on_textDocument_didOpen(params)
|
@@ -11,10 +11,10 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['kurt@CircleW.org']
|
12
12
|
|
13
13
|
spec.summary = 'Provide a language server implementation for ruby in ruby.'
|
14
|
-
spec.description = 'See https://microsoft.github.io/language-server-protocol/ "A Language Server is meant to provide the language-specific smarts and communicate with development tools over a protocol that enables inter-process communication."'
|
14
|
+
spec.description = 'Provide a language server implementation for ruby in ruby. See https://microsoft.github.io/language-server-protocol/ "A Language Server is meant to provide the language-specific smarts and communicate with development tools over a protocol that enables inter-process communication."'
|
15
15
|
spec.homepage = 'https://github.com/kwerle/ruby_language_server'
|
16
16
|
spec.license = 'MIT'
|
17
|
-
spec.required_ruby_version = '>=
|
17
|
+
spec.required_ruby_version = '>=3.1.0'
|
18
18
|
|
19
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
20
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.metadata['changelog_uri'] = 'https://github.com/kwerle/ruby_language_server/blob/develop/CHANGELOG.txt'
|
25
25
|
else
|
26
26
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
27
|
-
|
27
|
+
'public gem pushes.'
|
28
28
|
end
|
29
29
|
|
30
30
|
# Specify which files should be added to the gem when it is released.
|
@@ -40,23 +40,25 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_dependency 'json'
|
41
41
|
|
42
42
|
# No - do not put these in dev - they are needed for the app
|
43
|
-
spec.add_dependency 'rubocop'
|
43
|
+
spec.add_dependency 'rubocop', '>1.38.0' # Something broke in 1.38.0. Move to rubocop --server?
|
44
|
+
spec.add_dependency 'rubocop-ast', '>1.32.0' # Something broke in 1.38.0. Move to rubocop --server?
|
44
45
|
spec.add_dependency 'rubocop-performance' # Linter - no longer needed - use additional gems?
|
45
46
|
spec.add_dependency 'rubocop-rspec' # Linter - no longer needed - use additional gems?
|
46
47
|
|
47
48
|
spec.add_dependency 'amatch' # in c
|
48
49
|
spec.add_dependency 'fuzzy_match' # completion matching
|
49
50
|
|
50
|
-
spec.add_dependency 'activerecord', '~>
|
51
|
-
spec.add_dependency 'sqlite3'
|
51
|
+
spec.add_dependency 'activerecord', '~>7.0'
|
52
|
+
spec.add_dependency 'sqlite3', '<1.5.0' # 1.5.0 breaks in docker M1 at least
|
52
53
|
|
54
|
+
spec.add_development_dependency 'byebug'
|
53
55
|
spec.add_development_dependency 'guard'
|
54
56
|
spec.add_development_dependency 'guard-minitest'
|
55
57
|
spec.add_development_dependency 'guard-rubocop'
|
56
58
|
spec.add_development_dependency 'minitest'
|
57
59
|
spec.add_development_dependency 'minitest-reporters'
|
58
|
-
spec.add_development_dependency 'pry'
|
59
|
-
spec.add_development_dependency 'pry-byebug'
|
60
60
|
spec.add_development_dependency 'rake' # required by guard :-(
|
61
|
-
spec.add_development_dependency '
|
61
|
+
spec.add_development_dependency 'rubocop-minitest'
|
62
|
+
spec.add_development_dependency 'rubocop-rake'
|
63
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
62
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_language_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kurt Werle
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -56,16 +56,30 @@ dependencies:
|
|
56
56
|
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.38.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.38.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-ast
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.32.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.32.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rubocop-performance
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,30 +142,30 @@ dependencies:
|
|
128
142
|
requirements:
|
129
143
|
- - "~>"
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
145
|
+
version: '7.0'
|
132
146
|
type: :runtime
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
152
|
+
version: '7.0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: sqlite3
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
|
-
- - "
|
157
|
+
- - "<"
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
159
|
+
version: 1.5.0
|
146
160
|
type: :runtime
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- - "
|
164
|
+
- - "<"
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
166
|
+
version: 1.5.0
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
168
|
+
name: byebug
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
171
|
- - ">="
|
@@ -165,7 +179,7 @@ dependencies:
|
|
165
179
|
- !ruby/object:Gem::Version
|
166
180
|
version: '0'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
|
-
name: guard
|
182
|
+
name: guard
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - ">="
|
@@ -179,7 +193,7 @@ dependencies:
|
|
179
193
|
- !ruby/object:Gem::Version
|
180
194
|
version: '0'
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
|
-
name: guard-
|
196
|
+
name: guard-minitest
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
184
198
|
requirements:
|
185
199
|
- - ">="
|
@@ -193,7 +207,7 @@ dependencies:
|
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '0'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
210
|
+
name: guard-rubocop
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
198
212
|
requirements:
|
199
213
|
- - ">="
|
@@ -207,7 +221,7 @@ dependencies:
|
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
|
-
name: minitest
|
224
|
+
name: minitest
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
227
|
- - ">="
|
@@ -221,7 +235,7 @@ dependencies:
|
|
221
235
|
- !ruby/object:Gem::Version
|
222
236
|
version: '0'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
238
|
+
name: minitest-reporters
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
226
240
|
requirements:
|
227
241
|
- - ">="
|
@@ -235,7 +249,7 @@ dependencies:
|
|
235
249
|
- !ruby/object:Gem::Version
|
236
250
|
version: '0'
|
237
251
|
- !ruby/object:Gem::Dependency
|
238
|
-
name:
|
252
|
+
name: rake
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
240
254
|
requirements:
|
241
255
|
- - ">="
|
@@ -249,7 +263,7 @@ dependencies:
|
|
249
263
|
- !ruby/object:Gem::Version
|
250
264
|
version: '0'
|
251
265
|
- !ruby/object:Gem::Dependency
|
252
|
-
name:
|
266
|
+
name: rubocop-minitest
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|
254
268
|
requirements:
|
255
269
|
- - ">="
|
@@ -263,7 +277,7 @@ dependencies:
|
|
263
277
|
- !ruby/object:Gem::Version
|
264
278
|
version: '0'
|
265
279
|
- !ruby/object:Gem::Dependency
|
266
|
-
name:
|
280
|
+
name: rubocop-rake
|
267
281
|
requirement: !ruby/object:Gem::Requirement
|
268
282
|
requirements:
|
269
283
|
- - ">="
|
@@ -276,9 +290,9 @@ dependencies:
|
|
276
290
|
- - ">="
|
277
291
|
- !ruby/object:Gem::Version
|
278
292
|
version: '0'
|
279
|
-
description: See https://microsoft.github.io/language-server-protocol/
|
280
|
-
Server is meant to provide the language-specific smarts and communicate
|
281
|
-
tools over a protocol that enables inter-process communication."
|
293
|
+
description: Provide a language server implementation for ruby in ruby. See https://microsoft.github.io/language-server-protocol/
|
294
|
+
"A Language Server is meant to provide the language-specific smarts and communicate
|
295
|
+
with development tools over a protocol that enables inter-process communication."
|
282
296
|
email:
|
283
297
|
- kurt@CircleW.org
|
284
298
|
executables:
|
@@ -332,6 +346,7 @@ metadata:
|
|
332
346
|
homepage_uri: https://github.com/kwerle/ruby_language_server
|
333
347
|
source_code_uri: https://github.com/kwerle/ruby_language_server
|
334
348
|
changelog_uri: https://github.com/kwerle/ruby_language_server/blob/develop/CHANGELOG.txt
|
349
|
+
rubygems_mfa_required: 'true'
|
335
350
|
post_install_message:
|
336
351
|
rdoc_options: []
|
337
352
|
require_paths:
|
@@ -340,14 +355,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
340
355
|
requirements:
|
341
356
|
- - ">="
|
342
357
|
- !ruby/object:Gem::Version
|
343
|
-
version:
|
358
|
+
version: 3.1.0
|
344
359
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
345
360
|
requirements:
|
346
361
|
- - ">="
|
347
362
|
- !ruby/object:Gem::Version
|
348
363
|
version: '0'
|
349
364
|
requirements: []
|
350
|
-
rubygems_version: 3.
|
365
|
+
rubygems_version: 3.5.11
|
351
366
|
signing_key:
|
352
367
|
specification_version: 4
|
353
368
|
summary: Provide a language server implementation for ruby in ruby.
|