We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Doing :-w open crashes
When typing `:-w open ` (with trailing space):

```
17:56:49 DEBUG    completion completer:_partition:141 partitioning ['-w', ' open', ' '] around position 8
17:56:49 DEBUG    completion completer:_partition:153 partitioned: ['-w', 'open'] '' []
17:56:49 DEBUG    completion completer:_update_completion:236 Updating completion: ['-w', 'open']  []
17:56:49 DEBUG    completion completer:_get_new_completion:89 Before removing flags: ['-w', 'open']
17:56:49 DEBUG    completion completer:_get_new_completion:91 After removing flags: ['open']
17:56:49 DEBUG    completion debug:__exit__:264 Starting url completion took 6.5e-05 seconds.
17:56:49 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py", line 255, in _update_completion
    model = func(*args, info=info)
TypeError: url() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given
```

cc @rcorre 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qutebrowser/completion/completer.py`
Content:
```
1 # vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
2 
3 # Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
4 #
5 # This file is part of qutebrowser.
6 #
7 # qutebrowser is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # qutebrowser is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.
19 
20 """Completer attached to a CompletionView."""
21 
22 import attr
23 from PyQt5.QtCore import pyqtSlot, QObject, QTimer
24 
25 from qutebrowser.config import config
26 from qutebrowser.commands import cmdutils, runners
27 from qutebrowser.utils import log, utils, debug
28 from qutebrowser.completion.models import miscmodels
29 
30 
31 @attr.s
32 class CompletionInfo:
33 
34     """Context passed into all completion functions."""
35 
36     config = attr.ib()
37     keyconf = attr.ib()
38     win_id = attr.ib()
39 
40 
41 class Completer(QObject):
42 
43     """Completer which manages completions in a CompletionView.
44 
45     Attributes:
46         _cmd: The statusbar Command object this completer belongs to.
47         _win_id: The id of the window that owns this object.
48         _timer: The timer used to trigger the completion update.
49         _last_cursor_pos: The old cursor position so we avoid double completion
50                           updates.
51         _last_text: The old command text so we avoid double completion updates.
52         _last_completion_func: The completion function used for the last text.
53     """
54 
55     def __init__(self, *, cmd, win_id, parent=None):
56         super().__init__(parent)
57         self._cmd = cmd
58         self._win_id = win_id
59         self._timer = QTimer()
60         self._timer.setSingleShot(True)
61         self._timer.setInterval(0)
62         self._timer.timeout.connect(self._update_completion)
63         self._last_cursor_pos = None
64         self._last_text = None
65         self._last_completion_func = None
66         self._cmd.update_completion.connect(self.schedule_completion_update)
67 
68     def __repr__(self):
69         return utils.get_repr(self)
70 
71     def _model(self):
72         """Convenience method to get the current completion model."""
73         completion = self.parent()
74         return completion.model()
75 
76     def _get_new_completion(self, before_cursor, under_cursor):
77         """Get the completion function based on the current command text.
78 
79         Args:
80             before_cursor: The command chunks before the cursor.
81             under_cursor: The command chunk under the cursor.
82 
83         Return:
84             A completion model.
85         """
86         if '--' in before_cursor or under_cursor.startswith('-'):
87             # cursor on a flag or after an explicit split (--)
88             return None
89         log.completion.debug("Before removing flags: {}".format(before_cursor))
90         before_cursor = [x for x in before_cursor if not x.startswith('-')]
91         log.completion.debug("After removing flags: {}".format(before_cursor))
92         if not before_cursor:
93             # '|' or 'set|'
94             log.completion.debug('Starting command completion')
95             return miscmodels.command
96         try:
97             cmd = cmdutils.cmd_dict[before_cursor[0]]
98         except KeyError:
99             log.completion.debug("No completion for unknown command: {}"
100                                  .format(before_cursor[0]))
101             return None
102         argpos = len(before_cursor) - 1
103         try:
104             func = cmd.get_pos_arg_info(argpos).completion
105         except IndexError:
106             log.completion.debug("No completion in position {}".format(argpos))
107             return None
108         return func
109 
110     def _quote(self, s):
111         """Quote s if it needs quoting for the commandline.
112 
113         Note we don't use shlex.quote because that quotes a lot of shell
114         metachars we don't need to have quoted.
115         """
116         if not s:
117             return "''"
118         elif any(c in s for c in ' "\'\t\n\\'):
119             # use single quotes, and put single quotes into double quotes
120             # the string $'b is then quoted as '$'"'"'b'
121             return "'" + s.replace("'", "'\"'\"'") + "'"
122         else:
123             return s
124 
125     def _partition(self):
126         """Divide the commandline text into chunks around the cursor position.
127 
128         Return:
129             ([parts_before_cursor], 'part_under_cursor', [parts_after_cursor])
130         """
131         text = self._cmd.text()[len(self._cmd.prefix()):]
132         if not text or not text.strip():
133             # Only ":", empty part under the cursor with nothing before/after
134             return [], '', []
135         parser = runners.CommandParser()
136         result = parser.parse(text, fallback=True, keep=True)
137         parts = [x for x in result.cmdline if x]
138         pos = self._cmd.cursorPosition() - len(self._cmd.prefix())
139         pos = min(pos, len(text))  # Qt treats 2-byte UTF-16 chars as 2 chars
140         log.completion.debug('partitioning {} around position {}'.format(parts,
141                                                                          pos))
142         for i, part in enumerate(parts):
143             pos -= len(part)
144             if pos <= 0:
145                 if part[pos-1:pos+1].isspace():
146                     # cursor is in a space between two existing words
147                     parts.insert(i, '')
148                 prefix = [x.strip() for x in parts[:i]]
149                 center = parts[i].strip()
150                 # strip trailing whitepsace included as a separate token
151                 postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]
152                 log.completion.debug(
153                     "partitioned: {} '{}' {}".format(prefix, center, postfix))
154                 return prefix, center, postfix
155 
156         raise utils.Unreachable("Not all parts consumed: {}".format(parts))
157 
158     @pyqtSlot(str)
159     def on_selection_changed(self, text):
160         """Change the completed part if a new item was selected.
161 
162         Called from the views selectionChanged method.
163 
164         Args:
165             text: Newly selected text.
166         """
167         if text is None:
168             return
169         before, center, after = self._partition()
170         log.completion.debug("Changing {} to '{}'".format(center, text))
171         try:
172             maxsplit = cmdutils.cmd_dict[before[0]].maxsplit
173         except (KeyError, IndexError):
174             maxsplit = None
175         if maxsplit is None:
176             text = self._quote(text)
177         model = self._model()
178         if model.count() == 1 and config.val.completion.quick:
179             # If we only have one item, we want to apply it immediately and go
180             # on to the next part, unless we are quick-completing the part
181             # after maxsplit, so that we don't keep offering completions
182             # (see issue #1519)
183             if maxsplit is not None and maxsplit < len(before):
184                 self._change_completed_part(text, before, after)
185             else:
186                 self._change_completed_part(text, before, after,
187                                             immediate=True)
188         else:
189             self._change_completed_part(text, before, after)
190 
191     @pyqtSlot()
192     def schedule_completion_update(self):
193         """Schedule updating/enabling completion.
194 
195         For performance reasons we don't want to block here, instead we do this
196         in the background.
197 
198         We delay the update only if we've already input some text and ignore
199         updates if the text is shorter than completion.min_chars (unless we're
200         hitting backspace in which case updates won't be ignored).
201         """
202         _cmd, _sep, rest = self._cmd.text().partition(' ')
203         input_length = len(rest)
204         if (0 < input_length < config.val.completion.min_chars and
205                 self._cmd.cursorPosition() > self._last_cursor_pos):
206             log.completion.debug("Ignoring update because the length of "
207                                  "the text is less than completion.min_chars.")
208         elif (self._cmd.cursorPosition() == self._last_cursor_pos and
209               self._cmd.text() == self._last_text):
210             log.completion.debug("Ignoring update because there were no "
211                                  "changes.")
212         else:
213             log.completion.debug("Scheduling completion update.")
214             start_delay = config.val.completion.delay if self._last_text else 0
215             self._timer.start(start_delay)
216         self._last_cursor_pos = self._cmd.cursorPosition()
217         self._last_text = self._cmd.text()
218 
219     @pyqtSlot()
220     def _update_completion(self):
221         """Check if completions are available and activate them."""
222         completion = self.parent()
223 
224         if self._cmd.prefix() != ':':
225             # This is a search or gibberish, so we don't need to complete
226             # anything (yet)
227             # FIXME complete searches
228             # https://github.com/qutebrowser/qutebrowser/issues/32
229             completion.set_model(None)
230             self._last_completion_func = None
231             return
232 
233         before_cursor, pattern, after_cursor = self._partition()
234 
235         log.completion.debug("Updating completion: {} {} {}".format(
236             before_cursor, pattern, after_cursor))
237 
238         pattern = pattern.strip("'\"")
239         func = self._get_new_completion(before_cursor, pattern)
240 
241         if func is None:
242             log.completion.debug('Clearing completion')
243             completion.set_model(None)
244             self._last_completion_func = None
245             return
246 
247         if func != self._last_completion_func:
248             self._last_completion_func = func
249             args = (x for x in before_cursor[1:] if not x.startswith('-'))
250             with debug.log_time(log.completion, 'Starting {} completion'
251                                 .format(func.__name__)):
252                 info = CompletionInfo(config=config.instance,
253                                       keyconf=config.key_instance,
254                                       win_id=self._win_id)
255                 model = func(*args, info=info)
256             with debug.log_time(log.completion, 'Set completion model'):
257                 completion.set_model(model)
258 
259         completion.set_pattern(pattern)
260 
261     def _change_completed_part(self, newtext, before, after, immediate=False):
262         """Change the part we're currently completing in the commandline.
263 
264         Args:
265             text: The text to set (string) for the token under the cursor.
266             before: Commandline tokens before the token under the cursor.
267             after: Commandline tokens after the token under the cursor.
268             immediate: True if the text should be completed immediately
269                        including a trailing space and we shouldn't continue
270                        completing the current item.
271         """
272         text = self._cmd.prefix() + ' '.join(before + [newtext])
273         pos = len(text) + (1 if immediate else 0)
274         if after:
275             text += ' ' + ' '.join(after)
276         elif immediate:
277             # pad with a space if quick-completing the last entry
278             text += ' '
279         log.completion.debug("setting text = '{}', pos = {}".format(text, pos))
280 
281         # generally, we don't want to let self._cmd emit cursorPositionChanged,
282         # because that'll schedule a completion update. That happens when
283         # tabbing through the completions, and we want to change the command
284         # text but we also want to keep the original completion list for the
285         # command the user manually entered. The exception is when we're
286         # immediately completing, in which case we *do* want to update the
287         # completion view so that we can start completing the next part
288         if not immediate:
289             self._cmd.blockSignals(True)
290 
291         self._cmd.setText(text)
292         self._cmd.setCursorPosition(pos)
293         self._cmd.setFocus()
294 
295         self._cmd.blockSignals(False)
296         self._cmd.show_cmd.emit()
297
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -87,8 +87,6 @@
             # cursor on a flag or after an explicit split (--)
             return None
         log.completion.debug("Before removing flags: {}".format(before_cursor))
