module Diakonos::Functions

The Diakonos::Functions module contains all the methods that can be mapped to keys in Diakonos. New methods can be added to this module by extensions.

Public Instance Methods

about() click to toggle source

Shows the About page, which gives information on Diakonos.

# File lib/diakonos/functions.rb, line 10
def about
  about_write
  open_file @about_filename
end
addNamedBookmark( name_ = nil )
Alias for: add_named_bookmark
add_named_bookmark( name_ = nil ) click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 4
def add_named_bookmark( name_ = nil )
  if name_.nil?
    name = get_user_input "Bookmark name: "
  else
    name = name_
  end

  if name
    @bookmarks[ name ] = Bookmark.new( buffer_current, buffer_current.current_row, buffer_current.current_column, name )
    set_iline "Added bookmark #{@bookmarks[ name ].to_s}."
  end
end
Also aliased as: addNamedBookmark
anchorSelection()
Alias for: anchor_selection
anchor_selection() click to toggle source

Begins selecting text by anchoring (marking) the start of a selection.

# File lib/diakonos/functions/selection.rb, line 5
def anchor_selection
  buffer_current.anchor_selection
  update_status_line
end
Also aliased as: anchorSelection
anchor_unanchored_selection( *method_and_args ) click to toggle source

Used for “shift+arrow” style selection.

# File lib/diakonos/functions/selection.rb, line 11
def anchor_unanchored_selection( *method_and_args )
  buffer_current.anchor_unanchored_selection
  if method_and_args[0]
    self.send method_and_args[0], *method_and_args[1..-1]
  end
  update_status_line
end
backspace() click to toggle source

Move one character left, then delete one character.

@see Diakonos::Buffer#delete

# File lib/diakonos/functions/basics.rb, line 7
def backspace
  if( buffer_current.changing_selection || cursor_left( Buffer::STILL_TYPING ) )
    delete
  end
end
carriageReturn()
Alias for: carriage_return
carriage_return() click to toggle source

Insert a carriage return (newline) at the current cursor location. Deletes any currently selected text.

# File lib/diakonos/functions/basics.rb, line 15
def carriage_return
  buffer_current.carriage_return
  buffer_current.delete_selection
end
Also aliased as: carriageReturn
changeSessionSetting( key_ = nil, value = nil, do_redraw = DONT_REDRAW )
change_session_setting( key_ = nil, value = nil, do_redraw = DONT_REDRAW ) click to toggle source
# File lib/diakonos/functions/sessions.rb, line 8
def change_session_setting( key_ = nil, value = nil, do_redraw = DONT_REDRAW )
  if key_.nil?
    key = get_user_input( "Setting: " )
  else
    key = key_
  end

  if key
    if value.nil?
      value = get_user_input( "Value: " )
    end
    case @settings[ key ]
    when String
      value = value.to_s
    when Integer
      value = value.to_i
    when TrueClass, FalseClass
      value = value.to_b
    end
    @session.settings[ key ] = value
    merge_session_settings
    redraw  if do_redraw
    set_iline "#{key} = #{value}"
  end
end
Also aliased as: changeSessionSetting
chdir( dir = nil ) click to toggle source

Change the current working directory (CWD) of the Diakonos process. @param [String] dir The directory to change to

# File lib/diakonos/functions/shell.rb, line 6
def chdir( dir = nil )
  dir ||= get_user_input( "Change to directory: ", initial_text: Dir.pwd )
  if dir
    Dir.chdir dir
  end
end
clearMatches()
Alias for: clear_matches
clear_matches() click to toggle source

Removes the highlighting from any text that matches the most recent search.

# File lib/diakonos/functions/selection.rb, line 21
def clear_matches
  buffer_current.clear_matches Buffer::DO_DISPLAY
end
Also aliased as: clearMatches
closeFile( buffer = buffer_current, opts = {} )
Alias for: close_buffer
close_buffer( buffer = buffer_current, opts = {} ) click to toggle source

Closes a buffer.

@param [Diakonos::Buffer] buffer

The buffer to close.  If no buffer is provided, defaults to the current buffer.

@option opts [Integer] :to_all

The CHOICE to assume for the prompt.

@option opts [Boolean] :do_display

Whether or not to update the display after closure

@return [Integer] the choice the user made, or nil if the user was not prompted to choose. @see Diakonos::CHOICE_YES @see Diakonos::CHOICE_NO

