feat: initial commit
This commit is contained in:
4 files changed
+236
No files matched your search
+27
@@ -0,0 +1,27 @@
|
|||||||
|
image: alpine/edge
|
||||||
|
packages:
|
||||||
|
- git
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
- 88cce185-d2ec-4573-9546-e33f36f79bbf
|
||||||
|
|
||||||
|
environment:
|
||||||
|
# repo and user names on both sr.ht and github
|
||||||
|
REPO: universal-clipboard.nvim
|
||||||
|
USER: swaits
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- fetch-all-branches: |
|
||||||
|
cd "$HOME/$REPO"
|
||||||
|
git fetch origin '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*' --prune
|
||||||
|
|
||||||
|
- get-github-public-key: |
|
||||||
|
ssh-keyscan -t rsa github.com >> "$HOME/.ssh/known_hosts"
|
||||||
|
|
||||||
|
- add-github-remote: |
|
||||||
|
cd "$HOME/$REPO"
|
||||||
|
git remote add github "git@github.com:$USER/$REPO.git"
|
||||||
|
|
||||||
|
- mirror-to-github: |
|
||||||
|
cd "$HOME/$REPO"
|
||||||
|
git push --mirror github
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Stephen Waits <steve@waits.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# universal-clipboard.nvim
|
||||||
|
|
||||||
|
A **minimal** Neovim plugin that automatically sets up sharing your **system
|
||||||
|
clipboard** across multiple platforms. It addresses two common issues:
|
||||||
|
|
||||||
|
1. **Platform Differences**: On macOS, `pbcopy/pbpaste` is native; on Linux,
|
||||||
|
there’s `wl-copy`/`wl-paste` for Wayland or `xclip`/`xsel` for X11.
|
||||||
|
2. **Missing `+clipboard`**: Many distro packages ship Neovim **without**
|
||||||
|
built-in clipboard support.
|
||||||
|
|
||||||
|
With **universal-clipboard.nvim**:
|
||||||
|
|
||||||
|
- If Neovim **has** `+clipboard`, we simply use `unnamedplus`.
|
||||||
|
- If **not**, we detect which clipboard tool (`wl-clipboard`, `xclip`, `xsel`)
|
||||||
|
is available, and configure a fallback automatically.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Using [**packer.nvim**](https://github.com/wbthomason/packer.nvim):
|
||||||
|
|
||||||
|
```lua
|
||||||
|
use({
|
||||||
|
"swaits/universal-clipboard.nvim",
|
||||||
|
config = function()
|
||||||
|
require("universal-clipboard").setup({
|
||||||
|
verbose = false, -- optional, set true to see a small startup message
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Or [**lazy.nvim**](https://github.com/folke/lazy.nvim):
|
||||||
|
|
||||||
|
```lua
|
||||||
|
{
|
||||||
|
"swaits/universal-clipboard.nvim",
|
||||||
|
opts = {
|
||||||
|
verbose = true, -- optional, set true to see a small startup message
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Default Options
|
||||||
|
|
||||||
|
```lua
|
||||||
|
{
|
||||||
|
-- If true, prints the chosen clipboard mode at startup
|
||||||
|
verbose = false,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Once installed, **no additional steps** are needed. The plugin configures your
|
||||||
|
clipboard on startup. Simply copy and paste in Neovim as usual.
|
||||||
|
|
||||||
|
> **Note:** If your Neovim lacks `+clipboard`, make sure you have at least one
|
||||||
|
> of `wl-clipboard`, `xclip`, or `xsel` is installed.
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
- `:UniversalClipboardCheck` - Shows whether Neovim has `+clipboard` and the
|
||||||
|
current fallback configuration, if any.
|
||||||
|
- `:UniversalClipboardReinit` - Re-runs detection. You **do not need to run
|
||||||
|
this.** It's run automatically on startup.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT License](LICENSE)
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
-- lua/universal-clipboard/init.lua
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- 1) Default options
|
||||||
|
local default_opts = {
|
||||||
|
verbose = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- 2) Check if Neovim has '+clipboard'
|
||||||
|
local function has_builtin_clipboard()
|
||||||
|
return vim.fn.has("clipboard") == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 3) Pick copy/paste commands for Wayland or X11 if '+clipboard' is missing
|
||||||
|
local function pick_copy_paste_commands()
|
||||||
|
-- Check Wayland + wl-copy/wl-paste
|
||||||
|
local wayland_display = os.getenv("WAYLAND_DISPLAY")
|
||||||
|
local wayland_runtime = os.getenv("XDG_RUNTIME_DIR")
|
||||||
|
local wayland_socket_path = (wayland_runtime or "") .. "/" .. (wayland_display or "")
|
||||||
|
|
||||||
|
local has_wlcopy = (vim.fn.executable("wl-copy") == 1)
|
||||||
|
local has_wlpaste = (vim.fn.executable("wl-paste") == 1)
|
||||||
|
local have_wayland = wayland_display and wayland_display ~= "" and (vim.fn.isdirectory(wayland_socket_path) == 1)
|
||||||
|
|
||||||
|
if has_wlcopy and has_wlpaste and have_wayland then
|
||||||
|
return {
|
||||||
|
copy = "wl-copy",
|
||||||
|
paste = "wl-paste --no-newline",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise, try xclip
|
||||||
|
if vim.fn.executable("xclip") == 1 then
|
||||||
|
return {
|
||||||
|
copy = "xclip -selection clipboard",
|
||||||
|
paste = "xclip -selection clipboard -o",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise, try xsel
|
||||||
|
if vim.fn.executable("xsel") == 1 then
|
||||||
|
return {
|
||||||
|
copy = "xsel --clipboard --input",
|
||||||
|
paste = "xsel --clipboard --output",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No suitable tool found
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 4) Actually configure Neovim's clipboard usage
|
||||||
|
local function configure_clipboard()
|
||||||
|
if has_builtin_clipboard() then
|
||||||
|
-- Neovim has native +clipboard
|
||||||
|
vim.opt.clipboard = "unnamedplus"
|
||||||
|
return "builtin"
|
||||||
|
else
|
||||||
|
-- Fall back to custom clipboard provider
|
||||||
|
local commands = pick_copy_paste_commands()
|
||||||
|
if commands then
|
||||||
|
vim.g.clipboard = {
|
||||||
|
name = "UniversalClipboard",
|
||||||
|
copy = {
|
||||||
|
["+"] = commands.copy,
|
||||||
|
["*"] = commands.copy,
|
||||||
|
},
|
||||||
|
paste = {
|
||||||
|
["+"] = commands.paste,
|
||||||
|
["*"] = commands.paste,
|
||||||
|
},
|
||||||
|
cache_enabled = 0,
|
||||||
|
}
|
||||||
|
-- Also unify normal yanks/pastes to system clipboard
|
||||||
|
vim.opt.clipboard = "unnamedplus"
|
||||||
|
return "fallback"
|
||||||
|
else
|
||||||
|
-- No tool found
|
||||||
|
vim.notify(
|
||||||
|
"[universal-clipboard.nvim] No suitable clipboard tool found (wl-copy, xclip, xsel).",
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
|
return "none"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 5) Setup function (entry point)
|
||||||
|
function M.setup(user_opts)
|
||||||
|
-- Merge defaults with user_opts
|
||||||
|
local opts = vim.tbl_deep_extend("force", default_opts, user_opts or {})
|
||||||
|
|
||||||
|
local mode = configure_clipboard()
|
||||||
|
if opts.verbose then
|
||||||
|
vim.notify(("[universal-clipboard.nvim] Clipboard mode: %s"):format(mode), vim.log.levels.INFO)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create user commands for debugging / re-init
|
||||||
|
vim.api.nvim_create_user_command("UniversalClipboardCheck", function()
|
||||||
|
if has_builtin_clipboard() then
|
||||||
|
print("Neovim has +clipboard. Current setting:")
|
||||||
|
print(vim.inspect(vim.opt.clipboard:get()))
|
||||||
|
else
|
||||||
|
print("Neovim lacks +clipboard. Using fallback if available.")
|
||||||
|
if vim.g.clipboard then
|
||||||
|
print("Fallback config: " .. vim.inspect(vim.g.clipboard))
|
||||||
|
else
|
||||||
|
print("No fallback is set (no suitable tool found?).")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, {})
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("UniversalClipboardReinit", function()
|
||||||
|
local new_mode = configure_clipboard()
|
||||||
|
print("Reinitialized clipboard mode: " .. new_mode)
|
||||||
|
end, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
Reference in new issue
Block a user