textbringer 1.0.1 → 1.1.0

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