Class: RubyLsp::Requests::OnTypeFormatting

Inherits:
Request
  • Object
show all
Defined in:
lib/ruby_lsp/requests/on_type_formatting.rb

Overview

The [on type formatting](microsoft.github.io/language-server-protocol/specification#textDocument_onTypeFormatting) request formats code as the user is typing. For example, automatically adding ‘end` to class definitions.

Constant Summary collapse

END_REGEXES =
[
  /\b(if|unless|for|while|until)\b($|\s|\()/,
  /\b(class|module|def|case)\b($|\s)/,
  /.*\s\bdo\b($|\s)/,
]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, position, trigger_character, client_name) ⇒ OnTypeFormatting

: (RubyDocument document, Hash[Symbol, untyped] position, String trigger_character, String client_name) -> void



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ruby_lsp/requests/on_type_formatting.rb', line 27

def initialize(document, position, trigger_character, client_name)
  super()
  @document = document
  @lines = @document.source.lines #: Array[String]
  line = @lines[[position[:line] - 1, 0].max]

  @indentation = line ? find_indentation(line) : 0 #: Integer
  @previous_line = line ? line.strip.chomp : "" #: String
  @position = position
  @edits = [] #: Array[Interface::TextEdit]
  @trigger_character = trigger_character
  @client_name = client_name
end

Class Method Details

.providerObject

: -> Interface::DocumentOnTypeFormattingRegistrationOptions



11
12
13
14
15
16
17
# File 'lib/ruby_lsp/requests/on_type_formatting.rb', line 11

def provider
  Interface::DocumentOnTypeFormattingRegistrationOptions.new(
    document_selector: nil,
    first_trigger_character: "{",
    more_trigger_character: ["\n", "|", "d"],
  )
end

Instance Method Details

#performObject

: -> (Array & Object)



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
71
72
# File 'lib/ruby_lsp/requests/on_type_formatting.rb', line 43

def perform
  case @trigger_character
  when "{"
    handle_curly_brace if @document.syntax_error?
  when "|"
    handle_pipe if @document.syntax_error?
  when "\n"
    # If the previous line is a simple comment, we'll add a comment continuation
    # But if it's a RBS signature starting with `#:`, we'll ignore it
    # so users can immediately continue typing the method definition
    if (comment_match = @previous_line.match(/^#(?!:)(\s*)/))
      handle_comment_line(
        comment_match[1], #: as !nil
      )
    elsif @document.syntax_error?
      match = /(<<((-|~)?))(?<quote>['"`]?)(?<delimiter>\w+)\k<quote>/.match(@previous_line)
      heredoc_delimiter = match && match.named_captures["delimiter"]

      if heredoc_delimiter
        handle_heredoc_end(heredoc_delimiter)
      else
        handle_statement_end
      end
    end
  when "d"
    auto_indent_after_end_keyword
  end

  @edits
end