Repository: xonsh/xonsh

Issue:
AttributeError: '_MergedKeyBindings' object has no attribute 'add'
<!--- 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.21               |
| Git SHA          | 95b3872c             |
| Commit Date      | Sep 12 04:57:08 2020 |
| Python           | 3.8.5                |
| PLY              | 3.11                 |
| have readline    | True                 |
| prompt toolkit   | 3.0.7                |
| 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>


## Current Behavior
this happens on the master branch when xontrib uses `bindings.add `

### Traceback (if applicable)

<details>

```
Traceback (most recent call last):
  File "/home/noor/.config/xonsh/xonsh/xonsh/events.py", line 248, in _call
    handler(**self._kwargs)
  File "/home/noor/.config/xonsh/.venv/lib/python3.8/site-packages/xontrib/hist_navigator.xsh", line 72, in custom_keybindings
    handler = bindings.add
AttributeError: '_MergedKeyBindings' object has no attribute 'add'
Exception raised in event handler; ignored.
Traceback (most recent call last):
  File "/home/noor/.config/xonsh/xonsh/xonsh/events.py", line 248, in _call
    handler(**self._kwargs)
  File "/home/noor/.config/xonsh/xonsh/xontrib/abbrevs.py", line 80, in custom_keybindings
    handler = bindings.add
AttributeError: '_MergedKeyBindings' object has no attribute 'add'
Exception raised in event handler; ignored.
Traceback (most recent call last):
  File "/home/noor/.config/xonsh/xonsh/xonsh/events.py", line 248, in _call
    handler(**self._kwargs)
  File "/home/noor/.config/xonsh/user_xsh/evnt_hooks/keybindings/bindings.py", line 23, in custom_keybindings
    handler = bindings.add
AttributeError: '_MergedKeyBindings' object has no attribute 'add'
Exception raised in event handler; ignored.
```

</details>

## Steps to Reproduce
- install xonsh from latest master branch
- enable a xontrib
```sh
xontrib load abbrevs
```

## For community
⬇️  **Please click the 👍 reaction instead of leaving a `+1` or 👍  comment**



Discussion:
ah dang! i bet this is fallout from this diff https://github.com/xonsh/xonsh/pull/3697 -- i can fix, thanks!

Resolving patch:
diff --git a/xonsh-in-docker.py b/xonsh-in-docker.py
--- a/xonsh-in-docker.py
+++ b/xonsh-in-docker.py
@@ -11,7 +11,7 @@
 parser.add_argument("env", nargs="*", default=[], metavar="ENV=value")
 parser.add_argument("--python", "-p", default="3.6", metavar="python_version")
 parser.add_argument("--pypy", default=None, metavar="pypy_version")
-parser.add_argument("--ptk", "-t", default="2.0.4", metavar="ptk_version")
+parser.add_argument("--ptk", "-t", default="3.0.7", metavar="ptk_version")
 parser.add_argument("--keep", action="store_true")
 parser.add_argument("--build", action="store_true")
 parser.add_argument("--command", "-c", default="xonsh", metavar="command")
@@ -30,7 +30,9 @@
 ADD ./ ./
 RUN python setup.py install
 """.format(
-    python_version=args.python, ptk_version=args.ptk, pytest="pytest" if args.pytest else ""
+    python_version=args.python,
+    ptk_version=args.ptk,
+    pytest="pytest" if args.pytest else "",
 )
 
 if args.pypy:
@@ -46,7 +48,9 @@
 ADD ./ ./
 RUN pypy3 setup.py install
     """.format(
-        python_version=args.pypy, ptk_version=args.ptk, pytest="pytest" if args.pytest else ""
+        python_version=args.pypy,
+        ptk_version=args.ptk,
+        pytest="pytest" if args.pytest else "",
     )
 
 print("Building and running Xonsh")
diff --git a/xonsh/ptk_shell/shell.py b/xonsh/ptk_shell/shell.py
--- a/xonsh/ptk_shell/shell.py
+++ b/xonsh/ptk_shell/shell.py
@@ -94,9 +94,7 @@ def __init__(self, **kwargs):
         self.history = ThreadedHistory(PromptToolkitHistory())
         self.prompter = PromptSession(history=self.history)
         self.pt_completer = PromptToolkitCompleter(self.completer, self.ctx, self)
-        self.key_bindings = merge_key_bindings(
-            [load_xonsh_bindings(), load_emacs_shift_selection_bindings()]
-        )
+        self.key_bindings = load_xonsh_bindings()
 
         # Store original `_history_matches` in case we need to restore it
         self._history_matches_orig = self.prompter.default_buffer._history_matches
@@ -107,6 +105,11 @@ def __init__(self, **kwargs):
             completer=self.pt_completer,
             bindings=self.key_bindings,
         )
+        # Goes at the end, since _MergedKeyBindings objects do not have
+        # an add() function, which is necessary for on_ptk_create events
+        self.key_bindings = merge_key_bindings(
+            [self.key_bindings, load_emacs_shift_selection_bindings()]
+        )
 
     def singleline(
         self, auto_suggest=None, enable_history_search=True, multiline=True, **kwargs


Test patch: