You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As part of #218, I've been digging in to the code fsharp-mode uses to compute indentation. This is a fairly complicated topic, including regexen for keyword detection, predicate functions, and motion functions. In particular, I've found a set of problems with fsharp-statement-opens-block-p and fsharp-goto-beyond-final-line. This goes like so:
fsharp-statement-opens-block-p needs to compute whether or not the current statement creates a new block or not. To do this, it searches between the current value of point, and an endpoint called finish. finish is set to the value of fsharp-goto-beyond-final-line.
fsharp-goto-beyond-final-line claims to go to the line after the end of "the current statement."[^1]
fsharp-goto-beyond-final-line uses a while loop and-ing on fsharp-continuation-line-p.
fsharp-continuation-line-ponly considers a line a "continuation line" if it either 1) ends in a dangling arithmetic operator or 2) point is inside a block delimited by a pair (i.e. point is inside [] or {}). This means the function almost always goes one line forward, then returns point at that position.
fsharp-statement-opens-block-pimmediately adjusts the value returned from fsharp-continuation-line-p by subtracting 1.
To summarize:
fsharp-statement-opens-block-p is taking an incredibly convoluted approach to searching until end of same line. This might be correct, but there are no previously existing tests.
fsharp-goto-beyond-final-line definitely does no such thing. (Again, no tests.)
fsharp-continuation-line-p is being used when we likely want a slightly different function.
For example, let x = 5 + is a "continuation line", but type Shape = is not.
(As a final, frustrating note, F# does not, in fact, have statements, at all.)
Proposed Solutions
fsharp-statement-opens-block-p needs to reliably return whether or not the statement (which is to say, expression) opens a block. It is used all over the place, so should be well documented, and under test. (Also, the name should be changed to use "expression" over "statement".)
fsharp-goto-beyond-final-line should do so, and be under test. I assert we need a function similar to, but distinct from, fsharp-continuation-line-p. Something like fsharp-in-block-p -- "tell me if this line could be considered part of an ongoing block." Right now, there is no code to detect this -- it's handled in fsharp-compute-indentation as the final default "fall-through" case, so lacks a proper predicate. We should probably have one!
Footnotes
[^1] Note that if #223 has been merged, this will say "the current expression."
The text was updated successfully, but these errors were encountered:
Description
As part of #218, I've been digging in to the code
fsharp-mode
uses to compute indentation. This is a fairly complicated topic, including regexen for keyword detection, predicate functions, and motion functions. In particular, I've found a set of problems withfsharp-statement-opens-block-p
andfsharp-goto-beyond-final-line
. This goes like so:fsharp-statement-opens-block-p
needs to compute whether or not the current statement creates a new block or not. To do this, it searches between the current value ofpoint
, and an endpoint calledfinish
.finish
is set to the value offsharp-goto-beyond-final-line
.fsharp-goto-beyond-final-line
claims to go to the line after the end of "the current statement."[^1]fsharp-goto-beyond-final-line
uses a while loopand
-ing onfsharp-continuation-line-p
.fsharp-continuation-line-p
only considers a line a "continuation line" if it either 1) ends in a dangling arithmetic operator or 2) point is inside a block delimited by a pair (i.e. point is inside[]
or{}
). This means the function almost always goes one line forward, then returnspoint
at that position.fsharp-statement-opens-block-p
immediately adjusts the value returned fromfsharp-continuation-line-p
by subtracting1
.To summarize:
fsharp-statement-opens-block-p
is taking an incredibly convoluted approach to searching until end of same line. This might be correct, but there are no previously existing tests.fsharp-goto-beyond-final-line
definitely does no such thing. (Again, no tests.)fsharp-continuation-line-p
is being used when we likely want a slightly different function.For example,
let x = 5 +
is a "continuation line", buttype Shape =
is not.(As a final, frustrating note, F# does not, in fact, have statements, at all.)
Proposed Solutions
fsharp-statement-opens-block-p
needs to reliably return whether or not the statement (which is to say, expression) opens a block. It is used all over the place, so should be well documented, and under test. (Also, the name should be changed to use "expression" over "statement".)fsharp-goto-beyond-final-line
should do so, and be under test. I assert we need a function similar to, but distinct from,fsharp-continuation-line-p
. Something likefsharp-in-block-p
-- "tell me if this line could be considered part of an ongoing block." Right now, there is no code to detect this -- it's handled infsharp-compute-indentation
as the final default "fall-through" case, so lacks a proper predicate. We should probably have one!Footnotes
[^1] Note that if #223 has been merged, this will say "the current expression."
The text was updated successfully, but these errors were encountered: