textbringer 0.3.2 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.github/workflows/macos.yml +15 -0
- data/.github/workflows/ubuntu.yml +25 -0
- data/.github/workflows/windows.yml +19 -0
- data/CHANGES.md +29 -0
- data/README.md +4 -11
- data/exe/textbringer +5 -0
- data/lib/textbringer.rb +0 -2
- data/lib/textbringer/buffer.rb +43 -42
- data/lib/textbringer/color.rb +0 -2
- data/lib/textbringer/commands.rb +0 -2
- data/lib/textbringer/commands/buffers.rb +22 -2
- data/lib/textbringer/commands/clipboard.rb +3 -5
- data/lib/textbringer/commands/ctags.rb +3 -5
- data/lib/textbringer/commands/dabbrev.rb +1 -3
- data/lib/textbringer/commands/files.rb +10 -5
- data/lib/textbringer/commands/fill.rb +2 -2
- data/lib/textbringer/commands/help.rb +25 -18
- data/lib/textbringer/commands/isearch.rb +11 -4
- data/lib/textbringer/commands/keyboard_macro.rb +0 -2
- data/lib/textbringer/commands/misc.rb +29 -27
- data/lib/textbringer/commands/register.rb +0 -2
- data/lib/textbringer/commands/replace.rb +0 -2
- data/lib/textbringer/commands/server.rb +0 -2
- data/lib/textbringer/commands/windows.rb +0 -2
- data/lib/textbringer/config.rb +0 -2
- data/lib/textbringer/controller.rb +2 -4
- data/lib/textbringer/errors.rb +0 -2
- data/lib/textbringer/face.rb +0 -2
- data/lib/textbringer/faces/basic.rb +0 -2
- data/lib/textbringer/faces/programming.rb +0 -2
- data/lib/textbringer/keymap.rb +44 -26
- data/lib/textbringer/mode.rb +0 -2
- data/lib/textbringer/modes/backtrace_mode.rb +1 -3
- data/lib/textbringer/modes/buffer_list_mode.rb +1 -3
- data/lib/textbringer/modes/c_mode.rb +4 -2
- data/lib/textbringer/modes/completion_list_mode.rb +1 -3
- data/lib/textbringer/modes/fundamental_mode.rb +0 -2
- data/lib/textbringer/modes/help_mode.rb +1 -3
- data/lib/textbringer/modes/programming_mode.rb +25 -5
- data/lib/textbringer/modes/ruby_mode.rb +33 -10
- data/lib/textbringer/plugin.rb +0 -2
- data/lib/textbringer/ring.rb +0 -2
- data/lib/textbringer/utils.rb +8 -7
- data/lib/textbringer/version.rb +1 -3
- data/lib/textbringer/window.rb +5 -3
- data/logo/logo.jpg +0 -0
- data/logo/logo.png +0 -0
- metadata +12 -9
- data/.travis.yml +0 -56
- data/appveyor.yml +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cadae924b2e85758480d58a7f4ba6ff48fc6ac1971039159a8b81a1a0bbbd29
|
4
|
+
data.tar.gz: cb981c7fb394e1c4683cd1365f5da1ed1f372c4254d3e9d8ca5782cad18cf167
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a57df2132fc40661649106e25f523e7f866ae469020fb33b687d1bf05921f0b4f17915271df4745035737b3be0c65d34650ae55af3ca10d4f677d7c2ac4d7715
|
7
|
+
data.tar.gz: fd5081ffaa6a8f42466fdc9fd82d6acd4a732941c66d5e2d37fd1c2a66cafba947de668a08ea60ac87f171306aadcaeca6e815991666bcac47ac376a8cd16d73
|
data/.gitattributes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.rb diff=ruby
|
@@ -0,0 +1,15 @@
|
|
1
|
+
name: macos
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: macos-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@master
|
10
|
+
- name: Install dependencies
|
11
|
+
run: |
|
12
|
+
gem install bundler --no-document
|
13
|
+
bundle install
|
14
|
+
- name: Run test
|
15
|
+
run: bundle exec rake test
|
@@ -0,0 +1,25 @@
|
|
1
|
+
name: ubuntu
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
strategy:
|
8
|
+
matrix:
|
9
|
+
ruby: [ head, 2.7, 2.6, 2.5, 2.4 ]
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v2
|
13
|
+
- uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: ${{ matrix.ruby }}
|
16
|
+
- name: Install dependencies
|
17
|
+
run: |
|
18
|
+
sudo apt install libncursesw5-dev
|
19
|
+
gem install bundler --no-document
|
20
|
+
bundle install
|
21
|
+
- name: Run test
|
22
|
+
run: xvfb-run bundle exec rake test
|
23
|
+
env:
|
24
|
+
UPLOAD_TO_CODECOV: 1
|
25
|
+
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
name: windows
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: windows-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
ruby: [ 'mingw', 'mswin', '2.7', '2.6', '2.5' ]
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v2
|
13
|
+
- name: Set up Ruby
|
14
|
+
uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: ${{ matrix.ruby }}
|
17
|
+
bundler-cache: true
|
18
|
+
- name: Run test
|
19
|
+
run: bundle exec rake test
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
## 1.0.4
|
2
|
+
|
3
|
+
* Support Ruby 3.0.
|
4
|
+
* Do not record backtrace of Quit (C-g).
|
5
|
+
|
6
|
+
## 1.0.3
|
7
|
+
|
8
|
+
* Fix indentation bugs.
|
9
|
+
* Fix a bug of fourground! when it is called in the main thread.
|
10
|
+
|
11
|
+
## 1.0.2
|
12
|
+
|
13
|
+
* Add isearch_quoted_insert.
|
14
|
+
* Use M- notation instead of ESC in define_key and help.
|
15
|
+
* Add indent_new_comment_line_command.
|
16
|
+
* Add find_alternate_file.
|
17
|
+
* Fix indentation bugs in the Ruby mode.
|
18
|
+
|
19
|
+
## 1.0.1
|
20
|
+
|
21
|
+
* Support pattern matching in the Ruby mode.
|
22
|
+
* Bug fixes.
|
23
|
+
|
24
|
+
## 1.0.0
|
25
|
+
|
26
|
+
* Add mark_whole_buffer.
|
27
|
+
* Add zap_to_char.
|
28
|
+
* Exit on SIGTERM, SIGHUP etc.
|
29
|
+
|
1
30
|
## 0.3.2
|
2
31
|
|
3
32
|
* Drop Ruby 2.3 support.
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
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
|
-
[![
|
5
|
-
[![
|
4
|
+
[![ubuntu](https://github.com/shugo/textbringer/workflows/ubuntu/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Aubuntu)
|
5
|
+
[![windows](https://github.com/shugo/textbringer/workflows/windows/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Awindows)
|
6
|
+
[![macos](https://github.com/shugo/textbringer/workflows/macos/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Amacos)
|
6
7
|
[![codecov](https://codecov.io/gh/shugo/textbringer/branch/master/graph/badge.svg)](https://codecov.io/gh/shugo/textbringer)
|
7
8
|
|
8
9
|
Textbringer is a member of a demon race that takes on the form of an Emacs-like
|
@@ -18,14 +19,6 @@ text editor.
|
|
18
19
|
* Ruby Programming: https://asciinema.org/a/100156
|
19
20
|
* Japanese Text Editing: https://asciinema.org/a/100166
|
20
21
|
|
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
22
|
## Installation
|
30
23
|
|
31
24
|
$ gem install textbringer
|
data/exe/textbringer
CHANGED
data/lib/textbringer.rb
CHANGED
data/lib/textbringer/buffer.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "nkf"
|
4
2
|
require "unicode/display_width"
|
5
3
|
require "json"
|
@@ -205,7 +203,7 @@ def display_width(s)
|
|
205
203
|
end
|
206
204
|
|
207
205
|
# s might not be copied.
|
208
|
-
def initialize(s =
|
206
|
+
def initialize(s = +"", name: nil,
|
209
207
|
file_name: nil,
|
210
208
|
file_encoding: CONFIG[:default_file_encoding],
|
211
209
|
file_mtime: nil, new_file: true, undo_limit: UNDO_LIMIT,
|
@@ -524,7 +522,7 @@ def goto_char(pos)
|
|
524
522
|
if pos < 0 || pos > size
|
525
523
|
raise RangeError, "Out of buffer"
|
526
524
|
end
|
527
|
-
if !@binary && /[\x80-\xbf]/n
|
525
|
+
if !@binary && byte_after(pos)&.match?(/[\x80-\xbf]/n)
|
528
526
|
raise ArgumentError, "Position is in the middle of a character"
|
529
527
|
end
|
530
528
|
@goal_column = nil
|
@@ -578,12 +576,12 @@ def insert(x, merge_undo = false)
|
|
578
576
|
|
579
577
|
def newline
|
580
578
|
indentation = save_point { |saved|
|
581
|
-
if /[ \t]
|
579
|
+
if char_after&.match?(/[ \t]/)
|
582
580
|
next ""
|
583
581
|
end
|
584
582
|
beginning_of_line
|
585
583
|
s = @point
|
586
|
-
while /[ \t]
|
584
|
+
while char_after&.match?(/[ \t]/)
|
587
585
|
forward_char
|
588
586
|
end
|
589
587
|
str = substring(s, @point)
|
@@ -964,7 +962,7 @@ def replace(str, start: point_min, end: point_max)
|
|
964
962
|
|
965
963
|
def clear
|
966
964
|
check_read_only_flag
|
967
|
-
@contents =
|
965
|
+
@contents = +""
|
968
966
|
@point = @gap_start = @gap_end = 0
|
969
967
|
@marks.each do |m|
|
970
968
|
m.location = 0
|
@@ -1065,40 +1063,54 @@ def redo
|
|
1065
1063
|
end
|
1066
1064
|
end
|
1067
1065
|
|
1068
|
-
def re_search_forward(s, raise_error: true)
|
1066
|
+
def re_search_forward(s, raise_error: true, count: 1)
|
1067
|
+
if count < 0
|
1068
|
+
return re_search_backward(s, raise_error: raise_error, count: -count)
|
1069
|
+
end
|
1069
1070
|
re = new_regexp(s)
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1071
|
+
pos = @point
|
1072
|
+
count.times do
|
1073
|
+
i = byteindex(true, re, pos)
|
1074
|
+
if i.nil?
|
1075
|
+
if raise_error
|
1076
|
+
raise SearchError, "Search failed"
|
1077
|
+
else
|
1078
|
+
return nil
|
1079
|
+
end
|
1076
1080
|
end
|
1081
|
+
pos = match_end(0)
|
1077
1082
|
end
|
1078
|
-
goto_char(
|
1083
|
+
goto_char(pos)
|
1079
1084
|
end
|
1080
1085
|
|
1081
|
-
def re_search_backward(s, raise_error: true)
|
1086
|
+
def re_search_backward(s, raise_error: true, count: 1)
|
1087
|
+
if count < 0
|
1088
|
+
return re_search_forward(s, raise_error: raise_error, count: -count)
|
1089
|
+
end
|
1082
1090
|
re = new_regexp(s)
|
1083
1091
|
pos = @point
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1092
|
+
count.times do
|
1093
|
+
p = pos
|
1094
|
+
begin
|
1095
|
+
i = byteindex(false, re, p)
|
1096
|
+
if i.nil?
|
1097
|
+
if raise_error
|
1098
|
+
raise SearchError, "Search failed"
|
1099
|
+
else
|
1100
|
+
return nil
|
1101
|
+
end
|
1102
|
+
end
|
1103
|
+
p = get_pos(p, -1)
|
1104
|
+
rescue RangeError
|
1087
1105
|
if raise_error
|
1088
1106
|
raise SearchError, "Search failed"
|
1089
1107
|
else
|
1090
1108
|
return nil
|
1091
1109
|
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))
|
1110
|
+
end while match_end(0) > pos
|
1111
|
+
pos = match_beginning(0)
|
1112
|
+
end
|
1113
|
+
goto_char(pos)
|
1102
1114
|
end
|
1103
1115
|
|
1104
1116
|
def looking_at?(re)
|
@@ -1233,7 +1245,7 @@ def transpose_chars
|
|
1233
1245
|
end
|
1234
1246
|
|
1235
1247
|
def gap_filled_with_nul?
|
1236
|
-
|
1248
|
+
@contents[@gap_start...@gap_end]&.match?(/\A\0*\z/)
|
1237
1249
|
end
|
1238
1250
|
|
1239
1251
|
def composite_edit
|
@@ -1338,7 +1350,7 @@ def skip_re_backward(re)
|
|
1338
1350
|
def gsub(*args, &block)
|
1339
1351
|
if block
|
1340
1352
|
s = to_s.gsub(*args) { |*params|
|
1341
|
-
|
1353
|
+
block.binding.eval('->(backref) { $~ = backref }').call($~)
|
1342
1354
|
block.call(*params)
|
1343
1355
|
}
|
1344
1356
|
else
|
@@ -1576,17 +1588,6 @@ def fire_callbacks(name)
|
|
1576
1588
|
callback.call(self)
|
1577
1589
|
end
|
1578
1590
|
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
1591
|
end
|
1591
1592
|
|
1592
1593
|
class Mark
|
data/lib/textbringer/color.rb
CHANGED
data/lib/textbringer/commands.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Textbringer
|
4
2
|
module Commands
|
5
3
|
define_command(:forward_char,
|
@@ -244,5 +242,27 @@ module Commands
|
|
244
242
|
buffer.insert(" ")
|
245
243
|
buffer.backward_char
|
246
244
|
end
|
245
|
+
|
246
|
+
define_command(:mark_whole_buffer,
|
247
|
+
doc: <<~EOD) do
|
248
|
+
Put point at beginning and mark at end of buffer.
|
249
|
+
EOD
|
250
|
+
buffer = Buffer.current
|
251
|
+
buffer.push_mark
|
252
|
+
buffer.push_mark(buffer.point_max)
|
253
|
+
buffer.beginning_of_buffer
|
254
|
+
end
|
255
|
+
|
256
|
+
define_command(:zap_to_char,
|
257
|
+
doc: <<~EOD) do
|
258
|
+
Kill up to and including count-th occurrence of char.
|
259
|
+
EOD
|
260
|
+
|char = read_char, count: number_prefix_arg|
|
261
|
+
|
262
|
+
buffer = Buffer.current
|
263
|
+
s = buffer.point
|
264
|
+
e = buffer.re_search_forward(Regexp.quote(char), count: count)
|
265
|
+
buffer.kill_region(s, e)
|
266
|
+
end
|
247
267
|
end
|
248
268
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Clipboard
|
4
2
|
@implementation = nil
|
5
3
|
end
|
@@ -13,12 +11,12 @@ module Commands
|
|
13
11
|
(ENV["DISPLAY"] && system("which xclip > /dev/null 2>&1"))
|
14
12
|
|
15
13
|
if CLIPBOARD_AVAILABLE
|
16
|
-
GLOBAL_MAP.define_key("\
|
14
|
+
GLOBAL_MAP.define_key("\M-w", :clipboard_copy_region)
|
17
15
|
GLOBAL_MAP.define_key("\C-w", :clipboard_kill_region)
|
18
16
|
GLOBAL_MAP.define_key(?\C-k, :clipboard_kill_line)
|
19
|
-
GLOBAL_MAP.define_key("\
|
17
|
+
GLOBAL_MAP.define_key("\M-d", :clipboard_kill_word)
|
20
18
|
GLOBAL_MAP.define_key("\C-y", :clipboard_yank)
|
21
|
-
GLOBAL_MAP.define_key("\
|
19
|
+
GLOBAL_MAP.define_key("\M-y", :clipboard_yank_pop)
|
22
20
|
end
|
23
21
|
|
24
22
|
define_command(:clipboard_copy_region, doc: <<~EOD) do
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Textbringer
|
4
2
|
module Commands
|
5
3
|
CTAGS = {
|
@@ -51,12 +49,12 @@ module Commands
|
|
51
49
|
when /\A\d+\z/
|
52
50
|
push_tag_mark_and_find_file(file)
|
53
51
|
goto_line(addr.to_i)
|
54
|
-
when %r'\A/\^(
|
52
|
+
when %r'\A/\^(.*?)(\$)?/\z'
|
53
|
+
re = "^" + Regexp.quote($1.gsub(/\\([\\\/])/, "\\1")) + $2.to_s
|
55
54
|
push_tag_mark_and_find_file(file)
|
56
55
|
beginning_of_buffer
|
57
56
|
n.times do
|
58
|
-
|
59
|
-
re_search_forward("^" + s + "$")
|
57
|
+
re_search_forward(re)
|
60
58
|
end
|
61
59
|
beginning_of_line
|
62
60
|
when %r'\A\?\^(.*)\$\?\z'
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Textbringer
|
4
2
|
module DabbrevExtension
|
5
3
|
refine Buffer do
|
@@ -93,7 +91,7 @@ def dabbrev_regexp(stem, candidates)
|
|
93
91
|
using DabbrevExtension
|
94
92
|
|
95
93
|
module Commands
|
96
|
-
GLOBAL_MAP.define_key("\
|
94
|
+
GLOBAL_MAP.define_key("\M-/", :dabbrev_expand_command)
|
97
95
|
|
98
96
|
define_command(:dabbrev_expand_command) do
|
99
97
|
contd = Controller.current.last_command == :dabbrev_expand_command
|
@@ -1,11 +1,9 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "editorconfig"
|
4
2
|
|
5
3
|
module Textbringer
|
6
4
|
module Commands
|
7
5
|
define_command(:find_file, doc: "Open or create a file.") do
|
8
|
-
|file_name = read_file_name("Find file: ")|
|
6
|
+
|file_name = read_file_name("Find file: ", default: (Buffer.current.file_name ? File.dirname(Buffer.current.file_name) : Dir.pwd) + "/")|
|
9
7
|
config = EditorConfig.load_file(file_name)
|
10
8
|
buffer = Buffer.find_file(file_name)
|
11
9
|
if buffer.new_file?
|
@@ -88,12 +86,13 @@ module Commands
|
|
88
86
|
|
89
87
|
define_command(:write_file,
|
90
88
|
doc: "Save the current buffer as the specified file.") do
|
91
|
-
|file_name = read_file_name("Write file: "
|
89
|
+
|file_name = read_file_name("Write file: ",
|
90
|
+
default: Buffer.current.file_name)|
|
92
91
|
if File.directory?(file_name)
|
93
92
|
file_name = File.expand_path(Buffer.current.name, file_name)
|
94
93
|
end
|
95
94
|
if File.exist?(file_name)
|
96
|
-
unless y_or_n?("File
|
95
|
+
unless y_or_n?("File exists; overwrite?")
|
97
96
|
message("Cancelled")
|
98
97
|
next
|
99
98
|
end
|
@@ -126,5 +125,11 @@ module Commands
|
|
126
125
|
File.dirname(Buffer.current.file_name))|
|
127
126
|
Dir.chdir(dir_name)
|
128
127
|
end
|
128
|
+
|
129
|
+
define_command(:find_alternate_file, doc: "Find an alternate file.") do
|
130
|
+
|file_name = read_file_name("Find alternate file: ",
|
131
|
+
default: Buffer.current.file_name)|
|
132
|
+
find_file(file_name)
|
133
|
+
end
|
129
134
|
end
|
130
135
|
end
|