Class: Utils::Editor

Inherits:
Object show all
Defined in:
lib/utils/editor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ Utils::Editor

The initialize method sets up a new editor instance with default configuration.

This method configures the editor by initializing default values for wait flag, pause duration, and server name. It also loads the configuration file and assigns the edit configuration section to the instance.

Parameters:

  • block (Proc)

    optional block to be executed after initialization

Yields:

  • (_self)

Yield Parameters:

  • _self (Utils::Editor)

    the object that the method was called on



17
18
19
20
21
22
23
24
25
# File 'lib/utils/editor.rb', line 17

def initialize
  self.wait           = false
  self.pause_duration = 1
  self.servername     = derive_server_name
  config              = Utils::ConfigFile.new
  config.configure_from_paths
  self.config = config.edit
  yield self if block_given?
end

Instance Attribute Details

#configUtils::ConfigFile

The config method provides access to the configuration object.

This method returns the configuration instance variable that holds the settings and options for the object’s operation.

Returns:



79
80
81
# File 'lib/utils/editor.rb', line 79

def config
  @config
end

#mkdirTrueClass, FalseClass

The mkdir method provides access to the directory creation flag.

This method returns the current value of the mkdir flag, which determines whether directory creation should be attempted when processing files.

Returns:

  • (TrueClass, FalseClass)

    the current state of the mkdir flag



71
72
73
# File 'lib/utils/editor.rb', line 71

def mkdir
  @mkdir
end

#pause_durationInteger

The pause_duration method gets or sets the pause duration value.

Parameters:

  • value (Integer)

    the new pause duration value to set

Returns:

  • (Integer)

    the current pause duration value



48
49
50
# File 'lib/utils/editor.rb', line 48

def pause_duration
  @pause_duration
end

#servernameString

The servername method provides access to the server name attribute.

This method returns the value of the server name instance variable, which represents the name of the server being used.

Returns:

  • (String)

    the server name value



63
64
65
# File 'lib/utils/editor.rb', line 63

def servername
  @servername
end

#waitTrueClass, ... Also known as: wait?

The wait method gets the wait status.

Returns:

  • (TrueClass, FalseClass, nil)

    the wait status value



53
54
55
# File 'lib/utils/editor.rb', line 53

def wait
  @wait
end

Instance Method Details

#activateObject

The activate method switches to the Vim editor window or opens a new one.

This method checks if the Vim default arguments include the ‘-g’ flag to determine whether to open a new buffer in the current window or switch to an existing Vim pane. When the ‘-g’ flag is present, it creates a temporary file and then closes it. Otherwise, it identifies the appropriate tmux pane running an editor process and switches to it.



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/utils/editor.rb', line 305

def activate
  if Array(config.vim_default_args).include?('-g')
    edit_remote("stupid_trick#{rand}")
    sleep pause_duration
    edit_remote_send('<ESC>:bw<CR>')
  else
    pstree = PSTree.new
    switch_to_index =
      `tmux list-panes -F '\#{pane_pid} \#{pane_index}'`.lines.find { |l|
        pid, index = l.split(' ')
        pid = pid.to_i
        if pstree.find { |ps| ps.pid != $$ && ps.ppid == pid && ps.cmd =~ %r(/edit( |$)) }
          break index.to_i
        end
      }
    switch_to_index and system "tmux select-pane -t #{switch_to_index}"
  end
end

#cmd(*parts) ⇒ Boolean

The cmd method constructs a command from parts and executes it.

This method takes multiple arguments, processes them to build a command array, and then executes the command using the system call.

Parameters:

  • parts (Array)

    the parts to be included in the command

Returns:

  • (Boolean)

    true if the command was successful, false otherwise



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/utils/editor.rb', line 100

def cmd(*parts)
  command = parts.compact.inject([]) do |a, p|
    case
    when p == nil, p == []
      a
    when p.respond_to?(:to_ary)
      a.concat p.to_ary
    else
      a << p.to_s
    end
  end
  $DEBUG and warn command * ' '
  system(*command.map(&:to_s))
end

#edit(*filenames) ⇒ Object

The edit method processes filenames to determine their source location and delegates to appropriate editing methods.

If a single filename is provided and it has a source location, the method checks whether the location includes filename and linenumber attributes. If so, it calls edit_source_location with the source location; otherwise, it calls edit_file_linenumber with the source location components. If multiple filenames are provided and all have source locations, the method expands any glob patterns in the filenames, then calls edit_file with the expanded list of filenames. Finally, it ensures the editor is activated after processing.

