ruby_language_server 0.3.10 → 0.3.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd91d47c15d866df0d207db2e5f9d289200e006620bf0457a62309630e3da707
4
- data.tar.gz: 4dfac7f73cc17285a0543596d17bdd5326603d3716a625add6644ee55966c59d
3
+ metadata.gz: 77c419c9b73abc288b78499f96ebb5ab58eacbb2ab6fb52509cbe9f28bcfef88
4
+ data.tar.gz: bb93242e228b943605f669da4dc248533f640513511d7433ed23c12196e70558
5
5
  SHA512:
6
- metadata.gz: 7d7782c575a27ab425bd3c3e73330a3196407e2a1caedcc4b9ac90f238f245bd0a6f2d98b1966e34ce203646bffec484831cf7b02828d063797cc5091d984be7
7
- data.tar.gz: 5506cfa8697302b0be73362f709f51f0ac70b264749bcae831a278f355d44f8eff360b2b5aca8d895bc1508145253d585860fa946512be7d148167768173dd35
6
+ metadata.gz: 82b59f72c3d1476f137e89ca4078f3f8df2cbf15c83c3405e1a7d4558d4c18e92421666787b293af0be45c9e27cad72026ed2b9796ceb71ec4377ce0c57be115
7
+ data.tar.gz: c8c6afef362d2b5610a4321448b252a18acc3a2f77637fb26f6f74e09538c464052282ab4dc7dc7b739223a3bd7713fef16c30d4703a0a4f91fdb5f2a30a61b3
data/CHANGELOG.txt CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ #### 0.3.15 Tue May 4 15:34:22 PDT 2021
4
+
5
+ * Add support for rspec context blocks #53
6
+
7
+ #### 0.3.14 Sat Apr 24 21:09:07 PDT 2021
8
+
9
+ * Update rails activerecord to 6.1
10
+ * Update ruby to 3
11
+ * Fix some tests, docs, etc
12
+
13
+ #### 0.3.13 Fri Feb 14 00:55:28 PST 2020
14
+
15
+ * More stabbing at goodcop gemfile issues
16
+ * Hopefully much higher performance and better completions
17
+
18
+ #### 0.3.12 Thu Feb 6 06:18:33 UTC 2020
19
+
20
+ * #58 Change the way additional gems are installed so there are not conflicts
21
+
22
+ #### 0.3.11 Wed Jan 29 06:48:37 UTC 2020
23
+
24
+ * #57 rubocop gemfiles mismatch
25
+ * #56 .rubocop.yml changes do not rerun rubocop validations
26
+
3
27
  #### 0.3.10 Fri Jan 24 00:19:14 PST 2020
4
28
 
5
29
  * botched the 0.3.9 release
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_language_server (0.3.10)
5
- activerecord (~> 5.2)
4
+ ruby_language_server (0.3.15)
5
+ activerecord (~> 6.1)
6
6
  amatch
7
7
  bundler
8
8
  etc
@@ -16,30 +16,31 @@ PATH
16
16
  GEM
17
17
  remote: https://rubygems.org/
18
18
  specs:
19
- activemodel (5.2.4.1)
20
- activesupport (= 5.2.4.1)
21
- activerecord (5.2.4.1)
22
- activemodel (= 5.2.4.1)
23
- activesupport (= 5.2.4.1)
24
- arel (>= 9.0)
25
- activesupport (5.2.4.1)
19
+ activemodel (6.1.3.1)
20
+ activesupport (= 6.1.3.1)
21
+ activerecord (6.1.3.1)
22
+ activemodel (= 6.1.3.1)
23
+ activesupport (= 6.1.3.1)
24
+ activesupport (6.1.3.1)
26
25
  concurrent-ruby (~> 1.0, >= 1.0.2)
27
- i18n (>= 0.7, < 2)
28
- minitest (~> 5.1)
29
- tzinfo (~> 1.1)
26
+ i18n (>= 1.6, < 2)
27
+ minitest (>= 5.1)
28
+ tzinfo (~> 2.0)
29
+ zeitwerk (~> 2.3)
30
30
  amatch (0.4.0)
31
31
  mize
32
32
  tins (~> 1.0)
33
- arel (9.0.0)
34
- ast (2.4.0)
35
- byebug (11.0.1)
36
- coderay (1.1.2)
37
- concurrent-ruby (1.1.5)
38
- etc (1.1.0)
39
- ffi (1.11.1)
33
+ ansi (1.5.0)
34
+ ast (2.4.2)
35
+ builder (3.2.4)
36
+ byebug (11.1.3)
37
+ coderay (1.1.3)
38
+ concurrent-ruby (1.1.8)
39
+ etc (1.2.0)
40
+ ffi (1.15.0)
40
41
  formatador (0.2.5)
41
42
  fuzzy_match (2.1.0)
42
- guard (2.15.0)
43
+ guard (2.16.2)
43
44
  formatador (>= 0.2.4)
44
45
  listen (>= 2.7, < 4.0)
45
46
  lumberjack (>= 1.0.12, < 2.0)
@@ -52,80 +53,88 @@ GEM
52
53
  guard-minitest (2.4.6)
53
54
  guard-compat (~> 1.2)
54
55
  minitest (>= 3.0)
55
- guard-rubocop (1.3.0)
56
+ guard-rubocop (1.4.0)
56
57
  guard (~> 2.0)
57
- rubocop (~> 0.20)
58
- i18n (1.8.1)
58
+ rubocop (< 2.0)
59
+ i18n (1.8.10)
59
60
  concurrent-ruby (~> 1.0)
60
- jaro_winkler (1.5.3)
61
- json (2.3.0)
62
- listen (3.1.5)
63
- rb-fsevent (~> 0.9, >= 0.9.4)
64
- rb-inotify (~> 0.9, >= 0.9.7)
65
- ruby_dep (~> 1.2)
66
- lumberjack (1.0.13)
67
- method_source (0.9.2)
68
- minitest (5.11.3)
69
- minitest-color (0.0.2)
70
- minitest (~> 5)
61
+ json (2.5.1)
62
+ listen (3.5.1)
63
+ rb-fsevent (~> 0.10, >= 0.10.3)
64
+ rb-inotify (~> 0.9, >= 0.9.10)
65
+ lumberjack (1.2.8)
66
+ method_source (1.0.0)
67
+ minitest (5.14.4)
68
+ minitest-reporters (1.4.3)
69
+ ansi
70
+ builder
71
+ minitest (>= 5.0)
72
+ ruby-progressbar
71
73
  mize (0.4.0)
72
74
  protocol (~> 2.0)
73
75
  nenv (0.3.0)
74
76
  notiffany (0.1.3)
75
77
  nenv (~> 0.1)
76
78
  shellany (~> 0.0)
77
- parallel (1.17.0)
78
- parser (2.6.3.0)
79
- ast (~> 2.4.0)
79
+ parallel (1.20.1)
80
+ parser (3.0.1.0)
81
+ ast (~> 2.4.1)
80
82
  protocol (2.0.0)
81
83
  ruby_parser (~> 3.0)
82
- pry (0.12.2)
83
- coderay (~> 1.1.0)
84
- method_source (~> 0.9.0)
85
- pry-byebug (3.7.0)
84
+ pry (0.13.1)
85
+ coderay (~> 1.1)
86
+ method_source (~> 1.0)
87
+ pry-byebug (3.9.0)
86
88
  byebug (~> 11.0)
87
- pry (~> 0.10)
89
+ pry (~> 0.13.0)
88
90
  rainbow (3.0.0)
89
- rake (13.0.1)
90
- rb-fsevent (0.10.3)
91
- rb-inotify (0.10.0)
91
+ rake (13.0.3)
92
+ rb-fsevent (0.10.4)
93
+ rb-inotify (0.10.1)
92
94
  ffi (~> 1.0)
93
- rubocop (0.74.0)
94
- jaro_winkler (~> 1.5.1)
95
+ regexp_parser (2.1.1)
96
+ rexml (3.2.5)
97
+ rubocop (1.13.0)
95
98
  parallel (~> 1.10)
96
- parser (>= 2.6)
99
+ parser (>= 3.0.0.0)
97
100
  rainbow (>= 2.2.2, < 4.0)
101
+ regexp_parser (>= 1.8, < 3.0)
102
+ rexml
103
+ rubocop-ast (>= 1.2.0, < 2.0)
98
104
  ruby-progressbar (~> 1.7)
99
- unicode-display_width (>= 1.4.0, < 1.7)
100
- rubocop-performance (1.5.2)
101
- rubocop (>= 0.71.0)
102
- rubocop-rspec (1.37.1)
103
- rubocop (>= 0.68.1)
104
- ruby-progressbar (1.10.1)
105
- ruby_dep (1.5.0)
106
- ruby_parser (3.14.1)
105
+ unicode-display_width (>= 1.4.0, < 3.0)
106
+ rubocop-ast (1.4.1)
107
+ parser (>= 2.7.1.5)
108
+ rubocop-performance (1.11.0)
109
+ rubocop (>= 1.7.0, < 2.0)
110
+ rubocop-ast (>= 0.4.0)
111
+ rubocop-rspec (2.2.0)
112
+ rubocop (~> 1.0)
113
+ rubocop-ast (>= 1.1.0)
114
+ ruby-progressbar (1.11.0)
115
+ ruby_parser (3.15.1)
107
116
  sexp_processor (~> 4.9)
108
- sexp_processor (4.12.1)
117
+ sexp_processor (4.15.2)
109
118
  shellany (0.0.1)
110
119
  sqlite3 (1.4.2)
111
120
  sync (0.5.0)
112
- thor (0.20.3)
113
- thread_safe (0.3.6)
114
- tins (1.24.0)
121
+ thor (1.1.0)
122
+ tins (1.28.0)
115
123
  sync
116
- tzinfo (1.2.6)
117
- thread_safe (~> 0.1)
118
- unicode-display_width (1.6.0)
124
+ tzinfo (2.0.4)
125
+ concurrent-ruby (~> 1.0)
126
+ unicode-display_width (2.0.0)
127
+ zeitwerk (2.4.2)
119
128
 
120
129
  PLATFORMS
121
- ruby
130
+ x86_64-linux-musl
122
131
 
123
132
  DEPENDENCIES
124
133
  guard
125
134
  guard-minitest
126
135
  guard-rubocop
127
- minitest (~> 5.11)
128
- minitest-color
136
+ minitest
137
+ minitest-reporters
129
138
  pry
130
139
  pry-byebug
131
140
  rake
@@ -133,4 +142,4 @@ DEPENDENCIES
133
142
  sexp_processor
134
143
 
135
144
  BUNDLED WITH
136
- 2.1.3
145
+ 2.2.16
data/Guardfile CHANGED
@@ -18,7 +18,7 @@
18
18
  # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
19
19
 
20
20
  group :red_green_refactor, halt_on_fail: true do
21
- guard :minitest, all_after_pass: true do
21
+ guard :minitest, all_after_pass: true, cli: '--guard' do
22
22
  # with Minitest::Unit
23
23
  # watch(%r{^test/(.*)\/?test_(.*)\.rb$})
24
24
  # watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
data/Makefile CHANGED
@@ -1,15 +1,15 @@
1
1
  PROJECT_NAME=ruby_language_server
2
2
  LOCAL_LINK=-v $(PWD):/tmp/src -w /tmp/src
3
3
 
4
- build:
4
+ image:
5
5
  docker build -t $(PROJECT_NAME) .
6
6
 
7
- guard: build
7
+ guard: image
8
8
  echo > active_record.log
9
9
  docker run -it --rm $(LOCAL_LINK) -e LOG_LEVEL=DEBUG $(PROJECT_NAME) bundle exec guard
10
10
  echo > active_record.log
11
11
 
12
- continuous_development: build
12
+ continuous_development: image
13
13
  docker build -t local_ruby_language_server .
14
14
  echo "You are going to want to set the ide-ruby 'Image Name' to local_ruby_language_server"
15
15
  sleep 15
@@ -19,20 +19,20 @@ continuous_development: build
19
19
  sleep 2 ; \
20
20
  done
21
21
 
22
- console: build
22
+ console: image
23
23
  docker run -it --rm $(LOCAL_LINK) $(PROJECT_NAME) bin/console
24
24
 
25
- test: build
25
+ test: image
26
26
  docker run -it --rm $(LOCAL_LINK) $(PROJECT_NAME) sh -c 'bundle exec rake test && bundle exec rubocop'
27
27
 
28
- shell: build
28
+ shell: image
29
29
  docker run -it --rm $(LOCAL_LINK) $(PROJECT_NAME) sh
30
30
 
31
31
  # Just to make sure it works.
32
- server: build
32
+ server: image
33
33
  docker run -it --rm $(LOCAL_LINK) $(PROJECT_NAME)
34
34
 
35
- gem: build
35
+ gem: image
36
36
  rm -f $(PROJECT_NAME)*.gem
37
37
  docker run $(LOCAL_LINK) $(PROJECT_NAME) gem build $(PROJECT_NAME)
