fancy_buff 2.0.0 → 2.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fancy_buff.rb +128 -76
  3. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 693126b181dc6a997dd15d46158a437d31e3957c88fd314edf557c16c905a36e
4
- data.tar.gz: 5f88475a875d86e13192b397f35c7970cfcb11a12390315114dedfe38d82d13b
3
+ metadata.gz: 54eb5fe670bbed8371d3d40a04a202820455b2563725c27e1b5639bedfdc9cb4
4
+ data.tar.gz: 07703ee689b16d4544f889c68c7ecd5028829b9004a1a9081f76a332b9d1d724
5
5
  SHA512:
6
- metadata.gz: fd662a50783b6a3af23bdbd70f3065952a7d1faac12af6208a699ee53527d26d60f5958fcf9b045e6ba0fb196744db151a38395966332aee70ae8eb383d30828
7
- data.tar.gz: befd4e7240600a0001697c647eaef1efef60a0635cc5db27988b580ad0930d3538de02d4f6a0390476c444753d29b12c63d47919d7d7ee0869933e42e37d274f
6
+ metadata.gz: 0d98a27f8aea897b1a3313e9fe830dc633b0b4f5e93978188a40dae468b4bdfbd35254a6ddaae8ef5188f9f13eeb6c1ec9f09909d081709ee3114efa28e3e408
7
+ data.tar.gz: a3d70930ba010a6803cfb7db4aad39e18a00dae2c4eb97b0732212ba5a9d884505491373a50b4264d7baa9827cba4e24a5d03ca2e9fbdbda5a324d5af6c47b28
data/lib/fancy_buff.rb CHANGED
@@ -1,118 +1,170 @@
1
1
  # a text buffer with marks, selections, and rudimentary editing
2
- class TinyBuff
3
- attr_reader :length
2
+ class FancyBuff
3
+ attr_reader :chars,
4
+ :bytes,
5
+ :lines,
6
+ :length,
7
+ :max_char_width,
8
+ :marks,
9
+ :selections
10
+
11
+ # allows the consuming application to set the window size, since that
12
+ # application is probably mananging the other buffers in use
13
+ attr_accessor :win
14
+
15
+ # gives you a default, empty, zero slice
16
+ def initialize
17
+ # size tracking
18
+ @chars = 0 # the number of characters in the buffer (not the same as the number of bytes)
19
+ @bytes = 0 # the number of bytes in the buffer (not the same as the number of characters)
20
+ @lines = []
21
+ @max_char_width = 0
4
22
 
5
- # content: the starting content of the buffer as a String
6
- def initialize(content='')
7
- @content = content.lines.map(&:chomp)
8
23
  @marks = {}
9
24
  @selections = {}
25
+ @win = [0, 0, 0, 0] # the default slice is at the beginning of the buffer, and has a zero size
26
+ end
10
27
 
11
- @length = @content
12
- .map{|l| l.length }
13
- .sum
28
+ # index of first visible row
29
+ def r
30
+ @win[0]
14
31
  end
15
32
 
16
- # returns the number of lines
17
- def lines
18
- @content.length
33
+ # index of first visible column
34
+ def c
35
+ @win[1]
19
36
  end
20
37
 
21
- # line_range: the Range of lines to return (NOT line indexes numbers)
22
- # max_len (optional): the maximum length of each line to return; useful when you want to
23
- # return a rectangular region of text for display, for example
24
- def [](line_range, max_len=nil)
25
- !!max_len ? @content[line_range] : @content[line_range].map{|l| l[..max_len] }
38
+ # width of the buffer window
39
+ def w
40
+ @win[2]
26
41
  end
27
42
 
28
- # col: starting column (zero-based)
29
- # row: starting line (zero-based)
30
- # wid: the number of characters per line
31
- # hgt: the number of rows
32
- def rect(col, row, wid, hgt)
33
- @content[row..(row + hgt - 1)]
34
- .map{|row| row.chomp.chars[col..(col + wid - 1)].join }
43
+ # height of the buffer window
44
+ def h
45
+ @win[3]
35
46
  end
36
47
 
37
- # set a mark, as in the Vim sense
38
- #
39
- # sym: the name of the mark
40
- # char_num: the number of characters from the top of the buffer to set the
41
- # mark
42
- def mark(sym, char_num)
43
- @marks[sym] = char_num
48
+ # returns an array of strings representing the visible characters from this
49
+ # FancyBuffer's @rect
50
+ def win_s
51
+ r, c, w, h = @win
44
52
 
45
- nil
53
+ return [] if h == 0 || w == 0
54
+
55
+ @lines[r..(r + visible_lines - 1)]
56
+ .map.with_index{|row, i| "#{(i + r + 1).to_s.rjust(3)} #{row.chars[c..(c + w - 1 - 4)]&.join}\e[0K" } +
57
+ Array.new(blank_lines) { "\e[0K" }
46
58
  end
47
59
 
48
- # selects a named range of characters
49
- #
50
- # sym: the name of the range
51
- # char_range: a Range representing the starting and ending byte of the
52
- # selection
53
- def select(sym, char_range)
54
- @selections[sym] = char_range
60
+ # the number of visible lines from @lines at any given time
61
+ def visible_lines
62
+ [h, @lines.length - r].min
63
+ end
55
64
 
56
- nil
65
+ # the number of blank lines in the buffer after showing all visible lines
66
+ def blank_lines
67
+ [@win[3] - visible_lines, 0].max
57
68
  end
58
69
 
59
- # line: the line to insert
60
- # index: the index to insert it at (NOT the 1-based line number)
61
- def insert_line(line, index)
62
- @content.insert(line, index)
63
- @length += line.length
70
+ # scrolls the visible window up
71
+ def win_up(n=1)
72
+ @win[0] = [@win[0] - n, 0].max
64
73
  end
65
74
 
66
- # str: the String to insert
67
- # char_num: the char_num at which to start the insertion
68
- def insert_text(str, char_num)
69
- # TODO: this is tricky because if the string contains multiple lines then
70
- # you're not just inserting in the middle of an existing line, you're
71
- # inserting some text which may include multiple lines
75
+ # scrolls the visible window down
76
+ def win_down(n=1)
77
+ @win[0] = [@win[0] + n, @lines.length - 1].min
72
78
  end
73
79
 
74
- # index: the indext of the line to delete (NOT the 1-based line number)
75
- def delete_at(index)
76
- @length -= @content[index].length
77
- @content.delete_at(index)
80
+ # scrolls the visible window left
81
+ def win_left(n=1)
82
+ @win[1] = [@win[1] - n, 0].max
78
83
  end
79
84
 
80
- # char_range: the range of characters to remove from this TinyBuff
81
- def delete_range(char_range)
82
- # TODO: this deletes the Range of characters, which may span multiple lines
85
+ # scrolls the visible window right
86
+ def win_right(n=1)
87
+ @win[1] = [@win[1] + n, max_char_width - 1].min
83
88
  end
84
89
 
85
- # line: the line to add to the end of the buffer
86
- def push(line)
87
- @content << line
88
- @length += line.length
90
+ # set a mark, as in the Vim sense
91
+ #
92
+ # sym: the name of the mark
93
+ # char_num: the number of characters from the top of the buffer to set the
94
+ # mark
95
+ def mark(sym, char_num)
96
+ @marks[sym] = [@chars, char_num].min
89
97
 
90
98
  nil
91
99
  end
92
- alias << push
93
-
94
- # deletes and returns the last line of this buffer
95
- def pop
96
- @length -= (@content.pop).length
97
100
 
101
+ # remote a mark by name
102
+ #
103
+ # sym: the name of the mark to remove
104
+ def unmark(sym)
105
+ @marks.delete(sym)
106
+
98
107
  nil
99
108
  end
100
109
 
101
- # line: the line to be added to the beginning of the buffer
102
- def unshift(line)
103
- @content.unshift(line)
104
- @length += line.length
110
+ # selects a named range of characters. selections are used to highlight
111
+ # chunks of text that you can refer to later. by giving them a name it's like
112
+ # having a clipboard with multiple clips on it.
113
+ #
114
+ # sym: the name of the selection
115
+ # char_range: a Range representing the starting and ending char of the
116
+ # selection
117
+ def select(sym, char_range)
118
+ @selections[sym] = char_range
105
119
 
106
120
  nil
107
121
  end
108
- alias >> unshift
109
122
 
110
- # deletes and returns the first line of the buffer
111
- def shift
112
- @length -= (@content.shift).length
123
+ # deletes a named selection
124
+ #
125
+ # sym: the name of the selection
126
+ # char_range: a Range representing the starting and ending char of the
127
+ # selection
128
+ def unselect(sym)
129
+ @selections.delete(sym)
130
+
131
+ nil
113
132
  end
114
133
 
115
- def to_s
116
- @content.join("\n")
134
+ # line: the line to add to the end of the buffer
135
+ def <<(line)
136
+ line.chomp!
137
+ @lines << line
138
+ @bytes += line.length
139
+ @chars += line.chars.length
140
+ @max_char_width = line.chars.length if line.chars.length > @max_char_width
141
+
142
+ nil
117
143
  end
144
+ #
145
+ # # deletes and returns the last line of this buffer
146
+ # def pop
147
+ # l = @lines.pop
148
+ # @bytes -= l.length
149
+ # @chars -= l.chars.length
150
+ #
151
+ # nil
152
+ # end
153
+ #
154
+ # # line: the line to be added to the beginning of the buffer
155
+ # def unshift(line)
156
+ # @lines.unshift(line)
157
+ # @bytes += line.length
158
+ # @chars += line.chars.length
159
+ #
160
+ # nil
161
+ # end
162
+ # alias >> unshift
163
+ #
164
+ # # deletes and returns the first line of the buffer
165
+ # def shift
166
+ # l = @lines.shift
167
+ # @bytes -= l.length
168
+ # @chars -= l.chars.length
169
+ # end
118
170
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fancy_buff
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Lunt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2023-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: a text buffer with marks, selections, and simple insert/delete
14
28
  email: jefflunt@gmail.com
15
29
  executables: []