textbringer 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +7 -0
- data/appveyor.yml +2 -1
- data/lib/textbringer.rb +2 -0
- data/lib/textbringer/buffer.rb +24 -6
- data/lib/textbringer/commands/misc.rb +1 -1
- data/lib/textbringer/controller.rb +4 -1
- data/lib/textbringer/keymap.rb +0 -2
- data/lib/textbringer/mode.rb +9 -3
- data/lib/textbringer/modes/programming_mode.rb +10 -5
- data/lib/textbringer/plugin.rb +2 -9
- data/lib/textbringer/version.rb +3 -1
- data/lib/textbringer/window.rb +17 -48
- data/textbringer.gemspec +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e327730f3f4d3b64bf57ce835400f4a44475c600
|
4
|
+
data.tar.gz: 3b9adf68d12de90e5d6106e4aa2f9e4cfd0a5599
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aef52effa70699fbc3a32d80354027caf1d606ecb31331c8adfb83a5649e66a444244c73985206249046da68c2c00cf0c753ffcb974e4ff157418d7a188c9a82
|
7
|
+
data.tar.gz: 65cfd1a1cdf62888061a3b40e0e9b7620b56374927c4e2844efba890707b567badfa5586205bc1d07cc3b596c5e31e058fb7a78bc1aed3503ce0f792431f5a33
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.2.3
|
2
|
+
|
3
|
+
* Add the on_modified callback to Buffer.
|
4
|
+
* Use Gem.find_latest_files to find plugins.
|
5
|
+
* Turn off synatx highlighting when the buffer is binary.
|
6
|
+
* Add define_local_command.
|
7
|
+
|
1
8
|
## 0.2.2
|
2
9
|
|
3
10
|
* Rename read_char to read_event and add read_char as a new method.
|
data/appveyor.yml
CHANGED
@@ -4,7 +4,8 @@ install:
|
|
4
4
|
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
5
5
|
- gem install bundler --no-document
|
6
6
|
- bundle install
|
7
|
-
- ps:
|
7
|
+
- ps: '[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12'
|
8
|
+
- ps: Invoke-WebRequest -Uri https://curl.haxx.se/ca/cacert.pem -OutFile C:\projects\textbringer\cacert.pem
|
8
9
|
build: off
|
9
10
|
test_script:
|
10
11
|
- rake
|
data/lib/textbringer.rb
CHANGED
data/lib/textbringer/buffer.rb
CHANGED
@@ -12,7 +12,6 @@ module Textbringer
|
|
12
12
|
attr_accessor :mode, :keymap
|
13
13
|
attr_reader :name, :file_name, :file_encoding, :file_format, :point, :marks
|
14
14
|
attr_reader :current_line, :current_column, :visible_mark
|
15
|
-
attr_writer :modified
|
16
15
|
|
17
16
|
GAP_SIZE = 256
|
18
17
|
UNDO_LIMIT = 1000
|
@@ -226,6 +225,7 @@ module Textbringer
|
|
226
225
|
@match_offsets = []
|
227
226
|
@visible_mark = nil
|
228
227
|
@read_only = read_only
|
228
|
+
@on_modified_callbacks = []
|
229
229
|
end
|
230
230
|
|
231
231
|
def inspect
|
@@ -307,10 +307,21 @@ module Textbringer
|
|
307
307
|
@@current == self
|
308
308
|
end
|
309
309
|
|
310
|
+
def modified=(modified)
|
311
|
+
@modified = modified
|
312
|
+
if @composite_edit_level == 0 && modified
|
313
|
+
fire_on_modified_callbacks
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
310
317
|
def modified?
|
311
318
|
@modified
|
312
319
|
end
|
313
320
|
|
321
|
+
def on_modified(&callback)
|
322
|
+
@on_modified_callbacks.push(callback)
|
323
|
+
end
|
324
|
+
|
314
325
|
def [](name)
|
315
326
|
if @attributes.key?(name)
|
316
327
|
@attributes[name]
|
@@ -527,7 +538,7 @@ module Textbringer
|
|
527
538
|
push_undo(InsertAction.new(self, pos, s))
|
528
539
|
end
|
529
540
|
end
|
530
|
-
|
541
|
+
self.modified = true
|
531
542
|
@goal_column = nil
|
532
543
|
self
|
533
544
|
end
|
@@ -569,7 +580,7 @@ module Textbringer
|
|
569
580
|
end
|
570
581
|
end
|
571
582
|
push_undo(DeleteAction.new(self, s, s, str))
|
572
|
-
|
583
|
+
self.modified = true
|
573
584
|
elsif n < 0
|
574
585
|
str = substring(pos, s)
|
575
586
|
update_line_and_column(@point, pos)
|
@@ -584,7 +595,7 @@ module Textbringer
|
|
584
595
|
end
|
585
596
|
@point = @gap_start = pos
|
586
597
|
push_undo(DeleteAction.new(self, s, pos, str))
|
587
|
-
|
598
|
+
self.modified = true
|
588
599
|
end
|
589
600
|
@goal_column = nil
|
590
601
|
end
|
@@ -906,7 +917,7 @@ module Textbringer
|
|
906
917
|
end
|
907
918
|
end
|
908
919
|
push_undo(DeleteAction.new(self, old_pos, s, str))
|
909
|
-
|
920
|
+
self.modified = true
|
910
921
|
end
|
911
922
|
end
|
912
923
|
|
@@ -920,7 +931,7 @@ module Textbringer
|
|
920
931
|
@current_line = 1
|
921
932
|
@current_column = 1
|
922
933
|
@goal_column = nil
|
923
|
-
|
934
|
+
self.modified = true
|
924
935
|
@undo_stack.clear
|
925
936
|
@redo_stack.clear
|
926
937
|
end
|
@@ -1202,6 +1213,7 @@ module Textbringer
|
|
1202
1213
|
@composite_edit_actions.clear
|
1203
1214
|
end
|
1204
1215
|
end
|
1216
|
+
fire_on_modified_callbacks
|
1205
1217
|
end
|
1206
1218
|
|
1207
1219
|
def apply_mode(mode_class)
|
@@ -1490,6 +1502,12 @@ module Textbringer
|
|
1490
1502
|
raise ReadOnlyError, "Buffer is read only: #{self.inspect}"
|
1491
1503
|
end
|
1492
1504
|
end
|
1505
|
+
|
1506
|
+
def fire_on_modified_callbacks
|
1507
|
+
@on_modified_callbacks.each do |callback|
|
1508
|
+
callback.call(self)
|
1509
|
+
end
|
1510
|
+
end
|
1493
1511
|
end
|
1494
1512
|
|
1495
1513
|
class Mark
|
@@ -115,6 +115,9 @@ module Textbringer
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def read_event
|
118
|
+
if executing_keyboard_macro?
|
119
|
+
return @executing_keyboard_macro.shift
|
120
|
+
end
|
118
121
|
event = read_event_nonblock
|
119
122
|
if event
|
120
123
|
return event
|
@@ -253,7 +256,7 @@ module Textbringer
|
|
253
256
|
def read_event_with_keyboard_macro(read_event_method)
|
254
257
|
if !executing_keyboard_macro?
|
255
258
|
c = call_read_event_method(read_event_method)
|
256
|
-
if @recording_keyboard_macro
|
259
|
+
if c && @recording_keyboard_macro
|
257
260
|
@recording_keyboard_macro.push(c)
|
258
261
|
end
|
259
262
|
c
|
data/lib/textbringer/keymap.rb
CHANGED
data/lib/textbringer/mode.rb
CHANGED
@@ -20,13 +20,13 @@ module Textbringer
|
|
20
20
|
attr_reader :syntax_table
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.define_generic_command(name)
|
23
|
+
def self.define_generic_command(name, **options)
|
24
24
|
command_name = (name.to_s + "_command").intern
|
25
|
-
define_command(command_name) do |*args|
|
25
|
+
define_command(command_name, **options) do |*args|
|
26
26
|
begin
|
27
27
|
Buffer.current.mode.send(name, *args)
|
28
28
|
rescue NoMethodError => e
|
29
|
-
if e.receiver == Buffer.current.mode && e.name == name
|
29
|
+
if (e.receiver rescue nil) == Buffer.current.mode && e.name == name
|
30
30
|
raise EditorError,
|
31
31
|
"#{command_name} is not supported in the current mode"
|
32
32
|
else
|
@@ -36,6 +36,12 @@ module Textbringer
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def self.define_local_command(name, **options, &block)
|
40
|
+
define_generic_command(name, **options)
|
41
|
+
define_method(name, &block)
|
42
|
+
name
|
43
|
+
end
|
44
|
+
|
39
45
|
def self.define_syntax(face_name, re)
|
40
46
|
@syntax_table[face_name] = re
|
41
47
|
end
|
@@ -74,12 +74,17 @@ module Textbringer
|
|
74
74
|
|
75
75
|
def indent_region(s = @buffer.mark, e = @buffer.point)
|
76
76
|
s, e = Buffer.region_boundaries(s, e)
|
77
|
-
@buffer.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
@buffer.
|
77
|
+
end_mark = @buffer.new_mark(e)
|
78
|
+
begin
|
79
|
+
@buffer.save_excursion do
|
80
|
+
@buffer.goto_char(s)
|
81
|
+
until @buffer.end_of_buffer? || @buffer.point_after_mark?(end_mark)
|
82
|
+
indent_line
|
83
|
+
@buffer.forward_line
|
84
|
+
end
|
82
85
|
end
|
86
|
+
ensure
|
87
|
+
end_mark.delete
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
data/lib/textbringer/plugin.rb
CHANGED
@@ -9,15 +9,8 @@ module Textbringer
|
|
9
9
|
@directory = File.expand_path("~/.textbringer/plugins")
|
10
10
|
|
11
11
|
def self.load_plugins
|
12
|
-
files = Gem.
|
13
|
-
|
14
|
-
}.map { |gem, versions|
|
15
|
-
versions.sort_by { |version|
|
16
|
-
v = version.slice(/[^\/]+-([\w.]+)\/lib\/textbringer_plugin\.rb\z/,
|
17
|
-
1)
|
18
|
-
Gem::Version.create(v)
|
19
|
-
}.last
|
20
|
-
} + Dir.glob(File.join(directory, "*/**/textbringer_plugin.rb"))
|
12
|
+
files = Gem.find_latest_files("textbringer_plugin.rb", false) +
|
13
|
+
Dir.glob(File.join(directory, "*/**/textbringer_plugin.rb"))
|
21
14
|
files.each do |file|
|
22
15
|
load(file)
|
23
16
|
end
|
data/lib/textbringer/version.rb
CHANGED
data/lib/textbringer/window.rb
CHANGED
@@ -2,45 +2,8 @@
|
|
2
2
|
|
3
3
|
require "curses"
|
4
4
|
require "unicode/display_width"
|
5
|
-
require "fiddle/import"
|
6
5
|
|
7
6
|
module Textbringer
|
8
|
-
# These features should be provided by curses.gem.
|
9
|
-
module PDCurses
|
10
|
-
KEY_OFFSET = 0xec00
|
11
|
-
ALT_0 = KEY_OFFSET + 0x97
|
12
|
-
ALT_9 = KEY_OFFSET + 0xa0
|
13
|
-
ALT_A = KEY_OFFSET + 0xa1
|
14
|
-
ALT_Z = KEY_OFFSET + 0xba
|
15
|
-
ALT_NUMBER_BASE = ALT_0 - ?0.ord
|
16
|
-
ALT_ALPHA_BASE = ALT_A - ?a.ord
|
17
|
-
|
18
|
-
KEY_MODIFIER_SHIFT = 1
|
19
|
-
KEY_MODIFIER_CONTROL = 2
|
20
|
-
KEY_MODIFIER_ALT = 4
|
21
|
-
KEY_MODIFIER_NUMLOCK = 8
|
22
|
-
|
23
|
-
@dll_loaded = false
|
24
|
-
|
25
|
-
class << self
|
26
|
-
attr_writer :dll_loaded
|
27
|
-
|
28
|
-
def dll_loaded?
|
29
|
-
@dll_loaded
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
begin
|
34
|
-
extend Fiddle::Importer
|
35
|
-
dlload "pdcurses.dll"
|
36
|
-
extern "unsigned long PDC_get_key_modifiers(void)"
|
37
|
-
extern "int PDC_save_key_modifiers(unsigned char)"
|
38
|
-
extern "int PDC_return_key_modifiers(unsigned char)"
|
39
|
-
@dll_loaded = true
|
40
|
-
rescue Fiddle::DLError
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
7
|
class Window
|
45
8
|
KEY_NAMES = {}
|
46
9
|
Curses.constants.grep(/\AKEY_/).each do |name|
|
@@ -48,6 +11,12 @@ module Textbringer
|
|
48
11
|
name.slice(/\AKEY_(.*)/, 1).downcase.intern
|
49
12
|
end
|
50
13
|
|
14
|
+
HAVE_GET_KEY_MODIFIERS = defined?(Curses.get_key_modifiers)
|
15
|
+
if HAVE_GET_KEY_MODIFIERS
|
16
|
+
ALT_NUMBER_BASE = Curses::ALT_0 - ?0.ord
|
17
|
+
ALT_ALPHA_BASE = Curses::ALT_A - ?a.ord
|
18
|
+
end
|
19
|
+
|
51
20
|
@@started = false
|
52
21
|
@@list = []
|
53
22
|
@@current = nil
|
@@ -325,12 +294,12 @@ module Textbringer
|
|
325
294
|
def read_event
|
326
295
|
key = get_char
|
327
296
|
if key.is_a?(Integer)
|
328
|
-
if
|
329
|
-
if
|
330
|
-
@key_buffer.push((key -
|
297
|
+
if HAVE_GET_KEY_MODIFIERS
|
298
|
+
if Curses::ALT_0 <= key && key <= Curses::ALT_9
|
299
|
+
@key_buffer.push((key - ALT_NUMBER_BASE).chr)
|
331
300
|
return "\e"
|
332
|
-
elsif
|
333
|
-
@key_buffer.push((key -
|
301
|
+
elsif Curses::ALT_A <= key && key <= Curses::ALT_Z
|
302
|
+
@key_buffer.push((key - ALT_ALPHA_BASE).chr)
|
334
303
|
return "\e"
|
335
304
|
end
|
336
305
|
end
|
@@ -384,7 +353,7 @@ module Textbringer
|
|
384
353
|
def highlight
|
385
354
|
@highlight_on = {}
|
386
355
|
@highlight_off = {}
|
387
|
-
return if !@@has_colors || !CONFIG[:syntax_highlight]
|
356
|
+
return if !@@has_colors || !CONFIG[:syntax_highlight] || @buffer.binary?
|
388
357
|
syntax_table = @buffer.mode.syntax_table
|
389
358
|
return if syntax_table.empty?
|
390
359
|
if @buffer.bytesize < CONFIG[:highlight_buffer_size_limit]
|
@@ -780,7 +749,7 @@ module Textbringer
|
|
780
749
|
|
781
750
|
def get_char
|
782
751
|
if @key_buffer.empty?
|
783
|
-
|
752
|
+
Curses.save_key_modifiers(true) if HAVE_GET_KEY_MODIFIERS
|
784
753
|
begin
|
785
754
|
need_retry = false
|
786
755
|
if @raw_key_buffer.empty?
|
@@ -788,13 +757,13 @@ module Textbringer
|
|
788
757
|
else
|
789
758
|
key = @raw_key_buffer.shift
|
790
759
|
end
|
791
|
-
if
|
792
|
-
mods =
|
760
|
+
if HAVE_GET_KEY_MODIFIERS
|
761
|
+
mods = Curses.get_key_modifiers
|
793
762
|
if key.is_a?(String) && key.ascii_only?
|
794
|
-
if (mods &
|
763
|
+
if (mods & Curses::PDC_KEY_MODIFIER_CONTROL) != 0
|
795
764
|
key = key == ?? ? "\x7f" : (key.ord & 0x9f).chr
|
796
765
|
end
|
797
|
-
if (mods &
|
766
|
+
if (mods & Curses::PDC_KEY_MODIFIER_ALT) != 0
|
798
767
|
if key == "\0"
|
799
768
|
# Alt + `, Alt + < etc. return NUL, so ignore it.
|
800
769
|
need_retry = true
|
data/textbringer.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.required_ruby_version = '>= 2.3'
|
23
23
|
|
24
|
-
spec.add_runtime_dependency "curses", "
|
24
|
+
spec.add_runtime_dependency "curses", ">= 1.2.2"
|
25
25
|
spec.add_runtime_dependency "unicode-display_width", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "clipboard", "~> 1.1"
|
27
27
|
spec.add_runtime_dependency "fiddley", ">= 0.0.5"
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: textbringer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.2.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.2.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: unicode-display_width
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -257,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
257
257
|
version: '0'
|
258
258
|
requirements: []
|
259
259
|
rubyforge_project:
|
260
|
-
rubygems_version: 2.6.
|
260
|
+
rubygems_version: 2.6.12
|
261
261
|
signing_key:
|
262
262
|
specification_version: 4
|
263
263
|
summary: An Emacs-like text editor
|