vimamsa 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,255 @@
1
+ # Operations that change the content of the buffer
2
+ # e.g. insert, delete
3
+
4
+ class Buffer < String
5
+
6
+ #TODO: change to apply=true as default
7
+ def add_delta(delta, apply = false, auto_update_cpos = false)
8
+ return if !is_delta_ok(delta)
9
+ if delta[1] == DELETE
10
+ return if delta[0] >= self.size
11
+ # If go over length of buffer
12
+ if delta[0] + delta[2] >= self.size
13
+ delta[2] = self.size - delta[0]
14
+ end
15
+ end
16
+
17
+ @edit_version += 1
18
+ @redo_stack = []
19
+ if apply
20
+ delta = run_delta(delta, auto_update_cpos)
21
+ else
22
+ @deltas << delta
23
+ end
24
+ @edit_history << delta
25
+ if self[-1] != "\n"
26
+ add_delta([self.size, INSERT, 1, "\n"], true)
27
+ end
28
+ reset_larger_cpos #TODO: correct here?
29
+ end
30
+
31
+ # TODO: rename ot auto-format. separate module?
32
+ # Indents whole buffer using external program
33
+ def indent()
34
+ file = Tempfile.new("out")
35
+ infile = Tempfile.new("in")
36
+ file.write(self.to_s)
37
+ file.flush
38
+ bufc = "FOO"
39
+
40
+ tmppos = @pos
41
+
42
+ message("Auto format #{@fname}")
43
+
44
+ ftype = get_file_type()
45
+ if ["chdr", "c", "cpp", "cpphdr"].include?(ftype)
46
+
47
+ #C/C++/Java/JavaScript/Objective-C/Protobuf code
48
+ system("clang-format -style='{BasedOnStyle: LLVM, ColumnLimit: 100, SortIncludes: false}' #{file.path} > #{infile.path}")
49
+ bufc = IO.read(infile.path)
50
+ elsif ftype == "Javascript"
51
+ cmd = "clang-format #{file.path} > #{infile.path}'"
52
+ debug cmd
53
+ system(cmd)
54
+ bufc = IO.read(infile.path)
55
+ elsif ftype == "ruby"
56
+ cmd = "rufo #{file.path}"
57
+ debug cmd
58
+ system(cmd)
59
+ bufc = IO.read(file.path)
60
+ else
61
+ message("No auto-format handler for file of type: #{ftype}")
62
+ return
63
+ end
64
+ self.update_content(bufc)
65
+ center_on_current_line #TODO: needed?
66
+ file.close; file.unlink
67
+ infile.close; infile.unlink
68
+ end
69
+
70
+ # Create a new line after current line and insert text on that line
71
+ def put_to_new_next_line(txt)
72
+ l = current_line_range()
73
+ insert_txt_at(txt, l.end + 1)
74
+ set_pos(l.end + 1)
75
+ end
76
+
77
+ # Start asynchronous read of system clipboard
78
+ def paste_start(at, register)
79
+ @clipboard_paste_running = true
80
+ clipboard = vma.gui.window.display.clipboard
81
+ clipboard.read_text_async do |_clipboard, result|
82
+ begin
83
+ text = clipboard.read_text_finish(result)
84
+ rescue Gio::IOError::NotSupported
85
+ # Happens when pasting from KeePassX and clipboard cleared
86
+ debug Gio::IOError::NotSupported
87
+ else
88
+ paste_finish(text, at, register)
89
+ end
90
+ end
91
+ end
92
+
93
+ def paste_finish(text, at, register)
94
+ debug "PASTE: #{text}"
95
+
96
+ # If we did not put this text to clipboard
97
+ if text != vma.clipboard[-1]
98
+ @paste_lines = false
99
+ end
100
+
101
+ text = sanitize_input(text)
102
+
103
+ vma.clipboard << text
104
+
105
+ return if text == ""
106
+
107
+ if @paste_lines
108
+ debug "PASTE LINES"
109
+ put_to_new_next_line(text)
110
+ else
111
+ debug "PASTE !LINES"
112
+ if at_end_of_buffer? or at_end_of_line? or at == BEFORE
113
+ pos = @pos
114
+ else
115
+ pos = @pos + 1
116
+ end
117
+ insert_txt_at(text, pos)
118
+ set_pos(pos + text.size)
119
+ end
120
+ set_pos(@pos)
121
+ @clipboard_paste_running = false
122
+ end
123
+
124
+ def paste(at = AFTER, register = nil)
125
+ # Macro's don't work with asynchronous call using GTK
126
+ # TODO: implement as synchronous?
127
+ # Use internal clipboard
128
+ if vma.macro.running_macro
129
+ text = vma.clipboard.get()
130
+ paste_finish(text, at, register)
131
+ else
132
+ # Get clipboard using GUI
133
+ paste_start(at, register)
134
+ end
135
+ return true
136
+ end
137
+
138
+ def delete2(range_id, mark = nil)
139
+ @paste_lines = false
140
+ range = get_range(range_id, mark: mark)
141
+ return if range == nil
142
+ debug "RANGE"
143
+ debug range.inspect
144
+ debug range.inspect
145
+ debug "------"
146
+ delete_range(range.first, range.last)
147
+ pos = [range.first, @pos].min
148
+ set_pos(pos)
149
+ end
150
+
151
+ def delete(op, x = nil)
152
+ @paste_lines = false
153
+ # Delete selection
154
+ if op == SELECTION && visual_mode?
155
+ (startpos, endpos) = get_visual_mode_range2
156
+ delete_range(startpos, endpos, x)
157
+ @pos = [@pos, @selection_start].min
158
+ end_visual_mode
159
+ #return
160
+
161
+ # Delete current char
162
+ elsif op == CURRENT_CHAR_FORWARD
163
+ return if @pos >= self.size - 1 # May not delete last '\n'
164
+ add_delta([@pos, DELETE, 1], true)
165
+
166
+ # Delete current char and then move backward
167
+ elsif op == CURRENT_CHAR_BACKWARD
168
+ add_delta([@pos, DELETE, 1], true)
169
+ @pos -= 1
170
+
171
+ # Delete the char before current char and move backward
172
+ elsif op == BACKWARD_CHAR and @pos > 0
173
+ add_delta([@pos - 1, DELETE, 1], true)
174
+ @pos -= 1
175
+ elsif op == FORWARD_CHAR #TODO: ok?
176
+ add_delta([@pos + 1, DELETE, 1], true)
177
+ end
178
+ set_pos(@pos)
179
+ #recalc_line_ends
180
+ calculate_line_and_column_pos
181
+ #need_redraw!
182
+ end
183
+
184
+ def delete_range(startpos, endpos, x = nil)
185
+ s = self[startpos..endpos]
186
+ if startpos == endpos or s == ""
187
+ return
188
+ end
189
+ if x == :append
190
+ debug "APPEND"
191
+ s += "\n" + vma.clipboard.get()
192
+ end
193
+ vma.clipboard.set(s)
194
+ add_delta([startpos, DELETE, (endpos - startpos + 1)], true)
195
+ #recalc_line_ends
196
+ calculate_line_and_column_pos
197
+ end
198
+
199
+ def is_delta_ok(delta)
200
+ ret = true
201
+ pos = delta[0]
202
+ if pos < 0
203
+ ret = false
204
+ debug "pos=#{pos} < 0"
205
+ elsif pos > self.size
206
+ debug "pos=#{pos} > self.size=#{self.size}"
207
+ ret = false
208
+ end
209
+ if ret == false
210
+ # crash("DELTA OK=#{ret}")
211
+ end
212
+ return ret
213
+ end
214
+
215
+ def delete_line()
216
+ vma.kbd.method_handles_repeat = true
217
+ num_lines = 1
218
+ if !vma.kbd.next_command_count.nil? and vma.kbd.next_command_count > 0
219
+ num_lines = vma.kbd.next_command_count
220
+ debug "copy num_lines:#{num_lines}"
221
+ end
222
+ lrange = line_range(@lpos, num_lines)
223
+ s = self[lrange]
224
+ add_delta([lrange.begin, DELETE, lrange.end - lrange.begin + 1], true)
225
+ vma.clipboard.set(s)
226
+ update_pos(lrange.begin)
227
+ @paste_lines = true
228
+ #recalc_line_ends
229
+ end
230
+
231
+ def insert_tab
232
+ convert = conf(:tab_to_spaces_default)
233
+ convert = true if conf(:tab_to_spaces_languages).include?(@lang)
234
+ convert = false if conf(:tab_to_spaces_not_languages).include?(@lang)
235
+ tw = conf(:tab_width)
236
+ if convert
237
+ indent_to = (@cpos / tw) * tw + tw
238
+ indentdiff = indent_to - @cpos
239
+ insert_txt(" " * indentdiff)
240
+ else
241
+ insert_txt("\t")
242
+ end
243
+ end
244
+
245
+ def insert_image_after_current_line(fname)
246
+ lr = current_line_range()
247
+ a = "⟦img:#{fname}⟧\n"
248
+ b = " \n"
249
+ txt = a + b
250
+ insert_txt_at(txt, lr.end + 1)
251
+ buf.view.handle_deltas
252
+ imgpos = lr.end + 1 + a.size
253
+ add_image(fname, imgpos)
254
+ end
255
+ end
@@ -0,0 +1,303 @@
1
+ # Buffer operations related to cursor position, e.g. moving the cursor (backward, forward, next line etc.)
2
+ class Buffer < String
3
+
4
+ def line(lpos)
5
+ if @line_ends.size == 0
6
+ return self
7
+ end
8
+
9
+ #TODO: implement using line_range()
10
+ if lpos >= @line_ends.size
11
+ debug("lpos too large") #TODO
12
+ return ""
13
+ elsif lpos == @line_ends.size
14
+ end
15
+ start = @line_ends[lpos - 1] + 1 if lpos > 0
16
+ start = 0 if lpos == 0
17
+ _end = @line_ends[lpos]
18
+ debug "start: _#{start}, end: #{_end}"
19
+ return self[start.._end]
20
+ end
21
+
22
+ def at_end_of_line?()
23
+ return (self[@pos] == "\n" or at_end_of_buffer?)
24
+ end
25
+
26
+ def at_end_of_buffer?()
27
+ return @pos == self.size
28
+ end
29
+
30
+ def refresh_cursor
31
+ self.view.set_cursor_pos(@pos)
32
+ end
33
+
34
+ def set_pos(new_pos)
35
+ if new_pos >= self.size
36
+ @pos = self.size - 1 # TODO:??right side of last char
37
+ elsif new_pos >= 0
38
+ @pos = new_pos
39
+ end
40
+ self.view.set_cursor_pos(pos)
41
+ # gui_set_cursor_pos(@id, @pos)
42
+ calculate_line_and_column_pos
43
+
44
+ check_if_modified_outside
45
+ end
46
+
47
+ # Get the line number of character position
48
+ def get_line_pos(pos)
49
+ lpos = @line_ends.bsearch_index { |x, _| x >= pos }
50
+ return lpos
51
+ end
52
+
53
+ # Calculate the two dimensional column and line positions based on
54
+ # (one dimensional) position in the buffer.
55
+ def get_line_and_col_pos(pos)
56
+ pos = self.size if pos > self.size
57
+ pos = 0 if pos < 0
58
+
59
+ lpos = get_line_pos(pos)
60
+
61
+ lpos = @line_ends.size if lpos == nil
62
+ cpos = pos
63
+ cpos -= @line_ends[lpos - 1] + 1 if lpos > 0
64
+
65
+ return [lpos, cpos]
66
+ end
67
+
68
+ def calculate_line_and_column_pos(reset = true)
69
+ @lpos, @cpos = get_line_and_col_pos(@pos)
70
+ reset_larger_cpos if reset
71
+ end
72
+
73
+ def set_line_and_column_pos(lpos, cpos, _reset_larger_cpos = true)
74
+ @lpos = lpos if !lpos.nil?
75
+ @cpos = cpos if !cpos.nil?
76
+ if @lpos > 0
77
+ new_pos = @line_ends[@lpos - 1] + 1
78
+ else
79
+ new_pos = 0
80
+ end
81
+
82
+ if @cpos > (line(@lpos).size - 1)
83
+ debug("$cpos too large: #{@cpos} #{@lpos}")
84
+ if @larger_cpos < @cpos
85
+ @larger_cpos = @cpos
86
+ end
87
+ @cpos = line(@lpos).size - 1
88
+ end
89
+ new_pos += @cpos
90
+ set_pos(new_pos)
91
+ reset_larger_cpos if _reset_larger_cpos
92
+ end
93
+
94
+ # Calculate the one dimensional array index based on column and line positions
95
+ def calculate_pos_from_cpos_lpos(reset = true)
96
+ set_line_and_column_pos(nil, nil)
97
+ end
98
+
99
+ def update_pos(pos)
100
+ @pos = pos
101
+ calculate_line_and_column_pos
102
+ end
103
+
104
+ def is_legal_pos(pos, op = :read)
105
+ return false if pos < 0
106
+ if op == :add
107
+ return false if pos > self.size
108
+ elsif op == :read
109
+ return false if pos >= self.size
110
+ end
111
+ return true
112
+ end
113
+
114
+ def jump_to_last_edit()
115
+ return if @edit_pos_history.empty?
116
+ @edit_pos_history_i += 1
117
+
118
+ if @edit_pos_history_i > @edit_pos_history.size
119
+ @edit_pos_history_i = 0
120
+ end
121
+
122
+ # if @edit_pos_history.size >= @edit_pos_history_i
123
+ set_pos(@edit_pos_history[-@edit_pos_history_i])
124
+ center_on_current_line
125
+ return true
126
+ # end
127
+ end
128
+
129
+ def jump_to_next_edit()
130
+ return if @edit_pos_history.empty?
131
+ @edit_pos_history_i -= 1
132
+ @edit_pos_history_i = @edit_pos_history.size - 1 if @edit_pos_history_i < 0
133
+ debug "@edit_pos_history_i=#{@edit_pos_history_i}"
134
+ set_pos(@edit_pos_history[-@edit_pos_history_i])
135
+ center_on_current_line
136
+ return true
137
+ end
138
+
139
+ def jump_to_random_pos()
140
+ set_pos(rand(self.size))
141
+ end
142
+
143
+ def jump_to_next_instance_of_word()
144
+ if $kbd.last_action == $kbd.cur_action and @current_word != nil
145
+ # debug "REPEATING *"
146
+ else
147
+ start_search = [@pos - 150, 0].max
148
+
149
+ search_str1 = self[start_search..(@pos)]
150
+ wsmarks = scan_indexes(search_str1, /(?<=[^\p{Word}])\p{Word}/)
151
+ a = wsmarks[-1]
152
+ a = 0 if a == nil
153
+
154
+ search_str2 = self[(@pos)..(@pos + 150)]
155
+ wemarks = scan_indexes(search_str2, /(?<=\p{Word})[^\p{Word}]/)
156
+ b = wemarks[0]
157
+ word_start = (@pos - search_str1.size + a + 1)
158
+ word_start = 0 if !(word_start >= 0)
159
+ @current_word = self[word_start..(@pos + b - 1)]
160
+ end
161
+
162
+ #TODO: search for /[^\p{Word}]WORD[^\p{Word}]/
163
+ position_of_next_word = self.index(@current_word, @pos + 1)
164
+ if position_of_next_word != nil
165
+ set_pos(position_of_next_word)
166
+ else #Search from beginning
167
+ position_of_next_word = self.index(@current_word)
168
+ set_pos(position_of_next_word) if position_of_next_word != nil
169
+ end
170
+ center_on_current_line
171
+ return true
172
+ end
173
+
174
+ def jump_word(direction, wordpos)
175
+ offset = 0
176
+ if direction == FORWARD
177
+ debug "POS: #{@pos},"
178
+ search_str = self[(@pos)..(@pos + 250)]
179
+ return if search_str == nil
180
+ if wordpos == WORD_START # vim 'w'
181
+ wsmarks = scan_indexes(search_str, /(?<=[^\p{Word}])\p{Word}|\Z/) # \Z = end of string, just before last newline.
182
+ wsmarks2 = scan_indexes(search_str, /\n[ \t]*\n/) # "empty" lines that have whitespace
183
+ wsmarks2 = wsmarks2.collect { |x| x + 1 }
184
+ wsmarks = (wsmarks2 + wsmarks).sort.uniq
185
+ offset = 0
186
+ if wsmarks.any?
187
+ next_pos = @pos + wsmarks[0] + offset
188
+ set_pos(next_pos)
189
+ end
190
+ elsif wordpos == WORD_END
191
+ search_str = self[(@pos + 1)..(@pos + 150)]
192
+ wsmarks = scan_indexes(search_str, /(?<=\p{Word})[^\p{Word}]/)
193
+ offset = -1
194
+ if wsmarks.any?
195
+ next_pos = @pos + 1 + wsmarks[0] + offset
196
+ set_pos(next_pos)
197
+ end
198
+ end
199
+ end
200
+ if direction == BACKWARD # vim 'b'
201
+ start_search = @pos - 150 #TODO 150 length limit
202
+ start_search = 0 if start_search < 0
203
+ search_str = self[start_search..(@pos - 1)]
204
+ return if search_str == nil
205
+ wsmarks = scan_indexes(search_str,
206
+ #/(^|(\W)\w|\n)/) #TODO 150 length limit
207
+ #/^|(?<=[^\p{Word}])\p{Word}|(?<=\n)\n/) #include empty lines?
208
+ /\A|(?<=[^\p{Word}])\p{Word}/) # Start of string or nonword,word.
209
+
210
+ offset = 0
211
+
212
+ if wsmarks.any?
213
+ next_pos = start_search + wsmarks.last + offset
214
+ set_pos(next_pos)
215
+ end
216
+ end
217
+ end
218
+
219
+ def jump_to_mark(mark_char)
220
+ p = @marks[mark_char]
221
+ set_pos(p) if p
222
+ center_on_current_line
223
+ return true
224
+ end
225
+
226
+ def jump(target)
227
+ if target == START_OF_BUFFER
228
+ set_pos(0)
229
+ end
230
+ if target == END_OF_BUFFER
231
+ set_pos(self.size - 1)
232
+ end
233
+ if target == BEGINNING_OF_LINE
234
+ @cpos = 0
235
+ calculate_pos_from_cpos_lpos
236
+ end
237
+ if target == END_OF_LINE
238
+ @cpos = line(@lpos).size - 1
239
+ calculate_pos_from_cpos_lpos
240
+ end
241
+
242
+ if target == FIRST_NON_WHITESPACE
243
+ l = current_line()
244
+ debug l.inspect
245
+ @cpos = line(@lpos).size - 1
246
+ a = scan_indexes(l, /\S/)
247
+ debug a.inspect
248
+ if a.any?
249
+ @cpos = a[0]
250
+ else
251
+ @cpos = 0
252
+ end
253
+ calculate_pos_from_cpos_lpos
254
+ end
255
+ end
256
+
257
+ def jump_to_line(line_n = 1)
258
+
259
+ # $method_handles_repeat = true
260
+ # if !$next_command_count.nil? and $next_command_count > 0
261
+ # line_n = $next_command_count
262
+ # debug "jump to line:#{line_n}"
263
+ # end
264
+ debug "jump to line:#{line_n}"
265
+ line_n = get_repeat_num() if line_n == 1
266
+
267
+ if line_n > @line_ends.size
268
+ debug("lpos too large") #TODO
269
+ return
270
+ end
271
+ if line_n == 1
272
+ set_pos(0)
273
+ else
274
+ set_pos(@line_ends[line_n - 2] + 1)
275
+ end
276
+ end
277
+
278
+ def jump_to_next_instance_of_char(char, direction = FORWARD)
279
+ if direction == FORWARD
280
+ position_of_next_char = self.index(char, @pos + 1)
281
+ if position_of_next_char != nil
282
+ @pos = position_of_next_char
283
+ end
284
+ elsif direction == BACKWARD
285
+ start_search = @pos - 250
286
+ start_search = 0 if start_search < 0
287
+ search_substr = self[start_search..(@pos - 1)]
288
+ _pos = search_substr.reverse.index(char)
289
+ if _pos != nil
290
+ @pos -= (_pos + 1)
291
+ end
292
+ end
293
+ m = method("jump_to_next_instance_of_char")
294
+ set_last_command({ method: m, params: [char, direction] })
295
+ $last_find_command = { char: char, direction: direction }
296
+ set_pos(@pos)
297
+ return true
298
+ end
299
+
300
+ def jump_to_pos(new_pos)
301
+ set_pos(new_pos)
302
+ end
303
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  def save_buffer_list()
3
2
  message("Save buffer list")
