created 2003 · complexity basic · author Siegfried Bublitz · version 5.7
I prefer all my calendar items to be available in one text file, which is easily handled with Vim. You can map a key to open your calendar file when using Vim.
The function Calendar() below generates the following output (extract):
----- Week 1 ----- Mo 30 Tu 31 ==================== 2003 ======================================== ==================== Q 1 ======================================== -------------------- Jan 2003 ---------------------------------------- We 01 Th 02 Fr 03 Sa 04 Su 05 ----- Week 2 ----- Mo 06 Tu 07
function! Calendar(year, month, day, weekday, week, daycount) " output daycount calendar days starting from given date " into new buffer new set buftype=nofile bufhidden=hide noswapfile let year = a:year let month = a:month let day = a:day let wd = a:weekday let week = a:week let index = 0 let date = '' 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 if (wd == 1) " day name let dn = "Mo" elseif (wd == 2) let dn = "Tu" elseif (wd == 3) let dn = "We" elseif (wd == 4) let dn = "Th" elseif (wd == 5) let dn = "Fr" elseif (wd == 6) let dn = "Sa" elseif (wd == 7) let dn = "Su" else let dn = "** ERROR: Unknown day name ** " endif 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 if (month == 1) let yline = "====================" call append(line("$"), yline . " " . year . " " . yline . yline ) call append(line("$"), yline . " Q 1 " . yline . yline ) let monthn = "Jan" " month name elseif (month == 2) let monthn = "Feb" elseif (month == 3) let monthn = "Mar" elseif (month == 4) let monthn = "Apr" call append(line("$"), yline . " Q 2 " . yline . yline ) elseif (month == 5) let monthn = "May" elseif (month == 6) let monthn = "Jun" elseif (month == 7) let monthn = "Jul" call append(line("$"), yline . " Q 3 " . yline . yline ) elseif (month == 8) let monthn = "Aug" elseif (month == 9) let monthn = "Sep" elseif (month == 10) let monthn = "Oct" call append(line("$"), yline . " Q 4 " . yline . yline ) elseif (month == 11) let monthn = "Nov" elseif (month == 12) let monthn = "Dec" else let monthn = "** ERROR: Unknown month ** " endif let mline = "--------------------" call append(line("$"), mline . " " . monthn . " " . year . " " . mline . mline ) endif if (wd == 1) "call append(line("$"), "----- Week " . week . " (" . diy . "..) -----") call append(line("$"), "----- Week " . week . " -----") endif let date = dn . " " " begin with name of day of week if (month < 10) let date = date . year . '-0' . month else let date = date . year . '-' . month endif " skip month, year let date = dn . " " " not interested in year, month if (day < 10) let date = date . '0' . day else let date = date . day endif " let date = date . " (" . diy . ")" call append(line("$"), date) let index = index + 1 let day = day + 1 let wd = wd + 1 endwhile endfunction
map <S-F7> :call Calendar(2002, 12, 30, 1, 1, 1000)<CR><CR> " Dec 30, 2003 is Monday (day 1 in week), week 1 in 2003
Put the above code in your vimrc and call the function, here it is shown with entries for 1000 days. Of course, if you do not use correct arguments matching an existing day, all output will be mess.
Comments[]
The computation of the leap years is a little careless; the code will regard year 2100 as a leapyear, which it is not.
Maybe it is better to substitute the code part
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))
with this
if ((day > 31) || (day > 30 && \ (month == 4 || month == 6 || month == 9 || month == 11)) \ || (month == 2 && \ (day > 29 || (day > 28 && (year%4 || (!(year%100) && year%400))))))
but you have more than 90 years time to do this.
If you want to go to the current day with one keystroke, you can do the following.
Assuming the calendar is contained in a file pointed to by the global variable cal and the formatting of month and days is as generated, this should work by just pressing Shift-F4:
function! Today() let calfile = g:cal if (bufnr(calfile) > 0) exe ":bu " . bufnr(calfile) else exe "edit " . calfile endif let a = search("- " . strftime("%b %Y") . " -", "w") let a = search("^.. " . strftime("%d"), "w") endfunction map <S-F4> :call Today()<CR>