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 :^)
Before this we just added a new tab and left the `(Untitled)` tab in the
background. Now we instead check that it hasn't been modified and that
it's empty; if both these conditions are true we replace the blank
editor with the newly opened one.
This fixes issue #14429. The editor actions were not given a parent as
scope so defaulted to global. Because HackStudio can have multiple
editors and even multiple editor tab widgets, I chose the
VerticalSplitter that all editor tab widgets get added to as the parent.
With a Widget set as the parent, the action gets WidgetLocal scope and
allows the embedded terminals to receive shortcuts.
Thanks to Andreas for doing a quick look at this and pointing in the
right direction during an Office Hours stream :)
Previously if the user closed the last open tab in the last TabWidget
then the open file action would stop working until they explicitly
went to the View menu and added a new editor group.
Before this commit there was an attempt at preventing the user to
close the last open tab by hiding its close button, this didn't
account for the many other ways one could close it though.
Previously when trying to open a file from the tree view the file
would open in the currently selected tab, substituting the file
we were previously reading.
This change makes it so that clicking on a file from the tree view
opens it in a new tab, or selects the tab containing that file if
it's already open in the selected editor group.
URL had properly named replacements for protocol(), set_protocol() and
create_with_file_protocol() already. This patch removes these function
and updates all call sites to use the functions named according to the
specification.
See https://url.spec.whatwg.org/#concept-url-scheme
Before, the warning dialog would be opened after the NewProjectDialog,
leading to focus-fighting by the two windows. This fixes that and makes
the action more consistent with the standard serenity way of handling
unsaved changes by asking before the NewProjectDialog is brought up.
The way this is achieved avoids having to rewrite open_project as well.
And adjust some GML properties. Since a808cfa, splitters grow
opportunistically. Setting them to fixed sizes now quite literally
fixes them in place. Fixes immovable splitters missed in the
aforementioned commit.
This prevents us from needing a sv suffix, and potentially reduces the
need to run generic code for a single character (as contains,
starts_with, ends_with etc. for a char will be just a length and
equality check).
No functional changes.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
This commit adds support for the option described above.
The option can be seen after a right click on a TreeView item,
and it puts the item's full path in the clipboard.
This commit adds support for the option described above.
The option can be seen after a right click on a TreeView item,
and it puts the item's relative path in the clipboard (relative
to the project's root directory).
Before this commit the close tab button, which is meant to only
show when more than one tab is open, would be present on the tab
of a new project opened after the first project.
This was due to m_all_editor_tab_widgets not being cleared when closing
the first project. This is now cleared when close_current_project() is
called.
The find widget appears on Ctrl+F.
It uses the GUI::TextEditor search API to search for text, which also
takes care of highlighting the search results.
This will move the editors inside a tab widget and the user
will be able to add new editors as tabs as well as add new
tab widgets. The user will be able to easily switch between
editors as well as the tab widgets.
Currently we have a 'Project' menu with a 'New' menu in it, this tries
to organize things by just having one 'New...' sub-menu in the 'File'
menu that creates new files, projects and directories.
To solve conflicts, move 'Semantic Highlighting' to the 'View' menu.
As a result of both of these changes, remove 'Project' menu.
Use the ErrorOr pattern with the Core::System wrappers to propagate more
errors from the TerminalWrapper.
The run_command method, when called with WaitForExit::Yes now returns an
error on command failure.
Different thread highlights between widgets lead to different
visual weights between splitters, even when they have the same
width or height. This means some splitters look best at odd
sizes while others even. This sets the default spacing to the
most commonly used, depending on orientation, and adjusts
spacing for a few apps based on the new paint rect.
The most consistent look across apps requires some manual
tweaking occassionally. Knurlheads, use your discretion!
Splitters could be resized in such an order that all their remaining
children were fixed size, leading to unfillable gaps on resize events.
HackStudio and TextEditor already had logic to handle this edge case,
so this patch factors it into a general solution for all Splitters.
At least one widget is now guaranteed to be resizeable after a child
is removed.
Because the wake pipe is thread-local, it was previously not possible
to wake an event loop across a thread. Therefore, this commit
rearchitects event loop waking by making the wake function a member of
the event loop itself and having it keep a pointer to its thread's wake
pipe. The global wake() function calls wake on the current thread's
event loop.
This also fixes a bug in BackgroundAction: it should wake the event loop
it was created on, instead of the current thread's event loop.
When saving a new file, save_as_action will return if the filename
input was empty, but save_action would still try to save the file.
Added a guard to make sure we never try to save files with empty
filenames.
Until it becomes enough stable and performant, semantic highlighting is
disabled by default.
It can be toggled on via the "Project" menu in HackStudio.
LexicalPath is a 'heavier' object than a String that is mainly used for
path parsing and validation, we don't actually need any of that in
GitRepo and its related files, so let's move to String :^)
I've also done some east-const conversion in the files that I was
editing for the string change.
Previously the debuggee process used the same tty of the HackStudio
process.
We now set things up so the debuggee gets attached to the
TerminalWrapper in the "Console" tab.
Persist EditingEngine mode in HackStudio and TextEditor when opening new
files or editing splits. Previously, the EditingEngine defaulted to a
RegularEditingEngine for a new Editor, even if Vim Emulation had been
selected in the existing Editor.
If you saved a file under a different name and then went back to
the first file, then you had the same TextDocument buffer, and therefore
the same changes to the file as in the new one.
Previously, the modification tag in the editor file label was unset only
after a file was saved.
This commit will also unset the tag if you undo the stack (for example
by hitting Ctrl+Z) to the last saved state.
Core::deferred_invoke is a way of executing an action after previously
queued events have been processed. It removes the requirement of
having/being a Core::Object subclass in order to defer invocation
through Core::Object::deferred_invoke.
Core::Object::deferred_invoke now delegates to Core::deferred_invoke.
The version with the Object& argument is still present but will be
removed in the following commits.
This commit additionally fixes a new places where the
DeferredInvocationEvent was dispatched to the event loop directly, and
replaces them with the Core::deferred_invoke equivalent.
The more important thing here is to update the tree view
on 'Save As..', as we want to drop every connection from an old file.
Updating the tree view on current editor change is just a cool small
bonus. :^)
Prior this change, if user had more than two copies of one file opened
in a split view, then only the active editor was renamed,
when the others had the same file contents changed.
This change will set a new file name for every file.
The is_null() check is for uncreated files, as they shouldn't be
treated as the same single file.
This makes the editor title a bit more consistent with the other files
and removes duplicating the file name in the file history
when reopening that file.
The editor's on_change callback was being overwritten in
HackStudioWidget.cpp in order to call update_gml_preview on every
change. This stopped the original callback from being called and marking
files as dirty when changed.
Now we call update_gml_preview in a new callback within the editor
wrapper, which is then called within the original on_change callback
in the editor.
GitWidget no longer crashes upon trying to create a repository for a new
project, and it correctly updates after opening a different project. A
new method, change_repo, has been added to make this work, which changes
m_repo_root and resets most of the widget's state in order to make this
work.
Moved code to stop the debugger in the HackStudioWidget destructor to
a new method so that this can be called in both the destructor and when
opening a new project.
The ToDoEntries and ToDoEntriesWidget classes now have methods for
clearing the entries, before entries would stay permanently, even after
switching to a new project.
Added a close_file_in_all_editors method to HackStudioWidget and moved
the code from handle_external_file_deletion into it so that it can be
reused elsewhere to close files.
Prior this change, the window title was updated only when a new file
has been opened, which means that it wasn't updated when user selected
an already opened file in the split view.
This change updates the title whenever the active editor changes.
In addition, this title update logic has now its own function
as it'll also be used in the next commit. :)
This allows for typing [8] instead of [8, 8, 8, 8] to specify the same
margin on all edges, for example. The constructors follow CSS' style of
specifying margins. The added constructors are:
- Margins(int all): Sets the same margin on all edges.
- Margins(int vertical, int horizontal): Sets the first argument to top
and bottom margins, and the second argument to left and right margins.
- Margins(int top, int vertical, int bottom): Sets the first argument to
the top margin, the second argument to the left and right margins,
and the third argument to the bottom margin.
Previously the argument order for Margins was (left, top, right,
bottom). To make it more familiar and closer to how CSS does it, the
argument order is now (top, right, bottom, left).
28b1e66b51 made that
the m_all_editor_wrappers vector is cleared everytime a project path
is changed (the m_project if check is just for the app launch --
the vector is empty there anyway), making the code never execute.
Previously when user wanted to save an uncreated file, the program
would just quietly ignore the save request, without giving any message.
This can be seen when creating a new editor in split view mode.
Prior this change, the action opened a File Picker
in user home directory.
Changing the startup path to a project path might make correcting
the path or switching between different projects a bit faster,
as you don't have to go through the subdirectories all over again.
It's also the path that's showed in the project tree view.
Most of the models were just calling did_update anyway, which is
pointless since it can be unified to the base Model class. Instead, code
calling update() will now call invalidate(), which functions identically
and is more obvious in what it does.
Additionally, a default implementation is provided, which removes the
need to add empty implementations of update() for each model subclass.
Co-Authored-By: Ali Mohammad Pur <ali.mpfard@gmail.com>