textbringer 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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