xiki 0.5.0a

Sign up to get free protection for your applications and to get access to all the features.
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,1000 @@
1
+ require 'styles'
2
+ require 'line'
3
+ require 'effects'
4
+ require 'view'
5
+ require 'keys'
6
+ require 'clipboard'
7
+
8
+ class Notes
9
+
10
+ LABEL_REGEX = /(?:[a-zA-Z0-9 _-]+\) )?/
11
+
12
+ def self.menu
13
+ %`
14
+ - api/
15
+ > Turn notes wiki text into html
16
+ @ Notes.to_html "> Heading\\njust text\\n"
17
+ `
18
+ end
19
+
20
+ def self.block regex="^> "
21
+ left, after_header, right = View.block_positions regex
22
+ View.txt after_header, right
23
+ end
24
+
25
+ def self.narrow_block options={}
26
+
27
+ delimiter = options[:delimiter] || ">"
28
+
29
+ # If nothing hidden, hide all but current
30
+ if $el.point_min == 1 && ($el.buffer_size + 1 == $el.point_max)
31
+ left, after_header, right = View.block_positions "^#{delimiter}\\( \\|$\\)"
32
+ $el.narrow_to_region left, right
33
+ return
34
+ end
35
+ # Otherwise, expand all, go to next heading, hide all but current
36
+ $el.widen
37
+ Notes.to_block
38
+ left, after_header, right = View.block_positions "^#{delimiter}\\( \\|$\\)"
39
+ $el.narrow_to_region left, right
40
+ end
41
+
42
+ def self.archive
43
+ block = get_block
44
+ block.archive
45
+ end
46
+
47
+ def self.show_text
48
+ block = get_block
49
+ block.show_text
50
+ end
51
+
52
+ def self.hide_text
53
+ block = get_block
54
+ block.hide_text
55
+ end
56
+
57
+ def self.to_block up=false
58
+
59
+ regex = self.heading_regex Keys.prefix
60
+
61
+ prefix = Keys.prefix :clear=>1
62
+
63
+ times = prefix.is_a?(Fixnum) ? prefix : 1
64
+
65
+ if up
66
+ times.times do
67
+ Line.to_left
68
+ Search.backward regex
69
+ end
70
+ else
71
+ times.times do
72
+ Line.next if $el.string_match regex, Line.value # Use elisp matcher
73
+ Search.forward regex
74
+ Line.to_left
75
+ end
76
+ end
77
+ end
78
+
79
+ def self.heading_regex prefix=nil
80
+ prefix == :u ?
81
+ "^[>=]\\{1,2\\}\\( \\|$\\)" :
82
+ "^[>=]\\( \\|$\\)"
83
+ end
84
+
85
+ def self.move_block up=false
86
+ regex = self.heading_regex Keys.prefix
87
+
88
+ times = Keys.prefix_times
89
+
90
+ orig = Location.new
91
+
92
+ prefix = Keys.prefix :clear=>1
93
+
94
+ block = get_block prefix == :u ? 2 : 1
95
+ block.delete_content
96
+
97
+ if up
98
+ times.times do
99
+ Search.backward regex, :go_anyway=>true
100
+ end
101
+ $el.insert block.content
102
+ Search.backward regex
103
+ else
104
+
105
+ move_regex = prefix == :u ? "^>" : regex
106
+
107
+ Search.forward move_regex
108
+ times.times do
109
+ Search.forward move_regex, :go_anyway=>true
110
+ end
111
+ Move.to_axis
112
+
113
+ View.insert block.content
114
+
115
+ Search.backward move_regex
116
+ end
117
+ moved_block = get_block regex
118
+
119
+ times == 1 ?
120
+ moved_block.fade_in :
121
+ orig.go
122
+ end
123
+
124
+ def self.insert_heading options={}
125
+ Line.start
126
+ orig = Line.value
127
+
128
+ times = Keys.prefix_u? ? 1 : (Keys.prefix || 1)
129
+ times.times { $el.insert ">" }
130
+ View.insert " " # unless times > 1
131
+
132
+ if options[:extra_space] || Keys.prefix_u? # If U create blank lines.
133
+ View.insert("\n"*4, :dont_move=>1)
134
+ return
135
+ end
136
+
137
+ View.insert("\n", :dont_move=>1) if orig != ""
138
+ end
139
+
140
+ def self.cut_block no_clipboard=false
141
+ block = get_block Keys.prefix
142
+
143
+ block.blink
144
+
145
+ unless no_clipboard
146
+ Clipboard.set("0", block.content)
147
+ end
148
+ block.delete_content
149
+ end
150
+
151
+ def self.copy_block
152
+ prefix = Keys.prefix
153
+ block = get_block prefix == :u ? 2 : 1
154
+ block.blink
155
+ Clipboard.set("0", Keys.prefix_u ? block.text : block.content)
156
+ end
157
+
158
+ def self.move_block_to_top no_clipboard=false
159
+
160
+ prefix_u = Keys.prefix_u :clear=>true
161
+ block = get_block
162
+
163
+ if prefix_u
164
+ line = View.line_number
165
+ scroll = View.scroll_position
166
+ orig_right = block.right
167
+ end
168
+
169
+ block.fade_out unless prefix_u
170
+
171
+ block.delete_content
172
+
173
+ $el.beginning_of_buffer
174
+ $el.insert block.content
175
+
176
+ if prefix_u
177
+ View.to_line line
178
+ View.scroll_position = scroll
179
+ View.cursor = orig_right
180
+ Line.next
181
+ else
182
+ View.to_line 2
183
+ end
184
+
185
+ moved_block = get_block
186
+
187
+ moved_block.fade_in unless prefix_u
188
+
189
+ end
190
+
191
+ def self.keys
192
+
193
+ return if ! $el
194
+
195
+ # Get reference to map if already there (don't mess with existing buffers)
196
+ $el.elvar.notes_mode_map = $el.make_sparse_keymap unless $el.boundp :notes_mode_map
197
+
198
+ Keys.custom_archive(:notes_mode_map) { Notes.archive }
199
+ Keys.custom_back(:notes_mode_map) { Notes.move_block :backwards } # Move block up to before next block
200
+ Keys.custom_clipboard(:notes_mode_map) { Notes.copy_block } # block -> clipboard
201
+ Keys.custom_delete(:notes_mode_map) { Notes.cut_block :backwards } # block -> clear
202
+ # Keys.custom_expand(:notes_mode_map) { Notes.narrow_block } # Show just block
203
+ Keys.custom_forward(:notes_mode_map) { Notes.move_block } # Move block down to after next block
204
+ Keys.custom_heading(:notes_mode_map) { Notes.insert_heading } # Insert |... etc. heading
205
+ Keys.custom_item(:notes_mode_map) { Agenda.quick_add_line }
206
+ # j
207
+ Keys.custom_kill(:notes_mode_map) { Notes.cut_block } # block -> cut
208
+ # l
209
+ Keys.custom_mask(:notes_mode_map) { Notes.hide_text } # block -> hide
210
+ Keys.custom_next(:notes_mode_map) { Notes.to_block } # Go to block after next block
211
+ Keys.custom_open(:notes_mode_map) { Notes.show_text } # block -> reveal
212
+ Keys.custom_previous(:notes_mode_map) { Notes.to_block :backwards } # Go to block before next block
213
+ # q
214
+ # r
215
+ Keys.custom_stamp(:notes_mode_map) { $el.insert Time.now.strftime("- %Y-%m-%d %I:%M%p: ").downcase.sub(' 0', ' ') }
216
+ Keys.custom_top(:notes_mode_map) { Notes.move_block_to_top } # block -> top
217
+ # u
218
+ # v
219
+ # w
220
+ Keys.custom_x(:notes_mode_map) { Notes.cut_block } # block -> cut
221
+ # y
222
+ # z
223
+
224
+ $el.define_key(:notes_mode_map, $el.kbd("<double-mouse-1>"), :notes_mouse_double_click)
225
+ $el.define_key(:notes_mode_map, $el.kbd("<mouse-1>"), :notes_mouse_toggle)
226
+
227
+ $el.define_key(:notes_mode_map, $el.kbd("<M-mouse-1>"), :notes_mouse_double_click)
228
+ $el.define_key(:notes_mode_map, $el.kbd("<S-mouse-1>"), :notes_mouse_double_click)
229
+ $el.define_key(:notes_mode_map, $el.kbd("<C-mouse-1>"), :notes_mouse_double_click)
230
+
231
+
232
+ $el.define_key(:notes_mode_map, $el.kbd("C-i")) { Notes.tab_key }
233
+ end
234
+
235
+ def self.define_styles
236
+
237
+ return if ! $el
238
+
239
+ # - foo (r): <here>
240
+ Styles.define :notes_light_gray,
241
+ :fg => "bbb"
242
+
243
+ # - foo (r): <here>
244
+ Styles.define :variable,
245
+ :face => 'verdana' #, :size => "+2"
246
+
247
+ # - foo (r): <here>
248
+ Styles.define :notes_label_parens,
249
+ :fg => "bbb",
250
+ :size => "-2",
251
+ :face => 'arial'
252
+
253
+ # |...
254
+ h1_size = "+3"
255
+
256
+ # Colors of "| ..." headings
257
+ if Styles.inverse # If black bg
258
+ @@h1_styles = {
259
+ :notes_h1 =>"333",
260
+ :notes_h1r=>"611", # | r This will be red
261
+ :notes_h1o=>"841", # | o This will be orange
262
+ :notes_h1y=>"871",
263
+ :notes_h1e=>"363",
264
+ :notes_h1g=>"363",
265
+ :notes_h1b=>"678",
266
+ :notes_h1p=>"636",
267
+ :notes_h1m=>"622",
268
+ :notes_h1x=>"345",
269
+ :notes_h1t=>"055",
270
+ }
271
+ else
272
+ # Colors of headings
273
+ @@h1_styles = {
274
+ :notes_h1 =>"aaa",
275
+ :notes_h1r=>"b66", # | r This will be red
276
+ :notes_h1o=>"b83", # | o This will be orange
277
+ :notes_h1y=>"bb3",
278
+ :notes_h1e=>"363",
279
+ :notes_h1g=>"7b6",
280
+ :notes_h1b=>"678",
281
+ :notes_h1p=>"b8b",
282
+ :notes_h1m=>"944",
283
+ :notes_h1x=>"678",
284
+ :notes_h1t=>"055",
285
+ }
286
+ end
287
+
288
+ @@h1_styles.each do |k, v|
289
+ pipe = v.gsub(/./) {|c| (c.to_i(16) + "3".to_i(16)).to_s(16)}
290
+ label = v.gsub(/./) {|c| (c.to_i(16) + "6".to_i(16)).to_s(16)}
291
+ Styles.define k,
292
+ :face=>'arial', :size=>h1_size, :fg=>'ffffff', :bg=>v, :bold=> true
293
+ Styles.define "#{k}_pipe".to_sym, :face=>'arial', :size=>h1_size, :fg=>pipe, :bg=>v, :bold=>true
294
+ Styles.define "#{k}_label".to_sym, :face=>'arial', :size=>h1_size, :fg=>label, :bg=>v, :bold=>true
295
+ end
296
+
297
+ Styles.define :notes_h1_agenda_pipe, :face => 'arial', :size => h1_size, :fg => '88cc88', :bg => '336633', :bold => true
298
+ Styles.define :notes_h1_agenda, :face => 'arial', :size => h1_size, :fg => 'ffffff', :bg => '336633', :bold => true
299
+
300
+ # |||...
301
+ Styles.define :notes_h3,
302
+ :face => 'arial', :size => "-1",
303
+ :fg => '999',#, :bg => "9999cc",
304
+ :bold => true
305
+ Styles.define :notes_h3_pipe,
306
+ :face => 'arial', :size => "-1",
307
+ :fg => '333'
308
+
309
+ # ||||...
310
+ Styles.define :notes_h4,
311
+ :face => 'arial', :size => "-3",
312
+ :fg => '55b',
313
+ :bold => true
314
+ Styles.define :notes_h4_pipe,
315
+ :face => 'arial', :size => "-3",
316
+ :fg => '224'
317
+
318
+
319
+ if Styles.inverse # If black and white
320
+ label_color = "e70"
321
+ else
322
+ label_color = "f70"
323
+ end
324
+
325
+ # Labels, emphasis
326
+ Styles.define :notes_label,
327
+ :face=>'arial black', :size=>"0", # Mac
328
+ #:face=>'courier', :size=>"0", # Mac
329
+ :fg=>label_color, :bold=>true
330
+
331
+ Styles.define :notes_bullet_parens,
332
+ :face => 'arial', :size => "-2",
333
+ :fg => "ee7700", :bold => true
334
+
335
+ # Strikethrough
336
+ Styles.define(:strike, :strike=>true)
337
+
338
+ # - <here> (r): foo
339
+ Styles.define :notes_label_link,
340
+ :face => 'verdana', :size => "-1",
341
+ :fg => "66f",
342
+ :bold => true, :underline => true
343
+
344
+ Styles.define :notes_g, :fg=>"6cf", :face=>'arial black', :size=>"0", :bold=>true
345
+ Styles.define :notes_blue, :fg=>"69f", :face=>'arial black', :size=>"0", :bold=>true
346
+ Styles.define :notes_red, :fg=>"c55", :face=>'arial black', :size=>"0", :bold=>true
347
+ Styles.define :notes_yellow, :fg=>"CC0", :face=>'arial black', :size=>"0", :bold=>true
348
+ Styles.define :notes_green, :fg=>"3C3", :face=>'arial black', :size=>"0", :bold=>true
349
+
350
+
351
+ if Styles.inverse # If black bg
352
+ # >>...
353
+ Styles.define :notes_h2, :face=>'arial', :size=>"-1", :fg=>'fff', :bg=>"333", :bold=>false
354
+ Styles.define :notes_h2_pipe, :face=>'arial', :size=>"-1", :fg=>'555555', :bg=>"333333", :bold=> true
355
+ else
356
+ Styles.define :notes_h2, :face=>'arial', :size=>"-1", :fg=>'fff', :bg=>"999", :bold=>true
357
+ Styles.define :notes_h2_pipe, :face=>'arial', :size=>"-1", :fg=>'bbb', :bg=>"999", :bold=>true
358
+ end
359
+
360
+ if Styles.inverse # If black bg
361
+ Styles.dotted :bg=>'080808', :fg=>'111', :strike=>nil, :underline=>nil, :border=>['111', -1]
362
+ else
363
+ Styles.dotted :bg=>'eee', :fg=>'ddd', :strike=>nil, :underline=>nil, :border=>['ddd', -1]
364
+ end
365
+
366
+ notes_exclamation_color = Styles.inverse ? "7c4" : "5a0"
367
+
368
+ Styles.define :notes_exclamation, # Green bold text
369
+ :face=>'arial black', :size=>"0",
370
+ :fg=>notes_exclamation_color, :bold=>true
371
+
372
+ Styles.notes_link :fg=>(Styles.inverse ? "9ce" : "08f")
373
+
374
+ Styles.shell_prompt :fg=>'#888', :bold=>1
375
+
376
+ end
377
+
378
+ def self.apply_styles
379
+ # Don't format quotes (it overrides the following formatting)
380
+ Styles.clear
381
+
382
+ # >... lines (headings)
383
+ Styles.apply("^\\(>\\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)
384
+
385
+ Styles.apply("^\\(> \\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)
386
+ Styles.apply("^\\(>> \\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)
387
+ Styles.apply("^\\(= \\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)
388
+ Styles.apply("^\\(== \\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)
389
+
390
+ Styles.apply("^\\(>\\)\\( .+?: \\)\\(.+\n\\)", nil, :notes_h1_pipe, :notes_h1_label, :notes_h1)
391
+
392
+ Styles.apply("^\\(> 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].*:\\)\\(.*\n\\)", nil, :notes_h1_agenda_pipe, :notes_h1_agenda)
393
+
394
+ @@h1_styles.each do |k, v|
395
+ l = k.to_s[/_..(.)$/, 1]
396
+ next unless l
397
+ Styles.apply("^\\(> #{l}\\)\\(\n\\| .*\n\\)", nil, "#{k}_pipe".to_sym, k)
398
+ Styles.apply("^\\(>\\)\\( #{l} .+: \\)\\(.*\n\\)", nil, "#{k}_pipe".to_sym, "#{k}_label".to_sym, k)
399
+ end
400
+
401
+ # >>... lines
402
+ # Styles.apply("^\\(>>\\)\\(.*\\)", nil, :notes_h2_pipe, :notes_h2)
403
+ Styles.apply("^\\(>>\\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)
404
+
405
+ # Commented
406
+ Styles.apply("^\\(>> .+?: \\)\\(.+\n\\)", nil, :notes_h2_pipe, :notes_h2)
407
+
408
+ # >>>... lines
409
+ Styles.apply("^\\(>>>\\)\\(.*\n\\)", nil, :notes_h3_pipe, :notes_h3)
410
+
411
+ # >>>... lines
412
+ Styles.apply("^\\(>>>>\\)\\(.*\n\\)", nil, :notes_h4_pipe, :notes_h4)
413
+
414
+ # - bullets with labels and comments
415
+ Styles.apply("^[ \t]*\\([<+-]\\) \\([^/:\n]+:\\) ", nil, :ls_bullet, :notes_label) # - hey: you
416
+ Styles.apply("^[ \t]*\\([<+-]<*\\) \\([^(\n]+?)\\) ", nil, :ls_bullet, :notes_label) # - hey) you
417
+
418
+ Styles.apply("^[ \t]*\\([<+=-]<*\\) \\([^(\n]+)\\)$", nil, :ls_bullet, :notes_label) # - hey)
419
+ Styles.apply("^[ \t]*\\([<+=-]<*\\) \\(.+:\\)$", nil, :ls_bullet, :notes_label) # - hey)
420
+
421
+ # Styles.apply("^[ \t]*\\(x\\)\\( \\)\\(.+\\)", nil, :notes_label, :variable, :strike)
422
+
423
+ Styles.apply("^\\([ \t]*\\)\\([<+-]\\) \\(.+?:\\) +\\(|.*\n\\)", nil, :default, :ls_bullet, :notes_label, :ls_quote)
424
+ Styles.apply("^\\([ \t]*\\)\\([<+-]\\) \\([^(\n]+?)\\) +\\(|.*\n\\)", nil, :default, :ls_bullet, :notes_label, :ls_quote)
425
+
426
+ Styles.apply("^ +\\(!.*\n\\)", nil, :ls_quote) # ^!... for commands
427
+
428
+ # exclamation! / todo
429
+ Styles.apply("^[ \t]*\\([<+-]\\) \\(.*!\\)$", nil, :ls_bullet, :notes_exclamation)
430
+ Styles.apply("^ +\\(!\\+.*\n\\)", nil, :diff_green) # Whole lines
431
+ Styles.apply("^ +\\(!-.*\n\\)", nil, :diff_red)
432
+
433
+ Styles.apply("\\(\(-\\)\\(.+?\\)\\(-\)\\)", nil, :diff_small, :diff_red, :diff_small)
434
+ Styles.apply("\\(\(\\+\\)\\(.+?\\)\\(\\+\)\\)", nil, :diff_small, :diff_green, :diff_small)
435
+
436
+ # google/
437
+ Styles.apply "^ *\\(-?\\) ?\\(@?\\)\\(g\\)\\(o\\)\\(o\\)\\(g\\)\\(l\\)\\(e\\)\\(/\\)", nil, :ls_bullet, :ls_dir,
438
+ :notes_blue, :notes_red, :notes_yellow, :notes_blue, :notes_green, :notes_red,
439
+ :ls_dir
440
+
441
+ Styles.apply "^hint/.+", :fade6
442
+
443
+ Styles.apply "^ *@? ?\\([%$&]\\) ", nil, :shell_prompt # Colorize shell prompts
444
+
445
+ Styles.apply("^ *\\(|`\\)\\(.*\n\\)", nil, :quote_heading_pipe, :dotsies_experimental)
446
+ Styles.apply("^ *\\(|~\\)\\([^\n~]+\\)\\(~?\\)", nil, :quote_heading_pipe, :dotsies, :quote_heading_pipe)
447
+
448
+ end
449
+
450
+ # Startup
451
+ def self.init
452
+
453
+ return if ! $el
454
+
455
+ $el.defun(:notes_mouse_meta_click, :interactive => "e") do |e|
456
+ $el.mouse_set_point(e)
457
+ View.insert "hey"
458
+ end
459
+
460
+ $el.defun(:notes_mouse_double_click, :interactive => "e") do |e|
461
+ next Launcher.insert "h" if Line =~ /^$/ # If blank line, launch history
462
+ Launcher.launch_or_hide(:blink=>true)
463
+ end
464
+
465
+ $el.defun(:notes_mouse_toggle, :interactive => "e") do |e|
466
+ $el.mouse_set_point(e)
467
+ Notes.mouse_toggle
468
+ end
469
+
470
+ $el.defun(:notes_mode, :interactive => "", :docstring => "Apply notes styles, etc") {# |point|
471
+ $el.el4r_lisp_eval "(setq font-lock-defaults '(nil t))"
472
+
473
+ FileTree.apply_styles
474
+ Notes.apply_styles
475
+ FileTree.apply_styles_at_end
476
+ $el.use_local_map $el.elvar.notes_mode_map
477
+ }
478
+ $el.el4r_lisp_eval %q<
479
+ (progn
480
+ (add-to-list 'auto-mode-alist '("\\\\.notes\\\\'" . notes-mode))
481
+ (add-to-list 'auto-mode-alist '("\\\\.xik\\\\'" . notes-mode))
482
+ (add-to-list 'auto-mode-alist '("\\\\.wik\\\\'" . notes-mode)))
483
+ >
484
+ end
485
+
486
+ def self.mode
487
+ $el.notes_mode
488
+ end
489
+
490
+ def self.enter_label_bullet
491
+ Line.to_left
492
+ View.insert "- : "
493
+ Move.backward 2
494
+ end
495
+
496
+ def self.enter_junior
497
+
498
+ Move.to_end if Line.before_cursor =~ /^ +$/ # If at awkward position, move
499
+
500
+ cursor = View.cursor
501
+ line = Line.value
502
+ indent = Line.indent line
503
+ pipe = line =~ /^ *([|#])/ ? $1 : ""
504
+ if Line.left == cursor || Line.right == cursor # If beginning or end, leave current line alone
505
+ Move.to_end
506
+ else # In middle of line
507
+ Deletes.delete_whitespace
508
+ end
509
+
510
+ return View.<< "\n#{line[/^[ |#]*/]} " if pipe
511
+ View << "\n#{indent}#{pipe} "
512
+ end
513
+
514
+ def self.bullet bullet_text="- "
515
+ prefix = Keys.prefix :clear=>true
516
+
517
+ if prefix == :u
518
+ Move.forward if Line.at_right?
519
+ return Tree.collapse
520
+ end
521
+
522
+ if prefix == :uu
523
+ return Tree.collapse :replace_parent=>1
524
+ end
525
+
526
+ line = Line.value
527
+ indent = Line.indent indent
528
+
529
+ if line.present? # If non-blank line
530
+ Move.to_end if line =~ /^ / && View.column <= indent.length # If just entered a bullet, go to end first
531
+
532
+ Move.to_end if line =~ /^[+-] / && View.column <= 2 # If just entered a bullet, go to end first
533
+
534
+ # If at beginning of line, just insert bullet
535
+ return View.insert "- " if View.column == 0 && bullet_text == "- " && line !~ /^ /
536
+
537
+ if View.cursor != Line.right
538
+ Deletes.delete_whitespace
539
+ end
540
+ View.insert "\n"
541
+
542
+ # Do simple case if quoted
543
+ return View.<<("#{line[/^[ |#]*/]} - ") if line =~ /^ *[|#]/
544
+
545
+ # Do simple case if on heading
546
+ return View.<<("- ") if line =~ /^>/
547
+ end
548
+
549
+ if prefix.is_a? Fixnum # If numeric prefix, indent by n
550
+ View.insert((" " * prefix) + bullet_text)
551
+ else # Get bullet indent of previous line
552
+ prev = Line.value(0)
553
+ prev_indent = prev[/^( *)/]
554
+
555
+ # Indent further, unless it we're doing bullets and not following bullet
556
+ prev_indent << " " if line != "" && (bullet_text != "- " || prev =~ /^ *[+-]/ || prev !~ /^>/)
557
+ prev_indent = "#{prev_indent}#{bullet_text}"
558
+ View.insert prev_indent
559
+
560
+ if prefix == :-
561
+ View.insert "(): "
562
+ Move.backward 3
563
+ end
564
+ end
565
+
566
+ return if bullet_text == "" # Don't indent rest if not using bullets (enter_junior)
567
+
568
+ following_line = Line.value(2)
569
+ return if following_line !~ /^ / # Don't indent rest of lines if at left margin
570
+ return if Line.matches /^[ -]*$/ # Exit if new bullet was blank
571
+
572
+ indent = Line.indent
573
+
574
+ return if indent.empty? # Don't indent anything if new bullet wasn't indented
575
+
576
+ cursor = View.cursor
577
+ Line.next
578
+ top = View.cursor
579
+
580
+ # Find next line not indented underneath
581
+ Search.forward "^ \\{0,#{indent.size-1}\\}\\($\\|[^ \n]\\)", :beginning=>true
582
+ $el.indent_rigidly top, Line.left, 2
583
+ View.cursor = cursor
584
+
585
+ end
586
+
587
+ def self.mouse_toggle
588
+ #Launcher.launch_or_hide(:blink=>true)
589
+
590
+ # If next line is indented more, kill children
591
+ # If starts with plus or minus, and on plus or minus, launch
592
+ if Line.matches(/^\s*[+-]/) and View.char =~ /[+-]/
593
+ plus_or_minus = Tree.toggle_plus_and_minus
594
+ if ! Tree.children?
595
+ #plus_or_minus == '+' # If +, expand (launch
596
+
597
+ if FileTree.dir? or ! FileTree.handles? # If on a dir or code_tree
598
+ Launcher.launch
599
+ else # If on a file in a FileTree
600
+ FileTree.enter_lines
601
+ end
602
+
603
+ else # If -, kill under
604
+ Tree.kill_under
605
+ Line.to_beginning
606
+ end
607
+ end
608
+ end
609
+
610
+ # Returns an instance of BlockNotes representing the block the point is currently in
611
+ # def self.get_block regex="^[|>]\\( \\|$\\)"
612
+ def self.get_block regex=nil
613
+ regex ||= self.heading_regex
614
+
615
+ regex = self.heading_regex if regex == 1
616
+ regex = self.heading_regex(:u) if regex == 2 || regex == :u
617
+
618
+ left, after_header, right = View.block_positions regex
619
+ NotesBlock.new(left, after_header, right)
620
+ end
621
+
622
+ def self.to_html txt
623
+ txt = txt.
624
+ gsub(/^> (.+)/, "<h1>\\1</h1>").
625
+ gsub(/(^|[^\n>])$/, "\\0<br>")
626
+ end
627
+
628
+ def self.as_nav
629
+
630
+ prefix = Keys.prefix :clear=>true
631
+ txt = ""
632
+ if prefix == :u || prefix == :uu
633
+ txt = Code.grab_containing_method
634
+ end
635
+
636
+ label = nil
637
+ if prefix == 9
638
+ label = Keys.input :prompt=>"label: ", :timed=>1
639
+ label = "do" if label.blank?
640
+ label = Notes.expand_if_action_abbrev(label) || label
641
+
642
+ prefix = nil
643
+ end
644
+
645
+ if prefix == :uu # up+up means add function and line
646
+ txt << "\n#{Line.value}"
647
+ elsif prefix != :u
648
+ txt = View.txt_per_prefix prefix, :selection=>1, :default_is_line=>1, :just_txt=>1
649
+ end
650
+
651
+ # If file has bullet or ends with slash, grab path
652
+
653
+ keep_tweeking = true
654
+ if ! prefix && FileTree.handles? # Grab tree
655
+ txt = Tree.ancestors_indented :just_sub_tree=>1
656
+ txt.sub! /^ /, ' - '
657
+ keep_tweeking = false
658
+ end
659
+
660
+ file = View.file
661
+ orig = Location.new
662
+
663
+ if keep_tweeking
664
+ if Search.fit_in_snippet(txt) # Insert it in existing tree if there
665
+ View << " - #{label}:\n" if label
666
+ return orig.go
667
+ end
668
+ else
669
+ View.layout_files :no_blink=>1
670
+ end
671
+
672
+ # Make it quoted, unless already a quote
673
+ if keep_tweeking && (txt !~ /\A([+-] |\/)/ || txt !~ /^ +/) # If txt isn't already a tree, make it one
674
+ txt = FileTree.snippet :txt=>txt, :file=>file
675
+ txt.sub! /^ /, " - #{label}:\n " if label
676
+ end
677
+
678
+ # Else, add it to top...
679
+
680
+ View.to_highest
681
+
682
+ if prefix == 8
683
+ if Line =~ /^>/
684
+ Line.next
685
+ end
686
+ result = "#{txt}\n"
687
+ else
688
+ result = ">\n#{txt}\n"
689
+ end
690
+
691
+ View.<< result, :dont_move=>1
692
+
693
+ orig.go
694
+ end
695
+
696
+
697
+ def self.as_todo
698
+ prefix = Keys.prefix :clear=>1
699
+
700
+ txt = nil
701
+
702
+ # If method, make it Foo.bar method call
703
+ line = Line.value
704
+
705
+ if View.file =~ /_spec.rb/ && line =~ /^ *(it|describe) /
706
+ return Specs.enter_as_rspec
707
+ end
708
+
709
+ buffer_name = $el.buffer_name
710
+ file_name = View.file_name
711
+ trunk = Xiki.trunk
712
+
713
+ if prefix.nil? # So 1+ or numeric prefix just grab normally
714
+ if buffer_name == "*ol" # Make it into "foo = bar" format
715
+ txt = line[/\) (.+)/, 1]
716
+ txt.sub!(": ", " = ") if txt
717
+ txt ||= line[/ *- (.+?) /, 1]
718
+
719
+ elsif trunk.last =~ /(\w+)\.rb\/\| *def ([\w\.?]+)/
720
+ clazz = $1
721
+ method = $2
722
+ clazz = TextUtil.camel_case clazz if method.slice! /^self\./
723
+ txt = "#{clazz}.#{method}"
724
+
725
+ elsif line =~ /^ +def (.+)/ # Make it into Foo.bar format
726
+ method = $1
727
+ clazz = file_name[/\w+/]
728
+ clazz = TextUtil.camel_case clazz if method.slice! /^self\./
729
+
730
+ txt = "#{clazz}.#{method}"
731
+
732
+ elsif line =~ /^ *\|/ # Make it into Foo.bar format
733
+ txt = line.sub /^ *\| ?/, ''
734
+ elsif FileTree.handles?
735
+ txt = Tree.dir
736
+ elsif line =~ /(^ *[+-] |\/$)/ # Make it into Foo.bar format
737
+ txt = Xiki.trunk.last
738
+ end
739
+ end
740
+
741
+ txt ||= View.txt_per_prefix(prefix, :selection=>1, :just_txt=>1, :default_is_line=>1)
742
+ txt.strip! if txt =~ /\A.+\n\z/ # Strip when only 1 linebreak
743
+
744
+ options = prefix == :uu ? {:append=>1} : {}
745
+ Search.move_to "$t", txt, options
746
+ end
747
+
748
+
749
+ class NotesBlock
750
+
751
+ attr_accessor :left, :after_header, :right
752
+ attr_accessor :header, :text
753
+
754
+ def initialize(left, after_header, right)
755
+ @left, @after_header, @right = left, after_header, right
756
+ @header = $el.buffer_substring left, after_header
757
+ @text = $el.buffer_substring after_header, right
758
+ end
759
+
760
+ def positions
761
+ [left, after_header, right]
762
+ end
763
+
764
+ def content
765
+ header + text
766
+ end
767
+
768
+ def to_s
769
+ content
770
+ end
771
+
772
+ def blink
773
+ Effects.blink :left => after_header, :right => right
774
+ end
775
+
776
+ def fade_out
777
+ Effects.glow :fade_out=>1, :what=>[left, right]
778
+ end
779
+
780
+ def fade_in
781
+ Effects.glow :fade_in=>1, :what=>[left, right]
782
+ end
783
+
784
+ def delete_content
785
+ $el.delete_region left, right
786
+ end
787
+
788
+ # initialize an overlay for this notes block
789
+ # it has a special hook that updates name to be header always
790
+ # this way we can always find the overlay corresponding to header
791
+
792
+ def show_text
793
+ @header_overlay ||= Overlay.find_or_make(left, after_header - 1)
794
+
795
+ @body_overlay ||= Overlay.find_or_make(after_header, right)
796
+ @body_overlay.invisible = false
797
+ end
798
+
799
+ def hide_text
800
+ @header_overlay ||= Overlay.find_or_make(left, after_header - 1)
801
+
802
+ @body_overlay ||= Overlay.find_or_make(after_header, right)
803
+ @body_overlay.invisible = true
804
+ end
805
+
806
+ # cuts the block, and stores it in archive.file.notes
807
+ # example: ruby.notes -> archive.ruby.notes
808
+ def archive
809
+ delete_content
810
+ filename = 'archive.' + $el.file_name_nondirectory(buffer_file_name)
811
+ timestamp = "--- archived on #{Time.now.strftime('%Y-%m-%d at %H:%M')} --- \n"
812
+ $el.append_to_file timestamp, nil, filename
813
+ $el.append_to_file content, nil, filename
814
+ end
815
+ end
816
+
817
+ def self.enter_do_bullet
818
+
819
+ txt = Keys.input :chars=>1, :prompt=>'Enter a character: '
820
+ expanded = Notes.expand_if_action_abbrev txt
821
+
822
+ # If on blank line, just insert it
823
+ if ! Line.blank?
824
+ line = Line.value
825
+ indent, first_char = line.match(/^( *)(.)/)[1..2]
826
+
827
+ Move.to_axis
828
+ $el.open_line(1)
829
+ end
830
+
831
+ if txt == " "
832
+ View << "#{indent}- !"
833
+ ControlLock.disable
834
+ return View.column = -1
835
+ end
836
+
837
+ if expanded
838
+ View << "#{indent}- #{expanded}!"
839
+ Line.to_beginning
840
+ else
841
+ View << "#{indent}- !"
842
+ Move.backward
843
+ View << txt
844
+ end
845
+
846
+ nil
847
+ end
848
+
849
+ def self.drill file, heading=nil, *content
850
+
851
+ prefix = Keys.prefix :clear=>true
852
+ content = content.any? ? content.join('/') : nil
853
+
854
+ file_orig = file.dup
855
+ file = Bookmarks[file]
856
+
857
+ # If bookmark wasn't found, complain
858
+ if file =~ /^\$(\w+)/
859
+ bm = $1
860
+ return "| Set the following bookmark first. Then you'll be able to use this menu to\n| browse the file. The file should have '> ...' headings.\n\n@ $#{bm}\n"
861
+ end
862
+
863
+ # If docs/, output docs string...
864
+
865
+ if heading == "docs"
866
+ message = "
867
+ > Summary
868
+ | Convenient way for browsing the headings in this file:
869
+ |
870
+ - @ #{file}
871
+ ".unindent
872
+ return message
873
+ end
874
+
875
+ if ! File.exists? file
876
+ return "
877
+ | File doesn't exist yet, do as+update to create it:
878
+ @ #{file}
879
+ | > Heading
880
+ | Stuff
881
+ "
882
+ end
883
+
884
+ txt = File.read file
885
+
886
+ # If just file passed, headings
887
+
888
+ if ! heading
889
+
890
+ return View.open file if prefix == "open" # If as+open, just jump there
891
+
892
+ txt = txt.grep /^\>( .+)/
893
+ return "| This file has no '>...' headings:\n@ #{file}" if txt.empty?
894
+ return txt.join('') #.gsub /^> /, '| '
895
+ end
896
+
897
+ # If just heading passed, show text under heading
898
+
899
+ heading.sub!(/^\| /, '> ')
900
+ escaped_heading = Regexp.escape heading
901
+ if ! content
902
+
903
+ if prefix == :u || prefix == "open" # If C-u on a heading, just jump there
904
+ View.open file
905
+ View.to_highest
906
+ Search.forward "^#{$el.regexp_quote heading}$", :beginning=>1
907
+ View.recenter_top
908
+ return
909
+ end
910
+
911
+ txt = self.extract_block txt, heading
912
+ return txt.gsub(/^/, '| ').gsub(/^\| $/, '|')
913
+ end
914
+
915
+ # If content passed
916
+
917
+ # If C-4, grab text and save it to file / update
918
+ if prefix == "update"
919
+ # Update difflog
920
+
921
+ # Grab before and after
922
+ index = txt.index /^#{escaped_heading}$/
923
+ index += heading.length
924
+
925
+ before = txt[0..index]
926
+
927
+ after = txt[index..-1].sub(/.*?^>( |$)/m, ">\\1")
928
+
929
+ content = Tree.siblings :string=>1
930
+
931
+ txt = "#{before}#{content}#{after}"
932
+
933
+ DiffLog.save_diffs :patha=>file, :textb=>txt
934
+
935
+ # return
936
+ File.open(file, "w") { |f| f << txt }
937
+
938
+ # Revert file if it's open?
939
+
940
+ View.flash "- Saved!"
941
+ return
942
+ end
943
+
944
+ # Navigate to heading, then content
945
+
946
+ View.open file
947
+ View.to_highest
948
+ Search.forward "^#{$el.regexp_quote heading}$"
949
+ View.recenter_top
950
+ Search.forward "^#{$el.regexp_quote content.sub(/^\| /, '')}"
951
+ Move.to_axis
952
+ nil
953
+ end
954
+
955
+ def self.extract_block txt, heading
956
+ txt = txt.sub /.*^#{Regexp.escape heading}\n/m, '' # Delete before block
957
+ txt.sub! /^>( |$).*/m, '' # Delete after block
958
+ txt # = txt.gsub(/^.?/, "|\\1") # Escape with pipes
959
+ end
960
+
961
+ def self.read_block file, heading
962
+ self.extract_block File.read(file), heading
963
+ end
964
+
965
+ def self.tab_key
966
+ indent = Line.indent(Line.value 0)
967
+ Line.sub! /^ */, indent
968
+ Line.to_beginning
969
+ end
970
+
971
+ @@single_letter_abbrev = {
972
+ "f"=>"fix",
973
+ "b"=>"borrow",
974
+ "i"=>"implement",
975
+ "d"=>"delete",
976
+ "r"=>"rename",
977
+ "t"=>"todo",
978
+ "e"=>"extract",
979
+ }
980
+
981
+ # If the string is "t" or "i", or a few others, return "todo" or "imprement" etc. respectively.
982
+ def self.expand_if_action_abbrev txt
983
+ @@single_letter_abbrev[txt] || txt
984
+ end
985
+
986
+ def self.do_as_quote
987
+ # Make this add or remove quotes
988
+ end
989
+ end
990
+
991
+ Notes.define_styles
992
+ Notes.init
993
+ Notes.keys # Define local keys
994
+
995
+ # TODO - how to turn these on conditionally?
996
+ # What's the best approach for presentations?
997
+ # Probably make .deck files use notes mode
998
+ # Why wasn't working before?
999
+ # require 'deck'
1000
+ # Deck.keys :notes_mode_map # Temporary - only when doing presentations