may contain source location information

Parameters:

  • filenames (Array<String, Integer>)

    an array of filenames that



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/utils/editor.rb', line 179

def edit(*filenames)
  source_location = nil
  if filenames.size == 1 and
    source_location = filenames.first.source_location
  then
    if source_location.respond_to?(:filename) and source_location.respond_to?(:linenumber)
      edit_source_location(source_location)
    else
      edit_file_linenumber(*source_location)
    end
  elsif source_locations = filenames.map(&:source_location).compact.full?
    filenames = expand_globs(source_locations.map(&:first))
    edit_file(*filenames)
  end.tap do
    activate
  end
end

#edit_file(*filenames) ⇒ Object

The edit_file method processes a list of filenames by ensuring their directories exist and then delegates to a remote file editing function.

Parameters:

  • filenames (Array<String>)

    an array of filename strings to be processed



218
219
220
221
# File 'lib/utils/editor.rb', line 218

def edit_file(*filenames)
  make_dirs(*filenames)
  edit_remote_file(*filenames)
end

#edit_file_linenumber(filename, linenumber, rangeend = nil) ⇒ Object

The edit_file_linenumber method opens a file at a specific line number and optionally selects a range of lines in an editor.

opened nil if no range is specified

Parameters:

  • filename (String)

    the path to the file to be opened

  • linenumber (Integer)

    the line number where the file should be

  • rangeend (Integer, nil) (defaults to: nil)

    the ending line number for selection, or



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/utils/editor.rb', line 231

def edit_file_linenumber(filename, linenumber, rangeend = nil)
  make_dirs filename
  if rangeend
    Thread.new do
      while !started?
        sleep 1
      end
      edit_remote_send("<ESC>:normal #{linenumber}GV#{rangeend}G<CR>")
    end
  end
  if wait?
    activate
    edit_remote_wait("+#{linenumber}", filename)
  else
    edit_remote("+#{linenumber}", filename)
  end
end

#edit_remote(*args) ⇒ Object

The edit_remote method executes a remote Vim command with the specified arguments.

This method prepares a command to communicate with a running Vim server instance, allowing for remote execution of Vim commands without directly interacting with the terminal. It ensures the window is renamed before sending the command and constructs the appropriate command line arguments for the Vim server interface.

Parameters:

  • args (Array)

    the arguments to be passed to the remote Vim command



357
358
359
360
# File 'lib/utils/editor.rb', line 357

def edit_remote(*args)
  rename_window
  cmd(*vim, '--servername', servername, '--remote', *args)
end

#edit_remote_file(*filenames) ⇒ Object

The edit_remote_file method delegates to either edit_remote_wait or edit_remote based on the wait? condition.

This method determines whether to execute file editing operations with waiting for completion or without waiting, depending on the result of the wait? check.

Parameters:

  • filenames (Array<String>)

    an array of filenames to be processed



398
399
400
401
402
403
404
# File 'lib/utils/editor.rb', line 398

def edit_remote_file(*filenames)
  if wait?
    edit_remote_wait(*filenames)
  else
    edit_remote(*filenames)
  end
end

#edit_remote_send(*args) ⇒ Object

The edit_remote_send method transmits a sequence of arguments to a remote Vim server for execution.

This method prepares and sends commands to an already running Vim instance identified by its server name, allowing for remote control of the editor session. It ensures the window is properly named before sending the command, and uses the configured Vim executable along with its remote communication flags.

Parameters:

  • args (Array<String>)

    the arguments to be sent to the remote Vim server



385
386
387
388
# File 'lib/utils/editor.rb', line 385

def edit_remote_send(*args)
  rename_window
  cmd(*vim, '--servername', servername, '--remote-send', *args)
end

#edit_remote_wait(*args) ⇒ Object

The edit_remote_wait method executes a command remotely and waits for its completion.

This method sends a command to a remote server using the specified vim server connection, and blocks until the remote operation finishes executing.

Parameters:

  • args (Array)

    the arguments to be passed to the remote command



370
371
372
373
# File 'lib/utils/editor.rb', line 370

def edit_remote_wait(*args)
  rename_window
  cmd(*vim, '--servername', servername, '--remote-wait', *args)
end

#edit_source_location(source_location) ⇒ Object

The edit_source_location method processes a source location object to open the corresponding file at the specified line number.

This method takes a source location object and uses its filename, line number, and optional range end to invoke the edit_file_linenumber method for opening the file in an editor.

containing filename and line number information

Parameters:

  • source_location (Array<String, Integer>)

    the source location



258
259
260
261
262
263
264
# File 'lib/utils/editor.rb', line 258

def edit_source_location(source_location)
  edit_file_linenumber(
    source_location.filename,
    source_location.linenumber,
    source_location.rangeend
  )
end

#expand_globs(filenames) ⇒ Array<String>

The expand_globs method processes an array of filename patterns by expanding glob expressions and returning a sorted array of unique filenames.

include glob expressions

patterns expanded, or the original array if no glob patterns are present

Parameters:

  • filenames (Array<String>)

    an array of filename patterns that may

Returns:

  • (Array<String>)

    a sorted array of unique filenames with glob



161
162
163
# File 'lib/utils/editor.rb', line 161

def expand_globs(filenames)
  filenames.map { |f| Dir[f] }.flatten.uniq.sort.full? || filenames
end

#file_linenumber?(filename) ⇒ MatchData?

The file_linenumber? method checks if a filename matches the file and line number pattern.

This method determines whether the provided filename string conforms to the regular expression pattern used for identifying file paths accompanied by line numbers.

Parameters:

  • filename (String)

    the filename string to be checked

Returns:

  • (MatchData, nil)

    a match data object if the filename matches the pattern, or nil if it does not match



148
149
150
# File 'lib/utils/editor.rb', line 148

def file_linenumber?(filename)
  filename.match(Utils::Xt::SourceLocationExtension::FILE_LINENUMBER_REGEXP)
end

#fullscreen=(enabled) ⇒ Object

The fullscreen= method sets the fullscreen state for the remote editor session.

This method configures the fullscreen mode of the remote editor by sending appropriate commands through the edit_remote_send mechanism. It ensures the editor session is started and paused briefly before applying the fullscreen setting, then activates the session to apply the changes.

disable fullscreen mode

Parameters:

  • enabled (TrueClass, FalseClass)

    determines whether to enable or



126
127
128
129
130
131
132
133
134
135
# File 'lib/utils/editor.rb', line 126

def fullscreen=(enabled)
  start
  sleep pause_duration
  if enabled
    edit_remote_send '<ESC>:set fullscreen<CR>'
  else
    edit_remote_send '<ESC>:set nofullscreen<CR>'
  end
  activate
end

#serverlistArray<String>

The serverlist method retrieves a list of available Vim server names.

This method executes the Vim command to list all active servers and returns the results as an array of server names.

Returns:

  • (Array<String>)

    an array of Vim server names currently available



330
331
332
# File 'lib/utils/editor.rb', line 330

def serverlist
  `#{vim.map(&:inspect) * ' '} --serverlist`.split
end

#startObject

The start method initializes the Vim server connection if it is not already running.

This method first attempts to rename the terminal window to reflect the server name, then checks if the Vim server has already been started. If not, it executes the command to launch the Vim server with the specified server name.



285
286
287
288
# File 'lib/utils/editor.rb', line 285

def start
  rename_window
  started? or cmd(*vim, '--servername', servername)
end

#started?(name = servername) ⇒ TrueClass, FalseClass

The started? method checks whether a server with the given name is currently running.

This method verifies the presence of a server in the list of active servers by checking if the server name exists within the serverlist.

Parameters:

  • name (String) (defaults to: servername)

    the name of the server to check for

Returns:

  • (TrueClass, FalseClass)

    true if the server is running, false otherwise



343
344
345
# File 'lib/utils/editor.rb', line 343

def started?(name = servername)
  serverlist.member?(name)
end

#stopObject

The stop method sends a quit command to the remote editor.

This method checks if the editor is currently running and, if so, sends a quit command to close all windows and terminate the editor session.



294
295
296
# File 'lib/utils/editor.rb', line 294

def stop
  started? and edit_remote_send('<ESC>:qa<CR>')
end

#vimArray<String>

The vim method constructs and returns the Vim command configuration.

This method assembles the Vim command by combining the configured Vim path with any default arguments specified in the configuration.

Returns:

  • (Array<String>)

    an array containing the Vim executable path and its default arguments for command execution



88
89
90
# File 'lib/utils/editor.rb', line 88

def vim
  ([ config.vim_path ] + Array(config.vim_default_args))
end