rcurses 4.9.4 → 4.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26aa4084a7e60a2da827d96974c2eefa1f5f49c592858148e479857346b92f13
4
- data.tar.gz: 56c0a760d5d082b5927eca4d4d7c3952525d82ed3689f4f0f6ffb253235d8e87
3
+ metadata.gz: 3640945686095502c9c1cd2d3c38223a6af7dfc5c30ac9a7e6c2bcd311c156f2
4
+ data.tar.gz: fee33bc2c07cec00788c402c66707a1cdc0ccd4a3a7d7099a8cb8857bba2091b
5
5
  SHA512:
6
- metadata.gz: a3f1885d497548d271e8c1c85b73eb161edf1f5a73e627175a108180fd9a745dc4eba93af13ec0ad0ad84957ab02b3419fd1233bc5c2ad582a66ad6c2b411227
7
- data.tar.gz: fd6e8f2c3efc3f0169cb41d5901fe002d3350b8c0fd083378555d08be4caa2472312bc2bf23adf5b4e157a6ce54858aaf4c9aae1265d60ef658c2a9002f5d165
6
+ metadata.gz: 330e0732e4996d66e2f1843dfe88fdbd9fc905375cec018ecccd31582f9915a21e2a461528ec1f7c9e7f54d3582a2ff2d29d7aaf20dc6a1f6d61754e688f229f
7
+ data.tar.gz: 6c77f6074af662c578d4df20fccc4a03d1512252a0d71fea3e2e0d2af6ee7327a03fc2fdec90858d49f4c89fd864948e45504310f75c921ce5f68c2c93d251fc
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rcurses'
4
+
5
+ @max_h, @max_w = IO.console.winsize
6
+
7
+ # Start by creating the panes; Format:
8
+ # pane = Rcurses::Pane.new( startx, starty, width, height, fg, bg)
9
+ pane_top = Rcurses::Pane.new( 1, 1, @max_w, 1, 255, 236)
10
+ pane_bottom = Rcurses::Pane.new( 1, @max_h, @max_w, 1, 236, 254)
11
+ pane_left = Rcurses::Pane.new( 2, 3, @max_w/2 - 2, @max_h - 4, 52, nil)
12
+ pane_right = Rcurses::Pane.new(@max_w/2 + 1, 2, @max_w/2, @max_h - 2, 255, 52)
13
+
14
+ pane_left.border = true # Adding a border to the left pane
15
+
16
+ # Add content to the panes
17
+ pane_top.text = Time.now.to_s[0..15].b + " Welcome to the rcurses example program"
18
+ pane_left.text = `ls --color`
19
+ pane_right.text = "Output of free:\n\n" + `free`
20
+ pane_bottom.prompt = "Enter any text and press ENTER: ".b # The prompt text before the user starts writing content
21
+
22
+ pane_top.refresh # This is the order of drawing/refreshing the panes
23
+ pane_left.refresh # ...then the left pane
24
+ pane_right.refresh # ...and the right pane
25
+ pane_bottom.editline # Do not use a refresh before editline
26
+
27
+ # Then create a "pop-up" pane in the middle of the screen
28
+ pane_mid = Rcurses::Pane.new(@max_w/2 - 10, @max_h/2 - 5, 20, 10, 18, 254)
29
+ pane_mid.border = true
30
+ pane_mid.text = "You wrote:" + "\n" + pane_bottom.text.i
31
+ pane_mid.align = "c"
32
+ pane_mid.refresh
33
+
34
+ # Then ask the user to hit ENTER before exiting the program
35
+ pane_bottom.prompt = "Now hit ENTER again "
36
+ pane_bottom.text = ""
37
+ pane_bottom.editline
38
+
39
+ # Reset terminal
40
+ $stdin.cooked!
41
+ $stdin.echo = true
42
+ Rcurses::clear_screen
43
+ Rcurses::Cursor.show
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rcurses'
4
+ include Rcurses::Input
5
+ include Rcurses::Cursor
6
+
7
+ @max_h, @max_w = IO.console.winsize
8
+ @pane = []
9
+ @focused = 3 # Start with pane 3 so that the first keypress focuses back to Pane 0
10
+ Rcurses::Cursor.hide
11
+
12
+ # Start by creating the panes; Format:
13
+ # pane = Rcurses::Pane.new( startx, starty, width, height, fg, bg)
14
+ pane_back = Rcurses::Pane.new( 1, 1, @max_w, @max_h, nil, 236)
15
+ @pane[0] = Rcurses::Pane.new( 4, 4, 20, 10, 236, 254)
16
+ @pane[1] = Rcurses::Pane.new( 30, 10, 16, 12, 232, 132)
17
+ @pane[2] = Rcurses::Pane.new( 8, 20, 30, 20, 136, 54)
18
+ @pane[3] = Rcurses::Pane.new( 50, 30, 24, 10, 206, 24)
19
+
20
+ pane_back.text = "PRESS ANY KEY TO SHIFT FOCUS. PRESS 'ESC' TO QUIT."
21
+ @pane.each_index { |i| @pane[i].text = "This is pane " + i.to_s }
22
+ pane_back.full_refresh
23
+ @pane.each_index { |i| @pane[i].refresh }
24
+
25
+ input = ''
26
+ while input != 'ESC'
27
+ input = getchr
28
+ pane_back.full_refresh
29
+ @focused += 1
30
+ @focused = 0 if @focused == @pane.size
31
+ @pane.each_index {|i| @pane[i].border = false}
32
+ @pane.each_index {|i| @pane[i].full_refresh}
33
+ @pane[@focused].border = true
34
+ @pane[@focused].full_refresh
35
+ end
36
+
37
+ # Always end an application with these lines:
38
+ $stdin.cooked!
39
+ $stdin.echo = true
40
+ Rcurses.clear_screen
41
+ Rcurses::Cursor.show
42
+
@@ -0,0 +1,48 @@
1
+ module Rcurses
2
+ module Cursor
3
+ # Terminal cursor movement ANSI codes (inspired by https://github.com/piotrmurach/tty-cursor)
4
+ module_function
5
+ ESC = "\e".freeze
6
+ CSI = "\e[".freeze
7
+ def save; print(Gem.win_platform? ? CSI + 's' : ESC + '7'); end # Save current position
8
+ def restore; print(Gem.win_platform? ? CSI + 'u' : ESC + '8'); end # Restore cursor position
9
+ def pos # Query cursor current position
10
+ res = ''
11
+ $stdin.raw do |stdin|
12
+ $stdout << CSI + '6n' # The actual ANSI get-position
13
+ $stdout.flush
14
+ while (c = stdin.getc) != 'R'
15
+ res << c if c
16
+ end
17
+ end
18
+ m = res.match(/(?<row>\d+);(?<col>\d+)/)
19
+ return m[:row].to_i, m[:col].to_i
20
+ end
21
+ def rowget
22
+ row, _col = pos
23
+ row
24
+ end
25
+ def colget
26
+ _row, col = pos
27
+ col
28
+ end
29
+ def set(r = 1, c = 1); print(CSI + "#{r}d"); print(CSI + "#{c}G"); end # Set cursor position to Row, Col (y,x)
30
+ def up(n = 1); print(CSI + "#{(n)}A"); end # Move cursor up by n
31
+ def down(n = 1); print(CSI + "#{(n)}B"); end # Move the cursor down by n
32
+ def left(n = 1); print(CSI + "#{n}D"); end # Move the cursor backward by n
33
+ def right(n = 1); print(CSI + "#{n}C"); end # Move the cursor forward by n
34
+ def col(c = 1); print(CSI + "#{c}G"); end # Cursor moves to nth position horizontally in the current line
35
+ def row(r = 1); print(CSI + "#{r}d"); end # Cursor moves to the nth position vertically in the current column
36
+ def next_line; print(CSI + 'E' + CSI + "1G"); end # Move cursor down to beginning of next line
37
+ def prev_line; print(CSI + 'A' + CSI + "1G"); end # Move cursor up to beginning of previous line
38
+ def clear_char(n = 1); print(CSI + "#{n}X"); end # Erase n characters from the current cursor position
39
+ def clear_line; print(CSI + '2K' + CSI + "1G"); end # Erase the entire current line and return to beginning of the line
40
+ def clear_line_before; print(CSI + '1K'); end # Erase from the beginning of the line up to and including the current cursor position.
41
+ def clear_line_after; print(CSI + '0K'); end # Erase from the current position (inclusive) to the end of the line
42
+ def clear_screen_down; print(CSI + 'J'); end # Clear screen down from current row
43
+ def scroll_up; print(ESC + 'M'); end # Scroll display up one line
44
+ def scroll_down; print(ESC + 'D'); end # Scroll display down one line
45
+ def hide; print(CSI + '?25l'); end # Scroll display down one line
46
+ def show; print(CSI + '?25h'); end # Scroll display down one line
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ module Rcurses
2
+ def self.clear_screen
3
+ # ANSI code \e[2J clears the screen, and \e[H moves the cursor to the top left.
4
+ print "\e[2J\e[H"
5
+ end
6
+ end
@@ -0,0 +1,127 @@
1
+ module Rcurses
2
+ module Input
3
+ def getchr(t = nil, flush: true)
4
+ begin
5
+ # 1) Read a byte (with optional timeout)
6
+ begin
7
+ c = t ? Timeout.timeout(t) { $stdin.getch } : $stdin.getch
8
+ rescue Timeout::Error
9
+ return nil
10
+ end
11
+
12
+ # 2) If it's ESC, grab any quick trailing bytes
13
+ seq = c
14
+ if c == "\e"
15
+ if IO.select([$stdin], nil, nil, 0.05)
16
+ begin
17
+ seq << $stdin.read_nonblock(16)
18
+ rescue IO::WaitReadable, EOFError
19
+ end
20
+ end
21
+ end
22
+
23
+ # 3) Single ESC alone
24
+ return "ESC" if seq == "\e"
25
+
26
+ # 4) Shift‑TAB
27
+ return "S-TAB" if seq == "\e[Z"
28
+
29
+ # 5) Legacy single‑char shift‑arrows (your old working ones)
30
+ case seq
31
+ when "\e[a" then return "S-UP"
32
+ when "\e[b" then return "S-DOWN"
33
+ when "\e[c" then return "S-RIGHT"
34
+ when "\e[d" then return "S-LEFT"
35
+ end
36
+
37
+ # 6) CSI style shift‑arrows (e.g. ESC [1;2A )
38
+ if m = seq.match(/\A\e\[\d+;2([ABCD])\z/)
39
+ return { 'A' => "S-UP", 'B' => "S-DOWN", 'C' => "S-RIGHT", 'D' => "S-LEFT" }[m[1]]
40
+ end
41
+
42
+ # 7) Plain arrows
43
+ if m = seq.match(/\A\e\[([ABCD])\z/)
44
+ return { 'A' => "UP", 'B' => "DOWN", 'C' => "RIGHT", 'D' => "LEFT" }[m[1]]
45
+ end
46
+
47
+ # 8) CSI + '~' sequences (Ins, Del, Home, End, PgUp, PgDn, F5-F12)
48
+ if seq.start_with?("\e[") && seq.end_with?("~")
49
+ num = seq[/\d+(?=~)/].to_i
50
+ return case num
51
+ when 1, 7 then "HOME"
52
+ when 2 then "INS"
53
+ when 3 then "DEL"
54
+ when 4, 8 then "END"
55
+ when 5 then "PgUP"
56
+ when 6 then "PgDOWN"
57
+ when 15 then "F5"
58
+ when 17 then "F6"
59
+ when 18 then "F7"
60
+ when 19 then "F8"
61
+ when 20 then "F9"
62
+ when 21 then "F10"
63
+ when 23 then "F11"
64
+ when 24 then "F12"
65
+ else ""
66
+ end
67
+ end
68
+
69
+ # 9) SS3 function keys F1-F4
70
+ if seq.start_with?("\eO") && seq.length == 3
71
+ return case seq[2]
72
+ when 'P' then "F1"
73
+ when 'Q' then "F2"
74
+ when 'R' then "F3"
75
+ when 'S' then "F4"
76
+ else ""
77
+ end
78
+ end
79
+
80
+ # 10) Single / Ctrl-char mappings
81
+ return case seq
82
+ when "\r", "\n" then "ENTER"
83
+ when "\t" then "TAB"
84
+ when "\u007F", "\b" then "BACK"
85
+ when "\u0000" then "C-SPACE"
86
+ when "\u0001" then "C-A"
87
+ when "\u0002" then "C-B"
88
+ when "\u0003" then "C-C"
89
+ when "\u0004" then "C-D"
90
+ when "\u0005" then "C-E"
91
+ when "\u0006" then "C-F"
92
+ when "\u0007" then "C-G"
93
+ when "\u0008" then "C-H"
94
+ when "\u000B" then "C-K"
95
+ when "\u000C" then "C-L"
96
+ when "\u000D" then "C-M"
97
+ when "\u000E" then "C-N"
98
+ when "\u000F" then "C-O"
99
+ when "\u0010" then "C-P"
100
+ when "\u0011" then "C-Q"
101
+ when "\u0012" then "C-R"
102
+ when "\u0013" then "C-S"
103
+ when "\u0014" then "C-T"
104
+ when "\u0015" then "C-U"
105
+ when "\u0016" then "C-V"
106
+ when "\u0018" then "C-X"
107
+ when "\u0019" then "C-Y"
108
+ when "\u001A" then "C-Z"
109
+ when "\u0017" then "WBACK"
110
+ when /\A[[:print:]]\z/ then seq
111
+ else ""
112
+ end
113
+ ensure
114
+ if flush
115
+ while IO.select([$stdin], nil, nil, 0)
116
+ begin
117
+ $stdin.read_nonblock(4096)
118
+ rescue IO::WaitReadable, EOFError
119
+ break
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+