class Reline::ANSI
def self.cursor_pos
def self.cursor_pos begin res = +'' m = nil @@input.raw do |stdin| @@output << "\e[6n" @@output.flush loop do c = stdin.getc next if c.nil? res << c m = res.match(/\e\[(?<row>\d+);(?<column>\d+)R/) break if m end (m.pre_match + m.post_match).chars.reverse_each do |ch| stdin.ungetc ch end end column = m[:column].to_i - 1 row = m[:row].to_i - 1 rescue Errno::ENOTTY begin buf = @@output.pread(@@output.pos, 0) row = buf.count("\n") column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0 rescue Errno::ESPIPE # Just returns column 1 for ambiguous width because this I/O is not # tty and can't seek. row = 0 column = 1 end end Reline::CursorPos.new(column, row) end