Merge branch 'blyxxyz-insert-text'

This commit is contained in:
Florian Bruhin 2016-08-16 13:33:20 +02:00
commit 33cda441e6
9 changed files with 89 additions and 68 deletions

View File

@ -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
~~~~~~~

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
"""

View File

@ -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}'),
]

View File

@ -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 = []

View File

@ -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"

View File

@ -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')