prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Use CommandParser for configmodel.bind
  In the `new-config` branch, there's a `CommandParser` in `commands/runners.py` which got split off from `CommandRunner` and can be used standalone. Various places doing their own command parsing got updated accordingly, but `configmodel.bind` is still doing its own parsing. An example how it's used, from `:bind`:
  
  https://github.com/qutebrowser/qutebrowser/blob/2117824cf9fdc47ea6fd9457c12cecbac117202e/qutebrowser/config/config.py#L179-L189
  
  Split off from #2779, cc @rcorre - if you want to take a look at this, feel free to do a PR against `new-config`, or wait until that's merged and then do one against `master`.
  
  </issue>
  <code>
  [start of qutebrowser/completion/models/configmodel.py]
  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 """Functions that return config-related completion models."""
  21 
  22 from qutebrowser.config import configdata, configexc
  23 from qutebrowser.completion.models import completionmodel, listcategory, util
  24 from qutebrowser.commands import cmdutils
  25 
  26 
  27 def option(*, info):
  28     """A CompletionModel filled with settings and their descriptions."""
  29     model = completionmodel.CompletionModel(column_widths=(20, 70, 10))
  30     options = ((opt.name, opt.description, info.config.get_str(opt.name))
  31                for opt in configdata.DATA.values())
  32     model.add_category(listcategory.ListCategory("Options", sorted(options)))
  33     return model
  34 
  35 
  36 def value(optname, *_values, info):
  37     """A CompletionModel filled with setting values.
  38 
  39     Args:
  40         optname: The name of the config option this model shows.
  41         _values: The values already provided on the command line.
  42         info: A CompletionInfo instance.
  43     """
  44     model = completionmodel.CompletionModel(column_widths=(30, 70, 0))
  45 
  46     try:
  47         current = info.config.get_str(optname) or '""'
  48     except configexc.NoOptionError:
  49         return None
  50 
  51     opt = info.config.get_opt(optname)
  52     default = opt.typ.to_str(opt.default)
  53     cur_cat = listcategory.ListCategory("Current/Default",
  54         [(current, "Current value"), (default, "Default value")])
  55     model.add_category(cur_cat)
  56 
  57     vals = opt.typ.complete()
  58     if vals is not None:
  59         model.add_category(listcategory.ListCategory("Completions",
  60                                                      sorted(vals)))
  61     return model
  62 
  63 
  64 def bind(key, *, info):
  65     """A CompletionModel filled with all bindable commands and descriptions.
  66 
  67     Args:
  68         key: the key being bound.
  69     """
  70     model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
  71     cmd_text = info.keyconf.get_command(key, 'normal')
  72 
  73     if cmd_text:
  74         cmd_name = cmd_text.split(' ')[0]
  75         cmd = cmdutils.cmd_dict.get(cmd_name)
  76         data = [(cmd_text, cmd.desc, key)]
  77         model.add_category(listcategory.ListCategory("Current", data))
  78 
  79     cmdlist = util.get_cmd_completions(info, include_hidden=True,
  80                                        include_aliases=True)
  81     model.add_category(listcategory.ListCategory("Commands", cmdlist))
  82     return model
  83
  [end of qutebrowser/completion/models/configmodel.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/qutebrowser/completion/models/configmodel.py b/qutebrowser/completion/models/configmodel.py
  --- a/qutebrowser/completion/models/configmodel.py
  +++ b/qutebrowser/completion/models/configmodel.py
  @@ -21,7 +21,7 @@
   
   from qutebrowser.config import configdata, configexc
   from qutebrowser.completion.models import completionmodel, listcategory, util
  -from qutebrowser.commands import cmdutils
  +from qutebrowser.commands import runners
   
   
   def option(*, info):
  @@ -71,8 +71,8 @@
       cmd_text = info.keyconf.get_command(key, 'normal')
   
       if cmd_text:
  -        cmd_name = cmd_text.split(' ')[0]
  -        cmd = cmdutils.cmd_dict.get(cmd_name)
  +        parser = runners.CommandParser()
  +        cmd = parser.parse(cmd_text).cmd
           data = [(cmd_text, cmd.desc, key)]
           model.add_category(listcategory.ListCategory("Current", data))
  
verification_info: {"golden_diff": "diff --git a/qutebrowser/completion/models/configmodel.py b/qutebrowser/completion/models/configmodel.py\n--- a/qutebrowser/completion/models/configmodel.py\n+++ b/qutebrowser/completion/models/configmodel.py\n@@ -21,7 +21,7 @@\n \n from qutebrowser.config import configdata, configexc\n from qutebrowser.completion.models import completionmodel, listcategory, util\n-from qutebrowser.commands import cmdutils\n+from qutebrowser.commands import runners\n \n \n def option(*, info):\n@@ -71,8 +71,8 @@\n     cmd_text = info.keyconf.get_command(key, 'normal')\n \n     if cmd_text:\n-        cmd_name = cmd_text.split(' ')[0]\n-        cmd = cmdutils.cmd_dict.get(cmd_name)\n+        parser = runners.CommandParser()\n+        cmd = parser.parse(cmd_text).cmd\n         data = [(cmd_text, cmd.desc, key)]\n         model.add_category(listcategory.ListCategory(\"Current\", data))\n", "issue": "Use CommandParser for configmodel.bind\nIn the `new-config` branch, there's a `CommandParser` in `commands/runners.py` which got split off from `CommandRunner` and can be used standalone. Various places doing their own command parsing got updated accordingly, but `configmodel.bind` is still doing its own parsing. An example how it's used, from `:bind`:\r\n\r\nhttps://github.com/qutebrowser/qutebrowser/blob/2117824cf9fdc47ea6fd9457c12cecbac117202e/qutebrowser/config/config.py#L179-L189\r\n\r\nSplit off from #2779, cc @rcorre - if you want to take a look at this, feel free to do a PR against `new-config`, or wait until that's merged and then do one against `master`.\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\"\"\"Functions that return config-related completion models.\"\"\"\n\nfrom qutebrowser.config import configdata, configexc\nfrom qutebrowser.completion.models import completionmodel, listcategory, util\nfrom qutebrowser.commands import cmdutils\n\n\ndef option(*, info):\n    \"\"\"A CompletionModel filled with settings and their descriptions.\"\"\"\n    model = completionmodel.CompletionModel(column_widths=(20, 70, 10))\n    options = ((opt.name, opt.description, info.config.get_str(opt.name))\n               for opt in configdata.DATA.values())\n    model.add_category(listcategory.ListCategory(\"Options\", sorted(options)))\n    return model\n\n\ndef value(optname, *_values, info):\n    \"\"\"A CompletionModel filled with setting values.\n\n    Args:\n        optname: The name of the config option this model shows.\n        _values: The values already provided on the command line.\n        info: A CompletionInfo instance.\n    \"\"\"\n    model = completionmodel.CompletionModel(column_widths=(30, 70, 0))\n\n    try:\n        current = info.config.get_str(optname) or '\"\"'\n    except configexc.NoOptionError:\n        return None\n\n    opt = info.config.get_opt(optname)\n    default = opt.typ.to_str(opt.default)\n    cur_cat = listcategory.ListCategory(\"Current/Default\",\n        [(current, \"Current value\"), (default, \"Default value\")])\n    model.add_category(cur_cat)\n\n    vals = opt.typ.complete()\n    if vals is not None:\n        model.add_category(listcategory.ListCategory(\"Completions\",\n                                                     sorted(vals)))\n    return model\n\n\ndef bind(key, *, info):\n    \"\"\"A CompletionModel filled with all bindable commands and descriptions.\n\n    Args:\n        key: the key being bound.\n    \"\"\"\n    model = completionmodel.CompletionModel(column_widths=(20, 60, 20))\n    cmd_text = info.keyconf.get_command(key, 'normal')\n\n    if cmd_text:\n        cmd_name = cmd_text.split(' ')[0]\n        cmd = cmdutils.cmd_dict.get(cmd_name)\n        data = [(cmd_text, cmd.desc, key)]\n        model.add_category(listcategory.ListCategory(\"Current\", data))\n\n    cmdlist = util.get_cmd_completions(info, include_hidden=True,\n                                       include_aliases=True)\n    model.add_category(listcategory.ListCategory(\"Commands\", cmdlist))\n    return model\n", "path": "qutebrowser/completion/models/configmodel.py"}]}