Module: RubyLsp::Refactor::Support::NodeHelpers

Overview

Shared helpers mixed into every listener.

Provides:

- node_to_lsp_range(node)       – Prism location → Interface::Range
- node_covers_cursor?(node)      – overlap check against @node_context.range
- single_edit_workspace_edit(…)  – convenience WorkspaceEdit factory

Instance Method Summary collapse

Instance Method Details

#delete_line_edit(node) ⇒ Interface::TextEdit

Produces a TextEdit that deletes the full source line of node, including its trailing newline so no blank line is left behind.

Parameters:

  • node (Prism::Node)

Returns:

  • (Interface::TextEdit)


80
81
82
83
84
85
86
87
88
89
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 80

def delete_line_edit(node)
  line = node.location.start_line - 1
  Interface::TextEdit.new(
    range: Interface::Range.new(
      start: Interface::Position.new(line: line, character: 0),
      end: Interface::Position.new(line: line + 1, character: 0)
    ),
    new_text: ""
  )
end

#indent_for(node) ⇒ String

Leading whitespace for the line that contains node.

Parameters:

  • node (Prism::Node)

Returns:

  • (String)


95
96
97
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 95

def indent_for(node)
  " " * node.location.start_column
end

#multi_edit_workspace_edit(edits) ⇒ Interface::WorkspaceEdit

Builds a WorkspaceEdit from an arbitrary array of TextEdit objects.

Parameters:

  • edits (Array<Interface::TextEdit>)

Returns:

  • (Interface::WorkspaceEdit)


69
70
71
72
73
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 69

def multi_edit_workspace_edit(edits)
  Interface::WorkspaceEdit.new(
    changes: { @node_context.uri => edits }
  )
end

#node_covers_cursor?(node) ⇒ Boolean

Returns true when the node’s source range overlaps the cursor/selection range provided by the LSP client via @node_context.

Parameters:

  • node (Prism::Node)

Returns:

  • (Boolean)


36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 36

def node_covers_cursor?(node)
  cursor = @node_context.range
  return true unless cursor

  node_start = node.location.start_line - 1
  node_end   = node.location.end_line   - 1

  cursor_start = cursor.start.line
  cursor_end   = cursor.end.line

  node_start <= cursor_end && node_end >= cursor_start
end

#node_to_lsp_range(node) ⇒ Interface::Range

Converts a Prism node’s location to an LSP Interface::Range.

Parameters:

  • node (Prism::Node)

Returns:

  • (Interface::Range)


17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 17

def node_to_lsp_range(node)
  loc = node.location
  Interface::Range.new(
    start: Interface::Position.new(
      line: loc.start_line - 1,
      character: loc.start_column
    ),
    end: Interface::Position.new(
      line: loc.end_line - 1,
      character: loc.end_column
    )
  )
end

#single_edit_workspace_edit(node, new_text) ⇒ Interface::WorkspaceEdit

Builds a WorkspaceEdit containing a single TextEdit that replaces the entire range of node with new_text.

Parameters:

  • node (Prism::Node)
  • new_text (String)

Returns:

  • (Interface::WorkspaceEdit)


55
56
57
58
59
60
61
62
63
# File 'lib/ruby_lsp/ruby_lsp_refactor/support/node_helpers.rb', line 55

def single_edit_workspace_edit(node, new_text)
  Interface::WorkspaceEdit.new(
    changes: {
      @node_context.uri => [
        Interface::TextEdit.new(range: node_to_lsp_range(node), new_text: new_text)
      ]
    }
  )
end