Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #=====================================
- #
- # OpenBSD Install
- #
- #=====================================
- ### Installation ###
- ## pick shell:
- s
- ## wipe drive and clear the dead space:
- dd if=/dev/urandom of=/dev/rsd0c bs=1m
- ## encrypt the drive
- # create efi partition system:
- fdisk -iy -g -b 960 sd0
- # make one parition for the whole disk:
- disklabel -E sd0
- Label editor (enter '?' for help at any prompt)
- > a a
- offset: defaults
- size: defaults
- FS type: RAID
- > w
- > q
- No label changes.
- # encrypt drive:
- bioctl -c C -l sd0a softraid0
- # make device node and clear out first megabyte:
- cd /dev && sh MAKEDEV sd2
- dd if=/dev/zero of=/dev/rsd2c bs=1m count=1
- ## installer
- # start installer
- exit and choose installer:
- exit
- i
- # pick keyboard:
- US QWERTY
- # hostname:
- host
- # wireless:
- skip:
- done
- # DNS domain name:
- default
- # password for root:
- *type password*
- # start sshd:
- no
- # start the x window system by xenodm:
- yes
- # user setup:
- # setup a user: user
- # full name: User
- # password for user: *enter password*
- # which disk is the root disk:
- sd2
- # use whole disk with MBR or GPT:
- gtp
- # use auto layout
- a
- # location of sets:
- disk
- # Is the disk partition already mounted?:
- no
- # Which disk contains the install media? (or 'done'):
- sd1
- # Available sd1 partitions are:
- a
- # Which sd1 partition has the install sets? (or 'done')
- [a]
- # Pathname to the sets? (or 'done'):
- [6.4/amd64]
- # what timezone:
- UTC
- # reboot
- ### Post Installation ###
- ## login as root:
- username: root
- password: *enter root password*
- ## disable bell
- # ttys
- wsconsctl keyboard.bell.volume=0
- edit /etc/wsconsctl.conf:
- # disable bell
- keyboard.bell.volume=0
- # xorg
- echo 'xset b off' >> /etc/X11/xenodm/Xsetup_0
- ## network
- # setup with ethernet
- # find ethernet interface:
- ifconfig
- # setup ethernet:
- dhclient em0
- # get and install wifi firmware:
- fw_update
- # setup wifi card and find wifi:
- ifconfig iwn0 up
- ifconfig iwn0 scan
- # connect to wifi
- ifconfig iwn0 nwid YOUR_SSID wpakey "YOUR_PASSPHRASE"
- dhclient iwn0
- # create /etc/hostname.iwn0 with the following:
- vi /etc/hostname.iwn0:
- # add networks in order of priority, for example:
- # join "HOME_SSID" wpakey "HOME_PASSPHRASE"
- # join "WORK_SSID" wpakey "WORK_PASSPHRASE"
- # join "OPEN_COFFEE_SHOP"
- # home:
- join "SSID" wpakey "PASSPHRASE"
- dhcp
- inet6 autoconf
- up powersave
- # test changes:
- ifconfig em0 down
- ifconfig iwn0 down
- pkill dhclient
- sh /etc/netstart
- # if that doesn't work reboot
- # set usb mount directory and test usb mounting
- mkdir /mnt/usb
- chown user:user /mnt/usb
- mount -t msdos /dev/sd2i /mnt/usb
- # disable xconsole window from autostarting at each login:
- sed -i 's/xconsole/#xconsole/' /etc/X11/xenodm/Xsetup_0
- # remap keys
- ## map caps lock to esacpe key in tty:
- # tty
- vi /etc/wsconsctl.conf:
- keyboard.map+="keysym Caps_Lock = Escape"
- # set UTF-8 for tty:
- export LANG=en_US.UTF-8
- export LC_ALL=en_US.UTF-8
- # and add it to /etc/login.conf
- :charset=UTF-8:\
- :LANG=en_US.UTF-8:\
- :LC_ALL=en_US.UTF-8:
- # setup doas for user:
- echo 'permit persist keepenv user' > /etc/doas.conf
- # enable power managemnt options:
- rcctl enable apmd
- rcctl set apmd flags -A
- rcctl start apmd
- # add user to groups:
- usermod -G staff user
- usermod -G operator
- usermod -G games
- # change resource limits:
- vi /etc/login.conf:
- staff:\
- :datasize-cur=1024M:\
- :datasize-max=8192M:\
- :maxproc-cur=512:\
- :maxproc-max=1024:\
- :openfiles-cur=4096:\
- :openfiles-max=8192:\
- :stacksize-cur=32M:\
- :ignorenologin:\
- :requirehome@:\
- :tc=default:
- # bump up kernal sysctls:
- vi /etc/sysctl.conf:
- # shared memory limits
- kern.shminfo.shmall=3145728
- kern.shminfo.shmmax=2147483647
- kern.shminfo.shmmni=1024
- # semaphores
- kern.shminfo.shmseg=1024
- kern.seminfo.semmns=4096
- kern.seminfo.semmni=1024
- kern.maxproc=32768
- kern.maxfiles=65535
- kern.bufcachepercent=90
- kern.maxvnodes=262144
- kern.somaxconn=2048
- # lock screen automaticaly when you close the lid:
- # make the directory for apm:
- mkdir /etc/apm
- # Then, create the file /etc/apm/suspend with the following contents:
- #!/bin/sh
- pkill -USR1 xidle
- # And make it executable:
- chmod +x /etc/apm/suspend
- # turn off ntpd google check:
- sed -i '/google/d' /etc/ntpd.conf
- # restart ntpd:
- rcctl restart ntpd
- # change hostname:
- vi /etc/myname:
- host
- # exit and login as user
- # uninstall fvwm
- ## install ports tree
- # fetch the ports tree:
- cd /tmp
- ftp https://cdn.openbsd.org/pub/OpenBSD/$(uname -r)/{ports.tar.gz,SHA256.sig}
- signify -Cp /etc/signify/openbsd-$(uname -r | cut -c 1,3)-base.pub -x SHA256.sig ports.tar.gz
- # untar the ports tree in /usr/ports:
- cd /usr
- tar xzf /tmp/ports.tar.gz
- # configure ports:
- # vi /etc/mk.conf:
- WRKOBJDIR=/usr/obj/ports
- DISTDIR=/usr/distfiles
- PACKAGE_REPOSITORY=/usr/packages
- ## install programs
- # shell:
- ## zsh:
- doas pkg_add zsh
- # editor:
- ## neovim:
- doas pkg_add neovim
- # music and video:
- ## mpd:
- doas pkg_add mpd
- ## mpc:
- doas pkg_add mpc
- ## ncmpcpp:
- doas pkg_add ncmpcpp
- ## ncmpc:
- doas pkg_add ncmpc
- ## mpv:
- doas pkg_add mpv
- # network:
- ## tor:
- doas pkg_add tor
- # web browsing
- ## tor-browser:
- doas pkg_add tor-browser
- ## firefox:
- doas pkg_add firefox
- ## qutebrowser:
- doas pkg_add qutebrowser
- ## w3m:
- doas pkg_add w3m
- choice: (2)
- # file management:
- ## thunar:
- doas pkg_add thunar
- ## ranger:
- doas pkg_add ranger
- # utilities:
- ## feh:
- doas pkg_add feh
- ## dunst:
- doas pkg_add dunst
- ## tree:
- doas pkg_add tree
- ## scrot:
- doas pkg_add scrot
- ## neofetch:
- doas pkg_add neofetch
- ## htop:
- doas pkg_add htop
- ## wget:
- doas pkg_add wget
- ## git:
- doas pkg_add git
- ## gimp:
- doas pkg_add gimp
- ## transmission:
- doas pkg_add transmission
- ## unzip:
- doas pkg_add unzip
- choice (1)
- ## zathura:
- doas pkg_add zathura
- ## qemu:
- doas pkg_add qemu
- ## imagemagick:
- doas pkg_add ImageMagick
- # social media:
- ## pidgin:
- doas pkg_add pidgin
- choice (1)
- ## pidgin-otr:
- doas pkg_add pidgin-otr
- ## pidgin-libnotify:
- doas pkg_add pidgin-libnotify
- ## irssi:
- doas pkg_add irssi
- choice (2)
- ## irssi-otr:
- doas pkg_add irssi-otr
- ## neomutt:
- doas pkg_add neomutt
- choice (1)
- # programming
- ## ipython:
- doas pkg_add ipython
- ## py-virtualenv:
- doas pkg_add py-virtualenv
- ## py3-virtualenv:
- doas pkg_add py3-virtualenv
- ## py-pip:
- doas pkg_add py-pip
- ## py3-pip:
- doas pkg_add py3-pip
- # games
- ## wesnoth:
- doas pkg_add wesnoth
- ## 0ad:
- doas pkg_add 0ad
- ## minetest:
- doas pkg_add mintest
- ## nethack:
- doas pkg_add nethack
- choice (2)
- ## supertux:
- doas pkg_add supertux
- ## supertuxkart:
- doas pkg_add supertuxkart
- # terminal
- ## urxvt-unicode:
- doas pkg_add urxvt-unicode
- # fonts
- ## noto-fonts:
- doas pkg_add noto-fonts
- ## liberation-fonts:
- doas pkg_add liberation-fonts
- ## zh-fonts-arphicttf:
- doas pkg_add zh-fonts-arphicttf
- ## terminus-font:
- doas pkg_add terminus-font
- choice (1: terminus-font)
- ## p5-Locale-Hebrew:
- doas pkg_add p5-Locale-Hebrew
- ## migmix:
- doas pkg_add migmix
- ## migu:
- doas pkg_add migu
- ## ja-sazanami-ttf:
- doas pkg_add ja-sazanami-ttf
- ## vlgothic:
- doas pkg_add vlgothic
- ## hanazono:
- doas pkg_add hanazono
- ## anonymous-pro:
- doas pkg_add anonymous-pro
- ## artwiz-aleczapka:
- doas pkg_add artwiz-aleczapka
- ## inconsolata-font:
- doas pkg_add inconsolata-font
- ## cantarell-fonts:
- doas pkg_add cantarell-fonts
- ## doulos:
- doas pkg_add doulos
- ## ubuntu-fonts:
- doas pkg_add ubuntu-fonts
- ## junicode:
- doas pkg_add junicode
- ## charis:
- doas pkg_add charis
- ## gentium:
- doas pkg_add gentium
- ## powerline-fonts:
- doas pkg_add powerline-fonts
- # make a build directory:
- mkdir .builds
- # window manageer
- ## dwm
- cd .builds
- git clone git://git.suckless.org/dwm
- cd dwm
- # uncomment openbsd libs in config.mk:
- # OpenBSD (uncomment)
- FREETYPEINC = ${X11INC}/freetype2
- # build dwm:
- doas make clean install
- # application menu
- ## demenu
- cd .builds
- git clone git://git.suckless.org/dmenu
- cd dmenu
- # uncomment openbsd libs in config.mk:
- FREETYPEINC = ${X11INC}/freetype2
- # build dmenu:
- doas make clean install
- # make subdirecories and change shell:
- mkdir Documents Downloads Music Videos Pictures
- mkdir Pictures/.screenshots
- mkdir ~/.config
- doas mkdir /usr/local/share/backgrounds
- # change shell for user:
- chsh -s /usr/local/bin/zsh
- # move files to the right places:
- doas mv Fonts /usr/local/share/fonts
- doas mv wallpapers /usr/local/share/backgrounds
- ### Configurations ###
- ============================================================================================================================
- ## .xsession:
- vi ~/.xsessions
- #####################
- #
- # .xsession
- #
- #####################
- # use UTF-8 everywhere
- export LANG=en_US.UTF-8
- # specify location of .zshrc
- export ENV=$HOME/.zshrc
- # load .Xresources
- xrdb -merge $HOME/.Xresources
- # set background color
- xsetroot -solid back
- # enable scrolling with trackpoint and middle button
- xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation" 1
- xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Button" 2
- xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Axes" 6 7 4 5
- # remap caps lock to esacpe
- setxkbmap -option caps:escape
- # start dwm
- exec dwm
- ============================================================================================================================
- ## .Xresources:
- vi ~/.Xresources
- !!!!!!!!!!!!!!!!!!!!!!!!!!
- !
- ! .Xresources
- !
- !!!!!!!!!!!!!!!!!!!!!!!!!!
- ! to load .Xresources run:
- ! xrdb ~/.Xresources
- ! ===== fonts
- !to find which font is used as the fall back font for a specific character run:
- ! FC_DEBUG=4 pango-view -q -t '{character}' 2>&1 |\grep -o 'family: "[^"]\+' | cut -c 10- | tail -n 1
- !to find the name of a font:
- ! fc-list -v | grep *name*
- Xft.autohint : 0
- Xft.lcdfilter : lcddefault
- Xft.hintstyle : hintslight
- Xft.hinting : 1
- Xft.antialias : 1
- Xft.rgba : rgb
- *font : Terminus (TTF):size=9
- ! ===== urxvt:
- ! fonts
- URxvt.font: xft:Terminus (TTF):size=9, xft:Noto Sans Devanagari:9, xft:Noto Emoji, xft:DejaVu Serif, xft:Noto Sans Kannada
- ! scrollbar
- URxvt.scrollBar: false
- ! scrollback
- URxvt*.saveLines: 10000
- ! transparency
- URxvt.depth: 32
- URxvt.background: [95]#000000
- ! fading
- URxvt*fading: 30
- ! cursor
- URxvt*cursorUnderline: true
- URxvt*cursorBlink: true
- URxvt*cursorColor: #FF0099
- !! theme
- !background color
- URxvt*background: #000000
- ! font color
- URxvt*foreground: #67C8FF
- ! other colors
- URxvt*color0: #000000
- URxvt*color1: #FF0000
- URxvt*color2: #67C8FF
- URxvt*color3: #FF1493
- URxvt*color4: #099FFF
- URxvt*color5: #CC00FF
- URxvt*color6: #099FFF
- URxvt*color7: #820571
- URxvt*color8: #45013C
- URxvt*color9: #099FFF
- URxvt*color10: #FF0099
- URxvt*color11: #E6FB04
- URxvt*color12: #9400D3
- URxvt*color13: #DB329D
- URxvt*color14: #9400D3
- URxvt*color15: #FF0099
- URxvt*underlineColor: #FF34B3
- URxvt*highlightColor: #191970
- URxvt*highlightTextColor: #EE00EE
- !! extensions
- !fullscreen
- URxvt.perl-ext-common: fullscreen
- URxvt.keysym.F11: perl:fullscreen:switch
- ! ===== xterm
- !! theme
- XTerm*background : #000000
- XTerm*foreground : #67C8FF
- XTerm*cursorColor : #FF0099
- XTerm*colorUL : #366060
- XTerm*underlineColor : #FF34B3
- XTerm*color0 : #000000
- XTerm*color1 : #FF0000
- XTerm*color2 : #67C8FF
- XTerm*color3 : #FF1493
- XTerm*color4 : #099FFF
- XTerm*color5 : #CC00FF
- XTerm*color6 : #099FFF
- XTerm*color7 : #820571
- XTerm*color8 : #45013C
- XTerm*color9 : #099FFF
- XTerm*color10 : #FF0099
- XTerm*color11 : #E6FB04
- XTerm*color12 : #9400D3
- XTerm*color13 : #DB329D
- XTerm*color14 : #9400D3
- XTerm*color15 : #FF0099
- ! remove the additional black border
- XTerm*borderWidth : 0
- XTerm*internalBorder : 2
- ! set TERM env variable to use 256 colors
- XTerm*termName : xterm-256color
- ! make alt key work normally
- XTerm*vt100.metaSendsEscape : true
- ! save ~10,000 lines of scrollback
- XTerm*v100.saveLines : 10240
- ! hide scrollbar
- XTerm*vt100.scrollBar : false
- ! some black magic to change what characters XTerm considers "word delimiters"
- XTerm*charClass : 33:48,36-47:48,58-59:48,61:48,63-64:48,95:48,126:48
- ============================================================================================================================
- ## GTK3 settings
- # make the file:
- mkdir -p ~/.config/gtk-3.0
- # vi ~/.config/gtk-3.0/settings.ini:
- [Settings]
- gtk-theme-name=Adwaita
- gtk-icon-theme-name=Adwaita
- gtk-font-name=Arimo 9
- gtk-toolbar-style=GTK_TOOLBAR_ICONS
- gtk-toolbar-icon-size=GTK_ICON_SIZE_SMALL_TOOLBAR
- gtk-button-images=1
- gtk-menu-images=1
- gtk-enable-event-sounds=1
- gtk-enable-input-feedback-sounds=0
- gtk-xft-antialias=1
- gtk-xft-hinting=1
- gtk-xft-hintstyle=hintslight
- gtk-xft-rgba=rgb
- gtk-cursor-theme-size=0
- gtk-cursor-theme-name=Default
- gtk-key-theme-name=Default
- ============================================================================================================================
- ## dwm (config.def.h)
- ## to rebuild for changes to take affect do the following:
- # copy config.def.h to config.h:
- doas cp confg.def.h config.h
- # rebuild and install:
- doas make clean install
- /* See LICENSE file for copyright and license details. */
- /* appearance */
- static const unsigned int borderpx = 1; /* border pixel of windows */
- static const unsigned int snap = 32; /* snap pixel */
- static const int showbar = 1; /* 0 means no bar */
- static const int topbar = 1; /* 0 means bottom bar */
- static const char *fonts[] = { "Terminus (TTF):size=9" };
- static const char dmenufont[] = "Sparkles:size=9";
- static const char col_black1[] = "#000000";
- static const char col_gray2[] = "#444444";
- static const char col_gray3[] = "#bbbbbb";
- static const char col_gray4[] = "#eeeeee";
- static const char col_cyan[] = "#67C8FF";
- static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_black1, col_gray2 },
- [SchemeSel] = { col_gray4, col_black1, col_cyan },
- };
- /* tagging */
- static const char *tags[] = { "零", "一", "二", "三", "四", "五", " 六", "七", "八" };
- static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { "Gimp", NULL, NULL, 0, 1, -1 },
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
- };
- /* layout(s) */
- static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
- static const int nmaster = 1; /* number of clients in master area */
- static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
- static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
- };
- /* key definitions */
- #define MODKEY Mod4Mask
- #define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
- /* helper for spawning shell commands in the pre dwm-5.0 fashion */
- #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
- /* commands */
- static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
- static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_black1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
- static const char *termcmd[] = { "urxvt", NULL };
- static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_d, spawn, {.v = dmenucmd } },
- { MODKEY, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_h, incnmaster, {.i = +1 } },
- { MODKEY, XK_v, incnmaster, {.i = -1 } },
- { MODKEY, XK_i, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY|ShiftMask, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_p, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
- };
- /* button definitions */
- /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
- static Button buttons[] = {
- /* click event mask button function argument */
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
- };
- ============================================================================================================================
- ## Zsh
- ##################################
- #
- # ZSH Config
- #
- ##################################
- ### Global Settings ###
- ## completions
- zstyle :compinstall filename '/home/user/.zshrc'
- autoload -Uz compinit
- compinit
- ## enable highlighting
- zstyle ':completion:*' menu select=1
- ## corrections settings
- zstyle ':completion:*' completer _complete _approximate
- ## automatically change directory if a directory is entered
- setopt autocd
- setopt extendedglob
- ## case-insensitive globbing
- zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
- ## history settings
- HISTFILE=~/.zsh_history
- HISTSIZE=20000
- SAVEHIST=$HISTSIZE
- ######################################################################################################################
- ### Keybindings ###
- if [[ ${terminfo[smkx]} && ${terminfo[rmkx]} ]]
- then
- function zle-line-init {
- echoti smkx
- }
- function zle-line-finish {
- echoti rmkx
- }
- zle -N zle-line-init
- zle -N zle-line-finish
- fi
- # Create a hashmap from key names to their codes.
- typeset -gA key
- key[Home]=${terminfo[khome]}
- key[End]=${terminfo[kend]}
- key[Insert]=${terminfo[kich1]}
- key[Delete]=${terminfo[kdch1]}
- key[Up]=${terminfo[kcuu1]}
- key[Down]=${terminfo[kcud1]}
- key[Left]=${terminfo[kcub1]}
- key[Right]=${terminfo[kcuf1]}
- key[Shift-Home]=${terminfo[kHOM]}
- key[Shift-End]=${terminfo[kEND]}
- key[Shift-Insert]=${terminfo[kIC]}
- key[Shift-Delete]=${terminfo[kDC]}
- key[Shift-Up]=${terminfo[kUP]}
- key[Shift-Down]=${terminfo[kDN]}
- key[Shift-Left]=${terminfo[kLFT]}
- key[Shift-Right]=${terminfo[kRIT]}
- key[Alt-Home]=${terminfo[kHOM3]}
- key[Alt-End]=${terminfo[kEND3]}
- key[Alt-Insert]=${terminfo[kIC3]}
- key[Alt-Delete]=${terminfo[kDC3]}
- key[Alt-Up]=${terminfo[kUP3]}
- key[Alt-Down]=${terminfo[kDN3]}
- key[Alt-Left]=${terminfo[kLFT3]}
- key[Alt-Right]=${terminfo[kRIT3]}
- key[Shift-Alt-Home]=${terminfo[kHOM4]}
- key[Shift-Alt-End]=${terminfo[kEND4]}
- key[Shift-Alt-Insert]=${terminfo[kIC4]}
- key[Shift-Alt-Delete]=${terminfo[kDC4]}
- key[Shift-Alt-Up]=${terminfo[kUP4]}
- key[Shift-Alt-Down]=${terminfo[kDN4]}
- key[Shift-Alt-Left]=${terminfo[kLFT4]}
- key[Shift-Alt-Right]=${terminfo[kRIT4]}
- key[Ctrl-Home]=${terminfo[kHOM5]}
- key[Ctrl-End]=${terminfo[kEND5]}
- key[Ctrl-Insert]=${terminfo[kIC5]}
- key[Ctrl-Delete]=${terminfo[kDC5]}
- key[Ctrl-Up]=${terminfo[kUP5]}
- key[Ctrl-Down]=${terminfo[kDN5]}
- key[Ctrl-Left]=${terminfo[kLFT5]}
- key[Ctrl-Right]=${terminfo[kRIT5]}
- key[Shift-Ctrl-Home]=${terminfo[kHOM6]}
- key[Shift-Ctrl-End]=${terminfo[kEND6]}
- key[Shift-Ctrl-Insert]=${terminfo[kIC6]}
- key[Shift-Ctrl-Delete]=${terminfo[kDC6]}
- key[Shift-Ctrl-Up]=${terminfo[kUP6]}
- key[Shift-Ctrl-Down]=${terminfo[kDN6]}
- key[Shift-Ctrl-Left]=${terminfo[kLFT6]}
- key[Shift-Ctrl-Right]=${terminfo[kRIT6]}
- key[Alt-Ctrl-Home]=${terminfo[kHOM7]}
- key[Alt-Ctrl-End]=${terminfo[kEND7]}
- key[Alt-Ctrl-Insert]=${terminfo[kIC7]}
- key[Alt-Ctrl-Delete]=${terminfo[kDC7]}
- key[Alt-Ctrl-Up]=${terminfo[kUP7]}
- key[Alt-Ctrl-Down]=${terminfo[kDN7]}
- key[Alt-Ctrl-Left]=${terminfo[kLFT7]}
- key[Alt-Ctrl-Right]=${terminfo[kRIT7]}
- key[Shift-Alt-Ctrl-Home]='' # TODO
- key[Shift-Alt-Ctrl-End]='' # TODO
- key[Shift-Alt-Ctrl-Insert]='' # TODO
- key[Shift-Alt-Ctrl-Delete]='' # TODO
- key[Shift-Alt-Ctrl-Up]='' # TODO
- key[Shift-Alt-Ctrl-Down]='' # TODO
- key[Shift-Alt-Ctrl-Left]='' # TODO
- key[Shift-Alt-Ctrl-Right]='' # TODO
- # Other keys:
- # The traditional effect of the Alt-Key is to send Esc then Key.
- key[Backspace]='^?'
- key[Alt-Backspace]='\e^?'
- key[Prior]=${terminfo[kpp]}
- key[Next]=${terminfo[knp]}
- key[Tab]='\t'
- key[Shift-Tab]=${terminfo[kcbt]}
- # Key bindings:
- # Now that our keycodes are defined, we actually bind them to ZLE widgets.
- bindkey -v # Default to emacs key bindings for many widgets.
- [[ ${key[Home]} ]] && bindkey ${key[Home]} beginning-of-line
- [[ ${key[End]} ]] && bindkey ${key[End]} end-of-line
- [[ ${key[Insert]} ]] && bindkey ${key[Insert]} overwrite-mode
- [[ ${key[Delete]} ]] && bindkey ${key[Delete]} delete-char
- [[ ${key[Up]} ]] && bindkey ${key[Up]} up-line-or-search
- [[ ${key[Down]} ]] && bindkey ${key[Down]} down-line-or-search
- [[ ${key[Left]} ]] && bindkey ${key[Left]} backward-char
- [[ ${key[Right]} ]] && bindkey ${key[Right]} forward-char
- [[ ${key[Ctrl-Left]} ]] && bindkey ${key[Ctrl-Left]} backward-word
- [[ ${key[Ctrl-Right]} ]] && bindkey ${key[Ctrl-Right]} forward-word
- [[ ${key[Alt-Left]} ]] && bindkey ${key[Alt-Left]} backward-word
- [[ ${key[Alt-Right]} ]] && bindkey ${key[Alt-Right]} forward-word
- [[ ${key[Tab]} ]] && bindkey ${key[Tab]} menu-expand-or-complete
- [[ ${key[Shift-Tab]} ]] && bindkey ${key[Shift-Tab]} reverse-menu-complete
- ######################################################################################################################
- ### Functions ###
- ## Git Prompt ##
- function git_prompt_info() {
- local ref
- if [[ "$(command git config --get oh-my-zsh.hide-status 2>/dev/null)" != "1" ]]; then
- ref=$(command git symbolic-ref HEAD 2> /dev/null) || \
- ref=$(command git rev-parse --short HEAD 2> /dev/null) || return 0
- echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX"
- fi
- }
- # Checks if working tree is dirty
- function parse_git_dirty() {
- local STATUS=''
- local -a FLAGS
- FLAGS=('--porcelain')
- if [[ "$(command git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
- if [[ $POST_1_7_2_GIT -gt 0 ]]; then
- FLAGS+='--ignore-submodules=dirty'
- fi
- if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then
- FLAGS+='--untracked-files=no'
- fi
- STATUS=$(command git status ${FLAGS} 2> /dev/null | tail -n1)
- fi
- if [[ -n $STATUS ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
- else
- echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
- fi
- }
- # Gets the difference between the local and remote branches
- function git_remote_status() {
- local remote ahead behind git_remote_status git_remote_status_detailed
- remote=${$(command git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/}
- if [[ -n ${remote} ]]; then
- ahead=$(command git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
- behind=$(command git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
- if [[ $ahead -eq 0 ]] && [[ $behind -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE"
- elif [[ $ahead -gt 0 ]] && [[ $behind -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}"
- elif [[ $behind -gt 0 ]] && [[ $ahead -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
- elif [[ $ahead -gt 0 ]] && [[ $behind -gt 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
- fi
- if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX$remote$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
- fi
- echo $git_remote_status
- fi
- }
- # Outputs the name of the current branch
- # Usage example: git pull origin $(git_current_branch)
- # Using '--quiet' with 'symbolic-ref' will not cause a fatal error (128) if
- # it's not a symbolic ref, but in a Git repo.
- function git_current_branch() {
- local ref
- ref=$(command git symbolic-ref --quiet HEAD 2> /dev/null)
- local ret=$?
- if [[ $ret != 0 ]]; then
- [[ $ret == 128 ]] && return # no git repo.
- ref=$(command git rev-parse --short HEAD 2> /dev/null) || return
- fi
- echo ${ref#refs/heads/}
- }
- # Gets the number of commits ahead from remote
- function git_commits_ahead() {
- if command git rev-parse --git-dir &>/dev/null; then
- local commits="$(git rev-list --count @{upstream}..HEAD 2>/dev/null)"
- if [[ -n "$commits" && "$commits" != 0 ]]; then
- echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"
- fi
- fi
- }
- # Gets the number of commits behind remote
- function git_commits_behind() {
- if command git rev-parse --git-dir &>/dev/null; then
- local commits="$(git rev-list --count HEAD..@{upstream} 2>/dev/null)"
- if [[ -n "$commits" && "$commits" != 0 ]]; then
- echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"
- fi
- fi
- }
- # Outputs if current branch is ahead of remote
- function git_prompt_ahead() {
- if [[ -n "$(command git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
- fi
- }
- # Outputs if current branch is behind remote
- function git_prompt_behind() {
- if [[ -n "$(command git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_BEHIND"
- fi
- }
- # Outputs if current branch exists on remote or not
- function git_prompt_remote() {
- if [[ -n "$(command git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"
- else
- echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING"
- fi
- }
- # Formats prompt string for current git commit short SHA
- function git_prompt_short_sha() {
- local SHA
- SHA=$(command git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
- }
- # Formats prompt string for current git commit long SHA
- function git_prompt_long_sha() {
- local SHA
- SHA=$(command git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
- }
- # Get the status of the working tree
- function git_prompt_status() {
- local INDEX STATUS
- INDEX=$(command git status --porcelain -b 2> /dev/null)
- STATUS=""
- if $(echo "$INDEX" | command grep -E '^\?\? ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^A ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
- elif $(echo "$INDEX" | grep '^M ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
- elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^ M ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
- elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
- elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
- elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^R ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
- elif $(echo "$INDEX" | grep '^D ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
- elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
- fi
- if $(command git rev-parse --verify refs/stash >/dev/null 2>&1); then
- STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS"
- fi
- if $(echo "$INDEX" | grep '^## [^ ]\+ .*ahead' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_AHEAD$STATUS"
- fi
- if $(echo "$INDEX" | grep '^## [^ ]\+ .*behind' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_BEHIND$STATUS"
- fi
- if $(echo "$INDEX" | grep '^## [^ ]\+ .*diverged' &> /dev/null); then
- STATUS="$ZSH_THEME_GIT_PROMPT_DIVERGED$STATUS"
- fi
- echo $STATUS
- }
- # Compares the provided version of git to the version installed and on path
- # Outputs -1, 0, or 1 if the installed version is less than, equal to, or
- # greater than the input version, respectively.
- function git_compare_version() {
- local INPUT_GIT_VERSION INSTALLED_GIT_VERSION i
- INPUT_GIT_VERSION=(${(s/./)1})
- INSTALLED_GIT_VERSION=($(command git --version 2>/dev/null))
- INSTALLED_GIT_VERSION=(${(s/./)INSTALLED_GIT_VERSION[3]})
- for i in {1..3}; do
- if [[ $INSTALLED_GIT_VERSION[$i] -gt $INPUT_GIT_VERSION[$i] ]]; then
- echo 1
- return 0
- fi
- if [[ $INSTALLED_GIT_VERSION[$i] -lt $INPUT_GIT_VERSION[$i] ]]; then
- echo -1
- return 0
- fi
- done
- echo 0
- }
- # Outputs the name of the current user
- # Usage example: $(git_current_user_name)
- function git_current_user_name() {
- command git config user.name 2>/dev/null
- }
- # Outputs the email of the current user
- # Usage example: $(git_current_user_email)
- function git_current_user_email() {
- command git config user.email 2>/dev/null
- }
- # This is unlikely to change so make it all statically assigned
- POST_1_7_2_GIT=$(git_compare_version "1.7.2")
- # Clean up the namespace slightly by removing the checker function
- unfunction git_compare_version
- #====================================================================================================================#
- ## Syntax Highlighting ##
- typeset -gA __fast_highlight_main__command_type_cache FAST_BLIST_PATTERNS
- typeset -g FAST_WORK_DIR
- : ${FAST_WORK_DIR:=$FAST_BASE_DIR}
- FAST_WORK_DIR=${~FAST_WORK_DIR}
- () {
- setopt localoptions extendedglob
- local -A map
- map=( "XDG:" "${XDG_CONFIG_HOME:-$HOME/.config}/fsh/"
- "LOCAL:" "/usr/local/share/fsh/"
- "HOME:" "$HOME/.fsh/"
- "OPT:" "/opt/local/share/fsh/"
- )
- FAST_WORK_DIR=${${FAST_WORK_DIR/(#m)(#s)(XDG|LOCAL|HOME|OPT):(#c0,1)/${map[${MATCH%:}:]}}%/}
- }
- # Define default styles. You can set this after loading the plugin in
- # Zshrc and use 256 colors via numbers, like: fg=150
- typeset -gA FAST_HIGHLIGHT_STYLES
- if [[ -e $FAST_WORK_DIR/current_theme.zsh ]]; then
- source $FAST_WORK_DIR/current_theme.zsh
- else
- # built-in theme
- zstyle :plugin:fast-syntax-highlighting theme default
- : ${FAST_HIGHLIGHT_STYLES[default]:=none}
- : ${FAST_HIGHLIGHT_STYLES[unknown-token]:=fg=red,bold}
- : ${FAST_HIGHLIGHT_STYLES[reserved-word]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[subcommand]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[alias]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[suffix-alias]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[global-alias]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[builtin]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[function]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[command]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[precommand]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[commandseparator]:=none}
- : ${FAST_HIGHLIGHT_STYLES[hashed-command]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[path]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[path-to-dir]:=fg=magenta,underline}
- : ${FAST_HIGHLIGHT_STYLES[path_pathseparator]:=}
- : ${FAST_HIGHLIGHT_STYLES[globbing]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[globbing-ext]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[history-expansion]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[single-hyphen-option]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[double-hyphen-option]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[back-quoted-argument]:=none}
- : ${FAST_HIGHLIGHT_STYLES[single-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[back-dollar-quoted-argument]:=fg=cyan}
- : ${FAST_HIGHLIGHT_STYLES[assign]:=none}
- : ${FAST_HIGHLIGHT_STYLES[redirection]:=none}
- : ${FAST_HIGHLIGHT_STYLES[comment]:=fg=black,bold}
- : ${FAST_HIGHLIGHT_STYLES[variable]:=fg=113}
- : ${FAST_HIGHLIGHT_STYLES[mathvar]:=fg=blue,bold}
- : ${FAST_HIGHLIGHT_STYLES[mathnum]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[matherr]:=fg=red}
- : ${FAST_HIGHLIGHT_STYLES[assign-array-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-variable]:=none}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-operator]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-number]:=fg=magenta}
- : ${FAST_HIGHLIGHT_STYLES[for-loop-separator]:=fg=yellow,bold}
- : ${FAST_HIGHLIGHT_STYLES[here-string-tri]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[here-string-text]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[here-string-var]:=fg=cyan,bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[case-input]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[case-parentheses]:=fg=yellow}
- : ${FAST_HIGHLIGHT_STYLES[case-condition]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[paired-bracket]:=bg=blue}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-1]:=fg=green,bold}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-2]:=fg=yellow,bold}
- : ${FAST_HIGHLIGHT_STYLES[bracket-level-3]:=fg=cyan,bold}
- : ${FAST_HIGHLIGHT_STYLES[single-sq-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[double-sq-bracket]:=fg=green}
- : ${FAST_HIGHLIGHT_STYLES[double-paren]:=fg=yellow}
- fi
- # This can overwrite some of *_STYLES fields
- [[ -r $FAST_WORK_DIR/theme_overlay.zsh ]] && source $FAST_WORK_DIR/theme_overlay.zsh
- typeset -gA __FAST_HIGHLIGHT_TOKEN_TYPES
- __FAST_HIGHLIGHT_TOKEN_TYPES=(
- # Precommand
- 'builtin' 1
- 'command' 1
- 'exec' 1
- 'nocorrect' 1
- 'noglob' 1
- 'pkexec' 1 # immune to #121 because it's usually not passed --option flags
- # Control flow
- # Tokens that, at (naively-determined) "command position", are followed by
- # a de jure command position. All of these are reserved words.
- $'\x7b' 2 # block '{'
- $'\x28' 2 # subshell '('
- '()' 2 # anonymous function
- 'while' 2
- 'until' 2
- 'if' 2
- 'then' 2
- 'elif' 2
- 'else' 2
- 'do' 2
- 'time' 2
- 'coproc' 2
- '!' 2 # reserved word; unrelated to $histchars[1]
- # Command separators
- '|' 3
- '||' 3
- ';' 3
- '&' 3
- '&&' 3
- '|&' 3
- '&!' 3
- '&|' 3
- # ### 'case' syntax, but followed by a pattern, not by a command
- # ';;' ';&' ';|'
- )
- # A hash instead of multiple globals
- typeset -gA FAST_HIGHLIGHT
- # Brackets highlighter active by default
- : ${FAST_HIGHLIGHT[use_brackets]:=1}
- FAST_HIGHLIGHT+=(
- chroma-fast-theme chroma/-fast-theme.ch
- chroma-alias chroma/-alias.ch
- chroma-autoload chroma/-autoload.ch
- chroma-autorandr chroma/-autorandr.ch
- chroma-docker chroma/-docker.ch
- chroma-example chroma/-example.ch
- chroma-make chroma/-make.ch
- chroma-nmcli chroma/-nmcli.ch
- chroma-node chroma/-node.ch
- chroma-perl chroma/-perl.ch
- chroma-printf chroma/-printf.ch
- chroma-ruby chroma/-ruby.ch
- chroma-scp chroma/-scp.ch
- chroma-ssh chroma/-ssh.ch
- chroma-git chroma/-git.ch
- chroma-hub chroma/-git.ch
- chroma-lab chroma/-git.ch
- chroma-egrep chroma/-grep.ch
- chroma-fgrep chroma/-grep.ch
- chroma-grep chroma/-grep.ch
- chroma-awk chroma/-awk.ch
- chroma-gawk chroma/-awk.ch
- chroma-mawk chroma/-awk.ch
- chroma-source chroma/-source.ch
- chroma-. chroma/-source.ch
- chroma-bash chroma/-sh.ch
- chroma-fish chroma/-sh.ch
- chroma-sh chroma/-sh.ch
- chroma-tmux chroma/-sh.ch
- chroma-zsh chroma/-sh.ch
- chroma-whatis chroma/-whatis.ch
- chroma-man chroma/-whatis.ch
- chroma-hg chroma/-subcommand.ch
- chroma-cvs chroma/-subcommand.ch
- chroma-pip chroma/-subcommand.ch
- chroma-pip2 chroma/-subcommand.ch
- chroma-pip3 chroma/-subcommand.ch
- chroma-gem chroma/-subcommand.ch
- chroma-yard chroma/-subcommand.ch
- chroma-cabal chroma/-subcommand.ch
- chroma-npm chroma/-subcommand.ch
- chroma-nvm chroma/-subcommand.ch
- chroma-yarn chroma/-subcommand.ch
- chroma-brew chroma/-subcommand.ch
- chroma-port chroma/-subcommand.ch
- chroma-yum chroma/-subcommand.ch
- chroma-dnf chroma/-subcommand.ch
- chroma-apt-get chroma/-subcommand.ch
- chroma-apt-cache chroma/-subcommand.ch
- chroma-aptitude chroma/-subcommand.ch
- chroma-keyctl chroma/-subcommand.ch
- chroma-systemctl chroma/-subcommand.ch
- chroma-asciinema chroma/-subcommand.ch
- chroma-ipfs chroma/-subcommand.ch
- chroma-zplugin chroma/-subcommand.ch
- chroma-aspell chroma/-subcommand.ch
- chroma-bspc chroma/-subcommand.ch
- chroma-cryptsetup chroma/-subcommand.ch
- chroma-diskutil chroma/-subcommand.ch
- chroma-exercism chroma/-subcommand.ch
- chroma-gulp chroma/-subcommand.ch
- chroma-i3-msg chroma/-subcommand.ch
- chroma-openssl chroma/-subcommand.ch
- chroma-solargraph chroma/-subcommand.ch
- chroma-subliminal chroma/-subcommand.ch
- chroma-svnadmin chroma/-subcommand.ch
- chroma-travis chroma/-subcommand.ch
- chroma-xdotool chroma/-subcommand.ch
- chroma-zmanage chroma/-subcommand.ch
- chroma-zsystem chroma/-subcommand.ch
- chroma-zypper chroma/-subcommand.ch
- chroma-fpath+=\( chroma/-fpath_peq.ch
- chroma-fpath=\( chroma/-fpath_peq.ch
- chroma-FPATH+= chroma/-fpath_peq.ch
- chroma-FPATH= chroma/-fpath_peq.ch
- #chroma-which chroma/-which.ch
- #chroma-vim chroma/-vim.ch
- )
- # Assignments seen, to know if math parameter exists
- typeset -gA FAST_ASSIGNS_SEEN
- # Exposing tokens found on command position,
- # for other scripts to process
- typeset -ga ZLAST_COMMANDS
- # Get the type of a command.
- #
- # Uses the zsh/parameter module if available to avoid forks, and a
- # wrapper around 'type -w' as fallback.
- #
- # Takes a single argument.
- #
- # The result will be stored in REPLY.
- -fast-highlight-main-type() {
- REPLY=$__fast_highlight_main__command_type_cache[(e)$1]
- [[ -z $REPLY ]] && {
- if zmodload -e zsh/parameter; then
- if (( $+aliases[(e)$1] )); then
- REPLY=alias
- elif (( ${+galiases[(e)$1]} )); then
- REPLY="global alias"
- elif (( $+functions[(e)$1] )); then
- REPLY=function
- elif (( $+builtins[(e)$1] )); then
- REPLY=builtin
- elif (( $+commands[(e)$1] )); then
- REPLY=command
- elif (( $+saliases[(e)${1##*.}] )); then
- REPLY='suffix alias'
- elif (( $reswords[(Ie)$1] )); then
- REPLY=reserved
- # zsh 5.2 and older have a bug whereby running 'type -w ./sudo' implicitly
- # runs 'hash ./sudo=/usr/local/bin/./sudo' (assuming /usr/local/bin/sudo
- # exists and is in $PATH). Avoid triggering the bug, at the expense of
- # falling through to the $() below, incurring a fork. (Issue #354.)
- #
- # The second disjunct mimics the isrelative() C call from the zsh bug.
- elif [[ $1 != */* || ${+ZSH_ARGZERO} = "1" ]] && ! builtin type -w -- $1 >/dev/null 2>&1; then
- REPLY=none
- fi
- fi
- [[ -z $REPLY ]] && REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)##*: }"
- [[ $REPLY = "none" ]] && {
- [[ -n ${FAST_BLIST_PATTERNS[(k)${${(M)1:#/*}:-$PWD/$1}]} ]] || {
- [[ -d $1 ]] && REPLY="dirpath" || {
- for cdpath_dir in $cdpath; do
- [[ -d $cdpath_dir/$1 ]] && { REPLY="dirpath"; break; }
- done
- }
- }
- }
- __fast_highlight_main__command_type_cache[(e)$1]=$REPLY
- }
- }
- # Below are variables that must be defined in outer
- # scope so that they are reachable in *-process()
- -fast-highlight-fill-option-variables() {
- if [[ -o ignore_braces ]] || eval '[[ -o ignore_close_braces ]] 2>/dev/null'; then
- FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=0
- else
- FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=1
- fi
- if [[ -o path_dirs ]]; then
- FAST_HIGHLIGHT[path_dirs_was_set]=1
- else
- FAST_HIGHLIGHT[path_dirs_was_set]=0
- fi
- if [[ -o multi_func_def ]]; then
- FAST_HIGHLIGHT[multi_func_def]=1
- else
- FAST_HIGHLIGHT[multi_func_def]=0
- fi
- if [[ -o interactive_comments ]]; then
- FAST_HIGHLIGHT[ointeractive_comments]=1
- else
- FAST_HIGHLIGHT[ointeractive_comments]=0
- fi
- }
- # Main syntax highlighting function.
- -fast-highlight-process()
- {
- emulate -L zsh
- setopt extendedglob bareglobqual nonomatch noksharrays
- [[ $CONTEXT == "select" ]] && return 0
- (( FAST_HIGHLIGHT[path_dirs_was_set] )) && setopt PATH_DIRS
- (( FAST_HIGHLIGHT[ointeractive_comments] )) && local interactive_comments= # _set_ to empty
- # Variable declarations and initializations
- # in_array_assignment true between 'a=(' and the matching ')'
- # braces_stack: "R" for round, "Q" for square, "Y" for curly
- # _mybuf, cdpath_dir are used in sub-functions
- local _start_pos=$3 _end_pos __start __end highlight_glob=1 __arg __style in_array_assignment=0 MATCH expanded_path braces_stack __buf=$1$2 _mybuf __workbuf cdpath_dir active_command alias_target _was_double_hyphen=0 __nul=$'\0' __tmp
- # __arg_type can be 0, 1, 2 or 3, i.e. precommand, control flow, command separator
- # __idx and _end_idx are used in sub-functions
- # for this_word and next_word look below at commented integers and at state machine description
- integer __arg_type=0 MBEGIN MEND in_redirection __len=${#__buf} __PBUFLEN=${#1} already_added offset __idx _end_idx this_word=1 next_word=0 __pos __asize __delimited=0 itmp iitmp
- local -a match mbegin mend __inputs __list
- # This comment explains the numbers:
- # BIT_for - word after reserved-word-recognized `for'
- # BIT_afpcmd - word after a precommand that can take options, like `command' and `exec'
- # integer BIT_start=1 BIT_regular=2 BIT_sudo_opt=4 BIT_sudo_arg=8 BIT_always=16 BIT_for=32 BIT_afpcmd=64
- # integer BIT_chroma=8192
- integer BIT_case_preamble=512 BIT_case_item=1024 BIT_case_nempty_item=2048 BIT_case_code=4096
- # Braces stack
- # T - typeset, local, etc.
- # State machine
- #
- # The states are:
- # - :__start: Command word
- # - :sudo_opt: A leading-dash option to sudo (such as "-u" or "-i")
- # - :sudo_arg: The argument to a sudo leading-dash option that takes one,
- # when given as a separate word; i.e., "foo" in "-u foo" (two
- # words) but not in "-ufoo" (one word).
- # - :regular: "Not a command word", and command delimiters are permitted.
- # Mainly used to detect premature termination of commands.
- # - :always: The word 'always' in the «{ foo } always { bar }» syntax.
- #
- # When the kind of a word is not yet known, $this_word / $next_word may contain
- # multiple states. For example, after "sudo -i", the next word may be either
- # another --flag or a command name, hence the state would include both :__start:
- # and :sudo_opt:.
- #
- # The tokens are always added with both leading and trailing colons to serve as
- # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/}
- # will DTRT regardless of how many elements or repetitions $x has..
- #
- # Handling of redirections: upon seeing a redirection token, we must stall
- # the current state --- that is, the value of $this_word --- for two iterations
- # (one for the redirection operator, one for the word following it representing
- # the redirection target). Therefore, we set $in_redirection to 2 upon seeing a
- # redirection operator, decrement it each iteration, and stall the current state
- # when it is non-zero. Thus, upon reaching the next word (the one that follows
- # the redirection operator and target), $this_word will still contain values
- # appropriate for the word immediately following the word that preceded the
- # redirection operator.
- #
- # The "the previous word was a redirection operator" state is not communicated
- # to the next iteration via $next_word/$this_word as usual, but via
- # $in_redirection. The value of $next_word from the iteration that processed
- # the operator is discarded.
- #
- # Command exposure for other scripts
- ZLAST_COMMANDS=()
- # Restart observing of assigns
- FAST_ASSIGNS_SEEN=()
- # Restart function's gathering
- FAST_HIGHLIGHT[chroma-autoload-elements]=""
- # Restart FPATH elements gathering
- FAST_HIGHLIGHT[chroma-fpath_peq-elements]=""
- [[ -n $ZCALC_ACTIVE ]] && {
- _start_pos=0; _end_pos=__len; __arg=$__buf
- -fast-highlight-math-string
- return 0
- }
- # Processing buffer
- local proc_buf=$__buf needle
- for __arg in ${interactive_comments-${(z)__buf}} \
- ${interactive_comments+${(zZ+c+)__buf}}; do
- # Initialize $next_word to its default value?
- (( in_redirection = in_redirection > 0 ? in_redirection - 1 : in_redirection ));
- (( next_word = (in_redirection == 0) ? 2 : next_word )) # else Stall $next_word.
- (( next_word = next_word | (this_word & (BIT_case_code|8192)) ))
- # If we have a good delimiting construct just ending, and '{'
- # occurs, then respect this and go for alternate syntax, i.e.
- # treat '{' (\x7b) as if it's on command position
- [[ $__arg = '{' && $__delimited = 2 ]] && { (( this_word = (this_word & ~2) | 1 )); __delimited=0; }
- __asize=${#__arg}
- # Reset state of working variables
- already_added=0
- __style=${FAST_THEME_NAME}unknown-token
- (( this_word & 1 )) && { in_array_assignment=0; [[ $__arg == 'noglob' ]] && highlight_glob=0; }
- # Compute the new $_start_pos and $_end_pos, skipping over whitespace in $__buf.
- if [[ $__arg == ';' ]] ; then
- braces_stack=${braces_stack#T}
- __delimited=0
- # Both ; and \n are rendered as a ";" (SEPER) by the ${(z)..} flag.
- needle=$';\n'
- [[ $proc_buf = (#b)[^$needle]#([$needle]##)* ]] && offset=${mbegin[1]}-1
- (( _start_pos += offset ))
- (( _end_pos = _start_pos + __asize ))
- # Prepare next loop cycle
- (( this_word & BIT_case_item )) || { (( in_array_assignment )) && (( this_word = 2 | (this_word & BIT_case_code) )) || { (( this_word = 1 | (this_word & BIT_case_code) )); highlight_glob=1; }; }
- in_redirection=0
- # Chance to highlight ';'
- [[ ${proc_buf[offset+1]} != $'\n' ]] && {
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}commandseparator]} != "none" ]] && \
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}commandseparator]}")
- }
- proc_buf=${proc_buf[offset + __asize + 1,__len]}
- _start_pos=$_end_pos
- continue
- else
- offset=0
- if [[ $proc_buf = (#b)(#s)(([[:space:]]|\\[[:space:]])##)* ]]; then
- # The first, outer parenthesis
- offset=${mend[1]}
- fi
- (( _start_pos += offset ))
- (( _end_pos = _start_pos + __asize ))
- # No-hit will result in value 0
- __arg_type=${__FAST_HIGHLIGHT_TOKEN_TYPES[$__arg]}
- fi
- (( this_word & 1 )) && ZLAST_COMMANDS+=( $__arg );
- proc_buf=${proc_buf[offset + __asize + 1,__len]}
- # Handle the INTERACTIVE_COMMENTS option.
- #
- # We use the (Z+c+) flag so the entire comment is presented as one token in $__arg.
- if [[ -n ${interactive_comments+'set'} && $__arg == ${histchars[3]}* ]]; then
- if (( this_word & 3 )); then
- __style=${FAST_THEME_NAME}comment
- else
- __style=${FAST_THEME_NAME}unknown-token # prematurely terminated
- fi
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- _start_pos=$_end_pos
- continue
- fi
- # Redirection?
- [[ $__arg == (<0-9>|)(\<|\>)* && $__arg != (\<|\>)$'\x28'* && $__arg != "<<<" ]] && \
- in_redirection=2
- # Special-case the first word after 'sudo'.
- if (( ! in_redirection )); then
- (( this_word & 4 )) && [[ $__arg != -* ]] && (( this_word = this_word ^ 4 ))
- # Parse the sudo command line
- if (( this_word & 4 )); then
- case $__arg in
- # Flag that requires an argument
- '-'[Cgprtu])
- (( this_word = this_word & ~1 ))
- (( next_word = 8 | (this_word & BIT_case_code) ))
- ;;
- # This prevents misbehavior with sudo -u -otherargument
- '-'*)
- (( this_word = this_word & ~1 ))
- (( next_word = next_word | 1 | 4 ))
- ;;
- esac
- elif (( this_word & 8 )); then
- (( next_word = next_word | 4 | 1 ))
- elif (( this_word & 64 )); then
- [[ $__arg = -[pvV-]## && $active_command = "command" ]] && (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- [[ $__arg = -[cla-]## && $active_command = "exec" ]] && (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- [[ $__arg = \{[a-zA-Z][a-zA-Z0-9]#\} && $active_command = "exec" ]] && {
- # Highlight {descriptor} passed to exec
- (( this_word = (this_word & ~1) | 2, next_word = (next_word | 65) & ~2 ))
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}exec-descriptor]}")
- already_added=1
- }
- fi
- fi
- (( this_word & 1 )) && {
- # !in_redirection needed particularly for exec {A}>b {C}>d
- (( !in_redirection )) && active_command=$__arg
- _mybuf=${${aliases[$active_command]:-$active_command}##[[:space:]]#(command|builtin|exec|noglob|nocorrect|pkexec)[[:space:]]#}
- [[ "$_mybuf" = (#b)(FPATH+(#c0,1)=)* ]] && _mybuf="${match[1]} ${(j: :)${(s,:,)${_mybuf#FPATH+(#c0,1)=}}}"
- [[ -n ${FAST_HIGHLIGHT[chroma-${_mybuf%% *}]} ]] && {
- __list=( ${(z@)_mybuf} )
- if (( ${#__list} > 1 )) || [[ $active_command != $_mybuf ]]; then
- __style=${FAST_THEME_NAME}alias
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- ${FAST_HIGHLIGHT[chroma-${__list[1]}]} 1 "${__list[1]}" "-100000" $_end_pos 2>/dev/null || \
- (( this_word = next_word, next_word = 2 ))
- for _mybuf in "${(@)__list[2,-1]}"; do
- (( next_word = next_word | (this_word & (BIT_case_code|8192)) ))
- ${FAST_HIGHLIGHT[chroma-${__list[1]}]} 0 "$_mybuf" "-100000" $_end_pos 2>/dev/null || \
- (( this_word = next_word, next_word = 2 ))
- done
- # This might have been done multiple times in chroma, but
- # as _end_pos doesn't change, it can be done one more time
- _start_pos=$_end_pos
- continue
- else
- ${FAST_HIGHLIGHT[chroma-$active_command]} 1 "$__arg" $_start_pos $_end_pos 2>/dev/null && continue
- fi
- } || (( 1 ))
- } || {
- (( this_word & 8192 )) && {
- __list=( ${(z@)${aliases[$active_command]:-$active_command}##[[:space:]]#(command|builtin|exec|noglob|nocorrect|pkexec)[[:space:]]#} )
- ${FAST_HIGHLIGHT[chroma-${__list[1]}]} 0 "$__arg" $_start_pos $_end_pos 2>/dev/null && continue
- }
- }
- expanded_path=""
- # The Great Fork: is this a command word? Is this a non-command word?
- if (( this_word & 16 )) && [[ $__arg == 'always' ]]; then
- # try-always construct
- __style=${FAST_THEME_NAME}reserved-word # de facto a reserved word, although not de jure
- (( next_word = 1 | (this_word & BIT_case_code) ))
- elif (( (this_word & 1) && (in_redirection == 0) )) || [[ $braces_stack = T* ]]; then
- if (( __arg_type == 1 )); then
- __style=${FAST_THEME_NAME}precommand
- [[ $__arg = "command" || $__arg = "exec" ]] && (( next_word = next_word | 64 ))
- elif [[ $__arg = "sudo" ]]; then
- __style=${FAST_THEME_NAME}precommand
- (( next_word = (next_word & ~2) | 4 | 1 ))
- else
- _mybuf=${${(Q)__arg}#\"}
- if [[ $_mybuf == \$* ]] && (( ${+parameters} )) && \
- [[ $_mybuf = (#b)\$([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##)(/*|) || $_mybuf = (#b)\$\{([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##)\}(/*|) ]] && \
- (( ${+parameters[${match[1]}]} )); then
- -fast-highlight-main-type ${(P)match[1]}${match[2]}
- elif [[ $braces_stack = T* ]]; then # T - typedef, etc.
- REPLY=none
- else
- : ${expanded_path::=${~_mybuf}}
- -fast-highlight-main-type $expanded_path
- fi
- case $REPLY in
- reserved) # reserved word
- [[ $__arg = "[[" ]] && __style=${FAST_THEME_NAME}double-sq-bracket || __style=${FAST_THEME_NAME}reserved-word
- if [[ $__arg == $'\x7b' ]]; then # '{'
- braces_stack='Y'$braces_stack
- elif [[ $__arg == $'\x7d' && $braces_stack = Y* ]]; then # '}'
- # We're at command word, so no need to check right_brace_is_recognised_everywhere
- braces_stack=${braces_stack#Y}
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = next_word | 16 ))
- elif [[ $__arg == "[[" ]]; then
- braces_stack='A'$braces_stack
- # Counting complex brackets (for brackets-highlighter): 1. [[ as command
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- elif [[ $__arg == "for" ]]; then
- (( next_word = next_word | 32 )) # BIT_for
- elif [[ $__arg == "case" ]]; then
- (( next_word = BIT_case_preamble ))
- elif [[ $__arg = (typeset|declare|local|float|integer|export|readonly) ]]; then
- braces_stack='T'$braces_stack
- fi
- ;;
- 'suffix alias') __style=${FAST_THEME_NAME}suffix-alias;;
- 'global alias') __style=${FAST_THEME_NAME}global-alias;;
- alias)
- if [[ $__arg = ?*'='* ]]; then
- # The so called (by old code) "insane_alias"
- __style=${FAST_THEME_NAME}unknown-token
- else
- __style=${FAST_THEME_NAME}alias
- (( ${+aliases} )) && alias_target=${aliases[$__arg]} || alias_target="${"$(alias -- $__arg)"#*=}"
- [[ ${__FAST_HIGHLIGHT_TOKEN_TYPES[$alias_target]} = "1" && $__arg_type != "1" ]] && __FAST_HIGHLIGHT_TOKEN_TYPES[$__arg]="1"
- fi
- ;;
- builtin) [[ $__arg = "[" ]] && {
- __style=${FAST_THEME_NAME}single-sq-bracket
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- } || __style=${FAST_THEME_NAME}builtin
- # T - typeset, etc. mode
- [[ $__arg = (typeset|declare|local|float|integer|export|readonly) ]] && braces_stack='T'$braces_stack
- [[ $__arg = eval ]] && (( next_word = next_word | 256 ))
- ;;
- function) __style=${FAST_THEME_NAME}function;;
- command) __style=${FAST_THEME_NAME}command;;
- hashed) __style=${FAST_THEME_NAME}hashed-command;;
- dirpath) __style=${FAST_THEME_NAME}path-to-dir;;
- none) # Assign?
- if [[ $__arg == [a-zA-Z_][a-zA-Z0-9_]#(|\[[^\]]#\])(|[^\]]#\])(|[+])=* || $__arg == [0-9]##(|[+])=* || ( $braces_stack = T* && ${__arg_type} != 3 ) ]]; then
- __style=${FAST_THEME_NAME}assign
- [[ $__arg = ?*[=]* ]] && FAST_ASSIGNS_SEEN[${__arg%%=*}]=1
- # Handle array assignment
- [[ $__arg = (#b)*=(\()*(\))* || $__arg = (#b)*=(\()* ]] && {
- (( __start=_start_pos-__PBUFLEN+${mbegin[1]}-1, __end=__start+1, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- # Counting complex brackets (for brackets-highlighter): 2. ( in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- (( mbegin[2] >= 1 )) && {
- (( __start=_start_pos-__PBUFLEN+${mbegin[2]}-1, __end=__start+1, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- # Counting complex brackets (for brackets-highlighter): 3a. ) in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- } || in_array_assignment=1
- } || { [[ ${braces_stack[1]} != 'T' ]] && (( next_word = (next_word | 1) & ~2 )); }
- # Handle no-string highlight, string "/' highlight, math mode highlight
- local ctmp="\"" dtmp="'"
- itmp=${__arg[(i)$ctmp]}-1 iitmp=${__arg[(i)$dtmp]}-1
- integer jtmp=${__arg[(b:itmp+2:i)$ctmp]} jjtmp=${__arg[(b:iitmp+2:i)$dtmp]}
- (( itmp < iitmp && itmp <= __asize - 1 )) && (( jtmp > __asize && (jtmp = __asize), 1 > 0 )) && \
- (( __start=_start_pos-__PBUFLEN+itmp, __end=_start_pos-__PBUFLEN+jtmp, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-quoted-argument]}") && \
- { itmp=${__arg[(i)=]}; __arg=${__arg[itmp,__asize]}; (( _start_pos += itmp - 1 ));
- -fast-highlight-string; (( _start_pos = _start_pos - itmp + 1, 1 > 0 )); } || \
- {
- (( iitmp <= __asize - 1 )) && (( jjtmp > __asize && (jjtmp = __asize), 1 > 0 )) && \
- (( __start=_start_pos-__PBUFLEN+iitmp, __end=_start_pos-__PBUFLEN+jjtmp, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}single-quoted-argument]}")
- } || \
- {
- itmp=${__arg[(i)=]}; __arg=${__arg[itmp,__asize]}; (( _start_pos += itmp - 1 ));
- [[ ${__arg[2,4]} = '$((' ]] && { -fast-highlight-math-string;
- (( __start=_start_pos-__PBUFLEN+2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 4. $(( in assign argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- (( jtmp = ${__arg[(I)\)\)]}-1, jtmp > 0 )) && {
- (( __start=_start_pos-__PBUFLEN+jtmp, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 5. )) in assign argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- }
- } || -fast-highlight-string;
- (( _start_pos = _start_pos - itmp + 1, 1 > 0 ))
- }
- elif [[ $__arg = ${histchars[1]}* && -n ${__arg[2]} ]]; then
- __style=${FAST_THEME_NAME}history-expansion
- elif [[ $__arg == ${histchars[2]}* ]]; then
- __style=${FAST_THEME_NAME}history-expansion
- elif (( __arg_type == 3 )); then
- # This highlights empty commands (semicolon follows nothing) as an error.
- # Zsh accepts them, though.
- (( this_word & 2 )) && __style=${FAST_THEME_NAME}commandseparator
- elif [[ $__arg[1,2] == '((' ]]; then
- # Arithmetic evaluation.
- #
- # Note: prior to zsh-5.1.1-52-g4bed2cf (workers/36669), the ${(z)...}
- # splitter would only output the '((' token if the matching '))' had
- # been typed. Therefore, under those versions of zsh, BUFFER="(( 42"
- # would be highlighted as an error until the matching "))" are typed.
- #
- # We highlight just the opening parentheses, as a reserved word; this
- # is how [[ ... ]] is highlighted, too.
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- already_added=1
- # Counting complex brackets (for brackets-highlighter): 6. (( as command
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- -fast-highlight-math-string
- # ADD
- [[ $__arg[-2,-1] == '))' ]] && {
- (( __start=_end_pos-__PBUFLEN-2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- (( __delimited = __delimited ? 2 : __delimited ))
- # Counting complex brackets (for brackets-highlighter): 7. )) for as-command ((
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- }
- elif [[ $__arg == '()' ]]; then
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- # anonymous function
- __style=${FAST_THEME_NAME}reserved-word
- elif [[ $__arg == $'\x28' ]]; then
- # subshell '(', stack: letter 'R'
- __style=${FAST_THEME_NAME}reserved-word
- braces_stack='R'$braces_stack
- elif [[ $__arg == $'\x29' ]]; then
- # ')', stack: letter 'R' for subshell
- [[ $braces_stack = R* ]] && { braces_stack=${braces_stack#R}; __style=${FAST_THEME_NAME}reserved-word; }
- elif (( this_word & 14 )); then
- __style=${FAST_THEME_NAME}default
- elif [[ $__arg = (';;'|';&'|';|') ]] && (( this_word & BIT_case_code )); then
- (( next_word = (next_word | BIT_case_item) & ~(BIT_case_code+3) ))
- __style=${FAST_THEME_NAME}default
- elif [[ $__arg = \$\([^\(]* ]]; then
- already_added=1
- fi
- ;;
- *)
- # ADD
- # (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end commandtypefromthefuture-$REPLY")
- already_added=1
- ;;
- esac
- fi
- # in_redirection || BIT_regular || BIT_sudo_opt || BIT_sudo_arg
- elif (( in_redirection + this_word & 14 ))
- then # $__arg is a non-command word
- case $__arg in
- ']]')
- # A - [[
- [[ $braces_stack = A* ]] && {
- __style=${FAST_THEME_NAME}double-sq-bracket
- (( __delimited = __delimited ? 2 : __delimited ))
- # Counting complex brackets (for brackets-highlighter): 8a. ]] for as-command [[
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- } || {
- [[ $braces_stack = *A* ]] && {
- __style=${FAST_THEME_NAME}unknown-token
- # Counting complex brackets (for brackets-highlighter): 8b. ]] for as-command [[
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- } || __style=${FAST_THEME_NAME}default
- }
- braces_stack=${braces_stack#A}
- ;;
- ']')
- __style=${FAST_THEME_NAME}single-sq-bracket
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- ;;
- $'\x28')
- # '(' inside [[
- __style=${FAST_THEME_NAME}reserved-word
- braces_stack='R'$braces_stack
- ;;
- $'\x29') # ')' - subshell or end of array assignment
- if (( in_array_assignment )); then
- in_array_assignment=0
- (( next_word = next_word | 1 ))
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}assign-array-bracket]}")
- already_added=1
- # Counting complex brackets (for brackets-highlighter): 3b. ) in array assign
- _FAST_COMPLEX_BRACKETS+=( $__start )
- elif [[ $braces_stack = R* ]]; then
- braces_stack=${braces_stack#R}
- __style=${FAST_THEME_NAME}reserved-word
- # Zsh doesn't tokenize final ) if it's just single ')',
- # but logically what's below is correct, so it is kept
- # in case Zsh will be changed / fixed, etc.
- elif [[ $braces_stack = F* ]]; then
- __style=${FAST_THEME_NAME}builtin
- fi
- ;;
- $'\x28\x29') # '()' - possibly a function definition
- # || false # TODO: or if the previous word was a command word
- (( FAST_HIGHLIGHT[multi_func_def] )) && (( next_word = next_word | 1 ))
- __style=${FAST_THEME_NAME}reserved-word
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN + 1 )) )
- # Remove possible annoying unknown-token __style, or misleading function __style
- reply[-1]=()
- __fast_highlight_main__command_type_cache[$active_command]="function"
- ;;
- '--'*) [[ $__arg == "--" ]] && { _was_double_hyphen=1; __style=${FAST_THEME_NAME}double-hyphen-option; } || {
- (( !_was_double_hyphen )) && {
- [[ "$__arg" = (#b)(--[a-zA-Z0-9_]##)=(*) ]] && {
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-hyphen-option]}")
- (( __start=_start_pos-__PBUFLEN+1+mend[1], __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}optarg-${${${(M)match[2]:#<->}:+number}:-string}]}")
- already_added=1
- } || __style=${FAST_THEME_NAME}double-hyphen-option
- } || __style=${FAST_THEME_NAME}default
- }
- ;;
- '-'*) (( !_was_double_hyphen )) && __style=${FAST_THEME_NAME}single-hyphen-option || __style=${FAST_THEME_NAME}default;;
- \$\'*)
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}dollar-quoted-argument]}")
- -fast-highlight-dollar-string
- already_added=1
- ;;
- [\"\']*|[^\"\\]##([\\][\\])#\"*|[^\'\\]##([\\][\\])#\'*)
- if (( this_word & 256 )) && [[ $__arg = [\'\"]* ]]; then
- if [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]} ]]; then
- __idx=1
- _mybuf=$FAST_THEME_NAME
- FAST_THEME_NAME=${${${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]}:t:r}#(XDG|LOCAL|HOME|OPT):}
- (( ${+FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}default]} )) || source $FAST_WORK_DIR/secondary_theme.zsh
- else
- __idx=0
- fi
- -fast-highlight-process "$PREBUFFER" ${${__arg%[\'\"]}#[\'\"]} $(( _start_pos + 1 ))
- (( __idx )) && FAST_THEME_NAME=$_mybuf
- already_added=1
- else
- [[ $__arg = *([^\\][\#][\#]|"(#b)"|"(#B)"|"(#m)"|"(#c")* && $highlight_glob -ne 0 ]] && \
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}globbing-ext]}")
- # Reusing existing vars, treat this code like C++ STL
- # header, full of underscores and unhelpful var names
- itmp=0 __workbuf=$__arg __tmp="" cdpath_dir=$__arg
- while [[ $__workbuf = (#b)[^\"\'\\]#(([\"\'])|[\\](*))(*) ]]; do
- [[ -n ${match[3]} ]] && {
- itmp+=${mbegin[1]}
- # Optionally skip 1 quoted char
- [[ $__tmp = \' ]] && __workbuf=${match[3]} || { itmp+=1; __workbuf=${match[3]:1}; }
- } || {
- itmp+=${mbegin[1]}
- __workbuf=${match[4]}
- # Toggle quoting
- [[ ( ${match[1]} = \" && $__tmp != \' ) || ( ${match[1]} = \' && $__tmp != \" ) ]] && {
- [[ $__tmp = [\"\'] ]] && {
- # End of quoting
- (( __start=_start_pos-__PBUFLEN+iitmp-1, __end=_start_pos-__PBUFLEN+itmp, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}${${${__tmp#\'}:+double-quoted-argument}:-single-quoted-argument}]}")
- already_added=1
- [[ $__tmp = \" ]] && {
- __arg=${cdpath_dir[iitmp+1,itmp-1]}
- (( _start_pos += iitmp - 1 + 1 ))
- -fast-highlight-string
- (( _start_pos = _start_pos - iitmp + 1 - 1 ))
- }
- # The end-of-quoting proper algorithm action
- __tmp=
- } || {
- # Beginning of quoting
- iitmp=itmp
- # The beginning-of-quoting proper algorithm action
- __tmp=${match[1]}
- }
- }
- }
- done
- [[ $__tmp = [\"\'] ]] && {
- (( __start=_start_pos-__PBUFLEN+iitmp-1, __end=_start_pos-__PBUFLEN+__asize, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}${${${__tmp#\'}:+double-quoted-argument}:-single-quoted-argument}]}")
- already_added=1
- [[ $__tmp = \" ]] && {
- __arg=${cdpath_dir[iitmp+1,__asize]}
- (( _start_pos += iitmp - 1 + 1 ))
- -fast-highlight-string
- (( _start_pos = _start_pos - iitmp + 1 - 1 ))
- }
- }
- fi
- ;;
- \$\(\(*)
- already_added=1
- -fast-highlight-math-string
- # ADD
- (( __start=_start_pos-__PBUFLEN+1, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 9. $(( as argument
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- # ADD
- [[ $__arg[-2,-1] == '))' ]] && (( __start=_end_pos-__PBUFLEN-2, __end=__start+2, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}double-paren]}")
- # Counting complex brackets (for brackets-highlighter): 10. )) for as-argument $((
- _FAST_COMPLEX_BRACKETS+=( $__start $(( __start + 1 )) )
- ;;
- '`'*) __style=${FAST_THEME_NAME}back-quoted-argument;;
- '((') # 'F' - (( after for
- (( this_word & 32 )) && {
- braces_stack='F'$braces_stack
- __style=${FAST_THEME_NAME}double-paren
- # Counting complex brackets (for brackets-highlighter): 11. (( as for-syntax
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- # This is set after __arg_type == 2, and also here,
- # when another alternate-syntax capable command occurs
- __delimited=1
- }
- ;;
- '))') # 'F' - (( after for
- [[ $braces_stack = F* ]] && {
- braces_stack=${braces_stack#F}
- __style=${FAST_THEME_NAME}double-paren
- # Counting complex brackets (for brackets-highlighter): 12. )) as for-syntax
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) $(( _start_pos-__PBUFLEN+1 )) )
- (( __delimited = __delimited ? 2 : __delimited ))
- }
- ;;
- '<<<')
- (( next_word = (next_word | 128) & ~3 ))
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-tri]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-tri]}")
- already_added=1
- ;;
- *) # F - (( after for
- if [[ $braces_stack = F* ]]; then
- -fast-highlight-string
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^a-zA-Z\{\$]#([a-zA-Z][a-zA-Z0-9]#)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-variable]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^+\<\>=:\*\|\&\^\~-]#([+\<\>=:\*\|\&\^\~-]##)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-operator]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
- _mybuf=$__arg
- __idx=_start_pos
- while [[ $_mybuf = (#b)[^0-9]#([0-9]##)(*) ]]; do
- (( __start=__idx-__PBUFLEN+${mbegin[1]}-1, __end=__idx-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-number]}")
- __idx+=${mend[1]}
- _mybuf=${match[2]}
- done
- if [[ $__arg = (#b)[^\;]#(\;)[\ ]# ]]; then
- (( __start=_start_pos-__PBUFLEN+${mbegin[1]}-1, __end=_start_pos-__PBUFLEN+${mend[1]}+1-1, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}for-loop-separator]}")
- fi
- already_added=1
- elif [[ $__arg = *([^\\][\#][\#]|"(#b)"|"(#B)"|"(#m)"|"(#c")* ]]; then
- (( highlight_glob )) && __style=${FAST_THEME_NAME}globbing-ext || __style=${FAST_THEME_NAME}default
- elif [[ $__arg = ([*?]*|*[^\\][*?]*) ]]; then
- (( highlight_glob )) && __style=${FAST_THEME_NAME}globbing || __style=${FAST_THEME_NAME}default
- elif [[ $__arg = \$* ]]; then
- __style=${FAST_THEME_NAME}variable
- elif [[ $__arg = $'\x7d' && $braces_stack = Y* && ${FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]} = "1" ]]; then
- # right brace, i.e. $'\x7d' == '}'
- # Parsing rule: # {
- #
- # Additionally, `tt(})' is recognized in any position if neither the
- # tt(IGNORE_BRACES) option nor the tt(IGNORE_CLOSE_BRACES) option is set."""
- braces_stack=${braces_stack#Y}
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = next_word | 16 ))
- elif [[ $__arg = (';;'|';&'|';|') ]] && (( this_word & BIT_case_code )); then
- (( next_word = (next_word | BIT_case_item) & ~(BIT_case_code+3) ))
- __style=${FAST_THEME_NAME}default
- elif [[ $__arg = ${histchars[1]}* && -n ${__arg[2]} ]]; then
- __style=${FAST_THEME_NAME}history-expansion
- elif (( __arg_type == 3 )); then
- __style=${FAST_THEME_NAME}commandseparator
- elif (( in_redirection == 2 )); then
- __style=${FAST_THEME_NAME}redirection
- elif (( ${+galiases[(e)$__arg]} )); then
- __style=${FAST_THEME_NAME}global-alias
- else
- if [[ ${FAST_HIGHLIGHT[no_check_paths]} != 1 ]]; then
- if [[ ${FAST_HIGHLIGHT[use_async]} != 1 ]]; then
- if -fast-highlight-check-path noasync; then
- # ADD
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- already_added=1
- # TODO: path separators, optimize and add to async code-path
- [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]} && ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path]} != ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]} ]] && {
- for (( __pos = _start_pos; __pos <= _end_pos; __pos++ )) ; do
- # ADD
- [[ ${__buf[__pos]} == "/" ]] && (( __start=__pos-__PBUFLEN, __start >= 0 )) && reply+=("$(( __start - 1 )) $__start ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path_pathseparator]}")
- done
- }
- else
- __style=${FAST_THEME_NAME}default
- fi
- else
- if [[ -z ${FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]} || $(( EPOCHSECONDS - FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}-born-at] )) -gt 8 ]]; then
- if [[ $LASTWIDGET != *-or-beginning-search ]]; then
- exec {PCFD}< <(-fast-highlight-check-path; sleep 5)
- command sleep 0
- FAST_HIGHLIGHT[path-queue]+=";$_start_pos $_end_pos;"
- is-at-least 5.0.6 && __pos=1 || __pos=0
- zle -F ${${__pos:#0}:+-w} $PCFD fast-highlight-check-path-handler
- already_added=1
- else
- __style=${FAST_THEME_NAME}default
- fi
- elif [[ ${FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]%D} -eq 1 ]]; then
- (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path${${(M)FAST_HIGHLIGHT[cache-path-${(q)__arg}-${_start_pos}]%D}:+-to-dir}]}")
- already_added=1
- else
- __style=${FAST_THEME_NAME}default
- fi
- fi
- else
- __style=${FAST_THEME_NAME}default
- fi
- fi
- ;;
- esac
- elif (( this_word & 128 ))
- then
- (( next_word = (next_word | 2) & ~129 ))
- [[ ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-text]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-text]}")
- -fast-highlight-string ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}here-string-var]:#none}
- already_added=1
- elif (( this_word & (BIT_case_preamble + BIT_case_item) ))
- then
- if (( this_word & BIT_case_preamble )); then
- [[ $__arg = "in" ]] && {
- __style=${FAST_THEME_NAME}reserved-word
- (( next_word = BIT_case_item ))
- } || {
- __style=${FAST_THEME_NAME}case-input
- (( next_word = BIT_case_preamble ))
- }
- else
- if (( this_word & BIT_case_nempty_item == 0 )) && [[ $__arg = "esac" ]]; then
- (( next_word = 1 ))
- __style=${FAST_THEME_NAME}reserved-word
- elif [[ $__arg = [\)\(] ]]; then
- __style=${FAST_THEME_NAME}case-parentheses
- [[ $__arg = \) ]] && (( next_word = BIT_case_code | 1 )) || (( next_word = BIT_case_item | BIT_case_nempty_item ))
- _FAST_COMPLEX_BRACKETS+=( $(( _start_pos-__PBUFLEN )) )
- else
- (( next_word = BIT_case_item | BIT_case_nempty_item ))
- __style=${FAST_THEME_NAME}case-condition
- fi
- fi
- fi
- # ADD
- (( already_added == 0 )) && [[ ${FAST_HIGHLIGHT_STYLES[$__style]} != "none" ]] && (( __start=_start_pos-__PBUFLEN, __end=_end_pos-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- if (( (__arg_type == 3) && ((this_word & (BIT_case_preamble|BIT_case_item)) == 0) )); then
- if [[ $__arg == ';' ]] && (( in_array_assignment )); then
- # literal newline inside an array assignment
- (( next_word = 2 | (next_word & BIT_case_code) ))
- elif [[ -n ${braces_stack[(r)A]} ]]; then
- # 'A' in stack -> inside [[ ... ]]
- (( next_word = 2 | (next_word & BIT_case_code) ))
- else
- braces_stack=${braces_stack#T}
- (( next_word = 1 | (next_word & BIT_case_code) ))
- highlight_glob=1
- # A new command means that we should not expect that alternate
- # syntax will occur (this is also in the ';' short-path), but
- # || and && mean going down just 1 step, not all the way to 0
- [[ $__arg != ("||"|"&&") ]] && __delimited=0 || (( __delimited = __delimited == 2 ? 1 : __delimited ))
- fi
- elif (( ( (__arg_type == 1) || (__arg_type == 2) ) && (this_word & 1) )); then # (( __arg_type == 1 || __arg_type == 2 )) && (( this_word & 1 ))
- __delimited=1
- (( next_word = 1 | (next_word & (64 | BIT_case_code)) ))
- elif [[ $__arg == "repeat" ]] && (( this_word & 1 )); then
- __delimited=1
- # skip the repeat-count word
- in_redirection=2
- # The redirection mechanism assumes $this_word describes the word
- # following the redirection. Make it so.
- #
- # That word can be a command word with shortloops (`repeat 2 ls`)
- # or a command separator (`repeat 2; ls` or `repeat 2; do ls; done`).
- #
- # The repeat-count word will be handled like a redirection target.
- (( this_word = 3 ))
- fi
- _start_pos=$_end_pos
- # This is the default/common codepath.
- (( this_word = in_redirection == 0 ? next_word : this_word )) #else # Stall $this_word.
- done
- # Do we have whole buffer? I.e. start at zero
- [[ $3 != 0 ]] && return 0
- # The loop overwrites ")" with "x", except those from $( ) substitution
- #
- # __pos: current nest level, starts from 0
- # __workbuf: copy of __buf, with limit on 250 characters
- # __idx: index in whole command line buffer
- # __list: list of coordinates of ) which shouldn't be ovewritten
- _mybuf=${__buf[1,250]} __workbuf=$_mybuf __idx=0 __pos=0 __list=()
- while [[ $__workbuf = (#b)[^\(\)]#([\(\)])(*) ]]; do
- if [[ ${match[1]} == \( ]]; then
- __arg=${_mybuf[__idx+${mbegin[1]}-1,__idx+${mbegin[1]}-1+2]}
- [[ $__arg = '$('[^\(] ]] && __list+=( $__pos )
- [[ $__arg = '$((' ]] && _mybuf[__idx+${mbegin[1]}-1]=x
- # Increase parenthesis level
- __pos+=1
- else
- # Decrease parenthesis level
- __pos=__pos-1
- [[ -z ${__list[(r)$__pos]} ]] && [[ $__pos -gt 0 ]] && _mybuf[__idx+${mbegin[1]}]=x
- fi
- __idx+=${mbegin[2]}-1
- __workbuf=${match[2]}
- done
- # Run on fake buffer with replaced parentheses: ")" into "x"
- __inputs=( ${(0)${(S)_mybuf//(#b)*\$\(([^\)]#)(\)|(#e))/${mbegin[1]};${mend[1]}${__nul}}%$__nul*} )
- if [[ ${__inputs[1]} != $_mybuf ]]; then
- if [[ -n ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]} ]]; then
- __idx=1
- __tmp=$FAST_THEME_NAME
- FAST_THEME_NAME=${${${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}secondary]}:t:r}#(XDG|LOCAL|HOME|OPT):}
- (( ${+FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}default]} )) || source $FAST_WORK_DIR/secondary_theme.zsh
- else
- __idx=0
- fi
- for _mybuf in $__inputs; do
- # Pass authentic buffer for recursive analysis
- -fast-highlight-process "$PREBUFFER" ${__buf[${_mybuf%%;*},${_mybuf##*;}]} $(( ${_mybuf%%;*} - 1 ))
- done
- # Restore theme
- (( __idx )) && FAST_THEME_NAME=$__tmp
- fi
- return 0
- }
- -fast-highlight-check-path()
- {
- [[ $1 != "noasync" ]] && {
- print -r -- ${sysparams[pid]}
- # This is to fill cache
- print -r -- $__arg
- }
- : ${expanded_path:=${(Q)~__arg}}
- [[ -n ${FAST_BLIST_PATTERNS[(k)${${(M)expanded_path:#/*}:-$PWD/$expanded_path}]} ]] && { [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"; return 1; }
- [[ -z $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"; return 1; }
- [[ -d $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos ${_end_pos}D" || __style=${FAST_THEME_NAME}path-to-dir; return 0; }
- [[ -e $expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos $_end_pos" || __style=${FAST_THEME_NAME}path; return 0; }
- # Search the path in CDPATH, only for CD command
- [[ $active_command = "cd" ]] && for cdpath_dir in $cdpath; do
- [[ -d $cdpath_dir/$expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos ${_end_pos}D" || __style=${FAST_THEME_NAME}path-to-dir; return 0; }
- [[ -e $cdpath_dir/$expanded_path ]] && { [[ $1 != "noasync" ]] && print -r -- "$_start_pos $_end_pos" || __style=${FAST_THEME_NAME}path; return 0; }
- done
- # It's not a path.
- [[ $1 != "noasync" ]] && print -r -- "- $_start_pos $_end_pos"
- return 1
- }
- -fast-highlight-check-path-handler() {
- local IFS=$'\n' pid PCFD=$1 line stripped val
- integer idx
- if read -r -u $PCFD pid; then
- if read -r -u $PCFD val; then
- if read -r -u $PCFD line; then
- stripped=${${line#- }%D}
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}-born-at]=$EPOCHSECONDS
- idx=${${FAST_HIGHLIGHT[path-queue]}[(I)$stripped]}
- (( idx > 0 )) && {
- if [[ $line != -* ]]; then
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]="1${(M)line%D}"
- region_highlight+=("${line%% *} ${${line##* }%D} ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}path${${(M)line%D}:+-to-dir}]}")
- else
- FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]=0
- fi
- val=${FAST_HIGHLIGHT[path-queue]}
- val[idx-1,idx+${#stripped}]=""
- FAST_HIGHLIGHT[path-queue]=$val
- [[ ${FAST_HIGHLIGHT[cache-path-${(q)val}-${stripped%% *}]%D} = 1 && ${#val} -le 27 ]] && zle .redisplay
- }
- fi
- fi
- kill -9 $pid 2>/dev/null
- fi
- zle -F -w ${PCFD}
- exec {PCFD}<&-
- }
- zle -N -- fast-highlight-check-path-handler -fast-highlight-check-path-handler
- # Highlight special blocks inside double-quoted strings
- #
- # The while [[ ... ]] pattern is logically ((A)|(B)|(C)|(D)|(E))(*), where:
- # - A matches $var[abc]
- # - B matches ${(...)var[abc]}
- # - C matches $
- # - D matches \$ or \" or \'
- # - E matches \*
- #
- # and the first condition -n ${match[7] uses D to continue searching when
- # backslash-something (not ['"$]) is occured.
- #
- # $1 - additional style to glue-in to added style
- -fast-highlight-string()
- {
- _mybuf=$__arg
- __idx=_start_pos
- # 7 8
- while [[ $_mybuf = (#b)[^\$\\]#((\$(#B)([#+^=~](#c1,2))(#c0,1)(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]#\])(#c0,1))|(\$[{](#B)([#+^=~](#c1,2))(#c0,1)(#b)(\([a-zA-Z0-9_:@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]#\])(#c0,1)[}])|\$|[\\][\'\"\$]|[\\](*))(*) ]]; do
- [[ -n ${match[7]} ]] && {
- # Skip following char – it is quoted. Choice is
- # made to not highlight such quoting
- __idx+=${mbegin[1]}+1
- _mybuf=${match[7]:1}
- } || {
- __idx+=${mbegin[1]}-1
- _end_idx=__idx+${mend[1]}-${mbegin[1]}+1
- _mybuf=${match[8]}
- # ADD
- (( __start=__idx-__PBUFLEN, __end=_end_idx-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${${1:+$1}:-${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}back-or-dollar-double-quoted-argument]}}")
- __idx=_end_idx
- }
- done
- return 0
- }
- # Highlight math and non-math context variables inside $(( )) and (( ))
- #
- # The while [[ ... ]] pattern is logically ((A)|(B)|(C)|(D))(*), where:
- # - A matches $var[abc]
- # - B matches ${(...)var[abc]}
- # - C matches $
- # - D matches words [a-zA-Z]## (variables)
- #
- # Parameters used: _mybuf, __idx, _end_idx, __style
- -fast-highlight-math-string()
- {
- _mybuf=$__arg
- __idx=_start_pos
- # 7
- while [[ $_mybuf = (#b)[^\$_a-zA-Z0-9]#((\$(#B)(+|)(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]##\])(#c0,1))|(\$[{](#B)(+|)(#b)(\([a-zA-Z0-9_:@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]##\])(#c0,1)[}])|\$|[a-zA-Z_][a-zA-Z0-9_]#|[0-9]##)(*) ]]; do
- __idx+=${mbegin[1]}-1
- _end_idx=__idx+${mend[1]}-${mbegin[1]}+1
- _mybuf=${match[7]}
- [[ ${match[1]} = [0-9]* ]] && __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}mathnum]} || {
- [[ ${match[1]} = [a-zA-Z_]* ]] && {
- [[ -n ${(P)match[1]} || ${FAST_ASSIGNS_SEEN[${match[1]}]} = 1 ]] && __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}mathvar]} || __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}matherr]}
- } || {
- [[ ${match[1]} = "$"* ]] && {
- match[1]=${match[1]//[\{\}\+]/}
- [[ ${match[1]} = "$" || -n ${(P)${match[1]:1}} || ${FAST_ASSIGNS_SEEN[${match[1]:1}]} = 1 ]] && __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}back-or-dollar-double-quoted-argument]} || __style=${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}matherr]}
- }
- }
- }
- # ADD
- [[ $__style != "none" && -n $__style ]] && (( __start=__idx-__PBUFLEN, __end=_end_idx-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end $__style")
- __idx=_end_idx
- done
- }
- # Highlight special chars inside dollar-quoted strings
- -fast-highlight-dollar-string()
- {
- local i j k __style
- local AA
- integer c
- # Starting dollar-quote is at 1:2, so __start parsing at offset 3 in the string.
- for (( i = 3 ; i < _end_pos - _start_pos ; i += 1 )) ; do
- (( j = i + _start_pos - 1 ))
- (( k = j + 1 ))
- case ${__arg[$i]} in
- "\\") __style=${FAST_THEME_NAME}back-dollar-quoted-argument
- for (( c = i + 1 ; c <= _end_pos - _start_pos ; c += 1 )); do
- [[ ${__arg[$c]} != ([0-9xXuUa-fA-F]) ]] && break
- done
- AA=$__arg[$i+1,$c-1]
- # Matching for HEX and OCT values like \0xA6, \xA6 or \012
- if [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}"
- || "$AA" =~ "^[0-7]{1,3}"
- || "$AA" =~ "^u[0-9a-fA-F]{1,4}"
- || "$AA" =~ "^U[0-9a-fA-F]{1,8}"
- ]]; then
- (( k += $#MATCH ))
- (( i += $#MATCH ))
- else
- if (( __asize > i+1 )) && [[ $__arg[i+1] == [xXuU] ]]; then
- # \x not followed by hex digits is probably an error
- __style=${FAST_THEME_NAME}unknown-token
- fi
- (( k += 1 )) # Color following char too.
- (( i += 1 )) # Skip parsing the escaped char.
- fi
- ;;
- *) continue ;;
- esac
- # ADD
- (( __start=j-__PBUFLEN, __end=k-__PBUFLEN, __start >= 0 )) && reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- done
- }
- -fast-highlight-init() {
- _FAST_COMPLEX_BRACKETS=()
- __fast_highlight_main__command_type_cache=()
- }
- typeset -ga FSH_LIST
- -fsh_sy_h_shappend() {
- FSH_LIST+=( "$(( $1 - 1 ));;$(( $2 ))" )
- }
- functions -M fsh_sy_h_append 2 2 -fsh_sy_h_shappend 2>/dev/null
- # vim:ft=zsh:sw=2:sts=2
- # $1 - PREBUFFER
- # $2 - BUFFER
- #
- function -fast-highlight-string-process {
- local -A pos_to_level level_to_pos pair_map final_pairs
- local input=$1$2 _mybuf=$1$2 __style __quoting
- integer __idx=0 __pair_idx __level=0 __start __end
- local -a match mbegin mend
- pair_map=( "(" ")" "{" "}" "[" "]" )
- while [[ $_mybuf = (#b)[^"{}()[]\\\"'"]#((["({[]})\"'"])|[\\](*))(*) ]]; do
- [[ -n ${match[3]} ]] && {
- __idx+=${mbegin[1]}
- [[ $__quoting = \' ]] && _mybuf=${match[3]} || { _mybuf=${match[3]:1}; (( ++ __idx )); }
- } || {
- __idx+=${mbegin[1]}
- [[ -z $__quoting && -z ${_FAST_COMPLEX_BRACKETS[(r)$((__idx-${#PREBUFFER}-1))]} ]] && {
- if [[ ${match[1]} = ["({["] ]]; then
- pos_to_level[$__idx]=$(( ++__level ))
- level_to_pos[$__level]=$__idx
- elif [[ ${match[1]} = ["]})"] ]]; then
- if (( __level > 0 )); then
- __pair_idx=${level_to_pos[$__level]}
- pos_to_level[$__idx]=$(( __level -- ))
- [[ ${pair_map[${input[__pair_idx]}]} = ${input[__idx]} ]] && {
- final_pairs[$__idx]=$__pair_idx
- final_pairs[$__pair_idx]=$__idx
- }
- else
- pos_to_level[$__idx]=-1
- fi
- fi
- }
- [[ ${match[1]} = \" && $__quoting != \' ]] && { [[ $__quoting = '"' ]] && __quoting="" || __quoting='"'; }
- [[ ${match[1]} = \' && $__quoting != \" ]] && { [[ $__quoting = "'" ]] && __quoting="" || __quoting="'"; }
- _mybuf=${match[4]}
- }
- done
- for __idx in ${(k)pos_to_level}; do
- (( ${+final_pairs[$__idx]} )) && __style=${FAST_THEME_NAME}bracket-level-$(( ( (pos_to_level[$__idx]-1) % 3 ) + 1 )) || __style=${FAST_THEME_NAME}unknown-token
- (( __start=__idx-${#PREBUFFER}-1, __end=__idx-${#PREBUFFER}, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[$__style]}")
- done
- # If cursor is on a bracket, then highlight corresponding bracket, if any.
- if [[ $WIDGET != zle-line-finish ]]; then
- __idx=$(( CURSOR + 1 ))
- if (( ${+pos_to_level[$__idx]} )) && (( ${+final_pairs[$__idx]} )); then
- (( __start=final_pairs[$__idx]-${#PREBUFFER}-1, __end=final_pairs[$__idx]-${#PREBUFFER}, __start >= 0 )) && \
- reply+=("$__start $__end ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}paired-bracket]}") && \
- reply+=("$CURSOR $__idx ${FAST_HIGHLIGHT_STYLES[${FAST_THEME_NAME}paired-bracket]}")
- fi
- fi
- return 0
- }
- # Standarized way of handling finding plugin dir,
- # regardless of functionargzero and posixargzero,
- # and with an option for a plugin manager to alter
- # the plugin directory (i.e. set ZERO parameter)
- # http://zdharma.org/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
- 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
- typeset -g FAST_BASE_DIR="${0:h}"
- typeset -ga _FAST_MAIN_CACHE
- # Holds list of indices pointing at brackets that
- # are complex, i.e. e.g. part of "[[" in [[ ... ]]
- typeset -ga _FAST_COMPLEX_BRACKETS
- typeset -g FAST_WORK_DIR
- : ${FAST_WORK_DIR:=$FAST_BASE_DIR}
- FAST_WORK_DIR=${~FAST_WORK_DIR}
- if [[ -z "$ZPLG_CUR_PLUGIN" && "${fpath[(r)$FAST_BASE_DIR]}" != $FAST_BASE_DIR ]]; then
- fpath+=( "$FAST_BASE_DIR" )
- fi
- if [[ "$FAST_WORK_DIR" = /usr/* || ( "$FAST_WORK_DIR" = /opt/* && ! -w "$FAST_WORK_DIR" ) ]]; then
- FAST_WORK_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/fsh"
- command mkdir -p "$FAST_WORK_DIR"
- fi
- # Invokes each highlighter that needs updating.
- # This function is supposed to be called whenever the ZLE state changes.
- _zsh_highlight()
- {
- # Store the previous command return code to restore it whatever happens.
- local ret=$?
- # Remove all highlighting in isearch, so that only the underlining done by zsh itself remains.
- # For details see FAQ entry 'Why does syntax highlighting not work while searching history?'.
- if [[ $WIDGET == zle-isearch-update ]] && ! (( $+ISEARCHMATCH_ACTIVE )); then
- region_highlight=()
- return $ret
- fi
- setopt localoptions warncreateglobal noksharrays noshwordsplit extendedglob typesetsilent nokshglob
- local REPLY # don't leak $REPLY into global scope
- local -a reply
- # Do not highlight if there are more than 300 chars in the buffer. It's most
- # likely a pasted command or a huge list of files in that case..
- [[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return $ret
- # Do not highlight if there are pending inputs (copy/paste).
- [[ $PENDING -gt 0 ]] && return $ret
- # Reset region highlight to build it from scratch
- # may need to remove path_prefix highlighting when the line ends
- if [[ $WIDGET == zle-line-finish ]] || _zsh_highlight_buffer_modified; then
- -fast-highlight-init
- -fast-highlight-process "$PREBUFFER" "$BUFFER" 0
- (( FAST_HIGHLIGHT[use_brackets] )) && {
- _FAST_MAIN_CACHE=( $reply )
- -fast-highlight-string-process "$PREBUFFER" "$BUFFER"
- }
- region_highlight=( $reply )
- else
- local char="${BUFFER[CURSOR+1]}"
- if [[ "$char" = ["{([])}"] || "${FAST_HIGHLIGHT[prev_char]}" = ["{([])}"] ]]; then
- FAST_HIGHLIGHT[prev_char]="$char"
- (( FAST_HIGHLIGHT[use_brackets] )) && {
- reply=( $_FAST_MAIN_CACHE )
- -fast-highlight-string-process "$PREBUFFER" "$BUFFER"
- region_highlight=( $reply )
- }
- fi
- fi
- {
- local cache_place
- local -a region_highlight_copy
- # Re-apply zle_highlight settings
- # region
- if (( REGION_ACTIVE == 1 )); then
- _zsh_highlight_apply_zle_highlight region standout "$MARK" "$CURSOR"
- elif (( REGION_ACTIVE == 2 )); then
- () {
- local needle=$'\n'
- integer min max
- if (( MARK > CURSOR )) ; then
- min=$CURSOR max=$MARK
- else
- min=$MARK max=$CURSOR
- fi
- (( min = ${${BUFFER[1,$min]}[(I)$needle]} ))
- (( max += ${${BUFFER:($max-1)}[(i)$needle]} - 1 ))
- _zsh_highlight_apply_zle_highlight region standout "$min" "$max"
- }
- fi
- # yank / paste (zsh-5.1.1 and newer)
- (( $+YANK_ACTIVE )) && (( YANK_ACTIVE )) && _zsh_highlight_apply_zle_highlight paste standout "$YANK_START" "$YANK_END"
- # isearch
- (( $+ISEARCHMATCH_ACTIVE )) && (( ISEARCHMATCH_ACTIVE )) && _zsh_highlight_apply_zle_highlight isearch underline "$ISEARCHMATCH_START" "$ISEARCHMATCH_END"
- # suffix
- (( $+SUFFIX_ACTIVE )) && (( SUFFIX_ACTIVE )) && _zsh_highlight_apply_zle_highlight suffix bold "$SUFFIX_START" "$SUFFIX_END"
- return $ret
- } always {
- typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER="$BUFFER"
- typeset -g _ZSH_HIGHLIGHT_PRIOR_RACTIVE="$REGION_ACTIVE"
- typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=$CURSOR
- }
- }
- # Apply highlighting based on entries in the zle_highlight array.
- # This function takes four arguments:
- # 1. The exact entry (no patterns) in the zle_highlight array:
- # region, paste, isearch, or suffix
- # 2. The default highlighting that should be applied if the entry is unset
- # 3. and 4. Two integer values describing the beginning and end of the
- # range. The order does not matter.
- _zsh_highlight_apply_zle_highlight() {
- local entry="$1" default="$2"
- integer first="$3" second="$4"
- # read the relevant entry from zle_highlight
- local region="${zle_highlight[(r)${entry}:*]}"
- if [[ -z "$region" ]]; then
- # entry not specified at all, use default value
- region=$default
- else
- # strip prefix
- region="${region#${entry}:}"
- # no highlighting when set to the empty string or to 'none'
- if [[ -z "$region" ]] || [[ "$region" == none ]]; then
- return
- fi
- fi
- integer start end
- if (( first < second )); then
- start=$first end=$second
- else
- start=$second end=$first
- fi
- region_highlight+=("$start $end $region")
- }
- # -------------------------------------------------------------------------------------------------
- # API/utility functions for highlighters
- # -------------------------------------------------------------------------------------------------
- # Whether the command line buffer has been modified or not.
- #
- # Returns 0 if the buffer has changed since _zsh_highlight was last called.
- _zsh_highlight_buffer_modified()
- {
- [[ "${_ZSH_HIGHLIGHT_PRIOR_BUFFER:-}" != "$BUFFER" ]] || [[ "$REGION_ACTIVE" != "$_ZSH_HIGHLIGHT_PRIOR_RACTIVE" ]] || { _zsh_highlight_cursor_moved && [[ "$REGION_ACTIVE" = 1 || "$REGION_ACTIVE" = 2 ]] }
- }
- # Whether the cursor has moved or not.
- #
- # Returns 0 if the cursor has moved since _zsh_highlight was last called.
- _zsh_highlight_cursor_moved()
- {
- [[ -n $CURSOR ]] && [[ -n ${_ZSH_HIGHLIGHT_PRIOR_CURSOR-} ]] && (($_ZSH_HIGHLIGHT_PRIOR_CURSOR != $CURSOR))
- }
- # -------------------------------------------------------------------------------------------------
- # Setup functions
- # -------------------------------------------------------------------------------------------------
- # Helper for _zsh_highlight_bind_widgets
- # $1 is name of widget to call
- _zsh_highlight_call_widget()
- {
- builtin zle "$@" && _zsh_highlight
- }
- # Rebind all ZLE widgets to make them invoke _zsh_highlights.
- _zsh_highlight_bind_widgets()
- {
- setopt localoptions noksharrays
- typeset -F SECONDS
- local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once
- # Load ZSH module zsh/zleparameter, needed to override user defined widgets.
- zmodload zsh/zleparameter 2>/dev/null || {
- print -r -- >&2 'zsh-syntax-highlighting: failed loading zsh/zleparameter.'
- return 1
- }
- # Override ZLE widgets to make them invoke _zsh_highlight.
- local -U widgets_to_bind
- widgets_to_bind=(${${(k)widgets}:#(.*|run-help|which-command|beep|set-local-history|yank)})
- # Always wrap special zle-line-finish widget. This is needed to decide if the
- # current line ends and special highlighting logic needs to be applied.
- # E.g. remove cursor imprint, don't highlight partial paths, ...
- widgets_to_bind+=(zle-line-finish)
- # Always wrap special zle-isearch-update widget to be notified of updates in isearch.
- # This is needed because we need to disable highlighting in that case.
- widgets_to_bind+=(zle-isearch-update)
- local cur_widget
- for cur_widget in $widgets_to_bind; do
- case $widgets[$cur_widget] in
- # Already rebound event: do nothing.
- user:_zsh_highlight_widget_*);;
- # The "eval"'s are required to make $cur_widget a closure: the value of the parameter at function
- # definition time is used.
- #
- # We can't use ${0/_zsh_highlight_widget_} because these widgets are always invoked with
- # NO_function_argzero, regardless of the option's setting here.
- # User defined widget: override and rebind old one with prefix "orig-".
- user:*) zle -N $prefix-$cur_widget ${widgets[$cur_widget]#*:}
- eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }"
- zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;;
- # Completion widget: override and rebind old one with prefix "orig-".
- completion:*) zle -C $prefix-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]}
- eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }"
- zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;;
- # Builtin widget: override and make it call the builtin ".widget".
- builtin) eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget .${(q)cur_widget} -- \"\$@\" }"
- zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;;
- # Incomplete or nonexistent widget: Bind to z-sy-h directly.
- *)
- if [[ $cur_widget == zle-* ]] && [[ -z $widgets[$cur_widget] ]]; then
- _zsh_highlight_widget_${cur_widget}() { :; _zsh_highlight }
- zle -N $cur_widget _zsh_highlight_widget_$cur_widget
- else
- # Default: unhandled case.
- print -r -- >&2 "zsh-syntax-highlighting: unhandled ZLE widget ${(qq)cur_widget}"
- fi
- esac
- done
- }
- # -------------------------------------------------------------------------------------------------
- # Setup
- # -------------------------------------------------------------------------------------------------
- # Try binding widgets.
- _zsh_highlight_bind_widgets || {
- print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.'
- return 1
- }
- # Reset scratch variables when commandline is done.
- _zsh_highlight_preexec_hook()
- {
- typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER=
- typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=0
- typeset -ga _FAST_MAIN_CACHE
- _FAST_MAIN_CACHE=()
- }
- autoload -Uz add-zsh-hook
- add-zsh-hook preexec _zsh_highlight_preexec_hook 2>/dev/null || {
- print -r -- >&2 'zsh-syntax-highlighting: failed loading add-zsh-hook.'
- }
- ZSH_HIGHLIGHT_MAXLENGTH=10000
- # Load zsh/parameter module if available
- zmodload zsh/parameter 2>/dev/null
- zmodload zsh/system 2>/dev/null
- autoload -Uz -- is-at-least fast-theme fast-read-ini-file -fast-run-git-command -fast-make-targets \
- -fast-run-command
- autoload -Uz -- chroma/-git.ch chroma/-example.ch chroma/-grep.ch chroma/-perl.ch chroma/-make.ch \
- chroma/-awk.ch chroma/-vim.ch chroma/-source.ch chroma/-sh.ch chroma/-docker.ch \
- chroma/-autoload.ch chroma/-ssh.ch chroma/-scp.ch chroma/-which.ch chroma/-printf.ch \
- chroma/-ruby.ch chroma/-whatis.ch chroma/-alias.ch chroma/-subcommand.ch \
- chroma/-autorandr.ch chroma/-nmcli.ch chroma/-fast-theme.ch chroma/-node.ch \
- chroma/-fpath_peq.ch
- local __fsyh_theme
- zstyle -s :plugin:fast-syntax-highlighting theme __fsyh_theme
- [[ "${+termcap[Co]}" != 1 || "${termcap[Co]}" != "256" ]] && \
- [[ "${FAST_HIGHLIGHT_STYLES[variable]}" = "fg=113" && "$__fsyh_theme" = default ]] && \
- FAST_HIGHLIGHT_STYLES[variable]="none"
- unset __fsyh_theme
- alias fsh-alias=fast-theme
- -fast-highlight-fill-option-variables
- #====================================================================================================================#
- ## Auto Suggestions ##
- #--------------------------------------------------------------------#
- # Setup #
- #--------------------------------------------------------------------#
- # Precmd hooks for initializing the library and starting pty's
- autoload -Uz add-zsh-hook
- # Asynchronous suggestions are generated in a pty
- zmodload zsh/zpty
- #--------------------------------------------------------------------#
- # 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='fg=8'
- # Prefix to use when saving original versions of bound widgets
- ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig-
- ZSH_AUTOSUGGEST_STRATEGY=default
- # Widgets that clear the suggestion
- 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
- )
- # Widgets that accept the entire suggestion
- 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=(
- )
- # Widgets that accept the suggestion as far as the cursor moves
- 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=(
- orig-\*
- beep
- run-help
- set-local-history
- which-command
- yank
- yank-pop
- )
- # Max size of buffer to trigger autosuggestion. Leave undefined for no upper bound.
- ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=
- # Pty name for calculating autosuggestions asynchronously
- ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=zsh_autosuggest_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}"
- }
- #--------------------------------------------------------------------#
- # Feature Detection #
- #--------------------------------------------------------------------#
- _zsh_autosuggest_feature_detect_zpty_returns_fd() {
- typeset -g _ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD
- typeset -h REPLY
- zpty zsh_autosuggest_feature_detect '{ zshexit() { kill -KILL $$; sleep 1 } }'
- if (( REPLY )); then
- _ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD=1
- else
- _ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD=0
- fi
- zpty -d zsh_autosuggest_feature_detect
- }
- #--------------------------------------------------------------------#
- # Widget Helpers #
- #--------------------------------------------------------------------#
- _zsh_autosuggest_incr_bind_count() {
- if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
- ((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]++))
- else
- _ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=1
- fi
- typeset -gi bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
- }
- _zsh_autosuggest_get_bind_count() {
- if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
- typeset -gi bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
- else
- typeset -gi bind_count=0
- fi
- }
- # 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)_*);;
- # 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
- _zsh_autosuggest_get_bind_count $widget
- # 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() {
- local widget
- local ignore_widgets
- ignore_widgets=(
- .\*
- _\*
- zle-\*
- 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 [[ -n "${_ZSH_AUTOSUGGEST_DISABLED+x}" ]]; 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=$?
- # 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
- if (( $#BUFFER > $#orig_buffer )); then
- local added=${BUFFER#$orig_buffer}
- # If the string added matches the beginning of the postdisplay
- if [[ "$added" = "${orig_postdisplay:0:$#added}" ]]; then
- POSTDISPLAY="${orig_postdisplay:$#added}"
- return $retval
- fi
- fi
- # Don't fetch a new suggestion if the buffer hasn't changed
- if [[ "$BUFFER" = "$orig_buffer" ]]; then
- POSTDISPLAY="$orig_postdisplay"
- return $retval
- fi
- # Bail out if suggestions are disabled
- if [[ -n "${_ZSH_AUTOSUGGEST_DISABLED+x}" ]]; 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 zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then
- _zsh_autosuggest_async_request "$BUFFER"
- else
- local suggestion
- _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$BUFFER"
- _zsh_autosuggest_suggest "$suggestion"
- fi
- }
- # Offer a suggestion
- _zsh_autosuggest_suggest() {
- local suggestion="$1"
- if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
- POSTDISPLAY="${suggestion#$BUFFER}"
- else
- unset POSTDISPLAY
- fi
- }
- # Accept the entire suggestion
- _zsh_autosuggest_accept() {
- local -i 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
- # Only accept if the cursor is at the end of the buffer
- if [[ $CURSOR = $max_cursor_pos ]]; then
- # Add the suggestion to the buffer
- BUFFER="$BUFFER$POSTDISPLAY"
- # Remove the suggestion
- unset POSTDISPLAY
- # Move the cursor to the end of the buffer
- CURSOR=${#BUFFER}
- fi
- _zsh_autosuggest_invoke_original_widget $@
- }
- # 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
- }
- for action in clear modify fetch suggest accept partial_accept execute enable disable toggle; 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
- zle -N autosuggest-fetch _zsh_autosuggest_widget_fetch
- zle -N autosuggest-suggest _zsh_autosuggest_widget_suggest
- zle -N autosuggest-accept _zsh_autosuggest_widget_accept
- zle -N autosuggest-clear _zsh_autosuggest_widget_clear
- zle -N autosuggest-execute _zsh_autosuggest_widget_execute
- zle -N autosuggest-enable _zsh_autosuggest_widget_enable
- zle -N autosuggest-disable _zsh_autosuggest_widget_disable
- zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
- #--------------------------------------------------------------------#
- # Default Suggestion Strategy #
- #--------------------------------------------------------------------#
- # Suggests the most recent history item that matches the given
- # prefix.
- #
- _zsh_autosuggest_strategy_default() {
- # Reset options to defaults and enable LOCAL_OPTIONS
- emulate -L zsh
- # Enable globbing flags so that we can use (#m)
- 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
- # - (r) subscript flag makes the pattern match on values
- typeset -g suggestion="${history[(r)${prefix}*]}"
- }
- #--------------------------------------------------------------------#
- # 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)
- 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 all history event numbers that correspond to history
- # entries that match pattern $prefix*
- local history_match_keys
- history_match_keys=(${(k)history[(R)$prefix*]})
- # 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]"
- }
- #--------------------------------------------------------------------#
- # Async #
- #--------------------------------------------------------------------#
- # Zpty process is spawned running this function
- _zsh_autosuggest_async_server() {
- emulate -R zsh
- # There is a bug in zpty module (fixed in zsh/master) 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.
- zshexit() {
- kill -KILL $$
- sleep 1 # Block for long enough for the signal to come through
- }
- # Output only newlines (not carriage return + newline)
- stty -onlcr
- # Silence any error messages
- exec 2>/dev/null
- local last_pid
- while IFS='' read -r -d $'\0' query; do
- # Kill last bg process
- kill -KILL $last_pid &>/dev/null
- # Run suggestion search in the background
- (
- local suggestion
- _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query"
- echo -n -E "$suggestion"$'\0'
- ) &
- last_pid=$!
- done
- }
- _zsh_autosuggest_async_request() {
- # Write the query to the zpty process to fetch a suggestion
- zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\0'
- }
- # Called when new data is ready to be read from the pty
- # First arg will be fd ready for reading
- # Second arg will be passed in case of error
- _zsh_autosuggest_async_response() {
- setopt LOCAL_OPTIONS EXTENDED_GLOB
- local suggestion
- zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME suggestion '*'$'\0' 2>/dev/null
- zle autosuggest-suggest -- "${suggestion%%$'\0'##}"
- }
- _zsh_autosuggest_async_pty_create() {
- # With newer versions of zsh, REPLY stores the fd to read from
- typeset -h REPLY
- # If we won't get a fd back from zpty, try to guess it
- if (( ! $_ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD )); then
- integer -l zptyfd
- exec {zptyfd}>&1 # Open a new file descriptor (above 10).
- exec {zptyfd}>&- # Close it so it's free to be used by zpty.
- fi
- # Fork a zpty process running the server function
- zpty -b $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME _zsh_autosuggest_async_server
- # Store the fd so we can remove the handler later
- if (( REPLY )); then
- _ZSH_AUTOSUGGEST_PTY_FD=$REPLY
- else
- _ZSH_AUTOSUGGEST_PTY_FD=$zptyfd
- fi
- # Set up input handler from the zpty
- zle -F $_ZSH_AUTOSUGGEST_PTY_FD _zsh_autosuggest_async_response
- }
- _zsh_autosuggest_async_pty_destroy() {
- # Remove the input handler
- zle -F $_ZSH_AUTOSUGGEST_PTY_FD &>/dev/null
- # Destroy the zpty
- zpty -d $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME &>/dev/null
- }
- _zsh_autosuggest_async_pty_recreate() {
- _zsh_autosuggest_async_pty_destroy
- _zsh_autosuggest_async_pty_create
- }
- _zsh_autosuggest_async_start() {
- typeset -g _ZSH_AUTOSUGGEST_PTY_FD
- _zsh_autosuggest_feature_detect_zpty_returns_fd
- _zsh_autosuggest_async_pty_recreate
- # We recreate the pty to get a fresh list of history events
- add-zsh-hook precmd _zsh_autosuggest_async_pty_recreate
- }
- #--------------------------------------------------------------------#
- # Start #
- #--------------------------------------------------------------------#
- # Start the autosuggestion widgets
- _zsh_autosuggest_start() {
- add-zsh-hook -d precmd _zsh_autosuggest_start
- _zsh_autosuggest_bind_widgets
- # 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.
- add-zsh-hook precmd _zsh_autosuggest_bind_widgets
- if [[ -n "${ZSH_AUTOSUGGEST_USE_ASYNC+x}" ]]; then
- _zsh_autosuggest_async_start
- fi
- }
- # Start the autosuggestion widgets on the next precmd
- add-zsh-hook precmd _zsh_autosuggest_start
- #====================================================================================================================#
- ## Colored Man Pages ##
- # termcap
- # ks make the keypad send commands
- # ke make the keypad send digits
- # vb emit visual bell
- # mb start blink
- # md start bold
- # me turn off bold, blink and underline
- # so start standout (reverse video)
- # se stop standout
- # us start underline
- # ue stop underline
- function man() {
- env \
- LESS_TERMCAP_mb=$(printf "\e[1;34m") \
- LESS_TERMCAP_md=$(printf "\e[1;34m") \
- LESS_TERMCAP_me=$(printf "\e[0m") \
- LESS_TERMCAP_so=$(printf "\e[1;47;33m") \
- LESS_TERMCAP_se=$(printf "\e[0m") \
- LESS_TERMCAP_us=$(printf "\e[1;32m") \
- LESS_TERMCAP_ue=$(printf "\e[0m") \
- PAGER="${commands[less]:-$PAGER}" \
- man "$@"
- }
- #====================================================================================================================#
- ## Emoticons ##
- export em_confused='¯\_(⊙︿⊙)_/¯'
- export em_crying='ಥ_ಥ'
- export em_cute_bear='ʕ•ᴥ•ʔ'
- export em_cute_face='(。◕‿◕。)'
- export em_excited='☜(⌒▽⌒)☞'
- export em_fisticuffs='ლ(`ー´ლ)'
- export em_fliptable='(╯°□°)╯︵ ┻━┻'
- export em_person_flip_table=$em_fliptable
- export em_person_flip_person='(╯°Д°)╯︵/(.□ . \)\'
- export em_table_flip_person='ノ┬─┬ノ ︵ ( \o°o)\'
- export em_person_unflip_table='┬──┬◡ノ(° -°ノ)'
- export em_happy='ヽ(´▽`)/'
- export em_innocent='ʘ‿ʘ'
- export em_kirby='⊂(◉‿◉)つ'
- export em_lennyface='( ͡° ͜ʖ ͡°)'
- export em_lion='°‿‿°'
- export em_muscleflex='ᕙ(⇀‸↼‶)ᕗ'
- export em_muscleflex2='ᕦ(∩◡∩)ᕤ'
- export em_perky='(`・ω・´)'
- export em_piggy='(´・ω・`)'
- export em_shrug='¯\_(ツ)_/¯'
- export em_point_right='(☞゚ヮ゚)☞'
- export em_point_left='☜(゚ヮ゚☜)'
- export em_magic='╰(•̀ 3 •́)━☆゚.*・。゚'
- export em_shades='(•_•)
- ( •_•)>⌐■-■
- (⌐■_■)'
- export em_disapprove='ಠ_ಠ'
- export em_wink='ಠ‿↼'
- export em_facepalm='(-‸ლ)'
- export em_hataz_gon_hate='ᕕ( ᐛ )ᕗ'
- export em_salute='( ̄^ ̄)ゞ'
- #====================================================================================================================#
- ## Command Not Found Insults ##
- print_message () {
- local messages
- local message
- messages=(
- "Boooo!"
- "Don't you know anything?"
- "RTFM!"
- "Haha, n00b!"
- "Wow! That was impressively wrong!"
- "Pathetic"
- "The worst one today!"
- "n00b alert!"
- "Your application for reduced salary has been sent!"
- "lol"
- "u suk"
- "lol... plz"
- "plz uninstall"
- "And the Darwin Award goes to.... ${USER}!"
- "ERROR_INCOMPETENT_USER"
- "Incompetence is also a form of competence"
- "Bad."
- "Fake it till you make it!"
- "What is this...? Amateur hour!?"
- "Come on! You can do it!"
- "Nice try."
- "What if... you type an actual command the next time!"
- "What if I told you... it is possible to type valid commands."
- "Y u no speak computer???"
- "This is not Windows"
- "Perhaps you should leave the command line alone..."
- "Please step away from the keyboard!"
- "error code: 1D10T"
- "ACHTUNG! ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS! DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN. IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS. ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN."
- "Pro tip: type a valid command!"
- "Go outside."
- "This is not a search engine."
- "(╯°□°)╯︵ ┻━┻"
- "¯\_(ツ)_/¯"
- "So, I'm just going to go ahead and run rm -rf / for you."
- "Why are you so stupid?!"
- "Perhaps computers is not for you..."
- "Why are you doing this to me?!"
- "Don't you have anything better to do?!"
- "I am _seriously_ considering 'rm -rf /'-ing myself..."
- "This is why you get to see your children only once a month."
- "This is why nobody likes you."
- "Are you even trying?!"
- "Try using your brain the next time!"
- "My keyboard is not a touch screen!"
- "Commands, random gibberish, who cares!"
- "Typing incorrect commands, eh?"
- "Are you always this stupid or are you making a special effort today?!"
- "Dropped on your head as a baby, eh?"
- "Brains aren't everything. In your case they're nothing."
- "I don't know what makes you so stupid, but it really works."
- "You are not as bad as people say, you are much, much worse."
- "Two wrongs don't make a right, take your parents as an example."
- "You must have been born on a highway because that's where most accidents happen."
- "If what you don't know can't hurt you, you're invulnerable."
- "If ignorance is bliss, you must be the happiest person on earth."
- "You're proof that god has a sense of humor."
- "Keep trying, someday you'll do something intelligent!"
- "If shit was music, you'd be an orchestra."
- "How many times do I have to flush before you go away?"
- )
- # If CMD_NOT_FOUND_MSGS array is populated use those messages instead of the defaults
- [[ -n ${CMD_NOT_FOUND_MSGS} ]] && messages=( "${CMD_NOT_FOUND_MSGS[@]}" )
- # If CMD_NOT_FOUND_MSGS_APPEND array is populated append those to the existing messages
- [[ -n ${CMD_NOT_FOUND_MSGS_APPEND} ]] && messages+=( "${CMD_NOT_FOUND_MSGS_APPEND[@]}" )
- # Seed RANDOM with an integer of some length
- RANDOM=$(od -vAn -N4 -tu < /dev/urandom)
- # Print a randomly selected message, but only about half the time to annoy the user a
- # little bit less.
- # if [[ $((${RANDOM} % 2)) -lt 1 ]]; then
- # message=${messages[${RANDOM} % ${#messages[@]}]}
- # printf "\n $(tput bold)$(tput setaf 1)${message}$(tput sgr0)\n\n"
- printf "\n $(tput bold)$(tput setaf 1)$(shuf -n 1 -e "${messages[@]}")$(tput sgr0)\n\n"
- #fi
- }
- function_exists () {
- # Zsh returns 0 even on non existing functions with -F so use -f
- declare -f $1 > /dev/null
- return $?
- }
- #
- # The idea below is to copy any existing handlers to another function
- # name and insert the message in front of the old handler in the
- # new handler. By default, neither bash or zsh has has a handler function
- # defined, so the default behaviour is replicated.
- #
- # Also, ensure the handler is only copied once. If we do not ensure this
- # the handler would add itself recursively if this file happens to be
- # sourced multiple times in the same shell, resulting in a neverending
- # stream of messages.
- #
- #
- # Zsh
- #
- if function_exists command_not_found_handler; then
- if ! function_exists orig_command_not_found_handler; then
- eval "orig_$(declare -f command_not_found_handler)"
- fi
- else
- orig_command_not_found_handler () {
- echo "zsh: command not found: $1"
- return 127
- }
- fi
- command_not_found_handler () {
- print_message
- orig_command_not_found_handler "$@"
- }
- #====================================================================================================================#
- ## Hacker Quotes ##
- if [[ -o interactive ]]; then
- hacker_quotes=(
- # Linus Torvalds
- # https://en.wikiquote.org/wiki/Linus_Torvalds
- "Talk is cheap. Show me the code.\n - Linus Torvalds"
- "Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.\n - Linus Torvalds"
- "I'm an egotistical bastard, and I name all my projects after myself. First Linux, now git.\n - Linus Torvalds"
- # Alan J. Perlis
- # https://en.wikiquote.org/wiki/Alan_Perlis
- "One man's constant is another man's variable.\n - Alan J. Perlis"
- "Functions delay binding; data structures induce binding. Moral: Structure data late in the programming process.\n - Alan J. Perlis"
- "Syntactic sugar causes cancer of the semicolon.\n - Alan J. Perlis"
- "Every program is a part of some other program and rarely fits.\n - Alan J. Perlis"
- "If a program manipulates a large amount of data, it does so in a small number of ways.\n - Alan J. Perlis"
- "Symmetry is a complexity-reducing concept (co-routines include subroutines); seek it everywhere.\n - Alan J. Perlis"
- "It is easier to write an incorrect program than understand a correct one.\n - Alan J. Perlis"
- "A programming language is low level when its programs require attention to the irrelevant.\n - Alan J. Perlis"
- "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.\n - Alan J. Perlis"
- "Get into a rut early: Do the same process the same way. Accumulate idioms. Standardize. The only difference(!) between Shakespeare and you was the size of his idiom list - not the size of his vocabulary.\n - Alan J. Perlis"
- "If you have a procedure with ten parameters, you probably missed some.\n - Alan J. Perlis"
- "Recursion is the root of computation since it trades description for time.\n - Alan J. Perlis"
- "If two people write exactly the same program, each should be put into microcode and then they certainly won't be the same.\n - Alan J. Perlis"
- "In the long run every program becomes rococo - then rubble.\n - Alan J. Perlis"
- "Everything should be built top-down, except the first time.\n - Alan J. Perlis"
- "Every program has (at least) two purposes: the one for which it was written, and another for which it wasn't.\n - Alan J. Perlis"
- "If a listener nods his head when you're explaining your program, wake him up.\n - Alan J. Perlis"
- "A program without a loop and a structured variable isn't worth writing.\n - Alan J. Perlis"
- "A language that doesn't affect the way you think about programming, is not worth knowing.\n - Alan J. Perlis"
- "Wherever there is modularity there is the potential for misunderstanding: Hiding information implies a need to check communication.\n - Alan J. Perlis"
- "Optimization hinders evolution.\n - Alan J. Perlis"
- "A good system can't have a weak command language.\n - Alan J. Perlis"
- "To understand a program you must become both the machine and the program.\n - Alan J. Perlis"
- "Perhaps if we wrote programs from childhood on, as adults we'd be able to read them.\n - Alan J. Perlis"
- "One can only display complex information in the mind. Like seeing, movement or flow or alteration of view is more important than the static picture, no matter how lovely.\n - Alan J. Perlis"
- "There will always be things we wish to say in our programs that in all known languages can only be said poorly.\n - Alan J. Perlis"
- "Once you understand how to write a program get someone else to write it.\n - Alan J. Perlis"
- "Around computers it is difficult to find the correct unit of time to measure progress. Some cathedrals took a century to complete. Can you imagine the grandeur and scope of a program that would take as long?\n - Alan J. Perlis"
- "For systems, the analogue of a face-lift is to add to the control graph an edge that creates a cycle, not just an additional node.\n - Alan J. Perlis"
- "In programming, everything we do is a special case of something more general -- and often we know it too quickly.\n - Alan J. Perlis"
- "Simplicity does not precede complexity, but follows it.\n - Alan J. Perlis"
- "Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis.\n - Alan J. Perlis"
- "The eleventh commandment was \"Thou Shalt Compute\" or \"Thou Shalt Not Compute\" - I forget which.\n - Alan J. Perlis"
- "The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information.\n - Alan J. Perlis"
- "Everyone can be taught to sculpt: Michelangelo would have had to be taught not to. So it is with great programmers.\n - Alan J. Perlis"
- "The use of a program to prove the 4-color theorem will not change mathematics - it merely demonstrates that the theorem, a challenge for a century, is probably not important to mathematics.\n - Alan J. Perlis"
- "The most important computer is the one that rages in our skulls and ever seeks that satisfactory external emulator. The standarization of real computers would be a disaster - and so it probably won't happen.\n - Alan J. Perlis"
- "Structured Programming supports the law of the excluded middle.\n - Alan J. Perlis"
- "Re graphics: A picture is worth 10K words - but only those to describe the picture. Hardly any sets of 10K words can be adequately described with pictures.\n - Alan J. Perlis"
- "There are two ways to write error-free programs; only the third one works.\n - Alan J. Perlis"
- "Some programming languages manage to absorb change, but withstand progress.\n - Alan J. Perlis"
- "You can measure a programmer's perspective by noting his attitude on the continuing vitality of FORTRAN.\n - Alan J. Perlis"
- "In software systems, it is often the early bird that makes the worm.\n - Alan J. Perlis"
- "Sometimes I think the only universal in the computing field is the fetch-execute cycle.\n - Alan J. Perlis"
- "The goal of computation is the emulation of our synthetic abilities, not the understanding of our analytic ones.\n - Alan J. Perlis"
- "Like punning, programming is a play on words.\n - Alan J. Perlis"
- "As Will Rogers would have said, \"There is no such thing as a free variable.\"\n - Alan J. Perlis"
- "The best book on programming for the layman is \"Alice in Wonderland\"; but that's because it's the best book on anything for the layman.\n - Alan J. Perlis"
- "Giving up on assembly language was the apple in our Garden of Eden: Languages whose use squanders machine cycles are sinful. The LISP machine now permits LISP programmers to abandon bra and fig-leaf.\n - Alan J. Perlis"
- "When we understand knowledge-based systems, it will be as before -- except our fingertips will have been singed.\n - Alan J. Perlis"
- "Bringing computers into the home won't change either one, but may revitalize the corner saloon.\n - Alan J. Perlis"
- "Systems have sub-systems and sub-systems have sub- systems and so on ad infinitum - which is why we're always starting over.\n - Alan J. Perlis"
- "So many good ideas are never heard from again once they embark in a voyage on the semantic gulf.\n - Alan J. Perlis"
- "Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.\n - Alan J. Perlis"
- "A LISP programmer knows the value of everything, but the cost of nothing.\n - Alan J. Perlis"
- "Software is under a constant tension. Being symbolic it is arbitrarily perfectible; but also it is arbitrarily changeable.\n - Alan J. Perlis"
- "It is easier to change the specification to fit the program than vice versa.\n - Alan J. Perlis"
- "Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it.\n - Alan J. Perlis"
- "In English every word can be verbed. Would that it were so in our programming languages.\n - Alan J. Perlis"
- "In seeking the unattainable, simplicity only gets in the way.\n - Alan J. Perlis"
- "In programming, as in everything else, to be in error is to be reborn.\n - Alan J. Perlis"
- "In computing, invariants are ephemeral.\n - Alan J. Perlis"
- "When we write programs that \"learn\", it turns out that we do and they don't.\n - Alan J. Perlis"
- "Often it is the means that justify the ends: Goals advance technique and technique survives even when goal structures crumble.\n - Alan J. Perlis"
- "Make no mistake about it: Computers process numbers - not symbols. We measure our understanding (and control) by the extent to which we can arithmetize an activity.\n - Alan J. Perlis"
- "Making something variable is easy. Controlling duration of constancy is the trick.\n - Alan J. Perlis"
- "Think of all the psychic energy expended in seeking a fundamental distinction between \"algorithm\" and \"program\".\n - Alan J. Perlis"
- "If we believe in data structures, we must believe in independent (hence simultaneous) processing. For why else would we collect items within a structure? Why do we tolerate languages that give us the one without the other?\n - Alan J. Perlis"
- "In a 5 year period we get one superb programming language. Only we can't control when the 5 year period will be.\n - Alan J. Perlis"
- "Over the centuries the Indians developed sign language for communicating phenomena of interest. Programmers from different tribes (FORTRAN, LISP, ALGOL, SNOBOL, etc.) could use one that doesn't require them to carry a blackboard on their ponies.\n - Alan J. Perlis"
- "Documentation is like term insurance: It satisfies because almost no one who subscribes to it depends on its benefits.\n - Alan J. Perlis"
- "An adequate bootstrap is a contradiction in terms.\n - Alan J. Perlis"
- "It is not a language's weakness but its strengths that control the gradient of its change: Alas, a language never escapes its embryonic sac.\n - Alan J. Perlis"
- "Is it possible that software is not like anything else, that it is meant to be discarded: that the whole point is to see it as a soap bubble?\n - Alan J. Perlis"
- "Because of its vitality, the computing field is always in desperate need of new cliches: Banality soothes our nerves.\n - Alan J. Perlis"
- "It is the user who should parameterize procedures, not their creators.\n - Alan J. Perlis"
- "The cybernetic exchange between man, computer and algorithm is like a game of musical chairs: The frantic search for balance always leaves one of the three standing ill at ease.\n - Alan J. Perlis"
- "If your computer speaks English, it was probably made in Japan.\n - Alan J. Perlis"
- "A year spent in artificial intelligence is enough to make one believe in God.\n - Alan J. Perlis"
- "Prolonged contact with the computer turns mathematicians into clerks and vice versa.\n - Alan J. Perlis"
- "In computing, turning the obvious into the useful is a living definition of the word \"frustration\".\n - Alan J. Perlis"
- "We are on the verge: Today our program proved Fermat's next-to-last theorem.\n - Alan J. Perlis"
- "What is the difference between a Turing machine and the modern computer? It's the same as that between Hillary's ascent of Everest and the establishment of a Hilton hotel on its peak.\n - Alan J. Perlis"
- "Motto for a research laboratory: What we work on today, others will first think of tomorrow.\n - Alan J. Perlis"
- "Though the Chinese should adore APL, it's FORTRAN they put their money on.\n - Alan J. Perlis"
- "We kid ourselves if we think that the ratio of procedure to data in an active data-base system can be made arbitrarily small or even kept small.\n - Alan J. Perlis"
- "We have the mini and the micro computer. In what semantic niche would the pico computer fall?\n - Alan J. Perlis"
- "It is not the computer's fault that Maxwell's equations are not adequate to design the electric motor.\n - Alan J. Perlis"
- "One does not learn computing by using a hand calculator, but one can forget arithmetic.\n - Alan J. Perlis"
- "Computation has made the tree flower.\n - Alan J. Perlis"
- "The computer reminds one of Lon Chaney -- it is the machine of a thousand faces.\n - Alan J. Perlis"
- "The computer is the ultimate polluter: its feces are indistinguish- able from the food it produces.\n - Alan J. Perlis"
- "When someone says \"I want a programming language in which I need only say what I wish done,\" give him a lollipop.\n - Alan J. Perlis"
- "Interfaces keep things tidy, but don't accelerate growth: Functions do.\n - Alan J. Perlis"
- "Don't have good ideas if you aren't willing to be responsible for them.\n - Alan J. Perlis"
- "Computers don't introduce order anywhere as much as they expose opportunities.\n - Alan J. Perlis"
- "When a professor insists computer science is X but not Y, have compassion for his graduate students.\n - Alan J. Perlis"
- "In computing, the mean time to failure keeps getting shorter.\n - Alan J. Perlis"
- "In man-machine symbiosis, it is man who must adjust: The machines can't.\n - Alan J. Perlis"
- "We will never run out of things to program as long as there is a single program around.\n - Alan J. Perlis"
- "Dealing with failure is easy: Work hard to improve. Success is also easy to handle: You've solved the wrong problem. Work hard to improve.\n - Alan J. Perlis"
- "One can't proceed from the informal to the formal by formal means.\n - Alan J. Perlis"
- "Purely applicative languages are poorly applicable.\n - Alan J. Perlis"
- "The proof of a system's value is its existence.\n - Alan J. Perlis"
- "You can't communicate complexity, only an awareness of it.\n - Alan J. Perlis"
- "It's difficult to extract sense from strings, but they're the only communication coin we can count on.\n - Alan J. Perlis"
- "The debate rages on: is PL/I Bachtrian or Dromedary?\n - Alan J. Perlis"
- "Whenever two programmers meet to criticize their programs, both are silent.\n - Alan J. Perlis"
- "Think of it! With VLSI we can pack 100 ENIACS in 1 sq. cm.\n - Alan J. Perlis"
- "Editing is a rewording activity.\n - Alan J. Perlis"
- "Why did the Roman Empire collapse? What is Latin for office automation?\n - Alan J. Perlis"
- "Computer Science is embarrassed by the computer.\n - Alan J. Perlis"
- "The only constructive theory connecting neuroscience and psychology will arise from the study of software.\n - Alan J. Perlis"
- "Within a computer natural language is unnatural.\n - Alan J. Perlis"
- "Most people find the concept of programming obvious, but the doing impossible.\n - Alan J. Perlis"
- "You think you know when you can learn, are more sure when you can write, even more when you can teach, but certain when you can program.\n - Alan J. Perlis"
- "It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?\n - Alan J. Perlis"
- "If you can imagine a society in which the computer- robot is the only menial, you can imagine anything.\n - Alan J. Perlis"
- "Programming is an unnatural act.\n - Alan J. Perlis"
- "Adapting old programs to fit new machines usually means adapting new machines to behave like old ones.\n - Alan J. Perlis"
- # Donald E. Knuth
- # https://en.wikiquote.org/wiki/Donald_Knuth
- "Beware of bugs in the above code; I have only proved it correct, not tried it.\n - Donald E. Knuth"
- "Science is knowledge which we understand so well that we can teach it to a computer; and if we don't fully understand something, it is an art to deal with it.\n - Donald E. Knuth"
- "In fact, my main conclusion after spending ten years of my life working on the TEX project is that software is hard. It’s harder than anything else I’ve ever had to do.\n - Donald E. Knuth"
- "Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.\n - Donald E. Knuth"
- "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.\n - Donald E. Knuth"
- # Edsger W. Dijkstra
- # https://en.wikiquote.org/wiki/Edsger_W._Dijkstra
- "Testing shows the presence, not the absence of bugs.\n - Edsger W. Dijkstra"
- "The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.\n - Edsger W. Dijkstra"
- "LISP has been jokingly described as \"the most intelligent way to misuse a computer\". I think that description a great compliment because it transmits the full flavor of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts.\n - Edsger W. Dijkstra"
- "Besides a mathematical inclination, an exceptionally good mastery of one's native tongue is the most vital asset of a competent programmer.\n - Edsger W. Dijkstra"
- "Simplicity is a great virtue but it requires hard work to achieve it and education to appreciate it. And to make matters worse: complexity sells better.\n - Edsger W. Dijkstra"
- "My point today is that, if we wish to count lines of code, we should not regard them as \"lines produced\" but as \"lines spent\": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger.\n - Edsger W. Dijkstra"
- # Richard Stallmon
- "I'd just like to interject for a moment. What you’re referring to as Linux, is in fact, GNU/Linux, or as I’ve recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called “Linux”, and many of its users are not aware that it is basically the GNU system, developed by the GNU Project. There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine’s resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called “Linux” distributions are really distributions of GNU/Linux.\n - Richard Stallmon"
- # mics
- "There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.\n - C.A.R. Hoare"
- "There are only two hard things in Computer Science: cache invalidation and naming things.\n - Phil Karlton"
- "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.\n - Martin Golding"
- "The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.\n - Seymour Cray"
- "First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack.\n - George Carrette"
- "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.\n - Brian W. Kernighan"
- "Measuring programming progress by lines of code is like measuring aircraft building progress by weight.\n - Bill Gates"
- "The best programmers are not marginally better than merely good ones. They are an order-of-magnitude better, measured by whatever standard: conceptual creativity, speed, ingenuity of design, or problem-solving ability.\n - Randall E. Stross"
- "For a long time it puzzled me how something so expensive, so leading edge, could be so useless. And then it occurred to me that a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are, in short, a perfect match.\n - Bill Bryson"
- "You can’t have great software without a great team, and most software teams behave like dysfunctional families.\n - Jim McCarthy"
- "Incorrect documentation is often worse than no documentation.\n - Bertrand Meyer"
- "Correctness is clearly the prime quality. If a system does not do what it is supposed to do, then everything else about it matters little.\n - Bertrand Meyer"
- "I would love to change the world, but they won't give me the source code.\n - Anonymous"
- "Any fool can write code that a computer can understand. Good programmers write code that humans can understand.\n - Martin Fowler"
- "I am not a great programmer; I am just a good programmer with great habits.\n - Kent Beck"
- "A Computer is a state machine. Threads are for people who can't program state machines.\n - Alan Cox"
- "Not everything worth doing is worth doing well.\n - Tom West"
- "Peace comes from thinking.\n - N.S.A"
- )
- echo "${hacker_quotes[RANDOM % #hacker_quotes + 1]}"
- echo
- # release memory
- unset hacker_quotes
- fi
- #====================================================================================================================#
- ######################################################################################################################
- ### Aliases ###
- ## files and directories
- # trash
- alias trash="~/.local/share/Trash/files"
- #====================================================================================================================#
- ## shorter commands
- # clear
- alias c="clear"
- # man
- alias m="man"
- # list
- alias l="ls"
- # grep
- alias g="grep"
- # list and grep
- alias lg="ls | grep"
- # list all
- alias la="ls -a"
- # list long
- alias ll="ls -l"
- # list recursively
- alias lR="ls -R"
- # get pid ID of a process
- alias getpid="ps ax | grep"
- # check aliases
- alias falias="cat /home/user/.zsh | grep alias"
- # exit
- alias e="exit"
- # start tmux
- alias t="tmux"
- #====================================================================================================================#
- ## package management
- # install
- alias install="sudo apt install --no-install-recommends"
- # install from backport
- alias install-backport="sudo apt -t stretch-backports install --no-install-recommends"
- # update
- alias update="sudo apt update"
- # upgrade
- alias upgrade="sudo apt upgrade"
- # remove uneeded dependencies
- alias autoremove="sudo apt autoremove"
- # fix broken packages
- alias apt-fix="sudo apt update --fix-missing"
- # mark a package as manually installed
- alias mark-manual="sudo apt-mark manual"
- # mark a package as automatically installed
- alias mark-auto="sudo apt-mark auto"
- # search for a package
- alias apt-search="sudo apt-cache search"
- # search for a package in backport
- alias apt-search-backport="sudo apt-cache search -t stretch-backports"
- # uninstall a package
- alias uninstall="sudo apt remove"
- #====================================================================================================================#
- ## system functions
- # reboot
- alias reboot="/sbin/reboot"
- # shutdown
- alias shutdown="/sbin/shutdown"
- # poweroff
- alias poweroff="/sbin/poweroff"
- #====================================================================================================================#
- ## quicker editing
- # zsh config
- alias .zsh="nvim /home/user/.zsh"
- # add WiFi
- alias wifi="doas nvim /etc/hostname.iwn0"
- # .Xresources
- alias .Xresources="nvim /home/user/.Xresources"
- # .xsession
- alias .xsession="nvim /home/user/.xsession"
- #====================================================================================================================#
- ######################################################################################################################
- ### Prompt ###
- ## smiley prompt
- $Smilies
- setopt PROMPT_SUBST
- prompt_status_smiley() {
- [[ $? -ne 0 ]] && echo '%F{1}):%f'
- }
- RPROMPT='$(prompt_status_smiley)'
- PS2=$' \e[0;34m%}%B>%{\e[0m%}%b'
- ## main prompt
- if [[ $BENDER_THEME_STYLE == "mini" ]] ; then
- local user_host_jobs=
- else
- local user_host_jobs='[ %F{white}%n%F{red} :: %F{yellow}%m%F{red} ]-( %F{white}%j%F{red} )-'
- fi
- PROMPT='
- %B%F{red}┌───=${user_host_jobs}[ %F{white}%~%F{red} ]$(git_prompt_info)
- └──(%b%f '
- ZSH_THEME_GIT_PROMPT_PREFIX="-( %F{blue}"
- ZSH_THEME_GIT_PROMPT_SUFFIX="%F{red} )"
- ######################################################################################################################
- ============================================================================================================================
- ## htop
- #####################
- #
- # htoprc
- #
- #####################
- fields=0 48 17 18 38 39 2 46 47 49 1
- sort_key=46
- sort_direction=1
- hide_threads=0
- hide_kernel_threads=0
- hide_userland_threads=0
- shadow_other_users=0
- show_thread_names=1
- show_program_path=1
- highlight_base_name=1
- highlight_megabytes=1
- highlight_threads=1
- tree_view=1
- header_margin=0
- detailed_cpu_time=1
- cpu_count_from_zero=1
- update_process_names=1
- account_guest_in_cpu_meter=1
- color_scheme=0
- delay=15
- left_meters=AllCPUs Memory Swap
- left_meter_modes=1 1 1
- right_meters=Hostname Clock Tasks LoadAverage Uptime
- right_meter_modes=2 2 2 2 2
- ============================================================================================================================
- ## neovim
- """""""""""""""""""""
- "
- " Neovim Config
- "
- """""""""""""""""""""
- """ Global Settings
- " enter the current millenium
- set nocompatible
- " highlight matching characters
- set showmatch
- " enable folding
- set foldenable
- " open most folds by default
- set foldlevelstart=10
- " 10 nested fold max
- set foldnestmax=10
- " fold based on indent level
- set foldmethod=indent
- " highlight search
- set hlsearch
- " set incremental search
- set incsearch
- " ingore cases in search
- set ignorecase
- set smartcase
- " disable swap file creation
- set noswapfile
- " enable syntax
- syntax enable
- syntax on
- " enable plugins for netrw
- filetype plugin on
- " enable numbers
- set number
- set relativenumber
- " filetype detection
- filetype plugin indent on
- " replace ~ with a space
- set fcs=eob:\
- " list chars
- :set listchars=tab:\|\
- :set list
- " turn on cursor line highlighting
- set cursorline
- " search down into subfolders and provide tab-completion for all file-related tasks
- set path+=**
- " display all matching files when using tab completion
- set wildmenu
- "" - Hit tab to :find by partial match
- "" - Use * to make it fuzzy
- "" - :b lets you autocomplete any open buffer
- " Create the `tags` file (need to create a `tags` file)
- command! MakeTags !ctags -R .
- "" - Use ^] to jump to tag under cursor
- "" - Use g^] for ambiguous tags
- "" - Use ^t to jump back up the tag stack
- " autocomplete notes
- "" - ^x^n for JUST this file
- "" - ^x^f for filenames (works with our path trick!)
- "" - ^x^] for tags only
- "" - ^n for anything specified by the 'complete' option
- "" - Use ^n and ^p to go back and forth in the suggestion list
- " file browsing
- "" Tweaks for browsing
- let g:netrw_banner=0 " disable annoying banner
- let g:netrw_browse_split=4 " open in prior window
- let g:netrw_altv=1 " open splits to the right
- let g:netrw_liststyle=3 " tree view
- let g:netrw_winsize = 25 " set window size
- let g:netrw_list_hide=netrw_gitignore#Hide()
- let g:netrw_list_hide.=',\(^\|\s\s\)\zs\.\S\+'
- "" - :edit a folder to open a file browser
- "" - <CR>/v/t to open in an h-split/v-split/tab
- "" - check |netrw-browse-maps| for more mappings
- """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
- """ Cursor
- :set guicursor=n-v-c:hor20,i-ci-ve:ver25,r-cr:hor20,o:hor50
- \,a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor
- \,sm:block-blinkwait175-blinkoff150-blinkon175
- let $NVIM_TUI_ENABLE_CURSOR_SHAPE = 0
- """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
- """ Keybindings
- " source init.vim
- map <F5> :source ~/.config/nvim/init.vim<CR>
- " enable spell check
- map <M-c> :set spell spelllang=en_us<CR>
- " split veritcally
- map <M-v> :vsplit<CR>
- " split horizontally
- map <M-h> :split<CR>
- " file browsing
- map <M-l> :Vexplore<CR>
- " open a terminal window
- map <M-t> :tabnew +terminal<CR>
- " space open/closes folds
- map <space> za<CR>
- " copy to system keyboard
- vnoremap <M-y> "+y
- " paste from system keyboard
- vnoremap <M-p> "*p
- " unbind up arrow key
- "inoremap <up> <nop>
- "vnoremap <up> <nop>
- " unbind down arrow key
- "inoremap <down> <nop>
- "vnoremap <down> <nop>
- " unbind Left arrow key
- "inoremap <left> <nop>
- "vnoremap <left> <nop>
- " unbind Right arrow key
- "inoremap <right> <nop>
- "vnoremap <right> <nop>
- """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
- """ Theme
- let g:currentmode={
- \ 'n' : 'N ',
- \ 'no' : 'N·Operator Pending ',
- \ 'v' : 'V ',
- \ 'V' : 'V·Line ',
- \ "\<C-V>" : 'V·Block ',
- \ 's' : 'Select ',
- \ 'S' : 'S·Line ',
- \ "\<C-S>" : 'S·Block ',
- \ 'i' : 'I ',
- \ 'R' : 'R ',
- \ 'Rv' : 'V·Replace ',
- \ 'c' : 'Command ',
- \ 'cv' : 'Vim Ex ',
- \ 'ce' : 'Ex ',
- \ 'r' : 'Prompt ',
- \ 'rm' : 'More ',
- \ 'r?' : 'Confirm ',
- \ '!' : 'Shell ',
- \ 't' : 'Terminal '
- \}
- " Automatically change the statusline color depending on mode
- function! ChangeStatuslineColor()
- if (mode() =~# '\v(n|no)')
- exe 'hi! StatusLine ctermfg=008'
- elseif (mode() =~# '\v(v|V)' || g:currentmode[mode()] ==# 'V·Block' || get(g:currentmode, mode(), '') ==# 't')
- exe 'hi! StatusLine ctermfg=005'
- elseif (mode() ==# 'i')
- exe 'hi! StatusLine ctermfg=004'
- else
- exe 'hi! StatusLine ctermfg=006'
- endif
- return ''
- endfunction
- " Find out current buffer's size and output it.
- function! FileSize()
- let bytes = getfsize(expand('%:p'))
- if (bytes >= 1024)
- let kbytes = bytes / 1024
- endif
- if (exists('kbytes') && kbytes >= 1000)
- let mbytes = kbytes / 1000
- endif
- if bytes <= 0
- return '0'
- endif
- if (exists('mbytes'))
- return mbytes . 'MB '
- elseif (exists('kbytes'))
- return kbytes . 'KB '
- else
- return bytes . 'B '
- endif
- endfunction
- function! ReadOnly()
- if &readonly || !&modifiable
- return ''
- else
- return ''
- endfunction
- "" git status
- function! GitBranch()
- return system("git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'")
- endfunction
- function! StatuslineGit()
- let l:branchname = GitBranch()
- return strlen(l:branchname) > 0 ? ''.l:branchname.' ':''
- endfunction
- set laststatus=2
- set statusline=
- set statusline+=%{ChangeStatuslineColor()} " Changing the statusline color
- set statusline+=%0*\ %{toupper(g:currentmode[mode()])} " Current mode
- set statusline+=%8*\ [%n] " buffernr
- set statusline+=%8*\ %{StatuslineGit()} " Git Branch name
- set statusline+=%8*\ %<%F\ %{ReadOnly()}\ %m\ %w\ " File+path
- set statusline+=%#warningmsg#
- "set statusline+=%{SyntasticStatuslineFlag()} " Syntastic errors
- set statusline+=%*
- set statusline+=%9*\ %= " Space
- set statusline+=%8*\ %y\ " FileType
- set statusline+=%7*\ %{(&fenc!=''?&fenc:&enc)}\[%{&ff}]\
- set statusline+=%8*\ %-3(%{FileSize()}%) " File size
- set statusline+=%0*\ %3p%%\ \ %l:\ %3c\ " Rownumber/total (%)
- hi User1 ctermfg=007
- hi User2 ctermfg=008
- hi User3 ctermfg=008
- hi User4 ctermfg=008
- hi User5 ctermfg=008
- hi User7 ctermfg=008
- hi User8 ctermfg=008
- hi User9 ctermfg=007
- " colors
- set background=dark
- if version > 580
- hi clear
- if exists("syntax_on")
- syntax reset
- endif
- endif
- set t_Co=256
- hi Normal ctermfg=15 ctermbg=0 cterm=bold
- hi IncSearch ctermfg=15 ctermbg=33 cterm=NONE
- hi WildMenu ctermfg=NONE ctermbg=17 cterm=NONE
- hi SignColumn ctermfg=234 ctermbg=60 cterm=NONE
- hi SpecialComment ctermfg=33 ctermbg=NONE cterm=bold
- hi Typedef ctermfg=80 ctermbg=NONE cterm=bold
- hi Title ctermfg=15 ctermbg=NONE cterm=NONE
- hi Folded ctermfg=234 ctermbg=109 cterm=NONE
- hi PreCondit ctermfg=13 ctermbg=NONE cterm=NONE
- hi Include ctermfg=13 ctermbg=NONE cterm=NONE
- hi Float ctermfg=197 ctermbg=NONE cterm=NONE
- hi StatusLineNC ctermfg=15 ctermbg=NONE cterm=bold
- hi NonText ctermfg=237 ctermbg=NONE cterm=NONE
- hi DiffText ctermfg=230 ctermbg=53 cterm=NONE
- hi ErrorMsg ctermfg=15 ctermbg=52 cterm=NONE
- hi Debug ctermfg=101 ctermbg=NONE cterm=NONE
- hi PMenuSbar ctermfg=NONE ctermbg=60 cterm=NONE
- hi Identifier ctermfg=80 ctermbg=NONE cterm=NONE
- hi SpecialChar ctermfg=13 ctermbg=NONE cterm=bold
- hi Conditional ctermfg=214 ctermbg=NONE cterm=bold
- hi StorageClass ctermfg=80 ctermbg=NONE cterm=bold
- hi Todo ctermfg=220 ctermbg=NONE cterm=NONE
- hi Special ctermfg=13 ctermbg=NONE cterm=bold
- hi LineNr ctermfg=58 ctermbg=NONE cterm=NONE
- hi StatusLine ctermfg=15 ctermbg=NONE cterm=bold
- hi Label ctermfg=214 ctermbg=NONE cterm=bold
- hi PMenuSel ctermfg=15 ctermbg=0 cterm=NONE
- hi Search ctermfg=15 ctermbg=33 cterm=NONE
- hi Delimiter ctermfg=101 ctermbg=NONE cterm=NONE
- hi Statement ctermfg=214 ctermbg=NONE cterm=bold
- hi Comment ctermfg=33 ctermbg=NONE cterm=NONE
- hi Character ctermfg=197 ctermbg=NONE cterm=NONE
- hi TabLineSel ctermfg=15 ctermbg=33 cterm=bold
- hi Number ctermfg=197 ctermbg=NONE cterm=NONE
- hi Boolean ctermfg=197 ctermbg=NONE cterm=NONE
- hi Operator ctermfg=214 ctermbg=NONE cterm=bold
- hi CursorLine ctermfg=NONE ctermbg=233 cterm=NONE
- hi TabLineFill ctermfg=234 ctermbg=66 cterm=bold
- hi WarningMsg ctermfg=232 ctermbg=220 cterm=NONE
- hi DiffDelete ctermfg=197 ctermbg=NONE cterm=NONE
- hi CursorColumn ctermfg=NONE ctermbg=8 cterm=NONE
- hi Define ctermfg=101 ctermbg=NONE cterm=NONE
- hi Function ctermfg=80 ctermbg=NONE cterm=bold
- hi FoldColumn ctermfg=234 ctermbg=109 cterm=NONE
- hi PreProc ctermfg=13 ctermbg=NONE cterm=NONE
- hi Visual ctermfg=58 ctermbg=0 cterm=NONE
- hi Exception ctermfg=214 ctermbg=NONE cterm=bold
- hi Keyword ctermfg=220 ctermbg=NONE cterm=bold
- hi Type ctermfg=80 ctermbg=NONE cterm=bold
- hi DiffChange ctermfg=230 ctermbg=24 cterm=NONE
- hi Cursor ctermfg=NONE ctermbg=225 cterm=NONE
- hi Error ctermfg=15 ctermbg=52 cterm=NONE
- hi PMenu ctermfg=15 ctermbg=NONE cterm=NONE
- hi SpecialKey ctermfg=220 ctermbg=NONE cterm=NONE
- hi Constant ctermfg=197 ctermbg=NONE cterm=NONE
- hi Tag ctermfg=214 ctermbg=NONE cterm=NONE
- hi String ctermfg=76 ctermbg=NONE cterm=NONE
- hi PMenuThumb ctermfg=NONE ctermbg=103 cterm=NONE
- hi MatchParen ctermfg=15 ctermbg=161 cterm=bold
- hi Repeat ctermfg=214 ctermbg=NONE cterm=bold
- hi Directory ctermfg=39 ctermbg=NONE cterm=NONE
- hi Structure ctermfg=214 ctermbg=NONE cterm=bold
- hi Macro ctermfg=220 ctermbg=NONE cterm=NONE
- hi DiffAdd ctermfg=NONE ctermbg=237 cterm=NONE
- hi TabLine ctermfg=15 ctermbg=NONE cterm=bold
- hi cursorim ctermfg=234 ctermbg=60 cterm=NONE
- hi CursorLineNr ctermfg=154 ctermbg=0 cterm=NONE
- hi VertSplit ctermfg=15 ctermbg=0 cterm=NONE
- hi Folded ctermfg=15 ctermbg=0 cterm=NONE
- """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
- ============================================================================================================================
- ## dunst
- [global]
- ##########################################
- #
- # Display
- #
- ##########################################
- # Which monitor should the notifications be displayed on.
- monitor = 0
- # Display notification on focused monitor. Possible modes are:
- # mouse: follow mouse pointer
- # keyboard: follow window with keyboard focus
- # none: don't follow anything
- #
- # "keyboard" needs a window manager that exports the
- # _NET_ACTIVE_WINDOW property.
- # This should be the case for almost all modern window managers.
- #
- # If this option is set to mouse or keyboard, the monitor option
- # will be ignored.
- follow = mouse
- # The geometry of the window:
- # [{width}]x{height}[+/-{x}+/-{y}]
- # The geometry of the message window.
- # The height is measured in number of notifications everything else
- # in pixels. If the width is omitted but the height is given
- # ("-geometry x2"), the message window expands over the whole screen
- # (dmenu-like). If width is 0, the window expands to the longest
- # message displayed. A positive x is measured from the left, a
- # negative from the right side of the screen. Y is measured from
- # the top and down respectively.
- # The width can be negative. In this case the actual width is the
- # screen width minus the width defined in within the geometry option.
- geometry = "300x5-30+10"
- # Show how many messages are currently hidden (because of geometry).
- indicate_hidden = yes
- # Shrink window if it's smaller than the width. Will be ignored if
- # width is 0.
- shrink = yes
- # The transparency of the window. Range: [0; 100].
- # This option will only work if a compositing window manager is
- # present (e.g. xcompmgr, compiz, etc.).
- transparency = 15
- # The height of the entire notification. If the height is smaller
- # than the font height and padding combined, it will be raised
- # to the font height and padding.
- notification_height = 0
- # Draw a line of "separator_height" pixel height between two
- # notifications.
- # Set to 0 to disable.
- separator_height = 2
- # Padding between text and separator.
- padding = 8
- # Horizontal padding.
- horizontal_padding = 8
- # Defines width in pixels of frame around the notification window.
- # Set to 0 to disable.
- frame_width = 1
- # Defines color of the frame around the notification window.
- frame_color = "#FF1493"
- # Define a color for the separator.
- # possible values are:
- # * auto: dunst tries to find a color fitting to the background;
- # * foreground: use the same color as the foreground;
- # * frame: use the same color as the frame;
- # * anything else will be interpreted as a X color.
- separator_color = frame
- # Sort messages by urgency.
- sort = yes
- # Don't remove messages, if the user is idle (no mouse or keyboard input)
- # for longer than idle_threshold seconds.
- # Set to 0 to disable.
- # Transient notifications ignore this setting.
- idle_threshold = 20
- ### Text ###
- font = Terminus (TTF) 9
- # The spacing between lines. If the height is smaller than the
- # font height, it will get raised to the font height.
- line_height = 1
- # Possible values are:
- # full: Allow a small subset of html markup in notifications:
- # <b>bold</b>
- # <i>italic</i>
- # <s>strikethrough</s>
- # <u>underline</u>
- #
- # For a complete reference see
- # <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
- #
- # strip: This setting is provided for compatibility with some broken
- # clients that send markup even though it's not enabled on the
- # server. Dunst will try to strip the markup but the parsing is
- # simplistic so using this option outside of matching rules for
- # specific applications *IS GREATLY DISCOURAGED*.
- #
- # no: Disable markup parsing, incoming notifications will be treated as
- # plain text. Dunst will not advertise that it has the body-markup
- # capability if this is set as a global setting.
- #
- # It's important to note that markup inside the format option will be parsed
- # regardless of what this is set to.
- markup = full
- # The format of the message. Possible variables are:
- # %a appname
- # %s summary
- # %b body
- # %i iconname (including its path)
- # %I iconname (without its path)
- # %p progress value if set ([ 0%] to [100%]) or nothing
- # %n progress value if set without any extra characters
- # %% Literal %
- # Markup is allowed
- format = "<b>%s</b>\n%b"
- # Alignment of message text.
- # Possible values are "left", "center" and "right".
- alignment = left
- # Show age of message if message is older than show_age_threshold
- # seconds.
- # Set to -1 to disable.
- show_age_threshold = 60
- # Split notifications into multiple lines if they don't fit into
- # geometry.
- word_wrap = yes
- # When word_wrap is set to no, specify where to ellipsize long lines.
- # Possible values are "start", "middle" and "end".
- ellipsize = middle
- # Ignore newlines '\n' in notifications.
- ignore_newline = no
- # Merge multiple notifications with the same content
- stack_duplicates = true
- # Hide the count of merged notifications with the same content
- hide_duplicate_count = false
- # Display indicators for URLs (U) and actions (A).
- show_indicators = yes
- ### Icons ###
- # Align icons left/right/off
- icon_position = off
- # Scale larger icons down to this size, set to 0 to disable
- max_icon_size = 32
- # Paths to default icons.
- icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
- ### History ###
- # Should a notification popped up from history be sticky or timeout
- # as if it would normally do.
- sticky_history = yes
- # Maximum amount of notifications kept in history
- history_length = 20
- ### Misc/Advanced ###
- # dmenu path.
- dmenu = /usr/bin/dmenu -p dunst:
- # Browser for opening urls in context menu.
- browser = /usr/bin/firefox -new-tab
- # Always run rule-defined scripts, even if the notification is suppressed
- always_run_script = true
- # Define the title of the windows spawned by dunst
- title = Dunst
- # Define the class of the windows spawned by dunst
- class = Dunst
- # Print a notification on startup.
- # This is mainly for error detection, since dbus (re-)starts dunst
- # automatically after a crash.
- startup_notification = false
- ### Legacy
- # Use the Xinerama extension instead of RandR for multi-monitor support.
- # This setting is provided for compatibility with older nVidia drivers that
- # do not support RandR and using it on systems that support RandR is highly
- # discouraged.
- #
- # By enabling this setting dunst will not be able to detect when a monitor
- # is connected or disconnected which might break follow mode if the screen
- # layout changes.
- force_xinerama = false
- # Experimental features that may or may not work correctly. Do not expect them
- # to have a consistent behaviour across releases.
- [experimental]
- # Calculate the dpi to use on a per-monitor basis.
- # If this setting is enabled the Xft.dpi value will be ignored and instead
- # dunst will attempt to calculate an appropriate dpi value for each monitor
- # using the resolution and physical size. This might be useful in setups
- # where there are multiple screens with very different dpi values.
- per_monitor_dpi = false
- [shortcuts]
- # Shortcuts are specified as [modifier+][modifier+]...key
- # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
- # "mod3" and "mod4" (windows-key).
- # Xev might be helpful to find names for keys.
- # Close notification.
- close = ctrl+space
- # Close all notifications.
- close_all = ctrl+shift+space
- # Redisplay last message(s).
- # On the US keyboard layout "grave" is normally above TAB and left
- # of "1". Make sure this key actually exists on your keyboard layout,
- # e.g. check output of 'xmodmap -pke'
- history = ctrl+grave
- # Context menu.
- context = ctrl+shift+period
- [urgency_low]
- # IMPORTANT: colors have to be defined in quotation marks.
- # Otherwise the "#" and following would be interpreted as a comment.
- background = "#000000"
- foreground = "#67C8FF"
- frame_color = "#67C8FF"
- timeout = 5
- # Icon for notifications with low urgency, uncomment to enable
- #icon = /path/to/icon
- [urgency_normal]
- background = "#000000"
- foreground = "#FF1493"
- frame_color = "#FF1493"
- timeout = 5
- # Icon for notifications with normal urgency, uncomment to enable
- #icon = /path/to/icon
- [urgency_critical]
- background = "#000000"
- foreground = "#FF0000"
- frame_color = "#FF0000"
- timeout = 10
- # Icon for notifications with critical urgency, uncomment to enable
- #icon = /path/to/icon
- # Every section that isn't one of the above is interpreted as a rules to
- # override settings for certain messages.
- # Messages can be matched by "appname", "summary", "body", "icon", "category",
- # "msg_urgency" and you can override the "timeout", "urgency", "foreground",
- # "background", "new_icon" and "format".
- # Shell-like globbing will get expanded.
- #
- # SCRIPTING
- # You can specify a script that gets run when the rule matches by
- # setting the "script" option.
- # The script will be called as follows:
- # script appname summary body icon urgency
- # where urgency can be "LOW", "NORMAL" or "CRITICAL".
- #
- # NOTE: if you don't want a notification to be displayed, set the format
- # to "".
- # NOTE: It might be helpful to run dunst -print in a terminal in order
- # to find fitting options for rules.
- #[espeak]
- # summary = "*"
- # script = dunst_espeak.sh
- #[script-test]
- # summary = "*script*"
- # script = dunst_test.sh
- #[ignore]
- # # This notification will not be displayed
- # summary = "foobar"
- # format = ""
- #[history-ignore]
- # # This notification will not be saved in history
- # summary = "foobar"
- # history_ignore = yes
- [signed_on]
- appname = Pidgin
- summary = "*signed on*"
- urgency = low
- [signed_off]
- appname = Pidgin
- summary = *signed off*
- urgency = low
- [says]
- appname = Pidgin
- summary = *says*
- urgency = normal
- # vim: ft=cfg
- ============================================================================================================================
- ## Firefox
- ## edit preferences:
- # Gerneral:
- Check Spelling as You Type (off)
- Automatically update search engines (off)
- # Home:
- Home Page: https://start.duckduckgo.com
- Tops Sites (off)
- Recommended by Pocket (off)
- Highlights (off)
- Snippets (off)
- # Search:
- Defaults Search Engine (duckduckgo)
- Turn off all search suggestions
- remove all search engines but duckduckgo
- # Provacy & security:
- Ask to save logins (off)
- History (custom)
- Always in private browser (on)
- remember browsing and download history (off)
- remember search and form history (off)
- Clear hisotry when FF closes (yes), settings (all yes)
- cookies:
- keep until I close FF
- third party (never)
- addrs bar:
- browsing hsitory (no)
- Bookmarks (yes)
- open tabs (yes)
- Tracjing protection (always)
- do not track (always)
- prevent accessability (yes)
- allow ff studies (no)
- # install addons:
- HTTPSeverywhere
- privacy badger
- cookie autodelete
- noscript
- ublock origin
- umatrix
- Decentraleyes
- # delete all bookmarks
- # about config tweaks:
- privacy.firstparty.isolate = true
- A result of the Tor Uplift effort, this preference isolates all browser identifier sources (e.g. cookies) to the first party domain, with the goal of preventing tracking across different domains. (Don't do this if you are using the Firefox Addon "Cookie AutoDelete" with Firefox v58 or below.)
- privacy.resistFingerprinting = true
- A result of the Tor Uplift effort, this preference makes Firefox more resistant to browser fingerprinting.
- privacy.trackingprotection.enabled = true
- This is Mozilla’s new built-in tracking protection. It uses Disconnect.me filter list, which is redundant if you are already using uBlock Origin 3rd party filters, therefore you should set it to false if you are using the add-on functionalities.
- browser.cache.offline.enable = false
- Disables offline cache.
- browser.safebrowsing.malware.enabled = false
- Disable Google Safe Browsing malware checks. Security risk, but privacy improvement.
- browser.safebrowsing.phishing.enabled = false
- Disable Google Safe Browsing and phishing protection. Security risk, but privacy improvement.
- browser.send_pings = false
- The attribute would be useful for letting websites track visitors’ clicks.
- browser.sessionstore.max_tabs_undo = 0
- Even with Firefox set to not remember history, your closed tabs are stored temporarily at Menu -> History -> Recently Closed Tabs.
- browser.urlbar.speculativeConnect.enabled = false
- Disable preloading of autocomplete URLs. Firefox preloads URLs that autocomplete when a user types into the address bar, which is a concern if URLs are suggested that the user does not want to connect to. Source
- dom.battery.enabled = false
- Website owners can track the battery status of your device. Source
- dom.event.clipboardevents.enabled = false
- Disable that websites can get notifications if you copy, paste, or cut something from a web page, and it lets them know which part of the page had been selected.
- geo.enabled = false
- Disables geolocation.
- media.eme.enabled = false
- Disables playback of DRM-controlled HTML5 content, which, if enabled, automatically downloads the Widevine Content Decryption Module provided by Google Inc. Details
- DRM-controlled content that requires the Adobe Flash or Microsoft Silverlight NPAPI plugins will still play, if installed and enabled in Firefox.
- media.gmp-widevinecdm.enabled = false
- Disables the Widevine Content Decryption Module provided by Google Inc., used for the playback of DRM-controlled HTML5 content. Details
- media.navigator.enabled = false
- Websites can track the microphone and camera status of your device.
- network.cookie.cookieBehavior = 1
- Disable cookies
- 0 = Accept all cookies by default
- 1 = Only accept from the originating site (block third-party cookies)
- 2 = Block all cookies by default
- network.cookie.lifetimePolicy = 2
- cookies are deleted at the end of the session
- 0 = Accept cookies normally
- 1 = Prompt for each cookie
- 2 = Accept for current session only
- 3 = Accept for N days
- network.http.referer.trimmingPolicy = 2
- Send only the scheme, host, and port in the Referer header
- 0 = Send the full URL in the Referer header
- 1 = Send the URL without its query string in the Referer header
- 2 = Send only the scheme, host, and port in the Referer header
- network.http.referer.XOriginPolicy = 2
- Only send Referer header when the full hostnames match. (Note: if you notice significant breakage, you might try 1 combined with an XOriginTrimmingPolicy tweak below.) Source
- 0 = Send Referer in all cases
- 1 = Send Referer to same eTLD sites
- 2 = Send Referer only when the full hostnames match
- network.http.referer.XOriginTrimmingPolicy = 2
- When sending Referer across origins, only send scheme, host, and port in the Referer header of cross-origin requests. Source
- 0 = Send full url in Referer
- 1 = Send url without query string in Referer
- 2 = Only send scheme, host, and port in Referer
- webgl.disabled = true
- WebGL is a potential security risk. Source
- browser.sessionstore.privacy_level = 2
- This preference controls when to store extra information about a session: contents of forms, scrollbar positions, cookies, and POST data. Details
- 0 = Store extra session data for any site. (Default starting with Firefox 4.)
- 1 = Store extra session data for unencrypted (non-HTTPS) sites only. (Default before Firefox 4.)
- 2 = Never store extra session data.
- network.IDN_show_punycode = true
- Not rendering IDNs as their Punycode equivalent leaves you open to phishing attacks that can be very difficult to notice. Source
- extensions.blocklist.url = https://blocklists.settings.services.mozilla.com/v1/blocklist/3/%20/%20/
- Limit the amount of identifiable information sent when requesting the Mozilla harmful extension blocklist.
- Optionally, the blocklist can be disabled entirely by setting extensions.blocklist.enabled to false for increased privacy, but decreased security. Source
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement