Repository: alacritty/alacritty (language: rust)

Issue:
toml bindings documentation not possible to understand 
I'm trying to configure mouse and keyboard binds in the new toml format. I have converted it using `alacritty migrate` from my yml config from before, but it creates a separate heading for every single key bind and this is not practical. 

In reviewing the docs, 

```
Example: [keyboard]++ bindings = [++ { key = "N", mods = "Control|Shift", action = "CreateNewWindow" },++ { key = "L", mods = "Control|Shift", chars = "l" },++ ]
```

```
See _keyboard.bindings_ for full documentation on _mods_, _mode_, _action_,
and _chars_.

When an application running within Alacritty captures the mouse, the `Shift`
modifier can be used to suppress mouse reporting. If no action is found for
the event, actions for the event without the `Shift` modifier are triggered
instead.

*mouse* = _"Middle"_ | _"Left"_ | _"Right"_ | _"Back"_ | _"Forward"_ | _<integer>_

	Mouse button which needs to be pressed to trigger this binding.

*action* = *<keyboard.bindings.action>* | _"ExpandSelection"_

	*ExpandSelection*
		Expand the selection to the current mouse cursor location.

Example:
	*[mouse]*++
```

I wish I had something more helpful or specific to say but honestly none of this documentation really makes any sense. All the components we're used to seeing before are here but it's shocking to find lacking here a concrete example, only abstract symbolic examples. In particular it is not understood what `++` means. 

My simple attempt to bind mouse buttons results in failure: 

```
[mouse]
hide_when_typing = true
bindings = [ { mouse = "Middle", action = "PasteSelection" }, { mouse = "Back", chars = "abc" } ]
```

from logfile:
```
[13.304506648s] [ERROR] [alacritty_config_derive] Config error: duplicate field `mouse`
                                                  ; ignoring binding
```


Discussion / hints:
It's a manpage, render it if you can't understand the raw markup.

It's also not even released yet.
>All the components we're used to seeing before are here but it's shocking to find lacking here a concrete example, only abstract symbolic examples

![image](https://github.com/alacritty/alacritty/assets/27620401/77c88585-c1e9-41bd-937d-ca98057e7c54)

I think this is kind of clear? The keyboard one was also clear.

>My simple attempt to bind mouse buttons results in failure:

That actually looks correct.

btw, you found like a 4 years old bug, since `chars` doesn't work with `mouse` and it was like that for a while.

See #7414.
Thank you, I am glad to learn that I did interpret the document right and thank you for restoring a not insignificant amount of my sanity. 

I found the instructions to build the manpage and install it. I hope sometime there can be a single command that takes care of installing that. 

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58d0a70e269..238769ca2a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -74,6 +74,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Vi cursor position not redrawn on PageUp/PageDown without scrollback
 - Cursor not updating when blinking and viewport is scrolled
 - Failure to start with recent version of mesa's i915 driver
+- Error when using `chars` inside the mouse bindings
 
 ### Removed
 
diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs
index a84e967a6d8..d836c5e69c7 100644
--- a/alacritty/src/config/bindings.rs
+++ b/alacritty/src/config/bindings.rs
@@ -899,7 +899,7 @@ impl<'a> Deserialize<'a> for MouseButtonWrapper {
             type Value = MouseButtonWrapper;
 
             fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                f.write_str("Left, Right, Middle, or a number from 0 to 65536")
+                f.write_str("Left, Right, Middle, Back, Forward, or a number from 0 to 65536")
             }
 
             fn visit_u64<E>(self, value: u64) -> Result<MouseButtonWrapper, E>
@@ -920,6 +920,8 @@ impl<'a> Deserialize<'a> for MouseButtonWrapper {
                     "Left" => Ok(MouseButtonWrapper(MouseButton::Left)),
                     "Right" => Ok(MouseButtonWrapper(MouseButton::Right)),
                     "Middle" => Ok(MouseButtonWrapper(MouseButton::Middle)),
+                    "Back" => Ok(MouseButtonWrapper(MouseButton::Back)),
+                    "Forward" => Ok(MouseButtonWrapper(MouseButton::Forward)),
                     _ => Err(E::invalid_value(Unexpected::Str(value), &self)),
                 }
             }
@@ -1134,7 +1136,7 @@ impl<'a> Deserialize<'a> for RawBinding {
                             chars = Some(map.next_value()?);
                         },
                         Field::Mouse => {
-                            if chars.is_some() {
+                            if mouse.is_some() {
                                 return Err(<V::Error as Error>::duplicate_field("mouse"));
                             }
 


Test patch: