diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc new file mode 100644 index 0000000..c532555 --- /dev/null +++ b/.config/dunst/dunstrc @@ -0,0 +1,414 @@ +[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 = none + + # 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 elxse + # 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 = "300x5-30-20" + + # 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 = 16 + + # 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 = "#7f3fbf" + + # 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 = auto + + # 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 = Noto Sans Regular 9 + + # 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: + # bold + # italic + # strikethrough + # underline + # + # For a complete reference see + # . + # + # 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 = no + + # 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 = "%s\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # 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 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/ + icon_path = /usr/share/icons/Paper/16x16/status/:/usr/share/icons/Paper/16x16/devices/:/usr/share/icons/Paper/16x16/apps/:/usr/share/pixmaps/ + ### 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/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 = 3 + + ### 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 = "#28143c" + foreground = "#ffffff" + timeout = 5 + # Icon for notifications with low urgency, uncomment to enable + icon = /usr/share/icons/Arc-X-D/status/16/dialog-information.png + +[urgency_normal] + background = "#28143c" + foreground = "#ffffff" + timeout = 5 + # Icon for notifications with normal urgency, uncomment to enable + icon = /usr/share/icons/Arc-X-D/status/16/dialog-question.png + +[urgency_critical] + background = "#28143c" + foreground = "#ffffff" + frame_color = "#ff7f7f" + timeout = 120 + # Icon for notifications with critical urgency, uncomment to enable + icon = /usr/share/icons/Arc-X-D/status/16/dialog-warning.png + +# 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/.config/git/ignore b/.config/git/ignore new file mode 100755 index 0000000..a49b79c --- /dev/null +++ b/.config/git/ignore @@ -0,0 +1,5 @@ +# Vim directory +.vim/ +.cache/ + +*.lock diff --git a/.config/htop/htoprc b/.config/htop/htoprc new file mode 100644 index 0000000..fbfc7d5 --- /dev/null +++ b/.config/htop/htoprc @@ -0,0 +1,39 @@ +# Beware! This file is rewritten by htop when settings are changed in the interface. +# The parser is also very primitive, and not human-friendly. +fields=0 48 17 18 38 39 40 2 46 47 49 1 +sort_key=47 +sort_direction=1 +tree_sort_key=0 +tree_sort_direction=1 +hide_kernel_threads=1 +hide_userland_threads=0 +shadow_other_users=0 +show_thread_names=0 +show_program_path=0 +highlight_base_name=0 +highlight_megabytes=1 +highlight_threads=1 +highlight_changes=0 +highlight_changes_delay_secs=5 +find_comm_in_cmdline=1 +strip_exe_from_cmdline=1 +show_merged_command=0 +tree_view=0 +tree_view_always_by_pid=0 +header_margin=1 +detailed_cpu_time=0 +cpu_count_from_one=1 +show_cpu_usage=1 +show_cpu_frequency=0 +show_cpu_temperature=0 +degree_fahrenheit=0 +update_process_names=0 +account_guest_in_cpu_meter=0 +color_scheme=0 +enable_mouse=1 +delay=15 +left_meters=LeftCPUs2 Memory Swap +left_meter_modes=1 1 1 +right_meters=RightCPUs2 Tasks LoadAverage Uptime +right_meter_modes=1 2 2 2 +hide_function_bar=0 diff --git a/.config/i3/config b/.config/i3/config new file mode 100755 index 0000000..1dbe221 --- /dev/null +++ b/.config/i3/config @@ -0,0 +1,301 @@ +# =====GENERAL===== +# Main modifier; Mod1 is alt +set $mod Mod1 + +# Modifier for floating-related operations +floating_modifier $mod + +# Layout for new workspaces; default means tiling +workspace_layout default + +#do not show titlebar on windows: +default_border pixel + +# thin borders +hide_edge_borders both + +# Font for window titles & bar, unless specified otherwise +font pango:Noto Sans Regular 8 + + +# =====WINDOW MANAGEMENT===== +# change focus +bindsym $mod+h focus left +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right + +# move focused window +bindsym $mod+Shift+h move left +bindsym $mod+Shift+j move down +bindsym $mod+Shift+k move up +bindsym $mod+Shift+l move right + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# kill focused window +bindsym $mod+x kill + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# Resize focused window +mode "resize" { + bindsym h resize shrink width 10 px or 10 ppt + bindsym j resize shrink height 10 px or 10 ppt + bindsym k resize grow height 10 px or 10 ppt + bindsym l resize grow width 10 px or 10 ppt + + bindsym Escape mode "default" +} + +bindsym $mod+r mode "resize" + +#resize floating windows with mouse scroll: +bindsym --whole-window --border $mod+button4 resize shrink height 5 px or 5 ppt +bindsym --whole-window --border $mod+button5 resize grow height 5 px or 5 ppt +bindsym --whole-window --border $mod+shift+button4 resize shrink width 5 px or 5 ppt +bindsym --whole-window --border $mod+shift+button5 resize grow width 5 px or 5 ppt + + +# =====WORKSPACES===== +set $ws01 "" +set $ws02 "" +set $ws03 "" +set $ws04 "" +set $ws05 "" +set $ws11 "α" +set $ws12 "β" +set $ws13 "γ" +set $ws14 "δ" +set $ws15 "ε" +set $ws21 "2:1" +set $ws22 "2:2" +set $ws23 "2:3" +set $ws24 "2:4" +set $ws25 "2:5" + +workspace $ws01 output primary +workspace $ws02 output primary +workspace $ws03 output primary +workspace $ws04 output primary +workspace $ws05 output primary +workspace $ws11 output eDP-1-1 +workspace $ws12 output eDP-1-1 +workspace $ws13 output eDP-1-1 +workspace $ws14 output eDP-1-1 +workspace $ws15 output eDP-1-1 +workspace $ws21 output HDMI-0 +workspace $ws22 output HDMI-0 +workspace $ws23 output HDMI-0 +workspace $ws24 output HDMI-0 +workspace $ws25 output HDMI-0 + +# switch to main workspaces +bindsym $mod+y workspace $ws01 +bindsym $mod+u workspace $ws02 +bindsym $mod+i workspace $ws03 +bindsym $mod+o workspace $ws04 +bindsym $mod+p workspace $ws05 + +# move focused container to main workspace +bindsym $mod+Shift+y move container to workspace $ws01 +bindsym $mod+Shift+u move container to workspace $ws02 +bindsym $mod+Shift+i move container to workspace $ws03 +bindsym $mod+Shift+o move container to workspace $ws04 +bindsym $mod+Shift+p move container to workspace $ws05 + +# Manage other workspaces +mode "eDP-1-1" { + # switch to workspace + bindsym y workspace $ws11 + bindsym u workspace $ws12 + bindsym i workspace $ws13 + bindsym o workspace $ws14 + bindsym p workspace $ws15 + + # move focused container to workspace + bindsym Shift+y move container to workspace $ws11 + bindsym Shift+u move container to workspace $ws12 + bindsym Shift+i move container to workspace $ws13 + bindsym Shift+o move container to workspace $ws14 + bindsym Shift+p move container to workspace $ws15 + + # Go to HDMI-0 mode + bindsym e mode "HDMI-0" + + # Go back to normal mode + bindsym Escape mode "default" +} + +mode "HDMI-0" { + # switch to workspace + bindsym y workspace $ws21 + bindsym u workspace $ws22 + bindsym i workspace $ws23 + bindsym o workspace $ws24 + bindsym p workspace $ws25 + + # move focused container to workspace + bindsym Shift+y move container to workspace $ws21 + bindsym Shift+u move container to workspace $ws22 + bindsym Shift+i move container to workspace $ws23 + bindsym Shift+o move container to workspace $ws24 + bindsym Shift+p move container to workspace $ws25 + + # Go to eDP-1-1 mode + bindsym e mode "eDP-1-1" + + # Go back to normal mode + bindsym Escape mode "default" +} + +bindsym $mod+e mode "eDP-1-1" + +# Configuration mode +mode "config" { + # Switch split mode + bindsym j split vertical; mode "default" + bindsym h split horizontal; mode "default" + bindsym k split vertical; mode "default" + bindsym l split horizontal; mode "default" + + # Switch layout + bindsym y layout stacking; mode "default" + bindsym u layout tabbed; mode "default" + bindsym i layout toggle split; mode "default" + + # Go back to normal mode + bindsym Escape mode "default" +} + +bindsym $mod+s mode "config" + +# Assign certain programs to workspaces +# for_window [class=Xfce4-terminal] focus +# assign [class="(?i)firefox"] $ws02 +# for_window [class=(?i)firefox] focus +# assign [class="Thunar"] $ws03 +# for_window [class=Thunar] focus +# assign [class="Thunderbird"] $ws04 +# for_window [class=Thunderbird] focus +# assign [class="TelegramDesktop"] $ws05 +# for_window [class=TelegramDesktop] focus + + +# =====OTHER KEYBINDINGS===== +# reload the configuration file +bindsym $mod+Shift+c reload + +# Restart i3 in-place +bindsym $mod+Shift+r restart + +# exit i3 (logs you out of your X session) +bindsym $mod+Shift+q exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" + +# Volume +bindsym XF86AudioRaiseVolume exec amixer -D pulse sset Master 5%+ && pkill -RTMIN+1 i3blocks +bindsym XF86AudioLowerVolume exec amixer -D pulse sset Master 5%- && pkill -RTMIN+1 i3blocks +bindsym $mod+XF86AudioRaiseVolume exec amixer -D pulse sset Master 1%+ && pkill -RTMIN+1 i3blocks +bindsym $mod+XF86AudioLowerVolume exec amixer -D pulse sset Master 1%- && pkill -RTMIN+1 i3blocks +bindsym XF86AudioMute exec amixer -D pulse set Master toggle + +# Foobar2000 controls +bindsym F8 exec --no-startup-id wine ~/.wine/drive_c/users/jjr/Desktop/foobar2000/foobar2000.exe /playpause + +# Backlight +bindsym XF86MonBrightnessUp exec brightnessctl --device='intel_backlight' set +10% +bindsym XF86MonBrightnessDown exec brightnessctl --device='intel_backlight' set 10%- + +# Keyboard brightness +bindsym XF86KbdBrightnessUp exec brightnessctl --device='smc::kbd_backlight' set +10% +bindsym XF86KbdBrightnessDown exec brightnessctl --device='smc::kbd_backlight' set 10%- + +# Screenshot +bindsym Print exec "scrot ~/%Y-%m-%d-%T-screenshot.png" + +# Show shutdown menu +bindsym $mod+Escape exec ~/.config/i3/scripts/shutdown_menu -p rofi -c + + +# =====APPLICATIONS===== +# Launch applications +# start a terminal +bindsym $mod+Return exec --no-startup-id st +# Launch output device configuration +bindsym $mod+m exec --no-startup-id pavucontrol -t 3 +# Open dmenu +bindsym $mod+d exec --no-startup-id i3-dmenu-desktop +# Open Galculator +bindsym XF86Calculator exec --no-startup-id galculator + + +# =====AUTOSTART APPLICATIONS===== +#get auth work with polkit-gnome +exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 +# Run setup script +exec --no-startup-id ~/.config/i3/startup.sh +# Bluetooth applet +exec --no-startup-id blueman-tray +# Nextcloud sync +exec --no-startup-id nextcloud +# Compositor +exec --no-startup-id picom --config ~/.config/picom.conf --experimental-backends +# Network Manager applet +exec --no-startup-id nm-applet +#set powersavings for display +exec --no-startup-id xset s 480 dpms 600 600 600 +# Desktop notifications +exec --no-startup-id /usr/bin/dunst +# Mail notifications +# exec --no-startup-id thunderbird +# Joplin sync +exec --no-startup-id joplin-desktop + + +# =====FLOAT RULES===== +for_window [class="Yad" instance="yad"] floating enable +for_window [class="Galculator" instance="galculator"] floating enable +for_window [class="Xsane" instance="xsane"] floating enable +for_window [class="Pavucontrol" instance="pavucontrol"] floating enable +for_window [class="qt5ct" instance="qt5ct"] floating enable +for_window [class="Blueberry.py" instance="blueberry.py"] floating enable +for_window [class="Bluetooth-sendto" instance="bluetooth-sendto"] floating enable +for_window [class="Gufw.py" instance="gufw.py"] floating enable + + +# =====COLORS===== +set $bg-color #2f343f +set $inactive-bg-color #2f343f +set $text-color #f3f4f5 +set $inactive-text-color #676e7d +set $urgent-bg-color #e53935 +set $indicator-color #a0a0a0 + +# set window colors +# border background text indicator +client.focused $bg-color $bg-color $text-color $indicator-color +client.unfocused $inactive-bg-color $inactive-bg-color $inactive-text-color $indicator-color +client.focused_inactive $inactive-bg-color $inactive-bg-color $inactive-text-color $indicator-color +client.urgent $urgent-bg-color $urgent-bg-color $text-color $indicator-color + + +# =====STATUS BAR===== +bar { + status_command i3blocks -c ~/.config/i3/i3blocks.conf + position bottom + tray_output primary + colors { + separator #666666 + background #222222 + statusline #dddddd + focused_workspace #0088CC #0088CC #ffffff + active_workspace #333333 #333333 #ffffff + inactive_workspace #333333 #333333 #888888 + urgent_workspace #2f343a #900000 #ffffff + } +} diff --git a/.config/i3/i3blocks.conf b/.config/i3/i3blocks.conf new file mode 100755 index 0000000..dcb74f4 --- /dev/null +++ b/.config/i3/i3blocks.conf @@ -0,0 +1,155 @@ +# i3blocks config file + +# source is available here: +# https://raw.githubusercontent.com/endeavouros-team/i3-EndeavourOS/master/.config/i3/i3blocks.conf +# Maintainer: joekamprad [joekamprad@endeavouros.com] +# created for i3wm setup on EndeavourOS +# https://endeavouros.com + +# cheatsheet for icon fonts used on the block-bar: +# https://fontawesome.com/cheatsheet + +# Please see man i3blocks for a complete reference! +# The man page is also hosted at http://vivien.github.io/i3blocks + + +# List of valid properties: +# +# align +# color +# command +# full_text +# instance +# interval +# label +# min_width +# name +# separator +# separator_block_width +# short_text +# signal +# urgent + +# Global properties +# +# The top properties below are applied to every block, but can be overridden. +separator=false +markup=pango + +#[apps] +#full_text=Applications: +#separator=true + +#[terminal] +#full_text=Terminal  +#color=#807dfe +#command=xfce4-terminal +#separator=true +# +#[browser] +#full_text=Browser  +#color=#ff7f81 +#command=firefox +#separator=true +# +#[files] +#full_text=Files  +#color=#7f3fbf +#command=thunar ~/ +#separator=true + +#[mail] +#full_text=Mail  +#color=#dbcb75 +#command=thunderbird +#separator=true + +#[bandwidth] +#command=~/.config/i3/scripts/bandwidth2 +#color=#e07221 +#interval=persist + +# [net] +# label=SSID: +# command=echo "$(LANG=C nmcli d | grep connected | awk '{print $4}')" +# color=#e07221 +# interval=5 +# separator=true + +# Players online on Karaoke server +[karaoke] +label=M +command=mcstatus karaoke.roosens.me status | grep -o '[0-9]*/[0-9]*' +color=#96c6f8 +interval=60 + +# Memory usage +# +# The type defaults to "mem" if the instance is not specified. +[memory] +label= +command=~/.config/i3/scripts/memory +color=#96c6f8 +interval=30 + +# Disk usage +# +# The directory defaults to $HOME if the instance is not specified. +# The script may be called with a optional argument to set the alert +# (defaults to 10 for 10%). +[disk] +label=~ +instance=/home +command=~/.config/i3/scripts/disk +color=#96c6f8 +interval=30 + +[disk] +label= +instance=/ +command=~/.config/i3/scripts/disk +color=#96c6f8 +interval=30 + +[CPU-temperature] +label=CPU +command=~/.config/i3/scripts/temperature --chip coretemp-isa-0000 +color=#96c6f8 +interval=5 + +[cpu_usage] +label= +interval=5 +command=~/.config/i3/scripts/cpu_usage +color=#96c6f8 +#min_width=CPU: 100.00% + +# Battery indicator +# +# The battery instance defaults to 0. +[battery] +command=~/.config/i3/scripts/battery.sh +label= +#instance=1 +interval=30 + +# Volume indicator +[volume-pulseaudio] +label=Vol: +command=~/.config/i3/scripts/volume +color=#208273 +instance=Master +interval=1 + +[time] +label= +command=date '+%a %d %b %Y %H:%M:%S' +color=#dbcb75 +interval=1 + +#[shutdown_menu] +#full_text= +#command=~/.config/i3/scripts/shutdown_menu -p rofi -c; +#color=#96c6f8 + + diff --git a/.config/i3/scripts/bandwidth2 b/.config/i3/scripts/bandwidth2 new file mode 100755 index 0000000..d21aefa --- /dev/null +++ b/.config/i3/scripts/bandwidth2 @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2015 James Murphy +# Licensed under the terms of the GNU GPL v2 only. +# +# i3blocks blocklet script to monitor bandwidth usage + +iface="${BLOCK_INSTANCE}" +iface="${IFACE:-$iface}" +dt="${DT:-3}" +unit="${UNIT:-Mb}" +LABEL="${LABEL:-}" # down arrow up arrow +printf_command="${PRINTF_COMMAND:-"printf \"${LABEL}%-5.1f/%5.1f %s/s\\n\", rx, wx, unit;"}" + +function default_interface { + ip route | awk '/^default via/ {print $5; exit}' +} + +function check_proc_net_dev { + if [ ! -f "/proc/net/dev" ]; then + echo "/proc/net/dev not found" + exit 1 + fi +} + +function list_interfaces { + check_proc_net_dev + echo "Interfaces in /proc/net/dev:" + grep -o "^[^:]\\+:" /proc/net/dev | tr -d " :" +} + +while getopts i:t:u:p:lh opt; do + case "$opt" in + i) iface="$OPTARG" ;; + t) dt="$OPTARG" ;; + u) unit="$OPTARG" ;; + p) printf_command="$OPTARG" ;; + l) list_interfaces && exit 0 ;; + h) printf \ +"Usage: bandwidth3 [-i interface] [-t time] [-u unit] [-p printf_command] [-l] [-h] +Options: +-i\tNetwork interface to measure. Default determined using \`ip route\`. +-t\tTime interval in seconds between measurements. Default: 3 +-u\tUnits to measure bytes in. Default: Mb +\tAllowed units: Kb, KB, Mb, MB, Gb, GB, Tb, TB +\tUnits may have optional it/its/yte/ytes on the end, e.g. Mbits, KByte +-p\tAwk command to be called after a measurement is made. +\tDefault: printf \" %%-5.1f/%%5.1f %%s/s\\\\n\", rx, wx, unit; +\tExposed variables: rx, wx, tx, unit, iface +-l\tList available interfaces in /proc/net/dev +-h\tShow this help text +" && exit 0;; + esac +done + +check_proc_net_dev + +iface="${iface:-$(default_interface)}" +while [ -z "$iface" ]; do + echo No default interface + sleep "$dt" + iface=$(default_interface) +done + +case "$unit" in + Kb|Kbit|Kbits) bytes_per_unit=$((1024 / 8));; + KB|KByte|KBytes) bytes_per_unit=$((1024));; + Mb|Mbit|Mbits) bytes_per_unit=$((1024 * 1024 / 8));; + MB|MByte|MBytes) bytes_per_unit=$((1024 * 1024));; + Gb|Gbit|Gbits) bytes_per_unit=$((1024 * 1024 * 1024 / 8));; + GB|GByte|GBytes) bytes_per_unit=$((1024 * 1024 * 1024));; + Tb|Tbit|Tbits) bytes_per_unit=$((1024 * 1024 * 1024 * 1024 / 8));; + TB|TByte|TBytes) bytes_per_unit=$((1024 * 1024 * 1024 * 1024));; + *) echo Bad unit "$unit" && exit 1;; +esac + +scalar=$((bytes_per_unit * dt)) +init_line=$(cat /proc/net/dev | grep "^[ ]*$iface:") +if [ -z "$init_line" ]; then + echo Interface not found in /proc/net/dev: "$iface" + exit 1 +fi + +init_received=$(awk '{print $2}' <<< $init_line) +init_sent=$(awk '{print $10}' <<< $init_line) + +(while true; do cat /proc/net/dev; sleep "$dt"; done) |\ + stdbuf -oL grep "^[ ]*$iface:" |\ + awk -v scalar="$scalar" -v unit="$unit" -v iface="$iface" ' +BEGIN{old_received='"$init_received"';old_sent='"$init_sent"'} +{ + received=$2 + sent=$10 + rx=(received-old_received)/scalar; + wx=(sent-old_sent)/scalar; + tx=rx+wr; + old_received=received; + old_sent=sent; + if(rx >= 0 && wx >= 0){ + '"$printf_command"'; + fflush(stdout); + } +} +' diff --git a/.config/i3/scripts/battery-pinebook-pro.sh b/.config/i3/scripts/battery-pinebook-pro.sh new file mode 100755 index 0000000..142b31f --- /dev/null +++ b/.config/i3/scripts/battery-pinebook-pro.sh @@ -0,0 +1,18 @@ +#!/bin/bash +#simple Shellscript for i3blocks on Pinebook pro +#05012020 geri123@gmx.net Gerhard S. +#battery-symbols: on Manjaro you need the awesome-terminal-fonts package installed! +PERCENT=$(cat /sys/class/power_supply/cw2015-battery/capacity) +STATUS=$(cat /sys/class/power_supply/cw2015-battery/status) +case $(( + $PERCENT >= 0 && $PERCENT <= 20 ? 1 : + $PERCENT > 20 && $PERCENT <= 40 ? 2 : + $PERCENT > 40 && $PERCENT <= 60 ? 3 : + $PERCENT > 60 && $PERCENT <= 80 ? 4 : 5)) in +# + (1) echo $STATUS:"" :$PERCENT%;; + (2) echo $STATUS:"" :$PERCENT%;; + (3) echo $STATUS:"" :$PERCENT%;; + (4) echo $STATUS:"" :$PERCENT%;; + (5) echo $STATUS:"" :$PERCENT%;; +esac diff --git a/.config/i3/scripts/battery.sh b/.config/i3/scripts/battery.sh new file mode 100755 index 0000000..d36acae --- /dev/null +++ b/.config/i3/scripts/battery.sh @@ -0,0 +1,89 @@ +#!/usr/bin/perl +# +# Copyright 2014 Pierre Mavro +# Copyright 2014 Vivien Didelot +# +# Licensed under the terms of the GNU GPL v3, or any later version. +# +# This script is meant to use with i3blocks. It parses the output of the "acpi" +# command (often provided by a package of the same name) to read the status of +# the battery, and eventually its remaining time (to full charge or discharge). +# +# The color will gradually change for a percentage below 85%, and the urgency +# (exit code 33) is set if there is less that 5% remaining. + +use strict; +use warnings; +use utf8; + +my $acpi; +my $status; +my $percent; +my $ac_adapt; +my $full_text; +my $short_text; +my $bat_number = $ENV{BLOCK_INSTANCE} || 0; + +# read the first line of the "acpi" command output +open (ACPI, "acpi -b | grep 'Battery $bat_number' |") or die; +$acpi = ; +close(ACPI); + +# fail on unexpected output +if ($acpi !~ /: (\w+), (\d+)%/) { + die "$acpi\n"; +} + +$status = $1; +$percent = $2; +$full_text = "$percent%"; + +if ($status eq 'Discharging') { + $full_text .= ' DIS'; +} elsif ($status eq 'Charging') { + $full_text .= ' CHR'; +} elsif ($status eq 'Unknown') { + open (AC_ADAPTER, "acpi -a |") or die; + $ac_adapt = ; + close(AC_ADAPTER); + + if ($ac_adapt =~ /: ([\w-]+)/) { + $ac_adapt = $1; + + if ($ac_adapt eq 'on-line') { + $full_text .= ' CHR'; + } elsif ($ac_adapt eq 'off-line') { + $full_text .= ' DIS'; + } + } +} + +$short_text = $full_text; + +if ($acpi =~ /(\d\d:\d\d):/) { + $full_text .= " ($1)"; +} + +# print text +print "$full_text\n"; +print "$short_text\n"; + +# consider color and urgent flag only on discharge +if ($status eq 'Discharging') { + + if ($percent < 20) { + print "#FF0000\n"; + } elsif ($percent < 40) { + print "#FFAE00\n"; + } elsif ($percent < 60) { + print "#FFF600\n"; + } elsif ($percent < 85) { + print "#A8FF00\n"; + } + + if ($percent < 5) { + exit(33); + } +} + +exit(0); diff --git a/.config/i3/scripts/cpu_usage b/.config/i3/scripts/cpu_usage new file mode 100755 index 0000000..44c1189 --- /dev/null +++ b/.config/i3/scripts/cpu_usage @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# +# Copyright 2014 Pierre Mavro +# Copyright 2014 Vivien Didelot +# Copyright 2014 Andreas Guldstrand +# +# Licensed under the terms of the GNU GPL v3, or any later version. + +use strict; +use warnings; +use utf8; +use Getopt::Long; + +# default values +my $t_warn = $ENV{T_WARN} // 50; +my $t_crit = $ENV{T_CRIT} // 80; +my $cpu_usage = -1; +my $decimals = $ENV{DECIMALS} // 2; +my $label = $ENV{LABEL} // ""; + +sub help { + print "Usage: cpu_usage [-w ] [-c ] [-d ]\n"; + print "-w : warning threshold to become yellow\n"; + print "-c : critical threshold to become red\n"; + print "-d : Use decimals for percentage (default is $decimals) \n"; + exit 0; +} + +GetOptions("help|h" => \&help, + "w=i" => \$t_warn, + "c=i" => \$t_crit, + "d=i" => \$decimals, +); + +# Get CPU usage +$ENV{LC_ALL}="en_US"; # if mpstat is not run under en_US locale, things may break, so make sure it is +open (MPSTAT, 'mpstat 1 1 |') or die; +while () { + if (/^.*\s+(\d+\.\d+)[\s\x00]?$/) { + $cpu_usage = 100 - $1; # 100% - %idle + last; + } +} +close(MPSTAT); + +$cpu_usage eq -1 and die 'Can\'t find CPU information'; + +# Print short_text, full_text +print "${label}"; +printf "%.${decimals}f%%\n", $cpu_usage; +print "${label}"; +printf "%.${decimals}f%%\n", $cpu_usage; + +# Print color, if needed +if ($cpu_usage >= $t_crit) { + print "#FF0000\n"; + exit 33; +} elsif ($cpu_usage >= $t_warn) { + print "#FFFC00\n"; +} + +exit 0; diff --git a/.config/i3/scripts/disk b/.config/i3/scripts/disk new file mode 100755 index 0000000..c34240d --- /dev/null +++ b/.config/i3/scripts/disk @@ -0,0 +1,48 @@ +#!/bin/sh +# Copyright (C) 2014 Julien Bonjean + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +DIR="${DIR:-$BLOCK_INSTANCE}" +DIR="${DIR:-$HOME}" +ALERT_LOW="${ALERT_LOW:-$1}" +ALERT_LOW="${ALERT_LOW:-10}" # color will turn red under this value (default: 10%) + +LOCAL_FLAG="-l" +if [ "$1" = "-n" ] || [ "$2" = "-n" ]; then + LOCAL_FLAG="" +fi + +df -h -P $LOCAL_FLAG "$DIR" | awk -v label="$LABEL" -v alert_low=$ALERT_LOW ' +/\/.*/ { + # full text + print label $4 + + # short text + print label $4 + + use=$5 + + # no need to continue parsing + exit 0 +} + +END { + gsub(/%$/,"",use) + if (100 - use < alert_low) { + # color + print "#FF0000" + } +} +' diff --git a/.config/i3/scripts/empty_workspace.sh b/.config/i3/scripts/empty_workspace.sh new file mode 100755 index 0000000..b4c28dc --- /dev/null +++ b/.config/i3/scripts/empty_workspace.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +MAX_DESKTOPS=20 + +WORKSPACES=$(seq -s '\n' 1 1 ${MAX_DESKTOPS}) + +EMPTY_WORKSPACE=$( (i3-msg -t get_workspaces | tr ',' '\n' | grep num | awk -F: '{print int($2)}' ; \ + echo -e ${WORKSPACES} ) | sort -n | uniq -u | head -n 1) + +i3-msg workspace ${EMPTY_WORKSPACE} diff --git a/.config/i3/scripts/exit_menu b/.config/i3/scripts/exit_menu new file mode 100755 index 0000000..35b3231 --- /dev/null +++ b/.config/i3/scripts/exit_menu @@ -0,0 +1,7 @@ +#!/bin/bash +while [ "$select" != "NO" -a "$select" != "YES" ]; do + select=$(echo -e 'NO\nYES' | dmenu -nb '#2f343f' -nf '#f3f4f5' -sb '#9575cd' -sf '#f3f4f5' -fn '-*-*-medium-r-normal-*-*-*-*-*-*-100-*-*' -i -p "Are you sure you want to logout?") + [ -z "$select" ] && exit 0 +done +[ "$select" = "NO" ] && exit 0 +i3-msg exit diff --git a/.config/i3/scripts/memory b/.config/i3/scripts/memory new file mode 100755 index 0000000..90eb2c6 --- /dev/null +++ b/.config/i3/scripts/memory @@ -0,0 +1,69 @@ +#!/bin/sh +# Copyright (C) 2014 Julien Bonjean + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +TYPE="${BLOCK_INSTANCE:-mem}" + +awk -v type=$TYPE ' +/^MemTotal:/ { + mem_total=$2 +} +/^MemFree:/ { + mem_free=$2 +} +/^Buffers:/ { + mem_free+=$2 +} +/^Cached:/ { + mem_free+=$2 +} +/^SwapTotal:/ { + swap_total=$2 +} +/^SwapFree:/ { + swap_free=$2 +} +END { + if (type == "swap") { + free=swap_free/1024/1024 + used=(swap_total-swap_free)/1024/1024 + total=swap_total/1024/1024 + } else { + free=mem_free/1024/1024 + used=(mem_total-mem_free)/1024/1024 + total=mem_total/1024/1024 + } + + pct=0 + if (total > 0) { + pct=used/total*100 + } + + # full text + printf("%.1fG/%.1fG (%.f%%)\n", used, total, pct) + + # short text + printf("%.f%%\n", pct) + + # color + if (pct > 90) { + print("#FF0000") + } else if (pct > 80) { + print("#FFAE00") + } else if (pct > 70) { + print("#FFF600") + } +} +' /proc/meminfo diff --git a/.config/i3/scripts/openweather.conf b/.config/i3/scripts/openweather.conf new file mode 100755 index 0000000..5d5d2e2 --- /dev/null +++ b/.config/i3/scripts/openweather.conf @@ -0,0 +1,8 @@ +# Weather +[Weather] +command=~/.config/i3/scripts/openweather.sh +interval=1800 +color=#7275b3 + + + diff --git a/.config/i3/scripts/openweather.sh b/.config/i3/scripts/openweather.sh new file mode 100755 index 0000000..7fcef77 --- /dev/null +++ b/.config/i3/scripts/openweather.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +command -v jq >/dev/null 2>&1 || { echo >&2 "Program 'jq' required but it is not installed. +Aborting."; exit 1; } +command -v wget >/dev/null 2>&1 || { echo >&2 "Program 'wget' required but is not installed. +Aborting."; exit 1; } + +APIKEY="get your key first" +#ZIPCODE="1234" +CITY_ID="Get your City ID first" +URL="http://api.openweathermap.org/data/2.5/weather?id=${CITY_ID}&units=metric&APPID=${APIKEY}" + +WEATHER_RESPONSE=$(wget -qO- "${URL}") + +WEATHER_CONDITION=$(echo $WEATHER_RESPONSE | jq '.weather[0].main' | sed 's/"//g') +WEATHER_TEMP=$(echo $WEATHER_RESPONSE | jq '.main.temp') +WIND_DIR=$( echo "$WEATHER_RESPONSE" | jq '.wind.deg') +WIND_SPEED=$( echo "$WEATHER_RESPONSE" | jq '.wind.speed') + +WIND_SPEED=$(awk "BEGIN {print 60*60*$WIND_SPEED/1000}") +WIND_DIR=$(awk "BEGIN {print int(($WIND_DIR % 360)/22.5)}") +DIR_ARRAY=( N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N ) +WIND_DIR=${DIR_ARRAY[WIND_DIR]} + +case $WEATHER_CONDITION in + 'Clouds') + WEATHER_ICON="" + ;; + 'Rain') + WEATHER_ICON="" + ;; + 'Snow') + WEATHER_ICON="" + ;; + *) + WEATHER_ICON="" + ;; +esac + +echo "${WEATHER_ICON} ${WEATHER_TEMP}°C: ${WIND_SPEED} km/h ${WIND_DIR}" diff --git a/.config/i3/scripts/shutdown_menu b/.config/i3/scripts/shutdown_menu new file mode 100755 index 0000000..3949d6f --- /dev/null +++ b/.config/i3/scripts/shutdown_menu @@ -0,0 +1,186 @@ +#!/usr/bin/env bash +# +# Use rofi/zenity to change system runstate thanks to systemd. +# +# Note: this currently relies on associative array support in the shell. +# +# Inspired from i3pystatus wiki: +# https://github.com/enkore/i3pystatus/wiki/Shutdown-Menu +# +# Copyright 2015 Benjamin Chrétien +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +####################################################################### +# BEGIN CONFIG # +####################################################################### + +# Use a custom lock script +#LOCKSCRIPT="i3lock-extra -m pixelize" + +# Colors: FG (foreground), BG (background), HL (highlighted) +FG_COLOR="${FG_COLOR:-#bbbbbb}" +BG_COLOR="${BG_COLOR:-#111111}" +HLFG_COLOR="${HLFG_COLOR:-#111111}" +HLBG_COLOR="${HLBG_COLOR:-#bbbbbb}" +BORDER_COLOR="${BORDER_COLOR:-#222222}" + +# Options not related to colors +ROFI_TEXT="${ROFI_TEXT:-Menu:}" +ROFI_OPTIONS=(${ROFI_OPTIONS:--width 11 -location 3 -hide-scrollbar -bw 2}) + +# Zenity options +ZENITY_TITLE="${ZENITY_TITLE:-Menu}" +ZENITY_TEXT="${ZENITY_TEXT:-Action:}" +ZENITY_OPTIONS=(${ZENITY_OPTIONS:---column= --hide-header}) + +####################################################################### +# END CONFIG # +####################################################################### + +# Whether to ask for user's confirmation +enable_confirmation=${ENABLE_CONFIRMATIONS:-false} + +# Preferred launcher if both are available +preferred_launcher="${LAUNCHER:-rofi}" + +usage="$(basename "$0") [-h] [-c] [-p name] -- display a menu for shutdown, reboot, lock etc. + +where: + -h show this help text + -c ask for user confirmation + -p preferred launcher (rofi or zenity) + +This script depends on: + - systemd, + - i3, + - rofi or zenity." + +# Check whether the user-defined launcher is valid +launcher_list=(rofi zenity) +function check_launcher() { + if [[ ! "${launcher_list[@]}" =~ (^|[[:space:]])"$1"($|[[:space:]]) ]]; then + echo "Supported launchers: ${launcher_list[*]}" + exit 1 + else + # Get array with unique elements and preferred launcher first + # Note: uniq expects a sorted list, so we cannot use it + i=1 + launcher_list=($(for l in "$1" "${launcher_list[@]}"; do printf "%i %s\n" "$i" "$l"; let i+=1; done \ + | sort -uk2 | sort -nk1 | cut -d' ' -f2- | tr '\n' ' ')) + fi +} + +# Parse CLI arguments +while getopts "hcp:" option; do + case "${option}" in + h) echo "${usage}" + exit 0 + ;; + c) enable_confirmation=true + ;; + p) preferred_launcher="${OPTARG}" + check_launcher "${preferred_launcher}" + ;; + *) exit 1 + ;; + esac +done +check_launcher "${preferred_launcher}" + +# Check whether a command exists +function command_exists() { + command -v "$1" &> /dev/null 2>&1 +} + +# systemctl required +if ! command_exists systemctl ; then + exit 1 +fi + +# menu defined as an associative array +typeset -A menu + +# Menu with keys/commands +menu=( + [Shutdown]="systemctl poweroff" + [Reboot]="systemctl reboot" + [Hibernate]="systemctl hibernate" + [Suspend]="systemctl suspend" + [Halt]="systemctl halt" + [Lock]="${LOCKSCRIPT:-i3lock --color=${BG_COLOR#"#"}}" + [Logout]="i3-msg exit" + [Cancel]="" +) +menu_nrows=${#menu[@]} + +# Menu entries that may trigger a confirmation message +menu_confirm="Shutdown Reboot Hibernate Suspend Halt Logout" + +launcher_exe="" +launcher_options="" +rofi_colors="" + +function prepare_launcher() { + if [[ "$1" == "rofi" ]]; then + rofi_colors=(-bc "${BORDER_COLOR}" -bg "${BG_COLOR}" -fg "${FG_COLOR}" \ + -hlfg "${HLFG_COLOR}" -hlbg "${HLBG_COLOR}") + launcher_exe="rofi" + launcher_options=(-dmenu -i -lines "${menu_nrows}" -p "${ROFI_TEXT}" \ + "${rofi_colors[@]}" "${ROFI_OPTIONS[@]}") + elif [[ "$1" == "zenity" ]]; then + launcher_exe="zenity" + launcher_options=(--list --title="${ZENITY_TITLE}" --text="${ZENITY_TEXT}" \ + "${ZENITY_OPTIONS[@]}") + fi +} + +for l in "${launcher_list[@]}"; do + if command_exists "${l}" ; then + prepare_launcher "${l}" + break + fi +done + +# No launcher available +if [[ -z "${launcher_exe}" ]]; then + exit 1 +fi + +launcher=(${launcher_exe} "${launcher_options[@]}") +selection="$(printf '%s\n' "${!menu[@]}" | sort | "${launcher[@]}")" + +function ask_confirmation() { + if [ "${launcher_exe}" == "rofi" ]; then + confirmed=$(echo -e "Yes\nNo" | rofi -dmenu -i -lines 2 -p "${selection}?" \ + "${rofi_colors[@]}" "${ROFI_OPTIONS[@]}") + [ "${confirmed}" == "Yes" ] && confirmed=0 + elif [ "${launcher_exe}" == "zenity" ]; then + zenity --question --text "Are you sure you want to ${selection,,}?" + confirmed=$? + fi + + if [ "${confirmed}" == 0 ]; then + i3-msg -q "exec ${menu[${selection}]}" + fi +} + +if [[ $? -eq 0 && ! -z ${selection} ]]; then + if [[ "${enable_confirmation}" = true && \ + ${menu_confirm} =~ (^|[[:space:]])"${selection}"($|[[:space:]]) ]]; then + ask_confirmation + else + i3-msg -q "exec ${menu[${selection}]}" + fi +fi diff --git a/.config/i3/scripts/temperature b/.config/i3/scripts/temperature new file mode 100755 index 0000000..2170f10 --- /dev/null +++ b/.config/i3/scripts/temperature @@ -0,0 +1,69 @@ +#!/usr/bin/env perl +# Copyright 2014 Pierre Mavro +# Copyright 2014 Vivien Didelot +# Copyright 2014 Andreas Guldstrand +# Copyright 2014 Benjamin Chretien + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +use strict; +use warnings; +use utf8; +use Getopt::Long; + +binmode(STDOUT, ":utf8"); + +# default values +my $t_warn = $ENV{T_WARN} || 70; +my $t_crit = $ENV{T_CRIT} || 90; +my $chip = $ENV{SENSOR_CHIP} || ""; +my $temperature = -9999; + +sub help { + print "Usage: temperature [-w ] [-c ] [--chip ]\n"; + print "-w : warning threshold to become yellow\n"; + print "-c : critical threshold to become red\n"; + print "--chip : sensor chip\n"; + exit 0; +} + +GetOptions("help|h" => \&help, + "w=i" => \$t_warn, + "c=i" => \$t_crit, + "chip=s" => \$chip); + +# Get chip temperature +open (SENSORS, "sensors -u $chip |") or die; +while () { + if (/^\s+temp1_input:\s+[\+]*([\-]*\d+\.\d)/) { + $temperature = $1; + last; + } +} +close(SENSORS); + +$temperature eq -9999 and die 'Cannot find temperature'; + +# Print short_text, full_text +print "$temperature°C\n" x2; + +# Print color, if needed +if ($temperature >= $t_crit) { + print "#FF0000\n"; + exit 33; +} elsif ($temperature >= $t_warn) { + print "#FFFC00\n"; +} + +exit 0; diff --git a/.config/i3/scripts/volume b/.config/i3/scripts/volume new file mode 100755 index 0000000..6e0c4fe --- /dev/null +++ b/.config/i3/scripts/volume @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Copyright (C) 2014 Julien Bonjean +# Copyright (C) 2014 Alexander Keller + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +#------------------------------------------------------------------------ + +# The second parameter overrides the mixer selection +# For PulseAudio users, eventually use "pulse" +# For Jack/Jack2 users, use "jackplug" +# For ALSA users, you may use "default" for your primary card +# or you may use hw:# where # is the number of the card desired +if [[ -z "$MIXER" ]] ; then + MIXER="default" + if command -v pulseaudio >/dev/null 2>&1 && pulseaudio --check ; then + # pulseaudio is running, but not all installations use "pulse" + if amixer -D pulse info >/dev/null 2>&1 ; then + MIXER="pulse" + fi + fi + [ -n "$(lsmod | grep jack)" ] && MIXER="jackplug" + MIXER="${2:-$MIXER}" +fi + +# The instance option sets the control to report and configure +# This defaults to the first control of your selected mixer +# For a list of the available, use `amixer -D $Your_Mixer scontrols` +if [[ -z "$SCONTROL" ]] ; then + SCONTROL="${BLOCK_INSTANCE:-$(amixer -D $MIXER scontrols | + sed -n "s/Simple mixer control '\([^']*\)',0/\1/p" | + head -n1 + )}" +fi + +# The first parameter sets the step to change the volume by (and units to display) +# This may be in in % or dB (eg. 5% or 3dB) +if [[ -z "$STEP" ]] ; then + STEP="${1:-5%}" +fi + +#------------------------------------------------------------------------ + +capability() { # Return "Capture" if the device is a capture device + amixer -D $MIXER get $SCONTROL | + sed -n "s/ Capabilities:.*cvolume.*/Capture/p" +} + +volume() { + amixer -D $MIXER get $SCONTROL $(capability) +} + +format() { + + perl_filter='if (/.*\[(\d+%)\] (\[(-?\d+.\d+dB)\] )?\[(on|off)\]/)' + perl_filter+='{CORE::say $4 eq "off" ? "MUTE" : "' + # If dB was selected, print that instead + perl_filter+=$([[ $STEP = *dB ]] && echo '$3' || echo '$1') + perl_filter+='"; exit}' + output=$(perl -ne "$perl_filter") + echo "$LABEL$output" +} + +#------------------------------------------------------------------------ + +case $BLOCK_BUTTON in + 3) amixer -q -D $MIXER sset $SCONTROL $(capability) toggle ;; # right click, mute/unmute + 4) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}+ unmute ;; # scroll up, increase + 5) amixer -q -D $MIXER sset $SCONTROL $(capability) ${STEP}- unmute ;; # scroll down, decrease +esac + +volume | format diff --git a/.config/i3/startup.sh b/.config/i3/startup.sh new file mode 100755 index 0000000..1979359 --- /dev/null +++ b/.config/i3/startup.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +# Setup displays layout +autorandr --change + +# Display wallpapers +nitrogen --restore + +cur_layout="$(autorandr --current)" + +# Properly set DPI & keyboard layout +if [ "$cur_layout" = loftie ]; then + xrandr --dpi 120 + setxkbmap -layout us -variant altgr-intl + +# Display sys tray on correct display +elif [ "$cur_layout" = default ]; then + xrandr --output eDP-1-1 --primary +fi diff --git a/.config/nvim/.gitignore b/.config/nvim/.gitignore new file mode 100644 index 0000000..fba9346 --- /dev/null +++ b/.config/nvim/.gitignore @@ -0,0 +1,11 @@ +# File manager history +.netrwhist + +# Directory where my swap/undo files are stored +.vim/ + +# Where plugins are installed; can be done locally +plugged/ + +# Old file after updating plug.vim +plug.vim.old diff --git a/.config/nvim/LICENSE b/.config/nvim/LICENSE new file mode 100644 index 0000000..75bebc6 --- /dev/null +++ b/.config/nvim/LICENSE @@ -0,0 +1,8 @@ +MIT License +Copyright (c) 2021 Jef Roosens + +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/.config/nvim/README.md b/.config/nvim/README.md new file mode 100644 index 0000000..35ca8f5 --- /dev/null +++ b/.config/nvim/README.md @@ -0,0 +1,40 @@ +# neovim-config + +This repo contains the full Neovim config that I use on a daily basis for +college and personal projects. This file explains the basic structure of my +config, while setting-specific information can be found inside the config files +themselves. + +## Config structure +The config exists of a few key components: + +* `coc-settings.json`: config for the + [CoC](https://github.com/neoclide/coc.nvim) plugin. +* `init.vim`: this is the actual config file that gets loaded. It sources + everything else. +* `autoload/`: a special directory allowing the files inside to be used in the + `:call` command. Its only use is allowing usage of + [vim-plug](https://github.com/junegunn/vim-plug), my plugin manager. +* `colors/`: contains my themes. +* `ftplugin/`: this is where you can put filetype plugins. These are vim + scripts that are sourced whenever you open a buffer with the given filetype, + e.g. if you open a file with filetype `markdown`, it will source the file + `ftplugin/markdown.vim`, if it exists. This allows for custom configs for + certain filetypes. +* `init/`: contains the various config files sourced by `init.vim`. I could + just cram it all into a single file, but I find this difficult to maintain. + +## Choice of leader +In my opinion, an important part of any (Neo)vim config is choosing which +leader key to use. The default `\` leader wasn't going to cut it for me for +three main reasons: + +* Backslash required me to stretch my hand every time +* In Belgium (where I live), we use AZERTY instead of QWERTY, and the backslash + key is often not present on those keyboards or requires a key combination to + type +* I use both AZERTY and QWERTY and wanted a key that was the same on both + +Therefore, I chose Space as my main leader key and Tab as my local leader (even +though I've never actually used it). This allows me to use the same muscle +memory on my refurbished MacBook (AZERTY) and my Ducky (QWERTY). diff --git a/.config/nvim/autoload/plug.vim b/.config/nvim/autoload/plug.vim new file mode 100644 index 0000000..9c296ac --- /dev/null +++ b/.config/nvim/autoload/plug.vim @@ -0,0 +1,2788 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" +" " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align +" Plug 'junegunn/vim-easy-align' +" +" " Any valid git URL is allowed +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Multiple Plug commands can be written in a single line using | separators +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using a non-default branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } +" +" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) +" Plug 'fatih/vim-go', { 'tag': '*' } +" +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Initialize plugin system +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" +" Plug options: +" +"| Option | Description | +"| ----------------------- | ------------------------------------------------ | +"| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | +"| `rtp` | Subdirectory that contains Vim plugin | +"| `dir` | Custom directory for the plugin | +"| `as` | Use different name for the plugin | +"| `do` | Post-update hook (string or funcref) | +"| `on` | On-demand loading: Commands or ``-mappings | +"| `for` | On-demand loading: File types | +"| `frozen` | Do not update unless explicitly specified | +" +" More information: https://github.com/junegunn/vim-plug +" +" +" Copyright (c) 2017 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') +let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) +let s:vim8 = has('patch-8.0.0039') && exists('*job_start') +if s:is_win && &shellslash + set noshellslash + let s:me = resolve(expand(':p')) + set shellslash +else + let s:me = resolve(expand(':p')) +endif +let s:base_spec = { 'branch': '', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! s:isabsolute(dir) abort + return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)') +endfunction + +function! s:git_dir(dir) abort + let gitdir = s:trim(a:dir) . '/.git' + if isdirectory(gitdir) + return gitdir + endif + if !filereadable(gitdir) + return '' + endif + let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*') + if len(gitdir) && !s:isabsolute(gitdir) + let gitdir = a:dir . '/' . gitdir + endif + return isdirectory(gitdir) ? gitdir : '' +endfunction + +function! s:git_origin_url(dir) abort + let gitdir = s:git_dir(a:dir) + let config = gitdir . '/config' + if empty(gitdir) || !filereadable(config) + return '' + endif + return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze') +endfunction + +function! s:git_revision(dir) abort + let gitdir = s:git_dir(a:dir) + let head = gitdir . '/HEAD' + if empty(gitdir) || !filereadable(head) + return '' + endif + + let line = get(readfile(head), 0, '') + let ref = matchstr(line, '^ref: \zs.*') + if empty(ref) + return line + endif + + if filereadable(gitdir . '/' . ref) + return get(readfile(gitdir . '/' . ref), 0, '') + endif + + if filereadable(gitdir . '/packed-refs') + for line in readfile(gitdir . '/packed-refs') + if line =~# ' ' . ref + return matchstr(line, '^[0-9a-f]*') + endif + endfor + endif + + return '' +endfunction + +function! s:git_local_branch(dir) abort + let gitdir = s:git_dir(a:dir) + let head = gitdir . '/HEAD' + if empty(gitdir) || !filereadable(head) + return '' + endif + let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*') + return len(branch) ? branch : 'HEAD' +endfunction + +function! s:git_origin_branch(spec) + if len(a:spec.branch) + return a:spec.branch + endif + + " The file may not be present if this is a local repository + let gitdir = s:git_dir(a:spec.dir) + let origin_head = gitdir.'/refs/remotes/origin/HEAD' + if len(gitdir) && filereadable(origin_head) + return matchstr(get(readfile(origin_head), 0, ''), + \ '^ref: refs/remotes/origin/\zs.*') + endif + + " The command may not return the name of a branch in detached HEAD state + let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir)) + return v:shell_error ? '' : result[-1] +endfunction + +if s:is_win + function! s:plug_call(fn, ...) + let shellslash = &shellslash + try + set noshellslash + return call(a:fn, a:000) + finally + let &shellslash = shellslash + endtry + endfunction +else + function! s:plug_call(fn, ...) + return call(a:fn, a:000) + endfunction +endif + +function! s:plug_getcwd() + return s:plug_call('getcwd') +endfunction + +function! s:plug_fnamemodify(fname, mods) + return s:plug_call('fnamemodify', a:fname, a:mods) +endfunction + +function! s:plug_expand(fmt) + return s:plug_call('expand', a:fmt, 1) +endfunction + +function! s:plug_tempname() + return s:plug_call('tempname') +endfunction + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp + return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call plug#() + if !executable('git') + return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') + endif + if has('win32') + \ && &shellslash + \ && (&shell =~# 'cmd\(\.exe\)\?$' || &shell =~# 'powershell\(\.exe\)\?$') + return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.') + endif + if !has('nvim') + \ && (has('win32') || has('win32unix')) + \ && !has('multi_byte') + return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, []) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, []) + command! -nargs=0 -bar -bang PlugClean call s:clean(0) + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, ) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:glob(from, pattern) + return s:lines(globpath(a:from, a:pattern)) +endfunction + +function! s:source(from, ...) + let found = 0 + for pattern in a:000 + for vim in s:glob(a:from, pattern) + execute 'source' s:esc(vim) + let found = 1 + endfor + endfor + return found +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! s:ask(message, ...) + call inputsave() + echohl WarningMsg + let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) ')) + echohl None + call inputrestore() + echo "\r" + return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0 +endfunction + +function! s:ask_no_interrupt(...) + try + return call('s:ask', a:000) + catch + return 0 + endtry +endfunction + +function! s:lazy(plug, opt) + return has_key(a:plug, a:opt) && + \ (empty(s:to_a(a:plug[a:opt])) || + \ !isdirectory(a:plug.dir) || + \ len(s:glob(s:rtp(a:plug), 'plugin')) || + \ len(s:glob(s:rtp(a:plug), 'after/plugin'))) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('plug#end() called without calling plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + if exists('g:did_load_filetypes') + filetype off + endif + for name in g:plugs_order + if !has_key(g:plugs, name) + continue + endif + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + let cmd = substitute(cmd, '!*$', '', '') + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or ``.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + augroup filetypedetect + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + augroup END + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")', + \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + if has('syntax') && !exists('g:syntax_on') + syntax enable + end + else + call s:reload_plugins() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:load_plugin(spec) + call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim') +endfunction + +function! s:reload_plugins() + for name in s:loaded_names() + call s:load_plugin(g:plugs[name]) + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + if !exists('s:git_version') + let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)') + endif + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) +endfunction + +if s:is_win + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction + + " Copied from fzf + function! s:wrap_cmds(cmds) + let cmds = [ + \ '@echo off', + \ 'setlocal enabledelayedexpansion'] + \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) + \ + ['endlocal'] + if has('iconv') + if !exists('s:codepage') + let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0) + endif + return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage)) + endif + return map(cmds, 'v:val."\r"') + endfunction + + function! s:batchfile(cmd) + let batchfile = s:plug_tempname().'.bat' + call writefile(s:wrap_cmds(a:cmd), batchfile) + let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0}) + if &shell =~# 'powershell\(\.exe\)\?$' + let cmd = '& ' . cmd + endif + return [batchfile, cmd] + endfunction +else + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None +endfunction + +function! s:warn(cmd, msg) + echohl WarningMsg + execute a:cmd 'a:msg' + echohl None +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! s:doautocmd(...) + if exists('#'.join(a:000, '#')) + execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000) + endif +endfunction + +function! s:dobufread(names) + for name in a:names + let path = s:rtp(g:plugs[name]) + for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin'] + if len(finddir(dir, path)) + if exists('#BufRead') + doautocmd BufRead + endif + return + endif + endfor + endfor +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000 + let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)') + if !empty(unloaded) + for name in unloaded + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + call s:dobufread(unloaded) + return 1 + end + return 0 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types, ...) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if a:0 + if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2)) + execute 'runtime' a:1 + endif + call s:source(rtp, a:2) + endif + call s:doautocmd('User', name) + endfor +endfunction + +function! s:lod_ft(pat, names) + let syn = 'syntax/'.a:pat.'.vim' + call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) + execute 'autocmd! PlugLOD FileType' a:pat + call s:doautocmd('filetypeplugin', 'FileType') + call s:doautocmd('filetypeindent', 'FileType') +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, with_prefix, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + call s:dobufread(a:names) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + + if a:with_prefix + let prefix = v:count ? v:count : '' + let prefix .= '"'.v:register.a:prefix + if mode(1) == 'no' + if v:operator == 'c' + let prefix = "\" . prefix + endif + let prefix .= v:operator + endif + call feedkeys(prefix, 'n') + endif + call feedkeys(substitute(a:map, '^', "\", '') . extra) +endfunction + +function! plug#(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec + let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??')) + let spec = extend(s:infer_properties(name, repo), opts) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(repo . ' ' . v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)' + if type == s:TYPE.string + if empty(a:arg) + throw printf(opt_errfmt, 'tag', 'string') + endif + let opts.tag = a:arg + elseif type == s:TYPE.dict + for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as'] + if has_key(a:arg, opt) + \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) + throw printf(opt_errfmt, opt, 'string') + endif + endfor + for opt in ['on', 'for'] + if has_key(a:arg, opt) + \ && type(a:arg[opt]) != s:TYPE.list + \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt])) + throw printf(opt_errfmt, opt, 'string or list') + endif + endfor + if has_key(a:arg, 'do') + \ && type(a:arg.do) != s:TYPE.funcref + \ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do)) + throw printf(opt_errfmt, 'do', 'string or funcref') + endif + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(s:plug_expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(s:plug_expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo) + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([s:rtp(spec), 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-\{1}\ / + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/ + syn match plugTag /(tag: [^)]\+)/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag + syn match plugEdge /^ \X\+$/ + syn match plugEdge /^ \X*/ contained nextgroup=plugSha + syn match plugSha /[0-9a-f]\{7,9}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ + syn match plugH2 /^.*:\n-\+$/ + syn match plugH2 /^-\{2,}/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugH2 Type + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugDeleted Ignore + hi def link plugRelDate Comment + hi def link plugEdge PreProc + hi def link plugSha Identifier + hi def link plugTag Constant + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:finish_bindings() + nnoremap R :call retry() + nnoremap D :PlugDiff + nnoremap S :PlugStatus + nnoremap U :call status_update() + xnoremap U :call status_update() + nnoremap ]] :silent! call section('') + nnoremap [[ :silent! call section('b') +endfunction + +function! s:prepare(...) + if empty(s:plug_getcwd()) + throw 'Invalid current working directory. Cannot proceed.' + endif + + for evar in ['$GIT_DIR', '$GIT_WORK_TREE'] + if exists(evar) + throw evar.' detected. Cannot proceed.' + endif + endfor + + call s:job_abort() + if s:switch_in() + if b:plug_preview == 1 + pc + endif + enew + else + call s:new_window() + endif + + nnoremap q :if b:plug_preview==1pcendifbd + if a:0 == 0 + call s:finish_bindings() + endif + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + + for k in ['', 'L', 'o', 'X', 'd', 'dd'] + execute 'silent! unmap ' k + endfor + setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell + if exists('+colorcolumn') + setlocal colorcolumn= + endif + setf vim-plug + if exists('g:syntax_on') + call s:syntax() + endif +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:chsh(swap) + let prev = [&shell, &shellcmdflag, &shellredir] + if !s:is_win + set shell=sh + endif + if a:swap + if &shell =~# 'powershell\(\.exe\)\?$' || &shell =~# 'pwsh$' + let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s' + elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$' + set shellredir=>%s\ 2>&1 + endif + endif + return prev +endfunction + +function! s:bang(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(a:0) + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') + execute "normal! :execute g:_plug_bang\\" + finally + unlet g:_plug_bang + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + return v:shell_error ? 'Exit status: ' . v:shell_error : '' +endfunction + +function! s:regress_bar() + let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '') + call s:progress_bar(2, bar, len(bar)) +endfunction + +function! s:is_updated(dir) + return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir)) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir)) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + if spec.do[0] == ':' + if !get(s:loaded, name, 0) + let s:loaded[name] = 1 + call s:reorg_rtp() + endif + call s:load_plugin(spec) + try + execute spec.do[1:] + catch + let error = v:exception + endtry + if !s:plug_window_exists() + cd - + throw 'Warning: vim-plug was terminated by the post-update hook of '.name + endif + else + let error = s:bang(spec.do) + endif + elseif type == s:TYPE.funcref + try + call s:load_plugin(spec) + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call s:switch_in() + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + if !empty(error) + call add(s:update.errors, name) + call s:regress_bar() + endif + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(spec) + let sha = a:spec.commit + let output = s:git_revision(a:spec.dir) + if !empty(output) && !s:hash_match(sha, s:lines(output)[0]) + let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : '' + let output = s:system( + \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir) + endif + return output +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') | 4 + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') + call s:finish_bindings() +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + echo + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:check_ruby() + silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'") + if !exists('g:plug_ruby') + redraw! + return s:warn('echom', 'Warning: Ruby interface is broken') + endif + let ruby_version = split(g:plug_ruby, '\.') + unlet g:plug_ruby + return s:version_requirement(ruby_version, [1, 8, 7]) +endfunction + +function! s:update_impl(pull, force, args) abort + let sync = index(a:args, '--sync') >= 0 || has('vim_starting') + let args = filter(copy(a:args), 'v:val != "--sync"') + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install')) + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') + endif + + let use_job = s:nvim || s:vim8 + let python = (has('python') || has('python3')) && !use_job + let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby() + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare(1) + call append(0, ['', '']) + normal! 2G + silent! redraw + + let s:clone_opt = [] + if get(g:, 'plug_shallow', 1) + call extend(s:clone_opt, ['--depth', '1']) + if s:git_version_requirement(1, 7, 10) + call add(s:clone_opt, '--no-single-branch') + endif + endif + + if has('win32unix') || has('wsl') + call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input']) + endif + + let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !use_job && s:update.threads > 1 + redir => pyv + silent python import platform; print platform.python_version() + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + while use_job && sync + sleep 100m + if s:update.fin + break + endif + endwhile + endif +endfunction + +function! s:log4(name, msg) + call setline(4, printf('- %s (%s)', a:msg, a:name)) + redraw +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call append(3, '- Updating ...') | 4 + for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) + let [pos, _] = s:logpos(name) + if !pos + continue + endif + if has_key(spec, 'commit') + call s:log4(name, 'Checking out '.spec.commit) + let out = s:checkout(spec) + elseif has_key(spec, 'tag') + let tag = spec.tag + if tag =~ '\*' + let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir)) + if !v:shell_error && !empty(tags) + let tag = tags[0] + call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) + call append(3, '') + endif + endif + call s:log4(name, 'Checking out '.tag) + let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir) + else + let branch = s:git_origin_branch(spec) + call s:log4(name, 'Merging origin/'.s:esc(branch)) + let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1' + \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir) + endif + if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && + \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) + call s:log4(name, 'Updating submodules. This may take a while.') + let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir) + endif + let msg = s:format_message(v:shell_error ? 'x': '-', name, out) + if v:shell_error + call add(s:update.errors, name) + call s:regress_bar() + silent execute pos 'd _' + call append(4, msg) | 4 + elseif !empty(out) + call setline(pos, msg[0]) + endif + redraw + endfor + silent 4 d _ + try + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) + catch + call s:warn('echom', v:exception) + call s:warn('echo', '') + return + endtry + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if (!s:nvim && !s:vim8) || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + if s:nvim + silent! call jobstop(j.jobid) + elseif s:vim8 + silent! call job_stop(j.jobid) + endif + if j.new + call s:rm_rf(g:plugs[name].dir) + endif + endfor + let s:jobs = {} +endfunction + +function! s:last_non_empty_line(lines) + let len = len(a:lines) + for idx in range(len) + let line = a:lines[len-idx-1] + if !empty(line) + return line + endif + endfor + return '' +endfunction + +function! s:job_out_cb(self, data) abort + let self = a:self + let data = remove(self.lines, -1) . a:data + let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]') + call extend(self.lines, lines) + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if !self.running || self.tick % len(s:jobs) == 0 + let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-') + let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines) + call s:log(bullet, self.name, result) + endif +endfunction + +function! s:job_exit_cb(self, data) abort + let a:self.running = 0 + let a:self.error = a:data != 0 + call s:reap(a:self.name) + call s:tick() +endfunction + +function! s:job_cb(fn, job, ch, data) + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + call call(a:fn, [a:job, a:data]) +endfunction + +function! s:nvim_cb(job_id, data, event) dict abort + return (a:event == 'stdout' || a:event == 'stderr') ? + \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : + \ s:job_cb('s:job_exit_cb', self, 0, a:data) +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], + \ 'new': get(a:opts, 'new', 0) } + let s:jobs[a:name] = job + + if s:nvim + if has_key(a:opts, 'dir') + let job.cwd = a:opts.dir + endif + let argv = a:cmd + call extend(job, { + \ 'on_stdout': function('s:nvim_cb'), + \ 'on_stderr': function('s:nvim_cb'), + \ 'on_exit': function('s:nvim_cb'), + \ }) + let jid = s:plug_call('jobstart', argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = [jid < 0 ? argv[0].' is not executable' : + \ 'Invalid arguments (or job table is full)'] + endif + elseif s:vim8 + let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})')) + if has_key(a:opts, 'dir') + let cmd = s:with_cd(cmd, a:opts.dir, 0) + endif + let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd] + let jid = job_start(s:is_win ? join(argv, ' ') : argv, { + \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'err_cb': function('s:job_cb', ['s:job_out_cb', job]), + \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), + \ 'err_mode': 'raw', + \ 'out_mode': 'raw' + \}) + if job_status(jid) == 'run' + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.lines = ['Failed to start job'] + endif + else + let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd])) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + let bullet = job.error ? 'x' : '-' + let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines) + call s:log(bullet, a:name, empty(result) ? 'OK' : result) + call s:bar() + + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + let max = line('$') + for i in range(4, max > 4 ? max : 4) + if getline(i) =~# '^[-+x*] '.a:name.':' + for j in range(i + 1, max > 5 ? max : 5) + if getline(j) !~ '^ ' + return [i, j - 1] + endif + endfor + return [i, i] + endif + endfor + return [0, 0] +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let [b, e] = s:logpos(a:name) + if b > 0 + silent execute printf('%d,%d d _', b, e) + if b > winheight('.') + let b = 4 + endif + else + let b = 4 + endif + " FIXME For some reason, nomodifiable is set after :d in vim8 + setlocal modifiable + call append(b - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim || s:vim8) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + call s:update_finish() + let s:update.fin = 1 + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = empty(globpath(spec.dir, '.git', 1)) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + if !new + let [error, _] = s:git_validate(spec, 0) + if empty(error) + if pull + let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch'] + if has_tag && !empty(globpath(spec.dir, '.git/shallow')) + call extend(cmd, ['--depth', '99999999']) + endif + if !empty(prog) + call add(cmd, prog) + endif + call s:spawn(name, cmd, { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } + endif + else + let cmd = ['git', 'clone'] + if !has_tag + call extend(cmd, s:clone_opt) + endif + if !empty(prog) + call add(cmd, prog) + endif + call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python') ? 'python' : 'python3' +execute py_exe "<< EOF" +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt')) +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_IS_WIN = vim.eval('s:is_win') == '1' + +class PlugError(Exception): + def __init__(self, msg): + self.msg = msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + CD = 'cd /d' if G_IS_WIN else 'cd' + + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + if cmd_dir: + self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd) + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + preexec_fn = not G_IS_WIN and os.setsid or None + self.proc = subprocess.Popen(self.cmd, stdout=tfile, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, shell=True, + preexec_fn=preexec_fn) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = '' if G_IS_WIN else nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + if G_IS_WIN: + os.kill(self.proc.pid, signal.SIGINT) + else: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + self.tag = args.get('tag', 0) + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + if target[-1] == '\\': + target = target[0:-1] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} {2} {3} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + actual_uri = self.repo_uri() + expect_uri = self.args['uri'] + regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$') + ma = regex.match(actual_uri) + mb = regex.match(expect_uri) + if ma is None or mb is None or ma.groups() != mb.groups(): + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + start_cnt = thr.active_count() + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or thr.active_count() != start_cnt: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, ['OK'] if not msg else msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM + pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil } + else + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + end + + def compare_git_uri a, b + regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$} + regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1) + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/ + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + if vim7 + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + else + require 'io/console' # >= Ruby 1.9 + nil until IO.console.getch == 3.chr + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } unless vim7 + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt').join(' ') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, tag = pair.last.values_at *%w[dir uri tag] + exists = File.directory? dir + ok, result = + if exists + chdir = "#{cd} #{iswin ? dir : esc(dir)}" + ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif !compare_git_uri(current_uri, uri) + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc_cmd(arg, script) + let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g') + return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g') +endfunction + +function! s:shellesc_ps1(arg) + return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'" +endfunction + +function! s:shellesc_sh(arg) + return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'" +endfunction + +" Escape the shell argument based on the shell. +" Vim and Neovim's shellescape() are insufficient. +" 1. shellslash determines whether to use single/double quotes. +" Double-quote escaping is fragile for cmd.exe. +" 2. It does not work for powershell. +" 3. It does not work for *sh shells if the command is executed +" via cmd.exe (ie. cmd.exe /c sh -c command command_args) +" 4. It does not support batchfile syntax. +" +" Accepts an optional dictionary with the following keys: +" - shell: same as Vim/Neovim 'shell' option. +" If unset, fallback to 'cmd.exe' on Windows or 'sh'. +" - script: If truthy and shell is cmd.exe, escape for batchfile syntax. +function! plug#shellescape(arg, ...) + if a:arg =~# '^[A-Za-z0-9_/:.-]\+$' + return a:arg + endif + let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} + let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') + let script = get(opts, 'script', 1) + if shell =~# 'cmd\(\.exe\)\?$' + return s:shellesc_cmd(a:arg, script) + elseif shell =~# 'powershell\(\.exe\)\?$' || shell =~# 'pwsh$' + return s:shellesc_ps1(a:arg) + endif + return s:shellesc_sh(a:arg) +endfunction + +function! s:glob_dir(path) + return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + " See `git help clone' + " https:// [user@] github.com[:port] / junegunn/vim-plug [.git] + " [git@] github.com[:port] : junegunn/vim-plug [.git] + " file:// / junegunn/vim-plug [/] + " / junegunn/vim-plug [/] + let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$' + let ma = matchlist(a:a, pat) + let mb = matchlist(a:b, pat) + return ma[1:2] ==# mb[1:2] +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir, ...) + let script = a:0 > 0 ? a:1 : 1 + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd) +endfunction + +function! s:system(cmd, ...) + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + if type(a:cmd) == s:TYPE.list + " Neovim's system() supports list argument to bypass the shell + " but it cannot set the working directory for the command. + " Assume that the command does not rely on the shell. + if has('nvim') && a:0 == 0 + return system(a:cmd) + endif + let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})')) + if &shell =~# 'powershell\(\.exe\)\?$' + let cmd = '& ' . cmd + endif + else + let cmd = a:cmd + endif + if a:0 > 0 + let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list) + endif + if s:is_win && type(a:cmd) != s:TYPE.list + let [batchfile, cmd] = s:batchfile(cmd) + endif + return system(cmd) + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)] + let remote = result[-1] + if empty(remote) + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let sha = s:git_revision(a:spec.dir) + if empty(sha) + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let current_branch = result[0] + " Check tag + let origin_branch = s:git_origin_branch(a:spec) + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag && a:spec.tag !~ '\*' + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif origin_branch !=# current_branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ current_branch, origin_branch) + endif + if empty(err) + let [ahead, behind] = split(s:lastline(s:system([ + \ 'git', 'rev-list', '--count', '--left-right', + \ printf('HEAD...origin/%s', origin_branch) + \ ], a:spec.dir)), '\t') + if !v:shell_error && ahead + if behind + " Only mention PlugClean if diverged, otherwise it's likely to be + " pushable (and probably not that messed up). + let err = printf( + \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" + \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind) + else + let err = printf("Ahead of origin/%s by %d commit(s).\n" + \ .'Cannot update until local changes are pushed.', + \ origin_branch, ahead) + endif + endif + endif + endif + else + let err = 'Not found' + endif + return [err, err =~# 'PlugClean'] +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + return s:system(s:is_win + \ ? 'rmdir /S /Q '.plug#shellescape(a:dir) + \ : ['rm', '-rf', a:dir]) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for invalid plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let errs = {} + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) + call add(dirs, spec.dir) + else + let [err, clean] = s:git_validate(spec, 1) + if clean + let errs[spec.dir] = s:lines(err)[0] + else + call add(dirs, spec.dir) + endif + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + if has_key(errs, f) + call append(line('$'), ' ' . errs[f]) + endif + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + 4 + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + let s:clean_count = 0 + call append(3, ['Directories to delete:', '']) + redraw! + if a:force || s:ask_no_interrupt('Delete all directories?') + call s:delete([6, line('$')], 1) + else + call setline(4, 'Cancelled.') + nnoremap d :set opfunc=delete_opg@ + nmap dd d_ + xnoremap d :call delete_op(visualmode(), 1) + echo 'Delete the lines (d{motion}) to delete the corresponding directories' + endif + endif + 4 + setlocal nomodifiable +endfunction + +function! s:delete_op(type, ...) + call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0) +endfunction + +function! s:delete(range, force) + let [l1, l2] = a:range + let force = a:force + let err_count = 0 + while l1 <= l2 + let line = getline(l1) + if line =~ '^- ' && isdirectory(line[2:]) + execute l1 + redraw! + let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) + let force = force || answer > 1 + if answer + let err = s:rm_rf(line[2:]) + setlocal modifiable + if empty(err) + call setline(l1, '~'.line[1:]) + let s:clean_count += 1 + else + delete _ + call append(l1 - 1, s:format_message('x', line[1:], err)) + let l2 += len(s:lines(err)) + let err_count += 1 + endif + let msg = printf('Removed %d directories.', s:clean_count) + if err_count > 0 + let msg .= printf(' Failed to remove %d directories.', err_count) + endif + call setline(4, msg) + setlocal nomodifiable + endif + endif + let l1 += 1 + endwhile +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = s:plug_tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp]) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + let is_dir = isdirectory(spec.dir) + if has_key(spec, 'uri') + if is_dir + let [err, _] = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if is_dir + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if is_dir && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap L :call status_load(line('.')) + xnoremap L :call status_load(line('.')) + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + if exists('g:plug_pwindow') && !s:is_preview_window_open() + execute g:plug_pwindow + execute 'e' sha + else + execute 'pedit' sha + wincmd P + endif + setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable + let batchfile = '' + try + let [sh, shellcmdflag, shrd] = s:chsh(1) + let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha + if s:is_win + let [batchfile, cmd] = s:batchfile(cmd) + endif + execute 'silent %!' cmd + finally + let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] + if s:is_win && filereadable(batchfile) + call delete(batchfile) + endif + endtry + setlocal nomodifiable + nnoremap q :q + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:format_git_log(line) + let indent = ' ' + let tokens = split(a:line, nr2char(1)) + if len(tokens) != 5 + return indent.substitute(a:line, '\s*$', '', '') + endif + let [graph, sha, refs, subject, date] = tokens + let tag = matchstr(refs, 'tag: [^,)]\+') + let tag = empty(tag) ? ' ' : ' ('.tag.') ' + return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date) +endfunction + +function! s:append_ul(lnum, text) + call append(a:lnum, ['', a:text, repeat('-', len(a:text))]) +endfunction + +function! s:diff() + call s:prepare() + call append(0, ['Collecting changes ...', '']) + let cnts = [0, 0] + let bar = '' + let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)') + call s:progress_bar(2, bar, len(total)) + for origin in [1, 0] + let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))')))) + if empty(plugs) + continue + endif + call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') + for [k, v] in plugs + let branch = s:git_origin_branch(v) + if len(branch) + let range = origin ? '..origin/'.branch : 'HEAD@{1}..' + let cmd = ['git', 'log', '--graph', '--color=never'] + if s:git_version_requirement(2, 10, 0) + call add(cmd, '--no-show-signature') + endif + call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range]) + if has_key(v, 'rtp') + call extend(cmd, ['--', v.rtp]) + endif + let diff = s:system_chomp(cmd, v.dir) + if !empty(diff) + let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' + call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) + let cnts[origin] += 1 + endif + endif + let bar .= '=' + call s:progress_bar(2, bar, len(total)) + normal! 2G + redraw + endfor + if !cnts[origin] + call append(5, ['', 'N/A']) + endif + endfor + call setline(1, printf('%d plugin(s) updated.', cnts[0]) + \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : '')) + + if cnts[0] || cnts[1] + nnoremap (plug-preview) :silent! call preview_commit() + if empty(maparg("\", 'n')) + nmap (plug-preview) + endif + if empty(maparg('o', 'n')) + nmap o (plug-preview) + endif + endif + if cnts[0] + nnoremap X :call revert() + echo "Press 'X' on each block to revert the update" + endif + normal! gg + setlocal nomodifiable +endfunction + +function! s:revert() + if search('^Pending updates', 'bnW') + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted' +endfunction + +function! s:snapshot(force, ...) abort + call s:prepare() + setf vim + call append(0, ['" Generated by vim-plug', + \ '" '.strftime("%c"), + \ '" :source this file in vim to restore the snapshot', + \ '" or execute: vim -S snapshot.vim', + \ '', '', 'PlugUpdate!']) + 1 + let anchor = line('$') - 3 + let names = sort(keys(filter(copy(g:plugs), + \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) + for name in reverse(names) + let sha = s:git_revision(g:plugs[name].dir) + if !empty(sha) + call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = s:plug_expand(a:1) + if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) + return + endif + call writefile(getline(1, '$'), fn) + echo 'Saved as '.a:1 + silent execute 'e' s:esc(fn) + setf vim + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@ +" Website: https://github.com/ghifarit53/tokyonight.vim/ +" License: MIT +" ----------------------------------------------------------------------------- + +" Initialization: {{{ +highlight clear +if exists('syntax_on') + syntax reset +endif +set background=dark + +let s:t_Co = exists('&t_Co') && !empty(&t_Co) && &t_Co > 1 ? &t_Co : 2 +let s:tmux = executable('tmux') && $TMUX !=# '' + +let g:colors_name = 'tokyonight' +" }}} +" Configuration: {{{ +let s:configuration = {} +let s:configuration.style = get(g:, 'tokyonight_style', 'night') +let s:configuration.transparent_background = get(g:, 'tokyonight_transparent_background', 0) +let s:configuration.menu_selection_background = get(g:, 'tokyonight_menu_selection_background', 'green') +let s:configuration.disable_italic_comment = get(g:, 'tokyonight_disable_italic_comment', 0) +let s:configuration.enable_italic = get(g:, 'tokyonight_enable_italic', 0) +let s:configuration.cursor = get(g:, 'tokyonight_cursor', 'auto') +let s:configuration.current_word = get(g:, 'tokyonight_current_word', get(g:, 'tokyonight_transparent_background', 0) == 0 ? 'grey background' : 'bold') +" }}} +" Palette: {{{ +" +if s:configuration.style ==# 'night' + let s:palette = { + \ 'black': ['#06080a', '237', 'DarkGrey'], + \ 'bg0': ['#1a1b26', '235', 'Black'], + \ 'bg1': ['#232433', '236', 'DarkGrey'], + \ 'bg2': ['#2a2b3d', '236', 'DarkGrey'], + \ 'bg3': ['#32344a', '237', 'DarkGrey'], + \ 'bg4': ['#3b3d57', '237', 'Grey'], + \ 'bg_red': ['#ff7a93', '203', 'Red'], + \ 'diff_red': ['#803d49', '52', 'DarkRed'], + \ 'bg_green': ['#b9f27c', '107', 'Green'], + \ 'diff_green': ['#618041', '22', 'DarkGreen'], + \ 'bg_blue': ['#7da6ff', '110', 'Blue'], + \ 'diff_blue': ['#3e5380', '17', 'DarkBlue'], + \ 'fg': ['#a9b1d6', '250', 'White'], + \ 'red': ['#F7768E', '203', 'Red'], + \ 'orange': ['#FF9E64', '215', 'Orange'], + \ 'yellow': ['#E0AF68', '179', 'Yellow'], + \ 'green': ['#9ECE6A', '107', 'Green'], + \ 'blue': ['#7AA2F7', '110', 'Blue'], + \ 'purple': ['#ad8ee6', '176', 'Magenta'], + \ 'grey': ['#444B6A', '246', 'LightGrey'], + \ 'none': ['NONE', 'NONE', 'NONE'] + \ } +elseif s:configuration.style ==# 'storm' + let s:palette = { + \ 'black': ['#06080a', '237', 'DarkGrey'], + \ 'bg0': ['#24283b', '235', 'Black'], + \ 'bg1': ['#282d42', '236', 'DarkGrey'], + \ 'bg2': ['#2f344d', '236', 'DarkGrey'], + \ 'bg3': ['#333954', '237', 'DarkGrey'], + \ 'bg4': ['#3a405e', '237', 'Grey'], + \ 'bg_red': ['#ff7a93', '203', 'Red'], + \ 'diff_red': ['#803d49', '52', 'DarkRed'], + \ 'bg_green': ['#b9f27c', '107', 'Green'], + \ 'diff_green': ['#618041', '22', 'DarkGreen'], + \ 'bg_blue': ['#7da6ff', '110', 'Blue'], + \ 'diff_blue': ['#3e5380', '17', 'DarkBlue'], + \ 'fg': ['#a9b1d6', '250', 'White'], + \ 'red': ['#F7768E', '203', 'Red'], + \ 'orange': ['#FF9E64', '215', 'Orange'], + \ 'yellow': ['#E0AF68', '179', 'Yellow'], + \ 'green': ['#9ECE6A', '107', 'Green'], + \ 'blue': ['#7AA2F7', '110', 'Blue'], + \ 'purple': ['#ad8ee6', '176', 'Magenta'], + \ 'grey': ['#444B6A', '246', 'LightGrey'], + \ 'none': ['NONE', 'NONE', 'NONE'] + \ } +endif + +" }}} +" Function: {{{ +" call s:HL(group, foreground, background) +" call s:HL(group, foreground, background, gui, guisp) +" +" E.g.: +" call s:HL('Normal', s:palette.fg, s:palette.bg0) + +if (has('termguicolors') && &termguicolors) || has('gui_running') " guifg guibg gui cterm guisp + function! s:HL(group, fg, bg, ...) + let hl_string = [ + \ 'highlight', a:group, + \ 'guifg=' . a:fg[0], + \ 'guibg=' . a:bg[0], + \ ] + if a:0 >= 1 + if a:1 ==# 'undercurl' + if !s:tmux + call add(hl_string, 'gui=undercurl') + else + call add(hl_string, 'gui=underline') + endif + call add(hl_string, 'cterm=underline') + else + call add(hl_string, 'gui=' . a:1) + call add(hl_string, 'cterm=' . a:1) + endif + else + call add(hl_string, 'gui=NONE') + call add(hl_string, 'cterm=NONE') + endif + if a:0 >= 2 + call add(hl_string, 'guisp=' . a:2[0]) + endif + execute join(hl_string, ' ') + endfunction +elseif s:t_Co >= 256 " ctermfg ctermbg cterm + function! s:HL(group, fg, bg, ...) + let hl_string = [ + \ 'highlight', a:group, + \ 'ctermfg=' . a:fg[1], + \ 'ctermbg=' . a:bg[1], + \ ] + if a:0 >= 1 + if a:1 ==# 'undercurl' + call add(hl_string, 'cterm=underline') + else + call add(hl_string, 'cterm=' . a:1) + endif + else + call add(hl_string, 'cterm=NONE') + endif + execute join(hl_string, ' ') + endfunction +else " ctermfg ctermbg cterm + function! s:HL(group, fg, bg, ...) + let hl_string = [ + \ 'highlight', a:group, + \ 'ctermfg=' . a:fg[2], + \ 'ctermbg=' . a:bg[2], + \ ] + if a:0 >= 1 + if a:1 ==# 'undercurl' + call add(hl_string, 'cterm=underline') + else + call add(hl_string, 'cterm=' . a:1) + endif + else + call add(hl_string, 'cterm=NONE') + endif + execute join(hl_string, ' ') + endfunction +endif +" }}} + +" Common Highlight Groups: {{{ +" UI: {{{ +if s:configuration.transparent_background + call s:HL('Normal', s:palette.fg, s:palette.none) + call s:HL('Terminal', s:palette.fg, s:palette.none) + call s:HL('EndOfBuffer', s:palette.bg0, s:palette.none) + call s:HL('FoldColumn', s:palette.grey, s:palette.none) + call s:HL('Folded', s:palette.grey, s:palette.none) + call s:HL('SignColumn', s:palette.fg, s:palette.none) + call s:HL('ToolbarLine', s:palette.fg, s:palette.none) +else + call s:HL('Normal', s:palette.fg, s:palette.bg0) + call s:HL('Terminal', s:palette.fg, s:palette.bg0) + call s:HL('EndOfBuffer', s:palette.bg0, s:palette.bg0) + call s:HL('FoldColumn', s:palette.grey, s:palette.bg1) + call s:HL('Folded', s:palette.grey, s:palette.bg1) + call s:HL('SignColumn', s:palette.fg, s:palette.bg1) + call s:HL('ToolbarLine', s:palette.fg, s:palette.bg2) +endif +call s:HL('ColorColumn', s:palette.none, s:palette.bg1) +call s:HL('Conceal', s:palette.grey, s:palette.none) +if s:configuration.cursor ==# 'auto' + call s:HL('Cursor', s:palette.none, s:palette.none, 'reverse') +elseif s:configuration.cursor ==# 'red' + call s:HL('Cursor', s:palette.bg0, s:palette.red) +elseif s:configuration.cursor ==# 'green' + call s:HL('Cursor', s:palette.bg0, s:palette.green) +elseif s:configuration.cursor ==# 'blue' + call s:HL('Cursor', s:palette.bg0, s:palette.blue) +endif +highlight! link vCursor Cursor +highlight! link iCursor Cursor +highlight! link lCursor Cursor +highlight! link CursorIM Cursor +call s:HL('CursorColumn', s:palette.none, s:palette.bg1) +call s:HL('CursorLine', s:palette.none, s:palette.bg1) +call s:HL('LineNr', s:palette.grey, s:palette.none) +if &relativenumber == 1 && &cursorline == 0 + call s:HL('CursorLineNr', s:palette.fg, s:palette.none) +else + call s:HL('CursorLineNr', s:palette.fg, s:palette.bg1) +endif +call s:HL('DiffAdd', s:palette.none, s:palette.diff_green) +call s:HL('DiffChange', s:palette.none, s:palette.diff_blue) +call s:HL('DiffDelete', s:palette.none, s:palette.diff_red) +call s:HL('DiffText', s:palette.none, s:palette.none, 'reverse') +call s:HL('Directory', s:palette.green, s:palette.none) +call s:HL('ErrorMsg', s:palette.red, s:palette.none, 'bold,underline') +call s:HL('WarningMsg', s:palette.yellow, s:palette.none, 'bold') +call s:HL('ModeMsg', s:palette.fg, s:palette.none, 'bold') +call s:HL('MoreMsg', s:palette.blue, s:palette.none, 'bold') +call s:HL('IncSearch', s:palette.bg0, s:palette.bg_red) +call s:HL('Search', s:palette.bg0, s:palette.bg_green) +call s:HL('MatchParen', s:palette.none, s:palette.bg4) +call s:HL('NonText', s:palette.bg4, s:palette.none) +call s:HL('Whitespace', s:palette.bg4, s:palette.none) +call s:HL('SpecialKey', s:palette.bg4, s:palette.none) +call s:HL('Pmenu', s:palette.fg, s:palette.bg2) +call s:HL('PmenuSbar', s:palette.none, s:palette.bg2) +if s:configuration.menu_selection_background ==# 'blue' + call s:HL('PmenuSel', s:palette.bg0, s:palette.bg_blue) + call s:HL('WildMenu', s:palette.bg0, s:palette.bg_blue) +elseif s:configuration.menu_selection_background ==# 'green' + call s:HL('PmenuSel', s:palette.bg0, s:palette.bg_green) + call s:HL('WildMenu', s:palette.bg0, s:palette.bg_green) +elseif s:configuration.menu_selection_background ==# 'red' + call s:HL('PmenuSel', s:palette.bg0, s:palette.bg_red) + call s:HL('WildMenu', s:palette.bg0, s:palette.bg_red) +endif +call s:HL('PmenuThumb', s:palette.none, s:palette.grey) +call s:HL('Question', s:palette.yellow, s:palette.none) +call s:HL('SpellBad', s:palette.red, s:palette.none, 'undercurl', s:palette.red) +call s:HL('SpellCap', s:palette.yellow, s:palette.none, 'undercurl', s:palette.yellow) +call s:HL('SpellLocal', s:palette.blue, s:palette.none, 'undercurl', s:palette.blue) +call s:HL('SpellRare', s:palette.purple, s:palette.none, 'undercurl', s:palette.purple) +call s:HL('StatusLine', s:palette.fg, s:palette.bg3) +call s:HL('StatusLineTerm', s:palette.fg, s:palette.bg3) +call s:HL('StatusLineNC', s:palette.grey, s:palette.bg1) +call s:HL('StatusLineTermNC', s:palette.grey, s:palette.bg1) +call s:HL('TabLine', s:palette.fg, s:palette.bg4) +call s:HL('TabLineFill', s:palette.grey, s:palette.bg1) +call s:HL('TabLineSel', s:palette.bg0, s:palette.bg_red) +call s:HL('VertSplit', s:palette.black, s:palette.none) +call s:HL('Visual', s:palette.none, s:palette.bg3) +call s:HL('VisualNOS', s:palette.none, s:palette.bg3, 'underline') +call s:HL('QuickFixLine', s:palette.blue, s:palette.none, 'bold') +call s:HL('Debug', s:palette.yellow, s:palette.none) +call s:HL('debugPC', s:palette.bg0, s:palette.green) +call s:HL('debugBreakpoint', s:palette.bg0, s:palette.red) +call s:HL('ToolbarButton', s:palette.bg0, s:palette.bg_blue) +if has('nvim') + highlight! link healthError Red + highlight! link healthSuccess Green + highlight! link healthWarning Yellow + highlight! link LspDiagnosticsError Grey + highlight! link LspDiagnosticsWarning Grey + highlight! link LspDiagnosticsInformation Grey + highlight! link LspDiagnosticsHint Grey + highlight! link LspReferenceText CocHighlightText + highlight! link LspReferenceRead CocHighlightText + highlight! link LspReferenceWrite CocHighlightText +endif +" +" }}} +" Syntax: {{{ +if s:configuration.enable_italic + call s:HL('Type', s:palette.blue, s:palette.none, 'italic') + call s:HL('Structure', s:palette.blue, s:palette.none, 'italic') + call s:HL('StorageClass', s:palette.blue, s:palette.none, 'italic') + call s:HL('Identifier', s:palette.orange, s:palette.none, 'italic') + call s:HL('Constant', s:palette.orange, s:palette.none, 'italic') +else + call s:HL('Type', s:palette.blue, s:palette.none) + call s:HL('Structure', s:palette.blue, s:palette.none) + call s:HL('StorageClass', s:palette.blue, s:palette.none) + call s:HL('Identifier', s:palette.orange, s:palette.none) + call s:HL('Constant', s:palette.orange, s:palette.none) +endif +call s:HL('PreProc', s:palette.red, s:palette.none) +call s:HL('PreCondit', s:palette.red, s:palette.none) +call s:HL('Include', s:palette.red, s:palette.none) +call s:HL('Keyword', s:palette.red, s:palette.none) +call s:HL('Define', s:palette.red, s:palette.none) +call s:HL('Typedef', s:palette.red, s:palette.none) +call s:HL('Exception', s:palette.red, s:palette.none) +call s:HL('Conditional', s:palette.red, s:palette.none) +call s:HL('Repeat', s:palette.red, s:palette.none) +call s:HL('Statement', s:palette.red, s:palette.none) +call s:HL('Macro', s:palette.purple, s:palette.none) +call s:HL('Error', s:palette.red, s:palette.none) +call s:HL('Label', s:palette.purple, s:palette.none) +call s:HL('Special', s:palette.purple, s:palette.none) +call s:HL('SpecialChar', s:palette.purple, s:palette.none) +call s:HL('Boolean', s:palette.purple, s:palette.none) +call s:HL('String', s:palette.yellow, s:palette.none) +call s:HL('Character', s:palette.yellow, s:palette.none) +call s:HL('Number', s:palette.purple, s:palette.none) +call s:HL('Float', s:palette.purple, s:palette.none) +call s:HL('Function', s:palette.green, s:palette.none) +call s:HL('Operator', s:palette.red, s:palette.none) +call s:HL('Title', s:palette.red, s:palette.none, 'bold') +call s:HL('Tag', s:palette.orange, s:palette.none) +call s:HL('Delimiter', s:palette.fg, s:palette.none) +if s:configuration.disable_italic_comment + call s:HL('Comment', s:palette.grey, s:palette.none) + call s:HL('SpecialComment', s:palette.grey, s:palette.none) + call s:HL('Todo', s:palette.blue, s:palette.none) +else + call s:HL('Comment', s:palette.grey, s:palette.none, 'italic') + call s:HL('SpecialComment', s:palette.grey, s:palette.none, 'italic') + call s:HL('Todo', s:palette.blue, s:palette.none, 'italic') +endif +call s:HL('Ignore', s:palette.grey, s:palette.none) +call s:HL('Underlined', s:palette.none, s:palette.none, 'underline') +" }}} +" Predefined Highlight Groups: {{{ +call s:HL('Fg', s:palette.fg, s:palette.none) +call s:HL('Grey', s:palette.grey, s:palette.none) +call s:HL('Red', s:palette.red, s:palette.none) +call s:HL('Orange', s:palette.orange, s:palette.none) +call s:HL('Yellow', s:palette.yellow, s:palette.none) +call s:HL('Green', s:palette.green, s:palette.none) +call s:HL('Blue', s:palette.blue, s:palette.none) +call s:HL('Purple', s:palette.purple, s:palette.none) +if s:configuration.enable_italic + call s:HL('RedItalic', s:palette.red, s:palette.none, 'italic') + call s:HL('BlueItalic', s:palette.blue, s:palette.none, 'italic') + call s:HL('OrangeItalic', s:palette.orange, s:palette.none, 'italic') +else + call s:HL('RedItalic', s:palette.red, s:palette.none) + call s:HL('BlueItalic', s:palette.blue, s:palette.none) + call s:HL('OrangeItalic', s:palette.orange, s:palette.none) +endif +" }}} +" +" }}} +" Extended File Types: {{{ +" Markdown: {{{ +" builtin: {{{ +call s:HL('markdownH1', s:palette.red, s:palette.none, 'bold') +call s:HL('markdownH2', s:palette.orange, s:palette.none, 'bold') +call s:HL('markdownH3', s:palette.yellow, s:palette.none, 'bold') +call s:HL('markdownH4', s:palette.green, s:palette.none, 'bold') +call s:HL('markdownH5', s:palette.blue, s:palette.none, 'bold') +call s:HL('markdownH6', s:palette.purple, s:palette.none, 'bold') +call s:HL('markdownUrl', s:palette.blue, s:palette.none, 'underline') +call s:HL('markdownItalic', s:palette.none, s:palette.none, 'italic') +call s:HL('markdownBold', s:palette.none, s:palette.none, 'bold') +call s:HL('markdownItalicDelimiter', s:palette.grey, s:palette.none, 'italic') +highlight! link markdownCode Green +highlight! link markdownCodeBlock Green +highlight! link markdownCodeDelimiter Green +highlight! link markdownBlockquote Grey +highlight! link markdownListMarker Red +highlight! link markdownOrderedListMarker Red +highlight! link markdownRule Purple +highlight! link markdownHeadingRule Grey +highlight! link markdownUrlDelimiter Grey +highlight! link markdownLinkDelimiter Grey +highlight! link markdownLinkTextDelimiter Grey +highlight! link markdownHeadingDelimiter Grey +highlight! link markdownLinkText Red +highlight! link markdownUrlTitleDelimiter Green +highlight! link markdownIdDeclaration markdownLinkText +highlight! link markdownBoldDelimiter Grey +highlight! link markdownId Yellow +" }}} +" vim-markdown: https://github.com/gabrielelana/vim-markdown{{{ +call s:HL('mkdURL', s:palette.blue, s:palette.none, 'underline') +call s:HL('mkdInlineURL', s:palette.blue, s:palette.none, 'underline') +call s:HL('mkdItalic', s:palette.grey, s:palette.none, 'italic') +highlight! link mkdCodeDelimiter Green +highlight! link mkdBold Grey +highlight! link mkdLink Red +highlight! link mkdHeading Grey +highlight! link mkdListItem Red +highlight! link mkdRule Purple +highlight! link mkdDelimiter Grey +highlight! link mkdId Yellow +" }}} +" }}} +" ReStructuredText: {{{ +" builtin: https://github.com/marshallward/vim-restructuredtext{{{ +call s:HL('rstStandaloneHyperlink', s:palette.purple, s:palette.none, 'underline') +call s:HL('rstEmphasis', s:palette.none, s:palette.none, 'italic') +call s:HL('rstStrongEmphasis', s:palette.none, s:palette.none, 'bold') +call s:HL('rstStandaloneHyperlink', s:palette.blue, s:palette.none, 'underline') +call s:HL('rstHyperlinkTarget', s:palette.blue, s:palette.none, 'underline') +highlight! link rstSubstitutionReference Blue +highlight! link rstInterpretedTextOrHyperlinkReference Green +highlight! link rstTableLines Grey +highlight! link rstInlineLiteral Green +highlight! link rstLiteralBlock Green +highlight! link rstQuotedLiteralBlock Green +" }}} +" }}} +" LaTex: {{{ +" builtin: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_TEX{{{ +highlight! link texStatement BlueItalic +highlight! link texOnlyMath Grey +highlight! link texDefName Yellow +highlight! link texNewCmd Orange +highlight! link texCmdName Blue +highlight! link texBeginEnd Red +highlight! link texBeginEndName Green +highlight! link texDocType RedItalic +highlight! link texDocTypeArgs Orange +highlight! link texInputFile Green +" }}} +" }}} +" Html: {{{ +" builtin: https://notabug.org/jorgesumle/vim-html-syntax{{{ +call s:HL('htmlH1', s:palette.red, s:palette.none, 'bold') +call s:HL('htmlH2', s:palette.orange, s:palette.none, 'bold') +call s:HL('htmlH3', s:palette.yellow, s:palette.none, 'bold') +call s:HL('htmlH4', s:palette.green, s:palette.none, 'bold') +call s:HL('htmlH5', s:palette.blue, s:palette.none, 'bold') +call s:HL('htmlH6', s:palette.purple, s:palette.none, 'bold') +call s:HL('htmlLink', s:palette.none, s:palette.none, 'underline') +call s:HL('htmlBold', s:palette.none, s:palette.none, 'bold') +call s:HL('htmlBoldUnderline', s:palette.none, s:palette.none, 'bold,underline') +call s:HL('htmlBoldItalic', s:palette.none, s:palette.none, 'bold,italic') +call s:HL('htmlBoldUnderlineItalic', s:palette.none, s:palette.none, 'bold,underline,italic') +call s:HL('htmlUnderline', s:palette.none, s:palette.none, 'underline') +call s:HL('htmlUnderlineItalic', s:palette.none, s:palette.none, 'underline,italic') +call s:HL('htmlItalic', s:palette.none, s:palette.none, 'italic') +highlight! link htmlTag Green +highlight! link htmlEndTag Blue +highlight! link htmlTagN RedItalic +highlight! link htmlTagName RedItalic +highlight! link htmlArg Blue +highlight! link htmlScriptTag Purple +highlight! link htmlSpecialTagName RedItalic +highlight! link htmlString Green +" }}} +" }}} +" Xml: {{{ +" builtin: https://github.com/chrisbra/vim-xml-ftplugin{{{ +highlight! link xmlTag Green +highlight! link xmlEndTag Blue +highlight! link xmlTagName RedItalic +highlight! link xmlEqual Orange +highlight! link xmlAttrib Blue +highlight! link xmlEntity Red +highlight! link xmlEntityPunct Red +highlight! link xmlDocTypeDecl Grey +highlight! link xmlDocTypeKeyword RedItalic +highlight! link xmlCdataStart Grey +highlight! link xmlCdataCdata Purple +highlight! link xmlString Green +" }}} +" }}} +" CSS: {{{ +" builtin: https://github.com/JulesWang/css.vim{{{ +highlight! link cssStringQ Green +highlight! link cssStringQQ Green +highlight! link cssAttrComma Grey +highlight! link cssBraces Grey +highlight! link cssTagName Purple +highlight! link cssClassNameDot Orange +highlight! link cssClassName Red +highlight! link cssFunctionName Orange +highlight! link cssAttr Green +highlight! link cssCommonAttr Green +highlight! link cssProp Blue +highlight! link cssPseudoClassId Yellow +highlight! link cssPseudoClassFn Green +highlight! link cssPseudoClass Yellow +highlight! link cssImportant Red +highlight! link cssSelectorOp Orange +highlight! link cssSelectorOp2 Orange +highlight! link cssColor Green +highlight! link cssUnitDecorators Orange +highlight! link cssValueLength Green +highlight! link cssValueInteger Green +highlight! link cssValueNumber Green +highlight! link cssValueAngle Green +highlight! link cssValueTime Green +highlight! link cssValueFrequency Green +highlight! link cssVendor Grey +highlight! link cssNoise Grey +" }}} +" }}} +" SASS: {{{ +" scss-syntax: https://github.com/cakebaker/scss-syntax.vim{{{ +highlight! link scssMixinName Orange +highlight! link scssSelectorChar Orange +highlight! link scssSelectorName Red +highlight! link scssInterpolationDelimiter Yellow +highlight! link scssVariableValue Green +highlight! link scssNull Purple +highlight! link scssBoolean Purple +highlight! link scssVariableAssignment Grey +highlight! link scssAttribute Green +highlight! link scssFunctionName Orange +highlight! link scssVariable Fg +highlight! link scssAmpersand Purple +" }}} +" }}} +" LESS: {{{ +" vim-less: https://github.com/groenewege/vim-less{{{ +highlight! link lessMixinChar Grey +highlight! link lessClass Red +highlight! link lessFunction Orange +" }}} +" }}} +" JavaScript: {{{ +" builtin: http://www.fleiner.com/vim/syntax/javascript.vim{{{ +highlight! link javaScriptNull OrangeItalic +highlight! link javaScriptIdentifier BlueItalic +highlight! link javaScriptParens Fg +highlight! link javaScriptBraces Fg +highlight! link javaScriptNumber Purple +highlight! link javaScriptLabel Red +highlight! link javaScriptGlobal BlueItalic +highlight! link javaScriptMessage BlueItalic +" }}} +" vim-javascript: https://github.com/pangloss/vim-javascript{{{ +highlight! link jsNoise Fg +highlight! link Noise Fg +highlight! link jsParens Fg +highlight! link jsBrackets Fg +highlight! link jsObjectBraces Fg +highlight! link jsThis BlueItalic +highlight! link jsUndefined OrangeItalic +highlight! link jsNull OrangeItalic +highlight! link jsNan OrangeItalic +highlight! link jsSuper OrangeItalic +highlight! link jsPrototype OrangeItalic +highlight! link jsFunction Red +highlight! link jsGlobalNodeObjects BlueItalic +highlight! link jsGlobalObjects BlueItalic +highlight! link jsArrowFunction Red +highlight! link jsArrowFuncArgs Fg +highlight! link jsFuncArgs Fg +highlight! link jsObjectProp Fg +highlight! link jsVariableDef Fg +highlight! link jsObjectKey Fg +highlight! link jsParen Fg +highlight! link jsParenIfElse Fg +highlight! link jsParenRepeat Fg +highlight! link jsParenSwitch Fg +highlight! link jsParenCatch Fg +highlight! link jsBracket Fg +highlight! link jsObjectValue Fg +highlight! link jsDestructuringBlock Fg +highlight! link jsBlockLabel Purple +highlight! link jsFunctionKey Green +highlight! link jsClassDefinition BlueItalic +highlight! link jsDot Orange +highlight! link jsSpreadExpression Purple +highlight! link jsSpreadOperator Green +highlight! link jsModuleKeyword BlueItalic +highlight! link jsTemplateExpression Purple +highlight! link jsTemplateBraces Purple +highlight! link jsClassMethodType BlueItalic +highlight! link jsExceptions BlueItalic +" }}} +" yajs: https://github.com/othree/yajs.vim{{{ +highlight! link javascriptOpSymbol Red +highlight! link javascriptOpSymbols Red +highlight! link javascriptIdentifierName Fg +highlight! link javascriptVariable BlueItalic +highlight! link javascriptObjectLabel Fg +highlight! link javascriptPropertyNameString Fg +highlight! link javascriptFuncArg Fg +highlight! link javascriptObjectLiteral Green +highlight! link javascriptIdentifier OrangeItalic +highlight! link javascriptArrowFunc Red +highlight! link javascriptTemplate Purple +highlight! link javascriptTemplateSubstitution Purple +highlight! link javascriptTemplateSB Purple +highlight! link javascriptNodeGlobal BlueItalic +highlight! link javascriptDocTags RedItalic +highlight! link javascriptDocNotation Blue +highlight! link javascriptClassSuper OrangeItalic +highlight! link javascriptClassName BlueItalic +highlight! link javascriptClassSuperName BlueItalic +highlight! link javascriptOperator Red +highlight! link javascriptBrackets Fg +highlight! link javascriptBraces Fg +highlight! link javascriptLabel Purple +highlight! link javascriptEndColons Grey +highlight! link javascriptObjectLabelColon Grey +highlight! link javascriptDotNotation Orange +highlight! link javascriptGlobalArrayDot Orange +highlight! link javascriptGlobalBigIntDot Orange +highlight! link javascriptGlobalDateDot Orange +highlight! link javascriptGlobalJSONDot Orange +highlight! link javascriptGlobalMathDot Orange +highlight! link javascriptGlobalNumberDot Orange +highlight! link javascriptGlobalObjectDot Orange +highlight! link javascriptGlobalPromiseDot Orange +highlight! link javascriptGlobalRegExpDot Orange +highlight! link javascriptGlobalStringDot Orange +highlight! link javascriptGlobalSymbolDot Orange +highlight! link javascriptGlobalURLDot Orange +highlight! link javascriptMethod Green +highlight! link javascriptMethodName Green +highlight! link javascriptObjectMethodName Green +highlight! link javascriptGlobalMethod Green +highlight! link javascriptDOMStorageMethod Green +highlight! link javascriptFileMethod Green +highlight! link javascriptFileReaderMethod Green +highlight! link javascriptFileListMethod Green +highlight! link javascriptBlobMethod Green +highlight! link javascriptURLStaticMethod Green +highlight! link javascriptNumberStaticMethod Green +highlight! link javascriptNumberMethod Green +highlight! link javascriptDOMNodeMethod Green +highlight! link javascriptES6BigIntStaticMethod Green +highlight! link javascriptBOMWindowMethod Green +highlight! link javascriptHeadersMethod Green +highlight! link javascriptRequestMethod Green +highlight! link javascriptResponseMethod Green +highlight! link javascriptES6SetMethod Green +highlight! link javascriptReflectMethod Green +highlight! link javascriptPaymentMethod Green +highlight! link javascriptPaymentResponseMethod Green +highlight! link javascriptTypedArrayStaticMethod Green +highlight! link javascriptGeolocationMethod Green +highlight! link javascriptES6MapMethod Green +highlight! link javascriptServiceWorkerMethod Green +highlight! link javascriptCacheMethod Green +highlight! link javascriptFunctionMethod Green +highlight! link javascriptXHRMethod Green +highlight! link javascriptBOMNavigatorMethod Green +highlight! link javascriptServiceWorkerMethod Green +highlight! link javascriptDOMEventTargetMethod Green +highlight! link javascriptDOMEventMethod Green +highlight! link javascriptIntlMethod Green +highlight! link javascriptDOMDocMethod Green +highlight! link javascriptStringStaticMethod Green +highlight! link javascriptStringMethod Green +highlight! link javascriptSymbolStaticMethod Green +highlight! link javascriptRegExpMethod Green +highlight! link javascriptObjectStaticMethod Green +highlight! link javascriptObjectMethod Green +highlight! link javascriptBOMLocationMethod Green +highlight! link javascriptJSONStaticMethod Green +highlight! link javascriptGeneratorMethod Green +highlight! link javascriptEncodingMethod Green +highlight! link javascriptPromiseStaticMethod Green +highlight! link javascriptPromiseMethod Green +highlight! link javascriptBOMHistoryMethod Green +highlight! link javascriptDOMFormMethod Green +highlight! link javascriptClipboardMethod Green +highlight! link javascriptTypedArrayStaticMethod Green +highlight! link javascriptBroadcastMethod Green +highlight! link javascriptDateStaticMethod Green +highlight! link javascriptDateMethod Green +highlight! link javascriptConsoleMethod Green +highlight! link javascriptArrayStaticMethod Green +highlight! link javascriptArrayMethod Green +highlight! link javascriptMathStaticMethod Green +highlight! link javascriptSubtleCryptoMethod Green +highlight! link javascriptCryptoMethod Green +highlight! link javascriptProp Fg +highlight! link javascriptBOMWindowProp Fg +highlight! link javascriptDOMStorageProp Fg +highlight! link javascriptFileReaderProp Fg +highlight! link javascriptURLUtilsProp Fg +highlight! link javascriptNumberStaticProp Fg +highlight! link javascriptDOMNodeProp Fg +highlight! link javascriptRequestProp Fg +highlight! link javascriptResponseProp Fg +highlight! link javascriptES6SetProp Fg +highlight! link javascriptPaymentProp Fg +highlight! link javascriptPaymentResponseProp Fg +highlight! link javascriptPaymentAddressProp Fg +highlight! link javascriptPaymentShippingOptionProp Fg +highlight! link javascriptTypedArrayStaticProp Fg +highlight! link javascriptServiceWorkerProp Fg +highlight! link javascriptES6MapProp Fg +highlight! link javascriptRegExpStaticProp Fg +highlight! link javascriptRegExpProp Fg +highlight! link javascriptXHRProp Fg +highlight! link javascriptBOMNavigatorProp Green +highlight! link javascriptDOMEventProp Fg +highlight! link javascriptBOMNetworkProp Fg +highlight! link javascriptDOMDocProp Fg +highlight! link javascriptSymbolStaticProp Fg +highlight! link javascriptSymbolProp Fg +highlight! link javascriptBOMLocationProp Fg +highlight! link javascriptEncodingProp Fg +highlight! link javascriptCryptoProp Fg +highlight! link javascriptBOMHistoryProp Fg +highlight! link javascriptDOMFormProp Fg +highlight! link javascriptDataViewProp Fg +highlight! link javascriptBroadcastProp Fg +highlight! link javascriptMathStaticProp Fg +" }}} +" }}} +" JavaScript React: {{{ +" vim-jsx-pretty: https://github.com/maxmellon/vim-jsx-pretty{{{ +highlight! link jsxTagName RedItalic +highlight! link jsxOpenPunct Green +highlight! link jsxClosePunct Blue +highlight! link jsxEscapeJs Purple +highlight! link jsxAttrib Blue +" }}} +" }}} +" TypeScript: {{{ +" vim-typescript: https://github.com/leafgarland/typescript-vim{{{ +highlight! link typescriptStorageClass Red +highlight! link typescriptEndColons Fg +highlight! link typescriptSource BlueItalic +highlight! link typescriptMessage Green +highlight! link typescriptGlobalObjects BlueItalic +highlight! link typescriptInterpolation Purple +highlight! link typescriptInterpolationDelimiter Purple +highlight! link typescriptBraces Fg +highlight! link typescriptParens Fg +" }}} +" yats: https:github.com/HerringtonDarkholme/yats.vim{{{ +highlight! link typescriptMethodAccessor Red +highlight! link typescriptVariable Red +highlight! link typescriptVariableDeclaration Fg +highlight! link typescriptTypeReference BlueItalic +highlight! link typescriptBraces Fg +highlight! link typescriptEnumKeyword Red +highlight! link typescriptEnum BlueItalic +highlight! link typescriptIdentifierName Fg +highlight! link typescriptProp Fg +highlight! link typescriptCall Fg +highlight! link typescriptInterfaceName BlueItalic +highlight! link typescriptEndColons Fg +highlight! link typescriptMember Fg +highlight! link typescriptMemberOptionality Red +highlight! link typescriptObjectLabel Fg +highlight! link typescriptDefaultParam Fg +highlight! link typescriptArrowFunc Red +highlight! link typescriptAbstract Red +highlight! link typescriptObjectColon Grey +highlight! link typescriptTypeAnnotation Grey +highlight! link typescriptAssign Red +highlight! link typescriptBinaryOp Red +highlight! link typescriptUnaryOp Red +highlight! link typescriptFuncComma Fg +highlight! link typescriptClassName BlueItalic +highlight! link typescriptClassHeritage BlueItalic +highlight! link typescriptInterfaceHeritage BlueItalic +highlight! link typescriptIdentifier OrangeItalic +highlight! link typescriptGlobal BlueItalic +highlight! link typescriptOperator Red +highlight! link typescriptNodeGlobal BlueItalic +highlight! link typescriptExport Red +highlight! link typescriptImport Red +highlight! link typescriptTypeParameter BlueItalic +highlight! link typescriptReadonlyModifier Red +highlight! link typescriptAccessibilityModifier Red +highlight! link typescriptAmbientDeclaration Red +highlight! link typescriptTemplateSubstitution Purple +highlight! link typescriptTemplateSB Purple +highlight! link typescriptExceptions Red +highlight! link typescriptCastKeyword Red +highlight! link typescriptOptionalMark Red +highlight! link typescriptNull OrangeItalic +highlight! link typescriptMappedIn Red +highlight! link typescriptFuncTypeArrow Red +highlight! link typescriptTernaryOp Red +highlight! link typescriptParenExp Fg +highlight! link typescriptIndexExpr Fg +highlight! link typescriptDotNotation Orange +highlight! link typescriptGlobalNumberDot Orange +highlight! link typescriptGlobalStringDot Orange +highlight! link typescriptGlobalArrayDot Orange +highlight! link typescriptGlobalObjectDot Orange +highlight! link typescriptGlobalSymbolDot Orange +highlight! link typescriptGlobalMathDot Orange +highlight! link typescriptGlobalDateDot Orange +highlight! link typescriptGlobalJSONDot Orange +highlight! link typescriptGlobalRegExpDot Orange +highlight! link typescriptGlobalPromiseDot Orange +highlight! link typescriptGlobalURLDot Orange +highlight! link typescriptGlobalMethod Green +highlight! link typescriptDOMStorageMethod Green +highlight! link typescriptFileMethod Green +highlight! link typescriptFileReaderMethod Green +highlight! link typescriptFileListMethod Green +highlight! link typescriptBlobMethod Green +highlight! link typescriptURLStaticMethod Green +highlight! link typescriptNumberStaticMethod Green +highlight! link typescriptNumberMethod Green +highlight! link typescriptDOMNodeMethod Green +highlight! link typescriptPaymentMethod Green +highlight! link typescriptPaymentResponseMethod Green +highlight! link typescriptHeadersMethod Green +highlight! link typescriptRequestMethod Green +highlight! link typescriptResponseMethod Green +highlight! link typescriptES6SetMethod Green +highlight! link typescriptReflectMethod Green +highlight! link typescriptBOMWindowMethod Green +highlight! link typescriptGeolocationMethod Green +highlight! link typescriptServiceWorkerMethod Green +highlight! link typescriptCacheMethod Green +highlight! link typescriptES6MapMethod Green +highlight! link typescriptFunctionMethod Green +highlight! link typescriptRegExpMethod Green +highlight! link typescriptXHRMethod Green +highlight! link typescriptBOMNavigatorMethod Green +highlight! link typescriptServiceWorkerMethod Green +highlight! link typescriptIntlMethod Green +highlight! link typescriptDOMEventTargetMethod Green +highlight! link typescriptDOMEventMethod Green +highlight! link typescriptDOMDocMethod Green +highlight! link typescriptStringStaticMethod Green +highlight! link typescriptStringMethod Green +highlight! link typescriptSymbolStaticMethod Green +highlight! link typescriptObjectStaticMethod Green +highlight! link typescriptObjectMethod Green +highlight! link typescriptJSONStaticMethod Green +highlight! link typescriptEncodingMethod Green +highlight! link typescriptBOMLocationMethod Green +highlight! link typescriptPromiseStaticMethod Green +highlight! link typescriptPromiseMethod Green +highlight! link typescriptSubtleCryptoMethod Green +highlight! link typescriptCryptoMethod Green +highlight! link typescriptBOMHistoryMethod Green +highlight! link typescriptDOMFormMethod Green +highlight! link typescriptConsoleMethod Green +highlight! link typescriptDateStaticMethod Green +highlight! link typescriptDateMethod Green +highlight! link typescriptArrayStaticMethod Green +highlight! link typescriptArrayMethod Green +highlight! link typescriptMathStaticMethod Green +highlight! link typescriptStringProperty Fg +highlight! link typescriptDOMStorageProp Fg +highlight! link typescriptFileReaderProp Fg +highlight! link typescriptURLUtilsProp Fg +highlight! link typescriptNumberStaticProp Fg +highlight! link typescriptDOMNodeProp Fg +highlight! link typescriptBOMWindowProp Fg +highlight! link typescriptRequestProp Fg +highlight! link typescriptResponseProp Fg +highlight! link typescriptPaymentProp Fg +highlight! link typescriptPaymentResponseProp Fg +highlight! link typescriptPaymentAddressProp Fg +highlight! link typescriptPaymentShippingOptionProp Fg +highlight! link typescriptES6SetProp Fg +highlight! link typescriptServiceWorkerProp Fg +highlight! link typescriptES6MapProp Fg +highlight! link typescriptRegExpStaticProp Fg +highlight! link typescriptRegExpProp Fg +highlight! link typescriptBOMNavigatorProp Green +highlight! link typescriptXHRProp Fg +highlight! link typescriptDOMEventProp Fg +highlight! link typescriptDOMDocProp Fg +highlight! link typescriptBOMNetworkProp Fg +highlight! link typescriptSymbolStaticProp Fg +highlight! link typescriptEncodingProp Fg +highlight! link typescriptBOMLocationProp Fg +highlight! link typescriptCryptoProp Fg +highlight! link typescriptDOMFormProp Fg +highlight! link typescriptBOMHistoryProp Fg +highlight! link typescriptMathStaticProp Fg +" }}} +" }}} +" Dart: {{{ +" dart-lang: https://github.com/dart-lang/dart-vim-plugin{{{ +highlight! link dartCoreClasses BlueItalic +highlight! link dartTypeName BlueItalic +highlight! link dartInterpolation Purple +highlight! link dartTypeDef Red +highlight! link dartClassDecl Red +highlight! link dartLibrary Red +highlight! link dartMetadata OrangeItalic +" }}} +" }}} +" C/C++: {{{ +" vim-cpp-enhanced-highlight: https://github.com/octol/vim-cpp-enhanced-highlight{{{ +highlight! link cLabel Red +highlight! link cppSTLnamespace BlueItalic +highlight! link cppSTLtype BlueItalic +highlight! link cppAccess Red +highlight! link cppStructure Red +highlight! link cppSTLios BlueItalic +highlight! link cppSTLiterator BlueItalic +highlight! link cppSTLexception Red +" }}} +" vim-cpp-modern: https://github.com/bfrg/vim-cpp-modern{{{ +highlight! link cppSTLVariable BlueItalic +" }}} +" chromatica: https://github.com/arakashic/chromatica.nvim{{{ +highlight! link Member OrangeItalic +highlight! link Variable Fg +highlight! link Namespace BlueItalic +highlight! link EnumConstant OrangeItalic +highlight! link chromaticaException Red +highlight! link chromaticaCast Red +highlight! link OperatorOverload Red +highlight! link AccessQual Red +highlight! link Linkage Red +highlight! link AutoType BlueItalic +" }}} +" vim-lsp-cxx-highlight https://github.com/jackguo380/vim-lsp-cxx-highlight{{{ +highlight! link LspCxxHlSkippedRegion Grey +highlight! link LspCxxHlSkippedRegionBeginEnd Red +highlight! link LspCxxHlGroupEnumConstant OrangeItalic +highlight! link LspCxxHlGroupNamespace BlueItalic +highlight! link LspCxxHlGroupMemberVariable OrangeItalic +" }}} +" }}} +" ObjectiveC: {{{ +" builtin: {{{ +highlight! link objcModuleImport Red +highlight! link objcException Red +highlight! link objcProtocolList Fg +highlight! link objcDirective Red +highlight! link objcPropertyAttribute Purple +highlight! link objcHiddenArgument Fg +" }}} +" }}} +" C#: {{{ +" builtin: https://github.com/nickspoons/vim-cs{{{ +highlight! link csUnspecifiedStatement Red +highlight! link csStorage Red +highlight! link csClass Red +highlight! link csNewType BlueItalic +highlight! link csContextualStatement Red +highlight! link csInterpolationDelimiter Purple +highlight! link csInterpolation Purple +highlight! link csEndColon Fg +" }}} +" }}} +" Python: {{{ +" builtin: {{{ +highlight! link pythonBuiltin BlueItalic +highlight! link pythonExceptions Red +highlight! link pythonDecoratorName OrangeItalic +" }}} +" python-syntax: https://github.com/vim-python/python-syntax{{{ +highlight! link pythonExClass BlueItalic +highlight! link pythonBuiltinType BlueItalic +highlight! link pythonBuiltinObj OrangeItalic +highlight! link pythonDottedName OrangeItalic +highlight! link pythonBuiltinFunc Green +highlight! link pythonFunction Green +highlight! link pythonDecorator OrangeItalic +highlight! link pythonInclude Include +highlight! link pythonImport PreProc +highlight! link pythonOperator Red +highlight! link pythonConditional Red +highlight! link pythonRepeat Red +highlight! link pythonException Red +highlight! link pythonNone OrangeItalic +highlight! link pythonCoding Grey +highlight! link pythonDot Grey +" }}} +" semshi: https://github.com/numirias/semshi{{{ +call s:HL('semshiUnresolved', s:palette.orange, s:palette.none, 'undercurl') +highlight! link semshiImported BlueItalic +highlight! link semshiParameter OrangeItalic +highlight! link semshiParameterUnused Grey +highlight! link semshiSelf BlueItalic +highlight! link semshiGlobal Green +highlight! link semshiBuiltin Green +highlight! link semshiAttribute OrangeItalic +highlight! link semshiLocal Red +highlight! link semshiFree Red +highlight! link semshiSelected CocHighlightText +highlight! link semshiErrorSign ALEErrorSign +highlight! link semshiErrorChar ALEErrorSign +" }}} +" }}} +" Lua: {{{ +" builtin: {{{ +highlight! link luaFunc Green +highlight! link luaFunction Red +highlight! link luaTable Fg +highlight! link luaIn Red +" }}} +" vim-lua: https://github.com/tbastos/vim-lua{{{ +highlight! link luaFuncCall Green +highlight! link luaLocal Red +highlight! link luaSpecialValue Green +highlight! link luaBraces Fg +highlight! link luaBuiltIn BlueItalic +highlight! link luaNoise Grey +highlight! link luaLabel Purple +highlight! link luaFuncTable BlueItalic +highlight! link luaFuncArgName Fg +highlight! link luaEllipsis Red +highlight! link luaDocTag Green +" }}} +" }}} +" Java: {{{ +" builtin: {{{ +highlight! link javaClassDecl Red +highlight! link javaMethodDecl Red +highlight! link javaVarArg Fg +highlight! link javaAnnotation Purple +highlight! link javaUserLabel Purple +highlight! link javaTypedef OrangeItalic +highlight! link javaParen Fg +highlight! link javaParen1 Fg +highlight! link javaParen2 Fg +highlight! link javaParen3 Fg +highlight! link javaParen4 Fg +highlight! link javaParen5 Fg +" }}} +" }}} +" Kotlin: {{{ +" kotlin-vim: https://github.com/udalov/kotlin-vim{{{ +highlight! link ktSimpleInterpolation Purple +highlight! link ktComplexInterpolation Purple +highlight! link ktComplexInterpolationBrace Purple +highlight! link ktStructure Red +highlight! link ktKeyword OrangeItalic +" }}} +" }}} +" Scala: {{{ +" builtin: https://github.com/derekwyatt/vim-scala{{{ +highlight! link scalaNameDefinition Fg +highlight! link scalaInterpolationBoundary Purple +highlight! link scalaInterpolation Purple +highlight! link scalaTypeOperator Red +highlight! link scalaOperator Red +highlight! link scalaKeywordModifier Red +" }}} +" }}} +" Go: {{{ +" builtin: https://github.com/google/vim-ft-go{{{ +highlight! link goDirective Red +highlight! link goConstants OrangeItalic +highlight! link goDeclType Red +" }}} +" polyglot: {{{ +highlight! link goPackage Red +highlight! link goImport Red +highlight! link goBuiltins Green +highlight! link goPredefinedIdentifiers OrangeItalic +highlight! link goVar Red +" }}} +" }}} +" Rust: {{{ +" builtin: https://github.com/rust-lang/rust.vim{{{ +highlight! link rustStructure Red +highlight! link rustIdentifier OrangeItalic +highlight! link rustModPath BlueItalic +highlight! link rustModPathSep Grey +highlight! link rustSelf OrangeItalic +highlight! link rustSuper OrangeItalic +highlight! link rustDeriveTrait Purple +highlight! link rustEnumVariant Purple +highlight! link rustMacroVariable OrangeItalic +highlight! link rustAssert Green +highlight! link rustPanic Green +highlight! link rustPubScopeCrate BlueItalic +highlight! link rustAttribute Purple +" }}} +" }}} +" Swift: {{{ +" swift.vim: https://github.com/keith/swift.vim{{{ +highlight! link swiftInterpolatedWrapper Purple +highlight! link swiftInterpolatedString Purple +highlight! link swiftProperty Fg +highlight! link swiftTypeDeclaration Red +highlight! link swiftClosureArgument OrangeItalic +highlight! link swiftStructure Red +" }}} +" }}} +" PHP: {{{ +" builtin: https://jasonwoof.com/gitweb/?p=vim-syntax.git;a=blob;f=php.vim;hb=HEAD{{{ +highlight! link phpVarSelector Fg +highlight! link phpIdentifier Fg +highlight! link phpDefine Green +highlight! link phpStructure Red +highlight! link phpSpecialFunction Green +highlight! link phpInterpSimpleCurly Purple +highlight! link phpComparison Red +highlight! link phpMethodsVar Fg +highlight! link phpInterpVarname Fg +highlight! link phpMemberSelector Red +highlight! link phpLabel Red +" }}} +" php.vim: https://github.com/StanAngeloff/php.vim{{{ +highlight! link phpParent Fg +highlight! link phpNowDoc Yellow +highlight! link phpFunction Green +highlight! link phpMethod Green +highlight! link phpClass BlueItalic +highlight! link phpSuperglobals BlueItalic +highlight! link phpNullValue OrangeItalic +" }}} +" }}} +" Ruby: {{{ +" builtin: https://github.com/vim-ruby/vim-ruby{{{ +highlight! link rubyKeywordAsMethod Green +highlight! link rubyInterpolation Purple +highlight! link rubyInterpolationDelimiter Purple +highlight! link rubyStringDelimiter Yellow +highlight! link rubyBlockParameterList Fg +highlight! link rubyDefine Red +highlight! link rubyModuleName Red +highlight! link rubyAccess Red +highlight! link rubyMacro Red +highlight! link rubySymbol Fg +" }}} +" }}} +" Haskell: {{{ +" haskell-vim: https://github.com/neovimhaskell/haskell-vim{{{ +highlight! link haskellBrackets Fg +highlight! link haskellIdentifier OrangeItalic +highlight! link haskellDecl Red +highlight! link haskellType BlueItalic +highlight! link haskellDeclKeyword Red +highlight! link haskellWhere Red +highlight! link haskellDeriving Red +highlight! link haskellForeignKeywords Red +" }}} +" }}} +" Perl: {{{ +" builtin: https://github.com/vim-perl/vim-perl{{{ +highlight! link perlStatementPackage Red +highlight! link perlStatementInclude Red +highlight! link perlStatementStorage Red +highlight! link perlStatementList Red +highlight! link perlMatchStartEnd Red +highlight! link perlVarSimpleMemberName Green +highlight! link perlVarSimpleMember Fg +highlight! link perlMethod Green +highlight! link podVerbatimLine Green +highlight! link podCmdText Yellow +highlight! link perlVarPlain Fg +highlight! link perlVarPlain2 Fg +" }}} +" }}} +" OCaml: {{{ +" builtin: https://github.com/rgrinberg/vim-ocaml{{{ +highlight! link ocamlArrow Red +highlight! link ocamlEqual Red +highlight! link ocamlOperator Red +highlight! link ocamlKeyChar Red +highlight! link ocamlModPath Green +highlight! link ocamlFullMod Green +highlight! link ocamlModule BlueItalic +highlight! link ocamlConstructor Orange +highlight! link ocamlModParam Fg +highlight! link ocamlModParam1 Fg +highlight! link ocamlAnyVar Fg " aqua +highlight! link ocamlPpxEncl Red +highlight! link ocamlPpxIdentifier Fg +highlight! link ocamlSigEncl Red +highlight! link ocamlModParam1 Fg +" }}} +" }}} +" Erlang: {{{ +" builtin: https://github.com/vim-erlang/vim-erlang-runtime{{{ +highlight! link erlangAtom Fg +highlight! link erlangVariable Fg +highlight! link erlangLocalFuncRef Green +highlight! link erlangLocalFuncCall Green +highlight! link erlangGlobalFuncRef Green +highlight! link erlangGlobalFuncCall Green +highlight! link erlangAttribute BlueItalic +highlight! link erlangPipe Red +" }}} +" }}} +" Elixir: {{{ +" vim-elixir: https://github.com/elixir-editors/vim-elixir{{{ +highlight! link elixirStringDelimiter Yellow +highlight! link elixirKeyword Red +highlight! link elixirInterpolation Purple +highlight! link elixirInterpolationDelimiter Purple +highlight! link elixirSelf BlueItalic +highlight! link elixirPseudoVariable OrangeItalic +highlight! link elixirModuleDefine Red +highlight! link elixirBlockDefinition Red +highlight! link elixirDefine Red +highlight! link elixirPrivateDefine Red +highlight! link elixirGuard Red +highlight! link elixirPrivateGuard Red +highlight! link elixirProtocolDefine Red +highlight! link elixirImplDefine Red +highlight! link elixirRecordDefine Red +highlight! link elixirPrivateRecordDefine Red +highlight! link elixirMacroDefine Red +highlight! link elixirPrivateMacroDefine Red +highlight! link elixirDelegateDefine Red +highlight! link elixirOverridableDefine Red +highlight! link elixirExceptionDefine Red +highlight! link elixirCallbackDefine Red +highlight! link elixirStructDefine Red +highlight! link elixirExUnitMacro Red +" }}} +" }}} +" Common Lisp: {{{ +" builtin: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_LISP{{{ +highlight! link lispAtomMark Purple +highlight! link lispKey Orange +highlight! link lispFunc Green +" }}} +" }}} +" Clojure: {{{ +" builtin: https://github.com/guns/vim-clojure-static{{{ +highlight! link clojureMacro Red +highlight! link clojureFunc Green +highlight! link clojureConstant OrangeItalic +highlight! link clojureSpecial Red +highlight! link clojureDefine Red +highlight! link clojureKeyword Blue +highlight! link clojureVariable Fg +highlight! link clojureMeta Purple +highlight! link clojureDeref Purple +" }}} +" }}} +" Matlab: {{{ +" builtin: {{{ +highlight! link matlabSemicolon Fg +highlight! link matlabFunction RedItalic +highlight! link matlabImplicit Green +highlight! link matlabDelimiter Fg +highlight! link matlabOperator Green +highlight! link matlabArithmeticOperator Red +highlight! link matlabArithmeticOperator Red +highlight! link matlabRelationalOperator Red +highlight! link matlabRelationalOperator Red +highlight! link matlabLogicalOperator Red +" }}} +" }}} +" Shell: {{{ +" builtin: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH{{{ +highlight! link shRange Fg +highlight! link shOption Purple +highlight! link shQuote Yellow +highlight! link shVariable BlueItalic +highlight! link shDerefSimple BlueItalic +highlight! link shDerefVar BlueItalic +highlight! link shDerefSpecial BlueItalic +highlight! link shDerefOff BlueItalic +highlight! link shVarAssign Red +highlight! link shFunctionOne Green +highlight! link shFunctionKey Red +" }}} +" }}} +" Zsh: {{{ +" builtin: https://github.com/chrisbra/vim-zsh{{{ +highlight! link zshOption BlueItalic +highlight! link zshSubst Orange +highlight! link zshFunction Green +" }}} +" }}} +" PowerShell: {{{ +" vim-ps1: https://github.com/PProvost/vim-ps1{{{ +highlight! link ps1FunctionInvocation Green +highlight! link ps1FunctionDeclaration Green +highlight! link ps1InterpolationDelimiter Purple +highlight! link ps1BuiltIn BlueItalic +" }}} +" }}} +" VimL: {{{ +highlight! link vimLet Red +highlight! link vimFunction Green +highlight! link vimIsCommand Fg +highlight! link vimUserFunc Green +highlight! link vimFuncName Green +highlight! link vimMap BlueItalic +highlight! link vimNotation Purple +highlight! link vimMapLhs Green +highlight! link vimMapRhs Green +highlight! link vimSetEqual BlueItalic +highlight! link vimSetSep Fg +highlight! link vimOption BlueItalic +highlight! link vimUserAttrbKey BlueItalic +highlight! link vimUserAttrb Green +highlight! link vimAutoCmdSfxList Orange +highlight! link vimSynType Orange +highlight! link vimHiBang Orange +highlight! link vimSet BlueItalic +highlight! link vimSetSep Grey +" }}} +" Makefile: {{{ +highlight! link makeIdent Purple +highlight! link makeSpecTarget BlueItalic +highlight! link makeTarget Orange +highlight! link makeCommands Red +" }}} +" CMake: {{{ +highlight! link cmakeCommand Red +highlight! link cmakeKWconfigure_package_config_file BlueItalic +highlight! link cmakeKWwrite_basic_package_version_file BlueItalic +highlight! link cmakeKWExternalProject Green +highlight! link cmakeKWadd_compile_definitions Green +highlight! link cmakeKWadd_compile_options Green +highlight! link cmakeKWadd_custom_command Green +highlight! link cmakeKWadd_custom_target Green +highlight! link cmakeKWadd_definitions Green +highlight! link cmakeKWadd_dependencies Green +highlight! link cmakeKWadd_executable Green +highlight! link cmakeKWadd_library Green +highlight! link cmakeKWadd_link_options Green +highlight! link cmakeKWadd_subdirectory Green +highlight! link cmakeKWadd_test Green +highlight! link cmakeKWbuild_command Green +highlight! link cmakeKWcmake_host_system_information Green +highlight! link cmakeKWcmake_minimum_required Green +highlight! link cmakeKWcmake_parse_arguments Green +highlight! link cmakeKWcmake_policy Green +highlight! link cmakeKWconfigure_file Green +highlight! link cmakeKWcreate_test_sourcelist Green +highlight! link cmakeKWctest_build Green +highlight! link cmakeKWctest_configure Green +highlight! link cmakeKWctest_coverage Green +highlight! link cmakeKWctest_memcheck Green +highlight! link cmakeKWctest_run_script Green +highlight! link cmakeKWctest_start Green +highlight! link cmakeKWctest_submit Green +highlight! link cmakeKWctest_test Green +highlight! link cmakeKWctest_update Green +highlight! link cmakeKWctest_upload Green +highlight! link cmakeKWdefine_property Green +highlight! link cmakeKWdoxygen_add_docs Green +highlight! link cmakeKWenable_language Green +highlight! link cmakeKWenable_testing Green +highlight! link cmakeKWexec_program Green +highlight! link cmakeKWexecute_process Green +highlight! link cmakeKWexport Green +highlight! link cmakeKWexport_library_dependencies Green +highlight! link cmakeKWfile Green +highlight! link cmakeKWfind_file Green +highlight! link cmakeKWfind_library Green +highlight! link cmakeKWfind_package Green +highlight! link cmakeKWfind_path Green +highlight! link cmakeKWfind_program Green +highlight! link cmakeKWfltk_wrap_ui Green +highlight! link cmakeKWforeach Green +highlight! link cmakeKWfunction Green +highlight! link cmakeKWget_cmake_property Green +highlight! link cmakeKWget_directory_property Green +highlight! link cmakeKWget_filename_component Green +highlight! link cmakeKWget_property Green +highlight! link cmakeKWget_source_file_property Green +highlight! link cmakeKWget_target_property Green +highlight! link cmakeKWget_test_property Green +highlight! link cmakeKWif Green +highlight! link cmakeKWinclude Green +highlight! link cmakeKWinclude_directories Green +highlight! link cmakeKWinclude_external_msproject Green +highlight! link cmakeKWinclude_guard Green +highlight! link cmakeKWinstall Green +highlight! link cmakeKWinstall_files Green +highlight! link cmakeKWinstall_programs Green +highlight! link cmakeKWinstall_targets Green +highlight! link cmakeKWlink_directories Green +highlight! link cmakeKWlist Green +highlight! link cmakeKWload_cache Green +highlight! link cmakeKWload_command Green +highlight! link cmakeKWmacro Green +highlight! link cmakeKWmark_as_advanced Green +highlight! link cmakeKWmath Green +highlight! link cmakeKWmessage Green +highlight! link cmakeKWoption Green +highlight! link cmakeKWproject Green +highlight! link cmakeKWqt_wrap_cpp Green +highlight! link cmakeKWqt_wrap_ui Green +highlight! link cmakeKWremove Green +highlight! link cmakeKWseparate_arguments Green +highlight! link cmakeKWset Green +highlight! link cmakeKWset_directory_properties Green +highlight! link cmakeKWset_property Green +highlight! link cmakeKWset_source_files_properties Green +highlight! link cmakeKWset_target_properties Green +highlight! link cmakeKWset_tests_properties Green +highlight! link cmakeKWsource_group Green +highlight! link cmakeKWstring Green +highlight! link cmakeKWsubdirs Green +highlight! link cmakeKWtarget_compile_definitions Green +highlight! link cmakeKWtarget_compile_features Green +highlight! link cmakeKWtarget_compile_options Green +highlight! link cmakeKWtarget_include_directories Green +highlight! link cmakeKWtarget_link_directories Green +highlight! link cmakeKWtarget_link_libraries Green +highlight! link cmakeKWtarget_link_options Green +highlight! link cmakeKWtarget_precompile_headers Green +highlight! link cmakeKWtarget_sources Green +highlight! link cmakeKWtry_compile Green +highlight! link cmakeKWtry_run Green +highlight! link cmakeKWunset Green +highlight! link cmakeKWuse_mangled_mesa Green +highlight! link cmakeKWvariable_requires Green +highlight! link cmakeKWvariable_watch Green +highlight! link cmakeKWwrite_file Green +" }}} +" Json: {{{ +highlight! link jsonKeyword Red +highlight! link jsonString Green +highlight! link jsonBoolean Blue +highlight! link jsonNoise Grey +highlight! link jsonQuote Grey +highlight! link jsonBraces Fg +" }}} +" Yaml: {{{ +highlight! link yamlKey Red +highlight! link yamlConstant BlueItalic +highlight! link yamlString Green +" }}} +" Toml: {{{ +call s:HL('tomlTable', s:palette.purple, s:palette.none, 'bold') +highlight! link tomlKey Red +highlight! link tomlBoolean Blue +highlight! link tomlString Green +highlight! link tomlTableArray tomlTable +" }}} +" Diff: {{{ +highlight! link diffAdded Green +highlight! link diffRemoved Red +highlight! link diffChanged Blue +highlight! link diffOldFile Yellow +highlight! link diffNewFile Orange +highlight! link diffFile Purple +highlight! link diffLine Grey +highlight! link diffIndexLine Purple +" }}} +" Git Commit: {{{ +highlight! link gitcommitSummary Red +highlight! link gitcommitUntracked Grey +highlight! link gitcommitDiscarded Grey +highlight! link gitcommitSelected Grey +highlight! link gitcommitUnmerged Grey +highlight! link gitcommitOnBranch Grey +highlight! link gitcommitArrow Grey +highlight! link gitcommitFile Green +" }}} +" INI: {{{ +call s:HL('dosiniHeader', s:palette.red, s:palette.none, 'bold') +highlight! link dosiniLabel Blue +highlight! link dosiniValue Green +highlight! link dosiniNumber Green +" }}} +" Help: {{{ +call s:HL('helpNote', s:palette.purple, s:palette.none, 'bold') +call s:HL('helpHeadline', s:palette.red, s:palette.none, 'bold') +call s:HL('helpHeader', s:palette.orange, s:palette.none, 'bold') +call s:HL('helpURL', s:palette.green, s:palette.none, 'underline') +call s:HL('helpHyperTextEntry', s:palette.blue, s:palette.none, 'bold') +highlight! link helpHyperTextJump Blue +highlight! link helpCommand Yellow +highlight! link helpExample Green +highlight! link helpSpecial Purple +highlight! link helpSectionDelim Grey +" }}} +" }}} +" Plugins: {{{ +" junegunn/vim-plug{{{ +call s:HL('plug1', s:palette.red, s:palette.none, 'bold') +call s:HL('plugNumber', s:palette.yellow, s:palette.none, 'bold') +highlight! link plug2 Blue +highlight! link plugBracket Blue +highlight! link plugName Green +highlight! link plugDash Red +highlight! link plugNotLoaded Grey +highlight! link plugH2 Purple +highlight! link plugMessage Purple +highlight! link plugError Red +highlight! link plugRelDate Grey +highlight! link plugStar Purple +highlight! link plugUpdate Blue +highlight! link plugDeleted Grey +highlight! link plugEdge Purple +" }}} +" neoclide/coc.nvim{{{ +if s:configuration.current_word ==# 'bold' + call s:HL('CocHighlightText', s:palette.none, s:palette.none, 'bold') +elseif s:configuration.current_word ==# 'underline' + call s:HL('CocHighlightText', s:palette.none, s:palette.none, 'underline') +elseif s:configuration.current_word ==# 'italic' + call s:HL('CocHighlightText', s:palette.none, s:palette.none, 'italic') +elseif s:configuration.current_word ==# 'grey background' + call s:HL('CocHighlightText', s:palette.none, s:palette.bg1) +endif +call s:HL('CocHoverRange', s:palette.none, s:palette.none, 'bold,underline') +call s:HL('CocHintHighlight', s:palette.none, s:palette.none, 'undercurl', s:palette.green) +call s:HL('CocErrorFloat', s:palette.red, s:palette.bg2) +call s:HL('CocWarningFloat', s:palette.yellow, s:palette.bg2) +call s:HL('CocInfoFloat', s:palette.blue, s:palette.bg2) +call s:HL('CocHintFloat', s:palette.green, s:palette.bg2) +if s:configuration.transparent_background + call s:HL('CocHintSign', s:palette.purple, s:palette.none) +else + call s:HL('CocHintSign', s:palette.purple, s:palette.bg1) +endif +highlight! link CocCodeLens Grey +highlight! link CocErrorSign ALEErrorSign +highlight! link CocWarningSign ALEWarningSign +highlight! link CocInfoSign ALEInfoSign +highlight! link CocHintSign Label +highlight! link CocErrorHighlight ALEError +highlight! link CocWarningHighlight ALEWarning +highlight! link CocInfoHighlight ALEInfo +highlight! link CocWarningVirtualText ALEVirtualTextWarning +highlight! link CocErrorVirtualText ALEVirtualTextError +highlight! link CocInfoVirtualText ALEVirtualTextInfo +highlight! link CocHintVirtualText ALEVirtualTextInfo +highlight! link CocGitAddedSign GitGutterAdd +highlight! link CocGitChangeRemovedSign GitGutterChangeDelete +highlight! link CocGitChangedSign GitGutterChange +highlight! link CocGitRemovedSign GitGutterDelete +highlight! link CocGitTopRemovedSign GitGutterDelete +highlight! link CocExplorerBufferRoot Red +highlight! link CocExplorerBufferExpandIcon Blue +highlight! link CocExplorerBufferBufnr Yellow +highlight! link CocExplorerBufferModified Red +highlight! link CocExplorerBufferBufname Grey +highlight! link CocExplorerBufferFullpath Grey +highlight! link CocExplorerFileRoot Red +highlight! link CocExplorerFileExpandIcon Blue +highlight! link CocExplorerFileFullpath Grey +highlight! link CocExplorerFileDirectory Green +highlight! link CocExplorerFileGitStage Blue +highlight! link CocExplorerFileGitUnstage Yellow +highlight! link CocExplorerFileSize Blue +highlight! link CocExplorerTimeAccessed Purple +highlight! link CocExplorerTimeCreated Purple +highlight! link CocExplorerTimeModified Purple +highlight! link CocExplorerFileRootName Orange +highlight! link CocExplorerBufferNameVisible Green +" }}} +" dense-analysis/ale{{{ +call s:HL('ALEError', s:palette.none, s:palette.none, 'undercurl', s:palette.red) +call s:HL('ALEWarning', s:palette.none, s:palette.none, 'undercurl', s:palette.yellow) +call s:HL('ALEInfo', s:palette.none, s:palette.none, 'undercurl', s:palette.blue) +if s:configuration.transparent_background + call s:HL('ALEErrorSign', s:palette.red, s:palette.none) + call s:HL('ALEWarningSign', s:palette.yellow, s:palette.none) + call s:HL('ALEInfoSign', s:palette.blue, s:palette.none) +else + call s:HL('ALEErrorSign', s:palette.red, s:palette.bg1) + call s:HL('ALEWarningSign', s:palette.yellow, s:palette.bg1) + call s:HL('ALEInfoSign', s:palette.blue, s:palette.bg1) +endif +highlight! link ALEVirtualTextError Grey +highlight! link ALEVirtualTextWarning Grey +highlight! link ALEVirtualTextInfo Grey +highlight! link ALEVirtualTextStyleError ALEVirtualTextError +highlight! link ALEVirtualTextStyleWarning ALEVirtualTextWarning +" }}} +" neomake/neomake{{{ +highlight! link NeomakeError ALEError +highlight! link NeomakeErrorSign ALEErrorSign +highlight! link NeomakeWarning ALEWarning +highlight! link NeomakeWarningSign ALEWarningSign +highlight! link NeomakeInfo ALEInfo +highlight! link NeomakeInfoSign ALEInfoSign +highlight! link NeomakeMessage ALEInfo +highlight! link NeomakeMessageSign CocHintSign +highlight! link NeomakeVirtualtextError Grey +highlight! link NeomakeVirtualtextWarning Grey +highlight! link NeomakeVirtualtextInfo Grey +highlight! link NeomakeVirtualtextMessag Grey +" }}} +" vim-syntastic/syntastic{{{ +highlight! link SyntasticError ALEError +highlight! link SyntasticWarning ALEWarning +highlight! link SyntasticErrorSign ALEErrorSign +highlight! link SyntasticWarningSign ALEWarningSign +" }}} +" Yggdroot/LeaderF{{{ +if !exists('g:Lf_StlColorscheme') + let g:Lf_StlColorscheme = 'one' +endif +call s:HL('Lf_hl_match', s:palette.green, s:palette.none, 'bold') +call s:HL('Lf_hl_match0', s:palette.green, s:palette.none, 'bold') +call s:HL('Lf_hl_match1', s:palette.blue, s:palette.none, 'bold') +call s:HL('Lf_hl_match2', s:palette.red, s:palette.none, 'bold') +call s:HL('Lf_hl_match3', s:palette.yellow, s:palette.none, 'bold') +call s:HL('Lf_hl_match4', s:palette.purple, s:palette.none, 'bold') +call s:HL('Lf_hl_matchRefine', s:palette.yellow, s:palette.none, 'bold') +highlight! link Lf_hl_cursorline Fg +highlight! link Lf_hl_selection DiffAdd +highlight! link Lf_hl_rgHighlight Visual +highlight! link Lf_hl_gtagsHighlight Visual +" }}} +" junegunn/fzf.vim{{{ +let g:fzf_colors = { + \ 'fg': ['fg', 'Normal'], + \ 'bg': ['bg', 'Normal'], + \ 'hl': ['fg', 'Green'], + \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'], + \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], + \ 'hl+': ['fg', 'Green'], + \ 'info': ['fg', 'Yellow'], + \ 'prompt': ['fg', 'Red'], + \ 'pointer': ['fg', 'Blue'], + \ 'marker': ['fg', 'Blue'], + \ 'spinner': ['fg', 'Yellow'], + \ 'header': ['fg', 'Blue'] + \ } +" }}} +" Shougo/denite.nvim{{{ +call s:HL('deniteMatchedChar', s:palette.green, s:palette.none, 'bold') +call s:HL('deniteMatchedRange', s:palette.green, s:palette.none, 'bold,underline') +call s:HL('deniteInput', s:palette.green, s:palette.bg1, 'bold') +call s:HL('deniteStatusLineNumber', s:palette.purple, s:palette.bg1) +call s:HL('deniteStatusLinePath', s:palette.fg, s:palette.bg1) +highlight! link deniteSelectedLine Green +" }}} +" kien/ctrlp.vim{{{ +call s:HL('CtrlPMatch', s:palette.green, s:palette.none, 'bold') +call s:HL('CtrlPPrtBase', s:palette.grey, s:palette.none) +call s:HL('CtrlPLinePre', s:palette.grey, s:palette.none) +call s:HL('CtrlPMode1', s:palette.blue, s:palette.bg1, 'bold') +call s:HL('CtrlPMode2', s:palette.bg1, s:palette.blue, 'bold') +call s:HL('CtrlPStats', s:palette.grey, s:palette.bg1, 'bold') +highlight! link CtrlPNoEntries Red +highlight! link CtrlPPrtCursor Blue +" }}} +" majutsushi/tagbar{{{ +highlight! link TagbarFoldIcon Blue +highlight! link TagbarSignature Green +highlight! link TagbarKind Red +highlight! link TagbarScope Orange +highlight! link TagbarNestedKind Blue +highlight! link TagbarVisibilityPrivate Red +highlight! link TagbarVisibilityPublic Blue +" }}} +" liuchengxu/vista.vim{{{ +highlight! link VistaBracket Grey +highlight! link VistaChildrenNr Yellow +highlight! link VistaScope Red +highlight! link VistaTag Green +highlight! link VistaPrefix Grey +highlight! link VistaColon Green +highlight! link VistaIcon Purple +highlight! link VistaLineNr Fg +" }}} +" airblade/vim-gitgutter{{{ +if s:configuration.transparent_background + call s:HL('GitGutterAdd', s:palette.green, s:palette.none) + call s:HL('GitGutterChange', s:palette.blue, s:palette.none) + call s:HL('GitGutterDelete', s:palette.red, s:palette.none) + call s:HL('GitGutterChangeDelete', s:palette.purple, s:palette.none) +else + call s:HL('GitGutterAdd', s:palette.green, s:palette.bg1) + call s:HL('GitGutterChange', s:palette.blue, s:palette.bg1) + call s:HL('GitGutterDelete', s:palette.red, s:palette.bg1) + call s:HL('GitGutterChangeDelete', s:palette.purple, s:palette.bg1) +endif +" }}} +" mhinz/vim-signify{{{ +highlight! link SignifySignAdd GitGutterAdd +highlight! link SignifySignChange GitGutterChange +highlight! link SignifySignDelete GitGutterDelete +highlight! link SignifySignChangeDelete GitGutterChangeDelete +" }}} +" scrooloose/nerdtree{{{ +highlight! link NERDTreeDir Green +highlight! link NERDTreeDirSlash Green +highlight! link NERDTreeOpenable Blue +highlight! link NERDTreeClosable Blue +highlight! link NERDTreeFile Fg +highlight! link NERDTreeExecFile Red +highlight! link NERDTreeUp Grey +highlight! link NERDTreeCWD Purple +highlight! link NERDTreeHelp Grey +highlight! link NERDTreeToggleOn Green +highlight! link NERDTreeToggleOff Red +highlight! link NERDTreeFlags Blue +highlight! link NERDTreeLinkFile Grey +highlight! link NERDTreeLinkTarget Green +" }}} +" justinmk/vim-dirvish{{{ +highlight! link DirvishPathTail Blue +highlight! link DirvishArg Yellow +" }}} +" vim.org/netrw {{{ +" https://www.vim.org/scripts/script.php?script_id=1075 +highlight! link netrwDir Green +highlight! link netrwClassify Green +highlight! link netrwLink Grey +highlight! link netrwSymLink Fg +highlight! link netrwExe Red +highlight! link netrwComment Grey +highlight! link netrwList Yellow +highlight! link netrwHelpCmd Blue +highlight! link netrwCmdSep Grey +highlight! link netrwVersion Purple +" }}} +" andymass/vim-matchup{{{ +call s:HL('MatchParenCur', s:palette.none, s:palette.none, 'bold') +call s:HL('MatchWord', s:palette.none, s:palette.none, 'underline') +call s:HL('MatchWordCur', s:palette.none, s:palette.none, 'underline') +" }}} +" easymotion/vim-easymotion {{{ +highlight! link EasyMotionTarget Search +highlight! link EasyMotionShade Grey +" }}} +" justinmk/vim-sneak {{{ +highlight! link Sneak Cursor +highlight! link SneakLabel Cursor +highlight! link SneakScope DiffAdd +" }}} +" terryma/vim-multiple-cursors{{{ +highlight! link multiple_cursors_cursor Cursor +highlight! link multiple_cursors_visual Visual +" }}} +" mg979/vim-visual-multi{{{ +let g:VM_Mono_hl = 'Cursor' +let g:VM_Extend_hl = 'Visual' +let g:VM_Cursor_hl = 'Cursor' +let g:VM_Insert_hl = 'Cursor' +" }}} +" dominikduda/vim_current_word{{{ +highlight! link CurrentWord CocHighlightText +highlight! link CurrentWordTwins CocHighlightText +" }}} +" RRethy/vim-illuminate{{{ +highlight! link illuminatedWord CocHighlightText +" }}} +" itchyny/vim-cursorword{{{ +highlight! link CursorWord0 CocHighlightText +highlight! link CursorWord1 CocHighlightText +" }}} +" Yggdroot/indentLine{{{ +let g:indentLine_color_gui = s:palette.grey[0] +let g:indentLine_color_term = s:palette.grey[1] +" }}} +" nathanaelkane/vim-indent-guides{{{ +if get(g:, 'indent_guides_auto_colors', 1) == 0 + call s:HL('IndentGuidesOdd', s:palette.bg0, s:palette.bg1) + call s:HL('IndentGuidesEven', s:palette.bg0, s:palette.bg2) +endif +" }}} +" kshenoy/vim-signature {{{ +if s:configuration.transparent_background + call s:HL('SignatureMarkText', s:palette.blue, s:palette.none) + call s:HL('SignatureMarkerText', s:palette.red, s:palette.none) +else + call s:HL('SignatureMarkText', s:palette.blue, s:palette.bg1) + call s:HL('SignatureMarkerText', s:palette.red, s:palette.bg1) +endif +" }}} +" mhinz/vim-startify{{{ +highlight! link StartifyBracket Grey +highlight! link StartifyFile Green +highlight! link StartifyNumber Orange +highlight! link StartifyPath Grey +highlight! link StartifySlash Grey +highlight! link StartifySection Blue +highlight! link StartifyHeader Red +highlight! link StartifySpecial Grey +" }}} +" ap/vim-buftabline{{{ +highlight! link BufTabLineCurrent TabLineSel +highlight! link BufTabLineActive TabLine +highlight! link BufTabLineHidden TabLineFill +highlight! link BufTabLineFill TabLineFill +" }}} +" liuchengxu/vim-which-key{{{ +highlight! link WhichKey Red +highlight! link WhichKeySeperator Green +highlight! link WhichKeyGroup Orange +highlight! link WhichKeyDesc Blue +" }}} +" skywind3000/quickmenu.vim{{{ +highlight! link QuickmenuOption Green +highlight! link QuickmenuNumber Orange +highlight! link QuickmenuBracket Grey +highlight! link QuickmenuHelp Blue +highlight! link QuickmenuSpecial Grey +highlight! link QuickmenuHeader Purple +" }}} +" mbbill/undotree{{{ +call s:HL('UndotreeSavedBig', s:palette.red, s:palette.none, 'bold') +highlight! link UndotreeNode Blue +highlight! link UndotreeNodeCurrent Purple +highlight! link UndotreeSeq Green +highlight! link UndotreeCurrent Blue +highlight! link UndotreeNext Yellow +highlight! link UndotreeTimeStamp Grey +highlight! link UndotreeHead Purple +highlight! link UndotreeBranch Blue +highlight! link UndotreeSavedSmall Red +" }}} +" unblevable/quick-scope {{{ +call s:HL('QuickScopePrimary', s:palette.green, s:palette.none, 'underline') +call s:HL('QuickScopeSecondary', s:palette.blue, s:palette.none, 'underline') +" }}} +" APZelos/blamer.nvim {{{ +highlight! link Blamer Grey +" }}} +" cohama/agit.vim {{{ +highlight! link agitTree Grey +highlight! link agitDate Green +highlight! link agitRemote Red +highlight! link agitHead Blue +highlight! link agitRef Orange +highlight! link agitTag Blue +highlight! link agitStatFile Blue +highlight! link agitStatRemoved Red +highlight! link agitStatAdded Green +highlight! link agitStatMessage Orange +highlight! link agitDiffRemove diffRemoved +highlight! link agitDiffAdd diffAdded +highlight! link agitDiffHeader Blue +highlight! link agitAuthor Yellow +" }}} +" }}} +" Terminal: {{{ +if (has('termguicolors') && &termguicolors) || has('gui_running') + " Definition + let s:terminal = { + \ 'black': s:palette.black, + \ 'red': s:palette.red, + \ 'yellow': s:palette.yellow, + \ 'green': s:palette.green, + \ 'cyan': s:palette.orange, + \ 'blue': s:palette.blue, + \ 'purple': s:palette.purple, + \ 'white': s:palette.fg + \ } + " Implementation: {{{ + if !has('nvim') + let g:terminal_ansi_colors = [s:terminal.black[0], s:terminal.red[0], s:terminal.green[0], s:terminal.yellow[0], + \ s:terminal.blue[0], s:terminal.purple[0], s:terminal.cyan[0], s:terminal.white[0], s:terminal.black[0], s:terminal.red[0], + \ s:terminal.green[0], s:terminal.yellow[0], s:terminal.blue[0], s:terminal.purple[0], s:terminal.cyan[0], s:terminal.white[0]] + else + let g:terminal_color_0 = s:terminal.black[0] + let g:terminal_color_1 = s:terminal.red[0] + let g:terminal_color_2 = s:terminal.green[0] + let g:terminal_color_3 = s:terminal.yellow[0] + let g:terminal_color_4 = s:terminal.blue[0] + let g:terminal_color_5 = s:terminal.purple[0] + let g:terminal_color_6 = s:terminal.cyan[0] + let g:terminal_color_7 = s:terminal.white[0] + let g:terminal_color_8 = s:terminal.black[0] + let g:terminal_color_9 = s:terminal.red[0] + let g:terminal_color_10 = s:terminal.green[0] + let g:terminal_color_11 = s:terminal.yellow[0] + let g:terminal_color_12 = s:terminal.blue[0] + let g:terminal_color_13 = s:terminal.purple[0] + let g:terminal_color_14 = s:terminal.cyan[0] + let g:terminal_color_15 = s:terminal.white[0] + endif + " }}} +endif +" }}} + +" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker fmr={{{,}}}: diff --git a/.config/nvim/ftplugin/c.vim b/.config/nvim/ftplugin/c.vim new file mode 100644 index 0000000..e1b4628 --- /dev/null +++ b/.config/nvim/ftplugin/c.vim @@ -0,0 +1,2 @@ +setlocal colorcolumn=80 +setlocal textwidth=79 diff --git a/.config/nvim/ftplugin/cpp.vim b/.config/nvim/ftplugin/cpp.vim new file mode 100644 index 0000000..e1b4628 --- /dev/null +++ b/.config/nvim/ftplugin/cpp.vim @@ -0,0 +1,2 @@ +setlocal colorcolumn=80 +setlocal textwidth=79 diff --git a/.config/nvim/ftplugin/lua.vim b/.config/nvim/ftplugin/lua.vim new file mode 100644 index 0000000..e615312 --- /dev/null +++ b/.config/nvim/ftplugin/lua.vim @@ -0,0 +1,2 @@ +set textwidth=79 +set colorcolumn=80 diff --git a/.config/nvim/ftplugin/markdown.vim b/.config/nvim/ftplugin/markdown.vim new file mode 100644 index 0000000..cb1e5b3 --- /dev/null +++ b/.config/nvim/ftplugin/markdown.vim @@ -0,0 +1,10 @@ +" Show a visual line at width 120 +setlocal colorcolumn=80 +" This auto-wraps the lines after it's reached more than 119 characters. +setlocal textwidth=79 + +" Spellcheck +" Turn on spell check +setlocal spell +" Set it to English US +setlocal spelllang=en diff --git a/.config/nvim/ftplugin/python.vim b/.config/nvim/ftplugin/python.vim new file mode 100644 index 0000000..ccc3bc8 --- /dev/null +++ b/.config/nvim/ftplugin/python.vim @@ -0,0 +1,6 @@ +" Show a visual market at text width 80 +setlocal colorcolumn=81 + +" Auto-wrap lines +setlocal textwidth=80 + diff --git a/.config/nvim/ftplugin/rust.vim b/.config/nvim/ftplugin/rust.vim new file mode 100644 index 0000000..e1b4628 --- /dev/null +++ b/.config/nvim/ftplugin/rust.vim @@ -0,0 +1,2 @@ +setlocal colorcolumn=80 +setlocal textwidth=79 diff --git a/.config/nvim/ftplugin/vim.vim b/.config/nvim/ftplugin/vim.vim new file mode 100644 index 0000000..c13c740 --- /dev/null +++ b/.config/nvim/ftplugin/vim.vim @@ -0,0 +1,2 @@ +setlocal textwidth=79 +setlocal colorcolumn=80 diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim new file mode 100644 index 0000000..192116b --- /dev/null +++ b/.config/nvim/init.vim @@ -0,0 +1,25 @@ +" The leader key is the main modifier used for keybindings. +" You can use it inside keybindings by using +" I use space as my leader key +let g:mapleader = ' ' +" Local leader is the same principle as leader, but it's used +" for keybindings that are local to the current buffer, to +" avoid confusion +" I use tab as my local leader +let g:maplocalleader = "\" + +" Here, I source the various config files. I explicitely source them one by one +" to ensure their order is always the same (the autocmds are needed later, e.g. +" when the colorscheme is sourced) +runtime init/autocmds.vim +runtime init/keys.vim +runtime init/netrw.vim +runtime init/settings.vim + +" The configs for the various plugins don't have a particular order to them +runtime! init/plugins/*.vim + +" This sources a .vim/local.vim file in the current directory, if it exists. +" This allows for project-specific settings, such as on-write autocmd's etc. +" The silent! prevents it from showing an error if no local.vim file is found +silent! source .vim/local.vim diff --git a/.config/nvim/init/autocmds.vim b/.config/nvim/init/autocmds.vim new file mode 100644 index 0000000..fc65f3f --- /dev/null +++ b/.config/nvim/init/autocmds.vim @@ -0,0 +1,12 @@ +function! OverwriteBackground() + " We only want a transparent background if we're using the dark theme + if g:colors_name == 'flattened_dark' + highlight Normal guibg=NONE ctermbg=NONE + highlight LineNr ctermfg=NONE ctermbg=NONE + endif +endfunction + +augroup ColorschemeOverwrite + autocmd! + autocmd ColorScheme * call OverwriteBackground() +augroup END diff --git a/.config/nvim/init/keys.vim b/.config/nvim/init/keys.vim new file mode 100644 index 0000000..3d6799b --- /dev/null +++ b/.config/nvim/init/keys.vim @@ -0,0 +1,94 @@ +" zz centers the cursor, so combining this with navigation commands keeps my +" cursor centered +" nnoremap j jzz +" nnoremap k kzz +" nnoremap gg ggzz +" nnoremap G Gzz + +" I navigate my splits using hjkl. This setup allows for fast +" switching, which is important as I often end up with 3-4 splits after a while +nnoremap h :wincmd h +nnoremap j :wincmd j +nnoremap k :wincmd k +nnoremap l :wincmd l + +" These mappings just exist because I'm lazy, and they only really work in +" QWERTY +nnoremap w :w +nnoremap q :q + +" As I don't use the arrow keys for navigation, I remapped them to allow for +" resizing of my splits. If you hold down shift, you can control the size of +" the splits more precisely +nnoremap :resize +5 +nnoremap :resize -5 +nnoremap :vertical resize +5 +nnoremap :vertical resize -5 +nnoremap :resize +1 +nnoremap :resize -1 +nnoremap :vertical resize +1 +nnoremap :vertical resize -1 + +" Disable arrow keys in editing & visual mode, as I have no need for them +inoremap +inoremap +inoremap +inoremap +vnoremap +vnoremap +vnoremap +vnoremap + +" Tabs bindings +" TODO improve on these +" Create tab +nnoremap o :tabnew +" Close current tab +nnoremap p :tabclose +" Go to next tab +nnoremap i :tabnext +" Go to previous tab +nnoremap u :tabprevious + +" This function allows me to switch between a dark & light theme. I mainly use +" the dark theme, but when I'm sitting outside, the light theme can be much +" more readable +function! ColorschemeToggle() + if g:colors_name == 'flattened_dark' + colorscheme flattened_light + else + colorscheme flattened_dark + endif +endfunction + +nnoremap c :call ColorschemeToggle() + +" As I'm constantly tweaking my config, I use keybindings to easily open & +" source it without leaving my session +nnoremap vs :source $MYVIMRC +" Opens CtrlP in my config directory +nnoremap ve :split:exec 'CtrlP ' . fnamemodify($MYVIMRC, ':h') + +" This was probably one of the best ideas I found (it wasn't my original idea). +" By remapping Esc to jk, I could switch between modes without moving my hands. +" This improved my speed by much more than I was expecting, and helped with not +" straining my hands as much. +inoremap jk +inoremap + +" I use this binding to quickly switch between two files. +nnoremap a + +" Terminal keybindings +" I use the terminal inside Neovim a lot, so I have some keybindings to easily +" open one +" Use jk in terminal as well +tnoremap jk + +" I explicitely use $SHELL, because my main shell is not necessarily Bash, and +" I want to use my main shell inside Vim as well +nnoremap rr :e term://$SHELL +nnoremap rh :vsp:wincmd h:e term://$SHELL +nnoremap rl :vsp:e term://$SHELL +nnoremap rk :sp:wincmd k:e term://$SHELL +nnoremap rj :sp:e term://$SHELL diff --git a/.config/nvim/init/netrw.vim b/.config/nvim/init/netrw.vim new file mode 100644 index 0000000..95a966d --- /dev/null +++ b/.config/nvim/init/netrw.vim @@ -0,0 +1,20 @@ +" Open in tree view by default +let g:netrw_liststyle = 3 + +" Hide banner at the top +let g:netrw_banner = 0 + +" Change how netrc opens files +" 1 - horizontal split +" 2 - vertical split +" 3 - new tab +" 4 - previous window +let g:netrw_browse_split = 4 + +" Width of the view +let g:netrw_winsize = 15 + +" Start netrc on startup +augroup netrc + autocmd! +augroup END diff --git a/.config/nvim/init/plugins/README.md b/.config/nvim/init/plugins/README.md new file mode 100644 index 0000000..81d7cd2 --- /dev/null +++ b/.config/nvim/init/plugins/README.md @@ -0,0 +1,46 @@ +# Plugins +I use quite a lot of plugins, as they greatly improve my workflow or just add +features that you most definitely need if you want to use Vim as your main +editor. + +## List of plugins + +* [CoC](https://github.com/neoclide/coc.nvim): my autocomplete plugin of + choice. It provide full LSP support, so many of its plugins use the exact + same setup as a VSCode plugin. +* [CtrlP](https://github.com/ctrlpvim/ctrlp.vim): a fuzzy search tool which I + use for most navigation. +* [vim-fugitive](https://github.com/tpope/vim-fugitive): an amazing Git client + for Vim. It has support for all the usual stuff (commits, adding/removing + files etc.), as well as a merge conflict resolver using Vim's built-in diff + view. +* [vim-surround](https://github.com/tpope/vim-surround): adds mappings to + change/remove surrounding characters (e.g. (), "", '' etc.). It integrates + really well with already existing bindings, making it feel like it's a + built-in feature. +* [vim-commentary](https://github.com/tpope/vim-commentary): adds mappings for + commenting/uncommenting lines easily. It has support for basically all + languages I ever use. +* [tagbar](https://github.com/preservim/tagbar): a sidebar chowing you the + layout of the current file. It helps me orient myself within the file/class + I'm currently working on, as well as easing the movement between + classes, functions etc... +* [vim-gitgutter](https://github.com/airblade/vim-gitgutter): shows Git + diff markers in the sidebar. +* [indentline](https://github.com/Yggdroot/indentLine): shows a visual line to + indicate which lines are on the same indentation level. +* vim-python-pep8-indent: makes Vim properly indent Python according to PEP8 +* [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object): + allows you to select the current indentation block using the same bindings as + paragraphs, inner brackets, etc... +* NERDTree: file browser, useful for getting your bearings in a large project. +* [vim-toml](https://github.com/cespare/vim-toml): syntax highlighting for toml + files +* [auto-pairs](https://github.com/jiangmiao/auto-pairs): auto-insert matching + pairs +* [Tabular](https://github.com/godlygeek/tabular): useful plugin for aligning + text +* [haskell-vim](https://github.com/neovimhaskell/haskell-vim): indentation for + Haskell +* [ion-vim](https://github.com/vmchale/ion-vim): syntax highlighting for the + [ion shell](https://github.com/redox-os/ion) (my current shell). diff --git a/.config/nvim/init/plugins/coc.vim b/.config/nvim/init/plugins/coc.vim new file mode 100644 index 0000000..aa1af68 --- /dev/null +++ b/.config/nvim/init/plugins/coc.vim @@ -0,0 +1,38 @@ +function! s:check_back_space() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~ '\s' +endfunction + +inoremap + \ pumvisible() ? "\" : + \ check_back_space() ? "\" : + \ coc#refresh() + +" Navigating through results list +" Tab to select next result +inoremap pumvisible() ? "\" : "\" +" Shift+Tab to select previous +inoremap pumvisible() ? "\" : "\" +" Use enter to confirm completion +inoremap pumvisible() ? "\" : "\u\" +" Select first option if no option is selected on enter +inoremap pumvisible() ? coc#_select_confirm() : "\u\" + +" Project refactoring keybinding +nnoremap pwr :CocSearch =expand("") + +" Go to definition +nmap gd (coc-definition) +nmap gb +nmap gi (coc-implementation) +nmap gr (coc-references) + +" Jump between diagnostic positions +nmap dk (coc-diagnostic-prev) +nmap dK (coc-diagnostic-prev-error) +nmap dj (coc-diagnostic-next) +nmap dJ (coc-diagnostic-next-error) + +" Show full diagnostics list +nmap dd :CocDiagnostics + diff --git a/.config/nvim/init/plugins/ctrlp.vim b/.config/nvim/init/plugins/ctrlp.vim new file mode 100644 index 0000000..b3d5761 --- /dev/null +++ b/.config/nvim/init/plugins/ctrlp.vim @@ -0,0 +1,28 @@ +" Remap CtrlP shortcut +let g:ctrlp_map = 't' + +" Enable caching +" I think this'll make it run just a bit faster +let g:ctrlp_use_caching = 1 +" Don't clear the cache on exit, so it won't re-index every time we open the +" project +let g:ctrlp_clear_cache_on_exit = 0 +" Cache inside the project's .vim directory to keep things tidy +let g:ctrlp_cache_dir = './.vim/cache/ctrlp' + +" You can define different listing commands for different version controls +" systems etc. +" I currently only have experience with Git, but I've written the config like +" this to allow for easy expansion if needed. +let g:ctrlp_user_command = { + \ 'types': { + \ 1: ['.git', 'git --git-dir=%s/.git ls-files -oc --exclude-standard'] + \ }, + \ 'fallback': 'find %s -type f' +\ } + +" Limit max number of files +" This prevents me from indexing my entire HOME by accident +let g:ctrlp_max_files = 10000 +" Also limit recursion depth +let g:ctrlp_max_depth = 40 diff --git a/.config/nvim/init/plugins/git-fugitive.vim b/.config/nvim/init/plugins/git-fugitive.vim new file mode 100644 index 0000000..f296b94 --- /dev/null +++ b/.config/nvim/init/plugins/git-fugitive.vim @@ -0,0 +1,12 @@ +" Key bindings for quicker Git work +" Status +nnoremap gg :Git +" Commit +nnoremap gc :Git commit +" Push +nnoremap gp :Git push +" Show diffs +nnoremap gd :Gvdiffsplit! +" Easily resolve merges +nnoremap gh :diffget //2 +nnoremap gl :diffget //3 diff --git a/.config/nvim/init/plugins/gitgutter.vim b/.config/nvim/init/plugins/gitgutter.vim new file mode 100644 index 0000000..5c59776 --- /dev/null +++ b/.config/nvim/init/plugins/gitgutter.vim @@ -0,0 +1,2 @@ +" Disable key mappings +let g:gitgutter_map_keys = 0 diff --git a/.config/nvim/init/plugins/gutentags.vim b/.config/nvim/init/plugins/gutentags.vim new file mode 100644 index 0000000..b27308c --- /dev/null +++ b/.config/nvim/init/plugins/gutentags.vim @@ -0,0 +1,2 @@ +" Set name of tags file; should put it inside .vim directory +let g:gutentags_ctags_tagfile='.vim/tags' diff --git a/.config/nvim/init/plugins/indentline.vim b/.config/nvim/init/plugins/indentline.vim new file mode 100644 index 0000000..3ad303a --- /dev/null +++ b/.config/nvim/init/plugins/indentline.vim @@ -0,0 +1,2 @@ +" Make each indent level have a specific character +let g:indentLine_char_list = ['|', '¦', '┆', '┊'] diff --git a/.config/nvim/init/plugins/nerdtree.vim b/.config/nvim/init/plugins/nerdtree.vim new file mode 100644 index 0000000..c185ecb --- /dev/null +++ b/.config/nvim/init/plugins/nerdtree.vim @@ -0,0 +1,47 @@ +" Listing of paths to ignore. I think I could use something similar to CtrlP +" here as well, but I want NERDTree to also show some non-version +" controlled files. It ignores the following files: +" Vim +" Other IDEs +" Python +" Java +" Git +" Stack & Haskell +" CMake +" Non-text files +let NERDTreeIgnore = [ + \ '^\.vim$[[dir]]', + \ '^\.vscode$[[dir]]', '.*\.code-workspace$[[file]]', '^\.idea$[[dir]]', + \ '^__pycache__$[[dir]]', '^\.pytest_cache$[[dir]]', '^venv$[[dir]]', + \ '\.egg-info$[[dir]]', '^dist$[[dir]]', '^build$[[dir]]', + \ '^\.eggs$[[dir]]', + \ '^out$[[dir]]', + \ '^\.git$[[dir]]', + \ '^\.stack-work$[[dir]]', '\.lock$', + \ '^CMakeFiles$[[dir]]', '^CMakeCache.txt$[[file]]', + \ '.pdf$[[file]]'] + +" Show files starting with . +let NERDTreeShowHidden = 1 +" Hide 'Press ? for help' +let NERDTreeMinimalUI = 1 +let NERDTreeDirArrows = 1 +" Close NERDTree after opening a file +let NERDTreeQuitOnOpen = 1 +" Explicitely tell NERDTree to never change my current working directory +let NERDTreeChDirMode = 0 +" Sort naturally, e.g. z10.txt comes after z1.txt +let NERDTreeNaturalSort = 1 +" Show files, not only directories +let NERDTreeShowFiles = 1 +" Don't show line numbers +let NERDTreeShowLineNumbers = 0 +" Show NERDTree on the left side +let NERDTreeWinPos = 'left' +" Use the minimal menu system +let NERDTreeMinimalMenu = 1 +" Always delete the buffer when you rename the file +let NERDTreeAutoDeleteBuffer = 1 + +" Open NERDTree on the current file +nnoremap tt :NERDTreeFind diff --git a/.config/nvim/init/plugins/plugins.vim b/.config/nvim/init/plugins/plugins.vim new file mode 100644 index 0000000..2bc19d3 --- /dev/null +++ b/.config/nvim/init/plugins/plugins.vim @@ -0,0 +1,68 @@ +" See README.md for more information about the plugins +" +" Load the plugins +call plug#begin('~/.config/nvim/plugged') + +" Powerful auto-complete engine +" TODO switch to coc-jedi for Python stuff +Plug 'neoclide/coc.nvim', {'branch': 'release'} + +" Fast file navigation using fuzzy search +Plug 'ctrlpvim/ctrlp.vim' + +" Git client within Vim +Plug 'tpope/vim-fugitive' + +" Change surrounding quotes, brackets... +Plug 'tpope/vim-surround' + +" Comment out lines easily +Plug 'tpope/vim-commentary' + +" Show ctags in sidebar, useful for navigation +Plug 'majutsushi/tagbar' + +" Show Git diffs in sidebar +Plug 'airblade/vim-gitgutter' + +" Show indentation using thin lines +Plug 'yggdroot/indentline' + +" Auto-indent according to PEP8 rules +Plug 'hynek/vim-python-pep8-indent' + +" Text object based on current indent level (e.g. Python) +Plug 'michaeljsmith/vim-indent-object' + +" Sidebar showing file structure +Plug 'scrooloose/nerdtree' + +" Toml syntax highlighting +Plug 'cespare/vim-toml' + +" Auto-bracket pairs +Plug 'jiangmiao/auto-pairs' + +" This plugin allows you to align text according to specified delimiters +" e.g. this: +" x = 5 +" alongname = 15 +" can become this: +" x = 15 +" alongname = 15 +Plug 'godlygeek/tabular' + +" Some auto-complete for haskell +Plug 'neovimhaskell/haskell-vim' + +Plug 'vmchale/ion-vim' + +Plug 'Chiel92/vim-autoformat' + +Plug 'leafoftree/vim-vue-plugin' + +Plug 'othree/javascript-libraries-syntax.vim' + +Plug 'udalov/kotlin-vim' + +call plug#end() diff --git a/.config/nvim/init/plugins/tagbar.vim b/.config/nvim/init/plugins/tagbar.vim new file mode 100644 index 0000000..50989e5 --- /dev/null +++ b/.config/nvim/init/plugins/tagbar.vim @@ -0,0 +1,25 @@ +" Navigating between tags +" Go to next top-level tag +let g:tagbar_map_nexttag = 'J' +" Same, but previous +let g:tagbar_map_prevtag = 'K' +" Show prototype of current tag +let g:tagbar_map_showproto = 'u' +" Use order from source file +let g:tagbar_sort = 0 +" Don't show help tip at the top +let g:tagbar_compact = 1 +" Auto-open folds while following cursor +let g:tagbar_autoshowtag = 1 +" Don't show status line +let g:no_status_line = 1 +" Close tagbar when a tag is selected +let g:tagbar_autoclose = 1 + +" Open tagbar when opening certain language types +" autocmd BufNewFile,BufReadPre *.py,*.java,*.rs,*.cpp,*.c,*.r TagbarOpen + +" Explicitly close tagbar for these types +" autocmd BufNewFile,BufReadPre *.txt,*.rst TagbarClose + +nnoremap tr :TagbarToggle diff --git a/.config/nvim/init/settings.vim b/.config/nvim/init/settings.vim new file mode 100644 index 0000000..1699fec --- /dev/null +++ b/.config/nvim/init/settings.vim @@ -0,0 +1,63 @@ +" Terminal +" As I often use non-standard shells, certain things can break if this isn't +" explicitely set +" TODO maybe use which to find the executable? +set shell=/bin/bash + + +" Makes your cursor centered whenever possible. 999 is just a large number, +" making it always centered +set scrolloff=999 + +" Colorscheme +" This forces (Neo)Vim to assume the terminal supports 256 colors. +" Without this, some colorschemes (including mine) don't work properly. +set termguicolors +" Set colorscheme +colorscheme flattened_dark +hi Normal guibg=NONE ctermbg=NONE +hi LineNr ctermfg=NONE ctermbg=NONE + +" Line numbers +" I use the combination of absolute and relative line numbers. On the +" current line, it shows the absolute; on all the others, the relative. +set number relativenumber + +" Splits +" I prefer the logic of 'open your main window first, and all other +" afterwards', so this makes a new file open below or to the right of the +" current one. +set splitbelow splitright + +" Indentation +" I only use four spaces as indentation. This configures Vim to always use four +" spaces, for both manual tabs and automatic indentation. +set expandtab tabstop=4 shiftwidth=4 + +" Search functionality +" Show matches as pattern is being typed +set incsearch +" Ignore case as long as there are no capital letters in the pattern +set smartcase +" Don't hightlight search results after search is finished +set nohlsearch + +" autocmd BufReadPre * call SetDirs() +" Turn on swap files +set swapfile +set directory=./.vim/swap// +" Create file backups +" set backup +" Store backups in .vim directory, next to swap files +" set backupdir=./.vim/backup/, +" Temporary, until I've found a fix +set nobackup +" Create an undo file for each file; this makes undo persistent +set undofile +set undodir=./.vim/undo// + +" Increases speed of CoC and Gitgutter +set updatetime=250 + +" Make Vim use pipes instead of temp files when running commands +set noshelltemp diff --git a/.config/qutebrowser/autoconfig.yml b/.config/qutebrowser/autoconfig.yml new file mode 100644 index 0000000..0579994 --- /dev/null +++ b/.config/qutebrowser/autoconfig.yml @@ -0,0 +1,16 @@ +# If a config.py file exists, this file is ignored unless it's explicitly loaded +# via config.load_autoconfig(). For more information, see: +# https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#loading-autoconfigyml +# DO NOT edit this file by hand, qutebrowser will overwrite it. +# Instead, create a config.py - see :help for details. + +config_version: 2 +settings: + colors.webpage.darkmode.enabled: + global: false + content.notifications: + global: false + https://www.tubxporn.com: false + https://www.vrt.be: false + content.persistent_storage: + https://mega.nz: false diff --git a/.config/qutebrowser/bookmarks/urls b/.config/qutebrowser/bookmarks/urls new file mode 100644 index 0000000..e69de29 diff --git a/.config/qutebrowser/config.py b/.config/qutebrowser/config.py new file mode 100644 index 0000000..0c87852 --- /dev/null +++ b/.config/qutebrowser/config.py @@ -0,0 +1,29 @@ +import yaml + +def iterate_dict(dic, prefix=None): + for key, value in dic.items(): + if isinstance(value, dic): + pass + +with (config.configdir / "config.yml").open() as f: + yaml_data = yaml.safe_load(f) + + +# How frequently to save config/cookies etc. (in ms) +c.auto_save.interval = 5000 + +# Backend to use; webengine is recommended +c.backend = "webengine" + +# TODO keybindings + +# Show a changelog after every patch update +c.changelog_after_upgrade = "patch" + +# TODO color config + +c.confirm_quit = ["downloads"] + +c.content.blocking.adblock.lists.append("https://www.i-dont-care-about-cookies.eu/abp/") + +config.load_autoconfig() diff --git a/.config/qutebrowser/config.yml b/.config/qutebrowser/config.yml new file mode 100644 index 0000000..37417f9 --- /dev/null +++ b/.config/qutebrowser/config.yml @@ -0,0 +1,17 @@ +auto_save: + interval: 5000 + +confirm_quit: + - "downloads" + +backend: "webengine" +changelog_after_upgrade: "patch" + +confirm_quit: + - "downloads" + +content: + blocking: + adblock: + lists: + - "https://www.i-dont-care-about-cookies.eu/abp/" diff --git a/.config/qutebrowser/qsettings/QtProject.conf b/.config/qutebrowser/qsettings/QtProject.conf new file mode 100644 index 0000000..191c781 --- /dev/null +++ b/.config/qutebrowser/qsettings/QtProject.conf @@ -0,0 +1,8 @@ +[FileDialog] +history=file:///home/jjr/Documents/College/mm/practica/practicum-1.git +lastVisited=file:///home/jjr/Documents/College/mm/practica/practicum-1.git +qtVersion=5.15.2 +shortcuts=file:, file:///home/jjr +sidebarWidth=106 +treeViewHeader=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2g\0\0\0\x4\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0}\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1?\0\0\0\x1\0\0\0\0\0\0\0O\0\0\0\x1\0\0\0\0\0\0\0P\0\0\0\x1\0\0\0\0\0\0\0\x89\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff) +viewMode=Detail diff --git a/.config/qutebrowser/quickmarks b/.config/qutebrowser/quickmarks new file mode 100644 index 0000000..5bf0b6a --- /dev/null +++ b/.config/qutebrowser/quickmarks @@ -0,0 +1,2 @@ +ghu https://github.ugent.be/ +ufo https://ufora.ugent.be/d2l/home diff --git a/.config/yay/config.json b/.config/yay/config.json new file mode 100644 index 0000000..2515e06 --- /dev/null +++ b/.config/yay/config.json @@ -0,0 +1,43 @@ +{ + "aururl": "https://aur.archlinux.org", + "buildDir": "/home/jjr/.cache/yay", + "absdir": "/home/jjr/.cache/yay/abs", + "editor": "", + "editorflags": "", + "makepkgbin": "makepkg", + "makepkgconf": "", + "pacmanbin": "pacman", + "pacmanconf": "/etc/pacman.conf", + "redownload": "no", + "rebuild": "no", + "answerclean": "", + "answerdiff": "", + "answeredit": "", + "answerupgrade": "", + "gitbin": "git", + "gpgbin": "gpg", + "gpgflags": "", + "mflags": "", + "sortby": "votes", + "searchby": "name-desc", + "gitflags": "", + "removemake": "yes", + "sudobin": "sudo", + "sudoflags": "", + "requestsplitn": 150, + "sortmode": 0, + "completionrefreshtime": 7, + "sudoloop": true, + "timeupdate": false, + "devel": false, + "cleanAfter": true, + "provides": true, + "pgpfetch": true, + "upgrademenu": true, + "cleanmenu": true, + "diffmenu": true, + "editmenu": false, + "combinedupgrade": false, + "useask": false, + "batchinstall": true +}