textbringer 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f61a01528e59c0b8185339a9120fd528602e4df0c8db6b859a3756043309ac2
4
- data.tar.gz: cd1eef029b832c4fcdd9b7bdf709c29c3e60676d79f7084028ac2c683ca7ef82
3
+ metadata.gz: 501a7f57f239b45890a30564482e20d2f80d20b5b21719268f97d0f787600c77
4
+ data.tar.gz: 56ec3be0a84a84663542072d76d0bfd868e42144cab77d51439d3ba317fe6302
5
5
  SHA512:
6
- metadata.gz: 501f358854f97ca17dafdbd3d908d1a29a2ea32f103a596958b48e1f11c7397178334e75dfa369ac779e7df77d92958632790c77d2ffd520e6959a6a071e32a6
7
- data.tar.gz: d1c443c92cd12df433bdee6df2af8d211ebca023946c268386f813c3292bcc195f4f9cd2b6e17e010ff1d168e31d8ba3da92c75c181644585fe3fdb15d21b532
6
+ metadata.gz: fc8752782f2b63601fc382a88689b79d874d3deef1a829ef2efaa969ccfc43175b7d6f8ca2757dd345a88bb997cbc0e3b0aafaf4bcabafad478234e6e4ecd3af
7
+ data.tar.gz: 3d7ec2385be73f6d739e5fd0b547c28dc24001e58827d2d4ae15753d03d8d71e257a8f0efd50a9630ea169d3d2c58ade94104be772d9e0d91dfce08ea0b5f957
data/.editorconfig CHANGED
@@ -2,8 +2,11 @@ root = true
2
2
 
3
3
  [*]
4
4
  end_of_line = lf
5
+ insert_final_newline = true
5
6
 
6
7
  [*.rb]
7
8
  indent_style = space
8
9
  indent_size = 2
9
10
 
