|
Conflict handling Interactive prompt with backup, skip, overwrite, and diff options when files already exist. |
Orphan cleanup
|
|
Stow-compatible Works with existing GNU Stow symlinks. Supports tree folding for cleaner directory structures. |
Relative symlinks Portable across machines. Symlinks use relative paths, not absolute. |
Downloads a self-contained binary with no dependencies:
curl -fsSL https://raw.githubusercontent.com/Owloops/lnko/main/install.sh | bashInstalls as a Lua module (requires Lua and LuaFileSystem):
luarocks --local install lnko# Link packages from current directory to $HOME
lnko link bash git nvim
# Specify source and target directories
lnko link -d ~/dotfiles/config -t ~ bash git nvim
# Unlink packages
lnko unlink bash
# Show status of all packages
lnko status
# Remove orphan symlinks
lnko cleanOptions are scoped per command (--backup applies to link, --json to status, etc.). Run lnko <command> --help to see the exact set. Unknown options are rejected with a suggestion.
| Option | Commands | Description |
|---|---|---|
-d, --dir <dir> |
all | Source directory containing packages (default: cwd) |
-t, --target <dir> |
all | Target directory (default: $HOME) |
-n, --dry-run |
link, unlink, clean | Show what would be done |
-v, --verbose |
all | Show debug output |
-b, --backup |
link | Auto-backup conflicts to <target>/.lnko-backup/ |
-s, --skip |
link | Auto-skip conflicts |
-f, --force |
link | Auto-overwrite conflicts (dangerous) |
--ignore <glob> |
link | Ignore files matching glob (can be repeated; use / for path-scoped globs, basename otherwise) |
--no-folding |
link | Don't fold directories into symlinks |
--json |
status | Output JSON |
--remove-orphans |
clean | Auto-remove orphan symlinks |
--keep-orphans |
clean | Auto-keep orphan symlinks |
-h, --help |
all | Show help |
--version |
all | Show version |
An optional .lnkorc in the source directory provides defaults so you don't repeat flags. It's a Lua file returning a table:
return {
dir = "~/dotfiles/config",
target = "~",
ignore = { ".git", "*.swp" },
packages = os.getenv("TERMUX_VERSION")
and { "bash", "git", "termux", "nvim" }
or { "bash", "git", "fedora", "nvim", "tmux" },
}- Keys map to options:
dir,target,ignore,no_folding, andpackages(defaults for a barelnko link). - Explicit command-line flags always win over config values.
- The file is executable Lua, so per-host logic (like the
TERMUX_VERSIONcheck above) lives in the config, not in lnko. - Override the location with
--config <file>or theLNKO_CONFIGenvironment variable.
When lnko encounters existing files, it prompts for action:
- [b]ackup - Move existing file to
.lnko-backup/ - [s]kip - Leave existing file, skip this link
- [o]verwrite - Replace existing file
- [d]iff - Show diff between source and target
- [q]uit - Abort operation
Use -b, -s, or -f flags to auto-resolve conflicts.
lnko status classifies each package into one state:
| Status | Meaning |
|---|---|
ok |
every package path is linked |
partial |
some paths linked, some missing |
occupied |
no paths linked here; existing symlinks are owned by sibling packages from the same source dir |
not linked |
nothing linked and targets missing |
conflict |
a path is a real file or a symlink pointing outside the source dir |
Multi-host setups typically show host packages (e.g. fedora, termux) as occupied on other machines.
Use lnko status --json for machine-readable output:
[{"package":"termux","status":"occupied","total":2,"linked":0,"missing":0,"occupied":2,"conflict":0}]lnko creates relative symlinks from a source directory (containing "packages") to a target directory. Each package is a directory whose contents mirror the target structure.
dotfiles/
bash/
.bashrc
.bash_profile
git/
.gitconfig
Running lnko link -d dotfiles -t ~ bash git creates:
~/.bashrc -> ../dotfiles/bash/.bashrc
~/.bash_profile -> ../dotfiles/bash/.bash_profile
~/.gitconfig -> ../dotfiles/git/.gitconfig
See papungag/dotfiles for a real-world example using lnko.
Both use relative symlinks, tree folding, ignore patterns, and dry-run mode. lnko adds:
| Feature | Description |
|---|---|
| Interactive conflicts | Prompt with backup, skip, overwrite, diff |
| Orphan cleanup | Find and remove broken symlinks |
| Status command | See state of all packages |
See GNU Stow documentation for additional Stow features.
# Run from source
./bin/lnko.lua --help
# Run linter
luacheck lnko/ bin/ spec/
# Run tests
busted spec/