From be53c76ae5db553f1a27a741170107f38bf06703 Mon Sep 17 00:00:00 2001 From: Luke Channings <461449+LukeChannings@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:30:33 +0100 Subject: [PATCH] Messy test --- .gitmodules | 0 .vscode/settings.json | 5 +- Dockerfile | 41 - README.markdown | 34 +- Terminal/com.googlecode.iterm2.plist | 1944 -------------- boop/parseJson.js | 19 - editorconfig | 8 - fish/config.fish | 37 - fish/functions/convert-to-heic.fish | 6 - fish/functions/fish_user_key_bindings.fish | 2 - fish/functions/fundle.fish | 453 ---- fish/functions/gitco.fish | 9 - fish/functions/gzipsize.fish | 6 - fish/functions/krun.fish | 59 - fish/functions/ls.fish | 7 - fish/functions/mkcd.fish | 4 - fish/functions/mkpass.fish | 4 - fish/iterm2_shell_integration.fish | 92 - flake.lock | 186 +- flake.nix | 108 +- git/config | 39 - homebrew/Brewfile | 98 - install | 21 +- modules/util.nix | 26 - nushell/config.nu | 495 ---- nushell/env.nu | 77 - oni2/configuration.json | 33 - oni2/keybindings.json | 8 - overlays/README.markdown | 5 + overlays/brew-casks.nix | 23 + overlays/nixpkgs/chromium/default.nix | 52 + overlays/nixpkgs/chromium/release.nix | 7 + overlays/nixpkgs/default.nix | 9 + overlays/nixpkgs/nu/plugin_plist.nix | 59 + rstudio/rstudio-prefs.json | 7 - safari/stylesheet.css | 3 - systems/Scimitar.nix | 445 ++++ tmux/config | 61 - vim/autoload/plug.vim | 2797 -------------------- vim/vimrc | 163 -- vscode/extensions | 26 - 41 files changed, 858 insertions(+), 6620 deletions(-) delete mode 100644 .gitmodules delete mode 100644 Dockerfile delete mode 100644 Terminal/com.googlecode.iterm2.plist delete mode 100644 boop/parseJson.js delete mode 100644 editorconfig delete mode 100644 fish/config.fish delete mode 100644 fish/functions/convert-to-heic.fish delete mode 100644 fish/functions/fish_user_key_bindings.fish delete mode 100644 fish/functions/fundle.fish delete mode 100644 fish/functions/gitco.fish delete mode 100644 fish/functions/gzipsize.fish delete mode 100644 fish/functions/krun.fish delete mode 100644 fish/functions/ls.fish delete mode 100644 fish/functions/mkcd.fish delete mode 100644 fish/functions/mkpass.fish delete mode 100644 fish/iterm2_shell_integration.fish delete mode 100644 git/config delete mode 100644 homebrew/Brewfile delete mode 100644 modules/util.nix delete mode 100644 nushell/config.nu delete mode 100644 nushell/env.nu delete mode 100644 oni2/configuration.json delete mode 100644 oni2/keybindings.json create mode 100644 overlays/README.markdown create mode 100644 overlays/brew-casks.nix create mode 100644 overlays/nixpkgs/chromium/default.nix create mode 100644 overlays/nixpkgs/chromium/release.nix create mode 100644 overlays/nixpkgs/default.nix create mode 100644 overlays/nixpkgs/nu/plugin_plist.nix delete mode 100644 rstudio/rstudio-prefs.json delete mode 100644 safari/stylesheet.css create mode 100644 systems/Scimitar.nix delete mode 100644 tmux/config delete mode 100644 vim/autoload/plug.vim delete mode 100644 vim/vimrc delete mode 100644 vscode/extensions diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5e18b5a..e90976c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,5 +15,8 @@ ] } } - } + }, + "cSpell.words": [ + "Nixpkgs" + ] } diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8bffac4..0000000 --- a/Dockerfile +++ /dev/null @@ -1,41 +0,0 @@ -FROM ubuntu:focal - -SHELL ["/bin/bash", "-c"] - -RUN apt-get update -y -RUN apt-get install -y build-essential curl file git locales sudo - -RUN sed -i 's/%admin ALL=(ALL) ALL/%admin ALL=(ALL) NOPASSWD: ALL/' /etc/sudoers -RUN echo "Set disable_coredump false" >> /etc/sudo.conf - -RUN sudo locale-gen en_US -RUN sudo locale-gen en_US.UTF-8 -RUN sudo locale-gen en_GB -RUN sudo locale-gen en_GB.UTF-8 -RUN sudo update-locale LANG=en_GB - -ENV TZ=Europe/London -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -RUN groupadd admin - -RUN useradd -G admin -m -p '' luke - -USER luke - -RUN mkdir ~/.config -COPY --chown=luke:admin . /home/luke/.config/ - -WORKDIR /home/luke/.config - -RUN git remote remove origin -RUN git remote add origin https://github.com/LukeChannings/.config.git - -RUN ./install - -RUN sudo apt-get remove -y build-essential -RUN sudo apt-get autoremove -y - -WORKDIR /home/luke - -ENTRYPOINT [ "/usr/bin/fish" ] diff --git a/README.markdown b/README.markdown index 7119a53..c69b958 100644 --- a/README.markdown +++ b/README.markdown @@ -1,25 +1,43 @@ -# Luke's Configuration +# Luke's Config This repo contains a declarative configuration for all systems, including Operating System, shell, and application configurations. +## Usage + +``` +curl https://raw.githubusercontent.com/LukeChannings/.config/nix/install | sh -c -- "$(hostname)" +``` + ## Philosophy System configurations should not install frameworks (e.g. `ruby` or `python`) system-wide. Instead, each project should have its own environment in which it defines its dependencies, and dependency versions. If a useful system tool requires a specific framework (e.g. `http-server` requires `nodejs`), the `http-server` binary can wrap `nodejs`, but the `node` binary should not be in the global `PATH`. This ensures projects are insulated from system-wide dependencies. It also prevents issues where some tools (e.g. `brew install ffmpeg`) add many dependencies to the system and makes it hard to know if a dependency is still used. -## Levels +## Installer Levels Installing a complete configuration, including desktop applications, etc. can take a long time. To minimise the time to productivity the profiles are separated into three levels. -### Level 1 +- **Level 1** -Should be installable within 10 minutes and set up configurations and conveniences that make the system comfortable to use. + Should be installable within 10 minutes and set up configurations and conveniences that make the system comfortable to use. +- **Level 2** -### Level 2 + Should be installable within 30 minutes and provide the tools necessary for being productive. This usually includes developer tools, devenv environment, etc. +- **Level 3** -Should be installable within 30 minutes and provide the tools necessary for being productive. This usually includes developer tools, devenv environment, etc. + Everything else. It shouldn't matter if this takes a long time to install. -### Level 3 +## Documentation -Everything else. It shouldn't matter if this takes a long time to install. +- **Source** + - [Nixpkgs](https://github.com/NixOS/nixpkgs) + - [Home Manager](https://github.com/nix-community/home-manager) + - [Nix Darwin](https://github.com/LnL7/nix-darwin) + - [Determinate Systems Nix Installer](https://github.com/DeterminateSystems/nix-installer) + - [brew-nix](https://github.com/BatteredBunny/brew-nix/tree/main) +- **Options** + - [Home Manager](https://nix-community.github.io/home-manager/options.xhtml) + - [Searchable](https://home-manager-options.extranix.com) + - [Nix Darwin](https://daiderd.com/nix-darwin/manual/index.html) + - `man 5 configuration.nix` diff --git a/Terminal/com.googlecode.iterm2.plist b/Terminal/com.googlecode.iterm2.plist deleted file mode 100644 index 234fcdc..0000000 --- a/Terminal/com.googlecode.iterm2.plist +++ /dev/null @@ -1,1944 +0,0 @@ - - - - - AboutToPasteTabsWithCancel - - AboutToPasteTabsWithCancel_selection - 0 - AllowClipboardAccess - - AlternateMouseScroll - - AutoHideTmuxClientSession - - ClosingTmuxTabKillsTmuxWindows - - ClosingTmuxTabKillsTmuxWindows_selection - 1 - ClosingTmuxWindowKillsTmuxWindows - - ClosingTmuxWindowKillsTmuxWindows_selection - 2 - Command - - Custom Color Presets - - One Dark - - Ansi 0 Color - - Blue Component - 0.15294117647058825 - Green Component - 0.12941176470588237 - Red Component - 0.11764705882352941 - - Ansi 1 Color - - Blue Component - 0.38427838683128357 - Green Component - 0.33154326677322388 - Red Component - 0.83982789516448975 - - Ansi 10 Color - - Blue Component - 0.45990046858787537 - Green Component - 0.8412100076675415 - Red Component - 0.61288726329803467 - - Ansi 11 Color - - Blue Component - 0.46791279315948486 - Green Component - 0.80701065063476562 - Red Component - 0.9959147572517395 - - Ansi 12 Color - - Blue Component - 0.9987521767616272 - Green Component - 0.67180883884429932 - Red Component - 0.34587877988815308 - - Ansi 13 Color - - Blue Component - 0.96143209934234619 - Green Component - 0.41257083415985107 - Red Component - 0.82537251710891724 - - Ansi 14 Color - - Blue Component - 0.82634669542312622 - Green Component - 0.76449495553970337 - Red Component - 0.3224620521068573 - - Ansi 15 Color - - Blue Component - 0.75526618957519531 - Green Component - 0.66868430376052856 - Red Component - 0.63631373643875122 - - Ansi 2 Color - - Blue Component - 0.39974290132522583 - Green Component - 0.72638434171676636 - Red Component - 0.53152436017990112 - - Ansi 3 Color - - Blue Component - 0.40846776962280273 - Green Component - 0.70514953136444092 - Red Component - 0.86970347166061401 - - Ansi 4 Color - - Blue Component - 0.92034512758255005 - Green Component - 0.6175723671913147 - Red Component - 0.31691095232963562 - - Ansi 5 Color - - Blue Component - 0.83443146944046021 - Green Component - 0.36372146010398865 - Red Component - 0.72034633159637451 - - Ansi 6 Color - - Blue Component - 0.70909899473190308 - Green Component - 0.65958321094512939 - Red Component - 0.2818438708782196 - - Ansi 7 Color - - Blue Component - 0.69803921568627447 - Green Component - 0.63529411764705879 - Red Component - 0.60784313725490191 - - Ansi 8 Color - - Blue Component - 0.19104193150997162 - Green Component - 0.15894599258899689 - Red Component - 0.14500536024570465 - - Ansi 9 Color - - Blue Component - 0.43910089135169983 - Green Component - 0.37484294176101685 - Red Component - 0.96376317739486694 - - Background Color - - Blue Component - 0.15356595814228058 - Green Component - 0.12867720425128937 - Red Component - 0.1178457960486412 - - Bold Color - - Blue Component - 0.81480300426483154 - Green Component - 0.74774473905563354 - Red Component - 0.71537381410598755 - - Cursor Color - - Blue Component - 0.58823529411764708 - Green Component - 0.32549019607843138 - Red Component - 0.22352941176470589 - - Cursor Text Color - - Blue Component - 0.69803921568627447 - Green Component - 0.63529411764705879 - Red Component - 0.60784313725490191 - - Foreground Color - - Blue Component - 0.69588643312454224 - Green Component - 0.63642358779907227 - Red Component - 0.60774445533752441 - - Selected Text Color - - Blue Component - 0.69803921568627447 - Green Component - 0.63529411764705879 - Red Component - 0.60784313725490191 - - Selection Color - - Blue Component - 0.28627450980392155 - Green Component - 0.23529411764705882 - Red Component - 0.21568627450980393 - - - palenight - - Ansi 0 Color - - Alpha Component - 1 - Blue Component - 0.24313725531101227 - Color Space - sRGB - Green Component - 0.17647059261798859 - Red Component - 0.16078431904315948 - - Ansi 1 Color - - Alpha Component - 1 - Blue Component - 0.47058823704719543 - Color Space - sRGB - Green Component - 0.44313725829124451 - Red Component - 0.94117647409439087 - - Ansi 10 Color - - Alpha Component - 1 - Blue Component - 0.65490198135375977 - Color Space - sRGB - Green Component - 1 - Red Component - 0.86666667461395264 - - Ansi 11 Color - - Alpha Component - 1 - Blue Component - 0.5215686559677124 - Color Space - sRGB - Green Component - 0.89803922176361084 - Red Component - 1 - - Ansi 12 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.76862746477127075 - Red Component - 0.61176472902297974 - - Ansi 13 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.67450982332229614 - Red Component - 0.88235294818878174 - - Ansi 14 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.9686274528503418 - Red Component - 0.63921570777893066 - - Ansi 15 Color - - Alpha Component - 1 - Blue Component - 0.99999994039535522 - Color Space - sRGB - Green Component - 0.99999994039535522 - Red Component - 0.9999966025352478 - - Ansi 2 Color - - Alpha Component - 1 - Blue Component - 0.55294120311737061 - Color Space - sRGB - Green Component - 0.90980392694473267 - Red Component - 0.76470589637756348 - - Ansi 3 Color - - Alpha Component - 1 - Blue Component - 0.41960784792900085 - Color Space - sRGB - Green Component - 0.79607844352722168 - Red Component - 1 - - Ansi 4 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.66666668653488159 - Red Component - 0.50980395078659058 - - Ansi 5 Color - - Alpha Component - 1 - Blue Component - 0.91764706373214722 - Color Space - sRGB - Green Component - 0.57254904508590698 - Red Component - 0.78039216995239258 - - Ansi 6 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.86666667461395264 - Red Component - 0.5372549295425415 - - Ansi 7 Color - - Alpha Component - 1 - Blue Component - 0.81568628549575806 - Color Space - sRGB - Green Component - 0.81568628549575806 - Red Component - 0.81568628549575806 - - Ansi 8 Color - - Alpha Component - 1 - Blue Component - 0.34509804844856262 - Color Space - sRGB - Green Component - 0.27843138575553894 - Red Component - 0.26274511218070984 - - Ansi 9 Color - - Alpha Component - 1 - Blue Component - 0.57254904508590698 - Color Space - sRGB - Green Component - 0.54509806632995605 - Red Component - 1 - - Background Color - - Alpha Component - 1 - Blue Component - 0.24313725531101227 - Color Space - sRGB - Green Component - 0.17647059261798859 - Red Component - 0.16078431904315948 - - Badge Color - - Alpha Component - 0.5 - Blue Component - 0.0 - Color Space - sRGB - Green Component - 0.1491314172744751 - Red Component - 1 - - Bold Color - - Alpha Component - 1 - Blue Component - 0.93321198225021362 - Color Space - sRGB - Green Component - 0.93339759111404419 - Red Component - 0.93324452638626099 - - Cursor Color - - Alpha Component - 1 - Blue Component - 0.0 - Color Space - sRGB - Green Component - 0.80000001192092896 - Red Component - 1 - - Cursor Guide Color - - Alpha Component - 0.25 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.9268307089805603 - Red Component - 0.70213186740875244 - - Cursor Text Color - - Alpha Component - 1 - Blue Component - 0.24313725531101227 - Color Space - sRGB - Green Component - 0.17647059261798859 - Red Component - 0.16078431904315948 - - Foreground Color - - Alpha Component - 1 - Blue Component - 0.79607844352722168 - Color Space - sRGB - Green Component - 0.61568629741668701 - Red Component - 0.58431375026702881 - - Link Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.66666668653488159 - Red Component - 0.50980395078659058 - - Selected Text Color - - Alpha Component - 1 - Blue Component - 0.94509798288345337 - Color Space - sRGB - Green Component - 0.93725484609603882 - Red Component - 0.92549020051956177 - - Selection Color - - Alpha Component - 1 - Blue Component - 0.54509806632995605 - Color Space - sRGB - Green Component - 0.49019604921340942 - Red Component - 0.37647062540054321 - - - - DarkThemeHasBlackTitlebar - - Default Bookmark Guid - 23A858CE-FD7D-4786-A923-61AD9047DD28 - DeleteProfile_SilenceUntil - 679517368.50254202 - DeleteProfile_selection - 0 - DimBackgroundWindows - - DimInactiveSplitPanes - - DimOnlyText - - DisableFullscreenTransparency - - EnableAPIServer - - EnableDivisionView - - HapticFeedbackForEsc - - HideScrollbar - - HideTab - - HotkeyMigratedFromSingleToMulti - - IRMemory - 4 - JobName - - New Bookmarks - - - ASCII Anti Aliased - - ASCII Ligatures - - AWDS Pane Directory - - AWDS Pane Option - Recycle - AWDS Tab Directory - - AWDS Tab Option - Recycle - AWDS Window Directory - - AWDS Window Option - Recycle - Allow Title Setting - - Ambiguous Double Width - - Ansi 0 Color - - Alpha Component - 1 - Blue Component - 0.24313725531101227 - Color Space - sRGB - Green Component - 0.17647059261798859 - Red Component - 0.16078431904315948 - - Ansi 1 Color - - Alpha Component - 1 - Blue Component - 0.47058823704719543 - Color Space - sRGB - Green Component - 0.44313725829124451 - Red Component - 0.94117647409439087 - - Ansi 10 Color - - Alpha Component - 1 - Blue Component - 0.65490198135375977 - Color Space - sRGB - Green Component - 1 - Red Component - 0.86666667461395264 - - Ansi 11 Color - - Alpha Component - 1 - Blue Component - 0.5215686559677124 - Color Space - sRGB - Green Component - 0.89803922176361084 - Red Component - 1 - - Ansi 12 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.76862746477127075 - Red Component - 0.61176472902297974 - - Ansi 13 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.67450982332229614 - Red Component - 0.88235294818878174 - - Ansi 14 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.9686274528503418 - Red Component - 0.63921570777893066 - - Ansi 15 Color - - Alpha Component - 1 - Blue Component - 0.99999994039535522 - Color Space - sRGB - Green Component - 0.99999994039535522 - Red Component - 0.9999966025352478 - - Ansi 2 Color - - Alpha Component - 1 - Blue Component - 0.55294120311737061 - Color Space - sRGB - Green Component - 0.90980392694473267 - Red Component - 0.76470589637756348 - - Ansi 3 Color - - Alpha Component - 1 - Blue Component - 0.41960784792900085 - Color Space - sRGB - Green Component - 0.79607844352722168 - Red Component - 1 - - Ansi 4 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.66666668653488159 - Red Component - 0.50980395078659058 - - Ansi 5 Color - - Alpha Component - 1 - Blue Component - 0.91764706373214722 - Color Space - sRGB - Green Component - 0.57254904508590698 - Red Component - 0.78039216995239258 - - Ansi 6 Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.86666667461395264 - Red Component - 0.5372549295425415 - - Ansi 7 Color - - Alpha Component - 1 - Blue Component - 0.81568628549575806 - Color Space - sRGB - Green Component - 0.81568628549575806 - Red Component - 0.81568628549575806 - - Ansi 8 Color - - Alpha Component - 1 - Blue Component - 0.34509804844856262 - Color Space - sRGB - Green Component - 0.27843138575553894 - Red Component - 0.26274511218070984 - - Ansi 9 Color - - Alpha Component - 1 - Blue Component - 0.57254904508590698 - Color Space - sRGB - Green Component - 0.54509806632995605 - Red Component - 1 - - BM Growl - - Background Color - - Alpha Component - 1 - Blue Component - 0.14117647058823529 - Color Space - sRGB - Green Component - 0.14117647058823529 - Red Component - 0.14117647058823529 - - Background Image Location - - Badge Color - - Alpha Component - 0.5 - Blue Component - 0.0 - Color Space - sRGB - Green Component - 0.1491314172744751 - Red Component - 1 - - Blinking Cursor - - Blur - - Blur Radius - 30 - Bold Color - - Alpha Component - 1 - Blue Component - 0.93321198225021362 - Color Space - sRGB - Green Component - 0.93339759111404419 - Red Component - 0.93324452638626099 - - Character Encoding - 4 - Close Sessions On End - - Columns - 86 - Command - - Cursor Color - - Alpha Component - 1 - Blue Component - 0.0 - Color Space - sRGB - Green Component - 0.80000001192092896 - Red Component - 1 - - Cursor Guide Color - - Alpha Component - 0.25 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.9268307089805603 - Red Component - 0.70213186740875244 - - Cursor Text Color - - Alpha Component - 1 - Blue Component - 0.24313725531101227 - Color Space - sRGB - Green Component - 0.17647059261798859 - Red Component - 0.16078431904315948 - - Custom Command - No - Custom Directory - Recycle - Default Bookmark - No - Description - Default - Disable Window Resizing - - Draw Powerline Glyphs - - Flashing Bell - - Foreground Color - - Alpha Component - 1 - Blue Component - 0.9310302734375 - Color Space - sRGB - Green Component - 0.83843983385573961 - Red Component - 0.82233714871108532 - - Guid - 23A858CE-FD7D-4786-A923-61AD9047DD28 - Horizontal Spacing - 1 - Idle Code - 0 - Initial Text - - Jobs to Ignore - - rlogin - ssh - slogin - telnet - - Keyboard Map - - 0x2a-0x200000-0x0 - - Action - 12 - Text - * - - 0x2b-0x200000-0x0 - - Action - 12 - Text - + - - 0x2d-0x200000-0x0 - - Action - 12 - Text - - - - 0x2d-0x40000-0x0 - - Action - 11 - Text - 0x1f - - 0x2e-0x200000-0x0 - - Action - 12 - Text - . - - 0x2f-0x200000-0x0 - - Action - 12 - Text - / - - 0x3-0x200000-0x0 - - Action - 11 - Text - 0xd - - 0x30-0x200000-0x0 - - Action - 12 - Text - 0 - - 0x31-0x200000-0x0 - - Action - 12 - Text - 1 - - 0x32-0x200000-0x0 - - Action - 12 - Text - 2 - - 0x32-0x40000-0x0 - - Action - 11 - Text - 0x00 - - 0x33-0x200000-0x0 - - Action - 12 - Text - 3 - - 0x33-0x40000-0x0 - - Action - 11 - Text - 0x1b - - 0x34-0x200000-0x0 - - Action - 12 - Text - 4 - - 0x34-0x40000-0x0 - - Action - 11 - Text - 0x1c - - 0x35-0x200000-0x0 - - Action - 12 - Text - 5 - - 0x35-0x40000-0x0 - - Action - 11 - Text - 0x1d - - 0x36-0x200000-0x0 - - Action - 12 - Text - 6 - - 0x36-0x40000-0x0 - - Action - 11 - Text - 0x1e - - 0x37-0x200000-0x0 - - Action - 12 - Text - 7 - - 0x37-0x40000-0x0 - - Action - 11 - Text - 0x1f - - 0x38-0x200000-0x0 - - Action - 12 - Text - 8 - - 0x38-0x40000-0x0 - - Action - 11 - Text - 0x7f - - 0x39-0x200000-0x0 - - Action - 12 - Text - 9 - - 0x7f-0x100000-0x0 - - Action - 11 - Text - 0x15 - - 0x7f-0x80000-0x0 - - Action - 11 - Text - 0x1b 0x7f - - 0xf700-0x220000-0x0 - - Action - 10 - Text - [1;2A - - 0xf700-0x240000-0x0 - - Action - 10 - Text - [1;5A - - 0xf700-0x260000-0x0 - - Action - 10 - Text - [1;6A - - 0xf701-0x220000-0x0 - - Action - 10 - Text - [1;2B - - 0xf701-0x240000-0x0 - - Action - 10 - Text - [1;5B - - 0xf701-0x260000-0x0 - - Action - 10 - Text - [1;6B - - 0xf702-0x220000-0x0 - - Action - 10 - Text - [1;2D - - 0xf702-0x240000-0x0 - - Action - 10 - Text - [1;5D - - 0xf702-0x260000-0x0 - - Action - 10 - Text - [1;6D - - 0xf702-0x280000-0x0 - - Action - 10 - Text - b - - 0xf702-0x300000-0x0 - - Action - 11 - Text - 0x1 - - 0xf703-0x220000-0x0 - - Action - 10 - Text - [1;2C - - 0xf703-0x240000-0x0 - - Action - 10 - Text - [1;5C - - 0xf703-0x260000-0x0 - - Action - 10 - Text - [1;6C - - 0xf703-0x280000-0x0 - - Action - 10 - Text - f - - 0xf703-0x300000-0x0 - - Action - 11 - Text - 0x5 - - 0xf704-0x20000-0x0 - - Action - 10 - Text - [1;2P - - 0xf705-0x20000-0x0 - - Action - 10 - Text - [1;2Q - - 0xf706-0x20000-0x0 - - Action - 10 - Text - [1;2R - - 0xf707-0x20000-0x0 - - Action - 10 - Text - [1;2S - - 0xf708-0x20000-0x0 - - Action - 10 - Text - [15;2~ - - 0xf709-0x20000-0x0 - - Action - 10 - Text - [17;2~ - - 0xf70a-0x20000-0x0 - - Action - 10 - Text - [18;2~ - - 0xf70b-0x20000-0x0 - - Action - 10 - Text - [19;2~ - - 0xf70c-0x20000-0x0 - - Action - 10 - Text - [20;2~ - - 0xf70d-0x20000-0x0 - - Action - 10 - Text - [21;2~ - - 0xf70e-0x20000-0x0 - - Action - 10 - Text - [23;2~ - - 0xf70f-0x20000-0x0 - - Action - 10 - Text - [24;2~ - - 0xf728-0x0-0x0 - - Action - 11 - Text - 0x4 - - 0xf728-0x80000-0x0 - - Action - 10 - Text - d - - 0xf729-0x20000-0x0 - - Action - 10 - Text - [1;2H - - 0xf729-0x40000-0x0 - - Action - 10 - Text - [1;5H - - 0xf72b-0x20000-0x0 - - Action - 10 - Text - [1;2F - - 0xf72b-0x40000-0x0 - - Action - 10 - Text - [1;5F - - 0xf739-0x0-0x0 - - Action - 13 - Text - - - - Link Color - - Alpha Component - 1 - Blue Component - 1 - Color Space - sRGB - Green Component - 0.44092163085937452 - Red Component - 0.177825927734375 - - Minimum Contrast - 0.0 - Mouse Reporting - - Name - Default - Non Ascii Font - Monaco 12 - Non-ASCII Anti Aliased - - Normal Font - FiraMonoNerdFontCompleteM-Regular 16 - Only The Default BG Color Uses Transparency - - Option Key Sends - 0 - Prompt Before Closing 2 - - Right Option Key Sends - 0 - Rows - 40 - Screen - -1 - Scrollback Lines - 0 - Selected Text Color - - Alpha Component - 1 - Blue Component - 0.94509798288345337 - Color Space - sRGB - Green Component - 0.93725484609603882 - Red Component - 0.92549020051956177 - - Selection Color - - Alpha Component - 1 - Blue Component - 0.54509806632995605 - Color Space - sRGB - Green Component - 0.49019604921340942 - Red Component - 0.37647062540054321 - - Send Code When Idle - - Shortcut - - Show Mark Indicators - - Show Status Bar - - Silence Bell - - Status Bar Layout - - advanced configuration - - algorithm - 0 - auto-rainbow style - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Menlo-Regular 11 - remove empty components - - - components - - - class - iTermStatusBarGitComponent - configuration - - knobs - - base: compression resistance - 1 - base: priority - 5 - iTermStatusBarGitComponentPollingIntervalKey - 2 - maxwidth - +infinity - minwidth - 0 - shared text color - - Alpha Component - 1 - Blue Component - 0.62999999523162842 - Color Space - sRGB - Green Component - 0.62999999523162842 - Red Component - 0.89999997615814209 - - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - class - iTermStatusBarWorkingDirectoryComponent - configuration - - knobs - - base: compression resistance - 1 - base: priority - 5 - maxwidth - +infinity - minwidth - 0 - path - path - shared text color - - Alpha Component - 1 - Blue Component - 0.63 - Color Space - sRGB - Green Component - 0.90000000000000002 - Red Component - 0.90000000000000002 - - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - class - iTermStatusBarHostnameComponent - configuration - - knobs - - abbreviate-localhost - - base: compression resistance - 1 - base: priority - 5 - path - hostname - shared text color - - Alpha Component - 1 - Blue Component - 0.90000000000000002 - Color Space - sRGB - Green Component - 0.90000000000000002 - Red Component - 0.63 - - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - class - iTermStatusBarSpringComponent - configuration - - knobs - - iTermStatusBarSpringComponentSizeMultipleKey - 2 - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - class - iTermStatusBarMemoryUtilizationComponent - configuration - - knobs - - base: priority - 5 - shared text color - - Alpha Component - 1 - Blue Component - 0.90000000000000002 - Color Space - sRGB - Green Component - 0.63 - Red Component - 0.63 - - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - class - iTermStatusBarCPUUtilizationComponent - configuration - - knobs - - base: priority - 5 - shared text color - - Alpha Component - 1 - Blue Component - 0.89999997615814209 - Color Space - sRGB - Green Component - 0.62999999523162842 - Red Component - 0.89999997615814209 - - - layout advanced configuration dictionary value - - algorithm - 0 - default text color - - Alpha Component - 1 - Blue Component - 0.7611083984375 - Color Space - sRGB - Green Component - 0.50811672210693359 - Red Component - 0.43600910902023315 - - font - Hasklig-Semibold 12 - - - - - - Sync Title - - Tab Color - - Alpha Component - 1 - Blue Component - 0.24313725490196078 - Color Space - sRGB - Green Component - 0.17647058823529413 - Red Component - 0.16470588235294117 - - Tags - - Terminal Type - xterm-256color - Title Components - 2 - Transparency - 0.0 - Unicode Version - 9 - Unlimited Scrollback - - Use Bold Font - - Use Bright Bold - - Use HFS Plus Mapping - - Use Italic Font - - Use Non-ASCII Font - - Use Tab Color - - Use Underline Color - - Vertical Spacing - 1 - Visual Bell - - Window Type - 0 - Working Directory - /Users/luke - - - OnlyWhenMoreTabs - - OpenArrangementAtStartup - - OpenBookmark - - OpenNoWindowsAtStartup - - PMPrintingExpandedStateForPrint2 - - PerformDNSLookups - - PointerActions - - Button,1,1,, - - Action - kContextMenuPointerAction - - Button,2,1,, - - Action - kPasteFromSelectionPointerAction - - Gesture,ThreeFingerSwipeDown,, - - Action - kPrevWindowPointerAction - - Gesture,ThreeFingerSwipeLeft,, - - Action - kPrevTabPointerAction - - Gesture,ThreeFingerSwipeRight,, - - Action - kNextTabPointerAction - - Gesture,ThreeFingerSwipeUp,, - - Action - kNextWindowPointerAction - - - Print In Black And White - - PromptOnQuit - - ShowBookmarkName - - SmartPlacement - - SoundForEsc - - SplitPaneDimmingAmount - 0.10000000000000001 - StatusBarPosition - 1 - SwitchPaneModifier - 4 - SwitchTabModifier - 6 - TabStyle - 1 - TabStyleWithAutomaticOption - 5 - TabViewType - 0 - TmuxUsesDedicatedProfile - - TmuxVariableWindowSizesSupported - - URLHandlersByGuid - - ssh - 23A858CE-FD7D-4786-A923-61AD9047DD28 - - UseAdaptiveFrameRate - - UseBorder - - UseTmuxStatusBar - - VisualIndicatorForEsc - - WindowNumber - - WordCharacters - /-+\~_. - disableMetalWhenUnplugged - - findMode_iTerm - 0 - kCPKSelectionViewPreferredModeKey - 0 - kCPKSelectionViewShowHSBTextFieldsKey - - - diff --git a/boop/parseJson.js b/boop/parseJson.js deleted file mode 100644 index 89ceb2d..0000000 --- a/boop/parseJson.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - { - "api":1, - "name":"Parse JSON", - "description":"Parses a value as JSON and returns the parsed result", - "author":"Luke Channings", - "icon":"quote", - "tags":"add,slashes,escape" - } -**/ -function main(state) { - let selectedText = state.selection - - try { - state.text = JSON.parse(selectedText) - } catch (err) { - state.postError(`Didn't work. ${err}`) - } -} diff --git a/editorconfig b/editorconfig deleted file mode 100644 index 78c6dde..0000000 --- a/editorconfig +++ /dev/null @@ -1,8 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -charset = utf-8 -indent_style = space -indent_size = 2 diff --git a/fish/config.fish b/fish/config.fish deleted file mode 100644 index 05e8360..0000000 --- a/fish/config.fish +++ /dev/null @@ -1,37 +0,0 @@ -# FISH plugins -fundle plugin 'edc/bass' -fundle plugin 'tuvistavie/oh-my-fish-core' -fundle plugin 'tuvistavie/fish-completion-helpers' -fundle plugin 'oh-my-fish/plugin-foreign-env' -fundle plugin 'tuvistavie/fish-nvm' -fundle plugin 'LukeChannings/theme-l' -fundle plugin 'brgmnn/fish-docker-compose' -fundle plugin 'jukben/fish-nx' -fundle init - -# settings -set -gx EDITOR vim -set -gx VISUAL vim -set -gx GIT_EDITOR vim -set -gx FZF_DEFAULT_COMMAND 'rg --files --hidden --follow --glob "!{.git,node_modules}/*"' -set -gx fish_greeting -set -gx LESSOPEN "| "(which highlight)" --out-format xterm256 -s Zenburn --quiet --force %s" -set -gx LESS " -R -X -F " -set -gx SSH_AUTH_SOCK "~/.ssh/agent" - -alias git-branch-name="git rev-parse --abbrev-ref HEAD" - -export GPG_TTY=(tty) - -alias k8s-show-ns="kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n" - -alias k="kubectl" -alias r="radian" - -fish_add_path /opt/homebrew/bin /opt/homebrew/sbin $HOME/.cargo/bin - -alias hass="hass-cli -s https://home-assistant.private.channings.me --token $HASS_TOKEN" - -if test -f /opt/homebrew/Caskroom/miniforge/base/bin/conda - eval /opt/homebrew/Caskroom/miniforge/base/bin/conda "shell.fish" "hook" $argv | source -end diff --git a/fish/functions/convert-to-heic.fish b/fish/functions/convert-to-heic.fish deleted file mode 100644 index 4a923c1..0000000 --- a/fish/functions/convert-to-heic.fish +++ /dev/null @@ -1,6 +0,0 @@ -function convert-to-heic -d "Convert a PNG to HEIC" - set -l output_name (basename $argv[1] .png).heic - echo $output_name - heif-enc $argv[1] -L -b 12 -o $output_name - exiftool -overwrite_original -tagsFromFile $argv[1] -all:all $output_name -end diff --git a/fish/functions/fish_user_key_bindings.fish b/fish/functions/fish_user_key_bindings.fish deleted file mode 100644 index ff61c90..0000000 --- a/fish/functions/fish_user_key_bindings.fish +++ /dev/null @@ -1,2 +0,0 @@ - -fzf_key_bindings diff --git a/fish/functions/fundle.fish b/fish/functions/fundle.fish deleted file mode 100644 index 45742dc..0000000 --- a/fish/functions/fundle.fish +++ /dev/null @@ -1,453 +0,0 @@ -set __fundle_current_version '0.7.0' - -function __fundle_seq -a upto - seq 1 1 $upto 2>/dev/null -end - -function __fundle_next_arg -a index - set -l args $argv[2..-1] - set -l arg_index (math $index + 1) - if test (count $args) -lt $arg_index - echo "missing argument for $args[$index]" - return 1 - end - set -l arg $args[$arg_index] - switch $arg - case '--*' - echo "expected argument for $args[$index], got $arg"; and return 1 - case '*' - echo $arg; and return 0 - end -end - -function __fundle_compare_versions -a version1 -a version2 - for i in (__fundle_seq 4) - set -l v1 (echo $version1 | cut -d '.' -f $i | sed -Ee 's/[a-z]+//g') - set -l v2 (echo $version2 | cut -d '.' -f $i | sed -Ee 's/[a-z]+//g') - if test \( -n $v1 -a -z $v2 \) -o \( -n $v1 -a -n $v2 -a $v1 -lt $v2 \) - echo -n "lt"; and return 0 - else if test \( -z $v1 -a -n $v2 \) -o \( -n $v1 -a -n $v2 -a $v1 -gt $v2 \) - echo -n "gt"; and return 0 - end - end - echo -n "eq"; and return 0 -end - -function __fundle_date -d "returns a date" - set -l d (date +%s%N) - if echo $d | string match -rvq 'N' - echo $d - else - gdate +%s%N - end - return 0 -end - -function __fundle_self_update -d "updates fundle" - set -l fundle_repo_url "https://github.com/tuvistavie/fundle.git" - # This `sed` stays for now since doing it easily with `string` requires "--filter", which is only in 2.6.0 - set -l latest (command git ls-remote --tags $fundle_repo_url | sed -n -e 's|.*refs/tags/v\(.*\)|\1|p' | tail -n 1) - if test (__fundle_compare_versions $latest (__fundle_version)) != "gt" - echo "fundle is already up to date"; and return 0 - else - set -l file_url_template 'https://raw.githubusercontent.com/tuvistavie/fundle/VERSION/functions/fundle.fish' - set -l file_url (string replace 'VERSION' -- "v$latest" $file_url_template) - set -l tmp_file (mktemp /tmp/fundle.XXX) - set -l update_message "fundle has been updated to version $latest" - curl -Ls $file_url > $tmp_file; and mv $tmp_file (status -f); and echo $update_message; and return 0 - end -end - -function __fundle_url_rev -d "prints the revision from the url" -a git_url - set -l rev (echo $git_url | cut -d '#' -f 2 -s) - if test -n "$rev" - echo $rev - else - echo HEAD - end -end - -function __fundle_remote_url -d "prints the remote url from the full git url" -a git_url - echo $git_url | cut -d '#' -f 1 -end - -function __fundle_rev_parse -d "prints the revision if any" -a dir -a commitish - set -l sha (command git --git-dir $dir rev-parse -q --verify $commitish 2>/dev/null) - if test $status -eq 0 - echo -n $sha - return 0 - end - return 1 -end - -function __fundle_commit_sha -d "returns sha of the commit-ish" -a dir -a commitish - if test -d "$dir/.git" - set dir "$dir/.git" - end - if __fundle_rev_parse $dir "origin/$commitish" - return 0 - end - __fundle_rev_parse $dir $commitish -end - -function __fundle_plugins_dir -d "returns fundle directory" - if test -z "$fundle_plugins_dir" - if test -n "$XDG_CONFIG_HOME" - echo $XDG_CONFIG_HOME/fish/fundle - else - echo $HOME/.config/fish/fundle - end - else - echo $fundle_plugins_dir - end -end - -function __fundle_no_git -d "check if git is installed" - # `command -q` is >= 2.5.0 - if not command -s git > /dev/null 2>&1 - echo "git needs to be installed and in the path" - return 0 - end - return 1 -end - -function __fundle_check_date -d "check date" - if date +%s%N | string match -rvq 'N' - return 0 - end - if command -s gdate > /dev/null 2>&1 - return 0 - end - echo "You need to have a GNU date compliant date installed to use profiling. Use 'brew install coreutils' on OSX" - return 1 -end - -function __fundle_get_url -d "returns the url for the given plugin" -a repo - echo "https://github.com/$repo.git" -end - - -function __fundle_plugin_index -d "returns the index of the plugin" -a plugin - for i in (__fundle_seq (count $__fundle_plugin_names)) - if test "$__fundle_plugin_names[$i]" = "$plugin" - return $i - end - end - # NOTE: should never reach this point - echo "could not find plugin: $plugin" - exit 1 -end - -function __fundle_checkout_revision -a plugin -a git_url - set -l plugin_dir (__fundle_plugins_dir)/$plugin - set -l git_dir $plugin_dir/.git - - set -l sha (__fundle_commit_sha $git_dir (__fundle_url_rev $git_url)) - if test $status -eq 0 - command git --git-dir="$git_dir" --work-tree="$plugin_dir" checkout -q -f $sha - else - echo "Could not checkout $plugin revision $sha" - return 1 - end -end - -function __fundle_update_plugin -d "update the given plugin" -a plugin -a git_url - echo "Updating $plugin" - - set -l remote_url (__fundle_remote_url $git_url) - set -l git_dir (__fundle_plugins_dir)/$plugin/.git - - command git --git-dir=$git_dir remote set-url origin $remote_url 2>/dev/null - command git --git-dir=$git_dir fetch -q 2>/dev/null - - __fundle_checkout_revision $plugin $git_url -end - -function __fundle_install_plugin -d "install the given plugin" -a plugin -a git_url - if __fundle_no_git - return 1 - end - - set -l plugin_dir (__fundle_plugins_dir)/$plugin - set -l git_dir $plugin_dir/.git - set -l remote_url (__fundle_remote_url $git_url) - - if test -d $plugin_dir - echo "$argv[1] installed in $plugin_dir" - return 0 - else - echo "Installing $plugin" - command git clone -q $remote_url $plugin_dir - __fundle_checkout_revision $plugin $git_url - end -end - -function __fundle_update -d "update the given plugin, or all if unspecified" -a plugin - if test -n "$plugin"; and test ! -d (__fundle_plugins_dir)/$plugin/.git - echo "$plugin not installed. You may need to run 'fundle install'" - return 1 - end - - if test -n "$plugin" - set -l index (__fundle_plugin_index $plugin) - __fundle_update_plugin "$plugin" $__fundle_plugin_urls[$index] - else - for i in (__fundle_seq (count $__fundle_plugin_names)) - __fundle_update_plugin $__fundle_plugin_names[$i] $__fundle_plugin_urls[$i] - end - end -end - -function __fundle_show_doc_msg -d "show a link to fundle docs" - if test (count $argv) -ge 1 - echo $argv - end - echo "See the docs for more info. https://github.com/tuvistavie/fundle" -end - -function __fundle_load_plugin -a plugin -a path -a fundle_dir -a profile -d "load a plugin" - if begin; set -q __fundle_loaded_plugins; and contains $plugin $__fundle_loaded_plugins; end - return 0 - end - - set -l plugin_dir (string replace -r '/.$' '' -- "$fundle_dir/$plugin/$path") - - if not test -d $plugin_dir - __fundle_show_doc_msg "$plugin not installed. You may need to run 'fundle install'" - return 0 - end - - # Take everything but "plugin-" from the last path component - set -l plugin_name (string replace -r '.*/(plugin-)?(.*)$' '$2' -- $plugin) - set -l init_file "$plugin_dir/init.fish" - set -l conf_dir "$plugin_dir/conf.d" - set -l bindings_file "$plugin_dir/key_bindings.fish" - set -l functions_dir "$plugin_dir/functions" - set -l completions_dir "$plugin_dir/completions" - set -l plugin_paths $__fundle_plugin_name_paths - - if begin; test -d $functions_dir; and not contains $functions_dir $fish_function_path; end - set fish_function_path $fish_function_path[1] $functions_dir $fish_function_path[2..-1] - end - - if begin; test -d $completions_dir; and not contains $completions_dir $fish_complete_path; end - set fish_complete_path $fish_complete_path[1] $completions_dir $fish_complete_path[2..-1] - end - - if test -f $init_file - source $init_file - else if test -d $conf_dir - # read all *.fish files in conf.d - for f in $conf_dir/*.fish - source $f - end - else - # For compatibility with oh-my-fish themes, if there is no `init.fish` file in the plugin, - # which is the case with themses, the root directory of the plugin is trerated as a functions - # folder, so we include it in the `fish_function_path` variable. - if not contains $plugin_dir $fish_function_path - set fish_function_path $fish_function_path[1] $plugin_dir $fish_function_path[2..-1] - end - end - - if test -f $bindings_file - set -g __fundle_binding_paths $bindings_file $__fundle_binding_paths - end - - set -g __fundle_loaded_plugins $plugin $__fundle_loaded_plugins - - set -l dependencies (printf '%s\n' $plugin_paths $__fundle_plugin_name_paths | sort | uniq -u) - for dependency in $dependencies - set -l name_path (string split : -- $dependency) - if test "$profile" -eq 1 - set -l start_time (__fundle_date +%s%N) - __fundle_load_plugin $name_path[1] $name_path[2] $fundle_dir $profile - set -l ellapsed_time (math \((__fundle_date +%s%N) - $start_time\) / 1000) - echo "$name_path[1]": {$ellapsed_time}us - else - __fundle_load_plugin $name_path[1] $name_path[2] $fundle_dir $profile - end - end - - emit "init_$plugin_name" $plugin_dir -end - -function __fundle_bind -d "set up bindings" - if functions -q fish_user_key_bindings; and not functions -q __fish_user_key_bindings - functions -c fish_user_key_bindings __fish_user_key_bindings - end - - function fish_user_key_bindings - for bindings in $__fundle_binding_paths - source $bindings - end - if functions -q __fish_user_key_bindings - __fish_user_key_bindings - end - end -end - -function __fundle_init -d "initialize fundle" - set -l fundle_dir (__fundle_plugins_dir) - - if test (count $__fundle_plugin_names) -eq 0 - __fundle_show_doc_msg "No plugin registered. You need to call 'fundle plugin NAME' before using 'fundle init'. \ - -Try reloading your shell if you just edited your configuration." - return 1 - end - - set -l profile 0 - if begin; contains -- -p $argv; or contains -- --profile $argv; and __fundle_check_date; end - set profile 1 - end - - for name_path in $__fundle_plugin_name_paths - set -l name_path (string split : -- $name_path) - if test "$profile" -eq 1 - set -l start_time (__fundle_date +%s%N) - __fundle_load_plugin $name_path[1] $name_path[2] $fundle_dir $profile - set -l ellapsed_time (math \((__fundle_date +%s%N) - $start_time\) / 1000) - echo "$name_path[1]": {$ellapsed_time}us - else - __fundle_load_plugin $name_path[1] $name_path[2] $fundle_dir $profile - end - end - - __fundle_bind -end - -function __fundle_install -d "install plugin" - if test (count $__fundle_plugin_names) -eq 0 - __fundle_show_doc_msg "No plugin registered. You need to call 'fundle plugin NAME' before using 'fundle install'" - end - - for i in (__fundle_seq (count $__fundle_plugin_names)) - __fundle_install_plugin $__fundle_plugin_names[$i] $__fundle_plugin_urls[$i] $argv - end - - set -l original_plugins_count (count (__fundle_list -s)) - __fundle_init - - # if plugins count increase after init, new plugins have dependencies - # install new plugins dependencies if any - if test (count (__fundle_list -s)) -gt $original_plugins_count - __fundle_install $argv - end -end - -function __fundle_clean -d "cleans fundle directory" - set -l fundle_dir (__fundle_plugins_dir) - set -l used_plugins (__fundle_list -s) - set -l installed_plugins $fundle_dir/*/*/ - for installed_plugin in $installed_plugins - set -l plugin (string trim --chars="/" \ - (string replace -r -- "$fundle_dir" "" $installed_plugin)) - if not contains $plugin $used_plugins - echo "Removing $plugin" - rm -rf $fundle_dir/$plugin - end - end -end - -function __fundle_plugin -d "add plugin to fundle" -a name - set -l plugin_url "" - set -l plugin_path "." - set -l argv_count (count $argv) - set -l skip_next true - if test $argv_count -eq 0 -o -z "$argv" - echo "usage: fundle plugin NAME [[--url] URL] [--path PATH]" - return 1 - else if test $argv_count -gt 1 - for i in (__fundle_seq (count $argv)) - test $skip_next = true; and set skip_next false; and continue - set -l arg $argv[$i] - switch $arg - case '--url' - set plugin_url (__fundle_next_arg $i $argv) - test $status -eq 1; and echo $plugin_url; and return 1 - set skip_next true - case '--path' - set plugin_path (__fundle_next_arg $i $argv) - test $status -eq 1; and echo $plugin_path; and return 1 - set skip_next true - case '--*' - echo "unknown flag $arg"; and return 1 - case '*' - test $i -ne 2; and echo "invalid argument $arg"; and return 1 - set plugin_url $arg - end - end - end - test -z "$plugin_url"; and set plugin_url (__fundle_get_url $name) - - if not contains $name $__fundle_plugin_names - set -g __fundle_plugin_names $__fundle_plugin_names $name - set -g __fundle_plugin_urls $__fundle_plugin_urls $plugin_url - set -g __fundle_plugin_name_paths $__fundle_plugin_name_paths $name:$plugin_path - end -end - -function __fundle_version -d "prints fundle version" - echo $__fundle_current_version -end - -function __fundle_print_help -d "prints fundle help" - echo "usage: fundle (init | plugin | list | install | update | clean | self-update | version | help)" -end - -function __fundle_list -d "list registered plugins" - if begin; contains -- -s $argv; or contains -- --short $argv; end - for name in $__fundle_plugin_names - echo $name - end - else - for i in (__fundle_seq (count $__fundle_plugin_names)) - echo {$__fundle_plugin_names[$i]}\n\t{$__fundle_plugin_urls[$i]} - end - end -end - -function fundle -d "run fundle" - if __fundle_no_git - return 1 - end - - set -l sub_args "" - - switch (count $argv) - case 0 - __fundle_print_help - return 1 - case 1 - case '*' - set sub_args $argv[2..-1] - end - - switch $argv[1] - case "init" - __fundle_init $sub_args - case "plugin" - __fundle_plugin $sub_args - case "list" - __fundle_list $sub_args - case "plugins" - echo "'fundle plugins' has been replaced by 'fundle list'" - case "install" - __fundle_install $sub_args - case "update" - __fundle_update $sub_args - case "clean" - __fundle_clean - case "self-update" - __fundle_self_update - case "version" -v --version - __fundle_version - case "help" -h --help - __fundle_print_help - return 0 - case "*" - __fundle_print_help - return 1 - end -end diff --git a/fish/functions/gitco.fish b/fish/functions/gitco.fish deleted file mode 100644 index 2bb2404..0000000 --- a/fish/functions/gitco.fish +++ /dev/null @@ -1,9 +0,0 @@ -function gitco -d "Fuzzy-find and checkout a branch" - if test $argv[1] = '--' - git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | awk ' !x[$0]++' | egrep -v '^[a-f0-9]{40}$' | fzf | xargs git checkout - else if test $argv[1] - git checkout $argv - else - git branch --all | grep -v '*' | string replace -r 'remotes/.*?/' '' | sort -u | fzf | xargs git checkout - end -end diff --git a/fish/functions/gzipsize.fish b/fish/functions/gzipsize.fish deleted file mode 100644 index 6bc5a18..0000000 --- a/fish/functions/gzipsize.fish +++ /dev/null @@ -1,6 +0,0 @@ -function gzipsize - gzip $argv[1] - du -h $argv[1].gz - rm $argv[1].gz -end - diff --git a/fish/functions/krun.fish b/fish/functions/krun.fish deleted file mode 100644 index 2674f53..0000000 --- a/fish/functions/krun.fish +++ /dev/null @@ -1,59 +0,0 @@ -function krun --description "Run an ephemeral container in a kubernetes cluster" - argparse --name=krun 'H/hostname=' 'a/arch=' 'd/debug' -- $argv - or return - - set -x 'LC_ALL' 'C' - set -l USAGE "krun [-H|--hostname=node-hostname] [-a|--arch=architecture]" - - set -l image $argv[1] - set -l randomAffix (cat /dev/random | tr -dc '[:lower:]' | head -c 8) - - if ! test -n "$image" - echo $USAGE - return - end - - set -l spec ' ---- -apiVersion: v1 -kind: Namespace -metadata: - name: krun ---- -kind: Pod -apiVersion: v1 -metadata: - name: krun-'$randomAffix' - namespace: krun -spec: - containers: - - name: shell - image: '$image' - tty: true - stdin: true - command: ["/bin/sh"] - restartPolicy: Never' - - if test -n "$_flag_hostname" -o -n "$_flag_arch" - set spec $spec(echo -e '\n nodeSelector:' | string collect) - if test -n "$_flag_hostname" - set spec $spec(echo -e '\n kubernetes.io/hostname: '$_flag_hostname | string collect) - end - if test -n "$_flag_arch" - set spec $spec(echo -e '\n kubernetes.io/arch: '$_flag_arch | string collect) - end - end - - if test -n "$_flag_debug" - echo $spec - end - - echo $spec | kubectl apply -f - - - kubectl wait --for=condition=Ready -n krun pod krun-$randomAffix - - kubectl attach -n krun krun-$randomAffix -it --pod-running-timeout=2m0s - - kubectl delete -n krun pod krun-$randomAffix & -end - diff --git a/fish/functions/ls.fish b/fish/functions/ls.fish deleted file mode 100644 index d009de0..0000000 --- a/fish/functions/ls.fish +++ /dev/null @@ -1,7 +0,0 @@ -function ls --wraps=logo-ls --description 'alias ls=logo-ls' - if test (command -v logo-ls) - logo-ls $argv - else - /bin/ls $argv - end -end diff --git a/fish/functions/mkcd.fish b/fish/functions/mkcd.fish deleted file mode 100644 index 658fe16..0000000 --- a/fish/functions/mkcd.fish +++ /dev/null @@ -1,4 +0,0 @@ -function mkcd - mkdir -p $argv[1] - cd $argv[1] -end diff --git a/fish/functions/mkpass.fish b/fish/functions/mkpass.fish deleted file mode 100644 index a892920..0000000 --- a/fish/functions/mkpass.fish +++ /dev/null @@ -1,4 +0,0 @@ -function mkpass - set -x 'LC_ALL' 'C' - cat /dev/random | tr -dc '[:alnum:]' | head -c 40 -end diff --git a/fish/iterm2_shell_integration.fish b/fish/iterm2_shell_integration.fish deleted file mode 100644 index 39fba4c..0000000 --- a/fish/iterm2_shell_integration.fish +++ /dev/null @@ -1,92 +0,0 @@ -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -if begin; status --is-interactive; and not functions -q -- iterm2_status; and [ "$ITERM_ENABLE_SHELL_INTEGRATION_WITH_TMUX""$TERM" != screen ]; and [ "$TERM" != dumb ]; and [ "$TERM" != linux ]; end - function iterm2_status - printf "\033]133;D;%s\007" $argv - end - - # Mark start of prompt - function iterm2_prompt_mark - printf "\033]133;A\007" - end - - # Mark end of prompt - function iterm2_prompt_end - printf "\033]133;B\007" - end - - # Tell terminal to create a mark at this location - function iterm2_preexec --on-event fish_preexec - # For other shells we would output status here but we can't do that in fish. - printf "\033]133;C;\007" - end - - # Usage: iterm2_set_user_var key value - # These variables show up in badges (and later in other places). For example - # iterm2_set_user_var currentDirectory "$PWD" - # Gives a variable accessible in a badge by \(user.currentDirectory) - # Calls to this go in iterm2_print_user_vars. - function iterm2_set_user_var - printf "\033]1337;SetUserVar=%s=%s\007" "$argv[1]" (printf "%s" "$argv[2]" | base64 | tr -d "\n") - end - - function iterm2_write_remotehost_currentdir_uservars - printf "\033]1337;RemoteHost=%s@%s\007\033]1337;CurrentDir=%s\007" $USER $iterm2_hostname $PWD - - # Users can define a function called iterm2_print_user_vars. - # It should call iterm2_set_user_var and produce no other output. - if functions -q -- iterm2_print_user_vars - iterm2_print_user_vars - end - - end - - functions -c fish_prompt iterm2_fish_prompt - - functions -c fish_mode_prompt iterm2_fish_mode_prompt - function fish_mode_prompt --description 'Write out the mode prompt; do not replace this. Instead, change fish_mode_prompt before sourcing .iterm2_shell_integration.fish, or modify iterm2_fish_mode_prompt instead.' - set -l last_status $status - - iterm2_status $last_status - iterm2_write_remotehost_currentdir_uservars - if not functions iterm2_fish_prompt | grep iterm2_prompt_mark > /dev/null - iterm2_prompt_mark - end - sh -c "exit $last_status" - - iterm2_fish_mode_prompt - end - - function fish_prompt --description 'Write out the prompt; do not replace this. Instead, change fish_prompt before sourcing .iterm2_shell_integration.fish, or modify iterm2_fish_prompt instead.' - # Remove the trailing newline from the original prompt. This is done - # using the string builtin from fish, but to make sure any escape codes - # are correctly interpreted, use %b for printf. - printf "%b" (string join "\n" (iterm2_fish_prompt)) - - iterm2_prompt_end - end - - # If hostname -f is slow for you, set iterm2_hostname before sourcing this script - if not set -q -g iterm2_hostname - set -g iterm2_hostname (hostname -f 2>/dev/null) - # some flavors of BSD (i.e. NetBSD and OpenBSD) don't have the -f option - if test $status -ne 0 - set -g iterm2_hostname (hostname) - end - end - - iterm2_write_remotehost_currentdir_uservars - printf "\033]1337;ShellIntegrationVersion=10;shell=fish\007" -end diff --git a/flake.lock b/flake.lock index c920143..a701b8c 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,43 @@ { "nodes": { + "brew-api": { + "flake": false, + "locked": { + "lastModified": 1720368573, + "narHash": "sha256-sf83bf99I0aGvesGvg6PWQLGnTy4++tB0d7uQFYsKDI=", + "owner": "BatteredBunny", + "repo": "brew-api", + "rev": "ef88fc9cae4c96d255922e2f0ae0110486cf402e", + "type": "github" + }, + "original": { + "owner": "BatteredBunny", + "repo": "brew-api", + "type": "github" + } + }, + "brew-nix": { + "inputs": { + "brew-api": [ + "brew-api" + ], + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1717142677, + "narHash": "sha256-IJN07O2AcWoTI6lFW8GSrhi7MJ0P1pe4RY0aaG28t5w=", + "owner": "BatteredBunny", + "repo": "brew-nix", + "rev": "0b084fb3a92ec782a67f21110333fc2480d1285c", + "type": "github" + }, + "original": { + "owner": "BatteredBunny", + "repo": "brew-nix", + "type": "github" + } + }, "cachix": { "inputs": { "devenv": "devenv_2", @@ -30,6 +68,56 @@ "type": "github" } }, + "darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1720337362, + "narHash": "sha256-9TNQtlwu97NPaJYsKkdObOsy0MLN4NAOBz0pqwH3KnA=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "0f89b73f41eaa1dde67b291452c181d9a75f10dd", + "type": "github" + }, + "original": { + "owner": "lnl7", + "repo": "nix-darwin", + "type": "github" + } + }, + "darwin-systems": { + "locked": { + "lastModified": 1689347925, + "narHash": "sha256-ozenz5bFe1UUqOn7f60HRmgc01BgTGIKZ4Xl+HbocGQ=", + "owner": "nix-systems", + "repo": "default-darwin", + "rev": "2235d7e6cc29ae99878133c95e9fe5e157661ffb", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-darwin", + "type": "github" + } + }, + "default-systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "devenv": { "inputs": { "cachix": "cachix", @@ -62,7 +150,7 @@ "flake-compat" ], "nix": "nix", - "nixpkgs": "nixpkgs", + "nixpkgs": "nixpkgs_2", "poetry2nix": "poetry2nix", "pre-commit-hooks": [ "devenv", @@ -121,6 +209,24 @@ "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { "lastModified": 1689068808, "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", @@ -135,9 +241,9 @@ "type": "github" } }, - "flake-utils_2": { + "flake-utils_3": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1710146030, @@ -175,6 +281,27 @@ "type": "github" } }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1720327769, + "narHash": "sha256-kAsg3Lg4YKKpGw+f1W2s5hzjP8B0y/juowvjK8utIag=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "6b7ce96f34b324e4e104abc30d06955d216bac71", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, "nix": { "inputs": { "flake-compat": "flake-compat", @@ -254,16 +381,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1692808169, - "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "lastModified": 1715266358, + "narHash": "sha256-doPgfj+7FFe9rfzWo1siAV2mVCasW+Bh8I1cToAXEE4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", + "rev": "f1010e0469db743d14519a1efd37e23f8513d714", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -318,23 +445,39 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1716977621, - "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", "type": "github" }, "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1720031269, + "narHash": "sha256-rwz8NJZV+387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9f4128e00b0ae8ec65918efeba59db998750ead6", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", "type": "github" } }, "poetry2nix": { "inputs": { - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "nix-github-actions": "nix-github-actions", "nixpkgs": [ "devenv", @@ -363,7 +506,7 @@ "devenv", "flake-compat" ], - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils_3", "gitignore": "gitignore", "nixpkgs": [ "devenv", @@ -387,9 +530,14 @@ }, "root": { "inputs": { + "brew-api": "brew-api", + "brew-nix": "brew-nix", + "darwin": "darwin", + "darwin-systems": "darwin-systems", + "default-systems": "default-systems", "devenv": "devenv", - "nixpkgs": "nixpkgs_2", - "systems": "systems_3" + "home-manager": "home-manager", + "nixpkgs": "nixpkgs_3" } }, "systems": { diff --git a/flake.nix b/flake.nix index 7010b3f..8c806b0 100644 --- a/flake.nix +++ b/flake.nix @@ -1,81 +1,61 @@ { inputs = { - nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; - systems.url = "github:nix-systems/default"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + default-systems.url = "github:nix-systems/default"; + darwin-systems.url = "github:nix-systems/default-darwin"; + + darwin.url = "github:lnl7/nix-darwin"; + darwin.inputs.nixpkgs.follows = "nixpkgs"; + + home-manager.url = "github:nix-community/home-manager/master"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + brew-nix = { + url = "github:BatteredBunny/brew-nix"; + inputs.brew-api.follows = "brew-api"; + }; + + brew-api = { + url = "github:BatteredBunny/brew-api"; + flake = false; + }; + devenv.url = "github:cachix/devenv"; devenv.inputs.nixpkgs.follows = "nixpkgs"; }; - nixConfig = { - extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="; - extra-substituters = "https://devenv.cachix.org"; - }; - outputs = { self, nixpkgs, devenv, - systems, - ... - }@inputs: - let - forEachSystem = nixpkgs.lib.genAttrs (import systems); - util = import ./modules/util; - in - { - packages = forEachSystem (system: { - devenv-up = self.devShells.${system}.default.config.procfileScript; - }); - - devShells = forEachSystem ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - { - default = devenv.lib.mkShell { - inherit inputs pkgs; - modules = [ - { - packages = with pkgs; [ - stylua - shfmt - shellcheck - nixfmt-rfc-style - ]; - - languages.nix.enable = true; - - pre-commit.hooks = { - # lint shell scripts - shellcheck.enable = true; - # execute example shell from Markdown files - mdsh.enable = true; + default-systems, + darwin-systems, - nixfmt = { - enable = true; - package = pkgs.nixfmt-rfc-style; - }; - }; + darwin, + home-manager, + brew-nix, - scripts = { - install-workspace-extensions.exec = ( - util.installWorkspaceVSCodeExtensions ( - with pkgs.vscode-extensions; - [ - jnoortheen.nix-ide - thenuprojectcontributors.vscode-nushell-lang - timonwong.shellcheck - ] - ) - ); - }; - } + ... + }@inputs: + ( + let + forEachDarwinSystem = nixpkgs.lib.genAttrs (import darwin-systems); + in + { + darwinConfigurations = forEachDarwinSystem (system: { + Scimitar = darwin.lib.darwinSystem { + inherit system; + modules = [ + home-manager.darwinModules.home-manager + { nixpkgs.overlays = [ brew-nix.overlay.${system} ]; } + ./systems/Scimitar.nix ]; }; - } - ); - }; + }); + + packages = darwin.packages; + } + ); } diff --git a/git/config b/git/config deleted file mode 100644 index 7430dc0..0000000 --- a/git/config +++ /dev/null @@ -1,39 +0,0 @@ -[init] - defaultBranch = main - -[user] - name = Luke Channings - email = luke@channings.me - signingKey= 177226CADB96E582 - -[core] - editor = vim - autoclrf = input - ignorecase = false - -[merge] - tool = vscode -[mergetool "vscode"] - cmd = code --wait $MERGED -[diff] - tool = vscode -[difftool "vscode"] - cmd = code --wait --diff $LOCAL $REMOTE - -[alias] - lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -[filter "lfs"] - clean = git-lfs clean -- %f - smudge = git-lfs smudge -- %f - process = git-lfs filter-process - required = true -[credential] - helper = store -[diff "sopsdiffer"] - textconv = sops -d -[commit] - gpgsign = true -[gpg] - program = /opt/homebrew/bin/gpg -[pull] - rebase = true diff --git a/homebrew/Brewfile b/homebrew/Brewfile deleted file mode 100644 index 7c93215..0000000 --- a/homebrew/Brewfile +++ /dev/null @@ -1,98 +0,0 @@ -tap "argoproj/tap" -tap "aws/tap" -tap "boz/repo" -tap "bufbuild/buf" -tap "esphen/wsta", "https://github.com/esphen/wsta.git" -tap "fabianishere/personal" -tap "hivemq/mqtt-cli" -tap "homebrew/bundle" -tap "homebrew/cask" -tap "homebrew/cask-fonts" -tap "homebrew/cask-versions" -tap "homebrew/core" -tap "homebrew/services" -tap "instrumenta/instrumenta" -tap "johanhaleby/kubetail" -tap "marblenix/onivim2" -tap "mistertea/et" -tap "universal-ctags/universal-ctags" -brew "argocd" -brew "bash" -brew "bat" -brew "coreutils" -brew "deno" -brew "editorconfig" -brew "fish" -brew "fzf" -brew "gnu-sed" -brew "gpatch" -brew "grep" -brew "grpcurl" -brew "helm" -brew "highlight" -brew "homeassistant-cli" -brew "htop" -brew "jq" -brew "jsonnet" -brew "k9s" -brew "kubernetes-cli" -brew "kubeseal" -brew "ncdu" -brew "node" -brew "pkg-config" -brew "ripgrep" -brew "shellcheck" -brew "socat" -brew "tmux" -brew "tree" -brew "vim" -brew "watch" -brew "watchman" -brew "websocat" -cask "alfred" -cask "apparency" -cask "balenaetcher" -cask "brave-browser" -cask "brave-browser-nightly" -cask "docker" -cask "firefox-developer-edition" -cask "font-fira-mono" -cask "font-hasklig" -cask "font-inconsolata" -cask "font-monoid" -cask "font-roboto" -cask "font-source-code-pro" -cask "font-victor-mono" -cask "iterm2" -cask "marked" -cask "monitorcontrol" -cask "onivim2-nightly" -cask "plexamp" -cask "qlcolorcode" -cask "qlimagesize" -cask "qlmarkdown" -cask "qlstephen" -cask "qlvideo" -cask "quicklook-csv" -cask "quicklook-json" -cask "quicklookase" -cask "steam" -cask "suspicious-package" -cask "swish" -cask "vscodium" -cask "webtorrent" -mas "1Blocker", id: 1107421413 -mas "DaisyDisk", id: 411643860 -mas "Discovery", id: 1381004916 -mas "Disk Speed Test", id: 425264550 -mas "GarageBand", id: 682658836 -mas "iMovie", id: 408981434 -mas "Keynote", id: 409183694 -mas "Messenger", id: 1480068668 -mas "MQTT Explorer", id: 1455214828 -mas "Numbers", id: 409203825 -mas "Pages", id: 409201541 -mas "Telegram", id: 747648890 -mas "Textual IRC Client", id: 896450579 -mas "The Unarchiver", id: 425424353 -mas "WireGuard", id: 1451685025 diff --git a/install b/install index fc8c8c9..0b49ee1 100755 --- a/install +++ b/install @@ -1,7 +1,20 @@ -#!/usr/bin/env bash +#!/bin/sh -set -e -o pipefail -p +set -e -if ! command -v nix; then - curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install +if ! command -v nix > /dev/null; then + echo "Nix is not installed. Installing..." + + curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm + + # shellcheck disable=SC1091 + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh +else + echo "Nix is installed" fi + +CONFIG_REPO="github:LukeChannings/dotfiles/nix" +HOST="${1:-$(hostname)}" +SYSTEM="$([ "$(uname -m)" = "arm64" ] && echo "aarch64" || echo "x86_64")-darwin" + +nix run --refresh "$CONFIG_REPO#darwin-rebuild" -- switch --refresh --flake "$CONFIG_REPO#${SYSTEM}.${HOST}" diff --git a/modules/util.nix b/modules/util.nix deleted file mode 100644 index 30dbd16..0000000 --- a/modules/util.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - installWorkspaceVSCodeExtensions = - with builtins; - extensions: # bash - '' - rm -rf .vscode/extensions - mkdir -p .vscode/extensions - ${concatStringsSep "\n" ( - map (extension: "cp -R ${extension}/share/vscode/extensions/* .vscode/extensions/") extensions - )} - - chmod +rw -R .vscode/extensions - - for extension in $(ls .vscode/extensions); do - extensionPath=".vscode/extensions/''${extension}" - main="$(jq -r ".main" ''${extensionPath}/package.json)" - - if [ ! -e "''${extensionPath}/''${main}" ]; then - echo "''${extension} entry point is missing. Fixing." - tmp="$(mktemp)" - jq ".main = \"''${main}.js\"" "''${extensionPath}/package.json" > $tmp - cat $tmp > "''${extensionPath}/package.json" - fi - done - ''; -} diff --git a/nushell/config.nu b/nushell/config.nu deleted file mode 100644 index 6277028..0000000 --- a/nushell/config.nu +++ /dev/null @@ -1,495 +0,0 @@ -# Nushell Config File - -module completions { - # Custom completions for external commands (those outside of Nushell) - # Each completions has two parts: the form of the external command, including its flags and parameters - # and a helper command that knows how to complete values for those flags and parameters - # - # This is a simplified version of completions for git branches and git remotes - def "nu-complete git branches" [] { - ^git branch | lines | each { |line| $line | str replace '[\*\+] ' '' | str trim } - } - - def "nu-complete git remotes" [] { - ^git remote | lines | each { |line| $line | str trim } - } - - # Download objects and refs from another repository - export extern "git fetch" [ - repository?: string@"nu-complete git remotes" # name of the repository to fetch - branch?: string@"nu-complete git branches" # name of the branch to fetch - --all # Fetch all remotes - --append(-a) # Append ref names and object names to .git/FETCH_HEAD - --atomic # Use an atomic transaction to update local refs. - --depth: int # Limit fetching to n commits from the tip - --deepen: int # Limit fetching to n commits from the current shallow boundary - --shallow-since: string # Deepen or shorten the history by date - --shallow-exclude: string # Deepen or shorten the history by branch/tag - --unshallow # Fetch all available history - --update-shallow # Update .git/shallow to accept new refs - --negotiation-tip: string # Specify which commit/glob to report while fetching - --negotiate-only # Do not fetch, only print common ancestors - --dry-run # Show what would be done - --write-fetch-head # Write fetched refs in FETCH_HEAD (default) - --no-write-fetch-head # Do not write FETCH_HEAD - --force(-f) # Always update the local branch - --keep(-k) # Keep dowloaded pack - --multiple # Allow several arguments to be specified - --auto-maintenance # Run 'git maintenance run --auto' at the end (default) - --no-auto-maintenance # Don't run 'git maintenance' at the end - --auto-gc # Run 'git maintenance run --auto' at the end (default) - --no-auto-gc # Don't run 'git maintenance' at the end - --write-commit-graph # Write a commit-graph after fetching - --no-write-commit-graph # Don't write a commit-graph after fetching - --prefetch # Place all refs into the refs/prefetch/ namespace - --prune(-p) # Remove obsolete remote-tracking references - --prune-tags(-P) # Remove any local tags that do not exist on the remote - --no-tags(-n) # Disable automatic tag following - --refmap: string # Use this refspec to map the refs to remote-tracking branches - --tags(-t) # Fetch all tags - --recurse-submodules: string # Fetch new commits of populated submodules (yes/on-demand/no) - --jobs(-j): int # Number of parallel children - --no-recurse-submodules # Disable recursive fetching of submodules - --set-upstream # Add upstream (tracking) reference - --submodule-prefix: string # Prepend to paths printed in informative messages - --upload-pack: string # Non-default path for remote command - --quiet(-q) # Silence internally used git commands - --verbose(-v) # Be verbose - --progress # Report progress on stderr - --server-option(-o): string # Pass options for the server to handle - --show-forced-updates # Check if a branch is force-updated - --no-show-forced-updates # Don't check if a branch is force-updated - -4 # Use IPv4 addresses, ignore IPv6 addresses - -6 # Use IPv6 addresses, ignore IPv4 addresses - --help # Display this help message - ] - - # Check out git branches and files - export extern "git checkout" [ - ...targets: string@"nu-complete git branches" # name of the branch or files to checkout - --conflict: string # conflict style (merge or diff3) - --detach(-d) # detach HEAD at named commit - --force(-f) # force checkout (throw away local modifications) - --guess # second guess 'git checkout ' (default) - --ignore-other-worktrees # do not check if another worktree is holding the given ref - --ignore-skip-worktree-bits # do not limit pathspecs to sparse entries only - --merge(-m) # perform a 3-way merge with the new branch - --orphan: string # new unparented branch - --ours(-2) # checkout our version for unmerged files - --overlay # use overlay mode (default) - --overwrite-ignore # update ignored files (default) - --patch(-p) # select hunks interactively - --pathspec-from-file: string # read pathspec from file - --progress # force progress reporting - --quiet(-q) # suppress progress reporting - --recurse-submodules: string # control recursive updating of submodules - --theirs(-3) # checkout their version for unmerged files - --track(-t) # set upstream info for new branch - -b: string # create and checkout a new branch - -B: string # create/reset and checkout a branch - -l # create reflog for new branch - --help # Display this help message - ] - - # Push changes - export extern "git push" [ - remote?: string@"nu-complete git remotes", # the name of the remote - ...refs: string@"nu-complete git branches" # the branch / refspec - --all # push all refs - --atomic # request atomic transaction on remote side - --delete(-d) # delete refs - --dry-run(-n) # dry run - --exec: string # receive pack program - --follow-tags # push missing but relevant tags - --force-with-lease: string # require old value of ref to be at this value - --force(-f) # force updates - --ipv4(-4) # use IPv4 addresses only - --ipv6(-6) # use IPv6 addresses only - --mirror # mirror all refs - --no-verify # bypass pre-push hook - --porcelain # machine-readable output - --progress # force progress reporting - --prune # prune locally removed refs - --push-option(-o): string # option to transmit - --quiet(-q) # be more quiet - --receive-pack: string # receive pack program - --recurse-submodules: string # control recursive pushing of submodules - --repo: string # repository - --set-upstream(-u) # set upstream for git pull/status - --signed: string # GPG sign the push - --tags # push tags (can't be used with --all or --mirror) - --thin # use thin pack - --verbose(-v) # be more verbose - --help # Display this help message - ] -} - -# Get just the extern definitions without the custom completion commands -use completions * - -# for more information on themes see -# https://www.nushell.sh/book/coloring_and_theming.html -let dark_theme = { - # color for nushell primitives - separator: white - leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off - header: green_bold - empty: blue - bool: white - int: white - filesize: white - duration: white - date: white - range: white - float: white - string: white - nothing: white - binary: white - cellpath: white - row_index: green_bold - record: white - list: white - block: white - hints: dark_gray - - # shapes are used to change the cli syntax highlighting - shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b} - shape_binary: purple_bold - shape_bool: light_cyan - shape_int: purple_bold - shape_float: purple_bold - shape_range: yellow_bold - shape_internalcall: cyan_bold - shape_external: cyan - shape_externalarg: green_bold - shape_literal: blue - shape_operator: yellow - shape_signature: green_bold - shape_string: green - shape_string_interpolation: cyan_bold - shape_datetime: cyan_bold - shape_list: cyan_bold - shape_table: blue_bold - shape_record: cyan_bold - shape_block: blue_bold - shape_filepath: cyan - shape_globpattern: cyan_bold - shape_variable: purple - shape_flag: blue_bold - shape_custom: green - shape_nothing: light_cyan -} - -let light_theme = { - # color for nushell primitives - separator: dark_gray - leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off - header: green_bold - empty: blue - bool: dark_gray - int: dark_gray - filesize: dark_gray - duration: dark_gray - date: dark_gray - range: dark_gray - float: dark_gray - string: dark_gray - nothing: dark_gray - binary: dark_gray - cellpath: dark_gray - row_index: green_bold - record: white - list: white - block: white - hints: dark_gray - - # shapes are used to change the cli syntax highlighting - shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b} - shape_binary: purple_bold - shape_bool: light_cyan - shape_int: purple_bold - shape_float: purple_bold - shape_range: yellow_bold - shape_internalcall: cyan_bold - shape_external: cyan - shape_externalarg: green_bold - shape_literal: blue - shape_operator: yellow - shape_signature: green_bold - shape_string: green - shape_string_interpolation: cyan_bold - shape_datetime: cyan_bold - shape_list: cyan_bold - shape_table: blue_bold - shape_record: cyan_bold - shape_block: blue_bold - shape_filepath: cyan - shape_globpattern: cyan_bold - shape_variable: purple - shape_flag: blue_bold - shape_custom: green - shape_nothing: light_cyan -} - -# The default config record. This is where much of your global configuration is setup. -let-env config = { - show_banner: false - filesize_metric: false - table_mode: compact # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other - use_ls_colors: true - rm_always_trash: true - color_config: $dark_theme # if you want a light theme, replace `$dark_theme` to `$light_theme` - use_grid_icons: true - footer_mode: "25" # always, never, number_of_rows, auto - quick_completions: true # set this to false to prevent auto-selecting completions when only one remains - partial_completions: true # set this to false to prevent partial filling of the prompt - completion_algorithm: "prefix" # prefix, fuzzy - float_precision: 2 - # buffer_editor: "emacs" # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.EDITOR and $env.VISUAL - use_ansi_coloring: true - filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto - edit_mode: vi # emacs, vi - max_history_size: 10000 # Session has to be reloaded for this to take effect - sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file - history_file_format: "plaintext" # "sqlite" or "plaintext" - shell_integration: true # enables terminal markers and a workaround to arrow keys stop working issue - disable_table_indexes: true # set to true to remove the index column from tables - cd_with_abbreviations: false # set to true to allow you to do things like cd s/o/f and nushell expand it to cd some/other/folder - case_sensitive_completions: false # set to true to enable case-sensitive completions - enable_external_completion: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up my be very slow - - hooks: { - pre_prompt: [{ - $nothing # replace with source code to run before the prompt is shown - }] - pre_execution: [{ - $nothing # replace with source code to run before the repl input is run - }] - env_change: { - PWD: [{|before, after| - $nothing # replace with source code to run if the PWD environment is different since the last repl input - }] - } - } - menus: [ - # Configuration for default nushell menus - # Note the lack of souce parameter - { - name: completion_menu - only_buffer_difference: false - marker: "| " - type: { - layout: columnar - columns: 4 - col_width: 20 # Optional value. If missing all the screen width is used to calculate column width - col_padding: 2 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - } - { - name: history_menu - only_buffer_difference: true - marker: "? " - type: { - layout: list - page_size: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - } - { - name: help_menu - only_buffer_difference: true - marker: "? " - type: { - layout: description - columns: 4 - col_width: 20 # Optional value. If missing all the screen width is used to calculate column width - col_padding: 2 - selection_rows: 4 - description_rows: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - } - # Example of extra menus created using a nushell source - # Use the source field to create a list of records that populates - # the menu - { - name: commands_menu - only_buffer_difference: false - marker: "# " - type: { - layout: columnar - columns: 4 - col_width: 20 - col_padding: 2 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - source: { |buffer, position| - $nu.scope.commands - | where command =~ $buffer - | each { |it| {value: $it.command description: $it.usage} } - } - } - { - name: vars_menu - only_buffer_difference: true - marker: "# " - type: { - layout: list - page_size: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - source: { |buffer, position| - $nu.scope.vars - | where name =~ $buffer - | sort-by name - | each { |it| {value: $it.name description: $it.type} } - } - } - { - name: commands_with_description - only_buffer_difference: true - marker: "# " - type: { - layout: description - columns: 4 - col_width: 20 - col_padding: 2 - selection_rows: 4 - description_rows: 10 - } - style: { - text: green - selected_text: green_reverse - description_text: yellow - } - source: { |buffer, position| - $nu.scope.commands - | where command =~ $buffer - | each { |it| {value: $it.command description: $it.usage} } - } - } - ] - keybindings: [ - { - name: completion_menu - modifier: none - keycode: tab - mode: emacs # Options: emacs vi_normal vi_insert - event: { - until: [ - { send: menu name: completion_menu } - { send: menunext } - ] - } - } - { - name: completion_previous - modifier: shift - keycode: backtab - mode: [emacs, vi_normal, vi_insert] # Note: You can add the same keybinding to all modes by using a list - event: { send: menuprevious } - } - { - name: history_menu - modifier: control - keycode: char_r - mode: emacs - event: { send: menu name: history_menu } - } - { - name: next_page - modifier: control - keycode: char_x - mode: emacs - event: { send: menupagenext } - } - { - name: undo_or_previous_page - modifier: control - keycode: char_z - mode: emacs - event: { - until: [ - { send: menupageprevious } - { edit: undo } - ] - } - } - { - name: yank - modifier: control - keycode: char_y - mode: emacs - event: { - until: [ - {edit: pastecutbufferafter} - ] - } - } - { - name: unix-line-discard - modifier: control - keycode: char_u - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - {edit: cutfromlinestart} - ] - } - } - { - name: kill-line - modifier: control - keycode: char_k - mode: [emacs, vi_normal, vi_insert] - event: { - until: [ - {edit: cuttolineend} - ] - } - } - # Keybindings used to trigger the user defined menus - { - name: commands_menu - modifier: control - keycode: char_t - mode: [emacs, vi_normal, vi_insert] - event: { send: menu name: commands_menu } - } - { - name: vars_menu - modifier: alt - keycode: char_o - mode: [emacs, vi_normal, vi_insert] - event: { send: menu name: vars_menu } - } - { - name: commands_with_description - modifier: control - keycode: char_s - mode: [emacs, vi_normal, vi_insert] - event: { send: menu name: commands_with_description } - } - ] -} diff --git a/nushell/env.nu b/nushell/env.nu deleted file mode 100644 index 05e82f6..0000000 --- a/nushell/env.nu +++ /dev/null @@ -1,77 +0,0 @@ -# Nushell Environment Config File - -def create_left_prompt [] { - let short_pwd = $"($env.PWD | str replace $env.HOME '~')" - - let path_segment = if (is-admin) { - $"(ansi red_bold)($short_pwd)" - } else { - $"(ansi blue_bold)($short_pwd)" - } - - $path_segment -} - -def create_right_prompt [] { - let git_status = (do -i { git status -s --ignore-submodules=dirty } | complete) - let is_git? = $git_status.exit_code == 0 - let is_dirty? = ($git_status.stdout | str length) > 0 - - if ($is_git?) { - let git_branch = (git symbolic-ref HEAD | str replace 'refs/heads/' '' | str trim) - let git_branch_color = (if ($is_dirty?) { ansi red_bold } else { ansi green_bold }) - - $"($git_branch_color)($git_branch)(ansi reset)" - } else { - $"" - } -} - -# Use nushell functions to define your right and left prompt -let-env PROMPT_COMMAND = { create_left_prompt } -let-env PROMPT_COMMAND_RIGHT = { create_right_prompt } - -# The prompt indicators are environmental variables that represent -# the state of the prompt -let-env PROMPT_INDICATOR = { " λ " } -let-env PROMPT_INDICATOR_VI_INSERT = { $" (ansi defb)λ(ansi reset) " } -let-env PROMPT_INDICATOR_VI_NORMAL = { $" (ansi rb)λ(ansi reset) " } -let-env PROMPT_MULTILINE_INDICATOR = { "::: " } - -# Specifies how environment variables are: -# - converted from a string to a value on Nushell startup (from_string) -# - converted from a value back to a string when running external commands (to_string) -# Note: The conversions happen *after* config.nu is loaded -let-env ENV_CONVERSIONS = { - "PATH": { - from_string: { |s| $s | split row (char esep) } - to_string: { |v| $v | path expand | str collect (char esep) } - } - "Path": { - from_string: { |s| $s | split row (char esep) } - to_string: { |v| $v | path expand | str collect (char esep) } - } -} - -# Directories to search for scripts when calling source or use -# -# By default, /scripts is added -let-env NU_LIB_DIRS = [ - ($nu.config-path | path dirname | path join 'scripts') -] - -# Directories to search for plugin binaries when calling register -# -# By default, /plugins is added -let-env NU_PLUGIN_DIRS = [ - ($nu.config-path | path dirname | path join 'plugins') -] - -let-env PATH = ( - $env.PATH - | prepend ["/opt/homebrew/bin" "/opt/homebrew/sbin" "/usr/local/bin" "/usr/local/sbin"] - | append ["/opt/homebrew/opt/fzf/bin" "/Users/luke/.cargo/bin"] -) - -let-env EDITOR = "vim" -let-env VISUAL = "vim" diff --git a/oni2/configuration.json b/oni2/configuration.json deleted file mode 100644 index fa13e43..0000000 --- a/oni2/configuration.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "workbench.colorTheme": "Default Dark+", - "editor.detectIndentation": true, - "editor.fontFamily": "Victor Mono", - "editor.fontWeight": "700", - "editor.fontSize": 18, - "editor.fontLigatures": "'ss01'", - "editor.largeFileOptimizations": true, - "editor.highlightActiveIndentGuide": true, - "editor.indentSize": 2, - "editor.insertSpaces": true, - "editor.lineNumbers": "relative", - "editor.matchBrackets": true, - "editor.minimap.enabled": false, - "editor.minimap.maxColumn": 120, - "editor.minimap.showSlider": true, - "editor.renderIndentGuides": true, - "editor.renderWhitespace": "all", - "editor.rulers": [ 120 ], - "editor.tabSize": 2, - "editor.zenMode.hideTabs": true, - "editor.zenMode.singleFile": true, - "files.exclude": [ "_esy", "node_modules", ".git" ], - "workbench.activityBar.visible": true, - "workbench.editor.showTabs": true, - "workbench.editor.enablePreview": true, - "workbench.iconTheme": "vs-seti", - "workbench.sideBar.location": "left", - "workbench.sideBar.visible": true, - "workbench.statusBar.visible": true, - "workbench.tree.indent": 4, - "vim.useSystemClipboard": true -} \ No newline at end of file diff --git a/oni2/keybindings.json b/oni2/keybindings.json deleted file mode 100644 index 430a34c..0000000 --- a/oni2/keybindings.json +++ /dev/null @@ -1,8 +0,0 @@ - -[ - // See the onivim documentation for details on the format: - // https://onivim.github.io/docs/configuration/key-bindings - // Add key bindings here, for example: - // { "key": "", "command": "workbench.action.quickOpen", when: "editorTextFocus" }, - // { "key": "jk", "command": "vim.esc", when: "insertMode" }, -] diff --git a/overlays/README.markdown b/overlays/README.markdown new file mode 100644 index 0000000..226bfc6 --- /dev/null +++ b/overlays/README.markdown @@ -0,0 +1,5 @@ +# Overlays + +This is a place where additions or modifications to existing inputs live. + +As much as possible will be re-used from existing projects, but sometimes packages need to be implemented or modified. diff --git a/overlays/brew-casks.nix b/overlays/brew-casks.nix new file mode 100644 index 0000000..23e9826 --- /dev/null +++ b/overlays/brew-casks.nix @@ -0,0 +1,23 @@ +{ ... }: +self: super: +let + overrideHash = ( + name: hash: + super.brewCasks.${name}.overrideAttrs (oldAttrs: { + src = super.fetchurl { + url = builtins.head oldAttrs.src.urls; + inherit hash; + }; + }) + ); +in +{ + brewCasks = + super.brewCasks + // (builtins.mapAttrs overrideHash { + apparency = "sha256-XKxWxqfxy9AQneILLrN9XqLt4/k2N8yumZ5mrSvczFk="; + suspicious-package = "sha256-VKKbiO/0CIdY5OW19fAmJFHQfyZDNIY9MvGsFt9VD9s="; + bonjour-browser = "sha256-+crlyoU0zPu+oilrTyLIOO61H7U9bkyDWe8EpWJfnOQ="; + audio-hijack = "sha256-1ebSzwzvdcfkVlCjizIbEaGaSypyi0nDLEHpZRRVymA="; + }); +} diff --git a/overlays/nixpkgs/chromium/default.nix b/overlays/nixpkgs/chromium/default.nix new file mode 100644 index 0000000..aa093ff --- /dev/null +++ b/overlays/nixpkgs/chromium/default.nix @@ -0,0 +1,52 @@ +{ + lib, + fetchurl, + darwin, + stdenv, + undmg, + _7zz, + makeWrapper, +}: +let + release = import ./release.nix; + version = release.version; + digest = release.digest; +in +stdenv.mkDerivation rec { + name = "chromium"; + pname = name; + inherit version; + + src = fetchurl { + url = "https://github.com/claudiodekker/ungoogled-chromium-macos/releases/download/${version}/ungoogled-chromium_${version}_${ + if stdenv.isAarch64 then "arm64" else "x86-64" + }-macos-signed.dmg"; + hash = if stdenv.isAarch64 then digest.aarch64 else digest.x86-64; + }; + + nativeBuildInputs = [ + undmg + _7zz + makeWrapper + ]; + + unpackPhase = '' + undmg $src || 7zz x -snld $src + ''; + + sourceRoot = "Chromium.app"; + + installPhase = '' + mkdir -p "$out/Applications/${sourceRoot}" + cp -R . "$out/Applications/${sourceRoot}" + + makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${lib.removeSuffix ".app" sourceRoot}" $out/bin/chromium + ''; + + meta = { + homepage = "https://github.com/claudiodekker/ungoogled-chromium-macos"; + description = "Codesigned builds of Chromium"; + platforms = lib.platforms.darwin; + mainProgram = "Chromium"; + }; +} diff --git a/overlays/nixpkgs/chromium/release.nix b/overlays/nixpkgs/chromium/release.nix new file mode 100644 index 0000000..2734791 --- /dev/null +++ b/overlays/nixpkgs/chromium/release.nix @@ -0,0 +1,7 @@ +{ + version = "126.0.6478.126-1.1"; + digest = { + aarch64 = "sha256-fW+5EwxYa9Bwa0jIVSCs8CitjusuYxs4Lc4icABc1ZQ="; + x86-64 = "sha256-px45f0tXBo/gUzXdpb7i7ZtELHLgjhMFDsYw9XhuxOQ="; + }; +} diff --git a/overlays/nixpkgs/default.nix b/overlays/nixpkgs/default.nix new file mode 100644 index 0000000..c1f5e17 --- /dev/null +++ b/overlays/nixpkgs/default.nix @@ -0,0 +1,9 @@ +{ ... }: +self: super: { + nushellPlugins = super.nushellPlugins.overrideScope ( + final: current: { plist = (self.callPackage ./nu/plugin_plist { }); } + ); + + # Support Chromium on macOS + chromium-macos = (self.callPackage ./chromium { }); +} diff --git a/overlays/nixpkgs/nu/plugin_plist.nix b/overlays/nixpkgs/nu/plugin_plist.nix new file mode 100644 index 0000000..ce8eb71 --- /dev/null +++ b/overlays/nixpkgs/nu/plugin_plist.nix @@ -0,0 +1,59 @@ +{ + lib, + fetchFromGitHub, + rustPlatform, + darwin, + clang, + llvmPackages, + stdenv, +}: + +rustPlatform.buildRustPackage rec { + pname = "nu_plugin_plist"; + version = "0.94.0"; + + buildInputs = [ + darwin.IOKit + clang + llvmPackages.libclang + ]; + nativeBuildInputs = [ + darwin.IOKit + llvmPackages.libclang + ]; + + src = fetchFromGitHub { + owner = "ayax79"; + repo = pname; + rev = "1b6ce58bedfe4dcfc9d2853f604b62b919acf73f"; + hash = "sha256-iPXVYpAbCMtAzxhNKrID1XMc/65PfkC4m4AxzeiZ8dI="; + }; + + LIBCLANG_PATH = "${llvmPackages.libclang}/lib"; + + preBuild = '' + # From: https://github.com/NixOS/nixpkgs/blob/1fab95f5190d087e66a3502481e34e15d62090aa/pkgs/applications/networking/browsers/firefox/common.nix#L247-L253 + # Set C flags for Rust's bindgen program. Unlike ordinary C + # compilation, bindgen does not invoke $CC directly. Instead it + # uses LLVM's libclang. To make sure all necessary flags are + # included we need to look in a few places. + export BINDGEN_EXTRA_CLANG_ARGS="$(< ${stdenv.cc}/nix-support/libc-crt1-cflags) \ + $(< ${stdenv.cc}/nix-support/libc-cflags) \ + $(< ${stdenv.cc}/nix-support/cc-cflags) \ + $(< ${stdenv.cc}/nix-support/libcxx-cxxflags) \ + ${lib.optionalString stdenv.cc.isClang "-idirafter ${stdenv.cc.cc}/lib/clang/${lib.getVersion stdenv.cc.cc}/include"} \ + ${lib.optionalString stdenv.cc.isGNU "-isystem ${stdenv.cc.cc}/include/c++/${lib.getVersion stdenv.cc.cc} -isystem ${stdenv.cc.cc}/include/c++/${lib.getVersion stdenv.cc.cc}/${stdenv.hostPlatform.config} -idirafter ${stdenv.cc.cc}/lib/gcc/${stdenv.hostPlatform.config}/${lib.getVersion stdenv.cc.cc}/include"} \ + " + + export LIBCLANG_PATH="${llvmPackages.libclang}/lib" + ''; + + cargoHash = "sha256-mpCQsXzv9Amly5ct1xQ2ObmW84zghPGZLDyuFpUs6Jc="; + + meta = { + description = "Plugin for handling plist files in nu"; + homepage = "https://github.com/ayax79/nu_plugin_plist"; + license = lib.licenses.mit; + maintainers = [ ]; + }; +} diff --git a/rstudio/rstudio-prefs.json b/rstudio/rstudio-prefs.json deleted file mode 100644 index a396f16..0000000 --- a/rstudio/rstudio-prefs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "jobs_tab_visibility": "shown", - "initial_working_directory": "~", - "posix_terminal_shell": "custom", - "editor_theme": "Solarized Dark", - "custom_shell_command": "/opt/homebrew/bin/fish" -} \ No newline at end of file diff --git a/safari/stylesheet.css b/safari/stylesheet.css deleted file mode 100644 index ff4db20..0000000 --- a/safari/stylesheet.css +++ /dev/null @@ -1,3 +0,0 @@ -#plex .video-overlay-btn { - pointer-events: none; -} diff --git a/systems/Scimitar.nix b/systems/Scimitar.nix new file mode 100644 index 0000000..d7e17f2 --- /dev/null +++ b/systems/Scimitar.nix @@ -0,0 +1,445 @@ +{ pkgs, lib, ... }: +{ + config = { + # See + # https://daiderd.com/nix-darwin/manual/index.html#opt-system.stateVersion + system.stateVersion = 4; + + networking.hostName = "Scimitar"; + + security.pam.enableSudoTouchIdAuth = true; + + system.defaults.LaunchServices.LSQuarantine = false; + + services.nix-daemon.enable = true; + + nix = { + nixPath = [ "nixpkgs=${pkgs.path}" ]; + + registry.nixpkgs.to = { + type = "path"; + path = builtins.toString pkgs.path; + }; + + settings.experimental-features = [ + "nix-command" + "flakes" + ]; + + settings.trusted-users = [ + "root" + "luke" + ]; + + settings.trusted-public-keys = [ + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + ]; + + settings.extra-substituters = [ "https://devenv.cachix.org" ]; + }; + + nixpkgs.config.allowUnfree = true; + + users = { + knownUsers = [ "luke" ]; + + users = { + luke = { + description = "Luke Channings"; + home = "/Users/luke"; + createHome = true; + uid = 501; + gid = 501; + isHidden = false; + shell = pkgs.fish; + }; + root = { + home = "/var/root"; + }; + }; + }; + + home-manager.users = { + luke = ( + { + config, + lib, + pkgs, + ... + }: + { + home = { + # See + # https://nix-community.github.io/home-manager/options.xhtml#opt-home.stateVersion + stateVersion = "24.05"; + + packages = + with pkgs; + [ + # nice admin tools + lsd + tree + ripgrep + + # indispensible dev tools + nodePackages_latest.http-server + dig + jq + curl + devenv + kubectl + + # misc + chafa # imgcat / sizzle CLI that works well with Wezterm + + cloudflared + + # fonts + (nerdfonts.override { + fonts = [ + "Recursive" + "Hasklig" + "VictorMono" + "FiraCode" + "IosevkaTerm" + ]; + }) + ] + ++ (with pkgs.brewCasks; [ + # telegram + plexamp + # mqttx + # anki + # blender + # audio-hijack + ]); + + shellAliases = { + ls = "lsd"; + mkcd = "mkdir -p $1 && cd "; + gitco = "git checkout $1"; + tree = "tree --noreport"; + rg = "ripgrep"; + edit = "$VISUAL ."; + k = "kubctl"; + }; + }; + + xdg.enable = true; + editorconfig = { + enable = true; + + settings = { + "*" = { + end_of_line = "lf"; + insert_final_newline = true; + charset = "utf-8"; + indent_style = "space"; + indent_size = 2; + }; + }; + }; + + programs = { + atuin = { + enable = true; + # https://docs.atuin.sh/configuration/config/ + settings = { + auto_sync = true; + workspaces = true; + ctrl_n_shortcuts = true; + dialect = "uk"; + filter_mode = "host"; + filter_mode_shell_up_key_binding = "directory"; + style = "compact"; + inline_height = 5; + show_help = false; + enter_accept = true; + + sync = { + records = true; + }; + }; + }; + bat = { + enable = true; + config = { + theme = "OneHalfDark"; + style = "plain"; + }; + extraPackages = with pkgs.bat-extras; [ + batdiff + batman + batgrep + batwatch + ]; + }; + direnv = { + enable = true; + config = { + hide_env_diff = true; + }; + nix-direnv.enable = true; + }; + fzf.enable = true; + fd.enable = true; + git = { + enable = true; + userName = "Luke Channings"; + # userEmail = ""; + # signing = { + # key = config.gitSigningKey; + # signByDefault = config.gitSigningKey != null; + # }; + + extraConfig = { + pull.rebase = true; + rebase.autostash = true; + push.autosetupremote = true; + }; + + lfs.enable = true; + difftastic.enable = true; + }; + htop.enable = true; + ssh = { + enable = true; + forwardAgent = true; + hashKnownHosts = true; + addKeysToAgent = "yes"; + matchBlocks = { + "catalyst.channings.me" = { + user = "nemo"; + proxyCommand = "cloudflared --credentials-file ~/.cloudflared/cde1169a-5b87-4f2e-acc5-af61158aea84.json access ssh --hostname %h"; + identityFile = "~/.ssh/catalyst.pub"; + identitiesOnly = true; + }; + }; + }; + starship = { + enable = true; + settings = { + add_newline = false; + format = lib.concatStrings [ + "$directory" + "$character" + ]; + right_format = lib.concatStrings [ + "$git_branch" + "$git_status" + "$nix_shell" + ]; + scan_timeout = 10; + character = { + success_symbol = "[λ](bold green)"; + error_symbol = "[λ](bold red)"; + }; + nix_shell = { + disabled = false; + format = "[$symbol](bold blue) "; + }; + directory = { + fish_style_pwd_dir_length = 2; + }; + git_branch = { + format = "[$symbol$branch(:$remote_branch)]($style)"; + ignore_branches = [ + "master" + "main" + ]; + }; + cmd_duration = { + disabled = false; + }; + }; + }; + fish = { + enable = true; + + interactiveShellInit = "enable_transience"; + + functions = { + # https://fishshell.com/docs/current/interactive.html#vi-mode-commands + fish_user_key_bindings = '' + fish_default_key_bindings -M insert + + fish_vi_key_bindings --no-erase insert + ''; + mcat = '' + if file --mime-type $argv | grep -qF image/ + chafa -f iterm -s $FZF_PREVIEW_COLUMNS"x"$FZF_PREVIEW_LINES $argv + else + bat --color always --style numbers --theme TwoDark --line-range :200 $argv + end''; + fdz = "fd --type f --hidden --follow --exclude .git --color=always | fzf --ansi --multi --preview='mcat {}'"; + }; + }; + nushell = { + enable = true; + }; + zoxide = { + enable = true; + + options = [ "--cmd cd" ]; + }; + zsh.enable = true; + + vscode = { + enable = true; + + package = pkgs.vscodium; + enableUpdateCheck = false; + enableExtensionUpdateCheck = false; + mutableExtensionsDir = false; + + userSettings = { + "editor.fontFamily" = "RecMonoLinear Nerd Font"; + "editor.fontSize" = 16; + "notebook.markup.fontSize" = 14; + "terminal.integrated.fontSize" = 14; + "editor.fontLigatures" = true; + "explorer.confirmDelete" = false; + "editor.rulers" = [ 120 ]; + "editor.multiCursorModifier" = "ctrlCmd"; + "workbench.colorTheme" = "One Dark Pro Flat"; + "editor.suggestSelection" = "first"; + "typescript.updateImportsOnFileMove.enabled" = "always"; + "editor.renderWhitespace" = "all"; + "emmet.showSuggestionsAsSnippets" = true; + "editor.inlineSuggest.enabled" = true; + "redhat.telemetry.enabled" = false; + "editor.snippetSuggestions" = "bottom"; + "extensions.ignoreRecommendations" = true; + "cSpell.language" = "en;en-GB"; + "workbench.startupEditor" = "none"; + "window.commandCenter" = false; + "terminal.integrated.shellIntegration.enabled" = false; + "workbench.editor.empty.hint" = "hidden"; + "search.quickOpen.history.filterSortOrder" = "recency"; + "gitlens.showWelcomeOnInstall" = false; + "gitlens.showWhatsNewAfterUpgrades" = false; + "gitlens.plusFeatures.enabled" = false; + "[markdown]" = { + "editor.wordWrap" = "on"; + }; + }; + + extensions = with pkgs.vscode-extensions; [ + zhuangtongfa.material-theme + mkhl.direnv + editorconfig.editorconfig + redhat.vscode-yaml + redhat.vscode-xml + streetsidesoftware.code-spell-checker + eamodio.gitlens + tamasfe.even-better-toml + ]; + + keybindings = [ + { + key = "cmd+j"; + command = "editor.action.joinLines"; + } + { + key = "cmd+k cmd+l"; + command = "editor.action.transformToLowercase"; + when = "editorTextFocus"; + } + ]; + }; + + wezterm = { + enable = true; + }; + + helix = { + enable = true; + defaultEditor = config.shell.defaultEditor == "helix"; + + settings = { + theme = "onedark"; + + editor = { + line-number = "relative"; + + cursor-shape = { + insert = "bar"; + normal = "block"; + select = "underline"; + }; + + file-picker = { + hidden = false; + }; + }; + + keys.normal = { + A-up = [ + "extend_to_line_bounds" + "delete_selection" + "move_line_up" + "paste_before" + ]; + A-down = [ + "extend_to_line_bounds" + "delete_selection" + "paste_after" + ]; + }; + }; + + themes = { + onedark = { + inherits = "onedark"; + + "ui.background" = "#ff0000"; + }; + }; + + languages = { + language-server = { + nil = { + command = lib.getExe pkgs.nil; + config = { + nix = { + maxMemoryMB = 2560; + flake = { + autoArchive = false; + autoEvalInputs = true; + }; + }; + }; + }; + lua-language-server = { + command = lib.getExe pkgs.lua-language-server; + }; + }; + language = [ + { + name = "nix"; + auto-format = true; + formatter.command = lib.getExe pkgs.nixfmt-rfc-style; + } + { + name = "lua"; + auto-format = true; + formatter.command = lib.getExe pkgs.stylua; + } + ]; + }; + }; + + # chromium = { + # enable = true; + # package = if pkgs.stdenv.isDarwin then pkgs.chromium-macos else pkgs.chromium; + # extensions = [ + # { "id" = "fmkadmapgofadopljbjfkapdkoienihi"; } # React Developer Tools + # { "id" = "aeblfdkhhhdcdjpifhhbdiojplfjncoa"; } # 1Password + # ]; + # }; + }; + } + ); + }; + }; +} diff --git a/tmux/config b/tmux/config deleted file mode 100644 index ab073fd..0000000 --- a/tmux/config +++ /dev/null @@ -1,61 +0,0 @@ -# Enable 24 bit true colors -set -ga terminal-overrides ',xterm-256color:Tc' - -set -g status off -set-option -g prefix C-a -bind-key C-a last-window - -# Start numbering at 1 -set -g base-index 1 - -# Allows for faster key repetition -set -s escape-time 0 - -# increase scrollback buffer size -set -g history-limit 50000 - -# tmux messages are displayed for 4 seconds -set -g display-time 4000 - -# refresh 'status-left' and 'status-right' more often -set -g status-interval 5 - -# upgrade $TERM -set -g default-terminal "screen-256color" - -# focus events enabled for terminals that support them -set -g focus-events on - -# Allows us to use C-a a to send commands to a TMUX session inside -# another TMUX session -bind-key a send-prefix - -# Activity monitoring -setw -g monitor-activity on -set -g visual-activity on - -# hjkl pane traversal -bind h select-pane -L -bind j select-pane -D -bind k select-pane -U -bind l select-pane -R - -# mouse -set -g mouse on - -bind-key - split-window -c "#{pane_current_path}" -bind-key | split-window -c "#{pane_current_path}" -h - -bind r source-file ~/.tmux.conf \; display-message "Config reloaded..." - -# Use vim keybindings in copy mode -setw -g mode-keys vi - -set-window-option -g mode-keys vi -bind-key -T copy-mode-vi v send-keys -X begin-selection -bind-key -T copy-mode-vi y send-keys -X copy-selection - -set-option -g set-titles on -set-option -g set-titles-string '#T' - -set -g default-command "$SHELL" diff --git a/vim/autoload/plug.vim b/vim/autoload/plug.vim deleted file mode 100644 index 2b89b5a..0000000 --- a/vim/autoload/plug.vim +++ /dev/null @@ -1,2797 +0,0 @@ -" vim-plug: Vim plugin manager -" ============================ -" -" Download plug.vim and put it in ~/.vim/autoload -" -" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ -" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim -" -" Edit your .vimrc -" -" call plug#begin('~/.vim/plugged') -" -" " Make sure you use single quotes -" -" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align -" Plug 'junegunn/vim-easy-align' -" -" " Any valid git URL is allowed -" Plug 'https://github.com/junegunn/vim-github-dashboard.git' -" -" " Multiple Plug commands can be written in a single line using | separators -" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' -" -" " On-demand loading -" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } -" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } -" -" " Using a non-default branch -" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } -" -" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) -" Plug 'fatih/vim-go', { 'tag': '*' } -" -" " Plugin options -" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } -" -" " Plugin outside ~/.vim/plugged with post-update hook -" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } -" -" " Unmanaged plugin (manually installed and updated) -" Plug '~/my-prototype-plugin' -" -" " Initialize plugin system -" call plug#end() -" -" Then reload .vimrc and :PlugInstall to install plugins. -" -" Plug options: -" -"| Option | Description | -"| ----------------------- | ------------------------------------------------ | -"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | -"| `rtp` | Subdirectory that contains Vim plugin | -"| `dir` | Custom directory for the plugin | -"| `as` | Use different name for the plugin | -"| `do` | Post-update hook (string or funcref) | -"| `on` | On-demand loading: Commands or ``-mappings | -"| `for` | On-demand loading: File types | -"| `frozen` | Do not update unless explicitly specified | -" -" More information: https://github.com/junegunn/vim-plug -" -" -" Copyright (c) 2017 Junegunn Choi -" -" MIT License -" -" 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. - -if exists('g:loaded_plug') - finish -endif -let g:loaded_plug = 1 - -let s:cpo_save = &cpo -set cpo&vim - -let s:plug_src = 'https://github.com/junegunn/vim-plug.git' -let s:plug_tab = get(s:, 'plug_tab', -1) -let s:plug_buf = get(s:, 'plug_buf', -1) -let s:mac_gui = has('gui_macvim') && has('gui_running') -let s:is_win = has('win32') -let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) -let s:vim8 = has('patch-8.0.0039') && exists('*job_start') -if s:is_win && &shellslash - set noshellslash - let s:me = resolve(expand(':p')) - set shellslash -else - let s:me = resolve(expand(':p')) -endif -let s:base_spec = { 'branch': '', 'frozen': 0 } -let s:TYPE = { -\ 'string': type(''), -\ 'list': type([]), -\ 'dict': type({}), -\ 'funcref': type(function('call')) -\ } -let s:loaded = get(s:, 'loaded', {}) -let s:triggers = get(s:, 'triggers', {}) - -function! s:isabsolute(dir) abort - return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)') -endfunction - -function! s:git_dir(dir) abort - let gitdir = s:trim(a:dir) . '/.git' - if isdirectory(gitdir) - return gitdir - endif - if !filereadable(gitdir) - return '' - endif - let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*') - if len(gitdir) && !s:isabsolute(gitdir) - let gitdir = a:dir . '/' . gitdir - endif - return isdirectory(gitdir) ? gitdir : '' -endfunction - -function! s:git_origin_url(dir) abort - let gitdir = s:git_dir(a:dir) - let config = gitdir . '/config' - if empty(gitdir) || !filereadable(config) - return '' - endif - return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze') -endfunction - -function! s:git_revision(dir) abort - let gitdir = s:git_dir(a:dir) - let head = gitdir . '/HEAD' - if empty(gitdir) || !filereadable(head) - return '' - endif - - let line = get(readfile(head), 0, '') - let ref = matchstr(line, '^ref: \zs.*') - if empty(ref) - return line - endif - - if filereadable(gitdir . '/' . ref) - return get(readfile(gitdir . '/' . ref), 0, '') - endif - - if filereadable(gitdir . '/packed-refs') - for line in readfile(gitdir . '/packed-refs') - if line =~# ' ' . ref - return matchstr(line, '^[0-9a-f]*') - endif - endfor - endif - - return '' -endfunction - -function! s:git_local_branch(dir) abort - let gitdir = s:git_dir(a:dir) - let head = gitdir . '/HEAD' - if empty(gitdir) || !filereadable(head) - return '' - endif - let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*') - return len(branch) ? branch : 'HEAD' -endfunction - -function! s:git_origin_branch(spec) - if len(a:spec.branch) - return a:spec.branch - endif - - " The file may not be present if this is a local repository - let gitdir = s:git_dir(a:spec.dir) - let origin_head = gitdir.'/refs/remotes/origin/HEAD' - if len(gitdir) && filereadable(origin_head) - return matchstr(get(readfile(origin_head), 0, ''), - \ '^ref: refs/remotes/origin/\zs.*') - endif - - " The command may not return the name of a branch in detached HEAD state - let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir)) - return v:shell_error ? '' : result[-1] -endfunction - -if s:is_win - function! s:plug_call(fn, ...) - let shellslash = &shellslash - try - set noshellslash - return call(a:fn, a:000) - finally - let &shellslash = shellslash - endtry - endfunction -else - function! s:plug_call(fn, ...) - return call(a:fn, a:000) - endfunction -endif - -function! s:plug_getcwd() - return s:plug_call('getcwd') -endfunction - -function! s:plug_fnamemodify(fname, mods) - return s:plug_call('fnamemodify', a:fname, a:mods) -endfunction - -function! s:plug_expand(fmt) - return s:plug_call('expand', a:fmt, 1) -endfunction - -function! s:plug_tempname() - return s:plug_call('tempname') -endfunction - -function! plug#begin(...) - if a:0 > 0 - let s:plug_home_org = a:1 - let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p')) - elseif exists('g:plug_home') - let home = s:path(g:plug_home) - elseif !empty(&rtp) - let home = s:path(split(&rtp, ',')[0]) . '/plugged' - else - return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') - endif - if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp - return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') - endif - - let g:plug_home = home - let g:plugs = {} - let g:plugs_order = [] - let s:triggers = {} - - call s:define_commands() - return 1 -endfunction - -function! s:define_commands() - command! -nargs=+ -bar Plug call plug#() - if !executable('git') - return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') - endif - if has('win32') - \ && &shellslash - \ && (&shell =~# 'cmd\(\.exe\)\?$' || &shell =~# 'powershell\(\.exe\)\?$') - return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.') - endif - if !has('nvim') - \ && (has('win32') || has('win32unix')) - \ && !has('multi_byte') - return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.') - endif - command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) - command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) - command! -nargs=0 -bar -bang PlugClean call s:clean(0) - command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif - command! -nargs=0 -bar PlugStatus call s:status() - command! -nargs=0 -bar PlugDiff call s:diff() - command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) -endfunction - -function! s:to_a(v) - return type(a:v) == s:TYPE.list ? a:v : [a:v] -endfunction - -function! s:to_s(v) - return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" -endfunction - -function! s:glob(from, pattern) - return s:lines(globpath(a:from, a:pattern)) -endfunction - -function! s:source(from, ...) - let found = 0 - for pattern in a:000 - for vim in s:glob(a:from, pattern) - execute 'source' s:esc(vim) - let found = 1 - endfor - endfor - return found -endfunction - -function! s:assoc(dict, key, val) - let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) -endfunction - -function! s:ask(message, ...) - call inputsave() - echohl WarningMsg - let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) - echohl None - call inputrestore() - echo "\r" - return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 -endfunction - -function! s:ask_no_interrupt(...) - try - return call('s:ask', a:000) - catch - return 0 - endtry -endfunction - -function! s:lazy(plug, opt) - return has_key(a:plug, a:opt) && - \ (empty(s:to_a(a:plug[a:opt])) || - \ !isdirectory(a:plug.dir) || - \ len(s:glob(s:rtp(a:plug), 'plugin')) || - \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) -endfunction - -function! plug#end() - if !exists('g:plugs') - return s:err('plug#end() called without calling plug#begin() first') - endif - - if exists('#PlugLOD') - augroup PlugLOD - autocmd! - augroup END - augroup! PlugLOD - endif - let lod = { 'ft': {}, 'map': {}, 'cmd': {} } - - if exists('g:did_load_filetypes') - filetype off - endif - for name in g:plugs_order - if !has_key(g:plugs, name) - continue - endif - let plug = g:plugs[name] - if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') - let s:loaded[name] = 1 - continue - endif - - if has_key(plug, 'on') - let s:triggers[name] = { 'map': [], 'cmd': [] } - for cmd in s:to_a(plug.on) - if cmd =~? '^.\+' - if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) - call s:assoc(lod.map, cmd, name) - endif - call add(s:triggers[name].map, cmd) - elseif cmd =~# '^[A-Z]' - let cmd = substitute(cmd, '!*$', '', '') - if exists(':'.cmd) != 2 - call s:assoc(lod.cmd, cmd, name) - endif - call add(s:triggers[name].cmd, cmd) - else - call s:err('Invalid `on` option: '.cmd. - \ '. Should start with an uppercase letter or ``.') - endif - endfor - endif - - if has_key(plug, 'for') - let types = s:to_a(plug.for) - if !empty(types) - augroup filetypedetect - call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') - augroup END - endif - for type in types - call s:assoc(lod.ft, type, name) - endfor - endif - endfor - - for [cmd, names] in items(lod.cmd) - execute printf( - \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', - \ cmd, string(cmd), string(names)) - endfor - - for [map, names] in items(lod.map) - for [mode, map_prefix, key_prefix] in - \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] - execute printf( - \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', - \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) - endfor - endfor - - for [ft, names] in items(lod.ft) - augroup PlugLOD - execute printf('autocmd FileType %s call lod_ft(%s, %s)', - \ ft, string(ft), string(names)) - augroup END - endfor - - call s:reorg_rtp() - filetype plugin indent on - if has('vim_starting') - if has('syntax') && !exists('g:syntax_on') - syntax enable - end - else - call s:reload_plugins() - endif -endfunction - -function! s:loaded_names() - return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') -endfunction - -function! s:load_plugin(spec) - call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') -endfunction - -function! s:reload_plugins() - for name in s:loaded_names() - call s:load_plugin(g:plugs[name]) - endfor -endfunction - -function! s:trim(str) - return substitute(a:str, '[\/]\+$', '', '') -endfunction - -function! s:version_requirement(val, min) - for idx in range(0, len(a:min) - 1) - let v = get(a:val, idx, 0) - if v < a:min[idx] | return 0 - elseif v > a:min[idx] | return 1 - endif - endfor - return 1 -endfunction - -function! s:git_version_requirement(...) - if !exists('s:git_version') - let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)') - endif - return s:version_requirement(s:git_version, a:000) -endfunction - -function! s:progress_opt(base) - return a:base && !s:is_win && - \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' -endfunction - -function! s:rtp(spec) - return s:path(a:spec.dir . get(a:spec, 'rtp', '')) -endfunction - -if s:is_win - function! s:path(path) - return s:trim(substitute(a:path, '/', '\', 'g')) - endfunction - - function! s:dirpath(path) - return s:path(a:path) . '\' - endfunction - - function! s:is_local_plug(repo) - return a:repo =~? '^[a-z]:\|^[%~]' - endfunction - - " Copied from fzf - function! s:wrap_cmds(cmds) - let cmds = [ - \ '@echo off', - \ 'setlocal enabledelayedexpansion'] - \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) - \ + ['endlocal'] - if has('iconv') - if !exists('s:codepage') - let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0) - endif - return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage)) - endif - return map(cmds, 'v:val."\r"') - endfunction - - function! s:batchfile(cmd) - let batchfile = s:plug_tempname().'.bat' - call writefile(s:wrap_cmds(a:cmd), batchfile) - let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0}) - if &shell =~# 'powershell\(\.exe\)\?$' - let cmd = '& ' . cmd - endif - return [batchfile, cmd] - endfunction -else - function! s:path(path) - return s:trim(a:path) - endfunction - - function! s:dirpath(path) - return substitute(a:path, '[/\\]*$', '/', '') - endfunction - - function! s:is_local_plug(repo) - return a:repo[0] =~ '[/$~]' - endfunction -endif - -function! s:err(msg) - echohl ErrorMsg - echom '[vim-plug] '.a:msg - echohl None -endfunction - -function! s:warn(cmd, msg) - echohl WarningMsg - execute a:cmd 'a:msg' - echohl None -endfunction - -function! s:esc(path) - return escape(a:path, ' ') -endfunction - -function! s:escrtp(path) - return escape(a:path, ' ,') -endfunction - -function! s:remove_rtp() - for name in s:loaded_names() - let rtp = s:rtp(g:plugs[name]) - execute 'set rtp-='.s:escrtp(rtp) - let after = globpath(rtp, 'after') - if isdirectory(after) - execute 'set rtp-='.s:escrtp(after) - endif - endfor -endfunction - -function! s:reorg_rtp() - if !empty(s:first_rtp) - execute 'set rtp-='.s:first_rtp - execute 'set rtp-='.s:last_rtp - endif - - " &rtp is modified from outside - if exists('s:prtp') && s:prtp !=# &rtp - call s:remove_rtp() - unlet! s:middle - endif - - let s:middle = get(s:, 'middle', &rtp) - let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') - let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') - let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') - \ . ','.s:middle.',' - \ . join(map(afters, 'escape(v:val, ",")'), ',') - let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') - let s:prtp = &rtp - - if !empty(s:first_rtp) - execute 'set rtp^='.s:first_rtp - execute 'set rtp+='.s:last_rtp - endif -endfunction - -function! s:doautocmd(...) - if exists('#'.join(a:000, '#')) - execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) - endif -endfunction - -function! s:dobufread(names) - for name in a:names - let path = s:rtp(g:plugs[name]) - for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin'] - if len(finddir(dir, path)) - if exists('#BufRead') - doautocmd BufRead - endif - return - endif - endfor - endfor -endfunction - -function! plug#load(...) - if a:0 == 0 - return s:err('Argument missing: plugin name(s) required') - endif - if !exists('g:plugs') - return s:err('plug#begin was not called') - endif - let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 - let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') - if !empty(unknowns) - let s = len(unknowns) > 1 ? 's' : '' - return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) - end - let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') - if !empty(unloaded) - for name in unloaded - call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) - endfor - call s:dobufread(unloaded) - return 1 - end - return 0 -endfunction - -function! s:remove_triggers(name) - if !has_key(s:triggers, a:name) - return - endif - for cmd in s:triggers[a:name].cmd - execute 'silent! delc' cmd - endfor - for map in s:triggers[a:name].map - execute 'silent! unmap' map - execute 'silent! iunmap' map - endfor - call remove(s:triggers, a:name) -endfunction - -function! s:lod(names, types, ...) - for name in a:names - call s:remove_triggers(name) - let s:loaded[name] = 1 - endfor - call s:reorg_rtp() - - for name in a:names - let rtp = s:rtp(g:plugs[name]) - for dir in a:types - call s:source(rtp, dir.'/**/*.vim') - endfor - if a:0 - if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) - execute 'runtime' a:1 - endif - call s:source(rtp, a:2) - endif - call s:doautocmd('User', name) - endfor -endfunction - -function! s:lod_ft(pat, names) - let syn = 'syntax/'.a:pat.'.vim' - call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) - execute 'autocmd! PlugLOD FileType' a:pat - call s:doautocmd('filetypeplugin', 'FileType') - call s:doautocmd('filetypeindent', 'FileType') -endfunction - -function! s:lod_cmd(cmd, bang, l1, l2, args, names) - call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) - call s:dobufread(a:names) - execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) -endfunction - -function! s:lod_map(map, names, with_prefix, prefix) - call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) - call s:dobufread(a:names) - let extra = '' - while 1 - let c = getchar(0) - if c == 0 - break - endif - let extra .= nr2char(c) - endwhile - - if a:with_prefix - let prefix = v:count ? v:count : '' - let prefix .= '"'.v:register.a:prefix - if mode(1) == 'no' - if v:operator == 'c' - let prefix = "\" . prefix - endif - let prefix .= v:operator - endif - call feedkeys(prefix, 'n') - endif - call feedkeys(substitute(a:map, '^', "\", '') . extra) -endfunction - -function! plug#(repo, ...) - if a:0 > 1 - return s:err('Invalid number of arguments (1..2)') - endif - - try - let repo = s:trim(a:repo) - let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec - let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??')) - let spec = extend(s:infer_properties(name, repo), opts) - if !has_key(g:plugs, name) - call add(g:plugs_order, name) - endif - let g:plugs[name] = spec - let s:loaded[name] = get(s:loaded, name, 0) - catch - return s:err(repo . ' ' . v:exception) - endtry -endfunction - -function! s:parse_options(arg) - let opts = copy(s:base_spec) - let type = type(a:arg) - let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)' - if type == s:TYPE.string - if empty(a:arg) - throw printf(opt_errfmt, 'tag', 'string') - endif - let opts.tag = a:arg - elseif type == s:TYPE.dict - for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as'] - if has_key(a:arg, opt) - \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) - throw printf(opt_errfmt, opt, 'string') - endif - endfor - for opt in ['on', 'for'] - if has_key(a:arg, opt) - \ && type(a:arg[opt]) != s:TYPE.list - \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) - throw printf(opt_errfmt, opt, 'string or list') - endif - endfor - if has_key(a:arg, 'do') - \ && type(a:arg.do) != s:TYPE.funcref - \ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do)) - throw printf(opt_errfmt, 'do', 'string or funcref') - endif - call extend(opts, a:arg) - if has_key(opts, 'dir') - let opts.dir = s:dirpath(s:plug_expand(opts.dir)) - endif - else - throw 'Invalid argument type (expected: string or dictionary)' - endif - return opts -endfunction - -function! s:infer_properties(name, repo) - let repo = a:repo - if s:is_local_plug(repo) - return { 'dir': s:dirpath(s:plug_expand(repo)) } - else - if repo =~ ':' - let uri = repo - else - if repo !~ '/' - throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) - endif - let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') - let uri = printf(fmt, repo) - endif - return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } - endif -endfunction - -function! s:install(force, names) - call s:update_impl(0, a:force, a:names) -endfunction - -function! s:update(force, names) - call s:update_impl(1, a:force, a:names) -endfunction - -function! plug#helptags() - if !exists('g:plugs') - return s:err('plug#begin was not called') - endif - for spec in values(g:plugs) - let docd = join([s:rtp(spec), 'doc'], '/') - if isdirectory(docd) - silent! execute 'helptags' s:esc(docd) - endif - endfor - return 1 -endfunction - -function! s:syntax() - syntax clear - syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber - syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX - syn match plugNumber /[0-9]\+[0-9.]*/ contained - syn match plugBracket /[[\]]/ contained - syn match plugX /x/ contained - syn match plugDash /^-\{1}\ / - syn match plugPlus /^+/ - syn match plugStar /^*/ - syn match plugMessage /\(^- \)\@<=.*/ - syn match plugName /\(^- \)\@<=[^ ]*:/ - syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ - syn match plugTag /(tag: [^)]\+)/ - syn match plugInstall /\(^+ \)\@<=[^:]*/ - syn match plugUpdate /\(^* \)\@<=[^:]*/ - syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag - syn match plugEdge /^ \X\+$/ - syn match plugEdge /^ \X*/ contained nextgroup=plugSha - syn match plugSha /[0-9a-f]\{7,9}/ contained - syn match plugRelDate /([^)]*)$/ contained - syn match plugNotLoaded /(not loaded)$/ - syn match plugError /^x.*/ - syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ - syn match plugH2 /^.*:\n-\+$/ - syn match plugH2 /^-\{2,}/ - syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean - hi def link plug1 Title - hi def link plug2 Repeat - hi def link plugH2 Type - hi def link plugX Exception - hi def link plugBracket Structure - hi def link plugNumber Number - - hi def link plugDash Special - hi def link plugPlus Constant - hi def link plugStar Boolean - - hi def link plugMessage Function - hi def link plugName Label - hi def link plugInstall Function - hi def link plugUpdate Type - - hi def link plugError Error - hi def link plugDeleted Ignore - hi def link plugRelDate Comment - hi def link plugEdge PreProc - hi def link plugSha Identifier - hi def link plugTag Constant - - hi def link plugNotLoaded Comment -endfunction - -function! s:lpad(str, len) - return a:str . repeat(' ', a:len - len(a:str)) -endfunction - -function! s:lines(msg) - return split(a:msg, "[\r\n]") -endfunction - -function! s:lastline(msg) - return get(s:lines(a:msg), -1, '') -endfunction - -function! s:new_window() - execute get(g:, 'plug_window', 'vertical topleft new') -endfunction - -function! s:plug_window_exists() - let buflist = tabpagebuflist(s:plug_tab) - return !empty(buflist) && index(buflist, s:plug_buf) >= 0 -endfunction - -function! s:switch_in() - if !s:plug_window_exists() - return 0 - endif - - if winbufnr(0) != s:plug_buf - let s:pos = [tabpagenr(), winnr(), winsaveview()] - execute 'normal!' s:plug_tab.'gt' - let winnr = bufwinnr(s:plug_buf) - execute winnr.'wincmd w' - call add(s:pos, winsaveview()) - else - let s:pos = [winsaveview()] - endif - - setlocal modifiable - return 1 -endfunction - -function! s:switch_out(...) - call winrestview(s:pos[-1]) - setlocal nomodifiable - if a:0 > 0 - execute a:1 - endif - - if len(s:pos) > 1 - execute 'normal!' s:pos[0].'gt' - execute s:pos[1] 'wincmd w' - call winrestview(s:pos[2]) - endif -endfunction - -function! s:finish_bindings() - nnoremap R :call retry() - nnoremap D :PlugDiff - nnoremap S :PlugStatus - nnoremap U :call status_update() - xnoremap U :call status_update() - nnoremap ]] :silent! call section('') - nnoremap [[ :silent! call section('b') -endfunction - -function! s:prepare(...) - if empty(s:plug_getcwd()) - throw 'Invalid current working directory. Cannot proceed.' - endif - - for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] - if exists(evar) - throw evar.' detected. Cannot proceed.' - endif - endfor - - call s:job_abort() - if s:switch_in() - if b:plug_preview == 1 - pc - endif - enew - else - call s:new_window() - endif - - nnoremap q :call close_pane() - if a:0 == 0 - call s:finish_bindings() - endif - let b:plug_preview = -1 - let s:plug_tab = tabpagenr() - let s:plug_buf = winbufnr(0) - call s:assign_name() - - for k in ['', 'L', 'o', 'X', 'd', 'dd'] - execute 'silent! unmap ' k - endfor - setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell - if exists('+colorcolumn') - setlocal colorcolumn= - endif - setf vim-plug - if exists('g:syntax_on') - call s:syntax() - endif -endfunction - -function! s:close_pane() - if b:plug_preview == 1 - pc - let b:plug_preview = -1 - else - bd - endif -endfunction - -function! s:assign_name() - " Assign buffer name - let prefix = '[Plugins]' - let name = prefix - let idx = 2 - while bufexists(name) - let name = printf('%s (%s)', prefix, idx) - let idx = idx + 1 - endwhile - silent! execute 'f' fnameescape(name) -endfunction - -function! s:chsh(swap) - let prev = [&shell, &shellcmdflag, &shellredir] - if !s:is_win - set shell=sh - endif - if a:swap - if &shell =~# 'powershell\(\.exe\)\?$' || &shell =~# 'pwsh$' - let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s' - elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$' - set shellredir=>%s\ 2>&1 - endif - endif - return prev -endfunction - -function! s:bang(cmd, ...) - let batchfile = '' - try - let [sh, shellcmdflag, shrd] = s:chsh(a:0) - " FIXME: Escaping is incomplete. We could use shellescape with eval, - " but it won't work on Windows. - let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd - if s:is_win - let [batchfile, cmd] = s:batchfile(cmd) - endif - let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') - execute "normal! :execute g:_plug_bang\\" - finally - unlet g:_plug_bang - let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] - if s:is_win && filereadable(batchfile) - call delete(batchfile) - endif - endtry - return v:shell_error ? 'Exit status: ' . v:shell_error : '' -endfunction - -function! s:regress_bar() - let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') - call s:progress_bar(2, bar, len(bar)) -endfunction - -function! s:is_updated(dir) - return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir)) -endfunction - -function! s:do(pull, force, todo) - for [name, spec] in items(a:todo) - if !isdirectory(spec.dir) - continue - endif - let installed = has_key(s:update.new, name) - let updated = installed ? 0 : - \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) - if a:force || installed || updated - execute 'cd' s:esc(spec.dir) - call append(3, '- Post-update hook for '. name .' ... ') - let error = '' - let type = type(spec.do) - if type == s:TYPE.string - if spec.do[0] == ':' - if !get(s:loaded, name, 0) - let s:loaded[name] = 1 - call s:reorg_rtp() - endif - call s:load_plugin(spec) - try - execute spec.do[1:] - catch - let error = v:exception - endtry - if !s:plug_window_exists() - cd - - throw 'Warning: vim-plug was terminated by the post-update hook of '.name - endif - else - let error = s:bang(spec.do) - endif - elseif type == s:TYPE.funcref - try - call s:load_plugin(spec) - let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') - call spec.do({ 'name': name, 'status': status, 'force': a:force }) - catch - let error = v:exception - endtry - else - let error = 'Invalid hook type' - endif - call s:switch_in() - call setline(4, empty(error) ? (getline(4) . 'OK') - \ : ('x' . getline(4)[1:] . error)) - if !empty(error) - call add(s:update.errors, name) - call s:regress_bar() - endif - cd - - endif - endfor -endfunction - -function! s:hash_match(a, b) - return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 -endfunction - -function! s:checkout(spec) - let sha = a:spec.commit - let output = s:git_revision(a:spec.dir) - if !empty(output) && !s:hash_match(sha, s:lines(output)[0]) - let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : '' - let output = s:system( - \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir) - endif - return output -endfunction - -function! s:finish(pull) - let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) - if new_frozen - let s = new_frozen > 1 ? 's' : '' - call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) - endif - call append(3, '- Finishing ... ') | 4 - redraw - call plug#helptags() - call plug#end() - call setline(4, getline(4) . 'Done!') - redraw - let msgs = [] - if !empty(s:update.errors) - call add(msgs, "Press 'R' to retry.") - endif - if a:pull && len(s:update.new) < len(filter(getline(5, '$'), - \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) - call add(msgs, "Press 'D' to see the updated changes.") - endif - echo join(msgs, ' ') - call s:finish_bindings() -endfunction - -function! s:retry() - if empty(s:update.errors) - return - endif - echo - call s:update_impl(s:update.pull, s:update.force, - \ extend(copy(s:update.errors), [s:update.threads])) -endfunction - -function! s:is_managed(name) - return has_key(g:plugs[a:name], 'uri') -endfunction - -function! s:names(...) - return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) -endfunction - -function! s:check_ruby() - silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") - if !exists('g:plug_ruby') - redraw! - return s:warn('echom', 'Warning: Ruby interface is broken') - endif - let ruby_version = split(g:plug_ruby, '\.') - unlet g:plug_ruby - return s:version_requirement(ruby_version, [1, 8, 7]) -endfunction - -function! s:update_impl(pull, force, args) abort - let sync = index(a:args, '--sync') >= 0 || has('vim_starting') - let args = filter(copy(a:args), 'v:val != "--sync"') - let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? - \ remove(args, -1) : get(g:, 'plug_threads', 16) - - let managed = filter(copy(g:plugs), 's:is_managed(v:key)') - let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : - \ filter(managed, 'index(args, v:key) >= 0') - - if empty(todo) - return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) - endif - - if !s:is_win && s:git_version_requirement(2, 3) - let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' - let $GIT_TERMINAL_PROMPT = 0 - for plug in values(todo) - let plug.uri = substitute(plug.uri, - \ '^https://git::@github\.com', 'https://github.com', '') - endfor - endif - - if !isdirectory(g:plug_home) - try - call mkdir(g:plug_home, 'p') - catch - return s:err(printf('Invalid plug directory: %s. '. - \ 'Try to call plug#begin with a valid directory', g:plug_home)) - endtry - endif - - if has('nvim') && !exists('*jobwait') && threads > 1 - call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') - endif - - let use_job = s:nvim || s:vim8 - let python = (has('python') || has('python3')) && !use_job - let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() - - let s:update = { - \ 'start': reltime(), - \ 'all': todo, - \ 'todo': copy(todo), - \ 'errors': [], - \ 'pull': a:pull, - \ 'force': a:force, - \ 'new': {}, - \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, - \ 'bar': '', - \ 'fin': 0 - \ } - - call s:prepare(1) - call append(0, ['', '']) - normal! 2G - silent! redraw - - let s:clone_opt = [] - if get(g:, 'plug_shallow', 1) - call extend(s:clone_opt, ['--depth', '1']) - if s:git_version_requirement(1, 7, 10) - call add(s:clone_opt, '--no-single-branch') - endif - endif - - if has('win32unix') || has('wsl') - call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input']) - endif - - let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' - - " Python version requirement (>= 2.7) - if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 - redir => pyv - silent python import platform; print platform.python_version() - redir END - let python = s:version_requirement( - \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) - endif - - if (python || ruby) && s:update.threads > 1 - try - let imd = &imd - if s:mac_gui - set noimd - endif - if ruby - call s:update_ruby() - else - call s:update_python() - endif - catch - let lines = getline(4, '$') - let printed = {} - silent! 4,$d _ - for line in lines - let name = s:extract_name(line, '.', '') - if empty(name) || !has_key(printed, name) - call append('$', line) - if !empty(name) - let printed[name] = 1 - if line[0] == 'x' && index(s:update.errors, name) < 0 - call add(s:update.errors, name) - end - endif - endif - endfor - finally - let &imd = imd - call s:update_finish() - endtry - else - call s:update_vim() - while use_job && sync - sleep 100m - if s:update.fin - break - endif - endwhile - endif -endfunction - -function! s:log4(name, msg) - call setline(4, printf('- %s (%s)', a:msg, a:name)) - redraw -endfunction - -function! s:update_finish() - if exists('s:git_terminal_prompt') - let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt - endif - if s:switch_in() - call append(3, '- Updating ...') | 4 - for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) - let [pos, _] = s:logpos(name) - if !pos - continue - endif - if has_key(spec, 'commit') - call s:log4(name, 'Checking out '.spec.commit) - let out = s:checkout(spec) - elseif has_key(spec, 'tag') - let tag = spec.tag - if tag =~ '\*' - let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir)) - if !v:shell_error && !empty(tags) - let tag = tags[0] - call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) - call append(3, '') - endif - endif - call s:log4(name, 'Checking out '.tag) - let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir) - else - let branch = s:git_origin_branch(spec) - call s:log4(name, 'Merging origin/'.s:esc(branch)) - let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1' - \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir) - endif - if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && - \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) - call s:log4(name, 'Updating submodules. This may take a while.') - let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) - endif - let msg = s:format_message(v:shell_error ? 'x': '-', name, out) - if v:shell_error - call add(s:update.errors, name) - call s:regress_bar() - silent execute pos 'd _' - call append(4, msg) | 4 - elseif !empty(out) - call setline(pos, msg[0]) - endif - redraw - endfor - silent 4 d _ - try - call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) - catch - call s:warn('echom', v:exception) - call s:warn('echo', '') - return - endtry - call s:finish(s:update.pull) - call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') - call s:switch_out('normal! gg') - endif -endfunction - -function! s:job_abort() - if (!s:nvim && !s:vim8) || !exists('s:jobs') - return - endif - - for [name, j] in items(s:jobs) - if s:nvim - silent! call jobstop(j.jobid) - elseif s:vim8 - silent! call job_stop(j.jobid) - endif - if j.new - call s:rm_rf(g:plugs[name].dir) - endif - endfor - let s:jobs = {} -endfunction - -function! s:last_non_empty_line(lines) - let len = len(a:lines) - for idx in range(len) - let line = a:lines[len-idx-1] - if !empty(line) - return line - endif - endfor - return '' -endfunction - -function! s:job_out_cb(self, data) abort - let self = a:self - let data = remove(self.lines, -1) . a:data - let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') - call extend(self.lines, lines) - " To reduce the number of buffer updates - let self.tick = get(self, 'tick', -1) + 1 - if !self.running || self.tick % len(s:jobs) == 0 - let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') - let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) - call s:log(bullet, self.name, result) - endif -endfunction - -function! s:job_exit_cb(self, data) abort - let a:self.running = 0 - let a:self.error = a:data != 0 - call s:reap(a:self.name) - call s:tick() -endfunction - -function! s:job_cb(fn, job, ch, data) - if !s:plug_window_exists() " plug window closed - return s:job_abort() - endif - call call(a:fn, [a:job, a:data]) -endfunction - -function! s:nvim_cb(job_id, data, event) dict abort - return (a:event == 'stdout' || a:event == 'stderr') ? - \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : - \ s:job_cb('s:job_exit_cb', self, 0, a:data) -endfunction - -function! s:spawn(name, cmd, opts) - let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], - \ 'new': get(a:opts, 'new', 0) } - let s:jobs[a:name] = job - - if s:nvim - if has_key(a:opts, 'dir') - let job.cwd = a:opts.dir - endif - let argv = a:cmd - call extend(job, { - \ 'on_stdout': function('s:nvim_cb'), - \ 'on_stderr': function('s:nvim_cb'), - \ 'on_exit': function('s:nvim_cb'), - \ }) - let jid = s:plug_call('jobstart', argv, job) - if jid > 0 - let job.jobid = jid - else - let job.running = 0 - let job.error = 1 - let job.lines = [jid < 0 ? argv[0].' is not executable' : - \ 'Invalid arguments (or job table is full)'] - endif - elseif s:vim8 - let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})')) - if has_key(a:opts, 'dir') - let cmd = s:with_cd(cmd, a:opts.dir, 0) - endif - let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd] - let jid = job_start(s:is_win ? join(argv, ' ') : argv, { - \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), - \ 'err_cb': function('s:job_cb', ['s:job_out_cb', job]), - \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), - \ 'err_mode': 'raw', - \ 'out_mode': 'raw' - \}) - if job_status(jid) == 'run' - let job.jobid = jid - else - let job.running = 0 - let job.error = 1 - let job.lines = ['Failed to start job'] - endif - else - let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd])) - let job.error = v:shell_error != 0 - let job.running = 0 - endif -endfunction - -function! s:reap(name) - let job = s:jobs[a:name] - if job.error - call add(s:update.errors, a:name) - elseif get(job, 'new', 0) - let s:update.new[a:name] = 1 - endif - let s:update.bar .= job.error ? 'x' : '=' - - let bullet = job.error ? 'x' : '-' - let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) - call s:log(bullet, a:name, empty(result) ? 'OK' : result) - call s:bar() - - call remove(s:jobs, a:name) -endfunction - -function! s:bar() - if s:switch_in() - let total = len(s:update.all) - call setline(1, (s:update.pull ? 'Updating' : 'Installing'). - \ ' plugins ('.len(s:update.bar).'/'.total.')') - call s:progress_bar(2, s:update.bar, total) - call s:switch_out() - endif -endfunction - -function! s:logpos(name) - let max = line('$') - for i in range(4, max > 4 ? max : 4) - if getline(i) =~# '^[-+x*] '.a:name.':' - for j in range(i + 1, max > 5 ? max : 5) - if getline(j) !~ '^ ' - return [i, j - 1] - endif - endfor - return [i, i] - endif - endfor - return [0, 0] -endfunction - -function! s:log(bullet, name, lines) - if s:switch_in() - let [b, e] = s:logpos(a:name) - if b > 0 - silent execute printf('%d,%d d _', b, e) - if b > winheight('.') - let b = 4 - endif - else - let b = 4 - endif - " FIXME For some reason, nomodifiable is set after :d in vim8 - setlocal modifiable - call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) - call s:switch_out() - endif -endfunction - -function! s:update_vim() - let s:jobs = {} - - call s:bar() - call s:tick() -endfunction - -function! s:tick() - let pull = s:update.pull - let prog = s:progress_opt(s:nvim || s:vim8) -while 1 " Without TCO, Vim stack is bound to explode - if empty(s:update.todo) - if empty(s:jobs) && !s:update.fin - call s:update_finish() - let s:update.fin = 1 - endif - return - endif - - let name = keys(s:update.todo)[0] - let spec = remove(s:update.todo, name) - let new = empty(globpath(spec.dir, '.git', 1)) - - call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') - redraw - - let has_tag = has_key(spec, 'tag') - if !new - let [error, _] = s:git_validate(spec, 0) - if empty(error) - if pull - let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch'] - if has_tag && !empty(globpath(spec.dir, '.git/shallow')) - call extend(cmd, ['--depth', '99999999']) - endif - if !empty(prog) - call add(cmd, prog) - endif - call s:spawn(name, cmd, { 'dir': spec.dir }) - else - let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } - endif - else - let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } - endif - else - let cmd = ['git', 'clone'] - if !has_tag - call extend(cmd, s:clone_opt) - endif - if !empty(prog) - call add(cmd, prog) - endif - call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 }) - endif - - if !s:jobs[name].running - call s:reap(name) - endif - if len(s:jobs) >= s:update.threads - break - endif -endwhile -endfunction - -function! s:update_python() -let py_exe = has('python') ? 'python' : 'python3' -execute py_exe "<< EOF" -import datetime -import functools -import os -try: - import queue -except ImportError: - import Queue as queue -import random -import re -import shutil -import signal -import subprocess -import tempfile -import threading as thr -import time -import traceback -import vim - -G_NVIM = vim.eval("has('nvim')") == '1' -G_PULL = vim.eval('s:update.pull') == '1' -G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 -G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) -G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt')) -G_PROGRESS = vim.eval('s:progress_opt(1)') -G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) -G_STOP = thr.Event() -G_IS_WIN = vim.eval('s:is_win') == '1' - -class PlugError(Exception): - def __init__(self, msg): - self.msg = msg -class CmdTimedOut(PlugError): - pass -class CmdFailed(PlugError): - pass -class InvalidURI(PlugError): - pass -class Action(object): - INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] - -class Buffer(object): - def __init__(self, lock, num_plugs, is_pull): - self.bar = '' - self.event = 'Updating' if is_pull else 'Installing' - self.lock = lock - self.maxy = int(vim.eval('winheight(".")')) - self.num_plugs = num_plugs - - def __where(self, name): - """ Find first line with name in current buffer. Return line num. """ - found, lnum = False, 0 - matcher = re.compile('^[-+x*] {0}:'.format(name)) - for line in vim.current.buffer: - if matcher.search(line) is not None: - found = True - break - lnum += 1 - - if not found: - lnum = -1 - return lnum - - def header(self): - curbuf = vim.current.buffer - curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) - - num_spaces = self.num_plugs - len(self.bar) - curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') - - with self.lock: - vim.command('normal! 2G') - vim.command('redraw') - - def write(self, action, name, lines): - first, rest = lines[0], lines[1:] - msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] - msg.extend([' ' + line for line in rest]) - - try: - if action == Action.ERROR: - self.bar += 'x' - vim.command("call add(s:update.errors, '{0}')".format(name)) - elif action == Action.DONE: - self.bar += '=' - - curbuf = vim.current.buffer - lnum = self.__where(name) - if lnum != -1: # Found matching line num - del curbuf[lnum] - if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): - lnum = 3 - else: - lnum = 3 - curbuf.append(msg, lnum) - - self.header() - except vim.error: - pass - -class Command(object): - CD = 'cd /d' if G_IS_WIN else 'cd' - - def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): - self.cmd = cmd - if cmd_dir: - self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) - self.timeout = timeout - self.callback = cb if cb else (lambda msg: None) - self.clean = clean if clean else (lambda: None) - self.proc = None - - @property - def alive(self): - """ Returns true only if command still running. """ - return self.proc and self.proc.poll() is None - - def execute(self, ntries=3): - """ Execute the command with ntries if CmdTimedOut. - Returns the output of the command if no Exception. - """ - attempt, finished, limit = 0, False, self.timeout - - while not finished: - try: - attempt += 1 - result = self.try_command() - finished = True - return result - except CmdTimedOut: - if attempt != ntries: - self.notify_retry() - self.timeout += limit - else: - raise - - def notify_retry(self): - """ Retry required for command, notify user. """ - for count in range(3, 0, -1): - if G_STOP.is_set(): - raise KeyboardInterrupt - msg = 'Timeout. Will retry in {0} second{1} ...'.format( - count, 's' if count != 1 else '') - self.callback([msg]) - time.sleep(1) - self.callback(['Retrying ...']) - - def try_command(self): - """ Execute a cmd & poll for callback. Returns list of output. - Raises CmdFailed -> return code for Popen isn't 0 - Raises CmdTimedOut -> command exceeded timeout without new output - """ - first_line = True - - try: - tfile = tempfile.NamedTemporaryFile(mode='w+b') - preexec_fn = not G_IS_WIN and os.setsid or None - self.proc = subprocess.Popen(self.cmd, stdout=tfile, - stderr=subprocess.STDOUT, - stdin=subprocess.PIPE, shell=True, - preexec_fn=preexec_fn) - thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) - thrd.start() - - thread_not_started = True - while thread_not_started: - try: - thrd.join(0.1) - thread_not_started = False - except RuntimeError: - pass - - while self.alive: - if G_STOP.is_set(): - raise KeyboardInterrupt - - if first_line or random.random() < G_LOG_PROB: - first_line = False - line = '' if G_IS_WIN else nonblock_read(tfile.name) - if line: - self.callback([line]) - - time_diff = time.time() - os.path.getmtime(tfile.name) - if time_diff > self.timeout: - raise CmdTimedOut(['Timeout!']) - - thrd.join(0.5) - - tfile.seek(0) - result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] - - if self.proc.returncode != 0: - raise CmdFailed([''] + result) - - return result - except: - self.terminate() - raise - - def terminate(self): - """ Terminate process and cleanup. """ - if self.alive: - if G_IS_WIN: - os.kill(self.proc.pid, signal.SIGINT) - else: - os.killpg(self.proc.pid, signal.SIGTERM) - self.clean() - -class Plugin(object): - def __init__(self, name, args, buf_q, lock): - self.name = name - self.args = args - self.buf_q = buf_q - self.lock = lock - self.tag = args.get('tag', 0) - - def manage(self): - try: - if os.path.exists(self.args['dir']): - self.update() - else: - self.install() - with self.lock: - thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) - except PlugError as exc: - self.write(Action.ERROR, self.name, exc.msg) - except KeyboardInterrupt: - G_STOP.set() - self.write(Action.ERROR, self.name, ['Interrupted!']) - except: - # Any exception except those above print stack trace - msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) - self.write(Action.ERROR, self.name, msg.split('\n')) - raise - - def install(self): - target = self.args['dir'] - if target[-1] == '\\': - target = target[0:-1] - - def clean(target): - def _clean(): - try: - shutil.rmtree(target) - except OSError: - pass - return _clean - - self.write(Action.INSTALL, self.name, ['Installing ...']) - callback = functools.partial(self.write, Action.INSTALL, self.name) - cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( - '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], - esc(target)) - com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) - result = com.execute(G_RETRIES) - self.write(Action.DONE, self.name, result[-1:]) - - def repo_uri(self): - cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' - command = Command(cmd, self.args['dir'], G_TIMEOUT,) - result = command.execute(G_RETRIES) - return result[-1] - - def update(self): - actual_uri = self.repo_uri() - expect_uri = self.args['uri'] - regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') - ma = regex.match(actual_uri) - mb = regex.match(expect_uri) - if ma is None or mb is None or ma.groups() != mb.groups(): - msg = ['', - 'Invalid URI: {0}'.format(actual_uri), - 'Expected {0}'.format(expect_uri), - 'PlugClean required.'] - raise InvalidURI(msg) - - if G_PULL: - self.write(Action.UPDATE, self.name, ['Updating ...']) - callback = functools.partial(self.write, Action.UPDATE, self.name) - fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' - cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) - com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) - result = com.execute(G_RETRIES) - self.write(Action.DONE, self.name, result[-1:]) - else: - self.write(Action.DONE, self.name, ['Already installed']) - - def write(self, action, name, msg): - self.buf_q.put((action, name, msg)) - -class PlugThread(thr.Thread): - def __init__(self, tname, args): - super(PlugThread, self).__init__() - self.tname = tname - self.args = args - - def run(self): - thr.current_thread().name = self.tname - buf_q, work_q, lock = self.args - - try: - while not G_STOP.is_set(): - name, args = work_q.get_nowait() - plug = Plugin(name, args, buf_q, lock) - plug.manage() - work_q.task_done() - except queue.Empty: - pass - -class RefreshThread(thr.Thread): - def __init__(self, lock): - super(RefreshThread, self).__init__() - self.lock = lock - self.running = True - - def run(self): - while self.running: - with self.lock: - thread_vim_command('noautocmd normal! a') - time.sleep(0.33) - - def stop(self): - self.running = False - -if G_NVIM: - def thread_vim_command(cmd): - vim.session.threadsafe_call(lambda: vim.command(cmd)) -else: - def thread_vim_command(cmd): - vim.command(cmd) - -def esc(name): - return '"' + name.replace('"', '\"') + '"' - -def nonblock_read(fname): - """ Read a file with nonblock flag. Return the last line. """ - fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) - buf = os.read(fread, 100000).decode('utf-8', 'replace') - os.close(fread) - - line = buf.rstrip('\r\n') - left = max(line.rfind('\r'), line.rfind('\n')) - if left != -1: - left += 1 - line = line[left:] - - return line - -def main(): - thr.current_thread().name = 'main' - nthreads = int(vim.eval('s:update.threads')) - plugs = vim.eval('s:update.todo') - mac_gui = vim.eval('s:mac_gui') == '1' - - lock = thr.Lock() - buf = Buffer(lock, len(plugs), G_PULL) - buf_q, work_q = queue.Queue(), queue.Queue() - for work in plugs.items(): - work_q.put(work) - - start_cnt = thr.active_count() - for num in range(nthreads): - tname = 'PlugT-{0:02}'.format(num) - thread = PlugThread(tname, (buf_q, work_q, lock)) - thread.start() - if mac_gui: - rthread = RefreshThread(lock) - rthread.start() - - while not buf_q.empty() or thr.active_count() != start_cnt: - try: - action, name, msg = buf_q.get(True, 0.25) - buf.write(action, name, ['OK'] if not msg else msg) - buf_q.task_done() - except queue.Empty: - pass - except KeyboardInterrupt: - G_STOP.set() - - if mac_gui: - rthread.stop() - rthread.join() - -main() -EOF -endfunction - -function! s:update_ruby() - ruby << EOF - module PlugStream - SEP = ["\r", "\n", nil] - def get_line - buffer = '' - loop do - char = readchar rescue return - if SEP.include? char.chr - buffer << $/ - break - else - buffer << char - end - end - buffer - end - end unless defined?(PlugStream) - - def esc arg - %["#{arg.gsub('"', '\"')}"] - end - - def killall pid - pids = [pid] - if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM - pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } - else - unless `which pgrep 2> /dev/null`.empty? - children = pids - until children.empty? - children = children.map { |pid| - `pgrep -P #{pid}`.lines.map { |l| l.chomp } - }.flatten - pids += children - end - end - pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } - end - end - - def compare_git_uri a, b - regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} - regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) - end - - require 'thread' - require 'fileutils' - require 'timeout' - running = true - iswin = VIM::evaluate('s:is_win').to_i == 1 - pull = VIM::evaluate('s:update.pull').to_i == 1 - base = VIM::evaluate('g:plug_home') - all = VIM::evaluate('s:update.todo') - limit = VIM::evaluate('get(g:, "plug_timeout", 60)') - tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 - nthr = VIM::evaluate('s:update.threads').to_i - maxy = VIM::evaluate('winheight(".")').to_i - vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ - cd = iswin ? 'cd /d' : 'cd' - tot = VIM::evaluate('len(s:update.todo)') || 0 - bar = '' - skip = 'Already installed' - mtx = Mutex.new - take1 = proc { mtx.synchronize { running && all.shift } } - logh = proc { - cnt = bar.length - $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" - $curbuf[2] = '[' + bar.ljust(tot) + ']' - VIM::command('normal! 2G') - VIM::command('redraw') - } - where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } - log = proc { |name, result, type| - mtx.synchronize do - ing = ![true, false].include?(type) - bar += type ? '=' : 'x' unless ing - b = case type - when :install then '+' when :update then '*' - when true, nil then '-' else - VIM::command("call add(s:update.errors, '#{name}')") - 'x' - end - result = - if type || type.nil? - ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] - elsif result =~ /^Interrupted|^Timeout/ - ["#{b} #{name}: #{result}"] - else - ["#{b} #{name}"] + result.lines.map { |l| " " << l } - end - if lnum = where.call(name) - $curbuf.delete lnum - lnum = 4 if ing && lnum > maxy - end - result.each_with_index do |line, offset| - $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) - end - logh.call - end - } - bt = proc { |cmd, name, type, cleanup| - tried = timeout = 0 - begin - tried += 1 - timeout += limit - fd = nil - data = '' - if iswin - Timeout::timeout(timeout) do - tmp = VIM::evaluate('tempname()') - system("(#{cmd}) > #{tmp}") - data = File.read(tmp).chomp - File.unlink tmp rescue nil - end - else - fd = IO.popen(cmd).extend(PlugStream) - first_line = true - log_prob = 1.0 / nthr - while line = Timeout::timeout(timeout) { fd.get_line } - data << line - log.call name, line.chomp, type if name && (first_line || rand < log_prob) - first_line = false - end - fd.close - end - [$? == 0, data.chomp] - rescue Timeout::Error, Interrupt => e - if fd && !fd.closed? - killall fd.pid - fd.close - end - cleanup.call if cleanup - if e.is_a?(Timeout::Error) && tried < tries - 3.downto(1) do |countdown| - s = countdown > 1 ? 's' : '' - log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type - sleep 1 - end - log.call name, 'Retrying ...', type - retry - end - [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] - end - } - main = Thread.current - threads = [] - watcher = Thread.new { - if vim7 - while VIM::evaluate('getchar(1)') - sleep 0.1 - end - else - require 'io/console' # >= Ruby 1.9 - nil until IO.console.getch == 3.chr - end - mtx.synchronize do - running = false - threads.each { |t| t.raise Interrupt } unless vim7 - end - threads.each { |t| t.join rescue nil } - main.kill - } - refresh = Thread.new { - while true - mtx.synchronize do - break unless running - VIM::command('noautocmd normal! a') - end - sleep 0.2 - end - } if VIM::evaluate('s:mac_gui') == 1 - - clone_opt = VIM::evaluate('s:clone_opt').join(' ') - progress = VIM::evaluate('s:progress_opt(1)') - nthr.times do - mtx.synchronize do - threads << Thread.new { - while pair = take1.call - name = pair.first - dir, uri, tag = pair.last.values_at *%w[dir uri tag] - exists = File.directory? dir - ok, result = - if exists - chdir = "#{cd} #{iswin ? dir : esc(dir)}" - ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil - current_uri = data.lines.to_a.last - if !ret - if data =~ /^Interrupted|^Timeout/ - [false, data] - else - [false, [data.chomp, "PlugClean required."].join($/)] - end - elsif !compare_git_uri(current_uri, uri) - [false, ["Invalid URI: #{current_uri}", - "Expected: #{uri}", - "PlugClean required."].join($/)] - else - if pull - log.call name, 'Updating ...', :update - fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' - bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil - else - [true, skip] - end - end - else - d = esc dir.sub(%r{[\\/]+$}, '') - log.call name, 'Installing ...', :install - bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { - FileUtils.rm_rf dir - } - end - mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok - log.call name, result, ok - end - } if running - end - end - threads.each { |t| t.join rescue nil } - logh.call - refresh.kill if refresh - watcher.kill -EOF -endfunction - -function! s:shellesc_cmd(arg, script) - let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g') - return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g') -endfunction - -function! s:shellesc_ps1(arg) - return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'" -endfunction - -function! s:shellesc_sh(arg) - return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'" -endfunction - -" Escape the shell argument based on the shell. -" Vim and Neovim's shellescape() are insufficient. -" 1. shellslash determines whether to use single/double quotes. -" Double-quote escaping is fragile for cmd.exe. -" 2. It does not work for powershell. -" 3. It does not work for *sh shells if the command is executed -" via cmd.exe (ie. cmd.exe /c sh -c command command_args) -" 4. It does not support batchfile syntax. -" -" Accepts an optional dictionary with the following keys: -" - shell: same as Vim/Neovim 'shell' option. -" If unset, fallback to 'cmd.exe' on Windows or 'sh'. -" - script: If truthy and shell is cmd.exe, escape for batchfile syntax. -function! plug#shellescape(arg, ...) - if a:arg =~# '^[A-Za-z0-9_/:.-]\+$' - return a:arg - endif - let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} - let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') - let script = get(opts, 'script', 1) - if shell =~# 'cmd\(\.exe\)\?$' - return s:shellesc_cmd(a:arg, script) - elseif shell =~# 'powershell\(\.exe\)\?$' || shell =~# 'pwsh$' - return s:shellesc_ps1(a:arg) - endif - return s:shellesc_sh(a:arg) -endfunction - -function! s:glob_dir(path) - return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') -endfunction - -function! s:progress_bar(line, bar, total) - call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') -endfunction - -function! s:compare_git_uri(a, b) - " See `git help clone' - " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] - " [git@] github.com[:port] : junegunn/vim-plug [.git] - " file:// / junegunn/vim-plug [/] - " / junegunn/vim-plug [/] - let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' - let ma = matchlist(a:a, pat) - let mb = matchlist(a:b, pat) - return ma[1:2] ==# mb[1:2] -endfunction - -function! s:format_message(bullet, name, message) - if a:bullet != 'x' - return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] - else - let lines = map(s:lines(a:message), '" ".v:val') - return extend([printf('x %s:', a:name)], lines) - endif -endfunction - -function! s:with_cd(cmd, dir, ...) - let script = a:0 > 0 ? a:1 : 1 - return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd) -endfunction - -function! s:system(cmd, ...) - let batchfile = '' - try - let [sh, shellcmdflag, shrd] = s:chsh(1) - if type(a:cmd) == s:TYPE.list - " Neovim's system() supports list argument to bypass the shell - " but it cannot set the working directory for the command. - " Assume that the command does not rely on the shell. - if has('nvim') && a:0 == 0 - return system(a:cmd) - endif - let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})')) - if &shell =~# 'powershell\(\.exe\)\?$' - let cmd = '& ' . cmd - endif - else - let cmd = a:cmd - endif - if a:0 > 0 - let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list) - endif - if s:is_win && type(a:cmd) != s:TYPE.list - let [batchfile, cmd] = s:batchfile(cmd) - endif - return system(cmd) - finally - let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] - if s:is_win && filereadable(batchfile) - call delete(batchfile) - endif - endtry -endfunction - -function! s:system_chomp(...) - let ret = call('s:system', a:000) - return v:shell_error ? '' : substitute(ret, '\n$', '', '') -endfunction - -function! s:git_validate(spec, check_branch) - let err = '' - if isdirectory(a:spec.dir) - let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)] - let remote = result[-1] - if empty(remote) - let err = join([remote, 'PlugClean required.'], "\n") - elseif !s:compare_git_uri(remote, a:spec.uri) - let err = join(['Invalid URI: '.remote, - \ 'Expected: '.a:spec.uri, - \ 'PlugClean required.'], "\n") - elseif a:check_branch && has_key(a:spec, 'commit') - let sha = s:git_revision(a:spec.dir) - if empty(sha) - let err = join(add(result, 'PlugClean required.'), "\n") - elseif !s:hash_match(sha, a:spec.commit) - let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', - \ a:spec.commit[:6], sha[:6]), - \ 'PlugUpdate required.'], "\n") - endif - elseif a:check_branch - let current_branch = result[0] - " Check tag - let origin_branch = s:git_origin_branch(a:spec) - if has_key(a:spec, 'tag') - let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) - if a:spec.tag !=# tag && a:spec.tag !~ '\*' - let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', - \ (empty(tag) ? 'N/A' : tag), a:spec.tag) - endif - " Check branch - elseif origin_branch !=# current_branch - let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', - \ current_branch, origin_branch) - endif - if empty(err) - let [ahead, behind] = split(s:lastline(s:system([ - \ 'git', 'rev-list', '--count', '--left-right', - \ printf('HEAD...origin/%s', origin_branch) - \ ], a:spec.dir)), '\t') - if !v:shell_error && ahead - if behind - " Only mention PlugClean if diverged, otherwise it's likely to be - " pushable (and probably not that messed up). - let err = printf( - \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" - \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind) - else - let err = printf("Ahead of origin/%s by %d commit(s).\n" - \ .'Cannot update until local changes are pushed.', - \ origin_branch, ahead) - endif - endif - endif - endif - else - let err = 'Not found' - endif - return [err, err =~# 'PlugClean'] -endfunction - -function! s:rm_rf(dir) - if isdirectory(a:dir) - return s:system(s:is_win - \ ? 'rmdir /S /Q '.plug#shellescape(a:dir) - \ : ['rm', '-rf', a:dir]) - endif -endfunction - -function! s:clean(force) - call s:prepare() - call append(0, 'Searching for invalid plugins in '.g:plug_home) - call append(1, '') - - " List of valid directories - let dirs = [] - let errs = {} - let [cnt, total] = [0, len(g:plugs)] - for [name, spec] in items(g:plugs) - if !s:is_managed(name) - call add(dirs, spec.dir) - else - let [err, clean] = s:git_validate(spec, 1) - if clean - let errs[spec.dir] = s:lines(err)[0] - else - call add(dirs, spec.dir) - endif - endif - let cnt += 1 - call s:progress_bar(2, repeat('=', cnt), total) - normal! 2G - redraw - endfor - - let allowed = {} - for dir in dirs - let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1 - let allowed[dir] = 1 - for child in s:glob_dir(dir) - let allowed[child] = 1 - endfor - endfor - - let todo = [] - let found = sort(s:glob_dir(g:plug_home)) - while !empty(found) - let f = remove(found, 0) - if !has_key(allowed, f) && isdirectory(f) - call add(todo, f) - call append(line('$'), '- ' . f) - if has_key(errs, f) - call append(line('$'), ' ' . errs[f]) - endif - let found = filter(found, 'stridx(v:val, f) != 0') - end - endwhile - - 4 - redraw - if empty(todo) - call append(line('$'), 'Already clean.') - else - let s:clean_count = 0 - call append(3, ['Directories to delete:', '']) - redraw! - if a:force || s:ask_no_interrupt('Delete all directories?') - call s:delete([6, line('$')], 1) - else - call setline(4, 'Cancelled.') - nnoremap d :set opfunc=delete_opg@ - nmap dd d_ - xnoremap d :call delete_op(visualmode(), 1) - echo 'Delete the lines (d{motion}) to delete the corresponding directories' - endif - endif - 4 - setlocal nomodifiable -endfunction - -function! s:delete_op(type, ...) - call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) -endfunction - -function! s:delete(range, force) - let [l1, l2] = a:range - let force = a:force - let err_count = 0 - while l1 <= l2 - let line = getline(l1) - if line =~ '^- ' && isdirectory(line[2:]) - execute l1 - redraw! - let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) - let force = force || answer > 1 - if answer - let err = s:rm_rf(line[2:]) - setlocal modifiable - if empty(err) - call setline(l1, '~'.line[1:]) - let s:clean_count += 1 - else - delete _ - call append(l1 - 1, s:format_message('x', line[1:], err)) - let l2 += len(s:lines(err)) - let err_count += 1 - endif - let msg = printf('Removed %d directories.', s:clean_count) - if err_count > 0 - let msg .= printf(' Failed to remove %d directories.', err_count) - endif - call setline(4, msg) - setlocal nomodifiable - endif - endif - let l1 += 1 - endwhile -endfunction - -function! s:upgrade() - echo 'Downloading the latest version of vim-plug' - redraw - let tmp = s:plug_tempname() - let new = tmp . '/plug.vim' - - try - let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp]) - if v:shell_error - return s:err('Error upgrading vim-plug: '. out) - endif - - if readfile(s:me) ==# readfile(new) - echo 'vim-plug is already up-to-date' - return 0 - else - call rename(s:me, s:me . '.old') - call rename(new, s:me) - unlet g:loaded_plug - echo 'vim-plug has been upgraded' - return 1 - endif - finally - silent! call s:rm_rf(tmp) - endtry -endfunction - -function! s:upgrade_specs() - for spec in values(g:plugs) - let spec.frozen = get(spec, 'frozen', 0) - endfor -endfunction - -function! s:status() - call s:prepare() - call append(0, 'Checking plugins') - call append(1, '') - - let ecnt = 0 - let unloaded = 0 - let [cnt, total] = [0, len(g:plugs)] - for [name, spec] in items(g:plugs) - let is_dir = isdirectory(spec.dir) - if has_key(spec, 'uri') - if is_dir - let [err, _] = s:git_validate(spec, 1) - let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] - else - let [valid, msg] = [0, 'Not found. Try PlugInstall.'] - endif - else - if is_dir - let [valid, msg] = [1, 'OK'] - else - let [valid, msg] = [0, 'Not found.'] - endif - endif - let cnt += 1 - let ecnt += !valid - " `s:loaded` entry can be missing if PlugUpgraded - if is_dir && get(s:loaded, name, -1) == 0 - let unloaded = 1 - let msg .= ' (not loaded)' - endif - call s:progress_bar(2, repeat('=', cnt), total) - call append(3, s:format_message(valid ? '-' : 'x', name, msg)) - normal! 2G - redraw - endfor - call setline(1, 'Finished. '.ecnt.' error(s).') - normal! gg - setlocal nomodifiable - if unloaded - echo "Press 'L' on each line to load plugin, or 'U' to update" - nnoremap L :call status_load(line('.')) - xnoremap L :call status_load(line('.')) - end -endfunction - -function! s:extract_name(str, prefix, suffix) - return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') -endfunction - -function! s:status_load(lnum) - let line = getline(a:lnum) - let name = s:extract_name(line, '-', '(not loaded)') - if !empty(name) - call plug#load(name) - setlocal modifiable - call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) - setlocal nomodifiable - endif -endfunction - -function! s:status_update() range - let lines = getline(a:firstline, a:lastline) - let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') - if !empty(names) - echo - execute 'PlugUpdate' join(names) - endif -endfunction - -function! s:is_preview_window_open() - silent! wincmd P - if &previewwindow - wincmd p - return 1 - endif -endfunction - -function! s:find_name(lnum) - for lnum in reverse(range(1, a:lnum)) - let line = getline(lnum) - if empty(line) - return '' - endif - let name = s:extract_name(line, '-', '') - if !empty(name) - return name - endif - endfor - return '' -endfunction - -function! s:preview_commit() - if b:plug_preview < 0 - let b:plug_preview = !s:is_preview_window_open() - endif - - let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') - if empty(sha) - return - endif - - let name = s:find_name(line('.')) - if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) - return - endif - - if exists('g:plug_pwindow') && !s:is_preview_window_open() - execute g:plug_pwindow - execute 'e' sha - else - execute 'pedit' sha - wincmd P - endif - setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable - let batchfile = '' - try - let [sh, shellcmdflag, shrd] = s:chsh(1) - let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha - if s:is_win - let [batchfile, cmd] = s:batchfile(cmd) - endif - execute 'silent %!' cmd - finally - let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] - if s:is_win && filereadable(batchfile) - call delete(batchfile) - endif - endtry - setlocal nomodifiable - nnoremap q :q - wincmd p -endfunction - -function! s:section(flags) - call search('\(^[x-] \)\@<=[^:]\+:', a:flags) -endfunction - -function! s:format_git_log(line) - let indent = ' ' - let tokens = split(a:line, nr2char(1)) - if len(tokens) != 5 - return indent.substitute(a:line, '\s*$', '', '') - endif - let [graph, sha, refs, subject, date] = tokens - let tag = matchstr(refs, 'tag: [^,)]\+') - let tag = empty(tag) ? ' ' : ' ('.tag.') ' - return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) -endfunction - -function! s:append_ul(lnum, text) - call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) -endfunction - -function! s:diff() - call s:prepare() - call append(0, ['Collecting changes ...', '']) - let cnts = [0, 0] - let bar = '' - let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') - call s:progress_bar(2, bar, len(total)) - for origin in [1, 0] - let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) - if empty(plugs) - continue - endif - call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') - for [k, v] in plugs - let branch = s:git_origin_branch(v) - if len(branch) - let range = origin ? '..origin/'.branch : 'HEAD@{1}..' - let cmd = ['git', 'log', '--graph', '--color=never'] - if s:git_version_requirement(2, 10, 0) - call add(cmd, '--no-show-signature') - endif - call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range]) - if has_key(v, 'rtp') - call extend(cmd, ['--', v.rtp]) - endif - let diff = s:system_chomp(cmd, v.dir) - if !empty(diff) - let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' - call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) - let cnts[origin] += 1 - endif - endif - let bar .= '=' - call s:progress_bar(2, bar, len(total)) - normal! 2G - redraw - endfor - if !cnts[origin] - call append(5, ['', 'N/A']) - endif - endfor - call setline(1, printf('%d plugin(s) updated.', cnts[0]) - \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) - - if cnts[0] || cnts[1] - nnoremap (plug-preview) :silent! call preview_commit() - if empty(maparg("\", 'n')) - nmap (plug-preview) - endif - if empty(maparg('o', 'n')) - nmap o (plug-preview) - endif - endif - if cnts[0] - nnoremap X :call revert() - echo "Press 'X' on each block to revert the update" - endif - normal! gg - setlocal nomodifiable -endfunction - -function! s:revert() - if search('^Pending updates', 'bnW') - return - endif - - let name = s:find_name(line('.')) - if empty(name) || !has_key(g:plugs, name) || - \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' - return - endif - - call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir) - setlocal modifiable - normal! "_dap - setlocal nomodifiable - echo 'Reverted' -endfunction - -function! s:snapshot(force, ...) abort - call s:prepare() - setf vim - call append(0, ['" Generated by vim-plug', - \ '" '.strftime("%c"), - \ '" :source this file in vim to restore the snapshot', - \ '" or execute: vim -S snapshot.vim', - \ '', '', 'PlugUpdate!']) - 1 - let anchor = line('$') - 3 - let names = sort(keys(filter(copy(g:plugs), - \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) - for name in reverse(names) - let sha = s:git_revision(g:plugs[name].dir) - if !empty(sha) - call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) - redraw - endif - endfor - - if a:0 > 0 - let fn = s:plug_expand(a:1) - if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) - return - endif - call writefile(getline(1, '$'), fn) - echo 'Saved as '.a:1 - silent execute 'e' s:esc(fn) - setf vim - endif -endfunction - -function! s:split_rtp() - return split(&rtp, '\\\@ fzf#install() } } - Plug 'eugen0329/vim-esearch' - Plug 'tpope/vim-fugitive' - Plug 'w0rp/ale' - Plug 'itchyny/lightline.vim' - Plug 'airblade/vim-gitgutter' -call plug#end() - - "Settings -set shell=fish -set nocompatible -set number -set listchars=eol:¬,tab:>·,trail:~,extends:>,precedes:<,space:· -set list -set relativenumber -set wildignore+=node_modules/**,dist/** -set splitright -set splitbelow -set autoread -set colorcolumn=80 -set shiftwidth=2 -set smartindent -set clipboard=unnamed " Use system clipboard -set laststatus=2 -set noshowmode -set updatetime=250 -set timeoutlen=1000 -set ttimeoutlen=0 -set backspace=indent,eol,start -set completeopt=menu,menuone,preview,noselect,noinsert -set diffopt+=iwhite - -if has('mouse') - set mouse=a -endif - -if has('mouse_sgr') - set ttymouse=sgr -endif - -let g:netrw_liststyle = 3 " Tree view -let g:netrw_sort_sequence = '[\/]$,*' " Show directories first -let g:netrw_browse_split = 4 " Use the previous window for the new file -let g:netrw_winsize = -28 " Absolute width of the netrw window -let g:netrw_banner = 0 " Disable the banner - -let g:ackprg = 'rg --files --hidden --follow --glob "!{.git,node_modules}/*"' " Use RipGrep to search - -silent! syntax enable -filetype plugin on -filetype plugin indent on - -" Mappings -let mapleader = "\" - -" Keys in all modes -map :FZF -map :Lexplore - -" Keys in normal mode -nmap n :cnext -nmap N :cprev -nmap c :tabedit \| term ++curwin -nmap x :bd! -nmap q :q -nmap :noh -nmap gd :ALEGoToDefinition -nmap gN :ALERename - -" Replace mappings for keys in normal mode -nnoremap :Buffers -nnoremap \| :vsp \| term ++curwin -nnoremap - :sp \| term ++curwin -nnoremap :call SyntaxFold('zA') -noremap \\ :call NERDComment(0,"toggle") -noremap ; :Commands -noremap :ALEGoToDefinitionInVSplit - -function! WrapForTmux(s) - if !exists('$TMUX') - return a:s - endif - - let tmux_start = "\Ptmux;" - let tmux_end = "\\\" - - return tmux_start . substitute(a:s, "\", "\\", 'g') . tmux_end -endfunction - -let &t_SI .= WrapForTmux("\[?2004h") -let &t_EI .= WrapForTmux("\[?2004l") - -function! XTermPasteBegin() - set pastetoggle=[201~ - set paste - return "" -endfunction - -inoremap [200~ XTermPasteBegin() - -autocmd CursorHold * if mode() != 'c' | checktime | endif -autocmd FileChangedShellPost * - \ echohl WarningMsg | echo "File changed on disk. Buffer reloaded." | echohl None - -autocmd BufWritePost * GitGutter - -" Linting -let g:ale_fixers = { - \ 'javascript': ['eslint', 'remove_trailing_lines'], - \ 'json': ['prettier'], - \} - -let g:ale_linters = { - \ 'javascript': ['eslint'], - \ 'typescript': ['eslint', 'tsserver'], - \ 'typescriptreact': ['eslint', 'tsserver'], - \} - -let g:ale_sign_error = '😰' -let g:ale_sign_warning = '😕' -let g:ale_completion_enabled = 1 -let g:ale_completion_autoimport = 1 -let g:ale_fix_on_save = 1 -set omnifunc=ale#completion#OmniFunc - - -" Statusline -let g:lightline = { - \ 'colorscheme': 'wombat', - \ 'active': { - \ 'left': [ [ 'mode', 'paste' ], - \ [ 'gitbranch', 'readonly', 'filename', 'modified' ] ], - \ }, - \ 'component_function': { - \ 'gitbranch': 'fugitive#head', - \ 'filename': 'LightlineFilename', - \ }, - \ } - -function! LightlineFilename() - let root = fnamemodify(get(b:, 'git_dir'), ':h') - let path = expand('%:p') - if path[:len(root)-1] ==# root - return path[len(root)+1:] - endif - return expand('%') -endfunction" - -" Theming -silent! colorscheme onedark -hi Normal guibg=NONE ctermbg=NONE -hi Visual term=reverse cterm=reverse guibg=NONE ctermbg=NONE diff --git a/vscode/extensions b/vscode/extensions deleted file mode 100644 index 3b4fe33..0000000 --- a/vscode/extensions +++ /dev/null @@ -1,26 +0,0 @@ -bradlc.vscode-tailwindcss -christian-kohler.npm-intellisense -christian-kohler.path-intellisense -DavidAnson.vscode-markdownlint -dbaeumer.vscode-eslint -DotJoshJohnson.xml -eamodio.gitlens -EditorConfig.EditorConfig -eg2.vscode-npm-script -Equinusocio.vsc-community-material-theme -Equinusocio.vsc-material-theme -equinusocio.vsc-material-theme-icons -esbenp.prettier-vscode -firefox-devtools.vscode-firefox-debug -golang.go -idleberg.applescript -mrmlnc.vscode-scss -ms-python.python -ms-vscode.sublime-keybindings -msjsdiag.debugger-for-chrome -Prisma.vscode-graphql -redhat.vscode-yaml -samuelcolvin.jinjahtml -stylelint.vscode-stylelint -timonwong.shellcheck -Tyriar.sort-lines