Skip to content

Commit

Permalink
ca/fix: Don't suggest to Update TOC when it's up to date
Browse files Browse the repository at this point in the history
Resolves #52
  • Loading branch information
artempyanykh committed Aug 25, 2022
1 parent ba83152 commit fd2fc28
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 108 deletions.
90 changes: 49 additions & 41 deletions Marksman/CodeActions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,63 +22,71 @@ let documentEdit range text documentUri : WorkspaceEdit =

let tableOfContents (document: Doc) : DocumentAction option =
match TableOfContents.mk document.index with
| Some (toc) ->
| Some toc ->
let rendered = TableOfContents.render toc
let existing = TableOfContents.detect document.text
let existingRange = TableOfContents.detect document.text

let name =
match existing with
| None -> "Create a Table of Contents"
| _ -> "Update the Table of Contents"
let existingText =
existingRange
|> Option.map document.text.Substring
|> Option.map (fun x -> x.Trim())

let insertionPoint =
match existing with
| Some (range) -> Replacing range
| None -> TableOfContents.insertionPoint document
if existingText = Some rendered then
None
else
let name =
match existingRange with
| None -> "Create a Table of Contents"
| _ -> "Update the Table of Contents"

logger.trace (
Log.setMessage ("Determining table of contents insertion point")
>> Log.addContext "insertionPoint" insertionPoint
>> Log.addContext "existing" existing
>> Log.addContext "text" rendered
)
let insertionPoint =
match existingRange with
| Some range -> Replacing range
| None -> TableOfContents.insertionPoint document

let isEmpty lineNumber = document.text.LineContent(lineNumber).Trim().Length.Equals(0)
logger.trace (
Log.setMessage "Determining table of contents insertion point"
>> Log.addContext "insertionPoint" insertionPoint
>> Log.addContext "existing" existingRange
>> Log.addContext "text" rendered
)

let emptyLine = NewLine + NewLine
let lineBreak = NewLine
let isEmpty lineNumber = document.text.LineContent(lineNumber).IsWhitespace()

let editRange, newLinesBefore, newLinesAfter =
match insertionPoint with
| DocumentBeginning ->
let after =
if isEmpty Text.documentBeginning.Start.Line then "" else emptyLine
let emptyLine = NewLine + NewLine
let lineBreak = NewLine

Text.documentBeginning, "", after
let editRange, newLinesBefore, newLinesAfter =
match insertionPoint with
| DocumentBeginning ->
let after =
if isEmpty Text.documentBeginning.Start.Line then "" else emptyLine

| Replacing range ->
let before =
if range.Start.Line <= 0 || isEmpty (range.Start.Line - 1) then
""
else
emptyLine
Text.documentBeginning, "", after

let after = if isEmpty (range.End.Line + 1) then "" else emptyLine
| Replacing range ->
let before =
if range.Start.Line <= 0 || isEmpty (range.Start.Line - 1) then
""
else
emptyLine

range, before, after
let after = if isEmpty (range.End.Line + 1) then "" else emptyLine

| After range ->
let lineAfterLast = range.End.Line + 1
let newRange = Range.Mk(lineAfterLast, 0, lineAfterLast, 0)
range, before, after

let before = if isEmpty range.End.Line then "" else lineBreak
let after = if isEmpty (lineAfterLast) then lineBreak else emptyLine
| After range ->
let lineAfterLast = range.End.Line + 1
let newRange = Range.Mk(lineAfterLast, 0, lineAfterLast, 0)

newRange, before, after
let before = if isEmpty range.End.Line then "" else lineBreak
let after = if isEmpty (lineAfterLast) then lineBreak else emptyLine

newRange, before, after

let text = $"{newLinesBefore}{rendered}{newLinesAfter}"

Some { name = name; newText = text; edit = editRange }
let text = $"{newLinesBefore}{rendered}{newLinesAfter}"

Some { name = name; newText = text; edit = editRange }

| _ -> None
4 changes: 4 additions & 0 deletions Marksman/Misc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type String with

isMatching 0 0

member this.IsEmpty() : bool = String.IsNullOrEmpty(this)

member this.IsWhitespace() : bool = String.IsNullOrWhiteSpace(this)

member this.Slug() : string =
let mutable sb = StringBuilder()
let mutable sepSeen = false
Expand Down
2 changes: 0 additions & 2 deletions Marksman/Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,6 @@ type MarksmanServer(client: MarksmanClient) =
<| fun state ->
let docPath = opts.TextDocument.Uri |> PathUri.fromString

let documentBeginning = Range.Mk(0, 0, 0, 0)

