A dotfile manager for configs applied on different operating systems simultaneously. Write Lua scripts to decide where your stuff is being linked to
Say I want to link Vieb configuration:
~/Repos/dotfiles/
├── .dotune.lua # <-- linking script
└── web/ # <-- dotfiles source
└── vieb/
├── .viebrc
└── colors/...-- Check if Vieb is installed (if you want)
if not (Windows.roaming_app_data / 'Vieb'):exists() then
return
end
-- Use `Path` primitive instead of strings
local src = Path.here / 'web/vieb'
Dot.link(src / 'colors', Path.home / '.vieb/colors')
-- ^ symlink ~/Repos/dotfiles/web/vieb/colors -> ~/.vieb/colors
Dot.link((src / '.viebrc'):to(Path.home))
-- ^ symlink ~/Repos/dotfiles/web/vieb/.viebrc -> ~/.viebrc
-- Use `include` to run configs in child folders (like require, but relative)
include 'web/qutebrowser' -- https://github.com/qutebrowser/qutebrowser# Execute the script
dotune ~/Repos/dotfilesdotune --help # Show usage and options
dotune # Apply .dotune.lua in the current directory
dotune <dir> # Use another repository folder
dotune --dry-run # Don't apply write operations to the file system
dotune --version # Print version
# Pass parameters to scripts with -p / --param NAME=VALUE (repeat for multiple pairs)
dotune --param <key>=<value> <dir>Lua scripts have access to very basic parts of standard library: print, string, table and utf8. More complicated stuff like file I/O and environment access are disabled
include 'shell' -- Run shell/.dotune.lua relative to the current script
include 'web/vieb' -- Nested paths are allowed; absolute paths, . and .. are notlocal target = Input.param('target', 'path') -- Path. May not exist
local profile = Input.param('profile', 'string') -- string. May be empty
Dot.link(Path.here / profile / 'config', target / '.config')-- Create a symlink to a file or directory, creating missing parent directories.
-- Sources must be inside the repository; destinations must be outside it.
-- Replaces existing symlinks; errors if a regular file or directory exists.
Dot.link(Path.here / 'config', XDG.config / 'myapp')-- Copy a file or directory, creating missing parent directories.
-- Sources must be inside the repository; destinations must be outside it.
-- Directories are merged, matching files are overwritten, extra files are kept.
Dot.copy(Path.here / 'defaults', XDG.config / 'otherapp')local config = Path.here / 'config.toml' -- Join; same as Path.here:join('config.toml')
Dot.link(config:to(XDG.config)) -- Passes source and destination, keeping the filename
Dot.link(config, XDG.config / 'app.toml') -- Choose a different destination name
local renamed = config % 'app.toml' -- Replace filename; :with_tail('app.toml')
local backup = config * 'bak' -- Replace extension; :with_extension('bak')
local parent = config.parent -- Parent path, or nil at the filesystem root
local exists = config:exists() -- Whether the path exists
local resolved = config:resolve() -- Absolute path with symlinks resolved, or nil on failure
local text = tostring(config) -- Convert a Path to a string
local binary = Path.which('vieb') -- Find an executable on PATH, or return nil
local home = Path.home -- User's home directory
local here = Path.here -- Current script's directory; alias of Path.script_dir
local script = Path.script -- Current .dotune.lua file
local root = Path.root -- Filesystem root (e.g. / or C:\)-- Uses XDG environment variables, falling back to these paths under Path.home:
local config = XDG.config -- XDG_CONFIG_HOME: ~/.config
local data = XDG.data -- XDG_DATA_HOME: ~/.local/share
local state = XDG.state -- XDG_STATE_HOME: ~/.local/state
local cache = XDG.cache -- XDG_CACHE_HOME: ~/.cachelocal config = OS.match {
windows = Windows.roaming_app_data,
macos = Path.home / 'Library/Application Support',
linux = XDG.config,
unix = XDG.config,
_ = Path.home / '.config',
}
-- Priority: exact OS, then unix, then _;
-- All keys are optional, but no match is an error
local is_windows = OS.matches 'windows'
-- ^ Same thing just for boolean conditions(Not all paths are defined yet, more like a proof of concept for now)
local roaming = Windows.roaming_app_data -- APPDATA, or ~/AppData/Roaming
local local_data = Windows.local_app_data -- LOCALAPPDATA, or ~/AppData/Local
local low = Windows.local_low_app_data -- ~/AppData/LocalLow
local documents = Windows.documents -- ~/Documentslocal applications = Mac.applications -- /Applicationsmise install
cargo build --release