internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: qutebrowser/qutebrowser

Issue:
Completing URL with '&' shows '&amp;'
Consider this URL: https://wiki.archlinux.org/api.php?action=query&pageids=12345

After writing `action=query` in the `:open` prompt, it is highlighted correctly. After adding `&` (i.e. the filter is `action=query&`), the URL is changed to `https://wiki.archlinux.org/api.php?action=query&amp;pageids=12345` in the completer and the pattern is still highlighted. After adding anything what follows in the URL, e.g. `action=query&pageids`, the URL is changed back to the original and nothing is highlighted, although the URL still matches the filter as expected.


Discussion:
cc @rcorre
The problem is `html.escape` at https://github.com/qutebrowser/qutebrowser/blob/master/qutebrowser/completion/completiondelegate.py#L207. Removing it resolves this, but presumably could break the html in other cases
What if you _add_ another `html.escape` for the pattern?

```python
                text = re.sub(re.escape(html.escape(pattern)).replace(r'\ ', r'|'),
                              repl, html.escape(self._opt.text),
                              flags=re.IGNORECASE)
```

Resolving patch:
diff --git a/qutebrowser/completion/completiondelegate.py b/qutebrowser/completion/completiondelegate.py
--- a/qutebrowser/completion/completiondelegate.py
+++ b/qutebrowser/completion/completiondelegate.py
@@ -203,9 +203,9 @@ def _get_textdoc(self, index):
             columns_to_filter = index.model().columns_to_filter(index)
             if index.column() in columns_to_filter and pattern:
                 repl = r'<span class="highlight">\g<0></span>'
-                text = re.sub(re.escape(pattern).replace(r'\ ', r'|'),
-                              repl, html.escape(self._opt.text),
-                              flags=re.IGNORECASE)
+                pat = html.escape(re.escape(pattern)).replace(r'\ ', r'|')
+                txt = html.escape(self._opt.text)
+                text = re.sub(pat, repl, txt, flags=re.IGNORECASE)
                 self._doc.setHtml(text)
             else:
                 self._doc.setPlainText(self._opt.text)


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Feature request: Add option so that alt+# doesn't toggle between new and previous tab
It would be nice to have an option that can be set to disable the toggling between the new and previous tabs. I often find it easier to just press alt+# instead of looking to see if I'm on the correct tab. It can be confusing at times toggling back and forth since the tab colors don't stand out a lot.


Discussion:

Resolving patch:
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -1109,7 +1109,8 @@ def buffer(self, index=None, count=None):
     @cmdutils.register(instance='command-dispatcher', scope='window')
     @cmdutils.argument('index', choices=['last'])
     @cmdutils.argument('count', count=True)
-    def tab_focus(self, index: typing.Union[str, int] = None, count=None):
+    def tab_focus(self, index: typing.Union[str, int] = None,
+                  count=None, no_last=False):
         """Select the tab given as argument/[count].
 
         If neither count nor index are given, it behaves like tab-next.
@@ -1121,13 +1122,14 @@ def tab_focus(self, index: typing.Union[str, int] = None, count=None):
                    Negative indices count from the end, such that -1 is the
                    last tab.
             count: The tab index to focus, starting with 1.
+            no_last: Whether to avoid focusing last tab if already focused.
         """
         index = count if count is not None else index
 
         if index == 'last':
             self._tab_focus_last()
             return
-        elif index == self._current_index() + 1:
+        elif not no_last and index == self._current_index() + 1:
             self._tab_focus_last(show_error=False)
             return
         elif index is None:


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Restoring scroll position from sessions is broken with QtWebEngine
The position is saved correctly, and we try to restore it properly:

```
  /home/florian/proj/qutebrowser/git/qutebrowser/app.py(210)_process_args()
-> _load_session(args.session)
  /home/florian/proj/qutebrowser/git/qutebrowser/app.py(245)_load_session()
-> session_manager.load(name)
  /home/florian/proj/qutebrowser/git/qutebrowser/misc/sessions.py(392)load()
-> self._load_tab(new_tab, tab)
  /home/florian/proj/qutebrowser/git/qutebrowser/misc/sessions.py(364)_load_tab()
-> new_tab.history.load_items(entries)
> /home/florian/proj/qutebrowser/git/qutebrowser/browser/webengine/webenginetab.py(442)load_items()
-> QTimer.singleShot(0, functools.partial(
  /home/florian/proj/qutebrowser/git/qutebrowser/app.py(148)qt_mainloop()
-> return qApp.exec_()
> /home/florian/proj/qutebrowser/git/qutebrowser/browser/webengine/webenginetab.py(360)to_point()
-> self._tab.run_js_async(js_code)
```

