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