Compare commits
87 Commits
newi3
...
7cf33dc7a3
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cf33dc7a3 | |||
| 0f8362fb68 | |||
| 1b0c9b6e6a | |||
| c70ddcf2a2 | |||
| c379d8e714 | |||
| e8e1dc77fe | |||
| 4c1daf109d | |||
| 79cae3e93b | |||
| a9f4901e25 | |||
| 55a06db3fe | |||
| 84afe0a158 | |||
| 7e2832532f | |||
| 6e9996f0de | |||
| 1e5594721c | |||
| 40fc4b6e0c | |||
| c85812479d | |||
| f0fc5d1d88 | |||
| ca6b02e14b | |||
| 3abb253457 | |||
| 740729834a | |||
| b37976611b | |||
| 6f6dd21aaf | |||
| 6b5912091c | |||
| bd00a604bd | |||
| 380cb65dff | |||
| ef6bd41684 | |||
| 6889b32037 | |||
| fb4fe04c12 | |||
| 7087d7c876 | |||
| 593fc07c77 | |||
| 295f5b95a2 | |||
| 809d0eb37e | |||
| 4e0bd16800 | |||
| 129748fd8c | |||
| 73c948b25c | |||
| f41b947fc5 | |||
| 5aee564810 | |||
| 7b43075070 | |||
| adef40b760 | |||
| 49b3e061e0 | |||
| 94129da2ed | |||
| d5422a0695 | |||
| e6dc178e4d | |||
| b21211fc2b | |||
| b09891fd04 | |||
| 4d8e0d1f97 | |||
| f0fa3d9c06 | |||
| 179f9d96b2 | |||
| 39add5548b | |||
| 1dacfd4c3f | |||
| 07f006c37d | |||
| 0f7d4db0a3 | |||
|
|
827870bc01 | ||
|
|
c63af798fe | ||
|
|
a57aa206aa | ||
|
|
3ad338dbe4 | ||
|
|
c4e760d5e7 | ||
|
|
5195ae47bc | ||
| 5d1b35f18a | |||
|
|
0609c7cdc9 | ||
|
|
2b0de46869 | ||
|
|
5a882d1fae | ||
| 0359fac5bd | |||
| 05ece594ad | |||
| c6f48faff0 | |||
| 1367be34be | |||
| b8bf0c0f61 | |||
|
|
fb73f5342d | ||
|
|
106f9fe47f | ||
|
|
9097a98884 | ||
|
|
9f5078611c | ||
|
|
a86415f264 | ||
|
|
2f31eef54b | ||
| 14c346d8b1 | |||
| f31e3dd7dc | |||
| 8442b2b154 | |||
|
|
98cfe87cad | ||
|
|
73b7a7561a | ||
| e8420af927 | |||
| 88daa7e088 | |||
|
|
cc817e998f | ||
| c0d719ab78 | |||
| f3d47aaa31 | |||
| 6e86609086 | |||
| 481b19c5ce | |||
| 31c86dda7d | |||
| 84381b084a |
147
.bash_prompt.kuba
Normal file
147
.bash_prompt.kuba
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/bin/bash
|
||||
|
||||
format_modified_detailed() {
|
||||
local txtrst='\e[m'
|
||||
local txtred='\e[0;31m'
|
||||
local txtgrn='\e[0;32m'
|
||||
local txtyel='\e[0;33m'
|
||||
|
||||
# Modified, staged and untracked
|
||||
# A added (new file) M modified, D deleted, R renamed, T typechange
|
||||
stat="$(git status --porcelain 2>/dev/null)"
|
||||
n_sta=""
|
||||
n_mod=""
|
||||
for i in A M D R T; do
|
||||
c=$(echo "$stat" | grep "^[$i]" | wc -l)
|
||||
[ "$c" != "0" ] && n_sta="$n_sta$i$c"
|
||||
c=$(echo "$stat" | grep "^ [$i]" | wc -l)
|
||||
[ "$c" != "0" ] && n_mod="$n_mod$i$c"
|
||||
done
|
||||
n_unt=$(echo "$stat" | grep "??" | wc -l)
|
||||
|
||||
out=""
|
||||
[ ! -z "$n_sta" ] && out+="\[$txtgrn\]+$n_sta\[$txtrst\]"
|
||||
[ ! -z "$n_mod" ] && out+="\[$txtred\]*$n_mod\[$txtrst\]"
|
||||
[ ! -z "$n_unt" ] && out+="\[$txtyel\]^$n_unt\[$txtrst\]"
|
||||
echo "$out"
|
||||
}
|
||||
|
||||
format_modified() {
|
||||
local txtrst='\e[m'
|
||||
local txtred='\e[0;31m'
|
||||
local txtgrn='\e[0;32m'
|
||||
local txtyel='\e[0;33m'
|
||||
|
||||
# Modified, staged and untracked
|
||||
# A added (new file) M modified, D deleted, R renamed, T typechange
|
||||
stat="$(git status --porcelain 2>/dev/null)"
|
||||
n_sta=$(echo "$stat" | grep "^[AMDRT]" | wc -l)
|
||||
n_mod=$(echo "$stat" | grep "^ [AMDRT]" | wc -l)
|
||||
n_unt=$(echo "$stat" | grep "??" | wc -l)
|
||||
|
||||
out=""
|
||||
[ "$n_sta" != 0 ] && out+="\[$txtgrn\]+$n_sta\[$txtrst\]"
|
||||
[ "$n_mod" != 0 ] && out+="\[$txtred\]*$n_mod\[$txtrst\]"
|
||||
[ "$n_unt" != 0 ] && out+="\[$txtyel\]^$n_unt\[$txtrst\]"
|
||||
echo "$out"
|
||||
}
|
||||
|
||||
set_prompt_fancy()
|
||||
{
|
||||
local is_git="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
|
||||
|
||||
local last_cmd=$?
|
||||
local txtrst='\e[m'
|
||||
local txtbold='\e[1m'
|
||||
local txtblk='\e[30m'
|
||||
local txtred='\e[31m'
|
||||
local txtgrn='\e[32m'
|
||||
local txtyel='\e[33m'
|
||||
local txtblu='\e[34m'
|
||||
local txtpur='\e[35m'
|
||||
local txtcyn='\e[36m'
|
||||
local txtwht='\e[37m'
|
||||
# unicode "✗"
|
||||
local fancyx='\342\234\227'
|
||||
# unicode "✓"
|
||||
local checkmark='\342\234\223'
|
||||
# Line 1: Full date + full time (24h)
|
||||
# Line 2: current path
|
||||
PS1="\[$txtbold\]\[$txtwht\]\n\D{%A %d %B %Y %H:%M:%S}\n\[$txtgrn\]\w\n"
|
||||
# Line 3: Git repo + path in repo
|
||||
if [ "$is_git" ]; then
|
||||
local git_repo=$(basename `git rev-parse --show-toplevel` 2>/dev/null)
|
||||
local git_rel_path=$(git rev-parse --show-prefix 2>/dev/null)
|
||||
PS1+="$txtcyn$git_repo $txtpur$git_rel_path$txtrst\n"
|
||||
fi
|
||||
# User color: red for root, yel for others
|
||||
if [[ $EUID == 0 ]]; then
|
||||
PS1+="\[$txtred\]"
|
||||
else
|
||||
PS1+="\[$txtyel\]"
|
||||
fi
|
||||
# Line 3: user@host
|
||||
PS1+="\u\[$txtwht\]@\h\n"
|
||||
# Line 4: a red "✗" or a grn "✓" and the error number
|
||||
if [[ $last_cmd == 0 ]]; then
|
||||
PS1+="\[$txtgrn\]$checkmark \[$txtwht\](0)"
|
||||
else
|
||||
PS1+="\[$txtred\]$fancyx \[$txtwht\]($last_cmd)"
|
||||
fi
|
||||
# Line 4: grn git branch
|
||||
PS1+="\[$txtgrn\]$(__git_ps1 '(%s')\[$txtwht\]"
|
||||
PS1+="$(format_modified_detailed)\[$txtgrn\])\[$txtrst\] "
|
||||
# Line 4: good old prompt, $ for user, # for root
|
||||
PS1+=" \\$ "
|
||||
}
|
||||
|
||||
set_prompt()
|
||||
{
|
||||
local is_git="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
|
||||
|
||||
local txtrst='\e[m'
|
||||
local txtbold='\e[1m'
|
||||
local txtblk='\e[30m'
|
||||
local txtred='\e[31m'
|
||||
local txtgrn='\e[32m'
|
||||
local txtyel='\e[33m'
|
||||
local txtblu='\e[34m'
|
||||
local txtpur='\e[35m'
|
||||
local txtcyn='\e[36m'
|
||||
local txtwht='\e[37m'
|
||||
|
||||
# User color: red for root, yel for others
|
||||
if [[ $EUID == 0 ]]; then
|
||||
PS1+="\[$txtred\]"
|
||||
else
|
||||
PS1+="\[$txtyel\]"
|
||||
fi
|
||||
# user@host
|
||||
PS1="\u\[$txtwht\]@\h"
|
||||
# Git repo + path in repo
|
||||
if [ "$is_git" ]; then
|
||||
local git_repo=$(basename `git rev-parse --show-toplevel` 2>/dev/null)
|
||||
local git_rel_path=$(git rev-parse --show-prefix 2>/dev/null)
|
||||
PS1+="\[$txtcyn\][$git_repo] \[$txtpur\]$git_rel_path\[$txtrst\]"
|
||||
# Green git branch
|
||||
PS1+="\[$txtgrn\]$(__git_ps1 '(%s')\[$txtwht\]"
|
||||
PS1+="$(format_modified)\[$txtgrn\])\[$txtrst\] "
|
||||
else
|
||||
# Current path
|
||||
PS1+="\[$txtgrn\]\w "
|
||||
fi
|
||||
# Good old prompt, $ for user, # for root
|
||||
PS1+="\[$txtrst\]\\$ "
|
||||
}
|
||||
|
||||
f() {
|
||||
case $PROMPT_COMMAND in
|
||||
set_prompt )
|
||||
export PROMPT_COMMAND='set_prompt_fancy'
|
||||
;;
|
||||
set_prompt_fancy )
|
||||
export PROMPT_COMMAND='set_prompt'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
export PROMPT_COMMAND='set_prompt'
|
||||
52
.bashrc.kuba
52
.bashrc.kuba
@@ -4,17 +4,53 @@
|
||||
|
||||
# If not running interactively, don't do anything
|
||||
[[ $- != *i* ]] && return
|
||||
alias ls='ls --color=auto'
|
||||
PS1='[\u@\h \W]\$ '
|
||||
|
||||
# Convenient helper function
|
||||
source_existing() {
|
||||
[ -f "$1" ] && source "$1"
|
||||
}
|
||||
|
||||
export LC_ALL=en_US.UTF-8
|
||||
export LANG=en_US.UTF-8
|
||||
|
||||
export KRB5_CONFIG=".etcfiles/krb5.conf"
|
||||
export EDITOR="vim"
|
||||
export CUPS_GSSSERVICENAME=HTTP
|
||||
export PATH=$PATH:/home/kuba/bin
|
||||
export PATH="$HOME/git/esp-open-sdk/xtensa-lx106-elf/bin/:$PATH"
|
||||
|
||||
alias dotfiles="/usr/bin/git --git-dir=$HOME/.dotfiles.git --work-tree=$HOME"
|
||||
alias dvim="GIT_WORK_TREE='/home/kuba' GIT_DIR='/home/kuba/.dotfiles.git/' vim"
|
||||
|
||||
if xhost >& /dev/null ; then
|
||||
# X is running
|
||||
xhost +local:kuba > /dev/null
|
||||
alias ls='ls --color=auto'
|
||||
|
||||
# Define a OS X-like open command
|
||||
open() { command xdg-open "$@" > /dev/null 2>&1 & }
|
||||
|
||||
# Source git prompt
|
||||
source_existing ~/scripts/git-prompt.sh
|
||||
source_existing ~/.bash_prompt.kuba
|
||||
|
||||
# Activate python virtualenv
|
||||
source_existing ~/.python-venv.kuba/bin/activate
|
||||
|
||||
# Source lmod module setup
|
||||
source_existing /usr/share/lmod/lmod/init/profile
|
||||
|
||||
case $(hostname) in
|
||||
vera* )
|
||||
module use "$HOME/.modules.kuba/"
|
||||
module load iccifort/2019.5.281
|
||||
module load impi/2018.5.288
|
||||
module load imkl/2019.5.281
|
||||
module load Python/3.7.4
|
||||
module load clusterappl
|
||||
module load slurm-aliases
|
||||
;;
|
||||
tetralith* )
|
||||
module use "$HOME/.modules.kuba/"
|
||||
module load Python/3.6.3-anaconda-5.0.1-nsc1
|
||||
module load clusterappl
|
||||
;;
|
||||
* )
|
||||
if [ -e /usr/share/lmod/lmod/init/profile ]; then
|
||||
module use "$HOME/.modules.kuba/"
|
||||
fi
|
||||
esac
|
||||
|
||||
3
.config/nvim/init.vim
Normal file
3
.config/nvim/init.vim
Normal file
@@ -0,0 +1,3 @@
|
||||
set runtimepath^=~/.vim runtimepath+=~/.vim/after
|
||||
let &packpath=&runtimepath
|
||||
source ~/.vimrc
|
||||
@@ -1,20 +1,12 @@
|
||||
[global_config]
|
||||
title_inactive_bg_color = "#4C566A"
|
||||
title_inactive_fg_color = "#D8DEE9"
|
||||
title_receive_bg_color = "#8FBCBB"
|
||||
title_receive_fg_color = "#2E3440"
|
||||
title_transmit_bg_color = "#88C0D0"
|
||||
title_transmit_fg_color = "#2E3440"
|
||||
title_transmit_bg_color = "#88C0D0"
|
||||
title_receive_fg_color = "#2E3440"
|
||||
title_receive_bg_color = "#8FBCBB"
|
||||
title_inactive_fg_color = "#D8DEE9"
|
||||
title_inactive_bg_color = "#4C566A"
|
||||
always_split_with_profile = True
|
||||
[keybindings]
|
||||
[layouts]
|
||||
[[default]]
|
||||
[[[child1]]]
|
||||
parent = window0
|
||||
type = Terminal
|
||||
[[[window0]]]
|
||||
parent = ""
|
||||
type = Window
|
||||
[plugins]
|
||||
[profiles]
|
||||
[[default]]
|
||||
background_color = "#12204d"
|
||||
@@ -28,7 +20,16 @@
|
||||
cursor_color = "#D8DEE9"
|
||||
font = Hack 11
|
||||
foreground_color = "#d8dee9"
|
||||
palette = "#3b4252:#bf616a:#a3be8c:#ebcb8b:#81a1c1:#b48ead:#88c0d0:#e5e9f0:#4c566a:#bf616a:#a3be8c:#ebcb8b:#81a1c1:#b48ead:#8fbcbb:#eceff4"
|
||||
scrollbar_position = hidden
|
||||
show_titlebar = False
|
||||
scrollbar_position = hidden
|
||||
palette = "#3b4252:#bf616a:#a3be8c:#ebcb8b:#81a1c1:#b48ead:#88c0d0:#e5e9f0:#4c566a:#bf616a:#a3be8c:#ebcb8b:#81a1c1:#b48ead:#8fbcbb:#eceff4"
|
||||
use_system_font = False
|
||||
[layouts]
|
||||
[[default]]
|
||||
[[[child1]]]
|
||||
parent = window0
|
||||
type = Terminal
|
||||
[[[window0]]]
|
||||
parent = ""
|
||||
type = Window
|
||||
[plugins]
|
||||
|
||||
14
.etcfiles/krb5.conf
Normal file
14
.etcfiles/krb5.conf
Normal file
@@ -0,0 +1,14 @@
|
||||
[domain_realm]
|
||||
.pdc.kth.se = NADA.KTH.SE
|
||||
.chalmers.se = CHALMERS.SE
|
||||
chalmers.se = CHALMERS.SE
|
||||
|
||||
[appdefaults]
|
||||
forwardable = yes
|
||||
forward = yes
|
||||
krb4_get_tickets = no
|
||||
|
||||
[libdefaults]
|
||||
default_realm = NADA.KTH.SE
|
||||
dns_lookup_realm = true
|
||||
dns_lookup_kdc = true
|
||||
2
.etcfiles/lightdm/lightdm.conf
Normal file
2
.etcfiles/lightdm/lightdm.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
[Seat:*]
|
||||
greeter-session=lightdm-webkit2-greeter
|
||||
8
.etcfiles/package-list-ubuntu
Normal file
8
.etcfiles/package-list-ubuntu
Normal file
@@ -0,0 +1,8 @@
|
||||
git-lfs
|
||||
gnuplot-x11
|
||||
graphviz
|
||||
htop
|
||||
terminator
|
||||
tmux
|
||||
gnome-session
|
||||
lmod
|
||||
14
.gitconfig
Normal file
14
.gitconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
[user]
|
||||
email = jakub.fojt96@gmail.com
|
||||
name = Jakub Fojt
|
||||
[filter "lfs"]
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
required = true
|
||||
[credential]
|
||||
helper = cache --timeout=3600
|
||||
[color]
|
||||
ui = auto
|
||||
[pull]
|
||||
ff = only
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule ".i3/lemonbar"]
|
||||
path = .i3/lemonbar
|
||||
url = https://isabeljake.duckdns.org/gitea/kuba/lemonbar.git
|
||||
@@ -1,4 +1,6 @@
|
||||
sleep 2
|
||||
nextcloud &
|
||||
volnoti &
|
||||
conky -c ~/.conky/arch/.conkyrc-arch &
|
||||
conky -c ~/.conky/gmail/.conkyrc-gmail &
|
||||
conky -c ~/.conky/weather/.conkyrc-weather1 &
|
||||
@@ -6,5 +8,6 @@ conky -c ~/.conky/weather/.conkyrc-weather2 &
|
||||
conky -c ~/.conky/music/.conkyrc-music &
|
||||
python ~/.conky/music/playerctl_listen.py &
|
||||
sh ~/.conky/music/launcher.sh &
|
||||
source ~/.python-venv.kuba/bin/activate
|
||||
python ~/.i3/lemonbar/i3_lemonbar_launcher.py --debug >> /tmp/kuba_lemonbar_launcher.log &
|
||||
compton -b # --config=/home/kuba/.compton.conf
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
####
|
||||
|
||||
set $mod Mod4
|
||||
set $TERMINAL terminator
|
||||
set $TERMINAL terminator --profile=nord
|
||||
|
||||
font pango:FontAwesome 11
|
||||
|
||||
@@ -30,10 +30,10 @@ bindsym $mod+d exec dmenu_run
|
||||
bindsym $mod+Shift+d exec --no-startup-id i3-dmenu-desktop
|
||||
|
||||
# change focus
|
||||
bindsym $mod+j focus left
|
||||
bindsym $mod+k focus down
|
||||
bindsym $mod+l focus up
|
||||
bindsym $mod+semicolon focus right
|
||||
bindsym $mod+h focus left
|
||||
bindsym $mod+j focus down
|
||||
bindsym $mod+k focus up
|
||||
bindsym $mod+l focus right
|
||||
|
||||
# alternatively, you can use the cursor keys:
|
||||
bindsym $mod+Left focus left
|
||||
@@ -42,10 +42,10 @@ bindsym $mod+Up focus up
|
||||
bindsym $mod+Right focus right
|
||||
|
||||
# move focused window
|
||||
bindsym $mod+Shift+j move left
|
||||
bindsym $mod+Shift+k move down
|
||||
bindsym $mod+Shift+l move up
|
||||
bindsym $mod+Shift+semicolon move right
|
||||
bindsym $mod+Shift+h move left
|
||||
bindsym $mod+Shift+j move down
|
||||
bindsym $mod+Shift+k move up
|
||||
bindsym $mod+Shift+l move right
|
||||
|
||||
# alternatively, you can use the cursor keys:
|
||||
bindsym $mod+Shift+Left move left
|
||||
@@ -54,7 +54,7 @@ bindsym $mod+Shift+Up move up
|
||||
bindsym $mod+Shift+Right move right
|
||||
|
||||
# split in horizontal orientation
|
||||
bindsym $mod+h split h
|
||||
bindsym $mod+g split h
|
||||
|
||||
# split in vertical orientation
|
||||
bindsym $mod+v split v
|
||||
@@ -71,7 +71,7 @@ bindsym $mod+e layout toggle split
|
||||
bindsym $mod+Shift+space floating toggle
|
||||
|
||||
# change focus between tiling / floating windows
|
||||
bindsym $mod+space focus mode_toggle
|
||||
bindsym $mod+Shift+Return focus mode_toggle
|
||||
|
||||
# focus the parent container
|
||||
bindsym $mod+a focus parent
|
||||
|
||||
@@ -22,9 +22,9 @@ for_window [class="FLOAT_PAVU"] floating enable
|
||||
for_window [class="FLOAT_PAVU"] resize set 800 540
|
||||
for_window [class="FLOAT_PAVU"] border pixel 3
|
||||
for_window [class="FLOAT_PAVU"] move absolute position $pavuX px $below_barY px
|
||||
for_window [window_role="FLOAT_TERM"] floating enable
|
||||
for_window [window_role="FLOAT_TERM"] move absolute position $htopX px $below_barY px
|
||||
for_window [window_role="FLOAT_TERM"] border pixel 3
|
||||
for_window [class="FLOAT_TERM"] floating enable
|
||||
for_window [class="FLOAT_TERM"] move absolute position $htopX px $below_barY px
|
||||
for_window [class="FLOAT_TERM"] border pixel 3
|
||||
for_window [title="Memory"] floating enable
|
||||
for_window [class="Matplotlib"] floating enable
|
||||
for_window [class="Chromium"] border pixel 0
|
||||
@@ -83,7 +83,7 @@ bindsym XF86AudioPrevious exec playerctl previous
|
||||
bindsym Print exec scrot '%Y-%m-%d-%T_$wx$h_scrot.png' -e 'mv $f ~/Obrazy/screenshots/'
|
||||
bindsym Shift + Print exec scrot -s '%Y-%m-%d-%T_$wx$h_scrot.png' -e 'mv $f ~/Obrazy/screenshots/'
|
||||
|
||||
bindsym $mod+m exec sh ~/.i3/scripts/lang.sh next
|
||||
bindsym $mod+space exec sh ~/.i3/scripts/lang.sh next
|
||||
|
||||
# Exiting
|
||||
####
|
||||
|
||||
1
.i3/lemonbar
Submodule
1
.i3/lemonbar
Submodule
Submodule .i3/lemonbar added at 7d48ad9543
1
.i3/lemonbar/cache/credentials.json
vendored
1
.i3/lemonbar/cache/credentials.json
vendored
@@ -1 +0,0 @@
|
||||
{"username":"kuben-","auth_type":1,"auth_data":"QVFDYzhMY0tnZ2g2M2N1czFhcXI4c0xRMkQzc3pRdXlFZVVVeEVzN0xRRE1VSnItVmw3Z05XWWhRVUNCX2pqS25mSXhGcVRyV0RFcGtTWVFMR3pzSG1jZVdTY0JnNnJFT0hDdFptdzM="}
|
||||
1
.i3/lemonbar/cache/volume
vendored
1
.i3/lemonbar/cache/volume
vendored
@@ -1 +0,0 @@
|
||||
49151
|
||||
@@ -1,27 +0,0 @@
|
||||
-- Conky for external bar
|
||||
-- out simple text to console
|
||||
|
||||
conky.config = {
|
||||
background=false,
|
||||
update_interval=0.2,
|
||||
total_run_times=0,
|
||||
override_utf8_locale=true,
|
||||
short_units=true,
|
||||
uppercase=false,
|
||||
out_to_console=true,
|
||||
out_to_x=false,
|
||||
if_up_strictness='address',
|
||||
format_human_readable=true,
|
||||
}
|
||||
|
||||
conky.text = [[
|
||||
CNK_FAST \
|
||||
${time %a %d %b %H:%M:%S} \
|
||||
${exec ~/.i3/lemonbar/get_vol.sh} \
|
||||
${if_up wlp3s0}${downspeedf wlp3s0} ${upspeedf wlp3s0}\
|
||||
${else}down down${endif}\
|
||||
\
|
||||
${if_up enp2s0}${downspeedf enp2s0} ${upspeedf enp2s0}\
|
||||
${else}down down${endif}\
|
||||
\
|
||||
]]
|
||||
@@ -1,26 +0,0 @@
|
||||
-- Conky for external bar
|
||||
-- out simple text to console
|
||||
|
||||
conky.config = {
|
||||
background=false,
|
||||
update_interval=5,
|
||||
total_run_times=0,
|
||||
override_utf8_locale=true,
|
||||
short_units=true,
|
||||
uppercase=false,
|
||||
out_to_console=true,
|
||||
out_to_x=false,
|
||||
if_up_strictness='address',
|
||||
format_human_readable=true,
|
||||
}
|
||||
|
||||
conky.text = [[
|
||||
CNK_SLOW \
|
||||
${cpu} \
|
||||
${mem} \
|
||||
${fs_used_perc /} \
|
||||
${fs_used_perc /home} \
|
||||
${exec ~/.i3/lemonbar/get_bat.sh} \
|
||||
${exec brillo} \
|
||||
${exec /home/kuba/.i3/scripts/lang.sh show}
|
||||
]]
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
acpi | head -n 1 | awk '{pct = substr($4, 1, length($4)-2);\
|
||||
if($3 ~ "Dis") print "D"pct;\
|
||||
else if($3 ~ "Cha") printf "C"pct;\
|
||||
else print "F"substr($5, 1, length($5)-1);}'
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
RTN=$(amixer get Master | grep "Front Left: Playback" | \
|
||||
awk -F'[]%[]' '{if ($5 == "off") {print "MUTE"} else {printf "%d", $2}}')
|
||||
if [[ -z $RTN ]]; then
|
||||
echo "NONE"
|
||||
else
|
||||
echo "$RTN"
|
||||
fi
|
||||
@@ -1,153 +0,0 @@
|
||||
import subprocess, os, getpass
|
||||
import re # regexp
|
||||
from enum import Enum
|
||||
|
||||
import i3_lemonbar_config as config
|
||||
|
||||
kill_on_unfocus = []
|
||||
|
||||
# Loggers, initialized in main function
|
||||
logger = None
|
||||
health_logger = None
|
||||
|
||||
screen = None
|
||||
parsing_queue = None
|
||||
|
||||
class bar_mode(Enum):
|
||||
power, normal, control = range(-1,2) # Don't cycle through power
|
||||
|
||||
def cycle(self):
|
||||
try:
|
||||
return bar_mode(self.value + 1)
|
||||
except ValueError:
|
||||
return bar_mode(0)
|
||||
|
||||
mode = bar_mode.normal
|
||||
|
||||
floatterm_args = lambda prog : ['terminator', '-r', 'FLOAT_TERM', '-p'
|
||||
, 'dark', '-e', 'echo kill_unfocus $$ > {}; exec {}'.format(
|
||||
config.fifo_file_executor, prog)]
|
||||
def date_comm(args):
|
||||
subprocess.Popen(['yad', '--no-buttons', '--calendar', '--sticky'
|
||||
, '--on-top' , '--class' , '"YADWIN"', '--posx=1650', '--posy=24'
|
||||
, '--close-on-unfocus'])
|
||||
|
||||
def pavu_comm(args):
|
||||
global kill_on_unfocus
|
||||
p = subprocess.Popen(['pavucontrol', '--class=FLOAT_PAVU'])
|
||||
kill_on_unfocus.append(p.pid)
|
||||
|
||||
def htop_comm(args):
|
||||
subprocess.Popen(floatterm_args('htop'))
|
||||
|
||||
def nmtui_comm(args):
|
||||
subprocess.Popen(floatterm_args('nmtui'))
|
||||
def lang_comm(args):
|
||||
subprocess.Popen(['sh', '/home/kuba/.i3/scripts/lang.sh', 'next'])
|
||||
def dpms_comm(args):
|
||||
subprocess.Popen(['sh', '/home/kuba/.i3/scripts/dpmsctl.sh'])
|
||||
def adj_br(args):
|
||||
subprocess.Popen(['/home/kuba/.i3/scripts/adjbr.sh', '-b', config.fifo_file_executor])
|
||||
def i3msg_comm(args):
|
||||
subprocess.Popen(args.split())
|
||||
def add_tokill(args):
|
||||
global kill_on_unfocus
|
||||
kill_on_unfocus.append(int(args.split()[1]))
|
||||
def set_mode(args):
|
||||
global mode
|
||||
new_mode = args.split()[1]
|
||||
if new_mode == "cycle":
|
||||
mode = mode.cycle()
|
||||
|
||||
for m in bar_mode:
|
||||
if new_mode == m.name:
|
||||
mode = m
|
||||
break
|
||||
def bluetooth(args):
|
||||
btcargs = args.split()[1:]
|
||||
btcargs = [a.replace('pxc550', '00:16:94:22:29:0E') for a in btcargs]
|
||||
inp = ' '.join(btcargs)
|
||||
screen.send_cmd('bluetoothctl ' + inp)
|
||||
|
||||
show_secs = False
|
||||
def toggle_secs(args):
|
||||
global show_secs
|
||||
show_secs = not show_secs
|
||||
|
||||
# Keymaps
|
||||
def_keymap = 'pl'
|
||||
keymaps = {'Firefox': 'se'}
|
||||
cur_class = ''
|
||||
def set_lang(args):
|
||||
global keymaps
|
||||
lang = args.split()[1]
|
||||
keymaps[cur_class] = lang
|
||||
|
||||
commands_dict = {'toggle_secs': toggle_secs
|
||||
,'date': date_comm
|
||||
,'pavu': pavu_comm
|
||||
,'load': htop_comm
|
||||
,'wlan': nmtui_comm
|
||||
,'dpms': dpms_comm
|
||||
,'i3-msg': i3msg_comm
|
||||
,'switch_lang': lang_comm
|
||||
,'kill_unfocus': add_tokill
|
||||
,'mode': set_mode
|
||||
,'adj_br': adj_br
|
||||
,'setlang': set_lang
|
||||
,'bluetooth': bluetooth
|
||||
}
|
||||
|
||||
# Helper functions
|
||||
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
|
||||
def strip_ansi_unicode(s):
|
||||
# ANSI escape sequences are for colors in terminal and similar
|
||||
strip_ansi = ansi_escape.sub('', s)
|
||||
strip_unicode = (strip_ansi.encode('ascii', 'ignore')).decode('utf-8')
|
||||
return strip_unicode
|
||||
|
||||
def create_new_fifo(fifo_file):
|
||||
"""
|
||||
Create new fifo file, removing old one if it exists
|
||||
"""
|
||||
try:
|
||||
os.remove(fifo_file)
|
||||
logger.debug('''Removed old fifo file''')
|
||||
except OSError:
|
||||
logger.debug('''No old fifo file, good''')
|
||||
|
||||
try:
|
||||
os.mkfifo(fifo_file)
|
||||
except OSError:
|
||||
logger.error('''Failed, couldn't create fifo file''')
|
||||
os.remove(config.pid_file) # Clean up own PID file
|
||||
sys.exit(0)
|
||||
|
||||
class LemonbarScreen:
|
||||
# Start, stop and send commands to screen instance
|
||||
|
||||
# Start detached, in UTF-8 mode. Log to fifo
|
||||
start_flags = ['-d', '-m', '-U', '-L', '-Logfile', config.fifo_screen_log]
|
||||
|
||||
def __init__(self):
|
||||
self.identifier = 'lemonbar_{}_{}'.format(getpass.getuser(), os.getpid())
|
||||
|
||||
create_new_fifo(config.fifo_screen_log)
|
||||
self.send(self.start_flags) # Start screen
|
||||
self.send_cmd('stty -echo') # Do not echo what is written to screen terminal
|
||||
self.send_colon('logfile flush 0.1') # Log quickly
|
||||
|
||||
def destroy(self):
|
||||
self.send_colon('kill')
|
||||
|
||||
def send(self, args):
|
||||
# Send something to our screen instance
|
||||
subprocess.call(['screen', '-S', self.identifier] + args)
|
||||
|
||||
def send_cmd(self, cmd):
|
||||
# Send terminal input to our screen instance
|
||||
self.send(['-X', 'stuff', cmd + '\n'])
|
||||
|
||||
def send_colon(self, cmd):
|
||||
# Send colon command to our screen instance
|
||||
self.send(['-X', 'colon', cmd + '\n'])
|
||||
@@ -1,89 +0,0 @@
|
||||
import subprocess
|
||||
import getpass
|
||||
|
||||
# File locations
|
||||
pid_file = '/tmp/i3_lemonbar_launcher.pid'
|
||||
fifo_file_status = '/tmp/i3_lemonbar1_{}'.format(getpass.getuser())
|
||||
fifo_screen_log = '/tmp/i3_screen_{}'.format(getpass.getuser())
|
||||
health_file = '/tmp/i3_lemonbar_health.info'
|
||||
|
||||
path="/home/kuba/.i3/lemonbar/"
|
||||
logpath="/home/kuba/lemonbar.log" # Write here on exceptions
|
||||
|
||||
# color definitions
|
||||
color_back = "#FF1D1F21" # Default background
|
||||
color_fore = "#FFC5C8C6" # Default foreground
|
||||
color_poweropts = "#FF620A00"
|
||||
color_head = "#FFB5BD68" # Background for first element
|
||||
color_sec_b1 = "#FF282A2E" # Background for section 1
|
||||
color_sec_b2 = "#FF454A4F" # Background for section 2
|
||||
color_sec_b3 = "#FF60676E" # Background for section 3
|
||||
color_vga = "#FF3F8C0F"
|
||||
color_hdmi = "#FFDD5435"
|
||||
color_icon = "#FF979997" # For icons
|
||||
color_cpu = "#FF5F819D" # Background color for cpu alert
|
||||
color_net = "#FF5E8D87" # Background color for net alert
|
||||
color_disable = "#FF1D1F21" # Foreground for disable elements
|
||||
color_wsp = "#FF8C9440" # Background for selected workspace
|
||||
|
||||
# Lemonbar settings
|
||||
geometry="x24"
|
||||
fonts = ["Hack:pixelsize=12" #":style=Bold"
|
||||
,"Font Awesome 5 Free Solid:pixelsize=16"
|
||||
,"Font Awesome 5 Brands:pixelsize=16"]
|
||||
|
||||
lemonbar_args = ['lemonbar', '-p', '-g', geometry, '-B', color_back
|
||||
, '-F', color_fore, '-a' '20']
|
||||
|
||||
for font in fonts:
|
||||
lemonbar_args.append('-f')
|
||||
lemonbar_args.append(font)
|
||||
|
||||
# Misc. settings
|
||||
cpu_alert = 75
|
||||
net_alert = 5
|
||||
|
||||
#default space between sections
|
||||
#if [ ${res_w} -gt 1024 ]; then
|
||||
# stab=' '
|
||||
#else
|
||||
# stab=' '
|
||||
#fi
|
||||
|
||||
# Icon definitions
|
||||
sep_left = "" # Powerline separator left alt.
|
||||
sep_right = "" # Powerline separator right
|
||||
sep_l_left = "" # Powerline light separator left
|
||||
sep_l_right = "" # Powerline light sepatator right
|
||||
|
||||
# Icon glyphs from Terminusicons2
|
||||
icon_clock = "" # Clock icon
|
||||
icon_cpu = "" # CPU icon
|
||||
icon_mem = "" # MEM icon
|
||||
icon_dl = "" # Download icon
|
||||
icon_ul = "" # Upload icon
|
||||
icon_vol = "" # Volume icon
|
||||
icon_vol_low = "" # Volume icon
|
||||
icon_vol_mute = "" # Volume icon
|
||||
icon_hd = " [/]" # HD / icon
|
||||
icon_home = " [/home]" # HD /home icon
|
||||
icon_mail = "" # Mail icon
|
||||
icon_chat = "Ò" # IRC/Chat icon
|
||||
icon_music = "Î" # Music icon
|
||||
icon_prog = "" # Window icon alt.
|
||||
icon_contact = "Á" # Contact icon
|
||||
icon_wsp = "" # Workspace icon
|
||||
icon_wlan = ""
|
||||
icon_eth = ""
|
||||
icon_lang = ""
|
||||
icon_keyset = ""
|
||||
icon_bright = ""
|
||||
icon_brightness = '☼'
|
||||
icon_charged = ""
|
||||
icon_charging = ""
|
||||
icon_batt_0 = ""
|
||||
icon_batt_1 = ""
|
||||
icon_batt_2 = ""
|
||||
icon_batt_3 = ""
|
||||
icon_batt_4 = ""
|
||||
icon_bluetooth = ""
|
||||
@@ -1,269 +0,0 @@
|
||||
import fcntl, sys, os, time, logging
|
||||
import queue
|
||||
import signal, atexit
|
||||
import subprocess
|
||||
import contextlib
|
||||
from threading import Thread
|
||||
import argparse
|
||||
|
||||
import i3_lemonbar_config as config
|
||||
import i3_lemonbar_common as common
|
||||
import i3_lemonbar_modules as modules
|
||||
import i3_lemonbar_parser as lemonparser
|
||||
|
||||
p_conky_slow = None
|
||||
p_lemonbar = None
|
||||
|
||||
def assert_only_instance():
|
||||
"""
|
||||
If PID file exists:
|
||||
Look for process with given PID
|
||||
If found:
|
||||
Exit program
|
||||
If not found:
|
||||
Delete PID file and continue
|
||||
|
||||
Look for fifo file
|
||||
If exists:
|
||||
Delete it
|
||||
"""
|
||||
|
||||
try:
|
||||
pid = None
|
||||
with open(config.pid_file, 'r') as fp:
|
||||
pid = int(fp.read())
|
||||
except IOError:
|
||||
common.logger.debug('Could not open PID file. Assuming non existent')
|
||||
except ValueError:
|
||||
common.logger.debug('''PID file contents broken''')
|
||||
try:
|
||||
os.remove(config.pid_file)
|
||||
common.logger.debug('''Deleted old PID file, continuing as usual''')
|
||||
except OSError:
|
||||
common.logger.debug('''Failed deleting old PID file.''')
|
||||
os._exit(1)
|
||||
|
||||
|
||||
if pid is not None:
|
||||
try:
|
||||
common.logger.debug('''Found old PID file. Looking for owner''')
|
||||
os.kill(pid, 0)
|
||||
common.logger.debug('''Owner exists''')
|
||||
common.logger.debug('''Failed, another instance of the launcher is running
|
||||
(PID {})'''.format(pid))
|
||||
os._exit(1)
|
||||
except ProcessLookupError:
|
||||
common.logger.debug('''Owner does not exist''')
|
||||
try:
|
||||
os.remove(config.pid_file)
|
||||
common.logger.debug('''Deleted old PID file, continuing as usual''')
|
||||
except OSError:
|
||||
common.logger.debug('''Failed deleting old PID file.''')
|
||||
os._exit(1)
|
||||
|
||||
with open(config.pid_file, 'w+') as fp:
|
||||
fp.write('{:d}'.format(os.getpid()))
|
||||
common.logger.debug('''Created and wrote to PID file''')
|
||||
|
||||
common.create_new_fifo(config.fifo_file_status)
|
||||
|
||||
def handle_exit(signum, frame):
|
||||
common.logger.info('Signal handler called with signal {}'.format(signum))
|
||||
common.logger.info('Calling os._exit(0)')
|
||||
os._exit(0)
|
||||
|
||||
# Terminates process p nicely
|
||||
def nice_term(p):
|
||||
if p is not None:
|
||||
p.terminate()
|
||||
|
||||
def nice_delete(f):
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
os.remove(f)
|
||||
|
||||
def clean_up():
|
||||
common.logger.debug('Cleaning up')
|
||||
common.screen.destroy()
|
||||
nice_delete(config.pid_file)
|
||||
nice_delete(config.fifo_file_status)
|
||||
nice_term(p_conky_slow)
|
||||
modules.stop_all()
|
||||
sys.exit(0)
|
||||
|
||||
def queue_parse_job(job):
|
||||
common.parsing_queue.put(job)
|
||||
|
||||
def keep_fifo_open():
|
||||
with open(config.fifo_file_status, 'w', buffering=1) as fifo_write:
|
||||
while True:
|
||||
fifo_write.write('HEARTBEAT\n')
|
||||
time.sleep(30)
|
||||
def put_fifo_in_queue():
|
||||
with open(config.fifo_file_status, 'r', buffering=1) as fifo_read:
|
||||
# Let parser read from fifo
|
||||
common.logger.debug("FIFO {} opened for reading".format(config.fifo_file_status))
|
||||
|
||||
while True:
|
||||
try:
|
||||
data = fifo_read.readline() # Blocking read
|
||||
if len(data) == 0:
|
||||
common.logger.debug("Writer closed")
|
||||
break
|
||||
queue_parse_job(data)
|
||||
except BrokenPipeError:
|
||||
common.logger.debug('Broken pipe in parse status thread, exiting')
|
||||
common.health_logger.info('Broken pipe in parse status thread, exiting')
|
||||
clean_up()
|
||||
except:
|
||||
common.logger.debug('Unknown exception in parse status thread, exiting')
|
||||
common.health_logger.info('Unknown exception in parse status thread, exiting')
|
||||
clean_up()
|
||||
|
||||
def parse_status():
|
||||
global p_lemonbar
|
||||
p_lemonbar = subprocess.Popen(config.lemonbar_args, stdin=subprocess.PIPE
|
||||
, stdout=subprocess.PIPE, text=True)
|
||||
|
||||
lemonparser.parse_line('WSPINA1___main INA2___web FOC5___terms INA6___stats ') # TODO modular
|
||||
while True:
|
||||
data = common.parsing_queue.get() # Blocking read
|
||||
if data is None:
|
||||
common.logger.debug('Queue closed')
|
||||
common.health_logger.info('Queue closed')
|
||||
break
|
||||
|
||||
# Ugly temporary solution
|
||||
if (isinstance(data, list)):
|
||||
psd = data[0]
|
||||
else:
|
||||
psd = lemonparser.parse_line(data)
|
||||
p_lemonbar.stdin.write(psd + '\n')
|
||||
p_lemonbar.stdin.flush()
|
||||
#common.logger.debug('Read: "{0}"'.format(data))
|
||||
#common.logger.debug('Parsed "{0}"'.format(psd))
|
||||
|
||||
def exec_commands():
|
||||
global p_lemonbar
|
||||
|
||||
# Wait until up TODO better solution
|
||||
while True:
|
||||
if p_lemonbar is not None:
|
||||
break
|
||||
while True:
|
||||
data = p_lemonbar.stdout.readline()
|
||||
if not data:
|
||||
common.logger.debug('Lemonbar closed, exiting')
|
||||
common.health_logger.info('Lemonbar closed, exiting')
|
||||
clean_up()
|
||||
break
|
||||
|
||||
common.logger.debug('Trying reading: "{0}"'.format(data.strip('\n')))
|
||||
try:
|
||||
for key,func in common.commands_dict.items():
|
||||
l = len(key)
|
||||
if data[:l] == key:
|
||||
func(data)
|
||||
break
|
||||
|
||||
except:
|
||||
common.logger.debug('Exception occured executing command\n Line in: {}\n Data: {}'.format(line_in, line_in[l:].split()))
|
||||
if len(data) == 0:
|
||||
common.logger.debug("Lemonbar output closed")
|
||||
break
|
||||
common.logger.debug('Read: "{0}"'.format(data.strip('\n')))
|
||||
|
||||
|
||||
def user_screen():
|
||||
# Create screen session, in UTF-8 mode, logging to fifo
|
||||
common.screen = common.LemonbarScreen()
|
||||
with open(config.fifo_screen_log, 'r', buffering=1) as screen_read:
|
||||
empty_count = 0
|
||||
while empty_count < 3:
|
||||
try:
|
||||
line = screen_read.readline().strip('\n')
|
||||
line = common.strip_ansi_unicode(line)
|
||||
common.logger.debug('Screen read line {}'.format(line))
|
||||
if (not line.startswith('[CHG]')
|
||||
and not line.isspace()):
|
||||
#common.logger.debug('put in queue {}'.format(line))
|
||||
queue_parse_job('RESP {}\n'.format(line))
|
||||
|
||||
if not line:
|
||||
# End loop if many empty lines in a row
|
||||
empty_count = empty_count + 1
|
||||
else:
|
||||
empty_count = 0
|
||||
except:
|
||||
raise
|
||||
|
||||
common.screen.destroy()
|
||||
nice_delete(config.fifo_screen_log)
|
||||
|
||||
class i3_thread:
|
||||
""" Helper class to start and stop threads"""
|
||||
all_threads = [] # Static, contains all started threads
|
||||
|
||||
def __init__(self, target, desc):
|
||||
self.thread = Thread(target = self.__class__.run, args=(target,desc))
|
||||
self.desc = desc
|
||||
|
||||
self.all_threads.append(self)
|
||||
common.health_logger.info('"%s" starting', desc)
|
||||
self.thread.start()
|
||||
|
||||
# Wrapper around the target
|
||||
def run(target, desc):
|
||||
target()
|
||||
common.health_logger.info('"%s" reached end', desc)
|
||||
|
||||
def join_threads():
|
||||
for i3_th in i3_thread.all_threads:
|
||||
i3_th.thread.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Blah blah blah.')
|
||||
parser.add_argument('--debug', action='store_true')
|
||||
args = parser.parse_args()
|
||||
if(args.debug):
|
||||
debuglvl = logging.DEBUG
|
||||
else:
|
||||
debuglvl = logging.INFO
|
||||
|
||||
# Setup logger to stdout
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
common.logger = logging.getLogger('Normal logger')
|
||||
common.logger.setLevel(debuglvl)
|
||||
common.logger.addHandler(handler)
|
||||
|
||||
# Setup health logger to file in tmp
|
||||
formatter = logging.Formatter('%(asctime)s %(message)s')
|
||||
handler = logging.FileHandler(config.health_file)
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
common.health_logger = logging.getLogger('Health logger')
|
||||
common.health_logger.addHandler(handler)
|
||||
|
||||
# common.logger.basicConfig(stream=sys.stdout, level=debuglvl)
|
||||
assert_only_instance() # Creates pid file and fifo file
|
||||
atexit.register(clean_up)
|
||||
signal.signal(signal.SIGTERM, handle_exit)
|
||||
signal.signal(signal.SIGINT, handle_exit)
|
||||
|
||||
common.parsing_queue = queue.Queue()
|
||||
|
||||
# Start writing and reading threads
|
||||
# Create readers before writers
|
||||
i3_thread(target = exec_commands, desc='Exec commands thread')
|
||||
i3_thread(target = parse_status, desc='Parse status thread')
|
||||
i3_thread(target = keep_fifo_open, desc='')
|
||||
i3_thread(target = put_fifo_in_queue, desc='')
|
||||
i3_thread(target = user_screen, desc='Screen thread for user commands')
|
||||
modules.start_all()
|
||||
|
||||
common.logger.debug('Threads started')
|
||||
i3_thread.join_threads()
|
||||
|
||||
common.logger.debug('Reached end')
|
||||
@@ -1,443 +0,0 @@
|
||||
import threading
|
||||
import subprocess
|
||||
|
||||
import i3_lemonbar_config as config
|
||||
import i3_lemonbar_common as common
|
||||
import i3_lemonbar_parser as parser
|
||||
import i3_workspaces as wspaces
|
||||
|
||||
class LemonModule(threading.Thread):
|
||||
# Module generates some status message, parses it, and handles on click actions
|
||||
# Every module runs in its own thread
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._start_module()
|
||||
|
||||
def run(self):
|
||||
if self.status_handle is None:
|
||||
return
|
||||
|
||||
common.logger.info('Started module {}'.format(self.__class__.__name__))
|
||||
common.health_logger.info('Module {} up'.format(self.__class__.__name__))
|
||||
while True:
|
||||
line = self.status_handle.readline()
|
||||
if not line:
|
||||
common.logger.info('Reached end of module {}'.format(self.__class__.__name__))
|
||||
common.health_logger.info('Module {} down'.format(self.__class__.__name__))
|
||||
break
|
||||
|
||||
parsed = self.parse(line)
|
||||
common.parsing_queue.put([parsed]) # TODO Wrapped in list, temporary solution
|
||||
|
||||
def stop(self):
|
||||
self._stop_module()
|
||||
|
||||
def parse(self, line):
|
||||
# TODO get rid of prefix
|
||||
data = line[len(self.prefix):].split()
|
||||
self._parse_data(data) # Update correct field
|
||||
|
||||
formatted_line = parser.format_line() # Construct entire line
|
||||
return formatted_line
|
||||
|
||||
def format_load(data, module, alert):
|
||||
# Helper function to format network modules
|
||||
# Changes colors scheme to inactive when interfaces are down, or to alert when
|
||||
# alert level is reached
|
||||
# Returns tuple (down, up)
|
||||
if data[0] == 'down': # wlan
|
||||
module.alt_scheme = parser.COLOR_SCHEME.INA
|
||||
return ('x', 'x')
|
||||
else:
|
||||
(d_v, u_v) = (data[0],data[1])
|
||||
if max(float(d_v), float(u_v)) > float(alert):
|
||||
module.alt_scheme = parser.COLOR_SCHEME.NET_ALERT
|
||||
else:
|
||||
# Reset to default
|
||||
module.alt_scheme = None
|
||||
return (d_v, u_v)
|
||||
|
||||
class ConkyFastModule(LemonModule):
|
||||
|
||||
def __init__(self):
|
||||
self.prefix = 'CNK_FAST'
|
||||
super().__init__()
|
||||
|
||||
def _start_module(self):
|
||||
self.p_handle = subprocess.Popen(['conky', '-c', config.path+'conky_fast'],
|
||||
stdout=subprocess.PIPE, text=True)
|
||||
self.status_handle = self.p_handle.stdout
|
||||
|
||||
self.wlan_load = parser.IconTextUnit('wlan_load', action='wlan', order=13)
|
||||
self.eth_load = parser.IconTextUnit('eth_load', action='eth', order=14)
|
||||
self.volume = parser.IconTextUnit('volume', action='pavu', order=20)
|
||||
self.date = parser.IconTextUnit('date', action='date', order=40)
|
||||
self.time = parser.IconTextUnit('time', action='toggle_secs', order=41
|
||||
, alt_scheme=parser.COLOR_SCHEME.SPECIAL)
|
||||
self.time.modes = [mode for mode in common.bar_mode]
|
||||
|
||||
parser.g_parser.register_unit(self.wlan_load)
|
||||
parser.g_parser.register_unit(self.eth_load)
|
||||
parser.g_parser.register_unit(self.volume)
|
||||
parser.g_parser.register_unit(self.date)
|
||||
parser.g_parser.register_unit(self.time)
|
||||
|
||||
def _stop_module(self):
|
||||
if self.p_handle is not None:
|
||||
self.p_handle.terminate()
|
||||
|
||||
parser.g_parser.remove_unit(self.wlan_load)
|
||||
parser.g_parser.remove_unit(self.eth_load)
|
||||
parser.g_parser.remove_unit(self.volume)
|
||||
parser.g_parser.remove_unit(self.date)
|
||||
parser.g_parser.remove_unit(self.time)
|
||||
|
||||
def _parse_data(self, data):
|
||||
# wlan and eth
|
||||
(wland_v, wlanu_v) = format_load(data[5:7], self.wlan_load, config.net_alert)
|
||||
self.wlan_load.items = [(config.icon_wlan + config.icon_dl, wland_v)
|
||||
,(config.icon_ul, wlanu_v)]
|
||||
|
||||
(ethd_v, ethu_v) = format_load(data[7:9], self.eth_load, config.net_alert)
|
||||
self.eth_load.items = [(config.icon_eth + config.icon_dl, ethd_v)
|
||||
,(config.icon_ul, ethu_v)]
|
||||
|
||||
# Volume
|
||||
mute = data[4] == 'MUTE' or data[4] == 'NONE'
|
||||
(vol,vols) = (-1,'×') if mute else (int(data[4]), data[4]+'%')
|
||||
icon_v = config.icon_vol_mute if vol == 0 else \
|
||||
config.icon_vol_low if vol < 50 else config.icon_vol
|
||||
self.volume.items = [(icon_v, vols)]
|
||||
|
||||
# Date and time
|
||||
self.date.items = [(config.icon_clock, ' '.join(data[0:3]))]
|
||||
self.time.items = [('', data[3] if common.show_secs else data[3][:-3])]
|
||||
|
||||
class ConkySlowModule(LemonModule):
|
||||
|
||||
def __init__(self):
|
||||
self.prefix = 'CNK_SLOW'
|
||||
super().__init__()
|
||||
|
||||
def _start_module(self):
|
||||
self.p_handle = subprocess.Popen(['conky', '-c', config.path+'conky_slow'],
|
||||
stdout=subprocess.PIPE, text=True)
|
||||
self.status_handle = self.p_handle.stdout
|
||||
|
||||
self.sys_load = parser.IconTextUnit('sys_load', action='load', order=10)
|
||||
self.disk = parser.IconTextUnit('disk', order=11)
|
||||
self.brightness = parser.IconTextUnit('brightness', action='adj_br', order=21
|
||||
, external={'BRIGHT': self.parse_brightness})
|
||||
self.battery = parser.IconTextUnit('battery', action='dpms', order=22)
|
||||
self.language = parser.IconTextUnit('language', action='lang', order=32
|
||||
, external={'LANG': self.parse_language})
|
||||
|
||||
parser.g_parser.register_unit(self.sys_load)
|
||||
parser.g_parser.register_unit(self.disk)
|
||||
parser.g_parser.register_unit(self.brightness)
|
||||
parser.g_parser.register_unit(self.battery)
|
||||
parser.g_parser.register_unit(self.language)
|
||||
|
||||
def _stop_module(self):
|
||||
parser.g_parser.remove_unit(self.sys_load)
|
||||
parser.g_parser.remove_unit(self.disk)
|
||||
parser.g_parser.remove_unit(self.brightness)
|
||||
parser.g_parser.remove_unit(self.battery)
|
||||
parser.g_parser.remove_unit(self.language)
|
||||
|
||||
if self.p_handle is not None:
|
||||
self.p_handle.terminate()
|
||||
|
||||
def _parse_data(self, data):
|
||||
self.parse_sys_load (data[0:2]) # System load
|
||||
self.parse_disk (data[2:4]) # Disk usage
|
||||
self.parse_battery (data[4:5]) # Battery
|
||||
self.parse_brightness (data[5:6]) # Screen brightness
|
||||
self.parse_language (data[6:7]) # Language
|
||||
|
||||
def parse_sys_load(self, data):
|
||||
if int(data[0]) > int(config.cpu_alert):
|
||||
self.sys_load.alt_scheme = parser.COLOR_SCHEME.CPU_ALERT
|
||||
else:
|
||||
self.sys_load.alt_scheme = None
|
||||
|
||||
self.sys_load.items = [(config.icon_cpu, data[0] + '%')
|
||||
,(config.icon_ul, data[1])]
|
||||
|
||||
def parse_disk(self, data):
|
||||
self.disk.items = [(config.icon_hd , data[0] + '%')
|
||||
,(config.icon_home, data[1] + '%')]
|
||||
def parse_battery(self, data):
|
||||
(batt_stat, batt) = (data[0][0], data[0][1:])
|
||||
batt_i = int(batt)
|
||||
icon_batt = config.icon_charging if batt_stat == 'C' else \
|
||||
config.icon_charged if batt_stat == 'F' else \
|
||||
config.icon_batt_0 if batt_i < 20 else \
|
||||
config.icon_batt_1 if batt_i < 40 else \
|
||||
config.icon_batt_2 if batt_i < 60 else \
|
||||
config.icon_batt_3 if batt_i < 80 else \
|
||||
config.icon_batt_4
|
||||
self.battery.items = [(icon_batt, batt+'%')]
|
||||
|
||||
def parse_brightness(self, data):
|
||||
brtxt = str(int(float(data[0])))
|
||||
self.brightness.items = [(config.icon_bright, brtxt+'%')]
|
||||
|
||||
def parse_language(self, data):
|
||||
self.language.items = [(config.icon_lang, data[0])]
|
||||
|
||||
class i3Module(LemonModule):
|
||||
# Handles outputs (displays), workspaces and active window
|
||||
# TODO trigger formatting
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.displays = ''
|
||||
self.win_title = ''
|
||||
self.workspaces = ''
|
||||
|
||||
def _start_module(self):
|
||||
self.i3_ws_obj = wspaces.i3ws(logger=common.logger)
|
||||
|
||||
self.displays = parser.CustomUnit('displays', format_function = self.format_displays, order=-30)
|
||||
self.workspaces = parser.CustomUnit('workspaces', format_function = self.format_workspaces, order=-20)
|
||||
self.title = parser.CustomUnit('title', format_function = self.format_title, order=-10)
|
||||
self.displays.modes.append(common.bar_mode.control)
|
||||
self.workspaces.modes.append(common.bar_mode.control)
|
||||
|
||||
parser.g_parser.register_unit(self.displays)
|
||||
parser.g_parser.register_unit(self.workspaces)
|
||||
parser.g_parser.register_unit(self.title)
|
||||
|
||||
# Add callbacks for parsing
|
||||
self.i3_ws_obj.change_callbacks.append(self.parse_displays)
|
||||
self.i3_ws_obj.change_callbacks.append(self.parse_workspaces)
|
||||
self.i3_ws_obj.focus_callbacks.append(self.parse_title)
|
||||
|
||||
# Add callbacks for special actions
|
||||
self.i3_ws_obj.change_callbacks.append(i3Module.set_bg)
|
||||
self.i3_ws_obj.focus_callbacks.append(i3Module.set_keymap)
|
||||
self.i3_ws_obj.focus_callbacks.append(i3Module.kill_floating_windows)
|
||||
|
||||
def _stop_module(self):
|
||||
parser.g_parser.remove_unit(self.displays)
|
||||
parser.g_parser.remove_unit(self.workspaces)
|
||||
parser.g_parser.remove_unit(self.title)
|
||||
|
||||
if self.i3_ws_obj is not None:
|
||||
self.i3_ws_obj.quit()
|
||||
|
||||
# Overload run as i3_ws_obj.work() is a blocking command
|
||||
# Parsing is instead done through callbacks
|
||||
def run(self):
|
||||
common.logger.info('Started module {}'.format(self.__class__.__name__))
|
||||
common.health_logger.info('Module {} up'.format(self.__class__.__name__))
|
||||
|
||||
self.i3_ws_obj.work() # This is a blocking command
|
||||
|
||||
common.logger.info('Reached end of module {}'.format(self.__class__.__name__))
|
||||
common.health_logger.info('Module {} down'.format(self.__class__.__name__))
|
||||
|
||||
def parse_displays(self, i3ws):
|
||||
parsed_list = [parser.block(click='displays', font='2')]
|
||||
for output in i3ws.outputs:
|
||||
output_name = output.name
|
||||
if output.active:
|
||||
if output_name == 'eDP1':
|
||||
col_head = config.color_head
|
||||
elif output_name == 'DP1':
|
||||
col_head = config.color_vga
|
||||
elif output_name == 'HDMI2':
|
||||
col_head = config.color_hdmi
|
||||
else:
|
||||
col_head = '#00000000' # Undefined
|
||||
parsed_list.append(parser.block(fg=config.color_back, bg=col_head))
|
||||
parsed_list.append(config.icon_wsp)
|
||||
parsed_list.append(parser.block(click=''))
|
||||
|
||||
self.displays = ' '.join(parsed_list)
|
||||
|
||||
def parse_workspaces(self, i3ws):
|
||||
prefix = parser.block(font='1', fg=config.color_back, bg=config.color_head)
|
||||
prefix_foc = ''.join([parser.block(fg = config.color_head, bg=config.color_wsp)
|
||||
, ' ', config.sep_right, ' '
|
||||
, parser.block(fg=config.color_back, bg=config.color_wsp, font='1')])
|
||||
prefix_ina = parser.block(fg=config.color_back, bg=config.color_head, font='1', append=' ')
|
||||
wspces = []
|
||||
|
||||
for workspace in i3ws.workspaces:
|
||||
# Find out which output the workspace is on
|
||||
output = None # TODO actually use this information
|
||||
for output_ in i3ws.outputs:
|
||||
if output_['name'] == workspace['output']:
|
||||
output = output_
|
||||
break
|
||||
if not output:
|
||||
continue
|
||||
status = i3ws.state.get_state(workspace, output) # FOC or INA
|
||||
name = workspace['name'] # e.g. 5 terms
|
||||
current = ''.join([parser.block(click=('i3-msg workspace' + name))
|
||||
, name, parser.block(click='')])
|
||||
if status == "FOC":
|
||||
wspces.append(''.join([prefix_foc, current]))
|
||||
else:
|
||||
wspces.append(''.join([prefix_ina, current]))
|
||||
|
||||
self.workspaces = ''.join([prefix, ' '.join(wspces)])
|
||||
|
||||
def parse_title(self, i3ws):
|
||||
if i3ws.focused_window is None:
|
||||
return
|
||||
self.win_title = ' '.join([parser.block(fg=config.color_head, bg=config.color_sec_b2)
|
||||
, config.sep_right, parser.block(fg=config.color_head, bg=config.color_sec_b2, click='mode cycle')
|
||||
, config.icon_prog
|
||||
, parser.block(fg=config.color_sec_b2, bg='-')
|
||||
, i3ws.focused_window.name])
|
||||
|
||||
def format_displays(self):
|
||||
return self.displays
|
||||
|
||||
def format_workspaces(self):
|
||||
return self.workspaces
|
||||
|
||||
def format_title(self):
|
||||
return self.win_title
|
||||
|
||||
def img_path(num):
|
||||
dir = '/home/kuba/Obrazy/Wallpapers/'
|
||||
return dir + {
|
||||
1: '1_main',
|
||||
2: '2_web',
|
||||
3: '3_music',
|
||||
4: '4_work',
|
||||
5: '5_terms',
|
||||
6: '6_stats',
|
||||
7: '7',
|
||||
8: '8',
|
||||
9: '9',
|
||||
}.get(int(num), 'default')
|
||||
|
||||
def set_bg(i3ws):
|
||||
cmd_args = ['sh', '/home/kuba/scripts/set_bg.sh']
|
||||
for output in i3ws.outputs:
|
||||
if output.active:
|
||||
bg = i3Module.img_path(output.current_workspace.partition(' ')[0])
|
||||
cmd_args.append(bg)
|
||||
subprocess.call(cmd_args)
|
||||
|
||||
def kill_floating_windows(i3ws):
|
||||
if i3ws.focused_window is None:
|
||||
return
|
||||
|
||||
role = i3ws.focused_window.window_role
|
||||
wclass = i3ws.focused_window.window_class
|
||||
|
||||
if role != 'FLOAT_TERM' and wclass != 'FLOAT_PAVU' and wclass != 'YADWINBR':
|
||||
# Is there a window that the bar has opened?
|
||||
for pid in common.kill_on_unfocus:
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
except ProcessLookupError:
|
||||
common.logger.debug('Tried killing process {} but it doesn\'t exist'.format(pid))
|
||||
common.kill_on_unfocus = []
|
||||
|
||||
def set_keymap(i3ws):
|
||||
if i3ws.focused_window is None:
|
||||
return
|
||||
wclass = i3ws.focused_window.window_class
|
||||
common.cur_class = wclass
|
||||
|
||||
if wclass in common.keymaps:
|
||||
new_km = common.keymaps[wclass]
|
||||
common.logger.debug('Setting {} as keymap for {}'.format(new_km, wclass))
|
||||
else:
|
||||
new_km = common.def_keymap
|
||||
common.logger.debug('Setting default keymap {} for {}'.format(new_km, wclass))
|
||||
subprocess.call(['/home/kuba/.i3/scripts/lang.sh', 'qset', new_km])
|
||||
|
||||
class ScreenModule(LemonModule):
|
||||
|
||||
def __init__(self):
|
||||
self.prefix = 'RESP'
|
||||
super().__init__()
|
||||
|
||||
def _start_module(self):
|
||||
# No external commands needed
|
||||
self.status_handle = None
|
||||
|
||||
self.controls = parser.ButtonsUnit('controls', order=-10)
|
||||
self.response = parser.IconTextUnit('response', order=10)
|
||||
|
||||
self.controls.items = [('', config.icon_prog, 'mode cycle')
|
||||
,('', '', None)
|
||||
,('', 'on', 'bluetooth power on')
|
||||
,('', 'off', 'bluetooth power off')
|
||||
,('PXC 550', '', None)
|
||||
,('', 'conn.', 'bluetooth connect pxc550')
|
||||
,('', 'disc.', 'bluetooth disconnect pxc550')
|
||||
]
|
||||
|
||||
self.response.modes = [common.bar_mode.control]
|
||||
self.controls.modes = [common.bar_mode.control]
|
||||
|
||||
parser.g_parser.register_unit(self.response)
|
||||
parser.g_parser.register_unit(self.controls)
|
||||
|
||||
def _stop_module(self):
|
||||
parser.g_parser.remove_unit(self.response)
|
||||
parser.g_parser.remove_unit(self.controls)
|
||||
|
||||
def _parse_data(self, data):
|
||||
self.response.items = [('', ' '.join(data))]
|
||||
|
||||
class PowerOptionsModule(LemonModule):
|
||||
|
||||
def __init__(self):
|
||||
self.prefix = ''
|
||||
super().__init__()
|
||||
|
||||
def _start_module(self):
|
||||
# No external commands needed
|
||||
self.status_handle = None
|
||||
|
||||
self.power_opts = parser.CustomUnit('power', format_function=self.format_power_opts, order=-1)
|
||||
|
||||
self.power_opts.modes = [common.bar_mode.power]
|
||||
|
||||
parser.g_parser.register_unit(self.power_opts)
|
||||
|
||||
def _stop_module(self):
|
||||
parser.g_parser.remove_unit(self.power_opts)
|
||||
|
||||
def _parse_data(self, data):
|
||||
pass
|
||||
|
||||
def format_power_opts(self):
|
||||
return ''.join([parser.block(fg=config.color_fore, bg=config.color_poweropts)
|
||||
, ' Abort (Esc) | System (l) lock, (e) logout, (s) suspend, (h) hibernate'
|
||||
, ', (r) reboot, (Shift+s) shutdown'])
|
||||
|
||||
def start_all():
|
||||
global m_conky_fast, m_conky_slow, m_i3ws
|
||||
|
||||
m_i3ws = i3Module()
|
||||
m_conky_slow = ConkySlowModule()
|
||||
m_conky_fast = ConkyFastModule()
|
||||
m_screen = ScreenModule()
|
||||
m_power = PowerOptionsModule()
|
||||
|
||||
m_i3ws.start()
|
||||
m_conky_slow.start()
|
||||
m_conky_fast.start()
|
||||
m_screen.start()
|
||||
m_power.start()
|
||||
|
||||
def stop_all():
|
||||
global m_conky_fast, m_conky_slow, m_i3ws
|
||||
|
||||
m_i3ws.stop()
|
||||
m_conky_slow.stop()
|
||||
m_conky_fast.stop()
|
||||
m_screen.stop()
|
||||
m_power.stop()
|
||||
@@ -1,204 +0,0 @@
|
||||
import sys
|
||||
import bisect # Sorting of list
|
||||
from enum import Enum
|
||||
import i3_lemonbar_config as config
|
||||
import i3_lemonbar_common as common
|
||||
|
||||
sr = config.sep_right
|
||||
slr = config.sep_l_right
|
||||
sl = config.sep_left
|
||||
sll = config.sep_l_left
|
||||
|
||||
class IconTextUnit:
|
||||
def __init__(self, name, order, action = None, alt_scheme=None, external=None):
|
||||
self.name = name
|
||||
self.action = action
|
||||
self.order = order
|
||||
self.alt_scheme = alt_scheme # None means default
|
||||
self.external = external
|
||||
self.items = [] # List of tuples (icon, text)
|
||||
self.modes = [common.bar_mode.normal]
|
||||
|
||||
def format(self):
|
||||
close = block(click='') if self.action is not None else ''
|
||||
|
||||
b_color = self.alt_scheme.back_color
|
||||
i_color = self.alt_scheme.icon_color
|
||||
t_color = self.alt_scheme.text_color
|
||||
|
||||
# Start with a major separator. Keep previous background color, set foreground color
|
||||
# of separator to background color of this unit
|
||||
blocks = []
|
||||
blocks.append(block(fg=b_color, append=sl))
|
||||
blocks.append(' ') # TODO perhaps more nice solution than manual spacing
|
||||
if len(self.items) >= 1:
|
||||
(icon, text) = self.items[0]
|
||||
blocks.append(block(click=self.action, fg=i_color, bg=b_color, font='2'
|
||||
, append=' ' + icon))
|
||||
blocks.append(' ')
|
||||
blocks.append(block(fg=t_color, font='1', append=text))
|
||||
if len(self.items) >= 2:
|
||||
for item in self.items[1:]:
|
||||
(icon, text) = item
|
||||
# Append minor separator
|
||||
blocks.append(' ')
|
||||
blocks.append(sll)
|
||||
|
||||
blocks.append(block(fg=i_color, bg=b_color, font='2', append=' ' + icon))
|
||||
blocks.append(' ')
|
||||
blocks.append(block(fg=t_color, font='1', append=text))
|
||||
|
||||
if len(self.items) >= 1:
|
||||
blocks.append(close)
|
||||
return ''.join(blocks)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.order < other.order
|
||||
|
||||
class ButtonsUnit:
|
||||
def __init__(self, name, order, alt_scheme=None, external=None):
|
||||
self.name = name
|
||||
self.order = order
|
||||
self.alt_scheme = alt_scheme # None means default
|
||||
self.external = external
|
||||
self.items = [] # List of tuples (icon, text, action)
|
||||
self.modes = [common.bar_mode.normal]
|
||||
|
||||
def format(self):
|
||||
b_color = self.alt_scheme.back_color
|
||||
i_color = self.alt_scheme.icon_color
|
||||
t_color = self.alt_scheme.text_color
|
||||
|
||||
# Start with a major separator. Keep previous background color, set foreground color
|
||||
# of separator to background color of this unit
|
||||
blocks = []
|
||||
blocks.append(block(fg=b_color, append=sl))
|
||||
blocks.append(' ')
|
||||
for item in self.items:
|
||||
(icon, text, action) = item
|
||||
close = block(click='') if action is not None else ''
|
||||
|
||||
blocks.append(block(click=action, fg=i_color, bg=b_color, font='2'
|
||||
, append=' ' + icon))
|
||||
blocks.append(' ')
|
||||
blocks.append(block(fg=t_color, font='1', append=text))
|
||||
blocks.append(close)
|
||||
|
||||
return ''.join(blocks)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.order < other.order
|
||||
|
||||
class CustomUnit:
|
||||
def __init__(self, name, format_function, order, action = None, alt_scheme=None, external=None):
|
||||
self.name = name
|
||||
self.action = action
|
||||
self.order = order
|
||||
self.alt_scheme = alt_scheme # None means default
|
||||
self.external = external
|
||||
self.format = format_function
|
||||
self.items = [] # List of tuples (icon, text)
|
||||
self.modes = [common.bar_mode.normal]
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.order < other.order
|
||||
|
||||
class LemonParser:
|
||||
# Handle parsing of units
|
||||
# Apply alternating colors
|
||||
# Contains list of units
|
||||
|
||||
def __init__(self):
|
||||
self.units = []
|
||||
|
||||
def register_unit(self, unit):
|
||||
# Keep the list sorted
|
||||
bisect.insort_left(self.units, unit)
|
||||
|
||||
def remove_unit(self, unit):
|
||||
self.units.remove(unit)
|
||||
|
||||
def format(self):
|
||||
formatted = ['%{l}'] # Start left-justified
|
||||
previously_left_justified = True
|
||||
# Iterate over all units. Apply alternating color schemes
|
||||
alt = 1
|
||||
for unit in self.units:
|
||||
# Show only units appropriate for the current mode
|
||||
if common.mode not in unit.modes:
|
||||
continue
|
||||
|
||||
# Negative order means left justified, positive means right justified
|
||||
if previously_left_justified and unit.order > 0:
|
||||
# Switch to right justified
|
||||
formatted.append(block(fg='-', bg='-')) # Reset so the color doesn't fill
|
||||
formatted.append('%{r}')
|
||||
previously_left_justified = False
|
||||
|
||||
if unit.alt_scheme is None:
|
||||
# Apply default color scheme, which is alternating
|
||||
unit.alt_scheme = COLOR_SCHEME.A1 if alt == 1 else COLOR_SCHEME.A2
|
||||
else:
|
||||
# Keep alternate color scheme
|
||||
# INA is a special case
|
||||
if unit.alt_scheme == COLOR_SCHEME.INA:
|
||||
unit.alt_scheme = COLOR_SCHEME.A1_INA if alt == 1 else COLOR_SCHEME.A2_INA
|
||||
|
||||
formatted.append(unit.format())
|
||||
alt = alt + 1 if alt + 1 <= 2 else 1
|
||||
|
||||
formatted.append(block(fg='-', bg='-')) # Not sure if needed
|
||||
return ' '.join(formatted)
|
||||
|
||||
g_parser = LemonParser()
|
||||
|
||||
def block(fg = None, bg = None, font = None, click = None, append=''):
|
||||
# Remeber that clickable blocks need to be closed
|
||||
rtn = []
|
||||
if click is not None:
|
||||
if click == '':
|
||||
rtn.append('A')
|
||||
else:
|
||||
rtn.append('A:'+click+':')
|
||||
if fg is not None:
|
||||
rtn.append('F'+fg)
|
||||
if bg is not None:
|
||||
rtn.append('B'+bg)
|
||||
if font is not None:
|
||||
rtn.append('T'+font)
|
||||
return ''.join(['%{', ' '.join(rtn), '}', append])
|
||||
|
||||
class COLOR_SCHEME(Enum):
|
||||
A1 = (config.color_sec_b1, config.color_fore, config.color_icon)
|
||||
A2 = (config.color_sec_b2, config.color_fore, config.color_icon)
|
||||
INA = (None, None, None) # This one is special, dynamically changed to A1_INA or A2_INA
|
||||
A1_INA = (config.color_sec_b1, config.color_disable, config.color_disable)
|
||||
A2_INA = (config.color_sec_b2, config.color_disable, config.color_disable)
|
||||
CPU_ALERT= (config.color_cpu, config.color_back, config.color_back)
|
||||
NET_ALERT= (config.color_net, config.color_back, config.color_back)
|
||||
SPECIAL = (config.color_head, config.color_back, config.color_back)
|
||||
def __init__(self, back_color, text_color, icon_color):
|
||||
self.back_color = back_color
|
||||
self.text_color = text_color
|
||||
self.icon_color = icon_color
|
||||
|
||||
def format_line():
|
||||
return g_parser.format()
|
||||
|
||||
def parse_line(line_in):
|
||||
# Parse lines that external programs have written to fifo
|
||||
|
||||
for unit in g_parser.units:
|
||||
if unit.external is not None:
|
||||
for key,func in unit.external.items():
|
||||
l = len(key)
|
||||
if line_in[:l] == key:
|
||||
func(line_in[l:].split())
|
||||
break
|
||||
|
||||
formatted_line = format_line()
|
||||
return formatted_line
|
||||
|
||||
if __name__ == "__main__":
|
||||
for line in sys.stdin:
|
||||
print(parse_line(line))
|
||||
@@ -1,182 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Print i3 workspaces on every change.
|
||||
#
|
||||
# Format:
|
||||
# For every workspace (x = workspace name)
|
||||
# - "FOCx" -> Focused workspace
|
||||
# - "INAx" -> Inactive workspace
|
||||
# - "ACTx" -> Ative workspace
|
||||
# - "URGx" -> Urgent workspace
|
||||
#
|
||||
# Based in wsbar.py en examples dir
|
||||
#
|
||||
# 16 feb 2015 - Electro7
|
||||
|
||||
|
||||
import sys, os, signal
|
||||
import logging
|
||||
import time
|
||||
from subprocess import call
|
||||
import i3ipc
|
||||
|
||||
print_stdout = False
|
||||
|
||||
class State(object):
|
||||
# workspace states
|
||||
focused = 'FOC'
|
||||
active = 'ACT'
|
||||
inactive = 'INA'
|
||||
urgent = 'URG'
|
||||
|
||||
def get_state(self, workspace, output):
|
||||
if workspace['focused']:
|
||||
if output['current_workspace'] == workspace['name']:
|
||||
return self.focused
|
||||
else:
|
||||
return self.active
|
||||
if workspace['urgent']:
|
||||
return self.urgent
|
||||
else:
|
||||
return self.inactive
|
||||
|
||||
|
||||
# Create the i3ws object, then call locking function work()
|
||||
# Another implementation would be to create a thread in __init__
|
||||
# and implement a locking join() function
|
||||
class i3ws(object):
|
||||
ws_format = '%s%s '
|
||||
end_format = 'WSP%s'
|
||||
|
||||
def __init__(self, logger, state=None):
|
||||
self.state = State()
|
||||
self.outputs = []
|
||||
self.workspaces = []
|
||||
self.focused_window = None
|
||||
self.running = True
|
||||
if state:
|
||||
self.state = state
|
||||
self.logger = logger
|
||||
|
||||
# Callback functions have argument i3ws
|
||||
self.change_callbacks = []
|
||||
self.focus_callbacks = []
|
||||
|
||||
def work(self):
|
||||
# While loop to restart connection as long as there is an i3 ipc socket
|
||||
while self.running:
|
||||
self.resetConn()
|
||||
self.logger.debug('Started i3 workspaces manager')
|
||||
self.enterMain()
|
||||
self.logger.debug('Finished i3 workspaces manager')
|
||||
time.sleep(0.5) # TODO max number of attempts + catch exception instead
|
||||
|
||||
def resetConn(self):
|
||||
self.conn = i3ipc.Connection()
|
||||
|
||||
# Run call backs once
|
||||
for cb in self.change_callbacks:
|
||||
cb(self)
|
||||
|
||||
for cb in self.focus_callbacks:
|
||||
cb(self)
|
||||
|
||||
self.conn.on('workspace::focus' , self.change)
|
||||
self.conn.on('workspace::init' , self.change)
|
||||
self.conn.on('workspace::empty' , self.change)
|
||||
self.conn.on('window::focus' , self.win_focused)
|
||||
self.conn.on('shutdown' , self.shutdown)
|
||||
|
||||
def enterMain(self):
|
||||
try:
|
||||
# Locking call
|
||||
self.conn.main()
|
||||
except BrokenPipeError:
|
||||
self.logger.debug('Broken pipe in i3 workspaces thread, exiting')
|
||||
except:
|
||||
self.logger.debug('Unknown exception in i3 workspaces thread, exiting')
|
||||
|
||||
def shutdown(self, i3, e):
|
||||
self.logger.debug('Shut down i3ipc')
|
||||
|
||||
def change(self, i3, e):
|
||||
# Receives event and workspace data
|
||||
self.outputs = i3.get_outputs()
|
||||
fmt_outputs = ['DISP']
|
||||
for output in self.outputs:
|
||||
if output.active:
|
||||
fmt_outputs.append(output.name)
|
||||
self.display(':'.join(fmt_outputs))
|
||||
|
||||
self.workspaces = i3.get_workspaces()
|
||||
text = self.format(self.workspaces, self.outputs)
|
||||
self.display(text)
|
||||
|
||||
# Callbacks
|
||||
for cb in self.change_callbacks:
|
||||
cb(self)
|
||||
|
||||
def win_focused(self, i3, e):
|
||||
self.focused_window = i3.get_tree().find_focused()
|
||||
name = self.focused_window.name
|
||||
text = 'WIN{}'.format(name)
|
||||
self.display(text)
|
||||
|
||||
# Callbacks
|
||||
for cb in self.focus_callbacks:
|
||||
cb(self)
|
||||
|
||||
def format(self, workspaces, outputs):
|
||||
# Formats the text according to the workspace data given.
|
||||
# Only important when running in free standing mode
|
||||
out = ''
|
||||
for workspace in workspaces:
|
||||
output = None
|
||||
for output_ in outputs:
|
||||
if output_['name'] == workspace['output']:
|
||||
output = output_
|
||||
break
|
||||
if not output:
|
||||
continue
|
||||
st = self.state.get_state(workspace, output)
|
||||
name = workspace['name'].replace(" ","___")
|
||||
item= self.ws_format % (st, name)
|
||||
out += item
|
||||
return self.end_format % out
|
||||
|
||||
def display(self, text):
|
||||
global print_stdout
|
||||
if print_stdout:
|
||||
# Displays the text in stout
|
||||
print(text)
|
||||
sys.stdout.flush()
|
||||
|
||||
def quit(self):
|
||||
self.logger.debug('Quitting i3 workspace script')
|
||||
self.running = False
|
||||
self.conn.main_quit()
|
||||
|
||||
def handle_exit(signal, frame):
|
||||
global ws
|
||||
print("Recieved Keyboard Interrupt from user")
|
||||
ws.quit()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Run as stand-alone
|
||||
print_stdout = True
|
||||
|
||||
# Setup logger to stdout with debug log level
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
logger = logging.getLogger('Normal logger')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
|
||||
# Capture Keyboard Interrupt (i3ipc captures this internally)
|
||||
signal.signal(signal.SIGINT, handle_exit)
|
||||
|
||||
# Start main
|
||||
ws = i3ws(logger = logger)
|
||||
ws.work()
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
function get_index(){
|
||||
for i in "${!xra_out[@]}"; do
|
||||
if [[ "${xra_out[$i]}" = "$value" ]]; then
|
||||
echo "${i}";
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
xra_out=($(xrandr | grep ' connected' | awk '{print $1}'))
|
||||
in=($@)
|
||||
for i in `seq 0 2 ${#in[@]}`; do
|
||||
value="${in[$i]}"
|
||||
idx=$(get_index)
|
||||
if [ ! -z "$idx" ]; then
|
||||
screen_idx="$idx"
|
||||
#"${xra_out[$idx-1]}"
|
||||
paths[${screen_idx%:}]="--bg-scale ${in[$i+1]}"
|
||||
fi
|
||||
done
|
||||
#echo "${paths[@]}"
|
||||
str=`printf -v var "%s\n" "${System[@]}"`
|
||||
sh -c "feh ${paths[@]}"
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -p /tmp/i3_lemonbar2_$USER ]]; then
|
||||
echo "$@" > /tmp/i3_lemonbar2_$USER
|
||||
fi
|
||||
@@ -16,16 +16,16 @@ if [ "$1" == "next" ]; then
|
||||
fi
|
||||
setxkbmap $next
|
||||
if [ -e $panel_fifo ]; then
|
||||
echo -e "LANG$next\n" > "${panel_fifo}"
|
||||
echo -e "LANG$next" > "${panel_fifo}"
|
||||
fi
|
||||
if [ -e $panel_commands ]; then
|
||||
echo -e "setlang $next\n" > "${panel_commands}"
|
||||
echo -e "setlang $next" > "${panel_commands}"
|
||||
fi
|
||||
elif [ "$1" == "qset" ]; then
|
||||
next=$2
|
||||
setxkbmap $next
|
||||
if [ -e $panel_fifo ]; then
|
||||
echo -e "LANG$next\n" > "${panel_fifo}"
|
||||
echo -e "LANG$next" > "${panel_fifo}"
|
||||
fi
|
||||
elif [ "$1" == "show" ]; then
|
||||
show
|
||||
|
||||
22
.i3initrc
Normal file
22
.i3initrc
Normal file
@@ -0,0 +1,22 @@
|
||||
# Generate my i3 config based on hostname
|
||||
# Needs to be sourced by .xprofile (GDM) or .xinitrc (startx)
|
||||
|
||||
# Generate i3 config file
|
||||
i3config="/tmp/i3_${USER}_config"
|
||||
rm -f $i3config
|
||||
|
||||
if [ -f ~/.i3/base.config ]; then
|
||||
cat ~/.i3/base.config >> $i3config
|
||||
fi
|
||||
|
||||
if [ "`hostname`" = "kubaArch-Laptop" ] && [ -f ~/.i3/home.config ]; then
|
||||
cat ~/.i3/home.config >> $i3config
|
||||
elif [ "`hostname`" = "kubaDesktop" ] && [ -f ~/.i3/home.config ]; then
|
||||
cat ~/.i3/home.config >> $i3config
|
||||
elif [ "`hostname`" = "JakubArch" ] && [ -f ~/.i3/work.config ]; then
|
||||
cat ~/.i3/work.config >> $i3config
|
||||
fi
|
||||
|
||||
#exec i3 -c $i3config -V >> ~/${WM}.log 2>&1
|
||||
sh ~/scripts/displays.sh auto
|
||||
exec i3 -c $i3config
|
||||
0
.modules.kuba/ase/.version
Normal file
0
.modules.kuba/ase/.version
Normal file
27
.modules.kuba/ase/Vera/dev.lua
Normal file
27
.modules.kuba/ase/Vera/dev.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
whatis("Ase")
|
||||
|
||||
conflict("ASE")
|
||||
|
||||
function ld (m)
|
||||
if not ( isloaded(m) ) then
|
||||
load(m)
|
||||
end
|
||||
end
|
||||
|
||||
ld("iccifort/2019.5.281")
|
||||
ld("impi/2018.5.288")
|
||||
ld("imkl/2019.5.281")
|
||||
ld("Python/3.7.4")
|
||||
ld("Tkinter/3.7.4")
|
||||
ld("matplotlib/3.1.1-Python-3.7.4")
|
||||
|
||||
ld("clusterappl") -- Sets up MYNOBACKUP
|
||||
|
||||
local nobackup = os.getenv("MYNOBACKUP")
|
||||
local root = pathJoin(nobackup, "git/ase/dev")
|
||||
|
||||
prepend_path("PYTHONPATH", root)
|
||||
prepend_path("PATH", pathJoin(root, "tools"))
|
||||
prepend_path("PATH", pathJoin(root, "bin"))
|
||||
|
||||
execute {cmd='complete -o default -C "/usr/bin/python3 ' .. root .. '/ase/cli/complete.py" ase', modeA={"load"}}
|
||||
25
.modules.kuba/clusterappl.lua
Normal file
25
.modules.kuba/clusterappl.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
whatis([==[
|
||||
Creates $USERAPPL environment variable and adds paths
|
||||
]==])
|
||||
|
||||
local pyver = subprocess([[python --version 2>&1 | sed 's/.*\([23]\.[0-9]\).*/\1/']])
|
||||
if pyver:sub(1, 1) == "2" then
|
||||
LmodError("Must have Python 3 loaded")
|
||||
end
|
||||
|
||||
local home = os.getenv("HOME")
|
||||
local nobackup = pathJoin(home, "nobackup")
|
||||
local userappl = pathJoin(nobackup, "appl")
|
||||
local git = pathJoin(nobackup, "git")
|
||||
local pythonp = pathJoin(userappl, "lib", "python" .. pyver, "site-packages")
|
||||
local binp = pathJoin(userappl, "bin")
|
||||
local libp = pathJoin(userappl, "lib")
|
||||
|
||||
setenv("MYNOBACKUP", nobackup)
|
||||
setenv("USERAPPL", userappl)
|
||||
|
||||
prepend_path("PYTHONPATH", pythonp)
|
||||
prepend_path("PYTHONPATH", ".")
|
||||
prepend_path("PATH", binp)
|
||||
prepend_path("LD_LIBRARY_PATH", libp)
|
||||
execute {cmd='`snakemake --bash-completion`', modeA={"load"}}
|
||||
7
.modules.kuba/gpaw-setups/0.9.20000.lua
Normal file
7
.modules.kuba/gpaw-setups/0.9.20000.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
local name = myModuleName()
|
||||
local version = myModuleVersion()
|
||||
local home = os.getenv("HOME")
|
||||
local setups_root = pathJoin(home, "gpaw-setups", version)
|
||||
|
||||
prepend_path("GPAW_SETUP_PATH", pathJoin(setups_root, "gpaw-setups-" .. version))
|
||||
prepend_path("GPAW_SETUP_PATH", pathJoin(setups_root, "gpaw-basis-pvalence-" .. version))
|
||||
0
.modules.kuba/gpaw/.version
Normal file
0
.modules.kuba/gpaw/.version
Normal file
26
.modules.kuba/gpaw/Tetralith/20.1.0.lua
Normal file
26
.modules.kuba/gpaw/Tetralith/20.1.0.lua
Normal file
@@ -0,0 +1,26 @@
|
||||
whatis([==[My compiled version of GPAW]==])
|
||||
|
||||
unload("GPAW")
|
||||
|
||||
function ld (m)
|
||||
if not ( isloaded(m) ) then
|
||||
load(m)
|
||||
end
|
||||
end
|
||||
|
||||
ld("clusterappl")
|
||||
|
||||
local nobackup = os.getenv("MYNOBACKUP")
|
||||
local root = pathJoin(nobackup, "git/gpaw/20.1.0")
|
||||
|
||||
ld("Python/3.6.7-env-nsc1-gcc-2018a-eb")
|
||||
-- ld("Python/3.6.3-anaconda-5.0.1-nsc1")
|
||||
ld("ASE/3.18.0-nsc1")
|
||||
|
||||
ld("gpaw-setups/0.9.20000")
|
||||
|
||||
setenv("OMP_NUM_THREADS", 1)
|
||||
prepend_path("PATH", pathJoin(root, "tools"))
|
||||
prepend_path("PYTHONPATH", root)
|
||||
prepend_path("PYTHONPATH", pathJoin(root, "build/lib.linux-x86_64-3.7"))
|
||||
execute {cmd='complete -o default -C "/usr/bin/python3 ' .. root .. '/gpaw/cli/complete.py" gpaw', modeA={"load"}}
|
||||
1
.modules.kuba/gpaw/Vera/20.1.0.lua
Symbolic link
1
.modules.kuba/gpaw/Vera/20.1.0.lua
Symbolic link
@@ -0,0 +1 @@
|
||||
dev.lua
|
||||
23
.modules.kuba/gpaw/Vera/dev.lua
Normal file
23
.modules.kuba/gpaw/Vera/dev.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
whatis([==[My compiled version of GPAW]==])
|
||||
|
||||
unload("GPAW")
|
||||
|
||||
function ld (m)
|
||||
if not ( isloaded(m) ) then
|
||||
load(m)
|
||||
end
|
||||
end
|
||||
|
||||
ld("ase/dev")
|
||||
ld("libxc/4.3.4")
|
||||
ld("gpaw-setups/0.9.20000")
|
||||
|
||||
local _, version = splitFileName(myModuleVersion())
|
||||
local nobackup = os.getenv("MYNOBACKUP")
|
||||
local root = pathJoin(nobackup, "git/gpaw", version)
|
||||
|
||||
setenv("OMP_NUM_THREADS", 1)
|
||||
prepend_path("PATH", pathJoin(root, "tools"))
|
||||
prepend_path("PYTHONPATH", root)
|
||||
prepend_path("PYTHONPATH", pathJoin(root, "build/lib.linux-x86_64-3.7"))
|
||||
execute {cmd='complete -o default -C "/usr/bin/python3 ' .. root .. '/gpaw/cli/complete.py" gpaw', modeA={"load"}}
|
||||
1
.modules.kuba/gpaw/Vera/jfojt.lua
Symbolic link
1
.modules.kuba/gpaw/Vera/jfojt.lua
Symbolic link
@@ -0,0 +1 @@
|
||||
dev.lua
|
||||
14
.modules.kuba/gpaw/jfojt.lua
Normal file
14
.modules.kuba/gpaw/jfojt.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
local name, version = splitFileName(myModuleFullName())
|
||||
local platform = "linux-x86_64-ubuntu-3.8"
|
||||
local home = os.getenv("HOME")
|
||||
local gpaw_root = pathJoin(home, "git/gpaw", version)
|
||||
|
||||
load("gpaw-setups/0.9.20000")
|
||||
|
||||
setenv("OMP_NUM_THREADS", 1)
|
||||
prepend_path("PYTHONPATH", ".")
|
||||
prepend_path("PYTHONPATH", gpaw_root)
|
||||
prepend_path("PYTHONPATH", pathJoin(gpaw_root, "build/lib." .. platform))
|
||||
prepend_path("PATH", pathJoin(gpaw_root, "tools"))
|
||||
prepend_path("PATH", pathJoin(gpaw_root, "build/bin." .. platform))
|
||||
execute {cmd='complete -o default -C "/usr/bin/python3 ' .. gpaw_root .. '/gpaw/cli/complete.py" gpaw', modeA={"load"}}
|
||||
1
.modules.kuba/gpaw/trossi-dev.lua
Symbolic link
1
.modules.kuba/gpaw/trossi-dev.lua
Symbolic link
@@ -0,0 +1 @@
|
||||
jfojt.lua
|
||||
1
.modules.kuba/gpaw/trossi.lua
Symbolic link
1
.modules.kuba/gpaw/trossi.lua
Symbolic link
@@ -0,0 +1 @@
|
||||
jfojt.lua
|
||||
8
.modules.kuba/slurm-aliases.lua
Normal file
8
.modules.kuba/slurm-aliases.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
whatis([==[
|
||||
Defines useful SLURM aliases
|
||||
]==])
|
||||
|
||||
set_alias("si", 'sinfo -e -o "%9P %4a %8s %.10l %11A %6z %.7m %40N"')
|
||||
set_alias("q", 'squeue -u $USER -o "%7A %56j %2t %16S %.10M %.10L %.2D %4N"')
|
||||
set_alias("ql", 'squeue -u $USER -o "%8A %7K %56j %2t %3r %16S %.10M %.10L %.4D %8N %4f"')
|
||||
set_alias("qa", 'squeue -o "%8A %10u %.6Q %24j %2t %3r %16S %.10M %.10L %.4D %16N" -S t,-p | less')
|
||||
81
.ssh/config
Normal file
81
.ssh/config
Normal file
@@ -0,0 +1,81 @@
|
||||
# If ssh does not have gssapi enabled:
|
||||
IgnoreUnknown GSSAPIKeyExchange
|
||||
|
||||
ForwardX11 yes
|
||||
ForwardX11Trusted yes
|
||||
ForwardAgent yes
|
||||
|
||||
Host home
|
||||
HostName isabeljake.duckdns.org
|
||||
User kuba
|
||||
Port 9216
|
||||
|
||||
Host aino
|
||||
HostName aino.fy.chalmers.se
|
||||
User jakub
|
||||
Port 22209
|
||||
|
||||
Host tahoe
|
||||
HostName tahoe.fy.chalmers.se
|
||||
User jakub
|
||||
Port 22209
|
||||
|
||||
Host geym
|
||||
HostName geym.fy.chalmers.se
|
||||
User jakub
|
||||
Port 22209
|
||||
|
||||
Host pi4
|
||||
HostName 192.168.0.200
|
||||
User ubuntu
|
||||
Port 22
|
||||
|
||||
Host pi3
|
||||
HostName 192.168.0.202
|
||||
User ubuntu
|
||||
Port 22
|
||||
|
||||
Host vera
|
||||
Hostname vera1.c3se.chalmers.se
|
||||
User fojt
|
||||
|
||||
Host vera2
|
||||
Hostname vera2.c3se.chalmers.se
|
||||
User fojt
|
||||
|
||||
Host tetralith
|
||||
Hostname tetralith1.nsc.liu.se
|
||||
User x_jakfo
|
||||
|
||||
Host tetralith2
|
||||
Hostname tetralith2.nsc.liu.se
|
||||
User x_jakfo
|
||||
|
||||
Host remote11
|
||||
HostName remote11.chalmers.se
|
||||
User fojt
|
||||
Port 22
|
||||
ControlMaster auto
|
||||
ControlPersist yes
|
||||
ControlPath ~/.ssh/socket-%r@%h:%p
|
||||
|
||||
Host beskow
|
||||
Hostname beskow.pdc.kth.se
|
||||
User fojt
|
||||
GSSAPIAuthentication yes
|
||||
GSSAPIKeyExchange yes
|
||||
GSSAPIDelegateCredentials yes
|
||||
PreferredAuthentications gssapi-keyex,gssapi-with-mic
|
||||
|
||||
Host tegner
|
||||
Hostname tegner.pdc.kth.se
|
||||
User fojt
|
||||
GSSAPIAuthentication yes
|
||||
GSSAPIKeyExchange yes
|
||||
GSSAPIDelegateCredentials yes
|
||||
PreferredAuthentications gssapi-keyex,gssapi-with-mic
|
||||
|
||||
Host *
|
||||
ForwardAgent no
|
||||
ForwardX11 no
|
||||
ForwardX11Trusted no
|
||||
5
.ssh/rc
Executable file
5
.ssh/rc
Executable file
@@ -0,0 +1,5 @@
|
||||
# Create symlink to current ssh socket, if a symlink to an active socket
|
||||
# does not exist
|
||||
if [ ! -S ~/.ssh/ssh_auth_sock ] && [ -S "$SSH_AUTH_SOCK" ]; then
|
||||
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
|
||||
fi
|
||||
10
.tmux.conf
10
.tmux.conf
@@ -2,3 +2,13 @@ unbind C-b
|
||||
set-option -g prefix C-a
|
||||
bind-key C-a send-prefix
|
||||
set -g mouse on
|
||||
|
||||
# pane movement
|
||||
bind-key j command-prompt -p "join pane from:" "join-pane -s '%%'"
|
||||
bind-key s command-prompt -p "send pane to:" "join-pane -t '%%'"
|
||||
|
||||
# ssh socket, important to create symlink in ~/.ssh/rc
|
||||
set-environment -g 'SSH_AUTH_SOCK' ~/.ssh/ssh_auth_sock
|
||||
|
||||
# Shorten delay for relaying Esc (to e.g. vim). Too short and PgUp will not work
|
||||
set -sg escape-time 20
|
||||
|
||||
201
.vimrc
201
.vimrc
@@ -23,25 +23,59 @@ if filereadable(expand(vundle_dir) . "/README.md")
|
||||
Plugin 'airblade/vim-gitgutter'
|
||||
Plugin 'jeetsukumaran/vim-pythonsense'
|
||||
Plugin 'easymotion/vim-easymotion'
|
||||
Plugin 'file:///home/kuba/git/vim-indexer'
|
||||
Plugin 'cpiger/NeoDebug'
|
||||
Plugin 'ivan-krukov/vim-snakemake'
|
||||
Plugin 'nvie/vim-flake8'
|
||||
Plugin 'ludovicchabant/vim-gutentags'
|
||||
Plugin 'junegunn/vim-peekaboo'
|
||||
|
||||
call vundle#end() " required
|
||||
else
|
||||
let vundle_repo="https://github.com/VundleVim/Vundle.vim.git"
|
||||
echo "Vundle not installed, type :CloneVundle to clone the vundle repo and install it"
|
||||
command CloneVundle execute "!git clone " . vundle_repo . " " . vundle_dir
|
||||
command! CloneVundle execute "!git clone " . vundle_repo . " " . vundle_dir | source $MYVIMRC | echo "Cloned Vundle. Do :PluginInstall"
|
||||
endif
|
||||
|
||||
if !exists("vimrc_autocmds_loaded")
|
||||
let vimrc_autocmds_loaded = 1
|
||||
|
||||
" Set the filetype based on the file's extension, but only if
|
||||
" 'filetype' has not already been set
|
||||
au BufRead,BufNewFile .i3initrc setfiletype sh
|
||||
au BufRead,BufNewFile *.config setfiletype conf
|
||||
au BufRead,BufNewFile [Ss]nakefile.* setfiletype snakemake
|
||||
|
||||
au BufWritePost * if search('\s\+$', 'wn') | call WhitespaceWarn() | endif
|
||||
|
||||
au BufRead,BufNewFile * setlocal textwidth=0 | setlocal colorcolumn=
|
||||
au BufRead,BufNewFile *.md setlocal textwidth=80 | setlocal colorcolumn=80
|
||||
au BufRead,BufNewFile *.py setlocal colorcolumn=100
|
||||
|
||||
if exists(":NERDTree")
|
||||
" Open NERDTree if no file specified
|
||||
au StdinReadPre * let s:std_in=1
|
||||
au VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
|
||||
endif
|
||||
|
||||
au BufEnter,FocusGained,InsertLeave * set rnu
|
||||
au BufLeave,FocusLost,InsertEnter * set nornu
|
||||
endif
|
||||
set updatetime=1000 " Default is 4s, but reduce it to make things more real time, like git gutter
|
||||
highlight Search ctermbg=5
|
||||
highlight ColorColumn ctermbg=4
|
||||
|
||||
filetype plugin indent on " required
|
||||
syntax on
|
||||
"
|
||||
" Set the filetype based on the file's extension, but only if
|
||||
" 'filetype' has not already been set
|
||||
au BufRead,BufNewFile *.config setfiletype conf
|
||||
|
||||
" These two lines will fully disable any visual or noisy bell
|
||||
" on both windows and linux. >:)
|
||||
set noerrorbells visualbell t_vb=
|
||||
autocmd GUIEnter * set visualbell t_vb=
|
||||
|
||||
" Make indenting and unindenting in visual mode retain the selection so
|
||||
" you don't have to re-select or type gv every time.
|
||||
vnoremap > ><CR>gv
|
||||
vnoremap < <<CR>gv
|
||||
|
||||
set tabstop=4 " show existing tab with 4 spaces width
|
||||
set shiftwidth=4 " when indenting with '>', use 4 spaces width
|
||||
@@ -53,6 +87,9 @@ set scrolloff=5 " Don't let cursor be within 5 lines from top or bottom
|
||||
|
||||
" Warn for trailing whitespace. Search with wrap (w) do not move cursor (n)
|
||||
function! WhitespaceWarn()
|
||||
if &ft =~ 'markdown'
|
||||
return
|
||||
endif
|
||||
echohl WarningMsg
|
||||
echo 'Found whitespace.'
|
||||
echohl None
|
||||
@@ -67,16 +104,11 @@ function! StripTrailingWhitespace()
|
||||
call winrestview(l:save)
|
||||
echo "Stripped trailing whitespace"
|
||||
endfunction
|
||||
autocmd BufWritePost * if search('\s\+$', 'wn') | call WhitespaceWarn() | endif
|
||||
command TrailWhitespace call StripTrailingWhitespace()
|
||||
|
||||
command! TrailWhitespace call StripTrailingWhitespace()
|
||||
|
||||
" Hybrid line numbers on active buffer
|
||||
set nu rnu
|
||||
augroup numbertoggle
|
||||
autocmd!
|
||||
autocmd BufEnter,FocusGained,InsertLeave * set rnu
|
||||
autocmd BufLeave,FocusLost,InsertEnter * set nornu
|
||||
augroup END
|
||||
|
||||
" Do incremental searching when it's possible to timeout.
|
||||
if has('reltime')
|
||||
@@ -90,14 +122,98 @@ noremap Y y$
|
||||
command! -bang -range=% -complete=file -nargs=* W <line1>,<line2>write<bang> <args>
|
||||
command! -bang Q quit<bang>
|
||||
|
||||
" Gutentags configuration
|
||||
if !executable('ctags')
|
||||
let g:gutentags_enabled = 0
|
||||
else
|
||||
let g:gutentags_add_default_project_roots = 0
|
||||
let g:gutentags_project_root = ['.git']
|
||||
|
||||
let g:gutentags_generate_on_new = 1
|
||||
let g:gutentags_generate_on_missing = 1
|
||||
let g:gutentags_generate_on_write = 1
|
||||
let g:gutentags_generate_on_empty_buffer = 0
|
||||
|
||||
" Put all tags in one place
|
||||
let g:gutentags_cache_dir = expand('~/.cache/vim/ctags/')
|
||||
|
||||
" Extra tag information
|
||||
let g:gutentags_ctags_extra_args = [
|
||||
\ '--tag-relative=yes',
|
||||
\ '--fields=+ailmnS',
|
||||
\ ]
|
||||
|
||||
let g:gutentags_ctags_exclude = [
|
||||
\ '*.git', '*.svg', '*.hg',
|
||||
\ '*/tests/*',
|
||||
\ 'build',
|
||||
\ 'dist',
|
||||
\ '*sites/*/files/*',
|
||||
\ 'bin',
|
||||
\ 'node_modules',
|
||||
\ 'bower_components',
|
||||
\ 'cache',
|
||||
\ 'compiled',
|
||||
\ 'docs',
|
||||
\ 'example',
|
||||
\ 'bundle',
|
||||
\ 'vendor',
|
||||
\ '*.md',
|
||||
\ '*-lock.json',
|
||||
\ '*.lock',
|
||||
\ '*bundle*.js',
|
||||
\ '*build*.js',
|
||||
\ '.*rc*',
|
||||
\ '*.json',
|
||||
\ '*.min.*',
|
||||
\ '*.map',
|
||||
\ '*.bak',
|
||||
\ '*.zip',
|
||||
\ '*.pyc',
|
||||
\ '*.class',
|
||||
\ '*.sln',
|
||||
\ '*.Master',
|
||||
\ '*.csproj',
|
||||
\ '*.tmp',
|
||||
\ '*.csproj.user',
|
||||
\ '*.cache',
|
||||
\ '*.pdb',
|
||||
\ 'tags*',
|
||||
\ 'cscope.*',
|
||||
\ '*.css',
|
||||
\ '*.less',
|
||||
\ '*.scss',
|
||||
\ '*.exe', '*.dll',
|
||||
\ '*.mp3', '*.ogg', '*.flac',
|
||||
\ '*.swp', '*.swo',
|
||||
\ '*.bmp', '*.gif', '*.ico', '*.jpg', '*.png',
|
||||
\ '*.rar', '*.zip', '*.tar', '*.tar.gz', '*.tar.xz', '*.tar.bz2',
|
||||
\ '*.pdf', '*.doc', '*.docx', '*.ppt', '*.pptx',
|
||||
\ ]
|
||||
|
||||
endif
|
||||
|
||||
" fugitive.vim looks for tags in .git
|
||||
" set tags +=~/tags " Recursively move upwards in tree, searching in subfolders for tags file
|
||||
|
||||
if exists(":NERDTree")
|
||||
" Open NERDTree if no file specified
|
||||
autocmd StdinReadPre * let s:std_in=1
|
||||
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
|
||||
" Status line
|
||||
set laststatus=2
|
||||
set statusline=
|
||||
set statusline+=%#StatusLineTerm#
|
||||
if exists('g:loaded_fugitive')
|
||||
set statusline+=%{FugitiveStatusline()}
|
||||
endif
|
||||
set statusline+=%#MoreMsg#
|
||||
set statusline+=\ %f
|
||||
set statusline+=%m\ "
|
||||
set statusline+=%=
|
||||
set statusline+=%#WildMenu#
|
||||
set statusline+=%y
|
||||
set statusline+=\ %p%%
|
||||
set statusline+=\ %l:%c"
|
||||
set statusline+=%#MoreMsg#
|
||||
set statusline+=\ "
|
||||
|
||||
|
||||
" CtrlP
|
||||
let g:ctrlp_working_path_mode = 'ra'
|
||||
@@ -122,14 +238,31 @@ function! ToggleMiniMaxiWin()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ToggleNumbersAndGutter()
|
||||
if !exists('b:numbers_and_gutter_on') || b:numbers_and_gutter_on == 1
|
||||
set nonumber
|
||||
set norelativenumber
|
||||
GitGutterBufferDisable
|
||||
let b:numbers_and_gutter_on=0
|
||||
else
|
||||
set number
|
||||
set relativenumber
|
||||
GitGutterBufferEnable
|
||||
let b:numbers_and_gutter_on=1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
nnoremap <leader>1 :call ToggleNumbersAndGutter()<CR>
|
||||
|
||||
" Key binds
|
||||
"
|
||||
command! Csc cscope find c <cword>
|
||||
|
||||
" Easymotion leader
|
||||
map <Leader><tab> <Plug>(easymotion-prefix)
|
||||
" Forwards and backwards jump
|
||||
" Forwards and backwards jump and visual select
|
||||
map <tab> <Plug>(easymotion-s)
|
||||
map <space> <C-V><Plug>(easymotion-s)
|
||||
" Forwards and backwards word jump
|
||||
map <Leader>w <Plug>(easymotion-bd-w)
|
||||
" Easymotion overwin line
|
||||
@@ -146,36 +279,46 @@ vnoremap <leader>* y:%sno/<c-r>"//g<left><left>
|
||||
nmap <F2> :NERDTreeToggle<CR>
|
||||
nmap <F3> :NERDTreeFind<CR>
|
||||
map <F5> :call CurtineIncSw()<CR>
|
||||
nmap <F8> :silent !/home/efjtjkb/bin/comp<enter>
|
||||
" Remap <F9> (c-vim uses this)
|
||||
"nmap <F9> :silent !/home/efjtjkb/bin/run<enter>
|
||||
autocmd VimEnter * noremap <F9> :silent !/home/efjtjkb/bin/run<enter>
|
||||
nmap <F10> :silent !/home/efjtjkb/bin/run old<enter>
|
||||
|
||||
nmap <Leader>cf :cd %:p:h <CR> " Change dir to parent of current file
|
||||
nmap <Leader>cg :cd $git_root_location <CR> " Change dir to git root
|
||||
nmap <Leader>vs :sp $MYVIMRC <CR>
|
||||
nmap <Leader>vv :vsp $MYVIMRC <CR>
|
||||
nmap <Leader>vt :tabnew $MYVIMRC <CR>
|
||||
nmap <Leader>vo :e $MYVIMRC <CR>
|
||||
nmap <Leader>v :e $MYVIMRC <CR>
|
||||
nmap <Leader>vs :sp $HOME/.vimrc <CR>
|
||||
nmap <Leader>vv :vsp $HOME/.vimrc <CR>
|
||||
nmap <Leader>vt :tabnew $HOME/.vimrc <CR>
|
||||
nmap <Leader>vo :e $HOME/.vimrc <CR>
|
||||
nmap <Leader>v :e $HOME/.vimrc <CR>
|
||||
|
||||
" Match git conflict markers
|
||||
nmap <Leader>/g /[<=>]\{7,}.*$<CR>
|
||||
" Git-Gutter status, commit, grep, blame
|
||||
nmap <Leader>gs :Gstatus<CR>
|
||||
nmap <Leader>gS :!git add %<CR>
|
||||
nmap <Leader>gc :Gcommit<CR>
|
||||
nmap <Leader>gg :Ggrep<space>
|
||||
nmap <Leader>gb :Gblame<CR>
|
||||
nmap <Leader>gu :GitGutterUndoHunk<CR>
|
||||
|
||||
" Fugitive Conflict Resolution
|
||||
nnoremap <leader>gd :Gvdiffsplit!<CR>
|
||||
nnoremap gdh :diffget //2<CR>
|
||||
nnoremap gdl :diffget //3<CR>
|
||||
|
||||
" Toggle wrapping of long lines
|
||||
nmap <Leader>l :set wrap!<CR>
|
||||
|
||||
" Strip trailing whitespace
|
||||
nmap <Leader><space> :TrailWhitespace <CR>
|
||||
|
||||
" Scroll window while keeping cursor on same line with shift
|
||||
nmap <S-j> <c-e>
|
||||
nmap <S-k> <c-y>
|
||||
vmap <S-j> <c-e>
|
||||
vmap <S-k> <c-y>
|
||||
|
||||
" Toggle paste mode
|
||||
nmap <Leader>p :set paste! <CR>
|
||||
|
||||
" Misc.
|
||||
map <Leader>n :noh<CR>
|
||||
vmap <Leader>T :'<,'> Tabularize /
|
||||
nnoremap <leader>c :execute "set colorcolumn=" . (&colorcolumn == "" ? "120" : "")<CR>
|
||||
noremap <space> :
|
||||
|
||||
19
.xinitrc
19
.xinitrc
@@ -21,30 +21,13 @@ export CUPS_GSSSERVICENAME=HTTP
|
||||
|
||||
[[ -f ~/.Xresources ]] && xrdb -merge ~/.Xresources
|
||||
|
||||
volnoti &
|
||||
owncloud &
|
||||
|
||||
rm -f "~/${WM}.log.old"
|
||||
mv -f "~/${WM}.log" "~/${WM}.log.old"
|
||||
rm -f "~/${WM}.log"
|
||||
rm -f "~/${WM}.log"
|
||||
|
||||
if [ "$WM" = "i3" ]; then
|
||||
# Generate i3 config file
|
||||
i3config="/tmp/i3_${USER}_config"
|
||||
rm -f $i3config
|
||||
|
||||
if [ -f ~/.i3/base.config ]; then
|
||||
cat ~/.i3/base.config >> $i3config
|
||||
fi
|
||||
|
||||
if [ "`hostname`" = "kubaArch" ] && [ -f ~/.i3/home.config ]; then
|
||||
cat ~/.i3/home.config >> $i3config
|
||||
elif [ "`hostname`" = "JakubArch" ] && [ -f ~/.i3/work.config ]; then
|
||||
cat ~/.i3/work.config >> $i3config
|
||||
fi
|
||||
#exec i3 -c $i3config -V >> ~/${WM}.log 2>&1
|
||||
exec i3 -c $i3config
|
||||
. ~/.i3initrc
|
||||
else
|
||||
exec $WM >> "~/${WM}.log" 2>&1
|
||||
fi
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#!/bin/bash
|
||||
#$1 is -
|
||||
|
||||
#echo "DISP:eDP1"
|
||||
#exit 0
|
||||
|
||||
function primary() {
|
||||
xrandr | grep primary | awk '{print $1}'
|
||||
}
|
||||
|
||||
#displays=($(xrandr | sed -rn 's/(^|(.* ))([^ ]*) connected(( .*)|$)/\3/g; T; p' ))
|
||||
displays=$(xrandr | grep " connected" | awk '{print $1}')
|
||||
displays=$(xrandr --listactivemonitors | grep -v Monitors | awk '{print $NF}')
|
||||
case "$1" in
|
||||
"auto")
|
||||
echo "$displays" | while read display; do
|
||||
xrandr --output $display --auto
|
||||
done
|
||||
;;
|
||||
"connected")
|
||||
echo "$displays"
|
||||
# for i in "${displays[@]}"; do
|
||||
# echo "$i"
|
||||
# done
|
||||
;;
|
||||
"lemonbar")
|
||||
echo "DISP ${displays[@]}" | sed "s/ /:/g"
|
||||
|
||||
564
scripts/git-prompt.sh
Normal file
564
scripts/git-prompt.sh
Normal file
@@ -0,0 +1,564 @@
|
||||
# bash/zsh git prompt support
|
||||
#
|
||||
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
|
||||
# Distributed under the GNU General Public License, version 2.0.
|
||||
#
|
||||
# This script allows you to see repository status in your prompt.
|
||||
#
|
||||
# To enable:
|
||||
#
|
||||
# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
|
||||
# 2) Add the following line to your .bashrc/.zshrc:
|
||||
# source ~/.git-prompt.sh
|
||||
# 3a) Change your PS1 to call __git_ps1 as
|
||||
# command-substitution:
|
||||
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
|
||||
# ZSH: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
|
||||
# the optional argument will be used as format string.
|
||||
# 3b) Alternatively, for a slightly faster prompt, __git_ps1 can
|
||||
# be used for PROMPT_COMMAND in Bash or for precmd() in Zsh
|
||||
# with two parameters, <pre> and <post>, which are strings
|
||||
# you would put in $PS1 before and after the status string
|
||||
# generated by the git-prompt machinery. e.g.
|
||||
# Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
|
||||
# will show username, at-sign, host, colon, cwd, then
|
||||
# various status string, followed by dollar and SP, as
|
||||
# your prompt.
|
||||
# ZSH: precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
|
||||
# will show username, pipe, then various status string,
|
||||
# followed by colon, cwd, dollar and SP, as your prompt.
|
||||
# Optionally, you can supply a third argument with a printf
|
||||
# format string to finetune the output of the branch status
|
||||
#
|
||||
# The repository status will be displayed only if you are currently in a
|
||||
# git repository. The %s token is the placeholder for the shown status.
|
||||
#
|
||||
# The prompt status always includes the current branch name.
|
||||
#
|
||||
# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
|
||||
# unstaged (*) and staged (+) changes will be shown next to the branch
|
||||
# name. You can configure this per-repository with the
|
||||
# bash.showDirtyState variable, which defaults to true once
|
||||
# GIT_PS1_SHOWDIRTYSTATE is enabled.
|
||||
#
|
||||
# You can also see if currently something is stashed, by setting
|
||||
# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
|
||||
# then a '$' will be shown next to the branch name.
|
||||
#
|
||||
# If you would like to see if there're untracked files, then you can set
|
||||
# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
|
||||
# files, then a '%' will be shown next to the branch name. You can
|
||||
# configure this per-repository with the bash.showUntrackedFiles
|
||||
# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
|
||||
# enabled.
|
||||
#
|
||||
# If you would like to see the difference between HEAD and its upstream,
|
||||
# set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates you are behind, ">"
|
||||
# indicates you are ahead, "<>" indicates you have diverged and "="
|
||||
# indicates that there is no difference. You can further control
|
||||
# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
|
||||
# of values:
|
||||
#
|
||||
# verbose show number of commits ahead/behind (+/-) upstream
|
||||
# name if verbose, then also show the upstream abbrev name
|
||||
# legacy don't use the '--count' option available in recent
|
||||
# versions of git-rev-list
|
||||
# git always compare HEAD to @{upstream}
|
||||
# svn always compare HEAD to your SVN upstream
|
||||
#
|
||||
# You can change the separator between the branch name and the above
|
||||
# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
|
||||
# is SP.
|
||||
#
|
||||
# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
|
||||
# find one, or @{upstream} otherwise. Once you have set
|
||||
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
|
||||
# setting the bash.showUpstream config variable.
|
||||
#
|
||||
# If you would like to see more information about the identity of
|
||||
# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
|
||||
# to one of these values:
|
||||
#
|
||||
# contains relative to newer annotated tag (v1.6.3.2~35)
|
||||
# branch relative to newer tag or branch (master~4)
|
||||
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
|
||||
# tag relative to any older tag (v1.6.3.1-13-gdd42c2f)
|
||||
# default exactly matching tag
|
||||
#
|
||||
# If you would like a colored hint about the current dirty state, set
|
||||
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
|
||||
# the colored output of "git status -sb" and are available only when
|
||||
# using __git_ps1 for PROMPT_COMMAND or precmd.
|
||||
#
|
||||
# If you would like __git_ps1 to do nothing in the case when the current
|
||||
# directory is set up to be ignored by git, then set
|
||||
# GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the
|
||||
# repository level by setting bash.hideIfPwdIgnored to "false".
|
||||
|
||||
# check whether printf supports -v
|
||||
__git_printf_supports_v=
|
||||
printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
|
||||
|
||||
# stores the divergence from upstream in $p
|
||||
# used by GIT_PS1_SHOWUPSTREAM
|
||||
__git_ps1_show_upstream ()
|
||||
{
|
||||
local key value
|
||||
local svn_remote svn_url_pattern count n
|
||||
local upstream=git legacy="" verbose="" name=""
|
||||
|
||||
svn_remote=()
|
||||
# get some config options from git-config
|
||||
local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
|
||||
while read -r key value; do
|
||||
case "$key" in
|
||||
bash.showupstream)
|
||||
GIT_PS1_SHOWUPSTREAM="$value"
|
||||
if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
|
||||
p=""
|
||||
return
|
||||
fi
|
||||
;;
|
||||
svn-remote.*.url)
|
||||
svn_remote[$((${#svn_remote[@]} + 1))]="$value"
|
||||
svn_url_pattern="$svn_url_pattern\\|$value"
|
||||
upstream=svn+git # default upstream is SVN if available, else git
|
||||
;;
|
||||
esac
|
||||
done <<< "$output"
|
||||
|
||||
# parse configuration values
|
||||
for option in ${GIT_PS1_SHOWUPSTREAM}; do
|
||||
case "$option" in
|
||||
git|svn) upstream="$option" ;;
|
||||
verbose) verbose=1 ;;
|
||||
legacy) legacy=1 ;;
|
||||
name) name=1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Find our upstream
|
||||
case "$upstream" in
|
||||
git) upstream="@{upstream}" ;;
|
||||
svn*)
|
||||
# get the upstream from the "git-svn-id: ..." in a commit message
|
||||
# (git-svn uses essentially the same procedure internally)
|
||||
local -a svn_upstream
|
||||
svn_upstream=($(git log --first-parent -1 \
|
||||
--grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
|
||||
if [[ 0 -ne ${#svn_upstream[@]} ]]; then
|
||||
svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
|
||||
svn_upstream=${svn_upstream%@*}
|
||||
local n_stop="${#svn_remote[@]}"
|
||||
for ((n=1; n <= n_stop; n++)); do
|
||||
svn_upstream=${svn_upstream#${svn_remote[$n]}}
|
||||
done
|
||||
|
||||
if [[ -z "$svn_upstream" ]]; then
|
||||
# default branch name for checkouts with no layout:
|
||||
upstream=${GIT_SVN_ID:-git-svn}
|
||||
else
|
||||
upstream=${svn_upstream#/}
|
||||
fi
|
||||
elif [[ "svn+git" = "$upstream" ]]; then
|
||||
upstream="@{upstream}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Find how many commits we are ahead/behind our upstream
|
||||
if [[ -z "$legacy" ]]; then
|
||||
count="$(git rev-list --count --left-right \
|
||||
"$upstream"...HEAD 2>/dev/null)"
|
||||
else
|
||||
# produce equivalent output to --count for older versions of git
|
||||
local commits
|
||||
if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
|
||||
then
|
||||
local commit behind=0 ahead=0
|
||||
for commit in $commits
|
||||
do
|
||||
case "$commit" in
|
||||
"<"*) ((behind++)) ;;
|
||||
*) ((ahead++)) ;;
|
||||
esac
|
||||
done
|
||||
count="$behind $ahead"
|
||||
else
|
||||
count=""
|
||||
fi
|
||||
fi
|
||||
|
||||
# calculate the result
|
||||
if [[ -z "$verbose" ]]; then
|
||||
case "$count" in
|
||||
"") # no upstream
|
||||
p="" ;;
|
||||
"0 0") # equal to upstream
|
||||
p="=" ;;
|
||||
"0 "*) # ahead of upstream
|
||||
p=">" ;;
|
||||
*" 0") # behind upstream
|
||||
p="<" ;;
|
||||
*) # diverged from upstream
|
||||
p="<>" ;;
|
||||
esac
|
||||
else
|
||||
case "$count" in
|
||||
"") # no upstream
|
||||
p="" ;;
|
||||
"0 0") # equal to upstream
|
||||
p=" u=" ;;
|
||||
"0 "*) # ahead of upstream
|
||||
p=" u+${count#0 }" ;;
|
||||
*" 0") # behind upstream
|
||||
p=" u-${count% 0}" ;;
|
||||
*) # diverged from upstream
|
||||
p=" u+${count#* }-${count% *}" ;;
|
||||
esac
|
||||
if [[ -n "$count" && -n "$name" ]]; then
|
||||
__git_ps1_upstream_name=$(git rev-parse \
|
||||
--abbrev-ref "$upstream" 2>/dev/null)
|
||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||
p="$p \${__git_ps1_upstream_name}"
|
||||
else
|
||||
p="$p ${__git_ps1_upstream_name}"
|
||||
# not needed anymore; keep user's
|
||||
# environment clean
|
||||
unset __git_ps1_upstream_name
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# Helper function that is meant to be called from __git_ps1. It
|
||||
# injects color codes into the appropriate gitstring variables used
|
||||
# to build a gitstring.
|
||||
__git_ps1_colorize_gitstring ()
|
||||
{
|
||||
if [[ -n ${ZSH_VERSION-} ]]; then
|
||||
local c_red='%F{red}'
|
||||
local c_green='%F{green}'
|
||||
local c_lblue='%F{blue}'
|
||||
local c_clear='%f'
|
||||
else
|
||||
# Using \[ and \] around colors is necessary to prevent
|
||||
# issues with command line editing/browsing/completion!
|
||||
local c_red='\[\e[31m\]'
|
||||
local c_green='\[\e[32m\]'
|
||||
local c_lblue='\[\e[1;34m\]'
|
||||
local c_clear='\[\e[0m\]'
|
||||
fi
|
||||
local bad_color=$c_red
|
||||
local ok_color=$c_green
|
||||
local flags_color="$c_lblue"
|
||||
|
||||
local branch_color=""
|
||||
if [ $detached = no ]; then
|
||||
branch_color="$ok_color"
|
||||
else
|
||||
branch_color="$bad_color"
|
||||
fi
|
||||
c="$branch_color$c"
|
||||
|
||||
z="$c_clear$z"
|
||||
if [ "$w" = "*" ]; then
|
||||
w="$bad_color$w"
|
||||
fi
|
||||
if [ -n "$i" ]; then
|
||||
i="$ok_color$i"
|
||||
fi
|
||||
if [ -n "$s" ]; then
|
||||
s="$flags_color$s"
|
||||
fi
|
||||
if [ -n "$u" ]; then
|
||||
u="$bad_color$u"
|
||||
fi
|
||||
r="$c_clear$r"
|
||||
}
|
||||
|
||||
# Helper function to read the first line of a file into a variable.
|
||||
# __git_eread requires 2 arguments, the file path and the name of the
|
||||
# variable, in that order.
|
||||
__git_eread ()
|
||||
{
|
||||
test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
|
||||
}
|
||||
|
||||
# see if a cherry-pick or revert is in progress, if the user has committed a
|
||||
# conflict resolution with 'git commit' in the middle of a sequence of picks or
|
||||
# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
|
||||
# the todo file.
|
||||
__git_sequencer_status ()
|
||||
{
|
||||
local todo
|
||||
if test -f "$g/CHERRY_PICK_HEAD"
|
||||
then
|
||||
r="|CHERRY-PICKING"
|
||||
return 0;
|
||||
elif test -f "$g/REVERT_HEAD"
|
||||
then
|
||||
r="|REVERTING"
|
||||
return 0;
|
||||
elif __git_eread "$g/sequencer/todo" todo
|
||||
then
|
||||
case "$todo" in
|
||||
p[\ \ ]|pick[\ \ ]*)
|
||||
r="|CHERRY-PICKING"
|
||||
return 0
|
||||
;;
|
||||
revert[\ \ ]*)
|
||||
r="|REVERTING"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
|
||||
# when called from PS1 using command substitution
|
||||
# in this mode it prints text to add to bash PS1 prompt (includes branch name)
|
||||
#
|
||||
# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
|
||||
# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
|
||||
# when two arguments are given, the first is prepended and the second appended
|
||||
# to the state string when assigned to PS1.
|
||||
# The optional third parameter will be used as printf format string to further
|
||||
# customize the output of the git-status string.
|
||||
# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
|
||||
__git_ps1 ()
|
||||
{
|
||||
# preserve exit status
|
||||
local exit=$?
|
||||
local pcmode=no
|
||||
local detached=no
|
||||
local ps1pc_start='\u@\h:\w '
|
||||
local ps1pc_end='\$ '
|
||||
local printf_format=' (%s)'
|
||||
|
||||
case "$#" in
|
||||
2|3) pcmode=yes
|
||||
ps1pc_start="$1"
|
||||
ps1pc_end="$2"
|
||||
printf_format="${3:-$printf_format}"
|
||||
# set PS1 to a plain prompt so that we can
|
||||
# simply return early if the prompt should not
|
||||
# be decorated
|
||||
PS1="$ps1pc_start$ps1pc_end"
|
||||
;;
|
||||
0|1) printf_format="${1:-$printf_format}"
|
||||
;;
|
||||
*) return $exit
|
||||
;;
|
||||
esac
|
||||
|
||||
# ps1_expanded: This variable is set to 'yes' if the shell
|
||||
# subjects the value of PS1 to parameter expansion:
|
||||
#
|
||||
# * bash does unless the promptvars option is disabled
|
||||
# * zsh does not unless the PROMPT_SUBST option is set
|
||||
# * POSIX shells always do
|
||||
#
|
||||
# If the shell would expand the contents of PS1 when drawing
|
||||
# the prompt, a raw ref name must not be included in PS1.
|
||||
# This protects the user from arbitrary code execution via
|
||||
# specially crafted ref names. For example, a ref named
|
||||
# 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
|
||||
# shell to execute 'sudo rm -rf /' when the prompt is drawn.
|
||||
#
|
||||
# Instead, the ref name should be placed in a separate global
|
||||
# variable (in the __git_ps1_* namespace to avoid colliding
|
||||
# with the user's environment) and that variable should be
|
||||
# referenced from PS1. For example:
|
||||
#
|
||||
# __git_ps1_foo=$(do_something_to_get_ref_name)
|
||||
# PS1="...stuff...\${__git_ps1_foo}...stuff..."
|
||||
#
|
||||
# If the shell does not expand the contents of PS1, the raw
|
||||
# ref name must be included in PS1.
|
||||
#
|
||||
# The value of this variable is only relevant when in pcmode.
|
||||
#
|
||||
# Assume that the shell follows the POSIX specification and
|
||||
# expands PS1 unless determined otherwise. (This is more
|
||||
# likely to be correct if the user has a non-bash, non-zsh
|
||||
# shell and safer than the alternative if the assumption is
|
||||
# incorrect.)
|
||||
#
|
||||
local ps1_expanded=yes
|
||||
[ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
|
||||
[ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
|
||||
|
||||
local repo_info rev_parse_exit_code
|
||||
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
|
||||
--is-bare-repository --is-inside-work-tree \
|
||||
--short HEAD 2>/dev/null)"
|
||||
rev_parse_exit_code="$?"
|
||||
|
||||
if [ -z "$repo_info" ]; then
|
||||
return $exit
|
||||
fi
|
||||
|
||||
local short_sha=""
|
||||
if [ "$rev_parse_exit_code" = "0" ]; then
|
||||
short_sha="${repo_info##*$'\n'}"
|
||||
repo_info="${repo_info%$'\n'*}"
|
||||
fi
|
||||
local inside_worktree="${repo_info##*$'\n'}"
|
||||
repo_info="${repo_info%$'\n'*}"
|
||||
local bare_repo="${repo_info##*$'\n'}"
|
||||
repo_info="${repo_info%$'\n'*}"
|
||||
local inside_gitdir="${repo_info##*$'\n'}"
|
||||
local g="${repo_info%$'\n'*}"
|
||||
|
||||
if [ "true" = "$inside_worktree" ] &&
|
||||
[ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&
|
||||
[ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] &&
|
||||
git check-ignore -q .
|
||||
then
|
||||
return $exit
|
||||
fi
|
||||
|
||||
local r=""
|
||||
local b=""
|
||||
local step=""
|
||||
local total=""
|
||||
if [ -d "$g/rebase-merge" ]; then
|
||||
__git_eread "$g/rebase-merge/head-name" b
|
||||
__git_eread "$g/rebase-merge/msgnum" step
|
||||
__git_eread "$g/rebase-merge/end" total
|
||||
if [ -f "$g/rebase-merge/interactive" ]; then
|
||||
r="|REBASE-i"
|
||||
else
|
||||
r="|REBASE-m"
|
||||
fi
|
||||
else
|
||||
if [ -d "$g/rebase-apply" ]; then
|
||||
__git_eread "$g/rebase-apply/next" step
|
||||
__git_eread "$g/rebase-apply/last" total
|
||||
if [ -f "$g/rebase-apply/rebasing" ]; then
|
||||
__git_eread "$g/rebase-apply/head-name" b
|
||||
r="|REBASE"
|
||||
elif [ -f "$g/rebase-apply/applying" ]; then
|
||||
r="|AM"
|
||||
else
|
||||
r="|AM/REBASE"
|
||||
fi
|
||||
elif [ -f "$g/MERGE_HEAD" ]; then
|
||||
r="|MERGING"
|
||||
elif __git_sequencer_status; then
|
||||
:
|
||||
elif [ -f "$g/BISECT_LOG" ]; then
|
||||
r="|BISECTING"
|
||||
fi
|
||||
|
||||
if [ -n "$b" ]; then
|
||||
:
|
||||
elif [ -h "$g/HEAD" ]; then
|
||||
# symlink symbolic ref
|
||||
b="$(git symbolic-ref HEAD 2>/dev/null)"
|
||||
else
|
||||
local head=""
|
||||
if ! __git_eread "$g/HEAD" head; then
|
||||
return $exit
|
||||
fi
|
||||
# is it a symbolic ref?
|
||||
b="${head#ref: }"
|
||||
if [ "$head" = "$b" ]; then
|
||||
detached=yes
|
||||
b="$(
|
||||
case "${GIT_PS1_DESCRIBE_STYLE-}" in
|
||||
(contains)
|
||||
git describe --contains HEAD ;;
|
||||
(branch)
|
||||
git describe --contains --all HEAD ;;
|
||||
(tag)
|
||||
git describe --tags HEAD ;;
|
||||
(describe)
|
||||
git describe HEAD ;;
|
||||
(* | default)
|
||||
git describe --tags --exact-match HEAD ;;
|
||||
esac 2>/dev/null)" ||
|
||||
|
||||
b="$short_sha..."
|
||||
b="($b)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$step" ] && [ -n "$total" ]; then
|
||||
r="$r $step/$total"
|
||||
fi
|
||||
|
||||
local w=""
|
||||
local i=""
|
||||
local s=""
|
||||
local u=""
|
||||
local c=""
|
||||
local p=""
|
||||
|
||||
if [ "true" = "$inside_gitdir" ]; then
|
||||
if [ "true" = "$bare_repo" ]; then
|
||||
c="BARE:"
|
||||
else
|
||||
b="GIT_DIR!"
|
||||
fi
|
||||
elif [ "true" = "$inside_worktree" ]; then
|
||||
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
|
||||
[ "$(git config --bool bash.showDirtyState)" != "false" ]
|
||||
then
|
||||
git diff --no-ext-diff --quiet || w="*"
|
||||
git diff --no-ext-diff --cached --quiet || i="+"
|
||||
if [ -z "$short_sha" ] && [ -z "$i" ]; then
|
||||
i="#"
|
||||
fi
|
||||
fi
|
||||
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
|
||||
git rev-parse --verify --quiet refs/stash >/dev/null
|
||||
then
|
||||
s="$"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
|
||||
[ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
|
||||
git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
|
||||
then
|
||||
u="%${ZSH_VERSION+%}"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
|
||||
__git_ps1_show_upstream
|
||||
fi
|
||||
fi
|
||||
|
||||
local z="${GIT_PS1_STATESEPARATOR-" "}"
|
||||
|
||||
# NO color option unless in PROMPT_COMMAND mode
|
||||
if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
||||
__git_ps1_colorize_gitstring
|
||||
fi
|
||||
|
||||
b=${b##refs/heads/}
|
||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||
__git_ps1_branch_name=$b
|
||||
b="\${__git_ps1_branch_name}"
|
||||
fi
|
||||
|
||||
local f="$w$i$s$u"
|
||||
local gitstring="$c$b${f:+$z$f}$r$p"
|
||||
|
||||
if [ $pcmode = yes ]; then
|
||||
if [ "${__git_printf_supports_v-}" != yes ]; then
|
||||
gitstring=$(printf -- "$printf_format" "$gitstring")
|
||||
else
|
||||
printf -v gitstring -- "$printf_format" "$gitstring"
|
||||
fi
|
||||
PS1="$ps1pc_start$gitstring$ps1pc_end"
|
||||
else
|
||||
printf -- "$printf_format" "$gitstring"
|
||||
fi
|
||||
|
||||
return $exit
|
||||
}
|
||||
Reference in New Issue
Block a user