Merge branch 'insert-text' of https://github.com/blyxxyz/qutebrowser into blyxxyz-insert-text
This commit is contained in:
commit
8d6b905f95
@ -32,6 +32,7 @@
|
|||||||
|<<hint,hint>>|Start hinting.
|
|<<hint,hint>>|Start hinting.
|
||||||
|<<history-clear,history-clear>>|Clear all browsing history.
|
|<<history-clear,history-clear>>|Clear all browsing history.
|
||||||
|<<home,home>>|Open main startpage in current tab.
|
|<<home,home>>|Open main startpage in current tab.
|
||||||
|
|<<insert-text,insert-text>>|Insert text at cursor position.
|
||||||
|<<inspector,inspector>>|Toggle the web inspector.
|
|<<inspector,inspector>>|Toggle the web inspector.
|
||||||
|<<jseval,jseval>>|Evaluate a JavaScript string.
|
|<<jseval,jseval>>|Evaluate a JavaScript string.
|
||||||
|<<later,later>>|Execute a command after some time.
|
|<<later,later>>|Execute a command after some time.
|
||||||
@ -403,6 +404,18 @@ Note this only clears the global history (e.g. `~/.local/share/qutebrowser/histo
|
|||||||
=== home
|
=== home
|
||||||
Open main startpage in current tab.
|
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]]
|
||||||
=== inspector
|
=== inspector
|
||||||
Toggle the web inspector.
|
Toggle the web inspector.
|
||||||
@ -949,7 +962,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-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.
|
|<<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.
|
|<<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-accept,prompt-accept>>|Accept the current prompt.
|
||||||
|<<prompt-no,prompt-no>>|Answer no to a yes/no prompt.
|
|<<prompt-no,prompt-no>>|Answer no to a yes/no prompt.
|
||||||
|<<prompt-open-download,prompt-open-download>>|Immediately open a download.
|
|<<prompt-open-download,prompt-open-download>>|Immediately open a download.
|
||||||
@ -1178,10 +1190,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.
|
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]]
|
||||||
=== prompt-accept
|
=== prompt-accept
|
||||||
Accept the current prompt.
|
Accept the current prompt.
|
||||||
|
@ -1491,10 +1491,25 @@ class CommandDispatcher:
|
|||||||
raise cmdexc.CommandError("Element vanished while editing!")
|
raise cmdexc.CommandError("Element vanished while editing!")
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher',
|
@cmdutils.register(instance='command-dispatcher',
|
||||||
|
deprecated="Use :insert-text {primary}",
|
||||||
modes=[KeyMode.insert], hide=True, scope='window',
|
modes=[KeyMode.insert], hide=True, scope='window',
|
||||||
needs_js=True, backend=usertypes.Backend.QtWebKit)
|
needs_js=True, backend=usertypes.Backend.QtWebKit)
|
||||||
def paste_primary(self):
|
def paste_primary(self):
|
||||||
"""Paste the primary selection at cursor position."""
|
"""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
|
# FIXME:qtwebengine have a proper API for this
|
||||||
tab = self._current_widget()
|
tab = self._current_widget()
|
||||||
page = tab._widget.page() # pylint: disable=protected-access
|
page = tab._widget.page() # pylint: disable=protected-access
|
||||||
@ -1504,23 +1519,14 @@ class CommandDispatcher:
|
|||||||
raise cmdexc.CommandError("No element focused!")
|
raise cmdexc.CommandError("No element focused!")
|
||||||
if not elem.is_editable(strict=True):
|
if not elem.is_editable(strict=True):
|
||||||
raise cmdexc.CommandError("Focused element is not editable!")
|
raise cmdexc.CommandError("Focused element is not editable!")
|
||||||
|
log.misc.debug("Inserting text into element {}".format(
|
||||||
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(
|
|
||||||
elem.debug_text()))
|
elem.debug_text()))
|
||||||
elem.run_js_async("""
|
elem.run_js_async("""
|
||||||
var sel = '{}';
|
var text = '{}';
|
||||||
var event = document.createEvent('TextEvent');
|
var event = document.createEvent('TextEvent');
|
||||||
event.initTextEvent('textInput', true, true, null, sel);
|
event.initTextEvent('textInput', true, true, null, text);
|
||||||
this.dispatchEvent(event);
|
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):
|
def _search_cb(self, found, *, tab, old_scroll_pos, options, text, prev):
|
||||||
"""Callback called from search/search_next/search_prev.
|
"""Callback called from search/search_next/search_prev.
|
||||||
|
@ -1598,7 +1598,7 @@ KEY_DATA = collections.OrderedDict([
|
|||||||
|
|
||||||
('insert', collections.OrderedDict([
|
('insert', collections.OrderedDict([
|
||||||
('open-editor', ['<Ctrl-E>']),
|
('open-editor', ['<Ctrl-E>']),
|
||||||
('paste-primary', ['<Shift-Ins>']),
|
('insert-text {primary}', ['<Shift-Ins>']),
|
||||||
])),
|
])),
|
||||||
|
|
||||||
('hint', collections.OrderedDict([
|
('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-next'), r'completion-item-focus next'),
|
||||||
(re.compile(r'^completion-item-prev'), r'completion-item-focus prev'),
|
(re.compile(r'^completion-item-prev'), r'completion-item-focus prev'),
|
||||||
|
|
||||||
|
(re.compile(r'^paste-primary$'), r'insert-text {primary}'),
|
||||||
]
|
]
|
||||||
|
@ -215,82 +215,59 @@ Feature: Yanking and pasting.
|
|||||||
And I run :open -t {clipboard}
|
And I run :open -t {clipboard}
|
||||||
Then no crash should happen
|
Then no crash should happen
|
||||||
|
|
||||||
#### :paste-primary
|
#### :insert-text
|
||||||
|
|
||||||
Scenario: Pasting the primary selection into an empty text field
|
Scenario: Inserting text into an empty text field
|
||||||
When selection is supported
|
When I open data/paste_primary.html
|
||||||
And I open data/paste_primary.html
|
|
||||||
And I put "Hello world" into the primary selection
|
|
||||||
# Click the text field
|
# Click the text field
|
||||||
And I run :hint all
|
And I run :hint all
|
||||||
And I run :follow-hint a
|
And I run :follow-hint a
|
||||||
And I wait for "Clicked editable element!" in the log
|
And I wait for "Clicked editable element!" in the log
|
||||||
And I run :paste-primary
|
And I run :insert-text Hello world
|
||||||
# Compare
|
# Compare
|
||||||
Then the text field should contain "Hello world"
|
Then the text field should contain "Hello world"
|
||||||
|
|
||||||
Scenario: Pasting the primary selection into a text field at specific position
|
Scenario: Inserting text into a text field at specific position
|
||||||
When selection is supported
|
When I open data/paste_primary.html
|
||||||
And I open data/paste_primary.html
|
|
||||||
And I set the text field to "one two three four"
|
And I set the text field to "one two three four"
|
||||||
And I put " Hello world" into the primary selection
|
|
||||||
# Click the text field
|
# Click the text field
|
||||||
And I run :hint all
|
And I run :hint all
|
||||||
And I run :follow-hint a
|
And I run :follow-hint a
|
||||||
And I wait for "Clicked editable element!" in the log
|
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 keys "<Home>"
|
||||||
And I press the key "<Ctrl+Right>"
|
And I press the key "<Right>"
|
||||||
And I press the key "<Ctrl+Right>"
|
And I press the key "<Right>"
|
||||||
And I run :paste-primary
|
And I run :insert-text Hello world
|
||||||
# Compare
|
# 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
|
Scenario: Inserting text into a text field with undo
|
||||||
When selection is supported
|
When I open data/paste_primary.html
|
||||||
And I open data/paste_primary.html
|
|
||||||
# Click the text field
|
# Click the text field
|
||||||
And I run :hint all
|
And I run :hint all
|
||||||
And I run :follow-hint a
|
And I run :follow-hint a
|
||||||
And I wait for "Clicked editable element!" in the log
|
And I wait for "Clicked editable element!" in the log
|
||||||
# Paste and undo
|
# Paste and undo
|
||||||
And I put "This text should be undone" into the primary selection
|
And I run :insert-text This text should be undone
|
||||||
And I run :paste-primary
|
|
||||||
And I press the key "<Ctrl+z>"
|
And I press the key "<Ctrl+z>"
|
||||||
# Paste final text
|
# Paste final text
|
||||||
And I put "This text should stay" into the primary selection
|
And I run :insert-text This text should stay
|
||||||
And I run :paste-primary
|
|
||||||
# Compare
|
# Compare
|
||||||
Then the text field should contain "This text should stay"
|
Then the text field should contain "This text should stay"
|
||||||
|
|
||||||
Scenario: Pasting the primary selection without a focused field
|
Scenario: Inserting text without a focused field
|
||||||
When selection is supported
|
When I open data/paste_primary.html
|
||||||
And I open data/paste_primary.html
|
|
||||||
And I put "test" into the primary selection
|
|
||||||
And I run :enter-mode insert
|
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
|
Then the error "No element focused!" should be shown
|
||||||
|
|
||||||
Scenario: Pasting the primary selection with a read-only field
|
Scenario: Inserting text with a read-only field
|
||||||
When selection is supported
|
When I open data/paste_primary.html
|
||||||
And I open data/paste_primary.html
|
|
||||||
# Click the text field
|
# Click the text field
|
||||||
And I run :hint all
|
And I run :hint all
|
||||||
And I run :follow-hint s
|
And I run :follow-hint s
|
||||||
And I wait for "Clicked non-editable element!" in the log
|
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 :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
|
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)
|
quteproc.press_keys(input_text)
|
||||||
elif source == 'clipboard':
|
elif source == 'clipboard':
|
||||||
quteproc.send_cmd(':debug-set-fake-clipboard "{}"'.format(input_text))
|
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(':hint all')
|
||||||
quteproc.send_cmd(':follow-hint a')
|
quteproc.send_cmd(':follow-hint a')
|
||||||
|
Loading…
Reference in New Issue
Block a user