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

Issue:
Auto-use the first match in the completion
Requested by @Earnestly in IRC:

Typing, e.g. `:do`<kbd>Enter</kbd> should invoke `:download` automatically as that's the first-best match instead of showing an invalid command error.

(of course configurable)



Discussion:
We now do this when the entered text is unique already. It should be easy to extend this to use the first (or shortest?) match.


Resolving patch:
diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py
--- a/qutebrowser/commands/runners.py
+++ b/qutebrowser/commands/runners.py
@@ -220,6 +220,8 @@ def _completion_match(self, cmdstr):
                 matches.append(valid_command)
         if len(matches) == 1:
             cmdstr = matches[0]
+        elif len(matches) > 1 and config.val.completion.use_best_match:
+            cmdstr = matches[0]
         return cmdstr
 
     def _split_args(self, cmd, argstr, keep):


Test patch:
diff --git a/tests/unit/commands/test_runners.py b/tests/unit/commands/test_runners.py
--- a/tests/unit/commands/test_runners.py
+++ b/tests/unit/commands/test_runners.py
@@ -74,3 +74,30 @@ def test_partial_parsing(self):
         parser = runners.CommandParser(partial_match=True)
         result = parser.parse('message-i')
         assert result.cmd.name == 'message-info'
+
+
+class TestCompletions:
+
+    """Tests for completions.use_best_match."""
+
+    def test_dont_use_best_match(self, config_stub):
+        """Test multiple completion options with use_best_match set to false.
+
+        Should raise NoSuchCommandError
+        """
+        config_stub.val.completion.use_best_match = False
+        parser = runners.CommandParser(partial_match=True)
+
+        with pytest.raises(cmdexc.NoSuchCommandError):
+            result = parser.parse('do')
+
+    def test_use_best_match(self, config_stub):
+        """Test multiple completion options with use_best_match set to true.
+
+        The resulting command should be the best match
+        """
+        config_stub.val.completion.use_best_match = True
+        parser = runners.CommandParser(partial_match=True)
+
+        result = parser.parse('do')
+        assert result.cmd.name == 'download-cancel'
Repository: qutebrowser/qutebrowser

Issue:
Only show git commit (not git describe output) in version info



Discussion:

Resolving patch:
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -148,13 +148,14 @@ def _git_str_subprocess(gitpath):
     if not os.path.isdir(os.path.join(gitpath, ".git")):
         return None
     try:
