dotfiles

configuration files
git clone https://pi.duncano.de/git/dotfiles.git
Log | Files | Refs | README

commit 540c947d1fa946708b6372b6efe483a692147ad2
parent 92cd04320c9289639616529164c737b7ee555327
Author: Duncaen <mail@duncano.de>
Date:   Thu, 26 Nov 2015 15:41:55 +0100

update

Diffstat:
.gitignore | 1+
bin/colors | 11+++++++++++
bin/dmenu_playerctl | 2+-
bin/dmenu_power | 2+-
bin/dmenu_runit | 8++++++++
bin/dmenu_z | 2+-
bin/h | 2+-
bin/netflix | 2++
bin/oeffnen | 24++++++++++++++++++++++++
bin/psgrep | 3+++
bin/runx | 5++---
bin/s | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
bin/sh | 0
bin/swaptop | 23+++++++++++++++++++++++
bin/xbps-overlay | 6++++++
bin/xi | 0
bin/xr | 0
bin/yiff | 14++++++++++++++
mksh.d/00-editor.sh | 3---
mksh.d/00-git.sh | 11-----------
mksh.d/00-go.sh | 4----
mksh.d/00-grc.sh | 12------------
mksh.d/00-infinality.sh | 19-------------------
mksh.d/00-ls.sh | 2--
mksh.d/00-misc.sh | 17-----------------
mksh.d/00-pager.sh | 15---------------
mksh.d/00-xbps.sh | 6------
mksh.d/90-prompt.sh | 9---------
mksh.d/91-z.sh | 4----
mkshrc | 8++++----
mkshrc.d/00-editor.sh | 3+++
mkshrc.d/00-git.sh | 11+++++++++++
mkshrc.d/00-go.sh | 4++++
mkshrc.d/00-infinality.sh | 19+++++++++++++++++++
mkshrc.d/00-ls.sh | 2++
mkshrc.d/00-misc.sh | 6++++++
mkshrc.d/00-pager.sh | 15+++++++++++++++
mkshrc.d/00-sudo.sh | 4++++
mkshrc.d/00-xbps.sh | 5+++++
mkshrc.d/90-prompt.sh | 9+++++++++
mkshrc.d/91-z.sh | 4++++
profile | 4++--
service/x | 2++
sv/dwm/run | 2+-
sv/runsvdir-duncan/env/HOME | 1-
sv/runsvdir-duncan/env/LOGNAME | 1-
sv/runsvdir-duncan/env/SHELL | 1-
sv/runsvdir-duncan/env/USER | 1-
sv/runsvdir-duncan/run | 3+--
sv/statusbar/run | 5+++--
sv/syncthing/log/run | 2+-
sv/syncthing/run | 2+-
sv/unclutter/run | 2+-
sv/vbox-win/control/t | 2+-
sv/vbox-win/run | 2+-
sv/x/down | 0
sv/x/finish | 2+-
sv/x/run | 3++-
sv/x/xinit | 5++---
vim/autoload/plug.vim | 156+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
vim/autoload/plug.vim.old | 537+++++++++++++++++++++++++++++++++++++++++--------------------------------------
vimrc | 4++--
xinitrc | 10+++++++---
63 files changed, 647 insertions(+), 500 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ vim/.netrwhist vim/vim sv/*/supervise/ sv/*/log/supervise/ +sv/vpn-* diff --git a/bin/colors b/bin/colors @@ -0,0 +1,11 @@ +#!/bin/sh + +for x in 0 1 4 5 7 8; do + for i in $(seq 30 37); do + for a in $(seq 40 47); do + printf "\e[%d;%d;%dm\\\e[%d;%d;%dm\e[0;37;40m " "$x" "$i" "$a" "$x" "$i" "$a" + done + printf "\n" + done +done +printf "\n" diff --git a/bin/dmenu_playerctl b/bin/dmenu_playerctl @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh select_player() { playing="" diff --git a/bin/dmenu_power b/bin/dmenu_power @@ -1,4 +1,4 @@ -#!/usr/bin/mksh +#!/bin/sh : ${DMENU:=dmenu} ret=$(echo "Suspend\nLock\nHibernate\nReboot\nShutdown" | ${DMENU} -p "Power:" -i | tr '[A-Z]' '[a-z]') diff --git a/bin/dmenu_runit b/bin/dmenu_runit @@ -0,0 +1,8 @@ +#!/bin/sh + +list() { + +} + +dmenu | + diff --git a/bin/dmenu_z b/bin/dmenu_z @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh . /home/duncan/repos/github.com/Duncaen/dotfiles/z/z.sh ret=$(z -l | sort -nr | awk '{print $2}' | dmenu -l 10) diff --git a/bin/h b/bin/h @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh dir="$PWD" while [ -n "$dir" ]; do diff --git a/bin/netflix b/bin/netflix @@ -0,0 +1,2 @@ +#!/bin/sh +chromium --app="http://www.netflix.com/" diff --git a/bin/oeffnen b/bin/oeffnen @@ -0,0 +1,24 @@ +#!/bin/sh + +_youtube() { + grep '\(http[s]*://\)*\(www.\)*\(youtube\.com/watch\|youtu\.be\)*' || return 0 + echo "$1" +} + +_feh() { + grep '\.\(jpg\)*\(png\)*' || return 0 + echo "test $1" + feh "$1" +} + +_yt_REGEXP="" +_feh_REGEXP=".(jpg|jpeg|png|tiff)$" +_feh_CMD="feh %s" +cmds="youtube feh" + +arg="$1" + +for n in ${cmds}; do + echo "$arg" | "_$n" && break + echo "check next" +done diff --git a/bin/psgrep b/bin/psgrep @@ -0,0 +1,3 @@ +#!/bin/sh + +ps u $(pgrep "$1") diff --git a/bin/runx b/bin/runx @@ -1,4 +1,3 @@ -#!/bin/mksh +#!/bin/sh -cd ~/sv/x -exec runsv ~/sv/x +sv once ~/service/x diff --git a/bin/s b/bin/s @@ -1,4 +1,18 @@ -#!/usr/bin/mksh +#!/bin/sh + +usage() { + cat <<EOUSAGE +Usage: s [-u <user>] [-w <sec>] <COMMAND> [SERVICE...] +COMMANDS + enable + disable + up + down + reload + restart +EOUSAGE + exit 1 +} fatal() { msg "$@" >&2 @@ -6,41 +20,54 @@ fatal() { } msg() { - printf "$@" + printf "$@\n" } sv_enable() { - [ ! -e "${SVDIR}${1}" ] && fatal "service '${1}' not found.\n" - [ -e "${SERVICEDIR}${1}" ] && fatal "service '${1}' already enabled.\n" - ln -sfv "${SVDIR}${1}" "${SERVICEDIR}${1}" } sv_disable() { - [ ! -e "${SVDIR}${1}" ] && fatal "service '${1}' not found." - [ ! -e "${SERVICEDIR}${1}" ] && fatal "service '${1}' already disabled.\n" - rm -rfv "${SERVICEDIR}${1}" } -sv_list() { - sv s "${SVDIR}"* 2>/dev/null +sv_status_wants() { + dd if="$1/supervise/status" bs=1 skip=17 count=1 2>/dev/null } -sv_deps() { - for service in "$@"; do - # TODO: check if service exists - case $(cat "${SVDIR}${service}/supervise/stat") in - run*) - /home/duncan/bin/s check "${service}" >/dev/null || wait+=" $service" +sv_list() { + for dir in "$1/"*; do + status="disabled" + color="$COLOR_FG_GREY" + wants="" + name="${dir##*/}" + [ -e "${dir}/supervise/stat" ] && status=$(cat "${dir}/supervise/stat") + [ "$status" != "disabled" ] && wants=$(sv_status_wants "${dir}") + case "$status" in + run) + if [ "$wants" = "u" ]; then + color="$COLOR_FG_GREEN" + else + color="$COLOR_FG_RED" + fi ;; - down*) - /home/duncan/bin/s u "${service}" >/dev/null && wait+=" $service" + down) + if [ "$wants" = "d" ]; then + color="$COLOR_FG_GREEN" + else + color="$COLOR_FG_RED" + fi ;; esac + printf "%-20s\t$color%-10s$COLOR_FG\n" "$name" "$status" done - [ -z "$wait" ] || fatal "wait for dependencies:$wait.\n" - exit 0 } +: ${SVCMD:=$(command -v sv)} + +: ${COLOR_FG:="\e[0;37;40m"} +: ${COLOR_FG_RED="\e[0;31;40m"} +: ${COLOR_FG_GREEN="\e[0;32;40m"} +: ${COLOR_FG_GREY:="\e[1;30;40m"} + while getopts "u:w:v" opt; do case "$opt" in u) SVUSER="$OPTARG" ;; @@ -49,25 +76,33 @@ while getopts "u:w:v" opt; do done shift $(($OPTIND - 1)) -: ${SVUSER:=$USER} - -case "$SVUSER" in +case "${SVUSER:=$USER}" in root) - SVDIR="/etc/sv/" - SERVICEDIR="/var/service/" + : ${ETCSVDIR:="/etc/sv"} + : ${SVDIR:="/var/service"} ;; *) - HOMEDIR=$(getent passwd "$SVUSER" | cut -d':' -f6) - SVDIR="${HOMEDIR}/sv/" - SERVICEDIR="${HOMEDIR}/service/" + : ${ETCSVDIR:="${HOME}/sv"} + : ${SVDIR:="${HOME}/service"} ;; esac +[ -z "$1" ] && usage case "$1" in - ls|list) sv_list "$2" ;; - enable) sv_enable "$2" ;; - disable) sv_disable "$2" ;; - deps) shift 1; sv_deps "$@" ;; - tree) shift 1; sv_tree "$SVDIR" ;; - *) SVDIR="$SVDIR" sv "$@" ;; + ls|list) sv_list "${ETCSVDIR}" ;; + en) + [ -z "$2" ] && usage + [ -d "${ETCSVDIR}/$2" ] && fatal "service '$2' does not exist" + [ -h "$2" ] && fatal "service '$2' is already enabled" + ln -sfv "${ETCSVDIR}/${2}" "${SVDIR}/${2}" + ;; + dis) + [ -z "$2" ] && usage + [ -d "${ETCSVDIR}/$2" ] && fatal "service '$2' does not exist" + [ ! -h "$2" ] && fatal "service '$2' is not enabled" + rm -v "${SVDIR}/$2" + ;; + x|e|X|E|D|T|c|u|d|o|t|p|h|a|i|k|q|1|2|s|r|f|restart) + SVDIR="${SVDIR}" "${SVCMD}" "$@" + ;; esac diff --git a/bin/sh b/bin/sh Binary files differ. diff --git a/bin/swaptop b/bin/swaptop @@ -0,0 +1,23 @@ +#!/bin/sh +# swaptop - show most swap-using processes +# 17sep2011 +chris+, portable 19sep2011 +chris+ + +if grep -q VmSwap /proc/1/status; then + # Efficient interface since revision b084d435. + awk '/^Name:/ { name = $2 } + /^Pid:/ { pid = $2} + /^VmSwap:/ { + swap = $2 + if (swap>0) + printf "%8d %s %d\n", swap, name, pid + }' /proc/[0-9]*/status | sort -nr +else + for f in /proc/[0-9]*; do + # awk will fail on permission denied + awk 'BEGIN { swap=0 } + $30 { pid = $1; name = substr($2,2,length($2)-2) } + $1=="Swap:" {swap += $2} + END { if (swap>0) printf "%8d %s %d\n", swap, name, pid }' \ + $f/stat $f/smaps 2>/dev/null + done | sort -nr +fi diff --git a/bin/xbps-overlay b/bin/xbps-overlay @@ -0,0 +1,6 @@ +#!/bin/sh + +for pkg in "$@"; do + pkgver=$(xbps-uhelper getpkgversion "$pkg") + echo "$pkgver" +done diff --git a/bin/xi b/bin/xi diff --git a/bin/xr b/bin/xr diff --git a/bin/yiff b/bin/yiff @@ -0,0 +1,14 @@ +#!/usr/bin/mksh +# Script by Ypnose - http://ywstd.fr + +while IFS=$'\n' read -r LINE; do + CHAR="${LINE::1}" + case $CHAR in + \-) print -- "\033[1;31m${LINE}\033[0m" ;; + \+) print -- "\033[0;32m${LINE}\033[0m" ;; + \@) print -- "\033[1;35m${LINE}\033[0m" ;; + *) print -- "$LINE" ;; + esac +done + +exit diff --git a/mksh.d/00-editor.sh b/mksh.d/00-editor.sh @@ -1,3 +0,0 @@ -EDITOR=$(command -v vim) -VISUAL="$EDITOR" -export EDITOR VISUAL diff --git a/mksh.d/00-git.sh b/mksh.d/00-git.sh @@ -1,11 +0,0 @@ -if [ -x /usr/bin/git ]; then - alias ga='git add' - alias gc='git commit' - alias gca='git commit --amend' - alias gp='git pull' - alias gpr='git pull --rebase' - alias gs='git status -sb' - alias gb='git branch' - alias gd='git icdiff' - alias gl='git l' -fi diff --git a/mksh.d/00-go.sh b/mksh.d/00-go.sh @@ -1,4 +0,0 @@ -GOPATH="$HOME/go" -GOBIN="$GOPATH/bin" -PATH="$PATH:$GOBIN" -export GOPATH GOBIN PATH diff --git a/mksh.d/00-grc.sh b/mksh.d/00-grc.sh @@ -1,12 +0,0 @@ -case "$HOSTNAME" in - tux|mir02) - alias ld='grc -es --colour=auto ld' - alias ss='grc -es --colour=auto ss' - alias ps='grc -es --colour=auto ps' - alias mount='grc -es --colour=auto mount' - alias dig='grc -es --colour=auto dig' - alias ping='grc -es --colour=auto ping' - alias traceroute='grc -es --colour=auto traceroute' - alias df='grc -es --colour=auto df' - ;; -esac diff --git a/mksh.d/00-infinality.sh b/mksh.d/00-infinality.sh @@ -1,19 +0,0 @@ -if [ -n "$DISPLAY" ]; then - export INFINALITY_FT_FILTER_PARAMS='10 35 40 35 10' - export INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0 - export INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0 - export INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false - export INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0 - export INFINALITY_FT_GAMMA_CORRECTION='0 100' - export INFINALITY_FT_BRIGHTNESS=0 - export INFINALITY_FT_CONTRAST=0 - export INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=5 - export INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 - export INFINALITY_FT_FRINGE_FILTER_STRENGTH=5 - export INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=10 - export INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 - export INFINALITY_FT_STEM_FITTING_STRENGTH=0 - export INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 - export INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - export INFINALITY_FT_USE_VARIOUS_TWEAKS=true -fi diff --git a/mksh.d/00-ls.sh b/mksh.d/00-ls.sh @@ -1,2 +0,0 @@ -alias ls="ls -hF --color" - diff --git a/mksh.d/00-misc.sh b/mksh.d/00-misc.sh @@ -1,17 +0,0 @@ -alias wanip='curl ipinfo.io/ip' - -function psgrep { - ps u `pgrep "$1"` -} - -function colors { - for x in 0 1 4 5 7 8; do - for i in $(seq 30 37); do - for a in $(seq 40 47); do - echo -ne "\e[$x;$i;$a""m\\\e[$x;$i;$a""m\e[0;37;40m " - done - echo "" - done - done - echo "" -} diff --git a/mksh.d/00-pager.sh b/mksh.d/00-pager.sh @@ -1,15 +0,0 @@ -PAGER=$(command -v less) -LESS="-FXRi" -# LESSHISTFILE=- -MANWIDTH=80 - -# colored man pages: -LESS_TERMCAP_md=$'\e[1;31m' # start bold -LESS_TERMCAP_so=$'\e[1;40;37m' # start standout -LESS_TERMCAP_se=$'\e[0m' # end standout -LESS_TERMCAP_us=$'\e[0;34m' # start underlining -LESS_TERMCAP_ue=$'\e[0m' # end underlining -LESS_TERMCAP_me=$'\e[0m' # end all modes]']']']']']' - -export PAGER LESS LESSHISTFILE MANWIDTH LESS_TERMCAP_md LESS_TERMCAP_so \ - LESS_TERMCAP_se LESS_TERMCAP_us LESS_TERMCAP_ue LESS_TERMCAP_me diff --git a/mksh.d/00-xbps.sh b/mksh.d/00-xbps.sh @@ -1,6 +0,0 @@ -if [ -x /usr/bin/xbps-install ]; then - export XBPS_DISTDIR=/srv/void-packages - alias xi='sudo xbps-install' - alias xr='sudo xbps-remove' - alias xq='xbps-query' -fi diff --git a/mksh.d/90-prompt.sh b/mksh.d/90-prompt.sh @@ -1,9 +0,0 @@ -if [ -x /usr/bin/slcp ]; then - PS1='$(slcp $COLUMNS $?)' -fi - -case "$TERM" in - dvtm*|xterm*|rxvt*) - PS1+='$(echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007")' - ;; -esac diff --git a/mksh.d/91-z.sh b/mksh.d/91-z.sh @@ -1,4 +0,0 @@ -if [ -r /home/duncan/repos/github.com/Duncaen/dotfiles/z/z.sh ]; then - . /home/duncan/repos/github.com/Duncaen/dotfiles/z/z.sh - PS1+='$(_z --add "${PWD}")' -fi diff --git a/mkshrc b/mkshrc @@ -397,10 +397,10 @@ export HISTFILE HISTSIZE SHELL PATH printf '\033[?1h\033=' >/dev/tty -if [ -d ~/.mksh.d ]; then - for f in ~/.mksh.d/*.sh; do - [ -x "$f" ] && . "$f" - done +if [ -d ~/.mkshrc.d ]; then + for f in ~/.mkshrc.d/*.sh; do + [ -x "$f" ] && . "$f" + done fi : place customisations above this line diff --git a/mkshrc.d/00-editor.sh b/mkshrc.d/00-editor.sh @@ -0,0 +1,3 @@ +EDITOR=$(command -v vim) +VISUAL="$EDITOR" +export EDITOR VISUAL diff --git a/mkshrc.d/00-git.sh b/mkshrc.d/00-git.sh @@ -0,0 +1,11 @@ +if [ -x /usr/bin/git ]; then + alias ga='git add' + alias gc='git commit' + alias gca='git commit --amend' + alias gp='git pull' + alias gpr='git pull --rebase' + alias gs='git status -sb' + alias gb='git branch' + alias gd='git diff' + alias gl='git l' +fi diff --git a/mkshrc.d/00-go.sh b/mkshrc.d/00-go.sh @@ -0,0 +1,4 @@ +GOPATH="$HOME/go" +GOBIN="$GOPATH/bin" +PATH="$PATH:$GOBIN" +export GOPATH GOBIN PATH diff --git a/mkshrc.d/00-infinality.sh b/mkshrc.d/00-infinality.sh @@ -0,0 +1,19 @@ +if [ -n "$DISPLAY" ]; then + export INFINALITY_FT_FILTER_PARAMS='10 35 40 35 10' + export INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0 + export INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0 + export INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false + export INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0 + export INFINALITY_FT_GAMMA_CORRECTION='0 100' + export INFINALITY_FT_BRIGHTNESS=0 + export INFINALITY_FT_CONTRAST=0 + export INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=5 + export INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 + export INFINALITY_FT_FRINGE_FILTER_STRENGTH=5 + export INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=10 + export INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 + export INFINALITY_FT_STEM_FITTING_STRENGTH=0 + export INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 + export INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true + export INFINALITY_FT_USE_VARIOUS_TWEAKS=true +fi diff --git a/mkshrc.d/00-ls.sh b/mkshrc.d/00-ls.sh @@ -0,0 +1,2 @@ +alias ls="ls -hF --color" + diff --git a/mkshrc.d/00-misc.sh b/mkshrc.d/00-misc.sh @@ -0,0 +1,6 @@ +alias wanip='curl ipinfo.io/ip' + +psgrep() { +} + +# alias agsed="ag -l $1 | xargs sed -ri.bak -e 's/$1/$2/g'" diff --git a/mkshrc.d/00-pager.sh b/mkshrc.d/00-pager.sh @@ -0,0 +1,15 @@ +PAGER=$(command -v less) +LESS="-FXRi" +# LESSHISTFILE=- +MANWIDTH=80 + +# colored man pages: +LESS_TERMCAP_md=$'\e[1;31m' # start bold +LESS_TERMCAP_so=$'\e[1;40;37m' # start standout +LESS_TERMCAP_se=$'\e[0m' # end standout +LESS_TERMCAP_us=$'\e[0;34m' # start underlining +LESS_TERMCAP_ue=$'\e[0m' # end underlining +LESS_TERMCAP_me=$'\e[0m' # end all modes]']']']']']' + +export PAGER LESS LESSHISTFILE MANWIDTH LESS_TERMCAP_md LESS_TERMCAP_so \ + LESS_TERMCAP_se LESS_TERMCAP_us LESS_TERMCAP_ue LESS_TERMCAP_me diff --git a/mkshrc.d/00-sudo.sh b/mkshrc.d/00-sudo.sh @@ -0,0 +1,4 @@ +if [ -x "$(command -v /usr/bin/sudo)" ]; then + alias sudovi="EDITOR=vi sudoedit $@" + alias sudovim="EDITOR=vim sudoedit $@" +fi diff --git a/mkshrc.d/00-xbps.sh b/mkshrc.d/00-xbps.sh @@ -0,0 +1,5 @@ +if [ -x /usr/bin/xbps-install ]; then + alias xi='sudo xbps-install' + alias xr='sudo xbps-remove' + alias xq='xbps-query' +fi diff --git a/mkshrc.d/90-prompt.sh b/mkshrc.d/90-prompt.sh @@ -0,0 +1,9 @@ +if [ -x "$(command -v slcp)" ]; then + PS1='$(slcp $COLUMNS $?)' +fi + +case "$TERM" in + dvtm*|xterm*|rxvt*) + PS1+='$(echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007")' + ;; +esac diff --git a/mkshrc.d/91-z.sh b/mkshrc.d/91-z.sh @@ -0,0 +1,4 @@ +if [ -r /home/duncan/repos/github.com/Duncaen/dotfiles/z/z.sh ]; then + . /home/duncan/repos/github.com/Duncaen/dotfiles/z/z.sh + PS1+='$(_z --add "${PWD}")' +fi diff --git a/profile b/profile @@ -5,5 +5,5 @@ [ -r /usr/bin/keychain -a "$(tty)" = "/dev/tty1" ] && eval `keychain --eval --agents ssh id_rsa` # -export DISPLAY=:0 -export XAUTHORITY=/home/duncan/.Xauthority +# export DISPLAY=:0 +# export XAUTHORITY=/home/duncan/.Xauthority diff --git a/service/x b/service/x @@ -0,0 +1 @@ +/home/duncan/sv/x+ \ No newline at end of file diff --git a/sv/dwm/run b/sv/dwm/run @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh exec 2>&1 diff --git a/sv/runsvdir-duncan/env/HOME b/sv/runsvdir-duncan/env/HOME @@ -1 +0,0 @@ -/home/duncan diff --git a/sv/runsvdir-duncan/env/LOGNAME b/sv/runsvdir-duncan/env/LOGNAME @@ -1 +0,0 @@ -duncan diff --git a/sv/runsvdir-duncan/env/SHELL b/sv/runsvdir-duncan/env/SHELL @@ -1 +0,0 @@ -/usr/bin/mksh diff --git a/sv/runsvdir-duncan/env/USER b/sv/runsvdir-duncan/env/USER @@ -1 +0,0 @@ -duncan diff --git a/sv/runsvdir-duncan/run b/sv/runsvdir-duncan/run @@ -1,5 +1,4 @@ #!/bin/sh exec 2>&1 -# exec chpst -u duncan -e ./env runsvdir /home/duncan/service -exec su -l -c "exec runsvdir /home/duncan/service" duncan +exec chpst -e ./env -u duncan:duncan runsvdir /home/duncan/service/ diff --git a/sv/statusbar/run b/sv/statusbar/run @@ -1,3 +1,4 @@ -#!/bin/mksh +#!/bin/sh -exec go-dwmstatus +exec 2>&1 +exec /home/duncan/go/bin/go-dwmstatus diff --git a/sv/syncthing/log/run b/sv/syncthing/log/run @@ -1,3 +1,3 @@ -#!/bin/mksh +#!/bin/sh exec logger -t syncthing diff --git a/sv/syncthing/run b/sv/syncthing/run @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh exec 2>&1 exec syncthing -logflags 0 -no-restart diff --git a/sv/unclutter/run b/sv/unclutter/run @@ -1,3 +1,3 @@ -#!/usr/bin/mksh +#!/usr/bin/sh exec unclutter -noevents -root -visible -jitter 10 -idle 5 diff --git a/sv/vbox-win/control/t b/sv/vbox-win/control/t @@ -1,3 +1,3 @@ -#!/bin/mksh +#!/bin/sh VBoxManage controlvm "Windows 8.1" savestate diff --git a/sv/vbox-win/run b/sv/vbox-win/run @@ -1,3 +1,3 @@ -#!/bin/mksh +#!/bin/sh exec VBoxSDL --startvm "Windows 8.1" diff --git a/sv/x/down b/sv/x/down diff --git a/sv/x/finish b/sv/x/finish @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh sv -w600 force-stop ~/service.x/* sv exit ~/service.x/* diff --git a/sv/x/run b/sv/x/run @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh exec 2>&1 @@ -12,3 +12,4 @@ xauth -q -f "$xserverauthfile" add "$DISPLAY" . "$mcookie" xauth -q add "$DISPLAY" . "$mcookie" exec xinit "${PWD}/xinit" -- /etc/X11/xinit/xserverrc "$DISPLAY" -noreset -auth "${xserverauthfile}" +# exec /usr/bin/Xorg "$DISPLAY" -nolisten tcp -noreset -verbose 2 "vt7" diff --git a/sv/x/xinit b/sv/x/xinit @@ -1,4 +1,4 @@ -#!/bin/mksh +#!/bin/sh exec 2>&1 @@ -20,5 +20,4 @@ esac setxkbmap de -echo "starting ~/service.x" -exec /usr/bin/ck-launch-session dbus-launch runsvdir ~/service.x +exec runsvdir ~/service.x 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................' diff --git a/vim/autoload/plug.vim b/vim/autoload/plug.vim @@ -24,15 +24,19 @@ " " 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': 'yes \| ./install' } +" 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. @@ -398,7 +402,7 @@ function! s:lod(names, types) endfunction function! s:lod_ft(pat, names) - call s:lod(a:names, ['plugin', 'after/plugin']) + call s:lod(a:names, ['plugin', 'after/plugin', 'syntax', 'after/syntax']) execute 'autocmd! PlugLOD FileType' a:pat if exists('#filetypeplugin#FileType') doautocmd filetypeplugin FileType @@ -645,7 +649,7 @@ function! s:do(pull, force, todo) endif let installed = has_key(s:update.new, name) let updated = installed ? 0 : - \ (a:pull && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir))) + \ (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 .' ... ') @@ -1049,17 +1053,17 @@ G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) G_STOP = thr.Event() G_THREADS = {} -class BaseExc(Exception): +class PlugError(Exception): def __init__(self, msg): self._msg = msg @property def msg(self): return self._msg -class CmdTimedOut(BaseExc): +class CmdTimedOut(PlugError): pass -class CmdFailed(BaseExc): +class CmdFailed(PlugError): pass -class InvalidURI(BaseExc): +class InvalidURI(PlugError): pass class Action(object): INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] @@ -1073,7 +1077,7 @@ class Buffer(object): self.maxy = int(vim.eval('winheight(".")')) self.num_plugs = num_plugs - def _where(self, name): + 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)) @@ -1102,8 +1106,7 @@ class Buffer(object): def write(self, action, name, lines): first, rest = lines[0], lines[1:] msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)] - padded_rest = [' ' + line for line in rest] - msg.extend(padded_rest) + msg.extend([' ' + line for line in rest]) try: if action == Action.ERROR: @@ -1113,7 +1116,7 @@ class Buffer(object): self.bar += '=' curbuf = vim.current.buffer - lnum = self._where(name) + 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]): @@ -1127,56 +1130,73 @@ class Buffer(object): pass class Command(object): - def __init__(self, cmd, cmd_dir=None, timeout=60, ntries=3, cb=None, clean=None): + 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.ntries = ntries self.callback = cb if cb else (lambda msg: None) - self.clean = clean + self.clean = clean if clean else (lambda: None) + self.proc = None - def attempt_cmd(self): - """ Tries to run the command, returns result if no exceptions. """ - attempt = 0 - finished = False - limit = self.timeout + @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.timeout_cmd() + result = self.try_command() finished = True + return result except CmdTimedOut: - if attempt != self.ntries: - 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) + if attempt != ntries: + self.notify_retry() self.timeout += limit - self.callback(['Retrying ...']) else: raise - return result - - def timeout_cmd(self): + 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 + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output """ - proc = None first_line = True + try: - tfile = tempfile.NamedTemporaryFile(mode='w+b', delete=False) - proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile, - stderr=subprocess.STDOUT, shell=True, preexec_fn=os.setsid) - while proc.poll() is None: - # Yield this thread - time.sleep(0.2) + 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 @@ -1190,23 +1210,24 @@ class Command(object): if time_diff > self.timeout: raise CmdTimedOut(['Timeout!']) + thrd.join(0.5) + tfile.seek(0) - result = [line.decode().rstrip() for line in tfile] + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) - if proc.returncode != 0: - msg = [''] - msg.extend(result) - raise CmdFailed(msg) + return result except: - if proc and proc.poll() is None: - os.killpg(proc.pid, signal.SIGTERM) - if self.clean: - self.clean() + self.terminate() raise - finally: - os.remove(tfile.name) - return result + 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): @@ -1227,7 +1248,7 @@ class Plugin(object): self.install() with self.lock: thread_vim_command("let s:update.new['{0}'] = 1".format(self.name)) - except (CmdTimedOut, CmdFailed, InvalidURI) as exc: + except PlugError as exc: self.write(Action.ERROR, self.name, exc.msg) except KeyboardInterrupt: G_STOP.set() @@ -1252,11 +1273,18 @@ class Plugin(object): 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, G_RETRIES, callback, clean(target)) - result = com.attempt_cmd() + '' 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()) @@ -1277,18 +1305,12 @@ class Plugin(object): '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, G_RETRIES, callback) - result = com.attempt_cmd() + 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 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, G_RETRIES) - result = command.attempt_cmd() - return result[-1] - def write(self, action, name, msg): self.buf_q.put((action, name, msg)) @@ -1325,7 +1347,7 @@ class RefreshThread(thr.Thread): while self.running: with self.lock: thread_vim_command('noautocmd normal! a') - time.sleep(0.2) + time.sleep(0.33) def stop(self): self.running = False @@ -1343,7 +1365,7 @@ def esc(name): 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() + buf = os.read(fread, 100000).decode('utf-8', 'replace') os.close(fread) line = buf.rstrip('\r\n') diff --git a/vim/autoload/plug.vim.old b/vim/autoload/plug.vim.old @@ -3,8 +3,7 @@ " " Download plug.vim and put it in ~/.vim/autoload " -" mkdir -p ~/.vim/autoload -" curl -fLo ~/.vim/autoload/plug.vim \ +" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ " https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim " " Edit your .vimrc @@ -15,6 +14,9 @@ " 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' } @@ -23,7 +25,7 @@ " Plug 'https://github.com/junegunn/vim-github-dashboard.git' " " " Plugin options -" Plug 'nsf/gocode', { 'tag': 'go.weekly.2012-03-13', 'rtp': 'vim' } +" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } " " " Plugin outside ~/.vim/plugged with post-update hook " Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': 'yes \| ./install' } @@ -31,13 +33,14 @@ " " 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) 2014 Junegunn Choi +" Copyright (c) 2015 Junegunn Choi " " MIT License " @@ -68,14 +71,12 @@ let g:loaded_plug = 1 let s:cpo_save = &cpo set cpo&vim -let s:plug_src = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.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:py2 = has('python') && !s:is_win -let s:ruby = has('ruby') && (v:version >= 703 || v:version == 702 && has('patch374')) -let s:nvim = has('nvim') && !s:is_win +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 = { @@ -166,7 +167,7 @@ function! plug#end() if has_key(plug, 'on') let s:triggers[name] = { 'map': [], 'cmd': [] } for cmd in s:to_a(plug.on) - if cmd =~ '^<Plug>.\+' + if cmd =~? '^<Plug>.\+' if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i')) call s:assoc(lod.map, cmd, name) endif @@ -271,7 +272,7 @@ if s:is_win endfunction function! s:is_local_plug(repo) - return a:repo =~? '^[a-z]:' + return a:repo =~? '^[a-z]:\|^[%~]' endfunction else function! s:rtp(spec) @@ -359,7 +360,9 @@ function! plug#load(...) for name in a:000 call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) endfor - doautocmd BufRead + if exists('#BufRead') + doautocmd BufRead + endif return 1 endfunction @@ -389,14 +392,21 @@ function! s:lod(names, types) 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']) + call s:lod(a:names, ['plugin', 'after/plugin', 'syntax', 'after/syntax']) execute 'autocmd! PlugLOD FileType' a:pat - doautocmd filetypeplugin FileType - doautocmd filetypeindent FileType + 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) @@ -431,7 +441,7 @@ function! s:add(repo, ...) call add(g:plugs_order, name) endif let g:plugs[name] = spec - let s:loaded[name] = 0 + let s:loaded[name] = get(s:loaded, name, 0) catch return s:err(v:exception) endtry @@ -710,7 +720,7 @@ 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', 16) + \ 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)') : @@ -741,6 +751,16 @@ function! s:update_impl(pull, force, args) abort 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, @@ -749,7 +769,7 @@ function! s:update_impl(pull, force, args) abort \ 'pull': a:pull, \ 'force': a:force, \ 'new': {}, - \ 'threads': (s:py2 || s:ruby || s:nvim) ? min([len(todo), threads]) : 1, + \ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1, \ 'bar': '', \ 'fin': 0 \ } @@ -757,22 +777,27 @@ function! s:update_impl(pull, force, args) abort 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 s:py2 && !s:ruby && !s:nvim && s:update.threads > 1 + if python && !has('python3') && !ruby && !s:nvim && s:update.threads > 1 redir => pyv silent python import platform; print(platform.python_version()) redir END - let s:py2 = s:version_requirement( - \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 7]) + let python = s:version_requirement( + \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6]) endif - if (s:py2 || s:ruby) && !s:nvim && s:update.threads > 1 + + if (python || ruby) && s:update.threads > 1 try let imd = &imd if s:mac_gui set noimd endif - if s:ruby + if ruby call s:update_ruby() else call s:update_python() @@ -818,9 +843,7 @@ function! s:job_abort() if !s:nvim || !exists('s:jobs') return endif - augroup PlugJobControl - autocmd! - augroup END + for [name, j] in items(s:jobs) silent! call jobstop(j.jobid) if j.new @@ -830,52 +853,48 @@ function! s:job_abort() let s:jobs = {} endfunction -function! s:job_handler(name) abort +" 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 !has_key(s:jobs, a:name) - return - endif - let job = s:jobs[a:name] - - if v:job_data[1] == 'exit' - let job.running = 0 - if s:lastline(job.result) ==# 'Error' - let job.error = 1 - let job.result = substitute(job.result, "Error[\r\n]$", '', '') - endif - call s:reap(a:name) - call s:tick() - else - let job.result .= s:to_s(v:job_data[2]) + 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 job.tick = get(job, 'tick', -1) + 1 - if job.tick % len(s:jobs) == 0 - call s:log(job.new ? '+' : '*', a:name, job.result) + 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 = { 'running': 1, 'new': get(a:opts, 'new', 0), - \ 'error': 0, 'result': '' } + 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 x = jobstart(a:name, 'sh', ['-c', - \ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) - \ . ' || echo Error']) - if x > 0 - let job.jobid = x - augroup PlugJobControl - execute 'autocmd JobActivity' a:name printf('call s:job_handler(%s)', string(a:name)) - augroup END + 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 = x < 0 ? 'sh is not executable' : + let job.result = jid < 0 ? 'sh is not executable' : \ 'Invalid arguments (or job table is full)' endif else @@ -887,10 +906,6 @@ function! s:spawn(name, cmd, opts) endfunction function! s:reap(name) - if s:nvim - silent! execute 'autocmd! PlugJobControl JobActivity' a:name - endif - let job = s:jobs[a:name] if job.error call add(s:update.errors, a:name) @@ -966,16 +981,18 @@ while 1 " Without TCO, Vim stack is bound to explode call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') redraw - let checkout = s:shellesc(has_key(spec, 'tag') ? spec.tag : spec.branch) - let merge = s:shellesc(has_key(spec, 'tag') ? spec.tag : 'origin/'.spec.branch) + 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 [valid, msg] = s:git_valid(spec, 0) if valid if pull + let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' call s:spawn(name, - \ printf('(git fetch %s 2>&1 && git checkout -q %s 2>&1 && git merge --ff-only %s 2>&1 && git submodule update --init --recursive 2>&1)', - \ prog, checkout, merge), { 'dir': spec.dir }) + \ 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 @@ -984,7 +1001,8 @@ while 1 " Without TCO, Vim stack is bound to explode endif else call s:spawn(name, - \ printf('git clone %s --recursive %s -b %s %s 2>&1', + \ printf('git clone %s %s --recursive %s -b %s %s 2>&1', + \ has_tag ? '' : s:clone_opt, \ prog, \ s:shellesc(spec.uri), \ checkout, @@ -1001,12 +1019,16 @@ endwhile endfunction function! s:update_python() -python << EOF +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 -import Queue +try: + import queue +except ImportError: + import Queue as queue import random import re import shutil @@ -1018,56 +1040,44 @@ 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() - -class CmdTimedOut(Exception): +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(Exception): +class CmdFailed(PlugError): pass -class InvalidURI(Exception): +class InvalidURI(PlugError): pass class Action(object): INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-'] -class GLog(object): - ON = None - LOGDIR = None - @classmethod - def write(cls, msg): - if cls.ON is None: - cls.ON = int(vim.eval('get(g:, "plug_log_on", 0)')) - cls.LOGDIR = os.path.expanduser(vim.eval('get(g:, "plug_logs", "~/plug_logs")')) - if cls.ON: - if not os.path.exists(cls.LOGDIR): - os.makedirs(cls.LOGDIR) - cls._write(msg) - @classmethod - def _write(cls, msg): - name = thr.current_thread().name - fname = cls.LOGDIR + os.path.sep + name - with open(fname, 'ab') as flog: - ltime = datetime.datetime.now().strftime("%H:%M:%S.%f") - msg = '[{},{}] {}{}'.format(name, ltime, msg, '\n') - flog.write(msg) - class Buffer(object): - def __init__(self, lock, num_plugs): + def __init__(self, lock, num_plugs, is_pull, is_win): self.bar = '' - self.event = 'Updating' if vim.eval('s:update.pull') == '1' else 'Installing' - self.is_win = vim.eval('s:is_win') == '1' + 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): + def __where(self, name): """ Find first line with name in current buffer. Return line num. """ found, lnum = False, 0 - matcher = re.compile('^[-+x*] {}:'.format(name)) + matcher = re.compile('^[-+x*] {0}:'.format(name)) for line in vim.current.buffer: if matcher.search(line) is not None: found = True @@ -1080,37 +1090,33 @@ class Buffer(object): def header(self): curbuf = vim.current.buffer - curbuf[0] = self.event + ' plugins ({}/{})'.format(len(self.bar), self.num_plugs) + curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs) num_spaces = self.num_plugs - len(self.bar) - curbuf[1] = '[{}{}]'.format(self.bar, num_spaces * ' ') + curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ') - vim.command('normal! 2G') - if not self.is_win: - vim.command('redraw') - - def write(self, *args, **kwargs): with self.lock: - self._write(*args, **kwargs) + vim.command('normal! 2G') + if not self.is_win: + vim.command('redraw') - def _write(self, action, name, lines): + def write(self, action, name, lines): first, rest = lines[0], lines[1:] - msg = ['{} {}{}{}'.format(action, name, ': ' if first else '', first)] - padded_rest = [' ' + line for line in rest] - msg.extend(padded_rest) + 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, '{}')".format(name)) + vim.command("call add(s:update.errors, '{0}')".format(name)) elif action == Action.DONE: self.bar += '=' curbuf = vim.current.buffer - lnum = self._where(name) + lnum = self.__where(name) if lnum != -1: # Found matching line num del curbuf[lnum] - if lnum > self.maxy and action in {Action.INSTALL, Action.UPDATE}: + if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]): lnum = 3 else: lnum = 3 @@ -1118,59 +1124,76 @@ class Buffer(object): self.header() except vim.error: - GLog.write('Buffer Update FAILED.') + pass class Command(object): - def __init__(self, cmd, cmd_dir=None, timeout=60, ntries=3, cb=None, clean=None): + 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.ntries = ntries self.callback = cb if cb else (lambda msg: None) - self.clean = clean + self.clean = clean if clean else (lambda: None) + self.proc = None - def attempt_cmd(self): - """ Tries to run the command, returns result if no exceptions. """ - attempt = 0 - finished = False - limit = self.timeout + @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.timeout_cmd() + result = self.try_command() finished = True + return result except CmdTimedOut: - if attempt != self.ntries: - for count in range(3, 0, -1): - if G_STOP.is_set(): - raise KeyboardInterrupt - msg = 'Timeout. Will retry in {} second{} ...'.format( - count, 's' if count != 1 else '') - self.callback([msg]) - time.sleep(1) + if attempt != ntries: + self.notify_retry() self.timeout += limit - self.callback(['Retrying ...']) else: raise - return result - - def timeout_cmd(self): + 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 + Raises CmdFailed -> return code for Popen isn't 0 + Raises CmdTimedOut -> command exceeded timeout without new output """ - proc = None first_line = True + try: - tfile = tempfile.NamedTemporaryFile() - proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile, - stderr=subprocess.STDOUT, shell=True, preexec_fn=os.setsid) - while proc.poll() is None: - # Yield this thread - time.sleep(0.2) + 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 @@ -1184,31 +1207,35 @@ class Command(object): if time_diff > self.timeout: raise CmdTimedOut(['Timeout!']) + thrd.join(0.5) + tfile.seek(0) - result = [line.rstrip() for line in tfile] + result = [line.decode('utf-8', 'replace').rstrip() for line in tfile] + + if self.proc.returncode != 0: + raise CmdFailed([''] + result) - if proc.returncode != 0: - msg = [''] - msg.extend(result) - raise CmdFailed(msg) + return result except: - if proc and proc.poll() is None: - os.killpg(proc.pid, signal.SIGTERM) - if self.clean: - self.clean() + self.terminate() raise - return result + 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, lock): + def __init__(self, name, args, buf_q, lock): self.name = name self.args = args - self.buf = buf + 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: @@ -1217,15 +1244,15 @@ class Plugin(object): else: self.install() with self.lock: - vim.command("let s:update.new['{}'] = 1".format(self.name)) - except (CmdTimedOut, CmdFailed, InvalidURI) as exc: - self.write(Action.ERROR, self.name, exc.message) + 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{}'.format(traceback.format_exc().rstrip()) + msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip()) self.write(Action.ERROR, self.name, msg.split('\n')) raise @@ -1241,49 +1268,48 @@ class Plugin(object): return _clean self.write(Action.INSTALL, self.name, ['Installing ...']) - callback = functools.partial(self.buf.write, Action.INSTALL, self.name) - cmd = 'git clone {} --recursive {} -b {} {} 2>&1'.format( - G_PROGRESS, self.args['uri'], self.checkout, esc(target)) - com = Command(cmd, None, G_TIMEOUT, G_RETRIES, callback, clean(target)) - result = com.attempt_cmd() + 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: {}'.format(actual_uri), - 'Expected {}'.format(expect_uri), + '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.buf.write, Action.UPDATE, self.name) - cmds = ['git fetch {}'.format(G_PROGRESS), - 'git checkout -q {}'.format(self.checkout), - 'git merge --ff-only {}'.format(self.merge), + 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) - GLog.write(cmd) - com = Command(cmd, self.args['dir'], G_TIMEOUT, G_RETRIES, callback) - result = com.attempt_cmd() - GLog.write(result) + 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 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, G_RETRIES) - result = command.attempt_cmd() - return result[-1] - def write(self, action, name, msg): - GLog.write('{} {}: {}'.format(action, name, '\n'.join(msg))) - self.buf.write(action, name, msg) + self.buf_q.put((action, name, msg)) class PlugThread(thr.Thread): def __init__(self, tname, args): @@ -1293,17 +1319,20 @@ class PlugThread(thr.Thread): def run(self): thr.current_thread().name = self.tname - work_q, lock, buf = self.args + buf_q, work_q, lock = self.args try: while not G_STOP.is_set(): name, args = work_q.get_nowait() - GLog.write('{}: Dir {}'.format(name, args['dir'])) - plug = Plugin(name, args, buf, lock) + plug = Plugin(name, args, buf_q, lock) plug.manage() work_q.task_done() - except Queue.Empty: - GLog.write('Queue now empty.') + 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): @@ -1314,19 +1343,26 @@ class RefreshThread(thr.Thread): def run(self): while self.running: with self.lock: - vim.command('noautocmd normal! a') - time.sleep(0.2) + 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) + buf = os.read(fread, 100000).decode('utf-8', 'replace') os.close(fread) line = buf.rstrip('\r\n') @@ -1339,42 +1375,40 @@ def nonblock_read(fname): def main(): thr.current_thread().name = 'main' - GLog.write('') - if GLog.ON and os.path.exists(GLog.LOGDIR): - shutil.rmtree(GLog.LOGDIR) - - threads = [] 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' - GLog.write('Plugs: {}'.format(plugs)) - GLog.write('PULL: {}, WIN: {}, MAC: {}'.format(G_PULL, is_win, mac_gui)) - GLog.write('Num Threads: {}'.format(nthreads)) lock = thr.Lock() - buf = Buffer(lock, len(plugs)) - work_q = Queue.Queue() + 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) - GLog.write('Starting Threads') + global G_THREADS for num in range(nthreads): tname = 'PlugT-{0:02}'.format(num) - thread = PlugThread(tname, (work_q, lock, buf)) + thread = PlugThread(tname, (buf_q, work_q, lock)) thread.start() - threads.append(thread) + G_THREADS[tname] = thread if mac_gui: rthread = RefreshThread(lock) rthread.start() - GLog.write('Joining Live Threads') - for thread in threads: - thread.join() + 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() - GLog.write('Cleanly Exited Main') main() EOF @@ -1538,6 +1572,7 @@ function! s:update_ruby() 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 @@ -1567,7 +1602,8 @@ function! s:update_ruby() else if pull log.call name, 'Updating ...', :update - bt.call "#{cd} #{dir} && git fetch #{progress} 2>&1 && git checkout -q #{checkout} 2>&1 && git merge --ff-only #{merge} 2>&1 && #{subm}", name, :update, nil + 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 @@ -1575,7 +1611,7 @@ function! s:update_ruby() else d = esc dir.sub(%r{[\\/]+$}, '') log.call name, 'Installing ...', :install - bt.call "git clone #{progress} --recursive #{uri} -b #{checkout} #{d} 2>&1", name, :install, proc { + bt.call "git clone #{clone_opt unless tag} #{progress} --recursive #{uri} -b #{checkout} #{d} 2>&1", name, :install, proc { FileUtils.rm_rf dir } end @@ -1625,14 +1661,14 @@ endfunction function! s:system(cmd, ...) try - let sh = &shell + let [sh, shrd] = [&shell, &shellredir] if !s:is_win - set shell=sh + 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 = sh + let [&shell, &shellredir] = [sh, shrd] endtry endfunction @@ -1679,6 +1715,12 @@ function! s:git_valid(spec, check_branch) return [ret, msg] 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) @@ -1727,9 +1769,7 @@ function! s:clean(force) call inputrestore() if yes for dir in todo - if isdirectory(dir) - call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(dir)) - endif + call s:rm_rf(dir) endfor call append(line('$'), 'Removed.') else @@ -1740,55 +1780,30 @@ function! s:clean(force) endfunction function! s:upgrade() - let new = s:me . '.new' - echo 'Downloading '. s:plug_src + echo 'Downloading the latest version of vim-plug' redraw + let tmp = tempname() + let new = tmp . '/plug.vim' + try - if executable('curl') - let output = s:system(printf('curl -fLo %s %s', s:shellesc(new), s:plug_src)) - if v:shell_error - throw get(s:lines(output), -1, v:shell_error) - endif - elseif s:ruby - call s:upgrade_using_ruby(new) - elseif s:py2 - call s:upgrade_using_python(new) + 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 - return s:err('Missing: curl executable, ruby support or python support') + 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 - catch - return s:err('Error upgrading vim-plug: '. v:exception) + finally + silent! call s:rm_rf(tmp) endtry - - if readfile(s:me) ==# readfile(new) - echo 'vim-plug is already up-to-date' - silent! call delete(new) - 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 -endfunction - -function! s:upgrade_using_ruby(new) - ruby << EOF - require 'open-uri' - File.open(VIM::evaluate('a:new'), 'w') do |f| - f << open(VIM::evaluate('s:plug_src')).read - end -EOF -endfunction - -function! s:upgrade_using_python(new) -python << EOF -import urllib -import vim -psrc, dest = vim.eval('s:plug_src'), vim.eval('a:new') -urllib.urlretrieve(psrc, dest) -EOF endfunction function! s:upgrade_specs() @@ -1905,9 +1920,11 @@ function! s:preview_commit() execute 'pedit' sha wincmd P - setlocal filetype=git buftype=nofile nobuflisted - execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show' sha + 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 diff --git a/vimrc b/vimrc @@ -16,7 +16,7 @@ Plug 'chriskempson/vim-tomorrow-theme' " Navigation if hostname() != "pi" Plug 'Lokaltog/vim-easymotion' -Plug 'bling/vim-airline' +" Plug 'bling/vim-airline' Plug 'majutsushi/tagbar' endif Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': 'yes \| ./install' } @@ -42,7 +42,7 @@ endif Plug 'plasticboy/vim-markdown' Plug 'moll/vim-node', { 'for': 'javascript' } Plug 'Shougo/neocomplete.vim' -Plug 'honza/vim-snippets' +" Plug 'honza/vim-snippets' Plug 'cakebaker/scss-syntax.vim', { 'for': 'scss' } call plug#end() diff --git a/xinitrc b/xinitrc @@ -25,11 +25,15 @@ xrandr --dpi 96 & setxkbmap de & # hide cursor -# unclutter -noevents -root -visible -jitter 10 -idle 5 & +unclutter -noevents -root -visible -jitter 10 -idle 5 & # statusbar -# repos/go-dwmstatus/go-dwmstatus & +repos/go-dwmstatus/go-dwmstatus & # runsvdir ~/service/x/after/* -exec runsvdir ~/service.x +# exec runsvdir ~/service.x +# exec dwm +while dwm; do + sleep 1; +done