Class: RubyLsp::Requests::CodeLens

Inherits:
Listener
  • Object
show all
Extended by:
T::Generic, T::Sig
Defined in:
lib/ruby_lsp/requests/code_lens.rb

Overview

![Code lens demo](../../code_lens.gif)

This feature is currently experimental. Clients will need to pass experimentalFeaturesEnabled in the initialization options to enable it.

The [code lens](microsoft.github.io/language-server-protocol/specification#textDocument_codeLens) request informs the editor of runnable commands such as tests

# Example

“‘ruby # Run class Test < Minitest::Test end “`

Constant Summary collapse

ResponseType =
type_member { { fixed: T::Array[Interface::CodeLens] } }
BASE_COMMAND =
T.let((File.exist?("Gemfile.lock") ? "bundle exec ruby" : "ruby") + " -Itest ", String)
ACCESS_MODIFIERS =
T.let(["public", "private", "protected"], T::Array[String])

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Listener

add_listener, listeners

Methods included from Support::Common

#create_code_lens, #full_constant_name, #range_from_syntax_tree_node, #visible?

Constructor Details

#initialize(uri, emitter, message_queue) ⇒ CodeLens

Returns a new instance of CodeLens.



35
36
37
38
39
40
41
42
43
44
# File 'lib/ruby_lsp/requests/code_lens.rb', line 35

def initialize(uri, emitter, message_queue)
  super(emitter, message_queue)

  @response = T.let([], ResponseType)
  @path = T.let(T.must(URI(uri).path), String)
  @visibility = T.let("public", String)
  @prev_visibility = T.let("public", String)

  emitter.register(self, :on_class, :on_def, :on_command, :after_command, :on_call, :after_call, :on_vcall)
end

Instance Attribute Details

#responseObject (readonly)

Returns the value of attribute response.



32
33
34
# File 'lib/ruby_lsp/requests/code_lens.rb', line 32

def response
  @response
end

Instance Method Details

#after_call(node) ⇒ Object



95
96
97
# File 'lib/ruby_lsp/requests/code_lens.rb', line 95

def after_call(node)
  @visibility = @prev_visibility
end

#after_command(node) ⇒ Object



77
78
79
# File 'lib/ruby_lsp/requests/code_lens.rb', line 77

def after_command(node)
  @visibility = @prev_visibility
end

#merge_response!(other) ⇒ Object



110
111
112
113
# File 'lib/ruby_lsp/requests/code_lens.rb', line 110

def merge_response!(other)
  @response.concat(other.response)
  self
end

#on_call(node) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ruby_lsp/requests/code_lens.rb', line 82

def on_call(node)
  ident = node.message if node.message.is_a?(SyntaxTree::Ident)

  if ident
    ident_value = T.cast(ident, SyntaxTree::Ident).value
    if ACCESS_MODIFIERS.include?(ident_value)
      @prev_visibility = @visibility
      @visibility = ident_value
    end
  end
end

#on_class(node) ⇒ Object



47
48
49
50
51
52
# File 'lib/ruby_lsp/requests/code_lens.rb', line 47

def on_class(node)
  class_name = node.constant.constant.value
  if class_name.end_with?("Test")
    add_code_lens(node, name: class_name, command: BASE_COMMAND + @path)
  end
end

#on_command(node) ⇒ Object



69
70
71
72
73
74
# File 'lib/ruby_lsp/requests/code_lens.rb', line 69

def on_command(node)
  if ACCESS_MODIFIERS.include?(node.message.value) && node.arguments.parts.any?
    @prev_visibility = @visibility
    @visibility = node.message.value
  end
end

#on_def(node) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ruby_lsp/requests/code_lens.rb', line 55

def on_def(node)
  if @visibility == "public"
    method_name = node.name.value
    if method_name.start_with?("test_")
      add_code_lens(
        node,
        name: method_name,
        command: BASE_COMMAND + @path + " --name " + method_name,
      )
    end
  end
end

#on_vcall(node) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/ruby_lsp/requests/code_lens.rb', line 100

def on_vcall(node)
  vcall_value = node.value.value

  if ACCESS_MODIFIERS.include?(vcall_value)
    @prev_visibility = vcall_value
    @visibility = vcall_value
  end
end