1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-04-14 15:19:12 +08:00

feat(bundle#dein): update dein.vim

update dein to 9ab8106405
This commit is contained in:
wsdjeg 2022-01-01 22:47:56 +08:00
parent 5d74df0487
commit 7c9058447b
27 changed files with 1890 additions and 885 deletions

12
bundle/dein.vim/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: Shougo # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -1,13 +0,0 @@
dist: xenial
language: python
python:
- 3.7
install:
- eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64"
- make install
script:
- make --keep-going test

View File

@ -4,21 +4,21 @@ export THEMIS_ARGS := -e -s --headless
export THEMIS_HOME := ./vim-themis export THEMIS_HOME := ./vim-themis
install: vim-themis install:
pip install --upgrade -r test/requirements.txt pip install --upgrade -r test/requirements.txt
install-user: vim-themis install-user:
pip install --user --upgrade -r test/requirements.txt pip install --user --upgrade -r test/requirements.txt
lint: lint:
vint --version vint --version
vint autoload vint autoload
test: test: vim-themis
themis --version themis --version
themis test/ themis test/
vim-themis: vim-themis:
git clone https://github.com/thinca/vim-themis vim-themis git clone https://github.com/thinca/vim-themis vim-themis
.PHONY: install lint test .PHONY: install install-user lint test

View File

@ -1,6 +1,6 @@
# dein.vim # dein.vim
[![Join the chat at https://gitter.im/Shougo/dein.vim](https://badges.gitter.im/Shougo/dein.vim.svg)](https://gitter.im/Shougo/dein.vim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/Shougo/dein.vim.svg?branch=master)](https://travis-ci.org/Shougo/dein.vim) [![Join the chat at https://gitter.im/Shougo/dein.vim](https://badges.gitter.im/Shougo/dein.vim.svg)](https://gitter.im/Shougo/dein.vim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Please read [help](doc/dein.txt) for details. Please read [help](doc/dein.txt) for details.
@ -19,11 +19,12 @@ Dein.vim is a dark powered Vim/Neovim plugin manager.
## Requirements ## Requirements
- Vim 8.0 or above or NeoVim. - Vim 8.2 or above or NeoVim(0.5.0+).
- "xcopy" command in $PATH (Windows) - "xcopy" command in $PATH or Python3 interface (Windows)
- "git" command in $PATH (if you want to install github or vim.org plugins) - "git" command in $PATH (if you want to install github or vim.org plugins)
Note: If you use Vim 7.4, please use dein.vim ver.1.5 instead. Note: If you use below Vim 8.2 or neovim 0.5, please use dein.vim ver.2.2
instead.
If you need vim-plug like install UI, you can use dein-ui.vim. If you need vim-plug like install UI, you can use dein-ui.vim.
https://github.com/wsdjeg/dein-ui.vim https://github.com/wsdjeg/dein-ui.vim
@ -59,32 +60,7 @@ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
./installer.ps1 ~/.cache/dein ./installer.ps1 ~/.cache/dein
``` ```
2. Edit your .vimrc like this. 2. Edit your .vimrc like in "Examples" section.
```vim
if &compatible
set nocompatible
endif
" Add the dein installation directory into runtimepath
set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim
if dein#load_state('~/.cache/dein')
call dein#begin('~/.cache/dein')
call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim')
call dein#add('Shougo/deoplete.nvim')
if !has('nvim')
call dein#add('roxma/nvim-yarp')
call dein#add('roxma/vim-hug-neovim-rpc')
endif
call dein#end()
call dein#save_state()
endif
filetype plugin indent on
syntax enable
```
3. Open vim and install dein 3. Open vim and install dein
@ -92,6 +68,44 @@ syntax enable
:call dein#install() :call dein#install()
``` ```
## Examples
```vim
if &compatible
set nocompatible " Be iMproved
endif
" Required:
" Add the dein installation directory into runtimepath
set runtimepath+={path to dein.vim directory}
" Required:
call dein#begin({path to plugin base path directory})
" Let dein manage dein
call dein#add({path to dein.vim directory})
if !has('nvim')
call dein#add('roxma/nvim-yarp')
call dein#add('roxma/vim-hug-neovim-rpc')
endif
" Add or remove your plugins here like this:
"call dein#add('Shougo/neosnippet.vim')
"call dein#add('Shougo/neosnippet-snippets')
" Required:
call dein#end()
" Required:
filetype plugin indent on
syntax enable
" If you want to install not installed plugins on startup.
"if dein#check_install()
" call dein#install()
"endif
```
## Features ## Features

View File

@ -4,104 +4,15 @@
" License: MIT license " License: MIT license
"============================================================================= "=============================================================================
function! dein#_init() abort
let g:dein#name = ''
let g:dein#plugin = {}
let g:dein#_cache_version = 150
let g:dein#_plugins = {}
let g:dein#_base_path = ''
let g:dein#_cache_path = ''
let g:dein#_runtime_path = ''
let g:dein#_hook_add = ''
let g:dein#_ftplugin = {}
let g:dein#_called_lua = {}
let g:dein#_off1 = ''
let g:dein#_off2 = ''
let g:dein#_vimrcs = []
let g:dein#_block_level = 0
let g:dein#_event_plugins = {}
let g:dein#_is_sudo = $SUDO_USER !=# '' && $USER !=# $SUDO_USER
\ && $HOME !=# expand('~'.$USER)
\ && $HOME ==# expand('~'.$SUDO_USER)
let g:dein#_progname = fnamemodify(v:progname, ':r')
let g:dein#_init_runtimepath = &runtimepath
let g:dein#_loaded_rplugins = v:false
if get(g:, 'dein#lazy_rplugins', v:false)
" Disable remote plugin loading
let g:loaded_remote_plugins = 1
endif
augroup dein
autocmd!
autocmd FuncUndefined *
\ if stridx(expand('<afile>'), 'remote#') != 0 |
\ call dein#autoload#_on_func(expand('<afile>')) |
\ endif
autocmd BufRead *? call dein#autoload#_on_default_event('BufRead')
autocmd BufNew,BufNewFile *? call dein#autoload#_on_default_event('BufNew')
autocmd VimEnter *? call dein#autoload#_on_default_event('VimEnter')
autocmd FileType *? call dein#autoload#_on_default_event('FileType')
autocmd BufWritePost *.vim,*.toml,vimrc,.vimrc
\ call dein#util#_check_vimrcs()
augroup END
augroup dein-events | augroup END
if !exists('##CmdUndefined') | return | endif
autocmd dein CmdUndefined *
\ call dein#autoload#_on_pre_cmd(expand('<afile>'))
if has('nvim-0.5')
lua <<END
table.insert(package.loaders, 1, (function()
return function(mod_name)
vim.fn['dein#autoload#_on_lua'](mod_name)
return nil
end
end)())
END
endif
endfunction
function! dein#load_cache_raw(vimrcs) abort function! dein#load_cache_raw(vimrcs) abort
let g:dein#_vimrcs = a:vimrcs return dein#min#_load_cache_raw(a:vimrcs)
let cache = get(g:, 'dein#cache_directory', g:dein#_base_path)
\ .'/cache_' . g:dein#_progname
let time = getftime(cache)
if !empty(filter(map(copy(g:dein#_vimrcs),
\ 'getftime(expand(v:val))'), 'time < v:val'))
return [{}, {}]
endif
let list = readfile(cache)
if len(list) != 3 || string(g:dein#_vimrcs) !=# list[0]
return [{}, {}]
endif
return [json_decode(list[1]), json_decode(list[2])]
endfunction endfunction
function! dein#load_state(path, ...) abort function! dein#load_state(path, ...) abort
if !exists('#dein') return call('dein#min#load_state', [a:path] + a:000)
call dein#_init()
endif
let sourced = a:0 > 0 ? a:1 : has('vim_starting') &&
\ (!exists('&loadplugins') || &loadplugins)
if (g:dein#_is_sudo || !sourced) | return 1 | endif
let g:dein#_base_path = expand(a:path)
let state = get(g:, 'dein#cache_directory', g:dein#_base_path)
\ . '/state_' . g:dein#_progname . '.vim'
if !filereadable(state) | return 1 | endif
try
execute 'source' fnameescape(state)
catch
if v:exception !=# 'Cache loading error'
call dein#util#_error('Loading state error: ' . v:exception)
endif
call dein#clear_state()
return 1
endtry
endfunction endfunction
function! dein#tap(name) abort function! dein#tap(name) abort
if !has_key(g:dein#_plugins, a:name) if !dein#is_available(a:name) | return 0 | endif
\ || !isdirectory(g:dein#_plugins[a:name].path) | return 0 | endif
let g:dein#name = a:name let g:dein#name = a:name
let g:dein#plugin = g:dein#_plugins[a:name] let g:dein#plugin = g:dein#_plugins[a:name]
return 1 return 1
@ -111,6 +22,15 @@ function! dein#is_sourced(name) abort
\ && isdirectory(g:dein#_plugins[a:name].path) \ && isdirectory(g:dein#_plugins[a:name].path)
\ && g:dein#_plugins[a:name].sourced \ && g:dein#_plugins[a:name].sourced
endfunction endfunction
function! dein#is_available(names) abort
for name in type(a:names) ==# v:t_list ? a:names : [a:names]
if !has_key(g:dein#_plugins, name) | return 0 | endif
let plugin = g:dein#_plugins[name]
if !isdirectory(plugin.path)
\ || (has_key(plugin, 'if') && !eval(plugin.if)) | return 0 | endif
endfor
return 1
endfunction
function! dein#begin(path, ...) abort function! dein#begin(path, ...) abort
return dein#util#_begin(a:path, (empty(a:000) ? [] : a:1)) return dein#util#_begin(a:path, (empty(a:000) ? [] : a:1))
endfunction endfunction
@ -209,7 +129,7 @@ endfunction
function! dein#config(arg, ...) abort function! dein#config(arg, ...) abort
return type(a:arg) != v:t_list ? return type(a:arg) != v:t_list ?
\ dein#util#_config(a:arg, get(a:000, 0, {})) : \ dein#util#_config(a:arg, get(a:000, 0, {})) :
\ map(copy(a:arg), 'dein#util#_config(v:val, a:1)') \ map(copy(a:arg), { _, val -> dein#util#_config(val, a:1) })
endfunction endfunction
function! dein#set_hook(plugins, hook_name, hook) abort function! dein#set_hook(plugins, hook_name, hook) abort
return dein#util#_set_hook(a:plugins, a:hook_name, a:hook) return dein#util#_set_hook(a:plugins, a:hook_name, a:hook)
@ -218,5 +138,10 @@ function! dein#save_state() abort
return dein#util#_save_state(has('vim_starting')) return dein#util#_save_state(has('vim_starting'))
endfunction endfunction
function! dein#clear_state() abort function! dein#clear_state() abort
return dein#util#_clear_state() call dein#util#_clear_state()
if !get(g:, 'dein#auto_recache', v:false) && !empty(g:dein#_ftplugin)
call dein#util#_notify(
\ 'call dein#recache_runtimepath() is needed for ftplugin feature')
endif
endfunction endfunction

View File

@ -0,0 +1,801 @@
" date and time library.
function! s:_init() abort
let s:NUM_SECONDS = 60
let s:NUM_MINUTES = 60
let s:NUM_HOURS = 24
let s:NUM_DAYS_OF_WEEK = 7
let s:NUM_MONTHS = 12
let s:SECONDS_OF_HOUR = s:NUM_SECONDS * s:NUM_MINUTES
let s:SECONDS_OF_DAY = s:SECONDS_OF_HOUR * s:NUM_HOURS
let s:ERA_TIME = s:_g2jd(1, 1, 1)
let s:EPOC_TIME = s:_g2jd(1970, 1, 1)
let s:MONTHS = map(range(1, 12),
\ 's:from_date(1970, v:val, 1, 0, 0, 0, 0).unix_time()')
let s:WEEKS = map(range(4, 10),
\ 's:from_date(1970, 1, v:val, 0, 0, 0, 0).unix_time()')
let s:AM_PM_TIMES = map([0, 12],
\ 's:from_date(1970, 1, 1, v:val, 0, 0, 0).unix_time()')
" default values
call extend(s:DateTime, {
\ '_year': 0,
\ '_month': 1,
\ '_day': 1,
\ '_hour': 0,
\ '_minute': 0,
\ '_second': 0,
\ '_timezone': s:timezone(),
\ })
call extend(s:TimeDelta, {
\ '_days': 0,
\ '_seconds': 0,
\ })
let s:tz_default_offset = s:timezone().offset()
endfunction
" Creates a DateTime object with current time from system.
function! s:now(...) abort
let now = s:from_unix_time(localtime())
if a:0
let now = now.to(s:timezone(a:1))
endif
return now
endfunction
" Creates a DateTime object from given unix time.
function! s:from_unix_time(unix_time, ...) abort
let tz = call('s:timezone', a:000)
return call('s:from_date',
\ map(split(strftime('%Y %m %d %H %M %S', a:unix_time)),
\ 'str2nr(v:val, 10)')).to(tz)
endfunction
" Creates a DateTime object from given date and time.
" @param year = 1970
" @param month = 1
" @param day = 1
" @param hour = 0
" @param minute = 0
" @param second = 0
" @param timezone = ''
function! s:from_date(...) abort
let o = copy(s:DateTime)
let [o._year, o._month, o._day, o._hour, o._minute, o._second, tz] =
\ a:000 + [1970, 1, 1, 0, 0, 0, ''][a:0 :]
let o._timezone = s:timezone(tz)
return o._normalize()
endfunction
" Creates a DateTime object from format.
function! dein#DateTime#from_format(string, format, ...) abort
let o = copy(s:DateTime)
let locale = a:0 ? a:1 : ''
let remain = a:string
let skip_pattern = ''
for f in s:_split_format(a:format)
if type(f) == v:t_string
let pat = '^' . skip_pattern . '\V' . escape(f, '\')
let matched_len = len(matchstr(remain, pat))
if matched_len == 0
throw join([
\ 'vital: DateTime: Parse error:',
\ 'input: ' . a:string,
\ 'format: ' . a:format,
\ ], "\n")
endif
let remain = remain[matched_len :]
else " if type(f) == v:t_list
let info = f[0]
if info[0] ==# '#skip'
let skip_pattern = info[1]
else
let remain = s:_read_format(o, f, remain, skip_pattern, locale)
let skip_pattern = ''
endif
endif
unlet f
endfor
return o._normalize()
endfunction
" @vimlint(EVL102, 1, l:locale)
function! s:_read_format(datetime, descriptor, remain, skip_pattern, locale) abort
" "o", "key", "value" and "locale" are used by parse_conv
let o = a:datetime
let locale = a:locale " for parse_conv
let [info, flag, width] = a:descriptor
let key = '_' . info[0]
if !has_key(o, key)
let key = '_'
endif
let Captor = info[1]
if type(Captor) == v:t_func
let pattern = call(Captor, [a:locale], {})
if type(pattern) == v:t_list
let candidates = pattern
unlet pattern
let pattern = '\%(' . join(candidates, '\|') . '\)'
endif
elseif type(Captor) == v:t_list
if width ==# ''
let width = Captor[1]
endif
let pattern = '\d\{1,' . width . '}'
if flag ==# '_'
let pattern = '\s*' . pattern
endif
else " if type(Captor) == v:t_string
let pattern = Captor
endif
let value = matchstr(a:remain, '^' . a:skip_pattern . pattern)
let matched_len = len(value)
if exists('candidates')
let value = index(candidates, value)
elseif type(Captor) == v:t_list
let value = str2nr(value, 10)
endif
if 4 <= len(info)
let l:['value'] = eval(info[3])
endif
if key !=# '_'
let o[key] = value
endif
return a:remain[matched_len :]
endfunction
" @vimlint(EVL102, 0, l:locale)
" Creates a DateTime object from Julian day.
function! s:from_julian_day(jd, ...) abort
let tz = call('s:timezone', a:000)
let second = 0
if type(a:jd) == v:t_float
let jd = float2nr(floor(a:jd))
let second = float2nr(s:SECONDS_OF_DAY * (a:jd - jd))
else
let jd = a:jd
endif
let [year, month, day] = s:_jd2g(jd)
return s:from_date(year, month, day, 12, 0, second, '+0000').to(tz)
endfunction
" Creates a new TimeZone object.
function! s:timezone(...) abort
let info = a:0 ? a:1 : ''
if s:_is_class(info, 'TimeZone')
return info
endif
if info is# ''
unlet info
let info = s:_default_tz()
endif
let tz = copy(s:TimeZone)
if type(info) == v:t_number
let tz._offset = info * s:NUM_MINUTES * s:NUM_SECONDS
elseif type(info) == v:t_string
let list = matchlist(info, '\v^([+-])?(\d{1,2}):?(\d{1,2})?$')
if !empty(list)
let tz._offset = str2nr(list[1] . s:NUM_SECONDS) *
\ (str2nr(list[2]) * s:NUM_MINUTES + str2nr(list[3]))
else
" TODO: TimeZone names
throw 'vital: DateTime: Unknown timezone: ' . string(info)
endif
else
throw 'vital: DateTime: Invalid timezone: ' . string(info)
endif
return tz
endfunction
" Creates a new TimeDelta object.
function! s:delta(...) abort
let info = a:0 ? a:1 : ''
if s:_is_class(info, 'TimeDelta')
return info
endif
let d = copy(s:TimeDelta)
if a:0 == 2 && type(a:1) == v:t_number && type(a:2) == v:t_number
let d._days = a:1
let d._seconds = a:2
else
let a = copy(a:000)
while 2 <= len(a) && type(a[0]) == v:t_number && type(a[1]) == v:t_string
let [value, unit] = remove(a, 0, 1)
if unit =~? '^sec\%(onds\?\)\?$'
let d._seconds += value
elseif unit =~? '^min\%(utes\?\)\?$'
let d._seconds += value * s:NUM_SECONDS
elseif unit =~? '^hours\?$'
let d._seconds += value * s:SECONDS_OF_HOUR
elseif unit =~? '^days\?$'
let d._days += value
elseif unit =~? '^weeks\?$'
let d._days += value * s:NUM_DAYS_OF_WEEK
else
throw 'vital: DateTime: Invalid unit for delta(): ' . string(unit)
endif
endwhile
if !empty(a)
throw 'vital: DateTime: Invalid arguments for delta(): ' . string(a)
endif
endif
return d._normalize()
endfunction
function! s:compare(d1, d2) abort
return a:d1.compare(a:d2)
endfunction
" Returns month names according to the current or specified locale.
" @param fullname = false
" @param locale = ''
function! s:month_names(...) abort
return s:_names(s:MONTHS, a:0 && a:1 ? '%B' : '%b', get(a:000, 1, ''))
endfunction
" Returns weekday names according to the current or specified locale.
" @param fullname = false
" @param locale = ''
function! s:weekday_names(...) abort
return s:_names(s:WEEKS, a:0 && a:1 ? '%A' : '%a', get(a:000, 1, ''))
endfunction
" Returns am/pm names according to the current or specified locale.
" @param lowercase = false
" @param locale = ''
function! s:am_pm_names(...) abort
let [lowercase, locale] = a:000 + [0, ''][a:0 :]
let names = s:_am_pm_names(lowercase, locale)
if lowercase
" Some environments do not support %P.
" In this case, use tolower() of %p instead of.
let failed = names[0] ==# '' || names[0] ==# 'P'
if failed
let names = s:_am_pm_names(0, locale)
call map(names, 'tolower(v:val)')
endif
endif
return names
endfunction
function! s:_am_pm_names(lowercase, locale) abort
return s:_names(s:AM_PM_TIMES, a:lowercase ? '%P' : '%p', a:locale)
endfunction
" Returns 1 if the year is a leap year.
function! s:is_leap_year(year) abort
return a:year % 4 == 0 && a:year % 100 != 0 || a:year % 400 == 0
endfunction
" ----------------------------------------------------------------------------
let s:Class = {}
function! s:Class._clone() abort
return filter(copy(self), 'v:key !~# "^__"')
endfunction
function! s:_new_class(class) abort
return extend({'class': a:class}, s:Class)
endfunction
function! s:_is_class(obj, class) abort
return type(a:obj) == v:t_dict && get(a:obj, 'class', '') ==# a:class
endfunction
" ----------------------------------------------------------------------------
let s:DateTime = s:_new_class('DateTime')
function! s:DateTime.year() abort
return self._year
endfunction
function! s:DateTime.month() abort
return self._month
endfunction
function! s:DateTime.day() abort
return self._day
endfunction
function! s:DateTime.hour() abort
return self._hour
endfunction
function! s:DateTime.minute() abort
return self._minute
endfunction
function! s:DateTime.second() abort
return self._second
endfunction
function! s:DateTime.timezone(...) abort
if a:0
let dt = self._clone()
let dt._timezone = call('s:timezone', a:000)
return dt
endif
return self._timezone
endfunction
function! s:DateTime.day_of_week() abort
if !has_key(self, '__day_of_week')
let self.__day_of_week = self.timezone(0).days_from_era() % 7
endif
return self.__day_of_week
endfunction
function! s:DateTime.day_of_year() abort
if !has_key(self, '__day_of_year')
let self.__day_of_year = self.timezone(0).julian_day() -
\ s:_g2jd(self._year, 1, 1) + 1
endif
return self.__day_of_year
endfunction
function! s:DateTime.days_from_era() abort
if !has_key(self, '__day_from_era')
let self.__day_from_era = self.julian_day() - s:ERA_TIME + 1
endif
return self.__day_from_era
endfunction
function! s:DateTime.julian_day(...) abort
let utc = self.to(0)
let jd = s:_g2jd(utc._year, utc._month, utc._day)
if a:0 && a:1
if has('float')
let jd += (utc.seconds_of_day() + 0.0) / s:SECONDS_OF_DAY - 0.5
elseif utc._hour < 12
let jd -= 1
endif
endif
return jd
endfunction
function! s:DateTime.seconds_of_day() abort
return (self._hour * s:NUM_MINUTES + self._minute)
\ * s:NUM_SECONDS + self._second
endfunction
function! s:DateTime.quarter() abort
return (self._month - 1) / 3 + 1
endfunction
function! s:DateTime.unix_time() abort
if !has_key(self, '__unix_time')
if self._year < 1969 ||
\ (!has('num64') && (2038 < self._year))
let self.__unix_time = -1
else
let utc = self.to(0)
let self.__unix_time = (utc.julian_day() - s:EPOC_TIME) *
\ s:SECONDS_OF_DAY + utc.seconds_of_day()
if self.__unix_time < 0
let self.__unix_time = -1
endif
endif
endif
return self.__unix_time
endfunction
function! s:DateTime.is_leap_year() abort
return s:is_leap_year(self._year)
endfunction
function! s:DateTime.is(dt) abort
return self.compare(a:dt) == 0
endfunction
function! s:DateTime.compare(dt) abort
return self.delta(a:dt).sign()
endfunction
function! s:DateTime.delta(dt) abort
let left = self.to(0)
let right = a:dt.to(0)
return s:delta(left.days_from_era() - right.days_from_era(),
\ (left.seconds_of_day() + left.timezone().offset()) -
\ (right.seconds_of_day() + right.timezone().offset()))
endfunction
function! s:DateTime.to(...) abort
let dt = self._clone()
if a:0 == 1 && !s:_is_class(a:1, 'TimeDelta')
let tz = s:timezone(a:1)
let dt._second += tz.offset() - dt.timezone().offset()
let dt._timezone = tz
return dt._normalize()
endif
let delta = call('s:delta', a:000)
let dt._day += delta._days
let dt._second += delta._seconds
return dt._normalize()
endfunction
" @vimlint(EVL102, 1, l:locale)
function! s:DateTime.format(format, ...) abort
let locale = a:0 ? a:1 : ''
let result = ''
for f in s:_split_format(a:format)
if type(f) == v:t_string
let result .= f
elseif type(f) == v:t_list
let [info, flag, width] = f
let padding = ''
if type(info[1]) == v:t_list
let [padding, w] = info[1]
if width ==# ''
let width = w
endif
endif
if has_key(self, info[0])
let value = self[info[0]]()
if 2 < len(info)
let l:['value'] = eval(info[2])
endif
elseif 2 < len(info)
let value = info[2]
else
let value = ''
endif
if flag ==# '^'
let value = toupper(value)
elseif flag ==# '-'
let padding = ''
elseif flag ==# '_'
let padding = ' '
elseif flag ==# '0'
let padding = '0'
endif
let result .= printf('%' . padding . width . 's', value)
unlet value
endif
unlet f
endfor
return result
endfunction
" @vimlint(EVL102, 0, l:locale)
function! s:DateTime.strftime(format, ...) abort
let tz = self.timezone()
let ts = self.unix_time() + tz.offset() - s:tz_default_offset
let locale = get(a:000, 0, '')
let format = a:format =~? '%z'
\ ? substitute(a:format, '%z', tz.offset_string(), 'g')
\ : a:format
if empty(locale)
return strftime(format, ts)
else
let expr = printf('strftime(%s, %d)', string(format), ts)
return s:_with_locale(expr, locale)
endif
endfunction
function! s:DateTime.to_string() abort
return self.format('%c')
endfunction
function! s:DateTime._normalize() abort
let next = 0
for unit in ['second', 'minute', 'hour']
let key = '_' . unit
let self[key] += next
let [next, self[key]] =
\ s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')])
endfor
let self._day += next
let [self._year, self._month, self._day] =
\ s:_jd2g(s:_g2jd(self._year, self._month, self._day))
return self
endfunction
let s:DateTime['+'] = s:DateTime.to
let s:DateTime['-'] = s:DateTime.delta
let s:DateTime['=='] = s:DateTime.is
" ----------------------------------------------------------------------------
let s:TimeZone = s:_new_class('TimeZone')
function! s:TimeZone.offset() abort
return self._offset
endfunction
function! s:TimeZone.minutes() abort
return self._offset / s:NUM_SECONDS
endfunction
function! s:TimeZone.hours() abort
return self._offset / s:SECONDS_OF_HOUR
endfunction
function! s:TimeZone.sign() abort
return self._offset < 0 ? -1 : 0 < self._offset ? 1 : 0
endfunction
function! s:TimeZone.offset_string() abort
return substitute(self.w3c(), ':', '', '')
endfunction
function! s:TimeZone.w3c() abort
let sign = self._offset < 0 ? '-' : '+'
let minutes = abs(self._offset) / s:NUM_SECONDS
return printf('%s%02d:%02d', sign,
\ minutes / s:NUM_MINUTES, minutes % s:NUM_MINUTES)
endfunction
" ----------------------------------------------------------------------------
let s:TimeDelta = s:_new_class('TimeDelta')
function! s:TimeDelta.seconds() abort
return self._seconds % s:NUM_SECONDS
endfunction
function! s:TimeDelta.minutes() abort
return self._seconds / s:NUM_SECONDS % s:NUM_MINUTES
endfunction
function! s:TimeDelta.hours() abort
return self._seconds / s:SECONDS_OF_HOUR
endfunction
function! s:TimeDelta.days() abort
return self._days
endfunction
function! s:TimeDelta.weeks() abort
return self._days / s:NUM_DAYS_OF_WEEK
endfunction
function! s:TimeDelta.months() abort
return self._days / 30
endfunction
function! s:TimeDelta.years() abort
return self._days / 365
endfunction
function! s:TimeDelta.total_seconds() abort
return self._days * s:SECONDS_OF_DAY + self._seconds
endfunction
function! s:TimeDelta.is(td) abort
return self.subtract(a:td).sign() == 0
endfunction
function! s:TimeDelta.sign() abort
if self._days < 0 || self._seconds < 0
return -1
elseif 0 < self._days || 0 < self._seconds
return 1
endif
return 0
endfunction
function! s:TimeDelta.negate() abort
let td = self._clone()
let td._days = -self._days
let td._seconds = -self._seconds
return td._normalize()
endfunction
function! s:TimeDelta.duration() abort
return self.sign() < 0 ? self.negate() : self
endfunction
function! s:TimeDelta.add(...) abort
let n = self._clone()
let other = call('s:delta', a:000)
let n._days += other._days
let n._seconds += other._seconds
return n._normalize()
endfunction
function! s:TimeDelta.subtract(...) abort
let other = call('s:delta', a:000)
return self.add(other.negate())
endfunction
function! s:TimeDelta.about() abort
if self.sign() == 0
return 'now'
endif
let dir = self.sign() < 0 ? 'ago' : 'later'
let d = self.duration()
if d._days == 0
if d._seconds < s:NUM_SECONDS
let val = d.seconds()
let unit = val == 1 ? 'second' : 'seconds'
elseif d._seconds < s:SECONDS_OF_HOUR
let val = d.minutes()
let unit = val == 1 ? 'minute' : 'minutes'
else
let val = d.hours()
let unit = val == 1 ? 'hour' : 'hours'
endif
else
if d._days < s:NUM_DAYS_OF_WEEK
let val = d.days()
let unit = val == 1 ? 'day' : 'days'
elseif d._days < 30
let val = d.weeks()
let unit = val == 1 ? 'week' : 'weeks'
elseif d._days < 365
let val = d.months()
let unit = val == 1 ? 'month' : 'months'
else
let val = d.years()
let unit = val == 1 ? 'year' : 'years'
endif
endif
return printf('%d %s %s', val, unit, dir)
endfunction
function! s:TimeDelta.to_string() abort
let str = self.sign() < 0 ? '-' : ''
let d = self.duration()
if d._days != 0
let str .= d._days . (d._days == 1 ? 'day' : 'days') . ', '
endif
let str .= printf('%02d:%02d:%02d', d.hours(), d.minutes(), d.seconds())
return str
endfunction
function! s:TimeDelta._normalize() abort
let over_days = self._seconds / s:SECONDS_OF_DAY
let self._days += over_days
let self._seconds = self._seconds % s:SECONDS_OF_DAY
if self._days < 0 && 0 < self._seconds
let self._days += 1
let self._seconds -= s:SECONDS_OF_DAY
elseif 0 < self._days && self._seconds < 0
let self._days -= 1
let self._seconds += s:SECONDS_OF_DAY
endif
return self
endfunction
" ----------------------------------------------------------------------------
" Converts Gregorian Calendar to Julian day
function! s:_g2jd(year, month, day) abort
let [next, month] = s:_divmod(a:month - 1, s:NUM_MONTHS)
let year = a:year + next + 4800 - (month <= 1)
let month += month <= 1 ? 10 : -2
return a:day + (153 * month + 2) / 5 + s:_div(1461 * year, 4) - 32045
\ - s:_div(year, 100) + s:_div(year, 400)
endfunction
" Converts Julian day to Gregorian Calendar
function! s:_jd2g(jd) abort
let t = a:jd + 68569
let n = s:_div(4 * t, 146097)
let t -= s:_div(146097 * n + 3, 4) - 1
let i = (4000 * t) / 1461001
let t += -(1461 * i) / 4 + 30
let j = (80 * t) / 2447
let x = j / 11
let day = t - (2447 * j) / 80
let month = j + 2 - (12 * x)
let year = 100 * (n - 49) + i + x
return [year, month, day]
endfunction
function! s:_names(dates, format, locale) abort
return s:_with_locale('map(copy(a:1), "strftime(a:2, v:val)")',
\ a:locale, copy(a:dates), a:format)
endfunction
function! s:_with_locale(expr, locale, ...) abort
let current_locale = ''
if a:locale !=# ''
let current_locale = v:lc_time
execute 'language time' a:locale
endif
try
return eval(a:expr)
finally
if a:locale !=# ''
execute 'language time' current_locale
endif
endtry
endfunction
function! s:_div(n, d) abort
return s:_divmod(a:n, a:d)[0]
endfunction
function! s:_mod(n, d) abort
return s:_divmod(a:n, a:d)[1]
endfunction
function! s:_divmod(n, d) abort
let [q, mod] = [a:n / a:d, a:n % a:d]
return mod != 0 && (a:d < 0) != (mod < 0) ? [q - 1, mod + a:d] : [q, mod]
endfunction
" ----------------------------------------------------------------------------
function! s:_month_abbr(locale) abort
return s:month_names(0, a:locale)
endfunction
function! s:_month_full(locale) abort
return s:month_names(1, a:locale)
endfunction
function! s:_weekday_abbr(locale) abort
return s:weekday_names(0, a:locale)
endfunction
function! s:_weekday_full(locale) abort
return s:weekday_names(1, a:locale)
endfunction
function! s:_am_pm_lower(locale) abort
return s:am_pm_names(1, a:locale)
endfunction
function! s:_am_pm_upper(locale) abort
return s:am_pm_names(0, a:locale)
endfunction
" key = descriptor
" value = string (format alias)
" value = [field, captor, format_conv, parse_conv]
" at format:
" field = function name of source.
" captor = [flat, width] for number format.
" format_conv = expr for convert. some variables are available.
" parse_conv = unused.
" at parse:
" field = param name (with "_")
" if it doesn't exist, the descriptor can't use.
" field = #skip
" in this case, captor is a skipping pattern
" captor = pattern to match.
" captor = [flat, width] for number format.
" captor = a function to return a pattern or candidates.
" format_conv = unused.
" parse_conv = expr for convert. some variables are available.
let s:format_info = {
\ '%': ['', '%', '%'],
\ 'a': ['day_of_week', function('s:_weekday_abbr'),
\ 's:_weekday_abbr(locale)[value]'],
\ 'A': ['day_of_week', function('s:_weekday_full'),
\ 's:_weekday_full(locale)[value]'],
\ 'b': ['month', function('s:_month_abbr'),
\ 's:_month_abbr(locale)[value - 1]', 'value + 1'],
\ 'B': ['month', function('s:_month_full'),
\ 's:_month_full(locale)[value - 1]', 'value + 1'],
\ 'c': '%F %T %z',
\ 'C': ['year', ['0', 2], '(value + 99) / 100', 'o[key] % 100 + value * 100'],
\ 'd': ['day', ['0', 2]],
\ 'D': '%m/%d/%y',
\ 'e': '%_m/%_d/%_y',
\ 'F': '%Y-%m-%d',
\ 'h': '%b',
\ 'H': ['hour', ['0', 2]],
\ 'I': ['hour', ['0', 2], 's:_mod(value - 1, 12) + 1', 'value % 12'],
\ 'j': ['day_of_year', ['0', 3]],
\ 'k': '%_H',
\ 'l': '%_I',
\ 'm': ['month', ['0', 2]],
\ 'M': ['minute', ['0', 2]],
\ 'n': ['', '\_s*', "\n"],
\ 'p': ['hour', function('s:_am_pm_upper'),
\ 's:_am_pm_upper(locale)[value / 12]', 'o[key] + value * 12'],
\ 'P': ['hour', function('s:_am_pm_lower'),
\ 's:_am_pm_lower(locale)[value / 12]', 'o[key] + value * 12'],
\ 'r': '%I:%M:%S %p',
\ 'R': '%H:%M',
\ 's': ['unix_time', ['', '']],
\ 'S': ['second', ['0', 2]],
\ 't': ['', '\_.*', "\t"],
\ 'u': ['day_of_week', ['0', 1], 'value == 0 ? 7 : value'],
\ 'U': 'TODO',
\ 'T': '%H:%M:%S',
\ 'w': ['day_of_week', ['0', 1]],
\ 'y': ['year', ['0', 2], 'value % 100',
\ '(o[key] != 0 ? o[key] : (value < 69 ? 2000 : 1900)) + value'],
\ 'Y': ['year', ['0', 4]],
\ 'z': ['timezone', '\v[+-]?%(\d{1,2})?:?%(\d{1,2})?', 'value.offset_string()',
\ 's:timezone(empty(value) ? 0 : value)'],
\ '*': ['#skip', '.\{-}', ''],
\ }
let s:DESCRIPTORS_PATTERN = '[' . join(keys(s:format_info), '') . ']'
" 'foo%Ybar%02m' => ['foo', ['Y', '', -1], 'bar', ['m', '0', 2], '']
function! s:_split_format(format) abort
let res = []
let pat = '\C%\([-_0^#]\?\)\(\d*\)\(' . s:DESCRIPTORS_PATTERN . '\)'
let format = a:format
while format !=# ''
let i = match(format, pat)
if i < 0
let res += [format]
break
endif
if i != 0
let res += [format[: i - 1]]
let format = format[i :]
endif
let [matched, flag, width, d] = matchlist(format, pat)[: 3]
let format = format[len(matched) :]
let info = s:format_info[d]
if type(info) == v:t_string
let format = info . format
else
let res += [[info, flag, width]]
endif
unlet info
endwhile
return res
endfunction
if has('win32') " This means any versions of windows https://github.com/vim-jp/vital.vim/wiki/Coding-Rule#how-to-check-if-the-runtime-os-is-windows
function! s:_default_tz() abort
let hm = map(split(strftime('%H %M', 0), ' '), 'str2nr(v:val)')
if str2nr(strftime('%Y', 0)) != 1970
let tz_sec = s:SECONDS_OF_DAY - hm[0] * s:SECONDS_OF_HOUR - hm[1] * s:NUM_SECONDS
return printf('-%02d%02d', tz_sec / s:SECONDS_OF_HOUR, (tz_sec / s:NUM_SECONDS) % s:NUM_MINUTES)
endif
return printf('+%02d%02d', hm[0], hm[1])
endfunction
else
function! s:_default_tz() abort
return strftime('%z')
endfunction
endif
call s:_init()

View File

@ -8,23 +8,24 @@ function! dein#autoload#_source(...) abort
let plugins = empty(a:000) ? values(g:dein#_plugins) : let plugins = empty(a:000) ? values(g:dein#_plugins) :
\ dein#util#_convert2list(a:1) \ dein#util#_convert2list(a:1)
if empty(plugins) if empty(plugins)
return return []
endif endif
if type(plugins[0]) != v:t_dict if type(plugins[0]) != v:t_dict
let plugins = map(dein#util#_convert2list(a:1), let plugins = map(dein#util#_convert2list(a:1),
\ 'get(g:dein#_plugins, v:val, {})') \ { _, val -> get(g:dein#_plugins, val, {}) })
endif endif
let rtps = dein#util#_split_rtp(&runtimepath) let rtps = dein#util#_split_rtp(&runtimepath)
let index = index(rtps, dein#util#_get_runtime_path()) let index = index(rtps, dein#util#_get_runtime_path())
if index < 0 if index < 0
return 1 return []
endif endif
let sourced = [] let sourced = []
for plugin in filter(plugins, for plugin in filter(plugins,
\ "!empty(v:val) && !v:val.sourced && v:val.rtp !=# ''") \ { _, val -> !empty(val) && !val.sourced && val.rtp !=# ''
\ && (!has_key(v:val, 'if') || eval(v:val.if)) })
call s:source_plugin(rtps, index, plugin, sourced) call s:source_plugin(rtps, index, plugin, sourced)
endfor endfor
@ -35,11 +36,26 @@ function! dein#autoload#_source(...) abort
" Reload script files. " Reload script files.
for plugin in sourced for plugin in sourced
for directory in filter(['plugin', 'after/plugin'], for directory in map(filter(
\ "isdirectory(plugin.rtp.'/'.v:val)") \ ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'],
for file in dein#util#_globlist(plugin.rtp.'/'.directory.'/**/*.vim') \ { _, val -> isdirectory(plugin.rtp . '/' . val) }),
\ { _, val -> plugin.rtp . '/' . val })
if directory =~# 'ftdetect'
if get(plugin, 'merge_ftdetect')
continue
endif
execute 'augroup filetypedetect'
endif
let files = glob(directory . '/**/*.vim', v:true, v:true)
if has('nvim')
let files += glob(directory . '/**/*.lua', v:true, v:true)
endif
for file in files
execute 'source' fnameescape(file) execute 'source' fnameescape(file)
endfor endfor
if directory =~# 'ftdetect'
execute 'augroup END'
endif
endfor endfor
if !has('vim_starting') if !has('vim_starting')
@ -54,6 +70,19 @@ function! dein#autoload#_source(...) abort
silent execute 'doautocmd' augroup event silent execute 'doautocmd' augroup event
endif endif
endfor endfor
" Register for lazy loaded denops plugin
if isdirectory(plugin.rtp . '/denops')
\ && exists('*denops#plugin#is_loaded')
for name in filter(map(globpath(plugin.rtp,
\ 'denops/*/main.ts', v:true, v:true),
\ { _, val -> fnamemodify(val, ':h:t')}),
\ { _, val -> !denops#plugin#is_loaded(val) })
" Note: denops#plugin#register() may be failed
silent! call denops#plugin#register(name, { 'mode': 'skip' })
call denops#plugin#wait(name)
endfor
endif
endif endif
endfor endfor
@ -64,14 +93,16 @@ function! dein#autoload#_source(...) abort
call s:reset_ftplugin() call s:reset_ftplugin()
endif endif
if (is_reset || filetype_before !=# filetype_after) && &filetype !=# '' if (is_reset || filetype_before !=# filetype_after) && &l:filetype !=# ''
" Recall FileType autocmd " Recall FileType autocmd
let &filetype = &filetype let &l:filetype = &l:filetype
endif endif
if !has('vim_starting') if !has('vim_starting')
call dein#call_hook('post_source', sourced) call dein#call_hook('post_source', sourced)
endif endif
return sourced
endfunction endfunction
function! dein#autoload#_on_default_event(event) abort function! dein#autoload#_on_default_event(event) abort
@ -87,28 +118,28 @@ function! dein#autoload#_on_default_event(event) abort
for filetype in split(&l:filetype, '\.') for filetype in split(&l:filetype, '\.')
let plugins += filter(copy(lazy_plugins), let plugins += filter(copy(lazy_plugins),
\ "index(get(v:val, 'on_ft', []), filetype) >= 0") \ { _, val -> index(get(val, 'on_ft', []), filetype) >= 0 })
endfor endfor
let plugins += filter(copy(lazy_plugins), let plugins += filter(copy(lazy_plugins),
\ "!empty(filter(copy(get(v:val, 'on_path', [])), \ { _, val -> !empty(filter(copy(get(val, 'on_path', [])),
\ 'path =~? v:val'))") \ { _, val -> path =~? val })) })
let plugins += filter(copy(lazy_plugins), let plugins += filter(copy(lazy_plugins),
\ "!has_key(v:val, 'on_event') \ { _, val -> !has_key(val, 'on_event') && has_key(val, 'on_if')
\ && has_key(v:val, 'on_if') && eval(v:val.on_if)") \ && eval(val.on_if) })
call s:source_events(a:event, plugins) call s:source_events(a:event, plugins)
endfunction endfunction
function! dein#autoload#_on_event(event, plugins) abort function! dein#autoload#_on_event(event, plugins) abort
let lazy_plugins = filter(dein#util#_get_plugins(a:plugins), let lazy_plugins = filter(dein#util#_get_plugins(a:plugins),
\ '!v:val.sourced') \ { _, val -> !val.sourced })
if empty(lazy_plugins) if empty(lazy_plugins)
execute 'autocmd! dein-events' a:event execute 'autocmd! dein-events' a:event
return return
endif endif
let plugins = filter(copy(lazy_plugins), let plugins = filter(copy(lazy_plugins),
\ "!has_key(v:val, 'on_if') || eval(v:val.on_if)") \ { _, val -> !has_key(val, 'on_if') || eval(val.on_if) })
call s:source_events(a:event, plugins) call s:source_events(a:event, plugins)
endfunction endfunction
function! s:source_events(event, plugins) abort function! s:source_events(event, plugins) abort
@ -148,8 +179,8 @@ function! dein#autoload#_on_func(name) abort
endif endif
call dein#autoload#_source(filter(dein#util#_get_lazy_plugins(), call dein#autoload#_source(filter(dein#util#_get_lazy_plugins(),
\ "stridx(function_prefix, v:val.normalized_name.'#') == 0 \ { _, val -> stridx(function_prefix, val.normalized_name.'#') == 0
\ || (index(get(v:val, 'on_func', []), a:name) >= 0)")) \ || (index(get(val, 'on_func', []), a:name) >= 0) }))
endfunction endfunction
function! dein#autoload#_on_lua(name) abort function! dein#autoload#_on_lua(name) abort
@ -164,17 +195,17 @@ function! dein#autoload#_on_lua(name) abort
let g:dein#_called_lua[a:name] = v:true let g:dein#_called_lua[a:name] = v:true
call dein#autoload#_source(filter(dein#util#_get_lazy_plugins(), call dein#autoload#_source(filter(dein#util#_get_lazy_plugins(),
\ "index(get(v:val, 'on_lua', []), mod_root) >= 0")) \ { _, val -> index(get(val, 'on_lua', []), mod_root) >= 0 }))
endfunction endfunction
function! dein#autoload#_on_pre_cmd(name) abort function! dein#autoload#_on_pre_cmd(name) abort
call dein#autoload#_source( call dein#autoload#_source(
\ filter(dein#util#_get_lazy_plugins(), \ filter(dein#util#_get_lazy_plugins(),
\ "index(map(copy(get(v:val, 'on_cmd', [])), \ { _, val -> index(map(copy(get(val, 'on_cmd', [])),
\ 'tolower(v:val)'), a:name) >= 0 \ { _, val2 -> tolower(val2) }), a:name) >= 0
\ || stridx(tolower(a:name), \ || stridx(tolower(a:name),
\ substitute(tolower(v:val.normalized_name), \ substitute(tolower(val.normalized_name),
\ '[_-]', '', 'g')) == 0")) \ '[_-]', '', 'g')) == 0 }))
endfunction endfunction
function! dein#autoload#_on_cmd(command, name, args, bang, line1, line2) abort function! dein#autoload#_on_cmd(command, name, args, bang, line1, line2) abort
@ -202,7 +233,11 @@ function! dein#autoload#_on_map(mapping, name, mode) abort
let input = s:get_input() let input = s:get_input()
call dein#source(a:name) let sourced = dein#source(a:name)
if empty(sourced)
" Prevent infinite loop
silent! execute a:mode.'unmap' a:mapping
endif
if a:mode ==# 'v' || a:mode ==# 'x' if a:mode ==# 'v' || a:mode ==# 'x'
call feedkeys('gv', 'n') call feedkeys('gv', 'n')
@ -256,6 +291,7 @@ endfunction
function! s:source_plugin(rtps, index, plugin, sourced) abort function! s:source_plugin(rtps, index, plugin, sourced) abort
if a:plugin.sourced || index(a:sourced, a:plugin) >= 0 if a:plugin.sourced || index(a:sourced, a:plugin) >= 0
\ || (has_key(a:plugin, 'if') && !eval(a:plugin.if))
return return
endif endif
@ -286,7 +322,7 @@ function! s:source_plugin(rtps, index, plugin, sourced) abort
let a:plugin.sourced = 1 let a:plugin.sourced = 1
for on_source in filter(dein#util#_get_lazy_plugins(), for on_source in filter(dein#util#_get_lazy_plugins(),
\ "index(get(v:val, 'on_source', []), a:plugin.name) >= 0") \ { _, val -> index(get(val, 'on_source', []), a:plugin.name) >= 0 })
if s:source_plugin(a:rtps, index, on_source, a:sourced) if s:source_plugin(a:rtps, index, on_source, a:sourced)
let index += 1 let index += 1
endif endif
@ -362,19 +398,25 @@ function! s:get_input() abort
endfunction endfunction
function! s:is_reset_ftplugin(plugins) abort function! s:is_reset_ftplugin(plugins) abort
if &filetype ==# '' if &l:filetype ==# ''
return 0 return 0
endif endif
for plugin in a:plugins for plugin in a:plugins
let ftplugin = plugin.rtp . '/ftplugin/' . &filetype let ftplugin = plugin.rtp . '/ftplugin/' . &l:filetype
let after = plugin.rtp . '/after/ftplugin/' . &filetype let after = plugin.rtp . '/after/ftplugin/' . &l:filetype
if !empty(filter(['ftplugin', 'indent', let check_ftplugin = !empty(filter(['ftplugin', 'indent',
\ 'after/ftplugin', 'after/indent',], \ 'after/ftplugin', 'after/indent',],
\ "filereadable(printf('%s/%s/%s.vim', \ { _, val -> filereadable(printf('%s/%s/%s.vim',
\ plugin.rtp, v:val, &filetype))")) \ plugin.rtp, val, &l:filetype))
\ || isdirectory(ftplugin) || isdirectory(after) \ || filereadable(printf('%s/%s/%s.lua',
\ || glob(ftplugin. '_*.vim') !=# '' || glob(after . '_*.vim') !=# '' \ plugin.rtp, val, &l:filetype))}))
if check_ftplugin
\ || isdirectory(ftplugin) || isdirectory(after)
\ || glob(ftplugin. '_*.vim', v:true) !=# ''
\ || glob(after . '_*.vim', v:true) !=# ''
\ || glob(ftplugin. '_*.lua', v:true) !=# ''
\ || glob(after . '_*.lua', v:true) !=# ''
return 1 return 1
endif endif
endfor endfor

View File

@ -12,7 +12,8 @@ let s:progress = ''
" Global options definition. " Global options definition.
let g:dein#install_max_processes = let g:dein#install_max_processes =
\ get(g:, 'dein#install_max_processes', 8) \ get(g:, 'dein#install_max_processes',
\ dein#util#_is_windows() ? 16 : 8)
let g:dein#install_progress_type = let g:dein#install_progress_type =
\ get(g:, 'dein#install_progress_type', 'echo') \ get(g:, 'dein#install_progress_type', 'echo')
let g:dein#install_message_type = let g:dein#install_message_type =
@ -25,6 +26,8 @@ let g:dein#install_github_api_token =
\ get(g:, 'dein#install_github_api_token', '') \ get(g:, 'dein#install_github_api_token', '')
let g:dein#install_curl_command = let g:dein#install_curl_command =
\ get(g:, 'dein#install_curl_command', 'curl') \ get(g:, 'dein#install_curl_command', 'curl')
let g:dein#install_check_diff =
\ get(g:, 'dein#install_check_diff', v:false)
function! s:get_job() abort function! s:get_job() abort
if !exists('s:Job') if !exists('s:Job')
@ -42,7 +45,7 @@ function! dein#install#_update(plugins, update_type, async) abort
let plugins = dein#util#_get_plugins(a:plugins) let plugins = dein#util#_get_plugins(a:plugins)
if a:update_type ==# 'install' if a:update_type ==# 'install'
let plugins = filter(plugins, '!isdirectory(v:val.path)') let plugins = filter(plugins, { _, val -> !isdirectory(val.path) })
endif endif
if a:async && !empty(s:global_context) && if a:async && !empty(s:global_context) &&
@ -112,10 +115,6 @@ function! dein#install#_check_update(plugins, force, async) abort
call s:error('curl must be executable for the feature.') call s:error('curl must be executable for the feature.')
return return
endif endif
if !exists('*strptime') && !has('python3')
call s:error('+python3 is required for the feature.')
return
endif
let s:global_context.progress_type = 'echo' let s:global_context.progress_type = 'echo'
@ -158,6 +157,7 @@ function! dein#install#_check_update(plugins, force, async) abort
else else
let candidates[-1] .= a:data[0] let candidates[-1] .= a:data[0]
endif endif
let candidates += a:data[1:] let candidates += a:data[1:]
endfunction endfunction
let process.job = s:get_job().start( let process.job = s:get_job().start(
@ -177,7 +177,8 @@ function! dein#install#_check_update(plugins, force, async) abort
try try
let json = json_decode(result) let json = json_decode(result)
let results += filter(values(json['data']), let results += filter(values(json['data']),
\ "type(v:val) == v:t_dict && has_key(v:val, 'pushedAt')") \ { _, val -> type(val) == v:t_dict
\ && has_key(val, 'pushedAt') })
catch catch
call s:error('json output decode error: ' + string(result)) call s:error('json output decode error: ' + string(result))
endtry endtry
@ -193,15 +194,13 @@ function! dein#install#_check_update(plugins, force, async) abort
let check_pushed[node['nameWithOwner']] = let check_pushed[node['nameWithOwner']] =
\ exists('*strptime') ? \ exists('*strptime') ?
\ strptime(format, pushed_at) : \ strptime(format, pushed_at) :
\ has('nvim') ? \ dein#DateTime#from_format(pushed_at, format).unix_time()
\ msgpack#strptime(format, pushed_at) :
\ s:strptime_py(format, pushed_at)
endfor endfor
" Get the last updated time by rollbackfile timestamp. " Get the last updated time by rollbackfile timestamp.
" Note: .git timestamp may be changed by git commands. " Note: .git timestamp may be changed by git commands.
let rollbacks = reverse(sort(dein#util#_globlist( let rollbacks = reverse(sort(glob(
\ s:get_rollback_directory() . '/*'))) \ s:get_rollback_directory() . '/*', v:true, v:true)))
let rollback_time = empty(rollbacks) ? -1 : getftime(rollbacks[0]) let rollback_time = empty(rollbacks) ? -1 : getftime(rollbacks[0])
" Compare with .git directory updated time. " Compare with .git directory updated time.
@ -225,12 +224,13 @@ function! dein#install#_check_update(plugins, force, async) abort
let s:global_context = {} let s:global_context = {}
if empty(updated) if empty(updated)
call dein#util#_notify(strftime('Done: (%Y/%m/%d %H:%M:%S)')) call s:notify(strftime('Done: (%Y/%m/%d %H:%M:%S)'))
return return
endif endif
call dein#util#_notify('Updated plugins: ' . " Note: Use echo to display it in confirm
\ string(map(copy(updated), 'v:val.name'))) call s:echo('Updated plugins: ' .
\ string(map(copy(updated), { _, val -> val.name })), 'echo')
if !a:force && confirm( if !a:force && confirm(
\ 'Updated plugins are exists. Update now?', "yes\nNo", 2) != 1 \ 'Updated plugins are exists. Update now?', "yes\nNo", 2) != 1
return return
@ -240,6 +240,11 @@ function! dein#install#_check_update(plugins, force, async) abort
endfunction endfunction
function! dein#install#_reinstall(plugins) abort function! dein#install#_reinstall(plugins) abort
if g:dein#_is_sudo
call s:error('update/install is disabled in sudo session.')
return
endif
let plugins = dein#util#_get_plugins(a:plugins) let plugins = dein#util#_get_plugins(a:plugins)
for plugin in plugins for plugin in plugins
@ -265,6 +270,11 @@ function! dein#install#_reinstall(plugins) abort
\ 'install', 0) \ 'install', 0)
endfunction endfunction
function! dein#install#_direct_install(repo, options) abort function! dein#install#_direct_install(repo, options) abort
if g:dein#_is_sudo
call s:error('update/install is disabled in sudo session.')
return
endif
let options = copy(a:options) let options = copy(a:options)
let options.merged = 0 let options.merged = 0
@ -281,14 +291,19 @@ function! dein#install#_direct_install(repo, options) abort
let line = printf('call dein#add(%s, %s)', let line = printf('call dein#add(%s, %s)',
\ string(a:repo), string(options)) \ string(a:repo), string(options))
if !filereadable(file) if !filereadable(file)
call writefile([line], file) call dein#util#_safe_writefile([line], file)
else else
call writefile(add(readfile(file), line), file) call dein#util#_safe_writefile(add(readfile(file), line), file)
endif endif
endfunction endfunction
function! dein#install#_rollback(date, plugins) abort function! dein#install#_rollback(date, plugins) abort
if g:dein#_is_sudo
call s:error('update/install is disabled in sudo session.')
return
endif
let glob = s:get_rollback_directory() . '/' . a:date . '*' let glob = s:get_rollback_directory() . '/' . a:date . '*'
let rollbacks = reverse(sort(dein#util#_globlist(glob))) let rollbacks = reverse(sort(glob(glob, v:true, v:true)))
if empty(rollbacks) if empty(rollbacks)
return return
endif endif
@ -301,45 +316,54 @@ function! dein#install#_recache_runtimepath() abort
return return
endif endif
let start = reltime()
" Clear runtime path. " Clear runtime path.
call s:clear_runtimepath() call s:clear_runtimepath()
let plugins = values(dein#get()) let plugins = values(dein#get())
let merged_plugins = filter(copy(plugins), 'v:val.merged') let merged_plugins = filter(copy(plugins), { _, val -> val.merged })
let lazy_merged_plugins = filter(copy(merged_plugins),
\ { _, val -> val.lazy })
let nolazy_merged_plugins = filter(copy(merged_plugins),
\ { _, val -> !val.lazy })
let merge_ftdetect_plugins = filter(copy(plugins),
\ { _, val -> get(val, 'merge_ftdetect', 0)
\ || (val.merged && !val.lazy) })
call s:copy_files(lazy_merged_plugins, '')
let runtime = dein#util#_get_runtime_path()
call s:copy_files(filter(copy(merged_plugins), 'v:val.lazy'), '')
" Remove plugin directory " Remove plugin directory
call dein#install#_rm(dein#util#_get_runtime_path() . '/plugin') call dein#install#_rm(runtime . '/plugin')
call dein#install#_rm(dein#util#_get_runtime_path() . '/after/plugin') call dein#install#_rm(runtime . '/after/plugin')
call s:copy_files(filter(copy(merged_plugins), '!v:val.lazy'), '') call s:copy_files(nolazy_merged_plugins, '')
call s:helptags() call s:helptags()
call s:generate_ftplugin() call s:generate_ftplugin()
" Clear ftdetect and after/ftdetect directories. " Clear ftdetect and after/ftdetect directories.
call dein#install#_rm( call dein#install#_rm(runtime . '/ftdetect')
\ dein#util#_get_runtime_path().'/ftdetect') call dein#install#_rm(runtime . '/after/ftdetect')
call dein#install#_rm(
\ dein#util#_get_runtime_path().'/after/ftdetect')
call s:merge_files(plugins, 'ftdetect') call s:merge_files(merge_ftdetect_plugins, 'ftdetect')
call s:merge_files(plugins, 'after/ftdetect') call s:merge_files(merge_ftdetect_plugins, 'after/ftdetect')
silent call dein#remote_plugins() silent call dein#remote_plugins()
call dein#call_hook('post_source') call dein#call_hook('post_source')
call dein#util#_save_merged_plugins()
call dein#install#_save_rollback( call dein#install#_save_rollback(
\ s:get_rollback_directory() . '/' . strftime('%Y%m%d%H%M%S'), []) \ s:get_rollback_directory() . '/' . strftime('%Y%m%d%H%M%S'), [])
call dein#clear_state() call dein#util#_clear_state()
call s:log(strftime('Runtimepath updated: (%Y/%m/%d %H:%M:%S)')) call s:log(strftime('Runtimepath updated: (%Y/%m/%d %H:%M:%S)'))
call s:log('recache_runtimepath: ' . split(reltimestr(reltime(start)))[0])
endfunction endfunction
function! s:clear_runtimepath() abort function! s:clear_runtimepath() abort
if dein#util#_get_cache_path() ==# '' if dein#util#_get_cache_path() ==# ''
@ -354,21 +378,19 @@ function! s:clear_runtimepath() abort
if !isdirectory(runtimepath) if !isdirectory(runtimepath)
" Create runtime path " Create runtime path
call mkdir(runtimepath, 'p') call dein#util#_safe_mkdir(runtimepath)
endif endif
endfunction endfunction
function! s:helptags() abort function! s:helptags() abort
if g:dein#_runtime_path ==# '' || g:dein#_is_sudo if g:dein#_runtime_path ==# ''
return '' return ''
endif endif
try try
let tags = dein#util#_get_runtime_path() . '/doc' let tags = dein#util#_get_runtime_path() . '/doc'
if !isdirectory(tags) call dein#util#_safe_mkdir(tags)
call mkdir(tags, 'p') call s:copy_files(filter(values(dein#get()),
endif \ { _, val -> !val.merged }), 'doc')
call s:copy_files(filter(
\ values(dein#get()), '!v:val.merged'), 'doc')
silent execute 'helptags' fnameescape(tags) silent execute 'helptags' fnameescape(tags)
catch /^Vim(helptags):E151:/ catch /^Vim(helptags):E151:/
" Ignore an error that occurs when there is no help file " Ignore an error that occurs when there is no help file
@ -380,8 +402,8 @@ function! s:helptags() abort
endfunction endfunction
function! s:copy_files(plugins, directory) abort function! s:copy_files(plugins, directory) abort
let directory = (a:directory ==# '' ? '' : '/' . a:directory) let directory = (a:directory ==# '' ? '' : '/' . a:directory)
let srcs = filter(map(copy(a:plugins), 'v:val.rtp . directory'), let srcs = filter(map(copy(a:plugins), { _, val -> val.rtp . directory }),
\ 'isdirectory(v:val)') \ { _, val -> isdirectory(val) })
let stride = 50 let stride = 50
for start in range(0, len(srcs), stride) for start in range(0, len(srcs), stride)
call dein#install#_copy_directories(srcs[start : start + stride-1], call dein#install#_copy_directories(srcs[start : start + stride-1],
@ -391,42 +413,41 @@ endfunction
function! s:merge_files(plugins, directory) abort function! s:merge_files(plugins, directory) abort
let files = [] let files = []
for plugin in a:plugins for plugin in a:plugins
for file in filter(split(globpath( for file in filter(globpath(
\ plugin.rtp, a:directory.'/**', 1), '\n'), \ plugin.rtp, a:directory.'/**', v:true, v:true),
\ '!isdirectory(v:val)') \ { _, val -> !isdirectory(val) })
let files += readfile(file, ':t') let files += readfile(file, ':t')
endfor endfor
endfor endfor
if !empty(files) if !empty(files)
call dein#util#_writefile(printf('.dein/%s/%s.vim', call dein#util#_cache_writefile(files,
\ a:directory, a:directory), files) \ printf('.dein/%s/%s.vim', a:directory, a:directory))
endif endif
endfunction endfunction
function! s:list_directory(directory) abort
return dein#util#_globlist(a:directory . '/*')
endfunction
function! dein#install#_save_rollback(rollbackfile, plugins) abort function! dein#install#_save_rollback(rollbackfile, plugins) abort
let revisions = {} let revisions = {}
for plugin in filter(dein#util#_get_plugins(a:plugins), for plugin in filter(dein#util#_get_plugins(a:plugins),
\ 's:check_rollback(v:val)') \ { _, val -> s:check_rollback(val) })
let rev = s:get_revision_number(plugin) let rev = s:get_revision_number(plugin)
if rev !=# '' if rev !=# ''
let revisions[plugin.name] = rev let revisions[plugin.name] = rev
endif endif
endfor endfor
call writefile([json_encode(revisions)], expand(a:rollbackfile)) call dein#util#_safe_writefile(
\ [json_encode(revisions)], expand(a:rollbackfile))
endfunction endfunction
function! dein#install#_load_rollback(rollbackfile, plugins) abort function! dein#install#_load_rollback(rollbackfile, plugins) abort
let revisions = json_decode(readfile(a:rollbackfile)[0]) let revisions = json_decode(readfile(a:rollbackfile)[0])
let plugins = dein#util#_get_plugins(a:plugins) let plugins = dein#util#_get_plugins(a:plugins)
call filter(plugins, "has_key(revisions, v:val.name) call filter(plugins, { _, val -> has_key(revisions, val.name)
\ && has_key(dein#util#_get_type(v:val.type), \ && has_key(dein#util#_get_type(val.type),
\ 'get_rollback_command') \ 'get_rollback_command')
\ && s:check_rollback(v:val) \ && s:check_rollback(val)
\ && s:get_revision_number(v:val) !=# revisions[v:val.name]") \ && s:get_revision_number(val) !=# revisions[val.name]
\ })
if empty(plugins) if empty(plugins)
return return
endif endif
@ -444,9 +465,7 @@ endfunction
function! s:get_rollback_directory() abort function! s:get_rollback_directory() abort
let parent = printf('%s/rollbacks/%s', let parent = printf('%s/rollbacks/%s',
\ dein#util#_get_cache_path(), g:dein#_progname) \ dein#util#_get_cache_path(), g:dein#_progname)
if !isdirectory(parent) call dein#util#_safe_mkdir(parent)
call mkdir(parent, 'p')
endif
return parent return parent
endfunction endfunction
@ -480,6 +499,11 @@ function! dein#install#_get_default_ftplugin() abort
\ ' execute "runtime! ftplugin/" . ft . ".vim"', \ ' execute "runtime! ftplugin/" . ft . ".vim"',
\ ' \ "ftplugin/" . ft . "_*.vim"', \ ' \ "ftplugin/" . ft . "_*.vim"',
\ ' \ "ftplugin/" . ft . "/*.vim"', \ ' \ "ftplugin/" . ft . "/*.vim"',
\ ' if has("nvim")',
\ ' execute "runtime! ftplugin/" . ft . ".lua"',
\ ' \ "ftplugin/" . ft . "_*.lua"',
\ ' \ "ftplugin/" . ft . "/*.lua"',
\ ' endif',
\ ' endfor', \ ' endfor',
\ ' endif', \ ' endif',
\ ' call s:after_ftplugin()', \ ' call s:after_ftplugin()',
@ -488,11 +512,13 @@ function! dein#install#_get_default_ftplugin() abort
\] \]
endfunction endfunction
function! s:generate_ftplugin() abort function! s:generate_ftplugin() abort
if empty(g:dein#_ftplugin)
return
endif
" Create after/ftplugin " Create after/ftplugin
let after = dein#util#_get_runtime_path() . '/after/ftplugin' let after = dein#util#_get_runtime_path() . '/after/ftplugin'
if !isdirectory(after) call dein#util#_safe_mkdir(after)
call mkdir(after, 'p')
endif
" Merge g:dein#_ftplugin " Merge g:dein#_ftplugin
let ftplugin = {} let ftplugin = {}
@ -512,14 +538,17 @@ function! s:generate_ftplugin() abort
endfor endfor
" Generate ftplugin.vim " Generate ftplugin.vim
call writefile(dein#install#_get_default_ftplugin() + [ call dein#util#_safe_writefile(
\ dein#install#_get_default_ftplugin() + [
\ 'function! s:after_ftplugin()', \ 'function! s:after_ftplugin()',
\ ] + get(ftplugin, '_', []) + ['endfunction'], \ ] + get(ftplugin, '_', []) + ['endfunction'],
\ dein#util#_get_runtime_path() . '/ftplugin.vim') \ dein#util#_get_runtime_path() . '/ftplugin.vim')
" Generate after/ftplugin " Generate after/ftplugin
for [filetype, list] in filter(items(ftplugin), "v:val[0] !=# '_'") for [filetype, list] in filter(items(ftplugin),
call writefile(list, printf('%s/%s.vim', after, filetype)) \ { _, val -> val[0] !=# '_' })
call dein#util#_safe_writefile(
\ list, printf('%s/%s.vim', after, filetype))
endfor endfor
endfunction endfunction
@ -542,7 +571,7 @@ function! dein#install#_polling() abort
endfunction endfunction
function! dein#install#_remote_plugins() abort function! dein#install#_remote_plugins() abort
if !has('nvim') if !has('nvim') || g:dein#_is_sudo
return return
endif endif
@ -558,12 +587,12 @@ function! dein#install#_remote_plugins() abort
" Load not loaded neovim remote plugins " Load not loaded neovim remote plugins
let remote_plugins = filter(values(dein#get()), let remote_plugins = filter(values(dein#get()),
\ "isdirectory(v:val.rtp . '/rplugin') && !v:val.sourced") \ { _, val -> isdirectory(val.rtp . '/rplugin') && !val.sourced })
call dein#autoload#_source(remote_plugins) call dein#autoload#_source(remote_plugins)
call s:log('loaded remote plugins: ' . call s:log('loaded remote plugins: ' .
\ string(map(copy(remote_plugins), 'v:val.name'))) \ string(map(copy(remote_plugins), { _, val -> val.name })))
let &runtimepath = dein#util#_join_rtp(dein#util#_uniq( let &runtimepath = dein#util#_join_rtp(dein#util#_uniq(
\ dein#util#_split_rtp(&runtimepath)), &runtimepath, '') \ dein#util#_split_rtp(&runtimepath)), &runtimepath, '')
@ -574,7 +603,7 @@ endfunction
function! dein#install#_each(cmd, plugins) abort function! dein#install#_each(cmd, plugins) abort
let plugins = filter(dein#util#_get_plugins(a:plugins), let plugins = filter(dein#util#_get_plugins(a:plugins),
\ 'isdirectory(v:val.path)') \ { _, val -> isdirectory(val.path) })
let global_context_save = s:global_context let global_context_save = s:global_context
@ -604,7 +633,7 @@ endfunction
function! dein#install#_build(plugins) abort function! dein#install#_build(plugins) abort
let error = 0 let error = 0
for plugin in filter(dein#util#_get_plugins(a:plugins), for plugin in filter(dein#util#_get_plugins(a:plugins),
\ "isdirectory(v:val.path) && has_key(v:val, 'build')") \ { _, val -> isdirectory(val.path) && has_key(val, 'build') })
call s:print_progress_message('Building: ' . plugin.name) call s:print_progress_message('Building: ' . plugin.name)
if dein#install#_each(plugin.build, plugin) if dein#install#_each(plugin.build, plugin)
let error = 1 let error = 1
@ -741,19 +770,24 @@ function! s:get_updated_message(context, plugins) abort
return '' return ''
endif endif
" Diff check
if g:dein#install_check_diff
call s:check_diff(a:plugins)
endif
return "Updated plugins:\n". return "Updated plugins:\n".
\ join(map(copy(a:plugins), \ join(map(copy(a:plugins),
\ "' ' . v:val.name . (v:val.commit_count == 0 ? '' \ { _, val -> ' ' . val.name . (val.commit_count == 0 ? ''
\ : printf('(%d change%s)', \ : printf('(%d change%s)',
\ v:val.commit_count, \ val.commit_count,
\ (v:val.commit_count == 1 ? '' : 's'))) \ (val.commit_count == 1 ? '' : 's')))
\ . ((v:val.old_rev !=# '' \ . ((val.old_rev !=# ''
\ && v:val.uri =~# '^\\h\\w*://github.com/') ? \"\\n\" \ && val.uri =~# '^\h\w*://github.com/') ? "\n"
\ . printf(' %s/compare/%s...%s', \ . printf(' %s/compare/%s...%s',
\ substitute(substitute(v:val.uri, '\\.git$', '', ''), \ substitute(substitute(val.uri, '\.git$', '', ''),
\ '^\\h\\w*:', 'https:', ''), \ '^\h\w*:', 'https:', ''),
\ v:val.old_rev, v:val.new_rev) : '')") \ val.old_rev, val.new_rev) : '')
\ , "\n") \ }) , "\n")
endfunction endfunction
function! s:get_errored_message(plugins) abort function! s:get_errored_message(plugins) abort
if empty(a:plugins) if empty(a:plugins)
@ -761,12 +795,28 @@ function! s:get_errored_message(plugins) abort
endif endif
let msg = "Error installing plugins:\n".join( let msg = "Error installing plugins:\n".join(
\ map(copy(a:plugins), "' ' . v:val.name"), "\n") \ map(copy(a:plugins), { _, val -> ' ' . val.name }), "\n")
let msg .= "\n" let msg .= "\n"
let msg .= "Please read the error message log with the :message command.\n" let msg .= "Please read the error message log with the :message command.\n"
return msg return msg
endfunction endfunction
function! s:check_diff(plugins) abort
for plugin in a:plugins
let type = dein#util#_get_type(plugin.type)
if !has_key(type, 'get_diff_command') || plugin.old_rev ==# ''
continue
endif
let diff = s:system_cd(
\ type.get_diff_command(plugin, plugin.old_rev, plugin.new_rev),
\ plugin.path)
if diff !=# ''
echo printf("%s: The documentation is updated\n%s\n\n",
\ plugin.name, diff)
endif
endfor
endfunction
" Helper functions " Helper functions
@ -784,24 +834,33 @@ function! dein#install#_cd(path) abort
call s:error(v:throwpoint) call s:error(v:throwpoint)
endtry endtry
endfunction endfunction
function! dein#install#_system(command) abort function! dein#install#_system(command) abort
" Todo: use job API instead for Vim8/neovim only return s:job_system.system(a:command)
" let job = s:Job.start() endfunction
" let exitval = job.wait() let s:job_system = {}
function! s:job_system.on_out(data) abort
if !has('nvim') && type(a:command) == v:t_list let candidates = s:job_system.candidates
" system() does not support List arguments in Vim. if empty(candidates)
let command = s:args2string(a:command) call add(candidates, a:data[0])
else else
let command = a:command let candidates[-1] .= a:data[0]
endif endif
let candidates += a:data[1:]
endfunction
function! s:job_system.system(cmd) abort
let self.candidates = []
let command = s:iconv(command, &encoding, 'char') let job = s:get_job().start(
let output = s:iconv(system(command), 'char', &encoding) \ s:convert_args(a:cmd),
return substitute(output, '\n$', '', '') \ {'on_stdout': self.on_out})
let s:job_system.status = job.wait(
\ g:dein#install_process_timeout * 1000)
return join(s:job_system.candidates, "\n")
endfunction endfunction
function! dein#install#_status() abort function! dein#install#_status() abort
return v:shell_error return s:job_system.status
endfunction endfunction
function! s:system_cd(command, path) abort function! s:system_cd(command, path) abort
let cwd = getcwd() let cwd = getcwd()
@ -841,43 +900,29 @@ function! s:job_execute.execute(cmd) abort
return job.wait(g:dein#install_process_timeout * 1000) return job.wait(g:dein#install_process_timeout * 1000)
endfunction endfunction
function! dein#install#_system_bg(command) abort
let job = s:get_job().start(
\ s:convert_args(a:command),
\ {
\ 'on_stderr': {
\ v -> map(copy(v), { _, val -> dein#util#_error(val) })
\ }
\ })
return job
endfunction
function! dein#install#_rm(path) abort function! dein#install#_rm(path) abort
if !isdirectory(a:path) && !filereadable(a:path) if !isdirectory(a:path) && !filereadable(a:path)
return return
endif endif
" Note: delete rf is broken before Vim 8.1.1378 try
if has('patch-8.1.1378') call delete(a:path, 'rf')
try catch
call delete(a:path, 'rf') call s:error('Error deleting directory: ' . a:path)
catch call s:error(v:exception)
call s:error('Error deleting directory: ' . a:path) call s:error(v:throwpoint)
call s:error(v:exception) endtry
call s:error(v:throwpoint)
endtry
return
endif
" Note: In Windows, ['rmdir', '/S', '/Q'] does not work.
" After Vim 8.0.928, double quote escape does not work in job. Too bad.
let cmdline = ' "' . a:path . '"'
if dein#util#_is_windows()
" Note: In rm command, must use "\" instead of "/".
let cmdline = substitute(cmdline, '/', '\\\\', 'g')
endif
let rm_command = dein#util#_is_windows() ? 'cmd /C rmdir /S /Q' : 'rm -rf'
let cmdline = rm_command . cmdline
let result = system(cmdline)
if v:shell_error
call dein#util#_error(result)
endif
" Error check.
if getftype(a:path) !=# ''
call dein#util#_error(printf('"%s" cannot be removed.', a:path))
call dein#util#_error(printf('cmdline is "%s".', cmdline))
endif
endfunction endfunction
function! dein#install#_copy_directories(srcs, dest) abort function! dein#install#_copy_directories(srcs, dest) abort
@ -885,6 +930,13 @@ function! dein#install#_copy_directories(srcs, dest) abort
return 0 return 0
endif endif
if dein#util#_is_windows() && has('python3')
\ && dein#install#_python_version_check()
" In Windows, copy directory is too slow!
" Note: Python 3.8.0 is needed
return dein#install#_copy_directories_py(a:srcs, a:dest)
endif
let status = 0 let status = 0
if dein#util#_is_windows() if dein#util#_is_windows()
if !executable('robocopy') if !executable('robocopy')
@ -892,36 +944,11 @@ function! dein#install#_copy_directories(srcs, dest) abort
return 1 return 1
endif endif
let temp = tempname() . '.bat' let status = dein#install#_copy_directories_robocopy(a:srcs, a:dest)
let exclude = tempname()
try
let lines = ['@echo off']
let format ='robocopy.exe %s /E /NJH /NJS /NDL /NC /NS /MT /XO /XD ".git"'
for src in a:srcs
call add(lines, printf(format,
\ substitute(printf('"%s" "%s"', src, a:dest),
\ '/', '\\', 'g')))
endfor
call writefile(lines, temp)
let result = dein#install#_system(temp)
finally
call delete(temp)
endtry
" Robocopy returns between 0 and 7 upon success
let status = dein#install#_status()
let status = (status > 7) ? status : 0
if status
call dein#util#_error('copy command failed.')
call dein#util#_error(s:iconv(result, 'char', &encoding))
call dein#util#_error('cmdline: ' . temp)
call dein#util#_error('tempfile: ' . string(lines))
endif
else " Not Windows else " Not Windows
let srcs = map(filter(copy(a:srcs), let srcs = map(filter(copy(a:srcs),
\ 'len(s:list_directory(v:val))'), 'shellescape(v:val . ''/'')') \ { _, val -> len(glob(val . '/*', v:true, v:true)) }),
\ { _, val -> shellescape(val . '/') })
let is_rsync = executable('rsync') let is_rsync = executable('rsync')
if is_rsync if is_rsync
let cmdline = printf("rsync -a -q --exclude '/.git/' %s %s", let cmdline = printf("rsync -a -q --exclude '/.git/' %s %s",
@ -947,6 +974,80 @@ function! dein#install#_copy_directories(srcs, dest) abort
return status return status
endfunction endfunction
function! dein#install#_copy_directories_robocopy(srcs, dest) abort
let jobs = []
let format = 'robocopy.exe %s /E /NJH /NJS '
\ . '/NDL /NC /NS /MT:8 /XO /XD ".git"'
let srcs = a:srcs
let MAX_LINES = 8
while !empty(srcs)
let temp = tempname() . '.bat'
let lines = ['@echo off']
while len(lines) < MAX_LINES && !empty(srcs)
let path = substitute(printf('"%s" "%s"', srcs[0], a:dest),
\ '/', '\\', 'g')
call add(lines, printf(format, path))
let srcs = srcs[1:]
endwhile
call dein#util#_safe_writefile(lines, temp)
let job = dein#install#_system_bg(temp)
call add(jobs, { 'commands': lines, 'job': job })
endwhile
" Async check
let ret = 0
while !empty(jobs)
let i = 0
for job in jobs
let status = job.job.wait(100)
if status == -1
" Next check
let i += 1
continue
endif
" Robocopy returns between 0 and 7 upon success
let status = (status > 7) ? status : 0
if status
call dein#util#_error('copy command failed.')
call dein#util#_error('cmdline: ' . string(job.commands))
let ret = 1
endif
call remove(jobs, i)
break
endfor
endwhile
return ret
endfunction
function! dein#install#_copy_directories_py(srcs, dest) abort
py3 << EOF
import shutil
import vim
for src in vim.eval('a:srcs'):
shutil.copytree(src, vim.eval('a:dest'),
dirs_exist_ok=True,
ignore=shutil.ignore_patterns('.git'))
EOF
endfunction
function! dein#install#_python_version_check() abort
python3 << EOF
import vim
import sys
vim.vars['dein#_python_version_check'] = (
sys.version_info.major,
sys.version_info.minor,
sys.version_info.micro) >= (3, 8, 0)
EOF
return get(g:, 'dein#_python_version_check', 0)
endfunction
function! s:install_blocking(context) abort function! s:install_blocking(context) abort
try try
@ -962,7 +1063,6 @@ function! s:install_blocking(context) abort
call s:done(a:context) call s:done(a:context)
endtry endtry
return len(a:context.errored_plugins) return len(a:context.errored_plugins)
endfunction endfunction
function! s:install_async(context) abort function! s:install_async(context) abort
@ -1005,7 +1105,7 @@ function! s:check_loop(context) abort
endfor endfor
" Filter eof processes. " Filter eof processes.
call filter(a:context.processes, '!v:val.eof') call filter(a:context.processes, { _, val -> !val.eof })
endfunction endfunction
function! s:restore_view(context) abort function! s:restore_view(context) abort
if a:context.progress_type ==# 'tabline' if a:context.progress_type ==# 'tabline'
@ -1067,15 +1167,35 @@ function! s:done(context) abort
call s:notify(s:get_errored_message(a:context.errored_plugins)) call s:notify(s:get_errored_message(a:context.errored_plugins))
endif endif
call dein#install#_recache_runtimepath()
if !empty(a:context.synced_plugins) if !empty(a:context.synced_plugins)
call dein#call_hook('done_update', a:context.synced_plugins) call dein#install#_recache_runtimepath()
call dein#source(map(copy(a:context.synced_plugins), 'v:val.name'))
call dein#source(map(copy(a:context.synced_plugins),
\ { _, val -> val.name }))
" Execute done_update hooks
let done_update_plugins = filter(copy(a:context.synced_plugins),
\ { _, val -> has_key(val, 'hook_done_update') })
if !empty(done_update_plugins)
if has('vim_starting')
let s:done_updated_plugins = done_update_plugins
autocmd dein VimEnter * call s:call_done_update_hooks(
\ s:done_updated_plugins)
else
" Reload plugins to execute hooks
runtime! plugin/**/*.vim
if has('nvim')
" Neovim loads lua files at startup
runtime! plugin/**/*.lua
endif
call s:call_done_update_hooks(done_update_plugins)
endif
endif
endif endif
redraw redraw | echo ''
echo ''
call s:notify(strftime('Done: (%Y/%m/%d %H:%M:%S)')) call s:notify(strftime('Done: (%Y/%m/%d %H:%M:%S)'))
@ -1090,6 +1210,17 @@ function! s:done(context) abort
unlet s:timer unlet s:timer
endif endif
endfunction endfunction
function! s:call_done_update_hooks(plugins) abort
let cwd = getcwd()
try
for plugin in a:plugins
call dein#install#_cd(plugin.path)
call dein#call_hook('done_update', plugin)
endfor
finally
call dein#install#_cd(cwd)
endtry
endfunction
function! s:sync(plugin, context) abort function! s:sync(plugin, context) abort
let a:context.number += 1 let a:context.number += 1
@ -1204,6 +1335,8 @@ function! s:init_job(process, context, cmd) abort
let candidates[-1] .= a:data[0] let candidates[-1] .= a:data[0]
endif endif
call s:print_progress_message(candidates[-1])
let candidates += a:data[1:] let candidates += a:data[1:]
endfunction endfunction
@ -1221,12 +1354,9 @@ function! s:init_job(process, context, cmd) abort
let candidates = get(a:process.job, 'candidates', []) let candidates = get(a:process.job, 'candidates', [])
let output = join((self.eof ? candidates : candidates[: -2]), "\n") let output = join((self.eof ? candidates : candidates[: -2]), "\n")
if output !=# '' if output !=# '' && a:process.output !=# output
let a:process.output = output let a:process.output = output
let a:process.start_time = localtime() let a:process.start_time = localtime()
call s:log(s:get_short_message(
\ a:process.plugin, a:process.number,
\ a:process.max_plugins, output))
endif endif
let self.candidates = self.eof ? [] : candidates[-1:] let self.candidates = self.eof ? [] : candidates[-1:]
@ -1311,24 +1441,22 @@ function! s:check_output(context, process) abort
\ plugin, new_rev, a:process.rev), '\n') \ plugin, new_rev, a:process.rev), '\n')
let plugin.commit_count = len(log_messages) let plugin.commit_count = len(log_messages)
call s:log(map(log_messages, call s:log(map(log_messages,
\ 's:get_short_message(plugin, num, max, v:val)')) \ { _, val -> s:get_short_message(plugin, num, max, val) }))
let plugin.old_rev = a:process.rev let plugin.old_rev = a:process.rev
let plugin.new_rev = new_rev let plugin.new_rev = new_rev
" Execute "post_update" before "build"
if has_key(plugin, 'hook_post_update')
" To load plugin is needed to execute "post_update"
call dein#source(plugin.name)
call dein#call_hook('post_update', plugin)
endif
let type = dein#util#_get_type(plugin.type) let type = dein#util#_get_type(plugin.type)
let plugin.uri = has_key(type, 'get_uri') ? let plugin.uri = has_key(type, 'get_uri') ?
\ type.get_uri(plugin.repo, plugin) : '' \ type.get_uri(plugin.repo, plugin) : ''
let cwd = getcwd()
try
call dein#install#_cd(plugin.path)
call dein#call_hook('post_update', plugin)
finally
call dein#install#_cd(cwd)
endtry
if dein#install#_build([plugin.name]) if dein#install#_build([plugin.name])
call s:log(s:get_plugin_message(plugin, num, max, 'Build failed')) call s:log(s:get_plugin_message(plugin, num, max, 'Build failed'))
call s:error(plugin.path) call s:error(plugin.path)
@ -1348,7 +1476,7 @@ function! s:iconv(expr, from, to) abort
endif endif
if type(a:expr) == v:t_list if type(a:expr) == v:t_list
return map(copy(a:expr), 'iconv(v:val, a:from, a:to)') return map(copy(a:expr), { _, val -> iconv(val, a:from, a:to) })
else else
let result = iconv(a:expr, a:from, a:to) let result = iconv(a:expr, a:from, a:to)
return result !=# '' ? result : a:expr return result !=# '' ? result : a:expr
@ -1423,17 +1551,13 @@ function! s:append_log_file(msg) abort
let msg = readfile(logfile) + msg let msg = readfile(logfile) + msg
endif endif
let dir = fnamemodify(logfile, ':h') call dein#util#_safe_writefile(msg, logfile)
if !isdirectory(dir)
call mkdir(dir, 'p')
endif
call writefile(msg, logfile)
endfunction endfunction
function! s:echo(expr, mode) abort function! s:echo(expr, mode) abort
let msg = map(filter(dein#util#_convert2list(a:expr), "v:val !=# ''"), let msg = map(filter(dein#util#_convert2list(a:expr),
\ "'[dein] ' . v:val") \ { _, val -> val !=# '' }), { _, val -> '[dein] ' . val })
if empty(msg) if empty(msg)
return return
endif endif
@ -1519,36 +1643,3 @@ function! s:strwidthpart_reverse(str, width) abort
return ret return ret
endfunction endfunction
function! s:args2string(args) abort
return type(a:args) == v:t_string ? a:args :
\ dein#util#_is_windows() ?
\ dein#install#_args2string_windows(a:args) :
\ dein#install#_args2string_unix(a:args)
endfunction
function! dein#install#_args2string_windows(args) abort
if empty(a:args)
return ''
endif
let str = (a:args[0] =~# ' ') ? '"' . a:args[0] . '"' : a:args[0]
if len(a:args) > 1
let str .= ' '
let str .= join(map(copy(a:args[1:]), '''"'' . v:val . ''"'''))
endif
return str
endfunction
function! dein#install#_args2string_unix(args) abort
return join(map(copy(a:args), 'string(v:val)'))
endfunction
function! s:strptime_py(format, str) abort
let ret = ''
python3 << EOF
import datetime
import vim
vim.command('let ret = ' + str(datetime.datetime.strptime(
vim.eval('a:str'), vim.eval('a:format')).timestamp()))
EOF
return ret
endfunction

View File

@ -0,0 +1,94 @@
function! dein#min#_init() abort
let g:dein#name = ''
let g:dein#plugin = {}
let g:dein#_cache_version = 410
let g:dein#_plugins = {}
let g:dein#_multiple_plugins = []
let g:dein#_base_path = ''
let g:dein#_cache_path = ''
let g:dein#_runtime_path = ''
let g:dein#_hook_add = ''
let g:dein#_ftplugin = {}
let g:dein#_called_lua = {}
let g:dein#_off1 = ''
let g:dein#_off2 = ''
let g:dein#_vimrcs = []
let g:dein#_block_level = 0
let g:dein#_event_plugins = {}
let g:dein#_is_sudo = $SUDO_USER !=# '' && $USER !=# $SUDO_USER
\ && $HOME !=# expand('~'.$USER)
\ && $HOME ==# expand('~'.$SUDO_USER)
let g:dein#_progname = fnamemodify(v:progname, ':r')
let g:dein#_init_runtimepath = &runtimepath
let g:dein#_loaded_rplugins = v:false
if get(g:, 'dein#lazy_rplugins', v:false)
" Disable remote plugin loading
let g:loaded_remote_plugins = 1
endif
augroup dein
autocmd!
autocmd FuncUndefined *
\ if stridx(expand('<afile>'), 'remote#') != 0 |
\ call dein#autoload#_on_func(expand('<afile>')) |
\ endif
autocmd BufRead *? call dein#autoload#_on_default_event('BufRead')
autocmd BufNew,BufNewFile *? call dein#autoload#_on_default_event('BufNew')
autocmd VimEnter *? call dein#autoload#_on_default_event('VimEnter')
autocmd FileType *? call dein#autoload#_on_default_event('FileType')
autocmd BufWritePost *.lua,*.vim,*.toml,vimrc,.vimrc
\ call dein#util#_check_vimrcs()
augroup END
augroup dein-events | augroup END
if !exists('##CmdUndefined') | return | endif
autocmd dein CmdUndefined *
\ call dein#autoload#_on_pre_cmd(expand('<afile>'))
if has('nvim')
lua <<END
table.insert(package.loaders, 1, (function()
return function(mod_name)
if string.find(mod_name, '^vim.') == nil then
vim.fn['dein#autoload#_on_lua'](mod_name)
end
return nil
end
end)())
END
endif
endfunction
function! dein#min#_load_cache_raw(vimrcs) abort
let g:dein#_vimrcs = a:vimrcs
let cache = get(g:, 'dein#cache_directory', g:dein#_base_path)
\ .'/cache_' . g:dein#_progname
let time = getftime(cache)
if !empty(filter(map(copy(g:dein#_vimrcs),
\ { _, val -> getftime(expand(val)) }), { _, val -> time < val }))
return [{}, {}]
endif
return has('nvim') ? json_decode(readfile(cache))
\ : js_decode(readfile(cache)[0])
endfunction
function! dein#min#load_state(path, ...) abort
if !exists('#dein')
call dein#min#_init()
endif
let sourced = a:0 > 0 ? a:1 : has('vim_starting') &&
\ (!exists('&loadplugins') || &loadplugins)
if (g:dein#_is_sudo || !sourced) | return 1 | endif
let g:dein#_base_path = expand(a:path)
let state = get(g:, 'dein#cache_directory', g:dein#_base_path)
\ . '/state_' . g:dein#_progname . '.vim'
if !filereadable(state) | return 1 | endif
try
execute 'source' fnameescape(state)
catch
if v:exception !=# 'Cache loading error'
call dein#util#_error('Loading state error: ' . v:exception)
endif
call dein#clear_state()
return 1
endtry
endfunction

View File

@ -6,7 +6,7 @@
" Global options definition." " Global options definition."
let g:dein#enable_name_conversion = let g:dein#enable_name_conversion =
\ get(g:, 'dein#enable_name_conversion', 0) \ get(g:, 'dein#enable_name_conversion', v:false)
let g:dein#default_options = let g:dein#default_options =
\ get(g:, 'dein#default_options', {}) \ get(g:, 'dein#default_options', {})
@ -17,8 +17,8 @@ function! dein#parse#_add(repo, options, overwrite) abort
let plugin = dein#parse#_dict(dein#parse#_init(a:repo, a:options)) let plugin = dein#parse#_dict(dein#parse#_init(a:repo, a:options))
let plugin_check = get(g:dein#_plugins, plugin.name, {}) let plugin_check = get(g:dein#_plugins, plugin.name, {})
let overwrite = get(a:options, 'overwrite', a:overwrite) let overwrite = get(a:options, 'overwrite', a:overwrite)
if get(plugin_check, 'sourced', 0) || !get(plugin, 'if', 1) if get(plugin_check, 'sourced', 0)
" Skip already loaded or not enabled plugin. " Skip already loaded plugin.
return {} return {}
endif endif
@ -40,20 +40,20 @@ function! dein#parse#_add(repo, options, overwrite) abort
let plugin = dein#parse#_dict(dein#parse#_init(a:repo, options)) let plugin = dein#parse#_dict(dein#parse#_init(a:repo, options))
endif endif
let g:dein#_plugins[plugin.name] = plugin
if plugin.rtp !=# '' if plugin.rtp !=# ''
if plugin.lazy if plugin.lazy
call s:parse_lazy(plugin) call s:parse_lazy(plugin)
endif endif
if has_key(plugin, 'hook_add') if has_key(plugin, 'hook_add')
call dein#util#_execute_hook(plugin, plugin.hook_add) call dein#util#_call_hook('add', plugin)
endif endif
if has_key(plugin, 'ftplugin') if has_key(plugin, 'ftplugin')
call s:merge_ftplugin(plugin.ftplugin) call s:merge_ftplugin(plugin.ftplugin)
endif endif
endif endif
let g:dein#_plugins[plugin.name] = plugin
return plugin return plugin
endfunction endfunction
function! dein#parse#_init(repo, options) abort function! dein#parse#_init(repo, options) abort
@ -88,7 +88,7 @@ function! dein#parse#_dict(plugin) abort
if !has_key(plugin, 'normalized_name') if !has_key(plugin, 'normalized_name')
let plugin.normalized_name = substitute( let plugin.normalized_name = substitute(
\ fnamemodify(plugin.name, ':r'), \ fnamemodify(plugin.name, ':r'),
\ '\c^n\?vim[_-]\|[_-]n\?vim$', '', 'g') \ '\c^\%(n\?vim\|dps\)[_-]\|[_-]n\?vim$', '', 'g')
endif endif
if !has_key(a:plugin, 'name') && g:dein#enable_name_conversion if !has_key(a:plugin, 'name') && g:dein#enable_name_conversion
@ -131,16 +131,15 @@ function! dein#parse#_dict(plugin) abort
endif endif
" Deprecated check. " Deprecated check.
for key in filter(['directory', 'base'], 'has_key(plugin, v:val)') for key in filter(['directory', 'base'],
\ { _, val -> has_key(plugin, val) })
call dein#util#_error('plugin name = ' . plugin.name) call dein#util#_error('plugin name = ' . plugin.name)
call dein#util#_error(string(key) . ' is deprecated.') call dein#util#_error(string(key) . ' is deprecated.')
endfor endfor
if !has_key(plugin, 'lazy') if !has_key(plugin, 'lazy')
let plugin.lazy = let plugin.lazy =
\ has_key(plugin, 'on_i') \ has_key(plugin, 'on_ft')
\ || has_key(plugin, 'on_idle')
\ || has_key(plugin, 'on_ft')
\ || has_key(plugin, 'on_cmd') \ || has_key(plugin, 'on_cmd')
\ || has_key(plugin, 'on_func') \ || has_key(plugin, 'on_func')
\ || has_key(plugin, 'on_lua') \ || has_key(plugin, 'on_lua')
@ -161,17 +160,13 @@ function! dein#parse#_dict(plugin) abort
\ && stridx(plugin.rtp, dein#util#_get_base_path()) == 0 \ && stridx(plugin.rtp, dein#util#_get_base_path()) == 0
endif endif
if has_key(plugin, 'if') && type(plugin.if) == v:t_string
let plugin.if = eval(a:plugin.if)
endif
" Hooks " Hooks
for hook in filter([ for hook in filter([
\ 'hook_add', 'hook_source', \ 'hook_add', 'hook_source',
\ 'hook_post_source', 'hook_post_update', \ 'hook_post_source', 'hook_post_update',
\ ], 'has_key(plugin, v:val) && type(plugin[v:val]) == v:t_string') \ ], { _, val -> has_key(plugin, val)
let plugin[hook] = substitute(plugin[hook], \ && type(plugin[val]) == v:t_string })
\ '\n\s*\\\|\%(^\|\n\)\s*"[^\n]*', '', 'g') let plugin[hook] = substitute(plugin[hook], '\n\s*\\', '', 'g')
endfor endfor
return plugin return plugin
@ -191,13 +186,22 @@ function! dein#parse#_load_toml(filename, default) abort
" Parse. " Parse.
if has_key(toml, 'hook_add') if has_key(toml, 'hook_add')
let pattern = '\n\s*\\\|\%(^\|\n\)\s*"[^\n]*'
let g:dein#_hook_add .= "\n" . substitute( let g:dein#_hook_add .= "\n" . substitute(
\ toml.hook_add, pattern, '', 'g') \ toml.hook_add, '\n\s*\\', '', 'g')
endif endif
if has_key(toml, 'ftplugin') if has_key(toml, 'ftplugin')
call s:merge_ftplugin(toml.ftplugin) call s:merge_ftplugin(toml.ftplugin)
endif endif
if has_key(toml, 'multiple_plugins')
for multi in toml.multiple_plugins
if !has_key(multi, 'plugins')
call dein#util#_error('Invalid multiple_plugins: ' . a:filename)
return 1
endif
call add(g:dein#_multiple_plugins, multi)
endfor
endif
if has_key(toml, 'plugins') if has_key(toml, 'plugins')
for plugin in toml.plugins for plugin in toml.plugins
@ -222,8 +226,6 @@ function! dein#parse#_plugins2toml(plugins) abort
let default.frozen = 0 let default.frozen = 0
let default.local = 0 let default.local = 0
let default.depends = [] let default.depends = []
let default.on_i = 0
let default.on_idle = 0
let default.on_ft = [] let default.on_ft = []
let default.on_cmd = [] let default.on_cmd = []
let default.on_func = [] let default.on_func = []
@ -246,14 +248,15 @@ function! dein#parse#_plugins2toml(plugins) abort
\ 'repo': 1, \ 'repo': 1,
\ } \ }
for plugin in dein#util#_sort_by(a:plugins, 'v:val.repo') for plugin in sort(a:plugins,
\ { a, b -> a.repo ==# b.repo ? 0 : a.repo ># b.repo ? 1 : -1 })
let toml += ['[[plugins]]', let toml += ['[[plugins]]',
\ 'repo = ' . string(plugin.repo)] \ 'repo = ' . string(plugin.repo)]
for key in filter(sort(keys(default)), for key in filter(sort(keys(default)),
\ '!has_key(skip_default, v:val) && has_key(plugin, v:val) \ { _, val -> !has_key(skip_default, val) && has_key(plugin, val)
\ && (type(plugin[v:val]) !=# type(default[v:val]) \ && (type(plugin[val]) !=# type(default[val])
\ || plugin[v:val] !=# default[v:val])') \ || plugin[val] !=# default[val]) })
let val = plugin[key] let val = plugin[key]
if key =~# '^hook_' if key =~# '^hook_'
call add(toml, key . " = '''") call add(toml, key . " = '''")
@ -280,10 +283,10 @@ function! dein#parse#_local(localdir, options, includes) abort
let base = fnamemodify(dein#util#_expand(a:localdir), ':p') let base = fnamemodify(dein#util#_expand(a:localdir), ':p')
let directories = [] let directories = []
for glob in a:includes for glob in a:includes
let directories += map(filter(dein#util#_globlist(base . glob), let directories += map(filter(glob(base . glob, v:true, v:true),
\ 'isdirectory(v:val)'), " \ { _, val -> isdirectory(val) }),
\ substitute(dein#util#_substitute_path( \ { _, val -> substitute(dein#util#_substitute_path(
\ fnamemodify(v:val, ':p')), '/$', '', '')") \ fnamemodify(val, ':p')), '/$', '', '') })
endfor endfor
for dir in dein#util#_uniq(directories) for dir in dein#util#_uniq(directories)
@ -304,19 +307,12 @@ function! s:parse_lazy(plugin) abort
for key in filter([ for key in filter([
\ 'on_ft', 'on_path', 'on_cmd', 'on_func', 'on_map', \ 'on_ft', 'on_path', 'on_cmd', 'on_func', 'on_map',
\ 'on_lua', 'on_source', 'on_event', \ 'on_lua', 'on_source', 'on_event',
\ ], 'has_key(a:plugin, v:val) \ ], { _, val -> has_key(a:plugin, val)
\ && type(a:plugin[v:val]) != v:t_list \ && type(a:plugin[val]) != v:t_list
\ && type(a:plugin[v:val]) != v:t_dict \ && type(a:plugin[val]) != v:t_dict })
\')
let a:plugin[key] = [a:plugin[key]] let a:plugin[key] = [a:plugin[key]]
endfor endfor
if get(a:plugin, 'on_i', 0)
let a:plugin.on_event = ['InsertEnter']
endif
if get(a:plugin, 'on_idle', 0)
let a:plugin.on_event = ['FocusLost', 'CursorHold']
endif
if has_key(a:plugin, 'on_event') if has_key(a:plugin, 'on_event')
for event in a:plugin.on_event for event in a:plugin.on_event
if !has_key(g:dein#_event_plugins, event) if !has_key(g:dein#_event_plugins, event)
@ -355,11 +351,11 @@ function! s:generate_dummy_mappings(plugin) abort
let a:plugin.dummy_mappings = [] let a:plugin.dummy_mappings = []
let items = type(a:plugin.on_map) == v:t_dict ? let items = type(a:plugin.on_map) == v:t_dict ?
\ map(items(a:plugin.on_map), \ map(items(a:plugin.on_map),
\ "[split(v:val[0], '\\zs'), dein#util#_convert2list(v:val[1])]") : \ { _, val -> [split(val[0], '\zs'),
\ dein#util#_convert2list(val[1])]}) :
\ map(copy(a:plugin.on_map), \ map(copy(a:plugin.on_map),
\ "type(v:val) == v:t_list ? \ { _, val -> type(val) == v:t_list ?
\ [split(v:val[0], '\\zs'), v:val[1:]] : \ [split(val[0], '\zs'), val[1:]] : [['n', 'x'], [val]] })
\ [['n', 'x'], [v:val]]")
for [modes, mappings] in items for [modes, mappings] in items
if mappings ==# ['<Plug>'] if mappings ==# ['<Plug>']
" Use plugin name. " Use plugin name.
@ -378,9 +374,9 @@ function! s:generate_dummy_mappings(plugin) abort
\ string(a:plugin.name)) \ string(a:plugin.name))
for mode in modes for mode in modes
let raw_map = mode.'noremap <unique><silent> '.mapping let raw_map = mode.'noremap <unique><silent> '.mapping
\ . (mode ==# 'c' ? " \<C-r>=" : \ . (mode ==# 'c' ? " \<C-r>=" :
\ mode ==# 'i' ? " \<C-o>:call " : " :\<C-u>call ") . prefix \ mode ==# 'i' ? " \<C-o>:call " : " :\<C-u>call ")
\ . string(mode) . ')<CR>' \ . prefix . string(mode) . ')<CR>'
call add(a:plugin.dummy_mappings, [mode, mapping, raw_map]) call add(a:plugin.dummy_mappings, [mode, mapping, raw_map])
silent! execute raw_map silent! execute raw_map
endfor endfor
@ -396,17 +392,17 @@ function! s:merge_ftplugin(ftplugin) abort
let g:dein#_ftplugin[ft] .= "\n" . val let g:dein#_ftplugin[ft] .= "\n" . val
endif endif
endfor endfor
call map(g:dein#_ftplugin, "substitute(v:val, pattern, '', 'g')") call map(g:dein#_ftplugin, { _, val -> substitute(val, pattern, '', 'g') })
endfunction endfunction
function! dein#parse#_get_types() abort function! dein#parse#_get_types() abort
if !exists('s:types') if !exists('s:types')
" Load types. " Load types.
let s:types = {} let s:types = {}
for type in filter(map(split(globpath(&runtimepath, for type in filter(map(globpath(&runtimepath,
\ 'autoload/dein/types/*.vim', 1), '\n'), \ 'autoload/dein/types/*.vim', v:true, v:true),
\ "dein#types#{fnamemodify(v:val, ':t:r')}#define()"), \ { _, val -> dein#types#{fnamemodify(val, ':t:r')}#define() }),
\ '!empty(v:val)') \ { _, val -> !empty(val) })
let s:types[type.name] = type let s:types[type.name] = type
endfor endfor
endif endif

View File

@ -3,6 +3,27 @@
" "
" public api " public api
" "
function! dein#toml#syntax() abort
if has('nvim') && exists(':TSEnableAll')
TSBufDisable highlight
endif
syntax clear
unlet! b:current_syntax
runtime! syntax/toml.vim
unlet! b:current_syntax
syntax include @tomlVim syntax/vim.vim
syntax region tomlVim matchgroup=tomlString
\ start=+\<\w*\s*=\s*'''+
\ end=+'''+ contains=@tomlVim keepend
syntax region tomlVim matchgroup=tomlString
\ start=+\<\w*\s*=\s*"""+
\ end=+"""+ contains=@tomlVim keepend
endfunction
function! dein#toml#parse(text) abort function! dein#toml#parse(text) abort
let input = { let input = {
\ 'text': a:text, \ 'text': a:text,

View File

@ -6,12 +6,14 @@
"============================================================================= "=============================================================================
" Global options definition. " Global options definition.
call dein#util#_set_default(
\ 'g:dein#types#git#clone_depth', 0)
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#types#git#command_path', 'git') \ 'g:dein#types#git#command_path', 'git')
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#types#git#default_protocol', 'https') \ 'g:dein#types#git#default_hub_site', 'github.com')
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#types#git#clone_depth', 0) \ 'g:dein#types#git#default_protocol', 'https')
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#types#git#pull_command', 'pull --ff --ff-only') \ 'g:dein#types#git#pull_command', 'pull --ff --ff-only')
@ -69,7 +71,7 @@ function! s:type.get_uri(repo, options) abort
\ ':.*$', '', '') \ ':.*$', '', '')
endif endif
if host ==# '' if host ==# ''
let host = 'github.com' let host = g:dein#types#git#default_hub_site
endif endif
if protocol ==# '' if protocol ==# ''
@ -199,6 +201,14 @@ function! s:type.get_rollback_command(plugin, rev) abort
return [self.command, 'reset', '--hard', a:rev] return [self.command, 'reset', '--hard', a:rev]
endfunction endfunction
function! s:type.get_diff_command(plugin, old_rev, new_rev) abort
if !self.executable
return []
endif
return [self.command, 'diff', a:old_rev . '..'. a:new_rev,
\ '--', 'doc', 'README', 'README.md']
endfunction
function! s:is_git_dir(path) abort function! s:is_git_dir(path) abort
if isdirectory(a:path) if isdirectory(a:path)

View File

@ -27,12 +27,8 @@ function! s:type.init(repo, options) abort
endfunction endfunction
function! s:type.get_sync_command(plugin) abort function! s:type.get_sync_command(plugin) abort
let path = a:plugin.path call dein#util#_safe_mkdir(a:plugin.path)
if !isdirectory(path)
" Create script type directory.
call mkdir(path, 'p')
endif
let outpath = path . '/' . fnamemodify(a:plugin.repo, ':t') let outpath = a:plugin.path . '/' . fnamemodify(a:plugin.repo, ':t')
return dein#util#_download(a:plugin.repo, outpath) return dein#util#_download(a:plugin.repo, outpath)
endfunction endfunction

View File

@ -37,9 +37,7 @@ function! dein#util#_get_runtime_path() abort
endif endif
let g:dein#_runtime_path = dein#util#_get_cache_path() . '/.dein' let g:dein#_runtime_path = dein#util#_get_cache_path() . '/.dein'
if !isdirectory(g:dein#_runtime_path) call dein#util#_safe_mkdir(g:dein#_runtime_path)
call mkdir(g:dein#_runtime_path, 'p')
endif
return g:dein#_runtime_path return g:dein#_runtime_path
endfunction endfunction
function! dein#util#_get_cache_path() abort function! dein#util#_get_cache_path() abort
@ -50,14 +48,12 @@ function! dein#util#_get_cache_path() abort
let g:dein#_cache_path = get(g:, let g:dein#_cache_path = get(g:,
\ 'dein#cache_directory', g:dein#_base_path) \ 'dein#cache_directory', g:dein#_base_path)
\ . '/.cache/' . fnamemodify(dein#util#_get_myvimrc(), ':t') \ . '/.cache/' . fnamemodify(dein#util#_get_myvimrc(), ':t')
if !isdirectory(g:dein#_cache_path) call dein#util#_safe_mkdir(g:dein#_cache_path)
call mkdir(g:dein#_cache_path, 'p')
endif
return g:dein#_cache_path return g:dein#_cache_path
endfunction endfunction
function! dein#util#_get_vimrcs(vimrcs) abort function! dein#util#_get_vimrcs(vimrcs) abort
return !empty(a:vimrcs) ? return !empty(a:vimrcs) ?
\ map(dein#util#_convert2list(a:vimrcs), 'expand(v:val)') : \ map(dein#util#_convert2list(a:vimrcs), { _, val -> expand(val) }) :
\ [dein#util#_get_myvimrc()] \ [dein#util#_get_myvimrc()]
endfunction endfunction
function! dein#util#_get_myvimrc() abort function! dein#util#_get_myvimrc() abort
@ -74,52 +70,63 @@ function! dein#util#_error(msg) abort
endfunction endfunction
function! dein#util#_notify(msg) abort function! dein#util#_notify(msg) abort
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#enable_notification', 0) \ 'g:dein#enable_notification', v:false)
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#notification_icon', '') \ 'g:dein#notification_icon', '')
call dein#util#_set_default( call dein#util#_set_default(
\ 'g:dein#notification_time', 2) \ 'g:dein#notification_time', 2)
if !g:dein#enable_notification || a:msg ==# '' || has('vim_starting') if !g:dein#enable_notification || a:msg ==# ''
call dein#util#_error(a:msg)
return
endif
let title = '[dein]'
if has('nvim') && dein#util#_luacheck('notify')
" Use nvim-notify plugin
call luaeval('require("notify")(_A.msg, "info", {'.
\ 'timeout=vim.g["dein#notification_time"] * 1000,'.
\ 'title=_A.title })',
\ { 'msg': a:msg, 'title': title })
return
endif
if has('vim_starting') && !has('gui_running')
call dein#util#_error(a:msg) call dein#util#_error(a:msg)
return return
endif endif
let icon = dein#util#_expand(g:dein#notification_icon) let icon = dein#util#_expand(g:dein#notification_icon)
let title = '[dein]' let cmd = []
let cmd = ''
if executable('notify-send') if executable('notify-send')
let cmd = printf('notify-send --expire-time=%d', let cmd = ['notify-send', '-t', g:dein#notification_time * 1000]
\ g:dein#notification_time * 1000)
if icon !=# '' if icon !=# ''
let cmd .= ' --icon=' . string(icon) let cmd += ['-i', icon]
endif
let cmd .= ' ' . string(title) . ' ' . string(a:msg)
elseif dein#util#_is_windows() && executable('Snarl_CMD')
let cmd = printf('Snarl_CMD snShowMessage %d "%s" "%s"',
\ g:dein#notification_time, title, a:msg)
if icon !=# ''
let cmd .= ' "' . icon . '"'
endif endif
let cmd += [title, a:msg]
elseif dein#util#_is_mac() elseif dein#util#_is_mac()
let cmd = '' let cmd = []
if executable('terminal-notifier') if executable('terminal-notifier')
let cmd .= 'terminal-notifier -title ' let cmd += ['terminal-notifier', '-title', 'title', '-message', a:msg]
\ . string(title) . ' -message ' . string(a:msg)
if icon !=# '' if icon !=# ''
let cmd .= ' -appIcon ' . string(icon) let cmd += ['-appIcon', icon]
endif endif
else else
let cmd .= printf("osascript -e 'display notification " let cmd += ['osascript', '-e', 'display notification '
\ ."\"%s\" with title \"%s\"'", a:msg, title) \ . printf('"%s" with title "%s"', a:msg, title)]
endif endif
endif endif
if cmd !=# '' if !empty(cmd)
call dein#install#_system(cmd) call dein#install#_system_bg(cmd)
endif endif
endfunction endfunction
function! dein#util#_luacheck(module) abort
return luaeval('pcall(require, _A.module)', { 'module': a:module })
endfunction
function! dein#util#_chomp(str) abort function! dein#util#_chomp(str) abort
return a:str !=# '' && a:str[-1:] ==# '/' ? a:str[: -2] : a:str return a:str !=# '' && a:str[-1:] ==# '/' ? a:str[: -2] : a:str
@ -149,42 +156,49 @@ endfunction
function! dein#util#_is_powershell() abort function! dein#util#_is_powershell() abort
return dein#install#_is_async() && fnamemodify(&shell, ':t:r') =~? 'powershell\|pwsh' return dein#install#_is_async() && fnamemodify(&shell, ':t:r') =~? 'powershell\|pwsh'
endfunction endfunction
function! dein#util#_has_job() abort
return (has('nvim') && exists('v:t_list'))
\ || (has('patch-8.0.0027') && has('job'))
endfunction
function! dein#util#_check_lazy_plugins() abort function! dein#util#_check_lazy_plugins() abort
return map(filter(dein#util#_get_lazy_plugins(), return map(filter(dein#util#_get_lazy_plugins(), { _, val ->
\ "isdirectory(v:val.rtp) \ isdirectory(val.rtp)
\ && !get(v:val, 'local', 0) \ && !get(val, 'local', 0)
\ && get(v:val, 'hook_source', '') ==# '' \ && get(val, 'hook_source', '') ==# ''
\ && get(v:val, 'hook_add', '') ==# '' \ && get(val, 'hook_add', '') ==# ''
\ && !isdirectory(v:val.rtp . '/plugin') \ && !isdirectory(val.rtp . '/plugin')
\ && !isdirectory(v:val.rtp . '/after/plugin')"), \ && !isdirectory(val.rtp . '/after/plugin')
\ 'v:val.name') \ }), { _, val -> val.name })
endfunction endfunction
function! dein#util#_check_clean() abort function! dein#util#_check_clean() abort
let plugins_directories = map(values(dein#get()), 'v:val.path') let plugins_directories = map(values(dein#get()), { _, val -> val.path })
let path = dein#util#_substitute_path( let path = dein#util#_substitute_path(
\ globpath(dein#util#_get_base_path(), 'repos/*/*/*')) \ globpath(dein#util#_get_base_path(), 'repos/*/*/*', v:true))
return filter(split(path, "\n"), return filter(split(path, "\n"),
\ "isdirectory(v:val) && fnamemodify(v:val, ':t') !=# 'dein.vim' \ { _, val -> isdirectory(val)
\ && index(plugins_directories, v:val) < 0") \ && fnamemodify(val, ':t') !=# 'dein.vim'
\ && index(plugins_directories, val) < 0
\ })
endfunction endfunction
function! dein#util#_writefile(path, list) abort function! dein#util#_cache_writefile(list, path) abort
if g:dein#_is_sudo || !filewritable(dein#util#_get_cache_path()) if !filewritable(dein#util#_get_cache_path())
return 1 return 1
endif endif
let path = dein#util#_get_cache_path() . '/' . a:path let path = dein#util#_get_cache_path() . '/' . a:path
let dir = fnamemodify(path, ':h') return dein#util#_safe_writefile(a:list, path)
if !isdirectory(dir) endfunction
call mkdir(dir, 'p') function! dein#util#_safe_writefile(list, path, ...) abort
if g:dein#_is_sudo
return 1
endif endif
return writefile(a:list, path) call dein#util#_safe_mkdir(fnamemodify(a:path, ':h'))
return writefile(a:list, a:path, get(a:000, 0, ''))
endfunction
function! dein#util#_safe_mkdir(path) abort
if g:dein#_is_sudo || isdirectory(a:path)
return 1
endif
return mkdir(a:path, 'p')
endfunction endfunction
function! dein#util#_get_type(name) abort function! dein#util#_get_type(name) abort
@ -206,30 +220,33 @@ function! dein#util#_save_cache(vimrcs, is_state, is_starting) abort
if has_key(plugin, 'orig_opts') if has_key(plugin, 'orig_opts')
call remove(plugin, 'orig_opts') call remove(plugin, 'orig_opts')
endif endif
if has_key(plugin, 'called')
call remove(plugin, 'called')
endif
" Hooks " Hooks
for hook in filter([ for hook in filter([
\ 'hook_add', 'hook_source', \ 'hook_add', 'hook_source',
\ 'hook_post_source', 'hook_post_update', \ 'hook_post_source', 'hook_post_update',
\ ], 'has_key(plugin, v:val) \ ], { _, val -> has_key(plugin, val)
\ && type(plugin[v:val]) == v:t_func') \ && type(plugin[val]) == v:t_func })
call remove(plugin, hook) call remove(plugin, hook)
endfor endfor
endfor endfor
if !isdirectory(g:dein#_base_path) call dein#util#_safe_mkdir(g:dein#_base_path)
call mkdir(g:dein#_base_path, 'p')
endif
call writefile([string(a:vimrcs), let src = [plugins, g:dein#_ftplugin]
\ json_encode(plugins), json_encode(g:dein#_ftplugin)], call dein#util#_safe_writefile(
\ has('nvim') ? [json_encode(src)] : [js_encode(src)],
\ get(g:, 'dein#cache_directory', g:dein#_base_path) \ get(g:, 'dein#cache_directory', g:dein#_base_path)
\ .'/cache_' . g:dein#_progname) \ .'/cache_' . g:dein#_progname)
endfunction endfunction
function! dein#util#_check_vimrcs() abort function! dein#util#_check_vimrcs() abort
let time = getftime(dein#util#_get_runtime_path()) let time = getftime(dein#util#_get_runtime_path())
let ret = !empty(filter(map(copy(g:dein#_vimrcs), 'getftime(expand(v:val))'), let ret = !empty(filter(map(copy(g:dein#_vimrcs),
\ 'time < v:val')) \ { _, val -> getftime(expand(val)) }),
\ { _, val -> time < val }))
if !ret if !ret
return 0 return 0
endif endif
@ -238,33 +255,6 @@ function! dein#util#_check_vimrcs() abort
return ret return ret
endfunction endfunction
function! dein#util#_load_merged_plugins() abort
let path = dein#util#_get_cache_path() . '/merged'
if !filereadable(path)
return []
endif
let merged = readfile(path)
if len(merged) != s:merged_length
return []
endif
sandbox return merged[: s:merged_length - 2] + eval(merged[-1])
endfunction
function! dein#util#_save_merged_plugins() abort
let merged = dein#util#_get_merged_plugins()
call writefile(merged[: s:merged_length - 2] +
\ [string(merged[s:merged_length - 1 :])],
\ dein#util#_get_cache_path() . '/merged')
endfunction
function! dein#util#_get_merged_plugins() abort
let ftplugin_len = 0
for ftplugin in values(g:dein#_ftplugin)
let ftplugin_len += len(ftplugin)
endfor
let merged_format =
\ "{'repo': v:val.repo, 'rev': get(v:val, 'rev', '')}"
return [merged_format, string(ftplugin_len)] +
\ sort(map(values(g:dein#_plugins), merged_format))
endfunction
function! dein#util#_save_state(is_starting) abort function! dein#util#_save_state(is_starting) abort
if g:dein#_block_level != 0 if g:dein#_block_level != 0
@ -272,12 +262,12 @@ function! dein#util#_save_state(is_starting) abort
return 1 return 1
endif endif
if dein#util#_get_cache_path() ==# '' || !a:is_starting if dein#util#_get_cache_path() ==# '' || !a:is_starting || g:dein#_is_sudo
" Ignore " Ignore
return 1 return 1
endif endif
if get(g:, 'dein#auto_recache', 0) if get(g:, 'dein#auto_recache', v:false)
call dein#util#_notify('auto recached') call dein#util#_notify('auto recached')
call dein#recache_runtimepath() call dein#recache_runtimepath()
endif endif
@ -294,7 +284,7 @@ function! dein#util#_save_state(is_starting) abort
\ 'if g:dein#_cache_version !=# ' . g:dein#_cache_version . ' || ' . \ 'if g:dein#_cache_version !=# ' . g:dein#_cache_version . ' || ' .
\ 'g:dein#_init_runtimepath !=# ' . string(g:dein#_init_runtimepath) . \ 'g:dein#_init_runtimepath !=# ' . string(g:dein#_init_runtimepath) .
\ ' | throw ''Cache loading error'' | endif', \ ' | throw ''Cache loading error'' | endif',
\ 'let [plugins, ftplugin] = dein#load_cache_raw('. \ 'let [plugins, ftplugin] = dein#min#_load_cache_raw('.
\ string(g:dein#_vimrcs) .')', \ string(g:dein#_vimrcs) .')',
\ "if empty(plugins) | throw 'Cache loading error' | endif", \ "if empty(plugins) | throw 'Cache loading error' | endif",
\ 'let g:dein#_plugins = plugins', \ 'let g:dein#_plugins = plugins',
@ -333,7 +323,8 @@ function! dein#util#_save_state(is_starting) abort
" Invalid hooks detection " Invalid hooks detection
for key in keys(filter(copy(plugin), for key in keys(filter(copy(plugin),
\ "stridx(v:key, 'hook_') == 0 && type(v:val) != v:t_string")) \ { key, val -> stridx(key, 'hook_') == 0
\ && type(val) != v:t_string }))
call dein#util#_error( call dein#util#_error(
\ printf('%s: "%s" must be string to save state', \ printf('%s: "%s" must be string to save state',
\ plugin.name, key)) \ plugin.name, key))
@ -342,7 +333,7 @@ function! dein#util#_save_state(is_starting) abort
" Add events " Add events
for [event, plugins] in filter(items(g:dein#_event_plugins), for [event, plugins] in filter(items(g:dein#_event_plugins),
\ "exists('##' . v:val[0])") \ { _, val -> exists('##' . val[0]) })
call add(lines, printf('autocmd dein-events %s call ' call add(lines, printf('autocmd dein-events %s call '
\. 'dein#autoload#_on_event("%s", %s)', \. 'dein#autoload#_on_event("%s", %s)',
\ (exists('##' . event) ? event . ' *' : 'User ' . event), \ (exists('##' . event) ? event . ' *' : 'User ' . event),
@ -351,28 +342,25 @@ function! dein#util#_save_state(is_starting) abort
" Add inline vimrcs " Add inline vimrcs
for vimrc in get(g:, 'dein#inline_vimrcs', []) for vimrc in get(g:, 'dein#inline_vimrcs', [])
let lines += filter(readfile(vimrc), "v:val !=# '' && v:val !~# '^\\s*\"'") let lines += filter(readfile(vimrc),
\ { _, val -> val !=# '' && val !~# '^\s*"' })
endfor endfor
call writefile(lines, get(g:, 'dein#cache_directory', g:dein#_base_path) let state = get(g:, 'dein#cache_directory', g:dein#_base_path)
\ .'/state_' . g:dein#_progname . '.vim') \ . '/state_' . g:dein#_progname . '.vim'
call dein#util#_safe_writefile(lines, state)
endfunction endfunction
function! dein#util#_clear_state() abort function! dein#util#_clear_state() abort
let base = get(g:, 'dein#cache_directory', g:dein#_base_path) let base = get(g:, 'dein#cache_directory', g:dein#_base_path)
for cache in dein#util#_globlist(base.'/state_*.vim') for cache in glob(base.'/state_*.vim', v:true, v:true)
\ + dein#util#_globlist(base.'/cache_*') \ + glob(base.'/cache_*', v:true, v:true)
call delete(cache) call delete(cache)
endfor endfor
endfunction endfunction
function! dein#util#_begin(path, vimrcs) abort function! dein#util#_begin(path, vimrcs) abort
if !exists('#dein') if !exists('#dein')
call dein#_init() call dein#min#_init()
endif
if !dein#util#_has_job()
call dein#util#_error('Does not work in the Vim (' . v:version . ').')
return 1
endif endif
if a:path ==# '' || g:dein#_block_level != 0 if a:path ==# '' || g:dein#_block_level != 0
@ -388,6 +376,9 @@ function! dein#util#_begin(path, vimrcs) abort
call dein#util#_get_runtime_path() call dein#util#_get_runtime_path()
call dein#util#_get_cache_path() call dein#util#_get_cache_path()
let g:dein#_vimrcs = dein#util#_get_vimrcs(a:vimrcs) let g:dein#_vimrcs = dein#util#_get_vimrcs(a:vimrcs)
if exists('g:dein#inline_vimrcs')
let g:dein#_vimrcs += g:dein#inline_vimrcs
endif
let g:dein#_hook_add = '' let g:dein#_hook_add = ''
if has('vim_starting') if has('vim_starting')
@ -433,7 +424,7 @@ function! dein#util#_end() abort
if !has('vim_starting') if !has('vim_starting')
call dein#source(filter(values(g:dein#_plugins), call dein#source(filter(values(g:dein#_plugins),
\ "!v:val.lazy && !v:val.sourced && v:val.rtp !=# ''")) \ { _, val -> !val.lazy && !val.sourced && val.rtp !=# '' }))
endif endif
" Add runtimepath " Add runtimepath
@ -448,7 +439,10 @@ function! dein#util#_end() abort
let sourced = has('vim_starting') && let sourced = has('vim_starting') &&
\ (!exists('&loadplugins') || &loadplugins) \ (!exists('&loadplugins') || &loadplugins)
for plugin in filter(values(g:dein#_plugins), for plugin in filter(values(g:dein#_plugins),
\ "!v:val.lazy && !v:val.sourced && v:val.rtp !=# ''") \ { _, val -> !empty(val)
\ && !val.lazy && !val.sourced && val.rtp !=# ''
\ && (!has_key(v:val, 'if') || eval(v:val.if)) })
" Load dependencies " Load dependencies
if has_key(plugin, 'depends') if has_key(plugin, 'depends')
let depends += plugin.depends let depends += plugin.depends
@ -469,12 +463,20 @@ function! dein#util#_end() abort
call dein#source(depends) call dein#source(depends)
endif endif
for multi in filter(copy(g:dein#_multiple_plugins),
\ { _, val -> dein#is_available(val.plugins) })
if has_key(multi, 'hook_add')
let g:dein#_hook_add .= "\n" . substitute(
\ multi.hook_add, '\n\s*\\', '', 'g')
endif
endfor
if g:dein#_hook_add !=# '' if g:dein#_hook_add !=# ''
call dein#util#_execute_hook({}, g:dein#_hook_add) call dein#util#_execute_hook({}, g:dein#_hook_add)
endif endif
for [event, plugins] in filter(items(g:dein#_event_plugins), for [event, plugins] in filter(items(g:dein#_event_plugins),
\ "exists('##' . v:val[0])") \ { _, val -> exists('##' . val[0]) })
execute printf('autocmd dein-events %s call ' execute printf('autocmd dein-events %s call '
\. 'dein#autoload#_on_event("%s", %s)', \. 'dein#autoload#_on_event("%s", %s)',
\ (exists('##' . event) ? event . ' *' : 'User ' . event), \ (exists('##' . event) ? event . ' *' : 'User ' . event),
@ -508,17 +510,27 @@ endfunction
function! dein#util#_call_hook(hook_name, ...) abort function! dein#util#_call_hook(hook_name, ...) abort
let hook = 'hook_' . a:hook_name let hook = 'hook_' . a:hook_name
let plugins = filter(dein#util#_get_plugins((a:0 ? a:1 : [])), let plugins = filter(dein#util#_tsort(
\ "((a:hook_name !=# 'source' \ dein#util#_get_plugins((a:0 ? a:1 : []))),
\ && a:hook_name !=# 'post_source') || v:val.sourced) \ { _, val ->
\ && has_key(v:val, hook) && isdirectory(v:val.path)") \ ((a:hook_name !=# 'source'
\ && a:hook_name !=# 'post_source') || val.sourced)
for plugin in filter(dein#util#_tsort(plugins), \ && has_key(val, hook) && isdirectory(val.path)
\ 'has_key(v:val, hook)') \ && (!has_key(v:val, 'if') || eval(v:val.if))
\ })
for plugin in plugins
call dein#util#_execute_hook(plugin, plugin[hook]) call dein#util#_execute_hook(plugin, plugin[hook])
endfor endfor
endfunction endfunction
function! dein#util#_execute_hook(plugin, hook) abort function! dein#util#_execute_hook(plugin, hook) abort
" Skip twice call
if !has_key(a:plugin, 'called')
let a:plugin.called = {}
endif
if has_key(a:plugin.called, string(a:hook))
return
endif
try try
let g:dein#plugin = a:plugin let g:dein#plugin = a:plugin
@ -527,6 +539,8 @@ function! dein#util#_execute_hook(plugin, hook) abort
else else
call call(a:hook, []) call call(a:hook, [])
endif endif
let a:plugin.called[string(a:hook)] = v:true
catch catch
call dein#util#_error( call dein#util#_error(
\ 'Error occurred while executing hook: ' . \ 'Error occurred while executing hook: ' .
@ -547,16 +561,11 @@ function! dein#util#_set_hook(plugins, hook_name, hook) abort
\ type(a:hook) != v:t_string ? a:hook : \ type(a:hook) != v:t_string ? a:hook :
\ substitute(a:hook, '\n\s*\\\|\%(^\|\n\)\s*"[^\n]*', '', 'g') \ substitute(a:hook, '\n\s*\\\|\%(^\|\n\)\s*"[^\n]*', '', 'g')
if a:hook_name ==# 'hook_add' if a:hook_name ==# 'hook_add'
call dein#util#_execute_hook(plugin, plugin[a:hook_name]) call dein#util#_call_hook('add', plugin)
endif endif
endfor endfor
endfunction endfunction
function! dein#util#_sort_by(list, expr) abort
let pairs = map(a:list, printf('[v:val, %s]', a:expr))
return map(s:sort(pairs,
\ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')
endfunction
function! dein#util#_tsort(plugins) abort function! dein#util#_tsort(plugins) abort
let sorted = [] let sorted = []
let mark = {} let mark = {}
@ -573,11 +582,12 @@ function! dein#util#_split_rtp(runtimepath) abort
endif endif
let split = split(a:runtimepath, '\\\@<!\%(\\\\\)*\zs,') let split = split(a:runtimepath, '\\\@<!\%(\\\\\)*\zs,')
return map(split,'substitute(v:val, ''\\\([\\,]\)'', ''\1'', ''g'')') return map(split, { _, val -> substitute(val, '\\\([\\,]\)', '\1', 'g') })
endfunction endfunction
function! dein#util#_join_rtp(list, runtimepath, rtp) abort function! dein#util#_join_rtp(list, runtimepath, rtp) abort
return (stridx(a:runtimepath, '\,') < 0 && stridx(a:rtp, ',') < 0) ? return (stridx(a:runtimepath, '\,') < 0 && stridx(a:rtp, ',') < 0) ?
\ join(a:list, ',') : join(map(copy(a:list), 's:escape(v:val)'), ',') \ join(a:list, ',') : join(map(copy(a:list),
\ { _, val -> s:escape(val) }), ',')
endfunction endfunction
function! dein#util#_add_after(rtps, path) abort function! dein#util#_add_after(rtps, path) abort
@ -597,9 +607,6 @@ function! dein#util#_substitute_path(path) abort
return ((s:is_windows || has('win32unix')) && a:path =~# '\\') ? return ((s:is_windows || has('win32unix')) && a:path =~# '\\') ?
\ tr(a:path, '\', '/') : a:path \ tr(a:path, '\', '/') : a:path
endfunction endfunction
function! dein#util#_globlist(path) abort
return split(glob(a:path), '\n')
endfunction
function! dein#util#_convert2list(expr) abort function! dein#util#_convert2list(expr) abort
return type(a:expr) ==# v:t_list ? copy(a:expr) : return type(a:expr) ==# v:t_list ? copy(a:expr) :
@ -628,21 +635,22 @@ endfunction
function! dein#util#_get_lazy_plugins() abort function! dein#util#_get_lazy_plugins() abort
return filter(values(g:dein#_plugins), return filter(values(g:dein#_plugins),
\ "!v:val.sourced && v:val.rtp !=# ''") \ { _, val -> !val.sourced && val.rtp !=# '' })
endfunction endfunction
function! dein#util#_get_plugins(plugins) abort function! dein#util#_get_plugins(plugins) abort
return empty(a:plugins) ? return empty(a:plugins) ?
\ values(dein#get()) : \ values(dein#get()) :
\ filter(map(dein#util#_convert2list(a:plugins), \ filter(map(dein#util#_convert2list(a:plugins),
\ 'type(v:val) == v:t_dict ? v:val : dein#get(v:val)'), \ { _, val -> type(val) == v:t_dict ? val : dein#get(val) }),
\ '!empty(v:val)') \ { _, val -> !empty(val) })
endfunction endfunction
function! dein#util#_disable(names) abort function! dein#util#_disable(names) abort
for plugin in map(filter(dein#util#_convert2list(a:names), for plugin in map(filter(dein#util#_convert2list(a:names),
\ 'has_key(g:dein#_plugins, v:val) \ { _, val ->
\ && !g:dein#_plugins[v:val].sourced'), 'g:dein#_plugins[v:val]') \ has_key(g:dein#_plugins, val) && !g:dein#_plugins[val].sourced
\ }), { _, val -> g:dein#_plugins[val]})
if has_key(plugin, 'dummy_commands') if has_key(plugin, 'dummy_commands')
for command in plugin.dummy_commands for command in plugin.dummy_commands
silent! execute 'delcommand' command[0] silent! execute 'delcommand' command[0]
@ -699,21 +707,25 @@ function! s:tsort_impl(target, mark, sorted) abort
endfunction endfunction
function! dein#util#_check_install(plugins) abort function! dein#util#_check_install(plugins) abort
if g:dein#_is_sudo
return
endif
if !empty(a:plugins) if !empty(a:plugins)
let invalids = filter(dein#util#_convert2list(a:plugins), let invalids = filter(dein#util#_convert2list(a:plugins),
\ 'empty(dein#get(v:val))') \ { _, val -> empty(dein#get(val)) })
if !empty(invalids) if !empty(invalids)
call dein#util#_error('Invalid plugins: ' . call dein#util#_error('Invalid plugins: ' . string(invalids))
\ string(map(invalids, 'v:val')))
return -1 return -1
endif endif
endif endif
let plugins = empty(a:plugins) ? values(dein#get()) : let plugins = empty(a:plugins) ? values(dein#get()) :
\ map(dein#util#_convert2list(a:plugins), 'dein#get(v:val)') \ map(dein#util#_convert2list(a:plugins),
let plugins = filter(plugins, '!isdirectory(v:val.path)') \ { _, val -> dein#get(val) })
let plugins = filter(plugins, { _, val -> !isdirectory(val.path) })
if empty(plugins) | return 0 | endif if empty(plugins) | return 0 | endif
call dein#util#_notify('Not installed plugins: ' . call dein#util#_notify('Not installed plugins: ' .
\ string(map(plugins, 'v:val.name'))) \ string(map(plugins, { _, val -> val.name })))
return 1 return 1
endfunction endfunction
@ -721,7 +733,7 @@ function! s:msg2list(expr) abort
return type(a:expr) ==# v:t_list ? a:expr : split(a:expr, '\n') return type(a:expr) ==# v:t_list ? a:expr : split(a:expr, '\n')
endfunction endfunction
function! s:skipempty(string) abort function! s:skipempty(string) abort
return filter(split(a:string, '\n'), "v:val !=# ''") return filter(split(a:string, '\n'), { _, val -> val !=# '' })
endfunction endfunction
function! s:escape(path) abort function! s:escape(path) abort
@ -729,17 +741,6 @@ function! s:escape(path) abort
return substitute(a:path, ',\|\\,\@=', '\\\0', 'g') return substitute(a:path, ',\|\\,\@=', '\\\0', 'g')
endfunction endfunction
function! s:sort(list, expr) abort
if type(a:expr) == v:t_func
return sort(a:list, a:expr)
endif
let s:expr = a:expr
return sort(a:list, 's:_compare')
endfunction
function! s:_compare(a, b) abort
return eval(s:expr)
endfunction
function! s:execute(expr) abort function! s:execute(expr) abort
if exists('*execute') if exists('*execute')
return execute(split(a:expr, '\n'), '') return execute(split(a:expr, '\n'), '')

View File

@ -22,13 +22,13 @@ let s:kind.action_table.preview = {
\ } \ }
function! s:kind.action_table.preview.func(candidate) abort function! s:kind.action_table.preview.func(candidate) abort
" Search help files. " Search help files.
let readme = get(split(globpath( let readme = get(globpath(a:candidate.action__path, 'doc/*.?*',
\ a:candidate.action__path, 'doc/*.?*', 1), '\n'), 0, '') \ v:true, v:true), 0, '')
if readme ==# '' if readme ==# ''
" Search README files. " Search README files.
let readme = get(split(globpath( let readme = get(globpath(a:candidate.action__path, 'README*',
\ a:candidate.action__path, 'README*', 1), '\n'), 0, '') \ v:true, v:true), 0, '')
if readme ==# '' if readme ==# ''
return return
endif endif

View File

@ -43,22 +43,22 @@ let s:source.converters = s:source.source__converter
function! s:source.gather_candidates(args, context) abort function! s:source.gather_candidates(args, context) abort
let _ = map(copy(a:context.source__plugins), "{ let _ = map(copy(a:context.source__plugins), { _, val -> {
\ 'word': substitute(v:val.repo, \ 'word': substitute(val.repo,
\ '^\%(https\?\|git\)://\%(github.com/\)\?', '', ''), \ '^\%(https\?\|git\)://\%(github.com/\)\?', '', ''),
\ 'kind': 'dein', \ 'kind': 'dein',
\ 'action__path': v:val.path, \ 'action__path': val.path,
\ 'action__directory': v:val.path, \ 'action__directory': val.path,
\ 'action__plugin': v:val, \ 'action__plugin': val,
\ 'action__plugin_name': v:val.name, \ 'action__plugin_name': val.name,
\ 'source__type': v:val.type, \ 'source__type': val.type,
\ 'source__is_sourced': v:val.sourced, \ 'source__is_sourced': val.sourced,
\ 'source__is_installed': isdirectory(v:val.path), \ 'source__is_installed': isdirectory(val.path),
\ 'is_multiline': 1, \ 'is_multiline': 1,
\ } \ }
\") \ } )
let max = max(map(copy(_), 'len(v:val.word)')) let max = max(map(copy(_), { _, val -> len(val.word) }))
call unite#print_source_message( call unite#print_source_message(
\ '#: not sourced, X: not installed', self.name) \ '#: not sourced, X: not installed', self.name)
@ -85,24 +85,10 @@ function! s:get_commit_status(plugin) abort
return 'Not installed' return 'Not installed'
endif endif
let type = dein#types#git#define() let type = dein#util#_get_type(a:plugin.type)
let cmd = type.get_revision_number_command(a:plugin) if !has_key(type, 'get_revision_number')
if cmd ==# ''
return '' return ''
endif endif
let cwd = getcwd() return type.get_revision_number(a:plugin)
try
call dein#install#_cd(a:plugin.path)
let output = dein#install#_system(cmd)
finally
call dein#install#_cd(cwd)
endtry
if dein#install#_get_last_status()
return printf('Error(%d) occurred when executing "%s"',
\ dein#install#_get_last_status(), cmd)
endif
return output
endfunction endfunction

View File

@ -43,11 +43,11 @@ function! s:source.async_gather_candidates(args, context) abort
let log = a:context.source__is_bang ? let log = a:context.source__is_bang ?
\ dein#install#_get_updates_log() \ dein#install#_get_updates_log()
\ : dein#install#_get_log() \ : dein#install#_get_log()
let candidates = map(copy(log[len(a:context.source__log):]), "{ let candidates = map(copy(log[len(a:context.source__log):]), { _, val -> {
\ 'word' : (v:val =~# '^\\s*\\h\\w*://' ? ' -> diff URI' : v:val), \ 'word' : (val =~# '^\s*\h\w*://' ? ' -> diff URI' : val),
\ 'kind' : (v:val =~# '^\\s*\\h\\w*://' ? 'uri' : 'word'), \ 'kind' : (val =~# '^\s*\h\w*://' ? 'uri' : 'word'),
\ 'action__uri' : substitute(v:val, '^\\s\\+', '', ''), \ 'action__uri' : substitute(val, '^\s\+', '', ''),
\ }") \ } })
let a:context.source__log = copy(log) let a:context.source__log = copy(log)
return candidates return candidates
endfunction endfunction

View File

@ -14,7 +14,10 @@ endfunction
function! s:start(args, options) abort function! s:start(args, options) abort
let job = extend(copy(s:job), a:options) let job = extend(copy(s:job), a:options)
let job_options = {} let job_options = {
\ 'stderr_buffered': v:false,
\ 'stdout_buffered': v:false
\ }
if has_key(a:options, 'cwd') if has_key(a:options, 'cwd')
let job_options.cwd = a:options.cwd let job_options.cwd = a:options.cwd
endif endif

View File

@ -118,12 +118,12 @@ function! s:_self_vital_files() abort
let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name) let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name)
let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name) let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name)
let base = builtin . ',' . installed let base = builtin . ',' . installed
return split(globpath(base, '**/*.vim', 1), "\n") return globpath(base, '**/*.vim', v:true, v:true)
endfunction endfunction
function! s:_global_vital_files() abort function! s:_global_vital_files() abort
let pattern = 'autoload/vital/__*__/**/*.vim' let pattern = 'autoload/vital/__*__/**/*.vim'
return split(globpath(&runtimepath, pattern, 1), "\n") return globpath(&runtimepath, pattern, v:true, v:true)
endfunction endfunction
function! s:_extract_files(pattern, files) abort function! s:_extract_files(pattern, files) abort

View File

@ -37,21 +37,18 @@ Write-Output "`" Required:"
Write-Output "set runtimepath+=$InstallDir" Write-Output "set runtimepath+=$InstallDir"
Write-Output "" Write-Output ""
Write-Output "`" Required:" Write-Output "`" Required:"
Write-Output "if dein#load_state('$PluginDir')" Write-Output "call dein#begin('$PluginDir')"
Write-Output " call dein#begin('$PluginDir')"
Write-Output "" Write-Output ""
Write-Output " `" Let dein manage dein" Write-Output "`" Let dein manage dein"
Write-Output " `" Required:" Write-Output "`" Required:"
Write-Output " call dein#add('$InstallDir')" Write-Output "call dein#add('$InstallDir')"
Write-Output "" Write-Output ""
Write-Output " `" Add or remove your plugins here like this:" Write-Output "`" Add or remove your plugins here like this:"
Write-Output " `"call dein#add('Shougo/neosnippet.vim')" Write-Output "`"call dein#add('Shougo/neosnippet.vim')"
Write-Output " `"call dein#add('Shougo/neosnippet-snippets')" Write-Output "`"call dein#add('Shougo/neosnippet-snippets')"
Write-Output "" Write-Output ""
Write-Output " `" Required:" Write-Output "`" Required:"
Write-Output " call dein#end()" Write-Output "call dein#end()"
Write-Output " call dein#save_state()"
Write-Output "endif"
Write-Output "" Write-Output ""
Write-Output "`" Required:" Write-Output "`" Required:"
Write-Output "filetype plugin indent on" Write-Output "filetype plugin indent on"

View File

@ -3,6 +3,8 @@
# Original version is created by shoma2da # Original version is created by shoma2da
# https://github.com/shoma2da/neobundle_installer # https://github.com/shoma2da/neobundle_installer
set -e
if [ $# -ne 1 ]; then if [ $# -ne 1 ]; then
echo "You must specify the installation directory!" echo "You must specify the installation directory!"
exit 1 exit 1
@ -51,21 +53,18 @@ echo "Please add the following settings for dein to the top of your vimrc (Vim)
echo "set runtimepath+=$INSTALL_DIR" echo "set runtimepath+=$INSTALL_DIR"
echo "" echo ""
echo "\" Required:" echo "\" Required:"
echo "if dein#load_state('$PLUGIN_DIR')" echo "call dein#begin('$PLUGIN_DIR')"
echo " call dein#begin('$PLUGIN_DIR')"
echo "" echo ""
echo " \" Let dein manage dein" echo "\" Let dein manage dein"
echo " \" Required:" echo "\" Required:"
echo " call dein#add('$INSTALL_DIR')" echo "call dein#add('$INSTALL_DIR')"
echo "" echo ""
echo " \" Add or remove your plugins here like this:" echo "\" Add or remove your plugins here like this:"
echo " \"call dein#add('Shougo/neosnippet.vim')" echo "\"call dein#add('Shougo/neosnippet.vim')"
echo " \"call dein#add('Shougo/neosnippet-snippets')" echo "\"call dein#add('Shougo/neosnippet-snippets')"
echo "" echo ""
echo " \" Required:" echo "\" Required:"
echo " call dein#end()" echo "call dein#end()"
echo " call dein#save_state()"
echo "endif"
echo "" echo ""
echo "\" Required:" echo "\" Required:"
echo "filetype plugin indent on" echo "filetype plugin indent on"

View File

@ -1,6 +1,6 @@
*dein.txt* Dark powered Vim/Neovim plugin manager *dein.txt* Dark powered Vim/Neovim plugin manager
Version: 2.1 Version: 3.0
Author: Shougo <Shougo.Matsu at gmail.com> Author: Shougo <Shougo.Matsu at gmail.com>
License: MIT license License: MIT license
@ -18,6 +18,7 @@ Interface |dein-interface|
Unite Sources |dein-unite-sources| Unite Sources |dein-unite-sources|
Denite Sources |dein-denite-sources| Denite Sources |dein-denite-sources|
Configuration Examples |dein-examples| Configuration Examples |dein-examples|
Plugins merged feature |dein-merge|
FAQ |dein-faq| FAQ |dein-faq|
Compatibility |dein-compatibility| Compatibility |dein-compatibility|
@ -67,10 +68,11 @@ Note: The plugins are not updated automatically.
INSTALL *dein-install* INSTALL *dein-install*
Requirements: Requirements:
* Vim 8.0 or above or NeoVim. * Vim 8.2+ or NeoVim 0.5+.
* "git" command in $PATH (if you want to install github or vim.org plugins) * "git" command in $PATH (if you want to install github or vim.org plugins)
Note: If you use Vim 7.4, please use dein.vim ver.1.5 instead. Note: If you use below Vim 8.2 or neovim 0.5, please use dein.vim ver.2.2
instead.
First of all, git clone the repository. First of all, git clone the repository.
@ -180,7 +182,6 @@ dein#check_update([{force}[, {plugins}]])
|dein#check_install()|. |dein#check_install()|.
Note: You need to set |g:dein#install_github_api_token| to use Note: You need to set |g:dein#install_github_api_token| to use
the feature. the feature.
Note: |+python3| or |strptime()| is required.
Note: The update check is quick but it is not perfect Note: The update check is quick but it is not perfect
solution. If "git" command change ".git" directory status(for solution. If "git" command change ".git" directory status(for
example: "git reset"), it cannot detect the update properly. example: "git reset"), it cannot detect the update properly.
@ -230,6 +231,8 @@ dein#disable({plugins})
{plugins} is the plugins name list. {plugins} is the plugins name list.
Note: This command must be executed before dein loads Note: This command must be executed before dein loads
the plugins. the plugins.
Note: Disabled plugins are removed from dein's plugin list.
You cannot get disabled plugins from dein.
*dein#each()* *dein#each()*
dein#each({command}[, {plugins}]) dein#each({command}[, {plugins}])
@ -274,6 +277,10 @@ dein#install([{plugins}])
{plugins} is the plugins name list. {plugins} is the plugins name list.
If you omit it, dein will install all plugins. If you omit it, dein will install all plugins.
*dein#is_available()*
dein#is_available([{plugin-name}])
Return non-zero if {plugin-name} exists and is enabled.
*dein#is_sourced()* *dein#is_sourced()*
dein#is_sourced({plugin-name}) dein#is_sourced({plugin-name})
Return non-zero if {plugin-name} exists and is sourced. Return non-zero if {plugin-name} exists and is sourced.
@ -297,21 +304,22 @@ dein#load_rollback({rollbackfile}[, {plugins}])
Note: It is the dangerous command. Note: It is the dangerous command.
*dein#load_state()* *dein#load_state()*
*dein#min#load_state()*
dein#load_state({base-path}) dein#load_state({base-path})
Load dein's state from the cache script, dein#min#load_state({base-path})
which is located in `dein#util#_get_runtime_path() . '/state_' Load dein's state from the cache script, {base-path} is where
. fnamemodify(v:progname, ':r') . '.vim'`. your downloaded plugins will be placed.
{base-path} is where your downloaded plugins will be placed.
Note: You must call it before |dein#begin()|. It clears dein Note: You must call it before |dein#begin()|. It clears dein
all configuration. all configuration.
Note: It overwrites your 'runtimepath' completely, you must Note: It overwrites your 'runtimepath' completely, you must
not call it after change 'runtimepath' dynamically. not call it after change 'runtimepath' dynamically.
Note: The block is skipped if dein's state is loaded. Note: The block is skipped if dein's state is loaded.
Note: |dein#min#load_state()| is faster a bit.
It returns 1, if the cache script is old or invalid or not It returns 1, if the cache script is old or invalid or not
found. found.
> >
if dein#load_state(path) if dein#min#load_state(path)
call dein#begin(path) call dein#begin(path)
" My plugins here: " My plugins here:
" ... " ...
@ -354,6 +362,11 @@ dein#local({directory}, [{options}, [{names}]])
call dein#local("~/.vim/bundle", {}, call dein#local("~/.vim/bundle", {},
\ ['plugin1', 'plugin2', 'vim-*', '*.vim']) \ ['plugin1', 'plugin2', 'vim-*', '*.vim'])
< <
*dein#toml#syntax()*
dein#toml#syntax()
Enable dein specific toml syntax.
Note: It is experimental feature.
*dein#update()* *dein#update()*
dein#update([{plugins}]) dein#update([{plugins}])
Install/Update the plugins. Install/Update the plugins.
@ -425,6 +438,7 @@ dein#source([{plugins}])
|:source| the plugins specified by {plugins}. |:source| the plugins specified by {plugins}.
{plugins} is the plugins name list. {plugins} is the plugins name list.
If you omit it, dein will source all plugins. If you omit it, dein will source all plugins.
It returns sourced plugins list.
*dein#tap()* *dein#tap()*
dein#tap({plugin-name}) dein#tap({plugin-name})
@ -439,8 +453,9 @@ VARIABLES *dein-variables*
g:dein#auto_recache g:dein#auto_recache
If you set it to 1, call |dein#recache_runtimepath()| If you set it to 1, call |dein#recache_runtimepath()|
automatically in |dein#save_state()|. automatically in |dein#save_state()|.
Note: It is slow especially Windows.
Default: 0 Default: v:false
*g:dein#cache_directory* *g:dein#cache_directory*
g:dein#cache_directory g:dein#cache_directory
@ -468,32 +483,45 @@ g:dein#enable_name_conversion
|dein-options-normalized_name| is used as plugin name. |dein-options-normalized_name| is used as plugin name.
It is useful for absorbing difference of repository name. It is useful for absorbing difference of repository name.
Defaults: "0" Defaults: v:false
*g:dein#enable_notification* *g:dein#enable_notification*
g:dein#enable_notification g:dein#enable_notification
If you set it to 1, dein uses the notification feature. If you set it to 1, dein uses the notification feature.
You need the following commands to use it. You need the following commands to use it.
In Windows: "Snarl" and "Snarl_CMD" commands In neovim: "nvim-notify"
http://snarl.fullphat.net/ https://github.com/rcarriga/nvim-notify
https://www.tlhan-ghun.de/projects/snarl-command-line-tools/snarl_cmd-exe/ Note: This is experimental.
In Windows: "notify-send for Windows"
http://vaskovsky.net/notify-send/
https://github.com/vaskovsky/notify-send
In Mac: "terminal-notifier" or "osascript" command In Mac: "terminal-notifier" or "osascript" command
https://github.com/julienXX/terminal-notifier https://github.com/julienXX/terminal-notifier
Note: "reattach-to-user-namespace" command is needed in tmux. Note: "reattach-to-user-namespace" command is needed in tmux.
In Linux: "notify-send" command In Linux: "notify-send" command
Defaults: "0" Defaults: v:false
*g:dein#inline_vimrcs* *g:dein#inline_vimrcs*
g:dein#inline_vimrcs g:dein#inline_vimrcs
The vimrcs are sourced in |dein#end()| or The vimrcs are sourced in |dein#end()| or
|dein#load_state()|. |dein#load_state()|.
Note: It must be set before |dein#begin()|.
Note: The files must not be included "<<" pattern(here
document). It breaks the parser.
Defaults: [] Defaults: []
*g:dein#install_check_diff*
g:dein#install_check_diff
It checks plugins documentation diff when updated plugins.
Defaults: v:false
*g:dein#install_github_api_token* *g:dein#install_github_api_token*
g:dein#install_github_api_token g:dein#install_github_api_token
github API key to use |dein#check_update()|. github API key to use |dein#check_update()|.
@ -507,7 +535,7 @@ g:dein#install_max_processes
asynchronous update. asynchronous update.
If it is less than equal 1, this feature is disabled. If it is less than equal 1, this feature is disabled.
Defaults: "8" Defaults: "16"(Windows) or "8"(Others)
*g:dein#install_process_timeout* *g:dein#install_process_timeout*
g:dein#install_process_timeout g:dein#install_process_timeout
@ -553,8 +581,10 @@ g:dein#install_log_filename
g:dein#lazy_rplugins g:dein#lazy_rplugins
If you set it to 1, neovim remote plugins are lazy loaded. If you set it to 1, neovim remote plugins are lazy loaded.
It is useful to save startup time. It is useful to save startup time.
Note: It disables all remote plugins at startup. You must
define all remote plugins as lazy loaded if it is enabled.
Defaults: "0" Defaults: v:false
*g:dein#name* *g:dein#name*
g:dein#name g:dein#name
@ -564,7 +594,7 @@ g:dein#name
*g:dein#notification_icon* *g:dein#notification_icon*
g:dein#notification_icon g:dein#notification_icon
The notification icon path. The notification icon path or stocked icon to display.
Default: "" Default: ""
@ -594,6 +624,12 @@ g:dein#types#git#command_path
Default: "git" Default: "git"
*g:dein#types#git#default_hub_site*
g:dein#types#git#default_hub_site
The default hub site used for git type.
Default: "github.com"
*g:dein#types#git#default_protocol* *g:dein#types#git#default_protocol*
g:dein#types#git#default_protocol g:dein#types#git#default_protocol
The default protocol used for git (github). The default protocol used for git (github).
@ -635,6 +671,7 @@ build (String)
\ 'build': \ 'build':
\ 'sh -c "cd ruby/command-t && ruby extconf.rb && make"' \ 'sh -c "cd ruby/command-t && ruby extconf.rb && make"'
\ }) \ })
<
*dein-options-depends* *dein-options-depends*
depends (List or String) depends (List or String)
Specify a list of plugins a plugin depends on. Specify a list of plugins a plugin depends on.
@ -651,13 +688,16 @@ frozen (Bool)
ftplugin (Dictionary) ftplugin (Dictionary)
"_" key is executed after all ftplugin. "_" key is executed after all ftplugin.
"{filetype}" key is executed {filetype} ftplugin. "{filetype}" key is executed {filetype} ftplugin.
Note: You need to call |dein#recache_runtimepath()| or enable
|g:dein#auto_recache| after vimrc is changed.
*dein-options-if* *dein-options-if*
if (Bool) or (String) if (Bool) or (String)
If set to v:false, dein doesn't register the plugin, i.e. the If set to |v:false|, dein doesn't load the plugin.
plugin will be disabled. If it is |String|, dein will eval it.
If it is String, dein will eval it.
If you don't set it, dein will register (enable) the plugin. If you don't set it, dein will register (enable) the plugin.
Note: You cannot disable plugins register in dein if you use
the option.
*dein-options-lazy* *dein-options-lazy*
lazy (Bool) lazy (Bool)
@ -675,6 +715,13 @@ merged (Bool)
If set to v:false, dein doesn't merge the plugin directory. If set to v:false, dein doesn't merge the plugin directory.
It is useful for the plugin files conflicts. It is useful for the plugin files conflicts.
*dein-options-merge_ftdetect*
merge_ftdetect (Bool)
If set to v:true, dein merge the plugin "ftdetect" directory.
It is useful to enable file detection when lazy loaded plugin.
Note: It does not work if ftdetect script depends on lazy
plugin functions.
*dein-options-name* *dein-options-name*
name (String) name (String)
Specify the name of the plugin. This is used for dein Specify the name of the plugin. This is used for dein
@ -718,20 +765,6 @@ on_ft (List) or (String)
If it is matched to 'filetype', dein will call If it is matched to 'filetype', dein will call
|dein#source()|. |dein#source()|.
*dein-options-on_i*
on_i (Bool)
If set to v:true, dein will call |dein#source()| on
|InsertEnter| autocmd.
Note: This is deprecated option. You should use
|dein-options-on_event| instead.
*dein-options-on_idle*
on_idle (Bool)
If set to v:true, dein will call |dein#source()| on
|FocusLost| or |CursorHold| autocmd.
Note: This is deprecated option. You should use
|dein-options-on_event| instead.
*dein-options-on_if* *dein-options-on_if*
on_if (String) on_if (String)
If it is evaluated and it is non-zero, dein will call If it is evaluated and it is non-zero, dein will call
@ -750,6 +783,7 @@ on_lua (List) or (String)
If it is matched to the required lua module root, dein will If it is matched to the required lua module root, dein will
call |dein#source()|. call |dein#source()|.
Note: It is for neovim only. Note: It is for neovim only.
Note: It does not work for neovim standard modules.
*dein-options-on_map* *dein-options-on_map*
on_map (Dictionary) or (List) or (String) on_map (Dictionary) or (List) or (String)
@ -766,11 +800,20 @@ on_map (Dictionary) or (List) or (String)
\ { 'on_map': {'n': '<Plug>'} }) \ { 'on_map': {'n': '<Plug>'} })
< <
Note: You can use "<Plug>" keyword as {mapping}. If Note: You can use "<Plug>" keyword as {mapping}. If
{mapping} is "<Plug>", "<Plug>(normalized_name" is {mapping} is "<Plug>", "<Plug>({normalized_name}" is
used. used.
For example: > For example: >
" It is same as "'mappings': '<Plug>(anzu' " It is same as "'on_map': '<Plug>(anzu'"
call dein#add('osyo-manga/vim-anzu', {'on_map': '<Plug>'}) call dein#add('osyo-manga/vim-anzu', {'on_map': '<Plug>'})
" It is same as "'on_map': '<Plug>(easy-align'"
" But it does not work as expected. Because the plugin
" defines '<Plug>(EasyAlign)' mapping instead.
call dein#add('junegunn/vim-easy-align', {'on_map': '<Plug>'})
" This works as expected
call dein#add('junegunn/vim-easy-align',
\ {'on_map': '<Plug>(EasyAlign)'})
< <
Note: You cannot use lazy <Plug> mappings twice. Note: You cannot use lazy <Plug> mappings twice.
For example: > For example: >
@ -894,7 +937,7 @@ hook_add (String) or (Function)
Because the plugin is not sourced when "hook_add". Because the plugin is not sourced when "hook_add".
> >
call dein#add('Shougo/defx.nvim', { call dein#add('Shougo/defx.nvim', {
\ 'hook_add': 'nnoremap <silent> [Space]v \ 'hook_add': 'nnoremap <silent> <Space>v
\ :<C-u>Defx<CR>' \ :<C-u>Defx<CR>'
\ }) \ })
call dein#add('kana/vim-niceblock', { call dein#add('kana/vim-niceblock', {
@ -910,7 +953,9 @@ hook_add (String) or (Function)
< <
*dein-options-hook_done_update* *dein-options-hook_done_update*
hook_done_update (String) or (Function) hook_done_update (String) or (Function)
It is executed after the all plugins are updated. It is executed after are updated and before
|dein-options-build|.
Note: The plugin may not be sourced.
*dein-options-hook_post_source* *dein-options-hook_post_source*
hook_post_source (String) or (Function) hook_post_source (String) or (Function)
@ -923,7 +968,7 @@ hook_post_source (String) or (Function)
< <
*dein-options-hook_post_update* *dein-options-hook_post_update*
hook_post_update (String) or (Function) hook_post_update (String) or (Function)
It is executed after the plugins are updated. It is executed after plugins are sourced and updated.
*dein-options-hook_source* *dein-options-hook_source*
hook_source (String) or (Function) hook_source (String) or (Function)
@ -964,6 +1009,8 @@ TOML *dein-toml*
"{filetype}" key is executed {filetype} ftplugin. "{filetype}" key is executed {filetype} ftplugin.
You can define multiple filetypes by "{filetype1}_{filetype2}" You can define multiple filetypes by "{filetype1}_{filetype2}"
key. "b:undo_ftplugin" is defined automatically. key. "b:undo_ftplugin" is defined automatically.
Note: You need to call |dein#recache_runtimepath()| or enable
|g:dein#auto_recache| after vimrc is changed.
*dein-toml-hook_add* *dein-toml-hook_add*
hook_add (String) hook_add (String)
@ -975,6 +1022,11 @@ TOML *dein-toml*
It is converted to |dein#add()|. It is converted to |dein#add()|.
"repo" key is needed. "repo" key is needed.
*dein-toml-multple_plugins*
multiple_plugins (Dictionary)
It is converted to |dein-toml-hook_add|.
"plugins" key is needed.
*dein-toml-example* *dein-toml-example*
TOML file sample is here: TOML file sample is here:
@ -1008,12 +1060,18 @@ TOML *dein-toml*
python = ''' python = '''
let b:undo_ftplugin .= 'setlocal foldmethod<' let b:undo_ftplugin .= 'setlocal foldmethod<'
setlocal foldmethod=indent setlocal foldmethod=indent
# "hook_add" is only executed when both "foo" and "bar" are
# available.
[[multiple_plugins]]
plugins = ['foo', 'bar']
hook_add = ''
''' '''
============================================================================== ==============================================================================
UNITE SOURCES *dein-unite-sources* UNITE SOURCES *dein-unite-sources*
Here let me explain about a source for |unite| provided in dein. Here let me explain about a source for unite plugin provided in dein.
*dein-unite-source-dein* *dein-unite-source-dein*
dein dein
@ -1035,7 +1093,7 @@ dein_log
============================================================================== ==============================================================================
DENITE SOURCES *dein-denite-sources* DENITE SOURCES *dein-denite-sources*
Here let me explain about a source for |denite| provided in dein. Here let me explain about a source for denite plugin provided in dein.
*dein-denite-source-dein* *dein-denite-source-dein*
dein dein
@ -1055,37 +1113,69 @@ dein/log
EXAMPLES *dein-examples* EXAMPLES *dein-examples*
> >
if &compatible if &compatible
set nocompatible set nocompatible " Be iMproved
endif endif
" Required:
set runtimepath+={path to dein.vim directory} set runtimepath+={path to dein.vim directory}
if dein#load_state({path to plugin base path directory}) " Required:
call dein#begin({path to plugin base path directory}) call dein#begin({path to plugin base path directory})
call dein#add({path to dein.vim directory}) " Let dein manage dein
call dein#add('Shougo/deoplete.nvim') call dein#add({path to dein.vim directory})
if !has('nvim') if !has('nvim')
call dein#add('roxma/nvim-yarp') call dein#add('roxma/nvim-yarp')
call dein#add('roxma/vim-hug-neovim-rpc') call dein#add('roxma/vim-hug-neovim-rpc')
endif
...
call dein#end()
call dein#save_state()
endif endif
" Add or remove your plugins here like this:
"call dein#add('Shougo/neosnippet.vim')
"call dein#add('Shougo/neosnippet-snippets')
" Required:
call dein#end()
" Required:
filetype plugin indent on filetype plugin indent on
syntax enable syntax enable
" If you want to install not installed plugins on startup.
"if dein#check_install()
" call dein#install()
"endif
< <
==============================================================================
PLUGINS MERGED FEATURE *dein-merge*
dein.vim copies the files of multiple plugins into a single directory and
loads them as plugins by default. It expects to improve performance.
That path is usually `DEIN_INSTALLED_DIR/.cache/init.vim/.dein`.
For DEIN_INSTALLED_DIR, see |dein-install|.
Other plugin managers add a plugin path into 'runtimepath' to load external
plugins. However, if the 'runtimepath' is very large then it will load
slowly. This is because Vim needs to find and load all 'runtimepath' to load
plugins. In dein.vim, this problem does not exist.
The following plugins will not be merged to prevent merge problems
- |dein-options-merged| is v:false
- local plugin (|dein#local()|)
- lazy loaded plugin (|dein-options-lazy|)
- uses |dein-options-build|
- uses |dein-options-hook_post_update|
- uses |dein-options-if|
============================================================================== ==============================================================================
FAQ *dein-faq* FAQ *dein-faq*
Q: How to donate money to you? Q: How to donate money to you?
A: I don't get the donation, but if you want to donate, please support neovim A: I have started github sponsorship to spend more time for Vim/neovim
project. My plugins depends on neovim development. plugins. You can donate money to help me!
https://salt.bountysource.com/teams/neovim https://github.com/sponsors/Shougo
Q: Where is ":NeoBundleFetch" in dein features? Q: Where is ":NeoBundleFetch" in dein features?
@ -1110,7 +1200,7 @@ A: You can use |dein#check_install()|.
call dein#install() call dein#install()
endif endif
< <
Q: I want to disable plugins. Q: I want to disable plugins loading dynamically.
A: Please use |dein-options-if|. A: Please use |dein-options-if|.
@ -1133,15 +1223,15 @@ Or you can use |dein#source()| for it.
Q: There is the conflict between "jedi-vim" and "vim-pyenv" "initialize.py" Q: There is the conflict between "jedi-vim" and "vim-pyenv" "initialize.py"
file. file.
A: It is the plugins problem. The plugins should not create the conflited A: All plugins should avoid file name collisions. dein.vim can load them
name file. But you can avoid the problem by |dein-options-merged|. by setting |dein-options-merged|. See |dein-merge| for details.
Q: How to remove the disabled plugins? Q: How to remove the disabled plugins?
A: You can remove them like below. A: You can remove them like below.
Note: You must call |dein#recache_runtimepath()| after the remove. Note: You must call |dein#recache_runtimepath()| after the remove.
> >
call map(dein#check_clean(), "delete(v:val, 'rf')") call map(dein#check_clean(), { _, val -> delete(val, 'rf') })
call dein#recache_runtimepath() call dein#recache_runtimepath()
< <
Q: How to use the script functions for hooks feature? Q: How to use the script functions for hooks feature?
@ -1203,9 +1293,10 @@ If you have found "Process timeout" error, you should increase
Q: YouCompleteMe does not work. I have built YouCompleteMe manually. Q: YouCompleteMe does not work. I have built YouCompleteMe manually.
A: dein.vim has merge feature. It copys the plugins into the merge directory. A: dein.vim has |dein-merge| feature. It copies the plugin files into the
So dein.vim does not know the manually built binary. It does not be copied. merge directory. If you build it manually, it will not be copied
You should disable the merge feature manually. > from time to time.
You can disable the |dein-options-merged|. >
call dein#add('Valloric/YouCompleteMe', {'merged': 0}) call dein#add('Valloric/YouCompleteMe', {'merged': 0})
or > or >
@ -1217,9 +1308,9 @@ A: It is Vim/neovim |delete()| implementation bug.
It uses |glob()| internally. It uses |glob()| internally.
If the directory has contains "[]" files, it will be errored. If the directory has contains "[]" files, it will be errored.
For example, vimtex has the file. For example, vimtex has the file.
https://github.com/lervag/vimtex/tree/master/test/issues/237/ https://github.com/lervag/vimtex/issues/237
You can disable the merge feature to prevent the error. > You can disable the |dein-merge| feature to prevent the error. >
call dein#add('lervag/vimtex', {'merged': 0}) call dein#add('lervag/vimtex', {'merged': 0})
@ -1230,8 +1321,8 @@ repository.
Q: Why dein.vim merges the plugins directories automatically? Q: Why dein.vim merges the plugins directories automatically?
A: To avoid long 'runtimepath'. If 'runtimepath' is long, Vim/neovim loading A: |dein-merge| merge improves performance by avoiding long 'runtimepath'.
performance will be bad. See also the |dein-merge|.
Q: I want to update from shell. Q: I want to update from shell.
@ -1288,20 +1379,51 @@ plugins?
https://github.com/Shougo/dein.vim/issues/357 https://github.com/Shougo/dein.vim/issues/357
A: You can use |g:dein#auto_recache| option instead. A: You can use |g:dein#auto_recache| option instead.
Dein.vim has merge feature. It copys the plugins into the merge directory. Dein.vim has |dein-merge| feature. It copies the plugins into the
You can disable the feature by |dein-options-merged|. It is like other plugin merge directory. You can disable the feature by setting
managers behavior. |dein-options-merged|. See also the |dein-merge|.
Why dein.vim has the feature? It is for loading performance.
Other plugin manager adds 'runtimepath' to load external plugins.
But if 'runtimepath' is very big, plugin loading is slower. Because Vim needs
to search all huge 'runtimepath' to load it. Dein.vim has not the problem.
Q: I want to load plugins lazily on requiring lua modules Q: I want to load plugins lazily on requiring lua modules
A: > A: >
call dein#add('neovim/nvim-lsp', {'on_lua': 'nvim_lsp'}) call dein#add('neovim/nvim-lsp', {'on_lua': 'nvim_lsp'})
Q: deoplete does not work when I use |dein#load_state()|.
A: Please read |dein#load_state()| documentation. "The block is skipped if
dein's state is loaded." >
if dein#load_state(path)
call dein#begin(path)
call dein#add('Shougo/deoplete.nvim')
let g:deoplete#enable_at_startup = v:true " It will be skipped!
call dein#end()
call dein#save_state()
endif
" You must set variables or execute functions outside the block
let g:deoplete#enable_at_startup = v:true
Q: I want to enable default merged config in Windows.
A: >
let g:dein#default_options = { 'merged': v:true }
============================================================================== ==============================================================================
COMPATIBILITY *dein-compatibility* COMPATIBILITY *dein-compatibility*
2021.09.20
* Remove "dein-options-on_i".
* Remove "dein-options-on_idle".
2021.09.18
* hook_post_update is executed before "build".
* hook_done_update is executed after "build" and sourced.
2021.08.28
* Change dein#source() return value
2021.08.26
* Vim 8.2 or nvim 0.5 is required
============================================================================== ==============================================================================
vim:tw=78:ts=8:ft=help:norl:noet:fen: vim:tw=78:ts=8:ft=help:norl:noet:fen:

View File

@ -6,7 +6,7 @@ let s:assert = themis#helper('assert')
let s:path = tempname() let s:path = tempname()
function! s:suite.before_each() abort function! s:suite.before_each() abort
call dein#_init() call dein#min#_init()
endfunction endfunction
function! s:suite.block_normal() abort function! s:suite.block_normal() abort
@ -21,7 +21,7 @@ function! s:suite.begin_invalid() abort
call s:assert.equals(dein#begin(s:path), 0) call s:assert.equals(dein#begin(s:path), 0)
call s:assert.equals(dein#begin(s:path), 1) call s:assert.equals(dein#begin(s:path), 1)
call dein#_init() call dein#min#_init()
call s:assert.equals(dein#end(), 1) call s:assert.equals(dein#end(), 1)
call s:assert.equals(dein#end(), 1) call s:assert.equals(dein#end(), 1)

View File

@ -13,10 +13,7 @@ let s:filetype_save = &l:filetype
let s:this_script = fnamemodify(expand('<sfile>'), ':p') let s:this_script = fnamemodify(expand('<sfile>'), ':p')
let s:merged_format = "{'repo': v:val.repo, 'rev': get(v:val, 'rev', '')}"
function! s:dein_install() abort function! s:dein_install() abort
call dein#util#_save_merged_plugins()
return dein#install#_update([], 'install', 0) return dein#install#_update([], 'install', 0)
endfunction endfunction
@ -25,18 +22,18 @@ function! s:dein_update() abort
endfunction endfunction
function! s:suite.before_each() abort function! s:suite.before_each() abort
call dein#_init() call dein#min#_init()
let &runtimepath = s:runtimepath_save let &runtimepath = s:runtimepath_save
let &l:filetype = s:filetype_save let &l:filetype = s:filetype_save
let g:temp = tempname() let g:temp = tempname()
let g:dein#install_progress_type = 'echo' let g:dein#install_progress_type = 'echo'
let g:dein#enable_notification = 0 let g:dein#enable_notification = v:false
endfunction endfunction
" Note: It must be checked in the first " Note: It must be checked in the first
function! s:suite.install() abort function! s:suite.install() abort
let g:dein#install_progress_type = 'title' let g:dein#install_progress_type = 'title'
let g:dein#enable_notification = 1 let g:dein#enable_notification = v:true
call dein#begin(s:path) call dein#begin(s:path)
@ -54,9 +51,6 @@ function! s:suite.install() abort
let plugin = dein#get('deoplete.nvim') let plugin = dein#get('deoplete.nvim')
call s:assert.true(isdirectory(plugin.rtp)) call s:assert.true(isdirectory(plugin.rtp))
call s:assert.equals(dein#each('git gc'), 0) call s:assert.equals(dein#each('git gc'), 0)
call s:assert.equals(dein#util#_get_merged_plugins(),
\ dein#util#_load_merged_plugins())
endfunction endfunction
function! s:suite.tap() abort function! s:suite.tap() abort
@ -168,17 +162,7 @@ function! s:suite.if() abort
call dein#begin(s:path) call dein#begin(s:path)
call dein#add('Shougo/deoplete.nvim', {'if': 0, 'on_cmd': 'FooBar'}) call dein#add('Shougo/deoplete.nvim', {'if': 0, 'on_cmd': 'FooBar'})
call s:assert.equals(dein#get('deoplete.nvim').if, 0)
call s:assert.equals(dein#get('deoplete.nvim'), {})
call s:assert.false(exists(':FooBar'))
call dein#end()
call dein#begin(s:path)
call dein#add('Shougo/deoplete.nvim', {'if': '1+1'})
call s:assert.equals(dein#get('deoplete.nvim').if, 2)
call dein#end() call dein#end()
endfunction endfunction
@ -196,27 +180,14 @@ function! s:suite.lazy_manual() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
call s:assert.equals(dein#source(['deoplete.nvim']), 0) call s:assert.equals(len(dein#source(['deoplete.nvim'])), 1)
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction
function! s:suite.lazy_on_i() abort
call dein#begin(s:path)
call dein#add('Shougo/deoplete.nvim', { 'on_i': 1 })
call s:assert.equals(s:dein_install(), 0)
call dein#end()
call s:assert.equals(g:dein#_event_plugins,
\ {'InsertEnter': ['deoplete.nvim']})
endfunction endfunction
function! s:suite.lazy_on_ft() abort function! s:suite.lazy_on_ft() abort
@ -232,20 +203,20 @@ function! s:suite.lazy_on_ft() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
set filetype=c set filetype=c
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
set filetype=cpp set filetype=cpp
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_path() abort function! s:suite.lazy_on_path() abort
@ -261,14 +232,14 @@ function! s:suite.lazy_on_path() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
execute 'edit' tempname() execute 'edit' tempname()
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_if() abort function! s:suite.lazy_on_if() abort
@ -276,7 +247,7 @@ function! s:suite.lazy_on_if() abort
let temp = tempname() let temp = tempname()
call dein#add('Shougo/deol.nvim', call dein#add('Shougo/deol.nvim',
\ { 'on_if': '&filetype ==# "foobar"' }) \ { 'on_if': '&l:filetype ==# "foobar"' })
call s:assert.equals(s:dein_install(), 0) call s:assert.equals(s:dein_install(), 0)
@ -286,7 +257,7 @@ function! s:suite.lazy_on_if() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
set filetype=foobar set filetype=foobar
@ -294,7 +265,7 @@ function! s:suite.lazy_on_if() abort
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_source() abort function! s:suite.lazy_on_source() abort
@ -312,14 +283,14 @@ function! s:suite.lazy_on_source() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
call dein#source('deol.nvim') call dein#source('deol.nvim')
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_func() abort function! s:suite.lazy_on_func() abort
@ -338,26 +309,26 @@ function! s:suite.lazy_on_func() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin2.rtp')), 0) \ { _, val -> val ==# plugin2.rtp })), 0)
call dein#autoload#_on_func('deoplete#initialize') call dein#autoload#_on_func('deoplete#initialize')
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin2.rtp')), 0) \ { _, val -> val ==# plugin2.rtp })), 0)
call neosnippet#expandable() call neosnippet#expandable()
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin2.rtp')), 1) \ { _, val -> val ==# plugin2.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_cmd() abort function! s:suite.lazy_on_cmd() abort
@ -374,7 +345,7 @@ function! s:suite.lazy_on_cmd() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
NeoCompleteDisable NeoCompleteDisable
@ -396,7 +367,7 @@ function! s:suite.lazy_on_map() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin1.rtp')), 0) \ { _, val -> val ==# plugin1.rtp })), 0)
call dein#autoload#_on_map('', 'deol.nvim', 'n') call dein#autoload#_on_map('', 'deol.nvim', 'n')
call dein#autoload#_on_map('', 'neosnippet.vim', 'n') call dein#autoload#_on_map('', 'neosnippet.vim', 'n')
@ -405,7 +376,7 @@ function! s:suite.lazy_on_map() abort
call s:assert.equals(plugin2.sourced, 1) call s:assert.equals(plugin2.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin1.rtp')), 1) \ { _, val -> val ==# plugin1.rtp })), 1)
endfunction endfunction
function! s:suite.lazy_on_pre_cmd() abort function! s:suite.lazy_on_pre_cmd() abort
@ -421,7 +392,7 @@ function! s:suite.lazy_on_pre_cmd() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
call dein#autoload#_on_pre_cmd('Deol') call dein#autoload#_on_pre_cmd('Deol')
@ -429,58 +400,7 @@ function! s:suite.lazy_on_pre_cmd() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction
if has('nvim-0.5')
function! s:suite.lazy_on_lua() abort
call dein#begin(s:path)
call dein#add('Shougo/deoplete.nvim', { 'on_lua': 'vim' })
call s:assert.equals(s:dein_install(), 0)
call dein#end()
let plugin = dein#get('deoplete.nvim')
call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0)
lua require'vim.highlight'
call s:assert.equals(plugin.sourced, 1)
call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1)
endfunction
endif
function! s:suite.lazy_on_idle() abort
call dein#begin(s:path)
call dein#add('Shougo/defx.nvim', { 'on_idle': 1})
call s:assert.equals(s:dein_install(), 0)
call dein#end()
call s:assert.equals(g:dein#_event_plugins,
\ {'CursorHold': ['defx.nvim'], 'FocusLost': ['defx.nvim']})
let plugin = dein#get('defx.nvim')
call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0)
doautocmd CursorHold
call s:assert.equals(plugin.sourced, 1)
call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1)
endfunction endfunction
function! s:suite.depends() abort function! s:suite.depends() abort
@ -497,7 +417,7 @@ function! s:suite.depends() abort
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.depends_lazy() abort function! s:suite.depends_lazy() abort
@ -517,15 +437,15 @@ function! s:suite.depends_lazy() abort
call s:assert.equals(isdirectory(plugin.rtp), 1) call s:assert.equals(isdirectory(plugin.rtp), 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 0) \ { _, val -> val ==# plugin.rtp })), 0)
call s:assert.equals(dein#source(['deoplete.nvim']), 0) call s:assert.equals(len(dein#source(['deoplete.nvim'])), 2)
call s:assert.equals(plugin.sourced, 1) call s:assert.equals(plugin.sourced, 1)
call s:assert.equals( call s:assert.equals(
\ len(filter(dein#util#_split_rtp(&runtimepath), \ len(filter(dein#util#_split_rtp(&runtimepath),
\ 'v:val ==# plugin.rtp')), 1) \ { _, val -> val ==# plugin.rtp })), 1)
endfunction endfunction
function! s:suite.depends_error_lazy() abort function! s:suite.depends_error_lazy() abort
@ -538,7 +458,7 @@ function! s:suite.depends_error_lazy() abort
call s:assert.equals(dein#end(), 0) call s:assert.equals(dein#end(), 0)
call s:assert.equals(dein#source(['deoplete.nvim']), 0) call s:assert.equals(len(dein#source(['deoplete.nvim'])), 0)
call dein#begin(s:path) call dein#begin(s:path)
@ -550,7 +470,7 @@ function! s:suite.depends_error_lazy() abort
call s:assert.equals(dein#end(), 0) call s:assert.equals(dein#end(), 0)
call s:assert.equals(dein#source(['deoplete.nvim']), 0) call s:assert.equals(len(dein#source(['deoplete.nvim'])), 0)
endfunction endfunction
function! s:suite.hooks() abort function! s:suite.hooks() abort
@ -683,15 +603,13 @@ function! s:suite.build() abort
call dein#add('Shougo/vimproc.vim', { call dein#add('Shougo/vimproc.vim', {
\ 'build': 'make', \ 'build': 'make',
\ 'hook_add':
\ 'let g:foobar = 1',
\ 'hook_post_update': \ 'hook_post_update':
\ 'let g:foobar = 4', \ 'let g:foobar = 4',
\ }) \ })
call dein#end() call dein#end()
call s:assert.equals(g:foobar, 1) call s:assert.not_equals(g:foobar, 4)
call s:assert.true(dein#check_install()) call s:assert.true(dein#check_install())
call s:assert.true(dein#check_install(['vimproc.vim'])) call s:assert.true(dein#check_install(['vimproc.vim']))

View File

@ -31,16 +31,3 @@ function! s:suite.copy_directories() abort
call s:assert.true(filereadable(temp2.'/foo')) call s:assert.true(filereadable(temp2.'/foo'))
call s:assert.true(filereadable(temp2.'/bar')) call s:assert.true(filereadable(temp2.'/bar'))
endfunction endfunction
function! s:suite.args2string() abort
call s:assert.equals(
\ dein#install#_args2string_unix(['foo', 'bar']), "'foo' 'bar'")
call s:assert.equals(
\ dein#install#_args2string_windows([]), '')
call s:assert.equals(
\ dein#install#_args2string_windows(['foo']), 'foo')
call s:assert.equals(
\ dein#install#_args2string_windows(['foo', 'bar']), 'foo "bar"')
call s:assert.equals(
\ dein#install#_args2string_windows(['fo o', 'bar']), '"fo o" "bar"')
endfunction

View File

@ -6,7 +6,7 @@ let s:assert = themis#helper('assert')
let s:path = tempname() let s:path = tempname()
function! s:suite.before_each() abort function! s:suite.before_each() abort
call dein#_init() call dein#min#_init()
endfunction endfunction
function! s:suite.after_each() abort function! s:suite.after_each() abort
@ -41,7 +41,7 @@ function! s:suite.parse_dict() abort
endfunction endfunction
function! s:suite.name_conversion() abort function! s:suite.name_conversion() abort
let g:dein#enable_name_conversion = 1 let g:dein#enable_name_conversion = v:true
let plugin = dein#parse#_dict( let plugin = dein#parse#_dict(
\ {'repo': 'https://github.com/Shougo/dein.vim.git'}) \ {'repo': 'https://github.com/Shougo/dein.vim.git'})
@ -60,7 +60,7 @@ function! s:suite.name_conversion() abort
\ 'name': 'vim-qt-syntax'}) \ 'name': 'vim-qt-syntax'})
call s:assert.equals(plugin.name, 'vim-qt-syntax') call s:assert.equals(plugin.name, 'vim-qt-syntax')
let g:dein#enable_name_conversion = 0 let g:dein#enable_name_conversion = v:false
endfunction endfunction
function! s:suite.load_toml() abort function! s:suite.load_toml() abort
@ -78,7 +78,6 @@ function! s:suite.load_toml() abort
\ "on_map = '<Plug>'", \ "on_map = '<Plug>'",
\ '[[plugins]]', \ '[[plugins]]',
\ "repo = 'Shougo/neosnippet.vim'", \ "repo = 'Shougo/neosnippet.vim'",
\ 'on_i = 1',
\ "on_ft = 'snippet'", \ "on_ft = 'snippet'",
\ "hook_add = '''", \ "hook_add = '''",
\ '"echo', \ '"echo',
@ -92,6 +91,9 @@ function! s:suite.load_toml() abort
\ "'''", \ "'''",
\ '[plugins.ftplugin]', \ '[plugins.ftplugin]',
\ 'c = "let g:bar = 0"', \ 'c = "let g:bar = 0"',
\ '[[multiple_plugins]]',
\ "plugins = ['foo', 'bar']",
\ "hook_add = 'foo'",
\ ], toml) \ ], toml)
call dein#begin(s:path) call dein#begin(s:path)
@ -101,11 +103,13 @@ function! s:suite.load_toml() abort
call s:assert.equals(g:dein#_hook_add, "\nlet g:foo = 0") call s:assert.equals(g:dein#_hook_add, "\nlet g:foo = 0")
call s:assert.equals(g:dein#_ftplugin, call s:assert.equals(g:dein#_ftplugin,
\ {'c': "let g:bar = 0\nlet g:bar = 0"}) \ {'c': "let g:bar = 0\nlet g:bar = 0"})
call s:assert.equals(g:dein#_multiple_plugins, [
\ {'plugins': ['foo', 'bar'], 'hook_add': 'foo'},
\ ])
call dein#end() call dein#end()
call s:assert.equals(dein#get('neosnippet.vim').on_i, 1)
call s:assert.equals(dein#get('neosnippet.vim').hook_add, call s:assert.equals(dein#get('neosnippet.vim').hook_add,
\ "\necho\n") \ "\"echo\n\"comment\necho\n")
call s:assert.equals(dein#get('neosnippet.vim').hook_source, call s:assert.equals(dein#get('neosnippet.vim').hook_source,
\ "echo\necho\n") \ "echo\necho\n")
endfunction endfunction
@ -118,7 +122,6 @@ function! s:suite.error_toml() abort
\ '# repository name is required.', \ '# repository name is required.',
\ "on_map = '<Plug>'", \ "on_map = '<Plug>'",
\ '[[plugins]]', \ '[[plugins]]',
\ 'on_i = 1',
\ "on_ft = 'snippet'", \ "on_ft = 'snippet'",
\ ], toml) \ ], toml)
@ -158,29 +161,29 @@ function! s:suite.config() abort
\ 'Shougo/denite.nvim': {} \ 'Shougo/denite.nvim': {}
\ }) \ })
let g:dein#name = 'denite.nvim' let g:dein#name = 'denite.nvim'
call dein#config({'on_i': 1}) call dein#config({'on_event': ['InsertEnter']})
call dein#end() call dein#end()
call dein#config('unite', {'on_i': 0}) call dein#config('unite', {'on_event': ['InsertEnter']})
call s:assert.equals(dein#get('denite.nvim').on_i, 1) call s:assert.equals(dein#get('denite.nvim').on_event, ['InsertEnter'])
endfunction endfunction
function! s:suite.skip_overwrite() abort function! s:suite.skip_overwrite() abort
call dein#begin(s:path) call dein#begin(s:path)
call dein#add('Shougo/denite.nvim', {'on_i': 0}) call dein#add('Shougo/denite.nvim', {'on_event': []})
call dein#add('Shougo/denite.nvim', {'on_i': 1}) call dein#add('Shougo/denite.nvim', {'on_event': ['InsertEnter']})
call dein#end() call dein#end()
call s:assert.equals(dein#get('denite.nvim').on_i, 0) call s:assert.equals(dein#get('denite.nvim').on_event, [])
endfunction endfunction
function! s:suite.overwrite() abort function! s:suite.overwrite() abort
call dein#begin(s:path) call dein#begin(s:path)
call dein#add('Shougo/denite.nvim', {'on_i': 0}) call dein#add('Shougo/denite.nvim', {'on_event': []})
call dein#add('Shougo/denite.nvim', {'on_i': 1, 'overwrite': 1}) call dein#add('Shougo/denite.nvim', {'on_event': ['InsertEnter'], 'overwrite': 1})
call dein#end() call dein#end()
call s:assert.equals(dein#get('denite.nvim').on_i, 1) call s:assert.equals(dein#get('denite.nvim').on_event, ['InsertEnter'])
endfunction endfunction
function! s:suite.plugins2toml() abort function! s:suite.plugins2toml() abort

View File

@ -8,7 +8,7 @@ let s:path = fnamemodify('.cache', ':p') . '/'
let s:filetype_save = &l:filetype let s:filetype_save = &l:filetype
function! s:suite.before_each() abort function! s:suite.before_each() abort
call dein#_init() call dein#min#_init()
let &runtimepath = s:runtimepath_save let &runtimepath = s:runtimepath_save
let &l:filetype = s:filetype_save let &l:filetype = s:filetype_save
let g:temp = tempname() let g:temp = tempname()