vimamsa 0.1.12 → 0.1.13

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: 33b88d4f4c567a38c726a1eee1a408fb051a972a54afebfee29add1e81f7761d
4
- data.tar.gz: '0366913aba4ccf3f687cbce63fec3815df7cf8c98ae1e00272be32d898f4ec48'
3
+ metadata.gz: 9bd13f53f2d774550226da6e379842c2d54bde6e8ffa5362d4769940d93a033e
4
+ data.tar.gz: 5f2db7ad2c5402a816f186e266194f1a7545b1a2a71fd532f9140634835fc3f2
5
5
  SHA512:
6
- metadata.gz: 3eaa999737e313cfbfb1028031d60101c7c3fcbcfb30504991c4a7a350da374f0969502e13facf46cc69f63b60d576817fa86cbd87981be8988e7998fef119b7
7
- data.tar.gz: 298335f27adce1d7164ea138908419db2b7d1192014ad780651779f36d1a384cde34e5196fa3cae021beaf178e551de08e92a81f03643dec476bbb01a2e1d566
6
+ metadata.gz: d41917d0e0cfa9a876579bea6aaaafee3b3eff3757d74c399922a5db71220889f278df03bd1bc3e1177002fa906e3d30792280004dd5270d2b135dd6006f51ca
7
+ data.tar.gz: c4935e09ecb5a714cb481ac00386e698aee72583030f03cf9b7c182c71066513339c2c0c4aa6f723e00630e659704e95a107007a76af936d08e67a8e6ded5c5f
data/lib/vimamsa/ack.rb CHANGED
@@ -111,14 +111,15 @@ Will search the following directories:
111
111
  gui_one_input_action(nfo, "Search:", "search", callback)
112
112
  end
113
113
 
114
- def ack_buffer(instr, b = nil)
115
- instr = Shellwords.escape(instr)
114
+ def ack_buffer(_instr, b = nil)
115
+ instr = Shellwords.escape(_instr)
116
116
  bufstr = ""
117
117
  for path in vma.get_content_search_paths
118
118
  bufstr += run_cmd("ack -Q --type-add=gd=.gd -ki --nohtml --nojs --nojson #{instr} #{path}")
119
119
  end
120
120
  if bufstr.size > 5
121
- create_new_buffer(bufstr,"ack")
121
+ b = create_new_buffer(bufstr,"ack")
122
+ highlight_match(b, _instr, color: "#10bd8e")
122
123
  else
123
124
  message("No results for input:#{instr}")
124
125
  end
@@ -32,11 +32,14 @@ def missing_callfunc
32
32
  end
33
33
 
34
34
  #TODO: remove
35
- def call(id)
36
- call_action(id)
37
- end
35
+ # def call(id)
36
+ # call_action(id)
37
+ # end
38
+
39
+ $acth = []
38
40
 
39
41
  def call_action(id)
42
+ $acth << id
40
43
  a = $actions[id]
41
44
  if a
42
45
  a.method.call()
@@ -45,11 +48,15 @@ def call_action(id)
45
48
  end
46
49
  end
47
50
 
51
+ def last_action
52
+ return $acth[-1]
53
+ end
54
+
48
55
  def search_actions()
49
56
  l = []
50
- opt = { :title => "Search actions.", :desc => "Fuzzy search for actions. <up> or <down> to change selcted. <enter> to select current." }
57
+ opt = { :title => "Search for actions", :desc => "Fuzzy search for actions. <up> or <down> to change selcted. <enter> to select current." }
51
58
  $select_keys = ["h", "l", "f", "d", "s", "a", "g", "z"]
