Merge branch 'blyxxyz-insert-text'
This commit is contained in:
commit
33cda441e6
@ -32,6 +32,8 @@ Added
|
||||
in rapid mode.
|
||||
- New `{clipboard}` and `{primary}` replacements for the commandline which
|
||||
replace the `:paste` command.
|
||||
- New `:insert-text` command to insert a given text into a field on the page,
|
||||
which replaces `:paste-primary` together with the `{primary}` replacement.
|
||||
- New `:window-only` command to close all other windows.
|
||||
- New `prev-category` and `next-category` arguments to `:completion-item-focus`
|
||||
to focus the previous/next category in the completion (bound to `<Ctrl-Tab>`
|
||||
@ -80,6 +82,8 @@ Deprecated
|
||||
|
||||
- The `:paste` command got deprecated as `:open` with `{clipboard}` and
|
||||
`{primary}` can be used instead.
|
||||
- The `:paste-primary` command got deprecated as `:insert-text {primary}` can
|
||||
be used instead.
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
|
@ -145,8 +145,8 @@ Contributors, sorted by the number of commits in descending order:
|
||||
* Jakub Klinkovský
|
||||
* Antoni Boucher
|
||||
* Lamar Pavel
|
||||
* Bruno Oliveira
|
||||
* Jan Verbeek
|
||||
* Bruno Oliveira
|
||||
* Alexander Cogneau
|
||||
* Marshall Lochbaum
|
||||
* Felix Van der Jeugt
|
||||
|
@ -4,6 +4,18 @@
|
||||
|
||||
= Commands
|
||||
|
||||
In qutebrowser, all keybindings are mapped to commands.
|
||||
|
||||
Some commands are hidden, which means they don't show up in the command
|
||||
completion when pressing `:`, as they're typically not useful to run by hand.
|
||||
|
||||
In the commandline, there are also some variables you can use:
|
||||
|
||||
- `{url}` expands to the URL of the current page
|
||||
- `{url:pretty}` expands to the URL in decoded format
|
||||
- `{clipboard}` expands to the clipboard contents
|
||||
- `{primary}` expands to the primary selection contents
|
||||
|
||||
== Normal commands
|
||||
.Quick reference
|
||||
[options="header",width="75%",cols="25%,75%"]
|
||||
@ -32,6 +44,7 @@
|
||||
|<<hint,hint>>|Start hinting.
|
||||
|<<history-clear,history-clear>>|Clear all browsing history.
|
||||
|<<home,home>>|Open main startpage in current tab.
|
||||
|<<insert-text,insert-text>>|Insert text at cursor position.
|
||||
|<<inspector,inspector>>|Toggle the web inspector.
|
||||
|<<jseval,jseval>>|Evaluate a JavaScript string.
|
||||
|<<later,later>>|Execute a command after some time.
|
||||
@ -403,6 +416,18 @@ Note this only clears the global history (e.g. `~/.local/share/qutebrowser/histo
|
||||
=== home
|
||||
Open main startpage in current tab.
|
||||
|
||||
[[insert-text]]
|
||||
=== insert-text
|
||||
Syntax: +:insert-text 'text'+
|
||||
|
||||
Insert text at cursor position.
|
||||
|
||||
==== positional arguments
|
||||
* +'text'+: The text to insert.
|
||||
|
||||
==== note
|
||||
* This command does not split arguments after the last argument and handles quotes literally.
|
||||
|
||||
[[inspector]]
|
||||
=== inspector
|
||||
Toggle the web inspector.
|
||||
@ -949,7 +974,6 @@ How many steps to zoom out.
|
||||
|<<move-to-start-of-next-block,move-to-start-of-next-block>>|Move the cursor or selection to the start of next block.
|
||||
|<<move-to-start-of-prev-block,move-to-start-of-prev-block>>|Move the cursor or selection to the start of previous block.
|
||||
|<<open-editor,open-editor>>|Open an external editor with the currently selected form field.
|
||||
|<<paste-primary,paste-primary>>|Paste the primary selection at cursor position.
|
||||
|<<prompt-accept,prompt-accept>>|Accept the current prompt.
|
||||
|<<prompt-no,prompt-no>>|Answer no to a yes/no prompt.
|
||||
|<<prompt-open-download,prompt-open-download>>|Immediately open a download.
|
||||
@ -1178,10 +1202,6 @@ Open an external editor with the currently selected form field.
|
||||
|
||||
The editor which should be launched can be configured via the `general -> editor` config option.
|
||||
|
||||
[[paste-primary]]
|
||||
=== paste-primary
|
||||
Paste the primary selection at cursor position.
|
||||
|
||||
[[prompt-accept]]
|
||||
=== prompt-accept
|
||||
Accept the current prompt.
|
||||
|
@ -1491,10 +1491,25 @@ class CommandDispatcher:
|
||||
raise cmdexc.CommandError("Element vanished while editing!")
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher',
|
||||
deprecated="Use :insert-text {primary}",
|
||||
modes=[KeyMode.insert], hide=True, scope='window',
|
||||
needs_js=True, backend=usertypes.Backend.QtWebKit)
|
||||
def paste_primary(self):
|
||||
"""Paste the primary selection at cursor position."""
|
||||
try:
|
||||
self.insert_text(utils.get_clipboard(selection=True))
|
||||
except utils.SelectionUnsupportedError:
|
||||
self.insert_text(utils.get_clipboard())
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', maxsplit=0,
|
||||
scope='window', needs_js=True,
|
||||
backend=usertypes.Backend.QtWebKit)
|
||||
def insert_text(self, text):
|
||||
"""Insert text at cursor position.
|
||||
|
||||
Args:
|
||||
text: The text to insert.
|
||||
"""
|
||||
# FIXME:qtwebengine have a proper API for this
|
||||
tab = self._current_widget()
|
||||
page = tab._widget.page() # pylint: disable=protected-access
|
||||
@ -1504,23 +1519,14 @@ class CommandDispatcher:
|
||||
raise cmdexc.CommandError("No element focused!")
|
||||
if not elem.is_editable(strict=True):
|
||||
raise cmdexc.CommandError("Focused element is not editable!")
|
||||
|
||||
try:
|
||||
try:
|
||||
sel = utils.get_clipboard(selection=True)
|
||||
except utils.SelectionUnsupportedError:
|
||||
sel = utils.get_clipboard()
|
||||
except utils.ClipboardEmptyError:
|
||||
return
|
||||
|
||||
log.misc.debug("Pasting primary selection into element {}".format(
|
||||
log.misc.debug("Inserting text into element {}".format(
|
||||
elem.debug_text()))
|
||||
elem.run_js_async("""
|
||||
var sel = '{}';
|
||||
var text = '{}';
|
||||
var event = document.createEvent('TextEvent');
|
||||
event.initTextEvent('textInput', true, true, null, sel);
|
||||
event.initTextEvent('textInput', true, true, null, text);
|
||||
this.dispatchEvent(event);
|
||||
""".format(javascript.string_escape(sel)))
|
||||
""".format(javascript.string_escape(text)))
|
||||
|
||||
def _search_cb(self, found, *, tab, old_scroll_pos, options, text, prev):
|
||||
"""Callback called from search/search_next/search_prev.
|
||||
|
@ -17,4 +17,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Utilities and classes regarding to commands."""
|
||||
"""In qutebrowser, all keybindings are mapped to commands.
|
||||
|
||||
Some commands are hidden, which means they don't show up in the command
|
||||
completion when pressing `:`, as they're typically not useful to run by hand.
|
||||
|
||||
In the commandline, there are also some variables you can use:
|
||||
|
||||
- `{url}` expands to the URL of the current page
|
||||
- `{url:pretty}` expands to the URL in decoded format
|
||||
- `{clipboard}` expands to the clipboard contents
|
||||
- `{primary}` expands to the primary selection contents
|
||||
"""
|
||||
|
@ -1598,7 +1598,7 @@ KEY_DATA = collections.OrderedDict([
|
||||
|
||||
('insert', collections.OrderedDict([
|
||||
('open-editor', ['<Ctrl-E>']),
|
||||
('paste-primary', ['<Shift-Ins>']),
|
||||
('insert-text {primary}', ['<Shift-Ins>']),
|
||||
])),
|
||||
|
||||
('hint', collections.OrderedDict([
|
||||
@ -1720,4 +1720,6 @@ CHANGED_KEY_COMMANDS = [
|
||||
|
||||
(re.compile(r'^completion-item-next'), r'completion-item-focus next'),
|
||||
(re.compile(r'^completion-item-prev'), r'completion-item-focus prev'),
|
||||
|
||||
(re.compile(r'^paste-primary$'), r'insert-text {primary}'),
|
||||
]
|
||||
|
@ -37,7 +37,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir,
|
||||
# We import qutebrowser.app so all @cmdutils-register decorators are run.
|
||||
import qutebrowser.app
|
||||
from scripts import asciidoc2html, utils
|
||||
from qutebrowser import qutebrowser
|
||||
from qutebrowser import qutebrowser, commands
|
||||
from qutebrowser.commands import cmdutils, argparser
|
||||
from qutebrowser.config import configdata
|
||||
from qutebrowser.utils import docutils, usertypes
|
||||
@ -320,7 +320,8 @@ def generate_commands(filename):
|
||||
"""Generate the complete commands section."""
|
||||
with _open_file(filename) as f:
|
||||
f.write(FILE_HEADER)
|
||||
f.write("= Commands\n")
|
||||
f.write("= Commands\n\n")
|
||||
f.write(commands.__doc__)
|
||||
normal_cmds = []
|
||||
hidden_cmds = []
|
||||
debug_cmds = []
|
||||
|
@ -215,82 +215,59 @@ Feature: Yanking and pasting.
|
||||
And I run :open -t {clipboard}
|
||||
Then no crash should happen
|
||||
|
||||
#### :paste-primary
|
||||
#### :insert-text
|
||||
|
||||
Scenario: Pasting the primary selection into an empty text field
|
||||
When selection is supported
|
||||
And I open data/paste_primary.html
|
||||
And I put "Hello world" into the primary selection
|
||||
Scenario: Inserting text into an empty text field
|
||||
When I open data/paste_primary.html
|
||||
# Click the text field
|
||||
And I run :hint all
|
||||
And I run :follow-hint a
|
||||
And I wait for "Clicked editable element!" in the log
|
||||
And I run :paste-primary
|
||||
And I run :insert-text Hello world
|
||||
# Compare
|
||||
Then the text field should contain "Hello world"
|
||||
|
||||
Scenario: Pasting the primary selection into a text field at specific position
|
||||
When selection is supported
|
||||
And I open data/paste_primary.html
|
||||
Scenario: Inserting text into a text field at specific position
|
||||
When I open data/paste_primary.html
|
||||
And I set the text field to "one two three four"
|
||||
And I put " Hello world" into the primary selection
|
||||
# Click the text field
|
||||
And I run :hint all
|
||||
And I run :follow-hint a
|
||||
And I wait for "Clicked editable element!" in the log
|
||||
# Move to the beginning and two words to the right
|
||||
# Move to the beginning and two characters to the right
|
||||
And I press the keys "<Home>"
|
||||
And I press the key "<Ctrl+Right>"
|
||||
And I press the key "<Ctrl+Right>"
|
||||
And I run :paste-primary
|
||||
And I press the key "<Right>"
|
||||
And I press the key "<Right>"
|
||||
And I run :insert-text Hello world
|
||||
# Compare
|
||||
Then the text field should contain "one two Hello world three four"
|
||||
Then the text field should contain "onHello worlde two three four"
|
||||
|
||||
Scenario: Pasting the primary selection into a text field with undo
|
||||
When selection is supported
|
||||
And I open data/paste_primary.html
|
||||
Scenario: Inserting text into a text field with undo
|
||||
When I open data/paste_primary.html
|
||||
# Click the text field
|
||||
And I run :hint all
|
||||
And I run :follow-hint a
|
||||
And I wait for "Clicked editable element!" in the log
|
||||
# Paste and undo
|
||||
And I put "This text should be undone" into the primary selection
|
||||
And I run :paste-primary
|
||||
And I run :insert-text This text should be undone
|
||||
And I press the key "<Ctrl+z>"
|
||||
# Paste final text
|
||||
And I put "This text should stay" into the primary selection
|
||||
And I run :paste-primary
|
||||
And I run :insert-text This text should stay
|
||||
# Compare
|
||||
Then the text field should contain "This text should stay"
|
||||
|
||||
Scenario: Pasting the primary selection without a focused field
|
||||
When selection is supported
|
||||
And I open data/paste_primary.html
|
||||
And I put "test" into the primary selection
|
||||
Scenario: Inserting text without a focused field
|
||||
When I open data/paste_primary.html
|
||||
And I run :enter-mode insert
|
||||
And I run :paste-primary
|
||||
And I run :insert-text test
|
||||
Then the error "No element focused!" should be shown
|
||||
|
||||
Scenario: Pasting the primary selection with a read-only field
|
||||
When selection is supported
|
||||
And I open data/paste_primary.html
|
||||
Scenario: Inserting text with a read-only field
|
||||
When I open data/paste_primary.html
|
||||
# Click the text field
|
||||
And I run :hint all
|
||||
And I run :follow-hint s
|
||||
And I wait for "Clicked non-editable element!" in the log
|
||||
And I put "test" into the primary selection
|
||||
And I run :enter-mode insert
|
||||
And I run :paste-primary
|
||||
And I run :insert-text test
|
||||
Then the error "Focused element is not editable!" should be shown
|
||||
|
||||
Scenario: :paste-primary without primary selection supported
|
||||
When selection is not supported
|
||||
And I open data/paste_primary.html
|
||||
And I put "Hello world" into the clipboard
|
||||
# Click the text field
|
||||
And I run :hint all
|
||||
And I run :follow-hint a
|
||||
And I wait for "Clicked editable element!" in the log
|
||||
And I run :paste-primary
|
||||
# Compare
|
||||
Then the text field should contain "Hello world"
|
||||
|
@ -46,7 +46,7 @@ def test_insert_mode(file_name, source, input_text, auto_insert, quteproc):
|
||||
quteproc.press_keys(input_text)
|
||||
elif source == 'clipboard':
|
||||
quteproc.send_cmd(':debug-set-fake-clipboard "{}"'.format(input_text))
|
||||
quteproc.send_cmd(':paste-primary')
|
||||
quteproc.send_cmd(':insert-text {clipboard}')
|
||||
|
||||
quteproc.send_cmd(':hint all')
|
||||
quteproc.send_cmd(':follow-hint a')
|
||||
|
Loading…
Reference in New Issue
Block a user