vimamsa 0.1.16 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/vimamsa/ack.rb +91 -13
- data/lib/vimamsa/actions.rb +99 -84
- data/lib/vimamsa/buffer.rb +34 -44
- data/lib/vimamsa/buffer_changetext.rb +20 -5
- data/lib/vimamsa/buffer_list.rb +7 -0
- data/lib/vimamsa/buffer_manager.rb +1 -1
- data/lib/vimamsa/conf.rb +3 -0
- data/lib/vimamsa/editor.rb +26 -13
- data/lib/vimamsa/encrypt.rb +38 -1
- data/lib/vimamsa/file_history.rb +3 -3
- data/lib/vimamsa/file_manager.rb +1 -1
- data/lib/vimamsa/gui.rb +75 -30
- data/lib/vimamsa/gui_select_window.rb +2 -0
- data/lib/vimamsa/gui_sourceview.rb +91 -57
- data/lib/vimamsa/gui_sourceview_autocomplete.rb +3 -1
- data/lib/vimamsa/hyper_plain_text.rb +4 -3
- data/lib/vimamsa/key_actions.rb +1 -1
- data/lib/vimamsa/key_binding_tree.rb +5 -6
- data/lib/vimamsa/key_bindings_vimlike.rb +55 -18
- data/lib/vimamsa/langservp.rb +3 -1
- data/lib/vimamsa/macro.rb +4 -1
- data/lib/vimamsa/rbvma.rb +2 -2
- data/lib/vimamsa/tests.rb +6 -9
- data/lib/vimamsa/util.rb +56 -14
- data/lib/vimamsa/version.rb +1 -1
- data/vimamsa.gemspec +4 -4
- metadata +27 -27
data/lib/vimamsa/editor.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require "pty"
|
2
2
|
|
3
|
-
def handle_drag_and_drop(fname)
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
3
|
+
# def handle_drag_and_drop(fname)
|
4
|
+
# debug "EDITOR:handle_drag_and_drop"
|
5
|
+
# buf.handle_drag_and_drop(fname)
|
6
|
+
# end
|
8
7
|
|
9
8
|
class Editor
|
10
|
-
attr_reader :file_content_search_paths, :file_name_search_paths, :gui, :hook, :macro
|
9
|
+
attr_reader :file_content_search_paths, :file_name_search_paths, :gui, :hook, :macro, :actions
|
11
10
|
attr_accessor :converters, :fh, :paint_stack, :kbd, :langsrv, :register, :cur_register, :clipboard
|
12
11
|
#attr_writer :call_func, :update_highlight
|
13
12
|
|
@@ -63,6 +62,10 @@ class Editor
|
|
63
62
|
|
64
63
|
$hook = Hook.new
|
65
64
|
@hook = $hook
|
65
|
+
require "vimamsa/actions"
|
66
|
+
@actions = ActionList.new
|
67
|
+
require "vimamsa/key_actions"
|
68
|
+
|
66
69
|
register_plugin(:Hook, @hook)
|
67
70
|
@macro = Macro.new
|
68
71
|
register_plugin(:Macro, @macro)
|
@@ -126,9 +129,12 @@ class Editor
|
|
126
129
|
FileManager.init
|
127
130
|
Autocomplete.init
|
128
131
|
|
132
|
+
if cnf.audio.enabled?
|
133
|
+
require "vimamsa/audio"
|
134
|
+
end
|
135
|
+
|
129
136
|
if cnf.lsp.enabled?
|
130
137
|
require "vimamsa/langservp"
|
131
|
-
require "vimamsa/audio" # TODO:config
|
132
138
|
@langsrv["ruby"] = LangSrv.new("ruby")
|
133
139
|
@langsrv["cpp"] = LangSrv.new("cpp")
|
134
140
|
end
|
@@ -548,12 +554,14 @@ def load_buffer(fname)
|
|
548
554
|
end
|
549
555
|
|
550
556
|
def jump_to_file(filename, tnum = nil, charn = nil)
|
551
|
-
open_new_file(filename)
|
557
|
+
b = open_new_file(filename)
|
558
|
+
return if b.nil?
|
559
|
+
# debug "open_new_file #{filename}, #{tnum} = nil, #{charn}",2
|
552
560
|
|
553
561
|
# Link to character position
|
554
562
|
if !charn.nil?
|
555
563
|
if charn == "c"
|
556
|
-
|
564
|
+
b.jump_to_pos(tnum) # tnum=character position
|
557
565
|
center_on_current_line
|
558
566
|
return
|
559
567
|
end
|
@@ -561,7 +569,7 @@ def jump_to_file(filename, tnum = nil, charn = nil)
|
|
561
569
|
|
562
570
|
# Link to line
|
563
571
|
if !tnum.nil?
|
564
|
-
|
572
|
+
b.jump_to_line(tnum) # tnum=line position
|
565
573
|
center_on_current_line
|
566
574
|
return
|
567
575
|
end
|
@@ -579,7 +587,7 @@ def open_new_file(filename, file_contents = "")
|
|
579
587
|
# File is already opened to existing buffer
|
580
588
|
if b != nil
|
581
589
|
message "Switching to: #{filename}"
|
582
|
-
vma.buffers.set_current_buffer(b)
|
590
|
+
bu = vma.buffers.set_current_buffer(b)
|
583
591
|
else
|
584
592
|
if !is_path_writable(filename)
|
585
593
|
message("Path #{filename} cannot be written to")
|
@@ -591,11 +599,16 @@ def open_new_file(filename, file_contents = "")
|
|
591
599
|
message("File #{filename} does not contain text")
|
592
600
|
return false
|
593
601
|
end
|
602
|
+
if Encrypt.is_encrypted?(filename)
|
603
|
+
decrypt_dialog(filename: filename)
|
604
|
+
return nil
|
605
|
+
end
|
594
606
|
message "New file opened: #{filename}"
|
595
607
|
fname = filename
|
596
|
-
|
597
|
-
vma.buffers.set_current_buffer_by_id(
|
608
|
+
bu = load_buffer(fname)
|
609
|
+
vma.buffers.set_current_buffer_by_id(bu.id)
|
598
610
|
end
|
611
|
+
return bu
|
599
612
|
end
|
600
613
|
|
601
614
|
def scan_word_start_marks(search_str)
|
data/lib/vimamsa/encrypt.rb
CHANGED
@@ -1,6 +1,44 @@
|
|
1
1
|
require "openssl"
|
2
2
|
|
3
|
+
def decrypt_dialog(filename:, wrong_pass: false)
|
4
|
+
callback = proc { |x| Encrypt.open(filename, x) }
|
5
|
+
msg = ""
|
6
|
+
msg = "\nWRONG PASSWORD!\n" if wrong_pass
|
7
|
+
gui_one_input_action("Decrypt file \n #{filename}\n#{msg}", "Password:", "Decrypt", callback, { :hide => true })
|
8
|
+
end
|
9
|
+
|
3
10
|
class Encrypt
|
11
|
+
def self.is_encrypted?(fn)
|
12
|
+
debug "self.is_encrypted?(fn)", 2
|
13
|
+
begin
|
14
|
+
file = File.open(fn, "r")
|
15
|
+
first_11_characters = file.read(11)
|
16
|
+
return true if first_11_characters == "VMACRYPT001"
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
puts "File not found: #{file_path}"
|
19
|
+
rescue => e
|
20
|
+
puts "An error occurred: #{e.message}"
|
21
|
+
ensure
|
22
|
+
file&.close
|
23
|
+
end
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.open(fn, password)
|
28
|
+
debug "open_encrypted(filename,password)", 2
|
29
|
+
encrypted = read_file("", fn)[11..-1]
|
30
|
+
begin
|
31
|
+
crypt = Encrypt.new(password)
|
32
|
+
str = crypt.decrypt(encrypted)
|
33
|
+
# debug "PASS OK!", 2
|
34
|
+
bu = create_new_buffer(str)
|
35
|
+
bu.init_encrypted(crypt: crypt, filename: fn, encrypted: encrypted)
|
36
|
+
rescue OpenSSL::Cipher::CipherError => e
|
37
|
+
# Wrong password
|
38
|
+
decrypt_dialog(filename: fn, wrong_pass: true)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
4
42
|
def initialize(pass_phrase)
|
5
43
|
salt = "uvgixEtU"
|
6
44
|
@enc = OpenSSL::Cipher.new "AES-128-CBC"
|
@@ -31,7 +69,6 @@ class Encrypt
|
|
31
69
|
end
|
32
70
|
end
|
33
71
|
|
34
|
-
|
35
72
|
def encrypt_cur_buffer()
|
36
73
|
callback = proc { |x| encrypt_cur_buffer_callback(x) }
|
37
74
|
gui_one_input_action("Encrypt", "Password:", "Encrypt", callback, { :hide => true })
|
data/lib/vimamsa/file_history.rb
CHANGED
@@ -76,12 +76,12 @@ end
|
|
76
76
|
|
77
77
|
def gui_file_history_update_callback(search_str = "")
|
78
78
|
debug "gui_file_history_update_callback: #{search_str}"
|
79
|
-
return [] if
|
79
|
+
return [] if vma.fh.history.empty?
|
80
80
|
$search_list = []
|
81
|
-
files =
|
81
|
+
files = vma.fh.history.keys.sort.collect { |x| [x, 0] }
|
82
82
|
|
83
83
|
if (search_str.size > 1)
|
84
|
-
files = fuzzy_filter(search_str,
|
84
|
+
files = fuzzy_filter(search_str, vma.fh.history.keys, 40)
|
85
85
|
end
|
86
86
|
|
87
87
|
$search_list = files
|
data/lib/vimamsa/file_manager.rb
CHANGED
data/lib/vimamsa/gui.rb
CHANGED
@@ -2,6 +2,42 @@ $idle_scroll_to_mark = false
|
|
2
2
|
|
3
3
|
$removed_controllers = []
|
4
4
|
|
5
|
+
# Run one iteration of GMainLoop
|
6
|
+
# https://developer.gnome.org/documentation/tutorials/main-contexts.html
|
7
|
+
def iterate_gui_main_loop
|
8
|
+
GLib::MainContext.default.iteration(true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_profiler
|
12
|
+
require "ruby-prof"
|
13
|
+
RubyProf.start
|
14
|
+
end
|
15
|
+
|
16
|
+
def end_profiler
|
17
|
+
result = RubyProf.stop
|
18
|
+
printer = RubyProf::FlatPrinter.new(result)
|
19
|
+
printer.print(STDOUT)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Wait for window resize to take effect
|
23
|
+
# GTk3 had a resize notify event which got removed in gtk4
|
24
|
+
# https://discourse.gnome.org/t/gtk4-any-way-to-connect-to-a-window-resize-signal/14869/3
|
25
|
+
def wait_for_resize(window, tries = 200)
|
26
|
+
i = 0
|
27
|
+
widthold = @window.width
|
28
|
+
heightold = @window.height
|
29
|
+
while true
|
30
|
+
iterate_gui_main_loop
|
31
|
+
break if widthold != window.width
|
32
|
+
break if heightold != window.height
|
33
|
+
if i >= tries
|
34
|
+
debug "i >= tries", 2
|
35
|
+
break
|
36
|
+
end
|
37
|
+
i += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
5
41
|
def gui_remove_controllers(widget)
|
6
42
|
clist = widget.observe_controllers
|
7
43
|
to_remove = []
|
@@ -102,7 +138,7 @@ def gui_create_buffer(id, bufo)
|
|
102
138
|
view.set_buffer(buf1)
|
103
139
|
|
104
140
|
provider = Gtk::CssProvider.new
|
105
|
-
|
141
|
+
|
106
142
|
provider.load(data: "textview { font-family: #{cnf.font.family!}; font-size: #{cnf.font.size!}pt; }")
|
107
143
|
view.style_context.add_provider(provider)
|
108
144
|
view.wrap_mode = :char
|
@@ -168,21 +204,6 @@ class VMAgui
|
|
168
204
|
@img_resizer_active = false
|
169
205
|
@windows = {}
|
170
206
|
@app = nil
|
171
|
-
# imgproc = proc {
|
172
|
-
# GLib::Idle.add(proc {
|
173
|
-
# if !buf.images.empty?
|
174
|
-
# vma.gui.scale_all_images
|
175
|
-
|
176
|
-
# w = Gtk::Window.new(:toplevel)
|
177
|
-
# w.set_default_size(1, 1)
|
178
|
-
# w.show_all
|
179
|
-
# Thread.new { sleep 0.1; w.destroy }
|
180
|
-
# end
|
181
|
-
|
182
|
-
# false
|
183
|
-
# })
|
184
|
-
# }
|
185
|
-
# @delex = DelayExecutioner.new(1, imgproc)
|
186
207
|
end
|
187
208
|
|
188
209
|
def run
|
@@ -200,16 +221,13 @@ class VMAgui
|
|
200
221
|
end
|
201
222
|
end
|
202
223
|
|
203
|
-
def delay_scale()
|
204
|
-
if Time.now - @dtime > 2.0
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
224
|
def scale_all_images
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
img[:obj].
|
225
|
+
for k, window in @windows
|
226
|
+
bu = window[:sw].child.bufo
|
227
|
+
for img in bu.images
|
228
|
+
if !img[:obj].destroyed?
|
229
|
+
img[:obj].scale_image
|
230
|
+
end
|
213
231
|
end
|
214
232
|
end
|
215
233
|
false
|
@@ -549,11 +567,24 @@ class VMAgui
|
|
549
567
|
|
550
568
|
def idle_set_size()
|
551
569
|
# Need to wait for a while to window to be maximized to get correct @window.width
|
552
|
-
|
570
|
+
@window.maximize
|
571
|
+
wait_for_resize(@window)
|
572
|
+
# Set new size as half of the screeen
|
553
573
|
width = @window.width / 2
|
554
574
|
height = @window.height - 5
|
575
|
+
width = 600 if width < 600
|
576
|
+
height = 600 if height < 600
|
577
|
+
|
578
|
+
#Minimum size:
|
579
|
+
@window.set_size_request(600, 600)
|
580
|
+
@window.set_default_size(width, height)
|
581
|
+
debug "size #{[width, height]}", 2
|
555
582
|
@window.unmaximize
|
583
|
+
|
584
|
+
#set_default_size doesn't always have effect if run immediately
|
585
|
+
wait_for_resize(@window)
|
556
586
|
@window.set_default_size(width, height)
|
587
|
+
|
557
588
|
return false
|
558
589
|
end
|
559
590
|
|
@@ -569,10 +600,6 @@ class VMAgui
|
|
569
600
|
@window = Gtk::ApplicationWindow.new(app)
|
570
601
|
@window.set_application(app)
|
571
602
|
|
572
|
-
@window.maximize
|
573
|
-
# Need to let Gtk process after maximize
|
574
|
-
run_as_idle proc { idle_set_size }
|
575
|
-
|
576
603
|
@window.title = "Multiple Views"
|
577
604
|
@vpaned = Gtk::Paned.new(:vertical)
|
578
605
|
|
@@ -664,6 +691,8 @@ class VMAgui
|
|
664
691
|
|
665
692
|
@window.show
|
666
693
|
|
694
|
+
run_as_idle proc { idle_set_size }
|
695
|
+
|
667
696
|
prov = Gtk::CssProvider.new
|
668
697
|
# See gtk-4.9.4/gtk/theme/Default/_common.scss on how to theme
|
669
698
|
# gtksourceview/gtksourcestyleschemepreview.c
|
@@ -699,12 +728,28 @@ class VMAgui
|
|
699
728
|
end
|
700
729
|
|
701
730
|
# Vimamsa::Menu.new(@menubar) #TODO:gtk4
|
731
|
+
GLib::Idle.add(proc { self.monitor })
|
732
|
+
|
702
733
|
app.run
|
703
734
|
|
704
735
|
# @window.show_all
|
705
736
|
# @window.show
|
706
737
|
end
|
707
738
|
|
739
|
+
def monitor
|
740
|
+
@monitor_time ||= Time.now
|
741
|
+
@sw_width ||= @sw.width
|
742
|
+
return true if Time.now - @monitor_time < 0.2
|
743
|
+
# Detect element resize
|
744
|
+
if @sw.width != @sw_width
|
745
|
+
# puts "@sw.width=#{@sw.width}"
|
746
|
+
@sw_width = @sw.width
|
747
|
+
DelayExecutioner.exec(id: :scale_images, wait: 0.7, callable: proc { vma.gui.scale_all_images })
|
748
|
+
end
|
749
|
+
@monitor_time = Time.now
|
750
|
+
return true
|
751
|
+
end
|
752
|
+
|
708
753
|
def init_menu
|
709
754
|
Vimamsa::Menu.new(@menubar, @app)
|
710
755
|
end
|
@@ -52,9 +52,9 @@ class VSourceView < GtkSource::View
|
|
52
52
|
|
53
53
|
# Mainly after page-up or page-down
|
54
54
|
signal_connect("move-cursor") do |widget, event|
|
55
|
-
if event.name == "GTK_MOVEMENT_PAGES" and (last_action == "page_up" or last_action == "page_down")
|
56
|
-
|
57
|
-
end
|
55
|
+
# if event.name == "GTK_MOVEMENT_PAGES" and (vma.actions.last_action == "page_up" or vma.actions.last_action == "page_down")
|
56
|
+
# handle_scrolling()
|
57
|
+
# end
|
58
58
|
|
59
59
|
# handle_scrolling()
|
60
60
|
# curpos = buffer.cursor_position
|
@@ -79,7 +79,6 @@ class VSourceView < GtkSource::View
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def set_content(str)
|
82
|
-
delete_cursorchar
|
83
82
|
self.buffer.set_text(str)
|
84
83
|
end
|
85
84
|
|
@@ -123,6 +122,52 @@ class VSourceView < GtkSource::View
|
|
123
122
|
def register_signals()
|
124
123
|
check_controllers
|
125
124
|
|
125
|
+
# TODO: accept GLib::Type::STRING also?
|
126
|
+
@dt = Gtk::DropTarget.new(GLib::Type["GFile"], [Gdk::DragAction::COPY, Gdk::DragAction::MOVE])
|
127
|
+
# GLib::Type::INVALID
|
128
|
+
|
129
|
+
self.add_controller(@dt)
|
130
|
+
@dt.signal_connect "drop" do |obj, v, x, y|
|
131
|
+
if v.value.gtype == GLib::Type["GLocalFile"]
|
132
|
+
uri = v.value.uri
|
133
|
+
elsif v.value.class == String
|
134
|
+
uri = v.value.gsub(/\r\n$/, "")
|
135
|
+
end
|
136
|
+
debug "dt,drop #{v.value},#{x},#{y}", 2
|
137
|
+
begin
|
138
|
+
fp = URI(uri).path
|
139
|
+
buf.handle_drag_and_drop(fp)
|
140
|
+
rescue URI::InvalidURIError
|
141
|
+
end
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
@dt.signal_connect "enter" do |gesture, x, y, z, m|
|
146
|
+
debug "dt,enter", 2
|
147
|
+
Gdk::DragAction::COPY
|
148
|
+
end
|
149
|
+
|
150
|
+
@dt.signal_connect "motion" do |obj, x, y|
|
151
|
+
debug "dt,move", 2
|
152
|
+
|
153
|
+
Gdk::DragAction::COPY
|
154
|
+
end
|
155
|
+
|
156
|
+
# dc = Gtk::DropControllerMotion.new
|
157
|
+
# self.add_controller(dc)
|
158
|
+
# dc.signal_connect "enter" do |gesture, x, y|
|
159
|
+
# debug "enter", 2
|
160
|
+
# debug [x, y]
|
161
|
+
# # Ripl.start :binding => binding
|
162
|
+
# true
|
163
|
+
# end
|
164
|
+
|
165
|
+
# dc.signal_connect "motion" do |gesture, x, y|
|
166
|
+
# debug "move", 2
|
167
|
+
# debug [x, y]
|
168
|
+
# true
|
169
|
+
# end
|
170
|
+
|
126
171
|
# Implement mouse selections using @cnt_mo and @cnt_drag
|
127
172
|
@cnt_mo = Gtk::EventControllerMotion.new
|
128
173
|
self.add_controller(@cnt_mo)
|
@@ -149,10 +194,13 @@ class VSourceView < GtkSource::View
|
|
149
194
|
debug "drag-end", 2
|
150
195
|
if offsetx.abs < 5 and offsety.abs < 5
|
151
196
|
debug "Not enough drag", 2
|
152
|
-
|
153
|
-
|
197
|
+
buf.end_selection
|
198
|
+
# elsif !buf.visual_mode? and vma.kbd.get_scope != :editor
|
199
|
+
elsif vma.kbd.get_scope != :editor
|
154
200
|
# Can't transition from editor wide mode to buffer specific mode
|
155
|
-
|
201
|
+
vma.kbd.set_mode(:visual)
|
202
|
+
else
|
203
|
+
buf.end_selection
|
156
204
|
end
|
157
205
|
@range_start = nil
|
158
206
|
end
|
@@ -233,14 +281,12 @@ class VSourceView < GtkSource::View
|
|
233
281
|
|
234
282
|
def handle_scrolling()
|
235
283
|
return # TODO
|
236
|
-
delete_cursorchar
|
237
284
|
# curpos = buffer.cursor_position
|
238
285
|
# debug "MOVE CURSOR: #{curpos}"
|
239
286
|
return nil if vma.gui.nil?
|
240
287
|
return nil if @bufo.nil?
|
241
288
|
vma.gui.run_after_scrolling proc {
|
242
289
|
debug "START UPDATE POS AFTER SCROLLING", 2
|
243
|
-
delete_cursorchar
|
244
290
|
bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
|
245
291
|
if !bc.nil?
|
246
292
|
i = coord_to_iter(bc[0], bc[1])
|
@@ -254,7 +300,6 @@ class VSourceView < GtkSource::View
|
|
254
300
|
|
255
301
|
def set_cursor_to_top
|
256
302
|
debug "set_cursor_to_top", 2
|
257
|
-
delete_cursorchar
|
258
303
|
bc = window_to_buffer_coords(Gtk::TextWindowType::WIDGET, gutter_width + 2, 60)
|
259
304
|
if !bc.nil?
|
260
305
|
i = coord_to_iter(bc[0], bc[1])
|
@@ -267,7 +312,6 @@ class VSourceView < GtkSource::View
|
|
267
312
|
|
268
313
|
# def handle_key_event(event, sig)
|
269
314
|
def handle_key_event(keyval, keyname, sig)
|
270
|
-
delete_cursorchar
|
271
315
|
if $update_cursor
|
272
316
|
handle_scrolling
|
273
317
|
end
|
@@ -391,7 +435,6 @@ class VSourceView < GtkSource::View
|
|
391
435
|
end
|
392
436
|
|
393
437
|
def handle_deltas()
|
394
|
-
delete_cursorchar
|
395
438
|
any_change = false
|
396
439
|
while d = @bufo.deltas.shift
|
397
440
|
any_change = true
|
@@ -432,7 +475,6 @@ class VSourceView < GtkSource::View
|
|
432
475
|
end
|
433
476
|
|
434
477
|
def set_cursor_pos(pos)
|
435
|
-
delete_cursorchar
|
436
478
|
itr = buffer.get_iter_at(:offset => pos)
|
437
479
|
itr2 = buffer.get_iter_at(:offset => pos + 1)
|
438
480
|
buffer.place_cursor(itr)
|
@@ -451,7 +493,7 @@ class VSourceView < GtkSource::View
|
|
451
493
|
$idle_scroll_to_mark = true
|
452
494
|
ensure_cursor_visible
|
453
495
|
|
454
|
-
draw_cursor
|
496
|
+
# draw_cursor
|
455
497
|
|
456
498
|
return true
|
457
499
|
end
|
@@ -513,14 +555,12 @@ class VSourceView < GtkSource::View
|
|
513
555
|
end
|
514
556
|
end
|
515
557
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
@cursorchar = nil
|
523
|
-
end
|
558
|
+
def after_action
|
559
|
+
iterate_gui_main_loop
|
560
|
+
handle_deltas
|
561
|
+
iterate_gui_main_loop
|
562
|
+
draw_cursor
|
563
|
+
iterate_gui_main_loop
|
524
564
|
end
|
525
565
|
|
526
566
|
def set_cursor_color(ctype)
|
@@ -531,7 +571,8 @@ class VSourceView < GtkSource::View
|
|
531
571
|
self.style_context.remove_provider(@cursor_prov)
|
532
572
|
end
|
533
573
|
prov = Gtk::CssProvider.new
|
534
|
-
prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; }")
|
574
|
+
# prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; }")
|
575
|
+
prov.load(data: ".view text selection { background-color: #{bg}; color: #ffffff; } .view { caret-color: #{bg}; }")
|
535
576
|
self.style_context.add_provider(prov)
|
536
577
|
@cursor_prov = prov
|
537
578
|
end
|
@@ -545,38 +586,28 @@ class VSourceView < GtkSource::View
|
|
545
586
|
# @tt.font = "Arial"
|
546
587
|
# end
|
547
588
|
|
589
|
+
sv = vma.gui.sw.child
|
548
590
|
mode = vma.kbd.get_mode
|
549
591
|
ctype = vma.kbd.get_cursor_type
|
550
|
-
|
592
|
+
ctype = :visual if vma.buf.selection_active?
|
593
|
+
|
551
594
|
vma.gui.remove_overlay_cursor
|
552
595
|
if [:command, :replace, :browse].include?(ctype)
|
553
596
|
set_cursor_color(ctype)
|
554
|
-
if @bufo[@bufo.pos] == "\n"
|
555
|
-
# If we are at end of line, it's not possible to draw the cursor by making a selection. I tried to do this by drawing an overlay, but that generates issues. If moving the cursor causes the ScrolledWindow to be scrolled, these errors randomly appear and the whole view shows blank:
|
556
|
-
# (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
|
557
|
-
# (ruby:21016): Gtk-WARNING **: 19:52:23.181: Trying to snapshot GtkGizmo 0x55a9727d2580 without a current allocation
|
558
|
-
# (ruby:21016): Gtk-WARNING **: 19:52:23.243: Trying to snapshot GtkSourceView 0x55a97524c8c0 without a current allocation
|
559
|
-
# vma.gui.overlay_draw_cursor(@bufo.pos)
|
560
|
-
|
561
|
-
# Current workaround is to add an empty space to the place where the cursor is and then remove this whenever we get any kind of event that might cause this class to be accessed.
|
562
|
-
itr = buffer.get_iter_at(:offset => @bufo.pos)
|
563
|
-
buffer.insert(itr, " ") # normal space
|
564
|
-
# buffer.insert(itr, " ") # thin space (U+2009)
|
565
|
-
# buffer.insert(itr, "l")
|
566
|
-
@cursorchar = @bufo.pos
|
567
|
-
|
568
|
-
# Apparently we need to redo this after buffer.insert:
|
569
|
-
itr = buffer.get_iter_at(:offset => @bufo.pos)
|
570
|
-
itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
|
571
|
-
# buffer.apply_tag(@tt, itr, itr2)
|
572
|
-
buffer.select_range(itr, itr2)
|
573
|
-
else
|
574
|
-
itr = buffer.get_iter_at(:offset => @bufo.pos)
|
575
|
-
itr2 = buffer.get_iter_at(:offset => @bufo.pos + 1)
|
576
|
-
buffer.select_range(itr, itr2)
|
577
|
-
end
|
578
|
-
# elsif @bufo.visual_mode?
|
579
597
|
|
598
|
+
sv.overwrite = true
|
599
|
+
# sv.cursor_visible = true
|
600
|
+
# sv.reset_cursor_blink
|
601
|
+
|
602
|
+
# (Via trial and error) This combination is needed to make cursor visible:
|
603
|
+
sv.cursor_visible = false
|
604
|
+
sv.cursor_visible = true
|
605
|
+
|
606
|
+
# sv.reset_cursor_blink
|
607
|
+
Gtk::Settings.default.gtk_cursor_blink = false
|
608
|
+
# Gtk::Settings.default.gtk_cursor_blink_time = 8000
|
609
|
+
# vma.gui.sw.child.toggle_cursor_visible
|
610
|
+
# vma.gui.sw.child.cursor_visible = true
|
580
611
|
elsif ctype == :visual
|
581
612
|
set_cursor_color(ctype)
|
582
613
|
# debug "VISUAL MODE"
|
@@ -587,16 +618,19 @@ class VSourceView < GtkSource::View
|
|
587
618
|
# Pango-CRITICAL **: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
|
588
619
|
buffer.select_range(itr, itr2)
|
589
620
|
elsif ctype == :insert
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
# Via trial and error, this combination is only thing that seems to work:
|
595
|
-
vma.gui.sw.child.toggle_cursor_visible
|
596
|
-
vma.gui.sw.child.cursor_visible = true
|
597
|
-
|
621
|
+
set_cursor_color(ctype)
|
622
|
+
sv.overwrite = false
|
623
|
+
# sv.cursor_visible = false
|
624
|
+
# sv.cursor_visible = true
|
598
625
|
debug "INSERT MODE"
|
599
626
|
else # TODO
|
600
627
|
end
|
628
|
+
if [:insert, :command, :replace, :browse].include?(ctype)
|
629
|
+
# Place cursor where it already is
|
630
|
+
# Without this hack, the cursor doesn't always get drawn
|
631
|
+
pos = @bufo.pos
|
632
|
+
itr = buffer.get_iter_at(:offset => pos)
|
633
|
+
buffer.place_cursor(itr)
|
634
|
+
end
|
601
635
|
end
|
602
636
|
end
|
@@ -7,7 +7,7 @@ def hpt_check_cur_word(w)
|
|
7
7
|
dn = File.dirname(vma.buf.fname)
|
8
8
|
|
9
9
|
fcands = []
|
10
|
-
if fpfx[0] != "/"
|
10
|
+
if fpfx[0] != "/" and fpfx[0] != "~"
|
11
11
|
fcands << "#{dn}/#{fpfx}"
|
12
12
|
fcands << "#{dn}/#{fpfx}.txt"
|
13
13
|
end
|
@@ -26,7 +26,7 @@ def hpt_check_cur_word(w)
|
|
26
26
|
if fn
|
27
27
|
if m[2] == "audio"
|
28
28
|
# Thread.new { Audio.play(fn) }
|
29
|
-
Audio.play(fn)
|
29
|
+
Audio.play(fn) if cnf.audio.enabled?
|
30
30
|
else
|
31
31
|
if !file_is_text_file(fn)
|
32
32
|
message "Not text file #{fn}"
|
@@ -52,6 +52,7 @@ def hpt_check_cur_word(w)
|
|
52
52
|
return nil
|
53
53
|
end
|
54
54
|
|
55
|
+
|
55
56
|
def hpt_create_new_file(fn)
|
56
57
|
create_new_file(fn)
|
57
58
|
end
|
@@ -128,7 +129,7 @@ def hpt_scan_images(bf = nil)
|
|
128
129
|
}
|
129
130
|
|
130
131
|
# Need to scale after buffer loaded
|
131
|
-
|
132
|
+
run_as_idle proc { vma.gui.scale_all_images }
|
132
133
|
|
133
134
|
# vma.gui.delex.run #TODO:gtk4
|
134
135
|
end
|
data/lib/vimamsa/key_actions.rb
CHANGED
@@ -166,7 +166,7 @@ act_list = {
|
|
166
166
|
# { :proc => proc { },
|
167
167
|
# :desc => "", :group => : },
|
168
168
|
|
169
|
-
:search_actions => { :proc => proc {
|
169
|
+
:search_actions => { :proc => proc { vma.actions.gui_search },
|
170
170
|
:desc => "Search actions", :group => :search },
|
171
171
|
|
172
172
|
:toggle_active_window => { :proc => proc { vma.gui.toggle_active_window },
|