curses-extension 1.1.0
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 +7 -0
- data/lib/curses-extension.rb +91 -0
- data/lib/curses-template.rb +221 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a2491e7b9c8860078fcf3f353bdada531985f9a28308d661d6f7e752a9a283b2
|
4
|
+
data.tar.gz: 91e2e96db7fcda0247d02c09a33f2ca2fe28765bb0c9cf418c44bd98a5b7097b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 69aa81c3236cf57c80adc460fdc51d5b12b13685b8c702584e94f937e42552e6390b65bf3f6b4a46e6ce92cf51e7f8b7dd5367f5fb83448dc6b52c8892f1bc18
|
7
|
+
data.tar.gz: d405e32770f13d430e5c710240111affc6666916f2bc60505c9856f4c1a816a8fe5bdb43ee5bd1656969fc9c940398d3ffac92b7bde098d3d5c3215774cba848
|
@@ -0,0 +1,91 @@
|
|
1
|
+
class Curses::Window # CLASS EXTENSION
|
2
|
+
# General extensions (see https://github.com/isene/Ruby-Curses-Class-Extension)
|
3
|
+
attr_accessor :color, :fg, :bg, :attr, :update
|
4
|
+
# Set self.color for an already defined color pair such as: init_pair(1, 255, 3)
|
5
|
+
# The color pair is defined like this: init_pair(index, foreground, background)
|
6
|
+
# self.fg is set for the foreground color (and is used if self.color is not set)
|
7
|
+
# self.bg is set for the background color (and is used if self.color is not set)
|
8
|
+
# self.attr is set for text attributes like Curses::A_BOLD
|
9
|
+
def clr # Clears the whole window
|
10
|
+
self.setpos(0, 0)
|
11
|
+
self.maxy.times {self.deleteln()}
|
12
|
+
self.refresh
|
13
|
+
self.setpos(0, 0)
|
14
|
+
end
|
15
|
+
def clr_to_cur_line
|
16
|
+
l = self.cury
|
17
|
+
self.setpos(0, 0)
|
18
|
+
l.times {self.deleteln()}
|
19
|
+
self.refresh
|
20
|
+
end
|
21
|
+
def clr_from_cur_line
|
22
|
+
l = self.cury
|
23
|
+
(self.maxy - l).times {self.deleteln()}
|
24
|
+
self.refresh
|
25
|
+
self.setpos(l, 0)
|
26
|
+
end
|
27
|
+
def fill # Fill window with color as set by self.color (or self.bg if not set)
|
28
|
+
self.setpos(0, 0)
|
29
|
+
self.fill_from_cur_pos
|
30
|
+
end
|
31
|
+
def fill_to_cur_pos # Fills the window up to current line
|
32
|
+
x = self.curx
|
33
|
+
y = self.cury
|
34
|
+
self.setpos(0, 0)
|
35
|
+
blank = " " * self.maxx
|
36
|
+
if self.color == nil
|
37
|
+
self.bg = 0 if self.bg == nil
|
38
|
+
self.fg = 255 if self.fg == nil
|
39
|
+
init_pair(self.fg, self.fg, self.bg)
|
40
|
+
y.times {self.attron(color_pair(self.fg)) {self << blank}}
|
41
|
+
else
|
42
|
+
y.times {self.attron(color_pair(self.color)) {self << blank}}
|
43
|
+
end
|
44
|
+
self.refresh
|
45
|
+
self.setpos(y, x)
|
46
|
+
end
|
47
|
+
def fill_from_cur_pos # Fills the rest of the window from current line
|
48
|
+
x = self.curx
|
49
|
+
y = self.cury
|
50
|
+
self.setpos(y, 0)
|
51
|
+
blank = " " * self.maxx
|
52
|
+
if self.color == nil
|
53
|
+
self.bg = 0 if self.bg == nil
|
54
|
+
self.fg = 255 if self.fg == nil
|
55
|
+
init_pair(self.fg, self.fg, self.bg)
|
56
|
+
self.maxy.times {self.attron(color_pair(self.fg)) {self << blank}}
|
57
|
+
else
|
58
|
+
self.maxy.times {self.attron(color_pair(self.color)) {self << blank}}
|
59
|
+
end
|
60
|
+
self.refresh
|
61
|
+
self.setpos(y, x)
|
62
|
+
end
|
63
|
+
def p(text) # Puts text to window
|
64
|
+
self.attr = 0 if self.attr == nil
|
65
|
+
if self.color == nil
|
66
|
+
self.bg = 0 if self.bg == nil
|
67
|
+
self.fg = 255 if self.fg == nil
|
68
|
+
init_pair(self.fg, self.fg, self.bg)
|
69
|
+
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
70
|
+
else
|
71
|
+
self.attron(color_pair(self.color) | self.attr) { self << text }
|
72
|
+
end
|
73
|
+
self.refresh
|
74
|
+
end
|
75
|
+
def pclr(text) # Puts text to window and clears the rest of the window
|
76
|
+
self.p(text)
|
77
|
+
self.clr_from_cur_line
|
78
|
+
end
|
79
|
+
def paclr(fg, bg, attr, text) # Puts text to window with full set of attributes and clears rest of window
|
80
|
+
self.paclr(fg, bg, attr, text)
|
81
|
+
self.clr_from_cur_line
|
82
|
+
end
|
83
|
+
def pa(fg, bg, attr, text) # Puts text to window with full set of attributes
|
84
|
+
self.fg = fg
|
85
|
+
self.bg = bg
|
86
|
+
self.attr = attr
|
87
|
+
init_pair(self.fg, self.fg, self.bg)
|
88
|
+
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
89
|
+
self.refresh
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# This is a basic template for my Curses applications. Feel free to use.
|
5
|
+
#
|
6
|
+
# It is an example of a basic curses application with 4 windows like this:
|
7
|
+
#
|
8
|
+
# +-------------------------------+
|
9
|
+
# | @w_t |
|
10
|
+
# +---------------+---------------+
|
11
|
+
# | | |
|
12
|
+
# | @w_l | @w_r |
|
13
|
+
# | | |
|
14
|
+
# | | |
|
15
|
+
# +---------------+---------------+
|
16
|
+
# | @w_b |
|
17
|
+
# +-------------------------------+
|
18
|
+
|
19
|
+
require 'io/console'
|
20
|
+
require 'curses'
|
21
|
+
include Curses
|
22
|
+
|
23
|
+
Curses.init_screen
|
24
|
+
Curses.start_color
|
25
|
+
Curses.curs_set(0)
|
26
|
+
Curses.noecho
|
27
|
+
Curses.cbreak
|
28
|
+
Curses.stdscr.keypad = true
|
29
|
+
|
30
|
+
class Curses::Window # CLASS EXTENSION
|
31
|
+
# General extensions (see https://github.com/isene/Ruby-Curses-Class-Extension)
|
32
|
+
attr_accessor :color, :fg, :bg, :attr, :update
|
33
|
+
# Set self.color for an already defined color pair such as: init_pair(1, 255, 3)
|
34
|
+
# The color pair is defined like this: init_pair(index, foreground, background)
|
35
|
+
# self.fg is set for the foreground color (and is used if self.color is not set)
|
36
|
+
# self.bg is set for the background color (and is used if self.color is not set)
|
37
|
+
# self.attr is set for text attributes like Curses::A_BOLD
|
38
|
+
def clr # Clears the whole window
|
39
|
+
self.setpos(0, 0)
|
40
|
+
self.maxy.times {self.deleteln()}
|
41
|
+
self.refresh
|
42
|
+
self.setpos(0, 0)
|
43
|
+
end
|
44
|
+
def clr_to_cur_line
|
45
|
+
l = self.cury
|
46
|
+
self.setpos(0, 0)
|
47
|
+
l.times {self.deleteln()}
|
48
|
+
self.refresh
|
49
|
+
end
|
50
|
+
def clr_from_cur_line
|
51
|
+
l = self.cury
|
52
|
+
(self.maxy - l).times {self.deleteln()}
|
53
|
+
self.refresh
|
54
|
+
self.setpos(l, 0)
|
55
|
+
end
|
56
|
+
def fill # Fill window with color as set by self.color (or self.bg if not set)
|
57
|
+
self.setpos(0, 0)
|
58
|
+
self.fill_from_cur_pos
|
59
|
+
end
|
60
|
+
def fill_to_cur_pos # Fills the window up to current line
|
61
|
+
x = self.curx
|
62
|
+
y = self.cury
|
63
|
+
self.setpos(0, 0)
|
64
|
+
blank = " " * self.maxx
|
65
|
+
if self.color == nil
|
66
|
+
self.bg = 0 if self.bg == nil
|
67
|
+
self.fg = 255 if self.fg == nil
|
68
|
+
init_pair(self.fg, self.fg, self.bg)
|
69
|
+
y.times {self.attron(color_pair(self.fg)) {self << blank}}
|
70
|
+
else
|
71
|
+
y.times {self.attron(color_pair(self.color)) {self << blank}}
|
72
|
+
end
|
73
|
+
self.refresh
|
74
|
+
self.setpos(y, x)
|
75
|
+
end
|
76
|
+
def fill_from_cur_pos # Fills the rest of the window from current line
|
77
|
+
x = self.curx
|
78
|
+
y = self.cury
|
79
|
+
self.setpos(y, 0)
|
80
|
+
blank = " " * self.maxx
|
81
|
+
if self.color == nil
|
82
|
+
self.bg = 0 if self.bg == nil
|
83
|
+
self.fg = 255 if self.fg == nil
|
84
|
+
init_pair(self.fg, self.fg, self.bg)
|
85
|
+
self.maxy.times {self.attron(color_pair(self.fg)) {self << blank}}
|
86
|
+
else
|
87
|
+
self.maxy.times {self.attron(color_pair(self.color)) {self << blank}}
|
88
|
+
end
|
89
|
+
self.refresh
|
90
|
+
self.setpos(y, x)
|
91
|
+
end
|
92
|
+
def p(text) # Puts text to window
|
93
|
+
self.attr = 0 if self.attr == nil
|
94
|
+
if self.color == nil
|
95
|
+
self.bg = 0 if self.bg == nil
|
96
|
+
self.fg = 255 if self.fg == nil
|
97
|
+
init_pair(self.fg, self.fg, self.bg)
|
98
|
+
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
99
|
+
else
|
100
|
+
self.attron(color_pair(self.color) | self.attr) { self << text }
|
101
|
+
end
|
102
|
+
self.refresh
|
103
|
+
end
|
104
|
+
def pclr(text) # Puts text to window and clears the rest of the window
|
105
|
+
self.p(text)
|
106
|
+
self.clr_from_cur_line
|
107
|
+
end
|
108
|
+
def paclr(fg, bg, attr, text) # Puts text to window with full set of attributes and clears rest of window
|
109
|
+
self.paclr(fg, bg, attr, text)
|
110
|
+
self.clr_from_cur_line
|
111
|
+
end
|
112
|
+
def pa(fg, bg, attr, text) # Puts text to window with full set of attributes
|
113
|
+
self.fg = fg
|
114
|
+
self.bg = bg
|
115
|
+
self.attr = attr
|
116
|
+
init_pair(self.fg, self.fg, self.bg)
|
117
|
+
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
118
|
+
self.refresh
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def getchr # PROCESS KEY PRESSES
|
123
|
+
c = STDIN.getch(min: 0, time: 3)
|
124
|
+
case c
|
125
|
+
when "\e" # ANSI escape sequences
|
126
|
+
case $stdin.getc
|
127
|
+
when '[' # CSI
|
128
|
+
case $stdin.getc
|
129
|
+
when 'A' then chr = "UP"
|
130
|
+
when 'B' then chr = "DOWN"
|
131
|
+
when 'C' then chr = "RIGHT"
|
132
|
+
when 'D' then chr = "LEFT"
|
133
|
+
when 'Z' then chr = "S-TAB"
|
134
|
+
when '2' then chr = "INS" ; STDIN.getc
|
135
|
+
when '3' then chr = "DEL" ; STDIN.getc
|
136
|
+
when '5' then chr = "PgUP" ; STDIN.getc
|
137
|
+
when '6' then chr = "PgDOWN" ; STDIN.getc
|
138
|
+
when '7' then chr = "HOME" ; STDIN.getc
|
139
|
+
when '8' then chr = "END" ; STDIN.getc
|
140
|
+
end
|
141
|
+
end
|
142
|
+
when "", "" then chr = "BACK"
|
143
|
+
when "" then chr = "WBACK"
|
144
|
+
when "" then chr = "LDEL"
|
145
|
+
when "" then chr = "C-T"
|
146
|
+
when "\r" then chr = "ENTER"
|
147
|
+
when "\t" then chr = "TAB"
|
148
|
+
when /./ then chr = c
|
149
|
+
end
|
150
|
+
return chr
|
151
|
+
end
|
152
|
+
|
153
|
+
def main_getkey # GET KEY FROM USER
|
154
|
+
chr = getchr
|
155
|
+
case chr
|
156
|
+
when '?' # Show helptext in right window
|
157
|
+
# Add code to show help text here
|
158
|
+
when 'UP' # Examples of moving up and down in a window
|
159
|
+
@index = @index <= @min_index ? @max_index : @index - 1
|
160
|
+
when 'DOWN'
|
161
|
+
@index = @index >= @max_index ? @min_index : @index + 1
|
162
|
+
when 'PgUP'
|
163
|
+
@index -= @w_l.maxy - 2
|
164
|
+
@index = @min_index if @index < @min_index
|
165
|
+
when 'PgDOWN'
|
166
|
+
@index += @w_l.maxy - 2
|
167
|
+
@index = @max_index if @index > @max_index
|
168
|
+
when 'HOME'
|
169
|
+
@index = @min_index
|
170
|
+
when 'END'
|
171
|
+
@index = @max_index
|
172
|
+
when 'l'
|
173
|
+
# ...etc
|
174
|
+
when 'r'
|
175
|
+
@break = true
|
176
|
+
when 'q' # Exit
|
177
|
+
exit 0
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# TOP WINDOW FUNCTIONS
|
182
|
+
|
183
|
+
# BOTTOM WINDOW FUNCTIONS
|
184
|
+
|
185
|
+
# LEFT WINDOW FUNCTIONS
|
186
|
+
|
187
|
+
# RIGHT WINDOW FUNCTIONS
|
188
|
+
|
189
|
+
|
190
|
+
# MAIN PROGRAM
|
191
|
+
loop do # OUTER LOOP - (catching refreshes via 'r')
|
192
|
+
@break = false # Initialize @break variable (set if user hits 'r')
|
193
|
+
begin # Create the four windows/panels
|
194
|
+
maxx = Curses.cols
|
195
|
+
exit if maxx < @w_l_width
|
196
|
+
maxy = Curses.lines
|
197
|
+
# Curses::Window.new(h,w,y,x)
|
198
|
+
@w_t = Curses::Window.new(1, maxx, 0, 0)
|
199
|
+
@w_b = Curses::Window.new(1, maxx, maxy - 1, 0)
|
200
|
+
@w_l = Curses::Window.new(maxy - 2, maxx / 2, 1, 0)
|
201
|
+
@w_r = Curses::Window.new(maxy - 2, maxx / 2, 1, maxx / 2)
|
202
|
+
loop do # INNER, CORE LOOP
|
203
|
+
# Top window (info line)
|
204
|
+
|
205
|
+
# Bottom window (command line)
|
206
|
+
|
207
|
+
# Left window
|
208
|
+
|
209
|
+
# Right window
|
210
|
+
|
211
|
+
main_getkey # Get key from user
|
212
|
+
|
213
|
+
break if @break # Break to outer loop, redrawing windows, if user hit 'r'
|
214
|
+
break if Curses.cols != maxx or Curses.lines != maxy # break on terminal resize
|
215
|
+
end
|
216
|
+
ensure # On exit: close curses, clear terminal
|
217
|
+
close_screen
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# vim: set sw=2 sts=2 et fdm=syntax fdn=2 fcs=fold\:\ :
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: curses-extension
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Geir Isene
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-09-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: curses
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.3.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.3.2
|
33
|
+
description: "The attributes and functions included in this gem:\n\n Attribute |
|
34
|
+
Description\n ----------|--------------------------------------------------------\n
|
35
|
+
\ color | Set the windows color to an already initiated color pair with init_pair(index,
|
36
|
+
forground, backround)\n fg | Foreground color for window (0-255)\n bg |
|
37
|
+
Background color for window (0-255)\n attr | Attributes for window (such as
|
38
|
+
Curses::A_BOLD) - string with \"\\|\" (such as Curses::A_BOLD \\| Curses::A_UNDERLINE)\n
|
39
|
+
\ update | Whether to update the window on the next refresh\n \n Function |
|
40
|
+
Description\n --------------------|--------------------------------------------------------\n
|
41
|
+
\ clr | Clears window without flicker (win.clear flickers)\n clr_to_cur_pos
|
42
|
+
\ | Clears the window up to the current line\n clr_from_cur_pos | Clears
|
43
|
+
the rest of the window after the current line\n fill | Fill window
|
44
|
+
with color as set by :color ( or :bg if not :color is set)\n fill_to_cur_pos |
|
45
|
+
Fill the window up to the current line\n fill_from_cur_pos | Fill the rest of
|
46
|
+
the window after the current line\n p(text) | Write text to window
|
47
|
+
with color or fg/bg and attributes (will handle the exceptions if no colors are
|
48
|
+
set)\n pclr(text) | As `p(text)` but also clears the rest of the window\n
|
49
|
+
\ pa(fg,bg,attr,text) | Write text to window with specified fg, bg and attribute(s)\n
|
50
|
+
\ paclr(text) | As pa(text) but also clears the rest of the window\n \n
|
51
|
+
\ The curses_template.rb includes the class extension and serves as the basis for
|
52
|
+
my curses applications."
|
53
|
+
email: g@isene.com
|
54
|
+
executables: []
|
55
|
+
extensions: []
|
56
|
+
extra_rdoc_files: []
|
57
|
+
files:
|
58
|
+
- lib/curses-extension.rb
|
59
|
+
- lib/curses-template.rb
|
60
|
+
homepage: https://isene.com/
|
61
|
+
licenses:
|
62
|
+
- Unlicense
|
63
|
+
metadata:
|
64
|
+
source_code_uri: https://github.com/isene/Ruby-Curses-Class-Extension
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubygems_version: 3.1.2
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Extending the Ruby Curses module with some obvious functionality
|
84
|
+
test_files: []
|