textbringer 1.0.1 → 1.1.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ubuntu.yml +5 -9
  3. data/.github/workflows/windows.yml +4 -7
  4. data/CHANGES.md +47 -0
  5. data/README.md +0 -2
  6. data/bin/merge_mazegaki_dic +25 -0
  7. data/exe/textbringer +6 -5
  8. data/lib/textbringer.rb +4 -0
  9. data/lib/textbringer/buffer.rb +40 -3
  10. data/lib/textbringer/commands/clipboard.rb +3 -3
  11. data/lib/textbringer/commands/ctags.rb +3 -3
  12. data/lib/textbringer/commands/dabbrev.rb +1 -1
  13. data/lib/textbringer/commands/files.rb +18 -3
  14. data/lib/textbringer/commands/help.rb +25 -16
  15. data/lib/textbringer/commands/input_method.rb +18 -0
  16. data/lib/textbringer/commands/isearch.rb +23 -2
  17. data/lib/textbringer/commands/misc.rb +8 -3
  18. data/lib/textbringer/commands/windows.rb +8 -4
  19. data/lib/textbringer/config.rb +2 -1
  20. data/lib/textbringer/controller.rb +7 -1
  21. data/lib/textbringer/input_method.rb +63 -0
  22. data/lib/textbringer/input_methods/hiragana_input_method.rb +70 -0
  23. data/lib/textbringer/input_methods/t_code_input_method.rb +458 -0
  24. data/lib/textbringer/input_methods/t_code_input_method/tables.rb +64 -0
  25. data/lib/textbringer/keymap.rb +45 -26
  26. data/lib/textbringer/modes/backtrace_mode.rb +1 -1
  27. data/lib/textbringer/modes/buffer_list_mode.rb +1 -1
  28. data/lib/textbringer/modes/c_mode.rb +4 -0
  29. data/lib/textbringer/modes/completion_list_mode.rb +1 -1
  30. data/lib/textbringer/modes/help_mode.rb +1 -1
  31. data/lib/textbringer/modes/programming_mode.rb +24 -2
  32. data/lib/textbringer/modes/ruby_mode.rb +70 -12
  33. data/lib/textbringer/utils.rb +10 -5
  34. data/lib/textbringer/version.rb +1 -1
  35. data/lib/textbringer/window.rb +25 -10
  36. data/textbringer.gemspec +4 -5
  37. metadata +19 -28
  38. data/.github/workflows/ruby-head.yml +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '009c68bcdc928faff20b7ca1b75f92b21641dc6d29e392a05a279267418983d1'
4
- data.tar.gz: cad85dfebd2dc1b70cdbf9212bcda296bcde8204e529b0d82ce1663434a05d4b
3
+ metadata.gz: '0950d5d14bd72c43ec2270cbb545c0dc464b66662f85099ec5eed8dc3a5a56db'
4
+ data.tar.gz: 1874b1aa43e1ba76fc2d1c9c74f9351a3dc28a15b85c7d6a085cd8d5b669adb3
5
5
  SHA512:
6
- metadata.gz: 4923385439037b9ce5aa099a029f9ca6a3bc87205f85a74febaf165c3e512501303ad25c86cdc73191bf1fcd9cf9faa15b9633996bd1efdc69bb231fba781afe
7
- data.tar.gz: 9a624d55143b47100a6fc9a538d29c9f1151d7c6c38d3fdb4865739fd8d2b7a9c76bda2f8a29a6921ddc9e9e8cd8e5c73f1c25031fc9244e81da3547946559a4
6
+ metadata.gz: 63431a1a5a0425007e119cf3573b86d61d3a1df8cca7c8658ee5fd479201696adfeddb80c2a085fca1df89fa16862d47664a5f85ae31fd09fd4f36ce73058d71
7
+ data.tar.gz: 95876e6af0b0be40b684ac3b0703aaa08370b23647f50b4231d61bd5c8e9411ad0798107cc77f4cb67bcf06fbcbfdaaaf47074322933052783b29a7722d2ffed
@@ -3,15 +3,14 @@ name: ubuntu
3
3
  on: [push]
4
4
 
5
5
  jobs:
6
- build:
7
- runs-on: ubuntu-latest
6
+ test:
8
7
  strategy:
9
8
  matrix:
10
- ruby: [ '2.6.x', '2.5.x', '2.4.x' ]
9
+ ruby: [ head, 3.0, 2.7, 2.6 ]
10
+ runs-on: ubuntu-latest
11
11
  steps:
12
- - uses: actions/checkout@master
13
- - name: Set up Ruby
14
- uses: actions/setup-ruby@v1
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
15
14
  with:
16
15
  ruby-version: ${{ matrix.ruby }}
17
16
  - name: Install dependencies
@@ -21,6 +20,3 @@ jobs:
21
20
  bundle install
22
21
  - name: Run test
23
22
  run: xvfb-run bundle exec rake test
24
- env:
25
- UPLOAD_TO_CODECOV: 1
26
- CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
@@ -7,16 +7,13 @@ jobs:
7
7
  runs-on: windows-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ '2.6.x', '2.5.x', '2.4.x' ]
10
+ ruby: [ 'mingw', 'mswin', '3.0', '2.7', '2.6' ]
11
11
  steps:
12
- - uses: actions/checkout@master
12
+ - uses: actions/checkout@v2
13
13
  - name: Set up Ruby
14
- uses: actions/setup-ruby@v1
14
+ uses: ruby/setup-ruby@v1
15
15
  with:
16
16
  ruby-version: ${{ matrix.ruby }}
17
- - name: Set up Bundler
18
- run: gem install bundler --no-document
19
- - name: Install dependencies
20
- run: bundle install
17
+ bundler-cache: true
21
18
  - name: Run test
22
19
  run: bundle exec rake test
data/CHANGES.md CHANGED
@@ -1,3 +1,50 @@
1
+ ## 1.1.0
2
+
3
+ * Show unsaved buffers on exit
4
+ * Bug fixes.
5
+
6
+ ## 1.0.9
7
+
8
+ * Remove mazegaki.dic and bushu.rev
9
+
10
+ ## 1.0.8
11
+
12
+ * Updated mazegaki.dic
13
+ * Add licenses of dictionary data to LEGAL.txt
14
+
15
+ ## 1.0.7
16
+
17
+ * Support endless method definitions in ruby-mode.
18
+ * Updated mazegaki.dic.
19
+
20
+ ## 1.0.6
21
+
22
+ * Add the Hiragana input method.
23
+ * Add make_directory.
24
+ * Bug fixes.
25
+
26
+ ## 1.0.5
27
+
28
+ * Support the Japanese input method T-Code.
29
+
30
+ ## 1.0.4
31
+
32
+ * Support Ruby 3.0.
33
+ * Do not record backtrace of Quit (C-g).
34
+
35
+ ## 1.0.3
36
+
37
+ * Fix indentation bugs.
38
+ * Fix a bug of fourground! when it is called in the main thread.
39
+
40
+ ## 1.0.2
41
+
42
+ * Add isearch_quoted_insert.
43
+ * Use M- notation instead of ESC in define_key and help.
44
+ * Add indent_new_comment_line_command.
45
+ * Add find_alternate_file.
46
+ * Fix indentation bugs in the Ruby mode.
47
+
1
48
  ## 1.0.1
2
49
 
3
50
  * Support pattern matching in the Ruby mode.
