xiki 0.5.0a
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/Gemfile +11 -0
- data/LICENSE +22 -0
- data/README.markdown +83 -0
- data/Rakefile +8 -0
- data/bin/xiki +46 -0
- data/etc/command/xiki_command.rb +203 -0
- data/etc/command/xiki_process.rb +52 -0
- data/etc/command/xiki_wrapper +2 -0
- data/etc/js/menu1.js +55 -0
- data/etc/js/xiki.js +259 -0
- data/etc/logo.png +0 -0
- data/etc/presentations/bootstrap.deck +5 -0
- data/etc/presentations/databases.deck +41 -0
- data/etc/presentations/diffs.deck +23 -0
- data/etc/presentations/documentation.deck +14 -0
- data/etc/presentations/effects.deck +5 -0
- data/etc/presentations/face.deck +297 -0
- data/etc/presentations/files.deck +79 -0
- data/etc/presentations/icons.deck +22 -0
- data/etc/presentations/images.deck +24 -0
- data/etc/presentations/key_shortcuts.deck +16 -0
- data/etc/presentations/macros.deck +18 -0
- data/etc/presentations/menu_classes.deck +44 -0
- data/etc/presentations/menu_directories.deck +30 -0
- data/etc/presentations/notes.deck +19 -0
- data/etc/presentations/other_languages.deck +55 -0
- data/etc/presentations/other_wiki_syntaxes.deck +4 -0
- data/etc/presentations/piano.deck +5 -0
- data/etc/presentations/potential/diffs.deck +38 -0
- data/etc/presentations/potential/evolution.deck +18 -0
- data/etc/presentations/potential/intro.deck +711 -0
- data/etc/presentations/potential/intro1.deck +711 -0
- data/etc/presentations/potential/intro2.deck +97 -0
- data/etc/presentations/potential/make_mysql_menu.deck +36 -0
- data/etc/presentations/potential/ruby_development.deck +17 -0
- data/etc/presentations/potential/ui_prototyping.deck +50 -0
- data/etc/presentations/potential/web_dev.deck +4 -0
- data/etc/presentations/potential/web_development.deck +10 -0
- data/etc/presentations/potential/wiki.deck +45 -0
- data/etc/presentations/presentations.deck +24 -0
- data/etc/presentations/rails_development.deck +29 -0
- data/etc/presentations/search_key_shortcuts.deck +37 -0
- data/etc/presentations/simplest_possible_ui.deck +37 -0
- data/etc/presentations/svg.deck +5 -0
- data/etc/presentations/testing.deck +28 -0
- data/etc/presentations/the_end.deck +13 -0
- data/etc/presentations/type_something_and_double_click.deck +57 -0
- data/etc/presentations/type_the_acronym.deck +144 -0
- data/etc/presentations/web_browser.deck +56 -0
- data/etc/presentations/xiki_command.deck +20 -0
- data/etc/presentations/xiki_url.deck +14 -0
- data/etc/shark.icns +0 -0
- data/etc/shark_script.icns +0 -0
- data/etc/snippets/html.notes +7 -0
- data/etc/snippets/notes.notes +20 -0
- data/etc/snippets/rb.notes +38 -0
- data/etc/templates/menu_template.menu +2 -0
- data/etc/templates/menu_template.rb +8 -0
- data/etc/templates/template.rb +5 -0
- data/etc/themes/Dark_Metal.notes +28 -0
- data/etc/themes/Orange_Path.notes +15 -0
- data/etc/themes/Shiny_Blue.notes +27 -0
- data/etc/themes/Shiny_Green.notes +27 -0
- data/etc/wrappers/wrapper.js +17 -0
- data/etc/wrappers/wrapper.py +20 -0
- data/etc/wrappers/wrapper.rb +25 -0
- data/lib/block.rb +72 -0
- data/lib/bookmarks.rb +352 -0
- data/lib/buffers.rb +170 -0
- data/lib/clipboard.rb +333 -0
- data/lib/code.rb +860 -0
- data/lib/code_tree.rb +476 -0
- data/lib/color.rb +274 -0
- data/lib/console.rb +557 -0
- data/lib/control_lock.rb +9 -0
- data/lib/control_tab.rb +176 -0
- data/lib/core_ext.rb +31 -0
- data/lib/cursor.rb +111 -0
- data/lib/deletes.rb +65 -0
- data/lib/diff_log.rb +297 -0
- data/lib/effects.rb +145 -0
- data/lib/environment.rb +5 -0
- data/lib/file_tree.rb +1875 -0
- data/lib/files.rb +334 -0
- data/lib/hide.rb +259 -0
- data/lib/history.rb +286 -0
- data/lib/image.rb +51 -0
- data/lib/incrementer.rb +15 -0
- data/lib/insert.rb +7 -0
- data/lib/irc.rb +22 -0
- data/lib/key_bindings.rb +658 -0
- data/lib/keys.rb +754 -0
- data/lib/launcher.rb +1351 -0
- data/lib/line.rb +429 -0
- data/lib/links.rb +6 -0
- data/lib/location.rb +175 -0
- data/lib/macros.rb +48 -0
- data/lib/man.rb +19 -0
- data/lib/menu.rb +708 -0
- data/lib/merb.rb +259 -0
- data/lib/message.rb +5 -0
- data/lib/meths.rb +56 -0
- data/lib/mode.rb +34 -0
- data/lib/move.rb +248 -0
- data/lib/notes.rb +1000 -0
- data/lib/numbers.rb +45 -0
- data/lib/ol.rb +203 -0
- data/lib/ol_helper.rb +44 -0
- data/lib/overlay.rb +167 -0
- data/lib/pause_means_space.rb +68 -0
- data/lib/php.rb +22 -0
- data/lib/projects.rb +21 -0
- data/lib/relinquish_exception.rb +2 -0
- data/lib/remote.rb +206 -0
- data/lib/requirer.rb +46 -0
- data/lib/rest_tree.rb +108 -0
- data/lib/ruby.rb +57 -0
- data/lib/ruby_console.rb +165 -0
- data/lib/search.rb +1572 -0
- data/lib/search_term.rb +40 -0
- data/lib/snippet.rb +68 -0
- data/lib/specs.rb +229 -0
- data/lib/styles.rb +274 -0
- data/lib/svn.rb +682 -0
- data/lib/text_util.rb +110 -0
- data/lib/tree.rb +1871 -0
- data/lib/tree_cursor.rb +87 -0
- data/lib/trouble_shooting.rb +27 -0
- data/lib/url_tree.rb +11 -0
- data/lib/view.rb +1474 -0
- data/lib/window.rb +133 -0
- data/lib/xiki.rb +404 -0
- data/menus/accounts.rb +5 -0
- data/menus/address_book.rb +21 -0
- data/menus/agenda.rb +28 -0
- data/menus/all.rb +5 -0
- data/menus/amazon.rb +16 -0
- data/menus/app.rb +16 -0
- data/menus/applescript.rb +46 -0
- data/menus/as.rb +15 -0
- data/menus/bookmarklet.rb +63 -0
- data/menus/bootstrap.rb +568 -0
- data/menus/browse.rb +13 -0
- data/menus/browser.rb +78 -0
- data/menus/cassandra_db.rb +36 -0
- data/menus/chmod.rb +27 -0
- data/menus/classes.rb +5 -0
- data/menus/coffee_script.rb +35 -0
- data/menus/computer.rb +24 -0
- data/menus/contacts.rb +5 -0
- data/menus/cookies.rb +25 -0
- data/menus/couch.rb +184 -0
- data/menus/crop.rb +45 -0
- data/menus/css.rb +55 -0
- data/menus/current.rb +5 -0
- data/menus/db.rb +12 -0
- data/menus/deck.rb +219 -0
- data/menus/dictionary.rb +9 -0
- data/menus/dir.rb +8 -0
- data/menus/disk.rb +5 -0
- data/menus/do.rb +13 -0
- data/menus/docs.rb +58 -0
- data/menus/dotsies.rb +107 -0
- data/menus/edited.rb +18 -0
- data/menus/emacs.rb +17 -0
- data/menus/enter.rb +13 -0
- data/menus/eval.rb +17 -0
- data/menus/executable.rb +16 -0
- data/menus/filter.rb +46 -0
- data/menus/firefox.rb +607 -0
- data/menus/foo.rb +30 -0
- data/menus/french.rb +7 -0
- data/menus/git.rb +185 -0
- data/menus/gito.rb +785 -0
- data/menus/google.rb +35 -0
- data/menus/google_images.rb +11 -0
- data/menus/google_patents.rb +10 -0
- data/menus/gutenberg.rb +13 -0
- data/menus/head.rb +10 -0
- data/menus/headings.rb +39 -0
- data/menus/html.rb +61 -0
- data/menus/icon.rb +40 -0
- data/menus/images.menu +2 -0
- data/menus/img.rb +15 -0
- data/menus/info.rb +9 -0
- data/menus/ip.rb +10 -0
- data/menus/iterm.rb +36 -0
- data/menus/itunes.rb +78 -0
- data/menus/javascript.rb +74 -0
- data/menus/layout.rb +18 -0
- data/menus/local_storage.rb +67 -0
- data/menus/ls.rb +19 -0
- data/menus/mac.rb +87 -0
- data/menus/maps.rb +18 -0
- data/menus/matches.rb +18 -0
- data/menus/memcache.rb +117 -0
- data/menus/mkdir.rb +23 -0
- data/menus/mongo.rb +83 -0
- data/menus/mysql.rb +294 -0
- data/menus/node.rb +88 -0
- data/menus/open.rb +19 -0
- data/menus/outline.rb +24 -0
- data/menus/piano.rb +746 -0
- data/menus/postgres.rb +34 -0
- data/menus/pre.rb +5 -0
- data/menus/python.rb +39 -0
- data/menus/rails.rb +160 -0
- data/menus/rake.rb +12 -0
- data/menus/redmine.rb +168 -0
- data/menus/riak_tree.rb +204 -0
- data/menus/rss.rb +15 -0
- data/menus/safari.rb +11 -0
- data/menus/sass.rb +15 -0
- data/menus/say.rb +6 -0
- data/menus/scale.rb +49 -0
- data/menus/serve.rb +78 -0
- data/menus/shuffle.rb +24 -0
- data/menus/spanish.rb +7 -0
- data/menus/standalone.rb +57 -0
- data/menus/tail.rb +41 -0
- data/menus/technologies.rb +19 -0
- data/menus/themes.rb +32 -0
- data/menus/thesaurus.rb +13 -0
- data/menus/to.rb +24 -0
- data/menus/twitter.rb +57 -0
- data/menus/wikipedia.rb +34 -0
- data/menus/words.rb +11 -0
- data/spec/code_tree_spec.rb +59 -0
- data/spec/diff_log_spec.rb +40 -0
- data/spec/file_tree_spec.rb +102 -0
- data/spec/keys_spec.rb +24 -0
- data/spec/line_spec.rb +68 -0
- data/spec/menu_spec.rb +50 -0
- data/spec/ol_spec.rb +98 -0
- data/spec/remote_spec.rb +43 -0
- data/spec/search_spec.rb +162 -0
- data/spec/text_util_spec.rb +119 -0
- data/spec/tree_cursor_spec.rb +91 -0
- data/spec/tree_spec.rb +955 -0
- data/tests/console_test.rb +11 -0
- data/tests/couch_db_test.rb +12 -0
- data/tests/diff_log_test.rb +43 -0
- data/tests/el_mixin.rb +16 -0
- data/tests/git_test.rb +95 -0
- data/tests/keys_test.rb +19 -0
- data/tests/line_test.rb +38 -0
- data/tests/merb_test.rb +11 -0
- data/tests/redmine_test.rb +50 -0
- data/tests/remote_test.rb +31 -0
- data/tests/rest_tree_test.rb +70 -0
- data/xiki.gemspec +37 -0
- metadata +332 -0
data/lib/color.rb
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
require 'effects'
|
|
2
|
+
require 'styles'
|
|
3
|
+
|
|
4
|
+
# Colors lines, and shows only colored lines
|
|
5
|
+
class Color
|
|
6
|
+
|
|
7
|
+
def self.menu
|
|
8
|
+
"
|
|
9
|
+
> Make current line be red, yellow, or blue
|
|
10
|
+
@Color.colorize :r
|
|
11
|
+
@Color.colorize :y
|
|
12
|
+
@Color.colorize :b
|
|
13
|
+
|
|
14
|
+
> See
|
|
15
|
+
<< themes/
|
|
16
|
+
<< styles/
|
|
17
|
+
"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@@colors = {
|
|
22
|
+
"r"=>:color_rb_red, "y"=>:color_rb_yellow,
|
|
23
|
+
"t"=>:color_rb_orange,
|
|
24
|
+
"e"=>:color_rb_green, "b"=>:color_rb_blue, "u"=>:color_rb_purple,
|
|
25
|
+
"l"=>:color_rb_light,
|
|
26
|
+
"w"=>:color_rb_white,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def self.colorize char=nil
|
|
30
|
+
char ||= Keys.input(:chars=>1, :prompt=>'Enter first letter of color: ')
|
|
31
|
+
char = char.to_s
|
|
32
|
+
# If h, just show all colors
|
|
33
|
+
case char
|
|
34
|
+
when "l"
|
|
35
|
+
# We want there to be only one "light" line per file, so delete existing
|
|
36
|
+
overlays = $el.overlays_in(View.top, View.bottom) # Get all overlays
|
|
37
|
+
overlays.to_a.reverse.each do |o| # Loop through and copy all
|
|
38
|
+
if $el.overlay_get(o, :face).to_s == "color-rb-light"
|
|
39
|
+
$el.delete_overlay(o)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
when "s" # Search in all buffers for marked lines
|
|
44
|
+
|
|
45
|
+
prefix = Keys.prefix
|
|
46
|
+
|
|
47
|
+
if prefix.nil?
|
|
48
|
+
light = $el.overlays_in(View.top, View.bottom).to_a.find{|o| $el.overlay_get(o, :face).to_s == "color-rb-light"}
|
|
49
|
+
return View.to($el.overlay_start(light)) if light
|
|
50
|
+
# Else, contine on and do Color.search
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
return Launcher.open("- Color.search/") if Keys.prefix == 8
|
|
54
|
+
|
|
55
|
+
# Presumably :u
|
|
56
|
+
Launcher.open("- Color.search 'light'/")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
when "o" # Outline of marked lines
|
|
60
|
+
res = self.get_marked_lines
|
|
61
|
+
res.gsub! /^/, " | "
|
|
62
|
+
|
|
63
|
+
file = View.file
|
|
64
|
+
path = file ?
|
|
65
|
+
"- #{File.expand_path(file).sub(/(.+)\//, "\\1/\n - ")}\n" :
|
|
66
|
+
"- buffer #{View.name}/\n"
|
|
67
|
+
|
|
68
|
+
View.to_buffer("*outline of marked in #{path}")
|
|
69
|
+
View.clear; Notes.mode
|
|
70
|
+
View.insert path
|
|
71
|
+
if res == " | "
|
|
72
|
+
return View.insert " - Nothing was marked in this file!"
|
|
73
|
+
end
|
|
74
|
+
View.insert res
|
|
75
|
+
Keys.clear_prefix
|
|
76
|
+
View.to_line 3
|
|
77
|
+
Line.to_beginning
|
|
78
|
+
|
|
79
|
+
Tree.search :left=> Line.left, :number_means_enter=>true
|
|
80
|
+
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
when "c" # Copy marked lines
|
|
84
|
+
|
|
85
|
+
res = self.get_marked_lines
|
|
86
|
+
|
|
87
|
+
Clipboard['0'] = res
|
|
88
|
+
|
|
89
|
+
when "h" # Hilight
|
|
90
|
+
prefix = Keys.prefix :clear=>1
|
|
91
|
+
|
|
92
|
+
ignore, left, right = View.txt_per_prefix prefix, :just_positions=>1, :default_is_line=>1
|
|
93
|
+
|
|
94
|
+
prefix == :u ?
|
|
95
|
+
Effects.glow(:color=>:rainbow, :times=>4) :
|
|
96
|
+
Effects.glow(:what=>[left, right], :times=>4)
|
|
97
|
+
|
|
98
|
+
# when "h" # Hide
|
|
99
|
+
# Hide.hide_unless_block { |l, bol, eol|
|
|
100
|
+
# # Whether current line contains an overlay of this color
|
|
101
|
+
# $el.overlays_in(bol, eol).to_a.find{ |o|
|
|
102
|
+
# $el.overlay_get(o, :face).to_s =~ /^color-rb-/
|
|
103
|
+
# }
|
|
104
|
+
# }
|
|
105
|
+
# recenter(-3)
|
|
106
|
+
# Hide.search
|
|
107
|
+
# return
|
|
108
|
+
when "n" # to next marker
|
|
109
|
+
# Keys.prefix_times do
|
|
110
|
+
pos = $el.next_overlay_change(View.cursor)
|
|
111
|
+
# end
|
|
112
|
+
# If no overlay, may be at end, so continue on
|
|
113
|
+
pos = $el.next_overlay_change(pos) unless $el.overlays_at(pos)
|
|
114
|
+
return View.to(pos)
|
|
115
|
+
when "p" # to next marker
|
|
116
|
+
pos = $el.previous_overlay_change(View.cursor)
|
|
117
|
+
pos = $el.previous_overlay_change(pos-2) if $el.overlays_at(pos-2)
|
|
118
|
+
return View.to pos
|
|
119
|
+
when "d"
|
|
120
|
+
overlays = $el.overlays_at($el.next_overlay_change($el.point_at_bol - 1))
|
|
121
|
+
return View.beep "- No highlights after cursor!" if ! overlays
|
|
122
|
+
return $el.delete_overlay(overlays[0])
|
|
123
|
+
when "k"
|
|
124
|
+
|
|
125
|
+
if Keys.prefix_u # Don't delete map mark
|
|
126
|
+
return $el.remove_overlays
|
|
127
|
+
end
|
|
128
|
+
overlays = $el.overlays_in(View.top, View.bottom) # Get all overlays
|
|
129
|
+
overlays.to_a.reverse.each do |o| # Loop through and copy all
|
|
130
|
+
if $el.overlay_get(o, :face).to_s != "color-rb-light"
|
|
131
|
+
$el.delete_overlay(o)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
when "a"
|
|
137
|
+
return self.alternating
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
case Keys.prefix
|
|
141
|
+
when :u # If C-u, use region
|
|
142
|
+
left, right = View.range
|
|
143
|
+
when nil # If nothing, do line
|
|
144
|
+
left, right = Line.left, Line.right+1
|
|
145
|
+
else # Else, get N lines
|
|
146
|
+
txt, left, right = View.txt_per_prefix
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
if ! @@colors[char]
|
|
150
|
+
return View.message "No char color for '#{char}'"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
over = $el.make_overlay(left, right)
|
|
154
|
+
$el.overlay_put over, :face, @@colors[char]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def self.alternating
|
|
158
|
+
orig = View.cursor
|
|
159
|
+
# Get region to cover
|
|
160
|
+
txt, left, right = View.txt_per_prefix
|
|
161
|
+
View.cursor = left
|
|
162
|
+
while(View.cursor < right)
|
|
163
|
+
Color.colorize_line :color_rb_light
|
|
164
|
+
Line.next 2
|
|
165
|
+
end
|
|
166
|
+
View.cursor = orig
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def self.colorize_line face
|
|
170
|
+
over = $el.make_overlay(Line.left, Line.right+1)
|
|
171
|
+
$el.overlay_put over, :face, face
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def self.define_styles # For Keys.layout_kolor_light, etc.
|
|
175
|
+
|
|
176
|
+
return if ! $el
|
|
177
|
+
|
|
178
|
+
# Orange path in mode line
|
|
179
|
+
# Blue path in mode line
|
|
180
|
+
# Styles.define :mode_line_dir, :fg=>"7ce", :size=>"0", :face=>"arial", :bold=>false
|
|
181
|
+
|
|
182
|
+
Styles.define :mode_line_file, :fg=>"fff", :size=>"0", :face=>"arial", :bold=>false
|
|
183
|
+
|
|
184
|
+
if Styles.inverse
|
|
185
|
+
Styles.define :mode_line_dir, :fg=>"d93", :size=>"0", :face=>"arial", :bold=>false # Brighter
|
|
186
|
+
|
|
187
|
+
Styles.define :color_rb_red, :bg => "500"
|
|
188
|
+
Styles.define :color_rb_orange, :bg => "442500"
|
|
189
|
+
Styles.define :color_rb_yellow, :bg => "440"
|
|
190
|
+
Styles.define :color_rb_green, :bg => "131"
|
|
191
|
+
Styles.define :color_rb_white, :fg=>'222', :bg=>'fff', :border=>['fff', -1]
|
|
192
|
+
|
|
193
|
+
Styles.define :color_rb_light, :bg => "252525"
|
|
194
|
+
|
|
195
|
+
Styles.define :color_rb_blue, :bg => "005"
|
|
196
|
+
Styles.define :color_rb_purple, :bg => "203"
|
|
197
|
+
|
|
198
|
+
else
|
|
199
|
+
|
|
200
|
+
Styles.define :mode_line_dir, :fg=>"ea4", :size=>"0", :face=>"arial", :bold=>false # Brighter
|
|
201
|
+
|
|
202
|
+
Styles.define :color_rb_red, :bg => "ffd5d5"
|
|
203
|
+
Styles.define :color_rb_orange, :bg => "ffe5bb"
|
|
204
|
+
Styles.define :color_rb_yellow, :bg => "f9f9aa"
|
|
205
|
+
Styles.define :color_rb_green, :bg => "e0ffcc"
|
|
206
|
+
Styles.define :color_rb_light, :bg => "ddd"
|
|
207
|
+
Styles.define :color_rb_white, :fg=>'222', :bg=>'666', :border=>['666', -1]
|
|
208
|
+
|
|
209
|
+
Styles.define :color_rb_blue, :bg => "dde5ff"
|
|
210
|
+
Styles.define :color_rb_purple, :bg => "f2ddff"
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
Styles.define :fade7, :fg => "333"
|
|
215
|
+
Styles.define :fade6, :fg => "555"
|
|
216
|
+
Styles.define :fade5, :fg => "777"
|
|
217
|
+
Styles.define :fade4, :fg => "999"
|
|
218
|
+
Styles.define :fade3, :fg => "bbb"
|
|
219
|
+
Styles.define :fade2, :fg => "ddd"
|
|
220
|
+
Styles.define :fade1, :fg => "fff"
|
|
221
|
+
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def self.get_marked_lines label=nil
|
|
225
|
+
overlays = $el.overlays_in(View.top, View.bottom) # Get all overlays
|
|
226
|
+
res = ""
|
|
227
|
+
overlays.to_a.reverse.each do |o| # Loop through and copy all
|
|
228
|
+
if label
|
|
229
|
+
next if $el.overlay_get(o, :face).to_s != label
|
|
230
|
+
end
|
|
231
|
+
line = View.txt($el.overlay_start(o), overlay_end(o))
|
|
232
|
+
line << "\n" unless line =~ /\n$/
|
|
233
|
+
res << line
|
|
234
|
+
end
|
|
235
|
+
res
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def self.search label=nil
|
|
239
|
+
label = "color-rb-#{label}" if label
|
|
240
|
+
|
|
241
|
+
orig = View.buffer
|
|
242
|
+
txt = ""
|
|
243
|
+
Buffers.list.to_a.each do |b| # Each buffer open
|
|
244
|
+
|
|
245
|
+
$el.set_buffer b
|
|
246
|
+
res = self.get_marked_lines label
|
|
247
|
+
next if res.empty?
|
|
248
|
+
|
|
249
|
+
file = View.file
|
|
250
|
+
next unless file
|
|
251
|
+
path = file ?
|
|
252
|
+
"@#{File.expand_path(file).sub(/(.+)\//, "\\1/\n - ")}\n" :
|
|
253
|
+
"- buffer #{View.name}/\n"
|
|
254
|
+
|
|
255
|
+
txt << path
|
|
256
|
+
txt << res.gsub!(/^/, " | ")
|
|
257
|
+
|
|
258
|
+
end
|
|
259
|
+
View.to_buffer orig
|
|
260
|
+
txt
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# Returns list of colors at cursor
|
|
265
|
+
# Color.at_cursor
|
|
266
|
+
def self.at_cursor
|
|
267
|
+
overlays = $el.overlays_in(Line.left, Line.right)
|
|
268
|
+
overlays = overlays.to_a.reverse.inject([]) do |a, o| # Loop through and copy all
|
|
269
|
+
a.push $el.overlay_get(o, :face).to_s
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
end
|
|
274
|
+
Color.define_styles
|
data/lib/console.rb
ADDED
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
|
|
3
|
+
class Console
|
|
4
|
+
|
|
5
|
+
@@log = File.expand_path("~/.emacs.d/console_log.notes")
|
|
6
|
+
|
|
7
|
+
def self.menu
|
|
8
|
+
%`
|
|
9
|
+
- .log/
|
|
10
|
+
- .tree/
|
|
11
|
+
- .history/
|
|
12
|
+
- api/
|
|
13
|
+
| In console (asynchronously)
|
|
14
|
+
@ Console.run "ls"
|
|
15
|
+
@ Console.run "ls", :dir=>"/tmp"
|
|
16
|
+
|
|
17
|
+
| Inline (synchronously)
|
|
18
|
+
@ Console.sync "ls"
|
|
19
|
+
@ Console.sync "ls", :dir=>"/etc"
|
|
20
|
+
- docs/
|
|
21
|
+
You can run shell commands by typing things like this...
|
|
22
|
+
|
|
23
|
+
> In current dir
|
|
24
|
+
@ $ ls
|
|
25
|
+
|
|
26
|
+
> In other dir
|
|
27
|
+
@ /tmp/
|
|
28
|
+
$ ls
|
|
29
|
+
|
|
30
|
+
> Async, in any open console view
|
|
31
|
+
@ /tmp/
|
|
32
|
+
% ls
|
|
33
|
+
|
|
34
|
+
> Async, in other dir
|
|
35
|
+
@ /tmp/
|
|
36
|
+
% ls
|
|
37
|
+
|
|
38
|
+
> Async, in iTerm
|
|
39
|
+
@ /tmp/
|
|
40
|
+
& ls
|
|
41
|
+
|
|
42
|
+
> Commands you've run recently
|
|
43
|
+
<< log/
|
|
44
|
+
|
|
45
|
+
> Commands from currently open consoles
|
|
46
|
+
<< tree/
|
|
47
|
+
`
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.log
|
|
51
|
+
View.open @@log
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Run the command in a console
|
|
55
|
+
def self.[] command
|
|
56
|
+
self.run command, :sync=>1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.sync command, options={}
|
|
60
|
+
self.run command, options.merge(:sync=>1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Runs shell command asynchronously.
|
|
65
|
+
#
|
|
66
|
+
# Console.run "ls"
|
|
67
|
+
# Console.run "ls", :dir=>"/tmp/"
|
|
68
|
+
#
|
|
69
|
+
def self.run command, options={}
|
|
70
|
+
|
|
71
|
+
dir = options[:dir]
|
|
72
|
+
sync = options[:sync]
|
|
73
|
+
buffer = options[:buffer]
|
|
74
|
+
reuse_buffer = options[:reuse_buffer]
|
|
75
|
+
|
|
76
|
+
# Nil out dir if blank
|
|
77
|
+
dir = nil if dir && dir.length == 0
|
|
78
|
+
|
|
79
|
+
if dir
|
|
80
|
+
dir = Bookmarks.expand(dir)
|
|
81
|
+
# If relative dir, make current dir be on end of current
|
|
82
|
+
dir = "#{$el.elvar.default_directory}/#{dir}" unless dir =~ /^\//
|
|
83
|
+
dir.gsub!(/\/\/+/, '/')
|
|
84
|
+
|
|
85
|
+
# If file, but not dir, try backing up to the dir
|
|
86
|
+
raise "- Directory '#{dir}' doesn't exist!" if ! File.exists? dir
|
|
87
|
+
|
|
88
|
+
dir.sub!(/[^\/]+$/, '') if ! File.directory?(dir)
|
|
89
|
+
|
|
90
|
+
# If dir exists, continue
|
|
91
|
+
if File.directory?(dir)
|
|
92
|
+
# Put slash on end if not there
|
|
93
|
+
dir = "#{dir}/" unless dir =~ /\/$/
|
|
94
|
+
else # Otherwise, exit
|
|
95
|
+
return puts("#{dir} is not a dir")
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
dir = $el ? $el.elvar.default_directory : "/tmp/"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if sync
|
|
102
|
+
|
|
103
|
+
return command if options[:no_enter]
|
|
104
|
+
profile = File.exists?(File.expand_path('~/.profile')) ? '. ~/.profile;' : ''
|
|
105
|
+
stdin, stdout, stderr = Open3.popen3("#{profile}cd \"#{dir}\";#{command}")
|
|
106
|
+
result = ""
|
|
107
|
+
result << stdout.readlines.join('')
|
|
108
|
+
result << stderr.readlines.join('')
|
|
109
|
+
result.gsub!("\c@", '.') # Replace out characters that el4r can't handle
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
else
|
|
113
|
+
if View.in_bar? and ! options[:dont_leave_bar]
|
|
114
|
+
View.to_after_bar
|
|
115
|
+
end
|
|
116
|
+
buffer ||= "*console #{dir}"
|
|
117
|
+
|
|
118
|
+
if ! reuse_buffer
|
|
119
|
+
buffer = $el.generate_new_buffer(buffer)
|
|
120
|
+
end
|
|
121
|
+
View.to_buffer buffer
|
|
122
|
+
$el.erase_buffer if reuse_buffer
|
|
123
|
+
$el.elvar.default_directory = dir if dir
|
|
124
|
+
$el.shell $el.current_buffer
|
|
125
|
+
Move.bottom
|
|
126
|
+
if command # If nil, just open console
|
|
127
|
+
$el.insert command
|
|
128
|
+
Console.enter unless options[:no_enter]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
nil
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def self.open dir=nil
|
|
136
|
+
View.handle_bar
|
|
137
|
+
dir ||= $el.elvar.default_directory
|
|
138
|
+
dir = File.expand_path(dir)+"/"
|
|
139
|
+
View.to_buffer $el.generate_new_buffer("shell")
|
|
140
|
+
raise "dir '#{dir}' doesn't exist" unless File.directory?(dir)
|
|
141
|
+
$el.elvar.default_directory = dir
|
|
142
|
+
$el.shell $el.current_buffer
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def self.enter command=nil
|
|
146
|
+
View.insert command if command
|
|
147
|
+
|
|
148
|
+
begin
|
|
149
|
+
$el.comint_send_input
|
|
150
|
+
rescue
|
|
151
|
+
# Ol << "Console.enter error here!"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self.console?
|
|
156
|
+
View.mode == :shell_mode
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.to_shell_buffer dir=nil, options={}
|
|
160
|
+
if dir
|
|
161
|
+
dir = "#{dir}/" unless dir =~ /\/$/
|
|
162
|
+
pattern = /^\*console #{Regexp.quote(dir)}(<| |$)/
|
|
163
|
+
else
|
|
164
|
+
# If already in a shell (regardless of buffer name)
|
|
165
|
+
return true if View.mode == :shell_mode
|
|
166
|
+
pattern = /^\*console/
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
return true if View.name =~ pattern # If already there, do nothing
|
|
170
|
+
|
|
171
|
+
if ! dir
|
|
172
|
+
|
|
173
|
+
# Try to find visible shell buffer in same dir and with prompt
|
|
174
|
+
|
|
175
|
+
View.list.each do |w|
|
|
176
|
+
$el.set_buffer $el.window_buffer(w)
|
|
177
|
+
next if View.mode != :shell_mode || ! Console.prompt?
|
|
178
|
+
next if View.cursor != View.bottom
|
|
179
|
+
View.to_window(w)
|
|
180
|
+
return true
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
if dir && dir !~ /@/ # If local dir
|
|
185
|
+
|
|
186
|
+
# TODO Make sure there's no ssh or cd in history!
|
|
187
|
+
View.list.each do |w|
|
|
188
|
+
$el.set_buffer $el.window_buffer(w)
|
|
189
|
+
next if View.mode != :shell_mode || ! Console.prompt?
|
|
190
|
+
next if Tree.slashless(dir) != Tree.slashless(View.dir)
|
|
191
|
+
next if View.cursor != View.bottom
|
|
192
|
+
|
|
193
|
+
View.to_window(w)
|
|
194
|
+
return true
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# TODO: implement similar finding a dir for remote
|
|
198
|
+
# else
|
|
199
|
+
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Deprecated:
|
|
203
|
+
# Try to find visible shell buffer with matching name
|
|
204
|
+
View.list.each do |w|
|
|
205
|
+
next if $el.buffer_name($el.window_buffer w) !~ pattern
|
|
206
|
+
View.to_window(w)
|
|
207
|
+
return true
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
if Keys.prefix_u(:clear=>true)
|
|
211
|
+
|
|
212
|
+
found = Buffers.list.find do |b|
|
|
213
|
+
name = Buffers.name b
|
|
214
|
+
next false unless name =~ pattern
|
|
215
|
+
|
|
216
|
+
view = nil
|
|
217
|
+
$el.with(:save_window_excursion) do
|
|
218
|
+
View.to_buffer name
|
|
219
|
+
|
|
220
|
+
next false unless Console.prompt?
|
|
221
|
+
|
|
222
|
+
cd_dir = View.dir
|
|
223
|
+
cd_dir = "#{cd_dir}/" unless cd_dir =~ /\/$/
|
|
224
|
+
next false unless cd_dir == dir
|
|
225
|
+
next false if Console.commands.join("\n") =~ /^(ssh|ftp) /
|
|
226
|
+
true
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
if found
|
|
231
|
+
View.to_upper
|
|
232
|
+
return View.to_buffer(found)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Wasn't found among visible, so create new buffer
|
|
237
|
+
|
|
238
|
+
return false if options[:no_create] # Don't create it if option says not to
|
|
239
|
+
|
|
240
|
+
if dir =~ /@/ # If there's a @, it's remote
|
|
241
|
+
View.handle_bar
|
|
242
|
+
View.to_buffer $el.generate_new_buffer("*console #{dir}")
|
|
243
|
+
$el.elvar.default_directory = "/tmp"
|
|
244
|
+
$el.shell $el.current_buffer
|
|
245
|
+
if dir =~ /(.+?)(\/.+)/ # Split off dir if there
|
|
246
|
+
line = self.ssh_line($1)
|
|
247
|
+
Console.enter line
|
|
248
|
+
options[:cd_and_wait] ?
|
|
249
|
+
View.insert("cd #{$2} && ") :
|
|
250
|
+
Console.enter("cd #{$2}")
|
|
251
|
+
else
|
|
252
|
+
line = self.ssh_line(dir)
|
|
253
|
+
Console.enter line
|
|
254
|
+
end
|
|
255
|
+
else
|
|
256
|
+
Console.open dir
|
|
257
|
+
end
|
|
258
|
+
return true
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def self.do_last_command
|
|
262
|
+
# Code.open_log_view if Keys.prefix_u
|
|
263
|
+
|
|
264
|
+
orig = View.index
|
|
265
|
+
|
|
266
|
+
found = self.to_shell_buffer(nil, :no_create=>true) # If not in shell buffer, go to it
|
|
267
|
+
|
|
268
|
+
return View.message("No *console buffer was visible") unless found
|
|
269
|
+
|
|
270
|
+
$el.erase_buffer
|
|
271
|
+
$el.comint_previous_input(1)
|
|
272
|
+
self.enter
|
|
273
|
+
View.to_nth orig
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def self.launch_async options={}
|
|
277
|
+
|
|
278
|
+
orig = Location.new
|
|
279
|
+
orig_view = View.index
|
|
280
|
+
path = Tree.construct_path(:list=>true)
|
|
281
|
+
|
|
282
|
+
path[0] = Bookmarks[path[0]] if path[0] =~ /^(\.\/|\$[\w-])/ # Expand out bookmark or ./, if there
|
|
283
|
+
if path[0] =~ /^\// # If has dir (local or remote)
|
|
284
|
+
line = path.join('')
|
|
285
|
+
dir, command = line.match(/(.+?)[%&] (.*)/)[1..2]
|
|
286
|
+
self.append_log "#{command}", dir, '% '
|
|
287
|
+
|
|
288
|
+
return Iterm.run("cd #{dir}\n#{command}", :activate=>1) if Keys.prefix_uu
|
|
289
|
+
return Iterm.run("cd #{dir}\n#{command}") if Keys.prefix_u || options[:iterm]
|
|
290
|
+
|
|
291
|
+
Console.to_shell_buffer dir, :cd_and_wait=>true
|
|
292
|
+
else # Otherwise, if by itself - meaning on own line?
|
|
293
|
+
command = Line.without_label.match(/.*?[%&] ?(.*)/)[1]
|
|
294
|
+
self.append_log("#{command}", dir, '% ') if command.present?
|
|
295
|
+
|
|
296
|
+
return Iterm.run("#{command}", :activate=>1) if Keys.prefix_uu
|
|
297
|
+
return Iterm.run("#{command}", :activate=>1) if Keys.prefix_u && options[:iterm]
|
|
298
|
+
return Iterm.run("#{command}") if Keys.prefix_u || options[:iterm]
|
|
299
|
+
|
|
300
|
+
self.to_shell_buffer # Go to shell if one is visible
|
|
301
|
+
end
|
|
302
|
+
return if command.empty?
|
|
303
|
+
|
|
304
|
+
View.to_bottom
|
|
305
|
+
|
|
306
|
+
View.insert command
|
|
307
|
+
Console.enter
|
|
308
|
+
|
|
309
|
+
orig.go unless orig_view == View.index
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Synchronous - mapped to $ launcher
|
|
313
|
+
def self.launch options={}
|
|
314
|
+
trunk = Xiki.trunk # use Tree.path instead
|
|
315
|
+
|
|
316
|
+
# If it looks like error output, just jump to it
|
|
317
|
+
if trunk[-1] =~ /[^\/+]\/\| \s+from / || trunk[-1] =~ /[^\/+]\/\| +\//
|
|
318
|
+
return Code.open_as_file
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# if not under file
|
|
322
|
+
# raise RelinquishException.new
|
|
323
|
+
|
|
324
|
+
# Run in current dir if no parent or @$
|
|
325
|
+
if trunk[-1] =~ /^\$ /
|
|
326
|
+
# TODO Run in current dir?
|
|
327
|
+
# return
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# There's a dir in our chunk, so relinquish control if not fire tree
|
|
331
|
+
|
|
332
|
+
# Handle if
|
|
333
|
+
# no parent in our chunk
|
|
334
|
+
# parent in our chunk is file tree
|
|
335
|
+
|
|
336
|
+
line = Line.without_label :leave_indent=>true
|
|
337
|
+
# If indented, check whether file tree, extracting if yes
|
|
338
|
+
if line =~ /^\s+\$/
|
|
339
|
+
orig = View.cursor
|
|
340
|
+
path = Tree.construct_path(:list=>true)
|
|
341
|
+
if path[0] =~ /@/ # If there's a @, it's remote
|
|
342
|
+
self.append_log path[1], path[0]
|
|
343
|
+
return Remote.command path
|
|
344
|
+
end
|
|
345
|
+
if FileTree.handles?(path)
|
|
346
|
+
while(path.last =~ /^\$/) do # Remove all !foo lines from path
|
|
347
|
+
path.pop
|
|
348
|
+
end
|
|
349
|
+
dir = path.join('')
|
|
350
|
+
|
|
351
|
+
# If starts with ./, replace with current dir
|
|
352
|
+
dir.sub! /^\.\//, "#{View.dir}/"
|
|
353
|
+
|
|
354
|
+
end
|
|
355
|
+
View.to orig
|
|
356
|
+
end
|
|
357
|
+
line =~ / *@? ?(.*?)\$+ ?(.+)/
|
|
358
|
+
dir ||= $1 unless $1.empty?
|
|
359
|
+
command = $2
|
|
360
|
+
|
|
361
|
+
return Tree.<<("- Directory doesn't exist) #{dir}") if dir && ! File.exists?(dir)
|
|
362
|
+
|
|
363
|
+
if options[:sync]
|
|
364
|
+
output = Console.run command, :dir=>dir, :sync=>true
|
|
365
|
+
output.sub!(/\A\z/, "\n") # Add linebreak if blank
|
|
366
|
+
Keys.prefix == 1 ? output.gsub!(/^/, '|') : output.gsub!(/^/, '| ').gsub!(/^\| +$/, '|')
|
|
367
|
+
|
|
368
|
+
# Expose "!" and "- label: !" lines as commands
|
|
369
|
+
output.gsub!(/^\| \$/, '$')
|
|
370
|
+
output.gsub!(/^\| (- [\w ,-]+: \$)/, "\\1")
|
|
371
|
+
output.sub! /\n*\z/, "\n" # Guarantee exactly 1 linebreak at end
|
|
372
|
+
Tree.indent(output)
|
|
373
|
+
|
|
374
|
+
Tree.insert_quoted_and_search output
|
|
375
|
+
else
|
|
376
|
+
View.handle_bar
|
|
377
|
+
Console.run command, :dir=>dir #, :buffer=>"*console #{dir}"
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
self.append_log command, dir, '$ '
|
|
381
|
+
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def self.append_log command, dir, prefix=''
|
|
385
|
+
return if View.name =~ /_log.notes$/
|
|
386
|
+
if dir.nil?
|
|
387
|
+
dir ||= View.dir
|
|
388
|
+
dir = "#{dir}/" if dir !~ /\/$/
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
command = command.dup
|
|
392
|
+
command.gsub!(/^/, prefix) unless command =~ /^ *!/
|
|
393
|
+
command.gsub!(/^/, ' ')
|
|
394
|
+
|
|
395
|
+
txt = "- #{dir}\n#{command}\n"
|
|
396
|
+
File.open(@@log, "a") { |f| f << txt } rescue nil
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
def self.ssh_line path
|
|
400
|
+
path = path.sub /^\//, ''
|
|
401
|
+
path.sub! /\/$/, ''
|
|
402
|
+
|
|
403
|
+
if path =~ /(.+):(.+)/ # If port exists (colon)
|
|
404
|
+
"ssh -p #{$2} #{$1}"
|
|
405
|
+
# Pull out and pass with -p
|
|
406
|
+
else
|
|
407
|
+
"ssh -A #{path}"
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def self.do_as_execute options={}
|
|
412
|
+
|
|
413
|
+
if FileTree.handles? && ! Line.matches(/^\s*\|/) # If we're in a file tree
|
|
414
|
+
path = Tree.construct_path
|
|
415
|
+
|
|
416
|
+
# # Run command inside of dir
|
|
417
|
+
# if Line.matches(/\/$/) # If a dir
|
|
418
|
+
# command = Keys.input :prompt=>"Do shell command on '#{file}': "
|
|
419
|
+
# output = Console.run(command, :dir=>path, :sync=>true)
|
|
420
|
+
# FileTree.insert_under(output) if options[:insert]
|
|
421
|
+
# return View.message "Command ran with output: #{output.strip}."
|
|
422
|
+
# elsif Keys.prefix_n
|
|
423
|
+
# View.message "Running command on multiple files isn't implemented yet."
|
|
424
|
+
# return
|
|
425
|
+
# end
|
|
426
|
+
|
|
427
|
+
file = Line.without_label
|
|
428
|
+
command = Keys.input :prompt=>"Shell command on this file (_ means the filename): "
|
|
429
|
+
command = command =~ /\b_\b/ ? command.gsub(/\b_\b/, "\"#{file}\"") : "#{command} \"#{file}\""
|
|
430
|
+
|
|
431
|
+
output = Console.run(command, :dir=>File.dirname(path), :sync=>true)
|
|
432
|
+
Tree.under(output, :escape=>'| ') if options[:insert]
|
|
433
|
+
|
|
434
|
+
return View.message "Command ran with output: #{output.strip}."
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
command = Keys.input :prompt=>"Do shell command on '#{View.file_name}': "
|
|
438
|
+
command = "#{command} #{View.file_name}"
|
|
439
|
+
output = Console.run(command, :dir=>View.dir, :sync=>true)
|
|
440
|
+
View.insert(output) if options[:insert]
|
|
441
|
+
|
|
442
|
+
return View.message "Command ran with output: #{output.strip}."
|
|
443
|
+
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Whether buffer ends with shell prompt "...$ "
|
|
447
|
+
def self.prompt?
|
|
448
|
+
right = View.bottom
|
|
449
|
+
left = right - 10
|
|
450
|
+
left = 1 if left < 1
|
|
451
|
+
txt = View.txt left, right
|
|
452
|
+
|
|
453
|
+
txt =~ /[>#%$] \z/
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def self.history bm
|
|
457
|
+
|
|
458
|
+
dir = Bookmarks[bm]
|
|
459
|
+
dir = Files.dir_of dir
|
|
460
|
+
|
|
461
|
+
console_log = IO.read(@@log)
|
|
462
|
+
|
|
463
|
+
result = []
|
|
464
|
+
match = false
|
|
465
|
+
console_log.split("\n").each do |l|
|
|
466
|
+
if l =~ /^[+-] /
|
|
467
|
+
next match = l =~ /\A- #{Regexp.escape dir}/
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
result << "#{l}" if match
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
"@ #{dir}\n"+result.reverse.uniq.join("\n")+"\n"
|
|
474
|
+
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def self.commands
|
|
478
|
+
matches = $el.elvar.comint_input_ring.to_s.scan(/#\("(.+?)" /).flatten
|
|
479
|
+
|
|
480
|
+
matches.map!{|o| o.gsub '\\"', '"'}
|
|
481
|
+
matches
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def self.custom_history
|
|
485
|
+
dir = View.dir
|
|
486
|
+
history = Console.commands
|
|
487
|
+
history.uniq! unless Keys.prefix_u
|
|
488
|
+
history = history.join("\n").gsub(/^/, '% ')
|
|
489
|
+
View.create :u if ! View.list_names.member?("*shell history")
|
|
490
|
+
View.to_buffer "*shell history"
|
|
491
|
+
View.kill_all
|
|
492
|
+
Notes.mode
|
|
493
|
+
|
|
494
|
+
View.insert "#{history}\n"
|
|
495
|
+
View.to_highest
|
|
496
|
+
Tree.search
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def self.search_last_commands
|
|
500
|
+
bm = Keys.input(:timed => true, :prompt => "bookmark to show commands for (space for currently open): ")
|
|
501
|
+
return Launcher.open("- console/tree/") if bm == " "
|
|
502
|
+
if bm == "8"
|
|
503
|
+
Console.log; View.to_bottom; Search.isearch nil, :reverse=>true
|
|
504
|
+
return
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
Launcher.open("- console/history/$#{bm}/")
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def self.tree *args
|
|
511
|
+
command = args.pop if args[-1] =~ /^\|/
|
|
512
|
+
console = args.any? ? args.join("/") : nil
|
|
513
|
+
|
|
514
|
+
if console
|
|
515
|
+
View.to_buffer console#.sub /\/$/, ''
|
|
516
|
+
return
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
txt = ""
|
|
520
|
+
|
|
521
|
+
$el.with(:save_excursion) do
|
|
522
|
+
|
|
523
|
+
Buffers.list.each do |b|
|
|
524
|
+
next if $el.buffer_file_name b
|
|
525
|
+
name = $el.buffer_name b
|
|
526
|
+
$el.set_buffer b
|
|
527
|
+
next if $el.elvar.major_mode.to_s != 'shell-mode'
|
|
528
|
+
|
|
529
|
+
next if name == "*ol"
|
|
530
|
+
|
|
531
|
+
txt << "- #{name}/\n"
|
|
532
|
+
self.commands.reverse.each do |h|
|
|
533
|
+
txt << " | $ #{h}\n"
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
txt
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def self.exit # Kills running server or process in shell
|
|
542
|
+
$el.comint_interrupt_subjob
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
def self.wait_until buffer, options={}
|
|
546
|
+
max = options[:max] || 10
|
|
547
|
+
message = options[:message] || "Launching..."
|
|
548
|
+
while View.txt(:buffer=>buffer) !~ options[:contains]
|
|
549
|
+
View.flash message, :times=>1
|
|
550
|
+
max -= 1
|
|
551
|
+
break if max < 0
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
Keys.custom_history(:shell_mode_map) { Console.custom_history }
|