diff --git a/autoload/SpaceVim/layers/lang/org.vim b/autoload/SpaceVim/layers/lang/org.vim index 9008ab010..bb7f788a3 100644 --- a/autoload/SpaceVim/layers/lang/org.vim +++ b/autoload/SpaceVim/layers/lang/org.vim @@ -9,7 +9,7 @@ function! SpaceVim#layers#lang#org#plugins() abort let plugins = [] - call add(plugins, ['SpaceVim/org-mode', {'merged' : 0}]) + call add(plugins, [g:_spacevim_root_dir . 'bundle/org-mode', {'merged' : 0}]) return plugins endfunction diff --git a/bundle/org-mode/.gitignore b/bundle/org-mode/.gitignore new file mode 100644 index 000000000..6e92f57d4 --- /dev/null +++ b/bundle/org-mode/.gitignore @@ -0,0 +1 @@ +tags diff --git a/bundle/org-mode/INSTALL.txt b/bundle/org-mode/INSTALL.txt new file mode 100644 index 000000000..e3a179a32 --- /dev/null +++ b/bundle/org-mode/INSTALL.txt @@ -0,0 +1,82 @@ +Installation instructions for VimOrganizer v. 0.30, November 2011 +================================================================= + +1. Install VimOrganizer files as you would any other ftplugin, with downloaded +files going in their respective directories under your .vim (Linux/Mac) +or vimfiles (Windows) directory. + +2. Run helptags on the help file in the /doc directory, vimorg.txt, +so help items can be accessed using the Vim help system. + +3. Make sure your vimrc has these lines: +------------------------------------- + filetype plugin indent on + + [...and then somewhere below that:] + + au! BufRead,BufWrite,BufWritePost,BufNewFile *.org + au BufEnter *.org call org#SetOrgFileType() +------------------------------------ + +If you use VimOrganizer much you will also want to configure variables +and/or functions in your vimrc. A sample vimrc has been included +in the download. + +ALSO, you will want to install the plugins listed below. VimOrganizer +will work without them, but some functionality will be unavailable: + +4. Make sure you have Calendar.vim installed. + (Calendar.vim comes included in the /plugin/ directory as part of + the Vim runtime in some Vim installs, otherwise available at: + http://www.vim.org/scripts/script.php?script_id=52) + +Second, here are two plugins that you will want to download to +take advantage of Org-mode-like narrowing and link features that have been built +into VimOrganizer: + +5. Christian Brabandt's NarrowRegion plugin. Find and install it from here: + http://www.vim.org/scripts/script.php?script_id=3075 +6. The Utl "Universal Text Linking" plugin. Find and install it from here: + http://www.vim.org/scripts/script.php?script_id=293 + +If you are running on Windows another plugin will be useful: + +7. If you're running on Windows then you may want to get Peter Rodding's + shell.vim plugin. It's not necessary, but if you have installed + it VimOrganizer will use it to ensure that you don't see + the annoying Windows command prompt window pop up when VimOrganizer + calls out to Emacs/Org-mode. + http://www.vim.org/scripts/script.php?script_id=3123 + +8. FINALLY, install Emacs. Not necessary for basic outlining, agenda +searches, and other basic stuff, but it is necessary to do exports +to html and PDF (which you will definitely want) as well as other +advanced stuff. Don't be afraid, install is simply and configuration +is not hard. Find Emacs here: +http://www.gnu.org/software/emacs/ + +Vimorg uses a variable, g:org_command_for_emacsclient, to hold the +command that will start the emacsclient on your system. If you are +not on Linux or OSX you will need to set this explicitly in your +vimrc file. + +Also, please note that emacsclient works slightly differently on +Windows and Linux/OSX systems. You must manually start +Emacs on Linux/OSX or calls to emacsclient will not work. Please see +:h vimorg-emacs-setup + +For Emacs you should also install a hook function in the .emacs file, +which will automatically make minor conversions when you export and/or +open a VimOrganizer .org file in Emacs. You can find the text for that +function in the VimOrganizer help file: +:h vimorg-orgmode-conversion + +If you're scared of Emacs, don't worry. You don't ever need to edit +a document using Emacs. The most you will need to do is open up +the .emacs configuration file (in Vim) to make some configuration +changes, and that is required only if you're doing more advanced stuff. +Having said, that, if there are problems it can sometimes be easiest to +open Emacs and diagnose an issue there. Still, you don't ever need +to edit a document in Emacs, just think of Emacs as your "application +server". + diff --git a/bundle/org-mode/README.md b/bundle/org-mode/README.md new file mode 100644 index 000000000..23b97f84b --- /dev/null +++ b/bundle/org-mode/README.md @@ -0,0 +1,7 @@ +# org-mode for SpaceVim + +This plugin is a fork of VimOrganizer + + + + diff --git a/bundle/org-mode/VimOrganizerCheatsheet.org b/bundle/org-mode/VimOrganizerCheatsheet.org new file mode 100644 index 000000000..2edc7fd13 --- /dev/null +++ b/bundle/org-mode/VimOrganizerCheatsheet.org @@ -0,0 +1,113 @@ +* VimOrganizer CheatSheet +** TODO Outline Navigation + :home:work: + abc + TAB cycle visibilty of single headline/subtree + + Shift-TAB cycle visibility of entire outline + + ,1 show level 1 heads only + + ,2 show up to level 2 headings + + ... + + ,,3 show up to level 3 heads for current heading only + + ,,5 show up to level 5 heads for current heading only + . . . +** Basic Outline Editing + Name your file with a '.org' extension and then just start adding + headings with asterisks to indicate heading level. NOTE: asterisks must + be in the leftmost column and must be separated from heading text by a + space. This document is an example showing headings, subheadings, + and text underneath each. +*** Adding new headlines +**** TODO Enter, shift+Enter + add another headline of same level + works only in normal mode +**** Ctrl+Enter + add another headline of lower-level +**** DONE Ctrl+Shift+Enter + add another headline of higher-level +** TODO Time Stamps/Date-time prompt + The following commands may be issued anywhere within a headline and will + enter or edit the corresponding date for the headline. One date of + each type may be defined per headline (i.e, 'deadline', 'scheduled', + 'closed', and 'regular'. You can enter more dates anywhere you want, but + this editing mechanism is currently restricted to dealing with only these + "primary" dates. + + enter DEADLINE date for headline ,dd + enter SCHEDULED date for headline ,ds + enter CLOSED date for headline ,dc + enter regular date TIMESTAMP (i.e., no indicator) for headline + ,dt + enter timestamp into text ,dg + + The command-line prompt and calendar that appear when you enter a ,d + command operate nearly the same as the date-time prompt in Emacs' + Org-mode. A few options are not yet implemented (e.g., the 'w'eek + options), but most should work just the same. For excellent documentation + on Org-mode's date-time prompt see: + :http://orgmode.org/manual/The-date_002ftime-prompt.html#The-date_002ftime-prompt +** Agenda Dashboard + Type ,ag to bring up the Agenda Dashboard, which allows you to launch + some searches. +** Set Agenda Files + Agenda files are held in a list: g:agenda_files. You can enter values for + g:agenda_files in your vimrc, e.g., + + :let g:agenda_files = ['myfile.org','c:/path/myfile.org'] + + You can also use Vimscript to assign multiple files at a time to + g:agenda_files. For example, putting the line below in your vimrc would + put all .org files in the org_files directory into g:agenda_files: + + :let g:agenda_files = split(glob("~\desktop\org_files\*.org"),"\n") + + User Interface for runtime editing of g:agenda_files: + + There is a also a bare-bones agenda-editing mechanism that works like this: + (1) Put your .org working directories in list g:agenda_dirs. Mine is in my + vimrc and looks like this: + + :let g:agenda_dirs=["c:/users/herbert/documents/my\ dropbox","c:/users/herbert/desktop/org_Files"] + + (2) Then to edit your agenda files issue this command + + :call EditAgendaFiles() + + This will open a new tab and show your current agenda files along with a list + of all org files in your agenda dirs. Simply copy or move lines from the + agenda dirs list to the top and when done press :W (that's a capital 'W'). + Order of agenda files is sometimes important, e.g., it is used when ordering + some agenda results. + +** Tags + Tags for a file are defined using the SetupTags() function. There is an + example in the project's vimrc file. General structure of the + tag-setup-string is: (1) tags followed by the single-key access in parens, + (2) curly brackets (i.e., {} ) around sets of tags that are mutually exclusive. + For now you must place the single-key-access parens with character after the + tag, no letter is automatically assigned. The tags set up by SetupTags() are + used in the menu accessed by ,et . + + edit tags -- ,et + view items with tag in agenda -- double-click tag, + + (Note: The 'RunSearch' searches below can all be entered now + by accessing Agenda Dashboard (,ag) and pressing 'm') + view entries having both tag1 and tag2: + :call RunSearch('+tag1+tag2') + view entries having tag1 but not tag2: + :call RunSearch('+tag1-tag2') + view entries having tag1 or tag2: + :call RunSearch('+tag1|tag2') + view entries having tag1 that are also TODO: + :call RunSearch('+TODO+tag1') + view entries having tag1 that are also DONE: + :call RunSearch('+DONE+tag1') + view entries having tag1 that have any todo: + :call RunSearch('+ANY_TODO+tag1') + diff --git a/bundle/org-mode/_vimrc b/bundle/org-mode/_vimrc new file mode 100644 index 000000000..bb70b2b2b --- /dev/null +++ b/bundle/org-mode/_vimrc @@ -0,0 +1,180 @@ +" This is an example vimrc that should work for testing purposes. +" Integrate the VimOrganizer specific sections into your own +" vimrc if you wish to use VimOrganizer on a regular basis. . . + +"=================================================================== +" THE NECESSARY STUFF +" The three lines below are necessary for VimOrganizer to work right +" ================================================================== +let g:ft_ignore_pat = '\.org' +filetype plugin indent on +" and then put these lines in vimrc somewhere after the line above +au! BufRead,BufWrite,BufWritePost,BufNewFile *.org +au BufEnter *.org call org#SetOrgFileType() +" let g:org_capture_file = '~/org_files/mycaptures.org' +command! OrgCapture :call org#CaptureBuffer() +command! OrgCaptureFile :call org#OpenCaptureFile() +syntax on + +"============================================================== +" THE UNNECESSARY STUFF +"============================================================== +" Everything below here is a customization. None are needed. +"============================================================== + +" The variables below are used to define the default Todo list and +" default Tag list. Both of these can also be defined +" on a document-specific basis by config lines in a file. +" See :h vimorg-todo-metadata and/or :h vimorg-tag-metadata +" 'TODO | DONE' is the default, so not really necessary to define it at all +let g:org_todo_setup='TODO | DONE' +" OR, e.g.,: +"let g:org_todo_setup='TODO NEXT STARTED | DONE CANCELED' + +" include a tags setup string if you want: +let g:org_tags_alist='{@home(h) @work(w) @tennisclub(t)} {easy(e) hard(d)} {computer(c) phone(p)}' +" +" g:org_agenda_dirs specify directories that, along with +" their subtrees, are searched for list of .org files when +" accessing EditAgendaFiles(). Specify your own here, otherwise +" default will be for g:org_agenda_dirs to hold single +" directory which is directory of the first .org file opened +" in current Vim instance: +" Below is line I use in my Windows install: +" NOTE: case sensitive even on windows. +let g:org_agenda_select_dirs=["~/desktop/org_files"] +let g:org_agenda_files = split(glob("~/desktop/org_files/org-mod*.org"),"\n") + +" ---------------------- +" Emacs setup +" ---------------------- +" To use Emacs you will need to define the client. On +" Linux/OSX this is typically simple, just: +"let g:org_command_for_emacsclient = 'emacsclient' +" +" On Windows it is more complicated, and probably involves creating +" a 'soft link' to the emacsclient executable (which is 'emacsclientw') +" See :h vimorg-emacs-setup +"let g:org_command_for_emacsclient = 'c:\users\herbert\emacsclientw.exe' + +" ---------------------- +" Custom Agenda Searches +" ---------------------- +" The assignment to g:org_custom_searches below defines searches that a +" a user can then easily access from the Org menu or the Agenda Dashboard. +" (Still need to add help on how to define them, assignment below +" is hopefully illustrative for now. . . . ) +let g:org_custom_searches = [ + \ { 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w', 'agenda_duration':'w' } + \, { 'name':"Next week's TODOS", 'type':'agenda', + \ 'agenda_date':'+1w', 'agenda_duration':'w', + \ 'spec':'+UNFINISHED_TODOS' } + \, { 'name':'Home tags', 'type':'heading_list', 'spec':'+HOME' } + \, { 'name':'Home tags', 'type':'sparse_tree', 'spec':'+HOME' } + \ ] + +" -------------------------------- +" Custom colors +" --------------------------------" +" OrgCustomColors() allows a user to set highlighting for particular items +function! OrgCustomColors() + " Various text item 'highlightings' below + " are the defaults. Uncomment and change a line if you + " want different highlighting for the element. + " + " Below are defaults for any TODOS you define. TODOS that + " come before the | in a definition will use 'NOTDONETODO' + " and those that come after are DONETODO + "hi! DONETODO guifg=green ctermfg=green + "hi! NOTDONETODO guifg=red ctermfg=lightred + + " Heading level highlighting is done in pairs, one for the + " heading when unfolded and one for folded. Default is to make + " them the same except for the folded version being bold: + " assign OL1 pair for level 1, OL2 pair for level 2, etc. + "hi! OL1 guifg=somecolor guibg=somecolor + "hi! OL1Folded guifg=somecolor guibg=somecolor gui=bold + + + " Tags are lines below headings that have :colon:separated:tags: + "hi! Org_Tag guifg=lightgreen ctermfg=blue + + " Lines that begin with '#+' in column 0 are config lines + "hi! Org_Config_Line guifg=darkgray ctermfg=magenta + + " Drawers are :PROPERTIES: and :LOGBOOK: lines and their associated + " :END: lines + "hi! Org_Drawer guifg=pink ctermfg=magenta + "hi! Org_Drawer_Folded guifg=pink ctermfg=magenta gui=bold cterm=bold + + " This applies to value names in :PROPERTIES: blocks + "hi! Org_Property_Value guifg=pink ctermfg=magenta + + " Three lines below apply to different kinds of blocks + "hi! Org_Block guifg=#555555 ctermfg=magenta + "hi! Org_Src_Block guifg=#555555 ctermfg=magenta + "hi! Org_Table guifg=#888888 guibg=#333333 ctermfg=magenta + + " Dates are date specs between angle brackets (<>) or square brackets ([]) + "hi! Org_Date guifg=magenta ctermfg=magenta gui=underline cterm=underline + + " Org_Star is used to "hide" initial asterisks in a heading + "hi! Org_Star guifg=#444444 ctermfg=darkgray + + "hi! Props guifg=#ffa0a0 ctermfg=gray + + " Bold, italics, underline, and code are highlights applied + " to character formatting + "hi! Org_Code guifg=darkgray gui=bold ctermfg=14 + "hi! Org_Itals gui=italic guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Bold gui=bold guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Underline gui=underline guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Lnumber guifg=#999999 ctermfg=gray + + " These lines apply to links: [[link]], and [[link][link desc]] + "if has("conceal") + " hi! default linkends guifg=blue ctermfg=blue + "endif + "hi! Org_Full_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + "hi! Org_Half_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + + " Applies to the Heading line that can be displayed in column view + "highlight OrgColumnHeadings guibg=#444444 guifg=#aaaaaa gui=underline + + " Use g:org_todo_custom_highlights to set up highlighting for individual + " TODO items. Without this all todos that designate an unfinished state + " will be highlighted using NOTDONETODO highlight (see above) + " and all todos that designate a finished state will be highlighted using + " the DONETODO highlight (see above). + let g:org_todo_custom_highlights = + \ { 'NEXT': { 'guifg':'#888888', 'guibg':'#222222', + \ 'ctermfg':'gray', 'ctermbg':'darkgray'}, + \ 'WAITING': { 'guifg':'#aa3388', + \ 'ctermfg':'red' } } + +endfunction + +" Below are two examples of Org-mode "hook" functions +" These present opportunities for end-user customization +" of how VimOrganizer works. For more info see the +" documentation for hooks in Emacs' Org-mode documentation: +" http://orgmode.org/worg/org-configs/org-hooks.php#sec-1_40 +" +" These two hooks are currently the only ones enabled in +" the VimOrganizer codebase, but they are easy to add so if +" there's a particular hook you want go ahead and request it +" or look for where these hooks are implemented in +" /ftplugin/org.vim and use them as example for placing your +" own hooks in VimOrganizer: +function! Org_property_changed_functions(line,key, val) + "call confirm("prop changed: ".a:line."--key:".a:key." val:".a:val) +endfunction +function! Org_after_todo_state_change_hook(line,state1, state2) + "call confirm("changed: ".a:line."--key:".a:state1." val:".a:state2) + "call OrgConfirmDrawer("LOGBOOK") + "let str = ": - State: " . org#Pad(a:state2,10) . " from: " . Pad(a:state1,10) . + " \ ' [' . org#Timestamp() . ']' + "call append(line("."), repeat(' ',len(matchstr(getline(line(".")),'^\s*'))) . str) +endfunction + diff --git a/bundle/org-mode/autoload/calutil.vim b/bundle/org-mode/autoload/calutil.vim new file mode 100644 index 000000000..2149a2045 --- /dev/null +++ b/bundle/org-mode/autoload/calutil.vim @@ -0,0 +1,172 @@ +" calutil.vim: some calendar utilities +" Author: Charles E. Campbell, Jr. +" with modifications by Herbert Sitz for VimOrganizer +" Date: Oct 08, 2008 +" Version: 3b ASTRO-ONLY +" --------------------------------------------------------------------- +if exists("loaded_calutil") + finish +endif +let g:loaded_calutil= "v3b" +if v:version < 700 + echohl WarningMsg + echo "***warning*** this version of calutil needs vim 7.0" + echohl Normal + finish +endif + +function! calutil#dayname(date) + return calutil#DayOfWeek(split(a:date,'-')[0],split(a:date,'-')[1],split(a:date,'-')[2],2) +endfunction +function! calutil#dow(date) + return calutil#DayOfWeek(split(a:date,'-')[0],split(a:date,'-')[1],split(a:date,'-')[2],1) +endfunction + +function! calutil#jul(date) + return calutil#Cal2Jul(split(a:date,'-')[0],split(a:date,'-')[1],split(a:date,'-')[2]) +endfunction + +function! calutil#cal(julian) + return calutil#Jul2Cal(a:julian) +endfunction +" --------------------------------------------------------------------- +" DayOfWeek: {{{1 +" Usage : call calutil#DayOfWeek(y,m,d,[0|1|2]) +" g:CalUtilDayOfWeek: if 0-> integer (default) +" 1-> 3-letter English abbreviation for name of day +" 2-> English name of day +" Returns +" g:CalUtilDayOfWeek +" --------- +" 1 : 0 1 2 3 4 5 6 +" 2 : Mon Tue Wed Thu Fri Sat Sun +" 3 : Monday Tuesday Wednesday Thursday Friday Saturday Sunday +fun! calutil#DayOfWeek(y,m,d,...) + if a:0 > 0 + let g:CalUtilDayOfWeek= a:1 + endif + + let z = calutil#Cal2Jul(a:y,a:m,a:d) + if z >= 0 + let z= z%7 + else + let z= 7 - (-z%7) + endif + + if exists("g:CalUtilDayOfWeek") + if g:CalUtilDayOfWeek == 2 + let dow0="Mon" + let dow1="Tue" + let dow2="Wed" + let dow3="Thu" + let dow4="Fri" + let dow5="Sat" + let dow6="Sun" + return dow{z} + elseif g:CalUtilDayOfWeek == 3 + let dow0="Monday" + let dow1="Tuesday" + let dow2="Wednesday" + let dow3="Thursday" + let dow4="Friday" + let dow5="Saturday" + let dow6="Sunday" + return dow{z} + endif + endif + return z +endfun + +" --------------------------------------------------------------------- +" calutil#Cal2Jul: convert a (after 9/14/1752) Gregorian calendar date to Julian day {{{1 +" (on,before " ) Julian calendar date to Julian day +" (proleptic) +fun! calutil#Cal2Jul(y,m,d) + let year = a:y + let month= a:m + let day = a:d + + " there is no year zero + if year == 0 + let year= -1 + elseif year < 0 + let year= year + 1 + endif + + let julday= day - 32075 + + \ 1461*(year + 4800 + (month - 14)/12)/4 + + \ 367*(month - 2 - ((month - 14)/12)*12)/12 - + \ 3*((year + 4900 + (month - 14)/12)/100)/4 + + " 2361221 == Sep 2, 1752, which was followed immediately by + " Sep 14, 1752 (in England). Various countries + " adopted the Gregorian calendar at different times. + if julday <= 2361221 + let a = (14-month)/12 + let y = year + 4800 - a + let m = month + 12*a - 3 + let julday = day + (153*m + 2)/5 + y*365 + y/4 - 32083 + endif + return julday +endfun + +" --------------------------------------------------------------------- +" calutil#Jul2Cal: convert a Julian day to a date: {{{1 +" Default year/month/day +" julday,1 julday,"ymd" year/month/day +" julday,2 julday,"mdy" month/day/year +" julday,3 julday,"dmy" day/month/year +fun! calutil#Jul2Cal(julday,...) + let julday= a:julday + + if julday <= 2361221 + " Proleptic Julian Calendar: + " 2361210 == Sep 2, 1752, which was followed immediately by Sep 14, 1752 + " in England + let c = julday + 32082 + let d = (4*c + 3)/1461 + let e = c - (1461*d)/4 + let m = (5*e + 2)/153 + let day = e - (153*m + 2)/5 + 1 + let month = m + 3 - 12*(m/10) + let year = d - 4800 + m/10 + if year <= 0 + " proleptic Julian Calendar: there *is* no year 0! + let year= year - 1 + endif + + else + " Gregorian calendar + let t1 = julday + 68569 + let t2 = 4*t1/146097 + let t1 = t1 - (146097*t2 + 3)/4 + let yr = 4000*(t1 + 1)/1461001 + let t1 = t1 - (1461*yr/4 - 31) + let mo = 80*t1/2447 + let day = (t1 - 2447*mo/80) + let t1 = mo/11 + let month = (mo + 2 - 12*t1) + let year = (100*(t2 - 49) + yr + t1) + endif + + let month = (month<10) ? '0' . month : month + let day = (day < 10) ? '0' . day : day + + if a:0 > 0 + if a:1 == 1 || a:1 =~ "ymd" + return year."-".month."/".day + elseif a:1 == 2 || a:1 =~ "mdy" + return month."-".day."/".year + elseif a:1 == 3 || a:1 =~ "dmy" + return day."-".month."/".year + else + return year."-".month."/".day + endif + else + return year."-".month."-".day + endif +endfun + +" --------------------------------------------------------------------- +" vim: ts=4 fdm=marker + diff --git a/bundle/org-mode/autoload/org.vim b/bundle/org-mode/autoload/org.vim new file mode 100644 index 000000000..6be5746f3 --- /dev/null +++ b/bundle/org-mode/autoload/org.vim @@ -0,0 +1,245 @@ +" org.vim - VimOrganizer plugin for Vim +" ------------------------------------------------------------- +" Version: 0.30 +" Maintainer: Herbert Sitz +" Last Change: 2011 Nov 02 +" +" Script: http://www.vim.org/scripts/script.php?script_id=3342 +" Github page: http://github.com/hsitz/VimOrganizer +" Copyright: (c) 2010, 2011 by Herbert Sitz +" The VIM LICENSE applies to all files in the +" VimOrganizer plugin. +" (See the Vim copyright except read "VimOrganizer" +" in places where that copyright refers to "Vim".) +" http://vimdoc.sourceforge.net/htmldoc/uganda.html#license +" No warranty, express or implied. +" *** *** Use At-Your-Own-Risk *** *** + +if exists("g:org_autoload_funcs") + finish +endif + +let g:org_autoload_funcs=1 + +function! org#SetOrgFileType() + "if expand("%:e") == 'org' + "if exists("g:syntax_on") | syntax off | else | syntax enable | endif + "syntax enable + if &filetype != 'org' + execute "set filetype=org" + +" if !exists('g:org_todo_setup') +" let g:org_todo_setup = 'TODO | DONE' +" endif +" if !exists('g:org_tag_setup') +" let g:org_tag_setup = '{home(h) work(w)}' +" endif +" +" call OrgProcessConfigLines() +" exec "syntax match DONETODO '" . b:v.todoDoneMatch . "' containedin=OL1,OL2,OL3,OL4,OL5,OL6" +" exec "syntax match NOTDONETODO '" . b:v.todoNotDoneMatch . "' containedin=OL1,OL2,OL3,OL4,OL5,OL6" + + endif + + "endif + runtime syntax/org.vim + "syntax enable + "call OrgSetColors() +endfunction + +function! org#Pad(s,amt) + return a:s . repeat(' ',a:amt - len(a:s)) +endfunction + +function! org#Timestamp() + return strftime("%Y-%m-%d %a %H:%M") +endfunction + +function! org#redir(command) + let save_a = @a + try + silent! redir @a + silent! exe a:command + redir END + finally + "let res = split(@a,"\n") + let res = @a + + " restore register + let @a = save_a + return res + endtry +endfunction + +function! org#GetGroupHighlight(group) + " this code was copied and modified from code posted on StackOverflow + " http://stackoverflow.com/questions/1331213/how-to-modify-existing-highlight-group-in-vim + " Redirect the output of the "hi" command into a variable + " and find the highlighting + redir => GroupDetails + try + exe "silent hi " . a:group + catch + " skip error message if no such group exists + endtry + redir END + + " Resolve linked groups to find the root highlighting scheme + while GroupDetails =~ "links to" + let index = stridx(GroupDetails, "links to") + len("links to") + let LinkedGroup = strpart(GroupDetails, index + 1) + redir => GroupDetails + exe "silent hi " . LinkedGroup + redir END + endwhile + + if GroupDetails ># '' + " Extract the highlighting details (the bit after "xxx") + let MatchGroups = matchlist(GroupDetails, '\\s\+\(.*\)') + let ExistingHighlight = MatchGroups[1] !~? 'cleared' ? MatchGroups[1] : '' + else + " Group does not exist + let ExistingHighlight = '' + endif + + return ExistingHighlight + +endfunction + +function! org#ISODateToYWD(date) + "returns y,w,d which are iso week spec for date + let date = a:date + "let d = 1 + ((calutil#dow(date) + 4) % 7) + let d = 1 + calutil#dow(date) + let jul_nThur = calutil#jul(date) + 4 - d + let y = calutil#cal(jul_nThur)[0:3] + let julJan1 = calutil#jul(date[0:3] . '-01-01') + let w = 1 + ((jul_nThur - julJan1) / 7) + return [y,w,d] +endfunction + +function! org#LocateFile(filename) + let filename = a:filename + + if bufwinnr(filename) >= 0 + silent execute bufwinnr(filename)."wincmd w" + else + if org#redir('tabs') =~ fnamemodify(filename, ':t') + " proceed on assumption that file is open + " if match found in tablist + let this_tab = tabpagenr() + let last_tab = tabpagenr('$') + for i in range(1 , last_tab) + exec i . 'tabn' + if bufwinnr(filename) >= 0 + silent execute bufwinnr(filename)."wincmd w" + break + " if file not found then use tab drop to open new file + elseif i == last_tab + execute 'tab drop ' . filename + if (&ft != 'org') && (filename != '__Agenda__') + call org#SetOrgFileType() + endif + endif + tabn + endfor + else + exe 'tabn ' . tabpagenr('$') + execute 'tab drop ' . filename + if (&ft != 'org') && (filename != '__Agenda__') + call org#SetOrgFileType() + endif + endif + endif + if (&fdm != 'expr') && !exists('g:in_agenda_search') + set fdm=expr + set foldlevel=1 + endif + +endfunction + +function! org#SaveLocation() + let file_loc = bufname('%') ==? '__Agenda__' ? '__Agenda__' : expand('%:p') + let g:location = [ file_loc , getpos('.') ] +endfunction +function! org#RestoreLocation() + if expand('%:p') != g:location[0] + call org#LocateFile( g:location[0] ) + endif + call setpos( '.', g:location[1] ) +endfunction + + +function! org#OpenCaptureFile() + call org#LocateFile(g:org_capture_file) +endfunction + +function! org#CaptureBuffer() + if !exists('g:org_capture_file') || empty(g:org_capture_file) + echo 'Capture is not set up. Please read docs at :h vimorg-capture.' + return + endif + if bufnr('_Org_Capture_') > 0 + exec 'bwipeout! ' . bufnr('_Org_Capture_') + endif + sp _Org_Capture_ + autocmd BufWriteCmd :call ProcessCapture() + "autocmd BufLeave :bwipeout + autocmd BufUnload :set nomodified + set nobuflisted + set ft=org + setlocal buftype=acwrite + setlocal noswapfile + command! -buffer W :call ProcessCapture() + " below is the basic template + " a first level head with date timestamp + normal ggVGd + normal i* + silent exec "normal o:<".org#Timestamp().">" + normal gg + set nomodified + startinsert! + +endfunction +function! s:ProcessCapture() + "normal ggVG"xy + let curbufnr = bufnr(g:org_capture_file) + " check if capture file is already open or not + if curbufnr == -1 + exe '1,$write >> ' . g:org_capture_file + bw! _Org_Capture_ + else + normal ggVG"xy + bw! _Org_Capture_ + call org#SaveLocation() + call org#LocateFile(g:org_capture_file) + normal G"xp + silent write + call org#RestoreLocation() + endif + exe 'bwipeout! ' . g:org_capture_file + +endfunction + +function! s:Pre0(s) + return repeat('0',2 - len(a:s)) . a:s +endfunction +function! org#randomData() + + let date = string((2009 + org#util#random(3) - 1)).'-'.s:Pre0(org#util#random(12)).'-'.s:Pre0(org#util#random(28)) + let dstring = '' + if org#util#random(3) == 3 + let dstring = date. ' ' . calutil#dayname(date) + else + let dstring = date. ' ' . calutil#dayname(date).' '.s:Pre0(org#util#random(23)).':'.s:Pre0((org#util#random(12)-1)*5) + endif + if org#util#random(6) == 6 + let dstring .= ' +'.org#util#random(4).['d','w','m'][org#util#random(3)-1] + endif + return '<'.dstring.'>' + "if a:date_type != '' + " call s:SetProp(a:date_type,date) + "else + " silent execute "normal A".date + "endif +endfunction diff --git a/bundle/org-mode/autoload/org/buffer.vim b/bundle/org-mode/autoload/org/buffer.vim new file mode 100644 index 000000000..a4bae5cac --- /dev/null +++ b/bundle/org-mode/autoload/org/buffer.vim @@ -0,0 +1,52 @@ +function! org#buffer#init() + let b:v={} + let b:v.prevlev = 0 + let b:v.org_loaded=0 + let b:v.lasttext_lev='' + let b:v.dateMatch = '\(\d\d\d\d-\d\d-\d\d\)' + let b:v.headMatch = '^\*\+\s' + let b:v.tableMatch = '^\(\s*|.*|\s*$\|#+TBLFM\)' + let b:v.taglineMatch = '^\s*:\S\+:\s*$' + let b:v.headMatchLevel = '^\(\*\)\{level}\s' + let b:v.propMatch = '^\s*:\s*\(PROPERTIES\)' + let b:v.propvalMatch = '^\s*:\s*\(\S*\)\s*:\s*\(\S.*\)\s*$' + let b:v.drawerMatch = '^\s*:\(PROPERTIES\|LOGBOOK\)' + let b:v.levelstars = 1 + let b:v.effort=['0:05','0:10','0:15','0:30','0:45','1:00','1:30','2:00','4:00'] + let b:v.tagMatch = '\(:\S*:\)\s*$' + let b:v.mytags = ['buy','home','work','URGENT'] + let b:v.foldhi = '' + let b:v.org_inherited_properties = ['COLUMNS'] + let b:v.org_inherited_defaults = {'CATEGORY':expand('%:t:r'),'COLUMNS':'%40ITEM %30TAGS'} + let b:v.heading_marks = [] + let b:v.heading_marks_dict = {} + let b:v.chosen_agenda_heading = 0 + let b:v.prop_all_dict = {} + let b:v.buf_tags_static_spec = '' + let b:v.buffer_category = '' + if !exists('g:org_agenda_default_search_spec') + let g:org_agenda_default_search_spec = 'ANY_TODO' + endif + if exists('g:global_column_defaults') + let b:v.buffer_columns = g:global_column_defaults + else + let b:v.buffer_columns = '%40ITEM %30TAGS' + endif + let b:v.last_dict_time = 0 + let b:v.last_idict_time = 0 + let b:v.last_idict_type = 0 + let b:v.clock_to_logbook = 1 + let b:v.messages = [] + let b:v.global_cycle_levels_to_show=4 + let b:v.src_fold=0 + let b:v.foldhilines = [] + let b:v.cycle_with_text=1 + let b:v.foldcolors=['Normal','SparseSkip','Folded','WarningMsg','WildMenu','DiffAdd','DiffChange','Normal','Normal','Normal','Normal'] + let b:v.cols = [] + let b:v.basedate = strftime("%Y-%m-%d %a") + let b:v.sparse_list = [] + let b:v.fold_list = [] + let b:v.suppress_indent=0 + let b:v.suppress_list_indent=0 + +endfunction diff --git a/bundle/org-mode/autoload/org/fold.vim b/bundle/org-mode/autoload/org/fold.vim new file mode 100644 index 000000000..5e3311664 --- /dev/null +++ b/bundle/org-mode/autoload/org/fold.vim @@ -0,0 +1,119 @@ +function! org#fold#level(line) + if g:org_folds == 0 + return 0 + endif + + if exists('w:sparse_on') + \ && w:sparse_on + \ && (get(s:sparse_lines, a:line) == 1) + if index(b:v.sparse_list, a:line + 1) >= 0 + return '<0' + endif + let sparse = index(b:v.sparse_list, a:line) + if sparse >= 0 + return '>99' + endif + let sparse = index(b:v.fold_list, a:line) + if sparse >= 0 + return '<0' + endif + endif + + + let [l:text, l:nexttext] = getline(a:line, a:line+1) + + if l:text =~ '^\*\+\s' + let b:v.myAbsLevel = s:Ind(a:line) + elseif (b:v.lasttext_lev ># '') && (l:text !~ s:remstring) && (l:nexttext !~ '^\*\+\s') && (b:v.lastline == a:line - 1) + "elseif (b:v.lasttext_lev ># '') && (l:text !~ s:remstring) && (l:nexttext !~ '^\*\+\s\|^\s*:SYNOPSIS:') && (b:v.lastline == a:line - 1) + "if (b:v.lasttext_lev ># '') && (l:text !~ s:remstring) && (l:nexttext !~ '^\*\+\s') && (b:v.lastline == a:line - 1) + let b:v.lastline = a:line + return b:v.lasttext_lev + endif + let l:nextAbsLevel = s:Ind(a:line + 1) + + if l:text =~ '^\*\+\s' + " we're on a heading line + let b:v.lasttext_lev = '' + "let b:v.myAbsLevel = s:Ind(a:line) + + if l:nexttext =~ b:v.drawerMatch + let b:v.lev = '>' . string(b:v.myAbsLevel + 4) + elseif l:nexttext =~ s:remstring + let b:v.lev = '>' . string(b:v.myAbsLevel + 6) + elseif (l:nexttext !~ b:v.headMatch) && (a:line != line('$')) + let b:v.lev = '>' . string(b:v.myAbsLevel + 3) + elseif l:nextAbsLevel > b:v.myAbsLevel + let b:v.lev = '>' . string(b:v.myAbsLevel) + elseif l:nextAbsLevel < b:v.myAbsLevel + let b:v.lev = '<' . string(l:nextAbsLevel) + else + let b:v.lev = '<' . b:v.myAbsLevel + endif + let b:v.prevlev = b:v.myAbsLevel + + else + "we have a text line + if b:v.lastline != a:line - 1 " backup to headline to get bearings + if l:text =~ b:v.drawerMatch + let b:v.prevlev = s:Ind(s:OrgPrevHead_l(a:line)) + else + "don't just back up, recalc previous lines + " to set variables correctly + let prevhead = s:OrgPrevHead_l(a:line) + if prevhead == 0 + " shortcircuit here, it's blank line prior to any head + return -1 + endif + let b:v.prevlev = s:Ind(prevhead) + let i = prevhead + "for item in range(prevhead,a:line-1) + " call OrgFoldLevel(item) + "endfor + endif + "let b:v.prevlev = s:Ind(s:OrgPrevHead_l(a:line)) + endif + + if l:text =~ b:v.drawerMatch + let b:v.lev = '>' . string(b:v.prevlev + 4) + elseif (l:text =~ s:remstring) + if (getline(a:line - 1) =~ b:v.headMatch) && (l:nexttext =~ s:remstring) + let b:v.lev = string(b:v.prevlev + 5) + elseif (l:nexttext !~ s:remstring) || + \ (l:nexttext =~ b:v.drawerMatch) + let b:v.lev = '<' . string(b:v.prevlev + 4) + else + let b:v.lev = b:v.prevlev + 4 + endif + elseif l:text[0] != '#' + let b:v.lev = (b:v.prevlev + 2) + let b:v.lasttext_lev = b:v.lev + elseif b:v.src_fold + if l:text =~ '^#+begin_src' + let b:v.lev = '>' . (b:v.prevlev + 2) + elseif l:text =~ '^#+end_src' + let b:v.lev = '<' . (b:v.prevlev + 2) + endif + else + let b:v.lev = (b:v.prevlev + 2) + endif + + if l:nexttext =~ '^\* ' + " this is for perf reasons, closing fold + " back to zero avoids foldlevel calls sometimes + let b:v.lev = '<0' + elseif l:nexttext =~ '^\*\+\s' + let b:v.lev = '<' . string(l:nextAbsLevel) + endif + + endif + let b:v.lastline = a:line + return b:v.lev + +endfunction + +function! s:Ind(line) + " used to get level of a heading (todo : rename this function) + return 2 + (len(matchstr(getline(a:line), '^\**\s')) - 2) / b:v.levelstars + +endfunction diff --git a/bundle/org-mode/autoload/org/tbl.vim b/bundle/org-mode/autoload/org/tbl.vim new file mode 100644 index 000000000..d863d2f16 --- /dev/null +++ b/bundle/org-mode/autoload/org/tbl.vim @@ -0,0 +1,525 @@ +" vim:tabstop=2:shiftwidth=2:expandtab:foldmethod=marker:textwidth=79 +" Vimwiki autoload plugin file +" Desc: Tables +" | Easily | manageable | text | tables | ! | +" |--------+------------+-------+--------+---------| +" | Have | fun! | Drink | tea | Period. | +" +" Author: Maxim Kim +" Home: http://code.google.com/p/vimwiki/ + +" Load only once {{{ +if exists("g:loaded_vimwiki_tbl_auto") || &cp + finish +endif +let g:loaded_vimwiki_tbl_auto = 1 +"}}} + +let s:textwidth = &tw + +" Misc functions {{{ +function! s:wide_len(str) "{{{ + " vim73 has new function that gives correct string width. + if exists("*strdisplaywidth") + return strdisplaywidth(a:str) + endif + + " get str display width in vim ver < 7.2 + if !g:vimwiki_CJK_length + let ret = strlen(substitute(a:str, '.', 'x', 'g')) + else + let savemodified = &modified + let save_cursor = getpos('.') + exe "norm! o\" + call setline(line("."), a:str) + let ret = virtcol("$") - 1 + d + call setpos('.', save_cursor) + let &modified = savemodified + endif + return ret +endfunction "}}} + +function! s:is_table(line) "{{{ + return a:line =~ '^\s*\%(|[^|]\+\)\+|\s*$' || s:is_separator(a:line) +endfunction "}}} + +function! s:is_separator(line) "{{{ + return a:line =~ '^\s*[|+]\s*--[-|+]\+' +endfunction "}}} + +function! s:is_last_column(lnum, cnum) "{{{ + return strpart(getline(a:lnum), a:cnum - 1) =~ '^[^|]*|\s*$' +endfunction "}}} + +function! s:is_first_column(lnum, cnum) "{{{ + let line = strpart(getline(a:lnum), 0, a:cnum - 1) + return line =~ '^\s*|[^|]*$' || line =~ '^\s*$' +endfunction "}}} + +function! s:count_separators_up(lnum) "{{{ + let lnum = a:lnum - 1 + while lnum > 1 + if !s:is_separator(getline(lnum)) + break + endif + let lnum -= 1 + endwhile + + return (a:lnum-lnum) +endfunction "}}} + +function! s:count_separators_down(lnum) "{{{ + let lnum = a:lnum + 1 + while lnum < line('$') + if !s:is_separator(getline(lnum)) + break + endif + let lnum += 1 + endwhile + + return (lnum-a:lnum) +endfunction "}}} + +function! s:create_empty_row(cols) "{{{ + let first_cell = "| |" + let cell = " |" + let row = first_cell + + for c in range(a:cols - 1) + let row .= cell + endfor + + return row +endfunction "}}} + +function! s:create_row_sep(cols) "{{{ + let first_cell = "|---+" + let cell = "---+" + let last_cell = "---|" + + if a:cols < 2 + return "|---|" + endif + + let row = first_cell + + for c in range(a:cols - 2) + let row .= cell + endfor + + let row .= last_cell + + return row +endfunction "}}} + +function! s:get_values(line) "{{{ + return split(a:line, '\s*|\s*', 1)[1:-2] +endfunction "}}} + +function! s:col_count(lnum) "{{{ + let line = getline(a:lnum) + if !s:is_separator(line) + return len(split(line, '\s*|\s*', 1)[1:-2]) + else + return len(split(line, '-+-', 1)) + endif +endfunction "}}} + +function! s:get_indent(lnum) "{{{ + if !s:is_table(getline(a:lnum)) + return + endif + + let indent = 0 + + let lnum = a:lnum - 1 + while lnum > 1 + let line = getline(lnum) + if !s:is_table(line) + let indent = indent(lnum+1) + break + endif + let lnum -= 1 + endwhile + + return indent +endfunction " }}} + +function! s:get_rows(lnum) "{{{ + if !s:is_table(getline(a:lnum)) + return + endif + + let upper_rows = [] + let lower_rows = [] + + let lnum = a:lnum - 1 + while lnum > 1 + let line = getline(lnum) + if s:is_table(line) + call add(upper_rows, [lnum, line]) + else + break + endif + let lnum -= 1 + endwhile + call reverse(upper_rows) + + let lnum = a:lnum + while lnum <= line('$') + let line = getline(lnum) + if s:is_table(line) + call add(lower_rows, [lnum, line]) + else + break + endif + let lnum += 1 + endwhile + + return upper_rows + lower_rows +endfunction "}}} + +function! s:get_cell_max_lens(lnum) "{{{ + let max_lens = {} + for [lnum, row] in s:get_rows(a:lnum) + if s:is_separator(row) + continue + endif + let cells = s:get_values(row) + for idx in range(len(cells)) + let value = cells[idx] + if has_key(max_lens, idx) + let max_lens[idx] = max([s:wide_len(value), max_lens[idx]]) + else + let max_lens[idx] = s:wide_len(value) + endif + endfor + endfor + return max_lens +endfunction "}}} + +function! s:get_aligned_rows(lnum, col1, col2) "{{{ + let max_lens = s:get_cell_max_lens(a:lnum) + let rows = [] + for [lnum, row] in s:get_rows(a:lnum) + if s:is_separator(row) + let new_row = s:fmt_sep(max_lens, a:col1, a:col2) + else + let new_row = s:fmt_row(row, max_lens, a:col1, a:col2) + endif + call add(rows, [lnum, new_row]) + endfor + return rows +endfunction "}}} + +" Number of the current column. Starts from 0. +function! s:cur_column() "{{{ + let line = getline('.') + if !s:is_table(line) + return -1 + endif + if s:is_separator(line) + let sep = '[+|]' + else + let sep = '|' + endif + + let curs_pos = col('.') + let mpos = match(line, '|', 0) + let col = -1 + while mpos < curs_pos && mpos != -1 + let mpos = match(line, sep, mpos+1) + if mpos != -1 + let col += 1 + endif + endwhile + return col +endfunction "}}} + +" }}} + +" Format functions {{{ +function! s:fmt_cell(cell, max_len) "{{{ + let cell = ' '.a:cell.' ' + + let diff = a:max_len - s:wide_len(a:cell) + if diff == 0 && empty(a:cell) + let diff = 1 + endif + + let cell .= repeat(' ', diff) + return cell +endfunction "}}} + +function! s:fmt_row(line, max_lens, col1, col2) "{{{ + let new_line = '|' + let cells = s:get_values(a:line) + for idx in range(len(cells)) + if idx == a:col1 + let idx = a:col2 + elseif idx == a:col2 + let idx = a:col1 + endif + let value = cells[idx] + let new_line .= s:fmt_cell(value, a:max_lens[idx]).'|' + endfor + + let idx = len(cells) + while idx < len(a:max_lens) + let new_line .= s:fmt_cell('', a:max_lens[idx]).'|' + let idx += 1 + endwhile + return new_line +endfunction "}}} + +function! s:fmt_cell_sep(max_len) "{{{ + if a:max_len == 0 + return repeat('-', 3) + else + return repeat('-', a:max_len+2) + endif +endfunction "}}} + +function! s:fmt_sep(max_lens, col1, col2) "{{{ + let sep = '|' + for idx in range(len(a:max_lens)) + if idx == a:col1 + let idx = a:col2 + elseif idx == a:col2 + let idx = a:col1 + endif + let sep .= s:fmt_cell_sep(a:max_lens[idx]).'+' + endfor + let sep = substitute(sep, '+$', '|', '') + return sep +endfunction "}}} +"}}} + +" Keyboard functions "{{{ +function! s:kbd_create_new_row(cols, goto_first) "{{{ + let cmd = "\o".s:create_empty_row(a:cols) + let cmd .= "\:call org#tbl#format(line('.'))\" + if a:goto_first + let cmd .= "\0:call search('|', 'c', line('.'))\la" + else + let cmd .= "0".(col('.')-1)."lT|a" + endif + return cmd +endfunction "}}} + +function! s:kbd_goto_next_row() "{{{ + let cmd = "\jt|T|a" + return cmd +endfunction "}}} + +function! s:kbd_goto_prev_row() "{{{ + let cmd = "\jt|T|a" + return cmd +endfunction "}}} + +function! org#tbl#next_col(last) + return s:kbd_goto_next_col(a:last) +endfunction +function! s:kbd_goto_next_col(last) "{{{ + if a:last + let seps = s:count_separators_down(line('.')) + if mode() == 'n' + let cmd = seps . "j0:call search('|', 'c', line('.'))\l" + else + let cmd = "\".seps."j0:call search('|', 'c', line('.'))\la" + endif + else + if mode() == 'n' + let cmd = ":call search('|', 'c', line('.'))\l" + else + let cmd = "\:call search('|', 'c', line('.'))\la" + endif + endif + return cmd +endfunction "}}} + +function! org#tbl#prev_col(first) + return s:kbd_goto_prev_col(a:first) +endfunction +function! s:kbd_goto_prev_col(first) "{{{ + if a:first + let seps = s:count_separators_up(line('.')) + let cmd = "\".seps."k$:call search('|', 'b', line('.'))\la" + else + let cmd = "\2F|la" + endif + return cmd +endfunction "}}} + +"}}} + +" Global functions {{{ +function! org#tbl#kbd_cr() "{{{ + let lnum = line('.') + if !s:is_table(getline(lnum)) + return "\" + endif + + if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1)) + let cols = len(s:get_values(getline(lnum))) + return s:kbd_create_new_row(cols, 0) + else + return s:kbd_goto_next_row() + endif +endfunction "}}} + +function! org#tbl#kbd_tab() "{{{ + let lnum = line('.') + if !s:is_table(getline(lnum)) + return "\" + endif + + let last = s:is_last_column(lnum, col('.')) + if last && !s:is_table(getline(lnum+1)) + let cols = len(s:get_values(getline(lnum))) + return s:kbd_create_new_row(cols, 1) + endif + return s:kbd_goto_next_col(last) +endfunction "}}} + +function! org#tbl#kbd_shift_tab() "{{{ + let lnum = line('.') + if !s:is_table(getline(lnum)) + return "\" + endif + + let first = s:is_first_column(lnum, col('.')) + if first && !s:is_table(getline(lnum-1)) + return "" + endif + return s:kbd_goto_prev_col(first) +endfunction "}}} + +function! org#tbl#format(lnum, ...) "{{{ + let line = getline(a:lnum) + if !s:is_table(line) + return + endif + + if a:0 == 2 + let col1 = a:1 + let col2 = a:2 + else + let col1 = 0 + let col2 = 0 + endif + + let indent = s:get_indent(a:lnum) + + for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2) + let row = repeat(' ', indent).row + call setline(lnum, row) + endfor + + let &tw = s:textwidth +endfunction "}}} + +function! org#tbl#create(...) "{{{ + if a:0 > 1 + let cols = a:1 + let rows = a:2 + elseif a:0 == 1 + let cols = a:1 + let rows = 2 + elseif a:0 == 0 + let cols = 5 + let rows = 2 + endif + + if cols < 1 + let cols = 5 + endif + + if rows < 1 + let rows = 2 + endif + + let lines = [] + let row = s:create_empty_row(cols) + + call add(lines, row) + if rows > 1 + call add(lines, s:create_row_sep(cols)) + endif + + for r in range(rows - 1) + call add(lines, row) + endfor + + call append(line('.'), lines) +endfunction "}}} + +function! org#tbl#align_or_cmd(cmd) "{{{ + if s:is_table(getline('.')) + call org#tbl#format(line('.')) + else + exe 'normal! '.a:cmd + endif +endfunction "}}} + +function! org#tbl#reset_tw(lnum) "{{{ + let line = getline(a:lnum) + if !s:is_table(line) + return + endif + + let s:textwidth = &tw + let &tw = 0 +endfunction "}}} + +" TODO: move_column_left and move_column_right are good candidates to be +" refactored. +function! org#tbl#move_column_left() "{{{ + if !s:is_table(getline('.')) + return + endif + + let cur_col = s:cur_column() + if cur_col == -1 + return + endif + + if cur_col > 0 + call org#tbl#format(line('.'), cur_col-1, cur_col) + call cursor(line('.'), 1) + if !s:is_separator(getline('.')) + call search('\%(|[^|]\+\)\{'.(cur_col-1).'}| .', 'eW') + else + call search('|\%([^+]\++\)\{'.(cur_col-1).'}--', 'eW') + endif + endif +endfunction "}}} + +function! org#tbl#move_column_right() "{{{ + if !s:is_table(getline('.')) + return + endif + + let cur_col = s:cur_column() + if cur_col == -1 + return + endif + + if cur_col < s:col_count(line('.'))-1 + call org#tbl#format(line('.'), cur_col, cur_col+1) + call cursor(line('.'), 1) + if !s:is_separator(getline('.')) + call search('\%(|[^|]\+\)\{'.(cur_col+1).'}| .', 'eW') + else + call search('|\%([^+]\++\)\{'.(cur_col+1).'}--', 'eW') + endif + endif +endfunction "}}} + +function! org#tbl#get_rows(lnum) "{{{ + return s:get_rows(a:lnum) +endfunction "}}} + +"}}} + diff --git a/bundle/org-mode/autoload/org/util.vim b/bundle/org-mode/autoload/org/util.vim new file mode 100644 index 000000000..402f7fdd8 --- /dev/null +++ b/bundle/org-mode/autoload/org/util.vim @@ -0,0 +1,7 @@ +let s:NUM = SpaceVim#api#import('data#number') + +function! org#util#random(range) abort + + return s:NUM.random(1, a:range) + +endfunction diff --git a/bundle/org-mode/autoload/org/windows.vim b/bundle/org-mode/autoload/org/windows.vim new file mode 100644 index 000000000..1f23be3ac --- /dev/null +++ b/bundle/org-mode/autoload/org/windows.vim @@ -0,0 +1,10 @@ +function! org#windows#init() + let w:v={} + let w:v.total_columns_width = 30 + let w:v.columnview = 0 + let w:v.org_item_len = 100 + let w:v.org_colview_list = [] + let w:v.org_current_columns = '' + let w:v.org_column_item_head = '' + let w:sparse_on = 0 +endfunction diff --git a/bundle/org-mode/autoload/orgcheck.vim b/bundle/org-mode/autoload/orgcheck.vim new file mode 100644 index 000000000..3f7810ee8 --- /dev/null +++ b/bundle/org-mode/autoload/orgcheck.vim @@ -0,0 +1,185 @@ +function! s:AmtDone(lineno) dict + "use list_dict structure to calculate + "amount done for node at lineno + let mysum = 0 + let mycount = 0 + if (len(self[a:lineno].c) == 0) && ( get(self[a:lineno],'ckbox') ) + " just check val for current line + let mysum = get(self[a:lineno],'ckval',0) + let mycount = 1 + else + " sum vals for this item's immediate children + for item in self[a:lineno].c + if get(self[item],'ckbox') == 1 + let mysum += (get(self[item],'ckval',' ') == 'X') + let mycount += 1 + endif + endfor + endif + return [ mysum , mycount ] +endfunction + +function! orgcheck#ToggleCheck() + call s:MakeListDict() + let linetext = getline(line('.')) + let curval = matchstr(linetext,' \[\zs.\ze\]') + let has_checkbox = match(linetext, '^\s* [-\+\*] \[.\]') > -1 + if curval == 'X' + call s:ClearCheck() + elseif !has_checkbox + " give this list item a checkbox if it has none + let part1 = matchstr(linetext,'^\s* [-\+\*] ') + let part2 = matchstr(linetext,'^\s* [-\+\*] \zs.*') + call setline(line('.'),part1 . '[ ] ' . part2) + " need to redo dict after checkbox added + call s:MakeListDict() + else + call s:SetCheck() + endif + call s:UpdateCheckSummaries() +endfunction + +function! orgcheck#UpdateSummaries() + call s:MakeListDict() + call s:UpdateCheckSummaries() +endfunction + +function! s:SetCheck() + let save_pos = getpos('.') + exec 's/\[\zs.\ze\]/X/e' + let g:list_dict[line('.')].ckval = 'X' + " also set children, if any + for line in g:list_dict[line('.')].c + exec line + call s:SetCheck() + endfor + call setpos('.', save_pos) +endfunction + +function! s:ClearCheck() + let save_pos = getpos('.') + exec 's/\[\zs.\ze\]/ /e' + let g:list_dict[line('.')].ckval = ' ' + " also clear children, if any + for line in g:list_dict[line('.')].c + exec line + call s:ClearCheck() + endfor + call setpos('.', save_pos) +endfunction + +function! s:UpdateCheckSummaries(...) +" updates summaries (i.e., (x/x)) for list checkbox +" lines from beginning of list to current line + if a:0 > 0 | let lineno = a:1 | endif + let save_pos = getpos('.') + let this_line = line('.') + func! s:CheckCompare(i1, i2) + return a:i2 - a:i1 + endfunc + " get reversed list of lines + let list_lines = copy(sort(keys(g:list_dict),"s:CheckCompare")) + if a:0 > 0 + call s:UpdateListLine(key) + else + for key in list_lines + call s:UpdateListLine(key) + endfor + endif + call setpos('.',save_pos) +endfunction + +function! s:DoHeadingUpdate() + exec 'let lineno =' . g:org_sid . '_OrgGetHead()' + if lineno == 0 | return | endif + exec lineno + " delete existing stats, if any + exec 's/ \[\d\+\/\d\+\]\s*$//e' + " now put new stats in + let stats = g:list_dict.AmtDone(0) + let new_summary = ' [' . stats[0] . '\/' . stats[1] . ']' + exec 's/$/' . new_summary . '/' +endfunction + +function! s:UpdateListLine(key) + let key = a:key + if str2nr(key) > 0 + let parent = get(g:list_dict[key], 'p', 0) + if parent > 0 + call s:UpdateListLine(parent) + endif + endif + if key == 'AmtDone' | return | endif + if key == '0' + " put amtdone on heading and return + call s:DoHeadingUpdate() + return + else + exec key + endif + "delete current summary, if any + :s/\s*\[\d\+\/\d\+\]\s*$//e + " and put new summary on + let stats = g:list_dict.AmtDone(key) + let new_summary = ' [' . stats[0] . '\/' . stats[1] . ']' + if match(new_summary,'\/[01]\]') > -1 | return | endif + exec 's/$/' . new_summary . '/' + if stats[0] == 0 + exec 's/\[\zs.\ze\]/ /e' + let g:list_dict[key].ckval = ' ' + elseif stats[0] == stats[1] + exec 's/\[\zs.\ze\]/X/e' + let g:list_dict[key].ckval = 'X' + else + exec 's/\[\zs.\ze\]/-/e' + let g:list_dict[key].ckval = '-' + endif +endfunction + +function! s:MakeListDict() + let save_pos = getpos('.') + let list_dict = {'AmtDone':function('s:AmtDone'), 0:{'c':[], 'indent':0}} + let list_pat = '^\s* [-\+\*] *' + let item_stack = [ 0 ] + let last_indent = 0 + + ?\(^\s*$\|^\*\)?+1 + while 1 + let lineno = line('.') + let linetext = getline(lineno) + let start_indent = len(matchstr(linetext, list_pat)) + let is_list_item = match(linetext, list_pat) > -1 + let has_checkbox = match(linetext, '^\s* [-\+\*] \[.\]') > -1 + + if (linetext =~ '^\s*$') + break + elseif is_list_item + let list_dict[lineno] = { 'ckbox':has_checkbox, 'c':[] } + let this_indent = len(matchstr(linetext, list_pat)) + let list_dict[lineno].indent = this_indent + if this_indent < start_indent + break + endif + if has_checkbox && (matchstr(linetext,'^\s* [-\+\*] [\zsX\ze') == 'X') + let list_dict[lineno].ckval = 'X' + endif + if this_indent > last_indent + let list_dict[lineno].p = item_stack[-1] + call add(list_dict[item_stack[-1]].c, lineno) + call add(item_stack, lineno) + elseif this_indent <= last_indent + while list_dict[item_stack[-1]].indent > this_indent + unlet item_stack[-1] + endwhile + let item_stack[-1] = lineno + let list_dict[lineno].p = item_stack[-2] + call add(list_dict[item_stack[-2]].c, lineno) + endif + endif + let last_indent = this_indent + exec lineno + 1 + endwhile + let g:list_dict = list_dict + call setpos('.', save_pos) +endfunction + diff --git a/bundle/org-mode/contrib/README.txt b/bundle/org-mode/contrib/README.txt new file mode 100644 index 000000000..2d026b8b9 --- /dev/null +++ b/bundle/org-mode/contrib/README.txt @@ -0,0 +1,19 @@ +The vim73 patch in this directory does two things: + +1. Enables level-dependent fold highlighting in Vim73. +2. Enables separate TODO highlighting in folded headings + in VimOrganizer, so TODO's stand out even when a + heading is folded. + +Two versions of the Vim73 patch are included. The _46 version +is for source code downloaded from Vim.org. The _390 version +works for the Mercurial repo version as of Dec. 31, 2011. + +The vim72 patch is old and only does (1) above. + +If someone is using a version of Windows and wants to avoid +recompiling process you can contact me and I will send you an +executable you should be able to use on your system. + +Herbert Sitz +hesitz@gmail.com diff --git a/bundle/org-mode/contrib/vim72.diff b/bundle/org-mode/contrib/vim72.diff new file mode 100644 index 000000000..1d79a2056 --- /dev/null +++ b/bundle/org-mode/contrib/vim72.diff @@ -0,0 +1,79 @@ +=== (+2,-1) src/eval.c === +@@ -355,6 +355,7 @@ + {VV_NAME("operator", VAR_STRING), VV_RO}, + {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("oldfiles", VAR_LIST), 0}, ++ {VV_NAME("foldhighlight", VAR_NUMBER), 0}, + }; + + /* shorthand */ +=== (+18,-9) src/screen.c === +@@ -2179,9 +2179,17 @@ + # define RL_MEMSET(p, v, l) for (ri = 0; ri < l; ++ri) \ + ScreenAttrs[off + (p) + ri] = v + #endif ++ /* ++ * 4. Compose the folded-line string with 'foldtext', if set. ++ */ ++ text = get_foldtext(wp, lnum, lnume, foldinfo, buf); ++ ++ txtcol = col; /* remember where text starts */ + + /* Set all attributes of the 'number' column and the text */ +- RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); ++ //RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); ++ RL_MEMSET(col, hl_attr(get_vim_var_nr(VV_FOLDHIGHLIGHT)), W_WIDTH(wp) - col); ++ + + #ifdef FEAT_SIGNS + /* If signs are being displayed, add two spaces. */ +@@ -2196,10 +2204,11 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, +- (char_u *)" ", len, hl_attr(HLF_FL)); ++ (char_u *)" ", len, hl_attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); ++ + else + # endif +- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, (char_u *)" ", len, hl_attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); + col += len; + } + } +@@ -2222,10 +2231,10 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len, +- hl_attr(HLF_FL)); ++ hl_attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); + else + #endif +- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, buf, len, hl_attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); + col += len; + } + } +@@ -2233,9 +2242,9 @@ + /* + * 4. Compose the folded-line string with 'foldtext', if set. + */ +- text = get_foldtext(wp, lnum, lnume, foldinfo, buf); +- +- txtcol = col; /* remember where text starts */ ++ //text = get_foldtext(wp, lnum, lnume, foldinfo, buf); ++// moved up above to heappen earlier h.s. ++ // txtcol = col; /* remember where text starts */ + + /* + * 5. move the text to current_ScreenLine. Fill up with "fill_fold". +=== (+3,-2) src/vim.h === +@@ -1767,7 +1767,8 @@ + #define VV_OP 52 + #define VV_SEARCHFORWARD 53 + #define VV_OLDFILES 54 +-#define VV_LEN 55 /* number of v: vars */ ++#define VV_FOLDHIGHLIGHT 55 ++#define VV_LEN 56 /* number of v: vars */ + + #ifdef FEAT_CLIPBOARD diff --git a/bundle/org-mode/contrib/vim73_390_foldinghighlighting.patch b/bundle/org-mode/contrib/vim73_390_foldinghighlighting.patch new file mode 100644 index 000000000..958b29a5d --- /dev/null +++ b/bundle/org-mode/contrib/vim73_390_foldinghighlighting.patch @@ -0,0 +1,120 @@ +Common subdirectories: src/auto and patched_src/auto +diff -u src/eval.c patched_src/eval.c +--- src/eval.c 2012-01-01 16:30:50.421710297 +0100 ++++ patched_src/eval.c 2012-01-01 17:12:53.261832394 +0100 +@@ -360,6 +360,8 @@ + {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("oldfiles", VAR_LIST), 0}, + {VV_NAME("windowid", VAR_NUMBER), VV_RO}, ++ {VV_NAME("foldhighlight", VAR_NUMBER), 0}, ++ {VV_NAME("todohighlight", VAR_NUMBER), 0}, + }; + + /* shorthand */ +Common subdirectories: src/GvimExt and patched_src/GvimExt +Common subdirectories: src/os_mac_rsrc and patched_src/os_mac_rsrc +Common subdirectories: src/po and patched_src/po +Common subdirectories: src/proto and patched_src/proto +diff -u src/screen.c patched_src/screen.c +--- src/screen.c 2012-01-01 16:41:32.945741392 +0100 ++++ patched_src/screen.c 2012-01-01 17:17:33.209845943 +0100 +@@ -2214,6 +2214,9 @@ + * 4. Compose the text + * 5. Add the text + * 6. set highlighting for the Visual area an other text ++ * NOTE: in patch for VimOrganizer step 4, composing text ++ * is moved up to happen as part of step 2. ++ + */ + col = 0; + +@@ -2271,11 +2274,16 @@ + # define RL_MEMSET(p, v, l) for (ri = 0; ri < l; ++ri) \ + ScreenAttrs[off + (p) + ri] = v + #endif +- +- /* Set all attributes of the 'number' or 'relativenumber' column and the +- * text */ +- RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); +- ++ /* ++ * 4. Compose the folded-line string with 'foldtext', if set. ++ */ ++ text = get_foldtext(wp, lnum, lnume, foldinfo, buf); ++ ++ txtcol = col; /* remember where text starts */ ++ ++ /* Set all attributes of the 'number' column and the text */ ++ RL_MEMSET(col, syn_id2attr(get_vim_var_nr(VV_FOLDHIGHLIGHT)), W_WIDTH(wp) - col); ++ + #ifdef FEAT_SIGNS + /* If signs are being displayed, add two spaces. */ + if (draw_signcolumn(wp)) +@@ -2289,10 +2297,10 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, +- (char_u *)" ", len, hl_attr(HLF_FL)); ++ (char_u *)" ", len, hl_attr(HLF_SC)); + else + # endif +- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_SC)); + col += len; + } + } +@@ -2324,20 +2332,31 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len, +- hl_attr(HLF_FL)); ++ hl_attr(HLF_N)); + else + #endif +- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, buf, len, hl_attr(HLF_N)); + col += len; + } + } ++ /* now set attributes for vimorganizer todo word in headline, if any */ ++ /* v:todohighlight is set in user's OrgFoldText() function. . . */ ++ if (get_vim_var_nr(VV_TODOHIGHLIGHT) > 0 ) ++ { ++ int start=0, end; ++ ++ while( *(text + start) == ' ' ) ++ start++; ++ end = start; ++ while( *(text + end) != ' ' ) ++ end++; ++ RL_MEMSET(start+col, syn_id2attr(get_vim_var_nr(VV_TODOHIGHLIGHT)), end - start); ++ } + + /* + * 4. Compose the folded-line string with 'foldtext', if set. + */ +- text = get_foldtext(wp, lnum, lnume, foldinfo, buf); +- +- txtcol = col; /* remember where text starts */ ++ // moved up above to happen earlier h.s. + + /* + * 5. move the text to current_ScreenLine. Fill up with "fill_fold". +Common subdirectories: src/tee and patched_src/tee +Common subdirectories: src/testdir and patched_src/testdir +diff -u src/vim.h patched_src/vim.h +--- src/vim.h 2012-01-01 16:30:51.025710325 +0100 ++++ patched_src/vim.h 2012-01-01 17:18:31.933848785 +0100 +@@ -1860,7 +1860,9 @@ + #define VV_SEARCHFORWARD 53 + #define VV_OLDFILES 54 + #define VV_WINDOWID 55 +-#define VV_LEN 56 /* number of v: vars */ ++#define VV_FOLDHIGHLIGHT 56 ++#define VV_TODOHIGHLIGHT 57 ++#define VV_LEN 58 /* number of v: vars */ + + #ifdef FEAT_CLIPBOARD + +Common subdirectories: src/VisVim and patched_src/VisVim +Common subdirectories: src/xxd and patched_src/xxd diff --git a/bundle/org-mode/contrib/vim73_46_foldhighlight.patch b/bundle/org-mode/contrib/vim73_46_foldhighlight.patch new file mode 100644 index 000000000..152b87ceb --- /dev/null +++ b/bundle/org-mode/contrib/vim73_46_foldhighlight.patch @@ -0,0 +1,113 @@ +diff -u ./src/eval.c ./patched_src/eval.c +--- ./src/eval.c 2010-08-09 13:12:14.000000000 -0700 ++++ ./patched_src/eval.c 2011-08-24 12:45:30.990183200 -0700 +@@ -362,6 +362,8 @@ + {VV_NAME("operator", VAR_STRING), VV_RO}, + {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("oldfiles", VAR_LIST), 0}, ++ {VV_NAME("foldhighlight", VAR_NUMBER), 0}, ++ {VV_NAME("todohighlight", VAR_NUMBER), 0}, + }; + + /* shorthand */ +diff -u ./src/screen.c ./patched_src/screen.c +--- ./src/screen.c 2010-08-13 06:21:27.000000000 -0700 ++++ ./patched_src/screen.c 2011-10-15 04:01:17.947926300 -0700 +@@ -2214,6 +2214,8 @@ + * 4. Compose the text + * 5. Add the text + * 6. set highlighting for the Visual area an other text ++ * NOTE: in patch for VimOrganizer step 4, composing text ++ * is moved up to happen as part of step 2. + */ + col = 0; + +@@ -2271,10 +2273,16 @@ + # define RL_MEMSET(p, v, l) for (ri = 0; ri < l; ++ri) \ + ScreenAttrs[off + (p) + ri] = v + #endif ++ /* ++ * 4. Compose the folded-line string with 'foldtext', if set. ++ */ ++ text = get_foldtext(wp, lnum, lnume, foldinfo, buf); ++ ++ txtcol = col; /* remember where text starts */ ++ ++ /* Set all attributes of the 'number' column and the text */ ++ RL_MEMSET(col, syn_id2attr(get_vim_var_nr(VV_FOLDHIGHLIGHT)), W_WIDTH(wp) - col); + +- /* Set all attributes of the 'number' or 'relativenumber' column and the +- * text */ +- RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); + + #ifdef FEAT_SIGNS + /* If signs are being displayed, add two spaces. */ +@@ -2289,10 +2297,11 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, +- (char_u *)" ", len, hl_attr(HLF_FL)); ++ (char_u *)" ", len, hl_attr(HLF_SC)); + else + # endif +- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_SC)); ++ + col += len; + } + } +@@ -2324,20 +2333,35 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len, +- hl_attr(HLF_FL)); ++ hl_attr(HLF_N)); ++ //syn_id2attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); ++ + else + #endif +- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, buf, len, hl_attr(HLF_N)); ++ //copy_text_attr(off + col, buf, len, syn_id2attr(get_vim_var_nr(VV_FOLDHIGHLIGHT))); ++ + col += len; + } + } + ++ /* now set attributes for vimorganizer todo word in headline, if any */ ++ /* v:todohighlight is set in user's OrgFoldText() function. . . */ ++ if (get_vim_var_nr(VV_TODOHIGHLIGHT) > 0 ) ++ { ++ int start=0, end; ++ ++ while( *(text + start) == ' ' ) ++ start++; ++ end = start; ++ while( *(text + end) != ' ' ) ++ end++; ++ RL_MEMSET(start+col, syn_id2attr(get_vim_var_nr(VV_TODOHIGHLIGHT)), end - start); ++ } + /* + * 4. Compose the folded-line string with 'foldtext', if set. + */ +- text = get_foldtext(wp, lnum, lnume, foldinfo, buf); +- +- txtcol = col; /* remember where text starts */ ++ // moved up above to happen earlier h.s. + + /* + * 5. move the text to current_ScreenLine. Fill up with "fill_fold". +diff -u ./src/vim.h ./patched_src/vim.h +--- ./src/vim.h 2010-07-29 11:46:39.000000000 -0700 ++++ ./patched_src/vim.h 2011-08-11 14:22:52.525545700 -0700 +@@ -1842,7 +1842,9 @@ + #define VV_OP 52 + #define VV_SEARCHFORWARD 53 + #define VV_OLDFILES 54 +-#define VV_LEN 55 /* number of v: vars */ ++#define VV_FOLDHIGHLIGHT 55 ++#define VV_TODOHIGHLIGHT 56 ++#define VV_LEN 57 /* number of v: vars */ + + #ifdef FEAT_CLIPBOARD + diff --git a/bundle/org-mode/contrib/vim74_foldhighlight.patch b/bundle/org-mode/contrib/vim74_foldhighlight.patch new file mode 100644 index 000000000..79041781a --- /dev/null +++ b/bundle/org-mode/contrib/vim74_foldhighlight.patch @@ -0,0 +1,108 @@ +diff -u src-orig\eval.c src-changed\eval.c +--- src-orig\eval.c Fri Jul 05 09:23:42 2013 ++++ src-changed\eval.c Tue Oct 29 13:58:08 2013 +@@ -358,6 +358,8 @@ + {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("oldfiles", VAR_LIST), 0}, + {VV_NAME("windowid", VAR_NUMBER), VV_RO}, ++ {VV_NAME("foldhighlight", VAR_NUMBER), 0}, ++ {VV_NAME("todohighlight", VAR_NUMBER), 0}, + }; + + /* shorthand */ +diff -u src-orig\screen.c src-changed\screen.c +--- src-orig\screen.c Sat Jul 13 03:23:00 2013 ++++ src-changed\screen.c Tue Oct 29 13:52:39 2013 +@@ -2374,6 +2374,9 @@ + * 4. Compose the text + * 5. Add the text + * 6. set highlighting for the Visual area an other text ++ * NOTE: in patch for VimOrganizer step 4, composing text ++ * is moved up to happen as part of step 2. ++ + */ + col = 0; + +@@ -2432,9 +2435,15 @@ + ScreenAttrs[off + (p) + ri] = v + #endif + +- /* Set all attributes of the 'number' or 'relativenumber' column and the +- * text */ +- RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col); ++ /* ++ * 4. Compose the folded-line string with 'foldtext', if set. ++ */ ++ text = get_foldtext(wp, lnum, lnume, foldinfo, buf); ++ ++ txtcol = col; /* remember where text starts */ ++ ++ /* Set all attributes of the 'number' column and the text */ ++ RL_MEMSET(col, syn_id2attr(get_vim_var_nr(VV_FOLDHIGHLIGHT)), W_WIDTH(wp) - col); + + #ifdef FEAT_SIGNS + /* If signs are being displayed, add two spaces. */ +@@ -2449,10 +2458,10 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, +- (char_u *)" ", len, hl_attr(HLF_FL)); ++ (char_u *)" ", len, hl_attr(HLF_SC)); + else + # endif +- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_SC)); + col += len; + } + } +@@ -2494,20 +2503,31 @@ + if (wp->w_p_rl) + /* the line number isn't reversed */ + copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len, +- hl_attr(HLF_FL)); ++ hl_attr(HLF_N)); + else + #endif +- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL)); ++ copy_text_attr(off + col, buf, len, hl_attr(HLF_N)); + col += len; + } + } ++ /* now set attributes for vimorganizer todo word in headline, if any */ ++ /* v:todohighlight is set in user's OrgFoldText() function. . . */ ++ if (get_vim_var_nr(VV_TODOHIGHLIGHT) > 0 ) ++ { ++ int start=0, end; ++ ++ while( *(text + start) == ' ' ) ++ start++; ++ end = start; ++ while( *(text + end) != ' ' ) ++ end++; ++ RL_MEMSET(start+col, syn_id2attr(get_vim_var_nr(VV_TODOHIGHLIGHT)), end - start); ++ } + + /* + * 4. Compose the folded-line string with 'foldtext', if set. + */ +- text = get_foldtext(wp, lnum, lnume, foldinfo, buf); +- +- txtcol = col; /* remember where text starts */ ++ // moved up above to happen earlier h.s. + + /* + * 5. move the text to current_ScreenLine. Fill up with "fill_fold". +diff -u src-orig\vim.h src-changed\vim.h +--- src-orig\vim.h Fri Aug 02 07:02:27 2013 ++++ src-changed\vim.h Tue Oct 29 13:59:29 2013 +@@ -1866,7 +1866,9 @@ + #define VV_SEARCHFORWARD 53 + #define VV_OLDFILES 54 + #define VV_WINDOWID 55 +-#define VV_LEN 56 /* number of v: vars */ ++#define VV_FOLDHIGHLIGHT 56 ++#define VV_TODOHIGHLIGHT 57 ++#define VV_LEN 58 /* number of v: vars */ + + #ifdef FEAT_CLIPBOARD + diff --git a/bundle/org-mode/doc/vimorg.txt b/bundle/org-mode/doc/vimorg.txt new file mode 100644 index 000000000..e0ef79428 --- /dev/null +++ b/bundle/org-mode/doc/vimorg.txt @@ -0,0 +1,1833 @@ +*VimOrganizer.txt* for Vim versions with folding and tabs +A clone of Emacs' Org-mode for Vim + +Author: Herbert Sitz +Version: 0.30, 2011 Nov 02 + +Copyright: (c) 2010, 2011 by Herbert Sitz + The VIM LICENSE applies to code in the VimOrganizer project, + unless otherwise indicated. + (See Vim's |copyright| and substitute 'VimOrganizer' for 'Vim'.) + NO WARRANTY, EXPRESS OR IMPLIED. USE AT-YOUR-OWN-RISK. +============================================================================== +CONTENTS *VimOrganizer* *vimorg* + + Contents.....................................: |VimOrganizer| + VimOrganizer Overview........................: |vimorg-overview| + Document Structure...........................: |vimorg-document-structure| + File compatibility with Org-mode.............: |vimorg-org-compatibility| + Vimorg / Emacs Interaction ..................: |vimorg-emacs-interaction| + Vimorg / Org-mode Conversion.................: |vimorg-org-conversion| + Vimorg Metadata .............................: |vimorg-metadata| + |vimorg-tag-metadata| + |vimorg-todo-metadata| + |vimorg-property-metadata| + |vimorg-date-metadata| + |vimorg-categories| + + Vimorg Commands .............................: |vimorg-commands| + + Modifying view of the outline structure |vimorg-view-commands| + Adding new headings |vimorg-new-headings| + Heading Navigation |vimorg-navigation| + Editing Document Structure |vimorg-structure-editing| + Character formatting |vimorg-character-formatting| + Footnotes |vimorg-footnotes| + Capture |vimorg-capture-buffer| + Refiling |vimorg-refile-heading| + Mark |vimorg-mark| + Gather |vimorg-gather| + Hyperlinks |vimorg-hyperlinks| + Narrowing Regions |vimorg-narrowing| + Tables in VimOrganizer |vimorg-tables-editing| + Clocking |vimorg-clocking| + + Colorschemes and highlighting |vimorg-colors| + Code and spreadsheet evaluation in Emacs.....: |vimorg-code-eval| + |vimorg-spreadsheet-eval| + + Searches and the Agenda .....................: |vimorg-agenda| + agenda + Setting the agenda files + sparse tree + custom searches |vimorg-agenda-custom-searches| + block agendas |vimorg-agenda-blocks| + agenda window position |vimorg-agenda-window-position| + clocktables in agenda |vimorg-agenda-include-clocktable| + + Navigating agenda files |vimorg-files-navigating| + + Column view..................................: |vimorg-column-view| + Exporting and Printing.......................: |vimorg-export| + + Feedback.....................................: |vimorg-feedback| + +============================================================================== +VIMORGANIZER OVERVIEW *vimorg-overview* + +VimOrganizer is a Vim filetype plugin that attempts to clone Emacs' Org-mode. +It is currently (September 2011) in an alpha-stage, both in terms of (1) the +breadth and depth of Org-mode features it clones and (2) its level of polish +and presence of bugs. It's nevertheless very usable in its current state. + +Org-mode, and thus VimOrganizer, is a text-editor add-on/application that can +be used for (1) keeping notes, (2) maintaining TODO lists, (3) planning +projects, and/or (4) authoring and publishing documents, including support for +literate programming. Like Org-mode, VimOrganizer does this by implementing a +flexible plain-text system using a lightly structured document format. +Org-mode has been in constant development for seven or eight years, and +continues to be developed. Work on VimOrganizer is likewise ongoing, but +VimOrganizer is at present a much smaller and less ambitious project than +Org-mode. + +VimOrganizer also allows Vim users to make use of Org-babel, a subproject of +Org-mode that allows execution of source-code blocks in org-format +documents. Uses for Org-babel range from writing technical research papers to +simply using a VimOrganizer document as a "language-scratchpad". Over +twenty languages are supported, including C, R, Lisp, Python, Perl, Ruby, +and others. VimOrganizer calls out to a running Emacs server for Org-babel +processing; functionality and speed are basically the same as +when editing with Org-mode in Emacs. + +VimOrganizer doesn't have much documentation yet. The best way to learn how +to use VimOrganizer is to learn the basics of Emacs' Org-mode. VimOrganizer +uses the same basic concepts but implements them within the context of Vim +and with a reduced feature set. (Parts of this help file were +copied from Org-mode's documentation.) Org-mode's main documentation and +support newsgroup are found here: +Org-mode Main Manual: http://orgmode.org/manual/index.html +Org-mode Compact Guide: http://orgmode.org/guide/index.html +Org-mode support newsgroup: http://news.gmane.org/gmane.emacs.orgmode +Org-babel information: http://orgmode.org/worg/org-contrib/babel/ + +File formats and basic workflows for VimOrganizer and Org-mode are very +similar, and VimOrganizer actually calls out to an Emacs' Org-mode server to +implement important features, e.g., exporting to html and pdf formats. +Thus, to make full use of VimOrganizer you will often want to have an Emacs' +server running alongside. In most cases this requires little knowledge of +Emacs other than how to start it up and add a few lines to the '.emacs' file, +Emacs' counterpart to Vim's '.vimrc'. (You can even edit the .emacs file in +Vim.) + +=============================================================================== +VIMORGANIZER DOCUMENT STRUCTURE *vimorg-document-structure* + +VimOrganizer documents (an "Org document") are organized around a basic +outline structure. Headlines define the structure of an outline tree. The +headlines in an Org document start with one or more stars, which must start on +the leftmost column. For example: + +------ sample Org-format outline below -------------------------------- + > + * Top level headline + ** Second level + *** 3rd level + some text + *** 3rd level + more text + * Another top level headline + more text +------ sample Org-format outline above -------------------------------- + +An overview of this structure is achieved by folding (hiding) large parts of +the document to show only the general document structure and the parts +currently being worked on. VimOrganizer simplifies the use of outlines by +compressing the entire show/hide functionality of a heading and its subtree +into a simple "cycle" operation, which is bound to the key. A user can +cycle through several views, from fully folded to unfolded, by repeated +presses of . While operates on the structure of a single heading, + performs an analogous cycle operation on the document as a whole. + +Because all of the folds in VimOrganizer are ordinary Vim folds, users can +also manipulate folds with the usual array of Vim fold commands: zc, zv, zo, +etc. (see |fold.txt|) + +=============================================================================== +VIMORGANIZER FILE COMPATIBILITY WITH ORG-MODE *vimorg-org-compatiblity* + +VimOrganizer's file format is nearly identical to Org-mode. There are +currently a couple of differences: + +------------------------------------------------------------------------------- +METADATA-BLOCKS *vimorg-metadata-format* + +In VimOrganizer lines in a heading's metadata must (1) immediately follow +the heading line, and (2) all begin with a colon followed by a +non-whitespace character. + +Blocks of metadata typically follow a heading in Org-mode documents, but +Org-mode doesn't require this. That is, the metadata can be anywhere in the +text block of a heading. Also, in Org-mode some, but not all (e.g., dates), +metadata lines are preceded by a colon (:) character. E.g., + +------ sample Org-format outline below ---------- + > + * Top level headline + DEADLINE:<2011-11-13 Thu> + :PROPERTIES: + :SOMEPROP:SomePropValue + :END: + One or more lines of text for heading here. . . . + SCHEDULED:<2011-11-12 Wed> + One or more lines of text for heading here. . . . + ** subheading + ** another subheading +------ sample Org-format outline above --------- + +The sample above should be formatted like this in +VimOrganizer, with the SCHEDULED date moved above +PROPERTIES and colons preceding the date lines: + +------ sample VimOrganizer-format outline below ----- + > + * Top level headline + :DEADLINE:<2011-11-13 Thu> + :SCHEDULED:<2011-11-12 Wed> + :PROPERTIES: + :SOMEPROP:SomePropValue + :END: + One or more lines of text for heading here. . . . + ** subheading + ** another subheading +------ sample VimOrganizer-format outline above ---- + +------------------------------------------------------------------------------ +TAG FORMAT IN VIMORGANIZER *vimorg-tag-format* + +The second major difference between VimOrganizer and Org-mode is in the +format of tag data. In Org-mode tags are included on heading lines as +following the end of the heading. In VimOrganizer tags are included as part +of the metadata block and must be on the first line following a heading. + +For example, tags in Org-mode look like this: + +------ sample Org-format tags below ---------- +> + * Top level headline :tagone:tagtwo:tagthree: + :PROPERTIES: + :SOMEPROP:SomePropValue + :END: + One or more lines of text for heading here. . . . +------ sample Org-format tags above --------- + +The same tags in VimOrganizer would look like this: + +------ sample VimOrganizer-format tags below ---------- +> + * Top level headline + :tagone:tagtwo:tagthree: + :PROPERTIES: + :SOMEPROP: SomePropValue + :END: + One or more lines of text for heading here. . . . +------ sample VimOrganizer-format tags above --------- + +In practice the difference is less visible, since for folded headings the +default settings in VimOrganizer can show the tags on the same line as the +heading text. (See |vimorg-column-view|) + +============================================================================== + +VIMORGANIZER AND EMACS INTERACTION *vimorg-emacs-interaction* + *vimorg-emacs-setup* + +CALLING AN EMACS CLIENT FROM VIMORGANIZER *vimorg-invoking-emacs* + +For features where Vim/VimOrganizer call out to an Emacs client, setup +must be configured to properly invoke the Emacs client. This differs depending +on whether the user is running Windows or a Linux/OS X OS. + +First, of course, Emacs must be installed and Org-mode must be set up +properly. Recent Emacs installs include Org-mode and should work without any +more configuration than a basic install. A '.org' file should be opened in +Emacs to confirm this. Emacs can be obtained from a link at +http://www.gnu.org/software/emacs. + +a. On WINDOWS. The variable, g:org_command_for_emacsclient, must be +assigned in your vimrc file with a command that will open an emacs client +on your system. On Windows the associated exe file is emacsclientw.exe +in Emacs' bin directory. By default Emacs is installed with +a path that includes spaces in a directory name (viz., '/program files/). +The complex command that VimOrganizer constructs to call +Emacs won't work if the command invoking Emacs itself +includes a space. There are two ways to work around this: 1. Create a +"symbolic link" to the Emacs client executable that doesn't have a space and +include that link as value of g:org_command_for_emacs, e.g., +> + let g:org_command_for_emacsclient = c:\users\george\emacsclientw + +On Windows7 or Vista, the link can be created with Windows' MKLINK command line utility: +> + mklink c:\users\george\emacsclientw c:\program files(x86)\Emacs\emacs\bin\emacsclientw.exe + +Alternatively, rather than create a symbolic link having a path with no +spaces, a user can add the directory to the environment's path variable, so +that the emacsclient can be invoked simply by issuing the command +'emacsclientw', without including any element of its path. In that case you +would include this assignment in your vimrc: +> + let g:org_command_for_emacsclient = emacsclientw.exe + + +b. ON LINUX/OS X. On Linux the executable to start an Emacs client is +named emacsclient. In general all you need to do is put this line +in your vimrc: +> + let g:org_command_for_emacsclient = emacsclient + +NOTE: Unlike the Emacs client on Windows, emacsclient on Linux will NOT start +up an Emacs server if one is not running, the emacsclient command will simply +fail. +Thus, at least for the time being, the user must manually start Emacs before +using Emacs features from VimOrganizer, and in the running Emacs instance must +issue the server-start command, either by putting it in the .emacs file or by +issuing the command manually within Emacs (alt-x server-start). + +---------------------------------------------------------------------------- + +CONVERSION BETWEEN ORG-MODE AND VIMORGANIZER *vimorg-orgmode-conversion* + +In practice nothing may go drastically wrong if you don't have perfect +formatting, either in VimOrganizer or Org-mode, but VimOrganizer by default is +set to convert Org-mode documents to its own format upon opening. Also, it is +recommended to put a "hook" function in your .emacs file to convert +VimOrganizer-format documents to Org-mode format upon opening. Once set up in +this way you shouldn't need to worry about formatting differences. The +code to add to your .emacs file is below: + +--------- elisp code for .emacs --------------------- + > + (defun vimorg-tag-adjust () + (interactive) + (while (re-search-forward "^*.*?\n[ \t]+:[^ \t]+:" nil t) + (if (not (string-match "\\(PROPERTIES\\|LOGBOOK\\)" (thing-at-point 'line))) + (join-line)))) + + (defun vimorg-set-unmodified () + (interactive) + (set-buffer-modified-p nil)) + + (add-hook 'org-mode-hook + (lambda () (interactive)(replace-regexp "\\(\\s-*\\):\\(DEADLINE\\|CLOSED\\|SCHEDULED\\|CLOCK\\|<[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \\)" "\\1\\2") + (beginning-of-buffer)(vimorg-tag-adjust) + (beginning-of-buffer) )) +----------------------------------------------------- + +============================================================================== +METADATA *vimorg-metadata* + +Org-mode has different kinds of metadata: tags, todos, properties, dates, and +categories. Here is how to set up and edit them. +------------------------------------------------------------------------ +TODOS *vimorg-todo-metadata* + +*Todos* are single_words that can appear in a heading after the last asterisk +and immediately before the first word of the heading. By default the todos +are: (1) TODO and (2) DONE, to identify headings that are tasks that need to +be done, and headlines that are done tasks. + +A user can cycle between todo states by pressing in Normal mode +with the cursor on a headline. Here is how the todos would cycle with the +default setup of TODO and DONE todos: +> + * Work on final report + * TODO Work on final report (after user presses ) + * DONE Work on final report (after second press of ) + * Work on final report (after third press of ) + +The global default for todos setup is in g:org_todo_setup. If you want to +change the todo states you can reassign g:org_todo_setup in your vimrc. For +example, the line below would add a 'STARTED' state to indicate todos that +had been started but were not yet finished: +> + let g:org_todo_setup='TODO STARTED | DONE' + +Per-file defaults can be set by including a config line in a particular .org +file. For example, the config line below would add a CANCELLED keyword to +the todo cycle in a specific document: +> + #+TODO: TODO STARTED | DONE CANCELLED + +Please see the Org-mode documentation for more info on todos. It should be +helpful, even though not all Org-mode todo features are implemented yet in +VimOrganizer: http://orgmode.org/manual/TODO-Items.html. +------------------------------------------------------------------------- +TAGS *vimorg-tag-metadata* + +Tags offer a way of attaching multiple labels or contexts to a single heading. +Tags are added to a heading by putting them on the line immediately after +the heading, with each tag preceded and followed by a single colon. E.g., +here is a heading with two tags: +> + * Example heading + :work:urgent: + +You can add whatever tags you wish by editing the tag line directly, however +it's usually preferable to use VimOrganizer's system for setting up and +editing tags. Global tags setup is held in the variable, g:org_tag_setup, +which by default holds the setup string '{home(h) work(w)}'. You can override +the global setup by including a config line in a particular file. E.g.,: +> + #+TAGS: { work(w) home(h) tennisclub(t) } laptop(l) pc(p) + +The braces in the example above indicate that the tags inside are mutually +exclusive, so choosing one will automatically delete any other. The letters +in parentheses provide single-key selection when using VimOrganizer's +tag editing menu. (Single-key letters will be assigned automatically if +not explicitly assigned in the tag setup string. + +The tag editing menu can be opened by choosing 'Edit Tags' from the Org +menu, or by pressing ',et' in Normal mode. + +Although not all Org-mode tag functionality is present in VimOrganizer, it +may be helpful to review the Org-mode tag docs at: +http://orgmode.org/manual/Tags.html#Tags + +------------------------------------------------------------------------- +PROPERTIES *vimorg-property-metadata* + +Properties offer a way to attach key/value pairs to headings in a document. +These pairs must be included, one per line, in between a :PROPERTIES: and +an :END: marker beneath a heading. For example: +> + * Example heading + :PROPERTIES: + :Title: Goldberg Variations + :Composer: J.S. Bach + :Artist: Glen Gould + :Publisher: Deutsche Grammophon + :NDisks: 1 + :END: + +For more information on how properties work, please refer to the Org-mode +documentation: +http://orgmode.org/manual/Properties-and-Columns.html#Properties-and-Columns + +------------------------------------------------------------------------- +DATES *vimorg-date-metadata* + +Dates are another form of metadata that can be associated with a heading. +The following commands may be issued anywhere within a headline and will +enter or edit the corresponding date for the headline. One date of +each type may be defined per headline (i.e, 'DEADLINE', 'SCHEDULED', +'CLOSED', and 'timestamp'). You can enter more dates anywhere you want, but +this editing mechanism is currently restricted to dealing with only these +"primary" dates. + +Command Result +,dd enter DEADLINE date for headline +,ds enter SCHEDULED date for headline +,dc enter CLOSED date for headline +,dt enter timestamp date (i.e., no indicator) for headline +,dg set date at cursor + +The command-line prompt and calendar that appear when you execute a ',d_' +command operate nearly the same as the date-time prompt in Emacs' +Org-mode. Some options are not yet implemented (e.g., the 'w'eek +options), but most should work just the same. For documentation +on Org-mode's date-time prompt see: +http://orgmode.org/manual/The-date_002ftime-prompt.html#The-date_002ftime-prompt + +Except when using the 'set date at cursor' option, the date will be located +beneath the heading, immediately after any tag line, and immediately before +any PROPERTIES block. Dates added in other locations will be searched +when using VimOrganizer's searches, but they aren't strictly speaking part +of the 'metadata block' that immediately follows a heading. +------------------------------------------------------------------------- +CATEGORIES *vimorg-categories* + +Categories are yet another form of metadata in Org files. Categories +are useful because a heading's 'Category' is displayed as the first column +of data in a heading line in Agenda results. (Remember that there +is limited space for display, try to keep category names less than +10 characters.) By default a heading's Category will be its file name. +However you can change this in several ways. + +First, you can establish a new category for an entire document by +placing a category config line at the top of the document. All +headings in the document will inherit it as their default. Like +all config lines, it must begin in the leftmost column of the buffer, +e.g.,: +> + #+CATEGORY: MyCategory + +All headings in the document would now display that as the first column +when they are part of an agenda result. + +Second, you can override a document's default category by giving a +heading a category property, like this: +------------------------ +> + * Heading One + :PROPERTIES: + :CATEGORY: NewCategory + :END: + ** Subheading One + ** Subheading TWo + * Heading Two +------------------------ +In the snippet above, Heading One's category would be 'NewCategory'. +Categories are inherited by subheadings, so Subheading One and Sub- +heading Two would also be 'NewCategory'. Heading Two, on the other +hand, would inherit the category from a config line, if any, or its +category would be the file name (excluding the . and extension). + +You can read more about how categories work here: +http://orgmode.org/manual/Categories.html#Categories +NOTE: Although Org-mode still supports multiple category config +lines in a document, each affecting text occurring after it (and +before another category config line), VimOrganizer does not +support this. You can put one CATEGORY config line in a document and +it will be inherited by any heading that does not have a CATEGORY +property (or inherit a CATEGORY property from an ancestor heading). + +============================================================================= +VIMORGANIZER COMMANDS *vimorg-commands* + +VimOrganizer commands are listed below, along with the normal-mode +keystrokes to invoke them. ( in VimOrganizer documents +is by default the comma (",") character, which accounts for the commas +in the commands below): + +--------------------------------------------------------------------- +MODIFYING VIEW OF THE OUTLINE STRUCTURE *vimorg-view-commands* + +View Document Structure Show entire document with headings +,,N expanded to outline level N. +where N is for level 1-9 + +View Subtree Structure Show current subtree with headings +,N expanded to outline level N. +where N is for level 1-9 +--------------------------------------------------------------------- +ADDING NEW HEADINGS *vimorg-new-headings* + +New headings can of course be added by normal Vim text editing. Create +a new line and put one or more asterisks starting flush with the left +column. Normal mode commands below are shortcuts to do the same thing. + + +new heading same level Insert a new heading of current level + in normal mode after current heading's subtree. + in insert mode + +new subhead Insert a new heading that is a + sub-heading of the current heading + +new parent head Insert a new heading that is at + the level of current subhead's parent + +----------------------------------------------------------------------- +HEADING NAVIGATION *vimorg-navigation* + +VimOrganizer has commands that let you navigate a document by outline +node. Some outline navigation commands are not mapped to keys but are +available on the menu. + +Up to parent Move cursor to parent heading. + + +Previous sibling Move cursor to previous heading + of same level in current subtree. + +Next sibling Move cursor to next heading of + same level in current subtree + +First child Move cursor to first child heading + of current heading. + +Last child Move cursor to last child heading + of current heading. + +Next heading . . . to next heading of any kind + +Previous heading . . . to previous heading of any kind + +Next heading same level . . . to next heading of same level + regardless of whether it is in + current subtree + +Previous heading same level . . . to next heading of same level + regardless of whether it is in + current subtree +---------------------------------------------------------------------- +EDITING DOCUMENT STRUCTURE *vimorg-structure-editing* + +These commands let you move entire sections of a document based on its +outline structure. + +Move subtree up Move current subtree to position + before previous subtree. + +Move subtree down Move current subtree to position + after next subtree. + +Promote subtree Move entire subtree to be at parent + heading's level and position after + parent subtree. + +Demote subtree Move entire subtree to be child + of previous heading of same level. +-------------------------------------------------------------- +CHARACTER FORMATTING *vimorg-character-formatting* + +These commands automatically add the markup Org-mode uses to print +documents with specially formatted text. Text can be selected +prior to issuing command to wrap text in markup or just issue +the command then add text between the markup delimiters. + +NOTE: these delimiters do NOT format phrases that span +over a line break, they are for the same line only. If you +want to format over two or more lines you need to apply +to each word in the lines (for safety when reformatting) +or to the begin and end of each line (which will pose +problems upon reformatting). + +Bold text uses * delimiters +,cb + +Italic text uses / delimiters +,ci + +Underline text uses _ delimiters +,cu + +Code text uses = delimiters to specify +,cc monospaced unformatted text + +---------------------------------------------------- +FOOTNOTES *vimorg-footnotes* + +VimOrganizer has no special support for footnotes yet. However footnotes can +still be easily included, and upon export will be properly positioned +formatted (and linked, depending on the output format). The special support +that will be added consists mostly of automatically assembling footnote text +in a separate portion of the document. + +You can add footnotes in any of the following ways: + + [fn::text of footnote here] This inline method will make the + text into a footnote and add a + proper footnote reference at the + position of the reference. + + [fn:name:text of footnote here] This inline method allows the same + note to be referenced by another + note reference of this form: + [fn:name] + + [fn:name] This creates a reference point in + the document that will be numbered + and linked to the footnote text with + the same name. The text of the foot-, + note is entered in a separate + paragraph of its own, located + anywhere in the document but always + beginning in column 0, like this: + +[fn:name] This paragraph (text to next blank line) is the note +for the footnote reference: name. Upon export numbers will be +substituted for all of the footnote names in the document. + +See the Org-mode documentation for more complete information +on footnotes. Remember, you can use them in VimOrganizer, the +main thing missing is automatic gathering of all the note +text at a common point in the document: +http://orgmode.org/manual/Footnotes.html#Footnotes + +---------------------------------------------------- +CAPTURE BUFFER *vimorg-capture-buffer* + *OrgCapture* + *g:org_capture_file* + +The "capture buffer" is a buffer that can be opened +wherever you are in Vim. It provides a quick and +simple way to "capture" a note in a "capture file" +that you can review later and refile items to +whatever end location is appropriate. "Capturing" +in essence lets you quickly save a note without having +to worry about identifying or opening the file it +will eventually end up in. Later you can open your +capture file and focus on refiling all of your notes +to the appropriate spot in one of your .org files. + +The capture buffer opens with a simple +Org template of a single level 1 heading with no text +and a generic datetime marking the date of creation. +E.g., > + + * + :<2012-01-08 Sun 16:00> + +The buffer is opened in insert mode with the cursor positioned +one space to the right of the asterisk, where you can +enter the heading text, then enter the content of the note +below the timestamp. + +When in the capture buffer the write command (:w) will +(1) save the contents of the capture buffer to the capture file, +then (2) close the capture buffer. + +When in a capture buffer the quit command (:q) will abandon any changes +and close the buffer without confirmation. + +A "capture buffer" can be opened by choosing "Open +Capture Buffer" from the menu in gvim or with with the command +:OrgCapture. The :OrgCapture command should be defined in +your vimrc and is part of the sample vimrc of the VimOrganizer +project. This ensures that the command is enabled regardless +of whether you have opened a .org file in your Vim session. + +The command :OpenCaptureFile will open your capture file +into a Vim buffer, so you can then refile each of the items +in it to the appropriate location. + +---------------------------------------------------- +REFILING *vimorg-refile-heading* + *vimorg-jump-to-headng* + +Refiling involves moving a subtree structure +to a new location, either in the current document or +another document. (The user interface for +this is currently barebones and not optimal, like many other +things it will be revised. . . .) + + Open refile dashboard + ,r Open the refiling dashboard. Type an action's + character to perform it, or to cancel and + close the menu. + + Refile to point + ,rr Move current subtree to be subchild + of heading at a different location. + Invoking this command first presents + you with a 'Target file:' prompt, at + which you can use to choose the + file target. Then press to + get a list of top-level headings in + the selected file. If you want to + select a lower-level heading then add + a '/' and press to get list of + direct subheadings of the heading, or + '*' and to get list of all levels + of subheads of selected heading. Finally, + to choose the heading to refile to, + or to cancel the refile. + + Refile, jump to point + ,rj Uses same prompt as 'Refile to point' command, + but instead of moving subtree there simply + moves cursor to that point (which may involve + moving to a different buffer if chosen point + is not in current buffer). + + Refile, set persistent + refile point + ,rs Same prompt as for 'Refile to point' command, + but instead of refiling it saves the + chosen file and heading to be used as + target of subsequent 'Refile to Persistent + Point' command. + + Refile to persistent + refile point + ,rp Move current subtree to location defined + by the persistent refile point. + + Refile, jump to + persistent point + ,rx Move cursor to file/heading that is persistent + refile point. + + Refile to last + refile point + ,rl Refile the current subtree to the previously + used location + + Refile, jump to last + refile point + ,rz Move cursor to the previously used refile + location + +Items may be refiled to an archive file. The archive has the same path +and name as the originating file with '_archive' appended. Archived +subtrees are appended to the end. Additional properties are added like +the archival date and time. + + Refile to archive + ,ra Refile to the end of the archive file + associated with the current org file + + Jump to archive + ,rv Open the archive file in a new tab. + + +------------------------------------------------------------------------ +MARK *vimorg-mark* + +Headings may be toggled to a "marked" state in either an .org buffer +or in the agenda. +Note that the keymap to mark a heading is different depending on +whether you're in an .org buffer or in the Agenda: + +In an .org buffer: , +In the Agenda: + +In the Agenda certain operations will work on all marked headings -- +if any are marked -- otherwise only on current heading: + + Date edits + Todo edits + Refiling + +In an .org buffer these operations will operate on all marked +headings: + + Refiling + Gathering + +When operating on multiple marked headlines, the above operations will +operate on all marks in any open .org buffer. I.e., they are not restricted +to marks in the current .org buffer. + +Also, when the operation is complete the headlines will all be toggled +to an 'unmarked' state. + +All 'marked' headlines may be toggled to 'unmarked' by choosing +'Unmark all' from the 'Mark/Gather/Sort' menu in gvim, or with +key combination of: + , in an .org buffer, or + in Agenda + +'gathered' headings are normally placed after the last subhead of +the heading from where 'gather' command is issued, but they will +always be placed at top of subheads if g:org_reverse_note_order = 1 + +------------------------------------------------------------------------ +GATHERING *vimorg-gather* + *vimorg-gather-sort* + +'Gathering' refers to a process whereby all 'marked' headings are +moved to be subheads of the current heading in an .org buffer. +(Gather is not available from or to the Agenda buffer.) + +A simple gather dashboard is accessed by pressing: ,g + +'gather' can be thought of as a different way of doing 'refiling'. +In refiling you mark all headings to be refiled to the same spot, +then choose a refile operation to select a target heading to move them to. +With 'gather' you mark all the headings, then simply move to the target +heading and issue the 'gather' command. + +The 'gather' operation can be accessed from the 'Mark/Gather/Sort' +menu in gvim or by the key command: ,gh + +------------------------------------------------------------------------ +GATHER AND SORT *vimorg-sort* + +The 'sort' operation reorders subheadings of the current heading to +be in alphabetical or reverse-alphabetical order. Normal order +is (case-sensitive) alphabetical, reverse is used if the variable, +g:org_reverse_note_order is equal to 1. + + +------------------------------------------------------------------------ +KEYBINDINGS *vimorg-keybindings* + +Keybindings are still a moving target. I'm happy to hear from people +who think they've found better command bindings. You can look up bindings +(1) in this help file, (2) in the menu in g(raphical)vim, which lists +binding next to command you choose, and/or in the vimorg-main-mappings.vim +and vimorg-agenda-mappings.vim scripts in the ftplugin directory. A few +mappings, mostly agenda stuff, are also made in the main org.vim ftplugin +file. The keybindings are messy and will be cleaned up at some point. + + *vimorg-keybindings-terminal* +TERMINAL KEYBINDINGS. It's important to understand that many of the +default bindings are NOT available in many or all versions of vim running +on terminals. This is the fault of the terminal for not handling the +particular key combination. Here's a link to an Org-mode webpage listing +common key combinations that are not available in terminals, with suggested +Emacs alternatives. Vim keybindings are of course different (no crazy +chord combinations), but the suggestions there might give you ideas for +mappings you want to do for yourself: +http://orgmode.org/manual/TTY-keys.html#TTY-keys + +Below are the alternate mappings already in VimOrganizer for the most +commonly-used key combinations that aren't available in terminals. They +are found at the bottom of the file, vimorg-main-mappings.vim in the +ftplugin folder: + +, GlobalCycle (same as in gvim) + (note default for , is now to toggle between org buffer/Agenda buffer) +gk Node navigate up (same as ... ) +gj Node Navigate down (same as ... ) +gh Node navigate left (same as ... ) +gl Node navigate right (same as ... ) +<< Promote heading tree (same as ... ) +>> Demote headng tree (same as ...) +<, Move heading tree up (same as ... ) +>. Move headng tree down (same as ... ) +np Add new heading node below at parent's level () +ns Add new heading node below at subhead level () + + +------------------------------------------------------------------------ +HYPERLINKS *vimorg-hyperlinks* *vimorg-links* + +VimOrganizer uses the same hyperlink markup style as Org-mode, but doesn't +support as many types of links. You can read about the Org-mode link +format here: http://orgmode.org/manual/Hyperlinks.html#Hyperlinks . + +While you can add and edit links with VimOrganizer without it, to follow +external links you must have the "Universal Text Linking" Vim plugin (UTL) +installed. You can find it here: +http://www.vim.org/scripts/script.php?script_id=293 . +UTL itself does not use Org-mode compatible links, but it is used by +VimOrganizer behind the scenes to follow links. + +In general, an Org-mode formatted link looks like this: +> + [[link_specification][descriptive_link_name] + +You can also use a link with no descriptive name: +> + [[link_specification]] + +Here is an example that links to the Yahoo home page: +> + [[http://www.yahoo.com][Yahoo home page]] + +If using a Vim version that has the 'conceal' feature, VimOrganizer allows +you to set your display so that the brackets and the link specification +are hidden, and you see only the highlighted *descriptive_link_name* . +(If the link has a link-specification only, no descriptive name, then +just the brackets will be hidden in conceal mode.) + + +Add/edit link Allows you to edit a link in the command line. +,le You are first prompted for the link + specification, then press and you + will be prompted for a link name. + +Follow link Will "follow" a link. With web URLs this +,lf will open a browser, with files it will +(or just press open the file in an appropriate app if a +cursor on the link) handler app has been defined. (UTL setup + has default set of handlers and can be + changed.) Internal links will move to + associated spot within a vimorg document. + + NOTE: The Org-mode format requires that + the 'http://' prefix be included when specifying + web urls. Links will fail if you don't + include 'http://'. + +Next link Moves to next link in the document. +,ln + +Previous link Moves to previous link in the document. +,lp + +Perma-compress links There are three types of link "compression". +,lc All work only in Vim version 7.3 or later +Auto-compress links that is compiled with the conceal feature. +,la Perma-compress will keep the link com- +Do not compress links pressed using Vim's conceal feature unless +,lx you are Insert mode. (You can always edit + a link directly in Insert mode as well as + using the 'Add/edit link' function.) + Auto-compress keeps link ends concealed + in Normal mode except it automatically expands + all links on the same line as the cursor. + 'Do not compress' option sets things to always + show the entire link text (and is the only + option that works in Vim versions prior to 7.3). + +------------------------------------------------------------------------ +NARROWING REGIONS *vimorg-narrowing* + +VimOrganizer uses Christian Brabandt's NrwRgn plugin to edit subsections +of an outline in separate window. For outline sections this function is +sometimes called "hoisting". There are two different kinds of narrowing: (1) +narrowing of a subtree, and (2) narrowing of a code block. + +Narrow heading tree ,na is the keysequence to narrow a region. +,na If within a code block then the code block + -- or -- will be chosen as the region to be narrowed. +Narrow code block If not in a code block, then the current +,na heading will be used to determine the + narrowed region, with the heading and its + entire subtree opened in the new window. + If region is a code block, in most cases + the language of the code block will be recognized + and the new window will treat it as the + appropriate filetype, with correct syntax + highlighting and indenting. + +When editing a narrowed region in a separate window, the main buffer will +be uneditable and the region that was narrowed will be highlighted within it. +The narrowed region in the separate window is in a buffer that is different +from the buffer from the main document, so changes made in it are not +immediately reflected in the original buffer. To save changes use the *write* +command, *wq* to write and quit, or just *q* to abandon unsaved changes and +return to original buffer. See help for |NarrowRegion| for more information. + + +------------------------------------------------------------------------ +TABLES IN VIMORGANIZER *vimorg-tables-editing* + +Tables in VimOrganizer work very much like they work in Org-mode. +VimOrganizer uses some of the table code from the excellent VimWiki project. +Other major parts of the table functionality come from calling directly +to Org-mode in Emacs to evaluate or manipulate a table. + +Regardless of the editing functionality available in VimOrganizer, +the behavior of tables in export will be identical to what it is +in Org-mode, since exports are in fact done by Org-mode. + +Table operations are accessed through the Table Dashboard. You can open +the dashboard with the command :OrgTableDashboard or the key sequence +,b. The table dashboard is context-sensitive. Operations accessible +on the table dashboard are as follows: + +1. When cursor is on a blank line You are prompted to create + a new table, which you can do + by specifying rows and columns. + +2. When cursor is on non-table text You will be prompted to create a + table from the block of text you + are on. The block is defined as + the area between the previous + blank line and the next blank + line. This operation calls out + to Org-mode and processes the + text block with the elisp + function 'org-convert-table-region'. + The text will be split into a + table based on the following rules: + + a. If every line contains at least + one TAB character, the function + assumes that the material is tab + separated. + b. If every line contains a comma, + comma-separated values (CSV) are + assumed. + c. If neither of above apply, lines + are split at whitespace into fields. + +3. When cursor is on a table. In this case a full dashboard is shown. + All user options call out to Org-mode + in Emacs to process the table. This is + done even for relatively simple options, + since the #+TBLFM line may change. See + Org-mode documenation regading these + options and how tables and spreadsheet + functionality works: + http://orgmode.org/manual/Tables.html#Tables + + Dashboard operations: All of these operations depend on the + position of the cusor within the table. + + 'COLUMN' operatons: l -- move column left + r -- move column right + e -- delete column + o -- insert column + + 'ROW' operations d -- move row down + u -- move row up + x -- delete row + i -- insert row + + Insert horiontal line h -- insert a line below cursor + + 'RowSort' operations: All of the row sort operations operate + on the current 'row-region' of the table. + A row region is the range of rows + including the cursor row up to (1) + beginning-of-table or a horizontal line + above, and down to (2) the end-of-table + or a horizontal line below. + + Available sorts are + a -- alphabetical, a to z + A -- reverse alphabetical, z-a + n -- numeric, low to high + N -- numeric, high to low + +------------------------------------------------------------------------ +TABLE EVALUATION *vimorg-table-evaluation* + +Spreadsheet functionality is supported by calling out to Org-mode +in Emacs. You cause this by putting the cursor in a table and +choosing '(T)able, E(v)aluate Table' from the menu in gvim, or +by pressing |,v|. Evaluation will do two things: + + (1) If cursor is in a table cell with a valid row/col + formula, it will be moved into the #+TBLFM string. + (2) Formulas defined in the TBLFM string will be + evaluated and results will be placed in appropriate + cells in the table. + +Since the table is evaluated in Emacs, all of the spreadsheet +formulas are evaluated as specified in the Org-mode manual: +http://orgmode.org/manual/The-spreadsheet.html#The-spreadsheet + +NOTE: Be sure to note that the default evaluation does _NOT_ + follow the rule of equal precedence of multiplication + and division. Instead, division has lower precedence + than multiplication: + + 2/3*4 == 2 / (3 * 4) + + See: http://orgmode.org/manual/Formula-syntax-for-Calc.html#Formula-syntax-for-Calc + +------------------------------------------------------------------------ +CLOCKING *vimorg-clocking* + +Clocking means to record the amount time you spend on tasks. + +,ci Clock in *vimorg-clock-in* + +When you start work on an item, position the cursor on its headline and +press ,ci. A property :CLOCK: with the current timestamp is added, to +record the start time and to mark it as "open". + +,co Clock out *vimorg-clock-out* + +When you stop working on the current task, press ,co. You don't have to +be positioned on the item. The currently open task will be searched in +the current file or in all Agenda files (see |vimorg-agenda-files|). The +end time will be recorded. The start time, end time and duration will be +recorded in a :LOGBOOK: drawer like this: + + :LOGBOOK: + :CLOCK: [2010-07-11 Sun 20:30]--[2010-07-11 Sun 22:26] -> 1:56 + :END: + +You can clock the same task multiple times and multiple :CLOCK: lines +will accumulate in the logbook. + + +======================================================================== +COLORS AND HIGHLIGHTING IN VIMORGANIZER *vimorg-colors* + *vimorg-colorschemes* + *vimorg-highlighting* + +VimOrganizer works well with many different Vim colorschemes. It will +automatically adjust highlighting for major items when a new +colorscheme is loaded. Colors for heading lines are mapped to +the colors a colorscheme sets for the following syntax items: +> + Outline Level 1 - Statement + Outline Level 2 - Identifier + Outline Level 3 - Constant + Outline Level 4 - Comment + Outline Level 5 - Special + +Many elements in VimOrganizer documents have highlighting that is not +affected by generic colorschemes. These include items like TODO +keywords, tags, properties, configuration lines, etc. +------------------------------------------------------------------- + *vimorg-customizing-colors* +The main way to change highlighting is to add a special function to your +vimrc. This function is called when a VimOrganizer file is loaded +and whenever a colorscheme is changed. It provides a spot to write +your own highlight statements (see |highlight| ) to override the +default settings. +> + function! OrgCustomColors() + " various Org syntax item highlighting statements below + " are the current defaults. Uncomment and edit a line if you + " want different highlighting for the element. + + " Below are defaults for any TODOS you define. TODOS that + " come before the | in a definition will use 'NOTDONETODO' + " and those that come after are DONETODO + "hi! DONETODO guifg=green ctermfg=green + "hi! NOTDONETODO guifg=red ctermfg=lightred + + " Heading level highlighting is done in pairs, one for the + " heading when unfolded and one for folded. Default is to make + " them the same except for the folded version being bold: + " assign OL1 pair for level 1, OL2 pair for level 2, etc. + "hi! OL1 guifg=somecolor guibg=somecolor + "hi! OL1Folded guifg=somecolor guibg=somecolor gui=bold + + + " Tags are lines below headings that have :colon:separated:tags: + "hi! Org_Tag guifg=lightgreen ctermfg=blue + + " Lines that begin with '#+' in column 0 are config lines + "hi! Org_Config_Line guifg=darkgray ctermfg=magenta + + " Drawers are :PROPERTIES: and :LOGBOOK: lines and their associated + " :END: lines + "hi! Org_Drawer guifg=pink ctermfg=magenta + "hi! Org_Drawer_Folded guifg=pink ctermfg=magenta gui=bold cterm=bold + + " This applies to value names in :PROPERTIES: blocks + "hi! Org_Property_Value guifg=pink ctermfg=magenta + + " Three lines below apply to different kinds of blocks + "hi! Org_Block guifg=#555555 ctermfg=magenta + "hi! Org_Src_Block guifg=#555555 ctermfg=magenta + "hi! Org_Table guifg=#888888 guibg=#333333 ctermfg=magenta + + " Dates are date specs between angle brackets (<>) or square brackets ([]) + "hi! Org_Date guifg=magenta ctermfg=magenta gui=underline cterm=underline + + " Org_Star is used to "hide" initial asterisks in a heading + "hi! Org_Star guifg=#444444 ctermfg=darkgray + + "hi! Props guifg=#ffa0a0 ctermfg=gray + + " Bold, italics, underline, and code are highlights applied + " to character formatting + "hi! Org_Code guifg=darkgray gui=bold ctermfg=14 + "hi! Org_Itals gui=italic guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Bold gui=bold guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Underline gui=underline guifg=#aaaaaa ctermfg=lightgray + "hi! Org_Lnumber guifg=#999999 ctermfg=gray + + " These lines apply to links: [[link]], and [[link][link desc]] + "if has("conceal") + " hi! default linkends guifg=blue ctermfg=blue + "endif + "hi! Org_Full_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + "hi! Org_Half_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + + " Applies to the Heading line that can be displayed in column view + "highlight OrgColumnHeadings guibg=#444444 guifg=#aaaaaa gui=underline + + endfunction +---------------------------------------------------------------------- +CUSTOM TODO HIGHLIGHTING *vimorg-custom-todo-highlights* + +VimOrganizer will automatically highlight DONETODOs and NOTDONETODOs with +a default color, or color you assign in OrgCustomColors(). If you +want to assign custom highlighting for one or more TODOs then +you need to create a dictionary with appropriate values. +Below is an illustration: + + + Problem: You want to create custom highlights for the NEXT + and WAITING todos in the todo setup of: > + 'TODO NEXT WAITING | DONE CANCELED' +< + Solution: put statement like the one below in OrgCustomColors() + function in your vimrc, (or somewhere in vimrc below + the OrgCustomColors() func, if any): +> + let g:org_todo_custom_highlights = + \ { 'NEXT': { 'guifg':'#888888', 'guibg':'#222222', + \ 'ctermfg':'gray', 'ctermbg':'darkgray'} + \ 'WAITING': { 'guifg':'red', + \ 'ctermfg':'red' } } + + NOTE: (1) Vim has specific punctuation in its dictionary assignments. + Each of the keys in the statement above is a string, + and keys are separated from their values by a colon. + (2) You can override one or more of the highlight items: + guifg, guibg, ctermfg, ctermbg + +======================================================================== +SEARCHES AND THE AGENDA *vimorg-agenda* *vimorg-searches* + +The agenda is a buffer where VimOrganizer gathers heading lines from +one or more buffers in response to various kinds of searches. The content +of the agenda doesn't just show you the results of your search, it also +gives you the means to quickly view or jump to any of the "found" headings, +as well as providing a means to remotely edit them, i.e., effect changes in +the original buffer by making changes in the agenda. + +Here is how the Org-mode manual introduces the agenda: +----------------------------------------- +"Due to the way Org works, TODO items, time-stamped items, +and tagged headlines can be scattered throughout a file or +even a number of files. To get an overview of open action +items, or of events that are important for a particular +date, this information must be collected, sorted and +displayed in an organized way." + +"Org can select items based on various criteria and display +them in a separate buffer. Seven different view types +are provided:" + + "- an agenda that is like a calendar and shows + information for specific dates, + - a TODO list that covers all unfinished action items, + - a match view, showings headlines based on the tags, + properties, and TODO state associated with them, + - a timeline view that shows all events in a single + Org file, in time-sorted view, + [. . .] + - custom views that are special searches and + combinations of different views." +from http://orgmode.org/manual/Agenda-Views.html#Agenda-Views +------------------------------------------ + +VimOrganizer currently supports versions of the +above-mentioned agenda views, doesn't yet support the +'text search view' or the 'stuck projects view'. + +--------------------------------------------------------------------------- +AGENDA FILES *vimorg-agenda-files* + +When VimOrganizer runs a search to generate an agenda view, it searches +files that are included in the 'agenda files' list. If a file in agenda +files list has not yet been loaded, it will be loaded as part of the +search. + +The variable, g:agenda_files holds the list of agenda files. +You can enter values for g:agenda_files in your vimrc, e.g., +> + :let g:agenda_files = ['c:/path/myfile1.org','c:/path/myfile2.org'] + +There is a bare-bones agenda-editing mechanism that works like this: + + (1) Put your .org working directories in list g:agenda_dirs. Mine is in my + vimrc and includes a single directory: +> + :let g:agenda_dirs=["c:/users/herbert/documents/org-files"] + + (2) Then to edit your agenda files issue this command +> + :EditAgendaFiles +< + This will open a new tab and show your current agenda files along with a list + of all org files in your agenda dirs. Simply copy or move files from the + agenda dirs list to the top and when done press :W (that's a capital 'W'). + +You can also use Vimscript to add files to g:agenda_files. For +example, putting something like the following lines in your vimrc would +always fill g:agenda_files upon startup: +> + let g:org_agenda_files = split(glob("~/documents/org_files/*.org"),"\n") + +HINT: use the '+=' operator if you want to append these entries to those +already in g:org_agenda_files. E.g., +> + let g:org_agenda_files += split(glob("~/documents/org_files/*.org"),"\n") + +The 'agenda files dashboard' includes more commands that let you add, +remove, or rearrange files in the list of agenda files. You can bring +up this dashboard with the ',af' keymap, which will present these options: + + e Edit agenda files + t Current file to top of agenda file list + b Current file to bottom of agenda file list + r Remove Current file from agenda file list + +The 'agenda files dashboard' also has commands that let you navigate +among org buffers, see: |vimorg-files-navigating| +---------------------------------------------------------------------- +THE AGENDA DASHBOARD *vimorg-agenda-dashboard* + +The agenda_dashboard provides a user-interface for issuing different +kinds of agenda searches. Below is a list of the different commands +you can issue from the dashboard: + + a This will search agenda files for headings with dates + that fall in the current week. The resulting agenda allows + you to issue more commands to change the view: + + vd, vw, vm, vy -- Sets view period. The 'a' + command always starts with + a week view, but you can change + it to show single day (vd), + single month (vm), or year (vy). + []f, []b -- forward and backward to next + or previous view period. Optional + number prefix to specify number + of periods to jump. E.g., issuing + 3f when view is a month view + of August 2011 would jump forward + three months and show month view + of November 2011. + + t Assembles a list of headings marked as todo items. Top line + of agenda provides menu that allows you to press a number + to rerun the search limiting results to certain todo items. + UNFINISHED_TODOS will match whichever tags are before the '|' + in a buffer's todo spec, so may match multiple TODO items. + Likewise, FINISHED_TODOS will match whichever todos occur + _after_ the '|' in a buffer's todo setup. + + m Tags/TODO/Property match. Prompts you for a search + specification in command line and retrieves headings + with matching metadata. See |vimorg-tags-search| . + + c Show the 'custom searches' menu. + See |vimorg-agenda-custom-searches| + +-------------------------------------------------------------------- +AGENDA WINDOW POSITION *vimorg-agenda-window-position* + +Location of the agenda window can be controlled by setting the +g:org_agenda_window_position variable. Possible values are +'top', 'bottom', 'left', 'right'. The default position is +'bottom'. +------------------------------------------------------------------- +INCLUDING CLOCKTABLE IN AGENDA *vimorg-agenda-include-clocktable* + +You can have a clocktable included in agendas by setting the +variable below to 1 (default is 0). When set, agenda searches +that are of 'agenda' type (i.e., not just todo/tags/properties) +will include a clocktable after the regular view. The clocktable +will be for a period equal to the period of time shown +in the agenda view: +> + Include clocktable: g:org_agenda_include_clocktable = 1 + Don't include: g:org_agenda_include_clocktable = 0 + +-------------------------------------------------------------------- +KEYMAPPINGS IN THE AGENDA *vimorg-agenda-keys* + +Some keys have special operation in the Agenda: + + - pressing on a heading in agenda + will (1) switch (if necessary) to show + the chosen heading's buffer in window + above the agenda, (2) fully fold the + heading's entire buffer, and (3) position + buffer at heading and unfold the chosen + heading. The cursor remains in the agenda + but you can see the synched heading in + window above. + - Will stay in the Agenda's window and + switch to the chosen heading's buffer + with cursor positioned at heading. + - will toggle heading's text in its + original buffer (different from previous + versions where would toggle text + into the agenda buffer itself. . .) + - Will cycle through the heading's todo + items, simultaneously also changing the + heading in its original buffer. The + cycling is smart enough to use the todo + setup of each original buffer, so + different headings in agenda may cycle + different todo items. + q - close agenda window + r - rerun the search, in case you have + changed data and want to get new + view. Will use dates and view of the + results currently showing in the fifth + line of the agenda, including a filter + specification, which may be changed + before refreshing. For example, to + refresh agenda to show only unfinished + todo items, change text after 'FILTER:' + to be +UNFINISHED_TODOS. + ,d Invokes the date dashboard, allowing you + to remotely edit or add to the heading's dates + in the original buffer. +--------------------------------------------------------------- +TAGS-TODO-PROPERTY SEARCH *vimorg-tags-search* + + You can enter a tags/todo search that will search + various various parts of each heading's metadata + and return the results in the agenda. + Here are some examples that + illustrate the syntax: +> + Enter search string: +work + selects headlines tagged ':work:' +> + Enter search string: +work-boss +< selects headlines tagged ':work:', but + excludes those also tagged ':boss:'. +> + Enter search string: +work|+boss (or just work|boss) +< selects headlines tagged ':work:' or ':boss:' +> + Enter search string: +work|+laptop+night +< selects headlines tagged ':work:' or + both ':laptop:' and ':night:' + + The examples above are search tags, but you can include + searches for todo items in the same way: +> + Enter search string: +work+TODO +< selects headlines tagged ':work:' that + are marked with 'TODO' status. + (e.g., * TODO My work item + :work: ) +> + Enter search string: +work+DONE +< selects headlines tagged ':work:' that + are marked with 'DONE' status. + (e.g., * DONE My work item + :work: ) + + Instead of a tag, you may also specify a regular expression enclosed + in curly braces. For example: +> + Enter search string: +work+{boss.*} +< selects headlines that contain the tag ':work:' + and any tag starting with ‘:boss’. (Note: unlike + the similar search in Org-mode, there should be + _no_ initial '^'.) + + You may also search for properties at the search string. Properties + may be ones you have entered yourself ( see |vimorg-properties| ) or + one of a set of special properties that all headings have. E.g., + 'LEVEL' is a built-in property that indicates the outline level of a + heading, so you could do this: +> + Enter search string: +work+LEVEL=2 +< selects headlines at level 2 that are + also tagged ':work:' + + Here is an example of a complex search string, which assumes + the user has entered a 'WITH' property and an 'EFFORT' + property for some headings: +> + +work-boss+EFFORT<2+WITH={Sarah\|George}+DEADLINE>="2011-11-13" +< + The type of comparison done depends on how the comparison value is written: + + - If the comparison value is a plain number, a numerical comparison is + done, and the allowed operators are ‘<’, ‘=’, ‘>’, ‘<=’, ‘>=’, and + ‘!=’. + - If the comparison value is enclosed in double-quotes, a string + comparison is done, and the same operators are allowed. + - If the comparison value is enclosed in double-quotes and angular + brackets (like ‘DEADLINE<="<2008-12-24 18:30>"’), both values are + assumed to be date/time specifications in the standard way, + and the comparison will be done accordingly. + - If the comparison value is enclosed in curly braces, a regexp match + is performed, with ‘=’ meaning that the regexp matches the property + value, and ‘!=’ meaning that it does not match. + +--------------------------------------------------------------- +CUSTOM SEARCHES *vimorg-agenda-custom-searches* + +Any number of custom searches can be defined and accessed from the +'custom searches' menu, which can be accessed from the agenda +dashboard, from the Org menu in gvim, or directly via the ,ac +keymapping. + +Custom searches are stored in a list variable: + 'g:org_custom_searches'. You create new custom searches +by adding them to that list. Here is an example an assigment +that could be put in your vimrc to define a number of custom +searches, which I will explain below: + > + let g:org_custom_searches = [ + \ { 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w', 'agenda_duration':'w' } + \ ,{ 'name':"Next week's TODOS", 'type':'agenda', + \ 'agenda_date':'+1w', 'agenda_duration':'w', + \ 'spec':'+UNFINISHED_TODOS' } + \ ,{ 'name':'Home tags', 'type':'tags', 'spec':'+HOME' } + \ ,{ 'name':'Home tags', 'type':'sparse_tree', 'spec':'+HOME' } + \ ,[ { 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w', 'agenda_duration':'w' } + \ ,{ 'name':'Home tags', 'type':'tags', 'spec':'+HOME' } + \ ] + \ ] +< +The assignment above creates five different custom searches. +Basic searches are dictionaries containing key/value items that +specify the search. Each search must be given a name and a type. + +AGENDA-TYPE CUSTOM SEARCHES *vimorg-custom-agenda* +---------------------------- +The first two searches are 'agenda' type searches, which means their +results are shown in the agenda organized by date with same +functionality as the usual agenda view. You have to assign a +name and specify their 'type' as 'agenda'; their other values +described below ('agenda-date', 'agenda-duration', and 'spec') +are optional. + +The 'agenda-date' value defines the starting date. This date may be +specified explicitly, (e.g., '2012-01-13') or you can use any cue +that works on the date-time prompt command line (e.g., '+1w' for +starting date of 1 week from today, '+36d', '-1y', '+24m', etc. +-- most of the cues here are supported: +http://orgmode.org/manual/The-date_002ftime-prompt.html#The-date_002ftime-prompt + +The agenda-duration value defaults to a week ('w') if not specified, +but you can otherwise assign a number to represent the number of days +that should be displayed in the agenda view. + +The 'spec' in an agenda-type search allows you to specify additonal +restrictions on headings that will be included in the agenda view. +This 'spec' works identically to the specification for ad-hoc +searches that you can enter from the agenda-dashboard, see: +|vimorg-tags-search|. + +TAGS-TYPE CUSTOM SEARCHES *vimorg-custom-tags* +------------------------- +These searches are like the 'TAGS/PROPS/TODO' queries that you can +specify on the fly from the agenda dashboard. You have to +specify a name, the 'type' of 'tags', and then the 'spec' for the +search. 'Spec' works just as described here: +|vimorg-tags-search|. + +SPARSETREE TYPE CUSTOM SEARCHES *vimorg-custom-sparse_tree* +-------------------------------- +The fourth search in the above assignment to g:org_custom_searches is +has the 'name' of 'Home tags' and is a search of 'type' 'sparse_tree'. +This search is a pre-defined version of a search that can be run as a +'Freeform . . . sparse tree search' from the agenda dashboard. 'Spec' +works the same as it does for other searches. + +BLOCK SEARCHES *vimorg-agenda-block-search* +-------------- +The first four searches assigned to g:org_custom_searches, above, are +"simple" searches, in that they pre-define searches that correspond to +one of the agenda views accessible from the agenda dashboard. +Pre-defined block searches allow you to include the results of two or +more "simple" searches in a single agenda view. These searches are +defined by adding a list item in square brackes '[]' to +g:org_custom_searches, which contains two or more dictionaries +specifying agenda-type or tags-type simple searches. + +============================================================================== +NAVIGATING AMONG ORG FILES *vimorg-files-navigating* + +VimOrganizer provides several ways of moving directly between org files, +which are often preferable to using built-in Vim commands. This is +largely because VimOrganizer works best when all org files are open +on separate tabs (see Note 2 below). Most of these +VimOrganizer commands work between files included in the list of 'agenda +files'. The commands are listed on the 'agenda files' dashboard: + + Key mapping Operation + ,af Show 'agenda files' dashboard + + Here is the 'agenda files' dashboard: +> + Press key for an agenda files command: + -------------------------------------- + e Edit agenda files + t Current file to top of agenda file list + b Current file to bottom of agenda file list + r Remove Current file from agenda file list + n or f Cycle to next file in agenda files + p or b Cycle to previous file in agenda files + c or g Choose agenda file or org file to goto + +Note 1: The 'c or g' choice above provides a list of open org buffers; it is +_not_ limited to the list of agenda files. + +Note 2: You can of course use any means Vim provides to navigate among +Org buffers. Because of the way VimOrganizer works, however, you may want +to keep org files open on different tabs rather than switching to different +buffers within the current window. VimOrganizer depends on folding that +must be recalculated whenever a buffer is loaded into a window. For large +files these recalculations can take several seconds, thus making quick +navigation between buffers in the same window impossible. This problem +is avoided if you keep org files open on different tabs, where switching +between them is instantaneous. Many Vim plugins are available to +make file/buffer navigation faster and easier (e.g., Fuzzy Finder, +BufExplorer, etc.). If you use a plugin you will probably want to configure it +so that the default method of switching to a buffer is to move to a tab +with the desired buffer (rather than moving to new buffer while staying +in current window). + +============================================================================== +COLUMN VIEW *vimorg-column-view* + +Column view in VimOrganizer is similar to the feature having the same name +in Org-mode, but different in important ways. At its core it simply offers +a way to reveal data about a heading when it is displayed as a fold. +Folded heading lines in Vim are not directly editable. (A user interface +to allow easy editing of columns/properties is on VimOrganizer's todo list.) + +The default display in VimOrganizer (i.e., colmns off) merely shows the +number of lines in a fold along the right margin. Column view can be turned +on or off in each buffer, but to make each buffer default to on you can place +this line in your vimrc: +> + let g:global_column_view = 1 + +Specification of COLUMNS is similar to Org-mode, except that ITEM is +always included, although length settings for ITEM are always ignored. +This is because the ITEM display is automatically truncated to make +space for the other columns, and ITEM will automatically expand or +contract if you resize the Vim window. The column definition string +format is identical to that used by Org-mode, although the optional +'summary-type' attribute is currently ignored in VimOrganizer. See: +http://orgmode.org/manual/Defining-columns.html#Defining-columns + +The built-in global default for column view is to show any TAGS flush +left in a 35 character column. You can modify that be setting a global +default in your vimrc. The built-in default would look like this: +> + let g:global_column_defaults = '%ITEM %35TAGS' + +A default that would show the DEADLINE value in addition to TAGS might +look like this: +> + let g:global_column_defaults = '%ITEM %15DEADLINE %30TAGS' + +-------------------------------------------------------------------------- +COLUMNS DASHBOARD *vimorg-columns-dashboard* + +You can access the column dashboard by pressing ,m or by entering the command +:OrgColumns. The dashboard shows you the current relevant settings and +allows you to change them: + + buffer default columns -- These defaults are taken either + from the global defaults, or from the + settings in a columns configuration + line in a document. + current default columns -- The current settings, which may reflect + custom default settings + column view on -- Will be ON/OFF + Show column headers -- Will be ON/OFF + heading line count -- Will be ON/OFF, refers to whether the + count of heading lines shows at right + margin for a folded heading. Can be + ON even if column view is OFF. +> + Operations on Columns dashboard + ----------------------- + f -- Force all of buffer to use settings. If + not chosen then (1) only the current subtree will be + placed into column, or (2) entire buffer + will be in column view if cursor is in + front of the first heading in the document. + r -- Revert to buffer defaults, if defaults have + been changed + t -- Toggle column view ON/OFF + h -- Toggle column headings ON/OFF + l -- Toggle line count ON/OFF +< + *org_columns_custom_list* + Custom column options will then be listed. If no custom options have + been assigned in the vimrc, then built-in behavior is to have two + options as if the user had the line below in their vimrc. This line + defines a list of two custom column strings, one having a + DEADLINE and a TAGS column, the second having just a DEADLINE column: +> + let *g:org_custom_column_options* = ['%ITEM %14DEADLINE %30TAGS', + \ '%ITEM %14DEADLINE'] +< + g:org_custom_column_options is a list containing column format + strings. Each format string will be listed on the dashboard + with a number in front of it, and can be accessed by pressing + the key for that number (0-9). The format strings are constructed of + pairs of 'metadata field,format for field' with additional pairs + also separated by commas. The format options used are the same as those + of the |printf| function, which is used to format the columns internally. +-------------------------------------------------------------------------- +COLUMNS CONFIG LINE *vimorg-columns-config-line* + + Any document may have a line that sets the default column settings + for the document. This will override any global default that has been + set. The format allows for a single string, with settings like + those described above for g:org_custom_column_options. An example + COLUMNS config would look like this. Note that the '#' must be in the + leftmost column of the text: +> + #+COLUMNS: DEADLINE,%-14s,TAGS,%-30s + +--------------------------------------------------------------------- +COLUMNS PROPERTY *vimorg-columns-property* + +Columns properties work like how they work in Org-mode. You can set +a COLUMNS property in the property block of a heading. That setting +will (1) override any default or custom settings for the buffer (unless +you enter a buffer-wide columns mode with cursor not on the heading), and +(2) be inherited by subheadings of of that heading. (Also, you +can force entire buffer to use a headings COLUMNS property by +choosing 'f' on columns dashboard.) For example, entering columns +mode withe the cursor on 'Heading One' below below would display +folded lines with just a DEADLINE column, regardless of what the +settings were in the rest of the document: +> + * Heading One + :PROPERTIES: + :COLUMNS: %ITEM %14DEADLINE + :END: + ** Subhead One + Text for Subhead One + ** Subhead Two + Some text for Subhead Two + +============================================================================== +VIMORGANIZER EXPORT *vimorg-export* + *vimorg-print* + *vimorg-export-to-html* + *vimorg-export-to-pdf* + +VimOrganizer calls out to Org-mode in Emacs for all exports. To print +a VimOrganizer file the recommended method is to export to a format that +is better for printing. + +The Export Dashboard can be opened from the menu in gvim ('Export/Publish') +or with the key mapping |,x| . +The VimOrganizer Export Dashboard is similar to Org-mode's export +dispatcher, and the best way to learn about it is to read the Org-mode +documentation: +http://orgmode.org/manual/Exporting.html#Exporting + + *vimorg-export-microsoft-word* + *vimorg-export-opendocument* + *vimorg-export-openoffice* + *vimorg-export-docx* +The Export Dashboard includes an option for export to OpenDocument +format. This option creates an odt document that can then be +edited by (recent version) of Microsoft Word or OpenOffice. +Once into Word, OpenOffice, or LibreOffice the document can +be saved as a .doc or .docx file. +Export of items into odt supports objects like images, tables, +and footnotes in addition to highlighting and other simple formatting. +The odt export currently (November 2011) requires special configuration +of your Emacs install. Instructions are here: +http://orgmode.org/manual/OpenDocumentText-export.html#OpenDocumentText-export + + *vimorg-publishing* +As in Org-mode, VimOrganizer's Export Dashboard also includes +options for "publishing" a project. A "project" is a set of +related documents that you set up to be automatically exported +together, which is called "publishing" the project. The +publishing options on the VimOrganizer's Export Dashboard +simply call Emacs to process files so the Org-mode documentation for +publishing is best way to learn about them. Setting up a project +requires some fairly simple configuration using lisp statements +added to the .emacs file, which is Emacs' counterpart to Vim's vimrc: +http://orgmode.org/manual/Publishing.html#Publishing + + *vimorg-tangling* + *vimorg-literate-programming* +Another option on the Export Dashboard is 'tangle'. This operation +extracts source code blocks from an org document and saves them so +they're in a format that can be (1) executed by an interpreter or +(2) compiled, depending on the source block language. This provides +a way to use VimOrganizer as an editor for 'literate programming'. +See: http://en.wikipedia.org/wiki/Literate_programming +Documentation for tangling can be found in Org-mode's manual: +http://orgmode.org/manual/Extracting-source-code.html#Extracting-source-code + + *vimorg-export-options* +Finally, one option on the Export Dashboard simply inserts a template +of option lines into your document. This template can be inserted anywhere +in your document, but is typically placed at the very beginning. It +provides a default set of export-related options that you can modify +as you wish. For more information on all the options see this page: +http://orgmode.org/manual/Export-options.html#Export-options + + +============================================================================== +VIMORGANIZER FEEDBACK *vimorg-feedback* + +Feedback is always welcome. If you like the plugin, please rate it at the +vim-page: +http://www.vim.org/scripts/script.php?script_id=3075 + +You can also follow the development of the plugin at github: +http://github.com/hsitz/VimOrganizer + +Please don't hesitate to report any bugs to the maintainer, mentioned in the +third line of this document. + +============================================================================== +Modeline: +vim:tw=78:ts=8:ft=help:nowrap:et diff --git a/bundle/org-mode/ftplugin/org.vim b/bundle/org-mode/ftplugin/org.vim new file mode 100644 index 000000000..c94438c4b --- /dev/null +++ b/bundle/org-mode/ftplugin/org.vim @@ -0,0 +1,8150 @@ +scriptencoding utf-8 + +set foldmethod=manual + +call org#buffer#init() +call org#windows#init() + +set noswapfile + +setlocal ignorecase " searches ignore case +setlocal smartcase " searches use smart case +setlocal autoindent +setlocal fileformat=unix +setlocal backspace=2 +setlocal nowrap +setlocal tw=78 +setlocal expandtab +setlocal nosmarttab +setlocal softtabstop=0 +setlocal foldcolumn=1 +setlocal tabstop=4 +setlocal shiftwidth=4 +setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^\\s*\\-\\s\\+ +setlocal indentexpr= +setlocal foldexpr=org#fold#level(v:lnum) +"setlocal iskeyword+=< +setlocal nocindent +setlocal iskeyword=@,39,45,48-57,_,129-255 + + +" LINE BELOW IS MAJOR IF THAT ENCOMPASSES MOST OF org.vim +" endif is near bottom of document +" everything in between is executed only the first time an +" org file is opened +if !exists('g:org_loaded') +" Load the checkbox plugin +execute 'runtime ftplugins/vo_checkbox.vim' + +" set calfunc depending on which calendar version installed +if exists(':Calendar')==2 + if exists('*Calendar')>0 + let s:Calfunc=function('Calendar') + else " we have to assume it's more recent version + let s:Calfunc=function('calendar#show') + endif + if !exists('g:calendar_navi') + let g:calendar_navi='' + endif +endif + +function! s:SID() + return matchstr(expand(''), '\zs\d\+\ze_SID$') +endfun +let g:org_sid = s:SID() +let sid='' . g:org_sid . '_' +function! OrgSID(func) + execute 'call '.s:SID().'_'.a:func +endfunction + +if has('win32') || has('win64') + let s:cmd_line_quote_fix = '^' +else + let s:cmd_line_quote_fix = '' +endif +let g:org_filename_wildcards = ['*.org'] +let s:sfile = expand(":p:h") +let s:last_refile_point = [] +let g:org_todos_done_dict = {} +let g:org_todos_notdone_dict = {} +let g:org_agenda_todos_done_pattern = '' +let g:org_agenda_todos_notdone_pattern = '' +let g:org_clock_history=[] +let g:org_reverse_note_order = 0 +let g:org_html_app='' +let g:org_pdf_app='' +let s:org_headMatch = '^\*\+\s' +let s:org_cal_date = '2000-01-01' +let g:org_export_babel_evaluate = 1 +let g:org_tag_group_arrange = 0 +let g:org_first_sparse=1 +let g:org_clocks_in_agenda = 0 +let s:remstring = '^\s*:\S' +let s:block_line = '^\s*\(:\|DEADLINE\|SCHEDULED\|CLOSED\|<\d\d\d\d-\|[\d\d\d\d-\)' +"let s:remstring = '^\s*\(:\|DEADLINE:\|SCHEDULED:\|CLOSED:\|<\d\d\d\d-\)' +let g:org_use_calendar = 1 +let g:org_todoitems=[] +let s:headline = '' +let g:org_ColumnHead = 'Lines' +let g:org_gray_agenda = 0 +let g:org_sparse_lines_after = 10 +let g:org_log_todos=0 +let g:org_timegrid=[8,20,2] +let w:v.org_colview_list = [] +let s:firsttext = '' +let g:org_supported_link_types = '\(http\|file\|mailto\)' +let g:org_unsupported_link_types = '\(vm\|wl\|mhe\|rmail\|gnus\|bbdb\|irc\|info\|shell\|elisp\)' + + +let w:v.org_item_len=100 +let w:sparse_on = 0 +let g:org_folds = 1 +let g:org_show_fold_lines = 1 +let g:org_columns_default_width = 15 +let s:org_columns_master_heading = 0 +let w:v.org_colview_list=[] +let g:org_show_fold_dots = 0 +let g:org_show_matches_folded=1 +let g:org_indent_from_head = 0 +let g:org_agenda_skip_gap = 2 +let g:org_agenda_days=7 +let g:org_agenda_minforskip = 8 + +let g:org_show_balloon_tips=1 +let g:org_datelist = [] +let g:org_search_spec = '' +let g:org_deadline_warning_days = 3 +let s:org_weekdays = ['mon','tue','wed','thu','fri','sat','sun'] +let s:org_weekdaystring = '\cmon\|tue\|wed\|thu\|fri\|sat\|sun' +let s:org_months = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'] +let s:org_monthstring = '\c\(jan\|feb\|mar\|apr\|may\|jun\|jul\|aug\|sep\|oct\|nov\|dec\)\S*' +let s:include_inherited_props=0 +let s:AgendaBufferName = "__Agenda__" +let s:sparse_lines = {} +let s:search_list = [] +let s:last_search_list = [] + +"testing stuff +function! CustomSearchesSetup() + let g:org_custom_searches = [ + \ { 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w','agenda_duration':'w'} + \ ,{ 'name':"Next week's TODOS", 'type':'agenda', + \ 'agenda_date':'+1w','agenda_duration':'w','spec':'+UNFINISHED_TODOS'} + \ , { 'name':'Home tags', 'type':'tags', 'spec':'+HOME'} + \ , { 'name':'Home tags', 'type':'sparse_tree', 'spec':'+HOME'} + \ , [ { 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w','agenda_duration':'w'} + \ ,{ 'name':'Home tags', 'type':'tags', 'spec':'+HOME'} + \ ] + \ , [ { 'name':'Home tags', 'type':'tags', 'spec':'+HOME'} + \ ,{ 'name':"Next week's agenda", 'type':'agenda', + \ 'agenda_date':'+1w','agenda_duration':'w'} + \ ] + \ ] +endfunction +function! s:RunCustom(search) + " search arg is either number of predefined custom search, + " or full spec for search from agenda dashboard + if type(a:search) == type(1) + let search_spec = g:org_custom_searches[a:search] + else + let search_spec = a:search + endif + + if !exists("g:agenda_files") || (g:agenda_files == []) + if has('dialog_con') || has('dialog_gui') + unsilent call confirm("No agenda files defined. Will add current file to agenda files.") + endif + call s:CurfileAgenda() + endif + + if type(search_spec) == type({}) + "single spec + let s:search_list = [ search_spec ] + else + " block agenda specs + let s:search_list = search_spec + endif + + let this_time_list = s:search_list + if this_time_list[0].type !~ 'sparse_tree' + let curfile = expand("%:p") + let curtab = tabpagenr() + let curwin = winnr() + :AAgenda + " delete redo block (always just one) if any + if get(this_time_list[0],'redo_num') > 0 + "redo_num is block in agenda to redo + let redo_num = s:AgendaBlockNum(this_time_list[0].redo_num) + normal gg + if redo_num > 1 + for i in range(1,redo_num - 1) + call search('^==============','','') + endfor + endif + let start_line = (line('.') == 1) ? 1 : line('.') + 1 + let test_end = search('^=========','W','') + let end_line = test_end > 0 ? test_end - 1 : line('$') + silent exec start_line . ',' . end_line . 'delete' + call append(start_line - 1,['','']) " append to agenda buf + let s:agenda_insert_point = start_line + elseif len(this_time_list) == 1 + silent exec '%d' + let s:agenda_insert_point = 1 + else + let s:agenda_insert_point = line('$') + endif + endif + + let i = 0 + for item in this_time_list + if i > 0 + call append(line('$'),['',repeat('=',70),'','']) " append to agenda buf + let s:agenda_insert_point = line('$') + endif + let mydict = item + if mydict.type ==? 'agenda' + let mydate = DateCueResult( get(mydict,'agenda_date',''), s:Today()) + let mydur = get(mydict, 'agenda_duration','w') + let mydur = (mydur == 'w') ? '7' : (mydur == 'd' ? '1' : mydur) + + call OrgRunAgenda( mydate, + \ get(mydict, 'agenda_duration', 'w'), + \ get(mydict, 'spec','') ) + let save_line = line('.') + let last_line = search('^============','W','') - 1 + exec (last_line <= 0) ? line('$') : last_line + if (g:org_agenda_include_clocktable == 1) + call append(line('.'),OrgGetClocktable(g:agenda_files,' :narrow 40! :tstart ' . '"<' . mydate . ' xxx 00:00>" :tend "<' . calutil#cal(calutil#jul(mydate) + mydur ) . ' xxx 00:00>" :link ')[3:-3]) + endif + exec save_line + elseif mydict.type ==? 'sparse_tree' + call OrgRunSearch( mydict.spec, 1 ) + elseif mydict.type ==? 'sparse_tree_regex' + silent call s:SparseTreeRun(mydict.spec) + elseif mydict.type ==? 'tags' + call OrgRunSearch( mydict.spec ) + elseif mydict.type ==? 'tags-todo' + " add todos to spec + call OrgRunSearch( mydict.spec,'agenda_todo' ) + endif + let i += 1 + endfor + set foldlevel=999 + execute s:agenda_insert_point + nohl +endfunction +"Section Tag and Todo Funcs +function! OrgProcessConfigLines() + let b:v.org_config_lines = [] + let b:v.todoitems = [] + silent g/^#+/call add( b:v.org_config_lines, getline(line('.')) ) + + " clear out for new tag settings + let b:v.tagdict = {} + let b:v.buf_tags_static_spec = '' + let b:v.tagchars='' + let b:v.tags_order = [] + if g:org_tags_alist ==# '' + let b:v.dynamic_tags=1 + else + let b:v.dynamic_tags=0 + endif + + for line in b:v.org_config_lines + if line =~ '^#+CATEGORY' + let b:v.buffer_category = matchstr( line ,'^#+CATEGORY:\s*\zs.*') + let b:v.org_inherited_defaults['CATEGORY'] = b:v.buffer_category + elseif line =~ '^#+COLUMNS' + let b:v.buffer_columns = matchstr( line ,'^#+COLUMNS:\s*\zs.*') + let b:v.org_inherited_defaults['COLUMNS'] = b:v.buffer_columns + "let w:v.org_current_columns = b:v.buffer_columns + elseif line =~ '#+STARTUP:' + let startup_list = split(matchstr( line, '#+STARTUP:\s*\zs.*') ) + for item in startup_list + silent! exec "let b:v." . item . "=1" + endfor + elseif line =~ '#+TAGS:' + let newtags = matchstr( line, '#+TAGS:\s*\zs.*') + if newtags ==# '' + let b:v.dynamic_tags = 1 + else + let b:v.buf_tags_static_spec .= newtags . ' \n ' + endif + elseif line =~ '\(#+TODO:\|#+SEQ_TODO:\)' + call OrgTodoSetup(matchstr(line,'\(#+TODO:\|#+SEQ_TODO:\)\s*\zs.*')) + elseif line =~ '#+PROPERTY:' + let m = matchlist(line,'.\{-}:\s*\(.\{-}\)_ALL \(.*\)') + if m[2] ># '' + let b:v.prop_all_dict[toupper(m[1])] = m[2] + endif + endif + endfor + if empty(b:v.todoitems) + call OrgTodoSetup(g:org_todo_setup) + endif + + call OrgTagSetup( b:v.buf_tags_static_spec ) + + " get rid of b:v.buffer_category (and columns also) and just use o_i_d var??? + if b:v.buffer_category ==# '' + let b:v.buffer_category = expand("%:t:r") + endif + + normal gg +endfunction +function! s:EditProp(property) + let s:edit_prop = toupper(a:property) + let propval = get(s:GetProperties(line('.'),0), s:edit_prop,'') + function! s:PropCompleteFunc(arghead, sd, gf) + let prop = matchstr(a:sd,'^.\{-}\ze:') + let valuelist = split(get(b:v.prop_all_dict, s:edit_prop, '')) + let matches = filter(valuelist, 'v:val =~ a:arghead') + return join(matches, "\n") + endfunction + let myfunc = '' . s:SID() . '_PropCompleteFunc' + let newval = input("Enter value for " . s:edit_prop . ": ", propval, 'custom,' . myfunc) + if newval != propval + call s:SetProp(s:edit_prop, newval) + echo s:edit_prop . " changed to: " newval + else + echo s:edit_prop . " not changed." + endif +endfunction +function! OrgTodoConvert(orgtodo) + let todolist = [] + let sublist = [] + let b:v.tododict = {} + " let templist = [] + let temp_list = split(a:orgtodo,'\s\+') + + for item in temp_list + if item == '|' + continue + endif + let b:v.tododict[item] = {} + if matchstr(item,'.*(.)') ==# '' + let b:v.tododict[item].todotext = item + let b:v.tododict[item].todochar = '' + else + let b:v.tododict[item].todotext = matchstr(item,'.*\ze(.)') + let b:v.tododict[item].todochar = matchstr(item,'.*(\zs.\ze)') + endif + endfor + " count '|' chars in list, if 0 or 1 then + " it is like Org-mode format, otherwise + " sublists are used in non-done slot" + let bar_count = count(split(a:orgtodo,'\zs'),'|') + let after_bar = 0 + if bar_count >= 2 + for item in temp_list + if item != '|' + call add(sublist,item) + elseif (item ==? '|') + call add(todolist,sublist) + let sublist = [] + endif + endfor + else + for item in temp_list + if (item != '|') && (after_bar == 1) + call add(sublist,item) + elseif (item != '|') && (after_bar == 0) + call add(todolist,item) + elseif (item ==? '|') + let sublist = [] + let after_bar = 1 + endif + endfor + endif + if sublist != [] + call add(todolist,sublist) + endif + return todolist +endfunction + +function! OrgTodoSetup(todolist_str) + let todolist = OrgTodoConvert(a:todolist_str) + let b:v.todo_setup = a:todolist_str + "set up list and patterns for use throughout + let b:v.todoitems=[] + let b:v.todo_first_letters = '' + "let b:v.fulltodos=todolist + let b:v.todocycle=[] + let b:v.todoMatch='' + let b:v.todoNotDoneMatch='' + let b:v.todoDoneMatch='' + let i = 0 + while i < len(todolist) + if type(todolist[i]) == type('abc') + let thistodo = matchstr(todolist[i],'.*ze(.)') + let thistodo = b:v.tododict[todolist[i]].todotext + let todolist[i] = substitute(todolist[i],'(.)','','') + call add(b:v.todoitems,thistodo) + call add(b:v.todocycle,thistodo) + " add to patterns + "let newtodo = b:v.todoitems[len(b:v.todoitems)-1] + let newtodo = thistodo + let b:v.todoMatch .= newtodo . '\|' + if i < len(todolist) - 1 + let b:v.todoNotDoneMatch .= newtodo . '\|' + let g:org_todos_notdone_dict[newtodo] = 1 + else + let b:v.todoDoneMatch .= newtodo . '\|' + let g:org_todos_done_dict[newtodo] = 1 + endif + else + "item is itself a list + let j = 0 + while j < len(todolist[i]) + let thisitem = b:v.tododict[todolist[i][j]].todotext + let todolist[i][j] = substitute(todolist[i][j],'(.)','','') + call add(b:v.todoitems,thisitem ) + if j == 0 + call add(b:v.todocycle,thisitem) + endif + " add to patterns + let b:v.todoMatch .= thisitem . '\|' + if i < len(todolist) - 1 + let b:v.todoNotDoneMatch .= thisitem . '\|' + let g:org_todos_notdone_dict[thisitem] = 1 + else + let b:v.todoDoneMatch .= thisitem . '\|' + let g:org_todos_done_dict[thisitem] = 1 + endif + let j += 1 + endwhile + endif + let i += 1 + endwhile + let b:v.todoMatch = '^\*\+\s*\zs\('.b:v.todoMatch[:-2] . ')' + let b:v.todoDoneMatch = '^\*\+\s*\zs\('.b:v.todoDoneMatch[:-2] . ')' + let b:v.todoNotDoneMatch = '^\*\+\s*\zs\('.b:v.todoNotDoneMatch[:-2] . ')' + let b:v.fulltodos = todolist + + syntax clear DONETODO + exec 'syntax match DONETODO /' . b:v.todoDoneMatch[1:] . '/ containedin=OL1,OL2,OL3,OL4,OL5,OL6' + syntax clear NOTDONETODO + exec 'syntax match NOTDONETODO /' . b:v.todoNotDoneMatch[1:] . '/ containedin=OL1,OL2,OL3,OL4,OL5,OL6' + + call s:OrgCustomTodoHighlights() + for item in keys( b:v.tododict ) + let item_char = tolower( b:v.tododict[item].todochar) + if item_char ==# '' + let item_char = tolower(item[0]) + endif + endfor + +endfunction +function! s:CurfileAgenda() + exec "let g:agenda_files=['".expand("%:p")."']" +endfunction + +function! OrgTagSetup(tagspec) + let b:v.tags = split(tr(a:tagspec,'{}',' '),'\s\+') + for item in b:v.tags + if item =~ '(' + let char = matchstr(item,'(\zs.\ze)') + let tag = matchstr(item,'.*\ze(') + else + "find an unused character + let char = '' + let tag = item + let i = 0 + while i < len(item) + "if !has_key(chardict, item[i]) + " find char that isn't in tagchars yet + if b:v.tagchars !~ item[i] + let char = item[i] + "let chardict[item[i]] = 1 + break + endif + let i += 1 + endwhile + if char ==# '' + for i in range(65,90) + if b:v.tagchars !~ nr2char(i) + let char = nr2char(i) + break + endif + endfor + endif + endif + let b:v.tagdict[item] = {'char':char, 'tag':tag, 'exclude':'', 'exgroup':0} + call add(b:v.tags_order,item) + if char != '' + let b:v.tagchars .= char + endif + endfor + + let templist = a:tagspec + let i = 1 + while templist =~ '{.\{}}' + "cycle through groups and add exclude chars for any group members + let strikeout = matchstr(templist,'{.\{-}}') + let exclusive = matchstr(templist,'{\zs.\{-}\ze}') + let templist = substitute(templist,strikeout,'','') + let xlist = split(exclusive,'\s\+') + for item in xlist + let b:v.tagdict[item].exgroup = i + for x in xlist + if x != item + let b:v.tagdict[item].exclude .= b:v.tagdict[x].char + endif + endfor + endfor + let i += 1 + endwhile +endfunction + + +function! OrgTagsEdit(...) + let line_file_str = '' + let lineno=line('.') + let file = expand("%") + if bufname("%") ==? ('__Agenda__') + " new file and lineno below to test with new line marker in agenda + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + + call org#SaveLocation() + call org#LocateFile(file) + call s:SetDynamicTags() + call org#RestoreLocation() + + let b:v.tagdict = getbufvar(file,'v').tagdict + let b:v.tags_order = getbufvar(file,'v').tags_order + else + call s:SetDynamicTags() + endif + + let heading_tags = get(s:GetProperties(lineno,0,file),'TAGS','') + + let new_heading_tags = s:TagMenu(heading_tags) + if new_heading_tags != heading_tags + silent call s:SetProp('tags',new_heading_tags,lineno, file) + endif +endfunction + +function! s:TagMenu(heading_tags) + let heading_tags = a:heading_tags + + let tagstring = '' + let tagchars = '' + for item in b:v.tags_order + let tagchars .= b:v.tagdict[item].char + if match(heading_tags,':'.b:v.tagdict[item].tag .':') >= 0 + let tagstring .= b:v.tagdict[item].char + endif + endfor + + hi Cursor guibg=black + let cue = '' + set nomore + while 1 + echo repeat('-',winwidth(0)-1) + echohl Title | echo 'Choose tags: ' | echohl None | echon '( to accept, to cancel )' + echo '------------' + let oldgroup = 0 + let items_in_row = 1 + for item in b:v.tags_order + if item ==? '\n' + continue + endif + let curindex = index(b:v.tags_order,item) + let newgroup = b:v.tagdict[item].exgroup + let select = ' ' + if match(tagstring,b:v.tagdict[item].char) >= 0 + let select = 'X' + echohl Question + else + echohl None + endif + "if (g:org_tag_group_arrange == 0) || (newgroup != oldgroup) || (newgroup == 0 ) || (b:v.tags_order[curindex+1] ==? '\n') + if (curindex == 0) || (b:v.tags_order[curindex-1] ==? '\n') || (winwidth(0) - (items_in_row*20) < 20) + echo repeat(' ',3) . '[' | echohl Question | echon select | echohl None | echon '] ' + echohl None | echon b:v.tagdict[item].tag | echohl Title | echon '('.b:v.tagdict[item].char.')' | echohl None + let nextindent = repeat(' ',12-len(b:v.tagdict[item].tag)) + let items_in_row = 1 + else + "echon repeat(' ',3) . + echon nextindent + echon '[' | echohl Question | echon select | echohl None | echon '] ' + echohl None | echon b:v.tagdict[item].tag | echohl Title | echon '('.b:v.tagdict[item].char.')' | echohl None + let nextindent = repeat(' ',12-len(b:v.tagdict[item].tag)) + let items_in_row += 1 + "echon repeat(' ', 12-len(b:v.tagdict[item])) + endif + let oldgroup = b:v.tagdict[item].exgroup + endfor + echo "" + "echohl LineNr | echon 'Date+time ['.basedate . ' '.basetime.']: ' + "echohl None | echon cue.'_ =>' | echohl WildMenu | echon ' '.newdate.' '.newtime + let nchar = getchar() + let newchar = nr2char(nchar) + if (nchar ==? "\") && (len(cue)>0) + let cue = cue[:-2] + elseif nchar ==? "\" + let cue = ((curdif-365>=0) ?'+':'').(curdif-365).'d' + elseif newchar ==? "\" + " add new tag . . . todo . . . + elseif newchar ==? "\" + break + elseif newchar ==? "\" + hi Cursor guibg=gray + redraw + return a:heading_tags + elseif (match(tagchars,newchar) >= 0) + if (match(tagstring,newchar) == -1) + let tagstring .= newchar + " check for mutually exclusve tags + for item in keys(b:v.tagdict) + if b:v.tagdict[item].char ==? newchar + let exclude_str = b:v.tagdict[item].exclude + let tagstring = tr(tagstring,exclude_str,repeat(' ',len(exclude_str))) + break + endif + endfor + else + let tagstring = tr(tagstring,newchar,' ') + endif + endif + call substitute(tagstring,' ','','') + echon repeat(' ',72) + redraw + endwhile + + hi Cursor guibg=gray + redraw + echo + set more + + let heading_tags = '' + for item in keys(b:v.tagdict) + if (item!='\n') && (match(tagstring, b:v.tagdict[item].char) >= 0) + let heading_tags .= b:v.tagdict[item].tag . ':' + endif + endfor + if heading_tags ># '' | let heading_tags = ':' . heading_tags | endif + return heading_tags +endfunction + +function! s:SetDynamicTags() + let taglist = s:GetBufferTags() + let chardict = {} + let b:v.tagdict = {} + let b:v.tagchars = '' + let b:v.tags_order = [] + + if b:v.buf_tags_static_spec ==# '' + let static_tags = g:org_tags_alist . ' ' . g:org_tags_persistent_alist + if static_tags ==# '' + let b:v.dynamic_tags_only = 1 + endif + elseif exists('b:v.noptags') + let static_tags = b:v.buf_tags_static_spec + else + let static_tags = b:v.buf_tags_static_spec . ' ' . g:org_tags_persistent_alist + endif + + if exists('b:v.dynamic_tags_only') && (b:v.dynamic_tags_only == 1) + let setup_string = join(taglist) + elseif exists('b:v.dynamic_tags') && (b:v.dynamic_tags == 1) + "first need to remove dups in dynamic taglist + let temp_list = split(static_tags) + for i in range(0,len(temp_list)-1) + if temp_list[i] =~ '(.)' + let temp_list[i] = matchstr(temp_list[i],'^.*\ze(') + endif + endfor + let dup_list = s:Intersect( temp_list, taglist ) + for item in dup_list + call remove( taglist, index(taglist, item) ) + endfor + let setup_string = static_tags . ' ' . join(taglist) + else + let setup_string = static_tags + endif + + call OrgTagSetup( setup_string ) + +endfunction + +function! s:GetBufferTags() + let save_cursor = getpos(".") + let b:v.buftagdict = {} + " call addtags for each headline in buffer + g/^\*/call s:AddTagsToDict(line(".")) + call setpos('.',save_cursor) + return sort(keys(b:v.buftagdict)) +endfunction +inoremap =OrgEffort() +noremap A=OrgEffort() +function! OrgEffort() + if getline(line('.'))=~':Effort:' + call setline(line('.'), substitute(getline(line('.')),'ort:\zs.*','','')) + normal A + call complete(col('.'),b:v.effort) + endif + return '' +endfunction +function! s:AddTagsToDict(line) + let taglist = s:GetTagList(a:line) + if !empty(taglist) + for item in taglist + execute "let b:v.buftagdict['" . item . "'] = 1" + endfor + endif +endfunction + +function! s:GetTagList(line) + let text = getline(a:line+1) + if (text !~ b:v.drawerMatch) && (text !~ b:v.dateMatch) && (text =~ s:remstring) + let tags = matchlist(text,':\(\S*\):\s*$') + " include replacement of mistaken double colons with single colon + let tagstr = substitute(tags[1],'::',':','g') + if !empty(tags) + return split(tagstr,':') + else + return [] + endif + else + return [] + endif +endfunction +function! s:IsTagLine(line) + let text = getline(a:line) + return (text !~ b:v.drawerMatch) && (text !~ b:v.dateMatch) && (text =~ s:remstring) +endfunction +function! s:GetTags(line) + if s:IsTagLine(a:line+1) + return matchstr(getline(a:line+1),':.*$') + else + return '' + endif +endfunction +function! s:AddTag(tag,line) + if s:IsTagLine(a:line + 1) + if matchstr(getline(a:line+1),':'.a:tag.':') ==# '' + call setline(a:line+1,getline(a:line+1) . ':' .a:tag. ':') + endif + else + call append(a:line, ' :' . a:tag . ':') + endif +endfunction +function! s:TagInput(line) + let linetags = s:GetTagList(a:line) + if empty(linetags) + call append(a:line,':') + endif + let buftags = s:GetBufferTags() + let displaytags = deepcopy(buftags) + call insert(displaytags,' Exit Menu') + while 1 + let curstatus = [] + call add(curstatus,0) + let i = 1 + let linetags = s:GetTagList(a:line) + while i < len(buftags) + 1 + if index(linetags, buftags[i-1]) >= 0 + let cbox = '[ X ]' + call add(curstatus,1) + else + let cbox = ' ' + call add(curstatus,0) + endif + + let displaytags[i] = cbox . s:PrePad('&'.buftags[i-1],28) + let i += 1 + endwhile + + let @/='' + if foldclosed(a:line) > 0 + let b:v.sparse_list = [a:line] + else + normal V + endif + redraw + if foldclosed(a:line) > 0 + let b:v.sparse_list = [] + else + normal V + endif + "call insert(displaytags,'Choose tags below:') + "let key = inputlist(displaytags) - 1 + let taglist = join(displaytags,"\n") + set guioptions+=v + let key = confirm('Choose tags:',taglist)-1 + set guioptions-=v + "call remove(displaytags,0) + if (key == 0) " || (key == 1) + " need setline for final redraw + call setline(a:line+1,getline(a:line+1)) + redraw + break + endif + let curstatus[key] = 1 - curstatus[key] + let newtags = '' + let i = 1 + while i < len(curstatus) + if curstatus[i] == 1 + let newtags .= ':' . buftags[i-1] . ':' + endif + let i += 1 + endwhile + let newtags = substitute(newtags, '::',':','g') + call setline(a:line+1, repeat(' ',s:Starcount(a:line)+1) . newtags) + + endwhile + if empty(s:GetTagList(a:line)) + execute a:line+1 .'d' + execute a:line + endif +endfunction + +function! s:UnconvertTags(line) + if s:IsTagLine(a:line+1) + normal J + endif +endfunction +function! GlobalUnconvertTags(state) + if exists('g:org_emacs_autoconvert') && (g:org_emacs_autoconvert != 0) + let s:save_cursor = getpos(".") + let s:last_changenr = a:state + mkview + normal A + g/^\*\+\s/call s:UnconvertTags(line(".")) + silent! %s/^\(\s*\):\(DEADLINE\|SCHEDULED\|CLOSED\|CLOCK\|<\d\d\d\d-\d\d-\d\d\)/\1\2/ + endif +endfunction +function! UndoUnconvertTags() + if exists('g:org_emacs_autoconvert') && (g:org_emacs_autoconvert != 0) + silent exec 'undo ' . s:last_changenr + silent undo + loadview + call setpos(".",s:save_cursor) + endif +endfunction + +function! s:ConvertTags(line) + let tags = matchstr(getline(a:line), '\(:\S*:\)\s*$') + if tags ># '' + s/\s\+:.*:\s*$// + call append(a:line, repeat(' ',s:Starcount(a:line)+1) . tags) + endif +endfunction +function! GlobalConvertTags() + "if exists('g:org_emacs_autoconvert') && (g:org_emacs_autoconvert != 0) + let save_cursor = getpos(".") + g/^\*\+\s/call s:ConvertTags(line(".")) + silent! %s/^\(\s*\)\(DEADLINE:\|SCHEDULED:\|CLOSED:\|CLOCK:\|<\d\d\d\d-\d\d-\d\d\)/\1:\2/ + call setpos(".",save_cursor) + "endif +endfunction +function! s:GlobalFormatTags() + let save_cursor = getpos(".") + g/^\*\+\s/call s:FormatTags(line(".")) + call setpos(".",save_cursor) +endfunction +function! s:FormatTags(line) + let tagmatch = matchlist(getline(a:line),'\(:\S*:\)\s*$') + if !empty(tagmatch) + let linetags = tagmatch[1] + s/\s\+:.*:\s*$// + " add newtags back in, including new tag + call setline(a:line,getline(a:line) . ' ' + \ . repeat(' ', winwidth(0) - len(getline(a:line)) - len(linetags) - 15) + \ . linetags) + endif +endfunction + +function! s:FCTest(line) + if foldclosed(a:line) != a:line + return a:line . ' --- ' . foldclosed(a:line) + endif +endfunction + +function! OrgSequenceTodo(line,...) + if a:0 == 1 + if a:1 ==? 'x' + let newtodo = '' + else + for item in b:v.todoitems + if item[0] ==? a:1 + let newtodo = item + endif + endfor + endif + endif + let linetext = getline(a:line) + if (linetext =~ s:org_headMatch) + " get first word in line and its index in todoitems + let tword = matchstr(linetext,'\*\+\s\+\zs\S\+\ze') + if a:0 == 1 + call s:ReplaceTodo(newtodo) + else + call s:ReplaceTodo() + endif + endif +endfunction +function! s:NextTodo(curtodo) + let curtodo = a:curtodo + " check whether word is in todoitems and make appropriate + " substitution + let i = index(b:v.todoitems, curtodo) + if i == -1 + " Not found -> start with first todo + let newtodo = b:v.todoitems[0] + elseif i == len(b:v.todoitems) - 1 + " All cycled -> next is empty + let newtodo = '' + else + let newtodo = b:v.todoitems[i+1] + endif + return newtodo +endfunction +function! s:PreviousTodo(curtodo) + let curtodo = a:curtodo + " check whether word is in todoitems and make appropriate + " substitution + let i = index(b:v.todoitems, curtodo) + if i == -1 + " Not found -> Start with last todo + let last = len(b:v.todoitems) - 1 + let newtodo = b:v.todoitems[last] + elseif i == 0 + " All cycled -> next is empty + let newtodo = '' + else + let newtodo = b:v.todoitems[i-1] + endif + return newtodo +endfunction + +function! OrgTodoDashboard(...) + let key = (a:0==1) ? a:1 : '' + let save_cursor = getpos('.') + let save_window = winnr() + if bufname("%") ==? ('__Agenda__') + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + let buffer_lineno = s:ActualBufferLine(lineno,bufnr(file)) + let b:v.todoitems = getbufvar(file,'v').todoitems + let b:v.todo_setup = getbufvar(file,'v').todo_setup + let props = s:GetProperties(buffer_lineno, 0, file) + let Replace_func = function('s:AgendaReplaceTodo') + else + exec s:OrgGetHead() + let props = s:GetProperties(line('.'),0) + let Replace_func = function('s:ReplaceTodo') + endif + + if key ==# '' + echohl MoreMsg + echo " =================================" + echo " Todos defined in this " . (bufname("%") ==? ('__Agenda__') ? "heading's" : "" ) . " document are:" + echo " " . b:v.todo_setup + echo " =================================" + echo " Press key for a todo command:" + echo " ---------------------------------" + echo " f (or n) cycle current heading's todo Forward/Next" + echo " b (or p) cycle current heading's todo Backward/Previous" + echo " t mark current heading with initial 'unfinished' state" + echo " d mark current heading with main 'finished' state" + "if bufname("%") !=? ('__Agenda__') + let i = 1 + for item in b:v.todoitems + echo ' ' . i . ' mark current heading as ' . item + let i += 1 + endfor + "endif + echo " " + echohl Question + let key = nr2char(getchar()) + redraw + endif + "let thisline = getline(line('.')) + "let curTodo = matchstr(thisline, '\*\+ \zs\S\+') + + if key =~? 'f\|n' + call Replace_func() + elseif key =~? 'b\|p' + call Replace_func('todo-bkwd') + elseif key ==? 't' + "call Replace_func(b:v.todoitems[0]) + call Replace_func('first-todo') + elseif key ==? 'd' + "let done_state = (type(b:v.fulltodos[-1])==type([])) ? b:v.fulltodos[-1][0] : b:v.fulltodos[-1] + "call Replace_func(done_state) + call Replace_func('first-done') + elseif key =~ '[1-9]' + call Replace_func(b:v.todoitems[key-1]) + else + echo "No todo action selected." + endif + echohl None + exe save_window . 'wincmd w' + call setpos('.',save_cursor) +endfunction +function! s:AgendaReplaceTodo(...) + " wrapper to call OrgAgendaGetText to do todo operation + " OrgAgendaGetText does double duty (needs to be + " refactored) and both retrieves text from main buffer + " and handles todo replacements + if bufname('%') != '__Agenda__' + echo "Not in agenda, can't use AgendaReplaceTodo" + return + endif + if empty(b:v.heading_marks_dict) + " just mark and do current item + let b:v.heading_marks_dict[line('.')] = 1 + endif + + for item in sort(keys(b:v.heading_marks_dict), 's:ReverseSort') + " go to the line first, then process + exec item + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let b:v.fulltodos = getbufvar(file,'v').fulltodos + let b:v.todoitems = getbufvar(file,'v').todoitems + let todoword = matchstr(getline(line('.')), '.* \*\+ \zs\S\+') + if a:0 == 0 + let newtodo = 'todo-fwd' + else + let newtodo = a:1 + endif + if newtodo == 'todo-fwd' + let newtodo = s:NextTodo(todoword) + elseif newtodo == 'todo-bkwd' + let newtodo = s:PreviousTodo(todoword) + elseif newtodo == 'first-todo' + let newtodo = b:v.todoitems[0] + elseif newtodo == 'first-done' + let newtodo = (type(b:v.fulltodos[-1])==type([])) ? b:v.fulltodos[-1][0] : b:v.fulltodos[-1] + else + let newtodo = a:1 + endif + call OrgAgendaGetText(1,newtodo) + execute 'sign unplace ' . item . ' buffer=' . bufnr('%') + endfor + let b:v.heading_marks_dict = {} + +endfunction +function! s:ReplaceTodo(...) + "a:1 would be newtodo word + let save_cursor = getpos('.') + if getline(line('.'))[0] == '*' + exec s:OrgGetHead() + endif + let thisline = getline(line('.')) + if bufname("%") !=? '__Agenda__' + let todoword = matchstr(thisline, '\*\+ \zs\S\+') + else + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + " fulltodos needed for s:NewTodo() + let b:v.fulltodos = getbufvar(file,'v').fulltodos + let b:v.todoitems = getbufvar(file,'v').todoitems + let todoword = matchstr(thisline, '.* \*\+ \zs\S\+') + endif + + if a:0 == 0 + let newtodo = 'todo-fwd' + else + let newtodo = a:1 + endif + if newtodo == 'todo-fwd' + let newtodo = s:NextTodo(todoword) + elseif newtodo == 'todo-bkwd' + let newtodo = s:PreviousTodo(todoword) + elseif newtodo == 'first-todo' + let newtodo = b:v.todoitems[0] + elseif newtodo == 'first-done' + let newtodo = (type(b:v.fulltodos[-1])==type([])) ? b:v.fulltodos[-1][0] : b:v.fulltodos[-1] + else + let newtodo = a:1 + endif + + " if going to main done state check for repeater and change date if necessary + if (bufnr("%") != bufnr('Agenda')) && (newtodo =~ b:v.todoDoneMatch[11:]) + let newtodo = s:CheckDateRepeaterDone(todoword, newtodo) + endif + let s:last_newtodo = newtodo " used to set agenda line in next pass from agenda + + if newtodo ># '' + let newtodo .= ' ' + endif + if (index(b:v.todoitems,todoword) >= 0) + if newtodo ># '' + let newline = substitute(getline(line(".")), + \ '\* ' . todoword.' ', + \ '\* ' . newtodo,'g') + else + let newline = substitute(getline(line(".")), + \ '\* ' . todoword.' ', + \ '\* ' . '','g') + endif + else + let newline = substitute(getline(line(".")), + \ '\zs\* \ze\S\+', + \ '\* ' . newtodo ,'g') + endif + + + call setline(line("."),newline) + if exists("*Org_after_todo_state_change_hook") && (bufnr("%") != bufnr('Agenda')) + let Hook = function("Org_after_todo_state_change_hook") + call Hook(line('.'),todoword,newtodo) + endif + + call setpos('.',save_cursor) +endfunction +function! s:CheckDateRepeaterDone(state1,state2) + "check for date repeater on change of todo to done state + " and handle logging and resetting of date" + let newtodo = a:state2 + let props = s:GetProperties(line('.'),0) + let repeat_pattern = '\d\d\d\d-\d\d-\d\d.*[ +.]+\d\+\S\+.*' + for dateprop in ['DEADLINE','SCHEDULED','TIMESTAMP'] + let thisdate = get(props,dateprop) + if thisdate =~ repeat_pattern + "put in log note + call OrgConfirmDrawer("LOGBOOK") + let str = ":- State: " . printf('%.10s','"'.a:state2.'"') . " from: " . printf('%.10s','"'.a:state1.'"') . + \ ' [' . org#Timestamp() . ']' + call append(line("."), repeat(' ',len(matchstr(getline(line(".")),'^\s*'))) . str) + exec s:OrgGetHead() + let newtodo = b:v.todocycle[0] + "change date as appropriate + let basedate = matchstr(thisdate,'\d\d\d\d-\d\d-\d\d') + let cue = '+' . matchstr(thisdate,'+\d*[dwmy]') + if thisdate =~ ' +\d*[dwmy]' + let newdate = DateCueResult(cue,basedate) + elseif thisdate =~ '\.+\d*[dwmy]' + let newdate = DateCueResult(cue,org#Timestamp()[0:9]) + elseif thisdate =~ '++\d*[dwmy]' + let newdate = DateCueResult(cue,basedate) + let i = 0 + while newdate <= org#Timestamp()[0:9] + if i == 9 + unsilent call confirm('Ten adjustments failed to bring to future date.') + break + endif + let newdate = DateCueResult(cue,newdate) + let i += 1 + endwhile + endif + let mydow = calutil#dayname(newdate) + call s:SetProp(dateprop,'<' . newdate . ' ' . mydow . thisdate[14:] . '>') + " break as soon as one repeater is found + unsilent call confirm('Repeater date: entering log and resetting date.') + break + endif + endfor + return newtodo +endfunction + +"Section Navigation Funcs +" +function! s:OrgSubtreeLastLine() + " Return the line number of the next head at same level, 0 for none + return s:OrgSubtreeLastLine_l(line(".")) +endfunction + +function! s:OrgSubtreeLastLine_l(line) + if a:line == 0 + return line("$") + endif + let l:starthead = s:OrgGetHead_l(a:line) + let l:stars = s:Starcount(l:starthead) + let l:mypattern = substitute(b:v.headMatchLevel,'level', '1,'.l:stars, "") + let l:lastline = s:Range_Search(l:mypattern,'nW', line("$"), l:starthead) + " lastline now has NextHead on abs basis so return end of subtree + if l:lastline != 0 + let l:lastline -= 1 + else + let l:lastline = line("$") + endif + return l:lastline + +endfunction + +function! s:HasAncestorHeadOf(line,ancestor) + let ultimate = s:OrgUltimateParentHead_l(a:line) + if (a:line < a:ancestor) || (a:ancestor < ultimate) + let result = 0 + elseif (a:line == a:ancestor) + let result = 1 + else + let test_ancestor = s:OrgParentHead_l(a:line) + while 1 + if (test_ancestor == a:ancestor) + let result = 1 + break + elseif test_ancestor < ultimate + let result = 0 + break + endif + let test_ancestor = s:OrgParentHead_l(test_ancestor) + endwhile + endif + + return result +endfunction +function! s:OrgUltimateParentHead() + " Return the line number of the parent heading, 0 for none + return s:OrgUltimateParentHead_l(line(".")) +endfunction + +function! s:OrgUltimateParentHead_l(line) + " returns 0 for main headings, main heading otherwise + let l:starthead = s:OrgGetHead_l(a:line) + + if s:Ind(l:starthead) > 1 + return s:Range_Search('^* ','bnW',1,l:starthead) + else + return 0 + endif +endfunction + +function! s:OrgParentHead() + " Return the line number of the parent heading, 0 for none + return s:OrgParentHead_l(line(".")) +endfunction + +function! s:OrgParentHead_l(line) + " todo -- get b:v.levelstars in here + let l:starthead = s:OrgGetHead_l(a:line) + let l:parentheadlevel = s:Starcount(l:starthead) - b:v.levelstars + if l:parentheadlevel <= 0 + return 0 + else + let l:mypattern = substitute(b:v.headMatchLevel,'level',l:parentheadlevel,'') + return s:Range_Search(l:mypattern,'bnW',1,l:starthead) + endif +endfunction + + +function! s:Range_Search(stext, flags, ...) + " searches range, restores cursor to + " beginning position, and returns + " first occurrence of pattern + let save_cursor = getpos(".") + " a:1 and a:2 are stopline and startline + if a:0 == 2 + let l:stopline = a:1 + " go to startline + execute a:2 + normal! $ + elseif a:0 == 1 + let l:stopline = a:1 + else + let l:stopline = line("$") + endif + let l:result = search(a:stext, a:flags, l:stopline) + call setpos('.',save_cursor) + return l:result +endfunction + +function! s:OrgGetHead() + return s:OrgGetHead_l(line(".")) +endfunction + +function! s:OrgGetHead_l(line) + if s:IsText(a:line) + return s:Range_Search(b:v.headMatch,'nb', 1, a:line) + else + return a:line + endif +endfunction + +function! s:OrgPrevSiblingHead() + return s:OrgPrevSiblingHead_l(line(".")) +endfunction +function! s:OrgPrevSiblingHead_l(line) + if s:Ind(a:line) > 0 + let upperline = s:OrgParentHead_l(a:line) + else + let upperline = 0 + endif + let sibline = s:OrgPrevHeadSameLevel_l(a:line) + if (sibline <= upperline) + let sibline = 0 + endif + return sibline +endfunction + +function! s:OrgNextSiblingHead() + return s:OrgNextSiblingHead_l(line(".")) +endfunction +function! s:OrgNextSiblingHead_l(line) + if s:Ind(a:line) > 0 + let lastline = s:OrgSubtreeLastLine_l(s:OrgParentHead_l(a:line)) + else + let lastline = line("$") + endif + let sibline = s:OrgNextHeadSameLevel_l(a:line) + if (sibline > lastline) + let sibline = 0 + endif + return sibline +endfunction + +function! s:OrgNextHead() + " Return the line number of the next heading, 0 for none + return s:OrgNextHead_l(line(".")) +endfunction +function! s:OrgNextHead_l(line) + return s:Range_Search(b:v.headMatch,'n', line("$"),a:line) +endfunction + +function! s:OrgPrevHead() + " Return the line number of the previous heading, 0 for none + + return s:OrgPrevHead_l(line(".")) + +endfunction + +function! s:OrgPrevHead_l(line) + + return s:Range_Search(b:v.headMatch,'nb', 1, a:line-1) + +endfunction + +function! s:OrgNextHeadSameLevel() + " Return the line number of the next head at same level, 0 for none + return s:OrgNextHeadSameLevel_l(line(".")) +endfunction + +function! s:OrgNextHeadSameLevel_l(line) + let level = s:Starcount(a:line) + let mypattern = substitute(b:v.headMatchLevel,'level', level, "") + let foundline = s:Range_Search(mypattern,'nW', line("$"), a:line) + if foundline < line ("$") + return foundline + else + if s:Starcount(foundline) > 0 + return foundline + else + return 0 + endif + endif +endfunction + +function! s:OrgPrevHeadSameLevel() + " Return the line number of the previous heading, 0 for none + return s:OrgPrevHeadSameLevel_l(line(".")) +endfunction +function! s:OrgPrevHeadSameLevel_l(line) + let l:level = s:Starcount(a:line) + let l:mypattern = substitute(b:v.headMatchLevel,'level', l:level, "") + let foundline = s:Range_Search(mypattern,'nbW', 1, a:line-1) + if foundline > 1 + return foundline + else + if (s:Starcount(foundline) > 0) && (a:line != 1) + return 1 + else + return 0 + endif + endif + +endfunction + +function! s:OrgFirstChildHead() + " Return the line number of first child, 0 for none + return s:OrgFirstChildHead_l(line(".")) +endfunction +function! s:OrgFirstChildHead_l(line) + let l:starthead = s:OrgGetHead_l(a:line) + + let l:level = s:Starcount(l:starthead) + 1 + let l:nexthead = s:OrgNextHeadSameLevel_l(l:starthead) + if l:nexthead == 0 + let l:nexthead = line("$") + endif + let l:mypattern = substitute(b:v.headMatchLevel,'level', l:level, "") + return s:Range_Search(l:mypattern,'nW',l:nexthead, l:starthead) +endfunction + +function! s:OrgLastChildHead() + " Return the line number of the last child, 0 for none + return s:OrgLastChildHead_l(line(".")) +endfunction + +function! s:OrgLastChildHead_l(line) + " returns line number of last immediate child, 0 if none + let l:starthead = s:OrgGetHead_l(a:line) + + let l:level = s:Starcount(l:starthead) + 1 + + let l:nexthead = s:OrgNextHeadSameLevel_l(l:starthead) + if l:nexthead == 0 + let l:nexthead = line("$") + endif + + let l:mypattern = substitute(b:v.headMatchLevel,'level', l:level, "") + return s:Range_Search(l:mypattern,'nbW',l:starthead, l:nexthead) + +endfunction + +function! s:MyLastChild(line) + " Return the line number of the last decendent of parent line + let l:parentindent = s:Ind(a:line) + if s:IsText(a:line+1) + let l:searchline = s:NextLevelLine(a:line+1) + else + let l:searchline = a:line+1 + endif + while s:Ind(l:searchline) > l:parentindent + let l:searchline = l:searchline+1 + endwhile + return l:searchline-1 +endfunction + +function! s:NextVisibleHead(line) + " Return line of next visible heanding, 0 if none + let save_cursor = getpos(".") + + while 1 + let nh = s:OrgNextHead() + if (nh == 0) || s:IsVisibleHeading(nh) + break + endif + execute nh + endwhile + + call setpos('.',save_cursor) + return nh + +endfunction + +function! s:FoldStatus(line) + " adds new heading or text level depending on type + let l:fc = foldclosed(a:line) + if l:fc == -1 + let l:status = 'unfolded' + elseif l:fc > 0 && l:fc < a:line + let l:status = 'infold' + elseif l:fc == a:line + let l:status = 'foldhead' + endif + return l:status +endfunction + +function! OrgEnterFunc() + let syn_items = synstack(line('.'),col('.')) + call map(syn_items, "synIDattr(v:val,'name')") + if (index(syn_items,'Org_Full_Link') >= 0) || ( index(syn_items,'Org_Half_Link') >= 0) + call FollowLink( OrgGetLink() ) + else + call OrgNewHead('same') + endif +endfunction + +function! OrgNewHead(type,...) + " adds new heading or text level depending on type + if a:0 == 1 + normal  + endif + execute s:OrgGetHead() + let l:org_line = line(".") + let l:linebegin = matchlist(getline(line(".")),'^\(\**\s*\)')[1] + if s:IsText(line(".")) == 0 + + let l:lastline = s:OrgSubtreeLastLine() + if a:type ==? 'levelup' + let l:linebegin = substitute(l:linebegin,'^\*\{'.b:v.levelstars.'}','','') + elseif a:type ==? 'leveldown' + let l:linebegin = substitute(l:linebegin,'^\*',repeat('*',b:v.levelstars+1),'') + endif + call append( l:lastline ,l:linebegin) + execute l:lastline + 1 + startinsert! + + endif + return '' +endfunction + +function! s:IsText(line) + " checks for whether line is any kind of text block + " test if line matches all-inclusive text block pattern + return (getline(a:line) !~ b:v.headMatch) && (a:line <= line('$')) +endfunction + +function! s:NextLevelAbs(line) + " Return line of next heading + " in absolute terms, not just visible headings + let l:i = 1 + " go down to next non-text line + while s:IsText(a:line + l:i) + let l:i = l:i + 1 + "if (a:line + l:i) == line("$") + :" return 0 + "endif + endwhile + return a:line + l:i +endfunction + +function! s:NextLevelLine(line) + " Return line of next heading + let l:fend = foldclosedend(a:line) + if l:fend == -1 + let l:i = 1 + " go down to next non-text line + while s:IsText(a:line + l:i) + let l:i = l:i + 1 + endwhile + return a:line + l:i + else + return l:fend+1 + endif +endfunction + +function! s:HasChild(line) + " checks for whether heading line has + " a sublevel + " checks to see if heading has a non-text sublevel + let nh = s:OrgNextHead_l(a:line) + if nh == 0 + return 0 + else + return (s:Ind(nh) > s:Ind(a:line)) + endif + +" if s:IsText(a:line + 1) && +" \ (s:Ind(s:NextLevelLine(a:line+1)) > s:Ind(a:line)) +" return 1 +" elseif s:IsText(a:line + 1) == 0 && +" \ (s:Ind(s:NextLevelLine(a:line)) > s:Ind(a:line)) +" return 1 +" else +" return 0 +" endif +endfunction + +function! s:DoFullCollapse(line) + let lastline = s:OrgSubtreeLastLine_l(a:line) + if lastline == a:line + return + else + while foldclosedend(a:line) < lastline + normal! zc + endwhile + endif + " make sure headline is not just + " text collapse + " test if line matches all-inclusive text block pattern + " while foldclosed(a:line) == -1 && (s:HasChild(a:line) || s:IsText(a:line+1)) + " normal! zc + " endwhile + " if s:IsTextOnlyFold(a:line) && s:HasChild(a:line) + " normal! zc + " if s:IsTextOnlyFold(a:line) && s:HasChild(a:line) + " normal! zc + " if s:IsTextOnlyFold(a:line) && s:HasChild(a:line) + " normal! zc + " endif + " endif + " endif +endfunction + +function! s:IsTextOnlyFold(line) + " checks for whether heading line has full fold + " or merely a text fold + "if s:IsText(a:line + 1) && (foldclosed(a:line + 1) == a:line) + if s:IsText(a:line + 1) && (foldclosedend(a:line) > 0) + \ && (s:Ind(foldclosedend(a:line)) <= s:Ind(a:line)) + return 1 + else + return 0 + endif +endfunction + +function! s:MaxVisIndent(headingline) + " returns max indent for + " visible lines in a heading's subtree + " used by ShowSubs + let l:line = a:headingline + let l:endline = s:OrgSubtreeLastLine() + "let l:endline = s:MyLastChild(l:line) + let l:maxi = s:Ind(l:line) + let l:textflag = 0 + while l:line <= l:endline + if (s:Ind(l:line) > l:maxi) && + \ ( foldclosed(l:line) == l:line + \ || foldclosed(l:line) == -1 ) + let l:maxi = s:Ind(l:line) + if s:IsText(l:line) + let l:textflag = 1 + endif + endif + let l:line = l:line + 1 + endwhile + return l:maxi + l:textflag +endfunction + +function! OrgShowLess(headingline) + " collapses headings at farthest out visible level + let l:maxi = s:MaxVisIndent(a:headingline) + let l:offset = l:maxi - s:Ind(a:headingline) + echo 'offset: ' . l:offset + if l:offset > 1 + call s:ShowSubs(l:offset - 1,0) + elseif l:offset == 1 + normal zc + "normal! zc + endif +endfunction + + +function! OrgShowMore(headingline) + " expands headings at furthest out + " visible level in a heading's subtree + let l:maxi = s:MaxVisIndent(a:headingline) + let l:offset = l:maxi - s:Ind(a:headingline) + if l:offset >= 0 + call s:ShowSubs(l:offset + 1,0) + if l:maxi == s:MaxVisIndent(a:headingline) + "call OrgSingleHeadingText('expand') + endif + endif +endfunction + +function! OrgShowSubs(number,withtext) + " used by comma-num mapping + " expands/collapses individual heading to level visibility equal to a:number + if getline(line('.'))[0] != '*' + exec s:OrgPrevHead() + endif + let cur_level = s:Ind(line('.')) - 1 + if a:number > cur_level + let rel_level = a:number - cur_level + if rel_level >= 1 + call s:ShowSubs(rel_level ,0) + endif + else + call s:DoFullCollapse(line('.')) + endif + normal ztkj +endfunction + +function! s:ShowSubs(number,withtext) + " shows specif number of levels down from current + " heading, includes text + " or merely a text fold + let save_cursor = getpos(".") + + call s:DoFullCollapse(line(".")) + let l:start = foldclosed(line(".")) + if l:start != -1 + let l:end = foldclosedend(line(".")) + exec "" . l:start . "," . l:end . "foldc!" + exec "normal! zv" + let to_level = 2 + for to_level in range( 2 , a:number ) + exec "" . l:start . "," . l:end . "foldo" + endfor + endif + if a:withtext == 0 + call OrgSingleHeadingText('collapse') + endif + + call setpos(".",save_cursor) +endfunction + +" 2 args of start line num and direction ('up' or 'down') +"command -nargs=* OrgMoveLevel :call OrgMoveLevel(,v:count1) +nmap ,q :call OrgMoveLevel(line('.'),'up',v:count1) + +function! OrgMoveLevel(line, direction,...) + if (getline(a:line) !~ b:v.headMatch) + echo "Must be on a heading line to move subtrees." + return + endif + if a:0>=1 + let mycount = a:1 + else + let mycount = 1 + endif + " move a heading tree up, down, left, or right + let lastline = s:OrgSubtreeLastLine_l(a:line) + if a:direction ==? 'up' + let l:headabove = a:line + let count_message = '' + for i in range( 1, mycount) + let lasthead = l:headabove + let l:headabove = s:OrgPrevSiblingHead_l(l:headabove) + if l:headabove > 0 + let count_message = 'Moved up ' . i . ' levels.' + elseif i == 1 + " break with no message here + break + else + let l:headabove = lasthead + if i <= mycount | let count_message .= ' No more siblings above.' | endif + break + endif + endfor + if l:headabove > 0 + let l:lines = getline(line("."), lastline) + call s:DoFullCollapse(a:line) + silent normal! dd + call append(l:headabove-1,l:lines) + execute l:headabove + call s:ShowSubs(1,0) + echo count_message + else + echo "No sibling heading above in this subtree." + endif + elseif a:direction ==? 'down' + let l:headbelow = a:line + let count_message = '' + for i in range(1, mycount) + let lasthead = l:headbelow + let l:headbelow = s:OrgNextSiblingHead_l(l:headbelow) + if l:headbelow > 0 + let count_message = 'Moved down ' . i . ' levels.' + elseif i == 1 + " break with no message here + break + else + let l:headbelow = lasthead + if i <= mycount | let count_message .= ' No more siblings below.' | endif + break + endif + endfor + if l:headbelow > 0 + let endofnext = s:OrgSubtreeLastLine_l(l:headbelow) + let lines = getline(line("."),lastline) + silent call append(endofnext,lines) + execute endofnext + 1 + " set mark and go back to delete original subtree + normal ma + execute a:line + call s:DoFullCollapse(a:line) + silent normal! dd + normal g'a + call s:ShowSubs(1,0) + echo count_message + else + echo "No sibling below in this subtree." + endif + elseif a:direction ==? 'left' + if s:Ind(a:line) > 2 + " first move to be last sibling + let movetoline = s:OrgSubtreeLastLine_l(s:OrgParentHead_l(a:line)) + let lines = getline(line("."),lastline) + call append(movetoline,lines) + execute movetoline + 1 + " set mark and go back to delete original subtree + normal ma + execute a:line + call s:DoFullCollapse(a:line) + silent exe 'normal! dd' + normal g'a + " now move tree to the left + normal ma + silent execute line(".") ',' . s:OrgSubtreeLastLine() . 's/^' . repeat('\*',b:v.levelstars) .'//' + call s:DoFullCollapse(a:line) + normal g'a + call s:ShowSubs(1,0) + execute line(".") + else + echo "You're already at main heading level." + endif + elseif a:direction ==? 'right' + if s:Ind(s:OrgPrevHead_l(a:line)) >= s:Ind(a:line) + execute a:line . ',' . lastline . 's/^\*/'.repeat('\*',b:v.levelstars+1).'/' + call s:DoFullCollapse(a:line) + execute a:line + call s:ShowSubs(1,0) + else + echo "Already at lowest level of this subtree." + endif + endif +endfunction + +function! OrgNavigateLevels(direction) + " Move among headings + " direction: "up", "down", "right", "left","end", or 'home' + if s:IsText(line(".")) + exec s:OrgGetHead() + return + endif + + if s:Ind(line(".")) > 0 + let lowerlimit = s:OrgParentHead() + let upperlimit = s:OrgSubtreeLastLine_l(lowerlimit) + else + let lowerlimit = 0 + let upperlimit = line("$") + endif + + if a:direction ==? "left" + let dest = s:OrgParentHead() + let msg = "At highest level." + elseif a:direction ==? "home" + let dest = s:OrgParentHead() + let msg = "At highest level." + elseif a:direction ==? "right" + let dest = s:OrgFirstChildHead() + let msg = (dest > 0 ? "Has subheadings, but none visible." + \ : "No more subheadings.") + elseif a:direction ==? 'end' + let dest = s:OrgLastChildHead() + let msg = (dest > 0 ? "Has subheadings, but none visible." + \ : "No more subheadings.") + elseif a:direction ==? 'up' + let dest = s:OrgPrevHeadSameLevel() + let msg = "Can't go up more here." + elseif a:direction ==? 'down' + let dest = s:OrgNextHeadSameLevel() + let msg = "Can't go down more." + endif + + let visible = s:IsVisibleHeading(dest) + if (dest > 0) && visible && (dest >= lowerlimit) && (dest <= upperlimit) + execute dest + else + echo msg + endif +endfunction + +function! OrgHeadingFirstText(headline) + exec a:headline + 1 + let found = 0 + while 1 + let thisline = getline(line('.')) + if thisline =~ b:v.headMatch + break + else + if (thisline !~ s:remstring) && (thisline !~ b:v.dateMatch) + \ && (thisline !~ b:v.drawerMatch) + let found = line('.') + break + elseif line('.') == line('$') + break + endif + endif + exec line('.') + 1 + endwhile + return found +endfunction + +function! OrgUnfoldBodyText(headline) + if OrgHeadingFirstText(a:headline) > 0 + normal zv + endif +endfunction + +function! OrgExpandWithoutText(tolevel) + " expand all headings but leave Body Text collapsed + " tolevel: number, 0 to 9, of level to expand to + " expand levels to 'tolevel' with all body text collapsed + let l:startline = 1 + let l:endline = line("$") + let l:execstr = "set foldlevel=" . string(a:tolevel ) + "let l:execstr = "set foldlevel=" . (a:tolevel - 1) + exec l:execstr + call OrgBodyTextOperation(l:startline,l:endline,"collapse") +endfunction +function! s:OrgExpandSubtree(headline,...) + if a:0 > 0 + let withtext = a:1 + endif + let save_cursor = getpos(".") + call s:DoFullFold(a:headline) + "let end = foldclosedend(a:headline) + "normal! zO + "call OrgBodyTextOperation(a:headline, end, 'collapse') + call s:ShowSubs(3,withtext) + call setpos(".",save_cursor) +endfunction +function! s:OrgExpandHead(headline) + let save_cursor = getpos(".") + call s:DoFullFold(a:headline) + "let end = foldclosedend(a:headline) + "normal! zO + "call OrgBodyTextOperation(a:headline, end, 'collapse') + call s:ShowSubs(1,0) + while foldclosed(a:headline) != -1 + normal! zo + endwhile + call setpos(".",save_cursor) +endfunction +function! s:DoFullFold(headline) + let save_cursor = getpos(".") + "normal! zo + call s:DoAllTextFold(a:headline) + let fend = foldclosedend(a:headline) + if ((fend > a:headline) && (s:Ind(fend+1) > s:Ind(a:headline))) + \ || (s:Ind(a:headline+1) > s:Ind(a:headline)) + normal zc + endif + call setpos(".",save_cursor) +endfunction +function! s:OrgCycle(headline) + let save_cursor = getpos(".") + let topline = line("w0") + + let end = foldclosedend(a:headline) + if (end>0) && (s:Ind(end+1) <= s:Ind(a:headline)) + call s:OrgExpandHead(a:headline) + let endline = end + elseif ((end == -1) && (s:Ind(s:OrgNextHead_l(a:headline)) > s:Ind(a:headline)) + \ && (foldclosed(s:OrgNextHead_l(a:headline)) > 0)) + let nextsamelevel = s:OrgNextHeadSameLevel_l(a:headline) + "let nextuplevel = s:OrgNextHeadSameLevel_l(s:OrgParentHead_l(a:headline)) + let nextuplevel = s:OrgNextHeadSameLevel_l(a:headline) + if (nextsamelevel > 0) && (nextsamelevel > nextuplevel) + let endline = nextsamelevel + elseif nextuplevel > a:headline + let endline = nextuplevel - 1 + else + let endline = line('$') + endif + if b:v.cycle_with_text + call OrgBodyTextOperation(a:headline+1,endline,'expand') + else + call s:OrgExpandSubtree(a:headline,0) + endif + else + call s:DoFullFold(a:headline) + endif + + exe "normal! " . topline . "G" + normal zt + call setpos(".",save_cursor) + if exists('endline') && line('w$') < endline + normal ztkj + endif +endfunction +function! OrgCycle() + if getline(line(".")) =~ b:v.headMatch + call s:OrgCycle(line(".")) + elseif getline(line(".")) =~ b:v.drawerMatch + normal! za + elseif getline(line('.')) =~ '^\s*|.*|\s*$' + " we're in a table, do tab and short circuit + exec "normal i\tl" + return + endif +endfunction +let s:orgskipthirdcycle = 0 +function! OrgGlobalCycle() + if getline(line('.')) =~ '^\s*|.*|\s*$' + "short circuit if we're in table + exec "normal i\l" + return + endif + if exists('w:sparse_on') && w:sparse_on + call s:ClearSparseTree() + endif + if (&foldlevel > 1) && (&foldlevel != b:v.global_cycle_levels_to_show) + call OrgExpandWithoutText(1) + elseif &foldlevel == 1 + call OrgExpandWithoutText(b:v.global_cycle_levels_to_show) + "elseif (&foldlevel > 1) && ( s:orgskipthirdcycle == 0 ) + " let s = getpos('.') + " g/^\*\+ /call OrgUnfoldBodyText(line('.')) + " call setpos('.',s) + " let s:orgskipthirdcycle = 1 + else + let save_cursor = getpos('.') + set foldlevel=9999 + silent exec 'g/' . b:v.drawerMatch . '/normal! zc' + let s:orgskipthirdcycle = 0 + call setpos('.',save_cursor) + endif +endfunction +function! s:LastTextLine(headingline) + " returns last text line of text under + " a heading, or 0 if no text + let l:retval = 0 + if s:IsText(a:line + 1) + let l:i = a:line + 1 + while s:IsText(l:i) + let l:i = l:i + 1 + endwhile + let l:retval = l:i - 1 + endif + return l:retval +endfunction + +function! s:ShowSynStack() + for id in synstack(line("."),col(".")) + echo synIDattr(id,"name") + endfor +endfunction +function! s:SignList() + let signlist = '' + redir => signlist + silent execute "sign list" + redir END + return split(signlist,'\n') +endfunction +function! s:DeleteSigns() + " first delete all placed signs + sign unplace * + let signs = s:SignList() + for item in signs + silent execute "sign undefine " . matchstr(item,'\S\+ \zs\S\+\ze ') + endfor + sign define piet text=>> + sign define fbegin text=> + sign define fend text=< + sign define marked text=> linehl=Org_Marked +endfunction + +function! s:GetPlacedSignsString(buffer) + let placedstr = '' + redir => placedstr + silent execute "sign place buffer=".a:buffer + redir END + return placedstr + +endfunction +function! s:GetProperties(hl,withtextinfo,...) + let save_cursor = getpos(".") + if a:0 >=1 + let curtab = tabpagenr() + let curwin = winnr() + " optional args are: a:1 - lineno, a:2 - file + call org#LocateFile(a:1) + endif + let datesdone = 0 + let result1 = {} + let result = {} + + let linetext = getline(a:hl) + if linetext[0] == '*' + let hl = a:hl + else + let hl = s:OrgGetHead_l(a:hl) + let linetext = getline(hl) + endif + + let result1['LINE'] = hl + let result1['LEVEL'] = s:Ind(hl) - 1 + "let linetext = getline(hl) + let result1['ITEM'] = linetext + let result1['FILE'] = expand("%:t") + " get date on headline, if any + if linetext =~ b:v.dateMatch + let result1['ld'] = matchlist(linetext,b:v.dateMatch)[1] + endif + if (getline(hl+1) =~ b:v.tagMatch) && (getline(hl+1) !~ b:v.drawerMatch) + let result1['TAGS'] = matchstr(getline(hl+1),b:v.tagMatch) + endif + if linetext =~ b:v.todoMatch + let result1['TODO'] = matchstr(linetext,b:v.todoMatch) + else + let result1['TODO'] = '' + endif + + let line = hl + 1 + "let firsttext=0 + while 1 + let ltext = getline(line) + if ltext =~ b:v.propMatch + let result = s:GetPropVals(line+1) + elseif (ltext =~ '^\s*:\s*CLOCK') + " do nothing + elseif (ltext !~ s:block_line) || (ltext =~ b:v.headMatch) + call extend(result, result1) + if datesdone + call extend(result, dateresult) + endif + let result['BLOCK_END'] = line - 1 + break + elseif (ltext =~ b:v.dateMatch) && !datesdone + let dateresult = s:GetDateVals(line) + let datesdone = 1 + " no break, go back around to check for props + "elseif (ltext =~ '^\s*$') || (ltext =~ '^\s*:\s*CLOCK') + endif + let line += 1 + endwhile + " ***************************************** + " get inherited properties + if s:include_inherited_props == 1 + for item in b:v.org_inherited_properties + if index(keys(result), item) == -1 + let result[item] = s:IProp(hl , item) + endif + endfor + endif + " ***************************************** + " get last line + if a:withtextinfo + "let result['tbegin'] = line + let result['TEND'] = s:OrgNextHead_l(hl) - 1 + endif + if a:0 >= 1 + execute "tabnext ".curtab + execute curwin . "wincmd w" + endif + call setpos(".",save_cursor) + "debugging + let g:org_result = result + return result +endfunction + +function! s:GetDateVals(line) + "result is dict with all date vals + let myline = a:line + let result = {} + while 1 + let ltext = getline(myline) + let mtest1 = '<\zs'.b:v.dateMatch.'.*\ze>' + let mtest2 = '\[\zs'.b:v.dateMatch.'.*\ze\]' + if ltext =~ mtest1 + "let mymatch = matchlist(ltext, '.\{-}\(<\d\d\d\d-\d\d-\d\d\) \S\S\S\( \d\d:\d\d\)*') + "let mydate = mymatch[1] . mymatch[2] . '>' + let mymatch = '^\s*\(:DEADLINE:\|:SCHEDULED:\|:CLOSED:\|:<\)\s*\zs.*' + let mydate = matchstr(ltext,mymatch) + let mydate = (mydate[0]=='<') ? mydate[1:-2] : mydate[:-2] + if ltext =~ 'DEADLINE' + let dtype = 'DEADLINE' + elseif ltext =~ 'SCHEDULED' + let dtype = 'SCHEDULED' + elseif ltext =~ 'CLOSED' + let dtype = 'CLOSED' + else + let dtype = 'TIMESTAMP' + endif + elseif ltext =~ mtest2 + let mydate = matchstr(ltext, mtest2) + "let mydate = substitute(ltext, '\(\[\d\d\d\d-\d\d-\d\d\) \S\S\S\( \d\d:\d\d\)*','\1\2','') + let dtype = 'TIMESTAMP_IA' + else + break + endif + + try + "only add if first of dtype encountered + if get(result,dtype) == 0 + let result[dtype] = mydate + endif + catch /^Vim\%((\a\+)\)\=:E/ + endtry + let myline += 1 + endwhile + return result +endfunction + +function! s:GetPropVals(line) + "result is dict with all prop vals + let myline = a:line + let result = {} + while 1 + let ltext = getline(myline) + if ltext =~ b:v.propvalMatch + let mtch = matchlist(ltext, b:v.propvalMatch) + " mtch[1] is now property, mtch[2] is its value + try + let result[toupper(mtch[1])] = mtch[2] + catch /^Vim\%((\a\+)\)\=:E/ + endtry + else + break + endif + let myline += 1 + endwhile + return result +endfunction + + +function! s:RedoTextIndent() + set fdm=manual + set foldlevel=9999 + exec 1 + let myindent = 0 + while line(".") < line("$") + let line = getline(line(".")) + if matchstr(line,'^\*\+') ># '' + let myindent = len(matchstr(line,'^\*\+')) + g:org_indent_from_head + normal j + else + let text = matchstr(line,'^ *\zs.*') + let spaces = len(matchstr(line,'^ *')) + if (spaces != (myindent + 1)) && (text != '') + call setline(line("."),repeat(' ',myindent+1) . text) + endif + normal j + endif + endwhile + exec 1 + set fdm=expr +endfunction + +function! s:LoremIpsum() + let lines = ['Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?","At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.'] + return split(lines[org#util#random(3)-1],'\%70c\S*\zs \ze') +endfunction + +function! s:SetRandomDate(...) + call s:OrgGetHead() + if a:0 == 1 + let date_type = a:1 + else + let date_type = ['DEADLINE','TIMESTAMP','SCHEDULED'][org#util#random(3)-1] + endif + if date_type != '' + call s:SetProp(date_type,org#randomData()) + else + let hl = line('.') + let dmatch = match(getline(hl),'\s*<\d\d\d\d-\d\d-\d\d') + if dmatch > 0 + let dmatch = dmatch - 1 + call setline(hl,getline(hl)[:dmatch]) + endif + let newd = org#randomData() + execute hl + execute "normal A ". newd + endif +endfunction +function! s:SetRandomTodo() + let newtodo = b:v.todoitems[org#util#random(3)-1] + if index(b:v.todoitems,matchstr(getline(line('.')),'^\*\+ \zs\S*\ze ')) >= 0 + call setline(line('.'),matchstr(getline(line('.')),'^\*\+ ') . newtodo . + \ ' '. matchstr(getline(line('.')),'^\*\+ \S* \zs.*')) + else + call setline(line('.'),matchstr(getline(line('.')),'^\*\+ ') . newtodo . + \ ' '. matchstr(getline(line('.')),'^\*\+ \zs.*')) + endif + +endfunction + +function! s:UpdateHeadlineSums() + g/^\s*:TOTALCLOCKTIME/d + call OrgMakeDict() + let g:tempdict = {} + g/^\*\+ /let g:tempdict[line('.')] = b:v.org_dict.SumTime(line('.'),'ITEMCLOCKTIME') + let items = sort(map(copy(keys(g:tempdict)),"str2nr(v:val)"),'s:NumCompare') + let i = len(items) - 1 + while i >= 0 + if g:tempdict[items[i]] != '0:00' + call s:SetProp('TOTALCLOCKTIME',g:tempdict[items[i]],items[i]) + endif + let i = i-1 + endwhile +endfunction + +function! s:IProp(headline,property) + let prop = a:property + let parent = s:OrgParentHead_l(a:headline) + if parent == 0 + return get(b:v.org_inherited_defaults,prop) + else + return s:GetProperties(parent,0)[prop] + endif +endfunction + +function! OrgMakeDictInherited(...) + let get_tags = ((a:0==1) && (a:1 =='get_tags_too')) ? 1 : 0 + if (b:v.last_idict_time >= getftime(expand('%:p')) && (&modified==0)) + " now check and return if last run had tags or this run doesn't need them + if (b:v.last_idict_with_tags == 1) || (get_tags == 0) + return + endif + endif + let b:v.last_idict_time = localtime() + let b:v.last_idict_with_tags = get_tags + if s:OrgVal('g:org_save_when_searched') > 0 | write! | endif + let b:v.org_dict = {} + call OrgProcessConfigLines() + let b:v.org_dict = {'0':{'c':[],'CATEGORY':b:v.org_inherited_defaults['CATEGORY'] }} + function! b:v.org_dict.iprop(ndx,property) dict + let prop = a:property + let ndx = a:ndx + let result = get(self[ndx] , prop,'') + if (result ==# '') && (ndx != 0) + "recurse up through parents in tree + let result = b:v.org_dict.iprop(self[ndx].parent,prop) + endif + return result + endfunction + execute 1 + let next = 1 + if s:IsText(line('.')) + let next = s:OrgNextHead() + endif + while next > 0 + execute next + if getline(line('.'))[1] ==? ' ' + let parent = 0 + else + let parent = s:OrgParentHead() + endif + let b:v.org_dict[line('.')] = {'parent': parent} + let next = s:OrgNextHead() + endwhile + " parent properties assigned above, now explicity record CATEGORY for + " any headlines where CATEGORY won't be inherited + if get_tags == 0 + silent execute 'g/^\s*:CATEGORY:/let b:v.org_dict[s:OrgGetHead()].CATEGORY = matchstr(getline(line(".")),":CATEGORY:\\s*\\zs.*")' + else + silent execute 'g/^\s*:CATEGORY:/let b:v.org_dict[s:OrgGetHead()].CATEGORY = matchstr(getline(line(".")),":CATEGORY:\\s*\\zs.*")' + silent g/^\*\+\s*\S/call s:GetBasicMeta(line('.')) + endif +endfunction +function! s:GetBasicMeta(line) + "let b:v.org_dict[a:line].CATEGORY = matchstr(getline(a:line),":CATEGORY:\\s*\\zs.*") + let this_line = getline(a:line) + let todo = matchstr(this_line,b:v.todoMatch) + "let b:v.org_dict[a:line].TODO = matchstr(getline(a:line),b:v.todoMatch) + if s:IsTagLine(a:line + 1) + let tags = matchstr(getline(a:line+1),'^\s*\zs.*') + else + let tags = '' + endif + let b:v.org_dict[a:line].props = {'ITEM': this_line,'TODO':todo,'TAGS':tags} +endfunction +function! OrgMakeDict() + if (b:v.last_dict_time >= getftime(expand('%:p')) && (&modified==0)) + return + endif + " save new dict time to use in future searches + let b:v.last_dict_time = localtime() + "let b:v.org_dict = {} + "save buffer changes since last_dict + if s:OrgVal('g:org_save_when_searched') > 0 | write! | endif + " and recreate the dict + call OrgMakeDictInherited() + function! b:v.org_dict.SumTime(ndx,property) dict + let prop = a:property + let result = get(self[a:ndx].props , prop,'0:00') + " now recursion down the subtree of children in c + for item in self[a:ndx].c + let result = s:AddTime(result,b:v.org_dict.SumTime(item,prop)) + endfor + return result + endfunction + function! b:v.org_dict.Sum(ndx,property) dict + let prop = a:property + let result = get(self[a:ndx].props , prop) + " now recursion down the subtree of children in c + for item in self[a:ndx].c + let result += b:v.org_dict.Sum(item,prop) + endfor + return result + endfunction + execute 1 + let next = 1 + if s:IsText(line('.')) + let next = s:OrgNextHead() + endif + while next > 0 + execute next + let b:v.org_dict[line('.')].c = [] + let b:v.org_dict[line('.')].props = s:GetProperties(line('.'),1) + let parent = b:v.org_dict[line('.')].parent + call add(b:v.org_dict[parent].c ,line('.')) + let next = s:OrgNextHead() + endwhile +endfunction + +function! s:ClearSparseTreeOld() + set fdm=manual + silent exe '%s/^*x//' + silent exe 'undojoin | %s/^*o//' + "g/^*x/call substitute(getline(line(".")),'^*x','')) + "g/^*o/call substitute(getline(line(".")),'^*o','')) + + call clearmatches() + set fdm=expr + echo "sparse tree view cleared" +endfunction + +function! s:SparseTreeRun(term) + + call s:ClearSparseLists() + let w:sparse_on = 1 + execute 'g/' . a:term . '/call add(b:v.sparse_list,line("."))' + call s:SparseTreeDoFolds() + call clearmatches() + let g:org_first_sparse=1 + let b:v.signstring= s:GetPlacedSignsString(bufnr("%")) + set fdm=expr + set foldlevel=0 + let g:org_first_sparse=1 + execute 'let @/ ="' . a:term .'"' + execute 'g/' . a:term . '/normal zv' + set hlsearch + execute 1 +endfunction + +function! s:SparseTreeDoFolds() + let i = len(b:v.sparse_list) - 1 + while i >= 0 + "if b:v.sparse_list[i] + g:org_sparse_lines_after > line("$") + if b:v.sparse_list[i] + 10 > line("$") + call remove(b:v.sparse_list, i) "insert(b:v.fold_list,0) + let i -= 1 + continue + "elseif (i>0) && (b:v.sparse_list[i] < b:v.sparse_list[i-1] + g:org_sparse_lines_after) + elseif (i>0) && (b:v.sparse_list[i] < b:v.sparse_list[i-1] + 10) + call remove(b:v.sparse_list, i) "insert(b:v.fold_list,0) + let i -= 1 + continue + else + let phead = s:OrgUltimateParentHead_l(b:v.sparse_list[i]) + if phead >= 1 + call insert(b:v.fold_list,phead-1) + else + " match is already on level 1 head + call insert(b:v.fold_list,b:v.sparse_list[i]-1) + endif + endif + + let i -= 1 + endwhile + "call map(b:v.sparse_list,"v:val + g:org_sparse_lines_after") + call map(b:v.sparse_list,"v:val + 10") + call insert(b:v.sparse_list, 1) + call add(b:v.fold_list, line("$")) + + " sign method to potentially supersede list based method above + call s:DeleteSigns() + for item in b:v.sparse_list + execute "sign place " . item ." line=".item." name=fbegin buffer=".bufnr("%") + endfor + for item in b:v.fold_list + execute "sign place " . item ." line=".item." name=fend buffer=".bufnr("%") + endfor + let s:sparse_lines = {} + for item in b:v.sparse_list + let s:sparse_lines[item] = 1 + let s:sparse_lines[item-1] = 1 + endfor + for item in b:v.fold_list + let s:sparse_lines[item] = 1 + endfor + " FoldTouch below instead of fdm line above to save time + " updating folds for just newly changed foldlevel lines + "call s:FoldTouch() + +endfunction + +function! s:ClearSparseLists() + " mylist with lines of matches + let b:v.sparse_list = [] + " foldlist with line before previous level 1 parent + let b:v.fold_list = [] + let b:v.sparse_heads = [] +endfunction +function! s:ClearSparseTree() + " mylist with lines of matches + let w:sparse_on = 0 + let b:v.sparse_list = [] + " foldlist with line before previous level 1 parent + let b:v.fold_list = [] + set fdm=expr + set foldlevel=1 + execute 1 +endfunction + +function! s:FoldTouch() + " not used right now, since speed increase over + " set fdm=expr is uncertain, and was having problems + " in cleanly undoing it. + " + " touch each line in lists to update their fold levels + let i = 0 + while i < len(b:v.sparse_list) + execute b:v.sparse_list[i] + " insert letter 'b' to force level update and then undo + silent execute "normal! ib" + silent execute "normal! u" + execute b:v.fold_list[i] + silent execute "normal! ib" + silent execute "normal! u" + let i += 1 + endwhile +endfunction + +function! s:OrgIfExpr() + let mypattern = '' + " two wrapper subst statements around middle + " subst are to make dates work properly with substitute/split + " operation + let ifstring_list = [[]] + let test_str = g:org_search_spec + if test_str[0] !~ '[+-]' + let test_str = '+' . test_str + endif + + let ndx=0 + let result_if_list = [] +"try + while 1 +" text string +" curly bracket reg ex string +" numeric comparison +" single operand -- TAG or TODO + + let m = matchlist(test_str,'^\(|' + \ . '\|[+-]\w\{-}[!<>\=]=*".\{-}"' + \ . '\|[+-]\w\{-}[!\=]=*{.\{-}}' + \ . '\|[+-]\w\{-}[=<>!]=*[0-9+-.][0-9.]*' + \ . '\|[+-]\w*\)' + \ . '\(.*\)') + if m[1] == '|' + call add(ifstring_list,[]) + let ndx += 1 + let test_str = m[2] + if test_str !~ '+\|-' + let test_str = '+' . test_str + endif + elseif m[1] ># '' + call add(ifstring_list[ndx],m[1]) + let test_str = m[2] + if test_str == '' + break + endif + else + break + endif + endwhile + + for ifstr in ifstring_list + + let b:v.my_if_list = ifstr + let ifexpr = '' + " okay, right now we have split list with each item prepended by + or - + " now change each item to be a pattern match equation in parens + " e.g.,'( prop1 =~ propval) && (prop2 =~ propval) && (thisline =~tag) + let i = 0 + "using while structure because for structure doesn't allow changing + " items? + while i < len(b:v.my_if_list) + let item = b:v.my_if_list[i] + if item[0] !~ '+\|-' + let item = '+' . item + endif + " Propmatch has '=' sign and something before and after + if item =~ 'TEXT=\S.*' + let mtch = matchlist(item[1:],'\(\S.*\)=\(\S.*\)') + let b:v.my_if_list[i] = "(s:Range_Search('" . mtch[2][1:-2] . "','nbW'," + let b:v.my_if_list[i] .= 'tbegin,tend)> 0)' + let i += 1 + " loop to next item + continue + endif + if item =~ '\S.*[=><]\S.*' + if item =~ '[^<>!]=\\(' + let item = substitute(item,'=','=~','') + elseif item =~ '[^!]={' + let item = substitute(item,'[^!]\zs=','=~','') + let item = substitute(item,'{','"','') + let item = substitute(item,'}','"','') + elseif item =~ '!={' + let item = substitute(item,'!=','!~','') + let item = substitute(item,'{','"','') + let item = substitute(item,'}','"','') + elseif item =~ '[^<>!]=[^=]' + let item = substitute(item,'=','==','') + endif + let pat = '\(\S\{-}\)\(==\|=\~\|!\~\|>=\|<=\|!=\|<\|>\)\(\S.*\)' + let mtch = matchlist(item[1:],pat) + let mtch[1] = toupper(mtch[1]) + if mtch[3] =~ '^[+\-0-9.][0-9.]*$' + " numeric comparison + let b:v.my_if_list[i] = (item[0]=='-' ? '!' : '') . '(get(lineprops,"' . mtch[1] . '") ' . mtch[2]. mtch[3] . ')' + else + " string comparison + let rightside="'".mtch[3][1:-2]."'" + let b:v.my_if_list[i] = (item[0]=='-' ? '!' : '') . '(get(lineprops,"' . mtch[1] . '","") ' . mtch[2]. rightside. ')' + " line below is addd on to exclude headings not + " having an entry at all from the comparison + " \ . '&& (get(lineprops,"' . mtch[1] . '","") != "")' + endif + let i += 1 + " loop to next item + continue + endif + + " it must be a todo or tag item + if item[0] ==? '+' + let op = '=~' + elseif item[0] ==? '-' + let op = '!~' + endif + " if it's in todoitems assume it's a todo search item, not a tag + if index(b:v.todoitems,item[1:]) >= 0 + let item = '(lineprops.TODO ' . op . " '" . item[1:] . "')" + "let item = '(lineprops.TODO ' . op . " '^\\*\\+\\s*" . item[1:] . "')" + let b:v.my_if_list[i] = item + elseif item[1:] =~? 'UNFINISHED_TODO\|UNDONE_TODO' + let item = '(lineprops.TODO ' . op . " '" . b:v.todoNotDoneMatch[11:] . "')" + let b:v.my_if_list[i] = item + elseif item[1:] =~? 'FINISHED_TODO\|DONE_TODO' + let item = '(lineprops.TODO ' . op . " '" . b:v.todoDoneMatch[11:] . "')" + let b:v.my_if_list[i] = item + elseif item[1:] ==? 'ANY_TODO' + let item = '(lineprops.TODO ' . op . " '" . b:v.todoMatch[11:] . "')" + let b:v.my_if_list[i] = item + else + "not a todo so we treat it as a tag item + let item = '(get(lineprops,"TAGS","") ' . op . " ':" . item[1:] . ":')" + let b:v.my_if_list[i] = item + endif + let i += 1 + endwhile + let i = 0 + let b:v.check1 = b:v.my_if_list + let ifexpr = '' + while i < len(b:v.my_if_list) + let ifexpr .= b:v.my_if_list[i] + if i < len(b:v.my_if_list) - 1 + let ifexpr .= ' && ' + endif + let i += 1 + endwhile + + "return ifexpr + call add(result_if_list, ifexpr) + endfor +" let succeeded = 1 +"finally +" if !exists('succeeded') +" return [] +" else + return result_if_list +" endif +endfunction + +function! s:CheckIfExpr(line,ifexpr,...) + " this is 'ifexpr' eval func used for agenda date searches + let headline = s:OrgGetHead_l(a:line) + " 0 arg is to not get start and end line numbers + let lineprops=s:GetProperties(headline,0) + " _thisline_ is variable evaluated in myifexpr + let thisline = getline(headline) + if s:IsTagLine(headline + 1) + let thisline .= ' ' . getline(headline+1) + endif + let result = 0 + for item in a:ifexpr + if eval(item) == 1 + let result = 1 + break + endif + endfor + return result + +endfunction + +function! FileDict() + return s:filedict +endfunction + +function! s:OrgIfExprResults(ifexpr,...) + " ifexpr has single compound expression that will evaluate + " as true only for desired lines + let sparse_search = 0 + if a:0 > 0 + let sparse_search = a:1 + endif + + "let myifexpr = a:ifexpr + + execute 1 + if getline(line('.'))!~ '^\*\+ ' + let headline = s:OrgNextHead() + else + let headline = 1 + endif + let g:checkexpr = a:ifexpr + while 1 + if headline > 0 + execute headline + " _thisline_ is variable evaluated in myifexpr + let thisline = getline(headline) + if s:IsTagLine(headline + 1) + let thisline .= ' ' . getline(headline+1) + endif + " lineprops is main variable tested in 'ifexpr' + " expression that gets evaluated + "let lineprops = s:GetProperties(headline,1) + let lineprops = b:v.org_dict[headline].props + + for if_item in a:ifexpr + " next line is to fix for text area search + " now that we can reference tbegin and tend + let myifexpr = substitute(if_item,'\cTBEGIN,TEND',get(lineprops,'LINE') .','. get(lineprops,'TEND'),"") + " + "******** eval() is what does it all *************** + if eval(myifexpr) + if sparse_search + let keyval = headline + else + "let keyval = s:PrePad(index(s:agenda_files_copy, lineprops.file . '.org'),3,'0') . s:PrePad(headline,5,'0') + "let keyval = s:PrePad(lineprops.file,3,'0') . s:PrePad(headline,5,'0') + let keyval = s:PrePad(s:filenum,3,'0') . s:PrePad(headline,5,'0') + endif + + let g:adict[keyval]=lineprops + if !exists('g:adict[keyval].CATEGORY') + let g:adict[keyval].CATEGORY = b:v.org_dict.iprop(headline,'CATEGORY') + endif + break + endif + endfor + normal l + let headline = s:OrgNextHead() + else + break + endif + endwhile +endfunction + +function! s:MakeResults(search_spec,...) + let s:filedict = copy(g:agenda_files) + let sparse_search = 0 + if a:0 > 0 + let sparse_search = a:1 + endif + let save_cursor = getpos(".") + "let curfile = substitute(expand("%"),' ','\\ ','g') + let curfile = substitute(expand("%:p"),' ','\\ ','g') + let curtab = tabpagenr() + let curwin = winnr() + + let g:org_search_spec = a:search_spec + let g:org_todoitems=[] + let g:adict = {} + let g:datedict = {} + let s:agenda_files_copy = copy(g:agenda_files) + " fix so copy doesn't have full path. . . + "call map(s:agenda_files_copy, 'matchstr(v:val,"[\\/]") > "" ? matchstr(v:val,"[^/\\\\]*$") : v:val') + if sparse_search + call OrgMakeDict() + let ifexpr = s:OrgIfExpr() + call s:OrgIfExprResults(ifexpr,sparse_search) + else + let g:in_agenda_search = 1 + for file in g:agenda_files + "execute 'tab drop ' . file + call org#LocateFile(file) + call org#SaveLocation() + " let bnum = bufnr(file) + " if bnum == -1 + " execute 'tabedit ' . file + " else + " execute 'b' . bnum + " endif + let s:filenum = index(g:agenda_files,file) + if g:org_search_spec =~ '[<>\=!]' + call OrgMakeDict() + else + " it's just todos and/or tags + call OrgMakeDictInherited('get_tags_too') + endif + let ifexpr = s:OrgIfExpr() + let g:org_todoitems = extend(g:org_todoitems,b:v.todoitems) + call s:OrgIfExprResults(ifexpr,sparse_search) + call org#RestoreLocation() + endfor + unlet g:in_agenda_search + "call org#LocateFile(curfile) + execute 'tabnext ' . curtab + execute curwin . 'wincmd w' + endif + call setpos(".",save_cursor) +endfunction +function! s:DaysInMonth(date) + let month = str2nr(a:date[5:6]) + let year = str2nr(a:date[0:3]) + if (month == 2) && (year % 4) + let days = 28 + elseif month == 2 + let days = 29 + elseif index([1,3,5,7,8,10,12],month) >= 0 + let days = 31 + else + let days = 30 + endif + return days +endfunction + +function! s:MakeAgenda(date,count,...) + if a:0 >= 1 + let g:org_search_spec = a:1 + else + let g:org_search_spec = '' + endif + let as_today = '' + if a:0 >= 2 + let as_today = a:2 + endif + + "call org#SaveLocation() + let curtab = tabpagenr() + let curwin = winnr() + + let l:count = a:count + if l:count ==? 'd' | let l:count = 1 | endif + if l:count ==? 'w' + let g:agenda_startdate = calutil#cal(calutil#jul(a:date) - calutil#dow(a:date)) + let g:org_agenda_days=7 + elseif l:count ==? 'm' + let g:agenda_startdate = a:date[0:7].'01' + let g:org_agenda_days = s:DaysInMonth(a:date) + elseif l:count ==? 'y' + let g:agenda_startdate = a:date[0:3].'-01-01' + let g:org_agenda_days = ( a:date[0:3] % 4 == 0 ) ? 366 : 365 + else + let g:agenda_startdate = a:date + let g:org_agenda_days = l:count + endif + if l:count == 1 | let as_today = g:agenda_startdate | endif + let g:adict = {} + let s:filedict = copy(g:agenda_files) + let s:agenda_files_copy = copy(g:agenda_files) + let g:datedict = {} + call s:MakeCalendar(g:agenda_startdate,g:org_agenda_days) + let g:in_agenda_search=1 + for file in g:agenda_files + call org#LocateFile(file) + call org#SaveLocation() + " for now g:org_search_spec is limited to tags and + " todo prop which are part of OrgMakeDictInherited + " If ever want to expand to general props can + " add OrgMakeDict() + call OrgMakeDictInherited() + let s:filenum = index(g:agenda_files,file) + let t:agenda_date=a:date + if as_today ># '' + call s:GetDateHeads(g:agenda_startdate,g:org_agenda_days,as_today) + else + call s:GetDateHeads(g:agenda_startdate,g:org_agenda_days) + endif + call org#RestoreLocation() + endfor + unlet g:in_agenda_search + + "call org#RestoreLocation() + exec 'tabnext ' . curtab + exec curwin . 'wincmd w' + +endfunction + +function! s:NumCompare(i1, i2) + return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1 +endfunc + +function! OrgRunSearch(search_spec,...) + "set mouseshape-=n:busy,v:busy,i:busy + if bufnr('Calendar') > 0 + execute 'bw!' . bufnr('Calendar') + endif + + try + + if bufnr('__Agenda__') >= 0 + "bwipeout __Agenda__ + endif + + let g:agenda_head_lookup={} + let sparse_search = 0 + let search_type = '' + if a:0 > 0 + if a:1 == 1 + let sparse_search = a:1 + else + let search_type=a:1 + endif + endif + let g:adict={} + let g:agenda_date_dict={} + if !exists("g:agenda_files") || (g:agenda_files == []) + if has('dialog_con') || has('dialog_gui') + unsilent call confirm("No agenda files defined. Will add current file to agenda files.") + endif + call s:CurfileAgenda() + endif + if exists('b:v.sparse_list') && (len(b:v.sparse_list) > 0) + call s:ClearSparseTree() + endif + call s:MakeResults(a:search_spec,sparse_search) + + if sparse_search + call s:ResultsToSparseTree() + else + call s:ResultsToAgenda( search_type ) + endif + + finally + "set mouseshape-=n:busy,v:busy,i:busy + endtry +endfunction +function! s:ResultsToAgenda( search_type ) + " FOR OrgRunSearch() + ":AAgenda + :EditAgenda + let b:v={} + call s:AgendaBufSyntax() + set nowrap + + call s:DoAgendaMaps() + + let i = 0 + call s:ADictPlaceSigns() + let b:v.heading_marks_dict = {} + "call setline(line('$'), ["Headlines matching search spec: ".g:org_search_spec,'']) + let lines = [] + let lines = lines + ["Headlines matching search spec: ".g:org_search_spec,''] + if a:search_type ==? 'agenda_todo' + let msg = "Press r to re-search: " + let numstr= '' + nmap r :call OrgRunSearch(g:org_search_spec,'agenda_todo') + let tlist = ['ANY_TODO','UNFINISHED_TODOS', 'FINISHED_TODOS'] + s:Union(g:org_todoitems,[]) + for item in tlist + let num = index(tlist,item) + let numstr .= '('.num.')'.item.' ' + execute "nmap ".num."r :silent call OrgRunCustom({'redo_num':line('.'), 'type':'tags-todo', 'spec':'". tlist[num] . "'})" + endfor + "call add(lines,split(msg.numstr,'\%72c\S*\zs ')) + let lines = lines + split(msg.numstr,'\%72c\S*\zs ') + call add(lines,'') + endif + for key in sort(keys(g:adict)) + call add(lines , key . ' ' . + \ printf("%-12.12s",g:adict[key].CATEGORY ) . ' ' . + \ s:PrePad(matchstr(g:adict[key].ITEM,'^\*\+ '),8) . + \ matchstr(g:adict[key].ITEM,'\* \zs.*$')) + let i += 1 + endfor + call append(s:agenda_insert_point,lines) +endfunction +function! s:ToFromAgenda() + if bufname('%') == '__Agenda__' + for i in range(1, winnr('$')) + exe i . 'wincmd w' + if bufname('%') !~ '__Agenda__\|__Calendar' + break + endif + endfor + "windo if bufname('%') !~ '__Agenda__\|__Calendar' | let return | endif + elseif bufwinnr('__Agenda__') > 0 + exec bufwinnr('__Agenda__') . 'wincmd w' + endif +endfunction +function! s:DoAgendaMaps() + execute "source " . s:sfile . '/vimorg-agenda-mappings.vim' + + command! -buffer -nargs=* Agenda :call OrgAgendaCommand() + + " user can have a function in their vimrc to have their own + " agenda mappings + if exists('*OrgCustomAgendaMaps') + call OrgCustomAgendaMaps() + endif +endfunction + +function! s:OrgAgendaTab() + if getline(line(".")) !~ '^\d\+' + return + endif + let thisline = getline(line('.')) + let file = s:agenda_files_copy[str2nr(matchstr(thisline, '^\d\d\d'))] + if bufwinnr(file) == -1 + call s:OrgAgendaToBuf() + else + call s:MoveToHeadingFromAgenda(line('.')) + if b:v.chosen_agenda_heading != line('.') + "back to agenda and do agendatobuf from there + call org#LocateFile('__Agenda__') + call s:OrgAgendaToBuf() + else + " we're in file buffer, ready to cycle + call s:OrgCycle(line('.')) + call org#LocateFile('__Agenda__') + endif + endif +endfunction +function! s:ToggleHeadingMark(line) + let line = a:line + if (bufname('%') == '__Agenda__' && getline(line) !~ '^\d\{8}\s') + \ || ((&filetype == 'org') && getline(line) !~ b:v.headMatch) + return + endif + let list_item = get(b:v.heading_marks_dict, line) + if list_item == 0 + let b:v.heading_marks_dict[line] = 1 + execute "sign place " . line('.') . " line=" . line('.') . " name=marked buffer=".bufnr("%") + else + unlet b:v.heading_marks_dict[line] + execute "sign unplace " . line('.') . " buffer=".bufnr("%") + endif +endfunction +function! s:DeleteHeadingMarks() + if bufname('%')=='__Agenda__' + for item in keys(b:v.heading_marks_dict) + execute "sign unplace " . item . " buffer=".bufnr("%") + endfor + else + sign unplace * + endif + let b:v.heading_marks = [] + let b:v.heading_marks_dict = {} +endfunction +function! s:ResultsToSparseTree() + "call s:ClearSparseTree() + let w:sparse_on = 1 + let temp = [] + for key in keys(g:adict) + call add(temp,g:adict[key].LINE) + endfor + let b:v.sparse_list = sort(temp,'s:NumCompare') + "for key in keys(g:adict) + " call add(b:v.sparse_heads,str2nr(key)) + "endfor + "for item in sort(b:v.sparse_heads,'NumCompare') + call sort(b:v.fold_list,"s:NumCompare") + call s:SparseTreeDoFolds() + "for item in sort(b:v.fold_list,'NumCompare') + set fdm=expr + set foldlevel=0 + call clearmatches() + for item in b:v.sparse_list + if item > 11 + execute item - g:org_sparse_lines_after + normal! zv + call matchadd('Search','\%' . (item - g:org_sparse_lines_after) . 'l') + endif + endfor + execute 1 +endfunction + +function! s:TestTime() + let g:timestart=join(reltime(), ' ') + let g:start = strftime("%") + let i = 0 + set fdm=expr + let g:timefinish=join(reltime(), ' ') + echo g:timestart . ' --- ' . g:timefinish +endfunction +function! s:TestTime2(fu) + let g:timestart=join(reltime(), ' ') + let g:start = strftime("%") + let i = 0 + execute a:fu + let g:timefinish=join(reltime(), ' ') + echo g:timestart . ' --- ' . g:timefinish +endfunction + +function! s:ADictPlaceSigns() + let myl=[] + call s:DeleteSigns() " signs were placed during search + for key in keys(g:adict) + let headline = matchstr(key,'^\d\d\d\zs\d\+') + let filenum = str2nr(key[0:2]) + let buf = bufnr(s:agenda_files_copy[filenum]) + try + silent execute "sign place " . headline . " line=" + \ . headline . " name=piet buffer=" . buf + catch + echo "ERROR: headline " . headline . ' and buf ' .buf + echo key .', '. matchstr(key,'^.*\ze_\d\+$') + finally + endtry + endfor +endfunction +function! s:DateDictPlaceSigns() + let myl=[] + call s:DeleteSigns() " signs were placed in GetDateHeads + for key in keys(g:agenda_date_dict) + let myl = get(g:agenda_date_dict[key], 'l') + if len(myl) > 0 + for item in myl + let dateline = matchstr(item,'^\d\d\d\zs\d\+') + let filenum = str2nr(item[0:2]) + let buf = bufnr(s:agenda_files_copy[filenum]) + try + silent execute "sign place " . dateline . " line=" + \ . dateline . " name=piet buffer=" . buf + catch + echo "ERROR: headline " . headline . ' and buf ' . buf . ' and dateline ' . dateline + + echo (matchstr(item,'^\d\+\s\+\zs\S\+') . '.org') + finally + endtry + endfor + endif + endfor +endfunction + +function! s:DateDictToScreen() + ":%d "delete all lines + let lines = ["Press or for next or previous period, q to close agenda," , + \ " on a heading to synch main file, to goto line," , + \ " to cycle heading text, to cycle Todos.",''] + let search_spec = g:org_search_spec ># '' ? g:org_search_spec : 'None - include all heads' + let d = g:org_agenda_days + let start_week = 'W' . org#ISODateToYWD(g:agenda_startdate)[1] + let end_date = calutil#cal(calutil#jul(g:agenda_startdate)+g:org_agenda_days-1) + let end_week = 'W' . org#ISODateToYWD(end_date)[1] + if d==1 | let type = 'Day-agenda (' . start_week . '):' + elseif d==7 | let type = 'Week-agenda (' . start_week . '):' + elseif (d>27 && d<32) | let type = 'Month-agenda (' . start_week . '-' . end_week . '):' + elseif (d>364 && d<366) | let type = 'Year-agenda:' + else | let type = 'Agenda:' + endif + + call add(lines,"Agenda view for " . g:agenda_startdate + \ . " to ". calutil#cal(calutil#jul(g:agenda_startdate)+g:org_agenda_days-1) + \ . ' matching FILTER: ' . search_spec ) + call add(lines,'') + call add(lines,type) + + call s:DateDictPlaceSigns() + let b:v.heading_marks_dict = {} + let gap = 0 + let mycount = len(keys(g:agenda_date_dict)) + for key in sort(keys(g:agenda_date_dict)) + if empty(g:agenda_date_dict[key].l) + let gap +=1 + call add(lines, g:agenda_date_dict[key].marker) + else + if (gap > g:org_agenda_skip_gap) && (g:org_agenda_minforskip <= mycount) + call remove(lines, len(lines)-gap, -1 ) + let lines = lines + ['',' [. . . ' .gap. ' empty days omitted ]',''] + endif + let gap = 0 + call add(lines, g:agenda_date_dict[key].marker) + if ((g:org_agenda_days == 1) || (key == strftime("%Y-%m-%d"))) && exists('g:org_timegrid') && (g:org_timegrid != []) + let lines = lines + s:PlaceTimeGrid(g:agenda_date_dict[key].l) + else + let lines = lines + g:agenda_date_dict[key].l + endif + endif + endfor + + if (gap > g:org_agenda_skip_gap) && (g:org_agenda_minforskip <= mycount) + call remove(lines, len(lines)-gap, -1 ) + let lines = lines + ['',' [. . . ' .gap. ' empty days omitted ]',''] + endif + " finally, place all the prepared result lines in agenda buffer + call append(s:agenda_insert_point-1, lines) +endfunction +function! s:TimeGridSort(s1, s2) + return (a:s1[23:] == a:s2[23:]) ? 0 : (a:s1[23:] > a:s2[23:]) ? 1 : -1 +endfunction +function! s:PlaceTimeGrid(lines) + let lines = a:lines + " assemble timegrid for agenda view + if lines[0] =~ '\%24c\d\d:\d\d' + "if, at least one time item put grid lines in and sort with other time items + let grid = s:TimeGrid(g:org_timegrid[0],g:org_timegrid[1],g:org_timegrid[2]) + let lines = grid + lines + let i = len(grid) - 1 + while ((i < len(lines)) && matchstr(lines[i],'\%24c\d\d:\d\d') ) + let i += 1 + endwhile + let lines = sort(lines[0:i-1], 's:TimeGridSort') + lines[i :] + " now delete duplicates where grid is same as actual entry + " skip this part until rest is working. . . + "let i = 0 + "while i < len(lines) + " let match1 = matchstr(getline(line('.')),'\%24c.*\%29c') + " let match2 = matchstr(getline(line('.')-1),'\%24c.*\%29c') + " if match1 ==? match2 + " if match1[0] ==? ' ' + " normal ddk + " else + " normal kdd + " endif + " endif + " exec line('.')-1 + "endwhile + endif + return lines +endfunction +function! OrgRunAgenda(date,count,...) + try + + if bufname('%') ==? '__Agenda__' + "wincmd k + endif + let g:agenda_head_lookup={} + let win = bufwinnr('Calendar') + let file = expand('%:p') + if win >= 0 + execute win . 'wincmd w' + normal ggjjj + wincmd l + execute 'bw!' . bufnr('Calendar') + + endif + if !exists("g:agenda_files") || (g:agenda_files == []) + unsilent call confirm("No agenda files defined. Will add current file to agenda files.") + call s:CurfileAgenda() + endif + if exists('b:v.sparse_list') && (len(b:v.sparse_list) > 0) + call s:ClearSparseTree() + endif + " a:1 is search_spec, a:2 is "today" for search + if a:0 == 1 + call s:MakeAgenda(a:date,a:count,a:1) + elseif a:0 == 2 + call s:MakeAgenda(a:date,a:count,a:1,a:2) + else + call s:MakeAgenda(a:date,a:count) + endif + AAgenda + call s:SetupDateAgendaWin() + "we are no in newly created agenda buf/window + + for key in keys(g:agenda_date_dict) + call sort(g:agenda_date_dict[key].l, 's:AgendaCompare') + endfor + call s:DateDictToScreen() + if win >= 0 + let year = matchstr(t:agenda_date,'\d\d\d\d') + let month = matchstr(t:agenda_date,'\d-\zs\d\d\ze-') + execute 'Calendar ' . year .' '. str2nr(month) + execute bufwinnr('Agenda').'wincmd w' + endif + " we're in agenda, do rigamarole to get top column heading window, + " if any, back to zero height + let curheight=winheight(0) + call org#LocateFile(file) + "wincmd k + resize + call org#LocateFile('__Agenda__') + "wincmd j + execute 1 + execute 'resize ' . curheight + + finally + "set mouseshape-=n:busy,v:busy,i:busy + endtry + +endfunction +function! OrgRunCustom(arg) + call s:RunCustom(a:arg) +endfunction +function! s:SetupDateAgendaWin() + EditAgenda + let b:v={} + call s:AgendaBufSyntax() + set nowrap + call s:DoAgendaMaps() + + command! -buffer -nargs=* Agenda :call OrgAgendaCommand() + +endfunction + +function! OrgRefreshCalendarAgenda() + let g:org_search_spec = matchstr(getline(5),'FILTER:\s*\zs.*$') + if g:org_search_spec =~ '\c^None' + let g:org_search_spec = '' + endif + call OrgRunCustom({'redo_num': line('.'),'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration': g:org_agenda_days, 'spec': g:org_search_spec}) +endfunction +function! s:Resize() + let cur = winheight(0) + resize + resize cur +endfunction + +function! s:GetDateHeads(date1,count,...) + " a:1 is date for warnings + let save_cursor=getpos(".") + if g:org_search_spec ># '' + let b:v.agenda_ifexpr = s:OrgIfExpr() + endif + let g:date1 = a:date1 + let date1 = a:date1 + let date2 = calutil#Jul2Cal(calutil#Cal2Jul(split(date1,'-')[0],split(date1,'-')[1],split(date1,'-')[2]) + a:count) + execute 1 + while search('[^-][[<]\d\d\d\d-\d\d-\d\d','W') > 0 + "if ((g:org_search_spec ># '') && (s:CheckIfExpr(line("."),b:v.agenda_ifexpr)==0)) + " continue + "endif + let repeatlist = [] + let line = getline(line(".")) + let datematch = matchstr(line,'[[<]\d\d\d\d-\d\d-\d\d\ze') + let repeatmatch = matchstr(line, '<\d\d\d\d-\d\d-\d\d.*[ +.]+\d\+\S\+.*>\ze') + if repeatmatch != '' + " if date has repeater then call once for each repeat in period + let repeatlist = s:RepeatMatch(repeatmatch[1:],date1,date2) + for dateitem in repeatlist + if a:0 == 1 + call s:ProcessDateMatch(dateitem,date1,date2,a:1) + else + call s:ProcessDateMatch(dateitem,date1,date2) + endif + endfor + else + if (datematch[0]!='[') || g:org_clocks_in_agenda + if a:0 == 1 + call s:ProcessDateMatch(datematch[1:],date1,date2,a:1) + else + call s:ProcessDateMatch(datematch[1:],date1,date2) + endif + endif + endif + "endif + endwhile + call setpos(".",save_cursor) +endfunction + +function! s:ProcessDateMatch(datematch,date1,date2,...) + if a:0 > 0 + let today = a:1 + else + let today = strftime("%Y-%m-%d") + endif + let datematch = a:datematch + let rangedate = matchstr(getline(line(".")),'--<\zs\d\d\d\d-\d\d-\d\d') + + let locator = s:PrePad(s:filenum,3,'0') . s:PrePad(line('.'),5,'0') . ' ' + + let g:myline = s:OrgGetHead_l(line('.')) + "let g:myline = s:OrgParentHead_l(line('.')) + "if g:myline == 0 + " let filename = org#Pad(b:v.org_dict[g:myline].CATEGORY,13) + "else + "let filename = org#Pad(b:v.org_dict.iprop(g:myline,'CATEGORY'),12) . ' ' + let filename = printf("%-12.12s",b:v.org_dict.iprop(g:myline,'CATEGORY')) . ' ' + "endif + let line = getline(line(".")) + let date1 = a:date1 + let date2 = a:date2 + let s:headline=0 + if (datematch >= date1) && (datematch < date2) + \ && ((g:org_search_spec ==# '') || (s:CheckIfExpr(line("."),b:v.agenda_ifexpr))) + let mlist = matchlist(line,'\(DEADLINE\|SCHEDULED\|CLOSED\)') + call s:SetHeadInfo() + if empty(mlist) + " it's a regular date, first check for time parts + let tmatch = matchstr(line,' \zs\d\d:\d\d\ze.*[[>]') + if tmatch ># '' + let tmatch2 = matchstr(line,'<.\{-}-\zs\d\d:\d\d\ze.*>') + if tmatch2 ># '' + let tmatch .= '-' . tmatch2 + else + if match(line,':\s*CLOCK\s*:') >= 0 + let tmatch .= '-'.matchstr(line,'--\[.\{-}\zs\d\d:\d\d\ze\]') + let s:headtext = s:headtext[0:6] . 'Clocked: ('.matchstr(line,'->\s*\zs.*$') .') '.s:headtext[7:] + else + let tmatch .= '......' + endif + endif + endif + call add(g:agenda_date_dict[datematch].l, locator . filename . org#Pad(tmatch,11) . s:headtext) + "call add(g:agenda_date_dict[datematch].l, line(".") . repeat(' ',6-len(line("."))) . filename . org#Pad(tmatch,11) . s:headtext) + if rangedate != '' + "let startdate = matchstr(line,'<\zs\d\d\d\d-\d\d-\d\d\ze') + "let thisday = calutil#jul(datematch) - calutil#jul(startdate) + 1 + let days_in_range = calutil#jul(rangedate) - calutil#jul(datematch) + 1 + "let rangestr = '('.thisday.'/'.days_in_range.')' + let i = days_in_range + "while (rangedate < date2) && (rangedate > datematch) + while (rangedate > datematch) + let rangestr = '('.i.'/'.days_in_range.')' + if exists("g:agenda_date_dict['".rangedate."']") + "call add(g:agenda_date_dict[rangedate].l, line(".") . repeat(' ',6-len(line("."))) . + call add(g:agenda_date_dict[rangedate].l, locator . + \ filename . org#Pad(rangestr,11) . s:headtext) + endif + let rangedate = calutil#cal(calutil#jul(rangedate) - 1) + let i = i - 1 + endwhile + " to end of line to avoid double + " treatment + normal $ + endif + else + " it's a deadline/scheduled/closed date + let type = org#Pad(mlist[1][0] . tolower(mlist[1][1:]) . ':' , 11) + call add(g:agenda_date_dict[datematch].l, locator . filename . type . s:headtext) + endif + endif + " Now test for late and upcoming warnings if 'today' is in range and not + " a done-type todo + if (today >= date1) && (today < date2) && (getline(g:myline) !~ b:v.todoDoneMatch) + if (datematch < today) && (match(line,'\(DEADLINE\|SCHEDULED\)')>-1) + \ && ((g:org_search_spec ==# '') || (s:CheckIfExpr(line("."),b:v.agenda_ifexpr))) + let mlist = matchlist(line,'\(DEADLINE\|SCHEDULED\)') + call s:SetHeadInfo() + if !empty(mlist) + let dayspast = calutil#jul(today) - calutil#jul(datematch) + if mlist[1] ==? 'DEADLINE' + let newpart = org#Pad('In',6-len(dayspast)) . '-' . dayspast . ' d.:' + else + let newpart = org#Pad('Sched:',9-len(dayspast)) . dayspast . 'X:' + endif + call add(g:agenda_date_dict[today].l, locator . filename . newpart . s:headtext) + endif + " also put in warning entry for deadlines when appropriate + elseif (datematch > today) && (match(line,'DEADLINE')>-1) + \ && ((g:org_search_spec ==# '') || (s:CheckIfExpr(line("."),b:v.agenda_ifexpr))) + let mlist = matchlist(line,'DEADLINE') + call s:SetHeadInfo() + if !empty(mlist) + let daysahead = calutil#jul(datematch) - calutil#jul(today) + let g:specific_warning = str2nr(matchstr(line,'<\S*\d\d.*-\zs\d\+\zed.*>')) + if (daysahead <= g:org_deadline_warning_days) || (daysahead <= g:specific_warning) + let newpart = org#Pad('In',7-len(daysahead)) . daysahead . ' d.:' + call add(g:agenda_date_dict[today].l, locator . filename . newpart . s:headtext) + endif + endif + endif + endif + " finally handle things for a range that began before date1 + if (rangedate != '') && (datematch < date1) + \ && ((g:org_search_spec ==# '') || (s:CheckIfExpr(line("."),b:v.agenda_ifexpr))) + let days_in_range = calutil#jul(rangedate) - calutil#jul(datematch) + 1 + if rangedate >= date2 + let last_day_to_add = calutil#jul(date2) - calutil#jul(datematch) + let rangedate = calutil#cal(calutil#jul(date2)-1) + else + let last_day_to_add = days_in_range + endif + + call s:SetHeadInfo() + let i = last_day_to_add + while (rangedate >= date1) + let rangestr = '('.i.'/'.days_in_range.')' + call add(g:agenda_date_dict[rangedate].l, locator . + \ filename . org#Pad(rangestr,11) . s:headtext) + let rangedate = calutil#cal(calutil#jul(rangedate) - 1) + let i = i - 1 + endwhile + " go past match to avoid double treatment + normal $ + endif + if s:headline > 0 + let g:agenda_head_lookup[line(".")]=s:headline + endif +endfunction + +function! s:SetHeadInfo() + let s:headline = s:OrgGetHead_l(line(".")) + let s:headtext = getline(s:headline) + let s:mystars = matchstr(s:headtext,'^\*\+') + let s:headstars = s:PrePad(s:mystars,6) + let s:headtext = s:headstars . ' ' . s:headtext[len(s:mystars)+1:] +endfunction + +function! s:RepeatMatch(rptdate, date1, date2) + let yearflag = 0 + let basedate = matchstr(a:rptdate,'\d\d\d\d-\d\d-\d\d') + if basedate >= a:date2 + " no need for repeat, rturn to check fo deadlien warnings + return [basedate] + endif + let date1 = a:date1 + if basedate > date1 + let date1 = basedate + endif + let baserpt = matchstr(a:rptdate, ' \S\S\S [.+]\{0,1}+\zs\S\+\ze.*>') + let rptnum = matchstr(baserpt, '^\d\+') + let rpttype = matchstr(baserpt, '^\d\+\zs.') + let g:rptlist = [] + let date1jul = calutil#jul(date1) + let date2jul = calutil#jul(a:date2) + if rpttype ==? 'w' + let rpttype = 'd' + let rptnum = str2nr(rptnum)*7 + endif + if rpttype ==? 'y' + let rpttype = 'm' + let rptnum = str2nr(rptnum)*12 + let yearflag = 1 + endif + if rpttype ==? 'd' + let dmod = (date1jul - calutil#jul(basedate)) % rptnum + let i = 0 + while 1 + let testjul = date1jul - dmod + (i*rptnum) + if testjul < date2jul + call add(g:rptlist, calutil#cal(testjul)) + else + break + endif + let i += 1 + endwhile + elseif rpttype ==? 'm' + let g:special = baserpt[-1:] + let monthday = str2nr(basedate[8:]) + let baseclone = basedate + " this if-structure assigns begin test month as + " first repeat month _before_ date1 + if yearflag + if (date1[:6]) >= (date1[:3] . baseclone[4:6]) + let baseclone = date1[:3] . baseclone[4:] + else + let baseclone = string(str2nr(date1[:3]) - 1) . baseclone[4:] + endif + let first_of_month_jul = calutil#jul(baseclone[:7]. '01') + else + let first_of_month_jul = calutil#jul(date1[:4] . + \ s:Pre0( date1[5:6] ) . '-01') + "\ s:Pre0( date1[5:6] - 1) . '-01') + endif + + if g:special ==? '*' + let specialnum = (monthday / 7) + 1 + let specialdaynum = calutil#dow(basedate) + endif + while 1 + if g:special != '*' + let testjul = first_of_month_jul - 1 + monthday + else + " process for 'xth weekday of month' type + let fdow = calutil#dow(calutil#cal(first_of_month_jul)) + if fdow == specialdaynum + let testjul = first_of_month_jul + (specialnum-1)*7 + elseif fdow < specialdaynum + let testjul = first_of_month_jul + (specialnum-1)*7 + \ + (specialdaynum - fdow) + elseif fdow > specialdaynum + let testjul = first_of_month_jul + (specialnum*7) + \ - (fdow - specialdaynum) + endif + endif + + if (testjul < date2jul) && (testjul >= first_of_month_jul) + call add(g:rptlist, calutil#cal(testjul)) + else + "put in this one to check for deadline warnings + "if len(g:rptlist)>0 + call add(g:rptlist, calutil#cal(testjul)) + "endif + break + endif + let first_cal = calutil#cal(first_of_month_jul) + let nextmonth = str2nr(first_cal[5:6]) + rptnum + let year = str2nr(first_cal[0:3]) + if nextmonth >= 13 + let nextmonth = (nextmonth-12) + let year += 1 + endif + let first_of_month_jul = calutil#jul(string(year) . '-' . s:Pre0(nextmonth) . '-01') + endwhile + endif + + return g:rptlist + +endfunction + +function! s:BufMinMaxDate() + let b:v.MinMaxDate=['2099-12-31','1900-01-01'] + g/<\d\d\d\d-\d\d-\d\d/call s:CheckMinMax() + +endfunction +function! s:CheckMinMax() + let date = matchstr(getline(line(".")),'<\zs\d\d\d\d-\d\d-\d\d') + if (date < b:v.MinMaxDate[0]) + let b:v.MinMaxDate[0] = date + endif + if (date > b:v.MinMaxDate[1]) + let b:v.MinMaxDate[1] = date + endif +endfunction +function! s:Timeline(...) + if a:0 > 0 + let spec = a:1 + else + let spec = '' + endif + if bufname("%") ==? '__Agenda__' + "go back up to main org buffer + "wincmd k + endif + if exists('g:org_search_spec') + let prev_spec = g:org_search_spec + endif + if exists('g:agenda_files') + let prev_files = g:agenda_files + endif + exec "let g:agenda_files=['".substitute(expand("%:p"),' ','\\ ','g')."']" + call s:BufMinMaxDate() + let num_days = 1 + calutil#jul(b:v.MinMaxDate[1]) - calutil#jul(b:v.MinMaxDate[0]) + try + "AAgenda + call OrgRunAgenda(b:v.MinMaxDate[0], num_days,spec) + finally + if exists('prev_spec') + let g:org_search_spec = prev_spec + endif + if exists('prev_files') + let g:agenda_files = prev_files + endif + endtry +endfunction + +function! s:Pre0(s) + return repeat('0',2 - len(a:s)) . a:s +endfunction + +function! s:PrePad(s,amt,...) + if a:0 > 0 + let char = a:1 + else + let char = ' ' + endif + return repeat(char,a:amt - len(a:s)) . a:s +endfunction +function! s:AgendaCompare(i0, i1) + let mymstr = '^\(\d\+\)\s\+\(\S\+\)\s\+\(\%24c.\{11}\).*\(\*\+\)\s\(.*$\)' + " mymstr below would be better match string regex, but generic dates + " have no text at position 24 to match \S . . . " + "let mymstr = '^\(\d\+\)\s\+\(\S\+\)\s\+\(\S.\{10}\).*\(\*\+\)\s\(.*$\)' + " [1] is lineno, [2] is file, [3] is scheduling, [4] is levelstarts, + " [5] is headtext + let cp0 = matchlist(a:i0,mymstr) + let cp1 = matchlist(a:i1,mymstr) + let myitems = [cp0, cp1] + let sched_comp = [] + let i = 0 + while i < 2 + let item = myitems[i] + if item[3][0] ==? 'S' + if item[3][5] ==? ':' + "let str_ord = 'a' . substitute(item[3][6:8],' ', '0','') + let str_ord = 'aa' . s:PrePad(1000-str2nr(item[3][6:8]),' ', '0') + else + let str_ord = 'ab000' + endif + elseif item[3][0] ==? 'I' + if matchstr(item[3],'-') ># '' + let str_ord = 'd-'.s:PrePad(1000-str2nr(matchstr(item[3],'\d\+')),3,'0') + else + let str_ord = 'da'.s:PrePad(matchstr(item[3],'\d\+'),3,'0') + endif + elseif item[3][0] ==? 'D' + let str_ord = 'd0000' + elseif item[3][0] ==? ' ' + let str_ord = 'zzzzz' + else + let str_ord = item[3][:4] + endif + call add(sched_comp,str_ord.item[2].s:PrePad(item[1],5,'0')) + let i += 1 + endwhile + + return sched_comp[0] ==? sched_comp[1] ? 0 : sched_comp[0] > sched_comp[1] ? 1 : -1 + +" let num1 = str2nr(matchstr(a:i1,'In *\zs[ -]\d\+\ze d.:')) +" let num2 = str2nr(matchstr(a:i2,'In *\zs[ -]\d\+\ze d.:')) +" if num1 == 0 +" let num1 = str2nr(matchstr(a:i1,'Sched: *\zs\d\+\zeX:')) +" if num1 !=0 +" let num1 = -num1 - 10000 +" endif +" endif +" if num2 == 0 +" let num2 = str2nr(matchstr(a:i2,'Sched: *\zs\d\+\zeX:')) +" if num2 !=0 +" let num2 = -num2 - 10000 +" endif +" endif +" if (a:i1 =~ '^\d\+\s\+\S\+\s\+\d') +" let num1=num1-20000 +" endif +" if (a:i2 =~ '^\d\+\s\+\S\+\s\+\d') +" let num2=num2-20000 +" endif + +" return num1 == num2 ? 0 : num1 > num2 ? 1 : -1 + +endfunc + +function! s:DateListAdd(valdict) + let namelist = [' GENERAL','SCHEDULED','CLOSED','DEADLINE'] + let templist = [] + call add(templist, get(a:valdict,'ud',0)) + call add(templist, get(a:valdict,'sd',0)) + call add(templist, get(a:valdict,'cd',0)) + call add(templist, get(a:valdict,'dd',0)) + let i = 0 + while i < 4 + if templist[i] != 0 + call add(g:org_datelist, templist[i] . ' ' . namelist[i] . ' ' . a:valdict.l ) + endif + let i += 1 + endwhile + return a:valdict +endfunction + +function! OrgAgendaMove(direction,count) + " need to add functionaity for count, refactor + let cnt = (a:count == 0) ? 1 : a:count + let cnt = (a:direction ==? 'forward') ? cnt : -cnt + let date_jul = calutil#jul(g:agenda_startdate) + let ymd_list = split(g:agenda_startdate,'-') + + if g:org_agenda_days == 1 + let g:agenda_startdate = calutil#cal(date_jul + (cnt * 1)) + elseif g:org_agenda_days == 7 + let g:agenda_startdate = calutil#cal(date_jul + (cnt * 7)) + elseif g:org_agenda_days >= 360 + let g:agenda_startdate = string(ymd_list[0] + (cnt * 1)) .'-01-01' + else + let ymd_list[1] = ymd_list[1] + (cnt * 1) + if ymd_list[1] > 0 + let ymd_list[0] += ymd_list[1] / 12 + let ymd_list[1] = ymd_list[1] % 12 + else + let ymd_list[0] += (ymd_list[1] / 12) - 1 + let ymd_list[1] = 12 + (ymd_list[1] % 12) + endif + let g:agenda_startdate = ymd_list[0] . '-' . + \ s:Pre0(string(ymd_list[1])) .'-01' + let g:org_agenda_days = s:DaysInMonth(g:agenda_startdate) + endif + + if g:org_agenda_days == 1 + "call OrgRunAgenda(g:agenda_startdate,g:org_agenda_days,g:org_search_spec,g:agenda_startdate) + call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration': g:org_agenda_days, 'spec': g:org_search_spec}) + else + "call OrgRunAgenda(g:agenda_startdate,g:org_agenda_days,g:org_search_spec) + call s:RunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration': g:org_agenda_days ,'spec': g:org_search_spec}) + endif +endfunction + +function! s:TimeGrid(starthour,endhour,inc) + let result = [] + for i in range(a:starthour, a:endhour,a:inc) + call add(result,repeat(' ',23).s:Pre0(i).':00...... ------------') + endfor + return result +endfunction + +function! s:MakeCalendar(date, daycount) + "function! s:MakeCalendar(year, month, day, daycount) + " this function is taken from vim tip by Siegfried Bublitz + " at: http://vim.wikia.com/wiki/Generate_calendar_file + " with many mods to 1.output to list rather than to buffer + " and 2. get weekday and weekno from calutils + let g:agenda_date_dict = {} + let g:agenda_head_lookup = {} + "let startdate = calutil#Jul2Cal((calutil#Cal2Jul(a:year,a:month,a:day) - calutil#DayOfWeek(a:year,a:month,a:day))) + let year = split(a:date,'-')[0] + let month = split(a:date,'-')[1] + let day = split(a:date,'-')[2] + let day = str2nr(day) + + if a:daycount == 7 + let wd = 1 + elseif (a:daycount>=28) && (a:daycount <=31) + let wd = calutil#dow(a:date[0:7].'01') + 1 + else + let wd = calutil#dow(a:date) + 1 + endif + let week = 1 + (calutil#Cal2Jul(year,month,day) - calutil#Cal2Jul(year,1,1)) / 7 + let index = 0 + let datetext = '' + let diy = 777 " day in year, wrong before next year + while (index < a:daycount) " no of days to output + let diy = diy + 1 + if (wd > 7) + let wd = 1 + let week = week + 1 + if (week >= 53) + if (week >= 54) + let week = 1 + elseif (day >= 28 || day <= 3) + let week = 1 + endif + endif + endif + let monthnames=['January','February','March','April','May','June','July', + \ 'August','September','October','November','December'] + "let daynames = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'] + let daynames = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'] + let dn = daynames[wd-1] + if ((day > 31) || (month == 2 && (day > 29 || day > 28 && year % 4)) + \ || (month == 4 && day > 30) || (month == 6 && day > 30) + \ || (month == 9 && day > 30) || (month == 11 && day > 30)) + let day = 1 + let month = month + 1 + if (month > 12) + let month = 1 + let diy = 1 + let year = year + 1 + if (wd <= 3) + let week = 1 + endif + endif + endif + + let datetext = dn . repeat(' ',10-len(dn)) . (day<10?' ':' ') . + \ day . ' ' . monthnames[month-1] . ' ' . year . (wd == 1 ? ' Wk' . week : '' ) + + let g:agenda_date_dict[year . '-' . s:Pre0(month) . '-' . (day<10 ? '0'.day : day) ] + \ = {'marker': datetext, 'l': [] } + let index = index + 1 + let day = day + 1 + let wd = wd + 1 + endwhile + +endfunction + +function! s:ActualBufferLine(lineref_in_agenda,bufnumber) + let actual_line = matchstr(s:GetPlacedSignsString(a:bufnumber),'line=\zs\d\+\ze\s\+id='.a:lineref_in_agenda) + return actual_line +endfunction + +function! s:AgendaPutText(...) + let save_cursor = getpos(".") + let thisline = getline(line(".")) + if thisline =~ '^\d\+\s\+' + if (getline(line(".") + 1) =~ '^\*\+ ') + "let file = matchstr(thisline,'^\d\+\s\+\zs\S\+\ze') + "let file = s:filedict[str2nr(matchstr(thisline, '^\d\d\d'))] + let file = s:agenda_files_copy[str2nr(matchstr(thisline, '^\d\d\d'))] + "let lineno = matchstr(thisline,'^\d\+\ze\s\+') + let lineno = str2nr(matchstr(thisline,'^\d\d\d\zs\d*')) + let starttab = tabpagenr() + + "call org#LocateFile(file.'.org') + call org#LocateFile(file) + if g:agenda_date_dict != {} + "let confirmhead = g:agenda_head_lookup[lineno] + let confirmhead = lineno + elseif g:adict != {} + let confirmhead = lineno + endif + let newhead = matchstr(s:GetPlacedSignsString(bufnr("%")),'line=\zs\d\+\ze\s\+id='.confirmhead) + let newhead = s:OrgGetHead_l(newhead) + execute newhead + let lastline = s:OrgNextHead_l(newhead) - 1 + if lastline > newhead + let g:text = getline(newhead,lastline) + elseif lastline == -1 + let g:text = getline(newhead,line('$')) + else + let g:text = [] + endif + + execute 'tabnext ' . starttab + execute bufwinnr('Agenda').'wincmd w' + + call setpos(".",save_cursor) + " okay, we're back in agenda and have main buffer's + " text in g:text, now need to compare it + + normal j + let firstline = line(".") + let daytextpat = '^\S\+\s\+\d\{1,2}\s\S\+\s\d\d\d\d' + while (getline(line(".")) !~ '^\d\+\s\+') && (line(".") != line("$")) + \ && (getline(line(".")) !~ daytextpat) + \ && (getline(line(".")) !~ '\d empty days omitted') + normal j + endwhile + let lastline = line(".") + if (lastline < line("$")) || + \ ( (getline(line(".")) =~ '^\d\+\s\+') + \ || (getline(line(".")) =~ daytextpat) + \ || (getline(line(".")) =~ '\d empty days omitted') ) + let lastline = line(".") - 1 + endif + "execute firstline . ', ' . lastline . 'd' + if g:text ==? getline(firstline, lastline) + echo "headings are identical" + else + if g:adict != {} + let resp = confirm("Heading's text has changed, save changes?","&Save\n&Cancel",1) + if resp == 1 + call s:SaveHeadline(file, newhead,getline(firstline,lastline)) + "call s:SaveHeadline(file, confirmhead,getline(firstline,lastline)) + else + echo "Changes were _not_ saved." + endif + else + call confirm("Heading's text has changed, but saving is\n" + \ . "temporarily disabled for date-based agenda views.\n" + \ . "No changes are being saved, original buffer text remains as it was.") + endif + endif + endif + else + echo "You're not on a headline line." + endif + call setpos(".",save_cursor) +endfunction +function! s:SaveHeadline(file, headline, lines) + let file = a:file + let headline = a:headline + let lines=a:lines + let starttab = tabpagenr() + + "call org#LocateFile(file.'.org') + call org#LocateFile(file) + "let newhead = matchstr(s:GetPlacedSignsString(bufnr("%")),'line=\zs\d\+\ze\s\+id='.headline) + let newhead = a:headline + execute newhead + + let lastline = s:OrgNextHead_l(newhead) - 1 + execute newhead+1.','.lastline.'d' + " don't delete orig headline b/c that's where sign is placed + call setline(newhead,lines[0]) + call append(newhead,lines[1:]) + + execute 'tabnext ' . starttab + execute bufwinnr('Agenda').'wincmd w' + +endfunction +function! OrgAgendaGetText(...) + "type: 'datedict' for date agenda, 'adict' for regular search + let cycle_todo = 0 + if a:0 >= 1 + let cycle_todo = 1 + if a:0 == 2 + let newtodo = a:2 + endif + endif + " called by map to toggle view of heading's body text in agenda + " view + let save_cursor = getpos(".") + let thisline = getline(line(".")) + let curTodo = matchstr(thisline, '\*\+ \zs\S\+') + if thisline =~ '^\d\+\s\+' + if (getline(line(".") + 1) =~ '^\d\+\s\+') || (line(".") == line("$")) || + \ (getline(line(".") + 1 ) =~ '^\S\+\s\+\d\{1,2}\s\S\+\s\d\d\d\d') + \ || (getline(line(".") + 1 ) =~ '\d empty days omitted') + + let starttab = tabpagenr() + + " go to the heading's file + let file = s:agenda_files_copy[str2nr(matchstr(thisline, '^\d\d\d'))] + let lineno = str2nr(matchstr(thisline,'^\d\d\d\zs\d*')) + call org#LocateFile(file) + + let save_cursor2 = getpos(".") + + let newhead = matchstr(s:GetPlacedSignsString(bufnr("%")),'line=\zs\d\+\ze\s\+id=' . lineno) + let newhead = s:OrgGetHead_l(newhead) + + execute newhead + + if cycle_todo + " do todo operation + if a:0 >= 2 + silent call s:ReplaceTodo(newtodo) + else + silent call s:ReplaceTodo() + endif + "normal V + "redraw + "sleep 100m + "normal V + else + " get the heading's text block + let lastline = s:OrgNextHead_l(newhead) - 1 + if lastline > newhead + let g:text = getline(newhead,lastline) + elseif lastline == -1 + let g:text = getline(newhead,line('$')) + else + let g:text = [] + endif + endif + call setpos(".",save_cursor2) + " now go back to agenda + execute 'tabnext ' . starttab + execute bufwinnr('Agenda').'wincmd w' + if !cycle_todo + call append(line("."),g:text) + endif + else + " we're dealing with toggle of agenda heading that already + " has main buffer heading text in agenda. . . + normal j + let firstline = line(".") + let daytextpat = '^\S\+\s\+\d\{1,2}\s\S\+\s\d\d\d\d' + while (getline(line(".")) !~ '^\d\+\s\+') && (line(".") != line("$")) + \ && (getline(line(".")) !~ daytextpat) + \ && (getline(line(".")) !~ '\d empty days omitted') + normal j + endwhile + let lastline = line(".") + if (lastline < line("$")) || + \ ( (getline(line(".")) =~ '^\d\+\s\+') + \ || (getline(line(".")) =~ daytextpat) + \ || (getline(line(".")) =~ '\d empty days omitted')) + let lastline = line(".") - 1 + endif + call setpos(".",save_cursor) + " see if it there are changes that need to be + " pushed back to main buffer + call s:AgendaPutText() + silent execute firstline . ', ' . lastline . 'd' + endif + else + echo "You're not on a headline line." + endif + call setpos(".",save_cursor) + if cycle_todo + " we did cycle in main buffer, now do in agenda + if a:0 >= 2 + silent call s:ReplaceTodo(s:last_newtodo) + else + silent call s:ReplaceTodo(s:last_newtodo) + endif + echo "Todo cycled." + endif +endfunction + +function! s:MoveToHeadingFromAgenda(agenda_line) + "given line from agenda, go to the associated file and heading + let thisline = getline(a:agenda_line) + let file = s:agenda_files_copy[str2nr(matchstr(thisline, '^\d\d\d'))] + let lineno = str2nr(matchstr(thisline,'^\d\d\d\zs\d*')) + call org#LocateFile(file) + " need to check sign at this lineno, since for date agenda we're not necessarily at heading + let newhead = matchstr(s:GetPlacedSignsString(bufnr("%")),'line=\zs\d\+\ze\s\+id=' . lineno) + let newhead = s:OrgGetHead_l(newhead) + execute newhead +endfunction + + +function! s:IsVisibleHeading(line) + " returns 1 if line is of a visible heading, + " 0 if not + " a heading is visible if foldclosed = -1 + " (i.e., it's not in a fold) + " OR if it's not in an earlier-started fold + " (i.e. start of fold heading is in is + " same as line of heading) + " *************************** the second and third lines of if + " statement are necessary because of bug where foldclosed is less + " than a head even though it is the fold head *************** + let fc = foldclosed(a:line) + if ((a:line > 0) && (fc == -1)) || (fc == a:line) + \ || ((fc < a:line) && s:IsText(fc) ) + \ || ((fc < a:line) && (foldclosedend(fc) < a:line) ) + " \ || (s:Ind(a:line) == 2) + return 1 + else + return 0 + endif +endfunction + +function! OrgSingleHeadingText(operation) + " expand or collapse all visible Body Text + " under Heading fold that cursor is in + " operation: "collapse" or "expand" + " expand or collapse all Body Text + " currently visible under current heading + let l:startline = line(".") + let l:endline = s:OrgSubtreeLastLine_l(l:startline) - 1 + call OrgBodyTextOperation(l:startline,l:endline,a:operation) +endfunction + +function! s:StarLevelFromTo(from, to) + let save_cursor = getpos(".") + set fdm=manual + let b:v.levelstars = a:to + ChangeSyn + g/^\*\+/call setline(line("."),substitute(getline(line(".")),'^\*\+','*' . + \ repeat('*',(len(matchstr(getline(line(".")),'^\*\+')) - 1) * a:to / a:from),'')) + set fdm=expr + call setpos(".",save_cursor) +endfunction + +function! s:StarsForLevel(level) + return 1 + (a:level - 1) * b:v.levelstars +endfunction + +function! s:OrgExpandLevelText(startlevel, endlevel) + " expand regular text for headings by level + let save_cursor = getpos(".") + + normal gg + let startlevel = s:StarsForLevel(a:startlevel) + let endlevel = s:StarsForLevel(a:endlevel) + let l:mypattern = substitute(b:v.headMatchLevel,'level', startlevel . ',' . endlevel, "") + while search(l:mypattern, 'cW') > 0 + execute line(".") + 1 + while getline(line(".")) =~ b:v.drawerMatch + execute line(".") + 1 + normal! j + endwhile + if s:IsText(line(".")) + normal zv + endif + "normal l + endwhile + + call setpos('.',save_cursor) + +endfunction + +" just an idea using 'global' not used anywhere yet +" visible is problem, must operate only on visible, doesn't do ths now +function! s:BodyTextOperation3(startline,endline, operation) + let l:oldcursor = line(".") + let nh = 0 + call cursor(a:startline,0) + g/\*\{4,}/s:DoAllTextFold(line(".")) + call cursor(l:oldcursor,0) + +endfunction + + +function! OrgBodyTextOperation(startline,endline, operation) + " expand or collapse all Body Text from startline to endline + " operation: "collapse" or "expand" + " save original line + let l:oldcursor = line(".") + let nh = 0 + " go to startline + call cursor(a:startline,0) + " travel from start to end operating on any + while 1 + if getline(line(".")) =~ b:v.headMatch + if a:operation ==? "collapse" + call s:DoAllTextFold(line(".")) + elseif a:operation ==? 'expand' + normal zv + endif + "elseif s:IsText(line(".")+1) && foldclosed(line(".")) == line(".") + "elseif foldclosed(line(".")) == line(".") + " "echo 'in expand area' + " if a:operation ==? 'expand' + " normal zv + " endif + endif + let lastnh = nh + let nh = s:NextVisibleHead(line(".")) + "echo 'last ' . lastnh . ' now ' . nh + if (nh == 0) || (nh >= a:endline) || (nh == lastnh) + "echo "hit break" + break + elseif lastnh == nh + break + echo "bad exit from BodyTextOp" + else + "echo "hit ex" + execute nh + endif + + endwhile + " now go back to original line position in buffer + call cursor(l:oldcursor,0) +endfunction + +let g:calendar_sign = 'OrgCalSign' +function! OrgCalSign(day, month, year) + if a:year .'-'.s:Pre0(a:month).'-'.s:Pre0(a:day) ==? s:org_cal_date + return 1 + else + return 0 + endif +endfunction +function! OrgSetLine(line, file, newtext) + let save_cursor = getpos(".") + let curfile = expand("%:t") + + call org#LocateFile(a:file) + call setline(a:line,a:newtext) + + call org#LocateFile(curfile) + call setpos('.',save_cursor) +endfunction +function! OrgGetLine(line, file) + let save_cursor = getpos(".") + let curfile = expand("%:t") + + call org#LocateFile(a:file) + let result = getline(a:line) + + call org#LocateFile(curfile) + call setpos('.',save_cursor) + return result +endfunction +function! OrgAgendaDateType() + " return type of date line in Agenda + let text = getline(line('.'))[19:29] + if text =~ 'Sched' + let result = 'Scheduled' + elseif text =~ '\(In \|DEADLINE\)' + let result = 'Deadline' + elseif text =~ 'Closed' + let result = 'Closed' + elseif text =~ '(' + let result = 'Range' + else + let result = 'Regular' + endif + return result +endfunction + +function! GetDateAtCursor() + + return matchstr( GetDateSpecAtCursor() , '^[[<]\zs\d\d\d\d-\d\d-\d\d' ) + +endfunction + +function! GetDateSpecAtCursor() + let savecursor = getpos(".") + " save visual bell settings so no bell + " when not found" + let orig_vb = &vb + let orig_t_vb = &t_vb + set vb t_vb= + + " check for date string within brackets + normal! va< + silent! normal! "xy + call setpos('.',savecursor) + if len(@x) < 7 + "normal! vi["xy + normal! va[ + silent! normal! "xy + endif + + if (len(@x)>=15) && (len(@x)<41) + let date = matchstr(@x,'^[[<]\d\d\d\d-\d\d-\d\d') + else + let date = '' + endif + + " restore visual bell settings + let &vb = orig_vb + let &t_vb = orig_t_vb + + if date ># '' + " return with only opening '<' or '[' + return @x + else + return '' + endif + + call setpos(".", savecursor) + +endfunction + +function! CalEdit( sdate, stime ) + " bring up calendar to edit and return a date value + call org#SaveLocation() + let basedate = a:sdate ==# '' ? s:Today() : a:sdate + let basetime = a:stime + let newdate = '<' . basedate[0:9] . ' ' . calutil#dayname(basedate[0:9]) . (basetime ># '' ? ' ' . basetime : '') . '>' + let newtime = basetime + + hi Cursor guibg=black + let s:org_cal_date = newdate[1:10] + call s:Calfunc(1,newdate[1:4],str2nr(newdate[6:7])) + " highlight chosen dates in calendar + hi Ag_Date guifg=red + call matchadd('Ag_Date','+\s\{0,1}\d\+') + redraw + let g:calendar_action=''.s:SID().'_CalendarInsertDate' + let cue = '' + while 1 + echohl LineNr | echon 'Date+time ['.basedate . ' '.basetime.']: ' + "echohl None | echon cue.'_ =>' | echohl WildMenu | echon ' '.newdate[:-2] . ' ' . newtime + echohl None | echon cue.'_ =>' | echohl WildMenu | echon ' '.newdate[:-2] . '>' + let nchar = getchar() + let newchar = nr2char(nchar) + if newdate !~ 'interpret' + let curdif = calutil#jul(newdate[1:10])-calutil#jul(s:Today()) + endif + if (nchar ==? "\") && (len(cue)>0) + let cue = cue[:-2] + elseif nchar ==? "\" + let cue = ((curdif+1>=0) ?'+':'').(curdif+1).'d' + elseif nchar ==? "\" + let cue = ((curdif-1>=0) ?'+':'').(curdif-1).'d' + elseif nchar ==? "\" + let cue = ((curdif+7>=0) ?'+':'').(curdif+7).'d' + elseif nchar ==? "\" + let cue = ((curdif-7>=0) ?'+':'').(curdif-7).'d' + elseif nchar ==? "\" + let cue = ((curdif+30>=0) ?'+':'').(curdif+30).'d' + elseif nchar ==? "\" + let cue = ((curdif-30>=0) ?'+':'').(curdif-30).'d' + elseif nchar ==? "\" + let cue = ((curdif+365>=0) ?'+':'').(curdif+365).'d' + elseif nchar ==? "\" + let cue = ((curdif-365>=0) ?'+':'').(curdif-365).'d' + elseif newchar ==? "\" + break + elseif newchar ==? "\" + hi Cursor guibg=gray + if bufwinnr('__Calendar') > 0 + bdelete Calendar + endif + redraw + return '' + elseif (nchar ==? "\") && (v:mouse_win > 0) && (bufwinnr('__Calendar') == v:mouse_win) + let g:cal_list=[] + exe v:mouse_win . "wincmd w" + exe v:mouse_lnum + exe "normal " . v:mouse_col."|" + normal + if g:cal_list != [] + if newtime ># '' + let timespec = newtime + else + let timespec = matchstr(newdate,'\S\+:.*>') + endif + let newdate = '<'.g:cal_list[0].'-'.s:Pre0(g:cal_list[1]).'-'.s:Pre0(g:cal_list[2]) . ' ' + let newdate .= calutil#dayname( g:cal_list[0].'-'.g:cal_list[1].'-'.g:cal_list[2]) + let newdate .= timespec ># '' ? ' ' . timespec : ''.'>' + break + endif + else + let cue .= newchar + endif + try + let newdate = '<' . s:GetNewDate(cue,basedate,basetime) . '>' + catch + " don't raise error if user mistypes cue. . . + " or if last char makes cue uninterpretable + let newdate = "can't interpret date cue " + endtry + if g:org_use_calendar && (match(newdate,'\d\d\d\d-\d\d')>=0) + let s:org_cal_date = newdate[1:10] + call s:Calfunc(1,newdate[1:4],str2nr(newdate[6:7])) + endif + echon repeat(' ',72) + redraw + endwhile + hi Cursor guibg=gray + bdelete __Calendar + call org#RestoreLocation() + return newdate +endfunction + +command! OrgColumns :call OrgColumnsDashboard() +function! OrgColumnsDashboard(...) + let key = (a:0==1) ? a:1 : '' + let save_cursor = getpos('.') + if !exists('w:v.columnview') + let w:v={'columnview':0} + let w:v.org_item_len=100 + let w:v.org_colview_list = [] + let w:v.org_current_columns = '' + let w:v.org_column_item_head = '' + endif + if !exists('b:v.org_columns_show_headings') + let b:v.org_columns_show_headings = 0 + endif + let force_all = 0 + + echohl WarningMsg + let save_more = &more + set nomore + while 1 + if key ==# '' + echohl MoreMsg + echo "==========================================" + echo " Buffer default columns: " . b:v.buffer_columns + echo " Current default columns: " . w:v.org_current_columns + echo " Column view is currently: " . (w:v.columnview==1 ? 'ON' : 'OFF') + echo " Show column headers is currently: " . (b:v.org_columns_show_headings ? 'ON' : 'OFF') + echo " Heading line count is currently: " . (g:org_show_fold_lines==1 ? 'ON' : 'OFF') + if (w:v.columnview == 0) && (force_all == 1) + echo " NEXT CHOICE WILL BE APPLIED TO ENTIRE BUFFER" + endif + echo " " + echo " Press key to enter a columns command" + echo " ------------------------------------" + if (w:v.columnview == 0) && (force_all == 0) + echo " f force all of buffer to use chosen columns" + endif + if w:v.org_current_columns != b:v.buffer_columns + echo " r revert to buffer default columns" + endif + echo " t toggle column view on/off" + echo " h toggle show headings on/off" + echo " l line count on/off" + if len(g:org_custom_column_options) > 0 + echo " Custom columns settings:" + endif + let i = 0 + while i < len(g:org_custom_column_options) + echo " " . i . " " . g:org_custom_column_options[i] + let i += 1 + endwhile + echo " ------------------------------------" + echo " " + echohl Question + let key = nr2char(getchar()) + redraw + endif + + if key ==? 'f' + let force_all = 1 + let key = '' + redraw + continue + endif + + let master_head = (force_all == 1 ) ? 0 : line('.') + + if key ==? 'r' + let w:v.org_current_columns = b:v.buffer_columns + if w:v.columnview == 1 + "turn off col view + call ToggleColumnView(master_head, w:v.org_current_columns) + endif + call ToggleColumnView(master_head, w:v.org_current_columns) + elseif key ==? 't' + " current columns will get set in SetColumnHeads() + call ToggleColumnView(master_head,'') + elseif key ==? 'h' + let b:v.org_columns_show_headings = 1 - b:v.org_columns_show_headings + elseif key ==? 'l' + let g:org_show_fold_lines = 1 - g:org_show_fold_lines + elseif key =~ '[0-9]' + let w:v.org_current_columns = g:org_custom_column_options[key] + if w:v.columnview == 1 + " turn off + call ToggleColumnView(master_head, w:v.org_current_columns) + endif + call ToggleColumnView(master_head, w:v.org_current_columns) + else + echo "No column option selected." + endif + break + endwhile + + if b:v.org_columns_show_headings == 0 + call s:ColHeadWindow('',0) + elseif (w:v.columnview == 1) && (bufnr('ColHeadBuffer') == -1) + call s:ColHeadWindow(w:v.org_column_item_head) + endif + echohl None + let &more = save_more + call s:AdjustItemLen() + " redraw folded headings + setlocal foldtext=OrgFoldText() + call setpos('.',save_cursor) +endfunction +function! OrgDateDashboard(...) + let key = (a:0==1) ? a:1 : '' + let save_cursor = getpos('.') + let save_window = winnr() + if bufname("%") ==? ('__Agenda__') + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + let buffer_lineno = s:ActualBufferLine(lineno,bufnr(file)) + let props = s:GetProperties(buffer_lineno, 0, file) + else + let props = s:GetProperties(line('.'),0) + endif + + if key ==# '' + echohl MoreMsg + echo " =================================" + echo " Press key, for a date command:" + echo " ---------------------------------" + echo " d set DEADLINE for current heading (currently: " . get(props,'DEADLINE','NONE') . ')' + echo " s set SCHEDULED for current heading (currently: " . get(props,'SCHEDULED','NONE') . ')' + echo " c set CLOSED for current heading (currently: " . get(props,'CLOSED','NONE') . ')' + echo " t set TIMESTAMP for current heading (currently: " . get(props,'TIMESTAMP','NONE') . ')' + echo " g set date at cursor" + echo " " + echo " " + echohl Question + let key = nr2char(getchar()) + redraw + endif + if key ==? 'd' + call OrgDateEdit('DEADLINE') + elseif key ==? 's' + call OrgDateEdit('SCHEDULED') + elseif key ==? 'c' + call OrgDateEdit('CLOSED') + elseif key ==? 't' + call OrgDateEdit('TIMESTAMP') + elseif key ==? 'g' && (bufname('%') != '__Agenda__') + call OrgDateEdit('ATCURSOR') + else + echo "No date command selected." + endif + echohl None + exe save_window . 'wincmd w' + call setpos('.',save_cursor) +endfunction +function! OrgAgendaDateInc(datecue) + let agline = getline(line('.')) + if agline =~ 'Deadline:\|In.*\dd\.:' + call OrgDateEdit('DEADLINE',a:datecue) + elseif agline =~ 'Scheduled:\|Sched:' + call OrgDateEdit('SCHEDULED',a:datecue) + let type = 'SCHEDULED' + elseif agline =~ 'Closed:' + call OrgDateEdit('CLOSED',a:datecue) + else + call OrgDateEdit('TIMESTAMP',a:datecue) + endif + +endfunction +function! OrgDateEdit(type,...) + if a:0 == 1 + "use this to bypass calendar ui + let datecue = a:1 + endif + " type can equal DEADLINE/CLOSED/SCHEDULED/TIMESTAMP/ATCURSOR + let save_cursor = getpos('.') + let old_cal_navi = g:calendar_navi + unlet g:calendar_navi + try + let dtype = a:type + if bufname("%") ==? ('__Agenda__') + "get file, lineno, and other data if in Agenda + let from_agenda=1 + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + let buffer_lineno = s:ActualBufferLine(lineno,bufnr(file)) + let bufline = OrgGetLine(buffer_lineno,file) + else + let from_agenda=0 + let buffer_lineno = line('.') + let bufline = getline(buffer_lineno) + let file = expand("%:t") + endif + if dtype =~ '\(DEADLINE\|SCHEDULED\|CLOSED\|TIMESTAMP\|ATCURSOR\)' + if dtype == 'ATCURSOR' + let my_date = GetDateSpecAtCursor() + else + let my_date = s:GetProp(dtype,buffer_lineno, file) + endif + + let bracket = my_date[0] + let orig_date = matchstr( my_date, '[[<]\zs\d\d\d\d-\d\d-\d\d' ) + let orig_time = matchstr( my_date, '[[<]\d\d\d\d-\d\d-\d\d ... \zs\d\d:\d\d' ) + if orig_time ># '' + let rpt_or_warning = matchstr( my_date, ' \d\d:\d\d\zs .*\ze.$') + else + let rpt_or_warning = matchstr( my_date, '-\d\d-\d\d \S\S\S\zs .*\ze.$') + endif + + if !exists('datecue') + let cal_result = CalEdit(orig_date, orig_time) + if cal_result ==# '' + return + endif + else + let cal_result = s:GetNewDate(datecue, orig_date, orig_time) + let cal_result = bracket . cal_result . (bracket=='<'?'>':']') + endif + if bracket == '[' + let cal_result = '[' . cal_result[1:-2] . rpt_or_warning . ']' + else + let cal_result = '<' . cal_result[1:-2] . rpt_or_warning . '>' + endif + + " back to main window if agenda is present and cursor is in it + if (from_agenda == 0) && bufname("%") ==? '__Agenda__' + "wincmd k + exe bufwinnr(file) . 'wincmd w' + endif + + if dtype == 'ATCURSOR' + " put new date into text + call setpos('.', save_cursor) + if cal_result =~ '^.\d\d\d\d-\d\d' + let @x = cal_result[1:-2] + if my_date ># '' + "replace existing date within delimiters + exec 'normal vi' . my_date[0] . 'd' + normal h"xpll + else + "paste in brand new date + exec 'normal i <> ' + normal hh"xpll + endif + endif + else + " set the prop with new date . . . + if (from_agenda == 0) + "just set the prop if we're in org file buffer + call s:SetProp(dtype,cal_result,buffer_lineno, file) + else + if empty(b:v.heading_marks_dict) + " just mark and do current item + "let b:v.heading_marks = [line('.')] + let b:v.heading_marks_dict[line('.')] = 1 + endif + for item in sort(keys(b:v.heading_marks_dict), 's:ReverseSort') + exec item + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + let buffer_lineno = s:ActualBufferLine(lineno,bufnr(file)) + let bufline = OrgGetLine(buffer_lineno,file) + call s:SetProp(dtype,cal_result,buffer_lineno, file) + "put prop change indicator on line(s) + let cur_line = getline(line('.')) + let mylen = winwidth(0) - 29 + let cur_line = (len(cur_line) > mylen) ? cur_line[:mylen] : cur_line . repeat(' ', mylen-len(cur_line)) + let change_indicator = ' ' . dtype[0] . ' => ' . dtype . ' on ' . cal_result + call setline(line('.'), cur_line . change_indicator) + execute 'sign unplace ' . item . ' buffer=' . bufnr('%') + endfor + let b:v.heading_marks = [] + let b:v.heading_marks_dict = {} + endif + endif + + redraw + echo + redraw + else + echo "Date type wasn't DEADLINE, SCHEDULED, CLOSED, TIMESTAMP, or ATCURSOR." + endif + finally + let g:calendar_navi = old_cal_navi + call setpos('.',save_cursor) + endtry +endfunction + +function! s:GetNewTime(cue, basetime) + " called from caledit() + let timecue = a:cue + if timecue =~ '\d\d:\d\d' + let mytime = ' '.timecue + else + let mytime = '' + endif + return mytime + +endfunction + +function! s:GetNewDate(cue,basedate,basetime) + " called from caledit() + if match(a:cue,'\S:') >= 0 + let mlist = matchlist(a:cue, '^\(.*\) \(\S\+:.*\)') + let cue = mlist[1] + let timecue = mlist[2] + else + let cue = a:cue + let timecue = '' + endif + let basedate = a:basedate + let newdate = DateCueResult( cue , basedate ) + let tmatch = matchlist( timecue , '\(\d\{1,2}\):\(\d\d\)\(am\|pm\)*') + if !empty(tmatch) + let hours = tmatch[1] + if (tmatch[3]=='pm') && (hours < 12) + let hours = hours + 12 + elseif (tmatch[3]=='am') && (hours == 12) + let hours = 0 + endif + let hours = s:Pre0(hours) + let mytime = ' ' . hours . ':' . tmatch[2] + else + let mytime = a:basetime ># '' ? ' ' . a:basetime : '' + endif + let mydow = calutil#dayname(newdate) + return newdate . ' ' . mydow . mytime +endfunction +function! DateCueResult( cue, basedate) + let cue = a:cue + let basedate = a:basedate + if cue =~ '^\(+\|++\|-\|--\)$' + let cue = cue . '1d' + elseif cue =~ '^\(+\|++\|-\|--\)\d\+$' + let cue = cue .'d' + endif + if cue ==? '.' + let newdate = strftime('%Y-%m-%d') + elseif cue ==# '' + let newdate = a:basedate + elseif (cue =~ '^\d\+$') && (str2nr(cue) <= 31) + " day of month string + if str2nr(cue) > str2nr(basedate[8:9]) + let newdate = calutil#cal(calutil#jul(basedate[0:7].s:Pre0(cue))) + else + let newmonth = s:Pre0(basedate[5:6]+1) + let newdate = calutil#cal(calutil#jul(basedate[0:4].newmonth.'-'.s:Pre0(cue))) + endif + elseif cue =~ '^\d\+[-/]\d\+$' + " month/day string + let month = matchstr(cue,'^\d\+') + let day = matchstr(cue,'\d\+$') + let year = basedate[0:3] + if basedate[0:4] . s:Pre0(month) . '-' . s:Pre0(day) < basedate + let year = year + 1 + endif + let newdate = calutil#cal(calutil#Cal2Jul(year,month,day)) + elseif cue =~ '\d\+/\d\+/\d\+' + " m/d/y string + let month = matchstr(cue,'^\d\+\ze/.*/') + let day = matchstr(cue,'/\zs\d\+\ze/') + let year = matchstr(cue,'/\zs\d\+\ze$') + if len(year) < 3 + let year +=2000 + endif + let newdate = calutil#cal(calutil#Cal2Jul(year,month,day)) + elseif cue =~ '\d\+-\d\+-\d\+' + " y-m-d string + let year = matchstr(cue,'^\d\+\ze-.*-') + if year < 100 + let year +=2000 + endif + let month = matchstr(cue,'-\zs\d\+\ze-') + let day = matchstr(cue,'-\zs\d\+\ze$') + let newdate = calutil#cal(calutil#Cal2Jul(year,month,day)) + + elseif cue =~ s:org_monthstring . ' \d\+$' + let month_str = matchstr(cue,'^' . s:org_monthstring) + let month = 1 + index(s:org_months, tolower(month_str[:2])) + let day = matchstr(cue,' \zs\d\+$') + let year = basedate[0:3] + if basedate[0:4] . s:Pre0(month) . '-' . s:Pre0(day) < basedate + let year = year + 1 + endif + let newdate = calutil#cal(calutil#Cal2Jul(year,month,day)) + elseif cue =~ s:org_monthstring . ' \d\+ \d\+$' + let month_str = matchstr(cue,'^' . s:org_monthstring) + let month = 1 + index(s:org_months, tolower(month_str[:2])) + let day = matchstr(cue,' \zs\d\+\ze ') + let year = str2nr(matchstr(cue,' \d\+ \zs\d\+$')) + let year = (year < 1800) ? 2000 + year : year + let newdate = calutil#cal(calutil#Cal2Jul(year,month,day)) + elseif cue =~ s:org_weekdaystring + " wed, 3tue, 5fri, i.e., dow string + let mycount = matchstr(cue,'^\d\+') + let myday = matchstr(cue,s:org_weekdaystring) + let newday = index(s:org_weekdays,tolower(myday)) + let oldday = calutil#dow(matchstr(basedate,'\d\d\d\d-\d\d-\d\d')) + if newday > oldday + let amt=newday-oldday + elseif newday < oldday + let amt =7-oldday+newday + else + let amt = 7 + endif + let amt = amt + (mycount*7) + let newdate=calutil#cal(calutil#jul(basedate)+amt) + elseif cue =~ '\c\([-+]\|[-+][-+]\)\d\+[ dwmy]' + " plus minus count of dwmy + let mlist = matchlist(cue,'\c\([-+]\|[-+][-+]\)\(\d\+\)\([ wdmy]\)') + let op = mlist[1] + let mycount = mlist[2] + let type = mlist[3] + if len(op) == 1 + let mydate = strftime('%Y-%m-%d') + else + let mydate = basedate + endif + let op = op[0] + let year = mydate[0:3] + let month = mydate[5:6] + let day = mydate[8:9] + if type ==? 'y' + let type = 'm' + let mycount = mycount * 12 + elseif type ==? 'w' + let type='d' + let mycount = mycount * 7 + endif + if type ==? 'm' + if (op ==? '+') + let yplus = mycount / 12 + let mplus = mycount % 12 + let year += yplus + let month += mplus + if month > 12 + let month = month - 12 + let year = year + 1 + endif + elseif ((mycount % 12) >= month) && (op ==? '-') + let yminus = mycount/12 + let year = year - yminus - 1 + let month = (month + 12 - (mycount % 12)) + else " '-' with month greater + let month = month - (mycount % 12) + let year = year - (mycount / 12) + endif + " correct for bad dates + while calutil#cal(calutil#jul(year.'-'.s:Pre0(month).'-'.s:Pre0(day)))[5:6] != month + let day = day - 1 + endwhile + elseif (type ==? 'd') || (type ==? ' ') + let newjul = calutil#jul(mydate) + if op ==? '+' + let newjul = newjul + mycount + else + let newjul = newjul - mycount + endif + "execute 'let newjul = newjul ' . op . mycount + let mydate = calutil#cal(newjul) + let year = mydate[0:3] + let month = mydate[5:6] + let day = mydate[8:9] + endif + + let newdate = year . '-' . s:Pre0(month) . '-' . s:Pre0(day) + else + return " ?? can't interpret your spec" + endif + return newdate +endfunction +function! s:TimeInc(direction) + let save_cursor = getpos(".") + let i = 0 + let col = save_cursor[2] - 1 + let line = getline(line(".")) + if line[col] =~ '\d' + let i = 1 + while i < 6 + let start = col - i + let end = col - i + 6 + silent execute 'let timetest = line[' . start . ':' . end .']' + if timetest =~ ' \d\d:\d\d[>\]]' + break + endif + let i += 1 + endwhile + else + let i = 6 + endif + if i == 6 + execute "normal! \" + return + else + let start = col - i + 1 + let end = col - i + 5 + execute 'let time = line[' . start . ':' . end .']' + if i > 3 + let newminutes = (time[3:4] + (a:direction *5)) + let newminutes = newminutes - (newminutes % 5) + if (newminutes >= 60) + let newminutes = 0 + let newhours = time[0:1] + 1 + elseif (newminutes == -5) && (a:direction == -1) + let newminutes = 55 + let newhours = time[0:1] - 1 + else + let newhours = time[0:1] + endif + else + let newhours = time[0:1] + (1 * a:direction) + let newminutes = time[3:4] + endif + if newhours >= 24 + let newhours = 0 + "let tempsave = getpos(".") + elseif newhours < 0 + let newhours = 23 + "execute "normal ".start-6."|" + "call OrgDateInc(a:direction) + "call setpos(".",tempsave) + endif + let matchcol = col-i+2 + execute 's/\%'.matchcol.'c\zs\d\d:\d\d/' . s:Pre0(newhours) . ':' . s:Pre0(newminutes).'/' + endif + call setpos(".",save_cursor) +endfunction +function! OrgDateInc(direction) + " " + return + else + if i > 12 + call setpos(".",save_cursor) + call s:TimeInc(a:direction) + return + endif + let start = col - i + 1 + let end = col - i + 11 + execute 'let date = line[' . start . ':' . end .']' + if i > 7 + let newdate = calutil#cal(calutil#jul(date) + a:direction) + let newyear = newdate[0:3] + let newmonth = newdate[5:6] + let newday = newdate[8:9] + elseif i < 5 + let spot = 'year' + let newyear = date[0:3] + a:direction + let newmonth = date[5:6] + let newday = date[8:9] + "execute 's/\d\d\d\d/' . newyear . '/' + else + let spot = 'month' + let newmonth = date[5:6] + a:direction + let newday = date[8:9] + if newmonth > 12 + let newyear = date[0:3] + 1 + let newmonth = '01' + let newday = '01' + elseif newmonth < 1 + let newyear = date[0:3] - 1 + let newmonth = '12' + let newday = '31' + else + let newyear = date[0:3] + let newday = date[8:9] + endif + endif + " correct for bad dates + while calutil#cal(calutil#jul(newyear.'-'.newmonth.'-'.newday))[5:6] != newmonth + let newday = newday - 1 + endwhile + let matchcol = col-i+2 + execute 's/\%'.matchcol.'c\zs\d\d\d\d-\d\d-\d\d/' . newyear . '-' . s:Pre0(newmonth) . '-' . s:Pre0(newday).'/' + " update dow if there is one + let end +=5 + silent execute 'let datetest = line[' . start . ':' . end .']' + if datetest =~ '\d\d\d\d-\d\d-\d\d \S\S\S' + let dow = calutil#DayOfWeek(newyear,newmonth,newday,2) + silent execute 's/\%'.matchcol.'c\(\d\d\d\d-\d\d-\d\d \)\S\S\S/\1' . dow.'/' + endif + endif + call setpos(".",save_cursor) +endfunction + +function! s:GetClock() + return '['.strftime("%Y-%m-%d %a %H:%M").']' +endfunction +function! OrgClockIn(...) + let save_cursor=getpos(".") + let lineno=line('.') + if bufname("%") ==? ('__Agenda__') + let lineno = matchstr(getline(line('.')),'^\d\+') + let file = matchstr(getline(line('.')),'^\d\+\s*\zs\S\+').'.org' + let str = ','.lineno.',"'.file.'"' + call s:SetProp('CLOCKIN','',lineno,file) + else + + if a:0 > 1 + execute a:1 + endif + execute s:OrgGetHead() + if s:IsTagLine(line(".")+1) + execute line('.')+1 + endif + call append(line('.'),' :CLOCK: '.s:GetClock()) + let dict={'file':expand("%"),'line':line('.'),'Timestamp':org#Timestamp()} + call add(g:org_clock_history,dict) + endif + + + call setpos(".",save_cursor) +endfunction +function! s:GetOpenClock() + let found_line = 0 + let file = '' + if !exists('g:agenda_files') || (g:agenda_files == []) + unsilent call confirm("No agenda files defined, will search only this buffer for open clocks.") + let found_line = search('CLOCK: \[\d\d\d\d-\d\d-\d\d \S\S\S \d\d:\d\d\]\($\|\s\)','w') + else + let g:in_agenda_search = 1 + for file in g:agenda_files + call org#LocateFile(file) + let found_line = search('CLOCK: \[\d\d\d\d-\d\d-\d\d \S\S\S \d\d:\d\d\]\($\|\s\)','w') + let file = expand("%") + if found_line > 0 + break + endif + endfor + unlet g:in_agenda_search + endif + return [file,found_line] +endfunction +function! OrgClockOut(...) + let cur_file=expand("%") + let save_cursor= getpos('.') + if a:0 > 1 + execute a:1 + else + let oc = s:GetOpenClock() + if oc[0] ># '' + call org#LocateFile(oc[0]) + execute oc[1] + endif + endif + execute s:OrgGetHead() + let bottom = s:OrgNextHead() > 0 ? s:OrgNextHead() - 1 : line("$") + let str = 'CLOCK: \[\d\d\d\d-\d\d-\d\d \S\S\S \d\d:\d\d\]\($\|\s\)' + let found = s:Range_Search(str,'n',bottom,line(".")) + if found + execute found + execute 'normal A--' . s:GetClock() + if b:v.clock_to_logbook + let headline = s:OrgGetHead() + let clockline = getline(line(".")) . ' -> ' . s:ClockTime(line(".")) + normal! dd + call OrgConfirmDrawer("LOGBOOK",headline) + let clockline = matchstr(getline(line(".")),'^\s*') . matchstr(clockline,'\S.*') + call append(line("."),clockline ) + endif + let msg = "Open clock found and clocked out in \n" + let msg .= "file: ".expand("%")."\n" + let msg .= "in headline at line number: ".headline + call confirm(msg) + else + echo 'No open clock found. . . .' + endif + call org#LocateFile(cur_file) + call setpos(".",save_cursor) +endfunction +function! s:UpdateAllClocks() + %g/^\s*:CLOCK:/call s:AddClockTime(line(".")) +endfunction +function! s:AddClockTime(line) + call setline(a:line,matchstr(getline(a:line),'.*\]') . ' -> ' . s:ClockTime(a:line)) +endfunction + +function! s:UpdateClockSums() + let save_cursor = getpos(".") + g/^\s*:ItemClockTime/d + call s:UpdateAllClocks() + g/^\s*:CLOCK:/call s:SetProp('ItemClockTime', s:SumClockLines(line("."))) + call setpos(".",save_cursor) +endfunction + +function! s:SumClockLines(line) + let save_cursor = getpos(".") + execute s:OrgGetHead_l(a:line) + 1 + "execute a:line + 1 + let hours = 0 + let minutes = 0 + while 1 + let text = getline(line(".")) + if text !~ s:remstring + break + endif + let time = matchstr(text,'CLOCK.*->\s*\zs\d\+:\d\+') + if time ># '' + let hours += str2nr(split(time,':')[0]) + let minutes += str2nr(split(time,':')[1]) + endif + + if line('.') == line('$') + break + else + execute line('.') + 1 + endif + + endwhile + let totalminutes = (60 * hours) + minutes + call setpos(".",save_cursor) + return (totalminutes/60) . ':' . s:Pre0(totalminutes % 60) + +endfunction +function! s:UpdateBlock() + normal j + ?^#+BEGIN: + let block_type = matchstr(getline(line('.')),'\S\+\s\+\zs\S\+') + if matchstr(getline(line('.')+1),'^#+END') ==# '' + normal jV/^#+END/-1 dk + endif + if block_type ==? 'clocktable' + let block_type='ClockTable' + endif + let mycommand = block_type.'()' + execute "call append(line('.'),".mycommand.")" +endfunction +function! ClockTable() + let save_cursor = getpos(".") + + call s:UpdateClockSums() + call s:UpdateHeadlineSums() + call OrgMakeDict() + let g:ctable_dict = {} + let mycommand = "let g:ctable_dict[line('.')] = " + \ . "{'text':s:GetProperties(line('.'),0)['ITEM']" + \ . " , 'time':s:GetProperties(line('.'),0)['TOTALCLOCKTIME']}" + g/:TOTALCLOCKTIME/execute mycommand + let total='00:00' + for item in keys(g:ctable_dict) + "let test = g:ctable_dict[item].text + if g:ctable_dict[item].text[0:1] ==? '* ' + "if test[0:1] ==? '* ' + let total = s:AddTime(total,g:ctable_dict[item].time) + endif + endfor + let result = ['Clock summary at ['.org#Timestamp().']','', + \ '|Lev| Heading | ClockTime', + \ '|---+------------------------------+-------+--------' , + \ '| | *TOTAL* | '.total ] + for item in sort(keys(g:ctable_dict),'s:NumCompare') + let level = len(matchstr(g:ctable_dict[item].text,'^\*\+')) + let treesym = repeat(' ',level-2) . (level > 1 ? '\_ ' : '') + let str = '| '.level.' | ' + \ . org#Pad(treesym . matchstr(g:ctable_dict[item].text,'^\*\+ \zs.*')[:20],28) . ' | ' + \ . repeat(' | ',level-1) + \ . s:PrePad(g:ctable_dict[item].time,5) . ' |' + if g:ctable_dict[item].text[0:1] ==? '* ' + call add(result, '|---+------------------------------+-------+-------+' ) + endif + call add(result, str) + endfor + call setpos(".",save_cursor) + + unlet b:v.org_dict + return result + +endfunction + +function! s:NumCompare(i1,i2) + let i1 = str2nr(a:i1) + let i2 = str2nr(a:i2) + return i1 == i2 ? 0 : i1>i2 ? 1 : -1 +endfunction + +function! s:ClockTime(line) + let ctext = getline(a:line) + let start = matchstr(ctext,'CLOCK:\s*\[\zs\S\+\s\S\+\s\S\+\ze\]') + let end = matchstr(ctext,'--\[\zs.*\ze\]') + let daydifference = calutil#jul(end[0:9])-calutil#jul(start[0:9]) + let startmin = 60*start[15:16] + start[18:19] + let endmin = 60*end[15:16] + end[18:19] + let totalmin = (daydifference * 1440) + (endmin - startmin) + return string(totalmin/60) . ':' . s:Pre0(totalmin % 60) +endfunction +function! s:AddTime(time1, time2) + let time1 = a:time1 + let time2 = a:time2 + if match(time1,':') == -1 | let time1 = '00:00' | endif + if match(time2,':') == -1 | let time2 = '00:00' | endif + let hours = str2nr(matchstr(time1,'^.*\ze:')) + str2nr(matchstr(time2,'^.*\ze:')) + let minutes = (60*hours) + time1[-2:] + time2[-2:] + return (minutes/60) . ':' . s:Pre0(minutes % 60) +endfunction +function! s:GetProp(key,...) + let save_cursor = getpos(".") + if a:0 >=2 + let curtab = tabpagenr() + let curwin = winnr() + " optional args are: a:1 - lineno, a:2 - file + call org#LocateFile(a:2) + endif + if (a:0 >= 1) && (a:1 > 0) + execute a:1 + endif + execute s:OrgGetHead() + 1 + let myval = '' + while 1 + let text = getline(line(".")) + if text !~ s:remstring + break + endif + let mymatch = matchstr(text,':\s*'.a:key.'\s*:') + if mymatch ># '' + let myval = matchstr(text,':\s*'.a:key.'\s*:\s*\zs.*$') + break + endif + execute line(".") + 1 + if line(".") == line("$") + break + endif + endwhile + if a:0 >= 2 + execute "tabnext ".curtab + execute curwin . "wincmd w" + endif + call setpos(".",save_cursor) + return myval + +endfunction +function! s:SetDateProp(type,newdate,...) + " almost identical to s:GetProp() above, need to refactor + let save_cursor = getpos(".") + if a:0 == 1 + execute a:1 + 1 + else + execute line(".") + 1 + endif + let myval = '' + while 1 + let text = getline(line(".")) + if text !~ s:remstring + break + endif + let mymatch = matchstr(text,'\s*'.a:type.'\s*:') + if mymatch ># '' + execute 's/'.a:type.'.*$/'.a:type.':<'.a:newdate.'>/' + break + endif + execute line(".") + 1 + endwhile + call setpos(".",save_cursor) + return myval +endfunction +function! s:SetProp(key, val,...) + let save_cursor = getpos(".") + " optional args are: a:1 - lineno, a:2 - file + if a:0 >=2 + let curtab = tabpagenr() + let curwin = winnr() + call org#LocateFile(a:2) + endif + if (a:0 >= 1) && (a:1 > 0) + execute a:1 + endif + let key = a:key + let val = a:val + execute s:OrgGetHead() + " block_end was end of properties block, but getting that + " from GetProperties(line('.'),0) creates problems with + " line numbers having changed from previous run of OrgMakeDict + " So, just use next head as end of block for now. + let block_end = s:OrgNextHead() + let block_end = (block_end == 0) ? line('$') : block_end + if key =~ 'DEADLINE\|SCHEDULED\|CLOSED\|TIMESTAMP' + " it's one of the five date props + " find existing date line if there is one + if key ==? 'TIMESTAMP' + let key = '' + let foundline = s:Range_Search('^\s*:\s*<\d\d\d\d-\d\d-\d\d','n',block_end,line(".")) + elseif key ==? 'TIMESTAMP_IA' + let key = '' + let foundline = s:Range_Search('^\s*:\s*[\d\d\d\d-\d\d-\d\d','n',block_end,line(".")) + else + let foundline = s:Range_Search('^\s*\(:\)\{}'.key.'\s*:','n',block_end,line(".")) + endif + if foundline > 0 + "exec foundline + "exec 's/:\s*<\d\d\d\d-\d\d-\d\d \S\S\S\( \d\d:\d\d\)*/' . (key ==# '' ? ':' : ': ') . a:val[:-2] + call setline(foundline,substitute(getline(foundline), + \ ':\s*<\d\d\d\d-\d\d-\d\d \S\S\S.*$', (key ==# '' ? ':' : ': ') . a:val,'')) + "\ ':\s*<\d\d\d\d-\d\d-\d\d \S\S\S.*$', (key ==# '' ? ':' : ': ') . a:val[:-2],'')) + else + let line_ind = len(matchstr(getline(line(".")),'^\**'))+1 + g:org_indent_from_head + if s:IsTagLine(line('.')+1) + execute line('.') + 1 + endif + call append(line("."),org#Pad(' ',line_ind) + \ .':'.key.(key ==# '' ? '' : ': ').a:val) + endif + elseif key ==? 'tags' + let indent_count = len(matchstr(getline(line(".")),'^\*\+ ')) + let curindent = repeat(' ',indent_count) + let newval = curindent . a:val + if s:IsTagLine(line('.') + 1) + call setline(line('.') + 1, newval) + else + call append(line('.'), newval) + endif + "execute line('.') + 1 + "normal =$ + "execute line('.') - 1 + elseif key ==? 'CLOCKIN' + call OrgClockIn() + elseif key ==? 'CLOCKOUT' + call OrgClockOut(a:val) + else + " it's a regular key/val pair in properties drawer + call OrgConfirmDrawer("PROPERTIES") + while (getline(line(".")) !~ '^\s*:\s*' . key) && + \ (getline(line(".")) =~ s:remstring) && + \ (line('.') != line('$')) + execute line(".") + 1 + endwhile + + if (getline(line(".")) =~ s:remstring) && (getline(line('.')) !~ '^\s*:END:') + call setline(line("."), matchstr(getline(line(".")),'^\s*:') . + \ key . ': ' . val) + else + execute line(".") - 1 + call OrgConfirmDrawer("PROPERTIES") + let curindent = matchstr(getline(line(".")),'^\s*') + let newline = curindent . ':' . key . ': ' . val + call append(line("."),newline) + endif + endif + + if exists("*Org_property_changed_functions") && (bufnr("%") != bufnr('Agenda')) + let Hook = function("Org_property_changed_functions") + silent execute "call Hook(line('.'),a:key, a:val)" + endif + if a:0 >=2 + "back to tab/window where setprop call was made + execute "tabnext ".curtab + execute curwin . "wincmd w" + endif + call setpos(".",save_cursor) +endfunction +function! s:CurrentRemoveFromAgendaFiles() + let cur_file1 = fnamemodify(expand("%:p"), ":~")[1:] + let cur_file = substitute(cur_file1,'\','\\\\','g') + let cur_file = substitute(cur_file,'\\ ','\ ','g') + + let file_count = len(g:agenda_files) + + let ndx = -1 + for i in range(0, file_count - 1 ) + if g:agenda_files[i] =~ '\c' . cur_file + let ndx = i + break + endif + endfor + if ndx > -1 + call remove(g:agenda_files,ndx) + echo cur_file1 . ' was removed from agenda files list.' + else + echo cur_file1 . ' was not in agenda files list.' + endif +endfunction + +function! s:CurrentToAgendaFiles(top_or_bottom) + " argument should be either 'top' or 'bottom' + let cur_file1 = fnamemodify(expand("%:p"), ":~") + let cur_file = substitute(cur_file1[1:],'\','\\\\','g') + let cur_file = substitute(cur_file,'\\ ','\ ','g') + + if !exists('g:agenda_files') + let g:agenda_files = [] + endif + let file_count = len(g:agenda_files) + + let ndx = -1 + for i in range(0, file_count - 1 ) + if g:agenda_files[i] =~ '\c' . cur_file + let ndx = i + break + endif + endfor + if ndx > -1 + call remove(g:agenda_files,ndx) + endif + if a:top_or_bottom == 'top' + let g:agenda_files = [cur_file1] + g:agenda_files + else + let g:agenda_files = g:agenda_files + [cur_file1] + endif + echo cur_file1 . ' is at ' . a:top_or_bottom . ' of agenda files list.' +endfunction + +function! s:OrgGotoChosenFile(...) + if a:0 == 1 + " type is 'agenda' or 'all' + let type = a:1 + else + let type = 'all' + endif + let fdict = {} + let bufnums= [] + let bufnums_nonagenda = [] + if exists('g:agenda_files') && !empty(g:agenda_files) + for i in range(0, len(g:agenda_files) - 1) + let buf = bufnr(g:agenda_files[i]) + let buf = (buf == -1 ? 10000 + i : buf) + let fdict[buf] = g:agenda_files[i] + call add(bufnums,buf) + endfor + endif + if type == 'all' + let buffers = split(org#redir('buffers'), "\n") + for item in buffers + let m = matchlist(item,'\s*\(\d\+\).*"\(.*\)"') + if get(fdict, m[1], -1 ) == -1 + "put buffer as key and fname as value + let fdict[m[1]] = m[2] + call add(bufnums_nonagenda,str2nr(m[1])) + endif + endfor + " get rid of non org buffers + for bufnum in keys(fdict) + if (getbufvar(str2nr(bufnum), "&filetype") !=# 'org') && (bufnum < 10000) + unlet fdict[bufnum] + call remove(bufnums_nonagenda,index(bufnums_nonagenda,str2nr(bufnum))) + endif + endfor + endif + + redraw + echo "Agenda files:" + echo "=============================" + let nums = range(char2nr('a'),char2nr('z')) + range(char2nr('0'), char2nr('9')) + + for i in range(0,len(bufnums)-1) + echo ' ' . nr2char(nums[i]) . ' ' . g:agenda_files[i] + endfor + echo "Non-agenda org files:" + echo "=============================" + for i in range(0,len(bufnums_nonagenda)-1) + echo ' ' . nr2char(nums[i + len(bufnums)]) . ' ' . fdict[bufnums_nonagenda[i]] + endfor + let bufnums = bufnums + bufnums_nonagenda + echo "" + echo "Press a key to go to chosen file: " + silent let x = nr2char(getchar()) + redraw + + if x =~ '[0-9a-z]' + silent call org#LocateFile(fdict[bufnums[index(nums,char2nr(x))]]) + endif + +endfunction +function! s:CycleAgendaFiles(direction) + if exists('g:agenda_files') && !empty('g:agenda_files') + let cur_file = fnamemodify(expand("%:p"), ":~")[1:] + let cur_file = substitute(cur_file,'\','\\\\','g') + let cur_file = substitute(cur_file,'\\ ','\ ','g') + + let file_count = len(g:agenda_files) + "let ndx = index(g:agenda_files,cur_file) + let ndx = -1 + for i in range(0, file_count - 1 ) + if g:agenda_files[i] =~ '\c' . cur_file + let ndx = i + break + endif + endfor + if ndx > -1 + "let ndx = (ndx == len(g:agenda_files)) ? 0 : ndx + let ndx += (a:direction ==? 'backward') ? -1 : 1 + if a:direction == 'backward' + let ndx = (ndx == -1) ? (len(g:agenda_files) - 1) : ndx + elseif a:direction == 'forward' + let ndx = (ndx == len(g:agenda_files) ? 0 : ndx) + endif + + let filename = g:agenda_files[ndx] + else + let filename = g:agenda_files[0] + endif + call org#LocateFile(filename) + else + echo "No agenda files defined." + endif + +endfunction + +function! OrgConfirmDrawer(type,...) + let line = s:OrgGetHead() + if a:0 == 1 + let line = a:1 + endif + execute line + let indent = repeat(' ', len(matchstr(getline(line('.')),'^\*\+ '))) + let bottom = s:OrgNextHead() > 0 ? s:OrgNextHead() - 1 : line("$") + let found = s:Range_Search(':\s*'. a:type . '\s*:','n',bottom,line) + if !found + while getline(line(".") + 1) =~ s:remstring + execute line('.')+1 + endwhile + "execute 'normal o:'. a:type . ':' + "execute 'normal o:END:' + "normal k + call append(line('.'),[ indent . ':' . a:type . ':' , indent . ':END:'] ) + execute line('.') + 1 + else + execute found + endif +endfunction + +function! OrgGetLink() + let savecursor = getpos('.') + + let linkdict = {'link':'','desc':''} + let curpos = getpos('.')[2] + call search('\[\[','bc',line('.')) + let startpos = getpos('.')[2] - 1 + call search(']]','ce',line('.')) + let endpos = getpos('.')[2] - 1 + if (curpos >= startpos) && (curpos <= endpos) + let linktext = getline(line("."))[ startpos : endpos ] + if linktext =~ ']\[' + let linkdict.link = matchstr(linktext,'\[\[\zs.*\ze]\[') + let linkdict.desc = matchstr(linktext,']\[\zs.*\ze]]') + else + let linkdict.link = matchstr(linktext,'\[\[\zs.*\ze]]') + endif + endif + call setpos('.',savecursor) + return linkdict +endfunction +function! FollowLink(ldict) + let ld = a:ldict + let ld.suffix = '' + "process things so org-compatible while still calling Utl + let prefix = matchstr(ld.link,'\S\{-1,}\ze:') + if exists(":Utl") == 0 + echo "The Vim plugin Utl.vim must be installed to follow links." + echo "You can find a copy at:" + echo 'http://www.vim.org/scripts/script.php?script_id=293' + return + endif + if prefix =~ g:org_unsupported_link_types + echo 'Link type "' . prefix '" not supported in VimOrganizer.' + return + endif + " now have to translate from org format to Utl format + if ld.link[0] ==# '#' + let ld.link = '#tn=:CUSTOM_ID:\s\*' . ld.link[1:] + let prefix = '#' + elseif prefix ==? 'file' && (ld.link[5] ==# '.') + " || ld.link[5:6] ==# '\S:') + " take file prefix out b/c Utl can't handle relative file paths + let ld.link = ld.link[5:] + endif + + if prefix ==? 'file' && (ld.link =~ '::') + let mylist = split(ld.link,'::') + let ld.link = mylist[0] + let ld.suffix = mylist[1] + endif + + if (prefix ==# '') || ((prefix !~ g:org_supported_link_types) && (prefix != '#')) + " we have org text search that needs different treatment + call FollowTextLink(a:ldict.link) + "for search_type in ['dedicated', 'headline1', 'headline2', 'general'] + " let savecursor = getpos('.') + " if search_type is 'dedicated' + " let newlink = '#tn=<<' . a:ldict.link . '>>' + " elseif search_type is 'headline1' + " let newlink = '#tn=' . b:v.todoMatch . a:ldict.link + " elseif search_type is 'headline2' + " let newlink = '#tn=^*\+ ' . a:ldict.link + " else + " let newlink = '#tn=' . a:ldict.link + " endif + + " let newlink = substitute(newlink,' ','\\ ','g') + " let g:newlink = newlink + " silent! exec 'Utl o '. newlink . ' split' + + " if line('.') != savecursor[1] + " break + " endif + "endfor + else + exec 'Utl o ' . ld.link . ' split' + if ld.suffix ># '' + call FollowTextLink(ld.suffix) + endif + end +endfunction +function! FollowTextLink(link) + for search_type in ['dedicated', 'headline1', 'headline2', 'general'] + let savecursor = getpos('.') + if search_type is 'dedicated' + let newlink = '#tn=<<' . a:link . '>>' + elseif search_type is 'headline1' + let newlink = '#tn=' . b:v.todoMatch . a:link + elseif search_type is 'headline2' + let newlink = '#tn=^*\+ ' . a:link + else + let newlink = '#tn=' . a:link + endif + + let newlink = substitute(newlink,' ','\\ ','g') + let g:newlink = newlink + silent! exec 'Utl o '. newlink . ' split' + + if line('.') != savecursor[1] + break + endif + endfor +endfunction +function! EditLink() + "is this here: and is this there: + let thislink = OrgGetLink() + + let link = input('Link: ', thislink.link) + let desc = input('Description: ', thislink.desc) + + if thislink.link !=# '' + "delete existing hyperlink + call search('\[\[','b',line('.')) + normal v/]]/e xx + endif + + silent exec 'normal i[[' . link . ']' . (desc ># '' ? '[' . desc . ']' : '') . ']' + echo '' +endfunction +function! OrgMouseDate() + let @x='' + let date='' + let save_cursor = getpos(".") + let found = '' + silent! let date = GetDateAtCursor() + call setpos('.',save_cursor) + let linkdict = OrgGetLink() + if date ># '' + let found='date' + let date = date[0:9] + elseif linkdict.link ># '' + let found= 'link' + else + call setpos(".",save_cursor) + " get area between colons, if any, in @x + normal T:vt:"xy + if (matchstr(@x,'\S\+') ># '') && (len(@x)<25) + let found = 'tag' + endif + endif + call setpos(".",save_cursor) + if found ==? 'date' + silent call s:RunCustom({'type':'agenda','agenda_date':date, 'agenda_duration':'d'}) + "call OrgRunAgenda(date,1,'',date) + " go to 8th line in agenda buf + execute 8 + elseif found ==? 'link' + call FollowLink(linkdict) + elseif found ==? 'tag' + "call OrgRunSearch('+'.@x) + silent call s:RunCustom({'type':'tags','spec':@x}) + else + echo 'Nothing found to search for.' + endif + +endfunction +function! s:SetColumnHead() +" NOT USED NOW, NEEDS to be redone since switch to using orgmode-style col +" specs + "let i = 0 + "while i < len(w:v.org_colview_list) + " let result .= '|' . s:PrePad(w:v.org_colview_list[i] , w:v.org_colview_list[i+1]) . ' ' + " let i += 2 + "endwhile + "let g:org_ColumnHead = result[:-2] +endfunction + +function! s:OrgSetColumnList(line_for_cols,...) + " call GetProperties making sure it gets inherited props (viz. COLUMNS) + let save_inherit_setting = s:include_inherited_props + let s:include_inherited_props = 1 + try + let column_prop = s:GetProperties(a:line_for_cols,0)['COLUMNS'] + finally + let s:include_inherited_props = save_inherit_setting + endtry + + if (a:0 >= 1) && (a:1==0) + " use 0 for master head, i.e., columns for entire doc + let w:v.org_columns_master_heading = a:1 + else + let w:v.org_columns_master_heading = s:OrgGetHead_l(a:line_for_cols) + endif + if (a:0 >= 2) && (a:2 ># '') + " use column spec that was passed in + let column_prop = a:2 + else + let w:v.org_current_columns = column_prop + endif + + let result = '' + let g:org_column_headers = '' + let i = 0 + + if column_prop ># '' + let w:v.org_colview_list=split(column_prop,' ') + else + let w:v.org_colview_list=[] + endif + + call s:SetColumnHeaders() + +endfunction +function! s:SetColumnHeaders() + " build g:org_column_headers + let g:org_column_headers = '' + let w:v.org_column_item_head = '' + for item in (w:v.org_colview_list) + let [ fmt, field, hdr ] = matchlist(item,'%\(\d*\)\(\S\{-}[^({]*\)(*\([^ )]*\)')[1:3] + let fmt = (fmt ==# '') ? '%-' . g:org_columns_default_width . 's' : ('%-' . fmt . 's') + if field ==# 'ITEM' + let w:v.org_column_item_head = (hdr=='') ? 'ITEM' : hdr + continue + endif + let g:org_column_headers .= printf('|' . fmt, (hdr ==# '') ? field : hdr ) + endfor + +endfunction +function! s:GetFoldColumns(line) + let save_inherit_setting = s:include_inherited_props + let s:include_inherited_props = 1 + try + let props = s:GetProperties(a:line,0) + finally + let s:include_inherited_props = save_inherit_setting + endtry + " build text string with column values + let result = '' + for item in (w:v.org_colview_list) + let [ fmt, field, hdr ] = matchlist(item,'%\(\d*\)\(\S\{-}[^({]*\)(*\(\S*\))*')[1:3] + if field ==# 'ITEM' | continue | endif + let fldtext = get(props,toupper(field),'') + let fmt = (fmt ==# '') ? g:org_columns_default_width : fmt + " truncate text if too long + "let fldtext = (len(fldtext)<=fmt) ? fldtext : (fldtext[:fmt-3] . '..') + let fldtext = (strchars(fldtext)<=fmt) ? fldtext : (fldtext[:fmt-3] . '..') + let result .= printf( '|%-'.fmt.'s', fldtext,'') + endfor + + return result + +endfunction +function! ToggleColumnView(master_head,col_spec) + + if w:v.columnview + let winnum = bufwinnr('ColHeadBuffer') + if winnum > 0 + execute "bw!" . bufnr('ColHeadBuffer') + endif + let w:v.columnview = 0 + else + call s:OrgSetColumnList(line('.'),a:master_head,a:col_spec) + call s:ColHeadWindow(w:v.org_column_item_head) + let w:v.columnview = 1 + endif +endfunction +function! ColumnStatusLine() + if exists('g:org_column_headers') + let part2 = s:PrePad(g:org_column_headers, winwidth(0)-13) + + return ' ' . w:v.org_column_item_head . part2 + endif +endfunction +function! s:AdjustItemLen() + " called on VimResized event, adjusts length of heading when folded + if &filetype != 'org' + return + endif + + if !exists('w:v.columnview') + let w:v={'columnview':0, 'org_item_len':100, 'org_colview_list':[],'org_current_columns':'','org_column_item_head':''} + endif + let i = 1 + let w:v.total_columns_width = 3 + let colspec = split(w:v.org_current_columns, ' ') + + for item in colspec + let [ flen, field ] = matchlist(item,'%\(\d*\)\(\S\{-}[^({]*\)')[1:2] + if field == 'ITEM' | continue | endif + let w:v.total_columns_width += (flen > 0) ? flen : g:org_columns_default_width + endfor + + let w:v.org_item_len = winwidth(0) - 10 - ((w:v.columnview==1) ? w:v.total_columns_width : 0) +endfunction +au VimResized * :call s:ResizedWin() +function! s:ResizedWin() + let curwin = winnr() + ""avoid using 'windo' b/c it screws up colheadbuffer's 0 height + for i in range(1,winnr('$')) + if getbufvar(winbufnr(i),'&filetype') == 'org' + exec i . 'wincmd w' + call s:AdjustItemLen() + endif + endfor + exec curwin . 'wincmd w' +endfunction + +function! CalendarChoice(day, month, year, week, dir) + let g:agenda_startdate = a:year.'-' . s:Pre0(a:month).'-'.s:Pre0(a:day) + "call OrgRunAgenda(g:agenda_startdate, g:org_agenda_days,g:org_search_spec) + silent call s:RunCustom({'type':'agenda','agenda_date':g:agenda_startdate, 'agenda_duration':'d', 'spec':g:org_search_spec}) +endfunction +function! CalendarInsertDate(day, month, year, week, dir) + if (a:year > 0) && (a:month>0) && (a:day>0) + let g:cal_list=[a:year,a:month,a:day] + endif + + "call confirm('got here') +endfunction +function! OrgFunc(func,...) + "not working, itnended to be general way to + " call script-local functions + let myfunc = function(''.s:SID().'_'.a:func) + if a:000 > 0 + let myargs = split(a:000,',') + else + let myargs = '' + endif +endfunction + +function! s:MyPopup() + call feedkeys("i\\") +endfunction + +let g:calendar_action = '' . s:SID() .'_CalendarChoice' +let b:v.ColorList=['purple', 'green', 'white', 'black','blue','red','orange','green'] +function! s:CompleteOrg(findstart, base) + if a:findstart + " locate the start of the word + let line = getline('.') + let start = col('.') - 1 + while (start > 0) && (line[start - 1] =~ '\a') + let start -= 1 + endwhile + return start + else + let prop = matchstr(getline(line(".")),'^\s*:\zs\s*\S\+\s*\ze:') + " find months matching with "a:base" + let res = [] + execute "let proplist = b:v." . prop . 'List' + "for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec") + for m in proplist + if m =~ '^' . a:base + call add(res, m) + endif + endfor + return res + endif +endfunction +"set completefunc=CompleteOrg + + +function! OrgFoldText(...) + " Create string used for folded text blocks + if a:0 == 1 + let l:line = getline(line(".")) + let foldstart = line(".") + else + let l:line = getline(v:foldstart) + let foldstart = v:foldstart + endif + let origline = l:line + let l:nextline = getline(foldstart + 1) + let myind = s:Ind(foldstart) + + "let level_highlight = hlID(b:v.foldcolors[myind]) + let level_highlight = hlID('OL' . (myind-1) . 'Folded') + + " get rid of header prefix + let l:line = substitute(l:line,'^\*\+\s*','','g') + let l:line = repeat(' ', s:Starcount(foldstart)+1) . l:line + let line_count = v:foldend - v:foldstart + + if l:line =~ b:v.drawerMatch + "let level_highlight = hlID('Title') + let level_highlight = hlID('Org_Drawer_Folded') + let l:line = repeat(' ', strchars(matchstr(l:line,'^ *'))-1) + \ . matchstr(l:line,'\S.*$') + let line_count = line_count - 1 + elseif l:line[0] ==? '#' + let level_highlight = hlID('VisualNOS') + elseif w:v.columnview==1 + let mytrim = w:v.org_item_len + let line = line[:mytrim] + else + let mytrim = w:v.org_item_len + let line = line[:mytrim] + endif + if exists('w:sparse_on') && w:sparse_on && (a:0 == 0) + let b:v.signstring= s:GetPlacedSignsString(bufnr("%")) + if match(b:v.signstring,'line='.v:foldstart.'\s\sid=\d\+\s\sname=fbegin') >=0 + "if index(b:v.sparse_list,v:foldstart) > -1 "v:foldstart == 10 + let l:line = '* * * * * * * * * * * ' . (v:foldend - v:foldstart) . ' lines skipped here * * * * * * *' + let l:line .= repeat(' ', winwidth(0)-strchars(l:line)-28) . 'SPARSETREE SKIP >>' + let level_highlight = hlID('TabLineFill') + endif + endif + if g:org_show_fold_dots + let l:line .= '...' + endif + let offset = &fdc + 5*(&number) + (w:v.columnview ? 7 : 1) + if w:v.columnview && (origline =~ b:v.headMatch) + if (w:v.org_columns_master_heading == 0) || s:HasAncestorHeadOf(foldstart,w:v.org_columns_master_heading) + let l:line .= s:PrePad(s:GetFoldColumns(foldstart), winwidth(0)-strchars(l:line) - offset) + else + let offset -= 6 + endif + endif + if a:0 && (foldclosed(line('.')) > 0) + let l:line .= s:PrePad("(" + \ . s:PrePad( (foldclosedend(line('.'))-foldclosed(line('.'))) . ")",5), + \ winwidth(0)-strchars(l:line) - offset) + elseif (g:org_show_fold_lines ) || (l:line =~ b:v.drawerMatch) + let offset = (w:v.columnview && l:line =~ b:v.drawerMatch) ? offset - 6 : offset + let l:line .= s:PrePad("|" . s:PrePad( line_count . "|",5), + \ winwidth(0)-strchars(l:line) - offset) + endif + if exists('v:foldhighlight') + if get(b:v.heading_marks_dict, v:foldstart) == 1 + let v:foldhighlight = hlID('CursorLine') + elseif foldstart == b:v.chosen_agenda_heading + let v:foldhighlight = hlID('Org_Chosen_Agenda_Heading' . (myind>6 ? '' : myind-1)) + else + let v:foldhighlight = level_highlight + endif + if exists('v:todohighlight') + if matchstr(origline, b:v.todoMatch) ># '' + let this_todo = matchstr(origline, '^\*\+ \zs\S*') + if hlID(this_todo) > 55 " > 55 avoids built-in todo group + let v:todohighlight = hlID(this_todo) + else + let v:todohighlight = ('* ' . this_todo =~ b:v.todoDoneMatch) ? hlID('DONETODO') : hlID('NOTDONETODO') + endif + else + let v:todohighlight=0 + endif + endif + endif + return l:line +endfunction +function! s:MySort(comppattern) range + let b:v.sortcompare = a:comppattern + let b:v.complist = ['\s*\S\+','\s*\S\+\s\+\zs\S\+','\s*\(\S\+\s\+\)\{2}\zs\S\+' + \ , '\s*\(\S\+\s\+\)\{3}\zs\S\+' + \ , '\s*\(\S\+\s\+\)\{4}\zs\S\+' + \ , '\s*\(\S\+\s\+\)\{5}\zs\S\+' + \ , '\s*\(\S\+\s\+\)\{6}\zs\S\+'] + let mylines = getline(a:firstline, a:lastline) + let mylines = sort(mylines,"s:BCompare") + call setline(a:firstline, mylines) + unlet b:v.sortcompare + unlet b:v.complist +endfunction + +function! s:BCompare(i1,i2) + if !exists('b:v.sortcompare') + echo 'b:v.sortcompare is not defined' + return + endif + let i = 0 + + while i < len(b:v.sortcompare) + " prefix an item by 'n' if you want numeric sorting + if (i < len(b:v.sortcompare) - 1) && (b:v.sortcompare[i] ==? 'n') + let i = i + 1 + let m1 = str2nr(matchstr(a:i1,b:v.complist[b:v.sortcompare[i]-1])) + let m2 = str2nr(matchstr(a:i2,b:v.complist[b:v.sortcompare[i]-1])) + else + let m1 = matchstr(a:i1,b:v.complist[b:v.sortcompare[i]-1]) + let m2 = matchstr(a:i2,b:v.complist[b:v.sortcompare[i]-1]) + endif + if m1 == m2 + if i == len(b:v.sortcompare) - 1 + return 0 + else + let i += 1 + continue + endif + elseif m1 > m2 + return 1 + else + return -1 + endif + endwhile +endfunction + +function! s:OrgShowMatch(cycleflag) + "wincmd k + " first, make sure agenda buffer has same heading pattern + " and todo list as main buffer + call s:GotoMainWindow() + let l:headMatch = b:v.headMatch + let l:todoitems = b:v.todoitems + "wincmd j + call s:GotoAgendaWindow() + let b:v.headMatch = l:headMatch + let b:v.todoitems = l:todoitems + if a:cycleflag + call OrgSequenceTodo(line(".")) + endif + "let g:showndx = line(".")-1 + if getline(line(".")) =~ '^\d\+' + let g:showndx = matchlist(getline(line(".")),'^\d\+')[0] + execute "let b:v.sparse_list = [" . g:showndx . ']' + endif + "wincmd k + call s:GotoMainWindow() + call OrgExpandWithoutText(1) + execute g:showndx + "execute g:alines[g:showndx] + normal zv + if a:cycleflag + call OrgSequenceTodo(line(".")) + endif + if getline(line(".")) =~ b:v.headMatch + call OrgBodyTextOperation(line("."),s:OrgNextHead(),'collapse') + endif + "wincmd j + call s:GotoAgendaWindow() +endfunction +command! MySynch call OrgShowMatch(0) +command! MySynchCycle call OrgShowMatch(1) +command! MyAgendaToBuf call OrgAgendaToBufTest() +command! AgendaMoveToBuf call s:OrgAgendaToBuf() + +command! -range CodeEval :call CodeEval +command! -buffer -nargs=* Agenda :call OrgAgendaCommand() +function! CodeEval() range + +endfunction + +function! OrgAgendaCommand(...) + if exists('a:1') + let mydate = a:1 + else + let mydate = s:Today() + endif + if exists('a:2') + let viewdays = a:2 + else + let viewdays = 'w' + endif + if exists('a:3') + let search_spec = a:3 + else + let search_spec = '' + endif + if mydate =~ '\d\d\d\d-\d\d-\d\d' + call OrgRunAgenda(mydate,viewdays,search_spec) + else + call OrgRunAgenda(DateCueResult(mydate,s:Today()),viewdays,search_spec) + endif +endfunction + +function! s:OrgAgendaToBufTest() + " this loads unfolded buffer into same window as Agenda + if getline(line(".")) =~ '^\d\+' + let thisline = getline(line('.')) + let g:tofile = s:filedict[str2nr(matchstr(thisline, '^\d\d\d'))] + let g:showndx = str2nr(matchstr(thisline,'^\d\d\d\zs\d*')) + "let g:showndx = matchlist(getline(line(".")),'^\d\+')[0] + "let g:tofile = matchlist(getline(line(".")),'^\d\+\s*\(\S\+\)')[1] + endif + let cur_buf = bufnr("%") + "let g:org_folds=0 + let newbuf = bufnr(g:tofile) + execute "b"newbuf + set ft=org + execute g:showndx + normal zv + "let g:org_folds=1 +endfunction +function! s:OrgAgendaToBuf() + let win = bufwinnr('Calendar') + + if win >= 0 + execute win . 'wincmd w' + wincmd c + execute bufwinnr('Agenda').'wincmd w' + endif + + if getline(line(".")) =~ '^\d\+' + let thisline = getline(line('.')) + let g:tofile = s:filedict[str2nr(matchstr(thisline, '^\d\d\d'))] + let g:showndx = str2nr(matchstr(thisline,'^\d\d\d\zs\d*')) + endif + let ag_line = line(".") + let ag_height = winheight(0) + let cur_buf = bufnr("%") " should be Agenda + close! + call org#LocateFile(g:tofile ) + + AAgenda + + call org#LocateFile(g:tofile ) + "if &fdm != 'expr' + " set fdm=expr + "endif + set foldlevel=1 + let newhead = matchstr(s:GetPlacedSignsString(bufnr("%")),'line=\zs\d\+\ze\s\+id=' . g:showndx) + let newhead = s:OrgGetHead_l(newhead) + execute newhead + + normal! zv + if getline(line('.')) =~ b:v.headMatch + "restrict to headings only + call s:OrgExpandSubtree(line('.'),0) + "call s:OrgExpandSubtree(g:showndx,0) + endif + + let b:v.chosen_agenda_heading = s:OrgGetHead() + call clearmatches() + let headlevel = s:Ind(b:v.chosen_agenda_heading) + let headlevel = (headlevel > 6) ? '' : headlevel-1 + call matchadd('Org_Chosen_Agenda_Heading' . headlevel,'\%' . b:v.chosen_agenda_heading .'l') + + execute bufwinnr('Agenda').'wincmd w' + + execute ag_line + resize + execute "resize " . ag_height + + if win >= 0 + Calendar + execute 1 + call org#LocateFile('__Agenda__') + endif +endfunction + +function! s:OrgSource() + unlet g:org_loaded + source $VIM/vimfiles/ftplugin/org.vim +endfunction + +function! s:OrgSetLevel(startlevel, endlevel) + "call OrgExpandWithoutText(a:endlevel) + call s:OrgExpandLevelText(a:startlevel, a:endlevel) +endfunction + +function! s:Starcount(line) + " used to get number of stars for a heading + return (len(matchstr(getline(a:line),'^\**\s'))-1) +endfunction + +function! s:GotoAgendaWindow() + "wincmd b + silent execute "b __Agenda__" +endfunction + +function! s:GotoMainWindow() + wincmd t +endfunction + +function! s:Ind(line) + " used to get level of a heading (todo : rename this function) + "return 1 + (len(matchstr(getline(a:line),'^\**\s'))-1)/b:v.levelstars + return 2 + (len(matchstr(getline(a:line),'^\**\s'))-2)/b:v.levelstars + +endfunction + +function! s:DoAllTextFold(line) + "let d = inputdialog('in fullfold') + if s:IsText(a:line+1) == 0 + return + endif + while ((s:NextVisibleHead(a:line) != foldclosedend(a:line) + 1) + \ && (foldclosedend(a:line) <= line("$")) + \ && (s:NextVisibleHead(a:line) != 0) + \ && (org#fold#level(a:line) =~ '>')) + \ || (foldclosedend(a:line) < 0) + \ || ((s:NextVisibleHead(a:line) == 0) && (s:OrgSubtreeLastLine() == line('$')) && (foldclosedend(a:line)!=line('$'))) + call OrgDoSingleFold(a:line) + endwhile +endfunction + +function! OrgDoSingleFold(line) + if (foldclosed(a:line) == -1) "&& (getline(a:line+1) !~ b:v.headMatch) + if (getline(a:line+1) !~ b:v.headMatch) || (s:Ind(a:line+1) > s:Ind(a:line)) + while (foldclosed(a:line) == -1) && (a:line != line('$')) + normal! zc + endwhile + endif + "elseif (foldclosed(a:line) < a:line) + " do nothing, line is not visible + else + let cur_end = foldclosedend(a:line) + " I know runaway can happen if at last heading in document, + " not sure where else + let runaway_count = 0 + if (cur_end >= line("$")) "|| (org#fold#level(cur_end+1) ==? '<0') + return + endif + if getline(cur_end+1) =~ b:v.drawerMatch + "while (foldclosedend(a:line) == cur_end) && (runaway_count < 10) + while (foldclosedend(a:line) == cur_end) && (cur_end != line("$")) + let runaway_count += 1 + normal! zc + endwhile + elseif getline(cur_end+1) !~ b:v.headMatch + "while (foldclosedend(a:line) == cur_end) && (runaway_count < 10) + while (foldclosedend(a:line) == cur_end) && (cur_end <= line("$")) + let runaway_count += 1 + normal! zc + endwhile + elseif (getline(cur_end+1) =~ b:v.headMatch) && (s:Ind(cur_end+1) > s:Ind(a:line)) + while (foldclosedend(a:line) == cur_end) && (cur_end != line("$")) + " let runaway_count += 1 + normal! zc + endwhile + endif + endif +endfunction + + +function! s:AlignSection(regex,skip,extra) range + " skip is first part of regex, 'regex' is part to match + " they must work together so that 'skip.regex' is matched + " and the point where they connect is where space is inserted + let extra = a:extra + let sep = empty(a:regex) ? '=' : a:regex + let minst = 999 + let maxst = 0 + let b:v.stposd = {} + let section = getline(a:firstline, a:lastline) + for line in section + let stpos = matchend(line,a:skip) + let b:v.stposd[index(section,line)]=stpos + if maxst < stpos + let maxst = stpos + endif + let stpos = len(matchstr(matchstr(line,a:skip),'\s*$')) + if minst > stpos + let minst = stpos + endif + endfor + call map(section, 's:AlignLine(v:val, sep, a:skip, minst, maxst - matchend(v:val,a:skip), extra)') + call setline(a:firstline, section) +endfunction + +function! s:AlignLine(line, sep, skip, maxpos, offset, extra) + let b:v.m = matchlist(a:line, '\(' .a:skip . '\)\('.a:sep.'.*\)') + if empty(b:v.m) + return a:line + endif + let spaces = repeat(' ', a:offset + a:extra) + exec 'return b:v.m[1][:-' . a:maxpos .'] . spaces . b:v.m[3]' +endfunction +function! s:AlignSectionR(regex,skip,extra) range + let extra = a:extra + let sep = empty(a:regex) ? '=' : a:regex + let minst = 999 + let maxpos = 0 + let maxst = 0 + let b:v.stposd = {} + let section = getline(a:firstline, a:lastline) + for line in section + execute 'let pos = matchend(line, a:skip ." *".sep)' + if maxpos < pos + let maxpos = pos + endif + let stpos = len(matchstr(matchstr(line,a:skip),'\s*$')) + if minst > stpos + let minst = stpos + endif + endfor + call map(section, 's:AlignLine(v:val, sep, a:skip, minst, maxpos - matchend(v:val,a:skip.sep) , extra)') + call setline(a:firstline, section) +endfunction +function! s:ColHeadWindow(itemhead,...) + if (a:0 >= 1) && (a:1 == 0) + if bufnr('ColHeadBuffer') > -1 + bw ColHeadBuffer + endif + return + endif + + au! BufEnter ColHeadBuffer + "let s:AgendaBufferName = 'ColHeadBuffer' + "call s:AgendaBufferOpen(1) + "let s:AgendaBufferName = '__Agenda__' + 1split ColHeadBuffer + call s:ScratchBufSetup() + + execute "setlocal statusline=%#OrgColumnHeadings#%{" . s:SID() . '_ColumnStatusLine()}' + set winfixheight + set winminheight=0 + let w:v = {'org_column_item_head': a:itemhead} + + wincmd j + " make lower window as big as possible to shrink + " ColHeadWindow to zero height + let curheight = winheight(0) + resize 100 + if bufwinnr('Agenda') > 0 + execute "resize " . curheight + endif + au BufEnter ColHeadBuffer call s:ColHeadBufferEnter() +endfunction + +function! s:ColHeadBufferEnter() + "prevents user from entering this buffer + "wincmd j +endfunction +" AgendaBufferOpen +" Open the scratch buffer +function! s:AgendaBufferOpen(new_win) + let save_sb = &splitbelow + let save_sr = &splitright + let split_win = a:new_win + let t = g:org_agenda_window_position + if t == 'top' + let g:vsplit=0 + set nosplitbelow + elseif t == 'bottom' + let g:vsplit = 0 + set splitbelow + elseif t == 'left' + let g:vsplit = 1 + set nosplitright + elseif t == 'right' + let g:vsplit = 1 + set splitright + endif + " If the current buffer is modified then open the scratch buffer in a new + " window + "if !split_win && &modified + " let split_win = 1 + "endif + + " Check whether the scratch buffer is already created + let scr_bufnum = bufnr(s:AgendaBufferName) + "if scr_bufnum == -1 + if scr_bufnum == -1 + " open a new scratch buffer + if split_win + if exists('g:vsplit') && (g:vsplit==1) + exe "vsplit __Agenda__" + else + exe "split __Agenda__" + endif + else + exe "edit " . s:AgendaBufferName + endif + else + " Agenda buffer is already created. Check whether it is open + " in one of the windows + let scr_winnum = bufwinnr(scr_bufnum) + if scr_winnum != -1 + " Jump to the window which has the scratch buffer if we are not + " already in that window + if winnr() != scr_winnum + exe scr_winnum . "wincmd w" + endif + else + " open a window and put existing Agenda in + if split_win + if exists('g:vsplit') && (g:vsplit==1) + exe "vsplit +buffer __Agenda__" + else + exe "split +buffer __Agenda__" + endif + + else + exe "buffer " . scr_bufnum + endif + endif + endif + let &splitbelow = save_sb + let &splitright = save_sr +endfunction + +command! EditAgendaFiles :call EditAgendaFiles() +command! OrgCycleAgendaForward :call CycleAgendaFiles('forward') +command! OrgCycleAgendaBackward :call CycleAgendaFiles('backward') +command! OrgChooseOrgBuffer :call OrgGotoChosenFile() +function! s:EditAgendaFiles() + call org#SaveLocation() + if !exists("g:agenda_files") || (g:agenda_files == []) + call s:CurfileAgenda() + endif + tabnew Edit_Agenda_Files + call s:ScratchBufSetup() + set buftype=acwrite + autocmd BufLeave :call SaveAgendaFiles(0) + autocmd BufWriteCmd :call SaveAgendaFiles(1) + command! W :call s:SaveAgendaFiles() + let msg = "These are your current agenda files:" + let msg2 = "Org files in your 'g:org_agenda_select_dirs' are below." + call setline(1,[msg]) + call append(1, repeat('-',winwidth(0)-5)) + call append("$",g:agenda_files + ['','']) + " change '\ ' to plain ' ' for current text in buffer + silent! execute '%s/\\ / /g' + let line = repeat('-',winwidth(0)-5) + call append("$",[line] + [msg2,"To add files to 'g:agenda_files' copy or move them ","to between the preceding lines and press :W to save (or :q to cancel):","",""]) + for item in g:org_agenda_select_dirs + for wild_card in g:org_filename_wildcards + let dir_files = split(globpath(item,wild_card),"\n") + endfor + let heading_path = substitute(expand('~'),'\','\\\\','g') + call map(dir_files,'substitute( v:val , ' . "'" . heading_path . "'" . ' , ''~'','''')') + call append("$",dir_files) + endfor +endfunction +function! s:SaveAgendaFiles(save) + " saves edited file list into g:agenda_files + " yank files into @a + set nomodified + if a:save == 1 + normal gg/^-- jV/^-- ?^\S "ay + let @a = substitute(@a,' ','\\ ','g') + if @a[0] != '-' + let g:agenda_files = split(@a,"\n") + else + let g:agenda_files=[] + endif + endif + :bw + delcommand W + call org#RestoreLocation() +endfunction +"function! s:CycleAgendaFiles() +" let i = 0 +" while i < len(g:agenda_files) +" if g:agenda_files[i] =~ bufname('%') . '$' +" let i += 1 +" break +" endif +" let i += 1 +" endwhile +" if i >= len(g:agenda_files) - 1 +" let i = 0 +" endif +" +" call org#LocateFile(g:agenda_files[i]) +"endfunction +function! s:ScratchBufSetup() + "setlocal buftype=nofile + setlocal buftype=nofile + setlocal bufhidden=hide + setlocal noswapfile + setlocal buflisted + setlocal fdc=1 +endfunction +function! s:Emacs2PDF() + silent !"c:program files (x86)\emacs\emacs\bin\emacs.exe" -batch --visit=newtest3.org --funcall org-export-as-pdf + "silent !c:\sumatra.exe newtest3.org +endfunction +function! s:Today() + return strftime("%Y-%m-%d") +endfunction + +function! OrgCustomSearchMenu() + if !exists('g:org_custom_searches') || empty(g:org_custom_searches) + echo "No custom searches defined." + else + echo " Press number to run custom search:" + echo " ----------------------------------" + let i = 1 + for item in g:org_custom_searches + if type(item)==type({}) + echo printf(" (%d) %-25s %10s", i, item.name, item.type ) + elseif type(item) == type([]) + echo printf(" (%d) %-25s %10s", i, item[0].name, item[0].type ) + for each in item[1:] + "echo printf(" (%d) %-25s %10s", i, each.name, each.type ) + echo printf(" + %-25s %10s", each.name, each.type ) + endfor + endif + let i += 1 + unlet item + endfor + echo " " + let key = nr2char(getchar()) + let itemnum = str2nr(key) + if itemnum > 0 && itemnum <= len(g:org_custom_searches) + call s:RunCustom( itemnum - 1 ) + else + echo 'No search was chosen.' + endif + endif +endfunction + +function! s:AgendaBlockNum(line) + let block_num = 0 + let sep_list = [] + silent g/^========/call add(sep_list,line('.')) + call add(sep_list,line('$')) + for i in range(1,len(sep_list)) + if a:line < sep_list[i-1] + let block_num = i + break + endif + endfor + return block_num +endfunction + +function! OrgAgendaFilesDashboard() + echohl MoreMsg + echo "" + echo " ======================================" + echo " Press key for an agenda files command:" + echo " --------------------------------------" + echo " e Edit agenda files" + if (bufname('%') != '__Agenda__') + echo " t Current file to top of agenda file list" + echo " b Current file to bottom of agenda file list" + echo " r Remove Current file from agenda file list" + endif + echo " n or f Cycle to next file in agenda files" + echo " p or b Cycle to previous file in agenda files" + echo " c or g Choose agenda file to goto" + echo "" + echohl None + let key = nr2char(getchar()) + redraw + if key =~? 'e' + EditAgendaFiles + elseif key =~? 't' + call CurrentToAgendaFiles('top') + elseif key =~? 'b' + call CurrentToAgendaFiles('bottom') + elseif key =~? 'r' + call CurrentRemoveFromAgendaFiles() + elseif key =~? 'n\|f' + call CycleAgendaFiles('forward') + elseif key =~? 'p\|b' + call CycleAgendaFiles('backward') + elseif key =~? 'c\|g' + call OrgGotoChosenFile() + else + echo "No option chosen." + endif + "endif +endfunction +function! OrgAgendaDashboard() + if (bufnr('__Agenda__') >= 0) && (bufwinnr('__Agenda__') == -1) + " move agenda to cur tab if it exists and is on a different tab + "let curtab = tabpagenr() + "" go to current agenda win and close it + "call org#LocateFile('__Agenda__') + "wincmd c + ""back to start tab and open + "execute "tabnext ".curtab + "split + "winc j + "buffer __Agenda__ + AAgenda + else + " show dashboard if there is no agenda buffer or it's + " already on this tab page + let restrict = 0 + let saved_afiles = [] + while 1 + echohl MoreMsg + echo "" + echo " ================================" + echo " Press key for an agenda command:" + echo " --------------------------------" + echo " a Agenda for current week" + echo " t List of all TODO entries" + echo " m Match a TAGS/PROP/TODO query" + echo " L Timeline for current buffer" + "echo ' s Freeform regex search, not heading-metadata' + echo " " + echo " c Show custom search menu" + echo " " + echo " h Headline-metadata-based sparse tree search" + echo " f Freeform (i.e., regex) sparse tree search" + echo " < restrict to current buffer" + if restrict == 1 + echo " Will restrict to current buffer. Press a key to choose search..." + endif + echo "" + echohl None + let key = nr2char(getchar()) + redraw + if key == '<' + let restrict = 1 + continue + else + break + endif + endwhile + if restrict == 1 + let save_win = winnr() + for winnum in range(1,winnr('$')) + exec winnum . 'wincmd w' + if expand('%') =~ '\.org$' + let saved_afiles = copy(g:agenda_files) + let g:agenda_files = [expand('%:p')] + break + endif + endfor + exec save_win . 'wincmd w' + endif + try + if key =~ '[tTaALcCmM]' && bufnr('__Agenda__') >= 0 + bwipeout __Agenda__ + endif + if key ==? 't' + "silent execute "call OrgRunSearch('+ANY_TODO','agenda_todo')" + silent call s:RunCustom({'type':'tags-todo','spec':'+ANY_TODO'}) + elseif key ==? 'a' + "if (g:org_search_spec ==# '') + "let g:org_search_spec = g:agenda_default_search_spec + "endif + "silent execute "call OrgRunAgenda(s:Today(),'w', g:org_agenda_default_search_spec)" + let today = s:Today() + silent call s:RunCustom({'type':'agenda','agenda_date':today, 'agenda_duration':'w'}) + + elseif key ==? 'L' + silent execute "call s:Timeline()" + elseif key ==? 'c' + execute "call OrgCustomSearchMenu()" + elseif key ==? 'm' + let mysearch = input("Enter search string: ") + silent call s:RunCustom({'type':'tags','spec':mysearch}) + "silent execute "call OrgRunSearch(mysearch)" + elseif key ==? 'h' + let g:org_sparse_spec = input("Enter search string: ") + if bufname("%") ==? '__Agenda__' + :bd + endif + silent execute "call OrgRunSearch(g:org_sparse_spec,1)" + elseif key ==? 'f' + let g:org_sparse_spec = input("Enter search string: ") + if bufname("%") ==? '__Agenda__' + :bd + endif + silent call s:SparseTreeRun(g:org_sparse_spec) + endif + finally + if bufname('%') == '__Agenda__' + if !exists("b:v") + let b:v = {} + endif + let b:v.agenda_files = copy(g:agenda_files) + let @/='' + endif + if len(saved_afiles) > 0 + let g:agenda_files = copy(saved_afiles) + endif + endtry + endif +endfunction + +function! s:AgendaBufSyntax() + "called once whenever new agenda buffer is opened from regular or date agenda + "searches + call s:AgendaHighlight() + syntax clear + if has("conceal") + syntax match Locator '^\d\+' conceal containedin=AOL1,AOL2,AOL3,AOL4,AOL5,agenda_todo,agenda_done,agenda_scheduled,agenda_scheduled_previous + syntax match TimeGridSpace '^ \{8}\ze *\d\d:\d\d' conceal containedin=agenda_timegrid + "for agenda clocktable + syn region Org_Full_Link concealends matchgroup=linkends start='\[\[\(.\{-1,}\)]\[' end=']]' + endif + syntax match agenda_timegrid '^\s*\d\d:\d\d.\{14}--.*' + syntax match AOL1 '^\d\+\s\+\S\+\s\{-1,16}\*\{1} .*$'hs=s+23 + syntax match AOL2 '^\d\+\s\+\S\+\s\{-1,16}\*\{2} .*$'hs=s+23 + syntax match AOL3 '^\d\+\s\+\S\+\s\{-1,16}\*\{3} .*$'hs=s+23 + syntax match AOL4 '^\d\+\s\+\S\+\s\{-1,16}\*\{4} .*$'hs=s+23 + syntax match AOL5 '^\d\+\s\+\S\+\s\{-1,16}\*\{5} .*$'hs=s+23 + + let donepat_fragment = '\(' . join(keys(g:org_todos_done_dict),'\|') . '\)' + let donepat = ' \*\+ \zs' . donepat_fragment . ' ' + exec "syntax match DONETODO /" . donepat . '/ containedin=AOL1,AOL2,AOL3,AOL4,AOL5' + let notdonepat_fragment = '\(' . join(keys(g:org_todos_notdone_dict),'\|') . '\)' + let notdonepat = ' \*\+ \zs' . notdonepat_fragment . ' ' + exec "syntax match NOTDONETODO /" . notdonepat . '/ containedin=AOL1,AOL2,AOL3,AOL4,AOL5' + + syntax match agenda_scheduled_previous '^\d\+\s\+\S\+\s\+Sched.\{-}:.*$' + syntax match agenda_scheduled '^\d\+\s\+\S\+\s\+Scheduled:.*$' + + exec 'syntax match agenda_todo /^\d\+\s\+\S\+\s\+\(In\|Deadline\|(\d\).\{-}:.\{-}\* ' . notdonepat_fragment . ' .*$/ contains=Locator' + exec 'syntax match agenda_done /^\d\+\s\+\S\+\s\+\(In\|Deadline\|(\d\).\{-}:.\{-}\* ' . donepat_fragment . ' .*$/' + let daytextpat = '/^[^S]\S\+\s\+\d\{1,2}\s\S\+\s\d\d\d\d.*/' + let wkendtextpat = '/^S\S\+\s\+\d\{1,2}\s\S\+\s\d\d\d\d.*/' + exec 'syntax match agenda_date ' . daytextpat + + exec 'syntax match agenda_weekenddate ' . wkendtextpat + syntax match agenda_omitted_days ' \[\. \..\{-}empty days omitted \]' + + " call to set up syntax and highlights for custom todos in agenda + call s:OrgCustomTodoHighlights() + +endfunction +function! s:AgendaHighlight() + if g:org_gray_agenda + hi link AOL1 NONE + hi link AOL2 NONE + hi link AOL3 NONE + hi link AOL4 NONE + hi link AOL5 NONE + hi Deadline guifg=lightred + hi Scheduled guifg=lightyellow + else + hi link AOL1 OL1 + hi link AOL2 OL2 + hi link AOL3 OL3 + hi link AOL4 OL4 + hi link AOL5 OL5 + hi Deadline guifg=NONE + hi Scheduled guifg=NONE + endif +endfunction + +function! OrgScreenLines() range + " returns lines as + " seen on screen, including folded text overlays + " Call with visual selection set, or will + " use last selection + let save_cursor = getpos('.') + let newline=0 + let oldline=1 + let mylines=[] + normal '> + let endline = line('.') + " go to first line of selection + normal '< + while (line('.') <= endline) && (newline != oldline) + let oldline=line('.') + let newline=oldline + call add(mylines,OrgFoldText(line('.'))) + normal j + let newline=line('.') + endwhile + call setpos('.',save_cursor) + return mylines +endfunction + +function! s:CurTodo(line) + let result = matchstr(getline(a:line),'.*\* \zs\S\+\ze ') + if index(b:v.todoitems,curtodo) == -1 + let result = '' + endif + return result +endfunction + +"autocmd CursorHold * call s:Timer() +function! s:Timer() + call feedkeys("f\e") + " K_IGNORE keycode does not work after version 7.2.025) + echo strftime("%c") + " there are numerous other keysequences that you can use +endfunction + +autocmd BufNewFile __Agenda__ call s:ScratchBufSetup() +"autocmd BufWinEnter __Agenda__ call s:AgendaBufSyntax() +" Command to edit the scratch buffer in the current window +"command! -nargs=0 Agenda call s:AgendaBufferOpen(0) +" Command to open the scratch buffer in a new split window +command! -nargs=0 AAgenda call s:AgendaBufferOpen(1) +command! -nargs=0 EditAgenda call s:AgendaBufferOpen(0) + +command! -nargs=0 OrgToPDF :call s:ExportToPDF() +command! -nargs=0 OrgToHTML :call s:ExportToHTML() +command! -nargs=0 OrgToAscii :call s:ExportToAscii() +command! -nargs=0 OrgToDocBook :call s:ExportToDocBook() +function! s:OrgHasEmacsVar() + let result = 1 + if !exists('g:org_command_for_emacsclient') + let msg = "=============================================== \n" + \ . "You're trying to call out to Emacs but \n" + \ . "you haven't set an Emacs command variable. \n" + \ . "You should set this in your vimrc by including \n" + \ . "a line like: \n\n" + \ . " let g:org_command_for_emacsclient=[put command to start emacs here] \n\n" + \ . "See :h vimorg-emacs-setup for more info. \n\n" + \ . "The call you attempted to Emacs will now be aborted. \n" + \ . "Revise your vimrc and restart Vim to use this feature.\n" + \ . "==============================================\n" + \ . "Press to continue." + call input(msg) + let result = 0 + endif + return result +endfunction +function! OrgGetClocktable(filelist, options) + let i = 0 + let filelist = copy(a:filelist) + let filestr = '' + while i < len(filelist) + let filelist[i] = substitute(expand(filelist[i]),'\','/','g') + let filelist[i] = '"' . substitute(filelist[i],' ','\ ','g') . '" ' + let filestr .= filelist[i] + let i += 1 + endwhile + let clkfile = '~/cblock.org' + + let mylist = ['#+BEGIN: clocktable :scope (' . filestr . ') ' . a:options ,'','#+END:',''] + + call writefile(mylist, expand(clkfile) ) + + let part1 = '(let ((org-confirm-babel-evaluate nil)(buf (find-file \' . s:cmd_line_quote_fix . '"' . clkfile . '\' . s:cmd_line_quote_fix . '"' . '))) (progn (org-dblock-update)(save-buffer buf)(kill-buffer buf)))' + let orgcmd = g:org_command_for_emacsclient . ' --eval ' . s:cmd_line_quote_fix . '"' . part1 . s:cmd_line_quote_fix . '"' + "redraw + "unsilent echo "Calculating in Emacs. . . " + if exists('*xolox#shell#execute') + silent call xolox#shell#execute(orgcmd, 1) + else + silent exe '!' . orgcmd + endif + + return readfile(expand('~/cblock.org')) +endfunction +function! OrgEvalBlock() + let savecursor = getpos('.') + let save_showcmd = &showcmd | set noshowcmd + + let start = search('^#+begin:','bnW','') + let prev_end = search('^#+end','bnW','') + let end = search('^#+end','nW','') + if (start == 0) || (end == 0) || ( ( prev_end > start ) && (prev_end < line('.') ) ) + unsilent echo "You aren't in a dynamic block." + return + endif + + exec start + let block_name = matchstr(getline(line('.')),'\c^#+BEGIN:\s*\zs\S\+') + + if start < end - 1 + exec (start+1) . ',' . (end-1) . 'delete' + endif + exec start + let line_mark = '@@@@@' . start . '@e@f@g@h' + exec 'normal o' . line_mark + + silent write! + let this_file = substitute(expand("%:p"),'\','/','g') + let this_file = substitute(this_file,' ','\ ','g') + + let part1 = '(let ((org-confirm-babel-evaluate nil)(buf (find-file \' . s:cmd_line_quote_fix . '"' . this_file . '\' . s:cmd_line_quote_fix . '"' . '))) (progn (search-forward \^"' . line_mark . '\^" )(forward-line -1)(org-dblock-update)(beginning-of-line)(set-mark (point))(re-search-forward \^"^#\\+END\^")(end-of-line)(write-region (mark) (point) \' . s:cmd_line_quote_fix . '"~/org-block.org\' . s:cmd_line_quote_fix . '")(set-buffer buf) (not-modified) (kill-this-buffer)))' + " line below was using org-narrow-to-block, which may use again + "let part1 = '(let ((org-confirm-babel-evaluate nil)(buf (find-file \' . s:cmd_line_quote_fix . '"' . this_file . '\' . s:cmd_line_quote_fix . '"' . '))) (progn (search-forward \^"' . line_mark . '\^" )(forward-line -1)(org-dblock-update)(org-narrow-to-block)(write-region (point-min) (point-max) \' . s:cmd_line_quote_fix . '"~/org-block.org\' . s:cmd_line_quote_fix . '")(set-buffer buf) (not-modified) (kill-this-buffer)))' + let orgcmd = g:org_command_for_emacsclient . ' --eval ' . s:cmd_line_quote_fix . '"' . part1 . s:cmd_line_quote_fix . '"' + redraw + unsilent echo "Calculating in Emacs. . . " + if exists('*xolox#shell#execute') + silent call xolox#shell#execute(orgcmd, 1) + else + silent exe '!' . orgcmd + endif + let g:orgcmd = orgcmd + exec start + normal 3ddk + silent exe 'read ~/org-block.org' + redraw + unsilent echo "Block is being evaluated in Emacs. . . Evaluation complete." + + let &showcmd = save_showcmd + call setpos('.',savecursor) + "return readfile(expand('~/org-block.org')) +endfunction + +function! s:OrgTableOptionList(A,L,P) + return keys(s:OrgTableEvalOptions()) +endfunction +command! -buffer -nargs=? -complete=customlist,s:OrgTableOptions OrgTblEval :call OrgEvalTable() +function! s:OrgTableEvalOptions() + return { 'col_right':'org-table-move-column-right', + \ 'col_left': 'org-table-move-column-left', + \ 'col_delete': 'org-table-delete-column', + \ 'col_insert': 'org-table-insert-column', + \ 'row_down': 'org-table-move-row-down', + \ 'row_up': 'org-table-move-row-up', + \ 'row_delete': 'org-table-kill-row', + \ 'row_insert': 'org-table-insert-row', + \ 'row_sort_region_alpha': 'org-table-sort-lines nil ?a', + \ 'row_sort_region_numeric': 'org-table-sort-lines nil ?n', + \ 'row_sort_region_alpha_reverse': 'org-table-sort-lines nil ?A', + \ 'row_sort_region_numeric_reverse': 'org-table-sort-lines nil ?N', + \ 'row_hline_insert': 'org-table-insert-hline', + \ 'convert_region_to_table':'org-table-convert-region (point-min) (point-max)' } +endfunction + +command! -buffer -nargs=0 OrgTableDashboard :call OrgTableDashboard() +function! OrgTableDashboard() + if s:OrgHasEmacsVar() == 0 + return + endif + let save_more = &more | set nomore + let save_showcmd = &showcmd | set noshowcmd + " different dashboard for "in table" and "not in table" + " show export dashboard + if getline(line('.')) =~ '^\s*$' + let rows_cols = input("Create new table (enter rows, columns): ") + if rows_cols =~ '^\d\+\s*,\s*\d\+$' + let [rows,cols] = split(rows_cols,',') + call org#tbl#create(cols,rows) + elseif rows_cols =~ '^\d\+\s\+\d\+$' + let [rows,cols] = split(rows_cols,' ') + call org#tbl#create(cols,rows) + endif + return + endif + echohl MoreMsg + echo " --------------------------------" + echo " Press key for table operation:" + echo " --------------------------------" + if getline(line('.')) !~ b:v.tableMatch + let mydict = { 't' : 'convert_region_to_table'} + echo " [t] Create (t)able from current block" + else + let mydict = { 'l':'col_left', 'r':'col_right', 'e':'col_delete', 'o':'col_insert', + \ 'd':'row_down', 'u':'row_up', 'x':'row_delete', + \ 'i':'row_insert', 'a':'row_sort_region_alpha', 'A':'row_sort_region_alpha_reverse', + \ 'n':'row_sort_region_numeric', 'N':'row_sort_region_numeric', 'h':'row_hline_insert' + \ } + echo " COLUMN: [l] Move left [r] Move right [e] Delete [o] Insert" + echo " ROW: [d] Move down [u] Move up [x] Delete [i] Insert" + echo " " + echo " RowSort: [a] alpha(a-z) [A] alpha(z-a)" + echo " [n] numeric(1..9) [N] numeric(9-1)" + echo "" + echo " [h] insert horizontal line" + endif + echo " " + echohl None + let key = nr2char(getchar()) + for item in keys(mydict) + if key == 't' + let thisline = getline(line('.')) + if thisline !~ '^\s*$' + let firstline = search('^\s*$','nb','') + 1 + let lastline = search('^\s*$','n','') - 1 + exec firstline . ',' . lastline . 'call OrgEvalTable(mydict[item])' + else + echo "You aren't in a block of text." + endif + break + elseif (key =~# item) + exec 'OrgTblEval ' . mydict[item] + break + endif + endfor + let &more = save_more + let &showcmd = save_showcmd + +endfunction + +function! OrgEvalTable(...) range + let options = s:OrgTableEvalOptions() + if a:0 == 1 + let opt = a:1 + let opt_cmd = '(' . options[opt] . ')' + else + let opt = 'just_eval' + let opt_cmd = '' + endif + let savecursor = getpos('.') + if a:firstline == a:lastline + " get start, end for whole table + "call search('^\s*[^|]','b','') + call search('^\(\s*|\)\@!','b','') + let start=line('.') + call search('^\(\s*|\)\@!','','') + let end=line('.') + else + let start=a:firstline + let end =a:lastline + endif + let line_offset = savecursor[1] - start + 1 + "let line_offset = savecursor[1] - start + " find first line after table block and check for formulas + exe start . ',' . end . 'w! ~/org-tbl-block.org' + if opt != 'convert_region_to_table' + let part1 = '(let ((org-confirm-babel-evaluate nil)' + \ . '(buf (find-file \' . s:cmd_line_quote_fix . '"~/org-tbl-block.org\' . s:cmd_line_quote_fix . '"' . ')))' + \ . '(progn (beginning-of-line ' . line_offset . ')(forward-char ' . savecursor[2] .')' + \ . '(org-table-maybe-eval-formula)' + \ . ((opt=='just_eval') ? '' : '(unwind-protect ') . opt_cmd + \ . '(org-table-recalculate-buffer-tables)(save-buffer buf)(kill-buffer buf))))' + else + let part1 = '(let ((org-confirm-babel-evaluate nil)' + \ . '(buf (find-file \' . s:cmd_line_quote_fix . '"~/org-tbl-block.org\' . s:cmd_line_quote_fix . '"' . ')))' + \ . '(progn (beginning-of-line ' . line_offset . ')(forward-char ' . savecursor[2] .')' + \ . '(goto-char (point-min))(set-mark (point))(goto-char (point-max))' . opt_cmd + \ . '(save-buffer buf)(kill-buffer buf)))' + endif + let orgcmd = g:org_command_for_emacsclient . ' --eval ' . s:cmd_line_quote_fix . '"' . part1 . s:cmd_line_quote_fix . '"' + redraw + unsilent echo "Calculating in Emacs. . . " + + let g:orgcmd = orgcmd + + "if exists('*xolox#shell#execute') + " silent let myx = xolox#shell#execute(orgcmd . '| cat', 1) + "else + silent exe '!' . orgcmd + "endif + exe start .',' . end . 'read ~/org-tbl-block.org' + exe start . ',' . end . 'd' + redraw + unsilent echo "Calculating in Emacs. . . Calculations complete. " + "else + " unsilent echo "No #+TBLFM line at end of table, so no calculations necessary." + "endif + call setpos('.',savecursor) +endfunction +function! OrgEval() + if s:OrgHasEmacsVar() == 0 + call confirm('VimOrganizer has not been configured to make calls to Emacs.' + \ . "\nPlease see :h vimorg-emacs-setup.") + return + endif + " check if we're in source block + let line = getline(line('.')) + let start = search('\c^#+begin_src','cbnW','') + let prev_end = search('\c^#+end_src','bnW','') + let end = search('\c^#+end_src','cnW','') + if (start > 0) && (end > start) && ( prev_end < start ) + call OrgEvalSource() + return + endif + " check if we're in dynamic block + let start = search('^#+begin:','bnW','') + let prev_end = search('^#+end','bnW','') + let end = search('^#+end','nW','') + if (start > 0) && (end > start) && ( prev_end < start ) + call OrgEvalBlock() + return + endif + "check if we're in a table + if line =~ '^\s*|.*|\s*$' + call OrgEvalTable() + return + endif + + unsilent echo "No evaluation done. You must be in a table, or on an initial " + \ . "\nblock line that begins in col 0 with #+BEGIN . . ." + +endfunction + +function! OrgEvalSource() + let savecursor = getpos('.') + let start = search('^#+begin_src','cbnW','') - 1 + let prev_end = search('^#+end_src','bnW','') + let end = search('^#+end_src','cnW','') + if (start == -1) || (end == 0) || ( ( prev_end > start ) && (prev_end < line('.') ) ) + unsilent echo "You aren't in a code block." + return + endif + exec end + " include results if there is result block w/in a couple of lines + if ( search('^\s*#+results','nW','') - end ) <= 3 + call search('^\s*#+results','','') + if getline(line('.')+1) =~ '#+BEGIN_RESULT' + call search('^#+END_RESULT') + normal j + else + " :'s used as linebegins w/first blank line as end of result block + call search('^\s*$','','') + endif + normal k + let end = line('.') + endif + exe start . ',' . end . 'w! ~/org-src-block.org' + let part1 = '(let ((org-confirm-babel-evaluate nil)) (progn (find-file \' . s:cmd_line_quote_fix . '"~/org-src-block.org\' . s:cmd_line_quote_fix . '"' . ')(org-babel-next-src-block)(org-babel-execute-src-block)(save-buffer)(kill-buffer)))' + let orgcmd = g:org_command_for_emacsclient . ' --eval ' . s:cmd_line_quote_fix . '"' . part1 . s:cmd_line_quote_fix . '"' + if exists('*xolox#shell#execute') + silent call xolox#shell#execute(orgcmd, 1) + else + silent exe "!" . orgcmd + endif + exe start .',' . end . 'read ~/org-src-block.org' + exe start . ',' . end . 'd' + call setpos('.',savecursor) +endfunction +function! MyExpTest() + let g:orgpath='c:\users\herbert\emacsclientw.exe --eval ' + let g:myfilename = substitute(expand("%:p"),'\','/','g') + let g:myfilename = substitute(g:myfilename, '/ ','\ ','g') + let g:myvar = '(let ((org-export-babel-evaluate nil)) (progn (find-file \^' . '"' . g:myfilename . '\^' . '"' . ') (org-export-as-html-and-open 3) (kill-buffer) ))' + let g:myc = '!' . g:orgpath . '^"' . g:myvar . '^"' + silent exec g:myc +endfunction +function! OrgExportDashboard() + if s:OrgHasEmacsVar() == 0 + return + endif + let save_more = &more | set nomore + let save_showcmd = &showcmd | set noshowcmd + " show export dashboard + "let mydict = { 't':'template', 'a':'ascii', 'n':'latin1', 'u':'utf8', + let mydict = { 't':'template', 'a':'ascii', 'A':'ascii', 'o':'odt', 'O':'odt-and-open', + \ 'n':'latin1', 'N':'latin1', 'u':'utf8','U':'utf8', + \ 'h':'html', 'b':'html-and-open', 'l':'latex', + \ 'f':'freemind', 'j':'taskjuggler', 'k':'taskjuggler-and-open', + \ 'p':'pdf', 'd':'pdf-and-open', 'D':'docbook', 'g':'tangle', + \ 'F':'current-file', 'P':'current-project', 'E':'all' } + echohl MoreMsg + echo " Press key for export operation:" + echo " --------------------------------" + echo " [t] insert the export options template block" + echo " " + echo " [a/n/u] export as ASCII/Latin1/utf8 [A/N/U] ...and open in buffer" + echo " " + echo " [h] export as HTML" + echo " [b] export as HTML and open in browser" + echo " " + echo " [l] export as LaTeX" + echo " [p] export as LaTeX and process to PDF" + echo " [d] . . . and open PDF file" + echo " " + echo " [o] export as ODT [O] as ODT and open" + echo " [D] export as DocBook" + echo " [V] export as DocBook, process to PDF, and open" + echo " [x] export as XOXO [j] export as TaskJuggler" + echo " [m] export as Freemind [k] export as TaskJuggler and open" + + echo " [g] tangle file" + echo " " + echo " [F] publish current file" + echo " [P] publish current project" + echo " [E] publish all projects" + echo " " + echohl None + let key = nr2char(getchar()) + for item in keys(mydict) + if (item ==# key) && (item !=# 't') + "let g:org_emacs_autoconvert = 1 + "call s:GlobalUnconvertTags(changenr()) + let exportfile = expand('%:t') + silent exec 'write' + + let orgpath = g:org_command_for_emacsclient . ' -n --eval ' + let g:myfilename = substitute(expand("%:p"),'\','/','g') + let g:myfilename = substitute(g:myfilename, '/ ','\ ','g') + " set org-mode to either auto-evaluate all exec blocks or evaluate none w/o + " confirming each with yes/no + if g:org_export_babel_evaluate == 1 + let g:mypart1 = '(let ((org-export-babel-evaluate t)(org-confirm-babel-evaluate nil)' + else + let g:mypart1 = '(let ((org-export-babel-evaluate nil)' + endif + let g:mypart1 .= '(buf (find-file \' . s:cmd_line_quote_fix . '"' . g:myfilename . '\' . s:cmd_line_quote_fix . '"))) (progn (' + + if item =~? 'g' + let g:mypart3 = ' ) (set-buffer buf) (not-modified) (kill-this-buffer) ))' + else + let g:mypart3 = ' nil ) (set-buffer buf) (not-modified) (kill-this-buffer) ))' + endif + + if item =~# 'F\|P\|E' + let command_part2 = ' org-publish-' . mydict[key] + elseif item == 'g' + let command_part2 = ' org-babel-tangle' + else + let command_part2 = ' org-export-as-' . mydict[key] + endif + + let orgcmd = orgpath . s:cmd_line_quote_fix . '"' . g:mypart1 . command_part2 . g:mypart3 . s:cmd_line_quote_fix . '"' + let g:orgcmd = orgcmd + " execute the call out to emacs + redraw + echo "Export in progress. . . " + if exists('*xolox#shell#execute') + "silent! let g:expmsg = xolox#shell#execute(orgcmd . ' | cat ', 1) + silent! call xolox#shell#execute(orgcmd , 1) + else + "execute '!' . orgcmd + silent! execute '!' . orgcmd + endif + redraw + echo "Export in progress. . . Export complete." + break + endif + endfor + if key ==# 't' + let template = [ + \ '#+TITLE: ' . expand("%p") + \ ,'#+AUTHOR: ' + \ ,'#+EMAIL: ' + \ ,'#+DATE: ' . strftime("%Y %b %d %H:%M") + \ ,'#+DESCRIPTION: ' + \ ,'#+KEYWORDS: ' + \ ,'#+LANGUAGE: en' + \ ,'#+OPTIONS: H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t' + \ ,'#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc' + \ ,'#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js' + \ ,'#+EXPORT_SELECT_TAGS: export' + \ ,'#+EXPORT_EXCLUDE_TAGS: noexport' + \ ,'#+LINK_UP: ' + \ ,'#+LINK_HOME: ' + \ ,'#+XSLT: ' + \ ] + silent call append(line('.')-1,template) + elseif key =~# 'A\|N\|U' + exec 'split ' . expand('%:r') . '.txt' + normal gg + endif + + let &more = save_more + let &showcmd = save_showcmd + +endfunction + +function! s:MailLookup() + Utl openlink https://mail.google.com/mail/?hl=en&shva=1#search/after:2010-10-24+before:2010-10-26 + "https://mail.google.com/mail/?hl=en&shva=1#search/after%3A2010-10-24+before%3A2010-10-26 +endfunction +function! s:UniqueList(list) + " returns the union of two lists + " (some algo ...) + let rdict = {} + for item in a:list + let rdict[item] = 1 + endfor + return sort(map(keys(rdict),'str2nr(v:val)')) +endfunc +function! s:Union(list1, list2) + " returns the union of two lists + " (some algo ...) + let rdict = {} + for item in a:list1 + let rdict[item] = 1 + endfor + for item in a:list2 + let rdict[item] = 1 + endfor + return sort(keys(rdict)) +endfunc +function! s:Intersect(list1, list2) + " returns the intersection of two lists + " (some algo ...) + " fro andy wokula on vim-use mailing list + let rdict = {} + for item in a:list1 + if has_key(rdict, item) + let rdict[item] += 1 + else + let rdict[item] = 1 + endif + endfor + for item in a:list2 + if has_key(rdict, item) + let rdict[item] += 1 + else + let rdict[item] = 1 + endif + endfor + call filter(rdict, 'v:val == 2') + return sort(keys(rdict)) +endfunc + +function! OrgSetEmphasis( emph_char ) range + let emph_char = a:emph_char + let my_mode = mode() + if my_mode ==? 'v' + exe 'normal oi' . emph_char + exe 'normal gvoi' . emph_char + else + exe 'normal i' . emph_char . emph_char + endif +endfunction + +function! s:OrgCustomTodoHighlights() + if !exists('g:org_todo_custom_highlights') + return + endif + for item in keys(g:org_todo_custom_highlights) + let d = g:org_todo_custom_highlights + if has('gui_running') + let fg = get(d[item], 'guifg') + let bg = get(d[item], 'guibg') + exec 'hi! ' . item . ((fg>#'') ? ' guifg=' . fg : '') . ((bg>#'') ? ' guibg=' . bg : '') + else + let fg = get(d[item], 'ctermfg') + let bg = get(d[item], 'ctermfg') + exec 'hi! ' . item . ((fg>#'') ? ' ctermfg=' . fg : '') . ((bg>#'') ? ' ctermbg=' . bg : '') + endif + + " xxxx todo put back in containedins, do synclears? check order? + if bufname('%')=='__Agenda__' + exec 'syntax match ' . item . ' ' . '+ \*\+ \zs' . item . ' + containedin=AOL1,AOL2,AOL3,AOL4,AOL5,AOL6' + else + " delete current match if it already exists + let mymatches = getmatches() + let tempdict = {} + for i in range(0, len(mymatches)-1) + let tempdict[i] = mymatches[i] + endfor + for i in keys(tempdict) + if tempdict[i].group == item + exec 'syntax clear ' . tempdict[i].group + break + endif + endfor + "now put new match in + exec 'syntax match ' . item . ' ' . '+\*\+ \zs' . item . ' + containedin=OL1,OL2,OL3,OL4,OL5,OL6' + endif + + endfor +endfunction + +function! OrgSetColors() + " Set highlights for outline headings. These are set from existing + " highlights in a colorscheme: + " OL1 from Statement + " OL2 from Identifier + " OL3 from Constant + " OL4 from Comment + " OL5 from Special + for pair in [ ['OL1','Statement'], ['OL2','Identifier'], ['OL3','Constant'], + \ ['OL4','Comment'], ['OL5','Special'] ] + execute 'hi clear ' . pair[0] + execute 'hi clear ' . pair[0] .'Folded' + execute 'hi ' . pair[0] . ' ' . org#GetGroupHighlight( pair[1] ) + execute 'hi ' . pair[0] . 'Folded ' . org#GetGroupHighlight( pair[1] ) + execute 'hi ' . pair[0] . ' gui=NONE' + execute 'hi ' . pair[0] . 'Folded gui=bold' + endfor + + if has('gui_running') + hi! FoldColumn guifg=bg guibg=bg + else + try + hi! FoldColumn ctermfg=bg ctermbg=bg + catch + hi! FoldColumn ctermfg=0 ctermbg=0 + endtry + endif + + "show text on SignColumn + hi! SignColumn guibg=fg guibg=bg + + + " various text item "highlightings" are below + " change to suit your taste and put in OrgCustomColors() (see below) + hi! Org_Drawer guifg=pink ctermfg=magenta + hi! Org_Drawer_Folded guifg=pink ctermfg=magenta gui=bold cterm=bold + hi! Org_Property_Value guifg=pink ctermfg=magenta + hi! Org_Block guifg=#555555 ctermfg=magenta + hi! Org_Src_Block guifg=#555555 ctermfg=magenta + hi! Org_Table guifg=#888888 guibg=#333333 ctermfg=magenta + hi! Org_Config_Line guifg=darkgray ctermfg=magenta + hi! Org_Tag guifg=lightgreen ctermfg=blue + hi! Org_Date guifg=magenta ctermfg=magenta gui=underline cterm=underline + hi! Org_Star guifg=#444444 ctermfg=darkgray + hi! Props guifg=#ffa0a0 ctermfg=gray + hi! Org_Code guifg=darkgray gui=bold ctermfg=14 + hi! Org_Itals gui=italic guifg=#aaaaaa ctermfg=lightgray + hi! Org_Bold gui=bold guifg=#aaaaaa ctermfg=lightgray + hi! Org_Underline gui=underline guifg=#aaaaaa ctermfg=lightgray + hi! Org_Marked gui=bold guibg=#bbaacc ctermbg=lightgray + hi! Org_Lnumber guifg=#999999 ctermfg=gray + + " agenda highlight groups below + hi Overdue guifg=red + hi Upcoming guifg=yellow + hi DateType guifg=#dd66bb + hi Locator guifg=#333333 + + "hi agenda_dayline guifg=#44aa44 gui=underline + "hi agenda_weekendline guifg=#55ee55 gui=underline + hi agenda_omitted_days guifg=#555555 ctermfg=gray + hi agenda_todo guifg=lightred gui=bold ctermfg=lightred cterm=bold + hi agenda_done guifg=lightgreen ctermfg=lightgreen + hi agenda_date guifg=lightblue ctermfg=lightblue + hi agenda_weekenddate guifg=lightblue gui=bold ctermfg=lightblue cterm=bold + hi agenda_scheduled guifg=lightyellow ctermfg=lightyellow + hi agenda_scheduled_previous guifg=lightmagenta ctermfg=lightmagenta + hi agenda_timegrid guifg=#666666 ctermfg=gray + " end agenda highlights + + if has("conceal") + hi! default linkends guifg=blue ctermfg=blue + endif + hi! Org_Full_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + hi! Org_Half_Link guifg=cyan gui=underline ctermfg=lightblue cterm=underline + highlight OrgColumnHeadings guibg=#444444 guifg=#aaaaaa gui=underline + + hi! DONETODO guifg=green ctermfg=green + hi! NOTDONETODO guifg=red ctermfg=lightred + + "user can define OrgCustomColors() in vimrc for above items, these will be executed + "here and override the defaults above. + if exists('*OrgCustomColors') + call OrgCustomColors() + endif + + call s:OrgCustomTodoHighlights() + + " below is for setting highlight groups for when agenda is used to + " select a headline in main doc, or when items are marked. + " Use g:org_selector_ctermbg and/or g:org_selector_guibg + " to customize. + for i in range(1,5) + let hlstring = org#GetGroupHighlight('OL' . i) + let ctermbg = 'ctermbg=' . (exists('g:org_selector_ctermbg') ? g:org_selector_ctermbg : 'gray') + let guibg = 'guibg=' . (exists('g:org_selector_guibg') ? g:org_selector_guibg : '#333333') + if hlstring =~ 'ctermbg' + let hlstring = substitute(hlstring,'ctermbg=\S+',ctermbg,'') + else + let hlstring = hlstring . ' ' . ctermbg + endif + if hlstring =~ 'guibg' + let hlstring = substitute(hlstring,'guibg=\S+',guibg,'') + else + let hlstring = hlstring . ' ' . guibg + endif + exec 'hi! Org_Chosen_Agenda_Heading' . i . ' ' . hlstring + endfor + exec 'hi! Org_Chosen_Agenda_Heading ' . guibg . ' ' . ctermbg +endfunction +autocmd ColorScheme * :silent! call OrgSetColors() +call OrgSetColors() + +function! s:OrgPromoteSubheads() + let line = s:OrgGetHead() + let star_count = 1 + len(matchstr(getline(line('.')),'^\*\+')) + let start_line = line + 1 + let end_line = s:OrgSubtreeLastLine() + let subheads = [] + execute start_line . ',' . end_line . 'g/^\*\{' . star_count . '} /call add(subheads,line("."))' + for i in sort(subheads,'ReverseSort') + exec i + call OrgMoveLevel(i,'left') + endfor + execute line + echo "Subheads promoted." +endfunction +"Section for refile and archive funcs +function! OrgRefileDashboard() + echohl MoreMsg + echo " ================================" + echo " Persisted point is: " . (!exists('persistent_refile_point') ? 'None' : join(s:persistent_refile_point,'/')) + echo " Last point used: " . (!exists('s:last_refile_point') ? 'None' : join(s:last_refile_point,'/')) + echo " ================================" + echo " Press key for a refile command:" + echo " --------------------------------" + echo " r / l / p refile subtree to new point/last point/persisted point" + echo " j / z / t jump to new point/last point/persistent point" + echo " s set persistent refile point " + echo " a archive to _archive file" + echo " v jump to _archive file" + echo "" + echohl Question + let key = nr2char(getchar()) + redraw + if key ==? 'r' + call s:OrgRefile(line('.')) + elseif key ==? 'l' + call s:OrgRefileToLastPoint(line('.')) + elseif key ==? 'p' + call s:OrgRefileToPermPoint(line('.')) + elseif key ==? 'j' + call s:OrgJumpToRefilePoint() + elseif key ==? 'z' + call s:OrgJumpToLastRefilePoint() + elseif key ==? 't' + call s:OrgJumpToRefilePointPersistent() + elseif key ==? 's' + call s:OrgSetRefilePoint() + elseif key ==? 'v' + call org#LocateFile(expand('%:p') . '_archive') + elseif key ==? 'a' + if confirm('Confirm that you want to archive subtree(s)',"&Yes\n&Cancel") + call s:DoRefile(['_archive'],[line('.')]) + endif + else + echo "No refile option selected." + endif + echohl None +endfunction +function! s:OrgGatherDashboard() + echohl MoreMsg + echo " ================================" + echo " Press key for a mark/gather/sort command:" + echo " --------------------------------" + echo " toggle mark on/off for current heading" + echo " d delete all marks" + echo " h gather marked headings to current heading" + echo " s sort subheads of current heading" + echo "" + echohl Question + let key = nr2char(getchar()) + redraw + if key ==? ' ' + call s:ToggleHeadingMark(line('.')) + elseif key ==? 'd' + call s:DeleteHeadingMarks() + elseif key ==? 'h' + call s:GatherMarks() + elseif key ==? 's' + call s:OrgSortSubheads() + else + echo "No gather/mark option selected." + endif + echohl None +endfunction + +let g:org_heading_temp=['','','','','','','',''] +function! s:OutlineHeads() + let level = s:Ind(line('.')) + let g:org_heading_temp[level-1] = matchstr(getline(line('.')),'^\*\+ \zs.*') + " put level 1 head in result + let result = expand("%:t") . g:org_heading_temp[0] + " now add full tree to level of current heading + for item in g:org_heading_temp[1: level-1] + let result .= '/' . item + endfor + return result +endfunction +function! s:GetMyItems(arghead) + " assemble and return list of subheads of argument file/heading + let arghead = a:arghead + let result = [] + if a:arghead[-1:] == '*' + let arghead = arghead[:-2] + endif + let ilist = split(arghead,'/') + call org#SaveLocation() + if expand("%:t") != ilist[0] + "call org#LocateFile( '~\Desktop\org_files\' . ilist[0] ) + call org#LocateFile( fnamemodify(s:refile_file,":p:h:") . '/' . ilist[0] ) + if &ft != 'org' + set ft=org + endif + endif + if a:arghead[-1:] == '*' + let tolevel = 3 + else + let tolevel = len(ilist) + endif + exec 'g/^\*\{1,' . tolevel . '} /call add(result, s:OutlineHeads())' + call org#RestoreLocation() + return result +endfunction +function! OrgFileList(arghead,sd,gf) + let arghead = substitute(a:arghead,'\~','\\\~','g') + let s:myheads = ['[current file]'] + copy(g:agenda_files) + let matches = filter( copy( s:myheads ),'v:val =~ arghead') + redraw! + return join( matches, "\n" ) +endfunction + +function! OrgHeadingList(arghead,sd,gf) + let arghead = a:arghead + let s:myheads = s:GetMyItems(arghead) + let matches = filter( copy( s:myheads ),'v:val =~ a:arghead') + redraw! + return join( matches, "\n" ) +endfunction + +function! s:GetTarget() + let orig_wildmode = &wildmode + set wildmode=list:full + try + " need to modify getcmdline to strip back on bs + cmap egetcmdline()[-1:] == '/' ? matchstr(getcmdline()[:-2], '.*\ze/.*' ) . '/' : matchstr(getcmdline(), '.*\ze/.*') . '/' + while 1 + let s:refile_file = '' + "let s:refile_file = input("Target file: ","[current file]",'custom,s:FileList') + let file_default = (bufname('%')==#'__Agenda__') ? g:agenda_files[0] : "" + "[current file]" + let s:refile_file = input("Target file: ",file_default,'custom,OrgFileList') + if s:refile_file ==# '[current file]' + let s:refile_file = expand("%") + elseif index(g:agenda_files,s:refile_file) == -1 + break + endif + let heading = input('Outline heading: ', fnamemodify(s:refile_file,':t:') . "\t",'custom,OrgHeadingList') + let head = matchstr(heading,'.\{-}/\zs.*') + if head ==# '' + continue + else + return [ s:refile_file, head] + endif + endwhile + finally + let &wildmode = orig_wildmode + cunmap + endtry +endfunction +function! s:OrgJumpToRefilePointPersistent() + if exists('s:persistent_refile_point') && (len(s:persistent_refile_point)==2) + call s:OrgGotoHeading( s:persistent_refile_point[0], s:persistent_refile_point[1] ) + normal zv + else + echo 'No persistent refile point assigned.' + endif +endfunction +function! s:OrgJumpToLastRefilePoint() + if exists('s:last_refile_point') && (len(s:last_refile_point)==2) + let p = s:last_refile_point + call s:OrgGotoHeading( p[0], p[1]) + normal zv + else + echo 'No last refile point yet.' + endif +endfunction +function! s:OrgJumpToRefilePoint() + let my_refile_point = s:GetTarget() + if len(my_refile_point)==2 + call s:OrgGotoHeading( my_refile_point[0], my_refile_point[1] ) + normal zv + else + echo "Jump aborted." + endif +endfunction +function! s:OrgSetRefilePoint() + let s:persistent_refile_point = s:GetTarget() +endfunction +function! OrgSetArchivePoint() + let s:archive_refile_point = s:GetTarget() +endfunction + +function! OrgRefileToArchive(headline) + if exists('s:archive_refile_point') && (s:archive_refile_point[1] !=# '') + silent call s:DoRefile( s:archive_refile_point, [a:headline] ) + redraw! + let p = s:archive_refile_point + echo "Tree(s) refiled to: " . p[0] . '/' . p[1] + else + echo 'Refile aborted, archive point not assigned.' + endif +endfunction +function! s:OrgRefileToPermPoint(headline) + if exists('s:persistent_refile_point') && (s:persistent_refile_point[1] !=# '') + silent call s:DoRefile( s:persistent_refile_point, [a:headline] ) + redraw! + echo "Tree(s) refiled to: \n" . s:persistent_refile_point[0] . '/' . s:persistent_refile_point[1] + else + echo 'Refile aborted, persistent point not defined.' + endif +endfunction +function! s:OrgRefileToLastPoint(headline) + if exists('s:last_refile_point') && (s:last_refile_point[1] !=# '') + silent call s:DoRefile( s:last_refile_point, [a:headline] ) + redraw! + echo "Tree(s) refiled to: " . s:last_refile_point[0] . '/' . s:last_refile_point[1] + else + echo 'Refile aborted, no last point yet.' + endif +endfunction +function! s:OrgSortSubheads() + let start = line('.') + if getline(start) !~ b:v.headMatch + echo "You must be on a heading to sort subheads." + return + endif + + " FIRST DELETE ALL SIGNS + sign unplace * + let b:v.heading_marks_dict = {} + let end = s:OrgSubtreeLastLine() + execute start . ',' . end . 'g/^\*\{' . s:Ind(line('.')) . '} /call s:PlaceSignsForSort(line("."))' + exec start + call s:GatherMarks('forward') + +endfunction +function! s:PlaceSignsForSort(line) + exec 'sign place ' . a:line . " line=" . a:line . " name=marked buffer=".bufnr("%") +endfunction +command! -buffer OrgGatherMarks :call GatherMarks() +command! -buffer OrgGatherAgendaMarks :call GatherMarks('agenda') +function! s:GatherMarks(...) + if getline(line('.')) !~ b:v.headMatch + echo "You must be on a heading to gather." + return + endif + let targ_list = [expand('%:p'), getline(line('.'))] + if (a:0 == 1) && (a:1 ==# 'agenda') + call org#LocateFile('__Agenda__') + endif + if org#redir('sign place') =~ 'name=marked' + if (a:0 == 1) && (a:1 !=# 'agenda') + silent call s:DoRefile( targ_list, [line('.')], a:1 ) + else + silent call s:DoRefile( targ_list, [line('.')]) + endif + call s:OrgGotoHeading(targ_list[0], targ_list[1]) + call OrgShowSubs(s:Ind(line('.')), 0) + redraw! + echo "Gathered marked headings to subheads of current heading." + else + echo 'No headings marked, nothing gathered.' + endif +endfunction +function! s:OrgRefile(headline) + let targ_list = s:GetTarget() + if targ_list[1] !=# '' + silent call s:DoRefile( targ_list, [a:headline] ) + redraw! + echo "Tree(s) refiled to: " . targ_list[0] . '/' . targ_list[1] + else + echo 'Refile aborted.' + endif +endfunction +func! GetMarks() + echo b:v.heading_marks +endfunction +function! s:ChangeLevel( text_lines, change_val ) + let mylines = split( a:text_lines, "\n") + let change_val = a:change_val + let i = 0 + while i < len(mylines) + if mylines[i][0] == '*' + if change_val > 0 + let mylines[i] = repeat('*',change_val) . mylines[i] + else + let abs_change = -(change_val) + let mylines[i] = mylines[i][ abs_change :] + endif + endif + let i += 1 + endwhile + return mylines +endfunction +function! s:DoRefile(targ_list,heading_list,...) + + if a:0 == 1 + let sort_type = a:1 + endif + let targ_list = a:targ_list + let heading_list = a:heading_list + let file_lines_dict = {} + let first_lines = {} + let held_lines = {} + call org#SaveLocation() + + + if bufname('%') == '__Agenda__' + if len(b:v.heading_marks_dict) >= 1 + let heading_list = keys(b:v.heading_marks_dict) + endif + " go through and assemble dict of files and lists of lines for each + for item in heading_list + exec item + let file = s:filedict[str2nr(matchstr(getline(line('.')), '^\d\d\d'))] + let lineno = str2nr(matchstr(getline(line('.')),'^\d\d\d\zs\d*')) + let buffer_lineno = s:ActualBufferLine(lineno,bufnr(file)) + + if type(get(file_lines_dict,file)) == 0 + " add first line item + let file_lines_dict[file] = [buffer_lineno] + else + " add subsequent lines + call add(file_lines_dict[file], buffer_lineno) + endif + endfor + else + let file_lines_dict = s:AssembleFileHeadingsDict() + if empty(file_lines_dict) + let file_lines_dict = { expand('%:p'):heading_list} + endif + endif + + " now that we have dict of file(s) and linelists in file_lines_dict + " we can go through and refile/archive + let archiving = (targ_list[0] == '_archive') + if archiving + call s:ArchiveSubtrees(targ_list, file_lines_dict) + else + for afile in keys(file_lines_dict) + call org#LocateFile(afile) + " need to get heads and avoid duplicates in case we're in date agenda view + let linelist = file_lines_dict[afile] + call map( linelist, 's:OrgGetHead_l(v:val)') + let linelist = s:UniqueList(linelist) + " now linelist has list of heading line numbers, go through + for aline in sort(linelist,'ReverseSort') + call org#LocateFile(afile) + exec aline + let refile_stars = s:Ind(aline) - 1 + " delete subhead, but first guarantee it's not in a fold + normal! zv + + let aline_text = getline(aline) + silent execute aline . ',' . s:OrgSubtreeLastLine_l(aline) . 'delete x' + + " now go to refile point and put back in + call s:OrgGotoHeading(targ_list[0],targ_list[1]) + let target_stars = s:Ind(line('.')) " don't subtract 1 b/c refile will be subhead + if refile_stars != target_stars + let x = s:ChangeLevel( @x, target_stars - refile_stars ) + else + let x = split( @x, "\n") + endif + + let line_buf = string(aline) . bufname('%') + if g:org_sort_with_todo_words + let first_lines[aline_text . bufname('%')] = line_buf + else + let first_lines[matchstr(aline_text,b:v.todoMatch . '\{0,1}\s\{0,1}\zs.*') . bufname('%')] = line_buf + endif + let held_lines[line_buf] = x + "let held_lines[x[0]] = x + echo "Refiled " . x[0] . ' to: ' . join(targ_list,'/') + endfor " for lines in this file + "now go back and clear out its heading marks + call org#LocateFile(afile) + let b:v.heading_marks_dict = {} + endfor " for files in file_lines_dict + + " now put all the lines in . . . + " lines below were when each subtree was appended individually + " that's not case anymore, may need to rework and associate + " them with append of 'held_lines' to get ordering option. . . + for heading_line in (exists('sort_type') ? sort(keys(first_lines)) : keys(first_lines)) + "for heading_line in keys(held_lines) + call s:OrgGotoHeading(targ_list[0],targ_list[1]) + if g:org_reverse_note_order + let insert_line = s:OrgNextHead() - 1 + if insert_line == -1 + let insert_line = line('$') + endif + exec insert_line + else + exec s:OrgSubtreeLastLine() + endif + silent call append(line('.') , held_lines[first_lines[heading_line]]) + endfor + endif + if !archiving + let s:last_refile_point = targ_list + endif + + call org#RestoreLocation() + if bufname('%') == '__Agenda__' + if !empty(b:v.heading_marks_dict) + "need reverse list of str2nr(keys) + for line in sort(map(keys(b:v.heading_marks_dict), 'str2nr(v:val)'),'s:ReverseSort') + exec line . 'delete' + endfor + else "just delete this line + delete + endif + endif + call s:DeleteHeadingMarks() + +endfunction +function! s:AssembleFileHeadingsDict() + call org#SaveLocation() + let file_lines_dict = {} + let signlist = split(org#redir('sign place'),"\n") + for line in signlist + let ftest = matchstr(line, '^Signs for \zs.*\ze:$') + if (ftest ># '') "&& (getbufvar(ftest,'&filetype') == 'org') + let file = ftest + continue + endif + let markmatch = matchlist(line,'\s*line=\(\d\+\).*name=\(.*$\)') + if !empty(markmatch) && (markmatch[2] == 'marked') + if get(file_lines_dict, file, []) == [] + let file_lines_dict[file] = [ str2nr(markmatch[1]) ] + else + call add(file_lines_dict[file] , str2nr(markmatch[1])) + endif + endif + endfor + call org#RestoreLocation() + return file_lines_dict +endfunction +func! s:ReverseSort(i1, i2) + return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? -1 : 1 +endfunc +function! s:ArchiveSubtrees(targ_list, file_lines_dict) + let targ_list = a:targ_list + let file_lines_dict = a:file_lines_dict + let msg = '' + + for afile in keys(file_lines_dict) + call org#LocateFile(afile) + "need this dict for category + call OrgMakeDictInherited() + " need to get heads and avoid duplicates in case we're in date agenda view + let linelist = file_lines_dict[afile] + call map( linelist, 's:OrgGetHead_l(v:val)') + let linelist = s:UniqueList(linelist) + " reverse sort avoids problems with deleting as we go . . . + for aline in sort(linelist,'ReverseSort') + call org#LocateFile(afile) + exec aline + let refile_stars = s:Ind(aline) - 1 + " we will delete subhead, but first guarantee it's not in a fold + normal! zv + + call s:SetProp('ARCHIVE_TIME', strftime('%Y-%m-%d %a %H:%M')) + call s:SetProp('ARCHIVE_FILE', afile) + call s:SetProp('ARCHIVE_OLPATH', matchstr(getline(s:OrgParentHead()),'^\*\+\s\+\zs.*$') ) + call s:SetProp('ARCHIVE_CATEGORY', b:v.org_dict.iprop(aline,'CATEGORY')) + + silent execute aline . ',' . s:OrgSubtreeLastLine_l(aline) . 'delete x' + + call org#LocateFile(afile . '_archive') + if line('$') == 1 + let prefix_lines = [' # -*- mode: org -*-', + \ ' vim:ft=org:','','', + \ 'Archived entries from file ' . afile ] + call setline(1,prefix_lines) + endif + let target_stars = 1 + if refile_stars != target_stars + let x = s:ChangeLevel( @x, target_stars - refile_stars ) + else + let x = split( @x, "\n") + endif + silent call append(line('$') , x) + let msg .= "Archived " . x[0] . " to: " . afile . "_archive\n" + endfor " for lines in this file + " now write changes in this archive file and quit + silent wq + echo msg + echo " Press any key to continue..." + call getchar() + endfor " for files in file list +endfunction +function! s:OrgGotoHeading(target_file, target_head, ...) + call org#LocateFile( a:target_file ) + normal gg + let head_list = split(a:target_head,'/') + let head_list[0] = (head_list[0][0] ==# '*' ? head_list[0] : '\* ' . head_list[0]) + call search( head_list[0], 'c', '') + "call search( '^\* ' . head_list[0], 'c', '') + let heading_line = line('.') + let last_subline = s:OrgSubtreeLastLine_l(line('.')) + let i = 1 + while i < len(head_list) + let stars = repeat('\*', i + 1) + call search( '^' . stars . ' ' . head_list[i], '', last_subline) + let i += 1 + endwhile +endfunction + +function! s:OrgVal(variable_str) + " takes variable as an argument and tests whether it's defined + " if not returns -1, otherwise return variable value + if exists(a:variable_str) + execute 'let val=' . a:variable_str + else + let val = -1 + endif + return val +endfunction + +command! PreLoadTags :silent call GlobalConvertTags() +command! PreWriteTags :silent call GlobalUnconvertTags(changenr()) +command! PostWriteTags :silent call UndoUnconvertTags() +au BufRead *.org :PreLoadTags +au BufWrite *.org :PreWriteTags +au BufWritePost *.org :PostWriteTags + +setlocal fillchars=|, + +"Section Narrow Region +let g:nrrw_rgn_vert=1 +let g:nrrw_custom_options={'wrap':0} +command! -buffer Narrow :call NarrowCodeBlock(line('.')) + +function! NarrowCodeBlock(line) + if exists(":NarrowRegion") == 0 + echo "The Vim plugin NrrwRgn.vim must be installed for" + echo "narrowing to work. You can find a copy at:" + echo 'http://www.vim.org/scripts/script.php?script_id=3075' + return + endif + " function first tests if inside src block, and if so + " narrows the code block. If not, then + " tests for headline and narrows the heading subtree + " save buf vars to put in new org buffer if subtree narrowing + let main_buf_vars = b:v + execute a:line + call search('^#+begin_src','b','') + let start=line('.') + 1 + let language = matchstr(getline(line('.')), '^#+begin_src \zs\S\+') + if language == 'emacs-lisp' + let language = 'lisp' + endif + call search('^#+end_src','','') + let end=line('.') - 1 + + let start_width = winwidth(0) + let &winwidth = winwidth(0) / 3 + if (start <= a:line) && (end >= a:line) + execute start ',' . end . 'call nrrwrgn#NrrwRgn()' + set nomodified + if filereadable($VIMRUNTIME . '/ftplugin/' . language . '.vim') + execute 'set ft=' . language + endif + if filereadable($VIMRUNTIME. '/syntax/' . language . '.vim') + execute 'set syntax=' . language + endif + + let &winwidth=start_width*2/3 + else + let start = s:OrgGetHead_l(a:line) + if start > 0 + let end = s:OrgSubtreeLastLine_l(start) + execute start . ',' . end . 'call nrrwrgn#NrrwRgn()' + " then set ftype in new buffer + set ft=org + set nomodified + let b:v = main_buf_vars + let &winwidth=start_width*2/3 + else + execute a:line + echo "You're not in a source code block or an outline heading." + endif + endif +endfunction +" Org Menu Entries +amenu &Org.&View.Entire\ &Document.To\ Level\ &1,1 :set foldlevel=1 +amenu &Org.&View.Entire\ &Document.To\ Level\ &2,2 :set foldlevel=2 +amenu &Org.&View.Entire\ &Document.To\ Level\ &3,3 :set foldlevel=3 +amenu &Org.&View.Entire\ &Document.To\ Level\ &4,4 :set foldlevel=4 +amenu &Org.&View.Entire\ &Document.To\ Level\ &5,5 :set foldlevel=5 +amenu &Org.&View.Entire\ &Document.To\ Level\ &6,6 :set foldlevel=6 +amenu &Org.&View.Entire\ &Document.To\ Level\ &7,7 :set foldlevel=7 +amenu &Org.&View.Entire\ &Document.To\ Level\ &8,8 :set foldlevel=8 +amenu &Org.&View.Entire\ &Document.To\ Level\ &9,9 :set foldlevel=9 +amenu &Org.&View.Entire\ &Document.Expand\ Level\ &All :set foldlevel=99999 +amenu &Org.&View.&Subtree.To\ Level\ &1,,1 :silent call OrgShowSubs(1,0) +amenu &Org.&View.&Subtree.To\ Level\ &2,,2 :silent call OrgShowSubs(2,0) +amenu &Org.&View.&Subtree.To\ Level\ &3,,3 :silent call OrgShowSubs(3,0) +amenu &Org.&View.&Subtree.To\ Level\ &4,,4 :silent call OrgShowSubs(4,0) +amenu &Org.&View.&Subtree.To\ Level\ &5,,5 :silent call OrgShowSubs(5,0) +amenu &Org.&View.&Subtree.To\ Level\ &6,,6 :silent call OrgShowSubs(6,0) +amenu &Org.&View.&Subtree.To\ Level\ &7,,7 :silent call OrgShowSubs(7,0) +amenu &Org.&View.&Subtree.To\ Level\ &8,,8 :silent call OrgShowSubs(8,0) +amenu &Org.&View.&Subtree.To\ Level\ &9\ \ \ \ \ \ ,,9 :silent call OrgShowSubs(9,0)cr> +amenu &Org.-Sep1- : +amenu &Org.&New\ Heading.New\ Head\ Same\ Level(or\ ) :call OrgNewHead('same') +amenu &Org.&New\ Heading.New\ Subhead :call OrgNewHead('leveldown') +amenu &Org.&New\ Heading.New\ Head\ Parent\ Level :call OrgNewHead('levelup') +amenu &Org.&Navigate\ Headings.&Up\ to\ Parent\ Heading :exec OrgParentHead() +amenu &Org.&Navigate\ Headings.&First\ Child\ Heading :exec OrgFirstChildHead() +amenu &Org.&Navigate\ Headings.&Last\ Child\ Heading :exec OrgLastChildHead() +amenu &Org.&Navigate\ Headings.&Next\ Heading :exec OrgNextHead() +amenu &Org.&Navigate\ Headings.&Previous\ Heading :exec OrgPrevHead() +amenu &Org.&Navigate\ Headings.Next\ &Same\ Level :exec OrgNextHeadSameLevel() +amenu &Org.&Navigate\ Headings.Previous\ Same\ Level :exec OrgPrevHeadSameLevel() +amenu &Org.&Navigate\ Headings.Next\ &Sibling :exec OrgNextSiblingHead() +amenu &Org.&Navigate\ Headings.Previous\ Sibling :exec OrgPrevSiblingHead() +amenu &Org.Edit\ &Structure.Move\ Subtree\ &Up :call OrgMoveLevel(line('.'),'up') +amenu &Org.Edit\ &Structure.Move\ Subtree\ &Down :call OrgMoveLevel(line('.'),'down') +amenu &Org.Edit\ &Structure.&Promote\ Subtree :call OrgMoveLevel(line('.'),'left') +amenu &Org.Edit\ &Structure.&Demote\ Subtree :call OrgMoveLevel(line('.'),'right') +vmenu &Org.&Editing.&Bold\ (*),cb "zdi*z*l +vmenu &Org.&Editing.&Italic\ (/),ci "zdi/z/l +vmenu &Org.&Editing.&Underline\ (_),cu "zdi_z_l +vmenu &Org.&Editing.&Code\ (=),cc "zdi=z=l +amenu &Org.&Editing.-Sep22- : +amenu &Org.&Editing.&Narrow,na :silent call NarrowCodeBlock(line('.')) +"amenu &Org.&Editing.Narrow\ &Codeblock,nc :silent call NarrowCodeBlock(line('.')) +"amenu &Org.&Editing.Narrow\ Outline\ &Subtree,ns :silent call NarrowOutline(line('.')) +amenu &Org.&Refile.&Refile\ to\ Point,rh :call OrgRefile(line('.')) +amenu &Org.&Refile.&Jump\ to\ Point,rj :call OrgJumpToRefilePoint() +amenu &Org.&Refile.&Jump\ to\ Persistent\ Point,rx :call OrgJumpToRefilePointPersistent() +amenu &Org.&Refile.&Jump\ to\ Point,rj :call OrgJumpToRefilePoint() +amenu &Org.&Refile.&Set\ Persistent\ Refile\ Point,rs :call OrgSetRefilePoint() +amenu &Org.&Refile.Refile\ to\ Persistent\ Point,rp :call OrgRefileToPermPoint(line('.')) +amenu &Org.Open\ Capture\ File :call org#OpenCaptureFile() +amenu &Org.&Mark/Gather/Sort.&Mark/Unmark\ Heading, :call ToggleHeadingMark(line('.')) +amenu &Org.&Mark/Gather/Sort.&Unmark\ all, :call DeleteHeadingMarks() +amenu &Org.&Mark/Gather/Sort.&Gather\ to\ current\ heading,gh :call GatherMarks() +amenu &Org.&Mark/Gather/Sort.&Sort\ subheads,gs :call OrgSortSubheads() +amenu &Org.-Sep2- : +amenu &Org.&Columns\ Menu :call OrgColumnsDashboard() +amenu &Org.&Hyperlinks.Add/&edit\ link,le :call EditLink() +amenu &Org.&Hyperlinks.&Follow\ link,lf :call FollowLink(OrgGetLink()) +amenu &Org.&Hyperlinks.&Next\ link,ln :/]] +amenu &Org.&Hyperlinks.&Previous\ link,lp :?]] +amenu &Org.&Hyperlinks.Perma-compre&ss\ links,lc :set conceallevel=3\|set concealcursor=nc +amenu &Org.&Hyperlinks.&Autocompress\ links,la :set conceallevel=3\|set concealcursor=c +amenu &Org.&Hyperlinks.No\ auto&compress\ links,lx :set conceallevel=0 +amenu &Org.&Table.$Table\ Dashboard,b :call OrgTableDashboard() +amenu &Org.&Table.E$valuate\ Table,v :call OrgTableDashboard() +amenu &Org.-Sep3- : +amenu &Org.TODO\ &Dashboard,t :call OrgTodoDashboard() +amenu &Org.TODO\ &Cycle :call ReplaceTodo() +"amenu &Org.TODO\ Cycle\ &Backward :call ReplaceTodo('todo-bkwd') +amenu &Org.Edit\ TA&GS,et :call OrgTagsEdit() +amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Deadline,dd :call OrgDateEdit('DEADLINE') +amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Scheduled,ds :call OrgDateEdit('SCHEDULED') +amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Closed,dc :call OrgDateEdit('CLOSED') +amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Timestamp,dt :call OrgDateEdit('TIMESTAMP') +amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &GenericDate,dg :call OrgDateEdit('ATCURSOR') +amenu &Org.&Logging\ work.Clock\ in,ci :call OrgClockIn(line('.')) +amenu &Org.&Logging\ work.Clock\ out,co :call OrgClockOut() +amenu &Org.-Sep4- : +amenu &Org.Agenda\ command,ag :call OrgAgendaDashboard() +amenu &Org.Special\ &views\ current\ file :call OrgCustomSearchMenu() +amenu &Org.Agenda\ &files,af.&Edit\ Agenda\ Files :EditAgendaFiles +amenu &Org.Agenda\ &files,af.Current\ file\ to\ &top :call {sid}CurrentToAgendaFiles('top') +amenu &Org.Agenda\ &files,af.Current\ file\ to\ &bottom :call {sid}CurrentToAgendaFiles('bottom') +amenu &Org.Agenda\ &files,af.Current\ file\ &remove :call {sid}CurrentRemoveFromAgendaFiles() +amenu &Org.Agenda\ &files,af.Cycle\ to\ &next :call {sid}CycleAgendaFiles('forward') +amenu &Org.Agenda\ &files,af.Cycle\ to\ &previous :call {sid}CycleAgendaFiles('backward') +amenu &Org.Agenda\ &files,af.&Choose\ file\ to\ goto :call {sid}OrgGotoChosenFile() +amenu &Org.-Sep45- : +amenu &Org.&Do\ Emacs\ Eval,v :call OrgEval() +amenu &Org.-Sep5- : +amenu &Org.Narro&w.Outline\ &Subtree,ns :call NarrowCodeBlock(line('.')) +amenu &Org.Narro&w.&Code\ Block,nc :call NarrowCodeBlock(line('.')) +amenu &Org.-Sep6- : +amenu &Org.Open\ Capture\ Buffer :call org#CaptureBuffer() +amenu &Org.-Sep7- : +amenu &Org.Export/Publish\ w/Emacs :call OrgExportDashboard() +amenu &Org.-Sep8- : +amenu &Org.R&e-read\ Config\ Lines :call OrgProcessConfigLines() + +"********************************************************************* +"********************************************************************* +" 'endif' below is special 'endif' closing the 'if !exists(org_loaded) +" line near top of file. Thus the main functions are loaded +" only once for all buffers, with settngs at begin of file +" and mappings below this line executed for each buffer +" having org filetype +"********************************************************************* +"********************************************************************* +endif + +let g:org_loaded=1 +let b:v.org_loaded=1 +"********************************************************************* +"********************************************************************* +"********************************************************************* +"********************************************************************* +" convert to VimOrganizer tag format and add colon (:) before dates +PreLoadTags +" below is default todo setup, anything different can be done +" in vimrc (or in future using a config line in the org file itself) +if !exists('g:in_agenda_search') && ( &foldmethod!= 'expr') && !exists('b:v.bufloaded') + setlocal foldmethod=expr + "setlocal foldexpr=org#fold#level(v:lnum) + set foldlevel=1 + let b:v.bufloaded=1 +else + setlocal foldmethod=manual +endif +"if !exists('b:v.todoitems') +" call OrgTodoSetup('TODO | DONE') +"endif +if !exists('g:org_todo_setup') + let g:org_todo_setup = 'TODO | DONE' +endif +if !exists('g:org_tag_setup') + let g:org_tag_setup = '{home(h) work(w)}' +endif + +call OrgProcessConfigLines() +"syntax match OL1 +^\(*\)\{1}\s.*+ +"syntax match OL2 +^\(*\)\{2}\s.*+ +"syntax match OL3 +^\(*\)\{3}\s.*+ contains=CONTAINED +"exec "syntax match DONETODO '" . b:v.todoDoneMatch . "' containedin=OL1,OL2,OL3,OL4,OL5,OL6" +"exec "syntax match DONETODO '" . b:v.todoDoneMatch . "' containedin=OL1,OL2,OL3,OL4,OL5,OL6" +"exec "syntax match NOTDONETODO '" . b:v.todoNotDoneMatch . "' containedin=OL1,OL2,OL3,OL4,OL5,OL6" +"using matchadd b/c syntax match wouldn't show up as contained in OL group +"with start of '^' + +"Menu stuff +function! MenuCycle() + if foldclosed(line('.')) > -1 + exec foldclosed(line('.')) + else + exec s:OrgGetHead() + endif + call OrgCycle() +endfunction + +nmap t :call OrgTodoDashboard() +nmap :call ReplaceTodo() +nmap :call ReplaceTodo() +nmap :call ToggleHeadingMark(line('.')) +nmap :call DeleteHeadingMarks() +" c-s-cr already taken +nmap :call ReplaceTodo('todo-bkwd') +if !has('gui_running') + nmap nt :call ReplaceTodo() +endif +execute "source " . expand(":p:h") . '/vimorg-main-mappings.vim' +" next line call is to get signs defined +call s:DeleteSigns() +" below is autocmd to change tw for lines that have comments on them +" I think this should go in vimrc so i runs for each buffer load +" :autocmd CursorMoved,CursorMovedI * :if match(getline(line(".")), '^*\*\s') == 0 | :setlocal textwidth=99 | :else | :setlocal textwidth=79 | :endif +set com=sO::\ -,mO::\ \ ,eO:::,::,sO:>\ -,mO:>\ \ ,eO:>>,:> +set fo=qtcwn +let b:v.current_syntax = "org" +setlocal foldtext=OrgFoldText() + +"user can define OrgCustomSettings() in vimrc to change default settings +"in org buffers. If syntax or highlight related, though, should +"make changes in OrgCustomColors() +if exists('*OrgCustomSettings') + call OrgCustomSettings() +endif + + +" vim:set nofoldenable: diff --git a/bundle/org-mode/ftplugin/vimorg-agenda-mappings.vim b/bundle/org-mode/ftplugin/vimorg-agenda-mappings.vim new file mode 100644 index 000000000..1aef3cb53 --- /dev/null +++ b/bundle/org-mode/ftplugin/vimorg-agenda-mappings.vim @@ -0,0 +1,75 @@ +" org.vim - VimOrganizer plugin for Vim +" ------------------------------------------------------------- +" Version: 0.30 +" Maintainer: Herbert Sitz +" Last Change: 2011 Nov 02 +" +" Script: http://www.vim.org/scripts/script.php?script_id=3342 +" Github page: http://github.com/hsitz/VimOrganizer +" Copyright: (c) 2010, 2011 by Herbert Sitz +" The VIM LICENSE applies to all files in the +" VimOrganizer plugin. +" (See the Vim copyright except read "VimOrganizer" +" in places where that copyright refers to "Vim".) +" http://vimdoc.sourceforge.net/htmldoc/uganda.html#license +" No warranty, express or implied. +" *** *** Use At-Your-Own-Risk *** *** + let mysid='' . g:org_sid . '_' + nnoremap ag :call OrgAgendaDashboard() + nnoremap et :call OrgTagsEdit() + nnoremap ci :call OrgClockIn() + nnoremap co :call OrgClockOut() + nnoremap d :call OrgDateDashboard() + nnoremap t :call OrgTodoDashboard() + nnoremap a :call DoRefile(['_archive'],[line('.')]) + "nnoremap :call {mysid}ToFromAgenda() + nnoremap :call {mysid}ToFromAgenda() + "nnoremap q :sign unplace * | quit + nnoremap q :call OrgQuitAgenda() + + nmap :call {mysid}AgendaReplaceTodo() + nmap :MyAgendaToBuf + nmap :AgendaMoveToBuf + nmap ,r :call OrgRunCustom({'redo_num': line('.'), 'type':'tags-todo', 'spec': g:org_search_spec}) + nmap >> :call OrgAgendaDateInc('++1d') + nmap << :call OrgAgendaDateInc('--1d') + nmap t :call OrgTodoDashboard() + nmap :silent call {mysid}AgendaReplaceTodo() + + nmap :silent call {mysid}AgendaReplaceTodo('todo-bkwd') + nmap :call {mysid}ToggleHeadingMark(line('.')) + nmap :call {mysid}DeleteHeadingMarks() + nmap ,R :call OrgRefileDashboard() + nmap :call {mysid}OrgAgendaTab() + + "if a:search_type ==? 'agenda_todo' + " nmap r :call OrgRunSearch(g:org_search_spec,'agenda_todo') + "endif + + " lines below are from date searches + nmap v. :call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': strftime("%Y-%m-%d"), 'agenda_duration':'d', 'spec': g:org_search_spec}) + nmap vd :call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration':'d', 'spec': g:org_search_spec}) + nmap vw :call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration':'w', 'spec': g:org_search_spec}) + nmap vm :call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration':'m', 'spec': g:org_search_spec}) + nmap vy :call OrgRunCustom({'redo_num': line('.'), 'type':'agenda', 'agenda_date': g:agenda_startdate, 'agenda_duration':'y', 'spec': g:org_search_spec}) + nmap f :call OrgAgendaMove('forward',v:count1) + nmap b :call OrgAgendaMove('backward',v:count1) + + nmap :call {mysid}OrgAgendaTab() + "nmap :call OrgAgendaGetText(1) + nmap r :call OrgRefreshCalendarAgenda() + + +function! OrgQuitAgenda() + sign unplace * + bw + call clearmatches() + let b:v.chosen_agenda_heading = 0 + if bufnr('ColHeadBuffer') > -1 + "main window has column headings window that + "is now showing a blank buffer line, push back up . . . + resize 100 + endif + "quit +endfunction + diff --git a/bundle/org-mode/ftplugin/vimorg-main-mappings.vim b/bundle/org-mode/ftplugin/vimorg-main-mappings.vim new file mode 100644 index 000000000..c5315ab90 --- /dev/null +++ b/bundle/org-mode/ftplugin/vimorg-main-mappings.vim @@ -0,0 +1,216 @@ +" org.vim - VimOrganizer plugin for Vim +" ------------------------------------------------------------- +" Version: 0.30 +" Maintainer: Herbert Sitz +" Last Change: 2011 Nov 02 +" +" Script: http://www.vim.org/scripts/script.php?script_id=3342 +" Github page: http://github.com/hsitz/VimOrganizer +" Copyright: (c) 2010, 2011 by Herbert Sitz +" The VIM LICENSE applies to all files in the +" VimOrganizer plugin. +" (See the Vim copyright except read "VimOrganizer" +" in places where that copyright refers to "Vim".) +" http://vimdoc.sourceforge.net/htmldoc/uganda.html#license +" No warranty, express or implied. +" *** *** Use At-Your-Own-Risk *** *** +" +"Section Mappings and Endstuff +" below block of 10 or 15 maps are ones collected +" from body of doc that weren't getting assigned for docs +" oepened after initial org filetype doc +let mysid = '' . g:org_sid . '_' +nnoremap :call OrgCycle() +nnoremap :call OrgGlobalCycle() +nnoremap ci :call OrgClockIn(line(".")) +nnoremap co :call OrgClockOut() +"cnoremap e(OrgDateEdit()) +" dl is for the date on the current line +noremap x :call OrgExportDashboard() +noremap d :call OrgDateDashboard() +noremap b :call OrgTableDashboard() +"for char in split('fnbptd12345','\zs') +" exec 'noremap t' . char . ' :call OrgTodoDashboard("' . char . '")' +"endfor +"for char in split('dsctg','\zs') +" exec 'noremap d' . char . ' :call OrgDateDashboard("' . char . '")' +"endfor +"for char in split('hlt12345','\zs') +" exec 'noremap m' . char . ' :call OrgColumnsDashboard("' . char . '")' +"endfor +"noremap dg :call OrgGenericDateEdit() +"noremap dt :call OrgDateEdit('TIMESTAMP') +"noremap dd :call OrgDateEdit('DEADLINE') +"noremap dc :call OrgDateEdit('CLOSED') +"noremap ds :call OrgDateEdit('SCHEDULED') +noremap a* :call OrgRunAgenda(strftime("%Y-%m-%d"),'w,'') +noremap aa :call OrgRunAgenda(strftime("%Y-%m-%d"),'w,'+ANY_TODO') +noremap at :call OrgRunAgenda(strftime("%Y-%m-%d"),'w,'+UNFINISHED_TODOS') +noremap ad :call OrgRunAgenda(strftime("%Y-%m-%d"),'w,'+FINISHED_TODOS') +noremap ag :call OrgAgendaDashboard() +noremap af :call OrgAgendaFilesDashboard() +noremap ac :call OrgCustomSearchMenu() +"command! -nargs=0 Agenda :call OrgAgendaDashboard() +nnoremap :call OrgDateInc(1) +nnoremap :call OrgDateInc(-1) +nnoremap <2-LeftMouse> :call OrgMouseDate() +nnoremap pl :call s:MyPopup() +"map b :call ShowBottomCal() + +nnoremap et :call OrgTagsEdit() + +" clear search matching +nnoremap cs :let @/='' + +noremap r :call OrgRefileDashboard() +noremap g :call {mysid}OrgGatherDashboard() +"noremap rh :call OrgRefile(line('.')) +"noremap rj :call OrgJumpToRefilePoint() +"noremap rx :call OrgJumpToRefilePointPersistent() +"noremap rs :call OrgSetRefilePoint() +"noremap rp :call OrgRefileToPermPoint(line('.')) +noremap cx :silent call orgcheck#ToggleCheck() +noremap v :silent call OrgEval() + +noremap +noremap +noremap 0 :call OrgExpandWithoutText(99999) +noremap 9 :call OrgExpandWithoutText(9) +noremap 8 :call OrgExpandWithoutText(8) +noremap 7 :call OrgExpandWithoutText(7) +noremap 6 :call OrgExpandWithoutText(6) +noremap 5 :call OrgExpandWithoutText(5) +noremap 4 :call OrgExpandWithoutText(4) +noremap 3 :call OrgExpandWithoutText(3) +noremap 2 :call OrgExpandWithoutText(2) +noremap 1 :call OrgExpandWithoutText(1) +"noremap :call OrgExpandWithoutText(1) +"noremap / :let @/='exec call OrgExpandWithoutText(1) +"noremap / :let @a='/^\*\{1,' . &foldlevel . '\} .*'|call LevSearch() +nnoremap / '/^\*\{1,' . &foldlevel . '\} .*' +nnoremap ? '?^\*\{1,' . &foldlevel . '\} .*' + +" set reasonable max limit of 12 for '0' command below, because it iterates +" each for each level, just assume 12 is max. . . +noremap ,0 :call OrgShowSubs(12,0) +noremap ,9 :call OrgShowSubs(9,0) +noremap ,8 :call OrgShowSubs(8,0) +noremap ,7 :call OrgShowSubs(7,0) +noremap ,6 :call OrgShowSubs(6,0) +noremap ,5 :call OrgShowSubs(5,0) +noremap ,4 :call OrgShowSubs(4,0) +noremap ,3 :call OrgShowSubs(3,0) +noremap ,2 :call OrgShowSubs(2,0) +noremap ,1 :call OrgShowSubs(1,0) +noremap ,; :call OrgShowSubs(1,0) + + +"nnoremap no :call NarrowOutline(line('.')) +"nnoremap ns :call NarrowOutline(line('.')) +"nnoremap nc :call NarrowCodeBlock(line('.')) +nnoremap na :call NarrowCodeBlock(line('.')) +nnoremap m :call OrgColumnsDashboard() +" ---------------------------------------- +" table commands +au InsertEnter *.org :call org#tbl#reset_tw(line(".")) +au InsertLeave *.org :call org#tbl#format(line(".")) +command! -buffer -nargs=* OrgTable call org#tbl#create() +"nnoremap bc :call org#tbl#create() +command! -buffer OrgTableAlignQ call org#tbl#align_or_cmd('gqq') +command! -buffer OrgTableAlignW call org#tbl#align_or_cmd('gww') +command! -buffer OrgTableMoveColumnLeft call org#tbl#move_column_left() +"nnoremap bl :call org#tbl#move_column_left() +command! -buffer OrgTableMoveColumnRight call org#tbl#move_column_right() +"nnoremap br :call org#tbl#move_column_right() + +" table function mappings +inoremap org#tbl#kbd_cr() +inoremap org#tbl#kbd_tab() +inoremap org#tbl#kbd_shift_tab() +nnoremap gqq :OrgTableAlignQ +nnoremap gww :OrgTableAlignW + "nnoremap OrgTableMoveColumnLeft +nnoremap