38
38
 
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ ![Build Status](https://github.com/kwerle/ruby_language_server/actions/workflows/test.yml/badge.svg)
1
2
  # Overview
2
3
 
3
4
  https://github.com/kwerle/ruby_language_server
@@ -6,9 +7,9 @@ The goal of this project is to provide a [language server](https://microsoft.git
6
7
 
7
8
  # Status
8
9
 
9
- Beta. It does some stuff. Pretty stable. Used day-to-day.
10
+ Used day-to-day.
10
11
 
11
- Help wanted.
12
+ Help welcome.
12
13
 
13
14
  # Features
14
15
 
@@ -20,6 +21,7 @@ Help wanted.
20
21
  # Editor Integrations
21
22
 
22
23
  You probably want to use one of the developed integrations:
24
+ * VSCode - https://github.com/kwerle/vscode_ruby_language_server
23
25
  * Atom - https://github.com/kwerle/ide-ruby
24
26
  * Theia - https://github.com/kwerle/theia_ruby_language_server
25
27
 
@@ -8,12 +8,17 @@ ActiveRecord::Base.establish_connection(
8
8
  checkout_timeout: 30.seconds # does not seem to help
9
9
  )
10
10
 
11
+ database = ActiveRecord::Base.connection.instance_variable_get :@connection
12
+ database.enable_load_extension(1)
13
+ database.load_extension('/usr/local/lib/liblevenshtein.so.0.0.0')
14
+ database.enable_load_extension(0)
15
+
11
16
  if ENV['LOG_LEVEL'] == 'DEBUG'
12
17
  begin
13
- warn('Turning on active record logging')
18
+ warn('Turning on active record logging to active_record.log')
14
19
  ActiveRecord::Base.logger = Logger.new(File.open('active_record.log', 'w'))
15
20
  rescue Exception => e
16
- ActiveRecord::Base.logger = Logger.new(STDERR)
21
+ ActiveRecord::Base.logger = Logger.new($stderr)
17
22
  ActiveRecord::Base.logger.error(e)
18
23
  end
19
24
  end
@@ -1 +1,2 @@
1
- # This is a blank rubocop file just to have a handle to make rubocop happy
1
+ # This is a blank rubocop file just to have a handle to make rubocop happy.
2
+ # It is used if the project does not have a rubocop file.
@@ -20,28 +20,16 @@ module RubyLanguageServer
20
20
  def self.build(uri, text)
21
21
  RubyLanguageServer.logger.debug("CodeFile initialize #{uri}")
22
22
 
23
- new_code_file = create!(uri: uri, text: text)
24
- new_code_file
23
+ create!(uri: uri, text: text)
25
24
  end
26
25
 
27
- # def text=(new_text)
28
- # RubyLanguageServer.logger.debug("text= for #{uri}")
29
- # if @text == new_text
30
- # RubyLanguageServer.logger.debug('IT WAS THE SAME!!!!!!!!!!!!')
31
- # return
32
- # end
33
- # @text = new_text
34
- # update_attribute(:refresh_root_scope, true)
35
- # root_scope
36
- # end
37
- #
38
26
  SYMBOL_KIND = {
39
27
  file: 1,
40
- 'module': 5, # 2,
28
+ module: 5, # 2,
41
29
  namespace: 3,
42
30
  package: 4,
43
- 'class': 5,
44
- 'method': 6,
31
+ class: 5,
32
+ method: 6,
45
33
  'singleton method': 6,
46
34
  property: 7,
47
35
  field: 8,
@@ -32,7 +32,7 @@ module RubyLanguageServer
32
32
  else
33
33
  scope_completions_in_target_context(context, context_scope, position_scopes)
34
34
  end
35
- RubyLanguageServer.logger.debug("completions: #{completions.as_json}")
35
+ # RubyLanguageServer.logger.debug("completions: #{completions.as_json}")
36
36
  {
37
37
  isIncomplete: true,
38
38
  items: completions.uniq.map do |word, hash|
@@ -54,7 +54,7 @@ module RubyLanguageServer
54
54
 
55
55
  def scope_completions_in_target_context(context, context_scope, scopes)
56
56
  context_word = context[-2]
57
- context_word = context_word.split(/_/).map(&:capitalize).join('') unless context_word.match?(/^[A-Z]/)
57
+ context_word = context_word.split('_').map(&:capitalize).join unless context_word.match?(/^[A-Z]/)
58
58
  context_scopes = RubyLanguageServer::ScopeData::Scope.where(name: context_word)
59
59
  context_scopes ||= context_scope
60
60
  RubyLanguageServer.logger.debug("context_scopes: #{context_scopes.to_json}")
@@ -64,19 +64,34 @@ module RubyLanguageServer
64
64
 
65
65
  def module_completions(word)
66
66
  class_and_module_types = [RubyLanguageServer::ScopeData::Base::TYPE_CLASS, RubyLanguageServer::ScopeData::Base::TYPE_MODULE]
67
- scope_words = RubyLanguageServer::ScopeData::Scope.where(class_type: class_and_module_types).sort_by(&:depth).map { |scope| [scope.name, scope] }
68
- words = scope_words.to_h
69
- good_words = FuzzyMatch.new(words.keys, threshold: 0.01).find_all(word).slice(0..10) || []
70
- words = good_words.each_with_object({}) { |w, hash| hash[w] = {depth: words[w].depth, type: words[w].class_type} }.to_h
67
+
68
+ # scope_words = RubyLanguageServer::ScopeData::Scope.where(class_type: class_and_module_types).sort_by(&:depth).map { |scope| [scope.name, scope] }
69
+ # words = scope_words.to_h
70
+ # good_words = FuzzyMatch.new(words.keys, threshold: 0.01).find_all(word).slice(0..10) || []
71
+ # words = good_words.each_with_object({}) { |w, hash| hash[w] = {depth: words[w].depth, type: words[w].class_type} }.to_h
72
+
73
+ words = RubyLanguageServer::ScopeData::Scope.where(class_type: class_and_module_types).closest_to(word).limit(20)
74
+ RubyLanguageServer.logger.error("module_completions: #{words.as_json}")
75
+ # words.to_a.sort_by(&:depth).each_with_object({}){|a_word, hash| hash[a_word.name] = {depth: a_word.depth, type: a_word.class_type} }
76
+ good_words = FuzzyMatch.new(words.to_a, read: :name, threshold: 0.01).find_all(word).slice(0..10) || []
77
+ good_words.each_with_object({}) { |w, hash| hash[w.name] = {depth: w.depth, type: w.class_type} }.to_h
71
78
  end
72
79
 
73
80
  def scope_completions(word, scopes)
74
81
  return module_completions(word) if word.match?(/\A[A-Z][a-z]/)
75
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
+
76
91
  scope_ids = scopes.map(&:id)
77
- word_scopes = scopes.to_a + RubyLanguageServer::ScopeData::Scope.where(parent_id: scope_ids)
92
+ word_scopes = scopes.to_a + RubyLanguageServer::ScopeData::Scope.where(parent_id: scope_ids).closest_to(word).limit(5)
78
93
  scope_words = word_scopes.select(&:named_scope?).sort_by(&:depth).map { |scope| [scope.name, scope] }
79
- variable_words = RubyLanguageServer::ScopeData::Variable.where(scope_id: scope_ids).map { |variable| [variable.name, variable.scope] }
94
+ variable_words = RubyLanguageServer::ScopeData::Variable.where(scope_id: scope_ids).closest_to(word).limit(5).map { |variable| [variable.name, variable.scope] }
80
95
  words = (scope_words + variable_words).to_h
81
96
  good_words = FuzzyMatch.new(words.keys, threshold: 0.01).find_all(word).slice(0..10) || []
82
97
  words = good_words.each_with_object({}) { |w, hash| hash[w] = {depth: words[w].depth, type: words[w].class_type} }.to_h
@@ -6,18 +6,24 @@ module RubyLanguageServer
6
6
  # Sole purpose is to install gems
7
7
  module GemInstaller
8
8
  class << self
9
- def install_gems(gem_names)
10
- gem_names&.compact!
11
- gem_names&.reject! { |name| name.strip == '' }
12
- return if gem_names.nil? || gem_names.empty?
9
+ def install_gems(additional_gem_names)
10
+ additional_gem_names&.compact!
11
+ additional_gem_names&.reject! { |name| name.strip == '' }
12
+ return if additional_gem_names.nil? || additional_gem_names.empty?
13
13
 
14
- RubyLanguageServer.logger.info("Trying to install gems #{gem_names}")
15
- rubocop_gem = Gem::Specification.find_by_name 'rubocop'
14
+ RubyLanguageServer.logger.info("Trying to install gems #{additional_gem_names}")
15
+ gems_already_installed = []
16
16
  gemfile do
17
17
  source 'https://rubygems.org'
18
- gem 'rubocop', rubocop_gem.version.to_s
19
- gem_names.each do |gem_name|
20
- gem gem_name
18
+ # Lock all the gems we already have installed to the versions we have installed
19
+ # For some reason, installing bundler makes it unhappy. Whatever.
20
+ Gem::Specification.reject { |s| s.name == 'bundler' }.each do |specification|
21
+ gem_name = specification.name
22
+ gem(gem_name, specification.version.to_s)
23
+ gems_already_installed << gem_name
24
+ end
25
+ additional_gem_names.each do |gem_name|
26
+ gem gem_name unless gems_already_installed.include?(gem_name)
21
27
  end
22
28
  end
23
29
  end
@@ -4,12 +4,14 @@ require 'rubocop'
4
4
 
5
5
  module RubyLanguageServer
6
6
  class GoodCop < RuboCop::Runner
7
- def initialize
8
- @initialization_error = nil
9
- config_store = RuboCop::ConfigStore.new
10
- config_store.options_config = config_path
11
- RubyLanguageServer.logger.debug("Rubocop config_path: #{config_path}")
12
- super({}, config_store)
7
+ def initialize(config_path, initialization_error = nil)
8
+ @initialization_error = initialization_error
9
+ unless @initialization_error
10
+ initialize_rubocop_ivars
11
+ @config_store.options_config = config_path
12
+ RubyLanguageServer.logger.debug("Rubocop config_path: #{config_path}")
13
+ super({}, @config_store)
14
+ end
13
15
  rescue Exception => e
14
16
  RubyLanguageServer.logger.error(e)
15
17
  @initialization_error = "There was an issue loading the rubocop configuration file: #{e}. Maybe you need to add some additional gems to the ide-ruby settings?"
@@ -100,12 +102,25 @@ module RubyLanguageServer
100
102
  if excluded_file?(filename)
101
103
  []
102
104
  else
103
- processed_source = RuboCop::ProcessedSource.new(text, 2.7, filename)
105
+ ruby_version = 2.7
106
+ processed_source = RuboCop::ProcessedSource.new(text, ruby_version, filename)
104
107
  offenses = inspect_file(processed_source)
105
- offenses.compact.flatten
108
+ offenses.compact.flatten.reject(&:blank?) # reject blank because some are `false`
106
109
  end
107
110
  end
108
111
 
112
+ def initialize_rubocop_ivars
113
+ @config_store ||= RuboCop::ConfigStore.new
114
+ @options ||= {}
115
+ @errors ||= []
116
+ @warnings ||= []
117
+ end
118
+
119
+ def inspect_file(source)
120
+ initialize_rubocop_ivars
121
+ super
122
+ end
123
+
109
124
  def initialization_offenses
110
125
  [
111
126
  {
@@ -119,17 +134,35 @@ module RubyLanguageServer
119
134
  ]
120
135
  end
121
136
 
122
- def config_path
123
- my_path = __FILE__
124
- pathname = Pathname.new(my_path)
125
- my_directory = pathname.dirname
126
- fallback_pathname = my_directory + '../resources/fallback_rubocop.yml'
127
- project_path = RubyLanguageServer::ProjectManager.root_path + '.rubocop.yml'
128
- possible_config_paths = [project_path, fallback_pathname.to_s]
129
- possible_config_paths.detect { |path| File.exist?(path) }
137
+ class << self
138
+ def instance
139
+ @config_path ||= config_path
140
+ config_path_timestamp = File.mtime(@config_path)
141
+ if @cached_config_path_timestamp.nil? || @cached_config_path_timestamp < config_path_timestamp
142
+ @cached_config_path_timestamp = config_path_timestamp
143
+ @instance = new(@config_path)
144
+ else
145
+ @instance
146
+ end
147
+ rescue StandardError => e
148
+ @instance = new(@config_path, e.to_s)
149
+ end
150
+
151
+ private
152
+
153
+ def config_path
154
+ my_path = __FILE__
155
+ pathname = Pathname.new(my_path)
156
+ my_directory = pathname.dirname
157
+ fallback_pathname = "#{my_directory}/../resources/fallback_rubocop.yml"
158
+ project_path = "#{RubyLanguageServer::ProjectManager.root_path}.rubocop.yml"
159
+ possible_config_paths = [project_path, fallback_pathname.to_s]
160
+ possible_config_paths.detect { |path| File.exist?(path) }
161
+ end
130
162
  end
131
163
 
132
164
  def excluded_file?(filename)
165
+ initialize_rubocop_ivars
133
166
  file_config = @config_store.for(filename)
134
167
  file_config.file_to_exclude?(filename)
135
168
  end
@@ -9,8 +9,8 @@ module RubyLanguageServer
9
9
  @mutex = mutex
10
10
  server.io = self
11
11
  loop do
12
- (id, response) = process_request(STDIN)
13
- return_response(id, response, STDOUT) unless id.nil?
12
+ (id, response) = process_request($stdin)
13
+ return_response(id, response, $stdout) unless id.nil?
14
14
  rescue SignalException => e
15
15
  RubyLanguageServer.logger.error "We received a signal. Let's bail: #{e}"
16
16
  exit(true)
@@ -21,7 +21,7 @@ module RubyLanguageServer
21
21
  end
22
22
  end
23
23
 
24
- def return_response(id, response, io = STDOUT)
24
+ def return_response(id, response, io = $stdout)
25
25
  full_response = {
26
26
  jsonrpc: '2.0',
27
27
  id: id,
@@ -35,7 +35,7 @@ module RubyLanguageServer
35
35
  io.flush
36
36
  end
37
37
 
38
- def send_notification(message, params, io = STDOUT)
38
+ def send_notification(message, params, io = $stdout)
39
39
  full_response = {
40
40
  jsonrpc: '2.0',
41
41
  method: message,
@@ -49,7 +49,7 @@ module RubyLanguageServer
49
49
  io.flush
50
50
  end
51
51
 
52
- def process_request(io = STDIN)
52
+ def process_request(io = $stdin)
53
53
  request_body = get_request(io)
54
54
  # RubyLanguageServer.logger.debug "request_body: #{request_body}"
55
55
  request_json = JSON.parse request_body
@@ -71,7 +71,7 @@ module RubyLanguageServer
71
71
  end
72
72
  end
73
73
 
74
- def get_request(io = STDIN)
74
+ def get_request(io = $stdin)
75
75
  initial_line = get_initial_request_line(io)
76
76
  RubyLanguageServer.logger.debug "initial_line: #{initial_line}"
77
77
  length = get_length(initial_line)
@@ -89,7 +89,7 @@ module RubyLanguageServer
89
89
  content
90
90
  end
91
91
 
92
- def get_initial_request_line(io = STDIN)
92
+ def get_initial_request_line(io = $stdin)
93
93
  io.gets
94
94
  end
95
95
 
@@ -99,7 +99,7 @@ module RubyLanguageServer
99
99
  string.match(/Content-Length: (\d+)/)[1].to_i
100
100
  end
101
101
 
102
- def get_content(size, io = STDIN)
102
+ def get_content(size, io = $stdin)
103
103
  io.read(size)
104
104
  end
105
105
 
@@ -20,7 +20,7 @@ module RubyLanguageServer
20
20
  # This will not work if the search starts on the ending ? of "method?". Bummer.
21
21
  def self.for(line, position)
22
22
  # Grab just the last part of the line - from the index onward
23
- line_end = line[position..-1]
23
+ line_end = line[position..]
24
24
  return nil if line_end.nil?
25
25
 
26
26
  # Grab the portion of the word that starts at the position toward the end of the line
@@ -30,7 +30,7 @@ module RubyLanguageServer
30
30
  line_start = line[0..(position + match.length - 1)]
31
31
  RubyLanguageServer.logger.debug("line_start: #{line_start}")
32
32
  # Match as much as we can to the end of the line - which is now the end of the word
33
- end_match = line_start.partition(/(@{0,2}[:&\.\w]+\??)$/)[1]
33
+ end_match = line_start.partition(/(@{0,2}[:&.\w]+\??)$/)[1]
34
34
  matches = end_match.split('&.', -1)
35
35
  matches = matches.map { |m| m.length.positive? ? m.split('.', -1) : m }.flatten
36
36
  matches = matches.map { |m| m.length.positive? ? m.split('::', -1) : m }.flatten
@@ -20,7 +20,7 @@ module RubyLanguageServer
20
20
  line: start_line - 1,
21
21
  character: start_character
22
22
  },
23
- 'end': {
23
+ end: {
24
24
  line: end_line - 1,
25
25
  character: end_character
26
26
  }
@@ -3,12 +3,12 @@
3
3
  require 'logger'
4
4
 
5
5
  module RubyLanguageServer
6
- level_name = ENV.fetch('LOG_LEVEL') { 'error' }.upcase
6
+ level_name = ENV.fetch('LOG_LEVEL', 'error').upcase
7
7
  # level_name = 'DEBUG'
8
8
  level = Logger::Severity.const_get(level_name)
9
- @logger = ::Logger.new(STDERR, level: level)
10
- @logger.log(level, "Logger started at level #{level_name} -> #{level}")
11
- def self.logger
12
- @logger
9
+ class << self
10
+ attr_accessor :logger
13
11
  end
12
+ @logger = ::Logger.new($stderr, level: level)
13
+ @logger.log(level, "Logger started at level #{level_name} -> #{level}")
14
14
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'fuzzy_match'
4
- require 'amatch' # note that you have to require this... fuzzy_match won't require it for you
4
+ require 'amatch' # NOTE: that you have to require this... fuzzy_match won't require it for you
5
5
  FuzzyMatch.engine = :amatch # This should be in a config somewhere
6
6
 
7
7
  module RubyLanguageServer
@@ -62,7 +62,7 @@ module RubyLanguageServer
62
62
  RubyLanguageServer::GemInstaller.install_gems(gem_names)
63
63
  @additional_gem_mutex.synchronize { @additional_gems_installed = true }
64
64
  rescue StandardError => e
65
- RubyLanguageServer.logger.error("Issue installing rubocop gems: #{e}")
65
+ RubyLanguageServer.logger.error("Issue installing rubocop gems: #{e} #{e.backtrace}")
66
66
  end
67
67
  end
68
68
 
@@ -217,9 +217,8 @@ module RubyLanguageServer
217
217
  def updated_diagnostics_for_codefile(code_file)
218
218
  # Maybe we should be sharing this GoodCop across instances
219
219
  RubyLanguageServer.logger.debug("updated_diagnostics_for_codefile: #{code_file.uri}")
220
- @good_cop ||= GoodCop.new
221
220
  project_relative_filename = filename_relative_to_project(code_file.uri)
222
- code_file.diagnostics = @good_cop.diagnostics(code_file.text, project_relative_filename)
221
+ code_file.diagnostics = GoodCop.instance.diagnostics(code_file.text, project_relative_filename)
223
222
  RubyLanguageServer.logger.debug("code_file.diagnostics: #{code_file.diagnostics}")
224
223
  code_file.diagnostics
225
224
  end
@@ -272,8 +271,7 @@ module RubyLanguageServer
272
271
  private
273
272
 
274
273
  def code_file_for_uri(uri)
275
- code_file = CodeFile.find_by_uri(uri) || CodeFile.build(uri, nil)
276
- code_file
274
+ CodeFile.find_by_uri(uri) || CodeFile.build(uri, nil)
277
275
  end
278
276
 
279
277
  def filename_relative_to_project(filename)
@@ -27,6 +27,15 @@ module RubyLanguageServer
27
27
 
28
28
  attr_accessor :type # Type of this scope (module, class, block)
29
29
 
30
+ # bar should be closer to Bar than Far. Adding the UPPER version accomplishes this.
31
+ scope :with_distance_from, lambda { |word|
32
+ sanitized_word = sanitize_sql(word)
33
+ where("LENGTH(name) >= LENGTH('#{sanitized_word}')").select("*, LEVENSHTEIN(SUBSTR(name, 1, #{word.length}), '#{sanitized_word}') + LEVENSHTEIN(SUBSTR(UPPER(name), 1, #{word.length}), UPPER('#{sanitized_word}')) as levenshtein_distance")
34
+ }
35
+ scope :closest_to, ->(word) { with_distance_from(word).order(:levenshtein_distance) }
36
+
37
+ # RubyLanguageServer::ScopeData::Scope.connection.exec_query("SELECT LEVENSHTEIN( 'This is not correct', 'This is correct' )")
38
+
30
39
  def method?
31
40
  type == TYPE_METHOD
32
41
  end
@@ -8,7 +8,7 @@ module RubyLanguageServer
8
8
  # It is used to track top & bottom line, variables in this scope, constants, and children - which could be functions, classes, blocks, etc. Anything that adds scope.
9
9
  class Scope < Base
10
10
  has_many :variables, dependent: :destroy
11
- belongs_to :code_file
11
+ belongs_to :code_file # , optional: false
12
12
  belongs_to :parent, class_name: 'Scope', optional: true
13
13
  has_many :children, class_name: 'Scope', foreign_key: :parent_id
14
14
 
@@ -12,11 +12,6 @@ module RubyLanguageServer
12
12
 
13
13
  delegate :depth, to: :scope
14
14
 
15
- # attr_accessor :line # line
16
- # attr_accessor :column # column
17
- # attr_accessor :name # name
18
- # attr_accessor :path # Module::Class name
19
-
20
15
  def self.build(scope, name, line = 1, column = 1, type = TYPE_VARIABLE)
21
16
  path = [scope.full_name, name].join(JoinHash[TYPE_VARIABLE])
22
17
  create!(
@@ -26,12 +21,6 @@ module RubyLanguageServer
26
21
  path: path,
27
22
  variable_type: type
28
23
  )
29
- # @name = name
30
- # @line = line
31
- # @column = column
32
- # @full_name =
33
- # @type = type
34
- # raise "bogus variable #{inspect}" unless @name.instance_of? String
35
24
  end
36
25
 
37
26
  def constant?
@@ -15,9 +15,7 @@ module RubyLanguageServer
15
15
  include ScopeParserCommands::RspecCommands
16
16
  include ScopeParserCommands::RailsCommands
17
17
  include ScopeParserCommands::RubyCommands
18
- attr_reader :sexp
19
- attr_reader :lines
20
- attr_reader :current_scope
18
+ attr_reader :sexp, :lines, :current_scope
21
19
 
22
20
  def initialize(sexp, lines = 1)
23
21
  @sexp = sexp
@@ -54,9 +52,7 @@ module RubyLanguageServer
54
52
  when String
55
53
  # We really don't do anything with it!
56
54
  RubyLanguageServer.logger.debug("We don't do Strings like #{root} with #{args}")
57
- when NilClass
58
- process(args)
59
- when FalseClass
55
+ when NilClass, FalseClass
60
56
  process(args)
61
57
  else
62
58
  RubyLanguageServer.logger.warn("We don't respond to the likes of #{root} of class #{root.class}")
@@ -154,7 +150,7 @@ module RubyLanguageServer
154
150
  # def self.something(par)...
155
151
  # [:var_ref, [:@kw, "self", [28, 14]]], [[:@period, ".", [28, 18]], [:@ident, "something", [28, 19]], [:paren, [:params, [[:@ident, "par", [28, 23]]], nil, nil, nil, nil, nil, nil]], [:bodystmt, [[:assign, [:var_field, [:@ident, "pax", [29, 12]]], [:var_ref, [:@ident, "par", [29, 18]]]]], nil, nil, nil]]
156
152
  def on_defs(args, rest)
157
- on_def(rest[1], rest[2..-1]) if args[1][1] == 'self' && rest[0][1] == '.'
153
+ on_def(rest[1], rest[2..]) if args[1][1] == 'self' && rest[0][1] == '.'
158
154
  end
159
155
 
160
156
  # Multiple left hand side
@@ -269,7 +265,11 @@ module RubyLanguageServer
269
265
  private
270
266
 
271
267
  def add_variable(name, line, column, scope = @current_scope)
272
- scope.variables.where(name: name).first_or_create(line: line, column: column)
268
+ newvar = scope.variables.where(name: name).first_or_create!(
269
+ line: line,
270
+ column: column,
271
+ code_file: scope.code_file
272
+ )
273
273
  if scope.top_line.blank?
274
274
  scope.top_line = line
275
275
  scope.save!
@@ -278,6 +278,7 @@ module RubyLanguageServer
278
278
  # # blocks don't declare their first line in the parser
279
279
  # scope.top_line ||= line
280
280
  # scope.variables << new_variable unless scope.has_variable_or_constant?(new_variable)
281
+ newvar
281
282
  end
282
283
 
283
284
  def add_ivar(name, line, column)
@@ -7,6 +7,10 @@ module RubyLanguageServer
7
7
  rspec_block_command('describe', line, args, rest)
8
8
  end
9
9
 
10
+ def on_context_command(line, args, rest)
11
+ rspec_block_command('context', line, args, rest)
12
+ end
13
+
10
14
  def on_it_command(line, args, rest)
11
15
  rspec_block_command('it', line, args, rest)
12
16
  end
@@ -44,8 +44,7 @@ module RubyLanguageServer
44
44
  private
45
45
 
46
46
  def ruby_command_names(rest)
47
- names = rest.flatten.select { |o| o.instance_of? String }
48
- names
47
+ rest.flatten.select { |o| o.instance_of? String }
49
48
  end
50
49
 
51
50
  def ruby_command_column(args)
@@ -18,7 +18,7 @@ module RubyLanguageServer
18
18
  root_uri = params['rootUri']
19
19
  @project_manager = ProjectManager.new(root_path, root_uri)
20
20
  @project_manager.scan_all_project_files(@mutex)
21
- gem_string = ENV.fetch('ADDITIONAL_GEMS') {}
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)
24
24
  {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyLanguageServer
4
- VERSION = '0.3.10'
4
+ VERSION = '0.3.15'
5
5
  end
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
14
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."'
15
15
  spec.homepage = 'https://github.com/kwerle/ruby_language_server'
16
16
  spec.license = 'MIT'
17
+ spec.required_ruby_version = '>=2.7.0'
17
18
 
18
19
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
20
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -46,14 +47,14 @@ Gem::Specification.new do |spec|
46
47
  spec.add_dependency 'amatch' # in c
47
48
  spec.add_dependency 'fuzzy_match' # completion matching
48
49
 
49
- spec.add_dependency 'activerecord', '~>5.2'
50
+ spec.add_dependency 'activerecord', '~>6.1'
50
51
  spec.add_dependency 'sqlite3'
51
52
 
52
53
  spec.add_development_dependency 'guard'
53
54
  spec.add_development_dependency 'guard-minitest'
54
55
  spec.add_development_dependency 'guard-rubocop'
55
- spec.add_development_dependency 'minitest', '~>5.11'
56
- spec.add_development_dependency 'minitest-color'
56
+ spec.add_development_dependency 'minitest'
57
+ spec.add_development_dependency 'minitest-reporters'
57
58
  spec.add_development_dependency 'pry'
58
59
  spec.add_development_dependency 'pry-byebug'
59
60
  spec.add_development_dependency 'rake' # required by guard :-(
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.10
4
+ version: 0.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurt Werle
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-24 00:00:00.000000000 Z
11
+ date: 2021-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '5.2'
131
+ version: '6.1'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '5.2'
138
+ version: '6.1'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: sqlite3
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -196,18 +196,18 @@ dependencies:
196
196
  name: minitest
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
- - - "~>"
199
+ - - ">="
200
200
  - !ruby/object:Gem::Version
201
- version: '5.11'
201
+ version: '0'
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
- - - "~>"
206
+ - - ">="
207
207
  - !ruby/object:Gem::Version
208
- version: '5.11'
208
+ version: '0'
209
209
  - !ruby/object:Gem::Dependency
210
- name: minitest-color
210
+ name: minitest-reporters
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
@@ -332,7 +332,7 @@ metadata:
332
332
  homepage_uri: https://github.com/kwerle/ruby_language_server
333
333
  source_code_uri: https://github.com/kwerle/ruby_language_server
334
334
  changelog_uri: https://github.com/kwerle/ruby_language_server/blob/develop/CHANGELOG.txt
335
- post_install_message:
335
+ post_install_message:
336
336
  rdoc_options: []
337
337
  require_paths:
338
338
  - lib
@@ -340,15 +340,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
340
340
  requirements:
341
341
  - - ">="
342
342
  - !ruby/object:Gem::Version
343
- version: '0'
343
+ version: 2.7.0
344
344
  required_rubygems_version: !ruby/object:Gem::Requirement
345
345
  requirements:
346
346
  - - ">="
347
347
  - !ruby/object:Gem::Version
348
348
  version: '0'
349
349
  requirements: []
350
- rubygems_version: 3.1.2
351
- signing_key:
350
+ rubygems_version: 3.2.15
351
+ signing_key:
352
352
  specification_version: 4
353
353
  summary: Provide a language server implementation for ruby in ruby.
354
354
  test_files: []