4
3
  buffn = get_dot_path("buffers.txt")
@@ -21,13 +20,13 @@ def load_buffer_list()
21
20
  end
22
21
 
23
22
  class BufferList < Array
24
- attr_reader :current_buf, :last_dir, :buffer_history
23
+ attr_reader :current_buf, :last_dir, :last_file, :buffer_history
25
24
 
26
25
  def initialize()
27
26
  @last_dir = File.expand_path(".")
28
27
  @buffer_history = []
29
28
  super
30
- @current_buf=0
29
+ @current_buf = 0
31
30
  end
32
31
 
33
32
  # lastdir = File.expand_path(".") if lastdir.nil?
@@ -39,7 +38,8 @@ class BufferList < Array
39
38
  @recent_ind = 0
40
39
  $hook.call(:change_buffer, vma.buf)
41
40
  vma.gui.set_current_buffer(vma.buf.id)
42
- gui_set_cursor_pos(vma.buf.id, vma.buf.pos)
41
+ # gui_set_cursor_pos(vma.buf.id, vma.buf.pos)
42
+ vma.buf.view.set_cursor_pos(vma.buf.pos)
43
43
  update_last_dir(_buf)
44
44
  end
45
45
 
@@ -111,8 +111,13 @@ class BufferList < Array
111
111
  def set_current_buffer(buffer_i, update_history = true)
112
112
  buffer_i = self.size -1 if buffer_i > self.size
113
113
  buffer_i = 0 if buffer_i < 0
114
+ if !vma.buf.nil? and vma.kbd.get_mode != :browse #TODO
115
+ # Save keyboard mode status of old buffer when switching buffer
116
+ vma.buf.mode_stack = vma.kbd.default_mode_stack.clone
117
+ end
114
118
  vma.buf = self[buffer_i]
115
119
  return if !vma.buf
120
+ update_last_dir(vma.buf)
116
121
  @current_buf = buffer_i
117
122
  debug "SWITCH BUF2. bufsize:#{self.size}, curbuf: #{@current_buf}"
118
123
  fpath = vma.buf.fname
@@ -123,24 +128,36 @@ class BufferList < Array
123
128
  if update_history
124
129
  add_current_buf_to_history
125
130
  end
126
-
127
131
  vma.hook.call(:change_buffer, vma.buf)
128
- vma.buf.set_active
132
+ vma.buf.set_active # TODO
129
133
 
130
134
  vma.gui.set_current_buffer(vma.buf.id)
131
135
 
136
+ if !vma.buf.mode_stack.nil? and vma.kbd.get_mode != :browse #TODO
137
+ debug "set kbd mode stack #{vma.buf.mode_stack} #{vma.buf.id}", 2
138
+ # Reload previously saved keyboard mode status
139
+ # vma.kbd.set_mode_stack(vma.buf.mode_stack.clone) #TODO:needed?
140
+ vma.kbd.set_mode_stack([vma.buf.default_mode])
141
+ end
142
+ vma.kbd.set_mode_to_default
143
+
132
144
  gui_set_window_title(vma.buf.title, vma.buf.subtitle)