52
-
59
+
53
60
  gui_select_update_window(l, $select_keys.collect { |x| x.upcase },
54
61
  "search_actions_select_callback",
55
62
  "search_actions_update_callback",
@@ -109,7 +116,7 @@ def search_actions_select_callback(search_str, idx)
109
116
  eval(acc)
110
117
  elsif acc.class == Symbol
111
118
  debug "Symbol"
112
- call(acc)
119
+ call_action(acc)
113
120
  end
114
121
  end
115
122
 
@@ -0,0 +1,58 @@
1
+ require "gstreamer"
2
+
3
+ # following the example gstreamer-4.2.0/sample/helloworld_e.rb
4
+ class Audio
5
+ @@playbin = nil
6
+
7
+ def self.stop
8
+ @@playbin.stop if !@@playbin.nil?
9
+ end
10
+
11
+ def self.play(fn)
12
+ playbin = @@playbin
13
+ if playbin.nil?
14
+ playbin = Gst::ElementFactory.make("playbin")
15
+ if playbin.nil?
16
+ puts "'playbin' gstreamer plugin missing"
17
+ return
18
+ end
19
+ else
20
+ if playbin.current_state == "playing"
21
+ playbin.stop # Stop previous play
22
+ end
23
+ end
24
+
25
+ # playbin.volume
26
+ # playbin.volume=1.0
27
+ # playbin.stream_time
28
+ # playbin.current_state
29
+
30
+ # take the commandline argument and ensure that it is a uri
31
+ if Gst.valid_uri?(fn)
32
+ uri = fn
33
+ else
34
+ uri = Gst.filename_to_uri(fn)
35
+ end
36
+ playbin.uri = uri
37
+ @@playbin = playbin
38
+
39
+ bus = playbin.bus
40
+ bus.add_watch do |bus, message|
41
+
42
+ case message.type
43
+ when Gst::MessageType::EOS
44
+ puts "End-of-stream"
45
+ when Gst::MessageType::ERROR
46
+ error, debug = message.parse_error
47
+ puts "Debugging info: #{debug || "none"}"
48
+ puts "Error: #{error.message}"
49
+ end
50
+ true
51
+ end
52
+
53
+ message("Start playing audio: #{fn}")
54
+
55
+ # start play back and listed to events
56
+ playbin.play
57
+ end
58
+ end
@@ -5,7 +5,6 @@ require "pathname"
5
5
  require "openssl"
6
6
  require "ripl/multi_line"
7
7
 
8
- $paste_lines = false
9
8
  $buffer_history = []
10
9
 
11
10
  $update_highlight = false
@@ -15,7 +14,7 @@ $ifuncon = false
15
14
  class Buffer < String
16
15
  attr_reader :pos, :lpos, :cpos, :deltas, :edit_history, :fname, :call_func, :pathname, :basename, :dirname, :update_highlight, :marks, :is_highlighted, :syntax_detect_failed, :id, :lang, :images, :last_save
17
16
  attr_writer :call_func, :update_highlight
18
- attr_accessor :gui_update_highlight, :update_hl_startpos, :update_hl_endpos, :hl_queue, :syntax_parser, :highlights, :gui_reset_highlight, :is_parsing_syntax, :line_ends, :bt, :line_action_handler, :module, :active_kbd_mode, :title, :subtitle
17
+ attr_accessor :gui_update_highlight, :update_hl_startpos, :update_hl_endpos, :hl_queue, :syntax_parser, :highlights, :gui_reset_highlight, :is_parsing_syntax, :line_ends, :bt, :line_action_handler, :module, :active_kbd_mode, :title, :subtitle, :paste_lines
19
18
 
20
19
  @@num_buffers = 0
21
20
 
@@ -32,6 +31,9 @@ class Buffer < String
32
31
  gui_create_buffer(@id, self)
33
32
  debug "NEW BUFFER fn=#{fname} ID:#{@id}"
34
33
 
34
+ # If true, we will create new line after this and paste there
35
+ @paste_lines = false
36
+
35
37
  @module = nil
36
38
 
37
39
  @last_save = @last_asked_from_user = @file_last_cheked = Time.now
@@ -398,7 +400,6 @@ class Buffer < String
398
400
  gui_set_buffer_contents(@id, self.to_s)
399
401
  @images = [] #TODO: if reload
400
402
  hpt_scan_images(self)
401
- hpt_scan_audio(self)
402
403
 
403
404
  # add_hl_update(@update_hl_startpos, @update_hl_endpos)
404
405
  end
@@ -803,7 +804,7 @@ class Buffer < String
803
804
  end
804
805
 
805
806
  def copy(range_id)
806
- $paste_lines = false
807
+ @paste_lines = false
807
808
  debug "range_id: #{range_id}"
808
809
  debug range_id.inspect
809
810
  range = get_range(range_id)
@@ -966,9 +967,14 @@ class Buffer < String
966
967
  set_line_and_column_pos(nil, nil)
967
968
  end
968
969
 
969
- def delete2(range_id)
970
- $paste_lines = false
971
- range = get_range(range_id)
970
+ def delete2(range_id, mark = nil)
971
+ # if mark != nil
972
+ # debug mark, 2
973
+ # return
974
+ # end
975
+
976
+ @paste_lines = false
977
+ range = get_range(range_id, mark: mark)
972
978
  return if range == nil
973
979
  debug "RANGE"
974
980
  debug range.inspect
@@ -980,7 +986,7 @@ class Buffer < String
980
986
  end
981
987
 
982
988
  def delete(op, x = nil)
983
- $paste_lines = false
989
+ @paste_lines = false
984
990
  # Delete selection
985
991
  if op == SELECTION && visual_mode?
986
992
  (startpos, endpos) = get_visual_mode_range2
@@ -1028,7 +1034,7 @@ class Buffer < String
1028
1034
  end
1029
1035
 
1030
1036
  # Ranges to use in delete or copy operations
1031
- def get_range(range_id)
1037
+ def get_range(range_id, mark: nil)
1032
1038
  range = nil
1033
1039
  if range_id == :to_word_end
1034
1040
  # TODO: better way to make the search than + 150 from current position
@@ -1045,6 +1051,16 @@ class Buffer < String
1045
1051
  range = get_range(:to_word_end)
1046
1052
  end
1047
1053
  # Ripl.start :binding => binding
1054
+
1055
+ elsif range_id == :to_mark
1056
+ debug "TO MARK"
1057
+ start = @line_ends[@lpos]
1058
+ mpos = @marks[mark]
1059
+ if !mpos.nil?
1060
+ range = start..mpos
1061
+ else
1062
+ return nil
1063
+ end
1048
1064
  elsif range_id == :to_line_end
1049
1065
  debug "TO LINE END"
1050
1066
  range = @pos..(@line_ends[@lpos] - 1)
@@ -1068,15 +1084,18 @@ class Buffer < String
1068
1084
  end
1069
1085
  return range if range == nil
1070
1086
  if range.last < range.first
1071
- range.last = range.first
1087
+ range = range.last..range.first
1088
+ # range.last = range.first
1072
1089
  end
1073
1090
  if range.first < 0
1074
- range.first = 0
1091
+ # range.first = 0
1092
+ range = 0..range.last
1075
1093
  end
1076
1094
  if range.last >= self.size
1077
- range.last = self.size - 1
1095
+ # range.last = self.size - 1
1096
+ range = range.first..(self.size - 1)
1078
1097
  end
1079
- #TODO: sanity check
1098
+ debug range, 2
1080
1099
  return range
1081
1100
  end
1082
1101
 
@@ -1487,6 +1506,10 @@ class Buffer < String
1487
1506
  end
1488
1507
 
1489
1508
  def insert_txt_at(c, pos)
1509
+ if c.nil? or pos.nil?
1510
+ error("input c=nil || pos=nil")
1511
+ return
1512
+ end
1490
1513
  c = c.force_encoding("UTF-8"); #TODO:correct?
1491
1514
  c = "\n" if c == "\r"
1492
1515
  add_delta([pos, INSERT, c.size, c], true)
@@ -1608,26 +1631,32 @@ class Buffer < String
1608
1631
  @clipboard_paste_running = true
1609
1632
  clipboard = vma.gui.window.display.clipboard
1610
1633
  clipboard.read_text_async do |_clipboard, result|
1611
- text = clipboard.read_text_finish(result)
1612
- paste_finish(text, at, register)
1634
+ begin
1635
+ text = clipboard.read_text_finish(result)
1636
+ rescue Gio::IOError::NotSupported
1637
+ # Happens when pasting from KeePassX and clipboard cleared
1638
+ debug Gio::IOError::NotSupported
1639
+ else
1640
+ paste_finish(text, at, register)
1641
+ end
1613
1642
  end
1614
1643
  end
1615
1644
 
1616
1645
  def paste_finish(text, at, register)
1617
- # if text == ""
1618
- # return if !$clipboard.any?
1619
- # if register == nil
1620
- # text = $clipboard[-1]
1621
- # else
1622
- # text = $register[register]
1623
- # end
1624
- # end
1625
1646
  debug "PASTE: #{text}"
1647
+
1648
+ # If we did not put this text to clipboard
1649
+ if text != $clipboard[-1]
1650
+ @paste_lines = false
1651
+ end
1652
+
1653
+ text = sanitize_input(text)
1654
+
1626
1655
  $clipboard << text
1627
1656
 
1628
1657
  return if text == ""
1629
1658
 
1630
- if $paste_lines
1659
+ if @paste_lines
1631
1660
  debug "PASTE LINES"
1632
1661
  put_to_new_next_line(text)
1633
1662
  else
@@ -1669,7 +1698,7 @@ class Buffer < String
1669
1698
  add_delta([lrange.begin, DELETE, lrange.end - lrange.begin + 1], true)
1670
1699
  set_clipboard(s)
1671
1700
  update_pos(lrange.begin)
1672
- $paste_lines = true
1701
+ @paste_lines = true
1673
1702
  #recalc_line_ends
1674
1703
  end
1675
1704
 
@@ -1686,7 +1715,7 @@ class Buffer < String
1686
1715
 
1687
1716
  def copy_active_selection(x = nil)
1688
1717
  debug "!COPY SELECTION"
1689
- $paste_lines = false
1718
+ @paste_lines = false
1690
1719
  return if !@visual_mode
1691
1720
 
1692
1721
  debug "COPY SELECTION"
@@ -1766,7 +1795,7 @@ class Buffer < String
1766
1795
  debug "copy num_lines:#{num_lines}"
1767
1796
  end
1768
1797
  set_clipboard(self[line_range(@lpos, num_lines)])
1769
- $paste_lines = true
1798
+ @paste_lines = true
1770
1799
  end
1771
1800
 
1772
1801
  def put_file_path_to_clipboard
@@ -1786,6 +1815,7 @@ class Buffer < String
1786
1815
  end
1787
1816
 
1788
1817
  def end_visual_mode()
1818
+ return if !visual_mode?
1789
1819
  debug "End visual mode"
1790
1820
  #TODO:take previous mode (insert|command) from stack?
1791
1821
  $kbd.set_mode(:command)
@@ -2025,7 +2055,7 @@ class Buffer < String
2025
2055
  end
2026
2056
  end
2027
2057
 
2028
- #TODO
2058
+ #TODO: function not used
2029
2059
  def write_to_file(savepath, s)
2030
2060
  if is_path_writable(savepath)
2031
2061
  IO.write(savepath, self.to_s)
@@ -26,10 +26,6 @@ def handle_drag_and_drop(fname)
26
26
  buf.handle_drag_and_drop(fname)
27
27
  end
28
28
 
29
- def mkdir_if_not_exists(_dirpath)
30
- dirpath = File.expand_path(_dirpath)
31
- Dir.mkdir(dirpath) unless File.exist?(dirpath)
32
- end
33
29
 
34
30
  class Editor
35
31
  attr_reader :file_content_search_paths, :file_name_search_paths, :gui, :hook, :macro
@@ -49,6 +45,7 @@ class Editor
49
45
  @converters = {}
50
46
  @paint_stack = []
51
47
  @_plugins = {}
48
+ @errors
52
49
  end
53
50
 
54
51
  def open_file_listener(added)
@@ -93,11 +90,10 @@ class Editor
93
90
  $kbd = @kbd
94
91
  require "vimamsa/key_bindings_vimlike"
95
92
  sleep(0.03)
96
-
97
93
 
98
94
  FileManager.init
99
95
  BufferManager.init
100
-
96
+
101
97
  @gui.init_menu
102
98
 
103
99
  mkdir_if_not_exists("~/.vimamsa")
@@ -136,10 +132,11 @@ class Editor
136
132
 
137
133
  if conf(:enable_lsp)
138
134
  require "vimamsa/langservp"
135
+ require "vimamsa/audio" # TODO:config
139
136
  @langsrv["ruby"] = LangSrv.new("ruby")
140
137
  @langsrv["cpp"] = LangSrv.new("cpp")
141
138
  end
142
-
139
+
143
140
  # build_options
144
141
 
145
142
  fname = nil
@@ -282,6 +279,11 @@ class Editor
282
279
  debug "CAN OPEN?: #{can_open}"
283
280
  return can_open
284
281
  end
282
+
283
+ def error(message)
284
+ debug "ERORR #{caller[0]} #{str}", 2
285
+ @errors << [message, caller]
286
+ end
285
287
  end
286
288
 
287
289
  def _quit()
@@ -389,7 +391,7 @@ def show_key_bindings()
389
391
  kbd_s << vma.kbd.to_s
390
392
  kbd_s << "\n"
391
393
  kbd_s << "===============================================\n"
392
- b = create_new_buffer(kbd_s,"key-bindings")
394
+ b = create_new_buffer(kbd_s, "key-bindings")
393
395
  gui_set_file_lang(b.id, "hyperplaintext")
394
396
  #
395
397
  end
@@ -456,6 +458,11 @@ def minibuffer_delete()
456
458
  $minibuffer.delete(BACKWARD_CHAR)
457
459
  end
458
460
 
461
+ def error(str)
462
+ puts caller[0]
463
+ debug "#{caller[0]} ERROR: #{str}", 2
464
+ end
465
+
459
466
  def message(s)
460
467
  s = "[#{DateTime.now().strftime("%H:%M")}] #{s}"
461
468
  debug s
@@ -502,16 +509,16 @@ def create_new_file(filename = nil, file_contents = "\n")
502
509
  vma.kbd.set_mode_to_default
503
510
  vma.buffers.set_current_buffer_by_id(buffer.id)
504
511
 
505
- # Do set_content twice (once in Buffer.new) to force redraw and work around a bug
512
+ # Do set_content twice (once in Buffer.new) to force redraw and work around a bug
506
513
  # The bug: if switching a child of scrolledWindow to a textview with a file smaller than the window, it won't get drawn properly if in previous (larger) file the ScrolledWindow was scrolled down.
507
514
  buffer.set_content(file_contents)
508
515
 
509
516
  return buffer
510
517
  end
511
518
 
512
- def create_new_buffer(file_contents = "\n",prefix="buf", setcurrent=true)
519
+ def create_new_buffer(file_contents = "\n", prefix = "buf", setcurrent = true)
513
520
  debug "NEW BUFFER CREATED"
514
- buffer = Buffer.new(file_contents,nil,prefix)
521
+ buffer = Buffer.new(file_contents, nil, prefix)
515
522
  vma.buffers.add(buffer)
516
523
  vma.buffers.set_current_buffer_by_id(buffer.id) if setcurrent
517
524
  buffer.set_content(file_contents)
@@ -585,6 +592,10 @@ def open_new_file(filename, file_contents = "")
585
592
  message "Switching to: #{filename}"
586
593
  vma.buffers.set_current_buffer(b)
587
594
  else
595
+ if !is_path_writable(filename)
596
+ message("Path #{filename} cannot be written to")
597
+ return false
598
+ end
588
599
  message "New file opened: #{filename}"
589
600
  fname = filename
590
601
  bf = load_buffer(fname)
@@ -622,45 +633,7 @@ def get_file_line_pointer(s)
622
633
  return nil
623
634
  end
624
635
 
625
- def open_url(url)
626
- system("xdg-open", url)
627
- end
628
-
629
- def open_with_default_program(url)
630
- system("xdg-open", url)
631
- end
632
-
633
- def run_cmd(cmd)
634
- tmpf = Tempfile.new("vmarun", "/tmp").path
635
- cmd = "#{cmd} > #{tmpf}"
636
- debug "CMD:\n#{cmd}"
637
- system("bash", "-c", cmd)
638
- res_str = File.read(tmpf)
639
- return res_str
640
- end
641
-
642
- require "open3"
643
-
644
- def exec_cmd(bin_name, arg1 = nil, arg2 = nil, arg3 = nil, arg4 = nil, arg5 = nil)
645
- assert_binary_exists(bin_name)
646
- if !arg5.nil?
647
- p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4, arg5)
648
- elsif !arg4.nil?
649
- p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4)
650
- elsif !arg3.nil?
651
- p = Open3.popen2(bin_name, arg1, arg2, arg3)
652
- elsif !arg2.nil?
653
- p = Open3.popen2(bin_name, arg1, arg2)
654
- elsif !arg1.nil?
655
- p = Open3.popen2(bin_name, arg1)
656
- else
657
- p = Open3.popen2(bin_name)
658
- end
659
-
660
- ret_str = p[1].read
661
- return ret_str
662
- end
663
-
636
+ # TODO: Implement using https://github.com/blackwinter/ruby-filemagic
664
637
  def file_is_text_file(fpath)