However, at the time we run that JS, the page was not fully loaded yet, so our JavaScript probably runs too early.


Discussion:
Would the recent merged changes which now injects qutebrowser JS code at DocumentReady insteat of DocumentCreation fix this issue?
After testing, it looks like it does not... :(

Resolving patch:
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -26,7 +26,7 @@
 
 import sip
 from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QEvent, QPoint, QPointF,
-                          QUrl, QTimer)
+                          QUrl)
 from PyQt5.QtGui import QKeyEvent
 from PyQt5.QtNetwork import QAuthenticator
 from PyQt5.QtWidgets import QApplication
@@ -490,13 +490,18 @@ def deserialize(self, data):
     def load_items(self, items):
         stream, _data, cur_data = tabhistory.serialize(items)
         qtutils.deserialize_stream(stream, self._history)
+
+        @pyqtSlot()
+        def _on_load_finished():
+            self._tab.scroller.to_point(cur_data['scroll-pos'])
+            self._tab.load_finished.disconnect(_on_load_finished)
+
         if cur_data is not None:
             if 'zoom' in cur_data:
                 self._tab.zoom.set_factor(cur_data['zoom'])
             if ('scroll-pos' in cur_data and
                     self._tab.scroller.pos_px() == QPoint(0, 0)):
-                QTimer.singleShot(0, functools.partial(
-                    self._tab.scroller.to_point, cur_data['scroll-pos']))
+                self._tab.load_finished.connect(_on_load_finished)
 
 
 class WebEngineZoom(browsertab.AbstractZoom):


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Empty completion.timestamp_format crashes
After `:set completion.timestamp_format ''`:

```
17:26:29 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py", line 260, in _update_completion
    completion.set_pattern(pattern)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completionwidget.py", line 320, in set_pattern
    self.model().set_pattern(pattern)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/completionmodel.py", line 185, in set_pattern
    cat.set_pattern(pattern)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/histcategory.py", line 85, in set_pattern
    .format(timestamp_format.replace("'", "`")))
AttributeError: 'NoneType' object has no attribute 'replace'
```

cc @rcorre and @erikdsjostrom who reported this


Discussion:

Resolving patch:
diff --git a/qutebrowser/completion/models/histcategory.py b/qutebrowser/completion/models/histcategory.py
--- a/qutebrowser/completion/models/histcategory.py
+++ b/qutebrowser/completion/models/histcategory.py
@@ -80,7 +80,7 @@ def set_pattern(self, pattern):
             for i in range(len(words)))
 
         # replace ' in timestamp-format to avoid breaking the query
-        timestamp_format = config.val.completion.timestamp_format
+        timestamp_format = config.val.completion.timestamp_format or ''
         timefmt = ("strftime('{}', last_atime, 'unixepoch', 'localtime')"
                    .format(timestamp_format.replace("'", "`")))
 


Test patch:
diff --git a/tests/unit/completion/test_histcategory.py b/tests/unit/completion/test_histcategory.py
--- a/tests/unit/completion/test_histcategory.py
+++ b/tests/unit/completion/test_histcategory.py
@@ -205,3 +205,20 @@ def test_remove_rows_fetch(hist):
     hist.delete('url', '298')
     cat.removeRows(297, 1)
     assert cat.rowCount() == 299
+
+
+@pytest.mark.parametrize('fmt, expected', [
+    ('%Y-%m-%d', '2018-02-27'),
+    ('%m/%d/%Y %H:%M', '02/27/2018 08:30'),
+    ('', ''),
+])
+def test_timestamp_fmt(fmt, expected, model_validator, config_stub, init_sql):
+    """Validate the filtering and sorting results of set_pattern."""
+    config_stub.val.completion.timestamp_format = fmt
+    hist = sql.SqlTable('CompletionHistory', ['url', 'title', 'last_atime'])
+    atime = datetime.datetime(2018, 2, 27, 8, 30)
+    hist.insert({'url': 'foo', 'title': '', 'last_atime': atime.timestamp()})
+    cat = histcategory.HistoryCategory()
+    model_validator.set_model(cat)
+    cat.set_pattern('')
+    model_validator.validate([('foo', '', expected)])
Repository: qutebrowser/qutebrowser

