Module: CLI::UI::ANSI

Defined in:
lib/cli/ui/ansi.rb

Constant Summary collapse

ESC =
"\x1b"

Class Method Summary collapse

Class Method Details

.clear_to_end_of_lineObject


154
155
156
# File 'lib/cli/ui/ansi.rb', line 154

def self.clear_to_end_of_line
  control('', 'K')
end

.control(args, cmd) ⇒ Object

Returns an ANSI control sequence

Attributes

  • args - Argument to pass to the ANSI control sequence

  • cmd - ANSI control sequence Command


47
48
49
# File 'lib/cli/ui/ansi.rb', line 47

def self.control(args, cmd)
  ESC + "[" + args + cmd
end

.cursor_back(n = 1) ⇒ Object

Move the cursor back n columns

Attributes

  • n - number of columns by which to move the cursor back


97
98
99
100
# File 'lib/cli/ui/ansi.rb', line 97

def self.cursor_back(n = 1)
  return '' if n.zero?
  control(n.to_s, 'D')
end

.cursor_down(n = 1) ⇒ Object

Move the cursor down n lines

Attributes

  • n - number of lines by which to move the cursor down


75
76
77
78
# File 'lib/cli/ui/ansi.rb', line 75

def self.cursor_down(n = 1)
  return '' if n.zero?
  control(n.to_s, 'B')
end

.cursor_forward(n = 1) ⇒ Object

Move the cursor forward n columns

Attributes

  • n - number of columns by which to move the cursor forward


86
87
88
89
# File 'lib/cli/ui/ansi.rb', line 86

def self.cursor_forward(n = 1)
  return '' if n.zero?
  control(n.to_s, 'C')
end

.cursor_horizontal_absolute(n = 1) ⇒ Object

Move the cursor to a specific column

Attributes

  • n - The column to move to


108
109
110
111
112
# File 'lib/cli/ui/ansi.rb', line 108

def self.cursor_horizontal_absolute(n = 1)
  cmd = control(n.to_s, 'G')
  cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
  cmd
end

.cursor_restoreObject

Restore the saved cursor position


134
135
136
# File 'lib/cli/ui/ansi.rb', line 134

def self.cursor_restore
  control('', 'u')
end

.cursor_saveObject

Save the cursor position


128
129
130
# File 'lib/cli/ui/ansi.rb', line 128

def self.cursor_save
  control('', 's')
end

.cursor_up(n = 1) ⇒ Object

Move the cursor up n lines

Attributes

  • n - number of lines by which to move the cursor up


64
65
66
67
# File 'lib/cli/ui/ansi.rb', line 64

def self.cursor_up(n = 1)
  return '' if n.zero?
  control(n.to_s, 'A')
end

.hide_cursorObject

Hide the cursor


122
123
124
# File 'lib/cli/ui/ansi.rb', line 122

def self.hide_cursor
  control('', "?25l")
end

.next_lineObject

Move to the next line


140
141
142
143
144
# File 'lib/cli/ui/ansi.rb', line 140

def self.next_line
  cmd = cursor_down + control('1', 'G')
  cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
  cmd
end

.previous_lineObject

Move to the previous line


148
149
150
151
152
# File 'lib/cli/ui/ansi.rb', line 148

def self.previous_line
  cmd = cursor_up + control('1', 'G')
  cmd += control('1', 'D') if CLI::UI::OS.current.shift_cursor_on_line_reset?
  cmd
end

.printing_width(str) ⇒ Object

ANSI escape sequences (like x1b[31m) have zero width. when calculating the padding width, we must exclude them. This also implements a basic version of utf8 character width calculation like we could get for real from something like utf8proc.


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/cli/ui/ansi.rb', line 13

def self.printing_width(str)
  zwj = false
  strip_codes(str).codepoints.reduce(0) do |acc, cp|
    if zwj
      zwj = false
      next acc
    end
    case cp
    when 0x200d # zero-width joiner
      zwj = true
      acc
    else
      acc + 1
    end
  end
end

.sgr(params) ⇒ Object


52
53
54
# File 'lib/cli/ui/ansi.rb', line 52

def self.sgr(params)
  control(params.to_s, 'm')
end

.show_cursorObject

Show the cursor


116
117
118
# File 'lib/cli/ui/ansi.rb', line 116

def self.show_cursor
  control('', "?25h")
end

.strip_codes(str) ⇒ Object

Strips ANSI codes from a str

Attributes

  • str - The string from which to strip codes


36
37
38
# File 'lib/cli/ui/ansi.rb', line 36

def self.strip_codes(str)
  str.gsub(/\x1b\[[\d;]+[A-z]|\r/, '')
end