Skip to content
PicalinesPublic

About

A cross-platform dotfile manager configured with Lua

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

53 Commits

Folders and files

Repository files navigation

dotune

A dotfile manager for configs applied on different operating systems simultaneously. Write Lua scripts to decide where your stuff is being linked to

Example

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/dotfiles

CLI

dotune --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 API

Standard library

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

include 'shell'     -- Run shell/.dotune.lua relative to the current script
include 'web/vieb'  -- Nested paths are allowed; absolute paths, . and .. are not

Input

local 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')

Dot

Dot.link

-- 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')

Dot.copy

-- 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')

Path

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:\)

XDG

-- 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:  ~/.cache

OS

local 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

Platform paths

(Not all paths are defined yet, more like a proof of concept for now)

Windows

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           -- ~/Documents

Mac

local applications = Mac.applications  -- /Applications

Development

mise install
cargo build --release

About

A cross-platform dotfile manager configured with Lua

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages