Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime configuration of clipboard providers #1827

Closed
wants to merge 4 commits into from

Conversation

The0x539
Copy link
Contributor

Commit adf97e0 is mostly reasonable, but as a WSL user, it broke my workflow. The win32yank provider does work on WSL, and it's great.

Rather than simply revert the changes (or specifically the removal of win32yank on Linux), I took the opportunity to make the system more flexible. The majority of providers are already command-based, which really shouldn't require the whole WASM plugin system, hence this implementation. All of Neovim's presets are available, and the user can specify in config.toml which ones should be tried and in what order, as well as defining their own.

Comment on lines +94 to +101
#[cfg(unix)]
"wl-clipboard" {
copy: "wl-copy", "--type", "text/plain";
paste: "wl-paste", "--no-newline";
primary_copy: "wl-copy", "-p", "--type", "text/plain";
primary_paste: "wl-paste", "-p", "--no-newline";
env: "WAYLAND_DISPLAY";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need a macro for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, there was a macro before, and it didn't reduce boilerplate by nearly as much as these two macros.
This approach handles:

  • Converting every argument into a String so that the presets can coexist with deserialized config data.
  • Building a map of providers, for by-name lookup.
  • Building a list based on order of appearance, for specifying precedence.
  • Implicit defaults for env, primary, and test, which are each relatively rare among the presets.

Comment on lines +188 to +197
macro_rules! check {
($cond:expr) => {
if !$cond {
return false;
}
};
}

check!(!self.copy.is_empty() && exists(&self.copy[0]));
check!(!self.paste.is_empty() && exists(&self.paste[0]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this macro is unnecessary, it's just a couple of lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally follow the rule of three for avoiding repetitive code. This is five (or four, without test_commands), and I'm not a fan of how it looks without the macro:

pub fn is_available(&self) -> bool {
    if !self.copy.is_empty() && !exists(&self.copy[0]) {
        return false;
    }
    if !self.paste.is_empty() && !exists(&self.paste[0]) {
        return false;
    }

    if let Some(copy) = &self.primary_copy {
        if !copy.is_empty() && !exists(&copy[0]) {
            return false;
        }
    }
    if let Some(paste) = &self.primary_paste {
        if !paste.is_empty() && !exists(&paste[0]) {
            return false;
        }
    }
    for var in &self.env_vars {
        if !env_var_is_set(var) {
            return false;
        }
    }
    for cmd in &self.test_commands {
        // FIXME: check performance of is_exit_success
        if !cmd.is_empty() && !is_exit_success(&cmd[0], &cmd[1..]) {
            return false;
        }
    }

    true
}

@archseer
Copy link
Member

and the user can specify in config.toml which ones should be tried and in what order, as well as defining their own.

I think this is a bit of overkill. We either want to automatically detect a suitable provider and use it, or we want the user to manually specify clipboard = { paste = { cmd = "foo", args = ["bar"] } } that overrides.

Comment on lines +133 to +137
#[cfg(any(windows, target_os = "linux"))] // this is a godsend on WSL
"win32yank" {
copy: "win32yank.exe", "-i";
paste: "win32yank.exe", "-o";
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at what the code was before, you want to always use the WindowsProvider on windows, and win32yank on linux which will cover WSL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, my particular use case doesn't need anything other than clipboard-win on cfg(windows), but I believe the lemonade client also works on Windows.

@The0x539
Copy link
Contributor Author

I think this is a bit of overkill. We either want to automatically detect a suitable provider and use it, or we want the user to manually specify clipboard = { paste = { cmd = "foo", args = ["bar"] } } that overrides.

This approach makes it easier to have a single portable configuration. I personally use helix primarily in two Linux environments, one of which should use wl-clipboard and one of which should use win32yank. Both of those happen to be available as presets, but I don't want to discount the possibility of other providers that aren't. "Detection xor choice", either as a program decision or as a design decision, would interfere with such a use case, and detection shouldn't be limited to hardcoded presets.
Sure, adding a detection is an easy change to make, but then you're either forgoing your package manager to build from source or waiting for a contribution to get merged and make it into a versioned release.

@pickfire
Copy link
Contributor

This approach makes it easier to have a single portable configuration. I personally use helix primarily in two Linux environments, one of which should use wl-clipboard and one of which should use win32yank

The auto-detection ideally should cover all these cases, the user should only override it to a single specific config. In your case, if the auto-detection is done correctly then it should work without manual config, ideally we don't want users to do any config for this.

@the-mikedavis the-mikedavis added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label May 18, 2022
@kirawi kirawi added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. A-helix-term Area: Helix term improvements and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 13, 2022
@pascalkuthe
Copy link
Member

clsoing this one out as stale. We would still like to add the ability to do this but this has siginificant conflicts and open review comments so it makes more sense to start over with a new PR if somebody wants to pick this up. Thank you for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants