File: interface.rb

package info (click to toggle)
ruby-byebug 11.1.3-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,252 kB
  • sloc: ruby: 8,835; ansic: 1,662; sh: 6; makefile: 4
file content (146 lines) | stat: -rw-r--r-- 3,139 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# frozen_string_literal: true

require_relative "setting"
require_relative "history"
require_relative "helpers/file"

#
# Namespace for all of byebug's code
#
module Byebug
  #
  # Main Interface class
  #
  # Contains common functionality to all implemented interfaces.
  #
  class Interface
    include Helpers::FileHelper

    attr_accessor :command_queue, :history
    attr_reader :input, :output, :error

    def initialize
      @command_queue = []
      @history = History.new
      @last_line = ""
    end

    def last_if_empty(input)
      @last_line = input.empty? ? @last_line : input
    end

    #
    # Pops a command from the input stream.
    #
    def read_command(prompt)
      return command_queue.shift unless command_queue.empty?

      read_input(prompt)
    end

    #
    # Pushes lines in +filename+ to the command queue.
    #
    def read_file(filename)
      command_queue.concat(get_lines(filename))
    end

    #
    # Reads a new line from the interface's input stream, parses it into
    # commands and saves it to history.
    #
    # @return [String] Representing something to be run by the debugger.
    #
    def read_input(prompt, save_hist = true)
      line = prepare_input(prompt)
      return unless line

      history.push(line) if save_hist

      command_queue.concat(split_commands(line))
      command_queue.shift
    end

    #
    # Reads a new line from the interface's input stream.
    #
    # @return [String] New string read or the previous string if the string
    # read now was empty.
    #
    def prepare_input(prompt)
      line = readline(prompt)
      return unless line

      last_if_empty(line)
    end

    #
    # Prints an error message to the error stream.
    #
    def errmsg(message)
      error.print("*** #{message}\n")
    end

    #
    # Prints an output message to the output stream.
    #
    def puts(message)
      output.puts(message)
    end

    #
    # Prints an output message to the output stream without a final "\n".
    #
    def print(message)
      output.print(message)
    end

    #
    # Confirms user introduced an affirmative response to the input stream.
    #
    def confirm(prompt)
      readline(prompt) == "y"
    end

    def close
    end

    #
    # Saves or clears history according to +autosave+ setting.
    #
    def autosave
      Setting[:autosave] ? history.save : history.clear
    end

    #
    # Restores history according to +autosave+ setting.
    #
    def autorestore
      history.restore if Setting[:autosave]
    end

    private

    #
    # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
    # array of commands: [cmd1, cmd2, ..., cmdN]
    #
    def split_commands(cmd_line)
      return [""] if cmd_line.empty?

      cmd_line.split(/;/).each_with_object([]) do |v, m|
        if m.empty? || m.last[-1] != '\\'
          m << v.strip
          next
        end

        m.last[-1, 1] = ""
        m.last << ";" << v
      end
    end
  end
end

require_relative "interfaces/local_interface"
require_relative "interfaces/script_interface"
require_relative "interfaces/remote_interface"