data/README.md CHANGED
@@ -4,8 +4,6 @@
4
4
  [![ubuntu](https://github.com/shugo/textbringer/workflows/ubuntu/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Aubuntu)
5
5
  [![windows](https://github.com/shugo/textbringer/workflows/windows/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Awindows)
6
6
  [![macos](https://github.com/shugo/textbringer/workflows/macos/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Amacos)
7
- [![ruby-head](https://github.com/shugo/textbringer/workflows/ruby-head/badge.svg)](https://github.com/shugo/textbringer/actions?query=workflow%3Aruby-head)
8
- [![codecov](https://codecov.io/gh/shugo/textbringer/branch/master/graph/badge.svg)](https://codecov.io/gh/shugo/textbringer)
9
7
 
10
8
  Textbringer is a member of a demon race that takes on the form of an Emacs-like
11
9
  text editor.
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Usage: merge_mazegaki_dic /path/to/mazegaki.dic /path/to/skkdic/SKK-JISYO.* > ~/.textbringer/tcode/mazegaki.dic
4
+
5
+ MAZEGAKI_DIC = Hash.new([])
6
+
7
+ ARGF.each_line do |line|
8
+ next if /^\p{ascii}/.match?(line)
9
+ x, y = line.split
10
+ key = x.sub(/\A(\p{hiragana}+)[a-z>]\z/, "\\1—")
11
+ values = y.split("/").map { |i|
12
+ i.sub(/;.*/, "")
13
+ }.reject { |i|
14
+ i.empty? || i == key
15
+ }
16
+ MAZEGAKI_DIC[key] |= values
17
+ end
18
+
19
+ MAZEGAKI_DIC.sort_by { |key,|
20
+ key
21
+ }.each do |key, values|
22
+ puts "#{key} /#{values.join('/')}/"
23
+ end
24
+
25
+
data/exe/textbringer CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ $VERBOSE = nil
4
+
3
5
  require "textbringer"
4
6
 
5
7
  include Textbringer
6
8
  include Commands
7
9
 
8
- def load_user_config
9
- config_file = File.expand_path("~/.textbringer.rb")
10
+ def load_user_config(path)
11
+ config_file = File.expand_path(path)
10
12
  begin
11
13
  load(config_file)
12
14
  rescue LoadError
13
15
  end
14
16
  end
15
17
 
16
- $VERBOSE = nil
17
-
18
18
  unless STDIN.tty?
19
19
  STDERR.puts("textbringer: standard input is not a tty")
20
20
  exit 1
@@ -24,8 +24,9 @@ Controller.current = Controller.new
24
24
  begin
25
25
  Window.start do
26
26
  begin
27
+ load_user_config("~/.textbringer/init.rb")
27
28
  Plugin.load_plugins
28
- load_user_config
29
+ load_user_config("~/.textbringer.rb")
29
30
  ruby_mode
30
31
  if ARGV.size > 0
31
32
  ARGV.each do |arg|
data/lib/textbringer.rb CHANGED
@@ -22,6 +22,7 @@
22
22
  require_relative "textbringer/commands/keyboard_macro"
23
23
  require_relative "textbringer/commands/fill"
24
24
  require_relative "textbringer/commands/server"
25
+ require_relative "textbringer/commands/input_method"
25
26
  require_relative "textbringer/commands/help"
26
27
  require_relative "textbringer/mode"
27
28
  require_relative "textbringer/modes/fundamental_mode"
@@ -32,5 +33,8 @@
32
33
  require_relative "textbringer/modes/completion_list_mode"
33
34
  require_relative "textbringer/modes/buffer_list_mode"
34
35
  require_relative "textbringer/modes/help_mode"
36
+ require_relative "textbringer/input_method"
37
+ require_relative "textbringer/input_methods/t_code_input_method"
38
+ require_relative "textbringer/input_methods/hiragana_input_method"
35
39
  require_relative "textbringer/plugin"
36
40
  require_relative "textbringer/controller"
@@ -11,6 +11,7 @@ class Buffer
11
11
  attr_accessor :mode, :keymap
12
12
  attr_reader :name, :file_name, :file_encoding, :file_format, :point, :marks
13
13
  attr_reader :current_line, :current_column, :visible_mark
14
+ attr_reader :input_method
14
15
 
15
16
  GAP_SIZE = 256
16
17
  UNDO_LIMIT = 1000
@@ -240,6 +241,7 @@ def initialize(s = +"", name: nil,
240
241
  @visible_mark = nil
241
242
  @read_only = read_only
242
243
  @callbacks = {}
244
+ @input_method = nil
243
245
  end
244
246
 
245
247
  def inspect
@@ -410,6 +412,7 @@ def save(file_name = @file_name)
410
412
  f.flock(File::LOCK_EX)
411
413
  write_to_file(f)
412
414
  f.flush
415
+ f.fsync
413
416
  end
414
417
  @file_mtime = File.mtime(file_name)
415
418
  rescue Errno::EISDIR
@@ -1384,6 +1387,35 @@ def insert_final_newline
1384
1387
  end
1385
1388
  end
1386
1389
 
1390
+ def toggle_input_method(name)
1391
+ if name.nil?
1392
+ @input_method ||= InputMethod.find(CONFIG[:default_input_method])
1393
+ else
1394
+ @input_method = InputMethod.find(name)
1395
+ end
1396
+ @input_method.toggle
1397
+ end
1398
+
1399
+ def disable_input_method
1400
+ @input_method&.disable
1401
+ end
1402
+
1403
+ def filter_event(event)
1404
+ if @input_method
1405
+ @input_method.filter_event(event)
1406
+ else
1407
+ event
1408
+ end
1409
+ end
1410
+
1411
+ def input_method_status
1412
+ if @input_method&.enabled?
1413
+ @input_method.status
1414
+ else
1415
+ "--"
1416
+ end
1417
+ end
1418
+
1387
1419
  private
1388
1420
 
1389
1421
  def set_contents(s, enc)
@@ -1555,15 +1587,15 @@ def write_to_file(f)
1555
1587
 
1556
1588
  def push_undo(action)
1557
1589
  return if @undoing || @undo_limit == 0
1590
+ if !modified?
1591
+ action.version = @version
1592
+ end
1558
1593
  if @composite_edit_level > 0
1559
1594
  @composite_edit_actions.push(action)
1560
1595
  else
1561
1596
  if @undo_stack.size >= @undo_limit
1562
1597
  @undo_stack[0, @undo_stack.size + 1 - @undo_limit] = []
1563
1598
  end
1564
- if !modified?
1565
- action.version = @version
1566
- end
1567
1599
  @undo_stack.push(action)
1568
1600
  @redo_stack.clear
1569
1601
  end
@@ -1649,6 +1681,7 @@ class InsertAction < UndoableAction
1649
1681
  def initialize(buffer, location, string)
1650
1682
  super(buffer, location)
1651
1683
  @string = string
1684
+ @copied = false
1652
1685
  end
1653
1686
 
1654
1687
  def undo
@@ -1662,6 +1695,10 @@ def redo
1662
1695
  end
1663
1696
 
1664
1697
  def merge(s)
1698
+ unless @copied
1699
+ @string = @string.dup
1700
+ @copied = true
1701
+ end
1665
1702
  @string.concat(s)
1666
1703
  end
1667
1704
  end
@@ -11,12 +11,12 @@ module Commands
11
11
  (ENV["DISPLAY"] && system("which xclip > /dev/null 2>&1"))
12
12
 
13
13
  if CLIPBOARD_AVAILABLE
14
- GLOBAL_MAP.define_key("\ew", :clipboard_copy_region)
14
+ GLOBAL_MAP.define_key("\M-w", :clipboard_copy_region)
15
15
  GLOBAL_MAP.define_key("\C-w", :clipboard_kill_region)
16
16
  GLOBAL_MAP.define_key(?\C-k, :clipboard_kill_line)
17
- GLOBAL_MAP.define_key("\ed", :clipboard_kill_word)
17
+ GLOBAL_MAP.define_key("\M-d", :clipboard_kill_word)
18
18
  GLOBAL_MAP.define_key("\C-y", :clipboard_yank)
19
- GLOBAL_MAP.define_key("\ey", :clipboard_yank_pop)
19
+ GLOBAL_MAP.define_key("\M-y", :clipboard_yank_pop)
20
20
  end
21
21
 
22
22
  define_command(:clipboard_copy_region, doc: <<~EOD) do
@@ -49,12 +49,12 @@ module Commands
49
49
  when /\A\d+\z/
50
50
  push_tag_mark_and_find_file(file)
51
51
  goto_line(addr.to_i)
52
- when %r'\A/\^(.*)\$/\z'
52
+ when %r'\A/\^(.*?)(\$)?/\z'
53
+ re = "^" + Regexp.quote($1.gsub(/\\([\\\/])/, "\\1")) + $2.to_s
53
54
  push_tag_mark_and_find_file(file)
54
55
  beginning_of_buffer
55
56
  n.times do
56
- s = Regexp.quote($1.gsub(/\\([\\\/])/, "\\1"))
57
- re_search_forward("^" + s + "$")
57
+ re_search_forward(re)
58
58
  end
59
59
  beginning_of_line
60
60
  when %r'\A\?\^(.*)\$\?\z'
@@ -91,7 +91,7 @@ def dabbrev_regexp(stem, candidates)
91
91
  using DabbrevExtension
92
92
 
93
93
  module Commands
94
- GLOBAL_MAP.define_key("\e/", :dabbrev_expand_command)
94
+ GLOBAL_MAP.define_key("\M-/", :dabbrev_expand_command)
95
95
 
96
96
  define_command(:dabbrev_expand_command) do
97
97
  contd = Controller.current.last_command == :dabbrev_expand_command
@@ -1,9 +1,10 @@
1
1
  require "editorconfig"
2
+ require "fileutils"
2
3
 
3
4
  module Textbringer
4
5
  module Commands
5
6
  define_command(:find_file, doc: "Open or create a file.") do
6
- |file_name = read_file_name("Find file: ")|
7
+ |file_name = read_file_name("Find file: ", default: (Buffer.current.file_name ? File.dirname(Buffer.current.file_name) : Dir.pwd) + "/")|
7
8
  config = EditorConfig.load_file(file_name)
8
9
  buffer = Buffer.find_file(file_name)
9
10
  if buffer.new_file?
@@ -86,12 +87,13 @@ module Commands
86
87
 
87
88
  define_command(:write_file,
88
89
  doc: "Save the current buffer as the specified file.") do
89
- |file_name = read_file_name("Write file: ")|
90
+ |file_name = read_file_name("Write file: ",
91
+ default: Buffer.current.file_name)|
90
92
  if File.directory?(file_name)
91
93
  file_name = File.expand_path(Buffer.current.name, file_name)
92
94
  end
93
95
  if File.exist?(file_name)
94
- unless y_or_n?("File `#{file_name}' exists; overwrite?")
96
+ unless y_or_n?("File exists; overwrite?")
95
97
  message("Cancelled")
96
98
  next
97
99
  end
@@ -124,5 +126,18 @@ module Commands
124
126
  File.dirname(Buffer.current.file_name))|
125
127
  Dir.chdir(dir_name)
126
128
  end
129
+
130
+ define_command(:find_alternate_file, doc: "Find an alternate file.") do
131
+ |file_name = read_file_name("Find alternate file: ",
132
+ default: Buffer.current.file_name)|
133
+ find_file(file_name)
134
+ end
135
+
136
+ define_command(:make_directory, doc: "Create a new directory.") do
137
+ |dir_name = read_file_name("Make directory: ",
138
+ default: Buffer.current.file_name &&
139
+ File.dirname(Buffer.current.file_name))|
140
+ FileUtils.mkdir_p(dir_name)
141
+ end
127
142
  end
128
143
  end
@@ -21,27 +21,36 @@ def show_help
21
21
  end
22
22
  private :show_help
23
23
 
24
+ def keymap_bindings(keymap)
25
+ s = format("%-16s %s\n", "Key", "Binding")
26
+ s << format("%-16s %s\n", "---", "-------")
27
+ s << "\n"
28
+ keymap.each do |key_sequence, command|
29
+ if command != :self_insert
30
+ s << format("%-16s [%s]\n",
31
+ Keymap.key_sequence_string(key_sequence),
32
+ command)
33
+ end
34
+ end
35
+ s
36
+ end
37
+
24
38
  define_command(:describe_bindings,
25
39
  doc: "Display the key bindings.") do
26
40
  show_help do |help|
27
- s = format("%-16s %s\n", "Key", "Binding")
28
- s << format("%-16s %s\n", "---", "-------")
29
- s << "\n"
30
- bindings = {}
31
- [
32
- GLOBAL_MAP,
33
- Buffer.current.keymap,
34
- Controller.current.overriding_map
35
- ].each do |map|
36
- map&.each do |key_sequence, command|
37
- bindings[key_sequence] = command
38
- end
41
+ s = ""
42
+ if Controller.current.overriding_map
43
+ s << "Overriding Bindings:\n"
44
+ s << keymap_bindings(Controller.current.overriding_map)
45
+ s << "\n"
39
46
  end
40
- bindings.each do |key_sequence, command|
41
- s << format("%-16s [%s]\n",
42
- Keymap.key_sequence_string(key_sequence),
43
- command)
47
+ if Buffer.current.keymap
48
+ s << "Current Buffer Bindings:\n"
49
+ s << keymap_bindings(Buffer.current.keymap)
50
+ s << "\n"
44
51
  end
52
+ s << "Global Bindings:\n"
53
+ s << keymap_bindings(GLOBAL_MAP)
45
54
  help.insert(s)
46
55
  end
47
56
  push_help_command([:describe_bindings])
@@ -0,0 +1,18 @@
1
+ module Textbringer
2
+ module Commands
3
+ define_command(:toggle_input_method,
4
+ doc: "Toggel input method.") do |name = nil|
5
+ if name.nil? && current_prefix_arg
6
+ name = read_input_method_name("Input method: ")
7
+ end
8
+ Buffer.current.toggle_input_method(name)
9
+ end
10
+
11
+ def read_input_method_name(prompt, default: CONFIG[:default_input_method])
12
+ f = ->(s) {
13
+ complete_for_minibuffer(s.tr("-", "_"), InputMethod.list)
14
+ }
15
+ read_from_minibuffer(prompt, completion_proc: f, default: default)
16
+ end
17
+ end
18
+ end