Class: Ibex::LSP::PositionCodec
- Inherits:
-
Object
- Object
- Ibex::LSP::PositionCodec
- Defined in:
- lib/ibex/lsp/position_codec.rb
Overview
Converts between frontend byte offsets and zero-based LSP UTF-16 positions.
Instance Method Summary collapse
- #byte_offset(position) ⇒ Object
-
#initialize(source) ⇒ PositionCodec
constructor
A new instance of PositionCodec.
- #position(byte_offset) ⇒ Object
- #range(span) ⇒ Object
Constructor Details
#initialize(source) ⇒ PositionCodec
Returns a new instance of PositionCodec.
8 9 10 11 |
# File 'lib/ibex/lsp/position_codec.rb', line 8 def initialize(source) @source = Frontend::SourceEncoding.validated_utf8(source, "(lsp)") @line_starts = build_line_starts.freeze #: Array[Integer] end |
Instance Method Details
#byte_offset(position) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ibex/lsp/position_codec.rb', line 29 def byte_offset(position) line = integer_member(position, "line") character = integer_member(position, "character") raise ArgumentError, "line and character must be non-negative" if line.negative? || character.negative? line_start = @line_starts[line] raise ArgumentError, "line is outside the document" unless line_start text = @source.byteslice(line_start, content_end(line) - line_start) || "" line_start + byte_length_at_utf16(text, character) end |
#position(byte_offset) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/ibex/lsp/position_codec.rb', line 14 def position(byte_offset) validate_byte_offset(byte_offset) prefix = @source.byteslice(0, byte_offset) || "" raise ArgumentError, "byte offset is not on a UTF-8 character boundary" unless prefix.valid_encoding? line = (@line_starts.bsearch_index { |start| start > byte_offset } || @line_starts.length) - 1 line_start = @line_starts.fetch(line) line_end = content_end(line) raise ArgumentError, "byte offset points inside a line ending" if byte_offset > line_end text = @source.byteslice(line_start, byte_offset - line_start) || "" { "line" => line, "character" => utf16_length(text) } end |
#range(span) ⇒ Object
42 43 44 |
# File 'lib/ibex/lsp/position_codec.rb', line 42 def range(span) { "start" => position(span.start_byte), "end" => position(span.end_byte) } end |