This patch reintroduces the translation previously mistakenly removed
when adding support for different underline-styles.
Thanks for reporting the bug, kennethmyhra!
This commit should fix a bug where using leading whitespaces when a line
is wrapped results in a crash. Now it should correctly highlight the
leading whitespaces even when the leading whitespaces are longer than a
line.
The clipboard cannot reasonably contain the empty string. The clipboard
can be empty (i.e. cleared), sure, but that this check was about whether
the clipboard contained the empty string.
This cannot easily happen for two reasons:
- TextEditor GUI elements disable their copy actions when the selection
is empty.
- Clipboard::set_data, through which all text-copying operates,
implicitly forbids empty strings, because Process::sys$anon_create
forbids empty anonymous files.
- Even if it were sent (e.g. by creating a non-empty anonymous file and
sending it manually to the Clipboard server), it would not be
received, because decode(Decoder&, Core::AnonymousBuffer&) goes
through mmap() with a size of 0, which also is forbidden by the
Kernel.
In other words, if the clipboard is never the empty text, therefore
checking this condition is pointless, and we can save a roundtrip to the
Clipboard server.
Having the delete key handling be done via an action limits our ability
to support key modifiers (e.g. ctrl+delete deleting the word in front of
the cursor).
The fact that it was an action _did_ allow us to have a delete button in
the TextEditor UI. However, this is an odd choice in the first place
that isn't common in other text editors, so I just removed it.
Previously there was a situation where the autocomplete box would
appear to "jump" to the side. This was due to the following race
condition:
1. Start typing, thus triggering the autocomplete timer to start
2. Manually trigger autocomplete before the timer finishes
3. Continue typing
4. The autocomplete timer now fires
When the timer fires it causes the autocomplete box to show, which, if
it is already shown, has the effect of moving the box to the current
cursor position.
Previously the autocomplete box would always close after applying a
suggestion. This is the desired behavior in almost all cases, but there
are some situations (like autocompleting paths) where it would be nicer
to keep the autocomplete box open after applying the suggestion.
Moving the cursor to a different location, by any means, should
dismiss the autocomplete popup. This is the behavior of virtually
every editor/IDE out there, and it is really annoying (and
confusing) when our autocomplete doesn't behave like that.
Previously if there were no suggestions, we simply wouldn't show the
autocomplete popup at all. This is functional, but when there are no
resultes it does leave the user wondering if it actually worked.
Now, if the user requests autocomplete and we do have requests, it
behaves exactly as before, but if there' aren't any we now show a box
with the message "No suggestions" to show the user that we got the
request, there just isn't anything to suggest.
Showing the selection in non-focused text editors was not really useful,
since refocusing the widget would clear or change the selection
immediately anyway.
Note that TextEditors in inactive windows can still be the focused
widget within that window, and will still be painted with an "inactive"
looking selection.
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.
Only one place used this argument and it was to hold on to a strong ref
for the object. Since we already do that now, there's no need to keep
this argument around since this can be easily captured.
This commit contains no changes.
This allows the address bar to "select all" when initially gaining focus
as Firefox and Chrome do. A future improvement on this would be for the
Widget class to mange and provide focus transition as part of the events
instead of the UrlBox class. Currently focus is updated before the event
is provided to the UrlBox class.
This ensures that the user can't copy/cut text from password boxes which
would reveal the password. It also makes sure that the undo/redo actions
stay disabled because it's difficult to reason about what these do
exactly without being able to see the result.
Anyone who inherits from `GUI::Clipboard::ClipboardClient` will receive
clipboard notifications via `clipboard_content_did_change()`.
Update ClipboardHistoryModel, TextEditor and TerminalWidget to inherit
from this class.
This prevents GUI::TextBox and the `Paste & Go` action in the browser
from trying to paste a bitmap. Also, the paste action is enabled
and disabled on clipboard change to reflect if the clipboard data
can be pasted.
While under insert mode, Ctrl-U deletes all characters between the first
non-blank character of the line and the cursor.
Implement delete_from_line_start_to_cursor() in TextEditor. Then, call
the method in VimEditingEngine via its pointer to an instance of
TextEditor.
In Vim, Ctrl-H is effectively equivalent to backspace in insert mode, as
it deletes the previous character.
This commit implements method delete_previous_char() to TextEditor.
delete_char() already exists in EditingEngine, but it deletes the
next character rather than the previous. delete_previous_char() is then
called from within VimEditingEngine.
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.
AK's version should see better inlining behaviors, than the LibM one.
We avoid mixed usage for now though.
Also clean up some stale math includes and improper floatingpoint usage.
Making use of the new FileSystemAccessServer we are able to use
unveil without restricting our ability to open and save files.
A file argument will be unveiled automatically however all other files
require user action via the FileSystemAccessServer to gain access.
This patch adds the member variable m_substitution_code_point to
GUI::TextEditor. If non-zero, all gylphs to be drawn will be substituted
with the specified code point. This is mainly needed to support a
PasswordBox.
While the primary use-case is for single-line editors, multi-line
editors are also supported.
To prevent repeated String construction, a m_substitution_string_data
members has been added, which is an OwnPtr<Vector<u32>>. This is used as
a UTF-32 string builder. The substitution_code_point_view method uses
that Vector to provide a Utf32View of the specified length.
This patch fixes a bug where double-clicking on a word in a TextEditor
with syntax highlighting would also select an additional character after
the word. This also simplifies the logic for double- and
triple-clicking.
If something happens in response to on_change that causes the widget
to get unparented, creating a GUI::Painter will fail since it can't
find the window to paint into.
Since painting only cares about the syntax highlighting spans, what we
really want is to ensure that spans are up-to-date before we start
painting.
The problem was that rehighlighting and the on_change hook were bundled
together in an awkward lazy update mechanism. This patch fixes that by
decoupling rehighlighting and on_change. Rehighlighting is now lazy
and only happens when we handle either paint or mouse events. :^)
Fixes#8302.
Gutter -- a space left of the text, before the ruler -- is not a part of
the ruler, nor should it be treated as such. This commit implements
gutter handling in LibGUI::TextEditor as part of mild cleaning up of the
gutter handling (breakpoint icons) in HackStudio's Editor.
This commit also enables separate theming of the gutter.
The autocomplete box closes on its own when the user tries to hover
over it because text_editor consideres hovering over the box to be
a leave_event. This commit stops that from happening.
This fixes#7946
Previously, TextEditor::write_to_file() would not mark its document
as unmodified if the file size was 0. This caused a desync in the
Text Editor app between the window's is_modified state and the
TextEditor's. It's already noted in the comments of the app's
save action code that propagating the modified state automatically
would be good, and it would solve issues like this, but I'm not yet
familiar enough with the code to try a change like that.
This fixes an off-by-one error in TextEditor's rendering of the syntax
highlighting as generated by Syntax::Highlighter and its subclasses.
Before, a single character span was e.g. (0-3) to (0-3), but this was
considered invalid by GUI::TextRange. Now, a single character span would
be e.g. (0-3) to (0-4).
This fix requires all Syntax::Highlighter subclasses to be adjusted, as
they all relied on the previous implementation. This will then also fix
a bug where single-character HTML tags wouldn't be highlighted.