textbringer 0.3.2 → 1.0.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 +4 -4
- data/CHANGES.md +6 -0
- data/README.md +6 -9
- data/exe/textbringer +5 -0
- data/lib/textbringer/buffer.rb +40 -37
- data/lib/textbringer/commands/buffers.rb +22 -0
- data/lib/textbringer/commands/fill.rb +1 -1
- data/lib/textbringer/commands/isearch.rb +1 -1
- data/lib/textbringer/commands/misc.rb +27 -23
- data/lib/textbringer/controller.rb +2 -2
- data/lib/textbringer/keymap.rb +2 -0
- data/lib/textbringer/utils.rb +1 -1
- data/lib/textbringer/version.rb +1 -1
- data/logo/logo.jpg +0 -0
- data/logo/logo.png +0 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 670221472ba70164a2f44759e11011d8e70a5f467e067e4e400d732fe4082323
|
4
|
+
data.tar.gz: 26d15a0030cc1217f131ba761309b3d9bb17078fa5cfd1db24c651bdd5384fb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 000e800e06a430312b133dce7017c560723a473866cbb2c82754ac6af1da6f398be2cdf17b9708f20109784b698b70bb073c744afa4d7f7cc0e086b51db17ffc
|
7
|
+
data.tar.gz: ccb23431483eabe736e285d9ee72a17f7cb4f72be07fd049ec091f727a5671cd396e30504cd725d0938614a0fd58a56b8c5547a9e4d1275fd8faf8b654c6b25d
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Textbringer
|
1
|
+
# 
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/textbringer)
|
4
4
|
[](https://travis-ci.org/shugo/textbringer)
|
@@ -18,14 +18,6 @@ text editor.
|
|
18
18
|
* Ruby Programming: https://asciinema.org/a/100156
|
19
19
|
* Japanese Text Editing: https://asciinema.org/a/100166
|
20
20
|
|
21
|
-
## WARNING
|
22
|
-
|
23
|
-
Textbringer is beta software, and you may lose your text. Unsaved buffers will
|
24
|
-
be dumped in ~/.textbringer/buffer_dump on crash.
|
25
|
-
|
26
|
-
APIs are undocumented and unstable. There is no compatibility even in the same
|
27
|
-
minor versions.
|
28
|
-
|
29
21
|
## Installation
|
30
22
|
|
31
23
|
$ gem install textbringer
|
@@ -115,3 +107,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/shugo/
|
|
115
107
|
## License
|
116
108
|
|
117
109
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
110
|
+
|
111
|
+
|
112
|
+
## Credit
|
113
|
+
|
114
|
+
Logo made with [DesignEvo](https://www.designevo.com/en/).
|
data/exe/textbringer
CHANGED
data/lib/textbringer/buffer.rb
CHANGED
@@ -205,7 +205,7 @@ module Textbringer
|
|
205
205
|
end
|
206
206
|
|
207
207
|
# s might not be copied.
|
208
|
-
def initialize(s =
|
208
|
+
def initialize(s = +"", name: nil,
|
209
209
|
file_name: nil,
|
210
210
|
file_encoding: CONFIG[:default_file_encoding],
|
211
211
|
file_mtime: nil, new_file: true, undo_limit: UNDO_LIMIT,
|
@@ -964,7 +964,7 @@ module Textbringer
|
|
964
964
|
|
965
965
|
def clear
|
966
966
|
check_read_only_flag
|
967
|
-
@contents =
|
967
|
+
@contents = +""
|
968
968
|
@point = @gap_start = @gap_end = 0
|
969
969
|
@marks.each do |m|
|
970
970
|
m.location = 0
|
@@ -1065,40 +1065,54 @@ module Textbringer
|
|
1065
1065
|
end
|
1066
1066
|
end
|
1067
1067
|
|
1068
|
-
def re_search_forward(s, raise_error: true)
|
1068
|
+
def re_search_forward(s, raise_error: true, count: 1)
|
1069
|
+
if count < 0
|
1070
|
+
return re_search_backward(s, raise_error: raise_error, count: -count)
|
1071
|
+
end
|
1069
1072
|
re = new_regexp(s)
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1073
|
+
pos = @point
|
1074
|
+
count.times do
|
1075
|
+
i = byteindex(true, re, pos)
|
1076
|
+
if i.nil?
|
1077
|
+
if raise_error
|
1078
|
+
raise SearchError, "Search failed"
|
1079
|
+
else
|
1080
|
+
return nil
|
1081
|
+
end
|
1076
1082
|
end
|
1083
|
+
pos = match_end(0)
|
1077
1084
|
end
|
1078
|
-
goto_char(
|
1085
|
+
goto_char(pos)
|
1079
1086
|
end
|
1080
1087
|
|
1081
|
-
def re_search_backward(s, raise_error: true)
|
1088
|
+
def re_search_backward(s, raise_error: true, count: 1)
|
1089
|
+
if count < 0
|
1090
|
+
return re_search_forward(s, raise_error: raise_error, count: -count)
|
1091
|
+
end
|
1082
1092
|
re = new_regexp(s)
|
1083
1093
|
pos = @point
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1094
|
+
count.times do
|
1095
|
+
p = pos
|
1096
|
+
begin
|
1097
|
+
i = byteindex(false, re, p)
|
1098
|
+
if i.nil?
|
1099
|
+
if raise_error
|
1100
|
+
raise SearchError, "Search failed"
|
1101
|
+
else
|
1102
|
+
return nil
|
1103
|
+
end
|
1104
|
+
end
|
1105
|
+
p = get_pos(p, -1)
|
1106
|
+
rescue RangeError
|
1087
1107
|
if raise_error
|
1088
1108
|
raise SearchError, "Search failed"
|
1089
1109
|
else
|
1090
1110
|
return nil
|
1091
1111
|
end
|
1092
|
-
end
|
1093
|
-
pos =
|
1094
|
-
|
1095
|
-
|
1096
|
-
raise SearchError, "Search failed"
|
1097
|
-
else
|
1098
|
-
return nil
|
1099
|
-
end
|
1100
|
-
end while match_end(0) > @point
|
1101
|
-
goto_char(match_beginning(0))
|
1112
|
+
end while match_end(0) > pos
|
1113
|
+
pos = match_beginning(0)
|
1114
|
+
end
|
1115
|
+
goto_char(pos)
|
1102
1116
|
end
|
1103
1117
|
|
1104
1118
|
def looking_at?(re)
|
@@ -1233,7 +1247,7 @@ module Textbringer
|
|
1233
1247
|
end
|
1234
1248
|
|
1235
1249
|
def gap_filled_with_nul?
|
1236
|
-
/\A\0*\z
|
1250
|
+
/\A\0*\z/.match?(@contents[@gap_start...@gap_end])
|
1237
1251
|
end
|
1238
1252
|
|
1239
1253
|
def composite_edit
|
@@ -1338,7 +1352,7 @@ module Textbringer
|
|
1338
1352
|
def gsub(*args, &block)
|
1339
1353
|
if block
|
1340
1354
|
s = to_s.gsub(*args) { |*params|
|
1341
|
-
|
1355
|
+
block.binding.eval('->(backref) { $~ = backref }').call($~)
|
1342
1356
|
block.call(*params)
|
1343
1357
|
}
|
1344
1358
|
else
|
@@ -1576,17 +1590,6 @@ module Textbringer
|
|
1576
1590
|
callback.call(self)
|
1577
1591
|
end
|
1578
1592
|
end
|
1579
|
-
|
1580
|
-
def set_block_backref(block, backref)
|
1581
|
-
Thread.current[:__textbringer_backref] = backref
|
1582
|
-
begin
|
1583
|
-
block.binding.eval(<<-EOC)
|
1584
|
-
$~ = Thread.current[:__textbringer_backref]
|
1585
|
-
EOC
|
1586
|
-
ensure
|
1587
|
-
Thread.current[:__textbringer_backref] = nil
|
1588
|
-
end
|
1589
|
-
end
|
1590
1593
|
end
|
1591
1594
|
|
1592
1595
|
class Mark
|
@@ -244,5 +244,27 @@ module Textbringer
|
|
244
244
|
buffer.insert(" ")
|
245
245
|
buffer.backward_char
|
246
246
|
end
|
247
|
+
|
248
|
+
define_command(:mark_whole_buffer,
|
249
|
+
doc: <<~EOD) do
|
250
|
+
Put point at beginning and mark at end of buffer.
|
251
|
+
EOD
|
252
|
+
buffer = Buffer.current
|
253
|
+
buffer.push_mark
|
254
|
+
buffer.push_mark(buffer.point_max)
|
255
|
+
buffer.beginning_of_buffer
|
256
|
+
end
|
257
|
+
|
258
|
+
define_command(:zap_to_char,
|
259
|
+
doc: <<~EOD) do
|
260
|
+
Kill up to and including count-th occurrence of char.
|
261
|
+
EOD
|
262
|
+
|char = read_char, count: number_prefix_arg|
|
263
|
+
|
264
|
+
buffer = Buffer.current
|
265
|
+
s = buffer.point
|
266
|
+
e = buffer.re_search_forward(Regexp.quote(char), count: count)
|
267
|
+
buffer.kill_region(s, e)
|
268
|
+
end
|
247
269
|
end
|
248
270
|
end
|
@@ -43,7 +43,7 @@ module Textbringer
|
|
43
43
|
|
44
44
|
def isearch_mode(forward, recursive_edit: false)
|
45
45
|
ISEARCH_STATUS[:forward] = forward
|
46
|
-
ISEARCH_STATUS[:string] =
|
46
|
+
ISEARCH_STATUS[:string] = +""
|
47
47
|
ISEARCH_STATUS[:recursive_edit] = recursive_edit
|
48
48
|
Controller.current.overriding_map = ISEARCH_MODE_MAP
|
49
49
|
run_hooks(:isearch_mode_hook)
|
@@ -282,31 +282,35 @@ module Textbringer
|
|
282
282
|
if CONFIG[:shell_file_name]
|
283
283
|
cmd = [CONFIG[:shell_file_name], CONFIG[:shell_command_switch], cmd]
|
284
284
|
end
|
285
|
-
Open3.
|
285
|
+
Open3.popen3(*cmd, opts) do |input, output, error, wait_thread|
|
286
286
|
input.close
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
287
|
+
catch(:finish) do
|
288
|
+
loop do
|
289
|
+
rs, = IO.select([output, error], nil, nil, 0.5)
|
290
|
+
Window.redisplay
|
291
|
+
rs&.each do |r|
|
292
|
+
begin
|
293
|
+
s = r.read_nonblock(1024).force_encoding("utf-8").
|
294
|
+
scrub("\u{3013}").gsub(/\r\n/, "\n")
|
295
|
+
buffer.insert(s)
|
296
|
+
Window.redisplay
|
297
|
+
rescue EOFError
|
298
|
+
throw(:finish)
|
299
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
300
|
+
Window.redisplay
|
301
|
+
next
|
302
|
+
end
|
299
303
|
end
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
304
|
+
if received_keyboard_quit?
|
305
|
+
if signals.empty?
|
306
|
+
keyboard_quit
|
307
|
+
else
|
308
|
+
sig = signals.shift
|
309
|
+
pid = wait_thread.pid
|
310
|
+
pid = -pid if /mswin32|mingw32/ !~ RUBY_PLATFORM
|
311
|
+
message("Send #{sig} to #{pid}")
|
312
|
+
Process.kill(sig, pid)
|
313
|
+
end
|
310
314
|
end
|
311
315
|
end
|
312
316
|
end
|
@@ -128,7 +128,7 @@ module Textbringer
|
|
128
128
|
else
|
129
129
|
wait_files = [STDIN, @next_tick_input]
|
130
130
|
end
|
131
|
-
files, = IO.select(wait_files,
|
131
|
+
files, = IO.select(wait_files, nil, nil, 1)
|
132
132
|
# KEY_RESIZE may be returned even if STDIN is not included in files.
|
133
133
|
event = read_event_nonblock
|
134
134
|
if event
|
@@ -178,7 +178,7 @@ module Textbringer
|
|
178
178
|
return if wait_input(1000)
|
179
179
|
end
|
180
180
|
@echo_immediately = true
|
181
|
-
s =
|
181
|
+
s = +""
|
182
182
|
if @prefix_arg
|
183
183
|
s << "C-u"
|
184
184
|
if @prefix_arg != [4]
|
data/lib/textbringer/keymap.rb
CHANGED
@@ -144,6 +144,8 @@ module Textbringer
|
|
144
144
|
GLOBAL_MAP.define_key("\C-o", :open_line)
|
145
145
|
GLOBAL_MAP.define_key("\em", :back_to_indentation)
|
146
146
|
GLOBAL_MAP.define_key("\e^", :delete_indentation)
|
147
|
+
GLOBAL_MAP.define_key("\C-xh", :mark_whole_buffer)
|
148
|
+
GLOBAL_MAP.define_key("\ez", :zap_to_char)
|
147
149
|
GLOBAL_MAP.define_key("\C-l", :recenter)
|
148
150
|
GLOBAL_MAP.define_key("\C-v", :scroll_up)
|
149
151
|
GLOBAL_MAP.define_key(:npage, :scroll_up)
|
data/lib/textbringer/utils.rb
CHANGED
data/lib/textbringer/version.rb
CHANGED
data/logo/logo.jpg
ADDED
Binary file
|
data/logo/logo.png
ADDED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: textbringer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -227,6 +227,8 @@ files:
|
|
227
227
|
- lib/textbringer/utils.rb
|
228
228
|
- lib/textbringer/version.rb
|
229
229
|
- lib/textbringer/window.rb
|
230
|
+
- logo/logo.jpg
|
231
|
+
- logo/logo.png
|
230
232
|
- screenshot.png
|
231
233
|
- textbringer.gemspec
|
232
234
|
homepage: https://github.com/shugo/textbringer
|
@@ -248,8 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
250
|
- !ruby/object:Gem::Version
|
249
251
|
version: '0'
|
250
252
|
requirements: []
|
251
|
-
|
252
|
-
rubygems_version: 3.0.0.beta3
|
253
|
+
rubygems_version: 3.1.0.pre1
|
253
254
|
signing_key:
|
254
255
|
specification_version: 4
|
255
256
|
summary: An Emacs-like text editor
|