Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiline cursor support #11

Merged
merged 21 commits into from
Jul 15, 2023
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
go: ['1.19', '1.20']
steps:
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
id: go
Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: '1.20'
id: go
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ _testmain.go

# Glide
vendor/

# Logs
log
*.log
203 changes: 158 additions & 45 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,192 @@
# Change Log
# Changelog

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.0.0]

[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.6...elk-language:go-prompt:v1.0.0)

This release contains a major refactoring of the codebase.
It's the first release of the [elk-language/go-prompt](https://github.com/elk-language/go-prompt) fork.

The original library has been abandoned for at least 2 years now (although serious development has stopped 5 years ago).

This release aims to make the code a bit cleaner, fix a couple of bugs and provide new, essential functionality such as syntax highlighting, dynamic <kbd>Enter</kbd> and multiline edit support.

### Added

- `prompt.New` constructor options:
- `prompt.WithLexer` let's you set a custom lexer for providing syntax highlighting
- `prompt.WithCompleter` for setting a custom `Completer` (completer is no longer a required argument in `prompt.New`)
- `prompt.WithIndentSize` let's you customise how many spaces should constitute a single indentation level
- `prompt.WithExecuteOnEnterCallback`

- `prompt.Position` -- represents the cursor's position in 2D
- `prompt.Lexer`, `prompt.Token`, `prompt.SimpleToken`, `prompt.EagerLexer`, `prompt.LexerFunc` -- new syntax highlighting functionality
- `prompt.ExecuteOnEnterCallback` -- new dynamic <kbd>Enter</kbd> functionality (decide whether to insert a newline and indent or execute the input)

- examples:
- `_example/bang-executor` -- a sample program which uses the new `ExecuteOnEnterCallback`. Pressing <kbd>Enter</kbd> will insert a newline unless the input ends with an exclamation point `!` (then it gets executed).
- `_example/even-lexer` -- a sample program which shows how to use the new lexer feature. It implements a simple lexer which colours every character with an even index green.

### Changed

- Update Go from 1.16 to 1.19
- The cursor can move in 2D (left-right, up-down)
- The Up arrow key will jump to the line above if the cursor is beyond the first line, but it will replace the input with the previous history entry if it's on the first line (like in Ruby's irb)
- The Down arrow key will jump to the line below if the cursor is before the last line, but it will replace the input with the next history entry if it's on the last line (like in Ruby's irb)
- <kbd>Tab</kbd> will insert a single indentation level when there are no suggestions
- <kbd>Shift</kbd> + <kbd>Tab</kbd> will delete a single indentation level when there are no suggestions and the line before the cursor consists only of indentation (spaces)
- Make `Completer` optional when creating a new `prompt.Prompt`. Change the signature of `prompt.New` from `func New(Executor, Completer, ...Option) *Prompt` to `func New(Executor, ...Option) *Prompt`
- Make `prefix` optional in `prompt.Input`. Change the signature of `prompt.Input` from `func Input(string, ...Option) string` to `func Input(...Option) string`.
- Rename `prompt.ConsoleParser` to `prompt.Reader` and make it embed `io.ReadCloser`
- Rename `prompt.ConsoleWriter` to `prompt.Writer` and make it embed `io.Writer` and `io.StringWriter`
- Rename `prompt.OptionTitle` to `prompt.WithTitle`
- Rename `prompt.OptionPrefix` to `prompt.WithPrefix`
- Rename `prompt.OptionInitialBufferText` to `prompt.WithInitialText`
- Rename `prompt.OptionCompletionWordSeparator` to `prompt.WithCompletionWordSeparator`
- Replace `prompt.OptionLivePrefix` with `prompt.WithPrefixCallback` -- `func() string`. The prefix is always determined by a callback function which should always return a `string`.
- Rename `prompt.OptionPrefixTextColor` to `prompt.WithPrefixTextColor`
- Rename `prompt.OptionPrefixBackgroundColor` to `prompt.WithPrefixBackgroundColor`
- Rename `prompt.OptionInputTextColor` to `prompt.WithInputTextColor`
- Rename `prompt.OptionInputBGColor` to `prompt.WithInputBGColor`
- Rename `prompt.OptionPreviewSuggestionTextColor` to `prompt.WithPreviewSuggestionTextColor`
- Rename `prompt.OptionSuggestionTextColor` to `prompt.WithSuggestionTextColor`
- Rename `prompt.OptionSuggestionBGColor` to `prompt.WithSuggestionBGColor`
- Rename `prompt.OptionSelectedSuggestionTextColor` to `prompt.WithSelectedSuggestionTextColor`
- Rename `prompt.OptionSelectedSuggestionBGColor` to `prompt.WithSelectedSuggestionBGColor`
- Rename `prompt.OptionDescriptionTextColor` to `prompt.WithDescriptionTextColor`
- Rename `prompt.OptionDescriptionBGColor` to `prompt.WithDescriptionBGColor`
- Rename `prompt.OptionSelectedDescriptionTextColor` to `prompt.WithSelectedDescriptionTextColor`
- Rename `prompt.OptionSelectedDescriptionBGColor` to `prompt.WithSelectedDescriptionBGColor`
- Rename `prompt.OptionScrollbarThumbColor` to `prompt.WithScrollbarThumbColor`
- Rename `prompt.OptionScrollbarBGColor` to `prompt.WithScrollbarBGColor`
- Rename `prompt.OptionMaxSuggestion` to `prompt.WithMaxSuggestion`
- Rename `prompt.OptionHistory` to `prompt.WithHistory`
- Rename `prompt.OptionSwitchKeyBindMode` to `prompt.WithKeyBindMode`
- Rename `prompt.OptionCompletionOnDown` to `prompt.WithCompletionOnDown`
- Rename `prompt.OptionAddKeyBind` to `prompt.WithKeyBind`
- Rename `prompt.OptionAddASCIICodeBind` to `prompt.WithASCIICodeBind`
- Rename `prompt.OptionShowCompletionAtStart` to `prompt.WithShowCompletionAtStart`
- Rename `prompt.OptionBreakLineCallback` to `prompt.WithBreakLineCallback`
- Rename `prompt.OptionExitChecker` to `prompt.WithExitChecker`

