Class: RuVim::App

Inherits:
Object
  • Object
show all
Defined in:
lib/ruvim/app.rb

Defined Under Namespace

Classes: StartupState

Instance Method Summary collapse

Constructor Details

#initialize(path: nil, paths: nil, stdin: STDIN, ui_stdin: nil, stdin_stream_mode: false, stdout: STDOUT, pre_config_actions: [], startup_actions: [], clean: false, skip_user_config: false, config_path: nil, readonly: false, diff_mode: false, quickfix_errorfile: nil, session_file: nil, nomodifiable: false, follow: false, restricted: false, verbose_level: 0, verbose_io: STDERR, startup_time_path: nil, startup_open_layout: nil, startup_open_count: nil) ⇒ App

Returns a new instance of App.



18
19
20
21
22
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ruvim/app.rb', line 18

def initialize(path: nil, paths: nil, stdin: STDIN, ui_stdin: nil, stdin_stream_mode: false, stdout: STDOUT, pre_config_actions: [], startup_actions: [], clean: false, skip_user_config: false, config_path: nil, readonly: false, diff_mode: false, quickfix_errorfile: nil, session_file: nil, nomodifiable: false, follow: false, restricted: false, verbose_level: 0, verbose_io: STDERR, startup_time_path: nil, startup_open_layout: nil, startup_open_count: nil)
  startup_paths = Array(paths || path).compact
  @ui_stdin = ui_stdin || stdin
  @stdin_stream_mode = !!stdin_stream_mode
  @editor = Editor.new
  @terminal = Terminal.new(stdin: @ui_stdin, stdout:)
  @input = Input.new(@ui_stdin)
  @screen = Screen.new(terminal: @terminal)
  @dispatcher = Dispatcher.new
  @keymaps = KeymapManager.new
  @signal_r, @signal_w = IO.pipe
  @needs_redraw = true
  @clean_mode = clean
  @startup = StartupState.new(
    skip_user_config: skip_user_config,
    config_path: config_path,
    readonly: readonly,
    diff_mode: diff_mode,
    quickfix_errorfile: quickfix_errorfile,
    session_file: session_file,
    nomodifiable: nomodifiable,
    follow: follow,
    time_path: startup_time_path,
    time_origin: monotonic_now,
    timeline: [],
    open_layout: startup_open_layout,
    open_count: startup_open_count
  )
  @restricted_mode = restricted
  @verbose_level = verbose_level.to_i
  @verbose_io = verbose_io

  @stream_mixer = StreamMixer.new(editor: @editor, signal_w: @signal_w)
  @completion = CompletionManager.new(
    editor: @editor,
    terminal: @terminal,
    verbose_logger: method(:verbose_log)
  )
  @key_handler = KeyHandler.new(
    editor: @editor,
    dispatcher: @dispatcher,
    keymaps: @keymaps,
    terminal: @terminal,
    screen: @screen,
    completion: @completion,
    stream_mixer: @stream_mixer
  )

  @editor.restricted_mode = @restricted_mode
  @editor.open_path_handler = @stream_mixer.method(:open_path_with_large_file_support)
  @editor.keymap_manager = @keymaps
  @editor.app_action_handler = @key_handler.method(:handle_editor_app_action)
  @editor.git_stream_handler = @stream_mixer.method(:start_git_stream_command)
  @editor.git_stream_stop_handler = @stream_mixer.method(:stop_git_stream!)
  @editor.run_stream_handler = @stream_mixer.method(:start_command_stream!)
  @editor.shell_executor = ->(command) {
    result = @terminal.suspend_for_shell(command)
    @screen.invalidate_cache!
    result
  }

  @completion.load_history!

  startup_mark("init.start")
  register_builtins!
  bind_default_keys!
  init_config_loader!
  @editor.ensure_bootstrap_buffer!
  verbose_log(1, "startup: run_pre_config_actions count=#{Array(pre_config_actions).length}")
  run_startup_actions!(pre_config_actions, log_prefix: "pre-config")
  startup_mark("pre_config_actions.done")
  verbose_log(1, "startup: load_user_config")
  load_user_config!
  startup_mark("config.loaded")
  install_signal_handlers
  startup_mark("signals.installed")

  if @stdin_stream_mode && startup_paths.empty?
    verbose_log(1, "startup: stdin stream buffer")
    @stdin_stream_buf = @stream_mixer.prepare_stdin_stream_buffer!(stdin)
  elsif startup_paths.empty?
    verbose_log(1, "startup: intro")
    @editor.show_intro_buffer_if_applicable!
  else
    verbose_log(1, "startup: open_paths #{startup_paths.inspect} layout=#{@startup.open_layout || :single}")
    open_startup_paths!(startup_paths)
  end
  startup_mark("buffers.opened")
  verbose_log(1, "startup: load_current_ftplugin")
  load_current_ftplugin!
  startup_mark("ftplugin.loaded")
  apply_startup_compat_mode_messages!
  verbose_log(1, "startup: run_startup_actions count=#{Array(startup_actions).length}")
  run_startup_actions!(startup_actions)
  startup_mark("startup_actions.done")
  @stream_mixer.start_pending_stdin! if @stdin_stream_buf
  write_startuptime_log!
  @startup = nil
end

Instance Method Details

#runObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/ruvim/app.rb', line 118

def run
  @terminal.with_ui do
    loop do
      @needs_redraw = true if @stream_mixer.drain_events!
      if @needs_redraw
        @screen.render(@editor)
        @needs_redraw = false
      end
      break unless @editor.running?

      key = @input.read_key(
        wakeup_ios: [@signal_r],
        timeout: @key_handler.loop_timeout_seconds,
        esc_timeout: @key_handler.escape_sequence_timeout_seconds
      )
      if key.nil?
        @needs_redraw = true if @key_handler.handle_idle_timeout
        next
      end

      needs_redraw_from_key = @key_handler.handle(key)
      @needs_redraw = true
      load_current_ftplugin!

      # Force redraw after suspend_to_shell
      @needs_redraw = true if needs_redraw_from_key

      # Batch insert-mode keystrokes to avoid per-char rendering during paste
      if @editor.mode == :insert && @input.has_pending_input?
        @key_handler.paste_batch = true
        begin
          while @editor.mode == :insert && @input.has_pending_input?
            batch_key = @input.read_key(timeout: 0, esc_timeout: 0)
            break unless batch_key
            @key_handler.handle(batch_key)
          end
        ensure
          @key_handler.paste_batch = false
        end
      end
    end
  end
ensure
  @stream_mixer.shutdown!
  @completion.save_history!
end

#run_startup_actions!(actions, log_prefix: "startup") ⇒ Object



165
166
167
168
169
170
# File 'lib/ruvim/app.rb', line 165

def run_startup_actions!(actions, log_prefix: "startup")
  Array(actions).each do |action|
    run_startup_action!(action, log_prefix:)
    break unless @editor.running?
  end
end