# File lib/diakonos/functions/buffers.rb, line 15
  def close_buffer( buffer = buffer_current, opts = {} )
    return nil  if buffer.nil?

    to_all = opts[:to_all]
    do_display = opts.fetch( :do_display, true )

    choice = nil
    if ! @buffers.include?( buffer )
      log "No such buffer: #{buffer.name}"
      return nil
    end

    do_closure = true

    if buffer.modified? && ! buffer.read_only
      if to_all
        choice = to_all
      else
        choices = [ CHOICE_YES, CHOICE_NO, CHOICE_CANCEL ]
        if @quitting
          choices.concat [ CHOICE_YES_TO_ALL, CHOICE_NO_TO_ALL ]
        end
        choice = get_choice(
          "Save changes to #{buffer.nice_name}?",
          choices,
          CHOICE_CANCEL
        )
      end

      case choice
      when CHOICE_YES, CHOICE_YES_TO_ALL
        do_closure = true
        save_file buffer
      when CHOICE_NO, CHOICE_NO_TO_ALL
        do_closure = true
      when CHOICE_CANCEL
        do_closure = false
      end
    end

    if do_closure
      del_buffer = nil
      previous_buffer = nil
      to_switch_to = nil
      switching = false

      # Search the buffer hash for the buffer we want to delete,
      # and mark the one we will switch to after deletion.
      @buffers.each do |b|
        if switching
          to_switch_to = b
          break
        end

        if b == buffer
          del_buffer = b
          switching = true
          next
        end

        previous_buffer = b
      end

      buf = nil
      while(
        @buffer_stack.any? &&
        ! @buffers.include?( buf ) ||
        buf == del_buffer
      ) do
        buf = @buffer_stack.pop
      end
      if @buffers.include?( buf )
        to_switch_to = buf
      end

      if to_switch_to
        switch_to  to_switch_to, do_display: do_display
      elsif previous_buffer
        switch_to  previous_buffer, do_display: do_display
      end

      @buffer_closed = del_buffer
      @buffers.delete del_buffer
      cursor_stack_remove_buffer del_buffer

      if @buffer_stack.empty?
        # No buffers left.  Open a new blank one.
        open_file
      end

      save_session

      update_status_line
      update_context_line
    end

    choice
  end

  # Opens the special "buffer selection" buffer, and prompts the user
  # to select a buffer.  The user can select a buffer either with the
  # arrow keys and the Enter key, or by pressing the key corresponding
  # to an index presented in a left-hand column in the list.
  def list_buffers
    bullets = ( ('0'..'9').to_a + ('a'..'z').to_a ).map { |s| "#{s}  " }
    buffers_unnamed = @buffers.find_all { |b| b.name.nil? }
    buffers_named = @buffers.find_all { |b| b.name }

    with_list_file do |f|
      if buffers_unnamed.size == 1
        bullet = bullets.shift
        f.puts "#{bullet}(unnamed buffer)"
      else
        buffers_unnamed.each_with_index do |b,i|
          bullet = bullets.shift
          f.puts "#{bullet}(unnamed buffer #{i+1})"
        end
      end

      buffers_named.collect { |b| b.name }.sort.each_with_index do |name, index|
        bullet = bullets.shift
        f.puts "#{bullet}#{name}"
      end
    end
    open_list_buffer
    filename = get_user_input( "Switch to buffer: ", numbered_list: true )
    buffer = buffers_named.find { |b| b.name == filename }
    if buffer
      switch_to buffer
    elsif filename =~ /\(unnamed buffer( \d+)?/
      switch_to( buffers_unnamed[ $1.to_i - 1 ] )
    end
  end

  # Opens a file into a new Buffer.
  # @param filename
  #   The file to open.  If nil, an empty, unnamed buffer is opened.
  # @param [Hash] meta
  #   metadata containing additional information on how to open the file
  # @option meta [Hash] 'cursor' (nil)
  #   A Hash containing the 'row' and 'col' to position the cursor after opening.
  # @option meta [Hash] 'display' (nil)
  #   A Hash containing the 'top_line' and 'left_column' to use to position
  #   the view after opening.
  # @option meta [Boolean] 'read_only' (false)
  #   Whether to open the file in read-only (unmodifiable) mode
  # @option meta [Boolean] 'revert' (false)
  #   Whether to skip asking about reverting to on-disk file contents (if different)
  # @return [Buffer] the buffer of the opened file
  # @return [NilClass] nil on failure
  def open_file( filename = nil, meta = {} )
    read_only    = !!meta[ 'read_only' ]
    force_revert = meta[ 'revert' ] || ASK_REVERT
    if meta[ 'cursor' ]
      last_row = meta[ 'cursor' ][ 'row' ]
      last_col = meta[ 'cursor' ][ 'col' ]
    end
    if meta[ 'display' ]
      top_line    = meta[ 'display' ][ 'top_line' ]
      left_column = meta[ 'display' ][ 'left_column' ]
    end

    do_open = true
    buffer = nil
    if filename
      filename, last_row_ = ::Diakonos.parse_filename_and_line_number( filename )
      last_row = last_row_ || last_row
      if filename =~ /\(unnamed buffer (\d+)\)/
        existing_buffer = @buffers.find { |b| b.object_id == $1.to_i }
        filename = nil
        do_open = false
      else
        existing_buffer = @buffers.find { |b| b.name == filename }
      end

      if filename
        if existing_buffer
          do_open = force_revert || ( filename =~ /\.diakonos/ )
          switch_to  existing_buffer, do_display: false

          if ! do_open && existing_buffer.file_different?
            show_buffer_file_diff( existing_buffer ) do
              choice = get_choice(
                "Load on-disk version of #{existing_buffer.nice_name}?",
                [ CHOICE_YES, CHOICE_NO ]
              )
              case choice
              when CHOICE_YES
                do_open = true
              when CHOICE_NO
                do_open = false
              end
            end
          end
        end

        if FileTest.exist?( filename )
          # Don't try to open non-files (i.e. directories, pipes, sockets, etc.)
          do_open &&= FileTest.file?( filename )
        end
      end
    end

    if do_open
      # Is file readable?

      # Does the "file" utility exist?
      if(
        filename &&
        @settings[ 'use_magic_file' ] &&
        FileTest.exist?( "/usr/bin/file" ) &&
        FileTest.exist?( filename ) &&
        /\blisting\.txt\b/ !~ filename
      )
        file_type = `/usr/bin/file -L #{filename}`
        if file_type !~ /text/ && file_type !~ /empty$/
          choice = get_choice(
            "#{filename} does not appear to be readable.  Try to open it anyway?",
            [ CHOICE_YES, CHOICE_NO ],
            CHOICE_NO
          )
          case choice
          when CHOICE_NO
            do_open = false
          end

        end
      end

      if do_open
        buffer = Buffer.new(
          'filepath' => filename,
          'read_only' => read_only,
          'display' => {
            'top_line' => top_line,
            'left_column' => left_column,
          },
          'cursor' => {
            'row' => last_row,
            'col' => last_col,
          }
        )
        if existing_buffer
          @buffers[ @buffers.index( existing_buffer ) ] = buffer
        else
          if @settings['open_as_first_buffer']
            @buffers.unshift buffer
          else
            @buffers << buffer
          end
        end
        run_hook_procs( :after_open, buffer )
        save_session
        if switch_to( buffer, do_display: false )
          if last_row
            buffer.cursor_to last_row, last_col || 0, Buffer::DONT_DISPLAY
          end
          display_buffer buffer
        end
      end
    elsif existing_buffer
      if switch_to( existing_buffer, do_display: false )
        if last_row
          existing_buffer.cursor_to last_row, last_col || 0, Buffer::DONT_DISPLAY
        end
        display_buffer existing_buffer
      end
    end

    buffer || existing_buffer
  end
  alias_method :new_file, :open_file

  # Prompts the user for a file to open, then opens it with #open_file .
  # @see #open_file
  def open_file_ask
    prefill = ''

    if buffer_current
      if buffer_current.current_line =~ %r#(/\w+)+/\w+\.\w+#
        prefill = $&
      elsif buffer_current.name
        prefill = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
      end
    end

    if @settings[ 'fuzzy_file_find' ]
      prefill = ''
      finder = FuzzyFileFinder.new(
        directories: @session.dir,
        ceiling: @settings['fuzzy_file_find.max_files'] || 8192,
        ignores: @fuzzy_ignores,
        recursive: @settings['fuzzy_file_find.recursive']
      )

      finder_block = lambda { |input|
        break  if input =~ %r{^/}

        matches = finder.find(input).sort_by { |m| m[:path] }
        with_list_file do |list|
          list.puts matches.map { |m| m[:path] }
        end
        open_list_buffer
      }
    end

    file = get_user_input(
      "Filename: ",
      history: @rlh_files,
      initial_text: prefill,
      &finder_block
    )

    if file && ! file.empty?
      open_file file
      update_status_line
      update_context_line
    end
  end

  # Opens all files within a directory whose contents match a regular
  # expression.
  # @param regexp [String]
  #   The regular expression used to match against.  If nil, the user is
  #   prompted for a value.
  # @param search_root [String]
  #   The directory under which to recursively search for matches.  If nil,
  #   the user is prompted for a value.
  def open_matching_files( regexp = nil, search_root = nil )
    regexp ||= get_user_input( "Regexp: ", history: @rlh_search )
    return  if regexp.nil?

    if buffer_current.current_line =~ %r{\w*/[/\w.]+}
      prefill = $&
    else
      prefill = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
    end
    search_root ||= get_user_input( "Search within: ", history: @rlh_files, initial_text: prefill )
    return  if search_root.nil?

    files = `egrep -rl '#{regexp.gsub( /'/, "'\\\\''" )}' #{search_root}/*`.split( /\n/ )
    if files.any?
      if files.size > 5
          choice = get_choice( "Open #{files.size} files?", [ CHOICE_YES, CHOICE_NO ] )
          return  if choice == CHOICE_NO
      end
      files.each do |f|
        open_file f
      end
      find regexp, direction: :down, case_sensitive: true
    end
  end

  # Places a buffer at a new position in the array of Buffers
  # after shifting down (index+1) all existing Buffers from that position onwards.
  # @param to [Integer] The new 1-based position of the buffer to move
  # @param from [Integer] The original 1-based position of the buffer to move.  Default: current buffer
  def renumber_buffer( to, from = nil )
    if to < 1
      raise "Invalid buffer index: #{to.inspect}"
    end
    if from && from < 1
      raise "Invalid buffer index: #{from.inspect}"
    end

    from ||= buffer_to_number( buffer_current )
    from_ = from - 1
    to_   = to - 1
    b = @buffers[from_]
    @buffers.delete_at from_
    @buffers.insert( to_, b )
    @buffers.compact!

    update_status_line
  end

  # If the prompt is non-nil, ask the user yes or no question first.
  def revert( prompt = nil )
    do_revert = true

    if prompt
      show_buffer_file_diff do
        choice = get_choice(
          prompt,
          [ CHOICE_YES, CHOICE_NO ]
        )
        case choice
        when CHOICE_NO
          do_revert = false
        end
      end
    end

    if do_revert
      open_file(
        buffer_current.name,
        'read_only' => false,
        'revert' => FORCE_REVERT,
        'cursor' => {
          'row' => buffer_current.last_row,
          'col' => buffer_current.last_col
        }
      )
    end
  end

  # Saves a buffer, then runs the :after_save hook on it.
  # @param [Buffer] buffer
  #   The buffer to save.  If nil, defaults to the current buffer.
  def save_file( buffer = buffer_current )
    buffer.save
    run_hook_procs( :after_save, buffer )
  end

  def save_file_as
    if buffer_current && buffer_current.name
      path = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
      file = get_user_input( "Filename: ", history: @rlh_files, initial_text: path )
    else
      file = get_user_input( "Filename: ", history: @rlh_files )
    end
    if file
      old_name = buffer_current.name
      if buffer_current.save( file, PROMPT_OVERWRITE )
        save_session
      end
    end
  end

  # Sets the type (language) of the current buffer.
  # @param [String] type_
  #   The type to set the current buffer to.
  #   If nil, the user is prompted for a value.
  def set_buffer_type( type_ = nil )
    type = type_ || get_user_input( "Content type: " )

    if type
      if buffer_current.set_type( type )
        update_status_line
        update_context_line
      end
    end
  end

  # If read_only is nil, the read_only state of the current buffer is toggled.
  # Otherwise, the read_only state of the current buffer is set to read_only.
  def set_read_only( read_only = nil )
    if read_only
      buffer_current.read_only = read_only
    else
      buffer_current.read_only = ( ! buffer_current.read_only )
    end
    update_status_line
  end

  def switch_to_buffer_number( buffer_number_ )
    buffer_number = buffer_number_.to_i
    return  if buffer_number < 1
    if @buffer_number_last && buffer_number == buffer_to_number(buffer_current)
      buffer_number = @buffer_number_last
    end
    @buffer_number_last = buffer_to_number(buffer_current)
    switch_to @buffers[ buffer_number - 1 ]
  end

  def switch_to_next_buffer
    switch_to_buffer_number( buffer_to_number( buffer_current ) + 1 )
  end

  def switch_to_previous_buffer
    switch_to_buffer_number( buffer_to_number( buffer_current ) - 1 )
  end

end
Also aliased as: closeFile, close_file
close_code() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 6
def close_code
  buffer_current.close_code
end
close_file( buffer = buffer_current, opts = {} )
Alias for: close_buffer
collapseWhitespace()
Alias for: collapse_whitespace
collapse_whitespace() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 10
def collapse_whitespace
  buffer_current.collapse_whitespace
end
Also aliased as: collapseWhitespace
columnize( delimiter = nil, num_spaces_padding = 0 ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 15
def columnize( delimiter = nil, num_spaces_padding = 0 )
  delimiter ||= get_user_input(
    "Column delimiter (regexp): ",
    history: @rlh_general,
    initial_text: @settings[ "lang.#{buffer_current.original_language}.column_delimiters" ] || ''
  )
  if delimiter && num_spaces_padding
    buffer_current.columnize Regexp.new( delimiter ), num_spaces_padding
  end
end
comment_out() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 26
def comment_out
  buffer_current.comment_out
end
complete_word( direction = :down ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 30
def complete_word( direction = :down )
  b = buffer_current
  if b.selecting?
    old_word = b.word_before_cursor
    b.delete_selection
  end
  partial = b.word_before_cursor
  return  if partial.nil?

  all_words = @buffers.find_all { |b_|
    b_.original_language == b.original_language
  }.collect { |b_|
    b_.words( /^#{Regexp.escape(partial)}./ )
  }.flatten
  if all_words.any?
    words = all_words.uniq.sort
    if old_word
      i = (
        ( direction == :up ? words.size - 1 : 1 ) +
        words.find_index { |w|
          w == old_word
        }
      ) % words.size
    else
      freq_word = words.sort_by { |word|
        all_words.find_all { |w| w == word }.size
      }[ -1 ]
      i = words.find_index { |w| w == freq_word }
    end
    word = words[ i ]
    b.insert_string word[ partial.length..-1 ]
    r, c = b.last_row, b.last_col
    b.cursor_to( b.last_row, b.last_col + word.length - partial.length )
    b.set_selection( r, c, r, c + word.length - partial.length )
    n = words.size
    middle_word = words[ i ].center( Curses::cols / 4, ' ' )
    shown_words = [
      words[ ( n+i-2 ) % n ],
      words[ ( n+i-1 ) % n ],
      middle_word,
      words[ ( n+i+1 ) % n ],
      words[ ( n+i+2 ) % n ],
    ].compact.uniq.reject { |w| w == middle_word.strip }.join( ' ' )
    mi = shown_words.index( middle_word )
    padding = " " * ( Curses::cols / 2 - mi - ( middle_word.length / 2 ) )
    set_iline padding + shown_words
  end
end
copySelection()
Alias for: copy_selection
copy_selection() click to toggle source

Copies the currently selected text to clipboard then unselects.

# File lib/diakonos/functions/clipboard.rb, line 5
def copy_selection
  @clipboard.add_clip buffer_current.copy_selection
  remove_selection
end
Also aliased as: copySelection
cursorBOF()
Alias for: cursor_bof
cursorBOL()
Alias for: cursor_bol
cursorBOV()
Alias for: cursor_bov
cursorDown()
Alias for: cursor_down
cursorEOF()
Alias for: cursor_eof
cursorEOL()
Alias for: cursor_eol
cursorLeft( stopped_typing = Buffer::STOPPED_TYPING )
Alias for: cursor_left
cursorReturn( direction = :backward, different_file = NOT_DIFFERENT_FILE )
Alias for: cursor_return
cursorRight( stopped_typing = Buffer::STOPPED_TYPING, amount = 1 )
Alias for: cursor_right
cursorTOV()
Alias for: cursor_tov
cursorUp()
Alias for: cursor_up
cursor_bof() click to toggle source

Moves the cursor to the beginning of the current buffer. @return [true,false] true iff the cursor changed positions

# File lib/diakonos/functions/cursor.rb, line 110
def cursor_bof
  buffer_current.cursor_to( 0, 0, Buffer::DO_DISPLAY )
end
Also aliased as: cursorBOF
cursor_bol() click to toggle source

Moves the cursor to the beginning of the current line.

# File lib/diakonos/functions/cursor.rb, line 115
def cursor_bol
  buffer_current.cursor_to_bol
end
Also aliased as: cursorBOL
cursor_bov() click to toggle source

Moves the cursor to the bottom of the viewport of the current buffer.

# File lib/diakonos/functions/cursor.rb, line 135
def cursor_bov
  buffer_current.cursor_to_bov
end
Also aliased as: cursorBOV
cursor_down() click to toggle source

@return [true,false] true iff the cursor changed positions

# File lib/diakonos/functions/cursor.rb, line 11
def cursor_down
  buffer_current.cursor_to(
    buffer_current.last_row + 1,
    buffer_current.last_col,
    Buffer::DO_DISPLAY,
    Buffer::STOPPED_TYPING,
    DONT_ADJUST_ROW
  )
end
Also aliased as: cursorDown
cursor_eof() click to toggle source

Moves the cursor to the end of the current buffer.

# File lib/diakonos/functions/cursor.rb, line 125
def cursor_eof
  buffer_current.cursor_to_eof
end
Also aliased as: cursorEOF
cursor_eol() click to toggle source

Moves the cursor to the end of the current line.

# File lib/diakonos/functions/cursor.rb, line 120
def cursor_eol
  buffer_current.cursor_to_eol
end
Also aliased as: cursorEOL
cursor_left( stopped_typing = Buffer::STOPPED_TYPING ) click to toggle source

@return [true,false] true iff the cursor changed positions

# File lib/diakonos/functions/cursor.rb, line 22
def cursor_left( stopped_typing = Buffer::STOPPED_TYPING )
  buffer_current.cursor_to(
    buffer_current.last_row,
    buffer_current.last_col - 1,
    Buffer::DO_DISPLAY,
    stopped_typing
  )
end
Also aliased as: cursorLeft
cursor_return( direction = :backward, different_file = NOT_DIFFERENT_FILE ) click to toggle source

Pops the cursor stack. @param [Symbol] direction

Either :backward (default) or :forward.

@param [Boolean] different_file

Whether to pop just one frame (default), or many frames until a different file is reached.

@see Diakonos::DIFFERENT_FILE @see Diakonos::NOT_DIFFERENT_FILE

# File lib/diakonos/functions/cursor.rb, line 38
def cursor_return( direction = :backward, different_file = NOT_DIFFERENT_FILE )
  delta = 0
  if @cursor_stack_pointer.nil?
    push_cursor_state(
      buffer_current.top_line,
      buffer_current.last_row,
      buffer_current.last_col,
      DONT_CLEAR_STACK_POINTER
    )
    delta = 1
  end

  orig_ptr = @cursor_stack_pointer
  case direction
  when :backward
    @cursor_stack_pointer = ( @cursor_stack_pointer || @cursor_stack.length ) - 1 - delta
    while different_file && @cursor_stack[ @cursor_stack_pointer ] && @cursor_stack[ @cursor_stack_pointer ][ :buffer ] == buffer_current
      @cursor_stack_pointer -= 1
    end
  when :forward
    @cursor_stack_pointer = ( @cursor_stack_pointer || 0 ) + 1
    while different_file && @cursor_stack[ @cursor_stack_pointer ] && @cursor_stack[ @cursor_stack_pointer ][ :buffer ] == buffer_current
      @cursor_stack_pointer += 1
    end
  end
  if @cursor_stack[ @cursor_stack_pointer ].nil? && orig_ptr
    @cursor_stack_pointer = orig_ptr
  end

  return_pointer = @cursor_stack_pointer

  if @cursor_stack_pointer < 0
    return_pointer = @cursor_stack_pointer = 0
  elsif @cursor_stack_pointer >= @cursor_stack.length
    return_pointer = @cursor_stack_pointer = @cursor_stack.length - 1
  else
    cursor_state = @cursor_stack[ @cursor_stack_pointer ]
    if cursor_state
      buffer = cursor_state[ :buffer ]
      switch_to buffer
      buffer.pitch_view( cursor_state[ :top_line ] - buffer.top_line, Buffer::DONT_PITCH_CURSOR, Buffer::DO_DISPLAY )
      buffer.cursor_to( cursor_state[ :row ], cursor_state[ :col ] )
      update_status_line
    end
  end

  set_iline "Location: #{return_pointer+1}/#{@cursor_stack.size}"
end
Also aliased as: cursorReturn
cursor_right( stopped_typing = Buffer::STOPPED_TYPING, amount = 1 ) click to toggle source

@return [true,false] true iff the cursor changed positions

# File lib/diakonos/functions/cursor.rb, line 88
def cursor_right( stopped_typing = Buffer::STOPPED_TYPING, amount = 1 )
  buffer_current.cursor_to(
    buffer_current.last_row,
    buffer_current.last_col + amount,
    Buffer::DO_DISPLAY,
    stopped_typing
  )
end
Also aliased as: cursorRight
cursor_tov() click to toggle source

Moves the cursor to the top of the viewport of the current buffer.

# File lib/diakonos/functions/cursor.rb, line 130
def cursor_tov
  buffer_current.cursor_to_tov
end
Also aliased as: cursorTOV
cursor_up() click to toggle source

@return [true,false] true iff the cursor changed positions

# File lib/diakonos/functions/cursor.rb, line 98
def cursor_up
  buffer_current.cursor_to(
    buffer_current.last_row - 1,
    buffer_current.last_col,
    Buffer::DO_DISPLAY,
    Buffer::STOPPED_TYPING,
    DONT_ADJUST_ROW
  )
end
Also aliased as: cursorUp
cutSelection()
Alias for: cut_selection
cut_selection() click to toggle source

Copies the currently selected text to clipboard, then deletes it.

# File lib/diakonos/functions/clipboard.rb, line 11
def cut_selection
  if @clipboard.add_clip( buffer_current.copy_selection )
    delete
  end
end
Also aliased as: cutSelection
delete() click to toggle source

Calls Buffer#delete on the current buffer.

# File lib/diakonos/functions/basics.rb, line 21
def delete
  buffer_current.delete
end
deleteAndStoreLine()
deleteLine()
Alias for: delete_line
deleteToEOL()
Alias for: delete_to_eol
delete_and_store_line() click to toggle source

Deletes the current line, and adds it to the clipboard. If the previous command was also delete_and_store_line, append the line to the previous clip instead of making a new clip.

# File lib/diakonos/functions/clipboard.rb, line 21
def delete_and_store_line
  removed_text = buffer_current.delete_line
  if removed_text
    clip = [ removed_text, "" ]
    if @functions_last[ -1 ] =~ /^delete_and_store_line/
      @clipboard.append_to_clip clip
    else
      @clipboard.add_clip clip
    end
  end
end
Also aliased as: deleteAndStoreLine
delete_from( char = nil ) click to toggle source

Deletes characters starting from (but not including) a given character up to (but not including) the current cursor position. Also puts the deleted text into the clipboard.

# File lib/diakonos/functions.rb, line 36
def delete_from( char = nil )
  if char.nil?
    set_iline "Type character to delete from..."
    char = @win_main.getch
    set_iline
  end
  if char
    removed_text = buffer_current.delete_from(char)
    if removed_text
      @clipboard.add_clip removed_text
    else
      set_iline "'#{char}' not found."
    end
  end
end
delete_line() click to toggle source

Deletes the current line and adds it to the clipboard.

# File lib/diakonos/functions/basics.rb, line 26
def delete_line
  removed_text = buffer_current.delete_line
  if removed_text
    @clipboard.add_clip( [ removed_text, "" ] )
  end
end
Also aliased as: deleteLine
delete_to( char = nil ) click to toggle source

Deletes characters up to, but not including, a given character. Also puts the deleted text into the clipboard.

# File lib/diakonos/functions.rb, line 17
def delete_to( char = nil )
  if char.nil?
    set_iline "Type character to delete to..."
    char = @win_main.getch
    set_iline
  end
  if char
    removed_text = buffer_current.delete_to char
    if removed_text
      @clipboard.add_clip removed_text
    else
      set_iline "'#{char}' not found."
    end
  end
end
delete_to_and_from( inclusive = nil, char = nil ) click to toggle source

Deletes characters between, but not including, a given pair of characters. Also puts the deleted text into the clipboard. Brace characters are intelligently matched with their opposite-side counterparts if the left-side brace is given (e.g. ‘[’).

# File lib/diakonos/functions.rb, line 56
def delete_to_and_from( inclusive = nil, char = nil )
  if char.nil?
    set_iline "Type character to delete to and from..."
    char = @win_main.getch
    set_iline
  end
  if char
    removed_text = buffer_current.delete_to_and_from(
      char,
      inclusive == :inclusive ? INCLUSIVE : NOT_INCLUSIVE
    )
    if removed_text
      @clipboard.add_clip( [ removed_text ] )
    else
      set_iline "'#{char}' not found."
    end
  end
end
delete_to_eol() click to toggle source

Deletes the text from the current cursor position to the end of the line, then adds the deleted text to the clipboard.

# File lib/diakonos/functions/clipboard.rb, line 35
def delete_to_eol
  removed_text = buffer_current.delete_to_eol
  if removed_text
    @clipboard.add_clip removed_text
  end
end
Also aliased as: deleteToEOL
evaluate( code_ = nil ) click to toggle source

Evaluates (executes) Ruby code.

# File lib/diakonos/functions.rb, line 76
def evaluate( code_ = nil )
  if code_.nil?
    if buffer_current.changing_selection
      selected_text = buffer_current.copy_selection[ 0 ]
    end
    code = get_user_input(
      "Ruby code: ",
      history: @rlh_general,
      initial_text: selected_text || "",
      completion_array: ::Diakonos::Functions.public_instance_methods.map { |m| m.to_s }
    )
  else
    code = code_
  end

  if code
    begin
      eval code
    rescue Exception => e
      show_exception(
        e,
        [
          "The code given to evaluate has a syntax error.",
          "The code given to evaluate refers to a Diakonos command which does not exist, or is misspelled.",
          "The code given to evaluate refers to a Diakonos command with missing arguments.",
          "The code given to evaluate refers to a variable or method which does not exist.",
        ]
      )
    end
  end
end
execute( command_ = nil ) click to toggle source

Executes a command in a shell, and displays the exit code. Results of the shell command are discarded. Substitutes Diakonos shell variables. Interaction with Diakonos is not possible while the shell is running. For asynchronous shelling, use spawn. The execute function allows interaction with shell programs that accept keyboard interaction.

@param [String] command_

The shell command to execute

@see sub_shell_variables @see shell @see spawn @see paste_shell_result

# File lib/diakonos/functions/shell.rb, line 166
def execute( command_ = nil )
  command = command_ || get_user_input( "Command: ", history: @rlh_shell )

  return  if command.nil?

  command = sub_shell_variables( command )

  Curses::close_screen

  success = system( command )
  if ! success
    result = "Could not execute: #{command}"
  else
    result = "Exit code: #{$?}"
  end

  Curses::init_screen
  refresh_all

  set_iline result
end
find( regexp_source_ = nil, options = {} ) click to toggle source

Searches for matches of a regular expression in the current buffer. @param [String] regexp_source_

The regular expression to search for.

@param [Hash] options

Options that alter how the search is performed

@option options [Symbol] :direction (:down)

The direction to search; :down or :up.

@option options [Boolean] :case_sensitive (false)

Whether or not the search should be case_sensitive.

@option options [String] replacement

If provided, do a find and replace, and replace matches with replacement.

@option options [Boolean] :word_only (false)

Whether or not to search with word boundaries

@see find_exact @see find_again @see find_clip

# File lib/diakonos/functions/search.rb, line 20
def find( regexp_source_ = nil, options = {} )
  direction = options[:direction] || :down
  case_sensitive = options[:case_sensitive]
  replacement = options[:replacement]
  word_only = options[:word_only]

  if regexp_source_
    regexp_source = regexp_source_
  else
    buffer_current.clear_search_area
    m = buffer_current.selection_mark
    if m
      if m.start_row != m.end_row
        buffer_current.set_search_area buffer_current.selection_mark
        buffer_current.remove_selection
      else
        selected_text = buffer_current.copy_selection[ 0 ]
      end
    end
    starting_row, starting_col = buffer_current.last_row, buffer_current.last_col

    regexp_source = get_user_input(
      "Search regexp: ",
      history: @rlh_search,
      initial_text: selected_text || ""
    ) { |input|
      if input.length > 1
        regexp_source = word_only ? "\\b#{input}\\b" : input
        find_(
          direction: direction,
          case_sensitive: case_sensitive,
          regexp_source: regexp_source,
          starting_row: starting_row,
          starting_col: starting_col,
          quiet: true
        )
      else
        buffer_current.remove_selection Buffer::DONT_DISPLAY
        buffer_current.clear_matches Buffer::DO_DISPLAY
      end
    }
  end

  if regexp_source
    if word_only
      regexp_source = "\\b#{regexp_source}\\b"
    end
    num_replacements = find_(
      direction: direction,
      case_sensitive: case_sensitive,
      regexp_source: regexp_source,
      replacement: replacement,
      starting_row: starting_row,
      starting_col: starting_col,
      quiet: false
    )
    show_number_of_matches_found( replacement ? num_replacements : nil )
  elsif starting_row && starting_col
    buffer_current.clear_matches
    if @settings[ 'find.return_on_abort' ]
      buffer_current.cursor_to starting_row, starting_col, Buffer::DO_DISPLAY
    end
  end
end
findAgain( direction = :down )
Alias for: find_again
findAndReplace( case_sensitive = CASE_INSENSITIVE )
Alias for: search_and_replace
findExact( direction = :down, search_term_ = nil )
Alias for: find_exact
find_again( direction = :down ) click to toggle source

Search again for the most recently sought search term. @param [String] direction

The direction to search; :down or :up.

@see find @see find_exact

# File lib/diakonos/functions/search.rb, line 102
def find_again( direction = :down )
  if direction
    buffer_current.find_again( @last_search_regexps, direction )
  else
    buffer_current.find_again( @last_search_regexps )
  end
  show_number_of_matches_found
end
Also aliased as: findAgain
find_and_replace( case_sensitive = CASE_INSENSITIVE )
Alias for: search_and_replace
find_clip( direction = :down, case_sensitive = CASE_INSENSITIVE ) click to toggle source

Searches for matches of the latest clipboard item in the current buffer. Note that the clipboard item is interpreted as a regular expression. Only the last line of multi-line clipboard items is used. @param [String] direction

The direction to search.  :down (default) or :up.

@param [Boolean] case_sensitive

Whether or not the search should be case_sensitive.  Default is insensitive.

@see find

# File lib/diakonos/functions/search.rb, line 93
def find_clip( direction = :down, case_sensitive = CASE_INSENSITIVE )
  find @clipboard.clip[-1], direction: direction, case_sensitive: case_sensitive
end
find_exact( direction = :down, search_term_ = nil ) click to toggle source

Search for an exact string (not a regular expression). @param [Symbol] direction

The direction to search; :down (default) or :up.

@param [String] search_term_

The thing to search for.

@see find @see find_again

# File lib/diakonos/functions/search.rb, line 118
def find_exact( direction = :down, search_term_ = nil )
  buffer_current.clear_search_area
  if search_term_.nil?
    if buffer_current.changing_selection
      selected_text = buffer_current.copy_selection[ 0 ]
    end
    search_term = get_user_input(
      "Search for: ",
      history: @rlh_search,
      initial_text: selected_text || ""
    )
  else
    search_term = search_term_
  end
  if search_term
    regexp = [ Regexp.new( Regexp.escape( search_term ) ) ]
    buffer_current.find( regexp, :direction => direction )
    @last_search_regexps = regexp
  end
end
Also aliased as: findExact
goToLineAsk()
Alias for: go_to_line_ask
goToNamedBookmark( name_ = nil )
goToNextBookmark()
Alias for: go_to_next_bookmark
goToPreviousBookmark()
goToTag( tag_ = nil )
Alias for: go_to_tag
goToTagUnderCursor()
go_block_inner() click to toggle source

Moves the cursor to the beginning of the first child code block.

# File lib/diakonos/functions/cursor.rb, line 144
def go_block_inner
  buffer_current.go_block_inner
end
go_block_next() click to toggle source

Moves the cursor to the beginning of the next code block at the same indentation level as the current one.

# File lib/diakonos/functions/cursor.rb, line 149
def go_block_next
  buffer_current.go_block_next
end
go_block_outer() click to toggle source

Moves the cursor to the beginning of the parent code block.

# File lib/diakonos/functions/cursor.rb, line 140
def go_block_outer
  buffer_current.go_block_outer
end
go_block_previous() click to toggle source

Moves the cursor to the beginning of the previous code block at the same indentation level as the current one.

# File lib/diakonos/functions/cursor.rb, line 154
def go_block_previous
  buffer_current.go_block_previous
end
go_to_char( after = nil, char = nil ) click to toggle source

Moves the cursor to the next occurrence of the given character. @param [String] char The character to go to

# File lib/diakonos/functions/cursor.rb, line 160
def go_to_char( after = nil, char = nil )
  char ||= @interaction_handler.get_char( "Type character to go to..." )

  if char
    begin
      moved = buffer_current.go_to_char( char, after == :after ? AFTER_CHAR : ON_CHAR )
      if ! moved
        set_iline "'#{char}' not found."
      end
    rescue TypeError
      # User pressed Esc, or Ctrl-C, or similar.
      # Quietly continue.
    end
  end
end
go_to_char_previous( after = nil, char = nil ) click to toggle source

Moves the cursor to the closest previous occurrence of the given character. @param [String] char The character to go to

# File lib/diakonos/functions/cursor.rb, line 178
def go_to_char_previous( after = nil, char = nil )
  char ||= @interaction_handler.get_char( "Type character to go to..." )

  if char
    begin
      moved = buffer_current.go_to_char_previous( char, after == :after ? AFTER_CHAR : ON_CHAR )
      if ! moved
        set_iline "'#{char}' not found."
      end
    rescue TypeError
      # User pressed Esc, or Ctrl-C, or similar.
      # Quietly continue.
    end
  end
end
go_to_line_ask() click to toggle source

Prompts the user for a line number or line delta, with optional column number. Moves the cursor there.

# File lib/diakonos/functions/cursor.rb, line 196
def go_to_line_ask
  input = get_user_input( "Go to [line number|+lines][,column number]: " )
  if input
    row = nil
    col = 0

    if input =~ /([+-]\d+)/
      row = buffer_current.last_row + $1.to_i
      col = buffer_current.last_col
    else
      input = input.split( /\D+/ ).collect { |n| n.to_i }
      if input.size > 0
        if input[ 0 ] == 0
          row = nil
        else
          row = input[ 0 ] - 1
        end
        if input[ 1 ]
          col = input[ 1 ] - 1
        end
      end
    end

    if row
      buffer_current.go_to_line( row, col )
    end
  end
end
Also aliased as: goToLineAsk
go_to_named_bookmark( name_ = nil ) click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 17
def go_to_named_bookmark( name_ = nil )
  if name_.nil?
    name = get_user_input "Bookmark name: "
  else
    name = name_
  end

  if name
    bookmark = @bookmarks[ name ]
    if bookmark
      switch_to( bookmark.buffer )
      bookmark.buffer.cursor_to( bookmark.row, bookmark.col, Buffer::DO_DISPLAY )
    else
      set_iline "No bookmark named '#{name}'."
    end
  end
end
Also aliased as: goToNamedBookmark
go_to_next_bookmark() click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 35
def go_to_next_bookmark
  buffer_current.go_to_next_bookmark
end
Also aliased as: goToNextBookmark
go_to_pair_match() click to toggle source

Moves the cursor to the pair match of the current character, if any.

# File lib/diakonos/functions/search.rb, line 140
def go_to_pair_match
  buffer_current.go_to_pair_match
end
go_to_previous_bookmark() click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 39
def go_to_previous_bookmark
  buffer_current.go_to_previous_bookmark
end
Also aliased as: goToPreviousBookmark
go_to_tag( tag_ = nil ) click to toggle source
# File lib/diakonos/functions/tags.rb, line 4
def go_to_tag( tag_ = nil )
  load_tags

  # If necessary, prompt for tag name.

  if tag_.nil?
    if buffer_current.changing_selection
      selected_text = buffer_current.copy_selection[ 0 ]
    end
    tag_name = get_user_input(
      "Tag name: ",
      history: @rlh_general,
      initial_text: selected_text || "",
      completion_array: @tags.keys
    )
  else
    tag_name = tag_
  end

  tag_array = @tags[ tag_name ]
  if tag_array && tag_array.length > 0
    if i = tag_array.index( @last_tag )
      tag = ( tag_array[ i + 1 ] || tag_array[ 0 ] )
    else
      tag = tag_array[ 0 ]
    end
    @last_tag = tag
    @tag_stack.push [ buffer_current.name, buffer_current.last_row, buffer_current.last_col ]
    if switch_to( @buffers.find { |b| b.name == tag.file } )
      #buffer_current.go_to_line( 0 )
    else
      open_file tag.file
    end
    line_number = tag.command.to_i
    if line_number > 0
      buffer_current.go_to_line( line_number - 1 )
    else
      find tag.command case_sensitive: true
    end
  elsif tag_name
    set_iline "No such tag: '#{tag_name}'"
  end
end
Also aliased as: goToTag
go_to_tag_under_cursor() click to toggle source
# File lib/diakonos/functions/tags.rb, line 48
def go_to_tag_under_cursor
  go_to_tag buffer_current.word_under_cursor
end
Also aliased as: goToTagUnderCursor
grep( regexp_source = nil ) click to toggle source
# File lib/diakonos/functions/grepping.rb, line 4
def grep( regexp_source = nil )
  grep_( regexp_source, buffer_current )
end
grep_buffers( regexp_source = nil ) click to toggle source
# File lib/diakonos/functions/grepping.rb, line 8
def grep_buffers( regexp_source = nil )
  grep_( regexp_source, *@buffers )
end
grep_dir( regexp_source = nil, dir = nil ) click to toggle source
# File lib/diakonos/functions/grepping.rb, line 16
def grep_dir( regexp_source = nil, dir = nil )
  if dir.nil?
    dir = get_user_input(
      "Grep directory: ",
      history: @rlh_files,
      initial_text: @session.dir,
      do_complete: DONT_COMPLETE,
      on_dirs: :accept_dirs
    )
    return if dir.nil?
  end
  dir = File.expand_path( dir )

  original_buffer = buffer_current
  if buffer_current.changing_selection
    selected_text = buffer_current.copy_selection[ 0 ]
  end
  starting_row, starting_col = buffer_current.last_row, buffer_current.last_col

  selected = get_user_input(
    "Grep regexp: ",
    history: @rlh_search,
    initial_text: regexp_source || selected_text || ""
  ) { |input|
    next if input.length < 2
    escaped_input = input.gsub( /'/ ) { "\\047" }
    matching_files = `egrep '#{escaped_input}' -rniIl #{dir}`.split( /\n/ )

    grep_results = matching_files.map { |f|
      ::Diakonos.grep_array(
        Regexp.new( input ),
        File.read( f ).split( /\n/ ),
        settings[ 'grep.context' ],
        "#{File.basename( f )}:",
        f
      )
    }.flatten
    if settings[ 'grep.context' ] == 0
      join_str = "\n"
    else
      join_str = "\n---\n"
    end
    with_list_file do |list|
      list.puts grep_results.join( join_str )
    end

    list_buffer = open_list_buffer
    regexp = nil
    begin
      list_buffer.highlight_matches Regexp.new( input )
    rescue RegexpError => e
      # ignore
    end
    display_buffer list_buffer
  }

  if selected
    spl = selected.split( "| " )
    if spl.size > 1
      open_file spl[ -1 ]
    end
  else
    original_buffer.cursor_to starting_row, starting_col
  end
end
grep_session_dir( regexp_source = nil ) click to toggle source
# File lib/diakonos/functions/grepping.rb, line 12
def grep_session_dir( regexp_source = nil )
  grep_dir regexp_source, @session.dir
end
help( prefill = '' ) click to toggle source

Starts the interactive help system.

# File lib/diakonos/functions.rb, line 109
def help( prefill = '' )
  if ! File.exist?( @help_dir ) || Dir[ "#{@help_dir}/*" ].size == 0
    set_iline 'There are no help files installed.'
    return
  end

  open_help_buffer
  matching_docs = nil

  selected = get_user_input(
    "Search terms: ",
    history: @rlh_help,
    initial_text: prefill,
    completion_array: @help_tags
  ) { |input|
    next if input.length < 3 && input[ 0..0 ] != '/'

    matching_docs = matching_help_documents( input )
    with_list_file do |list|
      list.puts matching_docs.join( "\n" )
    end

    open_list_buffer
  }

  close_help_buffer

  case selected
  when /\|/
    open_help_document selected
  when nil
    # Help search aborted; do nothing
  else
    # Not a selected help document
    if matching_docs.nil? || matching_docs.empty?
      matching_docs = matching_help_documents( selected )
    end

    case matching_docs.size
    when 1
      open_help_document matching_docs[ 0 ]
    when 0
      File.open( @error_filename, 'w' ) do |f|
        f.puts "There were no help documents matching your search."
        f.puts "(#{selected.strip})"
        f.puts "Close this message with Ctrl-W (default keychord)."
      end
      error_file = open_file( @error_filename )
    else
      help selected
    end
  end
end
indent() click to toggle source
# File lib/diakonos/functions/indentation.rb, line 4
def indent
  if ! buffer_current.changing_selection
    buffer_current.indent
  else
    @do_display = false
    mark = buffer_current.selection_mark
    if mark.end_col > 0
      end_row = mark.end_row
    else
      end_row = mark.end_row - 1
    end
    (mark.start_row..end_row).each do |row|
      buffer_current.indent row, Buffer::DONT_DISPLAY
    end
    @do_display = true
    display_buffer buffer_current
  end
end
insertSpaces( num_spaces )
Alias for: insert_spaces
insertTab()
Alias for: insert_tab
insert_spaces( num_spaces ) click to toggle source
# File lib/diakonos/functions/indentation.rb, line 23
def insert_spaces( num_spaces )
  if num_spaces > 0
    buffer_current.delete_selection
    buffer_current.insert_string( " " * num_spaces )
    cursor_right( Buffer::STILL_TYPING, num_spaces )
  end
end
Also aliased as: insertSpaces
insert_tab() click to toggle source
# File lib/diakonos/functions/indentation.rb, line 31
def insert_tab
  type_character "\t"
end
Also aliased as: insertTab
joinLines()
Alias for: join_lines
join_lines() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 83
def join_lines
  buffer_current.join_lines( buffer_current.current_row, Buffer::STRIP_LINE )
end
Also aliased as: joinLines
join_lines_upward() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 79
def join_lines_upward
  buffer_current.join_lines_upward( buffer_current.current_row, Buffer::STRIP_LINE )
end
list_buffers() click to toggle source

Opens the special “buffer selection” buffer, and prompts the user to select a buffer. The user can select a buffer either with the arrow keys and the Enter key, or by pressing the key corresponding to an index presented in a left-hand column in the list.

# File lib/diakonos/functions/buffers.rb, line 118
def list_buffers
  bullets = ( ('0'..'9').to_a + ('a'..'z').to_a ).map { |s| "#{s}  " }
  buffers_unnamed = @buffers.find_all { |b| b.name.nil? }
  buffers_named = @buffers.find_all { |b| b.name }

  with_list_file do |f|
    if buffers_unnamed.size == 1
      bullet = bullets.shift
      f.puts "#{bullet}(unnamed buffer)"
    else
      buffers_unnamed.each_with_index do |b,i|
        bullet = bullets.shift
        f.puts "#{bullet}(unnamed buffer #{i+1})"
      end
    end

    buffers_named.collect { |b| b.name }.sort.each_with_index do |name, index|
      bullet = bullets.shift
      f.puts "#{bullet}#{name}"
    end
  end
  open_list_buffer
  filename = get_user_input( "Switch to buffer: ", numbered_list: true )
  buffer = buffers_named.find { |b| b.name == filename }
  if buffer
    switch_to buffer
  elsif filename =~ /\(unnamed buffer( \d+)?/
    switch_to( buffers_unnamed[ $1.to_i - 1 ] )
  end
end
loadScript( name_ = nil )
Alias for: load_script
load_script( name_ = nil ) click to toggle source

Loads Ruby code from file using Kernel#load.

# File lib/diakonos/functions.rb, line 164
def load_script( name_ = nil )
  if name_.nil?
    name = get_user_input( "File to load as script: ", history: @rlh_files )
  else
    name = name_
  end

  if name
    thread = Thread.new( name ) do |f|
      begin
        load( f )
      rescue Exception => e
        show_exception(
          e,
          [
            "The filename given does not exist.",
            "The filename given is not accessible or readable.",
            "The loaded script does not reference Diakonos commands as members of the global Diakonos object.  e.g. cursor_bol instead of $diakonos.cursor_bol",
            "The loaded script has syntax errors.",
            "The loaded script references objects or object members which do not exist."
          ]
        )
      end
      set_iline "Loaded script '#{name}'."
    end

    loop do
      if thread.status != "run"
        break
      else
        sleep 0.1
      end
    end
    thread.join
  end
end
Also aliased as: loadScript
merge_session_settings() click to toggle source
# File lib/diakonos/functions/sessions.rb, line 4
def merge_session_settings
  @settings.merge! @session.settings
end
move_lines(direction:) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 87
def move_lines(direction:)
  mover = LineMover.new(buffer: buffer_current)
  mover.move_selected_lines(direction: direction)
end
name_session() click to toggle source
# File lib/diakonos/functions/sessions.rb, line 34
def name_session
  name = get_user_input( 'Session name: ' )
  if name
    @session = Session.new("#{@session_dir}/#{name}")
    save_session
  end
end
newFile( filename = nil, meta = {} )
Alias for: open_file
openFile( filename = nil, meta = {} )
Alias for: open_file
openFileAsk()
Alias for: open_file_ask
open_file( filename = nil, meta = {} ) click to toggle source

Opens a file into a new Buffer. @param filename

The file to open.  If nil, an empty, unnamed buffer is opened.

@param [Hash] meta

metadata containing additional information on how to open the file

@option meta [Hash] ‘cursor’ (nil)

A Hash containing the 'row' and 'col' to position the cursor after opening.

@option meta [Hash] ‘display’ (nil)

A Hash containing the 'top_line' and 'left_column' to use to position
the view after opening.

@option meta [Boolean] ‘read_only’ (false)

Whether to open the file in read-only (unmodifiable) mode

@option meta [Boolean] ‘revert’ (false)

Whether to skip asking about reverting to on-disk file contents (if different)

@return [Buffer] the buffer of the opened file @return [NilClass] nil on failure

# File lib/diakonos/functions/buffers.rb, line 165
def open_file( filename = nil, meta = {} )
  read_only    = !!meta[ 'read_only' ]
  force_revert = meta[ 'revert' ] || ASK_REVERT
  if meta[ 'cursor' ]
    last_row = meta[ 'cursor' ][ 'row' ]
    last_col = meta[ 'cursor' ][ 'col' ]
  end
  if meta[ 'display' ]
    top_line    = meta[ 'display' ][ 'top_line' ]
    left_column = meta[ 'display' ][ 'left_column' ]
  end

  do_open = true
  buffer = nil
  if filename
    filename, last_row_ = ::Diakonos.parse_filename_and_line_number( filename )
    last_row = last_row_ || last_row
    if filename =~ /\(unnamed buffer (\d+)\)/
      existing_buffer = @buffers.find { |b| b.object_id == $1.to_i }
      filename = nil
      do_open = false
    else
      existing_buffer = @buffers.find { |b| b.name == filename }
    end

    if filename
      if existing_buffer
        do_open = force_revert || ( filename =~ /\.diakonos/ )
        switch_to  existing_buffer, do_display: false

        if ! do_open && existing_buffer.file_different?
          show_buffer_file_diff( existing_buffer ) do
            choice = get_choice(
              "Load on-disk version of #{existing_buffer.nice_name}?",
              [ CHOICE_YES, CHOICE_NO ]
            )
            case choice
            when CHOICE_YES
              do_open = true
            when CHOICE_NO
              do_open = false
            end
          end
        end
      end

      if FileTest.exist?( filename )
        # Don't try to open non-files (i.e. directories, pipes, sockets, etc.)
        do_open &&= FileTest.file?( filename )
      end
    end
  end

  if do_open
    # Is file readable?

    # Does the "file" utility exist?
    if(
      filename &&
      @settings[ 'use_magic_file' ] &&
      FileTest.exist?( "/usr/bin/file" ) &&
      FileTest.exist?( filename ) &&
      /\blisting\.txt\b/ !~ filename
    )
      file_type = `/usr/bin/file -L #{filename}`
      if file_type !~ /text/ && file_type !~ /empty$/
        choice = get_choice(
          "#{filename} does not appear to be readable.  Try to open it anyway?",
          [ CHOICE_YES, CHOICE_NO ],
          CHOICE_NO
        )
        case choice
        when CHOICE_NO
          do_open = false
        end

      end
    end

    if do_open
      buffer = Buffer.new(
        'filepath' => filename,
        'read_only' => read_only,
        'display' => {
          'top_line' => top_line,
          'left_column' => left_column,
        },
        'cursor' => {
          'row' => last_row,
          'col' => last_col,
        }
      )
      if existing_buffer
        @buffers[ @buffers.index( existing_buffer ) ] = buffer
      else
        if @settings['open_as_first_buffer']
          @buffers.unshift buffer
        else
          @buffers << buffer
        end
      end
      run_hook_procs( :after_open, buffer )
      save_session
      if switch_to( buffer, do_display: false )
        if last_row
          buffer.cursor_to last_row, last_col || 0, Buffer::DONT_DISPLAY
        end
        display_buffer buffer
      end
    end
  elsif existing_buffer
    if switch_to( existing_buffer, do_display: false )
      if last_row
        existing_buffer.cursor_to last_row, last_col || 0, Buffer::DONT_DISPLAY
      end
      display_buffer existing_buffer
    end
  end

  buffer || existing_buffer
end
Also aliased as: newFile, openFile
open_file_ask() click to toggle source

Prompts the user for a file to open, then opens it with open_file . @see open_file

# File lib/diakonos/functions/buffers.rb, line 290
def open_file_ask
  prefill = ''

  if buffer_current
    if buffer_current.current_line =~ %r#(/\w+)+/\w+\.\w+#
      prefill = $&
    elsif buffer_current.name
      prefill = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
    end
  end

  if @settings[ 'fuzzy_file_find' ]
    prefill = ''
    finder = FuzzyFileFinder.new(
      directories: @session.dir,
      ceiling: @settings['fuzzy_file_find.max_files'] || 8192,
      ignores: @fuzzy_ignores,
      recursive: @settings['fuzzy_file_find.recursive']
    )

    finder_block = lambda { |input|
      break  if input =~ %r{^/}

      matches = finder.find(input).sort_by { |m| m[:path] }
      with_list_file do |list|
        list.puts matches.map { |m| m[:path] }
      end
      open_list_buffer
    }
  end

  file = get_user_input(
    "Filename: ",
    history: @rlh_files,
    initial_text: prefill,
    &finder_block
  )

  if file && ! file.empty?
    open_file file
    update_status_line
    update_context_line
  end
end
Also aliased as: openFileAsk
open_matching_files( regexp = nil, search_root = nil ) click to toggle source

Opens all files within a directory whose contents match a regular expression. @param regexp [String]

The regular expression used to match against.  If nil, the user is
prompted for a value.

@param search_root [String]

The directory under which to recursively search for matches.  If nil,
the user is prompted for a value.
# File lib/diakonos/functions/buffers.rb, line 343
def open_matching_files( regexp = nil, search_root = nil )
  regexp ||= get_user_input( "Regexp: ", history: @rlh_search )
  return  if regexp.nil?

  if buffer_current.current_line =~ %r{\w*/[/\w.]+}
    prefill = $&
  else
    prefill = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
  end
  search_root ||= get_user_input( "Search within: ", history: @rlh_files, initial_text: prefill )
  return  if search_root.nil?

  files = `egrep -rl '#{regexp.gsub( /'/, "'\\\\''" )}' #{search_root}/*`.split( /\n/ )
  if files.any?
    if files.size > 5
        choice = get_choice( "Open #{files.size} files?", [ CHOICE_YES, CHOICE_NO ] )
        return  if choice == CHOICE_NO
    end
    files.each do |f|
      open_file f
    end
    find regexp, direction: :down, case_sensitive: true
  end
end
operateOnEachLine( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'line.' ) )
operateOnLines( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'lines.collect { |l| l }' ) )
Alias for: operate_on_lines
operateOnString( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'str.' ) )
Alias for: operate_on_string
operate_on_each_line( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'line.' ) ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 130
def operate_on_each_line(
  ruby_code = get_user_input(
    'Ruby code: ',
    history: @rlh_general,
    initial_text: 'line.'
  )
)
  if ruby_code
    lines = buffer_current.selected_text
    if lines && ! lines.empty?
      if lines[ -1 ].empty?
        lines.pop
        popped = true
      end
      new_lines = eval( "lines.collect { |line| #{ruby_code} }" )
      if popped
        new_lines << ''
      end
      buffer_current.paste new_lines
    end
  end
end
Also aliased as: operateOnEachLine
operate_on_lines( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'lines.collect { |l| l }' ) ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 107
def operate_on_lines(
  ruby_code = get_user_input(
    'Ruby code: ',
    history: @rlh_general,
    initial_text: 'lines.collect { |l| l }'
  )
)
  if ruby_code
    lines = buffer_current.selected_text
    if lines && ! lines.empty?
      if lines[ -1 ].empty?
        lines.pop
        popped = true
      end
      new_lines = eval( ruby_code )
      if popped
        new_lines << ''
      end
      buffer_current.paste new_lines
    end
  end
end
Also aliased as: operateOnLines
operate_on_string( ruby_code = get_user_input( 'Ruby code: ', history: @rlh_general, initial_text: 'str.' ) ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 92
def operate_on_string(
  ruby_code = get_user_input(
    'Ruby code: ',
    history: @rlh_general,
    initial_text: 'str.'
  )
)
  if ruby_code
    str = buffer_current.selected_string
    if str && ! str.empty?
      buffer_current.paste eval( ruby_code )
    end
  end
end
Also aliased as: operateOnString
pageDown()
Alias for: page_down
pageUp()
Alias for: page_up
page_down() click to toggle source

Pitches the current buffer’s view one screenful down.

# File lib/diakonos/functions/cursor.rb, line 226
def page_down
  if buffer_current.pitch_view( main_window_height, Buffer::DO_PITCH_CURSOR ) == 0
    buffer_current.cursor_to_eof
  end
  update_status_line
  update_context_line
end
Also aliased as: pageDown
page_up() click to toggle source

Pitches the current buffer’s view one screenful up.

# File lib/diakonos/functions/cursor.rb, line 235
def page_up
  if buffer_current.pitch_view( -main_window_height, Buffer::DO_PITCH_CURSOR ) == 0
    cursor_bof
  end
  update_status_line
  update_context_line
end
Also aliased as: pageUp
parsedIndent()
Alias for: parsed_indent
parsed_indent() click to toggle source
# File lib/diakonos/functions/indentation.rb, line 35
def parsed_indent
  if( buffer_current.changing_selection )
    @do_display = false
    mark = buffer_current.selection_mark
    (mark.start_row..mark.end_row).each do |row|
      buffer_current.parsed_indent  row: row, do_display: false
    end
    @do_display = true
    display_buffer buffer_current
  else
    buffer_current.parsed_indent
  end
  update_status_line
  update_context_line
end
Also aliased as: parsedIndent
paste() click to toggle source

Pastes the current clipboard item at the current cursor position.

# File lib/diakonos/functions/clipboard.rb, line 43
def paste
  buffer_current.paste @clipboard.clip
end
pasteShellResult( command_ = nil )
Alias for: paste_shell_result
paste_shell_result( command_ = nil ) click to toggle source

Executes a command in a shell, captures the results, and pastes them in the current buffer at the current cursor location. Substitutes Diakonos shell variables. Interaction with Diakonos is not possible while the shell is running. For asynchronous shelling, use spawn.

@param [String] command_

The shell command to execute

@see sub_shell_variables @see execute @see shell @see spawn

# File lib/diakonos/functions/shell.rb, line 200
def paste_shell_result( command_ = nil )
  command = command_ || get_user_input( "Command: ", history: @rlh_shell )

  return  if command.nil?

  command = sub_shell_variables( command )

  Curses::close_screen

  begin
    buffer_current.paste( `#{command} 2<&1`.split( /\n/, -1 ) )
  rescue Exception => e
    debug_log e.message
    debug_log e.backtrace.join( "\n\t" )
    show_exception e
  end

  Curses::init_screen
  refresh_all
end
Also aliased as: pasteShellResult
playMacro( name = nil )
Alias for: play_macro
play_macro( name = nil ) click to toggle source
# File lib/diakonos/functions.rb, line 201
def play_macro( name = nil )
  macro, input_history = @macros[ name ]
  if input_history
    @macro_input_history = input_history.deep_clone
    if macro
      @playing_macro = true
      macro.each do |command|
        eval command
      end
      @playing_macro = false
      @macro_input_history = nil
    end
  end
end
Also aliased as: playMacro
popTag()
Alias for: pop_tag
pop_tag() click to toggle source
# File lib/diakonos/functions/tags.rb, line 52
def pop_tag
  tag = @tag_stack.pop
  if tag
    if ! switch_to( @buffers.find { |b| b.name == tag[ 0 ] } )
      open_file tag[ 0 ]
    end
    buffer_current.cursor_to( tag[ 1 ], tag[ 2 ], Buffer::DO_DISPLAY )
  else
    set_iline "Tag stack empty."
  end
end
Also aliased as: popTag
printKeychain()
Alias for: print_keychain
print_keychain() click to toggle source
Also aliased as: printKeychain
print_mapped_function() click to toggle source
quit() click to toggle source

Quits Diakonos (gracefully).

# File lib/diakonos/functions.rb, line 227
def quit
  @quitting = true
  to_all = nil
  save_session
  @buffers.each do |buffer|
    next  if ! buffer.modified?
    switch_to buffer
    closure_choice = close_buffer( buffer, to_all: to_all )
    case closure_choice
    when CHOICE_CANCEL
      @quitting = false
      break
    when CHOICE_YES_TO_ALL, CHOICE_NO_TO_ALL
      to_all = closure_choice
    end
  end
end
readline_abort() click to toggle source
# File lib/diakonos/functions/readline.rb, line 4
def readline_abort
  @readline.abort
end
readline_accept() click to toggle source
# File lib/diakonos/functions/readline.rb, line 8
def readline_accept
  @readline.accept current_list_item
end
readline_backspace() click to toggle source
# File lib/diakonos/functions/readline.rb, line 12
def readline_backspace
  @readline.backspace
end
readline_complete_input() click to toggle source
# File lib/diakonos/functions/readline.rb, line 16
def readline_complete_input
  @readline.complete_input
end
readline_cursor_bol() click to toggle source
# File lib/diakonos/functions/readline.rb, line 28
def readline_cursor_bol
  @readline.cursor_bol
end
readline_cursor_down() click to toggle source
# File lib/diakonos/functions/readline.rb, line 48
def readline_cursor_down
  if showing_list?
    if list_item_selected?
      next_list_item
    end
    @readline.set_input select_list_item
  else
    @readline.history_down
  end
  @readline.cursor_write_input
end
readline_cursor_eol() click to toggle source
# File lib/diakonos/functions/readline.rb, line 32
def readline_cursor_eol
  @readline.cursor_eol
end
readline_cursor_left() click to toggle source
# File lib/diakonos/functions/readline.rb, line 20
def readline_cursor_left
  @readline.cursor_left
end
readline_cursor_right() click to toggle source
# File lib/diakonos/functions/readline.rb, line 24
def readline_cursor_right
  @readline.cursor_right
end
readline_cursor_up() click to toggle source
# File lib/diakonos/functions/readline.rb, line 36
def readline_cursor_up
  if showing_list?
    if list_item_selected?
      previous_list_item
    end
    @readline.set_input select_list_item
  else
    @readline.history_up
  end
  @readline.cursor_write_input
end
readline_delete() click to toggle source
# File lib/diakonos/functions/readline.rb, line 60
def readline_delete
  @readline.delete
end
readline_delete_line() click to toggle source
# File lib/diakonos/functions/readline.rb, line 64
def readline_delete_line
  @readline.delete_line
end
readline_delete_word() click to toggle source
# File lib/diakonos/functions/readline.rb, line 68
def readline_delete_word
  @readline.delete_word
end
readline_grep_context_decrease() click to toggle source
# File lib/diakonos/functions/readline.rb, line 72
def readline_grep_context_decrease
  decrease_grep_context
  @readline.call_block
end
readline_grep_context_increase() click to toggle source
# File lib/diakonos/functions/readline.rb, line 77
def readline_grep_context_increase
  increase_grep_context
  @readline.call_block
end
readline_page_down() click to toggle source
# File lib/diakonos/functions/readline.rb, line 82
def readline_page_down
  page_down
  @readline.list_sync select_list_item
end
readline_page_up() click to toggle source
# File lib/diakonos/functions/readline.rb, line 87
def readline_page_up
  page_up
  @readline.list_sync select_list_item
end
removeNamedBookmark( name_ = nil )
removeSelection()
Alias for: remove_selection
remove_named_bookmark( name_ = nil ) click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 43
def remove_named_bookmark( name_ = nil )
  if name_.nil?
    name = get_user_input "Bookmark name: "
  else
    name = name_
  end

  if name
    bookmark = @bookmarks.delete name
    set_iline "Removed bookmark #{bookmark.to_s}."
  end
end
Also aliased as: removeNamedBookmark
remove_selection() click to toggle source

Unselects any current selection (stops selecting).

# File lib/diakonos/functions/selection.rb, line 26
def remove_selection
  buffer_current.remove_selection
  update_status_line
end
Also aliased as: removeSelection
renumber_buffer( to, from = nil ) click to toggle source

Places a buffer at a new position in the array of Buffers after shifting down (index+1) all existing Buffers from that position onwards. @param to [Integer] The new 1-based position of the buffer to move @param from [Integer] The original 1-based position of the buffer to move. Default: current buffer

# File lib/diakonos/functions/buffers.rb, line 372
def renumber_buffer( to, from = nil )
  if to < 1
    raise "Invalid buffer index: #{to.inspect}"
  end
  if from && from < 1
    raise "Invalid buffer index: #{from.inspect}"
  end

  from ||= buffer_to_number( buffer_current )
  from_ = from - 1
  to_   = to - 1
  b = @buffers[from_]
  @buffers.delete_at from_
  @buffers.insert( to_, b )
  @buffers.compact!

  update_status_line
end
repeatLast()
Alias for: repeat_last
repeat_last() click to toggle source
# File lib/diakonos/functions.rb, line 245
def repeat_last
  eval @functions_last[ -1 ] if ! @functions_last.empty?
end
Also aliased as: repeatLast
revert( prompt = nil ) click to toggle source

If the prompt is non-nil, ask the user yes or no question first.

# File lib/diakonos/functions/buffers.rb, line 392
def revert( prompt = nil )
  do_revert = true

  if prompt
    show_buffer_file_diff do
      choice = get_choice(
        prompt,
        [ CHOICE_YES, CHOICE_NO ]
      )
      case choice
      when CHOICE_NO
        do_revert = false
      end
    end
  end

  if do_revert
    open_file(
      buffer_current.name,
      'read_only' => false,
      'revert' => FORCE_REVERT,
      'cursor' => {
        'row' => buffer_current.last_row,
        'col' => buffer_current.last_col
      }
    )
  end
end
saveFile( buffer = buffer_current )
Alias for: save_file
saveFileAs()
Alias for: save_file_as
save_file( buffer = buffer_current ) click to toggle source

Saves a buffer, then runs the :after_save hook on it. @param [Buffer] buffer

The buffer to save.  If nil, defaults to the current buffer.
# File lib/diakonos/functions/buffers.rb, line 424
def save_file( buffer = buffer_current )
  buffer.save
  run_hook_procs( :after_save, buffer )
end
Also aliased as: saveFile
save_file_as() click to toggle source
# File lib/diakonos/functions/buffers.rb, line 429
def save_file_as
  if buffer_current && buffer_current.name
    path = File.expand_path( File.dirname( buffer_current.name ) ) + "/"
    file = get_user_input( "Filename: ", history: @rlh_files, initial_text: path )
  else
    file = get_user_input( "Filename: ", history: @rlh_files )
  end
  if file
    old_name = buffer_current.name
    if buffer_current.save( file, PROMPT_OVERWRITE )
      save_session
    end
  end
end
Also aliased as: saveFileAs
scrollDown()
Alias for: scroll_down
scrollUp()
Alias for: scroll_up
scroll_down() click to toggle source

Scrolls the current buffer’s view down, as determined by the view.scroll_amount setting.

# File lib/diakonos/functions/cursor.rb, line 245
def scroll_down
  buffer_current.pitch_view( @settings[ "view.scroll_amount" ] || 1 )
  update_status_line
  update_context_line
end
Also aliased as: scrollDown
scroll_up() click to toggle source

Scrolls the current buffer’s view up, as determined by the view.scroll_amount setting.

# File lib/diakonos/functions/cursor.rb, line 253
def scroll_up
  if @settings[ "view.scroll_amount" ]
    buffer_current.pitch_view( -@settings[ "view.scroll_amount" ] )
  else
    buffer_current.pitch_view( -1 )
  end
  update_status_line
  update_context_line
end
Also aliased as: scrollUp
searchAndReplace( case_sensitive = CASE_INSENSITIVE )
Alias for: search_and_replace
search_and_replace( case_sensitive = CASE_INSENSITIVE ) click to toggle source

Wrapper method for calling find for search and replace. @see find

# File lib/diakonos/functions/search.rb, line 146
def search_and_replace( case_sensitive = CASE_INSENSITIVE )
  find nil, case_sensitive: case_sensitive, replacement: ASK_REPLACEMENT
end
seek( regexp_source, direction = :down ) click to toggle source

Immediately moves the cursor to the next match of a regular expression. The user is not prompted for any value. @param [String] regexp_source

The regular expression to search for.

@param [Symbol] direction

The direction to search; :down (default) or :up.
# File lib/diakonos/functions/search.rb, line 157
def seek( regexp_source, direction = :down )
  if regexp_source
    regexp = Regexp.new( regexp_source )
    buffer_current.seek( regexp, direction )
  end
end
select_all() click to toggle source

Selects the entire buffer contents.

# File lib/diakonos/functions/selection.rb, line 32
def select_all
  buffer_current.select_all
end
select_block( beginning = nil, ending = nil, including_ending = true ) click to toggle source

Selects text between two regexps.

# File lib/diakonos/functions/selection.rb, line 37
def select_block( beginning = nil, ending = nil, including_ending = true )
  if beginning.nil?
    input = get_user_input( "Start at regexp: " )
    if input
      beginning = Regexp.new input
    end
  end
  if beginning && ending.nil?
    input = get_user_input( "End before regexp: " )
    if input
      ending = Regexp.new input
    end
  end
  if beginning && ending
    buffer_current.select( beginning, ending, including_ending )
  end
end
select_line() click to toggle source

Selects the current line.

# File lib/diakonos/functions/selection.rb, line 75
def select_line
  buffer_current.select_current_line
  update_status_line
end
select_word() click to toggle source

Selects the word at the current cursor position. If the cursor is not on a word character, the first word following the cursor is selected.

# File lib/diakonos/functions/selection.rb, line 89
def select_word
  buffer_current.select_word
end
select_word_another() click to toggle source
# File lib/diakonos/functions/selection.rb, line 93
def select_word_another
  buffer_current.select_word_another
end
select_wrapping_block() click to toggle source

Selects the code block which wraps the current cursor position. Execute multiple times in succession to select increasingly outer code blocks.

# File lib/diakonos/functions/selection.rb, line 82
def select_wrapping_block
  buffer_current.select_wrapping_block
  update_status_line
end
selection_mode_block() click to toggle source

Changes selection mode to block mode (rectangular selection).

# File lib/diakonos/functions/selection.rb, line 56
def selection_mode_block
  buffer_current.selection_mode_block
  update_status_line
end
selection_mode_normal() click to toggle source

Changes selection mode to normal mode (flow selection).

# File lib/diakonos/functions/selection.rb, line 62
def selection_mode_normal
  buffer_current.selection_mode_normal
  update_status_line
end
setBufferType( type_ = nil )
Alias for: set_buffer_type
setReadOnly( read_only = nil )
Alias for: set_read_only
set_buffer_type( type_ = nil ) click to toggle source

Sets the type (language) of the current buffer. @param [String] type_

The type to set the current buffer to.
If nil, the user is prompted for a value.
# File lib/diakonos/functions/buffers.rb, line 448
def set_buffer_type( type_ = nil )
  type = type_ || get_user_input( "Content type: " )

  if type
    if buffer_current.set_type( type )
      update_status_line
      update_context_line
    end
  end
end
Also aliased as: setBufferType
set_read_only( read_only = nil ) click to toggle source

If read_only is nil, the read_only state of the current buffer is toggled. Otherwise, the read_only state of the current buffer is set to read_only.

# File lib/diakonos/functions/buffers.rb, line 461
def set_read_only( read_only = nil )
  if read_only
    buffer_current.read_only = read_only
  else
    buffer_current.read_only = ( ! buffer_current.read_only )
  end
  update_status_line
end
Also aliased as: setReadOnly
set_session_dir() click to toggle source
# File lib/diakonos/functions/sessions.rb, line 42
def set_session_dir
  path = get_user_input(
    "Session directory: ",
    history: @rlh_files,
    initial_text: @session.dir,
    do_complete: DONT_COMPLETE,
    on_dirs: :accept_dirs
  )
  if path
    @session.dir = File.expand_path( path )
    save_session
    set_iline "Session dir changed to: #{@session.dir}"
  else
    set_iline "(Session dir is: #{@session.dir})"
  end
end
shell( command_ = nil, result_filename = 'shell-result.txt' ) click to toggle source

Executes a command in a shell, captures the results, and displays them (if any) in a new buffer. Substitutes Diakonos shell variables. Interaction with Diakonos is not possible while the shell is running. For asynchronous shelling, use spawn. The shell function does not allow interaction with applications run in the shell. Use execute for interactivity.

@param [String] command_

The shell command to execute

@param [String] result_filename

The name of the temporary file to write the shell results to

@see sub_shell_variables @see execute @see spawn @see paste_shell_result

# File lib/diakonos/functions/shell.rb, line 93
def shell( command_ = nil, result_filename = 'shell-result.txt' )
  command = command_ || get_user_input( "Command: ", history: @rlh_shell )

  return  if command.nil?

  command = sub_shell_variables( command )

  completed = false
  result_file = "#{@diakonos_home}/#{result_filename}"
  File.open( result_file , "w" ) do |f|
    Curses::close_screen

    stdin, stdout, stderr = Open3.popen3( command )

    t1 = Thread.new do
      stdout.each_line do |line|
        f.puts line
      end
    end
    t2 = Thread.new do
      stderr.each_line do |line|
        f.puts line
      end
    end

    catch :stop do
      loop do
        begin
          Timeout::timeout( 5 ) do
            t1.join
            t2.join
            Curses::init_screen
            refresh_all
            completed = true
            throw :stop
          end
        rescue Timeout::Error => e
          choice = get_choice(
            "Keep waiting for shell results?",
            [ CHOICE_YES, CHOICE_NO ],
            CHOICE_YES
          )
          if choice != CHOICE_YES
            t1.terminate
            t2.terminate
            throw :stop
          end
        end
      end
    end

  end
  if File.size?( result_file )
    open_file result_file
    set_iline "#{completed ? '' : '(interrupted) '}Results for: #{command}"
  else
    set_iline "Empty result for: #{command}"
  end
end
showClips()
Alias for: show_clips
show_clips() click to toggle source

Opens a new buffer showing a list of all internal clipboard items. Only for use when no external clipboard is used.

# File lib/diakonos/functions/clipboard.rb, line 49
def show_clips
  clip_filename = @diakonos_home + "/clips.txt"
  File.open( clip_filename, "w" ) do |f|
    case @settings[ 'clipboard.external' ]
    when 'klipper'
      f.puts 'Access Klipper directly (tray icon) to get at all clips.'
    when 'xclip'
      f.puts 'xclip does not keep a history of clips.'
    when 'osx'
      f.puts 'The OSX clipboard does not keep a history of clips.'
    else
      @clipboard.each do |clip|
        f.puts clip
        f.puts "---------------------------"
      end
    end
  end
  open_file clip_filename
end
Also aliased as: showClips
show_number_of_matches_found( num_replacements = nil ) click to toggle source
# File lib/diakonos/functions/search.rb, line 164
def show_number_of_matches_found( num_replacements = nil )
  return  if buffer_current.num_matches_found.nil?

  num_found = buffer_current.num_matches_found
  if num_found != 1
    plural = 'es'
  end
  if num_replacements
    set_iline_if_empty "#{num_replacements} out of #{num_found} match#{plural} replaced"
  else
    set_iline_if_empty "#{num_found} match#{plural} found"
  end
end
spawn( command_ = nil ) click to toggle source

Executes a command in a shell, captures the results, and pastes them in the current buffer at the current cursor location. Substitutes Diakonos shell variables. The shell is executed in a separate thread, so interaction with Diakonos is possible during execution.

@param [String] command_

The shell command to execute

@see sub_shell_variables @see execute @see shell @see paste_shell_result

# File lib/diakonos/functions/shell.rb, line 233
def spawn( command_ = nil )
  command = command_ || get_user_input( "Command: ", history: @rlh_shell )

  return  if command.nil?

  command = sub_shell_variables( command )

  Thread.new do
    if system( command )
      set_iline "Return code #{$?} from '#{command}'"
    else
      set_iline "Error code #{$?} executing '#{command}'"
    end
  end
end
sub_shell_variables( string ) click to toggle source

Substitutes Diakonos shell variables in a String.

  • $f: The current buffer’s filename

  • $d: The current buffer’s directory

  • $F: A space-separated list of all buffer filenames

  • $i: A string acquired from the user with a prompt

  • $c: The current clipboard text

  • $s: The currently selected text

@param [String] string

The string containing variables to substitute

@return [String]

A new String with values substituted for all variables
# File lib/diakonos/functions/shell.rb, line 24
def sub_shell_variables( string )
  return  if string.nil?

  retval = string.dup

  # Current buffer filename
  retval.gsub!( /\$f/, ( $1 || "" ) + File.expand_path( buffer_current.name || "" ) )
  # Current buffer dir
  retval.gsub!( /\$d/, ( $1 || "" ) + File.dirname( File.expand_path( buffer_current.name || '' ) ) )

  # space-separated list of all buffer filenames
  name_array = Array.new
  @buffers.each do |b|
    name_array.push b.name
  end
  retval.gsub!( /\$F/, ( $1 || "" ) + ( name_array.join(' ') || "" ) )

  # Get user input, sub it in
  if retval =~ /\$i/
    user_input = get_user_input(
      "Argument: ",
      history: @rlh_shell,
      initial_text: buffer_current.selected_string
    )
    retval.gsub!( /\$i/, user_input )
  end

  # Current clipboard text
  if retval =~ /\$[ck]/
    clip_filename = @diakonos_home + "/clip.txt"
    File.open( clip_filename, "w" ) do |clipfile|
      if @clipboard.clip
        clipfile.puts( @clipboard.clip.join( "\n" ) )
      end
    end
    retval.gsub!( /\$[ck]/, clip_filename )
  end

  # Currently selected text
  if retval =~ /\$s/
    text_filename = @diakonos_home + "/selected.txt"

    File.open( text_filename, "w" ) do |textfile|
      selected_text = buffer_current.selected_text
      if selected_text
        textfile.puts( selected_text.join( "\n" ) )
      end
    end
    retval.gsub!( /\$s/, text_filename )
  end

  retval
end
surround_line( envelope = nil ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 153
def surround_line( envelope = nil )
  buffer_current.set_selection_current_line
  surround_selection envelope
end
surround_paragraph( envelope = nil ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 158
def surround_paragraph( envelope = nil )
  ( first, _ ), ( last, length ) = buffer_current.paragraph_under_cursor_pos
  buffer_current.set_selection( first, 0, last, length+1 )
  surround_selection envelope
end
surround_selection( parenthesis = nil ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 164
def surround_selection( parenthesis = nil )
  if ! buffer_current.selecting?
    set_iline "Nothing selected."
    return
  end

  parenthesis ||= get_user_input( "Surround with: " )
  if parenthesis
    text = buffer_current.surround( buffer_current.selected_text, parenthesis )
    if text
      buffer_current.paste text
    end
  end
end
surround_word( envelope = nil ) click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 179
def surround_word( envelope = nil )
  ( start_row, start_col ), ( end_row, end_col ) = buffer_current.word_under_cursor_pos
  if start_row && start_col && end_row && end_col
    buffer_current.set_selection( start_row, start_col, end_row, end_col )
    surround_selection envelope
  end
end
suspend() click to toggle source

Send the Diakonos job to background, as if with Ctrl-Z

# File lib/diakonos/functions.rb, line 250
def suspend
  Curses::close_screen
  Process.kill( "SIGSTOP", $PID )
  Curses::init_screen
  refresh_all
end
switchToBufferNumber( buffer_number_ )
switchToNextBuffer()
switchToPreviousBuffer()
switch_to_buffer_number( buffer_number_ ) click to toggle source
# File lib/diakonos/functions/buffers.rb, line 470
def switch_to_buffer_number( buffer_number_ )
  buffer_number = buffer_number_.to_i
  return  if buffer_number < 1
  if @buffer_number_last && buffer_number == buffer_to_number(buffer_current)
    buffer_number = @buffer_number_last
  end
  @buffer_number_last = buffer_to_number(buffer_current)
  switch_to @buffers[ buffer_number - 1 ]
end
Also aliased as: switchToBufferNumber
switch_to_next_buffer() click to toggle source
# File lib/diakonos/functions/buffers.rb, line 480
def switch_to_next_buffer
  switch_to_buffer_number( buffer_to_number( buffer_current ) + 1 )
end
Also aliased as: switchToNextBuffer
switch_to_previous_buffer() click to toggle source
# File lib/diakonos/functions/buffers.rb, line 484
def switch_to_previous_buffer
  switch_to_buffer_number( buffer_to_number( buffer_current ) - 1 )
end
Also aliased as: switchToPreviousBuffer
toggleBookmark()
Alias for: toggle_bookmark
toggleMacroRecording( name = nil )
toggleSelection()
Alias for: toggle_selection
toggleSessionSetting( key_ = nil, do_redraw = DONT_REDRAW )
toggle_bookmark() click to toggle source
# File lib/diakonos/functions/bookmarking.rb, line 56
def toggle_bookmark
  buffer_current.toggle_bookmark
end
Also aliased as: toggleBookmark
toggle_macro_recording( name = nil ) click to toggle source

Starts or stops macro recording.

# File lib/diakonos/functions.rb, line 258
def toggle_macro_recording( name = nil )
  if @macro_history
    stop_recording_macro
  else
    start_recording_macro name
  end
end
Also aliased as: toggleMacroRecording
toggle_selection() click to toggle source

If currently selecting, stops selecting. If not currently selecting, begins selecting.

# File lib/diakonos/functions/selection.rb, line 69
def toggle_selection
  buffer_current.toggle_selection
  update_status_line
end
Also aliased as: toggleSelection
toggle_session_setting( key_ = nil, do_redraw = DONT_REDRAW ) click to toggle source
# File lib/diakonos/functions/sessions.rb, line 59
def toggle_session_setting( key_ = nil, do_redraw = DONT_REDRAW )
  key = key_ || get_user_input( "Setting: " )
  return  if key.nil?

  value = nil
  if @session.settings[ key ].class == TrueClass || @session.settings[ key ].class == FalseClass
    value = ! @session.settings[ key ]
  elsif @settings[ key ].class == TrueClass || @settings[ key ].class == FalseClass
    value = ! @settings[ key ]
  end
  if value != nil   # explicitly true or false
    @session.settings[ key ] = value
    merge_session_settings
    redraw  if do_redraw
    set_iline "#{key} = #{value}"
  end
end
Also aliased as: toggleSessionSetting
uncomment() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 187
def uncomment
  buffer_current.uncomment
end
undo( buffer = buffer_current ) click to toggle source

Undoes the latest change made to the current buffer, or reopens the file that was just closed.

# File lib/diakonos/functions.rb, line 268
def undo( buffer = buffer_current )
  if @functions_last[-1] == 'close_buffer'
    open_file(
      @buffer_closed.name,
      'cursor' => {
        'row' => @buffer_closed.last_row,
        'col' => @buffer_closed.last_col,
      },
      'display' => {
        'top_line' => @buffer_closed.top_line,
        'left_col' => @buffer_closed.left_column,
      }
    )
  else
    buffer.undo
  end
end
unindent() click to toggle source
# File lib/diakonos/functions/indentation.rb, line 51
def unindent
  if( buffer_current.changing_selection )
    @do_display = false
    mark = buffer_current.selection_mark
    if mark.end_col > 0
      end_row = mark.end_row
    else
      end_row = mark.end_row - 1
    end
    (mark.start_row..end_row).each do |row|
      buffer_current.unindent row, Buffer::DONT_DISPLAY
    end
    @do_display = true
    display_buffer buffer_current
  else
    buffer_current.unindent
  end
end
unundo( buffer = buffer_current ) click to toggle source

Redoes the latest change undone on the current buffer.

# File lib/diakonos/functions.rb, line 287
def unundo( buffer = buffer_current )
  buffer.unundo
end
wrap_paragraph() click to toggle source
# File lib/diakonos/functions/text-manipulation.rb, line 191
def wrap_paragraph
  buffer_current.wrap_paragraph
end