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.
Files changed (252) hide show
  1. data/Gemfile +11 -0
  2. data/LICENSE +22 -0
  3. data/README.markdown +83 -0
  4. data/Rakefile +8 -0
  5. data/bin/xiki +46 -0
  6. data/etc/command/xiki_command.rb +203 -0
  7. data/etc/command/xiki_process.rb +52 -0
  8. data/etc/command/xiki_wrapper +2 -0
  9. data/etc/js/menu1.js +55 -0
  10. data/etc/js/xiki.js +259 -0
  11. data/etc/logo.png +0 -0
  12. data/etc/presentations/bootstrap.deck +5 -0
  13. data/etc/presentations/databases.deck +41 -0
  14. data/etc/presentations/diffs.deck +23 -0
  15. data/etc/presentations/documentation.deck +14 -0
  16. data/etc/presentations/effects.deck +5 -0
  17. data/etc/presentations/face.deck +297 -0
  18. data/etc/presentations/files.deck +79 -0
  19. data/etc/presentations/icons.deck +22 -0
  20. data/etc/presentations/images.deck +24 -0
  21. data/etc/presentations/key_shortcuts.deck +16 -0
  22. data/etc/presentations/macros.deck +18 -0
  23. data/etc/presentations/menu_classes.deck +44 -0
  24. data/etc/presentations/menu_directories.deck +30 -0
  25. data/etc/presentations/notes.deck +19 -0
  26. data/etc/presentations/other_languages.deck +55 -0
  27. data/etc/presentations/other_wiki_syntaxes.deck +4 -0
  28. data/etc/presentations/piano.deck +5 -0
  29. data/etc/presentations/potential/diffs.deck +38 -0
  30. data/etc/presentations/potential/evolution.deck +18 -0
  31. data/etc/presentations/potential/intro.deck +711 -0
  32. data/etc/presentations/potential/intro1.deck +711 -0
  33. data/etc/presentations/potential/intro2.deck +97 -0
  34. data/etc/presentations/potential/make_mysql_menu.deck +36 -0
  35. data/etc/presentations/potential/ruby_development.deck +17 -0
  36. data/etc/presentations/potential/ui_prototyping.deck +50 -0
  37. data/etc/presentations/potential/web_dev.deck +4 -0
  38. data/etc/presentations/potential/web_development.deck +10 -0
  39. data/etc/presentations/potential/wiki.deck +45 -0
  40. data/etc/presentations/presentations.deck +24 -0
  41. data/etc/presentations/rails_development.deck +29 -0
  42. data/etc/presentations/search_key_shortcuts.deck +37 -0
  43. data/etc/presentations/simplest_possible_ui.deck +37 -0
  44. data/etc/presentations/svg.deck +5 -0
  45. data/etc/presentations/testing.deck +28 -0
  46. data/etc/presentations/the_end.deck +13 -0
  47. data/etc/presentations/type_something_and_double_click.deck +57 -0
  48. data/etc/presentations/type_the_acronym.deck +144 -0
  49. data/etc/presentations/web_browser.deck +56 -0
  50. data/etc/presentations/xiki_command.deck +20 -0
  51. data/etc/presentations/xiki_url.deck +14 -0
  52. data/etc/shark.icns +0 -0
  53. data/etc/shark_script.icns +0 -0
  54. data/etc/snippets/html.notes +7 -0
  55. data/etc/snippets/notes.notes +20 -0
  56. data/etc/snippets/rb.notes +38 -0
  57. data/etc/templates/menu_template.menu +2 -0
  58. data/etc/templates/menu_template.rb +8 -0
  59. data/etc/templates/template.rb +5 -0
  60. data/etc/themes/Dark_Metal.notes +28 -0
  61. data/etc/themes/Orange_Path.notes +15 -0
  62. data/etc/themes/Shiny_Blue.notes +27 -0
  63. data/etc/themes/Shiny_Green.notes +27 -0
  64. data/etc/wrappers/wrapper.js +17 -0
  65. data/etc/wrappers/wrapper.py +20 -0
  66. data/etc/wrappers/wrapper.rb +25 -0
  67. data/lib/block.rb +72 -0
  68. data/lib/bookmarks.rb +352 -0
  69. data/lib/buffers.rb +170 -0
  70. data/lib/clipboard.rb +333 -0
  71. data/lib/code.rb +860 -0
  72. data/lib/code_tree.rb +476 -0
  73. data/lib/color.rb +274 -0
  74. data/lib/console.rb +557 -0
  75. data/lib/control_lock.rb +9 -0
  76. data/lib/control_tab.rb +176 -0
  77. data/lib/core_ext.rb +31 -0
  78. data/lib/cursor.rb +111 -0
  79. data/lib/deletes.rb +65 -0
  80. data/lib/diff_log.rb +297 -0
  81. data/lib/effects.rb +145 -0
  82. data/lib/environment.rb +5 -0
  83. data/lib/file_tree.rb +1875 -0
  84. data/lib/files.rb +334 -0
  85. data/lib/hide.rb +259 -0
  86. data/lib/history.rb +286 -0
  87. data/lib/image.rb +51 -0
  88. data/lib/incrementer.rb +15 -0
  89. data/lib/insert.rb +7 -0
  90. data/lib/irc.rb +22 -0
  91. data/lib/key_bindings.rb +658 -0
  92. data/lib/keys.rb +754 -0
  93. data/lib/launcher.rb +1351 -0
  94. data/lib/line.rb +429 -0
  95. data/lib/links.rb +6 -0
  96. data/lib/location.rb +175 -0
  97. data/lib/macros.rb +48 -0
  98. data/lib/man.rb +19 -0
  99. data/lib/menu.rb +708 -0
  100. data/lib/merb.rb +259 -0
  101. data/lib/message.rb +5 -0
  102. data/lib/meths.rb +56 -0
  103. data/lib/mode.rb +34 -0
  104. data/lib/move.rb +248 -0
  105. data/lib/notes.rb +1000 -0
  106. data/lib/numbers.rb +45 -0
  107. data/lib/ol.rb +203 -0
  108. data/lib/ol_helper.rb +44 -0
  109. data/lib/overlay.rb +167 -0
  110. data/lib/pause_means_space.rb +68 -0
  111. data/lib/php.rb +22 -0
  112. data/lib/projects.rb +21 -0
  113. data/lib/relinquish_exception.rb +2 -0
  114. data/lib/remote.rb +206 -0
  115. data/lib/requirer.rb +46 -0
  116. data/lib/rest_tree.rb +108 -0
  117. data/lib/ruby.rb +57 -0
  118. data/lib/ruby_console.rb +165 -0
  119. data/lib/search.rb +1572 -0
  120. data/lib/search_term.rb +40 -0
  121. data/lib/snippet.rb +68 -0
  122. data/lib/specs.rb +229 -0
  123. data/lib/styles.rb +274 -0
  124. data/lib/svn.rb +682 -0
  125. data/lib/text_util.rb +110 -0
  126. data/lib/tree.rb +1871 -0
  127. data/lib/tree_cursor.rb +87 -0
  128. data/lib/trouble_shooting.rb +27 -0
  129. data/lib/url_tree.rb +11 -0
  130. data/lib/view.rb +1474 -0
  131. data/lib/window.rb +133 -0
  132. data/lib/xiki.rb +404 -0
  133. data/menus/accounts.rb +5 -0
  134. data/menus/address_book.rb +21 -0
  135. data/menus/agenda.rb +28 -0
  136. data/menus/all.rb +5 -0
  137. data/menus/amazon.rb +16 -0
  138. data/menus/app.rb +16 -0
  139. data/menus/applescript.rb +46 -0
  140. data/menus/as.rb +15 -0
  141. data/menus/bookmarklet.rb +63 -0
  142. data/menus/bootstrap.rb +568 -0
  143. data/menus/browse.rb +13 -0
  144. data/menus/browser.rb +78 -0
  145. data/menus/cassandra_db.rb +36 -0
  146. data/menus/chmod.rb +27 -0
  147. data/menus/classes.rb +5 -0
  148. data/menus/coffee_script.rb +35 -0
  149. data/menus/computer.rb +24 -0
  150. data/menus/contacts.rb +5 -0
  151. data/menus/cookies.rb +25 -0
  152. data/menus/couch.rb +184 -0
  153. data/menus/crop.rb +45 -0
  154. data/menus/css.rb +55 -0
  155. data/menus/current.rb +5 -0
  156. data/menus/db.rb +12 -0
  157. data/menus/deck.rb +219 -0
  158. data/menus/dictionary.rb +9 -0
  159. data/menus/dir.rb +8 -0
  160. data/menus/disk.rb +5 -0
  161. data/menus/do.rb +13 -0
  162. data/menus/docs.rb +58 -0
  163. data/menus/dotsies.rb +107 -0
  164. data/menus/edited.rb +18 -0
  165. data/menus/emacs.rb +17 -0
  166. data/menus/enter.rb +13 -0
  167. data/menus/eval.rb +17 -0
  168. data/menus/executable.rb +16 -0
  169. data/menus/filter.rb +46 -0
  170. data/menus/firefox.rb +607 -0
  171. data/menus/foo.rb +30 -0
  172. data/menus/french.rb +7 -0
  173. data/menus/git.rb +185 -0
  174. data/menus/gito.rb +785 -0
  175. data/menus/google.rb +35 -0
  176. data/menus/google_images.rb +11 -0
  177. data/menus/google_patents.rb +10 -0
  178. data/menus/gutenberg.rb +13 -0
  179. data/menus/head.rb +10 -0
  180. data/menus/headings.rb +39 -0
  181. data/menus/html.rb +61 -0
  182. data/menus/icon.rb +40 -0
  183. data/menus/images.menu +2 -0
  184. data/menus/img.rb +15 -0
  185. data/menus/info.rb +9 -0
  186. data/menus/ip.rb +10 -0
  187. data/menus/iterm.rb +36 -0
  188. data/menus/itunes.rb +78 -0
  189. data/menus/javascript.rb +74 -0
  190. data/menus/layout.rb +18 -0
  191. data/menus/local_storage.rb +67 -0
  192. data/menus/ls.rb +19 -0
  193. data/menus/mac.rb +87 -0
  194. data/menus/maps.rb +18 -0
  195. data/menus/matches.rb +18 -0
  196. data/menus/memcache.rb +117 -0
  197. data/menus/mkdir.rb +23 -0
  198. data/menus/mongo.rb +83 -0
  199. data/menus/mysql.rb +294 -0
  200. data/menus/node.rb +88 -0
  201. data/menus/open.rb +19 -0
  202. data/menus/outline.rb +24 -0
  203. data/menus/piano.rb +746 -0
  204. data/menus/postgres.rb +34 -0
  205. data/menus/pre.rb +5 -0
  206. data/menus/python.rb +39 -0
  207. data/menus/rails.rb +160 -0
  208. data/menus/rake.rb +12 -0
  209. data/menus/redmine.rb +168 -0
  210. data/menus/riak_tree.rb +204 -0
  211. data/menus/rss.rb +15 -0
  212. data/menus/safari.rb +11 -0
  213. data/menus/sass.rb +15 -0
  214. data/menus/say.rb +6 -0
  215. data/menus/scale.rb +49 -0
  216. data/menus/serve.rb +78 -0
  217. data/menus/shuffle.rb +24 -0
  218. data/menus/spanish.rb +7 -0
  219. data/menus/standalone.rb +57 -0
  220. data/menus/tail.rb +41 -0
  221. data/menus/technologies.rb +19 -0
  222. data/menus/themes.rb +32 -0
  223. data/menus/thesaurus.rb +13 -0
  224. data/menus/to.rb +24 -0
  225. data/menus/twitter.rb +57 -0
  226. data/menus/wikipedia.rb +34 -0
  227. data/menus/words.rb +11 -0
  228. data/spec/code_tree_spec.rb +59 -0
  229. data/spec/diff_log_spec.rb +40 -0
  230. data/spec/file_tree_spec.rb +102 -0
  231. data/spec/keys_spec.rb +24 -0
  232. data/spec/line_spec.rb +68 -0
  233. data/spec/menu_spec.rb +50 -0
  234. data/spec/ol_spec.rb +98 -0
  235. data/spec/remote_spec.rb +43 -0
  236. data/spec/search_spec.rb +162 -0
  237. data/spec/text_util_spec.rb +119 -0
  238. data/spec/tree_cursor_spec.rb +91 -0
  239. data/spec/tree_spec.rb +955 -0
  240. data/tests/console_test.rb +11 -0
  241. data/tests/couch_db_test.rb +12 -0
  242. data/tests/diff_log_test.rb +43 -0
  243. data/tests/el_mixin.rb +16 -0
  244. data/tests/git_test.rb +95 -0
  245. data/tests/keys_test.rb +19 -0
  246. data/tests/line_test.rb +38 -0
  247. data/tests/merb_test.rb +11 -0
  248. data/tests/redmine_test.rb +50 -0
  249. data/tests/remote_test.rb +31 -0
  250. data/tests/rest_tree_test.rb +70 -0
  251. data/xiki.gemspec +37 -0
  252. metadata +332 -0
@@ -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
@@ -0,0 +1,11 @@
1
+ class UrlTree
2
+ def self.handles? list
3
+ list.first =~ /^http:\/\// ? 1 : nil
4
+ end
5
+
6
+ def self.launch options={}
7
+ url = options[:path].join("")
8
+ Keys.prefix_u ? $el.browse_url(url) : Firefox.url(url)
9
+ end
10
+ end
11
+
@@ -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