Issue:
Crash in schedule_completion_update because self._last_cursor_pos was None
From https://crashes.qutebrowser.org/view/2e422bf5

```
10:10:35 DEBUG    commands   command:run:485 command called: set-cmd-text ['-s', ':open -t']
10:10:35 DEBUG    commands   command:run:500 Calling qutebrowser.mainwindow.statusbar.command.Command.set_cmd_text_command(<qutebrowser.mainwindow.statusbar.command.Command>, ':open -t', None, True, False, False)
10:10:35 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/qutebrowser/completion/completer.py", line 206, in schedule_completion_update
    self._cmd.cursorPosition() > self._last_cursor_pos):
TypeError: '>' not supported between instances of 'int' and 'NoneType'
```


Discussion:
Can repro with `completion.min_chars=4` and press `O` right after opening the browser.

Resolving patch:
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -60,7 +60,7 @@ def __init__(self, *, cmd, win_id, parent=None):
         self._timer.setSingleShot(True)
         self._timer.setInterval(0)
         self._timer.timeout.connect(self._update_completion)
-        self._last_cursor_pos = None
+        self._last_cursor_pos = -1
         self._last_text = None
         self._last_completion_func = None
         self._cmd.update_completion.connect(self.schedule_completion_update)


Test patch:
diff --git a/tests/unit/completion/test_completer.py b/tests/unit/completion/test_completer.py
--- a/tests/unit/completion/test_completer.py
+++ b/tests/unit/completion/test_completer.py
@@ -313,3 +313,22 @@ def test_quickcomplete_flicker(status_command_stub, completer_obj,
     completer_obj.on_selection_changed('http://example.com')
     completer_obj.schedule_completion_update()
     assert not completion_widget_stub.set_model.called
+
+
+def test_min_chars(status_command_stub, completer_obj, completion_widget_stub,
+                   config_stub, key_config_stub):
+    """Test that an update is delayed until min_chars characters are input."""
+    config_stub.val.completion.min_chars = 3
+
+    # Test #3635, where min_chars could crash the first update
+    _set_cmd_prompt(status_command_stub, ':set c|')
+    completer_obj.schedule_completion_update()
+    assert completion_widget_stub.set_model.call_count == 0
+
+    _set_cmd_prompt(status_command_stub, ':set co|')
+    completer_obj.schedule_completion_update()
+    assert completion_widget_stub.set_model.call_count == 0
+
+    _set_cmd_prompt(status_command_stub, ':set com|')
+    completer_obj.schedule_completion_update()
+    assert completion_widget_stub.set_model.call_count == 1
Repository: qutebrowser/qutebrowser

Issue:
Deleted C++ object: QWebFrame in _inject_userjs
Getting various crash reports like this:

```
13:18:20 DEBUG    greasemonkey webpage:_inject_userjs:312 _inject_userjs called for <PyQt5.QtWebKitWidgets.QWebFrame object at 0x7fadc1f15288> (https://information.rapid7.com/index.php/form/XDFrame)
13:18:20 DEBUG    greasemonkey webpage:_inject_userjs:312 _inject_userjs called for <PyQt5.QtWebKitWidgets.QWebFrame object at 0x7fae080e8ca8> (https://www.google.com/recaptcha/api2/anchor?k=6LfW8QoUAAAAAN7jy-NRqt6xhlA_5LdQIyWI73V-&co=aHR0cHM6Ly93d3cucmFwaWQ3LmNvbTo0NDM.&hl=en&v=v1517812337239&theme=light&size=normal&cb=axrjnt33j5tk)
13:18:20 DEBUG    greasemonkey webpage:_connect_userjs_signals:101 Connecting to frame <PyQt5.QtWebKitWidgets.QWebFrame object at 0x7fadc1f151f8> ()
13:18:20 DEBUG    webview    webpage:acceptNavigationRequest:497 navigation request: url about:blank, type NavigationTypeOther, target ClickTarget.normal override None
13:18:20 DEBUG    greasemonkey webpage:_inject_userjs:312 _inject_userjs called for <PyQt5.QtWebKitWidgets.QWebFrame object at 0x7fadc1f151f8> (about:blank)
13:18:20 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/home/foka1/Downloads/qutebrowser-1.1.1/qutebrowser/browser/webkit/webpage.py", line 307, in _inject_userjs
    url = frame.url()
RuntimeError: wrapped C/C++ object of type QWebFrame has been deleted
```

reports:

- https://crashes.qutebrowser.org/view/2de60f99
- https://crashes.qutebrowser.org/view/8f8f6447
- https://crashes.qutebrowser.org/view/ccc6a034
- https://crashes.qutebrowser.org/view/cdddb995
- https://crashes.qutebrowser.org/view/1173dd85

cc @toofar because that was added for GreaseMonkey


Discussion:
Well the obvious solution is to check if the frame has been deleted but I would like to be able to reproduce it. It is stored in a closure like:
```python
frame.loadFinished.connect(
            functools.partial(self._inject_userjs, frame))
```
So it looks like frame gets deleted in the time between loadFinshed getting fire and this listener being called. Weird, maybe it is getting deleted from another handler... I should check with the host blocker.

Resolving patch:
diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py
--- a/qutebrowser/browser/webkit/webpage.py
+++ b/qutebrowser/browser/webkit/webpage.py
@@ -22,6 +22,7 @@
 import html
 import functools
 
+import sip
 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QPoint
 from PyQt5.QtGui import QDesktopServices
 from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
@@ -302,6 +303,10 @@ def _inject_userjs(self, frame):
         Args:
             frame: The QWebFrame to inject the user scripts into.
         """
+        if sip.isdeleted(frame):
+            log.greasemonkey.debug("_inject_userjs called for deleted frame!")
+            return
+
         url = frame.url()
         if url.isEmpty():
             url = frame.requestedUrl()


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Tooltips on pinned tabs are just numbers
Version: 1.2.1

Although this is the minorest of all issues, pinned tabs' tooltips don't seem to keep any information about what web page is actually loaded in the tab.


Discussion:
Hmm, by default, tooltips show just the content of the tab title (which is why they only show numbers by default). I can definetly see it being useful to have a `tabs.tooltip.format_pinned` or similar, to customize it (and perhaps defaulting to `tabs.title.format`).
Not sure if we need another config option for this - I'd prefer if it just always showed `tabs.title.format` or even only the actual page title.

Resolving patch:
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -148,9 +148,13 @@ def update_tab_title(self, idx, field=None):
         title = '' if fmt is None else fmt.format(**fields)
         tabbar = self.tabBar()
 
+        # Only change the tab title if it changes, setting the tab title causes
+        # a size recalculation which is slow.
         if tabbar.tabText(idx) != title:
             tabbar.setTabText(idx, title)
-            tabbar.setTabToolTip(idx, title)
+
+        # always show only plain title in tooltips
+        tabbar.setTabToolTip(idx, fields['title'])
 
     def get_tab_fields(self, idx):
         """Get the tab field data."""


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Tab-take should not show the tabs in current window
<!-- If this is a bug report, please remember to mention your version info from
`:open qute:version` or `qutebrowser --version` -->
If I am in one window and write ```:tab-take ```, the options of available tabs will pop up. All the tabs in the current window will be shown in the options as well. However, a window can not take its own tab, so I think we should remove the tabs in the current window from the options for the ```:tab-take```
![screen shot 2018-04-02 at 6 06 33 pm](https://user-images.githubusercontent.com/10876776/38218844-1a6ffdac-36a1-11e8-9415-fca73ca13884.png)
![screen shot 2018-04-02 at 6 08 13 pm](https://user-images.githubusercontent.com/10876776/38218845-1b9b7b70-36a1-11e8-8b7c-6ac6ffc1a047.png)

.  


Discussion:
Hm, the behavior you describe seems what was intended, I think this is a bug. let me take a stab.

I think that that tabs in win_id '0' are always included, on other window id's it behaves as expected

Resolving patch:
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
@@ -110,7 +110,7 @@ def delete_buffer(data):
     model = completionmodel.CompletionModel(column_widths=(6, 40, 54))
 
     for win_id in objreg.window_registry:
-        if skip_win_id and win_id == skip_win_id:
+        if skip_win_id is not None and win_id == skip_win_id:
             continue
         tabbed_browser = objreg.get('tabbed-browser', scope='window',
                                     window=win_id)


Test patch:
diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py
--- a/tests/unit/completion/test_models.py
+++ b/tests/unit/completion/test_models.py
@@ -618,6 +618,29 @@ def test_other_buffer_completion(qtmodeltester, fake_web_tab, app_stub,
     })
 
 
+def test_other_buffer_completion_id0(qtmodeltester, fake_web_tab, app_stub,
+                                     win_registry, tabbed_browser_stubs, info):
+    tabbed_browser_stubs[0].widget.tabs = [
+        fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
+        fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+        fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+    ]
+    tabbed_browser_stubs[1].widget.tabs = [
+        fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+    ]
+    info.win_id = 0
+    model = miscmodels.other_buffer(info=info)
+    model.set_pattern('')
+    qtmodeltester.data_display_may_return_none = True
+    qtmodeltester.check(model)
+
+    _check_completions(model, {
+        '1': [
+            ('1/1', 'https://wiki.archlinux.org', 'ArchWiki'),
+        ],
+    })
+
+
 def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs,
                            info):
     tabbed_browser_stubs[0].widget.tabs = [
Repository: qutebrowser/qutebrowser

Issue:
window.print() support
We can probably hack in `window.print()` support similar to how QupZilla did it 😆 

https://github.com/QupZilla/qupzilla/commit/d3f0d766fb052dc504de2426d42f235d96b5eb60


Discussion:
Heh looks like carewolf suggestion using window.location as RPC a while ago https://github.com/qutebrowser/qutebrowser/issues/27#issuecomment-219070932
I have a suggestion for a solution for this. Will open pull request soon, if the tests pass.

Resolving patch:
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -705,6 +705,10 @@ def _init_js(self):
             utils.read_file('javascript/webelem.js'),
             utils.read_file('javascript/caret.js'),
         )
+        self._inject_early_js('js',
+                              utils.read_file('javascript/print.js'),
+                              subframes=True,
+                              world=QWebEngineScript.MainWorld)
         # FIXME:qtwebengine what about subframes=True?
         self._inject_early_js('js', js_code, subframes=True)
         self._init_stylesheet()
@@ -1073,6 +1077,13 @@ def _on_navigation_request(self, navigation):
                                           .format(widget))
                         layout.removeWidget(widget)
 
+        if navigation.url == QUrl('qute://print'):
+            command_dispatcher = objreg.get('command-dispatcher',
+                                            scope='window',
+                                            window=self.win_id)
+            command_dispatcher.printpage()
+            navigation.accepted = False
+
         if not navigation.accepted or not navigation.is_main_frame:
             return
 


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
importer.py may fail on chrome bookmarks import
The importer.py failed on me at `assert 'type' in bm, bm` (currently line# 336). The reason being is there's an entry `"sync_transaction_version": "186"` in my chrome bookmarks, which is a string and doesn't have the `type` key.

I have a simple fix for it - adding `if isinstance(bm, dict):` before asserting type in bm, like
```
        def bm_tree_walk(bm, template):
            """Recursive function to walk through bookmarks."""
            if isinstance(bm, dict):
                assert 'type' in bm, bm
                if bm['type'] == 'url':
                    if urllib.parse.urlparse(bm['url']).scheme != 'chrome':
                        print(template.format(**bm))
                elif bm['type'] == 'folder':
                    for child in bm['children']:
                        bm_tree_walk(child, template)
```
(I'm not a Python developer. Let me know if this makes sense)


Discussion:
This looks right the right fix! However, I usually like to exit early for error conditions, i.e. something like:

```python
if not isinstance(bm, dict):
    return
```

Do you want to open a PR with that, or should I just apply it directly?

cc @ryan-farley who implemented this, though I suppose `sync_transaction_version` didn't exist back then.
I can create a PR, though this is my first time contributing to a public repo. Is there guide line I should follow? (I have done a lot of development on bitbucket private repos, but never contribute to gibhub public repo)
@jZhangTk: I guess your experience will do. Check the [contribution guide](https://www.qutebrowser.org/doc/contributing.html) for some helpful advice.

Resolving patch:
diff --git a/scripts/importer.py b/scripts/importer.py
--- a/scripts/importer.py
+++ b/scripts/importer.py
@@ -333,6 +333,8 @@ def import_chrome(profile, bookmark_types, output_format):
 
         def bm_tree_walk(bm, template):
             """Recursive function to walk through bookmarks."""
+            if not isinstance(bm, dict):
+                return
             assert 'type' in bm, bm
             if bm['type'] == 'url':
                 if urllib.parse.urlparse(bm['url']).scheme != 'chrome':


Test patch: