馃グ My dot files
1import platform
2from itertools import chain
3from os import environ, pathsep, system
4from pathlib import Path
5from tempfile import NamedTemporaryFile
6from urllib.request import urlopen
7
8DOTFILES_DIR = Path.cwd()
9DOTFILES_GIT = DOTFILES_DIR / ".git"
10HOME_DIR = Path.home()
11CONFIG_FILE_NAMES = (".fdignore", ".gitconfig", ".gitignore_global", ".ripgreprc")
12
13KITTY_CONF = HOME_DIR / ".config" / "kitty"
14CATPPUCCIN_THEMES = "https://raw.githubusercontent.com/catppuccin/kitty/main/themes/"
15
16IS_MAC = platform.system().lower() == "darwin"
17FONT_KEYS = ("font_family", "bold_font", "italic_font", "bold_italic_font")
18MAC_FONTS = (
19 "FiraCode Nerd Font Mono Retina",
20 "FiraCode Nerd Font Mono Bold",
21 "FiraCode Nerd Font Mono Light",
22 "FiraCode Nerd Font Mono Medium",
23)
24LINUX_FONTS = {
25 "Fira Code Retina Nerd Font Complete Mono",
26 "Fira Code Bold Nerd Font Complete Mono",
27 "Fira Code Light Nerd Font Complete Mono",
28 "Fira Code SemiBold Nerd Font Complete Mono",
29}
30FONTS = dict(zip(FONT_KEYS, MAC_FONTS if IS_MAC else LINUX_FONTS))
31DIRVENV_URL = "https://raw.githubusercontent.com/cuducos/dirvenv.fish/refs/heads/main/install.fish"
32
33
34def which(bin):
35 for directory in environ["PATH"].split(pathsep):
36 path = Path(directory) / bin
37 if not path.exists() or not path.is_file():
38 continue
39 return path
40
41
42def download_as(url, path):
43 if not path.exists():
44 path.touch()
45
46 with urlopen(url) as resp:
47 path.write_bytes(resp.read())
48
49
50def create_all_dirs():
51 for path in DOTFILES_DIR.glob("**/*"):
52 if not path.is_dir() or DOTFILES_GIT in path.parents:
53 continue
54
55 target = HOME_DIR / path.relative_to(DOTFILES_DIR)
56 target.mkdir(exist_ok=True)
57
58
59def create_all_symlinks():
60 config_files = (DOTFILES_DIR / f for f in CONFIG_FILE_NAMES)
61 for path in chain(config_files, (DOTFILES_DIR / ".config").glob("**/*")):
62 if not path.is_file():
63 continue
64
65 target = HOME_DIR / path.relative_to(DOTFILES_DIR)
66 if target.exists():
67 continue
68
69 target.symlink_to(path)
70
71
72def configure_kitty():
73 fish = which("fish")
74 if IS_MAC:
75 fish = f"{fish} --login --interactive"
76
77 fonts = "\n".join(f"{k}\t{v}" for k, v in FONTS.items())
78 (KITTY_CONF / "fonts.conf").write_text(fonts)
79 (KITTY_CONF / "shell.conf").write_text(f"shell\t{fish}")
80
81 for theme in ("latte", "frappe"):
82 path = KITTY_CONF / f"catppuccin-{theme}.conf"
83 if path.exists():
84 continue
85
86 url = f"{CATPPUCCIN_THEMES}{theme}.conf"
87 download_as(url, path)
88
89
90def install_dirvenv():
91 with NamedTemporaryFile(suffix=".fish") as tmp:
92 download_as(DIRVENV_URL, Path(tmp.name))
93 system(f"fish {tmp.name}")
94
95
96def configure_nvim():
97 system("nvim --headless '+Lazy! sync' +qa")
98 system("nvim --headless -c 'silent UpdateRemotePlugins' -c 'quitall'")
99 system(
100 "nvim --headless -c 'autocmd User MasonUpgradeComplete sleep 100m | qall' -c 'MasonUpgrade'"
101 )
102
103
104if __name__ == "__main__":
105 create_all_dirs()
106 create_all_symlinks()
107 configure_kitty()
108 install_dirvenv()
109 configure_nvim()