aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reline2.rb
blob: e5a9ff763a18b7b75aad9cad4ff7d48b6ebf45f6 (plain)
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
require 'io/console'
require 'timeout'
require "forwardable"
require 'reline/version'
require 'reline/config'
require 'reline/key_actor'
require 'reline/key_stroke'
require 'reline/line_editor'

module Reline2
  FILENAME_COMPLETION_PROC = nil
  USERNAME_COMPLETION_PROC = nil

  class Core
    Key = Struct.new('Key', :char, :combined_char, :with_meta)
    if RUBY_PLATFORM =~ /mswin|mingw/
      IS_WINDOWS = true
    else
      IS_WINDOWS = false
    end

    CursorPos = Struct.new(:x, :y)

    ATTR_ACCESSOR_NAMES = %i(
      completion_append_character
      basic_word_break_characters
      completer_word_break_characters
      basic_quote_characters
      completer_quote_characters
      filename_quote_characters
      special_prefixes
      completion_case_fold
      completion_proc
      output_modifier_proc
      prompt_proc
      auto_indent_proc
      pre_input_hook
      dig_perfect_match_proc
    ).freeze
    ATTR_ACCESSOR_NAMES.each &method(:attr_accessor)

    def initialize
      @config = Reline::Config.new
      @line_editor = Reline::LineEditor.new(@config)
      @ambiguous_width = nil

      self.basic_word_break_characters = " \t\n`><=;|&{("
      self.completer_word_break_characters = " \t\n`><=;|&{("
      self.basic_quote_characters = '"\''
      self.completer_quote_characters = '"\''
      self.filename_quote_characters = ""
      self.special_prefixes = ""
    end

    def completion_append_character=(val)
      if val.nil?
        @completion_append_character = nil
      elsif val.size == 1
        @completion_append_character = val.encode(Encoding::default_external)
      elsif val.size > 1
        @completion_append_character = val[0].encode(Encoding::default_external)
      else
        @completion_append_character = nil
      end
    end

    def basic_word_break_characters=(v)
      @basic_word_break_characters = v.encode(Encoding::default_external)
    end

    def completer_word_break_characters=(v)
      @completer_word_break_characters = v.encode(Encoding::default_external)
    end

    def basic_quote_characters=(v)
      @basic_quote_characters = v.encode(Encoding::default_external)
    end

    def completer_quote_characters=(v)
      @completer_quote_characters = v.encode(Encoding::default_external)
    end

    def filename_quote_characters=(v)
      @filename_quote_characters = v.encode(Encoding::default_external)
    end

    def special_prefixes=(v)
      @special_prefixes = v.encode(Encoding::default_external)
    end

    def completion_proc=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @completion_proc = p
    end

    def output_modifier_proc=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @output_modifier_proc = p
    end

    def prompt_proc=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @prompt_proc = p
    end

    def auto_indent_proc=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @auto_indent_proc = p
    end

    def pre_input_hook=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @pre_input_hook = p
    end

    def dig_perfect_match_proc=(p)
      raise ArgumentError unless p.is_a?(Proc)
      @dig_perfect_match_proc = p
    end
  end

  extend SingleForwardable

  Core::ATTR_ACCESSOR_NAMES.each { |name|
    def_delegators :core, "#{name}", "#{name}="
  }

  private

  def self.core
    @core ||= Core.new
  end
end