Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

rewrite: new format; checkboxes; omni-completion

  • Loading branch information...
commit 5626b61343917902f90ab6018f3465638b701e8b 1 parent 04c9940
Tom Link authored
View
54 README
@@ -1,22 +1,54 @@
*vimform.txt* Simple text-based forms for vim
-This experimental plugin provides simple text-based forms for vim.
-
Example: >
- let form_s = "Form Test~\n".
- \"Field1.1:� � Field1.2:� �\n".
- \"Field2.1:� � Field2.2:� �\n"
-
- let form = vimform#SimpleForm()
- let form.fields = {'Field2.1': 'foo', 'Field2.2': 'bar'}
+ let form = vimform#New()
+ let form.name = "Test Form"
+ let form.fields = [
+ \ ['Name'],
+ \ ['Address', {'join': "\n"}],
+ \ ['Planet', {'value': 'Earth'}],
+ \ ['Phone', {'validate': '%%s =~ ''^[0-9()+-]*$''',
+ \ 'message': 'Must be a phone number'}],
+ \ ['E-Mail', {'validate': '%%s =~ ''^\([a-zA-Z.]\+@[a-zA-Z]\+\.[a-zA-Z.]\+\)\?$''',
+ \ 'message': 'Must be an e-mail'}],
+ \ ['Private', {'value': 0, 'type': 'checkbox'}],
+ \ ['Business', {'value': 1, 'type': 'checkbox'}],
+ \ ]
function! form.Do_Submit() dict "{{{3
- echom "Test: ". self.fields['Field1.1'] ." ". self.fields['Field2.2']
+ echom "Test: ". self.name
+ for [field, value] in items(self.values)
+ echom "Field" field value
+ endfor
endf
- call vimform#WithString(form_s, form)
+ call form.Split()
+
+This will create a form, which looks like this: >
+
+ <<&Submit>> <<&Cancel>>
+ Name:
+ Address:
+ Planet: Earth
+ Phone:
+ E-Mail:
+ Private: [ ]
+ Business: [X]
+
+The following field types are currently supported:
+
+ - text fields
+ - check boxes
+
+Check boxes can be toggled by pressing: <cr>, <space>, of <LeftMouse>.
+
+Use <tab> to change fields.
+
+Press <c-cr> to submit the form. If the cursor, is not over a button,
+the Do_Submit() method will be called.
-Currently only single line text fields are supported.
+Buttons are marked with |mark|s. So you can jump to a button with |`|X,
+where X is the "accelerator" key marked with "&".
-----------------------------------------------------------------------
View
571 autoload/vimform.vim
@@ -3,19 +3,14 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-07-16.
-" @Last Change: 2010-04-08.
-" @Revision: 0.0.277
+" @Last Change: 2010-04-10.
+" @Revision: 0.0.707
"
" TODO: Demo: :s Form
" TODO: Multi-line text fields
-if &cp || exists("loaded_vimform_autoload")
- finish
-endif
-let loaded_vimform_autoload = 1
let s:save_cpo = &cpo
set cpo&vim
-" call tlog#Log('Load: '. expand('<sfile>')) " vimtlib-sfile
augroup Vimform
@@ -23,73 +18,125 @@ augroup Vimform
augroup END
-function! vimform#SimpleForm() "{{{3
- let form = copy(s:prototype)
- let form.simple = 1
- let form.Cancel = 'cancel'
- let form.Submit = 'submit'
- let form.epilogue = ['<<&Cancel>> <<&Submit>>']
+" Retrun the default form template.
+function! vimform#New() "{{{3
+ let form = copy(g:vimform#prototype)
return form
endf
-function! vimform#WithFile(file, ...) "{{{3
- let form = a:0 >= 1 ? a:1 : vimform#SimpleForm()
- let form.lines = readfile(a:file)
- call vimform#Form(form)
+" Return a form template that has no default buttons.
+function! vimform#SimpleForm() "{{{3
+ let form = vimform#New()
+ let form.buttons = []
+ return form
endf
-function! vimform#WithString(string, ...) "{{{3
- let form = a:0 >= 1 ? a:1 : vimform#SimpleForm()
- let form.lines = split(a:string, '\n')
- call vimform#Form(form)
+if !exists('g:vimform#prototype')
+ " The default form tepmlate.
+ " :read: let g:vimform#prototype = {...} "{{{2
+ let g:vimform#prototype = {
+ \ 'name': '__Form__',
+ \ 'indent': 0,
+ \ 'buttons': [
+ \ {'name': 'Submit', 'label': '&Submit'},
+ \ {'name': 'Cancel', 'label': '&Cancel'},
+ \ ],
+ \ 'fields': [],
+ \ '_fields': {},
+ \ }
+endif
+
+
+" :display: #Split(?cmd = "split")
+function! g:vimform#prototype.Split(...) dict "{{{3
+ let cmd = a:0 >= 1 ? a:1 : 'split'
+ exec cmd fnameescape(self.name)
+ let self.bufnr = bufnr('%')
+ let b:vimform = self.Setup()
+ setlocal filetype=vimform
+ call self.SetIndent()
+ call self.Display()
+ autocmd! Vimform * <buffer>
+ autocmd Vimform CursorMoved,CursorMovedI <buffer> call b:vimform.SetModifiable()
+ call self.NextField('w', 1)
endf
-function! vimform#WithArray(lines, ...) "{{{3
- let form = a:0 >= 1 ? a:1 : vimform#SimpleForm()
- let form.lines = a:lines
- call vimform#Form(form)
+function! g:vimform#prototype.Setup() dict "{{{3
+ let self._fields = {}
+ for def in self.fields
+ let name = get(def, 0)
+ if name !~ '^-'
+ let def1 = get(def, 1, {})
+ let self._fields[name] = def1
+ endif
+ endfor
+
+ let self._buttons = {}
+ for button in self.buttons
+ let name = self.GetButtonLabel(button)
+ let self._buttons[name] = button
+ endfor
+
+ return self
endf
-function! vimform#Form(form) "{{{3
- let name = get(a:form, 'name', '__Form__')
- let bufnr = bufnr('')
- exec 'split '. fnameescape(name)
- setlocal buftype=nofile
- setlocal bufhidden=hide
- setlocal noswapfile
+let s:indent_plus = 3
+
+function! g:vimform#prototype.Display() dict "{{{3
setlocal modifiable
- setfiletype vimform
- let b:vimform = copy(s:prototype)
- call extend(b:vimform, a:form)
- let b:vimform.bufnr = bufnr
1,$delete
- let lines = get(b:vimform, 'prologue', []) + b:vimform.lines + get(b:vimform, 'epilogue', [])
- call append(0, lines)
- call s:SetAccellerators()
- $delete
- if has_key(b:vimform, 'fields')
- for [field, value] in items(b:vimform.fields)
- call b:vimform.SetField(field, value)
- endfor
- endif
- exec 'resize '. len(lines)
- if b:vimform.simple
- noremap <buffer> <cr> :call <SID>Submit()<cr>
- inoremap <buffer> <cr> <c-\><c-n>:call <SID>Submit()<cr>
+
+ let formatted_buttons = []
+ for button in self.buttons
+ call add(formatted_buttons, s:FormatButton(self.GetButtonLabel(button)))
+ endfor
+ if !empty(formatted_buttons)
+ call append('$', join(formatted_buttons))
endif
- noremap <buffer> <c-cr> :call <SID>Submit()<cr>
- inoremap <buffer> <c-cr> <c-\><c-n>:call <SID>Submit()<cr>
- noremap <silent> <buffer> <tab> :call <SID>NextField('w', 1)<cr>
- inoremap <silent> <buffer> <tab> <c-\><c-n>:call <SID>NextField('w', 1)<cr>
- noremap <silent> <buffer> <s-tab> hh:call <SID>NextField('bw', 1)<cr>
- inoremap <silent> <buffer> <s-tab> <c-\><c-n>hh:call <SID>NextField('bw', 1)<cr>
+
+ let fmt = ' %'. (self.indent - s:indent_plus) .'s: %s'
+ " TLogVAR fmt
+ for def0 in self.fields
+ let name = get(def0, 0)
+ if name =~ '^-'
+ let text = matchstr(name, '^-\+\s\+\zs.*$')
+ let width = winwidth(0) - &foldcolumn - 4
+ let npre = self.indent - 1
+ let npost = width - npre - len(text)
+ let line = repeat('_', npre) .' '. text .' '. repeat('_', npost)
+ else
+ let def = get(def0, 1, {})
+ let type = get(def, 'type', 'text')
+ if type == 'checkbox'
+ let text = printf('[%s]', get(def, 'value', 0) ? 'X' : ' ')
+ else
+ let text = get(def, 'value', '')
+ endif
+ let line = printf(fmt, name, text)
+ endif
+ call append('$', line)
+ endfor
+
+ 0delete
+ call s:SetAccellerators()
norm! ggzt
- autocmd Vimform CursorMoved,CursorMovedI <buffer> call s:SetModifiable()
- call s:NextField('w', 1)
+endf
+
+
+function! g:vimform#prototype.EnsureBuffer() dict "{{{3
+ if bufnr('%') != self.bufnr
+ " TLogVAR bufnr('%'), self.bufnr
+ throw "Vimform: Wrong buffer"
+ endif
+endf
+
+
+function! s:FormatButton(name) "{{{3
+ return printf('<<%s>>', a:name)
endf
@@ -105,139 +152,361 @@ function! s:SetAccellerators() "{{{3
endf
-function! s:SetModifiable() "{{{3
- let line = getline('.')
- let col = col('.')
- let part = line[0 : col - 1]
- " TLogVAR line, col, part, part =~ ':´\(\\.\|[^´]\)*$'
- if part =~ ':´\(\\.\|[^´]\)\+$'
- setlocal modifiable
- else
- setlocal nomodifiable
- if mode() == 'R'
- call feedkeys("\<c-\>\<c-n>")
- endif
- endif
-endf
-
-
-function! s:Submit() "{{{3
+function! g:vimform#prototype.Submit() dict "{{{3
let m = matchlist(getline('.'), '<<\([^>]\{-}\%'. col('.') .'c[^>]\{-}\)>>')
if empty(m)
- echom 'Vimform: No button under cursor'
+ let name = 'Submit'
else
- let form = b:vimform
let name = substitute(m[1], '&', '', 'g')
let name = substitute(name, '\W', '_', 'g')
+ " TLogVAR name
+ endif
+ call self.CollectFields()
+ if self.Validate()
let cb_name = 'Do_'. name
- if has_key(form, cb_name)
- if name == 'Cancel'
- call form.Do_Cancel()
- elseif name == 'Submit'
- call form.CollectFields()
- call form.Do_Cancel()
- call form.Do_Submit()
- else
- call form.{cb_name}()
+ if name == 'Cancel'
+ call self.Do_Cancel()
+ elseif name == 'Submit'
+ call self.Do_Cancel()
+ call self.Do_Submit()
+ elseif has_key(self, cb_name)
+ call self.{cb_name}()
+ else
+ throw "VimForm: Unknown button: ". name
+ endif
+ endif
+endf
+
+
+function! g:vimform#prototype.Do_Submit() dict "{{{3
+endf
+
+
+function! g:vimform#prototype.Do_Cancel() dict "{{{3
+ wincmd c
+endf
+
+
+function! g:vimform#prototype.Validate() dict "{{{3
+ let invalid_values = filter(copy(self.values), '!self.ValidateField(v:key, v:val)')
+ if !empty(invalid_values)
+ echohl WarningMsg
+ let error_rx = []
+ for [field, value] in items(invalid_values)
+ call add(error_rx, self.GetFieldRx(field))
+ let def = self._fields[field]
+ let msg = 'Invalid value for '. field .': '. string(value)
+ if len(def) > 1 && has_key(def, 'message')
+ let msg .= ': '. def.message
endif
+ echom msg
+ endfor
+ echohl NONE
+ exec '3match Error /'. escape(join(error_rx, '\|'), '/') .'/'
+ call search(error_rx[0], 'ew')
+ call s:Feedkeys('a', 1)
+ return 0
+ else
+ 3match none
+ return 1
+ endif
+endf
+
+
+function! g:vimform#prototype.ValidateField(field, value) dict "{{{3
+ let def = self._fields[a:field]
+ let validate = get(def, 'validate', '')
+ if empty(validate)
+ return 1
+ else
+ return eval(printf(validate, string(a:value)))
+ endif
+endf
+
+
+function! g:vimform#prototype.NextField(flags, feedkeys) dict "{{{3
+ call self.EnsureBuffer()
+ exec 'resize '. line('$')
+ let frx = self.GetFieldsRx()
+ let brx = self.GetButtonsRx()
+ let rx = frx .'\|'. brx
+ let lnum = search(rx, 'e'. a:flags)
+ if getline(lnum) =~ frx
+ let type = self.GetCurrentFieldType()
+ if type == 'checkbox'
+ call s:Feedkeys('ll', 1)
+ else
+ call s:Feedkeys('a', 1)
endif
endif
endf
-function! s:NextField(flags, feedkeys) "{{{3
- if search(':´\(\\.\|[^´]\)\{-}´\|<<.\{-}>>', a:flags)
+function! g:vimform#prototype.GetCurrentFieldName() dict "{{{3
+ let frx = self.GetFieldsRx()
+ let view = winsaveview()
+ try
+ if search(frx, 'bW')
+ return matchstr(getline('.'), self.GetFieldRx('\zs\.\{-}\ze'))
+ endif
+ return ''
+ finally
+ call winrestview(view)
+ endtry
+endf
+
+
+function! g:vimform#prototype.GetCurrentFieldType() dict "{{{3
+ let field = self.GetCurrentFieldName()
+ if empty(field)
+ return ''
+ else
+ let type = get(self._fields[field], 'type', 'text')
+ return type
+ endif
+endf
+
+
+function! s:Feedkeys(keys, level) "{{{3
+ " TLogVAR a:keys
+ let s:vimform_modification = 1
+ setlocal modifiable
+ call feedkeys(a:keys, 'n')
+endf
+
+
+function! g:vimform#prototype.SetModifiable() dict "{{{3
+ if s:vimform_modification == 2
+ let modifiable = 1
+ elseif s:vimform_modification == 1
+ let s:vimform_modification = 0
+ let modifiable = 1
+ else
let line = getline('.')
- if line =~ '\%'. col('.') .'c<<'
- if a:feedkeys
- " TLogDBG "fk: ll"
- call feedkeys('ll')
- else
- " TLogDBG "n: ll"
- norm! ll
- endif
+ if line =~ '^-\+ '
+ let modifiable = 0
else
- if a:feedkeys
- " TLogDBG "fk: llR"
- call feedkeys('llR')
+ let field = self.GetCurrentFieldName()
+ " TLogVAR field
+ if empty(field)
+ let modifiable = 0
else
- " TLogDBG "n: ll"
- norm! ll
+ if col('.') <= self.indent
+ let modifiable = 0
+ else
+ let type = get(self._fields[field], 'type', 'text')
+ if type == 'checkbox'
+ let modifiable = 0
+ " let modifiable = getline('.')[col('.')] == ']'
+ " call feedkeys("\<c-\>\<c-o>", 0)
+ else
+ let modifiable = 1
+ endif
+ endif
endif
endif
- return line('.')
+ endif
+ " TLogVAR modifiable
+ " let &l:modifiable = modifiable
+ if modifiable
+ setlocal modifiable
else
- return 0
+ setlocal nomodifiable
endif
endf
-let s:prototype = {'simple': 0}
+function! g:vimform#prototype.SpecialKey(key) dict "{{{3
+ let view = winsaveview()
+ try
+ let type = self.GetCurrentFieldType()
+ finally
+ call winrestview(view)
+ endtry
+ let key = a:key
+ " TLogVAR type
+ if type == 'checkbox'
+ call s:ToggleCheckbox()
+ elseif !empty(key)
+ call feedkeys(key, 't')
+ endif
+endf
-function! s:prototype.Do_Cancel() dict "{{{3
- wincmd c
+function! s:ToggleCheckbox() "{{{3
+ let line = getline('.')
+ if line =~ '\[ \]$'
+ let value = 'X'
+ else
+ let value = ' '
+ endif
+ " TLogVAR value
+ let s:vimform_modification = 2
+ call b:vimform.SetModifiable()
+ let line = substitute(line, '\[\zs.\ze\]$', value, '')
+ call setline('.', line)
+ let s:vimform_modification = 0
endf
-function! s:prototype.CollectFields() dict "{{{3
- let pos = getpos('.')
- try
- norm! ggzt
- let self.fields = {}
- if mode() != 'n'
- exec "norm! <c-\><c-n>"
- endif
- while s:NextField('W', 0)
- let line = getline('.')
- let name = matchstr(line, '\(^\|[^:]´\|>\)\s*\zs[^´]\{-}\ze:´\%'. col('.') .'c')
- " TLogVAR name
- " TLogDBG line[0 : col('.') - 1]
- if !empty(name)
- let field = self.GetField(name)
- if !empty(field)
- call extend(self.fields, field)
+function! g:vimform#prototype.SetIndent() dict "{{{3
+ let self.indent = max(map(keys(self._fields), 'len(v:val) + s:indent_plus'))
+endf
+
+
+function! g:vimform#prototype.GetButtonLabel(def) dict "{{{3
+ return get(a:def, 'label', a:def.name)
+endf
+
+
+function! g:vimform#prototype.GetButtonsRx() dict "{{{3
+ let button_labels = map(copy(self.buttons), 'self.GetButtonLabel(v:val)')
+ call map(button_labels, 'strpart(v:val, 1)')
+ let rx = '\V<<\.\ze\('. join(button_labels, '\|') .'\)>>'
+ return rx
+endf
+
+
+function! g:vimform#prototype.CollectFields() dict "{{{3
+ let self.values = self.GetAllFields()
+endf
+
+
+function! g:vimform#prototype.GetAllFields() dict "{{{3
+ let dict = {}
+ let names = self.GetOrderedFieldNames()
+ TLogVAR names
+ for name in names
+ let dict[name] = self.GetField(name, names)
+ endfor
+ return dict
+endf
+
+
+function! g:vimform#prototype.GetOrderedFieldNames() dict "{{{3
+ return filter(map(copy(self.fields), 'v:val[0]'), 'v:val !~ ''^-''')
+endf
+
+
+function! g:vimform#prototype.GetField(name, ...) dict "{{{3
+ call self.EnsureBuffer()
+ let names = a:0 >= 1 ? a:1 : self.GetOrderedFieldNames()
+ let index = index(names, a:name)
+ if index == -1
+ echoerr 'VimForm: No field of that name:' a:name
+ else
+ let view = winsaveview()
+ try
+ let crx = self.GetFieldRx(a:name)
+ let start = search(crx, 'w')
+ " TLogVAR a:name, crx, start
+ if start
+ if index < len(names) - 1
+ let nrx = self.GetFieldRx(names[index + 1])
+ let nrx .= '\|\^_\+ \.\{-} _\+\$'
+ let end = search(nrx, 'w') - 1
+ else
+ let end = line('$')
+ endif
+ " TLogVAR end
+ if end
+ let lines = getline(start, end)
+ call map(lines, 'strpart(v:val, self.indent)')
+ " TLogVAR lines
+ let def = self._fields[a:name]
+ let join = get(def, 'join', ' ')
+ let out = []
+ for line in lines
+ if line =~ '\S'
+ if len(out) > 0 && out[-1] != "\n"
+ call add(out, join)
+ endif
+ call add(out, line)
+ elseif len(out) > 0
+ call add(out, "\n")
+ endif
+ endfor
+ " TLogVAR out
+ let value = join(out, '')
+ let type = get(def, 'type', 'text')
+ if type == 'checkbox'
+ let value = value =~ 'X'
+ endif
+ let return = get(def, 'return', {})
+ if !empty(return) && has_key(return, value)
+ return return[value]
+ else
+ return value
+ endif
endif
endif
- endwh
- finally
- call setpos('.', pos)
- endtry
+ echoerr 'VimForm: Field not found: ' a:name
+ finally
+ call winrestview(view)
+ endtry
+ endif
endf
-function! s:prototype.SetField(name, text) dict "{{{3
- let rx = '\V\('. escape(a:name, '\') .'\)\s\*:´\zs\s\*\(\(\\\.\|\[^´]\)\{-}\)\s\*\ze´'
- let lno = search(rx, 'wnc')
- if lno
- let line = getline(lno)
- let mlen = len(matchstr(line, rx))
- let tlen = len(a:text)
- let text = a:text
- if tlen < mlen
- let text .= repeat(' ', mlen - tlen)
- endif
- let line = substitute(line, rx, escape(text, '\~&'), '')
- call setline(lno, line)
+function! g:vimform#prototype.GetFieldRx(name) dict "{{{3
+ return '\V\^ \+'. a:name .': '
+endf
+
+
+function! g:vimform#prototype.GetFieldsRx() dict "{{{3
+ let rxs = map(keys(self._fields), 'escape(v:val, ''\'')')
+ return '\V\^ \+\('. join(rxs, '\|') .'\): '
+endf
+
+
+function! g:vimform#prototype.Indent() dict "{{{3
+ let indent = self.indent
+ let cline = getline(v:lnum)
+ let rx = self.GetFieldsRx()
+ " TLogVAR v:lnum, indent, cline
+ " call tlog#Debug(cline =~# self.GetFieldsRx())
+ if cline =~# self.GetFieldsRx()
+ let indent = 0
endif
+ " TLogVAR indent
+ return indent
endf
-function! s:prototype.GetField(name) dict "{{{3
- let rx = '\V\('. escape(a:name, '\') .'\)\s\*:´\s\*\(\(\\\.\|\[^´]\)\{-}\)\s\*´'
- " TLogVAR rx, a:name
- let lno = search(rx, 'wnc')
- if lno
- let line = getline(lno)
- let m = matchlist(line, rx)
- " TLogVAR line, m
- let rv = m[2]
- let rv = substitute(rv, '\\\zs.', '&', 'g')
- return {m[1]: rv}
+function! vimform#Complete1() "{{{3
+ return pumvisible() ? "\<c-n>" : "\<c-x>\<c-o>"
+endf
+
+
+function! vimform#Complete(findstart, base) "{{{3
+ if exists('b:vimform')
+ if a:findstart
+ let field = b:vimform.GetCurrentFieldName()
+ " TLogVAR a:findstart, a:base, field
+ let def = b:vimform._fields[field]
+ let b:vimform_complete = get(def, 'complete', '')
+ endif
+ if empty(b:vimform_complete)
+ if a:findstart
+ return col('.')
+ else
+ return ''
+ endif
+ else
+ return call(b:vimform_complete, [a:findstart, a:base])
+ endif
endif
- return {}
endf
let &cpo = s:save_cpo
unlet s:save_cpo
+
+finish
+
+0.1
+Initial
+
+0.2
+- Changed syntax & everything
+
View
135 doc/vimform.txt
@@ -1,23 +1,55 @@
*vimform.txt* Simple text-based forms for vim
Author: Tom Link, micathom at gmail com
-This experimental plugin provides simple text-based forms for vim.
-
Example: >
- let form_s = "Form Test~\n".
- \"Field1.1:� � Field1.2:� �\n".
- \"Field2.1:� � Field2.2:� �\n"
-
- let form = vimform#SimpleForm()
- let form.fields = {'Field2.1': 'foo', 'Field2.2': 'bar'}
+ let form = vimform#New()
+ let form.name = "Test Form"
+ let form.fields = [
+ \ ['Name'],
+ \ ['Address', {'join': "\n"}],
+ \ ['Planet', {'value': 'Earth'}],
+ \ ['Phone', {'validate': '%s =~ ''^[0-9()+-]*$''',
+ \ 'message': 'Must be a phone number'}],
+ \ ['E-Mail', {'validate': '%s =~ ''^\([a-zA-Z.]\+@[a-zA-Z]\+\.[a-zA-Z.]\+\)\?$''',
+ \ 'message': 'Must be an e-mail'}],
+ \ ['Private', {'value': 0, 'type': 'checkbox'}],
+ \ ['Business', {'value': 1, 'type': 'checkbox'}],
+ \ ]
function! form.Do_Submit() dict "{{{3
- " TLogVAR self.fields
- echom "Test: ". self.fields['Field1.1'] ." ". self.fields['Field2.2']
+ echom "Test: ". self.name
+ for [field, value] in items(self.values)
+ echom "Field" field value
+ endfor
endf
- call vimform#WithString(form_s, form)
+ call form.Split()
+
+This will create a form, which looks like this: >
+
+ <<&Submit>> <<&Cancel>>
+ Name:
+ Address:
+ Planet: Earth
+ Phone:
+ E-Mail:
+ Private: [ ]
+ Business: [X]
+
+The following field types are currently supported:
+
+ - text fields
+ - check boxes
+
+Check boxes can be toggled by pressing: <cr>, <space>, of <LeftMouse>.
+Use <tab> to change fields.
+
+Press <c-cr> to submit the form. If the cursor, is not over a button,
+the Do_Submit() method will be called.
+
+Buttons are marked with |mark|s. So you can jump to a button with |`|X,
+where X is the "accelerator" key marked with "&".
-----------------------------------------------------------------------
@@ -31,84 +63,39 @@ See :help vimball for details.
This script requires hookcursormoved (vimscript #2037) to be installed.
-Also available via git: http://github.com/tomtom/vimtlib/
+Also available via git: http://github.com/tomtom/vimform_vim/
========================================================================
Contents~
- vimform#SimpleForm ........ |vimform#SimpleForm()|
- vimform#WithFile .......... |vimform#WithFile()|
- vimform#WithString ........ |vimform#WithString()|
- vimform#WithArray ......... |vimform#WithArray()|
- vimform#Form .............. |vimform#Form()|
- <cr> ...................... |<cr>|
- i_<cr> .................... |i_<cr>|
- <c-cr> .................... |<c-cr>|
- i_<c-cr> .................. |i_<c-cr>|
- <tab> ..................... |<tab>|
- i_<tab> ................... |i_<tab>|
- <s-tab> ................... |<s-tab>|
- i_<s-tab> ................. |i_<s-tab>|
- prototype.Do_Cancel
- prototype.CollectFields
- prototype.SetField
- prototype.GetField
+ vimform#New ............ |vimform#New()|
+ vimform#SimpleForm ..... |vimform#SimpleForm()|
+ g:vimform#prototype .... |g:vimform#prototype|
+ vimform#Complete1 ...... |vimform#Complete1()|
+ vimform#Complete ....... |vimform#Complete()|
========================================================================
autoload/vimform.vim~
+ *vimform#New()*
+vimform#New()
+ Retrun the default form template.
+
*vimform#SimpleForm()*
vimform#SimpleForm()
+ Return a form template that has no default buttons.
- *vimform#WithFile()*
-vimform#WithFile(file, ...)
-
- *vimform#WithString()*
-vimform#WithString(string, ...)
-
- *vimform#WithArray()*
-vimform#WithArray(lines, ...)
-
- *vimform#Form()*
-vimform#Form(form)
-
- *<cr>*
-<cr> ... :call <SID>Submit()<cr>
-
- *i_<cr>*
-i_<cr> ... <c-\><c-n>:call <SID>Submit()<cr>
-
- *<c-cr>*
-<c-cr> ... :call <SID>Submit()<cr>
-
- *i_<c-cr>*
-i_<c-cr> ... <c-\><c-n>:call <SID>Submit()<cr>
-
- *<tab>*
-<tab> ... :call <SID>NextField('w', 1)<cr>
-
- *i_<tab>*
-i_<tab> ... <c-\><c-n>:call <SID>NextField('w', 1)<cr>
-
- *<s-tab>*
-<s-tab> ... hh:call <SID>NextField('bw', 1)<cr>
-
- *i_<s-tab>*
-i_<s-tab> ... <c-\><c-n>hh:call <SID>NextField('bw', 1)<cr>
-
-
-prototype.Do_Cancel
-
-
-prototype.CollectFields
-
-
-prototype.SetField
+ *g:vimform#prototype*
+g:vimform#prototype (default: {...})
+ The default form tepmlate.
+ *vimform#Complete1()*
+#Split(?cmd = "split")
-prototype.GetField
+ *vimform#Complete()*
+vimform#Complete(findstart, base)
View
39 ftplugin/vimform.vim
@@ -0,0 +1,39 @@
+" vimform.vim
+" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
+" @Website: http://www.vim.org/account/profile.php?user_id=4037
+" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
+" @Created: 2010-04-09.
+" @Last Change: 2010-04-10.
+" @Revision: 52
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+setlocal buftype=nofile
+setlocal bufhidden=hide
+setlocal noswapfile
+setlocal modifiable
+setlocal omnifunc=vimform#Complete
+
+noremap <buffer> <cr> :call b:vimform.SpecialKey('<lt>cr>')<cr>
+noremap <buffer> <space> :call b:vimform.SpecialKey('<lt>space>')<cr>
+noremap <buffer> <LeftMouse> <LeftMouse>:call b:vimform.SpecialKey('')<cr>
+inoremap <buffer> <LeftMouse> <LeftMouse><c-\><c-n>:call b:vimform.SpecialKey('')<cr>
+
+noremap <buffer> <c-cr> :call b:vimform.Submit()<cr>
+inoremap <buffer> <c-cr> <c-\><c-n>:call b:vimform.Submit()<cr>
+noremap <silent> <buffer> <tab> :call b:vimform.NextField('w', 1)<cr>
+inoremap <silent> <buffer> <tab> <c-\><c-n>:call b:vimform.NextField('w', 1)<cr>
+noremap <silent> <buffer> <s-tab> :call b:vimform.NextField('bw', 1)<cr>
+inoremap <silent> <buffer> <s-tab> <c-\><c-n>:call b:vimform.NextField('bw', 1)<cr>
+
+imap <expr> <buffer> <c-space> vimform#Complete1()
+
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
View
16 indent/vimform.vim
@@ -0,0 +1,16 @@
+" @Author: Tom Link (micathom AT gmail com?subject=[vim])
+" @Website: http://www.vim.org/account/profile.php?user_id=4037
+" @GIT: http://github.com/tomtom/vimform_vim/
+" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
+" @Created: 2010-04-09.
+" @Last Change: 2010-04-09.
+" @Revision: 4
+
+if exists("b:did_indent") || exists("g:vikiNoIndent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=b:vimform.Indent()
+" setlocal indentkeys=!^F,o,O
+
View
6 plugin/vimform.vim
@@ -3,14 +3,14 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-07-16.
-" @Last Change: 2009-02-15.
-" @Revision: 2
+" @Last Change: 2010-04-09.
+" @Revision: 3
" GetLatestVimScripts: 0 0 vimform.vim
if &cp || exists("loaded_vimform")
finish
endif
-let loaded_vimform = 1
+let loaded_vimform = 2
let s:save_cpo = &cpo
set cpo&vim
View
6 syntax/vimform.vim
@@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-07-16.
-" @Last Change: 2009-02-15.
-" @Revision: 0.0.17
+" @Last Change: 2010-04-10.
+" @Revision: 0.0.19
if version < 600
syntax clear
@@ -22,11 +22,13 @@ syn match VimformLabel /[^][:space:]][^]:]\{-}\s*\ze:/ nextgroup=VimformField
syn region VimformField matchgroup=Comment start=/:´/ end=/´/ skip=/\\´/
syn match VimformButton /<<.\{-}>>/
syn match VimformTitle /^.\{-}\~$/
+syn match VimformSeparator /^_\+ .\{-} _\+$/
HiLink VimformLabel Constant
HiLink VimformField Statement
HiLink VimformButton Special
HiLink VimformTitle PreProc
+HiLink VimformSeparator PreProc
delcommand HiLink
View
39 test/address.vim
@@ -0,0 +1,39 @@
+" vimform.vim
+" @Author: Tom Link (micathom AT gmail com?subject=[vim])
+" @Website: http://www.vim.org/account/profile.php?user_id=4037
+" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
+" @Created: 2008-07-16.
+" @Last Change: 2010-04-10.
+" @Revision: 88
+
+
+let form = vimform#New()
+let form.name = "Test Form"
+let form.fields = [
+ \ ['Name'],
+ \ ['Address', {'join': "\n"}],
+ \ ['Planet', {'value': 'Earth', 'complete': 'CompletePlanets'}],
+ \ ['Phone', {'validate': '%s =~ ''^[0-9()+-]*$''', 'message': 'Must be a phone number'}],
+ \ ['E-Mail', {'validate': '%s =~ ''^\([a-zA-Z.]\+@[a-zA-Z]\+\.[a-zA-Z.]\+\)\?$''', 'message': 'Must be an e-mail'}],
+ \ ['Private', {'value': 0, 'type': 'checkbox'}],
+ \ ['Business', {'value': 1, 'type': 'checkbox'}],
+ \ ]
+function! form.Do_Submit() dict "{{{3
+ echom "Test: ". self.name
+ for [field, value] in items(self.values)
+ echom "Field" field value
+ endfor
+endf
+
+let s:planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptun', 'Pluto FTW']
+function! CompletePlanets(findstart, base) "{{{3
+ if a:findstart
+ return match(getline('.'), '\k\{-}\%'. col('.') .'c')
+ else
+ let rx = '\V'. escape(a:base, '\')
+ return filter(copy(s:planets), 'v:val =~ rx')
+ endif
+endf
+
+call form.Split()
+
View
33 test/replace_gui.vim
@@ -0,0 +1,33 @@
+" vimform.vim
+" @Author: Tom Link (micathom AT gmail com?subject=[vim])
+" @Website: http://www.vim.org/account/profile.php?user_id=4037
+" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
+" @Created: 2008-07-16.
+" @Last Change: 2010-04-10.
+" @Revision: 95
+
+
+let replace_form= vimform#SimpleForm()
+let replace_form.name = "Search & Replace"
+let replace_form.fields = [
+ \ ['Search'],
+ \ ['Replace'],
+ \ ['--- Options'],
+ \ ['Replace all', {'value': 1, 'type': 'checkbox', 'return': {'1': 'g', '0': ''}}],
+ \ ['Case-sensitive', {'type': 'checkbox', 'return': {'1': 'I', '0': ''}}],
+ \ ['Confirm', {'value': 1, 'type': 'checkbox', 'return': {'1': 'c', '0': ''}}],
+ \ ['Ignore errors', {'type': 'checkbox', 'return': {'1': 'e', '0': ''}}],
+ \ ]
+function! replace_form.Do_Submit() dict "{{{3
+ let search = self.values['Search']
+ if !empty(search)
+ let flags = map(["Replace all", "Case-sensitive", "Confirm", "Ignore errors"], 'self.values[v:val]')
+ exec printf('%%s/%s/%s/%s',
+ \ escape(search, '/'),
+ \ escape(self.values['Replace'], '/'),
+ \ join(flags, ''))
+ endif
+endf
+
+call replace_form.Split()
+
Please sign in to comment.
Something went wrong with that request. Please try again.