665
638
  debug "file_is_text_file(#{fpath})"
666
639
  fpath = File.expand_path(fpath)
data/lib/vimamsa/gui.rb CHANGED
@@ -90,33 +90,6 @@ def page_down
90
90
  return true
91
91
  end
92
92
 
93
- def paste_system_clipboard()
94
-
95
- #TODO: Check if something useful in this old GTK3 code.
96
- utf8_string = Gdk::Atom.intern("UTF8_STRING")
97
-
98
- clipboard = Gtk::Clipboard.get_default($vmag.window.display)
99
- received_text = ""
100
-
101
- target_string = Gdk::Selection::TARGET_STRING
102
- ti = clipboard.request_contents(target_string)
103
-
104
- if clipboard.wait_is_text_available?
105
- received_text = clipboard.wait_for_text
106
- end
107
-
108
- if received_text != "" and !received_text.nil?
109
- max_clipboard_items = 100
110
- if received_text != $clipboard[-1]
111
- #TODO: HACK
112
- $paste_lines = false
113
- end
114
- $clipboard << received_text
115
- # debug $clipboard[-1]
116
- $clipboard = $clipboard[-([$clipboard.size, max_clipboard_items].min)..-1]
117
- end
118
- return received_text
119
- end
120
93
 
121
94
  def set_system_clipboard(arg)
