Module: RubyLsp::Rails::Common

Included in:
Server, ServerAddon
Defined in:
lib/ruby_lsp/ruby_lsp_rails/server.rb

Overview

@requires_ancestor: ServerComponent

Defined Under Namespace

Classes: Progress

Instance Method Summary collapse

Instance Method Details

#begin_progress(id, title, percentage: nil, message: nil) ⇒ Object

: (String, String, ?percentage: Integer?, ?message: String?) -> void



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 94

def begin_progress(id, title, percentage: nil, message: nil)
  return unless capabilities[:supports_progress]

  # This is actually a request, but it is sent asynchronously and we do not return the response back to the
  # server, so we consider it a notification from the perspective of the client/runtime server dynamic
  send_notification({
    id: "progress-request-#{id}",
    method: "window/workDoneProgress/create",
    params: { token: id },
  })

  send_notification({
    method: "$/progress",
    params: {
      token: id,
      value: {
        kind: "begin",
        title: title,
        percentage: percentage,
        message: message,
      },
    },
  })
end

#end_progress(id) ⇒ Object

: (String) -> void



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 137

def end_progress(id)
  return unless capabilities[:supports_progress]

  send_notification({
    method: "$/progress",
    params: {
      token: id,
      value: { kind: "end" },
    },
  })
end

#log_message(message, type: 4) ⇒ Object

Log a message to the editor’s output panel. The type is the number of the message type, which can be found in the specification microsoft.github.io/language-server-protocol/specification/#messageType : (String, ?type: Integer) -> void



44
45
46
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 44

def log_message(message, type: 4)
  send_notification({ method: "window/logMessage", params: { type: type, message: message } })
end

#report_progress(id, percentage: nil, message: nil) ⇒ Object

: (String, ?percentage: Integer?, ?message: String?) -> void



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 120

def report_progress(id, percentage: nil, message: nil)
  return unless capabilities[:supports_progress]

  send_notification({
    method: "$/progress",
    params: {
      token: id,
      value: {
        kind: "report",
        percentage: percentage,
        message: message,
      },
    },
  })
end

#send_error_response(message) ⇒ Object

Sends an error result to a request, if the request failed. DO NOT INVOKE THIS METHOD FOR NOTIFICATIONS! Use ‘log_message` instead, otherwise the client/server communication will go out of sync : (String) -> void



51
52
53
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 51

def send_error_response(message)
  send_message({ error: message })
end

#send_result(result) ⇒ Object

Sends a result back to the client : (Hash[Symbol | String, untyped]?) -> void



57
58
59
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 57

def send_result(result)
  send_message({ result: result })
end

#with_notification_error_handling(notification_name, &block) ⇒ Object

Handle possible errors for a notification. This should only be used for notifications, which means messages that do not return a response back to the client. Errors are logged to the editor’s output panel : (String) { () -> void } -> void



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 80

def with_notification_error_handling(notification_name, &block)
  block.call
rescue ActiveRecord::ConnectionNotEstablished
  # Since this is a common problem, we show a specific error message to the user, instead of the full stack trace.
  log_message("Request #{notification_name} failed because database connection was not established.")
rescue ActiveRecord::NoDatabaseError
  log_message("Request #{notification_name} failed because the database does not exist.")
rescue NotImplementedError, LoadError, SyntaxError, SystemExit, SystemStackError => e
  log_message("Request #{notification_name} failed with #{e.class}:\n#{e.full_message(highlight: false)}")
rescue StandardError => e
  log_message("Request #{notification_name} failed with StandardError:\n#{e.full_message(highlight: false)}")
end

#with_progress(id, title, percentage: nil, message: nil, &block) ⇒ Object

: (String, String, ?percentage: Integer?, ?message: String?) { (Progress) -> void } -> void



150
151
152
153
154
155
156
157
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 150

def with_progress(id, title, percentage: nil, message: nil, &block)
  progress_block = Progress.new(stderr, id, capabilities[:supports_progress])
  return block.call(progress_block) unless capabilities[:supports_progress]

  begin_progress(id, title, percentage: percentage, message: message)
  block.call(progress_block)
  end_progress(id)
end

#with_request_error_handling(request_name, &block) ⇒ Object

Handle possible errors for a request. This should only be used for requests, which means messages that return a response back to the client. Errors are returned as an error object back to the client : (String) { () -> void } -> void



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ruby_lsp/ruby_lsp_rails/server.rb', line 64

def with_request_error_handling(request_name, &block)
  block.call
rescue ActiveRecord::ConnectionNotEstablished
  # Since this is a common problem, we show a specific error message to the user, instead of the full stack trace.
  send_error_response("Request #{request_name} failed because database connection was not established.")
rescue ActiveRecord::NoDatabaseError
  send_error_response("Request #{request_name} failed because the database does not exist.")
rescue NotImplementedError, LoadError, SyntaxError, SystemExit, SystemStackError => e
  send_error_response("Request #{request_name} failed with #{e.class}:\n#{e.full_message(highlight: false)}")
rescue StandardError => e
  send_error_response("Request #{request_name} failed with StandardError:\n#{e.full_message(highlight: false)}")
end