let codeAction title edit =
{ Title = title
Kind = Some CodeActionKind.Source
Expand Down
2 changes: 1 addition & 1 deletion Marksman/Toc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module TableOfContents =
let mk (index: Marksman.Index.Index) : TableOfContents option =
let headings = index.headings |> Array.map (fun x -> x.data)

if index.headings.Length.Equals 0 then
if Array.isEmpty index.headings then
None
else
Some { entries = Array.map Entry.fromHeading headings }
Expand Down
94 changes: 30 additions & 64 deletions Tests/TocTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module DetectToc =

Assert.Equal(tocText.TrimEnd(), expectedTocText.TrimEnd())
Assert.Equal(3, toc.End.Line)
Assert.Equal(Toc.EndMarker.Length, toc.End.Character)
Assert.Equal(EndMarker.Length, toc.End.Character)

module CreateToc =
[<Fact>]
Expand Down Expand Up @@ -152,7 +152,7 @@ module RenderToc =
" - [T3](#t3)"
" - [T4](#t4)"
" - [T5](#t5)"
Toc.EndMarker |]
EndMarker |]

let expected = String.concat NewLine expectedLines

Expand All @@ -161,7 +161,7 @@ module RenderToc =
module DocumentEdit =
[<Fact>]
let insert_afterYaml () =
let text =
let text =
stripMarginTrim
$"
|---
Expand All @@ -174,6 +174,7 @@ module DocumentEdit =
|## T3
|#### T4
"

let doc = FakeDoc.Mk text

let action = CodeActions.tableOfContents doc |> Option.get
Expand All @@ -188,12 +189,12 @@ module DocumentEdit =
|tags: [1, 2]
|---
|
|{Toc.StartMarker}
|{StartMarker}
|- [T1](#t1)
| - [T2](#t2)
|- [T3](#t3)
| - [T4](#t4)
|{Toc.EndMarker}
|{EndMarker}
|
|## T1
|### T2
Expand Down Expand Up @@ -226,12 +227,12 @@ module DocumentEdit =
$"
|# T1
|
|{Toc.StartMarker}
|{StartMarker}
|- [T1](#t1)
| - [T2](#t2)
| - [T3](#t3)
| - [T4](#t4)
|{Toc.EndMarker}
|{EndMarker}
|
|### T2
|
Expand Down Expand Up @@ -264,12 +265,12 @@ module DocumentEdit =
let expected =
stripMarginTrim
$"
|{Toc.StartMarker}
|{StartMarker}
|- [T1](#t1)
| - [T2](#t2)
|- [T3](#t3)
| - [T4](#t4)
|{Toc.EndMarker}
|{EndMarker}
|
|## T1
|
Expand All @@ -283,81 +284,46 @@ module DocumentEdit =
Assert.Equal(expected, modifiedText)

[<Fact>]
let idempotent_application () =

let text =
stripMarginTrim
"
|---
|hello: bla
|yo: 11
|---
|
|## T1
|
|hello
|## T2
|
|### T3
|
|#### T4"

let doc = FakeDoc.Mk text
let update_atBeginningOfFile () =
let doc =
FakeDoc.Mk(
stripMarginTrim
$"
|{StartMarker}
|- [T1](#t1)
|{EndMarker}
|
|# T2"
)

let action = CodeActions.tableOfContents doc |> Option.get

let modifiedText = applyDocumentAction doc action

let expected =
stripMarginTrim
$"
|---
|hello: bla
|yo: 11
|---
|
|{Toc.StartMarker}
|- [T1](#t1)
|{StartMarker}
|- [T2](#t2)
| - [T3](#t3)
| - [T4](#t4)
|{Toc.EndMarker}
|
|## T1
|
|hello
|## T2
|
|### T3
|{EndMarker}
|
|#### T4"

Assert.Equal(expected, modifiedText)
|# T2"

let doc2 = FakeDoc.Mk modifiedText

let action2 = CodeActions.tableOfContents doc2 |> Option.get
let modifiedText2 = applyDocumentAction doc2 action2
Assert.Equal(expected, modifiedText)

Assert.Equal(expected, modifiedText2)

[<Fact>]
let update_atBeginningOfFile () =

let upToDate_noUpdate () =
let text =
stripMarginTrim
$"
|{Toc.StartMarker}
|{StartMarker}
|- [T1](#t1)
|{Toc.EndMarker}
|{EndMarker}
|
|# T1"

let doc = FakeDoc.Mk text

let action = CodeActions.tableOfContents doc |> Option.get

let modifiedText = applyDocumentAction doc action

let action = CodeActions.tableOfContents doc

Assert.Equal(text, modifiedText)
Assert.Equal(None, action)

0 comments on commit fd2fc28

Please sign in to comment.