11
+ [lib/**.rb]
12
+ trim_trailing_whitespace = true
data/.travis.yml CHANGED
@@ -4,28 +4,28 @@ matrix:
4
4
  - os: linux
5
5
  dist: trusty
6
6
  sudo: false
7
- rvm: 2.3.5
7
+ rvm: 2.4.5
8
8
  - os: linux
9
9
  dist: trusty
10
10
  sudo: false
11
- rvm: 2.4.3
11
+ rvm: 2.5.2
12
12
  - os: linux
13
13
  dist: trusty
14
14
  sudo: false
15
- rvm: 2.5.0
15
+ rvm: 2.6.0
16
16
  - os: linux
17
17
  dist: trusty
18
18
  sudo: false
19
19
  rvm: ruby-head
20
20
  - os: osx
21
21
  osx_image: xcode8.2
22
- rvm: 2.3.5
22
+ rvm: 2.4.5
23
23
  - os: osx
24
24
  osx_image: xcode8.2
25
- rvm: 2.4.3
25
+ rvm: 2.5.2
26
26
  - os: osx
27
27
  osx_image: xcode8.2
28
- rvm: 2.5.0
28
+ rvm: 2.6.0
29
29
  - os: osx
30
30
  osx_image: xcode8.2
31
31
  rvm: ruby-head
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.3.1
2
+
3
+ * Depend on curses 1.2.6 or later for mingw.
4
+
1
5
  ## 0.3.0
2
6
 
3
7
  * toggle_test_command supports RSpec now.
data/exe/tbclient ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "drb"
4
+ require "optparse"
5
+
6
+ eval = false
7
+ wait = true
8
+ uri = "drbunix:" + File.expand_path("server.sock", "~/.textbringer")
9
+
10
+ opt = OptionParser.new
11
+ opt.banner = "Usage: tbclient [OPTIONS] FILE"
12
+ opt.on("--uri URI", "Specify the URI of the server") do |val|
13
+ uri = val
14
+ end
15
+ opt.on("-e", "--eval", "Evaluate FILE as a Ruby expression") do
16
+ eval = true
17
+ end
18
+ opt.on("-n", "--no-wait", "Don't wait for the server") do
19
+ wait = false
20
+ end
21
+ args = ARGV.dup
22
+ opt.parse!(args)
23
+ if args.empty?
24
+ STDERR.puts(opt.help)
25
+ exit 1
26
+ end
27
+ arg = args.first
28
+ tb = DRbObject.new_with_uri(uri)
29
+ if eval
30
+ puts tb.eval(arg)
31
+ else
32
+ tb.visit_file(File.expand_path(arg), wait: wait)
33
+ end
34
+
data/lib/textbringer.rb CHANGED
@@ -23,6 +23,7 @@ require_relative "textbringer/commands/clipboard"
23
23
  require_relative "textbringer/commands/register"
24
24
  require_relative "textbringer/commands/keyboard_macro"
25
25
  require_relative "textbringer/commands/fill"
26
+ require_relative "textbringer/commands/server"
26
27
  require_relative "textbringer/commands/help"
27
28
  require_relative "textbringer/mode"
28
29
  require_relative "textbringer/modes/fundamental_mode"
@@ -4,6 +4,7 @@ require "nkf"
4
4
  require "unicode/display_width"
5
5
  require "json"
6
6
  require "fileutils"
7
+ require "editorconfig"
7
8
 
8
9
  module Textbringer
9
10
  class Buffer
@@ -398,6 +399,13 @@ module Textbringer
398
399
  raise EditorError, "File name is not set"
399
400
  end
400
401
  file_name = File.expand_path(file_name)
402
+ config = EditorConfig.load_file(file_name)
403
+ if config["trim_trailing_whitespace"]
404
+ trim_trailing_whitespace
405
+ end
406
+ if config["insert_final_newline"]
407
+ insert_final_newline
408
+ end
401
409
  begin
402
410
  File.open(file_name, "w",
403
411
  external_encoding: @file_encoding, binmode: true) do |f|
@@ -666,7 +674,7 @@ module Textbringer
666
674
  end
667
675
  end
668
676
  end
669
-
677
+
670
678
  def forward_line(n = 1)
671
679
  if n > 0
672
680
  n.times do
@@ -683,7 +691,7 @@ module Textbringer
683
691
  end
684
692
  end
685
693
  end
686
-
694
+
687
695
  def backward_line(n = 1)
688
696
  forward_line(-n)
689
697
  end
@@ -941,7 +949,7 @@ module Textbringer
941
949
  m.location = s
942
950
  end
943
951
  end
944
- push_undo(DeleteAction.new(self, old_pos, s, str))
952
+ push_undo(DeleteAction.new(self, old_pos, s, str))
945
953
  self.modified = true
946
954
  end
947
955
  end
@@ -1328,7 +1336,15 @@ module Textbringer
1328
1336
  end
1329
1337
 
1330
1338
  def gsub(*args, &block)
1331
- s = to_s.gsub(*args, &block)
1339
+ if block
1340
+ s = to_s.gsub(*args) { |*params|
1341
+ set_block_backref(block, $~)
1342
+ block.call(*params)
1343
+ }
1344
+ else
1345
+ s = to_s.gsub(*args)
1346
+ end
1347
+
1332
1348
  composite_edit do
1333
1349
  delete_region(point_min, point_max)
1334
1350
  insert(s)
@@ -1336,6 +1352,26 @@ module Textbringer
1336
1352
  self
1337
1353
  end
1338
1354
 
1355
+ def trim_trailing_whitespace
1356
+ save_excursion do
1357
+ beginning_of_buffer
1358
+ composite_edit do
1359
+ while re_search_forward(/[ \t]+$/, raise_error: false)
1360
+ replace_match("")
1361
+ end
1362
+ end
1363
+ end
1364
+ end
1365
+
1366
+ def insert_final_newline
1367
+ save_excursion do
1368
+ end_of_buffer
1369
+ if char_before != "\n"
1370
+ insert("\n")
1371
+ end
1372
+ end
1373
+ end
1374
+
1339
1375
  private
1340
1376
 
1341
1377
  def set_contents(s, enc)
@@ -1348,7 +1384,7 @@ module Textbringer
1348
1384
  @contents.force_encoding(Encoding::ASCII_8BIT)
1349
1385
  self.file_encoding = enc
1350
1386
  case @contents
1351
- when /(?<!\r)\n/
1387
+ when /(?<!\r)\n/
1352
1388
  @file_format = :unix
1353
1389
  when /\r(?!\n)/
1354
1390
  @file_format = :mac
@@ -1391,7 +1427,7 @@ module Textbringer
1391
1427
  if pos <= @gap_start
1392
1428
  pos
1393
1429
  else
1394
- gap_size + pos
1430
+ gap_size + pos
1395
1431
  end
1396
1432
  end
1397
1433
 
@@ -1540,6 +1576,17 @@ module Textbringer
1540
1576
  callback.call(self)
1541
1577
  end
1542
1578
  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
1543
1590
  end
1544
1591
 
1545
1592
  class Mark
@@ -7,7 +7,7 @@ module Textbringer
7
7
  |n = number_prefix_arg|
8
8
  Buffer.current.forward_char(n)
9
9
  end
10
-
10
+
11
11
  define_command(:backward_char,
12
12
  doc: "Move point n characters backward.") do
13
13
  |n = number_prefix_arg|
@@ -25,26 +25,25 @@ module Textbringer
25
25
  |n = number_prefix_arg|
26
26
  Buffer.current.backward_word(n)
27
27
  end
28
-
29
28
 
30
29
  define_command(:next_line,
31
30
  doc: "Move point n lines forward.") do
32
31
  |n = number_prefix_arg|
33
32
  Buffer.current.next_line(n)
34
33
  end
35
-
34
+
36
35
  define_command(:previous_line,
37
36
  doc: "Move point n lines backward.") do
38
37
  |n = number_prefix_arg|
39
38
  Buffer.current.previous_line(n)
40
39
  end
41
-
40
+
42
41
  define_command(:delete_char,
43
42
  doc: "Delete n characters forward.") do
44
43
  |n = number_prefix_arg|
45
44
  Buffer.current.delete_char(n)
46
45
  end
47
-
46
+
48
47
  define_command(:backward_delete_char,
49
48
  doc: "Delete n characters backward.") do
50
49
  |n = number_prefix_arg|
@@ -122,7 +122,7 @@ module Textbringer
122
122
 
123
123
  define_command(:chdir, doc: "Change the current working directory.") do
124
124
  |dir_name = read_file_name("Change directory: ",
125
- default: Buffer.current.file_name &&
125
+ default: Buffer.current.file_name &&
126
126
  File.dirname(Buffer.current.file_name))|
127
127
  Dir.chdir(dir_name)
128
128
  end
@@ -20,7 +20,7 @@ module Textbringer
20
20
  while !beginning_of_buffer? &&
21
21
  !looking_at?(/^[ \t]*$/)
22
22
  backward_line
23
- end
23
+ end
24
24
  while looking_at?(/^[ \t]*$/)
25
25
  forward_line
26
26
  end
@@ -8,7 +8,7 @@ module Textbringer
8
8
  end
9
9
  ISEARCH_MODE_MAP.define_key(?\t, :isearch_printing_char)
10
10
  ISEARCH_MODE_MAP.handle_undefined_key do |key|
11
- if key.is_a?(String) && /[\0-\x7f]/ !~ key
11
+ if key.is_a?(String) && /[\0-\x7f]/ !~ key
12
12
  :isearch_printing_char
13
13
  else
14
14
  nil
@@ -21,7 +21,7 @@ module Textbringer
21
21
  ISEARCH_MODE_MAP.define_key(?\C-w, :isearch_yank_word_or_char)
22
22
  ISEARCH_MODE_MAP.define_key(?\C-m, :isearch_exit)
23
23
  ISEARCH_MODE_MAP.define_key(?\C-g, :isearch_abort)
24
-
24
+
25
25
  ISEARCH_STATUS = {
26
26
  forward: true,
27
27
  string: "",
@@ -4,7 +4,7 @@ module Textbringer
4
4
  module Commands
5
5
  class BufferPosition
6
6
  attr_reader :buffer, :mark
7
-
7
+
8
8
  def initialize(buffer, mark)
9
9
  @buffer = buffer
10
10
  @mark = mark
@@ -118,7 +118,7 @@ module Textbringer
118
118
  when Integer
119
119
  REGISTERS[register] = i + prefix_numeric_value(n)
120
120
  when String
121
- append_to_register(register,
121
+ append_to_register(register,
122
122
  Buffer.current.mark, Buffer.current.point, n)
123
123
  else
124
124
  raise ArgumentError, "Register doesn't contain a number or text"
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "drb"
4
+
5
+ module Textbringer
6
+ module Commands
7
+ define_command(:server_start,
8
+ doc: "Start Textbringer server.") do
9
+ uri = CONFIG[:server_uri] ||
10
+ "drbunix:" + File.expand_path("server.sock", "~/.textbringer")
11
+ options = CONFIG[:server_options] || { UNIXFileMode: 0600 }
12
+ DRb.start_service(uri, Server.new, options)
13
+ end
14
+
15
+ define_command(:server_kill,
16
+ doc: "Kill Textbringer server.") do
17
+ DRb.stop_service
18
+ end
19
+
20
+ define_command(:server_edit_done,
21
+ doc: "Finish server edit.") do
22
+ queue = Buffer.current[:client_wait_queue]
23
+ if queue.nil?
24
+ raise EditorError, "No waiting clients"
25
+ end
26
+ if Buffer.current.modified? &&
27
+ y_or_n?("Save file #{Buffer.current.file_name}?")
28
+ save_buffer
29
+ end
30
+ kill_buffer(Buffer.current, force: true)
31
+ queue.push(:done)
32
+ end
33
+ end
34
+
35
+ class Server
36
+ def eval(s)
37
+ redisplay do
38
+ Controller.current.instance_eval(s).inspect
39
+ end
40
+ end
41
+
42
+ def visit_file(filename, wait: true)
43
+ queue = Queue.new if wait
44
+ redisplay do
45
+ find_file(filename)
46
+ Buffer.current[:client_wait_queue] = queue if wait
47
+ end
48
+ queue.deq if wait
49
+ end
50
+
51
+ private
52
+
53
+ def redisplay
54
+ foreground! do
55
+ begin
56
+ yield
57
+ ensure
58
+ Window.redisplay
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -191,8 +191,9 @@ module Textbringer
191
191
  GLOBAL_MAP.define_key([:f1, "b"], :describe_bindings)
192
192
  GLOBAL_MAP.define_key([:f1, "f"], :describe_command)
193
193
  GLOBAL_MAP.define_key([:f1, "k"], :describe_key)
194
+ GLOBAL_MAP.define_key("\C-x#", :server_edit_done)
194
195
  GLOBAL_MAP.handle_undefined_key do |key|
195
- if key.is_a?(String) && /[\0-\x7f]/ !~ key
196
+ if key.is_a?(String) && /[\0-\x7f]/ !~ key
196
197
  :self_insert
197
198
  else
198
199
  nil
@@ -4,13 +4,13 @@ module Textbringer
4
4
  class Mode
5
5
  extend Commands
6
6
  include Commands
7
-
7
+
8
8
  @@mode_list = []
9
9
 
10
10
  DEFAULT_SYNTAX_TABLE = {
11
11
  control: /[\0-\t\v-\x1f\x7f\u{3000}]+/
12
12
  }
13
-
13
+
14
14
  def self.list
15
15
  @@mode_list
16
16
  end
@@ -35,7 +35,7 @@ module Textbringer
35
35
  (?: " (?: [^\\"] | \\ (?:.|\n) )* " ) |
36
36
  (?: ' (?: [^\\'] | \\ (?:.|\n) )* ' )
37
37
  /x
38
-
38
+
39
39
  def initialize(buffer)
40
40
  super(buffer)
41
41
  @buffer[:indent_level] = CONFIG[:c_indent_level]
@@ -68,7 +68,7 @@ module Textbringer
68
68
  :partial_comment,
69
69
  :unknown
70
70
  ]
71
-
71
+
72
72
  TOKEN_REGEXP = /\G(?:
73
73
  (?<preprocessing_directive>
74
74
  ^[ \t\f\v]*(?:\#|%:).*(?:\\\n.*)*[^\\]\n
@@ -259,7 +259,7 @@ module Textbringer
259
259
  indentation
260
260
  end
261
261
  end
262
-
262
+
263
263
  BLOCK_END = {
264
264
  "{" => "}",
265
265
  "(" => ")",
@@ -334,7 +334,7 @@ module Textbringer
334
334
  end
335
335
  nil
336
336
  end
337
-
337
+
338
338
  class PartialLiteralAnalyzer < Ripper
339
339
  def self.in_literal?(src)
340
340
  new(src).in_literal?
@@ -54,20 +54,22 @@ module Textbringer
54
54
  begin
55
55
  yield
56
56
  rescue Exception => e
57
- next_tick do
57
+ foreground do
58
58
  raise e
59
59
  end
60
60
  end
61
61
  end
62
62
  end
63
63
 
64
- def next_tick(&block)
64
+ def foreground(&block)
65
65
  Controller.current.next_tick(&block)
66
66
  end
67
67
 
68
- def next_tick!
68
+ alias next_tick foreground
69
+
70
+ def foreground!
69
71
  q = Queue.new
70
- next_tick do
72
+ foreground do
71
73
  begin
72
74
  result = yield
73
75
  q.push([:ok, result])
@@ -77,12 +79,14 @@ module Textbringer
77
79
  end
78
80
  status, value = q.pop
79
81
  if status == :error
80
- raise value
82
+ raise value
81
83
  else
82
84
  value
83
85
  end
84
86
  end
85
87
 
88
+ alias next_tick! foreground!
89
+
86
90
  def read_event
87
91
  Controller.current.read_event
88
92
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Textbringer
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -479,7 +479,7 @@ module Textbringer
479
479
  @window.noutrefresh
480
480
  end
481
481
  end
482
-
482
+
483
483
  def redraw
484
484
  @window.redraw
485
485
  @mode_line.redraw
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", ">= 1.2.2"
24
+ spec.add_runtime_dependency "curses", ">= 1.2.6"
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,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textbringer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-31 00:00:00.000000000 Z
11
+ date: 2019-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.2.2
19
+ version: 1.2.6
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: 1.2.2
26
+ version: 1.2.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: unicode-display_width
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +183,7 @@ description: Textbringer is a member of a demon race that takes on the form of a
183
183
  email:
184
184
  - shugo@ruby-lang.org
185
185
  executables:
186
+ - tbclient
186
187
  - tbtags
187
188
  - textbringer
188
189
  extensions: []
@@ -198,6 +199,7 @@ files:
198
199
  - Rakefile
199
200
  - appveyor.yml
200
201
  - bin/console
202
+ - exe/tbclient
201
203
  - exe/tbtags
202
204
  - exe/textbringer
203
205
  - lib/textbringer.rb
@@ -216,6 +218,7 @@ files:
216
218
  - lib/textbringer/commands/misc.rb
217
219
  - lib/textbringer/commands/register.rb
218
220
  - lib/textbringer/commands/replace.rb
221
+ - lib/textbringer/commands/server.rb
219
222
  - lib/textbringer/commands/windows.rb
220
223
  - lib/textbringer/config.rb
221
224
  - lib/textbringer/controller.rb