Class: Solargraph::Source::Cursor

Inherits:
Object
  • Object
show all
Defined in:
lib/solargraph/source/cursor.rb

Overview

Information about a position in a source, including the word located there.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, position) ⇒ Cursor


15
16
17
18
# File 'lib/solargraph/source/cursor.rb', line 15

def initialize source, position
  @source = source
  @position = Position.normalize(position)
end

Instance Attribute Details

#positionPosition (readonly)


8
9
10
# File 'lib/solargraph/source/cursor.rb', line 8

def position
  @position
end

#sourceSource (readonly)


11
12
13
# File 'lib/solargraph/source/cursor.rb', line 11

def source
  @source
end

Instance Method Details

#argument?Boolean

True if the statement at the cursor is an argument to a previous method.

Given the code `process(foo)`, a cursor pointing at `foo` would identify it as an argument being passed to the `process` method.

If #argument? is true, the #recipient method will return a cursor that points to the method receiving the argument.


89
90
91
92
# File 'lib/solargraph/source/cursor.rb', line 89

def argument?
  # @argument ||= !signature_position.nil?
  @argument ||= !recipient.nil?
end

#chainChain


75
76
77
# File 'lib/solargraph/source/cursor.rb', line 75

def chain
  @chain ||= SourceChainer.chain(source, position)
end

#comment?Boolean


95
96
97
# File 'lib/solargraph/source/cursor.rb', line 95

def comment?
  @comment ||= source.comment_at?(position)
end

#end_of_wordString

The part of the word after the current position. Given the text `foo.bar`, the end_of_word at position (0,6) is `r`.


51
52
53
54
55
56
# File 'lib/solargraph/source/cursor.rb', line 51

def end_of_word
  @end_of_word ||= begin
    match = source.code[offset..-1].to_s.match(end_word_pattern)
    match ? match[0] : ''
  end
end

#filenameString


21
22
23
# File 'lib/solargraph/source/cursor.rb', line 21

def filename
  source.filename
end

#node_positionPosition


126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/solargraph/source/cursor.rb', line 126

def node_position
  @node_position ||= begin
    if start_of_word.empty?
      match = source.code[0, offset].match(/[\s]*(\.|:+)[\s]*$/)
      if match
        Position.from_offset(source.code, offset - match[0].length)
      else
        position
      end
    else
      position
    end
  end
end

#rangeRange

The range of the word at the current position.


66
67
68
69
70
71
72
# File 'lib/solargraph/source/cursor.rb', line 66

def range
  @range ||= begin
    s = Position.from_offset(source.code, offset - start_of_word.length)
    e = Position.from_offset(source.code, offset + end_of_word.length)
    Solargraph::Range.new(s, e)
  end
end

#recipientCursor? Also known as: receiver

Get a cursor pointing to the method that receives the current statement as an argument.


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/solargraph/source/cursor.rb', line 108

def recipient
  @recipient ||= begin
    result = nil
    node = recipient_node
    unless node.nil?
      result = if node.children[1].is_a?(AST::Node)
                 pos = Range.from_node(node.children[1]).start
                 Cursor.new(source, Position.new(pos.line, pos.column - 1))
               else
                 Cursor.new(source, Range.from_node(node).ending)
               end
    end
    result
  end
end

#recipient_nodeParser::AST::Node?


142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/solargraph/source/cursor.rb', line 142

def recipient_node
  return nil if source.code[offset-1] == ')' || source.code[0..offset] =~ /[^,][ \t]*?\n[ \t]*?\Z/
  return nil if first_char_offset < offset && source.code[first_char_offset..offset-1] =~ /\)[\s]*\Z/
  pos = Position.from_offset(source.code, first_char_offset)
  tree = source.tree_at(pos.line, pos.character)
  if tree[0] && tree[0].type == :send
    rng = Range.from_node(tree[0])
    return tree[0] if (rng.contain?(position) || offset + 1 == Position.to_offset(source.code, rng.ending)) && source.code[offset] =~ /[ \t\)\,'")]/
    return tree[0] if (source.code[0..offset-1] =~ /\([\s]*\Z/ || source.code[0..offset-1] =~ /[a-z0-9_][ \t]+\Z/i)
  end
  return tree[1] if tree[1] && tree[1].type == :send
  return tree[3] if tree[1] && tree[3] && tree[1].type == :pair && tree[3].type == :send
  nil
end

#start_of_constant?Boolean


59
60
61
# File 'lib/solargraph/source/cursor.rb', line 59

def start_of_constant?
  source.code[offset-2, 2] == '::'
end

#start_of_wordString

The part of the word before the current position. Given the text `foo.bar`, the start_of_word at position(0, 6) is `ba`.


37
38
39
40
41
42
43
44
45
# File 'lib/solargraph/source/cursor.rb', line 37

def start_of_word
  @start_of_word ||= begin
    match = source.code[0..offset-1].to_s.match(start_word_pattern)
    result = (match ? match[0] : '')
    # Including the preceding colon if the word appears to be a symbol
    result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::')
    result
  end
end

#string?Boolean


100
101
102
# File 'lib/solargraph/source/cursor.rb', line 100

def string?
  @string ||= source.string_at?(position)
end

#wordString

The whole word at the current position. Given the text `foo.bar`, the word at position(0,6) is `bar`.


29
30
31
# File 'lib/solargraph/source/cursor.rb', line 29

def word
  @word ||= start_of_word + end_of_word
end