Skip to content

Commit

Permalink
Add clipboard provider configuration (#8826)
Browse files Browse the repository at this point in the history
This change adds the `clipboard-provider` setting to the `editor` section
of configuration.

This option can have values of:
- `none`
(on windows only)
- `windows` (use native windows clipboard)
- `pasteboard` (use pbcopy/pbpaste)
(on neiter of the above)
- `wayland`
- `x-clip`
- `x-sel`
- `win-32-yank` (for wsl)
- `termux`
- `tmux`
(on all targets with "term")
- `termcode` (osc codes)
- `custom` (see below for the configuration)

Note for a custom provider the configurations should look like:
```toml
[editor.clipboard-provider.custom]
yank = { command = "cat",  args = ["test.txt"] }
paste = { command = "tee",  args = ["test.txt"] }
primary-yank = { command = "cat",  args = ["test-primary.txt"] } # optional
primary-paste = { command = "tee",  args = ["test-primary.txt"] } # optional
```

This can be configured at runtime with the usual:
```
set clipboard-provider term
```
Note: I was unable to work out a syntax expression for setting a `custom`
provider at runtime. In my opinion this is probably a fine limitation to
have but I am curious if there is a correct way I couldn't work out.

This ports over the previous provider selection logic so hopefully the
same default behaviour should apply.

I updated the health command to reflect the provider.
Note: this required reading the user configurations within the health command
which warrants discussion as this seems to not have been done before.

This is my first contribution, I am a C++ developer by profession and
a rust hobyist at best so nits and style updates very welcome.
  • Loading branch information
AlfGalf committed Oct 13, 2024
1 parent 6309cc7 commit 16368b7
Show file tree
Hide file tree
Showing 7 changed files with 488 additions and 358 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions book/src/editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
| `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable"
| `clipboard-provider` | Which API to use for clipboard interaction. One of `pasteboard` (MacOS), `wayland`, `x-clip`, `x-sel`, `win-32-yank`, `termux`, `tmux`, `windows`, `termcode`, `none`, or a custom command set. | Platform and environment specific. |

### `[editor.clipboard-provider]` Section

Helix can be configured wither to use a builtin clipboard configuration or to use
a provided command.

For instance, setting it to use OSC 52 termcodes, the configuration would be:
```toml
[editor]
clipboard-provider = "termcode"
```

Alternatively, Helix can be configured to use arbitary commands for clipboard integration:

```toml
[editor.clipboard-provider.custom]
yank = { command = "cat", args = ["test.txt"] }
paste = { command = "tee", args = ["test.txt"] }
primary-yank = { command = "cat", args = ["test-primary.txt"] } # optional
primary-paste = { command = "tee", args = ["test-primary.txt"] } # optional
```

For custom commands the contents of the yank/paste is communicated over stdin/stdout.

### `[editor.statusline]` Section

Expand Down
1 change: 1 addition & 0 deletions helix-stdx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ homepage.workspace = true
dunce = "1.0"
etcetera = "0.8"
ropey = { version = "1.6.1", default-features = false }
serde = { version = "1.0" }
which = "6.0"
regex-cursor = "0.1.4"
bitflags = "2.6"
Expand Down
19 changes: 14 additions & 5 deletions helix-term/src/health.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::config::{Config, ConfigLoadError};
use crossterm::{
style::{Color, Print, Stylize},
tty::IsTty,
};
use helix_core::config::{default_lang_config, user_lang_config};
use helix_loader::grammar::load_runtime_file;
use helix_view::clipboard::get_clipboard_provider;
use std::io::Write;

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -53,7 +53,6 @@ pub fn general() -> std::io::Result<()> {
let lang_file = helix_loader::lang_config_file();
let log_file = helix_loader::log_file();
let rt_dirs = helix_loader::runtime_dirs();
let clipboard_provider = get_clipboard_provider();

if config_file.exists() {
writeln!(stdout, "Config file: {}", config_file.display())?;
Expand Down Expand Up @@ -92,7 +91,6 @@ pub fn general() -> std::io::Result<()> {
writeln!(stdout, "{}", msg.yellow())?;
}
}
writeln!(stdout, "Clipboard provider: {}", clipboard_provider.name())?;

Ok(())
}
Expand All @@ -101,8 +99,19 @@ pub fn clipboard() -> std::io::Result<()> {
let stdout = std::io::stdout();
let mut stdout = stdout.lock();

let board = get_clipboard_provider();
match board.name().as_ref() {
let config = match Config::load_default() {
Ok(config) => config,
Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {
Config::default()
}
Err(err) => {
writeln!(stdout, "{}", "Configuration file malformed".red())?;
writeln!(stdout, "{}", err)?;
return Ok(());
}
};

match config.editor.clipboard_provider.name().as_ref() {
"none" => {
writeln!(
stdout,
Expand Down
Loading

0 comments on commit 16368b7

Please sign in to comment.