From a6cb43b411ace3b5360db230769ecd0bb0db1331 Mon Sep 17 00:00:00 2001 From: Georgii Gerasev <54953043+VenInf@users.noreply.github.com> Date: Mon, 27 May 2024 16:01:21 +0300 Subject: [PATCH] Shorter file names completion (#4252) Don't autocomplete `./` in cabal filepaths (e.g. `hs-source-dirs` or `main-is`), unless the user explicitly wrote `./`. --- .../Cabal/Completion/Completer/Paths.hs | 29 ++++++++++++++++++- plugins/hls-cabal-plugin/test/Completer.hs | 20 ++++++------- plugins/hls-cabal-plugin/test/Context.hs | 6 ++-- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs index b067fa9e49..5defdbbe63 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs @@ -1,6 +1,7 @@ module Ide.Plugin.Cabal.Completion.Completer.Paths where import qualified Data.List as List +import Data.List.Extra (dropPrefix) import qualified Data.Text as T import Distribution.PackageDescription (Benchmark (..), BuildInfo (..), @@ -45,6 +46,32 @@ data PathCompletionInfo = PathCompletionInfo } deriving (Eq, Show) + +{- | Posix.splitFileName modification, that drops trailing ./ if + if wasn't present in the original path. + + Fix for the issue #3774 + Examples: + + >>> splitFileNameNoTrailingSlash "" + ("", "") + >>> splitFileNameNoTrailingSlash "./" + ("./", "") + >>> splitFileNameNoTrailingSlash "dir" + ("", "dir") + >>> splitFileNameNoTrailingSlash "./dir" + ("./", "dir") + >>> splitFileNameNoTrailingSlash "dir1/dir2" + ("dir1/","dir2") + >>> splitFileNameNoTrailingSlash "./dir1/dir2" + ("./dir1/","dir2") +-} +splitFileNameNoTrailingSlash :: FilePath -> (String, String) +splitFileNameNoTrailingSlash prefix = rmTrailingSlash ("./" `List.isPrefixOf` prefix) (Posix.splitFileName prefix) + where rmTrailingSlash hadTrailingSlash (queryDirectory', pathSegment') + | hadTrailingSlash = (queryDirectory', pathSegment') + | otherwise = ("./" `dropPrefix` queryDirectory', pathSegment') + {- | Takes an optional source subdirectory and a prefix info and creates a path completion info accordingly. @@ -64,7 +91,7 @@ pathCompletionInfoFromCabalPrefixInfo srcDir prefInfo = } where prefix = T.unpack $ completionPrefix prefInfo - (queryDirectory', pathSegment') = Posix.splitFileName prefix + (queryDirectory', pathSegment') = splitFileNameNoTrailingSlash prefix -- | Extracts the source directories of the library stanza. sourceDirsExtractionLibrary :: Maybe StanzaName -> GenericPackageDescription -> [FilePath] diff --git a/plugins/hls-cabal-plugin/test/Completer.hs b/plugins/hls-cabal-plugin/test/Completer.hs index 61d637a1b6..80da8c53e6 100644 --- a/plugins/hls-cabal-plugin/test/Completer.hs +++ b/plugins/hls-cabal-plugin/test/Completer.hs @@ -55,8 +55,8 @@ basicCompleterTests = doc <- openDoc "main-is.cabal" "cabal" compls <- getCompletions doc (Position 10 12) let complTexts = getTextEditTexts compls - liftIO $ assertBool "suggests f2" $ "./f2.hs" `elem` complTexts - liftIO $ assertBool "does not suggest" $ "./Content.hs" `notElem` complTexts + liftIO $ assertBool "suggests f2" $ "f2.hs" `elem` complTexts + liftIO $ assertBool "does not suggest" $ "Content.hs" `notElem` complTexts ] where getTextEditTexts :: [CompletionItem] -> [T.Text] @@ -66,21 +66,21 @@ fileCompleterTests :: TestTree fileCompleterTests = testGroup "File Completer Tests" - [ testCase "Current Directory" $ do + [ testCase "Current Directory - no leading ./ by default" $ do completions <- completeFilePath "" filePathComplTestDir - completions @?== ["./.hidden", "./Content.hs", "./dir1/", "./dir2/", "./textfile.txt", "./main-is.cabal"], + completions @?== [".hidden", "Content.hs", "dir1/", "dir2/", "textfile.txt", "main-is.cabal"], testCase "Current Directory - alternative writing" $ do completions <- completeFilePath "./" filePathComplTestDir completions @?== ["./.hidden", "./Content.hs", "./dir1/", "./dir2/", "./textfile.txt", "./main-is.cabal"], testCase "Current Directory - hidden file start" $ do completions <- completeFilePath "." filePathComplTestDir - completions @?== ["./Content.hs", "./.hidden", "./textfile.txt", "./main-is.cabal"], + completions @?== ["Content.hs", ".hidden", "textfile.txt", "main-is.cabal"], testCase "Current Directory - incomplete directory path written" $ do completions <- completeFilePath "di" filePathComplTestDir - completions @?== ["./dir1/", "./dir2/"], + completions @?== ["dir1/", "dir2/"], testCase "Current Directory - incomplete filepath written" $ do completions <- completeFilePath "te" filePathComplTestDir - completions @?== ["./Content.hs", "./textfile.txt"], + completions @?== ["Content.hs", "textfile.txt"], testCase "Subdirectory" $ do completions <- completeFilePath "dir1/" filePathComplTestDir completions @?== ["dir1/f1.txt", "dir1/f2.hs"], @@ -165,15 +165,15 @@ directoryCompleterTests :: TestTree directoryCompleterTests = testGroup "Directory Completer Tests" - [ testCase "Current Directory" $ do + [ testCase "Current Directory - no leading ./ by default" $ do completions <- completeDirectory "" filePathComplTestDir - completions @?== ["./dir1/", "./dir2/"], + completions @?== ["dir1/", "dir2/"], testCase "Current Directory - alternative writing" $ do completions <- completeDirectory "./" filePathComplTestDir completions @?== ["./dir1/", "./dir2/"], testCase "Current Directory - incomplete directory path written" $ do completions <- completeDirectory "di" filePathComplTestDir - completions @?== ["./dir1/", "./dir2/"], + completions @?== ["dir1/", "dir2/"], testCase "Current Directory - incomplete filepath written" $ do completions <- completeDirectory "te" filePathComplTestDir completions @?== [], diff --git a/plugins/hls-cabal-plugin/test/Context.hs b/plugins/hls-cabal-plugin/test/Context.hs index ba2275dc1b..badc9263c0 100644 --- a/plugins/hls-cabal-plugin/test/Context.hs +++ b/plugins/hls-cabal-plugin/test/Context.hs @@ -31,12 +31,12 @@ pathCompletionInfoFromCompletionContextTests :: TestTree pathCompletionInfoFromCompletionContextTests = testGroup "Completion Info to Completion Context Tests" - [ testCase "Current Directory" $ do + [ testCase "Current Directory - no leading ./ by default" $ do let complInfo = pathCompletionInfoFromCabalPrefixInfo "" $ simpleCabalPrefixInfoFromFp "" testDataDir - queryDirectory complInfo @?= "./" + queryDirectory complInfo @?= "" , testCase "Current Directory - partly written next" $ do let complInfo = pathCompletionInfoFromCabalPrefixInfo "" $ simpleCabalPrefixInfoFromFp "di" testDataDir - queryDirectory complInfo @?= "./" + queryDirectory complInfo @?= "" pathSegment complInfo @?= "di" , testCase "Current Directory - alternative writing" $ do let complInfo = pathCompletionInfoFromCabalPrefixInfo "" $ simpleCabalPrefixInfoFromFp "./" testDataDir