1" Vim script to download a missing spell file
2" Maintainer:	Bram Moolenaar <[email protected]>
3" Last Change:	2007 May 06
4
5if !exists('g:spellfile_URL')
6  let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
7endif
8let s:spellfile_URL = ''    " Start with nothing so that s:donedict is reset.
9
10" This function is used for the spellfile plugin.
11function! spellfile#LoadFile(lang)
12  " If the netrw plugin isn't loaded we silently skip everything.
13  if !exists(":Nread")
14    if &verbose
15      echomsg 'spellfile#LoadFile(): Nread command is not available.'
16    endif
17    return
18  endif
19
20  " If the URL changes we try all files again.
21  if s:spellfile_URL != g:spellfile_URL
22    let s:donedict = {}
23    let s:spellfile_URL = g:spellfile_URL
24  endif
25
26  " I will say this only once!
27  if has_key(s:donedict, a:lang . &enc)
28    if &verbose
29      echomsg 'spellfile#LoadFile(): Tried this language/encoding before.'
30    endif
31    return
32  endif
33  let s:donedict[a:lang . &enc] = 1
34
35  " Find spell directories we can write in.
36  let dirlist = []
37  let dirchoices = '&Cancel'
38  for dir in split(globpath(&rtp, 'spell'), "\n")
39    if filewritable(dir) == 2
40      call add(dirlist, dir)
41      let dirchoices .= "\n&" . len(dirlist)
42    endif
43  endfor
44  if len(dirlist) == 0
45    if &verbose
46      echomsg 'spellfile#LoadFile(): There is no writable spell directory.'
47    endif
48    return
49  endif
50
51  let msg = 'Cannot find spell file for "' . a:lang . '" in ' . &enc
52  let msg .= "\nDo you want me to try downloading it?"
53  if confirm(msg, "&Yes\n&No", 2) == 1
54    let enc = &encoding
55    if enc == 'iso-8859-15'
56      let enc = 'latin1'
57    endif
58    let fname = a:lang . '.' . enc . '.spl'
59
60    " Split the window, read the file into a new buffer.
61    " Remember the buffer number, we check it below.
62    new
63    let newbufnr = winbufnr(0)
64    setlocal bin
65    echo 'Downloading ' . fname . '...'
66    call spellfile#Nread(fname)
67    if getline(2) !~ 'VIMspell'
68      " Didn't work, perhaps there is an ASCII one.
69      " Careful: Nread() may have opened a new window for the error message,
70      " we need to go back to our own buffer and window.
71      if newbufnr != winbufnr(0)
72	let winnr = bufwinnr(newbufnr)
73	if winnr == -1
74	  " Our buffer has vanished!?  Open a new window.
75	  echomsg "download buffer disappeared, opening a new one"
76	  new
77	  setlocal bin
78	else
79	  exe winnr . "wincmd w"
80	endif
81      endif
82      if newbufnr == winbufnr(0)
83	" We are back the old buffer, remove any (half-finished) download.
84        g/^/d
85      else
86	let newbufnr = winbufnr(0)
87      endif
88
89      let fname = a:lang . '.ascii.spl'
90      echo 'Could not find it, trying ' . fname . '...'
91      call spellfile#Nread(fname)
92      if getline(2) !~ 'VIMspell'
93	echo 'Sorry, downloading failed'
94	exe newbufnr . "bwipe!"
95	return
96      endif
97    endif
98
99    " Delete the empty first line and mark the file unmodified.
100    1d
101    set nomod
102
103    let msg = "In which directory do you want to write the file:"
104    for i in range(len(dirlist))
105      let msg .= "\n" . (i + 1) . '. ' . dirlist[i]
106    endfor
107    let dirchoice = confirm(msg, dirchoices) - 2
108    if dirchoice >= 0
109      exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
110
111      " Also download the .sug file, if the user wants to.
112      let msg = "Do you want me to try getting the .sug file?\n"
113      let msg .= "This will improve making suggestions for spelling mistakes,\n"
114      let msg .= "but it uses quite a bit of memory."
115      if confirm(msg, "&No\n&Yes") == 2
116	g/^/d
117	let fname = substitute(fname, '\.spl$', '.sug', '')
118	echo 'Downloading ' . fname . '...'
119	call spellfile#Nread(fname)
120	if getline(2) =~ 'VIMsug'
121	  1d
122	  exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
123	  set nomod
124	else
125	  echo 'Sorry, downloading failed'
126	  " Go back to our own buffer/window, Nread() may have taken us to
127	  " another window.
128	  if newbufnr != winbufnr(0)
129	    let winnr = bufwinnr(newbufnr)
130	    if winnr != -1
131	      exe winnr . "wincmd w"
132	    endif
133	  endif
134	  if newbufnr == winbufnr(0)
135	    set nomod
136	  endif
137	endif
138      endif
139    endif
140
141    " Wipe out the buffer we used.
142    exe newbufnr . "bwipe"
143  endif
144endfunc
145
146" Read "fname" from the server.
147function! spellfile#Nread(fname)
148  if g:spellfile_URL =~ '^ftp://'
149    " for an ftp server use a default login and password to avoid a prompt
150    let machine = substitute(g:spellfile_URL, 'ftp://\([^/]*\).*', '\1', '')
151    let dir = substitute(g:spellfile_URL, 'ftp://[^/]*/\(.*\)', '\1', '')
152    exe 'Nread "' . machine . ' anonymous vim7user ' . dir . '/' . a:fname . '"'
153  else
154    exe 'Nread ' g:spellfile_URL . '/' . a:fname
155  endif
156endfunc
157