textbringer 0.3.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
# ![Textbringer](logo/logo.png)
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/textbringer.svg)](https://badge.fury.io/rb/textbringer)
|
4
4
|
[![Build Status](https://travis-ci.org/shugo/textbringer.svg?branch=master)](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
|