diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0ac8871
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+script-resources/markdown2htmldoc/themes-out/**/* linguist-generated
diff --git a/.github/pull.yml b/.github/pull.yml
new file mode 100644
index 0000000..08de30a
--- /dev/null
+++ b/.github/pull.yml
@@ -0,0 +1,6 @@
+version: '1'
+rules:
+ - base: master
+ upstream: dmitmel:master
+ mergeMethod: merge
+ mergeUnstable: true
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
deleted file mode 100644
index 5696d4b..0000000
--- a/.github/workflows/sync.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Update submodules
-
-on:
- workflow_dispatch:
- schedule:
- - cron: '0 0 * * *'
-
-jobs:
- update:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v2
-
- - name: Pull & update submodules recursively
- run: |
- git submodule update --init --recursive
- git submodule update --recursive --remote
- - name: Commit & push changes
- run: |
- git config --global user.name GitHub
- git config --global user.email actions@github.com
- git commit -am "[dmitmel] Update submodule" | true
- git push
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..349d9a2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.pyc
+node_modules/
+.venv
+*.md.html
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 6b506b3..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "dmitmel-dotfiles"]
- path = dmitmel-dotfiles
- url = https://github.com/dmitmel/dotfiles
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..98d3340
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2021 Dmytro Meleshko
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8ae3c22
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# dotfiles
+
+My dotfiles (configurations and settings) for shells, text editors and other terminal programs, plus
+a collection of scripts. Written for and work on various UNIX-like OSes, primarily for:
+
+- Arch Linux,
+- Linux Mint,
+- server Ubuntu,
+- macOS with GNU coreutils (i.e. BSDs are not supported),
+- Android with Termux.
+
+And also a legendary project that has survived for thousands of years of development.
+
+## Disclaimer
+
+### **This is my personal project! No warranty is provided for running these as a superuser, I am in no way responsible for deletion of `/` with `rm -rf`, and _absolutely no support is provided_ whatsoever unless I explicitly say so personally!**
+
+**It is also recommended for users of this repository to read the scripts they are running. I didn't
+write the comments just for myself!**
+
+**Automatic installers are deliberately not provided.**
diff --git a/colorschemes/main.py b/colorschemes/main.py
new file mode 100755
index 0000000..209a460
--- /dev/null
+++ b/colorschemes/main.py
@@ -0,0 +1,426 @@
+#!/usr/bin/env python3
+
+import json
+import os
+from abc import abstractmethod
+from typing import Dict, Iterator, List, Protocol, TextIO
+
+__dir__ = os.path.dirname(__file__)
+
+
+class Color:
+
+ def __init__(self, r: int, g: int, b: int) -> None:
+ if not (0 <= r <= 0xff):
+ raise Exception("r component out of range")
+ if not (0 <= g <= 0xff):
+ raise Exception("g component out of range")
+ if not (0 <= b <= 0xff):
+ raise Exception("b component out of range")
+ self.r = r
+ self.g = g
+ self.b = b
+
+ @classmethod
+ def from_hex(cls, s: str) -> "Color":
+ if len(s) != 6:
+ raise Exception("hex color string must be 6 characters long")
+ return Color(int(s[0:2], 16), int(s[2:4], 16), int(s[4:6], 16))
+
+ @property
+ def css_hex(self) -> str:
+ return "#{:02x}{:02x}{:02x}".format(self.r, self.g, self.b)
+
+ @property
+ def hex(self) -> str:
+ return "{:02x}{:02x}{:02x}".format(self.r, self.g, self.b)
+
+ def __getitem__(self, index: int) -> int:
+ if index == 0:
+ return self.r
+ elif index == 1:
+ return self.g
+ elif index == 2:
+ return self.b
+ else:
+ raise IndexError("color component index out of range")
+
+ def __iter__(self) -> Iterator[int]:
+ yield self.r
+ yield self.g
+ yield self.b
+
+
+BASE16_TO_ANSI_MAPPING: List[int] = [
+ 0x0, 0x8, 0xB, 0xA, 0xD, 0xE, 0xC, 0x5, # 0x0
+ 0x3, 0x8, 0xB, 0xA, 0xD, 0xE, 0xC, 0x7, # 0x8
+ 0x9, 0xF, 0x1, 0x2, 0x4, 0x6, # 0x10
+] # yapf: disable
+
+ANSI_TO_BASE16_MAPPING: List[int] = [BASE16_TO_ANSI_MAPPING.index(i) for i in range(16)]
+
+
+class Theme(Protocol):
+ base16_name: str
+ is_dark: bool
+ base16_colors: List[Color]
+
+ @property
+ def name(self) -> str:
+ return "base16-{}".format(self.base16_name)
+
+ @property
+ def bg(self) -> Color:
+ return self.base16_colors[0x0]
+
+ @property
+ def fg(self) -> Color:
+ return self.base16_colors[0x5]
+
+ @property
+ def cursor_bg(self) -> Color:
+ return self.fg
+
+ @property
+ def cursor_fg(self) -> Color:
+ return self.bg
+
+ @property
+ def selection_bg(self) -> Color:
+ return self.base16_colors[0x2]
+
+ @property
+ def selection_fg(self) -> Color:
+ return self.fg
+
+ @property
+ def ansi_colors(self) -> List[Color]:
+ return [self.base16_colors[i] for i in BASE16_TO_ANSI_MAPPING]
+
+ @property
+ def link_color(self) -> Color:
+ return self.ansi_colors[0xC]
+
+ @property
+ def css_variables(self) -> Dict[str, Color]:
+ d = {
+ "bg": self.bg,
+ "fg": self.fg,
+ "selection-bg": self.selection_bg,
+ "selection-fg": self.selection_fg,
+ "cursor-bg": self.cursor_bg,
+ "cursor-fg": self.cursor_fg,
+ }
+ for index, color in enumerate(self.base16_colors):
+ d["base-{:02X}".format(index)] = color
+ return d
+
+
+class MyTheme(Theme):
+ base16_name = "eighties"
+ is_dark = True
+ base16_colors = [
+ Color.from_hex("2d2d2d"), # 0
+ Color.from_hex("393939"), # 1
+ Color.from_hex("515151"), # 2
+ Color.from_hex("747369"), # 3
+ Color.from_hex("a09f93"), # 4
+ Color.from_hex("d3d0c8"), # 5
+ Color.from_hex("e8e6df"), # 6
+ Color.from_hex("f2f0ec"), # 7
+ Color.from_hex("f2777a"), # 8
+ Color.from_hex("f99157"), # 9
+ Color.from_hex("ffcc66"), # a
+ Color.from_hex("99cc99"), # b
+ Color.from_hex("66cccc"), # c
+ Color.from_hex("6699cc"), # d
+ Color.from_hex("cc99cc"), # e
+ Color.from_hex("d27b53"), # f
+ ]
+
+
+class ThemeGenerator(Protocol):
+
+ @abstractmethod
+ def file_name(self) -> str:
+ raise NotImplementedError()
+
+ @abstractmethod
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ raise NotImplementedError()
+
+
+class ThemeGeneratorKitty(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "kitty.conf"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+
+ def write_color(key_name: str, color: Color) -> None:
+ output.write("{} {}\n".format(key_name, color.css_hex))
+
+ write_color("background", theme.bg)
+ write_color("foreground", theme.fg)
+ write_color("cursor", theme.cursor_bg)
+ write_color("cursor_text_color", theme.cursor_fg)
+ write_color("selection_background", theme.selection_bg)
+ write_color("selection_foreground", theme.selection_fg)
+ for index, color in enumerate(theme.ansi_colors[:16]):
+ write_color("color{}".format(index), color)
+ write_color("url_color", theme.link_color)
+
+ write_color("active_border_color", theme.ansi_colors[2])
+ write_color("inactive_border_color", theme.ansi_colors[8])
+ write_color("bell_border_color", theme.ansi_colors[1])
+
+ write_color("active_tab_foreground", theme.base16_colors[0x1])
+ write_color("active_tab_background", theme.base16_colors[0xB])
+ write_color("inactive_tab_foreground", theme.base16_colors[0x4])
+ write_color("inactive_tab_background", theme.base16_colors[0x1])
+ write_color("tab_bar_background", theme.base16_colors[0x1])
+
+
+class ThemeGeneratorTermux(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "termux.properties"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+
+ def write_color(key_name: str, color: Color) -> None:
+ output.write("{}={}\n".format(key_name, color.css_hex))
+
+ write_color("background", theme.bg)
+ write_color("foreground", theme.fg)
+ write_color("cursor", theme.cursor_bg)
+ for index, color in enumerate(theme.ansi_colors[:16]):
+ write_color("color{}".format(index), color)
+
+
+class ThemeGeneratorZsh(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "zsh.zsh"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+
+ def write_color(key_name: str, color: Color) -> None:
+ output.write("colorscheme_{}={}\n".format(key_name, color.hex))
+
+ write_color("bg", theme.bg)
+ write_color("fg", theme.fg)
+ write_color("cursor_bg", theme.cursor_bg)
+ write_color("cursor_fg", theme.cursor_fg)
+ write_color("selection_bg", theme.selection_bg)
+ write_color("selection_fg", theme.selection_fg)
+ write_color("link_color", theme.link_color)
+
+ output.write("colorscheme_ansi_colors=(\n")
+ for color in theme.ansi_colors:
+ output.write(" {}\n".format(color.hex))
+ output.write(")\n")
+
+
+class ThemeGeneratorVim(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "vim.vim"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ namespace = "dotfiles_colorscheme_"
+ output.write("let {}name = '{}'\n".format(namespace, theme.name))
+ output.write("let {}base16_name = '{}'\n".format(namespace, theme.base16_name))
+ output.write("let {}base16_colors = [\n".format(namespace))
+ for gui_color, cterm_color in zip(theme.base16_colors, ANSI_TO_BASE16_MAPPING):
+ output.write(
+ "\\ {{'gui': '{}', 'cterm': '{:02}'}},\n".format(gui_color.css_hex, cterm_color),
+ )
+ output.write("\\ ]\n")
+
+ namespace = "terminal_color_"
+ output.write("let {}background = '{}'\n".format(namespace, theme.bg.css_hex))
+ output.write("let {}foreground = '{}'\n".format(namespace, theme.fg.css_hex))
+ for index, color in enumerate(theme.ansi_colors[:16]):
+ output.write("let {}{} = '{}'\n".format(namespace, index, color.css_hex))
+
+
+class ThemeGeneratorSetvtrgb(ThemeGenerator):
+ # default setvtrgb config:
+ # 0,170,0,170,0,170,0,170,85,255,85,255,85,255,85,255
+ # 0,0,170,85,0,0,170,170,85,85,255,255,85,85,255,255
+ # 0,0,0,0,170,170,170,170,85,85,85,85,255,255,255,255
+
+ def file_name(self) -> str:
+ return "setvtrgb.txt"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ for i in range(3):
+ output.write(",".join(str(color[i]) for color in theme.ansi_colors[:16]))
+ output.write("\n")
+
+
+class ThemeGeneratorXfceTerminal(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "xfce4-terminal.theme"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ output.write("[Scheme]\n")
+ output.write("Name=dmitmel's dotfiles colorscheme\n")
+ output.write("ColorForeground={}\n".format(theme.fg.css_hex))
+ output.write("ColorBackground={}\n".format(theme.bg.css_hex))
+ output.write("ColorCursorUseDefault=FALSE\n")
+ output.write("ColorCursorForeground={}\n".format(theme.cursor_fg.css_hex))
+ output.write("ColorCursor={}\n".format(theme.cursor_bg.css_hex))
+ output.write("ColorSelectionUseDefault=FALSE\n")
+ output.write("ColorSelection={}\n".format(theme.selection_fg.css_hex))
+ output.write("ColorSelectionBackground={}\n".format(theme.selection_bg.css_hex))
+ output.write("TabActivityColor={}\n".format(theme.base16_colors[0x8].css_hex))
+ output.write("ColorBoldUseDefault=TRUE\n")
+ output.write(
+ "ColorPalette={}\n".format(";".join(color.css_hex for color in theme.ansi_colors)),
+ )
+
+
+class ThemeGeneratorVscode(ThemeGenerator):
+
+ ANSI_COLOR_NAMES = [
+ "Black",
+ "Red",
+ "Green",
+ "Yellow",
+ "Blue",
+ "Magenta",
+ "Cyan",
+ "White",
+ ]
+
+ def file_name(self) -> str:
+ return "vscode-colorCustomizations.json"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+
+ colors: Dict[str, str] = {
+ "terminal.background": theme.bg.css_hex,
+ "terminal.foreground": theme.fg.css_hex,
+ "terminal.selectionBackground": theme.selection_bg.css_hex,
+ "terminalCursor.background": theme.cursor_fg.css_hex,
+ "terminalCursor.foreground": theme.cursor_bg.css_hex,
+ }
+
+ for is_bright in [False, True]:
+ for color_index, color_name in enumerate(self.ANSI_COLOR_NAMES):
+ color = theme.ansi_colors[color_index + int(is_bright) * len(self.ANSI_COLOR_NAMES)]
+ colors["terminal.ansi" + ("Bright" if is_bright else "") + color_name] = color.css_hex
+
+ json.dump(colors, output, ensure_ascii=False, indent=2)
+ output.write("\n")
+
+
+class ThemeGeneratorIterm(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "iterm.itermcolors"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ output.write('\n')
+ output.write(
+ '\n',
+ )
+ output.write('\n')
+ output.write("\n")
+
+ def write_color(key_name: str, color: Color) -> None:
+ r, g, b = (float(component) / 0xff for component in color)
+ output.write(" {} Color\n".format(key_name))
+ output.write(" \n")
+ output.write(" Color Space\n")
+ output.write(" sRGB\n")
+ output.write(" Red Component\n")
+ output.write(" {}\n".format(r))
+ output.write(" Green Component\n")
+ output.write(" {}\n".format(g))
+ output.write(" Blue Component\n")
+ output.write(" {}\n".format(b))
+ output.write(" \n")
+
+ write_color("Background", theme.bg)
+ write_color("Foreground", theme.fg)
+ write_color("Bold", theme.fg)
+ write_color("Cursor", theme.cursor_bg)
+ write_color("Cursor Text", theme.cursor_fg)
+ write_color("Selection Color", theme.selection_bg)
+ write_color("Selected Text Color", theme.selection_fg)
+ for index, color in enumerate(theme.ansi_colors[:16]):
+ write_color("Ansi " + str(index), color)
+ write_color("Link", theme.link_color)
+
+ output.write("\n")
+ output.write("\n")
+
+
+class ThemeGeneratorCssVariables(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "variables.css"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ output.write(":root {\n")
+ for var_name, color in theme.css_variables.items():
+ output.write(" --dotfiles-colorscheme-{}: {};\n".format(var_name, color.css_hex))
+ output.write("}\n")
+
+
+class ThemeGeneratorScss(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "_colorscheme.scss"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ output.write("$is-dark: {};\n".format("true" if theme.is_dark else "false"))
+ for var_name, color in theme.css_variables.items():
+ output.write("${}: {};\n".format(var_name, color.css_hex))
+ output.write("$base: ({});\n".format(", ".join(c.css_hex for c in theme.base16_colors)))
+ output.write("$ansi: ({});\n".format(", ".join(c.css_hex for c in theme.ansi_colors)))
+
+
+class ThemeGeneratorPrismJs(ThemeGenerator):
+
+ def file_name(self) -> str:
+ return "prismjs-theme.css"
+
+ def generate(self, theme: Theme, output: TextIO) -> None:
+ with open(os.path.join(__dir__, "prismjs-theme-src.css")) as src_file:
+ src_css = src_file.read()
+ for var_name, color in theme.css_variables.items():
+ src_css = src_css.replace("var(--dotfiles-colorscheme-{})".format(var_name), color.css_hex)
+ output.write(src_css)
+
+
+def main() -> None:
+ theme: Theme = MyTheme()
+ generators: List[ThemeGenerator] = [
+ ThemeGeneratorKitty(),
+ ThemeGeneratorTermux(),
+ ThemeGeneratorZsh(),
+ ThemeGeneratorVim(),
+ ThemeGeneratorSetvtrgb(),
+ ThemeGeneratorXfceTerminal(),
+ ThemeGeneratorVscode(),
+ ThemeGeneratorIterm(),
+ ThemeGeneratorCssVariables(),
+ ThemeGeneratorScss(),
+ ThemeGeneratorPrismJs(),
+ ]
+
+ out_dir = os.path.join(__dir__, "out")
+ os.makedirs(out_dir, exist_ok=True)
+
+ for generator in generators:
+ with open(os.path.join(out_dir, generator.file_name()), "w") as output_file:
+ generator.generate(theme, output_file)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/colorschemes/out/_colorscheme.scss b/colorschemes/out/_colorscheme.scss
new file mode 100644
index 0000000..6ce8cd2
--- /dev/null
+++ b/colorschemes/out/_colorscheme.scss
@@ -0,0 +1,25 @@
+$is-dark: true;
+$bg: #2d2d2d;
+$fg: #d3d0c8;
+$selection-bg: #515151;
+$selection-fg: #d3d0c8;
+$cursor-bg: #d3d0c8;
+$cursor-fg: #2d2d2d;
+$base-00: #2d2d2d;
+$base-01: #393939;
+$base-02: #515151;
+$base-03: #747369;
+$base-04: #a09f93;
+$base-05: #d3d0c8;
+$base-06: #e8e6df;
+$base-07: #f2f0ec;
+$base-08: #f2777a;
+$base-09: #f99157;
+$base-0A: #ffcc66;
+$base-0B: #99cc99;
+$base-0C: #66cccc;
+$base-0D: #6699cc;
+$base-0E: #cc99cc;
+$base-0F: #d27b53;
+$base: (#2d2d2d, #393939, #515151, #747369, #a09f93, #d3d0c8, #e8e6df, #f2f0ec, #f2777a, #f99157, #ffcc66, #99cc99, #66cccc, #6699cc, #cc99cc, #d27b53);
+$ansi: (#2d2d2d, #f2777a, #99cc99, #ffcc66, #6699cc, #cc99cc, #66cccc, #d3d0c8, #747369, #f2777a, #99cc99, #ffcc66, #6699cc, #cc99cc, #66cccc, #f2f0ec, #f99157, #d27b53, #393939, #515151, #a09f93, #e8e6df);
diff --git a/colorschemes/out/iterm.itermcolors b/colorschemes/out/iterm.itermcolors
new file mode 100644
index 0000000..1d03f1c
--- /dev/null
+++ b/colorschemes/out/iterm.itermcolors
@@ -0,0 +1,270 @@
+
+
+
+
+ Background Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.17647058823529413
+ Green Component
+ 0.17647058823529413
+ Blue Component
+ 0.17647058823529413
+
+ Foreground Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8274509803921568
+ Green Component
+ 0.8156862745098039
+ Blue Component
+ 0.7843137254901961
+
+ Bold Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8274509803921568
+ Green Component
+ 0.8156862745098039
+ Blue Component
+ 0.7843137254901961
+
+ Cursor Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8274509803921568
+ Green Component
+ 0.8156862745098039
+ Blue Component
+ 0.7843137254901961
+
+ Cursor Text Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.17647058823529413
+ Green Component
+ 0.17647058823529413
+ Blue Component
+ 0.17647058823529413
+
+ Selection Color Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.3176470588235294
+ Green Component
+ 0.3176470588235294
+ Blue Component
+ 0.3176470588235294
+
+ Selected Text Color Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8274509803921568
+ Green Component
+ 0.8156862745098039
+ Blue Component
+ 0.7843137254901961
+
+ Ansi 0 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.17647058823529413
+ Green Component
+ 0.17647058823529413
+ Blue Component
+ 0.17647058823529413
+
+ Ansi 1 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.9490196078431372
+ Green Component
+ 0.4666666666666667
+ Blue Component
+ 0.47843137254901963
+
+ Ansi 2 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.6
+ Green Component
+ 0.8
+ Blue Component
+ 0.6
+
+ Ansi 3 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 1.0
+ Green Component
+ 0.8
+ Blue Component
+ 0.4
+
+ Ansi 4 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4
+ Green Component
+ 0.6
+ Blue Component
+ 0.8
+
+ Ansi 5 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8
+ Green Component
+ 0.6
+ Blue Component
+ 0.8
+
+ Ansi 6 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4
+ Green Component
+ 0.8
+ Blue Component
+ 0.8
+
+ Ansi 7 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8274509803921568
+ Green Component
+ 0.8156862745098039
+ Blue Component
+ 0.7843137254901961
+
+ Ansi 8 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4549019607843137
+ Green Component
+ 0.45098039215686275
+ Blue Component
+ 0.4117647058823529
+
+ Ansi 9 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.9490196078431372
+ Green Component
+ 0.4666666666666667
+ Blue Component
+ 0.47843137254901963
+
+ Ansi 10 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.6
+ Green Component
+ 0.8
+ Blue Component
+ 0.6
+
+ Ansi 11 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 1.0
+ Green Component
+ 0.8
+ Blue Component
+ 0.4
+
+ Ansi 12 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4
+ Green Component
+ 0.6
+ Blue Component
+ 0.8
+
+ Ansi 13 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.8
+ Green Component
+ 0.6
+ Blue Component
+ 0.8
+
+ Ansi 14 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4
+ Green Component
+ 0.8
+ Blue Component
+ 0.8
+
+ Ansi 15 Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.9490196078431372
+ Green Component
+ 0.9411764705882353
+ Blue Component
+ 0.9254901960784314
+
+ Link Color
+
+ Color Space
+ sRGB
+ Red Component
+ 0.4
+ Green Component
+ 0.6
+ Blue Component
+ 0.8
+
+
+
diff --git a/colorschemes/out/kitty.conf b/colorschemes/out/kitty.conf
new file mode 100644
index 0000000..5736557
--- /dev/null
+++ b/colorschemes/out/kitty.conf
@@ -0,0 +1,31 @@
+background #2d2d2d
+foreground #d3d0c8
+cursor #d3d0c8
+cursor_text_color #2d2d2d
+selection_background #515151
+selection_foreground #d3d0c8
+color0 #2d2d2d
+color1 #f2777a
+color2 #99cc99
+color3 #ffcc66
+color4 #6699cc
+color5 #cc99cc
+color6 #66cccc
+color7 #d3d0c8
+color8 #747369
+color9 #f2777a
+color10 #99cc99
+color11 #ffcc66
+color12 #6699cc
+color13 #cc99cc
+color14 #66cccc
+color15 #f2f0ec
+url_color #6699cc
+active_border_color #99cc99
+inactive_border_color #747369
+bell_border_color #f2777a
+active_tab_foreground #393939
+active_tab_background #99cc99
+inactive_tab_foreground #a09f93
+inactive_tab_background #393939
+tab_bar_background #393939
diff --git a/colorschemes/out/prismjs-theme.css b/colorschemes/out/prismjs-theme.css
new file mode 100644
index 0000000..fd4b76e
--- /dev/null
+++ b/colorschemes/out/prismjs-theme.css
@@ -0,0 +1,123 @@
+/* Based on */
+
+.markdown-body code,
+.markdown-body pre {
+ font-family: 'Ubuntu Mono', monospace;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+}
+
+.markdown-body pre {
+ background-color: #2d2d2d;
+ color: #d3d0c8;
+}
+
+.markdown-body pre::-moz-selection,
+.markdown-body pre::selection,
+.markdown-body pre ::-moz-selection,
+.markdown-body pre ::selection {
+ background-color: #515151;
+ color: #d3d0c8;
+}
+
+.token.symbol {
+ color: #905;
+}
+
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.url {
+ text-decoration: underline;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.attr-equals,
+.token.punctuation,
+.token.operator,
+.token.combinator {
+ color: #d3d0c8;
+}
+
+.token.comment,
+.token.doctype,
+.token.doctype > .token.punctuation,
+.token.cdata,
+.token.cdata > .token.punctuation,
+.token.prolog,
+.token.blockquote,
+.token.hr {
+ color: #747369;
+}
+
+.token.variable,
+.token.parameter,
+.token.constant,
+.token.tag,
+.token.property,
+.token.deleted,
+.token.selector {
+ color: #f2777a;
+}
+
+.token.boolean,
+.token.number,
+.token.unit,
+.token.attr-name,
+.token.color.hexcode,
+.token.list,
+.token.nil,
+.token.nil.keyword {
+ color: #f99157;
+}
+
+.token.class-name,
+.token.maybe-class-name,
+.token.builtin,
+.token.variable.dom,
+.token.macro,
+.token.interpolation-punctuation,
+.language-json .token.property {
+ color: #ffcc66;
+}
+
+.token.string,
+.token.char,
+.token.attr-value,
+.token.attr-value > .token.punctuation:not(.attr-equals),
+.token.inserted {
+ color: #99cc99;
+}
+
+.token.regex,
+.token.pseudo-class,
+.token.pseudo-element,
+.token.entity,
+.token.important {
+ color: #66cccc;
+}
+
+.token.function,
+.token.coord,
+.token.url,
+.token.heading,
+.token.title,
+.token.heading > .token.important,
+.token.title > .token.punctuation {
+ color: #6699cc;
+}
+
+.token.keyword,
+.token.operator.arrow,
+.token.rule {
+ color: #cc99cc;
+}
diff --git a/colorschemes/out/setvtrgb.txt b/colorschemes/out/setvtrgb.txt
new file mode 100644
index 0000000..5886b18
--- /dev/null
+++ b/colorschemes/out/setvtrgb.txt
@@ -0,0 +1,3 @@
+45,242,153,255,102,204,102,211,116,242,153,255,102,204,102,242
+45,119,204,204,153,153,204,208,115,119,204,204,153,153,204,240
+45,122,153,102,204,204,204,200,105,122,153,102,204,204,204,236
diff --git a/colorschemes/out/termux.properties b/colorschemes/out/termux.properties
new file mode 100644
index 0000000..70f5a30
--- /dev/null
+++ b/colorschemes/out/termux.properties
@@ -0,0 +1,19 @@
+background=#2d2d2d
+foreground=#d3d0c8
+cursor=#d3d0c8
+color0=#2d2d2d
+color1=#f2777a
+color2=#99cc99
+color3=#ffcc66
+color4=#6699cc
+color5=#cc99cc
+color6=#66cccc
+color7=#d3d0c8
+color8=#747369
+color9=#f2777a
+color10=#99cc99
+color11=#ffcc66
+color12=#6699cc
+color13=#cc99cc
+color14=#66cccc
+color15=#f2f0ec
diff --git a/colorschemes/out/variables.css b/colorschemes/out/variables.css
new file mode 100644
index 0000000..7a7d1d4
--- /dev/null
+++ b/colorschemes/out/variables.css
@@ -0,0 +1,24 @@
+:root {
+ --dotfiles-colorscheme-bg: #2d2d2d;
+ --dotfiles-colorscheme-fg: #d3d0c8;
+ --dotfiles-colorscheme-selection-bg: #515151;
+ --dotfiles-colorscheme-selection-fg: #d3d0c8;
+ --dotfiles-colorscheme-cursor-bg: #d3d0c8;
+ --dotfiles-colorscheme-cursor-fg: #2d2d2d;
+ --dotfiles-colorscheme-base-00: #2d2d2d;
+ --dotfiles-colorscheme-base-01: #393939;
+ --dotfiles-colorscheme-base-02: #515151;
+ --dotfiles-colorscheme-base-03: #747369;
+ --dotfiles-colorscheme-base-04: #a09f93;
+ --dotfiles-colorscheme-base-05: #d3d0c8;
+ --dotfiles-colorscheme-base-06: #e8e6df;
+ --dotfiles-colorscheme-base-07: #f2f0ec;
+ --dotfiles-colorscheme-base-08: #f2777a;
+ --dotfiles-colorscheme-base-09: #f99157;
+ --dotfiles-colorscheme-base-0A: #ffcc66;
+ --dotfiles-colorscheme-base-0B: #99cc99;
+ --dotfiles-colorscheme-base-0C: #66cccc;
+ --dotfiles-colorscheme-base-0D: #6699cc;
+ --dotfiles-colorscheme-base-0E: #cc99cc;
+ --dotfiles-colorscheme-base-0F: #d27b53;
+}
diff --git a/colorschemes/out/vim.vim b/colorschemes/out/vim.vim
new file mode 100644
index 0000000..32d8f6f
--- /dev/null
+++ b/colorschemes/out/vim.vim
@@ -0,0 +1,38 @@
+let dotfiles_colorscheme_name = 'base16-eighties'
+let dotfiles_colorscheme_base16_name = 'eighties'
+let dotfiles_colorscheme_base16_colors = [
+\ {'gui': '#2d2d2d', 'cterm': '00'},
+\ {'gui': '#393939', 'cterm': '18'},
+\ {'gui': '#515151', 'cterm': '19'},
+\ {'gui': '#747369', 'cterm': '08'},
+\ {'gui': '#a09f93', 'cterm': '20'},
+\ {'gui': '#d3d0c8', 'cterm': '07'},
+\ {'gui': '#e8e6df', 'cterm': '21'},
+\ {'gui': '#f2f0ec', 'cterm': '15'},
+\ {'gui': '#f2777a', 'cterm': '01'},
+\ {'gui': '#f99157', 'cterm': '16'},
+\ {'gui': '#ffcc66', 'cterm': '03'},
+\ {'gui': '#99cc99', 'cterm': '02'},
+\ {'gui': '#66cccc', 'cterm': '06'},
+\ {'gui': '#6699cc', 'cterm': '04'},
+\ {'gui': '#cc99cc', 'cterm': '05'},
+\ {'gui': '#d27b53', 'cterm': '17'},
+\ ]
+let terminal_color_background = '#2d2d2d'
+let terminal_color_foreground = '#d3d0c8'
+let terminal_color_0 = '#2d2d2d'
+let terminal_color_1 = '#f2777a'
+let terminal_color_2 = '#99cc99'
+let terminal_color_3 = '#ffcc66'
+let terminal_color_4 = '#6699cc'
+let terminal_color_5 = '#cc99cc'
+let terminal_color_6 = '#66cccc'
+let terminal_color_7 = '#d3d0c8'
+let terminal_color_8 = '#747369'
+let terminal_color_9 = '#f2777a'
+let terminal_color_10 = '#99cc99'
+let terminal_color_11 = '#ffcc66'
+let terminal_color_12 = '#6699cc'
+let terminal_color_13 = '#cc99cc'
+let terminal_color_14 = '#66cccc'
+let terminal_color_15 = '#f2f0ec'
diff --git a/colorschemes/out/vscode-colorCustomizations.json b/colorschemes/out/vscode-colorCustomizations.json
new file mode 100644
index 0000000..8912830
--- /dev/null
+++ b/colorschemes/out/vscode-colorCustomizations.json
@@ -0,0 +1,23 @@
+{
+ "terminal.background": "#2d2d2d",
+ "terminal.foreground": "#d3d0c8",
+ "terminal.selectionBackground": "#515151",
+ "terminalCursor.background": "#2d2d2d",
+ "terminalCursor.foreground": "#d3d0c8",
+ "terminal.ansiBlack": "#2d2d2d",
+ "terminal.ansiRed": "#f2777a",
+ "terminal.ansiGreen": "#99cc99",
+ "terminal.ansiYellow": "#ffcc66",
+ "terminal.ansiBlue": "#6699cc",
+ "terminal.ansiMagenta": "#cc99cc",
+ "terminal.ansiCyan": "#66cccc",
+ "terminal.ansiWhite": "#d3d0c8",
+ "terminal.ansiBrightBlack": "#747369",
+ "terminal.ansiBrightRed": "#f2777a",
+ "terminal.ansiBrightGreen": "#99cc99",
+ "terminal.ansiBrightYellow": "#ffcc66",
+ "terminal.ansiBrightBlue": "#6699cc",
+ "terminal.ansiBrightMagenta": "#cc99cc",
+ "terminal.ansiBrightCyan": "#66cccc",
+ "terminal.ansiBrightWhite": "#f2f0ec"
+}
diff --git a/colorschemes/out/xfce4-terminal.theme b/colorschemes/out/xfce4-terminal.theme
new file mode 100644
index 0000000..34872c2
--- /dev/null
+++ b/colorschemes/out/xfce4-terminal.theme
@@ -0,0 +1,13 @@
+[Scheme]
+Name=dmitmel's dotfiles colorscheme
+ColorForeground=#d3d0c8
+ColorBackground=#2d2d2d
+ColorCursorUseDefault=FALSE
+ColorCursorForeground=#2d2d2d
+ColorCursor=#d3d0c8
+ColorSelectionUseDefault=FALSE
+ColorSelection=#d3d0c8
+ColorSelectionBackground=#515151
+TabActivityColor=#f2777a
+ColorBoldUseDefault=TRUE
+ColorPalette=#2d2d2d;#f2777a;#99cc99;#ffcc66;#6699cc;#cc99cc;#66cccc;#d3d0c8;#747369;#f2777a;#99cc99;#ffcc66;#6699cc;#cc99cc;#66cccc;#f2f0ec;#f99157;#d27b53;#393939;#515151;#a09f93;#e8e6df
diff --git a/colorschemes/out/zsh.zsh b/colorschemes/out/zsh.zsh
new file mode 100644
index 0000000..d159d23
--- /dev/null
+++ b/colorschemes/out/zsh.zsh
@@ -0,0 +1,31 @@
+colorscheme_bg=2d2d2d
+colorscheme_fg=d3d0c8
+colorscheme_cursor_bg=d3d0c8
+colorscheme_cursor_fg=2d2d2d
+colorscheme_selection_bg=515151
+colorscheme_selection_fg=d3d0c8
+colorscheme_link_color=6699cc
+colorscheme_ansi_colors=(
+ 2d2d2d
+ f2777a
+ 99cc99
+ ffcc66
+ 6699cc
+ cc99cc
+ 66cccc
+ d3d0c8
+ 747369
+ f2777a
+ 99cc99
+ ffcc66
+ 6699cc
+ cc99cc
+ 66cccc
+ f2f0ec
+ f99157
+ d27b53
+ 393939
+ 515151
+ a09f93
+ e8e6df
+)
diff --git a/colorschemes/prismjs-theme-src.css b/colorschemes/prismjs-theme-src.css
new file mode 100644
index 0000000..7bdfd8b
--- /dev/null
+++ b/colorschemes/prismjs-theme-src.css
@@ -0,0 +1,123 @@
+/* Based on */
+
+.markdown-body code,
+.markdown-body pre {
+ font-family: 'Ubuntu Mono', monospace;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+}
+
+.markdown-body pre {
+ background-color: var(--dotfiles-colorscheme-bg);
+ color: var(--dotfiles-colorscheme-fg);
+}
+
+.markdown-body pre::-moz-selection,
+.markdown-body pre::selection,
+.markdown-body pre ::-moz-selection,
+.markdown-body pre ::selection {
+ background-color: var(--dotfiles-colorscheme-selection-bg);
+ color: var(--dotfiles-colorscheme-selection-fg);
+}
+
+.token.symbol {
+ color: #905;
+}
+
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.url {
+ text-decoration: underline;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.attr-equals,
+.token.punctuation,
+.token.operator,
+.token.combinator {
+ color: var(--dotfiles-colorscheme-fg);
+}
+
+.token.comment,
+.token.doctype,
+.token.doctype > .token.punctuation,
+.token.cdata,
+.token.cdata > .token.punctuation,
+.token.prolog,
+.token.blockquote,
+.token.hr {
+ color: var(--dotfiles-colorscheme-base-03);
+}
+
+.token.variable,
+.token.parameter,
+.token.constant,
+.token.tag,
+.token.property,
+.token.deleted,
+.token.selector {
+ color: var(--dotfiles-colorscheme-base-08);
+}
+
+.token.boolean,
+.token.number,
+.token.unit,
+.token.attr-name,
+.token.color.hexcode,
+.token.list,
+.token.nil,
+.token.nil.keyword {
+ color: var(--dotfiles-colorscheme-base-09);
+}
+
+.token.class-name,
+.token.maybe-class-name,
+.token.builtin,
+.token.variable.dom,
+.token.macro,
+.token.interpolation-punctuation,
+.language-json .token.property {
+ color: var(--dotfiles-colorscheme-base-0A);
+}
+
+.token.string,
+.token.char,
+.token.attr-value,
+.token.attr-value > .token.punctuation:not(.attr-equals),
+.token.inserted {
+ color: var(--dotfiles-colorscheme-base-0B);
+}
+
+.token.regex,
+.token.pseudo-class,
+.token.pseudo-element,
+.token.entity,
+.token.important {
+ color: var(--dotfiles-colorscheme-base-0C);
+}
+
+.token.function,
+.token.coord,
+.token.url,
+.token.heading,
+.token.title,
+.token.heading > .token.important,
+.token.title > .token.punctuation {
+ color: var(--dotfiles-colorscheme-base-0D);
+}
+
+.token.keyword,
+.token.operator.arrow,
+.token.rule {
+ color: var(--dotfiles-colorscheme-base-0E);
+}
diff --git a/crosscode/btw-i-use-arch-mod/README.md b/crosscode/btw-i-use-arch-mod/README.md
new file mode 100644
index 0000000..4b55718
--- /dev/null
+++ b/crosscode/btw-i-use-arch-mod/README.md
@@ -0,0 +1,4 @@
+The file [`icon24.png`](icon24.png) was cropped from the file
+[`/usr/share/archlinux/web/arch83x31.gif`](file:///usr/share/archlinux/web/arch83x31.gif) of the AUR
+package [`archlinux-artwork`](https://aur.archlinux.org/packages/archlinux-artwork/) and is
+distributed under the CC-BY-NC-SA license.
diff --git a/crosscode/btw-i-use-arch-mod/ccmod.json b/crosscode/btw-i-use-arch-mod/ccmod.json
new file mode 100644
index 0000000..f5a112b
--- /dev/null
+++ b/crosscode/btw-i-use-arch-mod/ccmod.json
@@ -0,0 +1,13 @@
+{
+ "id": "btw-i-use-arch",
+ "title": "btw I use Arch",
+ "description": "A mod for masochists like myself",
+ "icons": {
+ "24": "icon24.png"
+ },
+ "dependencies": {
+ "crosscode-tweak-pack": "*"
+ },
+ "prestart": "prestart.js",
+ "poststart": "poststart.js"
+}
diff --git a/crosscode/btw-i-use-arch-mod/icon24.png b/crosscode/btw-i-use-arch-mod/icon24.png
new file mode 100644
index 0000000..9d83ec3
Binary files /dev/null and b/crosscode/btw-i-use-arch-mod/icon24.png differ
diff --git a/crosscode/btw-i-use-arch-mod/package.json b/crosscode/btw-i-use-arch-mod/package.json
new file mode 100644
index 0000000..fee2c33
--- /dev/null
+++ b/crosscode/btw-i-use-arch-mod/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "btw-i-use-arch",
+ "ccmodHumanName": "btw I use Arch",
+ "description": "A mod for masochists like myself",
+ "dependencies": {
+ "crosscode-tweak-pack": "*"
+ },
+ "prestart": "prestart.js",
+ "main": "poststart.js",
+ "module": true
+}
diff --git a/crosscode/btw-i-use-arch-mod/poststart.js b/crosscode/btw-i-use-arch-mod/poststart.js
new file mode 100644
index 0000000..bf661c6
--- /dev/null
+++ b/crosscode/btw-i-use-arch-mod/poststart.js
@@ -0,0 +1,4 @@
+export {};
+
+ig.input.bind(ig.KEY.J, 'aim');
+ig.input.bind(ig.KEY.K, 'dash');
diff --git a/crosscode/btw-i-use-arch-mod/prestart.js b/crosscode/btw-i-use-arch-mod/prestart.js
new file mode 100644
index 0000000..e69de29
diff --git a/dmitmel-dotfiles b/dmitmel-dotfiles
deleted file mode 160000
index 71a04af..0000000
--- a/dmitmel-dotfiles
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 71a04af8d770235eb5369cd4a3749054a453f6af
diff --git a/git/gitconfig b/git/gitconfig
new file mode 100644
index 0000000..ca5da55
--- /dev/null
+++ b/git/gitconfig
@@ -0,0 +1,27 @@
+[color]
+ ui = true
+
+[pull]
+ rebase = true
+
+[core]
+ pager = diff-so-fancy | less --tabs=4 --RAW-CONTROL-CHARS
+
+[color "diff-highlight"]
+ oldNormal = red bold
+ oldHighlight = red bold 52
+ newNormal = green bold
+ newHighlight = green bold 22
+[color "diff"]
+ meta = yellow
+ frag = magenta bold
+ commit = yellow bold
+ old = red bold
+ new = green bold
+ whitespace = red reverse
+
+[alias]
+ initial-commit = commit --message 'initial commit' --allow-empty
+
+[init]
+ defaultBranch = main
diff --git a/git/gitignore_global b/git/gitignore_global
new file mode 100644
index 0000000..61d9754
--- /dev/null
+++ b/git/gitignore_global
@@ -0,0 +1,6 @@
+Session.vim
+.project.vim
+.DS_Store
+.ropeproject/
+.ccls-cache/
+*~
diff --git a/hammerspoon/.gitignore b/hammerspoon/.gitignore
new file mode 100644
index 0000000..9f2ac48
--- /dev/null
+++ b/hammerspoon/.gitignore
@@ -0,0 +1 @@
+/Spoons/
diff --git a/hammerspoon/TerminalPalette.lua b/hammerspoon/TerminalPalette.lua
new file mode 100644
index 0000000..2f327d4
--- /dev/null
+++ b/hammerspoon/TerminalPalette.lua
@@ -0,0 +1,117 @@
+items = {
+ { text = "clear screen", keys = {{"ctrl","L"}} },
+ { text = "insert mode", keys = {{"ctrl","X"},{"ctrl","O"}} },
+ { text = "undo", keys = {{"ctrl","shift", "-"}} },
+ -- { text = "redo", keys = {{"alt","X"},{"r"},{"e"},{"d"},{"o"},{"return"}} },
+
+ { text = "open command in editor", keys = {{"ctrl","X"},{"ctrl","E"}} },
+ { text = "push input", keys = {{"ctrl","Q"}} },
+ { text = "pop input", keys = {{"alt","G"}} },
+ { text = "run buffer and reuse", keys = {{"alt","G"}} },
+
+ { text = "execute ZLE widget", keys = {{"alt","X"}} },
+ { text = "cancel ZLE widget", keys = {{"ctrl","G"}} },
+
+ { text = "display help for current command", keys = {{"alt","H"}} },
+ { text = "locate current command", keys = {{"alt","shift","?"}} },
+
+ { text = "go to the buffer start", keys = {{"alt","shift","."}} },
+ { text = "go to the buffer end", keys = {{"alt","shift",","}} },
+ { text = "go to the line start", keys = {{"ctrl","A"}} },
+ { text = "go to the line end", keys = {{"ctrl","E"}} },
+ { text = "move one word backward", keys = {{"alt","B"}} },
+ { text = "move one word forward", keys = {{"alt","F"}} },
+ { text = "go to the matching bracket", keys = {{"ctrl","X"},{"ctrl","B"}} },
+
+ { text = "find in previous commands", keys = {{"ctrl","R"}} },
+ { text = "find in following commands", keys = {{"ctrl","S"}} },
+
+ { text = "select", keys = {{"ctrl","shift","2"}} },
+ { text = "cut word", keys = {{"alt","D"}} },
+ { text = "go to selection start/end", keys = {{"ctrl","X"},{"ctrl","X"}} },
+ { text = "cut selected text", keys = {{"alt","W"}} },
+ { text = "quote selected text", keys = {{"alt","shift","'"}} },
+ { text = "paste copied text", keys = {{"ctrl","Y"}} },
+
+ { text = "clear buffer", keys = {{"ctrl","X"},{"ctrl","K"}} },
+ { text = "delete line", keys = {{"ctrl","U"}} },
+ { text = "delete word", keys = {{"ctrl","W"}} },
+
+ { text = "join lines", keys = {{"ctrl","X"},{"ctrl","J"}} },
+
+ { text = "tmux: send Ctrl+B", keys = {{"ctrl","B"},{"ctrl","B"}} },
+ { text = "tmux: command prompt", keys = {{"ctrl","B"},{"shift",";"}} },
+
+ { text = "tmux: rename current session", keys = {{"ctrl","B"},{"shift","4"}} },
+ { text = "tmux: detach", keys = {{"ctrl","B"},{"d"}} },
+ { text = "tmux: sessions", keys = {{"ctrl","B"},{"s"}} },
+ { text = "tmux: next session", keys = {{"ctrl","B"},{")"}} },
+ { text = "tmux: previous session", keys = {{"ctrl","B"},{"("}} },
+ { text = "tmux: last session", keys = {{"ctrl","B"},{"shift","l"}} },
+
+ { text = "tmux: create window", keys = {{"ctrl","B"},{"c"}} },
+ { text = "tmux: switch to window", keys = {{"ctrl","B"}}, message = "press a number key (0-9)" },
+ { text = "tmux: rename current window", keys = {{"ctrl","B"},{","}} },
+ { text = "tmux: kill current window", keys = {{"ctrl","B"},{"shift","7"}} },
+ { text = "tmux: windows", keys = {{"ctrl","B"},{"w"}} },
+ { text = "tmux: next window", keys = {{"ctrl","B"},{"n"}} },
+ { text = "tmux: previous window", keys = {{"ctrl","B"},{"p"}} },
+ { text = "tmux: last window", keys = {{"ctrl","B"},{"l"}} },
+ { text = "tmux: find window", keys = {{"ctrl","B"},{"f"}} },
+
+ { text = "tmux: split horizontally", keys = {{"ctrl","B"},{"shift","'"}} },
+ { text = "tmux: split vertically", keys = {{"ctrl","B"},{"shift","5"}} },
+ { text = "tmux: switch to pane in a direction", keys = {{"ctrl","B"}}, message = "press an arrow key" },
+ { text = "tmux: kill current pane", keys = {{"ctrl","B"},{"x"}} },
+ { text = "tmux: next pane", keys = {{"ctrl","B"},{"o"}} },
+ { text = "tmux: last pane", keys = {{"ctrl","B"},{";"}} },
+ { text = "tmux: toggle pane zoom", keys = {{"ctrl","B"},{"z"}} },
+ { text = "tmux: change pane layout", keys = {{"ctrl","B"},{"space"}} },
+ { text = "tmux: move pane to a new window", keys = {{"ctrl","B"},{"shift","1"}} },
+
+ { text = "tmux: copy mode", keys = {{"ctrl","B"},{"["}} },
+ { text = "tmux: paste", keys = {{"ctrl","B"},{"]"}} },
+}
+
+chooser = hs.chooser.new(function(item)
+ if item then
+ if item.message then hs.alert(item.message) end
+ for _, key_combo in ipairs(item.keys) do
+ hs.eventtap.keyStroke(key_combo.mods, key_combo.key)
+ end
+ end
+end)
+
+chooser:choices(
+ hs.fnutils.imap(items, function(item)
+ subText = table.concat(hs.fnutils.imap(item.keys, function(key_combo)
+ return table.concat(hs.fnutils.imap(key_combo, function(key_stroke)
+ return hs.utf8.registeredKeys[key_stroke] or key_stroke
+ end))
+ end), " ")
+
+ keys = hs.fnutils.imap(item.keys, function(key_combo)
+ mods = {}
+ for i = 1, #key_combo - 1 do mods[i] = key_combo[i] end
+ key = key_combo[#key_combo]
+ return { mods = mods, key = key }
+ end)
+
+ return {
+ text = item.text,
+ subText = subText,
+ keys = keys,
+ message = item.message
+ }
+ end)
+)
+
+chooser:rows(9)
+
+hs.hotkey.bind({"cmd", "shift"}, "a", function()
+ app = hs.application.frontmostApplication()
+ app_name = app:name():lower()
+ if app_name:match("term") or app_name:match("kitty") then
+ chooser:show()
+ end
+end)
diff --git a/hammerspoon/init.lua b/hammerspoon/init.lua
new file mode 100644
index 0000000..47dce16
--- /dev/null
+++ b/hammerspoon/init.lua
@@ -0,0 +1,3 @@
+require "TerminalPalette"
+
+hs.notify.show("Hammerspoon", "", "Hammespoon config loaded")
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..22b40ad
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,8 @@
+sudo hostname KeanuCodespaces
+rm -rf ~/.oh-my-zsh
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
+git clone https://github.com/keanuplayz/dotfiles ~/.dotfiles
+echo "source ~/.dotfiles/zsh/zshrc" >> ~/.zshrc
+pip install colorama psutil distro
+echo "zsh" >> ~/.bashrc
+source ~/.bashrc
\ No newline at end of file
diff --git a/kitty/.gitignore b/kitty/.gitignore
new file mode 100644
index 0000000..4f00cd9
--- /dev/null
+++ b/kitty/.gitignore
@@ -0,0 +1 @@
+/src/
diff --git a/kitty/install.sh b/kitty/install.sh
new file mode 100755
index 0000000..d49af24
--- /dev/null
+++ b/kitty/install.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+
+set -e
+shopt -s nullglob
+
+cd "$(dirname "$0")"
+
+ansi_reset="$(tput sgr0)"
+ansi_bold="$(tput bold)"
+ansi_rev="$(tput rev)"
+log() {
+ echo >&2 "${ansi_bold}${ansi_rev}[$0]${ansi_reset}" "$@"
+}
+
+mkdir -p src
+cd src
+
+log "fetching release information"
+eval "$(
+ curl --show-error --fail https://api.github.com/repos/kovidgoyal/kitty/releases/latest |
+ jq --raw-output '
+ "release_version=" + (.name | sub("^version "; "") | @sh) + "\n" + (
+ .assets | map(select(.label == "Source code")) | first |
+ "release_src_filename=" + (.name | @sh) + "\n" +
+ "release_src_url=" + (.browser_download_url | @sh)
+ )
+ '
+)"
+if [ -z "$release_version" ]; then
+ log "couldn't parse response from GitHub API"
+ exit 1
+fi
+log "the latest version is $release_version"
+
+if [ ! -f "$release_src_filename" ]; then
+ log "downloading $release_src_filename from $release_src_url"
+ curl --show-error --fail --location "$release_src_url" -o "$release_src_filename"
+else
+ log "$release_src_filename has already been downloaded"
+fi
+
+release_src_dir="${release_src_filename%.tar.xz}"
+if [ -d "$release_src_dir" ]; then
+ log "clearing previous source code directory"
+ rm -r "$release_src_dir"
+fi
+
+log "unpacking source code archive to src/$release_src_dir"
+tar --xz -xf "$release_src_filename"
+cd "$release_src_dir"
+
+log "patching"
+for patch in ../../patches/*.patch; do
+ log "applying $(basename "$patch")"
+ patch --unified --strip 0 < "$patch"
+done
+
+log "compiling"
+case "$OSTYPE" in
+ darwin*) make app ;;
+ linux*) python3 setup.py linux-package ;;
+ *) log "error: compilation on $OSTYPE is not supported"; exit 1 ;;
+esac
diff --git a/kitty/kitty.conf b/kitty/kitty.conf
index bf1e1bf..714c9eb 100644
--- a/kitty/kitty.conf
+++ b/kitty/kitty.conf
@@ -1,14 +1,58 @@
-# Include Dima's config.
-include ../dmitmel-dotfiles/kitty/kitty.conf
+include ../colorschemes/out/kitty.conf
-# I sure do love ligatures.
-font_family Fira Code
+# Mouse {{{
+# Disable cursor blinking
+cursor_blink_interval 0
+cursor_stop_blinking_after 0
+mouse_hide_wait 1
+# }}}
-# Remember previous window size. (which will probably always be maximized)
-remember_window_size yes
+# OS Windows {{{
+# Always ask for confirmation before closing OS windows
+confirm_os_window_close 1
+# }}}
-# Disable the stupid bell.
-enable_audio_bell no
+# Windows {{{
+# These are the only layouts I use:
+enabled_layouts horizontal, vertical
+window_margin_width 1.0
+window_padding_width 2.0
+inactive_text_alpha 0.5
+# }}}
-# The block confuses me, shush.
-cursor_shape beam
+# Tabs {{{
+tab_bar_edge top
+tab_bar_style powerline
+# This option doesn't really do anything when the tab bar style is `powerline`,
+# but this Unicode character is a nice find, so let's keep it just in case.
+tab_separator " │ "
+# Always show the tab bar
+tab_bar_min_tabs 1
+active_tab_font_style bold
+inactive_tab_font_style none
+# }}}
+
+# Miscellaneous {{{
+# Tip: on high-DPI screens the `double` style is more discernible
+url_style single
+# }}}
+
+# macOS-specific settings {{{
+macos_option_as_alt yes
+macos_custom_beam_cursor yes
+macos_show_window_title_in window
+# open_url_modifiers cmd
+# }}}
+
+# Keybindings {{{
+map kitty_mod+1 goto_tab 1
+map kitty_mod+2 goto_tab 2
+map kitty_mod+3 goto_tab 3
+map kitty_mod+4 goto_tab 4
+map kitty_mod+5 goto_tab 5
+map kitty_mod+6 goto_tab 6
+map kitty_mod+7 goto_tab 7
+map kitty_mod+8 goto_tab 8
+map kitty_mod+9 goto_tab 9
+map kitty_mod+0 goto_tab 10
+# }}}
diff --git a/kitty/patches/audio_bell.patch b/kitty/patches/audio_bell.patch
new file mode 100644
index 0000000..ebdc8ab
--- /dev/null
+++ b/kitty/patches/audio_bell.patch
@@ -0,0 +1,16 @@
+--- kitty/glfw.c 2019-07-29 07:15:02.000000000 +0300
++++ kitty/glfw.c 2019-08-01 23:38:47.259980678 +0300
+@@ -842,13 +842,9 @@
+ double now = monotonic();
+ if (now - last_bell_at <= 0.1) return;
+ last_bell_at = now;
+-#ifdef __APPLE__
+ if (w->handle) {
+ glfwWindowBell(w->handle);
+ }
+-#else
+- play_canberra_sound("bell", "kitty bell");
+-#endif
+ }
+
+ static PyObject*
diff --git a/kitty/patches/tab_title.patch b/kitty/patches/tab_title.patch
new file mode 100644
index 0000000..d2c0df9
--- /dev/null
+++ b/kitty/patches/tab_title.patch
@@ -0,0 +1,57 @@
+--- kitty/tab_bar.py.orig 2019-11-27 06:25:00.000000000 +0200
++++ kitty/tab_bar.py 2019-11-30 12:07:00.559881682 +0200
+@@ -25,7 +25,7 @@
+ return (x << 8) | 2
+
+
+-def draw_title(draw_data, screen, tab, index):
++def draw_title(draw_data, screen, tab, index, max_title_text_length):
+ if tab.needs_attention and draw_data.bell_on_tab:
+ fg = screen.cursor.fg
+ screen.cursor.fg = draw_data.bell_fg
+@@ -38,19 +38,20 @@
+ draw_title.template_failure_reported = True
+ log_error('Invalid tab title template: "{}" with error: {}'.format(draw_data.title_template, e))
+ title = tab.title
++ extra = len(title) - max_title_text_length
++ if extra > 0:
++ title = '…' + title[1 + extra:]
+ screen.draw(title)
++ return extra
+
+
+ def draw_tab_with_separator(draw_data, screen, tab, before, max_title_length, index, is_last):
+ if draw_data.leading_spaces:
+ screen.draw(' ' * draw_data.leading_spaces)
+- draw_title(draw_data, screen, tab, index)
++ max_title_text_length = max_title_length - draw_data.leading_spaces - draw_data.trailing_spaces
++ draw_title(draw_data, screen, tab, index, max_title_text_length)
+ trailing_spaces = min(max_title_length - 1, draw_data.trailing_spaces)
+ max_title_length -= trailing_spaces
+- extra = screen.cursor.x - before - max_title_length
+- if extra > 0:
+- screen.cursor.x -= extra + 1
+- screen.draw('…')
+ if trailing_spaces:
+ screen.draw(' ' * trailing_spaces)
+ end = screen.cursor.x
+@@ -66,15 +67,12 @@
+ for bg in fade_colors:
+ screen.cursor.bg = bg
+ screen.draw(' ')
+- draw_title(draw_data, screen, tab, index)
+- extra = screen.cursor.x - before - max_title_length
++ max_title_text_length = max_title_length - len(fade_colors) * 2
++ extra = draw_title(draw_data, screen, tab, index, max_title_text_length)
+ if extra > 0:
+ screen.cursor.x = before
+- draw_title(draw_data, screen, tab, index)
+- extra = screen.cursor.x - before - max_title_length
+- if extra > 0:
+- screen.cursor.x -= extra + 1
+- screen.draw('…')
++ max_title_text_length = max_title_length
++ extra = draw_title(draw_data, screen, tab, index, max_title_text_length)
+ for bg in reversed(fade_colors):
+ if extra >= 0:
+ break
diff --git a/misc/gdbinit b/misc/gdbinit
new file mode 100644
index 0000000..2818e64
--- /dev/null
+++ b/misc/gdbinit
@@ -0,0 +1,8 @@
+set disassembly-flavor intel
+set print asm-demangle on
+
+python
+import os
+if 'GDB_OUTPUT_TTY' in os.environ:
+ gdb.execute('tty ' + os.environ['GDB_OUTPUT_TTY'])
+end
diff --git a/misc/rofi.config.rasi b/misc/rofi.config.rasi
new file mode 100644
index 0000000..1305d5e
--- /dev/null
+++ b/misc/rofi.config.rasi
@@ -0,0 +1,5 @@
+configuration {
+ modi: "window,run,drun,ssh";
+ font: "monospace 16";
+ kb-cancel: "Control+g,Control+bracketleft,!Escape";
+}
diff --git a/misc/wgetrc b/misc/wgetrc
new file mode 100644
index 0000000..0d90f7f
--- /dev/null
+++ b/misc/wgetrc
@@ -0,0 +1 @@
+content_disposition = on
diff --git a/misc/yay.config.json b/misc/yay.config.json
new file mode 100644
index 0000000..10d82fa
--- /dev/null
+++ b/misc/yay.config.json
@@ -0,0 +1,6 @@
+{
+ "answerdiff": "All",
+ "completioninterval": 1,
+ "devel": true,
+ "removemake": "yes"
+}
diff --git a/nvim/.gitignore b/nvim/.gitignore
new file mode 100644
index 0000000..43cbc06
--- /dev/null
+++ b/nvim/.gitignore
@@ -0,0 +1 @@
+/spell
diff --git a/nvim/after/ftplugin/asm.vim b/nvim/after/ftplugin/asm.vim
new file mode 100644
index 0000000..dd3c908
--- /dev/null
+++ b/nvim/after/ftplugin/asm.vim
@@ -0,0 +1 @@
+setlocal commentstring=#%s
diff --git a/nvim/after/ftplugin/awk.vim b/nvim/after/ftplugin/awk.vim
new file mode 100644
index 0000000..d7574a4
--- /dev/null
+++ b/nvim/after/ftplugin/awk.vim
@@ -0,0 +1,4 @@
+"
+let &l:makeprg = 'awk --lint --source "BEGIN{exit(0)}END{exit(0)}" --file %:S'
+"
+let &l:errorformat = 'awk: %f:%l: %m'
diff --git a/nvim/after/ftplugin/css.vim b/nvim/after/ftplugin/css.vim
new file mode 100644
index 0000000..df4fe48
--- /dev/null
+++ b/nvim/after/ftplugin/css.vim
@@ -0,0 +1 @@
+setlocal iskeyword+=-
diff --git a/nvim/after/ftplugin/diff.vim b/nvim/after/ftplugin/diff.vim
new file mode 100644
index 0000000..ab49c88
--- /dev/null
+++ b/nvim/after/ftplugin/diff.vim
@@ -0,0 +1 @@
+setlocal nofoldenable foldmethod=manual
diff --git a/nvim/after/ftplugin/fugitive.vim b/nvim/after/ftplugin/fugitive.vim
new file mode 100644
index 0000000..ab49c88
--- /dev/null
+++ b/nvim/after/ftplugin/fugitive.vim
@@ -0,0 +1 @@
+setlocal nofoldenable foldmethod=manual
diff --git a/nvim/after/ftplugin/haskell.vim b/nvim/after/ftplugin/haskell.vim
new file mode 100644
index 0000000..8d98c34
--- /dev/null
+++ b/nvim/after/ftplugin/haskell.vim
@@ -0,0 +1 @@
+setlocal foldmethod< foldtext<
diff --git a/nvim/after/ftplugin/html.vim b/nvim/after/ftplugin/html.vim
new file mode 100644
index 0000000..e0a2437
--- /dev/null
+++ b/nvim/after/ftplugin/html.vim
@@ -0,0 +1 @@
+nnoremap Open
diff --git a/nvim/after/ftplugin/javascript.vim b/nvim/after/ftplugin/javascript.vim
new file mode 100644
index 0000000..d4217f4
--- /dev/null
+++ b/nvim/after/ftplugin/javascript.vim
@@ -0,0 +1 @@
+setlocal matchpairs-=<:>
diff --git a/nvim/after/ftplugin/javascriptreact.vim b/nvim/after/ftplugin/javascriptreact.vim
new file mode 100644
index 0000000..2d9e54a
--- /dev/null
+++ b/nvim/after/ftplugin/javascriptreact.vim
@@ -0,0 +1 @@
+source :h/javascript.vim
diff --git a/nvim/after/ftplugin/kivy.vim b/nvim/after/ftplugin/kivy.vim
new file mode 100644
index 0000000..08d6c41
--- /dev/null
+++ b/nvim/after/ftplugin/kivy.vim
@@ -0,0 +1 @@
+IndentTabs 4
diff --git a/nvim/after/ftplugin/mail.vim b/nvim/after/ftplugin/mail.vim
new file mode 100644
index 0000000..5138151
--- /dev/null
+++ b/nvim/after/ftplugin/mail.vim
@@ -0,0 +1 @@
+source :h/text.vim
diff --git a/nvim/after/ftplugin/make.vim b/nvim/after/ftplugin/make.vim
new file mode 100644
index 0000000..b3d732f
--- /dev/null
+++ b/nvim/after/ftplugin/make.vim
@@ -0,0 +1 @@
+IndentTabs 2
diff --git a/nvim/after/ftplugin/markdown.vim b/nvim/after/ftplugin/markdown.vim
new file mode 100644
index 0000000..94e958b
--- /dev/null
+++ b/nvim/after/ftplugin/markdown.vim
@@ -0,0 +1,5 @@
+source :h/text.vim
+
+let &l:makeprg = 'markdown2htmldoc -- %:S %:S.html'
+
+nnoremap Open %.html
diff --git a/nvim/after/ftplugin/mediawiki.vim b/nvim/after/ftplugin/mediawiki.vim
new file mode 100644
index 0000000..5138151
--- /dev/null
+++ b/nvim/after/ftplugin/mediawiki.vim
@@ -0,0 +1 @@
+source :h/text.vim
diff --git a/nvim/after/ftplugin/rust.vim b/nvim/after/ftplugin/rust.vim
new file mode 100644
index 0000000..d4217f4
--- /dev/null
+++ b/nvim/after/ftplugin/rust.vim
@@ -0,0 +1 @@
+setlocal matchpairs-=<:>
diff --git a/nvim/after/ftplugin/sass.vim b/nvim/after/ftplugin/sass.vim
new file mode 100644
index 0000000..6e88f83
--- /dev/null
+++ b/nvim/after/ftplugin/sass.vim
@@ -0,0 +1 @@
+source :h/scss.vim
diff --git a/nvim/after/ftplugin/scss.vim b/nvim/after/ftplugin/scss.vim
new file mode 100644
index 0000000..db198fe
--- /dev/null
+++ b/nvim/after/ftplugin/scss.vim
@@ -0,0 +1,3 @@
+source :h/css.vim
+
+let &l:makeprg = 'sass -- %:S:%:S.css'
diff --git a/nvim/after/ftplugin/text.vim b/nvim/after/ftplugin/text.vim
new file mode 100644
index 0000000..8b66a8f
--- /dev/null
+++ b/nvim/after/ftplugin/text.vim
@@ -0,0 +1,5 @@
+call pencil#init()
+IndentLinesDisable
+" Reset these mappings to their default function (jumping over sentences):
+noremap ( (
+noremap ) )
diff --git a/nvim/after/ftplugin/typescript.vim b/nvim/after/ftplugin/typescript.vim
new file mode 100644
index 0000000..2d9e54a
--- /dev/null
+++ b/nvim/after/ftplugin/typescript.vim
@@ -0,0 +1 @@
+source :h/javascript.vim
diff --git a/nvim/after/ftplugin/typescriptreact.vim b/nvim/after/ftplugin/typescriptreact.vim
new file mode 100644
index 0000000..6a77e28
--- /dev/null
+++ b/nvim/after/ftplugin/typescriptreact.vim
@@ -0,0 +1 @@
+source :h/typescript.vim
diff --git a/nvim/after/ftplugin/vim.vim b/nvim/after/ftplugin/vim.vim
new file mode 100644
index 0000000..aa6f680
--- /dev/null
+++ b/nvim/after/ftplugin/vim.vim
@@ -0,0 +1 @@
+nnoremap source %
diff --git a/nvim/after/syntax/cabal.vim b/nvim/after/syntax/cabal.vim
new file mode 100644
index 0000000..8d98c34
--- /dev/null
+++ b/nvim/after/syntax/cabal.vim
@@ -0,0 +1 @@
+setlocal foldmethod< foldtext<
diff --git a/nvim/after/syntax/cabalconfig.vim b/nvim/after/syntax/cabalconfig.vim
new file mode 100644
index 0000000..8d98c34
--- /dev/null
+++ b/nvim/after/syntax/cabalconfig.vim
@@ -0,0 +1 @@
+setlocal foldmethod< foldtext<
diff --git a/nvim/after/syntax/javascript.vim b/nvim/after/syntax/javascript.vim
new file mode 100644
index 0000000..4a253a1
--- /dev/null
+++ b/nvim/after/syntax/javascript.vim
@@ -0,0 +1 @@
+syntax sync minlines=500
diff --git a/nvim/after/syntax/json.vim b/nvim/after/syntax/json.vim
new file mode 100644
index 0000000..2775816
--- /dev/null
+++ b/nvim/after/syntax/json.vim
@@ -0,0 +1 @@
+syntax match Comment +\/\/.\+$+
diff --git a/nvim/after/syntax/nginx.vim b/nvim/after/syntax/nginx.vim
new file mode 100644
index 0000000..bf72a83
--- /dev/null
+++ b/nvim/after/syntax/nginx.vim
@@ -0,0 +1,7 @@
+" Guess what. The `syntax/jinja.vim` script for the jinja templating language,
+" which is not included in neither Vim's runtime, nor Neovim's runtime, nor in
+" vim-polyglot (so the only way to get it is to install the python package) is
+" sourced in `syntax/nginx.vim` in vim-polyglot, which resets the `commentstring`
+" set in `ftplugin/nginx.vim` and sets `comments` to some garbage. This script
+" undoes that damage.
+setlocal comments< commentstring=#%s
diff --git a/nvim/after/syntax/po.vim b/nvim/after/syntax/po.vim
new file mode 100644
index 0000000..d345d77
--- /dev/null
+++ b/nvim/after/syntax/po.vim
@@ -0,0 +1 @@
+setl commentstring=#%s
diff --git a/nvim/after/syntax/python.vim b/nvim/after/syntax/python.vim
new file mode 100644
index 0000000..2b6c632
--- /dev/null
+++ b/nvim/after/syntax/python.vim
@@ -0,0 +1,2 @@
+syn keyword pythonOperatorKeyword and in is not or
+hi def link pythonOperatorKeyword Keyword
diff --git a/nvim/after/syntax/rust.vim b/nvim/after/syntax/rust.vim
new file mode 100644
index 0000000..9d961c2
--- /dev/null
+++ b/nvim/after/syntax/rust.vim
@@ -0,0 +1,2 @@
+syn keyword rustOperatorKeyword as
+hi def link rustOperatorKeyword Keyword
diff --git a/nvim/after/syntax/typescript.vim b/nvim/after/syntax/typescript.vim
new file mode 100644
index 0000000..2d9e54a
--- /dev/null
+++ b/nvim/after/syntax/typescript.vim
@@ -0,0 +1 @@
+source :h/javascript.vim
diff --git a/nvim/after/syntax/typescriptreact.vim b/nvim/after/syntax/typescriptreact.vim
new file mode 100644
index 0000000..6a77e28
--- /dev/null
+++ b/nvim/after/syntax/typescriptreact.vim
@@ -0,0 +1 @@
+source :h/typescript.vim
diff --git a/nvim/autoload/airline/extensions/dotfiles_coclist.vim b/nvim/autoload/airline/extensions/dotfiles_coclist.vim
new file mode 100644
index 0000000..0e355ae
--- /dev/null
+++ b/nvim/autoload/airline/extensions/dotfiles_coclist.vim
@@ -0,0 +1,126 @@
+if !exists('g:did_coc_loaded')
+ finish
+endif
+
+function! airline#extensions#dotfiles_coclist#init(ext) abort
+ let g:coc_user_config['list.statusLineSegments'] = v:null
+
+ call a:ext.add_statusline_func('airline#extensions#dotfiles_coclist#apply')
+ call a:ext.add_inactive_statusline_func('airline#extensions#dotfiles_coclist#apply')
+
+ call airline#parts#define('dotfiles_coclist_mode', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_mode',
+ \ 'accent': 'bold',
+ \ })
+ call airline#parts#define('dotfiles_coclist_args', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_args',
+ \ })
+ call airline#parts#define('dotfiles_coclist_name', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_name',
+ \ })
+ call airline#parts#define('dotfiles_coclist_cwd', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_cwd',
+ \ })
+ call airline#parts#define('dotfiles_coclist_loading', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_loading',
+ \ })
+ call airline#parts#define('dotfiles_coclist_total', {
+ \ 'function': 'airline#extensions#dotfiles_coclist#part_total',
+ \ })
+
+ " Default airline section setup:
+ "
+ " Beware that whitespaces in function expansions can cause some weirdness:
+ "
+ let s:section_a = airline#section#create_left(['dotfiles_coclist_mode'])
+ let s:section_b = airline#section#create(['dotfiles_coclist_name'])
+ let s:section_c = airline#section#create(['%<', 'dotfiles_coclist_args', ' ', 'dotfiles_coclist_loading'])
+ let s:section_x = airline#section#create(['dotfiles_coclist_cwd'])
+ let s:section_y = airline#section#create(['#%L/', 'dotfiles_coclist_total'])
+ let s:section_z = airline#section#create(['%p%%', 'linenr', 'maxlinenr'])
+endfunction
+
+function! airline#extensions#dotfiles_coclist#statusline() abort
+ let context = { 'winnr': winnr(), 'active': 1, 'bufnr': bufnr() }
+ let builder = airline#builder#new(context)
+ call airline#extensions#dotfiles_coclist#apply(builder, context)
+ return builder.build()
+endfunction
+
+function! airline#extensions#dotfiles_coclist#apply(builder, context) abort
+ if getbufvar(a:context.bufnr, '&filetype', '') !=# 'list' | return 0 | endif
+ let list_status = getbufvar(a:context.bufnr, 'list_status', 0)
+ if type(list_status) !=# v:t_dict | return 0 | endif
+
+ " How b:list_status is populated:
+ "
+ " How the list buffer is created:
+ "
+ " The default statusline:
+ "
+ " How airline generates its actual statuslines:
+ "
+ "
+ "
+
+ let spc = g:airline_symbols.space
+ if a:context.active || (!a:context.active && !g:airline_inactive_collapse)
+ call a:builder.add_section('airline_a', s:get_section('a'))
+ call a:builder.add_section('airline_b', s:get_section('b'))
+ endif
+ call a:builder.add_section('airline_c', s:get_section('c'))
+ call a:builder.split()
+ call a:builder.add_section('airline_x', s:get_section('x'))
+ call a:builder.add_section('airline_y', s:get_section('y'))
+ call a:builder.add_section('airline_z', s:get_section('z'))
+
+ return 1
+endfunction
+
+" Copied from
+let s:section_truncate_width = get(g:, 'airline#extensions#default#section_truncate_width', {
+\ 'b': 79,
+\ 'x': 60,
+\ 'y': 88,
+\ 'z': 45,
+\ })
+
+function! s:get_section(key) abort
+ if has_key(s:section_truncate_width, a:key) && airline#util#winwidth() < s:section_truncate_width[a:key]
+ return ''
+ endif
+ let spc = g:airline_symbols.space
+ let text = s:section_{a:key}
+ if empty(text) | return '' | endif
+ return '%(' . spc . text . spc . '%)'
+endfunction
+
+" TODO: Is recoloring of the section A based on `b:list_status.mode` possible?
+function! airline#extensions#dotfiles_coclist#part_mode() abort
+ if get(w:, 'airline_active', 1)
+ "
+ return airline#util#shorten(get(b:list_status, 'mode', ''), 79, 1)
+ else
+ return get(g:airline_mode_map, '__')
+ else
+endfunction
+
+function! airline#extensions#dotfiles_coclist#part_args() abort
+ return get(b:list_status, 'args', '')
+endfunction
+
+function! airline#extensions#dotfiles_coclist#part_name() abort
+ return get(b:list_status, 'name', '')
+endfunction
+
+function! airline#extensions#dotfiles_coclist#part_loading() abort
+ return get(b:list_status, 'loading', '')
+endfunction
+
+function! airline#extensions#dotfiles_coclist#part_total() abort
+ return get(b:list_status, 'total', '')
+endfunction
+
+function! airline#extensions#dotfiles_coclist#part_cwd() abort
+ return pathshorten(fnamemodify(get(b:list_status, 'cwd', ''), ':~:.'))
+endfunction
diff --git a/nvim/autoload/airline/extensions/dotfiles_filesize.vim b/nvim/autoload/airline/extensions/dotfiles_filesize.vim
new file mode 100644
index 0000000..aa52fcd
--- /dev/null
+++ b/nvim/autoload/airline/extensions/dotfiles_filesize.vim
@@ -0,0 +1,43 @@
+" Based on
+
+function! airline#extensions#dotfiles_filesize#init(ext) abort
+ call airline#parts#define_function('dotfiles_filesize', 'airline#extensions#dotfiles_filesize#get')
+ call a:ext.add_statusline_func('airline#extensions#dotfiles_filesize#apply')
+endfunction
+
+function! airline#extensions#dotfiles_filesize#apply(...) abort
+ call airline#extensions#append_to_section('y', airline#section#create_right(['', '', 'dotfiles_filesize']))
+endfunction
+
+" Finally, this function will be invoked from the statusline.
+function! airline#extensions#dotfiles_filesize#get() abort
+ " Use several preliminary checks to prevent frequent updates. You see,
+ " wordcount() has to iterate the entire file to calculate its byte size.
+ "
+ "
+ " Implementation of wordcount:
+ if empty(get(b:, 'dotfiles_filesize_str', '')) ||
+ \ (get(b:, 'dotfiles_filesize_changedtick', 0) !=# b:changedtick &&
+ \ reltimefloat(reltime()) - get(b:, 'dotfiles_filesize_timer') >=# get(g:, 'airline#extensions#dotfiles_filesize#update_delay', 0))
+ let bytes = wordcount().bytes
+ let b:dotfiles_filesize = bytes
+
+ let factor = 1
+ for unit in ['B', 'K', 'M', 'G']
+ let next_factor = factor * 1024
+ if bytes <# next_factor
+ let number_str = printf('%.2f', (bytes * 1.0) / factor)
+ " remove trailing zeros
+ let number_str = substitute(number_str, '\v(\.0*)=$', '', '')
+ let b:dotfiles_filesize_str = number_str . unit
+ break
+ endif
+ let factor = next_factor
+ endfor
+
+ let b:dotfiles_filesize_changedtick = b:changedtick
+ let b:dotfiles_filesize_timer = reltimefloat(reltime())
+ endif
+
+ return b:dotfiles_filesize_str
+endfunction
diff --git a/nvim/autoload/airline/extensions/dotfiles_tweaks.vim b/nvim/autoload/airline/extensions/dotfiles_tweaks.vim
new file mode 100644
index 0000000..ee76228
--- /dev/null
+++ b/nvim/autoload/airline/extensions/dotfiles_tweaks.vim
@@ -0,0 +1,7 @@
+function! airline#extensions#dotfiles_tweaks#init(ext) abort
+ " Undo this commit a little bit:
+ "
+ " Most of the hacks present here are not required anymore:
+ "
+ call airline#parts#define_accent('colnr', 'none')
+endfunction
diff --git a/nvim/autoload/airline/themes/dotfiles.vim b/nvim/autoload/airline/themes/dotfiles.vim
new file mode 100644
index 0000000..a1ebe81
--- /dev/null
+++ b/nvim/autoload/airline/themes/dotfiles.vim
@@ -0,0 +1,59 @@
+let s:palette = {
+\ "inactive" : {},
+\ "replace" : {},
+\ "normal" : {},
+\ "visual" : {},
+\ "insert" : {},
+\ "terminal" : {},
+\ "commandline" : {},
+\ }
+
+let s:colors = g:dotfiles_colorscheme_base16_colors
+function! s:base16_color(fg, bg) abort
+ let fg = s:colors[a:fg]
+ let bg = s:colors[a:bg]
+ return [fg.gui, bg.gui, fg.cterm, bg.cterm]
+endfunction
+
+let s:section_a = s:base16_color(0x1, 0xB)
+let s:section_b = s:base16_color(0x6, 0x2)
+let s:section_c = s:base16_color(0x9, 0x1)
+let s:palette.normal = airline#themes#generate_color_map(
+\ s:section_a,
+\ s:section_b,
+\ s:section_c)
+
+let s:section_a_overrides = {
+\ 'insert' : s:base16_color(0x1, 0xD),
+\ 'visual' : s:base16_color(0x1, 0xE),
+\ 'replace' : s:base16_color(0x1, 0x8),
+\ 'terminal' : s:base16_color(0x1, 0xD),
+\ 'commandline' : s:base16_color(0x1, 0xC),
+\ }
+for [s:mode, s:color] in items(s:section_a_overrides)
+ let s:palette[s:mode] = { 'airline_a': s:color, 'airline_z': s:color }
+endfor
+
+let s:section_inactive = s:base16_color(0x5, 0x1)
+let s:palette.inactive = airline#themes#generate_color_map(
+\ s:section_inactive,
+\ s:section_inactive,
+\ s:section_inactive)
+
+if get(g:, 'loaded_ctrlp', 0)
+ let s:ctrlp_dark = s:base16_color(0x7, 0x2)
+ let s:ctrlp_light = s:base16_color(0x7, 0x4)
+ let s:ctrlp_white = s:base16_color(0x5, 0x1) + ['bold']
+ let s:palette.ctrlp = airline#extensions#ctrlp#generate_color_map(
+ \ s:ctrlp_dark,
+ \ s:ctrlp_light,
+ \ s:ctrlp_white)
+endif
+
+for s:mode in keys(s:palette)
+ let s:palette[s:mode]['airline_warning'] = s:base16_color(0x0, 0xA)
+ let s:palette[s:mode]['airline_error'] = s:base16_color(0x0, 0x8)
+ let s:palette[s:mode]['airline_term'] = s:base16_color(0x9, 0x1)
+endfor
+
+let airline#themes#dotfiles#palette = s:palette
diff --git a/nvim/autoload/dotfiles/fugitive/aur.vim b/nvim/autoload/dotfiles/fugitive/aur.vim
new file mode 100644
index 0000000..18df068
--- /dev/null
+++ b/nvim/autoload/dotfiles/fugitive/aur.vim
@@ -0,0 +1,84 @@
+" Based on
+" Also see .
+" Other intersting links:
+"
+"
+"
+"
+"
+"
+function! dotfiles#fugitive#aur#handler(opts) abort
+ if type(a:opts) != v:t_dict
+ return ''
+ endif
+ let opts = a:opts
+
+ let parsed = dotfiles#fugitive#aur#parse_url(get(opts, 'remote', ''))
+ if empty(parsed)
+ return ''
+ endif
+
+ let path = substitute(opts.path, '^/', '', '')
+ if path =~# '^\.git/refs/heads/'
+ let branch = path[16:-1]
+ " AUR packages can have only a single branch, master, as it is mapped to
+ " the branch named after the package in the central Git repository.
+ if branch ==# 'master'
+ return parsed.cgit_prefix . '/log/' . parsed.cgit_suffix
+ endif
+ return ''
+ elseif path =~# '^\.git/refs/tags/'
+ " Tags are not allowed for AUR packages.
+ let tag = path[15:-1]
+ return ''
+ elseif path =~# '^\.git/refs/remotes/[^/]\+/.'
+ let remote_branch = matchstr(path[18:-1], '^[^/]\+/\zs.*$')
+ " Same story as with regular branches.
+ if remote_branch ==# 'master'
+ return parsed.cgit_prefix . '/log/' . parsed.cgit_suffix
+ endif
+ return ''
+ elseif path =~# '^\.git/'
+ return parsed.cgit_prefix . '/' . parsed.cgit_suffix
+ endif
+
+ if opts.commit =~# '^\d\=$'
+ return ''
+ elseif expand('%') =~? '^fugitive:'
+ let commit = opts.commit
+ else
+ let commit = a:opts.repo.rev_parse('HEAD')
+ endif
+
+ let line = min([opts.line1, opts.line2])
+ let parsed.cgit_suffix .= '&id=' . substitute(commit, '#', '%23', 'g')
+ if opts.type ==# 'blob' || opts.type ==# 'tree'
+ return parsed.cgit_prefix . '/tree/' . substitute(path, '/$', '', 'g') . parsed.cgit_suffix . (line ? '#n'.line : '')
+ elseif opts.type ==# 'commit' || opts.type ==# 'tag'
+ return parsed.cgit_prefix . '/commit/' . parsed.cgit_suffix
+ endif
+
+ return ''
+endfunction
+
+
+" Based on
+" and .
+" Also see .
+function! dotfiles#fugitive#aur#parse_url(url) abort
+ let intro_re = '%(https=|git|ssh)\://%([^/@]+\@)='
+ let domain_re = 'aur\.archlinux\.org'
+ let repo_path_re = '[a-zA-Z0-9][a-zA-Z0-9_\.\+\-]{-}'
+ let outro_re = '%(\.git)=/='
+ let combined_re = '\v^'.intro_re.'\zs('.domain_re.')/('.repo_path_re.')\ze'.outro_re.'$'
+ let matches = matchlist(a:url, combined_re)
+ if empty(matches)
+ return {}
+ endif
+ let domain = matches[1]
+ let package = matches[2]
+ let homepage = 'https://'.domain.'/pkgbase/'.package
+ let cgit_prefix = 'https://'.domain.'/cgit/aur.git'
+ let cgit_suffix = '?h='.package
+ return {'domain': domain, 'package': package, 'homepage': homepage, 'cgit_prefix': cgit_prefix, 'cgit_suffix': cgit_suffix}
+endfunction
diff --git a/nvim/autoload/dotfiles/indent_motion.vim b/nvim/autoload/dotfiles/indent_motion.vim
new file mode 100644
index 0000000..42ab37d
--- /dev/null
+++ b/nvim/autoload/dotfiles/indent_motion.vim
@@ -0,0 +1,63 @@
+" Based on
+" A motion for moving over enclosing indentation blocks. Primarily intended
+" for reverse-engineering CrossCode.
+
+function! dotfiles#indent_motion#run(direction) abort
+ let cursor_linenr = line(".")
+ let max_linenr = line("$")
+
+ let retry = 0
+ while retry <# 2
+ let retry += 1
+
+ let base_linenr = cursor_linenr
+ let base_indent = 0
+ while 1 <=# base_linenr && base_linenr <=# max_linenr
+ let base_indent = dotfiles#indent_motion#indent_level_of(base_linenr)
+ if base_indent >=# 0
+ break
+ endif
+ let base_linenr += a:direction
+ endwhile
+
+ let target_linenr = base_linenr
+
+ let curr_linenr = base_linenr + a:direction
+ let prev_indent = base_indent
+ while 1 <=# curr_linenr && curr_linenr <=# max_linenr
+ let indent = dotfiles#indent_motion#indent_level_of(curr_linenr)
+
+ if indent >=# 0
+ if indent <# base_indent
+ break
+ else
+ let target_linenr = curr_linenr
+ endif
+ elseif base_indent ==# 0 && prev_indent ==# 0
+ break
+ endif
+
+ let prev_indent = indent
+ let curr_linenr += a:direction
+ endwhile
+
+ if target_linenr ==# cursor_linenr
+ let cursor_linenr += a:direction
+ if 1 <=# cursor_linenr && cursor_linenr <=# max_linenr
+ continue
+ endif
+ endif
+
+ break
+ endwhile
+
+ execute "normal! " . target_linenr . "G^"
+endfunction
+
+"
+function! dotfiles#indent_motion#indent_level_of(linenr) abort
+ if getline(a:linenr) ==# ""
+ return -1
+ endif
+ return indent(a:linenr)
+endfunction
diff --git a/nvim/autoload/dotfiles/utils.vim b/nvim/autoload/dotfiles/utils.vim
new file mode 100644
index 0000000..b96de6e
--- /dev/null
+++ b/nvim/autoload/dotfiles/utils.vim
@@ -0,0 +1,6 @@
+function! dotfiles#utils#array_remove_element(array, element) abort
+ let index = index(a:array, a:element)
+ if index >= 0
+ call remove(a:array, index)
+ endif
+endfunction
diff --git a/nvim/coc-languages/c.vim b/nvim/coc-languages/c.vim
new file mode 100644
index 0000000..6b3e983
--- /dev/null
+++ b/nvim/coc-languages/c.vim
@@ -0,0 +1,17 @@
+let s:filetypes = ['c', 'cpp', 'objc', 'objcpp']
+let g:coc_filetypes += s:filetypes
+
+let g:coc_user_config['languageserver.ccls'] = {
+\ 'filetypes': s:filetypes,
+\ 'command': 'ccls',
+\ 'rootPatterns': ['.ccls', 'compile_commands.json', '.vim/', '.git/', '.hg/'],
+\ 'initializationOptions': {
+\ 'cache.directory': tempname(),
+\ },
+\ }
+
+" let g:coc_user_config['languageserver.clangd'] = {
+" \ 'filetypes': s:filetypes,
+" \ 'command': 'clangd',
+" \ 'rootPatterns': ['compile_flags.txt', 'compile_commands.json', '.vim/', '.git/', '.hg/'],
+" \ }
diff --git a/nvim/coc-languages/css.vim b/nvim/coc-languages/css.vim
new file mode 100644
index 0000000..aedd28e
--- /dev/null
+++ b/nvim/coc-languages/css.vim
@@ -0,0 +1,2 @@
+let g:coc_global_extensions += ['coc-css']
+let g:coc_filetypes += ['css', 'scss', 'less']
diff --git a/nvim/coc-languages/haskell.vim b/nvim/coc-languages/haskell.vim
new file mode 100644
index 0000000..a80de3e
--- /dev/null
+++ b/nvim/coc-languages/haskell.vim
@@ -0,0 +1,8 @@
+let s:filetypes = ['haskell', 'lhaskell', 'chaskell']
+let g:coc_filetypes += s:filetypes
+let g:coc_user_config['languageserver.haskell'] = {
+\ 'filetypes': s:filetypes,
+\ 'command': 'hie-wrapper',
+\ 'rootPatterns': ['.stack.yaml', 'cabal.config', 'package.yaml'],
+\ 'initializationOptions': {},
+\ }
diff --git a/nvim/coc-languages/html.vim b/nvim/coc-languages/html.vim
new file mode 100644
index 0000000..700fbf4
--- /dev/null
+++ b/nvim/coc-languages/html.vim
@@ -0,0 +1,4 @@
+let g:coc_global_extensions += ['coc-html', 'coc-emmet']
+let s:emmet_filetype_mapping = { 'jinja': 'html' }
+let g:coc_filetypes += ['html'] + keys(s:emmet_filetype_mapping)
+let g:coc_user_config['emmet.includeLanguages'] = s:emmet_filetype_mapping
diff --git a/nvim/coc-languages/javascript.vim b/nvim/coc-languages/javascript.vim
new file mode 100644
index 0000000..0356ad9
--- /dev/null
+++ b/nvim/coc-languages/javascript.vim
@@ -0,0 +1,23 @@
+let g:coc_global_extensions += ['coc-tsserver', 'coc-eslint', 'coc-prettier']
+let s:filetypes = ['javascript', 'javascriptreact', 'typescript', 'typescriptreact']
+let g:coc_filetypes += s:filetypes
+let g:coc_user_config['eslint'] = {
+\ 'filetypes': s:filetypes,
+\ 'autoFixOnSave': v:true,
+\ }
+" See
+let g:coc_user_config['prettier'] = {
+\ 'printWidth': 100,
+\ 'tabWidth': 2,
+\ 'useTabs': v:false,
+\ 'semi': v:true,
+\ 'singleQuote': v:true,
+\ 'quoteProps': 'as-needed',
+\ 'jsxSingleQuote': v:false,
+\ 'trailingComma': 'all',
+\ 'bracketSpacing': v:true,
+\ 'jsxBracketSameLine': v:true,
+\ 'arrowParens': 'always',
+\ 'proseWrap': 'preserve',
+\ 'disableSuccessMessage': v:true,
+\ }
diff --git a/nvim/coc-languages/json.vim b/nvim/coc-languages/json.vim
new file mode 100644
index 0000000..d875e3c
--- /dev/null
+++ b/nvim/coc-languages/json.vim
@@ -0,0 +1,2 @@
+let g:coc_global_extensions += ['coc-json']
+let g:coc_filetypes += ['json', 'json5']
diff --git a/nvim/coc-languages/lua.vim b/nvim/coc-languages/lua.vim
new file mode 100644
index 0000000..e68ab5d
--- /dev/null
+++ b/nvim/coc-languages/lua.vim
@@ -0,0 +1,3 @@
+let g:coc_global_extensions += ['coc-lua']
+let s:filetypes = ['lua']
+let g:coc_filetypes += s:filetypes
diff --git a/nvim/coc-languages/markdown.vim b/nvim/coc-languages/markdown.vim
new file mode 100644
index 0000000..7234c40
--- /dev/null
+++ b/nvim/coc-languages/markdown.vim
@@ -0,0 +1 @@
+let g:coc_filetypes += ['markdown']
diff --git a/nvim/coc-languages/python.vim b/nvim/coc-languages/python.vim
new file mode 100644
index 0000000..c6a7357
--- /dev/null
+++ b/nvim/coc-languages/python.vim
@@ -0,0 +1,17 @@
+let g:coc_global_extensions += ['coc-pyright']
+let g:coc_filetypes += ['python']
+
+let g:coc_user_config['python'] = {
+\ 'formatting': {
+\ 'provider': 'yapf',
+\ 'yapfArgs': ['--style=' . simplify(g:dotfiles_dir.'/python/yapf.ini')],
+\ },
+\ 'linting': {
+\ 'pylintEnabled': v:false,
+\ 'flake8Enabled': v:true,
+\ 'flake8Args': ['--config=' . simplify(g:dotfiles_dir.'/python/flake8.ini')],
+\ },
+\ 'analysis': {
+\ 'typeCheckingMode': 'strict',
+\ },
+\ }
diff --git a/nvim/coc-languages/rust.vim b/nvim/coc-languages/rust.vim
new file mode 100644
index 0000000..8deabe8
--- /dev/null
+++ b/nvim/coc-languages/rust.vim
@@ -0,0 +1,15 @@
+let g:coc_filetypes += ['rust']
+let g:coc_global_extensions += ['coc-rust-analyzer']
+let g:coc_user_config['rust-analyzer'] = {
+\ 'serverPath': 'rust-analyzer',
+\ 'lens.enable': v:false,
+\ 'inlayHints.typeHints': v:false,
+\ 'inlayHints.chainingHints': v:false,
+\ 'diagnostics.enable': v:false,
+\ 'completion.autoimport.enable': v:false,
+\ 'checkOnSave.command': 'clippy',
+\ 'cargo.loadOutDirsFromCheck': v:true,
+\ }
+
+" let g:coc_global_extensions += ['coc-rls']
+" let g:coc_user_config['rust'] = { 'clippy_preference': 'on' }
diff --git a/nvim/coc-languages/sh.vim b/nvim/coc-languages/sh.vim
deleted file mode 100644
index 293dd51..0000000
--- a/nvim/coc-languages/sh.vim
+++ /dev/null
@@ -1,2 +0,0 @@
-let g:coc_global_extensions += ['coc-sh']
-let g:coc_filetypes += ['sh', 'zsh']
diff --git a/nvim/coc-languages/vim.vim b/nvim/coc-languages/vim.vim
new file mode 100644
index 0000000..247de75
--- /dev/null
+++ b/nvim/coc-languages/vim.vim
@@ -0,0 +1,55 @@
+" This plugin ended up being useless.
+finish
+
+let s:filetypes = ['vim']
+let g:coc_filetypes += s:filetypes
+
+let g:coc_global_extensions += ['coc-vimlsp']
+let g:coc_user_config['vimlsp'] = {
+\ 'suggest.fromRuntimepath': v:true,
+\ }
+
+" The coc-vimlsp plugin is basically reimplemented here because it doesn't do
+" much beyond just wrapping the language server and passing some init options,
+" but having two processes (plugin+LSP) almost doubles the memory usage.
+"
+" On a second thought... Apparently that's just how this extension works...
+" Either way it spawns two processes (with the controller process having
+" roughly the same memory usage regardless of being in a coc extension). And
+" having updates through :CocUpdate is nice, so I'm gonna use the coc-vimlsp
+" plugin itself. The janky reimplementation is left in this file for better
+" times and bragging purposes.
+finish
+
+"
+" workspace.isNvim:
+let g:coc_user_config['languageserver.vimls'] = {
+\ 'filetypes': s:filetypes,
+\ 'command': 'vim-language-server',
+\ 'args': ['--stdio'],
+\ 'initializationOptions': {
+\ 'isNeovim': has('nvim'),
+\ 'iskeyword': &iskeyword,
+\ 'vimruntime': $VIMRUNTIME,
+\ 'runtimepath': &runtimepath,
+\ 'suggest.fromRuntimepath': v:true,
+\ },
+\ }
+
+augroup dotfiles-coc-vimls
+ autocmd!
+
+ " NOTE: Apparently delaying runtimepath initialization even until VimEnter
+ " is not enough, as coc-snippets adds its plugin to rtp during coc
+ " intialization phase which happens sometime after VimEnter[1]. Although,
+ " judging by the coc source code, custom language servers are initialized
+ " just before activation of extensions[2], and coc-snippets adds its plugin
+ " to rtp in the activation phase[3], so this might be reasonable for us.
+ " [1]:
+ " [2]:
+ " [3]:
+ autocmd VimEnter * let g:coc_user_config['languageserver.vimls.initializationOptions.runtimepath'] = &runtimepath
+
+ autocmd User CocNvimInit call CocNotify('vimls', '$/change/iskeyword', &iskeyword)
+ autocmd OptionSet iskeyword call CocNotify('vimls', '$/change/iskeyword', v:option_new)
+augroup END
diff --git a/nvim/coc-languages/yaml.vim b/nvim/coc-languages/yaml.vim
new file mode 100644
index 0000000..3c48b35
--- /dev/null
+++ b/nvim/coc-languages/yaml.vim
@@ -0,0 +1 @@
+let g:coc_filetypes += ['yaml']
diff --git a/nvim/colors/dotfiles.vim b/nvim/colors/dotfiles.vim
new file mode 100644
index 0000000..03db6bd
--- /dev/null
+++ b/nvim/colors/dotfiles.vim
@@ -0,0 +1,438 @@
+" modified version of base16-vim (https://github.com/chriskempson/base16-vim)
+" by Chris Kempson (http://chriskempson.com)
+
+" Color definitions {{{
+
+ execute 'source' fnameescape(g:dotfiles_dir.'/colorschemes/out/vim.vim')
+
+ let s:is_gui_color = !has('win32') && !has('win64') && !has('win32unix') && has('termguicolors') && &termguicolors
+ if s:is_gui_color && exists('$_COLORSCHEME_TERMINAL')
+ set notermguicolors
+ endif
+
+ let s:is_kitty = $TERM ==# 'xterm-kitty'
+
+" }}}
+
+" Theme setup {{{
+ hi clear
+ syntax reset
+ let g:colors_name = g:dotfiles_colorscheme_name
+" }}}
+
+" The highlighting function {{{
+ function! s:is_number(value) abort
+ return type(a:value) == v:t_number
+ endfunction
+
+ let s:colors = g:dotfiles_colorscheme_base16_colors
+ function! s:hi(group, fg, bg, attr, sp) abort
+ let fg = {}
+ let bg = {}
+ let attr = 'NONE'
+ let sp = {}
+ if a:fg isnot ''
+ let fg = s:is_number(a:fg) ? s:colors[a:fg] : {'gui': a:fg, 'cterm': a:fg}
+ endif
+ if a:bg isnot ''
+ let bg = s:is_number(a:bg) ? s:colors[a:bg] : {'gui': a:bg, 'cterm': a:bg}
+ endif
+ if a:attr isnot ''
+ let attr = a:attr
+ endif
+ if a:sp isnot ''
+ let sp = s:is_number(a:sp) ? s:colors[a:sp] : {'gui': a:sp, 'cterm': a:sp}
+ endif
+ exec 'hi' a:group
+ \ 'guifg='.get(fg, 'gui', 'NONE') 'ctermfg='.get(fg, 'cterm', 'NONE')
+ \ 'guibg='.get(bg, 'gui', 'NONE') 'ctermbg='.get(bg, 'cterm', 'NONE')
+ \ 'gui='.(attr) 'cterm='.(attr)
+ \ 'guisp='.get(sp, 'gui', 'NONE')
+ endfunction
+" }}}
+
+" General syntax highlighting {{{
+
+ " TODO: `hi clear` ?
+
+ call s:hi('Normal', 0x5, 0x0, '', '')
+ call s:hi('Italic', 0xE, '', 'italic', '')
+ call s:hi('Bold', 0xA, '', 'bold', '')
+ call s:hi('Underlined', 0x8, '', 'underline', '')
+ call s:hi('Title', 0xD, '', '', '')
+ hi! link Directory Title
+ call s:hi('Conceal', 0xC, '', '', '')
+ call s:hi('IndentLine', 0x2, '', '', '')
+ call s:hi('NonText', 0x3, '', '', '')
+ hi! link SpecialKey Special
+ call s:hi('MatchParen', 'fg', 0x3, '', '')
+
+ call s:hi('Keyword', 0xE, '', '', '')
+ hi! link Statement Keyword
+ hi! link Repeat Keyword
+ hi! link StorageClass Keyword
+ hi! link Exception Keyword
+ hi! link Structure Keyword
+ hi! link Conditional Keyword
+ call s:hi('Constant', 0x9, '', '', '')
+ hi! link Boolean Constant
+ hi! link Float Constant
+ hi! link Number Constant
+ call s:hi('String', 0xB, '', '', '')
+ hi! link Character String
+ hi! link Quote String
+ hi! link StringDelimiter String
+ call s:hi('Comment', 0x3, '', '', '')
+ hi! link SpecialComment Comment
+ call s:hi('Todo', 'bg', 0xA, 'bold', '')
+ call s:hi('Function', 0xD, '', '', '')
+ call s:hi('Identifier', 0x8, '', '', '')
+ hi! link Variable Identifier
+ " call s:hi('Include', 0xF, '', '', '')
+ hi! link Include Keyword
+ call s:hi('PreProc', 0xA, '', '', '')
+ call s:hi('Label', 0xA, '', '', '')
+ hi! link Operator NONE
+ hi! link Delimiter NONE
+ call s:hi('Special', 0xC, '', '', '')
+ call s:hi('Tag', 0xA, '', '', '')
+ call s:hi('Type', 0xA, '', '', '')
+ hi! link Typedef Type
+
+" }}}
+
+" User interface {{{
+
+ call s:hi('Error', 'bg', 0x8, '', '')
+ call s:hi('ErrorMsg', 0x8, '', '', '')
+ call s:hi('WarningMsg', 0x9, '', '', '')
+ call s:hi('TooLong', 0x8, '', '', '')
+ call s:hi('Debug', 0x8, '', '', '')
+
+ call s:hi('CocErrorSign', 'bg', 0x8, '', '')
+ call s:hi('CocWarningSign', 'bg', 0xA, '', '')
+ call s:hi('CocInfoSign', 'bg', 0xD, '', '')
+ hi! link CocHintSign CocInfoSign
+ call s:hi('CocSelectedText', 0xE, 0x1, 'bold', '')
+ call s:hi('CocCodeLens', 0x4, '', '', '')
+ call s:hi('CocFadeOut', 0x3, '', '', '')
+ call s:hi('CocStrikeThrough', '', '', 'strikethrough', '')
+ hi! link CocMarkdownLink Underlined
+ hi! link CocDiagnosticsFile Directory
+ hi! link CocOutlineName NONE
+ hi! link CocExtensionsLoaded NONE
+ hi! link CocSymbolsName NONE
+ hi! link CocOutlineIndentLine IndentLine
+ hi! link CocSymbolsFile Directory
+
+ call s:hi('FoldColumn', 0xC, 0x1, '', '')
+ call s:hi('Folded', 0x3, 0x1, '', '')
+
+ call s:hi('IncSearch', 0x1, 0x9, '', '')
+ call s:hi('Search', 0x1, 0xA, '', '')
+ hi! link Substitute Search
+
+ call s:hi('ModeMsg', 0xB, '', 'bold', '')
+ call s:hi('Question', 0xB, '', '', '')
+ hi! link MoreMsg Question
+ call s:hi('Visual', '', 0x2, '', '')
+ call s:hi('WildMenu', 0x1, 'fg', '', '')
+
+ call s:hi('CursorLine', '', 0x1, '', '')
+ hi! link CursorColumn CursorLine
+ call s:hi('ColorColumn', '', 0x1, '', '')
+ call s:hi('LineNr', 0x3, 0x1, '', '')
+ call s:hi('CursorLineNr', 0x4, 0x1, '', '')
+ call s:hi('QuickFixLine', '', 0x2, '', '')
+
+ call s:hi('SignColumn', 0x3, 0x1, '', '')
+ call s:hi('StatusLine', 0x4, 0x1, '', '')
+ call s:hi('StatusLineNC', 0x3, 0x1, '', '')
+ call s:hi('VertSplit', 0x2, 0x2, '', '')
+ call s:hi('TabLine', 0x3, 0x1, '', '')
+ call s:hi('TabLineFill', 0x3, 0x1, '', '')
+ call s:hi('TabLineSel', 0xB, 0x1, '', '')
+
+ call s:hi('PMenu', 'fg', 0x1, '', '')
+ call s:hi('PMenuSel', 0x1, 'fg', '', '')
+
+ hi! link ctrlsfMatch Search
+ hi! link ctrlsfLnumMatch ctrlsfMatch
+
+ let s:spell_fg = s:is_kitty ? '' : 'bg'
+ let s:spell_attr = s:is_kitty ? 'undercurl' : ''
+ call s:hi('SpellBad', s:spell_fg, s:is_kitty ? '' : 0x8, s:spell_attr, 0x8)
+ call s:hi('SpellLocal', s:spell_fg, s:is_kitty ? '' : 0xC, s:spell_attr, 0xC)
+ call s:hi('SpellCap', s:spell_fg, s:is_kitty ? '' : 0xD, s:spell_attr, 0xD)
+ call s:hi('SpellRare', s:spell_fg, s:is_kitty ? '' : 0xE, s:spell_attr, 0xE)
+ unlet s:spell_fg s:spell_attr
+
+ call s:hi('Sneak', 'bg', 0xB, 'bold', '')
+ hi! link SneakScope Visual
+ hi! link SneakLabel Sneak
+
+ " checkhealth UI
+ call s:hi('healthSuccess', 'bg', 0xB, 'bold', '')
+ call s:hi('healthWarning', 'bg', 0xA, 'bold', '')
+ call s:hi('healthError', 'bg', 0x8, 'bold', '')
+
+" }}}
+
+" AWK {{{
+ hi! link awkArrayElement Number
+ hi! link awkBoolLogic Operator
+ hi! link awkComma Delimiter
+ hi! link awkExpression Operator
+ hi! link awkFieldVars awkVariables
+ hi! link awkOperator Operator
+ hi! link awkPatterns Label
+ hi! link awkSemicolon Delimiter
+ hi! link awkVariables Variable
+" }}}
+
+" Diff {{{
+ " diff mode
+ call s:hi('DiffAdd', 0xB, 0x1, '', '')
+ call s:hi('DiffDelete', 0x8, 0x1, '', '')
+ call s:hi('DiffText', 0xE, 0x1, '', '')
+ call s:hi('DiffChange', 0x3, 0x1, '', '')
+ " diff file
+ call s:hi('diffAdded', 0xB, '', '', '')
+ call s:hi('diffRemoved', 0x8, '', '', '')
+ call s:hi('diffChanged', 0xE, '', '', '')
+ hi! link diffNewFile diffAdded
+ hi! link diffFile diffRemoved
+ hi! link diffIndexLine Bold
+ hi! link diffLine Title
+ hi! link diffSubname Include
+" }}}
+
+" XML {{{
+ call s:hi('xmlTagName', 0x8, '', '', '')
+ call s:hi('xmlAttrib', 0x9, '', '', '')
+ hi! link xmlTag Delimiter
+ hi! link xmlEndTag Delimiter
+ hi! link xmlAttribPunct Delimiter
+ hi! link xmlProcessingDelim Delimiter
+" }}}
+
+" Git {{{
+ hi! link gitCommitOverflow TooLong
+ hi! link gitCommitSummary String
+ hi! link gitCommitComment Comment
+ hi! link gitcommitUntracked Comment
+ hi! link gitcommitDiscarded Comment
+ hi! link gitcommitSelected Comment
+ hi! link gitcommitHeader Keyword
+ call s:hi('gitcommitSelectedType', 0xD, '', '', '')
+ call s:hi('gitcommitUnmergedType', 0xD, '', '', '')
+ call s:hi('gitcommitDiscardedType', 0xD, '', '', '')
+ hi! link gitcommitBranch Function
+ call s:hi('gitcommitUntrackedFile', 0xA, '', 'bold', '')
+ call s:hi('gitcommitUnmergedFile', 0x8, '', 'bold', '')
+ call s:hi('gitcommitDiscardedFile', 0x8, '', 'bold', '')
+ call s:hi('gitcommitSelectedFile', 0xB, '', 'bold', '')
+
+ hi! link GitGutterAdd DiffAdd
+ hi! link GitGutterDelete DiffDelete
+ hi! link GitGutterChange DiffText
+ hi! link GitGutterChangeDelete GitGutterDelete
+ hi! link SignifySignAdd DiffAdd
+ hi! link SignifySignChange DiffText
+ hi! link SignifySignDelete DiffDelete
+" }}}
+
+" Vim scripts {{{
+ hi! link vimUserFunc vimFuncName
+ hi! link vimBracket vimMapModKey
+ hi! link vimFunction vimFuncName
+ hi! link vimParenSep Delimiter
+ hi! link vimSep Delimiter
+ hi! link vimVar Variable
+ hi! link vimFuncVar Variable
+" }}}
+
+" C {{{
+ hi! link cOperator Special
+" }}}
+
+" C# {{{
+ call s:hi('csClass', 0xA, '', '', '')
+ call s:hi('csAttribute', 0xA, '', '', '')
+ call s:hi('csModifier', 0xE, '', '', '')
+ hi! link csType Type
+ call s:hi('csUnspecifiedStatement', 0xD, '', '', '')
+ call s:hi('csContextualStatement', 0xE, '', '', '')
+ call s:hi('csNewDecleration', 0x8, '', '', '')
+" }}}
+
+" Rust {{{
+ hi! link rustEnumVariant rustType
+ hi! link rustSelf Variable
+ hi! link rustSigil rustOperator
+ hi! link rustMacroVariable Variable
+ hi! link rustModPath Identifier
+" }}}
+
+" HTML {{{
+ hi! link htmlBold Bold
+ hi! link htmlItalic Italic
+ hi! link htmlTag xmlTag
+ hi! link htmlTagName xmlTagName
+ hi! link htmlSpecialTagName xmlTagName
+ hi! link htmlEndTag xmlEndTag
+ hi! link htmlArg xmlAttrib
+" }}}
+
+" CSS {{{
+ hi! link cssBraces Delimiter
+ hi! link cssTagName htmlTagName
+ hi! link cssPseudoClassId Type
+ hi! link cssPseudoClass cssPseudoClassId
+ hi! link cssClassName Type
+ hi! link cssClassNameDot cssClassName
+ hi! link cssAtRule Keyword
+ hi! link cssProp Identifier
+ hi! link cssVendor Special
+ hi! link cssNoise Delimiter
+ hi! link cssAttr String
+ hi! link cssAttrComma Delimiter
+ hi! link cssAttrRegion cssAttr
+" }}}
+
+" SCSS {{{
+ hi! link scssSelectorName cssClassName
+ hi! link scssSelectorChar cssClassnameDot
+ hi! link scssAmpersand cssSelectorOp
+ hi! link scssProperty cssProp
+" }}}
+
+" JavaScript {{{
+ hi! link javaScriptBraces Delimiter
+ hi! link jsParens Delimiter
+ hi! link jsOperator Operator
+ hi! link jsStorageClass StorageClass
+ hi! link jsThis Variable
+ hi! link jsSuper jsThis
+ hi! link jsClassDefinition Type
+ hi! link jsFunction Keyword
+ hi! link jsArrowFunction jsFunction
+ hi! link jsFuncName jsFuncCall
+ hi! link jsClassFuncName jsFuncCall
+ hi! link jsClassMethodType jsFunction
+ hi! link jsRegexpString Special
+ hi! link jsGlobalObjects Type
+ hi! link jsGlobalNodeObjects Type
+ hi! link jsException Exception
+ hi! link jsExceptions Type
+ hi! link jsBuiltins jsFuncName
+ hi! link jsNull Constant
+ hi! link jsUndefined Constant
+ hi! link jsOperatorKeyword Keyword
+ hi! link jsObjectKey Identifier
+ hi! link jsEnvComment Special
+ hi! link jsImport Include
+ hi! link jsExport Include
+ hi! link jsTemplateBraces PreProc
+" }}}
+
+" JSON {{{
+ hi! link jsonNull Constant
+" }}}
+
+" TypeScript {{{
+ let g:yats_host_keyword = 0
+ hi! link typescriptParens jsParens
+ hi! link typescriptBraces javaScriptBraces
+ hi! link typescriptOperator jsOperatorKeyword
+ hi! link typescriptKeywordOp typescriptOperator
+ hi! link typescriptCastKeyword typescriptOperator
+ hi! link typescriptMappedIn typescriptOperator
+ hi! link typescriptBinaryOp jsOperator
+ hi! link typescriptOptionalMark typescriptBinaryOp
+ hi! link typescriptIdentifier jsThis
+ hi! link typescriptArrowFunc jsArrowFunction
+ hi! link typescriptFuncTypeArrow typescriptArrowFunc
+ hi! link typescriptCall Variable
+ hi! link typescriptArrowFuncArg typescriptCall
+ hi! link typescriptFuncType typescriptCall
+ hi! link typescriptMessage NONE
+ hi! link typescriptVariable jsStorageClass
+ hi! link typescriptAmbientDeclaration typescriptVariable
+ hi! link typescriptVariableDeclaration Variable
+ hi! link typescriptDestructureLabel typescriptVariableDeclaration
+ hi! link typescriptDestructureVariable typescriptVariableDeclaration
+ hi! link typescriptGlobal typescriptVariableDeclaration
+ hi! link typescriptTypeReference Type
+ hi! link typescriptTypeParameter typescriptTypeReference
+ hi! link typescriptConstructSignature Keyword
+ hi! link typescriptConstructorType typescriptConstructSignature
+ hi! link typescriptEndColons Delimiter
+ hi! link typescriptImport jsImport
+ hi! link typescriptImportType typescriptImport
+ hi! link typescriptExport jsExport
+ hi! link typescriptNull jsNull
+ hi! link typescriptObjectLabel jsObjectKey
+ hi! link typescriptMethodAccessor Keyword
+ hi! link typescriptClassName jsClassDefinition
+ hi! link typescriptClassHeritage jsClassDefinition
+ hi! link typescriptExceptions jsException
+ hi! link typescriptTry typescriptExceptions
+ hi! link typescriptEnumKeyword typescriptClassKeyword
+ hi! link typescriptModule jsImport
+ hi! link typescriptAbstract Keyword
+ hi! link typescriptTemplateSB PreProc
+ hi! link typescriptDebugger Keyword
+" }}}
+
+" Markdown {{{
+ hi! link mkdHeading Title
+" }}}
+
+" Mail {{{
+ call s:hi('mailQuoted1', 0x8, '', '', '')
+ call s:hi('mailQuoted2', 0x9, '', '', '')
+ call s:hi('mailQuoted3', 0xA, '', '', '')
+ call s:hi('mailQuoted4', 0xB, '', '', '')
+ call s:hi('mailQuoted5', 0xD, '', '', '')
+ call s:hi('mailQuoted6', 0xE, '', '', '')
+ hi! link mailURL Underlined
+ hi! link mailEmail Underlined
+" }}}
+
+" Python {{{
+ hi! link pythonClass Type
+ hi! link pythonBuiltinType pythonClass
+ hi! link pythonExClass pythonClass
+ hi! link pythonBuiltinObj pythonFunction
+ hi! link pythonClassVar Variable
+" }}}
+
+" Ruby {{{
+ hi! link rubyPseudoVariable Variable
+ hi! link rubyClassName Type
+ hi! link rubyAttribute rubyFunction
+ hi! link rubyConstant Constant
+ hi! link rubyInterpolationDelimiter PreProc
+ hi! link rubySymbol String
+ hi! link rubyStringDelimiter StringDelimiter
+ hi! link rubyRegexp Special
+ hi! link rubyRegexpDelimiter rubyRegexp
+" }}}
+
+" Lua {{{
+ hi! link luaFuncCall Function
+ hi! link luaBraces Delimiter
+" }}}
+
+" Shell {{{
+ hi! link shQuote String
+ hi! link zshFunction Function
+ hi! link zshVariable Variable
+" }}}
+
+" Assembly {{{
+ hi! def link riscvRegister Variable
+ hi! def link riscvCSRegister Special
+ hi! def link riscvLabel Function
+" }}}
diff --git a/nvim/dotfiles/plugins-list.vim b/nvim/dotfiles/plugins-list.vim
index 061cedc..6a49609 100644
--- a/nvim/dotfiles/plugins-list.vim
+++ b/nvim/dotfiles/plugins-list.vim
@@ -1,13 +1,76 @@
" Files {{{
-Plug 'weirongxu/coc-explorer'
+ Plug 'tpope/vim-eunuch'
+ if g:vim_ide
+ Plug 'francoiscabrol/ranger.vim'
+ Plug 'rbgrouleff/bclose.vim'
+ endif
+ Plug 'weirongxu/coc-explorer'
" }}}
-" Language specific {{{
-Plug 'alaviss/nim.nvim'
+" Editing {{{
+ if g:vim_ide
+ " Plug 'easymotion/vim-easymotion'
+ Plug 'junegunn/vim-easy-align'
+ endif
+ Plug 'Raimondi/delimitMate'
+ Plug 'tpope/vim-repeat'
+ Plug 'tomtom/tcomment_vim'
+ Plug 'tpope/vim-surround'
+ Plug 'Yggdroot/indentLine'
+ Plug 'henrik/vim-indexed-search'
+ Plug 'andymass/vim-matchup'
+ Plug 'inkarkat/vim-ingo-library' " required by LineJuggler
+ Plug 'inkarkat/vim-LineJuggler', { 'branch': 'stable' }
+ Plug 'reedes/vim-pencil'
+ Plug 'tommcdo/vim-exchange'
+ Plug 'justinmk/vim-sneak'
+" }}}
+
+" Text objects {{{
+ Plug 'kana/vim-textobj-user'
+ Plug 'kana/vim-textobj-entire'
+ Plug 'kana/vim-textobj-line'
+ Plug 'kana/vim-textobj-indent'
+ Plug 'glts/vim-textobj-comment'
+" }}}
+
+" UI {{{
+ Plug 'moll/vim-bbye'
+ Plug 'gerw/vim-HiLinkTrace'
+ Plug 'vim-airline/vim-airline'
+ Plug 'tpope/vim-obsession'
+ Plug 'romainl/vim-qf'
+" }}}
+
+" Git {{{
+ if g:vim_ide
+ Plug 'tpope/vim-fugitive'
+ Plug 'tpope/vim-rhubarb'
+ Plug 'airblade/vim-gitgutter'
+ endif
+" }}}
+
+" FZF {{{
+ Plug 'junegunn/fzf', { 'do': './install --bin' }
+ Plug 'junegunn/fzf.vim'
+" }}}
+
+" Programming {{{
+ let g:polyglot_disabled = ['sensible']
+ Plug 'sheerun/vim-polyglot'
+ Plug 'chikamichi/mediawiki.vim'
+ Plug 'ron-rs/ron.vim'
+ Plug 'kylelaker/riscv.vim'
+ if g:vim_ide
+ Plug 'neoclide/coc.nvim', { 'branch': 'release' }
+ Plug 'dag/vim2hs'
+ Plug 'norcalli/nvim-colorizer.lua'
+ if g:vim_ide_treesitter
+ Plug 'nvim-treesitter/nvim-treesitter', { 'do': ':TSUpdate' }
+ endif
+ endif
" }}}
" Misc {{{
- if has('nvim-0.5.0')
- Plug 'andweeb/presence.nvim'
- endif
+ Plug 'wakatime/vim-wakatime'
" }}}
diff --git a/nvim/dotfiles/treesitter.vim b/nvim/dotfiles/treesitter.vim
new file mode 100644
index 0000000..3c0e5e8
--- /dev/null
+++ b/nvim/dotfiles/treesitter.vim
@@ -0,0 +1,11 @@
+lua <:p:h')
-let g:k_dotfiles_dir = expand(':p:h:h')
+let g:nvim_dotfiles_dir = expand(':p:h')
+let g:dotfiles_dir = expand(':p:h:h')
-let &runtimepath = g:k_nvim_dotfiles_dir.','.&runtimepath.','.g:k_nvim_dotfiles_dir.'/after'
+let g:vim_ide = get(g:, 'vim_ide', 0)
+let g:vim_ide_treesitter = get(g:, 'vim_ide_treesitter', 0)
-" Enable the clearly superior mode.
-let g:vim_ide = 1
+let &runtimepath = g:nvim_dotfiles_dir.','.&runtimepath.','.g:nvim_dotfiles_dir.'/after'
-" Source Dima's config
-source :p:h/../dmitmel-dotfiles/nvim/init.vim
-" Give me that beautiful colorscheme
-set termguicolors
-let airline_powerline_fonts = 1
+let s:vim_config_dir = stdpath("config")
+let s:vim_plug_script = s:vim_config_dir . '/autoload/plug.vim'
+let s:vim_plug_home = s:vim_config_dir . '/plugged'
-" Copy to clipboard register and paste from clipboard register {{{
- " Taken from https://unix.stackexchange.com/a/23437
- nnoremap "+y
- vnoremap "+y
- nnoremap "+gP
- vnoremap "+gP
+let s:just_installed_vim_plug = 0
+if !filereadable(s:vim_plug_script)
+ execute '!curl -fL https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim --create-dirs -o' shellescape(s:vim_plug_script, 1)
+ autocmd VimEnter * PlugInstall --sync
+endif
+
+" HACK: Set `shiftwidth` to something unreasonable to make Polyglot's built-in
+" indentation detector believe that it's the "default" value. The problem
+" comes from the fact that Polyglot bundles vim-sleuth, but executes it in an
+" autoload script, which is loaded by an ftdetect script, which is... loaded
+" when vim-plug invokes `filetype on`. Thus vim-sleuth is loaded way before
+" the primary chunk of my configuration is loaded, so it won't see my
+" preferred indentation value, save 8 (Vim's default) to a local variable
+" `s:default_shiftwidth` and always assume that some ftplugin explicitly
+" modified the shiftwidth to 2 (my real default value) for that particular
+" filetype. So instead I use a classic approach to rectify the problem:
+" ridiculously hacky workarounds. In any case, blame this commit:
+" .
+let s:fake_default_shiftwidth = 0
+let &shiftwidth = s:fake_default_shiftwidth
+
+call plug#begin(s:vim_plug_home)
+Plug 'junegunn/vim-plug'
+runtime! dotfiles/plugins-list.vim
+call plug#end()
+if g:vim_ide_treesitter
+ runtime! dotfiles/treesitter.vim
+endif
+
+" Automatically install/clean plugins (because I'm a programmer) {{{
+ augroup vimrc-plugins
+ autocmd!
+ autocmd VimEnter *
+ \ if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
+ \| PlugInstall --sync | q
+ \| endif
+ augroup END
" }}}
+
+colorscheme dotfiles
+
+if exists(':Sleuth')
+ " HACK: Continuation of the indentation detection hack. Here I first destroy
+ " Polyglot's vim-sleuth's autocommands, fortunately there is just one, which
+ " calls `s:detect_indent()` on `BufEnter`. And also registration into tpope's
+ " statusline plugin, which I don't use, therefore I don't care.
+ augroup polyglot-sleuth
+ autocmd!
+ " HACK: Now I install my own autocommand, which first resets the local
+ " shiftwidth to the unreasonable value picked above, which vim-sleuth
+ " internally compares with its local `s:default_shiftwidth`, sees that both
+ " are the same, and proceeds to execute the indent detection algorithm.
+ " ALSO Note how I'm not using `BufEnter` as vim-sleuth does because
+ " apparently `BufWinEnter` leads to better compatibility with the
+ " indentLine plugin and potentially less useless invocations (see the note
+ " about window splits in the docs for this event). Oh, one last thing:
+ " vim-sleuth forgets to assign the tabstop options, which I have to do as
+ " well. But anyway, boom, my work here is done.
+ autocmd BufWinEnter *
+ \ let &l:shiftwidth = s:fake_default_shiftwidth
+ \| Sleuth
+ \| let &l:tabstop = &l:shiftwidth
+ \| let &l:softtabstop = &l:shiftwidth
+ augroup END
+
+ " HACK: In case you are wondering why I'm using Polyglot's bundled vim-sleuth
+ " given that it requires those terrible hacks to function normally and respect
+ " my configs, and not something like
+ " (this is a fork I used to use and which checks syntax groups to improve
+ " detection quality). ...Well, frankly, even though vim-sleuth's detector uses
+ " unreliable (at first glance) regex heuristics, in practice it still works
+ " better than detectindent's syntax group querying.
+endif
diff --git a/nvim/keymap/russian-jcuken-custom.vim b/nvim/keymap/russian-jcuken-custom.vim
new file mode 100644
index 0000000..d56470f
--- /dev/null
+++ b/nvim/keymap/russian-jcuken-custom.vim
@@ -0,0 +1,87 @@
+" Vim Keymap file for russian characters, layout 'jcuken', MS Windows variant
+" (slightly incompatible with XFree86 'ru' keymap - makes use of NUMERO SIGN)
+" Useful mainly with utf-8 but may work with other encodings
+
+" Maintainer: Artem Chuprina
+" Last Changed: 2001 Jun 23
+
+" All characters are given literally, conversion to another encoding (e.g.,
+" UTF-8) should work.
+scriptencoding utf-8
+
+let b:keymap_name = "ru"
+
+loadkeymap
+~ Ё CYRILLIC CAPITAL LETTER IO
+` ё CYRILLIC SMALL LETTER IO
+F А CYRILLIC CAPITAL LETTER A
+< Б CYRILLIC CAPITAL LETTER BE
+D В CYRILLIC CAPITAL LETTER VE
+U Г CYRILLIC CAPITAL LETTER GHE
+L Д CYRILLIC CAPITAL LETTER DE
+T Е CYRILLIC CAPITAL LETTER IE
+: Ж CYRILLIC CAPITAL LETTER ZHE
+P З CYRILLIC CAPITAL LETTER ZE
+B И CYRILLIC CAPITAL LETTER I
+Q Й CYRILLIC CAPITAL LETTER SHORT I
+R К CYRILLIC CAPITAL LETTER KA
+K Л CYRILLIC CAPITAL LETTER EL
+V М CYRILLIC CAPITAL LETTER EM
+Y Н CYRILLIC CAPITAL LETTER EN
+J О CYRILLIC CAPITAL LETTER O
+G П CYRILLIC CAPITAL LETTER PE
+H Р CYRILLIC CAPITAL LETTER ER
+C С CYRILLIC CAPITAL LETTER ES
+N Т CYRILLIC CAPITAL LETTER TE
+E У CYRILLIC CAPITAL LETTER U
+A Ф CYRILLIC CAPITAL LETTER EF
+{ Х CYRILLIC CAPITAL LETTER HA
+W Ц CYRILLIC CAPITAL LETTER TSE
+X Ч CYRILLIC CAPITAL LETTER CHE
+I Ш CYRILLIC CAPITAL LETTER SHA
+O Щ CYRILLIC CAPITAL LETTER SHCHA
+} Ъ CYRILLIC CAPITAL LETTER HARD SIGN
+S Ы CYRILLIC CAPITAL LETTER YERU
+M Ь CYRILLIC CAPITAL LETTER SOFT SIGN
+\" Э CYRILLIC CAPITAL LETTER E
+> Ю CYRILLIC CAPITAL LETTER YU
+Z Я CYRILLIC CAPITAL LETTER YA
+f а CYRILLIC SMALL LETTER A
+, б CYRILLIC SMALL LETTER BE
+d в CYRILLIC SMALL LETTER VE
+u г CYRILLIC SMALL LETTER GHE
+l д CYRILLIC SMALL LETTER DE
+t е CYRILLIC SMALL LETTER IE
+; ж CYRILLIC SMALL LETTER ZHE
+p з CYRILLIC SMALL LETTER ZE
+b и CYRILLIC SMALL LETTER I
+q й CYRILLIC SMALL LETTER SHORT I
+r к CYRILLIC SMALL LETTER KA
+k л CYRILLIC SMALL LETTER EL
+v м CYRILLIC SMALL LETTER EM
+y н CYRILLIC SMALL LETTER EN
+j о CYRILLIC SMALL LETTER O
+g п CYRILLIC SMALL LETTER PE
+h р CYRILLIC SMALL LETTER ER
+c с CYRILLIC SMALL LETTER ES
+n т CYRILLIC SMALL LETTER TE
+e у CYRILLIC SMALL LETTER U
+a ф CYRILLIC SMALL LETTER EF
+[ х CYRILLIC SMALL LETTER HA
+w ц CYRILLIC SMALL LETTER TSE
+x ч CYRILLIC SMALL LETTER CHE
+i ш CYRILLIC SMALL LETTER SHA
+o щ CYRILLIC SMALL LETTER SHCHA
+] ъ CYRILLIC SMALL LETTER HARD SIGN
+s ы CYRILLIC SMALL LETTER YERU
+m ь CYRILLIC SMALL LETTER SOFT SIGN
+' э CYRILLIC SMALL LETTER E
+. ю CYRILLIC SMALL LETTER YU
+z я CYRILLIC SMALL LETTER YA
+@ "
+# № NUMERO SIGN
+$ ;
+^ :
+& ?
+/ .
+? ,
diff --git a/nvim/keymap/ukrainian-jcuken-custom.vim b/nvim/keymap/ukrainian-jcuken-custom.vim
new file mode 100644
index 0000000..68600db
--- /dev/null
+++ b/nvim/keymap/ukrainian-jcuken-custom.vim
@@ -0,0 +1,92 @@
+" Vim Keymap file for ukrainian characters, layout 'jcuken', MS Windows variant
+" (slightly incompatible with XFree86 'uk' keymap - makes use of NUMERO SIGN)
+" Derived from russian-jcuken.vim by Artem Chuprina
+" Useful mainly with utf-8 but may work with other encodings
+
+" Maintainer: Anatoli Sakhnik
+" Last Changed: 2007 Nov 11
+
+" All characters are given literally, conversion to another encoding (e.g.,
+" UTF-8) should work.
+scriptencoding utf-8
+
+let b:keymap_name = "uk"
+
+loadkeymap
+~ ~
+` '
+F А CYRILLIC CAPITAL LETTER A
+< Б CYRILLIC CAPITAL LETTER BE
+D В CYRILLIC CAPITAL LETTER VE
+U Г CYRILLIC CAPITAL LETTER GHE
+L Д CYRILLIC CAPITAL LETTER DE
+T Е CYRILLIC CAPITAL LETTER IE
+: Ж CYRILLIC CAPITAL LETTER ZHE
+P З CYRILLIC CAPITAL LETTER ZE
+B И CYRILLIC CAPITAL LETTER I
+Q Й CYRILLIC CAPITAL LETTER SHORT I
+R К CYRILLIC CAPITAL LETTER KA
+K Л CYRILLIC CAPITAL LETTER EL
+V М CYRILLIC CAPITAL LETTER EM
+Y Н CYRILLIC CAPITAL LETTER EN
+J О CYRILLIC CAPITAL LETTER O
+G П CYRILLIC CAPITAL LETTER PE
+H Р CYRILLIC CAPITAL LETTER ER
+C С CYRILLIC CAPITAL LETTER ES
+N Т CYRILLIC CAPITAL LETTER TE
+E У CYRILLIC CAPITAL LETTER U
+A Ф CYRILLIC CAPITAL LETTER EF
+{ Х CYRILLIC CAPITAL LETTER HA
+W Ц CYRILLIC CAPITAL LETTER TSE
+X Ч CYRILLIC CAPITAL LETTER CHE
+I Ш CYRILLIC CAPITAL LETTER SHA
+O Щ CYRILLIC CAPITAL LETTER SHCHA
+} Ї CYRILLIC CAPITAL LETTER YI
+S І CYRILLIC CAPITAL LETTER BYELORUSSION-UKRAINIAN I
+M Ь CYRILLIC CAPITAL LETTER SOFT SIGN
+\" Є CYRILLIC CAPITAL LETTER UKRAINIAN IE
+> Ю CYRILLIC CAPITAL LETTER YU
+Z Я CYRILLIC CAPITAL LETTER YA
+| Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+f а CYRILLIC SMALL LETTER A
+, б CYRILLIC SMALL LETTER BE
+d в CYRILLIC SMALL LETTER VE
+u г CYRILLIC SMALL LETTER GHE
+l д CYRILLIC SMALL LETTER DE
+t е CYRILLIC SMALL LETTER IE
+; ж CYRILLIC SMALL LETTER ZHE
+p з CYRILLIC SMALL LETTER ZE
+b и CYRILLIC SMALL LETTER I
+q й CYRILLIC SMALL LETTER SHORT I
+r к CYRILLIC SMALL LETTER KA
+k л CYRILLIC SMALL LETTER EL
+v м CYRILLIC SMALL LETTER EM
+y н CYRILLIC SMALL LETTER EN
+j о CYRILLIC SMALL LETTER O
+g п CYRILLIC SMALL LETTER PE
+h р CYRILLIC SMALL LETTER ER
+c с CYRILLIC SMALL LETTER ES
+n т CYRILLIC SMALL LETTER TE
+e у CYRILLIC SMALL LETTER U
+a ф CYRILLIC SMALL LETTER EF
+[ х CYRILLIC SMALL LETTER HA
+w ц CYRILLIC SMALL LETTER TSE
+x ч CYRILLIC SMALL LETTER CHE
+i ш CYRILLIC SMALL LETTER SHA
+o щ CYRILLIC SMALL LETTER SHCHA
+] ї CYRILLIC SMALL LETTER YI
+s і CYRILLIC SMALL LETTER BYELORUSSION-UKRAINIAN I
+m ь CYRILLIC SMALL LETTER SOFT SIGN
+' є CYRILLIC SMALL LETTER UKRAINIAN IE
+. ю CYRILLIC SMALL LETTER YU
+z я CYRILLIC SMALL LETTER YA
+\\ ґ CYRILLIC SMALL LETTER GHE WITH UPTURN
+@ "
+# № NUMERO SIGN
+$ ;
+^ :
+& ?
+/ .
+? ,
+~ ~
+~~ Stress
diff --git a/nvim/plugin/commands.vim b/nvim/plugin/commands.vim
deleted file mode 100644
index 7842ea6..0000000
--- a/nvim/plugin/commands.vim
+++ /dev/null
@@ -1 +0,0 @@
-command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
diff --git a/nvim/plugin/completion.vim b/nvim/plugin/completion.vim
new file mode 100644
index 0000000..bec2c0f
--- /dev/null
+++ b/nvim/plugin/completion.vim
@@ -0,0 +1,97 @@
+" pop-up (completion) menu mappings {{{
+ imap pumvisible() ? "\" : "\delimitMateCR"
+ imap pumvisible() ? "\" : "\"
+ imap pumvisible() ? "\" : "\"
+ imap pumvisible() ? "\" : "\"
+" }}}
+
+if !g:vim_ide
+ function! IsCocEnabled() abort
+ return 0
+ endfunction
+ finish
+endif
+
+" coc.nvim {{{
+ " list of filetypes (that are added in language-specific scripts) for which
+ " coc mappings are enabled
+ let g:coc_filetypes = []
+
+ function! IsCocEnabled() abort
+ return index(g:coc_filetypes, &filetype) >= 0
+ endfunction
+
+ command -nargs=* CocKeywordprg call CocAction('doHover')
+ augroup vimrc-coc
+ autocmd!
+ autocmd FileType * if IsCocEnabled()
+ \|let &l:keywordprg = ":CocKeywordprg"
+ \|endif
+ autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
+ augroup end
+
+ " mappings {{{
+ let g:coc_snippet_next = ''
+ let g:coc_snippet_prev = ''
+
+ inoremap coc#refresh()
+ inoremap call CocActionAsync('showSignatureHelp')
+ imap
+
+ nmap [c (coc-diagnostic-prev)
+ nmap ]c (coc-diagnostic-next)
+
+ nmap gd (coc-definition)
+ nmap gt (coc-type-definition)
+ nmap gi (coc-implementation)
+ nmap gr (coc-references)
+ nmap (coc-rename)
+ nmap (coc-codeaction-line)
+ vmap (coc-codeaction-selected)
+ " nmap qf (coc-fix-current)
+
+ nnoremap l CocList
+ nnoremap d CocList --auto-preview diagnostics
+ nnoremap c CocList commands
+ nnoremap o CocList --auto-preview outline
+ nnoremap s CocList --interactive symbols
+ nnoremap e CocList extensions
+ nnoremap h CocPrev
+ nnoremap k CocPrev
+ nnoremap l CocNext
+ nnoremap j CocNext
+ nnoremap p CocListResume
+ " }}}
+
+ " CocFormat {{{
+ function! s:CocFormat(range, line1, line2) abort
+ if a:range == 0
+ call CocAction('format')
+ else
+ call cursor(a:line1, 1)
+ normal! V
+ call cursor(a:line2, 1)
+ call CocAction('formatSelected', 'V')
+ endif
+ endfunction
+ command! -nargs=0 -range -bar CocFormat call s:CocFormat(, , )
+ " }}}
+
+ let g:coc_global_extensions = []
+ let g:coc_user_config = {}
+
+ let g:coc_global_extensions += ['coc-snippets']
+ let g:coc_user_config['diagnostic'] = {
+ \ 'virtualText': v:true,
+ \ 'virtualTextCurrentLineOnly': v:false,
+ \ 'enableMessage': 'jump',
+ \ 'errorSign': 'XX',
+ \ 'warningSign': '!!',
+ \ }
+ let g:coc_user_config['suggest.floatEnable'] = v:false
+ let g:coc_user_config['workspace.progressTarget'] = "statusline"
+ let g:coc_user_config['list.selectedSignText'] = '> '
+
+ runtime! coc-languages/*.vim
+
+" }}}
diff --git a/nvim/plugin/dotfiles/indent_motion.vim b/nvim/plugin/dotfiles/indent_motion.vim
new file mode 100644
index 0000000..32c4525
--- /dev/null
+++ b/nvim/plugin/dotfiles/indent_motion.vim
@@ -0,0 +1,9 @@
+for [s:plug_mapping, s:direction, s:user_mapping] in [["prev", -1, "("], ["next", 1, ")"]]
+ let s:plug_mapping = "dotfiles_indent_motion_".s:plug_mapping
+ for s:mode in ["n", "v", "o"]
+ execute s:mode."noremap" "" s:plug_mapping "call dotfiles#indent_motion#run(".s:direction.")"
+ if !empty(s:user_mapping)
+ execute s:mode."map" s:user_mapping s:plug_mapping
+ endif
+ endfor
+endfor
diff --git a/nvim/plugin/editing.vim b/nvim/plugin/editing.vim
new file mode 100644
index 0000000..658adf4
--- /dev/null
+++ b/nvim/plugin/editing.vim
@@ -0,0 +1,300 @@
+" is comma
+let mapleader = ','
+
+" allow moving cursor just after the last chraracter of the line
+set virtualedit=onemore
+
+set foldmethod=marker
+
+" use line C-style comments instead of block ones (/* ... */)
+set commentstring=//%s
+
+
+" Indentination {{{
+
+ function! SetIndent(expandtab, shiftwidth) abort
+ let &l:expandtab = a:expandtab
+ let &l:shiftwidth = str2nr(a:shiftwidth)
+ let &l:tabstop = &l:shiftwidth
+ let &l:softtabstop = &l:shiftwidth
+ endfunction
+ command -nargs=1 Indent call SetIndent(1, )
+ command -nargs=1 IndentTabs call SetIndent(0, )
+
+ " use 2 spaces for indentination
+ set expandtab shiftwidth=2 tabstop=2 softtabstop=2
+ " round indents to multiple of shiftwidth when using shift (< and >) commands
+ set shiftround
+
+ let g:indentLine_char = "\u2502"
+ let g:indentLine_first_char = g:indentLine_char
+ let g:indentLine_showFirstIndentLevel = 1
+ let g:indentLine_fileTypeExclude = ['text', 'help', 'tutor', 'man']
+ let g:indentLine_defaultGroup = 'IndentLine'
+
+ augroup vimrc-indentlines-disable
+ autocmd!
+ autocmd TermOpen * IndentLinesDisable
+ "
+ autocmd VimEnter * if bufname('%') == '' | IndentLinesDisable | endif
+ augroup END
+
+" }}}
+
+
+" Invisible characters {{{
+ set list
+ let &listchars = "tab:\u2192 ,extends:>,precedes:<,eol:\u00ac,trail:\u00b7,nbsp:+"
+ let &showbreak = '>'
+ set display+=uhex
+" }}}
+
+
+" Cursor and Scrolling {{{
+ set number relativenumber cursorline
+ " remember cursor position
+ augroup vimrc-editing-remember-cursor-position
+ autocmd!
+ autocmd BufReadPost *
+ \ if line("'\"") > 1 && line("'\"") <= line("$")
+ \| exec "normal! g`\""
+ \|endif
+ \|silent! .foldopen
+ augroup END
+" }}}
+
+
+" Wrapping {{{
+ set nowrap colorcolumn=81,101,121 textwidth=79
+" }}}
+
+
+" Mappings {{{
+
+ " stay in the Visual mode when using shift commands
+ xnoremap < >gv
+
+ " 2 mappings for quick prototyping: duplicate this line and comment it out
+ nmap ] m'yygccp`'j
+ nmap [ m'yygccP`'k
+
+ function! PutOutput(cmd) abort
+ let output = execute(a:cmd)
+ execute "noswapfile pedit" "+" . fnameescape("setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile") fnameescape("preview://" . a:cmd)
+ wincmd P
+ call setline(1, split(output, "\n"))
+ endfunction
+ command! -nargs=+ -complete=command PutOutput silent call PutOutput()
+
+ " ,c is easier to type than "+ because it doesn't require pressing Shift
+ noremap c "+
+
+ " make the default Vim mappings more consistent
+ " https://www.reddit.com/r/vim/comments/dgbr9l/mappings_i_would_change_for_more_consistent_vim/
+ nmap U
+ nnoremap Y y$
+
+ " is treated as in terminals, so the original function of
+ " is inaccessible when something is bound to (buffer switching in my
+ " case). and are basically useless because they are equivalent
+ " to j and k respectively, but now they go to newer or older recorded cursor
+ " position in the jump list.
+ nnoremap
+ nnoremap
+
+ " Source of this trick:
+ nnoremap Q gq
+
+ " normal mode
+ nnoremap dg :.diffget
+ nnoremap dp :.diffput
+ " visual mode
+ xnoremap dg :diffget
+ xnoremap dp :diffput
+
+ " Horizontal scroll
+ " Alt+hjkl and Alt+Arrow - scroll one column/row
+ " Alt+Shift+hjkl - scroll half a page
+ " normal mode
+ nnoremap zh
+ nnoremap zH
+ nnoremap zh
+ nnoremap
+ nnoremap
+ nnoremap
+ nnoremap
+ nnoremap
+ nnoremap
+ nnoremap zl
+ nnoremap zL
+ nnoremap zl
+ " visual mode
+ xnoremap zh
+ xnoremap zH
+ xnoremap zh
+ xnoremap
+ xnoremap
+ xnoremap
+ xnoremap
+ xnoremap
+ xnoremap
+ xnoremap zl
+ xnoremap zL
+ xnoremap zl
+
+ " Repeat the last edit n times, taken from