Skip to content

Commit

Permalink
feat: Add "line" and "filter" placeholder filters
Browse files Browse the repository at this point in the history
  • Loading branch information
myme committed Nov 13, 2024
1 parent 3bbd8da commit 102d5a1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 34 deletions.
4 changes: 4 additions & 0 deletions src/Nixon/Command/Placeholder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ data Placeholder = Placeholder
name :: Text,
-- | The field numbers to extract
format :: PlaceholderFormat,
-- | The filter to apply
filter :: Maybe Text,
-- | If the placeholder just lists the available options
list :: Bool,
-- | If the placeholder can select multiple
multiple :: Bool,
-- | Pre-expanded value of the placeholder
Expand Down
14 changes: 9 additions & 5 deletions src/Nixon/Command/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import Control.Arrow ((&&&))
import Control.Monad (foldM)
import Data.Aeson (eitherDecodeStrict)
import Data.Foldable (find)
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import qualified Nixon.Backend.Fzf as Fzf
import Nixon.Command (Command)
import qualified Nixon.Command as Cmd
import Nixon.Command.Find (findProjectCommands)
Expand All @@ -23,7 +25,7 @@ import Nixon.Process (run_with_output)
import qualified Nixon.Process
import Nixon.Project (Project)
import qualified Nixon.Project as Project
import Nixon.Select (Selection (..), Selector, selector_format, selector_multiple)
import Nixon.Select (Selection (..), Selector, selector_format, selector_multiple, selector_search)
import qualified Nixon.Select as Select
import Nixon.Types (Nixon)
import Nixon.Utils (shell_to_list, toLines)
Expand Down Expand Up @@ -55,24 +57,26 @@ resolveEnv project selector cmd args = do
zipArgs :: [P.Placeholder] -> [Text] -> [(P.Placeholder, Select.SelectorOpts)]
zipArgs [] args' = map ((,Select.defaults) . argOverflow) args'
where
argOverflow = P.Placeholder P.Arg "arg" P.Lines False . pure
argOverflow = P.Placeholder P.Arg "arg" P.Lines Nothing False False . pure
zipArgs placeholders [] = map (,Select.defaults) placeholders
zipArgs (p : ps) (a : as) = (p, Select.search a) : zipArgs ps as

-- | Resolve all command placeholders to either stdin input, positional arguments or env vars.
resolveEnv' :: Project -> Selector Nixon -> [(P.Placeholder, Select.SelectorOpts)] -> Nixon (Maybe (Shell Text), [Text], Nixon.Process.Env)
resolveEnv' project selector = foldM resolveEach (Nothing, [], [])
where
resolveEach (stdin, args', envs) (P.Placeholder envType cmdName format' multiple value, select_opts) = do
resolveEach (stdin, args', envs) (P.Placeholder envType cmdName format' search list multiple value, select_opts) = do
resolved <- case value of
[] -> do
let selector' = if list then const (Fzf.fzf $ Fzf.fzfFilter $ fromMaybe "" search) else selector
cmd' <- assertCommand cmdName
let select_opts' =
select_opts
{ selector_format = format',
selector_multiple = Just multiple
selector_multiple = Just multiple,
selector_search = search
}
resolveCmd project selector cmd' select_opts'
resolveCmd project selector' cmd' select_opts'
_ -> pure value
case envType of
-- Standard inputs are concatenated
Expand Down
16 changes: 13 additions & 3 deletions src/Nixon/Config/Markdown.hs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ parseCommandPlaceholder = do
P.EnvVar "" -> P.EnvVar $ fixup name
P.EnvVar alias -> P.EnvVar $ fixup alias
same -> same
pure $ P.Placeholder placeholderWithName name P.Lines False []
pure $ P.Placeholder placeholderWithName name P.Lines Nothing False False []
parsePlaceholderModifiers placeholder <* P.char '}'

