We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Buffer command does not complete on id
When the `:buffer` completions are shown, typing in the numbers for the tab indices does not get completed.


--- 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/models/miscmodels.py`
Content:
```
1 # vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
2 
3 # Copyright 2014-2016 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 """Misc. CompletionModels."""
21 
22 from PyQt5.QtCore import Qt, QTimer, pyqtSlot
23 
24 from qutebrowser.browser import browsertab
25 from qutebrowser.config import config, configdata
26 from qutebrowser.utils import objreg, log, qtutils
27 from qutebrowser.commands import cmdutils
28 from qutebrowser.completion.models import base
29 
30 
31 class CommandCompletionModel(base.BaseCompletionModel):
32 
33     """A CompletionModel filled with non-hidden commands and descriptions."""
34 
35     # https://github.com/The-Compiler/qutebrowser/issues/545
36     # pylint: disable=abstract-method
37 
38     COLUMN_WIDTHS = (20, 60, 20)
39 
40     def __init__(self, parent=None):
41         super().__init__(parent)
42         cmdlist = _get_cmd_completions(include_aliases=True,
43                                        include_hidden=False)
44         cat = self.new_category("Commands")
45         for (name, desc, misc) in cmdlist:
46             self.new_item(cat, name, desc, misc)
47 
48 
49 class HelpCompletionModel(base.BaseCompletionModel):
50 
51     """A CompletionModel filled with help topics."""
52 
53     # https://github.com/The-Compiler/qutebrowser/issues/545
54     # pylint: disable=abstract-method
55 
56     def __init__(self, parent=None):
57         super().__init__(parent)
58         self._init_commands()
59         self._init_settings()
60 
61     def _init_commands(self):
62         """Fill completion with :command entries."""
63         cmdlist = _get_cmd_completions(include_aliases=False,
64                                        include_hidden=True, prefix=':')
65         cat = self.new_category("Commands")
66         for (name, desc, misc) in cmdlist:
67             self.new_item(cat, name, desc, misc)
68 
69     def _init_settings(self):
70         """Fill completion with section->option entries."""
71         cat = self.new_category("Settings")
72         for sectname, sectdata in configdata.DATA.items():
73             for optname in sectdata:
74                 try:
75                     desc = sectdata.descriptions[optname]
76                 except (KeyError, AttributeError):
77                     # Some stuff (especially ValueList items) don't have a
78                     # description.
79                     desc = ""
80                 else:
81                     desc = desc.splitlines()[0]
82                 name = '{}->{}'.format(sectname, optname)
83                 self.new_item(cat, name, desc)
84 
85 
86 class QuickmarkCompletionModel(base.BaseCompletionModel):
87 
88     """A CompletionModel filled with all quickmarks."""
89 
90     # https://github.com/The-Compiler/qutebrowser/issues/545
91     # pylint: disable=abstract-method
92 
93     def __init__(self, parent=None):
94         super().__init__(parent)
95         cat = self.new_category("Quickmarks")
96         quickmarks = objreg.get('quickmark-manager').marks.items()
97         for qm_name, qm_url in quickmarks:
98             self.new_item(cat, qm_name, qm_url)
99 
100 
101 class BookmarkCompletionModel(base.BaseCompletionModel):
102 
103     """A CompletionModel filled with all bookmarks."""
104 
105     # https://github.com/The-Compiler/qutebrowser/issues/545
106     # pylint: disable=abstract-method
107 
108     def __init__(self, parent=None):
109         super().__init__(parent)
110         cat = self.new_category("Bookmarks")
111         bookmarks = objreg.get('bookmark-manager').marks.items()
112         for bm_url, bm_title in bookmarks:
113             self.new_item(cat, bm_url, bm_title)
114 
115 
116 class SessionCompletionModel(base.BaseCompletionModel):
117 
118     """A CompletionModel filled with session names."""
119 
120     # https://github.com/The-Compiler/qutebrowser/issues/545
121     # pylint: disable=abstract-method
122 
123     def __init__(self, parent=None):
124         super().__init__(parent)
125         cat = self.new_category("Sessions")
126         try:
127             for name in objreg.get('session-manager').list_sessions():
128                 if not name.startswith('_'):
129                     self.new_item(cat, name)
130         except OSError:
131             log.completion.exception("Failed to list sessions!")
132 
133 
134 class TabCompletionModel(base.BaseCompletionModel):
135 
136     """A model to complete on open tabs across all windows.
137 
138     Used for switching the buffer command.
139     """
140 
141     IDX_COLUMN = 0
142     URL_COLUMN = 1
143     TEXT_COLUMN = 2
144 
145     COLUMN_WIDTHS = (6, 40, 54)
146     DUMB_SORT = Qt.DescendingOrder
147 
148     def __init__(self, parent=None):
149         super().__init__(parent)
150 
151         self.columns_to_filter = [self.URL_COLUMN, self.TEXT_COLUMN]
152 
153         for win_id in objreg.window_registry:
154             tabbed_browser = objreg.get('tabbed-browser', scope='window',
155                                         window=win_id)
156             for i in range(tabbed_browser.count()):
157                 tab = tabbed_browser.widget(i)
158                 tab.url_changed.connect(self.rebuild)
159                 tab.title_changed.connect(self.rebuild)
160                 tab.shutting_down.connect(self.delayed_rebuild)
161             tabbed_browser.new_tab.connect(self.on_new_tab)
162         objreg.get("app").new_window.connect(self.on_new_window)
163         self.rebuild()
164 
165     def on_new_window(self, window):
166         """Add hooks to new windows."""
167         window.tabbed_browser.new_tab.connect(self.on_new_tab)
168 
169     @pyqtSlot(browsertab.AbstractTab)
170     def on_new_tab(self, tab):
171         """Add hooks to new tabs."""
172         tab.url_changed.connect(self.rebuild)
173         tab.title_changed.connect(self.rebuild)
174         tab.shutting_down.connect(self.delayed_rebuild)
175         self.rebuild()
176 
177     @pyqtSlot()
178     def delayed_rebuild(self):
179         """Fire a rebuild indirectly so widgets get a chance to update."""
180         QTimer.singleShot(0, self.rebuild)
181 
182     @pyqtSlot()
183     def rebuild(self):
184         """Rebuild completion model from current tabs.
185 
186         Very lazy method of keeping the model up to date. We could connect to
187         signals for new tab, tab url/title changed, tab close, tab moved and
188         make sure we handled background loads too ... but iterating over a
189         few/few dozen/few hundred tabs doesn't take very long at all.
190         """
191         window_count = 0
192         for win_id in objreg.window_registry:
193             tabbed_browser = objreg.get('tabbed-browser', scope='window',
194                                         window=win_id)
195             if not tabbed_browser.shutting_down:
196                 window_count += 1
197 
198         if window_count < self.rowCount():
199             self.removeRows(window_count, self.rowCount() - window_count)
200 
201         for i, win_id in enumerate(objreg.window_registry):
202             tabbed_browser = objreg.get('tabbed-browser', scope='window',
203                                         window=win_id)
204             if tabbed_browser.shutting_down:
205                 continue
206             if i >= self.rowCount():
207                 c = self.new_category("{}".format(win_id))
208             else:
209                 c = self.item(i, 0)
210                 c.setData("{}".format(win_id), Qt.DisplayRole)
211             if tabbed_browser.count() < c.rowCount():
212                 c.removeRows(tabbed_browser.count(),
213                              c.rowCount() - tabbed_browser.count())
214             for idx in range(tabbed_browser.count()):
215                 tab = tabbed_browser.widget(idx)
216                 if idx >= c.rowCount():
217                     self.new_item(c, "{}/{}".format(win_id, idx + 1),
218                                   tab.url().toDisplayString(),
219                                   tabbed_browser.page_title(idx))
220                 else:
221                     c.child(idx, 0).setData("{}/{}".format(win_id, idx + 1),
222                                             Qt.DisplayRole)
223                     c.child(idx, 1).setData(tab.url().toDisplayString(),
224                                             Qt.DisplayRole)
225                     c.child(idx, 2).setData(tabbed_browser.page_title(idx),
226                                             Qt.DisplayRole)
227 
228     def delete_cur_item(self, completion):
229         """Delete the selected item.
230 
231         Args:
232             completion: The Completion object to use.
233         """
234         index = completion.currentIndex()
235         qtutils.ensure_valid(index)
236         category = index.parent()
237         qtutils.ensure_valid(category)
238         index = category.child(index.row(), self.IDX_COLUMN)
239         win_id, tab_index = index.data().split('/')
240 
241         tabbed_browser = objreg.get('tabbed-browser', scope='window',
242                                     window=int(win_id))
243         tabbed_browser.on_tab_close_requested(int(tab_index) - 1)
244 
245 
246 class BindCompletionModel(base.BaseCompletionModel):
247 
248     """A CompletionModel filled with all bindable commands and descriptions."""
249 
250     # https://github.com/The-Compiler/qutebrowser/issues/545
251     # pylint: disable=abstract-method
252 
253     COLUMN_WIDTHS = (20, 60, 20)
254 
255     def __init__(self, parent=None):
256         super().__init__(parent)
257         cmdlist = _get_cmd_completions(include_hidden=True,
258                                        include_aliases=True)
259         cat = self.new_category("Commands")
260         for (name, desc, misc) in cmdlist:
261             self.new_item(cat, name, desc, misc)
262 
263 
264 def _get_cmd_completions(include_hidden, include_aliases, prefix=''):
265     """Get a list of completions info for commands, sorted by name.
266 
267     Args:
268         include_hidden: True to include commands annotated with hide=True.
269         include_aliases: True to include command aliases.
270         prefix: String to append to the command name.
271 
272     Return: A list of tuples of form (name, description, bindings).
273     """
274     assert cmdutils.cmd_dict
275     cmdlist = []
276     cmd_to_keys = objreg.get('key-config').get_reverse_bindings_for('normal')
277     for obj in set(cmdutils.cmd_dict.values()):
278         hide_debug = obj.debug and not objreg.get('args').debug
279         hide_hidden = obj.hide and not include_hidden
280         if not (hide_debug or hide_hidden or obj.deprecated):
281             bindings = ', '.join(cmd_to_keys.get(obj.name, []))
282             cmdlist.append((prefix + obj.name, obj.desc, bindings))
283 
284     if include_aliases:
285         for name, cmd in config.section('aliases').items():
286             bindings = ', '.join(cmd_to_keys.get(name, []))
287             cmdlist.append((name, "Alias for '{}'".format(cmd), bindings))
288 
289     return cmdlist
290
```
--- 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/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py
--- a/qutebrowser/completion/models/miscmodels.py
+++ b/qutebrowser/completion/models/miscmodels.py
@@ -148,7 +148,8 @@
     def __init__(self, parent=None):
         super().__init__(parent)
 
-        self.columns_to_filter = [self.URL_COLUMN, self.TEXT_COLUMN]
+        self.columns_to_filter = [self.IDX_COLUMN, self.URL_COLUMN,
+                                  self.TEXT_COLUMN]
 
         for win_id in objreg.window_registry:
             tabbed_browser = objreg.get('tabbed-browser', scope='window',

{"golden_diff": "diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py\n--- a/qutebrowser/completion/models/miscmodels.py\n+++ b/qutebrowser/completion/models/miscmodels.py\n@@ -148,7 +148,8 @@\n     def __init__(self, parent=None):\n         super().__init__(parent)\n \n-        self.columns_to_filter = [self.URL_COLUMN, self.TEXT_COLUMN]\n+        self.columns_to_filter = [self.IDX_COLUMN, self.URL_COLUMN,\n+                                  self.TEXT_COLUMN]\n \n         for win_id in objreg.window_registry:\n             tabbed_browser = objreg.get('tabbed-browser', scope='window',\n", "issue": "Buffer command does not complete on id\nWhen the `:buffer` completions are shown, typing in the numbers for the tab indices does not get completed.\n\n", "before_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2014-2016 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\"\"\"Misc. CompletionModels.\"\"\"\n\nfrom PyQt5.QtCore import Qt, QTimer, pyqtSlot\n\nfrom qutebrowser.browser import browsertab\nfrom qutebrowser.config import config, configdata\nfrom qutebrowser.utils import objreg, log, qtutils\nfrom qutebrowser.commands import cmdutils\nfrom qutebrowser.completion.models import base\n\n\nclass CommandCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with non-hidden commands and descriptions.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    COLUMN_WIDTHS = (20, 60, 20)\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cmdlist = _get_cmd_completions(include_aliases=True,\n                                       include_hidden=False)\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n\nclass HelpCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with help topics.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        self._init_commands()\n        self._init_settings()\n\n    def _init_commands(self):\n        \"\"\"Fill completion with :command entries.\"\"\"\n        cmdlist = _get_cmd_completions(include_aliases=False,\n                                       include_hidden=True, prefix=':')\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n    def _init_settings(self):\n        \"\"\"Fill completion with section->option entries.\"\"\"\n        cat = self.new_category(\"Settings\")\n        for sectname, sectdata in configdata.DATA.items():\n            for optname in sectdata:\n                try:\n                    desc = sectdata.descriptions[optname]\n                except (KeyError, AttributeError):\n                    # Some stuff (especially ValueList items) don't have a\n                    # description.\n                    desc = \"\"\n                else:\n                    desc = desc.splitlines()[0]\n                name = '{}->{}'.format(sectname, optname)\n                self.new_item(cat, name, desc)\n\n\nclass QuickmarkCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all quickmarks.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Quickmarks\")\n        quickmarks = objreg.get('quickmark-manager').marks.items()\n        for qm_name, qm_url in quickmarks:\n            self.new_item(cat, qm_name, qm_url)\n\n\nclass BookmarkCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all bookmarks.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Bookmarks\")\n        bookmarks = objreg.get('bookmark-manager').marks.items()\n        for bm_url, bm_title in bookmarks:\n            self.new_item(cat, bm_url, bm_title)\n\n\nclass SessionCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with session names.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Sessions\")\n        try:\n            for name in objreg.get('session-manager').list_sessions():\n                if not name.startswith('_'):\n                    self.new_item(cat, name)\n        except OSError:\n            log.completion.exception(\"Failed to list sessions!\")\n\n\nclass TabCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A model to complete on open tabs across all windows.\n\n    Used for switching the buffer command.\n    \"\"\"\n\n    IDX_COLUMN = 0\n    URL_COLUMN = 1\n    TEXT_COLUMN = 2\n\n    COLUMN_WIDTHS = (6, 40, 54)\n    DUMB_SORT = Qt.DescendingOrder\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n\n        self.columns_to_filter = [self.URL_COLUMN, self.TEXT_COLUMN]\n\n        for win_id in objreg.window_registry:\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            for i in range(tabbed_browser.count()):\n                tab = tabbed_browser.widget(i)\n                tab.url_changed.connect(self.rebuild)\n                tab.title_changed.connect(self.rebuild)\n                tab.shutting_down.connect(self.delayed_rebuild)\n            tabbed_browser.new_tab.connect(self.on_new_tab)\n        objreg.get(\"app\").new_window.connect(self.on_new_window)\n        self.rebuild()\n\n    def on_new_window(self, window):\n        \"\"\"Add hooks to new windows.\"\"\"\n        window.tabbed_browser.new_tab.connect(self.on_new_tab)\n\n    @pyqtSlot(browsertab.AbstractTab)\n    def on_new_tab(self, tab):\n        \"\"\"Add hooks to new tabs.\"\"\"\n        tab.url_changed.connect(self.rebuild)\n        tab.title_changed.connect(self.rebuild)\n        tab.shutting_down.connect(self.delayed_rebuild)\n        self.rebuild()\n\n    @pyqtSlot()\n    def delayed_rebuild(self):\n        \"\"\"Fire a rebuild indirectly so widgets get a chance to update.\"\"\"\n        QTimer.singleShot(0, self.rebuild)\n\n    @pyqtSlot()\n    def rebuild(self):\n        \"\"\"Rebuild completion model from current tabs.\n\n        Very lazy method of keeping the model up to date. We could connect to\n        signals for new tab, tab url/title changed, tab close, tab moved and\n        make sure we handled background loads too ... but iterating over a\n        few/few dozen/few hundred tabs doesn't take very long at all.\n        \"\"\"\n        window_count = 0\n        for win_id in objreg.window_registry:\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            if not tabbed_browser.shutting_down:\n                window_count += 1\n\n        if window_count < self.rowCount():\n            self.removeRows(window_count, self.rowCount() - window_count)\n\n        for i, win_id in enumerate(objreg.window_registry):\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            if tabbed_browser.shutting_down:\n                continue\n            if i >= self.rowCount():\n                c = self.new_category(\"{}\".format(win_id))\n            else:\n                c = self.item(i, 0)\n                c.setData(\"{}\".format(win_id), Qt.DisplayRole)\n            if tabbed_browser.count() < c.rowCount():\n                c.removeRows(tabbed_browser.count(),\n                             c.rowCount() - tabbed_browser.count())\n            for idx in range(tabbed_browser.count()):\n                tab = tabbed_browser.widget(idx)\n                if idx >= c.rowCount():\n                    self.new_item(c, \"{}/{}\".format(win_id, idx + 1),\n                                  tab.url().toDisplayString(),\n                                  tabbed_browser.page_title(idx))\n                else:\n                    c.child(idx, 0).setData(\"{}/{}\".format(win_id, idx + 1),\n                                            Qt.DisplayRole)\n                    c.child(idx, 1).setData(tab.url().toDisplayString(),\n                                            Qt.DisplayRole)\n                    c.child(idx, 2).setData(tabbed_browser.page_title(idx),\n                                            Qt.DisplayRole)\n\n    def delete_cur_item(self, completion):\n        \"\"\"Delete the selected item.\n\n        Args:\n            completion: The Completion object to use.\n        \"\"\"\n        index = completion.currentIndex()\n        qtutils.ensure_valid(index)\n        category = index.parent()\n        qtutils.ensure_valid(category)\n        index = category.child(index.row(), self.IDX_COLUMN)\n        win_id, tab_index = index.data().split('/')\n\n        tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                    window=int(win_id))\n        tabbed_browser.on_tab_close_requested(int(tab_index) - 1)\n\n\nclass BindCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all bindable commands and descriptions.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    COLUMN_WIDTHS = (20, 60, 20)\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cmdlist = _get_cmd_completions(include_hidden=True,\n                                       include_aliases=True)\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n\ndef _get_cmd_completions(include_hidden, include_aliases, prefix=''):\n    \"\"\"Get a list of completions info for commands, sorted by name.\n\n    Args:\n        include_hidden: True to include commands annotated with hide=True.\n        include_aliases: True to include command aliases.\n        prefix: String to append to the command name.\n\n    Return: A list of tuples of form (name, description, bindings).\n    \"\"\"\n    assert cmdutils.cmd_dict\n    cmdlist = []\n    cmd_to_keys = objreg.get('key-config').get_reverse_bindings_for('normal')\n    for obj in set(cmdutils.cmd_dict.values()):\n        hide_debug = obj.debug and not objreg.get('args').debug\n        hide_hidden = obj.hide and not include_hidden\n        if not (hide_debug or hide_hidden or obj.deprecated):\n            bindings = ', '.join(cmd_to_keys.get(obj.name, []))\n            cmdlist.append((prefix + obj.name, obj.desc, bindings))\n\n    if include_aliases:\n        for name, cmd in config.section('aliases').items():\n            bindings = ', '.join(cmd_to_keys.get(name, []))\n            cmdlist.append((name, \"Alias for '{}'\".format(cmd), bindings))\n\n    return cmdlist\n", "path": "qutebrowser/completion/models/miscmodels.py"}], "after_files": [{"content": "# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:\n\n# Copyright 2014-2016 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\"\"\"Misc. CompletionModels.\"\"\"\n\nfrom PyQt5.QtCore import Qt, QTimer, pyqtSlot\n\nfrom qutebrowser.browser import browsertab\nfrom qutebrowser.config import config, configdata\nfrom qutebrowser.utils import objreg, log, qtutils\nfrom qutebrowser.commands import cmdutils\nfrom qutebrowser.completion.models import base\n\n\nclass CommandCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with non-hidden commands and descriptions.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    COLUMN_WIDTHS = (20, 60, 20)\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cmdlist = _get_cmd_completions(include_aliases=True,\n                                       include_hidden=False)\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n\nclass HelpCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with help topics.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        self._init_commands()\n        self._init_settings()\n\n    def _init_commands(self):\n        \"\"\"Fill completion with :command entries.\"\"\"\n        cmdlist = _get_cmd_completions(include_aliases=False,\n                                       include_hidden=True, prefix=':')\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n    def _init_settings(self):\n        \"\"\"Fill completion with section->option entries.\"\"\"\n        cat = self.new_category(\"Settings\")\n        for sectname, sectdata in configdata.DATA.items():\n            for optname in sectdata:\n                try:\n                    desc = sectdata.descriptions[optname]\n                except (KeyError, AttributeError):\n                    # Some stuff (especially ValueList items) don't have a\n                    # description.\n                    desc = \"\"\n                else:\n                    desc = desc.splitlines()[0]\n                name = '{}->{}'.format(sectname, optname)\n                self.new_item(cat, name, desc)\n\n\nclass QuickmarkCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all quickmarks.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Quickmarks\")\n        quickmarks = objreg.get('quickmark-manager').marks.items()\n        for qm_name, qm_url in quickmarks:\n            self.new_item(cat, qm_name, qm_url)\n\n\nclass BookmarkCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all bookmarks.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Bookmarks\")\n        bookmarks = objreg.get('bookmark-manager').marks.items()\n        for bm_url, bm_title in bookmarks:\n            self.new_item(cat, bm_url, bm_title)\n\n\nclass SessionCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with session names.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cat = self.new_category(\"Sessions\")\n        try:\n            for name in objreg.get('session-manager').list_sessions():\n                if not name.startswith('_'):\n                    self.new_item(cat, name)\n        except OSError:\n            log.completion.exception(\"Failed to list sessions!\")\n\n\nclass TabCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A model to complete on open tabs across all windows.\n\n    Used for switching the buffer command.\n    \"\"\"\n\n    IDX_COLUMN = 0\n    URL_COLUMN = 1\n    TEXT_COLUMN = 2\n\n    COLUMN_WIDTHS = (6, 40, 54)\n    DUMB_SORT = Qt.DescendingOrder\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n\n        self.columns_to_filter = [self.IDX_COLUMN, self.URL_COLUMN,\n                                  self.TEXT_COLUMN]\n\n        for win_id in objreg.window_registry:\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            for i in range(tabbed_browser.count()):\n                tab = tabbed_browser.widget(i)\n                tab.url_changed.connect(self.rebuild)\n                tab.title_changed.connect(self.rebuild)\n                tab.shutting_down.connect(self.delayed_rebuild)\n            tabbed_browser.new_tab.connect(self.on_new_tab)\n        objreg.get(\"app\").new_window.connect(self.on_new_window)\n        self.rebuild()\n\n    def on_new_window(self, window):\n        \"\"\"Add hooks to new windows.\"\"\"\n        window.tabbed_browser.new_tab.connect(self.on_new_tab)\n\n    @pyqtSlot(browsertab.AbstractTab)\n    def on_new_tab(self, tab):\n        \"\"\"Add hooks to new tabs.\"\"\"\n        tab.url_changed.connect(self.rebuild)\n        tab.title_changed.connect(self.rebuild)\n        tab.shutting_down.connect(self.delayed_rebuild)\n        self.rebuild()\n\n    @pyqtSlot()\n    def delayed_rebuild(self):\n        \"\"\"Fire a rebuild indirectly so widgets get a chance to update.\"\"\"\n        QTimer.singleShot(0, self.rebuild)\n\n    @pyqtSlot()\n    def rebuild(self):\n        \"\"\"Rebuild completion model from current tabs.\n\n        Very lazy method of keeping the model up to date. We could connect to\n        signals for new tab, tab url/title changed, tab close, tab moved and\n        make sure we handled background loads too ... but iterating over a\n        few/few dozen/few hundred tabs doesn't take very long at all.\n        \"\"\"\n        window_count = 0\n        for win_id in objreg.window_registry:\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            if not tabbed_browser.shutting_down:\n                window_count += 1\n\n        if window_count < self.rowCount():\n            self.removeRows(window_count, self.rowCount() - window_count)\n\n        for i, win_id in enumerate(objreg.window_registry):\n            tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                        window=win_id)\n            if tabbed_browser.shutting_down:\n                continue\n            if i >= self.rowCount():\n                c = self.new_category(\"{}\".format(win_id))\n            else:\n                c = self.item(i, 0)\n                c.setData(\"{}\".format(win_id), Qt.DisplayRole)\n            if tabbed_browser.count() < c.rowCount():\n                c.removeRows(tabbed_browser.count(),\n                             c.rowCount() - tabbed_browser.count())\n            for idx in range(tabbed_browser.count()):\n                tab = tabbed_browser.widget(idx)\n                if idx >= c.rowCount():\n                    self.new_item(c, \"{}/{}\".format(win_id, idx + 1),\n                                  tab.url().toDisplayString(),\n                                  tabbed_browser.page_title(idx))\n                else:\n                    c.child(idx, 0).setData(\"{}/{}\".format(win_id, idx + 1),\n                                            Qt.DisplayRole)\n                    c.child(idx, 1).setData(tab.url().toDisplayString(),\n                                            Qt.DisplayRole)\n                    c.child(idx, 2).setData(tabbed_browser.page_title(idx),\n                                            Qt.DisplayRole)\n\n    def delete_cur_item(self, completion):\n        \"\"\"Delete the selected item.\n\n        Args:\n            completion: The Completion object to use.\n        \"\"\"\n        index = completion.currentIndex()\n        qtutils.ensure_valid(index)\n        category = index.parent()\n        qtutils.ensure_valid(category)\n        index = category.child(index.row(), self.IDX_COLUMN)\n        win_id, tab_index = index.data().split('/')\n\n        tabbed_browser = objreg.get('tabbed-browser', scope='window',\n                                    window=int(win_id))\n        tabbed_browser.on_tab_close_requested(int(tab_index) - 1)\n\n\nclass BindCompletionModel(base.BaseCompletionModel):\n\n    \"\"\"A CompletionModel filled with all bindable commands and descriptions.\"\"\"\n\n    # https://github.com/The-Compiler/qutebrowser/issues/545\n    # pylint: disable=abstract-method\n\n    COLUMN_WIDTHS = (20, 60, 20)\n\n    def __init__(self, parent=None):\n        super().__init__(parent)\n        cmdlist = _get_cmd_completions(include_hidden=True,\n                                       include_aliases=True)\n        cat = self.new_category(\"Commands\")\n        for (name, desc, misc) in cmdlist:\n            self.new_item(cat, name, desc, misc)\n\n\ndef _get_cmd_completions(include_hidden, include_aliases, prefix=''):\n    \"\"\"Get a list of completions info for commands, sorted by name.\n\n    Args:\n        include_hidden: True to include commands annotated with hide=True.\n        include_aliases: True to include command aliases.\n        prefix: String to append to the command name.\n\n    Return: A list of tuples of form (name, description, bindings).\n    \"\"\"\n    assert cmdutils.cmd_dict\n    cmdlist = []\n    cmd_to_keys = objreg.get('key-config').get_reverse_bindings_for('normal')\n    for obj in set(cmdutils.cmd_dict.values()):\n        hide_debug = obj.debug and not objreg.get('args').debug\n        hide_hidden = obj.hide and not include_hidden\n        if not (hide_debug or hide_hidden or obj.deprecated):\n            bindings = ', '.join(cmd_to_keys.get(obj.name, []))\n            cmdlist.append((prefix + obj.name, obj.desc, bindings))\n\n    if include_aliases:\n        for name, cmd in config.section('aliases').items():\n            bindings = ', '.join(cmd_to_keys.get(name, []))\n            cmdlist.append((name, \"Alias for '{}'\".format(cmd), bindings))\n\n    return cmdlist\n", "path": "qutebrowser/completion/models/miscmodels.py"}]}