ruby_language_server 0.3.9 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7f8d3e239241819fab0206c27fa63422d46001a58048b52355e3817243b8239
4
- data.tar.gz: 8c43b621ee0d3124fb122f725828426d9a9c88dc2a8217a74725c0868dabb4bc
3
+ metadata.gz: 1fdf50a580011d2f07140cf07fdc61118f002ecc8e59fb62646316b6141ada95
4
+ data.tar.gz: 5cc56793731893e50c390274dbec4e28f6b7066624f8df7202732a4139ba5a2a
5
5
  SHA512:
6
- metadata.gz: a90bef1450867b3816a091175a7d2a51e25f05972fdce4460c0f0da472e9ba2ae09af7aa23a48a290e5fa53925619af942752e34af390b436fa79256c0198108
7
- data.tar.gz: e6d05f5fce1ee700e55e0e863f1731481848cba12ab6e2f6064270e67ae5711da43ea5da1896608389e052b474fd11394fd5ec458288e9b5ad665119ceef39e6
6
+ metadata.gz: 4f355accf5116abd9cad0a0d9ee5f30e0853821d2860df3d4394d62ead5cea50cd5acfcb0187bd3fafefb7752bfc78d6dd8b5cc347ec29df2d3095c3c8a9917b
7
+ data.tar.gz: ab2415c7d9ad243730380ebd7b808c4d8c4911f725f5505e658de3439880755e86b7f50ea57ae21ca506c38ddf86e99d6a877958a6c2ba2d4a56d219d7c30a36
data/CHANGELOG.txt CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ #### 0.3.14 Sat Apr 24 21:09:07 PDT 2021
4
+
5
+ * Update rails activerecord to 6.1
6
+ * Update ruby to 3
7
+ * Fix some tests, docs, etc
8
+
9
+ #### 0.3.13 Fri Feb 14 00:55:28 PST 2020
10
+
11
+ * More stabbing at goodcop gemfile issues
12
+ * Hopefully much higher performance and better completions
13
+
14
+ #### 0.3.12 Thu Feb 6 06:18:33 UTC 2020
15
+
16
+ * #58 Change the way additional gems are installed so there are not conflicts
17
+
18
+ #### 0.3.11 Wed Jan 29 06:48:37 UTC 2020
19
+
20
+ * #57 rubocop gemfiles mismatch
21
+ * #56 .rubocop.yml changes do not rerun rubocop validations
22
+
23
+ #### 0.3.10 Fri Jan 24 00:19:14 PST 2020
24
+
25
+ * botched the 0.3.9 release
26
+
3
27
  #### 0.3.9 Fri Jan 24 00:19:14 PST 2020
4
28
 
5
29
  * #55 Some problem with completion
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_language_server (0.3.9)
5
- activerecord (~> 5.2)
4
+ ruby_language_server (0.3.14)
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/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)
@@ -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.9'
4
+ VERSION = '0.3.14'
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.9
4
+ version: 0.3.14
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-04-25 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: []