Skip to content

Commit

Permalink
Add methods concerning the previous line
Browse files Browse the repository at this point in the history
  • Loading branch information
Verseth committed Jul 29, 2023
1 parent c162d83 commit 55f678e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.4] - 29.07.2023

[Diff](https://github.com/elk-language/go-prompt/compare/v1.1.3...elk-language:go-prompt:v1.1.4)

### Added
- `func (*prompt.Document).PreviousLineIndentSpaces() int`
- `func (*prompt.Document).PreviousLineIndentLevel(indentSize int) int`
- `func (*prompt.Document).PreviousLine() (s string, ok bool)`

## [1.1.3] - 29.07.2023

[Diff](https://github.com/elk-language/go-prompt/compare/v1.1.2...elk-language:go-prompt:v1.1.3)
Expand Down
34 changes: 34 additions & 0 deletions document.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ func (d *Document) CurrentLineIndentLevel(indentSize int) int {
return d.IndentLevel(d.TextBeforeCursor(), indentSize)
}

// Returns the amount of spaces that the previous line (relative to the cursor)
// is indented with.
func (d *Document) PreviousLineIndentSpaces() int {
line, ok := d.PreviousLine()
if !ok {
return 0
}
return d.IndentSpaces(line)
}

// Returns the indentation level of the previous line (relative to the cursor).
func (d *Document) PreviousLineIndentLevel(indentSize int) int {
line, ok := d.PreviousLine()
if !ok {
return 0
}
return d.IndentLevel(line, indentSize)
}

// TextBeforeCursor returns the text before the cursor.
func (d *Document) TextBeforeCursor() string {
r := []rune(d.Text)
Expand Down Expand Up @@ -349,6 +368,21 @@ func (d *Document) CurrentLine() string {
return d.CurrentLineBeforeCursor() + d.CurrentLineAfterCursor()
}

// Return the text of the previous line (relative to the cursor).
// If the cursor is on the first line then false is returned in the second value
// to signify that there is no previous line.
func (d *Document) PreviousLine() (s string, ok bool) {
indices := d.lineStartIndices()
pos := bisect.Right(indices, d.cursorPosition) - 1
if pos == 0 {
return "", false
}

prevLineStartIndex := indices[pos-1]
lineStartIndex := indices[pos]
return d.Text[prevLineStartIndex : lineStartIndex-1], true
}

// Array pointing to the start indices of all the lines.
func (d *Document) lineStartIndices() []istrings.RuneNumber {
// TODO: Cache, because this is often reused.
Expand Down
40 changes: 40 additions & 0 deletions document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,46 @@ func TestDocument_LastLineIndentLevel(t *testing.T) {
}
}

func TestDocument_PreviousLine(t *testing.T) {
tests := []struct {
document *Document
want string
ok bool
}{
{
document: &Document{
Text: "line 1\nline 2\nline 3\n line 4",
cursorPosition: 32,
},
want: "line 3",
ok: true,
},
{
document: &Document{
Text: "line 1\nline 2\nline 3\n line 4",
cursorPosition: 19,
},
want: "line 2",
ok: true,
},
{
document: &Document{
Text: "line 1\nline 2\nline 3\n line 4",
cursorPosition: 1,
},
want: "",
ok: false,
},
}

for i, tc := range tests {
got, ok := tc.document.PreviousLine()
if got != tc.want || ok != tc.ok {
t.Errorf("[%d] Should be (%#v, %#v), got (%#v, %#v)", i, tc.want, tc.ok, got, ok)
}
}
}

func TestDocument_TextAfterCursor(t *testing.T) {
pattern := []struct {
document *Document
Expand Down

0 comments on commit 55f678e

Please sign in to comment.