miv 0.4.6 → 0.4.7
raw patch · 9 files changed
+133/−166 lines, 9 filesdep +HsYAMLdep +bytestringdep +containersdep −aesondep −hashabledep −yaml
Dependencies added: HsYAML, bytestring, containers
Dependencies removed: aeson, hashable, yaml
Files
- LICENSE +1/−1
- miv.cabal +7/−8
- src/Cmdline.hs +10/−27
- src/Main.hs +22/−21
- src/Mode.hs +18/−17
- src/Plugin.hs +6/−5
- src/ReadText.hs +0/−10
- src/Setting.hs +11/−11
- src/VimScript.hs +58/−66
LICENSE view
@@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2019 itchyny <https://github.com/itchyny>+Copyright (c) 2014-2021 itchyny <https://github.com/itchyny> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
miv.cabal view
@@ -1,5 +1,5 @@ name: miv-version: 0.4.6+version: 0.4.7 author: itchyny <https://github.com/itchyny> maintainer: itchyny <https://github.com/itchyny> license: MIT@@ -22,7 +22,6 @@ , Cmdline , Mapping , ShowText- , ReadText , VimScript , Git , Paths_miv@@ -34,9 +33,9 @@ , SafeSemaphore , time , directory- , hashable- , aeson- , yaml+ , containers+ , HsYAML+ , bytestring , text , unordered-containers , monad-parallel@@ -55,10 +54,10 @@ , process , time , directory- , hashable+ , containers , hspec- , aeson- , yaml+ , HsYAML+ , bytestring , text , unordered-containers , monad-parallel
src/Cmdline.hs view
@@ -1,14 +1,10 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments, LambdaCase, OverloadedStrings #-} module Cmdline where -import Data.Aeson-import qualified Data.Aeson as Aeson-import Data.Hashable-import Data.Text (Text,unpack)+import Data.Text (Text, unpack)+import Data.YAML import Prelude hiding (show)-import qualified Prelude as Prelude -import ReadText import ShowText data Cmdline = CmdlineExCommand@@ -23,26 +19,13 @@ show CmdlineBackwardSearch = "?" show CmdlineInput = "@" -instance ReadText Cmdline where- read ":" = CmdlineExCommand- read "/" = CmdlineForwardSearch- read "?" = CmdlineBackwardSearch- read "@" = CmdlineInput- read m = error $ "unknown cmdline: " ++ unpack m--instance Hashable Cmdline where- hashWithSalt a CmdlineExCommand = a `hashWithSalt` (0 :: Int)- hashWithSalt a CmdlineForwardSearch = a `hashWithSalt` (1 :: Int)- hashWithSalt a CmdlineBackwardSearch = a `hashWithSalt` (2 :: Int)- hashWithSalt a CmdlineInput = a `hashWithSalt` (3 :: Int)--instance FromJSON Cmdline where- parseJSON (Aeson.String str)- | unpack str == ":" = return CmdlineExCommand- | unpack str == "/" = return CmdlineForwardSearch- | unpack str == "?" = return CmdlineBackwardSearch- | unpack str == "@" = return CmdlineInput- parseJSON o = error $ "failed to parse cmdline: " <> Prelude.show o+instance FromYAML Cmdline where+ parseYAML = withStr "!!str" \case+ ":" -> return CmdlineExCommand+ "/" -> return CmdlineForwardSearch+ "?" -> return CmdlineBackwardSearch+ "@" -> return CmdlineInput+ x -> fail $ unpack $ "failed to parse cmdline: " <> x cmdlinePattern :: Cmdline -> Text cmdlinePattern CmdlineExCommand = ":"
src/Main.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+{-# LANGUAGE BlockArguments, OverloadedStrings, ScopedTypeVariables #-} module Main where import Control.Applicative@@ -8,6 +8,7 @@ import Control.Exception import Control.Monad (filterM, forM_, unless, void, when, guard) import qualified Control.Monad.Parallel as P+import qualified Data.ByteString.Lazy as BS import Data.Functor ((<&>)) import Data.List (foldl', isPrefixOf, nub, sort, (\\)) import Data.Maybe (listToMaybe, fromMaybe, isNothing)@@ -16,7 +17,7 @@ import Data.Text.IO (putStrLn, putStr, writeFile, hGetContents) import Data.Time (getZonedTime) import Data.Version (showVersion)-import Data.Yaml (decodeFileEither, prettyPrintParseException)+import qualified Data.YAML as YAML import GHC.Conc (getNumProcessors, setNumCapabilities) import Prelude hiding (readFile, writeFile, unlines, putStrLn, putStr, show) import System.Console.Concurrent ()@@ -75,10 +76,10 @@ maybeFile <- getFirstExistingFile $ return candidates case maybeFile of Just file -> do- maybeSetting <- decodeFileEither file- case maybeSetting of+ cnt <- BS.readFile file+ case YAML.decode1 cnt of Right setting -> return setting- Left err -> error $ prettyPrintParseException err+ Left (pos, err) -> error $ YAML.prettyPosWithSource pos cnt err Nothing -> error $ unpack $ unlines $ "No setting file! Tried following locations:" : map (\x -> " - " <> pack x) candidates@@ -230,13 +231,13 @@ status <- fmap mconcat <$> displayConsoleRegions $ mapM' (\p -> updateOnePlugin time dir update (specified p) p) ps putStrLn $ (if null (failed status) then "Success" else "Error occured") <> " in " <> show update <> "."- unless (null (installed status)) $ do+ unless (null (installed status)) do putStrLn $ "Installed plugin" <> count (installed status) <> ": " mapM_ (putStrLn . (" "<>) . name) (sort (installed status))- unless (null (updated status)) $ do+ unless (null (updated status)) do putStrLn $ "Updated plugin" <> count (updated status) <> ": " mapM_ (putStrLn . (" "<>) . name) (sort (updated status))- unless (null (failed status)) $ do+ unless (null (failed status)) do putStrLn $ "Failed plugin" <> count (failed status) <> ": " mapM_ (putStrLn . (" "<>) . name) (sort (failed status)) generatePluginCode setting@@ -261,13 +262,13 @@ dir <- pluginDirectory let docdir = dir </> "miv" </> "doc" cleanAndCreateDirectory docdir- P.forM_ (map (\p -> dir </> rtpName p </> "doc") (plugins setting)) $ \path -> do+ P.forM_ (map (\p -> dir </> rtpName p </> "doc") (plugins setting)) \path -> do exists <- doesDirectoryExist path when exists $- void $ do (_, _, _, ph) <- createProcess (proc "sh" ["-c", "cp -R * " <> singleQuote docdir]) {- cwd = Just path- }- waitForProcess ph+ void do (_, _, _, ph) <- createProcess (proc "sh" ["-c", "cp -R * " <> singleQuote docdir]) {+ cwd = Just path+ }+ waitForProcess ph _ <- system $ "vim -u NONE -i NONE -N -e -s -c 'helptags " <> docdir <> "' -c quit" putStrLn "Success in processing helptags." @@ -288,12 +289,12 @@ exists <- doesDirectoryExist path gitstatus <- gitStatus path if not exists || (gitstatus /= ExitSuccess && not (sync plugin))- then withConsoleRegion Linear $ \region -> do+ then withConsoleRegion Linear \region -> do putStrLn' region "Installing" when exists $ removeDirectoryRecursive path cloneStatus <- execCommand (unpack $ name plugin) region dir $ cloneCommand repo path created <- doesDirectoryExist path- when created $ do+ when created do buildPlugin path region changeModifiedTime path =<< lastUpdate path if cloneStatus /= ExitSuccess || not created@@ -301,7 +302,7 @@ else return mempty { installed = [plugin] } else if update == Install || not (sync plugin) then return mempty { nosync = [plugin] }- else withConsoleRegion Linear $ \region -> do+ else withConsoleRegion Linear \region -> do lastUpdateTime <- lastUpdate path if lastUpdateTime < time - 60 * 60 * 24 * 30 && not specified then do@@ -386,7 +387,7 @@ putStr "Really? [y/N] " hFlush stdout c <- getChar- when (c == 'y' || c == 'Y') $ do+ when (c == 'y' || c == 'Y') do mapM_ removeDirectoryRecursive deldirs mapM_ removeFile $ delfiles else putStrLn "Clean."@@ -440,12 +441,12 @@ gatherFtdetectScript setting = do dir <- pluginDirectory cleanAndCreateDirectory (dir </> "miv" </> "ftdetect")- forM_ (plugins setting) $ \plugin -> do+ forM_ (plugins setting) \plugin -> do let path = rtpName plugin exists <- doesDirectoryExist (dir </> path </> "ftdetect")- when exists $ do+ when exists do files <- listDirectory (dir </> path </> "ftdetect")- forM_ files $ \file ->+ forM_ files \file -> copyFile (dir </> path </> "ftdetect" </> file) (dir </> "miv" </> "ftdetect" </> file) putStrLn "Success in gathering ftdetect scripts." @@ -462,7 +463,7 @@ createPluginDirectory dir <- pluginDirectory status <- mconcat <$> mapM (eachOnePlugin command dir) (plugins setting)- unless (null (failed' status)) $ do+ unless (null (failed' status)) do putStrLn "Error:" mapM_ (putStrLn . (" "<>) . name) (failed' status)
src/Mode.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments, LambdaCase, OverloadedStrings #-} module Mode where import Data.Text (unpack)+import Data.YAML -import ReadText import ShowText data Mode = NormalMode@@ -18,7 +18,7 @@ | InsertNormalMode | InesrtVisualMode | InsertSelectMode- deriving Eq+ deriving (Eq, Ord) instance ShowText Mode where show NormalMode = "n"@@ -34,17 +34,18 @@ show InesrtVisualMode = "iv" show InsertSelectMode = "is" -instance ReadText Mode where- read "n" = NormalMode- read "v" = VisualMode- read "s" = SelectMode- read "i" = InsertMode- read "c" = CmdlineMode- read "ex" = ExMode- read "o" = OperatorPendingMode- read "r" = ReplaceMode- read "vr" = VirtualReplaceMode- read "in" = InsertNormalMode- read "iv" = InesrtVisualMode- read "is" = InsertSelectMode- read m = error $ "unknown mode: " ++ unpack m+instance FromYAML Mode where+ parseYAML = withStr "!!str" \case+ "n" -> return NormalMode+ "v" -> return VisualMode+ "s" -> return SelectMode+ "i" -> return InsertMode+ "c" -> return CmdlineMode+ "ex" -> return ExMode+ "o" -> return OperatorPendingMode+ "r" -> return ReplaceMode+ "vr" -> return VirtualReplaceMode+ "in" -> return InsertNormalMode+ "iv" -> return InesrtVisualMode+ "is" -> return InsertSelectMode+ x -> fail $ unpack $ "failed to parse mode: " <> x
src/Plugin.hs view
@@ -1,12 +1,13 @@-{-# LANGUAGE OverloadedStrings, RecordWildCards #-}+{-# LANGUAGE BlockArguments, OverloadedStrings, RecordWildCards #-} module Plugin where import Control.Applicative ((<|>))-import Data.Aeson import qualified Data.Text as T import Data.Text (Text, unpack)+import Data.YAML import Cmdline+import Mode import ShowText data Plugin =@@ -15,7 +16,7 @@ , commands :: [Text] , functions :: [Text] , mappings :: [Text]- , mapmodes :: [Text]+ , mapmodes :: [Mode] , cmdlines :: [Cmdline] , insert :: Bool , enable :: Text@@ -44,8 +45,8 @@ rtpName :: Plugin -> String rtpName = unpack . ShowText.show -instance FromJSON Plugin where- parseJSON = withObject "plugin" $ \o -> do+instance FromYAML Plugin where+ parseYAML = withMap "!!map" \o -> do name <- o .:? "name" .!= "" filetypes <- o .: "filetype" <|> (fmap return <$> o .:? "filetype") .!= [] commands <- o .: "command" <|> (fmap return <$> o .:? "command") .!= []
− src/ReadText.hs
@@ -1,10 +0,0 @@-{-# LANGUAGE FlexibleInstances, IncoherentInstances, UndecidableInstances #-}-module ReadText where--import Data.Text--class ReadText a where- read :: Text -> a--instance Read a => ReadText a where- read = Prelude.read . unpack
src/Setting.hs view
@@ -1,32 +1,32 @@-{-# LANGUAGE OverloadedStrings, RecordWildCards #-}+{-# LANGUAGE BlockArguments, OverloadedStrings, RecordWildCards #-} module Setting where -import Data.Aeson import Data.Function (on)-import qualified Data.HashMap.Lazy as HM import Data.List (sortBy)+import qualified Data.Map.Strict as M import Data.Text (Text, lines)+import Data.YAML import Prelude hiding (lines) import Plugin data Setting = Setting { plugins :: [Plugin]- , filetype :: HM.HashMap Text [Text]- , syntax :: HM.HashMap Text [Text]+ , filetype :: M.Map Text [Text]+ , syntax :: M.Map Text [Text] , before :: [Text] , after :: [Text] } deriving Eq -instance FromJSON Setting where- parseJSON = withObject "setting" $ \o -> do- plugins <- pluginHashMapToList <$> o .:? "plugin" .!= HM.empty- filetype <- HM.map lines <$> o .:? "filetype" .!= HM.empty- syntax <- HM.map lines <$> o .:? "syntax" .!= HM.empty+instance FromYAML Setting where+ parseYAML = withMap "!!map" \o -> do+ plugins <- pluginMapToList <$> o .:? "plugin" .!= M.empty+ filetype <- M.map lines <$> o .:? "filetype" .!= M.empty+ syntax <- M.map lines <$> o .:? "syntax" .!= M.empty before <- lines <$> o .:? "before" .!= "" after <- lines <$> o .:? "after" .!= "" return Setting {..}- where pluginHashMapToList = sortWith name . HM.foldlWithKey' (\a k v -> v { name = k } : a) []+ where pluginMapToList = sortWith name . M.foldlWithKey' (\a k v -> v { name = k } : a) [] sortWith :: Ord b => (a -> b) -> [a] -> [a] sortWith = sortBy . on compare
src/VimScript.hs view
@@ -3,37 +3,28 @@ import Data.Char (isAlpha, isAlphaNum, ord, toLower) import Data.Function (on)-import Data.Hashable-import qualified Data.HashMap.Lazy as HM import Data.List (foldl', groupBy, sort, sortBy, nub)+import qualified Data.Map.Strict as M import Data.Text (Text, singleton, unpack, unwords) import qualified Data.Text as T-import GHC.Generics (Generic)-import Prelude hiding (show, unwords, read)+import Prelude hiding (show, unwords) import Cmdline import qualified Command as C import qualified Mapping as M import Mode import qualified Plugin as P-import ReadText import qualified Setting as S import ShowText -data VimScript = VimScript (HM.HashMap Place [Text])+data VimScript = VimScript (M.Map Place [Text]) deriving (Eq) data Place = Plugin | Autoload Text | Ftplugin Text | Syntax Text- deriving (Eq, Generic)--instance Hashable Place where- hashWithSalt a Plugin = a `hashWithSalt` (0 :: Int) `hashWithSalt` ("" :: Text)- hashWithSalt a (Autoload s) = a `hashWithSalt` (1 :: Int) `hashWithSalt` s- hashWithSalt a (Ftplugin s) = a `hashWithSalt` (2 :: Int) `hashWithSalt` s- hashWithSalt a (Syntax s) = a `hashWithSalt` (3 :: Int) `hashWithSalt` s+ deriving (Eq, Ord) instance ShowText Place where show Plugin = "plugin/miv.vim"@@ -43,20 +34,20 @@ show (Syntax s) = "syntax/" <> s <> ".vim" vimScriptToList :: VimScript -> [(Place, [Text])]-vimScriptToList (VimScript x) = HM.toList x+vimScriptToList (VimScript x) = M.toList x instance Semigroup VimScript where VimScript x <> VimScript y- | HM.null x = VimScript y- | HM.null y = VimScript x- | otherwise = VimScript (HM.unionWith concat' x y)+ | M.null x = VimScript y+ | M.null y = VimScript x+ | otherwise = VimScript (M.unionWith concat' x y) where concat' a [] = a concat' [] b = b concat' a b = a <> [""] <> b instance Monoid VimScript where- mempty = VimScript HM.empty+ mempty = VimScript M.empty gatherScript :: S.Setting -> VimScript gatherScript setting = beforeScript setting@@ -64,7 +55,7 @@ <> gather' "dependon" P.dependon P.loadbefore plugins <> gather' "dependedby" P.dependedby P.loadafter plugins <> gather "mappings" P.mappings plugins- <> gather "mapmodes" P.mapmodes plugins+ <> gather "mapmodes" (map show . P.mapmodes) plugins <> gather "functions" P.functions plugins <> pluginLoader <> mappingLoader@@ -80,30 +71,30 @@ where plugins = S.plugins setting gatherBeforeAfterScript :: [P.Plugin] -> VimScript-gatherBeforeAfterScript x = insertAuNameMap $ gatherScripts x (mempty, HM.empty)+gatherBeforeAfterScript x = insertAuNameMap $ gatherScripts x (mempty, M.empty) where- insertAuNameMap :: (VimScript, HM.HashMap Text Text) -> VimScript- insertAuNameMap (vs, hm) = VimScript (HM.singleton (Autoload "") $+ insertAuNameMap :: (VimScript, M.Map Text Text) -> VimScript+ insertAuNameMap (vs, m) = VimScript (M.singleton (Autoload "") $ [ "let s:autoload = {" ]- <> [ " \\ " <> singleQuote k <> ": " <> singleQuote a <> "," | (k, a) <- HM.toList hm ]+ <> [ " \\ " <> singleQuote k <> ": " <> singleQuote a <> "," | (k, a) <- M.toList m ] <> [ " \\ }" ]) <> vs- gatherScripts :: [P.Plugin] -> (VimScript, HM.HashMap Text Text) -> (VimScript, HM.HashMap Text Text)- gatherScripts (p:ps) (vs, hm)- | null (P.before p) && null (P.after p) = gatherScripts ps (vs, hm)- | otherwise = gatherScripts ps (vs <> vs', HM.insert name hchar hm)+ gatherScripts :: [P.Plugin] -> (VimScript, M.Map Text Text) -> (VimScript, M.Map Text Text)+ gatherScripts (p:ps) (vs, m)+ | null (P.before p) && null (P.after p) = gatherScripts ps (vs, m)+ | otherwise = gatherScripts ps (vs <> vs', M.insert name hchar m) where name = T.filter isAlphaNum (T.toLower (show p)) hchar | null (loadScript p) = maybe "_" singleton $ getHeadChar $ show p | otherwise = "_" funcname str = "miv#" <> hchar <> "#" <> str <> "_" <> name- vs' = VimScript $ HM.singleton (Autoload hchar) $+ vs' = VimScript $ M.singleton (Autoload hchar) $ wrapFunction (funcname "before") (P.before p) <> wrapFunction (funcname "after") (P.after p)- gatherScripts [] (vs, hm) = (vs, hm)+ gatherScripts [] (vs, m) = (vs, m) gather :: Text -> (P.Plugin -> [Text]) -> [P.Plugin] -> VimScript gather name f plg- = VimScript (HM.singleton (Autoload "") $+ = VimScript (M.singleton (Autoload "") $ [ "let s:" <> name <> " = {" ] <> [ " \\ " <> singleQuote (show p) <> ": [ " <> T.intercalate ", " (map singleQuote (f p)) <> " ],"@@ -113,7 +104,7 @@ gather' :: Text -> (P.Plugin -> [Text]) -> (P.Plugin -> [Text]) -> [P.Plugin] -> VimScript gather' name f g plg- = VimScript (HM.singleton (Autoload "") $+ = VimScript (M.singleton (Autoload "") $ [ "let s:" <> name <> " = {" ] <> [ " \\ " <> singleQuote p <> ": [ " <> T.intercalate ", " (map singleQuote $ sort $ nub q) <> " ],"@@ -129,7 +120,7 @@ pluginConfig :: P.Plugin -> VimScript pluginConfig plg- = VimScript (HM.singleton Plugin $ wrapInfo $+ = VimScript (M.singleton Plugin $ wrapInfo $ wrapEnable (P.enable plg) $ mapleader <> gatherCommand plg <> gatherMapping plg <> P.script plg <> loadScript plg) where wrapInfo [] = []@@ -146,37 +137,38 @@ gatherCommand :: P.Plugin -> [Text] gatherCommand plg | not (null (P.commands plg))- = [show (C.defaultCommand { C.cmdName = c- , C.cmdRepText = unwords ["call miv#command(" <> singleQuote (show plg) <> ","- , singleQuote c <> ","- , singleQuote "<bang>" <> ","- , "<q-args>,"- , "expand('<line1>'),"- , "expand('<line2>'))" ] }) | c <- P.commands plg]+ = [show C.defaultCommand+ { C.cmdName = c,+ C.cmdRepText = unwords [+ "call miv#command(" <> singleQuote (show plg) <> ",",+ singleQuote c <> ",",+ singleQuote "<bang>" <> ",",+ "<q-args>,",+ "expand('<line1>'),",+ "expand('<line2>'))"+ ] } | c <- P.commands plg] | otherwise = [] gatherMapping :: P.Plugin -> [Text] gatherMapping plg | not (null (P.mappings plg))- = let genMapping- = [\mode ->- M.defaultMapping- { M.mapName = c- , M.mapRepText = escape mode <> ":<C-u>call miv#mapping("- <> singleQuote (show plg) <> ", "- <> singleQuote c <> ", "- <> singleQuote (show mode) <> ")<CR>"- , M.mapMode = mode } | c <- P.mappings plg]- escape m = if m `elem` [ InsertMode, OperatorPendingMode ] then "<ESC>" else ""- modes = if null (P.mapmodes plg) then [NormalMode] else map read (P.mapmodes plg)- in concat [map (show . f) modes | f <- genMapping]+ = [show M.defaultMapping+ { M.mapName = mapping,+ M.mapRepText = escape mode <> ":<C-u>call miv#mapping("+ <> singleQuote (show plg) <> ", "+ <> singleQuote mapping <> ", "+ <> singleQuote (show mode) <> ")<CR>",+ M.mapMode = mode+ } | mapping <- P.mappings plg, mode <- modes] | otherwise = []+ where modes = if null (P.mapmodes plg) then [NormalMode] else P.mapmodes plg+ escape mode = if mode `elem` [InsertMode, OperatorPendingMode] then "<ESC>" else "" beforeScript :: S.Setting -> VimScript-beforeScript setting = VimScript (HM.singleton Plugin (S.before setting))+beforeScript setting = VimScript (M.singleton Plugin (S.before setting)) afterScript :: S.Setting -> VimScript-afterScript setting = VimScript (HM.singleton Plugin (S.after setting))+afterScript setting = VimScript (M.singleton Plugin (S.after setting)) filetypeLoader :: S.Setting -> VimScript filetypeLoader setting@@ -186,12 +178,12 @@ 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+ in VimScript (M.singleton Plugin [ "augroup miv-file-type-" <> ft , " autocmd!" , " autocmd FileType " <> ft <> " call " <> funcname <> "()" , "augroup END" ]) <>- VimScript (HM.singleton (Autoload (singleton c)) $+ VimScript (M.singleton (Autoload (singleton c)) $ ("function! " <> funcname <> "() abort") : " setlocal filetype=" : loadPlugins plugins@@ -221,10 +213,10 @@ singleQuote str = "'" <> str <> "'" filetypeScript :: S.Setting -> VimScript-filetypeScript = foldMap (\(ft, src) -> VimScript (HM.singleton (Ftplugin ft) src)) . HM.toList . S.filetype+filetypeScript = foldMap (\(ft, src) -> VimScript (M.singleton (Ftplugin ft) src)) . M.toList . S.filetype syntaxScript :: S.Setting -> VimScript-syntaxScript = foldMap (\(ft, src) -> VimScript (HM.singleton (Syntax ft) src)) . HM.toList . S.syntax+syntaxScript = foldMap (\(ft, src) -> VimScript (M.singleton (Syntax ft) src)) . M.toList . S.syntax wrapFunction :: Text -> [Text] -> [Text] wrapFunction funcname script =@@ -238,7 +230,7 @@ | otherwise = let x = T.head xs in if isAlpha x then Just (toLower x) else getHeadChar (T.tail xs) mappingLoader :: VimScript-mappingLoader = VimScript (HM.singleton (Autoload "")+mappingLoader = VimScript (M.singleton (Autoload "") [ "function! miv#mapping(name, mapping, mode) abort" , " call miv#load(a:name)" , " if a:mode ==# 'v' || a:mode ==# 'x'"@@ -252,7 +244,7 @@ , "endfunction" ]) commandLoader :: VimScript-commandLoader = VimScript (HM.singleton (Autoload "")+commandLoader = VimScript (M.singleton (Autoload "") [ "function! miv#command(name, command, bang, args, line1, line2) abort" , " silent! execute 'delcommand' a:command" , " call miv#load(a:name)"@@ -266,13 +258,13 @@ funcUndefinedLoader :: S.Setting -> VimScript funcUndefinedLoader setting = if null functions then mempty else- VimScript (HM.singleton Plugin+ VimScript (M.singleton Plugin [ "\" FuncUndefined" , "augroup miv-func-undefined" , " autocmd!" , " autocmd FuncUndefined * call miv#func_undefined(expand('<amatch>'))" , "augroup END" ])- <> VimScript (HM.singleton (Autoload "")+ <> VimScript (M.singleton (Autoload "") [ "function! miv#func_undefined(pattern) abort" , " if a:pattern !~# " <> singleQuote (T.intercalate "\\|" functions) , " return"@@ -299,7 +291,7 @@ collectSndByFst [(cmdline, p) | p <- S.plugins setting, cmdline <- P.cmdlines p] where f :: Cmdline -> [P.Plugin] -> VimScript- f cmdline plugins = VimScript (HM.singleton Plugin+ f cmdline plugins = VimScript (M.singleton Plugin [ "\" CmdlineEnter " <> (show cmdline) , "if exists('#CmdlineEnter')" , " augroup " <> group@@ -309,7 +301,7 @@ , "else" , " call miv#cmdline_enter_" <> c <> "()" , "endif" ])- <> VimScript (HM.singleton (Autoload "") $+ <> VimScript (M.singleton (Autoload "") $ ("function! miv#cmdline_enter_" <> c <> "() abort") : loadPlugins plugins <> [ " if exists('#CmdlineEnter')"@@ -322,13 +314,13 @@ insertEnterLoader :: S.Setting -> VimScript insertEnterLoader setting = if null plugins then mempty else- VimScript (HM.singleton Plugin+ VimScript (M.singleton Plugin [ "\" InsertEnter" , "augroup miv-insert-enter" , " autocmd!" , " autocmd InsertEnter * call miv#insert_enter()" , "augroup END" ])- <> VimScript (HM.singleton (Autoload "")+ <> VimScript (M.singleton (Autoload "") $ "function! miv#insert_enter() abort" : loadPlugins plugins <> [ " autocmd! miv-insert-enter"@@ -338,7 +330,7 @@ where plugins = filter P.insert (S.plugins setting) pluginLoader :: VimScript-pluginLoader = VimScript (HM.singleton (Autoload "")+pluginLoader = VimScript (M.singleton (Autoload "") [ "let s:loaded = {}" , "let s:path = expand('<sfile>:p:h:h')" , "let s:mivpath = expand('<sfile>:p:h:h:h') . '/'"