packages feed

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 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') . '/'"