vimamsa 0.1.12 → 0.1.13

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: 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