diff options
67 files changed, 2870 insertions, 0 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 0000000..0fd8842 --- /dev/null +++ b/.DS_Store @@ -0,0 +1,34 @@ +Please append you name/nick here when you have contributed with something! + +Erik Westrup <erik.westrup@gmail.com> +Suvash Thapaliya <suvash@gmail.com> +Erik Jansson <erikjansson90@gmail.com> +Yuku Takahashi <taka84u9@gmail.com> +Oscar Olsson <osse.olsson@gmail.com> +Ryo Katsuma +negipo +Sina Siadat +Vivien Leroy <fantattitude@me.com> +Gino Lucero +Derek Ashley Thomas <derekathomas@gmail.com> +LuRsT +Tomokazu Hirai <tomokazu.hirai@gmail.com> +Matt Black +krieiter +Viktor Jackson +flytreeleft <flytreeleft@126.com> +Conner McDaniel +David Francos <me@davidfrancos.net> +Travis Thompson <butters08@gmail.com> +Jonathon Klobucar +Dylan Copeland <me@dylancopeland.com> +Pete Johns <paj-github@johnsy.com> +Robert Murray McMahon +Jeff Felchner +tobetoby +Matthew Lanigan +Hadret <hadret@gmail.com> +antiAgainst <antiAgainst@gmail.com> +Alexander Luberg <alex@luberg.me> +Stanislaw Pusep <stas@sysd.org> +Austin Beam @@ -0,0 +1,14 @@ +tmux-powerline - Statusbar configuration for tmux that looks like vim-powerline and consist of dynamic segments. + +Copyright (c) 2012, see AUTHORS +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +http://opensource.org/licenses/BSD-3-Clause diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac82fe1 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Setup +These are the settings that I use for tmux. +I use the code from tmux-powerline to get some cool functionality out of the status line. +I also added a few scripts in the scripts dir. +One is for listing active sessions/giving you the ability to call tmuxomatic scripts and the other script is for tmux renumbering. +All you need to do is pull this directory and symlink the tmux config to ~/.tmux.conf + +``` +git clone https://github.com/thornycrackers/.tmux.git +ln -s .tmux/tmux.config .tmux.conf +``` + +This will overwrite an existing .tmux.conf file if you have one. diff --git a/color_palette.sh b/color_palette.sh new file mode 100755 index 0000000..3762fae --- /dev/null +++ b/color_palette.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Print tmux color palette. +# Idea from http://superuser.com/questions/285381/how-does-the-tmux-color-palette-work + +for i in $(seq 0 4 255); do + for j in $(seq $i $(expr $i + 3)); do + for k in $(seq 1 $(expr 3 - ${#j})); do + printf " " + done + printf "\x1b[38;5;${j}mcolour${j}" + [[ $(expr $j % 4) != 3 ]] && printf " " + done + printf "\n" +done diff --git a/config/defaults.sh b/config/defaults.sh new file mode 100644 index 0000000..bc79496 --- /dev/null +++ b/config/defaults.sh @@ -0,0 +1,5 @@ +# Default values for non segment configuration options. + +export TMUX_POWERLINE_DEBUG_MODE_ENABLED_DEFAULT="false" +export TMUX_POWERLINE_PATCHED_FONT_IN_USE_DEFAULT="true" +export TMUX_POWERLINE_THEME_DEFAULT="default" diff --git a/config/helpers.sh b/config/helpers.sh new file mode 100644 index 0000000..caba053 --- /dev/null +++ b/config/helpers.sh @@ -0,0 +1,9 @@ +# Other settings and helper functions. + +debug_mode_enabled() { + [ -n "$TMUX_POWERLINE_DEBUG_MODE_ENABLED" -a "$TMUX_POWERLINE_DEBUG_MODE_ENABLED" != "false" ]; +} + +patched_font_in_use() { + [ -z "$TMUX_POWERLINE_PATCHED_FONT_IN_USE" -o "$TMUX_POWERLINE_PATCHED_FONT_IN_USE" != "false" ]; +} diff --git a/config/paths.sh b/config/paths.sh new file mode 100644 index 0000000..bf72be3 --- /dev/null +++ b/config/paths.sh @@ -0,0 +1,12 @@ +# Paths + +export TMUX_POWERLINE_DIR_LIB="$TMUX_POWERLINE_DIR_HOME/lib" +export TMUX_POWERLINE_DIR_SEGMENTS="$TMUX_POWERLINE_DIR_HOME/segments" +export TMUX_POWERLINE_DIR_TEMPORARY="/tmp/tmux-powerline_${USER}" +export TMUX_POWERLINE_DIR_THEMES="$TMUX_POWERLINE_DIR_HOME/themes" +export TMUX_POWERLINE_RCFILE="$HOME/.tmux-powerlinerc" +export TMUX_POWERLINE_RCFILE_DEFAULT="$HOME/.tmux-powerlinerc.default" + +if [ ! -d "$TMUX_POWERLINE_DIR_TEMPORARY" ]; then + mkdir "$TMUX_POWERLINE_DIR_TEMPORARY" +fi diff --git a/config/shell.sh b/config/shell.sh new file mode 100644 index 0000000..d24bcf8 --- /dev/null +++ b/config/shell.sh @@ -0,0 +1,20 @@ +# Shell Configuration +# vi: sw=8 ts=8 noet + +ostype() { echo $OSTYPE | tr '[A-Z]' '[a-z]'; } + +export SHELL_PLATFORM='unknown' + +case "$(ostype)" in + *'linux'* ) SHELL_PLATFORM='linux' ;; + *'darwin'* ) SHELL_PLATFORM='osx' ;; + *'bsd'* ) SHELL_PLATFORM='bsd' ;; +esac + +shell_is_linux() { [[ $SHELL_PLATFORM == 'linux' || $SHELL_PLATFORM == 'bsd' ]]; } +shell_is_osx() { [[ $SHELL_PLATFORM == 'osx' ]]; } +shell_is_bsd() { [[ $SHELL_PLATFORM == 'bsd' || $SHELL_PLATFORM == 'osx' ]]; } + +export -f shell_is_linux +export -f shell_is_osx +export -f shell_is_bsd diff --git a/generate_rc.sh b/generate_rc.sh new file mode 100755 index 0000000..33e16b7 --- /dev/null +++ b/generate_rc.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Generate default rc file. + +export TMUX_POWERLINE_DIR_HOME="$(dirname $0)" +source "${TMUX_POWERLINE_DIR_HOME}/config/paths.sh" +source "${TMUX_POWERLINE_DIR_HOME}/config/defaults.sh" +source "${TMUX_POWERLINE_DIR_LIB}/rcfile.sh" + +generate_default_rc + +exit 0 diff --git a/img/full.png b/img/full.png Binary files differnew file mode 100644 index 0000000..8f6a0ec --- /dev/null +++ b/img/full.png diff --git a/img/left-status.png b/img/left-status.png Binary files differnew file mode 100644 index 0000000..bed57a9 --- /dev/null +++ b/img/left-status.png diff --git a/img/right-status.png b/img/right-status.png Binary files differnew file mode 100644 index 0000000..c20b31d --- /dev/null +++ b/img/right-status.png diff --git a/img/right-status_no_mail.png b/img/right-status_no_mail.png Binary files differnew file mode 100644 index 0000000..4da8e53 --- /dev/null +++ b/img/right-status_no_mail.png diff --git a/img/right-status_no_mpd.png b/img/right-status_no_mpd.png Binary files differnew file mode 100644 index 0000000..7ca067e --- /dev/null +++ b/img/right-status_no_mpd.png diff --git a/img/right-status_weather_battery.png b/img/right-status_weather_battery.png Binary files differnew file mode 100644 index 0000000..77442d8 --- /dev/null +++ b/img/right-status_weather_battery.png diff --git a/lib/arg_processing.sh b/lib/arg_processing.sh new file mode 100644 index 0000000..d8fb92c --- /dev/null +++ b/lib/arg_processing.sh @@ -0,0 +1,9 @@ +#! Check script arguments. + +check_arg_side() { + local side="$1" + if ! [ "$side" == "left" -o "$side" == "right" ]; then + echo "Argument must be must be the side to handle {left, right} and not \"${side}\"." + exit 1 + fi +} diff --git a/lib/formatting.sh b/lib/formatting.sh new file mode 100644 index 0000000..d891863 --- /dev/null +++ b/lib/formatting.sh @@ -0,0 +1,5 @@ +__print_colored_content() { + echo -n "#[fg=colour$3, bg=colour$2]" + echo -n "$1" + echo -n "#[default]" +} diff --git a/lib/muting.sh b/lib/muting.sh new file mode 100644 index 0000000..595ba87 --- /dev/null +++ b/lib/muting.sh @@ -0,0 +1,20 @@ +# Muting Logic +# In all cases $1 is the side to be muted (eg left/right). + +powerline_muted() { + [ -e "$(__powerline_mute_file $1)" ]; +} + +toggle_powerline_mute_status() { + if powerline_muted $1; then + rm "$(__powerline_mute_file $1)" + else + touch "$(__powerline_mute_file $1)" + fi +} + +__powerline_mute_file() { + local tmux_session=$(tmux display -p "#S") + + echo -n "${TMUX_POWERLINE_DIR_TEMPORARY}/mute_${tmux_session}_$1" +} diff --git a/lib/powerline.sh b/lib/powerline.sh new file mode 100644 index 0000000..3a3fb68 --- /dev/null +++ b/lib/powerline.sh @@ -0,0 +1,142 @@ +# Library functions + +print_powerline() { + local side="$1" + local upper_side=$(echo "$1" | tr '[:lower:]' '[:upper:]') + eval "local input_segments=(\"\${TMUX_POWERLINE_${upper_side}_STATUS_SEGMENTS[@]}\")" + local powerline_segments=() + local powerline_segment_contents=() + + __check_platform + + __process_segment_defaults + __process_scripts + __process_colors + + __process_powerline +} + +__process_segment_defaults() { + for segment_index in "${!input_segments[@]}"; do + local input_segment=(${input_segments[$segment_index]}) + eval "local default_separator=\$TMUX_POWERLINE_DEFAULT_${upper_side}SIDE_SEPARATOR" + + powerline_segment_with_defaults=( + ${input_segment[0]:-"no_script"} \ + ${input_segment[1]:-$TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR} \ + ${input_segment[2]:-$TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR} \ + ${input_segment[3]:-$default_separator} \ + ) + + powerline_segments[$segment_index]="${powerline_segment_with_defaults[@]}" + done +} + +__process_scripts() { + for segment_index in "${!powerline_segments[@]}"; do + local powerline_segment=(${powerline_segments[$segment_index]}) + + if [ -n "$TMUX_POWERLINE_DIR_USER_SEGMENTS" ] && [ -f "$TMUX_POWERLINE_DIR_USER_SEGMENTS/${powerline_segment[0]}.sh" ] ; then + local script="$TMUX_POWERLINE_DIR_USER_SEGMENTS/${powerline_segment[0]}.sh" + else + local script="$TMUX_POWERLINE_DIR_SEGMENTS/${powerline_segment[0]}.sh" + fi + + export TMUX_POWERLINE_CUR_SEGMENT_BG="${powerline_segment[1]}" + export TMUX_POWERLINE_CUR_SEGMENT_FG="${powerline_segment[2]}" + source "$script" + local output + output=$(run_segment) + local exit_code="$?" + unset -f run_segment + + if [ "$exit_code" -ne 0 ] && debug_mode_enabled ; then + local seg_name="${script##*/}" + echo "Segment '${seg_name}' exited with code ${exit_code}. Aborting." + exit 1 + fi + + if [ -n "$output" ]; then + powerline_segment_contents[$segment_index]=" $output " + else + unset -v powerline_segments[$segment_index] + fi + done +} + +__process_colors() { + for segment_index in "${!powerline_segments[@]}"; do + local powerline_segment=(${powerline_segments[$segment_index]}) + # Find the next segment that produces content (i.e. skip empty segments). + for next_segment_index in $(eval echo {$(($segment_index + 1))..${#powerline_segments}}) ; do + [[ -n ${powerline_segments[next_segment_index]} ]] && break + done + local next_segment=(${powerline_segments[$next_segment_index]}) + + if [ $side == 'left' ]; then + powerline_segment[4]=${next_segment[1]:-$TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR} + elif [ $side == 'right' ]; then + powerline_segment[4]=${previous_background_color:-$TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR} + fi + + if __segment_separator_is_thin; then + powerline_segment[5]=${powerline_segment[2]} + else + powerline_segment[5]=${powerline_segment[1]} + fi + + local previous_background_color=${powerline_segment[1]} + + powerline_segments[$segment_index]="${powerline_segment[@]}" + done +} + +__process_powerline() { + for segment_index in "${!powerline_segments[@]}"; do + local powerline_segment=(${powerline_segments[$segment_index]}) + + local background_color=${powerline_segment[1]} + local foreground_color=${powerline_segment[2]} + local separator=${powerline_segment[3]} + local separator_background_color=${powerline_segment[4]} + local separator_foreground_color=${powerline_segment[5]} + + eval "__print_${side}_segment ${segment_index} ${background_color} ${foreground_color} ${separator} ${separator_background_color} ${separator_foreground_color}" + done +} + +__print_left_segment() { + local content=${powerline_segment_contents[$1]} + local content_background_color=$2 + local content_foreground_color=$3 + local separator=$4 + local separator_background_color=$5 + local separator_foreground_color=$6 + + __print_colored_content "$content" $content_background_color $content_foreground_color + __print_colored_content $separator $separator_background_color $separator_foreground_color +} + +__print_right_segment() { + local content=${powerline_segment_contents[$1]} + local content_background_color=$2 + local content_foreground_color=$3 + local separator=$4 + local separator_background_color=$5 + local separator_foreground_color=$6 + + __print_colored_content $separator $separator_background_color $separator_foreground_color + __print_colored_content "$content" $content_background_color $content_foreground_color +} + +__segment_separator_is_thin() { + [[ ${powerline_segment[3]} == $TMUX_POWERLINE_SEPARATOR_LEFT_THIN || \ + ${powerline_segment[3]} == $TMUX_POWERLINE_SEPARATOR_RIGHT_THIN ]]; +} + +__check_platform() { + if [ "$SHELL_PLATFORM" == "unknown" ] && debug_mode_enabled; then + echo "Unknown platform; modify config/shell.sh" &1>&2 + fi +} + diff --git a/lib/rcfile.sh b/lib/rcfile.sh new file mode 100644 index 0000000..db88198 --- /dev/null +++ b/lib/rcfile.sh @@ -0,0 +1,68 @@ +# Read user rc file. + +process_settings() { + __read_rcfile + + if [ -z "$TMUX_POWERLINE_DEBUG_MODE_ENABLED" ]; then + export TMUX_POWERLINE_DEBUG_MODE_ENABLED="${TMUX_POWERLINE_DEBUG_MODE_ENABLED_DEFAULT}" + fi + + if [ -z "$TMUX_POWERLINE_PATCHED_FONT_IN_USE" ]; then + export TMUX_POWERLINE_PATCHED_FONT_IN_USE="${TMUX_POWERLINE_PATCHED_FONT_IN_USE_DEFAULT}" + fi + + if [ -z "$TMUX_POWERLINE_THEME" ]; then + export TMUX_POWERLINE_THEME="${TMUX_POWERLINE_THEME_DEFAULT}" + fi + + eval TMUX_POWERLINE_DIR_USER_SEGMENTS="$TMUX_POWERLINE_DIR_USER_SEGMENTS" + eval TMUX_POWERLINE_DIR_USER_THEMES="$TMUX_POWERLINE_DIR_USER_THEMES" + if [ -n "$TMUX_POWERLINE_DIR_USER_THEMES" ] && [ -f "${TMUX_POWERLINE_DIR_USER_THEMES}/${TMUX_POWERLINE_THEME}.sh" ]; then + source "${TMUX_POWERLINE_DIR_USER_THEMES}/${TMUX_POWERLINE_THEME}.sh" + else + source "${TMUX_POWERLINE_DIR_THEMES}/${TMUX_POWERLINE_THEME}.sh" + fi + +} + +generate_default_rc() { + read -d '' rccontents << EORC +# Default configuration file for tmux-powerline. +# Modeline { +# vi: foldmarker={,} foldmethod=marker foldlevel=0 tabstop=4 filetype=sh +# } + +# General { + # Show which segment fails and its exit code. + export TMUX_POWERLINE_DEBUG_MODE_ENABLED="${TMUX_POWERLINE_DEBUG_MODE_ENABLED_DEFAULT}" + # Use patched font symbols. + export TMUX_POWERLINE_PATCHED_FONT_IN_USE="${TMUX_POWERLINE_PATCHED_FONT_IN_USE_DEFAULT}" + # The theme to use. + export TMUX_POWERLINE_THEME="${TMUX_POWERLINE_THEME_DEFAULT}" + # Overlay dirctory to look for themes. There you can put your own themes outside the repo. Fallback will still be the "themes" directory in the repo. + export TMUX_POWERLINE_DIR_USER_THEMES="" + # Overlay dirctory to look for segments. There you can put your own segments outside the repo. Fallback will still be the "segments" directory in the repo. + export TMUX_POWERLINE_DIR_USER_SEGMENTS="" +# } +EORC + + for segment in ${TMUX_POWERLINE_DIR_SEGMENTS}/*.sh; do + source "$segment" + if declare -f generate_segmentrc >/dev/null; then + segmentrc=$(generate_segmentrc | sed -e 's/^/\\t/g') + unset -f generate_segmentrc + local seg_name="${segment##*/}" + rccontents="${rccontents}\n\n# ${seg_name} {\n${segmentrc}\n# }" + fi + done + + echo -e "$rccontents" > "$TMUX_POWERLINE_RCFILE_DEFAULT" + echo "Default configuration file generated to: ${TMUX_POWERLINE_RCFILE_DEFAULT}" + echo "Copy/move it to \"${TMUX_POWERLINE_RCFILE}\" and make your changes." +} + +__read_rcfile() { + if [ -f "$TMUX_POWERLINE_RCFILE" ]; then + source "$TMUX_POWERLINE_RCFILE" + fi +} diff --git a/lib/text_roll.sh b/lib/text_roll.sh new file mode 100644 index 0000000..e53247f --- /dev/null +++ b/lib/text_roll.sh @@ -0,0 +1,63 @@ +# Rolling anything what you want. +# arg1: text to roll. +# arg2: max length to display. +# arg3: roll speed in characters per second. +roll_text() { + local text="$1" # Text to print + + if [ -z "$text" ]; then + return; + fi + + local max_len="10" # Default max length. + + if [ -n "$2" ]; then + max_len="$2" + fi + + local speed="1" # Default roll speed in chars per second. + + if [ -n "$3" ]; then + speed="$3" + fi + + # Skip rolling if the output is less than max_len. + if [ "${#text}" -le "$max_len" ]; then + echo "$text" + return + fi + + # Anything starting with 0 is an Octal number in Shell,C or Perl, + # so we must explicitly state the base of a number using base#number + local offset=$((10#$(date +%s) * ${speed} % ${#text})) + + # Truncate text. + text=${text:offset} + + local char # Character. + local bytes # The bytes of one character. + local index + + for ((index=0; index < max_len; index++)); do + char=${text:index:1} + bytes=$(echo -n $char | wc -c) + # The character will takes twice space + # of an alphabet if (bytes > 1). + if ((bytes > 1)); then + max_len=$((max_len - 1)) + fi + done + + text=${text:0:max_len} + + #echo "index=${index} max=${max_len} len=${#text}" + # How many spaces we need to fill to keep + # the length of text that will be shown? + local fill_count=$((${index} - ${#text})) + + for ((index=0; index < fill_count; index++)); do + text="${text} " + done + + echo "${text}" +} diff --git a/lib/tmux_adapter.sh b/lib/tmux_adapter.sh new file mode 100644 index 0000000..17674e4 --- /dev/null +++ b/lib/tmux_adapter.sh @@ -0,0 +1,12 @@ +# Get the current path in the segment. +get_tmux_cwd() { + local env_name=$(tmux display -p "TMUXPWD_#D" | tr -d %) + local env_val=$(tmux show-environment | grep --color=never "$env_name") + # The version below is still quite new for tmux. Uncomment this in the future :-) + #local env_val=$(tmux show-environment "$env_name" 2>&1) + + if [[ ! $env_val =~ "unknown variable" ]]; then + local tmux_pwd=$(echo "$env_val" | sed 's/^.*=//') + echo "$tmux_pwd" + fi +} diff --git a/mute_powerline.sh b/mute_powerline.sh new file mode 100755 index 0000000..0c9316f --- /dev/null +++ b/mute_powerline.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +export TMUX_POWERLINE_DIR_HOME="$(dirname $0)" +source "${TMUX_POWERLINE_DIR_HOME}/config/paths.sh" +source "${TMUX_POWERLINE_DIR_LIB}/muting.sh" +source "${TMUX_POWERLINE_DIR_LIB}/arg_processing.sh" + +side="$1" +check_arg_side "$side" +toggle_powerline_mute_status "$side" diff --git a/powerline.sh b/powerline.sh new file mode 100755 index 0000000..92c0414 --- /dev/null +++ b/powerline.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +export TMUX_POWERLINE_DIR_HOME="$(dirname $0)" + +source "${TMUX_POWERLINE_DIR_HOME}/config/helpers.sh" +source "${TMUX_POWERLINE_DIR_HOME}/config/paths.sh" +source "${TMUX_POWERLINE_DIR_HOME}/config/shell.sh" +source "${TMUX_POWERLINE_DIR_HOME}/config/defaults.sh" + +source "${TMUX_POWERLINE_DIR_LIB}/arg_processing.sh" +source "${TMUX_POWERLINE_DIR_LIB}/formatting.sh" +source "${TMUX_POWERLINE_DIR_LIB}/muting.sh" +source "${TMUX_POWERLINE_DIR_LIB}/powerline.sh" +source "${TMUX_POWERLINE_DIR_LIB}/rcfile.sh" + +if ! powerline_muted "$1"; then + process_settings + check_arg_side "$1" + print_powerline "$1" +fi + +exit 0 diff --git a/scripts/tmux_start.sh b/scripts/tmux_start.sh new file mode 100755 index 0000000..bbf33c5 --- /dev/null +++ b/scripts/tmux_start.sh @@ -0,0 +1,38 @@ +#!/bin/sh +#from http://www.huyng.com/posts/productivity-boost-with-tmux-iterm2-workspaces/ +export PATH=$PATH:/usr/local/bin + +# abort if we're already inside a TMUX session +[ "$TMUX" == "" ] || exit 0 + +# startup a "default" session if none currently exists +#tmux has-session -t _default || tmux new-session -s _default -d + +# present menu for user to choose which workspace to open +PS3="Please choose your session: " +options=("tmux" "dashboard" $(tmux list-sessions -F "#S")) +echo "Available sessions" +echo "------------------" +echo " " +select opt in "${options[@]}" +do + case $opt in + #"NEW SESSION") + #read -p "Enter new session name: " SESSION_NAME + #tmux new -s "$SESSION_NAME" + #break + #;; + "dashboard") + tmuxomatic ~/.tmux/tmuxomatic/dashboard + break + ;; + "tmux") + tmux + break + ;; + *) + tmux attach-session -t $opt + break + ;; + esac +done diff --git a/scripts/tmux_window_renum.sh b/scripts/tmux_window_renum.sh new file mode 100755 index 0000000..6a63814 --- /dev/null +++ b/scripts/tmux_window_renum.sh @@ -0,0 +1,15 @@ +for session in $(tmux ls | awk -F: '{print $1}') ;do + active_window=$(tmux lsw -t ${session} | awk -F: '/\(active\)$/ {print $1}') + inum=0 + for window in $(tmux lsw -t ${session} | awk -F: '{print $1}') ;do + if [ ${window} -gt ${inum} ] ;then + echo "${session}:${window} -> ${session}:${inum}" + tmux movew -d -s ${session}:${window} -t ${session}:${inum} + fi + if [ ${window} = ${active_window} ] ;then + new_active_window=${inum} + fi + inum=$((${inum}+1)) + done + tmux select-window -t ${session}:${new_active_window} +done diff --git a/segments/Makefile b/segments/Makefile new file mode 100644 index 0000000..07767b5 --- /dev/null +++ b/segments/Makefile @@ -0,0 +1,18 @@ +# Build the small MPD NP program. +# Enable debug printing with $ make -e DEBUG=1 +DEBUG=0 +CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc) +CFLAGS = -O3 -Wall -std=c99 -I /usr/include/ -D DEBUG=${DEBUG} +LDLIBS = -lmpdclient +XKB_LAYOUT_LDLIBS= -lX11 + +.PHONY: all clean + +all: np_mpd xkb_layout + +xkb_layout: xkb_layout.c + $(CC) $(CFLAGS) $(LDFLAGS) $< $(XKB_LAYOUT_LDLIBS) -o $@ + +clean: + $(RM) np_mpd + $(RM) xkb_layout diff --git a/segments/battery.sh b/segments/battery.sh new file mode 100755 index 0000000..9b7084d --- /dev/null +++ b/segments/battery.sh @@ -0,0 +1,150 @@ +# LICENSE This code is not under the same license as the rest of the project as it's "stolen". It's cloned from https://github.com/richoH/dotfiles/blob/master/bin/battery and just some modifications are done so it works for my laptop. Check that URL for more recent versions. + +TMUX_POWERLINE_SEG_BATTERY_TYPE_DEFAULT="percentage" +TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS_DEFAULT=5 + +HEART_FULL="♥" +HEART_EMPTY="♡" + +generate_segmentrc() { + read -d '' rccontents << EORC +# How to display battery remaining. Can be {percentage, cute}. +export TMUX_POWERLINE_SEG_BATTERY_TYPE="${TMUX_POWERLINE_SEG_BATTERY_TYPE_DEFAULT}" +# How may hearts to show if cute indicators are used. +export TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS="${TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS_DEFAULT}" +EORC + echo "$rccontents" +} + +run_segment() { + __process_settings + if shell_is_osx; then + battery_status=$(__battery_osx) + else + battery_status=$(__battery_linux) + fi + [ -z "$battery_status" ] && return + + case "$TMUX_POWERLINE_SEG_BATTERY_TYPE" in + "percentage") + output="${HEART_FULL} ${battery_status}%" + ;; + "cute") + output=$(__cutinate $battery_status) + esac + if [ -n "$output" ]; then + echo "$output" + fi +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_BATTERY_TYPE" ]; then + export TMUX_POWERLINE_SEG_BATTERY_TYPE="${TMUX_POWERLINE_SEG_BATTERY_TYPE_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS" ]; then + export TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS="${TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS_DEFAULT}" + fi +} + +__battery_osx() { + ioreg -c AppleSmartBattery -w0 | \ + grep -o '"[^"]*" = [^ ]*' | \ + sed -e 's/= //g' -e 's/"//g' | \ + sort | \ + while read key value; do + case $key in + "MaxCapacity") + export maxcap=$value;; + "CurrentCapacity") + export curcap=$value;; + "ExternalConnected") + export extconnect=$value;; + "FullyCharged") + export fully_charged=$value;; + esac + if [[ -n $maxcap && -n $curcap && -n $extconnect ]]; then + if [[ "$curcap" == "$maxcap" || "$fully_charged" == "Yes" && $extconnect == "Yes" ]]; then + return + fi + charge=$(( 100 * $curcap / $maxcap )) + if [[ "$extconnect" == "Yes" ]]; then + echo "$charge" + else + if [[ $charge -lt 50 ]]; then + echo -n "#[fg=red]" + fi + echo "$charge" + fi + break + fi + done + } + + __battery_linux() { + case "$SHELL_PLATFORM" in + "linux") + BATPATH=/sys/class/power_supply/BAT0 + if [ ! -d $BATPATH ]; then + BATPATH=/sys/class/power_supply/BAT1 + fi + STATUS=$BATPATH/status + BAT_FULL=$BATPATH/charge_full + if [ ! -r $BAT_FULL ]; then + BAT_FULL=$BATPATH/energy_full + fi + BAT_NOW=$BATPATH/charge_now + if [ ! -r $BAT_NOW ]; then + BAT_NOW=$BATPATH/energy_now + fi + + if [ "$1" = `cat $STATUS` -o "$1" = "" ]; then + __linux_get_bat + fi + ;; + "bsd") + STATUS=`sysctl -n hw.acpi.battery.state` + case $1 in + "Discharging") + if [ $STATUS -eq 1 ]; then + __freebsd_get_bat + fi + ;; + "Charging") + if [ $STATUS -eq 2 ]; then + __freebsd_get_bat + fi + ;; + "") + __freebsd_get_bat + ;; + esac + ;; + esac + } + + __cutinate() { + perc=$1 + inc=$(( 100 / $TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS )) + + + for i in `seq $TMUX_POWERLINE_SEG_BATTERY_NUM_HEARTS`; do + if [ $perc -lt 99 ]; then + echo -n $HEART_EMPTY + else + echo -n $HEART_FULL + fi + echo -n " " + perc=$(( $perc + $inc )) + done + } + + __linux_get_bat() { + bf=$(cat $BAT_FULL) + bn=$(cat $BAT_NOW) + echo $(( 100 * $bn / $bf )) + } + + __freebsd_get_bat() { + echo "$(sysctl -n hw.acpi.battery.life)" + + } diff --git a/segments/cpu.sh b/segments/cpu.sh new file mode 100755 index 0000000..637bcda --- /dev/null +++ b/segments/cpu.sh @@ -0,0 +1,22 @@ +# Prints the CPU usage: user% sys% idle. + +run_segment() { + if shell_is_linux; then + cpu_line=$(top -b -n 1 | grep "Cpu(s)" ) + cpu_user=$(echo "$cpu_line" | grep -Po "(\d+(.\d+)?)(?=%?\s?(us(er)?))") + cpu_system=$(echo "$cpu_line" | grep -Po "(\d+(.\d+)?)(?=%?\s?(sys?))") + cpu_idle=$(echo "$cpu_line" | grep -Po "(\d+(.\d+)?)(?=%?\s?(id(le)?))") + elif shell_is_osx; then + cpus_line=$(top -e -l 1 | grep "CPU usage:" | sed 's/CPU usage: //') + cpu_user=$(echo "$cpus_line" | awk '{print $1}' | sed 's/%//' ) + cpu_system=$(echo "$cpus_line" | awk '{print $3}'| sed 's/%//' ) + cpu_idle=$(echo "$cpus_line" | awk '{print $5}' | sed 's/%//' ) + fi + + if [ -n "$cpu_user" ] && [ -n "$cpu_system" ] && [ -n "$cpu_idle" ]; then + echo "${cpu_user}, ${cpu_system}, ${cpu_idle}" | awk -F', ' '{printf("%5.1f,%5.1f,%5.1f",$1,$2,$3)}' + return 0 + else + return 1 + fi +} diff --git a/segments/date.sh b/segments/date.sh new file mode 100755 index 0000000..32263d5 --- /dev/null +++ b/segments/date.sh @@ -0,0 +1,23 @@ +# Print the current date. + +TMUX_POWERLINE_SEG_DATE_FORMAT_DEFAULT="%F" + +generate_segmentrc() { + read -d '' rccontents << EORC +# date(1) format for the date. If you don't, for some reason, like ISO 8601 format you might want to have "%D" or "%m/%d/%Y". +export TMUX_POWERLINE_SEG_DATE_FORMAT="${TMUX_POWERLINE_SEG_DATE_FORMAT_DEFAULT}" +EORC + echo "$rccontents" +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_DATE_FORMAT" ]; then + export TMUX_POWERLINE_SEG_DATE_FORMAT="${TMUX_POWERLINE_SEG_DATE_FORMAT_DEFAULT}" + fi +} + +run_segment() { + __process_settings + date +"$TMUX_POWERLINE_SEG_DATE_FORMAT" + return 0 +} diff --git a/segments/date_day.sh b/segments/date_day.sh new file mode 100755 index 0000000..35a42eb --- /dev/null +++ b/segments/date_day.sh @@ -0,0 +1,6 @@ +# Prints the name of the current day. + +run_segment() { + date +"%a" + return 0 +} diff --git a/segments/earthquake.sh b/segments/earthquake.sh new file mode 100755 index 0000000..3859094 --- /dev/null +++ b/segments/earthquake.sh @@ -0,0 +1,173 @@ +# Prints the most recent earthquake (currently only supports japan) +# It prints the location, time, and magnitude if the quake happened within +# a timelimit and magnitude threshold + +earthquake_symbol='#[fg=colour1]~' + +# The update period in seconds. +update_period=600 + +TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER_DEFAULT="goo" +TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD_DEFAULT="600" +TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW_DEFAULT="60" +TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT_DEFAULT='(%H:%M)' +TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE_DEFAULT='3' + +generate_segmentrc() { + read -d '' rccontents << EORC +# The data provider to use. Currently only "goo" is supported. +export TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER="${TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER_DEFAULT}" +# How often to update the earthquake data in seconds. +# Note: This is not an early warning detector, use this +# to be informed about recent earthquake magnitudes in your +# area. If this is too often, goo may decide to ban you form +# their server +export TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD_DEFAULT}" +# Only display information when earthquakes are within this many minutes +export TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW="${TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW_DEFAULT}" +# Display time with this format +export TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT='${TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT_DEFAULT}' +# Display only if magnitude is greater or equal to this number +export TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE="${TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE_DEFAULT}" +EORC + echo "$rccontents" +} + +run_segment() { + __process_settings + local tmp_file="${TMUX_POWERLINE_DIR_TEMPORARY}/earthquake.txt" + local earthquake + case "$TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER" in + "goo") earthquake=$(__goo_earthquake) ;; + *) + echo "Unknown earthquake-information provider [${$TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER}]"; + return 1 + esac + if [ -n "$earthquake" ]; then + echo "$earthquake_symbol #[fg=colour237]${earthquake}" + fi +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER" ]; then + export TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER="${TMUX_POWERLINE_SEG_EARTHQUAKE_DATA_PROVIDER_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD" ]; then + export TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_EARTHQUAKE_UPDATE_PERIOD_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW" ]; then + export TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW="${TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT" ]; then + export TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT="${TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE" ]; then + export TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE="${TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE_DEFAULT}" + fi +} + +__goo_earthquake() { + location="" + magnitude="" + magnitude_number="" + timestamp="" + if [[ -f "$tmp_file" ]]; then + if shell_is_osx || shell_is_bsd; then + last_update=$(stat -f "%m" ${tmp_file}) + elif shell_is_linux; then + last_update=$(stat -c "%Y" ${tmp_file}) + fi + time_now=$(date +%s) + + up_to_date=$(echo "(${time_now}-${last_update}) < ${update_period}" | bc) + if [ "$up_to_date" -eq 1 ]; then + __read_tmp_file + fi + fi + + if [ -z "$magnitude" ]; then + # get the rss file, convert encoding to UTF-8, then delete windows carriage-returns + earthquake_data=$(curl --max-time 4 -s "http://weather.goo.ne.jp/earthquake/index.rdf" | iconv -f EUC-JP -t UTF-8 | tr -d "\r") + if [ "$?" -eq "0" ]; then + # This rss feed is not very clean or easy to use, but we will use it because + # this is all that can be found for now + + # we grab the data from the title of the first item (most recent earthquake) + earthquake_data=${earthquake_data#*item\><title>} + # end our data at the end of the approx. time + earthquake_data=${earthquake_data%%頃*} + + # pluck our data + location=$(echo $earthquake_data | awk '{print $2}') + magnitude=$(echo $earthquake_data | awk '{print $4}') + timestamp=${earthquake_data#*\(} + + __convert_jp_magnitude + __convert_jp_timestamp + + echo $location > $tmp_file + echo $magnitude >> $tmp_file + echo $timestamp >> $tmp_file + elif [ -f "$tmp_file" ]; then + __read_tmp_file + fi + fi + __convert_timestamp_to_fmt + + # extract the numerical portion of magnitude + magnitude_number=$(echo $magnitude | sed -e 's/+//' -e 's/-//') + + if [ -n "$magnitude" ]; then + if __check_alert_time_window && __check_min_magnitude ; then + echo "${location}${timestamp_fmt}:#[fg=colour0]${magnitude}" + fi + fi +} + +__convert_jp_magnitude() { + magnitude=${magnitude#震度} + # simplify high-lower designation (only used in extreme cases: above 4) + if [[ "$magnitude" == *弱 ]] ; then + magnitude="-${magnitude%弱}" + elif [[ "$magnitude" == *強 ]] ; then + magnitude="+${magnitude%強}" + fi +} + +__check_alert_time_window() { + [[ $(( ( $(date +%s) - $timestamp ) / 60 )) -lt $TMUX_POWERLINE_SEG_EARTHQUAKE_ALERT_TIME_WINDOW ]] +} + +__check_min_magnitude() { + [[ $magnitude_number -ge $TMUX_POWERLINE_SEG_EARTHQUAKE_MIN_MAGNITUDE ]] +} + +__convert_jp_timestamp() { + if shell_is_osx ; then + timestamp=$(date -j -f "%Y年%m月%d日 %H時%M分" "$timestamp" +"%s") + else + timestamp=$(echo $timestamp | $sed -e 's/年/-/' -e 's/月/-/' -e 's/日//' -e 's/時/:/' -e 's/分//') + timestamp=$(date -d "$timestamp" +"%s") + fi +} + +__convert_timestamp_to_fmt() { + if shell_is_osx ; then + timestamp_fmt=$(date -r "$timestamp" +"$TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT") + else + timestamp_fmt=$(date -d "$timestamp" +"$TMUX_POWERLINE_SEG_EARTHQUAKE_TIME_FORMAT") + fi +} + +__read_tmp_file() { + if [ ! -f "$tmp_file" ]; then + return + fi + IFS_bak="$IFS" + IFS=$'\n' + lines=($(cat ${tmp_file})) + IFS="$IFS_bak" + location="${lines[0]}" + magnitude="${lines[1]}" + timestamp="${lines[2]}" +} diff --git a/segments/hostname.sh b/segments/hostname.sh new file mode 100755 index 0000000..c3dfbf9 --- /dev/null +++ b/segments/hostname.sh @@ -0,0 +1,31 @@ +# Prints the hostname. + +TMUX_POWERLINE_SEG_HOSTNAME_FORMAT_DEFAULT="short" + +generate_segmentrc() { + read -d '' rccontents << EORC +# Use short or long format for the hostname. Can be {"short, long"}. +export TMUX_POWERLINE_SEG_HOSTNAME_FORMAT="${TMUX_POWERLINE_SEG_HOSTNAME_FORMAT_DEFAULT}" +EORC + echo "$rccontents" +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_HOSTNAME_FORMAT" ]; then + export TMUX_POWERLINE_SEG_HOSTNAME_FORMAT="${TMUX_POWERLINE_SEG_HOSTNAME_FORMAT_DEFAULT}" + fi +} +run_segment() { + __process_settings + local opts="" + if [ "$TMUX_POWERLINE_SEG_HOSTNAME_FORMAT" == "short" ]; then + if shell_is_osx || shell_is_bsd; then + opts="-s" + else + opts="--short" + fi + fi + + hostname ${opts} + return 0 +} diff --git a/segments/ifstat.sh b/segments/ifstat.sh new file mode 100755 index 0000000..2666496 --- /dev/null +++ b/segments/ifstat.sh @@ -0,0 +1,39 @@ +# Show network statistics for all active interfaces found. + +run_segment() { + type ifstat >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return 1 + fi + + sed="sed" + type gsed >/dev/null 2>&1 + if [ "$?" -eq 0 ]; then + sed="gsed" + fi + + data=$(ifstat -z -S -q 1 1) + interfaces=$(echo -e "${data}" | head -n 1) + flow_data=$(echo -e "${data}" | tail -n 1 | ${sed} "s/\s\{1,\}/,/g") + index=1 + for inf in ${interfaces}; do + type="" + case ${inf} in + eth*) type="⎆" + ;; + wlan*) type="☫" + ;; + en*) type=" " + ;; + esac + if [ -n "${type}" ]; then + formate=$(echo "${formate} ${type} ⇊ %.2f ⇈ %.2f") + holder=$(echo "${holder},\$$((index)),\$$((index+1))") + fi + index=$((index+2)) + done + if [ -n "${formate}" ]; then + echo $(echo "${flow_data#,}" | awk -F"," "{printf(\"${formate}\"${holder})}") + fi + return 0 +} diff --git a/segments/ifstat_sys.sh b/segments/ifstat_sys.sh new file mode 100755 index 0000000..1059dc4 --- /dev/null +++ b/segments/ifstat_sys.sh @@ -0,0 +1,28 @@ +# Show if stats by sampling /sys/. +# Originally stolen from http://unix.stackexchange.com/questions/41346/upload-download-speed-in-tmux-status-line + +run_segment() { + sleeptime="0.5" + iface="eth0" + RXB=$(</sys/class/net/"$iface"/statistics/rx_bytes) + TXB=$(</sys/class/net/"$iface"/statistics/tx_bytes) + sleep "$sleeptime" + RXBN=$(</sys/class/net/"$iface"/statistics/rx_bytes) + TXBN=$(</sys/class/net/"$iface"/statistics/tx_bytes) + RXDIF=$(echo "$((RXBN - RXB)) / 1024 / ${sleeptime}" | bc ) + TXDIF=$(echo "$((TXBN - TXB)) / 1024 / ${sleeptime}" | bc ) + + if [ $RXDIF -gt 1024 ]; then + RXDIF_ECHO="↓ $(echo "scale=1;${RXDIF} / 1024" | bc)M/s" + else + RXDIF_ECHO="↓ ${RXDIF}K/s" + fi + if [ $TXDIF -gt 1024 ]; then + TXDIF_ECHO="↑ $(echo "scale=1;${TXDIF} / 1024" | bc)M/s" + else + TXDIF_ECHO="↑ ${TXDIF}K/s" + fi + + echo -e "${RXDIF_ECHO} ${TXDIF_ECHO}" + return 0 +} diff --git a/segments/lan_ip.sh b/segments/lan_ip.sh new file mode 100755 index 0000000..fe97dad --- /dev/null +++ b/segments/lan_ip.sh @@ -0,0 +1,32 @@ +# Prints the local network IPv4 address for a statically defined NIC or search for an IPv4 address on all active NICs. + +run_segment() { + if shell_is_bsd || shell_is_osx ; then + all_nics=$(ifconfig 2>/dev/null | awk -F':' '/^[a-z]/ && !/^lo/ { print $1 }') + for nic in ${all_nics[@]}; do + ipv4s_on_nic=$(ifconfig ${nic} 2>/dev/null | awk '$1 == "inet" { print $2 }') + for lan_ip in ${ipv4s_on_nic[@]}; do + [[ -n "${lan_ip}" ]] && break + done + [[ -n "${lan_ip}" ]] && break + done + else + # Get the names of all attached NICs. + all_nics="$(ip addr show | cut -d ' ' -f2 | tr -d :)" + all_nics=(${all_nics[@]//lo/}) # Remove lo interface. + + for nic in "${all_nics[@]}"; do + # Parse IP address for the NIC. + lan_ip="$(ip addr show ${nic} | grep '\<inet\>' | tr -s ' ' | cut -d ' ' -f3)" + # Trim the CIDR suffix. + lan_ip="${lan_ip%/*}" + # Only display the last entry + lan_ip="$(echo "$lan_ip" | tail -1)" + + [ -n "$lan_ip" ] && break + done + fi + + echo "ⓛ ${lan_ip-N/a}" + return 0 +} diff --git a/segments/load.sh b/segments/load.sh new file mode 100755 index 0000000..7480d96 --- /dev/null +++ b/segments/load.sh @@ -0,0 +1,6 @@ +# Print the average load. + +run_segment() { + uptime | cut -d "," -f 3- | cut -d ":" -f2 | sed -e "s/^[ \t]*//" + exit 0 +} diff --git a/segments/mailcount.sh b/segments/mailcount.sh new file mode 100755 index 0000000..68029aa --- /dev/null +++ b/segments/mailcount.sh @@ -0,0 +1,204 @@ +# Report mail count for your mailbox type + +TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX_DEFAULT="$HOME/.mail/inbox/new" +TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX_DEFAULT="${MAIL}" +TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC_DEFAULT="${HOME}/.mailcheckrc" +TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER_DEFAULT="gmail.com" +TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL_DEFAULT="5" + + +generate_segmentrc() { + read -d '' rccontents << EORC +# Mailbox type to use. Can be any of {apple_mail, gmail, maildir, mbox, mailcheck} +export TMUX_POWERLINE_SEG_MAILCOUNT_MAILBOX_TYPE="" + +## Gmail +# Enter your Gmail username here WITH OUT @gmail.com.( OR @domain) +export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_USERNAME="" +# Google password. Recomenned to use application specific password (https://accounts.google.com/b/0/IssuedAuthSubTokens) Leave this empty to get password from OS X keychain. +# For OSX users : MAKE SURE that you add a key to the keychain in the format as follows +# Keychain Item name : http://<value-you-fill-in-server-variable-below> +# Account name : <username-below>@<server-below> +# Password : Your password ( Once again, try to use 2 step-verification and application-specific password) +# See http://support.google.com/accounts/bin/answer.py?hl=en&answer=185833 for more info. +export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_PASSWORD="" +# Domain name that will complete your email. For normal GMail users it probably is "gmail.com but can be "foo.tld" for Google Apps users. +export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER="${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER_DEFAULT}" +# How often in minutes to check for new mails. +export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL="${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL_DEFAULT}" + +## Maildir +# Path to the maildir to check. +export TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX="${TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX_DEFAULT}" + +## mbox +# Path to the mbox to check. +export TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX="${TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX_DEFAULT}" + +## mailcheck +# Optional path to mailcheckrc +export TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC="${TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC_DEFAULT}" +EORC + echo "${rccontents}" +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER" ]; then + export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER="${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL" ]; then + export TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL="${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL_DEFAULT}" + fi + + eval TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX="$TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX" + if [ -z "$TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX" ]; then + export TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX="${TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX_DEFAULT}" + fi + + eval TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX="$TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX" + if [ -z "${TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX}" ]; then + export TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX="${TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX_DEFAULT}" + fi + + eval TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC="$TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC" + if [ -z "${TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC}" ]; then + export TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC="${TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC_DEFAULT}" + fi + +} + +run_segment() { + __process_settings + + if [ -z "$TMUX_POWERLINE_SEG_MAILCOUNT_MAILBOX_TYPE" ]; then + return 2 + fi + + local count + case "$TMUX_POWERLINE_SEG_MAILCOUNT_MAILBOX_TYPE" in + "apple_mail") count=$(__count_apple_mail) ;; + "gmail") count=$(__count_gmail) ;; + "maildir") count=$(__count_maildir) ;; + "mbox") count=$(__count_mbox) ;; + "mailcheck") count=$(__count_mailcheck) ;; + *) + echo "Unknown mailbox type [${TMUX_POWERLINE_SEG_MAILCOUNT_MAILBOX_TYPE}]"; + return 1 + esac + local exitcode="$?" + if [ "$exitcode" -ne 0 ]; then + return $exitcode + fi + + if [[ -n "$count" && "$count" -gt 0 ]]; then + echo "✉ ${count}" + fi + + return 0 +} + + +__count_apple_mail() { + count=$(${TMUX_POWERLINE_DIR_SEGMENTS}/mailcount_apple_mail.script) + echo "$count" +} + +__count_gmail() { + local tmp_file="${TMUX_POWERLINE_DIR_TEMPORARY}/gmail_count.txt" + local tmp_wgetrc="${TMUX_POWERLINE_DIR_TEMPORARY}/tmp_wgetrc.txt" + local override_passget="false" # When true a force reloaded will be done. + + # Create the cache file if it doesn't exist. + if [ ! -f "$tmp_file" ]; then + touch $tmp_file + override_passget=true + fi + + # Refresh mail count if the tempfile is older than $interval minutes. + let interval=60*$TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_INTERVAL + if shell_is_osx || shell_is_bsd; then + last_update=$(stat -f "%m" ${tmp_file}) + elif shell_is_linux; then + last_update=$(stat -c "%Y" ${tmp_file}) + fi + if [ "$(( $(date +"%s") - ${last_update} ))" -gt "$interval" ] || [ "$override_passget" == true ]; then + if [ -z "$TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_PASSWORD" ]; then # Get password from keychain if it isn't already set. + if shell_is_osx; then + __mac_keychain_get_pass "${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_USERNAME}@${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER}" "$TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER" + else + echo "Implement your own sexy password fetching mechanism here." + return 1 + fi + fi + + # Check for wget before proceeding. + which wget 2>&1 > /dev/null + if [ $? -ne 0 ]; then + echo "This script requires wget." 1>&2 + return 1 + fi + + # Hide password from command line (visible with e.g. ps(1)). + echo -e "user=${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_USERNAME}@${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER}\npassword=${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_PASSWORD}" > "$tmp_wgetrc" + mail=$(wget -q -O - https://mail.google.com/a/${TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_SERVER}/feed/atom --config "$tmp_wgetrc" | grep fullcount | sed 's/<[^0-9]*>//g') + rm "$tmp_wgetrc" + + if [ "$mail" != "" ]; then + echo $mail > $tmp_file + else + return 1 + fi + fi + + count=$(cat $tmp_file) + echo "$count" + return 0; +} + +__count_maildir() { + if [ ! -d "$TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX" ]; then + return 1 + fi + + count=$(ls "$TMUX_POWERLINE_SEG_MAILCOUNT_MAILDIR_INBOX" | wc -l) + + # Fix for mac, otherwise whitespace is left in output + if shell_is_osx; then + count=$(echo "$count" | sed -e "s/^[ \t]*//") + fi + + echo "$count" + return 0; +} + +__count_mbox() { + if [ ! -f "${TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX}" ]; then + return 1 + fi + + # This matches the From_ line (see man 5 mbox) e.g. + # From noreply@github.com Sun Dec 2 03:52:25 2012 + # See https://github.com/erikw/tmux-powerline/pull/91#issuecomment-10926053 for discussion. + count=$(grep -c '^From [^[:space:]]\+ ... ... .. ..:..:.. ....$' ${TMUX_POWERLINE_SEG_MAILCOUNT_MBOX_INBOX}) + + echo "$count" + return 0; +} + +__mac_keychain_get_pass() { + result="$(security 2>&1 > /dev/null find-internet-password -ga $1 -s $2)" + if [ $? -eq 0 ]; then + TMUX_POWERLINE_SEG_MAILCOUNT_GMAIL_PASSWORD=$(echo "$result" | sed -e 's/password: \"\(.*\)\"/\1/g') + return 0 + fi + return 1 +} + +__count_mailcheck() { + count=$(mailcheck -f ${TMUX_POWERLINE_SEG_MAILCOUNT_MAILCHECKRC} | awk '{ if (/new/) { print $3; exit } else { print 0; exit } }') + if [ $? -eq 0 ]; then + echo "$count" + return 0 + fi + return 1; +} diff --git a/segments/mailcount_apple_mail.script b/segments/mailcount_apple_mail.script new file mode 100755 index 0000000..fca8acb --- /dev/null +++ b/segments/mailcount_apple_mail.script @@ -0,0 +1,14 @@ +#!/usr/bin/env osascript +# Returns the number of unread mails in the INBOX of Apple Mail. + +tell application "System Events" + set process_list to (name of every process) +end tell + +if process_list contains "Mail" then + tell application "Mail" + if unread count of inbox > 0 then + set a to unread count of inbox + end if + end tell +end if diff --git a/segments/now_playing.sh b/segments/now_playing.sh new file mode 100755 index 0000000..6fdf251 --- /dev/null +++ b/segments/now_playing.sh @@ -0,0 +1,274 @@ +# Print current playing song in your music player of choice. + +source "${TMUX_POWERLINE_DIR_LIB}/text_roll.sh" + +TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN_DEFAULT="40" +TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD_DEFAULT="trim" +TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED_DEFAULT="2" +TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST_DEFAULT="localhost" +TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT_DEFAULT="6600" +TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD_DEFAULT="30" +TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT_DEFAULT="%artist% - %title%" +TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR_DEFAULT="♫" + +generate_segmentrc() { + read -d '' rccontents << EORC +# Music player to use. Can be any of {audacious, banshee, cmus, itunes, lastfm, mocp, mpd, mpd_simple, pithos, rdio, rhythmbox, spotify, spotify_wine}. +export TMUX_POWERLINE_SEG_NOW_PLAYING_MUSIC_PLAYER="" +# Maximum output length. +export TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN="${TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN_DEFAULT}" +# How to handle too long strings. Can be {trim, roll}. +export TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD="${TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD_DEFAULT}" +# Charcters per second to roll if rolling trim method is used. +export TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED="${TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED_DEFAULT}" + +# Hostname for MPD server in the format "[password@]host" +export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST_DEFAULT}" +# Port the MPD server is running on. +export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT_DEFAULT}" +# Song display format for mpd_simple. See mpc(1) for delimiters. +export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT_DEFAULT}" + +# Username for Last.fm if that music player is used. +export TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_USERNAME="" +# How often in seconds to update the data from last.fm. +export TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD_DEFAULT}" +# Fancy char to display before now playing track +export TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR="${TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR_DEFAULT}" +EORC + echo "$rccontents" +} + +run_segment() { + __process_settings + + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_MUSIC_PLAYER" ]; then + return 1 + fi + + local np + case "$TMUX_POWERLINE_SEG_NOW_PLAYING_MUSIC_PLAYER" in + "audacious") np=$(__np_audacious) ;; + "banshee") np=$(__np_banshee) ;; + "cmus") np=$(__np_cmus) ;; + "itunes") np=$(__np_itunes) ;; + "lastfm") np=$(__np_lastfm) ;; + "mocp") np=$(__np_mocp) ;; + "mpd") np=$(__np_mpd) ;; + "mpd_simple") np=$(__np_mpd_simple) ;; + "pithos") np=$(__np_pithos) ;; + "rdio") np=$(__np_rdio) ;; + "rhythmbox") np=$(__np_rhythmbox) ;; + "spotify") np=$(__np_spotify) ;; + "spotify_wine") np=$(__np_spotify_native) ;; + *) + echo "Unknown music player type [${TMUX_POWERLINE_SEG_NOW_PLAYING_MUSIC_PLAYER}]"; + return 1 + esac + local exitcode="$?" + if [ "${exitcode}" -ne 0 ]; then + return ${exitcode} + fi + if [ -n "$np" ]; then + case "$TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD" in + "roll") + np=$(roll_text "${np}" ${TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN} ${TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED_DEFAULT}) + ;; + "trim") + np=${np:0:TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN} + ;; + esac + echo "${TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR} ${np}" + fi + return 0 +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN="${TMUX_POWERLINE_SEG_NOW_PLAYING_MAX_LEN_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD="${TMUX_POWERLINE_SEG_NOW_PLAYING_TRIM_METHOD_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED="${TMUX_POWERLINE_SEG_NOW_PLAYING_ROLL_SPEED_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT="${TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR" ]; then + export TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR="${TMUX_POWERLINE_SEG_NOW_PLAYING_NOTE_CHAR_DEFAULT}" + fi +} + +__np_mpd() { + cd "$TMUX_POWERLINE_DIR_SEGMENTS" + + if [ ! -x "np_mpd" ]; then + make clean np_mpd &>/dev/null + fi + + if [ ! -x "np_mpd" ]; then + return 2 + fi + + np=$(MPD_HOST="$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST" MPD_PORT="$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT" ./np_mpd) + echo "$np" +} + +__np_mpd_simple() { + np=$(MPD_HOST="$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_HOST" MPD_PORT="$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_PORT" mpc current -f "$TMUX_POWERLINE_SEG_NOW_PLAYING_MPD_SIMPLE_FORMAT" 2>&1) + if [ $? -eq 0 ] && [ -n "$np" ]; then + mpc | grep "paused" > /dev/null + if [ $? -eq 0 ]; then + return 1 + fi + echo "$np" + fi +} + + +__np_audacious() { + audacious_pid=$(pidof audacious) + if [ -n "$audacious_pid" ]; then + if $(audtool playback-playing); then + np=$(audtool current-song) + echo "$np" + fi + fi +} + +__np_banshee() { + banshee_pid=$(pidof banshee) + if [ -n "$banshee_pid" ]; then + banshee_status=$(banshee --query-current-state 2> /dev/null) + if [[ "$banshee_status" == "current-state: playing" ]]; then + np=$(banshee --query-artist --query-title | cut -d ":" -f2 | sed -e 's/ *$//g' -e 's/^ *//g'| sed -e ':a;N;$!ba;s/\n/ - /g' ) + echo "$np" + fi + fi +} + +__np_cmus() { + #cmus-remote returns EXIT_FAILURE/EXIT_SUCCESS depending on whether or not cmus is running. + if cmus-remote -Q > /dev/null 2>&1; then + status=$(cmus-remote -Q | grep "status" | cut -d ' ' -f 2) + artist=$(cmus-remote -Q | grep -m 1 "artist" | cut -d ' ' -f 3-) + title=$(cmus-remote -Q | grep "title" | cut -d ' ' -f 3-) + #The lines below works fine. Just uncomment them and add them + # in np below if you want the track number or album name. + #tracknumber=$(cmus-remote -Q | grep "tracknumber" | cut -d ' ' -f 3) + #album=$(cmus-remote -Q | grep "album" | cut -d ' ' -f 3-) + + np=$(echo "${artist} - ${title}") + + if [ "$status" == "playing" ]; then + echo "$np" + fi + fi +} + +__np_itunes() { + [ ! shell_is_osx ] && return 1 + np=$(${TMUX_POWERLINE_DIR_SEGMENTS}/np_itunes.script) + echo "$np" +} + +__np_lastfm() { + local tmp_file="${TMUX_POWERLINE_DIR_TEMPORARY}/np_lastfm.txt" + if [ -f "$tmp_file" ]; then + if shell_is_osx || shell_is_bsd; then + last_update=$(stat -f "%m" ${tmp_file}) + elif shell_is_linux; then + last_update=$(stat -c "%Y" ${tmp_file}) + fi + time_now=$(date +%s) + + up_to_date=$(echo "(${time_now}-${last_update}) < ${TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_UPDATE_PERIOD}" | bc) + if [ "$up_to_date" -eq 1 ]; then + np=$(cat ${tmp_file}) + fi + fi + + if [ -z "$np" ]; then + np=$(curl --max-time 2 -s http://ws.audioscrobbler.com/1.0/user/${TMUX_POWERLINE_SEG_NOW_PLAYING_LASTFM_USERNAME}/recenttracks.txt | head -n 1 | sed -e 's/^[0-9]*,//' | sed 's/\xe2\x80\x93/-/') + if [ "$?" -eq "0" ] && [ -n "$np" ]; then + echo "${np}" > $tmp_file + fi + fi + echo "$np" +} + +__np_pithos() { + if [ "$(dbus-send --reply-timeout=10 --print-reply --dest=net.kevinmehall.Pithos /net/kevinmehall/Pithos net.kevinmehall.Pithos.IsPlaying 2>/dev/null | grep boolean | cut -d' ' -f5)" == "true" ]; then + np=$(${TMUX_POWERLINE_DIR_SEGMENTS}/np_pithos.py) + echo "$np" + fi +} + +__np_mocp() { + mocp_pid=$(pidof mocp) + if [ -n "$mocp_pid" ]; then + np=$(mocp -i | grep ^Title | sed "s/^Title://") + mocp_paused=$(mocp -i | grep ^State | sed "s/^State: //") + if [ -n "$np" -a "$mocp_paused" != "PAUSE" ]; then + echo "$np" + fi + fi +} + +__np_rdio() { + [ ! shell_is_osx ] && return 1 + np=$(osascript ${TMUX_POWERLINE_DIR_SEGMENTS}/np_rdio_mac.script) + echo "$np" +} + +__np_rhythmbox() { + rhythmbox_pid=$(pidof rhythmbox) + if [ -n "$rhythmbox_pid" ]; then + np=$(rhythmbox-client --no-start --print-playing) # Does not tell if the music is playing or paused. + rhythmbox_paused=$(xwininfo -root -tree | grep "$np" | sed "s/${np}//;s/ //g" | cut -f2 -d '"') + # TODO I cant produce the output "Not playing", using rhythmbox 2.97. + #STATUS=$(rhythmbox-client --no-start --print-playing) + if [[ "$rhythmbox_paused" != "(Paused)" ]]; then + echo "$np" + fi + fi +} + +__np_spotify() { + if shell_is_linux; then + metadata=$(dbus-send --reply-timeout=42 --print-reply --dest=org.mpris.MediaPlayer2.spotify / org.freedesktop.MediaPlayer2.GetMetadata 2>/dev/null) + if [ "$?" -eq 0 ] && [ -n "$metadata" ]; then + # TODO how do one express this with dbus-send? It works with qdbus but the problem is that it's probably not as common as dbus-send. + state=$(qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player PlaybackStatus) + if [[ $state == "Playing" ]]; then + artist=$(echo "$metadata" | grep -PA2 "string\s\"xesam:artist\"" | tail -1 | grep -Po "(?<=\").*(?=\")") + track=$(echo "$metadata" | grep -PA1 "string\s\"xesam:title\"" | tail -1 | grep -Po "(?<=\").*(?=\")") + np=$(echo "${artist} - ${track}") + fi + fi + elif shell_is_osx; then + np=$(${TMUX_POWERLINE_DIR_SEGMENTS}/np_spotify_mac.script) + fi + echo "$np" +} + +__np_spotify_wine() { + [ ! shell_is_linux ] && return 1 + spotify_id=$(xwininfo -root -tree | grep '("spotify' | cut -f1 -d'"' | sed 's/ //g') + echo $spotify_id + if [ -n "$spotify_id" ]; then + np=$(xwininfo -id "$spotify_id" | grep "xwininfo.*Spotify -" | grep -Po "(?<=\"Spotify - ).*(?=\"$)") + echo "$np" + fi +} diff --git a/segments/np_itunes.script b/segments/np_itunes.script new file mode 100755 index 0000000..8ac66bd --- /dev/null +++ b/segments/np_itunes.script @@ -0,0 +1,24 @@ +#!/usr/bin/env osascript +# Returns the current playing song in iTunes for OSX + +tell application "System Events" + set process_list to (name of every process) +end tell + +if process_list contains "iTunes" then + tell application "iTunes" + if player state is playing then + set track_name to name of current track + set artist_name to artist of current track + # set album_name to album of current track + set trim_length to 40 + set now_playing to artist_name & " - " & track_name + if length of now_playing is less than trim_length then + set now_playing_trim to now_playing + else + set now_playing_trim to characters 1 thru trim_length of now_playing as string + end if + end if + end tell +end if + diff --git a/segments/np_mpd.c b/segments/np_mpd.c new file mode 100644 index 0000000..97c4a6a --- /dev/null +++ b/segments/np_mpd.c @@ -0,0 +1,179 @@ +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <mpd/client.h> + +#ifdef DEBUG + #define DO_DEBUG DEBUG +#else + #define DO_DEBUG 0 +#endif +#define DEBUG_PRINTF(...) do{ if (DO_DEBUG) { printf(__VA_ARGS__);} } while(0) + +/* Output the current song if MPD is in a playing state. The connection password, host and port is + * specified like for mpc with environment variables + * MPD_HOST=[password@]host + * MPD_PORT=port + * If they are empty they defaults to localhost on port 6600. + */ +int main(int argc, const char *argv[]) +{ + char *mpd_host = NULL; + char *mpd_password = NULL; + unsigned int mpd_port = 0; + + char *mpd_host_m = NULL; + char *mpd_password_m = NULL; + + const char *mpd_host_str = getenv("MPD_HOST"); + if (mpd_host_str == NULL || strlen(mpd_host_str) == 0) { + DEBUG_PRINTF("No envvar MPD_HOST set or empty. Using default value (localhost).\n"); + mpd_host = "localhost"; + } else { + size_t mpd_host_len = strlen(mpd_host_str); + char mpd_host_env[mpd_host_len + 1]; + strncpy(mpd_host_env, mpd_host_str, mpd_host_len); + mpd_host_env[mpd_host_len] = '\0'; + + char *pch = strtok(mpd_host_env, "@"); + char *first = NULL; + char *second = NULL; + if (pch != NULL) { + first = pch; + } + pch = strtok(NULL, "@"); + if (pch != NULL) { + second = pch; + } + + if (first != NULL && second != NULL) { + DEBUG_PRINTF("%s - %s\n", first, second); + size_t first_len = strlen(first); + size_t second_len = strlen(second); + mpd_password_m = (char *) malloc(first_len + 1); + mpd_host_m= (char *) malloc(second_len + 1); + if (mpd_password_m == NULL || mpd_host_m == NULL) { + DEBUG_PRINTF("Failed alloc password/host.\n"); + return EXIT_FAILURE; + } + strncpy(mpd_password_m, first, first_len); + mpd_password_m[first_len] = '\0'; + strncpy(mpd_host_m, second, second_len); + mpd_host_m[second_len] = '\0'; + } else if (first != NULL) { + DEBUG_PRINTF("%s\n", first); + size_t first_len = strlen(first); + mpd_host_m = (char *) malloc(first_len + 1); + if (mpd_host_m == NULL ) { + DEBUG_PRINTF("Failed alloc host.\n"); + return EXIT_FAILURE; + } + strncpy(mpd_host_m, first, first_len); + mpd_host_m[first_len] = '\0'; + } + } + + if (mpd_host_m != NULL) { + mpd_host = mpd_host_m; + } + + if (mpd_password_m != NULL) { + mpd_password = mpd_password_m; + } + + const char *mpd_port_env = getenv("MPD_PORT"); + if (mpd_port_env == NULL || strlen(mpd_port_env) == 0) { + DEBUG_PRINTF("No envvar MPD_PORT set or empty. Using default value (6600).\n"); + mpd_port = 6600; + } else { + int mpd_port_m = atoi(mpd_port_env); + if (mpd_port_m == 0) { + DEBUG_PRINTF("Could not convert MPD_PORT to int.\n"); + return EXIT_FAILURE; + } else if (mpd_port_m < 0) { + DEBUG_PRINTF("Negative port?!\n"); + return EXIT_FAILURE; + } else { + mpd_port = mpd_port_m; + DEBUG_PRINTF("Using port %i\n", mpd_port); + } + } + + + struct mpd_connection *mpd_connection = mpd_connection_new(mpd_host, mpd_port, 1000); + if (mpd_connection == NULL) { + DEBUG_PRINTF("%s\n", "Could Not connect"); + return EXIT_FAILURE; + } + + if (mpd_password != NULL) { + bool authenticated = mpd_run_password(mpd_connection, mpd_password); + if (!authenticated) { + DEBUG_PRINTF("Failed to authenticate.\n"); + return EXIT_FAILURE; + } + } + + free(mpd_host_m); + free(mpd_password_m); + + bool sent_status = mpd_send_status(mpd_connection); + if (!sent_status) { + DEBUG_PRINTF("Could not send status request."); + return EXIT_FAILURE; + } + struct mpd_status *mpd_status = mpd_recv_status(mpd_connection); + if (mpd_status == NULL) { + DEBUG_PRINTF("Could not get mpd status.\n"); + return EXIT_FAILURE; + } + + enum mpd_state mpd_state = mpd_status_get_state(mpd_status); + DEBUG_PRINTF("State: "); + if (mpd_state == MPD_STATE_PLAY) { + DEBUG_PRINTF("Playing."); + } else if (mpd_state == MPD_STATE_PAUSE) { + DEBUG_PRINTF("Paused."); + } else if (mpd_state == MPD_STATE_UNKNOWN) { + DEBUG_PRINTF("Unknown state."); + } else if (mpd_state == MPD_STATE_STOP) { + DEBUG_PRINTF("Stopped."); + } + DEBUG_PRINTF("\n"); + + if (mpd_state != MPD_STATE_PLAY) { + // Nothing to do. + mpd_status_free(mpd_status); + mpd_connection_free(mpd_connection); + return EXIT_SUCCESS; + } + + int song_id = mpd_status_get_song_id(mpd_status); + DEBUG_PRINTF("songid = %i\n", song_id); + + mpd_status_free(mpd_status); + + struct mpd_song *song = mpd_run_get_queue_song_id(mpd_connection, song_id); + if (song == NULL) { + DEBUG_PRINTF("Could not get song.\n"); + return EXIT_FAILURE; + } + + const char *song_artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0); + if (song_artist == NULL) { + DEBUG_PRINTF("Could not get song artist."); + return EXIT_FAILURE; + } + + const char *song_title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0); + if (song_title == NULL) { + DEBUG_PRINTF("Could not get song title."); + return EXIT_FAILURE; + } + printf("%s - %s\n", song_artist, song_title); + + mpd_song_free(song); + mpd_connection_free(mpd_connection); + return EXIT_SUCCESS; +} diff --git a/segments/np_pithos.py b/segments/np_pithos.py new file mode 100755 index 0000000..9d022e6 --- /dev/null +++ b/segments/np_pithos.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +import dbus + +pithos_bus = dbus.SessionBus() + +pithos = pithos_bus.get_object('net.kevinmehall.Pithos', '/net/kevinmehall/Pithos') +props = pithos.get_dbus_method('GetCurrentSong', 'net.kevinmehall.Pithos') + +print props()["artist"] + " - " + props()["title"] diff --git a/segments/np_rdio_mac.script b/segments/np_rdio_mac.script new file mode 100755 index 0000000..d46bd0f --- /dev/null +++ b/segments/np_rdio_mac.script @@ -0,0 +1,20 @@ +#!/usr/bin/env osascript +# Returns the current playing song in Rdio for OS X. + +tell application "System Events" + set process_list to (name of every process) +end tell + +if process_list contains "Rdio" then + tell application "Rdio" + if player state is playing then + set track_name to name of current track + set artist_name to artist of current track + set album_name to album of current track + set now_playing to artist_name & " - " & track_name + # Uncomment if Album name is wanted + #set now_playing to now_playing & " - " & album_name + end if + end tell +end if + diff --git a/segments/np_spotify_mac.script b/segments/np_spotify_mac.script new file mode 100755 index 0000000..91fbb63 --- /dev/null +++ b/segments/np_spotify_mac.script @@ -0,0 +1,23 @@ +#!/usr/bin/env osascript +# Returns the current playing song in Spotify for OSX + +tell application "System Events" + set process_list to (name of every process) +end tell + +if process_list contains "Spotify" then + tell application "Spotify" + if player state is playing then + set track_name to name of current track + set artist_name to artist of current track + #set album_name to album of current track + set trim_length to 40 + set now_playing to artist_name & " - " & track_name + if length of now_playing is less than trim_length then + set now_playing_trim to now_playing + else + set now_playing_trim to characters 1 thru trim_length of now_playing as string + end if + end if + end tell +end if diff --git a/segments/pwd.sh b/segments/pwd.sh new file mode 100755 index 0000000..2499762 --- /dev/null +++ b/segments/pwd.sh @@ -0,0 +1,39 @@ +# Print the current working directory (trimmed to max length). +# NOTE The trimming code's stolen from the web. Courtesy to who ever wrote it. + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +TMUX_POWERLINE_SEG_PWD_MAX_LEN_DEFAULT="40" + +generate_segmentrc() { + read -d '' rccontents << EORC +# Maximum length of output. +export TMUX_POWERLINE_SEG_PWD_MAX_LEN="${TMUX_POWERLINE_SEG_PWD_MAX_LEN_DEFAULT}" +EORC + echo "$rccontents" +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_PWD_MAX_LEN" ]; then + export TMUX_POWERLINE_SEG_PWD_MAX_LEN="${TMUX_POWERLINE_SEG_PWD_MAX_LEN_DEFAULT}" + fi +} + +run_segment() { + __process_settings + # Truncate from the left. + tcwd=$(get_tmux_cwd) + trunc_symbol="···" + dir=${tcwd##*/} + local max_len="$TMUX_POWERLINE_SEG_PWD_MAX_LEN" + max_len=$(( ( max_len < ${#dir} ) ? ${#dir} : max_len )) + ttcwd=${tcwd/#$HOME/\~} + pwdoffset=$(( ${#ttcwd} - max_len )) + if [ ${pwdoffset} -gt "0" ]; then + ttcwd=${ttcwd:$pwdoffset:$max_len} + ttcwd=${trunc_symbol}/${ttcwd#*/} + fi + echo "$ttcwd" + return 0 +} diff --git a/segments/rainbarf.sh b/segments/rainbarf.sh new file mode 100755 index 0000000..a9c6c1f --- /dev/null +++ b/segments/rainbarf.sh @@ -0,0 +1,15 @@ +# Print out Memory and CPU using https://github.com/creaktive/rainbarf + +run_segment() { + type rainbarf >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + # Customize via ~/.rainbarf.conf + stats=$(rainbarf --tmux) + if [ -n "$stats" ]; then + echo "$stats"; + fi + return 0 +} diff --git a/segments/time.sh b/segments/time.sh new file mode 100755 index 0000000..e307399 --- /dev/null +++ b/segments/time.sh @@ -0,0 +1,23 @@ +# Prints the current time. + +TMUX_POWERLINE_SEG_TIME_FORMAT_DEFAULT="%H:%M" + +generate_segmentrc() { + read -d '' rccontents << EORC +# date(1) format for the time. Americans might want to have "%I:%M %p". +export TMUX_POWERLINE_SEG_TIME_FORMAT="${TMUX_POWERLINE_SEG_TIME_FORMAT_DEFAULT}" +EORC + echo "$rccontents" +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_TIME_FORMAT" ]; then + export TMUX_POWERLINE_SEG_TIME_FORMAT="${TMUX_POWERLINE_SEG_TIME_FORMAT_DEFAULT}" + fi +} + +run_segment() { + __process_settings + date +"$TMUX_POWERLINE_SEG_TIME_FORMAT" + return 0 +} diff --git a/segments/tmux_mem_cpu_load.sh b/segments/tmux_mem_cpu_load.sh new file mode 100755 index 0000000..c05be3e --- /dev/null +++ b/segments/tmux_mem_cpu_load.sh @@ -0,0 +1,14 @@ +# Print out Memory, cpu and load using https://github.com/thewtex/tmux-mem-cpu-load + +run_segment() { + type tmux-mem-cpu-load >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + stats=$(tmux-mem-cpu-load) + if [ -n "$stats" ]; then + echo "$stats"; + fi + return 0 +} diff --git a/segments/tmux_session_info.sh b/segments/tmux_session_info.sh new file mode 100755 index 0000000..fbfddc2 --- /dev/null +++ b/segments/tmux_session_info.sh @@ -0,0 +1,7 @@ +# Prints tmux session info. +# Assuems that [ -n "$TMUX"]. + +run_segment() { + tmux display-message -p '#S' + return 0 +} diff --git a/segments/uptime.sh b/segments/uptime.sh new file mode 100755 index 0000000..276cfbe --- /dev/null +++ b/segments/uptime.sh @@ -0,0 +1,6 @@ +# Prints the uptime. + +run_segment() { + uptime | grep -PZo "(?<=up )[^,]*" + return 0 +} diff --git a/segments/utc_time.sh b/segments/utc_time.sh new file mode 100755 index 0000000..4da6149 --- /dev/null +++ b/segments/utc_time.sh @@ -0,0 +1,6 @@ +# Prints the current time in UTC. + +run_segment() { + date -u +"%H:%M" + return 0 +} diff --git a/segments/vcs_branch.sh b/segments/vcs_branch.sh new file mode 100755 index 0000000..f8d973d --- /dev/null +++ b/segments/vcs_branch.sh @@ -0,0 +1,90 @@ +# Prints current branch in a VCS directory if it could be detected. + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +branch_symbol="⭠" +git_colour="5" +svn_colour="220" +hg_colour="45" + + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + branch="" + if [ -n "${git_branch=$(__parse_git_branch)}" ]; then + branch="$git_branch" + elif [ -n "${svn_branch=$(__parse_svn_branch)}" ]; then + branch="$svn_branch" + elif [ -n "${hg_branch=$(__parse_hg_branch)}" ]; then + branch="$hg_branch" + fi + + if [ -n "$branch" ]; then + echo "${branch}" + fi + return 0 +} + + +# Show git banch. +__parse_git_branch() { + type git >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + #git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \[\1\]/' + + # Quit if this is not a Git repo. + branch=$(git symbolic-ref HEAD 2> /dev/null) + if [[ -z $branch ]] ; then + # attempt to get short-sha-name + branch=":$(git rev-parse --short HEAD 2> /dev/null)" + fi + if [ "$?" -ne 0 ]; then + # this must not be a git repo + return + fi + + # Clean off unnecessary information. + branch=${branch##*/} + + echo -n "#[fg=colour${git_colour}]${branch_symbol} #[fg=colour${TMUX_POWERLINE_CUR_SEGMENT_FG}]${branch}" +} + +# Show SVN branch. +__parse_svn_branch() { + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + local svn_info=$(svn info 2>/dev/null) + if [ -z "${svn_info}" ]; then + return + fi + + + local svn_root=$(echo "${svn_info}" | sed -ne 's#^Repository Root: ##p') + local svn_url=$(echo "${svn_info}" | sed -ne 's#^URL: ##p') + + local branch=$(echo "${svn_url}" | egrep -o '[^/]+$') + echo "#[fg=colour${svn_colour}]${branch_symbol} #[fg=colour${TMUX_POWERLINE_CUR_SEGMENT_FG}]${branch}" +} + +__parse_hg_branch() { + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + summary=$(hg summary) + if [ "$?" -ne 0 ]; then + return + fi + + local branch=$(echo "$summary" | grep 'branch:' | cut -d ' ' -f2) + echo "#[fg=colour${hg_colour}]${branch_symbol} #[fg=colour${TMUX_POWERLINE_CUR_SEGMENT_FG}]${branch}" +} diff --git a/segments/vcs_compare.sh b/segments/vcs_compare.sh new file mode 100755 index 0000000..988751c --- /dev/null +++ b/segments/vcs_compare.sh @@ -0,0 +1,68 @@ +# This checks if the current branch is ahead of +# or behind the remote branch with which it is tracked + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +flat_symbol="⤚" + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + stats="" + if [ -n "${git_stats=$(__parse_git_stats)}" ]; then + stats="$git_stats" + elif [ -n "${svn_stats=$(__parse_svn_stats)}" ]; then + stats="$svn_stats" + elif [ -n "${hg_stats=$(__parse_hg_stats)}" ]; then + stats="$hg_stats" + fi + + if [ -n "$stats" ]; then + echo "${stats}" + fi + return 0 +} + +__parse_git_stats() { + type git >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + # check if git + [[ -z $(git rev-parse --git-dir 2> /dev/null) ]] && return + + tracking_branch=$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) + + # creates global variables $1 and $2 based on left vs. right tracking + set -- $(git rev-list --left-right --count $tracking_branch...HEAD) + + behind=$1 + ahead=$2 + + # print out the information + if [[ $behind -gt 0 ]] ; then + local ret="↓ $behind" + fi + if [[ $ahead -gt 0 ]] ; then + local ret="${ret}↑ $ahead" + fi + echo "$ret" +} + +__parse_hg_stats() { + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} + +__parse_svn_stats() { + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} diff --git a/segments/vcs_modified.sh b/segments/vcs_modified.sh new file mode 100755 index 0000000..ebec1f4 --- /dev/null +++ b/segments/vcs_modified.sh @@ -0,0 +1,70 @@ +# This checks if the current branch is ahead of +# or behind the remote branch with which it is tracked + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +mod_symbol="﹢" + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + + stats="" + if [ -n "${git_stats=$(__parse_git_stats)}" ]; then + stats="$git_stats" + elif [ -n "${svn_stats=$(__parse_svn_stats)}" ]; then + stats="$svn_stats" + elif [ -n "${hg_stats=$(__parse_hg_stats)}" ]; then + stats="$hg_stats" + fi + if [[ -n "$stats" && $stats -gt 0 ]]; then + echo "${mod_symbol}${stats}" + fi +} + +__parse_git_stats(){ + type git >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + # check if git + [[ -z $(git rev-parse --git-dir 2> /dev/null) ]] && return + + # return the number of staged items + staged=$(git ls-files --modified | wc -l) + echo $staged +} +__parse_hg_stats(){ + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} +__parse_svn_stats() { + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + local svn_info=$(svn info 2>/dev/null) + if [ -z "${svn_info}" ]; then + return + fi + + local svn_wcroot=$(echo "${svn_info}" | sed -ne 's#^Working Copy Root Path: ##p') + local svn_st=$(cd "${svn_wcroot}"; svn st) + local modified=$(echo "${svn_st}" | egrep '^M' | wc -l) + local conflicted=$(echo "${svn_st}" | egrep '^!?\s*C' | wc -l) + + #print + if [[ $modified -gt 0 ]] ; then + local ret="#[fg=colour${TMUX_POWERLINE_CUR_SEGMENT_FG}]±${modified}" + fi + if [[ $conflicted -gt 0 ]] ; then + local ret="#[fg=colour${svn_colour}]ϟ${conflicted} ${ret}" + fi + echo "${ret}" +} diff --git a/segments/vcs_others.sh b/segments/vcs_others.sh new file mode 100755 index 0000000..0911468 --- /dev/null +++ b/segments/vcs_others.sh @@ -0,0 +1,51 @@ +# This checks if the current branch is ahead of or behind the remote branch with which it is tracked. + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +other_symbol="⋯ " + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + stats="" + if [ -n "${git_stats=$(__parse_git_stats)}" ]; then + stats="$git_stats" + elif [ -n "${svn_stats=$(__parse_svn_stats)}" ]; then + stats="$svn_stats" + elif [ -n "${hg_stats=$(__parse_hg_stats)}" ]; then + stats="$hg_stats" + fi + if [[ -n "$stats" && $stats -gt 0 ]]; then + echo "${other_symbol}${stats}" + fi + return 0 +} + +__parse_git_stats(){ + type git >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + # check if git + [[ -z $(git rev-parse --git-dir 2> /dev/null) ]] && return + + # return the number of staged items + other=$(git ls-files --others --exclude-standard | wc -l) + echo $other +} +__parse_hg_stats(){ + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} +__parse_svn_stats(){ + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} diff --git a/segments/vcs_revision.sh b/segments/vcs_revision.sh new file mode 100755 index 0000000..0ff0f74 --- /dev/null +++ b/segments/vcs_revision.sh @@ -0,0 +1,43 @@ +# This prints the vcs revision in the working directory +# currently only used in SVN + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + + stats="" + if [[ -n "${svn_stats=$(__parse_svn_stats)}" ]]; then + stats="$svn_stats" + elif [[ -n "${hg_stats=$(__parse_hg_stats)}" ]]; then + stats="$hg_stats" + fi + if [[ -n "$stats" ]]; then + echo "${stats}" + fi +} + +__parse_hg_stats(){ + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} +__parse_svn_stats(){ + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + local svn_info=$(svn info 2>/dev/null) + if [ -z "${svn_info}" ]; then + return + fi + + local svn_ref=$(echo "${svn_info}" | sed -ne 's#^Revision: ##p') + + echo "r${svn_ref}" +} diff --git a/segments/vcs_staged.sh b/segments/vcs_staged.sh new file mode 100755 index 0000000..8818b3c --- /dev/null +++ b/segments/vcs_staged.sh @@ -0,0 +1,57 @@ +# This checks if the current branch is ahead of +# or behind the remote branch with which it is tracked + +# Source lib to get the function get_tmux_pwd +source "${TMUX_POWERLINE_DIR_LIB}/tmux_adapter.sh" + +staged_symbol="⊕ " + +run_segment() { + tmux_path=$(get_tmux_cwd) + cd "$tmux_path" + + stats="" + if [ -n "${git_stats=$(__parse_git_stats)}" ]; then + stats="$git_stats" + elif [ -n "${svn_stats=$(__parse_svn_stats)}" ]; then + stats="$svn_stats" + elif [ -n "${hg_stats=$(__parse_hg_stats)}" ]; then + stats="$hg_stats" + fi + if [[ -n "$stats" && $stats -gt 0 ]]; then + stats=$(echo $stats | sed -e "s/^[ \t]*//") + echo "${staged_symbol}${stats}" + fi + return 0 +} + + +__parse_git_stats(){ + type git >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + + # Check if git. + [[ -z $(git rev-parse --git-dir 2> /dev/null) ]] && return + + # Return the number of staged items. + staged=$(git diff --staged --name-status | wc -l) + echo "$staged" +} + +__parse_hg_stats(){ + type svn >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} + +__parse_svn_stats(){ + type hg >/dev/null 2>&1 + if [ "$?" -ne 0 ]; then + return + fi + # not yet implemented +} diff --git a/segments/wan_ip.sh b/segments/wan_ip.sh new file mode 100755 index 0000000..811d100 --- /dev/null +++ b/segments/wan_ip.sh @@ -0,0 +1,43 @@ +# Prints the WAN IP address. The result is cached and updated according to $update_period. + +run_segment() { + local tmp_file="${TMUX_POWERLINE_DIR_TEMPORARY}/wan_ip.txt" + local wan_ip + + if [ -f "$tmp_file" ]; then + if shell_is_osx || shell_is_bsd; then + stat >/dev/null 2>&1 && is_gnu_stat=false || is_gnu_stat=true + if [ "$is_gnu_stat" == "true" ];then + last_update=$(stat -c "%Y" ${tmp_file}) + else + last_update=$(stat -f "%m" ${tmp_file}) + fi + elif shell_is_linux || [ -z $is_gnu_stat]; then + last_update=$(stat -c "%Y" ${tmp_file}) + fi + + time_now=$(date +%s) + update_period=900 + up_to_date=$(echo "(${time_now}-${last_update}) < ${update_period}" | bc) + + if [ "$up_to_date" -eq 1 ]; then + wan_ip=$(cat ${tmp_file}) + fi + fi + + if [ -z "$wan_ip" ]; then + wan_ip=$(curl --max-time 2 -s http://whatismyip.akamai.com/) + + if [ "$?" -eq "0" ]; then + echo "${wan_ip}" > $tmp_file + elif [ -f "${tmp_file}" ]; then + wan_ip=$(cat "$tmp_file") + fi + fi + + if [ -n "$wan_ip" ]; then + echo "ⓦ ${wan_ip}" + fi + + return 0 +} diff --git a/segments/weather.sh b/segments/weather.sh new file mode 100755 index 0000000..74e352e --- /dev/null +++ b/segments/weather.sh @@ -0,0 +1,182 @@ +# Prints the current weather in Celsius, Fahrenheits or lord Kelvins. The forecast is cached and updated with a period of $update_period. + +# The update period in seconds. +update_period=600 + +TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER_DEFAULT="yahoo" +TMUX_POWERLINE_SEG_WEATHER_UNIT_DEFAULT="c" +TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD_DEFAULT="600" +if shell_is_bsd; then + TMUX_POWERLINE_SEG_WEATHER_GREP_DEFAULT="/usr/local/bin/grep" +else + TMUX_POWERLINE_SEG_WEATHER_GREP_DEFAULT="grep" +fi + + +generate_segmentrc() { + read -d '' rccontents << EORC +# The data provider to use. Currently only "yahoo" is supported. +export TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER="${TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER_DEFAULT}" +# What unit to use. Can be any of {c,f,k}. +export TMUX_POWERLINE_SEG_WEATHER_UNIT="${TMUX_POWERLINE_SEG_WEATHER_UNIT_DEFAULT}" +# How often to update the weather in seconds. +export TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD_DEFAULT}" +# Name of GNU grep binary if in PATH, or path to it. +export TMUX_POWERLINE_SEG_WEATHER_GREP="${TMUX_POWERLINE_SEG_WEATHER_GREP_DEFAULT}" + +# Your location. Find a code that works for you: +# 1. Go to Yahoo weather http://weather.yahoo.com/ +# 2. Find the weather for you location +# 3. Copy the last numbers in that URL. e.g. "http://weather.yahoo.com/united-states/california/newport-beach-12796587/" has the numbers "12796587" +export TMUX_POWERLINE_SEG_WEATHER_LOCATION="8691" +EORC + echo "$rccontents" +} + +run_segment() { + __process_settings + local tmp_file="${TMUX_POWERLINE_DIR_TEMPORARY}/weather_yahoo.txt" + local weather + case "$TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER" in + "yahoo") weather=$(__yahoo_weather) ;; + *) + echo "Unknown weather provider [${$TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER}]"; + return 1 + esac + if [ -n "$weather" ]; then + echo "$weather" + fi +} + +__process_settings() { + if [ -z "$TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER" ]; then + export TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER="${TMUX_POWERLINE_SEG_WEATHER_DATA_PROVIDER_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_WEATHER_UNIT" ]; then + export TMUX_POWERLINE_SEG_WEATHER_UNIT="${TMUX_POWERLINE_SEG_WEATHER_UNIT_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD" ]; then + export TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD="${TMUX_POWERLINE_SEG_WEATHER_UPDATE_PERIOD_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_WEATHER_GREP" ]; then + export TMUX_POWERLINE_SEG_WEATHER_GREP="${TMUX_POWERLINE_SEG_WEATHER_GREP_DEFAULT}" + fi + if [ -z "$TMUX_POWERLINE_SEG_WEATHER_LOCATION" ]; then + echo "No weather location specified."; + exit 8 + fi +} + +__yahoo_weather() { + degree="" + if [ -f "$tmp_file" ]; then + if shell_is_osx || shell_is_bsd; then + last_update=$(stat -f "%m" ${tmp_file}) + elif shell_is_linux; then + last_update=$(stat -c "%Y" ${tmp_file}) + fi + time_now=$(date +%s) + + up_to_date=$(echo "(${time_now}-${last_update}) < ${update_period}" | bc) + if [ "$up_to_date" -eq 1 ]; then + __read_tmp_file + fi + fi + + if [ -z "$degree" ]; then + weather_data=$(curl --max-time 4 -s "http://weather.yahooapis.com/forecastrss?w=${TMUX_POWERLINE_SEG_WEATHER_LOCATION}&u=${TMUX_POWERLINE_SEG_WEATHER_UNIT}") + if [ "$?" -eq "0" ]; then + error=$(echo "$weather_data" | grep "problem_cause\|DOCTYPE"); + if [ -n "$error" ]; then + echo "error" + exit 1 + fi + + # Assume latest grep is in PATH + gnugrep="${TMUX_POWERLINE_SEG_WEATHER_GREP}" + + # <yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/> + unit=$(echo "$weather_data" | "$gnugrep" -PZo "<yweather:units [^<>]*/>" | sed 's/.*temperature="\([^"]*\)".*/\1/') + condition=$(echo "$weather_data" | "$gnugrep" -PZo "<yweather:condition [^<>]*/>") + # <yweather:condition text="Clear" code="31" temp="66" date="Mon, 01 Oct 2012 8:00 pm CST" /> + degree=$(echo "$condition" | sed 's/.*temp="\([^"]*\)".*/\1/') + condition=$(echo "$condition" | sed 's/.*text="\([^"]*\)".*/\1/') + # Pull the times for sunrise and sunset so we know when to change the day/night indicator + # <yweather:astronomy sunrise="6:56 am" sunset="6:21 pm"/> + sunrise=$(date -d"$(echo "$weather_data" | "$gnugrep" "yweather:astronomy" | sed 's/^\(.*\)sunset.*/\1/' | sed 's/^.*sunrise="\(.*m\)".*/\1/')" +%H%M) + sunset=$(date -d"$(echo "$weather_data" | "$gnugrep" "yweather:astronomy" | sed 's/^.*sunset="\(.*m\)".*/\1/')" +%H%M) + elif [ -f "${tmp_file}" ]; then + __read_tmp_file + fi + fi + + if [ -n "$degree" ]; then + if [ "$TMUX_POWERLINE_SEG_WEATHER_UNIT" == "k" ]; then + degree=$(echo "${degree} + 273.15" | bc) + fi + condition_symbol=$(__get_condition_symbol "$condition" "$sunrise" "$sunset") + echo "${condition_symbol} ${degree}°$(echo "$TMUX_POWERLINE_SEG_WEATHER_UNIT" | tr '[:lower:]' '[:upper:]')" | tee "${tmp_file}" + fi +} + +# Get symbol for condition. Available conditions: http://developer.yahoo.com/weather/#codes +__get_condition_symbol() { + local condition=$(echo "$1" | tr '[:upper:]' '[:lower:]') + local sunrise="$2" + local sunset="$3" + case "$condition" in + "sunny" | "hot") + hourmin=$(date +%H%M) + if [ "$hourmin" -ge "$sunset" -o "$hourmin" -le "$sunrise" ]; then + #echo "☽" + echo "☾" + else + #echo "☀" + echo "☼" + fi + ;; + "rain" | "mixed rain and snow" | "mixed rain and sleet" | "freezing drizzle" | "drizzle" | "light drizzle" | "freezing rain" | "showers" | "mixed rain and hail" | "scattered showers" | "isolated thundershowers" | "thundershowers" | "light rain with thunder" | "light rain" | "rain and snow") + #echo "☂" + echo "☔" + ;; + "snow" | "mixed snow and sleet" | "snow flurries" | "light snow showers" | "blowing snow" | "sleet" | "hail" | "heavy snow" | "scattered snow showers" | "snow showers" | "light snow" | "snow/windy" | "snow grains" | "snow/fog") + #echo "☃" + echo "❅" + ;; + "cloudy" | "mostly cloudy" | "partly cloudy" | "partly cloudy/windy") + echo "☁" + ;; + "tornado" | "tropical storm" | "hurricane" | "severe thunderstorms" | "thunderstorms" | "isolated thunderstorms" | "scattered thunderstorms") + #echo "⚡" + echo "☈" + ;; + "dust" | "foggy" | "fog" | "haze" | "smoky" | "blustery" | "mist") + #echo "♨" + #echo "﹌" + echo "〰" + ;; + "windy" | "fair/windy") + #echo "⚐" + echo "⚑" + ;; + "clear" | "fair" | "cold") + hourmin=$(date +%H%M) + if [ "$hourmin" -ge "$sunset" -o "$hourmin" -le "$sunrise" ]; then + echo "☾" + else + echo "〇" + fi + ;; + *) + echo "?" + ;; + esac +} + +__read_tmp_file() { + if [ ! -f "$tmp_file" ]; then + return + fi + cat "${tmp_file}" + exit +} diff --git a/segments/xkb_layout.c b/segments/xkb_layout.c new file mode 100644 index 0000000..7c94f96 --- /dev/null +++ b/segments/xkb_layout.c @@ -0,0 +1,64 @@ +/* xkb_layout + * Description: + * This program will connect to the X Server and print the id of the currently + * active keyboard layout. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <X11/XKBlib.h> + +#ifdef DEBUG + #define DO_DEBUG DEBUG +#else + #define DO_DEBUG 0 +#endif +#define DEBUG_PRINTF(...) do{ if (DO_DEBUG) { printf(__VA_ARGS__);} } while(0) + +int main() { + // Get X display + char *displayName = ""; + int eventCode; + int errorReturn; + int major = XkbMajorVersion; + int minor = XkbMinorVersion;; + int reasonReturn; + Display *_display = XkbOpenDisplay(displayName, &eventCode, &errorReturn, + &major, &minor, &reasonReturn); + bool error = false; + switch (reasonReturn) { + case XkbOD_BadLibraryVersion: + DEBUG_PRINTF("Bad XKB library version.\n"); + error = true; + break; + case XkbOD_ConnectionRefused: + DEBUG_PRINTF("Connection to X server refused.\n"); + error = true; + break; + case XkbOD_BadServerVersion: + DEBUG_PRINTF("Bad X11 server version.\n"); + error = true; + break; + case XkbOD_NonXkbServer: + DEBUG_PRINTF("XKB not present.\n"); + error = true; + break; + case XkbOD_Success: + break; + } + + if (error) { + return EXIT_FAILURE; + } + + // Get current state of keyboard. + int _deviceId = XkbUseCoreKbd; + XkbStateRec xkbState; + XkbGetState(_display, _deviceId, &xkbState); + // print the groupnumber, may be used with setxkbmap -query to get name + // of current layout + printf("%d\n", xkbState.group); + return 0; + return EXIT_SUCCESS; +} diff --git a/segments/xkb_layout.sh b/segments/xkb_layout.sh new file mode 100755 index 0000000..c8f38c1 --- /dev/null +++ b/segments/xkb_layout.sh @@ -0,0 +1,32 @@ +# Print the currently used keyboard layout +# This depends on a specifically developed program which prints the group id of +# the currently used layout. +# I developed the simple program myself with some guidance as I was unable to +# find anything already developed. +# Some people might suggest: +# $ setxkbmod -query -v | awk -F "+" '{print $2}' +# this will only work if you have set up XKB with a single layout which is true +# for some. + +# This script will print the correct layout even if layout is set per window. +# Exit if platform is not linux as this script is dependant on X11 + +run_segment() { + if ! shell_is_linux; then + return 1 + fi + + cd "$TMUX_POWERLINE_DIR_SEGMENTS" + if [ ! -x "xkb_layout" ]; then + make clean xkb_layout &>/dev/null + fi + + if [ -x ./xkb_layout ]; then + cur_layout_nbr=$(($(./xkb_layout)+1)); + cur_layout=$(setxkbmap -query | grep layout | sed 's/layout:\s\+//g' | \ + awk -F ',' '{print $'$(echo "$cur_layout_nbr")'}') + echo "⌨ $cur_layout" + else + return 1 + fi +} diff --git a/themes/default.sh b/themes/default.sh new file mode 100644 index 0000000..6ef5e55 --- /dev/null +++ b/themes/default.sh @@ -0,0 +1,62 @@ +# Default Theme + +#if patched_font_in_use; then + #TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="⮂" + #TMUX_POWERLINE_SEPARATOR_LEFT_THIN="⮃" + #TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="⮀" + #TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="⮁" +#else + #TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="◀" + #TMUX_POWERLINE_SEPARATOR_LEFT_THIN="❮" + #TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="▶" + #TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="❯" +#fi +TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="" #Byte code for zero width space to make the segments into bars instead of arrows +TMUX_POWERLINE_SEPARATOR_LEFT_THIN="" +TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="" +TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="" + +TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR:-'235'} +TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR:-'255'} + +TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD} +TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_LEFT_BOLD} + + +# Format: segment_name background_color foreground_color [non_default_separator] + +if [ -z $TMUX_POWERLINE_LEFT_STATUS_SEGMENTS ]; then + TMUX_POWERLINE_LEFT_STATUS_SEGMENTS=( + "tmux_session_info 26 253" + "hostname 6 253" \ + #"ifstat 30 255" \ + #"ifstat_sys 30 255" \ + #"vcs_branch 29 88" \ + #"vcs_compare 60 255" \ + #"vcs_staged 64 255" \ + #"vcs_modified 9 255" \ + #"vcs_others 245 0" \ + ) +fi + +if [ -z $TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS ]; then + TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS=( + #"earthquake 3 0" \ + "pwd 89 211" \ + "mailcount 9 255" \ + "now_playing 234 37" \ + #"cpu 240 136" \ + #"load 237 167" \ + #"tmux_mem_cpu_load 234 136" \ + #"battery 137 127" \ + #"weather 37 255" \ + #"rainbarf 0 0" \ + #"xkb_layout 125 117" \ + "lan_ip 24 255" \ + "wan_ip 24 255" \ + "date_day 235 136" \ + "date 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + "time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + #"utc_time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + ) +fi diff --git a/themes/default.sh.bak b/themes/default.sh.bak new file mode 100644 index 0000000..ae7a063 --- /dev/null +++ b/themes/default.sh.bak @@ -0,0 +1,58 @@ +# Default Theme + +if patched_font_in_use; then + TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="⮂" + TMUX_POWERLINE_SEPARATOR_LEFT_THIN="⮃" + TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="⮀" + TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="⮁" +else + TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="◀" + TMUX_POWERLINE_SEPARATOR_LEFT_THIN="❮" + TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="▶" + TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="❯" +fi + +TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR:-'235'} +TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR:-'255'} + +TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD} +TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_LEFT_BOLD} + + +# Format: segment_name background_color foreground_color [non_default_separator] + +if [ -z $TMUX_POWERLINE_LEFT_STATUS_SEGMENTS ]; then + TMUX_POWERLINE_LEFT_STATUS_SEGMENTS=( + "tmux_session_info 148 234" \ + "hostname 33 0" \ + #"ifstat 30 255" \ + #"ifstat_sys 30 255" \ + "lan_ip 24 255 ${TMUX_POWERLINE_SEPARATOR_RIGHT_THIN}" \ + "wan_ip 24 255" \ + "vcs_branch 29 88" \ + "vcs_compare 60 255" \ + "vcs_staged 64 255" \ + "vcs_modified 9 255" \ + "vcs_others 245 0" \ + ) +fi + +if [ -z $TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS ]; then + TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS=( + #"earthquake 3 0" \ + "pwd 89 211" \ + "mailcount 9 255" \ + "now_playing 234 37" \ + #"cpu 240 136" \ + "load 237 167" \ + #"tmux_mem_cpu_load 234 136" \ + "battery 137 127" \ + "weather 37 255" \ + #"rainbarf 0 0" \ + #"xkb_layout 125 117" \ + "date_day 235 136" \ + "date 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + "time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + #"utc_time 235 136 ${TMUX_POWERLINE_SEPARATOR_LEFT_THIN}" \ + ) +fi diff --git a/tmux.config b/tmux.config new file mode 100644 index 0000000..68988ad --- /dev/null +++ b/tmux.config @@ -0,0 +1,99 @@ +# Use Ctrl A instead of Ctrl b +#unbind C-b +#set -g prefix C-x + +# Resize pane single keys +bind-key + resize-pane -D 20 +bind-key - resize-pane -U 20 +bind-key / resize-pane -L 20 +bind-key * resize-pane -R 20 + +# Vim movements +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Kill without prompting +bind-key x kill-pane +bind-key & kill-window + +# Help with the color problems +set -g default-terminal "xterm" + +#Mouse Scrolling +set-window-option -g mode-mouse on + +# Mouse window resizing +set -g mouse-resize-pane on +set -g mouse-select-pane on +set -g mouse-select-window on + +#Use vim keybindings in copy mode +setw -g mode-keys vi + +# Setup 'v' to begin selection as in Vim +bind-key -t vi-copy v begin-selection +bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy" + +# Update default binding of `Enter` to also use copy-pipe +unbind -t vi-copy Enter +bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy" + +# Set the display panes timeout +set-option -g display-panes-time 4000 + +# Change binding for display panes +bind-key b display-panes + +# Allow pbcopy inside of session +set-option -g default-command "reattach-to-user-namespace -l zsh" + + + +#### COLOUR (Solarized dark) + +## default statusbar colors +set-option -g status-bg colour19 #base02 +set-option -g status-fg colour253 #yellow +#set-option -g status-attr default + +## default window title colors +#set-window-option -g window-status-fg colour20 #base0 +#set-window-option -g window-status-bg default +##set-window-option -g window-status-attr dim + +## active window title colors +#set-window-option -g window-status-current-fg colour44 #orange +#set-window-option -g window-status-current-bg default +##set-window-option -g window-status-current-attr bright + +## pane border +##set-option -g pane-border-fg colour235 #base02 +##set-option -g pane-active-border-fg colour46 #base01 +set-option -g pane-border-fg colour23 #base02 +set-option -g pane-active-border-fg colour23 #base01 + + +## message text +set-option -g message-bg colour235 #base02 +set-option -g message-fg colour196 #orange + +## pane number display +#set-option -g display-panes-active-colour colour160 #blue +#set-option -g display-panes-colour colour15 #orange + +## clock +#set-window-option -g clock-mode-colour colour40 #green + +set-option -g status on +set-option -g status-interval 2 +set-option -g status-utf8 on +set-option -g status-justify "centre" +set-option -g status-left-length 110 +set-option -g status-right-length 90 +set-option -g status-left "#(~/.tmux/powerline.sh left)" +set-option -g status-right "#(~/.tmux/powerline.sh right)" + +# Make the escape faster +set -s escape-time 0 diff --git a/tmuxomatic/dashboard b/tmuxomatic/dashboard new file mode 100644 index 0000000..710d340 --- /dev/null +++ b/tmuxomatic/dashboard @@ -0,0 +1,30 @@ +##------------------------------------------------------------------------------ +## +## Session file created by tmuxomatic flex 2.4 +## +##------------------------------------------------------------------------------ + +## Window added by tmuxomatic flex 2.4 + +window Workspace + +11111112222222222222222222 +11111112222222222222222222 +11111112222222222222222222 +11111112222222222222222222 +ggggggg2222222222222222222 +ggggggg2222222222222222222 +ggggggg2222222222222222222 +ggggggg2222222222222222222 +aaaaaaa2222222222222222222 +aaaaaaa2222222222222222222 +aaaaaaa2222222222222222222 +aaaaaaa2222222222222222222 +ttttttt2222222222222222222 + + dir ~ + #5 run command + 1 run ~/.dotfiles/scripts/jira_active.sh + g run ~/.dotfiles/scripts/jira_waiting.sh + t run ~/.dotfiles/scripts/file_check.sh + |