Class: Pikuri::Lsp::Position
- Inherits:
-
Data
- Object
- Data
- Pikuri::Lsp::Position
- Defined in:
- lib/pikuri/lsp/position.rb
Overview
One cursor position in pikuri's coordinates: 1-based line, 1-based
character column — the same numbers read and grep print, so a
rendered location needs no arithmetic and the model never sees an encoded
offset in either direction.
The wire is 0-based and code-unit-encoded, and this pair of calls is the only place that is true:
line = File.readlines('read.rb')[164] # " workspace.resolve_for_read(path)"
pos = Position.new(line: 165, column: line.index('resolve_for_read') + 1)
pos.to_wire(line_text: line, encoding: PositionEncoding::UTF8)
# => {:line=>164, :character=>14}
Position.from_wire({ 'line' => 164, 'character' => 14 },
line_text: line, encoding: PositionEncoding::UTF8).to_s
# => "165:15"
Instance Attribute Summary collapse
-
#column ⇒ Integer
readonly
1-based column, counted in characters (not bytes, not UTF-16 code units).
-
#line ⇒ Integer
readonly
1-based line number.
Class Method Summary collapse
-
.from_wire(hash, line_text: nil, encoding: PositionEncoding::DEFAULT) ⇒ Position
Parse LSP's
Positionobject.
Instance Method Summary collapse
-
#initialize(line:, column:) ⇒ Position
constructor
A new instance of Position.
-
#to_s ⇒ String
"165:15"— the form a rendered location appends to a path. -
#to_wire(line_text:, encoding: PositionEncoding::DEFAULT) ⇒ Hash{Symbol => Integer}
Render as LSP's
Positionobject.
Constructor Details
#initialize(line:, column:) ⇒ Position
Returns a new instance of Position.
46 47 48 49 50 51 |
# File 'lib/pikuri/lsp/position.rb', line 46 def initialize(line:, column:) raise ArgumentError, "line must be >= 1, got #{line}" if line < 1 raise ArgumentError, "column must be >= 1, got #{column}" if column < 1 super end |
Instance Attribute Details
#column ⇒ Integer (readonly)
Returns 1-based column, counted in characters (not bytes, not UTF-16 code units).
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/pikuri/lsp/position.rb', line 27 Position = Data.define(:line, :column) do # Parse LSP's +Position+ object. # # @param hash [Hash{String => Integer}] +{"line" =>, "character" =>}+, # 0-based. # @param line_text [String, nil] the target line's text; +nil+ costs # column exactness on a line with multi-unit characters, see # {PositionEncoding.column_for}. # @param encoding [String] the server's negotiated +positionEncoding+. # @return [Position] # @raise [KeyError] if either wire field is missing. def self.from_wire(hash, line_text: nil, encoding: PositionEncoding::DEFAULT) new(line: Integer(hash.fetch('line')) + 1, column: PositionEncoding.column_for(line_text, Integer(hash.fetch('character')), encoding)) end # @raise [ArgumentError] if either coordinate is below 1 — a 0 means an # unconverted wire value leaked in, which is the bug this type exists # to prevent. def initialize(line:, column:) raise ArgumentError, "line must be >= 1, got #{line}" if line < 1 raise ArgumentError, "column must be >= 1, got #{column}" if column < 1 super end # Render as LSP's +Position+ object. # # @param line_text [String] the text of {#line}, required because the # column's encoding depends on the characters preceding it. # @param encoding [String] the server's negotiated +positionEncoding+. # @return [Hash{Symbol => Integer}] +{line:, character:}+, 0-based, # ready for +JSON.generate+. # @raise [ArgumentError] if {#column} points past the end of +line_text+. def to_wire(line_text:, encoding: PositionEncoding::DEFAULT) { line: line - 1, character: PositionEncoding.offset_for(line_text, column, encoding) } end # @return [String] +"165:15"+ — the form a rendered location appends to a # path. def to_s "#{line}:#{column}" end end |
#line ⇒ Integer (readonly)
Returns 1-based line number.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/pikuri/lsp/position.rb', line 27 Position = Data.define(:line, :column) do # Parse LSP's +Position+ object. # # @param hash [Hash{String => Integer}] +{"line" =>, "character" =>}+, # 0-based. # @param line_text [String, nil] the target line's text; +nil+ costs # column exactness on a line with multi-unit characters, see # {PositionEncoding.column_for}. # @param encoding [String] the server's negotiated +positionEncoding+. # @return [Position] # @raise [KeyError] if either wire field is missing. def self.from_wire(hash, line_text: nil, encoding: PositionEncoding::DEFAULT) new(line: Integer(hash.fetch('line')) + 1, column: PositionEncoding.column_for(line_text, Integer(hash.fetch('character')), encoding)) end # @raise [ArgumentError] if either coordinate is below 1 — a 0 means an # unconverted wire value leaked in, which is the bug this type exists # to prevent. def initialize(line:, column:) raise ArgumentError, "line must be >= 1, got #{line}" if line < 1 raise ArgumentError, "column must be >= 1, got #{column}" if column < 1 super end # Render as LSP's +Position+ object. # # @param line_text [String] the text of {#line}, required because the # column's encoding depends on the characters preceding it. # @param encoding [String] the server's negotiated +positionEncoding+. # @return [Hash{Symbol => Integer}] +{line:, character:}+, 0-based, # ready for +JSON.generate+. # @raise [ArgumentError] if {#column} points past the end of +line_text+. def to_wire(line_text:, encoding: PositionEncoding::DEFAULT) { line: line - 1, character: PositionEncoding.offset_for(line_text, column, encoding) } end # @return [String] +"165:15"+ — the form a rendered location appends to a # path. def to_s "#{line}:#{column}" end end |
Class Method Details
.from_wire(hash, line_text: nil, encoding: PositionEncoding::DEFAULT) ⇒ Position
Parse LSP's Position object.
38 39 40 41 |
# File 'lib/pikuri/lsp/position.rb', line 38 def self.from_wire(hash, line_text: nil, encoding: PositionEncoding::DEFAULT) new(line: Integer(hash.fetch('line')) + 1, column: PositionEncoding.column_for(line_text, Integer(hash.fetch('character')), encoding)) end |
Instance Method Details
#to_s ⇒ String
Returns "165:15" — the form a rendered location appends to a
path.
67 68 69 |
# File 'lib/pikuri/lsp/position.rb', line 67 def to_s "#{line}:#{column}" end |
#to_wire(line_text:, encoding: PositionEncoding::DEFAULT) ⇒ Hash{Symbol => Integer}
Render as LSP's Position object.
61 62 63 |
# File 'lib/pikuri/lsp/position.rb', line 61 def to_wire(line_text:, encoding: PositionEncoding::DEFAULT) { line: line - 1, character: PositionEncoding.offset_for(line_text, column, encoding) } end |