Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

let _ =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

let _ =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

type T() =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

type T() =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

type T() =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ${CHAR:Enter}
// ${CHAR:Enter}
module Module

type T() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ class FSharpEnterHandlerDelegate : EnterHandlerDelegateAdapter() {
FSharpTokenType.END
)

private val bracketsAllowingDeindent: TokenSet = TokenSet.create(
FSharpTokenType.LBRACE,
FSharpTokenType.LBRACK,
FSharpTokenType.LBRACK_BAR,
FSharpTokenType.LPAREN
)

private val emptyBracketsToAddSpace = setOf(
Pair(FSharpTokenType.LBRACE, FSharpTokenType.RBRACE),
Pair(FSharpTokenType.LBRACK, FSharpTokenType.RBRACK),
Expand All @@ -108,7 +115,13 @@ class FSharpEnterHandlerDelegate : EnterHandlerDelegateAdapter() {
FSharpTokenType.LBRACK_BAR,
FSharpTokenType.LBRACK_LESS,
FSharpTokenType.LQUOTE_TYPED,
FSharpTokenType.LQUOTE_UNTYPED
FSharpTokenType.LQUOTE_UNTYPED,

FSharpTokenType.CLASS,
FSharpTokenType.INTERFACE,
FSharpTokenType.STRUCT,

FSharpTokenType.BEGIN
)

private val rightBracketsToAddSpace = emptyBracketsToAddSpace.map { it.second }.toSet()
Expand Down Expand Up @@ -621,6 +634,8 @@ class FSharpEnterHandlerDelegate : EnterHandlerDelegateAdapter() {
val document = editor.document
val line = document.getLineNumber(tokenStart)

if (handleEnterInsideSingleLineBrackets(editor, iterator, line)) return true

if (leftBracketsToAddIndent.contains(tokenType) &&
!isSingleLineBrackets(editor, tokenStart) &&
!isLastTokenOnLine(editor, tokenStart) &&
Expand Down Expand Up @@ -705,6 +720,71 @@ class FSharpEnterHandlerDelegate : EnterHandlerDelegateAdapter() {
return true
}

fun handleEnterInsideSingleLineBrackets(editor: Editor, iterator: HighlighterIterator, line: Int): Boolean {
val document = editor.document
val iterator = editor.highlighter.createIterator(iterator.start)

val tokenType = iterator.tokenType
val leftBracketStartOffset = iterator.start
val leftBracketEndOffset = iterator.end
val leftBracketLine = document.getLineNumber(leftBracketStartOffset)

if (!findRightBracket(iterator)) return false
if (document.getLineNumber(iterator.start) != leftBracketLine) return false

val rightBracketStartOffset = iterator.start

iterator.retreat()
while (iterator.tokenTypeSafe == FSharpTokenType.WHITESPACE)
iterator.retreat()

val lastElementEndOffset = iterator.end

val deindentIter = editor.highlighter.createIterator(leftBracketStartOffset - 1)
while (!deindentIter.atEnd() && isIgnored(iterator.tokenType))
deindentIter.retreat()

val shouldDeindent =
bracketsAllowingDeindent.contains(tokenType) && deindentIter.tokenType != FSharpTokenType.NEW_LINE

val baseIndentLength =
if (!shouldDeindent)
getOffsetInLine(document, line, leftBracketStartOffset)
else {
val line = getContinuedIndentLine(editor, leftBracketStartOffset, true)
getLineWhitespaceIndent(editor, line)
}

val indent = getIndentSettings(editor).indentSize
val baseIndentString = "\n" + " ".repeat(baseIndentLength)
val indentString = baseIndentString + " ".repeat(indent)

if (lastElementEndOffset == leftBracketEndOffset) {
val newText = if (tokenType == FSharpTokenType.LPAREN) {
indentString
} else {
indentString + baseIndentString
}
document.replaceString(lastElementEndOffset, rightBracketStartOffset, newText)
} else {
val firstElementIter = editor.highlighter.createIterator(leftBracketEndOffset)

while (!firstElementIter.atEnd() && isIgnored(firstElementIter.tokenTypeSafe))
firstElementIter.advance()

val firstElementStartOffset = firstElementIter.start

if (tokenType != FSharpTokenType.LPAREN) {
document.replaceString(lastElementEndOffset, rightBracketStartOffset, baseIndentString)
}
document.replaceString(leftBracketEndOffset, firstElementStartOffset, indentString)
}

editor.caretModel.moveToOffset(leftBracketEndOffset + indentString.length)
editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE)
return true
}

private fun handleEnter(
editor: Editor,
caretOffset: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class FSharpBracketMatcher : BracketMatcher(
Pair(FSharpTokenType.LBRACE_BAR, FSharpTokenType.BAR_RBRACE),
Pair(FSharpTokenType.LBRACK_LESS, FSharpTokenType.GREATER_RBRACK),
Pair(FSharpTokenType.LQUOTE_TYPED, FSharpTokenType.RQUOTE_TYPED),
Pair(FSharpTokenType.LQUOTE_UNTYPED, FSharpTokenType.RQUOTE_UNTYPED)
Pair(FSharpTokenType.LQUOTE_UNTYPED, FSharpTokenType.RQUOTE_UNTYPED),

Pair(FSharpTokenType.CLASS, FSharpTokenType.END),
Pair(FSharpTokenType.INTERFACE, FSharpTokenType.END),
Pair(FSharpTokenType.STRUCT, FSharpTokenType.END),

Pair(FSharpTokenType.BEGIN, FSharpTokenType.END)
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,19 @@ class FSharpEnterTypingAssistSyncTest : FSharpBackendSyncTypingAssistTestBase(Id
"Enter 28 - No indent after else and new line",
"Enter 29 - No indent before source",
"Enter 30 - No indent before source 2",
"Enter 31 - Inside empty ctor",
"Enter 32 - Nested binding",
"Enter 33 - After then on line with multiple parens in row",
"Enter 34 - After line with multiple parens in row",
"Enter 35 - Nested binding and indent",
"Enter 36 - Indent after =, trim before source",
"Enter 38 - Empty list",
"Enter 39 - Empty list with spaces",
"Enter 40 - Empty list continuing line",
"Enter 41 - Empty array continuing line",
"Enter 42 - Before first list element and new line",
"Enter 43 - Before first list element",
"Enter 44 - Before first list element and spaces",
"Enter 45 - Before first list element in multiline list",
"Enter 46 - Before first list element in multiline list",
"Enter 47 - Before first list element in multiline list",
Expand Down Expand Up @@ -261,7 +268,13 @@ class FSharpEnterTypingAssistSyncTest : FSharpBackendSyncTypingAssistTestBase(Id
"Enter - String 12",
"Enter - String 13",
"Enter - String 14",
"Enter - String 15"
"Enter - String 15",
"Enter - Parens - Begin 01",
"Enter - Parens - Begin 02",
"Enter - Parens - Type 01",
"Enter - Parens - Type 02",
"Enter - Parens - Type 03",
"Enter - Parens - Type 04"
)

@DataProvider(name = SUPPORTED_BACKEND_CASES)
Expand Down
Loading