config

betoissues' dotfiles
Log | Files | Refs | Submodules | README

commit fc8336cea87061aa4bdf0355074dd81eaca75884
Author: Alberto Castillo G <me@albertocastillog.com>
Date:   Wed, 24 Jun 2020 18:44:34 -0500

Initial commit

Diffstat:
A.gitignore | 17+++++++++++++++++
A.gitmodules | 3+++
A2bwm/config.h | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AREADME.md | 0
AX11/.xinitrc | 4++++
Aaerc/.config/aerc/aerc.conf | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaerc/.config/aerc/binds.conf | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aalacritty/.config/alacritty/alacritty.yml | 602+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adunst/.config/dunst/dunstrc | 423+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adunst/.config/dunst/launch.sh | 9+++++++++
Akde-2bwm/.config/plasma-workspace/env/set_window_manager.sh | 3+++
Anewsboat/.config/newsboat/config | 30++++++++++++++++++++++++++++++
Anewsboat/.config/newsboat/urls | 16++++++++++++++++
Anvim/.config/nvim/autoload/plug.vim | 2454+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anvim/.config/nvim/colors/ThemerVim.vim | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anvim/.config/nvim/colors/base16-gruvbox-dark-hard.vim | 413+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anvim/.config/nvim/colors/contrastneed.vim | 819+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anvim/.config/nvim/init.vim | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apolybar/.config/polybar/config | 212+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apolybar/.config/polybar/gmail/.gitignore | 1+
Apolybar/.config/polybar/gmail/LICENSE | 21+++++++++++++++++++++
Apolybar/.config/polybar/gmail/README.md | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apolybar/.config/polybar/gmail/auth.py | 27+++++++++++++++++++++++++++
Apolybar/.config/polybar/gmail/client_secrets.json | 2++
Apolybar/.config/polybar/gmail/launch.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apolybar/.config/polybar/gmail/list_labels.py | 18++++++++++++++++++
Apolybar/.config/polybar/gmail/poetry.lock | 391+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apolybar/.config/polybar/gmail/preview.png | 0
Apolybar/.config/polybar/gmail/pyproject.toml | 18++++++++++++++++++
Apolybar/.config/polybar/launch.sh | 17+++++++++++++++++
Apolybar/.config/polybar/spotify/spotify_status.py | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/config | 2++
Arofi/.config/rofi/themes/gruvbox/gruvbox-common.rasi | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-dark-hard.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-dark-soft.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-dark.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-light-hard.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-light-soft.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arofi/.config/rofi/themes/gruvbox/gruvbox-light.rasi | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atmux/.config/tmux/plugins/tpm | 1+
Atmux/.config/tmux/tmux.conf | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atmux/.config/tmux/tmux_session.sh | 24++++++++++++++++++++++++
Azathura/.config/zathura/zathurarc | 4++++
Azsh/.config/zsh/.zshrc | 27+++++++++++++++++++++++++++
Azsh/.config/zsh/themes/beto_prompt.zsh-theme | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Azsh/.config/zsh/themes/beto_prompt.zsh-theme.antigen-compat | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Azsh/.fzf.bash | 13+++++++++++++
Azsh/.fzf.zsh | 13+++++++++++++
Azsh/.zprofile | 8++++++++
49 files changed, 7553 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,17 @@ +aerc/.config/aerc/accounts.conf + +newsboat/.config/newsboat/cache.db* + +nvim/.config/nvim/.netrwhist +nvim/.config/nvim/plugged/* +nvim/.config/nvim/ftplugin/* + +polybar/.config/polybar/gmail/credentials.json + +tmux/.config/tmux/plugins/tmux-sensible/ + +zsh/.config/antigen/ +zsh/.config/**/.zcompdump +zsh/.config/**/*.zwc +zsh/.config/zsh/history +zsh/.fzf/ diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tmux/.config/tmux/plugins/tpm"] + path = tmux/.config/tmux/plugins/tpm + url = https://github.com/tmux-plugins/tpm diff --git a/2bwm/config.h b/2bwm/config.h @@ -0,0 +1,233 @@ +///---User configurable stuff---/// +///---Modifiers---/// +#define MOD XCB_MOD_MASK_4 /* Super/Windows key or check xmodmap(1) with -pm defined in /usr/include/xcb/xproto.h */ +///--Speed---/// +#include <X11/XF86keysym.h> +/* Move this many pixels when moving or resizing with keyboard unless the window has hints saying otherwise. + *0)move step slow 1)move step fast + *2)mouse slow 3)mouse fast */ +static const uint16_t movements[] = {20,40,15,400}; +/* resize by line like in mcwm -- jmbi */ +static const bool resize_by_line = true; +/* the ratio used when resizing and keeping the aspect */ +static const float resize_keep_aspect_ratio= 1.03; +///---Offsets---/// +/*0)offsetx 1)offsety + *2)maxwidth 3)maxheight */ +static const uint8_t offsets[] = {0,0,0,30}; +///---Colors---/// +/*0)focuscol 1)unfocuscol + *2)fixedcol 3)unkilcol + *4)fixedunkilcol 5)outerbordercol + *6)emptycol */ +static const char *colors[] = {"#EEEEEE","#1C1B19","#7a8c5c","#ff6666","#cc9933","#111111","#000000"}; +/* if this is set to true the inner border and outer borders colors will be swapped */ +static const bool inverted_colors = false; +///---Cursor---/// +/* default position of the cursor: + * correct values are: + * TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, MIDDLE + * All these are relative to the current window. */ +#define CURSOR_POSITION MIDDLE +///---Borders---/// +/*0) Outer border size. If you put this negative it will be a square. + *1) Full borderwidth 2) Magnet border size + *3) Resize border size */ +static const uint8_t borders[] = {4,6,3,5}; +/* Windows that won't have a border. + * It uses substring comparison with what is found in the WM_NAME + * attribute of the window. You can test this using `xprop WM_NAME` + */ +#define LOOK_INTO "WM_NAME" +static const char *ignore_names[] = {"bar", "xclock", "polybar"}; +///--Menus and Programs---/// +static const char *rofiLaunch[] = { "rofi", "-show", "run", NULL }; +static const char *rofiWin[] = { "rofi", "-show", "window", NULL }; +static const char *rofiDesktop[] = { "rofi", "-show", "drun", "-show-icons", NULL }; +static const char *printGui[] = { "flameshot", "gui", NULL }; +static const char *printAll[] = { "flameshot", "full", NULL }; +static const char *terminal[] = { "alacritty", NULL }; +static const char *browser[] = { "firefox", NULL }; +static const char *toggleMute[] = { "amixer", "set", "Master", "toggle", NULL }; +static const char *volUp[] = { "amixer", "sset", "Master", "5%+", NULL }; +static const char *volDown[] = { "amixer", "sset", "Master", "5%-", NULL }; +static const char *lightUp[] = { "xbacklight", "-inc", "5", NULL }; +static const char *playNext[] = { "playerctl", "next", NULL }; +static const char *playPrev[] = { "playerctl", "previous", NULL }; +static const char *playPause[] = { "playerctl", "play-pause", NULL }; +static const char *lightDown[] = { "xbacklight", "-dec", "5", NULL }; +///--Custom foo---/// +static void halfandcentered(const Arg *arg) +{ + Arg arg2 = {.i=TWOBWM_MAXHALF_VERTICAL_LEFT}; + maxhalf(&arg2); + Arg arg3 = {.i=TWOBWM_TELEPORT_CENTER}; + teleport(&arg3); +} +///---Shortcuts---/// +/* Check /usr/include/X11/keysymdef.h for the list of all keys + * 0x000000 is for no modkey + * If you are having trouble finding the right keycode use the `xev` to get it + * For example: + * KeyRelease event, serial 40, synthetic NO, window 0x1e00001, + * root 0x98, subw 0x0, time 211120530, (128,73), root:(855,214), + * state 0x10, keycode 171 (keysym 0x1008ff17, XF86AudioNext), same_screen YES, + * XLookupString gives 0 bytes: + * XFilterEvent returns: False + * + * The keycode here is keysym 0x1008ff17, so use 0x1008ff17 + * + * + * For AZERTY keyboards XK_1...0 should be replaced by : + * DESKTOPCHANGE( XK_ampersand, 0) + * DESKTOPCHANGE( XK_eacute, 1) + * DESKTOPCHANGE( XK_quotedbl, 2) + * DESKTOPCHANGE( XK_apostrophe, 3) + * DESKTOPCHANGE( XK_parenleft, 4) + * DESKTOPCHANGE( XK_minus, 5) + * DESKTOPCHANGE( XK_egrave, 6) + * DESKTOPCHANGE( XK_underscore, 7) + * DESKTOPCHANGE( XK_ccedilla, 8) + * DESKTOPCHANGE( XK_agrave, 9)* + */ +#define DESKTOPCHANGE(K,N) \ +{ MOD , K, changeworkspace, {.i=N}}, \ +{ MOD |SHIFT, K, sendtoworkspace, {.i=N}}, +static key keys[] = { + /* modifier key function argument */ + // Focus to next/previous window + { MOD , XK_Tab, focusnext, {.i=TWOBWM_FOCUS_NEXT}}, + { MOD |SHIFT, XK_Tab, focusnext, {.i=TWOBWM_FOCUS_PREVIOUS}}, + // Kill a window + { MOD , XK_q, deletewin, {}}, + // Resize a window + { MOD |SHIFT, XK_k, resizestep, {.i=TWOBWM_RESIZE_UP}}, + { MOD |SHIFT, XK_j, resizestep, {.i=TWOBWM_RESIZE_DOWN}}, + { MOD |SHIFT, XK_l, resizestep, {.i=TWOBWM_RESIZE_RIGHT}}, + { MOD |SHIFT, XK_h, resizestep, {.i=TWOBWM_RESIZE_LEFT}}, + // Resize a window slower + { MOD |SHIFT|CONTROL,XK_k, resizestep, {.i=TWOBWM_RESIZE_UP_SLOW}}, + { MOD |SHIFT|CONTROL,XK_j, resizestep, {.i=TWOBWM_RESIZE_DOWN_SLOW}}, + { MOD |SHIFT|CONTROL,XK_l, resizestep, {.i=TWOBWM_RESIZE_RIGHT_SLOW}}, + { MOD |SHIFT|CONTROL,XK_h, resizestep, {.i=TWOBWM_RESIZE_LEFT_SLOW}}, + // Move a window + { MOD , XK_k, movestep, {.i=TWOBWM_MOVE_UP}}, + { MOD , XK_j, movestep, {.i=TWOBWM_MOVE_DOWN}}, + { MOD , XK_l, movestep, {.i=TWOBWM_MOVE_RIGHT}}, + { MOD , XK_h, movestep, {.i=TWOBWM_MOVE_LEFT}}, + // Move a window slower + { MOD |CONTROL, XK_k, movestep, {.i=TWOBWM_MOVE_UP_SLOW}}, + { MOD |CONTROL, XK_j, movestep, {.i=TWOBWM_MOVE_DOWN_SLOW}}, + { MOD |CONTROL, XK_l, movestep, {.i=TWOBWM_MOVE_RIGHT_SLOW}}, + { MOD |CONTROL, XK_h, movestep, {.i=TWOBWM_MOVE_LEFT_SLOW}}, + // Teleport the window to an area of the screen. + // Center: + { MOD , XK_g, teleport, {.i=TWOBWM_TELEPORT_CENTER}}, + // Center y: + { MOD |SHIFT, XK_g, teleport, {.i=TWOBWM_TELEPORT_CENTER_Y}}, + // Center x: + { MOD |CONTROL, XK_g, teleport, {.i=TWOBWM_TELEPORT_CENTER_X}}, + // Top left: + { MOD , XK_y, teleport, {.i=TWOBWM_TELEPORT_TOP_LEFT}}, + // Top right: + { MOD , XK_u, teleport, {.i=TWOBWM_TELEPORT_TOP_RIGHT}}, + // Bottom left: + { MOD , XK_b, teleport, {.i=TWOBWM_TELEPORT_BOTTOM_LEFT}}, + // Bottom right: + { MOD , XK_n, teleport, {.i=TWOBWM_TELEPORT_BOTTOM_RIGHT}}, + // Resize while keeping the window aspect + { MOD , XK_Home, resizestep_aspect, {.i=TWOBWM_RESIZE_KEEP_ASPECT_GROW}}, + { MOD , XK_End, resizestep_aspect, {.i=TWOBWM_RESIZE_KEEP_ASPECT_SHRINK}}, + // Maximize (ignore offset and no EWMH atom) + { MOD , XK_x, maximize, {}}, + // Full screen (disregarding offsets and adding EWMH atom) + { MOD |SHIFT , XK_x, fullscreen, {}}, + // Maximize vertically + { MOD , XK_m, maxvert_hor, {.i=TWOBWM_MAXIMIZE_VERTICALLY}}, + // Maximize horizontally + { MOD |SHIFT, XK_m, maxvert_hor, {.i=TWOBWM_MAXIMIZE_HORIZONTALLY}}, + // Maximize and move + // vertically left + { MOD |SHIFT, XK_y, maxhalf, {.i=TWOBWM_MAXHALF_VERTICAL_LEFT}}, + // vertically right + { MOD |SHIFT, XK_u, maxhalf, {.i=TWOBWM_MAXHALF_VERTICAL_RIGHT}}, + // horizontally left + { MOD |SHIFT, XK_b, maxhalf, {.i=TWOBWM_MAXHALF_HORIZONTAL_BOTTOM}}, + // horizontally right + { MOD |SHIFT, XK_n, maxhalf, {.i=TWOBWM_MAXHALF_HORIZONTAL_TOP}}, + //fold half vertically + { MOD |SHIFT|CONTROL,XK_y, maxhalf, {.i=TWOBWM_MAXHALF_FOLD_VERTICAL}}, + //fold half horizontally + { MOD |SHIFT|CONTROL,XK_b, maxhalf, {.i=TWOBWM_MAXHALF_FOLD_HORIZONTAL}}, + //unfold vertically + { MOD |SHIFT|CONTROL,XK_u, maxhalf, {.i=TWOBWM_MAXHALF_UNFOLD_VERTICAL}}, + //unfold horizontally + { MOD |SHIFT|CONTROL,XK_n, maxhalf, {.i=TWOBWM_MAXHALF_UNFOLD_HORIZONTAL}}, + // Next/Previous screen + { MOD , XK_comma, changescreen, {.i=TWOBWM_NEXT_SCREEN}}, + { MOD , XK_period, changescreen, {.i=TWOBWM_PREVIOUS_SCREEN}}, + // Raise or lower a window + { MOD , XK_r, raiseorlower, {}}, + // Next/Previous workspace + { MOD , XK_v, nextworkspace, {}}, + { MOD , XK_c, prevworkspace, {}}, + // Move to Next/Previous workspace + { MOD |SHIFT , XK_v, sendtonextworkspace,{}}, + { MOD |SHIFT , XK_c, sendtoprevworkspace,{}}, + // Iconify the window + { MOD , XK_i, hide, {}}, + // Make the window unkillable + { MOD , XK_a, unkillable, {}}, + // Make the window appear always on top + { MOD, XK_t, always_on_top, {}}, + // Make the window stay on all workspaces + { MOD , XK_f, fix, {}}, + // Move the cursor + { MOD , XK_Up, cursor_move, {.i=TWOBWM_CURSOR_UP_SLOW}}, + { MOD , XK_Down, cursor_move, {.i=TWOBWM_CURSOR_DOWN_SLOW}}, + { MOD , XK_Right, cursor_move, {.i=TWOBWM_CURSOR_RIGHT_SLOW}}, + { MOD , XK_Left, cursor_move, {.i=TWOBWM_CURSOR_LEFT_SLOW}}, + // Move the cursor faster + { MOD |SHIFT, XK_Up, cursor_move, {.i=TWOBWM_CURSOR_UP}}, + { MOD |SHIFT, XK_Down, cursor_move, {.i=TWOBWM_CURSOR_DOWN}}, + { MOD |SHIFT, XK_Right, cursor_move, {.i=TWOBWM_CURSOR_RIGHT}}, + { MOD |SHIFT, XK_Left, cursor_move, {.i=TWOBWM_CURSOR_LEFT}}, + // Start programs + { MOD , XK_w, start, {.com = rofiDesktop}}, + { MOD|SHIFT , XK_w, start, {.com = rofiWin}}, + { MOD|SHIFT , XK_o, start, {.com = rofiLaunch}}, + { MOD , XK_Return, start, {.com = terminal}}, + { MOD , XK_e, start, {.com = browser}}, + // Exit or restart 2bwm + { MOD |CONTROL, XK_q, twobwm_exit, {.i=0}}, + { MOD |CONTROL, XK_r, twobwm_restart, {.i=0}}, + { 0 , XF86XK_AudioLowerVolume, start, {.com=volDown}}, + { 0 , XF86XK_AudioRaiseVolume, start, {.com=volUp}}, + { 0 , XF86XK_AudioMute, start, {.com=toggleMute}}, + { 0 , XF86XK_AudioPlay, start, {.com=playPause}}, + { 0 , XF86XK_AudioNext, start, {.com=playNext}}, + { 0 , XF86XK_AudioPrev, start, {.com=playPrev}}, + { 0 , XF86XK_MonBrightnessUp, start, {.com=lightUp}}, + { 0 , XF86XK_MonBrightnessDown, start, {.com=lightDown}}, + // Change current workspace + DESKTOPCHANGE( XK_1, 0) + DESKTOPCHANGE( XK_2, 1) + DESKTOPCHANGE( XK_3, 2) + DESKTOPCHANGE( XK_4, 3) + DESKTOPCHANGE( XK_5, 4) + DESKTOPCHANGE( XK_6, 5) + DESKTOPCHANGE( XK_7, 6) + DESKTOPCHANGE( XK_8, 7) + DESKTOPCHANGE( XK_9, 8) + DESKTOPCHANGE( XK_0, 9) +}; +// the last argument makes it a root window only event +static Button buttons[] = { + { MOD ,XCB_BUTTON_INDEX_1, mousemotion, {.i=TWOBWM_MOVE}, false}, + { MOD ,XCB_BUTTON_INDEX_3, mousemotion, {.i=TWOBWM_RESIZE}, false}, + { 0 ,XCB_BUTTON_INDEX_3, start, {.com = rofiLaunch}, true}, + { MOD|SHIFT, XCB_BUTTON_INDEX_1, changeworkspace, {.i=0}, false}, + { MOD|SHIFT, XCB_BUTTON_INDEX_3, changeworkspace, {.i=1}, false}, + { MOD|ALT, XCB_BUTTON_INDEX_1, changescreen, {.i=1}, false}, + { MOD|ALT, XCB_BUTTON_INDEX_3, changescreen, {.i=0}, false} +}; diff --git a/README.md b/README.md diff --git a/X11/.xinitrc b/X11/.xinitrc @@ -0,0 +1,4 @@ +#!/bin/sh + +[ -f ~/.zprofile ] && . ~/.zprofile +exec startplasma-x11 diff --git a/aerc/.config/aerc/aerc.conf b/aerc/.config/aerc/aerc.conf @@ -0,0 +1,186 @@ +# +# aerc main configuration + +[ui] +# +# Describes the format for each row in a mailbox view. This field is compatible +# with mutt's printf-like syntax. +# +# Default: %D %-17.17n %Z %s +index-format=%D %-17.17n %Z %s + +# +# See time.Time#Format at https://godoc.org/time#Time.Format +# +# Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time) +timestamp-format=2006-01-02 03:04 PM + +# +# Width of the sidebar, including the border. +# +# Default: 20 +sidebar-width=20 + +# +# Message to display when viewing an empty folder. +# +# Default: (no messages) +empty-message=(no messages) + +# Message to display when no folders exists or are all filtered +# +# Default: (no folders) +empty-dirlist=(no folders) + +# Enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel +# +# Default: false +mouse-enabled=false + +# +# Ring the bell when new messages are received +# +# Default: true +new-message-bell=true + +# Marker to show before a pinned tab's name. +# +# Default: ` +pinned-tab-marker='`' + +# Describes the format string to use for the directory list +# +# Default: %n %>r +dirlist-format=%n %>r + +# List of space-separated criteria to sort the messages by, see *sort* +# command in *aerc*(1) for reference. Prefixing a criterion with "-r " +# reverses that criterion. +# +# Example: "from -r date" +# +# Default: "" +sort= + +# Moves to next message when the current message is deleted +# +# Default: true +next-message-on-delete=true + +[viewer] +# +# Specifies the pager to use when displaying emails. Note that some filters +# may add ANSI codes to add color to rendered emails, so you may want to use a +# pager which supports ANSI codes. +# +# Default: less -R +pager=less -R + +# +# If an email offers several versions (multipart), you can configure which +# mimetype to prefer. For example, this can be used to prefer plaintext over +# html emails. +# +# Default: text/plain,text/html +alternatives=text/plain,text/html + +# +# Default setting to determine whether to show full headers or only parsed +# ones in message viewer. +# +# Default: false +show-headers=false + +# +# Layout of headers when viewing a message. To display multiple headers in the +# same row, separate them with a pipe, e.g. "From|To". Rows will be hidden if +# none of their specified headers are present in the message. +# +# Default: From|To,Cc|Bcc,Date,Subject +header-layout=From|To,Cc|Bcc,Date,Subject + +# Whether to always show the mimetype of an email, even when it is just a single part +# +# Default: false +always-show-mime=false + +# How long to wait after the last input before auto-completion is triggered. +# +# Default: 250ms +completion-delay=250ms + +# +# Global switch for completion popovers +# +# Default: true +completion-popovers=true + +[compose] +# +# Specifies the command to run the editor with. It will be shown in an embedded +# terminal, though it may also launch a graphical window if the environment +# supports it. Defaults to $EDITOR, or vi. +editor=nvim + +# +# Default header fields to display when composing a message. To display +# multiple headers in the same row, separate them with a pipe, e.g. "To|From". +# +# Default: To|From,Subject +header-layout=To|From,CC|BCC,Subject + +# +# Specifies the command to be used to tab-complete email addresses. Any +# occurrence of "%s" in the address-book-cmd will be replaced with what the +# user has typed so far. +# +# The command must output the completions to standard output, one completion +# per line. Each line must be tab-delimited, with an email address occurring as +# the first field. Only the email address field is required. The second field, +# if present, will be treated as the contact name. Additional fields are +# ignored. +address-book-cmd=khard email --remove-first-line --parsable '%s' + +[filters] +# +# Filters allow you to pipe an email body through a shell command to render +# certain emails differently, e.g. highlighting them with ANSI escape codes. +# +# The first filter which matches the email's mimetype will be used, so order +# them from most to least specific. +# +# You can also match on non-mimetypes, by prefixing with the header to match +# against (non-case-sensitive) and a comma, e.g. subject,text will match a +# subject which contains "text". Use header,~regex to match against a regex. +subject,~^\[PATCH=awk -f /usr/share/aerc/filters/hldiff +text/html=/usr/share/aerc/filters/html +text/*=awk -f /usr/share/aerc/filters/plaintext +#image/*=catimg -w $(tput cols) - + +[triggers] +# +# Triggers specify commands to execute when certain events occur. +# +# Example: +new-email=exec notify-send "New email from %n" "%s" + + +[templates] +# Templates are used to populate email bodies automatically. +# + +# The directories where the templates are stored. It takes a colon-separated +# list of directories. +# +# default: /usr/share/aerc/templates/ +template-dirs=/usr/share/aerc/templates/ + +# The template to be used for quoted replies. +# +# default: quoted_reply +quoted-reply=quoted_reply + +# The template to be used for forward as body. +# +# default: forward_as_body +forwards=forward_as_body diff --git a/aerc/.config/aerc/binds.conf b/aerc/.config/aerc/binds.conf @@ -0,0 +1,105 @@ +# Binds are of the form <key sequence> = <command to run> +# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>" +# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit +<C-p> = :prev-tab<Enter> +<C-n> = :next-tab<Enter> +<C-t> = :term<Enter> + +[messages] +q = :quit<Enter> + +j = :next<Enter> +<Down> = :next<Enter> +<C-d> = :next 50%<Enter> +<C-f> = :next 100%<Enter> +<PgDn> = :next -s 100%<Enter> + +k = :prev<Enter> +<Up> = :prev<Enter> +<C-u> = :prev 50%<Enter> +<C-b> = :prev 100%<Enter> +<PgUp> = :prev -s 100%<Enter> +g = :select 0<Enter> +G = :select -1<Enter> + +J = :next-folder<Enter> +K = :prev-folder<Enter> + +v = :mark -t<Enter> +V = :mark -v<Enter> + +<Enter> = :view<Enter> +d = :prompt 'Really delete this message?' 'delete-message'<Enter> +D = :delete<Enter> +A = :archive flat<Enter> +m = :move<space> +M = :read -t<Enter> + +C = :compose<Enter> + +rr = :reply -a<Enter> +rq = :reply -aq<Enter> +Rr = :reply<Enter> +Rq = :reply -q<Enter> + +c = :cf<space> +$ = :term<space> +! = :term<space> +| = :pipe<space> + +/ = :search<space> +\ = :filter<space> +n = :next-result<Enter> +N = :prev-result<Enter> + +[view] +q = :close<Enter> +| = :pipe<space> +D = :delete<Enter> +S = :save<space> +A = :archive flat<Enter> + +f = :forward<Enter> +rr = :reply -a<Enter> +rq = :reply -aq<Enter> +Rr = :reply<Enter> +Rq = :reply -q<Enter> + +H = :toggle-headers<Enter> +<C-k> = :prev-part<Enter> +<C-j> = :next-part<Enter> +J = :next<Enter> +K = :prev<Enter> + +[compose] +# Keybindings used when the embedded terminal is not selected in the compose +# view +$ex = <C-x> +<C-k> = :prev-field<Enter> +<C-j> = :next-field<Enter> +<tab> = :next-field<Enter> + +[compose::editor] +# Keybindings used when the embedded terminal is selected in the compose view +$noinherit = true +$ex = <C-x> +<C-k> = :prev-field<Enter> +<C-j> = :next-field<Enter> +<C-p> = :prev-tab<Enter> +<C-n> = :next-tab<Enter> + +[compose::review] +# Keybindings used when reviewing a message to be sent +y = :send<Enter> +n = :abort<Enter> +p = :postpone<Enter> +q = :abort<Enter> +e = :edit<Enter> +a = :attach<space> + +[terminal] +$noinherit = true +$ex = <C-x> + +<C-p> = :prev-tab<Enter> +<C-n> = :next-tab<Enter> diff --git a/alacritty/.config/alacritty/alacritty.yml b/alacritty/.config/alacritty/alacritty.yml @@ -0,0 +1,602 @@ +# Configuration for Alacritty, the GPU enhanced terminal emulator. + +# Any items in the `env` entry below will be added as +# environment variables. Some entries may override variables +# set by alacritty itself. +#env: + # TERM variable + # + # This value is used to set the `$TERM` environment variable for + # each instance of Alacritty. If it is not present, alacritty will + # check the local terminfo database and use `alacritty` if it is + # available, otherwise `xterm-256color` is used. + #TERM: xterm-256color + +window: + # Window dimensions (changes require restart) + # + # Specified in number of columns/lines, not pixels. + # If both are `0`, this setting is ignored. + dimensions: + columns: 0 + lines: 0 + + # Window position (changes require restart) + # + # Specified in number of pixels. + # If the position is not set, the window manager will handle the placement. + #position: + # x: 0 + # y: 0 + + # Window padding (changes require restart) + # + # Blank space added around the window in pixels. This padding is scaled + # by DPI and the specified value is always added at both opposing sides. + padding: + x: 2 + y: 2 + + # Spread additional padding evenly around the terminal content. + dynamic_padding: false + + # Window decorations + # + # Values for `decorations`: + # - full: Borders and title bar + # - none: Neither borders nor title bar + # + # Values for `decorations` (macOS only): + # - transparent: Title bar, transparent background and title bar buttons + # - buttonless: Title bar, transparent background, but no title bar buttons + decorations: none + + # When true, alacritty starts maximized. + #start_maximized: false + +scrolling: + # Maximum number of lines in the scrollback buffer. + # Specifying '0' will disable scrolling. + history: 10000 + + # Number of lines the viewport will move for every line scrolled when + # scrollback is enabled (history > 0). + multiplier: 3 + +# Font configuration (changes require restart) +font: + # Normal (roman) font face + normal: + # Font family + # + # Default: + # - (macOS) Menlo + # - (Linux) monospace + # - (Windows) Consolas + family: Fira Mono + + # The `style` can be specified to pick a specific face. + style: Regular + + # Bold font face + #bold: + # Font family + # + # If the bold family is not specified, it will fall back to the + # value specified for the normal font. + #family: monospace + + # The `style` can be specified to pick a specific face. + #style: Bold + + # Italic font face + #italic: + # Font family + # + # If the italic family is not specified, it will fall back to the + # value specified for the normal font. + #family: monospace + + # The `style` can be specified to pick a specific face. + #style: Italic + + # Point size + size: 8.0 + + # Offset is the extra space around each character. `offset.y` can be thought of + # as modifying the line spacing, and `offset.x` as modifying the letter spacing. + offset: + x: 0 + y: 0 + + # Glyph offset determines the locations of the glyphs within their cells with + # the default being at the bottom. Increasing `x` moves the glyph to the right, + # increasing `y` moves the glyph upwards. + glyph_offset: + x: 0 + y: 0 + + # Thin stroke font rendering (macOS only) + # + # Thin strokes are suitable for retina displays, but for non-retina screens + # it is recommended to set `use_thin_strokes` to `false` + # + # macOS >= 10.14.x: + # + # If the font quality on non-retina display looks bad then set + # `use_thin_strokes` to `true` and enable font smoothing by running the + # following command: + # `defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO` + # + # This is a global setting and will require a log out or restart to take + # effect. + use_thin_strokes: true + +# Display the time it takes to redraw each frame. +#render_timer: false + +# Keep the log file after quitting Alacritty. +#persistent_logging: false + +# If `true`, bold text is drawn using the bright color variants. +draw_bold_text_with_bright_colors: true + +# Colors (Gruvbox dark) +colors: + # Default colors + primary: + # hard contrast: background = '0x1d2021' + background: '0x1d2021' + # soft contrast: background = '0x32302f' + foreground: '0xebdbb2' + + # Normal colors + normal: + black: '0x282828' + red: '0xcc241d' + green: '0x98971a' + yellow: '0xd79921' + blue: '0x458588' + magenta: '0xb16286' + cyan: '0x689d6a' + white: '0xa89984' + + # Bright colors + bright: + black: '0x928374' + red: '0xfb4934' + green: '0xb8bb26' + yellow: '0xfabd2f' + blue: '0x83a598' + magenta: '0xd3869b' + cyan: '0x8ec07c' + white: '0xebdbb2' + # Default colors + #primary: + #background: '0x000000' + #foreground: '0xeaeaea' + + # Bright and dim foreground colors + # + # The dimmed foreground color is calculated automatically if it is not present. + # If the bright foreground color is not set, or `draw_bold_text_with_bright_colors` + # is `false`, the normal foreground color will be used. + #dim_foreground: '0x9a9a9a' + #bright_foreground: '0xffffff' + + # Cursor colors + # + # Colors which should be used to draw the terminal cursor. If these are unset, + # the cursor color will be the inverse of the cell color. + #cursor: + # text: '0x000000' + # cursor: '0xffffff' + + # Selection colors + # + # Colors which should be used to draw the selection area. If selection + # background is unset, selection color will be the inverse of the cell colors. + # If only text is unset the cell text color will remain the same. + #selection: + # text: '0xeaeaea' + # background: '0x404040' + + # Normal colors + # normal: + # black: '0x000000' + # red: '0xd54e53' + # green: '0xb9ca4a' + # yellow: '0xe6c547' + # blue: '0x7aa6da' + # magenta: '0xc397d8' + # cyan: '0x70c0ba' + # white: '0xeaeaea' + + # # Bright colors + # bright: + # black: '0x666666' + # red: '0xff3334' + # green: '0x9ec400' + # yellow: '0xe7c547' + # blue: '0x7aa6da' + # magenta: '0xb77ee0' + # cyan: '0x54ced6' + # white: '0xffffff' + + # Dim colors + # + # If the dim colors are not set, they will be calculated automatically based + # on the `normal` colors. + #dim: + # black: '0x000000' + # red: '0x8c3336' + # green: '0x7a8530' + # yellow: '0x97822e' + # blue: '0x506d8f' + # magenta: '0x80638e' + # cyan: '0x497e7a' + # white: '0x9a9a9a' + + # Indexed Colors + # + # The indexed colors include all colors from 16 to 256. + # When these are not set, they're filled with sensible defaults. + # + # Example: + # `- { index: 16, color: '0xff00ff' }` + # + indexed_colors: [] + +# Visual Bell +# +# Any time the BEL code is received, Alacritty "rings" the visual bell. Once +# rung, the terminal background will be set to white and transition back to the +# default background color. You can control the rate of this transition by +# setting the `duration` property (represented in milliseconds). You can also +# configure the transition function by setting the `animation` property. +# +# Values for `animation`: +# - Ease +# - EaseOut +# - EaseOutSine +# - EaseOutQuad +# - EaseOutCubic +# - EaseOutQuart +# - EaseOutQuint +# - EaseOutExpo +# - EaseOutCirc +# - Linear +# +# Specifying a `duration` of `0` will disable the visual bell. +visual_bell: + animation: EaseOutExpo + duration: 0 + color: '0xffffff' + +# Background opacity +# +# Window opacity as a floating point number from `0.0` to `1.0`. +# The value `0.0` is completely transparent and `1.0` is opaque. +background_opacity: 1.0 + +# Mouse bindings +# +# Available fields: +# - mouse +# - action +# - mods (optional) +# +# Values for `mouse`: +# - Middle +# - Left +# - Right +# - Numeric identifier such as `5` +# +# All available `mods` and `action` values are documented in the key binding +# section. +mouse_bindings: + - { mouse: Middle, action: PasteSelection } + +mouse: + # Click settings + # + # The `double_click` and `triple_click` settings control the time + # alacritty should wait for accepting multiple clicks as one double + # or triple click. + double_click: { threshold: 300 } + triple_click: { threshold: 300 } + + # If this is `true`, the cursor is temporarily hidden when typing. + hide_when_typing: false + + url: + # URL launcher + # + # This program is executed when clicking on a text which is recognized as a URL. + # The URL is always added to the command as the last parameter. + # + # When set to `None`, URL launching will be disabled completely. + # + # Default: + # - (macOS) open + # - (Linux) xdg-open + # - (Windows) explorer + #launcher: + # program: xdg-open + # args: [] + + # URL modifiers + # + # These are the modifiers that need to be held down for opening URLs when clicking + # on them. The available modifiers are documented in the key binding section. + modifiers: None + +selection: + semantic_escape_chars: ",│`|:\"' ()[]{}<>" + + # When set to `true`, selected text will be copied to the primary clipboard. + save_to_clipboard: false + +# Allow terminal applications to change Alacritty's window title. +dynamic_title: true + +cursor: + # Cursor style + # + # Values for `style`: + # - ▇ Block + # - _ Underline + # - | Beam + style: Underline + + # If this is `true`, the cursor will be rendered as a hollow box when the + # window is not focused. + unfocused_hollow: true + +# Live config reload (changes require restart) +live_config_reload: true + +# Shell +# +# You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`. +# Entries in `shell.args` are passed unmodified as arguments to the shell. +# +# Default: +# - (Linux/macOS) /bin/bash --login +# - (Windows) powershell +#shell: +# program: /bin/bash +# args: +# - --login + +# Windows 10 ConPTY backend (Windows only) +# +# This will enable better color support and may resolve other issues, +# however this API and its implementation is still young and so is +# disabled by default, as stability may not be as good as the winpty +# backend. +# +# Alacritty will fall back to the WinPTY automatically if the ConPTY +# backend cannot be initialized. +enable_experimental_conpty_backend: false + +# Send ESC (\x1b) before characters when alt is pressed. +alt_send_esc: true + +# Key bindings +# +# Key bindings are specified as a list of objects. Each binding will specify a +# key and modifiers required to trigger it, terminal modes where the binding is +# applicable, and what should be done when the key binding fires. It can either +# send a byte sequence to the running application (`chars`), execute a +# predefined action (`action`) or fork and execute a specified command plus +# arguments (`command`). +# +# Bindings are always filled by default, but will be replaced when a new binding +# with the same triggers is defined. To unset a default binding, it can be +# mapped to the `None` action. +# +# Example: +# `- { key: V, mods: Control|Shift, action: Paste }` +# +# Available fields: +# - key +# - mods (optional) +# - chars | action | command (exactly one required) +# - mode (optional) +# +# Values for `key`: +# - `A` -> `Z` +# - `F1` -> `F12` +# - `Key1` -> `Key0` +# +# A full list with available key codes can be found here: +# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants +# +# Instead of using the name of the keys, the `key` field also supports using +# the scancode of the desired key. Scancodes have to be specified as a +# decimal number. +# This command will allow you to display the hex scancodes for certain keys: +# `showkey --scancodes` +# +# Values for `mods`: +# - Command +# - Control +# - Super +# - Shift +# - Alt +# +# Multiple `mods` can be combined using `|` like this: `mods: Control|Shift`. +# Whitespace and capitalization is relevant and must match the example. +# +# Values for `chars`: +# The `chars` field writes the specified string to the terminal. This makes +# it possible to pass escape sequences. +# To find escape codes for bindings like `PageUp` ("\x1b[5~"), you can run +# the command `showkey -a` outside of tmux. +# Note that applications use terminfo to map escape sequences back to +# keys. It is therefore required to update the terminfo when +# changing an escape sequence. +# +# Values for `action`: +# - Paste +# - PasteSelection +# - Copy +# - IncreaseFontSize +# - DecreaseFontSize +# - ResetFontSize +# - ScrollPageUp +# - ScrollPageDown +# - ScrollLineUp +# - ScrollLineDown +# - ScrollToTop +# - ScrollToBottom +# - ClearHistory +# - Hide +# - Quit +# - ClearLogNotice +# - SpawnNewInstance +# - None +# +# Values for `command`: +# The `command` field must be a map containing a `program` string and +# an `args` array of command line parameter strings. +# +# Example: +# `command: { program: "alacritty", args: ["-e", "vttest"] }` +# +# Values for `mode`: +# - ~AppCursor +# - AppCursor +# - ~AppKeypad +# - AppKeypad +key_bindings: + # (Windows/Linux only) + #- { key: V, mods: Control|Shift, action: Paste } + #- { key: C, mods: Control|Shift, action: Copy } + #- { key: Insert, mods: Shift, action: PasteSelection } + #- { key: Key0, mods: Control, action: ResetFontSize } + #- { key: Equals, mods: Control, action: IncreaseFontSize } + #- { key: Add, mods: Control, action: IncreaseFontSize } + #- { key: Subtract, mods: Control, action: DecreaseFontSize } + #- { key: Minus, mods: Control, action: DecreaseFontSize } + + # (macOS only) + #- { key: Key0, mods: Command, action: ResetFontSize } + #- { key: Equals, mods: Command, action: IncreaseFontSize } + #- { key: Add, mods: Command, action: IncreaseFontSize } + #- { key: Minus, mods: Command, action: DecreaseFontSize } + #- { key: K, mods: Command, action: ClearHistory } + #- { key: K, mods: Command, chars: "\x0c" } + #- { key: V, mods: Command, action: Paste } + #- { key: C, mods: Command, action: Copy } + #- { key: H, mods: Command, action: Hide } + #- { key: Q, mods: Command, action: Quit } + #- { key: W, mods: Command, action: Quit } + + - { key: Paste, action: Paste } + - { key: Copy, action: Copy } + - { key: L, mods: Control, action: ClearLogNotice } + - { key: L, mods: Control, chars: "\x0c" } + - { key: Home, mods: Alt, chars: "\x1b[1;3H" } + - { key: Home, chars: "\x1bOH", mode: AppCursor } + - { key: Home, chars: "\x1b[H", mode: ~AppCursor } + - { key: End, mods: Alt, chars: "\x1b[1;3F" } + - { key: End, chars: "\x1bOF", mode: AppCursor } + - { key: End, chars: "\x1b[F", mode: ~AppCursor } + - { key: PageUp, mods: Shift, action: ScrollPageUp, mode: ~Alt } + - { key: PageUp, mods: Shift, chars: "\x1b[5;2~", mode: Alt } + - { key: PageUp, mods: Control, chars: "\x1b[5;5~" } + - { key: PageUp, mods: Alt, chars: "\x1b[5;3~" } + - { key: PageUp, chars: "\x1b[5~" } + - { key: PageDown, mods: Shift, action: ScrollPageDown, mode: ~Alt } + - { key: PageDown, mods: Shift, chars: "\x1b[6;2~", mode: Alt } + - { key: PageDown, mods: Control, chars: "\x1b[6;5~" } + - { key: PageDown, mods: Alt, chars: "\x1b[6;3~" } + - { key: PageDown, chars: "\x1b[6~" } + - { key: Tab, mods: Shift, chars: "\x1b[Z" } + - { key: Back, chars: "\x7f" } + - { key: Back, mods: Alt, chars: "\x1b\x7f" } + - { key: Insert, chars: "\x1b[2~" } + - { key: Delete, chars: "\x1b[3~" } + - { key: Left, mods: Shift, chars: "\x1b[1;2D" } + - { key: Left, mods: Control, chars: "\x1b[1;5D" } + - { key: Left, mods: Alt, chars: "\x1b[1;3D" } + - { key: Left, chars: "\x1b[D", mode: ~AppCursor } + - { key: Left, chars: "\x1bOD", mode: AppCursor } + - { key: Right, mods: Shift, chars: "\x1b[1;2C" } + - { key: Right, mods: Control, chars: "\x1b[1;5C" } + - { key: Right, mods: Alt, chars: "\x1b[1;3C" } + - { key: Right, chars: "\x1b[C", mode: ~AppCursor } + - { key: Right, chars: "\x1bOC", mode: AppCursor } + - { key: Up, mods: Shift, chars: "\x1b[1;2A" } + - { key: Up, mods: Control, chars: "\x1b[1;5A" } + - { key: Up, mods: Alt, chars: "\x1b[1;3A" } + - { key: Up, chars: "\x1b[A", mode: ~AppCursor } + - { key: Up, chars: "\x1bOA", mode: AppCursor } + - { key: Down, mods: Shift, chars: "\x1b[1;2B" } + - { key: Down, mods: Control, chars: "\x1b[1;5B" } + - { key: Down, mods: Alt, chars: "\x1b[1;3B" } + - { key: Down, chars: "\x1b[B", mode: ~AppCursor } + - { key: Down, chars: "\x1bOB", mode: AppCursor } + - { key: F1, chars: "\x1bOP" } + - { key: F2, chars: "\x1bOQ" } + - { key: F3, chars: "\x1bOR" } + - { key: F4, chars: "\x1bOS" } + - { key: F5, chars: "\x1b[15~" } + - { key: F6, chars: "\x1b[17~" } + - { key: F7, chars: "\x1b[18~" } + - { key: F8, chars: "\x1b[19~" } + - { key: F9, chars: "\x1b[20~" } + - { key: F10, chars: "\x1b[21~" } + - { key: F11, chars: "\x1b[23~" } + - { key: F12, chars: "\x1b[24~" } + - { key: F1, mods: Shift, chars: "\x1b[1;2P" } + - { key: F2, mods: Shift, chars: "\x1b[1;2Q" } + - { key: F3, mods: Shift, chars: "\x1b[1;2R" } + - { key: F4, mods: Shift, chars: "\x1b[1;2S" } + - { key: F5, mods: Shift, chars: "\x1b[15;2~" } + - { key: F6, mods: Shift, chars: "\x1b[17;2~" } + - { key: F7, mods: Shift, chars: "\x1b[18;2~" } + - { key: F8, mods: Shift, chars: "\x1b[19;2~" } + - { key: F9, mods: Shift, chars: "\x1b[20;2~" } + - { key: F10, mods: Shift, chars: "\x1b[21;2~" } + - { key: F11, mods: Shift, chars: "\x1b[23;2~" } + - { key: F12, mods: Shift, chars: "\x1b[24;2~" } + - { key: F1, mods: Control, chars: "\x1b[1;5P" } + - { key: F2, mods: Control, chars: "\x1b[1;5Q" } + - { key: F3, mods: Control, chars: "\x1b[1;5R" } + - { key: F4, mods: Control, chars: "\x1b[1;5S" } + - { key: F5, mods: Control, chars: "\x1b[15;5~" } + - { key: F6, mods: Control, chars: "\x1b[17;5~" } + - { key: F7, mods: Control, chars: "\x1b[18;5~" } + - { key: F8, mods: Control, chars: "\x1b[19;5~" } + - { key: F9, mods: Control, chars: "\x1b[20;5~" } + - { key: F10, mods: Control, chars: "\x1b[21;5~" } + - { key: F11, mods: Control, chars: "\x1b[23;5~" } + - { key: F12, mods: Control, chars: "\x1b[24;5~" } + - { key: F1, mods: Alt, chars: "\x1b[1;6P" } + - { key: F2, mods: Alt, chars: "\x1b[1;6Q" } + - { key: F3, mods: Alt, chars: "\x1b[1;6R" } + - { key: F4, mods: Alt, chars: "\x1b[1;6S" } + - { key: F5, mods: Alt, chars: "\x1b[15;6~" } + - { key: F6, mods: Alt, chars: "\x1b[17;6~" } + - { key: F7, mods: Alt, chars: "\x1b[18;6~" } + - { key: F8, mods: Alt, chars: "\x1b[19;6~" } + - { key: F9, mods: Alt, chars: "\x1b[20;6~" } + - { key: F10, mods: Alt, chars: "\x1b[21;6~" } + - { key: F11, mods: Alt, chars: "\x1b[23;6~" } + - { key: F12, mods: Alt, chars: "\x1b[24;6~" } + - { key: F1, mods: Super, chars: "\x1b[1;3P" } + - { key: F2, mods: Super, chars: "\x1b[1;3Q" } + - { key: F3, mods: Super, chars: "\x1b[1;3R" } + - { key: F4, mods: Super, chars: "\x1b[1;3S" } + - { key: F5, mods: Super, chars: "\x1b[15;3~" } + - { key: F6, mods: Super, chars: "\x1b[17;3~" } + - { key: F7, mods: Super, chars: "\x1b[18;3~" } + - { key: F8, mods: Super, chars: "\x1b[19;3~" } + - { key: F9, mods: Super, chars: "\x1b[20;3~" } + - { key: F10, mods: Super, chars: "\x1b[21;3~" } + - { key: F11, mods: Super, chars: "\x1b[23;3~" } + - { key: F12, mods: Super, chars: "\x1b[24;3~" } + - { key: NumpadEnter, chars: "\n" } diff --git a/dunst/.config/dunst/dunstrc b/dunst/.config/dunst/dunstrc @@ -0,0 +1,423 @@ +[global] + ### Display ### + + # Which monitor should the notifications be displayed on. + monitor = 0 + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a window manager that exports the + # _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern window managers. + # + # If this option is set to mouse or keyboard, the monitor option + # will be ignored. + follow = mouse + + # The geometry of the window: + # [{width}]x{height}[+/-{x}+/-{y}] + # The geometry of the message window. + # The height is measured in number of notifications everything else + # in pixels. If the width is omitted but the height is given + # ("-geometry x2"), the message window expands over the whole screen + # (dmenu-like). If width is 0, the window expands to the longest + # message displayed. A positive x is measured from the left, a + # negative from the right side of the screen. Y is measured from + # the top and down respectively. + # The width can be negative. In this case the actual width is the + # screen width minus the width defined in within the geometry option. + geometry = "350x5-30-60" + + # Show how many messages are currently hidden (because of geometry). + indicate_hidden = yes + + # Shrink window if it's smaller than the width. Will be ignored if + # width is 0. + shrink = no + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing window manager is + # present (e.g. xcompmgr, compiz, etc.). + transparency = 0 + + # The height of the entire notification. If the height is smaller + # than the font height and padding combined, it will be raised + # to the font height and padding. + notification_height = 0 + + # Draw a line of "separator_height" pixel height between two + # notifications. + # Set to 0 to disable. + separator_height = 2 + + # Padding between text and separator. + padding = 8 + + # Horizontal padding. + horizontal_padding = 8 + + # Defines width in pixels of frame around the notification window. + # Set to 0 to disable. + frame_width = 3 + + # Defines color of the frame around the notification window. + frame_color = "#ebdbb2" + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + # Don't remove messages, if the user is idle (no mouse or keyboard input) + # for longer than idle_threshold seconds. + # Set to 0 to disable. + # A client can set the 'transient' hint to bypass this. See the rules + # section for how to disable this if necessary + idle_threshold = 120 + + ### Text ### + + font = Fira Code 12 + + # The spacing between lines. If the height is smaller than the + # font height, it will get raised to the font height. + line_height = 0 + + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # <b>bold</b> + # <i>italic</i> + # <s>strikethrough</s> + # <u>underline</u> + # + # For a complete reference see + # <https://developer.gnome.org/pango/stable/pango-Markup.html>. + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "<b>%s</b>\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # Vertical alignment of message text and icon. + # Possible values are "top", "center" and "bottom". + vertical_alignment = center + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60 + + # Split notifications into multiple lines if they don't fit into + # geometry. + word_wrap = yes + + # When word_wrap is set to no, specify where to make an ellipsis in long lines. + # Possible values are "start", "middle" and "end". + ellipsize = middle + + # Ignore newlines '\n' in notifications. + ignore_newline = no + + # Stack together notifications with the same content + stack_duplicates = true + + # Hide the count of stacked notifications with the same content + hide_duplicate_count = false + + # Display indicators for URLs (U) and actions (A). + show_indicators = yes + + ### Icons ### + + # Align icons left/right/off + icon_position = left + + # Scale small icons up to this size, set to 0 to disable. Helpful + # for e.g. small files or high-dpi screens. In case of conflict, + # max_icon_size takes precedence over this. + min_icon_size = 0 + + # Scale larger icons down to this size, set to 0 to disable + max_icon_size = 32 + + # Paths to default icons. + icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ + + ### History ### + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = yes + + # Maximum amount of notifications kept in history + history_length = 20 + + ### Misc/Advanced ### + + # dmenu path. + dmenu = /usr/bin/rofi -dmenu -p dunst: + + # Browser for opening urls in context menu. + browser = /usr/bin/firefox -new-tab + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + # Define the title of the windows spawned by dunst + title = Dunst + + # Define the class of the windows spawned by dunst + class = Dunst + + # Print a notification on startup. + # This is mainly for error detection, since dbus (re-)starts dunst + # automatically after a crash. + startup_notification = false + + # Manage dunst's desire for talking + # Can be one of the following values: + # crit: Critical features. Dunst aborts + # warn: Only non-fatal warnings + # mesg: Important Messages + # info: all unimportant stuff + # debug: all less than unimportant stuff + verbosity = mesg + + # Define the corner radius of the notification window + # in pixel size. If the radius is 0, you have no rounded + # corners. + # The radius will be automatically lowered if it exceeds half of the + # notification height to avoid clipping text and/or icons. + corner_radius = 0 + + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + + ### mouse + + # Defines action of mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: If the notification has exactly one action, or one is marked as default, + # invoke it. If there are multiple and no default, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + mouse_left_click = close_current + mouse_middle_click = do_action + mouse_right_click = close_all + +# Experimental features that may or may not work correctly. Do not expect them +# to have a consistent behaviour across releases. +[experimental] + # Calculate the dpi to use on a per-monitor basis. + # If this setting is enabled the Xft.dpi value will be ignored and instead + # dunst will attempt to calculate an appropriate dpi value for each monitor + # using the resolution and physical size. This might be useful in setups + # where there are multiple screens with very different dpi values. + per_monitor_dpi = false + +[shortcuts] + + # Shortcuts are specified as [modifier+][modifier+]...key + # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", + # "mod3" and "mod4" (windows-key). + # Xev might be helpful to find names for keys. + + # Close notification. + close = ctrl+space + + # Close all notifications. + close_all = ctrl+shift+space + + # Redisplay last message(s). + # On the US keyboard layout "grave" is normally above TAB and left + # of "1". Make sure this key actually exists on your keyboard layout, + # e.g. check output of 'xmodmap -pke' + # history = ctrl+grave + + # Context menu. + context = ctrl+shift+period + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + background = "#1d2021" + foreground = "#ebdbb2" + timeout = 10 + # Icon for notifications with low urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_normal] + background = "#1d2021" + foreground = "#ebdbb2" + timeout = 10 + # Icon for notifications with normal urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_critical] + background = "#1d2021" + foreground = "#ebdbb2" + frame_color = "#cc241d" + timeout = 0 + # Icon for notifications with critical urgency, uncomment to enable + #icon = /path/to/icon + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# +# Messages can be matched by +# appname (discouraged, see desktop_entry) +# body +# category +# desktop_entry +# icon +# match_transient +# msg_urgency +# stack_tag +# summary +# +# and you can override the +# background +# foreground +# format +# frame_color +# fullscreen +# new_icon +# set_stack_tag +# set_transient +# timeout +# urgency +# +# Shell-like globbing will get expanded. +# +# Instead of the appname filter, it's recommended to use the desktop_entry filter. +# GLib based applications export their desktop-entry name. In comparison to the appname, +# the desktop-entry won't get localized. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: if you don't want a notification to be displayed, set the format +# to "". +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +# Disable the transient hint so that idle_threshold cannot be bypassed from the +# client +#[transient_disable] +# match_transient = yes +# set_transient = no +# +# Make the handling of transient notifications more strict by making them not +# be placed in history. +#[transient_history_ignore] +# match_transient = yes +# history_ignore = yes + +# fullscreen values +# show: show the notifications, regardless if there is a fullscreen window opened +# delay: displays the new notification, if there is no fullscreen window active +# If the notification is already drawn, it won't get undrawn. +# pushback: same as delay, but when switching into fullscreen, the notification will get +# withdrawn from screen again and will get delayed like a new notification +#[fullscreen_delay_everything] +# fullscreen = delay +#[fullscreen_show_critical] +# msg_urgency = critical +# fullscreen = show + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# format = "" + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +#[stack-volumes] +# appname = "some_volume_notifiers" +# set_stack_tag = "volume" +# +# vim: ft=cfg diff --git a/dunst/.config/dunst/launch.sh b/dunst/.config/dunst/launch.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +killall -q dunst + +# Wait until the processes have been shut down +while pgrep -u $UID -x dunst >/dev/null; do sleep 1; done + +feh --bg-scale ~/img/redfox.jpg +dunst -config $HOME/.config/dunst/dunstrc diff --git a/kde-2bwm/.config/plasma-workspace/env/set_window_manager.sh b/kde-2bwm/.config/plasma-workspace/env/set_window_manager.sh @@ -0,0 +1,3 @@ +export AWT_TOOLKIT=MToolkit +export _JAVA_AWT_WM_NONREPARENTING=1 +export KDEWM=/usr/local/bin/2bwm diff --git a/newsboat/.config/newsboat/config b/newsboat/.config/newsboat/config @@ -0,0 +1,30 @@ +show-keymap-hint false +swap-title-and-hints false +browser firefox %u +external-url-viewer "/usr/bin/urlview" +pager internal +html-renderer internal +save-path ~/doc/articles +text-width 72 +show-read-feeds no + +bind-key j next +bind-key k prev +bind-key J next-feed +bind-key K prev-feed +bind-key j down article +bind-key k up article +bind-key J next article +bind-key K prev article + +macro v set browser "mpv %u"; open-in-browser ; set browser "firefox %u" +macro y set browser "(echo %u | xclip -i ) && (echo %u | xclip -i -sel clip )"; open-in-browser ; set browser "firefox %u" + +color background white default +color listnormal white default +color listfocus black color9 standout +color info black color9 standout +color listfocus_unread black color9 standout +color listnormal_unread white default + +feed-sort-order date diff --git a/newsboat/.config/newsboat/urls b/newsboat/.config/newsboat/urls @@ -0,0 +1,16 @@ +https://www.uninformativ.de/blog/feeds/en.atom +https://venam.nixers.net/blog/feed.xml +https://drewdevault.com/feed.xml "Drew" +http://www.saminiir.com/feed +https://medium.com/feed/privacy-international +https://decentralize.today/feed +http://blog.z3bra.org/rss/feed.xml "~z3bra's blog" +http://feeds.xero.nu/atom/blog/newest "~xero's blog" +https://venam.nixers.net/blog/feed.xml "~venam's blog" +https://theintercept.com/feed/?lang=en "~The Intercept" +https://github.com/blog/engineering.atom "~GH Engineering" +https://www.albertocastillog.com/rss.xml "~Blog Personal" +https://nilsschulte.de/posts/rss.xml +https://desu.blog/feed/ +https://mochiro.moe/rss.xml +https://blog.sasach.work/feed diff --git a/nvim/.config/nvim/autoload/plug.vim b/nvim/.config/nvim/autoload/plug.vim @@ -0,0 +1,2454 @@ +" 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-master 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 `<Plug>`-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') || has('win64') +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') +let s:me = resolve(expand('<sfile>:p')) +let s:base_spec = { 'branch': 'master', '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! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(fnamemodify(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 + + 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#(<args>) + 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 + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(<bang>0, [<f-args>]) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(<bang>0, [<f-args>]) + command! -nargs=0 -bar -bang PlugClean call s:clean(<bang>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(<bang>0, <f-args>) +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! plug#end() + if !exists('g:plugs') + return s:err('Call 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) || !has_key(plug, 'on') && !has_key(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 =~? '^<Plug>.\+' + 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 `<Plug>`.') + 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, "<bang>", <line1>, <line2>, <q-args>, %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>', + \ 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 <SID>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 + +if s:is_win + function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + 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 +else + function! s:rtp(spec) + return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + 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')) ? '<nomodeline>' : '') 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'] + 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 unknowns = filter(copy(a:000), '!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(a:000), '!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 = "\<esc>" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . 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', 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(v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + if type == s:TYPE.string + let opts.tag = a:arg + elseif type == s:TYPE.dict + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(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(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([spec.dir, '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 /^-/ + 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 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 <silent> <buffer> R :call <SID>retry()<cr> + nnoremap <silent> <buffer> D :PlugDiff<cr> + nnoremap <silent> <buffer> S :PlugStatus<cr> + nnoremap <silent> <buffer> U :call <SID>status_update()<cr> + xnoremap <silent> <buffer> U :call <SID>status_update()<cr> + nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr> + nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr> +endfunction + +function! s:prepare(...) + if empty(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 <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>bd<cr> + 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 ['<cr>', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap <buffer>' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + 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, &shellredir] + if !s:is_win && a:swap + set shell=sh shellredir=>%s\ 2>&1 + endif + return prev +endfunction + +function! s:bang(cmd, ...) + try + let [sh, 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 + let g:_plug_bang = '!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\<cr>\<cr>" + finally + unlet g:_plug_bang + let [&shell, &shellredir] = [sh, shrd] + 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 + 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:system('git rev-parse HEAD', a:spec.dir) + if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) + let output = s:system( + \ 'git fetch --depth 999999 && git checkout '.s:esc(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 =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0")) + 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 = get(g:, 'plug_shallow', 1) ? + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' + + if has('win32unix') + let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' + endif + + " 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 '.s:shellesc(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 '.s:esc(tag).' -- 2>&1', spec.dir) + else + let branch = s:esc(get(spec, 'branch', 'master')) + call s:log4(name, 'Merging origin/'.branch) + let out = s:system('git checkout -q '.branch.' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only 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 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:system('rm -rf ' . s:shellesc(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' ? + \ 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 + let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'], + \ has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) + + if s:nvim + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = 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 jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ '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 params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] + let job.lines = s:lines(call('s:system', params)) + 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) + for i in range(4, line('$')) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, line('$')) + 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 = !isdirectory(spec.dir) + + 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 fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' + call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { '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 + call s:spawn(name, + \ printf('git clone %s %s %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, + \ prog, + \ s:shellesc(spec.uri), + \ s:shellesc(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 = 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') + 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(arg) + return '"'.escape(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) + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) +endfunction + +function! s:system(cmd, ...) + try + let [sh, shrd] = s:chsh(1) + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + return system(s:is_win ? '('.cmd.')' : cmd) + finally + let [&shell, &shellredir] = [sh, shrd] + 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:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + 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 result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + 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 branch = result[0] + " Check tag + 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 a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system(printf( + \ 'git rev-list --count --left-right HEAD...origin/%s', + \ a:spec.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.', a:spec.branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ a:spec.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) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(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(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 <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@ + nmap <silent> <buffer> dd d_ + xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr> + 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 + 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 + call s:rm_rf(line[2:]) + setlocal modifiable + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + call setline(4, printf('Removed %d directories.', s:clean_count)) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(printf('git clone --depth 1 %s %s', 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) + if has_key(spec, 'uri') + if isdirectory(spec.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 isdirectory(spec.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 valid && 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 <silent> <buffer> L :call <SID>status_load(line('.'))<cr> + xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr> + 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 + try + let [sh, shrd] = s:chsh(1) + execute 'silent %!cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha + finally + let [&shell, &shellredir] = [sh, shrd] + endtry + setlocal nomodifiable + nnoremap <silent> <buffer> q :q<cr> + 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 range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' + let diff = s:system_chomp('git log --graph --color=never --pretty=format:"%x01%h%x01%d%x01%s%x01%cr" '.s:shellesc(range), 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 + 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 <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr> + nnoremap <silent> <buffer> o :silent! call <SID>preview_commit()<cr> + endif + if cnts[0] + nnoremap <silent> <buffer> X :call <SID>revert()<cr> + 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 '.s:esc(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:system_chomp('git rev-parse --short HEAD', 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 = 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, '\\\@<!,') +endfunction + +let s:first_rtp = s:escrtp(get(s:split_rtp(), 0, '')) +let s:last_rtp = s:escrtp(get(s:split_rtp(), -1, '')) + +if exists('g:plugs') + let g:plugs_order = get(g:, 'plugs_order', keys(g:plugs)) + call s:upgrade_specs() + call s:define_commands() +endif + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/nvim/.config/nvim/colors/ThemerVim.vim b/nvim/.config/nvim/colors/ThemerVim.vim @@ -0,0 +1,155 @@ + + + + if &background == 'dark' + + let s:shade0 = "#282c34" + let s:shade1 = "#393e48" + let s:shade2 = "#4b515c" + let s:shade3 = "#5c6370" + let s:shade4 = "#636d83" + let s:shade5 = "#828997" + let s:shade6 = "#979eab" + let s:shade7 = "#abb2bf" + let s:accent0 = "#e06c75" + let s:accent1 = "#d19a66" + let s:accent2 = "#e5c07b" + let s:accent3 = "#98c379" + let s:accent4 = "#56b6c2" + let s:accent5 = "#61afef" + let s:accent6 = "#c678dd" + let s:accent7 = "#be5046" + + endif + + + + if &background == 'light' + + let s:shade0 = "#fafafa" + let s:shade1 = "#CDCED1" + let s:shade2 = "#a0a1a7" + let s:shade3 = "#9d9d9f" + let s:shade4 = "#83858B" + let s:shade5 = "#696c77" + let s:shade6 = "#51535D" + let s:shade7 = "#383a42" + let s:accent0 = "#e45649" + let s:accent1 = "#986801" + let s:accent2 = "#c18401" + let s:accent3 = "#50a14f" + let s:accent4 = "#0184bc" + let s:accent5 = "#4078f2" + let s:accent6 = "#a626a4" + let s:accent7 = "#ca1243" + + endif + + + highlight clear + syntax reset + let g:colors_name = "ThemerVim" + + """""""""" + " Normal " + """""""""" + + exec "hi Normal guifg=".s:shade6." guibg=".s:shade0 + + """"""""""""""""" + " Syntax groups " + """"""""""""""""" + + " Default + + exec "hi Comment guifg=".s:shade2 + exec "hi Constant guifg=".s:accent3 + exec "hi Character guifg=".s:accent4 + exec "hi Identifier guifg=".s:accent2." gui=none cterm=none" + exec "hi Statement guifg=".s:accent5 + exec "hi PreProc guifg=".s:accent6 + exec "hi Type guifg=".s:accent7 + exec "hi Special guifg=".s:accent4 + exec "hi Underlined guifg=".s:accent5 + exec "hi Error guifg=".s:accent0." guibg=".s:shade1 + exec "hi Todo guifg=".s:accent0." guibg=".s:shade1 + + " GitGutter + + exec "hi GitGutterAdd guifg=".s:accent3 + exec "hi GitGutterChange guifg=".s:accent2 + exec "hi GitGutterChangeDelete guifg=".s:accent2 + exec "hi GitGutterDelete guifg=".s:accent0 + + " fugitive + + exec "hi gitcommitComment guifg=".s:shade3 + exec "hi gitcommitOnBranch guifg=".s:shade3 + exec "hi gitcommitHeader guifg=".s:shade5 + exec "hi gitcommitHead guifg=".s:shade3 + exec "hi gitcommitSelectedType guifg=".s:accent3 + exec "hi gitcommitSelectedFile guifg=".s:accent3 + exec "hi gitcommitDiscardedType guifg=".s:accent2 + exec "hi gitcommitDiscardedFile guifg=".s:accent2 + exec "hi gitcommitUntrackedFile guifg=".s:accent0 + + """"""""""""""""""""""" + " Highlighting Groups " + """"""""""""""""""""""" + + " Default + + exec "hi ColorColumn guibg=".s:shade1 + exec "hi Conceal guifg=".s:shade2 + exec "hi Cursor guifg=".s:shade0 + exec "hi CursorColumn guibg=".s:shade1 + exec "hi CursorLine guibg=".s:shade1." cterm=none" + exec "hi Directory guifg=".s:accent5 + exec "hi DiffAdd guifg=".s:accent3." guibg=".s:shade1 + exec "hi DiffChange guifg=".s:accent2." guibg=".s:shade1 + exec "hi DiffDelete guifg=".s:accent0." guibg=".s:shade1 + exec "hi DiffText guifg=".s:accent2." guibg=".s:shade2 + exec "hi ErrorMsg guifg=".s:shade7." guibg=".s:accent0 + exec "hi VertSplit guifg=".s:shade0." guibg=".s:shade3 + exec "hi Folded guifg=".s:shade4." guibg=".s:shade1 + exec "hi FoldColumn guifg=".s:shade4." guibg=".s:shade1 + exec "hi SignColumn guibg=".s:shade0 + exec "hi IncSearch guifg=".s:shade0." guibg=".s:accent2 + exec "hi LineNr guifg=".s:shade2." guibg=".s:shade0 + exec "hi CursorLineNr guifg=".s:shade3." guibg=".s:shade1 + exec "hi MatchParen guibg=".s:shade2 + exec "hi MoreMsg guifg=".s:shade0." guibg=".s:accent4 + exec "hi NonText guifg=".s:shade2." guibg=".s:shade0 + exec "hi Pmenu guifg=".s:shade6." guibg=".s:shade1 + exec "hi PmenuSel guifg=".s:accent4." guibg=".s:shade1 + exec "hi PmenuSbar guifg=".s:accent3." guibg=".s:shade1 + exec "hi PmenuThumb guifg=".s:accent0." guibg=".s:shade2 + exec "hi Question guifg=".s:shade7." guibg=".s:shade1 + exec "hi Search guifg=".s:shade0." guibg=".s:accent2 + exec "hi SpecialKey guifg=".s:accent7." guibg=".s:shade0 + exec "hi SpellBad guifg=".s:accent0 + exec "hi SpellCap guifg=".s:accent2 + exec "hi SpellLocal guifg=".s:accent4 + exec "hi SpellRare guifg=".s:accent1 + exec "hi StatusLine guifg=".s:shade4." guibg=".s:shade1." gui=none cterm=none" + exec "hi TabLine guifg=".s:shade5." guibg=".s:shade1 + exec "hi TabLineFill guibg=".s:shade1 + exec "hi TabLineSel guifg=".s:shade6." guibg=".s:shade0 + exec "hi Title guifg=".s:accent5 + exec "hi Visual guibg=".s:shade1 + exec "hi VisualNOS guifg=".s:accent0." guibg=".s:shade1 + exec "hi WarningMsg guifg=".s:accent0 + exec "hi WildMenu guifg=".s:accent4." guibg=".s:shade1 + + " NERDTree + + exec "hi NERDTreeExecFile guifg=".s:accent4 + exec "hi NERDTreeDirSlash guifg=".s:accent5 + exec "hi NERDTreeCWD guifg=".s:accent0 + + """""""""""" + " Clean up " + """""""""""" + + unlet s:shade0 s:shade1 s:shade2 s:shade3 s:shade4 s:shade5 s:shade6 s:shade7 s:accent0 s:accent1 s:accent2 s:accent3 s:accent4 s:accent5 s:accent6 s:accent7 + + \ No newline at end of file diff --git a/nvim/.config/nvim/colors/base16-gruvbox-dark-hard.vim b/nvim/.config/nvim/colors/base16-gruvbox-dark-hard.vim @@ -0,0 +1,413 @@ +" vi:syntax=vim + +" base16-vim (https://github.com/chriskempson/base16-vim) +" by Chris Kempson (http://chriskempson.com) +" Gruvbox dark, hard scheme by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox) + +" This enables the coresponding base16-shell script to run so that +" :colorscheme works in terminals supported by base16-shell scripts +" User must set this variable in .vimrc +" let g:base16_shell_path=base16-builder/output/shell/ +if !has("gui_running") + if exists("g:base16_shell_path") + execute "silent !/bin/sh ".g:base16_shell_path."/base16-gruvbox-dark-hard.sh" + endif +endif + +" GUI color definitions +let s:gui00 = "1d2021" +let g:base16_gui00 = "1d2021" +let s:gui01 = "3c3836" +let g:base16_gui01 = "3c3836" +let s:gui02 = "504945" +let g:base16_gui02 = "504945" +let s:gui03 = "665c54" +let g:base16_gui03 = "665c54" +let s:gui04 = "bdae93" +let g:base16_gui04 = "bdae93" +let s:gui05 = "d5c4a1" +let g:base16_gui05 = "d5c4a1" +let s:gui06 = "ebdbb2" +let g:base16_gui06 = "ebdbb2" +let s:gui07 = "fbf1c7" +let g:base16_gui07 = "fbf1c7" +let s:gui08 = "fb4934" +let g:base16_gui08 = "fb4934" +let s:gui09 = "fe8019" +let g:base16_gui09 = "fe8019" +let s:gui0A = "fabd2f" +let g:base16_gui0A = "fabd2f" +let s:gui0B = "b8bb26" +let g:base16_gui0B = "b8bb26" +let s:gui0C = "8ec07c" +let g:base16_gui0C = "8ec07c" +let s:gui0D = "83a598" +let g:base16_gui0D = "83a598" +let s:gui0E = "d3869b" +let g:base16_gui0E = "d3869b" +let s:gui0F = "d65d0e" +let g:base16_gui0F = "d65d0e" + +" Terminal color definitions +let s:cterm00 = "00" +let g:base16_cterm00 = "00" +let s:cterm03 = "08" +let g:base16_cterm03 = "08" +let s:cterm05 = "07" +let g:base16_cterm05 = "07" +let s:cterm07 = "15" +let g:base16_cterm07 = "15" +let s:cterm08 = "01" +let g:base16_cterm08 = "01" +let s:cterm0A = "03" +let g:base16_cterm0A = "03" +let s:cterm0B = "02" +let g:base16_cterm0B = "02" +let s:cterm0C = "06" +let g:base16_cterm0C = "06" +let s:cterm0D = "04" +let g:base16_cterm0D = "04" +let s:cterm0E = "05" +let g:base16_cterm0E = "05" +if exists("base16colorspace") && base16colorspace == "256" + let s:cterm01 = "18" + let g:base16_cterm01 = "18" + let s:cterm02 = "19" + let g:base16_cterm02 = "19" + let s:cterm04 = "20" + let g:base16_cterm04 = "20" + let s:cterm06 = "21" + let g:base16_cterm06 = "21" + let s:cterm09 = "16" + let g:base16_cterm09 = "16" + let s:cterm0F = "17" + let g:base16_cterm0F = "17" +else + let s:cterm01 = "10" + let g:base16_cterm01 = "10" + let s:cterm02 = "11" + let g:base16_cterm02 = "11" + let s:cterm04 = "12" + let g:base16_cterm04 = "12" + let s:cterm06 = "13" + let g:base16_cterm06 = "13" + let s:cterm09 = "09" + let g:base16_cterm09 = "09" + let s:cterm0F = "14" + let g:base16_cterm0F = "14" +endif + +" Neovim terminal colours +if has("nvim") + let g:terminal_color_0 = "#1d2021" + let g:terminal_color_1 = "#fb4934" + let g:terminal_color_2 = "#b8bb26" + let g:terminal_color_3 = "#fabd2f" + let g:terminal_color_4 = "#83a598" + let g:terminal_color_5 = "#d3869b" + let g:terminal_color_6 = "#8ec07c" + let g:terminal_color_7 = "#d5c4a1" + let g:terminal_color_8 = "#665c54" + let g:terminal_color_9 = "#fb4934" + let g:terminal_color_10 = "#b8bb26" + let g:terminal_color_11 = "#fabd2f" + let g:terminal_color_12 = "#83a598" + let g:terminal_color_13 = "#d3869b" + let g:terminal_color_14 = "#8ec07c" + let g:terminal_color_15 = "#fbf1c7" + let g:terminal_color_background = g:terminal_color_0 + let g:terminal_color_foreground = g:terminal_color_5 + if &background == "light" + let g:terminal_color_background = g:terminal_color_7 + let g:terminal_color_foreground = g:terminal_color_2 + endif +elseif has("terminal") + let g:terminal_ansi_colors = [ + \ "#1d2021", + \ "#fb4934", + \ "#b8bb26", + \ "#fabd2f", + \ "#83a598", + \ "#d3869b", + \ "#8ec07c", + \ "#d5c4a1", + \ "#665c54", + \ "#fb4934", + \ "#b8bb26", + \ "#fabd2f", + \ "#83a598", + \ "#d3869b", + \ "#8ec07c", + \ "#fbf1c7", + \ ] +endif + +" Theme setup +hi clear +syntax reset +let g:colors_name = "base16-gruvbox-dark-hard" + +" Highlighting function +" Optional variables are attributes and guisp +function! g:Base16hi(group, guifg, guibg, ctermfg, ctermbg, ...) + let l:attr = get(a:, 1, "") + let l:guisp = get(a:, 2, "") + + if a:guifg != "" + exec "hi " . a:group . " guifg=#" . a:guifg + endif + if a:guibg != "" + exec "hi " . a:group . " guibg=#" . a:guibg + endif + if a:ctermfg != "" + exec "hi " . a:group . " ctermfg=" . a:ctermfg + endif + if a:ctermbg != "" + exec "hi " . a:group . " ctermbg=" . a:ctermbg + endif + if l:attr != "" + exec "hi " . a:group . " gui=" . l:attr . " cterm=" . l:attr + endif + if l:guisp != "" + exec "hi " . a:group . " guisp=#" . l:guisp + endif +endfunction + + +fun <sid>hi(group, guifg, guibg, ctermfg, ctermbg, attr, guisp) + call g:Base16hi(a:group, a:guifg, a:guibg, a:ctermfg, a:ctermbg, a:attr, a:guisp) +endfun + +" Vim editor colors +call <sid>hi("Normal", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call <sid>hi("Bold", "", "", "", "", "bold", "") +call <sid>hi("Debug", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("Directory", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("Error", s:gui00, s:gui08, s:cterm00, s:cterm08, "", "") +call <sid>hi("ErrorMsg", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call <sid>hi("Exception", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("FoldColumn", s:gui0C, s:gui01, s:cterm0C, s:cterm01, "", "") +call <sid>hi("Folded", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call <sid>hi("IncSearch", s:gui01, s:gui09, s:cterm01, s:cterm09, "none", "") +call <sid>hi("Italic", "", "", "", "", "none", "") +call <sid>hi("Macro", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("MatchParen", "", s:gui03, "", s:cterm03, "", "") +call <sid>hi("ModeMsg", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("MoreMsg", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("Question", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("Search", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "", "") +call <sid>hi("Substitute", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "none", "") +call <sid>hi("SpecialKey", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("TooLong", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("Underlined", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("Visual", "", s:gui02, "", s:cterm02, "", "") +call <sid>hi("VisualNOS", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("WarningMsg", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("WildMenu", s:gui08, s:gui0A, s:cterm08, "", "", "") +call <sid>hi("Title", s:gui0D, "", s:cterm0D, "", "none", "") +call <sid>hi("Conceal", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call <sid>hi("Cursor", s:gui00, s:gui05, s:cterm00, s:cterm05, "", "") +call <sid>hi("NonText", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("LineNr", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call <sid>hi("SignColumn", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call <sid>hi("StatusLine", s:gui04, s:gui02, s:cterm04, s:cterm02, "none", "") +call <sid>hi("StatusLineNC", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call <sid>hi("VertSplit", s:gui02, s:gui02, s:cterm02, s:cterm02, "none", "") +call <sid>hi("ColorColumn", "", s:gui01, "", s:cterm01, "none", "") +call <sid>hi("CursorColumn", "", s:gui01, "", s:cterm01, "none", "") +call <sid>hi("CursorLine", "", s:gui01, "", s:cterm01, "none", "") +call <sid>hi("CursorLineNr", s:gui04, s:gui01, s:cterm04, s:cterm01, "", "") +call <sid>hi("QuickFixLine", "", s:gui01, "", s:cterm01, "none", "") +call <sid>hi("PMenu", s:gui05, s:gui01, s:cterm05, s:cterm01, "none", "") +call <sid>hi("PMenuSel", s:gui01, s:gui05, s:cterm01, s:cterm05, "", "") +call <sid>hi("TabLine", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call <sid>hi("TabLineFill", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call <sid>hi("TabLineSel", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "none", "") + +" Standard syntax highlighting +call <sid>hi("Boolean", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("Character", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("Comment", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("Conditional", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("Constant", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("Define", s:gui0E, "", s:cterm0E, "", "none", "") +call <sid>hi("Delimiter", s:gui0F, "", s:cterm0F, "", "", "") +call <sid>hi("Float", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("Function", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("Identifier", s:gui08, "", s:cterm08, "", "none", "") +call <sid>hi("Include", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("Keyword", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("Label", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("Number", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("Operator", s:gui05, "", s:cterm05, "", "none", "") +call <sid>hi("PreProc", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("Repeat", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("Special", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("SpecialChar", s:gui0F, "", s:cterm0F, "", "", "") +call <sid>hi("Statement", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("StorageClass", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("String", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("Structure", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("Tag", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("Todo", s:gui0A, s:gui01, s:cterm0A, s:cterm01, "", "") +call <sid>hi("Type", s:gui0A, "", s:cterm0A, "", "none", "") +call <sid>hi("Typedef", s:gui0A, "", s:cterm0A, "", "", "") + +" C highlighting +call <sid>hi("cOperator", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("cPreCondit", s:gui0E, "", s:cterm0E, "", "", "") + +" C# highlighting +call <sid>hi("csClass", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("csAttribute", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("csModifier", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("csType", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("csUnspecifiedStatement", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("csContextualStatement", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("csNewDecleration", s:gui08, "", s:cterm08, "", "", "") + +" CSS highlighting +call <sid>hi("cssBraces", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("cssClassName", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("cssColor", s:gui0C, "", s:cterm0C, "", "", "") + +" Diff highlighting +call <sid>hi("DiffAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call <sid>hi("DiffChange", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call <sid>hi("DiffDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call <sid>hi("DiffText", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call <sid>hi("DiffAdded", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call <sid>hi("DiffFile", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call <sid>hi("DiffNewFile", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call <sid>hi("DiffLine", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call <sid>hi("DiffRemoved", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") + +" Git highlighting +call <sid>hi("gitcommitOverflow", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("gitcommitSummary", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("gitcommitComment", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("gitcommitUntracked", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("gitcommitDiscarded", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("gitcommitSelected", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("gitcommitHeader", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("gitcommitSelectedType", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("gitcommitUnmergedType", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("gitcommitDiscardedType", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("gitcommitBranch", s:gui09, "", s:cterm09, "", "bold", "") +call <sid>hi("gitcommitUntrackedFile", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("gitcommitUnmergedFile", s:gui08, "", s:cterm08, "", "bold", "") +call <sid>hi("gitcommitDiscardedFile", s:gui08, "", s:cterm08, "", "bold", "") +call <sid>hi("gitcommitSelectedFile", s:gui0B, "", s:cterm0B, "", "bold", "") + +" GitGutter highlighting +call <sid>hi("GitGutterAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call <sid>hi("GitGutterChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call <sid>hi("GitGutterDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call <sid>hi("GitGutterChangeDelete", s:gui0E, s:gui01, s:cterm0E, s:cterm01, "", "") + +" HTML highlighting +call <sid>hi("htmlBold", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("htmlItalic", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("htmlEndTag", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("htmlTag", s:gui05, "", s:cterm05, "", "", "") + +" JavaScript highlighting +call <sid>hi("javaScript", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("javaScriptBraces", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("javaScriptNumber", s:gui09, "", s:cterm09, "", "", "") +" pangloss/vim-javascript highlighting +call <sid>hi("jsOperator", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("jsStatement", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("jsReturn", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("jsThis", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("jsClassDefinition", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("jsFunction", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("jsFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("jsFuncCall", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("jsClassFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("jsClassMethodType", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("jsRegexpString", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("jsGlobalObjects", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("jsGlobalNodeObjects", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("jsExceptions", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("jsBuiltins", s:gui0A, "", s:cterm0A, "", "", "") + +" Mail highlighting +call <sid>hi("mailQuoted1", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("mailQuoted2", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("mailQuoted3", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("mailQuoted4", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("mailQuoted5", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("mailQuoted6", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("mailURL", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("mailEmail", s:gui0D, "", s:cterm0D, "", "", "") + +" Markdown highlighting +call <sid>hi("markdownCode", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("markdownError", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call <sid>hi("markdownCodeBlock", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("markdownHeadingDelimiter", s:gui0D, "", s:cterm0D, "", "", "") + +" NERDTree highlighting +call <sid>hi("NERDTreeDirSlash", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("NERDTreeExecFile", s:gui05, "", s:cterm05, "", "", "") + +" PHP highlighting +call <sid>hi("phpMemberSelector", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("phpComparison", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("phpParent", s:gui05, "", s:cterm05, "", "", "") +call <sid>hi("phpMethodsVar", s:gui0C, "", s:cterm0C, "", "", "") + +" Python highlighting +call <sid>hi("pythonOperator", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("pythonRepeat", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("pythonInclude", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("pythonStatement", s:gui0E, "", s:cterm0E, "", "", "") + +" Ruby highlighting +call <sid>hi("rubyAttribute", s:gui0D, "", s:cterm0D, "", "", "") +call <sid>hi("rubyConstant", s:gui0A, "", s:cterm0A, "", "", "") +call <sid>hi("rubyInterpolationDelimiter", s:gui0F, "", s:cterm0F, "", "", "") +call <sid>hi("rubyRegexp", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("rubySymbol", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("rubyStringDelimiter", s:gui0B, "", s:cterm0B, "", "", "") + +" SASS highlighting +call <sid>hi("sassidChar", s:gui08, "", s:cterm08, "", "", "") +call <sid>hi("sassClassChar", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("sassInclude", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("sassMixing", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("sassMixinName", s:gui0D, "", s:cterm0D, "", "", "") + +" Signify highlighting +call <sid>hi("SignifySignAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call <sid>hi("SignifySignChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call <sid>hi("SignifySignDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") + +" Spelling highlighting +call <sid>hi("SpellBad", "", "", "", "", "undercurl", s:gui08) +call <sid>hi("SpellLocal", "", "", "", "", "undercurl", s:gui0C) +call <sid>hi("SpellCap", "", "", "", "", "undercurl", s:gui0D) +call <sid>hi("SpellRare", "", "", "", "", "undercurl", s:gui0E) + +" Startify highlighting +call <sid>hi("StartifyBracket", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("StartifyFile", s:gui07, "", s:cterm07, "", "", "") +call <sid>hi("StartifyFooter", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("StartifyHeader", s:gui0B, "", s:cterm0B, "", "", "") +call <sid>hi("StartifyNumber", s:gui09, "", s:cterm09, "", "", "") +call <sid>hi("StartifyPath", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("StartifySection", s:gui0E, "", s:cterm0E, "", "", "") +call <sid>hi("StartifySelect", s:gui0C, "", s:cterm0C, "", "", "") +call <sid>hi("StartifySlash", s:gui03, "", s:cterm03, "", "", "") +call <sid>hi("StartifySpecial", s:gui03, "", s:cterm03, "", "", "") + +" Java highlighting +call <sid>hi("javaOperator", s:gui0D, "", s:cterm0D, "", "", "") + +" Remove functions +delf <sid>hi + +" Remove color variables +unlet s:gui00 s:gui01 s:gui02 s:gui03 s:gui04 s:gui05 s:gui06 s:gui07 s:gui08 s:gui09 s:gui0A s:gui0B s:gui0C s:gui0D s:gui0E s:gui0F +unlet s:cterm00 s:cterm01 s:cterm02 s:cterm03 s:cterm04 s:cterm05 s:cterm06 s:cterm07 s:cterm08 s:cterm09 s:cterm0A s:cterm0B s:cterm0C s:cterm0D s:cterm0E s:cterm0F diff --git a/nvim/.config/nvim/colors/contrastneed.vim b/nvim/.config/nvim/colors/contrastneed.vim @@ -0,0 +1,819 @@ +" 'contrastneed.vim' -- Vim color scheme. +" Maintainer: acg (acg@albertocg.com) +" Description: srcery theme fork. Dark colorscheme using 16 color palette + +if version > 580 + hi clear + if exists("syntax_on") + syntax reset + endif +endif + +let g:colors_name='contrastneed' + +if !has('gui_running') && &t_Co != 256 + finish +endif + +" Palette {{{ + +let s:black = ["#1d2021", 0] +let s:red = ["#CC241D", 1] +let s:green = ["#98971A", 2] +let s:yellow = ["#D79921", 3] +let s:blue = ["#458588", 4] +let s:magenta = ["#B16286", 5] +let s:cyan = ["#689D6A", 6] +let s:gray = ["#A89984", 7] +let s:bright_black = ["#928374", 8] +let s:bright_red = ["#FB4934", 9] +let s:bright_green = ["#B8BB26", 10] +let s:bright_yellow = ["#FABD2F", 11] +let s:bright_blue = ["#83A598", 12] +let s:bright_magenta = ["#D3869B", 13] +let s:bright_cyan = ["#8EC07C", 14] +let s:white = ["#EBDBB2", 15] + +" default xterm colors. +let s:orange = ['#D75F00', 166] +let s:bright_orange = ['#FF8700', 208] +let s:hard_black = ['#080808', 232] +let s:gray_alt = ['#4E4E4E', 239] + +"}}} +" Setup Variables: {{{ + +let s:none = ['NONE', 'NONE'] + +if !exists('g:contrastneed_bold') + let g:contrastneed_bold=1 +endif + +if !exists('g:contrastneed_italic') + if has('gui_running') || $TERM_ITALICS == 'true' + let g:contrastneed_italic=1 + else + let g:contrastneed_italic=0 + endif +endif + +if !exists('g:contrastneed_undercurl') + let g:contrastneed_undercurl=1 +endif + +if !exists('g:contrastneed_underline') + let g:contrastneed_underline=1 +endif + +if !exists('g:contrastneed_inverse') + let g:contrastneed_inverse=1 +endif + +" }}} +" Setup Emphasis: {{{ + +let s:bold = 'bold,' +if g:contrastneed_bold == 0 + let s:bold = '' +endif + +let s:italic = 'italic,' +if g:contrastneed_italic == 0 + let s:italic = '' +endif + +let s:underline = 'underline,' +if g:contrastneed_underline == 0 + let s:underline = '' +endif + +let s:undercurl = 'undercurl,' +if g:contrastneed_undercurl == 0 + let s:undercurl = '' +endif + +let s:inverse = 'inverse,' +if g:contrastneed_inverse == 0 + let s:inverse = '' +endif + +" }}} +" Highlighting Function: {{{ + +function! s:HL(group, fg, ...) + " Arguments: group, guifg, guibg, gui, guisp + + " foreground + let fg = a:fg + + " background + if a:0 >= 1 + let bg = a:1 + else + let bg = s:none + endif + + " emphasis + if a:0 >= 2 && strlen(a:2) + let emstr = a:2 + else + let emstr = 'NONE,' + endif + + let histring = [ 'hi', a:group, + \ 'guifg=' . fg[0], 'ctermfg=' . fg[1], + \ 'guibg=' . bg[0], 'ctermbg=' . bg[1], + \ 'gui=' . emstr[:-2], 'cterm=' . emstr[:-2] + \ ] + + " special + if a:0 >= 3 + call add(histring, 'guisp=' . a:3[0]) + endif + + execute join(histring, ' ') +endfunction +"}}} +" contrastneed Hi Groups: {{{ + +" memoize common hi groups +call s:HL('contrastneedWhite', s:white) +call s:HL('contrastneedRed', s:red) +call s:HL('contrastneedGreen', s:green) +call s:HL('contrastneedYellow', s:yellow) +call s:HL('contrastneedBlue', s:blue) +call s:HL('contrastneedMagenta', s:magenta) +call s:HL('contrastneedCyan', s:cyan) + +call s:HL('contrastneedRedbold', s:red, s:none, s:bold) +call s:HL('contrastneedGreenbold', s:green, s:none, s:bold) +call s:HL('contrastneedYellowbold', s:yellow, s:none, s:bold) +call s:HL('contrastneedBluebold', s:blue, s:none, s:bold) +call s:HL('contrastneedMagentabold', s:magenta, s:none, s:bold) +call s:HL('contrastneedCyanbold', s:cyan, s:none, s:bold) + +call s:HL('contrastneedBrightRed', s:bright_red, s:none) +call s:HL('contrastneedBrightGreen', s:bright_green, s:none) +call s:HL('contrastneedBrightYellow', s:bright_yellow, s:none) +call s:HL('contrastneedBrightBlue', s:bright_blue, s:none) +call s:HL('contrastneedBrightMagenta', s:bright_magenta, s:none) +call s:HL('contrastneedBrightCyan', s:bright_cyan, s:none) + +" special +call s:HL('contrastneedOrange', s:orange) +call s:HL('contrastneedOrangeBold', s:orange, s:none, s:bold) +call s:HL('contrastneedGrayAlt', s:gray_alt) +call s:HL('contrastneedHardBlack', s:hard_black) + +" }}} + +" Vanilla colorscheme --------------------------------------------------------- +" General UI: {{{ + +" Normal text +call s:HL('Normal', s:white, s:none) + +if version >= 700 + " Screen line that the cursor is + call s:HL('CursorLine', s:none, s:bright_black) + " Screen column that the cursor is + hi! link CursorColumn CursorLine + + " Tab pages line filler + call s:HL('TabLineFill', s:black, s:black) + " Active tab page label + call s:HL('TabLineSel', s:black, s:black, s:bold) + " Not active tab page label + hi! link TabLine TabLineFill + + " Match paired bracket under the cursor + call s:HL('MatchParen', s:red, s:black, s:bold) +endif + +if version >= 703 + " Highlighted screen columns + call s:HL('ColorColumn', s:none, s:black) + + " Concealed element: \lambda → λ + call s:HL('Conceal', s:blue, s:none) + + " Line number of CursorLine + call s:HL('CursorLineNr', s:red, s:black) +endif + +hi! link NonText contrastneedGrayAlt +hi! link SpecialKey contrastneedGrayAlt + +call s:HL('Visual', s:none, s:black, s:inverse) +hi! link VisualNOS Visual + +call s:HL('Search', s:none, s:yellow) +call s:HL('IncSearch', s:none, s:yellow) + +call s:HL('Underlined', s:blue, s:none, s:underline) + +call s:HL('StatusLine', s:red, s:none, s:bold) +call s:HL('StatusLineNC', s:gray, s:black, s:underline) + +" The column separating vertically split windows +call s:HL('VertSplit', s:red, s:black) + +" Current match in wildmenu completion +call s:HL('WildMenu', s:blue, s:black, s:bold) + +" Directory names, special names in listing +hi! link Directory contrastneedGreenBold + +" Titles for output from :set all, :autocmd, etc. +hi! link Title contrastneedGreenBold + +" Error messages on the command line +call s:HL('ErrorMsg', s:white, s:red) +" More prompt: -- More -- +hi! link MoreMsg contrastneedRedBold +" Current mode message: -- INSERT -- +hi! link ModeMsg contrastneedRedBold +" 'Press enter' prompt and yes/no questions +hi! link Question contrastneedOrangeBold +" Warning messages +hi! link WarningMsg contrastneedRedBold + +" }}} +" Gutter: {{{ + +" Line number for :number and :# commands +call s:HL('LineNr', s:gray) + +" Column where signs are displayed +call s:HL('SignColumn', s:none, s:black) + +" Line used for closed folds +call s:HL('Folded', s:gray, s:none, s:italic) +" Column where folds are displayed +call s:HL('FoldColumn', s:gray, s:none) + +" }}} +" Cursor: {{{ + +" Character under cursor +call s:HL('Cursor', s:none, s:none, s:inverse) +" Visual mode cursor, selection +hi! link vCursor Cursor +" Input moder cursor +hi! link iCursor Cursor +" Language mapping cursor +hi! link lCursor Cursor + +" }}} +" Syntax Highlighting: {{{ + +hi! link Special contrastneedOrange + +call s:HL('Comment', s:gray, s:none, s:italic . s:bold) +call s:HL('Todo', s:white, s:none, s:bold . s:italic) +call s:HL('Error', s:red, s:none, s:bold . s:inverse) + +" String constant: "this is a string" +call s:HL('String', s:bright_green) + +" Generic statement +hi! link Statement contrastneedRed +" if, then, else, endif, swicth, etc. +hi! link Conditional contrastneedRed +" for, do, while, etc. +hi! link Repeat contrastneedRed +" case, default, etc. +hi! link Label contrastneedRed +" try, catch, throw +hi! link Exception contrastneedRed +" sizeof, "+", "*", etc. +hi! link Operator Normal +" Any other keyword +hi! link Keyword contrastneedRed + +" Variable name +hi! link Identifier contrastneedBlue +" Function name +hi! link Function contrastneedGreenBold + +" Generic preprocessor +hi! link PreProc contrastneedCyan +" Preprocessor #include +hi! link Include contrastneedCyan +" Preprocessor #define +hi! link Define contrastneedCyan +" Same as Define +hi! link Macro contrastneedCyan +" Preprocessor #if, #else, #endif, etc. +hi! link PreCondit contrastneedCyan + +" Generic constant +hi! link Constant contrastneedBrightMagenta +" Character constant: 'c', '/n' +hi! link Character contrastneedBrightMagenta +" Boolean constant: TRUE, false +hi! link Boolean contrastneedBrightMagenta +" Number constant: 234, 0xff +hi! link Number contrastneedBrightMagenta +" Floating point constant: 2.3e10 +hi! link Float contrastneedBrightMagenta + +" Generic type +hi! link Type contrastneedYellow +" static, register, volatile, etc +hi! link StorageClass contrastneedOrange +" struct, union, enum, etc. +hi! link Structure contrastneedCyan +" typedef +hi! link Typedef contrastneedYellow + +" }}} +" Completion Menu: {{{ + +if version >= 700 + " Popup menu: normal item + call s:HL('Pmenu', s:white, s:black) + " Popup menu: selected item + call s:HL('PmenuSel', s:black, s:blue, s:bold) + " Popup menu: scrollbar + call s:HL('PmenuSbar', s:none, s:black) + " Popup menu: scrollbar thumb + call s:HL('PmenuThumb', s:none, s:black) +endif + +" }}} +" Diffs: {{{ + +call s:HL('DiffDelete', s:red, s:none, s:inverse) +call s:HL('DiffAdd', s:green, s:none, s:inverse) +"call s:HL('DiffChange', s:black, s:blue) +"call s:HL('DiffText', s:black, s:yellow) + +" Alternative setting +call s:HL('DiffChange', s:cyan, s:black, s:inverse) +call s:HL('DiffText', s:yellow, s:black, s:inverse) + +" }}} +" Spelling: {{{ + +if has("spell") + " Not capitalised word, or compile warnings + call s:HL('SpellCap', s:green, s:none, s:bold . s:italic) + " Not recognized word + call s:HL('SpellBad', s:none, s:none, s:undercurl, s:blue) + " Wrong spelling for selected region + call s:HL('SpellLocal', s:none, s:none, s:undercurl, s:cyan) + " Rare word + call s:HL('SpellRare', s:none, s:none, s:undercurl, s:magenta) +endif + +" }}} + +" Plugin specific ------------------------------------------------------------- +" Sneak: {{{ + +hi! link SneakPluginTarget Search +hi! link SneakStreakTarget Search +call s:HL('SneakStreakMask', s:yellow, s:yellow) +hi! link SneakStreakStatusLine Search + +" }}} +" Rainbow Parentheses: {{{ + +if !exists('g:rbpt_colorpairs') + let g:rbpt_colorpairs = + \ [ + \ ['blue', '#458588'], ['magenta', '#b16286'], + \ ['red', '#cc241d'], ['166', '#d65d0e'] + \ ] +endif + +let g:rainbow_guifgs = [ '#d65d0e', '#cc241d', '#b16286', '#458588' ] +let g:rainbow_ctermfgs = [ '166', 'red', 'magenta', 'blue' ] + +if !exists('g:rainbow_conf') + let g:rainbow_conf = {} +endif +if !has_key(g:rainbow_conf, 'guifgs') + let g:rainbow_conf['guifgs'] = g:rainbow_guifgs +endif +if !has_key(g:rainbow_conf, 'ctermfgs') + let g:rainbow_conf['ctermfgs'] = g:rainbow_ctermfgs +endif + +let g:niji_dark_colours = g:rbpt_colorpairs +let g:niji_light_colours = g:rbpt_colorpairs + +"}}} +" GitGutter: {{{ + +hi! link GitGutterAdd contrastneedGreen +hi! link GitGutterChange contrastneedCyan +hi! link GitGutterDelete contrastneedRed +hi! link GitGutterChangeDelete contrastneedCyan + +" }}} +" GitCommit: "{{{ + +hi! link gitcommitSelectedFile contrastneedGreen +hi! link gitcommitDiscardedFile contrastneedRed + +" }}} + +" Filetype specific ----------------------------------------------------------- +" Diff: {{{ + +hi! link diffAdded contrastneedGreen +hi! link diffRemoved contrastneedRed +hi! link diffChanged contrastneedCyan + +hi! link diffFile contrastneedOrange +hi! link diffNewFile contrastneedYellow + +hi! link diffLine contrastneedBlue + +" }}} +" Html: {{{ + +hi! link htmlTag contrastneedBlue +hi! link htmlEndTag contrastneedBlue + +hi! link htmlTagName contrastneedCyanBold +hi! link htmlArg contrastneedCyan + +hi! link htmlScriptTag contrastneedMagenta +hi! link htmlTagN contrastneedFg1 +hi! link htmlSpecialTagName contrastneedCyanBold + +call s:HL('htmlLink', s:white, s:none, s:underline) + +hi! link htmlSpecialChar contrastneedYellow + +call s:HL('htmlBold', s:white, s:none, s:bold) +call s:HL('htmlBoldUnderline', s:white, s:none, s:bold . s:underline) +call s:HL('htmlBoldItalic', s:white, s:none, s:bold . s:italic) +call s:HL('htmlBoldUnderlineItalic', s:white, s:none, s:bold . s:underline . s:italic) + +call s:HL('htmlUnderline', s:white, s:none, s:underline) +call s:HL('htmlUnderlineItalic', s:white, s:none, s:underline . s:italic) +call s:HL('htmlItalic', s:white, s:none, s:italic) + +" }}} +" Xml: {{{ + +hi! link xmlTag contrastneedBlue +hi! link xmlEndTag contrastneedBlue +hi! link xmlTagName contrastneedBlue +hi! link xmlEqual contrastneedBlue +hi! link docbkKeyword contrastneedCyanBold + +hi! link xmlDocTypeDecl contrastneedGray +hi! link xmlDocTypeKeyword contrastneedMagenta +hi! link xmlCdataStart contrastneedGray +hi! link xmlCdataCdata contrastneedMagenta +hi! link dtdFunction contrastneedGray +hi! link dtdTagName contrastneedMagenta + +hi! link xmlAttrib contrastneedCyan +hi! link xmlProcessingDelim contrastneedGray +hi! link dtdParamEntityPunct contrastneedGray +hi! link dtdParamEntityDPunct contrastneedGray +hi! link xmlAttribPunct contrastneedGray + +hi! link xmlEntity contrastneedYellow +hi! link xmlEntityPunct contrastneedYellow +" }}} +" Vim: {{{ + +call s:HL('vimCommentTitle', s:white, s:none, s:bold . s:italic) + +hi! link vimNotation contrastneedYellow +hi! link vimBracket contrastneedYellow +hi! link vimMapModKey contrastneedYellow +hi! link vimFuncSID contrastneedWhite +hi! link vimSetSep contrastneedWhite +hi! link vimSep contrastneedWhite +hi! link vimContinue contrastneedWhite + +" }}} +" Clojure: {{{ + +hi! link clojureKeyword contrastneedBlue +hi! link clojureCond contrastneedOrange +hi! link clojureSpecial contrastneedOrange +hi! link clojureDefine contrastneedOrange + +hi! link clojureFunc contrastneedYellow +hi! link clojureRepeat contrastneedYellow +hi! link clojureCharacter contrastneedCyan +hi! link clojureStringEscape contrastneedCyan +hi! link clojureException contrastneedRed + +hi! link clojureRegexp contrastneedCyan +hi! link clojureRegexpEscape contrastneedCyan +call s:HL('clojureRegexpCharClass', s:white, s:none, s:bold) +hi! link clojureRegexpMod clojureRegexpCharClass +hi! link clojureRegexpQuantifier clojureRegexpCharClass + +hi! link clojureParen contrastneedFg3 +hi! link clojureAnonArg contrastneedYellow +hi! link clojureVariable contrastneedBlue +hi! link clojureMacro contrastneedOrange + +hi! link clojureMeta contrastneedYellow +hi! link clojureDeref contrastneedYellow +hi! link clojureQuote contrastneedYellow +hi! link clojureUnquote contrastneedYellow +" }}} +" C: {{{ + +hi! link cOperator contrastneedMagenta +hi! link cStructure contrastneedYellow + +" }}} +" Python: {{{ + +hi! link pythonBuiltin contrastneedYellow +hi! link pythonBuiltinObj contrastneedYellow +hi! link pythonBuiltinFunc contrastneedYellow +hi! link pythonFunction contrastneedCyan +hi! link pythonDecorator contrastneedRed +hi! link pythonInclude contrastneedBlue +hi! link pythonImport contrastneedBlue +hi! link pythonRun contrastneedBlue +hi! link pythonCoding contrastneedBlue +hi! link pythonOperator contrastneedRed +hi! link pythonExceptions contrastneedMagenta +hi! link pythonBoolean contrastneedMagenta +hi! link pythonDot contrastneedWhite + +" }}} +" CSS: {{{ + +hi! link cssBraces contrastneedBlue +hi! link cssFunctionName contrastneedYellow +hi! link cssIdentifier contrastneedYellow +hi! link cssClassName contrastneedGreen +hi! link cssColor contrastneedBlue +hi! link cssSelectorOp contrastneedBlue +hi! link cssSelectorOp2 contrastneedBlue +hi! link cssImportant contrastneedGreen +hi! link cssVendor contrastneedFg1 + +hi! link cssTextProp contrastneedCyan +hi! link cssAnimationProp contrastneedCyan +hi! link cssUIProp contrastneedYellow +hi! link cssTransformProp contrastneedCyan +hi! link cssTransitionProp contrastneedCyan +hi! link cssPrintProp contrastneedCyan +hi! link cssPositioningProp contrastneedYellow +hi! link cssBoxProp contrastneedCyan +hi! link cssFontDescriptorProp contrastneedCyan +hi! link cssFlexibleBoxProp contrastneedCyan +hi! link cssBorderOutlineProp contrastneedCyan +hi! link cssBackgroundProp contrastneedCyan +hi! link cssMarginProp contrastneedCyan +hi! link cssListProp contrastneedCyan +hi! link cssTableProp contrastneedCyan +hi! link cssFontProp contrastneedCyan +hi! link cssPaddingProp contrastneedCyan +hi! link cssDimensionProp contrastneedCyan +hi! link cssRenderProp contrastneedCyan +hi! link cssColorProp contrastneedCyan +hi! link cssGeneratedContentProp contrastneedCyan + +" }}} +" JavaScript: {{{ + +hi! link javaScriptBraces contrastneedFg1 +hi! link javaScriptFunction contrastneedCyan +hi! link javaScriptIdentifier contrastneedRed +hi! link javaScriptMember contrastneedBlue +hi! link javaScriptNumber contrastneedMagenta +hi! link javaScriptNull contrastneedMagenta +hi! link javaScriptParens contrastneedWhite + +" }}} +" YAJS: {{{ + +hi! link javascriptImport contrastneedCyan +hi! link javascriptExport contrastneedCyan +hi! link javascriptClassKeyword contrastneedCyan +hi! link javascriptClassExtends contrastneedCyan +hi! link javascriptDefault contrastneedCyan + +hi! link javascriptClassName contrastneedYellow +hi! link javascriptClassSuperName contrastneedYellow +hi! link javascriptGlobal contrastneedYellow + +hi! link javascriptEndColons contrastneedFg1 +hi! link javascriptFuncArg contrastneedFg1 +hi! link javascriptGlobalMethod contrastneedFg1 +hi! link javascriptNodeGlobal contrastneedFg1 + +" hi! link javascriptVariable contrastneedYellow +hi! link javascriptVariable contrastneedRed +" hi! link javascriptIdentifier contrastneedYellow +" hi! link javascriptClassSuper contrastneedYellow +hi! link javascriptIdentifier contrastneedYellow +hi! link javascriptClassSuper contrastneedYellow + +" hi! link javascriptFuncKeyword contrastneedYellow +" hi! link javascriptAsyncFunc contrastneedYellow +hi! link javascriptFuncKeyword contrastneedCyan +hi! link javascriptAsyncFunc contrastneedCyan +hi! link javascriptClassStatic contrastneedYellow + +hi! link javascriptOperator contrastneedRed +hi! link javascriptForOperator contrastneedRed +hi! link javascriptYield contrastneedRed +hi! link javascriptExceptions contrastneedRed +hi! link javascriptMessage contrastneedRed + +hi! link javascriptTemplateSB contrastneedCyan +hi! link javascriptTemplateSubstitution contrastneedFg1 + +" hi! link javascriptLabel contrastneedBlue +" hi! link javascriptObjectLabel contrastneedBlue +" hi! link javascriptPropertyName contrastneedBlue +hi! link javascriptLabel contrastneedFg1 +hi! link javascriptObjectLabel contrastneedFg1 +hi! link javascriptPropertyName contrastneedFg1 + +hi! link javascriptLogicSymbols contrastneedFg1 +hi! link javascriptArrowFunc contrastneedFg1 + +hi! link javascriptDocParamName contrastneedFg4 +hi! link javascriptDocTags contrastneedFg4 +hi! link javascriptDocNotation contrastneedFg4 +hi! link javascriptDocParamType contrastneedFg4 +hi! link javascriptDocNamedParamType contrastneedFg4 + +" }}} +" CoffeeScript: {{{ + +hi! link coffeeExtendedOp contrastneedWhite +hi! link coffeeSpecialOp contrastneedWhite +hi! link coffeeCurly contrastneedYellow +hi! link coffeeParen contrastneedWhite +hi! link coffeeBracket contrastneedYellow + +" }}} +" Ruby: {{{ + +hi! link rubyStringDelimiter contrastneedGreen +hi! link rubyInterpolationDelimiter contrastneedCyan + +" }}} +" ObjectiveC: {{{ + +hi! link objcTypeModifier contrastneedRed +hi! link objcDirective contrastneedBlue + +" }}} +" Go: {{{ + +hi! link goDirective contrastneedCyan +hi! link goConstants contrastneedMagenta +hi! link goDeclaration contrastneedRed +hi! link goDeclType contrastneedBlue +hi! link goBuiltins contrastneedYellow + +" }}} +" Lua: {{{ + +hi! link luaIn contrastneedRed +hi! link luaFunction contrastneedCyan +hi! link luaTable contrastneedYellow + +" }}} +" MoonScript: {{{ + +hi! link moonSpecialOp contrastneedWhite +hi! link moonExtendedOp contrastneedWhite +hi! link moonFunction contrastneedWhite +hi! link moonObject contrastneedYellow + +" }}} +" Java: {{{ + +hi! link javaAnnotation contrastneedBlue +hi! link javaDocTags contrastneedCyan +hi! link javaCommentTitle vimCommentTitle +hi! link javaParen contrastneedWhite +hi! link javaParen1 contrastneedWhite +hi! link javaParen2 contrastneedWhite +hi! link javaParen3 contrastneedWhite +hi! link javaParen4 contrastneedWhite +hi! link javaParen5 contrastneedWhite +hi! link javaOperator contrastneedYellow + +hi! link javaVarArg contrastneedGreen + +" }}} +" Elixir: {{{ + +hi! link elixirDocString Comment + +hi! link elixirStringDelimiter contrastneedGreen +hi! link elixirInterpolationDelimiter contrastneedCyan + +" }}} +" Scala: {{{ + +" NB: scala vim syntax file is kinda horrible +hi! link scalaNameDefinition contrastneedFg1 +hi! link scalaCaseFollowing contrastneedFg1 +hi! link scalaCapitalWord contrastneedFg1 +hi! link scalaTypeExtension contrastneedFg1 + +hi! link scalaKeyword contrastneedRed +hi! link scalaKeywordModifier contrastneedRed + +hi! link scalaSpecial contrastneedCyan +hi! link scalaOperator contrastneedFg1 + +hi! link scalaTypeDeclaration contrastneedYellow +hi! link scalaTypeTypePostDeclaration contrastneedYellow + +hi! link scalaInstanceDeclaration contrastneedFg1 +hi! link scalaInterpolation contrastneedCyan + +" }}} +" Markdown: {{{ + +call s:HL('markdownItalic', s:white, s:none, s:italic) + +hi! link markdownH1 contrastneedGreenBold +hi! link markdownH2 contrastneedGreenBold +hi! link markdownH3 contrastneedYellowBold +hi! link markdownH4 contrastneedYellowBold +hi! link markdownH5 contrastneedYellow +hi! link markdownH6 contrastneedYellow + +hi! link markdownCode contrastneedCyan +hi! link markdownCodeBlock contrastneedCyan +hi! link markdownCodeDelimiter contrastneedCyan + +hi! link markdownBlockquote contrastneedGray +hi! link markdownListMarker contrastneedGray +hi! link markdownOrderedListMarker contrastneedGray +hi! link markdownRule contrastneedGray +hi! link markdownHeadingRule contrastneedGray + +hi! link markdownUrlDelimiter contrastneedWhite +hi! link markdownLinkDelimiter contrastneedWhite +hi! link markdownLinkTextDelimiter contrastneedWhite + +hi! link markdownHeadingDelimiter contrastneedYellow +hi! link markdownUrl contrastneedMagenta +hi! link markdownUrlTitleDelimiter contrastneedGreen + +call s:HL('markdownLinkText', s:gray, s:none, s:underline) +hi! link markdownIdDeclaration markdownLinkText + +" }}} +" Haskell: {{{ + +" hi! link haskellType contrastneedYellow +" hi! link haskellOperators contrastneedYellow +" hi! link haskellConditional contrastneedCyan +" hi! link haskellLet contrastneedYellow +" +hi! link haskellType contrastneedFg1 +hi! link haskellIdentifier contrastneedFg1 +hi! link haskellSeparator contrastneedFg1 +hi! link haskellDelimiter contrastneedFg4 +hi! link haskellOperators contrastneedBlue +" +hi! link haskellBacktick contrastneedYellow +hi! link haskellStatement contrastneedYellow +hi! link haskellConditional contrastneedYellow + +hi! link haskellLet contrastneedCyan +hi! link haskellDefault contrastneedCyan +hi! link haskellWhere contrastneedCyan +hi! link haskellBottom contrastneedCyan +hi! link haskellBlockKeywords contrastneedCyan +hi! link haskellImportKeywords contrastneedCyan +hi! link haskellDeclKeyword contrastneedCyan +hi! link haskellDeriving contrastneedCyan +hi! link haskellAssocType contrastneedCyan + +hi! link haskellNumber contrastneedMagenta +hi! link haskellPragma contrastneedMagenta + +hi! link haskellString contrastneedGreen +hi! link haskellChar contrastneedGreen + +" }}} +" Json: {{{ + +hi! link jsonKeyword contrastneedGreen +hi! link jsonQuote contrastneedGreen +hi! link jsonBraces contrastneedFg1 +hi! link jsonString contrastneedFg1 + +" }}} + +" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker: diff --git a/nvim/.config/nvim/init.vim b/nvim/.config/nvim/init.vim @@ -0,0 +1,209 @@ +set nocompatible +scriptencoding utf-8 +let g:python3_host_prog='/usr/bin/python3' + +" ===== PLUGINS ===== + +call plug#begin('~/.config/nvim/plugged') + +"" Fuzzy finder +Plug 'airblade/vim-rooter' +Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +Plug 'junegunn/fzf.vim' + +"" Autocomplete +Plug 'ncm2/ncm2' +Plug 'roxma/nvim-yarp' +Plug 'ncm2/ncm2-path' +Plug 'ncm2/ncm2-bufword' +Plug 'ncm2/ncm2-tmux' + +"" Language Support +Plug 'phpactor/phpactor' , {'do': 'composer install', 'for': 'php'} +Plug 'autozimu/LanguageClient-neovim', { + \ 'branch': 'next', + \ 'do': 'bash install.sh', + \ } + +"" Rust +Plug 'rust-lang/rust.vim' + +"" Python +Plug 'python-mode/python-mode', { 'for': 'python', 'branch': 'develop' } + +Plug 'majutsushi/tagbar' +Plug 'tomtom/tcomment_vim' +Plug 'jiangmiao/auto-pairs' +Plug 'airblade/vim-gitgutter' +Plug 'stanangeloff/php.vim' +Plug 'mattn/emmet-vim' +Plug 'chriskempson/base16-vim' + + +call plug#end() +filetype plugin indent on +set timeoutlen=300 +set encoding=utf-8 +set noshowmode +set hidden +set nowrap +set nojoinspaces + +let mapleader = " " + +" ===== PERSONAL ===== +set background=dark +colorscheme contrastneed + +map j gj +map k gk +vnoremap > >gv +vnoremap < <gv + +set number +set numberwidth=4 +syn on + +set ruler +set noswapfile + +"Case insensitive +set incsearch +set ignorecase +set smartcase +set gdefault + +"Soft tabs +set tabstop=4 +set shiftwidth=4 +set shiftround +set expandtab +set smarttab +set clipboard+=unnamedplus + +" Splits autoresize +set winwidth=84 +set winheight=5 +set winminheight=5 +set winheight=999 +set splitright +set splitbelow + +nnoremap <C-J> <C-W><C-J> +nnoremap <C-K> <C-W><C-K> +nnoremap <C-L> <C-W><C-L> +nnoremap <C-H> <C-W><C-H> + +nnoremap <leader><leader> <c-^> +nnoremap <C-w> :bd<CR> + +"Line 80 mark +set tw=80 +set colorcolumn=+1 +highlight ColorColumn ctermbg=0 + +set wrapmargin=0 +" Wrapping options +set formatoptions=tc " wrap text and comments using textwidth +set formatoptions+=r " continue comments when pressing ENTER in I mode +set formatoptions+=q " enable formatting of comments with gq +set formatoptions+=n " detect lists for formatting +set formatoptions+=b " auto-wrap in insert mode, and do not wrap old long + +set showcmd + + +set laststatus=2 + +" ==== GUI ==== +set guioptions-=T +set vb t_vb= +set backspace=2 +set nofoldenable +set ruler +set ttyfast +set lazyredraw +set synmaxcol=500 +set relativenumber +set number +set diffopt+=iwhite +set diffopt+=algorithm:patience +set diffopt+=indent-heuristic +set shortmess+=c +set nolist +set listchars=nbsp:¬,extends:»,precedes:«,trail:• + + +" ==== MOVEMENT ==== +nnoremap <C-j> <C-w>j +nnoremap <C-k> <C-w>k +nnoremap <C-l> <C-w>l +nnoremap <C-h> <C-w>h + +map <C-tab> :bn + +" == SCROLLING == +set scrolloff=10 + +" ==== TAGBAR ==== +nmap <leader>t :TagbarToggle<CR> + +" ==== vim closetag ===== +let g:closetag_filenames = "*.html,*.xhtml,*.phtml,*.php" + +au BufNewFile,BufRead *.py + \ set tabstop=4 + \ set softtabstop=4 + \ set shiftwidth=4 + \ set textwidth=79 + \ set expandtab + \ set autoindent + \ set fileformat=unix +autocmd FileType php setlocal tabstop=4 shiftwidth=4 expandtab + +" ==== LANGUAGE SUPPORT ==== +" Completion +set hidden +let g:LanguageClient_serverCommands = { + \ 'rust': ['rustup', 'run', 'stable', 'rls'], + \ } +autocmd BufEnter * call ncm2#enable_for_buffer() +" set completeopt=noinsert,menuone,noselect +au User Ncm2PopupOpen set completeopt=noinsert,menuone,noselect +inoremap <expr><Tab> (pumvisible()?(empty(v:completed_item)?"\<C-n>":"\<C-y>"):"\<Tab>") +inoremap <expr><CR> (pumvisible()?(empty(v:completed_item)?"\<CR>\<CR>":"\<C-y>"):"\<CR>") + +let g:LanguageClient_autoStart = 1 +let g:LanguageClient_useVirtualText = "No" +let g:LanguageClient_useFloatingHover = 0 +nnoremap <silent> cm :call LanguageClient_contextMenu()<CR> +nnoremap <silent> gd :call LanguageClient#textDocument_definition()<CR> +nnoremap <silent> K :call LanguageClient#textDocument_hover()<CR> + +let $FZF_DEFAULT_COMMAND = 'rg --files' + +" Python Mode +let g:pymode_python = 'python3' + +map <C-p> :Files<CR> +nmap <leader>; :Buffers<CR> + +if executable('rg') + set grepprg=rg\ --no-heading\ --vimgrep + set grepformat=%f:%l:%c:m +endif + +" Follow Rust code style rules +au Filetype rust set colorcolumn=100 + +" Buffer Hooks +autocmd BufEnter * silent! cd %:p:h +autocmd BufWinLeave *.* mkview +autocmd BufWinEnter *.* silent loadview" +autocmd BufRead *.plot set filetype=gnuplot +autocmd BufRead *.md set filetype=markdown +autocmd BufRead *.lds set filetype=ld +autocmd BufRead *.tex set filetype=tex +autocmd BufRead *.trm set filetype=c +autocmd BufReadPost *.rs setlocal filetype=rust +set t_Co=256 diff --git a/polybar/.config/polybar/config b/polybar/.config/polybar/config @@ -0,0 +1,212 @@ +[colors] +background = #1d2021 +background-alt = #444 +foreground = #ebdbb2 +foreground-alt = #888 +primary = #ffb52a +secondary = #e60053 +alert = #bd2c40 +dark-red = #cc241d +red = #fb4934 +dark-yellow = #d79921 +yellow = #fabd2f + +[bar/main] +monitor = ${env:MONITOR:HDMI-0} +width = 100% +height = 30px +radius = 0 +fixed-center = true +bottom = true +override-redirect = true +wm-restack = i3 + +background = ${colors.background} +foreground = ${colors.foreground} + +border-size = 1 +line-size = 2 +padding = 1 +module-margin = 1 + +font-0 = "Fira Mono Medium:size=10;1" +font-1 = "Material Design Icons:scale=1;size=10;1" +font-2 = "WenQuanYi Zen Hei Mono:size=10;1" +font-3 = "Noto Sans Symbols2:size=10;1" + +modules-left = gmail spotify +modules-center = +modules-right = network pulseaudio date + +tray-position = right +tray-padding = 2 +tray-maxsize = 24 + +[global/wm] +margin-top = 0 + +[module/xkeyboard] +type = internal/xkeyboard + +; List of indicators to ignore +blacklist-0 = num lock +blacklist-1 = scroll lock + +format = <label-layout> +label-layout = ⌨ %icon% +format-underline = ${colors.dark-red} +layout-icon-0 = us;us +layout-icon-1 = latam;la + +[module/gmail] +type = custom/script +exec = ~/.config/polybar/gmail/launch.py -ns -c '#fb4934' -p '✉️' +tail = true +format-underline = ${colors.dark-yellow} +click-left = xdg-open https://mail.google.com + +[module/pulseaudio] +type = internal/pulseaudio + +; Sink to be used, if it exists (find using `pacmd list-sinks`, name field) +; If not, uses default sink +;sink = alsa_output.pci-0000_12_00.3.analog-stereo + +; Use PA_VOLUME_UI_MAX (~153%) if true, or PA_VOLUME_NORM (100%) if false +; Default: true +use-ui-max = true +interval = 5 +label-muted = 🔇 muted +label-muted-foreground = #666 +format-volume = <ramp-volume> <label-volume> +format-volume-underline = ${colors.dark-yellow} +format-muted-underline = ${colors.dark-red} + +; Only applies if <ramp-volume> is used +ramp-volume-0 = 🔈 +ramp-volume-1 = 🔉 +ramp-volume-2 = 🔊 +click-right = pavucontrol & + +[module/cpu] +type = internal/cpu +interval = 2 +format-prefix = "💻 " +format-prefix-foreground = ${colors.foreground-alt} +format-underline = #f90000 +label = %percentage:2%% + +[module/memory] +type = internal/memory +interval = 2 +format-prefix = "🗍 " +format-prefix-foreground = ${colors.foreground-alt} +format-underline = #4bffdc +label = %percentage_used:2%% + +[module/network] +type = internal/network +interface = enp39s0 +interval = 5.0 + +format-connected-underline = ${colors.dark-yellow} +label-connected = %upspeed% | %downspeed% + +label-disconnected = ❎ not connected + +[module/spotify] +type = custom/script +interval = 1 +format-prefix = " " +format = <label> +exec = python ~/.config/polybar/spotify/spotify_status.py -f '{play_pause}{artist} - {song}' -p ',[paused] ' +format-underline = ${colors.dark-yellow} + +[module/date] +type = internal/date +interval = 5 + +date = +date-alt = "%a %b %d " + +time = %H:%M +time-alt = %H:%M% + +format-prefix = +format-underline = ${colors.dark-yellow} + +label = %date%%time% + +[module/brightness] +type = internal/xbacklight + +; Create scroll handlers used to set the backlight value +; Default: true +enable-scroll = true +format = <ramp> <label> + +label = %percentage%% + +; Only applies if <ramp> is used +ramp-0 = 🌕 +ramp-1 = 🌔 +ramp-2 = 🌓 +ramp-3 = 🌒 +ramp-4 = 🌑 + +format-underline = #ffb52a + +[module/battery] +type = internal/battery +battery = BAT0 +adapter = AC +full-at = 98 + +format-charging = <label-charging> +format-charging-underline = #ffb52a + +format-discharging = <ramp-capacity> <label-discharging> +format-discharging-underline = ${self.format-charging-underline} + +format-full = <label-full> +format-full-underline = ${self.format-charging-underline} + +ramp-capacity-0 = ⚋ +ramp-capacity-1 = ⚊ +ramp-capacity-2 = ⚍ +ramp-capacity-3 = ⚌ +ramp-capacity-foreground = ${colors.foreground} + +label-charging = ⚡ %percentage%% +label-discharging = %percentage%% +label-full = " ☀ " + +[module/battery2] +type = internal/battery +battery = BAT1 +adapter = AC +full-at = 98 + +format-charging = <label-charging> +format-charging-underline = #ffb52a + +format-discharging = <ramp-capacity> <label-discharging> +format-discharging-underline = ${self.format-charging-underline} + +format-full = <label-full> +format-full-underline = ${self.format-charging-underline} + +ramp-capacity-0 = ⚋ +ramp-capacity-1 = ⚊ +ramp-capacity-2 = ⚍ +ramp-capacity-3 = ⚌ +ramp-capacity-foreground = ${colors.foreground-alt} + +label-charging = ⚡ %percentage%% +label-discharging = %percentage%% +label-full = " ☀ " + +[settings] +screenchange-reload = true + +; vim:ft=dosini diff --git a/polybar/.config/polybar/gmail/.gitignore b/polybar/.config/polybar/gmail/.gitignore @@ -0,0 +1 @@ +credentials.json diff --git a/polybar/.config/polybar/gmail/LICENSE b/polybar/.config/polybar/gmail/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2019 Vyacheslav Konovalov https://github.com/vyachkonovalov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/polybar/.config/polybar/gmail/README.md b/polybar/.config/polybar/gmail/README.md @@ -0,0 +1,65 @@ +# Polybar Gmail + +A [Polybar](https://github.com/jaagr/polybar) module to show unread messages from Gmail. + +![preview](https://github.com/vyachkonovalov/polybar-gmail/raw/master/preview.png) + +## Dependencies + +```sh +pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib +# or use poetry +``` + +**Font Awesome** - default email icon + +**canberra-gtk-play** - new email sound notification + +You can change the icon or turn off sound, for more info see [script arguments](#script-arguments) + +## Installation + +```sh +cd ~/.config/polybar +curl -LO https://github.com/vyachkonovalov/polybar-gmail/archive/master.tar.gz +tar zxf master.tar.gz && rm master.tar.gz +mv polybar-gmail-master gmail +``` + +and obtain/refresh credentials + +```sh +~/.config/polybar/gmail/auth.py +``` + +### Module + +```ini +[module/gmail] +type = custom/script +exec = ~/.config/polybar/gmail/launch.py +tail = true +click-left = xdg-open https://mail.google.com +``` + +## Script arguments + +`-l` or `--label` - set user's mailbox [label](https://developers.google.com/gmail/api/v1/reference/users/labels/list), default: INBOX + +`-p` or `--prefix` - set email icon, default:  + +`-c` or `--color` - set new email icon color, default: #e06c75 + +`-ns` or `--nosound` - turn off new email sound + +### Example + +```sh +./launch.py --label 'CATEGORY_PERSONAL' --prefix '✉' --color '#be5046' --nosound +``` + +## Get list of all your mailbox labels + +```python +./list_labels.py +``` diff --git a/polybar/.config/polybar/gmail/auth.py b/polybar/.config/polybar/gmail/auth.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +from pathlib import Path +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from google.auth.transport.requests import Request + +SCOPE = 'https://www.googleapis.com/auth/gmail.labels' +DIR = Path(__file__).resolve().parent +CLIENT_SECRETS_PATH = Path(DIR, 'client_secrets.json') +CREDENTIALS_PATH = Path(DIR, 'credentials.json') + +if Path(CREDENTIALS_PATH).is_file(): + creds = Credentials.from_authorized_user_file(CREDENTIALS_PATH) + if creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + print('Credentials looks ok, try to remove credentials.json if something doesn\'t work') + exit() +else: + flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_PATH, scopes=[SCOPE]) + creds = flow.run_console() + +# Save credentials +with open(CREDENTIALS_PATH, 'w') as creds_file: + creds_file.write(creds.to_json()) +print('Credentials successfully refreshed/created') diff --git a/polybar/.config/polybar/gmail/client_secrets.json b/polybar/.config/polybar/gmail/client_secrets.json @@ -0,0 +1 @@ +{"installed":{"client_id":"1041679298587-8solnkr9tr8iktrut958if6tsgqt42m2.apps.googleusercontent.com","project_id":"polybar-gmail","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"-aZZAslLp6ydldCAFvH9AEwi","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}+ \ No newline at end of file diff --git a/polybar/.config/polybar/gmail/launch.py b/polybar/.config/polybar/gmail/launch.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +import time +import argparse +import subprocess +from pathlib import Path +from googleapiclient import discovery, errors +from google.oauth2.credentials import Credentials +from httplib2 import ServerNotFoundError + +parser = argparse.ArgumentParser() +parser.add_argument('-l', '--label', default='INBOX') +parser.add_argument('-p', '--prefix', default='\uf0e0') +parser.add_argument('-c', '--color', default='#e06c75') +parser.add_argument('-ns', '--nosound', action='store_true') +args = parser.parse_args() + +DIR = Path(__file__).resolve().parent +CREDENTIALS_PATH = Path(DIR, 'credentials.json') + +unread_prefix = '%{F' + args.color + '}' + args.prefix + ' %{F-}' +error_prefix = '%{F' + args.color + '}\uf06a %{F-}' +count_was = 0 + +def print_count(count, is_odd=False): + tilde = '~' if is_odd else '' + output = '' + if count > 0: + output = unread_prefix + tilde + str(count) + else: + output = (args.prefix + ' ' + tilde).strip() + print(output, flush=True) + +def update_count(count_was): + creds = Credentials.from_authorized_user_file(CREDENTIALS_PATH) + gmail = discovery.build('gmail', 'v1', credentials=creds) + labels = gmail.users().labels().get(userId='me', id=args.label).execute() + count = labels['messagesUnread'] + print_count(count) + if not args.nosound and count_was < count and count > 0: + subprocess.run(['canberra-gtk-play', '-i', 'message']) + return count + +print_count(0, True) + +while True: + try: + if Path(CREDENTIALS_PATH).is_file(): + count_was = update_count(count_was) + time.sleep(10) + else: + print(error_prefix + 'credentials not found', flush=True) + time.sleep(2) + except errors.HttpError as error: + if error.resp.status == 404: + print(error_prefix + f'"{args.label}" label not found', flush=True) + else: + print_count(count_was, True) + time.sleep(5) + except (ServerNotFoundError, OSError): + print_count(count_was, True) + time.sleep(5) diff --git a/polybar/.config/polybar/gmail/list_labels.py b/polybar/.config/polybar/gmail/list_labels.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +import os +import sys +from googleapiclient.discovery import build +from google.oauth2.credentials import Credentials + +DIR = os.path.dirname(os.path.realpath(__file__)) +CREDENTIALS_PATH = os.path.join(DIR, 'credentials.json') + +try: + creds = Credentials.from_authorized_user_file(CREDENTIALS_PATH) +except FileNotFoundError: + sys.exit('File ' + CREDENTIALS_PATH + ' not found. Run auth.py to obtain credentials.') +gmail = build('gmail', 'v1', credentials=creds) +labels = gmail.users().labels().list(userId='me').execute() +for label in labels['labels']: + print(label['id']) diff --git a/polybar/.config/polybar/gmail/poetry.lock b/polybar/.config/polybar/gmail/poetry.lock @@ -0,0 +1,391 @@ +[[package]] +category = "main" +description = "Extensible memoizing collections and decorators" +name = "cachetools" +optional = false +python-versions = "~=3.5" +version = "4.1.0" + +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2020.4.5.1" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "main" +description = "Google API client core library" +name = "google-api-core" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.17.0" + +[package.dependencies] +google-auth = ">=1.14.0,<2.0dev" +googleapis-common-protos = ">=1.6.0,<2.0dev" +protobuf = ">=3.4.0" +pytz = "*" +requests = ">=2.18.0,<3.0.0dev" +setuptools = ">=34.0.0" +six = ">=1.10.0" + +[package.extras] +grpc = ["grpcio (>=1.8.2,<2.0dev)"] +grpcgcp = ["grpcio-gcp (>=0.2.2)"] +grpcio-gcp = ["grpcio-gcp (>=0.2.2)"] + +[[package]] +category = "main" +description = "Google API Client Library for Python" +name = "google-api-python-client" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.8.2" + +[package.dependencies] +google-api-core = ">=1.13.0,<2dev" +google-auth = ">=1.4.1" +google-auth-httplib2 = ">=0.0.3" +httplib2 = ">=0.9.2,<1dev" +six = ">=1.6.1,<2dev" +uritemplate = ">=3.0.0,<4dev" + +[[package]] +category = "main" +description = "Google Authentication Library" +name = "google-auth" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.14.2" + +[package.dependencies] +cachetools = ">=2.0.0,<5.0" +pyasn1-modules = ">=0.2.1" +rsa = ">=3.1.4,<4.1" +setuptools = ">=40.3.0" +six = ">=1.9.0" + +[[package]] +category = "main" +description = "Google Authentication Library: httplib2 transport" +name = "google-auth-httplib2" +optional = false +python-versions = "*" +version = "0.0.3" + +[package.dependencies] +google-auth = "*" +httplib2 = ">=0.9.1" + +[[package]] +category = "main" +description = "Google Authentication Library" +name = "google-auth-oauthlib" +optional = false +python-versions = "*" +version = "0.4.1" + +[package.dependencies] +google-auth = "*" +requests-oauthlib = ">=0.7.0" + +[package.extras] +tool = ["click"] + +[[package]] +category = "main" +description = "Common protobufs used in Google APIs" +name = "googleapis-common-protos" +optional = false +python-versions = "*" +version = "1.51.0" + +[package.dependencies] +protobuf = ">=3.6.0" + +[package.extras] +grpc = ["grpcio (>=1.0.0)"] + +[[package]] +category = "main" +description = "A comprehensive HTTP client library." +name = "httplib2" +optional = false +python-versions = "*" +version = "0.17.3" + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.9" + +[[package]] +category = "main" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +name = "oauthlib" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.1.0" + +[package.extras] +rsa = ["cryptography"] +signals = ["blinker"] +signedtoken = ["cryptography", "pyjwt (>=1.0.0)"] + +[[package]] +category = "main" +description = "Protocol Buffers" +name = "protobuf" +optional = false +python-versions = "*" +version = "3.11.3" + +[package.dependencies] +setuptools = "*" +six = ">=1.9" + +[[package]] +category = "main" +description = "ASN.1 types and codecs" +name = "pyasn1" +optional = false +python-versions = "*" +version = "0.4.8" + +[[package]] +category = "main" +description = "A collection of ASN.1-based protocols modules." +name = "pyasn1-modules" +optional = false +python-versions = "*" +version = "0.2.8" + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.5.0" + +[[package]] +category = "main" +description = "World timezone definitions, modern and historical" +name = "pytz" +optional = false +python-versions = "*" +version = "2020.1" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.23.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + +[[package]] +category = "main" +description = "OAuthlib authentication support for Requests." +name = "requests-oauthlib" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib (>=3.0.0)"] + +[[package]] +category = "main" +description = "Pure-Python RSA implementation" +name = "rsa" +optional = false +python-versions = "*" +version = "4.0" + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +category = "main" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.14.0" + +[[package]] +category = "main" +description = "URI templates" +name = "uritemplate" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.0.1" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.25.9" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + +[metadata] +content-hash = "468168e9c86bc0321220d5fceab4632c5ec02490cf9dc22e4d213f04155e42a5" +python-versions = "^3.8" + +[metadata.files] +cachetools = [ + {file = "cachetools-4.1.0-py3-none-any.whl", hash = "sha256:de5d88f87781602201cde465d3afe837546663b168e8b39df67411b0bf10cefc"}, + {file = "cachetools-4.1.0.tar.gz", hash = "sha256:1d057645db16ca7fe1f3bd953558897603d6f0b9c51ed9d11eb4d071ec4e2aab"}, +] +certifi = [ + {file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"}, + {file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"}, +] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] +google-api-core = [ + {file = "google-api-core-1.17.0.tar.gz", hash = "sha256:e4082a0b479dc2dee2f8d7b80ea8b5d0184885b773caab15ab1836277a01d689"}, + {file = "google_api_core-1.17.0-py2.py3-none-any.whl", hash = "sha256:c0e430658ed6be902d7ba7095fb0a9cac810270d71bf7ac4484e76c300407aae"}, +] +google-api-python-client = [ + {file = "google-api-python-client-1.8.2.tar.gz", hash = "sha256:bf482c13fb41a6d01770f9d62be6b33fdcd41d68c97f2beb9be02297bdd9e725"}, + {file = "google_api_python_client-1.8.2-py3-none-any.whl", hash = "sha256:8dd35a3704650c2db44e6cf52abdaf9de71f409c93c56bbe48a321ab5e14ebad"}, +] +google-auth = [ + {file = "google-auth-1.14.2.tar.gz", hash = "sha256:2243db98475f7f2033c41af5185333cbf13780e8f5f96eaadd997c6f34181dcc"}, + {file = "google_auth-1.14.2-py2.py3-none-any.whl", hash = "sha256:23cfeeb71d98b7f51cd33650779d35291aeb8b23384976d497805d12eefc6e9b"}, +] +google-auth-httplib2 = [ + {file = "google-auth-httplib2-0.0.3.tar.gz", hash = "sha256:098fade613c25b4527b2c08fa42d11f3c2037dda8995d86de0745228e965d445"}, + {file = "google_auth_httplib2-0.0.3-py2.py3-none-any.whl", hash = "sha256:f1c437842155680cf9918df9bc51c1182fda41feef88c34004bd1978c8157e08"}, +] +google-auth-oauthlib = [ + {file = "google-auth-oauthlib-0.4.1.tar.gz", hash = "sha256:88d2cd115e3391eb85e1243ac6902e76e77c5fe438b7276b297fbe68015458dd"}, + {file = "google_auth_oauthlib-0.4.1-py2.py3-none-any.whl", hash = "sha256:a92a0f6f41a0fb6138454fbc02674e64f89d82a244ea32f98471733c8ef0e0e1"}, +] +googleapis-common-protos = [ + {file = "googleapis-common-protos-1.51.0.tar.gz", hash = "sha256:013c91704279119150e44ef770086fdbba158c1f978a6402167d47d5409e226e"}, +] +httplib2 = [ + {file = "httplib2-0.17.3-py3-none-any.whl", hash = "sha256:6d9722decd2deacd486ef10c5dd5e2f120ca3ba8736842b90509afcdc16488b1"}, + {file = "httplib2-0.17.3.tar.gz", hash = "sha256:39dd15a333f67bfb70798faa9de8a6e99c819da6ad82b77f9a259a5c7b1225a2"}, +] +idna = [ + {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, + {file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"}, +] +oauthlib = [ + {file = "oauthlib-3.1.0-py2.py3-none-any.whl", hash = "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"}, + {file = "oauthlib-3.1.0.tar.gz", hash = "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889"}, +] +protobuf = [ + {file = "protobuf-3.11.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ef2c2e56aaf9ee914d3dccc3408d42661aaf7d9bb78eaa8f17b2e6282f214481"}, + {file = "protobuf-3.11.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:dd9aa4401c36785ea1b6fff0552c674bdd1b641319cb07ed1fe2392388e9b0d7"}, + {file = "protobuf-3.11.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:310a7aca6e7f257510d0c750364774034272538d51796ca31d42c3925d12a52a"}, + {file = "protobuf-3.11.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:e512b7f3a4dd780f59f1bf22c302740e27b10b5c97e858a6061772668cd6f961"}, + {file = "protobuf-3.11.3-cp35-cp35m-win32.whl", hash = "sha256:fdfb6ad138dbbf92b5dbea3576d7c8ba7463173f7d2cb0ca1bd336ec88ddbd80"}, + {file = "protobuf-3.11.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e2f8a75261c26b2f5f3442b0525d50fd79a71aeca04b5ec270fc123536188306"}, + {file = "protobuf-3.11.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c40973a0aee65422d8cb4e7d7cbded95dfeee0199caab54d5ab25b63bce8135a"}, + {file = "protobuf-3.11.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:adf0e4d57b33881d0c63bb11e7f9038f98ee0c3e334c221f0858f826e8fb0151"}, + {file = "protobuf-3.11.3-cp36-cp36m-win32.whl", hash = "sha256:0bae429443cc4748be2aadfdaf9633297cfaeb24a9a02d0ab15849175ce90fab"}, + {file = "protobuf-3.11.3-cp36-cp36m-win_amd64.whl", hash = "sha256:e11df1ac6905e81b815ab6fd518e79be0a58b5dc427a2cf7208980f30694b956"}, + {file = "protobuf-3.11.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7774bbbaac81d3ba86de646c39f154afc8156717972bf0450c9dbfa1dc8dbea2"}, + {file = "protobuf-3.11.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8eb9c93798b904f141d9de36a0ba9f9b73cc382869e67c9e642c0aba53b0fc07"}, + {file = "protobuf-3.11.3-cp37-cp37m-win32.whl", hash = "sha256:fac513a9dc2a74b99abd2e17109b53945e364649ca03d9f7a0b96aa8d1807d0a"}, + {file = "protobuf-3.11.3-cp37-cp37m-win_amd64.whl", hash = "sha256:82d7ac987715d8d1eb4068bf997f3053468e0ce0287e2729c30601feb6602fee"}, + {file = "protobuf-3.11.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:73152776dc75f335c476d11d52ec6f0f6925774802cd48d6189f4d5d7fe753f4"}, + {file = "protobuf-3.11.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e586072612c1eec18e1174f8e3bb19d08f075fc2e3f91d3b16c919078469d0"}, + {file = "protobuf-3.11.3-py2.7.egg", hash = "sha256:2affcaba328c4662f3bc3c0e9576ea107906b2c2b6422344cdad961734ff6b93"}, + {file = "protobuf-3.11.3-py2.py3-none-any.whl", hash = "sha256:24e3b6ad259544d717902777b33966a1a069208c885576254c112663e6a5bb0f"}, + {file = "protobuf-3.11.3.tar.gz", hash = "sha256:c77c974d1dadf246d789f6dad1c24426137c9091e930dbf50e0a29c1fcf00b1f"}, +] +pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, + {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, + {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, +] +pyasn1-modules = [ + {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, + {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, + {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, + {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, + {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, + {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, + {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, + {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, + {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, + {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, + {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, + {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, +] +pytz = [ + {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, + {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, +] +requests = [ + {file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"}, + {file = "requests-2.23.0.tar.gz", hash = "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"}, +] +requests-oauthlib = [ + {file = "requests-oauthlib-1.3.0.tar.gz", hash = "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"}, + {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"}, + {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"}, +] +rsa = [ + {file = "rsa-4.0-py2.py3-none-any.whl", hash = "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66"}, + {file = "rsa-4.0.tar.gz", hash = "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487"}, +] +six = [ + {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, + {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, +] +uritemplate = [ + {file = "uritemplate-3.0.1-py2.py3-none-any.whl", hash = "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f"}, + {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"}, +] +urllib3 = [ + {file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"}, + {file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"}, +] diff --git a/polybar/.config/polybar/gmail/preview.png b/polybar/.config/polybar/gmail/preview.png Binary files differ. diff --git a/polybar/.config/polybar/gmail/pyproject.toml b/polybar/.config/polybar/gmail/pyproject.toml @@ -0,0 +1,18 @@ +[tool.poetry] +name = "polybar-gmail" +version = "0.1.0" +description = "A Polybar module to show unread messages from Gmail" +authors = ["Vyacheslav Konovalov <vyachkonovalov@protonmail.com>"] +license = "MIT" + +[tool.poetry.dependencies] +python = "^3.8" +google-api-python-client = "^1.8.2" +google-auth-httplib2 = "^0.0.3" +google-auth-oauthlib = "^0.4.1" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/polybar/.config/polybar/launch.sh b/polybar/.config/polybar/launch.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env sh + +killall xembedsniproxy +# Terminate already running bar instances +killall -q polybar + +# Wait until the processes have been shut down +while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done + +m=$(xrandr --query | grep " connected" | grep primary | cut -d" " -f1) +cmd=(env "MONITOR=$m" polybar --reload main) + +if [[ $# -gt 0 ]] && [[ $1 = "block" ]]; then + exec "${cmd[@]}" +else + "${cmd[@]}" & +fi diff --git a/polybar/.config/polybar/spotify/spotify_status.py b/polybar/.config/polybar/spotify/spotify_status.py @@ -0,0 +1,141 @@ +#!/bin/python + +import sys +import dbus +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument( + '-t', + '--trunclen', + type=int, + metavar='trunclen' +) +parser.add_argument( + '-f', + '--format', + type=str, + metavar='custom format', + dest='custom_format' +) +parser.add_argument( + '-p', + '--playpause', + type=str, + metavar='play-pause indicator', + dest='play_pause' +) +parser.add_argument( + '--font', + type=str, + metavar='the index of the font to use for the main label', + dest='font' +) +parser.add_argument( + '--playpause-font', + type=str, + metavar='the index of the font to use to display the playpause indicator', + dest='play_pause_font' +) +parser.add_argument( + '-q', + '--quiet', + action='store_true', + help="if set, don't show any output when the current song is paused", + dest='quiet', +) + +args = parser.parse_args() + + +def fix_string(string): + # corrects encoding for the python version used + if sys.version_info.major == 3: + return string + else: + return string.encode('utf-8') + + +def truncate(name, trunclen): + if len(name) > trunclen: + name = name[:trunclen] + name += '...' + if ('(' in name) and (')' not in name): + name += ')' + return name + + + +# Default parameters +output = fix_string(u'{play_pause} {artist}: {song}') +trunclen = 35 +play_pause = fix_string(u'\u25B6,\u23F8') # first character is play, second is paused + +label_with_font = '%{{T{font}}}{label}%{{T-}}' +font = args.font +play_pause_font = args.play_pause_font + +quiet = args.quiet + +# parameters can be overwritten by args +if args.trunclen is not None: + trunclen = args.trunclen +if args.custom_format is not None: + output = args.custom_format +if args.play_pause is not None: + play_pause = args.play_pause + +try: + session_bus = dbus.SessionBus() + spotify_bus = session_bus.get_object( + 'org.mpris.MediaPlayer2.spotify', + '/org/mpris/MediaPlayer2' + ) + + spotify_properties = dbus.Interface( + spotify_bus, + 'org.freedesktop.DBus.Properties' + ) + + metadata = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'Metadata') + status = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus') + + # Handle play/pause label + + play_pause = play_pause.split(',') + + if status == 'Playing': + play_pause = play_pause[0] + elif status == 'Paused': + play_pause = play_pause[1] + else: + play_pause = str() + + if play_pause_font: + play_pause = label_with_font.format(font=play_pause_font, label=play_pause) + + # Handle main label + + artist = fix_string(metadata['xesam:artist'][0]) if metadata['xesam:artist'] else '' + song = fix_string(metadata['xesam:title']) if metadata['xesam:title'] else '' + album = fix_string(metadata['xesam:album']) if metadata['xesam:album'] else '' + + if (quiet and status == 'Paused') or (not artist and not song and not album): + print('') + else: + if font: + artist = label_with_font.format(font=font, label=artist) + song = label_with_font.format(font=font, label=song) + album = label_with_font.format(font=font, label=album) + + # Add 4 to trunclen to account for status symbol, spaces, and other padding characters + print(truncate(output.format(artist=artist, + song=song, + play_pause=play_pause, + album=album), trunclen + 4)) + +except Exception as e: + if isinstance(e, dbus.exceptions.DBusException): + print('') + else: + print(e) diff --git a/rofi/.config/rofi/config b/rofi/.config/rofi/config @@ -0,0 +1,2 @@ +rofi.theme: ~/.config/rofi/themes/gruvbox/gruvbox-dark-hard.rasi +rofi.modi: window,drun,ssh,run diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-common.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-common.rasi @@ -0,0 +1,127 @@ +/* ========================================================================== + File: gruvbox-common.rasi + Desc: Shared rules between all gruvbox themes + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:06:47 PST -0800 + ========================================================================== */ + +window { + background-color: @background; + border: 2; + padding: 2; +} + +mainbox { + border: 0; + padding: 0; +} + +message { + border: 2px 0 0; + border-color: @separatorcolor; + padding: 1px; +} + +textbox { + highlight: @highlight; + text-color: @foreground; +} + +listview { + border: 2px solid 0 0; + padding: 2px 0 0; + border-color: @separatorcolor; + spacing: 2px; + scrollbar: @scrollbar; +} + +element { + border: 0; + padding: 2px; +} + +element.normal.normal { + background-color: @normal-background; + text-color: @normal-foreground; +} + +element.normal.urgent { + background-color: @urgent-background; + text-color: @urgent-foreground; +} + +element.normal.active { + background-color: @active-background; + text-color: @active-foreground; +} + +element.selected.normal { + background-color: @selected-normal-background; + text-color: @selected-normal-foreground; +} + +element.selected.urgent { + background-color: @selected-urgent-background; + text-color: @selected-urgent-foreground; +} + +element.selected.active { + background-color: @selected-active-background; + text-color: @selected-active-foreground; +} + +element.alternate.normal { + background-color: @alternate-normal-background; + text-color: @alternate-normal-foreground; +} + +element.alternate.urgent { + background-color: @alternate-urgent-background; + text-color: @alternate-urgent-foreground; +} + +element.alternate.active { + background-color: @alternate-active-background; + text-color: @alternate-active-foreground; +} + +scrollbar { + width: 4px; + border: 0; + handle-color: @scrollbar-handle; + handle-width: 8px; + padding: 0; +} + +sidebar { + border: 2px 0 0; + border-color: @separatorcolor; +} + +inputbar { + spacing: 0; + text-color: @normal-foreground; + padding: 2px; + children: [ prompt, textbox-prompt-sep, entry, case-indicator ]; +} + +case-indicator, +entry, +prompt, +button { + spacing: 0; + text-color: @normal-foreground; +} + +button.selected { + background-color: @selected-normal-background; + text-color: @selected-normal-foreground; +} + +textbox-prompt-sep { + expand: false; + str: ":"; + text-color: @normal-foreground; + margin: 0 0.3em 0 0; +} diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-dark-hard.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-dark-hard.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-dark-hard.rasi + Desc: Gruvbox dark (hard contrast) color theme for Rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:04:26 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox dark colors */ + gruvbox-dark-bg0-hard: #1d2021; + gruvbox-dark-bg0: #282828; + gruvbox-dark-bg2: #504945; + gruvbox-dark-fg0: #fbf1c7; + gruvbox-dark-fg1: #ebdbb2; + gruvbox-dark-red-dark: #cc241d; + gruvbox-dark-red-light: #fb4934; + gruvbox-dark-yellow-dark: #d79921; + gruvbox-dark-yellow-light: #fabd2f; + gruvbox-dark-gray: #a89984; + + /* Theme colors */ + background: @gruvbox-dark-bg0-hard; + background-color: @background; + foreground: @gruvbox-dark-fg1; + border-color: @gruvbox-dark-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-dark-bg0; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-dark-bg2; + selected-normal-foreground: @gruvbox-dark-fg0; + + active-background: @gruvbox-dark-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-dark-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-dark-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-dark-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-dark-soft.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-dark-soft.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-dark-soft.rasi + Desc: Gruvbox dark (soft contrast) color theme for Rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:04:37 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox dark colors */ + gruvbox-dark-bg0-soft: #32302f; + gruvbox-dark-bg1: #3c3836; + gruvbox-dark-bg3: #665c54; + gruvbox-dark-fg0: #fbf1c7; + gruvbox-dark-fg1: #ebdbb2; + gruvbox-dark-red-dark: #cc241d; + gruvbox-dark-red-light: #fb4934; + gruvbox-dark-yellow-dark: #d79921; + gruvbox-dark-yellow-light: #fabd2f; + gruvbox-dark-gray: #a89984; + + /* Theme colors */ + background: @gruvbox-dark-bg0-soft; + background-color: @background; + foreground: @gruvbox-dark-fg1; + border-color: @gruvbox-dark-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-dark-bg1; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-dark-bg3; + selected-normal-foreground: @gruvbox-dark-fg0; + + active-background: @gruvbox-dark-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-dark-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-dark-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-dark-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-dark.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-dark.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-dark.rasi + Desc: Gruvbox dark color theme for Rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 04:08:43 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox dark colors */ + gruvbox-dark-bg0: #282828; + gruvbox-dark-bg0-soft: #32302f; + gruvbox-dark-bg3: #665c54; + gruvbox-dark-fg0: #fbf1c7; + gruvbox-dark-fg1: #ebdbb2; + gruvbox-dark-red-dark: #cc241d; + gruvbox-dark-red-light: #fb4934; + gruvbox-dark-yellow-dark: #d79921; + gruvbox-dark-yellow-light: #fabd2f; + gruvbox-dark-gray: #a89984; + + /* Theme colors */ + background: @gruvbox-dark-bg0; + background-color: @background; + foreground: @gruvbox-dark-fg1; + border-color: @gruvbox-dark-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-dark-bg0-soft; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-dark-bg3; + selected-normal-foreground: @gruvbox-dark-fg0; + + active-background: @gruvbox-dark-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-dark-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-dark-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-dark-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-light-hard.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-light-hard.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-light-hard.rasi + Desc: Gruvbox light (hard contrast) color theme for Rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:04:48 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox light colors */ + gruvbox-light-bg0-hard: #f9f5d7; + gruvbox-light-bg0: #fbf1c7; + gruvbox-light-bg1: #ebdbb2; + gruvbox-light-fg0: #282828; + gruvbox-light-fg1: #3c3836; + gruvbox-light-red-dark: #9d0006; + gruvbox-light-red-light: #cc241d; + gruvbox-light-yellow-dark: #b57614; + gruvbox-light-yellow-light: #d79921; + gruvbox-light-gray: #7c6f64; + + /* Theme colors */ + background: @gruvbox-light-bg0-hard; + background-color: @background; + foreground: @gruvbox-light-fg1; + border-color: @gruvbox-light-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-light-bg0; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-light-bg1; + selected-normal-foreground: @gruvbox-light-fg0; + + active-background: @gruvbox-light-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-light-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-light-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-light-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-light-soft.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-light-soft.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-light-soft.rasi + Desc: Gruvbox light (soft contrast) color theme for Rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:05:38 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox light colors */ + gruvbox-light-bg0-soft: #f2e5bc; + gruvbox-light-bg1: #ebdbb2; + gruvbox-light-bg2: #d5c4a1; + gruvbox-light-fg0: #282828; + gruvbox-light-fg1: #3c3836; + gruvbox-light-red-dark: #9d0006; + gruvbox-light-red-light: #cc241d; + gruvbox-light-yellow-dark: #b57614; + gruvbox-light-yellow-light: #d79921; + gruvbox-light-gray: #7c6f64; + + /* Theme colors */ + background: @gruvbox-light-bg0-soft; + background-color: @background; + foreground: @gruvbox-light-fg1; + border-color: @gruvbox-light-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-light-bg1; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-light-bg2; + selected-normal-foreground: @gruvbox-light-fg0; + + active-background: @gruvbox-light-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-light-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-light-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-light-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/rofi/.config/rofi/themes/gruvbox/gruvbox-light.rasi b/rofi/.config/rofi/themes/gruvbox/gruvbox-light.rasi @@ -0,0 +1,62 @@ +/* ========================================================================== + Rofi color theme + + Based on the Gruvbox color scheme for Vim by morhetz + https://github.com/morhetz/gruvbox + + File: gruvbox-light.rasi + Desc: Gruvbox light color theme for rofi + Author: bardisty <b@bah.im> + Source: https://github.com/bardisty/gruvbox-rofi + Modified: Mon Feb 12 2018 06:06:06 PST -0800 + ========================================================================== */ + +* { + /* Theme settings */ + highlight: bold italic; + scrollbar: true; + + /* Gruvbox light colors */ + gruvbox-light-bg0: #fbf1c7; + gruvbox-light-bg0-soft: #f2e5bc; + gruvbox-light-bg2: #d5c4a1; + gruvbox-light-fg0: #282828; + gruvbox-light-fg1: #3c3836; + gruvbox-light-gray: #7c6f64; + gruvbox-light-red-dark: #9d0006; + gruvbox-light-red-light: #cc241d; + gruvbox-light-yellow-dark: #b57614; + gruvbox-light-yellow-light: #d79921; + + /* Theme colors */ + background: @gruvbox-light-bg0; + background-color: @background; + foreground: @gruvbox-light-fg1; + border-color: @gruvbox-light-gray; + separatorcolor: @border-color; + scrollbar-handle: @border-color; + + normal-background: @background; + normal-foreground: @foreground; + alternate-normal-background: @gruvbox-light-bg0-soft; + alternate-normal-foreground: @foreground; + selected-normal-background: @gruvbox-light-bg2; + selected-normal-foreground: @gruvbox-light-fg0; + + active-background: @gruvbox-light-yellow-dark; + active-foreground: @background; + alternate-active-background: @active-background; + alternate-active-foreground: @active-foreground; + selected-active-background: @gruvbox-light-yellow-light; + selected-active-foreground: @active-foreground; + + urgent-background: @gruvbox-light-red-dark; + urgent-foreground: @background; + alternate-urgent-background: @urgent-background; + alternate-urgent-foreground: @urgent-foreground; + selected-urgent-background: @gruvbox-light-red-light; + selected-urgent-foreground: @urgent-foreground; +} + +@import "gruvbox-common.rasi" + diff --git a/tmux/.config/tmux/plugins/tpm b/tmux/.config/tmux/plugins/tpm @@ -0,0 +1 @@ +Subproject commit 5c4f37a52d05022d689fb4364a53cfe78d83dc75 diff --git a/tmux/.config/tmux/tmux.conf b/tmux/.config/tmux/tmux.conf @@ -0,0 +1,84 @@ +set -g default-terminal "screen-256color" +set -g set-titles on +set -g set-titles-string "#T@#H" +set -g pane-border-format "#T@#H" +set-window-option -g automatic-rename off +set-option -g allow-rename off +set -g message-style bg=colour0,fg=colour1 +set -g mode-style bg=colour3,fg=colour0 +set -g message-command-style bg=colour0 + +## +## Navigation +## +setw -g mode-keys vi +unbind l +bind h select-pane -L +bind l select-pane -R +bind j select-pane -D +bind k select-pane -U +bind -r H resize-pane -L 2 +bind -r J resize-pane -D 2 +bind -r K resize-pane -U 2 +bind -r L resize-pane -R 2 +set -s escape-time 0 + +unbind C-b + +set -g prefix C-a +bind-key C-a last-window + +unbind % +bind-key b set status + +bind-key - split-window -v -c '#{pane_current_path}' +bind-key | split-window -h -c '#{pane_current_path}' + +bind-key c new-window -c '#{pane_current_path}' + +bind q kill-window +bind Q kill-session + +#Start windows with 1 +set -g base-index 1 +setw -g pane-base-index 1 +set-option -g renumber-windows on + +bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "~/.config/tmux/tmux.conf reloaded" + +# mpc controller +bind -r P run "playerctl play-pause" +bind -r > run "playerctl next" +bind -r < run "playerctl previous" + +#### statusbar #### +# status line +set -g status-justify left +set -g status-bg colour0 +set -g status-fg colour15 +set-option -g status-right "" +set-option -g status-right-length 0 +set-option -g status-left "" + +# panes +set -g pane-active-border-style fg=colour3 + +# window status +set -g status-left '#[bg=colour3]#[fg=colour0]#{?client_prefix,#[bg=colour1],} ❐ #S #{?client_prefix,,}#{?window_zoomed_flag,🔍,}' +set -g window-status-current-format " #[fg=colour1]#[bg=colour0][#I] #W" +set -g window-status-format " #[fg=colour15]#[bg=colour0][#I] #W" + +bind-key S command-prompt -p "join pane from:" "join-pane -s '%%'" +bind-key s command-prompt -p "send pane to:" "join-pane -t '%%'" +bind-key m set-option -g mouse on \; display 'Mouse: ON' +bind-key M set-option -g mouse off \; display 'Mouse: OFF' + +bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel -i -p && xsel -o -p | xsel -i -b" +## +## Plugins +## +# List of plugins +set-environment -g TMUX_PLUGIN_MANAGER_PATH '~/.config/tmux/plugins' +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' +run -b '~/.config/tmux/plugins/tpm/tpm' diff --git a/tmux/.config/tmux/tmux_session.sh b/tmux/.config/tmux/tmux_session.sh @@ -0,0 +1,24 @@ +#! /bin/sh + +if [ ${#} -eq 2 ]; then + echo "Provide a session name" 2>&1 + exit 1 +fi +name=${1} + +if tmux list-sessions | grep "^${name}:"; then + tmux -2 attach-session -d -t ${name} +else + case "${name}" in + freebsd) dir=freebsd/base/head ;; + freebsd-10) dir=freebsd/base/stable/10 ;; + netbsd) dir=netbsd/src ;; + ports) dir=freebsd/ports ;; + *) dir="${name}" ;; + esac + if test -d "os/${dir}"; then + ( cd "os/${dir}" && tmux -2 new-session -s ${name}) + else + ( tmux -2 new-session -s "${name}") + fi +fi diff --git a/zathura/.config/zathura/zathurarc b/zathura/.config/zathura/zathurarc @@ -0,0 +1,4 @@ +set selection-clipboard clipboard +set highlight-color "#A10C00" +set highlight-active-color "#0E028D" +set highlight-transparency 0.3 diff --git a/zsh/.config/zsh/.zshrc b/zsh/.config/zsh/.zshrc @@ -0,0 +1,27 @@ +autoload -U colors && colors + +# History in cache directory: +HISTSIZE=10000 +SAVEHIST=10000 +HISTFILE=$XDG_CONFIG_HOME/zsh/history +LSCOLORS="Gxfxcxdxbxegedabagacad" + +export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +source /usr/share/zsh/share/antigen.zsh +antigen bundle zsh-users/zsh-completions +antigen bundle Tarrasch/zsh-autoenv +antigen use oh-my-zsh +antigen bundle git +antigen bundle fzf +antigen theme $XDG_CONFIG_HOME/zsh/themes --no-local-clone +antigen apply + +alias s="$XDG_CONFIG_HOME/tmux/tmux_session.sh" +alias ls="exa" + +source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh 2>/dev/null + +[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh +source $XDG_CONFIG_HOME/cargo/env diff --git a/zsh/.config/zsh/themes/beto_prompt.zsh-theme b/zsh/.config/zsh/themes/beto_prompt.zsh-theme @@ -0,0 +1,110 @@ +# BOLD Arrow ZSH Theme +# Based on AVIT theme + +# PROMPT='%B%{fg[red]%}[%{fg[yellow]%}%n%{$fg[green]%}]' +# $(_user_host)%{$fg_bold[white]%}%c $(git_prompt_info) $(_ruby_version)%{$fg[$CARETCOLOR]%}❱%{$resetcolor%} ' +PROMPT='%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[green]%}%c%{$fg[red]%}]%{$reset_color%}$(git_prompt_info) $ ' +# PROMPT2='%{$fg[$CARETCOLOR]%}◀%{$reset_color%} ' + +# RPROMPT='$(_vi_status)%{$(echotc UP 1)%}$(_git_time_since_commit) $(git_prompt_status) ${_return_status}%{$(echotc DO 1)%}' + +# local _current_dir="%{$fg_bold[blue]%}%3~%{$reset_color%} " +local _return_status="%{$fg_bold[red]%}%(?..⍉)%{$reset_color%}" +local _hist_no="%{$fg[grey]%}%h%{$reset_color%}" + +# function _current_dir() { +# local _max_pwd_length="65" +# if [[ $(echo -n $PWD | wc -c) -gt ${_max_pwd_length} ]]; then +# echo "%{$fg_bold[blue]%}%-2~ ... %3~%{$reset_color%} " +# else +# echo "%{$fg_bold[blue]%}%~%{$reset_color%} " +# fi +# } + +function _user_host() { + if [[ -n $SSH_CONNECTION ]]; then + me="%n@%m" + elif [[ $LOGNAME != $USER ]]; then + me="%n" + fi + if [[ -n $me ]]; then + echo "%{$fg[cyan]%}$me%{$reset_color%}:" + fi +} + +function _vi_status() { + if {echo $fpath | grep -q "plugins/vi-mode"}; then + echo "$(vi_mode_prompt_info)" + fi +} + +function _ruby_version() { + if {echo $fpath | grep -q "plugins/rvm"}; then + echo "%{$fg[grey]%}$(rvm_prompt_info)%{$reset_color%}" + elif {echo $fpath | grep -q "plugins/rbenv"}; then + echo "%{$fg[grey]%}$(rbenv_prompt_info)%{$reset_color%}" + fi +} + +# Determine the time since last commit. If branch is clean, +# use a neutral color, otherwise colors will vary according to time. +function _git_time_since_commit() { +# Only proceed if there is actually a commit. + if git log -1 > /dev/null 2>&1; then + # Get the last commit. + last_commit=$(git log --pretty=format:'%at' -1 2> /dev/null) + now=$(date +%s) + seconds_since_last_commit=$((now-last_commit)) + + # Totals + minutes=$((seconds_since_last_commit / 60)) + hours=$((seconds_since_last_commit/3600)) + + # Sub-hours and sub-minutes + days=$((seconds_since_last_commit / 86400)) + sub_hours=$((hours % 24)) + sub_minutes=$((minutes % 60)) + + if [ $hours -gt 24 ]; then + commit_age="${days}d" + elif [ $minutes -gt 60 ]; then + commit_age="${sub_hours}h${sub_minutes}m" + else + commit_age="${minutes}m" + fi + + color=$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL + echo "$color$commit_age%{$reset_color%}" + fi +} + +if [[ $USER == "root" ]]; then + CARETCOLOR="red" +else + CARETCOLOR="red" +fi + +MODE_INDICATOR="%{$fg_bold[yellow]%}❮%{$reset_color%}%{$fg[yellow]%}❮❮%{$reset_color%}" + +ZSH_THEME_GIT_PROMPT_PREFIX=" %B(%{$fg[green]%}" +ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg_bold[white]%})%{$reset_color%}" + +ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%}✚ " +ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%}⚑ " +ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}✖ " +ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}▴ " +ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[cyan]%}§ " +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[white]%}◒ " + +# Colors vary depending on time lapsed. +ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}" +ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}" +ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}" +ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[white]%}" + +# LS colors, made with http://geoff.greer.fm/lscolors/ +export LSCOLORS="exfxcxdxbxegedabagacad" +export LS_COLORS='di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:' +export GREP_COLOR='1;33' diff --git a/zsh/.config/zsh/themes/beto_prompt.zsh-theme.antigen-compat b/zsh/.config/zsh/themes/beto_prompt.zsh-theme.antigen-compat @@ -0,0 +1,111 @@ +# Generated by Antigen. Do not edit! +# BOLD Arrow ZSH Theme +# Based on AVIT theme + +# PROMPT='%B%{fg[red]%}[%{fg[yellow]%}%n%{$fg[green]%}]' +# $(_user_host)%{$fg_bold[white]%}%c $(git_prompt_info) $(_ruby_version)%{$fg[$CARETCOLOR]%}❱%{$resetcolor%} ' +PROMPT='%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[green]%}%c%{$fg[red]%}]%{$reset_color%}$(git_prompt_info) $ ' +# PROMPT2='%{$fg[$CARETCOLOR]%}◀%{$reset_color%} ' + +# RPROMPT='$(_vi_status)%{$(echotc UP 1)%}$(_git_time_since_commit) $(git_prompt_status) ${_return_status}%{$(echotc DO 1)%}' + +# local _current_dir="%{$fg_bold[blue]%}%3~%{$reset_color%} " +_return_status="%{$fg_bold[red]%}%(?..⍉)%{$reset_color%}" +_hist_no="%{$fg[grey]%}%h%{$reset_color%}" + +# function _current_dir() { +# local _max_pwd_length="65" +# if [[ $(echo -n $PWD | wc -c) -gt ${_max_pwd_length} ]]; then +# echo "%{$fg_bold[blue]%}%-2~ ... %3~%{$reset_color%} " +# else +# echo "%{$fg_bold[blue]%}%~%{$reset_color%} " +# fi +# } + +function _user_host() { + if [[ -n $SSH_CONNECTION ]]; then + me="%n@%m" + elif [[ $LOGNAME != $USER ]]; then + me="%n" + fi + if [[ -n $me ]]; then + echo "%{$fg[cyan]%}$me%{$reset_color%}:" + fi +} + +function _vi_status() { + if {echo $fpath | grep -q "plugins/vi-mode"}; then + echo "$(vi_mode_prompt_info)" + fi +} + +function _ruby_version() { + if {echo $fpath | grep -q "plugins/rvm"}; then + echo "%{$fg[grey]%}$(rvm_prompt_info)%{$reset_color%}" + elif {echo $fpath | grep -q "plugins/rbenv"}; then + echo "%{$fg[grey]%}$(rbenv_prompt_info)%{$reset_color%}" + fi +} + +# Determine the time since last commit. If branch is clean, +# use a neutral color, otherwise colors will vary according to time. +function _git_time_since_commit() { +# Only proceed if there is actually a commit. + if git log -1 > /dev/null 2>&1; then + # Get the last commit. + last_commit=$(git log --pretty=format:'%at' -1 2> /dev/null) + now=$(date +%s) + seconds_since_last_commit=$((now-last_commit)) + + # Totals + minutes=$((seconds_since_last_commit / 60)) + hours=$((seconds_since_last_commit/3600)) + + # Sub-hours and sub-minutes + days=$((seconds_since_last_commit / 86400)) + sub_hours=$((hours % 24)) + sub_minutes=$((minutes % 60)) + + if [ $hours -gt 24 ]; then + commit_age="${days}d" + elif [ $minutes -gt 60 ]; then + commit_age="${sub_hours}h${sub_minutes}m" + else + commit_age="${minutes}m" + fi + + color=$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL + echo "$color$commit_age%{$reset_color%}" + fi +} + +if [[ $USER == "root" ]]; then + CARETCOLOR="red" +else + CARETCOLOR="red" +fi + +MODE_INDICATOR="%{$fg_bold[yellow]%}❮%{$reset_color%}%{$fg[yellow]%}❮❮%{$reset_color%}" + +ZSH_THEME_GIT_PROMPT_PREFIX=" %B(%{$fg[green]%}" +ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg_bold[white]%})%{$reset_color%}" + +ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%}✚ " +ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%}⚑ " +ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}✖ " +ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}▴ " +ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[cyan]%}§ " +ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[white]%}◒ " + +# Colors vary depending on time lapsed. +ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}" +ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}" +ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}" +ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[white]%}" + +# LS colors, made with http://geoff.greer.fm/lscolors/ +export LSCOLORS="exfxcxdxbxegedabagacad" +export LS_COLORS='di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:' +export GREP_COLOR='1;33' diff --git a/zsh/.fzf.bash b/zsh/.fzf.bash @@ -0,0 +1,13 @@ +# Setup fzf +# --------- +if [[ ! "$PATH" == *$HOME/.fzf/bin* ]]; then + export PATH="${PATH:+${PATH}:}$HOME/.fzf/bin" +fi + +# Auto-completion +# --------------- +[[ $- == *i* ]] && source "$HOME/.fzf/shell/completion.bash" 2> /dev/null + +# Key bindings +# ------------ +source "$HOME/.fzf/shell/key-bindings.bash" diff --git a/zsh/.fzf.zsh b/zsh/.fzf.zsh @@ -0,0 +1,13 @@ +# Setup fzf +# --------- +if [[ ! "$PATH" == *$HOME/.fzf/bin* ]]; then + export PATH="${PATH:+${PATH}:}$HOME/.fzf/bin" +fi + +# Auto-completion +# --------------- +[[ $- == *i* ]] && source "$HOME/.fzf/shell/completion.zsh" 2> /dev/null + +# Key bindings +# ------------ +source "$HOME/.fzf/shell/key-bindings.zsh" diff --git a/zsh/.zprofile b/zsh/.zprofile @@ -0,0 +1,8 @@ +export EDITOR='nvim' +export PATH="$PATH:$HOME/.local/bin:$CARGO_HOME/bin" +export XDG_CONFIG_HOME="$HOME/.config" +export ADOTDIR="$XDG_CONFIG_HOME/antigen" +export CARGO_HOME="$XDG_CONFIG_HOME/cargo" +export RUSTUP_HOME="$XDG_CONFIG_HOME/rustup" +export AWT_TOOLKIT=MToolkit +export _JAVA_AWT_WM_NONREPARENTING=1