summaryrefslogtreecommitdiff
path: root/.config
diff options
context:
space:
mode:
Diffstat (limited to '.config')
-rw-r--r--.config/Thunar/accels.scm118
-rw-r--r--.config/Thunar/uca.xml15
-rw-r--r--.config/X11/Xmodmap248
-rw-r--r--.config/X11/Xresources164
-rw-r--r--.config/X11/xbindkeysrc96
-rw-r--r--.config/X11/xinitrc42
-rw-r--r--.config/X11/xprofile18
-rw-r--r--.config/Zeal/Zeal.conf52
-rw-r--r--.config/Zeal/style.css3
-rw-r--r--.config/git/config5
-rw-r--r--.config/gotop/gotop.conf33
-rw-r--r--.config/gtk-2.0/gtkfilechooser.ini11
-rw-r--r--.config/gtk-2.0/gtkrc-2.019
-rw-r--r--.config/gtk-2.0/gtkrc-2.0.bak20
-rw-r--r--.config/gtk-3.0/bookmarks1
-rw-r--r--.config/gtk-3.0/settings.ini20
-rw-r--r--.config/htop/htoprc63
-rw-r--r--.config/i3/config644
-rw-r--r--.config/i3blocks/config71
-rw-r--r--.config/i3blocks/systeminfo50
-rw-r--r--.config/ipython/profile_default/db/dhistbin0 -> 109 bytes
-rw-r--r--.config/ipython/profile_default/history.sqlitebin0 -> 118784 bytes
-rw-r--r--.config/ipython/profile_default/ipython_config.py1146
-rw-r--r--.config/ipython/profile_default/startup/05-keybindings.py18
-rw-r--r--.config/ipython/profile_default/startup/10-startup.ipy13
-rw-r--r--.config/ipython/profile_default/startup/20-functions.ipy13
-rw-r--r--.config/ipython/profile_default/startup/README11
-rw-r--r--.config/jgmenu/append.csv7
-rw-r--r--.config/jgmenu/backup/20230925074149958689103/jgmenurc74
-rw-r--r--.config/jgmenu/jgmenurc74
-rw-r--r--.config/keepassxc/keepassxc.ini37
-rw-r--r--.config/lf/brodie/draw_img67
-rw-r--r--.config/lf/brodie/image18
-rw-r--r--.config/lf/brodie/preview48
-rw-r--r--.config/lf/colors175
-rw-r--r--.config/lf/draw_img67
-rw-r--r--.config/lf/history7
-rw-r--r--.config/lf/icons358
-rw-r--r--.config/lf/image18
-rw-r--r--.config/lf/lfrc160
-rw-r--r--.config/lf/luke/scope56
-rw-r--r--.config/lf/preview48
-rw-r--r--.config/lxsession/i3/desktop.conf9
-rw-r--r--.config/nvim/autoload/airline/themes/onedark.vim130
-rw-r--r--.config/nvim/autoload/lightline/colorscheme/onedark.vim58
-rw-r--r--.config/nvim/autoload/onedark.vim29
-rw-r--r--.config/nvim/autoload/plug.vim2863
-rw-r--r--.config/nvim/autoload/scratch.vim49
-rw-r--r--.config/nvim/coc/coc-onload.vim144
-rw-r--r--.config/nvim/coc/coc-settings.json6
-rw-r--r--.config/nvim/colors/onedark.vim713
-rw-r--r--.config/nvim/dev.vim93
-rw-r--r--.config/nvim/init.bak.vim225
-rw-r--r--.config/nvim/init.vim178
-rw-r--r--.config/nvim/onedark.vim713
-rw-r--r--.config/nvim/other/fzf.vim19
-rw-r--r--.config/nvim/other/learn.vim649
-rw-r--r--.config/nvim/out.vim36
m---------.config/nvim/pack/colors/opt/onedark.vim0
-rw-r--r--.config/nvim/templates/_default.c5
-rw-r--r--.config/nvim/templates/_default.html13
-rw-r--r--.config/nvim/templates/_default.tex7
-rw-r--r--.config/nvim/templates/article.tex11
-rw-r--r--.config/nvim/vim.log170
-rw-r--r--.config/nvim/vimspector/python.json31
-rw-r--r--.config/python/pythonrc22
-rw-r--r--.config/shell/aliasrc85
-rw-r--r--.config/shell/bm-dirs51
-rw-r--r--.config/shell/bm-files28
-rw-r--r--.config/shell/inputrc38
-rw-r--r--.config/shell/profile268
-rw-r--r--.config/terminal-colors.d/cal.scheme5
-rw-r--r--.config/tmux/tmux-gruvbox-dark.conf53
-rw-r--r--.config/tmux/tmux-gruvbox-light.conf56
-rw-r--r--.config/tmux/tmux-onedark-theme.tmux95
-rw-r--r--.config/tmux/tmux.conf77
-rw-r--r--.config/wget/wgetrc1
-rw-r--r--.config/yt-dlp/channel.conf12
-rw-r--r--.config/yt-dlp/config14
-rw-r--r--.config/yt-dlp/playlist.conf12
-rw-r--r--.config/yt-dlp/sequenced-playlist.conf7
-rw-r--r--.config/yt-dlp/videos.conf2
-rw-r--r--.config/zathura/zathurarc10
-rw-r--r--.config/zsh/.zshrc293
-rw-r--r--.config/zsh/command-tools.zsh61
m---------.config/zsh/plugins/fast-syntax-highlighting0
-rw-r--r--.config/zsh/plugins/fzf-completion.zsh329
-rw-r--r--.config/zsh/plugins/zsh-autosuggestions.zsh864
-rw-r--r--.config/zsh/plugins/zsh-history-substring-search.zsh759
m---------.config/zsh/plugins/zsh-syntax-highlighting0
-rw-r--r--.config/zsh/zprofile21
91 files changed, 13422 insertions, 0 deletions
diff --git a/.config/Thunar/accels.scm b/.config/Thunar/accels.scm
new file mode 100644
index 0000000..638a9f3
--- /dev/null
+++ b/.config/Thunar/accels.scm
@@ -0,0 +1,118 @@
+; thunar GtkAccelMap rc-file -*- scheme -*-
+; this file is an automated accelerator map dump
+;
+; (gtk_accel_path "<Actions>/ThunarActionManager/restore" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/undo" "<Primary>z")
+; (gtk_accel_path "<Actions>/ThunarStandardView/select-all-files" "<Primary>a")
+; (gtk_accel_path "<Actions>/ThunarBookmarks/0064c8b8c2b8ae1954479b6f2feab576" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-dtime" "")
+; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-last-modified" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/invert-selection" "")
+; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-display-name" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/cut" "<Primary>x")
+; (gtk_accel_path "<Actions>/ThunarActionManager/restore-show" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in" "<Primary>plus")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-ascending" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/empty-trash" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/reload" "<Primary>r")
+; (gtk_accel_path "<Actions>/ThunarWindow/toggle-image-preview" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/cut-2" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-menu" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/trash-delete" "Delete")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-network" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/trash-delete-2" "KP_Delete")
+; (gtk_accel_path "<Actions>/ThunarWindow/contents/help-menu" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/delete" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/set-default-app" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/back-alt" "BackSpace")
+; (gtk_accel_path "<Actions>/ThunarActionManager/open-in-new-tab" "<Primary><Shift>p")
+; (gtk_accel_path "<Actions>/ThunarWindow/switch-next-tab" "<Primary>Page_Down")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-file-menu" "F10")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-as-compact-list" "<Primary>3")
+; (gtk_accel_path "<Actions>/ThunarWindow/about" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-computer" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/clear-directory-specific-settings" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-file-system" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-parent" "<Alt>Up")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-menu" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/copy" "<Primary>c")
+; (gtk_accel_path "<Actions>/ThunarStandardView/properties" "<Alt>Return")
+; (gtk_accel_path "<Actions>/ThunarStandardView/back" "<Alt>Left")
+; (gtk_accel_path "<Actions>/ThunarWindow/sendto-menu" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-mtime" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/open-location" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/bookmarks-menu" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/reload-alt" "F5")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-buttons" "")
+; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-size-in-bytes" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/unselect-all-files" "Escape")
+; (gtk_accel_path "<Actions>/ThunarActionManager/copy-2" "<Primary>Insert")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-out-alt" "<Primary>KP_Subtract")
+; (gtk_accel_path "<Actions>/ThunarWindow/cancel-search" "Escape")
+; (gtk_accel_path "<Actions>/ThunarStandardView/select-by-pattern" "<Primary>s")
+; (gtk_accel_path "<Actions>/ThunarStandardView/rename" "F2")
+; (gtk_accel_path "<Actions>/ThunarStandardView/configure-columns" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/create-document" "")
+; (gtk_accel_path "<Actions>/ThunarShortcutsPane/sendto-shortcuts" "<Primary>d")
+; (gtk_accel_path "<Actions>/ThunarActionManager/move-to-trash" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/close-tab" "<Primary>w")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-tree" "<Primary>e")
+; (gtk_accel_path "<Actions>/ThunarActionManager/open" "<Primary>o")
+; (gtk_accel_path "<Actions>/ThunarWindow/toggle-side-pane" "F9")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-entry" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-recent" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-home" "<Alt>Home")
+; (gtk_accel_path "<Actions>/ThunarWindow/toggle-split-view" "F3")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-templates" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-location-alt" "<Alt>d")
+; (gtk_accel_path "<Actions>/ThunarStandardView/create-folder" "<Primary><Shift>n")
+; (gtk_accel_path "<Actions>/ThunarWindow/search" "<Primary>f")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-type" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/paste-2" "<Shift>Insert")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in-alt2" "<Primary>equal")
+; (gtk_accel_path "<Actions>/ThunarStandardView/duplicate" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/remove-from-recent" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-out" "<Primary>minus")
+; (gtk_accel_path "<Actions>/ThunarWindow/close-window" "<Primary>q")
+; (gtk_accel_path "<Actions>/ThunarWindow/edit-menu" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-side-pane-shortcuts" "<Primary>b")
+; (gtk_accel_path "<Actions>/ThunarWindow/show-highlight" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/contents" "F1")
+; (gtk_accel_path "<Actions>/ThunarWindow/preferences" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/switch-previous-tab" "<Primary>Page_Up")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-in-alt1" "<Primary>KP_Add")
+; (gtk_accel_path "<Actions>/ThunarStandardView/toggle-sort-order" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/open-in-new-window" "<Primary><Shift>o")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-configure-toolbar" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-location-selector-menu" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-statusbar" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/close-all-windows" "<Primary><Shift>w")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-trash" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/paste" "<Primary>v")
+; (gtk_accel_path "<Actions>/ThunarActionManager/delete-3" "<Shift>KP_Delete")
+; (gtk_accel_path "<Actions>/ThunarActionManager/execute" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-desktop" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/open-with-other" "")
+; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-size" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/sendto-desktop" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/open-location" "<Primary>l")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-menubar" "<Primary>m")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-reset-alt" "<Primary>KP_0")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-as-detailed-list" "<Primary>2")
+; (gtk_accel_path "<Actions>/ThunarWindow/view-as-icons" "<Primary>1")
+; (gtk_accel_path "<Actions>/ThunarWindow/new-window" "<Primary>n")
+; (gtk_accel_path "<Actions>/ThunarStandardView/forward" "<Alt>Right")
+; (gtk_accel_path "<Actions>/ThunarActionManager/redo" "<Primary><Shift>z")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-descending" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/file-menu" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/make-link" "")
+; (gtk_accel_path "<Actions>/ThunarActionManager/delete-2" "<Shift>Delete")
+; (gtk_accel_path "<Actions>/ThunarWindow/new-tab" "<Primary>t")
+; (gtk_accel_path "<Actions>/ThunarWindow/go-menu" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-size" "")
+; (gtk_accel_path "<Actions>/ThunarStandardView/arrange-items-menu" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/show-hidden" "<Primary>h")
+; (gtk_accel_path "<Actions>/ThunarStandardView/sort-by-name" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/zoom-reset" "<Primary>0")
+; (gtk_accel_path "<Actions>/ThunarStatusBar/toggle-filetype" "")
+; (gtk_accel_path "<Actions>/ThunarWindow/detach-tab" "")
diff --git a/.config/Thunar/uca.xml b/.config/Thunar/uca.xml
new file mode 100644
index 0000000..3d179a4
--- /dev/null
+++ b/.config/Thunar/uca.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+<action>
+ <icon>utilities-terminal</icon>
+ <name>Open Terminal Here</name>
+ <submenu></submenu>
+ <unique-id>1722344429525890-1</unique-id>
+ <command>exo-open --working-directory %f --launch TerminalEmulator</command>
+ <description>Example for a custom action</description>
+ <range></range>
+ <patterns>*</patterns>
+ <startup-notify/>
+ <directories/>
+</action>
+</actions>
diff --git a/.config/X11/Xmodmap b/.config/X11/Xmodmap
new file mode 100644
index 0000000..797b664
--- /dev/null
+++ b/.config/X11/Xmodmap
@@ -0,0 +1,248 @@
+keycode 8 =
+keycode 9 = Escape NoSymbol Escape
+keycode 10 = 1 exclam 1 exclam
+keycode 11 = 2 at 2 at
+keycode 12 = 3 numbersign 3 numbersign
+keycode 13 = 4 dollar 4 dollar
+keycode 14 = 5 percent 5 percent
+keycode 15 = 6 asciicircum 6 asciicircum
+keycode 16 = 7 ampersand 7 ampersand
+keycode 17 = 8 asterisk 8 asterisk
+keycode 18 = 9 parenleft 9 parenleft
+keycode 19 = 0 parenright 0 parenright
+keycode 20 = minus underscore minus underscore
+keycode 21 = equal plus equal plus
+keycode 22 = BackSpace BackSpace BackSpace BackSpace
+keycode 23 = Tab ISO_Left_Tab Tab ISO_Left_Tab
+keycode 24 = q Q q Q
+keycode 25 = w W w W
+keycode 26 = e E e E
+keycode 27 = r R r R
+keycode 28 = t T t T
+keycode 29 = y Y y Y
+keycode 30 = u U u U
+keycode 31 = i I i I
+keycode 32 = o O o O
+keycode 33 = p P p P
+keycode 34 = bracketleft braceleft bracketleft braceleft
+keycode 35 = bracketright braceright bracketright braceright
+keycode 36 = Return NoSymbol Return
+keycode 37 = Control_L NoSymbol Control_L
+keycode 38 = a A a A
+keycode 39 = s S s S
+keycode 40 = d D d D
+keycode 41 = f F f F
+keycode 42 = g G g G
+keycode 43 = h H h H
+keycode 44 = j J j J
+keycode 45 = k K k K
+keycode 46 = l L l L
+keycode 47 = semicolon colon semicolon colon
+keycode 48 = apostrophe quotedbl apostrophe quotedbl
+keycode 49 = grave asciitilde grave asciitilde
+keycode 50 = Shift_L NoSymbol Shift_L
+keycode 51 = backslash bar backslash bar
+keycode 52 = z Z z Z
+keycode 53 = x X x X
+keycode 54 = c C c C
+keycode 55 = v V v V
+keycode 56 = b B b B
+keycode 57 = n N n N
+keycode 58 = m M m M
+keycode 59 = comma less comma less
+keycode 60 = period greater period greater
+keycode 61 = slash question slash question
+keycode 62 = Shift_R NoSymbol Shift_R
+keycode 63 = KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply XF86ClearGrab
+keycode 64 = Alt_L Meta_L Alt_L Meta_L
+keycode 65 = space NoSymbol space
+keycode 66 = Caps_Lock NoSymbol Caps_Lock
+keycode 67 = F1 F1 F1 F1 F1 F1 XF86Switch_VT_1
+keycode 68 = F2 F2 F2 F2 F2 F2 XF86Switch_VT_2
+keycode 69 = F3 F3 F3 F3 F3 F3 XF86Switch_VT_3
+keycode 70 = F4 F4 F4 F4 F4 F4 XF86Switch_VT_4
+keycode 71 = F5 F5 F5 F5 F5 F5 XF86Switch_VT_5
+keycode 72 = F6 F6 F6 F6 F6 F6 XF86Switch_VT_6
+keycode 73 = F7 F7 F7 F7 F7 F7 XF86Switch_VT_7
+keycode 74 = F8 F8 F8 F8 F8 F8 XF86Switch_VT_8
+keycode 75 = F9 F9 F9 F9 F9 F9 XF86Switch_VT_9
+keycode 76 = F10 F10 F10 F10 F10 F10 XF86Switch_VT_10
+keycode 77 = Num_Lock NoSymbol Num_Lock
+keycode 78 = Scroll_Lock NoSymbol Scroll_Lock
+keycode 79 = KP_Home KP_7 KP_Home KP_7
+keycode 80 = KP_Up KP_8 KP_Up KP_8
+keycode 81 = KP_Prior KP_9 KP_Prior KP_9
+keycode 82 = KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract XF86Prev_VMode
+keycode 83 = KP_Left KP_4 KP_Left KP_4
+keycode 84 = KP_Begin KP_5 KP_Begin KP_5
+keycode 85 = KP_Right KP_6 KP_Right KP_6
+keycode 86 = KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add XF86Next_VMode
+keycode 87 = KP_End KP_1 KP_End KP_1
+keycode 88 = KP_Down KP_2 KP_Down KP_2
+keycode 89 = KP_Next KP_3 KP_Next KP_3
+keycode 90 = KP_Insert KP_0 KP_Insert KP_0
+keycode 91 = KP_Delete KP_Decimal KP_Delete KP_Decimal
+keycode 92 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift
+keycode 93 =
+keycode 94 = less greater less greater bar brokenbar bar
+keycode 95 = F11 F11 F11 F11 F11 F11 XF86Switch_VT_11
+keycode 96 = F12 F12 F12 F12 F12 F12 XF86Switch_VT_12
+keycode 97 =
+keycode 98 = Katakana NoSymbol Katakana
+keycode 99 = Hiragana NoSymbol Hiragana
+keycode 100 = Henkan_Mode NoSymbol Henkan_Mode
+keycode 101 = Hiragana_Katakana NoSymbol Hiragana_Katakana
+keycode 102 = Muhenkan NoSymbol Muhenkan
+keycode 103 =
+keycode 104 = KP_Enter NoSymbol KP_Enter
+keycode 105 = Control_R NoSymbol Control_R
+keycode 106 = KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide XF86Ungrab
+keycode 107 = Print Sys_Req Print Sys_Req
+keycode 108 = Alt_R Meta_R Alt_R Meta_R
+keycode 109 = Linefeed NoSymbol Linefeed
+keycode 110 = Home NoSymbol Home
+keycode 111 = Up NoSymbol Up
+keycode 112 = Prior NoSymbol Prior
+keycode 113 = Left NoSymbol Left
+keycode 114 = Right NoSymbol Right
+keycode 115 = End NoSymbol End
+keycode 116 = Down NoSymbol Down
+keycode 117 = Next NoSymbol Next
+keycode 118 = Insert NoSymbol Insert
+keycode 119 = Delete NoSymbol Delete
+keycode 120 =
+keycode 121 = XF86AudioMute NoSymbol XF86AudioMute
+keycode 122 = XF86AudioLowerVolume NoSymbol XF86AudioLowerVolume
+keycode 123 = XF86AudioRaiseVolume NoSymbol XF86AudioRaiseVolume
+keycode 124 = XF86PowerOff NoSymbol XF86PowerOff
+keycode 125 = KP_Equal NoSymbol KP_Equal
+keycode 126 = plusminus NoSymbol plusminus
+keycode 127 = Pause Break Pause Break
+keycode 128 = XF86LaunchA NoSymbol XF86LaunchA
+keycode 129 = KP_Decimal KP_Decimal KP_Decimal KP_Decimal
+keycode 130 = Hangul NoSymbol Hangul
+keycode 131 = Hangul_Hanja NoSymbol Hangul_Hanja
+keycode 132 =
+keycode 133 = Super_L NoSymbol Super_L
+keycode 134 = Super_R NoSymbol Super_R
+keycode 135 = Menu NoSymbol Menu
+keycode 136 = Cancel NoSymbol Cancel
+keycode 137 = Redo NoSymbol Redo
+keycode 138 = SunProps NoSymbol SunProps
+keycode 139 = Undo NoSymbol Undo
+keycode 140 = SunFront NoSymbol SunFront
+keycode 141 = XF86Copy NoSymbol XF86Copy
+keycode 142 = XF86Open NoSymbol XF86Open
+keycode 143 = XF86Paste NoSymbol XF86Paste
+keycode 144 = Find NoSymbol Find
+keycode 145 = XF86Cut NoSymbol XF86Cut
+keycode 146 = Help NoSymbol Help
+keycode 147 = XF86MenuKB NoSymbol XF86MenuKB
+keycode 148 = XF86Calculator NoSymbol XF86Calculator
+keycode 149 =
+keycode 150 = XF86Sleep NoSymbol XF86Sleep
+keycode 151 = XF86WakeUp NoSymbol XF86WakeUp
+keycode 152 = XF86Explorer NoSymbol XF86Explorer
+keycode 153 = XF86Send NoSymbol XF86Send
+keycode 154 =
+keycode 155 = XF86Xfer NoSymbol XF86Xfer
+keycode 156 = XF86Launch1 NoSymbol XF86Launch1
+keycode 157 = XF86Launch2 NoSymbol XF86Launch2
+keycode 158 = XF86WWW NoSymbol XF86WWW
+keycode 159 = XF86DOS NoSymbol XF86DOS
+keycode 160 = XF86ScreenSaver NoSymbol XF86ScreenSaver
+keycode 161 = XF86RotateWindows NoSymbol XF86RotateWindows
+keycode 162 = XF86TaskPane NoSymbol XF86TaskPane
+keycode 163 = XF86Mail NoSymbol XF86Mail
+keycode 164 = XF86Favorites NoSymbol XF86Favorites
+keycode 165 = XF86MyComputer NoSymbol XF86MyComputer
+keycode 166 = XF86Back NoSymbol XF86Back
+keycode 167 = XF86Forward NoSymbol XF86Forward
+keycode 168 =
+keycode 169 = XF86Eject NoSymbol XF86Eject
+keycode 170 = XF86Eject NoSymbol XF86Eject
+keycode 171 = XF86AudioNext NoSymbol XF86AudioNext
+keycode 172 = XF86AudioPlay XF86AudioPause XF86AudioPlay XF86AudioPause
+keycode 173 = XF86AudioPrev NoSymbol XF86AudioPrev
+keycode 174 = XF86AudioStop XF86Eject XF86AudioStop XF86Eject
+keycode 175 = XF86AudioRecord NoSymbol XF86AudioRecord
+keycode 176 = XF86AudioRewind NoSymbol XF86AudioRewind
+keycode 177 = XF86Phone NoSymbol XF86Phone
+keycode 178 =
+keycode 179 = XF86Tools NoSymbol XF86Tools
+keycode 180 = XF86HomePage NoSymbol XF86HomePage
+keycode 181 = XF86Reload NoSymbol XF86Reload
+keycode 182 = XF86Close NoSymbol XF86Close
+keycode 183 =
+keycode 184 =
+keycode 185 = XF86ScrollUp NoSymbol XF86ScrollUp
+keycode 186 = XF86ScrollDown NoSymbol XF86ScrollDown
+keycode 187 = parenleft NoSymbol parenleft
+keycode 188 = parenright NoSymbol parenright
+keycode 189 = XF86New NoSymbol XF86New
+keycode 190 = Redo NoSymbol Redo
+keycode 191 = XF86Tools NoSymbol XF86Tools
+keycode 192 = XF86Launch5 NoSymbol XF86Launch5
+keycode 193 = XF86Launch6 NoSymbol XF86Launch6
+keycode 194 = XF86Launch7 NoSymbol XF86Launch7
+keycode 195 = XF86Launch8 NoSymbol XF86Launch8
+keycode 196 = XF86Launch9 NoSymbol XF86Launch9
+keycode 197 =
+keycode 198 = XF86AudioMicMute NoSymbol XF86AudioMicMute
+keycode 199 = XF86TouchpadToggle NoSymbol XF86TouchpadToggle
+keycode 200 = XF86TouchpadOn NoSymbol XF86TouchpadOn
+keycode 201 = XF86TouchpadOff NoSymbol XF86TouchpadOff
+keycode 202 =
+keycode 203 = ISO_Level5_Shift NoSymbol ISO_Level5_Shift
+keycode 204 = NoSymbol Alt_L NoSymbol Alt_L
+keycode 205 = NoSymbol Meta_L NoSymbol Meta_L
+keycode 206 = NoSymbol Super_L NoSymbol Super_L
+keycode 207 = NoSymbol Hyper_L NoSymbol Hyper_L
+keycode 208 = XF86AudioPlay NoSymbol XF86AudioPlay
+keycode 209 = XF86AudioPause NoSymbol XF86AudioPause
+keycode 210 = XF86Launch3 NoSymbol XF86Launch3
+keycode 211 = XF86Launch4 NoSymbol XF86Launch4
+keycode 212 = XF86LaunchB NoSymbol XF86LaunchB
+keycode 213 = XF86Suspend NoSymbol XF86Suspend
+keycode 214 = XF86Close NoSymbol XF86Close
+keycode 215 = XF86AudioPlay NoSymbol XF86AudioPlay
+keycode 216 = XF86AudioForward NoSymbol XF86AudioForward
+keycode 217 =
+keycode 218 = Print NoSymbol Print
+keycode 219 =
+keycode 220 = XF86WebCam NoSymbol XF86WebCam
+keycode 221 = XF86AudioPreset NoSymbol XF86AudioPreset
+keycode 222 =
+keycode 223 = XF86Mail NoSymbol XF86Mail
+keycode 224 = XF86Messenger NoSymbol XF86Messenger
+keycode 225 = XF86Search NoSymbol XF86Search
+keycode 226 = XF86Go NoSymbol XF86Go
+keycode 227 = XF86Finance NoSymbol XF86Finance
+keycode 228 = XF86Game NoSymbol XF86Game
+keycode 229 = XF86Shop NoSymbol XF86Shop
+keycode 230 =
+keycode 231 = Cancel NoSymbol Cancel
+keycode 232 = XF86MonBrightnessDown NoSymbol XF86MonBrightnessDown
+keycode 233 = XF86MonBrightnessUp NoSymbol XF86MonBrightnessUp
+keycode 234 = XF86AudioMedia NoSymbol XF86AudioMedia
+keycode 235 = XF86Display NoSymbol XF86Display
+keycode 236 = XF86KbdLightOnOff NoSymbol XF86KbdLightOnOff
+keycode 237 = XF86KbdBrightnessDown NoSymbol XF86KbdBrightnessDown
+keycode 238 = XF86KbdBrightnessUp NoSymbol XF86KbdBrightnessUp
+keycode 239 = XF86Send NoSymbol XF86Send
+keycode 240 = XF86Reply NoSymbol XF86Reply
+keycode 241 = XF86MailForward NoSymbol XF86MailForward
+keycode 242 = XF86Save NoSymbol XF86Save
+keycode 243 = XF86Documents NoSymbol XF86Documents
+keycode 244 = XF86Battery NoSymbol XF86Battery
+keycode 245 = XF86Bluetooth NoSymbol XF86Bluetooth
+keycode 246 = XF86WLAN NoSymbol XF86WLAN
+keycode 247 = XF86UWB NoSymbol XF86UWB
+keycode 248 =
+keycode 249 = XF86Next_VMode NoSymbol XF86Next_VMode
+keycode 250 = XF86Prev_VMode NoSymbol XF86Prev_VMode
+keycode 251 = XF86MonBrightnessCycle NoSymbol XF86MonBrightnessCycle
+keycode 252 = XF86BrightnessAuto NoSymbol XF86BrightnessAuto
+keycode 253 = XF86DisplayOff NoSymbol XF86DisplayOff
+keycode 254 = XF86WWAN NoSymbol XF86WWAN
+keycode 255 = XF86RFKill NoSymbol XF86RFKill
diff --git a/.config/X11/Xresources b/.config/X11/Xresources
new file mode 100644
index 0000000..294f1fb
--- /dev/null
+++ b/.config/X11/Xresources
@@ -0,0 +1,164 @@
+!! Transparency (0-1):
+st.alpha: 0.95
+st.alphaOffset: 0.1
+
+!! Set a default font and font size as below:
+st.font: MesloLGS Nerd\ Font:size=17
+
+! st.termname: st-256color
+! st.borderpx: 2
+st.background: #1d1f21
+
+/* name dark light */
+/* black 0 8 */
+/* red 1 9 */
+/* green 2 10 */
+/* yellow 3 11 */
+/* blue 4 12 */
+/* purple 5 13 */
+/* cyan 6 14 */
+/* white 7 15 */
+
+! gruvbox neomutt selected text
+*.color8: #524334
+
+/* !! gruvbox: */
+/* *.color0: #1d2021 */
+/* *.color1: #cc241d */
+/* *.color2: #98971a */
+/* *.color3: #d79921 */
+/* *.color4: #458588 */
+/* *.color5: #b16286 */
+/* *.color6: #689d6a */
+/* *.color7: #a89984 */
+/* *.color8: #928374 */
+/* *.color9: #fb4934 */
+/* *.color10: #b8bb26 */
+/* *.color11: #fabd2f */
+/* *.color12: #83a598 */
+/* *.color13: #d3869b */
+/* *.color14: #8ec07c */
+/* *.color15: #ebdbb2 */
+/* *.color256: #1d2021 */
+/* *.color257: #ebdbb2 */
+
+/* !! gruvbox light: */
+/* *.color0: #fbf1c7 */
+/* *.color1: #cc241d */
+/* *.color2: #98971a */
+/* *.color3: #d79921 */
+/* *.color4: #458588 */
+/* *.color5: #b16286 */
+/* *.color6: #689d6a */
+/* *.color7: #7c6f64 */
+/* *.color8: #928374 */
+/* *.color9: #9d0006 */
+/* *.color10: #79740e */
+/* *.color11: #b57614 */
+/* *.color12: #076678 */
+/* *.color13: #8f3f71 */
+/* *.color14: #427b58 */
+/* *.color15: #3c3836 */
+/* *.background: #fbf1c7 */
+/* *.foreground: #282828 */
+/* st.alpha: 0.9 */
+
+/* !! brogrammer: */
+/* *.foreground: #d6dbe5 */
+/* *.background: #131313 */
+/* *.color0: #1f1f1f */
+/* *.color8: #d6dbe5 */
+/* *.color1: #f81118 */
+/* *.color9: #de352e */
+/* *.color2: #2dc55e */
+/* *.color10: #1dd361 */
+/* *.color3: #ecba0f */
+/* *.color11: #f3bd09 */
+/* *.color4: #2a84d2 */
+/* *.color12: #1081d6 */
+/* *.color5: #4e5ab7 */
+/* *.color13: #5350b9 */
+/* *.color6: #1081d6 */
+/* *.color14: #0f7ddb */
+/* *.color7: #d6dbe5 */
+/* *.color15: #ffffff */
+/* *.colorBD: #d6dbe5 */
+
+/* ! base16 */
+/* *.color0: #181818 */
+/* *.color1: #ab4642 */
+/* *.color2: #a1b56c */
+/* *.color3: #f7ca88 */
+/* *.color4: #7cafc2 */
+/* *.color5: #ba8baf */
+/* *.color6: #86c1b9 */
+/* *.color7: #d8d8d8 */
+/* *.color8: #585858 */
+/* *.color9: #ab4642 */
+/* *.color10: #a1b56c */
+/* *.color11: #f7ca88 */
+/* *.color12: #7cafc2 */
+/* *.color13: #ba8baf */
+/* *.color14: #86c1b9 */
+/* *.color15: #f8f8f8 */
+
+/* !! solarized */
+/* *.color0: #073642 */
+/* *.color1: #dc322f */
+/* *.color2: #859900 */
+/* *.color3: #b58900 */
+/* *.color4: #268bd2 */
+/* *.color5: #d33682 */
+/* *.color6: #2aa198 */
+/* *.color7: #eee8d5 */
+/* *.color9: #cb4b16 */
+/* *.color8: #fdf6e3 */
+/* *.color10: #586e75 */
+/* *.color11: #657b83 */
+/* *.color12: #839496 */
+/* *.color13: #6c71c4 */
+/* *.color14: #93a1a1 */
+/* *.color15: #fdf6e3 */
+
+/* !! xterm */
+/* *.color0: #000000 */
+/* *.color1: #cd0000 */
+/* *.color2: #00cd00 */
+/* *.color3: #cdcd00 */
+/* *.color4: #0000cd */
+/* *.color5: #cd00cd */
+/* *.color6: #00cdcd */
+/* *.color7: #e5e5e5 */
+/* *.color8: #4d4d4d */
+/* *.color9: #ff0000 */
+/* *.color10: #00ff00 */
+/* *.color11: #ffff00 */
+/* *.color12: #0000ff */
+/* *.color13: #ff00ff */
+/* *.color14: #00ffff */
+/* *.color15: #aabac8 */
+/* *.background: #000000 */
+
+/* ! Dracula Xresources palette */
+/* *.foreground: #F8F8F2 */
+/* *.background: #282A36 */
+/* *.color0: #000000 */
+/* *.color8: #4D4D4D */
+/* *.color1: #FF5555 */
+/* *.color9: #FF6E67 */
+/* *.color2: #50FA7B */
+/* *.color10: #5AF78E */
+/* *.color3: #F1FA8C */
+/* *.color11: #F4F99D */
+/* *.color4: #BD93F9 */
+/* *.color12: #CAA9FA */
+/* *.color5: #FF79C6 */
+/* *.color13: #FF92D0 */
+/* *.color6: #8BE9FD */
+/* *.color14: #9AEDFE */
+/* *.color7: #BFBFBF */
+/* *.color15: #E6E6E6 */
+
+/* *.background: .color0 */
+/* *.color256: 0#1d2021 */
+/* *.color257: 15#ebdbb2 */
diff --git a/.config/X11/xbindkeysrc b/.config/X11/xbindkeysrc
new file mode 100644
index 0000000..11b227e
--- /dev/null
+++ b/.config/X11/xbindkeysrc
@@ -0,0 +1,96 @@
+# For the benefit of emacs users: -*- shell-script -*-
+###########################
+# xbindkeys configuration #
+###########################
+#
+# Version: 1.8.7
+#
+# If you edit this file, do not forget to uncomment any lines
+# that you change.
+# The pound(#) symbol may be used anywhere for comments.
+#
+# To specify a key, you can use 'xbindkeys --key' or
+# 'xbindkeys --multikey' and put one of the two lines in this file.
+#
+# The format of a command line is:
+# "command to start"
+# associated key
+#
+#
+# A list of keys is in /usr/include/X11/keysym.h and in
+# /usr/include/X11/keysymdef.h
+# The XK_ is not needed.
+#
+# List of modifier:
+# Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),
+# Mod3 (CapsLock), Mod4, Mod5 (Scroll).
+#
+
+# The release modifier is not a standard X modifier, but you can
+# use it if you want to catch release events instead of press events
+
+# By defaults, xbindkeys does not pay attention with the modifiers
+# NumLock, CapsLock and ScrollLock.
+# Uncomment the lines above if you want to pay attention to them.
+
+#keystate_numlock = enable
+#keystate_capslock = enable
+#keystate_scrolllock= enable
+
+# Examples of commands:
+
+# "xbindkeys_show"
+# control+shift + q
+#
+# # set directly keycode (here control + f with my keyboard)
+# "xterm"
+# c:41 + m:0x4
+#
+# # specify a mouse button
+# "xterm"
+# control + b:2
+
+# "notify-send xte 'keydown Shift_R'"
+# b:9 + b:4
+
+# "notify-send xte 'keyup Shift_R'"
+# b:9 + b:5
+
+# "xte 'mouseclick 3'"
+# Shift_R
+
+"xvkbd -text "\[F8]""
+ m:0x0 + b:8
+"xvkbd -text "\[Shift]"
+ m:0x0 + b:9
+"xvkbd -text "\[Shift]\[Right]""
+ m:0x0 + b:10
+"xvkbd -text 2"
+ m:0x0 + b:11
+"xvkbd -text 3"
+ m:0x0 + b:12
+
+# "xte 'keydown Control_L'"
+# b:8
+
+# "xte 'keyup Control_L'"
+# b:8 + release
+
+#"xterm -geom 50x20+20+20"
+# Shift+Mod2+alt + s
+#
+## set directly keycode (here control+alt+mod2 + f with my keyboard)
+#"xterm"
+# alt + c:0x29 + m:4 + mod2
+#
+## Control+Shift+a release event starts rxvt
+#"rxvt"
+# release+control+shift + a
+#
+## Control + mouse button 2 release event starts rxvt
+#"rxvt"
+# Control + b:2 + Release
+
+##################################
+# End of xbindkeys configuration #
+##################################
diff --git a/.config/X11/xinitrc b/.config/X11/xinitrc
new file mode 100644
index 0000000..fa3fac4
--- /dev/null
+++ b/.config/X11/xinitrc
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# userresources=$HOME/.Xresources
+# usermodmap=$HOME/.Xmodmap
+# userresourcesconfig="${XDG_CONFIG_HOME:-$HOME/.config}/Xresources"
+# usermodmapconfig="${XDG_CONFIG_HOME:-$HOME/.config}/Xmodmap"
+# sysresources=/etc/X11/xinit/.Xresources
+# sysmodmap=/etc/X11/xinit/.Xmodmap
+
+# # merge in defaults and keymaps
+# [ -f $sysresources ] && { xrdb -merge $sysresources; }
+# [ -f $sysmodmap ] && { xmodmap $sysmodmap; }
+# [ -f "$userresources" ] && { xrdb -merge "$userresources"; }
+# [ -f "$usermodmap" ] && { xmodmap "$usermodmap"; }
+# [ -f "$userresourcesconfig" ] && { xrdb -merge "$userresourcesconfig"; }
+# [ -f "$usermodmapconfig" ] && { xmodmap "$usermodmapconfig"; }
+
+# start some nice programs
+
+# if [ -d /etc/X11/xinit/xinitrc.d ] ; then
+# for f in /etc/X11/xinit/xinitrc.d/?*.sh ; do
+# [ -x "$f" ] && . "$f"
+# done
+# unset f
+# fi
+
+printf "\n%s\n" "~/xinitrc loaded." >> ~/.local/state/xprofile.logs
+
+if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/x11/xprofile" ]; then
+ . "${XDG_CONFIG_HOME:-$HOME/.config}/x11/xprofile"
+else
+ . "$HOME/.xprofile"
+fi
+
+# twm &
+# xclock -geometry 50x50-1+1 &
+# xterm -geometry 80x50+494+51 &
+# xterm -geometry 80x20+494-0 &
+# exec xterm -geometry 80x66+0+0 -name login
+
+export $(dbus-launch)
+exec i3
diff --git a/.config/X11/xprofile b/.config/X11/xprofile
new file mode 100644
index 0000000..29250ae
--- /dev/null
+++ b/.config/X11/xprofile
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# gui -e
+
+echo "Sourced: $(date)" >> ~/.local/state/xprofile.logs
+
+xrdb "${XDG_CONFIG_HOME:-$HOME/.config}/X11/Xresources" & xrdbpid=$!
+numlockx on &
+setdp &
+
+autostart="copyq dunst pipewire syncthing remapd"
+
+for program in $autostart; do
+ pidof -sx "$program" || "$program" &
+done >/dev/null 2>&1
+
+{ sleep 5; wireplumber; } &
+[ -n "$xrdbpid" ] && wait "$xrdbpid"
diff --git a/.config/Zeal/Zeal.conf b/.config/Zeal/Zeal.conf
new file mode 100644
index 0000000..aee4b0c
--- /dev/null
+++ b/.config/Zeal/Zeal.conf
@@ -0,0 +1,52 @@
+[General]
+check_for_update=true
+hide_on_close=false
+minimize_to_systray=false
+show_systray_icon=true
+start_minimized=false
+
+[content]
+appearance=@Variant(\0\0\0\x7f\0\0\0\x12\x43ontentAppearance\0\0\0\0\x2)
+custom_css_file=/home/master/.config/Zeal/style.css
+dark_mode=true
+default_fixed_font_size=16
+default_font_family=sans-serif
+default_font_size=16
+disable_ad=true
+external_link_policy=@Variant(\0\0\0\x7f\0\0\0\x13\x45xternalLinkPolicy\0\0\0\0\0)
+fixed_font_family=DejaVu Sans Mono
+highlight_on_navigate=true
+minimum_font_size=16
+sans_serif_font_family=DejaVu Sans
+serif_font_family=DejaVu Serif
+smooth_scrolling=true
+
+[docsets]
+path=/home/master/.local/share/Zeal/Zeal/docsets
+
+[global_shortcuts]
+show=Meta+/
+
+[internal]
+install_id=7cf1e6a2-9a52-4dfc-a7de-bc1acd562804
+version=0.7.2
+
+[proxy]
+authenticate=false
+host=localhost
+ignore_ssl_errors=false
+password=
+port=9050
+type=0
+username=
+
+[search]
+fuzzy_search_enabled=true
+
+[state]
+splitter_geometry=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1X\0\0\x5P\0\xff\xff\xff\xff\x1\0\0\0\x1\0)
+toc_splitter_state=@ByteArray()
+window_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\a\x80\0\0\0\0\0\0\xf\x88\0\0\x4i\0\0\a\x80\0\0\0\0\0\0\xf\x88\0\0\x4i\0\0\0\x1\0\0\0\0\b\t\0\0\a\x80\0\0\0\0\0\0\xf\x88\0\0\x4i)
+
+[tabs]
+open_new_tab_after_active=true
diff --git a/.config/Zeal/style.css b/.config/Zeal/style.css
new file mode 100644
index 0000000..f8c0936
--- /dev/null
+++ b/.config/Zeal/style.css
@@ -0,0 +1,3 @@
+.main-page-content .section-contnet p {
+ font: 40px;
+}
diff --git a/.config/git/config b/.config/git/config
new file mode 100644
index 0000000..e63dac2
--- /dev/null
+++ b/.config/git/config
@@ -0,0 +1,5 @@
+[user]
+ email = dev@vikas.rocks
+ name = Vikas Kushwaha
+[init]
+ defaultBranch = master
diff --git a/.config/gotop/gotop.conf b/.config/gotop/gotop.conf
new file mode 100644
index 0000000..aeb918c
--- /dev/null
+++ b/.config/gotop/gotop.conf
@@ -0,0 +1,33 @@
+# Scale graphs to this level; 7 is the default, 2 is zoomed out.
+graphhorizontalscale=7
+# If true, start the UI with the help visible
+helpvisible=false
+# The color scheme to use. See `--list colorschemes`
+colorscheme=monokai
+# How frequently to update the UI, in nanoseconds
+updateinterval=1000000000
+# If true, show the average CPU load
+averagecpu=false
+# If true, show load per CPU
+percpuload=false
+# Temperature units. C for Celsius, F for Fahrenheit
+tempscale=C
+# If true, display a status bar
+statusbar=false
+# The network interface to monitor
+netinterface=all
+# A layout name. See `--list layouts`
+layout=default
+# The maximum log file size, in bytes
+maxlogsize=5000000
+# If set, export data as Promethius metrics on the interface:port.
+# E.g., `:8080` (colon is required, interface is not)
+#metricsexportport=
+# Display network IO in mpbs if true
+mbps=false
+# A list of enabled temp sensors. See `--list devices`
+#temperatures=
+# Enable NVidia GPU metrics.
+nvidia=false
+# To configure the NVidia refresh rate, set a duration:
+#nvidiarefresh=30s
diff --git a/.config/gtk-2.0/gtkfilechooser.ini b/.config/gtk-2.0/gtkfilechooser.ini
new file mode 100644
index 0000000..bc097de
--- /dev/null
+++ b/.config/gtk-2.0/gtkfilechooser.ini
@@ -0,0 +1,11 @@
+[Filechooser Settings]
+LocationMode=path-bar
+ShowHidden=false
+ShowSizeColumn=true
+GeometryX=393
+GeometryY=71
+GeometryWidth=1140
+GeometryHeight=855
+SortColumn=name
+SortOrder=ascending
+StartupMode=recent
diff --git a/.config/gtk-2.0/gtkrc-2.0 b/.config/gtk-2.0/gtkrc-2.0
new file mode 100644
index 0000000..73dbc57
--- /dev/null
+++ b/.config/gtk-2.0/gtkrc-2.0
@@ -0,0 +1,19 @@
+# DO NOT EDIT! This file will be overwritten by LXAppearance.
+# Any customization should be done in ~/.gtkrc-2.0.mine instead.
+
+include "/home/master/.gtkrc-2.0.mine"
+gtk-theme-name="Arc-Dark"
+gtk-icon-theme-name="Gruvbox-Plus-Dark"
+gtk-font-name="Fira Sans 14"
+gtk-cursor-theme-size=24
+gtk-toolbar-style=GTK_TOOLBAR_ICONS
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-button-images=1
+gtk-menu-images=1
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle="hintmedium"
+gtk-xft-rgba="none"
+gtk-modules="canberra-gtk-module:gail:atk-bridge"
diff --git a/.config/gtk-2.0/gtkrc-2.0.bak b/.config/gtk-2.0/gtkrc-2.0.bak
new file mode 100644
index 0000000..c8d0af9
--- /dev/null
+++ b/.config/gtk-2.0/gtkrc-2.0.bak
@@ -0,0 +1,20 @@
+# DO NOT EDIT! This file will be overwritten by LXAppearance.
+# Any customization should be done in ~/.gtkrc-2.0.mine instead.
+
+include "/home/master/.gtkrc-2.0.mine"
+gtk-theme-name="Arc-Dark"
+gtk-icon-theme-name="Gruvbox-Material-Dark"
+gtk-font-name="Fira Sans 14"
+gtk-cursor-theme-name="Qogir-dark"
+gtk-cursor-theme-size=24
+gtk-toolbar-style=GTK_TOOLBAR_ICONS
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-button-images=1
+gtk-menu-images=1
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle="hintfull"
+gtk-xft-rgba="none"
+gtk-modules="canberra-gtk-module:gail:atk-bridge"
diff --git a/.config/gtk-3.0/bookmarks b/.config/gtk-3.0/bookmarks
new file mode 100644
index 0000000..ce1b7aa
--- /dev/null
+++ b/.config/gtk-3.0/bookmarks
@@ -0,0 +1 @@
+file:///mnt
diff --git a/.config/gtk-3.0/settings.ini b/.config/gtk-3.0/settings.ini
new file mode 100644
index 0000000..1dea2a0
--- /dev/null
+++ b/.config/gtk-3.0/settings.ini
@@ -0,0 +1,20 @@
+[Settings]
+gtk-theme-name=Arc-Dark
+gtk-icon-theme-name=Gruvbox-Plus-Dark
+gtk-sound-theme-name=Smooth
+gtk-application-prefer-dark-theme=true
+# GTK3 ignores bold or italic attributes.
+gtk-font-name=Fira Sans 14
+gtk-menu-images=1
+gtk-button-images=1
+gtk-toolbar-style=GTK_TOOLBAR_ICONS
+gtk-cursor-theme-name=Qogir-dark
+gtk-cursor-theme-size=24
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle=hintmedium
+gtk-xft-rgba=none
+gtk-modules=canberra-gtk-module:gail:atk-bridge
diff --git a/.config/htop/htoprc b/.config/htop/htoprc
new file mode 100644
index 0000000..4a3ad55
--- /dev/null
+++ b/.config/htop/htoprc
@@ -0,0 +1,63 @@
+# Beware! This file is rewritten by htop when settings are changed in the interface.
+# The parser is also very primitive, and not human-friendly.
+htop_version=3.3.0
+config_reader_min_version=3
+fields=0 48 17 18 38 39 40 2 46 47 49 1
+hide_kernel_threads=1
+hide_userland_threads=0
+hide_running_in_container=0
+shadow_other_users=0
+show_thread_names=0
+show_program_path=1
+highlight_base_name=0
+highlight_deleted_exe=1
+shadow_distribution_path_prefix=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
+header_margin=1
+screen_tabs=0
+detailed_cpu_time=0
+cpu_count_from_one=0
+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
+hide_function_bar=0
+header_layout=two_50_50
+column_meters_0=LeftCPUs Memory Swap
+column_meter_modes_0=1 1 1
+column_meters_1=RightCPUs Tasks LoadAverage Uptime
+column_meter_modes_1=1 2 2 2
+tree_view=0
+sort_key=46
+tree_sort_key=0
+sort_direction=-1
+tree_sort_direction=1
+tree_view_always_by_pid=0
+all_branches_collapsed=0
+screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
+.sort_key=PERCENT_CPU
+.tree_sort_key=PID
+.tree_view_always_by_pid=0
+.tree_view=0
+.sort_direction=-1
+.tree_sort_direction=1
+.all_branches_collapsed=0
+screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
+.sort_key=IO_RATE
+.tree_sort_key=PID
+.tree_view_always_by_pid=0
+.tree_view=0
+.sort_direction=-1
+.tree_sort_direction=1
+.all_branches_collapsed=0
diff --git a/.config/i3/config b/.config/i3/config
new file mode 100644
index 0000000..47a3b3e
--- /dev/null
+++ b/.config/i3/config
@@ -0,0 +1,644 @@
+# i3 config file (v4)
+# Please see http://i3wm.org/docs/userguide.html for a complete reference!
+
+
+
+
+##################
+### Autostart: ###
+##################
+
+# exec --no-startup-id sh ~/.xprofile
+# exec_always xrdb ~/.Xresources
+
+# important for fonts and anti aliasing
+# exec --no-startup-id xsettingsd &
+
+# pulseaudio system tray
+# exec --no-startup-id pasystray
+
+exec st -c dropdown_tmuxdd -e tmux
+
+################################
+### Commonly Used Variables: ###
+################################
+# - Below defined are some of the very common variables that users like to customise
+# - For Keybindings search: Commonly Used Keybindings in this document
+# - Make sure that you give the absolute path to the binary / program / executable
+# - You may specify any additional arguments required by the binary / executable
+
+### Wallpaper: ###
+# - You need to specify homescreen wallpaper using azote
+set $lockScreenWallpaper '/usr/share/wallpapers/garuda-wallpapers/Garuda-Desert.png'
+set $homeScreenWallpaper '/usr/share/wallpapers/garuda-wallpapers/background.jpg'
+
+### Applications: ###
+set $preferredTerminalEmulator $TERMINAL
+set $preferredBrowser torbrowser open
+set $preferredFileManager thunar
+set $preferredMailClient $MAIL
+set $preferredTextEditor $EDITOR
+set $preferredScreenCaptureTool flameshot gui
+
+### Movement keys ###
+set $left h
+set $down j
+set $up k
+set $right l
+
+# set modifier
+set $super Mod4
+set $alt Mod1
+
+
+
+
+###########################################
+### Commonly Used Application Keybinds: ###
+###########################################
+
+bindsym $super+F2 exec --no-startup-id dmenu-unicode
+bindsym $super+Shift+F2 exec --no-startup-id dmenu-unicode get-code
+bindsym $super+F3 exec --no-startup-id st -c "dropdown_sender" -e fsend
+bindsym $super+F4 exec --no-startup-id passmenu
+bindsym $super+Shift+F4 exec --no-startup-id passmenu --type
+bindsym $super+F5 exec --no-startup-id dmenu-zeal
+bindsym $super+F7 exec --no-startup-id sh -c 'find ~/.librewolf -mindepth 1 -maxdepth 1 -type d -name '????????.*' -printf "%f\n" | cut -d. -f2- | dmenu -p "LibreWolf Profile" | xargs -I{} setsid -f librewolf -P "{}"'
+bindsym $super+b exec --no-startup-id librewolf-open
+bindsym $super+c exec --no-startup-id edit-graphical-buffer
+bindsym $super+x exec --no-startup-id toggle-xeyes
+bindsym $super+i exec --no-startup-id sh -c 'xdotool type "$(grep -v "^#\|^\s*$" ~/Documents/Notes/bookmarks.txt | tac | dmenu -i -l 50 | cut -d\ -f1)"'
+bindsym $super+Shift+z exec --no-startup-id dmenu-zeal
+bindsym $super+Shift+b exec --no-startup-id librewolf-open "$(xprint)"
+bindsym $super+period exec --no-startup-id sh -c 'xdotool click --clearmodifiers 1 && xdotool keyup super'
+bindsym $super+slash exec --no-startup-id sh -c 'xdotool click --clearmodifiers 3 && xdotool keyup super'
+bindsym $super+comma exec --no-startup-id scrcpy-k
+bindsym $super+$alt+s exec --no-startup-id sh -c 'bm="$(xprint)" && echo "$bm" >> ~/Documents/Notes/bookmarks.txt && notify-send " Bookmark added" "$bm" || notify-send "❌ Failed to add bookmark" "$bm"'
+
+bindsym $super+$alt+F1 exec --no-startup-id _macro_F1
+bindsym $super+$alt+F2 exec --no-startup-id _macro_F2
+bindsym $super+$alt+F3 exec --no-startup-id _macro_F3
+bindsym $super+$alt+F4 exec --no-startup-id _macro_F4
+bindsym $super+$alt+F5 exec --no-startup-id _macro_F5
+bindsym $super+$alt+F6 exec --no-startup-id _macro_F6
+bindsym $super+$alt+F7 exec --no-startup-id _macro_F7
+bindsym $super+$alt+F8 exec --no-startup-id _macro_F8
+bindsym $super+$alt+F9 exec --no-startup-id _macro_F9
+bindsym $super+$alt+F10 exec --no-startup-id _macro_F10
+bindsym $super+$alt+F11 exec --no-startup-id _macro_F11
+bindsym $super+$alt+F12 exec --no-startup-id _macro_F12
+
+### Screen Capturing & Print Screen: ###
+
+bindsym $super+F9 exec $preferredScreenCaptureTool
+bindsym Print exec --no-startup-id flameshot screen
+bindsym Ctrl+Print exec --no-startup-id $preferredScreenCaptureTool
+
+### Start a Terminal Emulator: ###
+# - You can change the preferredTerminalEmulator variable
+# - $TERMINAL & xfce4-terminal can also be started using their individual keybindings
+
+bindsym $super+Return exec --no-startup-id $preferredTerminalEmulator
+bindsym $super+t exec --no-startup-id xfce4-terminal
+
+font pango: source code pro 16
+
+# Use Mouse+$super to drag floating windows to their wanted position
+floating_modifier $super
+
+
+# hide/unhide i3status bar
+bindsym $super+m bar mode toggle
+
+# start dmenu (a program launcher)
+set $i3dmenu i3-dmenu-desktop --dmenu="dmenu -i"
+
+bindsym $super+Shift+d exec --no-startup-id $i3dmenu
+bindsym $super+d exec --no-startup-id dmenu_run
+
+
+
+
+###################
+### Media Keys: ###
+###################
+
+# Screen brightness controls
+set $brightnessUp brightness up
+set $brightnessDown brightness down
+# set $brightnessUp brightnessctl set +5% && notify-send -r 4023423 "brightness: $(( $(brightnessctl g) / 1200 ))%"
+# set $brightnessDown brightnessctl set 5%- && notify-send -r 4023423 "brightness: $(( $(brightnessctl g) / 1200 ))%"
+
+# Use pactl to adjust volume in PulseAudio.
+set $refresh_i3status killall -SIGUSR1 i3status
+set $raiseVolume volctl up && pkill -SIGRTMIN+4 i3block
+set $lowerVolume volctl down && pkill -SIGRTMIN+4 i3block
+# pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
+# pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
+set $muteOutput pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
+set $muteInput pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
+
+# music control
+set $nextAudio playerctl next
+set $prevAudio playerctl previous
+set $playAudio playerctl play-pause
+set $stopAudio playerctl stop
+
+bindsym XF86MonBrightnessUp exec $brightnessUp
+bindsym XF86MonBrightnessDown exec $brightnessDown
+
+bindsym XF86AudioRaiseVolume exec --no-startup-id $raiseVolume
+bindsym XF86AudioLowerVolume exec --no-startup-id $lowerVolume
+bindsym XF86AudioMute exec --no-startup-id $muteOutput
+bindsym XF86AudioMicMute exec --no-startup-id $muteInput
+#change volume
+#bindsym XF86AudioRaiseVolume exec pulseaudio-ctl up
+#bindsym XF86AudioLowerVolume exec pulseaudio-ctl down
+#bindsym XF86AudioMute exec pulseaudio-ctl mute
+
+bindsym XF86AudioNext exec $nextAudio
+bindsym XF86AudioPrev exec $prevAudio
+bindsym XF86AudioPlay exec $playAudio
+bindsym XF86AudioStop exec $stopAudio
+
+
+bindsym $super+Ctrl+Right exec $brightnessUp
+bindsym $super+Ctrl+Left exec $brightnessDown
+
+bindsym $super+Ctrl+Up exec --no-startup-id $raiseVolume
+bindsym $super+Ctrl+Down exec --no-startup-id $lowerVolume
+bindsym $super+Ctrl+Insert exec --no-startup-id $muteOutput
+bindsym $super+Ctrl+Del exec --no-startup-id $muteInput
+
+bindsym $super+Ctrl+Next exec $nextAudio
+bindsym $super+Ctrl+Prior exec $prevAudio
+bindsym $super+Ctrl+Home exec $playAudio
+bindsym $super+Ctrl+End exec $stopAudio
+
+
+# bindsym XF86TouchpadToggle exec ~/bin/toggletouchpad.sh
+bindsym XF86PowerOff exec --no-startup-id notify-send "Power Off"
+bindsym XF86PowerDown exec --no-startup-id notify-send "Power Down"
+
+# Print screen
+bindsym $super+Print --release exec --no-startup-id i3-scrot -w
+bindsym $super+Shift+Print --release exec --no-startup-id i3-scrot -s
+
+
+
+
+#########################
+### window management ###
+#########################
+
+# kill focused window
+bindsym $super+q kill
+
+# split in horizontal orientation
+# bindsym $super+apostrophe split h
+# split in vertical orientation
+# bindsym $super+v split v
+
+bindsym $super+apostrophe split toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $super+s layout stacking
+bindsym $super+w layout tabbed
+bindsym $super+e layout toggle split # try 'layout default' here
+
+# enter fullscreen mode for the focused container
+bindsym $super+f fullscreen toggle
+bindsym $super+Shift+f fullscreen toggle global
+# change focus between tiling / floating windows
+bindsym $super+space focus mode_toggle
+# toggle tiling / floating
+bindsym $super+Shift+space floating toggle
+# toggle sticky
+bindsym $super+Shift+s sticky toggle
+
+# focus the parent container
+bindsym $super+a focus parent
+# focus the child container
+bindsym $super+Shift+a focus child
+
+# move the currently focused window to the scratchpad
+bindsym $super+Shift+minus move scratchpad
+# Show the next scratchpad window or hide the focused scratchpad window.
+# If there are multiple scratchpad windows, this command cycles through them.
+bindsym $super+minus scratchpad show
+
+# reload the configuration file
+bindsym $super+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $super+Shift+r restart
+bindsym $super+Shift+e exec --no-startup-id $TERMINAL -e nvim ~/.config/i3/config
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ bindsym $left resize shrink width 30 px or 5 ppt
+ bindsym $down resize grow height 30 px or 5 ppt
+ bindsym $up resize shrink height 30 px or 5 ppt
+ bindsym $right resize grow width 30 px or 5 ppt
+
+ bindsym Left resize shrink width 1 px or 1 ppt
+ bindsym Down resize grow height 1 px or 1 ppt
+ bindsym Up resize shrink height 1 px or 1 ppt
+ bindsym Right resize grow width 1 px or 1 ppt
+
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+
+}
+bindsym $super+r mode "resize"
+
+
+# change focus
+bindsym $super+$left focus left
+bindsym $super+$down focus down
+bindsym $super+$up focus up
+bindsym $super+$right focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $super+Left focus left
+bindsym $super+Down focus down
+bindsym $super+Up focus up
+bindsym $super+Right focus right
+
+# move focused window
+bindsym $super+Shift+$left move container left 30
+bindsym $super+Shift+$down move container down 30
+bindsym $super+Shift+$up move container up 30
+bindsym $super+Shift+$right move container right 30
+
+# alternatively, you can use the cursor keys:
+bindsym $super+Shift+Left move left
+bindsym $super+Shift+Down move down
+bindsym $super+Shift+Up move up
+bindsym $super+Shift+Right move right
+
+
+##################
+### Workspaces ###
+##################
+
+# navigate workspaces
+bindsym $super+bracketleft workspace $ws1
+bindsym $super+n workspace next
+bindsym $super+p workspace prev
+bindsym $super+bracketright workspace $ws10
+
+bindsym $super+Home workspace $ws1
+bindsym $super+Prior workspace prev
+bindsym $super+Next workspace next
+bindsym $super+End workspace $ws10
+
+bindsym $super+Tab workspace back_and_forth
+bindsym $super+Shift+Tab move container to workspace back_and_forth; workspace back_and_forth
+bindsym $super+$alt+Tab move container to workspace back_and_forth
+
+bindsym $super+o focus output right
+bindsym $super+Shift+o move container to output right; focus output right
+bindsym $super+$alt+o move container to output right
+bindsym $super+semicolon workspace back_and_forth
+bindsym $super+Shift+semicolon move container to workspace back_and_forth; focus output right
+bindsym $super+$alt+semicolon move container to workspace back_and_forth
+
+bindsym $super+Ctrl+semicolon workspace back_and_forth
+bindsym $super+Ctrl+Shift+semicolon move container to workspace back_and_forth; workspace back_and_forth
+bindsym $super+Ctrl+$alt+semicolon move container to workspace back_and_forth
+
+
+# move containers
+bindsym $super+Shift+bracketleft move container to workspace $ws1 ; workspace $ws1
+bindsym $super+Shift+n move container to workspace next ; workspace next
+bindsym $super+Shift+p move container to workspace prev ; workspace prev
+bindsym $super+Shift+bracketright move container to workspace $ws10; workspace $ws10
+
+bindsym $super+Shift+Home move container to workspace $ws1 ; workspace $ws1
+bindsym $super+Shift+Prior move container to workspace prev ; workspace prev
+bindsym $super+Shift+Next move container to workspace next ; workspace next
+bindsym $super+Shift+End move container to workspace $ws10; workspace $ws10
+
+
+# send containers
+bindsym $super+$alt+bracketleft move container to workspace $ws1
+bindsym $super+$alt+n move container to workspace next
+bindsym $super+$alt+p move container to workspace prev
+bindsym $super+$alt+bracketright move container to workspace $ws10
+
+bindsym $super+$alt+Home move container to workspace $ws1
+bindsym $super+$alt+Prior move container to workspace prev
+bindsym $super+$alt+Next move container to workspace next
+bindsym $super+$alt+End move container to workspace $ws10
+
+
+# set $ws1 " 1 󰣇 "
+# set $ws2 " 2  "
+# set $ws3 " 3  "
+# set $ws4 " 4  "
+# set $ws5 " 5  "
+# set $ws6 " 6  "
+# set $ws7 " 7 󰈹 "
+# set $ws8 " 8 󰈙 "
+# set $ws9 " 9  "
+# set $ws10 " 10  "
+
+set $ws1 "1:󰎤"
+set $ws2 "2:󰎧"
+set $ws3 "3:󰎪"
+set $ws4 "4:󰎭"
+set $ws5 "5:󰎱"
+set $ws6 "6:󰎳"
+set $ws7 "7:󰎶"
+set $ws8 "8:󰎹"
+set $ws9 "9:󰎼"
+set $ws10 "10:󰽽"
+
+
+# switch to workspace
+bindsym $super+1 workspace $ws1
+bindsym $super+2 workspace $ws2
+bindsym $super+3 workspace $ws3
+bindsym $super+4 workspace $ws4
+bindsym $super+5 workspace $ws5
+bindsym $super+6 workspace $ws6
+bindsym $super+7 workspace $ws7
+bindsym $super+8 workspace $ws8
+bindsym $super+9 workspace $ws9
+bindsym $super+0 workspace $ws10
+
+
+# Move to workspace with focused container
+bindsym $super+Shift+1 move container to workspace $ws1; workspace $ws1
+bindsym $super+Shift+2 move container to workspace $ws2; workspace $ws2
+bindsym $super+Shift+3 move container to workspace $ws3; workspace $ws3
+bindsym $super+Shift+4 move container to workspace $ws4; workspace $ws4
+bindsym $super+Shift+5 move container to workspace $ws5; workspace $ws5
+bindsym $super+Shift+6 move container to workspace $ws6; workspace $ws6
+bindsym $super+Shift+7 move container to workspace $ws7; workspace $ws7
+bindsym $super+Shift+8 move container to workspace $ws8; workspace $ws8
+bindsym $super+Shift+9 move container to workspace $ws9; workspace $ws9
+bindsym $super+Shift+0 move container to workspace $ws10; workspace $ws10
+
+
+# move focused container to workspace
+bindsym $super+$alt+1 move container to workspace $ws1
+bindsym $super+$alt+2 move container to workspace $ws2
+bindsym $super+$alt+3 move container to workspace $ws3
+bindsym $super+$alt+4 move container to workspace $ws4
+bindsym $super+$alt+5 move container to workspace $ws5
+bindsym $super+$alt+6 move container to workspace $ws6
+bindsym $super+$alt+7 move container to workspace $ws7
+bindsym $super+$alt+8 move container to workspace $ws8
+bindsym $super+$alt+9 move container to workspace $ws9
+bindsym $super+$alt+0 move container to workspace $ws10
+
+
+workspace $ws1 output "eDP-1-1"
+workspace $ws2 output "eDP-1-1"
+workspace $ws3 output "eDP-1-1"
+workspace $ws4 output "eDP-1-1"
+workspace $ws5 output "eDP-1-1"
+
+workspace $ws6 output "HDMI-0"
+workspace $ws7 output "HDMI-0"
+workspace $ws8 output "HDMI-0"
+workspace $ws9 output "HDMI-0"
+workspace $ws10 output "HDMI-0"
+workspace "12: W " output "HDMI-0"
+
+
+####################
+### Window rules ###
+####################
+
+# assign [class="Tor Browser"] $ws6
+# assign [class="librewolf"] $ws7
+# assign [class="Zeal"] $ws8
+
+# window rules, you can find the window class using xprop
+for_window [class=".*"] border pixel 4
+assign [class=URxvt] 1
+for_window [class=Viewnior|feh|Audacious|File-roller|Lxappearance|Lxtask|Pavucontrol|upgrade2ultimate.sh] floating enable
+for_window [class=URxvt|firedragon|Geany|Evince|Soffice|libreoffice*|mpv|Ghb|Xfburn|Gimp*|Inkscape|Vlc|Lxappearance|Audacity] focus
+for_window [class=Xfburn|GParted|System-config-printer.py|Lxtask|Pavucontrol|Exo-helper*|Lxrandr|Arandr] focus
+
+# Open specific applications in floating mode
+for_window [title="alsamixer"] floating enable border pixel 1
+for_window [class="calamares"] floating enable border normal
+for_window [class="Clipgrab"] floating enable
+for_window [title="File Transfer*"] floating enable
+for_window [class="bauh"] floating enable
+for_window [class="Galculator"] floating enable border pixel 1
+for_window [class="GParted"] floating enable border normal
+for_window [title="i3_help"] floating enable sticky enable border normal
+for_window [class="Lightdm-settings"] floating enable
+for_window [class="Lxappearance"] floating enable border normal
+for_window [class="Garuda Settings Manager"] floating enable border normal
+for_window [title="MuseScore: Play Panel"] floating enable
+for_window [class="azote"] floating enable sticky enable border normal
+for_window [class="Oblogout"] fullscreen enable
+for_window [class="octopi"] floating enable
+for_window [title="About Pale Moon"] floating enable
+for_window [class="Pamac-manager"] floating enable
+for_window [class="Pamac-updater"] floating enable
+for_window [class="Pavucontrol"] floating enable
+for_window [class="Qtconfig-qt4"] floating enable border normal
+for_window [class="qt5ct"] floating enable sticky enable border normal
+#for_window [title="sudo"] floating enable border normal
+for_window [class="Simple-scan"] floating enable border normal
+for_window [class="(?i)System-config-printer.py"] floating enable border normal
+for_window [class="Skype"] floating enable border normal
+for_window [class="Timeshift-gtk"] floating enable border normal
+for_window [class="(?i)virtualbox"] floating enable border normal
+for_window [class="Xfburn"] floating enable
+for_window [class="garuda-welcome"] floating enable
+for_window [class="Artha"] floating enable
+for_window [class="Tk"] floating enable border normal
+for_window [title="Swing"] floating enable move position center
+for_window [class="copyq"] floating enable
+for_window [class="tabbed"] floating enable border normal
+for_window [class="Yad"] floating enable border normal
+for_window [class="Dialog"] move position center
+for_window [class="KeePassXC"] move position center
+for_window [class="sun-applet-Main"] floating enable move position center
+for_window [window_type='dialog'] move position center
+for_window [title="Android Emulator - *"] floating enable border none sticky enable
+for_window [title="Emulator"] floating enable border none sticky enable
+for_window [class="mpv"] floating enable
+# for_window [class="Zeal"] floating enable move position below
+
+# #---Dropdown Windows---# #
+# General dropdown window traits. The order can matter.
+for_window [class="dropdown_*|tridactyl_*"] floating enable
+for_window [class="dropdown_*|tridactyl_*"] move scratchpad
+for_window [class="dropdown_*|tridactyl_*"] sticky enable
+for_window [class="dropdown_*|tridactyl_*"] scratchpad show
+for_window [class="dropdown_*"] move position center
+for_window [class="dropdown_tmuxdd"] scratchpad hide
+# for_window [class="dropdown_tmuxdd"] resize set 625 450
+# for_window [class="dropdown_dropdowncalc"] resize set 800 300
+# for_window [class="dropdown_tmuxdd"] border pixel 3
+# for_window [class="dropdown_dropdowncalc"] border pixel 2
+
+# setup xeyes rules
+for_window [class="XEyes"] floating enable
+for_window [class="XEyes"] sticky enable
+for_window [class="XEyes"] border pixel 0
+for_window [class="XEyes"] resize set 500 400
+for_window [class="XEyes"] move position 700 300
+# for_window [class="XEyes"] resize set 125 100
+# for_window [class="XEyes"] move position 1789 6
+
+# colour of border, background, text, indicator, and child_border
+client.focused #bf616a #2f343f #d8dee8 #bf616a #d8dee8
+client.focused_inactive #2f343f #2f343f #d8dee8 #2f343f #2f343f
+client.unfocused #2f343f #2f343f #d8dee8 #2f343f #2f343f
+client.urgent #2f343f #2f343f #d8dee8 #2f343f #2f343f
+client.placeholder #2f343f #2f343f #d8dee8 #2f343f #2f343f
+client.background #2f343f
+
+
+# change borders ?Convert this into a mode
+# bindsym $super+u border none
+# bindsym $super+y border pixel 1
+# bindsym $super+i border normal
+
+
+# panel
+# Start i3bar to display a workspace bar
+
+bar {
+ output primary
+ status_command exec i3blocks
+ bindsym --release button3 exec jgmenu --at-pointer
+ workspace_min_width 40
+ strip_workspace_numbers yes
+ #strip_workspace_name yes|no
+ # defaults
+ #colors {
+ #background #2f343f
+ #statusline #FFFFFF
+ #separator #666666
+
+ #focused_workspace #4C7899 #285577 #FFFFFF
+ #active_workspace #333333 #222222 #FFFFFF
+ #inactive_workspace #333333 #222222 #888888
+ #urgent_workspace #2F343A #900000 #FFFFFF
+ ##binding_mode #2F343A #900000 #FFFFFF
+ ## colour of border, background, and text
+ #}
+ colors {
+ background #2f343f
+ statusline #EEEEEE
+ separator #666666
+
+ focused_workspace #2f343f #2f343f #CCFFFF
+ active_workspace #2f343f #2f343f #EEEEEE
+ inactive_workspace #2f343f #2f343f #888888
+ urgent_workspace #AAFFFF #2f343f #AAFFFF
+ #binding_mode #2f343f #2f343f #EEEEEE
+ # colour of border, background, and text
+ }
+}
+
+
+bar {
+ output nonprimary
+ bindsym --release button3 exec jgmenu --at-pointer
+ workspace_min_width 40
+ strip_workspace_numbers yes
+ #strip_workspace_name yes|no
+ colors {
+ background #2f343f
+ statusline #EEEEEE
+ separator #666666
+
+ focused_workspace #2f343f #2f343f #AAFFFF
+ active_workspace #2f343f #2f343f #CCCCCC
+ inactive_workspace #2f343f #2f343f #888888
+ urgent_workspace #AACCFF #2f343f #AACCFF
+ #binding_mode #2f343f #2f343f #EEEEEE
+ # colour of border, background, and text
+ }
+}
+
+#############################
+### settings for i3-gaps: ###
+#############################
+
+# Set inner/outer gaps
+gaps inner 0
+gaps outer -2
+
+# Additionally, you can issue commands with the following syntax. This is useful to bind keys to changing the gap size.
+# gaps inner|outer current|all set|plus|minus <px>
+# gaps inner all set 10
+# gaps outer all plus 5
+
+# Smart gaps (gaps used if only more than one container on the workspace)
+smart_gaps on
+
+# Smart borders (draw borders around container only if it is not the only container on this workspace)
+# on|no_gaps (on=always activate and no_gaps=only activate if the gap size to the edge of the screen is 0)
+smart_borders on
+
+# Press $super+Shift+g to enter the gap mode. Choose o or i for modifying outer/inner gaps. Press one of + / - (in-/decrement for current workspace) or 0 (remove gaps for current workspace). If you also press Shift with these keys, the change will be global for all workspaces.
+set $mode_gaps Gaps: (o) outer, (i) inner
+set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global)
+set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global)
+bindsym $super+Shift+g mode "$mode_gaps"
+
+mode "$mode_gaps" {
+ bindsym o mode "$mode_gaps_outer"
+ bindsym i mode "$mode_gaps_inner"
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+mode "$mode_gaps_inner" {
+ bindsym plus gaps inner current plus 5
+ bindsym minus gaps inner current minus 5
+ bindsym 0 gaps inner current set 0
+
+ bindsym Shift+plus gaps inner all plus 5
+ bindsym Shift+minus gaps inner all minus 5
+ bindsym Shift+0 gaps inner all set 0
+
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+mode "$mode_gaps_outer" {
+ bindsym plus gaps outer current plus 5
+ bindsym minus gaps outer current minus 5
+ bindsym 0 gaps outer current set 0
+
+ bindsym Shift+plus gaps outer all plus 5
+ bindsym Shift+minus gaps outer all minus 5
+ bindsym Shift+0 gaps outer all set 0
+
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+
+# Set shut down, restart and locking features
+bindsym $super+BackSpace mode "$mode_system"
+set $mode_system (l)ock (e)xit switch_(u)ser (s)uspend (h)ibernate (r)eboot (Shift+s)hutdown
+mode "$mode_system" {
+ bindsym l exec --no-startup-id i3exit lock, mode "default"
+ bindsym e exec --no-startup-id i3exit logout, mode "default"
+ bindsym u exec --no-startup-id i3exit switch_user, mode "default"
+ bindsym s exec --no-startup-id i3exit suspend, mode "default"
+ bindsym h exec --no-startup-id i3exit hibernate, mode "default"
+ bindsym r exec --no-startup-id i3exit reboot, mode "default"
+ bindsym Shift+s exec --no-startup-id i3exit shutdown, mode "default"
+
+ # exit system mode: "Enter" or "Escape"
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+# TODO: create your own i3exit script as ?syst-power
+
+# Lock screen
+bindsym $super+Escape exec i3lock -t -i $lockScreenWallpaper
+
+# exec_always xrandr --output eDP-1-1-1 --auto --primary
diff --git a/.config/i3blocks/config b/.config/i3blocks/config
new file mode 100644
index 0000000..638f638
--- /dev/null
+++ b/.config/i3blocks/config
@@ -0,0 +1,71 @@
+# i3blocks configuration file
+#
+# The i3blocks man page describes the usage of the binary,
+# and its website describes the configuration:
+# https://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
+separator=false
+separator_block_width=35
+
+# Guess the weather hourly
+[weather]
+separator=true
+separator_block_width=50
+command=i3weather
+interval=1800
+color=#A4C2F4
+
+[badwidth]
+seprator=false
+command=echo "$(i3bandwidth)"
+interval=1
+
+[wifi]
+# command=echo "📡 $(i3wifi wlp0s20f3)"
+command=i3wifi wlp0s20f0u9
+interval=1
+
+[battery]
+command=i3battery
+interval=1
+
+[cpu]
+command=echo " $(i3cpu)"
+interval=3
+
+[memory]
+separator=true
+separator_block_width=50
+command=echo " $(i3memory)"
+interval=1
+
+[datetime]
+separator=false
+separator_block_width=25
+# command=case "$BLOCK_BUTTON" in 1) TERM=256colors clearx -n 'cal -y --color=always | less' ;; 2) $TERMINAL -e nvim ~/.config/i3blocks/config ;; esac; date +'🕒 %H:%M:%S 🗓️ %a %d.%m.%Y '
+command=case "$BLOCK_BUTTON" in 1) $TERMINAL -e sh -c 'cal -y --color=always | less' ;; 2) $TERMINAL -e nvim ~/.config/i3blocks/config ;; esac; date +' %H:%M:%S 󰃭 %a %d.%m.%Y '
+color=#CCFFFF
+interval=1
+
+# [ip]
+# command=hostname -i # | awk '{ print "IP:" $1 }'
+# interval=once
+# color=#91E78B
diff --git a/.config/i3blocks/systeminfo b/.config/i3blocks/systeminfo
new file mode 100644
index 0000000..68a6944
--- /dev/null
+++ b/.config/i3blocks/systeminfo
@@ -0,0 +1,50 @@
+# i3blocks configuration file
+#
+# The i3blocks man page describes the usage of the binary,
+# and its website describes the configuration:
+# https://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
+separator=false
+separator_block_width=35
+
+[badwidth]
+seprator=false
+command=echo "$(i3bandwidth)"
+interval=1
+
+[wifi]
+# command=echo "📡 $(i3wifi wlp0s20f3)"
+command=i3wifi wlp0s20f3
+interval=1
+
+[battery]
+command=i3battery
+interval=1
+
+[cpu]
+command=echo " $(i3cpu)"
+interval=3
+
+[memory]
+separator=true
+separator_block_width=50
+command=echo " $(i3memory)"
+interval=1
diff --git a/.config/ipython/profile_default/db/dhist b/.config/ipython/profile_default/db/dhist
new file mode 100644
index 0000000..a56d871
--- /dev/null
+++ b/.config/ipython/profile_default/db/dhist
Binary files differ
diff --git a/.config/ipython/profile_default/history.sqlite b/.config/ipython/profile_default/history.sqlite
new file mode 100644
index 0000000..3f42fc7
--- /dev/null
+++ b/.config/ipython/profile_default/history.sqlite
Binary files differ
diff --git a/.config/ipython/profile_default/ipython_config.py b/.config/ipython/profile_default/ipython_config.py
new file mode 100644
index 0000000..83056e8
--- /dev/null
+++ b/.config/ipython/profile_default/ipython_config.py
@@ -0,0 +1,1146 @@
+# Configuration file for ipython.
+
+#------------------------------------------------------------------------------
+# InteractiveShellApp(Configurable) configuration
+#------------------------------------------------------------------------------
+## A Mixin for applications that start InteractiveShell instances.
+#
+# Provides configurables for loading extensions and executing files
+# as part of configuring a Shell environment.
+#
+# The following methods should be called by the :meth:`initialize` method
+# of the subclass:
+#
+# - :meth:`init_path`
+# - :meth:`init_shell` (to be implemented by the subclass)
+# - :meth:`init_gui_pylab`
+# - :meth:`init_extensions`
+# - :meth:`init_code`
+
+## Execute the given command string.
+# Default: ''
+# c.InteractiveShellApp.code_to_run = ''
+
+## Run the file referenced by the PYTHONSTARTUP environment
+# variable at IPython startup.
+# Default: True
+# c.InteractiveShellApp.exec_PYTHONSTARTUP = True
+
+## List of files to run at IPython startup.
+# Default: []
+# c.InteractiveShellApp.exec_files = []
+
+## lines of code to run at IPython startup.
+# Default: []
+# c.InteractiveShellApp.exec_lines = []
+
+## A list of dotted module names of IPython extensions to load.
+# Default: []
+# c.InteractiveShellApp.extensions = []
+
+## Dotted module name(s) of one or more IPython extensions to load.
+#
+# For specifying extra extensions to load on the command-line.
+#
+# .. versionadded:: 7.10
+# Default: []
+# c.InteractiveShellApp.extra_extensions = []
+
+## A file to be run
+# Default: ''
+# c.InteractiveShellApp.file_to_run = ''
+
+## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk',
+# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt4', 'qt5', 'qt6', 'tk',
+# 'wx', 'gtk2', 'qt4').
+# Choices: any of ['asyncio', 'glut', 'gtk', 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt4', 'qt5', 'qt6', 'tk', 'wx', 'gtk2', 'qt4'] (case-insensitive) or None
+# Default: None
+# c.InteractiveShellApp.gui = None
+
+## Should variables loaded at startup (by startup files, exec_lines, etc.)
+# be hidden from tools like %who?
+# Default: True
+# c.InteractiveShellApp.hide_initial_ns = True
+
+## If True, IPython will not add the current working directory to sys.path.
+# When False, the current working directory is added to sys.path, allowing imports
+# of modules defined in the current directory.
+# Default: False
+# c.InteractiveShellApp.ignore_cwd = False
+
+## Configure matplotlib for interactive use with
+# the default matplotlib backend.
+# Choices: any of ['auto', 'agg', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'widget', 'wx'] (case-insensitive) or None
+# Default: None
+# c.InteractiveShellApp.matplotlib = None
+
+## Run the module as a script.
+# Default: ''
+# c.InteractiveShellApp.module_to_run = ''
+
+## Pre-load matplotlib and numpy for interactive use,
+# selecting a particular matplotlib backend and loop integration.
+# Choices: any of ['auto', 'agg', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'widget', 'wx'] (case-insensitive) or None
+# Default: None
+# c.InteractiveShellApp.pylab = None
+
+## If true, IPython will populate the user namespace with numpy, pylab, etc.
+# and an ``import *`` is done from numpy and pylab, when using pylab mode.
+#
+# When False, pylab mode should not import any names into the user
+# namespace.
+# Default: True
+# c.InteractiveShellApp.pylab_import_all = True
+
+## Reraise exceptions encountered loading IPython extensions?
+# Default: False
+# c.InteractiveShellApp.reraise_ipython_extension_failures = False
+
+#------------------------------------------------------------------------------
+# Application(SingletonConfigurable) configuration
+#------------------------------------------------------------------------------
+## This is an application.
+
+## The date format used by logging formatters for %(asctime)s
+# Default: '%Y-%m-%d %H:%M:%S'
+# c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S'
+
+## The Logging format template
+# Default: '[%(name)s]%(highlevel)s %(message)s'
+# c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s'
+
+## Set the log level by value or name.
+# Choices: any of [0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL']
+# Default: 30
+# c.Application.log_level = 30
+
+## Configure additional log handlers.
+#
+# The default stderr logs handler is configured by the log_level, log_datefmt
+# and log_format settings.
+#
+# This configuration can be used to configure additional handlers (e.g. to
+# output the log to a file) or for finer control over the default handlers.
+#
+# If provided this should be a logging configuration dictionary, for more
+# information see:
+# https://docs.python.org/3/library/logging.config.html#logging-config-
+# dictschema
+#
+# This dictionary is merged with the base logging configuration which defines
+# the following:
+#
+# * A logging formatter intended for interactive use called
+# ``console``.
+# * A logging handler that writes to stderr called
+# ``console`` which uses the formatter ``console``.
+# * A logger with the name of this application set to ``DEBUG``
+# level.
+#
+# This example adds a new handler that writes to a file:
+#
+# .. code-block:: python
+#
+# c.Application.logging_configuration = {
+# 'handlers': {
+# 'file': {
+# 'class': 'logging.FileHandler',
+# 'level': 'DEBUG',
+# 'filename': '<path/to/file>',
+# }
+# },
+# 'loggers': {
+# '<application-name>': {
+# 'level': 'DEBUG',
+# # NOTE: if you don't list the default "console"
+# # handler here then it will be disabled
+# 'handlers': ['console', 'file'],
+# },
+# }
+# }
+# Default: {}
+# c.Application.logging_config = {}
+
+## Instead of starting the Application, dump configuration to stdout
+# Default: False
+# c.Application.show_config = False
+
+## Instead of starting the Application, dump configuration to stdout (as JSON)
+# Default: False
+# c.Application.show_config_json = False
+
+#------------------------------------------------------------------------------
+# BaseIPythonApplication(Application) configuration
+#------------------------------------------------------------------------------
+## IPython: an enhanced interactive Python shell.
+
+# Default: False
+# c.BaseIPythonApplication.add_ipython_dir_to_sys_path = False
+
+## Whether to create profile dir if it doesn't exist
+# Default: False
+# c.BaseIPythonApplication.auto_create = False
+
+## Whether to install the default config files into the profile dir.
+# If a new profile is being created, and IPython contains config files for that
+# profile, then they will be staged into the new directory. Otherwise,
+# default config files will be automatically generated.
+# Default: False
+# c.BaseIPythonApplication.copy_config_files = False
+
+## Path to an extra config file to load.
+#
+# If specified, load this config file in addition to any other IPython
+# config.
+# Default: ''
+# c.BaseIPythonApplication.extra_config_file = ''
+
+## The name of the IPython directory. This directory is used for logging
+# configuration (through profiles), history storage, etc. The default is usually
+# $HOME/.ipython. This option can also be specified through the environment
+# variable IPYTHONDIR.
+# Default: ''
+# c.BaseIPythonApplication.ipython_dir = ''
+
+## The date format used by logging formatters for %(asctime)s
+# See also: Application.log_datefmt
+# c.BaseIPythonApplication.log_datefmt = '%Y-%m-%d %H:%M:%S'
+
+## The Logging format template
+# See also: Application.log_format
+# c.BaseIPythonApplication.log_format = '[%(name)s]%(highlevel)s %(message)s'
+
+## Set the log level by value or name.
+# See also: Application.log_level
+# c.BaseIPythonApplication.log_level = 30
+
+##
+# See also: Application.logging_config
+# c.BaseIPythonApplication.logging_config = {}
+
+## Whether to overwrite existing config files when copying
+# Default: False
+# c.BaseIPythonApplication.overwrite = False
+
+## The IPython profile to use.
+# Default: 'default'
+# c.BaseIPythonApplication.profile = 'default'
+
+## Instead of starting the Application, dump configuration to stdout
+# See also: Application.show_config
+# c.BaseIPythonApplication.show_config = False
+
+## Instead of starting the Application, dump configuration to stdout (as JSON)
+# See also: Application.show_config_json
+# c.BaseIPythonApplication.show_config_json = False
+
+## Create a massive crash report when IPython encounters what may be an
+# internal error. The default is to append a short message to the
+# usual traceback
+# Default: False
+# c.BaseIPythonApplication.verbose_crash = False
+
+#------------------------------------------------------------------------------
+# TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp) configuration
+#------------------------------------------------------------------------------
+# See also: BaseIPythonApplication.add_ipython_dir_to_sys_path
+# c.TerminalIPythonApp.add_ipython_dir_to_sys_path = False
+
+## Execute the given command string.
+# See also: InteractiveShellApp.code_to_run
+# c.TerminalIPythonApp.code_to_run = ''
+
+## Whether to install the default config files into the profile dir.
+# See also: BaseIPythonApplication.copy_config_files
+# c.TerminalIPythonApp.copy_config_files = False
+
+## Whether to display a banner upon starting IPython.
+# Default: True
+# c.TerminalIPythonApp.display_banner = True
+
+## Run the file referenced by the PYTHONSTARTUP environment
+# See also: InteractiveShellApp.exec_PYTHONSTARTUP
+# c.TerminalIPythonApp.exec_PYTHONSTARTUP = True
+
+## List of files to run at IPython startup.
+# See also: InteractiveShellApp.exec_files
+# c.TerminalIPythonApp.exec_files = []
+
+## lines of code to run at IPython startup.
+# See also: InteractiveShellApp.exec_lines
+# c.TerminalIPythonApp.exec_lines = []
+
+## A list of dotted module names of IPython extensions to load.
+# See also: InteractiveShellApp.extensions
+# c.TerminalIPythonApp.extensions = []
+
+## Path to an extra config file to load.
+# See also: BaseIPythonApplication.extra_config_file
+# c.TerminalIPythonApp.extra_config_file = ''
+
+##
+# See also: InteractiveShellApp.extra_extensions
+# c.TerminalIPythonApp.extra_extensions = []
+
+## A file to be run
+# See also: InteractiveShellApp.file_to_run
+# c.TerminalIPythonApp.file_to_run = ''
+
+## If a command or file is given via the command-line,
+# e.g. 'ipython foo.py', start an interactive shell after executing the
+# file or command.
+# Default: False
+# c.TerminalIPythonApp.force_interact = False
+
+## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk',
+# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt4', 'qt5', 'qt6', 'tk',
+# 'wx', 'gtk2', 'qt4').
+# See also: InteractiveShellApp.gui
+# c.TerminalIPythonApp.gui = None
+
+## Should variables loaded at startup (by startup files, exec_lines, etc.)
+# See also: InteractiveShellApp.hide_initial_ns
+# c.TerminalIPythonApp.hide_initial_ns = True
+
+## If True, IPython will not add the current working directory to sys.path.
+# See also: InteractiveShellApp.ignore_cwd
+# c.TerminalIPythonApp.ignore_cwd = False
+
+## Class to use to instantiate the TerminalInteractiveShell object. Useful for
+# custom Frontends
+# Default: 'IPython.terminal.interactiveshell.TerminalInteractiveShell'
+# c.TerminalIPythonApp.interactive_shell_class = 'IPython.terminal.interactiveshell.TerminalInteractiveShell'
+
+##
+# See also: BaseIPythonApplication.ipython_dir
+# c.TerminalIPythonApp.ipython_dir = ''
+
+## The date format used by logging formatters for %(asctime)s
+# See also: Application.log_datefmt
+# c.TerminalIPythonApp.log_datefmt = '%Y-%m-%d %H:%M:%S'
+
+## The Logging format template
+# See also: Application.log_format
+# c.TerminalIPythonApp.log_format = '[%(name)s]%(highlevel)s %(message)s'
+
+## Set the log level by value or name.
+# See also: Application.log_level
+# c.TerminalIPythonApp.log_level = 30
+
+##
+# See also: Application.logging_config
+# c.TerminalIPythonApp.logging_config = {}
+
+## Configure matplotlib for interactive use with
+# See also: InteractiveShellApp.matplotlib
+# c.TerminalIPythonApp.matplotlib = None
+
+## Run the module as a script.
+# See also: InteractiveShellApp.module_to_run
+# c.TerminalIPythonApp.module_to_run = ''
+
+## Whether to overwrite existing config files when copying
+# See also: BaseIPythonApplication.overwrite
+# c.TerminalIPythonApp.overwrite = False
+
+## The IPython profile to use.
+# See also: BaseIPythonApplication.profile
+# c.TerminalIPythonApp.profile = 'default'
+
+## Pre-load matplotlib and numpy for interactive use,
+# See also: InteractiveShellApp.pylab
+# c.TerminalIPythonApp.pylab = None
+
+## If true, IPython will populate the user namespace with numpy, pylab, etc.
+# See also: InteractiveShellApp.pylab_import_all
+# c.TerminalIPythonApp.pylab_import_all = True
+
+## Start IPython quickly by skipping the loading of config files.
+# Default: False
+# c.TerminalIPythonApp.quick = False
+
+## Reraise exceptions encountered loading IPython extensions?
+# See also: InteractiveShellApp.reraise_ipython_extension_failures
+# c.TerminalIPythonApp.reraise_ipython_extension_failures = False
+
+## Instead of starting the Application, dump configuration to stdout
+# See also: Application.show_config
+# c.TerminalIPythonApp.show_config = False
+
+## Instead of starting the Application, dump configuration to stdout (as JSON)
+# See also: Application.show_config_json
+# c.TerminalIPythonApp.show_config_json = False
+
+## Create a massive crash report when IPython encounters what may be an
+# See also: BaseIPythonApplication.verbose_crash
+# c.TerminalIPythonApp.verbose_crash = False
+
+#------------------------------------------------------------------------------
+# InteractiveShell(SingletonConfigurable) configuration
+#------------------------------------------------------------------------------
+## An enhanced, interactive shell for Python.
+
+## 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying which
+# nodes should be run interactively (displaying output from expressions).
+# Choices: any of ['all', 'last', 'last_expr', 'none', 'last_expr_or_assign']
+# Default: 'last_expr'
+# c.InteractiveShell.ast_node_interactivity = 'last_expr'
+
+## A list of ast.NodeTransformer subclass instances, which will be applied to
+# user input before code is run.
+# Default: []
+# c.InteractiveShell.ast_transformers = []
+
+## Automatically run await statement in the top level repl.
+# Default: True
+# c.InteractiveShell.autoawait = True
+
+## Make IPython automatically call any callable object even if you didn't type
+# explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically.
+# The value can be '0' to disable the feature, '1' for 'smart' autocall, where
+# it is not applied if there are no more arguments on the line, and '2' for
+# 'full' autocall, where all callable objects are automatically called (even if
+# no arguments are present).
+# Choices: any of [0, 1, 2]
+# Default: 0
+# c.InteractiveShell.autocall = 0
+
+## Autoindent IPython code entered interactively.
+# Default: True
+# c.InteractiveShell.autoindent = True
+
+## Enable magic commands to be called without the leading %.
+# Default: True
+# c.InteractiveShell.automagic = True
+
+## The part of the banner to be printed before the profile
+# Default: "Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0]\nType 'copyright', 'credits' or 'license' for more information\nIPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.\n"
+# c.InteractiveShell.banner1 = "Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0]\nType 'copyright', 'credits' or 'license' for more information\nIPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.\n"
+
+## The part of the banner to be printed after the profile
+# Default: ''
+# c.InteractiveShell.banner2 = ''
+
+## Set the size of the output cache. The default is 1000, you can change it
+# permanently in your config file. Setting it to 0 completely disables the
+# caching system, and the minimum value accepted is 3 (if you provide a value
+# less than 3, it is reset to 0 and a warning is issued). This limit is defined
+# because otherwise you'll spend more time re-flushing a too small cache than
+# working
+# Default: 1000
+# c.InteractiveShell.cache_size = 1000
+
+## Use colors for displaying information about objects. Because this information
+# is passed through a pager (like 'less'), and some pagers get confused with
+# color codes, this capability can be turned off.
+# Default: True
+# c.InteractiveShell.color_info = True
+
+## Set the color scheme (NoColor, Neutral, Linux, or LightBG).
+# Choices: any of ['Neutral', 'NoColor', 'LightBG', 'Linux'] (case-insensitive)
+# Default: 'Neutral'
+# c.InteractiveShell.colors = 'Neutral'
+
+# Default: False
+# c.InteractiveShell.debug = False
+
+## Don't call post-execute functions that have failed in the past.
+# Default: False
+# c.InteractiveShell.disable_failing_post_execute = False
+
+## If True, anything that would be passed to the pager
+# will be displayed as regular output instead.
+# Default: False
+# c.InteractiveShell.display_page = False
+
+## (Provisional API) enables html representation in mime bundles sent to pagers.
+# Default: False
+# c.InteractiveShell.enable_html_pager = False
+
+## Total length of command history
+# Default: 10000
+# c.InteractiveShell.history_length = 10000
+
+## The number of saved history entries to be loaded into the history buffer at
+# startup.
+# Default: 1000
+# c.InteractiveShell.history_load_length = 1000
+
+# Default: ''
+# c.InteractiveShell.ipython_dir = ''
+
+## Start logging to the given file in append mode. Use `logfile` to specify a log
+# file to **overwrite** logs to.
+# Default: ''
+# c.InteractiveShell.logappend = ''
+
+## The name of the logfile to use.
+# Default: ''
+# c.InteractiveShell.logfile = ''
+
+## Start logging to the default log file in overwrite mode. Use `logappend` to
+# specify a log file to **append** logs to.
+# Default: False
+# c.InteractiveShell.logstart = False
+
+## Select the loop runner that will be used to execute top-level asynchronous
+# code
+# Default: 'IPython.core.interactiveshell._asyncio_runner'
+# c.InteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner'
+
+# Choices: any of [0, 1, 2]
+# Default: 0
+# c.InteractiveShell.object_info_string_level = 0
+
+## Automatically call the pdb debugger after every exception.
+# Default: False
+# c.InteractiveShell.pdb = False
+
+# Default: False
+# c.InteractiveShell.quiet = False
+
+# Default: '\n'
+# c.InteractiveShell.separate_in = '\n'
+
+# Default: ''
+# c.InteractiveShell.separate_out = ''
+
+# Default: ''
+# c.InteractiveShell.separate_out2 = ''
+
+## Show rewritten input, e.g. for autocall.
+# Default: True
+# c.InteractiveShell.show_rewritten_input = True
+
+## Enables rich html representation of docstrings. (This requires the docrepr
+# module).
+# Default: False
+# c.InteractiveShell.sphinxify_docstring = False
+
+# Default: True
+# c.InteractiveShell.wildcards_case_sensitive = True
+
+## Switch modes for the IPython exception handlers.
+# Choices: any of ['Context', 'Plain', 'Verbose', 'Minimal'] (case-insensitive)
+# Default: 'Context'
+# c.InteractiveShell.xmode = 'Context'
+
+#------------------------------------------------------------------------------
+# TerminalInteractiveShell(InteractiveShell) configuration
+#------------------------------------------------------------------------------
+##
+# See also: InteractiveShell.ast_node_interactivity
+# c.TerminalInteractiveShell.ast_node_interactivity = 'last_expr'
+
+##
+# See also: InteractiveShell.ast_transformers
+# c.TerminalInteractiveShell.ast_transformers = []
+
+## Automatically add/delete closing bracket or quote when opening bracket or
+# quote is entered/deleted. Brackets: (), [], {} Quotes: '', ""
+# Default: False
+# c.TerminalInteractiveShell.auto_match = False
+
+##
+# See also: InteractiveShell.autoawait
+# c.TerminalInteractiveShell.autoawait = True
+
+##
+# See also: InteractiveShell.autocall
+# c.TerminalInteractiveShell.autocall = 0
+
+## Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None`
+# Default: None
+# c.TerminalInteractiveShell.autoformatter = None
+
+##
+# See also: InteractiveShell.autoindent
+# c.TerminalInteractiveShell.autoindent = True
+
+##
+# See also: InteractiveShell.automagic
+# c.TerminalInteractiveShell.automagic = True
+
+## Specifies from which source automatic suggestions are provided. Can be set to
+# `'AutoSuggestFromHistory`' or `None` to disableautomatic suggestions. Default
+# is `'AutoSuggestFromHistory`'.
+# Default: 'AutoSuggestFromHistory'
+# c.TerminalInteractiveShell.autosuggestions_provider = 'AutoSuggestFromHistory'
+
+## The part of the banner to be printed before the profile
+# See also: InteractiveShell.banner1
+# c.TerminalInteractiveShell.banner1 = "Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0]\nType 'copyright', 'credits' or 'license' for more information\nIPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.\n"
+
+## The part of the banner to be printed after the profile
+# See also: InteractiveShell.banner2
+# c.TerminalInteractiveShell.banner2 = ''
+
+##
+# See also: InteractiveShell.cache_size
+# c.TerminalInteractiveShell.cache_size = 1000
+
+##
+# See also: InteractiveShell.color_info
+# c.TerminalInteractiveShell.color_info = True
+
+## Set the color scheme (NoColor, Neutral, Linux, or LightBG).
+# See also: InteractiveShell.colors
+# c.TerminalInteractiveShell.colors = 'Neutral'
+
+## Set to confirm when you try to exit IPython with an EOF (Control-D in Unix,
+# Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a
+# direct exit without any confirmation.
+# Default: True
+c.TerminalInteractiveShell.confirm_exit = False
+
+# See also: InteractiveShell.debug
+# c.TerminalInteractiveShell.debug = False
+
+## File in which to store and read history
+# Default: '~/.pdbhistory'
+# c.TerminalInteractiveShell.debugger_history_file = '~/.pdbhistory'
+
+## Don't call post-execute functions that have failed in the past.
+# See also: InteractiveShell.disable_failing_post_execute
+# c.TerminalInteractiveShell.disable_failing_post_execute = False
+
+## Options for displaying tab completions, 'column', 'multicolumn', and
+# 'readlinelike'. These options are for `prompt_toolkit`, see `prompt_toolkit`
+# documentation for more information.
+# Choices: any of ['column', 'multicolumn', 'readlinelike']
+# Default: 'multicolumn'
+# c.TerminalInteractiveShell.display_completions = 'multicolumn'
+
+## If True, anything that would be passed to the pager
+# See also: InteractiveShell.display_page
+# c.TerminalInteractiveShell.display_page = False
+
+## Shortcut style to use at the prompt. 'vi' or 'emacs'.
+# Default: 'emacs'
+c.TerminalInteractiveShell.editing_mode = 'vi'
+
+## Set the editor used by IPython (default to $EDITOR/vi/notepad).
+# Default: 'nvim'
+# c.TerminalInteractiveShell.editor = 'nvim'
+
+## Add shortcuts from 'emacs' insert mode to 'vi' insert mode.
+# Default: True
+# c.TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode = True
+
+## Allows to enable/disable the prompt toolkit history search
+# Default: True
+# c.TerminalInteractiveShell.enable_history_search = True
+
+##
+# See also: InteractiveShell.enable_html_pager
+# c.TerminalInteractiveShell.enable_html_pager = False
+
+## Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. This is
+# in addition to the F2 binding, which is always enabled.
+# Default: False
+# c.TerminalInteractiveShell.extra_open_editor_shortcuts = False
+
+## Provide an alternative handler to be called when the user presses Return. This
+# is an advanced option intended for debugging, which may be changed or removed
+# in later releases.
+# Default: None
+# c.TerminalInteractiveShell.handle_return = None
+
+## Highlight matching brackets.
+# Default: True
+# c.TerminalInteractiveShell.highlight_matching_brackets = True
+
+## The name or class of a Pygments style to use for syntax
+# highlighting. To see available styles, run `pygmentize -L styles`.
+# Default: traitlets.Undefined
+# c.TerminalInteractiveShell.highlighting_style = traitlets.Undefined
+
+## Override highlighting format for specific tokens
+# Default: {}
+# c.TerminalInteractiveShell.highlighting_style_overrides = {}
+
+## Total length of command history
+# See also: InteractiveShell.history_length
+# c.TerminalInteractiveShell.history_length = 10000
+
+##
+# See also: InteractiveShell.history_load_length
+# c.TerminalInteractiveShell.history_load_length = 1000
+
+# See also: InteractiveShell.ipython_dir
+# c.TerminalInteractiveShell.ipython_dir = ''
+
+##
+# See also: InteractiveShell.logappend
+# c.TerminalInteractiveShell.logappend = ''
+
+##
+# See also: InteractiveShell.logfile
+# c.TerminalInteractiveShell.logfile = ''
+
+##
+# See also: InteractiveShell.logstart
+# c.TerminalInteractiveShell.logstart = False
+
+## Select the loop runner that will be used to execute top-level asynchronous
+# code
+# See also: InteractiveShell.loop_runner
+# c.TerminalInteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner'
+
+# Default: {}
+# c.TerminalInteractiveShell.mime_renderers = {}
+
+## Cursor shape changes depending on vi mode: beam in vi insert mode, block in
+# nav mode, underscore in replace mode.
+# Default: True
+# c.TerminalInteractiveShell.modal_cursor = True
+
+## Enable mouse support in the prompt (Note: prevents selecting text with the
+# mouse)
+# Default: False
+# c.TerminalInteractiveShell.mouse_support = False
+
+# See also: InteractiveShell.object_info_string_level
+# c.TerminalInteractiveShell.object_info_string_level = 0
+
+##
+# See also: InteractiveShell.pdb
+# c.TerminalInteractiveShell.pdb = False
+
+## Display the current vi mode (when using vi editing mode).
+# Default: True
+c.TerminalInteractiveShell.prompt_includes_vi_mode = False
+
+## Class used to generate Prompt token for prompt_toolkit
+# Default: 'IPython.terminal.prompts.Prompts'
+# c.TerminalInteractiveShell.prompts_class = 'IPython.terminal.prompts.Prompts'
+
+# See also: InteractiveShell.quiet
+# c.TerminalInteractiveShell.quiet = False
+
+# See also: InteractiveShell.separate_in
+# c.TerminalInteractiveShell.separate_in = '\n'
+
+# See also: InteractiveShell.separate_out
+# c.TerminalInteractiveShell.separate_out = ''
+
+# See also: InteractiveShell.separate_out2
+# c.TerminalInteractiveShell.separate_out2 = ''
+
+## Show rewritten input, e.g. for autocall.
+# See also: InteractiveShell.show_rewritten_input
+# c.TerminalInteractiveShell.show_rewritten_input = True
+
+## Use `raw_input` for the REPL, without completion and prompt colors.
+#
+# Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
+# IPython own testing machinery, and emacs inferior-shell integration through elpy.
+#
+# This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
+# environment variable is set, or the current terminal is not a tty.
+# Default: False
+# c.TerminalInteractiveShell.simple_prompt = False
+
+## Number of line at the bottom of the screen to reserve for the tab completion
+# menu, search history, ...etc, the height of these menus will at most this
+# value. Increase it is you prefer long and skinny menus, decrease for short and
+# wide.
+# Default: 6
+# c.TerminalInteractiveShell.space_for_menu = 6
+
+##
+# See also: InteractiveShell.sphinxify_docstring
+# c.TerminalInteractiveShell.sphinxify_docstring = False
+
+## Automatically set the terminal title
+# Default: True
+# c.TerminalInteractiveShell.term_title = True
+
+## Customize the terminal title format. This is a python format string.
+# Available substitutions are: {cwd}.
+# Default: 'IPython: {cwd}'
+# c.TerminalInteractiveShell.term_title_format = 'IPython: {cwd}'
+
+## The time in milliseconds that is waited for a mapped key
+# sequence to complete.
+# Default: 0.5
+# c.TerminalInteractiveShell.timeoutlen = 0.5
+
+## Use 24bit colors instead of 256 colors in prompt highlighting.
+# If your terminal supports true color, the following command should
+# print ``TRUECOLOR`` in orange::
+#
+# printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n"
+# Default: False
+# c.TerminalInteractiveShell.true_color = False
+
+## The time in milliseconds that is waited for a key code
+# to complete.
+# Default: 0.01
+# c.TerminalInteractiveShell.ttimeoutlen = 0.01
+
+# See also: InteractiveShell.wildcards_case_sensitive
+# c.TerminalInteractiveShell.wildcards_case_sensitive = True
+
+## Switch modes for the IPython exception handlers.
+# See also: InteractiveShell.xmode
+# c.TerminalInteractiveShell.xmode = 'Context'
+
+#------------------------------------------------------------------------------
+# HistoryAccessor(HistoryAccessorBase) configuration
+#------------------------------------------------------------------------------
+## Access the history database without adding to it.
+#
+# This is intended for use by standalone history tools. IPython shells use
+# HistoryManager, below, which is a subclass of this.
+
+## Options for configuring the SQLite connection
+#
+# These options are passed as keyword args to sqlite3.connect
+# when establishing database connections.
+# Default: {}
+# c.HistoryAccessor.connection_options = {}
+
+## enable the SQLite history
+#
+# set enabled=False to disable the SQLite history,
+# in which case there will be no stored history, no SQLite connection,
+# and no background saving thread. This may be necessary in some
+# threaded environments where IPython is embedded.
+# Default: True
+# c.HistoryAccessor.enabled = True
+
+## Path to file to use for SQLite history database.
+#
+# By default, IPython will put the history database in the IPython
+# profile directory. If you would rather share one history among
+# profiles, you can set this value in each, so that they are consistent.
+#
+# Due to an issue with fcntl, SQLite is known to misbehave on some NFS
+# mounts. If you see IPython hanging, try setting this to something on a
+# local disk, e.g::
+#
+# ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
+#
+# you can also use the specific value `:memory:` (including the colon
+# at both end but not the back ticks), to avoid creating an history file.
+# Default: traitlets.Undefined
+# c.HistoryAccessor.hist_file = traitlets.Undefined
+
+#------------------------------------------------------------------------------
+# HistoryManager(HistoryAccessor) configuration
+#------------------------------------------------------------------------------
+## A class to organize all history-related functionality in one place.
+
+## Options for configuring the SQLite connection
+# See also: HistoryAccessor.connection_options
+# c.HistoryManager.connection_options = {}
+
+## Write to database every x commands (higher values save disk access & power).
+# Values of 1 or less effectively disable caching.
+# Default: 0
+# c.HistoryManager.db_cache_size = 0
+
+## Should the history database include output? (default: no)
+# Default: False
+# c.HistoryManager.db_log_output = False
+
+## enable the SQLite history
+# See also: HistoryAccessor.enabled
+# c.HistoryManager.enabled = True
+
+## Path to file to use for SQLite history database.
+# See also: HistoryAccessor.hist_file
+# c.HistoryManager.hist_file = traitlets.Undefined
+
+#------------------------------------------------------------------------------
+# MagicsManager(Configurable) configuration
+#------------------------------------------------------------------------------
+## Object that handles all magic-related functionality for IPython.
+
+## Automatically call line magics without requiring explicit % prefix
+# Default: True
+# c.MagicsManager.auto_magic = True
+
+## Mapping from magic names to modules to load.
+#
+# This can be used in IPython/IPykernel configuration to declare lazy magics
+# that will only be imported/registered on first use.
+#
+# For example::
+#
+# c.MagicsManager.lazy_magics = {
+# "my_magic": "slow.to.import",
+# "my_other_magic": "also.slow",
+# }
+#
+# On first invocation of `%my_magic`, `%%my_magic`, `%%my_other_magic` or
+# `%%my_other_magic`, the corresponding module will be loaded as an ipython
+# extensions as if you had previously done `%load_ext ipython`.
+#
+# Magics names should be without percent(s) as magics can be both cell and line
+# magics.
+#
+# Lazy loading happen relatively late in execution process, and complex
+# extensions that manipulate Python/IPython internal state or global state might
+# not support lazy loading.
+# Default: {}
+# c.MagicsManager.lazy_magics = {}
+
+#------------------------------------------------------------------------------
+# ProfileDir(LoggingConfigurable) configuration
+#------------------------------------------------------------------------------
+## An object to manage the profile directory and its resources.
+#
+# The profile directory is used by all IPython applications, to manage
+# configuration, logging and security.
+#
+# This object knows how to find, create and manage these directories. This
+# should be used by any code that wants to handle profiles.
+
+## Set the profile location directly. This overrides the logic used by the
+# `profile` option.
+# Default: ''
+# c.ProfileDir.location = ''
+
+#------------------------------------------------------------------------------
+# BaseFormatter(Configurable) configuration
+#------------------------------------------------------------------------------
+## A base formatter class that is configurable.
+#
+# This formatter should usually be used as the base class of all formatters.
+# It is a traited :class:`Configurable` class and includes an extensible
+# API for users to determine how their objects are formatted. The following
+# logic is used to find a function to format an given object.
+#
+# 1. The object is introspected to see if it has a method with the name
+# :attr:`print_method`. If is does, that object is passed to that method
+# for formatting.
+# 2. If no print method is found, three internal dictionaries are consulted
+# to find print method: :attr:`singleton_printers`, :attr:`type_printers`
+# and :attr:`deferred_printers`.
+#
+# Users should use these dictionaries to register functions that will be
+# used to compute the format data for their objects (if those objects don't
+# have the special print methods). The easiest way of using these
+# dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
+# methods.
+#
+# If no function/callable is found to compute the format data, ``None`` is
+# returned and this format type is not used.
+
+# Default: {}
+# c.BaseFormatter.deferred_printers = {}
+
+# Default: True
+# c.BaseFormatter.enabled = True
+
+# Default: {}
+# c.BaseFormatter.singleton_printers = {}
+
+# Default: {}
+# c.BaseFormatter.type_printers = {}
+
+#------------------------------------------------------------------------------
+# PlainTextFormatter(BaseFormatter) configuration
+#------------------------------------------------------------------------------
+## The default pretty-printer.
+#
+# This uses :mod:`IPython.lib.pretty` to compute the format data of
+# the object. If the object cannot be pretty printed, :func:`repr` is used.
+# See the documentation of :mod:`IPython.lib.pretty` for details on
+# how to write pretty printers. Here is a simple example::
+#
+# def dtype_pprinter(obj, p, cycle):
+# if cycle:
+# return p.text('dtype(...)')
+# if hasattr(obj, 'fields'):
+# if obj.fields is None:
+# p.text(repr(obj))
+# else:
+# p.begin_group(7, 'dtype([')
+# for i, field in enumerate(obj.descr):
+# if i > 0:
+# p.text(',')
+# p.breakable()
+# p.pretty(field)
+# p.end_group(7, '])')
+
+# See also: BaseFormatter.deferred_printers
+# c.PlainTextFormatter.deferred_printers = {}
+
+# Default: ''
+# c.PlainTextFormatter.float_precision = ''
+
+## Truncate large collections (lists, dicts, tuples, sets) to this size.
+#
+# Set to 0 to disable truncation.
+# Default: 1000
+# c.PlainTextFormatter.max_seq_length = 1000
+
+# Default: 79
+# c.PlainTextFormatter.max_width = 79
+
+# Default: '\n'
+# c.PlainTextFormatter.newline = '\n'
+
+# Default: True
+# c.PlainTextFormatter.pprint = True
+
+# See also: BaseFormatter.singleton_printers
+# c.PlainTextFormatter.singleton_printers = {}
+
+# See also: BaseFormatter.type_printers
+# c.PlainTextFormatter.type_printers = {}
+
+# Default: False
+# c.PlainTextFormatter.verbose = False
+
+#------------------------------------------------------------------------------
+# Completer(Configurable) configuration
+#------------------------------------------------------------------------------
+## Enable unicode completions, e.g. \alpha<tab> . Includes completion of latex
+# commands, unicode names, and expanding unicode characters back to latex
+# commands.
+# Default: True
+# c.Completer.backslash_combining_completions = True
+
+## Enable debug for the Completer. Mostly print extra information for
+# experimental jedi integration.
+# Default: False
+# c.Completer.debug = False
+
+## Activate greedy completion
+# PENDING DEPRECATION. this is now mostly taken care of with Jedi.
+#
+# This will enable completion on elements of lists, results of function calls, etc.,
+# but can be unsafe because the code is actually evaluated on TAB.
+# Default: False
+# c.Completer.greedy = False
+
+## Experimental: restrict time (in milliseconds) during which Jedi can compute types.
+# Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
+# performance by preventing jedi to build its cache.
+# Default: 400
+# c.Completer.jedi_compute_type_timeout = 400
+
+## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is
+# installed.
+# Default: True
+# c.Completer.use_jedi = True
+
+#------------------------------------------------------------------------------
+# IPCompleter(Completer) configuration
+#------------------------------------------------------------------------------
+## Extension of the completer class with IPython-specific features
+
+## Enable unicode completions, e.g. \alpha<tab> . Includes completion of latex
+# commands, unicode names, and expanding unicode characters back to latex
+# commands.
+# See also: Completer.backslash_combining_completions
+# c.IPCompleter.backslash_combining_completions = True
+
+## Enable debug for the Completer. Mostly print extra information for
+# experimental jedi integration.
+# See also: Completer.debug
+# c.IPCompleter.debug = False
+
+## Activate greedy completion
+# See also: Completer.greedy
+# c.IPCompleter.greedy = False
+
+## Experimental: restrict time (in milliseconds) during which Jedi can compute
+# types.
+# See also: Completer.jedi_compute_type_timeout
+# c.IPCompleter.jedi_compute_type_timeout = 400
+
+## DEPRECATED as of version 5.0.
+#
+# Instruct the completer to use __all__ for the completion
+#
+# Specifically, when completing on ``object.<tab>``.
+#
+# When True: only those names in obj.__all__ will be included.
+#
+# When False [default]: the __all__ attribute is ignored
+# Default: False
+# c.IPCompleter.limit_to__all__ = False
+
+## Whether to merge completion results into a single list
+#
+# If False, only the completion results from the first non-empty
+# completer will be returned.
+# Default: True
+# c.IPCompleter.merge_completions = True
+
+## Instruct the completer to omit private method names
+#
+# Specifically, when completing on ``object.<tab>``.
+#
+# When 2 [default]: all names that start with '_' will be excluded.
+#
+# When 1: all 'magic' names (``__foo__``) will be excluded.
+#
+# When 0: nothing will be excluded.
+# Choices: any of [0, 1, 2]
+# Default: 2
+# c.IPCompleter.omit__names = 2
+
+## If True, emit profiling data for completion subsystem using cProfile.
+# Default: False
+# c.IPCompleter.profile_completions = False
+
+## Template for path at which to output profile data for completions.
+# Default: '.completion_profiles'
+# c.IPCompleter.profiler_output_dir = '.completion_profiles'
+
+## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is
+# installed.
+# See also: Completer.use_jedi
+# c.IPCompleter.use_jedi = True
+
+#------------------------------------------------------------------------------
+# ScriptMagics(Magics) configuration
+#------------------------------------------------------------------------------
+## Magics for talking to scripts
+#
+# This defines a base `%%script` cell magic for running a cell
+# with a program in a subprocess, and registers a few top-level
+# magics that call %%script with common interpreters.
+
+## Extra script cell magics to define
+#
+# This generates simple wrappers of `%%script foo` as `%%foo`.
+#
+# If you want to add script magics that aren't on your path,
+# specify them in script_paths
+# Default: []
+# c.ScriptMagics.script_magics = []
+
+## Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
+#
+# Only necessary for items in script_magics where the default path will not
+# find the right interpreter.
+# Default: {}
+# c.ScriptMagics.script_paths = {}
+
+#------------------------------------------------------------------------------
+# LoggingMagics(Magics) configuration
+#------------------------------------------------------------------------------
+## Magics related to all logging machinery.
+
+## Suppress output of log state when logging is enabled
+# Default: False
+# c.LoggingMagics.quiet = False
+
+#------------------------------------------------------------------------------
+# StoreMagics(Magics) configuration
+#------------------------------------------------------------------------------
+## Lightweight persistence for python variables.
+#
+# Provides the %store magic.
+
+## If True, any %store-d variables will be automatically restored
+# when IPython starts.
+# Default: False
+# c.StoreMagics.autorestore = False
diff --git a/.config/ipython/profile_default/startup/05-keybindings.py b/.config/ipython/profile_default/startup/05-keybindings.py
new file mode 100644
index 0000000..11439aa
--- /dev/null
+++ b/.config/ipython/profile_default/startup/05-keybindings.py
@@ -0,0 +1,18 @@
+from IPython import get_ipython
+from prompt_toolkit.enums import DEFAULT_BUFFER
+from prompt_toolkit.filters import HasFocus, ViInsertMode
+from prompt_toolkit.key_binding.vi_state import InputMode
+
+ip = get_ipython()
+
+def switch_to_navigation_mode(event):
+ vi_state = event.cli.vi_state
+ vi_state.input_mode = InputMode.NAVIGATION
+
+if getattr(ip, 'pt_app', None):
+ registry = ip.pt_app.key_bindings
+ registry.add_binding(u'j',u'k',
+ filter=(HasFocus(DEFAULT_BUFFER)
+ & ViInsertMode()))(switch_to_navigation_mode)
+
+
diff --git a/.config/ipython/profile_default/startup/10-startup.ipy b/.config/ipython/profile_default/startup/10-startup.ipy
new file mode 100644
index 0000000..05d2921
--- /dev/null
+++ b/.config/ipython/profile_default/startup/10-startup.ipy
@@ -0,0 +1,13 @@
+#!/usr/bin/ipython
+
+# print()
+# from math import *
+# print("Imported all functions from math")
+# import numpy as np
+# print("Imported numpy as np")
+# import sympy as sym
+# sym.var('a, b, c, x, y, z')
+
+# print("\n\t Don't waste time")
+# print("\t FOCUS ON THE ESSENTIAL \n")
+# alias q pkill ipython
diff --git a/.config/ipython/profile_default/startup/20-functions.ipy b/.config/ipython/profile_default/startup/20-functions.ipy
new file mode 100644
index 0000000..615a848
--- /dev/null
+++ b/.config/ipython/profile_default/startup/20-functions.ipy
@@ -0,0 +1,13 @@
+#!/usr/bin/ipython
+
+# def exp(x):
+# return sum([
+# x**n / m.factorial(n)
+# for n in range(0, 100)
+# ])
+#
+# def tables(from_, to_, rows=10):
+# for table in range(from_, to_+1):
+# for row in range(1, rows+1):
+# print(table, 'x', row, '=', table*row)
+# print()
diff --git a/.config/ipython/profile_default/startup/README b/.config/ipython/profile_default/startup/README
new file mode 100644
index 0000000..61d4700
--- /dev/null
+++ b/.config/ipython/profile_default/startup/README
@@ -0,0 +1,11 @@
+This is the IPython startup directory
+
+.py and .ipy files in this directory will be run *prior* to any code or files specified
+via the exec_lines or exec_files configurables whenever you load this profile.
+
+Files will be run in lexicographical order, so you can control the execution order of files
+with a prefix, e.g.::
+
+ 00-first.py
+ 50-middle.py
+ 99-last.ipy
diff --git a/.config/jgmenu/append.csv b/.config/jgmenu/append.csv
new file mode 100644
index 0000000..d370fc0
--- /dev/null
+++ b/.config/jgmenu/append.csv
@@ -0,0 +1,7 @@
+^sep()
+Lock,i3lock -c 000000,system-lock-screen
+Exit,^checkout(exit),system-shutdown
+^tag(exit)
+Suspend,systemctl -i suspend,system-log-out
+Reboot,systemctl -i reboot,system-reboot
+Poweroff,systemctl -i poweroff,system-shutdown
diff --git a/.config/jgmenu/backup/20230925074149958689103/jgmenurc b/.config/jgmenu/backup/20230925074149958689103/jgmenurc
new file mode 100644
index 0000000..c1632f7
--- /dev/null
+++ b/.config/jgmenu/backup/20230925074149958689103/jgmenurc
@@ -0,0 +1,74 @@
+# verbosity = 0
+# stay_alive = 1
+# persistent = 0
+# hide_on_startup = 0
+# csv_cmd = apps
+# tint2_look = 0
+# position_mode = fixed
+# edge_snap_x = 30
+# terminal_exec = x-terminal-emulator
+# terminal_args = -e
+# monitor = 0
+# hover_delay = 100
+# hide_back_items = 1
+# columns = 1
+# tabs = 120
+# menu_margin_x = 0
+# menu_margin_y = 0
+# menu_width = 200
+# menu_height_min = 0
+# menu_height_max = 0
+# menu_height_mode = static
+# menu_padding_top = 5
+# menu_padding_right = 5
+# menu_padding_bottom = 5
+# menu_padding_left = 5
+# menu_radius = 1
+# menu_border = 0
+# menu_halign = left
+# menu_valign = bottom
+# menu_gradient_pos = none
+# sub_spacing = 1
+# sub_padding_top = auto
+# sub_padding_right = auto
+# sub_padding_bottom = auto
+# sub_padding_left = auto
+# sub_hover_action = 1
+# item_margin_x = 3
+# item_margin_y = 3
+# item_height = 25
+# item_padding_x = 4
+# item_radius = 1
+# item_border = 0
+# item_halign = left
+# sep_height = 5
+# sep_halign = left
+# sep_markup =
+# font =
+# font_fallback = xtg
+# icon_size = 22
+# icon_text_spacing = 10
+# icon_norm_alpha = 100
+# icon_sel_alpha = 100
+# icon_theme =
+# icon_theme_fallback = xtg
+# arrow_string = ▸
+# arrow_width = 15
+# color_menu_bg = #000000 100
+# color_menu_bg_to = #000000 100
+# color_menu_border = #eeeeee 8
+# color_norm_bg = #000000 00
+# color_norm_fg = #eeeeee 100
+# color_sel_bg = #ffffff 20
+# color_sel_fg = #eeeeee 100
+# color_sel_border = #eeeeee 8
+# color_sep_fg = #ffffff 20
+# color_scroll_ind = #eeeeee 40
+# color_title_fg = #eeeeee 50
+# color_title_bg = #000000 0
+# color_title_border = #000000 0
+# csv_name_format = %n (%g)
+# csv_single_window = 0
+# csv_no_dirs = 0
+# csv_i18n =
+# csv_no_duplicates = 0
diff --git a/.config/jgmenu/jgmenurc b/.config/jgmenu/jgmenurc
new file mode 100644
index 0000000..741389b
--- /dev/null
+++ b/.config/jgmenu/jgmenurc
@@ -0,0 +1,74 @@
+# verbosity = 0
+stay_alive = 0
+# persistent = 0
+# hide_on_startup = 0
+# csv_cmd = apps
+# tint2_look = 0
+# position_mode = fixed
+# edge_snap_x = 30
+# terminal_exec = x-terminal-emulator
+# terminal_args = -e
+# monitor = 0
+# hover_delay = 100
+# hide_back_items = 1
+# columns = 1
+# tabs = 120
+# menu_margin_x = 0
+# menu_margin_y = 0
+# menu_width = 200
+# menu_height_min = 0
+# menu_height_max = 0
+# menu_height_mode = static
+# menu_padding_top = 5
+# menu_padding_right = 5
+# menu_padding_bottom = 5
+# menu_padding_left = 5
+# menu_radius = 1
+# menu_border = 0
+# menu_halign = left
+# menu_valign = bottom
+# menu_gradient_pos = none
+# sub_spacing = 1
+# sub_padding_top = auto
+# sub_padding_right = auto
+# sub_padding_bottom = auto
+# sub_padding_left = auto
+# sub_hover_action = 1
+# item_margin_x = 3
+# item_margin_y = 3
+item_height = 40
+# item_padding_x = 4
+# item_radius = 1
+# item_border = 0
+# item_halign = left
+# sep_height = 5
+# sep_halign = left
+# sep_markup =
+font = 16
+# font_fallback = xtg
+icon_size = 40
+# icon_text_spacing = 10
+# icon_norm_alpha = 100
+# icon_sel_alpha = 100
+icon_theme = Gruvbox-Material-Dark
+# icon_theme_fallback = xtg
+# arrow_string = ▸
+# arrow_width = 15
+# color_menu_bg = #000000 100
+# color_menu_bg_to = #000000 100
+# color_menu_border = #eeeeee 8
+# color_norm_bg = #000000 00
+# color_norm_fg = #eeeeee 100
+# color_sel_bg = #ffffff 20
+# color_sel_fg = #eeeeee 100
+# color_sel_border = #eeeeee 8
+# color_sep_fg = #ffffff 20
+# color_scroll_ind = #eeeeee 40
+# color_title_fg = #eeeeee 50
+# color_title_bg = #000000 0
+# color_title_border = #000000 0
+# csv_name_format = %n (%g)
+# csv_single_window = 0
+# csv_no_dirs = 0
+# csv_i18n =
+# csv_no_duplicates = 0
diff --git a/.config/keepassxc/keepassxc.ini b/.config/keepassxc/keepassxc.ini
new file mode 100644
index 0000000..a966b00
--- /dev/null
+++ b/.config/keepassxc/keepassxc.ini
@@ -0,0 +1,37 @@
+[General]
+ConfigVersion=2
+GlobalAutoTypeKey=65
+GlobalAutoTypeModifiers=402653184
+MinimizeAfterUnlock=true
+UpdateCheckMessageShown=true
+
+[Browser]
+CustomProxyLocation=
+
+[FdoSecrets]
+Enabled=false
+
+[GUI]
+CheckForUpdates=false
+CompactMode=false
+HidePreviewPanel=true
+HideToolbar=false
+MinimizeOnClose=false
+MinimizeOnStartup=true
+TrayIconAppearance=monochrome-light
+
+[KeeShare]
+Active="<?xml version=\"1.0\"?><KeeShare><Active/></KeeShare>\n"
+Foreign="<?xml version=\"1.0\"?>\n<KeeShare xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n <Foreign/>\n</KeeShare>\n"
+Own="<?xml version=\"1.0\"?><KeeShare><PrivateKey>MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkFWY7hom7zgQJHmTknXljZmUa0C6v5cxJzbzq8dPbwVXg9WbBiUoM9nwzaA8szfOrQhqN8KLNIuyxlmluQvyCzqO5tTomMRwRmjK47Bj6PJGGYSsJQnzMoFxiYGTDCJgUQGhFSYXdJcdepSx6AAuE44s1CMCqiNuoVVh/RfT6Vi6U3eMYnHaDohZeBV8u+BzNr9g6fBJOQV2+duIQ2gtmg4qYt8m87Nbhlw84l8/UBZ0EQot95yIupspE3hfepuWGZFsHOfRHQo/JT2utAihw/uNmVAr3Run3IrsM/mBrk4TJfwRuJDLYUyz6eqXhpM9astXxVEdU7Id0+340FKldAgMBAAECggEAHQfCPuJVZpOGvPhi5BxNBoNSbBLCVn4bvesTWB4WlpppiVwCy7BjPfojfdGJWO0PziT4R0exGQYQdVwNKE0bYbTWbv0rnQ/UIENtoE7gsP0DksSMWz3cr5jbmWPmf1J5NN6rxuHgSXEVCq1gV1jpHm1t2v61sx7/QlI2lOB9GV2gQ/xYqgQaWmRXVKnUnruCDextohTtcS2pMbM7+xIcgp0j7b5Cc5WrA5nRG4nlD2Nbn8QNMOwK+sqXcCobLvzPCVR/P3pfmRx6D9Cq61AJW4l7R0bKiIDhOGZW+l2FUAceFWVFHx+iVRS6usoH/BarEOq81TrnM+jQHjzaL5o3uwKBgQDtvtuf7CHZy8BdW2a6uBtBSv4UstC7UCfjWiTqqGE6ds8Gp03IusKin78MhQaMkInU4aPozUq78x46+KEOyEwURi7la+QpsyWPlHI1stJ/jAQ94ntRAYg/UR8p2pEVF2T7KVJpXtEU+MuwEY1gIdHMNl3c1p+DhCZ/2OEbLR4VJwKBgQD1mKAkYXEKeyAEM03nZag3JxnQ9Ny4G4sYmkplVH1uuMANssUpkems7+Q77V8waUvISO4/GhXEAr1S9Bxmw/PaGcDZw5ym6tc40gkXGpSrn6PgXtEqzDlXuyhOiDxqQ0YWtPSwKZZgANtK5mromgpPjqXZQ7dIlfyMrgL1GOeH2wKBgQCeIg+lDIPrgMm/jtcCpQiD4mSj0dhibstJPqFFb5/UKkhDja6AMDDbyFNj+WtEvbLf5QGIDFyELQ5TfSJrWbC434G72YqWbfEy0jMxInM+oRwFKYqKc/Fy4/tNdHKBy+C/6llFeuqo/19ECji102jfYt4F0L+i05hj+xanY9gZiwKBgQDhGfcN4VHerWN29h8dTAuWIXyEDSqQhI5FCoXNwlcFOMiuxX/4zghDvcyPMM3ibWBMPqw/ogT5Fxm4Ao5Vkpza9mfQMH5Qb0a8iaZTSsWhWDy31bAZbf3Q73XOJQhazTZccZckL7noXGCikfbDIwz4RmK0dGB1YyOLPaLwStdLqQKBgD4JWKVaOmb+6GzRC4PaCQoW4QVb/JEmcSclmQMPLWRFLRdjTH9A9Z4710+GoE5K1MG+9JR/Cj5iGeHXvnvo0OEF/GAJ0UvEt5nPuSHjQQwnDyHBgiYbRe+SuYJy0nPsDCuwGWjvyAzWPZA56eQ5MzliRioDWNyXxJPHTQLjPm+z</PrivateKey><PublicKey><Signer>master</Signer><Key>MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkFWY7hom7zgQJHmTknXljZmUa0C6v5cxJzbzq8dPbwVXg9WbBiUoM9nwzaA8szfOrQhqN8KLNIuyxlmluQvyCzqO5tTomMRwRmjK47Bj6PJGGYSsJQnzMoFxiYGTDCJgUQGhFSYXdJcdepSx6AAuE44s1CMCqiNuoVVh/RfT6Vi6U3eMYnHaDohZeBV8u+BzNr9g6fBJOQV2+duIQ2gtmg4qYt8m87Nbhlw84l8/UBZ0EQot95yIupspE3hfepuWGZFsHOfRHQo/JT2utAihw/uNmVAr3Run3IrsM/mBrk4TJfwRuJDLYUyz6eqXhpM9astXxVEdU7Id0+340FKldAgMBAAECggEAHQfCPuJVZpOGvPhi5BxNBoNSbBLCVn4bvesTWB4WlpppiVwCy7BjPfojfdGJWO0PziT4R0exGQYQdVwNKE0bYbTWbv0rnQ/UIENtoE7gsP0DksSMWz3cr5jbmWPmf1J5NN6rxuHgSXEVCq1gV1jpHm1t2v61sx7/QlI2lOB9GV2gQ/xYqgQaWmRXVKnUnruCDextohTtcS2pMbM7+xIcgp0j7b5Cc5WrA5nRG4nlD2Nbn8QNMOwK+sqXcCobLvzPCVR/P3pfmRx6D9Cq61AJW4l7R0bKiIDhOGZW+l2FUAceFWVFHx+iVRS6usoH/BarEOq81TrnM+jQHjzaL5o3uwKBgQDtvtuf7CHZy8BdW2a6uBtBSv4UstC7UCfjWiTqqGE6ds8Gp03IusKin78MhQaMkInU4aPozUq78x46+KEOyEwURi7la+QpsyWPlHI1stJ/jAQ94ntRAYg/UR8p2pEVF2T7KVJpXtEU+MuwEY1gIdHMNl3c1p+DhCZ/2OEbLR4VJwKBgQD1mKAkYXEKeyAEM03nZag3JxnQ9Ny4G4sYmkplVH1uuMANssUpkems7+Q77V8waUvISO4/GhXEAr1S9Bxmw/PaGcDZw5ym6tc40gkXGpSrn6PgXtEqzDlXuyhOiDxqQ0YWtPSwKZZgANtK5mromgpPjqXZQ7dIlfyMrgL1GOeH2wKBgQCeIg+lDIPrgMm/jtcCpQiD4mSj0dhibstJPqFFb5/UKkhDja6AMDDbyFNj+WtEvbLf5QGIDFyELQ5TfSJrWbC434G72YqWbfEy0jMxInM+oRwFKYqKc/Fy4/tNdHKBy+C/6llFeuqo/19ECji102jfYt4F0L+i05hj+xanY9gZiwKBgQDhGfcN4VHerWN29h8dTAuWIXyEDSqQhI5FCoXNwlcFOMiuxX/4zghDvcyPMM3ibWBMPqw/ogT5Fxm4Ao5Vkpza9mfQMH5Qb0a8iaZTSsWhWDy31bAZbf3Q73XOJQhazTZccZckL7noXGCikfbDIwz4RmK0dGB1YyOLPaLwStdLqQKBgD4JWKVaOmb+6GzRC4PaCQoW4QVb/JEmcSclmQMPLWRFLRdjTH9A9Z4710+GoE5K1MG+9JR/Cj5iGeHXvnvo0OEF/GAJ0UvEt5nPuSHjQQwnDyHBgiYbRe+SuYJy0nPsDCuwGWjvyAzWPZA56eQ5MzliRioDWNyXxJPHTQLjPm+z</Key></PublicKey></KeeShare>\n"
+QuietSuccess=true
+
+[PasswordGenerator]
+AdditionalChars=
+AdvancedMode=false
+EnsureEvery=false
+ExcludeAlike=false
+ExcludedChars=
+Length=60
+Numbers=false
+SpecialChars=false
diff --git a/.config/lf/brodie/draw_img b/.config/lf/brodie/draw_img
new file mode 100644
index 0000000..5a70d5e
--- /dev/null
+++ b/.config/lf/brodie/draw_img
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+
+clear_screen() {
+ printf '\e[%sH\e[9999C\e[1J%b\e[1;%sr' \
+ "$((LINES-2))" "${TMUX:+\e[2J}" "$max_items"
+}
+
+# Get a file's mime_type.
+mime_type=$(file -bi "$1")
+
+# File isn't an image file, give warning.
+if [[ $mime_type != image/* ]]; then
+ lf -remote "send $id echoerr 'Not an image'"
+ exit
+fi
+
+w3m_paths=(/usr/{local/,}{lib,libexec,lib64,libexec64}/w3m/w3mi*)
+read -r w3m _ < <(type -p w3mimgdisplay "${w3m_paths[@]}")
+read -r LINES COLUMNS < <(stty size)
+
+# Get terminal window size in pixels and set it to WIDTH and HEIGHT.
+export $(xdotool getactivewindow getwindowgeometry --shell)
+
+# Get the image size in pixels.
+read -r img_width img_height < <("$w3m" <<< "5;${CACHE:-$1}")
+
+((img_width > WIDTH)) && {
+ ((img_height=img_height*WIDTH/img_width))
+ ((img_width=WIDTH))
+}
+
+((img_height > HEIGHT)) && {
+ ((img_width=img_width*HEIGHT/img_height))
+ ((img_height=HEIGHT))
+}
+
+# Variable needed for centering image.
+HALF_HEIGHT=$(expr $HEIGHT / 2)
+HALF_WIDTH=$(expr $WIDTH / 2)
+HALF_IMG_HEIGHT=$(expr $img_height / 2)
+HALF_IMG_WIDTH=$(expr $img_width / 2)
+X_POS=$(expr $HALF_WIDTH - $HALF_IMG_WIDTH)
+Y_POS=$(expr $HALF_HEIGHT - $HALF_IMG_HEIGHT)
+
+clear_screen
+# Hide the cursor.
+printf '\e[?25l'
+
+# Display the image.
+printf '0;1;%s;%s;%s;%s;;;;;%s\n3;\n4\n' \
+ ${X_POS:-0} \
+ ${Y_POS:-0} \
+ "$img_width" \
+ "$img_height" \
+ "${CACHE:-$1}" | "$w3m" &>/dev/null
+
+# Wait for user input.
+read -ern 1
+
+# Clear the image.
+printf '6;%s;%s;%s;%s\n3;' \
+ "${X_POS:-0}" \
+ "${Y_POS:-0}" \
+ "$WIDTH" \
+ "$HEIGHT" | "$w3m" &>/dev/null
+
+clear_screen
diff --git a/.config/lf/brodie/image b/.config/lf/brodie/image
new file mode 100644
index 0000000..77ddb5b
--- /dev/null
+++ b/.config/lf/brodie/image
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+readonly ID_PREVIEW="preview"
+main() {
+ case "$1" in
+ "clear")
+ declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") \
+ > "$FIFO_UEBERZUG"
+ ;;
+ "draw")
+ declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" \
+ [x]="$3" [y]="$4" [max_width]="$5" [max_height]="$6" \
+ [path]="$2") > "$FIFO_UEBERZUG"
+ ;;
+ "*") echo "Unknown command: '$1', '$2'" ;;
+ esac
+}
+main "$@"
+
diff --git a/.config/lf/brodie/preview b/.config/lf/brodie/preview
new file mode 100644
index 0000000..3069a06
--- /dev/null
+++ b/.config/lf/brodie/preview
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# Clear the last preview (if any)
+$HOME/.config/lf/image clear
+
+# Calculate where the image should be placed on the screen.
+num=$(printf "%0.f\n" "`echo "$(tput cols) / 2" | bc`")
+numb=$(printf "%0.f\n" "`echo "$(tput cols) - $num - 1" | bc`")
+numc=$(printf "%0.f\n" "`echo "$(tput lines) - 2" | bc`")
+
+case "$1" in
+ *.tgz|*.tar.gz) tar tzf "$1";;
+ *.tar.bz2|*.tbz2) tar tjf "$1";;
+ *.tar.txz|*.txz) xz --list "$1";;
+ *.tar) tar tf "$1";;
+ *.zip|*.jar|*.war|*.ear|*.oxt) unzip -l "$1";;
+ *.rar) unrar l "$1";;
+ *.7z) 7z l "$1";;
+ *.[1-8]) man "$1" | col -b ;;
+ *.o) nm "$1" | less ;;
+ *.torrent) transmission-show "$1";;
+ *.iso) iso-info --no-header -l "$1";;
+ *odt,*.ods,*.odp,*.sxw) odt2txt "$1";;
+ *.doc) catdoc "$1" ;;
+ *.docx) docx2txt "$1" - ;;
+ *.csv) cat "$1" | sed s/,/\\n/g ;;
+ *.pdf)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ pdftoppm -png -f 1 -singlefile "$1" "$CACHE"
+ $HOME/.config/lf/image draw "$CACHE.png" $num 1 $numb $numc
+ ;;
+ *.epub)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ epub-thumbnailer "$1" "$CACHE" 1024
+ $HOME/.config/lf/image draw "$CACHE" $num 1 $numb $numc
+ ;;
+ *.bmp|*.jpg|*.jpeg|*.png|*.xpm)
+ $HOME/.config/lf/image draw "$1" $num 1 $numb $numc
+ ;;
+ *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.flac) exiftool "$1";;
+ *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ ffmpegthumbnailer -i "$1" -o "$CACHE" -s 0
+ $HOME/.config/lf/image draw "$CACHE" $num 1 $numb $numc
+ ;;
+ *) highlight --out-format ansi "$1" || cat "$1";;
+esac
+
diff --git a/.config/lf/colors b/.config/lf/colors
new file mode 100644
index 0000000..9edca7c
--- /dev/null
+++ b/.config/lf/colors
@@ -0,0 +1,175 @@
+# vim:ft=dircolors
+# (This is not a dircolors file but it helps to highlight colors and comments)
+
+# default values from dircolors
+# (entries with a leading # are not implemented in lf)
+# #no 00 # NORMAL
+# fi 00 # FILE
+# #rs 0 # RESET
+# di 01;34 # DIR
+# ln 01;36 # LINK
+# #mh 00 # MULTIHARDLINK
+# pi 40;33 # FIFO
+# so 01;35 # SOCK
+# #do 01;35 # DOOR
+# bd 40;33;01 # BLK
+# cd 40;33;01 # CHR
+# or 40;31;01 # ORPHAN
+# #mi 00 # MISSING
+# su 37;41 # SETUID
+# sg 30;43 # SETGID
+# #ca 30;41 # CAPABILITY
+# tw 30;42 # STICKY_OTHER_WRITABLE
+# ow 34;42 # OTHER_WRITABLE
+# st 37;44 # STICKY
+# ex 01;32 # EXEC
+
+# default values from lf (with matching order)
+# ln 01;36 # LINK
+# or 31;01 # ORPHAN
+# tw 01;34 # STICKY_OTHER_WRITABLE
+# ow 01;34 # OTHER_WRITABLE
+# st 01;34 # STICKY
+# di 01;34 # DIR
+# pi 33 # FIFO
+# so 01;35 # SOCK
+# bd 33;01 # BLK
+# cd 33;01 # CHR
+# su 01;32 # SETUID
+# sg 01;32 # SETGID
+# ex 01;32 # EXEC
+# fi 00 # FILE
+
+# file types (with matching order)
+ln 01;36 # LINK
+or 31;01 # ORPHAN
+tw 34 # STICKY_OTHER_WRITABLE
+ow 34 # OTHER_WRITABLE
+st 01;34 # STICKY
+di 01;34 # DIR
+pi 33 # FIFO
+so 01;35 # SOCK
+bd 33;01 # BLK
+cd 33;01 # CHR
+su 01;32 # SETUID
+sg 01;32 # SETGID
+ex 01;32 # EXEC
+fi 00 # FILE
+
+# archives or compressed (dircolors defaults)
+*.tar 01;31
+*.tgz 01;31
+*.arc 01;31
+*.arj 01;31
+*.taz 01;31
+*.lha 01;31
+*.lz4 01;31
+*.lzh 01;31
+*.lzma 01;31
+*.tlz 01;31
+*.txz 01;31
+*.tzo 01;31
+*.t7z 01;31
+*.zip 01;31
+*.z 01;31
+*.dz 01;31
+*.gz 01;31
+*.lrz 01;31
+*.lz 01;31
+*.lzo 01;31
+*.xz 01;31
+*.zst 01;31
+*.tzst 01;31
+*.bz2 01;31
+*.bz 01;31
+*.tbz 01;31
+*.tbz2 01;31
+*.tz 01;31
+*.deb 01;31
+*.rpm 01;31
+*.jar 01;31
+*.war 01;31
+*.ear 01;31
+*.sar 01;31
+*.rar 01;31
+*.alz 01;31
+*.ace 01;31
+*.zoo 01;31
+*.cpio 01;31
+*.7z 01;31
+*.rz 01;31
+*.cab 01;31
+*.wim 01;31
+*.swm 01;31
+*.dwm 01;31
+*.esd 01;31
+
+# image formats (dircolors defaults)
+*.jpg 01;35
+*.jpeg 01;35
+*.mjpg 01;35
+*.mjpeg 01;35
+*.gif 01;35
+*.bmp 01;35
+*.pbm 01;35
+*.pgm 01;35
+*.ppm 01;35
+*.tga 01;35
+*.xbm 01;35
+*.xpm 01;35
+*.tif 01;35
+*.tiff 01;35
+*.png 01;35
+*.webp 01;35
+*.svg 01;35
+*.svgz 01;35
+*.mng 01;35
+*.pcx 01;35
+*.mov 01;35
+*.mpg 01;35
+*.mpeg 01;35
+*.m2v 01;35
+*.mkv 01;35
+*.webm 01;35
+*.ogm 01;35
+*.mp4 01;35
+*.m4v 01;35
+*.mp4v 01;35
+*.vob 01;35
+*.qt 01;35
+*.nuv 01;35
+*.wmv 01;35
+*.asf 01;35
+*.rm 01;35
+*.rmvb 01;35
+*.flc 01;35
+*.avi 01;35
+*.fli 01;35
+*.flv 01;35
+*.gl 01;35
+*.dl 01;35
+*.xcf 01;35
+*.xwd 01;35
+*.yuv 01;35
+*.cgm 01;35
+*.emf 01;35
+*.ogv 01;35
+*.ogx 01;35
+
+# audio formats (dircolors defaults)
+*.aac 00;36
+*.au 00;36
+*.flac 00;36
+*.m4a 00;36
+*.mid 00;36
+*.midi 00;36
+*.mka 00;36
+*.mp3 00;36
+*.mpc 00;36
+*.ogg 00;36
+*.ra 00;36
+*.wav 00;36
+*.oga 00;36
+*.opus 00;36
+*.spx 00;36
+*.xspf 00;36
diff --git a/.config/lf/draw_img b/.config/lf/draw_img
new file mode 100644
index 0000000..5a70d5e
--- /dev/null
+++ b/.config/lf/draw_img
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+
+clear_screen() {
+ printf '\e[%sH\e[9999C\e[1J%b\e[1;%sr' \
+ "$((LINES-2))" "${TMUX:+\e[2J}" "$max_items"
+}
+
+# Get a file's mime_type.
+mime_type=$(file -bi "$1")
+
+# File isn't an image file, give warning.
+if [[ $mime_type != image/* ]]; then
+ lf -remote "send $id echoerr 'Not an image'"
+ exit
+fi
+
+w3m_paths=(/usr/{local/,}{lib,libexec,lib64,libexec64}/w3m/w3mi*)
+read -r w3m _ < <(type -p w3mimgdisplay "${w3m_paths[@]}")
+read -r LINES COLUMNS < <(stty size)
+
+# Get terminal window size in pixels and set it to WIDTH and HEIGHT.
+export $(xdotool getactivewindow getwindowgeometry --shell)
+
+# Get the image size in pixels.
+read -r img_width img_height < <("$w3m" <<< "5;${CACHE:-$1}")
+
+((img_width > WIDTH)) && {
+ ((img_height=img_height*WIDTH/img_width))
+ ((img_width=WIDTH))
+}
+
+((img_height > HEIGHT)) && {
+ ((img_width=img_width*HEIGHT/img_height))
+ ((img_height=HEIGHT))
+}
+
+# Variable needed for centering image.
+HALF_HEIGHT=$(expr $HEIGHT / 2)
+HALF_WIDTH=$(expr $WIDTH / 2)
+HALF_IMG_HEIGHT=$(expr $img_height / 2)
+HALF_IMG_WIDTH=$(expr $img_width / 2)
+X_POS=$(expr $HALF_WIDTH - $HALF_IMG_WIDTH)
+Y_POS=$(expr $HALF_HEIGHT - $HALF_IMG_HEIGHT)
+
+clear_screen
+# Hide the cursor.
+printf '\e[?25l'
+
+# Display the image.
+printf '0;1;%s;%s;%s;%s;;;;;%s\n3;\n4\n' \
+ ${X_POS:-0} \
+ ${Y_POS:-0} \
+ "$img_width" \
+ "$img_height" \
+ "${CACHE:-$1}" | "$w3m" &>/dev/null
+
+# Wait for user input.
+read -ern 1
+
+# Clear the image.
+printf '6;%s;%s;%s;%s\n3;' \
+ "${X_POS:-0}" \
+ "${Y_POS:-0}" \
+ "$WIDTH" \
+ "$HEIGHT" | "$w3m" &>/dev/null
+
+clear_screen
diff --git a/.config/lf/history b/.config/lf/history
new file mode 100644
index 0000000..1732142
--- /dev/null
+++ b/.config/lf/history
@@ -0,0 +1,7 @@
+$ mkdir "Gutar Gu S01 720p 10bit"
+$ mkdir Telusko
+$ mkdir Telusko
+$ mkdir system.txt
+$ mkdir Series
+$ chmod -x .dmenurc
+$ chmod -x .dmenurc
diff --git a/.config/lf/icons b/.config/lf/icons
new file mode 100644
index 0000000..7b900bc
--- /dev/null
+++ b/.config/lf/icons
@@ -0,0 +1,358 @@
+# vim:ft=conf
+
+# These examples require Nerd Fonts or a compatible font to be used.
+# See https://www.nerdfonts.com for more information.
+
+# default values from lf (with matching order)
+# ln l # LINK
+# or l # ORPHAN
+# tw t # STICKY_OTHER_WRITABLE
+# ow d # OTHER_WRITABLE
+# st t # STICKY
+# di d # DIR
+# pi p # FIFO
+# so s # SOCK
+# bd b # BLK
+# cd c # CHR
+# su u # SETUID
+# sg g # SETGID
+# ex x # EXEC
+# fi - # FILE
+
+# file types (with matching order)
+ln  # LINK
+or  # ORPHAN
+tw t # STICKY_OTHER_WRITABLE
+ow  # OTHER_WRITABLE
+st t # STICKY
+di  # DIR
+pi p # FIFO
+so s # SOCK
+bd b # BLK
+cd c # CHR
+su u # SETUID
+sg g # SETGID
+ex  # EXEC
+fi  # FILE
+
+# file extensions (vim-devicons)
+*.styl 
+*.sass 
+*.scss 
+*.htm 
+*.html 
+*.slim 
+*.haml 
+*.ejs 
+*.css 
+*.less 
+*.md 
+*.mdx 
+*.markdown 
+*.rmd 
+*.json 
+*.webmanifest 
+*.js 
+*.mjs 
+*.jsx 
+*.rb 
+*.gemspec 
+*.rake 
+*.php 
+*.py 
+*.pyc 
+*.pyo 
+*.pyd 
+*.coffee 
+*.mustache 
+*.hbs 
+*.conf 
+*.ini 
+*.yml 
+*.yaml 
+*.toml 
+*.bat 
+*.mk 
+*.jpg 
+*.jpeg 
+*.bmp 
+*.png 
+*.webp 
+*.gif 
+*.ico 
+*.twig 
+*.cpp 
+*.c++ 
+*.cxx 
+*.cc 
+*.cp 
+*.c 
+*.cs 󰌛
+*.h 
+*.hh 
+*.hpp 
+*.hxx 
+*.hs 
+*.lhs 
+*.nix 
+*.lua 
+*.java 
+*.sh 
+*.fish 
+*.bash 
+*.zsh 
+*.ksh 
+*.csh 
+*.awk 
+*.ps1 
+*.ml λ
+*.mli λ
+*.diff 
+*.db 
+*.sql 
+*.dump 
+*.clj 
+*.cljc 
+*.cljs 
+*.edn 
+*.scala 
+*.go 
+*.dart 
+*.xul 
+*.sln 
+*.suo 
+*.pl 
+*.pm 
+*.t 
+*.rss 
+'*.f#' 
+*.fsscript 
+*.fsx 
+*.fs 
+*.fsi 
+*.rs 
+*.rlib 
+*.d 
+*.erl 
+*.hrl 
+*.ex 
+*.exs 
+*.eex 
+*.leex 
+*.heex 
+*.vim 
+*.ai 
+*.psd 
+*.psb 
+*.ts 
+*.tsx 
+*.jl 
+*.pp 
+*.vue 
+*.elm 
+*.swift 
+*.xcplayground 
+*.tex 󰙩
+*.r 󰟔
+*.rproj 󰗆
+*.sol 󰡪
+*.pem 
+
+# file names (vim-devicons) (case-insensitive not supported in lf)
+*gruntfile.coffee 
+*gruntfile.js 
+*gruntfile.ls 
+*gulpfile.coffee 
+*gulpfile.js 
+*gulpfile.ls 
+*mix.lock 
+*dropbox 
+*.ds_store 
+*.gitconfig 
+*.gitignore 
+*.gitattributes 
+*.gitlab-ci.yml 
+*.bashrc 
+*.zshrc 
+*.zshenv 
+*.zprofile 
+*.vimrc 
+*.gvimrc 
+*_vimrc 
+*_gvimrc 
+*.bashprofile 
+*favicon.ico 
+*license 
+*node_modules 
+*react.jsx 
+*procfile 
+*dockerfile 
+*docker-compose.yml 
+*rakefile 
+*config.ru 
+*gemfile 
+*makefile 
+*cmakelists.txt 
+*robots.txt 󰚩
+
+# file names (case-sensitive adaptations)
+*Gruntfile.coffee 
+*Gruntfile.js 
+*Gruntfile.ls 
+*Gulpfile.coffee 
+*Gulpfile.js 
+*Gulpfile.ls 
+*Dropbox 
+*.DS_Store 
+*LICENSE 
+*React.jsx 
+*Procfile 
+*Dockerfile 
+*Docker-compose.yml 
+*Rakefile 
+*Gemfile 
+*Makefile 
+*CMakeLists.txt 
+
+# file patterns (vim-devicons) (patterns not supported in lf)
+# .*jquery.*\.js$ 
+# .*angular.*\.js$ 
+# .*backbone.*\.js$ 
+# .*require.*\.js$ 
+# .*materialize.*\.js$ 
+# .*materialize.*\.css$ 
+# .*mootools.*\.js$ 
+# .*vimrc.* 
+# Vagrantfile$ 
+
+# file patterns (file name adaptations)
+*jquery.min.js 
+*angular.min.js 
+*backbone.min.js 
+*require.min.js 
+*materialize.min.js 
+*materialize.min.css 
+*mootools.min.js 
+*vimrc 
+Vagrantfile 
+
+# archives or compressed (extensions from dircolors defaults)
+*.tar 
+*.tgz 
+*.arc 
+*.arj 
+*.taz 
+*.lha 
+*.lz4 
+*.lzh 
+*.lzma 
+*.tlz 
+*.txz 
+*.tzo 
+*.t7z 
+*.zip 
+*.z 
+*.dz 
+*.gz 
+*.lrz 
+*.lz 
+*.lzo 
+*.xz 
+*.zst 
+*.tzst 
+*.bz2 
+*.bz 
+*.tbz 
+*.tbz2 
+*.tz 
+*.deb 
+*.rpm 
+*.jar 
+*.war 
+*.ear 
+*.sar 
+*.rar 
+*.alz 
+*.ace 
+*.zoo 
+*.cpio 
+*.7z 
+*.rz 
+*.cab 
+*.wim 
+*.swm 
+*.dwm 
+*.esd 
+
+# image formats (extensions from dircolors defaults)
+*.jpg 
+*.jpeg 
+*.mjpg 
+*.mjpeg 
+*.gif 
+*.bmp 
+*.pbm 
+*.pgm 
+*.ppm 
+*.tga 
+*.xbm 
+*.xpm 
+*.tif 
+*.tiff 
+*.png 
+*.svg 
+*.svgz 
+*.mng 
+*.pcx 
+*.mov 
+*.mpg 
+*.mpeg 
+*.m2v 
+*.mkv 
+*.webm 
+*.ogm 
+*.mp4 
+*.m4v 
+*.mp4v 
+*.vob 
+*.qt 
+*.nuv 
+*.wmv 
+*.asf 
+*.rm 
+*.rmvb 
+*.flc 
+*.avi 
+*.fli 
+*.flv 
+*.gl 
+*.dl 
+*.xcf 
+*.xwd 
+*.yuv 
+*.cgm 
+*.emf 
+*.ogv 
+*.ogx 
+
+# audio formats (extensions from dircolors defaults)
+*.aac 
+*.au 
+*.flac 
+*.m4a 
+*.mid 
+*.midi 
+*.mka 
+*.mp3 
+*.mpc 
+*.ogg 
+*.ra 
+*.wav 
+*.oga 
+*.opus 
+*.spx 
+*.xspf 
+
+# other formats
+*.pdf 
+*.log 
diff --git a/.config/lf/image b/.config/lf/image
new file mode 100644
index 0000000..77ddb5b
--- /dev/null
+++ b/.config/lf/image
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+readonly ID_PREVIEW="preview"
+main() {
+ case "$1" in
+ "clear")
+ declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") \
+ > "$FIFO_UEBERZUG"
+ ;;
+ "draw")
+ declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" \
+ [x]="$3" [y]="$4" [max_width]="$5" [max_height]="$6" \
+ [path]="$2") > "$FIFO_UEBERZUG"
+ ;;
+ "*") echo "Unknown command: '$1', '$2'" ;;
+ esac
+}
+main "$@"
+
diff --git a/.config/lf/lfrc b/.config/lf/lfrc
new file mode 100644
index 0000000..daf9b1f
--- /dev/null
+++ b/.config/lf/lfrc
@@ -0,0 +1,160 @@
+# interpreter for shell commands
+set shell sh
+
+# set '-eu' options for shell commands
+# These options are used to have safer shell commands. Option '-e' is used to
+# exit on error and option '-u' is used to give error for unset variables.
+# Option '-f' disables pathname expansion which can be useful when $f, $fs, and
+# $fx variables contain names with '*' or '?' characters. However, this option
+# is used selectively within individual commands as it can be limiting at
+# times.
+set shellopts '-eu'
+
+# set internal field separator (IFS) to "\n" for shell commands
+# This is useful to automatically split file names in $fs and $fx properly
+# since default file separator used in these variables (i.e. 'filesep' option)
+# is newline. You need to consider the values of these options and create your
+# commands accordingly.
+set ifs "\n"
+
+# leave some space at the top and the bottom of the screen
+set scrolloff 5
+
+# Basic Settings
+set hidden true
+#set drawbox true
+set icons true
+set ignorecase true
+set smartcase true
+set mouse
+set previewer preview
+set preview
+
+cmd open $$OPENER $f
+
+cmd on-cd &{{
+ sed -i "\|^$PWD$|d" ${XDG_DATA_HOME:-$HOME/.local/share}/cdhist
+ echo "$PWD" >> ${XDG_DATA_HOME:-$HOME/.local/share}/cdhist
+}}
+
+cmd extract ${{
+ # extract the current file with the right command
+ # (xkcd link: https://xkcd.com/1168/)
+ set -f
+ for f in $fx; do case "$f" in
+ *.tar) tar xvf "$f" ;;
+ *.tar.bz|*.tar.bz2|*.tbz|*.tbz2) tar xjvf "$f" ;;
+ *.tar.gz|*.tgz) tar xzvf "$f" ;;
+ *.tar.xz|*.txz) tar xJvf "$f" ;;
+ *.gz) gunzip "$f" ;;
+ *.zip) unzip "$f" ;;
+ *.rar) unrar x "$f" ;;
+ *.7z) 7z x "$f" ;;
+ *.zst) unzstd "$f" ;;
+ *) echo "Unsupported format" >&2; exit 1 ;;
+ esac done
+}}
+
+cmd link_index %{{
+ case "$f" in
+ *.html) index="index.html" ;;
+ *) echo "Unsupported file"; exit 1 ;;
+ esac
+ [ -e "$index" ] && [ ! -L "$index" ] && {
+ echo "Failed: $index already exists and is not a symbolic link"
+ exit
+ }
+ ln -sf "$f" "$index"
+}}
+
+cmd select_eval ${{
+ res="$(eval "$@")"
+ [ -d "$res" ] &&
+ lf -remote "send $id cd \"$res\"" ||
+ lf -remote "send $id select \"$res\""
+}}
+
+cmd link %{{
+ set -- $(cat ~/.local/share/lf/files)
+ mode="$1"
+ shift
+ [ "$#" -lt 1 ] &&
+ { lf -remote "send $id echo no files to link"; exit 0; }
+ case "$mode" in
+ copy) ln -sr -t . -- "$@";;
+ move) ln -t . -- "$@";;
+ esac
+ rm ~/.local/share/lf/files
+ lf -remote "send clear"
+}}
+
+# Basic Functions
+cmap <tab> cmd-menu-complete
+cmap <backtab> cmd-menu-complete-back
+map <enter> shell
+map <delete> trash
+map <c-space> set preview!
+map <c-n> push $mkdir<space>""<c-b>
+map <a-s> :source ~/.config/lf/lfrc
+map <tab> :toggle; down
+map <backtab> :toggle; up
+map Z :toggle; up
+map <c-j> select_eval "fzf --reverse --header-first --header='Jump to location'"
+map <backspace> ${{ lf -remote "send $id select \"$(cat ${XDG_DATA_HOME:-$HOME/.local/share}/openhist |
+ fzf --tac --reverse --header-first --header='File History')\"" }}
+map <c-k> ${{ lf -remote "send $id cd \"$(cat ${XDG_DATA_HOME:-$HOME/.local/share}/cdhist |
+ fzf --tac --reverse --header-first --header='Path History')\"" }}
+map <c-c> ${{ lf -remote "send $id cd \"$(find -mindepth 1 -type d |
+ fzf --reverse --header-first --header='Jump to directory')\"" }}
+
+map c
+map d
+map I :rename; cmd-home
+map i :rename
+map a :rename; cmd-right
+map A :rename; cmd-end
+map S push A<c-u>
+map o $LESSOPEN="|preview %s" less $f
+map O $mimeopen --ask $f
+map . set hidden!
+map x cut
+map M $lf -remote "send $id select \"$(fmd)\""
+map D delete
+map W $setsid -f $TERMINAL >/dev/null 2>&1
+map X !$f
+map T !dev test $f
+map b $vidir
+map V push :!nvim<space>""<c-b>
+map P :link
+
+map ge extract $f
+map gl clear
+map gx ${{ chmod u+x $fx; lf -remote "send $id reload"; }}
+map gX ${{ chmod -x $fx; lf -remote "send $id reload"; }}
+map gm push $chmod<space>--<space>$fx<c-a><a-f><space>
+map gL %lf -remote "send ${id} select '$(readlink $f)'"
+map gd !du -hd1
+map gf !file $f
+map gy %{{ printf "%s" "$f" | xsel -b }}
+map gY %{{ printf "%s" "$fs" | xsel -b }}
+map gi link_index
+map gsh $setbg $f
+map gsl $setbg -l $f
+map zpp set previewer preview
+map zpc set previewer cat
+map zpb set previewer preview-bat
+map zph set previewer preview-highlight
+
+# Trash Mappings
+map dd ${{ echo "$fx" | xargs -I{} trash-put "{}" }}
+map dtc $trash-empty
+map dtr $trash-restore
+# Dragon Mapping
+map dr %dragon-drop -a -x $fx
+map ds %dragon-drop -a $fx
+map di %dragon-drop $fx
+map dm %cpdragon
+map dc %mvdragon
+map dl %dlfile
+
+source ~/.config/lf/shortcutrc
diff --git a/.config/lf/luke/scope b/.config/lf/luke/scope
new file mode 100644
index 0000000..cc55669
--- /dev/null
+++ b/.config/lf/luke/scope
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# File preview handler for lf.
+
+set -C -f
+IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}"
+
+image() {
+ if [ -f "$1" ] && [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && command -V ueberzug >/dev/null 2>&1; then
+ printf '{"action": "add", "identifier": "PREVIEW", "x": "%s", "y": "%s", "width": "%s", "height": "%s", "scaler": "contain", "path": "%s"}\n' "$4" "$5" "$(($2-1))" "$(($3-1))" "$1" > "$FIFO_UEBERZUG"
+ else
+ mediainfo "$6"
+ fi
+}
+
+ifub() {
+ [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && command -V ueberzug >/dev/null 2>&1
+}
+
+# Note that the cache file name is a function of file information, meaning if
+# an image appears in multiple places across the machine, it will not have to
+# be regenerated once seen.
+
+case "$(file --dereference --brief --mime-type -- "$1")" in
+ image/avif) CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)"
+ [ ! -f "$CACHE" ] && convert "$1" "$CACHE.jpg"
+ image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" ;;
+ image/vnd.djvu)
+ CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)"
+ [ ! -f "$CACHE" ] && djvused "$1" -e 'select 1; save-page-with /dev/stdout' | convert -density 200 - "$CACHE.jpg" > /dev/null 2>&1
+ image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" ;;
+ image/*) image "$1" "$2" "$3" "$4" "$5" "$1" ;;
+ text/html) lynx -width="$4" -display_charset=utf-8 -dump "$1" ;;
+ text/troff) man ./ "$1" | col -b ;;
+ text/* | */xml | application/json | application/x-ndjson) bat --terminal-width "$(($4-2))" -f "$1" ;;
+ audio/* | application/octet-stream) mediainfo "$1" || exit 1 ;;
+ video/* )
+ CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)"
+ [ ! -f "$CACHE" ] && ffmpegthumbnailer -i "$1" -o "$CACHE" -s 0
+ image "$CACHE" "$2" "$3" "$4" "$5" "$1"
+ ;;
+ */pdf)
+ CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)"
+ [ ! -f "$CACHE.jpg" ] && pdftoppm -jpeg -f 1 -singlefile "$1" "$CACHE"
+ image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1"
+ ;;
+ */epub+zip|*/mobi*)
+ CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)"
+ [ ! -f "$CACHE.jpg" ] && gnome-epub-thumbnailer "$1" "$CACHE.jpg"
+ image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1"
+ ;;
+ application/*zip) atool --list -- "$1" ;;
+ *opendocument*) odt2txt "$1" ;;
+ application/pgp-encrypted) gpg -d -- "$1" ;;
+esac
+exit 1
diff --git a/.config/lf/preview b/.config/lf/preview
new file mode 100644
index 0000000..3069a06
--- /dev/null
+++ b/.config/lf/preview
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# Clear the last preview (if any)
+$HOME/.config/lf/image clear
+
+# Calculate where the image should be placed on the screen.
+num=$(printf "%0.f\n" "`echo "$(tput cols) / 2" | bc`")
+numb=$(printf "%0.f\n" "`echo "$(tput cols) - $num - 1" | bc`")
+numc=$(printf "%0.f\n" "`echo "$(tput lines) - 2" | bc`")
+
+case "$1" in
+ *.tgz|*.tar.gz) tar tzf "$1";;
+ *.tar.bz2|*.tbz2) tar tjf "$1";;
+ *.tar.txz|*.txz) xz --list "$1";;
+ *.tar) tar tf "$1";;
+ *.zip|*.jar|*.war|*.ear|*.oxt) unzip -l "$1";;
+ *.rar) unrar l "$1";;
+ *.7z) 7z l "$1";;
+ *.[1-8]) man "$1" | col -b ;;
+ *.o) nm "$1" | less ;;
+ *.torrent) transmission-show "$1";;
+ *.iso) iso-info --no-header -l "$1";;
+ *odt,*.ods,*.odp,*.sxw) odt2txt "$1";;
+ *.doc) catdoc "$1" ;;
+ *.docx) docx2txt "$1" - ;;
+ *.csv) cat "$1" | sed s/,/\\n/g ;;
+ *.pdf)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ pdftoppm -png -f 1 -singlefile "$1" "$CACHE"
+ $HOME/.config/lf/image draw "$CACHE.png" $num 1 $numb $numc
+ ;;
+ *.epub)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ epub-thumbnailer "$1" "$CACHE" 1024
+ $HOME/.config/lf/image draw "$CACHE" $num 1 $numb $numc
+ ;;
+ *.bmp|*.jpg|*.jpeg|*.png|*.xpm)
+ $HOME/.config/lf/image draw "$1" $num 1 $numb $numc
+ ;;
+ *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.flac) exiftool "$1";;
+ *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx)
+ CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+ ffmpegthumbnailer -i "$1" -o "$CACHE" -s 0
+ $HOME/.config/lf/image draw "$CACHE" $num 1 $numb $numc
+ ;;
+ *) highlight --out-format ansi "$1" || cat "$1";;
+esac
+
diff --git a/.config/lxsession/i3/desktop.conf b/.config/lxsession/i3/desktop.conf
new file mode 100644
index 0000000..175a374
--- /dev/null
+++ b/.config/lxsession/i3/desktop.conf
@@ -0,0 +1,9 @@
+[Mouse]
+AccFactor=20
+AccThreshold=10
+LeftHanded=0
+
+[Keyboard]
+Delay=500
+Interval=30
+Beep=1
diff --git a/.config/nvim/autoload/airline/themes/onedark.vim b/.config/nvim/autoload/airline/themes/onedark.vim
new file mode 100644
index 0000000..65181dd
--- /dev/null
+++ b/.config/nvim/autoload/airline/themes/onedark.vim
@@ -0,0 +1,130 @@
+" [onedark.vim](https://github.com/joshdick/onedark.vim/)
+
+" This is a [vim-airline](https://github.com/vim-airline/vim-airline) theme for use with
+" the [onedark.vim](https://github.com/joshdick/onedark.vim) colorscheme.
+
+" It is based on vim-airline's ["tomorrow" theme](https://github.com/vim-airline/vim-airline-themes/blob/master/autoload/airline/themes/tomorrow.vim).
+function! airline#themes#onedark#refresh()
+ let s:colors = onedark#GetColors()
+
+ if get(g:, 'onedark_termcolors', 256) == 16
+ let s:term_red = s:colors.red.cterm16
+ let s:term_green = s:colors.green.cterm16
+ let s:term_yellow = s:colors.yellow.cterm16
+ let s:term_blue = s:colors.blue.cterm16
+ let s:term_purple = s:colors.purple.cterm16
+ let s:term_white = s:colors.white.cterm16
+ let s:term_cursor_grey = s:colors.cursor_grey.cterm16
+ let s:term_visual_grey = s:colors.visual_grey.cterm16
+ else
+ let s:term_red = s:colors.red.cterm
+ let s:term_green = s:colors.green.cterm
+ let s:term_yellow = s:colors.yellow.cterm
+ let s:term_blue = s:colors.blue.cterm
+ let s:term_purple = s:colors.purple.cterm
+ let s:term_white = s:colors.white.cterm
+ let s:term_cursor_grey = s:colors.cursor_grey.cterm
+ let s:term_visual_grey = s:colors.visual_grey.cterm
+ endif
+
+ let g:airline#themes#onedark#palette = {}
+
+ let g:airline#themes#onedark#palette.accents = {
+ \ 'red': [ s:colors.red.gui, '', s:term_red, 0 ]
+ \ }
+
+ let s:N1 = [ s:colors.cursor_grey.gui, s:colors.green.gui, s:term_cursor_grey, s:term_green ]
+ let s:N2 = [ s:colors.white.gui, s:colors.visual_grey.gui, s:term_white, s:term_visual_grey ]
+ let s:N3 = [ s:colors.green.gui, s:colors.cursor_grey.gui, s:term_green, s:term_cursor_grey ]
+ let g:airline#themes#onedark#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3)
+
+ let group = airline#themes#get_highlight('vimCommand')
+ let g:airline#themes#onedark#palette.normal_modified = {
+ \ 'airline_c': [ group[0], '', group[2], '', '' ]
+ \ }
+
+ let s:I1 = [ s:colors.cursor_grey.gui, s:colors.blue.gui, s:term_cursor_grey, s:term_blue ]
+ let s:I2 = s:N2
+ let s:I3 = [ s:colors.blue.gui, s:colors.cursor_grey.gui, s:term_blue, '' ]
+ let g:airline#themes#onedark#palette.insert = airline#themes#generate_color_map(s:I1, s:I2, s:I3)
+ let g:airline#themes#onedark#palette.insert_modified = g:airline#themes#onedark#palette.normal_modified
+
+ let s:R1 = [ s:colors.cursor_grey.gui, s:colors.red.gui, s:term_cursor_grey, s:term_red ]
+ let s:R2 = s:N2
+ let s:R3 = [ s:colors.red.gui, s:colors.cursor_grey.gui, s:term_red, '' ]
+ let g:airline#themes#onedark#palette.replace = airline#themes#generate_color_map(s:R1, s:R2, s:R3)
+ let g:airline#themes#onedark#palette.replace_modified = g:airline#themes#onedark#palette.normal_modified
+
+ let s:V1 = [ s:colors.cursor_grey.gui, s:colors.purple.gui, s:term_cursor_grey, s:term_purple ]
+ let s:V2 = s:N2
+ let s:V3 = [ s:colors.purple.gui, s:colors.cursor_grey.gui, s:term_purple, '' ]
+ let g:airline#themes#onedark#palette.visual = airline#themes#generate_color_map(s:V1, s:V2, s:V3)
+ let g:airline#themes#onedark#palette.visual_modified = g:airline#themes#onedark#palette.normal_modified
+
+ let s:IA1 = [ s:colors.cursor_grey.gui, s:colors.white.gui, s:term_cursor_grey, s:term_white ]
+ let s:IA2 = [ s:colors.white.gui, s:colors.visual_grey.gui, s:term_white, s:term_visual_grey ]
+ let s:IA3 = s:N2
+ let g:airline#themes#onedark#palette.inactive = airline#themes#generate_color_map(s:IA1, s:IA2, s:IA3)
+ let g:airline#themes#onedark#palette.inactive_modified = {
+ \ 'airline_c': [ group[0], '', group[2], '', '' ]
+ \ }
+
+ " Warning/Error styling code from vim-airline's ["base16" theme](https://github.com/vim-airline/vim-airline-themes/blob/master/autoload/airline/themes/base16.vim)
+
+ " Warnings
+ let s:WI = [ s:colors.cursor_grey.gui, s:colors.yellow.gui, s:term_cursor_grey, s:term_yellow ]
+ let g:airline#themes#onedark#palette.normal.airline_warning = [
+ \ s:WI[0], s:WI[1], s:WI[2], s:WI[3]
+ \ ]
+
+ let g:airline#themes#onedark#palette.normal_modified.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.insert.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.insert_modified.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.visual.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.visual_modified.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.replace.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ let g:airline#themes#onedark#palette.replace_modified.airline_warning =
+ \ g:airline#themes#onedark#palette.normal.airline_warning
+
+ " Errors
+ let s:ER = [ s:colors.cursor_grey.gui, s:colors.red.gui, s:term_cursor_grey, s:term_red ]
+ let g:airline#themes#onedark#palette.normal.airline_error = [
+ \ s:ER[0], s:ER[1], s:ER[2], s:ER[3]
+ \ ]
+
+ let g:airline#themes#onedark#palette.normal_modified.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.insert.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.insert_modified.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.visual.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.visual_modified.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.replace.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+ let g:airline#themes#onedark#palette.replace_modified.airline_error =
+ \ g:airline#themes#onedark#palette.normal.airline_error
+
+endfunction
+
+call airline#themes#onedark#refresh()
diff --git a/.config/nvim/autoload/lightline/colorscheme/onedark.vim b/.config/nvim/autoload/lightline/colorscheme/onedark.vim
new file mode 100644
index 0000000..d04a501
--- /dev/null
+++ b/.config/nvim/autoload/lightline/colorscheme/onedark.vim
@@ -0,0 +1,58 @@
+" [onedark.vim](https://github.com/joshdick/onedark.vim/)
+
+" This is a [lightline.vim](https://github.com/itchyny/lightline.vim) colorscheme for use with
+" the [onedark.vim](https://github.com/joshdick/onedark.vim) colorscheme.
+
+let s:colors = onedark#GetColors()
+
+if get(g:, 'onedark_termcolors', 256) == 16
+ let s:term_red = s:colors.red.cterm16
+ let s:term_green = s:colors.green.cterm16
+ let s:term_yellow = s:colors.yellow.cterm16
+ let s:term_blue = s:colors.blue.cterm16
+ let s:term_purple = s:colors.purple.cterm16
+ let s:term_white = s:colors.white.cterm16
+ let s:term_cursor_grey = s:colors.cursor_grey.cterm16
+ let s:term_visual_grey = s:colors.visual_grey.cterm16
+else
+ let s:term_red = s:colors.red.cterm
+ let s:term_green = s:colors.green.cterm
+ let s:term_yellow = s:colors.yellow.cterm
+ let s:term_blue = s:colors.blue.cterm
+ let s:term_purple = s:colors.purple.cterm
+ let s:term_white = s:colors.white.cterm
+ let s:term_cursor_grey = s:colors.cursor_grey.cterm
+ let s:term_visual_grey = s:colors.visual_grey.cterm
+endif
+
+let s:red = [ s:colors.red.gui, s:term_red ]
+let s:green = [ s:colors.green.gui, s:term_green ]
+let s:yellow = [ s:colors.yellow.gui, s:term_yellow ]
+let s:blue = [ s:colors.blue.gui, s:term_blue ]
+let s:purple = [ s:colors.purple.gui, s:term_purple ]
+let s:white = [ s:colors.white.gui, s:term_white ]
+let s:cursor_grey = [ s:colors.cursor_grey.gui, s:term_cursor_grey ]
+let s:visual_grey = [ s:colors.visual_grey.gui, s:term_visual_grey ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:cursor_grey, s:green ], [ s:white, s:visual_grey ] ]
+let s:p.normal.right = [ [ s:cursor_grey, s:green ], [ s:white, s:visual_grey ] ]
+let s:p.inactive.left = [ [ s:white, s:visual_grey ], [ s:white, s:visual_grey ] ]
+let s:p.inactive.right = [ [ s:cursor_grey, s:white ], [ s:cursor_grey, s:white ] ]
+let s:p.insert.left = [ [ s:cursor_grey, s:blue ], [ s:white, s:visual_grey ] ]
+let s:p.insert.right = [ [ s:cursor_grey, s:blue ], [ s:white, s:visual_grey ] ]
+let s:p.replace.left = [ [ s:cursor_grey, s:red ], [ s:white, s:visual_grey ] ]
+let s:p.replace.right = [ [ s:cursor_grey, s:red ], [ s:white, s:visual_grey ] ]
+let s:p.visual.left = [ [ s:cursor_grey, s:purple ], [ s:white, s:visual_grey ] ]
+let s:p.visual.right = [ [ s:cursor_grey, s:purple ], [ s:white, s:visual_grey ] ]
+let s:p.normal.middle = [ [ s:white, s:cursor_grey ] ]
+let s:p.inactive.middle = [ [ s:white, s:visual_grey ] ]
+let s:p.tabline.left = [ [ s:white, s:visual_grey ] ]
+let s:p.tabline.tabsel = [ [ s:cursor_grey, s:white ] ]
+let s:p.tabline.middle = [ [ s:white, s:cursor_grey ] ]
+let s:p.tabline.right = [ [ s:white, s:visual_grey ] ]
+let s:p.normal.error = [ [ s:cursor_grey, s:red ] ]
+let s:p.normal.warning = [ [ s:cursor_grey, s:yellow ] ]
+
+let g:lightline#colorscheme#onedark#palette = lightline#colorscheme#flatten(s:p)
+
diff --git a/.config/nvim/autoload/onedark.vim b/.config/nvim/autoload/onedark.vim
new file mode 100644
index 0000000..4630ff4
--- /dev/null
+++ b/.config/nvim/autoload/onedark.vim
@@ -0,0 +1,29 @@
+" [onedark.vim](https://github.com/joshdick/onedark.vim/)
+
+let s:overrides = get(g:, "onedark_color_overrides", {})
+
+let s:colors = {
+ \ "red": get(s:overrides, "red", { "gui": "#E06C75", "cterm": "204", "cterm16": "1" }),
+ \ "dark_red": get(s:overrides, "dark_red", { "gui": "#BE5046", "cterm": "196", "cterm16": "9" }),
+ \ "green": get(s:overrides, "green", { "gui": "#98C379", "cterm": "114", "cterm16": "2" }),
+ \ "yellow": get(s:overrides, "yellow", { "gui": "#E5C07B", "cterm": "180", "cterm16": "3" }),
+ \ "dark_yellow": get(s:overrides, "dark_yellow", { "gui": "#D19A66", "cterm": "173", "cterm16": "11" }),
+ \ "blue": get(s:overrides, "blue", { "gui": "#61AFEF", "cterm": "39", "cterm16": "4" }),
+ \ "purple": get(s:overrides, "purple", { "gui": "#C678DD", "cterm": "170", "cterm16": "5" }),
+ \ "cyan": get(s:overrides, "cyan", { "gui": "#56B6C2", "cterm": "38", "cterm16": "6" }),
+ \ "white": get(s:overrides, "white", { "gui": "#ABB2BF", "cterm": "145", "cterm16": "15" }),
+ \ "black": get(s:overrides, "black", { "gui": "#282C34", "cterm": "235", "cterm16": "0" }),
+ \ "foreground": get(s:overrides, "foreground", { "gui": "#ABB2BF", "cterm": "145", "cterm16": "NONE" }),
+ \ "background": get(s:overrides, "background", { "gui": "#282C34", "cterm": "235", "cterm16": "NONE" }),
+ \ "comment_grey": get(s:overrides, "comment_grey", { "gui": "#5C6370", "cterm": "59", "cterm16": "7" }),
+ \ "gutter_fg_grey": get(s:overrides, "gutter_fg_grey", { "gui": "#4B5263", "cterm": "238", "cterm16": "8" }),
+ \ "cursor_grey": get(s:overrides, "cursor_grey", { "gui": "#2C323C", "cterm": "236", "cterm16": "0" }),
+ \ "visual_grey": get(s:overrides, "visual_grey", { "gui": "#3E4452", "cterm": "237", "cterm16": "8" }),
+ \ "menu_grey": get(s:overrides, "menu_grey", { "gui": "#3E4452", "cterm": "237", "cterm16": "7" }),
+ \ "special_grey": get(s:overrides, "special_grey", { "gui": "#3B4048", "cterm": "238", "cterm16": "7" }),
+ \ "vertsplit": get(s:overrides, "vertsplit", { "gui": "#3E4452", "cterm": "59", "cterm16": "7" }),
+ \}
+
+function! onedark#GetColors()
+ return s:colors
+endfunction
diff --git a/.config/nvim/autoload/plug.vim b/.config/nvim/autoload/plug.vim
new file mode 100644
index 0000000..5c910ca
--- /dev/null
+++ b/.config/nvim/autoload/plug.vim
@@ -0,0 +1,2863 @@
+" vim-plug: Vim plugin manager
+" ============================
+"
+" 1. Download plug.vim and put it in 'autoload' directory
+"
+" # Vim
+" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
+" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
+"
+" # Neovim
+" sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
+" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
+"
+" 2. Add a vim-plug section to your ~/.vimrc (or ~/.config/nvim/init.vim for Neovim)
+"
+" call plug#begin()
+"
+" " List your plugins here
+" Plug 'tpope/vim-sensible'
+"
+" call plug#end()
+"
+" 3. Reload the file or restart Vim, then you can,
+"
+" :PlugInstall to install plugins
+" :PlugUpdate to update plugins
+" :PlugDiff to review the changes from the last update
+" :PlugClean to remove plugins no longer in the list
+"
+" For more information, see https://github.com/junegunn/vim-plug
+"
+"
+" Copyright (c) 2024 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('<sfile>:p'))
+ set shellslash
+else
+ let s:me = resolve(expand('<sfile>: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:is_powershell(shell)
+ return a:shell =~# 'powershell\(\.exe\)\?$' || a:shell =~# 'pwsh\(\.exe\)\?$'
+endfunction
+
+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 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 has('nvim')
+ let home = stdpath('data') . '/plugged'
+ 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#(<args>)
+ if !executable('git')
+ return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
+ endif
+ if has('win32')
+ \ && &shellslash
+ \ && (&shell =~# 'cmd\(\.exe\)\?$' || s:is_powershell(&shell))
+ 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(<bang>0, [<f-args>])
+ command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(<bang>0, [<f-args>])
+ command! -nargs=0 -bar -bang PlugClean call s:clean(<bang>0)
+ command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif
+ command! -nargs=0 -bar PlugStatus call s:status()
+ command! -nargs=0 -bar PlugDiff call s:diff()
+ command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(<bang>0, <f-args>)
+endfunction
+
+function! s:to_a(v)
+ return type(a:v) == s:TYPE.list ? a:v : [a:v]
+endfunction
+
+function! s:to_s(v)
+ return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n"
+endfunction
+
+function! s:glob(from, pattern)
+ return s:lines(globpath(a:from, a:pattern))
+endfunction
+
+function! s:source(from, ...)
+ let found = 0
+ for pattern in a:000
+ for vim in s:glob(a:from, pattern)
+ execute 'source' s:esc(vim)
+ let found = 1
+ endfor
+ endfor
+ return found
+endfunction
+
+function! s:assoc(dict, key, val)
+ let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
+endfunction
+
+function! s:ask(message, ...)
+ call inputsave()
+ echohl WarningMsg
+ let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
+ echohl None
+ call inputrestore()
+ echo "\r"
+ return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
+endfunction
+
+function! s:ask_no_interrupt(...)
+ try
+ return call('s:ask', a:000)
+ catch
+ return 0
+ endtry
+endfunction
+
+function! 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 get(g:, 'did_load_filetypes', 0)
+ 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 =~? '^<Plug>.\+'
+ if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i'))
+ call s:assoc(lod.map, cmd, name)
+ endif
+ call add(s:triggers[name].map, cmd)
+ elseif cmd =~# '^[A-Z]'
+ let cmd = substitute(cmd, '!*$', '', '')
+ if exists(':'.cmd) != 2
+ call s:assoc(lod.cmd, cmd, name)
+ endif
+ call add(s:triggers[name].cmd, cmd)
+ else
+ call s:err('Invalid `on` option: '.cmd.
+ \ '. Should start with an uppercase letter or `<Plug>`.')
+ endif
+ endfor
+ endif
+
+ if has_key(plug, 'for')
+ let types = s:to_a(plug.for)
+ if !empty(types)
+ augroup filetypedetect
+ call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim')
+ if has('nvim-0.5.0')
+ call s:source(s:rtp(plug), 'ftdetect/**/*.lua', 'after/ftdetect/**/*.lua')
+ endif
+ augroup END
+ endif
+ for type in types
+ call s:assoc(lod.ft, type, name)
+ endfor
+ endif
+ endfor
+
+ for [cmd, names] in items(lod.cmd)
+ execute printf(
+ \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)',
+ \ cmd, string(cmd), string(names))
+ endfor
+
+ for [map, names] in items(lod.map)
+ for [mode, map_prefix, key_prefix] in
+ \ [['i', '<C-\><C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
+ execute printf(
+ \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>',
+ \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
+ endfor
+ endfor
+
+ for [ft, names] in items(lod.ft)
+ augroup PlugLOD
+ execute printf('autocmd FileType %s call <SID>lod_ft(%s, %s)',
+ \ ft, string(ft), string(names))
+ augroup END
+ endfor
+
+ call s:reorg_rtp()
+ filetype plugin indent on
+ if has('vim_starting')
+ if has('syntax') && !exists('g:syntax_on')
+ syntax enable
+ end
+ else
+ call s:reload_plugins()
+ endif
+endfunction
+
+function! s:loaded_names()
+ return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
+endfunction
+
+function! s:load_plugin(spec)
+ call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
+ if has('nvim-0.5.0')
+ call s:source(s:rtp(a:spec), 'plugin/**/*.lua', 'after/plugin/**/*.lua')
+ endif
+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 s:is_powershell(&shell)
+ 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')) ? '<nomodeline>' : '') join(a:000)
+ endif
+endfunction
+
+function! s:dobufread(names)
+ for name in a:names
+ let path = s:rtp(g:plugs[name])
+ for dir in ['ftdetect', 'ftplugin', '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')
+ if has('nvim-0.5.0') " see neovim#14686
+ call s:source(rtp, dir.'/**/*.lua')
+ endif
+ endfor
+ if a:0
+ if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2))
+ execute 'runtime' a:1
+ endif
+ call s:source(rtp, a:2)
+ endif
+ call s:doautocmd('User', name)
+ endfor
+endfunction
+
+function! s:lod_ft(pat, names)
+ let syn = 'syntax/'.a:pat.'.vim'
+ call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn)
+ execute 'autocmd! PlugLOD FileType' a:pat
+ call s:doautocmd('filetypeplugin', 'FileType')
+ call s:doautocmd('filetypeindent', 'FileType')
+endfunction
+
+function! s:lod_cmd(cmd, bang, l1, l2, args, names)
+ call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
+ call s:dobufread(a:names)
+ execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
+endfunction
+
+function! s:lod_map(map, names, with_prefix, prefix)
+ call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
+ call s:dobufread(a:names)
+ let extra = ''
+ while 1
+ let c = getchar(0)
+ if c == 0
+ break
+ endif
+ let extra .= nr2char(c)
+ endwhile
+
+ if a:with_prefix
+ let prefix = v:count ? v:count : ''
+ let prefix .= '"'.v:register.a:prefix
+ if mode(1) == 'no'
+ if v:operator == 'c'
+ let prefix = "\<esc>" . prefix
+ endif
+ let prefix .= v:operator
+ endif
+ call feedkeys(prefix, 'n')
+ endif
+ call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
+endfunction
+
+function! plug#(repo, ...)
+ if a:0 > 1
+ return s:err('Invalid number of arguments (1..2)')
+ endif
+
+ try
+ let repo = s:trim(a:repo)
+ let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec
+ let name = get(opts, 'as', 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,plugAbort
+ syn match plugNumber /[0-9]\+[0-9.]*/ contained
+ syn match plugBracket /[[\]]/ contained
+ syn match plugX /x/ contained
+ syn match plugAbort /\~/ 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 plugAbort Ignore
+ 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', '-tabnew')
+endfunction
+
+function! s:plug_window_exists()
+ let buflist = tabpagebuflist(s:plug_tab)
+ return !empty(buflist) && index(buflist, s:plug_buf) >= 0
+endfunction
+
+function! s:switch_in()
+ if !s:plug_window_exists()
+ return 0
+ endif
+
+ if winbufnr(0) != s:plug_buf
+ let s:pos = [tabpagenr(), winnr(), winsaveview()]
+ execute 'normal!' s:plug_tab.'gt'
+ let winnr = bufwinnr(s:plug_buf)
+ execute winnr.'wincmd w'
+ call add(s:pos, winsaveview())
+ else
+ let s:pos = [winsaveview()]
+ endif
+
+ setlocal modifiable
+ return 1
+endfunction
+
+function! s:switch_out(...)
+ call winrestview(s:pos[-1])
+ setlocal nomodifiable
+ if a:0 > 0
+ execute a:1
+ endif
+
+ if len(s:pos) > 1
+ execute 'normal!' s:pos[0].'gt'
+ execute s:pos[1] 'wincmd w'
+ call winrestview(s:pos[2])
+ endif
+endfunction
+
+function! s:finish_bindings()
+ nnoremap <silent> <buffer> R :call <SID>retry()<cr>
+ nnoremap <silent> <buffer> D :PlugDiff<cr>
+ nnoremap <silent> <buffer> S :PlugStatus<cr>
+ nnoremap <silent> <buffer> U :call <SID>status_update()<cr>
+ xnoremap <silent> <buffer> U :call <SID>status_update()<cr>
+ nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr>
+ nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr>
+endfunction
+
+function! s:prepare(...)
+ if empty(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(0)
+ if s:switch_in()
+ if b:plug_preview == 1
+ pc
+ endif
+ enew
+ else
+ call s:new_window()
+ endif
+
+ nnoremap <silent> <buffer> q :call <SID>close_pane()<cr>
+ if a:0 == 0
+ call s:finish_bindings()
+ endif
+ let b:plug_preview = -1
+ let s:plug_tab = tabpagenr()
+ let s:plug_buf = winbufnr(0)
+ call s:assign_name()
+
+ for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
+ execute 'silent! unmap <buffer>' k
+ endfor
+ setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell
+ if exists('+colorcolumn')
+ setlocal colorcolumn=
+ endif
+ setf vim-plug
+ if exists('g:syntax_on')
+ call s:syntax()
+ endif
+endfunction
+
+function! s:close_pane()
+ if b:plug_preview == 1
+ pc
+ let b:plug_preview = -1
+ elseif exists('s:jobs') && !empty(s:jobs)
+ call s:job_abort(1)
+ else
+ bd
+ endif
+endfunction
+
+function! s:assign_name()
+ " Assign buffer name
+ let prefix = '[Plugins]'
+ let name = prefix
+ let idx = 2
+ while bufexists(name)
+ let name = printf('%s (%s)', prefix, idx)
+ let idx = idx + 1
+ endwhile
+ silent! execute 'f' fnameescape(name)
+endfunction
+
+function! s:chsh(swap)
+ let prev = [&shell, &shellcmdflag, &shellredir]
+ if !s:is_win
+ set shell=sh
+ endif
+ if a:swap
+ if s:is_powershell(&shell)
+ 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\<cr>\<cr>"
+ 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)
+ if has('nvim')
+ " Reset &rtp to invalidate Neovim cache of loaded Lua modules
+ " See https://github.com/junegunn/vim-plug/pull/1157#issuecomment-1809226110
+ let &rtp = &rtp
+ endif
+ 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)
+ let error = 0
+ 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)
+ let error = v:shell_error
+ endif
+ return [output, error]
+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(deepcopy(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
+
+ " Set remote name, overriding a possible user git config's clone.defaultRemoteName
+ let s:clone_opt = ['--origin', 'origin']
+ 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
+ let out = ''
+ let error = 0
+ if has_key(spec, 'commit')
+ call s:log4(name, 'Checking out '.spec.commit)
+ let [out, error] = 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)
+ let error = v:shell_error
+ endif
+ if !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)
+ let error = v:shell_error
+ endif
+ let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
+ if 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:mark_aborted(name, message)
+ let attrs = { 'running': 0, 'error': 1, 'abort': 1, 'lines': [a:message] }
+ let s:jobs[a:name] = extend(get(s:jobs, a:name, {}), attrs)
+endfunction
+
+function! s:job_abort(cancel)
+ 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
+ if a:cancel
+ call s:mark_aborted(name, 'Aborted')
+ endif
+ endfor
+
+ if a:cancel
+ for todo in values(s:update.todo)
+ let todo.abort = 1
+ endfor
+ else
+ let s:jobs = {}
+ endif
+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:bullet_for(job, ...)
+ if a:job.running
+ return a:job.new ? '+' : '*'
+ endif
+ if get(a:job, 'abort', 0)
+ return '~'
+ endif
+ return a:job.error ? 'x' : get(a:000, 0, '-')
+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 result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
+ if len(result)
+ call s:log(s:bullet_for(self), self.name, result)
+ endif
+ 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(0)
+ 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, spec, queue, opts)
+ let job = { 'name': a:name, 'spec': a:spec, 'running': 1, 'error': 0, 'lines': [''],
+ \ 'new': get(a:opts, 'new', 0), 'queue': copy(a:queue) }
+ let Item = remove(job.queue, 0)
+ let argv = type(Item) == s:TYPE.funcref ? call(Item, [a:spec]) : Item
+ let s:jobs[a:name] = job
+
+ if s:nvim
+ if has_key(a:opts, 'dir')
+ let job.cwd = a:opts.dir
+ endif
+ 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(argv), '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') ? [argv, a:opts.dir] : [argv]))
+ let job.error = v:shell_error != 0
+ let job.running = 0
+ endif
+endfunction
+
+function! s:reap(name)
+ let job = remove(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 more = len(get(job, 'queue', []))
+ let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
+ if len(result)
+ call s:log(s:bullet_for(job), a:name, result)
+ endif
+
+ if !job.error && more
+ let job.spec.queue = job.queue
+ let s:update.todo[a:name] = job.spec
+ else
+ let s:update.bar .= s:bullet_for(job, '=')
+ call s:bar()
+ endif
+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:checkout_command(spec)
+ let a:spec.branch = s:git_origin_branch(a:spec)
+ return ['git', 'checkout', '-q', a:spec.branch, '--']
+endfunction
+
+function! s:merge_command(spec)
+ let a:spec.branch = s:git_origin_branch(a:spec)
+ return ['git', 'merge', '--ff-only', 'origin/'.a:spec.branch]
+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)
+ if get(spec, 'abort', 0)
+ call s:mark_aborted(name, 'Skipped')
+ call s:reap(name)
+ continue
+ endif
+
+ let queue = get(spec, 'queue', [])
+ let new = empty(globpath(spec.dir, '.git', 1))
+
+ if empty(queue)
+ call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
+ redraw
+ endif
+
+ let has_tag = has_key(spec, 'tag')
+ if len(queue)
+ call s:spawn(name, spec, queue, { 'dir': spec.dir })
+ elseif !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
+ let queue = [cmd, split('git remote set-head origin -a')]
+ if !has_tag && !has_key(spec, 'commit')
+ call extend(queue, [function('s:checkout_command'), function('s:merge_command')])
+ endif
+ call s:spawn(name, spec, queue, { '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, spec, [extend(cmd, [spec.uri, s:trim(spec.dir)]), function('s:checkout_command'), function('s:merge_command')], { '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 s:is_powershell(shell)
+ 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
+ let pwsh = s:is_powershell(&shell)
+ let cd = s:is_win && !pwsh ? 'cd /d' : 'cd'
+ let sep = pwsh ? ';' : '&&'
+ return printf('%s %s %s %s', cd, plug#shellescape(a:dir, {'script': script, 'shell': &shell}), sep, 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 s:is_powershell(&shell)
+ 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 || len(ahead_behind) != 2
+ let err = "Failed to compare with the origin. The default branch might have changed.\nPlugClean required."
+ else
+ let [ahead, behind] = ahead_behind
+ if ahead && 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)
+ elseif ahead
+ 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) || get(spec, 'frozen', 0)
+ 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 <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@
+ nmap <silent> <buffer> dd d_
+ xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr>
+ echo 'Delete the lines (d{motion}) to delete the corresponding directories'
+ endif
+ endif
+ 4
+ setlocal nomodifiable
+endfunction
+
+function! s:delete_op(type, ...)
+ call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
+endfunction
+
+function! s:delete(range, force)
+ let [l1, l2] = a:range
+ let force = a:force
+ 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 <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
+ xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
+ end
+endfunction
+
+function! s:extract_name(str, prefix, suffix)
+ return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$')
+endfunction
+
+function! s:status_load(lnum)
+ let line = getline(a:lnum)
+ let name = s:extract_name(line, '-', '(not loaded)')
+ if !empty(name)
+ call plug#load(name)
+ setlocal modifiable
+ call setline(a:lnum, substitute(line, ' (not loaded)$', '', ''))
+ setlocal nomodifiable
+ endif
+endfunction
+
+function! s:status_update() range
+ let lines = getline(a:firstline, a:lastline)
+ let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)')
+ if !empty(names)
+ echo
+ execute 'PlugUpdate' join(names)
+ endif
+endfunction
+
+function! s:is_preview_window_open()
+ silent! wincmd P
+ if &previewwindow
+ wincmd p
+ return 1
+ endif
+endfunction
+
+function! s:find_name(lnum)
+ for lnum in reverse(range(1, a:lnum))
+ let line = getline(lnum)
+ if empty(line)
+ return ''
+ endif
+ let name = s:extract_name(line, '-', '')
+ if !empty(name)
+ return name
+ endif
+ endfor
+ return ''
+endfunction
+
+function! s:preview_commit()
+ if b:plug_preview < 0
+ let b:plug_preview = !s:is_preview_window_open()
+ endif
+
+ let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}')
+ if empty(sha)
+ let name = matchstr(getline('.'), '^- \zs[^:]*\ze:$')
+ if empty(name)
+ return
+ endif
+ let title = 'HEAD@{1}..'
+ let command = 'git diff --no-color HEAD@{1}'
+ else
+ let title = sha
+ let command = 'git show --no-color --pretty=medium '.sha
+ let name = s:find_name(line('.'))
+ endif
+
+ if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir)
+ return
+ endif
+
+ if !s:is_preview_window_open()
+ execute get(g:, 'plug_pwindow', 'vertical rightbelow new')
+ execute 'e' title
+ else
+ execute 'pedit' title
+ wincmd P
+ endif
+ setlocal previewwindow filetype=git buftype=nofile bufhidden=wipe nobuflisted modifiable
+ let batchfile = ''
+ try
+ let [sh, shellcmdflag, shrd] = s:chsh(1)
+ let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && '.command
+ 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 <silent> <buffer> q :q<cr>
+ wincmd p
+endfunction
+
+function! s:section(flags)
+ call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
+endfunction
+
+function! s:format_git_log(line)
+ let indent = ' '
+ let tokens = split(a:line, nr2char(1))
+ if len(tokens) != 5
+ return indent.substitute(a:line, '\s*$', '', '')
+ endif
+ let [graph, sha, refs, subject, date] = tokens
+ let tag = matchstr(refs, 'tag: [^,)]\+')
+ let tag = empty(tag) ? ' ' : ' ('.tag.') '
+ return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date)
+endfunction
+
+function! s:append_ul(lnum, text)
+ call append(a:lnum, ['', a:text, repeat('-', len(a:text))])
+endfunction
+
+function! s:diff()
+ call s:prepare()
+ call append(0, ['Collecting changes ...', ''])
+ let cnts = [0, 0]
+ let bar = ''
+ let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)')
+ call s:progress_bar(2, bar, len(total))
+ for origin in [1, 0]
+ let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))'))))
+ if empty(plugs)
+ continue
+ endif
+ call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
+ for [k, v] in plugs
+ let 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 <silent> <buffer> <plug>(plug-preview) :silent! call <SID>preview_commit()<cr>
+ if empty(maparg("\<cr>", 'n'))
+ nmap <buffer> <cr> <plug>(plug-preview)
+ endif
+ if empty(maparg('o', 'n'))
+ nmap <buffer> o <plug>(plug-preview)
+ endif
+ endif
+ if cnts[0]
+ nnoremap <silent> <buffer> X :call <SID>revert()<cr>
+ echo "Press 'X' on each block to revert the update"
+ endif
+ normal! gg
+ setlocal nomodifiable
+endfunction
+
+function! s:revert()
+ if search('^Pending updates', 'bnW')
+ return
+ endif
+
+ let name = s:find_name(line('.'))
+ if empty(name) || !has_key(g:plugs, name) ||
+ \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'
+ return
+ endif
+
+ call s:system('git reset --hard HEAD@{1} && git checkout '.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") && isdirectory(v:val.dir)')))
+ for name in reverse(names)
+ let sha = has_key(g:plugs[name], 'commit') ? g:plugs[name].commit : 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, '\\\@<!,')
+endfunction
+
+let s:first_rtp = s:escrtp(get(s:split_rtp(), 0, ''))
+let s:last_rtp = s:escrtp(get(s:split_rtp(), -1, ''))
+
+if exists('g:plugs')
+ let g:plugs_order = get(g:, 'plugs_order', keys(g:plugs))
+ call s:upgrade_specs()
+ call s:define_commands()
+endif
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/.config/nvim/autoload/scratch.vim b/.config/nvim/autoload/scratch.vim
new file mode 100644
index 0000000..0a06cdc
--- /dev/null
+++ b/.config/nvim/autoload/scratch.vim
@@ -0,0 +1,49 @@
+" Source: https://gist.github.com/romainl/eae0a260ab9c135390c30cd370c20cd7
+function! scratch#open(cmd, mods) abort
+ for win in filter(range(1, winnr('$')), 'getwinvar(v:val, "scratch")')
+ execute win . 'windo close'
+ endfor
+ if a:cmd =~# '^!'
+ let cmd = a:cmd =~# ' %' ? substitute(a:cmd, ' %', ' ' . expand('%:p'), '') : a:cmd
+ let output = systemlist(matchstr(cmd, '^!\zs.*'))
+ elseif a:cmd =~# '^@'
+ let output = getreg(a:cmd[1], 1, 1)
+ else
+ let output = split(execute(a:cmd), "\n")
+ endif
+ execute a:mods . ' new'
+ let w:scratch = 1
+ call setline(1, output)
+ nnoremap <buffer> q <C-W>q
+ setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nomodifiable
+ call s:highlight(a:cmd)
+
+ augroup scratch
+ autocmd BufEnter <buffer> ++nested if winnr('$') < 2 | q | endif
+ augroup END
+endfunction
+
+" Highlight scratch buffer to match native command output for certain commands
+function! s:highlight(cmd) abort
+ let firstline = getline(1)
+ if firstline =~# '^--- Registers ---\|Type Name Content$'
+ call matchaddpos('Title', [1])
+ call matchadd('SpecialKey', '\^\S\|<[^>]\{2}>')
+ elseif firstline =~# '^\%(mark\|change\| jump\) line col \%(file/\)\?text$'
+ call matchaddpos('Title', [1])
+ elseif firstline =~# '^\w\+\s\+xxx \%(links\|cleared\|cterm\|gui\|term\)'
+ syntax match Keyword /\v%(c?term%([fb]g)?|gui%([fb]g)?)\=/
+ syntax keyword Keyword links to
+ for linenr in range(1, line('$'))
+ let line = getline(linenr)
+ let syn = matchstr(line, '^\w\+')
+ let col = match(line, '\<xxx\>')
+ call matchaddpos(syn, [[linenr, col + 1, 3]])
+ endfor
+ elseif search('\v^(E[0-9]+:|line\s+[0-9]+:)', 'cnW')
+ call matchadd('ErrorMsg', '^E[0-9]\+: .\+$')
+ call matchadd('LineNr', '^line\s\+[0-9]\+:$')
+ elseif a:cmd =~# '^dig'
+ call matchadd('SpecialKey', '[A-Za-z0-9[:graph:]]\{2}\s\+\zs\S\+\ze\s\+\d\+')
+ endif
+endfunction
diff --git a/.config/nvim/coc/coc-onload.vim b/.config/nvim/coc/coc-onload.vim
new file mode 100644
index 0000000..c2835cc
--- /dev/null
+++ b/.config/nvim/coc/coc-onload.vim
@@ -0,0 +1,144 @@
+
+" May need for Vim (not Neovim) since coc.nvim calculates byte offset by count
+" utf-8 byte sequence
+set encoding=utf-8
+" Some servers have issues with backup files, see #649
+set nobackup
+set nowritebackup
+
+" Having longer updatetime (default is 4000 ms = 4s) leads to noticeable
+" delays and poor user experience
+set updatetime=1000
+
+" Always show the signcolumn, otherwise it would shift the text each time
+" diagnostics appear/become resolved
+set signcolumn=yes
+
+" Use tab for trigger completion with characters ahead and navigate
+" NOTE: There's always complete item selected by default, you may want to enable
+" no select by `"suggest.noselect": true` in your configuration file
+" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
+" other plugin before putting this into your config
+ inoremap <silent><expr> <TAB>
+ \ coc#pum#visible() ? coc#pum#next(1) :
+ \ CheckBackspace() ? "\<Tab>" :
+ \ coc#refresh()
+ inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"
+
+" Make <CR> to accept selected completion item or notify coc.nvim to format
+" <C-g>u breaks current undo, please make your own choice
+inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
+ \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
+
+function! CheckBackspace() abort
+ let col = col('.') - 1
+ return !col || getline('.')[col - 1] =~# '\s'
+endfunction
+
+" Use <c-space> to trigger completion
+if has('nvim')
+ inoremap <silent><expr> <c-space> coc#refresh()
+else
+ inoremap <silent><expr> <c-@> coc#refresh()
+endif
+
+" Use `[g` and `]g` to navigate diagnostics
+" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list
+nmap <silent> [g <Plug>(coc-diagnostic-prev)
+nmap <silent> ]g <Plug>(coc-diagnostic-next)
+
+" GoTo code navigation
+nmap <silent> gd <Plug>(coc-definition)
+nmap <silent> gy <Plug>(coc-type-definition)
+nmap <silent> gi <Plug>(coc-implementation)
+nmap <silent> gr <Plug>(coc-references)
+
+" Use K to show documentation in preview window
+nnoremap <silent> <C-k> :call ShowDocumentation()<CR>
+
+function! ShowDocumentation()
+ if CocAction('hasProvider', 'hover')
+ call CocActionAsync('doHover')
+ else
+ call feedkeys('K', 'in')
+ endif
+endfunction
+
+" Highlight the symbol and its references when holding the cursor
+autocmd CursorHold * silent call CocActionAsync('highlight')
+
+" Symbol renaming
+nmap <leader>rn <Plug>(coc-rename)
+
+" Formatting selected code
+xmap <leader>cf <Plug>(coc-format-selected)
+nmap <leader>cf <Plug>(coc-format-selected)
+
+augroup mygroup
+ autocmd!
+ " Setup formatexpr specified filetype(s)
+ autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
+ " Update signature help on jump placeholder
+ autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
+augroup end
+
+" Applying code actions to the selected code block
+" Example: `<leader>aap` for current paragraph
+xmap <leader>aa <Plug>(coc-codeaction-selected)
+nmap <leader>aa <Plug>(coc-codeaction-selected)
+
+" Remap keys for applying code actions at the cursor position
+nmap <leader>ac <Plug>(coc-codeaction-cursor)
+" Remap keys for apply code actions affect whole buffer
+nmap <leader>as <Plug>(coc-codeaction-source)
+" Apply the most preferred quickfix action to fix diagnostic on the current line
+nmap <leader>aq <Plug>(coc-fix-current)
+
+" Remap keys for applying refactor code actions
+nmap <silent> <leader>re <Plug>(coc-codeaction-refactor)
+xmap <silent> <leader>r <Plug>(coc-codeaction-refactor-selected)
+nmap <silent> <leader>r <Plug>(coc-codeaction-refactor-selected)
+
+" Run the Code Lens action on the current line
+nmap <leader>cl <Plug>(coc-codelens-action)
+
+" Map function and class text objects
+" NOTE: Requires 'textDocument.documentSymbol' support from the language server
+xmap if <Plug>(coc-funcobj-i)
+omap if <Plug>(coc-funcobj-i)
+xmap af <Plug>(coc-funcobj-a)
+omap af <Plug>(coc-funcobj-a)
+xmap ic <Plug>(coc-classobj-i)
+omap ic <Plug>(coc-classobj-i)
+xmap ac <Plug>(coc-classobj-a)
+omap ac <Plug>(coc-classobj-a)
+
+" Remap <C-f> and <C-b> to scroll float windows/popups
+if has('nvim-0.4.0') || has('patch-8.2.0750')
+ nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
+ nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
+ inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
+ inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
+ vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
+ vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
+endif
+
+" Use CTRL-S for selections ranges
+" Requires 'textDocument/selectionRange' support of language server
+nmap <silent> <C-s> <Plug>(coc-range-select)
+xmap <silent> <C-s> <Plug>(coc-range-select)
+
+" Add `:Format` command to format current buffer
+command! -nargs=0 Format :call CocActionAsync('format')
+
+" Add `:Fold` command to fold current buffer
+command! -nargs=? Fold :call CocAction('fold', <f-args>)
+
+" Add `:OR` command for organize imports of the current buffer
+command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport')
+
+" Add (Neo)Vim's native statusline support
+" NOTE: Please see `:h coc-status` for integrations with external plugins that
+" provide custom statusline: lightline.vim, vim-airline
+set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
+
diff --git a/.config/nvim/coc/coc-settings.json b/.config/nvim/coc/coc-settings.json
new file mode 100644
index 0000000..f90bc38
--- /dev/null
+++ b/.config/nvim/coc/coc-settings.json
@@ -0,0 +1,6 @@
+{
+ "suggest.autoTrigger": "always",
+ "diagnostic.enable": true,
+ "python.linting.pycodestyleEnabled": true,
+ "html.autoCreateQuotes": false
+}
diff --git a/.config/nvim/colors/onedark.vim b/.config/nvim/colors/onedark.vim
new file mode 100644
index 0000000..6769d6c
--- /dev/null
+++ b/.config/nvim/colors/onedark.vim
@@ -0,0 +1,713 @@
+" vim:fdm=marker
+" Vim Color File
+" Name: onedark.vim
+" Maintainer: https://github.com/joshdick/onedark.vim/
+" License: The MIT License (MIT)
+" Based On: https://github.com/MaxSt/FlatColor/
+
+" Companion statusline plugin and terminal themes are included with onedark.vim:
+" * https://github.com/joshdick/onedark.vim#lightlinevim-colorscheme
+" * https://github.com/joshdick/onedark.vim#vim-airline-theme
+" * https://github.com/joshdick/onedark.vim/tree/main/term
+
+" Color Reference {{{
+
+" The following colors were measured inside Atom using its built-in inspector.
+
+" +---------------------------------------------+
+" | Color Name | RGB | Hex |
+" |--------------+--------------------+---------|
+" | Black | rgb(40, 44, 52) | #282c34 |
+" |--------------+--------------------+---------|
+" | White | rgb(171, 178, 191) | #abb2bf |
+" |--------------+--------------------+---------|
+" | Light Red | rgb(224, 108, 117) | #e06c75 |
+" |--------------+--------------------+---------|
+" | Dark Red | rgb(190, 80, 70) | #be5046 |
+" |--------------+--------------------+---------|
+" | Green | rgb(152, 195, 121) | #98c379 |
+" |--------------+--------------------+---------|
+" | Light Yellow | rgb(229, 192, 123) | #e5c07b |
+" |--------------+--------------------+---------|
+" | Dark Yellow | rgb(209, 154, 102) | #d19a66 |
+" |--------------+--------------------+---------|
+" | Blue | rgb(97, 175, 239) | #61afef |
+" |--------------+--------------------+---------|
+" | Magenta | rgb(198, 120, 221) | #c678dd |
+" |--------------+--------------------+---------|
+" | Cyan | rgb(86, 182, 194) | #56b6c2 |
+" |--------------+--------------------+---------|
+" | Gutter Grey | rgb(76, 82, 99) | #4b5263 |
+" |--------------+--------------------+---------|
+" | Comment Grey | rgb(92, 99, 112) | #5c6370 |
+" +---------------------------------------------+
+
+" }}}
+
+" Initialization {{{
+
+highlight clear
+
+if exists("syntax_on")
+ syntax reset
+endif
+
+set t_Co=256
+
+let g:colors_name="onedark"
+
+" Set to "256" for 256-color terminals, or
+" set to "16" to use your terminal emulator's native colors
+" (a 16-color palette for this color scheme is available; see
+" < https://github.com/joshdick/onedark.vim/blob/main/README.md >
+" for more information.)
+if !exists("g:onedark_termcolors")
+ let g:onedark_termcolors = 256
+endif
+
+" Not all terminals support italics properly. If yours does, opt-in.
+if !exists("g:onedark_terminal_italics")
+ let g:onedark_terminal_italics = 0
+endif
+
+" This function is based on one from FlatColor: https://github.com/MaxSt/FlatColor/
+" Which in turn was based on one found in hemisu: https://github.com/noahfrederick/vim-hemisu/
+let s:group_colors = {} " Cache of default highlight group settings, for later reference via `onedark#extend_highlight`
+function! s:h(group, style, ...)
+ if (a:0 > 0) " Will be true if we got here from onedark#extend_highlight
+ let s:highlight = s:group_colors[a:group]
+ for style_type in ["fg", "bg", "sp"]
+ if (has_key(a:style, style_type))
+ let l:default_style = (has_key(s:highlight, style_type) ? copy(s:highlight[style_type]) : { "cterm16": "NONE", "cterm": "NONE", "gui": "NONE" })
+ let s:highlight[style_type] = extend(l:default_style, a:style[style_type])
+ endif
+ endfor
+ if (has_key(a:style, "gui"))
+ let s:highlight.gui = a:style.gui
+ endif
+ if (has_key(a:style, "cterm"))
+ let s:highlight.cterm = a:style.cterm
+ endif
+ else
+ let s:highlight = a:style
+ let s:group_colors[a:group] = s:highlight " Cache default highlight group settings
+ endif
+
+ if g:onedark_terminal_italics == 0
+ if has_key(s:highlight, "cterm") && s:highlight["cterm"] == "italic"
+ unlet s:highlight.cterm
+ endif
+ if has_key(s:highlight, "gui") && s:highlight["gui"] == "italic"
+ unlet s:highlight.gui
+ endif
+ endif
+
+ if g:onedark_termcolors == 16
+ let l:ctermfg = (has_key(s:highlight, "fg") ? s:highlight.fg.cterm16 : "NONE")
+ let l:ctermbg = (has_key(s:highlight, "bg") ? s:highlight.bg.cterm16 : "NONE")
+ else
+ let l:ctermfg = (has_key(s:highlight, "fg") ? s:highlight.fg.cterm : "NONE")
+ let l:ctermbg = (has_key(s:highlight, "bg") ? s:highlight.bg.cterm : "NONE")
+ endif
+
+ execute "highlight" a:group
+ \ "guifg=" (has_key(s:highlight, "fg") ? s:highlight.fg.gui : "NONE")
+ \ "guibg=" (has_key(s:highlight, "bg") ? s:highlight.bg.gui : "NONE")
+ \ "guisp=" (has_key(s:highlight, "sp") ? s:highlight.sp.gui : "NONE")
+ \ "gui=" (has_key(s:highlight, "gui") ? s:highlight.gui : "NONE")
+ \ "ctermfg=" . l:ctermfg
+ \ "ctermbg=" . l:ctermbg
+ \ "cterm=" (has_key(s:highlight, "cterm") ? s:highlight.cterm : "NONE")
+endfunction
+
+" public {{{
+
+function! onedark#set_highlight(group, style)
+ call s:h(a:group, a:style)
+endfunction
+
+function! onedark#extend_highlight(group, style)
+ call s:h(a:group, a:style, 1)
+endfunction
+
+" }}}
+
+" }}}
+
+" Color Variables {{{
+
+let s:colors = onedark#GetColors()
+
+let s:red = s:colors.red
+let s:dark_red = s:colors.dark_red
+let s:green = s:colors.green
+let s:yellow = s:colors.yellow
+let s:dark_yellow = s:colors.dark_yellow
+let s:blue = s:colors.blue
+let s:purple = s:colors.purple
+let s:cyan = s:colors.cyan
+let s:white = s:colors.white
+let s:black = s:colors.black
+let s:foreground = s:colors.foreground
+let s:background = s:colors.background
+let s:comment_grey = s:colors.comment_grey
+let s:gutter_fg_grey = s:colors.gutter_fg_grey
+let s:cursor_grey = s:colors.cursor_grey
+let s:visual_grey = s:colors.visual_grey
+let s:menu_grey = s:colors.menu_grey
+let s:special_grey = s:colors.special_grey
+let s:vertsplit = s:colors.vertsplit
+
+" }}}
+
+" Terminal Colors {{{
+
+if has('nvim')
+ let g:terminal_color_0 = s:black.gui
+ let g:terminal_color_1 = s:red.gui
+ let g:terminal_color_2 = s:green.gui
+ let g:terminal_color_3 = s:yellow.gui
+ let g:terminal_color_4 = s:blue.gui
+ let g:terminal_color_5 = s:purple.gui
+ let g:terminal_color_6 = s:cyan.gui
+ let g:terminal_color_7 = s:comment_grey.gui
+ let g:terminal_color_8 = s:visual_grey.gui
+ let g:terminal_color_9 = s:red.gui
+ let g:terminal_color_10 = s:green.gui
+ let g:terminal_color_11 = s:yellow.gui
+ let g:terminal_color_12 = s:blue.gui
+ let g:terminal_color_13 = s:purple.gui
+ let g:terminal_color_14 = s:cyan.gui
+ let g:terminal_color_15 = s:white.gui
+else
+ let g:terminal_ansi_colors = [
+ \ s:black.gui, s:red.gui, s:green.gui, s:yellow.gui,
+ \ s:blue.gui, s:purple.gui, s:cyan.gui, s:comment_grey.gui,
+ \ s:visual_grey.gui, s:red.gui, s:green.gui, s:yellow.gui,
+ \ s:blue.gui, s:purple.gui, s:cyan.gui, s:white.gui
+ \]
+endif
+
+" }}}
+
+" Syntax Groups (descriptions and ordering from `:h w18`) {{{
+
+call s:h("Comment", { "fg": s:comment_grey, "gui": "italic", "cterm": "italic" }) " any comment
+call s:h("Constant", { "fg": s:cyan }) " any constant
+call s:h("String", { "fg": s:green }) " a string constant: "this is a string"
+call s:h("Character", { "fg": s:green }) " a character constant: 'c', '\n'
+call s:h("Number", { "fg": s:dark_yellow }) " a number constant: 234, 0xff
+call s:h("Boolean", { "fg": s:dark_yellow }) " a boolean constant: TRUE, false
+call s:h("Float", { "fg": s:dark_yellow }) " a floating point constant: 2.3e10
+call s:h("Identifier", { "fg": s:red }) " any variable name
+call s:h("Function", { "fg": s:blue }) " function name (also: methods for classes)
+call s:h("Statement", { "fg": s:purple }) " any statement
+call s:h("Conditional", { "fg": s:purple }) " if, then, else, endif, switch, etc.
+call s:h("Repeat", { "fg": s:purple }) " for, do, while, etc.
+call s:h("Label", { "fg": s:purple }) " case, default, etc.
+call s:h("Operator", { "fg": s:purple }) " sizeof", "+", "*", etc.
+call s:h("Keyword", { "fg": s:purple }) " any other keyword
+call s:h("Exception", { "fg": s:purple }) " try, catch, throw
+call s:h("PreProc", { "fg": s:yellow }) " generic Preprocessor
+call s:h("Include", { "fg": s:blue }) " preprocessor #include
+call s:h("Define", { "fg": s:purple }) " preprocessor #define
+call s:h("Macro", { "fg": s:purple }) " same as Define
+call s:h("PreCondit", { "fg": s:yellow }) " preprocessor #if, #else, #endif, etc.
+call s:h("Type", { "fg": s:yellow }) " int, long, char, etc.
+call s:h("StorageClass", { "fg": s:yellow }) " static, register, volatile, etc.
+call s:h("Structure", { "fg": s:yellow }) " struct, union, enum, etc.
+call s:h("Typedef", { "fg": s:yellow }) " A typedef
+call s:h("Special", { "fg": s:blue }) " any special symbol
+call s:h("SpecialChar", { "fg": s:dark_yellow }) " special character in a constant
+call s:h("Tag", {}) " you can use CTRL-] on this
+call s:h("Delimiter", {}) " character that needs attention
+call s:h("SpecialComment", { "fg": s:comment_grey }) " special things inside a comment
+call s:h("Debug", {}) " debugging statements
+call s:h("Underlined", { "gui": "underline", "cterm": "underline" }) " text that stands out, HTML links
+call s:h("Ignore", {}) " left blank, hidden
+call s:h("Error", { "fg": s:red }) " any erroneous construct
+call s:h("Todo", { "fg": s:purple }) " anything that needs extra attention; mostly the keywords TODO FIXME and XXX
+
+" }}}
+
+" Highlighting Groups (descriptions and ordering from `:h highlight-groups`) {{{
+call s:h("ColorColumn", { "bg": s:cursor_grey }) " used for the columns set with 'colorcolumn'
+call s:h("Conceal", {}) " placeholder characters substituted for concealed text (see 'conceallevel')
+call s:h("Cursor", { "fg": s:black, "bg": s:blue }) " the character under the cursor
+call s:h("CursorIM", {}) " like Cursor, but used when in IME mode
+call s:h("CursorColumn", { "bg": s:cursor_grey }) " the screen column that the cursor is in when 'cursorcolumn' is set
+if &diff
+ " Don't change the background color in diff mode
+ call s:h("CursorLine", { "gui": "underline" }) " the screen line that the cursor is in when 'cursorline' is set
+else
+ call s:h("CursorLine", { "bg": s:cursor_grey }) " the screen line that the cursor is in when 'cursorline' is set
+endif
+call s:h("Directory", { "fg": s:blue }) " directory names (and other special names in listings)
+call s:h("DiffAdd", { "bg": s:green, "fg": s:black }) " diff mode: Added line
+call s:h("DiffChange", { "fg": s:yellow, "gui": "underline", "cterm": "underline" }) " diff mode: Changed line
+call s:h("DiffDelete", { "bg": s:red, "fg": s:black }) " diff mode: Deleted line
+call s:h("DiffText", { "bg": s:yellow, "fg": s:black }) " diff mode: Changed text within a changed line
+if get(g:, 'onedark_hide_endofbuffer', 0)
+ " If enabled, will style end-of-buffer filler lines (~) to appear to be hidden.
+ call s:h("EndOfBuffer", { "fg": s:black }) " filler lines (~) after the last line in the buffer
+endif
+call s:h("ErrorMsg", { "fg": s:red }) " error messages on the command line
+call s:h("VertSplit", { "fg": s:vertsplit }) " the column separating vertically split windows
+call s:h("Folded", { "fg": s:comment_grey }) " line used for closed folds
+call s:h("FoldColumn", {}) " 'foldcolumn'
+call s:h("SignColumn", {}) " column where signs are displayed
+call s:h("IncSearch", { "fg": s:yellow, "bg": s:comment_grey }) " 'incsearch' highlighting; also used for the text replaced with ":s///c"
+call s:h("LineNr", { "fg": s:gutter_fg_grey }) " Line number for ":number" and ":#" commands, and when 'number' or 'relativenumber' option is set.
+call s:h("CursorLineNr", {}) " Like LineNr when 'cursorline' or 'relativenumber' is set for the cursor line.
+call s:h("MatchParen", { "fg": s:blue, "gui": "underline", "cterm": "underline" }) " The character under the cursor or just before it, if it is a paired bracket, and its match.
+call s:h("ModeMsg", {}) " 'showmode' message (e.g., "-- INSERT --")
+call s:h("MoreMsg", {}) " more-prompt
+call s:h("NonText", { "fg": s:special_grey }) " '~' and '@' at the end of the window, characters from 'showbreak' and other characters that do not really exist in the text (e.g., ">" displayed when a double-wide character doesn't fit at the end of the line).
+call s:h("Normal", { "fg": s:foreground, "bg": s:background }) " normal text
+call s:h("Pmenu", { "fg": s:white, "bg": s:menu_grey }) " Popup menu: normal item.
+call s:h("PmenuSel", { "fg": s:cursor_grey, "bg": s:blue }) " Popup menu: selected item.
+call s:h("PmenuSbar", { "bg": s:cursor_grey }) " Popup menu: scrollbar.
+call s:h("PmenuThumb", { "bg": s:white }) " Popup menu: Thumb of the scrollbar.
+call s:h("Question", { "fg": s:purple }) " hit-enter prompt and yes/no questions
+call s:h("QuickFixLine", { "fg": s:black, "bg": s:yellow }) " Current quickfix item in the quickfix window.
+call s:h("Search", { "fg": s:black, "bg": s:yellow }) " Last search pattern highlighting (see 'hlsearch'). Also used for similar items that need to stand out.
+call s:h("SpecialKey", { "fg": s:special_grey }) " Meta and special keys listed with ":map", also for text used to show unprintable characters in the text, 'listchars'. Generally: text that is displayed differently from what it really is.
+call s:h("SpellBad", { "fg": s:red, "gui": "underline", "cterm": "underline" }) " Word that is not recognized by the spellchecker. This will be combined with the highlighting used otherwise.
+call s:h("SpellCap", { "fg": s:dark_yellow }) " Word that should start with a capital. This will be combined with the highlighting used otherwise.
+call s:h("SpellLocal", { "fg": s:dark_yellow }) " Word that is recognized by the spellchecker as one that is used in another region. This will be combined with the highlighting used otherwise.
+call s:h("SpellRare", { "fg": s:dark_yellow }) " Word that is recognized by the spellchecker as one that is hardly ever used. spell This will be combined with the highlighting used otherwise.
+call s:h("StatusLine", { "fg": s:white, "bg": s:cursor_grey }) " status line of current window
+call s:h("StatusLineNC", { "fg": s:comment_grey }) " status lines of not-current windows Note: if this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window.
+call s:h("StatusLineTerm", { "fg": s:white, "bg": s:cursor_grey }) " status line of current :terminal window
+call s:h("StatusLineTermNC", { "fg": s:comment_grey }) " status line of non-current :terminal window
+call s:h("TabLine", { "fg": s:comment_grey }) " tab pages line, not active tab page label
+call s:h("TabLineFill", {}) " tab pages line, where there are no labels
+call s:h("TabLineSel", { "fg": s:white }) " tab pages line, active tab page label
+call s:h("Terminal", { "fg": s:white, "bg": s:black }) " terminal window (see terminal-size-color)
+call s:h("Title", { "fg": s:green }) " titles for output from ":set all", ":autocmd" etc.
+call s:h("Visual", { "bg": s:visual_grey }) " Visual mode selection
+call s:h("VisualNOS", { "bg": s:visual_grey }) " Visual mode selection when vim is "Not Owning the Selection". Only X11 Gui's gui-x11 and xterm-clipboard supports this.
+call s:h("WarningMsg", { "fg": s:yellow }) " warning messages
+call s:h("WildMenu", { "fg": s:black, "bg": s:blue }) " current match in 'wildmenu' completion
+
+" }}}
+
+" Termdebug highlighting for Vim 8.1+ {{{
+
+" See `:h hl-debugPC` and `:h hl-debugBreakpoint`.
+call s:h("debugPC", { "bg": s:special_grey }) " the current position
+call s:h("debugBreakpoint", { "fg": s:black, "bg": s:red }) " a breakpoint
+
+" }}}
+
+" Language-Specific Highlighting {{{
+
+" CSS
+call s:h("cssAttrComma", { "fg": s:purple })
+call s:h("cssAttributeSelector", { "fg": s:green })
+call s:h("cssBraces", { "fg": s:white })
+call s:h("cssClassName", { "fg": s:dark_yellow })
+call s:h("cssClassNameDot", { "fg": s:dark_yellow })
+call s:h("cssDefinition", { "fg": s:purple })
+call s:h("cssFontAttr", { "fg": s:dark_yellow })
+call s:h("cssFontDescriptor", { "fg": s:purple })
+call s:h("cssFunctionName", { "fg": s:blue })
+call s:h("cssIdentifier", { "fg": s:blue })
+call s:h("cssImportant", { "fg": s:purple })
+call s:h("cssInclude", { "fg": s:white })
+call s:h("cssIncludeKeyword", { "fg": s:purple })
+call s:h("cssMediaType", { "fg": s:dark_yellow })
+call s:h("cssProp", { "fg": s:white })
+call s:h("cssPseudoClassId", { "fg": s:dark_yellow })
+call s:h("cssSelectorOp", { "fg": s:purple })
+call s:h("cssSelectorOp2", { "fg": s:purple })
+call s:h("cssTagName", { "fg": s:red })
+
+" Fish Shell
+call s:h("fishKeyword", { "fg": s:purple })
+call s:h("fishConditional", { "fg": s:purple })
+
+" Go
+call s:h("goDeclaration", { "fg": s:purple })
+call s:h("goBuiltins", { "fg": s:cyan })
+call s:h("goFunctionCall", { "fg": s:blue })
+call s:h("goVarDefs", { "fg": s:red })
+call s:h("goVarAssign", { "fg": s:red })
+call s:h("goVar", { "fg": s:purple })
+call s:h("goConst", { "fg": s:purple })
+call s:h("goType", { "fg": s:yellow })
+call s:h("goTypeName", { "fg": s:yellow })
+call s:h("goDeclType", { "fg": s:cyan })
+call s:h("goTypeDecl", { "fg": s:purple })
+
+" HTML (keep consistent with Markdown, below)
+call s:h("htmlArg", { "fg": s:dark_yellow })
+call s:h("htmlBold", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("htmlBoldItalic", { "fg": s:green, "gui": "bold,italic", "cterm": "bold,italic" })
+call s:h("htmlEndTag", { "fg": s:white })
+call s:h("htmlH1", { "fg": s:red })
+call s:h("htmlH2", { "fg": s:red })
+call s:h("htmlH3", { "fg": s:red })
+call s:h("htmlH4", { "fg": s:red })
+call s:h("htmlH5", { "fg": s:red })
+call s:h("htmlH6", { "fg": s:red })
+call s:h("htmlItalic", { "fg": s:purple, "gui": "italic", "cterm": "italic" })
+call s:h("htmlLink", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+call s:h("htmlSpecialChar", { "fg": s:dark_yellow })
+call s:h("htmlSpecialTagName", { "fg": s:red })
+call s:h("htmlTag", { "fg": s:white })
+call s:h("htmlTagN", { "fg": s:red })
+call s:h("htmlTagName", { "fg": s:red })
+call s:h("htmlTitle", { "fg": s:white })
+
+" JavaScript
+call s:h("javaScriptBraces", { "fg": s:white })
+call s:h("javaScriptFunction", { "fg": s:purple })
+call s:h("javaScriptIdentifier", { "fg": s:purple })
+call s:h("javaScriptNull", { "fg": s:dark_yellow })
+call s:h("javaScriptNumber", { "fg": s:dark_yellow })
+call s:h("javaScriptRequire", { "fg": s:cyan })
+call s:h("javaScriptReserved", { "fg": s:purple })
+" https://github.com/pangloss/vim-javascript
+call s:h("jsArrowFunction", { "fg": s:purple })
+call s:h("jsClassKeyword", { "fg": s:purple })
+call s:h("jsClassMethodType", { "fg": s:purple })
+call s:h("jsDocParam", { "fg": s:blue })
+call s:h("jsDocTags", { "fg": s:purple })
+call s:h("jsExport", { "fg": s:purple })
+call s:h("jsExportDefault", { "fg": s:purple })
+call s:h("jsExtendsKeyword", { "fg": s:purple })
+call s:h("jsFrom", { "fg": s:purple })
+call s:h("jsFuncCall", { "fg": s:blue })
+call s:h("jsFunction", { "fg": s:purple })
+call s:h("jsGenerator", { "fg": s:yellow })
+call s:h("jsGlobalObjects", { "fg": s:yellow })
+call s:h("jsImport", { "fg": s:purple })
+call s:h("jsModuleAs", { "fg": s:purple })
+call s:h("jsModuleWords", { "fg": s:purple })
+call s:h("jsModules", { "fg": s:purple })
+call s:h("jsNull", { "fg": s:dark_yellow })
+call s:h("jsOperator", { "fg": s:purple })
+call s:h("jsStorageClass", { "fg": s:purple })
+call s:h("jsSuper", { "fg": s:red })
+call s:h("jsTemplateBraces", { "fg": s:dark_red })
+call s:h("jsTemplateVar", { "fg": s:green })
+call s:h("jsThis", { "fg": s:red })
+call s:h("jsUndefined", { "fg": s:dark_yellow })
+" https://github.com/othree/yajs.vim
+call s:h("javascriptArrowFunc", { "fg": s:purple })
+call s:h("javascriptClassExtends", { "fg": s:purple })
+call s:h("javascriptClassKeyword", { "fg": s:purple })
+call s:h("javascriptDocNotation", { "fg": s:purple })
+call s:h("javascriptDocParamName", { "fg": s:blue })
+call s:h("javascriptDocTags", { "fg": s:purple })
+call s:h("javascriptEndColons", { "fg": s:white })
+call s:h("javascriptExport", { "fg": s:purple })
+call s:h("javascriptFuncArg", { "fg": s:white })
+call s:h("javascriptFuncKeyword", { "fg": s:purple })
+call s:h("javascriptIdentifier", { "fg": s:red })
+call s:h("javascriptImport", { "fg": s:purple })
+call s:h("javascriptMethodName", { "fg": s:white })
+call s:h("javascriptObjectLabel", { "fg": s:white })
+call s:h("javascriptOpSymbol", { "fg": s:cyan })
+call s:h("javascriptOpSymbols", { "fg": s:cyan })
+call s:h("javascriptPropertyName", { "fg": s:green })
+call s:h("javascriptTemplateSB", { "fg": s:dark_red })
+call s:h("javascriptVariable", { "fg": s:purple })
+
+" JSON
+call s:h("jsonCommentError", { "fg": s:white })
+call s:h("jsonKeyword", { "fg": s:red })
+call s:h("jsonBoolean", { "fg": s:dark_yellow })
+call s:h("jsonNumber", { "fg": s:dark_yellow })
+call s:h("jsonQuote", { "fg": s:white })
+call s:h("jsonMissingCommaError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonNoQuotesError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonNumError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonString", { "fg": s:green })
+call s:h("jsonStringSQError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonSemicolonError", { "fg": s:red, "gui": "reverse" })
+
+" LESS
+call s:h("lessVariable", { "fg": s:purple })
+call s:h("lessAmpersandChar", { "fg": s:white })
+call s:h("lessClass", { "fg": s:dark_yellow })
+
+" Markdown (keep consistent with HTML, above)
+call s:h("markdownBlockquote", { "fg": s:comment_grey })
+call s:h("markdownBold", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("markdownBoldItalic", { "fg": s:green, "gui": "bold,italic", "cterm": "bold,italic" })
+call s:h("markdownCode", { "fg": s:green })
+call s:h("markdownCodeBlock", { "fg": s:green })
+call s:h("markdownCodeDelimiter", { "fg": s:green })
+call s:h("markdownH1", { "fg": s:red })
+call s:h("markdownH2", { "fg": s:red })
+call s:h("markdownH3", { "fg": s:red })
+call s:h("markdownH4", { "fg": s:red })
+call s:h("markdownH5", { "fg": s:red })
+call s:h("markdownH6", { "fg": s:red })
+call s:h("markdownHeadingDelimiter", { "fg": s:red })
+call s:h("markdownHeadingRule", { "fg": s:comment_grey })
+call s:h("markdownId", { "fg": s:purple })
+call s:h("markdownIdDeclaration", { "fg": s:blue })
+call s:h("markdownIdDelimiter", { "fg": s:purple })
+call s:h("markdownItalic", { "fg": s:purple, "gui": "italic", "cterm": "italic" })
+call s:h("markdownLinkDelimiter", { "fg": s:purple })
+call s:h("markdownLinkText", { "fg": s:blue })
+call s:h("markdownListMarker", { "fg": s:red })
+call s:h("markdownOrderedListMarker", { "fg": s:red })
+call s:h("markdownRule", { "fg": s:comment_grey })
+call s:h("markdownUrl", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+
+" Perl
+call s:h("perlFiledescRead", { "fg": s:green })
+call s:h("perlFunction", { "fg": s:purple })
+call s:h("perlMatchStartEnd",{ "fg": s:blue })
+call s:h("perlMethod", { "fg": s:purple })
+call s:h("perlPOD", { "fg": s:comment_grey })
+call s:h("perlSharpBang", { "fg": s:comment_grey })
+call s:h("perlSpecialString",{ "fg": s:dark_yellow })
+call s:h("perlStatementFiledesc", { "fg": s:red })
+call s:h("perlStatementFlow",{ "fg": s:red })
+call s:h("perlStatementInclude", { "fg": s:purple })
+call s:h("perlStatementScalar",{ "fg": s:purple })
+call s:h("perlStatementStorage", { "fg": s:purple })
+call s:h("perlSubName",{ "fg": s:yellow })
+call s:h("perlVarPlain",{ "fg": s:blue })
+
+" PHP
+call s:h("phpVarSelector", { "fg": s:red })
+call s:h("phpOperator", { "fg": s:white })
+call s:h("phpParent", { "fg": s:white })
+call s:h("phpMemberSelector", { "fg": s:white })
+call s:h("phpType", { "fg": s:purple })
+call s:h("phpKeyword", { "fg": s:purple })
+call s:h("phpClass", { "fg": s:yellow })
+call s:h("phpUseClass", { "fg": s:white })
+call s:h("phpUseAlias", { "fg": s:white })
+call s:h("phpInclude", { "fg": s:purple })
+call s:h("phpClassExtends", { "fg": s:green })
+call s:h("phpDocTags", { "fg": s:white })
+call s:h("phpFunction", { "fg": s:blue })
+call s:h("phpFunctions", { "fg": s:cyan })
+call s:h("phpMethodsVar", { "fg": s:dark_yellow })
+call s:h("phpMagicConstants", { "fg": s:dark_yellow })
+call s:h("phpSuperglobals", { "fg": s:red })
+call s:h("phpConstants", { "fg": s:dark_yellow })
+
+" Ruby
+call s:h("rubyBlockParameter", { "fg": s:red})
+call s:h("rubyBlockParameterList", { "fg": s:red })
+call s:h("rubyClass", { "fg": s:purple})
+call s:h("rubyConstant", { "fg": s:yellow})
+call s:h("rubyControl", { "fg": s:purple })
+call s:h("rubyEscape", { "fg": s:red})
+call s:h("rubyFunction", { "fg": s:blue})
+call s:h("rubyGlobalVariable", { "fg": s:red})
+call s:h("rubyInclude", { "fg": s:blue})
+call s:h("rubyIncluderubyGlobalVariable", { "fg": s:red})
+call s:h("rubyInstanceVariable", { "fg": s:red})
+call s:h("rubyInterpolation", { "fg": s:cyan })
+call s:h("rubyInterpolationDelimiter", { "fg": s:red })
+call s:h("rubyInterpolationDelimiter", { "fg": s:red})
+call s:h("rubyRegexp", { "fg": s:cyan})
+call s:h("rubyRegexpDelimiter", { "fg": s:cyan})
+call s:h("rubyStringDelimiter", { "fg": s:green})
+call s:h("rubySymbol", { "fg": s:cyan})
+
+" Sass
+" https://github.com/tpope/vim-haml
+call s:h("sassAmpersand", { "fg": s:red })
+call s:h("sassClass", { "fg": s:dark_yellow })
+call s:h("sassControl", { "fg": s:purple })
+call s:h("sassExtend", { "fg": s:purple })
+call s:h("sassFor", { "fg": s:white })
+call s:h("sassFunction", { "fg": s:cyan })
+call s:h("sassId", { "fg": s:blue })
+call s:h("sassInclude", { "fg": s:purple })
+call s:h("sassMedia", { "fg": s:purple })
+call s:h("sassMediaOperators", { "fg": s:white })
+call s:h("sassMixin", { "fg": s:purple })
+call s:h("sassMixinName", { "fg": s:blue })
+call s:h("sassMixing", { "fg": s:purple })
+call s:h("sassVariable", { "fg": s:purple })
+" https://github.com/cakebaker/scss-syntax.vim
+call s:h("scssExtend", { "fg": s:purple })
+call s:h("scssImport", { "fg": s:purple })
+call s:h("scssInclude", { "fg": s:purple })
+call s:h("scssMixin", { "fg": s:purple })
+call s:h("scssSelectorName", { "fg": s:dark_yellow })
+call s:h("scssVariable", { "fg": s:purple })
+
+" TeX
+call s:h("texStatement", { "fg": s:purple })
+call s:h("texSubscripts", { "fg": s:dark_yellow })
+call s:h("texSuperscripts", { "fg": s:dark_yellow })
+call s:h("texTodo", { "fg": s:dark_red })
+call s:h("texBeginEnd", { "fg": s:purple })
+call s:h("texBeginEndName", { "fg": s:blue })
+call s:h("texMathMatcher", { "fg": s:blue })
+call s:h("texMathDelim", { "fg": s:blue })
+call s:h("texDelimiter", { "fg": s:dark_yellow })
+call s:h("texSpecialChar", { "fg": s:dark_yellow })
+call s:h("texCite", { "fg": s:blue })
+call s:h("texRefZone", { "fg": s:blue })
+
+" TypeScript
+call s:h("typescriptReserved", { "fg": s:purple })
+call s:h("typescriptEndColons", { "fg": s:white })
+call s:h("typescriptBraces", { "fg": s:white })
+
+" XML
+call s:h("xmlAttrib", { "fg": s:dark_yellow })
+call s:h("xmlEndTag", { "fg": s:red })
+call s:h("xmlTag", { "fg": s:red })
+call s:h("xmlTagName", { "fg": s:red })
+
+" }}}
+
+" Plugin Highlighting {{{
+
+" airblade/vim-gitgutter
+call s:h("GitGutterAdd", { "fg": s:green })
+call s:h("GitGutterChange", { "fg": s:yellow })
+call s:h("GitGutterDelete", { "fg": s:red })
+
+" dense-analysis/ale
+call s:h("ALEError", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+call s:h("ALEWarning", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+call s:h("ALEInfo", { "gui": "underline", "cterm": "underline" })
+call s:h("ALEErrorSign", { "fg": s:red })
+call s:h("ALEWarningSign", { "fg": s:yellow })
+call s:h("ALEInfoSign", { })
+
+" easymotion/vim-easymotion
+call s:h("EasyMotionTarget", { "fg": s:red, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionTarget2First", { "fg": s:yellow, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionTarget2Second", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionShade", { "fg": s:comment_grey })
+
+" lewis6991/gitsigns.nvim
+hi link GitSignsAdd GitGutterAdd
+hi link GitSignsChange GitGutterChange
+hi link GitSignsDelete GitGutterDelete
+
+" mhinz/vim-signify
+hi link SignifySignAdd GitGutterAdd
+hi link SignifySignChange GitGutterChange
+hi link SignifySignDelete GitGutterDelete
+
+" neoclide/coc.nvim
+call s:h("CocErrorSign", { "fg": s:red })
+call s:h("CocWarningSign", { "fg": s:yellow })
+call s:h("CocInfoSign", { "fg": s:blue })
+call s:h("CocHintSign", { "fg": s:cyan })
+call s:h("CocFadeOut", { "fg": s:comment_grey })
+" https://github.com/joshdick/onedark.vim/issues/313
+highlight! link CocMenuSel PmenuSel
+
+" neomake/neomake
+call s:h("NeomakeErrorSign", { "fg": s:red })
+call s:h("NeomakeWarningSign", { "fg": s:yellow })
+call s:h("NeomakeInfoSign", { "fg": s:blue })
+
+" plasticboy/vim-markdown (keep consistent with Markdown, above)
+call s:h("mkdDelimiter", { "fg": s:purple })
+call s:h("mkdHeading", { "fg": s:red })
+call s:h("mkdLink", { "fg": s:blue })
+call s:h("mkdURL", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+
+" prabirshrestha/vim-lsp
+call s:h("LspErrorText", { "fg": s:red })
+call s:h("LspWarningText", { "fg": s:yellow })
+call s:h("LspInformationText", { "fg":s:blue })
+call s:h("LspHintText", { "fg":s:cyan })
+call s:h("LspErrorHighlight", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+call s:h("LspWarningHighlight", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+call s:h("LspInformationHighlight", { "fg":s:blue, "gui": "underline", "cterm": "underline" })
+call s:h("LspHintHighlight", { "fg":s:cyan, "gui": "underline", "cterm": "underline" })
+
+" tpope/vim-fugitive
+call s:h("diffAdded", { "fg": s:green })
+call s:h("diffRemoved", { "fg": s:red })
+
+" }}}
+
+" Git Highlighting {{{
+
+call s:h("gitcommitComment", { "fg": s:comment_grey })
+call s:h("gitcommitUnmerged", { "fg": s:green })
+call s:h("gitcommitOnBranch", {})
+call s:h("gitcommitBranch", { "fg": s:purple })
+call s:h("gitcommitDiscardedType", { "fg": s:red })
+call s:h("gitcommitSelectedType", { "fg": s:green })
+call s:h("gitcommitHeader", {})
+call s:h("gitcommitUntrackedFile", { "fg": s:cyan })
+call s:h("gitcommitDiscardedFile", { "fg": s:red })
+call s:h("gitcommitSelectedFile", { "fg": s:green })
+call s:h("gitcommitUnmergedFile", { "fg": s:yellow })
+call s:h("gitcommitFile", {})
+call s:h("gitcommitSummary", { "fg": s:white })
+call s:h("gitcommitOverflow", { "fg": s:red })
+hi link gitcommitNoBranch gitcommitBranch
+hi link gitcommitUntracked gitcommitComment
+hi link gitcommitDiscarded gitcommitComment
+hi link gitcommitSelected gitcommitComment
+hi link gitcommitDiscardedArrow gitcommitDiscardedFile
+hi link gitcommitSelectedArrow gitcommitSelectedFile
+hi link gitcommitUnmergedArrow gitcommitUnmergedFile
+
+" }}}
+
+" Neovim-Specific Highlighting {{{
+
+if has("nvim")
+ " Neovim terminal colors {{{
+ let g:terminal_color_0 = s:black.gui
+ let g:terminal_color_1 = s:red.gui
+ let g:terminal_color_2 = s:green.gui
+ let g:terminal_color_3 = s:yellow.gui
+ let g:terminal_color_4 = s:blue.gui
+ let g:terminal_color_5 = s:purple.gui
+ let g:terminal_color_6 = s:cyan.gui
+ let g:terminal_color_7 = s:white.gui
+ let g:terminal_color_8 = s:visual_grey.gui
+ let g:terminal_color_9 = s:dark_red.gui
+ let g:terminal_color_10 = s:green.gui " No dark version
+ let g:terminal_color_11 = s:dark_yellow.gui
+ let g:terminal_color_12 = s:blue.gui " No dark version
+ let g:terminal_color_13 = s:purple.gui " No dark version
+ let g:terminal_color_14 = s:cyan.gui " No dark version
+ let g:terminal_color_15 = s:comment_grey.gui
+ let g:terminal_color_background = s:background.gui
+ let g:terminal_color_foreground = s:foreground.gui
+ " }}}
+
+ " Neovim Diagnostics {{{
+ call s:h("DiagnosticError", { "fg": s:red })
+ call s:h("DiagnosticWarn", { "fg": s:yellow })
+ call s:h("DiagnosticInfo", { "fg": s:blue })
+ call s:h("DiagnosticHint", { "fg": s:cyan })
+ call s:h("DiagnosticUnderlineError", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineWarn", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineInfo", { "fg": s:blue, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineHint", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+ " }}}
+
+ " Neovim LSP (for versions < 0.5.1) {{{
+ hi link LspDiagnosticsDefaultError DiagnosticError
+ hi link LspDiagnosticsDefaultWarning DiagnosticWarn
+ hi link LspDiagnosticsDefaultInformation DiagnosticInfo
+ hi link LspDiagnosticsDefaultHint DiagnosticHint
+ hi link LspDiagnosticsUnderlineError DiagnosticUnderlineError
+ hi link LspDiagnosticsUnderlineWarning DiagnosticUnderlineWarn
+ hi link LspDiagnosticsUnderlineInformation DiagnosticUnderlineInfo
+ hi link LspDiagnosticsUnderlineHint DiagnosticUnderlineHint
+ " }}}
+endif
+
+" }}}
+
+" Must appear at the end of the file to work around this oddity:
+" https://groups.google.com/forum/#!msg/vim_dev/afPqwAFNdrU/nqh6tOM87QUJ
+set background=dark
diff --git a/.config/nvim/dev.vim b/.config/nvim/dev.vim
new file mode 100644
index 0000000..89b8eca
--- /dev/null
+++ b/.config/nvim/dev.vim
@@ -0,0 +1,93 @@
+source ~/.config/nvim/init.vim
+
+packadd! onedark.vim
+
+" --> Zeal docs
+let g:zv_disable_mapping = 1
+nmap <leader>z <Plug>Zeavim
+vmap <leader>z <Plug>ZVVisSelection
+nmap gz <Plug>ZVOperator
+nmap <leader><leader>z <Plug>ZVKeyDocset
+
+" --> COC
+autocmd! User coc.nvim source $HOME/.config/nvim/coc/coc-onload.vim
+let g:coc_config_home = '$HOME/.config/nvim/coc'
+let g:coc_data_home = '$HOME/.local/share/nvim/site/coc'
+let g:coc_global_extensions = [
+ \ 'coc-json',
+ \ 'coc-marketplace',
+ \ 'coc-css',
+ \ 'coc-tsserver',
+ \ 'coc-pyright',
+ \ 'coc-java',
+ \ 'coc-sh',
+ \ ]
+nnoremap <silent><nowait> <leader>ca :<C-u>CocList diagnostics<cr>
+nnoremap <silent><nowait> <leader>ce :<C-u>CocList extensions<cr>
+nnoremap <silent><nowait> <leader>cc :<C-u>CocList commands<cr>
+nnoremap <silent><nowait> <leader>co :<C-u>CocList outline<cr>
+nnoremap <silent><nowait> <leader>cs :<C-u>CocList -I symbols<cr>
+nnoremap <silent><nowait> <leader>cj :<C-u>CocNext<CR>
+nnoremap <silent><nowait> <leader>ck :<C-u>CocPrev<CR>
+nnoremap <silent><nowait> <leader>cp :<C-u>CocListResume<CR>
+nnoremap <leader>cm :CocList marketplace<CR>
+
+" --> Vimspector
+let g:vimspector_base_dir = expand('$HOME/.local/share/nvim/vimspector')
+let g:vimspector_enable_mappings = 'HUMAN'
+nnoremap <leader>dc <Plug>VimspectorContinue
+nnoremap <leader>ds <Plug>VimspectorStop
+nnoremap <leader>dr <Plug>VimspectorRestart
+nnoremap <leader>dp <Plug>VimspectorPause
+nnoremap <leader>dl <Plug>VimspectorBreakpoints
+nnoremap <leader>dd <Plug>VimspectorToggleBreakpoint
+nnoremap <leader>db <Plug>VimspectorToggleConditionalBreakpoint
+nnoremap <leader>df <Plug>VimspectorAddFunctionBreakpoint
+nnoremap <leader>dg <Plug>VimspectorGoToCurrentLine
+nnoremap <leader>dx :call vimspector#ClearBreakpoints()<CR>
+nnoremap <leader>dq :VimspectorReset<CR>
+nnoremap <A-C> <Plug>VimspectorContinue
+nnoremap <A-n> <Plug>VimspectorStepOver
+nnoremap <A-i> <Plug>VimspectorStepInto
+nnoremap <A-o> <Plug>VimspectorStepOut
+nnoremap <A-b> <Plug>VimspectorToggleBreakpoint
+nnoremap <A-c> <Plug>VimspectorRunToCursor
+
+" --> onedark theme
+if exists('+termguicolors')
+ let g:airline_theme = 'onedark'
+ let g:onedark_terminal_italics = 1
+ let g:onedark_color_overrides = {
+ \ "foreground": { "gui": "#BBC2CF", "cterm": "145", "cterm16": "NONE" },
+ \ "background": { "gui": "#181C24", "cterm": "235", "cterm16": "NONE" },
+ \ "comment_grey": { "gui": "#6C7380", "cterm": "59", "cterm16": "7" },
+ \ "gutter_fg_grey": { "gui": "#6272A4", "cterm": "238", "cterm16": "8" },
+ \ "special_grey": { "gui": "#5Ba078", "cterm": "238", "cterm16": "7" },
+ \ }
+ " \ "background": { "gui": "#202426", "cterm": "235", "cterm16": "NONE" },
+ "
+ " \ "red": { "gui": "#E06C75", "cterm": "204", "cterm16": "1" },
+ " \ "dark_red": { "gui": "#BE5046", "cterm": "196", "cterm16": "9" },
+ " \ "green": { "gui": "#98C379", "cterm": "114", "cterm16": "2" },
+ " \ "yellow": { "gui": "#E5C07B", "cterm": "180", "cterm16": "3" },
+ " \ "dark_yellow": { "gui": "#D19A66", "cterm": "173", "cterm16": "11" },
+ " \ "blue": { "gui": "#61AFEF", "cterm": "39", "cterm16": "4" },
+ " \ "purple": { "gui": "#C678DD", "cterm": "170", "cterm16": "5" },
+ " \ "cyan": { "gui": "#56B6C2", "cterm": "38", "cterm16": "6" },
+ " \ "black": { "gui": "#282C34", "cterm": "235", "cterm16": "0" },
+ " \ "white": { "gui": "#ABB2BF", "cterm": "145", "cterm16": "15" },
+ " \ "cursor_grey": { "gui": "#2C323C", "cterm": "236", "cterm16": "0" },
+ " \ "visual_grey": { "gui": "#3E4452", "cterm": "237", "cterm16": "8" },
+ " \ "menu_grey": { "gui": "#3E4452", "cterm": "237", "cterm16": "7" },
+ " \ "vertsplit": { "gui": "#3E4452", "cterm": "59", "cterm16": "7" },
+
+ " autocmd ColorScheme * call onedark#extend_highlight("LineNr", {
+ " \ "fg": { "gui": "#6272A4", "cterm": "238", "cterm16": "8" },
+ " \ })
+ let &t_8f="\<Esc>[38;2;%lu;%lu;%lum"
+ let &t_8b="\<Esc>[48;2;%lu;%lu;%lum"
+ " set termguicolors noshowmode
+ colorscheme onedark
+ " autocmd VimEnter * AirlineTheme
+endif
+
diff --git a/.config/nvim/init.bak.vim b/.config/nvim/init.bak.vim
new file mode 100644
index 0000000..6057fe4
--- /dev/null
+++ b/.config/nvim/init.bak.vim
@@ -0,0 +1,225 @@
+let mapleader=" "
+
+if ! filereadable(system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim"'))
+ echo "Downloading junegunn/vim-plug to manage plugins..."
+ silent !mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/
+ silent !curl "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" > ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim
+ autocmd VimEnter * PlugInstall
+endif
+
+call plug#begin(system('echo -n "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/plugged"'))
+Plug 'tpope/vim-surround'
+Plug 'tpope/vim-commentary'
+Plug 'ptzz/lf.vim'
+Plug 'voldikss/vim-floaterm'
+Plug 'KabbAmine/zeavim.vim' ", {'on': ['Zeavim', 'ZeavimV', 'ZVVisSelection', 'ZVOperator', 'ZVKeyDocset']}
+Plug 'neoclide/coc.nvim', {'on': ['CocList', 'CocConfig'], 'branch': 'release'}
+Plug 'ap/vim-css-color' " color code highlighting
+Plug 'xuhdev/vim-latex-live-preview', {'for': 'tex'}
+Plug 'machakann/vim-verdin', {'for': 'vim'}
+Plug 'puremourning/vimspector', {'for': 'python'}
+" Plug 'powerman/vim-plugin-AnsiEsc'
+" Plug 'junegunn/goyo.vim', {'on': 'Goyo'}
+" Plug 'jreybert/vimagit'
+" Plug 'lukesmithxyz/vimling'
+" Plug 'vimwiki/vimwiki'
+Plug 'vim-airline/vim-airline', {'on': 'AirlineTheme'}
+Plug 'vim-airline/vim-airline-themes', {'on': 'AirlineTheme'}
+Plug 'joshdick/onedark.vim'
+call plug#end()
+
+let g:Verdin#autocomplete = 1
+let g:livepreview_previewer = 'zathura'
+
+set title showmatch nowrap
+set mouse=a
+set tabstop=2 shiftwidth=0
+set number relativenumber
+set cursorline cursorcolumn
+set cc=80
+set scrolloff=5
+set splitbelow splitright
+set updatetime=500
+
+syntax on
+filetype plugin indent on
+autocmd FileType text setlocal tabstop=8 shiftwidth=4
+autocmd FileType html setlocal tabstop=2 shiftwidth=2
+autocmd FileType sql setlocal commentstring=--\ %s
+autocmd BufEnter bm-files,bm-dirs setlocal tabstop=8 shiftwidth=8
+autocmd BufWritePost bm-files,bm-dirs silent !shortcuts
+autocmd BufWritePost config.h,config.def.h !cd "%:h"; sudo make clean install
+autocmd BufWritePre * %s/\s\+$//e
+au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
+
+autocmd BufWritePost */Documents/Notes/*.md silent !pandoc % -o "$HOME/Documents/Notes/.out/$(basename % .md).html"
+autocmd BufWritePost .Xresources silent !xrdb "%"
+autocmd BufRead,BufNewFile *.yt* set filetype=conf
+
+autocmd TermOpen * startinsert
+command! -nargs=* T split | terminal <args>
+
+" --> Scratch buffer
+if exists('g:loaded_scratch')
+ finish
+endif
+let g:loaded_scratch = 1
+command! -nargs=1 -complete=command D call scratch#open(<q-args>, <q-mods>)
+
+" --> Zeal docs
+let g:zv_disable_mapping = 1
+nmap <leader>z <Plug>Zeavim
+vmap <leader>z <Plug>ZVVisSelection
+nmap gz <Plug>ZVOperator
+nmap <leader><leader>z <Plug>ZVKeyDocset
+
+" --> COC
+autocmd! User coc.nvim source $HOME/.config/nvim/coc/coc-onload.vim
+let g:coc_config_home = '$HOME/.config/nvim/coc'
+let g:coc_data_home = '$HOME/.local/share/nvim/site/coc'
+let g:coc_global_extensions = [
+ \ 'coc-json',
+ \ 'coc-marketplace',
+ \ 'coc-css',
+ \ 'coc-tsserver',
+ \ 'coc-pyright',
+ \ 'coc-java',
+ \ 'coc-sh',
+ \ ]
+nnoremap <silent><nowait> <leader>ca :<C-u>CocList diagnostics<cr>
+nnoremap <silent><nowait> <leader>ce :<C-u>CocList extensions<cr>
+nnoremap <silent><nowait> <leader>cc :<C-u>CocList commands<cr>
+nnoremap <silent><nowait> <leader>co :<C-u>CocList outline<cr>
+nnoremap <silent><nowait> <leader>cs :<C-u>CocList -I symbols<cr>
+nnoremap <silent><nowait> <leader>cj :<C-u>CocNext<CR>
+nnoremap <silent><nowait> <leader>ck :<C-u>CocPrev<CR>
+nnoremap <silent><nowait> <leader>cp :<C-u>CocListResume<CR>
+nnoremap <leader>cm :CocList marketplace<CR>
+
+" --> Vimspector
+let g:vimspector_base_dir = expand('$HOME/.local/share/nvim/vimspector')
+let g:vimspector_enable_mappings = 'HUMAN'
+nnoremap <leader>dc <Plug>VimspectorContinue
+nnoremap <leader>ds <Plug>VimspectorStop
+nnoremap <leader>dr <Plug>VimspectorRestart
+nnoremap <leader>dp <Plug>VimspectorPause
+nnoremap <leader>dl <Plug>VimspectorBreakpoints
+nnoremap <leader>dd <Plug>VimspectorToggleBreakpoint
+nnoremap <leader>db <Plug>VimspectorToggleConditionalBreakpoint
+nnoremap <leader>df <Plug>VimspectorAddFunctionBreakpoint
+nnoremap <leader>dg <Plug>VimspectorGoToCurrentLine
+nnoremap <leader>dx :call vimspector#ClearBreakpoints()<CR>
+nnoremap <leader>dq :VimspectorReset<CR>
+nnoremap <A-C> <Plug>VimspectorContinue
+nnoremap <A-n> <Plug>VimspectorStepOver
+nnoremap <A-i> <Plug>VimspectorStepInto
+nnoremap <A-o> <Plug>VimspectorStepOut
+nnoremap <A-b> <Plug>VimspectorToggleBreakpoint
+nnoremap <A-c> <Plug>VimspectorRunToCursor
+
+" --> Lf
+" let g:lf_command_override = 'lf -command ...'
+let g:NERDTreeHijackNetrw = 0
+" let g:lf_replace_netrw = 1
+let g:lf_width = 1.0
+let g:lf_height = 1.0
+let g:lf_map_keys = 0
+nnoremap <Esc>o :LfCurrentFile<CR>
+nnoremap <Esc>l :LfWorkingDirectory<CR>
+nnoremap <leader>o :LfCurrentFileNewTab<CR>
+nnoremap <leader>l :LfWorkingDirectoryExistingOrNewTab<CR>
+
+" --> onedark theme
+if exists('+termguicolors') && filereadable(system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/onedark.vim"'))
+ let g:airline_theme = 'onedark'
+ let g:onedark_terminal_italics = 1
+ let g:onedark_color_overrides = {
+ \ "foreground": { "gui": "#BBC2CF", "cterm": "145", "cterm16": "NONE" },
+ \ "background": { "gui": "#181C24", "cterm": "235", "cterm16": "NONE" },
+ \ "comment_grey": { "gui": "#6C7380", "cterm": "59", "cterm16": "7" },
+ \ "gutter_fg_grey": { "gui": "#6272A4", "cterm": "238", "cterm16": "8" },
+ \ "special_grey": { "gui": "#5Ba078", "cterm": "238", "cterm16": "7" },
+ \ }
+ " \ "background": { "gui": "#202426", "cterm": "235", "cterm16": "NONE" },
+ "
+ " \ "red": { "gui": "#E06C75", "cterm": "204", "cterm16": "1" },
+ " \ "dark_red": { "gui": "#BE5046", "cterm": "196", "cterm16": "9" },
+ " \ "green": { "gui": "#98C379", "cterm": "114", "cterm16": "2" },
+ " \ "yellow": { "gui": "#E5C07B", "cterm": "180", "cterm16": "3" },
+ " \ "dark_yellow": { "gui": "#D19A66", "cterm": "173", "cterm16": "11" },
+ " \ "blue": { "gui": "#61AFEF", "cterm": "39", "cterm16": "4" },
+ " \ "purple": { "gui": "#C678DD", "cterm": "170", "cterm16": "5" },
+ " \ "cyan": { "gui": "#56B6C2", "cterm": "38", "cterm16": "6" },
+ " \ "black": { "gui": "#282C34", "cterm": "235", "cterm16": "0" },
+ " \ "white": { "gui": "#ABB2BF", "cterm": "145", "cterm16": "15" },
+ " \ "cursor_grey": { "gui": "#2C323C", "cterm": "236", "cterm16": "0" },
+ " \ "visual_grey": { "gui": "#3E4452", "cterm": "237", "cterm16": "8" },
+ " \ "menu_grey": { "gui": "#3E4452", "cterm": "237", "cterm16": "7" },
+ " \ "vertsplit": { "gui": "#3E4452", "cterm": "59", "cterm16": "7" },
+
+ " autocmd ColorScheme * call onedark#extend_highlight("LineNr", {
+ " \ "fg": { "gui": "#6272A4", "cterm": "238", "cterm16": "8" },
+ " \ })
+ let &t_8f="\<Esc>[38;2;%lu;%lu;%lum"
+ let &t_8b="\<Esc>[48;2;%lu;%lu;%lum"
+ set termguicolors noshowmode
+ colorscheme onedark
+ autocmd VimEnter * AirlineTheme
+endif
+
+if !exists('g:lasttab')
+ let g:lasttab = 1
+endif
+nmap g; :exe "tabn ".g:lasttab<CR>
+au TabLeave * let g:lasttab = tabpagenr()
+nnoremap g1 1gt
+nnoremap g2 2gt
+nnoremap g3 3gt
+nnoremap g4 4gt
+nnoremap g5 5gt
+nnoremap g6 6gt
+nnoremap g7 7gt
+nnoremap g8 8gt
+nnoremap g9 :tablast<CR>
+
+vnoremap <C-c> "*y :let @+=@*<CR>
+vnoremap <C-A-c> "*d :let @+=@*<CR>
+noremap <C-p> "+p
+noremap <C-A-p> "+P
+
+nnoremap c "_c
+inoremap jk <Esc>
+" map ;n /<++><Enter>c4l
+imap ;n <Esc>/<++><Enter>c4l
+
+autocmd FileType html,markdown inoremap ;s ><Esc>bi<<Esc>ea
+autocmd FileType html,markdown inoremap ;c ><Esc>bi</<Esc>ea
+autocmd FileType html,markdown inoremap ;i <Esc>b"tywi<<Esc>ea><++></><CR><++><Esc>k$P2F>i
+autocmd FileType html,markdown inoremap ;l <Esc>b"tywi<<Esc>ea></><CR><++><Esc>k$PF<i
+autocmd FileType html,markdown inoremap ;b <Esc>b"tywi<<Esc>ea><CR><++><CR></><CR><++><Esc>k$P2k$i
+autocmd FileType html,markdown inoremap ;ap <p><CR><++><CR></p><CR><++><Esc>3k$i
+autocmd FileType html,markdown inoremap ;aa <a href=""><CR><++><CR></a><CR><++><Esc>3k$hi
+
+nnoremap <leader>fl :w<CR>:!dev lint "%"<CR>
+nnoremap <leader>fm :w<CR>:!dev format "%"<CR>
+nnoremap <leader>fc :w<CR>:!dev compile "%"<CR>
+nnoremap <leader>fr :w<CR>:!dev run "%"<CR>
+nnoremap <leader>ft :w<CR>:!dev test "%"<CR>
+
+autocmd BufEnter * nmap <leader>t :w<CR>:se nornu<CR>:!dev test "%"<CR>:se rnu<CR>
+autocmd BufEnter * nmap <leader>T :w<CR>:se nornu<CR>:T dev test "%"<CR>
+autocmd BufEnter * imap <F5> <Esc>:w<CR>:se nornu<CR>:T dev test "%"<CR>
+
+nnoremap <leader>w :set wrap!<CR>
+nnoremap <leader>p :!opout "%:p"<CR>
+nnoremap <leader>F :Goyo<CR>
+nnoremap <leader>O :T mimeopen --ask %<CR>
+nnoremap <leader>ec :tabnew ~/.config/nvim/init.vim<CR>
+nnoremap <leader><C-r> :source ~/.config/nvim/init.vim<CR>
+nnoremap <leader>s :%s//gc<Left><Left><Left>
+nnoremap <leader>r :w<CR>:!%:p<CR>
+nnoremap <leader>R :w<CR>:T %:p<CR>
+
+nnoremap <leader>gc :T git add --all && git commit<CR>
+
+source ~/.config/nvim/shortcuts.vim
diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim
new file mode 100644
index 0000000..6583a94
--- /dev/null
+++ b/.config/nvim/init.vim
@@ -0,0 +1,178 @@
+let mapleader=" "
+let config_dir = system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/"')
+
+" if ! filereadable(system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim"'))
+" echo "Downloading junegunn/vim-plug to manage plugins..."
+" silent !mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/
+" silent !curl "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" > ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim
+" autocmd VimEnter * PlugInstall
+" endif
+
+if filereadable(config_dir . "autoload/plug.vim")
+ call plug#begin(system('echo -n "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/plugged"'))
+ Plug 'tpope/vim-commentary'
+ Plug 'tpope/vim-surround'
+ Plug 'ptzz/lf.vim'
+ Plug 'voldikss/vim-floaterm'
+ Plug 'xuhdev/vim-latex-live-preview', {'for': 'tex'}
+ Plug 'ap/vim-css-color' " color code highlighting
+ Plug 'neoclide/coc.nvim', {'on': ['CocList', 'CocConfig'], 'branch': 'release'}
+ " Plug 'KabbAmine/zeavim.vim' ", {'on': ['Zeavim', 'ZeavimV', 'ZVVisSelection', 'ZVOperator', 'ZVKeyDocset']}
+ " Plug 'machakann/vim-verdin', {'for': 'vim'}
+ " Plug 'puremourning/vimspector', {'for': 'python'}
+ " Plug 'powerman/vim-plugin-AnsiEsc'
+ " Plug 'junegunn/goyo.vim', {'on': 'Goyo'}
+ " Plug 'jreybert/vimagit'
+ " Plug 'lukesmithxyz/vimling'
+ " Plug 'vimwiki/vimwiki'
+ " Plug 'vim-airline/vim-airline', {'on': 'AirlineTheme'}
+ " Plug 'vim-airline/vim-airline-themes', {'on': 'AirlineTheme'}
+ " Plug 'joshdick/onedark.vim'
+ call plug#end()
+endif
+
+let g:Verdin#autocomplete = 1
+let g:livepreview_previewer = 'zathura'
+let g:tex_flavor = 'latex'
+
+set title showmatch nowrap mouse=a scrolloff=5
+set tabstop=2 shiftwidth=0
+set cursorline linebreak
+set number relativenumber
+set splitbelow splitright
+set updatetime=1000
+set notermguicolors lazyredraw
+set listchars=tab:\┆\ "│
+
+syntax on
+filetype plugin indent on
+colorscheme vim
+highlight NonText ctermfg=242
+highlight ColorColumn ctermbg=238
+highlight! link CursorColumn ColorColumn
+autocmd FileType text,fstab setlocal tabstop=8 shiftwidth=8
+autocmd FileType html setlocal tabstop=2 shiftwidth=2 list nolinebreak
+autocmd FileType sql setlocal commentstring=--\ %s
+autocmd BufEnter bm-files,bm-dirs setlocal tabstop=8 shiftwidth=8
+autocmd BufWritePost bm-files,bm-dirs silent !shortcuts
+autocmd VimLeave *.tex !dev clean "%"
+" autocmd BufWritePost config.h,config.def.h !cd "%:h"; rm -f config.h; sudo make install
+autocmd BufWritePre * %s/\s\+$//e
+au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
+
+autocmd BufWritePost */Documents/Notes/*.md silent !pandoc % -o "$HOME/Documents/Notes/.out/$(basename % .md).html"
+" autocmd BufWritePost */Documents/latex/resume/resume.tex !cd "%:h"; pdflatex resume.tex; cp -v resume.pdf ~/Dev/vikas.rocks/static/dox/
+autocmd BufWritePost *Xresources silent !xrdb "%"
+autocmd BufRead,BufNewFile *.yt* set filetype=conf
+
+function SourceTemplate()
+ let b:template = glob("${XDG_CONFIG_HOME:-$HOME/.config}/nvim/templates/_default." . expand('%:e'))
+ if !empty(b:template)
+ execute('0r' . b:template)
+ endif
+endfunction
+
+autocmd BufNewFile * call SourceTemplate()
+
+autocmd TermOpen * startinsert
+command! -nargs=* T split | terminal <args>
+
+" --> Scratch buffer
+if exists('g:loaded_scratch')
+ finish
+endif
+let g:loaded_scratch = 1
+command! -nargs=1 -complete=command D call scratch#open(<q-args>, <q-mods>)
+
+" --> Lf
+" let g:lf_command_override = 'lf -command ...'
+let g:NERDTreeHijackNetrw = 0
+" let g:lf_replace_netrw = 1
+let g:lf_width = 1.0
+let g:lf_height = 1.0
+let g:lf_map_keys = 0
+nnoremap <Esc>o :LfCurrentFile<CR>
+nnoremap <Esc>l :LfWorkingDirectory<CR>
+nnoremap <leader>o :LfCurrentFileNewTab<CR>
+nnoremap <leader>l :LfWorkingDirectoryExistingOrNewTab<CR>
+
+if !exists('g:lasttab')
+ let g:lasttab = 1
+endif
+nmap g; :exe "tabn ".g:lasttab<CR>
+au TabLeave * let g:lasttab = tabpagenr()
+nnoremap g1 1gt
+nnoremap g2 2gt
+nnoremap g3 3gt
+nnoremap g4 4gt
+nnoremap g5 5gt
+nnoremap g6 6gt
+nnoremap g7 7gt
+nnoremap g8 8gt
+nnoremap g9 :tablast<CR>
+
+vnoremap <C-c> "*y :let @+=@*<CR>
+vnoremap <C-A-c> "*d :let @+=@*<CR>
+noremap <C-p> "+p
+noremap <C-A-p> "+P
+
+nnoremap c "_c
+inoremap jk <Esc>
+" map ;n /<++><Enter>c4l
+inoremap ;n <Esc>/<++><Enter>c4l
+nnoremap <leader>n /<++><Enter>c4l
+
+autocmd FileType html,markdown inoremap ;s ><Esc>bi<<Esc>ea
+autocmd FileType html,markdown inoremap ;c ><Esc>bi</<Esc>ea
+autocmd FileType html,markdown inoremap ;i <Esc>b"tywi<<Esc>ea></><Esc>PF<i
+autocmd FileType html,markdown inoremap ;I <Esc>b"tywi<<Esc>ea><++></><Esc>P2F>i<Space>
+autocmd FileType html,markdown inoremap ;b <Esc>b"tywi<<Esc>ea><CR></<Esc>"tpa><CR><++><Esc>kO
+autocmd FileType html,markdown inoremap ;B <Esc>b"tywi<<Esc>ea><CR><++><CR></<Esc>"tpa><CR><++><Esc>3k$i<Space>
+autocmd FileType html,markdown inoremap ;ap <p><CR><++><CR></p><CR><++><Esc>3k$i
+autocmd FileType html,markdown inoremap ;aa <a href=""><CR><++><CR></a><CR><++><Esc>3k$hi
+
+autocmd FileType tex inoremap ;b <Esc>b"tywi\begin{<Esc>ea}<CR>\end{<Esc>"tpa}<Esc>kA
+autocmd FileType tex inoremap ;s \section{}<Esc>i
+autocmd FileType tex inoremap ;at \begin{tikzpicture}<CR>\end{tikzpicture}<Esc>O
+autocmd FileType tex inoremap ;ap \usepackage{}<Esc>i
+autocmd FileType tex inoremap ;aP \usepackage[]{}<Esc>F[a
+autocmd FileType tex inoremap ;ab \textbf{}<Esc>i
+autocmd FileType tex inoremap ;ai \textit{}<Esc>i
+autocmd FileType tex inoremap ;au \underline{}<Esc>i
+
+autocmd FileType go inoremap ;ae err<Space>:=<Space><++><CR>if<Space>err<Space>!=<Space>nil<Space>{<CR>return<Space>err<CR>}<Esc>3kI
+
+nnoremap <leader>fl :w<CR>:!dev lint "%"<CR>
+nnoremap <leader>fm :w<CR>:%!dev format "%"<CR>
+nnoremap <leader>fc :w<CR>:!dev compile "%"<CR>
+nnoremap <leader>fe :w<CR>:!dev run "%"<CR>
+nnoremap <leader>ft :w<CR>:!dev test "%"<CR>
+nnoremap <leader>fr :w<CR>:!dev clean "%"<CR>
+
+nnoremap <leader>Fl :w<CR>:T dev lint "%"<CR>
+nnoremap <leader>Fm :w<CR>:T dev format "%"<CR>
+nnoremap <leader>Fc :w<CR>:T dev compile "%"<CR>
+nnoremap <leader>Fe :w<CR>:T dev run "%"<CR>
+nnoremap <leader>Ft :w<CR>:T dev test "%"<CR>
+nnoremap <leader>Fr :w<CR>:T dev clean "%"<CR>
+
+autocmd BufEnter * nmap <leader>t :w<CR>:se nornu<CR>:!dev test "%"<CR>:se rnu<CR>
+autocmd BufEnter * nmap <leader>T :w<CR>:se nornu<CR>:T dev test "%"<CR>
+autocmd BufEnter * imap <F5> <Esc>:w<CR>:se nornu<CR>:T dev test "%"<CR>
+
+autocmd BufEnter vartak-results-data.pl nmap <leader>t :w<CR>:se nornu<CR>:!vartak-results-data.pl ~/GDrive/vartak/results/university/1S002557.pdf<CR>:se rnu<CR>
+
+nnoremap <leader>w :set wrap!<CR>
+nnoremap <leader>fo :!opout "%:p"<CR>
+nnoremap <leader>ec :tabnew ~/.config/nvim/init.vim<CR>
+nnoremap <leader><C-r> :source ~/.config/nvim/init.vim<CR>
+nnoremap <leader>s :%s//gc<Left><Left><Left>
+nnoremap <leader>r :w<CR>:!%:p<CR>
+nnoremap <leader>R :w<CR>:T %:p<CR>
+
+nnoremap <leader>gc :T git add --all && git commit<CR>
+
+let shortcuts = config_dir . "shortcuts.vim"
+if filereadable(shortcuts)
+ execute "source " . shortcuts
+endif
diff --git a/.config/nvim/onedark.vim b/.config/nvim/onedark.vim
new file mode 100644
index 0000000..6769d6c
--- /dev/null
+++ b/.config/nvim/onedark.vim
@@ -0,0 +1,713 @@
+" vim:fdm=marker
+" Vim Color File
+" Name: onedark.vim
+" Maintainer: https://github.com/joshdick/onedark.vim/
+" License: The MIT License (MIT)
+" Based On: https://github.com/MaxSt/FlatColor/
+
+" Companion statusline plugin and terminal themes are included with onedark.vim:
+" * https://github.com/joshdick/onedark.vim#lightlinevim-colorscheme
+" * https://github.com/joshdick/onedark.vim#vim-airline-theme
+" * https://github.com/joshdick/onedark.vim/tree/main/term
+
+" Color Reference {{{
+
+" The following colors were measured inside Atom using its built-in inspector.
+
+" +---------------------------------------------+
+" | Color Name | RGB | Hex |
+" |--------------+--------------------+---------|
+" | Black | rgb(40, 44, 52) | #282c34 |
+" |--------------+--------------------+---------|
+" | White | rgb(171, 178, 191) | #abb2bf |
+" |--------------+--------------------+---------|
+" | Light Red | rgb(224, 108, 117) | #e06c75 |
+" |--------------+--------------------+---------|
+" | Dark Red | rgb(190, 80, 70) | #be5046 |
+" |--------------+--------------------+---------|
+" | Green | rgb(152, 195, 121) | #98c379 |
+" |--------------+--------------------+---------|
+" | Light Yellow | rgb(229, 192, 123) | #e5c07b |
+" |--------------+--------------------+---------|
+" | Dark Yellow | rgb(209, 154, 102) | #d19a66 |
+" |--------------+--------------------+---------|
+" | Blue | rgb(97, 175, 239) | #61afef |
+" |--------------+--------------------+---------|
+" | Magenta | rgb(198, 120, 221) | #c678dd |
+" |--------------+--------------------+---------|
+" | Cyan | rgb(86, 182, 194) | #56b6c2 |
+" |--------------+--------------------+---------|
+" | Gutter Grey | rgb(76, 82, 99) | #4b5263 |
+" |--------------+--------------------+---------|
+" | Comment Grey | rgb(92, 99, 112) | #5c6370 |
+" +---------------------------------------------+
+
+" }}}
+
+" Initialization {{{
+
+highlight clear
+
+if exists("syntax_on")
+ syntax reset
+endif
+
+set t_Co=256
+
+let g:colors_name="onedark"
+
+" Set to "256" for 256-color terminals, or
+" set to "16" to use your terminal emulator's native colors
+" (a 16-color palette for this color scheme is available; see
+" < https://github.com/joshdick/onedark.vim/blob/main/README.md >
+" for more information.)
+if !exists("g:onedark_termcolors")
+ let g:onedark_termcolors = 256
+endif
+
+" Not all terminals support italics properly. If yours does, opt-in.
+if !exists("g:onedark_terminal_italics")
+ let g:onedark_terminal_italics = 0
+endif
+
+" This function is based on one from FlatColor: https://github.com/MaxSt/FlatColor/
+" Which in turn was based on one found in hemisu: https://github.com/noahfrederick/vim-hemisu/
+let s:group_colors = {} " Cache of default highlight group settings, for later reference via `onedark#extend_highlight`
+function! s:h(group, style, ...)
+ if (a:0 > 0) " Will be true if we got here from onedark#extend_highlight
+ let s:highlight = s:group_colors[a:group]
+ for style_type in ["fg", "bg", "sp"]
+ if (has_key(a:style, style_type))
+ let l:default_style = (has_key(s:highlight, style_type) ? copy(s:highlight[style_type]) : { "cterm16": "NONE", "cterm": "NONE", "gui": "NONE" })
+ let s:highlight[style_type] = extend(l:default_style, a:style[style_type])
+ endif
+ endfor
+ if (has_key(a:style, "gui"))
+ let s:highlight.gui = a:style.gui
+ endif
+ if (has_key(a:style, "cterm"))
+ let s:highlight.cterm = a:style.cterm
+ endif
+ else
+ let s:highlight = a:style
+ let s:group_colors[a:group] = s:highlight " Cache default highlight group settings
+ endif
+
+ if g:onedark_terminal_italics == 0
+ if has_key(s:highlight, "cterm") && s:highlight["cterm"] == "italic"
+ unlet s:highlight.cterm
+ endif
+ if has_key(s:highlight, "gui") && s:highlight["gui"] == "italic"
+ unlet s:highlight.gui
+ endif
+ endif
+
+ if g:onedark_termcolors == 16
+ let l:ctermfg = (has_key(s:highlight, "fg") ? s:highlight.fg.cterm16 : "NONE")
+ let l:ctermbg = (has_key(s:highlight, "bg") ? s:highlight.bg.cterm16 : "NONE")
+ else
+ let l:ctermfg = (has_key(s:highlight, "fg") ? s:highlight.fg.cterm : "NONE")
+ let l:ctermbg = (has_key(s:highlight, "bg") ? s:highlight.bg.cterm : "NONE")
+ endif
+
+ execute "highlight" a:group
+ \ "guifg=" (has_key(s:highlight, "fg") ? s:highlight.fg.gui : "NONE")
+ \ "guibg=" (has_key(s:highlight, "bg") ? s:highlight.bg.gui : "NONE")
+ \ "guisp=" (has_key(s:highlight, "sp") ? s:highlight.sp.gui : "NONE")
+ \ "gui=" (has_key(s:highlight, "gui") ? s:highlight.gui : "NONE")
+ \ "ctermfg=" . l:ctermfg
+ \ "ctermbg=" . l:ctermbg
+ \ "cterm=" (has_key(s:highlight, "cterm") ? s:highlight.cterm : "NONE")
+endfunction
+
+" public {{{
+
+function! onedark#set_highlight(group, style)
+ call s:h(a:group, a:style)
+endfunction
+
+function! onedark#extend_highlight(group, style)
+ call s:h(a:group, a:style, 1)
+endfunction
+
+" }}}
+
+" }}}
+
+" Color Variables {{{
+
+let s:colors = onedark#GetColors()
+
+let s:red = s:colors.red
+let s:dark_red = s:colors.dark_red
+let s:green = s:colors.green
+let s:yellow = s:colors.yellow
+let s:dark_yellow = s:colors.dark_yellow
+let s:blue = s:colors.blue
+let s:purple = s:colors.purple
+let s:cyan = s:colors.cyan
+let s:white = s:colors.white
+let s:black = s:colors.black
+let s:foreground = s:colors.foreground
+let s:background = s:colors.background
+let s:comment_grey = s:colors.comment_grey
+let s:gutter_fg_grey = s:colors.gutter_fg_grey
+let s:cursor_grey = s:colors.cursor_grey
+let s:visual_grey = s:colors.visual_grey
+let s:menu_grey = s:colors.menu_grey
+let s:special_grey = s:colors.special_grey
+let s:vertsplit = s:colors.vertsplit
+
+" }}}
+
+" Terminal Colors {{{
+
+if has('nvim')
+ let g:terminal_color_0 = s:black.gui
+ let g:terminal_color_1 = s:red.gui
+ let g:terminal_color_2 = s:green.gui
+ let g:terminal_color_3 = s:yellow.gui
+ let g:terminal_color_4 = s:blue.gui
+ let g:terminal_color_5 = s:purple.gui
+ let g:terminal_color_6 = s:cyan.gui
+ let g:terminal_color_7 = s:comment_grey.gui
+ let g:terminal_color_8 = s:visual_grey.gui
+ let g:terminal_color_9 = s:red.gui
+ let g:terminal_color_10 = s:green.gui
+ let g:terminal_color_11 = s:yellow.gui
+ let g:terminal_color_12 = s:blue.gui
+ let g:terminal_color_13 = s:purple.gui
+ let g:terminal_color_14 = s:cyan.gui
+ let g:terminal_color_15 = s:white.gui
+else
+ let g:terminal_ansi_colors = [
+ \ s:black.gui, s:red.gui, s:green.gui, s:yellow.gui,
+ \ s:blue.gui, s:purple.gui, s:cyan.gui, s:comment_grey.gui,
+ \ s:visual_grey.gui, s:red.gui, s:green.gui, s:yellow.gui,
+ \ s:blue.gui, s:purple.gui, s:cyan.gui, s:white.gui
+ \]
+endif
+
+" }}}
+
+" Syntax Groups (descriptions and ordering from `:h w18`) {{{
+
+call s:h("Comment", { "fg": s:comment_grey, "gui": "italic", "cterm": "italic" }) " any comment
+call s:h("Constant", { "fg": s:cyan }) " any constant
+call s:h("String", { "fg": s:green }) " a string constant: "this is a string"
+call s:h("Character", { "fg": s:green }) " a character constant: 'c', '\n'
+call s:h("Number", { "fg": s:dark_yellow }) " a number constant: 234, 0xff
+call s:h("Boolean", { "fg": s:dark_yellow }) " a boolean constant: TRUE, false
+call s:h("Float", { "fg": s:dark_yellow }) " a floating point constant: 2.3e10
+call s:h("Identifier", { "fg": s:red }) " any variable name
+call s:h("Function", { "fg": s:blue }) " function name (also: methods for classes)
+call s:h("Statement", { "fg": s:purple }) " any statement
+call s:h("Conditional", { "fg": s:purple }) " if, then, else, endif, switch, etc.
+call s:h("Repeat", { "fg": s:purple }) " for, do, while, etc.
+call s:h("Label", { "fg": s:purple }) " case, default, etc.
+call s:h("Operator", { "fg": s:purple }) " sizeof", "+", "*", etc.
+call s:h("Keyword", { "fg": s:purple }) " any other keyword
+call s:h("Exception", { "fg": s:purple }) " try, catch, throw
+call s:h("PreProc", { "fg": s:yellow }) " generic Preprocessor
+call s:h("Include", { "fg": s:blue }) " preprocessor #include
+call s:h("Define", { "fg": s:purple }) " preprocessor #define
+call s:h("Macro", { "fg": s:purple }) " same as Define
+call s:h("PreCondit", { "fg": s:yellow }) " preprocessor #if, #else, #endif, etc.
+call s:h("Type", { "fg": s:yellow }) " int, long, char, etc.
+call s:h("StorageClass", { "fg": s:yellow }) " static, register, volatile, etc.
+call s:h("Structure", { "fg": s:yellow }) " struct, union, enum, etc.
+call s:h("Typedef", { "fg": s:yellow }) " A typedef
+call s:h("Special", { "fg": s:blue }) " any special symbol
+call s:h("SpecialChar", { "fg": s:dark_yellow }) " special character in a constant
+call s:h("Tag", {}) " you can use CTRL-] on this
+call s:h("Delimiter", {}) " character that needs attention
+call s:h("SpecialComment", { "fg": s:comment_grey }) " special things inside a comment
+call s:h("Debug", {}) " debugging statements
+call s:h("Underlined", { "gui": "underline", "cterm": "underline" }) " text that stands out, HTML links
+call s:h("Ignore", {}) " left blank, hidden
+call s:h("Error", { "fg": s:red }) " any erroneous construct
+call s:h("Todo", { "fg": s:purple }) " anything that needs extra attention; mostly the keywords TODO FIXME and XXX
+
+" }}}
+
+" Highlighting Groups (descriptions and ordering from `:h highlight-groups`) {{{
+call s:h("ColorColumn", { "bg": s:cursor_grey }) " used for the columns set with 'colorcolumn'
+call s:h("Conceal", {}) " placeholder characters substituted for concealed text (see 'conceallevel')
+call s:h("Cursor", { "fg": s:black, "bg": s:blue }) " the character under the cursor
+call s:h("CursorIM", {}) " like Cursor, but used when in IME mode
+call s:h("CursorColumn", { "bg": s:cursor_grey }) " the screen column that the cursor is in when 'cursorcolumn' is set
+if &diff
+ " Don't change the background color in diff mode
+ call s:h("CursorLine", { "gui": "underline" }) " the screen line that the cursor is in when 'cursorline' is set
+else
+ call s:h("CursorLine", { "bg": s:cursor_grey }) " the screen line that the cursor is in when 'cursorline' is set
+endif
+call s:h("Directory", { "fg": s:blue }) " directory names (and other special names in listings)
+call s:h("DiffAdd", { "bg": s:green, "fg": s:black }) " diff mode: Added line
+call s:h("DiffChange", { "fg": s:yellow, "gui": "underline", "cterm": "underline" }) " diff mode: Changed line
+call s:h("DiffDelete", { "bg": s:red, "fg": s:black }) " diff mode: Deleted line
+call s:h("DiffText", { "bg": s:yellow, "fg": s:black }) " diff mode: Changed text within a changed line
+if get(g:, 'onedark_hide_endofbuffer', 0)
+ " If enabled, will style end-of-buffer filler lines (~) to appear to be hidden.
+ call s:h("EndOfBuffer", { "fg": s:black }) " filler lines (~) after the last line in the buffer
+endif
+call s:h("ErrorMsg", { "fg": s:red }) " error messages on the command line
+call s:h("VertSplit", { "fg": s:vertsplit }) " the column separating vertically split windows
+call s:h("Folded", { "fg": s:comment_grey }) " line used for closed folds
+call s:h("FoldColumn", {}) " 'foldcolumn'
+call s:h("SignColumn", {}) " column where signs are displayed
+call s:h("IncSearch", { "fg": s:yellow, "bg": s:comment_grey }) " 'incsearch' highlighting; also used for the text replaced with ":s///c"
+call s:h("LineNr", { "fg": s:gutter_fg_grey }) " Line number for ":number" and ":#" commands, and when 'number' or 'relativenumber' option is set.
+call s:h("CursorLineNr", {}) " Like LineNr when 'cursorline' or 'relativenumber' is set for the cursor line.
+call s:h("MatchParen", { "fg": s:blue, "gui": "underline", "cterm": "underline" }) " The character under the cursor or just before it, if it is a paired bracket, and its match.
+call s:h("ModeMsg", {}) " 'showmode' message (e.g., "-- INSERT --")
+call s:h("MoreMsg", {}) " more-prompt
+call s:h("NonText", { "fg": s:special_grey }) " '~' and '@' at the end of the window, characters from 'showbreak' and other characters that do not really exist in the text (e.g., ">" displayed when a double-wide character doesn't fit at the end of the line).
+call s:h("Normal", { "fg": s:foreground, "bg": s:background }) " normal text
+call s:h("Pmenu", { "fg": s:white, "bg": s:menu_grey }) " Popup menu: normal item.
+call s:h("PmenuSel", { "fg": s:cursor_grey, "bg": s:blue }) " Popup menu: selected item.
+call s:h("PmenuSbar", { "bg": s:cursor_grey }) " Popup menu: scrollbar.
+call s:h("PmenuThumb", { "bg": s:white }) " Popup menu: Thumb of the scrollbar.
+call s:h("Question", { "fg": s:purple }) " hit-enter prompt and yes/no questions
+call s:h("QuickFixLine", { "fg": s:black, "bg": s:yellow }) " Current quickfix item in the quickfix window.
+call s:h("Search", { "fg": s:black, "bg": s:yellow }) " Last search pattern highlighting (see 'hlsearch'). Also used for similar items that need to stand out.
+call s:h("SpecialKey", { "fg": s:special_grey }) " Meta and special keys listed with ":map", also for text used to show unprintable characters in the text, 'listchars'. Generally: text that is displayed differently from what it really is.
+call s:h("SpellBad", { "fg": s:red, "gui": "underline", "cterm": "underline" }) " Word that is not recognized by the spellchecker. This will be combined with the highlighting used otherwise.
+call s:h("SpellCap", { "fg": s:dark_yellow }) " Word that should start with a capital. This will be combined with the highlighting used otherwise.
+call s:h("SpellLocal", { "fg": s:dark_yellow }) " Word that is recognized by the spellchecker as one that is used in another region. This will be combined with the highlighting used otherwise.
+call s:h("SpellRare", { "fg": s:dark_yellow }) " Word that is recognized by the spellchecker as one that is hardly ever used. spell This will be combined with the highlighting used otherwise.
+call s:h("StatusLine", { "fg": s:white, "bg": s:cursor_grey }) " status line of current window
+call s:h("StatusLineNC", { "fg": s:comment_grey }) " status lines of not-current windows Note: if this is equal to "StatusLine" Vim will use "^^^" in the status line of the current window.
+call s:h("StatusLineTerm", { "fg": s:white, "bg": s:cursor_grey }) " status line of current :terminal window
+call s:h("StatusLineTermNC", { "fg": s:comment_grey }) " status line of non-current :terminal window
+call s:h("TabLine", { "fg": s:comment_grey }) " tab pages line, not active tab page label
+call s:h("TabLineFill", {}) " tab pages line, where there are no labels
+call s:h("TabLineSel", { "fg": s:white }) " tab pages line, active tab page label
+call s:h("Terminal", { "fg": s:white, "bg": s:black }) " terminal window (see terminal-size-color)
+call s:h("Title", { "fg": s:green }) " titles for output from ":set all", ":autocmd" etc.
+call s:h("Visual", { "bg": s:visual_grey }) " Visual mode selection
+call s:h("VisualNOS", { "bg": s:visual_grey }) " Visual mode selection when vim is "Not Owning the Selection". Only X11 Gui's gui-x11 and xterm-clipboard supports this.
+call s:h("WarningMsg", { "fg": s:yellow }) " warning messages
+call s:h("WildMenu", { "fg": s:black, "bg": s:blue }) " current match in 'wildmenu' completion
+
+" }}}
+
+" Termdebug highlighting for Vim 8.1+ {{{
+
+" See `:h hl-debugPC` and `:h hl-debugBreakpoint`.
+call s:h("debugPC", { "bg": s:special_grey }) " the current position
+call s:h("debugBreakpoint", { "fg": s:black, "bg": s:red }) " a breakpoint
+
+" }}}
+
+" Language-Specific Highlighting {{{
+
+" CSS
+call s:h("cssAttrComma", { "fg": s:purple })
+call s:h("cssAttributeSelector", { "fg": s:green })
+call s:h("cssBraces", { "fg": s:white })
+call s:h("cssClassName", { "fg": s:dark_yellow })
+call s:h("cssClassNameDot", { "fg": s:dark_yellow })
+call s:h("cssDefinition", { "fg": s:purple })
+call s:h("cssFontAttr", { "fg": s:dark_yellow })
+call s:h("cssFontDescriptor", { "fg": s:purple })
+call s:h("cssFunctionName", { "fg": s:blue })
+call s:h("cssIdentifier", { "fg": s:blue })
+call s:h("cssImportant", { "fg": s:purple })
+call s:h("cssInclude", { "fg": s:white })
+call s:h("cssIncludeKeyword", { "fg": s:purple })
+call s:h("cssMediaType", { "fg": s:dark_yellow })
+call s:h("cssProp", { "fg": s:white })
+call s:h("cssPseudoClassId", { "fg": s:dark_yellow })
+call s:h("cssSelectorOp", { "fg": s:purple })
+call s:h("cssSelectorOp2", { "fg": s:purple })
+call s:h("cssTagName", { "fg": s:red })
+
+" Fish Shell
+call s:h("fishKeyword", { "fg": s:purple })
+call s:h("fishConditional", { "fg": s:purple })
+
+" Go
+call s:h("goDeclaration", { "fg": s:purple })
+call s:h("goBuiltins", { "fg": s:cyan })
+call s:h("goFunctionCall", { "fg": s:blue })
+call s:h("goVarDefs", { "fg": s:red })
+call s:h("goVarAssign", { "fg": s:red })
+call s:h("goVar", { "fg": s:purple })
+call s:h("goConst", { "fg": s:purple })
+call s:h("goType", { "fg": s:yellow })
+call s:h("goTypeName", { "fg": s:yellow })
+call s:h("goDeclType", { "fg": s:cyan })
+call s:h("goTypeDecl", { "fg": s:purple })
+
+" HTML (keep consistent with Markdown, below)
+call s:h("htmlArg", { "fg": s:dark_yellow })
+call s:h("htmlBold", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("htmlBoldItalic", { "fg": s:green, "gui": "bold,italic", "cterm": "bold,italic" })
+call s:h("htmlEndTag", { "fg": s:white })
+call s:h("htmlH1", { "fg": s:red })
+call s:h("htmlH2", { "fg": s:red })
+call s:h("htmlH3", { "fg": s:red })
+call s:h("htmlH4", { "fg": s:red })
+call s:h("htmlH5", { "fg": s:red })
+call s:h("htmlH6", { "fg": s:red })
+call s:h("htmlItalic", { "fg": s:purple, "gui": "italic", "cterm": "italic" })
+call s:h("htmlLink", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+call s:h("htmlSpecialChar", { "fg": s:dark_yellow })
+call s:h("htmlSpecialTagName", { "fg": s:red })
+call s:h("htmlTag", { "fg": s:white })
+call s:h("htmlTagN", { "fg": s:red })
+call s:h("htmlTagName", { "fg": s:red })
+call s:h("htmlTitle", { "fg": s:white })
+
+" JavaScript
+call s:h("javaScriptBraces", { "fg": s:white })
+call s:h("javaScriptFunction", { "fg": s:purple })
+call s:h("javaScriptIdentifier", { "fg": s:purple })
+call s:h("javaScriptNull", { "fg": s:dark_yellow })
+call s:h("javaScriptNumber", { "fg": s:dark_yellow })
+call s:h("javaScriptRequire", { "fg": s:cyan })
+call s:h("javaScriptReserved", { "fg": s:purple })
+" https://github.com/pangloss/vim-javascript
+call s:h("jsArrowFunction", { "fg": s:purple })
+call s:h("jsClassKeyword", { "fg": s:purple })
+call s:h("jsClassMethodType", { "fg": s:purple })
+call s:h("jsDocParam", { "fg": s:blue })
+call s:h("jsDocTags", { "fg": s:purple })
+call s:h("jsExport", { "fg": s:purple })
+call s:h("jsExportDefault", { "fg": s:purple })
+call s:h("jsExtendsKeyword", { "fg": s:purple })
+call s:h("jsFrom", { "fg": s:purple })
+call s:h("jsFuncCall", { "fg": s:blue })
+call s:h("jsFunction", { "fg": s:purple })
+call s:h("jsGenerator", { "fg": s:yellow })
+call s:h("jsGlobalObjects", { "fg": s:yellow })
+call s:h("jsImport", { "fg": s:purple })
+call s:h("jsModuleAs", { "fg": s:purple })
+call s:h("jsModuleWords", { "fg": s:purple })
+call s:h("jsModules", { "fg": s:purple })
+call s:h("jsNull", { "fg": s:dark_yellow })
+call s:h("jsOperator", { "fg": s:purple })
+call s:h("jsStorageClass", { "fg": s:purple })
+call s:h("jsSuper", { "fg": s:red })
+call s:h("jsTemplateBraces", { "fg": s:dark_red })
+call s:h("jsTemplateVar", { "fg": s:green })
+call s:h("jsThis", { "fg": s:red })
+call s:h("jsUndefined", { "fg": s:dark_yellow })
+" https://github.com/othree/yajs.vim
+call s:h("javascriptArrowFunc", { "fg": s:purple })
+call s:h("javascriptClassExtends", { "fg": s:purple })
+call s:h("javascriptClassKeyword", { "fg": s:purple })
+call s:h("javascriptDocNotation", { "fg": s:purple })
+call s:h("javascriptDocParamName", { "fg": s:blue })
+call s:h("javascriptDocTags", { "fg": s:purple })
+call s:h("javascriptEndColons", { "fg": s:white })
+call s:h("javascriptExport", { "fg": s:purple })
+call s:h("javascriptFuncArg", { "fg": s:white })
+call s:h("javascriptFuncKeyword", { "fg": s:purple })
+call s:h("javascriptIdentifier", { "fg": s:red })
+call s:h("javascriptImport", { "fg": s:purple })
+call s:h("javascriptMethodName", { "fg": s:white })
+call s:h("javascriptObjectLabel", { "fg": s:white })
+call s:h("javascriptOpSymbol", { "fg": s:cyan })
+call s:h("javascriptOpSymbols", { "fg": s:cyan })
+call s:h("javascriptPropertyName", { "fg": s:green })
+call s:h("javascriptTemplateSB", { "fg": s:dark_red })
+call s:h("javascriptVariable", { "fg": s:purple })
+
+" JSON
+call s:h("jsonCommentError", { "fg": s:white })
+call s:h("jsonKeyword", { "fg": s:red })
+call s:h("jsonBoolean", { "fg": s:dark_yellow })
+call s:h("jsonNumber", { "fg": s:dark_yellow })
+call s:h("jsonQuote", { "fg": s:white })
+call s:h("jsonMissingCommaError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonNoQuotesError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonNumError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonString", { "fg": s:green })
+call s:h("jsonStringSQError", { "fg": s:red, "gui": "reverse" })
+call s:h("jsonSemicolonError", { "fg": s:red, "gui": "reverse" })
+
+" LESS
+call s:h("lessVariable", { "fg": s:purple })
+call s:h("lessAmpersandChar", { "fg": s:white })
+call s:h("lessClass", { "fg": s:dark_yellow })
+
+" Markdown (keep consistent with HTML, above)
+call s:h("markdownBlockquote", { "fg": s:comment_grey })
+call s:h("markdownBold", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("markdownBoldItalic", { "fg": s:green, "gui": "bold,italic", "cterm": "bold,italic" })
+call s:h("markdownCode", { "fg": s:green })
+call s:h("markdownCodeBlock", { "fg": s:green })
+call s:h("markdownCodeDelimiter", { "fg": s:green })
+call s:h("markdownH1", { "fg": s:red })
+call s:h("markdownH2", { "fg": s:red })
+call s:h("markdownH3", { "fg": s:red })
+call s:h("markdownH4", { "fg": s:red })
+call s:h("markdownH5", { "fg": s:red })
+call s:h("markdownH6", { "fg": s:red })
+call s:h("markdownHeadingDelimiter", { "fg": s:red })
+call s:h("markdownHeadingRule", { "fg": s:comment_grey })
+call s:h("markdownId", { "fg": s:purple })
+call s:h("markdownIdDeclaration", { "fg": s:blue })
+call s:h("markdownIdDelimiter", { "fg": s:purple })
+call s:h("markdownItalic", { "fg": s:purple, "gui": "italic", "cterm": "italic" })
+call s:h("markdownLinkDelimiter", { "fg": s:purple })
+call s:h("markdownLinkText", { "fg": s:blue })
+call s:h("markdownListMarker", { "fg": s:red })
+call s:h("markdownOrderedListMarker", { "fg": s:red })
+call s:h("markdownRule", { "fg": s:comment_grey })
+call s:h("markdownUrl", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+
+" Perl
+call s:h("perlFiledescRead", { "fg": s:green })
+call s:h("perlFunction", { "fg": s:purple })
+call s:h("perlMatchStartEnd",{ "fg": s:blue })
+call s:h("perlMethod", { "fg": s:purple })
+call s:h("perlPOD", { "fg": s:comment_grey })
+call s:h("perlSharpBang", { "fg": s:comment_grey })
+call s:h("perlSpecialString",{ "fg": s:dark_yellow })
+call s:h("perlStatementFiledesc", { "fg": s:red })
+call s:h("perlStatementFlow",{ "fg": s:red })
+call s:h("perlStatementInclude", { "fg": s:purple })
+call s:h("perlStatementScalar",{ "fg": s:purple })
+call s:h("perlStatementStorage", { "fg": s:purple })
+call s:h("perlSubName",{ "fg": s:yellow })
+call s:h("perlVarPlain",{ "fg": s:blue })
+
+" PHP
+call s:h("phpVarSelector", { "fg": s:red })
+call s:h("phpOperator", { "fg": s:white })
+call s:h("phpParent", { "fg": s:white })
+call s:h("phpMemberSelector", { "fg": s:white })
+call s:h("phpType", { "fg": s:purple })
+call s:h("phpKeyword", { "fg": s:purple })
+call s:h("phpClass", { "fg": s:yellow })
+call s:h("phpUseClass", { "fg": s:white })
+call s:h("phpUseAlias", { "fg": s:white })
+call s:h("phpInclude", { "fg": s:purple })
+call s:h("phpClassExtends", { "fg": s:green })
+call s:h("phpDocTags", { "fg": s:white })
+call s:h("phpFunction", { "fg": s:blue })
+call s:h("phpFunctions", { "fg": s:cyan })
+call s:h("phpMethodsVar", { "fg": s:dark_yellow })
+call s:h("phpMagicConstants", { "fg": s:dark_yellow })
+call s:h("phpSuperglobals", { "fg": s:red })
+call s:h("phpConstants", { "fg": s:dark_yellow })
+
+" Ruby
+call s:h("rubyBlockParameter", { "fg": s:red})
+call s:h("rubyBlockParameterList", { "fg": s:red })
+call s:h("rubyClass", { "fg": s:purple})
+call s:h("rubyConstant", { "fg": s:yellow})
+call s:h("rubyControl", { "fg": s:purple })
+call s:h("rubyEscape", { "fg": s:red})
+call s:h("rubyFunction", { "fg": s:blue})
+call s:h("rubyGlobalVariable", { "fg": s:red})
+call s:h("rubyInclude", { "fg": s:blue})
+call s:h("rubyIncluderubyGlobalVariable", { "fg": s:red})
+call s:h("rubyInstanceVariable", { "fg": s:red})
+call s:h("rubyInterpolation", { "fg": s:cyan })
+call s:h("rubyInterpolationDelimiter", { "fg": s:red })
+call s:h("rubyInterpolationDelimiter", { "fg": s:red})
+call s:h("rubyRegexp", { "fg": s:cyan})
+call s:h("rubyRegexpDelimiter", { "fg": s:cyan})
+call s:h("rubyStringDelimiter", { "fg": s:green})
+call s:h("rubySymbol", { "fg": s:cyan})
+
+" Sass
+" https://github.com/tpope/vim-haml
+call s:h("sassAmpersand", { "fg": s:red })
+call s:h("sassClass", { "fg": s:dark_yellow })
+call s:h("sassControl", { "fg": s:purple })
+call s:h("sassExtend", { "fg": s:purple })
+call s:h("sassFor", { "fg": s:white })
+call s:h("sassFunction", { "fg": s:cyan })
+call s:h("sassId", { "fg": s:blue })
+call s:h("sassInclude", { "fg": s:purple })
+call s:h("sassMedia", { "fg": s:purple })
+call s:h("sassMediaOperators", { "fg": s:white })
+call s:h("sassMixin", { "fg": s:purple })
+call s:h("sassMixinName", { "fg": s:blue })
+call s:h("sassMixing", { "fg": s:purple })
+call s:h("sassVariable", { "fg": s:purple })
+" https://github.com/cakebaker/scss-syntax.vim
+call s:h("scssExtend", { "fg": s:purple })
+call s:h("scssImport", { "fg": s:purple })
+call s:h("scssInclude", { "fg": s:purple })
+call s:h("scssMixin", { "fg": s:purple })
+call s:h("scssSelectorName", { "fg": s:dark_yellow })
+call s:h("scssVariable", { "fg": s:purple })
+
+" TeX
+call s:h("texStatement", { "fg": s:purple })
+call s:h("texSubscripts", { "fg": s:dark_yellow })
+call s:h("texSuperscripts", { "fg": s:dark_yellow })
+call s:h("texTodo", { "fg": s:dark_red })
+call s:h("texBeginEnd", { "fg": s:purple })
+call s:h("texBeginEndName", { "fg": s:blue })
+call s:h("texMathMatcher", { "fg": s:blue })
+call s:h("texMathDelim", { "fg": s:blue })
+call s:h("texDelimiter", { "fg": s:dark_yellow })
+call s:h("texSpecialChar", { "fg": s:dark_yellow })
+call s:h("texCite", { "fg": s:blue })
+call s:h("texRefZone", { "fg": s:blue })
+
+" TypeScript
+call s:h("typescriptReserved", { "fg": s:purple })
+call s:h("typescriptEndColons", { "fg": s:white })
+call s:h("typescriptBraces", { "fg": s:white })
+
+" XML
+call s:h("xmlAttrib", { "fg": s:dark_yellow })
+call s:h("xmlEndTag", { "fg": s:red })
+call s:h("xmlTag", { "fg": s:red })
+call s:h("xmlTagName", { "fg": s:red })
+
+" }}}
+
+" Plugin Highlighting {{{
+
+" airblade/vim-gitgutter
+call s:h("GitGutterAdd", { "fg": s:green })
+call s:h("GitGutterChange", { "fg": s:yellow })
+call s:h("GitGutterDelete", { "fg": s:red })
+
+" dense-analysis/ale
+call s:h("ALEError", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+call s:h("ALEWarning", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+call s:h("ALEInfo", { "gui": "underline", "cterm": "underline" })
+call s:h("ALEErrorSign", { "fg": s:red })
+call s:h("ALEWarningSign", { "fg": s:yellow })
+call s:h("ALEInfoSign", { })
+
+" easymotion/vim-easymotion
+call s:h("EasyMotionTarget", { "fg": s:red, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionTarget2First", { "fg": s:yellow, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionTarget2Second", { "fg": s:dark_yellow, "gui": "bold", "cterm": "bold" })
+call s:h("EasyMotionShade", { "fg": s:comment_grey })
+
+" lewis6991/gitsigns.nvim
+hi link GitSignsAdd GitGutterAdd
+hi link GitSignsChange GitGutterChange
+hi link GitSignsDelete GitGutterDelete
+
+" mhinz/vim-signify
+hi link SignifySignAdd GitGutterAdd
+hi link SignifySignChange GitGutterChange
+hi link SignifySignDelete GitGutterDelete
+
+" neoclide/coc.nvim
+call s:h("CocErrorSign", { "fg": s:red })
+call s:h("CocWarningSign", { "fg": s:yellow })
+call s:h("CocInfoSign", { "fg": s:blue })
+call s:h("CocHintSign", { "fg": s:cyan })
+call s:h("CocFadeOut", { "fg": s:comment_grey })
+" https://github.com/joshdick/onedark.vim/issues/313
+highlight! link CocMenuSel PmenuSel
+
+" neomake/neomake
+call s:h("NeomakeErrorSign", { "fg": s:red })
+call s:h("NeomakeWarningSign", { "fg": s:yellow })
+call s:h("NeomakeInfoSign", { "fg": s:blue })
+
+" plasticboy/vim-markdown (keep consistent with Markdown, above)
+call s:h("mkdDelimiter", { "fg": s:purple })
+call s:h("mkdHeading", { "fg": s:red })
+call s:h("mkdLink", { "fg": s:blue })
+call s:h("mkdURL", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+
+" prabirshrestha/vim-lsp
+call s:h("LspErrorText", { "fg": s:red })
+call s:h("LspWarningText", { "fg": s:yellow })
+call s:h("LspInformationText", { "fg":s:blue })
+call s:h("LspHintText", { "fg":s:cyan })
+call s:h("LspErrorHighlight", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+call s:h("LspWarningHighlight", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+call s:h("LspInformationHighlight", { "fg":s:blue, "gui": "underline", "cterm": "underline" })
+call s:h("LspHintHighlight", { "fg":s:cyan, "gui": "underline", "cterm": "underline" })
+
+" tpope/vim-fugitive
+call s:h("diffAdded", { "fg": s:green })
+call s:h("diffRemoved", { "fg": s:red })
+
+" }}}
+
+" Git Highlighting {{{
+
+call s:h("gitcommitComment", { "fg": s:comment_grey })
+call s:h("gitcommitUnmerged", { "fg": s:green })
+call s:h("gitcommitOnBranch", {})
+call s:h("gitcommitBranch", { "fg": s:purple })
+call s:h("gitcommitDiscardedType", { "fg": s:red })
+call s:h("gitcommitSelectedType", { "fg": s:green })
+call s:h("gitcommitHeader", {})
+call s:h("gitcommitUntrackedFile", { "fg": s:cyan })
+call s:h("gitcommitDiscardedFile", { "fg": s:red })
+call s:h("gitcommitSelectedFile", { "fg": s:green })
+call s:h("gitcommitUnmergedFile", { "fg": s:yellow })
+call s:h("gitcommitFile", {})
+call s:h("gitcommitSummary", { "fg": s:white })
+call s:h("gitcommitOverflow", { "fg": s:red })
+hi link gitcommitNoBranch gitcommitBranch
+hi link gitcommitUntracked gitcommitComment
+hi link gitcommitDiscarded gitcommitComment
+hi link gitcommitSelected gitcommitComment
+hi link gitcommitDiscardedArrow gitcommitDiscardedFile
+hi link gitcommitSelectedArrow gitcommitSelectedFile
+hi link gitcommitUnmergedArrow gitcommitUnmergedFile
+
+" }}}
+
+" Neovim-Specific Highlighting {{{
+
+if has("nvim")
+ " Neovim terminal colors {{{
+ let g:terminal_color_0 = s:black.gui
+ let g:terminal_color_1 = s:red.gui
+ let g:terminal_color_2 = s:green.gui
+ let g:terminal_color_3 = s:yellow.gui
+ let g:terminal_color_4 = s:blue.gui
+ let g:terminal_color_5 = s:purple.gui
+ let g:terminal_color_6 = s:cyan.gui
+ let g:terminal_color_7 = s:white.gui
+ let g:terminal_color_8 = s:visual_grey.gui
+ let g:terminal_color_9 = s:dark_red.gui
+ let g:terminal_color_10 = s:green.gui " No dark version
+ let g:terminal_color_11 = s:dark_yellow.gui
+ let g:terminal_color_12 = s:blue.gui " No dark version
+ let g:terminal_color_13 = s:purple.gui " No dark version
+ let g:terminal_color_14 = s:cyan.gui " No dark version
+ let g:terminal_color_15 = s:comment_grey.gui
+ let g:terminal_color_background = s:background.gui
+ let g:terminal_color_foreground = s:foreground.gui
+ " }}}
+
+ " Neovim Diagnostics {{{
+ call s:h("DiagnosticError", { "fg": s:red })
+ call s:h("DiagnosticWarn", { "fg": s:yellow })
+ call s:h("DiagnosticInfo", { "fg": s:blue })
+ call s:h("DiagnosticHint", { "fg": s:cyan })
+ call s:h("DiagnosticUnderlineError", { "fg": s:red, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineWarn", { "fg": s:yellow, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineInfo", { "fg": s:blue, "gui": "underline", "cterm": "underline" })
+ call s:h("DiagnosticUnderlineHint", { "fg": s:cyan, "gui": "underline", "cterm": "underline" })
+ " }}}
+
+ " Neovim LSP (for versions < 0.5.1) {{{
+ hi link LspDiagnosticsDefaultError DiagnosticError
+ hi link LspDiagnosticsDefaultWarning DiagnosticWarn
+ hi link LspDiagnosticsDefaultInformation DiagnosticInfo
+ hi link LspDiagnosticsDefaultHint DiagnosticHint
+ hi link LspDiagnosticsUnderlineError DiagnosticUnderlineError
+ hi link LspDiagnosticsUnderlineWarning DiagnosticUnderlineWarn
+ hi link LspDiagnosticsUnderlineInformation DiagnosticUnderlineInfo
+ hi link LspDiagnosticsUnderlineHint DiagnosticUnderlineHint
+ " }}}
+endif
+
+" }}}
+
+" Must appear at the end of the file to work around this oddity:
+" https://groups.google.com/forum/#!msg/vim_dev/afPqwAFNdrU/nqh6tOM87QUJ
+set background=dark
diff --git a/.config/nvim/other/fzf.vim b/.config/nvim/other/fzf.vim
new file mode 100644
index 0000000..32cb18b
--- /dev/null
+++ b/.config/nvim/other/fzf.vim
@@ -0,0 +1,19 @@
+" --> Fzf
+let g:fzf_layout = { 'window': { 'width': 1, 'height': 1 } }
+command! -bang -nargs=? -complete=dir Files
+ \ call fzf#vim#files(<q-args>, {'options': ['--info=inline', '--preview', 'preview {}']}, <bang>0)
+
+" Mapping selecting mappings
+nmap <leader><tab> <plug>(fzf-maps-n)
+xmap <leader><tab> <plug>(fzf-maps-x)
+omap <leader><tab> <plug>(fzf-maps-o)
+
+" Insert mode completion
+imap <c-x><c-k> <plug>(fzf-complete-word)
+imap <c-x><c-f> <plug>(fzf-complete-path)
+imap <c-x><c-l> <plug>(fzf-complete-line)
+
+" Fzf keybindings
+nnoremap <leader>ff :Files<CR>
+nnoremap <leader>. :Files %:p:h<CR>
+
diff --git a/.config/nvim/other/learn.vim b/.config/nvim/other/learn.vim
new file mode 100644
index 0000000..c3272d9
--- /dev/null
+++ b/.config/nvim/other/learn.vim
@@ -0,0 +1,649 @@
+" ##############
+" Introduction
+" ##############
+"
+" Vim script (also called VimL) is the subset of Vim's ex-commands which
+" supplies a number of features one would expect from a scripting language,
+" such as values, variables, functions or loops. Always keep in the back of
+" your mind that a Vim script file is just a sequence of ex-commands. It is
+" very common for a script to mix programming-language features and raw
+" ex-commands.
+"
+" You can run Vim script directly by entering the commands in command-line mode
+" (press `:` to enter command-line mode), or you can write them to a file
+" (without the leading `:`) and source it in a running Vim instance (`:source
+" path/to/file`). Some files are sourced automatically as part of your
+" configuration (see |startup|). This guide assumes that you are familiar
+" with ex-commands and will only cover the scripting. Help topics to the
+" relevant manual sections are included.
+"
+" See |usr_41.txt| for the official introduction to Vim script. A comment is
+" anything following an unmatched `"` until the end of the line, and `|`
+" separates instructions (what `;` does in most other languages). References to
+" the manual as surrounded with `|`, such as |help.txt|.
+
+" This is a comment
+
+" The vertical line '|' (pipe) separates commands
+echo 'Hello' | echo 'world!'
+
+" Putting a comment after a command usually works
+pwd " Displays the current working directory
+
+" Except for some commands it does not; use the command delimiter before the
+" comment (echo assumes that the quotation mark begins a string)
+echo 'Hello world!' | " Displays a message
+
+" Line breaks can be escaped by placing a backslash as the first non-whitespace
+" character on the *following* line. Only works in script files, not on the
+" command line
+echo " Hello
+ \ world "
+
+echo [1,
+ \ 2]
+
+echo {
+ \ 'a': 1,
+ \ 'b': 2
+\}
+
+
+" #######
+" Types
+" #######
+"
+" For an overview of types see |E712|. For an overview of operators see
+" |expression-syntax|
+
+" Numbers (|expr-number|)
+" #######
+
+echo 123 | " Decimal
+echo 0b1111011 | " Binary
+echo 0173 | " Octal
+echo 0x7B | " Hexadecimal
+echo 123.0 | " Floating-point
+echo 1.23e2 | " Floating-point (scientific notation)
+
+" Note that an *integer* number with a leading `0` is in octal notation. The
+" usual arithmetic operations are supported.
+
+echo 1 + 2 | " Addition
+echo 1 - 2 | " Subtraction
+echo - 1 | " Negation (unary minus)
+echo + 1 | " Unary plus (does nothing really, but still legal)
+echo 1 * 2 | " Multiplication
+echo 1 / 2 | " Division
+echo 1 % 2 | " Modulo (remainder)
+
+" Booleans (|Boolean|)
+" ########
+"
+" The number 0 is false, every other number is true. Strings are implicitly
+" converted to numbers (see below). There are two pre-defined semantic
+" constants.
+
+echo v:true | " Evaluates to 1 or the string 'v:true'
+echo v:false | " Evaluates to 0 or the string 'v:false'
+
+" Boolean values can result from comparison of two objects.
+
+echo x == y | " Equality by value
+echo x != y | " Inequality
+echo x > y | " Greater than
+echo x >= y | " Greater than or equal
+echo x < y | " Smaller than
+echo x <= y | " Smaller than or equal
+echo x is y | " Instance identity (lists and dictionaries)
+echo x isnot y | " Instance non-identity (lists and dictionaries)
+
+" Strings are compared based on their alphanumerical ordering
+" echo 'a' < 'b'. Case sensitivity depends on the setting of 'ignorecase'
+"
+" Explicit case-sensitivity is specified by appending '#' (match case) or '?'
+" (ignore case) to the operator. Prefer explicitly case sensitivity when writing
+" portable scripts.
+
+echo 'a' < 'B' | " True or false depending on 'ignorecase'
+echo 'a' <? 'B' | " True
+echo 'a' <# 'B' | " False
+
+" Regular expression matching
+echo "hi" =~ "hello" | " Regular expression match, uses 'ignorecase'
+echo "hi" =~# "hello" | " Regular expression match, case sensitive
+echo "hi" =~? "hello" | " Regular expression match, case insensitive
+echo "hi" !~ "hello" | " Regular expression unmatch, use 'ignorecase'
+echo "hi" !~# "hello" | " Regular expression unmatch, case sensitive
+echo "hi" !~? "hello" | " Regular expression unmatch, case insensitive
+
+" Boolean operations are possible.
+
+echo v:true && v:false | " Logical AND
+echo v:true || v:false | " Logical OR
+echo ! v:true | " Logical NOT
+echo v:true ? 'yes' : 'no' | " Ternary operator
+
+
+" Strings (|String|)
+" #######
+"
+" An ordered zero-indexed sequence of bytes. The encoding of text into bytes
+" depends on the option |'encoding'|.
+
+" Literal constructors
+echo "Hello world\n" | " The last two characters stand for newline
+echo 'Hello world\n' | " The last two characters are literal
+echo 'Let''s go!' | " Two single quotes become one quote character
+
+" Single-quote strings take all characters are literal, except two single
+" quotes, which are taken to be a single quote in the string itself. See
+" |expr-quote| for all possible escape sequences.
+
+" String concatenation
+" The .. operator is preferred, but only supported in since Vim 8.1.1114
+echo 'Hello ' . 'world' | " String concatenation
+echo 'Hello ' .. 'world' | " String concatenation (new variant)
+
+" String indexing
+echo 'Hello'[0] | " First byte
+echo 'Hello'[1] | " Second byte
+echo 'Hellö'[4] | " Returns a byte, not the character 'ö'
+
+" Substrings (second index is inclusive)
+echo 'Hello'[:] | " Copy of entire string
+echo 'Hello'[1:3] | " Substring, second to fourth byte
+echo 'Hello'[1:-2] | " Substring until second to last byte
+echo 'Hello'[1:] | " Substring with starting index
+echo 'Hello'[:2] | " Substring with ending index
+echo 'Hello'[-2:] | " Substring relative to end of string
+
+" A negative index is relative to the end of the string. See
+" |string-functions| for all string-related functions.
+
+" Lists (|List|)
+" #####
+"
+" An ordered zero-indexed heterogeneous sequence of arbitrary Vim script
+" objects.
+
+" Literal constructor
+echo [] | " Empty list
+echo [1, 2, 'Hello'] | " List with elements
+echo [1, 2, 'Hello', ] | " Trailing comma permitted
+echo [[1, 2], 'Hello'] | " Lists can be nested arbitrarily
+
+" List concatenation
+echo [1, 2] + [3, 4] | " Creates a new list
+
+" List indexing, negative is relative to end of list (|list-index|)
+echo [1, 2, 3, 4][2] | " Third element
+echo [1, 2, 3, 4][-1] | " Last element
+
+" List slicing (|sublist|)
+echo [1, 2, 3, 4][:] | " Shallow copy of entire list
+echo [1, 2, 3, 4][:2] | " Sublist until third item (inclusive)
+echo [1, 2, 3, 4][2:] | " Sublist from third item (inclusive)
+echo [1, 2, 3, 4][:-2] | " Sublist until second-to-last item (inclusive)
+
+" All slicing operations create new lists. To modify a list in-place use list
+" functions (|list-functions|) or assign directly to an item (see below about
+" variables).
+
+
+" Dictionaries (|Dictionary|)
+" ############
+"
+" An unordered sequence of key-value pairs, keys are always strings (numbers
+" are implicitly converted to strings).
+
+" Dictionary literal
+echo {} | " Empty dictionary
+echo {'a': 1, 'b': 2} | " Dictionary literal
+echo {'a': 1, 'b': 2, } | " Trailing comma permitted
+echo {'x': {'a': 1, 'b': 2}} | " Nested dictionary
+
+" Indexing a dictionary
+echo {'a': 1, 'b': 2}['a'] | " Literal index
+echo {'a': 1, 'b': 2}.a | " Syntactic sugar for simple keys
+
+" See |dict-functions| for dictionary manipulation functions.
+
+
+" Funcref (|Funcref|)
+" #######
+"
+" Reference to a function, uses the function name as a string for construction.
+" When stored in a variable the name of the variable has the same restrictions
+" as a function name (see below).
+
+echo function('type') | " Reference to function type()
+" Note that `funcref('type')` will throw an error because the argument must be
+" a user-defined function; see further below for defining your own functions.
+echo funcref('type') | " Reference by identity, not name
+" A lambda (|lambda|) is an anonymous function; it can only contain one
+" expression in its body, which is also its implicit return value.
+echo {x -> x * x} | " Anonymous function
+echo function('substitute', ['hello']) | " Partial function
+
+
+" Regular expression (|regular-expression|)
+" ##################
+"
+" A regular expression pattern is generally a string, but in some cases you can
+" also use a regular expression between a pair of delimiters (usually `/`, but
+" you can choose anything).
+
+" Substitute 'hello' for 'Hello'
+substitute/hello/Hello/
+
+
+" ###########################
+" Implicit type conversions
+" ###########################
+"
+" Strings are converted to numbers, and numbers to strings when necessary. A
+" number becomes its decimal notation as a string. A string becomes its
+" numerical value if it can be parsed to a number, otherwise it becomes zero.
+
+echo "1" + 1 | " Number
+echo "1" .. 1 | " String
+echo "0xA" + 1 | " Number
+
+" Strings are treated like numbers when used as booleans
+echo "true" ? 1 : 0 | " This string is parsed to 0, which is false
+
+" ###########
+" Variables
+" ###########
+"
+" Variables are bound within a scope; if no scope is provided a default is
+" chosen by Vim. Use `:let` and `:const` to bind a value and `:unlet` to unbind
+" it.
+
+let b:my_var = 1 | " Local to current buffer
+let w:my_var = 1 | " Local to current window
+let t:my_var = 1 | " Local to current tab page
+let g:my_var = 1 | " Global variable
+let l:my_var = 1 | " Local to current function (see functions below)
+let s:my_var = 1 | " Local to current script file
+let a:my_arg = 1 | " Function argument (see functions below)
+
+" The Vim scope is read-only
+echo v:true | " Special built-in Vim variables (|v:var|)
+
+" Access special Vim memory like variables
+let @a = 'Hello' | " Register
+let $PATH='' | " Environment variable
+let &textwidth = 79 | " Option
+let &l:textwidth = 79 | " Local option
+let &g:textwidth = 79 | " Global option
+
+" Access scopes as dictionaries (can be modified like all dictionaries)
+" See the |dict-functions|, especially |get()|, for access and manipulation
+echo b: | " All buffer variables
+echo w: | " All window variables
+echo t: | " All tab page variables
+echo g: | " All global variables
+echo l: | " All local variables
+echo s: | " All script variables
+echo a: | " All function arguments
+echo v: | " All Vim variables
+
+" Constant variables
+const x = 10 | " See |:const|, |:lockvar|
+
+" Function reference variables have the same restrictions as function names
+let IsString = {x -> type(x) == type('')} | " Global: capital letter
+let s:isNumber = {x -> type(x) == type(0)} | " Local: any name allowed
+
+" When omitted the scope `g:` is implied, except in functions, there `l:` is
+" implied.
+
+
+" Multiple value binding (list unpacking)
+" #######################################
+"
+" Assign values of list to multiple variables (number of items must match)
+let [x, y] = [1, 2]
+
+" Assign the remainder to a rest variable (note the semicolon)
+let [mother, father; children] = ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+
+
+" ##############
+" Flow control
+" ##############
+
+" Conditional (|:if|, |:elseif|, |:else|, |:endif|)
+" ###########
+"
+" Conditions are set between `if` and `endif`. They can be nested.
+
+let condition = v:true
+
+if condition
+ echo 'First condition'
+elseif another_condition
+ echo 'Second condition'
+else
+ echo 'Fail'
+endif
+
+" Loops (|:for|, |:endfor|, |:while|, |:endwhile|, |:break|, |:continue|)
+" #####
+"
+" Two types of loops: `:for` and `:while`. Use `:continue` to skip to the next
+" iteration, `:break` to break out of the loop.
+
+" For-loop (|:for|, |:endfor|)
+" ========
+"
+" For-loops iterate over lists and nothing else. If you want to iterate over
+" another sequence you need to use a function which will create a list.
+
+" Iterate over a list
+for person in ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+ echo 'Hello ' .. person
+endfor
+
+" Iterate over a nested list by unpacking it
+for [x, y] in [[1, 0], [0, 1], [-1, 0], [0, -1]]
+ echo 'Position: x =' .. x .. ', y = ' .. y
+endfor
+
+" Iterate over a range of numbers
+for i in range(10, 0, -1) " Count down from 10
+ echo 'T minus' .. i
+endfor
+
+" Iterate over the keys of a dictionary
+for symbol in keys({'π': 3.14, 'e': 2.71})
+ echo 'The constant ' .. symbol .. ' is a transcendent number'
+endfor
+
+" Iterate over the values of a dictionary
+for value in values({'π': 3.14, 'e': 2.71})
+ echo 'The value ' .. value .. ' approximates a transcendent number'
+endfor
+
+" Iterate over the keys and values of a dictionary
+for [symbol, value] in items({'π': 3.14, 'e': 2.71})
+ echo 'The number ' .. symbol .. ' is approximately ' .. value
+endfor
+
+" While-loops (|:while|, |:endwhile|)
+
+let there_yet = v:true
+while !there_yet
+ echo 'Are we there yet?'
+endwhile
+
+
+" Exception handling (|exception-handling|)
+" ##################
+"
+" Throw new exceptions as strings, catch them by pattern-matching a regular
+" expression against the string
+
+" Throw new exception
+throw "Wrong arguments"
+
+" Guard against an exception (the second catch matches any exception)
+try
+ source path/to/file
+catch /Cannot open/
+ echo 'Looks like that file does not exist'
+catch /.*/
+ echo 'Something went wrong, but I do not know what'
+finally
+ echo 'I am done trying'
+endtry
+
+
+" ##########
+" Functions
+" ##########
+
+" Defining functions (|:function|, |:endfunction|)
+" ##################
+
+" Unscoped function names have to start with a capital letter
+function! AddNumbersLoudly(x, y)
+ " Use a: scope to access arguments
+ echo 'Adding' .. a:x .. 'and' .. a:y | " A side effect
+ return a:x + a:y | " A return value
+endfunction
+
+" Scoped function names may start with a lower-case letter
+function! s:addNumbersLoudly(x, y)
+ echo 'Adding' .. a:x .. 'and' .. a:y
+ return a:x + a:y
+endfunction
+
+" Without the exclamation mark it would be an error to re-define a function,
+" with the exclamation mark the new definition can replace the old one. Since
+" Vim script files can be reloaded several times over the course of a session
+" it is best to use the exclamation mark unless you really know what you are
+" doing.
+
+" Function definitions can have special qualifiers following the argument list.
+
+" Range functions define two implicit arguments, which will be set to the range
+" of the ex-command
+function! FirstAndLastLine() range
+ echo [a:firstline, a:lastline]
+endfunction
+
+" Prints the first and last line that match a pattern (|cmdline-ranges|)
+/^#!/,/!#$/call FirstAndLastLine()
+
+" Aborting functions, abort once error occurs (|:func-abort|)
+function! SourceMyFile() abort
+ source my-file.vim | " Try sourcing non-existing file
+ echo 'This will never be printed'
+endfunction
+
+" Closures, functions carrying values from outer scope (|:func-closure|)
+function! MakeAdder(x)
+ function! Adder(n) closure
+ return a:n + a:x
+ endfunction
+ return funcref('Adder')
+endfunction
+let AddFive = MakeAdder(5)
+echo AddFive(3) | " Prints 8
+
+" Dictionary functions, poor man's OOP methods (|Dictionary-function|)
+function! Mylen() dict
+ return len(self.data) | " Implicit variable self
+endfunction
+let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+echo mydict.len()
+
+" Alternatively, more concise
+let mydict = {'data': [0, 1, 2, 3]}
+function! mydict.len()
+ return len(self.data)
+endfunction
+
+" Calling functions (|:call|)
+" #################
+
+" Call a function for its return value, and possibly for its side effects
+let animals = keys({'cow': 'moo', 'dog': 'woof', 'cat': 'meow'})
+
+" Call a function for its side effects only, ignore potential return value
+call sign_undefine()
+
+" The call() function calls a function reference and passes parameters as a
+" list, and returns the function's result.
+echo call(function('get'), [{'a': 1, 'b': 2}, 'c', 3]) | " Prints 3
+
+" Recall that Vim script is embedded within the ex-commands, that is why we
+" cannot just call a function directly, we have to use the `:call` ex-command.
+
+" Function namespaces (|write-library-script|, |autoload|)
+" ###################
+
+" Must be defined in autoload/foo/bar.vim
+" Namspaced function names do not have to start with a capital letter
+function! foo#bar#log(value)
+ echomsg value
+endfunction
+
+call foo#bar#log('Hello')
+
+
+" #############################
+" Frequently used ex-commands
+" #############################
+
+
+" Sourcing runtime files (|'runtimepath'|)
+" ######################
+
+" Source first match among runtime paths
+runtime plugin/my-plugin.vim
+
+
+" Defining new ex-commands (|40.2|, |:command|)
+" ########################
+
+" First argument here is the name of the command, rest is the command body
+command! SwapAdjacentLines normal! ddp
+
+" The exclamation mark works the same as with `:function`. User-defined
+" commands must start with a capital letter. The `:command` command can take a
+" number of attributes (some of which have their own parameters with `=`), such
+" as `-nargs`, all of them start with a dash to set them apart from the command
+" name.
+
+command! -nargs=1 Error echoerr <args>
+
+
+" Defining auto-commands (|40.3|, |autocmd|, |autocommand-events|)
+" ######################
+
+" The arguments are "events", "patterns", rest is "commands"
+autocmd BufWritePost $MYVIMRC source $MYVIMRC
+
+" Events and patterns are separated by commas with no space between. See
+" |autocmd-events| for standard events, |User| for custom events. Everything
+" else are the ex-commands which will be executed.
+
+" Auto groups
+" ===========
+"
+" When a file is sourced multiple times the auto-commands are defined anew,
+" without deleting the old ones, causing auto-commands to pile up over time.
+" Use auto-groups and the following ritual to guard against this.
+
+augroup auto-source | " The name of the group is arbitrary
+ autocmd! | " Deletes all auto-commands in the current group
+ autocmd BufWritePost $MYVIMRC source $MYVIMRC
+augroup END | " Switch back to default auto-group
+
+" It is also possible to assign a group directly. This is useful if the
+" definition of the group is in one script and the definition of the
+" auto-command is in another script.
+
+" In one file
+augroup auto-source
+ autocmd!
+augroup END
+
+" In another file
+autocmd auto-source BufWritePost $MYVIMRC source $MYVIMRC
+
+" Executing (run-time macros of sorts)
+" ####################################
+
+" Sometimes we need to construct an ex-command where part of the command is not
+" known until runtime.
+
+let line = 3 | " Line number determined at runtime
+execute line .. 'delete' | " Delete a line
+
+" Executing normal-mode commands
+" ##############################
+"
+" Use `:normal` to play back a sequence of normal mode commands from the
+" command-line. Add an exclamation mark to ignore user mappings.
+
+normal! ggddGp | " Transplant first line to end of buffer
+
+" Window commands can be used with :normal, or with :wincmd if :normal would
+" not work
+wincmd L | " Move current window all the way to the right
+
+
+" ###########################
+" Frequently used functions
+" ###########################
+
+" Feature check
+echo has('nvim') | " Running Neovim
+echo has('python3') | " Support for Python 3 plugins
+echo has('unix') | " Running on a Unix system
+echo has('win32') | " Running on a Windows system
+
+
+" Test if something exists
+echo exists('&mouse') | " Option (exists only)
+echo exists('+mouse') | " Option (exists and works)
+echo exists('$HOSTNAME') | " Environment variable
+echo exists('*strftime') | " Built-in function
+echo exists('**s:MyFunc') | " User-defined function
+echo exists('bufcount') | " Variable (scope optional)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists(':Make') | " Command
+echo exists("#CursorHold") | " Auto-command defined for event
+echo exists("#BufReadPre#*.gz") | " Event and pattern
+echo exists("#filetypeindent") | " Auto-command group
+echo exists("##ColorScheme") | " Auto-command supported for event
+
+" Various dynamic values (see |expand()|)
+echo expand('%') | " Current file name
+echo expand('<cword>') | " Current word under cursor
+echo expand('%:p') | " Modifier are possible
+
+" Type tests
+" There are unique constants defined for the following types. Older versions
+" of Vim lack the type variables, see the reference " documentation for a
+" workaround
+echo type(my_var) == v:t_number | " Number
+echo type(my_var) == v:t_string | " String
+echo type(my_var) == v:t_func | " Funcref
+echo type(my_var) == v:t_list | " List
+echo type(my_var) == v:t_dict | " Dictionary
+echo type(my_var) == v:t_float | " Float
+echo type(my_var) == v:t_bool | " Explicit Boolean
+" For the null object should compare it against itself
+echo my_var is v:null
+
+" Format strings
+echo printf('%d in hexadecimal is %X', 123, 123)
+
+
+" #####################
+" Tricks of the trade
+" #####################
+
+" Source guard
+" ############
+
+" Prevent a file from being sourced multiple times; users can set the variable
+" in their configuration to prevent the plugin from loading at all.
+if exists('g:loaded_my_plugin')
+ finish
+endif
+let g:loaded_my_plugin = v:true
+
+" Default values
+" ##############
+
+" Get a default value: if the user defines a variable use it, otherwise use a
+" hard-coded default. Uses the fact that a scope is also a dictionary.
+let s:greeting = get(g:, 'my_plugin_greeting', 'Hello')
diff --git a/.config/nvim/out.vim b/.config/nvim/out.vim
new file mode 100644
index 0000000..6e4e1f1
--- /dev/null
+++ b/.config/nvim/out.vim
@@ -0,0 +1,36 @@
+" capture (dump) the (somewhat long) ouput of the commands like `:digraph`, `:map', `:highlight`, `:scripnames` etc.
+
+function! s:dump(cmd) abort
+
+ " Start a new split or maybe a buffer or a tab
+ " enew | " open a new buffer
+ 10split | enew | " open a new split (with 10% height (?))
+ " tabnew | " open a new tab
+
+ " Make it a scratch buffer ( `:help special-buffers`)
+ setlocal
+ \ bufhidden=wipe
+ \ buftype=nofile
+ \ nobuflisted
+ \ nolist
+ \ noswapfile
+ \ norelativenumber
+ \ nonumber
+
+ " Write the cmd output to the buffer
+ put =execute(a:cmd)
+ " There are 2 empty line at the beginning of the buffer before the ouput of
+ " the cmd. Not sure from where they are comning from. Anyhow I will delete
+ " them.
+ norm gg2dd
+
+ " No modifications to this buffer
+ setlocal readonly nomodifiable nomodified
+
+ " Press escape to close when you're done
+ nnoremap <buffer><silent> <Esc> :bd<CR>
+
+endfunction
+
+" Define a command to use the function easier
+command! -nargs=1 Dump execute "call s:dump(" string(<q-args>) ")"
diff --git a/.config/nvim/pack/colors/opt/onedark.vim b/.config/nvim/pack/colors/opt/onedark.vim
new file mode 160000
+Subproject 390b893d361c356ac1b00778d849815f2aa44ae
diff --git a/.config/nvim/templates/_default.c b/.config/nvim/templates/_default.c
new file mode 100644
index 0000000..6d8e7c1
--- /dev/null
+++ b/.config/nvim/templates/_default.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main() {
+ <++>
+}
diff --git a/.config/nvim/templates/_default.html b/.config/nvim/templates/_default.html
new file mode 100644
index 0000000..4201ee8
--- /dev/null
+++ b/.config/nvim/templates/_default.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title><++></title>
+ <link rel="stylesheet" href="/style.css">
+</head>
+
+<body>
+ <++>
+</body>
+
+</html>
diff --git a/.config/nvim/templates/_default.tex b/.config/nvim/templates/_default.tex
new file mode 100644
index 0000000..397e28e
--- /dev/null
+++ b/.config/nvim/templates/_default.tex
@@ -0,0 +1,7 @@
+\documentclass{article}
+
+\begin{document}
+
+<++>
+
+\end{document}
diff --git a/.config/nvim/templates/article.tex b/.config/nvim/templates/article.tex
new file mode 100644
index 0000000..a821909
--- /dev/null
+++ b/.config/nvim/templates/article.tex
@@ -0,0 +1,11 @@
+\documentclass{article}
+
+\title{<++>}
+\author{<++>}
+
+\begin{document}
+\maketitle
+
+<++>
+
+\end{document}
diff --git a/.config/nvim/vim.log b/.config/nvim/vim.log
new file mode 100644
index 0000000..67ecb5b
--- /dev/null
+++ b/.config/nvim/vim.log
@@ -0,0 +1,170 @@
+
+
+times in msec
+ clock self+sourced self: sourced script
+ clock elapsed: other lines
+
+000.009 000.009: --- NVIM STARTING ---
+000.119 000.110: event init
+000.186 000.067: early init
+000.230 000.043: locale set
+000.260 000.030: init first window
+000.469 000.209: inits 1
+000.483 000.014: window checked
+000.484 000.001: parsing arguments
+000.872 000.051 000.051: require('vim.shared')
+000.971 000.034 000.034: require('vim._meta')
+000.973 000.095 000.061: require('vim._editor')
+000.974 000.190 000.044: require('vim._init_packages')
+000.975 000.301: init lua interpreter
+001.027 000.053: expanding arguments
+001.058 000.031: inits 2
+001.316 000.258: init highlight
+001.317 000.001: waiting for UI
+001.475 000.157: done waiting for UI
+001.481 000.007: clear screen
+001.588 000.107: init default mappings & autocommands
+001.883 000.041 000.041: sourcing /usr/share/nvim/runtime/ftplugin.vim
+001.936 000.022 000.022: sourcing /usr/share/nvim/runtime/indent.vim
+001.982 000.009 000.009: sourcing /usr/share/nvim/archlinux.vim
+001.985 000.030 000.021: sourcing /etc/xdg/nvim/sysinit.vim
+006.183 000.919 000.919: sourcing /home/master/.config/nvim/autoload/plug.vim
+012.319 000.007 000.007: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/filetype.vim
+012.437 000.007 000.007: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/ftdetect/polyglot.vim
+012.556 000.010 000.010: sourcing /usr/share/vim/vimfiles/ftdetect/PKGBUILD.vim
+012.580 000.008 000.008: sourcing /usr/share/vim/vimfiles/ftdetect/SRCINFO.vim
+012.604 000.007 000.007: sourcing /usr/share/vim/vimfiles/ftdetect/augeas.vim
+012.634 000.014 000.014: sourcing /usr/share/vim/vimfiles/ftdetect/conkyrc.vim
+012.672 000.022 000.022: sourcing /usr/share/vim/vimfiles/ftdetect/espeakfiletype.vim
+012.703 000.015 000.015: sourcing /usr/share/vim/vimfiles/ftdetect/lf.vim
+012.755 000.024 000.024: sourcing /usr/share/vim/vimfiles/ftdetect/nginx.vim
+023.697 011.642 011.528: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/autoload/polyglot/init.vim
+023.708 011.710 000.068: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/filetype.vim
+023.840 000.085 000.085: sourcing /usr/share/nvim/runtime/filetype.lua
+024.243 000.011 000.011: sourcing /usr/share/nvim/runtime/ftplugin.vim
+024.319 000.007 000.007: sourcing /usr/share/nvim/runtime/indent.vim
+024.499 000.063 000.063: sourcing /usr/share/nvim/runtime/syntax/synload.vim
+024.563 000.201 000.137: sourcing /usr/share/nvim/runtime/syntax/syntax.vim
+024.947 000.306 000.306: sourcing /usr/share/nvim/runtime/syntax/nosyntax.vim
+025.066 000.054 000.054: sourcing /usr/share/nvim/runtime/syntax/synload.vim
+025.118 000.505 000.145: sourcing /usr/share/nvim/runtime/syntax/syntax.vim
+025.229 000.008 000.008: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/filetype.vim
+025.302 000.053 000.053: sourcing /usr/share/nvim/runtime/filetype.lua
+025.391 000.008 000.008: sourcing /usr/share/nvim/runtime/ftplugin.vim
+025.499 000.007 000.007: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/filetype.vim
+025.566 000.048 000.048: sourcing /usr/share/nvim/runtime/filetype.lua
+025.652 000.008 000.008: sourcing /usr/share/nvim/runtime/ftplugin.vim
+025.723 000.006 000.006: sourcing /usr/share/nvim/runtime/indent.vim
+025.809 023.804 010.228: sourcing /home/master/.config/nvim/init.vim
+025.815 000.331: sourcing vimrc file(s)
+026.068 000.043 000.043: sourcing /home/master/.config/nvim/plugin/coc.vim
+026.166 000.080 000.080: sourcing /home/master/.config/nvim/plugin/debug.vim
+026.202 000.018 000.018: sourcing /home/master/.config/nvim/plugin/docs.vim
+026.303 000.082 000.082: sourcing /home/master/.config/nvim/plugin/fzf.vim
+026.366 000.041 000.041: sourcing /home/master/.config/nvim/plugin/scratch.vim
+026.863 000.071 000.071: sourcing /home/master/.config/nvim/autoload/onedark.vim
+039.423 012.982 012.912: sourcing /home/master/.config/nvim/colors/onedark.vim
+039.454 013.068 000.086: sourcing /home/master/.config/nvim/plugin/ui.vim
+039.812 000.227 000.227: sourcing /home/master/.local/share/nvim/plugged/vim-surround/plugin/surround.vim
+039.967 000.084 000.084: sourcing /home/master/.local/share/nvim/plugged/vim-commentary/plugin/commentary.vim
+040.116 000.063 000.063: sourcing /home/master/.local/share/nvim/plugged/lf.vim/plugin/lf.vim
+040.371 000.185 000.185: sourcing /home/master/.local/share/nvim/plugged/vim-floaterm/plugin/floaterm.vim
+040.855 000.418 000.418: sourcing /home/master/.local/share/nvim/plugged/fzf/plugin/fzf.vim
+041.550 000.617 000.617: sourcing /home/master/.local/share/nvim/plugged/fzf.vim/plugin/fzf.vim
+041.693 000.073 000.073: sourcing /home/master/.local/share/nvim/plugged/zeavim.vim/plugin/zeavim.vim
+042.133 000.339 000.339: sourcing /home/master/.local/share/nvim/plugged/vim-polyglot/plugin/polyglot.vim
+042.506 000.152 000.152: sourcing /usr/share/nvim/runtime/plugin/gzip.vim
+042.533 000.007 000.007: sourcing /usr/share/nvim/runtime/plugin/health.vim
+042.939 000.118 000.118: sourcing /usr/share/nvim/runtime/pack/dist/opt/matchit/plugin/matchit.vim
+043.016 000.466 000.348: sourcing /usr/share/nvim/runtime/plugin/matchit.vim
+043.131 000.099 000.099: sourcing /usr/share/nvim/runtime/plugin/matchparen.vim
+043.494 000.345 000.345: sourcing /usr/share/nvim/runtime/plugin/netrwPlugin.vim
+044.073 000.113 000.113: sourcing /usr/share/nvim/runtime/autoload/remote/host.vim
+044.305 000.089 000.089: sourcing /usr/share/nvim/runtime/autoload/remote/define.vim
+044.761 001.141 000.938: sourcing /home/master/.local/share/nvim/rplugin.vim
+044.768 001.244 000.103: sourcing /usr/share/nvim/runtime/plugin/rplugin.vim
+044.886 000.091 000.091: sourcing /usr/share/nvim/runtime/plugin/shada.vim
+044.928 000.017 000.017: sourcing /usr/share/nvim/runtime/plugin/spellfile.vim
+045.070 000.121 000.121: sourcing /usr/share/nvim/runtime/plugin/tarPlugin.vim
+045.154 000.058 000.058: sourcing /usr/share/nvim/runtime/plugin/tohtml.vim
+045.193 000.013 000.013: sourcing /usr/share/nvim/runtime/plugin/tutor.vim
+045.365 000.151 000.151: sourcing /usr/share/nvim/runtime/plugin/zipPlugin.vim
+045.471 000.012 000.012: sourcing /usr/share/vim/vimfiles/plugin/fzf.vim
+045.579 000.089 000.089: sourcing /usr/share/vim/vimfiles/plugin/redact_pass.vim
+046.186 000.100 000.100: sourcing /usr/share/nvim/runtime/plugin/editorconfig.lua
+046.313 000.104 000.104: sourcing /usr/share/nvim/runtime/plugin/man.lua
+046.371 000.037 000.037: sourcing /usr/share/nvim/runtime/plugin/nvim.lua
+046.425 002.166: loading rtp plugins
+046.501 000.075: loading packages
+046.527 000.027: loading after plugins
+046.535 000.007: inits 3
+049.346 002.812: reading ShaDa
+049.563 000.216: opening buffers
+049.592 000.029: BufEnter autocommands
+049.594 000.002: editing files in windows
+051.092 000.064 000.064: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/init.vim
+051.660 000.278 000.278: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/parts.vim
+051.828 000.011 000.011: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/formatter/short_path.vim
+052.601 000.102 000.102: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/util.vim
+052.898 000.159 000.159: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions.vim
+053.025 000.030 000.030: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/quickfix.vim
+053.204 000.108 000.108: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline.vim
+053.349 000.020 000.020: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/netrw.vim
+053.463 000.021 000.021: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/fzf.vim
+053.692 000.064 000.064: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/term.vim
+055.576 000.118 000.118: require('vim.lsp.log')
+056.062 000.483 000.483: require('vim.lsp.protocol')
+057.439 000.324 000.324: require('vim.lsp._snippet')
+057.532 000.090 000.090: require('vim.highlight')
+057.538 000.004 000.004: require('vim.F')
+057.556 001.459 001.041: require('vim.lsp.util')
+057.570 002.492 000.432: require('vim.lsp.handlers')
+057.977 000.405 000.405: require('vim.lsp.rpc')
+058.150 000.171 000.171: require('vim.lsp.sync')
+058.648 000.496 000.496: require('vim.lsp.semantic_tokens')
+059.000 000.349 000.349: require('vim.lsp.buf')
+059.135 000.133 000.133: require('vim.lsp.diagnostic')
+059.350 000.213 000.213: require('vim.lsp.codelens')
+059.382 005.520 001.261: require('vim.lsp')
+059.504 000.044 000.044: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/nvimlsp.vim
+059.696 000.071 000.071: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/whitespace.vim
+059.933 000.037 000.037: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/po.vim
+060.085 000.056 000.056: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/wordcount.vim
+060.283 000.019 000.019: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/keymap.vim
+060.481 000.028 000.028: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/searchcount.vim
+064.384 000.073 000.073: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/section.vim
+064.878 000.238 000.238: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/highlighter.vim
+068.911 000.072 000.072: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/themes.vim
+069.476 000.931 000.859: sourcing /home/master/.config/nvim/autoload/airline/themes/onedark.vim
+072.884 000.370 000.370: sourcing /home/master/.config/nvim/autoload/airline/themes/onedark.vim
+085.154 000.083 000.083: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/builder.vim
+085.516 000.050 000.050: sourcing /home/master/.local/share/nvim/plugged/vim-airline/autoload/airline/extensions/default.vim
+102.172 051.614 043.237: sourcing /home/master/.local/share/nvim/plugged/vim-airline/plugin/airline.vim
+102.485 000.031 000.031: sourcing /home/master/.local/share/nvim/plugged/vim-airline-themes/plugin/airline-themes.vim
+103.232 001.993: VimEnter autocommands
+103.235 000.003: UIEnter autocommands
+103.236 000.001: before starting main loop
+103.996 000.760: first screen update
+103.998 000.002: --- NVIM STARTED ---
+
+
+times in msec
+ clock self+sourced self: sourced script
+ clock elapsed: other lines
+
+000.009 000.009: --- NVIM STARTING ---
+000.188 000.179: event init
+000.251 000.063: early init
+000.292 000.041: locale set
+000.329 000.036: init first window
+000.545 000.217: inits 1
+000.551 000.006: window checked
+000.553 000.002: parsing arguments
+000.937 000.026 000.026: require('vim.shared')
+001.012 000.032 000.032: require('vim._meta')
+001.014 000.073 000.041: require('vim._editor')
+001.015 000.160 000.061: require('vim._init_packages')
+001.016 000.302: init lua interpreter
+001.515 000.500: expanding arguments
+001.559 000.044: inits 2
+001.793 000.233: init highlight
diff --git a/.config/nvim/vimspector/python.json b/.config/nvim/vimspector/python.json
new file mode 100644
index 0000000..7fff9ab
--- /dev/null
+++ b/.config/nvim/vimspector/python.json
@@ -0,0 +1,31 @@
+{
+ "configurations": {
+ "Python: Launch": {
+ "adapter": "debugpy",
+ "filetypes": [ "python" ],
+ "configuration": {
+ "name": "python: Launch",
+ "type": "python",
+ "request": "launch",
+ "python": "$HOME/Others/virtualenvs/main/bin/python",
+ "program": "$file",
+ "stopOnEntry": true,
+ "debugOptions": []
+ }
+ },
+ "Python: Launch interactive": {
+ "adapter": "debugpy",
+ "filetypes": [ "python" ],
+ "configuration": {
+ "name": "python: Launch",
+ "type": "python",
+ "request": "launch",
+ "python": "$HOME/Others/virtualenvs/main/bin/python",
+ "program": "$file",
+ "console": "externalTerminal",
+ "stopOnEntry": true,
+ "debugOptions": []
+ }
+ }
+ }
+}
diff --git a/.config/python/pythonrc b/.config/python/pythonrc
new file mode 100644
index 0000000..9ab457e
--- /dev/null
+++ b/.config/python/pythonrc
@@ -0,0 +1,22 @@
+import os
+import atexit
+import readline
+
+state_home = os.environ.get("XDG_STATE_HOME")
+if state_home is None:
+ state_home = os.path.join(os.path.expanduser('~'), ".local", "state")
+
+history = os.path.join(state_home, "python_history")
+
+try:
+ readline.read_history_file(history)
+except OSError:
+ pass
+
+def write_history():
+ try:
+ readline.write_history_file(history)
+ except OSError:
+ pass
+
+atexit.register(write_history)
diff --git a/.config/shell/aliasrc b/.config/shell/aliasrc
new file mode 100644
index 0000000..1c4c7fc
--- /dev/null
+++ b/.config/shell/aliasrc
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+# Common operations
+alias xx='chmod u+x'
+alias x-='chmod -x'
+alias th='touch'
+alias md='mkdir'
+alias s='sudo'
+alias l='ls -A'
+alias ll='ls -al'
+# open
+alias o='${OPENER:-xdg-open}'
+alias e='${EDITOR:-vi}'
+alias se='sudoedit'
+alias lf='lfcd'
+alias rs='exec $SHELL'
+alias sr='e "$(ff -L ~/.config ~/.local/bin ~/bin)"'
+alias fh='fzf --tac < "${XDG_DATA_HOME:-$HOME/.local/share}/openhist"'
+
+alias uc='cd ~ && gitpush'
+
+lt() { tree -aC "$@" | less -rF; }
+dul() { du -ahd 1 "$@" | sort -h | less -FX; }
+v() { LESSOPEN="|preview %s" less -r -F "${1:-.}"; }
+ff() { find "$@" ! -wholename '*.git*' \( -type d -printf '%p/\n' , ! -type d -print \) |
+ FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS $fo" fzf -m; }
+senv() { source "${XDG_DATA_HOME:-$HOME/.local/share}/virtualenvs/${1:-main}/bin/activate"; }
+
+sudoedit() {
+ if command -V vim >/dev/null; then
+ [ -f "$HOME/.vim/vimrc" ] && VIMRC="$HOME/.vim/vimrc"
+ sudo vim -u "${VIMRC:-$HOME/.vimrc}" "$@"
+ elif command -V nvim >/dev/null; then
+ sudo nvim -u "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim" "$@"
+ else
+ command sudoedit "$@"
+ fi
+}
+
+lfcd () {
+ [ $# -gt 0 ] && [ -z "$1" ] && return 2
+ # cd "$(command lf -print-last-dir "$@")"
+
+ tmp="$(mktemp)"
+ command lf -last-dir-path="$tmp" "$@"
+ if [ -f "$tmp" ]; then
+ dir="$(cat "$tmp")"
+ rm -f "$tmp"
+ [ -d "$dir" ] || return
+ [ "$dir" != "$PWD" ] || return
+ cd "$dir"
+ fi
+}
+
+# Dirs
+alias ..='cd ..'
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias .....='cd ../../../..'
+alias ......='cd ../../../../..'
+
+alias 1='pushd -1'
+alias 2='pushd -2'
+alias 3='pushd -3'
+alias 4='pushd -4'
+alias 5='pushd -5'
+alias 6='pushd -6'
+alias 7='pushd -7'
+alias 8='pushd -8'
+alias 9='pushd -9'
+
+## Default options
+alias rm='rm -Iv'
+alias cp='cp -iv'
+alias mv='mv -iv'
+alias du='du -h'
+alias mkdir='mkdir -pv'
+alias watch='watch -c -n 1 '
+alias wget='wget -c'
+alias fzf='fzf --ansi'
+alias diff='diff --color=auto'
+alias grep='grep --color=auto'
+alias tree='tree -C'
+alias ls='ls -h --group-directories-first --color=auto --classify=auto'
+alias info='info --vi-keys --init-file ~/.config/infokey'
diff --git a/.config/shell/bm-dirs b/.config/shell/bm-dirs
new file mode 100644
index 0000000..4918a18
--- /dev/null
+++ b/.config/shell/bm-dirs
@@ -0,0 +1,51 @@
+# You can add comments to these files with #
+cac ${XDG_CACHE_HOME:-$HOME/.cache}
+cg ${XDG_CONFIG_HOME:-$HOME/.config}
+lsh ${XDG_DATA_DIR:-$HOME/.local/share}
+vnv ${XDG_DATA_DIR:-$HOME/.local/share}/virtualenvs
+lsr ${XDG_DATA_DIR:-$HOME/.local/src}
+lst ${XDG_DATA_DIR:-$HOME/.local/state}
+dn ${XDG_DOWNLOAD_DIR:-$HOME/Downloads}
+dx ${XDG_DOCUMENTS_DIR:-$HOME/Documents}
+dl ${XDG_DOCUMENTS_DIR:-$HOME/Documents}/latex
+nt ${XDG_DOCUMENTS_DIR:-$HOME/Documents}/Notes
+ms ${XDG_MUSIC_DIR:-$HOME/Music}
+px ${XDG_PICTURES_DIR:-$HOME/Pictures}
+vd ${XDG_VIDEOS_DIR:-$HOME/Videos}
+
+lb ~/.local/bin
+bn ~/bin
+sd ~/sdcard
+rp ~/repos
+ap ~/Applications
+ad ~/Arduino
+dv ~/Dev
+cm ~/Dev/cloud-maker
+cs ~/Dev/sites/csstudent41.github.io
+vr ~/Dev/sites/vikas.rocks
+vrc ~/Dev/sites/vikas.rocks/content
+vrl ~/Dev/sites/vikas.rocks/layouts
+vrp ~/Dev/sites/vikas.rocks/public
+td ~/Dev/test
+gd ~/GDrive/vartak/CS
+gf ~/GDrive/vartak/CS/practical-files/sem5
+gp ~/GDrive/vartak/CS/practical-notes/sem5
+gz ~/GDrive/vartak/CS/practical-zip/sem5
+gn ~/GDrive/vartak/CS/notes/sem5
+rs ~/GDrive/vartak/results
+ph ~/Phone
+stv ~/Phone/.stversions
+pw ~/Phone/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp\ Documents
+
+mn /mnt
+stg ${STORAGE:-/mnt/storage}
+lr ${STORAGE:-/mnt/storage}/Library
+med ${STORAGE:-/mnt/storage}/Media
+sts ${STORAGE:-/mnt/storage}/sites
+sd /sdcard
+mp /run/media/$USER/
+mtp /run/user/1000/gvfs
+usr ${PREFIX:-/usr}
+ush /usr/share
+usd /usr/share/doc
+usha /usr/share/applications
diff --git a/.config/shell/bm-files b/.config/shell/bm-files
new file mode 100644
index 0000000..46723a5
--- /dev/null
+++ b/.config/shell/bm-files
@@ -0,0 +1,28 @@
+# These files automatically update when edited/saved in vim:
+
+# keys filename description
+bf ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-files
+bd ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs
+
+pf ~/.profile
+zp ~/.zprofile
+xp ~/.xprofile
+gi ~/.gitignore
+zc ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/.zshrc
+zh ${XDG_DATA_HOME:-$HOME/.config}/zsh/history
+za ${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc
+arc ${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc
+spf ${XDG_CONFIG_HOME:-$HOME/.config}/shell/server.profile
+lc ${XDG_CONFIG_HOME:-$HOME/.config}/lf/lfrc
+sx ${XDG_CONFIG_HOME:-$HOME/.config}/sxiv/exec/key-handler
+in ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim
+ac ${XDG_CONFIG_HOME:-$HOME/.config}/alacritty/alacritty.toml
+xr ${XDG_CONFIG_HOME:-$HOME/.config}/X11/Xresources
+xi ${XDG_CONFIG_HOME:-$HOME/.config}/X11/xinitrc
+mm ${XDG_CONFIG_HOME:-$HOME/.config}/mimeapps.list
+ssc ~/.ssh/config
+csh ~/Dev/csstudent41.github.io/layouts/_default/home.html
+qn ${XDG_DOCUMENTS_HOME:-$HOME/Documents}/Notes/QuickNote.md
+bm ${XDG_DOCUMENTS_HOME:-$HOME/Documents}/Notes/bookmarks.txt
+akn ${XDG_DOCUMENTS_HOME:-$HOME/Documents}/Notes/ak47.txt
+li ${XDG_DOCUMENTS_HOME:-$HOME/Documents}/latex/lorem-ipsum.txt
diff --git a/.config/shell/inputrc b/.config/shell/inputrc
new file mode 100644
index 0000000..4f7c652
--- /dev/null
+++ b/.config/shell/inputrc
@@ -0,0 +1,38 @@
+set editing-mode vi
+set keymap vi-insert
+RETURN: "\e\n"
+# set vi-ins-mode-string "+"
+# set vi-cmd-mode-string ":"
+# Add colorful command mode string
+# set vi-cmd-mode-string "\1\e[1;31m\2:\1\e[0m\2"
+# Change cursor bar -> insert mode block -> command mode
+set vi-ins-mode-string \1\e[6 q\2
+set vi-cmd-mode-string \1\e[2 q\2
+
+
+set show-mode-in-prompt on
+set show-all-if-ambiguous on
+set completion-ignore-case on
+set menu-complete-display-prefix on
+
+"\C-a": beginning-of-line
+"\C-b": backward-char
+"\C-d": delete-char
+"\C-e": end-of-line
+"\C-f": forward-char
+"\C-h": backward-delete-char
+"\C-k": kill-line
+"\C-l": clear-screen
+"\C-n": history-search-forward
+"\C-p": history-search-backward
+
+# "\e-b": backward-word
+# "\e-f": forward-word
+
+# "(": "\C-v()\C-b"
+# "[": "\C-v[]\C-b"
+# "{": "\C-v{}\C-b"
+# "\"": "\C-v\"\C-v\"\C-b"
+# Single quote (')
+# "\047": "\C-v\047\C-v\047\C-b"
+"jk": vi-movement-mode
diff --git a/.config/shell/profile b/.config/shell/profile
new file mode 100644
index 0000000..1393c45
--- /dev/null
+++ b/.config/shell/profile
@@ -0,0 +1,268 @@
+#!/bin/sh
+
+export OPENER="open"
+export PAGER="less"
+export EDITOR="nvim"
+export BROWSER="w3m"
+export FILES="lf"
+export TERMINAL="st"
+export PREVIEWER="preview"
+
+XDG_CONFIG_HOME="$HOME/.config"
+XDG_DATA_HOME="$HOME/.local/share"
+XDG_STATE_HOME="$HOME/.local/state"
+XDG_CACHE_HOME="$HOME/.cache"
+
+export MOUNTPATH="/run/media/$USER"
+export JUPYTER_CONFIG_DIR="$XDG_CONFIG_HOME/jupyter"
+export W3M_DIR="$XDG_CONFIG_HOME/w3m"
+export NCFTPDIR="$XDG_DATA_HOME/ncftp"
+export PASSWORD_STORE_DIR="$HOME/Phone/Backup/pass"
+export ANDROID_USER_HOME="$XDG_DATA_HOME/android"
+export __GL_SHADER_DISK_CACHE_PATH="$HOME/.cache/nv"
+
+export XINITRC="$XDG_CONFIG_HOME/X11/xinitrc"
+export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
+export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc"
+export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
+export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/pythonrc"
+export IPYTHONDIR="$XDG_CONFIG_HOME/ipython"
+export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch/config"
+export MBSYNCRC="$XDG_CONFIG_HOME/isyncrc"
+
+export LESSHISTFILE="$XDG_DATA_HOME/less/history"
+export FZF_HIST_FILE="$XDG_DATA_HOME/fzf/history"
+export SDCV_HISTFILE="$XDG_DATA_HOME/sdcv"
+export R_ENVIRON_USER="$XDG_DATA_HOME/R/.Renviron"
+export SSH_AUTH_SOCK="$HOME/.ssh/ssh_auth_sock"
+export GOPATH="$XDG_DATA_HOME/go"
+export SQLITE_HISTORY="$XDG_DATA_HOME/sqlite_history"
+
+# program configuration
+export LESS='-Rf --mouse --use-color -Dd+r$Du+b$'
+export LESSOPEN='|lessopen.sh %s'
+export GROFF_NO_SGR=1
+export GTK_IM_MODULE='fcitx'
+export QT_IM_MODULE='fcitx'
+export SDL_IM_MODULE='fcitx'
+export XMODIFIERS='@im=fcitx'
+export QT_QPA_PLATFORMTHEME='qt5ct'
+export QT_FONT_DPI=112
+export SDCV_PAGER='less -R --quit-if-one-screen'
+export HTTP_HOME='https://www.duckduckgo.com'
+export CHROME_EXECUTABLE='chromium'
+export FZF_DEFAULT_COMMAND="find -L . ! -wholename '*.git*' \( -type d -printf '%p/\n' , ! -type d -print \)"
+export FZF_DEFAULT_OPTS="
+ --history='$XDG_DATA_HOME/fzf/history'
+ --preview='\$PREVIEWER {}' --preview-window=hidden
+ --bind 'ctrl-s:toggle-sort'
+ --bind 'ctrl-y:execute-silent(printf \"%s\\\n\" {+} | xsel --clipboard)'
+ --bind 'ctrl-v:toggle-preview,ctrl-space:toggle-preview'
+ --bind 'alt-space:toggle-preview,alt-w:toggle-preview-wrap'
+ --bind 'alt-enter:print-query'
+ --bind 'ctrl-alt-c:change-preview-window(up|left:50%|down|right:50%)'
+ --bind 'ctrl-alt-a:select-all,ctrl-alt-d:deselect-all'
+ --bind 'alt-n:half-page-down,alt-p:half-page-up'
+ --bind 'alt-N:page-down,alt-P:page-up'
+ --bind 'alt-<:first,alt->:last'
+ --bind 'alt-J:preview-down,alt-K:preview-up'
+ --bind 'alt-j:preview-half-page-down,alt-k:preview-half-page-up'
+ --bind 'alt-l:preview-page-down,alt-h:preview-page-up'
+ --bind 'alt-H:preview-top,alt-L:preview-bottom'
+ --bind 'alt-g:preview-top,alt-G:preview-bottom'
+ --bind 'alt-s:execute(dmenu-send {})'
+ --bind 'alt-0:change-preview(echo {})'
+ --bind 'alt-1:change-preview(highlight --out-format=ansi -- {} 2>/dev/null ||
+ ls -Als --group-directories-first --color=always --classify=always -- {})'
+ --bind 'alt-2:change-preview(\$PREVIEWER {})'
+ --bind 'alt-9:change-preview(printf \"%s\\\n\" {+})'
+ --bind 'alt-!:execute(less {})'
+ --bind 'alt-@:execute(\$PREVIEWER {} | less)'
+ --bind 'alt-v:execute(echo {q} >> \"$FZF_HIST_FILE\"; LESSOPEN=\"|preview %s\" less {})'
+ --bind 'alt-e:execute(echo {q} >> \"$FZF_HIST_FILE\"; eval \"\${EDITOR:-vi} {}\")'
+ --bind 'ctrl-o:execute(echo {q} >> \"$FZF_HIST_FILE\"; eval \"\${OPENER:-xdg-open} {}\")'
+ --bind 'alt-O:execute(echo {q} >> \"$FZF_HIST_FILE\"; mimeopen --ask {})'
+ --bind 'alt-o:execute(echo {q} >> \"$FZF_HIST_FILE\"; eval \"\${FILES:-lf} {}\")'
+ --bind 'alt-D:become(echo {q} >> \"$FZF_HIST_FILE\"; dirname {} )'
+ "
+
+## Custom themes for GTypist
+# export GTYPIST_OPTS="--color 3,0 --banner-color 0,1,2,3" # red-yellow
+# export GTYPIST_OPTS="--color 3,0 --banner-colors 0,2,4,1" # green-yellow
+export GTYPIST_OPTS="--color 6,0 --banner-color 0,4,5,1" # blue-cyan
+
+
+# # path
+# find -L ~/.local/share/gem/ruby/3.0.0/bin ~/.local/bin ~/bin \
+# -type d ! -wholename '*/.st*' |
+# while read -r dir; do
+# [ "$PATH" = "${PATH#*"$dir"}" ] && export PATH="$dir:$PATH"
+# done
+
+if [ "$PATH" = "${PATH#*"$HOME/.local/bin"}" ]; then
+ _build_path() { find -L "$@" -type d ! -wholename '*/.st*' ! -wholename '*.git*' -printf '%p:'; }
+ [ -d ~/bin ] && export PATH="$(_build_path ~/bin)$PATH"
+ [ -d ~/.local/bin ] && export PATH="$(_build_path ~/.local/bin)$PATH"
+ export PATH="$PATH:$XDG_DATA_HOME/gem/ruby/3.0.0/bin"
+ export PATH="$PATH:$HOME/Applications/flutter/bin"
+fi
+
+[ -n "$TERMUX_VERSION" ] && {
+ export STORAGE="$HOME/storage"
+}
+
+export BLOCK_COLOR_LEVEL1="#66FF99"
+export BLOCK_COLOR_LEVEL2="#AAEE66"
+export BLOCK_COLOR_LEVEL3="#CCCC33"
+export BLOCK_COLOR_LEVEL4="#FF7733"
+export BLOCK_COLOR_LEVEL5="#FF3333"
+
+LS_COLORS='rs=0:\
+di=01;34:\
+ln=01;36:\
+mh=00:\
+pi=40;33:\
+so=01;35:\
+do=01;35:\
+bd=40;33;01:\
+cd=40;33;01:\
+or=40;31;01:\
+mi=00:\
+su=37;41:\
+sg=30;43:\
+ca=00:\
+tw=30;42:\
+ow=34;42:\
+st=37;44:\
+ex=01;32:\
+*.tar=01;31:\
+*.tgz=01;31:\
+*.arc=01;31:\
+*.arj=01;31:\
+*.taz=01;31:\
+*.lha=01;31:\
+*.lz4=01;31:\
+*.lzh=01;31:\
+*.lzma=01;31:\
+*.tlz=01;31:\
+*.txz=01;31:\
+*.tzo=01;31:\
+*.t7z=01;31:\
+*.zip=01;31:\
+*.z=01;31:\
+*.dz=01;31:\
+*.gz=01;31:\
+*.lrz=01;31:\
+*.lz=01;31:\
+*.lzo=01;31:\
+*.xz=01;31:\
+*.zst=01;31:\
+*.tzst=01;31:\
+*.bz2=01;31:\
+*.bz=01;31:\
+*.tbz=01;31:\
+*.tbz2=01;31:\
+*.tz=01;31:\
+*.deb=01;31:\
+*.rpm=01;31:\
+*.jar=01;31:\
+*.war=01;31:\
+*.ear=01;31:\
+*.sar=01;31:\
+*.rar=01;31:\
+*.alz=01;31:\
+*.ace=01;31:\
+*.zoo=01;31:\
+*.cpio=01;31:\
+*.7z=01;31:\
+*.rz=01;31:\
+*.cab=01;31:\
+*.wim=01;31:\
+*.swm=01;31:\
+*.dwm=01;31:\
+*.esd=01;31:\
+*.avif=01;35:\
+*.jpg=01;35:\
+*.jpeg=01;35:\
+*.mjpg=01;35:\
+*.mjpeg=01;35:\
+*.gif=01;35:\
+*.bmp=01;35:\
+*.pbm=01;35:\
+*.pgm=01;35:\
+*.ppm=01;35:\
+*.tga=01;35:\
+*.xbm=01;35:\
+*.xpm=01;35:\
+*.tif=01;35:\
+*.tiff=01;35:\
+*.png=01;35:\
+*.svg=01;35:\
+*.svgz=01;35:\
+*.mng=01;35:\
+*.pcx=01;35:\
+*.mov=01;35:\
+*.mpg=01;35:\
+*.mpeg=01;35:\
+*.m2v=01;35:\
+*.mkv=01;35:\
+*.webm=01;35:\
+*.webp=01;35:\
+*.ogm=01;35:\
+*.mp4=01;35:\
+*.m4v=01;35:\
+*.mp4v=01;35:\
+*.vob=01;35:\
+*.qt=01;35:\
+*.nuv=01;35:\
+*.wmv=01;35:\
+*.asf=01;35:\
+*.rm=01;35:\
+*.rmvb=01;35:\
+*.flc=01;35:\
+*.avi=01;35:\
+*.fli=01;35:\
+*.flv=01;35:\
+*.gl=01;35:\
+*.dl=01;35:\
+*.xcf=01;35:\
+*.xwd=01;35:\
+*.yuv=01;35:\
+*.cgm=01;35:\
+*.emf=01;35:\
+*.ogv=01;35:\
+*.ogx=01;35:\
+*.aac=00;36:\
+*.au=00;36:\
+*.flac=00;36:\
+*.m4a=00;36:\
+*.mid=00;36:\
+*.midi=00;36:\
+*.mka=00;36:\
+*.mp3=00;36:\
+*.mpc=00;36:\
+*.ogg=00;36:\
+*.ra=00;36:\
+*.wav=00;36:\
+*.oga=00;36:\
+*.opus=00;36:\
+*.spx=00;36:\
+*.xspf=00;36:\
+*~=00;90:\
+*#=00;90:\
+*.bak=00;90:\
+*.old=00;90:\
+*.orig=00;90:\
+*.part=00;90:\
+*.rej=00;90:\
+*.swp=00;90:\
+*.tmp=00;90:\
+*.dpkg-dist=00;90:\
+*.dpkg-old=00;90:\
+*.ucf-dist=00;90:\
+*.ucf-new=00;90:\
+*.ucf-old=00;90:\
+*.rpmnew=00;90:\
+*.rpmorig=00;90:\
+*.rpmsave=00;90:\
+';
diff --git a/.config/terminal-colors.d/cal.scheme b/.config/terminal-colors.d/cal.scheme
new file mode 100644
index 0000000..5d04f39
--- /dev/null
+++ b/.config/terminal-colors.d/cal.scheme
@@ -0,0 +1,5 @@
+today 30;43
+weeknumber 30;43
+header 30;44
+workday lightgreen
+weekend yellow
diff --git a/.config/tmux/tmux-gruvbox-dark.conf b/.config/tmux/tmux-gruvbox-dark.conf
new file mode 100644
index 0000000..0c3a4f9
--- /dev/null
+++ b/.config/tmux/tmux-gruvbox-dark.conf
@@ -0,0 +1,53 @@
+## COLORSCHEME: gruvbox dark (medium)
+set-option -g status "on"
+
+# default statusbar color
+set-option -g status-style bg=colour237,fg=colour223 # bg=bg1, fg=fg1
+
+# default window title colors
+set-window-option -g window-status-style bg=colour214,fg=colour237 # bg=yellow, fg=bg1
+
+# default window with an activity alert
+set-window-option -g window-status-activity-style bg=colour237,fg=colour248 # bg=bg1, fg=fg3
+
+# active window title colors
+set-window-option -g window-status-current-style bg=red,fg=colour237 # fg=bg1
+
+# pane border
+set-option -g pane-active-border-style fg=colour250 #fg2
+set-option -g pane-border-style fg=colour237 #bg1
+
+# message infos
+set-option -g message-style bg=colour239,fg=colour223 # bg=bg2, fg=fg1
+
+# writing commands inactive
+set-option -g message-command-style bg=colour239,fg=colour223 # bg=fg3, fg=bg1
+
+# pane number display
+set-option -g display-panes-active-colour colour250 #fg2
+set-option -g display-panes-colour colour237 #bg1
+
+# clock
+set-window-option -g clock-mode-colour colour109 #blue
+
+# bell
+set-window-option -g window-status-bell-style bg=colour167,fg=colour235 # bg=red, fg=bg
+
+## Theme settings mixed with colors (unfortunately, but there is no cleaner way)
+set-option -g status-justify "left"
+set-option -g status-left-style none
+set-option -g status-left-length "80"
+set-option -g status-right-style none
+set-option -g status-right-length "80"
+set-window-option -g window-status-separator ""
+
+set-option -g status-left "#[bg=colour241,fg=colour248] #S #[bg=colour237,fg=colour241,nobold,noitalics,nounderscore]"
+# set-option -g status-right "#[bg=colour237,fg=colour239 nobold, nounderscore, noitalics]#[bg=colour239,fg=colour246] %Y-%m-%d  %H:%M #[bg=colour239,fg=colour248,nobold,noitalics,nounderscore]#[bg=colour248,fg=colour237] #h "
+
+set-window-option -g window-status-current-format "#[bg=colour214,fg=colour237,nobold,noitalics,nounderscore]#[bg=colour214,fg=colour239] #I #[bg=colour214,fg=colour239,bold] #W#{?window_zoomed_flag,*Z,} #[bg=colour237,fg=colour214,nobold,noitalics,nounderscore]"
+set-window-option -g window-status-format "#[bg=colour239,fg=colour237,noitalics]#[bg=colour239,fg=colour223] #I #[bg=colour239,fg=colour223] #W #[bg=colour237,fg=colour239,noitalics]"
+
+# vim: set ft=tmux tw=0 nowrap:
+
+# user configuration
+set-option -g status-right "#[bg=colour237,fg=colour248 nobold, nounderscore, noitalics]#[bg=colour248,fg=colour237] #h "
diff --git a/.config/tmux/tmux-gruvbox-light.conf b/.config/tmux/tmux-gruvbox-light.conf
new file mode 100644
index 0000000..8761966
--- /dev/null
+++ b/.config/tmux/tmux-gruvbox-light.conf
@@ -0,0 +1,56 @@
+## COLORSCHEME: gruvbox light (medium)
+#
+# Some colors are not used by gruvbox light medium theme.
+# The main idea is to find best version of colors that fit
+# the spirit of gruvbox light theme with limited numbers of
+# 256 color palette.
+
+set-option -g status "on"
+
+# default statusbar colors
+set-option -g status-style bg=colour252,fg=colour239 # bg=notInGruvboxPallete, #fg=fg1
+
+# default window title colors
+set-window-option -g window-status-style bg=colour66,fg=colour229 # bg=aqua, fg=bg5
+
+# default window with an activity alert
+set-window-option -g window-status-activity-style bg=colour237,fg=colour241 # bg=bg1, fg=notInGruvboxPallete
+
+# active window title colors
+set-window-option -g window-status-current-style bg=default,fg=colour237 # bg=default, fg=bg1
+
+# pane border
+set-option -g pane-active-border-style fg=colour241 # fg=notInGruvboxPallete
+set-option -g pane-border-style fg=colour252 # bg1=notInGruvboxPallete
+
+# message infos (visible while writing command)
+set-option -g message-style bg=colour252,fg=colour241 # bg=notInGruvboxPallete, fg=notInGruvboxPallete
+
+# writing commands inactive
+set-option -g message-command-style bg=colour124,fg=colour241 # bg=notInGruvboxPallete, fg=notInGruvboxPallete
+
+# pane number display
+set-option -g display-panes-active-colour colour241 # notInGruvboxPallete
+set-option -g display-panes-colour colour248 # notInGruvboxPallete
+
+# clock
+set-window-option -g clock-mode-colour colour172 # orange
+
+# bell
+set-window-option -g window-status-bell-style bg=colour124,fg=colour229 # bg=red, fg=bg
+
+## Theme settings mixed with colors (unfortunately, but there is no cleaner way)
+set-option -g status-justify "left"
+set-option -g status-left-style none
+set-option -g status-left-length "80"
+set-option -g status-right-style none
+set-option -g status-right-length "80"
+set-window-option -g window-status-separator ""
+
+set-option -g status-left "#[bg=colour243,fg=colour255] #S #[bg=colour252,fg=colour243,nobold,noitalics,nounderscore]"
+set-option -g status-right "#[bg=colour252,fg=colour243,nobold,nounderscore,noitalics]#[bg=colour243,fg=colour255] %Y-%m-%d  %H:%M #[bg=colour243,fg=colour237,nobold,noitalics,nounderscore]#[bg=colour237,fg=colour255] #h "
+
+set-window-option -g window-status-current-format "#[bg=colour215,fg=colour252,nobold,noitalics,nounderscore]#[bg=colour215,fg=colour239] #I #[bg=colour215,fg=colour239,bold] #W#{?window_zoomed_flag,*Z,} #[bg=colour252,fg=colour215,nobold,noitalics,nounderscore]"
+set-window-option -g window-status-format "#[bg=colour249,fg=colour252,noitalics]#[bg=colour249,fg=colour241] #I #[bg=colour249,fg=colour241] #W #[bg=colour252,fg=colour249,noitalics]"
+
+# vim: set ft=tmux tw=0 nowrap:
diff --git a/.config/tmux/tmux-onedark-theme.tmux b/.config/tmux/tmux-onedark-theme.tmux
new file mode 100644
index 0000000..8150357
--- /dev/null
+++ b/.config/tmux/tmux-onedark-theme.tmux
@@ -0,0 +1,95 @@
+#!/bin/bash
+onedark_black="#282c34"
+onedark_blue="#61afef"
+onedark_yellow="#e5c07b"
+onedark_red="#e06c75"
+onedark_white="#aab2bf"
+onedark_green="#98c379"
+onedark_visual_grey="#3e4452"
+onedark_comment_grey="#5c6370"
+
+if [ -z "$SSH_CONNECTION" ] && [ -n "$TERMUX_VERSION" ]; then
+ onedark_white="#dddddd"
+fi
+
+get() {
+ local option=$1
+ local default_value=$2
+ local option_value="$(tmux show-option -gqv "$option")"
+
+ if [ -z "$option_value" ]; then
+ echo "$default_value"
+ else
+ echo "$option_value"
+ fi
+}
+
+set() {
+ local option=$1
+ local value=$2
+ tmux set-option -gq "$option" "$value"
+}
+
+setw() {
+ local option=$1
+ local value=$2
+ tmux set-window-option -gq "$option" "$value"
+}
+
+set "status" "on"
+set "status-justify" "left"
+
+set "status-left-length" "100"
+set "status-right-length" "100"
+set "status-right-attr" "none"
+
+set "message-fg" "$onedark_white"
+set "message-bg" "$onedark_black"
+
+set "message-command-fg" "$onedark_white"
+set "message-command-bg" "$onedark_black"
+
+set "status-attr" "none"
+set "status-left-attr" "none"
+
+setw "window-status-fg" "$onedark_black"
+setw "window-status-bg" "$onedark_black"
+setw "window-status-attr" "none"
+
+setw "window-status-activity-bg" "$onedark_black"
+setw "window-status-activity-fg" "$onedark_black"
+setw "window-status-activity-attr" "none"
+
+setw "window-status-separator" ""
+
+set "window-style" "fg=$onedark_comment_grey"
+set "window-active-style" "fg=$onedark_white"
+
+set "pane-border-fg" "$onedark_white"
+set "pane-border-bg" "$onedark_black"
+set "pane-active-border-fg" "$onedark_green"
+set "pane-active-border-bg" "$onedark_black"
+
+set "display-panes-active-colour" "$onedark_yellow"
+set "display-panes-colour" "$onedark_blue"
+
+set "status-bg" "$onedark_black"
+set "status-fg" "$onedark_white"
+
+set "@prefix_highlight_fg" "$onedark_black"
+set "@prefix_highlight_bg" "$onedark_green"
+set "@prefix_highlight_copy_mode_attr" "fg=$onedark_black,bg=$onedark_green"
+set "@prefix_highlight_output_prefix" "  "
+
+status_widgets=$(get "@onedark_widgets")
+time_format=$(get "@onedark_time_format" "%R")
+date_format=$(get "@onedark_date_format" "%d/%m/%Y")
+
+# set "status-right" "#[fg=$onedark_white,bg=$onedark_black,nounderscore,noitalics]${time_format}  ${date_format} #[fg=$onedark_visual_grey,bg=$onedark_black]#[fg=$onedark_visual_grey,bg=$onedark_visual_grey]#[fg=$onedark_white, bg=$onedark_visual_grey]${status_widgets} #[fg=$onedark_green,bg=$onedark_visual_grey,nobold,nounderscore,noitalics]#[fg=$onedark_black,bg=$onedark_green,bold] #h #[fg=$onedark_yellow, bg=$onedark_green]#[fg=$onedark_red,bg=$onedark_yellow]"
+set "status-left" "#[fg=$onedark_black,bg=$onedark_green,bold] #S #{prefix_highlight}#[fg=$onedark_green,bg=$onedark_black,nobold,nounderscore,noitalics]"
+
+set "window-status-format" "#[fg=$onedark_black,bg=$onedark_black,nobold,nounderscore,noitalics]#[fg=$onedark_white,bg=$onedark_black] #I  #W #[fg=$onedark_black,bg=$onedark_black,nobold,nounderscore,noitalics]"
+set "window-status-current-format" "#[fg=$onedark_black,bg=$onedark_visual_grey,nobold,nounderscore,noitalics]#[fg=$onedark_white,bg=$onedark_visual_grey,nobold] #I  #W #[fg=$onedark_visual_grey,bg=$onedark_black,nobold,nounderscore,noitalics]"
+
+# user configuration
+set "status-right" "#[bg=colour236,fg=colour248,nobold,noitalics,nounderscore]#[bg=colour248,fg=colour237] #h "
diff --git a/.config/tmux/tmux.conf b/.config/tmux/tmux.conf
new file mode 100644
index 0000000..cc53fde
--- /dev/null
+++ b/.config/tmux/tmux.conf
@@ -0,0 +1,77 @@
+if-shell '[ "$COLORTERM" != "${COLORTERM#*truecolor}" ]' {
+ set -g default-terminal "tmux-256color"
+ set -ga terminal-overrides ',*256col*:Tc'
+ source ~/.config/tmux/tmux-gruvbox-dark.conf
+ # run 'bash ~/.config/tmux/tmux-onedark-theme.tmux'
+}
+
+if-shell '[ -z "$SSH_CONNECTION" ] && [ -n "$TERMUX_VERSION" ]' {
+ set -g status-right ""
+}
+
+# if-shell '[ -n "$TERMUX_VERSION" ]' {
+# set -g status-right ""
+# }
+
+if-shell '[ -z "$EDITOR" ]' 'EDITOR=vi'
+
+unbind C-b
+set -g prefix `
+bind ` send-prefix
+
+set-window-option -g mode-keys vi
+set -g status-keys vi
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+bind -r C-h resize-pane -L
+bind -r C-j resize-pane -D
+bind -r C-k resize-pane -U
+bind -r C-l resize-pane -R
+bind -r M-h resize-pane -L 5
+bind -r M-j resize-pane -D 5
+bind -r M-k resize-pane -U 5
+bind -r M-l resize-pane -R 5
+
+bind -T copy-mode-vi u send -X halfpage-up
+bind -T copy-mode-vi d send -X halfpage-down
+bind -T copy-mode-vi i send -X cancel
+bind -T copy-mode-vi V send -X select-line
+bind -T copy-mode-vi v send -X rectangle-off \; send -X begin-selection
+bind -T copy-mode-vi C-v send -X rectangle-on \; send -X begin-selection
+bind -T copy-mode-vi p send -X copy-pipe \; paste-buffer
+bind -T copy-mode-vi y send -X copy-pipe
+bind -T copy-mode-vi Y send -X copy-pipe 'xclip -in -selection clipboard'
+bind -T copy-mode-vi MouseDragEnd1Pane send -X begin-selection -x
+
+bind -r \" split-window -c '#{pane_current_path}'
+bind -r % split-window -c '#{pane_current_path}' -h
+bind -r c new-window -c '#{pane_current_path}'
+bind -r \; last-window
+bind -r J rotate-window -D
+bind -r K rotate-window -U
+
+bind E new-window -t9 -n tmux.conf '$EDITOR ~/.config/tmux/tmux.conf'
+bind R source ~/.config/tmux/tmux.conf \; display "sourced config"
+bind H new-window -n tmux.help 'man tmux'
+bind G new-window -t0 gotop
+
+set -g base-index 1
+set -g escape-time 20
+set -g mouse on
+set -g display-time 0
+set -g history-limit 1000000
+
+set -g lock-command vlock
+# set -g lock-after-time 300
+bind Home lock-server
+bind End lock-session
+bind Delete lock-client
+
+bind -r C-u run -b 'brightness up'
+bind -r C-d run -b 'brightness down'
+
+# if -F "#{==:#{session_windows},1}" "set status off" "set status on"
+ set-hook -g window-linked 'if -F "#{==:#{session_windows},1}" "set status off" "set status on"'
+ set-hook -g window-unlinked 'if -F "#{==:#{session_windows},1}" "set status off" "set status on"'
diff --git a/.config/wget/wgetrc b/.config/wget/wgetrc
new file mode 100644
index 0000000..4fd7999
--- /dev/null
+++ b/.config/wget/wgetrc
@@ -0,0 +1 @@
+hsts-file=~/.cache/wget-hsts
diff --git a/.config/yt-dlp/channel.conf b/.config/yt-dlp/channel.conf
new file mode 100644
index 0000000..c742d18
--- /dev/null
+++ b/.config/yt-dlp/channel.conf
@@ -0,0 +1,12 @@
+--config videos.conf
+
+--output '%(channel)s/%(title)s.%(ext)s'
+--output 'thumbnail:%(channel)s/.thumbnail/%(title)s.%(ext)s'
+--output 'description:%(channel)s/.description/%(title)s.txt'
+
+--print-to-file %(title)s.%(ext)s %(channel)s/%(channel)s.channel.pl.txt
+# --playlist-items ::-1
+
+--write-thumbnail
+--write-playlist-metafiles
+--download-archive .info/archive.txt
diff --git a/.config/yt-dlp/config b/.config/yt-dlp/config
new file mode 100644
index 0000000..3c9c2e1
--- /dev/null
+++ b/.config/yt-dlp/config
@@ -0,0 +1,14 @@
+--output %(title)s.%(ext)s
+--restrict-filenames
+
+--format bestvideo*[height<=1080][fps<=30]+bestaudio
+--prefer-free-format
+
+--write-subs
+--write-auto-subs
+--convert-subs srt
+--embed-subs
+
+--write-description
+--embed-metadata
+--embed-chapters
diff --git a/.config/yt-dlp/playlist.conf b/.config/yt-dlp/playlist.conf
new file mode 100644
index 0000000..26adc67
--- /dev/null
+++ b/.config/yt-dlp/playlist.conf
@@ -0,0 +1,12 @@
+--config videos.conf
+
+--output '%(playlist)s/%(title)s.%(ext)s'
+--output 'thumbnail:%(playlist)s/.thumbnail/%(title)s.%(ext)s'
+--output 'description:%(playlist)s/.description/%(title)s.txt'
+
+--print-to-file %(title)s %(playlist)s/%(playlist)s.pl.txt
+--playlist-items ::-1
+
+--write-thumbnail
+--write-playlist-metafiles
+--download-archive archive.txt
diff --git a/.config/yt-dlp/sequenced-playlist.conf b/.config/yt-dlp/sequenced-playlist.conf
new file mode 100644
index 0000000..7d3f88e
--- /dev/null
+++ b/.config/yt-dlp/sequenced-playlist.conf
@@ -0,0 +1,7 @@
+--config playlist.conf
+
+--output '%(playlist)s/%(playlist_autonumber)s %(title)s.%(ext)s'
+--output 'thumbnail:%(playlist)s/.thumbnail/%(playlist_autonumber)s %(title)s.%(ext)s'
+--output 'description:%(playlist)s/.description/%(playlist_autonumber)s %(title)s'
+
+--playlist-items ::1
diff --git a/.config/yt-dlp/videos.conf b/.config/yt-dlp/videos.conf
new file mode 100644
index 0000000..cecd1bb
--- /dev/null
+++ b/.config/yt-dlp/videos.conf
@@ -0,0 +1,2 @@
+--config config
+--format bestvideo*[height<=720][fps<=30]+bestaudio
diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc
new file mode 100644
index 0000000..064e442
--- /dev/null
+++ b/.config/zathura/zathurarc
@@ -0,0 +1,10 @@
+map u scroll half-up
+map d scroll half-down
+map D toggle_page_mode
+
+map > rotate rotate-cw
+map < rotate rotate-ccw
+
+set selection-notification false
+set selection-clipboard clipboard
+set font 'monospace normal 14'
diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc
new file mode 100644
index 0000000..3f7ed30
--- /dev/null
+++ b/.config/zsh/.zshrc
@@ -0,0 +1,293 @@
+#############################
+## SHELL CONFIGURATION ##
+#############################
+
+bindkey -e
+alias find="2> >(grep -v 'Permission denied' >&2) find"
+
+source ~/.profile
+[ -n "$SDOTDIR" ] || SDOTDIR="${XDG_CONFIG_HOME:-$HOME/.config}/shell"
+[ -n "$ZDOTDIR" ] || ZDOTDIR="${XDG_CONFIG_HOME:-HOME/.config}/zsh"
+
+source "$ZDOTDIR/command-tools.zsh"
+source "$ZDOTDIR/plugins/fzf-completion.zsh"
+# source "$ZDOTDIR/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
+source "$ZDOTDIR/plugins/zsh-autosuggestions.zsh"
+
+setopt correct # Auto correct mistakes
+setopt extended_glob # Allows using regular expressions with *
+setopt rc_expand_param # Array expension with parameters
+setopt no_check_jobs # Don't warn about running processes when exiting
+setopt rm_star_silent # Don't warn when using glob with rm
+setopt numeric_glob_sort # Sort filenames numerically when it makes sense
+setopt no_beep # No beep
+setopt append_history # Immediately append history instead of overwriting
+setopt extended_history # Add timestamps to history
+setopt hist_ignore_all_dups # If a new command is a duplicate, remove the older one
+setopt auto_cd # if only directory path is entered, cd there.
+setopt auto_pushd # pushd on cd
+setopt pushd_ignore_dups # truncate duplicate directories
+setopt pushd_minus
+setopt interactive_comments # enable comments on the command line
+setopt histignorespace # ignore lines starting with a space
+
+# Enable colors and change prompt:
+autoload -U colors && colors
+PS1="%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%1~%{$fg[red]%}]%{$reset_color%}$%b "
+#PS1="%B%{$fg[red]%} %~ >%{$fg[yellow]%}%{$reset_color%}%b "
+[ -n "$LF_LEVEL" ] && PS1="$PS1(lf: $LF_LEVEL) "
+
+# Change cursor shape for different vi modes.
+function zle-keymap-select {
+ case $KEYMAP in
+ vicmd) echo -ne '\e[1 q';; # block
+ viins|main) echo -ne '\e[5 q';; # beam
+ esac
+}
+zle -N zle-keymap-select
+zle-line-init() { echo -ne "\e[5 q"; }
+zle -N zle-line-init
+# echo -ne '\e[5 q' # Use beam shape cursor on startup.
+preexec() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt.
+
+# Completion.
+autoload -Uz compinit
+compinit -d ~/.cache/zshcompdump-$ZSH_VERSION
+zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive tab completion
+zstyle ':completion:*' rehash true # automatically find new executables in path
+zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" # Colored completion (different colors for dirs/files/etc)
+zstyle ':completion:*' completer _expand _complete _ignored _approximate
+zstyle ':completion:*' menu select
+zstyle ':completion:*' select-prompt '%SScrolling active: current selection at %p%s'
+zstyle ':completion:*:descriptions' format '%U%F{cyan}%d%f%u'
+
+# Speed up completions
+zstyle ':completion:*' accept-exact '*(N)'
+zstyle ':completion:*' use-cache on
+zstyle ':completion:*' cache-path ~/.cache/zsh
+
+# automatically load bash completion functions
+autoload -U +X bashcompinit && bashcompinit
+source "$ZDOTDIR/completion/arduino-cli.zsh"
+
+ZSH_AUTOSUGGEST_STRATEGY=(history completion)
+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line vi-add-eol)
+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS+=(forward-char vi-forward-char)
+
+HISTFILE="${XDG_DATA_HOME:=$HOME/.local/share}/zsh/history"
+HISTSIZE=100000
+SAVEHIST=50000
+
+unset WORDCHARS
+stty -ixon
+
+# Angular
+# _ng_yargs_completions()
+# {
+# local reply
+# local si=$IFS
+# IFS=$'
+# ' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" ng --get-yargs-completions "${words[@]}"))
+# IFS=$si
+# _describe 'values' reply
+# }
+# compdef _ng_yargs_completions ng
+
+
+_command_fail_hook() {
+ [ $? != 1 ] && return
+ if [ -n "$TMUX" ]; then
+ tmux send-keys C-p
+ elif [ -n "$XDOTOOL_WINDOW_ID" ]; then
+ xdotool key --window "$XDOTOOL_WINDOW_ID" ctrl+p
+ fi
+}
+add-zsh-hook precmd _command_fail_hook
+
+_cd_history_hook() {
+ sed -i "\|^$PWD$|d" "${XDG_DATA_HOME:-$HOME/.local/share}/cdhist"
+ echo "$PWD" >> "${XDG_DATA_HOME:-$HOME/.local/share}/cdhist"
+}
+add-zsh-hook -Uz chpwd _cd_history_hook
+
+
+autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
+zle -N up-line-or-beginning-search
+zle -N down-line-or-beginning-search
+
+bindkey -s '^[o' '^[q lfcd^M'
+bindkey -s '^[j' '^[q lfcd "$(ff)"^M'
+bindkey -s '^[l' '^[q l^M'
+bindkey -s '^[L' '^[q lsblk^M'
+bindkey -s '^[D' '^[q dirs -v^M'
+bindkey -s '^[i' '^[q pushd -1^M'
+bindkey -s '^[-' '^[q cd -^M'
+bindkey -s '^[B' '^[q bindkey | less^M'
+
+bindkey jk vi-cmd-mode
+bindkey "^j" autosuggest-execute
+bindkey '^P' up-line-or-beginning-search
+bindkey '^N' down-line-or-beginning-search
+bindkey '^[p' up-line-or-history
+bindkey '^[n' down-line-or-history
+bindkey '^[w' backward-kill-word
+
+autoload -U edit-command-line; zle -N edit-command-line
+bindkey '^[E' edit-command-line
+
+typeset -g -A key
+if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
+ autoload -Uz add-zle-hook-widget
+ function zle_application_mode_start { echoti smkx }
+ function zle_application_mode_stop { echoti rmkx }
+ add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
+ add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
+fi
+
+
+[ -n "$DISPLAY" ] && command -V xdotool >/dev/null &&
+ XDOTOOL_WINDOW_ID="$(xdotool getactivewindow)"
+
+[ -f "$BUFFER_CACHE" ] && {
+ {
+ if [ -n "$TMUX" ]; then
+ tmux send-keys -l "$(cat "$BUFFER_CACHE")"
+ elif [ -z "$TERMUX_VERSION" ]; then
+ xdotool type --window "$XDOTOOL_WINDOW_ID" "$(cat "$BUFFER_CACHE")"
+ fi
+ rm -f "$BUFFER_CACHE"
+ } & disown
+}
+
+BUFFER_CACHE="${ZCACHEDIR:=$HOME/.cache/zsh}/previous-command-buffer-$$.tmp"
+_exec-zsh() {
+ echo "$BUFFER" > "$BUFFER_CACHE"
+ BUFFER=' exec zsh'
+ zle accept-line
+}
+zle -N exec-zsh _exec-zsh
+bindkey '^[r' exec-zsh
+
+backward-delete-word-to-slash() {
+ local WORDCHARS=${WORDCHARS/\//}
+ zle backward-delete-word
+}
+zle -N backward-delete-word-to-slash
+bindkey '^W' backward-delete-word-to-slash
+
+_fzf-file-history() {
+ LBUFFER="${LBUFFER}$(sed "s|$HOME|~|" "${XDG_DATA_HOME:-$HOME/.local/share}/openhist" | fzf --tac --reverse --height 40% | sed "s/ /\\\ /")"
+ zle reset-prompt
+}
+zle -N fzf-file-history _fzf-file-history
+bindkey '^T' fzf-file-history
+
+_fzf-cd-widget() {
+ cdpath="$(eval "${FZF_CD_COMMAND:-find -L . -type d ! -wholename '*.git*' -printf '%p/\n'}" |
+ FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --reverse --height 40% $FZF_CD_OPTS" fzf |
+ sed 's/"/\\\"/')"
+ [ -z "$cdpath" ] && { zle reset-prompt; return; }
+ zle push-line
+ BUFFER="cd -- \"$cdpath\""
+ zle reset-prompt
+ zle accept-line
+}
+zle -N fzf-cd-widget _fzf-cd-widget
+bindkey '^[c' fzf-cd-widget
+
+_cd-path-history() {
+ FZF_CD_COMMAND="< ${XDG_DATA_HOME:-$HOME/.local/share}/cdhist" \
+ FZF_CD_OPTS="--tac --tiebreak=index --no-sort" \
+ zle fzf-cd-widget
+}
+zle -N cd-path-history _cd-path-history
+bindkey '^[k' cd-path-history
+
+_fzf-history-widget() {
+ zle vi-fetch-history -n "$(fc -rl 1 | fzf --height 40% -n2.. --tiebreak=index \
+ --preview 'echo {2..}' --preview-window up:50%:hidden:wrap \
+ --bind 'ctrl-y:execute-silent(echo -n {2..} | xsel --clipboard)' \
+ --query="$LBUFFER")"
+ zle reset-prompt
+}
+zle -N fzf-history-widget _fzf-history-widget
+bindkey '^R' fzf-history-widget
+
+
+get-help() {
+ [ "$1" != sudo ] && cmd="$1" || cmd="$2"
+ cmdinfo="$(command -v "$cmd")"
+ case "${$(whence -w "$cmd")##*: }" in
+ builtin) MANPAGER="less +/'^ $cmd'" man zshbuiltins && HELP_FOUND=1 ;;
+ reserved) MANPAGER="less +/'^reserved' +/'$cmd'" man zshall && HELP_FOUND=1 ;;
+ alias) echo "$cmdinfo"; cmd="$(alias "$cmd" | sed "s/$cmd='\(\S*\) .*'/\1/")" ;;
+ esac
+ [ -n "$cmdinfo" ] && help "$cmd" || help "$1"
+}
+alias run-help='get-help'
+alias which-command='where'
+
+_get-help() {
+ cmd=(${=BUFFER})
+ zle push-line
+ case "${cmd[1]}" in
+ gh|hugo|npm|git) BUFFER="help ${cmd[1]}-${cmd[2]}" ;;
+ *) BUFFER="get-help $cmd" ;;
+ esac
+ zle accept-line
+}
+zle -N get-help _get-help
+bindkey '^[H' get-help
+
+
+[ -f "$SDOTDIR/aliasrc" ] && source "$SDOTDIR/aliasrc"
+[ -f "$SDOTDIR/shortcutrc" ] && source "$SDOTDIR/shortcutrc"
+[ -f "$ZDOTDIR/zshnameddirrc" ] && source "$ZDOTDIR/zshnameddirrc"
+
+case "$TERM" in *256*)
+ if [ -x /bin/eza ] || [ -x /usr/bin/eza ]; then
+ alias l='exa -aF --group-directories-first --color=always --icons'
+ lt() { exa --group-directories-first --color=always \
+ --icons -FaT "$@" | less -rF; }
+ fi
+
+ command -V starship >/dev/null && {
+ eval "$(starship init zsh)"
+ function set_win_title(){
+ echo -ne "\033]0; $USER@$HOST:${PWD/$HOME/~} \007"
+ }
+ precmd_functions+=(set_win_title)
+ }
+ ;;
+esac
+
+alias p='pacman'
+alias sp='sudo pacman'
+alias sv='sudo sv'
+alias mmv='noglob zmv -W'
+alias s='sudo '
+alias mirror='sudo reflector -f 30 -l 30 --number 10 --verbose --save /etc/pacman.d/mirrorlist'
+alias mirrord='sudo reflector --latest 50 --number 20 --sort delay --save /etc/pacman.d/mirrorlist'
+alias cleanup='sudo pacman -Rns $(pacman -Qtdq)'
+alias fixpacman='sudo rm /var/lib/pacman/db.lck'
+alias gtypist="gtypist $GTYPIST_OPTS"
+alias typ='launch-gtypist -l "$(sed "/^gtypist lesson - \(.*\)$/!d; s//\1/" ~/Documents/Notes/QuickNote.md)"'
+alias typa='launch-gtypist -e 3 -l "$(sed "/^gtypist lesson - \(.*\)$/!d; s//\1/" ~/Documents/Notes/ak47.txt)"'
+
+f() {
+ ret=$?
+ [ -n "$1" ] && { pacman -F "$@"; return; }
+ [ "$ret" != 127 ] && echo "Return code of last command is not 127" >&2 && return 2
+ pacman -F "$(fc -s 2>&1 | tail -1 | cut -d\ -f5-)"
+}
+
+# Execute functions with sudo
+# sudofu() {
+# [[ "$(type -w $1)" == "$1: function" ]] &&
+# ARGS="$@" && sudo bash -c "$(declare -f $1); $ARGS"
+# }
+# alias ssudo='sudofu '
+
+# Load syntax highlighter; should be last.
+source "$ZDOTDIR/plugins/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh"
+
diff --git a/.config/zsh/command-tools.zsh b/.config/zsh/command-tools.zsh
new file mode 100644
index 0000000..20126cb
--- /dev/null
+++ b/.config/zsh/command-tools.zsh
@@ -0,0 +1,61 @@
+whereis_alias() {
+ location="$(zsh -xic exit 2>&1 | sed -E "/alias[ '$]*$1=/!d" |
+ fzf --exit-0 --select-1 --ansi --header-first --header='Select alias location' |
+ sed -n "s|^\+\(/.*:[0-9]*\)>.*$|\1|p")"
+
+ if [ -z "$location" ]; then
+ echo "$0: '$1' not found in zsh debug log" >&2; return 1
+ elif [ "$location" != "${location#*shortcutrc}" ]; then
+ awk "/^$1/ {print FILENAME\":\"NR}" ~/.config/shell/bm-{files,dirs}
+ else
+ echo "$location"
+ fi
+}
+
+edit-command() {
+ [ -z "$1" ] && echo "USAGE: $0 <command>" >&2 && return 2
+ cmd="$1"
+ cmdtype=$(whence -w "$cmd" | cut -d: -f2 | tr -d ' ')
+
+ case "$cmdtype" in
+ alias)
+ query="alias ${cmd}="
+ location="$(whereis_alias "$cmd")" || return
+ file="${location%%:*}"
+ line="${location##*:}"
+ [ "$file" != "${file#*/bm-}" ] && query="^$cmd"
+ ;;
+ function)
+ query="^\s*${cmd}\s*()"
+ file=$(whence -v "$cmd" | awk '{print $NF}')
+ ;;
+ command)
+ file=$(whence -ps "$cmd" | awk -F' -> ' '{print $NF}')
+ case "$(file --mime-type --brief "$file")" in
+ text/*) $EDITOR "$file" ;;
+ *) echo "$0: not a text file: $file" >&2; return 2 ;;
+ esac
+ return
+ ;;
+ builtin) echo "$0: $cmd is a builtin command" >&2; return 2 ;;
+ reserved) echo "$0: $cmd is a reserved command" >&2; return 2 ;;
+ none) echo "$0: $cmd not found" >&2; return 2 ;;
+ *) echo "$0: unknown command type: $cmdtype" >&2; return 2 ;;
+ esac
+
+ if [ -n "$query" ]; then
+ $EDITOR +${line:-1} +/"$query" "$file"
+ else
+ $EDITOR "$file"
+ fi
+}
+
+_edit-command() {
+ [ -z "$BUFFER" ] && return 2
+ cmd=(${=BUFFER}); cmd="${cmd[1]}"
+ zle push-line
+ BUFFER="edit-command $cmd"
+ zle accept-line
+}
+zle -N edit-command _edit-command
+bindkey '^[e' edit-command
diff --git a/.config/zsh/plugins/fast-syntax-highlighting b/.config/zsh/plugins/fast-syntax-highlighting
new file mode 160000
+Subproject cf318e06a9b7c9f2219d78f41b46fa6e06011fd
diff --git a/.config/zsh/plugins/fzf-completion.zsh b/.config/zsh/plugins/fzf-completion.zsh
new file mode 100644
index 0000000..f12afca
--- /dev/null
+++ b/.config/zsh/plugins/fzf-completion.zsh
@@ -0,0 +1,329 @@
+# ____ ____
+# / __/___ / __/
+# / /_/_ / / /_
+# / __/ / /_/ __/
+# /_/ /___/_/ completion.zsh
+#
+# - $FZF_TMUX (default: 0)
+# - $FZF_TMUX_OPTS (default: '-d 40%')
+# - $FZF_COMPLETION_TRIGGER (default: '**')
+# - $FZF_COMPLETION_OPTS (default: empty)
+
+# Both branches of the following `if` do the same thing -- define
+# __fzf_completion_options such that `eval $__fzf_completion_options` sets
+# all options to the same values they currently have. We'll do just that at
+# the bottom of the file after changing options to what we prefer.
+#
+# IMPORTANT: Until we get to the `emulate` line, all words that *can* be quoted
+# *must* be quoted in order to prevent alias expansion. In addition, code must
+# be written in a way works with any set of zsh options. This is very tricky, so
+# careful when you change it.
+#
+# Start by loading the builtin zsh/parameter module. It provides `options`
+# associative array that stores current shell options.
+if 'zmodload' 'zsh/parameter' 2>'/dev/null' && (( ${+options} )); then
+ # This is the fast branch and it gets taken on virtually all Zsh installations.
+ #
+ # ${(kv)options[@]} expands to array of keys (option names) and values ("on"
+ # or "off"). The subsequent expansion# with (j: :) flag joins all elements
+ # together separated by spaces. __fzf_completion_options ends up with a value
+ # like this: "options=(shwordsplit off aliases on ...)".
+ __fzf_completion_options="options=(${(j: :)${(kv)options[@]}})"
+else
+ # This branch is much slower because it forks to get the names of all
+ # zsh options. It's possible to eliminate this fork but it's not worth the
+ # trouble because this branch gets taken only on very ancient or broken
+ # zsh installations.
+ () {
+ # That `()` above defines an anonymous function. This is essentially a scope
+ # for local parameters. We use it to avoid polluting global scope.
+ 'local' '__fzf_opt'
+ __fzf_completion_options="setopt"
+ # `set -o` prints one line for every zsh option. Each line contains option
+ # name, some spaces, and then either "on" or "off". We just want option names.
+ # Expansion with (@f) flag splits a string into lines. The outer expansion
+ # removes spaces and everything that follow them on every line. __fzf_opt
+ # ends up iterating over option names: shwordsplit, aliases, etc.
+ for __fzf_opt in "${(@)${(@f)$(set -o)}%% *}"; do
+ if [[ -o "$__fzf_opt" ]]; then
+ # Option $__fzf_opt is currently on, so remember to set it back on.
+ __fzf_completion_options+=" -o $__fzf_opt"
+ else
+ # Option $__fzf_opt is currently off, so remember to set it back off.
+ __fzf_completion_options+=" +o $__fzf_opt"
+ fi
+ done
+ # The value of __fzf_completion_options here looks like this:
+ # "setopt +o shwordsplit -o aliases ..."
+ }
+fi
+
+# Enable the default zsh options (those marked with <Z> in `man zshoptions`)
+# but without `aliases`. Aliases in functions are expanded when functions are
+# defined, so if we disable aliases here, we'll be sure to have no pesky
+# aliases in any of our functions. This way we won't need prefix every
+# command with `command` or to quote every word to defend against global
+# aliases. Note that `aliases` is not the only option that's important to
+# control. There are several others that could wreck havoc if they are set
+# to values we don't expect. With the following `emulate` command we
+# sidestep this issue entirely.
+'emulate' 'zsh' '-o' 'no_aliases'
+
+# This brace is the start of try-always block. The `always` part is like
+# `finally` in lesser languages. We use it to *always* restore user options.
+{
+
+# Bail out if not interactive shell.
+[[ -o interactive ]] || return 0
+
+# To use custom commands instead of find, override _fzf_compgen_{path,dir}
+if ! declare -f _fzf_compgen_path > /dev/null; then
+ _fzf_compgen_path() {
+ echo "$1"
+ command find -L "$1" \
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
+ }
+fi
+
+if ! declare -f _fzf_compgen_dir > /dev/null; then
+ _fzf_compgen_dir() {
+ command find -L "$1" \
+ -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
+ -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
+ }
+fi
+
+###########################################################
+
+__fzf_comprun() {
+ if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then
+ _fzf_comprun "$@"
+ elif [ -n "$TMUX_PANE" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "$FZF_TMUX_OPTS" ]; }; then
+ shift
+ if [ -n "$FZF_TMUX_OPTS" ]; then
+ fzf-tmux ${(Q)${(Z+n+)FZF_TMUX_OPTS}} -- "$@"
+ else
+ fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%} -- "$@"
+ fi
+ else
+ shift
+ fzf "$@"
+ fi
+}
+
+# Extract the name of the command. e.g. foo=1 bar baz**<tab>
+__fzf_extract_command() {
+ local token tokens
+ tokens=(${(z)1})
+ for token in $tokens; do
+ token=${(Q)token}
+ if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
+ echo "$token"
+ return
+ fi
+ done
+ echo "${tokens[1]}"
+}
+
+__fzf_generic_path_completion() {
+ local base lbuf cmd compgen fzf_opts suffix tail dir leftover matches
+ base=$1
+ lbuf=$2
+ cmd=$(__fzf_extract_command "$lbuf")
+ compgen=$3
+ fzf_opts=$4
+ suffix=$5
+ tail=$6
+
+ setopt localoptions nonomatch
+ eval "base=$base"
+ [[ $base = *"/"* ]] && dir="$base"
+ while [ 1 ]; do
+ if [[ -z "$dir" || -d ${dir} ]]; then
+ leftover=${base/#"$dir"}
+ leftover=${leftover/#\/}
+ [ -z "$dir" ] && dir='.'
+ [ "$dir" != "/" ] && dir="${dir/%\//}"
+ matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do
+ echo -n "${(q)item}$suffix "
+ done)
+ matches=${matches% }
+ if [ -n "$matches" ]; then
+ LBUFFER="$lbuf$matches$tail"
+ fi
+ zle reset-prompt
+ break
+ fi
+ dir=$(dirname "$dir")
+ dir=${dir%/}/
+ done
+}
+
+_fzf_path_completion() {
+ __fzf_generic_path_completion "$1" "$2" _fzf_compgen_path \
+ "-m" "" " "
+}
+
+_fzf_dir_completion() {
+ __fzf_generic_path_completion "$1" "$2" _fzf_compgen_dir \
+ "" "/" ""
+}
+
+_fzf_feed_fifo() (
+ command rm -f "$1"
+ mkfifo "$1"
+ cat <&0 > "$1" &
+)
+
+_fzf_complete() {
+ setopt localoptions ksh_arrays
+ # Split arguments around --
+ local args rest str_arg i sep
+ args=("$@")
+ sep=
+ for i in {0..${#args[@]}}; do
+ if [[ "${args[$i]}" = -- ]]; then
+ sep=$i
+ break
+ fi
+ done
+ if [[ -n "$sep" ]]; then
+ str_arg=
+ rest=("${args[@]:$((sep + 1)):${#args[@]}}")
+ args=("${args[@]:0:$sep}")
+ else
+ str_arg=$1
+ args=()
+ shift
+ rest=("$@")
+ fi
+
+ local fifo lbuf cmd matches post
+ fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$"
+ lbuf=${rest[0]}
+ cmd=$(__fzf_extract_command "$lbuf")
+ post="${funcstack[1]}_post"
+ type $post > /dev/null 2>&1 || post=cat
+
+ _fzf_feed_fifo "$fifo"
+ matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ')
+ if [ -n "$matches" ]; then
+ LBUFFER="$lbuf$matches"
+ fi
+ command rm -f "$fifo"
+}
+
+_fzf_complete_telnet() {
+ _fzf_complete +m -- "$@" < <(
+ command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
+ awk '{if (length($2) > 0) {print $2}}' | sort -u
+ )
+}
+
+_fzf_complete_ssh() {
+ _fzf_complete +m -- "$@" < <(
+ setopt localoptions nonomatch
+ command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \
+ <(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
+ <(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
+ awk '{if (length($2) > 0) {print $2}}' | sort -u
+ )
+}
+
+_fzf_complete_export() {
+ _fzf_complete -m -- "$@" < <(
+ declare -xp | sed 's/=.*//' | sed 's/.* //'
+ )
+}
+
+_fzf_complete_unset() {
+ _fzf_complete -m -- "$@" < <(
+ declare -xp | sed 's/=.*//' | sed 's/.* //'
+ )
+}
+
+_fzf_complete_unalias() {
+ _fzf_complete +m -- "$@" < <(
+ alias | sed 's/=.*//'
+ )
+}
+
+_fzf_complete_kill() {
+ _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
+ command ps -ef | sed 1d
+ )
+}
+
+_fzf_complete_kill_post() {
+ awk '{print $2}'
+}
+
+fzf-completion() {
+ local tokens cmd prefix trigger tail matches lbuf d_cmds
+ setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
+
+ # http://zsh.sourceforge.net/FAQ/zshfaq03.html
+ # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
+ tokens=(${(z)LBUFFER})
+ if [ ${#tokens} -lt 1 ]; then
+ zle ${fzf_default_completion:-expand-or-complete}
+ return
+ fi
+
+ cmd=$(__fzf_extract_command "$LBUFFER")
+
+ # Explicitly allow for empty trigger.
+ trigger=${FZF_COMPLETION_TRIGGER-'**'}
+ [ -z "$trigger" -a ${LBUFFER[-1]} = ' ' ] && tokens+=("")
+
+ # When the trigger starts with ';', it becomes a separate token
+ if [[ ${LBUFFER} = *"${tokens[-2]}${tokens[-1]}" ]]; then
+ tokens[-2]="${tokens[-2]}${tokens[-1]}"
+ tokens=(${tokens[0,-2]})
+ fi
+
+ lbuf=$LBUFFER
+ tail=${LBUFFER:$(( ${#LBUFFER} - ${#trigger} ))}
+ # Kill completion (do not require trigger sequence)
+ if [ "$cmd" = kill -a ${LBUFFER[-1]} = ' ' ]; then
+ tail=$trigger
+ tokens+=$trigger
+ lbuf="$lbuf$trigger"
+ fi
+
+ # Trigger sequence given
+ if [ ${#tokens} -gt 1 -a "$tail" = "$trigger" ]; then
+ d_cmds=(${=FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir})
+
+ [ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}}
+ [ -n "${tokens[-1]}" ] && lbuf=${lbuf:0:-${#tokens[-1]}}
+
+ if eval "type _fzf_complete_${cmd} > /dev/null"; then
+ prefix="$prefix" eval _fzf_complete_${cmd} ${(q)lbuf}
+ zle reset-prompt
+ elif [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then
+ _fzf_dir_completion "$prefix" "$lbuf"
+ else
+ _fzf_path_completion "$prefix" "$lbuf"
+ fi
+ # Fall back to default completion
+ else
+ zle ${fzf_default_completion:-expand-or-complete}
+ fi
+}
+
+[ -z "$fzf_default_completion" ] && {
+ binding=$(bindkey '^I')
+ [[ $binding =~ 'undefined-key' ]] || fzf_default_completion=$binding[(s: :w)2]
+ unset binding
+}
+
+zle -N fzf-completion
+bindkey '^I' fzf-completion
+
+} always {
+ # Restore the original options.
+ eval $__fzf_completion_options
+ 'unset' '__fzf_completion_options'
+}
diff --git a/.config/zsh/plugins/zsh-autosuggestions.zsh b/.config/zsh/plugins/zsh-autosuggestions.zsh
new file mode 100644
index 0000000..b19cac7
--- /dev/null
+++ b/.config/zsh/plugins/zsh-autosuggestions.zsh
@@ -0,0 +1,864 @@
+# Fish-like fast/unobtrusive autosuggestions for zsh.
+# https://github.com/zsh-users/zsh-autosuggestions
+# v0.7.0
+# Copyright (c) 2013 Thiago de Arruda
+# Copyright (c) 2016-2021 Eric Freese
+#
+# 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.
+
+#--------------------------------------------------------------------#
+# Global Configuration Variables #
+#--------------------------------------------------------------------#
+
+# Color to use when highlighting suggestion
+# Uses format of `region_highlight`
+# More info: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Widgets
+(( ! ${+ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE} )) &&
+typeset -g ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'
+
+# Prefix to use when saving original versions of bound widgets
+(( ! ${+ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX} )) &&
+typeset -g ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig-
+
+# Strategies to use to fetch a suggestion
+# Will try each strategy in order until a suggestion is returned
+(( ! ${+ZSH_AUTOSUGGEST_STRATEGY} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_STRATEGY
+ ZSH_AUTOSUGGEST_STRATEGY=(history)
+}
+
+# Widgets that clear the suggestion
+(( ! ${+ZSH_AUTOSUGGEST_CLEAR_WIDGETS} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_CLEAR_WIDGETS
+ ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(
+ history-search-forward
+ history-search-backward
+ history-beginning-search-forward
+ history-beginning-search-backward
+ history-substring-search-up
+ history-substring-search-down
+ up-line-or-beginning-search
+ down-line-or-beginning-search
+ up-line-or-history
+ down-line-or-history
+ accept-line
+ copy-earlier-word
+ )
+}
+
+# Widgets that accept the entire suggestion
+(( ! ${+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_ACCEPT_WIDGETS
+ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(
+ forward-char
+ end-of-line
+ vi-forward-char
+ vi-end-of-line
+ vi-add-eol
+ )
+}
+
+# Widgets that accept the entire suggestion and execute it
+(( ! ${+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_EXECUTE_WIDGETS
+ ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=(
+ )
+}
+
+# Widgets that accept the suggestion as far as the cursor moves
+(( ! ${+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS
+ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
+ forward-word
+ emacs-forward-word
+ vi-forward-word
+ vi-forward-word-end
+ vi-forward-blank-word
+ vi-forward-blank-word-end
+ vi-find-next-char
+ vi-find-next-char-skip
+ )
+}
+
+# Widgets that should be ignored (globbing supported but must be escaped)
+(( ! ${+ZSH_AUTOSUGGEST_IGNORE_WIDGETS} )) && {
+ typeset -ga ZSH_AUTOSUGGEST_IGNORE_WIDGETS
+ ZSH_AUTOSUGGEST_IGNORE_WIDGETS=(
+ orig-\*
+ beep
+ run-help
+ set-local-history
+ which-command
+ yank
+ yank-pop
+ zle-\*
+ )
+}
+
+# Pty name for capturing completions for completion suggestion strategy
+(( ! ${+ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME} )) &&
+typeset -g ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME=zsh_autosuggest_completion_pty
+
+#--------------------------------------------------------------------#
+# Utility Functions #
+#--------------------------------------------------------------------#
+
+_zsh_autosuggest_escape_command() {
+ setopt localoptions EXTENDED_GLOB
+
+ # Escape special chars in the string (requires EXTENDED_GLOB)
+ echo -E "${1//(#m)[\"\'\\()\[\]|*?~]/\\$MATCH}"
+}
+
+#--------------------------------------------------------------------#
+# Widget Helpers #
+#--------------------------------------------------------------------#
+
+_zsh_autosuggest_incr_bind_count() {
+ typeset -gi bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]+1))
+ _ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=$bind_count
+}
+
+# Bind a single widget to an autosuggest widget, saving a reference to the original widget
+_zsh_autosuggest_bind_widget() {
+ typeset -gA _ZSH_AUTOSUGGEST_BIND_COUNTS
+
+ local widget=$1
+ local autosuggest_action=$2
+ local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX
+
+ local -i bind_count
+
+ # Save a reference to the original widget
+ case $widgets[$widget] in
+ # Already bound
+ user:_zsh_autosuggest_(bound|orig)_*)
+ bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$widget]))
+ ;;
+
+ # User-defined widget
+ user:*)
+ _zsh_autosuggest_incr_bind_count $widget
+ zle -N $prefix$bind_count-$widget ${widgets[$widget]#*:}
+ ;;
+
+ # Built-in widget
+ builtin)
+ _zsh_autosuggest_incr_bind_count $widget
+ eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }"
+ zle -N $prefix$bind_count-$widget _zsh_autosuggest_orig_$widget
+ ;;
+
+ # Completion widget
+ completion:*)
+ _zsh_autosuggest_incr_bind_count $widget
+ eval "zle -C $prefix$bind_count-${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}"
+ ;;
+ esac
+
+ # Pass the original widget's name explicitly into the autosuggest
+ # function. Use this passed in widget name to call the original
+ # widget instead of relying on the $WIDGET variable being set
+ # correctly. $WIDGET cannot be trusted because other plugins call
+ # zle without the `-w` flag (e.g. `zle self-insert` instead of
+ # `zle self-insert -w`).
+ eval "_zsh_autosuggest_bound_${bind_count}_${(q)widget}() {
+ _zsh_autosuggest_widget_$autosuggest_action $prefix$bind_count-${(q)widget} \$@
+ }"
+
+ # Create the bound widget
+ zle -N -- $widget _zsh_autosuggest_bound_${bind_count}_$widget
+}
+
+# Map all configured widgets to the right autosuggest widgets
+_zsh_autosuggest_bind_widgets() {
+ emulate -L zsh
+
+ local widget
+ local ignore_widgets
+
+ ignore_widgets=(
+ .\*
+ _\*
+ ${_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS/#/autosuggest-}
+ $ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX\*
+ $ZSH_AUTOSUGGEST_IGNORE_WIDGETS
+ )
+
+ # Find every widget we might want to bind and bind it appropriately
+ for widget in ${${(f)"$(builtin zle -la)"}:#${(j:|:)~ignore_widgets}}; do
+ if [[ -n ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]]; then
+ _zsh_autosuggest_bind_widget $widget clear
+ elif [[ -n ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]]; then
+ _zsh_autosuggest_bind_widget $widget accept
+ elif [[ -n ${ZSH_AUTOSUGGEST_EXECUTE_WIDGETS[(r)$widget]} ]]; then
+ _zsh_autosuggest_bind_widget $widget execute
+ elif [[ -n ${ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS[(r)$widget]} ]]; then
+ _zsh_autosuggest_bind_widget $widget partial_accept
+ else
+ # Assume any unspecified widget might modify the buffer
+ _zsh_autosuggest_bind_widget $widget modify
+ fi
+ done
+}
+
+# Given the name of an original widget and args, invoke it, if it exists
+_zsh_autosuggest_invoke_original_widget() {
+ # Do nothing unless called with at least one arg
+ (( $# )) || return 0
+
+ local original_widget_name="$1"
+
+ shift
+
+ if (( ${+widgets[$original_widget_name]} )); then
+ zle $original_widget_name -- $@
+ fi
+}
+
+#--------------------------------------------------------------------#
+# Highlighting #
+#--------------------------------------------------------------------#
+
+# If there was a highlight, remove it
+_zsh_autosuggest_highlight_reset() {
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
+
+ if [[ -n "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" ]]; then
+ region_highlight=("${(@)region_highlight:#$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT}")
+ unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
+ fi
+}
+
+# If there's a suggestion, highlight it
+_zsh_autosuggest_highlight_apply() {
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
+
+ if (( $#POSTDISPLAY )); then
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT="$#BUFFER $(($#BUFFER + $#POSTDISPLAY)) $ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE"
+ region_highlight+=("$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT")
+ else
+ unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
+ fi
+}
+
+#--------------------------------------------------------------------#
+# Autosuggest Widget Implementations #
+#--------------------------------------------------------------------#
+
+# Disable suggestions
+_zsh_autosuggest_disable() {
+ typeset -g _ZSH_AUTOSUGGEST_DISABLED
+ _zsh_autosuggest_clear
+}
+
+# Enable suggestions
+_zsh_autosuggest_enable() {
+ unset _ZSH_AUTOSUGGEST_DISABLED
+
+ if (( $#BUFFER )); then
+ _zsh_autosuggest_fetch
+ fi
+}
+
+# Toggle suggestions (enable/disable)
+_zsh_autosuggest_toggle() {
+ if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then
+ _zsh_autosuggest_enable
+ else
+ _zsh_autosuggest_disable
+ fi
+}
+
+# Clear the suggestion
+_zsh_autosuggest_clear() {
+ # Remove the suggestion
+ unset POSTDISPLAY
+
+ _zsh_autosuggest_invoke_original_widget $@
+}
+
+# Modify the buffer and get a new suggestion
+_zsh_autosuggest_modify() {
+ local -i retval
+
+ # Only available in zsh >= 5.4
+ local -i KEYS_QUEUED_COUNT
+
+ # Save the contents of the buffer/postdisplay
+ local orig_buffer="$BUFFER"
+ local orig_postdisplay="$POSTDISPLAY"
+
+ # Clear suggestion while waiting for next one
+ unset POSTDISPLAY
+
+ # Original widget may modify the buffer
+ _zsh_autosuggest_invoke_original_widget $@
+ retval=$?
+
+ emulate -L zsh
+
+ # Don't fetch a new suggestion if there's more input to be read immediately
+ if (( $PENDING > 0 || $KEYS_QUEUED_COUNT > 0 )); then
+ POSTDISPLAY="$orig_postdisplay"
+ return $retval
+ fi
+
+ # Optimize if manually typing in the suggestion or if buffer hasn't changed
+ if [[ "$BUFFER" = "$orig_buffer"* && "$orig_postdisplay" = "${BUFFER:$#orig_buffer}"* ]]; then
+ POSTDISPLAY="${orig_postdisplay:$(($#BUFFER - $#orig_buffer))}"
+ return $retval
+ fi
+
+ # Bail out if suggestions are disabled
+ if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then
+ return $?
+ fi
+
+ # Get a new suggestion if the buffer is not empty after modification
+ if (( $#BUFFER > 0 )); then
+ if [[ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]] || (( $#BUFFER <= $ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE )); then
+ _zsh_autosuggest_fetch
+ fi
+ fi
+
+ return $retval
+}
+
+# Fetch a new suggestion based on what's currently in the buffer
+_zsh_autosuggest_fetch() {
+ if (( ${+ZSH_AUTOSUGGEST_USE_ASYNC} )); then
+ _zsh_autosuggest_async_request "$BUFFER"
+ else
+ local suggestion
+ _zsh_autosuggest_fetch_suggestion "$BUFFER"
+ _zsh_autosuggest_suggest "$suggestion"
+ fi
+}
+
+# Offer a suggestion
+_zsh_autosuggest_suggest() {
+ emulate -L zsh
+
+ local suggestion="$1"
+
+ if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
+ POSTDISPLAY="${suggestion#$BUFFER}"
+ else
+ unset POSTDISPLAY
+ fi
+}
+
+# Accept the entire suggestion
+_zsh_autosuggest_accept() {
+ local -i retval max_cursor_pos=$#BUFFER
+
+ # When vicmd keymap is active, the cursor can't move all the way
+ # to the end of the buffer
+ if [[ "$KEYMAP" = "vicmd" ]]; then
+ max_cursor_pos=$((max_cursor_pos - 1))
+ fi
+
+ # If we're not in a valid state to accept a suggestion, just run the
+ # original widget and bail out
+ if (( $CURSOR != $max_cursor_pos || !$#POSTDISPLAY )); then
+ _zsh_autosuggest_invoke_original_widget $@
+ return
+ fi
+
+ # Only accept if the cursor is at the end of the buffer
+ # Add the suggestion to the buffer
+ BUFFER="$BUFFER$POSTDISPLAY"
+
+ # Remove the suggestion
+ unset POSTDISPLAY
+
+ # Run the original widget before manually moving the cursor so that the
+ # cursor movement doesn't make the widget do something unexpected
+ _zsh_autosuggest_invoke_original_widget $@
+ retval=$?
+
+ # Move the cursor to the end of the buffer
+ if [[ "$KEYMAP" = "vicmd" ]]; then
+ CURSOR=$(($#BUFFER - 1))
+ else
+ CURSOR=$#BUFFER
+ fi
+
+ return $retval
+}
+
+# Accept the entire suggestion and execute it
+_zsh_autosuggest_execute() {
+ # Add the suggestion to the buffer
+ BUFFER="$BUFFER$POSTDISPLAY"
+
+ # Remove the suggestion
+ unset POSTDISPLAY
+
+ # Call the original `accept-line` to handle syntax highlighting or
+ # other potential custom behavior
+ _zsh_autosuggest_invoke_original_widget "accept-line"
+}
+
+# Partially accept the suggestion
+_zsh_autosuggest_partial_accept() {
+ local -i retval cursor_loc
+
+ # Save the contents of the buffer so we can restore later if needed
+ local original_buffer="$BUFFER"
+
+ # Temporarily accept the suggestion.
+ BUFFER="$BUFFER$POSTDISPLAY"
+
+ # Original widget moves the cursor
+ _zsh_autosuggest_invoke_original_widget $@
+ retval=$?
+
+ # Normalize cursor location across vi/emacs modes
+ cursor_loc=$CURSOR
+ if [[ "$KEYMAP" = "vicmd" ]]; then
+ cursor_loc=$((cursor_loc + 1))
+ fi
+
+ # If we've moved past the end of the original buffer
+ if (( $cursor_loc > $#original_buffer )); then
+ # Set POSTDISPLAY to text right of the cursor
+ POSTDISPLAY="${BUFFER[$(($cursor_loc + 1)),$#BUFFER]}"
+
+ # Clip the buffer at the cursor
+ BUFFER="${BUFFER[1,$cursor_loc]}"
+ else
+ # Restore the original buffer
+ BUFFER="$original_buffer"
+ fi
+
+ return $retval
+}
+
+() {
+ typeset -ga _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS
+
+ _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS=(
+ clear
+ fetch
+ suggest
+ accept
+ execute
+ enable
+ disable
+ toggle
+ )
+
+ local action
+ for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS modify partial_accept; do
+ eval "_zsh_autosuggest_widget_$action() {
+ local -i retval
+
+ _zsh_autosuggest_highlight_reset
+
+ _zsh_autosuggest_$action \$@
+ retval=\$?
+
+ _zsh_autosuggest_highlight_apply
+
+ zle -R
+
+ return \$retval
+ }"
+ done
+
+ for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS; do
+ zle -N autosuggest-$action _zsh_autosuggest_widget_$action
+ done
+}
+
+#--------------------------------------------------------------------#
+# Completion Suggestion Strategy #
+#--------------------------------------------------------------------#
+# Fetches a suggestion from the completion engine
+#
+
+_zsh_autosuggest_capture_postcompletion() {
+ # Always insert the first completion into the buffer
+ compstate[insert]=1
+
+ # Don't list completions
+ unset 'compstate[list]'
+}
+
+_zsh_autosuggest_capture_completion_widget() {
+ # Add a post-completion hook to be called after all completions have been
+ # gathered. The hook can modify compstate to affect what is done with the
+ # gathered completions.
+ local -a +h comppostfuncs
+ comppostfuncs=(_zsh_autosuggest_capture_postcompletion)
+
+ # Only capture completions at the end of the buffer
+ CURSOR=$#BUFFER
+
+ # Run the original widget wrapping `.complete-word` so we don't
+ # recursively try to fetch suggestions, since our pty is forked
+ # after autosuggestions is initialized.
+ zle -- ${(k)widgets[(r)completion:.complete-word:_main_complete]}
+
+ if is-at-least 5.0.3; then
+ # Don't do any cr/lf transformations. We need to do this immediately before
+ # output because if we do it in setup, onlcr will be re-enabled when we enter
+ # vared in the async code path. There is a bug in zpty module in older versions
+ # where the tty is not properly attached to the pty slave, resulting in stty
+ # getting stopped with a SIGTTOU. See zsh-workers thread 31660 and upstream
+ # commit f75904a38
+ stty -onlcr -ocrnl -F /dev/tty
+ fi
+
+ # The completion has been added, print the buffer as the suggestion
+ echo -nE - $'\0'$BUFFER$'\0'
+}
+
+zle -N autosuggest-capture-completion _zsh_autosuggest_capture_completion_widget
+
+_zsh_autosuggest_capture_setup() {
+ # There is a bug in zpty module in older zsh versions by which a
+ # zpty that exits will kill all zpty processes that were forked
+ # before it. Here we set up a zsh exit hook to SIGKILL the zpty
+ # process immediately, before it has a chance to kill any other
+ # zpty processes.
+ if ! is-at-least 5.4; then
+ zshexit() {
+ # The zsh builtin `kill` fails sometimes in older versions
+ # https://unix.stackexchange.com/a/477647/156673
+ kill -KILL $$ 2>&- || command kill -KILL $$
+
+ # Block for long enough for the signal to come through
+ sleep 1
+ }
+ fi
+
+ # Try to avoid any suggestions that wouldn't match the prefix
+ zstyle ':completion:*' matcher-list ''
+ zstyle ':completion:*' path-completion false
+ zstyle ':completion:*' max-errors 0 not-numeric
+
+ bindkey '^I' autosuggest-capture-completion
+}
+
+_zsh_autosuggest_capture_completion_sync() {
+ _zsh_autosuggest_capture_setup
+
+ zle autosuggest-capture-completion
+}
+
+_zsh_autosuggest_capture_completion_async() {
+ _zsh_autosuggest_capture_setup
+
+ zmodload zsh/parameter 2>/dev/null || return # For `$functions`
+
+ # Make vared completion work as if for a normal command line
+ # https://stackoverflow.com/a/7057118/154703
+ autoload +X _complete
+ functions[_original_complete]=$functions[_complete]
+ function _complete() {
+ unset 'compstate[vared]'
+ _original_complete "$@"
+ }
+
+ # Open zle with buffer set so we can capture completions for it
+ vared 1
+}
+
+_zsh_autosuggest_strategy_completion() {
+ # Reset options to defaults and enable LOCAL_OPTIONS
+ emulate -L zsh
+
+ # Enable extended glob for completion ignore pattern
+ setopt EXTENDED_GLOB
+
+ typeset -g suggestion
+ local line REPLY
+
+ # Exit if we don't have completions
+ whence compdef >/dev/null || return
+
+ # Exit if we don't have zpty
+ zmodload zsh/zpty 2>/dev/null || return
+
+ # Exit if our search string matches the ignore pattern
+ [[ -n "$ZSH_AUTOSUGGEST_COMPLETION_IGNORE" ]] && [[ "$1" == $~ZSH_AUTOSUGGEST_COMPLETION_IGNORE ]] && return
+
+ # Zle will be inactive if we are in async mode
+ if zle; then
+ zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_sync
+ else
+ zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_async "\$1"
+ zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME $'\t'
+ fi
+
+ {
+ # The completion result is surrounded by null bytes, so read the
+ # content between the first two null bytes.
+ zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0''*'$'\0'
+
+ # Extract the suggestion from between the null bytes. On older
+ # versions of zsh (older than 5.3), we sometimes get extra bytes after
+ # the second null byte, so trim those off the end.
+ # See http://www.zsh.org/mla/workers/2015/msg03290.html
+ suggestion="${${(@0)line}[2]}"
+ } always {
+ # Destroy the pty
+ zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME
+ }
+}
+
+#--------------------------------------------------------------------#
+# History Suggestion Strategy #
+#--------------------------------------------------------------------#
+# Suggests the most recent history item that matches the given
+# prefix.
+#
+
+_zsh_autosuggest_strategy_history() {
+ # Reset options to defaults and enable LOCAL_OPTIONS
+ emulate -L zsh
+
+ # Enable globbing flags so that we can use (#m) and (x~y) glob operator
+ setopt EXTENDED_GLOB
+
+ # Escape backslashes and all of the glob operators so we can use
+ # this string as a pattern to search the $history associative array.
+ # - (#m) globbing flag enables setting references for match data
+ # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
+ local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
+
+ # Get the history items that match the prefix, excluding those that match
+ # the ignore pattern
+ local pattern="$prefix*"
+ if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
+ pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
+ fi
+
+ # Give the first history item matching the pattern as the suggestion
+ # - (r) subscript flag makes the pattern match on values
+ typeset -g suggestion="${history[(r)$pattern]}"
+}
+
+#--------------------------------------------------------------------#
+# Match Previous Command Suggestion Strategy #
+#--------------------------------------------------------------------#
+# Suggests the most recent history item that matches the given
+# prefix and whose preceding history item also matches the most
+# recently executed command.
+#
+# For example, suppose your history has the following entries:
+# - pwd
+# - ls foo
+# - ls bar
+# - pwd
+#
+# Given the history list above, when you type 'ls', the suggestion
+# will be 'ls foo' rather than 'ls bar' because your most recently
+# executed command (pwd) was previously followed by 'ls foo'.
+#
+# Note that this strategy won't work as expected with ZSH options that don't
+# preserve the history order such as `HIST_IGNORE_ALL_DUPS` or
+# `HIST_EXPIRE_DUPS_FIRST`.
+
+_zsh_autosuggest_strategy_match_prev_cmd() {
+ # Reset options to defaults and enable LOCAL_OPTIONS
+ emulate -L zsh
+
+ # Enable globbing flags so that we can use (#m) and (x~y) glob operator
+ setopt EXTENDED_GLOB
+
+ # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
+ local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
+
+ # Get the history items that match the prefix, excluding those that match
+ # the ignore pattern
+ local pattern="$prefix*"
+ if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
+ pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
+ fi
+
+ # Get all history event numbers that correspond to history
+ # entries that match the pattern
+ local history_match_keys
+ history_match_keys=(${(k)history[(R)$~pattern]})
+
+ # By default we use the first history number (most recent history entry)
+ local histkey="${history_match_keys[1]}"
+
+ # Get the previously executed command
+ local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
+
+ # Iterate up to the first 200 history event numbers that match $prefix
+ for key in "${(@)history_match_keys[1,200]}"; do
+ # Stop if we ran out of history
+ [[ $key -gt 1 ]] || break
+
+ # See if the history entry preceding the suggestion matches the
+ # previous command, and use it if it does
+ if [[ "${history[$((key - 1))]}" == "$prev_cmd" ]]; then
+ histkey="$key"
+ break
+ fi
+ done
+
+ # Give back the matched history entry
+ typeset -g suggestion="$history[$histkey]"
+}
+
+#--------------------------------------------------------------------#
+# Fetch Suggestion #
+#--------------------------------------------------------------------#
+# Loops through all specified strategies and returns a suggestion
+# from the first strategy to provide one.
+#
+
+_zsh_autosuggest_fetch_suggestion() {
+ typeset -g suggestion
+ local -a strategies
+ local strategy
+
+ # Ensure we are working with an array
+ strategies=(${=ZSH_AUTOSUGGEST_STRATEGY})
+
+ for strategy in $strategies; do
+ # Try to get a suggestion from this strategy
+ _zsh_autosuggest_strategy_$strategy "$1"
+
+ # Ensure the suggestion matches the prefix
+ [[ "$suggestion" != "$1"* ]] && unset suggestion
+
+ # Break once we've found a valid suggestion
+ [[ -n "$suggestion" ]] && break
+ done
+}
+
+#--------------------------------------------------------------------#
+# Async #
+#--------------------------------------------------------------------#
+
+_zsh_autosuggest_async_request() {
+ zmodload zsh/system 2>/dev/null # For `$sysparams`
+
+ typeset -g _ZSH_AUTOSUGGEST_ASYNC_FD _ZSH_AUTOSUGGEST_CHILD_PID
+
+ # If we've got a pending request, cancel it
+ if [[ -n "$_ZSH_AUTOSUGGEST_ASYNC_FD" ]] && { true <&$_ZSH_AUTOSUGGEST_ASYNC_FD } 2>/dev/null; then
+ # Close the file descriptor and remove the handler
+ exec {_ZSH_AUTOSUGGEST_ASYNC_FD}<&-
+ zle -F $_ZSH_AUTOSUGGEST_ASYNC_FD
+
+ # We won't know the pid unless the user has zsh/system module installed
+ if [[ -n "$_ZSH_AUTOSUGGEST_CHILD_PID" ]]; then
+ # Zsh will make a new process group for the child process only if job
+ # control is enabled (MONITOR option)
+ if [[ -o MONITOR ]]; then
+ # Send the signal to the process group to kill any processes that may
+ # have been forked by the suggestion strategy
+ kill -TERM -$_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null
+ else
+ # Kill just the child process since it wasn't placed in a new process
+ # group. If the suggestion strategy forked any child processes they may
+ # be orphaned and left behind.
+ kill -TERM $_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null
+ fi
+ fi
+ fi
+
+ # Fork a process to fetch a suggestion and open a pipe to read from it
+ exec {_ZSH_AUTOSUGGEST_ASYNC_FD}< <(
+ # Tell parent process our pid
+ echo $sysparams[pid]
+
+ # Fetch and print the suggestion
+ local suggestion
+ _zsh_autosuggest_fetch_suggestion "$1"
+ echo -nE "$suggestion"
+ )
+
+ # There's a weird bug here where ^C stops working unless we force a fork
+ # See https://github.com/zsh-users/zsh-autosuggestions/issues/364
+ autoload -Uz is-at-least
+ is-at-least 5.8 || command true
+
+ # Read the pid from the child process
+ read _ZSH_AUTOSUGGEST_CHILD_PID <&$_ZSH_AUTOSUGGEST_ASYNC_FD
+
+ # When the fd is readable, call the response handler
+ zle -F "$_ZSH_AUTOSUGGEST_ASYNC_FD" _zsh_autosuggest_async_response
+}
+
+# Called when new data is ready to be read from the pipe
+# First arg will be fd ready for reading
+# Second arg will be passed in case of error
+_zsh_autosuggest_async_response() {
+ emulate -L zsh
+
+ local suggestion
+
+ if [[ -z "$2" || "$2" == "hup" ]]; then
+ # Read everything from the fd and give it as a suggestion
+ IFS='' read -rd '' -u $1 suggestion
+ zle autosuggest-suggest -- "$suggestion"
+
+ # Close the fd
+ exec {1}<&-
+ fi
+
+ # Always remove the handler
+ zle -F "$1"
+}
+
+#--------------------------------------------------------------------#
+# Start #
+#--------------------------------------------------------------------#
+
+# Start the autosuggestion widgets
+_zsh_autosuggest_start() {
+ # By default we re-bind widgets on every precmd to ensure we wrap other
+ # wrappers. Specifically, highlighting breaks if our widgets are wrapped by
+ # zsh-syntax-highlighting widgets. This also allows modifications to the
+ # widget list variables to take effect on the next precmd. However this has
+ # a decent performance hit, so users can set ZSH_AUTOSUGGEST_MANUAL_REBIND
+ # to disable the automatic re-binding.
+ if (( ${+ZSH_AUTOSUGGEST_MANUAL_REBIND} )); then
+ add-zsh-hook -d precmd _zsh_autosuggest_start
+ fi
+
+ _zsh_autosuggest_bind_widgets
+}
+
+# Mark for auto-loading the functions that we use
+autoload -Uz add-zsh-hook is-at-least
+
+# Automatically enable asynchronous mode in newer versions of zsh. Disable for
+# older versions because there is a bug when using async mode where ^C does not
+# work immediately after fetching a suggestion.
+# See https://github.com/zsh-users/zsh-autosuggestions/issues/364
+if is-at-least 5.0.8; then
+ typeset -g ZSH_AUTOSUGGEST_USE_ASYNC=
+fi
+
+# Start the autosuggestion widgets on the next precmd
+add-zsh-hook precmd _zsh_autosuggest_start
diff --git a/.config/zsh/plugins/zsh-history-substring-search.zsh b/.config/zsh/plugins/zsh-history-substring-search.zsh
new file mode 100644
index 0000000..a791cc4
--- /dev/null
+++ b/.config/zsh/plugins/zsh-history-substring-search.zsh
@@ -0,0 +1,759 @@
+#!/usr/bin/env zsh
+##############################################################################
+#
+# Copyright (c) 2009 Peter Stephenson
+# Copyright (c) 2011 Guido van Steen
+# Copyright (c) 2011 Suraj N. Kurapati
+# Copyright (c) 2011 Sorin Ionescu
+# Copyright (c) 2011 Vincent Guerci
+# Copyright (c) 2016 Geza Lore
+# Copyright (c) 2017 Bengt Brodersen
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# * Neither the name of the FIZSH nor the names of its contributors
+# may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# declare global configuration variables
+#-----------------------------------------------------------------------------
+
+typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'
+typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'
+typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'
+typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''
+typeset -g HISTORY_SUBSTRING_SEARCH_FUZZY=''
+
+#-----------------------------------------------------------------------------
+# declare internal global variables
+#-----------------------------------------------------------------------------
+
+typeset -g BUFFER MATCH MBEGIN MEND CURSOR
+typeset -g _history_substring_search_refresh_display
+typeset -g _history_substring_search_query_highlight
+typeset -g _history_substring_search_result
+typeset -g _history_substring_search_query
+typeset -g -a _history_substring_search_query_parts
+typeset -g -a _history_substring_search_raw_matches
+typeset -g -i _history_substring_search_raw_match_index
+typeset -g -a _history_substring_search_matches
+typeset -g -i _history_substring_search_match_index
+typeset -g -A _history_substring_search_unique_filter
+
+#-----------------------------------------------------------------------------
+# the main ZLE widgets
+#-----------------------------------------------------------------------------
+
+history-substring-search-up() {
+ _history-substring-search-begin
+
+ _history-substring-search-up-history ||
+ _history-substring-search-up-buffer ||
+ _history-substring-search-up-search
+
+ _history-substring-search-end
+}
+
+history-substring-search-down() {
+ _history-substring-search-begin
+
+ _history-substring-search-down-history ||
+ _history-substring-search-down-buffer ||
+ _history-substring-search-down-search
+
+ _history-substring-search-end
+}
+
+zle -N history-substring-search-up
+zle -N history-substring-search-down
+
+#-----------------------------------------------------------------------------
+# implementation details
+#-----------------------------------------------------------------------------
+
+zmodload -F zsh/parameter
+
+#
+# We have to "override" some keys and widgets if the
+# zsh-syntax-highlighting plugin has not been loaded:
+#
+# https://github.com/nicoulaj/zsh-syntax-highlighting
+#
+if [[ $+functions[_zsh_highlight] -eq 0 ]]; then
+ #
+ # Dummy implementation of _zsh_highlight() that
+ # simply removes any existing highlights when the
+ # user inserts printable characters into $BUFFER.
+ #
+ _zsh_highlight() {
+ if [[ $KEYS == [[:print:]] ]]; then
+ region_highlight=()
+ fi
+ }
+
+ #
+ # The following snippet was taken from the zsh-syntax-highlighting project:
+ #
+ # https://github.com/zsh-users/zsh-syntax-highlighting/blob/56b134f5d62ae3d4e66c7f52bd0cc2595f9b305b/zsh-syntax-highlighting.zsh#L126-161
+ #
+ # Copyright (c) 2010-2011 zsh-syntax-highlighting contributors
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification, are permitted provided that the following conditions are
+ # met:
+ #
+ # * Redistributions of source code must retain the above copyright
+ # notice, this list of conditions and the following disclaimer.
+ #
+ # * Redistributions in binary form must reproduce the above copyright
+ # notice, this list of conditions and the following disclaimer in the
+ # documentation and/or other materials provided with the distribution.
+ #
+ # * Neither the name of the zsh-syntax-highlighting contributors nor the
+ # names of its contributors may be used to endorse or promote products
+ # derived from this software without specific prior written permission.
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #
+ #--------------8<-------------------8<-------------------8<-----------------
+ # Rebind all ZLE widgets to make them invoke _zsh_highlights.
+ _zsh_highlight_bind_widgets()
+ {
+ # Load ZSH module zsh/zleparameter, needed to override user defined widgets.
+ zmodload zsh/zleparameter 2>/dev/null || {
+ echo 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' >&2
+ return 1
+ }
+
+ # Override ZLE widgets to make them invoke _zsh_highlight.
+ local cur_widget
+ for cur_widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|run-help|which-command|beep|yank*)}; do
+ case $widgets[$cur_widget] in
+
+ # Already rebound event: do nothing.
+ user:$cur_widget|user:_zsh_highlight_widget_*);;
+
+ # User defined widget: override and rebind old one with prefix "orig-".
+ user:*) eval "zle -N orig-$cur_widget ${widgets[$cur_widget]#*:}; \
+ _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \
+ zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+ # Completion widget: override and rebind old one with prefix "orig-".
+ completion:*) eval "zle -C orig-$cur_widget ${${widgets[$cur_widget]#*:}/:/ }; \
+ _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \
+ zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+ # Builtin widget: override and make it call the builtin ".widget".
+ builtin) eval "_zsh_highlight_widget_$cur_widget() { builtin zle .$cur_widget -- \"\$@\" && _zsh_highlight }; \
+ zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+ # Default: unhandled case.
+ *) echo "zsh-syntax-highlighting: unhandled ZLE widget '$cur_widget'" >&2 ;;
+ esac
+ done
+ }
+ #-------------->8------------------->8------------------->8-----------------
+
+ _zsh_highlight_bind_widgets
+fi
+
+_history-substring-search-begin() {
+ setopt localoptions extendedglob
+
+ _history_substring_search_refresh_display=
+ _history_substring_search_query_highlight=
+
+ #
+ # If the buffer is the same as the previously displayed history substring
+ # search result, then just keep stepping through the match list. Otherwise
+ # start a new search.
+ #
+ if [[ -n $BUFFER && $BUFFER == ${_history_substring_search_result:-} ]]; then
+ return;
+ fi
+
+ #
+ # Clear the previous result.
+ #
+ _history_substring_search_result=''
+
+ if [[ -z $BUFFER ]]; then
+ #
+ # If the buffer is empty, we will just act like up-history/down-history
+ # in ZSH, so we do not need to actually search the history. This should
+ # speed things up a little.
+ #
+ _history_substring_search_query=
+ _history_substring_search_query_parts=()
+ _history_substring_search_raw_matches=()
+
+ else
+ #
+ # For the purpose of highlighting we keep a copy of the original
+ # query string.
+ #
+ _history_substring_search_query=$BUFFER
+
+ #
+ # compose search pattern
+ #
+ if [[ -n $HISTORY_SUBSTRING_SEARCH_FUZZY ]]; then
+ #
+ # `=` split string in arguments
+ #
+ _history_substring_search_query_parts=(${=_history_substring_search_query})
+ else
+ _history_substring_search_query_parts=(${==_history_substring_search_query})
+ fi
+
+ #
+ # Escape and join query parts with wildcard character '*' as seperator
+ # `(j:CHAR:)` join array to string with CHAR as seperator
+ #
+ local search_pattern="*${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
+
+ #
+ # Find all occurrences of the search pattern in the history file.
+ #
+ # (k) returns the "keys" (history index numbers) instead of the values
+ # (R) returns values in reverse older, so the index of the youngest
+ # matching history entry is at the head of the list.
+ #
+ _history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]})
+ fi
+
+ #
+ # In order to stay as responsive as possible, we will process the raw
+ # matches lazily (when the user requests the next match) to choose items
+ # that need to be displayed to the user.
+ # _history_substring_search_raw_match_index holds the index of the last
+ # unprocessed entry in _history_substring_search_raw_matches. Any items
+ # that need to be displayed will be added to
+ # _history_substring_search_matches.
+ #
+ # We use an associative array (_history_substring_search_unique_filter) as
+ # a 'set' data structure to ensure uniqueness of the results if desired.
+ # If an entry (key) is in the set (non-empty value), then we have already
+ # added that entry to _history_substring_search_matches.
+ #
+ _history_substring_search_raw_match_index=0
+ _history_substring_search_matches=()
+ _history_substring_search_unique_filter=()
+
+ #
+ # If $_history_substring_search_match_index is equal to
+ # $#_history_substring_search_matches + 1, this indicates that we
+ # are beyond the end of $_history_substring_search_matches and that we
+ # have also processed all entries in
+ # _history_substring_search_raw_matches.
+ #
+ # If $#_history_substring_search_match_index is equal to 0, this indicates
+ # that we are beyond the beginning of $_history_substring_search_matches.
+ #
+ # If we have initially pressed "up" we have to initialize
+ # $_history_substring_search_match_index to 0 so that it will be
+ # incremented to 1.
+ #
+ # If we have initially pressed "down" we have to initialize
+ # $_history_substring_search_match_index to 1 so that it will be
+ # decremented to 0.
+ #
+ if [[ $WIDGET == history-substring-search-down ]]; then
+ _history_substring_search_match_index=1
+ else
+ _history_substring_search_match_index=0
+ fi
+}
+
+_history-substring-search-end() {
+ setopt localoptions extendedglob
+
+ _history_substring_search_result=$BUFFER
+
+ # the search was successful so display the result properly by clearing away
+ # existing highlights and moving the cursor to the end of the result buffer
+ if [[ $_history_substring_search_refresh_display -eq 1 ]]; then
+ region_highlight=()
+ CURSOR=${#BUFFER}
+ fi
+
+ # highlight command line using zsh-syntax-highlighting
+ _zsh_highlight
+
+ # highlight the search query inside the command line
+ if [[ -n $_history_substring_search_query_highlight ]]; then
+ # highlight first matching query parts
+ local highlight_start_index=0
+ local highlight_end_index=0
+ local query_part
+ for query_part in $_history_substring_search_query_parts; do
+ local escaped_query_part=${query_part//(#m)[\][()|\\*?#<>~^]/\\$MATCH}
+ # (i) get index of pattern
+ local query_part_match_index="${${BUFFER:$highlight_start_index}[(i)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${escaped_query_part}]}"
+ if [[ $query_part_match_index -le ${#BUFFER:$highlight_start_index} ]]; then
+ highlight_start_index=$(( $highlight_start_index + $query_part_match_index ))
+ highlight_end_index=$(( $highlight_start_index + ${#query_part} ))
+ region_highlight+=("$(($highlight_start_index - 1)) $(($highlight_end_index - 1)) $_history_substring_search_query_highlight")
+ fi
+ done
+ fi
+
+ # For debugging purposes:
+ # zle -R "mn: "$_history_substring_search_match_index" m#: "${#_history_substring_search_matches}
+ # read -k -t 200 && zle -U $REPLY
+
+ # Exit successfully from the history-substring-search-* widgets.
+ return 0
+}
+
+_history-substring-search-up-buffer() {
+ #
+ # Check if the UP arrow was pressed to move the cursor within a multi-line
+ # buffer. This amounts to three tests:
+ #
+ # 1. $#buflines -gt 1.
+ #
+ # 2. $CURSOR -ne $#BUFFER.
+ #
+ # 3. Check if we are on the first line of the current multi-line buffer.
+ # If so, pressing UP would amount to leaving the multi-line buffer.
+ #
+ # We check this by adding an extra "x" to $LBUFFER, which makes
+ # sure that xlbuflines is always equal to the number of lines
+ # until $CURSOR (including the line with the cursor on it).
+ #
+ local buflines XLBUFFER xlbuflines
+ buflines=(${(f)BUFFER})
+ XLBUFFER=$LBUFFER"x"
+ xlbuflines=(${(f)XLBUFFER})
+
+ if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xlbuflines -ne 1 ]]; then
+ zle up-line-or-history
+ return 0
+ fi
+
+ return 1
+}
+
+_history-substring-search-down-buffer() {
+ #
+ # Check if the DOWN arrow was pressed to move the cursor within a multi-line
+ # buffer. This amounts to three tests:
+ #
+ # 1. $#buflines -gt 1.
+ #
+ # 2. $CURSOR -ne $#BUFFER.
+ #
+ # 3. Check if we are on the last line of the current multi-line buffer.
+ # If so, pressing DOWN would amount to leaving the multi-line buffer.
+ #
+ # We check this by adding an extra "x" to $RBUFFER, which makes
+ # sure that xrbuflines is always equal to the number of lines
+ # from $CURSOR (including the line with the cursor on it).
+ #
+ local buflines XRBUFFER xrbuflines
+ buflines=(${(f)BUFFER})
+ XRBUFFER="x"$RBUFFER
+ xrbuflines=(${(f)XRBUFFER})
+
+ if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xrbuflines -ne 1 ]]; then
+ zle down-line-or-history
+ return 0
+ fi
+
+ return 1
+}
+
+_history-substring-search-up-history() {
+ #
+ # Behave like up in ZSH, except clear the $BUFFER
+ # when beginning of history is reached like in Fish.
+ #
+ if [[ -z $_history_substring_search_query ]]; then
+
+ # we have reached the absolute top of history
+ if [[ $HISTNO -eq 1 ]]; then
+ BUFFER=
+
+ # going up from somewhere below the top of history
+ else
+ zle up-line-or-history
+ fi
+
+ return 0
+ fi
+
+ return 1
+}
+
+_history-substring-search-down-history() {
+ #
+ # Behave like down-history in ZSH, except clear the
+ # $BUFFER when end of history is reached like in Fish.
+ #
+ if [[ -z $_history_substring_search_query ]]; then
+
+ # going down from the absolute top of history
+ if [[ $HISTNO -eq 1 && -z $BUFFER ]]; then
+ BUFFER=${history[1]}
+ _history_substring_search_refresh_display=1
+
+ # going down from somewhere above the bottom of history
+ else
+ zle down-line-or-history
+ fi
+
+ return 0
+ fi
+
+ return 1
+}
+
+_history_substring_search_process_raw_matches() {
+ #
+ # Process more outstanding raw matches and append any matches that need to
+ # be displayed to the user to _history_substring_search_matches.
+ # Return whether there were any more results appended.
+ #
+
+ #
+ # While we have more raw matches. Process them to see if there are any more
+ # matches that need to be displayed to the user.
+ #
+ while [[ $_history_substring_search_raw_match_index -lt $#_history_substring_search_raw_matches ]]; do
+ #
+ # Move on to the next raw entry and get its history index.
+ #
+ _history_substring_search_raw_match_index+=1
+ local index=${_history_substring_search_raw_matches[$_history_substring_search_raw_match_index]}
+
+ #
+ # If HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set to a non-empty value,
+ # then ensure that only unique matches are presented to the user.
+ # When HIST_IGNORE_ALL_DUPS is set, ZSH already ensures a unique history,
+ # so in this case we do not need to do anything.
+ #
+ if [[ ! -o HIST_IGNORE_ALL_DUPS && -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+ #
+ # Get the actual history entry at the new index, and check if we have
+ # already added it to _history_substring_search_matches.
+ #
+ local entry=${history[$index]}
+
+ if [[ -z ${_history_substring_search_unique_filter[$entry]} ]]; then
+ #
+ # This is a new unique entry. Add it to the filter and append the
+ # index to _history_substring_search_matches.
+ #
+ _history_substring_search_unique_filter[$entry]=1
+ _history_substring_search_matches+=($index)
+
+ #
+ # Indicate that we did find a match.
+ #
+ return 0
+ fi
+
+ else
+ #
+ # Just append the new history index to the processed matches.
+ #
+ _history_substring_search_matches+=($index)
+
+ #
+ # Indicate that we did find a match.
+ #
+ return 0
+ fi
+
+ done
+
+ #
+ # We are beyond the end of the list of raw matches. Indicate that no
+ # more matches are available.
+ #
+ return 1
+}
+
+_history-substring-search-has-next() {
+ #
+ # Predicate function that returns whether any more older matches are
+ # available.
+ #
+
+ if [[ $_history_substring_search_match_index -lt $#_history_substring_search_matches ]]; then
+ #
+ # We did not reach the end of the processed list, so we do have further
+ # matches.
+ #
+ return 0
+
+ else
+ #
+ # We are at the end of the processed list. Try to process further
+ # unprocessed matches. _history_substring_search_process_raw_matches
+ # returns whether any more matches were available, so just return
+ # that result.
+ #
+ _history_substring_search_process_raw_matches
+ return $?
+ fi
+}
+
+_history-substring-search-has-prev() {
+ #
+ # Predicate function that returns whether any more younger matches are
+ # available.
+ #
+
+ if [[ $_history_substring_search_match_index -gt 1 ]]; then
+ #
+ # We did not reach the beginning of the processed list, so we do have
+ # further matches.
+ #
+ return 0
+
+ else
+ #
+ # We are at the beginning of the processed list. We do not have any more
+ # matches.
+ #
+ return 1
+ fi
+}
+
+_history-substring-search-found() {
+ #
+ # A match is available. The index of the match is held in
+ # $_history_substring_search_match_index
+ #
+ # 1. Make $BUFFER equal to the matching history entry.
+ #
+ # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
+ # to highlight the current buffer.
+ #
+ BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]]
+ _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
+}
+
+_history-substring-search-not-found() {
+ #
+ # No more matches are available.
+ #
+ # 1. Make $BUFFER equal to $_history_substring_search_query so the user can
+ # revise it and search again.
+ #
+ # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND
+ # to highlight the current buffer.
+ #
+ BUFFER=$_history_substring_search_query
+ _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND
+}
+
+_history-substring-search-up-search() {
+ _history_substring_search_refresh_display=1
+
+ #
+ # Select history entry during history-substring-down-search:
+ #
+ # The following variables have been initialized in
+ # _history-substring-search-up/down-search():
+ #
+ # $_history_substring_search_matches is the current list of matches that
+ # need to be displayed to the user.
+ # $_history_substring_search_match_index is the index of the current match
+ # that is being displayed to the user.
+ #
+ # The range of values that $_history_substring_search_match_index can take
+ # is: [0, $#_history_substring_search_matches + 1]. A value of 0
+ # indicates that we are beyond the beginning of
+ # $_history_substring_search_matches. A value of
+ # $#_history_substring_search_matches + 1 indicates that we are beyond
+ # the end of $_history_substring_search_matches and that we have also
+ # processed all entries in _history_substring_search_raw_matches.
+ #
+ # If $_history_substring_search_match_index equals
+ # $#_history_substring_search_matches and
+ # $_history_substring_search_raw_match_index is not greater than
+ # $#_history_substring_search_raw_matches, then we need to further process
+ # $_history_substring_search_raw_matches to see if there are any more
+ # entries that need to be displayed to the user.
+ #
+ # In _history-substring-search-up-search() the initial value of
+ # $_history_substring_search_match_index is 0. This value is set in
+ # _history-substring-search-begin(). _history-substring-search-up-search()
+ # will initially increment it to 1.
+ #
+
+ if [[ $_history_substring_search_match_index -gt $#_history_substring_search_matches ]]; then
+ #
+ # We are beyond the end of $_history_substring_search_matches. This
+ # can only happen if we have also exhausted the unprocessed matches in
+ # _history_substring_search_raw_matches.
+ #
+ # 1. Update display to indicate search not found.
+ #
+ _history-substring-search-not-found
+ return
+ fi
+
+ if _history-substring-search-has-next; then
+ #
+ # We do have older matches.
+ #
+ # 1. Move index to point to the next match.
+ # 2. Update display to indicate search found.
+ #
+ _history_substring_search_match_index+=1
+ _history-substring-search-found
+
+ else
+ #
+ # We do not have older matches.
+ #
+ # 1. Move the index beyond the end of
+ # _history_substring_search_matches.
+ # 2. Update display to indicate search not found.
+ #
+ _history_substring_search_match_index+=1
+ _history-substring-search-not-found
+ fi
+
+ #
+ # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from
+ # history should be matched, make sure the new and old results are different.
+ #
+ # However, if the HIST_IGNORE_ALL_DUPS shell option, or
+ # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a
+ # unique history, so in this case we do not need to do anything.
+ #
+ if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+ return
+ fi
+
+ if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then
+ #
+ # Repeat the current search so that a different (unique) match is found.
+ #
+ _history-substring-search-up-search
+ fi
+}
+
+_history-substring-search-down-search() {
+ _history_substring_search_refresh_display=1
+
+ #
+ # Select history entry during history-substring-down-search:
+ #
+ # The following variables have been initialized in
+ # _history-substring-search-up/down-search():
+ #
+ # $_history_substring_search_matches is the current list of matches that
+ # need to be displayed to the user.
+ # $_history_substring_search_match_index is the index of the current match
+ # that is being displayed to the user.
+ #
+ # The range of values that $_history_substring_search_match_index can take
+ # is: [0, $#_history_substring_search_matches + 1]. A value of 0
+ # indicates that we are beyond the beginning of
+ # $_history_substring_search_matches. A value of
+ # $#_history_substring_search_matches + 1 indicates that we are beyond
+ # the end of $_history_substring_search_matches and that we have also
+ # processed all entries in _history_substring_search_raw_matches.
+ #
+ # In _history-substring-search-down-search() the initial value of
+ # $_history_substring_search_match_index is 1. This value is set in
+ # _history-substring-search-begin(). _history-substring-search-down-search()
+ # will initially decrement it to 0.
+ #
+
+ if [[ $_history_substring_search_match_index -lt 1 ]]; then
+ #
+ # We are beyond the beginning of $_history_substring_search_matches.
+ #
+ # 1. Update display to indicate search not found.
+ #
+ _history-substring-search-not-found
+ return
+ fi
+
+ if _history-substring-search-has-prev; then
+ #
+ # We do have younger matches.
+ #
+ # 1. Move index to point to the previous match.
+ # 2. Update display to indicate search found.
+ #
+ _history_substring_search_match_index+=-1
+ _history-substring-search-found
+
+ else
+ #
+ # We do not have younger matches.
+ #
+ # 1. Move the index beyond the beginning of
+ # _history_substring_search_matches.
+ # 2. Update display to indicate search not found.
+ #
+ _history_substring_search_match_index+=-1
+ _history-substring-search-not-found
+ fi
+
+ #
+ # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from
+ # history should be matched, make sure the new and old results are different.
+ #
+ # However, if the HIST_IGNORE_ALL_DUPS shell option, or
+ # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a
+ # unique history, so in this case we do not need to do anything.
+ #
+ if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+ return
+ fi
+
+ if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then
+ #
+ # Repeat the current search so that a different (unique) match is found.
+ #
+ _history-substring-search-down-search
+ fi
+}
+
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/.config/zsh/plugins/zsh-syntax-highlighting b/.config/zsh/plugins/zsh-syntax-highlighting
new file mode 160000
+Subproject e0165eaa730dd0fa321a6a6de74f092fe87630b
diff --git a/.config/zsh/zprofile b/.config/zsh/zprofile
new file mode 100644
index 0000000..46c5217
--- /dev/null
+++ b/.config/zsh/zprofile
@@ -0,0 +1,21 @@
+#!/bin/zsh
+. ~/.profile
+
+[ -n "$TMUX" ] || [ -n "$TERMUX_VERSION" ] || [ "$SSH_CONNECTION" ] &&
+ return
+
+on_ac_power="$(cat /sys/class/power_supply/ACAD/online)"
+[ "$on_ac_power" = 0 ] && brightnessctl set 5% || brightnessctl set 20%
+
+case "$TTY" in
+ /dev/tty1)
+ [ "$on_ac_power" = 1 ] && {
+ echo "Waiting for nvidia card to load up..."
+ until [ -e /dev/dri/card0 ]; do; sleep 0.1; done
+ }
+ command -V startx >/dev/null && { pgrep startx || startx }
+ ;;
+ /dev/tty3) tmux new -s master ;;
+ /dev/tty[2-5]) tmux new -s "${TTY#/dev/}" ;;
+ # /dev/pts/*) exec tmux new -s "${TTY#/dev/}" ;;
+esac