fancy_buff 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []