Changes the completer trait to take a mutable reference of itself on
calling `Completer::complete`
This enables the `Completer` to do caching or other smart things on the fly.
* generic reedline menus
* change word in description
* correct tests in examples
* corrected menu names
* renamed menu
* option for menus to take full line buffer
* corrected list menu insertion
The fallible std::io::Results were originally introduced for the history
file but the critical points are completely separated from the builder
pattern now.
Makes the public API nicer
* add description to completion suggestions
* completion menu with help
* corrected doc tests
* moved menu functions to module
* menu type with its own completer
* corrected doc tests
* function for menus to quick complete
Painter is currently leaked by `Menu` trait. Thus document the safe part
that is used for this implementation.
Also define the responsibility of editor
- Terminate with semicolon, where return type `()`
- Invert some conditionals for readability
- `match` to `if let` if binary
- pass by value vs by reference
- `must_use` attribute where applicable (builder patterns)
- make internal `Mode` enum explicitly `ViMode`
- Docstring fixes
- Format explicit identifiers in docs
Changes the `Highlighter` trait to include the position of the cursor in
the buffer. This allows it to make cursor aware highlighting such as
highlighting matching braces or code blocks
Prerequisite to address nushell/nushell#4325
Instead of affecting the editor this lets `Reedline::read_line` return
with `Ok(Signal::Success)` containing a predefined command to be executed or
consumed by the app using `reedline` as a line editor.
The state of the editor is preserved. After the command execution in a
REPL the host would call `Reedline::read_line` again and the line editor
would be redrawn on the next free line.
Command will not be added to the history in this config.
Open for debate if this should not expect printed output from the
command and try to redraw on top or reset some state.
Addresses #312
Keybindings are currently configured to require the completion menu. To
use the completions you have to manually add it.
Undocumented: Changing the keybindings to use the old bash style
completions with `CircularCompletionHandler`
Track #307
Add safe `sync` method to `History`
This method both reads from the file and writes local additions. Is safe
when multiple `History` instances try to truncate the history file on
disk.
To avoid race conditions on the file uses the `fd_lock` crate for file
advisory locks. (Inspiration for that thanks to rustyline: https://github.com/kkawakam/rustyline/blob/master/src/history.rs)
Fixes#221
- Cover history file ops with tests
- Add test for conflicting writes that should truncate
- Add safe `sync` method to `History`
- Test `FileBackedHistory` for threadsafety
To allow the automatic execution of multiple new line separated lines
only take events up until enter and execute to check if complete valide
expression. Remaining events present in crossterms event queue will be executed on next invocation.
Removes the need for the explicit Paste event, which in it's current
implementation did not provide a performance benefit over the existing
machinery (From the current state, it seems that the performance
improvement of that patch relies on the change in inner loop poll
timeout)
Introduces a minimal performance regression for pasting large text
containing many newlines which is a single valid entry as after the
validation step a repaint is triggered
Fixes#282
All `repaint`/`buffer_paint` calls are removed from the event handling,
instead the `EventStatus` determines if a repaint is necessary:
- `Handled` -> repaint
- `Inapplicable` -> no action was taken, thus no need to repaint
Additionally some conditions to check and repeatedly used patterns
abstracted as methods.
* Make cntrl-arrow keys available with vi insert
Move the key bindings based on cntrl arrow keys to the shared defaults
and place the emacs only alt-special keys to emacs
* Move emacs keybindings to eponymous file
* Correct allocation behavior of `coerce_crlf`
Empty string optimization of Cow<str> has to be avoided when trying to
use pre-sized buffers
* Consolidate names to `screen_width/height`
* Simplify the `PromptCoordinate` down to the row
Column of the prompt origin is never different from 0, can thus be
elided.
* Encapsulate the large buffer state readonly
* Consolidate line requirement calculion
Currently several places exists that try to estimate the number of lines
required for a given content
Extract for obvious places in the painter
Rename 'estimated_wrapped_line_count` due to misleading name to
`estimate_single_line_wraps`
* Unify painter initialization step
Prevents misuse of the painter that would cause overflows in position
calculations due to size and prompt positions being out of lockstep
* Fix painter debug output
The prompt initialization was still hardcoded for the two line prompt.
Now all adaptation to account for the number of prompt lines is done
during repaint
* dynamic menu
* corrected string
* no hints when a menu is active
* status bar style
* changed default page size
* cargo clippy
* status bar for empty list
* Coerce to CRLF lazily
Will only introduce a CR if LF is not part of CRLF.
Only allocates if necessary
* Coerce CRLF for prompt as well
In this case handled right before painting as lifetime construct would
be tricky otherwise.
Hopeful fix for nushell/engine-q#575
Now take into account that the new cursor position might have to be at
the last line of the screen that is already used. (Was hidden when on
the last line of a multiline buffer due to superfluous `CRLF` in the
event handler)
Fixes#261
* Doc and integerify `estimated_wrapped_line_count`
Avoid unnecessary float conversion and use usize properties
* Correct and doc `line_width`
- Fix the unlikely failure case for strip_ansi_escapes (Fallibility seems
to be driven mostly by the std::io::Write implementation of that crate)
to also compute a correct width.
- Remove unnecessary type conversions
* Single alloc strip_ansi
* Collapse ANSI handling in wrapping
* Remove superfluous fluff from painter
* Remove outdated ListCompletionActionHandler
The implementation is incompatible with the line estimation of the
painter and superseded by the selection supporting menu.
* Internalize Completer and the related UI
- Remove the `CompletionActionHandler` trait
- Make a single `Completer` member of the `Reedline` engine
- Provide a `CircularCompletionHandler` in the engine
Open question: How to manage configuration, whether circular completions
or the interactive completion menu are preferred
* Rename `ContextMenu` to `CompletionMenu`
Clarifies the exact purpose
* Remove noop as hints are completed only at the end
* Clarify names for hint completion
* Support "token by token"-hint completion
Hints can now be completed partially
Keybindings: `Alt-right` `Alt-f` `Ctrl-right`
Uses whitespace as token/word boundary for now
* Fix event dispatch for history search mode
* Support Ctrl-Right in vi insert as well
Hint partial completion for vi
Also move word in insert mode like vim (Ctrl supported Alt unsupported)
Changes initiated by @elferherrera in #266 to enable flexibility in the keymapping and simplify the individual event handlers in `handle_editor_events`
To make complex keybindings that behave differently based on context use the `ReedlineEvent::UntilFound(Vec<ReedlineEvent>)` start with the most special case that will fail to handle if conditions are not met and end with the most general handler.
TODO: Check how this interacts with vi normal mode
* multiple options for keybindings
* corrected tests and keybindings
* with handled flag
* Fix repaint usage
Don't repaint on inapplicable cases
Repaint for the ctrl-d Delete action
* Use enum to indicate the handling status of event
* Revert to explicit event keybinding method
Makes the unique situation with UntilFound more prominent
* Fix ordering of Arrow events
* Make emacs arrow commands fully compatible
Co-authored-by: Fernando Herrera <fernando.j.herrera@gmail.com>
* Show content after cursor when completing
Currently the content after the cursor was completely omitted when
entering the completion menu
Addresses it for the simple case of everything fitting on the screen
Question what should take priority if the entry and menu together exceed
the hight of the screen remains open!
* Place the hint obligatory behind the line content
In line with the behavior in fish and zsh autosuggestions hints are
displayed after the line.
Next step would be to make the DefaultHinter/Hinter trait conformant to
this behavior and also allow history hint suggestions based on the whole
line content, while editing inside the line.
* Simplify hinter internals/capabilities
DefaultHinter now only supports history
Requires no copies of the whole history anymore
* Remove `HistoryCompleter` (was never pub)
* Fix doctest `Reedline::with_hinter`
* Add configurable character threshold for Hinter
Only hint if a certain number of characters has been typed
Default: 1
As this function can only be called outside running
`Reedline::read_line` it is not relevant for raw mode reasons and can be
replaced by standard `println!()`
In the hinter logic `LF` was always replaced by `CRLF` thus inserting unnecessary `CR`'s into the linebuffer that accumulate if a multiline entry is recalled via hint autosuggestion from history multiple times.
Carriage returns, that are not introduced at the end of the line as part of the painter or the OS convention, break the painting of multilines, as the cursor position might jump to the start of the multiline continuation prompt and start painting from there!
* Move running of EditCommands to the editor
- Moves the big match statement for `EditCommand`s into `Editor`
- Removes the need for many `pub` wrappers around the `LineBuffer`
- Make `Left` a `ReedlineEvent` as well
- Fix left, right, up, down for vi mode
* Fix left move in vi insert mode
* support double prompt
* clippy warning
* better cursor position
* Move to estimating the right prompt cutoff
* refactor to use line_width
* refactor to use line_width
Co-authored-by: Fernando Herrera <fernando.j.herrera@gmail.com>
* test big buffer
* clippy error
* more clippy corrections
* extra else for position
* debug cursor
* moving to debug section
* hints in big buffer
* case for prompt one line
* corrected extra line
Fixes `history_search_paint`:
- Fix unnecessary clear of single line
- Ensure LF to CRLF in search results
Fixes `Painter`:
- Make sure that Color is cleared after prompt (Currently depends on
Highlighter to provide a new color)
- Remove unnecessary fn
Introduce simple highlighting of the search term in the search result:
- Introduce `SingleMatchHighlighter` that will highlight all matches of
the search string
- Rename `DefaultHighlighter` to `ExampleHightlighter` as the behavior
seems not very useful for default use.
- Extract styling operations into styled text
There are latent concerns about unicode correctness, but as long as
crossterm/hints are providing correct chars/strs this is neither a security risk
(no unchecked/unsafe string ops on our side) nor
a DoS risk.
- Made move up and move down unicode safe
- Added the option to constrict the char search (vi `f` `F` `t` `T`) to
the current line as usual in vi
- Improved test coverage
* prompt moves based on hint
* checked sub for the prompt
* checked sub for the prompt
* using promplines
* clean flush
* split lines before print
* test with full print
* test with full print
* removed flush
* no split
* drawing function with prompt
* replacing space return to string
* history search in repaint buffer
* using last row
* removed extra required lines
- current line detection was off on the first position of a following
line
- find_current_line_end was not correctly aware of CRLF platforms
- Increase of coverage for some old functions
- Moves to start and beginning of the line
- Make start and end of buffer available for move via `Ctrl-Home` and
`Ctrl-End`
- Support vi style cutting of whole lines in the cut buffer.
- add vi style `p` after paste in addition to before cursor paste with
`P` or in emacs mode
- Enables vi style `dd` and paste
- Make sure the line to end cut and clear operations work only on the
line
* Disable hints during history traversal
Additional autosuggestion (history) hints are confusing while
navigating through the history.
Example history:
```
hello test
hello
something else
hello world
whatever
```
- Type `h`
- Press up arrow
- Prefix based history search will return `hello world`
- Press up arrow again
- Previously `hello <hint>world</hint>` now just `hello`
* Reduce code duplication before painting
* Move history newline escape to the file IO
Avoids potential interference with history search, makes
`History::iter_chronologic` nice again, simplifies it regarding hints
and should address the `history` command in a better way.
+ Extract escape
+ Remove unwrap
* Remove unnecessary optional history allocation
No need to clone if entry is duplicate or empty
* Offset setting changes
* Rename `PromptWidget` to `PromptCoordinates`
* Explicit setters
* Set offset implicitly on `full_repaint`
* Rename origin and offset
As suggested by JT
origin -> prompt_start
offset -> input_start
* Move tracking of offsets and size into painter
Relatively basic refactor of all tracking of prompt/input offsets as
well as the terminal size into the painter.
Some cooperative behavior in the engine is still required
Wrapping handler is currently still a crutch in the engine as it is not
`InsertChar` specific and should be handled for every buffer change
instead
* Simplify restore from history stearch
Prompt is simply updated via full repaint
* Fix ansi coloring for history prompt
also ignore reset color in non ansi colored mode
* Make pedantic clippy happier
* Ensure prompt creation is tight and not wrapping
Fix additional line that is created upon prompt creation if the previous
output was printing a new line. Also ensures that line clearing and
regular prompt creation at the bottom of the screen doesn't cause
scrolling issues (Currently a hardcoded solution for the two line
prompt)
Also reduces the API surface for tools only necessary to deal within raw
mode.
* Fix doctests for internals removal
`print_crlf()` was removed from the public API as it should only be used
in raw mode for internal stuff.
As soon as we leave `Reedline.read_line()` raw mode should be disabled
and the regular print macros should work as expected
Panicking inside reedline (or bubbling up an Err inside reedline's
critical sections that gets unwrapped/expected by the hosting
application) leaves the terminal in a bad state. Workaround that should
also work without cooperation by the consumer would be to include a call
to `disable_raw_mode` in the `Drop` trait. With standard stack-unwinding
panics will call the drop.
Calling `crossterm::terminal::disable_raw_mode` twice seems to be fine
if the program started in non-raw mode (under linux)
* Improve undo of EditCommands
Address #190
Formalize the undo role of different edit commands via exhaustive
matching
Will track every move, but won't cause inconsistent cursor jumps while
undoing
* Multiline continuation prompt introduced
* Hardcoded multiline continuation prompt styling
A way to convert `crossterm::style::Color` in `nu_ansi_term::Color` must
be found/implemented. This enables creating a Style from it.
Otherwise, it is necessary that the Style of the prompt is accessible
from everywhere.
* Forward Prompt's multline prompt to rendering func
* Finish #185
Co-authored-by: Antonio Natilla <antonio.natilla@studenti.unimi.it>
Co-authored-by: sholderbach <ho.steve@web.de>
Avoids jumping cursor to the prompt on full repaints of the standard
buffer. Does not completely remove a perceptable flicker at the fixed
position if animation is active.
Partially addresses #174 as other cases still need to be checked for
cursor updates
* Multiline continuation prompt introduced
* Hardcoded multiline continuation prompt styling
A way to convert `crossterm::style::Color` in `nu_ansi_term::Color` must
be found/implemented. This enables creating a Style from it.
Otherwise, it is necessary that the Style of the prompt is accessible
from everywhere.
Co-authored-by: Antonio Natilla <antonio.natilla@studenti.unimi.it>
* Drain crossterm events, prioritize last resize
This attempts to address #166, some slowness is still observed
Co-authored-by: JT <547158+jntrnr@users.noreply.github.com>
* Fix timing of repaint with drained events
* Initial code to coalesce edit commands
Co-authored-by: JT <547158+jntrnr@users.noreply.github.com>
Support for Shift-AltGr is required for several European keyboards (e.g. italian) #169#136#139#171
* Curly braces fix
* Curly braces fix for vim events
Co-authored-by: Antonio Natilla <antonio.natilla@studenti.unimi.it>
* Introduced 'repaint' flag on struct ReedLine, and associated builder function
* Added builder to configure and disable idle animations
* Ran `cargo fmt` and `cargo clippy`
* [BugFix] undo function
This commit solves the problem that when the undo function is performed,
for some reason the buffer remained with 1 character.
The FIX consists in correcting the logic of the current implementation
by bringing it to the initial design state; Where the vector of the
buffer had been initialized with an empty entry so that when performing
many times the undo brought you back to an initial condition with
the blank buffer rather than show you the first character.
* [Add] doc-test for set_previous_lines
This test was created specifically to check that the insertion
of characters and words in the Editor.edits vector works properly.
* Replace doctest with unittest
This does not require exposing private functionality as pub
* Fix naming according to #160
Co-authored-by: sholderbach <ho.steve@web.de>
* Fix CtrlD/CtrlC and reverse-history-search + stuff
- `Ctrl+C` and `Ctrl+D` did not work after the changes in #138 and #146
- Fixed by only registering the `ReedlineEvent` and defering
potentially necessary edits to the `handle_event` stage
- Defined their behavior for the reverse history search
- Corrected interactions with undo (as best as I could understand it)
- Reverse history search did not allow for browsing through its results
- Fixed `handle_history_search_event` and simplified the cases
- Register undo steps for the reverse history search (when entering and
leaving via enter)
- Added comments to similar sounding methods and variants (UPDATE IF
NECESSARY!)
- Moved the repaint stuff closer together in engine.rs for better
readability
- Noncritical stuff that caught my eye
* Test first/last line detection
* Ignore tarpaulin coverage build folder and html report
* Add tests for line buffer
* Capitalize char only moves a character to right
* Uppercasing and lowercasing words works
* Fix the swap grapheme function
I have made this to be close to what I inferred the intent to be. I
really think we should probably have two functions which do this:
`swap_grapheme_left` and `swap_grapheme_right` which work in the
mentioned direction.
* Fix swap words
Swap words only swap words and there is no change in position.
* Add equality derive for EditCommand and ReedlineEvent
* Move matches to keybinds for emacs edit mode
* Simplify event matching in emacs edit mode
* Bugfix: All matches happening at same point
* Add failing test to check keybinding override
* Bugfix: Inserting capital character works
* Unknown requirement: test to be to capture currently unknown requirement
* Add rstest
The reason is to easily write parameterized tests
* Add test: for emoji input to emacs
* Add tests and fixes for vi edit mode
* Reedline None event and vi keybinds
* Keybindings are overridable
* Vi Reedline::None
* Extract hinter and highlighter out of Painter
* Cleanup unused variables, add comments
* Remove AppendToHistory Event
* Keybindings talk in terms of ReedlineEvent
* Add placeholder docs
* Push History handling one-level up
* Modify Enter handling to match others
* Extract Previous and Next History commands from EditCommand to ReedlineEvent
* Remove reduncant EditCommand -> ViFragment
* Pull Up/Down from EditCommand to ReedlineEvent
* Pull SearchHistory from EditCommand to ReedlineEvent
* Refactor insertion wrapping code
* Push History handling one more level up
* Fix doc test: keybind interface change
* Remove redundant indirections
* Reorganize methods in engine
* Update vi binds from history to up/down operations
* Remove the hacky EditInsert brach from ReedlineEvent
* Remove vagueness from position method
* Pull terminal size into the main struct
* WIP: prompt widget
* Remove a bunch of stuff
- clock
- vi stuff
- requirement to do full repaint state management
* Remove edit mode from event matcher
* Extract out event handling into a function
* Add reedline specific enum
* Rebase fixes
* Update docs
* Re-add clock functionality
* Add event-parser
* Pull out Input Parsing out of the main struct
* Move input parsing stuff into a directory
* Move vi stuff into input parsing
* Re-introduce Vi-Mode
* Remove EditMode enum
* Emacs mode uses non-default keybindings
* Basic hygine for edit_mode
- Rename: input_parsing to edit_mode
- Rename: EmacsInputParser to Emacs
- Rename: ViInputParser to Vi
- Rename: InputParser to EditMode
- Add docs: EditMode
- Add docs: Vi
- Add docs: Emacs
* Remove update_keybindings interface
* Vi sends Repaint events on mode switch
* Rename new to create
* Organise tab handling into files
* Concretise assumptions as manul tests
* Add expectation (failing test)
* Store one-level history for tab handler
* Remove reset index from the public interface of TabCompletion
* Update note on cycling though the tab-completions
* Cleanup: Remove un-necessary indirections from engine to editor functions
* Cleanup: Remove dead code - partial_command
* Cleanup: Make undo/redo interface consistent with other editor functions
* Cleanup: abstract up/down command logic to appropriate units
* Add a core-editor folder
* Add editor
Currently this is more of less line_buffer the integration with engine
has a few hacky edges that need to taken care off.
* Pull cut buffer operations into editor
* [WIP] Fixing the history behavior
* Repaint mode switching after the 1sec case
* Back to history cursor with len for not used -> fixes the skipping the
most recent
* unit tests not yet adapted
* None logic not yet smart to be able to leave history traversal
* Rewriting history with JT
Fixing the basic traversal as well as the prefix based search.
Ctrl-R search still dysfunctional. Missing the duplicate detection, thus
not passing tests. Missing test coverage for moving forward in a search.
* Complete basic history test suite
* Test the forward behavior in prefix search
* Skip consecutive equal matches
* Fix Ctrl-R search
* Update file_backed.rs
Co-authored-by: JT <547158+jntrnr@users.noreply.github.com>
* Cursor updates with the appropriate history command
* History command inserts after the end
we will most likely store multiline commands in history as `String`s so
I have opted for a converstion of this string to a vector separated by
newlines in `set_buffer`.
* History Traversal paining rules
- On normal up down we update the cursor to the end of the line
- On prefix based up and down we do not update the cursor
Rationale for this is that when we are doing prefix search a user might
want to add more to his query so as to get better prefix matching and
having to delete through all the chars we would otherwise fill in might
be annoying.
* Fix prefix search not updating properly
* Normal traversal sets history string at cursor to line buffer
Co-authored-by: JT <547158+jntrnr@users.noreply.github.com>