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/tree_cursor.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
class TreeCursor
|
|
2
|
+
@i = 0
|
|
3
|
+
@txt = ""
|
|
4
|
+
|
|
5
|
+
def initialize txt, i=0
|
|
6
|
+
raise "1st parameter to TreeCursor.initialize must be a string" unless txt.is_a? String
|
|
7
|
+
@i = i
|
|
8
|
+
@txt = txt
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
"[#{@i}, #{@txt.inspect}]"
|
|
13
|
+
end
|
|
14
|
+
def inspect
|
|
15
|
+
to_s
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def i; @i; end
|
|
19
|
+
def i= num; @i = num; end
|
|
20
|
+
def txt; @txt; end
|
|
21
|
+
|
|
22
|
+
def to_a
|
|
23
|
+
@txt.strip.split("\n", -1)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def length
|
|
27
|
+
@txt.strip.count("\n") + 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def line
|
|
31
|
+
to_a[@i]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def each &block
|
|
35
|
+
@i = 0
|
|
36
|
+
while @i < length
|
|
37
|
+
# while @i < @txt.split("\n").length
|
|
38
|
+
block.call
|
|
39
|
+
@i += 1
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def at_leaf?
|
|
44
|
+
a = to_a
|
|
45
|
+
following_line = a[@i+1]
|
|
46
|
+
return true if following_line.nil?
|
|
47
|
+
|
|
48
|
+
indent = Line.indent a[@i]
|
|
49
|
+
following_indent = Line.indent a[@i+1]
|
|
50
|
+
indent.length >= following_indent.length
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def [] index
|
|
54
|
+
to_a[index]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def select line
|
|
58
|
+
line = line.sub /^( *)\+ /, "\\1- "
|
|
59
|
+
index = to_a.index{|o| o.sub(/^( *)\+ /, "\\1- ") == line}
|
|
60
|
+
@i = index if index
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def under
|
|
64
|
+
result = ""
|
|
65
|
+
a = to_a
|
|
66
|
+
target_indent = Line.indent(a[@i]).length
|
|
67
|
+
i = @i + 1
|
|
68
|
+
while i < length
|
|
69
|
+
indent = Line.indent(a[i]).length
|
|
70
|
+
break if indent <= target_indent
|
|
71
|
+
result << "#{a[i]}\n"
|
|
72
|
+
i += 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
result
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def index_after
|
|
79
|
+
to_a[0..@i].join("\n").length
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def << lines
|
|
83
|
+
@txt.insert index_after+1, lines
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class TroubleShooting
|
|
2
|
+
def self.keys
|
|
3
|
+
return if ! $el
|
|
4
|
+
|
|
5
|
+
$el.el4r_lisp_eval '
|
|
6
|
+
(progn
|
|
7
|
+
(global-set-key (kbd "M-l") (lambda () (interactive)
|
|
8
|
+
"Load .emacs (reloading EmacsRuby)"
|
|
9
|
+
(switch-to-buffer "*el4r:process*")
|
|
10
|
+
(kill-buffer "*el4r:process*")
|
|
11
|
+
(load-file "~/.emacs")
|
|
12
|
+
))
|
|
13
|
+
(global-set-key (kbd "M-e") (lambda () (interactive)
|
|
14
|
+
"Go to EmacsRuby error"
|
|
15
|
+
(find-file el4r-log-path)
|
|
16
|
+
(revert-buffer t t t)
|
|
17
|
+
(setq truncate-lines nil)
|
|
18
|
+
(end-of-buffer)
|
|
19
|
+
(re-search-backward "^ from ")
|
|
20
|
+
(re-search-backward "^[A-Z]")
|
|
21
|
+
(recenter 0)
|
|
22
|
+
))
|
|
23
|
+
)
|
|
24
|
+
'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
TroubleShooting.keys
|
data/lib/url_tree.rb
ADDED
data/lib/view.rb
ADDED
|
@@ -0,0 +1,1474 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Represents a division of a window (in emacs terms, it's a window (which is within a frame))
|
|
3
|
+
#
|
|
4
|
+
class View
|
|
5
|
+
|
|
6
|
+
def self.menu
|
|
7
|
+
%`
|
|
8
|
+
<< @window/
|
|
9
|
+
- .flashes/
|
|
10
|
+
- api/
|
|
11
|
+
> Summary
|
|
12
|
+
| View class is the catch-all class for dealing with editing text.
|
|
13
|
+
| It has methods for inserting text and grabbing text, and quite a few
|
|
14
|
+
| other things.
|
|
15
|
+
|
|
16
|
+
> Text
|
|
17
|
+
@View << 'Hello' # Inserts into the view.
|
|
18
|
+
@p View.txt # Return all the text.
|
|
19
|
+
@p View.txt 1, 5 # Return text in a range.
|
|
20
|
+
@p View.cursor # Return where the cursor is.
|
|
21
|
+
@p View.line # Returns the line number the cursor is on.
|
|
22
|
+
|
|
23
|
+
> Files and dirs
|
|
24
|
+
@p View.name # Returns file name.
|
|
25
|
+
@p View.file # Returns file with whole path.
|
|
26
|
+
@p View.dir # Returns dir of file.
|
|
27
|
+
@View.open "/tmp/" # Opens file in the first view, (switching to it if it's already open)
|
|
28
|
+
@View.open nil, :txt=>"Hi" # Show message in new buffer.
|
|
29
|
+
|
|
30
|
+
> Messages
|
|
31
|
+
@View.flash # Shows temporary message inline.
|
|
32
|
+
@View.flash 'Saved'
|
|
33
|
+
@View.message 'Hi there' # Shows message at bottom.
|
|
34
|
+
@View.prompt # Prompt user to type at end af line.
|
|
35
|
+
@View.prompt 'Type here'
|
|
36
|
+
@View.beep # Makes a noise.
|
|
37
|
+
|
|
38
|
+
> Advanced
|
|
39
|
+
@View.<< "hey", :dont_move=>1 # Without moving cursor
|
|
40
|
+
|
|
41
|
+
> Also see
|
|
42
|
+
<< line/
|
|
43
|
+
|
|
44
|
+
- docs/
|
|
45
|
+
> Summary
|
|
46
|
+
| Menus to deal with the layout, etc.
|
|
47
|
+
|
|
48
|
+
- Keys/
|
|
49
|
+
| layout+create - TODO should we just refer to a @layout menu for these?
|
|
50
|
+
`
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Stores things user copies
|
|
54
|
+
@@hash = {}
|
|
55
|
+
|
|
56
|
+
def self.windows_in_my_column
|
|
57
|
+
my_left = left_edge
|
|
58
|
+
$el.window_list(nil, nil, $el.frame_first_window).to_a.select { |w| left_edge(w) == my_left }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Make current window larger. Take into account that there might be other vertical windows
|
|
62
|
+
def self.height
|
|
63
|
+
$el.window_height
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.frame_height= chars
|
|
67
|
+
$el.set_frame_parameter nil, :height, chars
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.frame_width= chars
|
|
71
|
+
$el.set_frame_parameter nil, :width, chars
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.frame_height options={}
|
|
75
|
+
return $el.frame_parameter(nil, :height) if options.empty?
|
|
76
|
+
return unless options.is_a?(Hash)
|
|
77
|
+
|
|
78
|
+
if options[:add]
|
|
79
|
+
self.frame_height = self.frame_height + 1
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.frame_width options={}
|
|
86
|
+
return $el.frame_parameter(nil, :width) if options.empty?
|
|
87
|
+
return unless options.is_a?(Hash)
|
|
88
|
+
|
|
89
|
+
if options[:add]
|
|
90
|
+
self.frame_width = self.frame_width + 1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.screen_width options={}
|
|
97
|
+
$el.x_display_pixel_width
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.screen_height options={}
|
|
101
|
+
$el.x_display_pixel_height
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def self.enlarge height=nil
|
|
106
|
+
default_height = 3
|
|
107
|
+
small = Keys.prefix || height || default_height
|
|
108
|
+
small = default_height if small == :u
|
|
109
|
+
|
|
110
|
+
small += 1
|
|
111
|
+
|
|
112
|
+
# If universal prefix and in bar, widen bar
|
|
113
|
+
self.balance if Keys.prefix_u and View.bar?
|
|
114
|
+
|
|
115
|
+
ws = self.windows_in_my_column
|
|
116
|
+
|
|
117
|
+
wnum = ws.length # Get number of windows
|
|
118
|
+
|
|
119
|
+
usable_height = $el.frame_height - 1 - wnum
|
|
120
|
+
|
|
121
|
+
biggest = usable_height - ((wnum-1) * (small-1))
|
|
122
|
+
selected = $el.selected_window
|
|
123
|
+
|
|
124
|
+
# Do multiple times (emacs daesn't get it right he first time)
|
|
125
|
+
5.times do
|
|
126
|
+
self.enlarge_internal :up, ws, selected, biggest, small
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.enlarge_internal direction, ws, selected, biggest, small
|
|
133
|
+
ws = ws.reverse if direction != :up
|
|
134
|
+
|
|
135
|
+
ws.each do |w|
|
|
136
|
+
# If current window, set to remaining
|
|
137
|
+
if w == selected
|
|
138
|
+
height = biggest # - 1
|
|
139
|
+
$el.set_window_text_height w, height
|
|
140
|
+
else
|
|
141
|
+
height = small - 1
|
|
142
|
+
$el.set_window_text_height w, height
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Creates a new window by splitting the current one
|
|
148
|
+
def self.create prefix=nil
|
|
149
|
+
prefix ||= Keys.prefix
|
|
150
|
+
if prefix == 3 # If prefix is 3, do Vertical split
|
|
151
|
+
$el.split_window_horizontally
|
|
152
|
+
View.next
|
|
153
|
+
elsif prefix == 4
|
|
154
|
+
$el.split_window_vertically
|
|
155
|
+
Keys.clear_prefix
|
|
156
|
+
View.next
|
|
157
|
+
View.enlarge
|
|
158
|
+
elsif prefix == :u
|
|
159
|
+
$el.split_window_vertically
|
|
160
|
+
else
|
|
161
|
+
$el.split_window_vertically
|
|
162
|
+
View.next
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def self.show_txt txt, options={}
|
|
167
|
+
View.to_buffer(options[:name] || "message")
|
|
168
|
+
View.kill_all
|
|
169
|
+
Notes.mode
|
|
170
|
+
View << "#{txt.strip}\n"
|
|
171
|
+
View.to_highest
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# Opens file (or whatever) from the path (can contain $bookmarks), just
|
|
176
|
+
# moving to or exposing its view if it's already open.
|
|
177
|
+
# By default it will open in 2nd view if we're in the bar view.
|
|
178
|
+
#
|
|
179
|
+
# View.open "/etc/paths"
|
|
180
|
+
# View.open "hello", :txt=>"> Hi\nMessage to show in new buffer."
|
|
181
|
+
#
|
|
182
|
+
def self.open path, options={}
|
|
183
|
+
|
|
184
|
+
return self.show_txt(options[:txt], :name=>path) if options[:txt]
|
|
185
|
+
|
|
186
|
+
# Pull off line number if there
|
|
187
|
+
path.sub!(/(.+?:\d+).*/, "\\1")
|
|
188
|
+
line_number = path.slice!(/:\d+$/)
|
|
189
|
+
|
|
190
|
+
# Open after bar if in bar
|
|
191
|
+
if View.in_bar? && (! options[:stay_in_bar]) && path != "$0" && path != Bookmarks['$t'] && path != Bookmarks['$f']
|
|
192
|
+
View.to_after_bar
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Expand $bookmark strings at beginning
|
|
196
|
+
expanded = Bookmarks.expand(path)
|
|
197
|
+
if expanded == "" # If nothing there, return false
|
|
198
|
+
path.sub!(/^- /, '')
|
|
199
|
+
if path =~ /^\$\w+$/
|
|
200
|
+
buffer = Bookmarks.buffer_bookmark path.sub(/^\$/, '')
|
|
201
|
+
View.to_buffer buffer if buffer
|
|
202
|
+
end
|
|
203
|
+
return nil
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
if expanded # Handle opening in other window
|
|
207
|
+
if options[:same_view]
|
|
208
|
+
$el.find_file expanded
|
|
209
|
+
elsif expanded == $el.buffer_file_name # If already there
|
|
210
|
+
# do nothing
|
|
211
|
+
elsif ( ( $el.window_list.collect {|b| $el.window_buffer b} ).collect {|u| $el.buffer_file_name u} ).member?(expanded) # If already displayed, move to its window
|
|
212
|
+
$el.find_file_other_window expanded
|
|
213
|
+
else # If not visible, just open it
|
|
214
|
+
$el.find_file expanded
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Jump to point if :goto_point (we assume path is just a bookmark)
|
|
219
|
+
if options[:go_to_point] == true
|
|
220
|
+
$el.bookmark_jump path.sub(/^\$/, "")
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
if line_number
|
|
224
|
+
View.to_line line_number[/\d+/]
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Saves the configuration
|
|
229
|
+
def self.save name=nil
|
|
230
|
+
name ||= Keys.input(:optional => true)
|
|
231
|
+
name ||= "0"
|
|
232
|
+
@@hash[name] = $el.current_window_configuration
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Saves the configuration
|
|
236
|
+
def self.restore name=nil
|
|
237
|
+
name ||= Keys.input(:optional => true) # Get single key from user if no param
|
|
238
|
+
name ||= "0" # Set to "0" if user entered nothing
|
|
239
|
+
# Todo: if "l", winner_undo
|
|
240
|
+
if(name == "l")
|
|
241
|
+
$el.winner_undo
|
|
242
|
+
return
|
|
243
|
+
end
|
|
244
|
+
# Use it to get configuration out of hash
|
|
245
|
+
$el.set_window_configuration(@@hash[name])
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Return list of windows
|
|
249
|
+
def self.list
|
|
250
|
+
$el.window_list(nil, nil, $el.frame_first_window).to_a
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def self.list_names
|
|
254
|
+
self.list.map{|v| $el.buffer_name $el.window_buffer(v)}
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def self.files options={}
|
|
258
|
+
if options[:visible]
|
|
259
|
+
return $el.window_list.
|
|
260
|
+
map {|b| $el.window_buffer b}.
|
|
261
|
+
collect {|u| $el.buffer_file_name u}.
|
|
262
|
+
select {|f| f}
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
Buffers.list.map { |b| $el.buffer_file_name(b) }.select{|path| path}
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Move to nth window
|
|
269
|
+
def self.to_nth_paragraph n
|
|
270
|
+
View.to_relative
|
|
271
|
+
|
|
272
|
+
if Line.blank? && ! Line.value(2).blank? # Weird case when just one blank line at top
|
|
273
|
+
n -= 1
|
|
274
|
+
Line.next if n == 0
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
n.times { Move.to_next_paragraph }
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def self.to_nth n
|
|
281
|
+
# If greater than size of windows, open last
|
|
282
|
+
#insert self.list.size.to_s
|
|
283
|
+
if n+1 > self.list.size
|
|
284
|
+
return $el.select_window(self.list.last)
|
|
285
|
+
end
|
|
286
|
+
# Otherwise, open nth
|
|
287
|
+
$el.select_window(self.list[n])
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def self.[] n
|
|
291
|
+
self.nth n
|
|
292
|
+
end
|
|
293
|
+
def self.nth n
|
|
294
|
+
orig = View.window
|
|
295
|
+
View.to_nth n
|
|
296
|
+
win = View.window
|
|
297
|
+
View.to_window orig
|
|
298
|
+
win
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def self.file_of_nth n
|
|
302
|
+
orig = View.window
|
|
303
|
+
View.to_nth n
|
|
304
|
+
file = View.file
|
|
305
|
+
View.to_window orig
|
|
306
|
+
file
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def self.buffer_of_nth n
|
|
310
|
+
window = View.window
|
|
311
|
+
View.to_nth n
|
|
312
|
+
buffer = $el.window_buffer
|
|
313
|
+
View.to_window window
|
|
314
|
+
buffer
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def self.dir_of_nth n
|
|
318
|
+
window = View.window
|
|
319
|
+
View.to_nth n
|
|
320
|
+
dir = View.dir
|
|
321
|
+
View.to_window window
|
|
322
|
+
dir
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def self.dir_of_after_bar
|
|
326
|
+
window = View.window
|
|
327
|
+
View.to_after_bar
|
|
328
|
+
dir = View.dir
|
|
329
|
+
View.to_window window
|
|
330
|
+
dir
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Open the bar
|
|
334
|
+
def self.bar
|
|
335
|
+
# If bar already there, just go to it
|
|
336
|
+
if self.bar?
|
|
337
|
+
View.to_nth(0)
|
|
338
|
+
return
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Remember buffers and heights
|
|
342
|
+
orig = []
|
|
343
|
+
self.list.each do |w|
|
|
344
|
+
orig << [$el.window_buffer(w), $el.window_height(w)]
|
|
345
|
+
end
|
|
346
|
+
$el.delete_other_windows
|
|
347
|
+
|
|
348
|
+
$el.split_window_horizontally 48 # Width of bar
|
|
349
|
+
# $el.split_window_horizontally 28 # Width of bar
|
|
350
|
+
|
|
351
|
+
# split_window_horizontally 32 # Width of bar
|
|
352
|
+
# split_window_horizontally 54 # Width of bar
|
|
353
|
+
|
|
354
|
+
$el.other_window 1
|
|
355
|
+
o = nil
|
|
356
|
+
# For each window but last
|
|
357
|
+
orig[0..-2].each do |w|
|
|
358
|
+
$el.switch_to_buffer w[0]
|
|
359
|
+
$el.split_window_vertically
|
|
360
|
+
$el.set_window_text_height nil, w[1]
|
|
361
|
+
o = $el.other_window 1
|
|
362
|
+
end
|
|
363
|
+
# Last window
|
|
364
|
+
$el.switch_to_buffer orig[-1][0]
|
|
365
|
+
$el.set_window_text_height o, orig[-1][1]
|
|
366
|
+
# Go to first window
|
|
367
|
+
$el.select_window self.first
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Returns whether bar is open
|
|
371
|
+
def self.bar?
|
|
372
|
+
$el.window_width(self.first) < $el.frame_width
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# Returns whether we're in the bar
|
|
376
|
+
def self.in_bar?
|
|
377
|
+
self.bar? && # Bar is open
|
|
378
|
+
View.edges[0] == 0 # Window is at left of frame
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def self.first
|
|
382
|
+
$el.frame_first_window
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def self.last
|
|
386
|
+
View.list[-1]
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Accounts for bar
|
|
390
|
+
def self.balance
|
|
391
|
+
$el.balance_windows
|
|
392
|
+
return if Keys.prefix_u
|
|
393
|
+
if self.bar?
|
|
394
|
+
buffer = $el.selected_window
|
|
395
|
+
$el.select_window $el.frame_first_window
|
|
396
|
+
# enlarge_window (31 - window_width), true
|
|
397
|
+
# enlarge_window (48 - window_width), true
|
|
398
|
+
|
|
399
|
+
$el.enlarge_window((42 - $el.window_width), true)
|
|
400
|
+
# $el.enlarge_window((22 - $el.window_width), true)
|
|
401
|
+
|
|
402
|
+
$el.select_window buffer
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Returns true if anything is hidden
|
|
407
|
+
def self.hidden?
|
|
408
|
+
$el.point_min != 1 || $el.point_max != $el.buffer_size+1
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def self.hide
|
|
412
|
+
Keys.prefix_times.times do
|
|
413
|
+
left = View.left_edge
|
|
414
|
+
|
|
415
|
+
# If there's one above me and before me
|
|
416
|
+
index = View.index
|
|
417
|
+
middle = false
|
|
418
|
+
size = View.list.size
|
|
419
|
+
if index > 0 && index < (size - 1) # Check existance
|
|
420
|
+
if( left == View.left_edge(View.list[index - 1]) &&
|
|
421
|
+
left == View.left_edge(View.list[index + 1]) ) # Check alignment
|
|
422
|
+
middle = true
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
# If I'm the last
|
|
426
|
+
last = index == (size - 1)
|
|
427
|
+
|
|
428
|
+
$el.delete_window
|
|
429
|
+
$el.previous_multiframe_window if View.left_edge != left || middle || last
|
|
430
|
+
end
|
|
431
|
+
nil
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
def self.hide_others options={}
|
|
435
|
+
if $el.elvar.current_prefix_arg || self.in_bar? || options[:all]
|
|
436
|
+
return $el.delete_other_windows
|
|
437
|
+
end
|
|
438
|
+
ws = self.windows_in_my_column
|
|
439
|
+
selected = $el.selected_window
|
|
440
|
+
# New height should be window minus 2 for each window
|
|
441
|
+
ws.each do |w|
|
|
442
|
+
# If current window, set to remaining
|
|
443
|
+
unless w == selected
|
|
444
|
+
$el.delete_window w
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def self.next options={}
|
|
450
|
+
(Keys.prefix_times || options[:times] || 1).times do
|
|
451
|
+
$el.other_window 1
|
|
452
|
+
end
|
|
453
|
+
Effects.blink(:what=>:line) if options[:blink]
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def self.previous options={}
|
|
457
|
+
(Keys.prefix_times || options[:times] || 1).times do
|
|
458
|
+
$el.other_window -1
|
|
459
|
+
end
|
|
460
|
+
Effects.blink(:what=>:line) if options[:blink]
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def self.show_dir
|
|
464
|
+
($el.elvar.current_prefix_arg || 1).times do
|
|
465
|
+
$el.dired_jump
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
# Return selected text (aka the "region")
|
|
470
|
+
def self.selection options={}
|
|
471
|
+
txt = $el.buffer_substring($el.region_beginning, $el.region_end)
|
|
472
|
+
$el.delete_region($el.point, $el.mark) if options[:delete]
|
|
473
|
+
txt
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def self.range
|
|
477
|
+
[$el.region_beginning, $el.region_end]
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def self.range_left
|
|
481
|
+
$el.region_beginning
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def self.range_right
|
|
485
|
+
$el.region_end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def self.buffer
|
|
489
|
+
$el.window_buffer
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Return currently-selected window
|
|
493
|
+
def self.current
|
|
494
|
+
$el.selected_window
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
# Move to window
|
|
498
|
+
def self.to_window window
|
|
499
|
+
$el.select_window(window)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def self.open_in_bar
|
|
503
|
+
# Remember buffer
|
|
504
|
+
buffer = self.buffer
|
|
505
|
+
|
|
506
|
+
# If already open, just go there
|
|
507
|
+
if View.bar?
|
|
508
|
+
$el.select_window(View.first)
|
|
509
|
+
else
|
|
510
|
+
View.bar
|
|
511
|
+
end
|
|
512
|
+
View.to_buffer buffer
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def self.open_in_right
|
|
516
|
+
# Remember buffer
|
|
517
|
+
buffer = self.buffer
|
|
518
|
+
|
|
519
|
+
View.bar unless View.bar? # If not open yet, open it
|
|
520
|
+
# Go to after bar
|
|
521
|
+
View.to_after_bar
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def self.handle_bar
|
|
525
|
+
self.to_after_bar if self.in_bar?
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
def self.to_upper options={}
|
|
529
|
+
down = Keys.prefix_times - 1
|
|
530
|
+
Keys.clear_prefix
|
|
531
|
+
View.to_after_bar
|
|
532
|
+
|
|
533
|
+
# If there's only one column (last view is at left), go to top
|
|
534
|
+
Move.to_window(1) if self.edges[0] == 0
|
|
535
|
+
down.times { View.next }
|
|
536
|
+
Effects.blink(:what=>:line) if options[:blink]
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
def self.to_after_bar
|
|
540
|
+
return unless self.bar?
|
|
541
|
+
|
|
542
|
+
# Get width of last window
|
|
543
|
+
width_of_last = $el.window_width(self.last)
|
|
544
|
+
|
|
545
|
+
# Go to first window not on left margin
|
|
546
|
+
self.list.each do |w|
|
|
547
|
+
if self.edges(w)[0] != 0 # Window is at left of frame
|
|
548
|
+
$el.select_window(w)
|
|
549
|
+
break
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def self.left_edge view=nil
|
|
555
|
+
view ||= $el.selected_window # Default to current view
|
|
556
|
+
self.edges(view)[0]
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def self.top_edge view=nil
|
|
560
|
+
view ||= $el.selected_window # Default to current view
|
|
561
|
+
self.edges(view)[1]
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
# Switches to a buffer
|
|
565
|
+
def self.to_buffer name, options={}
|
|
566
|
+
return if $el.buffer_name == name # If we're here already, do nothing
|
|
567
|
+
|
|
568
|
+
found = View.list.find do |w|
|
|
569
|
+
$el.buffer_name($el.window_buffer(w)) == name
|
|
570
|
+
end
|
|
571
|
+
found ? View.to_window(found) : $el.switch_to_buffer(name)
|
|
572
|
+
|
|
573
|
+
View.clear if options[:clear]
|
|
574
|
+
View.dir = options[:dir] if options[:dir]
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
def self.txt options={}, right=nil
|
|
578
|
+
|
|
579
|
+
options.is_a?(Hash) && buffer = options[:buffer] and return Buffers.txt(buffer)
|
|
580
|
+
|
|
581
|
+
# If 2nd arg is there, we were passed right,left
|
|
582
|
+
if right
|
|
583
|
+
left = options
|
|
584
|
+
else
|
|
585
|
+
left = options[:left] || $el.point_min
|
|
586
|
+
right = options[:right] || $el.point_max
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
# If :utf8 option, write to file via elisp and read via ruby (for correct encoding)
|
|
590
|
+
if options.is_a?(Hash) && options[:utf8]
|
|
591
|
+
# Write to file via elisp
|
|
592
|
+
$el.write_region left, right, "/tmp/utf.txt", nil
|
|
593
|
+
|
|
594
|
+
# Read via ruby (so correct encoding is obtained)
|
|
595
|
+
return File.read("/tmp/utf.txt")
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
$el.buffer_substring left, right
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
# Returns text from view according to prefix...
|
|
602
|
+
# - 3 means 3 lines, etc.
|
|
603
|
+
# - no prefix means the notes block
|
|
604
|
+
# - etc
|
|
605
|
+
def self.txt_per_prefix prefix=nil, options={}
|
|
606
|
+
prefix ||= Keys.prefix(:clear=>1)
|
|
607
|
+
|
|
608
|
+
prefix = prefix.abs if prefix.is_a?(Fixnum)
|
|
609
|
+
left, right = [nil, nil]
|
|
610
|
+
|
|
611
|
+
case prefix
|
|
612
|
+
when 0 # Do paragraph
|
|
613
|
+
left, right = View.paragraph(:bounds=>true)
|
|
614
|
+
when 1..6 # Should probably catch all numeric prefix?
|
|
615
|
+
left = Line.left
|
|
616
|
+
right = $el.point_at_bol(prefix+1)
|
|
617
|
+
when :-
|
|
618
|
+
left, right = View.range if options[:selection]
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
# If no prefixes
|
|
622
|
+
if left == nil
|
|
623
|
+
if options[:default_is_line]
|
|
624
|
+
left, right = [Line.left, Line.right]
|
|
625
|
+
else
|
|
626
|
+
ignore, left, right = View.block_positions("^>")
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
Effects.blink(:left=>left, :right=>right) if options[:blink]
|
|
631
|
+
txt = options[:just_positions] ? nil : View.txt(left, right)
|
|
632
|
+
|
|
633
|
+
if options[:remove_heading] && txt =~ /^>/
|
|
634
|
+
txt.sub! /.+\n/, ''
|
|
635
|
+
# left won't be fixed, but who cares, for now
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
return txt if options[:just_txt]
|
|
639
|
+
|
|
640
|
+
return [txt, left, right]
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
# Returns bounds of block in the form [left, after_header, right].
|
|
644
|
+
def self.block_positions regex="^> "
|
|
645
|
+
|
|
646
|
+
orig = $el.point
|
|
647
|
+
# Go to the end of the line, so if we're at the heading we'll find it
|
|
648
|
+
Line.end
|
|
649
|
+
found = $el.re_search_backward regex, nil, 1
|
|
650
|
+
if found
|
|
651
|
+
left = $el.point
|
|
652
|
+
after_header = Line.left 2
|
|
653
|
+
else
|
|
654
|
+
left = after_header = $el.point
|
|
655
|
+
end
|
|
656
|
+
Line.end
|
|
657
|
+
$el.re_search_forward regex, nil, 1
|
|
658
|
+
right = ($el.point == $el.point_max) ? $el.point_max : Line.left
|
|
659
|
+
$el.goto_char orig
|
|
660
|
+
|
|
661
|
+
[left, after_header, right]
|
|
662
|
+
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
def self.to_highest
|
|
666
|
+
prefix = Keys.prefix
|
|
667
|
+
return self.to_line(prefix) if(prefix) # If prefix, go to that line
|
|
668
|
+
self.to_top
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
def self.to_top
|
|
672
|
+
$el.beginning_of_buffer
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
def self.to_bottom
|
|
676
|
+
$el.end_of_buffer
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
def self.at_bottom
|
|
680
|
+
self.cursor == self.bottom
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
def self.to_end
|
|
684
|
+
$el.end_of_buffer
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
def self.beginning
|
|
688
|
+
$el.point_min
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
def self.top
|
|
692
|
+
$el.point_min
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
def self.bottom
|
|
696
|
+
$el.point_max
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
def self.clear name=nil
|
|
700
|
+
if name
|
|
701
|
+
if View.buffer_visible?(name)
|
|
702
|
+
View.to_buffer(name)
|
|
703
|
+
View.clear
|
|
704
|
+
end
|
|
705
|
+
return
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
$el.erase_buffer
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
def self.dir force_slash=nil
|
|
712
|
+
# TODO: merge with .path?
|
|
713
|
+
result = File.expand_path($el.elvar.default_directory)
|
|
714
|
+
|
|
715
|
+
if force_slash
|
|
716
|
+
return result =~ /\/$/ ? result : "#{result}/"
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
result
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
def self.dir= to
|
|
723
|
+
$el.elvar.default_directory = File.expand_path(to)+"/"
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
def self.file
|
|
727
|
+
file = $el.buffer_file_name
|
|
728
|
+
file ? File.expand_path(file) : nil
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
def self.extension
|
|
732
|
+
View.file[/\.(\w+)$/, 1]
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
def self.file_or_buffer
|
|
736
|
+
self.file || self.name
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
def self.file_name
|
|
740
|
+
$el.buffer_file_name ?
|
|
741
|
+
$el.file_name_nondirectory($el.buffer_file_name) :
|
|
742
|
+
nil
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
def self.path options={}
|
|
746
|
+
# TODO: merge with .dir?
|
|
747
|
+
$el.elvar.default_directory
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
def self.frame
|
|
751
|
+
$el.window_frame($el.frame_first_window)
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
def self.window
|
|
755
|
+
$el.selected_window
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
# Returns whether a buffer is open / exists
|
|
759
|
+
def self.buffer_open? name
|
|
760
|
+
Buffers.list.find{|b| $el.buffer_name(b) == name}
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
def self.buffer_visible? name
|
|
764
|
+
View.list.
|
|
765
|
+
collect {|b| $el.window_buffer b}.
|
|
766
|
+
collect {|u| $el.buffer_name u}.
|
|
767
|
+
member?(name)
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
def self.wrap on_or_off=:on
|
|
771
|
+
$el.elvar.truncate_lines = on_or_off.to_sym == :off
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
# Call this at startup to set some sensible view-related default behavior
|
|
775
|
+
def self.sensible_defaults
|
|
776
|
+
$el.el4r_lisp_eval("(progn (setq truncate-partial-width-windows nil)
|
|
777
|
+
(set 'default-truncate-lines t)
|
|
778
|
+
)")
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
def self.set_mark pos=nil
|
|
782
|
+
pos ||= self.cursor
|
|
783
|
+
$el.set_mark pos
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
def self.mark= pos=nil
|
|
787
|
+
self.set_mark pos
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
def self.insert txt, options={}
|
|
791
|
+
if options[:utf8]
|
|
792
|
+
File.open("/tmp/tmp.txt", "w") {|f| f << txt}
|
|
793
|
+
orig = $el.elvar.coding_system_for_read # Read file as utf-8
|
|
794
|
+
$el.elvar.coding_system_for_read = 'utf-8'.to_sym
|
|
795
|
+
$el.insert_file_contents "/tmp/tmp.txt"
|
|
796
|
+
|
|
797
|
+
# breaks when utf8 - doesn't go far enaugh??!
|
|
798
|
+
# Maybe get length of file instead of string?
|
|
799
|
+
# Or, set encoding of buffer to utf8?
|
|
800
|
+
|
|
801
|
+
$el.elvar.coding_system_for_read = orig
|
|
802
|
+
Move.forward txt.size unless options[:dont_move] # .insert_file_contents leaves cursor at beginning
|
|
803
|
+
else
|
|
804
|
+
$el.insert txt
|
|
805
|
+
Move.backward txt.size if options[:dont_move]
|
|
806
|
+
end
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
def self.<< txt, options={}
|
|
810
|
+
self.insert txt, options
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def self.unindent txt
|
|
814
|
+
|
|
815
|
+
# Trim off optional first line
|
|
816
|
+
txt = txt.sub /^\n/, ''
|
|
817
|
+
# Get indent of first line
|
|
818
|
+
indent = txt[/\A +/]
|
|
819
|
+
# Delete this much indent on other lines
|
|
820
|
+
txt.gsub! /^#{indent}/, ''
|
|
821
|
+
# Delete empty space at end
|
|
822
|
+
txt.sub!(/ +\z/, '')
|
|
823
|
+
|
|
824
|
+
$el.insert txt
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
def self.empty?
|
|
828
|
+
$el.point_min == $el.point_max
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
def self.recenter n=nil
|
|
832
|
+
n ||= Keys.prefix
|
|
833
|
+
|
|
834
|
+
return View.recenter_under "^\\( *def \\| *it \\|^>\\)", :relative=>1 if n == :u
|
|
835
|
+
|
|
836
|
+
if n == :uu
|
|
837
|
+
return View.recenter_under "^\\( *def \\| *it \\|^>\\)", :relative=>1, :incude_comments=>1
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
$el.recenter n
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
#
|
|
844
|
+
# Scrolls window so top line matches pattern (first match above).
|
|
845
|
+
#
|
|
846
|
+
# View.recenter_under "^ *def "
|
|
847
|
+
#
|
|
848
|
+
def self.recenter_under pattern, options={}
|
|
849
|
+
orig = Location.new
|
|
850
|
+
Line.next
|
|
851
|
+
Search.backward pattern
|
|
852
|
+
|
|
853
|
+
# If :relative, search backward from here...
|
|
854
|
+
|
|
855
|
+
if options[:relative]
|
|
856
|
+
Move.to_previous_paragraph if options[:incude_comments] && Line.value(0) =~ /^ *#/
|
|
857
|
+
line = View.line
|
|
858
|
+
View.recenter_top
|
|
859
|
+
orig.go
|
|
860
|
+
difference = View.line - line
|
|
861
|
+
View.recenter -2 if difference > (View.height-3)
|
|
862
|
+
return
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
# Search from top...
|
|
866
|
+
|
|
867
|
+
View.to_highest
|
|
868
|
+
Search.forward pattern
|
|
869
|
+
Line.to_beginning
|
|
870
|
+
View.recenter_top
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
def self.recenter_top
|
|
874
|
+
$el.recenter 0
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
def self.rest
|
|
878
|
+
$el.buffer_substring($el.point, $el.point_max)
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
def self.to_line n=nil
|
|
882
|
+
Move.to_line n
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
def self.line= n=nil
|
|
886
|
+
self.to_line n
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
def self.to_line_with_prefix first=""
|
|
890
|
+
line = "#{first}#{Keys.input(:prompt=>"goto line: #{first}")}"
|
|
891
|
+
View.to_line line
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
def self.to n
|
|
895
|
+
$el.goto_char n
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
def self.focus
|
|
899
|
+
$el.x_focus_frame($el.selected_frame)
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
def self.index
|
|
903
|
+
View.list.index(View.window)
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
def self.count_matches
|
|
907
|
+
right = $el.buffer_size
|
|
908
|
+
left = 1
|
|
909
|
+
left = $el.point if Keys.prefix_u?
|
|
910
|
+
$el.message how_many(Keys.input('pattern to count: a'), left, right).to_s
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
def self.line
|
|
914
|
+
Line.number
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
def self.line_number
|
|
918
|
+
Line.number
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
def self.column
|
|
922
|
+
$el.point - $el.point_at_bol
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
def self.column= to
|
|
926
|
+
Move.to_column to
|
|
927
|
+
nil
|
|
928
|
+
end
|
|
929
|
+
|
|
930
|
+
def self.cursor
|
|
931
|
+
$el.point
|
|
932
|
+
end
|
|
933
|
+
def self.cursor= n
|
|
934
|
+
$el.goto_char n
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
def self.visible_line_number
|
|
939
|
+
Line.number - Line.number($el.window_start) + 1
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
def self.visible_line_number= num
|
|
943
|
+
line = Line.number($el.window_start) + num - 1
|
|
944
|
+
View.line = line
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
#
|
|
948
|
+
# Delete string between two points, and returns deleted text.
|
|
949
|
+
#
|
|
950
|
+
# p View.delete 1, 10
|
|
951
|
+
# p View.delete :line
|
|
952
|
+
# p View.delete # Delete's selection (and returns it)
|
|
953
|
+
#
|
|
954
|
+
def self.delete left=nil, right=nil
|
|
955
|
+
return Line.delete if left == :line
|
|
956
|
+
|
|
957
|
+
# Default to deleting region
|
|
958
|
+
left, right = View.range if left.nil?
|
|
959
|
+
|
|
960
|
+
txt = $el.buffer_substring left, right
|
|
961
|
+
$el.delete_region left, right
|
|
962
|
+
txt
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
def self.char
|
|
966
|
+
$el.buffer_substring($el.point, $el.point+1)
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
def self.char_before
|
|
970
|
+
$el.buffer_substring($el.point-1, $el.point)
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
def self.scroll_bars= on
|
|
975
|
+
$el.toggle_scroll_bar on ? 1 : 0
|
|
976
|
+
end
|
|
977
|
+
|
|
978
|
+
def self.scroll_bars
|
|
979
|
+
$el.frame_parameter(nil, :vertical_scroll_bars) ? true : nil
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
def self.name
|
|
983
|
+
$el.buffer_name
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
def self.message txt, options={}
|
|
987
|
+
$el.message txt
|
|
988
|
+
View.beep if options[:beep]
|
|
989
|
+
|
|
990
|
+
nil
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
def self.alert txt
|
|
994
|
+
self.beep
|
|
995
|
+
self.message txt
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
# def self.beep options={}
|
|
999
|
+
def self.beep *args
|
|
1000
|
+
|
|
1001
|
+
# Pull out 1st arg if string
|
|
1002
|
+
txt = args[0].nil? || args[0].is_a?(Hash) ? nil : args.shift.to_s
|
|
1003
|
+
|
|
1004
|
+
options = args[0] || {}
|
|
1005
|
+
raise "Too many args" if args.size > 1
|
|
1006
|
+
|
|
1007
|
+
$el.beep
|
|
1008
|
+
if times = options[:times]
|
|
1009
|
+
(times-1).times do
|
|
1010
|
+
View.pause 0.11
|
|
1011
|
+
View.beep
|
|
1012
|
+
end
|
|
1013
|
+
end
|
|
1014
|
+
View.flash txt, :times=>6 if txt
|
|
1015
|
+
|
|
1016
|
+
options[:return_txt] ? txt : nil
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
def self.mode
|
|
1020
|
+
$el.elvar.major_mode.to_s.gsub('-','_').to_sym
|
|
1021
|
+
end
|
|
1022
|
+
|
|
1023
|
+
def self.init
|
|
1024
|
+
@@dimension_options ||= [] # Set to empty if not set yet
|
|
1025
|
+
$el.winner_mode 1 rescue nil
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
def self.paragraph options={}
|
|
1029
|
+
orig = Location.new
|
|
1030
|
+
found = Search.backward "^$", :go_anyway=>true
|
|
1031
|
+
Line.next if found
|
|
1032
|
+
left = Line.left
|
|
1033
|
+
Search.forward "^$", :go_anyway=>true
|
|
1034
|
+
right = Line.right
|
|
1035
|
+
orig.go
|
|
1036
|
+
left = Line.left if options[:start_here]
|
|
1037
|
+
|
|
1038
|
+
return [left, right] if options[:bounds]
|
|
1039
|
+
txt = View.txt(left, right)
|
|
1040
|
+
View.delete(left, right) if options[:delete]
|
|
1041
|
+
return [left, right] if options[:bounds]
|
|
1042
|
+
txt
|
|
1043
|
+
end
|
|
1044
|
+
|
|
1045
|
+
def self.url txt
|
|
1046
|
+
$el.browse_url txt
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
def self.kill
|
|
1050
|
+
$el.kill_this_buffer
|
|
1051
|
+
nil
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
def self.kill_all
|
|
1055
|
+
$el.erase_buffer
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
def self.kill_paragraph
|
|
1059
|
+
left, right = View.paragraph(:bounds => true)
|
|
1060
|
+
Effects.blink(:left=>left, :right=>right)
|
|
1061
|
+
View.delete(left, right)
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
def self.expand_path path
|
|
1065
|
+
path = "#{View.dir}/#{path}" if path !~ /^[\/~]/
|
|
1066
|
+
|
|
1067
|
+
# Expand ~
|
|
1068
|
+
|
|
1069
|
+
had_slash = path =~ /\/$/ # Check whether / at end
|
|
1070
|
+
|
|
1071
|
+
# This cleans up /./ nad /../ in paths as side-effect of above
|
|
1072
|
+
path = File.expand_path path
|
|
1073
|
+
|
|
1074
|
+
path = "#{path}/" if had_slash && path !~ /\/$/ # Put / back at end, if it was there (and not there now)
|
|
1075
|
+
|
|
1076
|
+
path
|
|
1077
|
+
end
|
|
1078
|
+
|
|
1079
|
+
def self.dimensions_set size_x, size_y, position_x=nil, position_y=nil
|
|
1080
|
+
self.fullscreen_off
|
|
1081
|
+
$el.set_frame_size(View.frame, size_x, size_y)
|
|
1082
|
+
$el.set_frame_position(View.frame, position_x, position_y) unless position_x.nil?
|
|
1083
|
+
nil
|
|
1084
|
+
end
|
|
1085
|
+
|
|
1086
|
+
# Toggle full-screen mode
|
|
1087
|
+
def self.dimensions_full
|
|
1088
|
+
if $el.frame_parameter(nil, :fullscreen) # If fullscreen on turn it off
|
|
1089
|
+
$el.set_frame_parameter(nil, :fullscreen, nil)
|
|
1090
|
+
else # Else, turn it on
|
|
1091
|
+
self.fullscreen_on
|
|
1092
|
+
end
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
def self.fullscreen_off
|
|
1096
|
+
$el.set_frame_parameter(nil, :fullscreen, nil) if $el.frame_parameter(nil, :fullscreen)
|
|
1097
|
+
end
|
|
1098
|
+
|
|
1099
|
+
def self.fullscreen_on
|
|
1100
|
+
$el.set_frame_parameter nil, :fullscreen, :fullboth
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
# Line at top of visible part of view
|
|
1104
|
+
def self.start
|
|
1105
|
+
$el.window_start
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
def self.insert_line
|
|
1109
|
+
|
|
1110
|
+
orig_indent = Line.indent
|
|
1111
|
+
n = Keys.prefix # Check for numeric prefix
|
|
1112
|
+
|
|
1113
|
+
if n == 0
|
|
1114
|
+
n = nil
|
|
1115
|
+
Line.previous
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
Move.to_end if Line.before_cursor =~ /^ +$/ # If at awkward position, move
|
|
1119
|
+
|
|
1120
|
+
indent_txt = n ?
|
|
1121
|
+
(" " * n) :
|
|
1122
|
+
Line[/^[ |$~&%@\/\\#+!-]+/] || "" # No numeric prefix, so just grab this line's opening indent text
|
|
1123
|
+
|
|
1124
|
+
Deletes.delete_whitespace if ! Line.at_left? && ! Line.at_right?
|
|
1125
|
+
|
|
1126
|
+
Line.to_right if Line.at_left?
|
|
1127
|
+
|
|
1128
|
+
View.insert "\n#{indent_txt}"
|
|
1129
|
+
end
|
|
1130
|
+
|
|
1131
|
+
def self.shift
|
|
1132
|
+
times = Keys.prefix_times; Keys.clear_prefix
|
|
1133
|
+
|
|
1134
|
+
choice = Keys.input :chars=>1, :prompt=>"Move this view to: (n)ext, (p)revious"
|
|
1135
|
+
Effects.blink
|
|
1136
|
+
times.times do
|
|
1137
|
+
|
|
1138
|
+
buffer_a = View.buffer
|
|
1139
|
+
|
|
1140
|
+
# Go to other and switch to A
|
|
1141
|
+
choice == "n" ? View.next : View.previous
|
|
1142
|
+
buffer_b = View.buffer
|
|
1143
|
+
$el.switch_to_buffer buffer_a
|
|
1144
|
+
|
|
1145
|
+
# Go to first and switch to B
|
|
1146
|
+
choice == "n" ? View.previous : View.next
|
|
1147
|
+
$el.switch_to_buffer buffer_b
|
|
1148
|
+
|
|
1149
|
+
choice == "n" ? View.next : View.previous
|
|
1150
|
+
|
|
1151
|
+
end
|
|
1152
|
+
Effects.blink
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
def self.edges view=nil
|
|
1156
|
+
view ||= self.current
|
|
1157
|
+
$el.window_edges(view).to_a
|
|
1158
|
+
end
|
|
1159
|
+
|
|
1160
|
+
def self.layout_right nth=nil
|
|
1161
|
+
nth ||= Keys.prefix
|
|
1162
|
+
if nth # If numeric prefix, go to nth
|
|
1163
|
+
down = nth - 1
|
|
1164
|
+
self.to_after_bar
|
|
1165
|
+
# If there's only one column (last view is at left), go to top
|
|
1166
|
+
Move.to_window(1) if self.edges[0] == 0
|
|
1167
|
+
down.times { self.next }
|
|
1168
|
+
Effects.blink(:what=>:line)# if options[:blink]
|
|
1169
|
+
return
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
current = View.name
|
|
1173
|
+
|
|
1174
|
+
second_visible = Buffers.list.each{|b|
|
|
1175
|
+
name = $el.buffer_name(b)
|
|
1176
|
+
next unless name != current
|
|
1177
|
+
next unless self.buffer_visible?(name)
|
|
1178
|
+
next unless self.edges(get_buffer_window(b))[0] != 0 # Window is at left of frame
|
|
1179
|
+
break name # Found
|
|
1180
|
+
}
|
|
1181
|
+
self.to_buffer second_visible
|
|
1182
|
+
Effects.blink(:what=>:line)# if options[:blink]
|
|
1183
|
+
|
|
1184
|
+
end
|
|
1185
|
+
|
|
1186
|
+
def self.layout_todo options={}
|
|
1187
|
+
FileTree.open_in_bar
|
|
1188
|
+
Effects.blink(:what=>:line) unless options[:no_blink]
|
|
1189
|
+
end
|
|
1190
|
+
|
|
1191
|
+
def self.layout_files options={}
|
|
1192
|
+
FileTree.open_in_bar
|
|
1193
|
+
View.to_nth 1
|
|
1194
|
+
Effects.blink(:what=>:line) unless options[:no_blink]
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1197
|
+
def self.layout_output options={}
|
|
1198
|
+
# If current line has Ol., grab line and path
|
|
1199
|
+
|
|
1200
|
+
prefix = Keys.prefix
|
|
1201
|
+
|
|
1202
|
+
if options[:called_by_launch]
|
|
1203
|
+
prefix = nil
|
|
1204
|
+
end
|
|
1205
|
+
|
|
1206
|
+
View.layout_files if ! View.bar? # If not already showing bar, do it first, so it shows up on left
|
|
1207
|
+
|
|
1208
|
+
found = prefix != :u && ! options[:dont_highlight] && Line =~ /^ *Ol\b/ && OlHelper.source_to_output(View.file, Line.number)
|
|
1209
|
+
|
|
1210
|
+
orig = nil
|
|
1211
|
+
if prefix == :- # If want to keep cursor where it is
|
|
1212
|
+
return View.flash("- Not found!") if ! found
|
|
1213
|
+
orig = Location.new
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
Code.open_log_view options
|
|
1217
|
+
|
|
1218
|
+
if found
|
|
1219
|
+
if found >= (Line.number(View.bottom) - 1) # If too far back to be shown
|
|
1220
|
+
found = nil
|
|
1221
|
+
View.flash("- Not found!", :times=>1)
|
|
1222
|
+
else
|
|
1223
|
+
View.to_bottom
|
|
1224
|
+
Line.previous(found+1)
|
|
1225
|
+
end
|
|
1226
|
+
end
|
|
1227
|
+
|
|
1228
|
+
if found
|
|
1229
|
+
Color.colorize :l
|
|
1230
|
+
Effects.blink(:what=>:line)
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
if orig
|
|
1234
|
+
return orig.go
|
|
1235
|
+
end
|
|
1236
|
+
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
def self.split options={}
|
|
1240
|
+
options[:horizontally] ?
|
|
1241
|
+
$el.split_window_horizontally :
|
|
1242
|
+
$el.split_window_vertically
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
def self.to_relative
|
|
1246
|
+
if Keys.prefix == 0
|
|
1247
|
+
$el.goto_char window_end - 1
|
|
1248
|
+
Line.to_left
|
|
1249
|
+
return
|
|
1250
|
+
end
|
|
1251
|
+
$el.goto_char $el.window_start
|
|
1252
|
+
((Keys.prefix || 1) -1).times do
|
|
1253
|
+
Line.next
|
|
1254
|
+
end
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
def self.gsub! from, to
|
|
1258
|
+
with(:save_excursion) do
|
|
1259
|
+
View.to_highest
|
|
1260
|
+
$el.replace_regexp(from, to)
|
|
1261
|
+
end
|
|
1262
|
+
end
|
|
1263
|
+
|
|
1264
|
+
def self.enter_upper
|
|
1265
|
+
prefix = Keys.prefix :clear=>true
|
|
1266
|
+
orig = Location.new
|
|
1267
|
+
|
|
1268
|
+
View.layout_todo :no_blink=>true
|
|
1269
|
+
todo_orig = Location.new
|
|
1270
|
+
View.to_highest
|
|
1271
|
+
|
|
1272
|
+
View.line = prefix if prefix.is_a? Fixnum
|
|
1273
|
+
|
|
1274
|
+
line = Line.value
|
|
1275
|
+
if prefix == :u
|
|
1276
|
+
Line.delete
|
|
1277
|
+
|
|
1278
|
+
orig.line -= 1 if Bookmarks['$t'] == orig.file # If in $t, adjust position by how much is deleted
|
|
1279
|
+
end
|
|
1280
|
+
|
|
1281
|
+
todo_orig.go
|
|
1282
|
+
orig.go
|
|
1283
|
+
|
|
1284
|
+
View.insert line
|
|
1285
|
+
end
|
|
1286
|
+
|
|
1287
|
+
def self.scroll_position
|
|
1288
|
+
$el.line_number_at_pos($el.point) - $el.line_number_at_pos($el.window_start)
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
def self.scroll_position= pos
|
|
1292
|
+
$el.recenter pos
|
|
1293
|
+
end
|
|
1294
|
+
|
|
1295
|
+
def self.under txt, options={}
|
|
1296
|
+
options[:escape] = '' if options[:escape].nil?
|
|
1297
|
+
txt = CodeTree.returned_to_s txt
|
|
1298
|
+
Tree.under txt, options # .merge(:escape=>'')
|
|
1299
|
+
end
|
|
1300
|
+
|
|
1301
|
+
def self.>> txt
|
|
1302
|
+
View.<< txt, :dont_move=>1
|
|
1303
|
+
end
|
|
1304
|
+
|
|
1305
|
+
def self.enter_date
|
|
1306
|
+
$el.insert $el.elvar.current_prefix_arg ?
|
|
1307
|
+
Time.now.strftime("%Y-%m-%d %I:%M:%S%p").sub(' 0', ' ').downcase :
|
|
1308
|
+
Time.now.strftime("%Y-%m-%d")
|
|
1309
|
+
end
|
|
1310
|
+
|
|
1311
|
+
#
|
|
1312
|
+
# Makes message glow at end of line, and adds "/", like
|
|
1313
|
+
#
|
|
1314
|
+
# foo/Type something here
|
|
1315
|
+
# View.prompt
|
|
1316
|
+
# @ View.prompt/
|
|
1317
|
+
#
|
|
1318
|
+
def self.prompt message="Type something here", options={}
|
|
1319
|
+
ControlLock.disable
|
|
1320
|
+
|
|
1321
|
+
if ! Line.blank?
|
|
1322
|
+
Move.to_end
|
|
1323
|
+
View << "/" unless Line =~ /\/$/
|
|
1324
|
+
end
|
|
1325
|
+
|
|
1326
|
+
self.insert(message, :dont_move=>1)
|
|
1327
|
+
|
|
1328
|
+
left, right = self.cursor, Line.right
|
|
1329
|
+
Effects.glow({:what=>[left, right], :reverse=>1}.merge(options))
|
|
1330
|
+
self.delete left, right
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
return unless options[:timed]
|
|
1334
|
+
|
|
1335
|
+
View.<< message, :dont_move=>1
|
|
1336
|
+
|
|
1337
|
+
$el.elvar.inhibit_quit = true
|
|
1338
|
+
|
|
1339
|
+
# Wait for first, then loop until pause
|
|
1340
|
+
c = $el.read_char("")
|
|
1341
|
+
key = Keys.to_letter c
|
|
1342
|
+
View.delete View.cursor, Line.right # Delete temporary message
|
|
1343
|
+
View << key
|
|
1344
|
+
|
|
1345
|
+
while(c = $el.read_char("", nil, 0.35))
|
|
1346
|
+
key = Keys.to_letter c
|
|
1347
|
+
if c == 7 # C-g?
|
|
1348
|
+
Cursor.restore :before_input
|
|
1349
|
+
$el.elvar.inhibit_quit = nil
|
|
1350
|
+
$el.keyboard_quit
|
|
1351
|
+
end
|
|
1352
|
+
View << key
|
|
1353
|
+
end
|
|
1354
|
+
$el.elvar.inhibit_quit = nil
|
|
1355
|
+
end
|
|
1356
|
+
|
|
1357
|
+
def self.modified?
|
|
1358
|
+
$el.buffer_modified_p
|
|
1359
|
+
end
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
#
|
|
1363
|
+
# Makes message temporarily appear and glow, then go away, like:
|
|
1364
|
+
#
|
|
1365
|
+
# foo/
|
|
1366
|
+
# - Success!
|
|
1367
|
+
#
|
|
1368
|
+
def self.flash message=nil, options={}
|
|
1369
|
+
|
|
1370
|
+
was_modified = $el.buffer_modified_p
|
|
1371
|
+
|
|
1372
|
+
File.open("/tmp/flashes.log", "a") { |f| f << "#{message}\n" } if message
|
|
1373
|
+
|
|
1374
|
+
message ||= "- Success!"
|
|
1375
|
+
|
|
1376
|
+
orig = self.cursor
|
|
1377
|
+
indent = Line.indent
|
|
1378
|
+
|
|
1379
|
+
blank_line = Line[/^$/]
|
|
1380
|
+
|
|
1381
|
+
Line.next unless blank_line
|
|
1382
|
+
message = "#{message.strip}"
|
|
1383
|
+
message << "\n" unless blank_line
|
|
1384
|
+
message.gsub! /^/, "#{indent} "
|
|
1385
|
+
self.insert message, :dont_move=>1
|
|
1386
|
+
left, right = Line.left, Line.left+message.length
|
|
1387
|
+
self.cursor = orig
|
|
1388
|
+
|
|
1389
|
+
Effects.glow({:what=>[left, right], :reverse=>1, :times=>2}.merge(options))
|
|
1390
|
+
|
|
1391
|
+
self.delete left, right
|
|
1392
|
+
|
|
1393
|
+
self.cursor = orig
|
|
1394
|
+
|
|
1395
|
+
$el.not_modified if ! was_modified
|
|
1396
|
+
|
|
1397
|
+
nil
|
|
1398
|
+
end
|
|
1399
|
+
|
|
1400
|
+
def self.flashes
|
|
1401
|
+
txt = IO.readlines File.expand_path("/tmp/flashes.log") rescue return "- No messages flashed yet!"
|
|
1402
|
+
txt = txt.reverse.uniq.join
|
|
1403
|
+
end
|
|
1404
|
+
|
|
1405
|
+
def self.refresh
|
|
1406
|
+
$el.sit_for 0
|
|
1407
|
+
end
|
|
1408
|
+
|
|
1409
|
+
def self.pause n=0.5 # wait / sleep / sit
|
|
1410
|
+
$el.sit_for n
|
|
1411
|
+
end
|
|
1412
|
+
|
|
1413
|
+
#
|
|
1414
|
+
# Set small string in mode line.
|
|
1415
|
+
#
|
|
1416
|
+
# View.status "aa"
|
|
1417
|
+
# View.status nil
|
|
1418
|
+
# View.status "bb", :nth=>2
|
|
1419
|
+
# View.status "dotsies", :nth=>3
|
|
1420
|
+
# View.status :scale=>5
|
|
1421
|
+
# View.status :scale=>1
|
|
1422
|
+
# View.status :scale=>0
|
|
1423
|
+
# View.status :bars=>[2, 5] # Show 2 bars
|
|
1424
|
+
#
|
|
1425
|
+
def self.status val=nil, options={}
|
|
1426
|
+
|
|
1427
|
+
if !options && ! val || val == :docs # If nothing passed, show help message
|
|
1428
|
+
return "
|
|
1429
|
+
> Examples
|
|
1430
|
+
@View.status 'aa'
|
|
1431
|
+
@View.status :scale=>5
|
|
1432
|
+
@View.status 'abc', :nth=>3
|
|
1433
|
+
"
|
|
1434
|
+
end
|
|
1435
|
+
|
|
1436
|
+
options = val if val.is_a? Hash
|
|
1437
|
+
|
|
1438
|
+
nth = options[:nth] || 1
|
|
1439
|
+
|
|
1440
|
+
# If :bars=>[n, n]...
|
|
1441
|
+
|
|
1442
|
+
if bars = options[:bars]
|
|
1443
|
+
nth = 3
|
|
1444
|
+
|
|
1445
|
+
a, b = bars
|
|
1446
|
+
if a < b
|
|
1447
|
+
common, remainder, remainder_char = a, b - a, 'i'
|
|
1448
|
+
else
|
|
1449
|
+
common, remainder, remainder_char = b, a - b, 'f'
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
val = " #{"z" * common}#{remainder_char * remainder}"
|
|
1453
|
+
end
|
|
1454
|
+
|
|
1455
|
+
if scale = options[:scale]
|
|
1456
|
+
nth = 3
|
|
1457
|
+
val = {0=>' ', 1=>'e', 2=>'i', 3=>'v', 4=>'�', 5=>'�'}[scale]
|
|
1458
|
+
end
|
|
1459
|
+
|
|
1460
|
+
key = "xiki_status#{nth}".to_sym
|
|
1461
|
+
|
|
1462
|
+
$el.make_local_variable key
|
|
1463
|
+
$el.elvar[key] = val
|
|
1464
|
+
|
|
1465
|
+
nil
|
|
1466
|
+
end
|
|
1467
|
+
|
|
1468
|
+
def self.length
|
|
1469
|
+
$el.buffer_size
|
|
1470
|
+
end
|
|
1471
|
+
|
|
1472
|
+
end
|
|
1473
|
+
|
|
1474
|
+
View.init
|