133
145
 
134
146
  if vma.buf.fname
135
147
  @last_dir = File.dirname(vma.buf.fname)
136
148
  end
137
149
 
138
- # hpt_scan_images() if $debug # experimental
150
+ # hpt_scan_images() if cnf.debug? # experimental
151
+ end
152
+
153
+ def to_s
154
+ return self.class.to_s
139
155
  end
140
156
 
141
157
  def update_last_dir(buf)
142
158
  if buf.fname
143
159
  @last_dir = File.dirname(buf.fname)
160
+ @last_file = buf.fname
144
161
  end
145
162
  end
146
163
 
@@ -213,8 +230,8 @@ class BufferList < Array
213
230
  if from_recent
214
231
  @current_buf = jump_to_buf
215
232
  else
216
- # Find last edited buffer that is not already open
217
- @current_buf = @buffer_history.filter{|x| !vma.gui.is_buffer_open(self[x].id)}.last
233
+ # Find last edited buffer that is not already open
234
+ @current_buf = @buffer_history.filter { |x| !vma.gui.is_buffer_open(self[x].id) }.last
218
235
  end
219
236
  end
220
237
  if self.size == 0 or @current_buf.nil?
@@ -7,11 +7,12 @@ class BufferManager
7
7
  end
8
8
 
9
9
  def self.init()
10
- vma.kbd.add_minor_mode("bmgr", :buf_mgr, :command)
10
+ # vma.kbd.add_minor_mode("bmgr", :buf_mgr, :command)
11
+ vma.kbd.add_minor_mode("bmgr", :bmgr, :command)
11
12
  reg_act(:bmgr_select, proc { buf.module.select_line }, "")
12
13
  reg_act(:bmgr_close, proc { buf.module.close_selected }, "")
13
14
 
14
- reg_act(:start_buf_manager, proc { BufferManager.new.run; vma.kbd.set_mode(:buf_mgr) }, "Buffer manager")
15
+ reg_act(:start_buf_manager, proc { BufferManager.new.run; vma.kbd.set_mode(:bmgr) }, "Buffer manager")
15
16
 
16
17
  bindkey "bmgr enter", :bmgr_select
17
18
  bindkey "bmgr c", :bmgr_close
@@ -84,6 +85,7 @@ class BufferManager
84
85
 
85
86
  if @buf.nil?
86
87
  @buf = create_new_buffer(s,"bufmgr")
88
+ @buf.default_mode = :buf_mgr
87
89
  @buf.module = self
88
90
  @buf.active_kbd_mode = :buf_mgr
89
91
  else
@@ -0,0 +1,35 @@
1
+ class Clipboard
2
+ def initialize
3
+ @clipboard = []
4
+ end
5
+
6
+ def [](key)
7
+ return @clipboard[key]
8
+ end
9
+
10
+ def <<(str)
11
+ return @clipboard << str
12
+ end
13
+
14
+ def set(s)
15
+ if !(s.class <= String) or s.size == 0
16
+ debug s.inspect
17
+ debug [s, s.class, s.size]
18
+ log_error("s.class != String or s.size == 0")
19
+ return
20
+ end
21
+ @clipboard << s
22
+ set_system_clipboard(s)
23
+ vma.register[vma.cur_register] = s
24
+ debug "SET CLIPBOARD: [#{s}]"
25
+ debug "REGISTER: #{vma.cur_register}:#{vma.register[vma.cur_register]}"
26
+ end
27
+
28
+ def get()
29
+ return @clipboard[-1]
30
+ end
31
+ end
32
+
33
+ def set_system_clipboard(arg)
34
+ vma.gui.window.display.clipboard.set(arg)
35
+ end