1" 2" Filename: cream-lib-os.vim 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" GNU General Public License (GPL) {{{1 9" 10" This program is free software; you can redistribute it and/or modify 11" it under the terms of the GNU General Public License as published by 12" the Free Software Foundation; either version 3 of the License, or 13" (at your option) any later version. [ 14" http://www.gnu.org/licenses/gpl.html ] 15" 16" This program is distributed in the hope that it will be useful, but 17" WITHOUT ANY WARRANTY; without even the implied warranty of 18" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19" General Public License for more details. 20" 21" You should have received a copy of the GNU General Public License 22" along with this program; if not, write to the Free Software 23" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 24" 02111-1307, USA. 25" 26" 1}}} 27 28" Local functions {{{1 29 30"function! s:OnMS() 31"" NOTE: This localized function a duplicate of that from genutils.vim. 32"" 33" return has("win32") || has("dos32") || has("win16") || has("dos16") || has("win95") 34"endfunction 35 36 37" Path and filenames {{{1 38 39function! Cream_path_fullsystem(path, ...) 40" Return a completely expanded and valid path for the current system 41" from string {path}. 42" o Path does not have to exist, although generally invalid formats 43" will not usually be properly expanded (e.g., backslash path separators 44" on Unix). 45" o Both files and directories may be processed. (Paths will not be 46" returned with a trailing path separator.) 47" o Preserves Windows UNC server name preceding "\\". 48" o {optional} argument can be used to override system settings: 49" * "win" forces return in Windows format as possible: 50" - No drive letter is added (none can be assumed) 51" * "unix" forces return to Unix format as possible: 52" - Windows drive letter is not removed 53" 54 55 " format type 56 " forced with argument 57 if a:0 == 1 58 if a:1 == "win" 59 let format = "win" 60 elseif a:1 == "unix" 61 let format = "unix" 62 endif 63 endif 64 " detected if not forced 65 if !exists("format") 66 if Cream_has("ms") 67 let format = "win" 68 else 69 let format = "unix" 70 endif 71 endif 72 73 " expand to full path 74 let path = fnamemodify(a:path, ":p") 75 76 " make Windows format (assume is Unix) 77 if format == "win" 78 79 " remove escaping of spaces 80 let path = substitute(path, '\\ ', ' ', "g") 81 82 " convert forward slashes to backslashes 83 let path = substitute(path, '/', '\', "g") 84 85 " make Unix format (assume is Windows) 86 else 87 88 "" strip drive letter 89 "let path = substitute(path, '^\a:', '', '') 90 91 " convert backslashes to forward slashes 92 let path = substitute(path, '\', '/', "g") 93 94 " escape spaces (but not twice) 95 let path = substitute(path, '[/\\]* ', '\\ ', "g") 96 97 endif 98 99 " remove duplicate separators 100 let path = substitute(path, '\\\+', '\', "g") 101 let path = substitute(path, '/\+', '/', "g") 102 103 " remove trailing separators 104 let path = substitute(path, '[/\\]*$', '', "") 105 106 " maintain Windows UNC servername 107 if Cream_path_isunc(a:path) 108 let path = substitute(path, '^\', '\\\\', "") 109 let path = substitute(path, '^/', '\\\\', "") 110 endif 111 112 return path 113 114endfunction 115 116function! Cream_path_isunc(path) 117" Returns 1 if {path} is in Windows UNC format, 0 if not. 118 if match(a:path, '^\\\\') != -1 || match(a:path, '^//') != -1 119 return 1 120 endif 121endfunction 122 123function! Cream_pathexists(path) 124" Returns 1 if {path} is an existing file or directory. (Ignores 125" ability to write or read to it, only if exists.) 126 127 " if both unreadable and not a directory 128 if !filereadable(a:path) && filewritable(a:path) != 2 129 return 0 130 else 131 return 1 132 endif 133 134endfunction 135 136" Open with default app {{{1 137 138function! Cream_file_open_defaultapp(...) 139" Open file {...} with OS default application. If none passed, current 140" file used. 141 142 if a:0 == 0 143 " use current file 144 let file = Cream_path_fullsystem(expand("%")) 145 else 146 let file = a:1 147 endif 148 149 " GNOME2 150 if has("gui_gtk2") 151 let cmd = 'silent! !gnome-open ' . escape(file, ' ') 152 " Windows 153 elseif Cream_has("ms") 154 " 95/98/ME 155 if has("win95") 156 let cmd = 'silent! !command /c start "' . file . '"' 157 " NT/2K/XP 158 else 159 " handle URLs differently (http://www.google.com) 160 if Cream_isURL(file) 161 " use start, don't quote 162 let cmd = 'silent! !cmd /c start ' . file 163 else 164 let cmd = 'silent! !cmd /c "' . file . '"' 165 endif 166 endif 167 else 168 " no command found, exit 169 call confirm( 170 \ "Platform not identified, unable to open file.\n" . 171 \ "\n", "&Ok", 1, "Info") 172 return 173 endif 174 if Cream_has("ms") 175 let myshellslash = &shellslash 176 set noshellslash 177 silent! execute cmd 178 let &shellslash = myshellslash 179 else 180 silent! execute cmd 181 endif 182 return 1 183 184endfunction 185 186" Open file explorer {{{1 187"function! Cream_open_fileexplorer() 188"" open the OS file manager to the current file's directory 189" 190" " parse b:cream_pathfilename (respects links as opposed to 191" " getcwd()) 192" if exists("b:cream_pathfilename") 193" let mypath = fnamemodify(b:cream_pathfilename, ":p:h") 194" else 195" let mypath = getcwd() 196" endif 197" 198" call Cream_file_open_defaultapp(mypath) 199" 200"endfunction 201function! Cream_open_fileexplorer() 202" open the OS file manager to the current file's directory 203 204 " parse b:cream_pathfilename (respects links as opposed to 205 " getcwd()) 206 if exists("b:cream_pathfilename") 207 let mypath = fnamemodify(b:cream_pathfilename, ":p:h") 208 else 209 let mypath = getcwd() 210 endif 211 212 let mypath = Cream_path_fullsystem(mypath) 213 214 " NOTE: On Windows XP (2008-01-07), pointing to a cmd.exe to a 215 " directory fails to open explorer--call explorer specifically 216 " 217 "call Cream_file_open_defaultapp(mypath) 218 " 219 " GNOME2 220 if has("gui_gtk2") 221 let cmd = 'silent! !gnome-open ' . escape(mypath, ' ') 222 " Windows 223 elseif Cream_has("ms") 224 " 95/98/ME 225 if has("win95") 226 let cmd = 'silent! !command /c start "' . mypath . '"' 227 " NT/2K/XP 228 else 229 "let cmd = 'silent! !cmd /c "' . mypath . '"' 230 let cmd = 'silent! !explorer /e,"' . mypath . '"' 231 endif 232 endif 233 234 " no command found, exit 235 if !exists("cmd") 236 call confirm("Platform not identified, unable to open file.\n", "&Ok", 1, "Info") 237 return 238 endif 239 silent! execute cmd 240 return 1 241 242endfunction 243 244" File operations {{{1 245 246"function! Cream_touch(pathfile) 247"" create an empty file {pathfile} 248"" WARNING: Will overwrite an existing file of the same name! 249" 250" " test that head exists 251" if !Cream_pathexists(fnamemodify(a:pathfile, ":p:h")) 252" call confirm( 253" \ "Error: Invalid path passed to Cream_touch()\n" . 254" \ "Touch file not created\n" . 255" \ "\n", "&Ok", 1, "Warning") 256" return -1 257" endif 258" 259" " save position 260" if exists("$CREAM") 261" let mypos = Cream_pos() 262" endif 263" 264" silent! enew 265" silent! execute "saveas! " . a:pathfile 266" " close buffer 267" silent! bwipeout! 268" 269" " restore pos 270" if exists("$CREAM") 271" execute mypos 272" endif 273" 274"endfunction 275 276function! Cream_touch(pathfile) 277" create an empty file {pathfile}, prompting if it exists 278 279 " test that head exists 280 if !Cream_pathexists(fnamemodify(a:pathfile, ":p:h")) 281 call confirm( 282 \ "Error: Invalid path passed to Cream_touch().\n" . 283 \ "File not created.\n" . 284 \ "\n", "&Ok", 1, "Warning") 285 return -1 286 endif 287 288 if Cream_has("ms") 289 let pathfile = fnamemodify(a:pathfile, ":p:8") 290 else 291 let pathfile = fnamemodify(a:pathfile, ":p") 292 endif 293 294 execute "silent! confirm 0write " . pathfile 295 296endfunction 297 298" Windows drive letters {{{1 299function! Cream_windrives() 300" Return string listing existing drive letters on MS Windows. Each is 301" returned followed by a newline. 302 303 if !Cream_has("ms") 304 return "" 305 endif 306 307 let cmd = 'for %A in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %A:\CON echo %A: >nul' 308 309 redir @x 310 silent! echo system(cmd) 311 redir END 312 313 let drives = @x 314 " remove DOS echos 315 let drives = substitute(drives, '\u:[[:print:]]\{-1,}>if exist \u:\\CON echo \u:', '', 'g') 316 " remove extra lines 317 let drives = substitute(drives, '\n\n', '', 'g') 318 " remove leading spaces 319 let drives = substitute(drives, '^[ \r\n]\+', '', 'g') 320 321 return drives 322 323endfunction 324 325" Windows Shortcut {{{1 326function! Cream_make_shortcut(spath, sname, target, key, desc) 327" Make a windows shortcut. 328" 329" Example: 330" call Cream_make_shortcut( . 331" \ "C:\WINDOWS\Desktop", . 332" \ "MyShortcut", . 333" \ "C:\WINDOWS\notepad.exe", . 334" \ "Ctrl+Shift+N", . 335" \ "My Notepad". 336" \ ) 337" 338" Arguments: 339" o {spath} :: Path to shortcut, must exist. 340" o {sname} :: Name of shortcut, extension ".lnk" not required. 341" o {target} :: Target (exe) of shortcut (can be empty ""). 342" o {key} :: Keyboard shortcut, e.g. "Ctrl+Shift+N". 343" o {desc} :: Brief description of shortcut, can be empty. 344 345 " only if on Windows 346 if !Cream_has("ms") 347 call confirm( 348 \ "Only available on Windows systems.\n" . 349 \ "\n", "&Ok", 1, "Info") 350 endif 351 " warn if not 9x/NT/64 352 if has("win95") || has("win16") || has("win32unix") 353 let n = confirm( 354 \ "This has not been tested on this version of Windows, continue?\n" . 355 \ "\n", "&Ok", 1, "Info") 356 if n != 1 357 return 358 endif 359 endif 360 361 " verify a:spath has trailing slash 362 let spath = Cream_path_addtrailingslash(a:spath) 363 364 " reject if a:spath doesn't point to a real directory 365 if filewritable(spath) != 2 366 let n = confirm( 367 \ "Path for shortcut doesn't exist, unable to continue.\n" . 368 \ "\n", "&Ok", 1, "Info") 369 return 370 endif 371 372 " a:sname--add .lnk if doesn't exist 373 let sname = a:sname 374 if strpart(sname, strlen(sname)-4) !=? ".lnk" 375 let sname = sname . ".lnk" 376 endif 377 378 " warn if a:target doesn't point to a real file 379 if filereadable(a:target) != 1 380 if filewritable(a:target) == 2 381 let n = confirm( 382 \ "Ok that target points to a directory?\n" . 383 \ "\n", "&Ok\n&Cancel", 1, "Info") 384 if n != 1 385 return 386 endif 387 else 388 let n = confirm( 389 \ "Target does not exist, create anyway?\n" . 390 \ "\n", "&Ok\n&Cancel", 1, "Info") 391 if n != 1 392 return 393 endif 394 endif 395 endif 396 397 " warn if a:desc is too long 398 if strlen(a:desc) > 200 399 let n = confirm( 400 \ "Description is too long for a tooltip, continue anyway?\n" . 401 \ "\n", "&Ok", 1, "Info") 402 if n != 1 403 return 404 endif 405 endif 406 407 " cat valid VBS statements 408 let @x = '' 409 let @x = @x . 'set WshShell = WScript.CreateObject("WScript.Shell")' . "\n" 410 let @x = @x . 'set oShortCutLink = WshShell.CreateShortcut("' . spath . '" & "' . sname . '")' . "\n" 411 let @x = @x . 'oShortCutLink.TargetPath = "' . a:target . '"' . "\n" 412 let @x = @x . 'oShortCutLink.WindowStyle = 1' . "\n" 413 let @x = @x . 'oShortCutLink.Hotkey = "' . a:key . '"' . "\n" 414 let @x = @x . 'oShortCutLink.Description = "' . a:desc . '"' . "\n" 415 let @x = @x . 'oShortCutLink.Save' . "\n" 416 417 " write as temp VBS file 418 call Cream_file_new() 419 put x 420 let fname = tempname() . ".vbs" 421 execute "saveas " . fname 422 423 " run 424 call Cream_file_open_defaultapp() 425 426 " close it 427 silent bwipeout! 428 429 " delete file 430 call delete(fname) 431 432 " verify .lnk made 433 if !filereadable(spath . sname) 434 call confirm( 435 \ "Error: Shortcut not made.\n" . 436 \ "\n", "&Ok", 1, "Info") 437 endif 438 439endfunction 440 441" 1}}} 442" vim:foldmethod=marker 443