fancy_buff 2.0.0 → 2.2.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 +138 -76
  3. metadata +31 -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: 919af51ebb70ff27b989e17db097db51eaae6c588200d86cc081c5e2c1e8d523
4
+ data.tar.gz: '049b9b7c4233e5aee2e807e16e5027fd703da72b6683231e348645df141889ee'
5
5
  SHA512:
6
- metadata.gz: fd662a50783b6a3af23bdbd70f3065952a7d1faac12af6208a699ee53527d26d60f5958fcf9b045e6ba0fb196744db151a38395966332aee70ae8eb383d30828
7
- data.tar.gz: befd4e7240600a0001697c647eaef1efef60a0635cc5db27988b580ad0930d3538de02d4f6a0390476c444753d29b12c63d47919d7d7ee0869933e42e37d274f
6
+ metadata.gz: fcb544d92688baa82919afb8fafcbc7761bc83db052759a0b6d25f15532f3b0a5d23a93628aecc1882dfcbc3a856b38241e9c846d7edae3536a1629ad18513e3
7
+ data.tar.gz: 4aa39cc8ac44c11c0bc3b31bd9f9ba882611e752bed58248301cfec5e3ad85e71c85c1e88b1312beeed36552c9894980557c06a230b74768832729bc158860e8
data/lib/fancy_buff.rb CHANGED
@@ -1,118 +1,180 @@
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
+ #
17
+ # formatter - a Rouge formatter
18
+ # lexer - a Rouge lexer
19
+ def initialize(formatter, lexer)
20
+ @formatter = formatter
21
+ @lexer = lexer
22
+
23
+ # size tracking
24
+ @chars = 0 # the number of characters in the buffer (not the same as the number of bytes)
25
+ @bytes = 0 # the number of bytes in the buffer (not the same as the number of characters)
26
+ @lines = []
27
+ @max_char_width = 0
28
+ @all_buff = @lines.join("\n")
4
29
 
5
- # content: the starting content of the buffer as a String
6
- def initialize(content='')
7
- @content = content.lines.map(&:chomp)
8
30
  @marks = {}
9
31
  @selections = {}
32
+ @win = [0, 0, 0, 0] # the default slice is at the beginning of the buffer, and has a zero size
33
+ end
10
34
 
11
- @length = @content
12
- .map{|l| l.length }
13
- .sum
35
+ # index of first visible row
36
+ def r
37
+ @win[0]
14
38
  end
15
39
 
16
- # returns the number of lines
17
- def lines
18
- @content.length
40
+ # index of first visible column
41
+ def c
42
+ @win[1]
19
43
  end
20
44
 
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] }
45
+ # width of the buffer window
46
+ def w
47
+ @win[2]
26
48
  end
27
49
 
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 }
50
+ # height of the buffer window
51
+ def h
52
+ @win[3]
35
53
  end
36
54
 
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
55
+ # returns an array of strings representing the visible characters from this
56
+ # FancyBuffer's @rect
57
+ def win_s
58
+ r, c, w, h = @win
44
59
 
45
- nil
60
+ return [] if h == 0 || w == 0
61
+
62
+ text = @formatter
63
+ .format(@lexer.lex(@lines.join("\n")))
64
+ .lines[r..(r + visible_lines - 1)]
65
+ .map.with_index{|row, i| "#{(i + r + 1).to_s.rjust(3)} #{row.chars[c..(c + w - 1 - 4)]&.join}" }
66
+ .map{|l| l.chomp + "\e[0K" } +
67
+ Array.new(blank_lines) { "\e[0K" }
46
68
  end
47
69
 
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
70
+ # the number of visible lines from @lines at any given time
71
+ def visible_lines
72
+ [h, @lines.length - r].min
73
+ end
55
74
 
56
- nil
75
+ # the number of blank lines in the buffer after showing all visible lines
76
+ def blank_lines
77
+ [@win[3] - visible_lines, 0].max
57
78
  end
58
79
 
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
80
+ # scrolls the visible window up
81
+ def win_up(n=1)
82
+ @win[0] = [@win[0] - n, 0].max
64
83
  end
65
84
 
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
85
+ # scrolls the visible window down
86
+ def win_down(n=1)
87
+ @win[0] = [@win[0] + n, @lines.length - 1].min
72
88
  end
73
89
 
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)
90
+ # scrolls the visible window left
91
+ def win_left(n=1)
92
+ @win[1] = [@win[1] - n, 0].max
78
93
  end
79
94
 
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
95
+ # scrolls the visible window right
96
+ def win_right(n=1)
97
+ @win[1] = [@win[1] + n, max_char_width - 1].min
83
98
  end
84
99
 
85
- # line: the line to add to the end of the buffer
86
- def push(line)
87
- @content << line
88
- @length += line.length
100
+ # set a mark, as in the Vim sense
101
+ #
102
+ # sym: the name of the mark
103
+ # char_num: the number of characters from the top of the buffer to set the
104
+ # mark
105
+ def mark(sym, char_num)
106
+ @marks[sym] = [@chars, char_num].min
89
107
 
90
108
  nil
91
109
  end
92
- alias << push
93
-
94
- # deletes and returns the last line of this buffer
95
- def pop
96
- @length -= (@content.pop).length
97
110
 
111
+ # remote a mark by name
112
+ #
113
+ # sym: the name of the mark to remove
114
+ def unmark(sym)
115
+ @marks.delete(sym)
116
+
98
117
  nil
99
118
  end
100
119
 
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
120
+ # selects a named range of characters. selections are used to highlight
121
+ # chunks of text that you can refer to later. by giving them a name it's like
122
+ # having a clipboard with multiple clips on it.
123
+ #
124
+ # sym: the name of the selection
125
+ # char_range: a Range representing the starting and ending char of the
126
+ # selection
127
+ def select(sym, char_range)
128
+ @selections[sym] = char_range
105
129
 
106
130
  nil
107
131
  end
108
- alias >> unshift
109
132
 
110
- # deletes and returns the first line of the buffer
111
- def shift
112
- @length -= (@content.shift).length
133
+ # deletes a named selection
134
+ #
135
+ # sym: the name of the selection
136
+ # char_range: a Range representing the starting and ending char of the
137
+ # selection
138
+ def unselect(sym)
139
+ @selections.delete(sym)
140
+
141
+ nil
113
142
  end
114
143
 
115
- def to_s
116
- @content.join("\n")
144
+ # line: the line to add to the end of the buffer
145
+ def <<(line)
146
+ line.chomp!
147
+ @lines << line
148
+ @bytes += line.length
149
+ @chars += line.chars.length
150
+ @max_char_width = line.chars.length if line.chars.length > @max_char_width
151
+
152
+ nil
117
153
  end
154
+ #
155
+ # # deletes and returns the last line of this buffer
156
+ # def pop
157
+ # l = @lines.pop
158
+ # @bytes -= l.length
159
+ # @chars -= l.chars.length
160
+ #
161
+ # nil
162
+ # end
163
+ #
164
+ # # line: the line to be added to the beginning of the buffer
165
+ # def unshift(line)
166
+ # @lines.unshift(line)
167
+ # @bytes += line.length
168
+ # @chars += line.chars.length
169
+ #
170
+ # nil
171
+ # end
172
+ # alias >> unshift
173
+ #
174
+ # # deletes and returns the first line of the buffer
175
+ # def shift
176
+ # l = @lines.shift
177
+ # @bytes -= l.length
178
+ # @chars -= l.chars.length
179
+ # end
118
180
  end
metadata CHANGED
@@ -1,15 +1,43 @@
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.2.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-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rouge
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: a text buffer with marks, selections, and simple insert/delete
14
42
  email: jefflunt@gmail.com
15
43
  executables: []