1" 2" cream-dailyread.vim -- Select a daily reading from master document. 3" 4" Cream -- An easy-to-use configuration of the famous Vim text editor 5" [ http://cream.sourceforge.net ] Copyright (C) 2001-2011 Steve Hall 6" 7" License: 8" This program is free software; you can redistribute it and/or modify 9" it under the terms of the GNU General Public License as published by 10" the Free Software Foundation; either version 3 of the License, or 11" (at your option) any later version. 12" [ http://www.gnu.org/licenses/gpl.html ] 13" 14" This program is distributed in the hope that it will be useful, but 15" WITHOUT ANY WARRANTY; without even the implied warranty of 16" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17" General Public License for more details. 18" 19" You should have received a copy of the GNU General Public License 20" along with this program; if not, write to the Free Software 21" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 22" 02111-1307, USA. 23" 24" Description: 25" * open a given document 26" * chop out the section equivalent to the portion and position for 27" that day of the year plus a day on either side. (Optional, prompt 28" or pass argument for which day's portion to get.) 29" * paste into a temporary document for daily reading 30" * demarcate today's read from context 31 32" register as a Cream add-on 33if exists("$CREAM") 34 call Cream_addon_register( 35 \ "Daily Read", 36 \ "Read a days portion of a document", 37 \ "Choose a document to read in entirety over a year and select and present that day's portion, including a day's context on either side. Great for meditative or religious readings.", 38 \ "Daily Read", 39 \ "call Cream_dailyread()", 40 \ '<Nil>' 41 \ ) 42endif 43 44function! Cream_dailyread(...) 45 46 " determine what we're reading 47 " if unset 48 if !exists("g:CREAM_DAILYREAD") 49 call confirm("Select a file from which to read daily portions...", "&Continue...", 1, "Info") 50 let myreturn = s:Cream_dailyread_setfile() 51 if myreturn != 1 52 call confirm("Valid file not found. Quitting...", "&Ok", 1, "Error") 53 return 54 endif 55 endif 56 " if unreadable 57 if !filereadable(g:CREAM_DAILYREAD) 58 call confirm("Unable to read previously selected daily read document. Select a new file...", "&Continue...", 1, "Info") 59 let myreturn = s:Cream_dailyread_setfile() 60 if myreturn != 1 61 call confirm("Valid file not found. Quitting...", "&Ok", 1, "Error") 62 return 63 endif 64 endif 65 66 " dialog 67 let n = confirm( 68 \ "Select option...\n" . 69 \ "\n", "&Select\ Day\n&Select\ New\ Document\n&Ok\n&Cancel", 3, "Info") 70 let myday = "" 71 while myday == "" 72 if n == 1 73 " get optional day to display 74 " manual call uses argument for day 75 if exists("a:1") 76 let myday = a:1 77 endif 78 " otherwise, prompt for day 79 if myday == "" 80 let myday = inputdialog("Please enter desired day number for reading.\n(Default is today, below.)", strftime("%j")) 81 " if empty, user is trying to quit 82 if myday == "" 83 call confirm( 84 \ "No day entered. Quitting...\n" . 85 \ "\n", "&Ok", 1, "Info") 86 return 87 endif 88 endif 89 elseif n == 2 90 let n = s:Cream_dailyread_setfile() 91 if n != 1 92 " didn't find a valid file 93 return 94 endif 95 elseif n == 3 96 " continue, use current day 97 let myday = strftime("%j") 98 else 99 " abort 100 return 101 endif 102 endwhile 103 104 " remove leading 0s on myday (known strftime() error on Win95) 105 while myday[0] == 0 106 let myday = strpart(myday, 1) 107 endwhile 108 109 " turn off myautoindent 110 let myautoindent = &autoindent 111 set noautoindent 112 113 " escape spaces and backslashes 114 let myfile = escape(g:CREAM_DAILYREAD, ' \') 115 116 " open master 117 execute "silent! view " . myfile 118 119 " calculate how long 1/(days in year) is by bytes (don't use 120 " getfsize()--will cause error with compressed files) 121 let mydoclen = line2byte("$") 122 " number of days in the year 123 let days = Cream_daysinyear() 124 let mydaylen = mydoclen / days 125 " must be at least one 126 if mydaylen < 1 127 let mydaylen = 1 128 endif 129 130 " validate day number (must happen after days calculated) 131 if myday > days || myday < 1 132 call confirm("Invalid day number provided. Defaulting to today...", "&Ok", 1, "Info") 133 unlet myday 134 endif 135 136 " find day of year number (if options above don't already provide) 137 if !exists("myday") 138 " numerical day of the year 139 let myday = strftime("%j") - 1 140 endif 141 " calculate current date's pos in year 142 " position = day count * length/day 143 let mypos = myday * mydaylen - mydaylen - mydaylen 144 if mypos < 0 145 let mypos = 1 146 endif 147 148 " go to byte count equivalent to day's start position 149 silent! execute "normal :goto " . mypos . "\<CR>" 150 if myday != 1 151 " select 3/364th of document down 152 silent! execute "normal v" . (mypos + (mydaylen * 3)) . "go" 153 else 154 " select 2/364th of document down 155 silent! execute "normal v" . (mypos + (mydaylen * 2)) . "go" 156 endif 157 158 " copy (register "x") 159 silent! normal "xy 160 " close master (don't save) 161 silent! bwipeout! 162 " open new document named with today's day number 163 silent! execute "silent! edit! " . myday 164 " paste (register "x") 165 silent! normal "xp 166 167 " mark today from context 168 " quit visual mode 169 if mode() == "v" 170 normal v 171 endif 172 normal i 173 " go to start of read 174 if myday != 1 175 silent! execute "normal :goto " . mydaylen . "\<CR>" 176 else 177 silent! execute "normal :goto " . 1 . "\<CR>" 178 endif 179 " start of line 180 normal g0 181 " insert line 182 silent! execute "silent! normal i\n\n======================================================================\n" 183 silent! execute "silent! normal i\t(Today's read below)\n\n" 184 " go to end of read 185 if myday != 1 186 silent! execute "normal :goto " . ((mydaylen * 2) + 5) . "\<CR>" 187 else 188 silent! execute "normal :goto " . ((mydaylen * 1) + 5) . "\<CR>" 189 endif 190 " start of line 191 normal g0 192 " insert line 193 silent! execute "silent! normal i\n\n\t(Today's read above)\n" 194 silent! execute "silent! normal i======================================================================\n\n" 195 " go back to beginning of today's read 196 if myday != 1 197 silent! execute "normal :goto " . (mydaylen + 4) . "\<CR>" 198 else 199 silent! execute "normal :goto " . ( 1 + 4) . "\<CR>" 200 endif 201 202 " return autoinsert state 203 let &autoindent = myautoindent 204 205 " don't warn the user about unsaved state 206 set nomodified 207 208endfunction 209 210function! s:Cream_dailyread_setfile() 211" file open dialog to select file 212" establish global for daily read file 213" return -1 if file not found or unreadable 214 215 if exists("g:CREAM_DAILYREAD") 216 " default path (current) 217 let tmp1 = fnamemodify(g:CREAM_DAILYREAD, ":p:h") 218 let tmp1 = escape(tmp1, ' ') 219 " default filename (current) 220 let tmp2 = fnamemodify(g:CREAM_DAILYREAD, ":p") 221 let tmp2 = escape(tmp2, ' ') 222 " reverse backslashes 223 if has("win32") 224 let tmp1 = substitute(tmp1, '/', '\\', 'g') 225 let tmp2 = substitute(tmp2, '/', '\\', 'g') 226 endif 227 let myfile = browse('1', 'Select Daily Read file...', tmp1, tmp2) 228 else 229 let myfile = browse("1", "Select Daily Read file...", getcwd(), "") 230 endif 231 232 " at least on unix, requires a full path 233 let myfile = fnamemodify(myfile, ":p") 234 235 " results 236 if filereadable(myfile) != 1 237 return -1 238 else 239 let g:CREAM_DAILYREAD = myfile 240 return 1 241 endif 242 243endfunction 244 245