Skip to content

Commit

Permalink
implement CmdlineEnter loader
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Nov 7, 2020
1 parent 0b204fe commit 94439f3
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ Shows the version of `miv`.
- `function`: load the plugin on calling a function matching the value in regex
- `mapping`: load the plugin on the mapping
- `mapmode`: specify the mapmode for the `mapping` configuration (for example: `o`, `v`)
- `cmdline`: specify the cmdline character to load the plugin (for example: `:`, `/`)
- `insert`: load the plugin on entering the insert mode for the first time
- `enable`: enable the plugin when the expression (in Vim script) is 1
- `mapleader`: specify the mapleader (`<Leader>`) for the `script` configuration
Expand Down
1 change: 1 addition & 0 deletions miv.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ executable miv
, Setting
, Mode
, Command
, Cmdline
, Mapping
, ShowText
, ReadText
Expand Down
51 changes: 51 additions & 0 deletions src/Cmdline.hs
Original file line number Diff line number Diff line change
@@ -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 = "@"
3 changes: 3 additions & 0 deletions src/Plugin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Data.Aeson
import qualified Data.Text as T
import Data.Text (Text, unpack)

import Cmdline
import ShowText

data Plugin =
Expand All @@ -15,6 +16,7 @@ data Plugin =
, functions :: [Text]
, mappings :: [Text]
, mapmodes :: [Text]
, cmdlines :: [Cmdline]
, insert :: Bool
, enable :: Text
, sync :: Bool
Expand Down Expand Up @@ -50,6 +52,7 @@ instance FromJSON Plugin where
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" .!= ""
Expand Down
31 changes: 28 additions & 3 deletions src/VimScript.hs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -78,6 +79,7 @@ gatherScript setting = addAutoloadNames
<> foldl' (<>) mempty (map pluginConfig plugins)
<> filetypeLoader setting
<> funcUndefinedLoader setting
<> cmdlineEnterLoader setting
<> insertEnterLoader setting
<> filetypeScript (S.filetype setting)
<> syntaxScript (S.syntax setting)
Expand Down Expand Up @@ -151,7 +153,7 @@ pluginConfig plg
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 = []

Expand Down Expand Up @@ -312,6 +314,29 @@ funcUndefinedLoader _ = VimScript (HM.singleton Plugin
, "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"
Expand Down

0 comments on commit 94439f3

Please sign in to comment.