Eugleo / magic-racket

The best coding experience for Racket in VS Code
https://marketplace.visualstudio.com/items?itemName=evzen-wybitul.magic-racket
GNU General Public License v3.0
204 stars 28 forks source link

Typing close paren reformats the whole document #102

Closed jryans closed 1 year ago

jryans commented 1 year ago

For some reason, typing a close paren seems to trigger the whole document to be reformatted, which is less than ideal for sure...

Any reformatting while typing should be limited to only the new expression. If that's not possible, then it should be disabled entirely (until it can be fixed).

Presumably this is langserver related.

jryans commented 1 year ago

Here's an example demonstrating the issue:

#lang racket/base

(struct document (author
  title
  content))

(struct book
  document
  (publisher)); <- Remove and re-add this close paren

If you remove and re-add the last closing paren in the file (for the book struct), you end up seeing that document struct earlier in the file gets reformatted, even though we are not working on that that expression. This behaviour is surprising and gets in the way when working on shared codebases that may use all sorts of different formatting styles. Ideally, only the actively edited expression would be reformatted when format on type is enabled.

After typing the close paren, VS Code shows the following LSP traffic:

[Trace - 17:55:29] Sending request 'textDocument/onTypeFormatting - (60)'.
Params: {
    "textDocument": {
        "uri": "..."
    },
    "position": {
        "line": 8,
        "character": 14
    },
    "ch": ")",
    "options": {
        "tabSize": 2,
        "insertSpaces": true,
        "insertFinalNewline": true
    }
}

[Trace - 17:55:29] Received response 'textDocument/onTypeFormatting - (60)' in 14ms.
Result: [
    {
        "newText": "",
        "range": {
            "end": {
                "character": 17,
                "line": 0
            },
            "start": {
                "character": 17,
                "line": 0
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 0,
                "line": 1
            },
            "start": {
                "character": 0,
                "line": 1
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 24,
                "line": 2
            },
            "start": {
                "character": 24,
                "line": 2
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 7,
                "line": 3
            },
            "start": {
                "character": 7,
                "line": 3
            }
        }
    },
    {
        "newText": "                ",
        "range": {
            "end": {
                "character": 0,
                "line": 3
            },
            "start": {
                "character": 0,
                "line": 3
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 11,
                "line": 4
            },
            "start": {
                "character": 11,
                "line": 4
            }
        }
    },
    {
        "newText": "                ",
        "range": {
            "end": {
                "character": 0,
                "line": 4
            },
            "start": {
                "character": 0,
                "line": 4
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 0,
                "line": 5
            },
            "start": {
                "character": 0,
                "line": 5
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 12,
                "line": 6
            },
            "start": {
                "character": 12,
                "line": 6
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 10,
                "line": 7
            },
            "start": {
                "character": 10,
                "line": 7
            }
        }
    },
    {
        "newText": "",
        "range": {
            "end": {
                "character": 14,
                "line": 8
            },
            "start": {
                "character": 14,
                "line": 8
            }
        }
    }
]

[Trace - 17:55:29] Sending notification 'textDocument/didChange'.
Params: {
    "textDocument": {
        "uri": "...",
        "version": 11
    },
    "contentChanges": [
        {
            "range": {
                "start": {
                    "line": 4,
                    "character": 0
                },
                "end": {
                    "line": 4,
                    "character": 0
                }
            },
            "rangeLength": 0,
            "text": "                "
        },
        {
            "range": {
                "start": {
                    "line": 3,
                    "character": 0
                },
                "end": {
                    "line": 3,
                    "character": 0
                }
            },
            "rangeLength": 0,
            "text": "                "
        }
    ]
}

The confirms that onTypeFormatting support in the lang server reformatted the whole file.

I suppose what's needed here is the lang server's onTypeFomatting support should specially handle the close paren character, and then look for the current expression, and only reformat that...?

jryans commented 1 year ago

Filed a lang server issue: https://github.com/jeapostrophe/racket-langserver/issues/111

jryans commented 1 year ago

Fixed by lang server change: https://github.com/jeapostrophe/racket-langserver/pull/114