From e279a570ca4409b958175850992bd0de6ef77a23 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 25 Feb 2021 15:24:33 +0100 Subject: [PATCH] Remove dracula themes --- .config/qutebrowser/config.py | 9 - .config/qutebrowser/dracula/.gitignore | 2 - .config/qutebrowser/dracula/__init__.py | 0 .config/qutebrowser/dracula/draw.py | 291 ---------- .config/vim/vimrc | 6 +- .config/zsh/.zshrc | 2 - .config/zsh/custom/themes/dracula.zsh-theme | 176 ------ .config/zsh/custom/themes/lib/async.zsh | 574 -------------------- 8 files changed, 1 insertion(+), 1059 deletions(-) delete mode 100644 .config/qutebrowser/dracula/.gitignore delete mode 100644 .config/qutebrowser/dracula/__init__.py delete mode 100644 .config/qutebrowser/dracula/draw.py delete mode 100644 .config/zsh/custom/themes/dracula.zsh-theme delete mode 100644 .config/zsh/custom/themes/lib/async.zsh diff --git a/.config/qutebrowser/config.py b/.config/qutebrowser/config.py index 758b537..0cc6c8e 100644 --- a/.config/qutebrowser/config.py +++ b/.config/qutebrowser/config.py @@ -44,12 +44,3 @@ config.bind('', 'tab-focus 9') config.bind('', 'tab-next') config.bind('', 'tab-prev') - -import dracula.draw - -dracula.draw.blood(c, { - 'spacing': { - 'vertical': 1, - 'horizontal': 1 - } -}) diff --git a/.config/qutebrowser/dracula/.gitignore b/.config/qutebrowser/dracula/.gitignore deleted file mode 100644 index 4949fe8..0000000 --- a/.config/qutebrowser/dracula/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bookmarks/ -quickmarks diff --git a/.config/qutebrowser/dracula/__init__.py b/.config/qutebrowser/dracula/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/.config/qutebrowser/dracula/draw.py b/.config/qutebrowser/dracula/draw.py deleted file mode 100644 index a1079a0..0000000 --- a/.config/qutebrowser/dracula/draw.py +++ /dev/null @@ -1,291 +0,0 @@ -def blood(c, options = {}): - palette = { - 'background': '#282a36', - 'background-alt': '#282a36', - 'background-attention': '#181920', - 'border': '#282a36', - 'current-line': '#44475a', - 'selection': '#44475a', - 'foreground': '#f8f8f2', - 'foreground-alt': '#e0e0e0', - 'foreground-attention': '#ffffff', - 'comment': '#6272a4', - 'cyan': '#8be9fd', - 'green': '#50fa7b', - 'orange': '#ffb86c', - 'pink': '#ff79c6', - 'purple': '#bd93f9', - 'red': '#ff5555', - 'yellow': '#f1fa8c' - } - - spacing = options.get('spacing', { - 'vertical': 5, - 'horizontal': 5 - }) - - padding = options.get('padding', { - 'top': spacing['vertical'], - 'right': spacing['horizontal'], - 'bottom': spacing['vertical'], - 'left': spacing['horizontal'] - }) - - ## Background color of the completion widget category headers. - c.colors.completion.category.bg = palette['background'] - - ## Bottom border color of the completion widget category headers. - c.colors.completion.category.border.bottom = palette['border'] - - ## Top border color of the completion widget category headers. - c.colors.completion.category.border.top = palette['border'] - - ## Foreground color of completion widget category headers. - c.colors.completion.category.fg = palette['foreground'] - - ## Background color of the completion widget for even rows. - c.colors.completion.even.bg = palette['background'] - - ## Background color of the completion widget for odd rows. - c.colors.completion.odd.bg = palette['background-alt'] - - ## Text color of the completion widget. - c.colors.completion.fg = palette['foreground'] - - ## Background color of the selected completion item. - c.colors.completion.item.selected.bg = palette['selection'] - - ## Bottom border color of the selected completion item. - c.colors.completion.item.selected.border.bottom = palette['selection'] - - ## Top border color of the completion widget category headers. - c.colors.completion.item.selected.border.top = palette['selection'] - - ## Foreground color of the selected completion item. - c.colors.completion.item.selected.fg = palette['foreground'] - - ## Foreground color of the matched text in the completion. - c.colors.completion.match.fg = palette['orange'] - - ## Color of the scrollbar in completion view - c.colors.completion.scrollbar.bg = palette['background'] - - ## Color of the scrollbar handle in completion view. - c.colors.completion.scrollbar.fg = palette['foreground'] - - ## Background color for the download bar. - c.colors.downloads.bar.bg = palette['background'] - - ## Background color for downloads with errors. - c.colors.downloads.error.bg = palette['background'] - - ## Foreground color for downloads with errors. - c.colors.downloads.error.fg = palette['red'] - - ## Color gradient stop for download backgrounds. - c.colors.downloads.stop.bg = palette['background'] - - ## Color gradient interpolation system for download backgrounds. - ## Type: ColorSystem - ## Valid values: - ## - rgb: Interpolate in the RGB color system. - ## - hsv: Interpolate in the HSV color system. - ## - hsl: Interpolate in the HSL color system. - ## - none: Don't show a gradient. - c.colors.downloads.system.bg = 'none' - - ## Background color for hints. Note that you can use a `rgba(...)` value - ## for transparency. - c.colors.hints.bg = palette['background'] - - ## Font color for hints. - c.colors.hints.fg = palette['purple'] - - ## Hints - c.hints.border = '1px solid ' + palette['background-alt'] - - ## Font color for the matched part of hints. - c.colors.hints.match.fg = palette['foreground-alt'] - - ## Background color of the keyhint widget. - c.colors.keyhint.bg = palette['background'] - - ## Text color for the keyhint widget. - c.colors.keyhint.fg = palette['purple'] - - ## Highlight color for keys to complete the current keychain. - c.colors.keyhint.suffix.fg = palette['selection'] - - ## Background color of an error message. - c.colors.messages.error.bg = palette['background'] - - ## Border color of an error message. - c.colors.messages.error.border = palette['background-alt'] - - ## Foreground color of an error message. - c.colors.messages.error.fg = palette['red'] - - ## Background color of an info message. - c.colors.messages.info.bg = palette['background'] - - ## Border color of an info message. - c.colors.messages.info.border = palette['background-alt'] - - ## Foreground color an info message. - c.colors.messages.info.fg = palette['comment'] - - ## Background color of a warning message. - c.colors.messages.warning.bg = palette['background'] - - ## Border color of a warning message. - c.colors.messages.warning.border = palette['background-alt'] - - ## Foreground color a warning message. - c.colors.messages.warning.fg = palette['red'] - - ## Background color for prompts. - c.colors.prompts.bg = palette['background'] - - # ## Border used around UI elements in prompts. - c.colors.prompts.border = '1px solid ' + palette['background-alt'] - - ## Foreground color for prompts. - c.colors.prompts.fg = palette['cyan'] - - ## Background color for the selected item in filename prompts. - c.colors.prompts.selected.bg = palette['selection'] - - ## Background color of the statusbar in caret mode. - c.colors.statusbar.caret.bg = palette['background'] - - ## Foreground color of the statusbar in caret mode. - c.colors.statusbar.caret.fg = palette['orange'] - - ## Background color of the statusbar in caret mode with a selection. - c.colors.statusbar.caret.selection.bg = palette['background'] - - ## Foreground color of the statusbar in caret mode with a selection. - c.colors.statusbar.caret.selection.fg = palette['orange'] - - ## Background color of the statusbar in command mode. - c.colors.statusbar.command.bg = palette['background'] - - ## Foreground color of the statusbar in command mode. - c.colors.statusbar.command.fg = palette['pink'] - - ## Background color of the statusbar in private browsing + command mode. - c.colors.statusbar.command.private.bg = palette['background'] - - ## Foreground color of the statusbar in private browsing + command mode. - c.colors.statusbar.command.private.fg = palette['foreground-alt'] - - ## Background color of the statusbar in insert mode. - c.colors.statusbar.insert.bg = palette['background-attention'] - - ## Foreground color of the statusbar in insert mode. - c.colors.statusbar.insert.fg = palette['foreground-attention'] - - ## Background color of the statusbar. - c.colors.statusbar.normal.bg = palette['background'] - - ## Foreground color of the statusbar. - c.colors.statusbar.normal.fg = palette['foreground'] - - ## Background color of the statusbar in passthrough mode. - c.colors.statusbar.passthrough.bg = palette['background'] - - ## Foreground color of the statusbar in passthrough mode. - c.colors.statusbar.passthrough.fg = palette['orange'] - - ## Background color of the statusbar in private browsing mode. - c.colors.statusbar.private.bg = palette['background-alt'] - - ## Foreground color of the statusbar in private browsing mode. - c.colors.statusbar.private.fg = palette['foreground-alt'] - - ## Background color of the progress bar. - c.colors.statusbar.progress.bg = palette['background'] - - ## Foreground color of the URL in the statusbar on error. - c.colors.statusbar.url.error.fg = palette['red'] - - ## Default foreground color of the URL in the statusbar. - c.colors.statusbar.url.fg = palette['foreground'] - - ## Foreground color of the URL in the statusbar for hovered links. - c.colors.statusbar.url.hover.fg = palette['cyan'] - - ## Foreground color of the URL in the statusbar on successful load - c.colors.statusbar.url.success.http.fg = palette['green'] - - ## Foreground color of the URL in the statusbar on successful load - c.colors.statusbar.url.success.https.fg = palette['green'] - - ## Foreground color of the URL in the statusbar when there's a warning. - c.colors.statusbar.url.warn.fg = palette['yellow'] - - ## Status bar padding - c.statusbar.padding = padding - - ## Background color of the tab bar. - ## Type: QtColor - c.colors.tabs.bar.bg = palette['selection'] - - ## Background color of unselected even tabs. - ## Type: QtColor - c.colors.tabs.even.bg = palette['selection'] - - ## Foreground color of unselected even tabs. - ## Type: QtColor - c.colors.tabs.even.fg = palette['foreground'] - - ## Color for the tab indicator on errors. - ## Type: QtColor - c.colors.tabs.indicator.error = palette['red'] - - ## Color gradient start for the tab indicator. - ## Type: QtColor - c.colors.tabs.indicator.start = palette['orange'] - - ## Color gradient end for the tab indicator. - ## Type: QtColor - c.colors.tabs.indicator.stop = palette['green'] - - ## Color gradient interpolation system for the tab indicator. - ## Type: ColorSystem - ## Valid values: - ## - rgb: Interpolate in the RGB color system. - ## - hsv: Interpolate in the HSV color system. - ## - hsl: Interpolate in the HSL color system. - ## - none: Don't show a gradient. - c.colors.tabs.indicator.system = 'none' - - ## Background color of unselected odd tabs. - ## Type: QtColor - c.colors.tabs.odd.bg = palette['selection'] - - ## Foreground color of unselected odd tabs. - ## Type: QtColor - c.colors.tabs.odd.fg = palette['foreground'] - - # ## Background color of selected even tabs. - # ## Type: QtColor - c.colors.tabs.selected.even.bg = palette['background'] - - # ## Foreground color of selected even tabs. - # ## Type: QtColor - c.colors.tabs.selected.even.fg = palette['foreground'] - - # ## Background color of selected odd tabs. - # ## Type: QtColor - c.colors.tabs.selected.odd.bg = palette['background'] - - # ## Foreground color of selected odd tabs. - # ## Type: QtColor - c.colors.tabs.selected.odd.fg = palette['foreground'] - - ## Tab padding - c.tabs.padding = padding - c.tabs.indicator.width = 1 - c.tabs.favicons.scale = 1 - diff --git a/.config/vim/vimrc b/.config/vim/vimrc index bf2094d..17f6e4f 100644 --- a/.config/vim/vimrc +++ b/.config/vim/vimrc @@ -24,7 +24,6 @@ call plug#begin('~/.config/vim/plugged') Plug 'nanotech/jellybeans.vim' Plug 'scrooloose/syntastic' Plug 'Yggdroot/indentLine' - Plug 'dracula/vim', { 'as': 'dracula' } " Commands Plug 'machakann/vim-swap' @@ -148,10 +147,7 @@ let g:jellybeans_overrides = { \ '256ctermbg': 'none' \ }, \ } -" colorscheme jellybeans - -let g:dracula_colorterm = 0 -colorscheme dracula + colorscheme jellybeans let g:syntastic_always_populate_loc_list = 0 let g:syntastic_auto_loc_list = 0 diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc index b62727b..147ec78 100644 --- a/.config/zsh/.zshrc +++ b/.config/zsh/.zshrc @@ -12,8 +12,6 @@ fi # to know which specific one was loaded, run: echo $RANDOM_THEME # See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes ZSH_THEME="tjkirch" -DRACULA_DISPLAY_TIME=1 -DRACULA_DISPLAY_CONTEXT=1 # Set list of themes to pick from when loading at random # Setting this variable when ZSH_THEME=random will cause zsh to load diff --git a/.config/zsh/custom/themes/dracula.zsh-theme b/.config/zsh/custom/themes/dracula.zsh-theme deleted file mode 100644 index c04d7a4..0000000 --- a/.config/zsh/custom/themes/dracula.zsh-theme +++ /dev/null @@ -1,176 +0,0 @@ -# -*- mode: sh; -*- -# Dracula Theme v1.2.5 -# -# https://github.com/dracula/dracula-theme -# -# Copyright 2019, All rights reserved -# -# Code licensed under the MIT license -# http://zenorocha.mit-license.org -# -# @author Zeno Rocha -# @maintainer Aidan Williams - -# Initialization {{{ -source ${0:A:h}/lib/async.zsh -autoload -Uz add-zsh-hook -setopt PROMPT_SUBST -async_init -# }}} - -# Options {{{ -# Set to 1 to show the date -DRACULA_DISPLAY_TIME=${DRACULA_DISPLAY_TIME:-0} - -# Set to 1 to show the 'context' segment -DRACULA_DISPLAY_CONTEXT=${DRACULA_DISPLAY_CONTEXT:-0} - -# Changes the arrow icon -DRACULA_ARROW_ICON=${DRACULA_ARROW_ICON:-➜} - -# function to detect if git has support for --no-optional-locks -dracula_test_git_optional_lock() { - local git_version=${DEBUG_OVERRIDE_V:-"$(git version | cut -d' ' -f3)"} - local git_version="$(git version | cut -d' ' -f3)" - # test for git versions < 2.14.0 - case "$git_version" in - [0-1].*) - echo 0 - return 1 - ;; - 2.[0-9].*) - echo 0 - return 1 - ;; - 2.1[0-3].*) - echo 0 - return 1 - ;; - esac - - # if version > 2.14.0 return true - echo 1 -} - -# use --no-optional-locks flag on git -DRACULA_GIT_NOLOCK=${DRACULA_GIT_NOLOCK:-$(dracula_test_git_optional_lock)} -# }}} - -# Status segment {{{ -# arrow is green if last command was successful, red if not, -# turns yellow in vi command mode -PROMPT='%(1V:%F{yellow}:%(?:%F{green}:%F{red}))${DRACULA_ARROW_ICON}' -# }}} - -# Time segment {{{ -dracula_time_segment() { - if (( DRACULA_DISPLAY_TIME )); then - if [[ -z "$TIME_FORMAT" ]]; then - TIME_FORMAT=" %-H:%M" - - # check if locale uses AM and PM - if ! locale -ck LC_TIME | grep 'am_pm=";"' > /dev/null; then - TIME_FORMAT=" %-I:%M%p" - fi - fi - - print -P "%D{$TIME_FORMAT}" - fi -} - -PROMPT+='%F{green}%B$(dracula_time_segment) ' -# }}} - -# User context segment {{{ -dracula_context() { - if (( DRACULA_DISPLAY_CONTEXT )); then - if [[ -n "${SSH_CONNECTION-}${SSH_CLIENT-}${SSH_TTY-}" ]] || (( EUID == 0 )); then - echo '%n@%m ' - else - echo '%n ' - fi - fi -} - -PROMPT+='%F{magenta}%B$(dracula_context)' -# }}} - -# Directory segment {{{ -PROMPT+='%F{blue}%B%c ' -# }}} - -# Async git segment {{{ - -dracula_git_status() { - cd "$1" - - local ref branch lockflag - - (( DRACULA_GIT_NOLOCK )) && lockflag="--no-optional-locks" - - ref=$(=git $lockflag symbolic-ref --quiet HEAD 2>/tmp/git-errors) - - case $? in - 0) ;; - 128) return ;; - *) ref=$(=git $lockflag rev-parse --short HEAD 2>/tmp/git-errors) || return ;; - esac - - branch=${ref#refs/heads/} - - if [[ -n $branch ]]; then - echo -n "${ZSH_THEME_GIT_PROMPT_PREFIX}${branch}" - - local git_status icon - git_status="$(LC_ALL=C =git $lockflag status 2>&1)" - - if [[ "$git_status" =~ 'new file:|deleted:|modified:|renamed:|Untracked files:' ]]; then - echo -n "$ZSH_THEME_GIT_PROMPT_DIRTY" - else - echo -n "$ZSH_THEME_GIT_PROMPT_CLEAN" - fi - - echo -n "$ZSH_THEME_GIT_PROMPT_SUFFIX" - fi -} - -dracula_git_callback() { - DRACULA_GIT_STATUS="$3" - zle && zle reset-prompt - async_stop_worker dracula_git_worker dracula_git_status "$(pwd)" -} - -dracula_git_async() { - async_start_worker dracula_git_worker -n - async_register_callback dracula_git_worker dracula_git_callback - async_job dracula_git_worker dracula_git_status "$(pwd)" -} - -add-zsh-hook precmd dracula_git_async - -PROMPT+='$DRACULA_GIT_STATUS' - -ZSH_THEME_GIT_PROMPT_CLEAN=") %F{green}%B✔ " -ZSH_THEME_GIT_PROMPT_DIRTY=") %F{yellow}%B✗ " -ZSH_THEME_GIT_PROMPT_PREFIX="%F{cyan}%B(" -ZSH_THEME_GIT_PROMPT_SUFFIX="%f%b" -# }}} - -# ensure vi mode is handled by prompt -function zle-keymap-select zle-line-init { - if [[ $KEYMAP = vicmd ]]; then - psvar[1]=vicmd - else - psvar[1]='' - fi - - zle reset-prompt - zle -R -} - -zle -N zle-line-init -zle -N zle-keymap-select - -# Ensure effects are reset -PROMPT+='%f%b' - diff --git a/.config/zsh/custom/themes/lib/async.zsh b/.config/zsh/custom/themes/lib/async.zsh deleted file mode 100644 index d0f3f00..0000000 --- a/.config/zsh/custom/themes/lib/async.zsh +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env zsh - -# -# zsh-async -# -# version: 1.7.2 -# author: Mathias Fredriksson -# url: https://github.com/mafredri/zsh-async -# - -typeset -g ASYNC_VERSION=1.7.2 -# Produce debug output from zsh-async when set to 1. -typeset -g ASYNC_DEBUG=${ASYNC_DEBUG:-0} - -# Execute commands that can manipulate the environment inside the async worker. Return output via callback. -_async_eval() { - local ASYNC_JOB_NAME - # Rename job to _async_eval and redirect all eval output to cat running - # in _async_job. Here, stdout and stderr are not separated for - # simplicity, this could be improved in the future. - { - eval "$@" - } &> >(ASYNC_JOB_NAME=[async/eval] _async_job 'cat') -} - -# Wrapper for jobs executed by the async worker, gives output in parseable format with execution time -_async_job() { - # Disable xtrace as it would mangle the output. - setopt localoptions noxtrace - - # Store start time for job. - float -F duration=$EPOCHREALTIME - - # Run the command and capture both stdout (`eval`) and stderr (`cat`) in - # separate subshells. When the command is complete, we grab write lock - # (mutex token) and output everything except stderr inside the command - # block, after the command block has completed, the stdin for `cat` is - # closed, causing stderr to be appended with a $'\0' at the end to mark the - # end of output from this job. - local jobname=${ASYNC_JOB_NAME:-$1} - local stdout stderr ret tok - { - stdout=$(eval "$@") - ret=$? - duration=$(( EPOCHREALTIME - duration )) # Calculate duration. - - # Grab mutex lock, stalls until token is available. - read -r -k 1 -p tok || exit 1 - - # Return output ( ). - print -r -n - $'\0'${(q)jobname} $ret ${(q)stdout} $duration - } 2> >(stderr=$(cat) && print -r -n - " "${(q)stderr}$'\0') - - # Unlock mutex by inserting a token. - print -n -p $tok -} - -# The background worker manages all tasks and runs them without interfering with other processes -_async_worker() { - # Reset all options to defaults inside async worker. - emulate -R zsh - - # Make sure monitor is unset to avoid printing the - # pids of child processes. - unsetopt monitor - - # Redirect stderr to `/dev/null` in case unforseen errors produced by the - # worker. For example: `fork failed: resource temporarily unavailable`. - # Some older versions of zsh might also print malloc errors (know to happen - # on at least zsh 5.0.2 and 5.0.8) likely due to kill signals. - exec 2>/dev/null - - # When a zpty is deleted (using -d) all the zpty instances created before - # the one being deleted receive a SIGHUP, unless we catch it, the async - # worker would simply exit (stop working) even though visible in the list - # of zpty's (zpty -L). - TRAPHUP() { - return 0 # Return 0, indicating signal was handled. - } - - local -A storage - local unique=0 - local notify_parent=0 - local parent_pid=0 - local coproc_pid=0 - local processing=0 - - local -a zsh_hooks zsh_hook_functions - zsh_hooks=(chpwd periodic precmd preexec zshexit zshaddhistory) - zsh_hook_functions=(${^zsh_hooks}_functions) - unfunction $zsh_hooks &>/dev/null # Deactivate all zsh hooks inside the worker. - unset $zsh_hook_functions # And hooks with registered functions. - unset zsh_hooks zsh_hook_functions # Cleanup. - - close_idle_coproc() { - local -a pids - pids=(${${(v)jobstates##*:*:}%\=*}) - - # If coproc (cat) is the only child running, we close it to avoid - # leaving it running indefinitely and cluttering the process tree. - if (( ! processing )) && [[ $#pids = 1 ]] && [[ $coproc_pid = $pids[1] ]]; then - coproc : - coproc_pid=0 - fi - } - - child_exit() { - close_idle_coproc - - # On older version of zsh (pre 5.2) we notify the parent through a - # SIGWINCH signal because `zpty` did not return a file descriptor (fd) - # prior to that. - if (( notify_parent )); then - # We use SIGWINCH for compatibility with older versions of zsh - # (pre 5.1.1) where other signals (INFO, ALRM, USR1, etc.) could - # cause a deadlock in the shell under certain circumstances. - kill -WINCH $parent_pid - fi - } - - # Register a SIGCHLD trap to handle the completion of child processes. - trap child_exit CHLD - - # Process option parameters passed to worker - while getopts "np:u" opt; do - case $opt in - n) notify_parent=1;; - p) parent_pid=$OPTARG;; - u) unique=1;; - esac - done - - killjobs() { - local tok - local -a pids - pids=(${${(v)jobstates##*:*:}%\=*}) - - # No need to send SIGHUP if no jobs are running. - (( $#pids == 0 )) && continue - (( $#pids == 1 )) && [[ $coproc_pid = $pids[1] ]] && continue - - # Grab lock to prevent half-written output in case a child - # process is in the middle of writing to stdin during kill. - (( coproc_pid )) && read -r -k 1 -p tok - - kill -HUP -$$ # Send to entire process group. - coproc : # Quit coproc. - coproc_pid=0 # Reset pid. - } - - local request do_eval=0 - local -a cmd - while :; do - # Wait for jobs sent by async_job. - read -r -d $'\0' request || { - # Since we handle SIGHUP above (and thus do not know when `zpty -d`) - # occurs, a failure to read probably indicates that stdin has - # closed. This is why we propagate the signal to all children and - # exit manually. - kill -HUP -$$ # Send SIGHUP to all jobs. - exit 0 - } - - # Check for non-job commands sent to worker - case $request in - _unset_trap) notify_parent=0; continue;; - _killjobs) killjobs; continue;; - _async_eval*) do_eval=1;; - esac - - # Parse the request using shell parsing (z) to allow commands - # to be parsed from single strings and multi-args alike. - cmd=("${(z)request}") - - # Name of the job (first argument). - local job=$cmd[1] - - # If worker should perform unique jobs - if (( unique )); then - # Check if a previous job is still running, if yes, let it finnish - for pid in ${${(v)jobstates##*:*:}%\=*}; do - if [[ ${storage[$job]} == $pid ]]; then - continue 2 - fi - done - fi - - # Guard against closing coproc from trap before command has started. - processing=1 - - # Because we close the coproc after the last job has completed, we must - # recreate it when there are no other jobs running. - if (( ! coproc_pid )); then - # Use coproc as a mutex for synchronized output between children. - coproc cat - coproc_pid="$!" - # Insert token into coproc - print -n -p "t" - fi - - if (( do_eval )); then - shift cmd # Strip _async_eval from cmd. - _async_eval $cmd - else - # Run job in background, completed jobs are printed to stdout. - _async_job $cmd & - # Store pid because zsh job manager is extremely unflexible (show jobname as non-unique '$job')... - storage[$job]="$!" - fi - - processing=0 # Disable guard. - - if (( do_eval )); then - do_eval=0 - - # When there are no active jobs we can't rely on the CHLD trap to - # manage the coproc lifetime. - close_idle_coproc - fi - done -} - -# -# Get results from finished jobs and pass it to the to callback function. This is the only way to reliably return the -# job name, return code, output and execution time and with minimal effort. -# -# If the async process buffer becomes corrupt, the callback will be invoked with the first argument being `[async]` (job -# name), non-zero return code and fifth argument describing the error (stderr). -# -# usage: -# async_process_results -# -# callback_function is called with the following parameters: -# $1 = job name, e.g. the function passed to async_job -# $2 = return code -# $3 = resulting stdout from execution -# $4 = execution time, floating point e.g. 2.05 seconds -# $5 = resulting stderr from execution -# $6 = has next result in buffer (0 = buffer empty, 1 = yes) -# -async_process_results() { - setopt localoptions unset noshwordsplit noksharrays noposixidentifiers noposixstrings - - local worker=$1 - local callback=$2 - local caller=$3 - local -a items - local null=$'\0' data - integer -l len pos num_processed has_next - - typeset -gA ASYNC_PROCESS_BUFFER - - # Read output from zpty and parse it if available. - while zpty -r -t $worker data 2>/dev/null; do - ASYNC_PROCESS_BUFFER[$worker]+=$data - len=${#ASYNC_PROCESS_BUFFER[$worker]} - pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). - - # Keep going until we find a NULL-character. - if (( ! len )) || (( pos > len )); then - continue - fi - - while (( pos <= len )); do - # Take the content from the beginning, until the NULL-character and - # perform shell parsing (z) and unquoting (Q) as an array (@). - items=("${(@Q)${(z)ASYNC_PROCESS_BUFFER[$worker][1,$pos-1]}}") - - # Remove the extracted items from the buffer. - ASYNC_PROCESS_BUFFER[$worker]=${ASYNC_PROCESS_BUFFER[$worker][$pos+1,$len]} - - len=${#ASYNC_PROCESS_BUFFER[$worker]} - if (( len > 1 )); then - pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). - fi - - has_next=$(( len != 0 )) - if (( $#items == 5 )); then - items+=($has_next) - $callback "${(@)items}" # Send all parsed items to the callback. - (( num_processed++ )) - elif [[ -z $items ]]; then - # Empty items occur between results due to double-null ($'\0\0') - # caused by commands being both pre and suffixed with null. - else - # In case of corrupt data, invoke callback with *async* as job - # name, non-zero exit status and an error message on stderr. - $callback "[async]" 1 "" 0 "$0:$LINENO: error: bad format, got ${#items} items (${(q)items})" $has_next - fi - done - done - - (( num_processed )) && return 0 - - # Avoid printing exit value when `setopt printexitvalue` is active.` - [[ $caller = trap || $caller = watcher ]] && return 0 - - # No results were processed - return 1 -} - -# Watch worker for output -_async_zle_watcher() { - setopt localoptions noshwordsplit - typeset -gA ASYNC_PTYS ASYNC_CALLBACKS - local worker=$ASYNC_PTYS[$1] - local callback=$ASYNC_CALLBACKS[$worker] - - if [[ -n $2 ]]; then - # from man zshzle(1): - # `hup' for a disconnect, `nval' for a closed or otherwise - # invalid descriptor, or `err' for any other condition. - # Systems that support only the `select' system call always use - # `err'. - - # this has the side effect to unregister the broken file descriptor - async_stop_worker $worker - - if [[ -n $callback ]]; then - $callback '[async]' 2 "" 0 "$worker:zle -F $1 returned error $2" 0 - fi - return - fi; - - if [[ -n $callback ]]; then - async_process_results $worker $callback watcher - fi -} - -# -# Start a new asynchronous job on specified worker, assumes the worker is running. -# -# usage: -# async_job [] -# -async_job() { - setopt localoptions noshwordsplit noksharrays noposixidentifiers noposixstrings - - local worker=$1; shift - - local -a cmd - cmd=("$@") - if (( $#cmd > 1 )); then - cmd=(${(q)cmd}) # Quote special characters in multi argument commands. - fi - - # Quote the cmd in case RC_EXPAND_PARAM is set. - zpty -w $worker "$cmd"$'\0' -} - -# -# Evaluate a command (like async_job) inside the async worker, then worker environment can be manipulated. For example, -# issuing a cd command will change the PWD of the worker which will then be inherited by all future async jobs. -# -# Output will be returned via callback, job name will be [async/eval]. -# -# usage: -# async_worker_eval [] -# -async_worker_eval() { - setopt localoptions noshwordsplit noksharrays noposixidentifiers noposixstrings - - local worker=$1; shift - - local -a cmd - cmd=("$@") - if (( $#cmd > 1 )); then - cmd=(${(q)cmd}) # Quote special characters in multi argument commands. - fi - - # Quote the cmd in case RC_EXPAND_PARAM is set. - zpty -w $worker "_async_eval $cmd"$'\0' -} - -# This function traps notification signals and calls all registered callbacks -_async_notify_trap() { - setopt localoptions noshwordsplit - - local k - for k in ${(k)ASYNC_CALLBACKS}; do - async_process_results $k ${ASYNC_CALLBACKS[$k]} trap - done -} - -# -# Register a callback for completed jobs. As soon as a job is finnished, async_process_results will be called with the -# specified callback function. This requires that a worker is initialized with the -n (notify) option. -# -# usage: -# async_register_callback -# -async_register_callback() { - setopt localoptions noshwordsplit nolocaltraps - - typeset -gA ASYNC_CALLBACKS - local worker=$1; shift - - ASYNC_CALLBACKS[$worker]="$*" - - # Enable trap when the ZLE watcher is unavailable, allows - # workers to notify (via -n) when a job is done. - if [[ ! -o interactive ]] || [[ ! -o zle ]]; then - trap '_async_notify_trap' WINCH - fi -} - -# -# Unregister the callback for a specific worker. -# -# usage: -# async_unregister_callback -# -async_unregister_callback() { - typeset -gA ASYNC_CALLBACKS - - unset "ASYNC_CALLBACKS[$1]" -} - -# -# Flush all current jobs running on a worker. This will terminate any and all running processes under the worker, use -# with caution. -# -# usage: -# async_flush_jobs -# -async_flush_jobs() { - setopt localoptions noshwordsplit - - local worker=$1; shift - - # Check if the worker exists - zpty -t $worker &>/dev/null || return 1 - - # Send kill command to worker - async_job $worker "_killjobs" - - # Clear the zpty buffer. - local junk - if zpty -r -t $worker junk '*'; then - (( ASYNC_DEBUG )) && print -n "async_flush_jobs $worker: ${(V)junk}" - while zpty -r -t $worker junk '*'; do - (( ASYNC_DEBUG )) && print -n "${(V)junk}" - done - (( ASYNC_DEBUG )) && print - fi - - # Finally, clear the process buffer in case of partially parsed responses. - typeset -gA ASYNC_PROCESS_BUFFER - unset "ASYNC_PROCESS_BUFFER[$worker]" -} - -# -# Start a new async worker with optional parameters, a worker can be told to only run unique tasks and to notify a -# process when tasks are complete. -# -# usage: -# async_start_worker [-u] [-n] [-p ] -# -# opts: -# -u unique (only unique job names can run) -# -n notify through SIGWINCH signal -# -p pid to notify (defaults to current pid) -# -async_start_worker() { - setopt localoptions noshwordsplit - - local worker=$1; shift - zpty -t $worker &>/dev/null && return - - typeset -gA ASYNC_PTYS - typeset -h REPLY - typeset has_xtrace=0 - - # Make sure async worker is started without xtrace - # (the trace output interferes with the worker). - [[ -o xtrace ]] && { - has_xtrace=1 - unsetopt xtrace - } - - if (( ! ASYNC_ZPTY_RETURNS_FD )) && [[ -o interactive ]] && [[ -o zle ]]; then - # When zpty doesn't return a file descriptor (on older versions of zsh) - # we try to guess it anyway. - integer -l zptyfd - exec {zptyfd}>&1 # Open a new file descriptor (above 10). - exec {zptyfd}>&- # Close it so it's free to be used by zpty. - fi - - zpty -b $worker _async_worker -p $$ $@ || { - async_stop_worker $worker - return 1 - } - - # Re-enable it if it was enabled, for debugging. - (( has_xtrace )) && setopt xtrace - - if [[ $ZSH_VERSION < 5.0.8 ]]; then - # For ZSH versions older than 5.0.8 we delay a bit to give - # time for the worker to start before issuing commands, - # otherwise it will not be ready to receive them. - sleep 0.001 - fi - - if [[ -o interactive ]] && [[ -o zle ]]; then - if (( ! ASYNC_ZPTY_RETURNS_FD )); then - REPLY=$zptyfd # Use the guessed value for the file desciptor. - fi - - ASYNC_PTYS[$REPLY]=$worker # Map the file desciptor to the worker. - zle -F $REPLY _async_zle_watcher # Register the ZLE handler. - - # Disable trap in favor of ZLE handler when notify is enabled (-n). - async_job $worker _unset_trap - fi -} - -# -# Stop one or multiple workers that are running, all unfetched and incomplete work will be lost. -# -# usage: -# async_stop_worker [] -# -async_stop_worker() { - setopt localoptions noshwordsplit - - local ret=0 worker k v - for worker in $@; do - # Find and unregister the zle handler for the worker - for k v in ${(@kv)ASYNC_PTYS}; do - if [[ $v == $worker ]]; then - zle -F $k - unset "ASYNC_PTYS[$k]" - fi - done - async_unregister_callback $worker - zpty -d $worker 2>/dev/null || ret=$? - - # Clear any partial buffers. - typeset -gA ASYNC_PROCESS_BUFFER - unset "ASYNC_PROCESS_BUFFER[$worker]" - done - - return $ret -} - -# -# Initialize the required modules for zsh-async. To be called before using the zsh-async library. -# -# usage: -# async_init -# -async_init() { - (( ASYNC_INIT_DONE )) && return - typeset -g ASYNC_INIT_DONE=1 - - zmodload zsh/zpty - zmodload zsh/datetime - - # Check if zsh/zpty returns a file descriptor or not, - # shell must also be interactive with zle enabled. - typeset -g ASYNC_ZPTY_RETURNS_FD=0 - [[ -o interactive ]] && [[ -o zle ]] && { - typeset -h REPLY - zpty _async_test : - (( REPLY )) && ASYNC_ZPTY_RETURNS_FD=1 - zpty -d _async_test - } -} - -async() { - async_init -} - -async "$@"