-- | Parse the "modifiers" which affect how command placeholders are handled.
Expand Down Expand Up @@ -358,8 +358,10 @@ parsePlaceholderModifiers placeholder = do
_ <- P.many P.space *> P.char '|' *> P.many P.space
p' <-
P.choice
[ parsePipeFields p,
parsePipeMultiple p
[ P.try $ parsePipeFields p,
P.try $ parsePipeFilter p,
P.try $ parsePipeList p,
P.try $ parsePipeMultiple p
]
_ <- P.many P.space
P.option p' (parsePipeModifiers p')
Expand All @@ -373,6 +375,14 @@ parsePlaceholderModifiers placeholder = do
<|> (P.string "fields" *> P.many P.space *> parseFields P.Fields p)
<|> (P.string "json" $> p {P.format = P.JSON})

-- Parse `filter "some-filter"`
parsePipeFilter p = do
_ <- (P.string "filter" :: Parser String) *> P.many P.space
f <- P.between (P.char '"') (P.char '"') (P.many P.alphaNum)
pure p {P.filter = Just $ pack f}

parsePipeList p = (P.string "list" :: Parser String) $> p {P.list = True}

parsePipeMultiple p = (P.string "multi" :: Parser String) $> p {P.multiple = True}

-- Parse `command-name:1,2`
Expand Down
60 changes: 34 additions & 26 deletions test/Test/Nixon/Config/Markdown.hs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ command_tests = describe "commands section" $ do
"```"
]
selector = fmap (Cmd.cmdName &&& Cmd.cmdPlaceholders) . Cfg.commands
placeholder = Placeholder Arg "placeholder" (Columns False [1]) False []
placeholder = Placeholder Arg "placeholder" (Columns False [1]) Nothing False False []
in selector <$> result `shouldBe` Right [("hello", [placeholder])]

it "detects columns with header output format"
Expand All @@ -340,7 +340,7 @@ command_tests = describe "commands section" $ do
"```"
]
selector = fmap (Cmd.cmdName &&& Cmd.cmdPlaceholders) . Cfg.commands
placeholder = Placeholder Arg "placeholder" (Columns True [1]) False []
placeholder = Placeholder Arg "placeholder" (Columns True [1]) Nothing False False []
in selector <$> result `shouldBe` Right [("hello", [placeholder])]

it "errors on combined columns and fields output format"
Expand All @@ -366,7 +366,7 @@ command_tests = describe "commands section" $ do
"```"
]
selector = fmap (Cmd.cmdName &&& Cmd.cmdPlaceholders) . Cfg.commands
in selector <$> result `shouldBe` Right [("hello", [Placeholder Arg "placeholder" JSON False []])]
in selector <$> result `shouldBe` Right [("hello", [Placeholder Arg "placeholder" JSON Nothing False False []])]

it "detects project type"
$ let result =
Expand Down Expand Up @@ -425,7 +425,7 @@ command_tests = describe "commands section" $ do
`shouldBe` Right
[ ( "hello",
True,
[Placeholder Arg "arg" Lines False [], Placeholder Arg "another-arg" Lines False []]
[Placeholder Arg "arg" Lines Nothing False False [], Placeholder Arg "another-arg" Lines Nothing False False []]
)
]

Expand All @@ -445,7 +445,7 @@ command_tests = describe "commands section" $ do
Cmd.cmdPlaceholders = placeholders
} = (lang, placeholders)
fmap selector . Cfg.commands <$> result
`shouldBe` Right [(Bash, [Placeholder Arg "arg" Lines False []])]
`shouldBe` Right [(Bash, [Placeholder Arg "arg" Lines Nothing False False []])]

