Generate calendar file
Talk0this wiki
Redirected from VimTip560
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
Edit
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>