1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 02:50:03 +08:00
SpaceVim/bundle/org-mode/ftplugin/org.vim
2022-01-15 22:22:23 +08:00

8151 lines
290 KiB
VimL
Vendored
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endfun
let g:org_sid = s:SID()
let sid='<SNR>' . g:org_sid . '_'
function! OrgSID(func)
execute 'call <SNR>'.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("<sfile>: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 = '<SNR>' . 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 '( <enter> to accept, <esc> 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 ==? "\<BS>") && (len(cue)>0)
let cue = cue[:-2]
elseif nchar ==? "\<s-c-up>"
let cue = ((curdif-365>=0) ?'+':'').(curdif-365).'d'
elseif newchar ==? "\<s-cr>"
" add new tag . . . todo . . .
elseif newchar ==? "\<cr>"
break
elseif newchar ==? "\<Esc>"
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 <F5> <C-R>=OrgEffort()<CR>
noremap <F5> A<C-R>=OrgEffort()<CR>
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! <SID>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! <SID>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! <SID>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(<f-args>,v:count1)
nmap <buffer> <localleader>,q :<C-U>call OrgMoveLevel(line('.'),'up',v:count1)<cr>
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\<s-tab>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 <num>r to re-search: "
let numstr= ''
nmap <buffer> r :call OrgRunSearch(g:org_search_spec,'agenda_todo')<cr>
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 <buffer> ".num."r :silent call OrgRunCustom({'redo_num':line('.'), 'type':'tags-todo', 'spec':'". tlist[num] . "'})<CR>"
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(<f-args>)
" 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 <f> or <b> for next or previous period, q to close agenda," ,
\ "<Enter> on a heading to synch main file, <ctl-Enter> to goto line," ,
\ "<tab> to cycle heading text, <shift-Enter> 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(<f-args>)
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 <TAB> 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='<SNR>'.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 ==? "\<BS>") && (len(cue)>0)
let cue = cue[:-2]
elseif nchar ==? "\<s-right>"
let cue = ((curdif+1>=0) ?'+':'').(curdif+1).'d'
elseif nchar ==? "\<s-left>"
let cue = ((curdif-1>=0) ?'+':'').(curdif-1).'d'
elseif nchar ==? "\<s-down>"
let cue = ((curdif+7>=0) ?'+':'').(curdif+7).'d'
elseif nchar ==? "\<s-up>"
let cue = ((curdif-7>=0) ?'+':'').(curdif-7).'d'
elseif nchar ==? "\<c-down>"
let cue = ((curdif+30>=0) ?'+':'').(curdif+30).'d'
elseif nchar ==? "\<c-up>"
let cue = ((curdif-30>=0) ?'+':'').(curdif-30).'d'
elseif nchar ==? "\<s-c-down>"
let cue = ((curdif+365>=0) ?'+':'').(curdif+365).'d'
elseif nchar ==? "\<s-c-up>"
let cue = ((curdif-365>=0) ?'+':'').(curdif-365).'d'
elseif newchar ==? "\<cr>"
break
elseif newchar ==? "\<Esc>"
hi Cursor guibg=gray
if bufwinnr('__Calendar') > 0
bdelete Calendar
endif
redraw
return ''
elseif (nchar ==? "\<LeftMouse>") && (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! \<s-up>"
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)
" <dddd-dd-dd
" 01234567890
" 09876543210
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 < 21
let start = col - i
let end = col - i + 11
silent execute 'let datetest = line[' . start . ':' . end .']'
if datetest =~ '[<[]\d\d\d\d-\d\d-\d\d'
break
endif
let i += 1
endwhile
else
let i = 21
endif
if i == 21
execute "normal! \<s-up>"
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! <SID>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! <SID>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! <SID>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('<SNR>'.s:SID().'_'.a:func)
if a:000 > 0
let myargs = split(a:000,',')
else
let myargs = ''
endif
endfunction
function! s:MyPopup()
call feedkeys("i\<c-x>\<c-u>")
endfunction
let g:calendar_action = '<SNR>' . 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 <SID>OrgShowMatch(0)
command! MySynchCycle call <SID>OrgShowMatch(1)
command! MyAgendaToBuf call <SID>OrgAgendaToBufTest()
command! AgendaMoveToBuf call s:OrgAgendaToBuf()
command! -range CodeEval :call <SID>CodeEval
command! -buffer -nargs=* Agenda :call OrgAgendaCommand(<f-args>)
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#%{<SNR>" . 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 <SID>EditAgendaFiles()
command! OrgCycleAgendaForward :call <SID>CycleAgendaFiles('forward')
command! OrgCycleAgendaBackward :call <SID>CycleAgendaFiles('backward')
command! OrgChooseOrgBuffer :call <SID>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 <buffer> :call <SID>SaveAgendaFiles(0)
autocmd BufWriteCmd <buffer> :call <SID>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 <SID>CurrentToAgendaFiles('top')
elseif key =~? 'b'
call <SID>CurrentToAgendaFiles('bottom')
elseif key =~? 'r'
call <SID>CurrentRemoveFromAgendaFiles()
elseif key =~? 'n\|f'
call <SID>CycleAgendaFiles('forward')
elseif key =~? 'p\|b'
call <SID>CycleAgendaFiles('backward')
elseif key =~? 'c\|g'
call <SID>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 <enter> 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(<f-args>)
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,'<SID>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 " <space> 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 <c-BS> <C-\>egetcmdline()[-1:] == '/' ? matchstr(getcmdline()[:-2], '.*\ze/.*' ) . '/' : matchstr(getcmdline(), '.*\ze/.*') . '/'<CR>
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 <c-BS>
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 <SID>GatherMarks()
command! -buffer OrgGatherAgendaMarks :call <SID>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,'<SID>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,'<SID>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 <SID>GlobalConvertTags()
command! PreWriteTags :silent call <SID>GlobalUnconvertTags(changenr())
command! PostWriteTags :silent call <SID>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<tab>,1 :set foldlevel=1<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &2<tab>,2 :set foldlevel=2<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &3<tab>,3 :set foldlevel=3<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &4<tab>,4 :set foldlevel=4<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &5<tab>,5 :set foldlevel=5<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &6<tab>,6 :set foldlevel=6<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &7<tab>,7 :set foldlevel=7<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &8<tab>,8 :set foldlevel=8<cr>
amenu &Org.&View.Entire\ &Document.To\ Level\ &9<tab>,9 :set foldlevel=9<cr>
amenu &Org.&View.Entire\ &Document.Expand\ Level\ &All :set foldlevel=99999<cr>
amenu &Org.&View.&Subtree.To\ Level\ &1<tab>,,1 :silent call OrgShowSubs(1,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &2<tab>,,2 :silent call OrgShowSubs(2,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &3<tab>,,3 :silent call OrgShowSubs(3,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &4<tab>,,4 :silent call OrgShowSubs(4,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &5<tab>,,5 :silent call OrgShowSubs(5,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &6<tab>,,6 :silent call OrgShowSubs(6,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &7<tab>,,7 :silent call OrgShowSubs(7,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &8<tab>,,8 :silent call OrgShowSubs(8,0)<cr>
amenu &Org.&View.&Subtree.To\ Level\ &9\ \ \ \ \ \ <tab>,,9 :silent call OrgShowSubs(9,0)cr>
amenu &Org.-Sep1- :
amenu &Org.&New\ Heading.New\ Head\ Same\ Level<tab><cr>(or\ <s-cr>) :call OrgNewHead('same')<cr>
amenu &Org.&New\ Heading.New\ Subhead<tab><c-cr> :call OrgNewHead('leveldown')<cr>
amenu &Org.&New\ Heading.New\ Head\ Parent\ Level<tab><s-c-cr> :call OrgNewHead('levelup')<cr>
amenu &Org.&Navigate\ Headings.&Up\ to\ Parent\ Heading<tab><a-left> :exec <SID>OrgParentHead()<cr>
amenu &Org.&Navigate\ Headings.&First\ Child\ Heading<tab><a-right> :exec <SID>OrgFirstChildHead()<cr>
amenu &Org.&Navigate\ Headings.&Last\ Child\ Heading :exec <SID>OrgLastChildHead()<cr>
amenu &Org.&Navigate\ Headings.&Next\ Heading :exec <SID>OrgNextHead()<cr>
amenu &Org.&Navigate\ Headings.&Previous\ Heading :exec <SID>OrgPrevHead()<cr>
amenu &Org.&Navigate\ Headings.Next\ &Same\ Level :exec <SID>OrgNextHeadSameLevel()<cr>
amenu &Org.&Navigate\ Headings.Previous\ Same\ Level :exec <SID>OrgPrevHeadSameLevel()<cr>
amenu &Org.&Navigate\ Headings.Next\ &Sibling<tab><a-down> :exec <SID>OrgNextSiblingHead()<cr>
amenu &Org.&Navigate\ Headings.Previous\ Sibling<tab><a-up> :exec <SID>OrgPrevSiblingHead()<cr>
amenu &Org.Edit\ &Structure.Move\ Subtree\ &Up<tab><c-a-up> :call OrgMoveLevel(line('.'),'up')<cr>
amenu &Org.Edit\ &Structure.Move\ Subtree\ &Down<tab><c-a-down> :call OrgMoveLevel(line('.'),'down')<cr>
amenu &Org.Edit\ &Structure.&Promote\ Subtree<tab><c-a-left> :call OrgMoveLevel(line('.'),'left')<cr>
amenu &Org.Edit\ &Structure.&Demote\ Subtree<tab><c-a-right> :call OrgMoveLevel(line('.'),'right')<cr>
vmenu &Org.&Editing.&Bold\ (*)<tab>,cb "zdi*<C-R>z*<ESC>l
vmenu &Org.&Editing.&Italic\ (/)<tab>,ci "zdi/<C-R>z/<ESC>l
vmenu &Org.&Editing.&Underline\ (_)<tab>,cu "zdi_<C-R>z_<ESC>l
vmenu &Org.&Editing.&Code\ (=)<tab>,cc "zdi=<C-R>z=<ESC>l
amenu &Org.&Editing.-Sep22- :
amenu &Org.&Editing.&Narrow<tab>,na :silent call NarrowCodeBlock(line('.'))<cr>
"amenu &Org.&Editing.Narrow\ &Codeblock<tab>,nc :silent call NarrowCodeBlock(line('.'))<cr>
"amenu &Org.&Editing.Narrow\ Outline\ &Subtree<tab>,ns :silent call NarrowOutline(line('.'))<cr>
amenu &Org.&Refile.&Refile\ to\ Point<tab>,rh :call OrgRefile(line('.'))<cr>
amenu &Org.&Refile.&Jump\ to\ Point<tab>,rj :call OrgJumpToRefilePoint()<cr>
amenu &Org.&Refile.&Jump\ to\ Persistent\ Point<tab>,rx :call OrgJumpToRefilePointPersistent()<cr>
amenu &Org.&Refile.&Jump\ to\ Point<tab>,rj :call OrgJumpToRefilePoint()<cr>
amenu &Org.&Refile.&Set\ Persistent\ Refile\ Point<tab>,rs :call OrgSetRefilePoint()<cr>
amenu &Org.&Refile.Refile\ to\ Persistent\ Point<tab>,rp :call OrgRefileToPermPoint(line('.'))<cr>
amenu &Org.Open\ Capture\ File :call org#OpenCaptureFile()<cr>
amenu &Org.&Mark/Gather/Sort.&Mark/Unmark\ Heading<tab>,<space> :call <SID>ToggleHeadingMark(line('.'))<cr>
amenu &Org.&Mark/Gather/Sort.&Unmark\ all<tab>,<c-space> :call <SID>DeleteHeadingMarks()<cr>
amenu &Org.&Mark/Gather/Sort.&Gather\ to\ current\ heading<tab>,gh :call <SID>GatherMarks()<cr>
amenu &Org.&Mark/Gather/Sort.&Sort\ subheads<tab>,gs :call <SID>OrgSortSubheads()<cr>
amenu &Org.-Sep2- :
amenu &Org.&Columns\ Menu :call OrgColumnsDashboard()<cr>
amenu &Org.&Hyperlinks.Add/&edit\ link<tab>,le :call EditLink()<cr>
amenu &Org.&Hyperlinks.&Follow\ link<tab>,lf :call FollowLink(OrgGetLink())<cr>
amenu &Org.&Hyperlinks.&Next\ link<tab>,ln :/]]<cr>
amenu &Org.&Hyperlinks.&Previous\ link<tab>,lp :?]]<cr>
amenu &Org.&Hyperlinks.Perma-compre&ss\ links<tab>,lc :set conceallevel=3\|set concealcursor=nc<cr>
amenu &Org.&Hyperlinks.&Autocompress\ links<tab>,la :set conceallevel=3\|set concealcursor=c<cr>
amenu &Org.&Hyperlinks.No\ auto&compress\ links<tab>,lx :set conceallevel=0<cr>
amenu &Org.&Table.$Table\ Dashboard<tab>,b :call OrgTableDashboard()<cr>
amenu &Org.&Table.E$valuate\ Table<tab>,v :call OrgTableDashboard()<cr>
amenu &Org.-Sep3- :
amenu <silent> &Org.TODO\ &Dashboard<tab>,t :call OrgTodoDashboard()<CR>
amenu <silent> &Org.TODO\ &Cycle<tab><s-cr> :call <SID>ReplaceTodo()<CR>
"amenu <silent> &Org.TODO\ Cycle\ &Backward<tab><c-s-cr> :call <SID>ReplaceTodo('todo-bkwd')<CR>
amenu &Org.Edit\ TA&GS<tab>,et :call OrgTagsEdit()<cr>
amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Deadline<tab>,dd :call OrgDateEdit('DEADLINE')<cr>
amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Scheduled<tab>,ds :call OrgDateEdit('SCHEDULED')<cr>
amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Closed<tab>,dc :call OrgDateEdit('CLOSED')<cr>
amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &Timestamp<tab>,dt :call OrgDateEdit('TIMESTAMP')<cr>
amenu &Org.&Dates\ and\ Scheduling.Add/Edit\ &GenericDate<tab>,dg :call OrgDateEdit('ATCURSOR')<cr>
amenu &Org.&Logging\ work.Clock\ in<tab>,ci :call OrgClockIn(line('.'))<cr>
amenu &Org.&Logging\ work.Clock\ out<tab>,co :call OrgClockOut()<cr>
amenu &Org.-Sep4- :
amenu &Org.Agenda\ command<tab>,ag :call OrgAgendaDashboard()<cr>
amenu &Org.Special\ &views\ current\ file :call OrgCustomSearchMenu()<cr>
amenu &Org.Agenda\ &files<tab>,af.&Edit\ Agenda\ Files :EditAgendaFiles<cr>
amenu &Org.Agenda\ &files<tab>,af.Current\ file\ to\ &top :call {sid}CurrentToAgendaFiles('top')<cr>
amenu &Org.Agenda\ &files<tab>,af.Current\ file\ to\ &bottom :call {sid}CurrentToAgendaFiles('bottom')<cr>
amenu &Org.Agenda\ &files<tab>,af.Current\ file\ &remove :call {sid}CurrentRemoveFromAgendaFiles()<cr>
amenu &Org.Agenda\ &files<tab>,af.Cycle\ to\ &next :call {sid}CycleAgendaFiles('forward')<cr>
amenu &Org.Agenda\ &files<tab>,af.Cycle\ to\ &previous :call {sid}CycleAgendaFiles('backward')<cr>
amenu &Org.Agenda\ &files<tab>,af.&Choose\ file\ to\ goto :call {sid}OrgGotoChosenFile()<cr>
amenu &Org.-Sep45- :
amenu <silent> &Org.&Do\ Emacs\ Eval<tab>,v :call OrgEval()<cr>
amenu &Org.-Sep5- :
amenu &Org.Narro&w.Outline\ &Subtree<tab>,ns :call NarrowCodeBlock(line('.'))<cr>
amenu &Org.Narro&w.&Code\ Block<tab>,nc :call NarrowCodeBlock(line('.'))<cr>
amenu &Org.-Sep6- :
amenu &Org.Open\ Capture\ Buffer :call org#CaptureBuffer()<cr>
amenu &Org.-Sep7- :
amenu &Org.Export/Publish\ w/Emacs :call OrgExportDashboard()<cr>
amenu &Org.-Sep8- :
amenu <silent> &Org.R&e-read\ Config\ Lines :call OrgProcessConfigLines()<cr>
"*********************************************************************
"*********************************************************************
" '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 <silent> <buffer> <localleader>t :call OrgTodoDashboard()<CR>
nmap <silent> <buffer> <s-CR> :call <SID>ReplaceTodo()<CR>
nmap <silent> <buffer> <s-right> :call <SID>ReplaceTodo()<CR>
nmap <silent> <buffer> <localleader><space> :call <SID>ToggleHeadingMark(line('.'))<CR>
nmap <silent> <buffer> <localleader><c-space> :call <SID>DeleteHeadingMarks()<CR>
" c-s-cr already taken
nmap <silent> <buffer> <s-left> :call <SID>ReplaceTodo('todo-bkwd')<CR>
if !has('gui_running')
nmap <silent> <buffer> <localleader>nt :call <SID>ReplaceTodo()<CR>
endif
execute "source " . expand("<sfile>: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: