{"id":21517553,"url":"https://github.com/tek/helic","last_synced_at":"2025-04-09T21:42:20.596Z","repository":{"id":62436130,"uuid":"439692418","full_name":"tek/helic","owner":"tek","description":"Clipboard synchronization tool","archived":false,"fork":false,"pushed_at":"2025-03-20T22:41:52.000Z","size":244,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-23T23:34:34.835Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tek.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-18T18:56:30.000Z","updated_at":"2025-03-20T22:41:56.000Z","dependencies_parsed_at":"2023-11-25T19:41:03.429Z","dependency_job_id":null,"html_url":"https://github.com/tek/helic","commit_stats":{"total_commits":57,"total_committers":1,"mean_commits":57.0,"dds":0.0,"last_synced_commit":"e26ab7c7f43da54bc74dd40816870cad07c96749"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fhelic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fhelic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fhelic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tek%2Fhelic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tek","download_url":"https://codeload.github.com/tek/helic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248118839,"owners_count":21050746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T00:42:28.570Z","updated_at":"2025-04-09T21:42:20.565Z","avatar_url":"https://github.com/tek.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n\n*Helic* is a tool for synchronizing clipboard contents across *X11*, *tmux* and network, consisting of a daemon\nlistening for changes and a CLI client for use in programs like *Neovim*.\n\n*X11* has three separate copy buffers, called the *clipboard*, the *primary selection* and the *secondary selection*.\nSelections are used when text is selected with the mouse, while the clipboard is updated by `Ctrl-C`.\n\nWhen some text is copied or selected in *X11*, the daemon receives an event that it proceeds to broadcast to the\nconfigured targets.\nIf the source was a selection, the *X11* clipboard is updated as well.\n\nThe CLI program `hel` can be used to manually send text to the daemon, for example from *tmux* or *Neovim*.\nIf remote hosts are configured, each yank event is sent over the network to update their clipboards.\n\nSeveral yank events are stored in memory in order to detect duplicates and cycles.\n\nThe CLI understands four different commands:\n\n|Command|Meaning|\n|---|---|\n|`hel listen`|Start the daemon. This is best done from a *systemd* user service.|\n|`hel yank`|Send standard input or argument to the daemon as a manual yank event.|\n|`hel list`|Print the event history.|\n|`hel load`|Load an older event to the clipboard, given its index into the history.|\n\nThe `list` command will print a table like this:\n\n```\n╭───┬──────────┬───────┬──────────┬──────────────────────────╮\n│ # │ Instance │ Agent │   Time   │         Content          │\n╞═══╪══════════╪═══════╪══════════╪══════════════════════════╡\n│ 2 │   test   │ nvim  │ 12:00:00 │ single line              │\n├───┼──────────┼───────┼──────────┼──────────────────────────┤\n│ 1 │   test   │ nvim  │ 12:00:00 │ single line with newline │\n├───┼──────────┼───────┼──────────┼──────────────────────────┤\n│ 0 │   test   │ nvim  │ 12:00:00 │ three lines 1 [3 lines]  │\n╰───┴──────────┴───────┴──────────┴──────────────────────────╯\n```\n\nThe index in the first column, with 0 being the latest event, can be used with `hel load`.\n\n# Installing and Running Helic\n\n## Nix\n\nThe project uses a [Nix] [flake] to configure its build, and it is recommended to install or run it using *Nix* as well.\nIf *Nix* is installed and configured for use with *flakes*, the app can be run without installation like this:\n\n```shell\n$ nix run github:tek/helic -- listen\n$ echo 'yank me' | nix run github:tek/helic -- yank --agent cli\n$ nix run github:tek/helic -- list 100\n$ nix run github:tek/helic -- load 5\n```\n\n## NixOS\n\nThe flake provides a *NixOS* module that can be used by adding it to `/etc/nixos/flake.nix`:\n\n```nix\n{\n  inputs.helic.url = \"github:tek/helic\";\n  outputs = { nixpkgs, helic, ... }: {\n    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {\n      modules = [helic.nixosModules.default];\n      services.helic.enable = true;\n    };\n  };\n}\n```\n\nWith this, a `systemd` user service will be started on login and the client will be in `$PATH`:\n\n```shell\n$ echo 'yank me' | hel yank\n$ hel yank --agent custom-name --text 'yank me'\n```\n\nAfter a rebuild, the service may not be started right away, so this command must be executed:\n\n```shell\n$ systemctl --user start helic\n```\n\nGlobally enabled `systemd` user services are started for all users on login.\nTo prevent that, you can set the module option `services.helic.user = \"myuser\"`.\n\n## Without Nix\n\nAlternatively, the app can be installed using a *Haskell* package manager, like [Cabal]:\n\n```shell\n$ cabal install helic\n$ hel listen\n```\n\n## CLI\n\nIf no command has been specified explicitly, *Helic* decides which one to start by the presence of stdin data:\n\n```shell\n$ hel # start daemon\n$ echo 'yank me' | hel # yank\n```\n\nGlobal CLI options are specified *before* the command name, command-specific ones after it.\n\n|Command|Name|Description|\n|---|---|---|\n|Global|`--verbose`|Increase the log level.|\n|Global|`--config-file FILE`|Use the specified file path instead of the default locations.|\n|`listen`|`--agent NAME`|Used to avoid sending yanks back to the application that sent them.|\n|`list`|positional (`hel list 5`)|Limit the number of printed events.|\n|`load`|positional (`hel load 5`)|Choose the index of the event to be loaded.|\n|`yank`|`--agent NAME`|Custom name used in the `list` output and to avoid cycles.|\n|`yank`|`--text TEXT`|Yank text, uses stdin if not specified.|\n\n# Configuring Helic\n\nThe app reads the first existing one of these three configuration files:\n\n* The file specified with `--config-file`\n* `$XDG_CONFIG_DIR/helic.yaml` (most likely `~/.config/helic.yaml`)\n* `/etc/helic.yaml`\n\nAn example config file looks like this:\n\n```yaml\nname: myhost\nmaxHistory: 1000\ndebounceMillis: 3000\nverbose: true\nnet:\n  enable: true\n  port: 10001\n  hosts:\n    - \"remote1:1000\"\n    - \"remote2:2000\"\n  timeout: 5\ntmux:\n  enable: true\n  exe: /bin/tmux\nx11:\n  enable: true\n  display: \":0\"\n```\n\nFor *NixOS*, the file `/etc/helic.yaml` is generated from module options:\n\n```nix\n{\n  services.helic = {\n    enable = true;\n    name = \"myhost\";\n    maxHistory = 1000;\n    debounceMillis = 3000;\n    verbose = true;\n    user = \"myuser\";\n    net = {\n      enable = true;\n      port = 10001;\n      hosts = [\"remote1:1000\" \"remote2:2000\"];\n      timeout = 5;\n    };\n    tmux = {\n      enable = true;\n      package = pkgs.tmux;\n    };\n    x11 = {\n      enable = true;\n      display = \":0\";\n    };\n  };\n}\n```\n\nThe meaning of these options is:\n\n|Key|Default|Description|\n|---|---|---|\n|`name`|Host name|An identifier for the host, used for filtering duplicates.|\n|`user`|null|Only for *NixOS*: If set, only start the service for that user.|\n|`maxHistory`|100|The number of yanks that should be kept.|\n|`debounceMillis`|3000|The interval in milliseconds during which the same text is ignored.|\n|`verbose`||Increase the log level.|\n|`net.enable`|`true`|Whether to send events over the network.|\n|`net.port`|`9500`|The HTTP port the daemon listens to for both remote sync and `hel yank`.|\n|`net.hosts`|`[]`|The addresses (with port) of the hosts to which this instance should broadcast yank events.|\n|`net.timeout`|`300`|The timeout in milliseconds for requests to remote hosts.|\n|`tmux.enable`|`true`|Whether to send events to *tmux*.|\n|`tmux.package`|`pkgs.tmux`|Only for *NixOS*: The `nixpkgs` package used for the *tmux* executable.|\n|`tmux.exe`|`tmux`|Only for YAML file: The path to the *tmux* executable|\n|`x11.enable`|`true`|Whether to synchronize the X11 clipboard.|\n|`x11.display`|`:0`|The display identifier used when connecting to the default display via GTK fails.|\n\n# Neovim\n\n*Neovim*'s clipboard requires configuration with a tool in any case, so changing it to use `hel` is simple:\n\n```vim\nlet g:clipboard = {\n  \\   'name': 'helic',\n  \\   'copy': {\n  \\      '+': 'hel yank --agent nvim',\n  \\      '*': 'hel yank --agent nvim',\n  \\    },\n  \\   'paste': {\n  \\      '+': 'xsel -bo',\n  \\      '*': 'xsel -bo',\n  \\   },\n  \\ }\n```\n\nSince *Helic* updates the *X11* clipboard, a custom `paste` command is not necessary.\n\n[Nix]: https://nixos.org/learn.html\n[flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html\n[Cabal]: https://cabal.readthedocs.io\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftek%2Fhelic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftek%2Fhelic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftek%2Fhelic/lists"}