-        cid = subprocess.check_output(
-            ['git', 'describe', '--tags', '--dirty', '--always'],
+        # https://stackoverflow.com/questions/21017300/21017394#21017394
+        commit_hash = subprocess.check_output(
+            ['git', 'describe', '--match=NeVeRmAtCh', '--always', '--dirty'],
             cwd=gitpath).decode('UTF-8').strip()
         date = subprocess.check_output(
             ['git', 'show', '-s', '--format=%ci', 'HEAD'],
             cwd=gitpath).decode('UTF-8').strip()
-        return '{} ({})'.format(cid, date)
+        return '{} ({})'.format(commit_hash, date)
     except (subprocess.CalledProcessError, OSError):
         return None
 
diff --git a/scripts/setupcommon.py b/scripts/setupcommon.py
--- a/scripts/setupcommon.py
+++ b/scripts/setupcommon.py
@@ -50,13 +50,14 @@ def _git_str():
     if not os.path.isdir(os.path.join(BASEDIR, ".git")):
         return None
     try:
-        cid = subprocess.check_output(
-            ['git', 'describe', '--tags', '--dirty', '--always'],
+        # https://stackoverflow.com/questions/21017300/21017394#21017394
+        commit_hash = subprocess.check_output(
+            ['git', 'describe', '--match=NeVeRmAtCh', '--always', '--dirty'],
             cwd=BASEDIR).decode('UTF-8').strip()
         date = subprocess.check_output(
             ['git', 'show', '-s', '--format=%ci', 'HEAD'],
             cwd=BASEDIR).decode('UTF-8').strip()
-        return '{} ({})'.format(cid, date)
+        return '{} ({})'.format(commit_hash, date)
     except (subprocess.CalledProcessError, OSError):
         return None
 


Test patch:
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -356,7 +356,7 @@ def _git(*args):
     def test_real_git(self, git_repo):
         """Test with a real git repository."""
         ret = version._git_str_subprocess(str(git_repo))
-        assert ret == 'foobar (1970-01-01 01:00:00 +0100)'
+        assert ret == '6e4b65a (1970-01-01 01:00:00 +0100)'
 
     def test_missing_dir(self, tmpdir):
         """Test with a directory which doesn't exist."""
Repository: qutebrowser/qutebrowser

Issue:
:home bypasses pinned tab locking
```
<hdqn> hi guys. :home ignores pinned tabs (there's no warning and it works
	   like usual) [11:41 AM]
<The-Compiler> jkamat: ^ ;) [11:42 AM]
<jkamat> aaah xD
<hdqn> something going on I'm not aware of? :D
<The-Compiler> I think pinned tabs are causing jkamat some more work than he
			   expected :D [11:43 AM]
<jkamat> hehehe :P
<jkamat> hdqn: do you mind opening an issue on github for it? Probs can't work
		 on it right now but I'll get it eventually
<jkamat> (while I'm at it, should we prevent hinting (f) in pinned tab mode? I
		 think that should be allowed but I'm not sure) [11:44 AM]
<The-Compiler> I guess it should be allowed, I mean, clicking hints works as
			   well [11:45 AM]
<The-Compiler> err, clicking links [11:46 AM]
<jkamat> yah, agreed [11:51 AM]
<jkamat> FWIW, firefox dosen't prevent you from moving around in pinned tabs
		 at all, so qb is a bit unique in that regard
```




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
@@ -353,6 +353,10 @@ def _parse_url_input(self, url):
         Return:
             A list of URLs that can be opened.
         """
+        if isinstance(url, QUrl):
+            yield url
+            return
+
         force_search = False
         urllist = [u for u in url.split('\n') if u.strip()]
         if (len(urllist) > 1 and not urlutils.is_url(urllist[0]) and
@@ -1210,7 +1214,7 @@ def spawn(self, cmdline, userscript=False, verbose=False, detach=False):
     @cmdutils.register(instance='command-dispatcher', scope='window')
     def home(self):
         """Open main startpage in current tab."""
-        self._current_widget().openurl(config.val.url.start_pages[0])
+        self.openurl(config.val.url.start_pages[0])
 
     def _run_userscript(self, cmd, *args, verbose=False):
         """Run a userscript given as argument.


Test patch:
diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature
--- a/tests/end2end/features/tabs.feature
+++ b/tests/end2end/features/tabs.feature
@@ -1197,6 +1197,14 @@ Feature: Tab management
         And the following tabs should be open:
             - data/numbers/1.txt (active) (pinned)
 
+    Scenario: :tab-pin open url
+        When I open data/numbers/1.txt
+        And I run :tab-pin
+        And I run :home
+        Then the message "Tab is pinned!" should be shown
+        And the following tabs should be open:
+            - data/numbers/1.txt (active) (pinned)
+
     Scenario: Cloning a pinned tab
         When I open data/numbers/1.txt
         And I run :tab-pin
Repository: qutebrowser/qutebrowser

Issue:
Typing space after completing full match does nothing
When typing `:set`, then tabbing to select `:set` and then pressing space, the completion doesn't change (it only does so when typing another space).

This also seems to happen with v0.11.0 (with the old completion code), but tagging @rcorre anyways in case you want to take a look :wink:


Discussion:

Resolving patch:
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -186,8 +186,6 @@ def on_selection_changed(self, text):
                 # keep offering completions (see issue #1519)
                 self._ignore_change = True
         else:
-            log.completion.debug("Will ignore next completion update.")
-            self._ignore_change = True
             self._change_completed_part(text, before, after)
 
     @pyqtSlot()
@@ -284,7 +282,20 @@ def _change_completed_part(self, newtext, before, after, immediate=False):
             # pad with a space if quick-completing the last entry
             text += ' '
         log.completion.debug("setting text = '{}', pos = {}".format(text, pos))
+
+        # generally, we don't want to let self._cmd emit cursorPositionChanged,
+        # because that'll schedule a completion update. That happens when
+        # tabbing through the completions, and we want to change the command
+        # text but we also want to keep the original completion list for the
+        # command the user manually entered. The exception is when we're
+        # immediately completing, in which case we *do* want to update the
+        # completion view so that we can start completing the next part
+        if not immediate:
+            self._cmd.blockSignals(True)
+
         self._cmd.setText(text)
         self._cmd.setCursorPosition(pos)
         self._cmd.setFocus()
+
+        self._cmd.blockSignals(False)
         self._cmd.show_cmd.emit()


Test patch:
diff --git a/tests/end2end/features/completion.feature b/tests/end2end/features/completion.feature
--- a/tests/end2end/features/completion.feature
+++ b/tests/end2end/features/completion.feature
@@ -95,3 +95,9 @@ Feature: Using completion
         Then the following tabs should be open:
             - data/hello2.txt (active)
             - data/hello.txt
+
+    Scenario: Space updates completion model after selecting full command
+        When I run :set-cmd-text :set
+        And I run :completion-item-focus next
+        When I run :set-cmd-text -s :set
+        Then the completion model should be option
Repository: qutebrowser/qutebrowser

Issue:
:tab-give with unknown window ID crashes
Running `:tab-give 1337`:

```
23:08:35 DEBUG    commands   command:run:489 command called: tab-give ['1337']
23:08:35 DEBUG    commands   command:run:504 Calling qutebrowser.browser.commands.CommandDispatcher.tab_give(<qutebrowser.browser.commands.CommandDispatcher>, 1337)
23:08:35 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/utils/objreg.py", line 200, in _get_window_registry
    return win.registry
AttributeError: 'NoneType' object has no attribute 'registry'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/runners.py", line 322, in run_safely
    self.run(text, count)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/runners.py", line 301, in run
    result.cmd.run(self._win_id, args, count=count)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/command.py", line 505, in run
    self.handler(*posargs, **kwargs)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/commands.py", line 559, in tab_give
    window=win_id)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/utils/objreg.py", line 227, in get
    reg = _get_registry(scope, window, tab)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/utils/objreg.py", line 216, in _get_registry
    return _get_window_registry(window)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/utils/objreg.py", line 202, in _get_window_registry
    raise RegistryUnavailableError('window')
```

cc @Enzime 


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
@@ -555,6 +555,10 @@ def tab_give(self, win_id: int = None):
             tabbed_browser = self._new_tabbed_browser(
                 private=self._tabbed_browser.private)
         else:
+            if win_id not in objreg.window_registry:
+                raise cmdexc.CommandError(
+                    "There's no window with id {}!".format(win_id))
+
             tabbed_browser = objreg.get('tabbed-browser', scope='window',
                                         window=win_id)
 


Test patch:
diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature
--- a/tests/end2end/features/tabs.feature
+++ b/tests/end2end/features/tabs.feature
@@ -1058,6 +1058,11 @@ Feature: Tab management
         And I run :tab-give
         Then the error "Cannot detach from a window with only one tab" should be shown
 
+    Scenario: Give a tab to a window ID that does not exist
+        When I open data/hello.txt
+        And I run :tab-give 99
+        Then the error "There's no window with id 99!" should be shown
+
     # Other
 
     Scenario: Using :tab-next after closing last tab (#1448)
Repository: qutebrowser/qutebrowser

Issue:
Deleted C++ object: TabbedBrowser when closing pinned tab
<!-- If this is a bug report, please remember to mention your version info from
`:open qute:version` or `qutebrowser --version` -->

When opening a second window (`:open -w`), pinning a tab (`:tab-pin`), closing it (`:tab-close`), then ignoring the prompt and closing the window, and then answering yes to the prompt (`:prompt-yes`), this happens:

```
09:25:53 ERROR    misc       crashsignal:exception_hook:216 Uncaught exception
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/commands.py", line 219, in _tab_close
    tabbar = self._tabbed_browser.tabBar()
RuntimeError: wrapped C/C++ object of type TabbedBrowser has been deleted
```

The question should probably be aborted when the tab is closed via some other way?

cc @jgkamat 


Discussion:

Resolving patch:
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -259,13 +259,14 @@ def shutdown(self):
     def tab_close_prompt_if_pinned(self, tab, force, yes_action):
         """Helper method for tab_close.
 
-        If tab is pinned, prompt. If everything is good, run yes_action.
+        If tab is pinned, prompt. If not, run yes_action.
+        If tab is destroyed, abort question.
         """
         if tab.data.pinned and not force:
             message.confirm_async(
                 title='Pinned Tab',
                 text="Are you sure you want to close a pinned tab?",
-                yes_action=yes_action, default=False)
+                yes_action=yes_action, default=False, abort_on=[tab.destroyed])
         else:
             yes_action()
 


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Yank value directly from completion menu
Some completion categories (e.g. anything with a url) could benefit from a `yank_cur_item` similar to `delete_cur_item`. Pressing (say) `<ctrl-y>` would place the first column of the selected completion item on the clipboard.



Discussion:
Sounds useful!


Resolving patch:
diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py
--- a/qutebrowser/completion/completionwidget.py
+++ b/qutebrowser/completion/completionwidget.py
@@ -377,3 +377,17 @@ def completion_item_del(self):
         if not index.isValid():
             raise cmdexc.CommandError("No item selected!")
         self.model().delete_cur_item(index)
+
+    @cmdutils.register(instance='completion', hide=True,
+                       modes=[usertypes.KeyMode.command], scope='window')
+    def completion_item_yank(self, sel=False):
+        """Yank the current completion item into the clipboard.
+
+        Args:
+            sel: Use the primary selection instead of the clipboard.
+        """
+        index = self.currentIndex()
+        if not index.isValid():
+            raise cmdexc.CommandError("No item selected!")
+        data = self.model().data(index)
+        utils.set_clipboard(data, selection=sel)


Test patch:
diff --git a/tests/unit/completion/test_completionwidget.py b/tests/unit/completion/test_completionwidget.py
--- a/tests/unit/completion/test_completionwidget.py
+++ b/tests/unit/completion/test_completionwidget.py
@@ -245,6 +245,23 @@ def test_completion_item_del_no_selection(completionview):
     func.assert_not_called()
 
 
+@pytest.mark.parametrize('sel', [True, False])
+def test_completion_item_yank(completionview, mocker, sel):
+    """Test that completion_item_yank invokes delete_cur_item in the model."""
+    m = mocker.patch(
+        'qutebrowser.completion.completionwidget.utils',
+        autospec=True)
+    model = completionmodel.CompletionModel()
+    cat = listcategory.ListCategory('', [('foo', 'bar')])
+    model.add_category(cat)
+
+    completionview.set_model(model)
+    completionview.completion_item_focus('next')
+    completionview.completion_item_yank(sel)
+
+    m.set_clipboard.assert_called_once_with('foo', sel)
+
+
 def test_resize_no_model(completionview, qtbot):
     """Ensure no crash if resizeEvent is triggered with no model (#2854)."""
     completionview.resizeEvent(None)
Repository: qutebrowser/qutebrowser

Issue:
Bigger pinned tabs
Currently pinned tabs only take minimum space and are not evenly spaced like normal tabs are. 
This is a wanted feature.
But it would be nice to have a setting so that pinned tabs have the same size as normal tabs.
To distinguish from normal tabs users can use the tabs.title.format_pinned setting to show different content in the tab title.


Discussion:
cc @jgkamat 

Resolving patch:
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -565,8 +565,12 @@ def tabSizeHint(self, index: int):
             # want to ensure it's valid in this special case.
             return QSize()
         else:
-            pinned = self._tab_pinned(index)
-            pinned_count, pinned_width = self._pinned_statistics()
+            if config.val.tabs.pinned.shrink:
+                pinned = self._tab_pinned(index)
+                pinned_count, pinned_width = self._pinned_statistics()
+            else:
+                pinned = False
+                pinned_count, pinned_width = (0, 0)
             no_pinned_count = self.count() - pinned_count
             no_pinned_width = self.width() - pinned_width
 


Test patch:
Repository: qutebrowser/qutebrowser

Issue:
Add uptime to qute:version output
When debugging #1476 or other time related issues it would be very helpful to have an `:uptime` command which prints how long the current instance has been alive (similar to `M-x emacs-uptime`).




Discussion:
I don't think it makes sense to have a separate command for this - why not simply add it to the `:version` output?

Resolving patch:
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -29,6 +29,7 @@
 import collections
 import enum
 import pkg_resources
+import datetime
 
 import attr
 from PyQt5.QtCore import PYQT_VERSION_STR, QLibraryInfo
@@ -324,6 +325,12 @@ def _backend():
         assert objects.backend == webengine, objects.backend
         return 'QtWebEngine (Chromium {})'.format(_chromium_version())
 
+def _uptime() -> datetime.timedelta:
+    launch_time = QApplication.instance().launch_time
+    time_delta = datetime.datetime.now() - launch_time
+    # Round off microseconds
+    time_delta -= datetime.timedelta(microseconds=time_delta.microseconds)
+    return time_delta
 
 def version():
     """Return a string with various version informations."""
@@ -388,6 +395,11 @@ def version():
     for name, path in sorted(_path_info().items()):
         lines += ['{}: {}'.format(name, path)]
 
+    lines += [
+        '',
+        'Uptime: {}'.format(str(_uptime()))
+    ]
+
     return '\n'.join(lines)
 
 


Test patch:
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -31,6 +31,7 @@
 import logging
 import textwrap
 import pkg_resources
+import datetime
 
 import attr
 import pytest
@@ -870,6 +871,7 @@ def httpUserAgent(self):
                          stubs.FakeQApplication(instance=None)),
         'QLibraryInfo.location': (lambda _loc: 'QT PATH'),
         'sql.version': lambda: 'SQLITE VERSION',
+        '_uptime': lambda: datetime.timedelta(hours=1, minutes=23, seconds=45),
     }
 
     substitutions = {
@@ -913,6 +915,8 @@ def httpUserAgent(self):
     else:
         monkeypatch.delattr(sys, 'frozen', raising=False)
 
+    substitutions['uptime'] = "1:23:45"
+
     template = textwrap.dedent("""
         qutebrowser vVERSION{git_commit}
         Backend: {backend}
@@ -934,6 +938,8 @@ def httpUserAgent(self):
         {osinfo}
         Paths:
         PATH DESC: PATH NAME
+
+        Uptime: {uptime}
     """.lstrip('\n'))
 
     expected = template.rstrip('\n').format(**substitutions)