Skip to content

ayvi-0001/dotfiles

Repository files navigation

dotfiles

A collection of my dotfiles/config/scripts, and a bash script to symlink them.

It's mainly focused on development, but also tracks some unrelated configs files, like utilities I frequently use or games I play (though often question why..).

Files are deployed with the install script along with a config file (dotfiles.toml) that lists source/dest paths and patterns for templating/obscuring secrets. The file structure is organized for convenience and doesn't determine the destination.

There's a private submodule at .secret/ for sensitive files (ssh/gnupg/etc). It's hosted on a local gitea server and the remote url points to my own tailnet domain.

It follows that this isn't designed to be run in anyone else's environment as is, but hopefully it can serve as a starting point or give you ideas if you are working on a similar process. Feel free to use anything found here and please open an issue if you have any questions or suggestions.  (:


Note

A lot of my development is currently done on windows using git-bash, if not wsl. Some of these files may have a few quirks and hacky solutions to make things work.



Config

Each directory has a key in the config file of the same name, with the table files and an optional array of table's templates. These top-level keys are referenced when running the install script.

[$DIR.files]

Keys correspond to the source file (relative to the parent $DIR), values point to the destination.

# If the destination ends in `/` then the symlink has the same name as the source file.
[yazi.files]
"yazi.toml"                          = "~/.config/yazi/"
"plugins/parent-arrow.yazi/init.lua" = "~/.config/yazi/plugins/parent-arrow.yazi/"

# If the destination doesn't end in `/` then the symlink target has the new file name.
[envrc.files]
".envrc.work" = "~/work/.envrc"

A key can contain multiple path segments, but it must be enclosed in quotes.

["bin/utils".files]
"fd-dup-file-names" = "~/bin/"

This would link all the files at ./bin/utils/ only, instead of everything at ./bin/. The option --fd-filter/-f can be used as an alternative.

[[$DIR.templates]]

Each table contains a pattern and replacement that is run through sd -F. Most templates are enclosed in double curly-braces, but it can be any single or multiline string. Patterns are searched for as fixed-strings.

# direnv/direnv.toml
[whitelist]
prefix = ['{{DIRENV_WHITELIST}}']
# dotfiles.toml
[[direnv.templates]]
pattern     = "'{{DIRENV_WHITELIST}}'"
replacement = '"~/source", "~/work"'

The config file is run through eval, so it can contain commands/environment variables.

[fancontrol.files]
"userConfig.json" = """\
$(if target=$(dirname $(which fancontrol)); then echo -n $target/configurations; else echo '/c/program files/fancontrol/configurations'; fi)/\
"""

[[yazi.templates]]
pattern     = "~/.cache" # e.g. if a program doesn't expand tilde when reading it's config file
replacement = "$HOME/.cache"

The config file doesn't need to specify which source file has which templates. A patterns file is compiled and matched against each source with rg -Ff "$patterns_file".

The process for linking templated files (also see diagram) is:

  1. The directory .templates/ is created (ignored by git).
  2. If a source file contains a pattern, it's copied to .templates/ and the patterns in the copied file are replaced.
  3. The copied file is the new source for the symlink.

File Structure

All files in the target directory are included except for README.md, .templates/, and .ignore/ (for uncommitted config files, tests, ect). Files starting with 2 leading underscores are tracked but skipped when linking files.

  ┣━━ bash/
  ┃   ┣━━ .templates/
# ┃   ┃   ┃ ^ ignored by git
  ┃   ┃   ┗━━ .bashrc
# ┃   ┃         ^ copy of .bashrc with patterns replaced, used as symlink source instead of original file.
  ┃   ┃
  ┃   ┗━━ .ignore/
# ┃       ┃ ^ ignored by git
  ┃       ┗━━ .bashrc
# ┃             ^ copy of .bashrc with removed functions, tests, etc.
  ┃
  ┣━━ .bash_logout
  ┣━━ .bash_profile
  ┣━━ .bashrc
  ┣━━ .inputrc
  ┗━━ __unused__.inputrc
#       ^ ignored by `./install`

Usage

Dependencies

Differences on Windows:

  • The expected ln command used is the Link Shell Extension cli, in place of the standard unix command ln. If this is detected, the option --absolute/-a is added.
  • It will check for the package gsudo and run ln -s with it if found.

If no args are passed to install, all top-level keys in the config file are used. A selection can be run by passing the names of directories as arguments.

# search for all top-level keys in config.
./install

# only search config for 2 keys.
./install yazi helix

# search for 1 key with multiple path segments
./install .secret/.ssh

Filtering

The --fd-filter / -f option can be used as a filter for fd when searching for files.

./install -f'utils' -- bin

Diagram

---
config:
  theme: neo-dark
  look: handDrawn
---
flowchart TD
    n1["start"] --> n8["./install<br>"]
    n3["search top-level keys in dotfiles.toml for args"] -. key not found .-> n6["ignored"]
    n8 -- args --> n3
    n8 -- no args --> n4["get all top-level keys in dotfiles.toml"]
    n3 -- "<span style=font-family:>key found</span>" --> n9["search directories by key for files using fd"]
    n4 --> n9
    n9 -- "corresponding key found in [$DIR.files]" --> n12@{ label: "<span style=\"background-color:\">search file for patterns from [[$DIR.templates]]</span><br>" }
    n9 -. "no key found in [$DIR.files]" .-> n13["skipped. log file found but no target set in config"]
    n12 -- file contains patterns --> n14@{ label: "copy file to $DIR/.templates/ &amp; replace patterns. use&nbsp;<span style=\"font-family:\">templated file in place of source</span>" }
    n12 -- file contains no patterns --> n15["symlink source to target"]
    n14 --> n15
    n15 -- "<span style=background-color:>target&nbsp;</span>exists as regular file" --> n16["delete file and symlink source"]
    n15 -- "<span style=background-color:>target&nbsp;</span><span style=font-family:>symlink&nbsp;</span>exists but path doesn't match source" --> n17["replace symlink with correct source"]
    n15 -- "<span style=background-color:>target&nbsp;</span>does not exist" --> n18["symlink source"]
    n17 --> n19["end"]
    n16 --> n19
    n18 --> n19
    n1@{ shape: start}
    n8@{ shape: manual-input}
    n3@{ shape: in-out}
    n6@{ shape: terminal}
    n4@{ shape: proc}
    n9@{ shape: procs}
    n12@{ shape: rect}
    n13@{ shape: terminal}
    n14@{ shape: rect}
    n15@{ shape: proc}
    n16@{ shape: event}
    n19@{ shape: stop}
    style n6 stroke-width:1px,stroke-dasharray: 1
    style n13 stroke-width:1px,stroke-dasharray: 1
Loading

About

my dotfiles and a bash script to symlink them. also other random configs unrelated to dev

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published