fine-grained space merging

This commit is contained in:
Mirek Kratochvil 2025-07-13 10:24:23 +02:00
parent 96a623ac07
commit bc5d7a6915
3 changed files with 30 additions and 7 deletions

20
Main.hs
View file

@ -112,13 +112,31 @@ zeal (Conflict m o y) =
pops ms ys = ((ms, ys), [])
zeal x = [x]
resolve Config {..} c@(Conflict m o y)
resolve cfg@Config {..} c@(Conflict m o y)
| all Toks.space (concat [m, o, y]) && cfgSpaces /= SpacesNormal =
resolveSpace cfg c
| m == o && o == y = Ok o
| m == o && cfgResolveSeparate = Ok y
| o == y && cfgResolveSeparate = Ok m
| m == y && cfgResolveOverlaps = Ok m
resolve _ x = x
-- TODO: there might be a bit of interplay between the spaces handling and
-- separate/overlapped conflict resolution -- e.g., what if someone wants to
-- merge overlapping edits in text but separate edits in spaces? At this point
-- that might be ignorable.
resolveSpace Config {..} c@(Conflict m o y)
| m == o && o == y = Ok o
| otherwise =
case cfgSpaces of
SpacesConflict -> c
SpacesMy -> Ok m
SpacesOld -> Ok o
SpacesYour -> Ok y
_ -> error "spaces resolution failed"
resolveSpaces _ x = x
merge cfg@Config {..} ms ys =
regroup
. map (resolve cfg)

14
Opts.hs
View file

@ -38,13 +38,15 @@ tokenizer =
]
data Spaces
= SpacesConflict
= SpacesNormal
| SpacesConflict
| SpacesMy
| SpacesOld
| SpacesYour
deriving (Show)
deriving (Show, Eq)
spaceMode x
| x `isPrefixOf` "normal" = Right SpacesNormal
| x `isPrefixOf` "conflict" = Right SpacesConflict
| x `isPrefixOf` "my" = Right SpacesMy
| x `isPrefixOf` "old" = Right SpacesOld
@ -53,7 +55,7 @@ spaceMode x
Left
$ "could not parse value `"
++ x
++ "', use one of `conflict', `my', `old', and `your'"
++ "', use one of `normal', `conflict', `my', `old', and `your'"
data Config = Config
{ cfgTokenizer :: Tokenizer
@ -75,10 +77,10 @@ config = do
option (eitherReader spaceMode)
$ long "spaces"
<> short 's'
<> metavar "(conflict|my|old|your)"
<> metavar "(normal|conflict|my|old|your)"
<> help
"mode of merging the spaces; instead of conflict one may choose to default the space from the source files (default: conflict)"
<> value SpacesConflict
"mode of merging the space-only changes; instead of usual resolution one may choose to always conflict or to default the space from the source files (default: normal)"
<> value SpacesNormal
cfgContext <-
option auto
$ long "expand-context"

View file

@ -23,6 +23,9 @@ unmarkSpace ('.':s) = s
unmarkSpace ('|':s) = s
unmarkSpace _ = error "wat"
space ('.':_) = True
space _ = False
split =
unlines
. map (concatMap escape . markSpace)