122
95
  vma.gui.window.display.clipboard.set(arg)
@@ -313,9 +286,15 @@ class VMAgui
313
286
  # Run proc after animated scrolling has stopped (e.g. after page down)
314
287
  def run_after_scrolling(p)
315
288
  Thread.new {
289
+ # After running
290
+ # view.signal_emit("move-cursor", Gtk::MovementStep.new(:PAGES)
291
+ # have to wait for animated page down scrolling to actually start
292
+ # Then have to wait determine that it has stopped if scrolling adjustment stops changing. There should be a better way to do this.
293
+ sleep 0.1
316
294
  while Time.now - @last_adj_time < 0.1
317
295
  sleep 0.1
318
296
  end
297
+ debug "SCROLLING ENDED", 2
319
298
  run_as_idle p
320
299
  }
321
300
  end
@@ -346,6 +325,7 @@ class VMAgui
346
325
  end
347
326
 
348
327
  def handle_deltas()
328
+ view.delete_cursor_char
349
329
  while d = buf.deltas.shift
350
330
  pos = d[0]
351
331
  op = d[1]
@@ -624,6 +604,7 @@ class VMAgui
624
604
  @sw = Gtk::ScrolledWindow.new
625
605
  @sw.set_policy(:automatic, :automatic)
626
606
 
607
+
627
608
  @last_adj_time = Time.now
628
609
  @sw.vadjustment.signal_connect("value-changed") { |x|
629
610
  # pp x.page_increment
@@ -69,13 +69,19 @@ class SelectUpdateWindow
69
69
 
70
70
  @window.add(vbox)
71
71
 
72
+ if !opt[:desc].nil?
73
+ descl = Gtk::Label.new(opt[:desc])
74
+ set_margin_all(descl,15)
75
+ # vbox.append(descl, :expand => false, :fill => false, :padding => 0)
76
+ vbox.append(descl)
77
+ end
78
+
72
79
  @entry = Gtk::SearchEntry.new
73
80
  @entry.width_chars = 45
74
81
  container = Gtk::Box.new(:horizontal, 10)
75
82
  # container.halign = :start
76
83
  container.halign = :center
77
- container.pack_start(@entry,
78
- :expand => false, :fill => false, :padding => 0)
84
+ container.append(@entry)
79
85
 
80
86
  # create tree view
81
87
  @model = Gtk::ListStore.new(String, String)
@@ -135,11 +141,6 @@ class SelectUpdateWindow
135
141
  @entry.signal_connect("changed") { debug "[changed] " }
136
142
  @entry.signal_connect("next-match") { debug "[next-match] " }
137
143
 
138
- if !opt[:desc].nil?
139
- descl = Gtk::Label.new(opt[:desc])
140
- vbox.pack_start(descl, :expand => false, :fill => false, :padding => 0)
141
- end
142
-
143
144
  # label = Gtk::Label.new(<<-EOF)
144
145
  # Search:
145
146
  # EOF
@@ -147,7 +148,7 @@ class SelectUpdateWindow
147
148
  # label = Gtk::Label.new("Input:")
148
149
  # vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
149
150
 
150
- vbox.pack_start(container, :expand => false, :fill => false, :padding => 0)
151
+ vbox.append(container)
151
152
  sw = Gtk::ScrolledWindow.new(nil, nil)
152
153
  # sw.shadow_type = :etched_in #TODO:gtk4
153
154
  sw.set_policy(:never, :automatic)
@@ -34,6 +34,7 @@ class VSourceView < GtkSource::View
34
34
  # puts "drag-data-received"
35
35
  # puts
36
36
  # if data.uris.size >= 1
37
+
37
38
  # imgpath = CGI.unescape(data.uris[0])
38
39
  # m = imgpath.match(/^file:\/\/(.*)/)
39
40
  # if m
@@ -46,8 +47,14 @@ class VSourceView < GtkSource::View
46
47
 
47
48
  # Mainly after page-up or page-down
48
49
  signal_connect("move-cursor") do |widget, event|
49
- debug("MOVE-CURSOR", 2)
50
- $update_cursor = true
50
+ if event.name == "GTK_MOVEMENT_PAGES" and (last_action == "page_up" or last_action == "page_down")
51
+ # Ripl.start :binding => binding
52
+
53
+ debug("MOVE-CURSOR", 2)
54
+ # $update_cursor = true
55
+ handle_scrolling()
56
+ end
57
+
51
58
  # handle_scrolling()
52
59
  # curpos = buffer.cursor_position
53
60
  # debug "MOVE CURSOR (sig): #{curpos}"
@@ -110,47 +117,116 @@ class VSourceView < GtkSource::View
110
117
  end
111
118
 
112
119
  def register_signals()
120
+ check_controllers
113
121
 
114
- #TODO: Doesn't seem to catch "move-cursor" signal since upgrade to gtk4
115
- # self.signal_connect("move-cursor") do |widget, event|
116
- # $update_cursor = true
117
- # false
118
- # end
122
+ # Implement mouse selections using @cnt_mo and @cnt_drag
123
+ @cnt_mo = Gtk::EventControllerMotion.new
124
+ self.add_controller(@cnt_mo)
125
+ @cnt_mo.signal_connect "motion" do |gesture, x, y|
126
+ if !@range_start.nil? and !x.nil? and !y.nil? and buf.visual_mode?
127
+ i = coord_to_iter(x, y, true)
128
+ @bufo.set_pos(i) if !i.nil? and @last_iter != i
129
+ @last_iter = i
130
+ end
131
+ end
132
+
133
+ @last_coord = nil
134
+ @cnt_drag = Gtk::GestureDrag.new
135
+ self.add_controller(@cnt_drag)
136
+ @cnt_drag.signal_connect "drag-begin" do |gesture, x, y|
137
+ debug "drag-begin", 2
138
+ i = coord_to_iter(x, y, true)
139
+ pp i
140
+ @range_start = i
141
+ if !buf.visual_mode?
142
+ buf.start_visual_mode
143
+ end
144
+ end
145
+
146
+ @cnt_drag.signal_connect "drag-end" do |gesture, offsetx, offsety|
147
+ debug "drag-end", 2
148
+
149
+ # Not enough drag
150
+ if offsetx.abs < 5 and offsety.abs < 5
151
+ buf.end_visual_mode
152
+ end
153
+ @range_start = nil
154
+ end
119
155
 
120
- check_controllers
121
156
  click = Gtk::GestureClick.new
122
157
  click.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
123
158
  self.add_controller(click)
124
159
  # Detect mouse click
125
160
  @click = click
161
+
162
+ @range_start = nil
126
163
  click.signal_connect "pressed" do |gesture, n_press, x, y, z|
127
- debug "SourceView, GestureClick x=#{x} y=#{y}"
128
- pp visible_rect
129
- winw = width
130
- view_width = visible_rect.width
131
- gutter_width = winw - view_width
164
+ debug "SourceView, GestureClick released x=#{x} y=#{y}"
165
+
166
+ if buf.visual_mode?
167
+ buf.end_visual_mode
168
+ end
132
169
 
133
170
  xloc = (x - gutter_width).to_i
134
171
  yloc = (y + visible_rect.y).to_i
135
172
  debug "xloc=#{xloc} yloc=#{yloc}"
136
173
 
174
+ i = coord_to_iter(xloc, yloc)
175
+ # @range_start = i
176
+
137
177
  # This needs to happen after xloc calculation, otherwise xloc gets a wrong value (around 200 bigger)
138
178
  if vma.gui.current_view != self
139
179
  vma.gui.set_current_view(self)
140
180
  end
141
181
 
142
- i = get_iter_at_location(xloc, yloc)
143
- if !i.nil?
144
- @bufo.set_pos(i.offset)
145
- else
146
- debug "iter nil"
147
- #TODO: find correct line position some other way
182
+ @bufo.set_pos(i) if !i.nil?
183
+ true
184
+ end
185
+
186
+ click.signal_connect "released" do |gesture, n_press, x, y, z|
187
+ debug "SourceView, GestureClick released x=#{x} y=#{y}"
188
+
189
+ xloc = (x - gutter_width).to_i
190
+ yloc = (y + visible_rect.y).to_i
191
+ debug "xloc=#{xloc} yloc=#{yloc}"
192
+
193
+ # This needs to happen after xloc calculation, otherwise xloc gets a wrong value (around 200 bigger)
194
+ if vma.gui.current_view != self
195
+ vma.gui.set_current_view(self)
148
196
  end
149
197
 
198
+ i = coord_to_iter(xloc, yloc)
199
+
200
+ # if i != @range_start
201
+ # debug "RANGE #{[@range_start, i]}", 2
202
+ # end
203
+
204
+ @bufo.set_pos(i) if !i.nil?
205
+ # @range_start = nil
150
206
  true
151
207
  end
152
208
  end
153
209
 
210
+ def coord_to_iter(xloc, yloc, transform_coord = false)
211
+ if transform_coord
212
+ xloc = (xloc - gutter_width).to_i
213
+ yloc = (yloc + visible_rect.y).to_i
214
+ end
215
+
216
+ # Try to get exact character position
217
+ i = get_iter_at_location(xloc, yloc)
218
+
219
+ # If doesn't work, at least get the start of correct line
220
+ # TODO: sometimes end of line is better choice
221
+ if i.nil?
222
+ r = get_line_at_y(yloc)
223
+ i = r[0] if !r.nil?
224
+ end
225
+
226
+ return i.offset if !i.nil?
227
+ return nil
228
+ end
229
+
154
230
  def handle_scrolling()
155
231
  delete_cursorchar
156
232
  # curpos = buffer.cursor_position
@@ -158,18 +234,13 @@ class VSourceView < GtkSource::View
158
234
  return nil if vma.gui.nil?
159
235
  return nil if @bufo.nil?
160
236
  vma.gui.run_after_scrolling proc {
237
+ debug "START UPDATE POS AFTER SCROLLING", 2
161
238
  delete_cursorchar
162
239
  bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
163
240
  if !bc.nil?
164
- # Try to get exact character position
165
- i = get_iter_at_location(bc[0], bc[1])
166
- if i.nil?
167
- # If doesn't work, at least get the start of correct line
168
- i = get_line_at_y(bc[1])
169
- i = i[0]
170
- end
241
+ i = coord_to_iter(bc[0], bc[1])
171
242
  if !i.nil?
172
- @bufo.set_pos(i.offset)
243
+ @bufo.set_pos(i)
173
244
  end
174
245
  end
175
246
  $update_cursor = false
@@ -342,8 +413,6 @@ class VSourceView < GtkSource::View
342
413
  itr2 = buffer.get_iter_at(:offset => pos + 1)
343
414
  buffer.place_cursor(itr)
344
415
 
345
- # $view.signal_emit("extend-selection", Gtk::MovementStep.new(:PAGES), -1, false)
346
-
347
416
  within_margin = 0.075 #margin as a [0.0,0.5) fraction of screen size
348
417
  use_align = false
349
418
  xalign = 0.5 #0.0=top 1.0=bottom, 0.5=center
@@ -358,9 +427,6 @@ class VSourceView < GtkSource::View
358
427
  $idle_scroll_to_mark = true
359
428
  ensure_cursor_visible
360
429
 
361
- # scroll_to_iter(itr, within_margin, use_align, xalign, yalign)
362
-
363
- # $view.signal_emit("extend-selection", Gtk::TextExtendSelection.new, itr,itr,itr2)
364
430
  draw_cursor
365
431
 
366
432
  return true
@@ -477,9 +543,9 @@ class VSourceView < GtkSource::View
477
543
  end
478
544
  # elsif @bufo.visual_mode?
479
545
  elsif ctype == :visual
480
- debug "VISUAL MODE"
546
+ # debug "VISUAL MODE"
481
547
  (_start, _end) = @bufo.get_visual_mode_range2
482
- debug "#{_start}, #{_end}"
548
+ # debug "#{_start}, #{_end}"
483
549
  itr = buffer.get_iter_at(:offset => _start)
484
550
  itr2 = buffer.get_iter_at(:offset => _end + 1)
485
551
  # Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
@@ -1,8 +1,10 @@
1
1
  def hpt_check_cur_word(w)
2
2
  debug "check_cur_word(w)"
3
- m = w.match(/⟦(.*)⟧/)
3
+ m = w.match(/⟦((audio|img):)(.*)⟧/)
4
4
  if m
5
- fpfx = m[1]
5
+ # Ripl.start :binding => binding
6
+
7
+ fpfx = m[3]
6
8
  if vma.buf.fname
7
9
  dn = File.dirname(vma.buf.fname)
8
10
 
@@ -23,8 +25,13 @@ def hpt_check_cur_word(w)
23
25
  end
24
26
 
25
27
  if fn
26
- message "HPT opening file #{fn}"
27
- return fn
28
+ if m[2] == "audio"
29
+ # Thread.new { Audio.play(fn) }
30
+ Audio.play(fn)
31
+ else
32
+ message "HPT opening file #{fn}"
33
+ return fn
34
+ end
28
35
  # open_existing_file(fn)
29
36
  # return true
30
37
  else
@@ -104,6 +104,10 @@ reg_act(:execute_current_line_in_terminal_autoclose, proc { buf.execute_current_
104
104
  reg_act(:show_images, proc { hpt_scan_images() }, "Show images inserted with ⟦img:file.png⟧ syntax")
105
105
  reg_act(:delete_current_file, proc { bufs.delete_current_buffer() }, "Delete current file")
106
106
 
107
+
108
+ reg_act(:audio_stop, proc { Audio.stop }, "Stop audio playback")
109
+
110
+
107
111
  act_list = {
108
112
  # File handling
109
113
  :buf_save => { :proc => proc { buf.save },
@@ -267,7 +267,12 @@ class KeyBindingTree
267
267
  for st in @state_trail
268
268
  st = st[0] if st.class == Array
269
269
  if first
270
- s_trail << "[#{st.to_s}]"
270
+ trailpfx = ""
271
+ if !st.major_modes.empty?
272
+ mmid = st.major_modes.first
273
+ trailpfx = "#{@modes[mmid].to_s}>"
274
+ end
275
+ s_trail << "[#{trailpfx}#{st.to_s}]"
271
276
  else
272
277
  s_trail << " #{st.to_s}"
273
278
  end
@@ -475,6 +480,7 @@ class KeyBindingTree
475
480
  end
476
481
 
477
482
  def handle_key_bindigs_action(action, c)
483
+ $acth << action
478
484
  $method_handles_repeat = false #TODO:??
479
485
  n = 1
480
486
  if $next_command_count and !(action.class == String and action.include?("set_next_command_count"))
@@ -531,7 +537,7 @@ def exec_action(action)
531
537
  $kbd.last_action = $kbd.cur_action
532
538
  $kbd.cur_action = action
533
539
  if action.class == Symbol
534
- return call(action)
540
+ return call_action(action)
535
541
  elsif action.class == Proc
536
542
  return action.call
537
543
  else
@@ -3,6 +3,8 @@ vma.kbd.add_mode("I", :insert, :insert)
3
3
  vma.kbd.add_mode("V", :visual, :visual)
4
4
  vma.kbd.add_mode("M", :minibuffer) #TODO: needed?
5
5
  vma.kbd.add_mode("R", :readchar)
6
+ # vma.kbd.add_mode("audio", :audio, :command)
7
+ vma.kbd.add_minor_mode("audio", :audio, :command)
6
8
  vma.kbd.add_mode("B", :browse, :command)
7
9
  vma.kbd.add_mode("X", :replace, :command, name: "Replace")
8
10
  vma.kbd.set_default_mode(:command)
@@ -49,6 +51,15 @@ bindkey "C , b", :start_buf_manager
49
51
  bindkey "C , w", :toggle_active_window
50
52
  bindkey "C , , w", :toggle_two_column
51
53
 
54
+ bindkey "C , u s", :audio_stop
55
+ bindkey "C m a", "vma.kbd.set_mode(:audio)"
56
+ bindkey "audio s", :audio_stop
57
+ bindkey "audio space", :audio_stop
58
+ bindkey "audio q || audio esc", "vma.kbd.set_mode_to_default"
59
+
60
+
61
+
62
+
52
63
  # bindkey "C , f o", :open_file_dialog
53
64
  bindkey "CI ctrl-o", :open_file_dialog
54
65
  # bindkey "M enter", :minibuffer_end
@@ -63,7 +74,7 @@ bindkey "C z ", :start_browse_mode
63
74
  bindkey "B h", :history_switch_backwards
64
75
  bindkey "B l", :history_switch_forwards
65
76
  #bindkey 'B z', :center_on_current_line
66
- bindkey "B z", "center_on_current_line();call(:exit_browse_mode)"
77
+ bindkey "B z", "center_on_current_line();call_action(:exit_browse_mode)"
67
78
  bindkey "B enter || B return || B esc || B j || B ctrl!", :exit_browse_mode
68
79
  bindkey "B s", :page_up
69
80
  bindkey "B d", :page_down
@@ -162,6 +173,7 @@ default_keys = {
162
173
  "C , d b" => "debug_print_buffer",
163
174
  "C , d c" => "debug_dump_clipboard",
164
175
  "C , d d" => "debug_dump_deltas",
176
+
165
177
  "VC O" => "buf.jump(END_OF_LINE)",
166
178
  "VC $" => "buf.jump(END_OF_LINE)",
167
179
 
@@ -197,6 +209,7 @@ default_keys = {
197
209
  "C d $" => "buf.delete2(:to_line_end)",
198
210
  # 'C d e'=> 'buf.delete_to_next_word_end',
199
211
  "C d <num> e" => "delete_next_word",
212
+ "C d ' <char>" => "buf.delete2(:to_mark,<char>)",
200
213
  "C r <char>" => "buf.replace_with_char(<char>)", # TODO
201
214
  "C , l b" => "load_buffer_list",
202
215
  "C , l l" => "save_buffer_list",
data/lib/vimamsa/main.rb CHANGED
@@ -49,18 +49,11 @@ end
49
49
 
50
50
  require "vimamsa/editor.rb"
51
51
 
52
- # load "gui_funcs.rb"
53
-
54
52
  $vma = Editor.new
55
53
  def vma()
56
54
  return $vma
57
55
  end
58
56
 
59
- # c_startup
60
- # run_random_jump_test
61
- # main_loop
62
-
63
- # debug("END")
64
57
 
65
58
 
66
59
 
data/lib/vimamsa/rbvma.rb CHANGED
@@ -48,12 +48,6 @@ require "vimamsa/conf"
48
48
  # load "vendor/ver/lib/ver/syntax/detector.rb"
49
49
  # load "vendor/ver/config/detect.rb"
50
50
 
51
- $vma = Editor.new
52
-
53
- def vma()
54
- return $vma
55
- end
56
-
57
51
  def unimplemented
58
52
  debug "unimplemented"
59
53
  end
@@ -68,6 +68,24 @@ def gui_grep()
68
68
  gui_one_input_action("Grep", "Search:", "grep", callback)
69
69
  end
70
70
 
71
+ def highlight_match(bf, str, color: "#aa0000ff")
72
+ vbuf = bf.view.buffer
73
+ r = Regexp.new(Regexp.escape(str), Regexp::IGNORECASE)
74
+
75
+ hlparts = []
76
+
77
+ tt = vma.gui.view.buffer.create_tag("highlight_match_tag")
78
+ tt.weight = 650
79
+ tt.foreground = color
80
+
81
+ ind = scan_indexes(bf, r)
82
+ ind.each { |x|
83
+ itr = vbuf.get_iter_at(:offset => x)
84
+ itr2 = vbuf.get_iter_at(:offset => x + str.size)
85
+ vbuf.apply_tag(tt, itr, itr2)
86
+ }
87
+ end
88
+
71
89
  def grep_cur_buffer(search_str, b = nil)
72
90
  debug "grep_cur_buffer(search_str)"
73
91
  lines = vma.buf.split("\n")
@@ -76,18 +94,21 @@ def grep_cur_buffer(search_str, b = nil)
76
94
  fpath = vma.buf.pathname.expand_path.to_s + ":" if vma.buf.pathname
77
95
  res_str = ""
78
96
 
97
+ hlparts = []
79
98
  $grep_matches = []
80
99
  lines.each_with_index { |l, i|
81
100
  if r.match(l)
82
- # res_str << "#{fpath}#{i + 1}:#{l}\n"
83
- res_str << "#{i + 1}:#{l}\n"
101
+ res_str << "#{i + 1}:"
102
+ # ind = scan_indexes(l, r)
103
+ res_str << "#{l}\n"
84
104
  $grep_matches << i + 1 # Lines start from index 1
85
105
  end
86
106
  }
87
107
  $grep_bufid = vma.buffers.current_buf
88
- b = create_new_file(nil, res_str)
89
- # set_current_buffer(buffer_i, update_history = true)
90
- # @current_buf = buffer_i
108
+ b = create_new_buffer(res_str, "grep")
109
+ vbuf = vma.gui.view.buffer
110
+
111
+ highlight_match(b, search_str, color: "#10bd8e")
91
112
 
92
113
  b.line_action_handler = proc { |lineno|
93
114
  debug "GREP HANDLER:#{lineno}"
@@ -99,10 +120,6 @@ def grep_cur_buffer(search_str, b = nil)
99
120
  }
100
121
  end
101
122
 
102
- # def invoke_grep_search()
103
- # start_minibuffer_cmd("", "", :grep_cur_buffer)
104
- # end
105
-
106
123
  def gui_one_input_action(title, field_label, button_title, callback, opt = {})
107
124
  a = OneInputAction.new(nil, title, field_label, button_title, callback, opt)
108
125
  a.run
@@ -188,6 +205,13 @@ module Gtk
188
205
  end
189
206
  end
190
207
 
208
+ def set_margin_all(widget, m)
209
+ widget.margin_bottom = m
210
+ widget.margin_top = m
211
+ widget.margin_end = m
212
+ widget.margin_start = m
213
+ end
214
+
191
215
  class OneInputAction
192
216
  def initialize(main_window, title, field_label, button_title, callback, opt = {})
193
217
  @window = Gtk::Window.new()
data/lib/vimamsa/util.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require "open3"
2
+
3
+
1
4
  # Run idle proc once
2
- # Delay execution of proc until Gtk has fully processed the last calls.
5
+ # Delay execution of proc until Gtk has fully processed the last calls.
3
6
  def run_as_idle(p)
4
7
  if p.class == Proc
5
8
  Thread.new {
@@ -8,6 +11,48 @@ def run_as_idle(p)
8
11
  end
9
12
  end
10
13
 
14
+ def open_url(url)
15
+ system("xdg-open", url)
16
+ end
17
+
18
+ def open_with_default_program(url)
19
+ system("xdg-open", url)
20
+ end
21
+
22
+ def run_cmd(cmd)
23
+ tmpf = Tempfile.new("vmarun", "/tmp").path
24
+ cmd = "#{cmd} > #{tmpf}"
25
+ debug "CMD:\n#{cmd}"
26
+ system("bash", "-c", cmd)
27
+ res_str = File.read(tmpf)
28
+ return res_str
29
+ end
30
+
31
+ def exec_cmd(bin_name, arg1 = nil, arg2 = nil, arg3 = nil, arg4 = nil, arg5 = nil)
32
+ assert_binary_exists(bin_name)
33
+ if !arg5.nil?
34
+ p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4, arg5)
35
+ elsif !arg4.nil?
36
+ p = Open3.popen2(bin_name, arg1, arg2, arg3, arg4)
37
+ elsif !arg3.nil?
38
+ p = Open3.popen2(bin_name, arg1, arg2, arg3)
39
+ elsif !arg2.nil?
40
+ p = Open3.popen2(bin_name, arg1, arg2)
41
+ elsif !arg1.nil?
42
+ p = Open3.popen2(bin_name, arg1)
43
+ else
44
+ p = Open3.popen2(bin_name)
45
+ end
46
+
47
+ ret_str = p[1].read
48
+ return ret_str
49
+ end
50
+
51
+ def mkdir_if_not_exists(_dirpath)
52
+ dirpath = File.expand_path(_dirpath)
53
+ Dir.mkdir(dirpath) unless File.exist?(dirpath)
54
+ end
55
+
11
56
  class HSafe
12
57
  def initialize(hash)
13
58
  @h = hash
@@ -139,6 +184,16 @@ def read_file(text, path)
139
184
  return content
140
185
  end
141
186
 
187
+ def sanitize_input(str)
188
+ if str.encoding != Encoding::UTF_8
189
+ str = text.encode(Encoding::UTF_8)
190
+ end
191
+ str.gsub!(/\r\n/, "\n")
192
+ return str
193
+ end
194
+
195
+
196
+
142
197
  def is_url(s)
143
198
  return s.match(/(https?|file):\/\/.*/) != nil
144
199
  end
@@ -1,3 +1,3 @@
1
1
  module Vimamsa
2
- VERSION = "0.1.12"
2
+ VERSION = "0.1.13"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vimamsa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sami Sieranoja
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-24 00:00:00.000000000 Z
11
+ date: 2023-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -190,6 +190,7 @@ files:
190
190
  - lib/vimamsa.rb
191
191
  - lib/vimamsa/ack.rb
192
192
  - lib/vimamsa/actions.rb
193
+ - lib/vimamsa/audio.rb
193
194
  - lib/vimamsa/buffer.rb
194
195
  - lib/vimamsa/buffer_list.rb
195
196
  - lib/vimamsa/buffer_manager.rb