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

Fix ionide#209: Remove (* *) from brackets config #210

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mbottini
Copy link
Contributor

@mbottini mbottini commented Dec 22, 2023

Remove (* *) from the brackets field of language-configuration.json. This prevents the (* part of the (*) operator from being treated as an unclosed bracket, followed by the ) bracket being associated with a previous paren.

The only side effect of this is that you'd lose nested bracket colorization for block comments, (which F# does support!) but we currently color comments a uniform green anyway.

Before:

image

After:

image

This fixes #209.

language-configuration.json lets you define various pairs of brackets
and braces for autoclosing, surrounding selected text with characters,
and, as it turns out, dictating which brackets get colorized by
the native bracket colorizer.

Currently, having `(* *)` inside the `brackets` field is causing the
infix multiplication operator to be treated by the bracket colorizer
as two brackets: an opening `(*` and a closing `)`. Two things happen
here:

* The `(*` does not correspond to a corresponding `*)` bracket, so it
  is treated as unbalanced (hence why that part of the operator is
  colored red).
* Absent any preceding parens in the expression, the `)` is also
  treated as an unbalanced paren and is colored red. This is the
  best case, which colors the entire operator a uniform red. Strange,
  but normal-looking enough that it actually looked intentional to me
  when I first started getting into F#. The multiplication operator is
  weird due to how similar it is to block comments - maybe it's
  supposed to be that way!
* But the bug really gets exposed when there is a preceding paren in
  the expression such as in the expression `(Seq.fold (*) 1 [1;2;3])`.
  In this case, there *is* a balancing paren - the paren that precedes
  `Seq.fold`. Now the multiplication operator is half red (the block
  comment bracket never gets balanced) and half whatever the colorizer
  picks for the two parens. And now the closing paren after `[1;2;3]` is
  unbalanced and made red!

As far as I can tell, putting the block comment brackets inside the
`brackets` field is pointless. We color our comments green anyway,
so the colors don't show anyway. It is true that F# provides
support for nested comment blocks, but we aren't taking advantage
of the color feature anyway (and I'm unsure if it's even possible
to do so).

The block comments should, however, remain in the other fields
that control autocomplete and surrounding selected text.
@mbottini mbottini force-pushed the mbottini/fix_block_comment_brackets branch from aa2565a to 81edefe Compare December 22, 2023 19:15
@baronfel
Copy link

This seems reasonable to me - @MangelMaxime do you have any concerns here?

@MangelMaxime
Copy link
Contributor

I don't have concerns regarding the grammar.

However, applying theses changes means:

We will lose:

  • Go to Bracket
  • Select to Bracket

and "auto-indentation":

Before

CleanShot.2023-12-28.at.11.00.06.mp4

After

CleanShot.2023-12-28.at.10.58.58.mp4

Source

@mbottini
Copy link
Contributor Author

mbottini commented Dec 28, 2023

This is a good point. The place to solve this might be upstream in VSCode's approach to finding brackets in a file (https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/languages/supports/richEditBrackets.ts). Currently, they do a pretty simple approach - they build a big regex from all of the bracket pairs and apply it in both directions (reversing the regex when they traverse the file toward the beginning). Brackets are matched greedily. This approach fails for this particular edge case, where the regex matches on (* instead of (. A more sophisticated approach might be able to resolve this better and remove the reason for this pull request altogether.

Regarding auto-indentation - it's not pretty, but the language-configuration.json rules describe an alternative to just doing whatever the brackets say - provide a big pile of regexes to define indent and dedent rules. So it would be possible, albeit really gross, to maintain the auto-indent rules even after removing (* *). I'd prefer the brackets, though!

@MangelMaxime
Copy link
Contributor

@mbottini We do indeed have some rules for indentation rules in https://github.com/ionide/ionide-vscode-fsharp/blob/5645d12af2293adaa995a8841c8eec9ad709fbd2/src/Components/LanguageConfiguration.fs

So perhaps, we can compensate the removal by adapting the onEnter rule.

mbottini added a commit to mbottini/ionide-vscode-fsharp that referenced this pull request Apr 1, 2024
Background: ionide/ionide-fsgrammar#209 and ionide/ionide-fsgrammar#210

This comes from a comment regarding a pull request that I made on the
ionide-fsgrammar repository, which removes the `(* *)` bracket pair
from the "brackets" field of language-configuration.json. One issue
with doing this is that we lose the bracket-like indentation that
VSCode provides by default for all bracket pairs.

In other words, when I hit Enter in the following configuration,
cursor location represented by the white block:

    (*█*)

It should indent the cursor and then put the `*)` on the next line
with the same indentation level as the `(*` as follows:

    (*
        █
    *)

---

When I hit Enter with an unaccompanied `(*`:

    (*█

It should simply indent as follows:

    (*
        █

---

Lastly, an unaccompanied `*)` should outdent. That is,

        *)█

should become

    *)█
mbottini added a commit to mbottini/ionide-vscode-fsharp that referenced this pull request Apr 1, 2024
Background: ionide/ionide-fsgrammar#209 and ionide/ionide-fsgrammar#210

This comes from a comment regarding a pull request that I made on the
ionide-fsgrammar repository, which removes the `(* *)` bracket pair
from the "brackets" field of language-configuration.json. One issue
with doing this is that we lose the bracket-like indentation that
VSCode provides by default for all bracket pairs.

Since I'd like to remove the block comment brackets from the
`language-configuration.json` file, this pull request re-adds
the same semantics to the indentation rules.

In other words, when I hit Enter in the following configuration,
cursor location represented by the white block:

    (*█*)

It should indent the cursor and then put the `*)` on the next line
with the same indentation level as the `(*` as follows:

    (*
        █
    *)

---

When I hit Enter with an unaccompanied `(*`:

    (*█

It should simply indent as follows:

    (*
        █

---

Lastly, an unaccompanied `*)` should outdent. That is,

        *)█

should become

    *)█
mbottini added a commit to mbottini/ionide-vscode-fsharp that referenced this pull request Apr 1, 2024
Background: ionide/ionide-fsgrammar#209 and ionide/ionide-fsgrammar#210

This comes from a comment regarding a pull request that I made on the
ionide-fsgrammar repository, which removes the `(* *)` bracket pair from
the "brackets" field of language-configuration.json. One issue with
doing this is that we lose the bracket-like indentation that VSCode
provides by default for all bracket pairs. This pull request re-adds the
same semantics to the indentation rules.

In other words, when I hit Enter in the following configuration,
cursor location represented by the white block:

    (*█*)

It should indent the cursor and then put the `*)` on the next line
with the same indentation level as the `(*` as follows:

    (*
        █
    *)

---

When I hit Enter with an unaccompanied `(*`:

    (*█

It should simply indent as follows:

    (*
        █

---

Lastly, an unaccompanied `*)` should outdent. That is,

        *)█

should become

    *)█
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.

Infix multiplication operator screws up parentheses coloring and is highlighted in red
3 participants