Module: MilkTea::LSP::Server::ServerSelectionRange
- Included in:
- MilkTea::LSP::Server
- Defined in:
- lib/milk_tea/lsp/server/selection_range.rb
Instance Method Summary collapse
- #build_selection_range(lines, lsp_line, lsp_char) ⇒ Object
- #find_enclosing_block_range(lines, lsp_line) ⇒ Object
- #find_statement_range(lines, lsp_line) ⇒ Object
- #handle_selection_range(params) ⇒ Object
- #token_bounds_at(line_str, lsp_char) ⇒ Object
Instance Method Details
#build_selection_range(lines, lsp_line, lsp_char) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/milk_tea/lsp/server/selection_range.rb', line 23 def build_selection_range(lines, lsp_line, lsp_char) line_str = lines[lsp_line] || "" return nil if line_str.empty? token_range = token_bounds_at(line_str, lsp_char) line_range = { start: { line: lsp_line, character: 0 }, end: { line: lsp_line, character: line_str.length } } current = { range: token_range || line_range, } current[:parent] = { range: line_range } statement_range = find_statement_range(lines, lsp_line) if statement_range current[:parent][:parent] = { range: statement_range } block_range = find_enclosing_block_range(lines, lsp_line) if block_range current[:parent][:parent][:parent] = { range: block_range } end end current end |
#find_enclosing_block_range(lines, lsp_line) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/milk_tea/lsp/server/selection_range.rb', line 94 def find_enclosing_block_range(lines, lsp_line) indent = (lines[lsp_line] || "").length - (lines[lsp_line] || "").lstrip.length return nil if indent <= 0 start_line = lsp_line start_line -= 1 while start_line > 0 && ((lines[start_line - 1].strip.empty?) || (lines[start_line - 1].length - lines[start_line - 1].lstrip.length) >= indent) while start_line > 0 && (lines[start_line - 1].strip.empty? || (lines[start_line - 1].length - lines[start_line - 1].lstrip.length) >= indent) start_line -= 1 end end_line = lsp_line while end_line < lines.length - 1 && (lines[end_line + 1].strip.empty? || (lines[end_line + 1].length - lines[end_line + 1].lstrip.length) >= indent) end_line += 1 end return nil if start_line == end_line { start: { line: start_line, character: 0 }, end: { line: end_line, character: (lines[end_line] || "").length }, } end |
#find_statement_range(lines, lsp_line) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/milk_tea/lsp/server/selection_range.rb', line 69 def find_statement_range(lines, lsp_line) indent = (lines[lsp_line] || "").length - (lines[lsp_line] || "").lstrip.length start_line = lsp_line start_line -= 1 while start_line > 0 && lines[start_line - 1].strip.empty? && (lines[start_line - 1].length - lines[start_line - 1].lstrip.length) >= indent start_line -= 1 while start_line > 0 && !lines[start_line - 1].strip.empty? && (lines[start_line - 1].length - lines[start_line - 1].lstrip.length) >= indent end_line = lsp_line end_line += 1 while end_line < lines.length - 1 && (lines[end_line + 1].strip.empty? || (lines[end_line + 1].length - lines[end_line + 1].lstrip.length) > indent) return nil if start_line == end_line && lines[start_line].strip.empty? { start: { line: start_line, character: 0 }, end: { line: end_line, character: (lines[end_line] || "").length }, } end |
#handle_selection_range(params) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/milk_tea/lsp/server/selection_range.rb', line 7 def handle_selection_range(params) positions = params["positions"] || [] uri = params["textDocument"]["uri"] content = @workspace.get_content(uri) return [] unless content lines = content.split("\n", -1) positions.map do |pos| line = pos["line"] char = pos["character"] build_selection_range(lines, line, char) end end |
#token_bounds_at(line_str, lsp_char) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/milk_tea/lsp/server/selection_range.rb', line 50 def token_bounds_at(line_str, lsp_char) col = [lsp_char, line_str.length - 1].min col = [col, 0].max return nil if line_str[col] == " " || line_str[col].nil? left = col left -= 1 while left > 0 && line_str[left - 1] =~ /[A-Za-z0-9_]/ right = col right += 1 while right < line_str.length - 1 && line_str[right + 1] =~ /[A-Za-z0-9_]/ return nil if left == right && line_str[left] !~ /[A-Za-z0-9_]/ { start: { line: 0, character: left }, end: { line: 0, character: right + 1 }, } end |