## v0.3.0 (2018/??/??)
### Fixed

- Make pasting multiline text work properly
- Make pasting text with tabs work properly (tabs get replaced with indentation -- spaces)
- Introduce `strings.ByteNumber`, `strings.RuneNumber`, `strings.StringWidth` to reduce the ambiguity of when to use which of the three main units used by this library to measure string length and index parts of strings. Several subtle bugs (using the wrong unit) causing panics have been fixed this way.
- Remove a `/dev/tty` leak in `prompt.PosixReader` (old `prompt.PosixParser`)

### Removed

- `prompt.SwitchKeyBindMode`


## [0.2.6] - 2021-03-03

[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.5...elk-language:go-prompt:v0.2.6)

### Changed

- Update pkg/term to 1.2.0


## [0.2.5] - 2020-09-19

[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.4...elk-language:go-prompt:v0.2.5)

### Changed

- Upgrade all dependencies to latest

next release.

## v0.2.3 (2018/10/25)
## [0.2.4] - 2020-09-18

### What's new?
[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.3...elk-language:go-prompt:v0.2.4)

* Add `prompt.FuzzyFilter` for fuzzy matching at [#92](https://github.com/c-bata/go-prompt/pull/92).
* Add `OptionShowCompletionAtStart` to show completion at start at [#100](https://github.com/c-bata/go-prompt/pull/100).
* Add `prompt.NewStderrWriter` at [#102](https://github.com/c-bata/go-prompt/pull/102).
### Changed

- Update pkg/term module to latest and use unix.Termios


## [0.2.3] - 2018-10-25

[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.2...elk-language:go-prompt:v0.2.3)

### Added

* `prompt.FuzzyFilter` for fuzzy matching at [#92](https://github.com/c-bata/go-prompt/pull/92).
* `OptionShowCompletionAtStart` to show completion at start at [#100](https://github.com/c-bata/go-prompt/pull/100).
* `prompt.NewStderrWriter` at [#102](https://github.com/c-bata/go-prompt/pull/102).

### Fixed

* Fix resetting display attributes (please see [pull #104](https://github.com/c-bata/go-prompt/pull/104) for more details).
* Fix error handling of Flush function in ConsoleWriter (please see [pull #97](https://github.com/c-bata/go-prompt/pull/97) for more details).
* Fix panic problem when reading from stdin before starting the prompt (please see [issue #88](https://github.com/c-bata/go-prompt/issues/88) for more details).
* reset display attributes (please see [pull #104](https://github.com/c-bata/go-prompt/pull/104) for more details).
* handle errors of Flush function in ConsoleWriter (please see [pull #97](https://github.com/c-bata/go-prompt/pull/97) for more details).
* don't panic problem when reading from stdin before starting the prompt (please see [issue #88](https://github.com/c-bata/go-prompt/issues/88) for more details).

### Deprecated

### Removed or Deprecated
* `prompt.NewStandardOutputWriter` -- please use `prompt.NewStdoutWriter`.

* `prompt.NewStandardOutputWriter` is deprecated. Please use `prompt.NewStdoutWriter`.

## v0.2.2 (2018/06/28)
## [0.2.2] - 2018-06-28

### What's new?
[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.1...elk-language:go-prompt:v0.2.2)

* Support CJK(Chinese, Japanese and Korean) and Cyrillic characters.
* Add OptionCompletionWordSeparator(x string) to customize insertion points for completions.
* To support this, text query functions by arbitrary word separator are added in Document (please see [here](https://github.com/c-bata/go-prompt/pull/79) for more details).
* Add FilePathCompleter to complete file path on your system.
* Add option to customize ascii code key bindings.
* Add GetWordAfterCursor method in Document.
### Added

### Removed or Deprecated
* Support CJK (Chinese, Japanese and Korean) and Cyrillic characters.
* `OptionCompletionWordSeparator(x string)` to customize insertion points for completions.
* To support this, text query functions by arbitrary word separator are added in `Document` (please see [here](https://github.com/c-bata/go-prompt/pull/79) for more details).
* `FilePathCompleter` to complete file path on your system.
* `option` to customize ascii code key bindings.
* `GetWordAfterCursor` method in `Document`.

* prompt.Choose shortcut function is deprecated.
### Deprecated

## v0.2.1 (2018/02/14)
* `prompt.Choose` shortcut function is deprecated.

### What's New?

## [0.2.1] - 2018-02-14

[Diff](https://github.com/elk-language/go-prompt/compare/v0.2.0...elk-language:go-prompt:v0.2.1)

### Added

* ~~It seems that windows support is almost perfect.~~
* A critical bug is found :( When you change a terminal window size, the layout will be broken because current implementation cannot catch signal for updating window size on Windows.

### Fixed

* Fix a Shift+Tab handling on Windows.
* Fix 4-dimension arrow keys handling on Windows.
* <kbd>Shift</kbd> + <kbd>Tab</kbd> handling on Windows.
* 4-dimension arrow keys handling on Windows.

## v0.2.0 (2018/02/13)

### What's New?
## [0.2.0] - 2018-02-13

* Supports scrollbar when there are too many matched suggestions
* Windows support (but please caution because this is still not perfect).
* Add OptionLivePrefix to update the prefix dynamically
* Implement clear screen by `Ctrl+L`.
[Diff](https://github.com/elk-language/go-prompt/compare/v0.1.0...elk-language:go-prompt:v0.2.0)

### Fixed

* Fix the behavior of `Ctrl+W` keybind.
* Fix the panic because when running on a docker container (please see [here](https://github.com/c-bata/go-prompt/pull/32) for details).
* Fix panic when making terminal window small size after input 2 lines of texts. See [here](https://github.com/c-bata/go-prompt/issues/37) for details).
* And also fixed many bugs that layout is broken when using Terminal.app, GNU Terminal and a Goland(IntelliJ).
### Added

### News
* Support scrollbar when there are too many matched suggestions
* Support Windows (but please caution because this is still not perfect).
* `OptionLivePrefix` to update the prefix dynamically
* Clear screen by <kbd>Ctrl</kbd> + <kbd>L</kbd>.

New core developers are joined (alphabetical order).
### Fixed

* Nao Yonashiro (Github @orisano)
* Ryoma Abe (Github @Allajah)
* Yusuke Nakamura (Github @unasuke)
* Improve the <kbd>Ctrl</kbd> + <kbd>W</kbd> keybind.
* Don't panic because when running in a docker container (please see [here](https://github.com/c-bata/go-prompt/pull/32) for details).
* Don't panic when making terminal window small size after input 2 lines of texts. See [here](https://github.com/c-bata/go-prompt/issues/37) for details).
* Get rid of many bugs that layout is broken when using Terminal.app, GNU Terminal and a Goland(IntelliJ).


## v0.1.0 (2017/08/15)
## [0.1.0] - 2017-08-15

Initial Release
14 changes: 13 additions & 1 deletion _example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
This directory includes some examples using go-prompt.
These examples are useful to know the usage of go-prompt and check behavior for development.

## even-lexer

Uses a custom lexer that colours every character with an even index green.

Shows you how to hook up a custom lexer for syntax highlighting.

## bang-executor

Inserts a newline when the <kbd>Enter</kbd> key is pressed unless the input ends with an exclamation point `!` (then it gets printed).

Shows you how to define a custom callback which determines whether the input is complete and should be executed or a newline should be inserted (after <kbd>Enter</kbd> has been pressed).

## simple-echo

![simple-input](https://github.com/c-bata/assets/raw/master/go-prompt/examples/input.gif)
Expand All @@ -19,7 +31,7 @@ A simple [http-prompt](https://github.com/eliangcs/http-prompt) implementation u

![live-prefix](https://github.com/c-bata/assets/raw/master/go-prompt/examples/live-prefix.gif)

A example application which changes a prefix string dynamically.
A example application which changes the prefix string dynamically.
This feature is used like [ktr0731/evans](https://github.com/ktr0731/evans) which is interactive gRPC client using go-prompt.

## exec-command
Expand Down
26 changes: 26 additions & 0 deletions _example/bang-executor/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"unicode/utf8"

"github.com/elk-language/go-prompt"
)

func main() {
p := prompt.New(
executor,
prompt.WithExecuteOnEnterCallback(ExecuteOnEnter),
)

p.Run()
}

func ExecuteOnEnter(input string, indentSize int) (int, bool) {
char, _ := utf8.DecodeLastRuneInString(input)
return 1, char == '!'
}

func executor(s string) {
fmt.Println("You printed: " + s)
}
1 change: 1 addition & 0 deletions _example/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ go build -o ${BIN_DIR}/live-prefix ${DIR}/live-prefix/main.go
go build -o ${BIN_DIR}/simple-echo ${DIR}/simple-echo/main.go
go build -o ${BIN_DIR}/simple-echo-cjk-cyrillic ${DIR}/simple-echo/cjk-cyrillic/main.go
go build -o ${BIN_DIR}/even-lexer ${DIR}/even-lexer/main.go
go build -o ${BIN_DIR}/bang-executor ${DIR}/bang-executor/main.go
7 changes: 1 addition & 6 deletions _example/even-lexer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import (
func main() {
p := prompt.New(
executor,
completer,
prompt.OptionSetLexer(prompt.NewEagerLexer(lexer)),
prompt.WithLexer(prompt.NewEagerLexer(lexer)),
)

p.Run()
Expand All @@ -38,10 +37,6 @@ func lexer(line string) []prompt.Token {
return elements
}

func completer(in prompt.Document) []prompt.Suggest {
return []prompt.Suggest{}
}

func executor(s string) {
fmt.Println("You printed: " + s)
}
17 changes: 9 additions & 8 deletions _example/exec-command/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import (
)

func executor(t string) {
if t == "bash" {
cmd := exec.Command("bash")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
if t != "bash" {
return
}
return

cmd := exec.Command("bash")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}

func completer(t prompt.Document) []prompt.Suggest {
Expand All @@ -27,7 +28,7 @@ func completer(t prompt.Document) []prompt.Suggest {
func main() {
p := prompt.New(
executor,
completer,
prompt.WithCompleter(completer),
)
p.Run()
}
Loading