-        before_cursor = [x for x in before_cursor if not x.startswith('-')]
-        log.completion.debug("After removing flags: {}".format(before_cursor))
         if not before_cursor:
             # '|' or 'set|'
             log.completion.debug('Starting command completion')
@@ -99,6 +97,9 @@
             log.completion.debug("No completion for unknown command: {}"
                                  .format(before_cursor[0]))
             return None
+
+        before_cursor = [x for x in before_cursor if not x.startswith('-')]
+        log.completion.debug("After removing flags: {}".format(before_cursor))
         argpos = len(before_cursor) - 1
         try:
             func = cmd.get_pos_arg_info(argpos).completion

{"golden_diff": "diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py\n--- a/qutebrowser/completion/completer.py\n+++ b/qutebrowser/completion/completer.py\n@@ -87,8 +87,6 @@\n             # cursor on a flag or after an explicit split (--)\n             return None\n         log.completion.debug(\"Before removing flags: {}\".format(before_cursor))\n-        before_cursor = [x for x in before_cursor if not x.startswith('-')]\n-        log.completion.debug(\"After removing flags: {}\".format(before_cursor))\n         if not before_cursor:\n             # '|' or 'set|'\n             log.completion.debug('Starting command completion')\n@@ -99,6 +97,9 @@\n             log.completion.debug(\"No completion for unknown command: {}\"\n                                  .format(before_cursor[0]))\n             return None\n+\n+        before_cursor = [x for x in before_cursor if not x.startswith('-')]\n+        log.completion.debug(\"After removing flags: {}\".format(before_cursor))\n         argpos = len(before_cursor) - 1\n         try:\n             func = cmd.get_pos_arg_info(argpos).completion\n", "issue": "Doing :-w open crashes\nWhen typing `:-w open ` (with trailing space):\r\n\r\n```\r\n17:56:49 DEBUG    completion completer:_partition:141 partitioning ['-w', ' open', ' '] around position 8\r\n17:56:49 DEBUG    completion completer:_partition:153 partitioned: ['-w', 'open'] '' []\r\n17:56:49 DEBUG    completion completer:_update_completion:236 Updating completion: ['-w', 'open']  []\r\n17:56:49 DEBUG    completion completer:_get_new_completion:89 Before removing flags: ['-w', 'open']\r\n17:56:49 DEBUG    completion completer:_get_new_completion:91 After removing flags: ['open']\r\n17:56:49 DEBUG    completion debug:__exit__:264 Starting url completion took 6.5e-05 seconds.\r\n17:56:49 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception\r\nTraceback (most recent call last):\r\n  File \"/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py\", line 255, in _update_completion\r\n    model = func(*args, info=info)\r\nTypeError: url() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given\r\n```\r\n\r\ncc @rcorre \n", "before_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>\n#\n# This file is part of qutebrowser.\n#\n# qutebrowser is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# qutebrowser is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.\n\n\"\"\"Completer attached to a CompletionView.\"\"\"\n\nimport attr\nfrom PyQt5.QtCore import pyqtSlot, QObject, QTimer\n\nfrom qutebrowser.config import config\nfrom qutebrowser.commands import cmdutils, runners\nfrom qutebrowser.utils import log, utils, debug\nfrom qutebrowser.completion.models import miscmodels\n\n\n@attr.s\nclass CompletionInfo:\n\n    \"\"\"Context passed into all completion functions.\"\"\"\n\n    config = attr.ib()\n    keyconf = attr.ib()\n    win_id = attr.ib()\n\n\nclass Completer(QObject):\n\n    \"\"\"Completer which manages completions in a CompletionView.\n\n    Attributes:\n        _cmd: The statusbar Command object this completer belongs to.\n        _win_id: The id of the window that owns this object.\n        _timer: The timer used to trigger the completion update.\n        _last_cursor_pos: The old cursor position so we avoid double completion\n                          updates.\n        _last_text: The old command text so we avoid double completion updates.\n        _last_completion_func: The completion function used for the last text.\n    \"\"\"\n\n    def __init__(self, *, cmd, win_id, parent=None):\n        super().__init__(parent)\n        self._cmd = cmd\n        self._win_id = win_id\n        self._timer = QTimer()\n        self._timer.setSingleShot(True)\n        self._timer.setInterval(0)\n        self._timer.timeout.connect(self._update_completion)\n        self._last_cursor_pos = None\n        self._last_text = None\n        self._last_completion_func = None\n        self._cmd.update_completion.connect(self.schedule_completion_update)\n\n    def __repr__(self):\n        return utils.get_repr(self)\n\n    def _model(self):\n        \"\"\"Convenience method to get the current completion model.\"\"\"\n        completion = self.parent()\n        return completion.model()\n\n    def _get_new_completion(self, before_cursor, under_cursor):\n        \"\"\"Get the completion function based on the current command text.\n\n        Args:\n            before_cursor: The command chunks before the cursor.\n            under_cursor: The command chunk under the cursor.\n\n        Return:\n            A completion model.\n        \"\"\"\n        if '--' in before_cursor or under_cursor.startswith('-'):\n            # cursor on a flag or after an explicit split (--)\n            return None\n        log.completion.debug(\"Before removing flags: {}\".format(before_cursor))\n        before_cursor = [x for x in before_cursor if not x.startswith('-')]\n        log.completion.debug(\"After removing flags: {}\".format(before_cursor))\n        if not before_cursor:\n            # '|' or 'set|'\n            log.completion.debug('Starting command completion')\n            return miscmodels.command\n        try:\n            cmd = cmdutils.cmd_dict[before_cursor[0]]\n        except KeyError:\n            log.completion.debug(\"No completion for unknown command: {}\"\n                                 .format(before_cursor[0]))\n            return None\n        argpos = len(before_cursor) - 1\n        try:\n            func = cmd.get_pos_arg_info(argpos).completion\n        except IndexError:\n            log.completion.debug(\"No completion in position {}\".format(argpos))\n            return None\n        return func\n\n    def _quote(self, s):\n        \"\"\"Quote s if it needs quoting for the commandline.\n\n        Note we don't use shlex.quote because that quotes a lot of shell\n        metachars we don't need to have quoted.\n        \"\"\"\n        if not s:\n            return \"''\"\n        elif any(c in s for c in ' \"\\'\\t\\n\\\\'):\n            # use single quotes, and put single quotes into double quotes\n            # the string $'b is then quoted as '$'\"'\"'b'\n            return \"'\" + s.replace(\"'\", \"'\\\"'\\\"'\") + \"'\"\n        else:\n            return s\n\n    def _partition(self):\n        \"\"\"Divide the commandline text into chunks around the cursor position.\n\n        Return:\n            ([parts_before_cursor], 'part_under_cursor', [parts_after_cursor])\n        \"\"\"\n        text = self._cmd.text()[len(self._cmd.prefix()):]\n        if not text or not text.strip():\n            # Only \":\", empty part under the cursor with nothing before/after\n            return [], '', []\n        parser = runners.CommandParser()\n        result = parser.parse(text, fallback=True, keep=True)\n        parts = [x for x in result.cmdline if x]\n        pos = self._cmd.cursorPosition() - len(self._cmd.prefix())\n        pos = min(pos, len(text))  # Qt treats 2-byte UTF-16 chars as 2 chars\n        log.completion.debug('partitioning {} around position {}'.format(parts,\n                                                                         pos))\n        for i, part in enumerate(parts):\n            pos -= len(part)\n            if pos <= 0:\n                if part[pos-1:pos+1].isspace():\n                    # cursor is in a space between two existing words\n                    parts.insert(i, '')\n                prefix = [x.strip() for x in parts[:i]]\n                center = parts[i].strip()\n                # strip trailing whitepsace included as a separate token\n                postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]\n                log.completion.debug(\n                    \"partitioned: {} '{}' {}\".format(prefix, center, postfix))\n                return prefix, center, postfix\n\n        raise utils.Unreachable(\"Not all parts consumed: {}\".format(parts))\n\n    @pyqtSlot(str)\n    def on_selection_changed(self, text):\n        \"\"\"Change the completed part if a new item was selected.\n\n        Called from the views selectionChanged method.\n\n        Args:\n            text: Newly selected text.\n        \"\"\"\n        if text is None:\n            return\n        before, center, after = self._partition()\n        log.completion.debug(\"Changing {} to '{}'\".format(center, text))\n        try:\n            maxsplit = cmdutils.cmd_dict[before[0]].maxsplit\n        except (KeyError, IndexError):\n            maxsplit = None\n        if maxsplit is None:\n            text = self._quote(text)\n        model = self._model()\n        if model.count() == 1 and config.val.completion.quick:\n            # If we only have one item, we want to apply it immediately and go\n            # on to the next part, unless we are quick-completing the part\n            # after maxsplit, so that we don't keep offering completions\n            # (see issue #1519)\n            if maxsplit is not None and maxsplit < len(before):\n                self._change_completed_part(text, before, after)\n            else:\n                self._change_completed_part(text, before, after,\n                                            immediate=True)\n        else:\n            self._change_completed_part(text, before, after)\n\n    @pyqtSlot()\n    def schedule_completion_update(self):\n        \"\"\"Schedule updating/enabling completion.\n\n        For performance reasons we don't want to block here, instead we do this\n        in the background.\n\n        We delay the update only if we've already input some text and ignore\n        updates if the text is shorter than completion.min_chars (unless we're\n        hitting backspace in which case updates won't be ignored).\n        \"\"\"\n        _cmd, _sep, rest = self._cmd.text().partition(' ')\n        input_length = len(rest)\n        if (0 < input_length < config.val.completion.min_chars and\n                self._cmd.cursorPosition() > self._last_cursor_pos):\n            log.completion.debug(\"Ignoring update because the length of \"\n                                 \"the text is less than completion.min_chars.\")\n        elif (self._cmd.cursorPosition() == self._last_cursor_pos and\n              self._cmd.text() == self._last_text):\n            log.completion.debug(\"Ignoring update because there were no \"\n                                 \"changes.\")\n        else:\n            log.completion.debug(\"Scheduling completion update.\")\n            start_delay = config.val.completion.delay if self._last_text else 0\n            self._timer.start(start_delay)\n        self._last_cursor_pos = self._cmd.cursorPosition()\n        self._last_text = self._cmd.text()\n\n    @pyqtSlot()\n    def _update_completion(self):\n        \"\"\"Check if completions are available and activate them.\"\"\"\n        completion = self.parent()\n\n        if self._cmd.prefix() != ':':\n            # This is a search or gibberish, so we don't need to complete\n            # anything (yet)\n            # FIXME complete searches\n            # https://github.com/qutebrowser/qutebrowser/issues/32\n            completion.set_model(None)\n            self._last_completion_func = None\n            return\n\n        before_cursor, pattern, after_cursor = self._partition()\n\n        log.completion.debug(\"Updating completion: {} {} {}\".format(\n            before_cursor, pattern, after_cursor))\n\n        pattern = pattern.strip(\"'\\\"\")\n        func = self._get_new_completion(before_cursor, pattern)\n\n        if func is None:\n            log.completion.debug('Clearing completion')\n            completion.set_model(None)\n            self._last_completion_func = None\n            return\n\n        if func != self._last_completion_func:\n            self._last_completion_func = func\n            args = (x for x in before_cursor[1:] if not x.startswith('-'))\n            with debug.log_time(log.completion, 'Starting {} completion'\n                                .format(func.__name__)):\n                info = CompletionInfo(config=config.instance,\n                                      keyconf=config.key_instance,\n                                      win_id=self._win_id)\n                model = func(*args, info=info)\n            with debug.log_time(log.completion, 'Set completion model'):\n                completion.set_model(model)\n\n        completion.set_pattern(pattern)\n\n    def _change_completed_part(self, newtext, before, after, immediate=False):\n        \"\"\"Change the part we're currently completing in the commandline.\n\n        Args:\n            text: The text to set (string) for the token under the cursor.\n            before: Commandline tokens before the token under the cursor.\n            after: Commandline tokens after the token under the cursor.\n            immediate: True if the text should be completed immediately\n                       including a trailing space and we shouldn't continue\n                       completing the current item.\n        \"\"\"\n        text = self._cmd.prefix() + ' '.join(before + [newtext])\n        pos = len(text) + (1 if immediate else 0)\n        if after:\n            text += ' ' + ' '.join(after)\n        elif immediate:\n            # pad with a space if quick-completing the last entry\n            text += ' '\n        log.completion.debug(\"setting text = '{}', pos = {}\".format(text, pos))\n\n        # generally, we don't want to let self._cmd emit cursorPositionChanged,\n        # because that'll schedule a completion update. That happens when\n        # tabbing through the completions, and we want to change the command\n        # text but we also want to keep the original completion list for the\n        # command the user manually entered. The exception is when we're\n        # immediately completing, in which case we *do* want to update the\n        # completion view so that we can start completing the next part\n        if not immediate:\n            self._cmd.blockSignals(True)\n\n        self._cmd.setText(text)\n        self._cmd.setCursorPosition(pos)\n        self._cmd.setFocus()\n\n        self._cmd.blockSignals(False)\n        self._cmd.show_cmd.emit()\n", "path": "qutebrowser/completion/completer.py"}], "after_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>\n#\n# This file is part of qutebrowser.\n#\n# qutebrowser is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# qutebrowser is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.\n\n\"\"\"Completer attached to a CompletionView.\"\"\"\n\nimport attr\nfrom PyQt5.QtCore import pyqtSlot, QObject, QTimer\n\nfrom qutebrowser.config import config\nfrom qutebrowser.commands import cmdutils, runners\nfrom qutebrowser.utils import log, utils, debug\nfrom qutebrowser.completion.models import miscmodels\n\n\n@attr.s\nclass CompletionInfo:\n\n    \"\"\"Context passed into all completion functions.\"\"\"\n\n    config = attr.ib()\n    keyconf = attr.ib()\n    win_id = attr.ib()\n\n\nclass Completer(QObject):\n\n    \"\"\"Completer which manages completions in a CompletionView.\n\n    Attributes:\n        _cmd: The statusbar Command object this completer belongs to.\n        _win_id: The id of the window that owns this object.\n        _timer: The timer used to trigger the completion update.\n        _last_cursor_pos: The old cursor position so we avoid double completion\n                          updates.\n        _last_text: The old command text so we avoid double completion updates.\n        _last_completion_func: The completion function used for the last text.\n    \"\"\"\n\n    def __init__(self, *, cmd, win_id, parent=None):\n        super().__init__(parent)\n        self._cmd = cmd\n        self._win_id = win_id\n        self._timer = QTimer()\n        self._timer.setSingleShot(True)\n        self._timer.setInterval(0)\n        self._timer.timeout.connect(self._update_completion)\n        self._last_cursor_pos = None\n        self._last_text = None\n        self._last_completion_func = None\n        self._cmd.update_completion.connect(self.schedule_completion_update)\n\n    def __repr__(self):\n        return utils.get_repr(self)\n\n    def _model(self):\n        \"\"\"Convenience method to get the current completion model.\"\"\"\n        completion = self.parent()\n        return completion.model()\n\n    def _get_new_completion(self, before_cursor, under_cursor):\n        \"\"\"Get the completion function based on the current command text.\n\n        Args:\n            before_cursor: The command chunks before the cursor.\n            under_cursor: The command chunk under the cursor.\n\n        Return:\n            A completion model.\n        \"\"\"\n        if '--' in before_cursor or under_cursor.startswith('-'):\n            # cursor on a flag or after an explicit split (--)\n            return None\n        log.completion.debug(\"Before removing flags: {}\".format(before_cursor))\n        if not before_cursor:\n            # '|' or 'set|'\n            log.completion.debug('Starting command completion')\n            return miscmodels.command\n        try:\n            cmd = cmdutils.cmd_dict[before_cursor[0]]\n        except KeyError:\n            log.completion.debug(\"No completion for unknown command: {}\"\n                                 .format(before_cursor[0]))\n            return None\n\n        before_cursor = [x for x in before_cursor if not x.startswith('-')]\n        log.completion.debug(\"After removing flags: {}\".format(before_cursor))\n        argpos = len(before_cursor) - 1\n        try:\n            func = cmd.get_pos_arg_info(argpos).completion\n        except IndexError:\n            log.completion.debug(\"No completion in position {}\".format(argpos))\n            return None\n        return func\n\n    def _quote(self, s):\n        \"\"\"Quote s if it needs quoting for the commandline.\n\n        Note we don't use shlex.quote because that quotes a lot of shell\n        metachars we don't need to have quoted.\n        \"\"\"\n        if not s:\n            return \"''\"\n        elif any(c in s for c in ' \"\\'\\t\\n\\\\'):\n            # use single quotes, and put single quotes into double quotes\n            # the string $'b is then quoted as '$'\"'\"'b'\n            return \"'\" + s.replace(\"'\", \"'\\\"'\\\"'\") + \"'\"\n        else:\n            return s\n\n    def _partition(self):\n        \"\"\"Divide the commandline text into chunks around the cursor position.\n\n        Return:\n            ([parts_before_cursor], 'part_under_cursor', [parts_after_cursor])\n        \"\"\"\n        text = self._cmd.text()[len(self._cmd.prefix()):]\n        if not text or not text.strip():\n            # Only \":\", empty part under the cursor with nothing before/after\n            return [], '', []\n        parser = runners.CommandParser()\n        result = parser.parse(text, fallback=True, keep=True)\n        parts = [x for x in result.cmdline if x]\n        pos = self._cmd.cursorPosition() - len(self._cmd.prefix())\n        pos = min(pos, len(text))  # Qt treats 2-byte UTF-16 chars as 2 chars\n        log.completion.debug('partitioning {} around position {}'.format(parts,\n                                                                         pos))\n        for i, part in enumerate(parts):\n            pos -= len(part)\n            if pos <= 0:\n                if part[pos-1:pos+1].isspace():\n                    # cursor is in a space between two existing words\n                    parts.insert(i, '')\n                prefix = [x.strip() for x in parts[:i]]\n                center = parts[i].strip()\n                # strip trailing whitepsace included as a separate token\n                postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]\n                log.completion.debug(\n                    \"partitioned: {} '{}' {}\".format(prefix, center, postfix))\n                return prefix, center, postfix\n\n        raise utils.Unreachable(\"Not all parts consumed: {}\".format(parts))\n\n    @pyqtSlot(str)\n    def on_selection_changed(self, text):\n        \"\"\"Change the completed part if a new item was selected.\n\n        Called from the views selectionChanged method.\n\n        Args:\n            text: Newly selected text.\n        \"\"\"\n        if text is None:\n            return\n        before, center, after = self._partition()\n        log.completion.debug(\"Changing {} to '{}'\".format(center, text))\n        try:\n            maxsplit = cmdutils.cmd_dict[before[0]].maxsplit\n        except (KeyError, IndexError):\n            maxsplit = None\n        if maxsplit is None:\n            text = self._quote(text)\n        model = self._model()\n        if model.count() == 1 and config.val.completion.quick:\n            # If we only have one item, we want to apply it immediately and go\n            # on to the next part, unless we are quick-completing the part\n            # after maxsplit, so that we don't keep offering completions\n            # (see issue #1519)\n            if maxsplit is not None and maxsplit < len(before):\n                self._change_completed_part(text, before, after)\n            else:\n                self._change_completed_part(text, before, after,\n                                            immediate=True)\n        else:\n            self._change_completed_part(text, before, after)\n\n    @pyqtSlot()\n    def schedule_completion_update(self):\n        \"\"\"Schedule updating/enabling completion.\n\n        For performance reasons we don't want to block here, instead we do this\n        in the background.\n\n        We delay the update only if we've already input some text and ignore\n        updates if the text is shorter than completion.min_chars (unless we're\n        hitting backspace in which case updates won't be ignored).\n        \"\"\"\n        _cmd, _sep, rest = self._cmd.text().partition(' ')\n        input_length = len(rest)\n        if (0 < input_length < config.val.completion.min_chars and\n                self._cmd.cursorPosition() > self._last_cursor_pos):\n            log.completion.debug(\"Ignoring update because the length of \"\n                                 \"the text is less than completion.min_chars.\")\n        elif (self._cmd.cursorPosition() == self._last_cursor_pos and\n              self._cmd.text() == self._last_text):\n            log.completion.debug(\"Ignoring update because there were no \"\n                                 \"changes.\")\n        else:\n            log.completion.debug(\"Scheduling completion update.\")\n            start_delay = config.val.completion.delay if self._last_text else 0\n            self._timer.start(start_delay)\n        self._last_cursor_pos = self._cmd.cursorPosition()\n        self._last_text = self._cmd.text()\n\n    @pyqtSlot()\n    def _update_completion(self):\n        \"\"\"Check if completions are available and activate them.\"\"\"\n        completion = self.parent()\n\n        if self._cmd.prefix() != ':':\n            # This is a search or gibberish, so we don't need to complete\n            # anything (yet)\n            # FIXME complete searches\n            # https://github.com/qutebrowser/qutebrowser/issues/32\n            completion.set_model(None)\n            self._last_completion_func = None\n            return\n\n        before_cursor, pattern, after_cursor = self._partition()\n\n        log.completion.debug(\"Updating completion: {} {} {}\".format(\n            before_cursor, pattern, after_cursor))\n\n        pattern = pattern.strip(\"'\\\"\")\n        func = self._get_new_completion(before_cursor, pattern)\n\n        if func is None:\n            log.completion.debug('Clearing completion')\n            completion.set_model(None)\n            self._last_completion_func = None\n            return\n\n        if func != self._last_completion_func:\n            self._last_completion_func = func\n            args = (x for x in before_cursor[1:] if not x.startswith('-'))\n            with debug.log_time(log.completion, 'Starting {} completion'\n                                .format(func.__name__)):\n                info = CompletionInfo(config=config.instance,\n                                      keyconf=config.key_instance,\n                                      win_id=self._win_id)\n                model = func(*args, info=info)\n            with debug.log_time(log.completion, 'Set completion model'):\n                completion.set_model(model)\n\n        completion.set_pattern(pattern)\n\n    def _change_completed_part(self, newtext, before, after, immediate=False):\n        \"\"\"Change the part we're currently completing in the commandline.\n\n        Args:\n            text: The text to set (string) for the token under the cursor.\n            before: Commandline tokens before the token under the cursor.\n            after: Commandline tokens after the token under the cursor.\n            immediate: True if the text should be completed immediately\n                       including a trailing space and we shouldn't continue\n                       completing the current item.\n        \"\"\"\n        text = self._cmd.prefix() + ' '.join(before + [newtext])\n        pos = len(text) + (1 if immediate else 0)\n        if after:\n            text += ' ' + ' '.join(after)\n        elif immediate:\n            # pad with a space if quick-completing the last entry\n            text += ' '\n        log.completion.debug(\"setting text = '{}', pos = {}\".format(text, pos))\n\n        # generally, we don't want to let self._cmd emit cursorPositionChanged,\n        # because that'll schedule a completion update. That happens when\n        # tabbing through the completions, and we want to change the command\n        # text but we also want to keep the original completion list for the\n        # command the user manually entered. The exception is when we're\n        # immediately completing, in which case we *do* want to update the\n        # completion view so that we can start completing the next part\n        if not immediate:\n            self._cmd.blockSignals(True)\n\n        self._cmd.setText(text)\n        self._cmd.setCursorPosition(pos)\n        self._cmd.setFocus()\n\n        self._cmd.blockSignals(False)\n        self._cmd.show_cmd.emit()\n", "path": "qutebrowser/completion/completer.py"}]}