diff options
author | Johannes Löthberg <johannes@kyriasis.com> | 2016-01-14 16:46:21 +0000 |
---|---|---|
committer | Johannes Löthberg <johannes@kyriasis.com> | 2016-01-14 16:46:21 +0000 |
commit | 7666a9cc93c079cd3a61ea8a7d4cf3103a74c56e (patch) | |
tree | e1e1b32e1666bead6a6ac7327bd2e253e989e80e | |
parent | cee153e1d03f215139ba6d74a8cd8fe039213992 (diff) | |
parent | 81873932548d4dda5345c19c3a635d53e25da061 (diff) | |
download | dotfiles-7666a9cc93c079cd3a61ea8a7d4cf3103a74c56e.tar.xz |
Merge remote-tracking branch 'k-kyrias/master' into theos
57 files changed, 4330 insertions, 390 deletions
@@ -1,4 +1,4 @@ install: - -ln -s "$(HOME)/.config/zsh/.zshenv" "$(HOME)/.zshenv" - -ln -s "$(HOME)/.config/pentadactyl/pentadactylrc" "$(HOME)/.pentadactylrc" - -ln -sn "$(HOME)/.config/ssh" "$(HOME)/.ssh" + -ln -sf "$(PWD)/zsh/.zshenv" "$(HOME)/.zshenv" + -ln -sfn "$(PWD)/ssh" "$(HOME)/.ssh" + -ln -sfn "$(PWD)/gnupg" "$(HOME)/.gnupg" diff --git a/X11/XCompose b/X11/XCompose index 0097034..406e921 100644 --- a/X11/XCompose +++ b/X11/XCompose @@ -18,6 +18,9 @@ include "%L" <Multi_key> <l> <a> : "λ" U03BB <Multi_key> <m> <u> : "µ" U00B5 +<Multi_key> <d> <e> <l> : "δ" U03B4 +<Multi_key> <D> <e> <l> : "Δ" U0394 + # Quotes <Multi_key> <quotedbl> <bracketleft> : "“" U201C <Multi_key> <quotedbl> <bracketright> : "”" U201D @@ -74,14 +77,6 @@ include "%L" <Multi_key> <b> <h> <s> : "☣" U2623 # BIOHAZARD SIGN <Multi_key> <r> <a> <s> : "☢" U2622 # RADIOACTIVE SIGN -<Multi_key> <S> <W> : "卐" U262D <Multi_key> <colon> <bar> <bar> : "ಠ_ಠ" -<Multi_key> <s> <a> : U00A0 -<Multi_key> <s> <b> : U2007 -<Multi_key> <s> <c> : U2008 -<Multi_key> <s> <d> : U2009 -<Multi_key> <s> <e> : U200A -<Multi_key> <s> <f> : U202F -<Multi_key> <s> <g> : U205F -<Multi_key> <s> <h> : U3000 +<Multi_key> <t> <r> <a> <i> <n> <s> : "🚂 🚊 🚉 🚞 🚆 🚄 🚅 🚈 🚇 🚝 🚋 🚃 🚟" diff --git a/X11/xorg.conf.d/20-intel.conf b/X11/xorg.conf.d/20-intel.conf new file mode 100644 index 0000000..0335cbe --- /dev/null +++ b/X11/xorg.conf.d/20-intel.conf @@ -0,0 +1,5 @@ +Section "Device" + Identifier "Intel Graphics" + Driver "intel" + Option "TearFree" "true" +EndSection diff --git a/X11/xorg.conf.d/90-keyboard.conf b/X11/xorg.conf.d/90-keyboard.conf new file mode 100644 index 0000000..c7c9b05 --- /dev/null +++ b/X11/xorg.conf.d/90-keyboard.conf @@ -0,0 +1,6 @@ +Section "InputClass" + Identifier "Keyboard Defaults" + MatchIsKeyboard "on" + Option "XkbLayout" "dvorak,us" + Option "XkbOptions" "caps:escape,compose:ralt,grp_led:caps,grp:menu_toggle" +EndSection diff --git a/autostart/clipit-startup.desktop b/autostart/clipit-startup.desktop new file mode 100644 index 0000000..017280b --- /dev/null +++ b/autostart/clipit-startup.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=ClipIt +Comment=Clipboard Manager +Icon=clipit-trayicon +Exec=clipit +Terminal=false +Type=Application +OnlyShowIn=i3; diff --git a/autostart/dunst.desktop b/autostart/dunst.desktop new file mode 100644 index 0000000..53e0de4 --- /dev/null +++ b/autostart/dunst.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=Dunst +Comment=Customizable and lightweight notification-daemon +Exec=dunst +Terminal=false +Type=Application +StartupNotify=false diff --git a/autostart/polkit-mate-authentication-agent-1.desktop b/autostart/polkit-mate-authentication-agent-1.desktop new file mode 100644 index 0000000..d5279b2 --- /dev/null +++ b/autostart/polkit-mate-authentication-agent-1.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=PolicyKit Authentication Agent +Comment=PolicyKit Authentication Agent for the MATE Desktop +Exec=/usr/lib/mate-polkit/polkit-mate-authentication-agent-1 +Terminal=false +Type=Application +Categories= +NoDisplay=true diff --git a/clipit/clipitrc b/clipit/clipitrc index b689a89..1cdf5f5 100644 --- a/clipit/clipitrc +++ b/clipit/clipitrc @@ -3,8 +3,8 @@ use_copy=true use_primary=true synchronize=true automatic_paste=true -show_indexes=false -save_uris=false +show_indexes=true +save_uris=true use_rmb_menu=true save_history=true history_limit=50 diff --git a/dunst/dunstrc b/dunst/dunstrc index 07c5114..3a5132b 100644 --- a/dunst/dunstrc +++ b/dunst/dunstrc @@ -1,5 +1,5 @@ [global] - font = Terminus 10 + font = Terminus 14 allow_markup = yes format = "%a\n%s %p\n%b" sort = no @@ -8,7 +8,7 @@ show_age_threshold = 60 word_wrap = yes ignore_newline = no - geometry = "550x0-1+18" + geometry = "600x0-1+18" transparency = 15 idle_threshold = 120 monitor = 0 @@ -6,7 +6,7 @@ [alias] amend = commit --amend --verbose br = branch - ci = commit --verbose + ci = commit --verbose --signoff co = checkout di = diff dc = diff --cached @@ -14,6 +14,7 @@ follow = log --oneline --follow --stat --summary -- last = log -1 HEAD lg = log --oneline --decorate + lol = log --oneline --graph --decorate --all mend = commit --amend --reuse-message HEAD mrproper = !git reset --hard HEAD && git clean -fdx ours = !git checkout --ours $@ @@ -21,7 +22,6 @@ rbc = rebase --continue rbs = rebase -i re = rebase - rec = rebase --continue st = status stat = diff --stat statc = diff --cached --stat @@ -34,6 +34,7 @@ wdiff = diff --word-diff wshow = show --word-diff fpush = push --force-with-lease + shortdesc = !git --no-pager log -1 --pretty='tformat:%h (%s, %ad)' --date=short [advice] detachedHead = false @@ -122,3 +123,5 @@ [credential "https://github.com"] username = kyrias helper = pass +[rerere] + enabled = true diff --git a/gtk-2.0/gtkrc-2.0 b/gtk-2.0/gtkrc-2.0 index 42d6b91..d5156f4 100644 --- a/gtk-2.0/gtkrc-2.0 +++ b/gtk-2.0/gtkrc-2.0 @@ -3,7 +3,7 @@ gtk-theme-name="Numix" gtk-icon-theme-name="elementary-xfce-darkest" -gtk-font-name="Ubuntu 9" +gtk-font-name="Ubuntu 10" gtk-cursor-theme-name="Neutral" gtk-cursor-theme-size=0 gtk-toolbar-style=GTK_TOOLBAR_BOTH diff --git a/gtk-3.0/settings.ini b/gtk-3.0/settings.ini index 07a3f6e..e63aa5a 100644 --- a/gtk-3.0/settings.ini +++ b/gtk-3.0/settings.ini @@ -1,7 +1,7 @@ [Settings] gtk-theme-name=Numix -gtk-icon-theme-name=elementary-xfce-darkest -gtk-font-name=Ubuntu 9 +gtk-icon-theme-name=elementary +gtk-font-name=Ubuntu 10 gtk-cursor-theme-size=0 gtk-toolbar-style=GTK_TOOLBAR_BOTH gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR diff --git a/htop/htoprc b/htop/htoprc index 05610e3..7d23a6f 100644 --- a/htop/htoprc +++ b/htop/htoprc @@ -6,17 +6,17 @@ sort_direction=1 hide_threads=0 hide_kernel_threads=0 hide_userland_threads=0 -shadow_other_users=0 -show_thread_names=0 -highlight_base_name=0 +shadow_other_users=1 +show_thread_names=1 +highlight_base_name=1 highlight_megabytes=1 -highlight_threads=0 -tree_view=0 +highlight_threads=1 +tree_view=1 header_margin=1 -detailed_cpu_time=0 +detailed_cpu_time=1 cpu_count_from_zero=0 update_process_names=0 -account_guest_in_cpu_meter=0 +account_guest_in_cpu_meter=1 color_scheme=0 delay=15 left_meters=AllCPUs Memory Swap @@ -7,7 +7,7 @@ from i3pystatus import Status status = Status(standalone=True) status.register("clock", - format="%y-%m-%d %H:%M:%S",) + format="%y-%m-%d %H:%M:%S%z",) status.register("battery", format="⚡:{percentage:.2f}% {remaining:%E%hh:%Mm}{status}", @@ -18,7 +18,7 @@ status.register("battery", "CHR": "↑", "FULL": "=", }, - battery_ident="BAT1",) + battery_ident="BAT0",) status.register("temp", @@ -36,8 +36,8 @@ status.register("pulseaudio", # },) status.register("network", - interface="wlp3s0", - format_up="{v4cidr} {quality:3.0f}%",) + interface="wlp4s0", + format_up="{essid:.10s}: {v4cidr} {quality:3.0f}%",) # Shows disk usage of / # Format: @@ -1,7 +1,7 @@ set $mod Mod4 #font pango:visitor tt2 brk 10 -font pango:Source Code Pro 8 +font pango:Source Code Pro 9 floating_modifier $mod bindsym $mod+Return exec termite @@ -21,12 +21,12 @@ bindsym $mod+Shift+j move down bindsym $mod+Shift+k move up bindsym $mod+Shift+l move right -bindsym $mod+b split h +bindsym $mod+w split h bindsym $mod+v split v bindsym $mod+f fullscreen bindsym $mod+s layout stacking -bindsym $mod+w layout tabbed +bindsym $mod+t layout tabbed bindsym $mod+e layout toggle split bindsym $mod+Shift+space floating toggle # change focus between tiling / floating windows @@ -111,7 +111,7 @@ bindsym $mod+r mode "resize" # i3bar bar { - status_command python ~/.config/i3/bar.py + status_command ~/.local/venv/bin/python ~/.config/i3/bar.py position bottom workspace_buttons yes colors { @@ -125,18 +125,15 @@ bar { } } +for_window [class="Gifview"] floating enable + + bindsym $mod+Shift+g exec --no-startup-id setxkbmap us #bindsym $mod+Shift+u exec --no-startup-id setxkbmap dvp bindsym $mod+Shift+u exec --no-startup-id setxkbmap dvorak -# TrackPoint scrolling -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 1 -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 2 -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Timeout" 150 -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5 -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Middle Button Emulation" 1 -exec --no-startup-id xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Inertia" 25 -exec --no-startup-id xinput set-prop "SynPS/2 Synaptics TouchPad" "Synaptics Off" 1 +bindsym XF86MonBrightnessUp exec --no-startup-id xbacklight -inc 10 +bindsym XF86MonBrightnessDown exec --no-startup-id xbacklight -dec 10 # control ncmpcpp / mpd from media keys bindsym XF86AudioPlay exec --no-startup-id mpc toggle @@ -144,19 +141,32 @@ bindsym XF86AudioStop exec --no-startup-id mpc stop bindsym XF86AudioNext exec --no-startup-id mpc next bindsym XF86AudioPrev exec --no-startup-id mpc prev + # control PulseAudio from media keys -bindsym XF86AudioMute exec volumecontrol.bash mute -bindsym XF86Back exec volumecontrol.bash lower -bindsym XF86AudioLowerVolume exec volumecontrol.bash lower -bindsym XF86Forward exec volumecontrol.bash raise -bindsym XF86AudioRaiseVolume exec volumecontrol.bash raise +bindsym XF86AudioMute exec volumecontrol mute +bindsym XF86AudioMicMute exec volumecontrol mute-mic +bindsym XF86AudioLowerVolume exec volumecontrol lower +bindsym XF86AudioRaiseVolume exec volumecontrol raise + + bindsym XF86ScreenSaver exec screenlock.bash + new_window 1pixel -bindsym $mod+t border normal -bindsym $mod+y border 1pixel -bindsym $mod+u border none +bindsym $mod+b border normal +bindsym $mod+p border 1pixel +bindsym $mod+n border none + + +# Make the currently focused window a scratchpad +bindsym $mod+Shift+minus move scratchpad + +# Show the first scratchpad window +bindsym $mod+minus scratchpad show + + +# TrackPoint scrolling +exec setup-trackpoint -for_window [class="Gifview"] floating enable exec --no-startup-id dex -s $HOME/.config/autostart -a -e i3 @@ -12,6 +12,7 @@ Account theos MaildirStore theos-local Path ~/mail/ Inbox ~/mail/inbox +SubFolders Verbatim Channel theos Master :theos-remote: diff --git a/mpv/mpv.conf b/mpv/mpv.conf index d366707..38b7961 100644 --- a/mpv/mpv.conf +++ b/mpv/mpv.conf @@ -1,12 +1,12 @@ demuxer-thread=yes -hwdec=auto +hwdec=vaapi vo=opengl no-osc # Use with disabled flat-volumes in /etc/pulse/daemon.conf -volume=15 +volume=100 softvol=yes softvol-max=400 @@ -14,3 +14,4 @@ no-embeddedfonts sub-auto=fuzzy sub-text-font="Source Sans Pro" osd-font="Source Sans Pro" +sub-use-margins @@ -4,13 +4,15 @@ port 587 protocol smtp tls on auth on -domain leeloo.kyriasis.com +domain zorg.kyriasis.com from johannes@kyriasis.com user kyrias passwordeval "pass show mail/johannes@kyriasis.com" syslog on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt +dsn_notify failure,delay +dsn_return full account jlgmail host smtp.gmail.com diff --git a/mutt/muttrc b/mutt/muttrc index ddfd9f6..6166c72 100644 --- a/mutt/muttrc +++ b/mutt/muttrc @@ -24,22 +24,68 @@ set sleep_time = 0 # No delay when opening a maildir! set mbox_type = Maildir set folder = "$HOME/mail" -set header_cache = "$XDG_CONFIG_HOME/mutt/cache/headers" # where to store headers -set message_cachedir = "$XDG_CONFIG_HOME/mutt/cache/" # where to store bodies +set tmpdir = "$XDG_CACHE_HOME/mutt/temp" # where to keep temp files +set message_cachedir = "$XDG_CACHE_HOME/mutt/cache/" # where to store bodies +set header_cache = "$XDG_CACHE_HOME/mutt/cache/headers" # where to store headers set certificate_file = "$XDG_CONFIG_HOME/mutt/certificates" # where to store certs set mailcap_path = "$XDG_CONFIG_HOME/mutt/mailcap" # entries for filetypes -set tmpdir = "$XDG_CONFIG_HOME/mutt/temp" # where to keep temp files set signature = "$XDG_CONFIG_HOME/mutt/sig" # my signature file + set spoolfile = "+inbox" -set mbox = "+archives" -set postponed = "+Drafts" -set record = "+Sent" -mailboxes +inbox +Sent +Drafts +Trash +archives -mailboxes +Spam +Ham +learn-spam +learn-ham +ccna -mailboxes +arch-dev-public +aur-general +arch-bugs +arch-mirrors +arch-women +pacman-dev -mailboxes +openldap-technical +opensmtpd +openssh-unix-dev +isync-devel +johannes-lothberg-gmail +lojban +Notes +set mbox = "+archive" +set postponed = "+drafts" +set record = "+sent" + +mailboxes +inbox +sent +drafts +trash +archive +mailboxes +Spam +Ham +learn-spam +learn-ham + +mailboxes +arch-dev-public +arch-bugs +arch-mirrors +aur-general +aur-requests +mailboxes +arch-women +pacman-dev + +mailboxes +isync-devel +opensmtpd + +mailboxes +openldap-technical +openssh-unix-dev + +mailboxes +johannes-lothberg-gmail +lojban +Notes +ccna + mailboxes ~/5mail/inbox +set virtual_spoolfile = yes +set nm_record = yes +set nm_record_tags = "-inbox,sent,me" +set nm_default_uri = "notmuch:///home/kyrias/mail" + +virtual-mailboxes \ + "inbox" "notmuch://?query=tag:inbox and NOT tag:archive" \ + "sent" "notmuch://?query=tag:sent" \ + "drafts" "notmuch://?query=tag:drafts" \ + "trash" "notmuch://?query=tag:trash" \ + "unread" "notmuch://?query=tag:unread" \ + "archive" "notmuch://?query=tag:archive" \ + \ + "spam" "notmuch://?query=tag:spam" \ + "ham" "notmuch://?query=tag:ham" \ + "learn-spam" "notmuch://?query=tag:learn-spam" \ + "learn-ham" "notmuch://?query=tag:learn-ham" \ + \ + "arch-dev-public" "notmuch://?query=tag:arch-dev-public" \ + "arch-bugs" "notmuch://?query=tag:arch-bugs" \ + "arch-mirrors" "notmuch://?query=tag:arch-mirrors" \ + "arch-general" "notmuch://?query=tag:arch-general" \ + "aur-requests" "notmuch://?query=tag:aur-requests" \ + "aur-general" "notmuch://?query=tag:aur-general" \ + "aur-dev" "notmuch://?query=tag:aur-dev" \ + "pacman-dev" "notmuch://?query=tag:pacman-dev" \ + "arch-women" "notmuch://?query=tag:arch-women" \ + "isync-devel" "notmuch://?query=tag:isync-devel" \ + "opensmtpd" "notmuch://?query=tag:opensmtpd" \ + "openldap-technical" "notmuch://?query=tag:openldap-technical" \ + "openssh-unix-dev" "notmuch://?query=tag:openssh-unix-dev" \ + "johannes-lothberg-gmail" "notmuch://?query=tag:johannes-lothberg-gmail" \ + "lojban" "notmuch://?query=tag:lojban" \ + "git" "notmuch://?query=tag:git" \ + "ccna" "notmuch://?query=tag:ccna" + set query_command='goobook -c "$XDG_CONFIG_HOME/goobookrc" query "%s"' macro index,pager A '<pipe-message>goobook -c "$XDG_CONFIG_HOME/goobookrc" add<return>' \ 'add the sender address to Google contacts' @@ -87,9 +133,11 @@ set ignore_list_reply_to = yes # Ignore mangled Reply-To:'s from MLs set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+" alternative_order text/plain text/enriched text/html - +macro index x "<change-vfolder>?" "change vfolder" macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox" macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox" +macro index,pager d "<modify-labels>+deleted -inbox -unread<enter>" "Mark an email as deleted" +bind index,pager <Esc>D delete-message bind index gg first-entry bind index G last-entry @@ -108,8 +156,8 @@ bind pager R group-reply bind compose P postpone-message bind index P recall-message -# Move message to archives -macro index,pager a "<save-message>=archives<enter>" +# Move message to archive +macro index,pager a "<modify-labels>-inbox +archive<enter>" # View attachments properly. bind attach <return> view-mailcap @@ -126,8 +174,10 @@ source ~/.config/mutt/themes/comidia subscribe arch-dev-public@archlinux.org subscribe aur-general@archlinux.org +subscribe aur-dev@archlinux.org subscribe pacman-dev@archlinux.org subscribe lojban@googlegroups.com subscribe openldap-technical@openldap.org subscribe misc@opensmtpd.org +subscribe git@vger.kernel.org lists linux-wireless@vger.kernel.org diff --git a/nvim/after/ftplugin/haskell.vim b/nvim/after/ftplugin/haskell.vim new file mode 100644 index 0000000..e7252f6 --- /dev/null +++ b/nvim/after/ftplugin/haskell.vim @@ -0,0 +1,4 @@ +set tabstop=4 +set softtabstop=4 +set shiftwidth=4 +set expandtab diff --git a/nvim/after/ftplugin/python.vim b/nvim/after/ftplugin/python.vim new file mode 100644 index 0000000..2a3d549 --- /dev/null +++ b/nvim/after/ftplugin/python.vim @@ -0,0 +1,4 @@ +setlocal shiftwidth=4 +setlocal tabstop=4 +setlocal softtabstop=4 +setlocal expandtab diff --git a/nvim/after/syntax/PKGBUILD.vim b/nvim/after/syntax/PKGBUILD.vim new file mode 100644 index 0000000..35ca6bd --- /dev/null +++ b/nvim/after/syntax/PKGBUILD.vim @@ -0,0 +1,320 @@ +" Vim syntax file +" Language: PKGBUILD +" Maintainer: Alessio 'mOLOk' Bolognino <themolok at gmail.com> +" Last Change: 2007/05/08 +" Version Info: PKGBUILD-0.2 (colorphobic) + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +let b:main_syntax = "sh" +let b:is_bash = 1 +runtime! syntax/sh.vim + +" case on +syn case match + +" pkgname +" FIXME if '=' is in pkgname/pkgver, it highlights whole string, not just '=' +syn keyword pb_k_pkgname pkgname contained +syn match pbValidPkgname /\([[:alnum:]]\|+\|-\|_\){,32}/ contained contains=pbIllegalPkgname +syn match pbIllegalPkgname /[[:upper:]]\|[^[:alnum:]-+_=]\|=.*=\|=['"]\?.\{33,\}['"]\?/ contained +syn match pbPkgnameGroup /^pkgname=.*/ contains=pbIllegalPkgname,pb_k_pkgname,shDoubleQuote,shSingleQuote + +" pkgbase +" FIXME if '=' is in pkgbase/pkgname/pkgver, it highlights whole string, not just '=' +syn keyword pb_k_pkgbase pkgbase contained +syn match pbValidPkgbase /\([[:alnum:]]\|+\|-\|_\){,32}/ contained contains=pbIllegalPkgbase +syn match pbIllegalPkgbase /[[:upper:]]\|[^[:alnum:]-+_=]\|=.*=\|=['"]\?.\{33,\}['"]\?/ contained +syn match pbPkgbaseGroup /^pkgbase=.*/ contains=pbIllegalPkgbase,pb_k_pkgbase,shDoubleQuote,shSingleQuote + +" pkgver +syn keyword pb_k_pkgver pkgver contained +syn match pbValidPkgver /\([[:alnum:]]\|\.\|+\|_\)/ contained contains=pbIllegalPkgver +syn match pbIllegalPkgver /[^[:alnum:]+=\.\_]\|=.*=/ contained +syn match pbPkgverGroup /^pkgver=.*/ contains=pbIllegalPkgver,pbValidPkgver,pb_k_pkgver,shDoubleQuote,shSingleQuote + +" pkgrel +syn keyword pb_k_pkgrel pkgrel contained +syn match pbValidPkgrel /[[:digit:]]*/ contained contains=pbIllegalPkgrel +syn match pbIllegalPkgrel /[^[:digit:]=]\|=.*=/ contained +syn match pbPkgrelGroup /^pkgrel=.*/ contains=pbIllegalPkgrel,pbValidPkgrel,pb_k_pkgrel,shDoubleQuote,shSingleQuote + +" pkgdesc +syn keyword pb_k_desc pkgdesc contained +" 90 chars: 80 for description, 8 for pkgdesc and 2 for '' +syn match pbIllegalPkgdesc /.\{90,}\|=['"]\?.*['" ]\+[iI][sS] [aA]/ contained contains=pbPkgdescSign +syn match pbValidPkgdesc /[^='"]\.\{,80}/ contained contains=pbIllegalPkgdesc +syn match pbPkgdescGroup /^pkgdesc=.*/ contains=pbIllegalPkgdesc,pb_k_desc,pbValidPkgdesc,shDoubleQuote,shSingleQuote +syn match pbPkgdescSign /[='"]/ contained + +" epoch +syn keyword pb_k_epoch epoch contained +syn match pbValidEpoch /[[:digit:]]*/ contained contains=pbIllegalEpoch +syn match pbIllegalEpoch /[^[:digit:]=]\|=.*=/ contained +syn match pbEpochGroup /^epoch=.*/ contains=pbIllegalEpoch,pbValidEpoch,pb_k_epoch,shDoubleQuote,shSingleQuote + +" url +syn keyword pb_k_url url contained +syn match pbValidUrl /['"]*\(https\|http\|ftp\)\:\/.*\.\+.*/ contained + +syn match pbIllegalUrl /[^=]/ contained contains=pbValidUrl +syn match pbUrlGroup /^url=.*/ contains=pbValidUrl,pb_k_url,pbIllegalUrl,shDoubleQuote,shSingleQuote + +" license +syn keyword pb_k_license license contained +" echo $(pacman -Ql licenses | grep '/usr/share/licenses/common/' | cut -d'/' -f6 | sort -u) +syn keyword pbLicense AGPL AGPL3 Apache APACHE Artistic2.0 CCPL CDDL CPL EPL FDL FDL1.2 FDL1.3 GPL GPL2 GPL3 LGPL LGPL2.1 LGPL3 LPPL MPL PerlArtistic PHP PSF RUBY W3C ZPL contained +" special cases from https://wiki.archlinux.org/index.php/Arch_Packaging_Standards +syn keyword pbLicenseSpecial BSD MIT ZLIB Python contained +syn match pbLicenseCustom /custom\(:[[:alnum:]]*\)*/ contained +syn match pbIllegalLicense /[^='"() ]/ contained contains=pbLicenseCustom,pbLicenseSpecial,pbLicense +syn region pbLicenseGroup start=/^license=(/ end=/)/ contains=pb_k_license,pbLicenseCustom,pbLicenseSpecial,pbLicense,pbIllegalLicense + +" backup +syn keyword pb_k_backup backup contained +syn match pbValidBackup /\.\?[[:alpha:]]*\/[[:alnum:]\{\}+._$-]*]*/ contained +syn region pbBackupGroup start=/^backup=(/ end=/)/ contains=pb_k_backup,pbValidBackup,shDoubleQuote,shSingleQuote + +" arch +syn keyword pb_k_arch arch contained +syn keyword pbArch i686 x86_64 ppc any contained +syn match pbIllegalArch /[^='"() ]/ contained contains=pbArch +syn region pbArchGroup start=/^arch=(/ end=/)/ contains=pb_k_arch,pbArch,pbIllegalArch + +" groups +syn keyword pb_k_groups groups contained +syn match pbValidGroups /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbGroupsGroup start=/^groups=(/ end=/)/ contains=pb_k_groups,pbValidGroups,shDoubleQuote,shSingleQuote + +" depends +syn keyword pb_k_depends depends contained +syn match pbValidDepends /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbDependsGroup start=/^depends=(/ end=/)/ contains=pb_k_depends,pbValidDepends,shDoubleQuote,shSingleQuote + +" makedepends +syn keyword pb_k_makedepends makedepends contained +syn match pbValidMakedepends /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbMakedependsGroup start=/^makedepends=(/ end=/)/ contains=pb_k_makedepends,pbValidMakedepends,shDoubleQuote,shSingleQuote + +" optdepends +syn keyword pb_k_optdepends optdepends contained +syn match pbValidOptdepends /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbOptdependsGroup start=/^optdepends=(/ end=/)/ contains=pb_k_optdepends,pbValidOptdepends,shDoubleQuote,shSingleQuote + +" checkdepends +syn keyword pb_k_ckdepends checkdepends contained +syn match pbValidCkdepends /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbCkdependsGroup start=/^checkdepends=(/ end=/)/ contains=pb_k_ckdepends,pbValidCkdepends,shDoubleQuote,shSingleQuote + +" conflicts +syn keyword pb_k_conflicts conflicts contained +syn match pbValidConflicts /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbConflictsGroup start=/^conflicts=(/ end=/)/ contains=pb_k_conflicts,pbValidConflicts,shDoubleQuote,shSingleQuote + +" provides +syn keyword pb_k_provides provides contained +syn match pbValidProvides /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbProvidesGroup start=/^provides=(/ end=/)/ contains=pb_k_provides,pbValidProvides,shDoubleQuote,shSingleQuote + +" replaces +syn keyword pb_k_replaces replaces contained +syn match pbValidReplaces /\([[:alnum:]]\|+\|-\|_\)*/ contained +syn region pbReplacesGroup start=/^replaces=(/ end=/)/ contains=pb_k_replaces,pbValidReplaces,shDoubleQuote,shSingleQuote + +" install +" XXX remove install from bashStatement, fix strange bug +syn clear bashStatement +syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch + +syn keyword pb_k_install install contained +syn match pbValidInstall /\([[:alnum:]]\|\$\|+\|-\|_\)*\.install/ contained +syn match pbIllegalInstall /[^=]/ contained contains=pbValidInstall +syn match pbInstallGroup /^install=.*/ contains=pb_k_install,pbValidInstall,pbIllegalInstall,shDeref,shDoubleQuote,shSingleQuote + +" changelog +syn keyword pb_k_changelog changelog contained +syn match pbValidChangelog /\([[:alnum:]]\|\$\|+\|-\|_\)*/ contained +syn match pbIllegalChangelog /[^=]/ contained contains=pbValidChangelog +syn match pbChangelogGroup /^changelog=.*/ contains=pb_k_changelog,pbValidChangelog,pbIllegalChangelog,shDeref,shDoubleQuote,shSingleQuote + +" source: +" XXX remove source from shStatement, fix strange bug +syn clear shStatement +syn keyword shStatement xxx wait getopts return autoload whence printf true popd nohup enable r trap readonly fc fg kill ulimit umask disown stop pushd read history logout times local exit test pwd time eval integer suspend dirs shopt hash false newgrp bg print jobs continue functions exec help cd break unalias chdir type shift builtin let bind + +syn keyword pb_k_source source contained +syn match pbIllegalSource /\(http\|ftp\|https\).*\.\+\(dl\|download.\?\)\.\(sourceforge\|sf\).net/ +syn region pbSourceGroup start=/^source=(/ end=/)/ contains=pb_k_source,pbIllegalSource,shNumber,shDoubleQuote,shSingleQuote,pbDerefEmulation +syn match pbDerefEmulation /\$[{]\?[[:alnum:]_]*[}]\?/ contained +hi def link pbDerefEmulation PreProc + +" md5sums +syn keyword pb_k_md5sums md5sums contained +syn match pbIllegalMd5sums /[^='"()\/ ]/ contained contains=pbValidMd5sums +syn match pbValidMd5sums /\x\{32\}/ contained +syn region pbMd5sumsGroup start=/^md5sums/ end=/)/ contains=pb_k_md5sums,pbMd5Quotes,pbMd5Hash,pbIllegalMd5sums keepend +syn match pbMd5Quotes /'.*'\|".*"/ contained contains=pbMd5Hash,pbIllegalMd5sums +syn match pbMd5Hash /\x\+/ contained contains=pbValidMd5sums +hi def link pbMd5Quotes Keyword +hi def link pbMd5Hash Error +hi def link pbValidMd5sums Number + +" sha1sums +syn keyword pb_k_sha1sums sha1sums contained +syn match pbIllegalSha1sums /[^='"()\/ ]/ contained contains=pbValidSha1sums +syn match pbValidSha1sums /\x\{40\}/ contained +syn region pbSha1sumsGroup start=/^sha1sums/ end=/)/ contains=pb_k_sha1sums,pbSha1Quotes,pbSha1Hash,pbIllegalSha1sums keepend +syn match pbSha1Quotes /'.*'\|".*"/ contained contains=pbSha1Hash,pbIllegalSha1sums +syn match pbSha1Hash /\x\+/ contained contains=pbValidSha1sums +hi def link pbSha1Quotes Keyword +hi def link pbSha1Hash Error +hi def link pbValidSha1sums Number + +" sha256sums +syn keyword pb_k_sha256sums sha256sums contained +syn match pbIllegalSha256sums /[^='"()\/ ]/ contained contains=pbValidSha256sums +syn match pbValidSha256sums /\x\{64\}/ contained +syn region pbSha256sumsGroup start=/^sha256sums/ end=/)/ contains=pb_k_sha256sums,pbSha256Quotes,pbSha256Hash,pbIllegalSha256sums keepend +syn match pbSha256Quotes /'.*'\|".*"/ contained contains=pbSha256Hash,pbIllegalSha256sums +syn match pbSha256Hash /\x\+/ contained contains=pbValidSha256sums +hi def link pbSha256Quotes Keyword +hi def link pbSha256Hash Error +hi def link pbValidSha256sums Number + +" sha384sums +syn keyword pb_k_sha384sums sha384sums contained +syn match pbIllegalSha384sums /[^='"()\/ ]/ contained contains=pbValidSha384sums +syn match pbValidSha384sums /\x\{96\}/ contained +syn region pbSha384sumsGroup start=/^sha384sums/ end=/)/ contains=pb_k_sha384sums,pbSha384Quotes,pbSha384Hash,pbIllegalSha384sums keepend +syn match pbSha384Quotes /'.*'\|".*"/ contained contains=pbSha384Hash,pbIllegalSha384sums +syn match pbSha384Hash /\x\+/ contained contains=pbValidSha384sums +hi def link pbSha384Quotes Keyword +hi def link pbSha384Hash Error +hi def link pbValidSha384sums Number + +" sha512sums +syn keyword pb_k_sha512sums sha512sums contained +syn match pbIllegalSha512sums /[^='"()\/ ]/ contained contains=pbValidSha512sums +syn match pbValidSha512sums /\x\{128\}/ contained +syn region pbSha512sumsGroup start=/^sha512sums/ end=/)/ contains=pb_k_sha512sums,pbSha512Quotes,pbSha512Hash,pbIllegalSha512sums keepend +syn match pbSha512Quotes /'.*'\|".*"/ contained contains=pbSha512Hash,pbIllegalSha512sums +syn match pbSha512Hash /\x\+/ contained contains=pbValidSha512sums +hi def link pbSha512Quotes Keyword +hi def link pbSha512Hash Error +hi def link pbValidSha512sums Number + +" options +syn keyword pb_k_options options contained +syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|zipman\|purge\|upx\|optipng\|distcc\|color\|ccache\|check\|sign\|makeflags\|buildflags\)/ contained +syn match pbOptionsNeg /\!/ contained +syn match pbOptionsDeprec /no/ contained +syn region pbOptionsGroup start=/^options=(/ end=/)/ contains=pb_k_options,pbOptions,pbOptionsNeg,pbOptionsDeprec,pbIllegalOption +syn match pbIllegalOption /[^!"'()= ]/ contained contains=pbOptionsDeprec,pbOptions + +" noextract +syn match pbNoextract /[[:alnum:]+._${}-]\+/ contained +syn keyword pb_k_noextract noextract contained +syn region pbNoextractGroup start=/^noextract=(/ end=/)/ contains=pb_k_noextract,pbNoextract,shDoubleQuote,shSingleQuote + +" comments +syn keyword pb_k_maintainer Maintainer Contributor contained +syn match pbMaintainerGroup /Maintainer.*/ contains=pbMaintainer contained + +syn match pbDate /[0-9]\{4}\/[0-9]\{2}\/[0-9]\{2}/ contained + +syn cluster pbCommentGroup contains=pbTodo,pb_k_maintainer,pbMaintainerGroup,pbDate +syn keyword pbTodo contained COMBAK FIXME TODO XXX +syn match pbComment "^#.*$" contains=@pbCommentGroup +syn match pbComment "[^0-9]#.*$" contains=@pbCommentGroup + +" quotes are handled by sh.vim + +hi def link pbComment Comment +hi def link pbTodo Todo + +hi def link pbIllegalPkgname Error +hi def link pb_k_pkgname pbKeywords + +hi def link pbIllegalPkgbase Error +hi def link pb_k_pkgbase pbKeywords + +hi def link pbIllegalPkgver Error +hi def link pb_k_pkgver pbKeywords + +hi def link pbIllegalPkgrel Error +hi def link pb_k_pkgrel pbKeywords + +hi def link pbIllegalPkgdesc Error +hi def link pb_k_desc pbKeywords + +hi def link pbIllegalEpoch Error +hi def link pb_k_epoch pbKeywords + +hi def link pbIllegalUrl Error +hi def link pb_k_url pbKeywords + +hi def link pb_k_license pbKeywords +hi def link pbIllegalLicense Error + +hi def link pb_k_backup pbKeywords + +hi def link pb_k_arch pbKeywords +hi def link pbIllegalArch Error + +hi def link pb_k_groups pbKeywords +hi def link pb_k_makedepends pbKeywords +hi def link pb_k_optdepends pbKeywords +hi def link pb_k_ckdepends pbKeywords +hi def link pb_k_depends pbKeywords +hi def link pb_k_replaces pbKeywords +hi def link pb_k_conflicts pbKeywords +hi def link pb_k_provides pbKeywords + +hi def link pbIllegalInstall Error +hi def link pb_k_install pbKeywords + +hi def link pbIllegalChangelog Error +hi def link pb_k_changelog pbKeywords + +hi def link pb_k_source pbKeywords +hi def link pbIllegalSource Error + +hi def link pb_k_md5sums pbKeywords +hi def link pbIllegalMd5sums Error + +hi def link pb_k_sha1sums pbKeywords +hi def link pbIllegalSha1sums Error + +hi def link pb_k_sha256sums pbKeywords +hi def link pbIllegalSha256sums Error + +hi def link pb_k_sha384sums pbKeywords +hi def link pbIllegalSha384sums Error + +hi def link pb_k_sha512sums pbKeywords +hi def link pbIllegalSha512sums Error + +hi def link pb_k_options pbKeywords +hi def link pbOptionsDeprec Todo +hi def link pbIllegalOption Error + +hi def link pb_k_noextract pbKeywords +hi def link pbNoextract Normal + +hi def link pb_k_maintainer pbKeywords + +hi def link pbKeywords Keyword + +hi def link pbDate Special + +"syntax include @SHELL syntax/sh.vim +"syntax region BUILD start=/^build()/ end=/^}/ contains=@SHELL +"let b:current_syntax = "PKGBUILD" + +" vim: ft=vim diff --git a/nvim/after/syntax/c.vim b/nvim/after/syntax/c.vim new file mode 100644 index 0000000..e9a795c --- /dev/null +++ b/nvim/after/syntax/c.vim @@ -0,0 +1,5 @@ +" Highlight Function names +syn match cCustomParen "(" contains=cParen +syn match cCustomFunc "\w\+\s*(" contains=cCustomParen + +hi def link cCustomFunc Function diff --git a/nvim/autoload/plug.vim b/nvim/autoload/plug.vim new file mode 100644 index 0000000..bdd647b --- /dev/null +++ b/nvim/autoload/plug.vim @@ -0,0 +1,2084 @@ +" vim-plug: Vim plugin manager +" ============================ +" +" Download plug.vim and put it in ~/.vim/autoload +" +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ +" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim +" +" Edit your .vimrc +" +" call plug#begin('~/.vim/plugged') +" +" " Make sure you use single quotes +" Plug 'junegunn/seoul256.vim' +" Plug 'junegunn/vim-easy-align' +" +" " Group dependencies, vim-snippets depends on ultisnips +" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets' +" +" " On-demand loading +" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } +" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } +" +" " Using git URL +" Plug 'https://github.com/junegunn/vim-github-dashboard.git' +" +" " Using a non-master branch +" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } + +" " Plugin options +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } +" +" " Plugin outside ~/.vim/plugged with post-update hook +" Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } +" +" " Unmanaged plugin (manually installed and updated) +" Plug '~/my-prototype-plugin' +" +" " Add plugins to &runtimepath +" call plug#end() +" +" Then reload .vimrc and :PlugInstall to install plugins. +" Visit https://github.com/junegunn/vim-plug for more information. +" +" +" Copyright (c) 2015 Junegunn Choi +" +" MIT License +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be +" included in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +if exists('g:loaded_plug') + finish +endif +let g:loaded_plug = 1 + +let s:cpo_save = &cpo +set cpo&vim + +let s:plug_src = 'https://github.com/junegunn/vim-plug.git' +let s:plug_tab = get(s:, 'plug_tab', -1) +let s:plug_buf = get(s:, 'plug_buf', -1) +let s:mac_gui = has('gui_macvim') && has('gui_running') +let s:is_win = has('win32') || has('win64') +let s:nvim = has('nvim') && exists('*jobwait') && !s:is_win +let s:me = resolve(expand('<sfile>:p')) +let s:base_spec = { 'branch': 'master', 'frozen': 0 } +let s:TYPE = { +\ 'string': type(''), +\ 'list': type([]), +\ 'dict': type({}), +\ 'funcref': type(function('call')) +\ } +let s:loaded = get(s:, 'loaded', {}) +let s:triggers = get(s:, 'triggers', {}) + +function! plug#begin(...) + if a:0 > 0 + let s:plug_home_org = a:1 + let home = s:path(fnamemodify(expand(a:1), ':p')) + elseif exists('g:plug_home') + let home = s:path(g:plug_home) + elseif !empty(&rtp) + let home = s:path(split(&rtp, ',')[0]) . '/plugged' + else + return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') + endif + + let g:plug_home = home + let g:plugs = {} + let g:plugs_order = [] + let s:triggers = {} + + call s:define_commands() + return 1 +endfunction + +function! s:define_commands() + command! -nargs=+ -bar Plug call s:add(<args>) + if !executable('git') + return s:err('`git` executable not found. vim-plug requires git.') + endif + command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install('<bang>' == '!', [<f-args>]) + command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update('<bang>' == '!', [<f-args>]) + command! -nargs=0 -bar -bang PlugClean call s:clean('<bang>' == '!') + command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif + command! -nargs=0 -bar PlugStatus call s:status() + command! -nargs=0 -bar PlugDiff call s:diff() + command! -nargs=? -bar PlugSnapshot call s:snapshot(<f-args>) +endfunction + +function! s:to_a(v) + return type(a:v) == s:TYPE.list ? a:v : [a:v] +endfunction + +function! s:to_s(v) + return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n" +endfunction + +function! s:source(from, ...) + for pattern in a:000 + for vim in s:lines(globpath(a:from, pattern)) + execute 'source' s:esc(vim) + endfor + endfor +endfunction + +function! s:assoc(dict, key, val) + let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) +endfunction + +function! plug#end() + if !exists('g:plugs') + return s:err('Call plug#begin() first') + endif + + if exists('#PlugLOD') + augroup PlugLOD + autocmd! + augroup END + augroup! PlugLOD + endif + let lod = { 'ft': {}, 'map': {}, 'cmd': {} } + + filetype off + for name in g:plugs_order + let plug = g:plugs[name] + if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') + let s:loaded[name] = 1 + continue + endif + + if has_key(plug, 'on') + let s:triggers[name] = { 'map': [], 'cmd': [] } + for cmd in s:to_a(plug.on) + if cmd =~? '^<Plug>.\+' + if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) + call s:assoc(lod.map, cmd, name) + endif + call add(s:triggers[name].map, cmd) + elseif cmd =~# '^[A-Z]' + if exists(':'.cmd) != 2 + call s:assoc(lod.cmd, cmd, name) + endif + call add(s:triggers[name].cmd, cmd) + else + call s:err('Invalid `on` option: '.cmd. + \ '. Should start with an uppercase letter or `<Plug>`.') + endif + endfor + endif + + if has_key(plug, 'for') + let types = s:to_a(plug.for) + if !empty(types) + call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') + endif + for type in types + call s:assoc(lod.ft, type, name) + endfor + endif + endfor + + for [cmd, names] in items(lod.cmd) + execute printf( + \ 'command! -nargs=* -range -bang %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)', + \ cmd, string(cmd), string(names)) + endfor + + for [map, names] in items(lod.map) + for [mode, map_prefix, key_prefix] in + \ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] + execute printf( + \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, "%s")<CR>', + \ mode, map, map_prefix, string(map), string(names), key_prefix) + endfor + endfor + + for [ft, names] in items(lod.ft) + augroup PlugLOD + execute printf('autocmd FileType %s call <SID>lod_ft(%s, %s)', + \ ft, string(ft), string(names)) + augroup END + endfor + + call s:reorg_rtp() + filetype plugin indent on + if has('vim_starting') + syntax enable + else + call s:reload() + endif +endfunction + +function! s:loaded_names() + return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') +endfunction + +function! s:reload() + for name in s:loaded_names() + call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim') + endfor +endfunction + +function! s:trim(str) + return substitute(a:str, '[\/]\+$', '', '') +endfunction + +function! s:version_requirement(val, min) + for idx in range(0, len(a:min) - 1) + let v = get(a:val, idx, 0) + if v < a:min[idx] | return 0 + elseif v > a:min[idx] | return 1 + endif + endfor + return 1 +endfunction + +function! s:git_version_requirement(...) + let s:git_version = get(s:, 'git_version', + \ map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)')) + return s:version_requirement(s:git_version, a:000) +endfunction + +function! s:progress_opt(base) + return a:base && !s:is_win && + \ s:git_version_requirement(1, 7, 1) ? '--progress' : '' +endfunction + +if s:is_win + function! s:rtp(spec) + return s:path(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + function! s:path(path) + return s:trim(substitute(a:path, '/', '\', 'g')) + endfunction + + function! s:dirpath(path) + return s:path(a:path) . '\' + endfunction + + function! s:is_local_plug(repo) + return a:repo =~? '^[a-z]:\|^[%~]' + endfunction +else + function! s:rtp(spec) + return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) + endfunction + + function! s:path(path) + return s:trim(a:path) + endfunction + + function! s:dirpath(path) + return substitute(a:path, '[/\\]*$', '/', '') + endfunction + + function! s:is_local_plug(repo) + return a:repo[0] =~ '[/$~]' + endfunction +endif + +function! s:err(msg) + echohl ErrorMsg + echom '[vim-plug] '.a:msg + echohl None + return 0 +endfunction + +function! s:esc(path) + return escape(a:path, ' ') +endfunction + +function! s:escrtp(path) + return escape(a:path, ' ,') +endfunction + +function! s:remove_rtp() + for name in s:loaded_names() + let rtp = s:rtp(g:plugs[name]) + execute 'set rtp-='.s:escrtp(rtp) + let after = globpath(rtp, 'after') + if isdirectory(after) + execute 'set rtp-='.s:escrtp(after) + endif + endfor +endfunction + +function! s:reorg_rtp() + if !empty(s:first_rtp) + execute 'set rtp-='.s:first_rtp + execute 'set rtp-='.s:last_rtp + endif + + " &rtp is modified from outside + if exists('s:prtp') && s:prtp !=# &rtp + call s:remove_rtp() + unlet! s:middle + endif + + let s:middle = get(s:, 'middle', &rtp) + let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') + let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), 'isdirectory(v:val)') + let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') + \ . ','.s:middle.',' + \ . join(map(afters, 'escape(v:val, ",")'), ',') + let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g') + let s:prtp = &rtp + + if !empty(s:first_rtp) + execute 'set rtp^='.s:first_rtp + execute 'set rtp+='.s:last_rtp + endif +endfunction + +function! plug#load(...) + if a:0 == 0 + return s:err('Argument missing: plugin name(s) required') + endif + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + let unknowns = filter(copy(a:000), '!has_key(g:plugs, v:val)') + if !empty(unknowns) + let s = len(unknowns) > 1 ? 's' : '' + return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) + end + for name in a:000 + call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + endfor + if exists('#BufRead') + doautocmd BufRead + endif + return 1 +endfunction + +function! s:remove_triggers(name) + if !has_key(s:triggers, a:name) + return + endif + for cmd in s:triggers[a:name].cmd + execute 'silent! delc' cmd + endfor + for map in s:triggers[a:name].map + execute 'silent! unmap' map + execute 'silent! iunmap' map + endfor + call remove(s:triggers, a:name) +endfunction + +function! s:lod(names, types) + for name in a:names + call s:remove_triggers(name) + let s:loaded[name] = 1 + endfor + call s:reorg_rtp() + + for name in a:names + let rtp = s:rtp(g:plugs[name]) + for dir in a:types + call s:source(rtp, dir.'/**/*.vim') + endfor + if exists('#User#'.name) + execute 'doautocmd User' name + endif + endfor +endfunction + +function! s:lod_ft(pat, names) + call s:lod(a:names, ['plugin', 'after/plugin', 'syntax', 'after/syntax']) + execute 'autocmd! PlugLOD FileType' a:pat + if exists('#filetypeplugin#FileType') + doautocmd filetypeplugin FileType + endif + if exists('#filetypeindent#FileType') + doautocmd filetypeindent FileType + endif +endfunction + +function! s:lod_cmd(cmd, bang, l1, l2, args, names) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) +endfunction + +function! s:lod_map(map, names, prefix) + call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) + let extra = '' + while 1 + let c = getchar(0) + if c == 0 + break + endif + let extra .= nr2char(c) + endwhile + call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra) +endfunction + +function! s:add(repo, ...) + if a:0 > 1 + return s:err('Invalid number of arguments (1..2)') + endif + + try + let repo = s:trim(a:repo) + let name = fnamemodify(repo, ':t:s?\.git$??') + let spec = extend(s:infer_properties(name, repo), + \ a:0 == 1 ? s:parse_options(a:1) : s:base_spec) + if !has_key(g:plugs, name) + call add(g:plugs_order, name) + endif + let g:plugs[name] = spec + let s:loaded[name] = get(s:loaded, name, 0) + catch + return s:err(v:exception) + endtry +endfunction + +function! s:parse_options(arg) + let opts = copy(s:base_spec) + let type = type(a:arg) + if type == s:TYPE.string + let opts.tag = a:arg + elseif type == s:TYPE.dict + call extend(opts, a:arg) + if has_key(opts, 'dir') + let opts.dir = s:dirpath(expand(opts.dir)) + endif + else + throw 'Invalid argument type (expected: string or dictionary)' + endif + return opts +endfunction + +function! s:infer_properties(name, repo) + let repo = a:repo + if s:is_local_plug(repo) + return { 'dir': s:dirpath(expand(repo)) } + else + if repo =~ ':' + let uri = repo + else + if repo !~ '/' + let repo = 'vim-scripts/'. repo + endif + let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') + let uri = printf(fmt, repo) + endif + let dir = s:dirpath( fnamemodify(join([g:plug_home, a:name], '/'), ':p') ) + return { 'dir': dir, 'uri': uri } + endif +endfunction + +function! s:install(force, names) + call s:update_impl(0, a:force, a:names) +endfunction + +function! s:update(force, names) + call s:update_impl(1, a:force, a:names) +endfunction + +function! plug#helptags() + if !exists('g:plugs') + return s:err('plug#begin was not called') + endif + for spec in values(g:plugs) + let docd = join([spec.dir, 'doc'], '/') + if isdirectory(docd) + silent! execute 'helptags' s:esc(docd) + endif + endfor + return 1 +endfunction + +function! s:syntax() + syntax clear + syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber + syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX + syn match plugNumber /[0-9]\+[0-9.]*/ contained + syn match plugBracket /[[\]]/ contained + syn match plugX /x/ contained + syn match plugDash /^-/ + syn match plugPlus /^+/ + syn match plugStar /^*/ + syn match plugMessage /\(^- \)\@<=.*/ + syn match plugName /\(^- \)\@<=[^ ]*:/ + syn match plugInstall /\(^+ \)\@<=[^:]*/ + syn match plugUpdate /\(^* \)\@<=[^:]*/ + syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha + syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained + syn match plugRelDate /([^)]*)$/ contained + syn match plugNotLoaded /(not loaded)$/ + syn match plugError /^x.*/ + syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean + hi def link plug1 Title + hi def link plug2 Repeat + hi def link plugX Exception + hi def link plugBracket Structure + hi def link plugNumber Number + + hi def link plugDash Special + hi def link plugPlus Constant + hi def link plugStar Boolean + + hi def link plugMessage Function + hi def link plugName Label + hi def link plugInstall Function + hi def link plugUpdate Type + + hi def link plugError Error + hi def link plugRelDate Comment + hi def link plugSha Identifier + + hi def link plugNotLoaded Comment +endfunction + +function! s:lpad(str, len) + return a:str . repeat(' ', a:len - len(a:str)) +endfunction + +function! s:lines(msg) + return split(a:msg, "[\r\n]") +endfunction + +function! s:lastline(msg) + return get(s:lines(a:msg), -1, '') +endfunction + +function! s:new_window() + execute get(g:, 'plug_window', 'vertical topleft new') +endfunction + +function! s:plug_window_exists() + let buflist = tabpagebuflist(s:plug_tab) + return !empty(buflist) && index(buflist, s:plug_buf) >= 0 +endfunction + +function! s:switch_in() + if !s:plug_window_exists() + return 0 + endif + + if winbufnr(0) != s:plug_buf + let s:pos = [tabpagenr(), winnr(), winsaveview()] + execute 'normal!' s:plug_tab.'gt' + let winnr = bufwinnr(s:plug_buf) + execute winnr.'wincmd w' + call add(s:pos, winsaveview()) + else + let s:pos = [winsaveview()] + endif + + setlocal modifiable + return 1 +endfunction + +function! s:switch_out(...) + call winrestview(s:pos[-1]) + setlocal nomodifiable + if a:0 > 0 + execute a:1 + endif + + if len(s:pos) > 1 + execute 'normal!' s:pos[0].'gt' + execute s:pos[1] 'wincmd w' + call winrestview(s:pos[2]) + endif +endfunction + +function! s:prepare() + call s:job_abort() + if s:switch_in() + silent %d _ + else + call s:new_window() + nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>echo<bar>q<cr> + nnoremap <silent> <buffer> R :silent! call <SID>retry()<cr> + nnoremap <silent> <buffer> D :PlugDiff<cr> + nnoremap <silent> <buffer> S :PlugStatus<cr> + nnoremap <silent> <buffer> U :call <SID>status_update()<cr> + xnoremap <silent> <buffer> U :call <SID>status_update()<cr> + nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr> + nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr> + let b:plug_preview = -1 + let s:plug_tab = tabpagenr() + let s:plug_buf = winbufnr(0) + call s:assign_name() + endif + silent! unmap <buffer> <cr> + silent! unmap <buffer> L + silent! unmap <buffer> o + silent! unmap <buffer> X + setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable + setf vim-plug + call s:syntax() +endfunction + +function! s:assign_name() + " Assign buffer name + let prefix = '[Plugins]' + let name = prefix + let idx = 2 + while bufexists(name) + let name = printf('%s (%s)', prefix, idx) + let idx = idx + 1 + endwhile + silent! execute 'f' fnameescape(name) +endfunction + +function! s:do(pull, force, todo) + for [name, spec] in items(a:todo) + if !isdirectory(spec.dir) + continue + endif + let installed = has_key(s:update.new, name) + let updated = installed ? 0 : + \ (a:pull && index(s:update.errors, name) < 0 && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir))) + if a:force || installed || updated + execute 'cd' s:esc(spec.dir) + call append(3, '- Post-update hook for '. name .' ... ') + let error = '' + let type = type(spec.do) + if type == s:TYPE.string + try + " FIXME: Escaping is incomplete. We could use shellescape with eval, + " but it won't work on Windows. + let g:_plug_do = '!'.escape(spec.do, '#!%') + execute "normal! :execute g:_plug_do\<cr>\<cr>" + finally + if v:shell_error + let error = 'Exit status: ' . v:shell_error + endif + unlet g:_plug_do + endtry + elseif type == s:TYPE.funcref + try + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) + catch + let error = v:exception + endtry + else + let error = 'Invalid hook type' + endif + call setline(4, empty(error) ? (getline(4) . 'OK') + \ : ('x' . getline(4)[1:] . error)) + cd - + endif + endfor +endfunction + +function! s:hash_match(a, b) + return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0 +endfunction + +function! s:checkout(plugs) + for [name, spec] in items(a:plugs) + let sha = spec.commit + call append(3, '- Checking out '.sha[:6].' of '.name.' ... ') + redraw + + let error = [] + let output = s:lines(s:system('git rev-parse HEAD', spec.dir)) + if v:shell_error + let error = output + elseif !s:hash_match(sha, output[0]) + let output = s:lines(s:system( + \ 'git fetch --depth 999999 && git checkout '.sha, spec.dir)) + if v:shell_error + let error = output + endif + endif + if empty(error) + call setline(4, getline(4) . 'OK') + else + call setline(4, 'x'.getline(4)[1:] . 'Error') + for line in reverse(error) + call append(4, ' '.line) + endfor + endif + endfor +endfunction + +function! s:finish(pull) + let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen')) + if new_frozen + let s = new_frozen > 1 ? 's' : '' + call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s)) + endif + call append(3, '- Finishing ... ') + redraw + call plug#helptags() + call plug#end() + call setline(4, getline(4) . 'Done!') + redraw + let msgs = [] + if !empty(s:update.errors) + call add(msgs, "Press 'R' to retry.") + endif + if a:pull && len(s:update.new) < len(filter(getline(5, '$'), + \ "v:val =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0")) + call add(msgs, "Press 'D' to see the updated changes.") + endif + echo join(msgs, ' ') +endfunction + +function! s:retry() + if empty(s:update.errors) + return + endif + call s:update_impl(s:update.pull, s:update.force, + \ extend(copy(s:update.errors), [s:update.threads])) +endfunction + +function! s:is_managed(name) + return has_key(g:plugs[a:name], 'uri') +endfunction + +function! s:names(...) + return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')) +endfunction + +function! s:update_impl(pull, force, args) abort + let args = copy(a:args) + let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? + \ remove(args, -1) : get(g:, 'plug_threads', s:is_win ? 1 : 16) + + let managed = filter(copy(g:plugs), 's:is_managed(v:key)') + let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') : + \ filter(managed, 'index(args, v:key) >= 0') + + if empty(todo) + echohl WarningMsg + echo 'No plugin to '. (a:pull ? 'update' : 'install') . '.' + echohl None + return + endif + + if !s:is_win && s:git_version_requirement(2, 3) + let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : '' + let $GIT_TERMINAL_PROMPT = 0 + for plug in values(todo) + let plug.uri = substitute(plug.uri, + \ '^https://git::@github\.com', 'https://github.com', '') + endfor + endif + + if !isdirectory(g:plug_home) + try + call mkdir(g:plug_home, 'p') + catch + return s:err(printf('Invalid plug directory: %s. '. + \ 'Try to call plug#begin with a valid directory', g:plug_home)) + endtry + endif + + if has('nvim') && !exists('*jobwait') && threads > 1 + echohl WarningMsg + echomsg 'vim-plug: update Neovim for parallel installer' + echohl None + endif + + let python = (has('python') || has('python3')) && !s:is_win && !has('win32unix') + \ && (!s:nvim || has('vim_starting')) + let ruby = has('ruby') && !s:nvim && (v:version >= 703 || v:version == 702 && has('patch374')) + + let s:update = { + \ 'start': reltime(), + \ 'all': todo, + \ 'todo': copy(todo), + \ 'errors': [], + \ 'pull': a:pull, + \ 'force': a:force, + \ 'new': {}, + \ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1, + \ 'bar': '', + \ 'fin': 0 + \ } + + call s:prepare() + call append(0, ['', '']) + normal! 2G + silent! redraw + + let s:clone_opt = get(g:, 'plug_shallow', 1) ? + \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' + + " Python version requirement (>= 2.7) + if python && !has('python3') && !ruby && !s:nvim && s:update.threads > 1 + redir => pyv + silent python import platform; print(platform.python_version()) + redir END + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) + endif + + if (python || ruby) && s:update.threads > 1 + try + let imd = &imd + if s:mac_gui + set noimd + endif + if ruby + call s:update_ruby() + else + call s:update_python() + endif + catch + let lines = getline(4, '$') + let printed = {} + silent! 4,$d _ + for line in lines + let name = s:extract_name(line, '.', '') + if empty(name) || !has_key(printed, name) + call append('$', line) + if !empty(name) + let printed[name] = 1 + if line[0] == 'x' && index(s:update.errors, name) < 0 + call add(s:update.errors, name) + end + endif + endif + endfor + finally + let &imd = imd + call s:update_finish() + endtry + else + call s:update_vim() + endif +endfunction + +function! s:update_finish() + if exists('s:git_terminal_prompt') + let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt + endif + if s:switch_in() + call s:checkout(filter(copy(s:update.all), 'has_key(v:val, "commit")')) + call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'has_key(v:val, "do")')) + call s:finish(s:update.pull) + call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') + call s:switch_out('normal! gg') + endif +endfunction + +function! s:job_abort() + if !s:nvim || !exists('s:jobs') + return + endif + + for [name, j] in items(s:jobs) + silent! call jobstop(j.jobid) + if j.new + call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) + endif + endfor + let s:jobs = {} +endfunction + +" When a:event == 'stdout', data = list of strings +" When a:event == 'exit', data = returncode +function! s:job_handler(job_id, data, event) abort + if !s:plug_window_exists() " plug window closed + return s:job_abort() + endif + + if a:event == 'stdout' + let self.result .= substitute(s:to_s(a:data), '[\r\n]', '', 'g') . "\n" + " To reduce the number of buffer updates + let self.tick = get(self, 'tick', -1) + 1 + if self.tick % len(s:jobs) == 0 + call s:log(self.new ? '+' : '*', self.name, self.result) + endif + elseif a:event == 'exit' + let self.running = 0 + if a:data != 0 + let self.error = 1 + endif + call s:reap(self.name) + call s:tick() + endif +endfunction + +function! s:spawn(name, cmd, opts) + let job = { 'name': a:name, 'running': 1, 'error': 0, 'result': '', + \ 'new': get(a:opts, 'new', 0), + \ 'on_stdout': function('s:job_handler'), + \ 'on_exit' : function('s:job_handler'), + \ } + let s:jobs[a:name] = job + + if s:nvim + let argv = [ 'sh', '-c', + \ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) ] + let jid = jobstart(argv, job) + if jid > 0 + let job.jobid = jid + else + let job.running = 0 + let job.error = 1 + let job.result = jid < 0 ? 'sh is not executable' : + \ 'Invalid arguments (or job table is full)' + endif + else + let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] + let job.result = call('s:system', params) + let job.error = v:shell_error != 0 + let job.running = 0 + endif +endfunction + +function! s:reap(name) + let job = s:jobs[a:name] + if job.error + call add(s:update.errors, a:name) + elseif get(job, 'new', 0) + let s:update.new[a:name] = 1 + endif + let s:update.bar .= job.error ? 'x' : '=' + + call s:log(job.error ? 'x' : '-', a:name, job.result) + call s:bar() + + call remove(s:jobs, a:name) +endfunction + +function! s:bar() + if s:switch_in() + let total = len(s:update.all) + call setline(1, (s:update.pull ? 'Updating' : 'Installing'). + \ ' plugins ('.len(s:update.bar).'/'.total.')') + call s:progress_bar(2, s:update.bar, total) + call s:switch_out() + endif +endfunction + +function! s:logpos(name) + for i in range(1, line('$')) + if getline(i) =~# '^[-+x*] '.a:name.':' + return i + endif + endfor + return 0 +endfunction + +function! s:log(bullet, name, lines) + if s:switch_in() + let pos = s:logpos(a:name) + if pos > 0 + execute pos 'd _' + if pos > winheight('.') + let pos = 4 + endif + else + let pos = 4 + endif + call append(pos - 1, s:format_message(a:bullet, a:name, a:lines)) + call s:switch_out() + endif +endfunction + +function! s:update_vim() + let s:jobs = {} + + call s:bar() + call s:tick() +endfunction + +function! s:tick() + let pull = s:update.pull + let prog = s:progress_opt(s:nvim) +while 1 " Without TCO, Vim stack is bound to explode + if empty(s:update.todo) + if empty(s:jobs) && !s:update.fin + let s:update.fin = 1 + call s:update_finish() + endif + return + endif + + let name = keys(s:update.todo)[0] + let spec = remove(s:update.todo, name) + let new = !isdirectory(spec.dir) + + call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') + redraw + + let has_tag = has_key(spec, 'tag') + let checkout = s:shellesc(has_tag ? spec.tag : spec.branch) + let merge = s:shellesc(has_tag ? spec.tag : 'origin/'.spec.branch) + + if !new + let error = s:git_validate(spec, 0) + if empty(error) + if pull + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' + call s:spawn(name, + \ printf('(git fetch %s %s 2>&1 && git checkout -q %s 2>&1 && git merge --ff-only %s 2>&1 && git submodule update --init --recursive 2>&1)', + \ fetch_opt, prog, checkout, merge), { 'dir': spec.dir }) + else + let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 } + endif + else + let s:jobs[name] = { 'running': 0, 'result': error, 'error': 1 } + endif + else + call s:spawn(name, + \ printf('git clone %s %s --recursive %s -b %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, + \ prog, + \ s:shellesc(spec.uri), + \ checkout, + \ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) + endif + + if !s:jobs[name].running + call s:reap(name) + endif + if len(s:jobs) >= s:update.threads + break + endif +endwhile +endfunction + +function! s:update_python() +let py_exe = has('python3') ? 'python3' : 'python' +execute py_exe "<< EOF" +""" Due to use of signals this function is POSIX only. """ +import datetime +import functools +import os +try: + import queue +except ImportError: + import Queue as queue +import random +import re +import shutil +import signal +import subprocess +import tempfile +import threading as thr +import time +import traceback +import vim + +G_NVIM = vim.eval("has('nvim')") == '1' +G_PULL = vim.eval('s:update.pull') == '1' +G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 +G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) +G_CLONE_OPT = vim.eval('s:clone_opt') +G_PROGRESS = vim.eval('s:progress_opt(1)') +G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) +G_STOP = thr.Event() +G_THREADS = {} + +class PlugError(Exception): + def __init__(self, msg): + self._msg = msg + @property + def msg(self): + return self._msg +class CmdTimedOut(PlugError): + pass +class CmdFailed(PlugError): + pass +class InvalidURI(PlugError): + pass +class Action(object): + INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] + +class Buffer(object): + def __init__(self, lock, num_plugs, is_pull, is_win): + self.bar = '' + self.event = 'Updating' if is_pull else 'Installing' + self.is_win = is_win + self.lock = lock + self.maxy = int(vim.eval('winheight(".")')) + self.num_plugs = num_plugs + + def __where(self, name): + """ Find first line with name in current buffer. Return line num. """ + found, lnum = False, 0 + matcher = re.compile('^[-+x*] {0}:'.format(name)) + for line in vim.current.buffer: + if matcher.search(line) is not None: + found = True + break + lnum += 1 + + if not found: + lnum = -1 + return lnum + + def header(self): + curbuf = vim.current.buffer + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) + + num_spaces = self.num_plugs - len(self.bar) + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') + + with self.lock: + vim.command('normal! 2G') + if not self.is_win: + vim.command('redraw') + + def write(self, action, name, lines): + first, rest = lines[0], lines[1:] + msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] + msg.extend([' ' + line for line in rest]) + + try: + if action == Action.ERROR: + self.bar += 'x' + vim.command("call add(s:update.errors, '{0}')".format(name)) + elif action == Action.DONE: + self.bar += '=' + + curbuf = vim.current.buffer + lnum = self.__where(name) + if lnum != -1: # Found matching line num + del curbuf[lnum] + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): + lnum = 3 + else: + lnum = 3 + curbuf.append(msg, lnum) + + self.header() + except vim.error: + pass + +class Command(object): + def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None): + self.cmd = cmd + self.cmd_dir = cmd_dir + self.timeout = timeout + self.callback = cb if cb else (lambda msg: None) + self.clean = clean if clean else (lambda: None) + self.proc = None + + @property + def alive(self): + """ Returns true only if command still running. """ + return self.proc and self.proc.poll() is None + + def execute(self, ntries=3): + """ Execute the command with ntries if CmdTimedOut. + Returns the output of the command if no Exception. + """ + attempt, finished, limit = 0, False, self.timeout + + while not finished: + try: + attempt += 1 + result = self.try_command() + finished = True + return result + except CmdTimedOut: + if attempt != ntries: + self.notify_retry() + self.timeout += limit + else: + raise + + def notify_retry(self): + """ Retry required for command, notify user. """ + for count in range(3, 0, -1): + if G_STOP.is_set(): + raise KeyboardInterrupt + msg = 'Timeout. Will retry in {0} second{1} ...'.format( + count, 's' if count != 1 else '') + self.callback([msg]) + time.sleep(1) + self.callback(['Retrying ...']) + + def try_command(self): + """ Execute a cmd & poll for callback. Returns list of output. + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output + """ + first_line = True + + try: + tfile = tempfile.NamedTemporaryFile(mode='w+b') + self.proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile, + stderr=subprocess.STDOUT, shell=True, + preexec_fn=os.setsid) + thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,)) + thrd.start() + + thread_not_started = True + while thread_not_started: + try: + thrd.join(0.1) + thread_not_started = False + except RuntimeError: + pass + + while self.alive: + if G_STOP.is_set(): + raise KeyboardInterrupt + + if first_line or random.random() < G_LOG_PROB: + first_line = False + line = nonblock_read(tfile.name) + if line: + self.callback([line]) + + time_diff = time.time() - os.path.getmtime(tfile.name) + if time_diff > self.timeout: + raise CmdTimedOut(['Timeout!']) + + thrd.join(0.5) + + tfile.seek(0) + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) + + return result + except: + self.terminate() + raise + + def terminate(self): + """ Terminate process and cleanup. """ + if self.alive: + os.killpg(self.proc.pid, signal.SIGTERM) + self.clean() + +class Plugin(object): + def __init__(self, name, args, buf_q, lock): + self.name = name + self.args = args + self.buf_q = buf_q + self.lock = lock + tag = args.get('tag', 0) + self.checkout = esc(tag if tag else args['branch']) + self.merge = esc(tag if tag else 'origin/' + args['branch']) + self.tag = tag + + def manage(self): + try: + if os.path.exists(self.args['dir']): + self.update() + else: + self.install() + with self.lock: + thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) + except PlugError as exc: + self.write(Action.ERROR, self.name, exc.msg) + except KeyboardInterrupt: + G_STOP.set() + self.write(Action.ERROR, self.name, ['Interrupted!']) + except: + # Any exception except those above print stack trace + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) + self.write(Action.ERROR, self.name, msg.split('\n')) + raise + + def install(self): + target = self.args['dir'] + + def clean(target): + def _clean(): + try: + shutil.rmtree(target) + except OSError: + pass + return _clean + + self.write(Action.INSTALL, self.name, ['Installing ...']) + callback = functools.partial(self.write, Action.INSTALL, self.name) + cmd = 'git clone {0} {1} --recursive {2} -b {3} {4} 2>&1'.format( + '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], + self.checkout, esc(target)) + com = Command(cmd, None, G_TIMEOUT, callback, clean(target)) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + + def repo_uri(self): + cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url' + command = Command(cmd, self.args['dir'], G_TIMEOUT,) + result = command.execute(G_RETRIES) + return result[-1] + + def update(self): + match = re.compile(r'git::?@') + actual_uri = re.sub(match, '', self.repo_uri()) + expect_uri = re.sub(match, '', self.args['uri']) + if actual_uri != expect_uri: + msg = ['', + 'Invalid URI: {0}'.format(actual_uri), + 'Expected {0}'.format(expect_uri), + 'PlugClean required.'] + raise InvalidURI(msg) + + if G_PULL: + self.write(Action.UPDATE, self.name, ['Updating ...']) + callback = functools.partial(self.write, Action.UPDATE, self.name) + fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else '' + cmds = ['git fetch {0} {1}'.format(fetch_opt, G_PROGRESS), + 'git checkout -q {0}'.format(self.checkout), + 'git merge --ff-only {0}'.format(self.merge), + 'git submodule update --init --recursive'] + cmd = ' 2>&1 && '.join(cmds) + com = Command(cmd, self.args['dir'], G_TIMEOUT, callback) + result = com.execute(G_RETRIES) + self.write(Action.DONE, self.name, result[-1:]) + else: + self.write(Action.DONE, self.name, ['Already installed']) + + def write(self, action, name, msg): + self.buf_q.put((action, name, msg)) + +class PlugThread(thr.Thread): + def __init__(self, tname, args): + super(PlugThread, self).__init__() + self.tname = tname + self.args = args + + def run(self): + thr.current_thread().name = self.tname + buf_q, work_q, lock = self.args + + try: + while not G_STOP.is_set(): + name, args = work_q.get_nowait() + plug = Plugin(name, args, buf_q, lock) + plug.manage() + work_q.task_done() + except queue.Empty: + pass + finally: + global G_THREADS + with lock: + del G_THREADS[thr.current_thread().name] + +class RefreshThread(thr.Thread): + def __init__(self, lock): + super(RefreshThread, self).__init__() + self.lock = lock + self.running = True + + def run(self): + while self.running: + with self.lock: + thread_vim_command('noautocmd normal! a') + time.sleep(0.33) + + def stop(self): + self.running = False + +if G_NVIM: + def thread_vim_command(cmd): + vim.session.threadsafe_call(lambda: vim.command(cmd)) +else: + def thread_vim_command(cmd): + vim.command(cmd) + +def esc(name): + return '"' + name.replace('"', '\"') + '"' + +def nonblock_read(fname): + """ Read a file with nonblock flag. Return the last line. """ + fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK) + buf = os.read(fread, 100000).decode('utf-8', 'replace') + os.close(fread) + + line = buf.rstrip('\r\n') + left = max(line.rfind('\r'), line.rfind('\n')) + if left != -1: + left += 1 + line = line[left:] + + return line + +def main(): + thr.current_thread().name = 'main' + nthreads = int(vim.eval('s:update.threads')) + plugs = vim.eval('s:update.todo') + mac_gui = vim.eval('s:mac_gui') == '1' + is_win = vim.eval('s:is_win') == '1' + + lock = thr.Lock() + buf = Buffer(lock, len(plugs), G_PULL, is_win) + buf_q, work_q = queue.Queue(), queue.Queue() + for work in plugs.items(): + work_q.put(work) + + global G_THREADS + for num in range(nthreads): + tname = 'PlugT-{0:02}'.format(num) + thread = PlugThread(tname, (buf_q, work_q, lock)) + thread.start() + G_THREADS[tname] = thread + if mac_gui: + rthread = RefreshThread(lock) + rthread.start() + + while not buf_q.empty() or len(G_THREADS) != 0: + try: + action, name, msg = buf_q.get(True, 0.25) + buf.write(action, name, msg) + buf_q.task_done() + except queue.Empty: + pass + except KeyboardInterrupt: + G_STOP.set() + + if mac_gui: + rthread.stop() + rthread.join() + +main() +EOF +endfunction + +function! s:update_ruby() + ruby << EOF + module PlugStream + SEP = ["\r", "\n", nil] + def get_line + buffer = '' + loop do + char = readchar rescue return + if SEP.include? char.chr + buffer << $/ + break + else + buffer << char + end + end + buffer + end + end unless defined?(PlugStream) + + def esc arg + %["#{arg.gsub('"', '\"')}"] + end + + def killall pid + pids = [pid] + unless `which pgrep 2> /dev/null`.empty? + children = pids + until children.empty? + children = children.map { |pid| + `pgrep -P #{pid}`.lines.map { |l| l.chomp } + }.flatten + pids += children + end + end + pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } + end + + require 'thread' + require 'fileutils' + require 'timeout' + running = true + iswin = VIM::evaluate('s:is_win').to_i == 1 + pull = VIM::evaluate('s:update.pull').to_i == 1 + base = VIM::evaluate('g:plug_home') + all = VIM::evaluate('s:update.todo') + limit = VIM::evaluate('get(g:, "plug_timeout", 60)') + tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 + nthr = VIM::evaluate('s:update.threads').to_i + maxy = VIM::evaluate('winheight(".")').to_i + cd = iswin ? 'cd /d' : 'cd' + tot = VIM::evaluate('len(s:update.todo)') || 0 + bar = '' + skip = 'Already installed' + mtx = Mutex.new + take1 = proc { mtx.synchronize { running && all.shift } } + logh = proc { + cnt = bar.length + $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})" + $curbuf[2] = '[' + bar.ljust(tot) + ']' + VIM::command('normal! 2G') + VIM::command('redraw') unless iswin + } + where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } } + log = proc { |name, result, type| + mtx.synchronize do + ing = ![true, false].include?(type) + bar += type ? '=' : 'x' unless ing + b = case type + when :install then '+' when :update then '*' + when true, nil then '-' else + VIM::command("call add(s:update.errors, '#{name}')") + 'x' + end + result = + if type || type.nil? + ["#{b} #{name}: #{result.lines.to_a.last}"] + elsif result =~ /^Interrupted|^Timeout/ + ["#{b} #{name}: #{result}"] + else + ["#{b} #{name}"] + result.lines.map { |l| " " << l } + end + if lnum = where.call(name) + $curbuf.delete lnum + lnum = 4 if ing && lnum > maxy + end + result.each_with_index do |line, offset| + $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp) + end + logh.call + end + } + bt = proc { |cmd, name, type, cleanup| + tried = timeout = 0 + begin + tried += 1 + timeout += limit + fd = nil + data = '' + if iswin + Timeout::timeout(timeout) do + tmp = VIM::evaluate('tempname()') + system("(#{cmd}) > #{tmp}") + data = File.read(tmp).chomp + File.unlink tmp rescue nil + end + else + fd = IO.popen(cmd).extend(PlugStream) + first_line = true + log_prob = 1.0 / nthr + while line = Timeout::timeout(timeout) { fd.get_line } + data << line + log.call name, line.chomp, type if name && (first_line || rand < log_prob) + first_line = false + end + fd.close + end + [$? == 0, data.chomp] + rescue Timeout::Error, Interrupt => e + if fd && !fd.closed? + killall fd.pid + fd.close + end + cleanup.call if cleanup + if e.is_a?(Timeout::Error) && tried < tries + 3.downto(1) do |countdown| + s = countdown > 1 ? 's' : '' + log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type + sleep 1 + end + log.call name, 'Retrying ...', type + retry + end + [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"] + end + } + main = Thread.current + threads = [] + watcher = Thread.new { + while VIM::evaluate('getchar(1)') + sleep 0.1 + end + mtx.synchronize do + running = false + threads.each { |t| t.raise Interrupt } + end + threads.each { |t| t.join rescue nil } + main.kill + } + refresh = Thread.new { + while true + mtx.synchronize do + break unless running + VIM::command('noautocmd normal! a') + end + sleep 0.2 + end + } if VIM::evaluate('s:mac_gui') == 1 + + clone_opt = VIM::evaluate('s:clone_opt') + progress = VIM::evaluate('s:progress_opt(1)') + nthr.times do + mtx.synchronize do + threads << Thread.new { + while pair = take1.call + name = pair.first + dir, uri, branch, tag = pair.last.values_at *%w[dir uri branch tag] + checkout = esc(tag ? tag : branch) + merge = esc(tag ? tag : "origin/#{branch}") + subm = "git submodule update --init --recursive 2>&1" + exists = File.directory? dir + ok, result = + if exists + dir = iswin ? dir : esc(dir) + ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil + current_uri = data.lines.to_a.last + if !ret + if data =~ /^Interrupted|^Timeout/ + [false, data] + else + [false, [data.chomp, "PlugClean required."].join($/)] + end + elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '') + [false, ["Invalid URI: #{current_uri}", + "Expected: #{uri}", + "PlugClean required."].join($/)] + else + if pull + log.call name, 'Updating ...', :update + fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : '' + bt.call "#{cd} #{dir} && git fetch #{fetch_opt} #{progress} 2>&1 && git checkout -q #{checkout} 2>&1 && git merge --ff-only #{merge} 2>&1 && #{subm}", name, :update, nil + else + [true, skip] + end + end + else + d = esc dir.sub(%r{[\\/]+$}, '') + log.call name, 'Installing ...', :install + bt.call "git clone #{clone_opt unless tag} #{progress} --recursive #{uri} -b #{checkout} #{d} 2>&1", name, :install, proc { + FileUtils.rm_rf dir + } + end + mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok + log.call name, result, ok + end + } if running + end + end + threads.each { |t| t.join rescue nil } + logh.call + refresh.kill if refresh + watcher.kill +EOF +endfunction + +function! s:shellesc(arg) + return '"'.escape(a:arg, '"').'"' +endfunction + +function! s:glob_dir(path) + return map(filter(s:lines(globpath(a:path, '**')), 'isdirectory(v:val)'), 's:dirpath(v:val)') +endfunction + +function! s:progress_bar(line, bar, total) + call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']') +endfunction + +function! s:compare_git_uri(a, b) + let a = substitute(a:a, 'git:\{1,2}@', '', '') + let b = substitute(a:b, 'git:\{1,2}@', '', '') + return a ==# b +endfunction + +function! s:format_message(bullet, name, message) + if a:bullet != 'x' + return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))] + else + let lines = map(s:lines(a:message), '" ".v:val') + return extend([printf('x %s:', a:name)], lines) + endif +endfunction + +function! s:with_cd(cmd, dir) + return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) +endfunction + +function! s:system(cmd, ...) + try + let [sh, shrd] = [&shell, &shellredir] + if !s:is_win + set shell=sh shellredir=>%s\ 2>&1 + endif + let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd + return system(s:is_win ? '('.cmd.')' : cmd) + finally + let [&shell, &shellredir] = [sh, shrd] + endtry +endfunction + +function! s:system_chomp(...) + let ret = call('s:system', a:000) + return v:shell_error ? '' : substitute(ret, '\n$', '', '') +endfunction + +function! s:git_validate(spec, check_branch) + let err = '' + if isdirectory(a:spec.dir) + let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url', a:spec.dir)) + let remote = result[-1] + if v:shell_error + let err = join([remote, 'PlugClean required.'], "\n") + elseif !s:compare_git_uri(remote, a:spec.uri) + let err = join(['Invalid URI: '.remote, + \ 'Expected: '.a:spec.uri, + \ 'PlugClean required.'], "\n") + elseif a:check_branch && has_key(a:spec, 'commit') + let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) + let sha = result[-1] + if v:shell_error + let err = join(add(result, 'PlugClean required.'), "\n") + elseif !s:hash_match(sha, a:spec.commit) + let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', + \ a:spec.commit[:6], sha[:6]), + \ 'PlugUpdate required.'], "\n") + endif + elseif a:check_branch + let branch = result[0] + " Check tag + if has_key(a:spec, 'tag') + let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) + if a:spec.tag !=# tag + let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.', + \ (empty(tag) ? 'N/A' : tag), a:spec.tag) + endif + " Check branch + elseif a:spec.branch !=# branch + let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', + \ branch, a:spec.branch) + endif + endif + else + let err = 'Not found' + endif + return err +endfunction + +function! s:rm_rf(dir) + if isdirectory(a:dir) + call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) + endif +endfunction + +function! s:clean(force) + call s:prepare() + call append(0, 'Searching for unused plugins in '.g:plug_home) + call append(1, '') + + " List of valid directories + let dirs = [] + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if !s:is_managed(name) || empty(s:git_validate(spec, 0)) + call add(dirs, spec.dir) + endif + let cnt += 1 + call s:progress_bar(2, repeat('=', cnt), total) + normal! 2G + redraw + endfor + + let allowed = {} + for dir in dirs + let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 + let allowed[dir] = 1 + for child in s:glob_dir(dir) + let allowed[child] = 1 + endfor + endfor + + let todo = [] + let found = sort(s:glob_dir(g:plug_home)) + while !empty(found) + let f = remove(found, 0) + if !has_key(allowed, f) && isdirectory(f) + call add(todo, f) + call append(line('$'), '- ' . f) + let found = filter(found, 'stridx(v:val, f) != 0') + end + endwhile + + normal! G + redraw + if empty(todo) + call append(line('$'), 'Already clean.') + else + call inputsave() + let yes = a:force || (input('Proceed? (y/N) ') =~? '^y') + call inputrestore() + if yes + for dir in todo + call s:rm_rf(dir) + endfor + call append(line('$'), 'Removed.') + else + call append(line('$'), 'Cancelled.') + endif + endif + normal! G +endfunction + +function! s:upgrade() + echo 'Downloading the latest version of vim-plug' + redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + + try + let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp)) + if v:shell_error + return s:err('Error upgrading vim-plug: '. out) + endif + + if readfile(s:me) ==# readfile(new) + echo 'vim-plug is already up-to-date' + return 0 + else + call rename(s:me, s:me . '.old') + call rename(new, s:me) + unlet g:loaded_plug + echo 'vim-plug has been upgraded' + return 1 + endif + finally + silent! call s:rm_rf(tmp) + endtry +endfunction + +function! s:upgrade_specs() + for spec in values(g:plugs) + let spec.frozen = get(spec, 'frozen', 0) + endfor +endfunction + +function! s:status() + call s:prepare() + call append(0, 'Checking plugins') + call append(1, '') + + let ecnt = 0 + let unloaded = 0 + let [cnt, total] = [0, len(g:plugs)] + for [name, spec] in items(g:plugs) + if has_key(spec, 'uri') + if isdirectory(spec.dir) + let err = s:git_validate(spec, 1) + let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] + else + let [valid, msg] = [0, 'Not found. Try PlugInstall.'] + endif + else + if isdirectory(spec.dir) + let [valid, msg] = [1, 'OK'] + else + let [valid, msg] = [0, 'Not found.'] + endif + endif + let cnt += 1 + let ecnt += !valid + " `s:loaded` entry can be missing if PlugUpgraded + if valid && get(s:loaded, name, -1) == 0 + let unloaded = 1 + let msg .= ' (not loaded)' + endif + call s:progress_bar(2, repeat('=', cnt), total) + call append(3, s:format_message(valid ? '-' : 'x', name, msg)) + normal! 2G + redraw + endfor + call setline(1, 'Finished. '.ecnt.' error(s).') + normal! gg + setlocal nomodifiable + if unloaded + echo "Press 'L' on each line to load plugin, or 'U' to update" + nnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr> + xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr> + end +endfunction + +function! s:extract_name(str, prefix, suffix) + return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$') +endfunction + +function! s:status_load(lnum) + let line = getline(a:lnum) + let name = s:extract_name(line, '-', '(not loaded)') + if !empty(name) + call plug#load(name) + setlocal modifiable + call setline(a:lnum, substitute(line, ' (not loaded)$', '', '')) + setlocal nomodifiable + endif +endfunction + +function! s:status_update() range + let lines = getline(a:firstline, a:lastline) + let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)') + if !empty(names) + echo + execute 'PlugUpdate' join(names) + endif +endfunction + +function! s:is_preview_window_open() + silent! wincmd P + if &previewwindow + wincmd p + return 1 + endif + return 0 +endfunction + +function! s:find_name(lnum) + for lnum in reverse(range(1, a:lnum)) + let line = getline(lnum) + if empty(line) + return '' + endif + let name = s:extract_name(line, '-', '') + if !empty(name) + return name + endif + endfor + return '' +endfunction + +function! s:preview_commit() + if b:plug_preview < 0 + let b:plug_preview = !s:is_preview_window_open() + endif + + let sha = matchstr(getline('.'), '\(^ \)\@<=[0-9a-z]\{7}') + if empty(sha) + return + endif + + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir) + return + endif + + execute 'pedit' sha + wincmd P + setlocal filetype=git buftype=nofile nobuflisted modifiable + execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --pretty=medium' sha + normal! gg"_dd + setlocal nomodifiable + nnoremap <silent> <buffer> q :q<cr> + wincmd p +endfunction + +function! s:section(flags) + call search('\(^[x-] \)\@<=[^:]\+:', a:flags) +endfunction + +function! s:diff() + call s:prepare() + call append(0, 'Collecting updated changes ...') + normal! gg + redraw + + let cnt = 0 + for [k, v] in filter(items(g:plugs), '!has_key(v:val[1], "commit")') + if !isdirectory(v.dir) || !s:is_managed(k) + continue + endif + + let diff = s:system_chomp('git log --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"', v.dir) + if !empty(diff) + call append(1, '') + call append(2, '- '.k.':') + call append(3, map(s:lines(diff), '" ". v:val')) + let cnt += 1 + normal! gg + redraw + endif + endfor + + call setline(1, cnt == 0 ? 'No updates.' : 'Last update:') + nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr> + nnoremap <silent> <buffer> o :silent! call <SID>preview_commit()<cr> + nnoremap <silent> <buffer> X :call <SID>revert()<cr> + normal! gg + setlocal nomodifiable + if cnt > 0 + echo "Press 'X' on each block to revert the update" + endif +endfunction + +function! s:revert() + let name = s:find_name(line('.')) + if empty(name) || !has_key(g:plugs, name) || + \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y' + return + endif + + call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch), g:plugs[name].dir) + setlocal modifiable + normal! "_dap + setlocal nomodifiable + echo 'Reverted.' +endfunction + +function! s:snapshot(...) abort + let home = get(s:, 'plug_home_org', g:plug_home) + let [type, var, header] = s:is_win ? + \ ['dosbatch', '%PLUG_HOME%', + \ ['@echo off', ':: Generated by vim-plug', ':: '.strftime("%c"), '', + \ ':: Make sure to PlugUpdate first', '', 'set PLUG_HOME='.home]] : + \ ['sh', '$PLUG_HOME', + \ ['#!/bin/sh', '# Generated by vim-plug', '# '.strftime("%c"), '', + \ 'vim +PlugUpdate +qa', '', 'PLUG_HOME='.s:esc(home)]] + + call s:prepare() + execute 'setf' type + call append(0, header) + call append('$', '') + 1 + redraw + + let dirs = sort(map(values(filter(copy(g:plugs), + \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)')), 'v:val.dir')) + let anchor = line('$') - 1 + for dir in reverse(dirs) + let sha = s:system_chomp('git rev-parse --short HEAD', dir) + if !empty(sha) + call append(anchor, printf('cd %s && git reset --hard %s', + \ substitute(dir, '^\V'.escape(g:plug_home, '\'), var, ''), sha)) + redraw + endif + endfor + + if a:0 > 0 + let fn = expand(a:1) + let fne = s:esc(fn) + call writefile(getline(1, '$'), fn) + if !s:is_win | call s:system('chmod +x ' . fne) | endif + echo 'Saved to '.a:1 + silent execute 'e' fne + endif +endfunction + +function! s:split_rtp() + return split(&rtp, '\\\@<!,') +endfunction + +let s:first_rtp = s:escrtp(get(s:split_rtp(), 0, '')) +let s:last_rtp = s:escrtp(get(s:split_rtp(), -1, '')) + +if exists('g:plugs') + let g:plugs_order = get(g:, 'plugs_order', keys(g:plugs)) + call s:upgrade_specs() + call s:define_commands() +endif + +let &cpo = s:cpo_save +unlet s:cpo_save + diff --git a/nvim/colors/Darkcustomside.vim b/nvim/colors/Darkcustomside.vim new file mode 100644 index 0000000..4a3cf34 --- /dev/null +++ b/nvim/colors/Darkcustomside.vim @@ -0,0 +1,98 @@ +" Vim color file +" Converted from Textmate theme Darkside using Coloration v0.3.2 (http://github.com/sickill/coloration) + +set background=dark +highlight clear + +if exists("syntax_on") + syntax reset +endif + +let g:colors_name = "Darkcustomside" + +hi Cursor ctermfg=NONE ctermbg=231 cterm=NONE guifg=NONE guibg=#f8f8f0 gui=NONE +hi Visual ctermfg=NONE ctermbg=16 cterm=NONE guifg=NONE guibg=#161a1f gui=NONE +hi CursorLine ctermfg=NONE ctermbg=239 cterm=NONE guifg=NONE guibg=#313233 gui=NONE +hi CursorColumn ctermfg=NONE ctermbg=236 cterm=NONE guifg=NONE guibg=#313233 gui=NONE +hi ColorColumn ctermfg=NONE ctermbg=236 cterm=NONE guifg=NONE guibg=#313233 gui=NONE +hi LineNr ctermfg=242 ctermbg=236 cterm=NONE guifg=#6e6f6f guibg=#313233 gui=NONE +hi VertSplit ctermfg=239 ctermbg=239 cterm=NONE guifg=#4e4f50 guibg=#4e4f50 gui=NONE +hi MatchParen ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi StatusLine ctermfg=250 ctermbg=239 cterm=bold guifg=#bababa guibg=#4e4f50 gui=bold +hi StatusLineNC ctermfg=250 ctermbg=239 cterm=NONE guifg=#bababa guibg=#4e4f50 gui=NONE +hi Pmenu ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi PmenuSel ctermfg=NONE ctermbg=16 cterm=NONE guifg=NONE guibg=#161a1f gui=NONE +hi IncSearch ctermfg=NONE ctermbg=58 cterm=NONE guifg=NONE guibg=#664624 gui=NONE +hi Search ctermfg=NONE ctermbg=58 cterm=NONE guifg=NONE guibg=#664624 gui=NONE +hi Directory ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi Folded ctermfg=59 ctermbg=235 cterm=NONE guifg=#494b4d guibg=#222324 gui=NONE + +hi Normal ctermfg=250 ctermbg=236cterm=NONE guifg=#bababa guibg=#303030 gui=NONE +hi Boolean ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi Character ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi Comment ctermfg=59 ctermbg=NONE cterm=NONE guifg=#595b5d guibg=NONE gui=NONE +hi Conditional ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi Constant ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi Define ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi ErrorMsg ctermfg=231 ctermbg=38 cterm=NONE guifg=#f8f8f0 guibg=#00a8c6 gui=NONE +hi WarningMsg ctermfg=231 ctermbg=38 cterm=NONE guifg=#f8f8f0 guibg=#00a8c6 gui=NONE +hi Float ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi Function ctermfg=71 ctermbg=NONE cterm=NONE guifg=#68c244 guibg=NONE gui=NONE +hi Identifier ctermfg=38 ctermbg=NONE cterm=NONE guifg=#1cc3e8 guibg=NONE gui=NONE +hi Keyword ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi Label ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi NonText ctermfg=59 ctermbg=236 cterm=NONE guifg=#3b3a32 guibg=#2a2b2c gui=NONE +hi Number ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi Operator ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi PreProc ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi Special ctermfg=250 ctermbg=NONE cterm=NONE guifg=#bababa guibg=NONE gui=NONE +hi SpecialKey ctermfg=59 ctermbg=236 cterm=NONE guifg=#4b4a42 guibg=#313233 gui=NONE +hi Statement ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi StorageClass ctermfg=38 ctermbg=NONE cterm=NONE guifg=#1cc3e8 guibg=NONE gui=italic +hi String ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi Tag ctermfg=166 ctermbg=NONE cterm=NONE guifg=#e8341c guibg=NONE gui=NONE +hi Title ctermfg=250 ctermbg=NONE cterm=bold guifg=#bababa guibg=NONE gui=bold +hi Todo ctermfg=59 ctermbg=NONE cterm=inverse,bold guifg=#494b4d guibg=NONE gui=inverse,bold +hi Type ctermfg=12 ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi Underlined ctermfg=NONE ctermbg=NONE cterm=underline guifg=NONE guibg=NONE gui=underline +hi rubyClass ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi rubyFunction ctermfg=71 ctermbg=NONE cterm=NONE guifg=#68c244 guibg=NONE gui=NONE +hi rubyInterpolationDelimiter ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi rubySymbol ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi rubyConstant ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=italic +hi rubyStringDelimiter ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi rubyBlockParameter ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=italic +hi rubyInstanceVariable ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi rubyInclude ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi rubyGlobalVariable ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi rubyRegexp ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi rubyRegexpDelimiter ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi rubyEscape ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi rubyControl ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi rubyClassVariable ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi rubyOperator ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi rubyException ctermfg=208 ctermbg=NONE cterm=NONE guifg=#f08d24 guibg=NONE gui=NONE +hi rubyPseudoVariable ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi rubyRailsUserClass ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=italic +hi rubyRailsARAssociationMethod ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi rubyRailsARMethod ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi rubyRailsRenderMethod ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi rubyRailsMethod ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi erubyDelimiter ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi erubyComment ctermfg=59 ctermbg=NONE cterm=NONE guifg=#595b5d guibg=NONE gui=NONE +hi erubyRailsMethod ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi javaScriptFunction ctermfg=38 ctermbg=NONE cterm=NONE guifg=#1cc3e8 guibg=NONE gui=italic +hi javaScriptRailsFunction ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi javaScriptBraces ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi yamlKey ctermfg=166 ctermbg=NONE cterm=NONE guifg=#e8341c guibg=NONE gui=NONE +hi yamlAnchor ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi yamlAlias ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE +hi yamlDocumentHeader ctermfg=220 ctermbg=NONE cterm=NONE guifg=#f2d42c guibg=NONE gui=NONE +hi cssURL ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=italic +hi cssFunctionName ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi cssColor ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi cssPseudoClassId ctermfg=71 ctermbg=NONE cterm=NONE guifg=#68c244 guibg=NONE gui=NONE +hi cssClassName ctermfg=71 ctermbg=NONE cterm=NONE guifg=#68c244 guibg=NONE gui=NONE +hi cssValueLength ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi cssCommonAttr ctermfg=98 ctermbg=NONE cterm=NONE guifg=#8e69c9 guibg=NONE gui=NONE +hi cssBraces ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE diff --git a/nvim/filetype.vim b/nvim/filetype.vim new file mode 100644 index 0000000..eba0855 --- /dev/null +++ b/nvim/filetype.vim @@ -0,0 +1,5 @@ +augroup filetypedetect + autocmd BufRead,BufNewFile *mutt-* setfiletype mail + autocmd BufRead,BufNewFile *.h setfiletype c + au BufReadPost PKGBUILD set syntax=PKGBUILD +augroup END diff --git a/nvim/ftplugin/mail.vim b/nvim/ftplugin/mail.vim new file mode 100644 index 0000000..309f8e0 --- /dev/null +++ b/nvim/ftplugin/mail.vim @@ -0,0 +1,18 @@ +set formatoptions=taw + +" * <F1> to re-format the current paragraph correctly +" * <F2> to format a line which is too long, and go to the next line +" * <F3> to merge the previous line with the current one, with a correct +" formatting (sometimes useful associated with <F2>) +" +" These keys might be used both in command mode and edit mode. +" +" <F1> might be smarter to use with the Mail_Del_Empty_Quoted() function +" defined below + +nmap <F1> gqap +nmap <F2> gqqj +nmap <F3> kgqj +map! <F1> <ESC>gqapi +map! <F2> <ESC>gqqji +map! <F3> <ESC>kgqji diff --git a/nvim/init.vim b/nvim/init.vim new file mode 100644 index 0000000..0d46c3d --- /dev/null +++ b/nvim/init.vim @@ -0,0 +1,172 @@ +""" +" Plugins +" + +call plug#begin(expand('$XDG_CONFIG_HOME/nvim/plugs')) + +Plug 'ctrlpvim/ctrlp.vim' " Fuzzy file/buffer/mru/tag/etc. finder +Plug 'mattn/emmet-vim' " Emmet-like snippet system +Plug 'tommcdo/vim-exchange' " Easy text exchange operator +Plug 'tpope/vim-git' " Vim runtime files +Plug 'tpope/vim-fugitive' " Git wrapper + +" Asynchronous :make using Neovim's job-control +" Upstream: Plug 'benekastah/neomake' +Plug 'kyrias/neomake', { 'branch': 'clang-check' } + +call plug#end() + + + +""" +" Set options +" + +syntax on +filetype plugin indent on +set hidden " Automatically hide buffers instead of requiring bangcommands +set number " always show line numbers +set ignorecase " Ignore case of normal letters +set smartcase " ignore case if search pattern is all lowercase, + " case-sensitive otherwise +set undolevels=1000 +set wildignore=*.swp,*.bak,*.pyc,*.o +set title " change the terminal's title +set visualbell " don't beep +set noerrorbells " don't beep +set backup " use backup files +set undofile " save undo's after file closes +set shortmess+=I " don't show the nag-screen +set showcmd " Show partial command in the last line of the screen +set scrolloff=1 " Minimum number of screen lines under/above the cursor +set linebreak " Don’t wrap lines in the middle of a word +set spelllang=en_us +set backupdir=$XDG_DATA_HOME/nvim/backup " Don't write backups in current dir + +set tabstop=4 +set shiftwidth=4 +set softtabstop=4 +set noexpandtab +set copyindent + +" Show tabs and end-of-line whitespace +set listchars=tab:»·,trail:· +set list + +" List of vim syntaxes to highlight in rST code blocks +let g:rst_syntax_code_list = ['vim', 'c', 'cpp', 'python', 'sh'] + + + +""" +" Mappings +" + +" Toggle spell checking +nmap <silent> <Leader>s :set spell!<CR> + +nmap <silent> <Leader>/ :nohlsearch<CR> + +cmap w!! w !sudo tee % >/dev/null +" Easier window moving +map <C-h> <C-w>h +map <C-j> <C-w>j +map <C-k> <C-w>k +map <C-l> <C-w>l + +vmap <C-j> gj +vmap <C-k> gk +nmap <C-j> gj +nmap <C-k> gk + + + +""" +" CtrlP +" + +let g:ctrlp_extensions = ['tag', 'buffertag', 'dir', 'undo', 'line', + \ 'changes', 'mixed', 'bookmarkdir'] + +nmap <silent> <Leader>p :CtrlPMixed<CR> + + + +""" +" Statusline +" + +set statusline= +set statusline+=[%n] " Buffer number +set statusline+=%<\ " Where to truncate +set statusline+=%.99f " Relative path to file +set statusline+=\ %y " Filetype flag, [c]; [help] +set statusline+=%w " Preview window flag, [Preview] +set statusline+=%m " Modified flag, [+]; [-] + +" Show a warning if file is read only, [RO] +set statusline+=%#identifier# +set statusline+=%r +set statusline+=%* + +if exists('g:loaded_fugitive') + set statusline+=%{fugitive#statusline()} +endif + +" Show a warning if file format isn’t unix +set statusline+=%#warningmsg# +set statusline+=%{&ff!='unix'?'['.&ff.']':''} +set statusline+=%* + +" Show a warning if file encoding isn’t utf-8 +set statusline+=%#warningmsg# +set statusline+=%{(&fenc!='utf-8'&&&fenc!='')?'['.&fenc.']':''} +set statusline+=%* + + +"" Right side of statusline +set statusline+=%= " Left/right separation point +set statusline+=%-15.((%l,%c-%v)\ %) " Line, column, percentage. (20,0) +set statusline+=%P " Percentage visible + +set laststatus=2 " Always show statusline + + + +""" +" Syntax highlighting +" + +" Colorscheme +colorscheme Darkcustomside + +" Color spaces at end of lines bright red for visibility +highlight ExtraWhitespace ctermbg=red guibg=red +match ExtraWhitespace /\s\+$/ +autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ +autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/ +autocmd InsertLeave * match ExtraWhitespace /\s\+$/ +autocmd BufWinLeave * call clearmatches() + + + +""" +" Indentation +" + +augroup indentation + autocmd! + autocmd FileType yaml setlocal ts=2 sts=2 sw=2 noet +augroup END + + + +""" +" Neomake +" + +" Open the location list when adding entries +let g:neomake_open_list = 2 + +" Run Neomake automatically when saving and entering a file +autocmd! BufWritePost * Neomake diff --git a/pentadactyl/chrome.css b/pentadactyl/chrome.css deleted file mode 100644 index bf2ea10..0000000 --- a/pentadactyl/chrome.css +++ /dev/null @@ -1,50 +0,0 @@ -/* ~/.config/pentadactyl/chrome.css */ - -@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); - -/* Get rid of the bottom border */ -#TabsToolbar:after { - border-bottom: 0px !important; -} - -/* Hide the new curved tab edges */ -.tab-background { - opacity: 0 !important; -} - -/* Hide the little graphic seperator between inactive tabs */ -.tabbrowser-tab:before, -.tabbrowser-tab:after { - visibility: hidden !important; -} - -/* Reduce the padding around the contents of a tab */ -.tabbrowser-tab .tab-content, -.tabbrowser-tab[selected] .tab-content { - padding: 0 2px 2px 4px !important; -} - -#TabsToolbar { - -moz-appearance: none !important; - background: #dedede !important; -} - -/* Hide the newtab button */ -.tabs-newtab-button { - display: none !important; -} - -/* Mostly hacks to try deal with tab overflow, it's not pretty */ -#tabbrowser-tabs { - margin-left: -15px !important; - margin-right: -15px !important; -} - -.tabbrowser-tab { - color: #000 !important; -} - -.tabbrowser-tab[selected] { - background: #787777 !important; - color: #efefef !important; -} diff --git a/pentadactyl/colors/wikipedia.org.penta b/pentadactyl/colors/wikipedia.org.penta deleted file mode 100644 index 5bc15ad..0000000 --- a/pentadactyl/colors/wikipedia.org.penta +++ /dev/null @@ -1,115 +0,0 @@ -style -append wikipedia.org <<EOF -body { - background: #EFEFEE !important; - text-align: justify !important; - font-family: "Linux Libertine O" !important; - font-size: 1.2em !important; -} - -span.mw-editsection { - display: none !important; -} - -h1 { - font-size: 2.2em !important; - font-weight: bold !important; - font-style: italic !important; - font-family: "Heuristica" !important; - color: #888889 !important; - overflow: visible !important; -} - -h2 { - font-size: 2em !important; - font-weight: bold !important; - font-style: italic !important; - font-family: "Heuristica" !important; - color: #888889 !important; - overflow: visible !important; -} - -h3 { - font-size: 1em !important; - font-weight: bold !important; - font-style: italic !important; - font-family: "Heuristica" !important; - color: #888889 !important; - overflow: visible !important; -} - - -table.vertical-navbox.nowraplinks { - width: 0em !important; - border: none !important; - padding: 0em !important; - border-spacing: none !important; -} - -#mw-page-base { - background: #EFEFEE !important; - background-image: none !important; -} - -div#mw-panel,div#mw-head { - display: none !important; -} - -div#toc.toc { - border: none !important; - display: block !important; - background: inherit !important; -} - -table.ambox { - display: none !important; -} - -div#content { - margin-left: 6em !important; - margin-right: 6em !important; - color: #444448 !important; - background: #EEEEDE !important; - box-shadow: inset 0 0 0.5em #AAA !important; - border-color: #666667 !important; - border-style: none !important; - border-radius: 0.1em; -} - -div#toctitle { - text-align: left !important; -} - -span.toctoggle { - display: none !important; -} - -div#footer { - margin-left: 6em !important; - margin-right: 6em !important; -} - -table.infobox td { - text-align: right !important; -} - -table.infobox tr td:nth-child(1) { - text-align: left !important; -} - -table.infobox, -table.infobox.vcard { - border: none !important; - margin: -0 0 0 0 !important; - padding: none !important; - background: none !important; - float: none !important; - color: inherit !important; - width: 100% !important; -} - -div#siteSub, -div#contentSub { - font-style: italic !important; - margin: -0 0 0 0 !important; -} -EOF diff --git a/pentadactyl/pentadactylrc b/pentadactyl/pentadactylrc deleted file mode 100644 index e2bad71..0000000 --- a/pentadactyl/pentadactylrc +++ /dev/null @@ -1,66 +0,0 @@ -" ~/.pentadactylrc - -set runtimepath=~/.config/pentadactyl - -loadplugins '\.(js|penta)$' -group user -highlight FontFixed font-family: monospace !important; font: 12px "Source Code Pro" !important; -map -modes=n -silent C -javascript commands.execute('!(mpv "' - \ + content.location.href.replace(/([$`"\\])/g, "\\$1") - \ + '") &'); -set defsearch=duckduckgoog - - -" ui -source ~/.config/pentadactyl/chrome.css -set guioptions=Csn -set hlfind - -" Speed up scrolling -nmap -b h 5h -nmap -b j 5j -nmap -b k 5k -nmap -b l 5l - -" Tab control -nmap <A-h> -e :tabprev -nmap <A-l> -e :tabnext -nmap <A-S-h> -e :tabmove -1 -nmap <A-S-l> -e :tabmove +1 - -" Toggle bookmark toolbar -nmap <A-b> -e :toolbartoggle Bookmarks Toolbar - -" Easily show downloads -nmap <S-d> -e :downloads - -" Stop <C-j> and <C-k> doing whatever it does -nmap <C-j> <nop> -nmap <C-k> <nop> - -nmap <A> <nop> - -" Open the current URL as an argument to yt-dl -nmap <S-u> -e :launchv - -" Same above but with quvi -nmap <S-q> -e :launchvq - -" Use vim instead of gvim for now -set editor='termite -e "vim +<line> <file>"' - -" Hide the status bar when using fullscreen -au fullscreen on set go-=s -au fullscreen off set go+=s - -" Change some default about:configs -set! noscript.keys.tempAllowPage="alt z" -set! noscript.keys.revokeTemp="alt c" -"set! noscript.notify=false -set! plugins.click_to_play=true -set! plugin.default.state=1 - -" Require websites preform safe ssl negotiation -set! security.ssl.treat_unsafe_negotiation_as_broken=true - -" vim: ft=pentadactyl @@ -1,5 +1,5 @@ Host * - HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-ed25519,ssh-rsa + HostKeyAlgorithms ssh-ed25519,ssh-rsa KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com @@ -10,12 +10,17 @@ Host * GSSAPIAuthentication yes PubkeyAuthentication yes + Host *.kyriasis.com GSSAPIDelegateCredentials yes ForwardAgent yes ForwardX11 yes ForwardX11Trusted yes +Host git.kyriasis.com + User git + PubkeyAuthentication no + Host theos hostname theos.kyriasis.com PubkeyAuthentication no @@ -23,11 +28,11 @@ Host theos Host lucifer hostname lucifer.kyriasis.com -Host git.kyriasis.com - User git - PubkeyAuthentication no -Host aur-dev.archlinux.org - IdentityFile ~/.ssh/id_ed25519 +Host *.archlinux.org + IdentityFile ~/.config/ssh/id_ed25519 + ForwardAgent yes + User demize + +Host aur.archlinux.org User aur - Port 2222 diff --git a/systemd/user/dumpwatch.service b/systemd/user/dumpwatch.service new file mode 100644 index 0000000..657424b --- /dev/null +++ b/systemd/user/dumpwatch.service @@ -0,0 +1,10 @@ +[Unit] +Description=Watch ~/dumpdir for things to upload to theos + +[Service] +Environment=dump_host=theos.kyriasis.com +Environment=dump_user=kyrias +ExecStart=/home/kyrias/.local/bin/dumpwatch.zsh + +[Install] +WantedBy=default.target diff --git a/termite/config b/termite/config index 8118806..6d5b01e 100644 --- a/termite/config +++ b/termite/config @@ -9,7 +9,7 @@ allow_bold = true dynamic_title = true urgent_on_bell = true clickable_url = true -font = Source Code Pro for Powerline 9 +font = FNCP6 11.2 scrollback_lines = 1000 search_wrap = true icon_name = terminal diff --git a/vim/after/ftplugin/python.vim b/vim/after/ftplugin/python.vim new file mode 100644 index 0000000..2a3d549 --- /dev/null +++ b/vim/after/ftplugin/python.vim @@ -0,0 +1,4 @@ +setlocal shiftwidth=4 +setlocal tabstop=4 +setlocal softtabstop=4 +setlocal expandtab @@ -78,9 +78,6 @@ set noexpandtab " Automatically hide buffers instead of requiring bangcommands set hidden -" Yank to clipboard/selection by default -set clipboard=unnamed,unnamedplus - " Easier window moving map <C-h> <C-w>h map <C-j> <C-w>j diff --git a/weechat/aspell.conf b/weechat/aspell.conf index 3f5c675..a408f98 100644 --- a/weechat/aspell.conf +++ b/weechat/aspell.conf @@ -9,7 +9,7 @@ suggestions = default [check] commands = "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic" default_dict = "en" -during_search = off +during_search = on enabled = on real_time = on suggestions = 0 diff --git a/weechat/colorize_nicks.conf b/weechat/colorize_nicks.conf new file mode 100644 index 0000000..1b6e461 --- /dev/null +++ b/weechat/colorize_nicks.conf @@ -0,0 +1,12 @@ +# +# weechat -- colorize_nicks.conf +# + +[look] +blacklist_channels = "" +blacklist_nicks = "so,root" +colorize_input = on +greedy_matching = on +ignore_nicks_in_urls = off +ignore_tags = "" +min_nick_length = 2 diff --git a/weechat/irc.conf b/weechat/irc.conf index eae28de..811b43b 100644 --- a/weechat/irc.conf +++ b/weechat/irc.conf @@ -23,8 +23,8 @@ display_join_message = "329,332,333" display_old_topic = on display_pv_away_once = on display_pv_back = on -highlight_channel = "$nick" -highlight_pv = "$nick" +highlight_channel = "$nick,demize,demi,remi,remize,kyrias" +highlight_pv = "" highlight_server = "$nick" highlight_tags_restrict = "irc_privmsg,irc_notice" item_away_message = on @@ -136,7 +136,7 @@ sasl_password = "" sasl_timeout = 15 sasl_username = "" ssl = on -ssl_cert = "%h/keys/demize.pem" +ssl_cert = "%h/keys/znc-cert.pem" ssl_dhkey_size = 512 ssl_fingerprint = "" ssl_priorities = "NORMAL" @@ -296,3 +296,41 @@ Therian.default_msg_kick Therian.default_msg_part Therian.default_msg_quit Therian.notify +HypeIRC.addresses = "theos.kyriasis.com/6697" +HypeIRC.proxy +HypeIRC.ipv6 +HypeIRC.ssl +HypeIRC.ssl_cert +HypeIRC.ssl_priorities +HypeIRC.ssl_dhkey_size +HypeIRC.ssl_fingerprint +HypeIRC.ssl_verify +HypeIRC.password = "kyrias/HypeIRC:" +HypeIRC.capabilities +HypeIRC.sasl_mechanism +HypeIRC.sasl_username +HypeIRC.sasl_password +HypeIRC.sasl_key +HypeIRC.sasl_timeout +HypeIRC.sasl_fail +HypeIRC.autoconnect = on +HypeIRC.autoreconnect +HypeIRC.autoreconnect_delay +HypeIRC.nicks +HypeIRC.username +HypeIRC.realname +HypeIRC.local_hostname +HypeIRC.command +HypeIRC.command_delay +HypeIRC.autojoin +HypeIRC.autorejoin +HypeIRC.autorejoin_delay +HypeIRC.connection_timeout +HypeIRC.anti_flood_prio_high +HypeIRC.anti_flood_prio_low +HypeIRC.away_check +HypeIRC.away_check_max_nicks +HypeIRC.default_msg_kick +HypeIRC.default_msg_part +HypeIRC.default_msg_quit +HypeIRC.notify diff --git a/weechat/perl/buffers.pl b/weechat/perl/buffers.pl index 472f6e9..c31d8fc 100644 --- a/weechat/perl/buffers.pl +++ b/weechat/perl/buffers.pl @@ -20,6 +20,8 @@ # # History: # +# 2015-03-29, Ed Santiago <ed@edsantiago.com> +# v5.1: merged buffers: always indent, except when filling is horizontal # 2014-12-12 # v5.0: fix cropping non-latin buffer names # 2014-08-29, Patrick Steinhardt <ps@pks.im>: @@ -164,7 +166,7 @@ use strict; use Encode qw( decode encode ); # -----------------------------[ internal ]------------------------------------- my $SCRIPT_NAME = "buffers"; -my $SCRIPT_VERSION = "5.0"; +my $SCRIPT_VERSION = "5.1"; my $BUFFERS_CONFIG_FILE_NAME = "buffers"; my $buffers_config_file; @@ -1298,8 +1300,17 @@ sub build_buffers } else { - my $indent = ""; - $indent = ((" " x length($buffer->{"number"}))." ") if (($position eq "left") || ($position eq "right")); + # Indentation aligns channels in a visually appealing way + # when viewing list top-to-bottom... + my $indent = (" " x length($buffer->{"number"}))." "; + # ...except when list is top/bottom and channels left-to-right. + my $option_pos = weechat::config_string( weechat::config_get( "weechat.bar.buffers.position" ) ); + if (($option_pos eq 'top') || ($option_pos eq 'bottom')) { + my $option_filling = weechat::config_string( weechat::config_get( "weechat.bar.buffers.filling_top_bottom" ) ); + if ($option_filling =~ /horizontal/) { + $indent = ''; + } + } $str .= weechat::color("default") .$color_bg .$indent; diff --git a/weechat/perl/iset.pl b/weechat/perl/iset.pl index f179022..af74767 100644 --- a/weechat/perl/iset.pl +++ b/weechat/perl/iset.pl @@ -1,6 +1,6 @@ # # Copyright (C) 2008-2014 Sebastien Helleu <flashcode@flashtux.org> -# Copyright (C) 2010-2014 Nils Görs <weechatter@arcor.de> +# Copyright (C) 2010-2015 Nils Görs <weechatter@arcor.de> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,6 +19,12 @@ # # History: # +# 2015-05-16, Sebastien Helleu <flashcode@flashtux.org>: +# version 3.9: fix cursor position when editing an option with WeeChat >= 1.2 +# 2015-05-02, arza <arza@arza.us>: +# version 3.8: don't append "null" to /set when setting an undefined setting +# 2015-05-01, nils_2 <weechatter@arcor.de>: +# version 3.7: fix two perl warnings (reported by t3chguy) # 2014-09-30, arza <arza@arza.us>: # version 3.6: fix current line counter when options aren't found # 2014-06-03, nils_2 <weechatter@arcor.de>: @@ -117,7 +123,7 @@ use strict; my $PRGNAME = "iset"; -my $VERSION = "3.6"; +my $VERSION = "3.9"; my $DESCR = "Interactive Set for configuration options"; my $AUTHOR = "Sebastien Helleu <flashcode\@flashtux.org>"; my $LICENSE = "GPL3"; @@ -237,6 +243,10 @@ sub iset_create_filter sub iset_buffer_input { my ($data, $buffer, $string) = ($_[0], $_[1], $_[2]); + + # string begins with space? + return weechat::WEECHAT_RC_OK if (substr($string, 0, 1 ) eq " "); + if ($string eq "q") { weechat::buffer_close($buffer); @@ -976,22 +986,34 @@ sub iset_cmd_cb my $value = $options_values[$current_line]; if ($options_is_null[$current_line]) { - $value = "null"; + $value = ""; } else { $quote = "\"" if ($options_types[$current_line] eq "string"); } + $value = " ".$quote.$value.$quote if ($value ne "" or $quote ne ""); + my $set_command = "/set"; - $set_command = "/mute " . $set_command if (weechat::config_boolean($options_iset{"use_mute"}) == 1); - - weechat::buffer_set($iset_buffer, "input", $set_command." ".$options_names[$current_line]." ".$quote.$value.$quote); - weechat::command($iset_buffer, "/input move_beginning_of_line"); - weechat::command($iset_buffer, "/input move_next_word"); - weechat::command($iset_buffer, "/input move_next_word"); - weechat::command($iset_buffer, "/input move_next_word") if (weechat::config_boolean($options_iset{"use_mute"}) == 1); - weechat::command($iset_buffer, "/input move_next_char"); - weechat::command($iset_buffer, "/input move_next_char") if ($quote ne ""); + my $start_index = 5; + if (weechat::config_boolean($options_iset{"use_mute"}) == 1) + { + $set_command = "/mute ".$set_command; + $start_index += 11; + } + $set_command = $set_command." ".$options_names[$current_line].$value; + my $pos_space = index($set_command, " ", $start_index); + if ($pos_space < 0) + { + $pos_space = 9999; + } + else + { + $pos_space = $pos_space + 1; + $pos_space = $pos_space + 1 if ($quote ne ""); + } + weechat::buffer_set($iset_buffer, "input", $set_command); + weechat::buffer_set($iset_buffer, "input_pos", "".$pos_space); } } weechat::bar_item_update("isetbar_help") if (weechat::config_boolean($options_iset{"show_help_bar"}) == 1); @@ -1162,6 +1184,8 @@ sub iset_hsignal_mouse_cb { my ($data, $signal, %hash) = ($_[0], $_[1], %{$_[2]}); + return weechat::WEECHAT_RC_OK unless (@options_types); + if ($hash{"_buffer_name"} eq $PRGNAME && ($hash{"_buffer_plugin"} eq $LANG)) { if ($hash{"_key"} eq "button1") diff --git a/weechat/perl/stalker.pl b/weechat/perl/stalker.pl index b418fad..ce2bb65 100644 --- a/weechat/perl/stalker.pl +++ b/weechat/perl/stalker.pl @@ -20,6 +20,9 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # # History: +# version 1.5:nils_2@freenode.#weechat +# 2015-06-15: add: new option del_date +# # version 1.4:nils_2@freenode.#weechat # 2014-05-14: fix: perl error under some circumstances (thanks Piotrek) # @@ -98,7 +101,7 @@ use File::Spec; use DBI; my $SCRIPT_NAME = "stalker"; -my $SCRIPT_VERSION = "1.4"; +my $SCRIPT_VERSION = "1.5"; my $SCRIPT_AUTHOR = "Nils Görs <weechatter\@arcor.de>"; my $SCRIPT_LICENCE = "GPL3"; my $SCRIPT_DESC = "Records and correlates nick!user\@host information"; @@ -777,6 +780,15 @@ sub _deassociate_nick_from_host return $sth->rows; } +sub delete_older_entries +{ + # $day = yyyy-mm-dd + my ( $day1, $day2 ) = @_; + # from date ? to date ? + $sth = $DBH->prepare( "DELETE FROM records WHERE added >= '" . $day1 . "' AND added < '" . $day2 . "'" ); + $sth->execute(); +} + # ------------------------[ OUTPUT with tags ]------------------------------ sub OUTPUT { @@ -934,6 +946,10 @@ sub stalker_command_cb my $DEBUG_prefix = weechat::config_string(weechat::config_get('weechat.look.prefix_error')); weechat::print($buffer, _color_str($color, $DEBUG_prefix) . "\t$SCRIPT_NAME: $affected_rows deleted"); } + elsif (lc($args_array[0]) eq 'del_date') + { + delete_older_entries($args_array[1],$args_array[2]) if ($args_array[1] and $args_array[2]); + } return weechat::WEECHAT_RC_OK; } @@ -1370,6 +1386,7 @@ weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION, " scan : scan a channel (be careful; scanning large channels takes a while!)\n". " you should manually /WHO #channel first or use /quote PROTOCTL UHNAMES\n". " count: display the number of rows in database\n". + " del_date: delete all entries from date1 to date2\n". "remove_nick_from_host: remove a nick from a given host\n". "\n\n". "Stalker will add nick!user\@host to database monitoring JOIN/WHOIS/NICK messages.\n\n". @@ -1411,8 +1428,11 @@ weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION, " /".$SCRIPT_NAME." host .*\\.de -regex\n". " remove nick from an association host'\n". " /".$SCRIPT_NAME." remove_nick_from_host TheNick ~the\@bad.users.host\n". + " remove entries from database in range of given date:'\n". + " /".$SCRIPT_NAME." del_date 2014-01-01 2014-12-31\n". "", "count %-||". + "del_date %-||". "host %% %(irc_servers)|-regex %-||". "nick %(nick) %(irc_servers)|-regex -regex %-||". "remove_nick_from_host %(nick) |-regex -regex %-||". diff --git a/weechat/plugins.conf b/weechat/plugins.conf index 0722f63..7bad995 100644 --- a/weechat/plugins.conf +++ b/weechat/plugins.conf @@ -129,7 +129,7 @@ python.announce_url_title.buffers = "freenode.#testing," python.announce_url_title.buffers_notice = "freenode.#testing," python.announce_url_title.global = "on" python.announce_url_title.global_prefix = "url" -python.announce_url_title.ignore_buffers = "freenode.#archlinux,freenode.#archlinux-offtopic,freenode.#archers,freenode.#archlinux-mordor,freenode.#archlinux-bugs,freenode.#archlinux-women,freenode.#archlinux-women-dev,freenode.#kyriasis,freenode.#archlinux-tu" +python.announce_url_title.ignore_buffers = "freenode.#archlinux,freenode.#archlinux-offtopic,freenode.#archers,freenode.#archlinux-mordor,freenode.#archlinux-bugs,freenode.#archlinux-women,freenode.#archlinux-women-dev,freenode.#kyriasis,freenode.#archlinux-tu,freenode.#archlinux-pacman,freenode.#lojban,freenode.#systemd" python.announce_url_title.prefix = "" python.announce_url_title.reannounce_wait = "5" python.announce_url_title.suffix = "" @@ -147,7 +147,7 @@ python.chanop.enable_multi_kick = "off" python.chanop.enable_remove = "off" python.chanop.kick_reason = "" python.chanop.op_command = "/msg chanserv op $channel $nick" -python.chanop.watchlist.freenode = "#kyriasis,#archlinux-botabuse,#archlinux-unregistered,#archlinux-offtopic" +python.chanop.watchlist.freenode = "#archlinux-classroom,#archlinux-botabuse,#archlinux,#archlinux-unregistered,#archlinux-offtopic,#kyriasis" python.check_license = "on" python.clone_scanner.autofocus = "on" python.clone_scanner.clone_onjoin_alert_key = "mask" @@ -216,22 +216,13 @@ python.notify.nick_separator = ": " python.notify.notify_when_away = "on" python.notify.show_hilights = "on" python.notify.show_priv_msg = "on" -python.notify.smart_notification = "off" +python.notify.smart_notification = "on" python.notify.urgency = "normal" -python.shortenurl.color = "red" -python.shortenurl.ignore_list = "http://is.gd,http://tinyurl.com" -python.shortenurl.short_own = "off" -python.shortenurl.shortener = "isgd" -python.shortenurl.urllength = "30" python.slack_extension.channels_not_on_current_server_color = "0" python.slack_extension.colorize_nicks = "1" python.slack_extension.debug_mode = "" python.slack_extension.distracting_channels = "" python.slack_extension.trigger_value = "0" -python.tinyurl.debug = "off" -python.tinyurl.printall = "on" -python.tinyurl.service = "tinyurl" -python.tinyurl.urllength = "30" python.title.short_name = "on" python.title.title_priority = "2" python.whois_on_query.command = "/whois $nick $nick" diff --git a/weechat/python/colorize_nicks.py b/weechat/python/colorize_nicks.py index d7b3b70..5978253 100644 --- a/weechat/python/colorize_nicks.py +++ b/weechat/python/colorize_nicks.py @@ -21,6 +21,12 @@ # # # History: +# 2015-04-19, xt +# version 20: fix ignore of nicks in URLs +# 2015-04-18, xt +# version 19: new option ignore nicks in URLs +# 2015-03-03, xt +# version 18: iterate buffers looking for nicklists instead of servers # 2015-02-23, holomorph # version 17: fix coloring in non-channel buffers (#58) # 2014-09-17, holomorph @@ -67,7 +73,7 @@ w = weechat SCRIPT_NAME = "colorize_nicks" SCRIPT_AUTHOR = "xt <xt@bash.no>" -SCRIPT_VERSION = "17" +SCRIPT_VERSION = "20" SCRIPT_LICENSE = "GPL" SCRIPT_DESC = "Use the weechat nick colors in the chat area" @@ -126,6 +132,10 @@ def colorize_config_init(): colorize_config_file, section_look, "greedy_matching", "boolean", "If off, then use lazy matching instead", "", 0, 0, "on", "on", 0, "", "", "", "", "", "") + colorize_config_option["ignore_nicks_in_urls"] = weechat.config_new_option( + colorize_config_file, section_look, "ignore_nicks_in_urls", + "boolean", "If on, don't colorize nicks inside URLs", "", 0, + 0, "off", "off", 0, "", "", "", "", "", "") def colorize_config_read(): ''' Read configuration file. ''' @@ -144,6 +154,7 @@ def colorize_cb(data, modifier, modifier_data, line): global ignore_nicks, ignore_channels, colored_nicks + full_name = modifier_data.split(';')[1] channel = '.'.join(full_name.split('.')[1:]) @@ -171,6 +182,7 @@ def colorize_cb(data, modifier, modifier_data, line): # Check that nick is not ignored and longer than minimum length if len(nick) < min_length or nick in ignore_nicks: continue + # Check that nick is in the dictionary colored_nicks if nick in colored_nicks[buffer]: nick_color = colored_nicks[buffer][nick] @@ -178,6 +190,10 @@ def colorize_cb(data, modifier, modifier_data, line): # Let's use greedy matching. Will check against every word in a line. if w.config_boolean(colorize_config_option['greedy_matching']): for word in line.split(): + if w.config_boolean(colorize_config_option['ignore_nicks_in_urls']) and \ + word.startswith(('http://', 'https://')): + continue + if nick in word: # Is there a nick that contains nick and has a greater lenght? # If so let's save that nick into var biggest_nick @@ -247,30 +263,23 @@ def populate_nicks(*args): colored_nicks = {} - servers = w.infolist_get('irc_server', '', '') - while w.infolist_next(servers): - servername = w.infolist_string(servers, 'name') - colored_nicks[servername] = {} - my_nick = w.info_get('irc_nick', servername) - channels = w.infolist_get('irc_channel', '', servername) - while w.infolist_next(channels): - pointer = w.infolist_pointer(channels, 'buffer') - nicklist = w.infolist_get('nicklist', pointer, '') - - if pointer not in colored_nicks: - colored_nicks[pointer] = {} - - while w.infolist_next(nicklist): - nick = w.infolist_string(nicklist, 'name') - nick_color = colorize_nick_color(nick, my_nick) + buffers = w.infolist_get('buffer', '', '') + while w.infolist_next(buffers): + buffer_ptr = w.infolist_pointer(buffers, 'pointer') + my_nick = w.buffer_get_string(buffer_ptr, 'localvar_nick') + nicklist = w.infolist_get('nicklist', buffer_ptr, '') + while w.infolist_next(nicklist): + if buffer_ptr not in colored_nicks: + colored_nicks[buffer_ptr] = {} - colored_nicks[pointer][nick] = nick_color + nick = w.infolist_string(nicklist, 'name') + nick_color = colorize_nick_color(nick, my_nick) - w.infolist_free(nicklist) + colored_nicks[buffer_ptr][nick] = nick_color - w.infolist_free(channels) + w.infolist_free(nicklist) - w.infolist_free(servers) + w.infolist_free(buffers) return w.WEECHAT_RC_OK diff --git a/weechat/python/go.py b/weechat/python/go.py new file mode 100644 index 0000000..0e5b6bd --- /dev/null +++ b/weechat/python/go.py @@ -0,0 +1,490 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009-2014 Sébastien Helleu <flashcode@flashtux.org> +# Copyright (C) 2010 m4v <lambdae2@gmail.com> +# Copyright (C) 2011 stfn <stfnmd@googlemail.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +# +# History: +# +# 2014-05-12, Sébastien Helleu <flashcode@flashtux.org>: +# version 2.0: add help on options, replace option "sort_by_activity" by +# "sort" (add sort by name and first match at beginning of +# name and by number), PEP8 compliance +# 2012-11-26, Nei <anti.teamidiot.de> +# version 1.9: add auto_jump option to automatically go to buffer when it +# is uniquely selected +# 2012-09-17, Sébastien Helleu <flashcode@flashtux.org>: +# version 1.8: fix jump to non-active merged buffers (jump with buffer name +# instead of number) +# 2012-01-03 nils_2 <weechatter@arcor.de> +# version 1.7: add option use_core_instead_weechat +# 2012-01-03, Sébastien Helleu <flashcode@flashtux.org>: +# version 1.6: make script compatible with Python 3.x +# 2011-08-24, stfn <stfnmd@googlemail.com>: +# version 1.5: /go with name argument jumps directly to buffer +# Remember cursor position in buffer input +# 2011-05-31, Elián Hanisch <lambdae2@gmail.com>: +# version 1.4: Sort list of buffers by activity. +# 2011-04-25, Sébastien Helleu <flashcode@flashtux.org>: +# version 1.3: add info "go_running" (used by script input_lock.rb) +# 2010-11-01, Sébastien Helleu <flashcode@flashtux.org>: +# version 1.2: use high priority for hooks to prevent conflict with other +# plugins/scripts (WeeChat >= 0.3.4 only) +# 2010-03-25, Elián Hanisch <lambdae2@gmail.com>: +# version 1.1: use a space for match the end of a string +# 2009-11-16, Sébastien Helleu <flashcode@flashtux.org>: +# version 1.0: add new option for displaying short names +# 2009-06-15, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.9: fix typo in /help go with command /key +# 2009-05-16, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.8: search buffer by number, fix bug when window is split +# 2009-05-03, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.7: eat tab key (do not complete input, just move buffer +# pointer) +# 2009-05-02, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.6: sync with last API changes +# 2009-03-22, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.5: update modifier signal name for input text display, +# fix arguments for function string_remove_color +# 2009-02-18, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.4: do not hook command and init options if register failed +# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.3: case insensitive search for buffers names +# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.2: add help about Tab key +# 2009-02-08, Sébastien Helleu <flashcode@flashtux.org>: +# version 0.1: initial release +# + +""" +Quick jump to buffers. +(this script requires WeeChat 0.3.0 or newer) +""" + +from __future__ import print_function + +SCRIPT_NAME = 'go' +SCRIPT_AUTHOR = 'Sébastien Helleu <flashcode@flashtux.org>' +SCRIPT_VERSION = '2.0' +SCRIPT_LICENSE = 'GPL3' +SCRIPT_DESC = 'Quick jump to buffers' + +SCRIPT_COMMAND = 'go' + +IMPORT_OK = True + +try: + import weechat +except ImportError: + print('This script must be run under WeeChat.') + print('Get WeeChat now at: http://www.weechat.org/') + IMPORT_OK = False + +import re + +# script options +SETTINGS = { + 'color_number': ( + 'yellow,magenta', + 'color for buffer number (not selected)'), + 'color_number_selected': ( + 'yellow,red', + 'color for selected buffer number'), + 'color_name': ( + 'black,cyan', + 'color for buffer name (not selected)'), + 'color_name_selected': ( + 'black,brown', + 'color for a selected buffer name'), + 'color_name_highlight': ( + 'red,cyan', + 'color for highlight in buffer name (not selected)'), + 'color_name_highlight_selected': ( + 'red,brown', + 'color for highlight in a selected buffer name'), + 'message': ( + 'Go to: ', + 'message to display before list of buffers'), + 'short_name': ( + 'off', + 'display and search in short names instead of buffer name'), + 'sort': ( + 'number,beginning', + 'comma-separated list of keys to sort buffers ' + '(the order is important, sorts are performed in the given order): ' + 'name = sort by name (or short name), ', + 'hotlist = sort by hotlist order, ' + 'number = first match a buffer number before digits in name, ' + 'beginning = first match at beginning of names (or short names); ' + 'the default sort of buffers is by numbers'), + 'use_core_instead_weechat': ( + 'off', + 'use name "core" instead of "weechat" for core buffer'), + 'auto_jump': ( + 'off', + 'automatically jump to buffer when it is uniquely selected'), +} + +# hooks management +HOOK_COMMAND_RUN = { + 'input': ('/input *', 'go_command_run_input'), + 'buffer': ('/buffer *', 'go_command_run_buffer'), + 'window': ('/window *', 'go_command_run_window'), +} +hooks = {} + +# input before command /go (we'll restore it later) +saved_input = '' +saved_input_pos = 0 + +# last user input (if changed, we'll update list of matching buffers) +old_input = None + +# matching buffers +buffers = [] +buffers_pos = 0 + + +def go_option_enabled(option): + """Checks if a boolean script option is enabled or not.""" + return weechat.config_string_to_boolean(weechat.config_get_plugin(option)) + + +def go_info_running(data, info_name, arguments): + """Returns "1" if go is running, otherwise "0".""" + return '1' if 'modifier' in hooks else '0' + + +def go_unhook_one(hook): + """Unhook something hooked by this script.""" + global hooks + if hook in hooks: + weechat.unhook(hooks[hook]) + del hooks[hook] + + +def go_unhook_all(): + """Unhook all.""" + go_unhook_one('modifier') + for hook in HOOK_COMMAND_RUN: + go_unhook_one(hook) + + +def go_hook_all(): + """Hook command_run and modifier.""" + global hooks + priority = '' + version = weechat.info_get('version_number', '') or 0 + # use high priority for hook to prevent conflict with other plugins/scripts + # (WeeChat >= 0.3.4 only) + if int(version) >= 0x00030400: + priority = '2000|' + for hook, value in HOOK_COMMAND_RUN.items(): + if hook not in hooks: + hooks[hook] = weechat.hook_command_run( + '%s%s' % (priority, value[0]), + value[1], '') + if 'modifier' not in hooks: + hooks['modifier'] = weechat.hook_modifier( + 'input_text_display_with_cursor', 'go_input_modifier', '') + + +def go_start(buf): + """Start go on buffer.""" + global saved_input, saved_input_pos, old_input, buffers_pos + go_hook_all() + saved_input = weechat.buffer_get_string(buf, 'input') + saved_input_pos = weechat.buffer_get_integer(buf, 'input_pos') + weechat.buffer_set(buf, 'input', '') + old_input = None + buffers_pos = 0 + + +def go_end(buf): + """End go on buffer.""" + global saved_input, saved_input_pos, old_input + go_unhook_all() + weechat.buffer_set(buf, 'input', saved_input) + weechat.buffer_set(buf, 'input_pos', str(saved_input_pos)) + old_input = None + + +def go_match_beginning(buf, string): + """Check if a string matches the beginning of buffer name/short name.""" + if not string: + return False + esc_str = re.escape(string) + if re.search(r'^#?' + esc_str, buf['name']) \ + or re.search(r'^#?' + esc_str, buf['short_name']): + return True + return False + + +def go_now(buf, args): + """Go to buffer specified by args.""" + listbuf = go_matching_buffers(args) + if not listbuf: + return + + # prefer buffer that matches at beginning (if option is enabled) + if 'beginning' in weechat.config_get_plugin('sort').split(','): + for index in range(len(listbuf)): + if go_match_beginning(listbuf[index], args): + weechat.command(buf, + '/buffer ' + str(listbuf[index]['full_name'])) + return + + # jump to first buffer in matching buffers by default + weechat.command(buf, '/buffer ' + str(listbuf[0]['full_name'])) + + +def go_cmd(data, buf, args): + """Command "/go": just hook what we need.""" + global hooks + if args: + go_now(buf, args) + elif 'modifier' in hooks: + go_end(buf) + else: + go_start(buf) + return weechat.WEECHAT_RC_OK + + +def go_matching_buffers(strinput): + """Return a list with buffers matching user input.""" + global buffers_pos + listbuf = [] + if len(strinput) == 0: + buffers_pos = 0 + strinput = strinput.lower() + infolist = weechat.infolist_get('buffer', '', '') + while weechat.infolist_next(infolist): + short_name = weechat.infolist_string(infolist, 'short_name') + if go_option_enabled('short_name'): + name = weechat.infolist_string(infolist, 'short_name') + else: + name = weechat.infolist_string(infolist, 'name') + if name == 'weechat' and go_option_enabled('use_core_instead_weechat'): + name = 'core' + number = weechat.infolist_integer(infolist, 'number') + full_name = weechat.infolist_string(infolist, 'full_name') + if not full_name: + full_name = '%s.%s' % ( + weechat.infolist_string(infolist, 'plugin_name'), + weechat.infolist_string(infolist, 'name')) + pointer = weechat.infolist_pointer(infolist, 'pointer') + matching = name.lower().find(strinput) >= 0 + if not matching and strinput[-1] == ' ': + matching = name.lower().endswith(strinput.strip()) + if not matching and strinput.isdigit(): + matching = str(number).startswith(strinput) + if len(strinput) == 0 or matching: + listbuf.append({ + 'number': number, + 'short_name': short_name, + 'name': name, + 'full_name': full_name, + 'pointer': pointer, + }) + weechat.infolist_free(infolist) + + # sort buffers + hotlist = [] + infolist = weechat.infolist_get('hotlist', '', '') + while weechat.infolist_next(infolist): + hotlist.append( + weechat.infolist_pointer(infolist, 'buffer_pointer')) + weechat.infolist_free(infolist) + last_index_hotlist = len(hotlist) + + def _sort_name(buf): + """Sort buffers by name (or short name).""" + return buf['name'] + + def _sort_hotlist(buf): + """Sort buffers by hotlist order.""" + try: + return hotlist.index(buf['pointer']) + except ValueError: + # not in hotlist, always last. + return last_index_hotlist + + def _sort_match_number(buf): + """Sort buffers by match on number.""" + return 0 if str(buf['number']) == strinput else 1 + + def _sort_match_beginning(buf): + """Sort buffers by match at beginning.""" + return 0 if go_match_beginning(buf, strinput) else 1 + + funcs = { + 'name': _sort_name, + 'hotlist': _sort_hotlist, + 'number': _sort_match_number, + 'beginning': _sort_match_beginning, + } + + for key in weechat.config_get_plugin('sort').split(','): + if key in funcs: + listbuf = sorted(listbuf, key=funcs[key]) + + if not strinput: + index = [i for i, buf in enumerate(listbuf) + if buf['pointer'] == weechat.current_buffer()] + if index: + buffers_pos = index[0] + + return listbuf + + +def go_buffers_to_string(listbuf, pos, strinput): + """Return string built with list of buffers found (matching user input).""" + string = '' + strinput = strinput.lower() + for i in range(len(listbuf)): + selected = '_selected' if i == pos else '' + index = listbuf[i]['name'].lower().find(strinput) + if index >= 0: + index2 = index + len(strinput) + name = '%s%s%s%s%s' % ( + listbuf[i]['name'][:index], + weechat.color(weechat.config_get_plugin( + 'color_name_highlight' + selected)), + listbuf[i]['name'][index:index2], + weechat.color(weechat.config_get_plugin( + 'color_name' + selected)), + listbuf[i]['name'][index2:]) + else: + name = listbuf[i]['name'] + string += ' %s%s%s%s%s' % ( + weechat.color(weechat.config_get_plugin( + 'color_number' + selected)), + str(listbuf[i]['number']), + weechat.color(weechat.config_get_plugin( + 'color_name' + selected)), + name, + weechat.color('reset')) + return ' ' + string if string else '' + + +def go_input_modifier(data, modifier, modifier_data, string): + """This modifier is called when input text item is built by WeeChat. + + This is commonly called after changes in input or cursor move: it builds + a new input with prefix ("Go to:"), and suffix (list of buffers found). + """ + global old_input, buffers, buffers_pos + if modifier_data != weechat.current_buffer(): + return '' + names = '' + new_input = weechat.string_remove_color(string, '') + new_input = new_input.lstrip() + if old_input is None or new_input != old_input: + old_buffers = buffers + buffers = go_matching_buffers(new_input) + if buffers != old_buffers and len(new_input) > 0: + if len(buffers) == 1 and go_option_enabled('auto_jump'): + weechat.command(modifier_data, '/wait 1ms /input return') + buffers_pos = 0 + old_input = new_input + names = go_buffers_to_string(buffers, buffers_pos, new_input.strip()) + return weechat.config_get_plugin('message') + string + names + + +def go_command_run_input(data, buf, command): + """Function called when a command "/input xxx" is run.""" + global buffers, buffers_pos + if command == '/input search_text' or command.find('/input jump') == 0: + # search text or jump to another buffer is forbidden now + return weechat.WEECHAT_RC_OK_EAT + elif command == '/input complete_next': + # choose next buffer in list + buffers_pos += 1 + if buffers_pos >= len(buffers): + buffers_pos = 0 + weechat.hook_signal_send('input_text_changed', + weechat.WEECHAT_HOOK_SIGNAL_STRING, '') + return weechat.WEECHAT_RC_OK_EAT + elif command == '/input complete_previous': + # choose previous buffer in list + buffers_pos -= 1 + if buffers_pos < 0: + buffers_pos = len(buffers) - 1 + weechat.hook_signal_send('input_text_changed', + weechat.WEECHAT_HOOK_SIGNAL_STRING, '') + return weechat.WEECHAT_RC_OK_EAT + elif command == '/input return': + # switch to selected buffer (if any) + go_end(buf) + if len(buffers) > 0: + weechat.command( + buf, '/buffer ' + str(buffers[buffers_pos]['full_name'])) + return weechat.WEECHAT_RC_OK_EAT + return weechat.WEECHAT_RC_OK + + +def go_command_run_buffer(data, buf, command): + """Function called when a command "/buffer xxx" is run.""" + return weechat.WEECHAT_RC_OK_EAT + + +def go_command_run_window(data, buf, command): + """Function called when a command "/window xxx" is run.""" + return weechat.WEECHAT_RC_OK_EAT + + +def go_unload_script(): + """Function called when script is unloaded.""" + go_unhook_all() + return weechat.WEECHAT_RC_OK + + +def go_main(): + """Entry point.""" + if not weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, + SCRIPT_LICENSE, SCRIPT_DESC, + 'go_unload_script', ''): + return + weechat.hook_command( + SCRIPT_COMMAND, + 'Quick jump to buffers', '[name]', + 'name: directly jump to buffer by name (without argument, list is ' + 'displayed)\n\n' + 'You can bind command to a key, for example:\n' + ' /key bind meta-g /go\n\n' + 'You can use completion key (commonly Tab and shift-Tab) to select ' + 'next/previous buffer in list.', + '%(buffers_names)', + 'go_cmd', '') + + # set default settings + version = weechat.info_get('version_number', '') or 0 + for option, value in SETTINGS.items(): + if not weechat.config_is_set_plugin(option): + weechat.config_set_plugin(option, value[0]) + if int(version) >= 0x00030500: + weechat.config_set_desc_plugin( + option, '%s (default: "%s")' % (value[1], value[0])) + weechat.hook_info('go_running', + 'Return "1" if go is running, otherwise "0"', + '', + 'go_info_running', '') + + +if __name__ == "__main__" and IMPORT_OK: + go_main() diff --git a/weechat/script.conf b/weechat/script.conf index 0c2b224..95c8c57 100644 --- a/weechat/script.conf +++ b/weechat/script.conf @@ -43,7 +43,7 @@ text_version_selected = lightmagenta [scripts] autoload = on cache_expire = 60 -dir = "%h/script" hold = "" +path = "%h/script" url = "http://www.weechat.org/files/plugins.xml.gz" url_force_https = on diff --git a/weechat/weechat.conf b/weechat/weechat.conf new file mode 100644 index 0000000..ea3e779 --- /dev/null +++ b/weechat/weechat.conf @@ -0,0 +1,652 @@ +# +# weechat -- weechat.conf +# + +[debug] + +[startup] +command_after_plugins = "" +command_before_plugins = "" +display_logo = on +display_version = on +sys_rlimit = "" + +[look] +align_end_of_lines = message +bar_more_down = "++" +bar_more_left = "<<" +bar_more_right = ">>" +bar_more_up = "--" +bare_display_exit_on_input = on +bare_display_time_format = "%H:%M" +buffer_auto_renumber = on +buffer_notify_default = all +buffer_position = end +buffer_search_case_sensitive = off +buffer_search_force_default = off +buffer_search_regex = off +buffer_search_where = prefix_message +buffer_time_format = "" +color_basic_force_bold = off +color_inactive_buffer = on +color_inactive_message = on +color_inactive_prefix = on +color_inactive_prefix_buffer = on +color_inactive_time = off +color_inactive_window = on +color_nick_offline = off +color_pairs_auto_reset = 5 +color_real_white = off +command_chars = "" +command_incomplete = off +confirm_quit = on +confirm_upgrade = off +day_change = on +day_change_message_1date = "-- %a, %d %b %Y --" +day_change_message_2dates = "-- %%a, %%d %%b %%Y (%a, %d %b %Y) --" +eat_newline_glitch = off +emphasized_attributes = "" +highlight = "" +highlight_regex = "" +highlight_tags = "" +hotlist_add_conditions = "${away} || ${buffer.num_displayed} == 0" +hotlist_buffer_separator = ", " +hotlist_count_max = 2 +hotlist_count_min_msg = 2 +hotlist_names_count = 3 +hotlist_names_length = 0 +hotlist_names_level = 12 +hotlist_names_merged_buffers = off +hotlist_prefix = "H: " +hotlist_remove = merged +hotlist_short_names = on +hotlist_sort = group_time_asc +hotlist_suffix = "" +hotlist_unique_numbers = on +input_cursor_scroll = 20 +input_share = none +input_share_overwrite = off +input_undo_max = 32 +item_buffer_filter = "*" +item_buffer_zoom = "!" +item_mouse_status = "M" +item_time_format = "%H:%M" +jump_current_to_previous_buffer = on +jump_previous_buffer_when_closing = on +jump_smart_back_to_buffer = on +key_bind_safe = on +mouse = on +mouse_timer_delay = 100 +nick_prefix = "" +nick_suffix = "" +paste_bracketed = on +paste_bracketed_timer_delay = 10 +paste_max_lines = 1 +prefix_action = " •" +prefix_align = none +prefix_align_max = 0 +prefix_align_min = 0 +prefix_align_more = "+" +prefix_align_more_after = on +prefix_buffer_align = right +prefix_buffer_align_max = 0 +prefix_buffer_align_more = "+" +prefix_buffer_align_more_after = on +prefix_error = "=!=" +prefix_join = "-->" +prefix_network = "--" +prefix_quit = "<--" +prefix_same_nick = "╰" +prefix_suffix = "|" +quote_nick_prefix = "<" +quote_nick_suffix = ">" +quote_time_format = "%H:%M:%S" +read_marker = line +read_marker_always_show = off +read_marker_string = "─" +save_config_on_exit = on +save_layout_on_exit = none +scroll_amount = 3 +scroll_bottom_after_switch = off +scroll_page_percent = 100 +search_text_not_found_alert = on +separator_horizontal = "━" +separator_vertical = "" +tab_width = 1 +time_format = "%a, %d %b %Y %T" +window_auto_zoom = off +window_separator_horizontal = on +window_separator_vertical = on +window_title = "WeeChat ${info:version}" +word_chars_highlight = "!\u00A0,-,_,|,alnum" +word_chars_input = "!\u00A0,-,_,|,alnum" + +[palette] + +[color] +bar_more = lightmagenta +chat = default +chat_bg = default +chat_buffer = white +chat_channel = white +chat_day_change = cyan +chat_delimiters = green +chat_highlight = yellow +chat_highlight_bg = magenta +chat_host = cyan +chat_inactive_buffer = default +chat_inactive_window = default +chat_nick = lightcyan +chat_nick_colors = "cyan,magenta,green,brown,lightblue,default,lightcyan,lightmagenta,lightgreen,blue" +chat_nick_offline = default +chat_nick_offline_highlight = default +chat_nick_offline_highlight_bg = blue +chat_nick_other = cyan +chat_nick_prefix = green +chat_nick_self = white +chat_nick_suffix = green +chat_prefix_action = white +chat_prefix_buffer = brown +chat_prefix_buffer_inactive_buffer = default +chat_prefix_error = yellow +chat_prefix_join = lightgreen +chat_prefix_more = lightmagenta +chat_prefix_network = magenta +chat_prefix_quit = lightred +chat_prefix_suffix = green +chat_read_marker = magenta +chat_read_marker_bg = default +chat_server = brown +chat_tags = red +chat_text_found = yellow +chat_text_found_bg = lightmagenta +chat_time = default +chat_time_delimiters = brown +chat_value = cyan +emphasized = yellow +emphasized_bg = magenta +input_actions = lightgreen +input_text_not_found = red +nicklist_away = cyan +nicklist_group = green +nicklist_offline = blue +separator = blue +status_count_highlight = magenta +status_count_msg = brown +status_count_other = default +status_count_private = green +status_data_highlight = lightmagenta +status_data_msg = yellow +status_data_other = default +status_data_private = lightgreen +status_filter = green +status_more = yellow +status_mouse = green +status_name = white +status_name_ssl = lightgreen +status_nicklist_count = default +status_number = yellow +status_time = default + +[completion] +base_word_until_cursor = on +command_inline = on +default_template = "%(nicks)|%(irc_channels)" +nick_add_space = on +nick_completer = ":" +nick_first_only = off +nick_ignore_chars = "[]`_-^" +partial_completion_alert = on +partial_completion_command = off +partial_completion_command_arg = off +partial_completion_count = on +partial_completion_other = off + +[history] +display_default = 5 +max_buffer_lines_minutes = 0 +max_buffer_lines_number = 4096 +max_commands = 100 +max_visited_buffers = 50 + +[proxy] + +[network] +connection_timeout = 60 +gnutls_ca_file = "/etc/ssl/certs/ca-certificates.crt" +gnutls_handshake_timeout = 30 +proxy_curl = "" + +[plugin] +autoload = "*" +debug = off +extension = ".so,.dll" +path = "%h/plugins" +save_config_on_unload = on + +[bar] +buffers.color_bg = default +buffers.color_delim = default +buffers.color_fg = default +buffers.conditions = "" +buffers.filling_left_right = vertical +buffers.filling_top_bottom = horizontal +buffers.hidden = on +buffers.items = "buffers" +buffers.position = bottom +buffers.priority = 0 +buffers.separator = on +buffers.size = 0 +buffers.size_max = 0 +buffers.type = root +chanop_bar.color_bg = blue +chanop_bar.color_delim = cyan +chanop_bar.color_fg = default +chanop_bar.conditions = "active" +chanop_bar.filling_left_right = vertical +chanop_bar.filling_top_bottom = horizontal +chanop_bar.hidden = on +chanop_bar.items = "chanop_status,chanop_ban_matches" +chanop_bar.position = bottom +chanop_bar.priority = 0 +chanop_bar.separator = off +chanop_bar.size = 0 +chanop_bar.size_max = 1 +chanop_bar.type = window +highmon.color_bg = default +highmon.color_delim = cyan +highmon.color_fg = default +highmon.conditions = "" +highmon.filling_left_right = vertical +highmon.filling_top_bottom = vertical +highmon.hidden = off +highmon.items = "highmon" +highmon.position = top +highmon.priority = 100 +highmon.separator = off +highmon.size = 0 +highmon.size_max = 0 +highmon.type = root +input.color_bg = default +input.color_delim = cyan +input.color_fg = default +input.conditions = "" +input.filling_left_right = vertical +input.filling_top_bottom = horizontal +input.hidden = off +input.items = "[input_prompt]+(away),[input_search],[input_paste],input_text" +input.position = bottom +input.priority = 1000 +input.separator = off +input.size = 0 +input.size_max = 0 +input.type = window +isetbar.color_bg = default +isetbar.color_delim = cyan +isetbar.color_fg = default +isetbar.conditions = "" +isetbar.filling_left_right = vertical +isetbar.filling_top_bottom = horizontal +isetbar.hidden = on +isetbar.items = "isetbar_help" +isetbar.position = top +isetbar.priority = 0 +isetbar.separator = on +isetbar.size = 3 +isetbar.size_max = 3 +isetbar.type = window +nicklist.color_bg = default +nicklist.color_delim = cyan +nicklist.color_fg = default +nicklist.conditions = "${nicklist}" +nicklist.filling_left_right = vertical +nicklist.filling_top_bottom = columns_vertical +nicklist.hidden = on +nicklist.items = "buffer_nicklist" +nicklist.position = right +nicklist.priority = 200 +nicklist.separator = on +nicklist.size = 0 +nicklist.size_max = 0 +nicklist.type = window +status.color_bg = blue +status.color_delim = cyan +status.color_fg = default +status.conditions = "" +status.filling_left_right = vertical +status.filling_top_bottom = horizontal +status.hidden = off +status.items = "[buffer_last_number],[buffer_plugin],buffer_number+:+buffer_name+(buffer_modes)+{buffer_nicklist_count}+buffer_zoom+buffer_filter,scroll,[lag],[hotlist],completion,aspell_suggest" +status.position = bottom +status.priority = 500 +status.separator = off +status.size = 1 +status.size_max = 0 +status.type = window +title.color_bg = blue +title.color_delim = cyan +title.color_fg = default +title.conditions = "" +title.filling_left_right = vertical +title.filling_top_bottom = horizontal +title.hidden = off +title.items = "buffer_title" +title.position = top +title.priority = 500 +title.separator = off +title.size = 0 +title.size_max = 0 +title.type = window + +[notify] + +[filter] +irc_smart = on;*;irc_smart_filter;* +ignore_xender_#git = on;*.Freenode.#git;nick_xender;* + +[key] +ctrl-? = "/input delete_previous_char" +ctrl-A = "/input move_beginning_of_line" +ctrl-B = "/input move_previous_char" +ctrl-C_ = "/input insert \x1F" +ctrl-Cb = "/input insert \x02" +ctrl-Cc = "/input insert \x03" +ctrl-Ci = "/input insert \x1D" +ctrl-Co = "/input insert \x0F" +ctrl-Cv = "/input insert \x16" +ctrl-D = "/input delete_next_char" +ctrl-E = "/input move_end_of_line" +ctrl-F = "/input move_next_char" +ctrl-H = "/input delete_previous_char" +ctrl-I = "/input complete_next" +ctrl-J = "/input return" +ctrl-K = "/input delete_end_of_line" +ctrl-L = "/window refresh" +ctrl-M = "/input return" +ctrl-N = "/buffer +1" +ctrl-P = "/buffer -1" +ctrl-R = "/input search_text" +ctrl-Sctrl-U = "/input set_unread" +ctrl-T = "/input transpose_chars" +ctrl-U = "/input delete_beginning_of_line" +ctrl-W = "/input delete_previous_word" +ctrl-X = "/input switch_active_buffer" +ctrl-Y = "/input clipboard_paste" +meta-meta2-1~ = "/window scroll_top" +meta-meta2-23~ = "/bar scroll nicklist * b" +meta-meta2-24~ = "/bar scroll nicklist * e" +meta-meta2-4~ = "/window scroll_bottom" +meta-meta2-5~ = "/window scroll_up" +meta-meta2-6~ = "/window scroll_down" +meta-meta2-7~ = "/window scroll_top" +meta-meta2-8~ = "/window scroll_bottom" +meta-meta2-A = "/buffer -1" +meta-meta2-B = "/buffer +1" +meta-meta2-C = "/buffer +1" +meta-meta2-D = "/buffer -1" +meta-- = "/filter toggle @" +meta-/ = "/input jump_last_buffer_displayed" +meta-0 = "/buffer *10" +meta-1 = "/buffer *1" +meta-2 = "/buffer *2" +meta-3 = "/buffer *3" +meta-4 = "/buffer *4" +meta-5 = "/buffer *5" +meta-6 = "/buffer *6" +meta-7 = "/buffer *7" +meta-8 = "/buffer *8" +meta-9 = "/buffer *9" +meta-< = "/input jump_previously_visited_buffer" +meta-= = "/filter toggle" +meta-> = "/input jump_next_visited_buffer" +meta-OA = "/input history_global_previous" +meta-OB = "/input history_global_next" +meta-OC = "/input move_next_word" +meta-OD = "/input move_previous_word" +meta-OF = "/input move_end_of_line" +meta-OH = "/input move_beginning_of_line" +meta-Oa = "/input history_global_previous" +meta-Ob = "/input history_global_next" +meta-Oc = "/input move_next_word" +meta-Od = "/input move_previous_word" +meta2-15~ = "/buffer -1" +meta2-17~ = "/buffer +1" +meta2-18~ = "/window -1" +meta2-19~ = "/window +1" +meta2-1;3A = "/buffer -1" +meta2-1;3B = "/buffer +1" +meta2-1;3C = "/buffer +1" +meta2-1;3D = "/buffer -1" +meta2-1;3F = "/window scroll_bottom" +meta2-1;3H = "/window scroll_top" +meta2-1;5A = "/input history_global_previous" +meta2-1;5B = "/input history_global_next" +meta2-1;5C = "/input move_next_word" +meta2-1;5D = "/input move_previous_word" +meta2-1~ = "/input move_beginning_of_line" +meta2-200~ = "/input paste_start" +meta2-201~ = "/input paste_stop" +meta2-20~ = "/bar scroll title * -30%" +meta2-21~ = "/bar scroll title * +30%" +meta2-23;3~ = "/bar scroll nicklist * b" +meta2-23~ = "/bar scroll nicklist * -100%" +meta2-24;3~ = "/bar scroll nicklist * e" +meta2-24~ = "/bar scroll nicklist * +100%" +meta2-3~ = "/input delete_next_char" +meta2-4~ = "/input move_end_of_line" +meta2-5;3~ = "/window scroll_up" +meta2-5~ = "/window page_up" +meta2-6;3~ = "/window scroll_down" +meta2-6~ = "/window page_down" +meta2-7~ = "/input move_beginning_of_line" +meta2-8~ = "/input move_end_of_line" +meta2-A = "/input history_previous" +meta2-B = "/input history_next" +meta2-C = "/input move_next_char" +meta2-D = "/input move_previous_char" +meta2-F = "/input move_end_of_line" +meta2-G = "/window page_down" +meta2-H = "/input move_beginning_of_line" +meta2-I = "/window page_up" +meta2-Z = "/input complete_previous" +meta2-[E = "/buffer -1" +meta-_ = "/input redo" +meta-a = "/input jump_smart" +meta-b = "/input move_previous_word" +meta-d = "/input delete_next_word" +meta-f = "/input move_next_word" +meta-g = "/go" +meta-h = "/input hotlist_clear" +meta-jmeta-f = "/buffer -" +meta-jmeta-l = "/buffer +" +meta-jmeta-r = "/server raw" +meta-jmeta-s = "/server jump" +meta-j01 = "/buffer 1" +meta-j02 = "/buffer 2" +meta-j03 = "/buffer 3" +meta-j04 = "/buffer 4" +meta-j05 = "/buffer 5" +meta-j06 = "/buffer 6" +meta-j07 = "/buffer 7" +meta-j08 = "/buffer 8" +meta-j09 = "/buffer 9" +meta-j10 = "/buffer 10" +meta-j11 = "/buffer 11" +meta-j12 = "/buffer 12" +meta-j13 = "/buffer 13" +meta-j14 = "/buffer 14" +meta-j15 = "/buffer 15" +meta-j16 = "/buffer 16" +meta-j17 = "/buffer 17" +meta-j18 = "/buffer 18" +meta-j19 = "/buffer 19" +meta-j20 = "/buffer 20" +meta-j21 = "/buffer 21" +meta-j22 = "/buffer 22" +meta-j23 = "/buffer 23" +meta-j24 = "/buffer 24" +meta-j25 = "/buffer 25" +meta-j26 = "/buffer 26" +meta-j27 = "/buffer 27" +meta-j28 = "/buffer 28" +meta-j29 = "/buffer 29" +meta-j30 = "/buffer 30" +meta-j31 = "/buffer 31" +meta-j32 = "/buffer 32" +meta-j33 = "/buffer 33" +meta-j34 = "/buffer 34" +meta-j35 = "/buffer 35" +meta-j36 = "/buffer 36" +meta-j37 = "/buffer 37" +meta-j38 = "/buffer 38" +meta-j39 = "/buffer 39" +meta-j40 = "/buffer 40" +meta-j41 = "/buffer 41" +meta-j42 = "/buffer 42" +meta-j43 = "/buffer 43" +meta-j44 = "/buffer 44" +meta-j45 = "/buffer 45" +meta-j46 = "/buffer 46" +meta-j47 = "/buffer 47" +meta-j48 = "/buffer 48" +meta-j49 = "/buffer 49" +meta-j50 = "/buffer 50" +meta-j51 = "/buffer 51" +meta-j52 = "/buffer 52" +meta-j53 = "/buffer 53" +meta-j54 = "/buffer 54" +meta-j55 = "/buffer 55" +meta-j56 = "/buffer 56" +meta-j57 = "/buffer 57" +meta-j58 = "/buffer 58" +meta-j59 = "/buffer 59" +meta-j60 = "/buffer 60" +meta-j61 = "/buffer 61" +meta-j62 = "/buffer 62" +meta-j63 = "/buffer 63" +meta-j64 = "/buffer 64" +meta-j65 = "/buffer 65" +meta-j66 = "/buffer 66" +meta-j67 = "/buffer 67" +meta-j68 = "/buffer 68" +meta-j69 = "/buffer 69" +meta-j70 = "/buffer 70" +meta-j71 = "/buffer 71" +meta-j72 = "/buffer 72" +meta-j73 = "/buffer 73" +meta-j74 = "/buffer 74" +meta-j75 = "/buffer 75" +meta-j76 = "/buffer 76" +meta-j77 = "/buffer 77" +meta-j78 = "/buffer 78" +meta-j79 = "/buffer 79" +meta-j80 = "/buffer 80" +meta-j81 = "/buffer 81" +meta-j82 = "/buffer 82" +meta-j83 = "/buffer 83" +meta-j84 = "/buffer 84" +meta-j85 = "/buffer 85" +meta-j86 = "/buffer 86" +meta-j87 = "/buffer 87" +meta-j88 = "/buffer 88" +meta-j89 = "/buffer 89" +meta-j90 = "/buffer 90" +meta-j91 = "/buffer 91" +meta-j92 = "/buffer 92" +meta-j93 = "/buffer 93" +meta-j94 = "/buffer 94" +meta-j95 = "/buffer 95" +meta-j96 = "/buffer 96" +meta-j97 = "/buffer 97" +meta-j98 = "/buffer 98" +meta-j99 = "/buffer 99" +meta-k = "/input grab_key_command" +meta-l = "/window bare" +meta-m = "/mute mouse toggle" +meta-n = "/window scroll_next_highlight" +meta-p = "/window scroll_previous_highlight" +meta-r = "/input delete_line" +meta-s = "/mute aspell toggle" +meta-u = "/window scroll_unread" +meta-wmeta-meta2-A = "/window up" +meta-wmeta-meta2-B = "/window down" +meta-wmeta-meta2-C = "/window right" +meta-wmeta-meta2-D = "/window left" +meta-wmeta2-1;3A = "/window up" +meta-wmeta2-1;3B = "/window down" +meta-wmeta2-1;3C = "/window right" +meta-wmeta2-1;3D = "/window left" +meta-wmeta-b = "/window balance" +meta-wmeta-s = "/window swap" +meta-x = "/input zoom_merged_buffer" +meta-z = "/window zoom" +ctrl-_ = "/input undo" + +[key_search] +ctrl-I = "/input search_switch_where" +ctrl-J = "/input search_stop" +ctrl-M = "/input search_stop" +ctrl-R = "/input search_switch_regex" +meta2-A = "/input search_previous" +meta2-B = "/input search_next" +meta-c = "/input search_switch_case" + +[key_cursor] +ctrl-J = "/cursor stop" +ctrl-M = "/cursor stop" +meta-meta2-A = "/cursor move area_up" +meta-meta2-B = "/cursor move area_down" +meta-meta2-C = "/cursor move area_right" +meta-meta2-D = "/cursor move area_left" +meta2-1;3A = "/cursor move area_up" +meta2-1;3B = "/cursor move area_down" +meta2-1;3C = "/cursor move area_right" +meta2-1;3D = "/cursor move area_left" +meta2-A = "/cursor move up" +meta2-B = "/cursor move down" +meta2-C = "/cursor move right" +meta2-D = "/cursor move left" +@item(buffer_nicklist):K = "/window ${_window_number};/kickban ${nick}" +@item(buffer_nicklist):b = "/window ${_window_number};/ban ${nick}" +@item(buffer_nicklist):k = "/window ${_window_number};/kick ${nick}" +@item(buffer_nicklist):q = "/window ${_window_number};/query ${nick};/cursor stop" +@item(buffer_nicklist):w = "/window ${_window_number};/whois ${nick}" +@chat:Q = "hsignal:chat_quote_time_prefix_message;/cursor stop" +@chat:m = "hsignal:chat_quote_message;/cursor stop" +@chat:q = "hsignal:chat_quote_prefix_message;/cursor stop" + +[key_mouse] +@bar(buffers):ctrl-wheeldown = "hsignal:buffers_mouse" +@bar(buffers):ctrl-wheelup = "hsignal:buffers_mouse" +@bar(input):button2 = "/input grab_mouse_area" +@bar(nicklist):button1-gesture-down = "/bar scroll nicklist ${_window_number} +100%" +@bar(nicklist):button1-gesture-down-long = "/bar scroll nicklist ${_window_number} e" +@bar(nicklist):button1-gesture-up = "/bar scroll nicklist ${_window_number} -100%" +@bar(nicklist):button1-gesture-up-long = "/bar scroll nicklist ${_window_number} b" +@chat(perl.iset):button1 = "hsignal:iset_mouse" +@chat(perl.iset):button2* = "hsignal:iset_mouse" +@chat(perl.iset):wheeldown = "/repeat 5 /iset **down" +@chat(perl.iset):wheelup = "/repeat 5 /iset **up" +@chat(script.scripts):button1 = "/window ${_window_number};/script go ${_chat_line_y}" +@chat(script.scripts):button2 = "/window ${_window_number};/script go ${_chat_line_y};/script installremove -q ${script_name_with_extension}" +@chat(script.scripts):wheeldown = "/script down 5" +@chat(script.scripts):wheelup = "/script up 5" +@item(buffer_nicklist):button1 = "/window ${_window_number};/query ${nick}" +@item(buffer_nicklist):button1-gesture-left = "/window ${_window_number};/kick ${nick}" +@item(buffer_nicklist):button1-gesture-left-long = "/window ${_window_number};/kickban ${nick}" +@item(buffer_nicklist):button2 = "/window ${_window_number};/whois ${nick}" +@item(buffer_nicklist):button2-gesture-left = "/window ${_window_number};/ban ${nick}" +@item(buffers):button1* = "hsignal:buffers_mouse" +@item(buffers):button2* = "hsignal:buffers_mouse" +@bar:wheeldown = "/bar scroll ${_bar_name} ${_window_number} +20%" +@bar:wheelup = "/bar scroll ${_bar_name} ${_window_number} -20%" +@chat:button1 = "/window ${_window_number}" +@chat:button1-gesture-left = "/window ${_window_number};/buffer -1" +@chat:button1-gesture-left-long = "/window ${_window_number};/buffer 1" +@chat:button1-gesture-right = "/window ${_window_number};/buffer +1" +@chat:button1-gesture-right-long = "/window ${_window_number};/input jump_last_buffer" +@chat:ctrl-wheeldown = "/window scroll_horiz -window ${_window_number} +10%" +@chat:ctrl-wheelup = "/window scroll_horiz -window ${_window_number} -10%" +@chat:wheeldown = "/window scroll_down -window ${_window_number}" +@chat:wheelup = "/window scroll_up -window ${_window_number}" +@*:button3 = "/cursor go ${_x},${_y}" diff --git a/zsh/.zprofile b/zsh/.zprofile index b4a6a5a..653b8ad 100644 --- a/zsh/.zprofile +++ b/zsh/.zprofile @@ -38,8 +38,11 @@ export SUDO_PROMPT=$'\e[31mSUDO\e[m password for \e[34m%p\e[m: ' export SHORTHOST=$(hostname -s) +# Don’t use the default venv prompt in favor of our custom one export VIRTUAL_ENV_DISABLE_PROMPT=1 +export FIGLET_FONTDIR="$HOME"/.local/share/figlet + if [[ -f "$ZDOTDIR"/profile-"$SHORTHOST" ]]; then source "$ZDOTDIR"/profile-"$SHORTHOST" fi @@ -48,5 +51,5 @@ fi source <(dircolors -b "$XDG_CONFIG_HOME"/dircolors) if [[ -z $DISPLAY && $XDG_VTNR -eq 1 ]]; then - exec startx "$XDG_CONFIG_HOME"/X11/xinitrc + exec startx "$XDG_CONFIG_HOME"/X11/xinitrc -- -configdir "$XDG_CONFIG_HOME"/X11/xorg.conf.d fi @@ -9,6 +9,8 @@ zstyle ':completion:*' menu select zstyle ':completion:*' use-cache on zstyle ':completion:*' rehash yes +fpath=("$ZDOTDIR"/completion "${fpath[@]}") + autoload -Uz colors \ compinit \ promptinit \ diff --git a/zsh/aliases.zsh b/zsh/aliases.zsh index b828a71..ebe3481 100644 --- a/zsh/aliases.zsh +++ b/zsh/aliases.zsh @@ -24,6 +24,8 @@ alias ms5='mbsync --config "$XDG_CONFIG_HOME/mbsyncrc" 5monkeys' alias msa='mbsync --config "$XDG_CONFIG_HOME/mbsyncrc" -a' alias ty='ttytter -rc="$XDG_CONFIG_HOME"/ttytter/ttytterrc' +alias pt='pstree --highlight-all --long --uid-changes' + alias sprin='curl -F "sprunge=<-" http://sprunge.us' sprfile() { curl -F "sprunge=<$1" http://sprunge.us @@ -73,31 +75,82 @@ if have systemctl && [[ -d /run/systemd/system ]]; then fi function 5v { - if [[ -d "$HOME"/5/venvs/"$1" ]]; then - source "$HOME"/5/venvs/"$1"/bin/activate + if [[ -d "$HOME"/venvs/"$1" ]]; then + source "$HOME"/venvs/"$1"/bin/activate printf "\x1b[38;5;2m==> 5venv ‘%s’ activated successfully.\x1b[0m\n" "$1" + else printf "==> 5venv ‘%s’ not found\n" "$1" printf "==> Create? [yN]: " read yn + if [[ "$yn" == 'y' || "$yn" == 'yes' ]]; then - virtualenv-2.7 "$HOME"/5/venvs/"$1" - if (( $? == 0 )); then - print "\x1b[38;5;2m==> 5venv created successfully, installing basic requirements.\x1b[0m" + printf "==> Python version? [23]: " + read venvver + + if [[ "$venvver" == '2' ]]; then + virtualenv2 "$HOME"/venvs/"$1" + if (( $? == 0 )); then + print "\x1b[38;5;2m==> 5venv created successfully, installing basic requirements.\x1b[0m" + else + print "\x1b[38;5;1m==> Error: 5env creation failed. Exiting.\x1b[0m" + return 1 + fi + source "$HOME"/venvs/"$1"/bin/activate + pip install -r "$HOME"/venvs/5_requirements.txt + + elif [[ "$venvver" == '3' ]]; then + virtualenv3 "$HOME"/venvs/"$1" + if (( $? == 0 )); then + print "\x1b[38;5;2m==> 5venv created successfully, activating environment.\x1b[0m" + print "==> Note that no requirements were installed due to version 3 was selected." + else + print "\x1b[38;5;1m==> Error: 5env creation failed. Exiting.\x1b[0m" + return 1 + fi + source "$HOME"/venvs/"$1"/bin/activate + else - print "\x1b[38;5;1m==> Error: 5env creation failed. Exiting.\x1b[0m" - return 1 + printf "==> virtualenv for version ‘%s’ not found.\n" "$venvver" + exit 1 fi - source "$HOME"/5/venvs/"$1"/bin/activate - pip install -r "$HOME"/5/venvs/5_requirements.txt fi fi } function 5c { - if [[ -n "$1" ]]; then - cd "$HOME"/5/code/"$1" - else - cd "$HOME"/5/code + cd "$HOME"/projects/"$1" +} + +function 5clone { + if [[ -z "$1" ]]; then + print "No repo name" + fi + + (cd "$HOME"/projects + git clone git@github.com:5m/"$1" + shift + cd -) + + pushd "$HOME"/projects/"$1" + git config --local user.email johannes@5monkeys.se +} + +alias 5ssh='TERM=xterm ssh' + +aur-push() { + git push aur@aur.archlinux.org:/"$1".git "$1":master +} + +aur-pull() { + local old_branch=$(git symbolic-ref --short HEAD) + git checkout "$1" + git pull aur@aur.archlinux.org:/"$1".git master:"$1" + git checkout "$old_branch" +} + +tt() { + if [[ -n "$@" ]]; then + print "$@" | ts '[%Y-%m-%d %H:%M:%S]' >> "$HOME"/documents/timetracking fi } diff --git a/zsh/completion/_5c b/zsh/completion/_5c new file mode 100644 index 0000000..5f309c7 --- /dev/null +++ b/zsh/completion/_5c @@ -0,0 +1,4 @@ +#compdef 5c + +_arguments \ + "1: :($(print $HOME/projects/*(/) | xargs -n1 basename))" diff --git a/zsh/completion/_5v b/zsh/completion/_5v new file mode 100644 index 0000000..659bb1a --- /dev/null +++ b/zsh/completion/_5v @@ -0,0 +1,4 @@ +#compdef 5v + +_arguments \ + "1: :($(print $HOME/venvs/*(/) | xargs -n1 basename))" diff --git a/zsh/completion/_aur b/zsh/completion/_aur new file mode 100644 index 0000000..83a359c --- /dev/null +++ b/zsh/completion/_aur @@ -0,0 +1,4 @@ +#compdef aur-push aur-pull + +_arguments \ + "1: :($(git for-each-ref --format='%(refname:short)' refs/heads))" diff --git a/zsh/profile-leeloo b/zsh/profile-leeloo index b37ac81..be9ae1a 100644 --- a/zsh/profile-leeloo +++ b/zsh/profile-leeloo @@ -1,8 +1,9 @@ if (( UID )); then - export LD_PRELOAD="$HOME"/.local/lib/libwcwidth.so + if [[ -x "$HOME"/.local/lib/libwcwidth.so ]]; then + export LD_PRELOAD="$HOME"/.local/lib/libwcwidth.so + fi export PERL5LIB="$HOME"/misc/grawity/code/lib/perl5"${PERL5LIB+:}$PERL5LIB"; - source <(perl -Mlocal::lib="$HOME"/.local) function { local envfile="$XDG_RUNTIME_DIR"/ssh-agent.env @@ -16,6 +17,9 @@ if (( UID )); then } source "$HOME"/misc/grawity/code/kerberos/kc.sh + + export MAILDIR="$HOME"/mail + export MANPATH="$(manpath)":"$HOME"/.local/share/man fi # vim: ft=zsh diff --git a/zsh/profile-macer b/zsh/profile-macer deleted file mode 100644 index 4d3e7fe..0000000 --- a/zsh/profile-macer +++ /dev/null @@ -1,5 +0,0 @@ -export PATH=/usr/local/bin:/usr/local/sbin:"$HOME"/Library/Haskell/bin:"$PATH" - -# path to GNU coreutils without g prefix -export PATH=/usr/local/opt/coreutils/libexec/gnubin:"$PATH" -export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH" diff --git a/zsh/profile-zorg b/zsh/profile-zorg new file mode 100644 index 0000000..0a19020 --- /dev/null +++ b/zsh/profile-zorg @@ -0,0 +1,21 @@ +if (( UID )); then + if [[ -x "$HOME"/.local/lib/libwcwidth.so ]]; then + export LD_PRELOAD="$HOME"/.local/lib/libwcwidth.so + fi + + function { + local envfile="$XDG_RUNTIME_DIR"/ssh-agent.env + local pid=$(awk -F'[=;]' 'FNR == 2 {print $2}' "$envfile" 2>/dev/null) + if [[ -n "$pid" ]] && kill -0 "$pid" &>/dev/null; then + source "$envfile" >/dev/null + else + ssh-agent > "$envfile" + source "$envfile" >/dev/null + fi + } + + export MAILDIR="$HOME"/mail + export MANPATH="$(manpath)":"$HOME"/.local/share/man +fi + +# vim: ft=zsh diff --git a/zsh/prompt.zsh b/zsh/prompt.zsh index 67e17b4..c83b2da 100644 --- a/zsh/prompt.zsh +++ b/zsh/prompt.zsh @@ -1,3 +1,4 @@ +# Red bg[light_pink]='%K{001}' bg[light_red]='%K{196}' bg[red]='%K{88}' @@ -9,6 +10,7 @@ fg[red]='%F{88}' fg[dark_red]='%F{52}' +# Yellow bg[light_gold]='%K{136}' bg[gold]='%K{139}' bg[dark_gold]='%K{94}' @@ -18,12 +20,17 @@ fg[gold]='%F{139}' fg[dark_gold]='%F{94}' +# Blue bg[light_blue]='%K{blue}' bg[blue]='%K{21}' fg[light_blue]='%F{blue}' fg[blue]='%F{21}' + +# Green +bg[dark_green]='%K{64}' + function virtualenv_prompt { if [[ -n "$VIRTUAL_ENV" ]]; then print "$bg[light_blue]$fg[white] $(basename $VIRTUAL_ENV) %f%k" @@ -32,23 +39,28 @@ function virtualenv_prompt { if (( UID == 0 )); then PROMPT='$bg[light_red] $fg[white]%m%f %k$bg[white]$fg[light_red] %~ %f%k$(virtualenv_prompt) -$bg[light_blue]%B ^_^ %b%k ' +$bg[light_blue] λ %k ' else case $SHORTHOST in "theos") PROMPT='$bg[light_pink] $fg[white]%m%f %k$bg[white]$fg[light_pink] %~ %f%k$(virtualenv_prompt) -$bg[light_blue]%B ^_^ %b %k' +$bg[light_blue] λ %k ' ;; "lucifer") PROMPT='$bg[dark_gold] $fg[white]%m%f %k$bg[white]$fg[dark_gold] %~ %f%k$(virtualenv_prompt) -$bg[light_blue]%B ^_^ %b %k' +$bg[light_blue] λ %k ' + ;; + + "nymeria") + PROMPT='$bg[dark_green] $fg[white]%m%f %k$bg[white]$fg[dark_gold] %~ %f%k$(virtualenv_prompt) +$bg[light_blue] λ %k ' ;; *) PROMPT='$bg[black] $fg[white]%m%f %k$bg[white]$fg[black] %~ %f%k$(virtualenv_prompt) -$bg[light_blue]%B ^_^ %b %k' +$bg[light_blue] λ %k ' ;; esac |