TextDocument::merge_span_collections() automatically makes sure that the
spans are valid, move forwards, are in order, and do not overlap. This
means we don't have to check these things every time TextEditor paints
the document.
merge_span_collections() now does these checks instead. I am not certain
they are still useful, but someone in the past certainly did. I have
modified them to take advantage of the operator overloads and Formatter
that we now have.
Updated TextDocument and TextEditor to use calls to
`find_grapheme_segmentation_boundary` in order to make "correct-feeling"
deletions on backspace and delete keys being pressed
Note that for traversing words with ctrl+(left or right arrow) on the
keyboard, we want to "skip" some boundaries. Consider the text:
The ("quick") fox can't jump 32.3 feet, right?
Using "|" to denote word break boundaries, we will have:
|The| |(|"|quick|"|)| |fox| |can't| |jump| |32.3| |feet|,| |right|?|
When starting at "The" and using ctrl+right to move rightward in this
text, it is unlikely that users will want to break at every single one
of those boundaries. Most text editors, for example, will skip from the
end of "The" to the end of "quick", not breaking at the parentheses or
opening quotation marks.
We try to mimic such desired behavior here. It likely isn't perfect, but
we can improve upon it as we find edge cases.
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
This adds shortcut for inserting a new empty indented line
above/below current cursor position.
- <Ctrl-Return> for inserting line below.
- <Ctrl-Shift-Return> for inserting line above.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
If selected text is less than a whole line, usual delete/replace takes
place. Otherwise, if the selected text is a whole line or spans
multiple lines, the selection will be indented.
TextDocument::set_spans() now also takes a "span collection index"
argument.
TextDocument keeps a map between a span collection index and its spans.
It merges the spans from all collections into a single set of spans
whenever set_spans() is called.
This allows us to style a document with multiple layers of spans, where
as previously we only supported a single layer of spans that was set
from the SyntaxHighlighter.
This impacts text editors' ctrl+left, ctrl+shift+right, ctrl+backspace,
etc..
For example, consider the text "Hello world |", pressing
ctrl+backspace each time.
Before: "hello world |"
"hello world|"
"hello |"
"hello|"
"|"
After: "hello world |"
"hello|"
"|"
Note that this breaks a nice symmetry. Doing ctrl+left and then
ctrl+right doesn't necessarily get you to the same place like it use to.
Before: " hello |"
" hello| "
" hello |" // same as initial
After: " hello |"
"|hello "
" hello| " // different from initial
There used to be the silly bug that when the cursor was already at the
end of a span (e.g. because the user just pressed Ctrl-Right), then
Ctrl-Right had no effect.
This bug does not appear with Ctrl-Left because due to the order in
which the spans are iterated, the effective result is always correct.
This patch also makes it more apparent that the algorithm is
unnecessarily inefficient.
This is a helpful option to prevent unwanted side effects, distinguish
between user and programmatic input, etc. Sliders and SpinBoxes were
implementing it idiosyncratically, so let's generalize the API and
give Buttons and TextEditors the same ability.
Previously, pressing 'x' for deletion on an otherwise empty line
insinuated a crash in TextEditor because a nonexistent code point was
accessed -- likewise for visual mode.
In Vim's insert mode, Ctrl-W deletes the word before the cursor, like
Ctrl-Backspace. Unlike Ctrl-Backspace, if only whitespace exists between
the end of the word and the cursor, the word will be deleted with the
whitespace.
To do so, this commit introduces two methods: delete_previous_word() for
TextEditor and first_word_before() for TextDocument, where the former
depends on the latter. delete_previous_word() is then called in
VimEditingEngine.
This replaces ctype.h with CharacterType.h everywhere I could find
issues with narrowing conversions. While using it will probably make
sense almost everywhere in the future, the most critical places should
have been addressed.
UndoStack will now merge adjacent commands *if they want to be merged*
instead of bundling everything you push onto it until you tell it
to "finalize the combo."
This uses less memory and gives applications full control over how
their undo stacks end up. :^)
Have TextDocument listen for state changes on the internal undo stack,
and forward those to all clients via a new virtual function.
This simplifies updating the can_undo / can_redo states of TextEditor.
This patch removes an incorrect way for TextDocument::text_in_range
to return early when the first line of the selection was empty. This
fixes an issue in TextEditor where the status bar showed that 0
characters are selected when the selection started on an empty line.