rcurses 0.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -2
  3. data/lib/rcurses.rb +474 -472
  4. metadata +5 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0a752aa8312d1c3b9ec5683f490da7666ca4e82599d7157105fcdfcfa7ce526
4
- data.tar.gz: a86545340dd98c390fca814a0e5d5521fc3def15ec56ba9c13d6ab12766109ee
3
+ metadata.gz: b705e1f22c190243e1564cd7b56018b152673e80f49ebfba5e7514ae1ebdc2c8
4
+ data.tar.gz: 8caf8faac21c53ef15c3e1845859475b0faadba9524fa960de7b617a4f074f69
5
5
  SHA512:
6
- metadata.gz: '038fb306d29aab4f30fa355a637cbd2338970458432fddca29f2e92faca3404a670b4641220e72cffd7f821bf6514c3f0838d7a764a6899eb00b8d84cd502120'
7
- data.tar.gz: 51e91e08b86d542d9b5d15050218decc2f0ed0debbe1d9c9eaacc2033b2b9c1cf0dd9ec39f27003670298590639bc5c6b66a730057e1f0af491a9858ab2f2e25
6
+ metadata.gz: afbdf8595e9a4d5e8d32e6b229afae6886370f87e4692602a37f6beb501f898b4755cb84c9255ade3f252a850ee836df2691671af30623bbd952e5c3df1baa30
7
+ data.tar.gz: eb3093ac60c4452b5c11f9174b7219f359ac93613bc36da413002521d6ec5344bcaf0904a1f309907b76c749d97644b2490262b9a2f953202ea701b6db22c4d1
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # rcurses - An alternative curses library written in pure Ruby
2
2
 
3
- ![Ruby](https://img.shields.io/badge/language-Ruby-red) ![Unlicense](https://img.shields.io/badge/license-Unlicense-green) ![Stay Amazing](https://img.shields.io/badge/Stay-Amazing-important)
3
+ ![Ruby](https://img.shields.io/badge/language-Ruby-red) [![Gem Version](https://badge.fury.io/rb/rcurses.svg)](https://badge.fury.io/rb/rcurses) ![Unlicense](https://img.shields.io/badge/license-Unlicense-green) ![Stay Amazing](https://img.shields.io/badge/Stay-Amazing-important)
4
4
 
5
5
  <img src="img/rcurses-logo.png" width="150" height="150">
6
6
 
@@ -14,7 +14,7 @@ Simple. One file. No external requirements.
14
14
  # Installation
15
15
  Clone this repo and drop `lib/rcurses.rb` into `/usr/lib/ruby/vendor_ruby/`
16
16
 
17
- Or simply `gem install rcurses` (when I get around to create the gem and this comment is removed).
17
+ Or simply run `gem install rcurses`.
18
18
 
19
19
  To use this library do:
20
20
  ```
@@ -95,6 +95,8 @@ r | Set text to be printed in reverse colors (example: `"TEST".r`)
95
95
  c(code) | Use coded format like "TEST".c("204,45,bui") to print "TEST" in bold, underline italic, fg=204 and bg=45 (the format is `.c("fg,bg,biulr"))
96
96
  pure | Strip text of any "dressing" (example: with `text = "TEST".b`, you will have bold text in the variable `text`, then with `text.pure` it will show "uncoded" or pure text)
97
97
 
98
+ PS: Blink does not work in conjunction with setting a background color in urxvt. It does work in gnome-terminal. But the overall performance in urxvt as orders of magnitude better than gnome-terminal.
99
+
98
100
  # module Cursor
99
101
  Create a new cursor object with `mycursor = Cursor`. Then you can apply the following methods to `mycursor`:
100
102
 
@@ -190,6 +192,19 @@ while $stdin.ready?
190
192
  end
191
193
  ```
192
194
 
195
+ # Example
196
+
197
+ Try this in `irb`:
198
+ ```
199
+ require 'rcurses'
200
+ mypane = Pane.new("@maxcol/2", 30, 30, 10, 19, 229)
201
+ mypane.border = true
202
+ mypane.text = "Hello".i + " World!".b.i + "\n \n" + "rcurses".r + " " + "is cool".c("16,212")
203
+ mypane.refresh
204
+ mypane.edit
205
+ ```
206
+ ... and then try to add some bold text by enclosing it in '*' and italics by enclosing text in '/'. Then press 'ctrl-s' to save your edited text - and then type `mypane.refresh` to see the result.
207
+
193
208
  # Not yet implemented
194
209
  Let me know what other features you like to see.
195
210
 
data/lib/rcurses.rb CHANGED
@@ -5,524 +5,526 @@
5
5
  # Web_site: http://isene.com/
6
6
  # Github: https://github.com/isene/rcurses
7
7
  # License: Public domain
8
- # Version = 0.1 : Initial upload to GitHub
8
+ # Version: 0.3 : Namespace fix & gemspec etc included
9
9
 
10
- class Pane
11
- attr_accessor :startx, :starty, :width, :height, :fg, :bg
12
- attr_reader :x, :y, :w, :h
13
- attr_accessor :border, :scroll, :text, :ix, :align, :prompt
14
- def initialize(startx=1, starty=1, width=1, height=1, fg=nil, bg=nil)
15
- @startx, @starty, @width, @height, @fg, @bg = startx, starty, width, height, fg, bg
16
- @text = "" # Initialize text variable
17
- @align = "l" # Default alignment
18
- @scroll = true # Initialize scroll indicators to true
19
- @prompt = "" # Initialize prompt for editline
20
- @c = Cursor # Local cursor object
21
- @ix = 0 # Text index (starting text line in pane)
22
- self.refresh # Draw the pane upon creation
23
- end
24
- def move (x,y)
25
- self.startx = self.x + x
26
- self.starty = self.y + y
27
- self.refresh
28
- end
29
- def ansicheck(string, ansi)
30
- ansi_beg = /\u0001\e\[#{ansi[0].to_s}m\u0002/
31
- if ansi[0] == 38 or ansi[0] == 48
32
- ansi_beg = /\u0001\e\[#{ansi[0].to_s}[\d;m]+\u0002/
33
- end
34
- ansi_end = /\u0001\e\[#{ansi[1].to_s}m\u0002/
35
- begix = string.rindex(ansi_beg)
36
- begix = -1 if begix == nil
37
- endix = string.rindex(ansi_end)
38
- endix = -1 if endix == nil
39
- dirty = string[begix..-1].match(ansi_beg)[0] if begix > endix
40
- dirty.to_s
41
- end
42
- def textformat(cont=self.text)
43
- @txt = cont.split("\n") # Split text into array
44
- if @txt.any? { |line| line.length >= self.w } # Splitx for lines breaking width
45
- @txt = cont.splitx(self.w)
46
- if cont != cont.pure # Treat lines that break ANSI escape codes
47
- @dirty = "" # Initiate dirty flag (for unclosed ANSI escape sequence)
48
- @txt.each_index do |i|
49
- if @dirty != "" # If dirty flag is set from previous line then add the ANSI sequence to beginning of this line
50
- @txt[i] = @dirty + @txt[i]; @dirty = ""
10
+ module Rcurses
11
+ class Pane
12
+ attr_accessor :startx, :starty, :width, :height, :fg, :bg
13
+ attr_accessor :x, :y, :w, :h
14
+ attr_accessor :border, :scroll, :text, :ix, :align, :prompt
15
+ def initialize(startx=1, starty=1, width=1, height=1, fg=nil, bg=nil)
16
+ @startx, @starty, @width, @height, @fg, @bg = startx, starty, width, height, fg, bg
17
+ @text = "" # Initialize text variable
18
+ @align = "l" # Default alignment
19
+ @scroll = true # Initialize scroll indicators to true
20
+ @prompt = "" # Initialize prompt for editline
21
+ @c = Cursor # Local cursor object
22
+ @ix = 0 # Text index (starting text line in pane)
23
+ self.refresh # Draw the pane upon creation
24
+ end
25
+ def move (x,y)
26
+ self.startx = self.x + x
27
+ self.starty = self.y + y
28
+ self.refresh
29
+ end
30
+ def ansicheck(string, ansi)
31
+ ansi_beg = /\u0001\e\[#{ansi[0].to_s}m\u0002/
32
+ if ansi[0] == 38 or ansi[0] == 48
33
+ ansi_beg = /\u0001\e\[#{ansi[0].to_s}[\d;m]+\u0002/
34
+ end
35
+ ansi_end = /\u0001\e\[#{ansi[1].to_s}m\u0002/
36
+ begix = string.rindex(ansi_beg)
37
+ begix = -1 if begix == nil
38
+ endix = string.rindex(ansi_end)
39
+ endix = -1 if endix == nil
40
+ dirty = string[begix..-1].match(ansi_beg)[0] if begix > endix
41
+ dirty.to_s
42
+ end
43
+ def textformat(cont=self.text)
44
+ @txt = cont.split("\n") # Split text into array
45
+ if @txt.any? { |line| line.length >= self.w } # Splitx for lines breaking width
46
+ @txt = cont.splitx(self.w)
47
+ if cont != cont.pure # Treat lines that break ANSI escape codes
48
+ @dirty = "" # Initiate dirty flag (for unclosed ANSI escape sequence)
49
+ @txt.each_index do |i|
50
+ if @dirty != "" # If dirty flag is set from previous line then add the ANSI sequence to beginning of this line
51
+ @txt[i] = @dirty + @txt[i]; @dirty = ""
52
+ end
53
+ @dirty += ansicheck(@txt[i], [1,22]) # Bold
54
+ @dirty += ansicheck(@txt[i], [3,23]) # Italic
55
+ @dirty += ansicheck(@txt[i], [4,24]) # Underline
56
+ @dirty += ansicheck(@txt[i], [5,25]) # Blink
57
+ @dirty += ansicheck(@txt[i], [7,27]) # Reverse
58
+ @dirty += ansicheck(@txt[i], [38,0]) # Foreground color
59
+ @dirty += ansicheck(@txt[i], [48,0]) # Background color
60
+ @txt[i].sub!(/[\u0001\u0002\e\[\dm]*$/, '')
51
61
  end
52
- @dirty += ansicheck(@txt[i], [1,22]) # Bold
53
- @dirty += ansicheck(@txt[i], [3,23]) # Italic
54
- @dirty += ansicheck(@txt[i], [4,24]) # Underline
55
- @dirty += ansicheck(@txt[i], [5,25]) # Blink
56
- @dirty += ansicheck(@txt[i], [7,27]) # Reverse
57
- @dirty += ansicheck(@txt[i], [38,0]) # Foreground color
58
- @dirty += ansicheck(@txt[i], [48,0]) # Background color
59
- @txt[i].sub!(/[\u0001\u0002\e\[\dm]*$/, '')
60
62
  end
61
63
  end
64
+ @txt
62
65
  end
63
- @txt
64
- end
65
- def refresh(cont=self.text)
66
- o_row, o_col = @c.pos
67
- @c.row(8000); @c.col(8000) # Set for maxrow/maxcol
68
- @maxrow, @maxcol = @c.pos
69
- self.x = eval(self.startx.to_s)
70
- self.y = eval(self.starty.to_s)
71
- self.w = eval(self.width.to_s)
72
- self.h = eval(self.height.to_s)
73
- if self.border # Keep panes inside screen
74
- self.x = 2 if self.x < 2; self.x = @maxcol - self.w if self.x + self.w > @maxcol
75
- self.y = 2 if self.y < 2; self.y = @maxrow - self.h if self.y + self.h > @maxrow
76
- else
77
- self.x = 1 if self.x < 1; self.x = @maxcol - self.w + 1 if self.x + self.w > @maxcol + 1
78
- self.y = 1 if self.y < 1; self.y = @maxrow - self.h + 1 if self.y + self.h > @maxrow + 1
79
- end
80
- @c.col(self.x); @c.row(self.y) # Cursor to start of pane
81
- fmt = self.fg.to_s + "," + self.bg.to_s # Format for printing in pane (fg,bg)
82
- @txt = textformat(cont) # Call function to create an array out of the pane text
83
- @ix = @txt.length - 1 if @ix > @txt.length - 1; @ix = 0 if @ix < 0 # Ensuring no out-of-bounds
84
- self.h.times do |i| # Print pane content
85
- l = @ix + i # The current line to be printed
86
- if @txt[l].to_s != "" # Print the text line for line
87
- pl = self.w - @txt[l].pure.length; hl = pl/2 # Get padding width and half width
88
- print @txt[l].c(fmt) + " ".c(fmt) * pl if self.align == "l"
89
- print " ".c(fmt) * pl + @txt[l].c(fmt) if self.align == "r"
90
- print " ".c(fmt) * hl + @txt[l].c(fmt) + " ".c(fmt) * (pl - hl) if self.align == "c"
66
+ def refresh(cont=self.text)
67
+ o_row, o_col = @c.pos
68
+ @c.row(8000); @c.col(8000) # Set for maxrow/maxcol
69
+ @maxrow, @maxcol = @c.pos
70
+ self.x = eval(self.startx.to_s)
71
+ self.y = eval(self.starty.to_s)
72
+ self.w = eval(self.width.to_s)
73
+ self.h = eval(self.height.to_s)
74
+ if self.border # Keep panes inside screen
75
+ self.x = 2 if self.x < 2; self.x = @maxcol - self.w if self.x + self.w > @maxcol
76
+ self.y = 2 if self.y < 2; self.y = @maxrow - self.h if self.y + self.h > @maxrow
91
77
  else
92
- print "".rjust(self.w).bg(self.bg)
78
+ self.x = 1 if self.x < 1; self.x = @maxcol - self.w + 1 if self.x + self.w > @maxcol + 1
79
+ self.y = 1 if self.y < 1; self.y = @maxrow - self.h + 1 if self.y + self.h > @maxrow + 1
80
+ end
81
+ @c.col(self.x); @c.row(self.y) # Cursor to start of pane
82
+ fmt = self.fg.to_s + "," + self.bg.to_s # Format for printing in pane (fg,bg)
83
+ @txt = textformat(cont) # Call function to create an array out of the pane text
84
+ @ix = @txt.length - 1 if @ix > @txt.length - 1; @ix = 0 if @ix < 0 # Ensuring no out-of-bounds
85
+ self.h.times do |i| # Print pane content
86
+ l = @ix + i # The current line to be printed
87
+ if @txt[l].to_s != "" # Print the text line for line
88
+ pl = self.w - @txt[l].pure.length; hl = pl/2 # Get padding width and half width
89
+ print @txt[l].c(fmt) + " ".c(fmt) * pl if self.align == "l"
90
+ print " ".c(fmt) * pl + @txt[l].c(fmt) if self.align == "r"
91
+ print " ".c(fmt) * hl + @txt[l].c(fmt) + " ".c(fmt) * (pl - hl) if self.align == "c"
92
+ else
93
+ print "".rjust(self.w).bg(self.bg)
94
+ end
95
+ r,c = @c.pos
96
+ @c.row(r + 1) # Cursor down one line
97
+ @c.col(self.x) # Cursor to start of pane
98
+ end
99
+ if @ix > 0 and self.scroll # Print "more" marker at top
100
+ @c.col(self.x + self.w - 1); @c.row(self.y)
101
+ print "▲".c(fmt)
93
102
  end
94
- r,c = @c.pos
95
- @c.row(r + 1) # Cursor down one line
96
- @c.col(self.x) # Cursor to start of pane
97
- end
98
- if @ix > 0 and self.scroll # Print "more" marker at top
99
- @c.col(self.x + self.w - 1); @c.row(self.y)
100
- print "▲".c(fmt)
101
- end
102
- if @txt.length - @ix > self.h and self.scroll # Print bottom "more" marker
103
- @c.col(self.x + self.w - 1); @c.row(self.y + self.h - 1)
104
- print "▼".c(fmt)
105
- end
106
- if self.border # Print border if self.border is set to "true"
107
- @c.row(self.y - 1); @c.col(self.x - 1)
108
- print ("┌" + "─" * self.w + "┐").c(fmt)
109
- self.h.times do |i|
110
- @c.row(self.y + i); @c.col(self.x - 1)
111
- print "│".c(fmt)
112
- @c.col(self.x + self.w)
113
- print "│".c(fmt)
103
+ if @txt.length - @ix > self.h and self.scroll # Print bottom "more" marker
104
+ @c.col(self.x + self.w - 1); @c.row(self.y + self.h - 1)
105
+ print "▼".c(fmt)
114
106
  end
115
- @c.row(self.y + self.h); @c.col(self.x - 1)
116
- print ("└" + "─" * self.w + "┘").c(fmt)
107
+ if self.border # Print border if self.border is set to "true"
108
+ @c.row(self.y - 1); @c.col(self.x - 1)
109
+ print ("┌" + "─" * self.w + "┐").c(fmt)
110
+ self.h.times do |i|
111
+ @c.row(self.y + i); @c.col(self.x - 1)
112
+ print "│".c(fmt)
113
+ @c.col(self.x + self.w)
114
+ print "│".c(fmt)
115
+ end
116
+ @c.row(self.y + self.h); @c.col(self.x - 1)
117
+ print ("└" + "─" * self.w + "┘").c(fmt)
118
+ end
119
+ @c.row(o_row)
120
+ @c.col(o_col)
121
+ @txt
117
122
  end
118
- @c.row(o_row)
119
- @c.col(o_col)
120
- @txt
121
- end
122
- def right
123
- if @pos < @txt[self.ix + @line].length
124
- @pos += 1
125
- else
126
- if @line == self.h
127
- self.ix += 1 unless self.ix >= @txt.length
128
- @pos = 0
129
- elsif @line + self.ix + 2 <= @txt.length
130
- @line += 1
131
- @pos = 0
123
+ def right
124
+ if @pos < @txt[self.ix + @line].length
125
+ @pos += 1
126
+ else
127
+ if @line == self.h
128
+ self.ix += 1 unless self.ix >= @txt.length
129
+ @pos = 0
130
+ elsif @line + self.ix + 2 <= @txt.length
131
+ @line += 1
132
+ @pos = 0
133
+ end
132
134
  end
133
135
  end
134
- end
135
- def left
136
- if @pos == 0
137
- if @line == 0
138
- unless self.ix == 0
139
- self.ix -= 1
136
+ def left
137
+ if @pos == 0
138
+ if @line == 0
139
+ unless self.ix == 0
140
+ self.ix -= 1
141
+ @pos = @txt[self.ix + @line].length - 1
142
+ end
143
+ else
144
+ @line -= 1
140
145
  @pos = @txt[self.ix + @line].length - 1
141
146
  end
142
147
  else
143
- @line -= 1
144
- @pos = @txt[self.ix + @line].length - 1
148
+ @pos -= 1
145
149
  end
146
- else
147
- @pos -= 1
148
150
  end
149
- end
150
- def up
151
- if @line == 0
152
- self.ix -= 1 unless self.ix == 0
153
- else
154
- @line -= 1
155
- end
156
- begin
157
- @pos = @txt[self.ix + @line].length - 1 if @pos > @txt[self.ix + @line].length - 1
158
- rescue
151
+ def up
152
+ if @line == 0
153
+ self.ix -= 1 unless self.ix == 0
154
+ else
155
+ @line -= 1
156
+ end
157
+ begin
158
+ @pos = @txt[self.ix + @line].length - 1 if @pos > @txt[self.ix + @line].length - 1
159
+ rescue
160
+ end
159
161
  end
160
- end
161
- def down
162
- if @line == self.h - 1
163
- self.ix += 1 unless self.ix + @line >= @txt.length - 1
164
- elsif @line + self.ix + 2 <= @txt.length
165
- @line += 1
162
+ def down
163
+ if @line == self.h - 1
164
+ self.ix += 1 unless self.ix + @line >= @txt.length - 1
165
+ elsif @line + self.ix + 2 <= @txt.length
166
+ @line += 1
167
+ end
168
+ begin
169
+ @pos = @txt[self.ix + @line].length - 1 if @pos > @txt[self.ix + @line].length - 1
170
+ rescue
171
+ end
166
172
  end
167
- begin
168
- @pos = @txt[self.ix + @line].length - 1 if @pos > @txt[self.ix + @line].length - 1
169
- rescue
173
+ def parse(cont)
174
+ cont.gsub!(/\*(.+?)\*/, '\1'.b)
175
+ cont.gsub!(/\/(.+?)\//, '\1'.i)
176
+ cont.gsub!(/_(.+?)_/, '\1'.u)
177
+ cont.gsub!(/#(.+?)#/, '\1'.r)
178
+ cont.gsub!(/<([^|]+)\|([^>]+)>/) do |m|
179
+ text = $2; codes = $1
180
+ text.c(codes)
181
+ end
182
+ cont
170
183
  end
171
- end
172
- def parse(cont)
173
- cont.gsub!(/\*(.+?)\*/, '\1'.b)
174
- cont.gsub!(/\/(.+?)\//, '\1'.i)
175
- cont.gsub!(/_(.+?)_/, '\1'.u)
176
- cont.gsub!(/#(.+?)#/, '\1'.r)
177
- cont.gsub!(/<([^|]+)\|([^>]+)>/) do |m|
178
- text = $2; codes = $1
179
- text.c(codes)
180
- end
181
- cont
182
- end
183
- def edit
184
- cont = self.text.pure.gsub(/\n/, "¬\n")
185
- @line = self.ix
186
- @pos = 0
187
- chr = ""
188
- while chr != "ESC" # Keep going with readline until user presses ESC
189
- @txt = self.refresh(cont)
190
- @c.row(self.y + @line)
191
- @c.col(self.x + @pos)
192
- chr = getchr
193
- case chr
194
- when 'C-L' # Left justify
195
- self.align = "l"
196
- when 'C-R' # Right Justify
197
- self.align = "r"
198
- when 'C-C' # Center justify
199
- self.align = "c"
200
- when 'C-Y' # Copy pane content to clipboard
201
- system("echo '#{self.text.pure}' | xclip")
202
- when 'C-S' # Save edited text back to self.text
203
- cont = cont.gsub("¬", "\n")
204
- cont = parse(cont)
205
- self.text = cont
206
- chr = "ESC"
207
- when 'DEL' # Delete character
208
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
209
- cont[posx] = ""
210
- when 'BACK' # Backspace
211
- left
212
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
213
- cont[posx] = ""
214
- when 'WBACK' # Word backspace
215
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
216
- until cont[posx - 1] == " " or @pos == 0
184
+ def edit
185
+ cont = self.text.pure.gsub(/\n/, "¬\n")
186
+ @line = self.ix
187
+ @pos = 0
188
+ chr = ""
189
+ while chr != "ESC" # Keep going with readline until user presses ESC
190
+ @txt = self.refresh(cont)
191
+ @c.row(self.y + @line)
192
+ @c.col(self.x + @pos)
193
+ chr = getchr
194
+ case chr
195
+ when 'C-L' # Left justify
196
+ self.align = "l"
197
+ when 'C-R' # Right Justify
198
+ self.align = "r"
199
+ when 'C-C' # Center justify
200
+ self.align = "c"
201
+ when 'C-Y' # Copy pane content to clipboard
202
+ system("echo '#{self.text.pure}' | xclip")
203
+ when 'C-S' # Save edited text back to self.text
204
+ cont = cont.gsub("¬", "\n")
205
+ cont = parse(cont)
206
+ self.text = cont
207
+ chr = "ESC"
208
+ when 'DEL' # Delete character
209
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
210
+ cont[posx] = ""
211
+ when 'BACK' # Backspace
217
212
  left
218
213
  posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
219
214
  cont[posx] = ""
215
+ when 'WBACK' # Word backspace
216
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
217
+ until cont[posx - 1] == " " or @pos == 0
218
+ left
219
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
220
+ cont[posx] = ""
221
+ end
222
+ when 'C-K' # Kill line
223
+ begin
224
+ prev_l = 0
225
+ line_c = self.ix + @line
226
+ line_c.times {|i| prev_l += @txt[i].length + 1}
227
+ cur_l = @txt[line_c].length
228
+ cont.slice!(prev_l,cur_l)
229
+ rescue
230
+ end
231
+ when 'UP' # Up one line
232
+ up
233
+ when 'DOWN' # Down one line
234
+ down
235
+ when 'RIGHT' # Right one character
236
+ right
237
+ when 'LEFT' # Left one character
238
+ left
239
+ when 'HOME' # Start of line
240
+ @pos = 0
241
+ when 'END' # End of line
242
+ @pos = @txt[self.ix + @line].length - 1
243
+ when 'C-HOME' # Start of pane
244
+ @line = 0
245
+ @pos = 0
246
+ when 'C-END' # End of pane
247
+ when 'ENTER'
248
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
249
+ cont.insert(posx,"¬\n")
250
+ right
251
+ when /^.$/
252
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
253
+ cont.insert(posx,chr)
220
254
  end
221
- when 'C-K' # Kill line
222
- begin
223
- prev_l = 0
224
- line_c = self.ix + @line
225
- line_c.times {|i| prev_l += @txt[i].length + 1}
226
- cur_l = @txt[line_c].length
227
- cont.slice!(prev_l,cur_l)
228
- rescue
255
+ charx = 1
256
+ posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
257
+ while $stdin.ready?
258
+ chr = $stdin.getc
259
+ charx += 1
260
+ posx += 1
261
+ cont.insert(posx,chr)
262
+ end
263
+ if chr =~ /^.$/
264
+ self.refresh(cont)
265
+ charx.times {right}
229
266
  end
230
- when 'UP' # Up one line
231
- up
232
- when 'DOWN' # Down one line
233
- down
234
- when 'RIGHT' # Right one character
235
- right
236
- when 'LEFT' # Left one character
237
- left
238
- when 'HOME' # Start of line
239
- @pos = 0
240
- when 'END' # End of line
241
- @pos = @txt[self.ix + @line].length - 1
242
- when 'C-HOME' # Start of pane
243
- @line = 0
244
- @pos = 0
245
- when 'C-END' # End of pane
246
- when 'ENTER'
247
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
248
- cont.insert(posx,"¬\n")
249
- right
250
- when /^.$/
251
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
252
- cont.insert(posx,chr)
253
- end
254
- charx = 1
255
- posx = 0; (self.ix + @line).times {|i| posx += @txt[i].length + 1}; posx += @pos
256
- while $stdin.ready?
257
- chr = $stdin.getc
258
- charx += 1
259
- posx += 1
260
- cont.insert(posx,chr)
261
- end
262
- if chr =~ /^.$/
263
- self.refresh(cont)
264
- charx.times {right}
265
- end
266
267
 
268
+ end
269
+ # Keep?
270
+ @c.row(nil)
271
+ @c.col(nil)
267
272
  end
268
- # Keep?
269
- @c.row(nil)
270
- @c.col(nil)
271
- end
272
- def editline
273
- self.x = eval(self.startx.to_s)
274
- self.y = eval(self.starty.to_s)
275
- self.w = eval(self.width.to_s)
276
- self.h = eval(self.height.to_s)
277
- self.x = 1 if self.x < 1; self.x = @maxcol - self.w + 1 if self.x + self.w > @maxcol + 1
278
- self.y = 1 if self.y < 1; self.y = @maxrow - self.h + 1 if self.y + self.h > @maxrow + 1
279
- self.scroll = false
280
- @c.row(self.y)
281
- fmt = self.fg.to_s + "," + self.bg.to_s # Format for printing in pane (fg,bg)
282
- @c.col(self.x); print self.prompt.c(fmt) # Print prompt from start of pane
283
- pl = self.prompt.pure.length # Prompt length
284
- cl = self.w - pl # Available content length
285
- cont = self.text.pure # Actual content
286
- @pos = cont.length # Initial position set at end of content
287
- chr = "" # Initialize chr
288
- while chr != "ESC" # Keep going with readline until user presses ESC
289
- @c.col(self.x + pl) # Set cursor at start of content
290
- cont = cont.slice(0,cl) # Trim content to max length
291
- print cont.ljust(cl).c(fmt) # Print content left justified to max length
292
- @c.col(self.x + pl + @pos) # Set cursor to current position (@pos)
293
- chr = getchr # Read character from user input
294
- case chr
295
- when 'LEFT' # One character left
296
- @pos -= 1 unless @pos == 0
297
- when 'RIGHT' # One character right
298
- @pos += 1 unless @pos >= cont.length
299
- when 'HOME' # To start of content
300
- @pos = 0
301
- when 'END' # To end of content
302
- @pos = cont.length - 1
303
- when 'DEL' # Delete character
304
- cont[@pos] = ""
305
- when 'BACK' # Backspace
306
- @pos -= 1 unless @pos == 0
307
- cont[@pos] = ""
308
- when 'WBACK' # Word backspace
309
- until cont[@pos - 1] == " " or @pos == 0
310
- @pos -= 1
273
+ def editline
274
+ self.x = eval(self.startx.to_s)
275
+ self.y = eval(self.starty.to_s)
276
+ self.w = eval(self.width.to_s)
277
+ self.h = eval(self.height.to_s)
278
+ self.x = 1 if self.x < 1; self.x = @maxcol - self.w + 1 if self.x + self.w > @maxcol + 1
279
+ self.y = 1 if self.y < 1; self.y = @maxrow - self.h + 1 if self.y + self.h > @maxrow + 1
280
+ self.scroll = false
281
+ @c.row(self.y)
282
+ fmt = self.fg.to_s + "," + self.bg.to_s # Format for printing in pane (fg,bg)
283
+ @c.col(self.x); print self.prompt.c(fmt) # Print prompt from start of pane
284
+ pl = self.prompt.pure.length # Prompt length
285
+ cl = self.w - pl # Available content length
286
+ cont = self.text.pure # Actual content
287
+ @pos = cont.length # Initial position set at end of content
288
+ chr = "" # Initialize chr
289
+ while chr != "ESC" # Keep going with readline until user presses ESC
290
+ @c.col(self.x + pl) # Set cursor at start of content
291
+ cont = cont.slice(0,cl) # Trim content to max length
292
+ print cont.ljust(cl).c(fmt) # Print content left justified to max length
293
+ @c.col(self.x + pl + @pos) # Set cursor to current position (@pos)
294
+ chr = getchr # Read character from user input
295
+ case chr
296
+ when 'LEFT' # One character left
297
+ @pos -= 1 unless @pos == 0
298
+ when 'RIGHT' # One character right
299
+ @pos += 1 unless @pos >= cont.length
300
+ when 'HOME' # To start of content
301
+ @pos = 0
302
+ when 'END' # To end of content
303
+ @pos = cont.length - 1
304
+ when 'DEL' # Delete character
311
305
  cont[@pos] = ""
306
+ when 'BACK' # Backspace
307
+ @pos -= 1 unless @pos == 0
308
+ cont[@pos] = ""
309
+ when 'WBACK' # Word backspace
310
+ until cont[@pos - 1] == " " or @pos == 0
311
+ @pos -= 1
312
+ cont[@pos] = ""
313
+ end
314
+ when 'C-K' # Kill line (set content to nothing)
315
+ cont = ""
316
+ @pos = 0
317
+ when 'ENTER' # Save content to self.text and end
318
+ self.text = parse(cont)
319
+ chr = 'ESC'
320
+ when /^.$/ # Add character to content
321
+ unless @pos >= cl - 1
322
+ cont.insert(@pos,chr)
323
+ @pos += 1
324
+ end
312
325
  end
313
- when 'C-K' # Kill line (set content to nothing)
314
- cont = ""
315
- @pos = 0
316
- when 'ENTER' # Save content to self.text and end
317
- self.text = parse(cont)
318
- chr = 'ESC'
319
- when /^.$/ # Add character to content
320
- unless @pos >= cl - 1
321
- cont.insert(@pos,chr)
322
- @pos += 1
323
- end
324
- end
325
- while $stdin.ready? # Add characters from pasted input
326
- chr = $stdin.getc
327
- unless @pos >= cl - 1
328
- cont.insert(@pos,chr)
329
- @pos += 1
326
+ while $stdin.ready? # Add characters from pasted input
327
+ chr = $stdin.getc
328
+ unless @pos >= cl - 1
329
+ cont.insert(@pos,chr)
330
+ @pos += 1
331
+ end
330
332
  end
331
333
  end
334
+ # Keep? Set cursor away from pane
335
+ @c.row(nil)
336
+ @c.col(nil)
332
337
  end
333
- # Keep? Set cursor away from pane
334
- @c.row(nil)
335
- @c.col(nil)
336
338
  end
337
- end
338
339
 
339
- class String # Add coloring to strings (with escaping for Readline)
340
- def fg(fg); color(self, "\001\e[38;5;#{fg}m\002", "\001\e[0m\002"); end # Foreground color code
341
- def bg(bg); color(self, "\001\e[48;5;#{bg}m\002", "\001\e[0m\002"); end # Background color code
342
- def fb(fg, bg); color(self, "\001\e[38;5;#{fg};48;5;#{bg}m\002"); end # Fore/Background color code
343
- def b; color(self, "\001\e[1m\002", "\001\e[22m\002"); end # Bold
344
- def i; color(self, "\001\e[3m\002", "\001\e[23m\002"); end # Italic
345
- def u; color(self, "\001\e[4m\002", "\001\e[24m\002"); end # Underline
346
- def l; color(self, "\001\e[5m\002", "\001\e[25m\002"); end # Blink
347
- def r; color(self, "\001\e[7m\002", "\001\e[27m\002"); end # Reverse
348
- def color(text, sp, ep) "#{sp}#{text}#{ep}" end # Internal function
349
- def c(code) # Use format "TEST".c("204,45,bui") to print "TEST" in bold, underline italic, fg=204 and bg=45
350
- prop = "\001\e["
351
- prop += "38;5;#{code.match(/^\d+/).to_s};" if code.match(/^\d+/)
352
- prop += "48;5;#{code.match(/(?<=,)\d+/).to_s};" if code.match(/(?<=,)\d+/)
353
- prop += "1;" if code.match(/b/)
354
- prop += "3;" if code.match(/i/)
355
- prop += "4;" if code.match(/u/)
356
- prop += "5;" if code.match(/l/)
357
- prop += "7;" if code.match(/r/)
358
- prop.chop! if prop[-1] == ";"
359
- prop += "m\002"
360
- prop += self
361
- prop += "\001\e[0m\002"
362
- #puts "\n XX\n" + code
363
- prop
364
- end
365
- def pure
366
- self.gsub(/\u0001.*?\u0002/, '')
367
- end
368
- def splitx(x)
369
- lines = self.split("\n")
370
- until lines.all? { |line| line.pure.length <= x } do
371
- lines.map! do |l|
372
- if l.pure.length > x and l[0..x].match(/ /)
373
- @ix = l[0..x].rindex(" ")
374
- [ l[0...@ix], l[(@ix + 1)..-1] ]
375
- elsif l.pure.length > x
376
- [l[0...x], l[x..-1]]
377
- else
378
- l
340
+ class String # Add coloring to strings (with escaping for Readline)
341
+ def fg(fg); color(self, "\001\e[38;5;#{fg}m\002", "\001\e[0m\002"); end # Foreground color code
342
+ def bg(bg); color(self, "\001\e[48;5;#{bg}m\002", "\001\e[0m\002"); end # Background color code
343
+ def fb(fg, bg); color(self, "\001\e[38;5;#{fg};48;5;#{bg}m\002"); end # Fore/Background color code
344
+ def b; color(self, "\001\e[1m\002", "\001\e[22m\002"); end # Bold
345
+ def i; color(self, "\001\e[3m\002", "\001\e[23m\002"); end # Italic
346
+ def u; color(self, "\001\e[4m\002", "\001\e[24m\002"); end # Underline
347
+ def l; color(self, "\001\e[5m\002", "\001\e[25m\002"); end # Blink
348
+ def r; color(self, "\001\e[7m\002", "\001\e[27m\002"); end # Reverse
349
+ def color(text, sp, ep) "#{sp}#{text}#{ep}" end # Internal function
350
+ def c(code) # Use format "TEST".c("204,45,bui") to print "TEST" in bold, underline italic, fg=204 and bg=45
351
+ prop = "\001\e["
352
+ prop += "38;5;#{code.match(/^\d+/).to_s};" if code.match(/^\d+/)
353
+ prop += "48;5;#{code.match(/(?<=,)\d+/).to_s};" if code.match(/(?<=,)\d+/)
354
+ prop += "1;" if code.match(/b/)
355
+ prop += "3;" if code.match(/i/)
356
+ prop += "4;" if code.match(/u/)
357
+ prop += "5;" if code.match(/l/)
358
+ prop += "7;" if code.match(/r/)
359
+ prop.chop! if prop[-1] == ";"
360
+ prop += "m\002"
361
+ prop += self
362
+ prop += "\001\e[0m\002"
363
+ #puts "\n XX\n" + code
364
+ prop
365
+ end
366
+ def pure
367
+ self.gsub(/\u0001.*?\u0002/, '')
368
+ end
369
+ def splitx(x)
370
+ lines = self.split("\n")
371
+ until lines.all? { |line| line.pure.length <= x } do
372
+ lines.map! do |l|
373
+ if l.pure.length > x and l[0..x].match(/ /)
374
+ @ix = l[0..x].rindex(" ")
375
+ [ l[0...@ix], l[(@ix + 1)..-1] ]
376
+ elsif l.pure.length > x
377
+ [l[0...x], l[x..-1]]
378
+ else
379
+ l
380
+ end
379
381
  end
382
+ lines.flatten!
380
383
  end
381
- lines.flatten!
384
+ lines.reject { |e| e.to_s.empty? }
382
385
  end
383
- lines.reject { |e| e.to_s.empty? }
384
386
  end
385
- end
386
387
 
387
- module Cursor # Terminal cursor movement ANSI codes (thanks to https://github.com/piotrmurach/tty-cursor)
388
- module_function
389
- ESC = "\e".freeze
390
- CSI = "\e[".freeze
391
- def save # Save current position
392
- print(Gem.win_platform? ? CSI + 's' : ESC + '7')
393
- end
394
- def restore # Restore cursor position
395
- print(Gem.win_platform? ? CSI + 'u' : ESC + '8')
396
- end
397
- def pos # Query cursor current position
398
- res = ''
399
- $stdin.raw do |stdin|
400
- $stdout << CSI + '6n' # Tha actual ANSI get-position
401
- $stdout.flush
402
- while (c = stdin.getc) != 'R'
403
- res << c if c
388
+ module Cursor # Terminal cursor movement ANSI codes (inspired by https://github.com/piotrmurach/tty-cursor)
389
+ module_function
390
+ ESC = "\e".freeze
391
+ CSI = "\e[".freeze
392
+ def save # Save current position
393
+ print(Gem.win_platform? ? CSI + 's' : ESC + '7')
394
+ end
395
+ def restore # Restore cursor position
396
+ print(Gem.win_platform? ? CSI + 'u' : ESC + '8')
397
+ end
398
+ def pos # Query cursor current position
399
+ res = ''
400
+ $stdin.raw do |stdin|
401
+ $stdout << CSI + '6n' # Tha actual ANSI get-position
402
+ $stdout.flush
403
+ while (c = stdin.getc) != 'R'
404
+ res << c if c
405
+ end
404
406
  end
407
+ m = res.match /(?<row>\d+);(?<col>\d+)/
408
+ return m[:row].to_i, m[:col].to_i
409
+ end
410
+ def rowget
411
+ row, col = self.pos
412
+ return row
413
+ end
414
+ def colget
415
+ row, col = self.pos
416
+ return col
417
+ end
418
+ def up(n = 1) # Move cursor up by n
419
+ print(CSI + "#{(n || 1)}A")
420
+ end
421
+ def down(n = 1) # Move the cursor down by n
422
+ print(CSI + "#{(n || 1)}B")
423
+ end
424
+ def left(n = 1) # Move the cursor backward by n
425
+ print(CSI + "#{n || 1}D")
426
+ end
427
+ def right(n = 1) # Move the cursor forward by n
428
+ print(CSI + "#{n || 1}C")
429
+ end
430
+ def col(n = 1) # Cursor moves to nth position horizontally in the current line
431
+ print(CSI + "#{n || 1}G")
432
+ end
433
+ def row(n = 1) # Cursor moves to the nth position vertically in the current column
434
+ print(CSI + "#{n || 1}d")
435
+ end
436
+ def next_line # Move cursor down to beginning of next line
437
+ print(CSI + 'E' + CSI + "1G")
438
+ end
439
+ def prev_line # Move cursor up to beginning of previous line
440
+ print(CSI + 'A' + CSI + "1G")
441
+ end
442
+ def clear_char(n = 1) # Erase n characters from the current cursor position
443
+ print(CSI + "#{n}X")
444
+ end
445
+ def clear_line # Erase the entire current line and return to beginning of the line
446
+ print(CSI + '2K' + CSI + "1G")
447
+ end
448
+ def clear_line_before # Erase from the beginning of the line up to and including the current cursor position.
449
+ print(CSI + '1K')
450
+ end
451
+ def clear_line_after # Erase from the current position (inclusive) to the end of the line
452
+ print(CSI + '0K')
453
+ end
454
+ def scroll_up # Scroll display up one line
455
+ print(ESC + 'M')
456
+ end
457
+ def scroll_down # Scroll display down one line
458
+ print(ESC + 'D')
459
+ end
460
+ def clear_screen_down # Clear screen down from current row
461
+ print(CSI + 'J')
405
462
  end
406
- m = res.match /(?<row>\d+);(?<col>\d+)/
407
- return m[:row].to_i, m[:col].to_i
408
- end
409
- def rowget
410
- row, col = self.pos
411
- return row
412
- end
413
- def colget
414
- row, col = self.pos
415
- return col
416
- end
417
- def up(n = 1) # Move cursor up by n
418
- print(CSI + "#{(n || 1)}A")
419
- end
420
- def down(n = 1) # Move the cursor down by n
421
- print(CSI + "#{(n || 1)}B")
422
- end
423
- def left(n = 1) # Move the cursor backward by n
424
- print(CSI + "#{n || 1}D")
425
- end
426
- def right(n = 1) # Move the cursor forward by n
427
- print(CSI + "#{n || 1}C")
428
- end
429
- def col(n = 1) # Cursor moves to nth position horizontally in the current line
430
- print(CSI + "#{n || 1}G")
431
- end
432
- def row(n = 1) # Cursor moves to the nth position vertically in the current column
433
- print(CSI + "#{n || 1}d")
434
- end
435
- def next_line # Move cursor down to beginning of next line
436
- print(CSI + 'E' + CSI + "1G")
437
- end
438
- def prev_line # Move cursor up to beginning of previous line
439
- print(CSI + 'A' + CSI + "1G")
440
- end
441
- def clear_char(n = 1) # Erase n characters from the current cursor position
442
- print(CSI + "#{n}X")
443
- end
444
- def clear_line # Erase the entire current line and return to beginning of the line
445
- print(CSI + '2K' + CSI + "1G")
446
- end
447
- def clear_line_before # Erase from the beginning of the line up to and including the current cursor position.
448
- print(CSI + '1K')
449
- end
450
- def clear_line_after # Erase from the current position (inclusive) to the end of the line
451
- print(CSI + '0K')
452
- end
453
- def scroll_up # Scroll display up one line
454
- print(ESC + 'M')
455
- end
456
- def scroll_down # Scroll display down one line
457
- print(ESC + 'D')
458
- end
459
- def clear_screen_down # Clear screen down from current row
460
- print(CSI + 'J')
461
463
  end
462
- end
463
464
 
464
- def getchr # Function to process key presses
465
- c = $stdin.getch
466
- case c
467
- when "\e" # ANSI escape sequences (with only ESC, it should stop right here)
468
- return "ESC" if $stdin.ready? == nil
469
- case $stdin.getc
470
- when '[' # CSI
471
- case $stdin.getc # Will get (or ASK) for more (remaining part of special character)
472
- when 'A' then chr = "UP"
473
- when 'B' then chr = "DOWN"
474
- when 'C' then chr = "RIGHT"
475
- when 'D' then chr = "LEFT"
476
- when 'Z' then chr = "S-TAB"
477
- when '2' then chr = "INS" ; chr = "C-INS" if $stdin.getc == "^"
478
- when '3' then chr = "DEL" ; chr = "C-DEL" if $stdin.getc == "^"
479
- when '5' then chr = "PgUP" ; chr = "C-PgUP" if $stdin.getc == "^"
480
- when '6' then chr = "PgDOWN" ; chr = "C-PgDOWN" if $stdin.getc == "^"
481
- when '7' then chr = "HOME" ; chr = "C-HOME" if $stdin.getc == "^"
482
- when '8' then chr = "END" ; chr = "C-END" if $stdin.getc == "^"
483
- else chr = ""
484
- end
485
- when 'O' # Set Ctrl+ArrowKey equal to ArrowKey; May be used for other purposes in the future
465
+ def getchr # Function to process key presses
466
+ c = $stdin.getch
467
+ case c
468
+ when "\e" # ANSI escape sequences (with only ESC, it should stop right here)
469
+ return "ESC" if $stdin.ready? == nil
486
470
  case $stdin.getc
487
- when 'a' then chr = "C-UP"
488
- when 'b' then chr = "C-DOWN"
489
- when 'c' then chr = "C-RIGHT"
490
- when 'd' then chr = "C-LEFT"
491
- else chr = ""
471
+ when '[' # CSI
472
+ case $stdin.getc # Will get (or ASK) for more (remaining part of special character)
473
+ when 'A' then chr = "UP"
474
+ when 'B' then chr = "DOWN"
475
+ when 'C' then chr = "RIGHT"
476
+ when 'D' then chr = "LEFT"
477
+ when 'Z' then chr = "S-TAB"
478
+ when '2' then chr = "INS" ; chr = "C-INS" if $stdin.getc == "^"
479
+ when '3' then chr = "DEL" ; chr = "C-DEL" if $stdin.getc == "^"
480
+ when '5' then chr = "PgUP" ; chr = "C-PgUP" if $stdin.getc == "^"
481
+ when '6' then chr = "PgDOWN" ; chr = "C-PgDOWN" if $stdin.getc == "^"
482
+ when '7' then chr = "HOME" ; chr = "C-HOME" if $stdin.getc == "^"
483
+ when '8' then chr = "END" ; chr = "C-END" if $stdin.getc == "^"
484
+ else chr = ""
485
+ end
486
+ when 'O' # Set Ctrl+ArrowKey equal to ArrowKey; May be used for other purposes in the future
487
+ case $stdin.getc
488
+ when 'a' then chr = "C-UP"
489
+ when 'b' then chr = "C-DOWN"
490
+ when 'c' then chr = "C-RIGHT"
491
+ when 'd' then chr = "C-LEFT"
492
+ else chr = ""
493
+ end
492
494
  end
495
+ when "", "" then chr = "BACK"
496
+ when "" then chr = "C-A"
497
+ when "" then chr = "C-B"
498
+ when "" then chr = "C-C"
499
+ when "^D" then chr = "C-D"
500
+ when "" then chr = "C-E"
501
+ when "" then chr = "C-F"
502
+ when "^G" then chr = "C-G"
503
+ when " " then chr = "C-I"
504
+ when "" then chr = "C-J"
505
+ when " " then chr = "C-K"
506
+ when " " then chr = "C-L"
507
+ when "
508
+ when "^N" then chr = "C-N"
509
+ when "^O" then chr = "C-O"
510
+ when "^P" then chr = "C-P"
511
+ when "" then chr = "C-Q"
512
+ when "" then chr = "C-R"
513
+ when "^T" then chr = "C-T"
514
+ when "" then chr = "C-U"
515
+ when "" then chr = "C-V"
516
+ when "" then chr = "C-X"
517
+ when "" then chr = "C-Y"
518
+ when "" then chr = "C-Z"
519
+ when "" then chr = "WBACK"
520
+ when "\r" then chr = "ENTER"
521
+ when "\t" then chr = "TAB"
522
+ when "" then chr = "C-S"
523
+ when /[[:print:]]/ then chr = c
524
+ else chr = ""
493
525
  end
494
- when "", "" then chr = "BACK"
495
- when "" then chr = "C-A"
496
- when "" then chr = "C-B"
497
- when "" then chr = "C-C"
498
- when "^D" then chr = "C-D"
499
- when "" then chr = "C-E"
500
- when "" then chr = "C-F"
501
- when "^G" then chr = "C-G"
502
- when " " then chr = "C-I"
503
- when "" then chr = "C-J"
504
- when " " then chr = "C-K"
505
- when " " then chr = "C-L"
506
- when "
507
- when "^N" then chr = "C-N"
508
- when "^O" then chr = "C-O"
509
- when "^P" then chr = "C-P"
510
- when "" then chr = "C-Q"
511
- when "" then chr = "C-R"
512
- when "^T" then chr = "C-T"
513
- when "" then chr = "C-U"
514
- when "" then chr = "C-V"
515
- when "" then chr = "C-X"
516
- when "" then chr = "C-Y"
517
- when "" then chr = "C-Z"
518
- when "" then chr = "WBACK"
519
- when "\r" then chr = "ENTER"
520
- when "\t" then chr = "TAB"
521
- when "" then chr = "C-S"
522
- when /[[:print:]]/ then chr = c
523
- else chr = ""
526
+ return chr
524
527
  end
525
- return chr
526
528
  end
527
529
 
528
530
  # vim: set sw=2 sts=2 et filetype=ruby fdm=syntax fdn=2 fcs=fold\:\ :
metadata CHANGED
@@ -1,20 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcurses
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geir Isene
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-16 00:00:00.000000000 Z
11
+ date: 2024-11-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Create panes (with the colors and(or border), manipulate the panes and
13
+ description: 'Create panes (with the colors and(or border), manipulate the panes and
14
14
  add content. Dress up text (in panes or anywhere in the terminal) in bold, italic,
15
15
  underline, reverse color, blink and in any 256 terminal colors for foreground and
16
16
  background. Use a simple editor to let users edit text in panes. Left, right or
17
- center align text in panes. Cursor movement around the terminal.
17
+ center align text in panes. Cursor movement around the terminal. New in 0.3: Namespace
18
+ fix & gemspec etc included'
18
19
  email: g@isene.com
19
20
  executables: []
20
21
  extensions: