├── .gitignore
├── .no-sublime-package
├── Color Scheme
├── light-orgmode.tmTheme
└── orgmode.tmTheme
├── Default (Linux).sublime-keymap
├── Default (OSX).sublime-keymap
├── Default (Windows).sublime-keymap
├── Default.sublime-commands
├── LICENSE
├── Main.sublime-menu
├── README.md
├── Symbol List.tmPreferences
├── help_it.py
├── images
├── screenshot1.png
└── screenshot2.png
├── messages.json
├── messages
├── 1.7.0.org
├── 1.7.4.org
├── 1.7.8.org
├── 1.9.0.org
└── install.org
├── navigation_history.py
├── orgmode.py
├── orgmode.sublime-settings
├── orgmode.tmLanguage
├── orgmode_store.py
├── packages.json
├── resolver
├── __init__.py
├── abstract.py
├── crucible.py
├── email.py
├── fisheye.py
├── http.py
├── https.py
├── jira.py
├── local_file.py
├── prompt.py
└── redmine.py
└── snippets
├── break.sublime-snippet
├── checkbox_checked.sublime-snippet
├── checkbox_summary.sublime-snippet
├── checkbox_unchecked.sublime-snippet
├── code.sublime-snippet
├── extlink.sublime-snippet
├── followup.sublime-snippet
├── headline.sublime-snippet
├── headline2.sublime-snippet
├── headline3.sublime-snippet
├── intlink.sublime-snippet
├── intlink2.sublime-snippet
├── multitag.sublime-snippet
├── page.sublime-snippet
├── sumup.sublime-snippet
├── tack.sublime-snippet
├── tack_checkbox_checked.sublime-snippet
├── tack_checkbox_unchecked.sublime-snippet
├── tack_checkbox_unchecked_extlink.sublime-snippet
├── tack_done.sublime-snippet
├── tack_todo.sublime-snippet
├── tack_working.sublime-snippet
└── tag.sublime-snippet
/.gitignore:
--------------------------------------------------------------------------------
1 | # Can ignore specific files
2 | .DS_Store
3 | *.pyc
4 | *.cache
5 | *.bak
--------------------------------------------------------------------------------
/.no-sublime-package:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielmagnussons/orgmode/73d52ba15a39e0c0649ed268ca1f268800a990aa/.no-sublime-package
--------------------------------------------------------------------------------
/Color Scheme/light-orgmode.tmTheme:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Monokai inverse
7 | settings
8 |
9 |
10 | settings
11 |
12 | background
13 | #D8D7DD
14 | caret
15 | #07070F
16 | foreground
17 | #07070D
18 | invisibles
19 | #C4C5CD
20 | lineHighlight
21 | #C1C2CD
22 | selection
23 | #B6B7C1
24 | findHighlight
25 | #00186D
26 | findHighlightForeground
27 | #FFFFFF
28 | selectionBorder
29 | #DDDDE7
30 | activeGuide
31 | #62AAF0
32 |
33 | bracketsForeground
34 | #07070D
35 | bracketsOptions
36 | underline
37 |
38 | bracketContentsForeground
39 | #07070D
40 | bracketContentsOptions
41 | underline
42 |
43 | tagsOptions
44 | stippled_underline
45 |
46 |
47 |
48 | name
49 | Comment
50 | scope
51 | comment
52 | settings
53 |
54 | foreground
55 | #8A8EA1
56 |
57 |
58 |
59 | name
60 | String
61 | scope
62 | string
63 | settings
64 |
65 | foreground
66 | #19248B
67 |
68 |
69 |
70 | name
71 | Number
72 | scope
73 | constant.numeric
74 | settings
75 |
76 | foreground
77 | #517E00
78 |
79 |
80 |
81 |
82 | name
83 | Built-in constant
84 | scope
85 | constant.language
86 | settings
87 |
88 | foreground
89 | #517E00
90 |
91 |
92 |
93 | name
94 | User-defined constant
95 | scope
96 | constant.character, constant.other
97 | settings
98 |
99 | foreground
100 | #517E00
101 |
102 |
103 |
104 | name
105 | Variable
106 | scope
107 | variable
108 | settings
109 |
110 | fontStyle
111 |
112 |
113 |
114 |
115 | name
116 | Keyword
117 | scope
118 | keyword
119 | settings
120 |
121 | foreground
122 | #06D98D
123 |
124 |
125 |
126 | name
127 | Storage
128 | scope
129 | storage
130 | settings
131 |
132 | fontStyle
133 |
134 | foreground
135 | #06D98D
136 |
137 |
138 |
139 | name
140 | Storage type
141 | scope
142 | storage.type
143 | settings
144 |
145 | fontStyle
146 | italic
147 | foreground
148 | #992610
149 |
150 |
151 |
152 | name
153 | Class name
154 | scope
155 | entity.name.class
156 | settings
157 |
158 | fontStyle
159 | underline
160 | foreground
161 | #591DD1
162 |
163 |
164 |
165 | name
166 | Inherited class
167 | scope
168 | entity.other.inherited-class
169 | settings
170 |
171 | fontStyle
172 | italic underline
173 | foreground
174 | #591DD1
175 |
176 |
177 |
178 | name
179 | Function name
180 | scope
181 | entity.name.function
182 | settings
183 |
184 | fontStyle
185 |
186 | foreground
187 | #591DD1
188 |
189 |
190 |
191 | name
192 | Function argument
193 | scope
194 | variable.parameter
195 | settings
196 |
197 | fontStyle
198 | italic
199 | foreground
200 | #0268E0
201 |
202 |
203 |
204 | name
205 | Tag name
206 | scope
207 | entity.name.tag
208 | settings
209 |
210 | fontStyle
211 |
212 | foreground
213 | #06D98D
214 |
215 |
216 |
217 | name
218 | Tag attribute
219 | scope
220 | entity.other.attribute-name
221 | settings
222 |
223 | fontStyle
224 |
225 | foreground
226 | #591DD1
227 |
228 |
229 |
230 | name
231 | Library function
232 | scope
233 | support.function
234 | settings
235 |
236 | fontStyle
237 |
238 | foreground
239 | #992610
240 |
241 |
242 |
243 | name
244 | Library constant
245 | scope
246 | support.constant
247 | settings
248 |
249 | fontStyle
250 |
251 | foreground
252 | #992610
253 |
254 |
255 |
256 | name
257 | Library class/type
258 | scope
259 | support.type, support.class
260 | settings
261 |
262 | fontStyle
263 | italic
264 | foreground
265 | #992610
266 |
267 |
268 |
269 | name
270 | Library variable
271 | scope
272 | support.other.variable
273 | settings
274 |
275 | fontStyle
276 |
277 |
278 |
279 |
280 | name
281 | Invalid
282 | scope
283 | invalid
284 | settings
285 |
286 | background
287 | #06D98D
288 | fontStyle
289 |
290 | foreground
291 | #07070F
292 |
293 |
294 |
295 | name
296 | Invalid deprecated
297 | scope
298 | invalid.deprecated
299 | settings
300 |
301 | background
302 | #517E00
303 | foreground
304 | #07070F
305 |
306 |
307 |
308 | name
309 | JSON String
310 | scope
311 | meta.structure.dictionary.json string.quoted.double.json
312 | settings
313 |
314 | foreground
315 | #30303D
316 |
317 |
318 |
319 |
320 | name
321 | diff.header
322 | scope
323 | meta.diff, meta.diff.header
324 | settings
325 |
326 | foreground
327 | #8A8EA1
328 |
329 |
330 |
331 | name
332 | diff.deleted
333 | scope
334 | markup.deleted
335 | settings
336 |
337 | foreground
338 | #06D98D
339 |
340 |
341 |
342 | name
343 | diff.inserted
344 | scope
345 | markup.inserted
346 | settings
347 |
348 | foreground
349 | #591DD1
350 |
351 |
352 |
353 | name
354 | diff.changed
355 | scope
356 | markup.changed
357 | settings
358 |
359 | foreground
360 | #19248B
361 |
362 |
363 |
364 |
365 | scope
366 | constant.numeric.line-number.find-in-files - match
367 | settings
368 |
369 | foreground
370 | #517E00
371 |
372 |
373 |
374 | scope
375 | entity.name.filename.find-in-files
376 | settings
377 |
378 | foreground
379 | #19248B
380 |
381 |
382 |
383 |
384 | name
385 | orgmode link
386 | scope
387 | orgmode.link
388 | settings
389 |
390 | foreground
391 | #FB9A4B
392 | fontStyle
393 | underline
394 |
395 |
396 |
397 | name
398 | orgmode page
399 | scope
400 | orgmode.page
401 | settings
402 |
403 | foreground
404 | #000055
405 |
406 |
407 |
408 | name
409 | orgmode break
410 | scope
411 | orgmode.break
412 | settings
413 |
414 | foreground
415 | #005555
416 |
417 |
418 |
419 | name
420 | orgmode headline
421 | scope
422 | orgmode.headline
423 | settings
424 |
425 | foreground
426 | #610000
427 |
428 |
429 |
430 | name
431 | orgmode tack
432 | scope
433 | orgmode.tack
434 | settings
435 |
436 | foreground
437 | #000055
438 |
439 |
440 |
441 | name
442 | orgmode follow up
443 | scope
444 | orgmode.follow_up
445 | settings
446 |
447 | foreground
448 | #000055
449 |
450 |
451 |
452 | name
453 | orgmode checkbox
454 | scope
455 | orgmode.checkbox
456 | settings
457 |
458 | foreground
459 | #000055
460 |
461 |
462 |
463 | name
464 | orgmode checkbox summary
465 | scope
466 | orgmode.checkbox.summary
467 | settings
468 |
469 | foreground
470 | #000055
471 |
472 |
473 |
474 | name
475 | orgmode tags
476 | scope
477 | orgmode.tags
478 | settings
479 |
480 | foreground
481 | #550055
482 |
483 |
484 |
485 |
486 | uuid
487 | D8D5E82E-3D5B-46B5-B38E-8C841C21347D
488 |
489 |
490 |
--------------------------------------------------------------------------------
/Color Scheme/orgmode.tmTheme:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Monokai Bright
7 | settings
8 |
9 |
10 | settings
11 |
12 | background
13 | #272822
14 | caret
15 | #F8F8F0
16 | foreground
17 | #F8F8F2
18 | invisibles
19 | #3B3A32
20 | lineHighlight
21 | #3E3D32
22 | selection
23 | #9D550F
24 | selectionForeground
25 | #fffff8
26 | inactiveSelection
27 | #bbbbbb
28 | inactiveSelectionForeground
29 | #222222
30 | findHighlight
31 | #FFE792
32 | findHighlightForeground
33 | #000000
34 | activeGuide
35 | #9D550FB0
36 |
37 | bracketsForeground
38 | #F8F8F2A5
39 | bracketsOptions
40 | underline
41 |
42 | bracketContentsForeground
43 | #F8F8F2A5
44 | bracketContentsOptions
45 | underline
46 |
47 | tagsOptions
48 | stippled_underline
49 |
50 |
51 |
52 | name
53 | Comment
54 | scope
55 | comment
56 | settings
57 |
58 | foreground
59 | #75715E
60 |
61 |
62 |
63 | name
64 | String
65 | scope
66 | string
67 | settings
68 |
69 | foreground
70 | #E6DB74
71 |
72 |
73 |
74 | name
75 | Number
76 | scope
77 | constant.numeric
78 | settings
79 |
80 | foreground
81 | #AE81FF
82 |
83 |
84 |
85 | name
86 | Built-in constant
87 | scope
88 | constant.language
89 | settings
90 |
91 | foreground
92 | #AE81FF
93 |
94 |
95 |
96 | name
97 | User-defined constant
98 | scope
99 | constant.character, constant.other
100 | settings
101 |
102 | foreground
103 | #AE81FF
104 |
105 |
106 |
107 | name
108 | Variable
109 | scope
110 | variable
111 | settings
112 |
113 | fontStyle
114 |
115 |
116 |
117 |
118 | name
119 | Keyword
120 | scope
121 | keyword
122 | settings
123 |
124 | foreground
125 | #F92672
126 |
127 |
128 |
129 | name
130 | Storage
131 | scope
132 | storage
133 | settings
134 |
135 | fontStyle
136 |
137 | foreground
138 | #F92672
139 |
140 |
141 |
142 | name
143 | Storage type
144 | scope
145 | storage.type
146 | settings
147 |
148 | fontStyle
149 | italic
150 | foreground
151 | #66D9EF
152 |
153 |
154 |
155 | name
156 | Class name
157 | scope
158 | entity.name.class
159 | settings
160 |
161 | fontStyle
162 | underline
163 | foreground
164 | #A6E22E
165 |
166 |
167 |
168 | name
169 | Inherited class
170 | scope
171 | entity.other.inherited-class
172 | settings
173 |
174 | fontStyle
175 | italic underline
176 | foreground
177 | #A6E22E
178 |
179 |
180 |
181 | name
182 | Function name
183 | scope
184 | entity.name.function
185 | settings
186 |
187 | fontStyle
188 |
189 | foreground
190 | #A6E22E
191 |
192 |
193 |
194 | name
195 | Function argument
196 | scope
197 | variable.parameter
198 | settings
199 |
200 | fontStyle
201 | italic
202 | foreground
203 | #FD971F
204 |
205 |
206 |
207 | name
208 | Tag name
209 | scope
210 | entity.name.tag
211 | settings
212 |
213 | fontStyle
214 |
215 | foreground
216 | #F92672
217 |
218 |
219 |
220 | name
221 | Tag attribute
222 | scope
223 | entity.other.attribute-name
224 | settings
225 |
226 | fontStyle
227 |
228 | foreground
229 | #A6E22E
230 |
231 |
232 |
233 | name
234 | Library function
235 | scope
236 | support.function
237 | settings
238 |
239 | fontStyle
240 |
241 | foreground
242 | #66D9EF
243 |
244 |
245 |
246 | name
247 | Library constant
248 | scope
249 | support.constant
250 | settings
251 |
252 | fontStyle
253 |
254 | foreground
255 | #66D9EF
256 |
257 |
258 |
259 | name
260 | Library class/type
261 | scope
262 | support.type, support.class
263 | settings
264 |
265 | fontStyle
266 | italic
267 | foreground
268 | #66D9EF
269 |
270 |
271 |
272 | name
273 | Library variable
274 | scope
275 | support.other.variable
276 | settings
277 |
278 | fontStyle
279 |
280 |
281 |
282 |
283 | name
284 | Invalid
285 | scope
286 | invalid
287 | settings
288 |
289 | background
290 | #F92672
291 | fontStyle
292 |
293 | foreground
294 | #F8F8F0
295 |
296 |
297 |
298 | name
299 | Invalid deprecated
300 | scope
301 | invalid.deprecated
302 | settings
303 |
304 | background
305 | #AE81FF
306 | foreground
307 | #F8F8F0
308 |
309 |
310 |
311 | name
312 | JSON String
313 | scope
314 | meta.structure.dictionary.json string.quoted.double.json
315 | settings
316 |
317 | foreground
318 | #CFCFC2
319 |
320 |
321 |
322 |
323 | name
324 | diff.header
325 | scope
326 | meta.diff, meta.diff.header
327 | settings
328 |
329 | foreground
330 | #75715E
331 |
332 |
333 |
334 | name
335 | diff.deleted
336 | scope
337 | markup.deleted
338 | settings
339 |
340 | foreground
341 | #F92672
342 |
343 |
344 |
345 | name
346 | diff.inserted
347 | scope
348 | markup.inserted
349 | settings
350 |
351 | foreground
352 | #A6E22E
353 |
354 |
355 |
356 | name
357 | diff.changed
358 | scope
359 | markup.changed
360 | settings
361 |
362 | foreground
363 | #E6DB74
364 |
365 |
366 |
367 |
368 | scope
369 | constant.numeric.line-number.find-in-files - match
370 | settings
371 |
372 | foreground
373 | #AE81FFA0
374 |
375 |
376 |
377 | scope
378 | entity.name.filename.find-in-files
379 | settings
380 |
381 | foreground
382 | #E6DB74
383 |
384 |
385 |
386 | name
387 | orgmode link
388 | scope
389 | orgmode.link
390 | settings
391 |
392 | foreground
393 | #FB9A4B
394 | fontStyle
395 | underline
396 |
397 |
398 |
399 | name
400 | orgmode page
401 | scope
402 | orgmode.page
403 | settings
404 |
405 | foreground
406 | #FFFFAA
407 |
408 |
409 |
410 | name
411 | orgmode break
412 | scope
413 | orgmode.break
414 | settings
415 |
416 | foreground
417 | #FFAAAA
418 |
419 |
420 |
421 | name
422 | orgmode headline
423 | scope
424 | orgmode.headline
425 | settings
426 |
427 | foreground
428 | #9EFFFF
429 |
430 |
431 |
432 | name
433 | orgmode tack
434 | scope
435 | orgmode.tack
436 | settings
437 |
438 | foreground
439 | #FFFFAA
440 |
441 |
442 |
443 | name
444 | orgmode follow up
445 | scope
446 | orgmode.follow_up
447 | settings
448 |
449 | foreground
450 | #FFFFAA
451 |
452 |
453 |
454 | name
455 | orgmode checkbox
456 | scope
457 | orgmode.checkbox
458 | settings
459 |
460 | foreground
461 | #FFFFAA
462 |
463 |
464 |
465 | name
466 | orgmode checkbox summary
467 | scope
468 | orgmode.checkbox.summary
469 | settings
470 |
471 | foreground
472 | #FFFFAA
473 |
474 |
475 |
476 | name
477 | orgmode tags
478 | scope
479 | orgmode.tags
480 | settings
481 |
482 | foreground
483 | #AAFFAA
484 |
485 |
486 |
487 |
488 | uuid
489 | D8D5E82E-3D5B-46B5-B38E-8C841C21347E
490 |
491 |
492 |
493 |
494 |
495 |
--------------------------------------------------------------------------------
/Default (Linux).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | /* Orgmode */
3 | { "keys": ["enter"], "command": "orgmode_toggle_checkbox", "context":
4 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox" }]
5 | },
6 | { "keys": ["enter"], "command": "orgmode_recalc_checkbox_summary", "context":
7 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox.summary" }]
8 | },
9 | { "keys": ["enter"], "command": "orgmode_open_link", "context":
10 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link" }]
11 | },
12 | { "keys": ["enter"], "command": "orgmode_cycle_internal_link", "context":
13 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link.internal" }]
14 | },
15 | { "keys": ["enter"], "command": "orgmode_cycle_todo", "context":
16 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.todo" }]
17 | },
18 |
19 | /* Navigation */
20 | { "keys": ["alt+left"], "command": "navigation_history_back"},
21 | { "keys": ["alt+right"], "command": "navigation_history_forward"},
22 |
23 | /* Helpit */
24 | { "keys": ["alt+f1"], "command": "help_it" },
25 |
26 | /* Fold headlines */
27 | { "keys": ["tab"], "command": "orgmode_folding", "context":
28 | [
29 | { "key": "selector", "operator": "equal", "operand": "orgmode.headline" }
30 | ]
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/Default (OSX).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | /* Orgmode */
3 | { "keys": ["enter"], "command": "orgmode_toggle_checkbox", "context":
4 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox" }]
5 | },
6 | { "keys": ["enter"], "command": "orgmode_recalc_checkbox_summary", "context":
7 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox.summary" }]
8 | },
9 | { "keys": ["enter"], "command": "orgmode_open_link", "context":
10 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link" }]
11 | },
12 | { "keys": ["enter"], "command": "orgmode_cycle_internal_link", "context":
13 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link.internal" }]
14 | },
15 | { "keys": ["enter"], "command": "orgmode_cycle_todo", "context":
16 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.todo" }]
17 | },
18 |
19 | /* Navigation */
20 | /*
21 | { "keys": ["super+alt+left"], "command": "navigation_history_back"},
22 | { "keys": ["super+alt+right"], "command": "navigation_history_forward"},
23 | */
24 |
25 | /* Helpit */
26 | { "keys": ["alt+f1"], "command": "help_it" },
27 |
28 | /* Fold headlines */
29 | { "keys": ["tab"], "command": "orgmode_folding", "context":
30 | [
31 | { "key": "selector", "operator": "equal", "operand": "orgmode.headline" }
32 | ]
33 | }
34 | ]
35 |
--------------------------------------------------------------------------------
/Default (Windows).sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | /* Orgmode */
3 | { "keys": ["enter"], "command": "orgmode_toggle_checkbox", "context":
4 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox" }]
5 | },
6 | { "keys": ["enter"], "command": "orgmode_recalc_checkbox_summary", "context":
7 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.checkbox.summary" }]
8 | },
9 | { "keys": ["enter"], "command": "orgmode_open_link", "context":
10 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link" }]
11 | },
12 | { "keys": ["enter"], "command": "orgmode_cycle_internal_link", "context":
13 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.link.internal" }]
14 | },
15 | { "keys": ["enter"], "command": "orgmode_cycle_todo", "context":
16 | [{ "key": "selector", "operator": "equal", "operand": "orgmode.todo" }]
17 | },
18 |
19 | /* Navigation */
20 | { "keys": ["alt+left"], "command": "navigation_history_back"},
21 | { "keys": ["alt+right"], "command": "navigation_history_forward"},
22 |
23 | /* Helpit */
24 | { "keys": ["alt+f1"], "command": "help_it" },
25 |
26 | /* Fold headlines */
27 | { "keys": ["tab"], "command": "orgmode_folding", "context":
28 | [
29 | { "key": "selector", "operator": "equal", "operand": "orgmode.headline" }
30 | ]
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "Preferences: orgmode Settings – Default",
4 | "command": "open_file",
5 | "args": {
6 | "file": "${packages}/orgmode/orgmode.sublime-settings"
7 | }
8 | },
9 | {
10 | "caption": "Preferences: orgmode Settings – User",
11 | "command": "open_file",
12 | "args": {
13 | "file": "${packages}/User/orgmode.sublime-settings"
14 | }
15 | }
16 | ]
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2011 Oktay Acikalin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "mnemonic": "n",
4 | "caption": "Preferences",
5 | "id": "preferences",
6 | "children": [
7 | {
8 | "mnemonic": "P",
9 | "caption": "Package Settings",
10 | "id": "package-settings",
11 | "children": [
12 | {
13 | "caption": "orgmode",
14 | "children": [
15 | {
16 | "caption": "Readme.org",
17 | "args": {
18 | "file": "${packages}/orgmode/messages/install.org"
19 | },
20 | "command": "open_file"
21 | },
22 | {
23 | "caption": "Settings – Default",
24 | "args": {
25 | "file": "${packages}/orgmode/orgmode.sublime-settings"
26 | },
27 | "command": "open_file"
28 | },
29 | {
30 | "caption": "Settings – User",
31 | "args": {
32 | "file": "${packages}/User/orgmode.sublime-settings"
33 | },
34 | "command": "open_file"
35 | },
36 | {
37 | "caption": "-"
38 | }
39 | ]
40 | }
41 | ]
42 | }
43 | ]
44 | }
45 | ]
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | orgmode for Sublime Text 2 & 3
2 | =============
3 |
4 | Adds support for [Org mode](http://orgmode.org)'s [.org syntax](http://orgmode.org/worg/dev/org-syntax.html) files to Sublime Text.
5 |
6 | Tested **on Windows 7 and Ubuntu 12.04 and Mac OS X 10.7.5** with Sublime Text 2 & 3
7 |
8 |
9 | Features
10 | =============
11 |
12 | _Full feature list available in [install.org](messages/install.org#features) or via the Sublime Text menus at Package Settings -> orgmode -> Readme.org_
13 |
14 | 
15 |
16 |
17 | Todo
18 | =============
19 | _Full todo list available in [install.org](https://github.com/danielmagnussons/orgmode/blob/master/messages/install.org) or via the Sublime Text menus at Package Settings -> orgmode -> Readme.org_
20 | 
21 | More Todo in Sublime Text 2/Packages/README.org
22 |
23 |
24 | Install with Package Control
25 | =============
26 |
27 | Package Control : Install Package
28 | Search for "orgmode"
29 | Restart Sublime
30 |
31 |
32 | Manual install
33 | =============
34 |
35 | cd .../Sublime Text 2/Packages/
36 | git clone git@github.com:danielmagnussons/orgmode.git
37 | restart sublime
38 | open .../Sublime Text 2/Packages/README.org
39 |
40 |
41 | Other
42 | =============
43 |
44 | * Forked from https://bitbucket.org/theblacklion/sublime_orgmode/
45 | * Inspired by http://orgmode.org/
46 |
--------------------------------------------------------------------------------
/Symbol List.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Symbol List
7 | scope
8 | text.orgmode orgmode.page, text.orgmode orgmode.break, text.orgmode orgmode.headline
9 | settings
10 |
11 | showInSymbolList
12 | 1
13 | symbolTransformation
14 |
15 | s/\s*\**\s*\z//g; #Search for *
16 | s/(?<=\*)\*/ /g; #replace * with two spaces, except first
17 | s/^\*( *)\s+(.*)/$1$2/; #replace first found with a space
18 |
19 |
20 | uuid
21 | 7A121D96-5F22-41B1-B749-8C4FCA7EA592
22 |
23 |
24 |
--------------------------------------------------------------------------------
/help_it.py:
--------------------------------------------------------------------------------
1 | '''
2 | Integrated from http://www.sublimetext.com/forum/viewtopic.php?f=5&t=2674
3 | Plugin inspired and modified from http://www.sublimetext.com/forum/viewtopic.php?f=5&t=2242
4 |
5 | keys;
6 | { "keys": ["alt+f1"], "command": "help_it" }
7 | '''
8 | import sublime
9 | import sublime_plugin
10 | import webbrowser
11 | import re
12 |
13 |
14 | class helpItCommand(sublime_plugin.TextCommand):
15 |
16 | """
17 | This will search a word in a language's documenation or google it with it's scope otherwise
18 | """
19 |
20 | def run(self, edit):
21 | if len(self.view.file_name()) > 0:
22 | settings = sublime.load_settings('orgmode.sublime-settings')
23 | item = None
24 | word = self.view.substr(self.view.word(self.view.sel()[0].begin()))
25 | scope = self.view.scope_name(self.view.sel()[0].begin()).strip()
26 | getlang = scope.split('.')
27 | language = getlang[-1]
28 | if language == 'basic':
29 | language = getlang[-2]
30 |
31 | if language == 'html': # HTML shows up A LOT for internal CSS, PHP and JS
32 | if 'php' in getlang:
33 | language = 'php'
34 | elif 'js' in getlang:
35 | language = 'js'
36 | elif 'css' in getlang:
37 | language = 'css'
38 |
39 | # Map languages if needed. For example: Map .less files to .css
40 | # searches
41 | print('language: ' + language)
42 | if settings.get(language) is not None:
43 | print('lang found in settings: ' + language)
44 | item = settings.get(language)
45 | if 'map' in item:
46 | language = item['map']
47 |
48 | sublime.status_message(
49 | 'helpIt invoked-- ' + 'Scope: ' + scope + ' Word: ' + word + ' Language: ' + language)
50 | for region in self.view.sel():
51 | phrase = self.view.substr(region)
52 | search = 'http://google.com/search?q=%s'
53 | custom = False
54 |
55 | # Define our search term
56 | if not region.empty():
57 | term = phrase
58 | else:
59 | term = word
60 |
61 | if item != None:
62 | if 'sub' in item: # check for sub searches based on our term
63 | subs = item['sub']
64 | for sub in subs:
65 | if 'contains' in sub and 'url' in sub: # Make sure we have everything
66 | if term.count(sub['contains']):
67 | if 'remove' in sub:
68 | term = re.sub(sub['remove'], '', term)
69 | search = sub['url']
70 | custom = True
71 | break
72 |
73 | if not custom:
74 | if isinstance(item, str):
75 | search = item
76 | custom = True
77 | elif 'url' in item:
78 | search = item['url']
79 | custom = True
80 |
81 | if not custom:
82 | term += " " + language
83 |
84 | try:
85 | search = search % (term)
86 | print(search)
87 | except TypeError:
88 | print("No replacements")
89 |
90 | webbrowser.open_new_tab(search)
91 | else:
92 | pass
93 |
94 | def is_enabled(self):
95 | return self.view.file_name() and len(self.view.file_name()) > 0
96 |
--------------------------------------------------------------------------------
/images/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielmagnussons/orgmode/73d52ba15a39e0c0649ed268ca1f268800a990aa/images/screenshot1.png
--------------------------------------------------------------------------------
/images/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielmagnussons/orgmode/73d52ba15a39e0c0649ed268ca1f268800a990aa/images/screenshot2.png
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "messages/install.org",
3 | "1.7.0": "messages/1.7.0.org",
4 | "1.7.4": "messages/1.7.4.org"
5 | }
6 |
--------------------------------------------------------------------------------
/messages/1.7.0.org:
--------------------------------------------------------------------------------
1 |
2 | [X] updated to 1.7.0
--------------------------------------------------------------------------------
/messages/1.7.4.org:
--------------------------------------------------------------------------------
1 |
2 | * What's new
3 | - When tabbing on a headline, like this on 'What's new' it will be folded. Tab on it again to unfold.
4 | - Everything folded/unfolded will be saved.
5 | - Sublime has a few fold keys built in, search for 'fold' in Default.sublime.keymap
--------------------------------------------------------------------------------
/messages/1.7.8.org:
--------------------------------------------------------------------------------
1 |
2 | * What's new
3 | - Summary of checkboxes will work better when nesting them like below
4 | - Fixes: [[https://github.com/danielmagnussons/orgmode/issues/34]]
5 |
6 | ---
7 |
8 | * Headline with summary [2/3]
9 | - [X] Do this
10 | - [X] Then this
11 | - [ ] Do this big task [0/2]
12 | - [ ] With a lot of sub tasks
13 | - [ ] And check the summary checkboxes.
14 |
15 | * Second headline here with more tasks [1/2]
16 | - [ ] One
17 | - [X] Two
--------------------------------------------------------------------------------
/messages/1.9.0.org:
--------------------------------------------------------------------------------
1 |
2 | * What's new
3 |
4 | 0269d47 Save folding with filename instead of view_index
5 | d3021e7 Remove spammy print
6 | fa487b1 Use realpath(__file__) instead of packages_path()
7 | 7c78a6f (martisak-todo) Merge branch 'todo' of github.com:martisak/orgmode into todo
8 | 36ee5a3 Hack to avoid problems if cursor is at the end of the line
9 | a37d433 Added example in install.org
10 | 2f8f5ae Merge pull request #69 from kxtcd950/master
11 | 4ae2b23 Added todo cycle to default keymaps
12 | 25d4817 Removed a print statement
13 | bf5f7b4 Pressing enter on TODO now changes to WORKING, and then DONE
14 | 514814a Added tri-state checkboxes. Some API changes as a result, but now a checkbox list performs identically to Emacs' orgmode checkboxes.
15 | ab2b1c0 Merge pull request #55 from edbedbe/master
16 | f5f3a56 added light org-mode color theme
17 | 9d22c59 Merge pull request #48 from rbenson/patch-1
18 | 34b9438 Merge pull request #47 from rbenson/master
19 | c158dde Update install.org
20 | a727cae adds support for deadlines and scheduled
21 | 1a1559c Merge pull request #46 from rbenson/master
22 | 4b9b94a Added support for headlines in GoTo Symbol
23 |
--------------------------------------------------------------------------------
/messages/install.org:
--------------------------------------------------------------------------------
1 | * After Install
2 | Apply orgmode syntax, ctrl+shift+p , then search for orgmode. This document will be colored.
3 |
4 | * Features
5 | Here's a list of all the features implemented so far:
6 |
7 | * Context sensitive highlighting
8 | - Headlines
9 | - Deadlines and due dates
10 | - Pages. E.g.:
11 | --- This is a page marker ---
12 | - Breaks. E.g.:
13 | ~ This is a break.
14 | - Tasks
15 | - Tags. E.g.: :important:, :one:two:three:
16 | - Follow ups. E.g.:
17 | -> Lorem ipsum.
18 | => Lorem ipsum.
19 | - Checkboxes
20 | - Checkbox summaries
21 | - External links
22 | - Inter document links. E.g. {1} {{Context sensitive actions}} {{Todo}}
23 | - Code blocks
24 | - Python tracebacks
25 |
26 | * Context sensitive actions
27 | - Toggle checkbox on pressing enter
28 | - TODO chain status cycles on pressing enter
29 | - Auto update of checkbox summary on toggle of checkboxes
30 | - Recalc number of children in checkbox summary on pressing enter
31 | - External link opener on pressing enter
32 | (currently only working on OSX and Windows)
33 | - Plugin-system including aliases
34 | - Plugin: Jira
35 | - Normal call: [[jira:PLAYGROUND]]
36 | - Alias j: [[j:PLAYGROUND-123]]
37 | - Plugin: Crucible code review
38 | - Normal call: [[crucible:CR-123]]
39 | - Aliases cru and cr: [[cr:CR-123]]
40 | - Plugin: FishEye repo incl. opt. changeset
41 | - Normal call: [[fisheye:some_repo]]
42 | - Normal call: [[fisheye:some_repo/revision_or_tag]]
43 | - Aliases fish and fe: [[fe:some_repo/123]]
44 | - Plugin: eMail
45 | - Create call: [[mailto:ok@ryotic.de]]
46 | - Create call with subject: [[mailto:ok@ryotic.de/some subject]]
47 | - Auto completion of filenames and directories when writing external links to local files
48 | - Jump between inter document links on pressing enter (e.g. {1})
49 | - Jump to linked headline on pressing enter (e.g. {{Installation}})
50 | - Show an outline of the document on using goto symbol
51 | - Open Python file at specific line from Python tracebacks when pressing enter on a filepath
52 |
53 | * Tab completions
54 | - Headlines: "*", "**", "***"
55 | - Pages: "p"
56 | - Breaks: "b"
57 | - Task: "-"
58 | - Task with unchecked checkbox: "-c"
59 | - Task with checked checkbox: "-cc"
60 | - Task with unchecked checkbox and external link: "-cl"
61 | - Task with TODO: "-t"
62 | - Task with WORKING: "-w"
63 | - Task with DONE: "-d"
64 | - Tag: "t"
65 | - Additional Tags: ":" (just keep hitting tab for more)
66 | - Follow ups: "f"
67 | - Sum ups: "ff"
68 | - External links: "l"
69 | - Inter document links: "i", "ii"
70 | - Checkbox unchecked: "c"
71 | - Checkbox checked: "cc"
72 | - Checkbox summary: "cs"
73 |
74 | * Todo [15/31]
75 | - [X] Persistant folding of headlines
76 | - needs indented formatting to work.
77 | - [X] Autocomplete for inserting current date, write "date" => 2013-05-25 18:53
78 | - [X] configure in settings
79 | - [X] Port to Sublime Text 3
80 | - [X] test
81 | - [X] mac,
82 | - [X] win,
83 | - [X] linux
84 | - [X] merge into sub2 branch, test both versions
85 | - [X] [[mailto:daniel@testtest.se]]
86 | - [X] support [[http://github.com]], [[https://github.com]]
87 | - [X] support [[cmd:c:\dev]]
88 | - [X] test all resolvers
89 | - [X] make key triggers work
90 | - [X] make theme work
91 | - [X] tmLangugage not working
92 | - [X] not crash on start
93 | - [X] import modules py3.3 style
94 | - [X] HelpIt integrated, alt+f1 looks up th eword on google.
95 | - [X] redmine, [[redmine:9726]], [[issue:9726]], [[#9726]]
96 | - [X] local file not working well for windows
97 | - [X] åäö problems
98 | - [X] linux open cmd line at "[[cmd:/home]]"
99 | - [X] open cmd line at "[[cmd:c:\dev]]"
100 | - [[cmd:c:\dev\]]
101 | - [[prompt:c:\dev\apps]]
102 | - [X] http resolver, make urls with '#'' work
103 | - [[http://www.sublimetext.com/forum/viewtopic.php?f=5&t=1838&p=18483#p18483]]
104 | - [X] https is not working, [[https://www.google.com/]]
105 | -https resolver..
106 | - [X] navigation history
107 | - [X] src refactor, moved settings to Global.sublime-settings
108 | - [X] added default theme in orgmode dir.
109 | - [X] External link opener on pressing enter [3/3]
110 | - [X] on OSX
111 | - [X] on Linux
112 | - [X] on Windows
113 | - [X] When (un-)checking *all* checkboxes of siblings, toggle parent checkbox.
114 | - [ ] Either make highlight_code_remarks.py configurable thru view settings so that orgmode can control its regex patterns or fork/extend it to archive an equal goal.
115 | - [ ] Export into formatted text file [0/1]
116 | - [ ] Format: Markdown
117 | - [ ] Automatic export after save into given format if mark found in org file.
118 | - [ ] Fix cursor position after filling checkbox summary on checkbox toggle
119 | - [ ] Tab trigger "c" [1/2]
120 | - [X] …which extends into "[ ] "
121 | - [ ] …and updates the summary
122 | - [ ] Define special block/area in document where time logging can occur. If one changes the status (TODO, WORKING, DONE etc.) this will be written into the log. Ideas for format are welcome!
123 | - [ ] If all children don't have checkboxes only show the number of children in the summary
124 | - [ ] If the summary ends with "%]" calculate percentage instead of amount
125 | - [ ] If multiple checkboxes are in one line only work with the one under the cursor
126 | - [ ] If multiple checkbox summaries are in one line only work with the one under the cursor
127 | - [ ] If mutliple checkbox summaries are in one line update every one of them independently on updating a child checkbox
128 | - [ ] Move key bindings out of readme into its own file
129 | - [ ] Move theme additions out of readme into its own file
130 | - [ ] Implement external link plugin: eMail [2/3]
131 | - [ ] Open call [[email:ok@ryotic.de/inbox/some title]]
132 | - [X] Create call [[mailto:ok@ryotic.de]]
133 | - [X] Create call with subject [[mailto:ok@ryotic.de/some subject]]
134 | - [X] Pressing return on a TODO chain shall set it to DONE
135 | - [ ] ASCII tables.
136 | - [ ] Code remark collector. Recursively scans a specified folder for files with given filename pattern for code remarks and shows them as a list. Should be realized with begin and end markers to support later update on pressing enter on either marker.
137 |
138 |
139 | * Known Issues
140 | - Subsequent indent of wrapped paragraphs don't respect stars, tacks, checkboxes, follow ups etc..
141 | -> [[http://sublimetext.userecho.com/feedback/26943-/]]
142 | - Update of checkbox summary should only see children who start with either an asterisk, tack or checkbox. Other things like external links or follow ups should be ignored.
143 |
144 | * External links
145 | {1} Homepage [[https://github.com/danielmagnussons/orgmode]]
146 | {2} Issue tracker [[https://github.com/danielmagnussons/orgmode/issues?state=open]]
147 | {3} Sublime Text 2 [[http://www.sublimetext.com/2]]
148 | {4} Org-Mode for Emacs [[http://orgmode.org/]]
149 |
150 | * Optional Attachments
151 |
152 | * Theme additions for proper syntax highlighting
153 | If you are not using Monokai Bright.tmTheme, put the following into your color scheme (.tmTheme file):
154 |
155 | [code]
156 |
157 | name
158 | orgmode link
159 | scope
160 | orgmode.link
161 | settings
162 |
163 | foreground
164 | #FB9A4B
165 | fontStyle
166 | underline
167 |
168 |
169 |
170 | name
171 | orgmode page
172 | scope
173 | orgmode.page
174 | settings
175 |
176 | foreground
177 | #FFFFAA
178 |
179 |
180 |
181 | name
182 | orgmode break
183 | scope
184 | orgmode.break
185 | settings
186 |
187 | foreground
188 | #FFAAAA
189 |
190 |
191 |
192 | name
193 | orgmode headline
194 | scope
195 | orgmode.headline
196 | settings
197 |
198 | foreground
199 | #9EFFFF
200 |
201 |
202 |
203 | name
204 | orgmode tack
205 | scope
206 | orgmode.tack
207 | settings
208 |
209 | foreground
210 | #FFFFAA
211 |
212 |
213 |
214 | name
215 | orgmode follow up
216 | scope
217 | orgmode.follow_up
218 | settings
219 |
220 | foreground
221 | #FFFFAA
222 |
223 |
224 |
225 | name
226 | orgmode checkbox
227 | scope
228 | orgmode.checkbox
229 | settings
230 |
231 | foreground
232 | #FFFFAA
233 |
234 |
235 |
236 | name
237 | orgmode checkbox summary
238 | scope
239 | orgmode.checkbox.summary
240 | settings
241 |
242 | foreground
243 | #FFFFAA
244 |
245 |
246 |
247 | name
248 | orgmode tags
249 | scope
250 | orgmode.tags
251 | settings
252 |
253 | foreground
254 | #AAFFAA
255 |
256 |
257 |
258 |
259 | name
260 | orgmode deadline
261 | scope
262 | orgmode.deadline
263 | settings
264 |
265 | foreground
266 | #AAFFAA
267 |
268 |
269 |
270 | name
271 | orgmode scheduled
272 | scope
273 | orgmode.scheduled
274 | settings
275 |
276 | foreground
277 | #0099FF
278 |
279 |
280 |
281 | [/code]
282 |
--------------------------------------------------------------------------------
/navigation_history.py:
--------------------------------------------------------------------------------
1 |
2 | '''
3 | http://www.sublimetext.com/forum/viewtopic.php?f=5&t=2738
4 |
5 | https://github.com/optilude/SublimeTextMisc
6 |
7 |
8 | Put this in your "Packages" directory and then configure "Key bindings - User" to use it. I use these keybindings for it on OS X:
9 |
10 | { "keys": ["alt+left"], "command": "navigation_history_back"},
11 | { "keys": ["alt+right"], "command": "navigation_history_forward"}
12 |
13 | '''
14 |
15 |
16 | import sublime
17 | import sublime_plugin
18 | from collections import deque
19 |
20 | MAX_SIZE = 64
21 | LINE_THRESHOLD = 2
22 |
23 |
24 | class Location(object):
25 |
26 | """A location in the history
27 | """
28 | def __init__(self, path, line, col):
29 | self.path = path
30 | self.line = line
31 | self.col = col
32 |
33 | def __eq__(self, other):
34 | return self.path == other.path and self.line == other.line
35 |
36 | def __ne__(self, other):
37 | return not self.__eq__(other)
38 |
39 | def __bool__(self):
40 | return (self.path is not None and self.line is not None)
41 |
42 | def near(self, other):
43 | return self.path == other.path and abs(self.line - other.line) <= LINE_THRESHOLD
44 |
45 | def copy(self):
46 | return Location(self.path, self.line, self.col)
47 |
48 |
49 | class History(object):
50 |
51 | """Keep track of the history for a single window
52 | """
53 |
54 | def __init__(self, max_size=MAX_SIZE):
55 | self._current = None # current location as far as the
56 | # history is concerned
57 | self._back = deque([], max_size) # items before self._current
58 | self._forward = deque([], max_size) # items after self._current
59 |
60 | self._last_movement = None # last recorded movement
61 |
62 | def record_movement(self, location):
63 | """Record movement to the given location, pushing history if
64 | applicable
65 | """
66 |
67 | if location:
68 | if self.has_changed(location):
69 | self.push(location)
70 | self.mark_location(location)
71 |
72 | def mark_location(self, location):
73 | """Remember the current location, for the purposes of being able
74 | to do a has_changed() check.
75 | """
76 | self._last_movement = location.copy()
77 |
78 | def has_changed(self, location):
79 | """Determine if the given location combination represents a
80 | significant enough change to warrant pushing history.
81 | """
82 |
83 | return self._last_movement is None or not self._last_movement.near(location)
84 |
85 | def push(self, location):
86 | """Push the given location to the back history. Clear the forward
87 | history.
88 | """
89 |
90 | if self._current is not None:
91 | self._back.append(self._current.copy())
92 | self._current = location.copy()
93 | self._forward.clear()
94 |
95 | def back(self):
96 | """Move backward in history, returning the location to jump to.
97 | Returns None if no history.
98 | """
99 |
100 | if not self._back:
101 | return None
102 |
103 | self._forward.appendleft(self._current)
104 | self._current = self._back.pop()
105 | self._last_movement = self._current # preempt, so we don't re-push
106 | return self._current
107 |
108 | def forward(self):
109 | """Move forward in history, returning the location to jump to.
110 | Returns None if no history.
111 | """
112 |
113 | if not self._forward:
114 | return None
115 |
116 | self._back.append(self._current)
117 | self._current = self._forward.popleft()
118 | self._last_movement = self._current # preempt, so we don't re-push
119 | return self._current
120 |
121 | _histories = {} # window id -> History
122 |
123 |
124 | def get_history():
125 | """Get a History object for the current window,
126 | creating a new one if required
127 | """
128 |
129 | window = sublime.active_window()
130 | if window is None:
131 | return None
132 |
133 | window_id = window.id()
134 | history = _histories.get(window_id, None)
135 | if history is None:
136 | _histories[window_id] = history = History()
137 | return history
138 |
139 |
140 | class NavigationHistoryRecorder(sublime_plugin.EventListener):
141 |
142 | """Keep track of history
143 | """
144 |
145 | def on_selection_modified(self, view):
146 | """When the selection is changed, possibly record movement in the
147 | history
148 | """
149 | history = get_history()
150 | if history is None:
151 | return
152 |
153 | path = view.file_name()
154 | row, col = view.rowcol(view.sel()[0].a)
155 | history.record_movement(Location(path, row + 1, col + 1))
156 |
157 | # def on_close(self, view):
158 | # """When a view is closed, check to see if the window was closed too
159 | # and clean up orphan histories
160 | # """
161 | #
162 | # XXX: This doesn't work - event runs before window is removed
163 | # from sublime.windows()
164 | #
165 | # windows_with_history = set(_histories.keys())
166 | # window_ids = set([w.id() for w in sublime.windows()])
167 | # closed_windows = windows_with_history.difference(window_ids)
168 | # for window_id in closed_windows:
169 | # del _histories[window_id]
170 |
171 |
172 | class NavigationHistoryBack(sublime_plugin.TextCommand):
173 |
174 | """Go back in history
175 | """
176 |
177 | def run(self, edit):
178 | history = get_history()
179 | if history is None:
180 | return
181 |
182 | location = history.back()
183 | if location:
184 | window = sublime.active_window()
185 | window.open_file("%s:%d:%d" % (
186 | location.path, location.line, location.col), sublime.ENCODED_POSITION)
187 |
188 |
189 | class NavigationHistoryForward(sublime_plugin.TextCommand):
190 |
191 | """Go forward in history
192 | """
193 |
194 | def run(self, edit):
195 | history = get_history()
196 | if history is None:
197 | return
198 |
199 | location = history.forward()
200 | if location:
201 | window = sublime.active_window()
202 | window.open_file("%s:%d:%d" % (
203 | location.path, location.line, location.col), sublime.ENCODED_POSITION)
204 |
--------------------------------------------------------------------------------
/orgmode.py:
--------------------------------------------------------------------------------
1 | '''
2 | Settings in orgmode.sublime-settings are:
3 | - orgmode.open_link.resolvers: See DEFAULT_OPEN_LINK_RESOLVERS.
4 | - orgmode.open_link.resolver.abstract.commands: See DEFAULT_OPEN_LINK_COMMANDS in resolver.abstract.
5 | For more settings see headers of specific resolvers.
6 | '''
7 |
8 | import sys
9 | import re
10 | import os.path
11 | import sublime
12 | import sublime_plugin
13 | import fnmatch
14 | import datetime
15 |
16 |
17 | try:
18 | import importlib
19 | except ImportError:
20 | pass
21 |
22 |
23 | DEFAULT_OPEN_LINK_RESOLVERS = [
24 | 'http',
25 | 'https',
26 | 'prompt',
27 | 'redmine',
28 | 'jira',
29 | 'crucible',
30 | 'fisheye',
31 | 'email',
32 | 'local_file',
33 | ]
34 |
35 |
36 | class OrgmodeNewTaskDocCommand(sublime_plugin.WindowCommand):
37 |
38 | def run(self):
39 | view = self.window.new_file()
40 | view.set_syntax_file('Packages/orgmode/orgmode.tmLanguage')
41 |
42 |
43 | def find_resolvers():
44 | base = os.path.dirname(os.path.abspath(__file__))
45 | path = base + '/resolver'
46 | available_resolvers = {}
47 | for root, dirnames, filenames in os.walk(base + '/resolver'):
48 | for filename in fnmatch.filter(filenames, '*.py'):
49 | module_path = 'orgmode.resolver.' + filename.split('.')[0]
50 | if sys.version_info[0] < 3:
51 | module_path = 'resolver.' + filename.split('.')[0]
52 | name = filename.split('.')[0]
53 | module = __import__(module_path, globals(), locals(), name)
54 | module = reload(module)
55 | else:
56 | module = importlib.import_module(module_path)
57 | if '__init__' in filename or 'abstract' in filename:
58 | continue
59 | available_resolvers[filename.split('.')[0]] = module
60 | return available_resolvers
61 | available_resolvers = find_resolvers()
62 |
63 |
64 | class OrgmodeOpenLinkCommand(sublime_plugin.TextCommand):
65 |
66 | def __init__(self, *args, **kwargs):
67 | super(OrgmodeOpenLinkCommand, self).__init__(*args, **kwargs)
68 | settings = sublime.load_settings('orgmode.sublime-settings')
69 | wanted_resolvers = settings.get(
70 | 'orgmode.open_link.resolvers', DEFAULT_OPEN_LINK_RESOLVERS)
71 | self.resolvers = [available_resolvers[name].Resolver(self.view)
72 | for name in wanted_resolvers]
73 |
74 | def resolve(self, content):
75 | for resolver in self.resolvers:
76 | result = resolver.resolve(content)
77 | if result is not None:
78 | return resolver, result
79 | return None, None
80 |
81 | def is_valid_scope(self, sel):
82 | scope_name = self.view.scope_name(sel.end())
83 | return 'orgmode.link' in scope_name
84 |
85 | def extract_content(self, region):
86 | content = self.view.substr(region)
87 | if content.startswith('[[') and content.endswith(']]'):
88 | content = content[2:-2]
89 | return content
90 |
91 | def run(self, edit):
92 | view = self.view
93 | for sel in view.sel():
94 | if not self.is_valid_scope(sel):
95 | continue
96 | region = view.extract_scope(sel.end())
97 | content = self.extract_content(region)
98 | resolver, content = self.resolve(content)
99 | if content is None:
100 | sublime.error_message('Could not resolve link:\n%s' % content)
101 | continue
102 | resolver.execute(content)
103 |
104 |
105 | class OrgmodeOpenPythonRefCommand(OrgmodeOpenLinkCommand):
106 |
107 | def __init__(self, *args, **kwargs):
108 | super(OrgmodeOpenPythonRefCommand, self).__init__(*args, **kwargs)
109 | pattern = r'.+", line (?P\d+), in (?P.+)$'
110 | self.regex = re.compile(pattern)
111 |
112 | def is_valid_scope(self, sel):
113 | scope_name = self.view.scope_name(sel.end())
114 | return 'filepath reference orgmode.python.traceback' in scope_name
115 |
116 | def extract_content(self, region):
117 | content = self.view.substr(region)
118 | outer_region = self.view.extract_scope(region.end() + 1)
119 | scope_name = self.view.scope_name(region.end() + 1)
120 | # print scope_name
121 | if 'reference orgmode.python.traceback' in scope_name:
122 | outer_content = self.view.substr(outer_region)
123 | # print outer_content
124 | match = self.regex.match(outer_content)
125 | if match:
126 | # print match.groupdict()
127 | content += ':%s' % match.group('line')
128 | return content
129 |
130 |
131 | class OrgmodeCycleInternalLinkCommand(sublime_plugin.TextCommand):
132 |
133 | def run(self, edit):
134 | view = self.view
135 | sels = view.sel()
136 | sel = sels[0]
137 | if 'orgmode.link.internal' not in view.scope_name(sel.end()):
138 | return
139 | region = view.extract_scope(sel.end())
140 | content = view.substr(region).strip()
141 | if content.startswith('{{') and content.endswith('}}'):
142 | content = '* %s' % content[2:-2]
143 | found = self.view.find(content, region.end(), sublime.LITERAL)
144 | if not found: # Try wrapping around buffer.
145 | found = self.view.find(content, 0, sublime.LITERAL)
146 | same = region.a == found.a and region.b == found.b
147 | if not found or same:
148 | sublime.status_message('No sibling found for: %s' % content)
149 | return
150 | found = view.extract_scope(found.begin())
151 | sels.clear()
152 | sels.add(sublime.Region(found.begin()))
153 | try:
154 | import show_at_center_and_blink
155 | view.run_command('show_at_center_and_blink')
156 | except ImportError:
157 | view.show_at_center(found)
158 |
159 | class CheckState:
160 | Unchecked, Checked, Indeterminate, Error = range(1, 5);
161 |
162 |
163 | class AbstractCheckboxCommand(sublime_plugin.TextCommand):
164 |
165 | def __init__(self, *args, **kwargs):
166 | super(AbstractCheckboxCommand, self).__init__(*args, **kwargs)
167 | indent_pattern = r'^(\s*).*$'
168 | summary_pattern = r'(\[\d*[/]\d*\])'
169 | checkbox_pattern = r'(\[[X\- ]\])'
170 | self.indent_regex = re.compile(indent_pattern)
171 | self.summary_regex = re.compile(summary_pattern)
172 | self.checkbox_regex = re.compile(checkbox_pattern)
173 |
174 | def get_indent(self, content):
175 | if isinstance(content, sublime.Region):
176 | content = self.view.substr(content)
177 | match = self.indent_regex.match(content)
178 | indent = match.group(1)
179 | return indent
180 |
181 | def find_parent(self, region):
182 | view = self.view
183 | row, col = view.rowcol(region.begin())
184 | line = view.line(region)
185 | content = view.substr(line)
186 | # print content
187 | indent = len(self.get_indent(content))
188 | # print repr(indent)
189 | row -= 1
190 | found = False
191 | while row >= 0:
192 | point = view.text_point(row, 0)
193 | line = view.line(point)
194 | content = view.substr(line)
195 | if len(content.strip()):
196 | cur_indent = len(self.get_indent(content))
197 | if cur_indent < indent:
198 | found = True
199 | break
200 | row -= 1
201 | if found:
202 | # print row
203 | point = view.text_point(row, 0)
204 | line = view.line(point)
205 | return line
206 |
207 | def find_children(self, region):
208 | view = self.view
209 | row, col = view.rowcol(region.begin())
210 | line = view.line(region)
211 | content = view.substr(line)
212 | # print content
213 | indent = len(self.get_indent(content))
214 | # print repr(indent)
215 | row += 1
216 | child_indent = None
217 | children = []
218 | last_row, _ = view.rowcol(view.size())
219 | while row <= last_row:
220 | point = view.text_point(row, 0)
221 | line = view.line(point)
222 | content = view.substr(line)
223 | summary = self.get_summary(line)
224 | if summary and content.lstrip().startswith("*"):
225 | break
226 | if self.checkbox_regex.search(content):
227 | cur_indent = len(self.get_indent(content))
228 | # check for end of descendants
229 | if cur_indent <= indent:
230 | break
231 | # only immediate children
232 | if child_indent is None:
233 | child_indent = cur_indent
234 | if cur_indent == child_indent:
235 | children.append(line)
236 | row += 1
237 | return children
238 |
239 | def find_siblings(self, child, parent):
240 | view = self.view
241 | row, col = view.rowcol(parent.begin())
242 | parent_indent = self.get_indent(parent)
243 | child_indent = self.get_indent(child)
244 | # print '***', repr(parent_indent), repr(child_indent)
245 | siblings = []
246 | row += 1
247 | last_row, _ = view.rowcol(view.size())
248 | while row <= last_row: # Don't go past end of document.
249 | line = view.text_point(row, 0)
250 | line = view.line(line)
251 | content = view.substr(line)
252 | # print content
253 | if len(content.strip()):
254 | cur_indent = self.get_indent(content)
255 | if len(cur_indent) <= len(parent_indent):
256 | # print 'OUT'
257 | break # Indent same as parent found!
258 | if len(cur_indent) == len(child_indent):
259 | # print 'MATCH'
260 | siblings.append((line, content))
261 | row += 1
262 | return siblings
263 |
264 | def get_summary(self, line):
265 | view = self.view
266 | row, _ = view.rowcol(line.begin())
267 | content = view.substr(line)
268 | # print content
269 | match = self.summary_regex.search(content)
270 | if not match:
271 | return None
272 | # summary = match.group(1)
273 | # print(repr(summary))
274 | # print dir(match), match.start(), match.span()
275 | col_start, col_stop = match.span()
276 | return sublime.Region(
277 | view.text_point(row, col_start),
278 | view.text_point(row, col_stop),
279 | )
280 |
281 | def get_checkbox(self, line):
282 | view = self.view
283 | row, _ = view.rowcol(line.begin())
284 | content = view.substr(line)
285 | # print content
286 | match = self.checkbox_regex.search(content)
287 | if not match:
288 | return None
289 | # checkbox = match.group(1)
290 | # print repr(checkbox)
291 | # print dir(match), match.start(), match.span()
292 | col_start, col_stop = match.span()
293 | return sublime.Region(
294 | view.text_point(row, col_start),
295 | view.text_point(row, col_stop),
296 | )
297 |
298 | def get_check_state(self, line):
299 | if '[-]' in self.view.substr(line):
300 | return CheckState.Indeterminate
301 | if '[ ]' in self.view.substr(line):
302 | return CheckState.Unchecked
303 | if '[X]' in self.view.substr(line):
304 | return CheckState.Checked
305 | return CheckState.Error
306 |
307 | def get_check_char(self, check_state):
308 | if check_state == CheckState.Unchecked:
309 | return ' '
310 | elif check_state == CheckState.Checked:
311 | return 'X'
312 | elif check_state == CheckState.Indeterminate:
313 | return '-'
314 | else:
315 | return 'E'
316 |
317 | def recalc_summary(self, region):
318 | # print('recalc_summary')
319 | children = self.find_children(region)
320 | if not len(children) > 0:
321 | return (0, 0)
322 | # print children
323 | num_children = len(children)
324 | checked_children = len(
325 | [child for child in children if (self.get_check_state(child) == CheckState.Checked)])
326 | # print ('checked_children: ' + str(checked_children) + ', num_children: ' + str(num_children))
327 | return (num_children, checked_children)
328 |
329 | def update_line(self, edit, region, parent_update=True):
330 | #print ('update_line', self.view.rowcol(region.begin())[0]+1)
331 | (num_children, checked_children) = self.recalc_summary(region)
332 | if not num_children > 0:
333 | return False
334 | # update region checkbox
335 | if checked_children == num_children:
336 | newstate = CheckState.Checked
337 | else:
338 | if checked_children != 0:
339 | newstate = CheckState.Indeterminate
340 | else:
341 | newstate = CheckState.Unchecked
342 | self.toggle_checkbox(edit, region, newstate)
343 | # update region summary
344 | self.update_summary(edit, region, checked_children, num_children)
345 |
346 | children = self.find_children(region)
347 | for child in children:
348 | line = self.view.line(child)
349 | summary = self.get_summary(self.view.line(child))
350 | if summary:
351 | return self.update_line(edit, line, parent_update=False)
352 |
353 | if parent_update:
354 | parent = self.find_parent(region)
355 | if parent:
356 | self.update_line(edit, parent)
357 |
358 | return True
359 |
360 | def update_summary(self, edit, region, checked_children, num_children):
361 | # print('update_summary', self.view.rowcol(region.begin())[0]+1)
362 | view = self.view
363 | summary = self.get_summary(region)
364 | if not summary:
365 | return False
366 | # print('checked_children: ' + str(checked_children) + ', num_children: ' + str(num_children))
367 | view.replace(edit, summary, '[%d/%d]' % (
368 | checked_children, num_children))
369 |
370 | def toggle_checkbox(self, edit, region, checked=None, recurse_up=False, recurse_down=False):
371 | # print 'toggle_checkbox', self.view.rowcol(region.begin())[0]+1
372 | view = self.view
373 | checkbox = self.get_checkbox(region)
374 | if not checkbox:
375 | return False
376 | if checked is None:
377 | check_state = self.get_check_state(region)
378 | if (check_state == CheckState.Unchecked) | (check_state == CheckState.Indeterminate):
379 | check_state = CheckState.Checked
380 | elif (check_state == CheckState.Checked):
381 | check_state = CheckState.Unchecked
382 | else:
383 | check_state = checked
384 | view.replace(edit, checkbox, '[%s]' % ( self.get_check_char(check_state)))
385 | if recurse_down:
386 | # all children should follow
387 | children = self.find_children(region)
388 | for child in children:
389 | self.toggle_checkbox(edit, child, check_state, recurse_down=True)
390 | if recurse_up:
391 | # update parent
392 | parent = self.find_parent(region)
393 | if parent:
394 | self.update_line(edit, parent)
395 |
396 |
397 | class OrgmodeCycleTodoCommand(sublime_plugin.TextCommand):
398 |
399 | def __init__(self, *args, **kwargs):
400 | super(OrgmodeCycleTodoCommand, self).__init__(*args, **kwargs)
401 |
402 | self.status = ["TODO", "WORKING", "DONE"]
403 | todo_pattern = r"|".join(self.status)
404 | self.todo_regex = re.compile(todo_pattern)
405 |
406 |
407 | def run(self, edit):
408 |
409 | view = self.view
410 | sels = view.sel()
411 | sel = sels[0]
412 |
413 | # Get the scope name for the current cursor position
414 | # also contains other scopes
415 | if 'orgmode.todo' not in view.scope_name(sel.end()):
416 | return
417 |
418 | # If the cursor is at the end of the view, return.
419 | if (sel.end() == sel.begin()) and (sel.end() == view.size()):
420 | view.insert(edit, view.size(), "\n")
421 | view.show(view.size())
422 | return
423 |
424 | region = view.extract_scope(sel.end())
425 |
426 | todo = self.get_todo(region)
427 | content = self.view.substr(todo)
428 |
429 | next_status_index = (self.status.index(content) + 1) % len(self.status)
430 | view.replace(edit, todo, self.status[next_status_index])
431 |
432 |
433 | def get_todo(self, line):
434 | view = self.view
435 | row, _ = view.rowcol(line.begin())
436 | content = view.substr(line)
437 | # print content
438 | match = self.todo_regex.search(content)
439 | if not match:
440 | return None
441 | # checkbox = match.group(1)
442 | # print repr(checkbox)
443 | # print dir(match), match.start(), match.span()
444 | col_start, col_stop = match.span()
445 | return sublime.Region(
446 | view.text_point(row, col_start),
447 | view.text_point(row, col_stop),
448 | )
449 |
450 |
451 | class OrgmodeToggleCheckboxCommand(AbstractCheckboxCommand):
452 |
453 | def run(self, edit):
454 | view = self.view
455 | backup = []
456 | for sel in view.sel():
457 | if 'orgmode.checkbox' not in view.scope_name(sel.end()):
458 | continue
459 | backup.append(sel)
460 | checkbox = view.extract_scope(sel.end())
461 | line = view.line(checkbox)
462 | self.toggle_checkbox(edit, line, recurse_up=True, recurse_down=True)
463 | view.sel().clear()
464 | for region in backup:
465 | view.sel().add(region)
466 |
467 |
468 | class OrgmodeRecalcCheckboxSummaryCommand(AbstractCheckboxCommand):
469 |
470 | def run(self, edit):
471 | view = self.view
472 | backup = []
473 | for sel in view.sel():
474 | if 'orgmode.checkbox.summary' not in view.scope_name(sel.end()):
475 | continue
476 | backup.append(sel)
477 | summary = view.extract_scope(sel.end())
478 | line = view.line(summary)
479 | self.update_line(edit, line)
480 | view.sel().clear()
481 | for region in backup:
482 | view.sel().add(region)
483 |
484 |
485 | class OrgmodeLinkCompletions(sublime_plugin.EventListener):
486 |
487 | def on_query_completions(self, view, prefix, locations):
488 | import os
489 | from glob import glob
490 | # print 'view =', view
491 | # print 'preifx =', prefix
492 | # print 'locations =', locations
493 | location = locations[0]
494 | if not 'orgmode.link' in view.scope_name(location):
495 | return []
496 | region = view.extract_scope(location)
497 | content = view.substr(region)
498 | inner_region = region
499 | if content.startswith('[[') and content.endswith(']]'):
500 | content = content[2:-2]
501 | inner_region = sublime.Region(region.begin() + 2, region.end() - 2)
502 | if not inner_region.contains(location):
503 | return []
504 | content = view.substr(sublime.Region(inner_region.begin(), location))
505 | content = os.path.expandvars(content)
506 | content = os.path.expanduser(content)
507 | # print 'region =', region
508 | # print 'content =', content
509 | path, base = os.path.split(content)
510 | # print 'split =', path, base
511 | if not len(path):
512 | path = os.path.dirname(view.file_name())
513 | if not os.path.exists(path):
514 | path = os.path.join(os.path.dirname(view.file_name()), path)
515 | # print 'path =', path, base
516 | pattern = os.path.join(path, '%s*' % base)
517 | # print 'pattern =', pattern
518 | files = glob(pattern)
519 | basename = os.path.basename
520 | isdir = os.path.isdir
521 | for pos, item in enumerate(files[:]):
522 | expr = basename(item)
523 | snippet = basename(item)
524 | if isdir(item):
525 | expr += '/'
526 | snippet += '/'
527 | files[pos] = (expr, snippet)
528 | # print 'files =', files
529 | if not files:
530 | return [(base + '/', base)]
531 | return files
532 |
533 |
534 | class OrgmodeDateCompleter(sublime_plugin.EventListener):
535 |
536 | def on_query_completions(self, view, prefix, locations):
537 | if not has_file_ext(view, "org"):
538 | return []
539 | self.settings = sublime.load_settings('orgmode.sublime-settings')
540 | self.date_format = self.settings.get(
541 | 'orgmode.autocomplete.date', "%Y-%m-%d %H:%M")
542 | self.date_format_cmd = self.settings.get(
543 | 'orgmode.autocomplete.date.cmd', "date")
544 |
545 | return [
546 | (self.date_format_cmd, datetime.datetime.now().strftime(
547 | self.date_format)),
548 | ("week", str(datetime.datetime.now().isocalendar()[1])),
549 | ]
550 |
551 | def has_file_ext(view, ext):
552 | """Returns ``True`` if view has file extension ``ext``.
553 | ``ext`` may be specified with or without leading ``.``.
554 | """
555 | if not view.file_name(): return False
556 | if not ext.strip().replace('.', ''): return False
557 |
558 | if not ext.startswith('.'):
559 | ext = '.' + ext
560 |
561 | return view.file_name().lower().endswith(ext)
562 |
--------------------------------------------------------------------------------
/orgmode.sublime-settings:
--------------------------------------------------------------------------------
1 | {
2 | // Global
3 | "color_scheme": "Packages/orgmode/Color Scheme/orgmode.tmTheme",
4 | "word_wrap": true,
5 | "translate_tabs_to_spaces": true,
6 | "tab_size": 2,
7 | "auto_indent": true,
8 | "indent_subsequent_lines": true,
9 | "detect_indentation": false,
10 | "line_numbers": true,
11 | "save_on_focus_lost": true,
12 | "gutter": true,
13 |
14 | // autocomplete of "date" will insert current date with format
15 | "orgmode.autocomplete.date.cmd":"date",
16 | "orgmode.autocomplete.date":"%Y-%m-%d %H:%M",
17 |
18 |
19 | //orgmode resolvers
20 | //jira
21 | "orgmode.open_link.resolver.jira.url":"http://sandbox.onjira.com/browse/%s",
22 | "orgmode.open_link.resolver.jira.pattern":"^(jira|j):(?P.+)$",
23 |
24 | //redmine
25 | "orgmode.open_link.resolver.redmine.url":"http://google.org/issues/%s",
26 | "orgmode.open_link.resolver.redmine.pattern":"^(issue:|redmine:|#)(?P.+)$",
27 |
28 | //crucible
29 | "orgmode.open_link.resolver.crucible.url":"http://sandbox.fisheye.atlassian.com/cru/%s",
30 | "orgmode.open_link.resolver.crucible.pattern":"^(crucible|cru|cr):(?P.+)$",
31 |
32 | //email
33 | "orgmode.open_link.resolver.email.url":"mailto:%s",
34 | "orgmode.open_link.resolver.email.pattern":"^(?Pemail|mailto):(?P[^/]+)(/(?P.+))?$",
35 |
36 | //fisheye
37 | "orgmode.open_link.resolver.fisheye.url":"http://sandbox.fisheye.atlassian.com/changelog/%s",
38 | "orgmode.open_link.resolver.fisheye.pattern":"^(fisheye|fish|fe):(?P[^/]+)(/(?P.+))?$",
39 |
40 | //prompt
41 | "orgmode.open_link.resolver.prompt.pattern":"^(cmd:|prompt:)(?P.+)$",
42 |
43 | //local_file
44 | "orgmode.open_link.resolver.local_file.force_into_sublime":"'*.txt', '*.org', '*.py', '*.rb', '*.html', '*.css', '*.js', '*.php', '*.c', '*.cpp', '*.h'",
45 | "orgmode.open_link.resolver.local_file.pattern":"^(?P.+?)(?::(?P\\d+)(?::(?P\\d+))?)?$",
46 |
47 |
48 |
49 | // HelpIt
50 | "cocoa" : {
51 | "url" : "http://www.google.com/search?btnI=1&q=site:developer.apple.com+%s"
52 | },
53 | "objc" : {
54 | "url" : "http://www.google.com/search?btnI=1&q=site:developer.apple.com+%s"
55 | },
56 | "java" : {
57 | "url" : "http://www.google.com/search?btnI=1&q=site:docs.oracle.com+javadoc+%s"
58 | },
59 | "python" : {
60 | "url" : "http://docs.python.org/search.html?q=%s"
61 | },
62 | "php" : {
63 | "url" : "http://php.net/%s"
64 | },
65 | "less" : {
66 | "map" : "css"
67 | },
68 | "js" : {
69 | "sub" : [{
70 | "contains" : "$",
71 | "url" : "http://api.jquery.com/%s",
72 | "remove" : "\\$.*\\."
73 | }]
74 | },
75 | "html" : "http://www.google.com/search?btnI=1&q=site:w3schools.com/html5+tag+%s",
76 | "plain": "http://answers.com/%s"
77 | }
78 |
--------------------------------------------------------------------------------
/orgmode.tmLanguage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | fileTypes
6 |
7 | org
8 | tasks
9 |
10 | keyEquivalent
11 | ^~P
12 | name
13 | orgmode
14 | patterns
15 |
16 |
17 | name
18 | orgmode.page
19 | match
20 | ^\s*\-\-\- [^\n]*
21 |
22 |
23 | name
24 | orgmode.break
25 | match
26 | ^\s*[~]+ [^\n]*
27 |
28 |
29 | name
30 | orgmode.headline
31 | match
32 | ^\s*[*]+ [^\[\]:\n]*
33 |
34 |
35 | name
36 | orgmode.deadline
37 | match
38 | DEADLINE: <\d{4}-\d{2}-\d{2}(?:\s*\w{3}>|>)
39 |
40 |
41 | name
42 | orgmode.scheduled
43 | match
44 | SCHEDULED: <\d{4}-\d{2}-\d{2}(?:\s*\w{3}>|>)
45 |
46 |
47 | name
48 | orgmode.tack
49 | match
50 | ^\s*\-
51 |
52 |
53 | name
54 | orgmode.follow_up
55 | match
56 | ^\s*(\-\>|\=\>)
57 |
58 |
59 | name
60 | orgmode.checkbox
61 | match
62 | (\[[xX\- ]\])\s?
63 |
64 |
65 | name
66 | orgmode.checkbox.summary
67 | match
68 | (\[\d*[/]\d*\])
69 |
70 |
71 | name
72 | orgmode.link
73 | match
74 | \[\[(.+?)?\]\]
75 |
76 |
77 | name
78 | orgmode.link.internal.number
79 | match
80 | \{(\d+)\}
81 |
82 |
83 | name
84 | orgmode.link.internal.headline
85 | match
86 | \{\{(.+?)\}\}
87 |
88 |
89 | contentName
90 | text source
91 | begin
92 | \[code\]\s*
93 | end
94 | \s*\[/code\]
95 | patterns
96 |
97 |
98 | include
99 | #python_exception.reference
100 |
101 |
102 |
103 |
104 | name
105 | orgmode.tags
106 | match
107 | (^|\s):[\w\d:]+:
108 |
109 |
110 | name
111 | orgmode.todo
112 | match
113 | TODO|WORKING|DONE
114 |
115 |
116 | name
117 | orgmode.python.traceback
118 | begin
119 | ^\s*Traceback \(most recent call last\):\s*$
120 | end
121 | ^\s*\w+: .+$
122 | patterns
123 |
124 |
125 | include
126 | #python_exception.reference
127 |
128 |
129 |
130 |
131 |
132 | scopeName
133 | text.orgmode
134 | uuid
135 | D0287542-2284-452C-8648-B885B3E16B6F
136 |
137 |
138 |
--------------------------------------------------------------------------------
/orgmode_store.py:
--------------------------------------------------------------------------------
1 | from gzip import GzipFile
2 | from os import makedirs
3 | from os.path import dirname, join, abspath
4 | from pickle import load, dump
5 | import os
6 | from os.path import dirname, realpath
7 | import sublime
8 | import sublime_plugin
9 | import logging as log
10 |
11 | log.basicConfig(level=log.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
12 |
13 | class OrgmodeStore(sublime_plugin.EventListener):
14 |
15 | def __init__(self, *args, **kwargs):
16 | self.debug = False
17 | self.db = {}
18 | self.store = os.path.join(dirname(dirname(realpath(__file__))),
19 | 'Settings',
20 | 'orgmode-store.bin.gz')
21 | log.debug("Orgmode settings path: " + self.store)
22 | try:
23 | makedirs(dirname(self.store))
24 | except:
25 | pass
26 | try:
27 | with GzipFile(self.store, 'rb') as f:
28 | self.db = load(f)
29 | except:
30 | self.db = {}
31 |
32 | self.on_load(sublime.active_window().active_view())
33 | for window in sublime.windows():
34 | self.on_load(window.active_view())
35 |
36 |
37 | def on_load(self, view):
38 | self.restore(view, 'on_load')
39 |
40 | def on_deactivated(self, view):
41 | window = view.window()
42 | if not window:
43 | window = sublime.active_window()
44 | index = window.get_view_index(view)
45 | if index != (-1, -1): # if the view was not closed
46 | self.save(view, 'on_deactivated')
47 |
48 | def on_activated(self, view):
49 | self.restore(view, 'on_activated')
50 |
51 | def on_pre_close(self, view):
52 | self.save(view, 'on_pre_close')
53 |
54 | def on_pre_save(self, view):
55 | self.save(view, 'on_pre_save')
56 |
57 | def save(self, view, where='unknow'):
58 | if view is None or not view.file_name():
59 | return
60 |
61 | if view.is_loading():
62 | sublime.set_timeout(lambda: self.save(view, where), 100)
63 | return
64 |
65 | _filename = view.file_name()
66 | if _filename not in self.db:
67 | self.db[_filename] = {}
68 |
69 | # if the result of the new collected data is different
70 | # from the old data, then will write to disk
71 | # this will hold the old value for comparison
72 | old_db = dict(self.db[_filename])
73 |
74 | # if the size of the view change outside the application skip
75 | # restoration
76 | self.db[_filename]['id'] = int(view.size())
77 |
78 | # marks
79 | self.db[_filename]['m'] = [[item.a, item.b]
80 | for item in view.get_regions("mark")]
81 | if self.debug:
82 | log.debug('marks: ' + str(self.db[_filename]['m']))
83 |
84 | # previous folding save, to be able to refold
85 | if 'f' in self.db[_filename] and list(self.db[_filename]['f']) != []:
86 | self.db[_filename]['pf'] = list(self.db[_filename]['f'])
87 |
88 | # folding
89 | self.db[_filename]['f'] = [[item.a, item.b] for item in view.folded_regions()]
90 | if self.debug:
91 | log.debug('fold: ' + str(self.db[_filename]['f']))
92 |
93 |
94 | if not self.db[_filename]['f'] and not self.db[_filename]['m']:
95 | if self.debug:
96 | log.debug("Nothing to save")
97 | return
98 |
99 | # write to disk only if something changed
100 | if old_db != self.db[_filename] or where == 'on_deactivated':
101 | log.debug("Orgmode settings write path: " + self.store)
102 | with GzipFile(self.store, 'wb') as f:
103 | dump(self.db, f, -1)
104 |
105 | def restore(self, view, where='unknow'):
106 | if view is None or not view.file_name():
107 | return
108 |
109 | if view.is_loading():
110 | sublime.set_timeout(lambda: self.restore(view, where), 100)
111 | return
112 |
113 | _filename = view.file_name()
114 | if _filename in self.db:
115 | if self.debug:
116 | log.debug('-----------------------------------')
117 | log.debug('RESTORING from: ' + where)
118 | log.debug('file: ' + view.file_name())
119 | # fold
120 | rs = []
121 | for r in self.db[_filename]['f']:
122 | rs.append(sublime.Region(int(r[0]), int(r[1])))
123 | if len(rs):
124 | view.fold(rs)
125 | if self.debug:
126 | log.debug("fold: " + str(rs))
127 |
128 | # marks
129 | rs = []
130 | for r in self.db[_filename]['m']:
131 | rs.append(sublime.Region(int(r[0]), int(r[1])))
132 | if len(rs):
133 | view.add_regions(
134 | "mark", rs, "mark", "dot", sublime.HIDDEN | sublime.PERSISTENT)
135 | if self.debug:
136 | log.debug('marks: ' + str(self.db[_filename]['m']))
137 |
138 |
139 | class OrgmodeFoldingCommand(sublime_plugin.TextCommand):
140 | """
141 | Bind to TAB key, and if the current line is not
142 | a headline, a \t would be inserted.
143 | """
144 |
145 | def run(self, edit):
146 | (row,col) = self.view.rowcol(self.view.sel()[0].begin())
147 | line = row + 1
148 | log.debug(line)
149 | for s in self.view.sel():
150 | r = self.view.full_line(s)
151 | if self._is_region_folded(r.b + 1, self.view):
152 | self.view.run_command("unfold")
153 | return
154 |
155 | pt = self.view.text_point(line, 0)
156 | self.view.sel().clear()
157 | self.view.sel().add(sublime.Region(pt))
158 | self.view.run_command("fold")
159 |
160 | def _is_region_folded(self, region, view):
161 | for i in view.folded_regions():
162 | if i.contains(region):
163 | return True
164 | return False
165 |
--------------------------------------------------------------------------------
/packages.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema_version": "2.0",
3 | "packages": [
4 | {
5 | "name": "orgmode",
6 | "author": "Daniel Magnusson(danielmagnussons)",
7 | "homepage": "https://github.com/danielmagnussons/orgmode",
8 | "donate": "https://www.gittip.com/danielmagnussons/",
9 | "details": "https://github.com/danielmagnussons/orgmode",
10 | "labels": ["text manipulation", "text navigation", "formatting", "todo", "color scheme"],
11 | "releases": [
12 | {
13 | "sublime_text": "*",
14 | "details": "https://github.com/danielmagnussons/orgmode/tags"
15 | }
16 | ]
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/resolver/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/danielmagnussons/orgmode/73d52ba15a39e0c0649ed268ca1f268800a990aa/resolver/__init__.py
--------------------------------------------------------------------------------
/resolver/abstract.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import sys
3 | import subprocess
4 | import sublime
5 |
6 |
7 | DEFAULT_OPEN_LINK_COMMANDS = dict(
8 | # Standard universal can opener for OSX.
9 | darwin=['open'],
10 | win32=['cmd', '/C', 'start'],
11 | linux=['xdg-open'],
12 | )
13 |
14 |
15 | class AbstractLinkResolver(object):
16 |
17 | def __init__(self, view):
18 | self.view = view
19 | self.settings = sublime.load_settings('orgmode.sublime-settings')
20 | self.link_commands = self.settings.get(
21 | 'orgmode.open_link.resolver.abstract.commands', DEFAULT_OPEN_LINK_COMMANDS)
22 |
23 | def extract(self, content):
24 | return content
25 |
26 | def replace(self, content):
27 | return content
28 |
29 | def resolve(self, content):
30 | match = self.extract(content)
31 | if not match:
32 | return None
33 | return self.replace(match)
34 |
35 | def get_link_command(self):
36 | platform = sys.platform
37 | for key, val in self.link_commands.items():
38 | if key in platform:
39 | return val
40 | return None
41 |
42 | def execute(self, content):
43 | command = self.get_link_command()
44 | if not command:
45 | sublime.error_message(
46 | 'Could not get link opener command.\nPlatform not yet supported.')
47 | return None
48 |
49 | if sys.version_info[0] < 3:
50 | content = content.encode(sys.getfilesystemencoding())
51 |
52 | cmd = command + [content]
53 | arg_list_wrapper = self.settings.get(
54 | "orgmode.open_link.resolver.abstract.arg_list_wrapper", [])
55 | if arg_list_wrapper:
56 | cmd = arg_list_wrapper + [' '.join(cmd)]
57 | source_filename = '\"' + self.view.file_name() + '\"'
58 | cmd += [source_filename]
59 | if sys.platform != 'win32':
60 | cmd += ['--origin', source_filename, '--quiet']
61 |
62 | print('*****')
63 | print(repr(content), content)
64 | print(cmd)
65 | sublime.status_message('Executing: %s' % cmd)
66 |
67 | if sys.platform != 'win32':
68 | process = subprocess.Popen(
69 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
70 | else:
71 | process = subprocess.Popen(
72 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
73 |
74 | stdout, stderr = process.communicate()
75 | if stdout:
76 | stdout = str(stdout, sys.getfilesystemencoding())
77 | sublime.status_message(stdout)
78 | if stderr:
79 | stderr = str(stderr, sys.getfilesystemencoding())
80 | sublime.error_message(stderr)
81 |
82 |
83 | class AbstractRegexLinkResolver(AbstractLinkResolver):
84 |
85 | def __init__(self, view):
86 | self.view = view
87 | self.settings = sublime.load_settings('orgmode.sublime-settings')
88 | self.link_commands = self.settings.get(
89 | 'orgmode.open_link.resolver.abstract.commands', DEFAULT_OPEN_LINK_COMMANDS)
90 | self.regex = None
91 |
92 | def extract(self, content):
93 | if self.regex is None:
94 | return content
95 | match = self.regex.match(content)
96 | return match
97 |
98 | def replace(self, match):
99 | return match.groups()[1]
100 |
--------------------------------------------------------------------------------
/resolver/crucible.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | from .abstract import AbstractRegexLinkResolver
4 |
5 |
6 | PATTERN_SETTING = 'orgmode.open_link.resolver.crucible.pattern'
7 | PATTERN_DEFAULT = r'^(crucible|cru|cr):(?P.+)$'
8 | URL_SETTING = 'orgmode.open_link.resolver.crucible.url'
9 | URL_DEFAULT = 'http://sandbox.fisheye.atlassian.com/cru/%s'
10 |
11 |
12 | class Resolver(AbstractRegexLinkResolver):
13 |
14 | def __init__(self, view):
15 | super(Resolver, self).__init__(view)
16 | get = self.settings.get
17 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
18 | self.regex = re.compile(pattern)
19 | self.url = get(URL_SETTING, URL_DEFAULT)
20 |
21 | def replace(self, match):
22 | return self.url % match.group('review')
23 |
--------------------------------------------------------------------------------
/resolver/email.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | from .abstract import AbstractRegexLinkResolver
4 |
5 |
6 | PATTERN_SETTING = 'orgmode.open_link.resolver.email.pattern'
7 | PATTERN_DEFAULT = r'^(?Pemail|mailto):(?P[^/]+)(/(?P.+))?$'
8 | URL_SETTING = 'orgmode.open_link.resolver.email.url'
9 | URL_DEFAULT = 'mailto:%s'
10 |
11 |
12 | class Resolver(AbstractRegexLinkResolver):
13 |
14 | def __init__(self, view):
15 | super(Resolver, self).__init__(view)
16 | get = self.settings.get
17 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
18 | self.regex = re.compile(pattern)
19 | self.url = get(URL_SETTING, URL_DEFAULT)
20 |
21 | def replace(self, match):
22 | match = match.groupdict()
23 | if match['type'] == 'mailto':
24 | url = self.url % match['email']
25 | if match['subject']:
26 | url += '?subject=%s' % match['subject']
27 | return url
28 | if match['type'] == 'email':
29 | return dict(email=match['email'], path=match['subject'])
30 |
31 | def execute(self, content):
32 | if isinstance(content, dict) and 'email' in content:
33 | import sublime
34 | # TODO Implement email opener here.
35 | sublime.error_message('Email opener not implemented yet.')
36 | raise NotImplemented()
37 | else:
38 | return super(Resolver, self).execute(content)
39 |
--------------------------------------------------------------------------------
/resolver/fisheye.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | from .abstract import AbstractRegexLinkResolver
4 |
5 |
6 | PATTERN_SETTING = 'orgmode.open_link.resolver.fisheye.pattern'
7 | PATTERN_DEFAULT = r'^(fisheye|fish|fe):(?P[^/]+)(/(?P.+))?$'
8 | URL_SETTING = 'orgmode.open_link.resolver.fisheye.url'
9 | URL_DEFAULT = 'http://sandbox.fisheye.atlassian.com/changelog/%s'
10 |
11 |
12 | class Resolver(AbstractRegexLinkResolver):
13 |
14 | def __init__(self, view):
15 | super(Resolver, self).__init__(view)
16 | get = self.settings.get
17 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
18 | self.regex = re.compile(pattern)
19 | self.url = get(URL_SETTING, URL_DEFAULT)
20 |
21 | def replace(self, match):
22 | match = match.groupdict()
23 | url = self.url % match['repo']
24 | if match['rev']:
25 | url += '?cs=%s' % match['rev']
26 | return url
27 |
--------------------------------------------------------------------------------
/resolver/http.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import re
4 | import subprocess
5 | import sublime
6 | from .abstract import AbstractRegexLinkResolver
7 |
8 | try:
9 | import urllib.request, urllib.parse, urllib.error
10 | except ImportError:
11 | import urllib
12 |
13 |
14 |
15 | PATTERN_SETTING = 'orgmode.open_link.resolver.http.pattern'
16 | PATTERN_DEFAULT = r'^(http):(?P.+)$'
17 | URL_SETTING = 'orgmode.open_link.resolver.http.url'
18 | URL_DEFAULT = 'http:%s'
19 |
20 |
21 | DEFAULT_OPEN_HTTP_LINK_COMMANDS = dict(
22 | darwin=['open'],
23 | win32=['cmd', '/C'],
24 | linux=['xdg-open'],
25 | )
26 |
27 |
28 | class Resolver(AbstractRegexLinkResolver):
29 |
30 | def __init__(self, view):
31 | super(Resolver, self).__init__(view)
32 | get = self.settings.get
33 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
34 | self.regex = re.compile(pattern)
35 | self.url = get(URL_SETTING, URL_DEFAULT)
36 | self.link_commands = self.settings.get(
37 | 'orgmode.open_link.resolver.abstract.commands', DEFAULT_OPEN_HTTP_LINK_COMMANDS)
38 |
39 | def replace(self, match):
40 | return self.url % match.group('url')
41 |
42 | def execute(self, content):
43 | command = self.get_link_command()
44 | if not command:
45 | sublime.error_message(
46 | 'Could not get link opener command.\nNot yet supported.')
47 | return None
48 |
49 | # cmd.exe quote is needed, http://ss64.com/nt/syntax-esc.html
50 | # escape these: ^\ ^& ^| ^> ^< ^^
51 | if sys.platform == 'win32':
52 | content = content.replace("^", "^^")
53 | content = content.replace("&", "^&")
54 | content = content.replace("\\", "^\\")
55 | content = content.replace("|", "^|")
56 | content = content.replace("<", "^<")
57 | content = content.replace(">", "^>")
58 |
59 |
60 | if sys.version_info[0] < 3:
61 | content = content.encode(sys.getfilesystemencoding())
62 |
63 | if sys.platform != 'win32':
64 | cmd = command + [content]
65 | else:
66 | cmd = command + ['start ' + content]
67 |
68 | print('HTTP*****')
69 | print(repr(content), content)
70 | print(repr(cmd))
71 | print(cmd)
72 | sublime.status_message('Executing: %s' % cmd)
73 | if sys.platform != 'win32':
74 | process = subprocess.Popen(
75 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
76 | else:
77 | process = subprocess.Popen(
78 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
79 |
80 | stdout, stderr = process.communicate()
81 | if stdout:
82 | stdout = str(stdout, sys.getfilesystemencoding())
83 | sublime.status_message(stdout)
84 | if stderr:
85 | stderr = str(stderr, sys.getfilesystemencoding())
86 | sublime.error_message(stderr)
87 |
--------------------------------------------------------------------------------
/resolver/https.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | import sys
4 | import subprocess
5 | import sublime
6 | from .abstract import AbstractRegexLinkResolver
7 |
8 | try:
9 | import urllib.request, urllib.parse, urllib.error
10 | except ImportError:
11 | import urllib
12 |
13 |
14 | PATTERN_SETTING = 'orgmode.open_link.resolver.https.pattern'
15 | PATTERN_DEFAULT = r'^(https):(?P.+)$'
16 | URL_SETTING = 'orgmode.open_link.resolver.https.url'
17 | URL_DEFAULT = 'https:%s'
18 |
19 | DEFAULT_OPEN_HTTP_LINK_COMMANDS = dict(
20 | darwin=['open'],
21 | win32=['cmd', '/C'],
22 | linux=['xdg-open'],
23 | )
24 |
25 |
26 | class Resolver(AbstractRegexLinkResolver):
27 |
28 | def __init__(self, view):
29 | super(Resolver, self).__init__(view)
30 | get = self.settings.get
31 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
32 | self.regex = re.compile(pattern)
33 | self.url = get(URL_SETTING, URL_DEFAULT)
34 | self.link_commands = self.settings.get(
35 | 'orgmode.open_link.resolver.abstract.commands', DEFAULT_OPEN_HTTP_LINK_COMMANDS)
36 |
37 | def replace(self, match):
38 | return self.url % match.group('url')
39 |
40 | def execute(self, content):
41 | command = self.get_link_command()
42 | if not command:
43 | sublime.error_message(
44 | 'Could not get link opener command.\nNot yet supported.')
45 | return None
46 |
47 | # cmd.exe quote is needed, http://ss64.com/nt/syntax-esc.html
48 | # escape these: ^\ ^& ^| ^> ^< ^^
49 | if sys.platform == 'win32':
50 | content = content.replace("^", "^^")
51 | content = content.replace("&", "^&")
52 | content = content.replace("\\", "^\\")
53 | content = content.replace("|", "^|")
54 | content = content.replace("<", "^<")
55 | content = content.replace(">", "^>")
56 |
57 | if sys.version_info[0] < 3:
58 | content = content.encode(sys.getfilesystemencoding())
59 |
60 | if sys.platform != 'win32':
61 | cmd = command + [content]
62 | else:
63 | cmd = command + ['start ' + content]
64 |
65 | print('HTTP*****')
66 | print(repr(content), content)
67 | print(repr(cmd))
68 | print(cmd)
69 | sublime.status_message('Executing: %s' % cmd)
70 | if sys.platform != 'win32':
71 | process = subprocess.Popen(
72 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
73 | else:
74 | process = subprocess.Popen(
75 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
76 |
77 | stdout, stderr = process.communicate()
78 | if stdout:
79 | stdout = str(stdout, sys.getfilesystemencoding())
80 | sublime.status_message(stdout)
81 | if stderr:
82 | stderr = str(stderr, sys.getfilesystemencoding())
83 | sublime.error_message(stderr)
84 |
--------------------------------------------------------------------------------
/resolver/jira.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | from .abstract import AbstractRegexLinkResolver
4 |
5 |
6 | PATTERN_SETTING = 'orgmode.open_link.resolver.jira.pattern'
7 | PATTERN_DEFAULT = r'^(jira|j):(?P.+)$'
8 | URL_SETTING = 'orgmode.open_link.resolver.jira.url'
9 | URL_DEFAULT = 'http://sandbox.onjira.com/browse/%s'
10 |
11 |
12 | class Resolver(AbstractRegexLinkResolver):
13 |
14 | def __init__(self, view):
15 | super(Resolver, self).__init__(view)
16 | get = self.settings.get
17 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
18 | self.regex = re.compile(pattern)
19 | self.url = get(URL_SETTING, URL_DEFAULT)
20 |
21 | def replace(self, match):
22 | return self.url % match.group('issue')
23 |
--------------------------------------------------------------------------------
/resolver/local_file.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | import os
4 | from fnmatch import fnmatch
5 | import sublime
6 | from .abstract import AbstractLinkResolver
7 |
8 |
9 | PATTERN_SETTING = 'orgmode.open_link.resolver.local_file.pattern'
10 | PATTERN_DEFAULT = r'^(?P.+?)(?::(?P\d+)(?::(?P\d+))?)?$'
11 |
12 | FORCE_LOAD_SETTING = 'orgmode.open_link.resolver.local_file.force_into_sublime'
13 | FORCE_LOAD_DEFAULT = ['*.txt', '*.org', '*.py', '*.rb',
14 | '*.html', '*.css', '*.js', '*.php', '*.c', '*.cpp', '*.h']
15 |
16 |
17 | class Resolver(AbstractLinkResolver):
18 |
19 | '''
20 | @todo: If the link is a local org-file open it directly via sublime, otherwise use OPEN_LINK_COMMAND.
21 | '''
22 |
23 | def __init__(self, view):
24 | super(Resolver, self).__init__(view)
25 | get = self.settings.get
26 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
27 | self.regex = re.compile(pattern)
28 | self.force_load_patterns = get(FORCE_LOAD_SETTING, FORCE_LOAD_DEFAULT)
29 |
30 | def file_is_excluded(self, filepath):
31 | basename = os.path.basename(filepath)
32 | for pattern in self.force_load_patterns:
33 | if fnmatch(basename, pattern):
34 | print('found in force_load_patterns')
35 | return False
36 | return True
37 |
38 | folder_exclude_patterns = self.settings.get('folder_exclude_patterns')
39 | if basename in folder_exclude_patterns:
40 | print('found in folder_exclude_patterns')
41 | return True
42 | file_exclude_patterns = self.settings.get('file_exclude_patterns')
43 | for pattern in file_exclude_patterns:
44 | if fnmatch(basename, pattern):
45 | print('found in file_exclude_patterns')
46 | return True
47 | return False
48 |
49 | def expand_path(self, filepath):
50 | filepath = os.path.expandvars(filepath)
51 | filepath = os.path.expanduser(filepath)
52 |
53 | match = self.regex.match(filepath)
54 | if match:
55 | filepath, row, col = match.group(
56 | 'filepath'), match.group('row'), match.group('col')
57 | else:
58 | row = None
59 | col = None
60 |
61 | drive, filepath = os.path.splitdrive(filepath)
62 | if not filepath.startswith('/'): # If filepath is relative...
63 | cwd = os.path.dirname(self.view.file_name())
64 | testfile = os.path.join(cwd, filepath)
65 | if os.path.exists(testfile): # See if it exists here...
66 | filepath = testfile
67 |
68 | filepath = ''.join([drive, filepath]) if drive else filepath
69 | print('filepath: ' + filepath)
70 | if not self.file_is_excluded(filepath):
71 | if row:
72 | filepath += ':%s' % row
73 | if col:
74 | filepath += ':%s' % col
75 | print('file_is_excluded')
76 | self.view.window().open_file(filepath, sublime.ENCODED_POSITION)
77 | return True
78 |
79 | return filepath
80 |
81 | def replace(self, content):
82 | content = self.expand_path(content)
83 | return content
84 |
85 | def execute(self, content):
86 | if content is not True:
87 | print('normal open')
88 | return super(Resolver, self).execute(content)
89 |
--------------------------------------------------------------------------------
/resolver/prompt.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | import sys
4 | import subprocess
5 | import sublime
6 | from .abstract import AbstractRegexLinkResolver
7 |
8 | DEFAULT_OPEN_PROMPT_LINK_COMMANDS = dict(
9 | darwin=['open', '-a', 'Terminal'],
10 | win32=['cmd'],
11 | linux=['gnome-terminal'],
12 | )
13 |
14 |
15 | PATTERN_SETTING = 'orgmode.open_link.resolver.prompt.pattern'
16 | PATTERN_DEFAULT = r'^(cmd:|prompt:)(?P.+)$'
17 | PROMPT_SETTING = 'orgmode.open_link.resolver.prompt.path'
18 | PROMPT_DEFAULT_WIN32 = '%s'
19 | PROMPT_DEFAULT_LINUX = '--working-directory=%s'
20 |
21 |
22 | class Resolver(AbstractRegexLinkResolver):
23 |
24 | def __init__(self, view):
25 | super(Resolver, self).__init__(view)
26 | get = self.settings.get
27 | self.link_commands = self.settings.get(
28 | 'orgmode.open_link.resolver.abstract.commands', DEFAULT_OPEN_PROMPT_LINK_COMMANDS)
29 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
30 | self.regex = re.compile(pattern)
31 | if sys.platform == 'win32' or sys.platform == 'darwin':
32 | self.url = get(PROMPT_SETTING, PROMPT_DEFAULT_WIN32)
33 | else:
34 | self.url = get(PROMPT_SETTING, PROMPT_DEFAULT_LINUX)
35 |
36 | def replace(self, match):
37 | return self.url % match.group('path')
38 |
39 | def get_link_command(self):
40 | platform = sys.platform
41 | for key, val in self.link_commands.items():
42 | if key in platform:
43 | return val
44 | return None
45 |
46 | def execute(self, content):
47 | command = self.get_link_command()
48 | if not command:
49 | sublime.error_message(
50 | 'Could not get link opener command.\nNot yet supported.')
51 | return None
52 |
53 | if sys.version_info[0] < 3:
54 | content = content.encode(sys.getfilesystemencoding())
55 |
56 | if sys.platform != 'win32':
57 | cmd = command + [content]
58 | else:
59 | cmd = 'cmd /C start cmd.exe /K "cd /d '+content+'"'
60 |
61 | print('PROMPT*****')
62 | print(repr(content))
63 | print(cmd)
64 | # \"cd /d c:\dev\apps\"' is not recognized as an internal or external command,
65 | sublime.status_message('Executing: %s' % cmd)
66 | if sys.platform != 'win32':
67 | process = subprocess.Popen(
68 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
69 | else:
70 | process = subprocess.Popen(
71 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
72 |
73 | stdout, stderr = process.communicate()
74 | if stdout:
75 | stdout = str(stdout, sys.getfilesystemencoding())
76 | sublime.status_message(stdout)
77 | if stderr:
78 | stderr = str(stderr, sys.getfilesystemencoding())
79 | sublime.error_message(stderr)
80 |
--------------------------------------------------------------------------------
/resolver/redmine.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | from .abstract import AbstractRegexLinkResolver
4 |
5 |
6 | PATTERN_SETTING = 'orgmode.open_link.resolver.redmine.pattern'
7 | PATTERN_DEFAULT = r'^(issue:|redmine:|#)(?P.+)$'
8 | URL_SETTING = 'orgmode.open_link.resolver.redmine.url'
9 | URL_DEFAULT = 'http://redmine.org/issues/%s'
10 |
11 |
12 | class Resolver(AbstractRegexLinkResolver):
13 |
14 | def __init__(self, view):
15 | super(Resolver, self).__init__(view)
16 | get = self.settings.get
17 | pattern = get(PATTERN_SETTING, PATTERN_DEFAULT)
18 | self.regex = re.compile(pattern)
19 | self.url = get(URL_SETTING, URL_DEFAULT)
20 |
21 | def replace(self, match):
22 | return self.url % match.group('issue')
23 |
--------------------------------------------------------------------------------
/snippets/break.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | b
4 | text.orgmode
5 | break
6 |
7 |
--------------------------------------------------------------------------------
/snippets/checkbox_checked.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | cc
4 | text.orgmode
5 | checkbox checked
6 |
7 |
--------------------------------------------------------------------------------
/snippets/checkbox_summary.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | cs
4 | text.orgmode
5 | checkbox summary
6 |
7 |
--------------------------------------------------------------------------------
/snippets/checkbox_unchecked.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | c
4 | text.orgmode
5 | checkbox unchecked
6 |
7 |
--------------------------------------------------------------------------------
/snippets/code.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
5 | code
6 | text.orgmode
7 | code block
8 |
9 |
--------------------------------------------------------------------------------
/snippets/extlink.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | l
4 | text.orgmode
5 | external link
6 |
7 |
--------------------------------------------------------------------------------
/snippets/followup.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 | ${0:CONTENT}]]>
3 | f
4 | text.orgmode
5 | follow up
6 |
7 |
--------------------------------------------------------------------------------
/snippets/headline.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | h
4 | text.orgmode
5 | headline
6 |
7 |
--------------------------------------------------------------------------------
/snippets/headline2.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | hh
4 | text.orgmode
5 | headline 2
6 |
7 |
--------------------------------------------------------------------------------
/snippets/headline3.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | hhh
4 | text.orgmode
5 | headline 3
6 |
7 |
--------------------------------------------------------------------------------
/snippets/intlink.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | i
4 | text.orgmode
5 | internal link
6 |
7 |
--------------------------------------------------------------------------------
/snippets/intlink2.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | ii
4 | text.orgmode
5 | internal headline link
6 |
7 |
--------------------------------------------------------------------------------
/snippets/multitag.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | :
4 | text.orgmode
5 | tag
6 |
7 |
--------------------------------------------------------------------------------
/snippets/page.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | p
4 | text.orgmode
5 | page
6 |
7 |
--------------------------------------------------------------------------------
/snippets/sumup.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 | ${0:CONTENT}]]>
3 | ff
4 | text.orgmode
5 | sum up
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 | text.orgmode
5 | tack
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_checkbox_checked.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -cc
4 | text.orgmode
5 | tack checkbox checked
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_checkbox_unchecked.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -c
4 | text.orgmode
5 | tack checkbox unchecked
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_checkbox_unchecked_extlink.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -cl
4 | text.orgmode
5 | tack checkbox unchecked external link
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_done.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -d
4 | text.orgmode
5 | tack done
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_todo.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -t
4 | text.orgmode
5 | tack todo
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tack_working.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | -w
4 | text.orgmode
5 | tack working
6 |
7 |
--------------------------------------------------------------------------------
/snippets/tag.sublime-snippet:
--------------------------------------------------------------------------------
1 |
2 |
3 | t
4 | text.orgmode
5 | tag
6 |
7 |
--------------------------------------------------------------------------------