Skip to content

Exactprinter & modification framework, take 2 - #12316

Draft
leana8959 wants to merge 63 commits into
haskell:masterfrom
leana8959:transform-fields-poc
Draft

Exactprinter & modification framework, take 2#12316
leana8959 wants to merge 63 commits into
haskell:masterfrom
leana8959:transform-fields-poc

Conversation

@leana8959

Copy link
Copy Markdown
Collaborator

I made substantial progress in the exactprinter & modification framework describe in the proposal haskell/cabal-proposals#7. This branch/PR shows how it works.

The diff is roughly 2.5k (it's stacked on the #11252).

TL;DR: The exactprinter allows programmers to parse a fields file, and printed it back exactly the same (with the exception that we decided that trailing spaces will be discarded for now for a simple first implementation).
The modification framework allows users to modify values in the cabal fields tree in a typed manner.

In Cabal-tests/tests/ParserTests.hs you can find examples of how the API would look like.


Please read Github PR Conventions and then fill in one of these two templates.


Template Α: This PR modifies behaviour or interface

Include the following checklist in your PR:


Template B: This PR does not modify behaviour or interface

E.g. the PR only touches documentation or tests, does refactorings, etc.

Include the following checklist in your PR:

  • Patches conform to the coding conventions.
  • Is this a PR that fixes CI? If so, it will need to be backported to older cabal release branches (ask maintainers for directions).

leana8959 and others added 30 commits July 24, 2026 11:16
This lays the foundation for Cabal-exactprint to consume user comments.

The parser of the envelope format ("field parser") now annotates each of
the parsed fields with its preceding and succeeding comments, along with
the existing source location annotation 'Position'.

This change is orthogonal to the final chosen exactprint implementation,
or the algebra we use to modify existing fields and/or generate new
fields. Instead, it merely makes the user comments available to any
consumer that reads cabal fields, the envelope format.

readFields* functions now have their counterparts that parses with
comments, named readFieldsWithComments*.
use transform example

refactor modifying, take 1

refactor modifying, take 2

rename functions

preverse correct starting position

extract and restore comments

edit target build depend example

HasPos class

print to stderr to avoid interleaving

test editing

make edit better

implement relativization

clean up relativization

compute line position

add new joining function

rewrite transformation algebra

use relative spacing in modification

clean up, move Fields.Spacing to its own module

clean up test suite

include comment in relative spacing conversion

checkpoint

implement a simple renderer for Field ann

initialize test for field exact rendering

debug exact printer

roundtrip is possible

roundtrip poc

Run cabal test Cabal-tests:hackage-tests --test-option="field-roundtrip"

dump everything that don't match in exact print hackage test

restore joining, ditch spacing experiments for now

add naive tabs to space substitution, remove tracing

demonstrate cabal project file roundtrip

ignore stupid errors and focus on the real ones

patch tabs -> space, empty lines, and lineendings

drop empty lines at end of file

retain position of colon

This needs to be refined but it's the basic idea.

make colon closest to field name and not separated by comments

print failed filenames for further processing and investigation

add a few examples for quotes

apply hints

rewrite exact printer with RWS

remove irrelevant todo

fix tests

restore final trailing newline

prevent memory leak

print quotes

add unit test for simple transformation

implement modifyValueList

remove useless instance

add few new tests and CRLF support

comment out traces

implement splitBSAtPosition, add tests

implement substituteSubBSAt

fix off by one

The way parsec combinators save position makes it save on the first and last char.
We need to increment the position to make the end position exclusive.

clean up joinFieldLine implementation, add tests

test modifyValueList

Located combinator will report the placement when the parser is done.
If a parser consumes trailing spaces, it will report a ending position that is too far below.
This is the case for dependency.

fix off by one

fix in list modification trailing list

remove tracing

split bytestring transformation from fieldlines

implement tests for modifyValueAtomAlaBS

rename functions

test modification of strings at any position within a dependency list

parameterize edit functions with lineending configuration

run formatter

add examples for stringy lists

implement prepend item in list

clean up modification framework to better match the proposal

add simple modification framework tests

field removal

fix removal, add tested test

add a line ending guessing function

add todos

fine grain adding/removing/modifying

fix mapping functions

doesn't really matter, we can just tell the user

but maybe the open approach can allow user to do this. hmm.

implement cascading to chain fallback edits

rewrite in individual simple functions

simplify function naming

add todos

rename configuration types

edit distributivity

add product operator

add hasChanged assertion operator

clean up todos

create a concrete edit error type

remove applicative instance

remove temporary call to error

implement fieldline splitting

remove duplicated functions and newline handling

We always split the lines to a field line, so we don't care

use split fieldlines

start implementing position fixing in addField

fixes, complete add's position shifting

fix one-indexed position, accept test result

test AddStart as well

implement position shifting in modifyField and modifySection

remove ModifyAll mode

add a modify test

update substitute sub bytestring at tests

Previously the ending was not inclusing, I must have changed how it
works.

add an integration test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant