mirror of
https://github.com/osyo-manga/vim-brightest.git
synced 2025-11-17 07:53:42 -05:00
Fix vital.
This commit is contained in:
@@ -1,13 +1,29 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_brightest#Vim#Buffer#import() abort
|
||||
return map({'_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_brightest#Vim#Buffer#import() abort', printf("return map({'_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:P = s:V.import('Prelude')
|
||||
let s:G = s:V.import('Vim.Guard')
|
||||
endfunction
|
||||
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude']
|
||||
return ['Prelude', 'Vim.Guard']
|
||||
endfunction
|
||||
|
||||
if exists('*getcmdwintype')
|
||||
@@ -27,7 +43,7 @@ function! s:open(buffer, opener) abort
|
||||
if s:P.is_funcref(a:opener)
|
||||
let loaded = !bufloaded(a:buffer)
|
||||
call a:opener(a:buffer)
|
||||
elseif a:buffer is 0 || a:buffer is ''
|
||||
elseif a:buffer is 0 || a:buffer is# ''
|
||||
let loaded = 1
|
||||
silent execute a:opener
|
||||
enew
|
||||
@@ -85,10 +101,58 @@ function! s:get_last_selected() abort
|
||||
\ + (end[1] - begin[1] <# 2 ? [] : getline(begin[1]+1, end[1]-1))
|
||||
\ + [getline(end[1])[: end[2]-2]]
|
||||
endif
|
||||
return join(lines, "\n") . lastchar . (visualmode() ==# "V" ? "\n" : "")
|
||||
return join(lines, "\n") . lastchar . (visualmode() ==# 'V' ? "\n" : '')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:read_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'tempfile': '',
|
||||
\ 'fileformat': '',
|
||||
\ 'encoding': '',
|
||||
\ 'binary': 0,
|
||||
\ 'nobinary': 0,
|
||||
\ 'bad': '',
|
||||
\ 'edit': 0,
|
||||
\}, get(a:000, 0, {}))
|
||||
let tempfile = empty(options.tempfile) ? tempname() : options.tempfile
|
||||
let optnames = [
|
||||
\ empty(options.fileformat) ? '' : '++ff=' . options.fileformat,
|
||||
\ empty(options.encoding) ? '' : '++enc=' . options.encoding,
|
||||
\ empty(options.binary) ? '' : '++bin',
|
||||
\ empty(options.nobinary) ? '' : '++nobin',
|
||||
\ empty(options.bad) ? '' : '++bad=' . options.bad,
|
||||
\ empty(options.edit) ? '' : '++edit',
|
||||
\]
|
||||
let optname = join(filter(optnames, '!empty(v:val)'))
|
||||
try
|
||||
call writefile(a:content, tempfile)
|
||||
execute printf('keepalt keepjumps read %s%s',
|
||||
\ empty(optname) ? '' : optname . ' ',
|
||||
\ fnameescape(tempfile),
|
||||
\)
|
||||
finally
|
||||
call delete(tempfile)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:edit_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'edit': 1,
|
||||
\}, get(a:000, 0, {}))
|
||||
let guard = s:G.store(['&l:modifiable'])
|
||||
let saved_view = winsaveview()
|
||||
try
|
||||
let &l:modifiable=1
|
||||
silent keepjumps %delete _
|
||||
silent call s:read_content(a:content, options)
|
||||
silent keepjumps 1delete _
|
||||
finally
|
||||
keepjump call winrestview(saved_view)
|
||||
call guard.restore()
|
||||
endtry
|
||||
setlocal nomodified
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
235
autoload/vital/_brightest/Vim/Guard.vim
Normal file
235
autoload/vital/_brightest/Vim/Guard.vim
Normal file
@@ -0,0 +1,235 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_brightest#Vim#Guard#import() abort
|
||||
return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_brightest#Vim#Guard#import() abort', printf("return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Use a Funcref as a special term _UNDEFINED
|
||||
function! s:_undefined() abort
|
||||
return 'undefined'
|
||||
endfunction
|
||||
let s:_UNDEFINED = function('s:_undefined')
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:Prelude = s:V.import('Prelude')
|
||||
let s:List = s:V.import('Data.List')
|
||||
let s:Dict = s:V.import('Data.Dict')
|
||||
endfunction
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude', 'Data.List', 'Data.Dict']
|
||||
endfunction
|
||||
function! s:_vital_created(module) abort
|
||||
" define constant variables
|
||||
if !exists('s:const')
|
||||
let s:const = {}
|
||||
let s:const.is_local_variable_supported =
|
||||
\ v:version > 703 || (v:version == 703 && has('patch560'))
|
||||
" NOTE:
|
||||
" The third argument is available from 7.4.242 but it had bug and that
|
||||
" bug was fixed from 7.4.513
|
||||
let s:const.is_third_argument_of_getreg_supported = has('patch-7.4.513')
|
||||
lockvar s:const
|
||||
endif
|
||||
call extend(a:module, s:const)
|
||||
endfunction
|
||||
function! s:_throw(msg) abort
|
||||
throw printf('vital: Vim.Guard: %s', a:msg)
|
||||
endfunction
|
||||
|
||||
let s:option = {}
|
||||
function! s:_new_option(name) abort
|
||||
if a:name !~# '^&'
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" requires to be started from "&"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" does not exist', a:name
|
||||
\))
|
||||
endif
|
||||
let option = copy(s:option)
|
||||
let option.name = a:name
|
||||
let option.value = eval(a:name)
|
||||
return option
|
||||
endfunction
|
||||
function! s:option.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:register = {}
|
||||
function! s:_new_register(name) abort
|
||||
if len(a:name) != 2
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be "@" + a single character', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be started from "@"', a:name
|
||||
\))
|
||||
elseif a:name =~# '^@[:.%]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" is read only', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@[@0-9a-zA-Z#=*+~_/-]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" does not exist. See ":help let-register"', a:name
|
||||
\))
|
||||
endif
|
||||
let name = a:name ==# '@@' ? '' : a:name[1]
|
||||
let register = copy(s:register)
|
||||
let register.name = name
|
||||
if s:const.is_third_argument_of_getreg_supported
|
||||
let register.value = getreg(name, 1, 1)
|
||||
else
|
||||
let register.value = getreg(name, 1)
|
||||
endif
|
||||
let register.type = getregtype(name)
|
||||
return register
|
||||
endfunction
|
||||
function! s:register.restore() abort
|
||||
call setreg(self.name, self.value, self.type)
|
||||
endfunction
|
||||
|
||||
let s:environment = {}
|
||||
function! s:_new_environment(name) abort
|
||||
if a:name !~# '^\$'
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" requires to be started from "$"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" does not exist. While Vim cannot unlet environment variable, it requires to exist', a:name
|
||||
\))
|
||||
endif
|
||||
let environment = copy(s:environment)
|
||||
let environment.name = a:name
|
||||
let environment.value = eval(a:name)
|
||||
return environment
|
||||
endfunction
|
||||
function! s:environment.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:variable = {}
|
||||
function! s:_new_variable(name, ...) abort
|
||||
if a:0 == 0
|
||||
let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$')
|
||||
if empty(m)
|
||||
call s:_throw(printf(
|
||||
\ join([
|
||||
\ 'An variable name "%s" requires to start from b:, w:, t:, or g:',
|
||||
\ 'while no {namespace} is specified',
|
||||
\ ]),
|
||||
\ a:name,
|
||||
\))
|
||||
endif
|
||||
let [prefix, name] = m[1 : 2]
|
||||
let namespace = eval(prefix)
|
||||
else
|
||||
let name = a:name
|
||||
let namespace = a:1
|
||||
endif
|
||||
let variable = copy(s:variable)
|
||||
let variable.name = name
|
||||
let variable.value = get(namespace, name, s:_UNDEFINED)
|
||||
let variable.value =
|
||||
\ type(variable.value) == type({}) || type(variable.value) == type([])
|
||||
\ ? deepcopy(variable.value)
|
||||
\ : variable.value
|
||||
let variable._namespace = namespace
|
||||
return variable
|
||||
endfunction
|
||||
function! s:variable.restore() abort
|
||||
" unlet the variable to prevent variable type mis-match in case
|
||||
silent! unlet! self._namespace[self.name]
|
||||
if type(self.value) == type(s:_UNDEFINED) && self.value == s:_UNDEFINED
|
||||
" do nothing, leave the variable as undefined
|
||||
else
|
||||
let self._namespace[self.name] = self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:instance = {}
|
||||
function! s:_new_instance(instance, ...) abort
|
||||
let shallow = get(a:000, 0, 0)
|
||||
if !s:Prelude.is_list(a:instance) && !s:Prelude.is_dict(a:instance)
|
||||
call s:_throw(printf(
|
||||
\'An instance "%s" requires to be List or Dictionary', string(a:instance)
|
||||
\))
|
||||
endif
|
||||
let instance = copy(s:instance)
|
||||
let instance.instance = a:instance
|
||||
let instance.values = shallow ? copy(a:instance) : deepcopy(a:instance)
|
||||
return instance
|
||||
endfunction
|
||||
function! s:instance.restore() abort
|
||||
if s:Prelude.is_list(self.instance)
|
||||
call s:List.clear(self.instance)
|
||||
else
|
||||
call s:Dict.clear(self.instance)
|
||||
endif
|
||||
call extend(self.instance, self.values)
|
||||
endfunction
|
||||
|
||||
let s:guard = {}
|
||||
function! s:store(targets) abort
|
||||
let resources = []
|
||||
for meta in a:targets
|
||||
if s:Prelude.is_list(meta)
|
||||
if len(meta) == 1
|
||||
call add(resources, s:_new_instance(meta[0]))
|
||||
elseif len(meta) == 2
|
||||
if s:Prelude.is_string(meta[0])
|
||||
call add(resources, call('s:_new_variable', meta))
|
||||
else
|
||||
call add(resources, call('s:_new_instance', meta))
|
||||
endif
|
||||
else
|
||||
call s:_throw('List assignment requires one or two elements')
|
||||
endif
|
||||
elseif type(meta) == type('')
|
||||
if meta =~# '^[bwtgls]:'
|
||||
" Note:
|
||||
" To improve an error message, handle l:XXX or s:XXX as well
|
||||
call add(resources, s:_new_variable(meta))
|
||||
elseif meta =~# '^&'
|
||||
call add(resources, s:_new_option(meta))
|
||||
elseif meta =~# '^@'
|
||||
call add(resources, s:_new_register(meta))
|
||||
elseif meta =~# '^\$'
|
||||
call add(resources, s:_new_environment(meta))
|
||||
else
|
||||
call s:_throw(printf(
|
||||
\ 'Unknown value "%s" was specified',
|
||||
\ meta
|
||||
\))
|
||||
endif
|
||||
endif
|
||||
unlet meta
|
||||
endfor
|
||||
let guard = copy(s:guard)
|
||||
let guard._resources = resources
|
||||
return guard
|
||||
endfunction
|
||||
function! s:guard.restore() abort
|
||||
for resource in self._resources
|
||||
call resource.restore()
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet! s:save_cpo
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker:
|
||||
Reference in New Issue
Block a user