packages feed

miv 0.4.4 → 0.4.5

raw patch · 4 files changed

+139/−45 lines, 4 files

Files

miv.cabal view
@@ -1,5 +1,5 @@ name:                   miv-version:                0.4.4+version:                0.4.5 author:                 itchyny <https://github.com/itchyny> maintainer:             itchyny <https://github.com/itchyny> license:                MIT@@ -19,6 +19,7 @@                       , Setting                       , Mode                       , Command+                      , Cmdline                       , Mapping                       , ShowText                       , ReadText
+ src/Cmdline.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE OverloadedStrings #-}+module Cmdline where++import Data.Aeson+import qualified Data.Aeson as Aeson+import Data.Hashable+import Data.Text (Text,unpack)+import Prelude hiding (show)+import qualified Prelude as Prelude++import ReadText+import ShowText++data Cmdline = CmdlineExCommand+             | CmdlineForwardSearch+             | CmdlineBackwardSearch+             | CmdlineInput+             deriving (Eq, Ord)++instance ShowText Cmdline where+  show CmdlineExCommand      = ":"+  show CmdlineForwardSearch  = "/"+  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++cmdlinePattern :: Cmdline -> Text+cmdlinePattern CmdlineExCommand      = ":"+cmdlinePattern CmdlineForwardSearch  = "/"+cmdlinePattern CmdlineBackwardSearch = "\\?"+cmdlinePattern CmdlineInput          = "@"
src/Plugin.hs view
@@ -6,6 +6,7 @@ import qualified Data.Text as T import Data.Text (Text, unpack) +import Cmdline import ShowText  data Plugin =@@ -15,6 +16,7 @@             , functions  :: [Text]             , mappings   :: [Text]             , mapmodes   :: [Text]+            , cmdlines   :: [Cmdline]             , insert     :: Bool             , enable     :: Text             , sync       :: Bool@@ -50,6 +52,7 @@     functions <- o .: "function" <|> (fmap return <$> o .:? "function") .!= []     mappings <- o .: "mapping" <|> (fmap return <$> o .:? "mapping") .!= []     mapmodes <- o .: "mapmode" <|> (fmap return <$> o .:? "mapmode") .!= []+    cmdlines <- o .: "cmdline" <|> (fmap return <$> o .:? "cmdline") .!= []     mapleader <- o .:? "mapleader" .!= ""     insert <- o .:? "insert" .!= False     enable <- o .:? "enable" .!= ""
src/VimScript.hs view
@@ -1,17 +1,18 @@ {-# LANGUAGE DeriveGeneric, OverloadedStrings #-} module VimScript where -import Data.Char (isAlpha, isAlphaNum, toLower)+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 Data.Maybe (mapMaybe)-import Data.Text (Text, unwords, singleton)+import Data.Text (Text, singleton, unpack, unwords) import qualified Data.Text as T import GHC.Generics (Generic) import Prelude hiding (show, unwords, read) +import Cmdline import qualified Command as C import qualified Mapping as M import Mode@@ -33,7 +34,7 @@   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` (2 :: Int) `hashWithSalt` s+  hashWithSalt a (Syntax s)   = a `hashWithSalt` (3 :: Int) `hashWithSalt` s  instance ShowText Place where   show Plugin        = "plugin/miv.vim"@@ -71,13 +72,15 @@                     <> gather' "dependedby" P.dependedby P.loadafter plugins                     <> gather "mappings" P.mappings plugins                     <> gather "mapmodes" P.mapmodes plugins-                    <> gatherFuncUndefined setting+                    <> gather "functions" P.functions plugins                     <> pluginLoader                     <> mappingLoader                     <> commandLoader                     <> foldl' (<>) mempty (map pluginConfig plugins)                     <> filetypeLoader setting-                    <> gatherInsertEnter setting+                    <> funcUndefinedLoader setting+                    <> cmdlineEnterLoader setting+                    <> insertEnterLoader setting                     <> filetypeScript (S.filetype setting)                     <> syntaxScript (S.syntax setting)                     <> afterScript setting@@ -150,7 +153,7 @@ loadScript :: P.Plugin -> [Text] loadScript plg   | all null [ P.commands plg, P.mappings plg, P.functions plg, P.filetypes plg-             , P.loadafter plg, P.loadbefore plg ] && not (P.insert plg)+             , P.loadafter plg, P.loadbefore plg ] && null (P.cmdlines plg) && not (P.insert plg)   = ["call miv#load(" <> singleQuote (show plg) <> ")"]   | otherwise = [] @@ -179,7 +182,7 @@                         <> 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, VisualMode] else map read (P.mapmodes plg)+          modes = if null (P.mapmodes plg) then [NormalMode] else map read (P.mapmodes plg)           in concat [map (show . f) modes | f <- genMapping]   | otherwise = [] @@ -201,11 +204,12 @@                  in val                   <> VimScript (HM.singleton (Autoload (singleton c))                        (("function! " <> funcname <> "() abort")-                       : "  setl ft="+                       : "  setlocal filetype="                        :  concat [wrapEnable b                        [ "  call miv#load(" <> singleQuote (show b) <> ")"] | b <- plg]                     <> [ "  autocmd! miv-file-type-" <> ft-                       , "  setl ft=" <> ft+                       , "  augroup! miv-file-type-" <> ft+                       , "  setlocal filetype=" <> ft                        , "  silent! doautocmd FileType " <> ft                        , "endfunction"                        ]))@@ -223,40 +227,6 @@   | otherwise = filetypeLoadPlugins plugins fts filetypeLoadPlugins [] fts = fts -gatherInsertEnter :: S.Setting -> VimScript-gatherInsertEnter setting-  = VimScript (HM.singleton Plugin (f [ p | p <- S.plugins setting, P.insert p ]))-  where f [] = []-        f plgs = "\" InsertEnter"-               : "function! s:insertEnter() abort"-             : [ "  call miv#load(" <> singleQuote (show p) <> ")" | p <- plgs :: [P.Plugin] ]-            <> [ "  autocmd! miv-insert-enter"-               , "  silent! doautocmd InsertEnter"-               , "endfunction"-               , ""-               , "augroup miv-insert-enter"-               , "  autocmd!"-               , "  autocmd InsertEnter * call s:insertEnter()"-               , "augroup END" ]--gatherFuncUndefined :: S.Setting -> VimScript-gatherFuncUndefined setting-  = VimScript (HM.singleton Plugin (f [ p | p <- S.plugins setting, not (null (P.functions p))]))-  where f [] = []-        f plgs = "\" FuncUndefined"-               : "function! s:funcUndefined() abort"-               : "  let f = expand('<amatch>')"-               : concat [-               [ "  if f =~# " <> singleQuote q-               , "    call miv#load(" <> singleQuote (show p) <> ")"-               , "  endif" ] | (p, q) <- concatMap (\q -> map ((,) q) (P.functions q)) plgs]-            <> [ "endfunction"-               , ""-               , "augroup miv-func-undefined"-               , "  autocmd!"-               , "  autocmd FuncUndefined * call s:funcUndefined()"-               , "augroup END" ]- wrapEnable :: P.Plugin -> [Text] -> [Text] wrapEnable plg str   | null str = []@@ -318,6 +288,72 @@   , "endfunction"   ]) +funcUndefinedLoader :: S.Setting -> VimScript+funcUndefinedLoader setting | all (null . P.functions) (S.plugins setting) = mempty+funcUndefinedLoader _ = VimScript (HM.singleton Plugin+  [ "\" FuncUndefined"+  , "augroup miv-func-undefined"+  , "  autocmd!"+  , "  autocmd FuncUndefined * call miv#func_undefined(expand('<amatch>'))"+  , "augroup END" ])+  <> VimScript (HM.singleton (Autoload "")+  [ "function! miv#func_undefined(pattern) abort"+  , "  if empty(s:functions)"+  , "    autocmd! miv-func-undefined"+  , "    augroup! miv-func-undefined"+  , "    return"+  , "  endif"+  , "  for [name, fs] in items(s:functions)"+  , "    for f in fs"+  , "      if a:pattern =~# f"+  , "        call miv#load(name)"+  , "        return"+  , "      endif"+  , "    endfor"+  , "  endfor"+  , "endfunction"+  ])++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 ]+  where+    f :: Cmdline -> [P.Plugin] -> VimScript -> VimScript+    f cmdline plugins val = val <> VimScript (HM.singleton Plugin+      [ "\" CmdlineEnter " <> (show cmdline)+      , "augroup " <> group+      , "  autocmd!"+      , "  autocmd CmdlineEnter " <> (cmdlinePattern cmdline) <> " call miv#cmdline_enter_" <> c <> "()"+      , "augroup END" ])+      <> VimScript (HM.singleton (Autoload "") $+       ("function! miv#cmdline_enter_" <> c <> "() abort") :+      [ "  call miv#load(" <> singleQuote (show p) <> ")" | p <- plugins ]+      <> [ "  autocmd! " <> group+      , "  augroup! " <> group+      , "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+  [ "\" 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 ]+  <> [ "  autocmd! miv-insert-enter"+  , "  augroup! miv-insert-enter"+  , "  silent! doautocmd InsertEnter"+  , "endfunction"+  ])+  where plugins = filter P.insert (S.plugins setting)+ pluginLoader :: VimScript pluginLoader = VimScript (HM.singleton (Autoload "")   [ "let s:loaded = {}"@@ -328,10 +364,13 @@   , "    return"   , "  endif"   , "  let s:loaded[a:name] = 1"+  , "  if has_key(s:functions, a:name)"+  , "    call remove(s:functions, a:name)"+  , "  endif"   , "  for n in get(s:dependon, a:name, [])"   , "    call miv#load(n)"   , "  endfor"-  , "  for mode in get(s:mapmodes, a:name, [ 'n', 'v' ])"+  , "  for mode in get(s:mapmodes, a:name, ['n'])"   , "    for mapping in get(s:mappings, a:name, [])"   , "      silent! execute mode . 'unmap' mapping"   , "    endfor"