Ncurses_windows

ruby_curses

I’m using a looping enumerator to Tab between windows. The variable win keeps the ‘current window’.. tested by allowing text insert (Space).

require './tab_lib.rb'

def with(obj, &bl) = ( obj.instance_eval &bl if block_given? )

wins = []
(0..2).each { wins << Curses::Window.new(5, 20, 0, 20*it) }

set_col = ->(w, c) { with(w) { attron(Curses.color_pair(c)); box; noutrefresh } }
wins.each {|win| set_col.(win, 20) }

wins = wins.cycle

begin
  win = wins.next
  
  loop {
    set_col.(win, 21)
    
    Curses.doupdate
    
    case key = Curses.getch
    when 'q', 'Q' then break #      q, Q
    when 'n', 'N', 9 #              n, N or Tab
      set_col.(win, 20)
      win = wins.next
    when 't', 'T', ' ' #            t, T or Space
      with(Curses) { setpos(15, 10); echo; curs_set 1 }
      txt = Curses.getstr[..18]
      with(Curses) { setpos(15,0); clrtoeol; noecho; curs_set 0 }
      with(win) { clear; setpos(1,1); addstr(txt); noutrefresh }
    else Lib::log('key: (%s)' % key)
    end
  }

ensure
  Lib.deinit
end

tab_lib requiring curses (ncurses) and logger; initializes ncurses screen; setting up colors; generating two color_pairs and defining a de-init method. It is separated for clarity.

UPDATE 2025-10-20 : In an improved version, I create a subwindow (derwin) to each window. The main window keeps the box (border), and the subwin keeps the text.

Several benefits: I can change color of box without changing color of text; I can addstr without overwriting the box (or using 1,1).

require './tab_lib.rb'

def with(obj, &bl) = ( obj.instance_eval &bl if block_given? )

set_col = ->(w, c) { with(w) { attron(Curses.color_pair(c)); box; noutrefresh } }

wins = [*0..2].map {|n|
  Curses::Window.new(5,20, 0,20*n).then {|w|
    set_col.(w, 20); [w, w.derwin(3,18, 1,1)]
  }
}.cycle

win, sub = wins.next

begin
  
  loop {
    set_col.(win, 21)
    
    Curses.doupdate
    
    case key = Curses.getch
    when 'q', 'Q' then break #      q, Q
    when 'n', 'N', 9 #              n, N or Tab
      set_col.(win, 20)
      win, sub = wins.next
    when 't', 'T', ' ' #            t, T or Space
      with(Curses) { setpos(15, 10); echo; curs_set 1 }
      txt = Curses.getstr[..17]
      with(Curses) { setpos(15,0); clrtoeol; noecho; curs_set 0 }
      with(sub) { clear; addstr(txt); noutrefresh }
    else Lib::log('key: (%s)' % key)
    end
  }

ensure
  Lib.deinit
end