Class: FlogLsp::Server
- Inherits:
-
Object
- Object
- FlogLsp::Server
- Defined in:
- lib/flog_lsp/lsp.rb
Constant Summary collapse
- HANDLERS =
{ "initialize" => :handle_initialize, "initialized" => :handle_initialized, "textDocument/diagnostic" => :handle_diagnostic, "textDocument/didOpen" => :handle_open, "textDocument/didChange" => :handle_change, "textDocument/didClose" => :handle_close, "shutdown" => :handle_shutdown, "exit" => :handle_exit, }
Instance Method Summary collapse
- #file_data(uri) ⇒ Object
- #get_diagnostics(contents) ⇒ Object
- #get_prefix(lines, line, character) ⇒ Object
- #get_suffix(lines, line, character) ⇒ Object
- #handle(request) ⇒ Object
- #handle_change(request) ⇒ Object
- #handle_close(request) ⇒ Object
- #handle_diagnostic(request) ⇒ Object
- #handle_exit(request) ⇒ Object
- #handle_initialize(request) ⇒ Object
- #handle_initialized(request) ⇒ Object
- #handle_open(request) ⇒ Object
- #handle_shutdown(request) ⇒ Object
-
#initialize ⇒ Server
constructor
A new instance of Server.
- #logger ⇒ Object
- #patch_contents(contents, range, text) ⇒ Object
- #score_threshold ⇒ Object
- #start ⇒ Object
Constructor Details
#initialize ⇒ Server
Returns a new instance of Server.
36 37 38 39 |
# File 'lib/flog_lsp/lsp.rb', line 36 def initialize @file_data = {} @options = {} end |
Instance Method Details
#file_data(uri) ⇒ Object
45 46 47 48 49 50 51 |
# File 'lib/flog_lsp/lsp.rb', line 45 def file_data(uri) @file_data[uri] ||= begin path = CGI.unescape(URI.parse(uri).path) logger.debug("Loading file #{path}") File.read(path) end end |
#get_diagnostics(contents) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/flog_lsp/lsp.rb', line 157 def get_diagnostics(contents) flog = Flog.new flog.flog_ruby(contents) flog.calculate_total_scores flog.totals.filter_map do |method_name, score| next if score <= score_threshold location = flog.method_locations[method_name] next unless location _filename, range = location.split(":") start_line, _end_line = range.split("-") [method_name, start_line, score] end end |
#get_prefix(lines, line, character) ⇒ Object
126 127 128 |
# File 'lib/flog_lsp/lsp.rb', line 126 def get_prefix(lines, line, character) lines[0...line].join + lines[line][0...character] end |
#get_suffix(lines, line, character) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/flog_lsp/lsp.rb', line 130 def get_suffix(lines, line, character) if line >= lines.length "" else lines[line][character..] + lines[line + 1..].join end end |
#handle(request) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/flog_lsp/lsp.rb', line 68 def handle(request) logger.debug("Received request: #{request[:method]}") if HANDLERS.key?(request[:method]) send(HANDLERS[request[:method]], request) else logger.warn("Unknown request: #{request[:method]}") nil end end |
#handle_change(request) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/flog_lsp/lsp.rb', line 145 def handle_change(request) uri = request[:params][:textDocument][:uri] request[:params][:contentChanges].each do |change| @file_data[uri] = if change.key?(:range) patch_contents(file_data(uri), change[:range], change[:text]) else change[:text] end end nil end |
#handle_close(request) ⇒ Object
120 121 122 123 124 |
# File 'lib/flog_lsp/lsp.rb', line 120 def handle_close(request) uri = request[:params][:textDocument][:uri] @file_data.delete(uri) nil end |
#handle_diagnostic(request) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/flog_lsp/lsp.rb', line 173 def handle_diagnostic(request) uri = request[:params][:textDocument][:uri] contents = file_data(uri) diagnostics = get_diagnostics(contents).map do |method_name, start_line, score| LSP::Interface::Diagnostic.new( range: LSP::Interface::Range.new( start: LSP::Interface::Position.new(line: start_line.to_i - 1, character: 0), end: LSP::Interface::Position.new(line: start_line.to_i - 1, character: 0), # end: LSP::Interface::Position.new(line: end_line.to_i - 1, character: 0), ), severity: LSP::Constant::DiagnosticSeverity::WARNING, source: "flog", message: "#{method_name} has a flog score of #{score.round(2)}", data: { correctable: false }, ) end LSP::Interface::FullDocumentDiagnosticReport.new(kind: "full", items: diagnostics) rescue StandardError => e logger.error("Error calculating flog: #{e}") LSP::Interface::FullDocumentDiagnosticReport.new(kind: "full", items: []) end |
#handle_exit(request) ⇒ Object
109 110 111 |
# File 'lib/flog_lsp/lsp.rb', line 109 def handle_exit(request) Kernel.exit(0) end |
#handle_initialize(request) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/flog_lsp/lsp.rb', line 78 def handle_initialize(request) logger.debug("Initializing with request: #{request}") @options = request[:params][:initializationOptions] || {} LSP::Interface::InitializeResult.new( capabilities: LSP::Interface::ServerCapabilities.new( text_document_sync: LSP::Interface::TextDocumentSyncOptions.new( change: LSP::Constant::TextDocumentSyncKind::INCREMENTAL, open_close: true, ), diagnostic_provider: LSP::Interface::DiagnosticOptions.new( identifier: "flog", inter_file_dependencies: false, workspace_diagnostics: false, ), ), server_info: { name: "Flog LSP", version: FlogLsp::VERSION, }, ) end |
#handle_initialized(request) ⇒ Object
101 102 103 |
# File 'lib/flog_lsp/lsp.rb', line 101 def handle_initialized(request) nil end |
#handle_open(request) ⇒ Object
113 114 115 116 117 118 |
# File 'lib/flog_lsp/lsp.rb', line 113 def handle_open(request) # Load the file uri = request[:params][:textDocument][:uri] file_data(uri) nil end |
#handle_shutdown(request) ⇒ Object
105 106 107 |
# File 'lib/flog_lsp/lsp.rb', line 105 def handle_shutdown(request) nil end |
#patch_contents(contents, range, text) ⇒ Object
138 139 140 141 142 143 |
# File 'lib/flog_lsp/lsp.rb', line 138 def patch_contents(contents, range, text) lines = contents.lines prefix = get_prefix(lines, range[:start][:line], range[:start][:character]) suffix = get_suffix(lines, range[:end][:line], range[:end][:character]) prefix + text + suffix end |
#score_threshold ⇒ Object
41 42 43 |
# File 'lib/flog_lsp/lsp.rb', line 41 def score_threshold @options.fetch(:score_threshold, 10) end |
#start ⇒ Object
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/flog_lsp/lsp.rb', line 57 def start writer = LSP::Transport::Stdio::Writer.new reader = LSP::Transport::Stdio::Reader.new reader.read do |request| response = handle(request) unless response.nil? writer.write(id: request[:id], result: response) end end end |