From 5fa47107a23e04e1de5425eff8f6d0c645f8b375 Mon Sep 17 00:00:00 2001 From: Alan Zimmerman Date: Tue, 29 Aug 2017 23:43:03 +0200 Subject: [PATCH] Sort out overlapping edits 1. Send the edits in reverse order, so that the line numbers are still valid, as edits later in the file will not change line numbers earlier in the file. 2. When something is added, make sure the change is expressed with respect to the file being changed, not the reference file for the diff. --- hie-hare/Haskell/Ide/HaRePlugin.hs | 12 ++++++-- hie-hare/hie-hare.cabal | 1 + .../Haskell/Ide/Engine/PluginUtils.hs | 9 ++++-- stack.yaml | 5 +++- test/HaRePluginSpec.hs | 28 +++++++++++-------- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/hie-hare/Haskell/Ide/HaRePlugin.hs b/hie-hare/Haskell/Ide/HaRePlugin.hs index 2c8de553..7dda6743 100644 --- a/hie-hare/Haskell/Ide/HaRePlugin.hs +++ b/hie-hare/Haskell/Ide/HaRePlugin.hs @@ -12,6 +12,8 @@ import Control.Monad.Trans.Control import Control.Monad.Trans.Either import Data.Aeson import qualified Data.Aeson.Types as J +import Data.Algorithm.Diff +import Data.Algorithm.DiffOutput import Data.Either import Data.Foldable import qualified Data.Map as Map @@ -37,10 +39,11 @@ import Haskell.Ide.Engine.PluginUtils import Haskell.Ide.GhcModPlugin (setTypecheckedModule) import HscTypes import Language.Haskell.GHC.ExactPrint.Print +import qualified Language.Haskell.LSP.Core as Core import qualified Language.Haskell.LSP.TH.DataTypesJSON as J -import Language.Haskell.Refact.API +import Language.Haskell.Refact.API hiding (logm) import Language.Haskell.Refact.HaRe -import Language.Haskell.Refact.Utils.Monad +import Language.Haskell.Refact.Utils.Monad hiding (logm) import Language.Haskell.Refact.Utils.MonadFunctions import Module import Name @@ -231,9 +234,12 @@ makeRefactorResult changedFiles = do diffOne :: (FilePath, T.Text) -> IdeM WorkspaceEdit diffOne (fp, newText) = do origText <- GM.withMappedFile fp $ liftIO . T.readFile + -- TODO: remove this logging once we are sure we have a working solution + logm $ "makeRefactorResult:groupedDiff = " ++ show (getGroupedDiff (lines $ T.unpack origText) (lines $ T.unpack newText)) + logm $ "makeRefactorResult:diffops = " ++ show (diffToLineRanges $ getGroupedDiff (lines $ T.unpack origText) (lines $ T.unpack newText)) return $ diffText (filePathToUri fp, origText) newText diffs <- mapM diffOne changedFiles - return $ fold diffs + return $ Core.reverseSortEdit $ fold diffs -- --------------------------------------------------------------------- nonExistentCacheErr :: String -> IdeResponse a diff --git a/hie-hare/hie-hare.cabal b/hie-hare/hie-hare.cabal index c59e7fe5..0ca80371 100644 --- a/hie-hare/hie-hare.cabal +++ b/hie-hare/hie-hare.cabal @@ -21,6 +21,7 @@ library , HaRe , aeson , containers + , Diff , either , ghc , ghc-mod diff --git a/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs b/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs index fca0296f..b0ffafad 100644 --- a/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs +++ b/hie-plugin-api/Haskell/Ide/Engine/PluginUtils.hs @@ -158,9 +158,14 @@ diffText (f,fText) f2Text = WorkspaceEdit (Just h) Nothing where range = calcRange fm - diffOperationToTextEdit (Addition fm _) = J.TextEdit range nt + diffOperationToTextEdit (Addition fm l) = J.TextEdit range nt + -- fm has a range wrt to the changed file, which starts in the current file at l + -- So the range has to be shifted to start at l where - range = calcRange fm + range = J.Range (J.Position (l - 1) 0) + (J.Position (l - 1 + el - sl) 0) + sl = fst $ lrNumbers fm + el = snd $ lrNumbers fm nt = T.pack $ unlines $ lrContents fm diff --git a/stack.yaml b/stack.yaml index 2c155204..cd75de3e 100644 --- a/stack.yaml +++ b/stack.yaml @@ -12,10 +12,13 @@ packages: - hie-hoogle - hie-plugin-api - hie-brittany + +# - ../haskell-lsp - location: git: https://github.com/alanz/haskell-lsp.git - commit: 50076561c9c9e4d86536efd9458ac3f1d14a68a4 + commit: e2dcd2be98c07a53b0df6ebb77b18bfac6403e31 extra-dep: true + - location: git: https://github.com/alanz/ghc-dump-tree.git commit: 9dbca928ad5507b144f46bb95123a08d24f24808 diff --git a/test/HaRePluginSpec.hs b/test/HaRePluginSpec.hs index 45ea1e40..168447bd 100644 --- a/test/HaRePluginSpec.hs +++ b/test/HaRePluginSpec.hs @@ -114,7 +114,7 @@ hareSpec = do $ toJSON $ WorkspaceEdit (Just $ H.singleton (filePathToUri $ cwd "test/testdata/HaReRename.hs") - $ List [TextEdit (Range (Position 6 0) (Position 8 0)) + $ List [TextEdit (Range (Position 5 0) (Position 7 0)) "foonew :: Int -> Int\nfoonew x = x + 3\n\n"]) Nothing) @@ -146,8 +146,9 @@ hareSpec = do $ WorkspaceEdit (Just $ H.singleton ( filePathToUri $ cwd "test/testdata/HaReMoveDef.hs" ) - $ List [TextEdit (Range (Position 4 0) (Position 5 9)) "" - ,TextEdit (Range (Position 5 0) (Position 6 0)) "y = 4\n\n"]) + $ List [ TextEdit (Range (Position 6 0) (Position 7 0)) "y = 4\n\n" + , TextEdit (Range (Position 4 0) (Position 5 9)) "" + ]) Nothing) -- --------------------------------- @@ -162,9 +163,10 @@ hareSpec = do $ WorkspaceEdit (Just $ H.singleton ( filePathToUri $ cwd "test/testdata/HaReMoveDef.hs") - $ List [TextEdit (Range (Position 10 0) (Position 11 13)) "" - ,TextEdit (Range (Position 11 0) (Position 11 5)) "z = 7\n" - ,TextEdit (Range (Position 13 0) (Position 13 0)) "\n"]) + $ List [ TextEdit (Range (Position 13 0) (Position 13 0)) "\n" + , TextEdit (Range (Position 12 0) (Position 12 0)) "z = 7\n" + , TextEdit (Range (Position 10 0) (Position 11 13)) "" + ]) Nothing) -- --------------------------------- @@ -245,7 +247,7 @@ hareSpec = do (IdeResponseOk $ WorkspaceEdit (Just $ H.singleton (filePathToUri $ cwd "test/testdata/HaReRename.hs") - $ List [TextEdit (Range (Position 6 0) (Position 8 0)) + $ List [TextEdit (Range (Position 5 0) (Position 7 0)) "foonew :: Int -> Int\nfoonew x = x + 3\n\n"]) Nothing) @@ -277,8 +279,9 @@ hareSpec = do $ WorkspaceEdit (Just $ H.singleton ( filePathToUri $ cwd "test/testdata/HaReMoveDef.hs" ) - $ List [TextEdit (Range (Position 4 0) (Position 5 9)) "" - ,TextEdit (Range (Position 5 0) (Position 6 0)) "y = 4\n\n"]) + $ List [ TextEdit (Range (Position 6 0) (Position 7 0)) "y = 4\n\n" + , TextEdit (Range (Position 4 0) (Position 5 9)) "" + ]) Nothing) -- --------------------------------- @@ -292,9 +295,10 @@ hareSpec = do $ WorkspaceEdit (Just $ H.singleton ( filePathToUri $ cwd "test/testdata/HaReMoveDef.hs") - $ List [TextEdit (Range (Position 10 0) (Position 11 13)) "" - ,TextEdit (Range (Position 11 0) (Position 11 5)) "z = 7\n" - ,TextEdit (Range (Position 13 0) (Position 13 0)) "\n"]) + $ List [ TextEdit (Range (Position 13 0) (Position 13 0)) "\n" + , TextEdit (Range (Position 12 0) (Position 12 0)) "z = 7\n" + , TextEdit (Range (Position 10 0) (Position 11 13)) "" + ]) Nothing) -- ---------------------------------