Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comments #86

Open
justinpombrio opened this issue Mar 6, 2024 · 0 comments
Open

Comments #86

justinpombrio opened this issue Mar 6, 2024 · 0 comments

Comments

@justinpombrio
Copy link
Owner

We need to handle comments. There are a few tricky issues.

Problems

Comments vs. Doc comments

Doc comments apply to a node, such as a function definition or an enum variant. Regular comments typically do not. For example, a comment in the middle of a function body might be meant to apply to all following lines; commented-out code does not apply to whatever happens to come next; and regular comments can appear at the end of a file.

Therefore, doc comments should be an optional child of the node they apply to. In Rust, they're placed above a function, or sometimes at the top of a module; in Python they're in doc strings before the function body; in other languages they might be allowed to be at the end of a line.

Regular comments, by contrast, exist between nodes. Usually they're between listy nodes, but we may want to support them appearing between fixed arity nodes as well. (The only real reason to support them between fixed arity nodes is to accurately represent code written in a text editor that has comments in strange places.)

Commented-out code

You should be able to

  • Comment some code with a hotkey
  • Uncomment some code with a hotkey
  • Maybe uncomment code that came from a text editor?
  • Navigate to the commented out code and edit it just like uncommented code.

End of line comments

What should happen if there's a comment like:

foobar(bizzazzle, boozazzle) // foobar the bezazzles

Is that equivalent to a comment on the previous line?

// foobar the bezazzles
foobar(bizzazzle, boozazzle)

Inline block comments

What should we do with inline block comments like these?

let x = /* one */ 1 /* plus */ + /* two */ 2;

Comments and commas

How is this JSON list displayed?

[
    one,
    // comment1
    two
    // comment2
    // comment3
]

Assuming that we're using "sibling comments" (see "Comments vs. Doc Comments"), this list has five elements, three of which are whitespace elements. Commas must be placed only after the element one, not after comments or two (because JSON). So the rule is that you put a comment after every non-last, non-whitespace element.

Proposed Solutions

Commented-out code

When you comment out code, it's placed in a special "code block" node in the comment. Or alternatively, it's placed in a "commented code" node (as distinguished from "comment" nodes). Either way, it marks what sort of code was commented. For example, commented-out code when saved to a text file might appear as:

// ``` rust statement
//     let x = 1;
// ```

Commented-out code from a text editor appears as regular comments, and cannot be un-commented. (Unless you manually add the "commented code" node syntax.)

End of line comments

End of line comments can be parsed, but are always converted to before-line comments. This is due to an interaction of rules we really want to hold:

  1. Navigation order equals visual order. A before-line comment would have to be the first child, while and end of line comment would have to be the last child, so that when you navigate to the next sibling you don't jump around.
  2. Fixed navigation order: if you edit a comment, it absolutely cannot move to a different location in the tree. However, an end of line comment can only be so long while fitting on the line and needing to be moved. (And in screen reader mode, line width isn't even defined).

Inline block comments

At least for now, turn inline block comments into before-line comments. Thus this code:

let x = /* one */ 1 /* plus */ + /* two */ 2;

gets converted into:

// one
// plus
// two
let x = 1 + 2;

Comments vs. Doc comments

Doc comments are optional children of the node they annotate.

Regular comments can appear only in listy nodes, where they can be interspersed with regular children.

Comments and commas

The notation language can handle this with two new predicates:

  • IsEmptyText: is the current node a text node with empty text?
  • IsLast: is the next fold child the last non-whitespace element?
  • IsWhitespace: is the next fold child a whitespace element?

There's a new kind of notation called If that takes a Predicate, which is made of the base predicates above joined by Not, And, Or. These predicates are implemented by PrettyDoc, just like IsEmptyText is currently.

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

No branches or pull requests

1 participant