3

There has absolutely got to be a better way to do this.

temp_file ||= Tempfile.new()
system("stty -echo; tput u7; read -d R x; stty echo; echo ${x#??} > #{temp_file.path}")
temp_file.gets.chomp.split(';').map(&:to_i)

Basically, I'm running the bash script from this question in a sub process and then reading the output from a redirected file.

Without using C or any gems (stdlib okay) what is a better way to do this? Cross compatibility is not of great concern.

Community
  • 1
  • 1
prater
  • 2,330
  • 1
  • 17
  • 15

3 Answers3

4

Here is a pure ruby implementation of getting cursor position:

require 'io/console'

class Cursor
  class << self
    def pos
      res = ''
      $stdin.raw do |stdin|
        $stdout << "\e[6n"
        $stdout.flush
        while (c = stdin.getc) != 'R'
          res << c if c
        end
      end
      m = res.match /(?<row>\d+);(?<column>\d+)/
      { row: Integer(m[:row]), column: Integer(m[:column]) }
    end
  end
end

puts Cursor.pos  #=> {:row=>25, :column=>1}

tput u7 was replaced with echoing \e[6n to $stdout. It is probably less portable but helps us to use only ruby code.

egwspiti
  • 957
  • 5
  • 10
2

curses is in the stdlib, but it's a mess.

Theo
  • 131,503
  • 21
  • 160
  • 205
  • It's for a multi-line "status bar" type thing, so I'm trying not to use the full on curses-lib. I can get this done without it, it's just. so. ugly. – prater Apr 27 '11 at 20:46
0

https://github.com/eclubb/ncurses-ruby

You could try this in Ruby. It seems to have the curX and curY stuff that you need.

rmk
  • 4,395
  • 3
  • 27
  • 32