it "extracts code block placeholders" $ do
let result =
Expand Down Expand Up @@ -477,10 +477,10 @@ command_tests = describe "commands section" $ do
} = (lang, placeholders)
fmap selector . Cfg.commands <$> result
`shouldBe` Right
[ (Bash, [Placeholder Arg "arg-one" Lines False []]),
(Bash, [Placeholder Arg "arg-two" Lines True []]),
(Bash, [Placeholder Arg "arg-three" (Fields [1, 2]) False []]),
(Bash, [Placeholder Arg "arg-four" (Fields [1, 2]) True []])
[ (Bash, [Placeholder Arg "arg-one" Lines Nothing False False []]),
(Bash, [Placeholder Arg "arg-two" Lines Nothing False True []]),
(Bash, [Placeholder Arg "arg-three" (Fields [1, 2]) Nothing False False []]),
(Bash, [Placeholder Arg "arg-four" (Fields [1, 2]) Nothing False True []])
]

it "complains on both header & code block placeholders" $ do
Expand Down Expand Up @@ -625,71 +625,79 @@ parse_command_name_tests = describe "parseCommandName" $ do

it "parses arg part" $ do
parseCommandName "cat ${arg}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines Nothing False False []])

it "parses stdin arg part" $ do
parseCommandName "cat <{arg}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" Lines Nothing False False []])

it "parses envvar arg part" $ do
parseCommandName "cat ={arg}"
`shouldBe` Right ("cat", [Placeholder (EnvVar "arg") "arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder (EnvVar "arg") "arg" Lines Nothing False False []])

it "parses envvar part with alias" $ do
parseCommandName "cat FOO={bar}"
`shouldBe` Right ("cat", [Placeholder (EnvVar "FOO") "bar" Lines False []])
`shouldBe` Right ("cat", [Placeholder (EnvVar "FOO") "bar" Lines Nothing False False []])

it "parses arg field selector" $ do
parseCommandName "cat <{arg:1}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1]) False []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1]) Nothing False False []])

it "parses several arg field selectors" $ do
parseCommandName "cat <{arg:1,3,5}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) False []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) Nothing False False []])

it "parses arg modifiers" $ do
parseCommandName "cat ${arg:m}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines True []])
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines Nothing False True []])

it "parses arg modifiers" $ do
parseCommandName "cat ${arg | fields 1,3}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" (Fields [1, 3]) False []])
`shouldBe` Right ("cat", [Placeholder Arg "arg" (Fields [1, 3]) Nothing False False []])

it "parses arg modifiers" $ do
parseCommandName "cat ${arg | multi}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines True []])
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines Nothing False True []])

it "parses stdin arg modifiers" $ do
parseCommandName "cat <{arg:m}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" Lines True []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" Lines Nothing False True []])

it "parses arg field and multiple selector" $ do
parseCommandName "cat <{arg:m1,3,5}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) True []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) Nothing False True []])

it "parses arg field and multiple selector (flipped)" $ do
parseCommandName "cat <{arg:1,3,5m}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) True []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) Nothing False True []])

it "parses arg field and pipe fields" $ do
parseCommandName "cat <{arg | fields 1,3,5}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) False []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) Nothing False False []])

it "parses list modifier" $ do
parseCommandName "cat ${arg | list}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines Nothing True False []])

it "parses filter modifier" $ do
parseCommandName "cat ${arg | filter \"filter\"}"
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines (Just "filter") False False []])

it "parses arg field, pipe fields and pipe multiple" $ do
parseCommandName "cat <{arg | fields 1,3,5 | multi}"
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) True []])
`shouldBe` Right ("cat", [Placeholder Stdin "arg" (Fields [1, 3, 5]) Nothing False True []])

it "parses text and placeholder part" $ do
parseCommandName "cat \"${arg}\""
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder Arg "arg" Lines Nothing False False []])

it "replaces '-' with '_' in env var name" $ do
parseCommandName "cat \"={some-arg}\""
`shouldBe` Right ("cat", [Placeholder (EnvVar "some_arg") "some-arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder (EnvVar "some_arg") "some-arg" Lines Nothing False False []])

it "supports '_' in env var alias" $ do
parseCommandName "cat some_arg={some-arg}"
`shouldBe` Right ("cat", [Placeholder (EnvVar "some_arg") "some-arg" Lines False []])
`shouldBe` Right ("cat", [Placeholder (EnvVar "some_arg") "some-arg" Lines Nothing False False []])

it "allows use of $ not matching '${'" $ do
parseCommandName "echo $SOME_VAR" `shouldBe` Right ("echo", [])
Expand Down

0 comments on commit 102d5a1

Please sign in to comment.