pwkeep 0.0.3 → 0.0.4
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.
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -13
- data/README.md +4 -2
- data/Rakefile +5 -0
- data/doc/PWKeep.html +323 -0
- data/doc/PWKeep/Config.html +192 -0
- data/doc/PWKeep/Editor.html +778 -0
- data/doc/PWKeep/EditorApplication.html +1221 -0
- data/doc/PWKeep/Exception.html +123 -0
- data/doc/PWKeep/Main.html +805 -0
- data/doc/PWKeep/StatusBar.html +436 -0
- data/doc/PWKeep/Storage.html +1128 -0
- data/doc/_index.html +191 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +338 -0
- data/doc/file.README.html +145 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +145 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +371 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/pwkeep.rb +0 -1
- data/lib/pwkeep/editor.rb +8 -457
- data/lib/pwkeep/main.rb +36 -13
- data/lib/pwkeep/storage.rb +22 -12
- data/pwkeep.gemspec +2 -2
- metadata +26 -4
@@ -0,0 +1,112 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.8.6.2
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
hasFrames = window.top.frames.main ? true : false;
|
19
|
+
relpath = '';
|
20
|
+
framesUrl = "frames.html#!" + escape(window.location.href);
|
21
|
+
</script>
|
22
|
+
|
23
|
+
|
24
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
25
|
+
|
26
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
27
|
+
|
28
|
+
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="header">
|
32
|
+
<div id="menu">
|
33
|
+
|
34
|
+
<a href="_index.html">Index</a> »
|
35
|
+
|
36
|
+
|
37
|
+
<span class="title">Top Level Namespace</span>
|
38
|
+
|
39
|
+
|
40
|
+
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div id="search">
|
44
|
+
|
45
|
+
<a class="full_list_link" id="class_list_link"
|
46
|
+
href="class_list.html">
|
47
|
+
Class List
|
48
|
+
</a>
|
49
|
+
|
50
|
+
<a class="full_list_link" id="method_list_link"
|
51
|
+
href="method_list.html">
|
52
|
+
Method List
|
53
|
+
</a>
|
54
|
+
|
55
|
+
<a class="full_list_link" id="file_list_link"
|
56
|
+
href="file_list.html">
|
57
|
+
File List
|
58
|
+
</a>
|
59
|
+
|
60
|
+
</div>
|
61
|
+
<div class="clear"></div>
|
62
|
+
</div>
|
63
|
+
|
64
|
+
<iframe id="search_frame"></iframe>
|
65
|
+
|
66
|
+
<div id="content"><h1>Top Level Namespace
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
</h1>
|
71
|
+
|
72
|
+
<dl class="box">
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
</dl>
|
82
|
+
<div class="clear"></div>
|
83
|
+
|
84
|
+
<h2>Defined Under Namespace</h2>
|
85
|
+
<p class="children">
|
86
|
+
|
87
|
+
|
88
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="PWKeep.html" title="PWKeep (module)">PWKeep</a></span>
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
</p>
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
</div>
|
104
|
+
|
105
|
+
<div id="footer">
|
106
|
+
Generated on Thu Jan 9 16:06:06 2014 by
|
107
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
108
|
+
0.8.6.2 (ruby-1.9.3).
|
109
|
+
</div>
|
110
|
+
|
111
|
+
</body>
|
112
|
+
</html>
|
data/lib/pwkeep.rb
CHANGED
data/lib/pwkeep/editor.rb
CHANGED
@@ -1,462 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'open3'
|
2
2
|
|
3
3
|
module PWKeep
|
4
|
-
def self.run_editor(data, options)
|
5
|
-
ret = [false, data]
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
)
|
12
|
-
|
13
|
-
screen.draw *app.display_info
|
14
|
-
|
15
|
-
Dispel::Keyboard.output do |key|
|
16
|
-
if key == :resize
|
17
|
-
app.resize(screen.lines, screen.columns)
|
18
|
-
else
|
19
|
-
result = app.key key
|
20
|
-
if result == :quit
|
21
|
-
ret = [app.editor.saved_content != data, app.editor.saved_content]
|
22
|
-
break
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
screen.draw *app.display_info
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
return ret
|
31
|
-
end
|
32
|
-
|
33
|
-
class EditorApplication
|
34
|
-
attr_reader :editor, :status, :command, :options
|
35
|
-
|
36
|
-
def initialize(data, options)
|
37
|
-
@options = Ruco::OptionAccessor.new(options)
|
38
|
-
@data = data
|
39
|
-
|
40
|
-
setup_actions
|
41
|
-
setup_keys
|
42
|
-
create_components
|
43
|
-
end
|
44
|
-
|
45
|
-
def display_info
|
46
|
-
[view, style_map, cursor]
|
47
|
-
end
|
48
|
-
|
49
|
-
def view
|
50
|
-
[status.view, editor.view, command.view].join("\n")
|
51
|
-
end
|
52
|
-
|
53
|
-
def style_map
|
54
|
-
status.style_map + editor.style_map + command.style_map
|
55
|
-
end
|
56
|
-
|
57
|
-
def cursor
|
58
|
-
Ruco::Position.new(@focused.cursor.line + @status_lines, @focused.cursor.column)
|
59
|
-
end
|
60
|
-
|
61
|
-
# user typed a key
|
62
|
-
def key(key)
|
63
|
-
# deactivate select_mode if its not re-enabled in this action
|
64
|
-
@select_mode_was_on = @select_mode
|
65
|
-
@select_mode = false
|
66
|
-
|
67
|
-
if bound = @bindings[key]
|
68
|
-
return execute_action(bound)
|
69
|
-
end
|
70
|
-
|
71
|
-
case key
|
72
|
-
|
73
|
-
# move
|
74
|
-
when :down then move_with_select_mode :relative, 1,0
|
75
|
-
when :right then move_with_select_mode :relative, 0,1
|
76
|
-
when :up then move_with_select_mode :relative, -1,0
|
77
|
-
when :left then move_with_select_mode :relative, 0,-1
|
78
|
-
when :page_up then move_with_select_mode :page_up
|
79
|
-
when :page_down then move_with_select_mode :page_down
|
80
|
-
when :"Ctrl+right", :"Alt+f" then move_with_select_mode :jump, :right
|
81
|
-
when :"Ctrl+left", :"Alt+b" then move_with_select_mode :jump, :left
|
82
|
-
|
83
|
-
# select
|
84
|
-
when :"Shift+down" then @focused.selecting { move(:relative, 1, 0) }
|
85
|
-
when :"Shift+right" then @focused.selecting { move(:relative, 0, 1) }
|
86
|
-
when :"Shift+up" then @focused.selecting { move(:relative, -1, 0) }
|
87
|
-
when :"Shift+left" then @focused.selecting { move(:relative, 0, -1) }
|
88
|
-
when :"Ctrl+Shift+left", :"Alt+Shift+left" then @focused.selecting{ move(:jump, :left) }
|
89
|
-
when :"Ctrl+Shift+right", :"Alt+Shift+right" then @focused.selecting{ move(:jump, :right) }
|
90
|
-
when :"Shift+end" then @focused.selecting{ move(:to_eol) }
|
91
|
-
when :"Shift+home" then @focused.selecting{ move(:to_bol) }
|
92
|
-
|
93
|
-
|
94
|
-
# modify
|
95
|
-
when :tab then
|
96
|
-
if @editor.selection
|
97
|
-
@editor.indent
|
98
|
-
else
|
99
|
-
@focused.insert("\t")
|
100
|
-
end
|
101
|
-
when :"Shift+tab" then @editor.unindent
|
102
|
-
when :enter then @focused.insert("\n")
|
103
|
-
when :backspace then @focused.delete(-1)
|
104
|
-
when :delete then @focused.delete(1)
|
105
|
-
|
106
|
-
when :escape then # escape from focused
|
107
|
-
@focused.reset
|
108
|
-
@focused = editor
|
109
|
-
else
|
110
|
-
@focused.insert(key) if key.is_a?(String)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def bind(key, action=nil, &block)
|
115
|
-
raise "Ctrl+m cannot be bound" if key == :"Ctrl+m" # would shadow enter -> bad
|
116
|
-
raise "Cannot bind an action and a block" if action and block
|
117
|
-
@bindings[key] = action || block
|
118
|
-
end
|
119
|
-
|
120
|
-
def action(name, &block)
|
121
|
-
@actions[name] = block
|
122
|
-
end
|
123
|
-
|
124
|
-
def ask(question, options={}, &block)
|
125
|
-
@focused = command
|
126
|
-
command.ask(question, options) do |response|
|
127
|
-
@focused = editor
|
128
|
-
block.call(response)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def loop_ask(question, options={}, &block)
|
133
|
-
ask(question, options) do |result|
|
134
|
-
finished = (block.call(result) == :finished)
|
135
|
-
loop_ask(question, options, &block) unless finished
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def configure(&block)
|
140
|
-
instance_exec(&block)
|
141
|
-
end
|
142
|
-
|
143
|
-
def resize(lines, columns)
|
144
|
-
@options[:lines] = lines
|
145
|
-
@options[:columns] = columns
|
146
|
-
create_components
|
147
|
-
@editor.resize(editor_lines, columns)
|
148
|
-
end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def setup_actions
|
153
|
-
@actions = {}
|
154
|
-
|
155
|
-
action :paste do
|
156
|
-
@focused.insert(Clipboard.paste)
|
157
|
-
end
|
158
|
-
|
159
|
-
action :copy do
|
160
|
-
Clipboard.copy(@focused.text_in_selection)
|
161
|
-
end
|
162
|
-
|
163
|
-
action :cut do
|
164
|
-
Clipboard.copy(@focused.text_in_selection)
|
165
|
-
@focused.delete(0)
|
166
|
-
end
|
167
|
-
|
168
|
-
action :save do
|
169
|
-
result = editor.save
|
170
|
-
if result != true
|
171
|
-
ask("#{result.slice(0,100)} -- Enter=Retry Esc=Cancel "){ @actions[:save].call }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
action :quit do
|
176
|
-
if editor.modified?
|
177
|
-
ask("Lose changes? Enter=Yes Esc=Cancel") do
|
178
|
-
editor.store_session
|
179
|
-
:quit
|
180
|
-
end
|
181
|
-
else
|
182
|
-
editor.store_session
|
183
|
-
:quit
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
action :go_to_line do
|
188
|
-
ask('Go to Line: ') do |result|
|
189
|
-
editor.move(:to_line, result.to_i - 1)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
action :delete_line do
|
194
|
-
editor.delete_line
|
195
|
-
end
|
196
|
-
|
197
|
-
action :select_mode do
|
198
|
-
@select_mode = !@select_mode_was_on
|
199
|
-
end
|
200
|
-
|
201
|
-
action :select_all do
|
202
|
-
@focused.move(:to, 0, 0)
|
203
|
-
@focused.selecting do
|
204
|
-
move(:to, 9999, 9999)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
action :find do
|
209
|
-
ask("Find: ", :cache => true) do |result|
|
210
|
-
next if editor.find(result)
|
211
|
-
|
212
|
-
if editor.content.include?(result)
|
213
|
-
ask("No matches found -- Enter=First match ESC=Stop") do
|
214
|
-
editor.move(:to, 0,0)
|
215
|
-
editor.find(result)
|
216
|
-
end
|
217
|
-
else
|
218
|
-
ask("No matches found in entire file", :auto_enter => true){}
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
action :find_and_replace do
|
224
|
-
ask("Find: ", :cache => true) do |term|
|
225
|
-
if editor.find(term)
|
226
|
-
ask("Replace with: ", :cache => true) do |replace|
|
227
|
-
loop_ask("Replace=Enter Skip=s All=a Cancel=Esc", :auto_enter => true) do |ok|
|
228
|
-
case ok
|
229
|
-
when '' # enter
|
230
|
-
editor.insert(replace)
|
231
|
-
when 'a'
|
232
|
-
stop = true
|
233
|
-
editor.insert(replace)
|
234
|
-
editor.insert(replace) while editor.find(term)
|
235
|
-
when 's' # do nothing
|
236
|
-
else
|
237
|
-
stop = true
|
238
|
-
end
|
239
|
-
|
240
|
-
:finished if stop or not editor.find(term)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
action(:undo){ @editor.undo if @focused == @editor }
|
248
|
-
action(:redo){ @editor.redo if @focused == @editor }
|
249
|
-
action(:move_line_up){ @editor.move_line(-1) if @focused == @editor }
|
250
|
-
action(:move_line_down){ @editor.move_line(1) if @focused == @editor }
|
251
|
-
|
252
|
-
action(:move_to_eol){ move_with_select_mode :to_eol }
|
253
|
-
action(:move_to_bol){ move_with_select_mode :to_bol }
|
254
|
-
|
255
|
-
action(:insert_hash_rocket){ @editor.insert(' => ') }
|
256
|
-
end
|
257
|
-
|
258
|
-
def setup_keys
|
259
|
-
@bindings = {}
|
260
|
-
bind :"Ctrl+s", :save
|
261
|
-
bind :"Ctrl+w", :quit
|
262
|
-
bind :"Ctrl+q", :quit
|
263
|
-
bind :"Ctrl+g", :go_to_line
|
264
|
-
bind :"Ctrl+f", :find
|
265
|
-
bind :"Ctrl+r", :find_and_replace
|
266
|
-
bind :"Ctrl+b", :select_mode
|
267
|
-
bind :"Ctrl+a", :select_all
|
268
|
-
bind :"Ctrl+d", :delete_line
|
269
|
-
bind :"Ctrl+l", :insert_hash_rocket
|
270
|
-
bind :"Ctrl+x", :cut
|
271
|
-
bind :"Ctrl+c", :copy
|
272
|
-
bind :"Ctrl+v", :paste
|
273
|
-
bind :"Ctrl+z", :undo
|
274
|
-
bind :"Ctrl+y", :redo
|
275
|
-
bind :"Alt+Ctrl+down", :move_line_down
|
276
|
-
bind :"Alt+Ctrl+up", :move_line_up
|
277
|
-
bind :end, :move_to_eol
|
278
|
-
bind :"Ctrl+e", :move_to_eol # for OsX
|
279
|
-
bind :home, :move_to_bol
|
280
|
-
end
|
281
|
-
|
282
|
-
def load_user_config
|
283
|
-
Ruco.application = self
|
284
|
-
config = File.expand_path(@options[:rc] || "~/.ruco.rb")
|
285
|
-
load config if File.exist?(config)
|
286
|
-
end
|
287
|
-
|
288
|
-
def create_components
|
289
|
-
@status_lines = 1
|
290
|
-
|
291
|
-
editor_options = @options.slice(
|
292
|
-
:columns, :convert_tabs, :convert_newlines, :undo_stack_size, :color_theme
|
293
|
-
).merge(
|
294
|
-
:window => @options.nested(:window),
|
295
|
-
:history => @options.nested(:history),
|
296
|
-
:lines => editor_lines
|
297
|
-
).merge(@options.nested(:editor))
|
298
|
-
|
299
|
-
@editor ||= PWKeep::Editor.new(@data, editor_options)
|
300
|
-
@status = PWKeep::StatusBar.new(@editor, @options.nested(:status_bar).merge(:columns => options[:columns]))
|
301
|
-
@command = Ruco::CommandBar.new(@options.nested(:command_bar).merge(:columns => options[:columns]))
|
302
|
-
command.cursor_line = editor_lines
|
303
|
-
@focused = @editor
|
304
|
-
end
|
305
|
-
|
306
|
-
def editor_lines
|
307
|
-
command_lines = 1
|
308
|
-
@options[:lines] - @status_lines - command_lines
|
309
|
-
end
|
310
|
-
|
311
|
-
def parse_file_and_line(file)
|
312
|
-
if file.to_s.include?(':') and not File.exist?(file)
|
313
|
-
short_file, go_to_line = file.split(':',2)
|
314
|
-
if File.exist?(short_file)
|
315
|
-
file = short_file
|
316
|
-
else
|
317
|
-
go_to_line = nil
|
318
|
-
end
|
319
|
-
end
|
320
|
-
[file, go_to_line]
|
321
|
-
end
|
322
|
-
|
323
|
-
def move_with_select_mode(*args)
|
324
|
-
@select_mode = true if @select_mode_was_on
|
325
|
-
if @select_mode
|
326
|
-
@focused.selecting do
|
327
|
-
move(*args)
|
328
|
-
end
|
329
|
-
else
|
330
|
-
@focused.send(:move, *args)
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
def execute_action(action)
|
335
|
-
if action.is_a?(Symbol)
|
336
|
-
@actions[action].call
|
337
|
-
else
|
338
|
-
action.call
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
class Editor
|
344
|
-
attr_reader :file
|
345
|
-
attr_reader :text_area
|
346
|
-
attr_reader :history
|
347
|
-
attr_reader :saved_content
|
348
|
-
|
349
|
-
private :text_area
|
350
|
-
delegate :view, :style_map, :cursor, :position,
|
351
|
-
:insert, :indent, :unindent, :delete, :delete_line,
|
352
|
-
:redo, :undo, :save_state,
|
353
|
-
:selecting, :selection, :text_in_selection, :reset,
|
354
|
-
:move, :resize, :move_line,
|
355
|
-
:to => :text_area
|
356
|
-
|
357
|
-
def initialize(data, options)
|
358
|
-
@options = options
|
359
|
-
|
360
|
-
content = data
|
361
|
-
@options[:language] ||= LanguageSniffer.detect(@file, :content => content).language
|
362
|
-
content.tabs_to_spaces! if @options[:convert_tabs]
|
363
|
-
|
364
|
-
# cleanup newline formats
|
365
|
-
@newline = content.match("\r\n|\r|\n")
|
366
|
-
@newline = (@newline ? @newline[0] : "\n")
|
367
|
-
content.gsub!(/\r\n?/,"\n")
|
368
|
-
|
369
|
-
@saved_content = content
|
370
|
-
@text_area = Ruco::EditorArea.new(content, @options)
|
371
|
-
@history = @text_area.history
|
372
|
-
restore_session
|
373
|
-
end
|
374
|
-
|
375
|
-
def find(text)
|
376
|
-
move(:relative, 0,0) # reset selection
|
377
|
-
start = text_area.content.index(text, text_area.index_for_position+1)
|
378
|
-
return unless start
|
379
|
-
|
380
|
-
# select the found word
|
381
|
-
finish = start + text.size
|
382
|
-
move(:to_index, finish)
|
383
|
-
selecting{ move(:to_index, start) }
|
384
|
-
|
385
|
-
true
|
386
|
-
end
|
387
|
-
|
388
|
-
def modified?
|
389
|
-
@saved_content != text_area.content
|
390
|
-
end
|
391
|
-
|
392
|
-
def save
|
393
|
-
lines = text_area.send(:lines)
|
394
|
-
lines.each(&:rstrip!) if @options[:remove_trailing_whitespace_on_save]
|
395
|
-
lines << '' if @options[:blank_line_before_eof_on_save] and lines.last.to_s !~ /^\s*$/
|
396
|
-
content = lines * @newline
|
397
|
-
|
398
|
-
@saved_content = content.gsub(/\r?\n/, "\n")
|
399
|
-
|
400
|
-
true
|
401
|
-
rescue Object => e
|
402
|
-
e.message
|
403
|
-
end
|
404
|
-
|
405
|
-
def store_session
|
406
|
-
end
|
407
|
-
|
408
|
-
def content
|
409
|
-
text_area.content.freeze # no modifications allowed
|
410
|
-
end
|
411
|
-
|
412
|
-
private
|
413
|
-
|
414
|
-
def restore_session
|
415
|
-
end
|
416
|
-
|
417
|
-
def session_store
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
class StatusBar
|
422
|
-
def initialize(editor, options)
|
423
|
-
@editor = editor
|
424
|
-
@options = options
|
425
|
-
end
|
426
|
-
|
427
|
-
def view
|
428
|
-
columns = @options[:columns]
|
429
|
-
|
430
|
-
version = "Ruco #{Ruco::VERSION} -- "
|
431
|
-
position = " #{@editor.position.line + 1}:#{@editor.position.column + 1}"
|
432
|
-
indicators = "#{change_indicator}#{writable_indicator}"
|
433
|
-
essential = version + position + indicators
|
434
|
-
space_left = [columns - essential.size, 0].max
|
435
|
-
|
436
|
-
# fit file name into remaining space
|
437
|
-
"#{version}#{indicators}#{' ' * space_left}#{position}"[0, columns]
|
438
|
-
end
|
439
|
-
|
440
|
-
def style_map
|
441
|
-
Dispel::StyleMap.single_line_reversed(@options[:columns])
|
442
|
-
end
|
443
|
-
|
444
|
-
def change_indicator
|
445
|
-
@editor.modified? ? '*' : ' '
|
446
|
-
end
|
447
|
-
|
448
|
-
def writable_indicator
|
449
|
-
true
|
450
|
-
end
|
451
|
-
|
452
|
-
private
|
453
|
-
|
454
|
-
# fill the line with left column and then overwrite the right section
|
455
|
-
def spread(left, right)
|
456
|
-
empty = [@options[:columns] - left.size, 0].max
|
457
|
-
line = left + (" " * empty)
|
458
|
-
line[(@options[:columns] - right.size - 1)..-1] = ' ' + right
|
459
|
-
line
|
4
|
+
def self.run_editor(data, options)
|
5
|
+
ret = [false, data]
|
6
|
+
Open3.pipeline_rw("vipe") do |din,dout,ts|
|
7
|
+
din.write data
|
8
|
+
din.close
|
9
|
+
data2 = dout.read
|
10
|
+
ret = [data != data2, data2]
|
460
11
|
end
|
461
12
|
end
|
462
13
|
end
|