miv 0.4.5 → 0.4.6
raw patch · 2 files changed
+84/−105 lines, 2 files
Files
- miv.cabal +1/−1
- src/VimScript.hs +83/−104
miv.cabal view
@@ -1,5 +1,5 @@ name: miv-version: 0.4.5+version: 0.4.6 author: itchyny <https://github.com/itchyny> maintainer: itchyny <https://github.com/itchyny> license: MIT
src/VimScript.hs view
@@ -6,7 +6,6 @@ import Data.Hashable import qualified Data.HashMap.Lazy as HM import Data.List (foldl', groupBy, sort, sortBy, nub)-import Data.Maybe (mapMaybe) import Data.Text (Text, singleton, unpack, unwords) import qualified Data.Text as T import GHC.Generics (Generic)@@ -43,11 +42,6 @@ show (Ftplugin s) = "ftplugin/" <> s <> ".vim" show (Syntax s) = "syntax/" <> s <> ".vim" -autoloadSubdirName :: Place -> Maybe Text-autoloadSubdirName (Autoload "") = Nothing-autoloadSubdirName (Autoload s) = Just s-autoloadSubdirName _ = Nothing- vimScriptToList :: VimScript -> [(Place, [Text])] vimScriptToList (VimScript x) = HM.toList x @@ -65,8 +59,7 @@ mempty = VimScript HM.empty gatherScript :: S.Setting -> VimScript-gatherScript setting = addAutoloadNames- $ beforeScript setting+gatherScript setting = beforeScript setting <> gatherBeforeAfterScript plugins <> gather' "dependon" P.dependon P.loadbefore plugins <> gather' "dependedby" P.dependedby P.loadafter plugins@@ -81,8 +74,8 @@ <> funcUndefinedLoader setting <> cmdlineEnterLoader setting <> insertEnterLoader setting- <> filetypeScript (S.filetype setting)- <> syntaxScript (S.syntax setting)+ <> filetypeScript setting+ <> syntaxScript setting <> afterScript setting where plugins = S.plugins setting @@ -103,18 +96,11 @@ hchar | null (loadScript p) = maybe "_" singleton $ getHeadChar $ show p | otherwise = "_" funcname str = "miv#" <> hchar <> "#" <> str <> "_" <> name- au = Autoload hchar- vs' = VimScript $ HM.singleton au $ wrapFunction (funcname "before") (P.before p)- <> wrapFunction (funcname "after") (P.after p)+ vs' = VimScript $ HM.singleton (Autoload hchar) $+ wrapFunction (funcname "before") (P.before p) <>+ wrapFunction (funcname "after") (P.after p) gatherScripts [] (vs, hm) = (vs, hm) -addAutoloadNames :: VimScript -> VimScript-addAutoloadNames h@(VimScript hm)- = VimScript (HM.singleton (Autoload "")- [ "let s:autoloads = { " <> T.intercalate ", " (((<>": 1") . singleQuote)- <$> mapMaybe autoloadSubdirName (HM.keys hm)) <> " }"])- <> h- gather :: Text -> (P.Plugin -> [Text]) -> [P.Plugin] -> VimScript gather name f plg = VimScript (HM.singleton (Autoload "") $@@ -144,7 +130,7 @@ pluginConfig :: P.Plugin -> VimScript pluginConfig plg = VimScript (HM.singleton Plugin $ wrapInfo $- wrapEnable plg $ mapleader <> gatherCommand plg <> gatherMapping plg <> P.script plg <> loadScript plg)+ wrapEnable (P.enable plg) $ mapleader <> gatherCommand plg <> gatherMapping plg <> P.script plg <> loadScript plg) where wrapInfo [] = [] wrapInfo str = ("\" " <> P.name plg) : str@@ -194,59 +180,51 @@ filetypeLoader :: S.Setting -> VimScript filetypeLoader setting- = HM.foldrWithKey f mempty (filetypeLoadPlugins (S.plugins setting) HM.empty)+ = mconcat $ map (uncurry f) $+ collectSndByFst [(ft, p) | p <- S.plugins setting, ft <- P.filetypes p] where- f ft plg val =- case getHeadChar ft of- Nothing -> val- Just c ->- let funcname = "miv#" <> singleton c <> "#load_" <> T.filter isAlphaNum (T.toLower ft)- in val- <> VimScript (HM.singleton (Autoload (singleton c))- (("function! " <> funcname <> "() abort")- : " setlocal filetype="- : concat [wrapEnable b- [ " call miv#load(" <> singleQuote (show b) <> ")"] | b <- plg]- <> [ " autocmd! miv-file-type-" <> ft- , " augroup! miv-file-type-" <> ft- , " setlocal filetype=" <> ft- , " silent! doautocmd FileType " <> ft- , "endfunction"- ]))- <> VimScript (HM.singleton Plugin- [ "augroup miv-file-type-" <> ft- , " autocmd!"- , " autocmd FileType " <> ft <> " call " <> funcname <> "()"- , "augroup END"- ])--filetypeLoadPlugins :: [P.Plugin] -> HM.HashMap Text [P.Plugin] -> HM.HashMap Text [P.Plugin]-filetypeLoadPlugins (b:plugins) fts- | not (null (P.filetypes b))- = filetypeLoadPlugins plugins (foldr (flip (HM.insertWith (<>)) [b]) fts (P.filetypes b))- | otherwise = filetypeLoadPlugins plugins fts-filetypeLoadPlugins [] fts = fts+ f :: Text -> [P.Plugin] -> VimScript+ f ft plugins = flip foldMap (getHeadChar ft) $+ \c -> let funcname = "miv#" <> singleton c <> "#load_" <> T.filter isAlphaNum (T.toLower ft)+ in VimScript (HM.singleton Plugin+ [ "augroup miv-file-type-" <> ft+ , " autocmd!"+ , " autocmd FileType " <> ft <> " call " <> funcname <> "()"+ , "augroup END" ]) <>+ VimScript (HM.singleton (Autoload (singleton c)) $+ ("function! " <> funcname <> "() abort")+ : " setlocal filetype="+ : loadPlugins plugins+ <> [ " autocmd! miv-file-type-" <> ft+ , " augroup! miv-file-type-" <> ft+ , " setlocal filetype=" <> ft+ , " silent! doautocmd FileType " <> ft+ , "endfunction" ]) -wrapEnable :: P.Plugin -> [Text] -> [Text]-wrapEnable plg str+wrapEnable :: Text -> [Text] -> [Text]+wrapEnable enable str | null str = []- | T.null (P.enable plg) = str- | P.enable plg == "0" = []- | otherwise = (indent <> "if " <> P.enable plg)+ | T.null enable = str+ | enable == "0" = []+ | otherwise = (indent <> "if " <> enable) : map (" "<>) str <> [indent <> "endif"] where indent = T.takeWhile (==' ') (head str) +loadPlugins :: [P.Plugin] -> [Text]+loadPlugins plugins = concat+ [wrapEnable enable+ [" call miv#load(" <> singleQuote (show p) <> ")" | p <- plugins']+ | (enable, plugins') <- collectSndByFst [(P.enable p, p) | p <- plugins]]+ singleQuote :: Text -> Text singleQuote str = "'" <> str <> "'" -filetypeScript :: HM.HashMap Text [Text] -> VimScript-filetypeScript =- HM.foldrWithKey (\ft scr val -> val <> VimScript (HM.singleton (Ftplugin ft) scr)) mempty+filetypeScript :: S.Setting -> VimScript+filetypeScript = foldMap (\(ft, src) -> VimScript (HM.singleton (Ftplugin ft) src)) . HM.toList . S.filetype -syntaxScript :: HM.HashMap Text [Text] -> VimScript-syntaxScript =- HM.foldrWithKey (\ft scr val -> val <> VimScript (HM.singleton (Syntax ft) scr)) mempty+syntaxScript :: S.Setting -> VimScript+syntaxScript = foldMap (\(ft, src) -> VimScript (HM.singleton (Syntax ft) src)) . HM.toList . S.syntax wrapFunction :: Text -> [Text] -> [Text] wrapFunction funcname script =@@ -271,8 +249,7 @@ , " endif" , " call feedkeys((v:count ? v:count : '') . substitute(a:mapping, '<Plug>', \"\\<Plug>\", 'g'), 'm')" , " return ''"- , "endfunction"- ])+ , "endfunction" ]) commandLoader :: VimScript commandLoader = VimScript (HM.singleton (Autoload "")@@ -285,12 +262,11 @@ , " catch /^Vim\\%((\\a\\+)\\)\\=:E481:/" , " exec a:command.a:bang a:args" , " endtry"- , "endfunction"- ])+ , "endfunction" ]) funcUndefinedLoader :: S.Setting -> VimScript-funcUndefinedLoader setting | all (null . P.functions) (S.plugins setting) = mempty-funcUndefinedLoader _ = VimScript (HM.singleton Plugin+funcUndefinedLoader setting = if null functions then mempty else+ VimScript (HM.singleton Plugin [ "\" FuncUndefined" , "augroup miv-func-undefined" , " autocmd!"@@ -298,6 +274,9 @@ , "augroup END" ]) <> VimScript (HM.singleton (Autoload "") [ "function! miv#func_undefined(pattern) abort"+ , " if a:pattern !~# " <> singleQuote (T.intercalate "\\|" functions)+ , " return"+ , " endif" , " if empty(s:functions)" , " autocmd! miv-func-undefined" , " augroup! miv-func-undefined"@@ -311,47 +290,51 @@ , " endif" , " endfor" , " endfor"- , "endfunction"- ])+ , "endfunction" ])+ where functions = [ f | p <- S.plugins setting, f <- P.functions p ] cmdlineEnterLoader :: S.Setting -> VimScript cmdlineEnterLoader setting- = HM.foldrWithKey f mempty $- foldr (uncurry (HM.insertWith (<>))) HM.empty- [ (cmdline, [p]) | p <- S.plugins setting, cmdline <- P.cmdlines p ]+ = mconcat $ map (uncurry f) $+ collectSndByFst [(cmdline, p) | p <- S.plugins setting, cmdline <- P.cmdlines p] where- f :: Cmdline -> [P.Plugin] -> VimScript -> VimScript- f cmdline plugins val = val <> VimScript (HM.singleton Plugin+ f :: Cmdline -> [P.Plugin] -> VimScript+ f cmdline plugins = VimScript (HM.singleton Plugin [ "\" CmdlineEnter " <> (show cmdline)- , "augroup " <> group- , " autocmd!"- , " autocmd CmdlineEnter " <> (cmdlinePattern cmdline) <> " call miv#cmdline_enter_" <> c <> "()"- , "augroup END" ])+ , "if exists('#CmdlineEnter')"+ , " augroup " <> group+ , " autocmd!"+ , " autocmd CmdlineEnter " <> (cmdlinePattern cmdline) <> " call miv#cmdline_enter_" <> c <> "()"+ , " augroup END"+ , "else"+ , " call miv#cmdline_enter_" <> c <> "()"+ , "endif" ]) <> VimScript (HM.singleton (Autoload "") $- ("function! miv#cmdline_enter_" <> c <> "() abort") :- [ " call miv#load(" <> singleQuote (show p) <> ")" | p <- plugins ]- <> [ " autocmd! " <> group- , " augroup! " <> group- , "endfunction"- ])+ ("function! miv#cmdline_enter_" <> c <> "() abort")+ : loadPlugins plugins+ <> [ " if exists('#CmdlineEnter')"+ , " autocmd! " <> group+ , " augroup! " <> group+ , " endif"+ , "endfunction" ]) where c = T.concat $ map (show . ord) (unpack (show cmdline)) group = "miv-cmdline-enter-" <> c insertEnterLoader :: S.Setting -> VimScript-insertEnterLoader setting = if null plugins then mempty else VimScript (HM.singleton Plugin+insertEnterLoader setting = if null plugins then mempty else+ VimScript (HM.singleton Plugin [ "\" InsertEnter" , "augroup miv-insert-enter" , " autocmd!" , " autocmd InsertEnter * call miv#insert_enter()" , "augroup END" ]) <> VimScript (HM.singleton (Autoload "")- $ "function! miv#insert_enter() abort" :- [ " call miv#load(" <> singleQuote (show p) <> ")" | p <- plugins ]+ $ "function! miv#insert_enter() abort"+ : loadPlugins plugins <> [ " autocmd! miv-insert-enter" , " augroup! miv-insert-enter" , " silent! doautocmd InsertEnter"- , "endfunction"- ])+ , "endfunction" ]) where plugins = filter P.insert (S.plugins setting) pluginLoader :: VimScript@@ -359,6 +342,7 @@ [ "let s:loaded = {}" , "let s:path = expand('<sfile>:p:h:h')" , "let s:mivpath = expand('<sfile>:p:h:h:h') . '/'"+ , "let s:rtpidx = 0" , "function! miv#load(name) abort" , " if has_key(s:loaded, a:name)" , " return"@@ -376,25 +360,21 @@ , " endfor" , " endfor" , " let name = substitute(tolower(a:name), '[^a-z0-9]', '', 'g')"- , " let au = has_key(s:autoload, name) && get(s:autoloads, s:autoload[name])"+ , " let au = has_key(s:autoload, name)" , " if au" , " call miv#{s:autoload[name]}#before_{name}()" , " endif"- , " let newrtp = s:mivpath . a:name . '/'"+ , " let newrtp = s:mivpath . a:name" , " if !isdirectory(newrtp)" , " return" , " endif" , " let rtps = split(&rtp, ',')"- , " let i = index(map(deepcopy(rtps), 'resolve(v:val)'), s:path)"- , " if i < 0"- , " let mivpath = get(filter(deepcopy(rtps), 'v:val =~# \"miv.\\\\?$\"'), 0, '')"- , " let i = max([0, index(deepcopy(rtps), mivpath)])"- , " endif"- , " let &rtp = join(insert(rtps, newrtp, i), ',')"- , " if isdirectory(newrtp . 'after/')"- , " exec 'set rtp+=' . newrtp . 'after/'"+ , " let s:rtpidx = max([index(rtps, s:path, s:rtpidx), 0])"+ , " let &rtp = join(insert(rtps, newrtp, s:rtpidx), ',')"+ , " if isdirectory(newrtp . '/after')"+ , " exec 'set rtp+=' . newrtp . '/after'" , " endif"- , " for dir in filter(['plugin', 'after/plugin'], 'isdirectory(newrtp . v:val)')"+ , " for dir in filter(['/plugin', '/after/plugin'], 'isdirectory(newrtp . v:val)')" , " for file in split(glob(newrtp . dir . '/**/*.vim'), '\\n')" , " silent! source `=file`" , " endfor"@@ -405,5 +385,4 @@ , " for n in get(s:dependedby, a:name, [])" , " call miv#load(n)" , " endfor"- , "endfunction"- ])+ , "endfunction" ])