Skip to content

Commit 7b66b8c

Browse files
committed
Select just the first alias for each command for bash completions.
1 parent c9d83af commit 7b66b8c

2 files changed

Lines changed: 19 additions & 32 deletions

File tree

src/Options/Applicative/BashCompletion.hs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ import Prelude
1717
#if !defined(__MHS__)
1818
import Data.Foldable ( asum )
1919
#endif
20+
21+
import qualified Data.Foldable as Foldable
2022
import Data.List ( isPrefixOf )
2123
import Data.List.NonEmpty (NonEmpty)
22-
import qualified Data.List.NonEmpty as NE
23-
import Data.Maybe ( fromMaybe, listToMaybe )
24+
import Data.Maybe ( fromMaybe, listToMaybe, mapMaybe )
2425

2526
import Options.Applicative.Builder
2627
import Options.Applicative.Common
@@ -159,12 +160,20 @@ bashCompletionQuery pinfo pprefs richness ws i _ = case runCompletion compl ppre
159160
--
160161
-- and the user types 'r', we should return
161162
--
162-
-- [(retry, p1), (run, p2), (r, p2)]
163+
-- [(retry, p1), (run, p2)]
164+
--
165+
-- If the first entry (command name) is the canonical one, we should
166+
-- favour it in completions, as if we were to provide all options there
167+
-- would be a good chance we'd be forcing the user to tab through and
168+
-- disambiguate between functionally identical options.
169+
--
170+
-- In zsh and fish we also provide the help doc in the completions, which
171+
-- we don't want to repeat a whole bunch of times.
163172
filter_completions :: [(NonEmpty String, ParserInfo a)] -> [(String, ParserInfo a)]
164173
filter_completions =
165-
let matchZip :: (NonEmpty String, b) -> [(String, b)]
166-
matchZip (aliases, painfo) = (\x -> (x, painfo)) <$> NE.filter is_completion aliases
167-
in (>>= matchZip)
174+
let findAlias :: (NonEmpty String, b) -> Maybe (String, b)
175+
findAlias (aliases, painfo) = (\x -> (x, painfo)) <$> Foldable.find is_completion aliases
176+
in mapMaybe findAlias
168177

169178
-- We only want to show a single line in the completion results description.
170179
-- If there was a line break, it would come across as a different completion

tests/test.hs

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,7 @@ prop_cmd_aliases_completion = once . ioProperty $
187187
Success val -> return $ counterexample ("unexpected result " ++ show val) failed
188188
where
189189
expected =
190-
[ "goodbye"
191-
, "hello"
192-
, "hi"
193-
, "au-revoir"
194-
, "adieu"
195-
, "ciao"
196-
, "bonjour"
197-
, "aux"
198-
, "health"
199-
]
190+
["goodbye","hello","au-revoir","bonjour","aux","health"]
200191

201192
prop_cmd_aliases_completion_alias1 :: Property
202193
prop_cmd_aliases_completion_alias1 = once . ioProperty $
@@ -222,10 +213,7 @@ prop_cmd_aliases_completion_alias2 = once . ioProperty $
222213
in assertCompletions result (=== expected)
223214
where
224215
expected =
225-
[ "au-revoir"
226-
, "adieu"
227-
, "aux"
228-
]
216+
["au-revoir","aux"]
229217

230218
prop_cmd_aliases_completion_alias3 :: Property
231219
prop_cmd_aliases_completion_alias3 = once . ioProperty $
@@ -263,13 +251,7 @@ prop_cmd_aliases_dupes_completion = once . ioProperty $
263251
in assertCompletions result (=== expected)
264252
where
265253
expected =
266-
[ "goodbye"
267-
, "g"
268-
, "h"
269-
, "hello"
270-
, "hi"
271-
, "h"
272-
]
254+
["goodbye","hello"]
273255

274256
prop_cmd_aliases_dupes_completion_alias1 :: Property
275257
prop_cmd_aliases_dupes_completion_alias1 = once . ioProperty $
@@ -281,11 +263,7 @@ prop_cmd_aliases_dupes_completion_alias1 = once . ioProperty $
281263
in assertCompletions result (=== expected)
282264
where
283265
expected =
284-
[ "h"
285-
, "hello"
286-
, "hi"
287-
, "h"
288-
]
266+
["h","hello"]
289267

290268
prop_alts :: Property
291269
prop_alts = once $

0 commit comments

Comments
 (0)