Skip to content

Instantly share code, notes, and snippets.

@yamaimo
Last active June 23, 2021 01:44
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yamaimo/fdb6235cc25f434bec60 to your computer and use it in GitHub Desktop.
Save yamaimo/fdb6235cc25f434bec60 to your computer and use it in GitHub Desktop.
Curses for Ruby
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
Curses.init_screen
text = "TEXT"
attrs = {
normal: Curses::A_NORMAL,
standout: Curses::A_STANDOUT,
underline: Curses::A_UNDERLINE,
reverse: Curses::A_REVERSE,
blink: Curses::A_BLINK}
Curses.setpos(0, 0)
Curses.addstr('-' * 48)
Curses.setpos(1, 0)
Curses.addstr(sprintf("%-10s %-32s %s", "attribute", "value", "view"))
Curses.setpos(2, 0)
Curses.addstr('-' * 48)
attrs.each_with_index do |(name, attr), i|
Curses.setpos(i + 3, 0)
Curses.addstr(sprintf("%-10s %032b ", name.to_s, attr))
Curses.attron(attr)
Curses.addstr(text)
Curses.attroff(attr)
end
Curses.setpos(attrs.size + 3, 0)
Curses.addstr('-' * 48)
Curses.refresh
Curses.getch
Curses.close_screen
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
Curses.init_screen
Curses.cbreak
Curses.stdscr.refresh
win = Curses::Window.new(5, 10, 0, 0)
win.setpos(2, 4)
win.addstr("Hi")
win.box('|', '-')
win.refresh
Curses.getch
win.move(2, 2)
win.refresh
Curses.getch
Curses.close_screen
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
Curses.init_screen
Curses.cbreak
Curses.stdscr.refresh
win = Curses::Window.new(5, 10, 0, 0)
win.setpos(2, 4)
win.addstr("Hi")
win.box('|', '-')
win.refresh
Curses.getch
Curses.stdscr.refresh
win.move(2, 2)
win.refresh
Curses.getch
Curses.close_screen
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
include Curses
init_screen
start_color
use_default_colors
setpos(0, 0)
if has_colors?
addstr "Terminal has colors."
else
addstr "Terminal does not have colors."
end
setpos(1, 0)
if can_change_color?
addstr "Terminal can change color."
else
addstr "Terminal can not change color."
end
lines = 2
rows = 6
p_idx = 0
colors.times do |fg_idx|
setpos(lines + fg_idx, 0)
attrset(A_NORMAL)
addstr sprintf("fg_idx:%02d (%4d, %4d, %4d)", fg_idx, *color_content(fg_idx))
colors.times do |bg_idx|
attrset(A_NORMAL)
addch " "
init_pair(p_idx, fg_idx, bg_idx)
attrset(color_pair(p_idx)|A_NORMAL)
addstr "Hello"
p_idx = (p_idx + 1) % color_pairs
end
end
refresh
getch
Curses.timeout = 0 # set non-blocking
bg_idx = pair_content(1).slice(1)
done = false
until(done)
colors.times do |fg_idx|
init_pair(1, fg_idx, bg_idx)
refresh
ch = getch
unless ch.nil?
done = true
break
end
sleep 0.1
end
end
close_screen
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
Curses.init_screen
Curses.cbreak
screen = Curses.stdscr
screen.refresh
win = Curses::Window.new(5, 10, 0, 0)
win.setpos(2, 4)
win.addstr("Hi")
win.box('|', '-')
win.refresh
Curses.getch
screen.move(screen.begy, screen.begx)
screen.refresh
win.move(2, 2)
win.refresh
Curses.getch
Curses.close_screen
#!/usr/bin/env ruby
# coding: utf-8
require "curses"
include Curses
def show_message(message)
width = message.length + 6
win = Window.new(5, width, (lines - 5) / 2, (cols - width) / 2)
win.box('|', '-')
win.setpos(2, 3)
win.addstr(message)
win.refresh
win.getch
win.close
end
init_screen
begin
crmode
# show_message("Hit any key")
setpos((lines - 5) / 2, (cols - 10) / 2)
addstr("Hit any key")
refresh
getch
show_message("Hello, World!")
refresh
ensure
close_screen
end
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
require 'timeout'
class Curses::Window
def touch
self.move(self.begy, self.begx)
end
def touch_noutrefresh
self.touch
self.noutrefresh
end
end
Curses.init_screen
Curses.cbreak
screen = Curses.stdscr
class << screen
def show_message(message)
self.setpos(0, 0)
self.clrtoeol
self.addstr(message)
end
end
prompt_message = "Input any string!"
input_dialog = Curses::Window.new(
4, prompt_message.size + 4,
(Curses.lines - 4) / 2, (Curses.cols - prompt_message.size - 4) /2)
input_dialog.box('|', '-')
input_dialog.setpos(1, 2)
input_dialog.addstr(prompt_message)
class << input_dialog
def get_input
self.setpos(2, 2)
Curses.echo
Curses.curs_set(1)
str = self.getstr
if (str == "exit") || (str == "quit")
str = nil
else
# clear input string.
# (and recover box.)
self.setpos(2, 2)
self.clrtoeol
self.box('|', '-')
end
Curses.noecho
Curses.curs_set(0)
return str
end
end
# main loop
loop do
screen.show_message("Input 'exit' or 'quit' to exit.")
screen.touch_noutrefresh
input_dialog.touch_noutrefresh
Curses.doupdate
input = input_dialog.get_input
if input.nil?
break
end
screen.show_message("Input 'q' to change string.")
word_win = Curses::Window.new(
1, input.size,
0, (Curses.cols - input.size) / 2)
word_win.addstr(input)
line = 0
speed = 0
acc = 0.4
rate = - 0.8
done = false
until(done)
screen.touch_noutrefresh
word_win.noutrefresh
Curses.doupdate
begin
timeout(0.05) do
ch = Curses.getch
if ch == "q"
done = true
end
sleep
end
rescue TimeoutError
# ignore
end
line = (line + speed).ceil
speed += acc
if (line >= Curses.lines)
line = Curses.lines - 1
speed *= rate
end
word_win.move(line, word_win.begx)
end
word_win.close
end
Curses.close_screen
#!/usr/bin/env ruby
# coding: utf-8
require 'curses'
class Curses::Window
# タッチ更新
def touch
self.move(self.begy, self.begx)
end
end
Curses.init_screen
Curses.cbreak
screen = Curses.stdscr
message = "Hello"
windows = Array.new
10.times do |i|
win = Curses::Window.new(3, 10, i+1, i+1)
win.setpos(1, (10 - message.size) / 2)
win.addstr(message)
win.box('|', '-')
windows.push win
end
# refresh
screen.setpos(0, 0)
screen.addstr("refresh")
screen.refresh
Curses.getch
windows.each do |win|
win.refresh
sleep 0.1
end
Curses.getch
# noutrefresh + doupdate
screen.clear
screen.setpos(0, 0)
screen.addstr("noutrefresh + doupdate")
screen.refresh
Curses.getch
windows.each do |win|
win.touch
win.noutrefresh
sleep 0.1
end
Curses.doupdate
Curses.getch
windows.map(&:close)
Curses.close_screen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment