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: