We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
abbrevs should only be expanded at the start of the command
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig

<details>

```
+------------------+---------------------+
| xonsh            | 0.9.18              |
| Git SHA          | 26475146            |
| Commit Date      | May 5 06:42:28 2020 |
| Python           | 3.8.3               |
| PLY              | 3.11                |
| have readline    | True                |
| prompt toolkit   | 3.0.5               |
| shell type       | prompt_toolkit      |
| pygments         | 2.6.1               |
| on posix         | True                |
| on linux         | True                |
| distro           | manjaro             |
| on darwin        | False               |
| on windows       | False               |
| on cygwin        | False               |
| on msys2         | False               |
| is superuser     | False               |
| default encoding | utf-8               |
| xonsh encoding   | utf-8               |
| encoding errors  | surrogateescape     |
+------------------+---------------------+
```

</details>

<!--- Tell us what should happen -->
as of abbrevs expands in all places. So it may clash will subcommands. For example, if we have 

~~`aliases['ps'] = 'procs'`~~
```
abbrevs['ps'] = 'procs'
``` 

and do type `docker ps` then it will get expanded to `docker procs`. 

So the default behaviour should be to expand only at the start of the command. special handling for sudo can be added. 
Also we could have special symbols in aliases to mark it as expandable in all places like `aliases['*ps*']` like the glob pattern. 





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `xontrib/abbrevs.py`
Content:
```
1 """
2 Command abbreviations.
3 
4 This expands input words from `abbrevs` disctionary as you type.
5 Adds ``abbrevs`` dictionary to hold user-defined "command abbreviations.
6 The dictionary is searched as you type the matching words are replaced
7 at the command line by the corresponding dictionary contents once you hit
8 'Space' or 'Return' key.
9 
10 For instance a frequently used command such as ``git status`` can be abbreviated to ``gst`` as follows::
11 
12     $ xontrib load abbrevs
13     $ abbrevs['gst'] = 'git status'
14     $ gst # Once you hit <space> or <return> 'gst' gets expanded to 'git status'.
15 
16 one can set a callback function that receives current buffer and word to customize the expanded word based on context
17 
18 .. code-block:: python
19 
20     $ abbrevs['ps'] = lambda buffer, word: "procs" if buffer.text.startswith(word) else word
21 
22 
23 It is also possible to set the cursor position after expansion with,
24 
25     $ abbrevs['gp'] = "git push <edit> --force"
26 """
27 
28 import builtins
29 import typing as tp
30 
31 from prompt_toolkit.filters import completion_is_selected, IsMultiline
32 from prompt_toolkit.keys import Keys
33 from xonsh.built_ins import DynamicAccessProxy
34 from xonsh.events import events
35 from xonsh.tools import check_for_partial_string
36 
37 __all__ = ()
38 
39 builtins.__xonsh__.abbrevs = dict()
40 proxy = DynamicAccessProxy("abbrevs", "__xonsh__.abbrevs")
41 setattr(builtins, "abbrevs", proxy)
42 
43 
44 class _LastExpanded(tp.NamedTuple):
45     word: str
46     expanded: str
47 
48 
49 last_expanded: tp.Optional[_LastExpanded] = None
50 EDIT_SYMBOL = "<edit>"
51 
52 
53 def get_abbreviated(key: str, buffer) -> str:
54     abbrevs = getattr(builtins, "abbrevs", None)
55     abbr = abbrevs[key]
56     if callable(abbr):
57         text = abbr(buffer=buffer, word=key)
58     else:
59         text = abbr
60     return text
61 
62 
63 def expand_abbrev(buffer) -> bool:
64     """expand the given abbr text. Return true if cursor position changed."""
65     global last_expanded
66     last_expanded = None
67     abbrevs = getattr(builtins, "abbrevs", None)
68     if abbrevs is None:
69         return False
70     document = buffer.document
71     word = document.get_word_before_cursor(WORD=True)
72     if word in abbrevs.keys():
73         partial = document.text[: document.cursor_position]
74         startix, endix, quote = check_for_partial_string(partial)
75         if startix is not None and endix is None:
76             return False
77         buffer.delete_before_cursor(count=len(word))
78         text = get_abbreviated(word, buffer)
79         buffer.insert_text(text)
80         last_expanded = _LastExpanded(word, text)
81         if EDIT_SYMBOL in text:
82             set_cursor_position(buffer, text)
83             return True
84     return False
85 
86 
87 def revert_abbrev(buffer) -> bool:
88     global last_expanded
89     if last_expanded is None:
90         return False
91     document = buffer.document
92     expansion = last_expanded.expanded + " "
93     if not document.text_before_cursor.endswith(expansion):
94         return False
95     buffer.delete_before_cursor(count=len(expansion))
96     buffer.insert_text(last_expanded.word)
97     last_expanded = None
98     return True
99 
100 
101 def set_cursor_position(buffer, expanded: str) -> None:
102     pos = expanded.rfind(EDIT_SYMBOL)
103     if pos == -1:
104         return
105     buffer.cursor_position = buffer.cursor_position - (len(expanded) - pos)
106     buffer.delete(len(EDIT_SYMBOL))
107 
108 
109 @events.on_ptk_create
110 def custom_keybindings(bindings, **kw):
111 
112     from xonsh.ptk_shell.key_bindings import carriage_return
113     from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode
114 
115     handler = bindings.add
116     insert_mode = ViInsertMode() | EmacsInsertMode()
117 
118     @handler(" ", filter=IsMultiline() & insert_mode)
119     def handle_space(event):
120         buffer = event.app.current_buffer
121 
122         add_space = True
123         if not revert_abbrev(buffer):
124             position_changed = expand_abbrev(buffer)
125             if position_changed:
126                 add_space = False
127         if add_space:
128             buffer.insert_text(" ")
129 
130     @handler(
131         Keys.ControlJ, filter=IsMultiline() & insert_mode & ~completion_is_selected
132     )
133     @handler(
134         Keys.ControlM, filter=IsMultiline() & insert_mode & ~completion_is_selected
135     )
136     def multiline_carriage_return(event):
137         buffer = event.app.current_buffer
138         current_char = buffer.document.current_char
139         if not current_char or current_char.isspace():
140             expand_abbrev(buffer)
141         carriage_return(buffer, event.cli)
142
```
--- 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/xontrib/abbrevs.py b/xontrib/abbrevs.py
--- a/xontrib/abbrevs.py
+++ b/xontrib/abbrevs.py
@@ -28,6 +28,7 @@
 import builtins
 import typing as tp
 
