The history completion query is extended to pick only the most recent item for
a given url.
The tests in test_models now check for ordering of elements.
Instead of add_list and add_sqltable, the completion model now supports
add_category, and callees either pass in a SqlCategory or ListCategory. This
makes unit testing much easier.
This also folds CompletionFilterModel into the ListCategory class.
The RFC on moving from plaintext to SQL storage (#2340) showed that many would
be upset if bookmarks and quickmarks were no longer stored in plaintext.
This commit uses list-based completion for quickmarks and bookmarks. Now the
history storage can be moved from plaintext to an on-disk SQL database while
leaving bookmarks and quickmarks as-is.
Now all completion models are of a single type called CompletionModel.
This model combines one or more categories. A category can either be a
ListCategory or a SqlCategory.
This simplifies the API, and will allow the use of models that combine simple
list-based and sql sources. This is important for two reasons:
- Adding searchengines to url completion
- Using an on-disk sqlite database for history, while keeping bookmarks and
quickmars as text files.
This was a performance optimization that shouldn't be needed with the new SQL
history backend. This also removes support for the LIMIT feature from SqlTable
as it only existed to support web-history-max-items.
Respond to the low-hanging code review fruit:
- Clean up some comments
- Remove an acidentally added duplicate init_autosave
- Combine two test_history tests
- Move test_init cleanup into a fixture to ensure it gets called.
- Name the _ argument of bind(_) to _key
- Ensure index is valid for first_item/last_item
- Move SqlException to top of module
- Rename test_index to test_getitem
- Return QItemFlags.None instead of None
- Fix copyright dates (its 2017 now!)
- Use * to force some args to be keyword-only
- Make some returns explicit
- Add sql to LOGGER_NAMES
- Add a comment to explain the sql escape statement
Change the logging to report the completion function name and have the end2end
tests check for this.
Remove the tests for realtime completion, as it was decided this is not an
important feature and the code is much simpler without it.
This just forwards canFetchMore and fetchMore to the underlying tables.
It seems to be returning True and fetching in some cases (with a large
history), so I guess it is useful?
Allow categories to specify a WHERE clause that applies in addition to the
pattern filter. This allows the url completion model to filter out redirect
entries.
This also fixed the usage of ESCAPE so it applies to all the LIKE statements.
A SQL completion category can now provide a customized column expression for
the select statement. This enables the url model to format timestamps, as well
as rearrange the name and url in the quickmark section.
This allows setting the query as a QSqlQuery instead of a string, which allows:
- Escaping quotes
- Using LIMIT (needed for history-max-items)
- Using ORDER BY (needed for sorting history)
- SELECTing columns (needed for quickmark completion)
- Creating a custom select (needed for history timestamp formatting)
For URL completion, time-based sorting is handled by the SQL model.
All the other models use simple alphabetical sorting. This allowed cleaning up
some logic in the sortfilter, removing DUMB_SORT, and removing the
completion.Role.sort.
This also removes the userdata completion field as it was only used in url
completion and is no longer necessary with the SQL model.
The new completion API no longer needs either of these. Instead of
referencing an enum member, cmdutils.argument.completion now points to
a function that returnsthe desired completion model.
This vastly simplifies the addition of new completion types. Previously
it was necessary to define the new model as well as editing usertypes
and completion.models.instances. Now it is only necessary to define a
single function under completion.models.
This is the next step of Completion Model/View Revamping (#74).
First step of Completion Model/View revamping (#74). Rewrite the
completion models as functions that each return an instance of a
CompletionModel class.
Caching is removed from all models except the UrlModel. Models other
than the UrlModel can be generated very quickly so caching just adds
needless complexity and can lead to incorrect results if one forgets to
wire up a signal.
This makes those UI elements look the same on different platforms/OS styles,
with the small drawback of overriding the context menu style.
This most likely fixes#80 (though I couldn't reproduce that on Windows 10).
I discovered this because of #2287 but it doesn't actually change anything
there. When we don't have a third column, subtract the scrollbar width from the
second one.
We already had some duplicated logic for completion/keyhint/messageview,
and plan to add prompt overlays too now - so here we refactor related
code to have a list of overlays instead, which are all
resized/positioned by the mainwindow when needed.
This also changes the size management, which gets moved into the
sizeHint of the respective overlay widgets.
Simplify the CompletionWidget/Completer interface by changing
on_selection_changed to pass the newly selected text rather than the
index of the newly selected item.
This moves the logic from Completer to CompletionWidget but simplifies
the interaction between the two and makes testing easier.
When the commandline reads ':open |', quick-completing the only offered
completion will set the commandline to ':open some_url |'. Since `open`
has `maxsplit=0`, everything after ':open' is (correctly) treated as
one argument. This means completion is opened again with 'some url '
as the pattern (note trailing whitespace), which makes the comletion
menu 'flicker' and stay open even though it was 'supposed' to quick
compelte.
This is fixed by ignoring the next completion request if we just
completed something after maxsplit (because we don't expect any more
completions after the last split).
Resolves#1519.
After the refactoring, _split is only called by _partition so just make
it part of the same method. This also removes the use of
_empty_item_index, as it can be figured out on the fly.
Remove the class variables _cursor_part and _empty_item_index. Instead,
split up the commandline around the cursor whenever that information is
needed. Using locals instead of class variables makes the logic easier
to follow and ends up requiring much less code.
Remove the dependency on the class variables _empty_item_index
and _cursor_part to make the code easier to follow. If
_update_completion is refactored in a similar way these variables can
be removed.
Turns out re.escape also escapes spaces, so we'd need to replace '(\\ )'
groups after escaping. At this point it's easier to just combine spaces
before escaping the pattern.
Fixes#1934.
Supersedes #1935.
Implement `completion-item-focus next-category` and
`completion-item-focus prev-category` to jump through completions by
category rather than by item.
Resolves#1567.
Command completions for `:bind` and `:` will now show bindings for
aliases. The binding is only included if it is bound to that alias, not
if it is bound to the command the alias points to.
Returning a defaultdict made the caller's code look confusing, as it
wasn't clear why there wouldn't be a Keyerror in some cases. Instead,
let the caller explicitly use `get`.
Consolidate the logic used to generate the command completion category
into one place. This is shared by CommandCompletionModel,
HelpCompletionModel, and BindCompletionModel.
Hidden commands are not shown in command completion as they typically
would not be run directly. However, a user might still might like to see
help for them if, for example, they are writing a script or creating a
binding.
Addresses #1707.
Wire up the config change event to update command completion on
changing aliases, so the new aliases will be included.
Fixes#1814.
Currently we do not have tests at a high enough level to test whether
signals are wired up correctly to update completions.
Completion.empty existed to fill a slot in the old Command.completions
interface if the first positional arg had no completions but the second
did, as is the case for the `bind` command. Now that
`Command.completions` is replaced by `Command.get_pos_arg_info`, this
is no longer needed.
Command completion types are now identified by ArgInfo, so just use
that directly and cut out the middle-man. This shouldn't change any
completion behavior.
Adds a test for get_pos_arg_info to test_cmdutils.
Modifies test_completer to test the use of get_pos_arg_info. Instead of
using FakeCommand, real Command objects are used, to validate that the
Completer works with the real Command interface. This also cleans out
some test cases that were testing things already covered by other cases.
first_item and last_item return an invalid index when there are no
items in the completion, and the completionwidget will throw on an
invalid index. However, setting an invalid index on the selection view
is fine, so just remove the assertion.
Resolves#1731.
These commands are more closely tied to the CompletionView than
Completer. This removes the need for an extra signal tying the
CompletionView to the Completer.
The call to _open_completion_if_needed was moved to
on_selection_changed, as this will already be called when a new item is
selected.
Rather than having a CompletionView instantiate and register a
Completer, instantiate both in MainWindow. The CompletionView is the
parent of the Completer, and communicates by emitting
selection_changed, meaning it no longer needs to contain a reference to
the Completer.
- clean up docstring typos
- use _ to name an unused loop variable
- parent the filter model to avoid an issue with disposal
- use mocker.patch instead of monkeypatch to mock Completer creation
- use is instead of == to compare by identity
It was implemented as a member of the Completer object, but registered
to the CompletionWidget. This led to the weird scenario where self was
actually a CompletionWidget, even though it was declared in Completer.
When a redirect occurs, the item is saved in history with a -r suffix
now. When opening qutebrowser that's picked up and the item is hidden
from completion.
The check `key.startswith('<') and key.endswith('>') is repeated many
times in code to check for a special key. Replace all these with a call
to the same function.
When showing the currently bound key in the misc column for command
completion, if the command has multiple bindings, show special bindings
(e.g. <ctrl-a>) after non-special bindings.
- Add a space after the comman for multiple binding suggestions.
- Use defaultdict(list) instead of defaultdict(lambda: [])
- Move the pylint comment back to the top of the class
Adds a title to the HistoryEntry class and includes it in the serialization
stuff. Not currently set from anywhere.
Not sure if anything more needs to be done to support non-ascii characters.
Everything works fine for me with unicode chars in url and title but
everything in my stack is utf-8.
The CompletionItemDelegate gets reused by Qt for various items in the
completion. Every time _get_textdoc() was called we created a new
QTextDocument, but since it has a long-living parent set (the delegate)
the old one was never actually garbage collected.
We now explicitly delete the old QTextDocument as it's not needed
anymore by either Qt or Python.
See #1476.
All commands will be offered as completions for the <command> argument
of :bind.
Due to the way completers parse the command line, the following
bind --mode caret j
will throw off completions as 'caret' is treated as a positional arg in
terms of the argument count for completions.
In the above example, completion will be triggered for 'j' and no
completions will be given for the actual command.
bind --mode=caret j will complete correctly, though completions are not
filtered by the given mode.
I attempted an approach to filter the commands based on the mode but it
ended up being messy and flaky.
This worked fine with Python 3.5 but causes a circular import which is
hard to break with Python 3.4.
The original solution was to do @pyqtSlot(object), but that doesn't work
with PyQt 5.6 anymore...
Allows to use ctrl+d to close tabs from the buffer completion widget
when they are selected. Respects current tab settings like whether you
can close the last tab in a window.
Had to change the `rebuild()` method to use `setData()` when possible
because the selection was being lost if the whole model was being rebuilt.
Current problems are:
1) When opening a new window while you already the tab completion open on
one window a category is added for the new window but new rows in
that category aren't picked up. Interesting if you open a third
window then close the second window the completion display is now
correct... I can see that the model is being updated correctly but I
am not sure why that isn't propagating to the view. Not sure whether
it is worth looking into (further) either.
2) Bit of duplication of code, it iterates over the window registry
twice. Could put everything in one loop but then that would be
dependant on the current behaviour of the `tab_closed` signal being
called with the relevant `tabbed_browser` still existing but with the
`shutting_down` flag set.
3) I'm still using just the one `rebuild()` method and removing items from
the end then calling `setData` on everything rather than having special
`on_tab/window_closed` methods (or partial functions) that delete the
actual corresponding item. Because if I did that I would also have to
special case tab moves etc.
`buffer` takes either a tab index or a string and focuses the specified
tab. The index can be of the form [0-9]+ which will switch to the
relevant tab in the current window or [0-9]+/[0-9]+ (that is
win_id/index) which will focus the specified window before switching
tabs. If a string is passed the list of open tabs across all windows is
sorted based on title and url (just like in the completion widget) and
the top result is selected.
WebHistory now has a clear() method which is also a command
(history-clear) which clears the qutebrowser history using the new
lineparser clear() method and emits a cleared signal.
The completion model urlmodel connects to the WebHistory.cleared signal
and clears its history category completion list.
I am adding this as a temporary fix before #58 or #1051 get implemented.