vimamsa 0.1.20 → 0.1.22

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.
@@ -19,12 +19,12 @@ def jump_to_next_edit
19
19
  end
20
20
 
21
21
  def is_command_mode()
22
- return true if $kbd.mode_root_state.to_s() == "C"
22
+ return true if vma.kbd.mode_root_state.to_s() == "C"
23
23
  return false
24
24
  end
25
25
 
26
26
  def is_visual_mode()
27
- return 1 if $kbd.mode_root_state.to_s() == "V"
27
+ return 1 if vma.kbd.mode_root_state.to_s() == "V"
28
28
  return 0
29
29
  end
30
30
 
@@ -33,6 +33,8 @@ reg_act(:command_to_buf, proc { command_to_buf }, "Execute command, output to bu
33
33
  reg_act(:lsp_debug, proc { vma.buf.lsp_get_def }, "LSP get definition")
34
34
  reg_act(:lsp_jump_to_definition, proc { vma.buf.lsp_jump_to_def }, "LSP jump to definition")
35
35
 
36
+ reg_act(:eval_buf, proc { vma.buf.eval_whole_buf }, "Eval whole current buffer as ruby code (DANGEROUS)")
37
+
36
38
  reg_act(:enable_debug, proc { cnf.debug = true }, "Enable debug")
37
39
  reg_act(:disable_debug, proc { cnf.debug = false }, "Disable debug")
38
40
 
@@ -67,7 +69,6 @@ reg_act(:set_executable, proc { buf.set_executable }, "Set current file permissi
67
69
  reg_act(:close_current_buffer, proc { bufs.close_current_buffer(true) }, "Close current buffer")
68
70
  reg_act(:comment_selection, proc { buf.comment_selection }, "")
69
71
  reg_act(:delete_char_forward, proc { buf.delete(CURRENT_CHAR_FORWARD) }, "Delete char forward", { :group => [:edit, :basic] })
70
- reg_act(:load_theme, proc { load_theme }, "Load theme")
71
72
  reg_act(:gui_file_finder, proc { vma.FileFinder.start_gui }, "Fuzzy file finder")
72
73
  reg_act(:gui_file_history_finder, proc { vma.FileHistory.start_gui }, "Fuzzy file history finder")
73
74
  reg_act(:gui_search_replace, proc { gui_search_replace }, "Search and replace")
@@ -83,7 +84,7 @@ reg_act(:set_line_style_h4, proc { buf.set_line_style(:h4) }, "Set cur line as H
83
84
  reg_act(:set_line_style_bold, proc { buf.set_line_style(:bold) }, "Set style of current line as bold")
84
85
  reg_act(:set_line_style_title, proc { buf.set_line_style(:title) }, "Set style of current line as title")
85
86
  reg_act(:clear_line_styles, proc { buf.set_line_style(:clear) }, "Clear styles of current line")
86
- reg_act(:gui_select_buffer, proc { $kbd.set_mode("S"); gui_select_buffer }, "Select buffer")
87
+ reg_act(:gui_select_buffer, proc { vma.kbd.set_mode("S"); gui_select_buffer }, "Select buffer")
87
88
  reg_act :open_file_dialog, "open_file_dialog", "Open file"
88
89
  reg_act :minibuffer_end, proc { minibuffer_end }
89
90
  reg_act(:invoke_replace, "invoke_replace", "")
@@ -96,6 +97,30 @@ reg_act :delete_to_word_end, proc { buf.delete2(:to_word_end) }, "Delete to file
96
97
  reg_act :delete_to_next_word_start, proc { buf.delete2(:to_next_word) }, "Delete to start of next word", { :group => [:edit, :basic] }
97
98
  reg_act :delete_to_line_start, proc { buf.delete2(:to_line_start) }, "Delete to line start", { :group => [:edit, :basic] }
98
99
 
100
+
101
+ reg_act(:ack_search, proc { gui_ack }, "")
102
+
103
+ reg_act(:copy_cur_line, proc {buf.copy_line}, "Copy the current line")
104
+ reg_act(:paste_before_cursor, proc {buf.paste(BEFORE)}, "Paste text before the cursor")
105
+ reg_act(:paste_after_cursor, proc {buf.paste(AFTER)}, "Paste text after the cursor")
106
+ reg_act(:redo, proc {buf.redo()}, "Redo the last undone action")
107
+ reg_act(:undo, proc {buf.undo()}, "Undo the last action")
108
+ reg_act(:jump_end_of_line, proc { buf.jump(END_OF_LINE) }, "Move to the end of the current line")
109
+ reg_act(:jump_end_of_buffer, proc {buf.jump(END_OF_BUFFER)}, "Move to the end of the buffer")
110
+ reg_act(:jump_start_of_buffer, proc { buf.jump(START_OF_BUFFER) }, "Move to the start of the buffer")
111
+ reg_act(:jump_beginning_of_line, proc { buf.jump(BEGINNING_OF_LINE) }, "Move to the beginning of the current line")
112
+ reg_act(:jump_next_word_end, proc { buf.jump_word(FORWARD,WORD_END) }, "Jump to the end of the next word")
113
+ reg_act(:jump_prev_word_start, proc { buf.jump_word(BACKWARD,WORD_START) }, "Jump to the start of the previous word")
114
+ reg_act(:jump_next_word_start, proc { buf.jump_word(FORWARD,WORD_START) }, "Jump to the start of the next word")
115
+ reg_act(:insert_mode, proc { vma.kbd.set_mode(:insert) }, "Switch to INSERT mode")
116
+ reg_act(:prev_mode, proc { vma.kbd.to_previous_mode }, "Return to the previous mode")
117
+ reg_act(:move_prev_line, proc { buf.move(BACKWARD_LINE) }, "Move the cursor to the previous line")
118
+ reg_act(:move_next_line, proc { buf.move(FORWARD_LINE) }, "Move the cursor to the next line")
119
+ reg_act(:move_backward_char, proc { buf.move(BACKWARD_CHAR) }, "Move one character backward")
120
+ reg_act(:start_visual_mode, proc { buf.start_selection;vma.kbd.set_mode(:visual) }, "Enter VISUAL mode (for selections)")
121
+ reg_act(:jump_last_edit, proc { buf.jump_to_last_edit }, "Jump to the last edit location")
122
+
123
+
99
124
  reg_act :start_browse_mode, proc {
100
125
  vma.kbd.set_mode(:browse)
101
126
  bufs.reset_navigation
@@ -7,8 +7,8 @@
7
7
  #
8
8
  # Change mode from INSERT into COMMAND when ctrl key is released immediately
9
9
  # after it has been pressed (there are no other key events between key press and key release).
10
- # 'I ctrl!'=> '$kbd.set_mode(:command)',
11
- # 'C ctrl!'=> '$kbd.set_mode(:insert)',
10
+ # 'I ctrl!'=> 'vma.kbd.set_mode(:command)',
11
+ # 'C ctrl!'=> 'vma.kbd.set_mode(:insert)',
12
12
 
13
13
  #
14
14
  # In command mode: press keys "," "r" "v" and "b" sequentially.
@@ -18,9 +18,8 @@
18
18
  # 'I ctrl-a'=> 'vma.buf.jump(BEGINNING_OF_LINE)',
19
19
  #
20
20
 
21
-
22
21
  class State
23
- attr_accessor :key_name, :eval_rule, :children, :action, :label, :major_modes, :level, :cursor_type
22
+ attr_accessor :key_name, :eval_rule, :children, :action, :label, :major_modes, :level, :cursor_type, :keywords
24
23
  attr_reader :cur_mode, :scope
25
24
 
26
25
  def initialize(key_name, eval_rule = "", ctype = :command, scope: :buffer)
@@ -29,6 +28,7 @@ class State
29
28
  @children = []
30
29
  @scope = scope
31
30
  @major_modes = []
31
+ @keywords = []
32
32
  @action = nil
33
33
  @level = 0
34
34
  @cursor_type = ctype
@@ -86,7 +86,7 @@ class KeyBindingTree
86
86
 
87
87
  def set_mode_stack(ms)
88
88
  debug "set_mode_stack(#{ms})", 2
89
- show_caller if cnf.debug? # TODO: remove
89
+ show_caller if cnf.debug? # TODO: remove
90
90
  @default_mode_stack = ms
91
91
  label = @default_mode_stack[-1]
92
92
  @match_state = [@modes[label]]
@@ -110,7 +110,7 @@ class KeyBindingTree
110
110
  end
111
111
 
112
112
  def to_previous_mode()
113
- debug "to_previous_mode",2
113
+ debug "to_previous_mode", 2
114
114
  debug @default_mode_stack
115
115
  if @default_mode_stack.size > 1
116
116
  @default_mode_stack.pop
@@ -135,7 +135,6 @@ class KeyBindingTree
135
135
  @modes[label] = mode
136
136
  if @root.nil?
137
137
  show_caller
138
- Ripl.start :binding => binding
139
138
  end
140
139
  @root.children << mode
141
140
  mode.major_modes << major_mode_label
@@ -165,6 +164,7 @@ class KeyBindingTree
165
164
 
166
165
  def match(key_name)
167
166
  new_state = []
167
+ debug = false
168
168
  @match_state.each { |parent|
169
169
  parent.children.each { |c|
170
170
  # printf(" KEY MATCH: ")
@@ -174,6 +174,9 @@ class KeyBindingTree
174
174
  elsif c.key_name == key_name and c.eval_rule != ""
175
175
  debug "CHECK EVAL: #{c.eval_rule}"
176
176
  if eval(c.eval_rule)
177
+ # if eval_rule.match(/macro/)
178
+ debug = true
179
+ # end
177
180
  new_state << c
178
181
  debug "EVAL TRUE"
179
182
  else
@@ -183,6 +186,10 @@ class KeyBindingTree
183
186
  }
184
187
  }
185
188
 
189
+ if debug
190
+ # require "pry"; binding.pry
191
+ end
192
+
186
193
  if new_state.any? # Match found
187
194
  @match_state = new_state
188
195
  return new_state
@@ -262,14 +269,66 @@ class KeyBindingTree
262
269
  @state_trail = [@mode_root_state]
263
270
  end
264
271
 
272
+ def get_by_keywords(modes: [], keywords: [])
273
+ s = ""
274
+ stack = [[@root, ""]]
275
+ lines = []
276
+
277
+ # Traverse the tree (class State objects) using a stack
278
+ while stack.any?
279
+ t, p = *stack.pop # t = current state, p = current path
280
+ if t.children.any?
281
+ t.children.reverse.each { |c|
282
+
283
+ # Restrict by modes if specified
284
+ if c.level == 1 and !modes.empty?
285
+ next if !modes.include?(c.key_name)
286
+ end
287
+
288
+ if c.eval_rule.size > 0
289
+ new_p = "#{p} #{c.key_name}(#{c.eval_rule})"
290
+ else
291
+ if c.level == 1
292
+ new_p = "#{p} [#{c.key_name}]"
293
+ else
294
+ new_p = "#{p} #{c.key_name}"
295
+ end
296
+ end
297
+ stack << [c, new_p]
298
+ }
299
+ # stack.concat[t.children]
300
+
301
+ else
302
+ method_desc = t.action
303
+ if t.action.class == Symbol
304
+ if vma.actions.include?(t.action)
305
+ a = vma.actions[t.action].method_name
306
+ if !a.nil? and !a.empty?
307
+ method_desc = a
308
+ end
309
+ end
310
+ end
311
+
312
+ if (keywords - t.keywords).empty? # All keywords are present
313
+ kw = ""
314
+ # kw = ", [#{t.keywords.join(",")}]" if !t.keywords.empty?
315
+ lines << p + " : #{method_desc}#{kw}"
316
+ end
317
+ end
318
+ end
319
+ s = lines.sort.join("\n")
320
+ return s
321
+ end
322
+
265
323
  # Print key bindings to show as documentation or for debugging
266
324
  def to_s()
267
- # return self.class.to_s
325
+ return self.class.to_s
268
326
  s = ""
269
327
  # @cur_state = @root
270
328
  stack = [[@root, ""]]
271
329
  lines = []
272
330
 
331
+ # Traverse the tree (class State objects) using a stack
273
332
  while stack.any?
274
333
  t, p = *stack.pop # t = current state, p = current path
275
334
  if t.children.any?
@@ -297,7 +356,9 @@ class KeyBindingTree
297
356
  end
298
357
  end
299
358
 
300
- lines << p + " : #{method_desc}"
359
+ kw = ""
360
+ # kw = ", " + t.keywords.join(",") if !t.keywords.empty?
361
+ lines << p + " : #{method_desc}#{kw}"
301
362
  end
302
363
  end
303
364
  s = lines.sort.join("\n")
@@ -426,11 +487,15 @@ class KeyBindingTree
426
487
  else
427
488
 
428
489
  # Don't execute action if one of the states has children
490
+ # TODO: why?
429
491
  state_with_children = new_state.select { |s| s.children.any? }
430
492
  s_act = new_state.select { |s| s.action != nil }
431
493
 
432
- if s_act.any? and !state_with_children.any?
494
+ if s_act.any? #and !state_with_children.any?
433
495
  eval_s = s_act.first.action if eval_s == nil
496
+ # if eval_s.to_s.match(/end_recording/)
497
+ # require "pry"; binding.pry
498
+ # end
434
499
  debug "FOUND MATCH:#{eval_s}"
435
500
  debug "CHAR: #{c}"
436
501
  c.gsub!("\\", %q{\\\\} * 4) # Escape \ -chars
@@ -449,7 +514,12 @@ class KeyBindingTree
449
514
  return true
450
515
  end
451
516
 
452
- def bindkey(key, action)
517
+ def bindkey(key, action, keywords: "")
518
+ # puts "keywords #{keywords}" if !keywords.empty?
519
+ if keywords.class == String
520
+ keywords = keywords.split(" ")
521
+ end
522
+ # puts "keywords #{keywords}" if !keywords.empty?
453
523
  if key.class != Array
454
524
  # Handle syntax like :
455
525
  # "X esc || X ctrl!" => "vma.kbd.to_previous_mode",
@@ -464,10 +534,10 @@ class KeyBindingTree
464
534
  msg = action[2]
465
535
  reg_act(label, proc, msg)
466
536
  end
467
- key.each { |k| _bindkey(k, a) }
537
+ key.each { |k| _bindkey(k, a, keywords: keywords) }
468
538
  end
469
539
 
470
- def _bindkey(key, action)
540
+ def _bindkey(key, action, keywords: [])
471
541
  key.strip!
472
542
  key.gsub!(/\s+/, " ")
473
543
 
@@ -502,15 +572,18 @@ class KeyBindingTree
502
572
  fatal_error("Error in keydef #{key.inspect}")
503
573
  end
504
574
 
575
+ # puts "keywords #{keywords}"
505
576
  modes.each { |mode_id|
506
- mode_bind_key(mode_id, keydef, action)
577
+ mode_bind_key(mode_id, keydef, action, keywords: keywords)
578
+
579
+ # Map froma actions to keybindings (e.g. to show bindings in menu)
507
580
  @act_bindings[mode_id][action] = keydef
508
581
  }
509
582
  end
510
583
 
511
584
  # Binds a keyboard key combination to an action,
512
585
  # for a given keyboard mode like insert ("I") or command ("C")
513
- def mode_bind_key(mode_id, keydef, action)
586
+ def mode_bind_key(mode_id, keydef, action, keywords: [])
514
587
  # debug "mode_bind_key #{mode_id.inspect}, #{keydef.inspect}, #{action.inspect}", 2
515
588
  # Example:
516
589
  # bindkey "C , f", :gui_file_finder
@@ -520,7 +593,7 @@ class KeyBindingTree
520
593
  set_state(mode_id, "") # TODO: check is ok?
521
594
  start_state = @cur_state
522
595
 
523
- k_arr = keydef.split
596
+ k_arr = keydef.split #e.g. definition: "C y e" = > ["C", "y", "e"]
524
597
 
525
598
  prev_state = nil
526
599
  s1 = start_state
@@ -561,6 +634,7 @@ class KeyBindingTree
561
634
  else
562
635
  @cur_state.action = action
563
636
  end
637
+ @cur_state.keywords = keywords
564
638
  @cur_state = @root
565
639
  end
566
640
 
@@ -614,13 +688,19 @@ class KeyBindingTree
614
688
  end
615
689
  end
616
690
 
617
- def bindkey(key, action)
618
- $kbd.bindkey(key, action)
691
+ def bindkey(key, action, keywords: "")
692
+ vma.kbd.bindkey(key, action, keywords: keywords)
693
+ end
694
+
695
+ def add_keys(keywords, to_add)
696
+ to_add.each { |key, value|
697
+ bindkey(key, value, keywords: keywords)
698
+ }
619
699
  end
620
700
 
621
701
  def exec_action(action)
622
- $kbd.last_action = $kbd.cur_action
623
- $kbd.cur_action = action
702
+ vma.kbd.last_action = vma.kbd.cur_action
703
+ vma.kbd.cur_action = action
624
704
  if action.class == Symbol
625
705
  return call_action(action)
626
706
  elsif action.class == Proc
@@ -630,13 +710,70 @@ def exec_action(action)
630
710
  end
631
711
  end
632
712
 
633
- # Try to clear modifiers when program loses focus
634
- # e.g. after alt-tab
635
- def focus_out
636
- debug "RB Clear modifiers"
637
- $kbd.clear_modifiers()
713
+ def show_key_bindings()
714
+ kbd_s = "❙Key bindings❙\n"
715
+ kbd_s << "\n⦁[Mode] <keys> : <action>⦁\n"
716
+ done = []
717
+
718
+ kbd_s << "[B]=Browse, [C]=Command, [I]=Insert, [V]=Visual\n"
719
+ kbd_s << "<key>!: Press <key> once, release before pressing any other keys\n"
720
+ kbd_s << "===============================================\n"
721
+ kbd_s << "◼ Basic\n"
722
+ kbd_s << "◼◼ Command mode\n"
723
+
724
+ x = vma.kbd.get_by_keywords(modes: ["C"], keywords: ["intro"])
725
+ done.concat(x.lines); kbd_s << x
726
+
727
+ kbd_s << "\n"
728
+ kbd_s << "◼◼ Insert mode\n"
729
+ x = vma.kbd.get_by_keywords(modes: ["I"], keywords: ["intro"])
730
+ done.concat(x.lines); kbd_s << x
731
+ kbd_s << "\n"
732
+ kbd_s << "◼◼ Visual mode\n"
733
+ x = vma.kbd.get_by_keywords(modes: ["V"], keywords: ["intro"])
734
+ done.concat(x.lines); kbd_s << x
735
+ kbd_s << "\n"
736
+
737
+ kbd_s << "◼ Core\n"
738
+ x = vma.kbd.get_by_keywords(modes: [], keywords: ["core"])
739
+ x << vma.kbd.get_by_keywords(modes: ["X"], keywords: ["intro"])
740
+
741
+ done.concat(x.lines); kbd_s << x
742
+ kbd_s << "\n"
743
+
744
+ kbd_s << "◼ Debug / Experimental\n"
745
+ x = vma.kbd.get_by_keywords(modes: [], keywords: ["experimental"])
746
+ done.concat(x.lines); kbd_s << x
747
+ kbd_s << "\n"
748
+
749
+ kbd_s << "◼ Others\n"
750
+ # x = vma.kbd.get_by_keywords(modes: [], keywords:["experimental"])
751
+ # x = vma.kbd.to_s
752
+ x = vma.kbd.get_by_keywords(modes: [], keywords: [])
753
+ done << x.lines - done
754
+ kbd_s << (x.lines - done).join
755
+ kbd_s << "\n"
756
+
757
+ kbd_s << "===============================================\n"
758
+ # x = vma.kbd.to_s
759
+ # # require "pry"; binding.pry
760
+ # done << x.lines - done
761
+ # kbd_s << (x.lines - done).join
762
+ # kbd_s << "\n"
763
+ # kbd_s << "===============================================\n"
764
+ b = create_new_buffer(kbd_s, "key-bindings")
765
+ gui_set_file_lang(b.id, "hyperplaintext")
766
+ #
638
767
  end
639
768
 
640
- def handle_key_event(event)
641
- $kbd.handle_key_event(event)
642
- end
769
+ # Try to clear modifiers when program loses focus
770
+ # e.g. after alt-tab
771
+ # TODO
772
+ # def focus_out
773
+ # debug "RB Clear modifiers"
774
+ # vma.kbd.clear_modifiers()
775
+ # end
776
+
777
+ # def handle_key_event(event)
778
+ # vma.kbd.handle_key_event(event)
779
+ # end