+from prompt_toolkit.buffer import Buffer
 from prompt_toolkit.filters import completion_is_selected, IsMultiline
 from prompt_toolkit.keys import Keys
 from xonsh.built_ins import DynamicAccessProxy
@@ -60,7 +61,7 @@
     return text
 
 
-def expand_abbrev(buffer) -> bool:
+def expand_abbrev(buffer: Buffer) -> bool:
     """expand the given abbr text. Return true if cursor position changed."""
     global last_expanded
     last_expanded = None
@@ -74,9 +75,11 @@
         startix, endix, quote = check_for_partial_string(partial)
         if startix is not None and endix is None:
             return False
-        buffer.delete_before_cursor(count=len(word))
         text = get_abbreviated(word, buffer)
+
+        buffer.delete_before_cursor(count=len(word))
         buffer.insert_text(text)
+
         last_expanded = _LastExpanded(word, text)
         if EDIT_SYMBOL in text:
             set_cursor_position(buffer, text)

{"golden_diff": "diff --git a/xontrib/abbrevs.py b/xontrib/abbrevs.py\n--- a/xontrib/abbrevs.py\n+++ b/xontrib/abbrevs.py\n@@ -28,6 +28,7 @@\n import builtins\n import typing as tp\n \n+from prompt_toolkit.buffer import Buffer\n from prompt_toolkit.filters import completion_is_selected, IsMultiline\n from prompt_toolkit.keys import Keys\n from xonsh.built_ins import DynamicAccessProxy\n@@ -60,7 +61,7 @@\n     return text\n \n \n-def expand_abbrev(buffer) -> bool:\n+def expand_abbrev(buffer: Buffer) -> bool:\n     \"\"\"expand the given abbr text. Return true if cursor position changed.\"\"\"\n     global last_expanded\n     last_expanded = None\n@@ -74,9 +75,11 @@\n         startix, endix, quote = check_for_partial_string(partial)\n         if startix is not None and endix is None:\n             return False\n-        buffer.delete_before_cursor(count=len(word))\n         text = get_abbreviated(word, buffer)\n+\n+        buffer.delete_before_cursor(count=len(word))\n         buffer.insert_text(text)\n+\n         last_expanded = _LastExpanded(word, text)\n         if EDIT_SYMBOL in text:\n             set_cursor_position(buffer, text)\n", "issue": "abbrevs should only be expanded at the start of the command\n<!--- Provide a general summary of the issue in the Title above -->\r\n<!--- If you have a question along the lines of \"How do I do this Bash command in xonsh\"\r\nplease first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html\r\nIf you don't find an answer there, please do open an issue! -->\r\n\r\n## xonfig\r\n\r\n<details>\r\n\r\n```\r\n+------------------+---------------------+\r\n| xonsh            | 0.9.18              |\r\n| Git SHA          | 26475146            |\r\n| Commit Date      | May 5 06:42:28 2020 |\r\n| Python           | 3.8.3               |\r\n| PLY              | 3.11                |\r\n| have readline    | True                |\r\n| prompt toolkit   | 3.0.5               |\r\n| shell type       | prompt_toolkit      |\r\n| pygments         | 2.6.1               |\r\n| on posix         | True                |\r\n| on linux         | True                |\r\n| distro           | manjaro             |\r\n| on darwin        | False               |\r\n| on windows       | False               |\r\n| on cygwin        | False               |\r\n| on msys2         | False               |\r\n| is superuser     | False               |\r\n| default encoding | utf-8               |\r\n| xonsh encoding   | utf-8               |\r\n| encoding errors  | surrogateescape     |\r\n+------------------+---------------------+\r\n```\r\n\r\n</details>\r\n\r\n<!--- Tell us what should happen -->\r\nas of abbrevs expands in all places. So it may clash will subcommands. For example, if we have \r\n\r\n~~`aliases['ps'] = 'procs'`~~\r\n```\r\nabbrevs['ps'] = 'procs'\r\n``` \r\n\r\nand do type `docker ps` then it will get expanded to `docker procs`. \r\n\r\nSo the default behaviour should be to expand only at the start of the command. special handling for sudo can be added. \r\nAlso we could have special symbols in aliases to mark it as expandable in all places like `aliases['*ps*']` like the glob pattern. \r\n\r\n\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nCommand abbreviations.\n\nThis expands input words from `abbrevs` disctionary as you type.\nAdds ``abbrevs`` dictionary to hold user-defined \"command abbreviations.\nThe dictionary is searched as you type the matching words are replaced\nat the command line by the corresponding dictionary contents once you hit\n'Space' or 'Return' key.\n\nFor instance a frequently used command such as ``git status`` can be abbreviated to ``gst`` as follows::\n\n    $ xontrib load abbrevs\n    $ abbrevs['gst'] = 'git status'\n    $ gst # Once you hit <space> or <return> 'gst' gets expanded to 'git status'.\n\none can set a callback function that receives current buffer and word to customize the expanded word based on context\n\n.. code-block:: python\n\n    $ abbrevs['ps'] = lambda buffer, word: \"procs\" if buffer.text.startswith(word) else word\n\n\nIt is also possible to set the cursor position after expansion with,\n\n    $ abbrevs['gp'] = \"git push <edit> --force\"\n\"\"\"\n\nimport builtins\nimport typing as tp\n\nfrom prompt_toolkit.filters import completion_is_selected, IsMultiline\nfrom prompt_toolkit.keys import Keys\nfrom xonsh.built_ins import DynamicAccessProxy\nfrom xonsh.events import events\nfrom xonsh.tools import check_for_partial_string\n\n__all__ = ()\n\nbuiltins.__xonsh__.abbrevs = dict()\nproxy = DynamicAccessProxy(\"abbrevs\", \"__xonsh__.abbrevs\")\nsetattr(builtins, \"abbrevs\", proxy)\n\n\nclass _LastExpanded(tp.NamedTuple):\n    word: str\n    expanded: str\n\n\nlast_expanded: tp.Optional[_LastExpanded] = None\nEDIT_SYMBOL = \"<edit>\"\n\n\ndef get_abbreviated(key: str, buffer) -> str:\n    abbrevs = getattr(builtins, \"abbrevs\", None)\n    abbr = abbrevs[key]\n    if callable(abbr):\n        text = abbr(buffer=buffer, word=key)\n    else:\n        text = abbr\n    return text\n\n\ndef expand_abbrev(buffer) -> bool:\n    \"\"\"expand the given abbr text. Return true if cursor position changed.\"\"\"\n    global last_expanded\n    last_expanded = None\n    abbrevs = getattr(builtins, \"abbrevs\", None)\n    if abbrevs is None:\n        return False\n    document = buffer.document\n    word = document.get_word_before_cursor(WORD=True)\n    if word in abbrevs.keys():\n        partial = document.text[: document.cursor_position]\n        startix, endix, quote = check_for_partial_string(partial)\n        if startix is not None and endix is None:\n            return False\n        buffer.delete_before_cursor(count=len(word))\n        text = get_abbreviated(word, buffer)\n        buffer.insert_text(text)\n        last_expanded = _LastExpanded(word, text)\n        if EDIT_SYMBOL in text:\n            set_cursor_position(buffer, text)\n            return True\n    return False\n\n\ndef revert_abbrev(buffer) -> bool:\n    global last_expanded\n    if last_expanded is None:\n        return False\n    document = buffer.document\n    expansion = last_expanded.expanded + \" \"\n    if not document.text_before_cursor.endswith(expansion):\n        return False\n    buffer.delete_before_cursor(count=len(expansion))\n    buffer.insert_text(last_expanded.word)\n    last_expanded = None\n    return True\n\n\ndef set_cursor_position(buffer, expanded: str) -> None:\n    pos = expanded.rfind(EDIT_SYMBOL)\n    if pos == -1:\n        return\n    buffer.cursor_position = buffer.cursor_position - (len(expanded) - pos)\n    buffer.delete(len(EDIT_SYMBOL))\n\n\n@events.on_ptk_create\ndef custom_keybindings(bindings, **kw):\n\n    from xonsh.ptk_shell.key_bindings import carriage_return\n    from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode\n\n    handler = bindings.add\n    insert_mode = ViInsertMode() | EmacsInsertMode()\n\n    @handler(\" \", filter=IsMultiline() & insert_mode)\n    def handle_space(event):\n        buffer = event.app.current_buffer\n\n        add_space = True\n        if not revert_abbrev(buffer):\n            position_changed = expand_abbrev(buffer)\n            if position_changed:\n                add_space = False\n        if add_space:\n            buffer.insert_text(\" \")\n\n    @handler(\n        Keys.ControlJ, filter=IsMultiline() & insert_mode & ~completion_is_selected\n    )\n    @handler(\n        Keys.ControlM, filter=IsMultiline() & insert_mode & ~completion_is_selected\n    )\n    def multiline_carriage_return(event):\n        buffer = event.app.current_buffer\n        current_char = buffer.document.current_char\n        if not current_char or current_char.isspace():\n            expand_abbrev(buffer)\n        carriage_return(buffer, event.cli)\n", "path": "xontrib/abbrevs.py"}], "after_files": [{"content": "\"\"\"\nCommand abbreviations.\n\nThis expands input words from `abbrevs` disctionary as you type.\nAdds ``abbrevs`` dictionary to hold user-defined \"command abbreviations.\nThe dictionary is searched as you type the matching words are replaced\nat the command line by the corresponding dictionary contents once you hit\n'Space' or 'Return' key.\n\nFor instance a frequently used command such as ``git status`` can be abbreviated to ``gst`` as follows::\n\n    $ xontrib load abbrevs\n    $ abbrevs['gst'] = 'git status'\n    $ gst # Once you hit <space> or <return> 'gst' gets expanded to 'git status'.\n\none can set a callback function that receives current buffer and word to customize the expanded word based on context\n\n.. code-block:: python\n\n    $ abbrevs['ps'] = lambda buffer, word: \"procs\" if buffer.text.startswith(word) else word\n\n\nIt is also possible to set the cursor position after expansion with,\n\n    $ abbrevs['gp'] = \"git push <edit> --force\"\n\"\"\"\n\nimport builtins\nimport typing as tp\n\nfrom prompt_toolkit.buffer import Buffer\nfrom prompt_toolkit.filters import completion_is_selected, IsMultiline\nfrom prompt_toolkit.keys import Keys\nfrom xonsh.built_ins import DynamicAccessProxy\nfrom xonsh.events import events\nfrom xonsh.tools import check_for_partial_string\n\n__all__ = ()\n\nbuiltins.__xonsh__.abbrevs = dict()\nproxy = DynamicAccessProxy(\"abbrevs\", \"__xonsh__.abbrevs\")\nsetattr(builtins, \"abbrevs\", proxy)\n\n\nclass _LastExpanded(tp.NamedTuple):\n    word: str\n    expanded: str\n\n\nlast_expanded: tp.Optional[_LastExpanded] = None\nEDIT_SYMBOL = \"<edit>\"\n\n\ndef get_abbreviated(key: str, buffer) -> str:\n    abbrevs = getattr(builtins, \"abbrevs\", None)\n    abbr = abbrevs[key]\n    if callable(abbr):\n        text = abbr(buffer=buffer, word=key)\n    else:\n        text = abbr\n    return text\n\n\ndef expand_abbrev(buffer: Buffer) -> bool:\n    \"\"\"expand the given abbr text. Return true if cursor position changed.\"\"\"\n    global last_expanded\n    last_expanded = None\n    abbrevs = getattr(builtins, \"abbrevs\", None)\n    if abbrevs is None:\n        return False\n    document = buffer.document\n    word = document.get_word_before_cursor(WORD=True)\n    if word in abbrevs.keys():\n        partial = document.text[: document.cursor_position]\n        startix, endix, quote = check_for_partial_string(partial)\n        if startix is not None and endix is None:\n            return False\n        text = get_abbreviated(word, buffer)\n\n        buffer.delete_before_cursor(count=len(word))\n        buffer.insert_text(text)\n\n        last_expanded = _LastExpanded(word, text)\n        if EDIT_SYMBOL in text:\n            set_cursor_position(buffer, text)\n            return True\n    return False\n\n\ndef revert_abbrev(buffer) -> bool:\n    global last_expanded\n    if last_expanded is None:\n        return False\n    document = buffer.document\n    expansion = last_expanded.expanded + \" \"\n    if not document.text_before_cursor.endswith(expansion):\n        return False\n    buffer.delete_before_cursor(count=len(expansion))\n    buffer.insert_text(last_expanded.word)\n    last_expanded = None\n    return True\n\n\ndef set_cursor_position(buffer, expanded: str) -> None:\n    pos = expanded.rfind(EDIT_SYMBOL)\n    if pos == -1:\n        return\n    buffer.cursor_position = buffer.cursor_position - (len(expanded) - pos)\n    buffer.delete(len(EDIT_SYMBOL))\n\n\n@events.on_ptk_create\ndef custom_keybindings(bindings, **kw):\n\n    from xonsh.ptk_shell.key_bindings import carriage_return\n    from prompt_toolkit.filters import EmacsInsertMode, ViInsertMode\n\n    handler = bindings.add\n    insert_mode = ViInsertMode() | EmacsInsertMode()\n\n    @handler(\" \", filter=IsMultiline() & insert_mode)\n    def handle_space(event):\n        buffer = event.app.current_buffer\n\n        add_space = True\n        if not revert_abbrev(buffer):\n            position_changed = expand_abbrev(buffer)\n            if position_changed:\n                add_space = False\n        if add_space:\n            buffer.insert_text(\" \")\n\n    @handler(\n        Keys.ControlJ, filter=IsMultiline() & insert_mode & ~completion_is_selected\n    )\n    @handler(\n        Keys.ControlM, filter=IsMultiline() & insert_mode & ~completion_is_selected\n    )\n    def multiline_carriage_return(event):\n        buffer = event.app.current_buffer\n        current_char = buffer.document.current_char\n        if not current_char or current_char.isspace():\n            expand_abbrev(buffer)\n        carriage_return(buffer, event.cli)\n", "path": "xontrib/abbrevs.py"}]}