diff --git a/.bash_logout b/.bash_logout new file mode 120000 index 00000000..0a9b92a3 --- /dev/null +++ b/.bash_logout @@ -0,0 +1 @@ +bash_logout \ No newline at end of file diff --git a/.bash_profile b/.bash_profile new file mode 120000 index 00000000..2329555f --- /dev/null +++ b/.bash_profile @@ -0,0 +1 @@ +bash_profile \ No newline at end of file diff --git a/.bashrc b/.bashrc new file mode 120000 index 00000000..cee304e6 --- /dev/null +++ b/.bashrc @@ -0,0 +1 @@ +bashrc \ No newline at end of file diff --git a/.bin b/.bin new file mode 120000 index 00000000..c5e82d74 --- /dev/null +++ b/.bin @@ -0,0 +1 @@ +bin \ No newline at end of file diff --git a/.config b/.config new file mode 120000 index 00000000..30fa1cea --- /dev/null +++ b/.config @@ -0,0 +1 @@ +config \ No newline at end of file diff --git a/.conky b/.conky new file mode 120000 index 00000000..9d8006a2 --- /dev/null +++ b/.conky @@ -0,0 +1 @@ +.config/conky/ \ No newline at end of file diff --git a/.gitconfig b/.gitconfig new file mode 120000 index 00000000..61463854 --- /dev/null +++ b/.gitconfig @@ -0,0 +1 @@ +gitconfig \ No newline at end of file diff --git a/.local b/.local new file mode 120000 index 00000000..c2c027fe --- /dev/null +++ b/.local @@ -0,0 +1 @@ +local \ No newline at end of file diff --git a/Templates/article.latex b/Templates/article.latex new file mode 100644 index 00000000..627cdf5d --- /dev/null +++ b/Templates/article.latex @@ -0,0 +1,33 @@ +\documentclass[12pt]{article} + +\usepackage{geometry} % Required for adjusting page dimensions +\usepackage{amsmath} +\usepackage{amsthm} +\usepackage{amssymb} +\usepackage{amsfonts} +\usepackage{longtable} +\usepackage{booktabs} +\usepackage[UKenglish]{babel} +\geometry{ + paper=a4paper, % Change to letterpaper for US letter + top=3cm, % Top margin + bottom=1.5cm, % Bottom margin + left=4.5cm, % Left margin + right=4.5cm, % Right margin + %showframe, % Uncomment to show how the type block is set on the page +} + +\title{<++>} +\author{Jonathan Hodgson} +\date{\today} + + +\begin{document} +\maketitle + + +\section{<++>} +<++> + + +\end{document} diff --git a/Templates/html b/Templates/html new file mode 100644 index 00000000..23f4e6b5 --- /dev/null +++ b/Templates/html @@ -0,0 +1,12 @@ + + + + + <++> + <++> + + + <++> + + + diff --git a/Templates/latex b/Templates/latex new file mode 120000 index 00000000..99559768 --- /dev/null +++ b/Templates/latex @@ -0,0 +1 @@ +article.latex \ No newline at end of file diff --git a/Templates/letter.latex b/Templates/letter.latex new file mode 100644 index 00000000..fbe42d2f --- /dev/null +++ b/Templates/letter.latex @@ -0,0 +1,37 @@ +\documentclass[12pt,stdletter,orderfromtodate,sigleft,a4paper,dateleft,addrfromemail,addrfromphone]{newlfm} +\usepackage{blindtext, xfrac} +\usepackage{longtable} +\usepackage{booktabs} +\usepackage[UKenglish]{babel} + +\newcommand{\latex}{\LaTeX} + +\newlfmP{dateskipbefore=20pt} +\newlfmP{sigsize=20pt} +\newlfmP{sigskipbefore=50pt} + +\newlfmP{Headlinewd=0pt,Footlinewd=0pt} + +\namefrom{Jonathan Hodgson} +\addrfrom{Cherrydown \\ The Meadows \\ Station Road \\ Cotton \\ Stowmarket \\ Suffolk \\ IP14 4NZ \\ +} +\phonefrom{07753 492267} +\emailfrom{jonathan@lunarweb.co.uk} + +\nameto{<+Recipient Name+>} +\addrto{% + <+Recipient Address+> +} + +\dateset{\today} +\regarding{<+Subject+>} + +\greetto{<+Dear Sir or Madam+>} +\closeline{Yours sincerely,} %Sincerly if you know the name. Failthfully if you don't + +\begin{document} +\begin{newlfm} + + <+Message+> +\end{newlfm} +\end{document} diff --git a/Templates/oldletter.latex b/Templates/oldletter.latex new file mode 100644 index 00000000..79a4fd62 --- /dev/null +++ b/Templates/oldletter.latex @@ -0,0 +1,60 @@ +%---------------------------------------------------------------------------------------- +% DOCUMENT CONFIGURATION +%---------------------------------------------------------------------------------------- + +\documentclass[12pt,a4paper,stdletter,sigleft]{newlfm} % 10pt font size default, 11pt and 12pt are also possible + + +%\longindentation=0pt % Un-commenting this line will push the closing "Sincerely," to the left of the page + + +\usepackage[T1]{fontenc} % Output font encoding for international characters +\usepackage[utf8]{inputenc} % Required for inputting international characters +\usepackage[UKenglish]{babel} +\usepackage{stix} % Use the Stix font by default + +\usepackage{microtype} % Improve justification + +%---------------------------------------------------------------------------------------- +% YOUR NAME & ADDRESS SECTION +%---------------------------------------------------------------------------------------- + +\signature{Jonathan Hodgson} % Your name for the signature at the bottom + +\address{Cherrydown \\ The Meadows \\ Station Road \\ Cotton \\ Stowmarket \\ Suffolk \\ IP14 4NZ \\ 07753 492267} % Your address and phone number + +%---------------------------------------------------------------------------------------- + +\begin{document} + +%---------------------------------------------------------------------------------------- +% ADDRESSEE SECTION +%---------------------------------------------------------------------------------------- + +\begin{letter}{<++>} % Name/title of the addressee{Recipient Name \\ Recipient Address} + +%---------------------------------------------------------------------------------------- +% LETTER CONTENT SECTION +%---------------------------------------------------------------------------------------- + +\opening{\textbf{Dear Sir or Madam,}} + +<++> + +Thank you for your time and consideration. + +I look forward to your reply. + +\vspace{2\parskip} % Extra whitespace for aesthetics +\closing{Yours failthfully,} +\vspace{2\parskip} % Extra whitespace for aesthetics + +%\ps{P.S. You can find additional information attached to this letter.} % Postscript text, comment this line to remove it + +%\encl{Copyright permission form} % Enclosures with the letter, comment this line to remove it + +%---------------------------------------------------------------------------------------- + +\end{letter} + +\end{document} diff --git a/bash_logout b/bash_logout new file mode 100644 index 00000000..0e4e4f18 --- /dev/null +++ b/bash_logout @@ -0,0 +1,3 @@ +# +# ~/.bash_logout +# diff --git a/bash_profile b/bash_profile new file mode 100644 index 00000000..8e44e9ef --- /dev/null +++ b/bash_profile @@ -0,0 +1,10 @@ +# +# ~/.bash_profile +# + + +[[ -f ~/.bashrc ]] && . ~/.bashrc + + + + diff --git a/bashrc b/bashrc new file mode 100644 index 00000000..bdb15acd --- /dev/null +++ b/bashrc @@ -0,0 +1,344 @@ +# +# ~/.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +export TERMINAL=/usr/bin/konsole +export TERM=xterm-256color +export PATH=~/.bin:/opt/lampp/bin:$PATH:. +export EDITOR=vim +export CDPATH=.:~:~/Sites + +#Ruby things +#GEM_HOME=$(ls -t -U | ruby -e 'puts Gem.user_dir') +#GEM_PATH=$GEM_HOME +#export PATH=$PATH:$GEM_HOME/bin +#export GEM_HOME=$(ruby -e 'print Gem.user_dir') + +big-chromium () { + chromium --force-device-scale-factor=$1 +} + +big-new-chromium () { + chromium-snapshot-bin --force-device-scale-factor=$1 +} + +#Swap two files +function swap() { + mv $1 $1._tmp; + mv $2 $1; + mv $1._tmp $2; +} + +function old() { + mv "$1" "$1.old" +} + +#This prints the current working directory after doing a cd" +cdls(){ + cd "$@" + ls -F --color=auto +} + +#Takes you to the aquarius theme +function aquarius() { + public_html=${PWD%/public_html*}/public_html + if [ -d $public_html ]; then + theme=$public_html/wp-content/themes + if [ -d $theme ]; then + cdls $theme/aquarius + else + echo " Can't find theme folder " + fi + else + echo " Can't find public_html folder." + fi +} + +#Takes you to the child theme +function theme() { + public_html=${PWD%/public_html*}/public_html + if [ -d $public_html ]; then + theme=$public_html/wp-content/themes + if [ -d $theme ]; then + child=$(ls -d $theme/*/ | grep -v "$theme\/aquarius" | grep -v "$theme\/twenty*" | grep -v "$theme\/barelycorporate" -m 1) + cdls $child + else + echo " Can't find theme folder " + fi + else + echo " Can't find public_html folder." + fi +} + +######################################## +## ## +## Search Functions ## +## ## +######################################## + +#These search functions use grep to search all sub-folders of the current working directory +searchjs() { + # This will search through .js and .es6 files but won't search minified files + grep -r -i -n --color="auto" --include=\*.{js,es6} --exclude=\*.min.js "$1" . +} +searchcss() { + # This will search through .css and .less files but won't search minified files + grep -r -i -n --color="auto" --include=\*.{css,less} --exclude=\*.min.css "$1" . +} +searchphp() { + grep -r -i -n --color="auto" --include="*.php" "$1" . +} + +# This makes cd use function above +alias cd="cdls" + +# These alow me to easily set the file and folder permissions for a wordpress instilation. +alias folder-perms='find . -type d -not -path "./.git/*" -not -path "./.git" -exec chmod 775 {} \;' +alias file-perms='find . -type f -not -path "./.git/*" -not -path "./.git" -exec chmod 664 {} \;' +alias wp-perms='folder-perms; file-perms' + +# Make ls add Indicators to file names and colour the output +alias ls='ls -F --color=auto' + +# Make tree add indicators and color +alias tree='tree -F -C' + +#Start cups +alias cups='sudo systemctl start org.cups.cupsd.service' + +#Start network manager +alias net='sudo systemctl start NetworkManager.service' + +# Alias lampp because I don't want to clog my PATH +alias lampp='/opt/lampp/lampp' +alias glampp='gksudo /opt/lampp/manager-linux-x64.run' + +#Always make all directories necesary +alias mkdir='mkdir -p' + +# Shortcut for rewriting wp permalinks +alias perms='wp rewrite flush' + +#Clear terminal and screenfetch +alias cls='clear; screenfetch' + +#An alias for my standard less configuration +#I don't set it to lessc because sometimes I don't use this config and I always forget how to ignore an alias +#alias myless='lessc --clean-css --source-map-basepath=/home/jonathan/Sites/charts/public_html --source-map --autoprefix="last 3 versions, ie >= 9" styles.less styles.min.css' +alias myless='lessc --clean-css --source-map --autoprefix="last 3 versions, ie >= 9" styles.less styles.min.css' + +# Git shortcuts +alias status='git status ' +alias st='git status' +alias checkout='git checkout' +alias ch='git checkout' +alias push='git push ' +alias pull='git pull ' +alias bb='git open' + +# Always make grep ouput color +alias grep="grep --color=auto" + +# Shortcuts to sites folder +alias sites="cd ~/Sites" +alias s="cd ~/Sites" + +# Shortcuts to documents folder +alias documents="cd ~/Documents/" +alias d="cd ~/Documents/" + +# Shortcuts to home folder +alias home="cd ~/" +alias ~="cd ~/" + +#Goes up to the public_html folder +alias ph='cd ${PWD%/public_html*}/public_html' + +# Quit the terminal using :q (The same as Vi/Vim) +alias :q='exit;' + +# Not sure why and how but this makes sudo work with my aliases +alias sudo='sudo ' + +#Make the cal command default to start on Sunday +alias cal='cal -s' + +# update the third party wordpress plugins we are mirroring +alias u3p='update3rdPartyPlugins' + +# Edit my bashrc +alias brc='$EDITOR ~/.bashrc' + +# Edit my vimrc +alias vrc='$EDITOR ~/.vimrc' + +# Go to my .vim folder +alias .v='cd ~/.vim/' +# Go to my dotfiles folder +if [[ $(hostname) == "jonathansnuc" ]]; then + #Please don't judge - This is a reminant from first days of version controlling dotfiles + alias df='cd ~/Downloads/laptopConfig/' +else + alias df='cd ~/.dotfiles' +fi + +#Old ps1 +#PS1='[\u@\h \W]\$ ' + + +# bash completion for the `wp` command +_wp_complete() { + local OLD_IFS="$IFS" + local cur=${COMP_WORDS[COMP_CWORD]} + IFS=$'\n'; # want to preserve spaces at the end + local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")" + if [[ "$opts" =~ \\s* ]] + then + COMPREPLY=( $(compgen -f -- $cur) ) + elif [[ $opts = "" ]] + then + COMPREPLY=( $(compgen -f -- $cur) ) + else + COMPREPLY=( ${opts[*]} ) + fi + IFS="$OLD_IFS" + return 0 +} +complete -o nospace -F _wp_complete wp + +export GIT_PS1_SHOWDIRTYSTATE=1 # Show the +(Staged) or *(unstaged) next to branch name for +export GIT_PS1_SHOWUNTRACKEDFILES=1 # Show the %(Untracked) next to branch name +export GIT_PS1_SHOWUPSTREAM="auto" + +source /usr/share/git/completion/git-completion.bash +source /usr/share/git/completion/git-prompt.sh + +############################################ +## ## +## Colours for output ## +## ## +############################################ +#{{{ +# Reset +Color_Off="\[\033[0m\]" # Text Reset + +# Regular Colors +Black="\[\033[0;30m\]" # Black +Red="\[\033[0;31m\]" # Red +Green="\[\033[0;32m\]" # Green +Yellow="\[\033[0;33m\]" # Yellow +Blue="\[\033[0;34m\]" # Blue +Purple="\[\033[0;35m\]" # Purple +Cyan="\[\033[0;36m\]" # Cyan +White="\[\033[0;37m\]" # White + +# Bold +BBlack="\[\033[1;30m\]" # Black +BRed="\[\033[1;31m\]" # Red +BGreen="\[\033[1;32m\]" # Green +BYellow="\[\033[1;33m\]" # Yellow +BBlue="\[\033[1;34m\]" # Blue +BPurple="\[\033[1;35m\]" # Purple +BCyan="\[\033[1;36m\]" # Cyan +BWhite="\[\033[1;37m\]" # White + +# Underline +UBlack="\[\033[4;30m\]" # Black +URed="\[\033[4;31m\]" # Red +UGreen="\[\033[4;32m\]" # Green +UYellow="\[\033[4;33m\]" # Yellow +UBlue="\[\033[4;34m\]" # Blue +UPurple="\[\033[4;35m\]" # Purple +UCyan="\[\033[4;36m\]" # Cyan +UWhite="\[\033[4;37m\]" # White + +# Background +On_Black="\[\033[40m\]" # Black +On_Red="\[\033[41m\]" # Red +On_Green="\[\033[42m\]" # Green +On_Yellow="\[\033[43m\]" # Yellow +On_Blue="\[\033[44m\]" # Blue +On_Purple="\[\033[45m\]" # Purple +On_Cyan="\[\033[46m\]" # Cyan +On_White="\[\033[47m\]" # White + +# High Intensty +IBlack="\[\033[0;90m\]" # Black +IRed="\[\033[0;91m\]" # Red +IGreen="\[\033[0;92m\]" # Green +IYellow="\[\033[0;93m\]" # Yellow +IBlue="\[\033[0;94m\]" # Blue +IPurple="\[\033[0;95m\]" # Purple +ICyan="\[\033[0;96m\]" # Cyan +IWhite="\[\033[0;97m\]" # White + +# Bold High Intensty +BIBlack="\[\033[1;90m\]" # Black +BIRed="\[\033[1;91m\]" # Red +BIGreen="\[\033[1;92m\]" # Green +BIYellow="\[\033[1;93m\]" # Yellow +BIBlue="\[\033[1;94m\]" # Blue +BIPurple="\[\033[1;95m\]" # Purple +BICyan="\[\033[1;96m\]" # Cyan +BIWhite="\[\033[1;97m\]" # White + +# High Intensty backgrounds +On_IBlack="\[\033[0;100m\]" # Black +On_IRed="\[\033[0;101m\]" # Red +On_IGreen="\[\033[0;102m\]" # Green +On_IYellow="\[\033[0;103m\]" # Yellow +On_IBlue="\[\033[0;104m\]" # Blue +On_IPurple="\[\033[10;95m\]" # Purple +On_ICyan="\[\033[0;106m\]" # Cyan +On_IWhite="\[\033[0;107m\]" # White +#}}} +# Various variables you might want for your PS1 prompt instead +Time12h="\T" +Time12a="\@" +PathShort="\w" +PathFull="\W" +NewLine="\n" +Jobs="\j" +Username="\u" + +# Default PS1 +# \u@\h [\w]$ +export PS1=$Username" "$Yellow$PathShort$Color_Off'$(git branch &>/dev/null;\ +if [ $? -eq 0 ]; then \ + echo "$(echo `git status` | grep "nothing to commit" > /dev/null 2>&1; \ + if [ "$?" -eq "0" ]; then \ + echo "'$Green'"$(__git_ps1 " (%s)");\ + else \ + echo "'$Red'"$(__git_ps1 " (%s)");\ + fi)"; \ +fi)'$Color_Off'\$ ' + +# export PS1="\[\033[0;97m\]\u \[\033[0;33m\]\w"'$(git branch &>/dev/null;\ +# if [ $? -eq 0 ]; then \ +# echo "$(echo `git status` | grep "nothing to commit" > /dev/null 2>&1; \ +# if [ "$?" -eq "0" ]; then \ +# echo "\[\033[0;32m\]"$(__git_ps1 " (%s)");\ +# else \ +# echo "\[\033[0;91m\]"$(__git_ps1 " (%s)");\ +# fi)"; \ +# fi)\[\033[0m\]\$ ' +function _update_ps1() { + export PS1="$(~/.config/powerline-shell/powerline-shell.py $? 2> /dev/null)" +} + +if [ "$TERM" != "linux" ]; then + PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND" +fi + +[ -r "$HOME/.smartcd_config" ] && ( [ -n $BASH_VERSION ] || [ -n $ZSH_VERSION ] ) && source ~/.smartcd_config + +#If on work computer, cd into sites + +clear +screenfetch +set -o vi + +# vim: foldmethod=marker diff --git a/bin/addhost b/bin/addhost new file mode 100755 index 00000000..81da83ba --- /dev/null +++ b/bin/addhost @@ -0,0 +1,26 @@ +#!/usr/bin/bash +if [ $1 ]; then + case $1 in + -h|--help) + echo "Add entrys to your hosts file" + echo "" + echo -e "addhost domain.com\t\t\t\tadds domain.com to your hosts and points to local machine" + echo -e "addhost (alex|aaron|jonathan) domain.com\tadds domain.com to your hosts and points to persons machine" + ;; + alex) + echo -e "10.0.1.201\t$2" | sudo tee -a /etc/hosts + ;; + aaron) + echo -e "10.0.1.202\t$2" | sudo tee -a /etc/hosts + ;; + jonathan) + echo -e "10.0.1.203\t$2" | sudo tee -a /etc/hosts + ;; + *) + echo -e "127.0.0.1\t$1" | sudo tee -a /etc/hosts + ;; + esac +else + echo "You need to add at least a domain" +fi + diff --git a/bin/capslock b/bin/capslock new file mode 100755 index 00000000..5a61a5fa --- /dev/null +++ b/bin/capslock @@ -0,0 +1,3 @@ +#!/usr/bin/bash +v=$(xset -q | grep Caps) +echo ${v:7:17} diff --git a/bin/code-to-pdf b/bin/code-to-pdf new file mode 100755 index 00000000..eabc5027 --- /dev/null +++ b/bin/code-to-pdf @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +TITLE="$1" +shift + +enscript -1 --media=A4 \ + --toc \ + --header '%H - $N | | page $% of $= in file $v' \ + --font "Menlo-Regular@8.5" \ + --header-font "Menlo-Bold@10" \ + --margins=60:60:18:60 \ + --fancy-header=sjl \ + --title $TITLE \ + --baselineskip 3 \ + --line-numbers \ + --highlight \ + --color \ + --mark-wrapped-lines=arrow \ + -p - \ + --word-wrap $* \ + | ps2pdf -i -o code.pdf + diff --git a/bin/csvtomd b/bin/csvtomd new file mode 100755 index 00000000..876db647 --- /dev/null +++ b/bin/csvtomd @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 + +""" +csvtomd 0.2.1 + +Convert your CSV files into Markdown tables. + +More info: http://github.com/mplewis/csvtomd +""" + +import argparse +import csv +import sys + + +def check_negative(value): + try: + ivalue = int(value) + except ValueError: + raise argparse.ArgumentTypeError( + '"%s" must be an integer' % value) + if ivalue < 0: + raise argparse.ArgumentTypeError( + '"%s" must not be a negative value' % value) + return ivalue + + +def pad_to(unpadded, target_len): + """ + Pad a string to the target length in characters, or return the original + string if it's longer than the target length. + """ + under = target_len - len(unpadded) + if under <= 0: + return unpadded + return unpadded + (' ' * under) + + +def normalize_cols(table): + """ + Pad short rows to the length of the longest row to help render "jagged" + CSV files + """ + longest_row_len = max([len(row) for row in table]) + for row in table: + while len(row) < longest_row_len: + row.append('') + return table + + +def pad_cells(table): + """Pad each cell to the size of the largest cell in its column.""" + col_sizes = [max(map(len, col)) for col in zip(*table)] + for row in table: + for cell_num, cell in enumerate(row): + row[cell_num] = pad_to(cell, col_sizes[cell_num]) + return table + + +def horiz_div(col_widths, horiz, vert, padding): + """ + Create the column dividers for a table with given column widths. + + col_widths: list of column widths + horiz: the character to use for a horizontal divider + vert: the character to use for a vertical divider + padding: amount of padding to add to each side of a column + """ + horizs = [horiz * w for w in col_widths] + div = ''.join([padding * horiz, vert, padding * horiz]) + return div.join(horizs) + + +def add_dividers(row, divider, padding): + """Add dividers and padding to a row of cells and return a string.""" + div = ''.join([padding * ' ', divider, padding * ' ']) + return div.join(row) + + +def md_table(table, *, padding=1, divider='|', header_div='-'): + """ + Convert a 2D array of items into a Markdown table. + + padding: the number of padding spaces on either side of each divider + divider: the vertical divider to place between columns + header_div: the horizontal divider to place between the header row and + body cells + """ + table = normalize_cols(table) + table = pad_cells(table) + header = table[0] + body = table[1:] + + col_widths = [len(cell) for cell in header] + horiz = horiz_div(col_widths, header_div, divider, padding) + + header = add_dividers(header, divider, padding) + body = [add_dividers(row, divider, padding) for row in body] + + table = [header, horiz] + table.extend(body) + table = [row.rstrip() for row in table] + return '\n'.join(table) + + +def csv_to_table(file, delimiter): + return list(csv.reader(file, delimiter=delimiter)) + + +def main(): + parser = argparse.ArgumentParser( + description='Read one or more CSV files and output their contents in ' + 'the form of Markdown tables.') + parser.add_argument('files', metavar='csv_file', type=str, nargs='*', + default=['-'], + help="One or more CSV files to be converted. " + "Use - for stdin.") + parser.add_argument('-n', '--no-filenames', action='store_false', + dest='show_filenames', + help="Don't display filenames when outputting " + "multiple Markdown tables.") + parser.add_argument('-p', '--padding', type=check_negative, default=2, + help="The number of spaces to add between table cells " + "and column dividers. Default is 2 spaces.") + parser.add_argument('-d', '--delimiter', default=',', + help='The delimiter to use when parsing CSV data. ' + 'Default is "%(default)s"') + + args = parser.parse_args() + first = True + + if '-' in args.files and len(args.files) > 1: + print('Standard input can only be used alone.', file=sys.stderr) + exit(1) + for file_num, filename in enumerate(args.files): + # Print space between consecutive tables + if not first: + print('') + else: + first = False + # Read the CSV files + if filename == '-': + table = csv_to_table(sys.stdin, args.delimiter) + else: + with open(filename, 'rU') as f: + table = csv_to_table(f, args.delimiter) + # Print filename for each table if --no-filenames wasn't passed and + # more than one CSV was provided + file_count = len(args.files) + if args.show_filenames and file_count > 1: + print(filename + '\n') + # Generate and print Markdown table + print(md_table(table, padding=args.padding)) + + +if __name__ == '__main__': + main() diff --git a/bin/extract b/bin/extract new file mode 100755 index 00000000..768b5ded --- /dev/null +++ b/bin/extract @@ -0,0 +1,80 @@ +#!/usr/bin/bash + +if [ -f $1 ] ; then + case $1 in + *.tar.bz2) + if [ "$2" ]; then + tar xvjf $1 -C $2 + else + tar xvjf $1 + fi + ;; + *.tar.gz) + if [ "$2" ]; then + tar xvzf $1 -C $2 + else + tar xvzf $1 + fi + ;; + *.bz2) + if [ "$2" ]; then + bunzip -c $1 > $2 + else + bunzip $1 + fi + ;; + #*.rar) rar x $1 ;; + *.gz) + if [ "$2" ]; then + gunzip -c $1 > $2 + else + gunzip $1 + fi + ;; + *.tar) + if [ "$2" ]; then + tar xvf $1 -C $2 + else + tar xvf $1 + fi + ;; + *.tbz2) + if [ "$2" ]; then + tar xvjf $1 -C $2 + else + tar xvjf $1 + fi + ;; + *.tgz) + if [ "$2" ]; then + tar xvzf $1 -C $2 + else + tar xvzf $1 + fi + ;; + *.zip) + if [ "$2" ]; then + unzip $1 -d $2 + else + unzip $1 + fi + ;; + *.Z) + if [ "$2" ]; then + uncompress -c $1 > $2 + else + uncompress $1 + fi + ;; + *.7z) + if [ "$2" ]; then + 7z x $1 -o$2 + else + 7z x $1 + fi + ;; + *) echo "don't know how to extract '$1'..." ;; + esac +else + echo "'$1' is not a valid file!" +fi diff --git a/bin/git-cleaner b/bin/git-cleaner new file mode 100755 index 00000000..71686075 --- /dev/null +++ b/bin/git-cleaner @@ -0,0 +1,75 @@ +#!/usr/bin/bash + +function help() { +cat </dev/null + if [[ $? == 0 ]]; then + echo "Removed stored data for commit $head_sha." + fi + local repo_root="$(git_repo_toplevel)" + git reset HEAD "$repo_root" >/dev/null + git clean -f -d -q -- "$repo_root" >/dev/null + git checkout -- "$repo_root" >/dev/null + echo "Unstaged changes and untracked files removed." +} + +# Remove (permanently) all saved tags +function clean_all_tags() { + git for-each-ref refs/tags --format='%(refname:short)' | \ + while read tag; do + if [[ "$tag" =~ ^git-jump- ]]; then + git tag -d "$tag" + fi + done +} + +# Handle CLI arguments +if [[ "$1" == "clean" ]]; then + clean +elif [[ "$1" == "cleanall" ]]; then + clean_all_tags + clean +else + usage + exit 1 +fi diff --git a/bin/git-delete-submodule b/bin/git-delete-submodule new file mode 100755 index 00000000..99ed0426 --- /dev/null +++ b/bin/git-delete-submodule @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +test -z "$1" && echo "submodule required" 1>&2 && exit 1 +#cd "$(git root)" +test ! -f .gitmodules && echo ".gitmodules file not found" 1>&2 && exit 2 + +NAME="$(echo "$1" | sed 's/\/$//g')" +test -z \ + "$(git config --file=.gitmodules submodule."$NAME".url)" \ + && echo "submodule not found" 1>&2 && exit 3 + +# 1. Delete the relevant section from .git/config and clean submodule files +git submodule deinit -f "$NAME" || exit 4 +rmdir "$NAME" +rm -rf .git/modules/"$NAME" +# 2. Delete the relevant line from .gitmodules +git config --file=.gitmodules --remove-section submodule."$NAME" +git add .gitmodules +# 3. Run git rm --cached path_to_submodule +git rm --cached -rf "$NAME" +# 4. Need to confirm and commit the changes for yourself +echo +echo "Now submodule $NAME is deleted." +echo 'Confirm with `git submodule status` and commit the changes for yourself.' diff --git a/bin/git-jump b/bin/git-jump new file mode 100755 index 00000000..c2a3e93e --- /dev/null +++ b/bin/git-jump @@ -0,0 +1,158 @@ +#!/usr/bin/bash + +function help() { +cat </dev/null + # If the commit was successful, tag it (overwriting any previous tag) + if [[ $? == 0 ]]; then + status="*" + git tag -f "git-jump-$head_sha" >/dev/null + fi + echo "Previous HEAD was $head_sha$status, $(git_commit_subject $head_sha)" +} + +# Restore previously-saved changes +function restore() { + local status="" + # Save current changes before restoring + save + # Attempt to restore saved changes for specified commit + git checkout "git-jump-$1" 2>/dev/null + if [[ $? == 0 ]]; then + # If the restore was successful, figure out exactly what was saved, check + # out the original commit, then restore the saved changes on top of it + status="*" + local patch="$(git format-patch HEAD^ --stdout)" + git checkout HEAD^ 2>/dev/null + echo "$patch" | git apply - + else + # Otherwise, just restore the original commit + git checkout "$1" 2>/dev/null + fi + echo "HEAD is now $1$status, $(git_commit_subject $1)" +} + +# Jump to next commit +function next() { + local next_sha=$(git_next_sha) + if [[ "$next_sha" == "$(git_head_sha)" ]]; then + # Abort if no more commits + echo "Already at last commit in $git_branch. Congratulations!" + else + # Checkout branch by name if at its HEAD + if [[ "$next_sha" == "$(git_branch_sha)" ]]; then + next_sha="$git_branch" + fi + echo "Jumping ahead to next commit." + restore $next_sha + fi +} + +# Jump to previous commit +function prev() { + local prev_sha=$(git_prev_sha) + if [[ "$prev_sha" == "$(git_head_sha)" ]]; then + # Abort if no more commits + echo "Already at first commit in $git_branch." + else + echo "Jumping back to previous commit." + restore $prev_sha + fi +} + +# Show help if requested +if [[ "$1" == "--help" || "$1" == "-h" ]]; then + help + exit +fi + +# Check if branch is valid +git rev-parse "$git_branch" &>/dev/null +if [[ $? != 0 ]]; then + echo "Error: Branch \"$git_branch\" does not appear to be valid." + echo "Try $(basename "$0") --help for more information." + exit 1 +fi + +# Handle CLI arguments +if [[ "$1" == "next" ]]; then + next +elif [[ "$1" == "prev" ]]; then + prev +else + usage + exit 1 +fi diff --git a/bin/git-nuke b/bin/git-nuke new file mode 100755 index 00000000..0d3dad4b --- /dev/null +++ b/bin/git-nuke @@ -0,0 +1,12 @@ +#!/bin/sh +# +# Nukes a branch locally and on the origin remote. +# +# $1 - Branch name. +# +# Examples +# +# git nuke add-git-nuke + +git branch -D $1 +git push origin :$1 diff --git a/bin/git-open b/bin/git-open new file mode 100755 index 00000000..838d0a9a --- /dev/null +++ b/bin/git-open @@ -0,0 +1,149 @@ +#!/usr/bin/env bash + +# Opens the BitBucket/GitHub page for a repo/branch in your browser. +# +# git open +# git open [remote] [branch] + + +# are we in a git repo? +git rev-parse --is-inside-work-tree &>/dev/null + +if [[ $? != 0 ]]; then + echo "Not a git repository." 1>&2 + exit 1 +fi + + +# assume origin if not provided +# fallback to upstream if neither is present. +remote="origin" +if [ -n "$1" ]; then + if [ "$1" == "issue" ]; then + currentBranch=$(git symbolic-ref -q --short HEAD) + regex='^issue' + if [[ $currentBranch =~ $regex ]]; then + issue=${currentBranch#*#} + else + echo "'git open issue' expect branch naming to be issues/#123" 1>&2 + exit 1 + fi + else + remote="$1" + fi +fi + +remote_url="remote.${remote}.url" + +giturl=$(git config --get "$remote_url") +if [ -z "$giturl" ]; then + echo "$remote_url not set." 1>&2 + exit 1 +fi + +# get current branch +if [ -z "$2" ]; then + branch=$(git symbolic-ref -q --short HEAD) +else + branch="$2" +fi + +# Make # and % characters url friendly +# github.com/paulirish/git-open/pull/24 +branch=${branch//%/%25} && branch=${branch//#/%23} + +# URL normalization +# GitHub gists +if grep -q gist.github <<<$giturl; then + giturl=${giturl/git\@gist.github\.com\:/https://gist.github.com/} + providerUrlDifference=tree + +# GitHub +elif grep -q github <<<$giturl; then + giturl=${giturl/git\@github\.com\:/https://github.com/} + + # handle SSH protocol (links like ssh://git@github.com/user/repo) + giturl=${giturl/#ssh\:\/\/git\@github\.com\//https://github.com/} + + providerUrlDifference=tree + +# Bitbucket +elif grep -q bitbucket <<<$giturl; then + giturl=${giturl/git\@bitbucket\.org\:/https://bitbucket.org/} + # handle SSH protocol (change ssh://https://bitbucket.org/user/repo to https://bitbucket.org/user/repo) + giturl=${giturl/#ssh\:\/\/git\@/https://} + + rev="$(git rev-parse HEAD)" + git_pwd="$(git rev-parse --show-prefix)" + providerUrlDifference="src/${rev}/${git_pwd}" + branch="?at=${branch}" + +# Atlassian Bitbucket Server +elif grep -q "/scm/" <<<$giturl; then + re='(.*)/scm/(.*)/(.*)\.git' + if [[ $giturl =~ $re ]]; then + giturl=${BASH_REMATCH[1]}/projects/${BASH_REMATCH[2]}/repos/${BASH_REMATCH[3]} + providerUrlDifference=browse + branch="?at=refs%2Fheads%2F${branch}" + fi + +# GitLab +else + # custom GitLab + gitlab_domain=$(git config --get gitopen.gitlab.domain) + gitlab_ssh_domain=$(git config --get gitopen.gitlab.ssh.domain) + gitlab_ssh_domain=${gitlab_ssh_domain:-$gitlab_domain} + gitlab_ssh_port=$(git config --get gitopen.gitlab.ssh.port) + + gitlab_protocol=$(git config --get gitopen.gitlab.protocol) + if [ -z "$gitlab_protocol" ]; then + gitlab_protocol=https + fi + +if [ -n "$gitlab_domain" ]; then + if egrep -q "${gitlab_domain}|${gitlab_ssh_domain}" <<<$giturl; then + + # Handle GitLab's default SSH notation (like git@gitlab.domain.com:user/repo) + giturl=${giturl/git\@${gitlab_ssh_domain}\:/${gitlab_protocol}://${gitlab_domain}/} + + # handle SSH protocol (links like ssh://git@gitlab.domain.com/user/repo) + giturl=${giturl/#ssh\:\/\//${gitlab_protocol}://} + + # remove git@ from the domain + giturl=${giturl/git\@${gitlab_ssh_domain}/${gitlab_domain}/} + + # remove SSH port + if [ -n "$gitlab_ssh_port" ]; then + giturl=${giturl/\/:${gitlab_ssh_port}\///} + fi + providerUrlDifference=tree + fi + # hosted GitLab + elif grep -q gitlab <<<$giturl; then + giturl=${giturl/git\@gitlab\.com\:/https://gitlab.com/} + providerUrlDifference=tree + fi +fi +giturl=${giturl%\.git} + +if [ -n "$issue" ]; then + giturl="${giturl}/issues/${issue}" +elif [ -n "$branch" ]; then + giturl="${giturl}/${providerUrlDifference}/${branch}" +fi + +# simplify URL for master +giturl=${giturl/tree\/master/} + +# get current open browser command +case $( uname -s ) in + Darwin) open=open;; + MINGW*) open=start;; + CYGWIN*) open=cygstart;; + MSYS*) open="powershell.exe –NoProfile Start";; + *) open=${BROWSER:-xdg-open};; +esac + +# open it in a browser +$open "$giturl" &> /dev/null +exit $? diff --git a/bin/git-recall b/bin/git-recall new file mode 100755 index 00000000..5c630df4 --- /dev/null +++ b/bin/git-recall @@ -0,0 +1,349 @@ +#!/usr/bin/env bash + + +# usage info +usage() { + cat </dev/null; then + echo "abort: not a git repository." 1>&2 + exit 1 +fi + +# Parse options +while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do + case $1 in + -v | --version ) + echo "$version" + exit + ;; + -d | --date ) + SINCE="$2 days ago" + shift; + ;; + -a | --author ) + AUTHOR="$2" + shift + ;; + -f | --fetch ) + FETCH=true + ;; + -h | --help ) + usage + exit + ;; + * ) + echo "abort: unknown argument" 1>&2 + exit 1 + esac + shift +done +if [[ "$1" == "--" ]]; then shift; fi + + +# Colored output. +function colored() { + GREEN=$(tput setaf 4) + YELLOW=$(tput setaf 3) + NORMAL=$(tput sgr0) + REVERSE=$(tput rev) +} + +# Uncolored output. +function uncolored() { + GREEN="" + YELLOW="" + NORMAL="" + REVERSE="" +} + +# Enable colors if supported by terminal. +if [[ -t 1 ]] && [[ -n "$TERM" ]] && which tput &>/dev/null && tput colors &>/dev/null; then + ncolors=$(tput colors) + if [[ -n "$ncolors" ]] && [[ "$ncolors" -ge 8 ]] ; then + colored + else + uncolored + fi +else + uncolored +fi + +# Check if lesskey is installed. +if command -v lesskey &> /dev/null; then + LESSKEY=true +fi + +# Set AUTHOR to current user if no param passed or display for all users if param equal to "all". +if [[ ! -n $AUTHOR ]]; then + AUTHOR=$(git config user.name 2>/dev/null) +elif [[ $AUTHOR = "all" ]]; then + AUTHOR=".*" +fi + +# Fetch changes before. +if [[ $FETCH == true ]]; then + echo "${GREEN}Fetching changes...${NORMAL}" + git fetch --all &> /dev/null + tput cuu1 + tput ed # clear screen +fi + +# Log template. +GIT_FORMAT="%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset" + +# Log command. +GIT_LOG="git log --pretty=format:'${GIT_FORMAT}' + --author \"$AUTHOR\" + --since \"$SINCE\" --abbrev-commit" + +# Change temporary the IFS to store GIT_LOG's output into an array. +IFS=$'\n' +COMMITS=($(eval ${GIT_LOG} 2>/dev/null)) +unset IFS + +NI=${#COMMITS[@]} # Total number of items. +SN=$(( `tput lines` - 1 )) # Screen's number of lines. +CN=$(tput cols) # Screen's number of columns. +TN=$(( $NI < $((SN -1)) ? $NI : $((SN -1)))) # Number of lines that we will display. +OFFSET=0 #Incremented by one each time a commit's length is higher than teminal width. + +# If there is no items, exit. +if [[ $NI = 0 ]]; then + if [[ $AUTHOR = ".*" ]]; then + echo "${YELLOW}All contributors did nothing during this period.${NORMAL}" && exit 0 + else + echo "${YELLOW}The contributor \"${AUTHOR}\" did nothing during this period.${NORMAL}" && exit 0 + fi +fi + +# Set correct sed option according OS's type +case "$OSTYPE" in + darwin*) SED_BIN="sed -E" ;; + *) SED_BIN="sed -r" ;; +esac + +# Create array with uncolred commits (removing escape sequences using sed) +for elt in "${COMMITS[@]}" +do + ELT="$(echo "$elt" | $SED_BIN "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes + COMMITS_UNCOL+=("$ELT") +done +# Add +1 to OFFSET if a commit's length is bigger than the current terminal session's width. (This is to fix a redraw issue) +for C in "${COMMITS_UNCOL[@]}" +do + if [[ ${#C} -gt $CN ]]; then + OFFSET=$(( OFFSET + 1 )) + fi +done + +# Set keys. +au="`echo -e '\e[A'`" # arrow up +au_1="k" # arrow up +ad="`echo -e '\e[B'`" # arrow down +ad_1="j" # arrow down +ec="`echo -e '\e'`" # escape +nl="`echo -e '\n'`" # newline +nl_1="e" # expand +co="c" # checkout + +# Create a temporary lesskey file to change the keybindings so the user can use the TAB key to quit less. (more convenient) +if [[ $LESSKEY = true ]]; then + echo "\t quit" | lesskey -o $HOME/.lsh_less_keys_tmp -- - &> /dev/null +fi + +## Get commit's diff. +function get_diff() { + ELT="$(echo "${COMMITS_UNCOL[$CP-1]}")" + DIFF_TIP=${ELT:0:7} + DIFF_CMD="git show $DIFF_TIP --color=always" + DIFF=$(eval ${DIFF_CMD} 2>/dev/null) + tmp_diff="$(echo "$DIFF" | $SED_BIN "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes + off=$(echo "$tmp_diff" | grep -c ".\{$CN\}") #Number of lines in the diff that are longer than terminal width. + DIFF_LINES_NUMBER="$(echo "$DIFF" | wc -l)" + DIFF_LINES_NUMBER=$(( DIFF_LINES_NUMBER + off )) +} + +## This function will print the diff according the commit's tip. If the diff is too long, the result will be displayed using 'less'. +function print_diff() { + get_diff # get commit's diff + if [[ $(( TN + DIFF_LINES_NUMBER + OFFSET )) -ge $(( `tput lines` - 1 )) ]]; then + if [[ $LESSKEY = true ]]; then + echo "$DIFF" | less -r -k $HOME/.lsh_less_keys_tmp + else + echo "$DIFF" | less -r + fi + tput ed # Clear screen + else + stop=false + tput ed + for i in `seq 1 $TN` + do + echo -n "$NORMAL" + [[ $CP == "$i" ]] && echo -n "$REVERSE" + echo "${COMMITS[$i - 1]}" + [[ $CP == "$i" ]] && echo "$DIFF" + done + # Wait for user action. + while ! $stop + do + read -sn 1 key + case "$key" in + "$nl" | "$nl_1") + stop=true + ;; + "q") + stop=true + END=true + ;; + esac + done + [[ $END = false ]] && tput cuu $(( TN + DIFF_LINES_NUMBER + OFFSET )) && tput ed + [[ $END = true ]] && tput cuu 1 + fi +} + +function do_checkout(){ + ELT="$(echo "${COMMITS_UNCOL[$CP-1]}")" + DIFF_TIP=${ELT:0:7} + eval "git checkout $DIFF_TIP 2> /dev/null" +} + +# Calculate OFFSET to avoid bad redraw. +function calculate_offset { + tmp=1 + index=$(( SI -1 )) + while [[ $tmp -lt $SN ]] + do + el=${COMMITS_UNCOL[$index]} + if [[ ${#el} -gt $CN ]] && [[ $CP -lt $((SN -1)) ]]; then + OFFSET_2=$(( OFFSET_2 + 1 )) + tmp=$(( tmp + 1 )) + fi + tmp=$(( tmp + 1 )) + index=$(( index + 1 )) + done +} + +{ # capture stdout to stderr + +tput civis # hide cursor. +CP=1 # current position +SI=1 # index +END=false # end while loop +EXT=0 # Used to extend the number of lines to display. + +## Loops, reads inputs and prints commits until user presses 'q' to exit or TAB to show the diff. +while ! $END +do + END_INDEX=0 # Index for the last item to display + # When the number of item is higher than screen's number of lines, OFFSET_2 is recalculated each time we select a new item + # Set last index to print. (based on OFFSET) + if [[ $TN == $NI ]]; then + END_INDEX=$TN + OFFSET_2=$OFFSET + elif [[ $TN == $(( SN - 1 )) ]]; then + # Calculate new OFFSET. + if [[ $OFFSET != 0 ]]; then + [[ $CP -lt $((SN -1)) ]] && OFFSET_2=0 + EXT=1 + calculate_offset + fi + END_INDEX=$(( TN + SI -1 + EXT - OFFSET_2 )) + fi + + # Loop and echo commits + for i in `seq $SI $END_INDEX` + do + echo -n "$NORMAL" + [[ $CP == $i ]] && echo -n "$REVERSE" + echo "${COMMITS[$i - 1]}" + done + + read -sn 1 key + [[ "$key" == "$ec" ]] && + { + read -sn 2 k2 + key="$key$k2" + } + + case "$key" in + + "$au" | "$au_1") + CP=$(( CP - 1 )) + [[ $CP == 0 ]] && [[ $SI == 1 ]] && [[ $TN == $(( SN - 1 )) ]] && CP=$NI && SI=$(( NI - SN + 2 + OFFSET_2 )) + [[ $CP == 0 ]] && [[ $SI == 1 ]] && [[ $TN == $NI ]] && CP=$TN + [[ $CP == $(( SI - 1 )) ]] && [[ $SI != 1 ]] && SI=$(( SI - 1 )) + + [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( TN + EXT )) + [[ $SI != 1 ]] && tput ed # clear screen + ;; + + "$ad" | "$ad_1") + CP=$(( CP + 1 )) + [[ $CP == $(( NI + 1 )) ]] && CP=1 && SI=1 + [[ $CP == $(( SN + SI - 1 + EXT - OFFSET_2 )) ]] && [[ $TN == $(( SN - 1 )) ]] && SI=$(( SI + 1 )) + + [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( TN + EXT )) + [[ $SI != 1 ]] && tput ed # clear screen + [[ $SI = 1 ]] && [[ $CP = 1 ]] && tput ed # clear screen + ;; + + "$nl" | "$nl_1") + [[ $TN == $NI ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN != $NI ]] && tput cuu $(( TN + EXT )) + print_diff + ;; + "$co") + si=false + END=true + do_checkout + tput cuu 1 #move cursor up one line. (remove extra line) + ;; + + "q") + si=false + END=true + tput cuu 1 #move cursor up one line. (remove extra line) + ;; + + * ) + tput cuu $(( TN + OFFSET_2 )) + esac + +done + +# remove temporary less keybindings +[[ $LESSKEY = true ]] && rm $HOME/.lsh_less_keys_tmp + +tput cnorm # unhide cursor +echo "$NORMAL" # normal colors + +} >&2 # END capture + diff --git a/bin/git-wtf b/bin/git-wtf new file mode 100755 index 00000000..0d2cba8b --- /dev/null +++ b/bin/git-wtf @@ -0,0 +1,364 @@ +#!/usr/bin/env ruby + +HELP = < +.git-wtfrc" and edit it. The config file is a YAML file that specifies the +integration branches, any branches to ignore, and the max number of commits to +display when --all-commits isn't used. git-wtf will look for a .git-wtfrc file +starting in the current directory, and recursively up to the root. + +IMPORTANT NOTE: all local branches referenced in .git-wtfrc must be prefixed +with heads/, e.g. "heads/master". Remote branches must be of the form +remotes//. +EOS + +COPYRIGHT = <. +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You can find the GNU General Public License at: http://www.gnu.org/licenses/ +EOS + +require 'yaml' +CONFIG_FN = ".git-wtfrc" + +class Numeric; def pluralize s; "#{to_s} #{s}" + (self != 1 ? "s" : "") end end + +if ARGV.delete("--help") || ARGV.delete("-h") + puts USAGE + exit +end + +## poor man's trollop +$long = ARGV.delete("--long") || ARGV.delete("-l") +$short = ARGV.delete("--short") || ARGV.delete("-s") +$all = ARGV.delete("--all") || ARGV.delete("-a") +$all_commits = ARGV.delete("--all-commits") || ARGV.delete("-A") +$dump_config = ARGV.delete("--dump-config") +$key = ARGV.delete("--key") || ARGV.delete("-k") +$show_relations = ARGV.delete("--relations") || ARGV.delete("-r") +ARGV.each { |a| abort "Error: unknown argument #{a}." if a =~ /^--/ } + +## search up the path for a file +def find_file fn + while true + return fn if File.exist? fn + fn2 = File.join("..", fn) + return nil if File.expand_path(fn2) == File.expand_path(fn) + fn = fn2 + end +end + +want_color = `git config color.wtf` +want_color = `git config color.ui` if want_color.empty? +$color = case want_color.chomp + when "true"; true + when "auto"; $stdout.tty? +end + +def red s; $color ? "\033[31m#{s}\033[0m" : s end +def green s; $color ? "\033[32m#{s}\033[0m" : s end +def yellow s; $color ? "\033[33m#{s}\033[0m" : s end +def cyan s; $color ? "\033[36m#{s}\033[0m" : s end +def grey s; $color ? "\033[1;30m#{s}\033[0m" : s end +def purple s; $color ? "\033[35m#{s}\033[0m" : s end + +## the set of commits in 'to' that aren't in 'from'. +## if empty, 'to' has been merged into 'from'. +def commits_between from, to + if $long + `git log --pretty=format:"- %s [#{yellow "%h"}] (#{purple "%ae"}; %ar)" #{from}..#{to}` + else + `git log --pretty=format:"- %s [#{yellow "%h"}]" #{from}..#{to}` + end.split(/[\r\n]+/) +end + +def show_commits commits, prefix=" " + if commits.empty? + puts "#{prefix} none" + else + max = $all_commits ? commits.size : $config["max_commits"] + max -= 1 if max == commits.size - 1 # never show "and 1 more" + commits[0 ... max].each { |c| puts "#{prefix}#{c}" } + puts grey("#{prefix}... and #{commits.size - max} more (use -A to see all).") if commits.size > max + end +end + +def ahead_behind_string ahead, behind + [ahead.empty? ? nil : "#{ahead.size.pluralize 'commit'} ahead", + behind.empty? ? nil : "#{behind.size.pluralize 'commit'} behind"]. + compact.join("; ") +end + +def widget merged_in, remote_only=false, local_only=false, local_only_merge=false + left, right = case + when remote_only; %w({ }) + when local_only; %w{( )} + else %w([ ]) + end + middle = case + when merged_in && local_only_merge; green("~") + when merged_in; green("x") + else " " + end + print left, middle, right +end + +def show b + have_both = b[:local_branch] && b[:remote_branch] + + pushc, pullc, oosync = if have_both + [x = commits_between(b[:remote_branch], b[:local_branch]), + y = commits_between(b[:local_branch], b[:remote_branch]), + !x.empty? && !y.empty?] + end + + if b[:local_branch] + puts "Local branch: " + green(b[:local_branch].sub(/^heads\//, "")) + + if have_both + if pushc.empty? + puts "#{widget true} in sync with remote" + else + action = oosync ? "push after rebase / merge" : "push" + puts "#{widget false} NOT in sync with remote (you should #{action})" + show_commits pushc unless $short + end + end + end + + if b[:remote_branch] + puts "Remote branch: #{cyan b[:remote_branch]} (#{b[:remote_url]})" + + if have_both + if pullc.empty? + puts "#{widget true} in sync with local" + else + action = pushc.empty? ? "merge" : "rebase / merge" + puts "#{widget false} NOT in sync with local (you should #{action})" + show_commits pullc unless $short + end + end + end + + puts "\n#{red "WARNING"}: local and remote branches have diverged. A merge will occur unless you rebase." if oosync +end + +def show_relations b, all_branches + ibs, fbs = all_branches.partition { |name, br| $config["integration-branches"].include?(br[:local_branch]) || $config["integration-branches"].include?(br[:remote_branch]) } + if $config["integration-branches"].include? b[:local_branch] + puts "\nFeature branches:" unless fbs.empty? + fbs.each do |name, br| + next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) + next if br[:ignore] + local_only = br[:remote_branch].nil? + remote_only = br[:local_branch].nil? + name = if local_only + purple br[:name] + elsif remote_only + cyan br[:name] + else + green br[:name] + end + + ## for remote_only branches, we'll compute wrt the remote branch head. otherwise, we'll + ## use the local branch head. + head = remote_only ? br[:remote_branch] : br[:local_branch] + + remote_ahead = b[:remote_branch] ? commits_between(b[:remote_branch], head) : [] + local_ahead = b[:local_branch] ? commits_between(b[:local_branch], head) : [] + + if local_ahead.empty? && remote_ahead.empty? + puts "#{widget true, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is merged in" + elsif local_ahead.empty? + puts "#{widget true, remote_only, local_only, true} #{name} merged in (only locally)" + else + behind = commits_between head, (br[:local_branch] || br[:remote_branch]) + ahead = remote_only ? remote_ahead : local_ahead + puts "#{widget false, remote_only, local_only} #{name} #{local_only ? "(local-only) " : ""}is NOT merged in (#{ahead_behind_string ahead, behind})" + show_commits ahead unless $short + end + end + else + puts "\nIntegration branches:" unless ibs.empty? # unlikely + ibs.sort_by { |v, br| v }.each do |v, br| + next if $config["ignore"].member?(br[:local_branch]) || $config["ignore"].member?(br[:remote_branch]) + next if br[:ignore] + local_only = br[:remote_branch].nil? + remote_only = br[:local_branch].nil? + name = remote_only ? cyan(br[:name]) : green(br[:name]) + + ahead = commits_between v, (b[:local_branch] || b[:remote_branch]) + if ahead.empty? + puts "#{widget true, local_only} merged into #{name}" + else + #behind = commits_between b[:local_branch], v + puts "#{widget false, local_only} NOT merged into #{name} (#{ahead.size.pluralize 'commit'} ahead)" + show_commits ahead unless $short + end + end + end +end + +#### EXECUTION STARTS HERE #### + +## find config file and load it +$config = { "integration-branches" => %w(heads/master heads/next heads/edge), "ignore" => [], "max_commits" => 5 }.merge begin + fn = find_file CONFIG_FN + if fn && (h = YAML::load_file(fn)) # yaml turns empty files into false + h["integration-branches"] ||= h["versions"] # support old nomenclature + h + else + {} + end +end + +if $dump_config + puts $config.to_yaml + exit +end + +## first, index registered remotes +remotes = `git config --get-regexp ^remote\.\*\.url`.split(/[\r\n]+/).inject({}) do |hash, l| + l =~ /^remote\.(.+?)\.url (.+)$/ or next hash + hash[$1] ||= $2 + hash +end + +## next, index followed branches +branches = `git config --get-regexp ^branch\.`.split(/[\r\n]+/).inject({}) do |hash, l| + case l + when /branch\.(.*?)\.remote (.+)/ + name, remote = $1, $2 + + hash[name] ||= {} + hash[name].merge! :remote => remote, :remote_url => remotes[remote] + when /branch\.(.*?)\.merge ((refs\/)?heads\/)?(.+)/ + name, remote_branch = $1, $4 + hash[name] ||= {} + hash[name].merge! :remote_mergepoint => remote_branch + end + hash +end + +## finally, index all branches +remote_branches = {} +`git show-ref`.split(/[\r\n]+/).each do |l| + sha1, ref = l.chomp.split " refs/" + + if ref =~ /^heads\/(.+)$/ # local branch + name = $1 + next if name == "HEAD" + branches[name] ||= {} + branches[name].merge! :name => name, :local_branch => ref + elsif ref =~ /^remotes\/(.+?)\/(.+)$/ # remote branch + remote, name = $1, $2 + remote_branches["#{remote}/#{name}"] = true + next if name == "HEAD" + ignore = !($all || remote == "origin") + + branch = name + if branches[name] && branches[name][:remote] == remote + # nothing + else + name = "#{remote}/#{branch}" + end + + branches[name] ||= {} + branches[name].merge! :name => name, :remote => remote, :remote_branch => "#{remote}/#{branch}", :remote_url => remotes[remote], :ignore => ignore + end +end + +## assemble remotes +branches.each do |k, b| + next unless b[:remote] && b[:remote_mergepoint] + b[:remote_branch] = if b[:remote] == "." + b[:remote_mergepoint] + else + t = "#{b[:remote]}/#{b[:remote_mergepoint]}" + remote_branches[t] && t # only if it's still alive + end +end + +show_dirty = ARGV.empty? +targets = if ARGV.empty? + [`git symbolic-ref HEAD`.chomp.sub(/^refs\/heads\//, "")] +else + ARGV.map { |x| x.sub(/^heads\//, "") } +end.map { |t| branches[t] or abort "Error: can't find branch #{t.inspect}." } + +targets.each do |t| + show t + show_relations t, branches if $show_relations || t[:remote_branch].nil? +end + +modified = show_dirty && `git ls-files -m` != "" +uncommitted = show_dirty && `git diff-index --cached HEAD` != "" + +if $key + puts + puts KEY +end + +puts if modified || uncommitted +puts "#{red "NOTE"}: working directory contains modified files." if modified +puts "#{red "NOTE"}: staging area contains staged but uncommitted files." if uncommitted + +# the end! \ No newline at end of file diff --git a/bin/imgcat b/bin/imgcat new file mode 100755 index 00000000..1303aa6d --- /dev/null +++ b/bin/imgcat @@ -0,0 +1,103 @@ +#!/bin/bash + +# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux; +# ST, and for all ESCs in to be replaced with ESC ESC. It +# only accepts ESC backslash for ST. +function print_osc() { + if [[ $TERM == screen* ]] ; then + printf "\033Ptmux;\033\033]" + else + printf "\033]" + fi +} + +# More of the tmux workaround described above. +function print_st() { + if [[ $TERM == screen* ]] ; then + printf "\a\033\\" + else + printf "\a" + fi +} + +# print_image filename inline base64contents +# filename: Filename to convey to client +# inline: 0 or 1 +# base64contents: Base64-encoded contents +function print_image() { + print_osc + printf '1337;File=' + if [[ -n "$1" ]]; then + printf 'name='`echo -n "$1" | base64`";" + fi + if $(base64 --version 2>&1 | grep GNU > /dev/null) + then + BASE64ARG=-d + else + BASE64ARG=-D + fi + echo -n "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}' + printf ";inline=$2" + printf ";width=50" + printf ":" + echo -n "$3" + print_st + printf '\n' +} + +function error() { + echo "ERROR: $*" 1>&2 +} + +function show_help() { + echo "Usage: imgcat filename ..." 1>& 2 + echo " or: cat filename | imgcat" 1>& 2 +} + +## Main + +if [ -t 0 ]; then + has_stdin=f +else + has_stdin=t +fi + +# Show help if no arguments and no stdin. +if [ $has_stdin = f -a $# -eq 0 ]; then + show_help + exit +fi + +# Look for command line flags. +while [ $# -gt 0 ]; do + case "$1" in + -h|--h|--help) + show_help + exit + ;; + -*) + error "Unknown option flag: $1" + show_help + exit 1 + ;; + *) + if [ -r "$1" ] ; then + print_image "$1" 1 "$(base64 < "$1")" + else + error "imgcat: $1: No such file or directory" + exit 2 + fi + ;; + esac + shift +done + +# Read and print stdin +if [ $has_stdin = t ]; then + print_image "" 1 "$(cat | base64)" +fi + +echo +echo + +exit 0 diff --git a/bin/new b/bin/new new file mode 100755 index 00000000..d0de91de --- /dev/null +++ b/bin/new @@ -0,0 +1,91 @@ +#!/usr/bin/bash + +if [ $1 ]; then + while test $# -gt 0; do + case $1 in + -h|--help) + echo "Create files from template" + echo "" + echo "Usage: new [options] newFile" + echo "" + echo "Options:" + echo "--------" + echo -e "{-t,--template} filename \t Force use of template in Template Directory" + echo -e "{-l,--list} \t\t\t Lists the available templates" + echo -e "{-h,--help} \t\t\t Show this help text" + exit 0 + ;; + -t|--template) + shift + if [[ -f "$HOME/Templates/$1" ]]; then + template="$HOME/Templates/$1" + else + echo "The file $HOME/Templates/$1 does not exits" + exit 1 + fi + shift + ;; + -l|--list) + shift + for file in $HOME/Templates/*$1; do + echo ${file##*/} + done + exit 0 + ;; + *) + file=$1 + if [[ "$template" == "" ]]; then + extention=${file##*.} + posTemplates=() + if [[ -f $HOME/Templates/$extention ]]; then + posTemplates+=("$HOME/Templates/$extention") + fi + for template in $HOME/Templates/*.$extention; do + if [[ -f $template ]]; then + posTemplates+=( $template ) + fi + done + if [[ ${#posTemplates[@]} == 1 ]]; then + echo "Only one template" + template=${posTemplates[0]} + else + + posTemplates+=("Cancel") + while + echo Your options are: + for (( i=0; i<${#posTemplates[@]}; i++ )); do + echo "$i: ${posTemplates[$i]##*/}" + done + echo -e -n "Please enter a number: [0] " + read input + if [[ "$input"=="" ]]; then + test=0 + fi; + if [[ "$input" == "$(expr ${#posTemplates[@]} - 1)" ]]; then + echo "Exited By User" + exit 0 + fi + template=${posTemplates[$input]} + [[ $input>=${#posTemplates[@]} || $input<0 ]] + do + echo + echo Please chose one of the available options + done + fi + fi + + + if [[ -f "$file" ]]; then + echo "$file already exists" + echo "delete it first" + exit 1 + fi + cat "$template" > "$file" + echo "$file created from template $template" + exit 0 + ;; + esac + done +else + echo "You haven't given anything to work with" +fi diff --git a/bin/php-swap b/bin/php-swap new file mode 100755 index 00000000..be755f27 --- /dev/null +++ b/bin/php-swap @@ -0,0 +1,31 @@ +#!/usr/bin/bash +line=$(php --version | grep "PHP" -m 1) +target="$1" +lampp='/opt/lampp/lampp' +echo $phpexe +if [ "$(id -u)" != "0" ]; then + echo "Sorry, you are not root." + exit 1 +fi +if [[ $target = "" ]]; then + echo "PLease specify the version you want" + exit 1 +fi; + +file="/opt/lampp/etc/extra/httpd-xampp-php$target.conf" +phpexe=$(ls /opt/lampp/bin/php-$target*) +phpcgi=$(ls /opt/lampp/bin/php-cgi-$target*) +phpconfig=$(ls /opt/lampp/bin/php-config-$target*) +phpize=$(ls /opt/lampp/bin/phpize-$target*) + +$lampp stopapache +ln -s -f $file /opt/lampp/etc/extra/httpd-xampp.conf +ln -s -f $phpexe /opt/lampp/bin/php +ln -s -f $phpcgi /opt/lampp/bin/php-cgi +ln -s -f $phpconfig /opt/lampp/bin/php-config +ln -s -f $phpize /opt/lampp/bin/phpize + +$lampp startapache +echo +echo "Now on PHP $target" +exit 0 diff --git a/bin/update3rdPartyPlugins b/bin/update3rdPartyPlugins new file mode 100755 index 00000000..a052a9b8 --- /dev/null +++ b/bin/update3rdPartyPlugins @@ -0,0 +1,8 @@ +#!/usr/bin/bash + +pluginFolder="/home/jonathan/WPPlugins" +for dir in $pluginFolder/*/; do + cd $dir + pwd | cowsay + git-svn-mirror update +done diff --git a/bin/weather b/bin/weather new file mode 100755 index 00000000..33149d41 --- /dev/null +++ b/bin/weather @@ -0,0 +1,7 @@ +#!/usr/bin/bash +initial=$@ +place=${initial// /+} +if [[ "$place" == "" ]]; then + place="Bury+St+Edmunds" +fi +curl "wttr.in/$place" diff --git a/bin/where b/bin/where new file mode 100755 index 00000000..4e56e051 --- /dev/null +++ b/bin/where @@ -0,0 +1,2 @@ +#!/usr/bin/bash +find . -name "$1" | sed 's/[^/]\+$//' | uniq -c | sort -g diff --git a/config/conky/.themepacks b/config/conky/.themepacks new file mode 100644 index 00000000..59ddd035 --- /dev/null +++ b/config/conky/.themepacks @@ -0,0 +1,4 @@ +default-themes-1.1.cmtp.7z +default-themes-1.2.cmtp.7z +default-themes-2.1.cmtp.7z +default-themes-2.1.cmtp.7z diff --git a/config/conky/BibleVerse/bibleGateway b/config/conky/BibleVerse/bibleGateway new file mode 100644 index 00000000..cdd27d3b --- /dev/null +++ b/config/conky/BibleVerse/bibleGateway @@ -0,0 +1,54 @@ +background yes +update_interval 0.2 + + +double_buffer yes +no_buffers yes +text_buffer_size 2048 + +gap_x 10 +gap_y 10 + +own_window yes +own_window_type override +own_window_class Conky +own_window_transparent yes +own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager +own_window_colour 000000 +#own_window_argb_visual yes +#own_window_argb_value 128 + +border_inner_margin 0 +border_outer_margin 0 +alignment top_left + + +draw_shades no +draw_outline no +draw_borders no +draw_graph_borders no + +override_utf8_locale yes +use_xft yes +xftfont caviar dreams:size=10 +xftalpha 0.5 +uppercase no + +# Defining colors +default_color FFFFFF +# Shades of Gray +color1 DDDDDD +color2 AAAAAA +color3 888888 +# Blue +color4 2f519a +# Green +color5 77B753 + + +minimum_size 250 500 +own_window_argb_value 0 +own_window_argb_visual no +TEXT +${font GE Inspira:pixelsize=30}${execpi 60 python ~/.conky/BibleVerse/bibleGateway.py} +${color 2f519a}${execpi 60 python ~/.conky/BibleVerse/reference.py} diff --git a/config/conky/BibleVerse/bibleGateway.py b/config/conky/BibleVerse/bibleGateway.py new file mode 100644 index 00000000..dd2848ba --- /dev/null +++ b/config/conky/BibleVerse/bibleGateway.py @@ -0,0 +1,11 @@ +__author__ = 'jonathan' + +import urllib.request +import json +import html +import textwrap + +f = urllib.request.urlopen("http://www.biblegateway.com/votd/get/?format=json&version=ESV") +content = json.loads(f.read().decode("utf-8")) + +print(textwrap.fill(html.unescape(content['votd']['text']),30)) diff --git a/config/conky/BibleVerse/reference.py b/config/conky/BibleVerse/reference.py new file mode 100644 index 00000000..29a4671b --- /dev/null +++ b/config/conky/BibleVerse/reference.py @@ -0,0 +1,8 @@ +__author__ = 'jonathan' + +import urllib.request +import json + +f = urllib.request.urlopen("http://www.biblegateway.com/votd/get/?format=json&version=ESV") +content = json.loads(f.read().decode("utf-8")) +print(content['votd']['reference']) \ No newline at end of file diff --git a/config/conky/MyBlue/MyBlue b/config/conky/MyBlue/MyBlue new file mode 100644 index 00000000..24fe397d --- /dev/null +++ b/config/conky/MyBlue/MyBlue @@ -0,0 +1,42 @@ +use_xft yes +xftfont 123:size=8 +xftalpha 0.1 +update_interval 0.5 +total_run_times 0 + +own_window yes +own_window_type override +own_window_class Conky +own_window_transparent yes +own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager +own_window_colour 000000 +#own_window_argb_visual yes +#own_window_argb_value 128 + +background yes + +double_buffer yes +maximum_width 500 +draw_shades no +draw_outline no +draw_borders no +draw_graph_borders no +default_color white +default_shade_color red +default_outline_color green +alignment top_right +gap_x 0 +gap_y 10 +no_buffers yes +uppercase no +cpu_avg_samples 2 +net_avg_samples 1 +override_utf8_locale yes + + +own_window_argb_value 0 +own_window_argb_visual no +minimum_size 0 0 +TEXT +${color EAEAEA}${font GE Inspira:pixelsize=120}${time %H:%M}${color 2f519a}${time :%S}${font} +${color EAEAEA}${font GE Inspira:pixelsize=58}${time %A}${font GE Inspira:pixelsize=42}${color 2f519a}${time %d}${font GE Inspira:pixelsize=22}${color EAEAEA}${time %B} ${time %Y} diff --git a/config/conky/Octupi_Arch/FAMI_E.TTF b/config/conky/Octupi_Arch/FAMI_E.TTF new file mode 100755 index 00000000..dc3a173f Binary files /dev/null and b/config/conky/Octupi_Arch/FAMI_E.TTF differ diff --git a/config/conky/Octupi_Arch/co_main b/config/conky/Octupi_Arch/co_main new file mode 100644 index 00000000..a639d8e5 --- /dev/null +++ b/config/conky/Octupi_Arch/co_main @@ -0,0 +1,60 @@ +# -- Conky settings -- # +background no +update_interval 2 + +cpu_avg_samples 2 +net_avg_samples 2 + +override_utf8_locale yes + +double_buffer yes +no_buffers yes + +text_buffer_size 2048 +imlib_cache_size 0 + +# -- Window specifications -- # + +own_window yes +own_window_type override +own_window_class Conky +own_window_transparent yes +own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager +own_window_colour 000000 +#own_window_argb_visual yes +#own_window_argb_value 128 +border_inner_margin 0 +border_outer_margin 0 + +minimum_size 7266 748 + +# -- Graphics settings -- # +draw_shades no +draw_outline no +draw_borders no +draw_graph_borders no + +# -- Text settings -- # +use_xft yes +xftfont Santana:size=8 +xftalpha 0.8 + +uppercase no + +default_color FFFFFF + +# -- Lua load -- # +lua_load main.lua +lua_draw_hook_pre main +lua_startup_hook setup + +alignment top_left +gap_x 280 +gap_y 80 +own_window_argb_value 0 +own_window_argb_visual yes +own_window_colour 000000 +TEXT +#${offset 636}${voffset 223}${font Roboto:size=12}${time %l:%M %P } +${offset 630}${voffset 228}${font Roboto:size=35}Arch + diff --git a/config/conky/Octupi_Arch/face b/config/conky/Octupi_Arch/face new file mode 120000 index 00000000..5274bf90 --- /dev/null +++ b/config/conky/Octupi_Arch/face @@ -0,0 +1 @@ +./face.png \ No newline at end of file diff --git a/config/conky/Octupi_Arch/face.png b/config/conky/Octupi_Arch/face.png new file mode 100644 index 00000000..e910474f Binary files /dev/null and b/config/conky/Octupi_Arch/face.png differ diff --git a/config/conky/Octupi_Arch/faceold b/config/conky/Octupi_Arch/faceold new file mode 100644 index 00000000..2f2a6543 Binary files /dev/null and b/config/conky/Octupi_Arch/faceold differ diff --git a/config/conky/Octupi_Arch/main.lua b/config/conky/Octupi_Arch/main.lua new file mode 100644 index 00000000..f95f715b --- /dev/null +++ b/config/conky/Octupi_Arch/main.lua @@ -0,0 +1,1012 @@ +require "cairo" -- cairo graphic library + +function set_color( num, alpha) + + -- for white color num has no significance + if color == "WHITE" then + cairo_set_source_rgba(cr, 1, 1, 1, alpha); + end + + -- for dark as well color has no significance + if color == "DARK" then + cairo_set_source_rgba(cr, 0, 0, 0, alpha); + end + +end + +-- the funtion which paints the image in circle +function draw_image (ir,xc, yc, radius, path) + local w, h; + + cairo_arc (ir, xc, yc, radius, 0, 2*math.pi); + cairo_clip (ir); + cairo_new_path (ir); + + + local image = cairo_image_surface_create_from_png (path); + w = cairo_image_surface_get_width (image); + h = cairo_image_surface_get_height (image); + + + cairo_scale (ir, 2*radius/w, 2*radius/h); + w = cairo_image_surface_get_width (image); + h = cairo_image_surface_get_height (image); + + cairo_set_source_surface (ir, image, xc*(1/(2*radius/w)) - w/2, yc*(1/(2*radius/h)) - h/2); + cairo_paint (ir); + + cairo_surface_destroy (image); + cairo_destroy(ir); +end + + +-- the funtion which will be called at the beginning of the run, used to setup a few global values +function conky_setup( ) + + -- opening the settings file for reading the variabes + local file = io.open("settings"); + local output = file:read("*a"); + io.close(file); + + -- reading the variables + local nex = 0; + -- dimensions + _,nex,width = string.find(output,"WIDTH%s*=%s*(.-)%s*;", nex); + _,nex,height = string.find(output,"HEIGHT%s*=%s*(.-)%s*;", nex); + -- network + _,nex,interface = string.find(output, "NETWORK%s*=%s*(.-)%s*;",nex); + -- cpu + _,nex,no_of_cores = string.find(output, "NO_OF_CORES%s*=%s*(.-)%s*;",nex); + -- color style + _,nex,color = string.find(output, "COLOR%s*=%s*(.-)%s*;",nex); + -- gmail + _,nex,mail = string.find(output, "MAIL%s*=%s*(.-)%s*;",nex); + -- startup variables + check_mail = 1; + start = 1; + + -- checking for internet connection + local file = io.popen("/sbin/route -n | grep -c '^0\.0\.0\.0'"); + internet = tonumber(file:read("*a")); + io.close(file); + +end + +function conky_main( ) + + -- if no conky window then exit + if conky_window == nil then return end + + -- the number of update + local updates = tonumber(conky_parse("${updates}")); + -- if not third update exit + if updates < 3 then return end + + -- prepare cairo drawing surface + local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height); + cr = cairo_create(cs); + + -- for text extents + local extents = cairo_text_extents_t:create(); + local text = ""; + + -- few co-ordinates + local centerx = width/2; + local centery = height/2; + + -- setup variables for web based content + local min = tonumber(conky_parse('${time %}')); + local sec = tonumber(conky_parse('${time %}')); + local file = io.popen("/sbin/route -n | grep -c '^0\.0\.0\.0'"); + internet = tonumber(file:read("*a")); + io.close(file); + + + -- the centered photo ------------------------------------------- the centered image ------------------------------------------------------- + + local face_radius = 60; + + -- image + local ir = cairo_create(cs); + draw_image(ir, centerx, centery, face_radius, "face"); + + -- color and other settings for outher boundary + set_color(1,0.9); + cairo_set_line_width(cr, 3); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + + -- outer boundary + cairo_arc(cr, centerx , centery, face_radius, 0, 2*math.pi); + cairo_stroke(cr); + + + -- cpu stats ------------------------------------------------------------ cpu ---------------------------------------------------------------------------- + + local angle = 10*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of cpu + local cpu = conky_parse("${cpu}"); + + -- arrow to cpu + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + if tonumber(cpu) > 25 then + cairo_set_source_rgba(cr,1,0,0,0.4); + end + cairo_fill(cr); + + -- DARKcpu image + local ir = cairo_create(cs); + local image_path = "cpu"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + if tonumber(cpu) > 25 then + cairo_set_source_rgba(cr,1,0,0,1); + end + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "CPU"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = cpu.."%"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- top 10 process ------------------------------------------------ top 10 process cpu ------------------------------------------------------------- + + angle = angle - 10*(math.pi/180); + item_startx = item_centerx + item_radius + 5; + item_starty = item_centery; + item_endx = item_startx + math.cos(angle) * width/6; + item_endy = item_starty + math.sin(angle) * height/6; + item_curvex = item_startx + math.cos(angle) * width/12; + item_curvey = item_starty + math.sin(angle) * height/12; + -- print(item_startx.." "..item_starty.." "..item_endx.." "..item_endy.." "..item_curvex.." "..item_curvey) + + -- arrow + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- label text + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "Top 10 Process"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size+2); + cairo_show_text(cr, text); + + -- the values + set_color(1,0.7); + cairo_select_font_face(cr,"Arial",0,0); + cairo_set_font_size(cr,item_font_size/1.4); + for i = 1,10 do + local addison = " "; + local name = string.sub(conky_parse("${top name "..i.."}")..addison,1,10); + local value = conky_parse("${top cpu "..i.."}"); + text = name.." "..value; + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size/1.2 * (i+1) + 5); + cairo_show_text(cr,text); + end + + + -- cpu cores ---------------------------------------------- cpu cores --------------------------------------------------------- + angle = angle + 70*(math.pi/180); + item_endx = item_startx + math.cos(angle) * width/6; + item_endy = item_starty + math.sin(angle) * height/6; + item_curvex = item_startx + math.cos(angle) * width/12; + item_curvey = item_starty + math.sin(angle) * height/12; + -- print(item_startx.." "..item_starty.." "..item_endx.." "..item_endy.." "..item_curvex.." "..item_curvey) + + -- arrow + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- label text + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "Cpu Cores"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size+2); + cairo_show_text(cr, text); + + -- the values + set_color(1,0.7); + cairo_select_font_face(cr,"Arial",0,0); + cairo_set_font_size(cr,item_font_size/1.4); + for i = 1,no_of_cores do + local name = "CPU "..i; + local value = conky_parse("${top cpu "..i.."}"); + text = name.." "..value.."%"; + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size/1.2 * (i+1) + 5); + cairo_show_text(cr,text); + end + + + -- swap ------------------------------------------------------------ swap ---------------------------------------------------------------------------- + + local angle = 50*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6 + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of cpu + local swap = conky_parse("${swapperc}"); + if tonumber(swap) == nil then + swap = 0; + end + + -- arrow to swap + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex-100, item_curvey+40, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- swap image + local ir = cairo_create(cs); + image_path = "swap"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "SWAP"; + cairo_text_extents(cr, text, extents); + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = swap.."%"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- uptime ------------------------------------------------------------ uptime ---------------------------------------------------------------------------- + + local angle = 90*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of uptime + local uptime = conky_parse("${uptime}"); + + -- arrow to uptime + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex-100, item_curvey+100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- uptime image + local ir = cairo_create(cs); + image_path = "uptime"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "UPTIME"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = uptime; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- root file system ------------------------------------------------------------ root fs ---------------------------------------------------------------------------- + + local angle = 130*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of free space and total space + local free = "Free: "..conky_parse("${fs_free}"); + local total = "Total: "..conky_parse("${fs_size}"); + + -- arrow to root + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey+100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- root drive image + local ir = cairo_create(cs); + image_path = "root"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "ROOT"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = free; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + text = total; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size*2 + 8); + cairo_show_text(cr, text); + + + -- ram ------------------------------------------------------------ ram ---------------------------------------------------------------------------- + + local angle = 210*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of ram + local ram = conky_parse("${memperc}"); + + -- arrow to ram + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-70, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- root drive image + local ir = cairo_create(cs); + image_path = "ram"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "RAM"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = ram.."%"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- top 10 process ------------------------------------------------ top 10 process ram ------------------------------------------------------------- + + angle = angle + 20*(math.pi/180); + item_startx = item_centerx - item_radius - 5; + item_starty = item_centery; + item_endx = item_startx + math.cos(angle) * width/6; + item_endy = item_starty + math.sin(angle) * height/6; + item_curvex = item_startx + math.cos(angle) * width/12; + item_curvey = item_starty + math.sin(angle) * height/12; + -- print(item_startx.." "..item_starty.." "..item_endx.." "..item_endy.." "..item_curvex.." "..item_curvey) + + -- arrow + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- label text + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "Top 10 Process"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size+2); + cairo_show_text(cr, text); + + -- the values + set_color(1,0.7); + cairo_select_font_face(cr,"Arial",0,0); + cairo_set_font_size(cr,item_font_size/1.4); + for i = 1,10 do + local addison = " "; + local name = string.sub(conky_parse("${top_mem name "..i.."}")..addison,1,10); + local value = conky_parse("${top_mem mem_res "..i.."}"); + text = name.." "..value; + cairo_move_to(cr, item_endx - extents.width/2, item_endy + item_font_size/1.2 * (i+1) + 5); + cairo_show_text(cr,text); + end + + + -- disk input output ------------------------------------------------------------ disk io ---------------------------------------------------------------------------- + + local angle = 170*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- value of disk io + local diskio = conky_parse("${diskio}"); + + -- arrow to disk io + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-40, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- root drive image + local ir = cairo_create(cs); + image_path = "root"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "DISK I/O"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = diskio; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- disk read write ------------------------------------------------ read write ------------------------------------------------------------- + + angle = angle + 10*(math.pi/180); + item_startx = item_centerx - item_radius - 5; + item_starty = item_centery; + item_endx = item_startx + math.cos(angle) * width/6; + item_endy = item_starty + math.sin(angle) * height/6; + item_curvex = item_startx + math.cos(angle) * width/12; + item_curvey = item_starty + math.sin(angle) * height/12; + -- print(item_startx.." "..item_starty.." "..item_endx.." "..item_endy.." "..item_curvex.." "..item_curvey) + + -- arrow + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-50, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- label text + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- read + text = "Read: "..conky_parse("${diskio_read}"); + cairo_text_extents(cr,text,extents); + cairo_move_to(cr, item_endx - extents.width/2, item_endy+item_font_size+2); + cairo_show_text(cr,text); + + -- write + text = "Write: "..conky_parse("${diskio_write}"); + cairo_text_extents(cr,text,extents); + cairo_move_to(cr, item_endx - extents.width/2, item_endy+item_font_size*2+2); + cairo_show_text(cr,text); + + + -- network ----------------------------------------------------------------------- network ------------------------------------------------------------------------- + + local angle = 320*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- ip address + local network = conky_parse("${addr "..interface.."}"); + + -- arrow to network + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-70, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- image + local ir = cairo_create(cs); + image_path = "network"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "I.P."; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = network; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- network stats ------------------------------------------------ network stats ------------------------------------------------------------- + + angle = angle - 10*(math.pi/180); + item_startx = item_centerx + item_radius + 5; + item_starty = item_centery; + item_endx = item_startx + math.cos(angle) * width/6; + item_endy = item_starty + math.sin(angle) * height/6; + item_curvex = item_startx + math.cos(angle) * width/12; + item_curvey = item_starty + math.sin(angle) * height/12; + -- print(item_startx.." "..item_starty.." "..item_endx.." "..item_endy.." "..item_curvex.." "..item_curvey) + + -- arrow + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-100, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + set_color(1,1); + cairo_move_to(cr,item_endx,item_endy+item_font_size+5); + cairo_show_text(cr,"Upload"); + cairo_move_to(cr,item_endx + width/13,item_endy+item_font_size+5); + cairo_show_text(cr,"Download"); + cairo_move_to(cr,item_endx - width/20,item_endy+item_font_size*2+5); + cairo_show_text(cr, "Now"); + + cairo_select_font_face(cr,"Arial",0,0) + cairo_set_font_size(cr,item_font_size/1.4); + set_color(1,0.6); + text = conky_parse("${upspeed "..interface.."}"); + cairo_move_to(cr,item_endx ,item_endy+item_font_size*2+5); + cairo_show_text(cr, text); + text = conky_parse("${downspeed "..interface.."}"); + cairo_move_to(cr,item_endx + width/13,item_endy+item_font_size*2+5); + cairo_show_text(cr, text); + + local month = conky_parse("${time %b}"); + local year = conky_parse("${time %y}"); + local stats = conky_parse("${exec vnstat -i wlo1}"); + local ntotal_recieved, ntotal_trans, nmonth_received, nmonth_trans, ntoday_rec, ntoday_trans; + -- print(stats); + if(stats ~= "") then + _,nex,ntotal_recieved = string.find(stats, "rx:%s*(.-)iB"); + if(ntotal_recieved ~= nil ) then + total_recieved = ntotal_recieved; + end + -- print("tr: "..total_recieved.."iB"); + _,nex,ntotal_trans = string.find(stats, "tx:%s*(.-)iB",nex); + if(ntotal_trans ~= nil) then + total_trans = ntotal_trans; + end + -- print("tt: "..total_trans..'iB'); + + _,nex,_ = string.find(stats, "monthly",nex); + + _,nex,nmonth_received = string.find(stats, month.."%s*\'"..year.."%s*(.-)iB",nex); + if(nmonth_received ~= nil) then + month_recieved = nmonth_received; + end + -- print("mr: "..month_recieved..'iB'); + + _,nex,nmonth_trans = string.find(stats, "|%s*(.-)iB",nex); + if(nmonth_trans ~= nil) then + month_trans = nmonth_trans; + end + -- print("mt: "..month_trans..'iB'); + + _,nex,ntoday_rec = string.find(stats, "today%s*(.-)iB",nex); + if(ntoday_rec ~= nil) then + today_rec = ntoday_rec; + end + -- print("tor: "..today_rec..'iB'); + + _,nex,ntoday_trans = string.find(stats, "|%s*(.-)iB",nex); + if(ntoday_trans ~= nil) then + today_trans = ntoday_trans; + end + -- print("tot: "..today_trans..'iB'); + + cairo_set_font_size(cr, item_font_size); + cairo_select_font_face(cr, "Familian Elder",0,1); + set_color(1,1); + cairo_move_to(cr,item_endx-width/20 ,item_endy+item_font_size*3+5); + cairo_show_text(cr,"Today"); + cairo_move_to(cr,item_endx-width/20 ,item_endy+item_font_size*4+5); + cairo_show_text(cr,"Month"); + cairo_move_to(cr,200,220); + cairo_move_to(cr,item_endx-width/20 ,item_endy+item_font_size*5+5); + cairo_show_text(cr,"Total"); + + cairo_select_font_face(cr,"Arial",0,0) + cairo_set_font_size(cr,item_font_size/1.4); + set_color(1,0.6); + cairo_move_to(cr,item_endx ,item_endy+item_font_size*3+5); + cairo_show_text(cr,today_trans.."iB"); + cairo_move_to(cr,item_endx ,item_endy+item_font_size*4+5); + cairo_show_text(cr,month_trans.."iB"); + cairo_move_to(cr,item_endx ,item_endy+item_font_size*5+5); + cairo_show_text(cr,total_trans.."iB"); + + + cairo_move_to(cr,item_endx + width/13 ,item_endy+item_font_size*3+5); + cairo_show_text(cr, today_rec.."iB"); + cairo_move_to(cr,item_endx + width/13 ,item_endy+item_font_size*4+5); + cairo_show_text(cr,month_recieved.."iB"); + cairo_move_to(cr,item_endx + width/13 ,item_endy+item_font_size*5+5); + cairo_show_text(cr,total_recieved.."iB"); + end + + + -- gmail --------------------------------------------------------------- gmail new message ------------------------------------------------------------- + + if (min*60 + sec)%298 == 0 then + check_mail = 1; + end + + if (min%5 == 0 and check_mail == 1) or start == 1 then + if internet == 1 then + local val = conky_parse("${execi 300 curl -u "..mail.."}"); + _,_,new_mail = string.find(val, "%s*(.-)%s*"); + end + check_mail = 0; + start = 0; + end + + if internet ~= 1 then + new_mail = "No Network" + end + + if new_mail == nil then + new_mail = "Error!" + end + + local angle = 290*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- arrow to mail + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex, item_curvey-70, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- image + local ir = cairo_create(cs); + image_path = "mail"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "Unread"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = new_mail; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + + + -- battery --------------------------------------------------- battery -------------------------------------------------------------------- + local angle = 250*math.pi/180; + local item_startx = centerx + math.cos(angle) * face_radius; + local item_starty = centery + math.sin(angle) * face_radius; + local item_endx = centerx + math.cos(angle) * width/6; + local item_endy = centery + math.sin(angle) * height/6; + local item_curvex = centerx + math.cos(angle) * width/12; + local item_curvey = centery + math.sin(angle) * height/12; + local item_radius = 15; + local item_centerx = item_endx + math.cos(angle) * (item_radius + 5); + local item_centery = item_endy + math.sin(angle) * (item_radius + 5); + local item_font_size = height/50; + + -- arrow to mail + cairo_move_to(cr, item_startx, item_starty); + cairo_curve_to(cr, item_curvex, item_curvey, item_curvex+50, item_curvey-70, item_endx, item_endy); + set_color(1,0.5); + cairo_stroke(cr); + + -- background circle + cairo_arc(cr, item_centerx, item_centery, item_radius+5, 0, 2*math.pi ); + set_color(1,0.4); + cairo_fill(cr); + + -- image + local ir = cairo_create(cs); + image_path = "battery"; + if color == "WHITE" then + image_path = "white/"..image_path + end + if color == "DARK" then + image_path = "dark/"..image_path + end + draw_image(ir, item_centerx, item_centery, item_radius, image_path); + + -- outside boundry + cairo_arc(cr, item_centerx, item_centery, item_radius + 5, 0, 2*math.pi ); + set_color(1,1); + cairo_stroke(cr); + + -- font settings + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0 , 1); + cairo_set_font_size(cr, item_font_size); + + -- name text + text = "Power"; + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery - item_radius - 10); + cairo_show_text(cr, text); + + -- value text + text = conky_parse("${battery_short}"); + cairo_text_extents(cr, text, extents) + cairo_move_to(cr, item_centerx - extents.width/2, item_centery + item_radius + item_font_size + 8); + cairo_show_text(cr, text); + + + -- time and date ------------------------------------------ time and date + + local hour = conky_parse('${time %I}'); + local minute = conky_parse('${time %M}'); + local part = conky_parse('${time %p}'); + local day = conky_parse('${time %d}'); + local month = conky_parse('${time %B}'); + local year = conky_parse('${time %G}'); + + -- time + set_color(1,1); + cairo_select_font_face(cr, "Familian Elder", 0,1); + cairo_set_font_size(cr,height/10); + text = hour..":"..minute..part; + cairo_text_extents(cr,text,extents) + cairo_move_to(cr, centerx - extents.width/2, height/6); + cairo_show_text(cr, text); + local time_height = height/6; + + -- date + set_color(1,0.6); + item_font_size = height/30; + cairo_select_font_face(cr, "Arial",0,0); + cairo_set_font_size(cr, item_font_size) + text = month.." "..day..", "..year; + cairo_text_extents(cr,text,extents) + cairo_move_to(cr, centerx - extents.width/2, time_height + height/30); + cairo_show_text(cr, text); + + + -- destroying the cairo surface + cairo_destroy(cr); + cairo_surface_destroy(cs); + cr=nil; +end diff --git a/config/conky/Octupi_Arch/settings b/config/conky/Octupi_Arch/settings new file mode 100644 index 00000000..5c2b567b --- /dev/null +++ b/config/conky/Octupi_Arch/settings @@ -0,0 +1,17 @@ + +# dimenstions +WIDTH = 1366; +HEIGHT = 748; + +# network +NETWORK = wlo1; + +# cpu +NO_OF_CORES = 8; + +# color scheme the values are DARK or WHITE +COLOR = WHITE; + +# gmail account +MAIL = '''MAIL''':'''PASSWARD''' https://mail.google.com/mail/feed/atom/unread; + diff --git a/config/conky/conky-startup.sh b/config/conky/conky-startup.sh new file mode 100644 index 00000000..7470f295 --- /dev/null +++ b/config/conky/conky-startup.sh @@ -0,0 +1,8 @@ +sleep 5s +killall conky +cd "/home/jonathan/.conky/BibleVerse" +conky -c "/home/jonathan/.conky/BibleVerse/bibleGateway" & +cd "/home/jonathan/.conky/MyBlue" +conky -c "/home/jonathan/.conky/MyBlue/MyBlue" & +cd "/home/jonathan/.conky/Octupi_Arch" +conky -c "/home/jonathan/.conky/Octupi_Arch/co_main" & diff --git a/config/i3/config b/config/i3/config new file mode 100644 index 00000000..67153671 --- /dev/null +++ b/config/i3/config @@ -0,0 +1,361 @@ +# This file has been auto-generated by i3-config-wizard(1). +# It will not be overwritten, so edit it as you like. +# +# Should you change your keyboard layout some time, delete +# this file and re-run i3-config-wizard(1). +# + +# i3 config file (v4) +# +# Please see http://i3wm.org/docs/userguide.html for a complete reference! + +set $mod Mod4 + +set $base00 #101218 +set $base01 #1f222d +set $base02 #252936 +set $base03 #7780a1 +set $base04 #C0C5CE +set $base05 #d1d4e0 +set $base06 #C9CCDB +set $base07 #ffffff +set $base08 #ee829f +set $base09 #f99170 +set $base0A #ffefcc +set $base0B #a5ffe1 +set $base0C #97e0ff +set $base0D #97bbf7 +set $base0E #c0b7f9 +set $base0F #fcc09e + + +# Font for window titles. Will also be used by the bar unless a different font +# is used in the bar {} block below. +font pango:monospace 8 + +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +#font pango:DejaVu Sans Mono 8 + +# Before i3 v4.8, we used to recommend this one as the default: +# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +# The font above is very space-efficient, that is, it looks good, sharp and +# clear in small sizes. However, its unicode glyph coverage is limited, the old +# X core fonts rendering does not support right-to-left and this being a bitmap +# font, it doesn’t scale on retina/hidpi displays. + +# Use Mouse+$mod to drag floating windows to their wanted position +floating_modifier $mod + +# start a terminal +# bindsym $mod+Return exec xfce4-terminal +#bindsym $mod+Return exec konsole +bindsym $mod+Return exec termite + +# kill focused window +bindsym $mod+q kill + +# start dmenu (a program launcher) +# bindsym $mod+d exec dmenu_run +bindsym $mod+d exec albert toggle +#bindsym $mod+z exec xfce4-appfinder + +#kill i3 +bindsym $mod+Shift+x exec killall i3 + +for_window [class="xfce4-appfinder"] floating enable + + + +# There also is the (new) i3-dmenu-desktop which only displays applications +# shipping a .desktop file. It is a wrapper around dmenu, so you need that +# installed. +# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop + +# change focus +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right +bindsym $mod+h focus left + +# alternatively, you can use the cursor keys: +bindsym $mod+Left focus left +bindsym $mod+Down focus down +bindsym $mod+Up focus up +bindsym $mod+Right focus right + +# move focused window +bindsym $mod+Shift+j move down +bindsym $mod+Shift+k move up +bindsym $mod+Shift+l move right +bindsym $mod+Shift+h move left + +# alternatively, you can use the cursor keys: +bindsym $mod+Shift+Left move left +bindsym $mod+Shift+Down move down +bindsym $mod+Shift+Up move up +bindsym $mod+Shift+Right move right + +# split in horizontal orientation +bindsym $mod+g split h + +# split in vertical orientation +bindsym $mod+v split v + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout toggle split + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# focus the parent container +bindsym $mod+a focus parent + +# move to the parent container +bindsym $mod+Shift+a move parent + +# focus the child container +bindsym $mod+z focus child + +# move to the child container +bindsym $mod+Shift+z focus child + + +#set workspace names +set $workspace1 "1: Browser " +set $workspace2 "2: Terminal " +set $workspace3 "3" +set $workspace4 "4" +set $workspace5 "5" +set $workspace6 "6" +set $workspace7 "7" +set $workspace8 "8" +set $workspace9 "9" +set $workspace10 "10: Chat " + +# switch to workspace +bindsym $mod+1 workspace $workspace1 +bindsym $mod+2 workspace $workspace2 +bindsym $mod+3 workspace $workspace3 +bindsym $mod+4 workspace $workspace4 +bindsym $mod+5 workspace $workspace5 +bindsym $mod+6 workspace $workspace6 +bindsym $mod+7 workspace $workspace7 +bindsym $mod+8 workspace $workspace8 +bindsym $mod+9 workspace $workspace9 +bindsym $mod+0 workspace $workspace10 + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace $workspace1, workspace $workspace1 +bindsym $mod+Shift+2 move container to workspace $workspace2, workspace $workspace2 +bindsym $mod+Shift+3 move container to workspace $workspace3, workspace $workspace3 +bindsym $mod+Shift+4 move container to workspace $workspace4, workspace $workspace4 +bindsym $mod+Shift+5 move container to workspace $workspace5, workspace $workspace5 +bindsym $mod+Shift+6 move container to workspace $workspace6, workspace $workspace6 +bindsym $mod+Shift+7 move container to workspace $workspace7, workspace $workspace7 +bindsym $mod+Shift+8 move container to workspace $workspace8, workspace $workspace8 +bindsym $mod+Shift+9 move container to workspace $workspace9, workspace $workspace9 +bindsym $mod+Shift+0 move container to workspace $workspace10, workspace $workspace10 + +#assign programs to workspaces +assign [class="chromium"] $workspace1 +assign [instance="crx_knipolnnllmklapflnccelgolnpehhpl"] to $workspace10 + +for_window [window_role="gimp-toolbox"] floating disable; move left; move left; +for_window [window_role="gimp-dock"] floating disable; move right; move right; + +# reload the configuration file +bindsym $mod+Shift+c reload + +# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) +bindsym $mod+Shift+r restart + +# exit i3 (logs you out of your X session) +#bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" + +# resize window (you can also use the mouse for that) +mode "resize" { + # These bindings trigger as soon as you enter the resize mode + + # Pressing left will shrink the window’s width. + # Pressing right will grow the window’s width. + # Pressing up will shrink the window’s height. + # Pressing down will grow the window’s height. + bindsym h resize shrink width 10 px or 10 ppt + bindsym j resize grow height 10 px or 10 ppt + bindsym k resize shrink height 10 px or 10 ppt + bindsym l resize grow width 10 px or 10 ppt + + # same bindings, but for the arrow keys + bindsym Left resize shrink width 10 px or 10 ppt + bindsym Down resize grow height 10 px or 10 ppt + bindsym Up resize shrink height 10 px or 10 ppt + bindsym Right resize grow width 10 px or 10 ppt + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + +bindsym $mod+r mode "resize" + + +# Widow Colours +# border background text indicator + client.focused $base01 $base01 $base07 $base0F + client.focused_inactive $base02 $base02 $base03 $base0F + client.unfocused $base02 $base02 $base03 $base0F + client.urgent $base02 $base08 $base00 $base0F + + +# Start i3bar to display a workspace bar (plus the system information i3status +# finds out, if available) +bar { + status_command i3status + #tray_output primary + colors { + separator $base03 + background $base01 + statusline $base05 + # border background text + focused_workspace $base01 $base01 $base07 + active_workspace $base01 $base02 $base03 + inactive_workspace $base01 $base01 $base03 + urgent_workspace $base01 $base01 $base08 + } +} + +#Use xfce4 panel instead of i3's +#exec --no-startup-id xfce4-panel --disable-wm-check + +bindsym control+mod1+c exec chromium, workspace $workspace1 +bindsym control+mod1+f exec thunar + + +# Pulse Audio controls +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 1 +5% #increase sound volume +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 1 -5% #decrease sound volume +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 1 toggle # mute sound + +# Sreen brightness controls +bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness +bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness + +# Touchpad controls +bindsym XF86TouchpadToggle exec /some/path/toggletouchpad.sh # toggle touchpad + +# Media player controls +bindsym XF86AudioPlay exec playerctl play +bindsym XF86AudioPause exec playerctl pause +bindsym XF86AudioNext exec playerctl next +bindsym XF86AudioPrev exec playerctl previous + +#printscreen +bindsym Print exec xfce4-screenshooter -f +bindsym ctrl+Print exec xfce4-screenshooter -w +bindsym Shift+Print exec xfce4-screenshooter -r + + +bindsym $mod+x exec --no-startup-id ~/.config/i3/i3exit logout + + +set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown +mode "$mode_system" { + bindsym l exec --no-startup-id ~/.config/i3/i3exit lock, mode "default" + bindsym e exec --no-startup-id ~/.config/i3/i3exit logout, mode "default" + bindsym s exec --no-startup-id ~/.config/i3/i3exit suspend, mode "default" + bindsym h exec --no-startup-id ~/.config/i3/i3exit hibernate, mode "default" + bindsym r exec --no-startup-id~/.config/i3/i3exit reboot, mode "default" + bindsym Shift+s exec --no-startup-id ~/.config/i3/i3exit shutdown, mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} +bindsym ctrl+Shift+l mode "$mode_system" +#bindsym ctrl+l exec "/home/jonathan/.bin/i3exit lock" + + +################################################## +# # +# i3 Gaps # +# # +################################################## + +for_window [class="^.*"] border pixel 0 +gaps outer 0 +gaps inner 10 +smart_gaps on + +set $mode_gaps Gaps: (o) outer, (i) inner, (d) default +set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global) +bindsym $mod+Shift+g mode "$mode_gaps" + +mode "$mode_gaps" { + bindsym o mode "$mode_gaps_outer" + bindsym i mode "$mode_gaps_inner" + bindsym d gaps inner current set 10; gaps outer current set 0 + bindsym Shift+d gaps inner all set 10; gaps outer all set 0 + bindsym Return mode "default" + bindsym Escape mode "default" +} + +mode "$mode_gaps_inner" { + bindsym plus gaps inner current plus 5 + bindsym minus gaps inner current minus 5 + bindsym 0 gaps inner current set 0 + bindsym d gaps inner current set 10 + + bindsym Shift+plus gaps inner all plus 5 + bindsym Shift+minus gaps inner all minus 5 + bindsym Shift+0 gaps inner all set 0 + bindsym Shift+d gaps inner all set 10 + + bindsym Return mode "default" + bindsym Escape mode "default" +} +mode "$mode_gaps_outer" { + bindsym plus gaps outer current plus 5 + bindsym minus gaps outer current minus 5 + bindsym 0 gaps outer current set 0 + bindsym d gaps outer current set 0 + + bindsym Shift+plus gaps outer all plus 5 + bindsym Shift+minus gaps outer all minus 5 + bindsym Shift+0 gaps outer all set 0 + bindsym Shift+d gaps outer all set 0 + + bindsym Return mode "default" + bindsym Escape mode "default" +} + + + + +#exec --no-startup-id redshift-gtk +#exec_always feh --bg-fill /home/jonathan/Pictures/Wallpapers/blueConky/dfCXBel.jpg +exec --no-startup-id compton -f -i 0.95 +exec --no-startup-id albert +#exec --no-startup-id nm-applet +#exec --no-startup-id blueman-applet +#exec --no-startup-id xfce4-clipman +#exec --no-startup-id xfce4-power-manager +#exec_always --no-startup-id /usr/lib/kdeconnectd +#exec_always --no-startup-id indicator-kdeconnect +#exec_always --no-startup-id killall conky +#exec_always --no-startup-id sleep 1s; killall -9 conky +#exec --no-startup-id sh /home/jonathan/.conky/conky-startup.sh +#exec_always --no-startup-id sleep 2s; conky -c "/home/jonathan/.conky/BibleVerse/bibleGateway" +#exec_always --no-startup-id sleep 2s; conky -c "/home/jonathan/.conky/MyBlue/MyBlue" +#exec_always --no-startup-id cd /home/jonathan/.conky/Octupi_Arch +#exec_always --no-startup-id sleep 2s; conky -c "co_main" +exec setxkbmap gb diff --git a/config/i3/configWork b/config/i3/configWork new file mode 100644 index 00000000..f1cf663c --- /dev/null +++ b/config/i3/configWork @@ -0,0 +1,363 @@ +# i3 config file (v4) +# +# Please see http://i3wm.org/docs/userguide.html for a complete reference! + +set $mod Mod4 + +set $base00 #101218 +set $base01 #1f222d +set $base02 #252936 +set $base03 #7780a1 +set $base04 #C0C5CE +set $base05 #d1d4e0 +set $base06 #C9CCDB +set $base07 #ffffff +set $base08 #ee829f +set $base09 #f99170 +set $base0A #ffefcc +set $base0B #a5ffe1 +set $base0C #97e0ff +set $base0D #97bbf7 +set $base0E #c0b7f9 +set $base0F #fcc09e + + +# Font for window titles. Will also be used by the bar unless a different font +# is used in the bar {} block below. +font pango:monospace 8 + +# This font is widely installed, provides lots of unicode glyphs, right-to-left +# text rendering and scalability on retina/hidpi displays (thanks to pango). +font pango:DejaVu Sans Mono 8 + +# Before i3 v4.8, we used to recommend this one as the default: +# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +# The font above is very space-efficient, that is, it looks good, sharp and +# clear in small sizes. However, its unicode glyph coverage is limited, the old +# X core fonts rendering does not support right-to-left and this being a bitmap +# font, it doesn’t scale on retina/hidpi displays. + +# Use Mouse+$mod to drag floating windows to their wanted position +floating_modifier $mod + +# start a terminal +# bindsym $mod+Return exec xfce4-terminal +# bindsym $mod+Return exec konsole +bindsym $mod+Return exec termite + +# kill focused window +bindsym $mod+q kill + +# start dmenu (a program launcher) +#bindsym $mod+d exec dmenu_run +bindsym $mod+d exec albert toggle +bindsym XF86Search exec albert toggle +#bindsym $mod+z exec xfce4-appfinder + +#kill i3 +bindsym $mod+Shift+x exec killall i3 + +for_window [class="xfce4-appfinder"] floating enable + + + +# There also is the (new) i3-dmenu-desktop which only displays applications +# shipping a .desktop file. It is a wrapper around dmenu, so you need that +# installed. +# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop + +# change focus +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right +bindsym $mod+h focus left + +# alternatively, you can use the cursor keys: +bindsym $mod+Left focus left +bindsym $mod+Down focus down +bindsym $mod+Up focus up +bindsym $mod+Right focus right + +# move focused window +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 +bindsym $mod+Shift+Down move down +bindsym $mod+Shift+Up move up +bindsym $mod+Shift+Right move right + +# split in horizontal orientation +bindsym $mod+g split h + +# split in vertical orientation +bindsym $mod+v split v + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout toggle split + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# focus the parent container +bindsym $mod+a focus parent + +# focus the child container +bindsym $mod+Shift+a focus child + + +#set workspace names +set $workspace1 "1: Browser " +set $workspace2 "2: Terminal " +set $workspace3 "3" +set $workspace4 "4" +set $workspace5 "5" +set $workspace6 "6" +set $workspace7 "7" +set $workspace8 "8" +set $workspace9 "9" +set $workspace10 "10 Chat " + +# switch to workspace +bindsym $mod+1 workspace $workspace1 +bindsym $mod+2 workspace $workspace2 +bindsym $mod+3 workspace $workspace3 +bindsym $mod+4 workspace $workspace4 +bindsym $mod+5 workspace $workspace5 +bindsym $mod+6 workspace $workspace6 +bindsym $mod+7 workspace $workspace7 +bindsym $mod+8 workspace $workspace8 +bindsym $mod+9 workspace $workspace9 +bindsym $mod+0 workspace $workspace10 + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace $workspace1, workspace $workspace1 +bindsym $mod+Shift+2 move container to workspace $workspace2, workspace $workspace2 +bindsym $mod+Shift+3 move container to workspace $workspace3, workspace $workspace3 +bindsym $mod+Shift+4 move container to workspace $workspace4, workspace $workspace4 +bindsym $mod+Shift+5 move container to workspace $workspace5, workspace $workspace5 +bindsym $mod+Shift+6 move container to workspace $workspace6, workspace $workspace6 +bindsym $mod+Shift+7 move container to workspace $workspace7, workspace $workspace7 +bindsym $mod+Shift+8 move container to workspace $workspace8, workspace $workspace8 +bindsym $mod+Shift+9 move container to workspace $workspace9, workspace $workspace9 +bindsym $mod+Shift+0 move container to workspace $workspace10, workspace $workspace10 + +# move workspace to left/right +bindsym $mod+control+Left move workspace to output left +bindsym $mod+control+Right move workspace to output right + + +bindsym $mod+control+h move workspace to output left +bindsym $mod+control+l move workspace to output right + + +#assign programs to workspaces +assign [class="chromium"] $workspace1 +assign [class="skypeforlinux"] $workspace10 + +#make applications open in floating mode +for_window [class="Galculator"] floating enable + +# reload the configuration file +bindsym $mod+Shift+c reload + +# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) +bindsym $mod+Shift+r restart + +# exit i3 (logs you out of your X session) +bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" + +# resize window (you can also use the mouse for that) +mode "resize" { + # These bindings trigger as soon as you enter the resize mode + + # Pressing left will shrink the window’s width. + # Pressing right will grow the window’s width. + # Pressing up will shrink the window’s height. + # Pressing down will grow the window’s height. + bindsym h resize shrink width 10 px or 10 ppt + bindsym j resize grow height 10 px or 10 ppt + bindsym k resize shrink height 10 px or 10 ppt + bindsym l resize grow width 10 px or 10 ppt + + # same bindings, but for the arrow keys + bindsym Left resize shrink width 10 px or 10 ppt + bindsym Down resize grow height 10 px or 10 ppt + bindsym Up resize shrink height 10 px or 10 ppt + bindsym Right resize grow width 10 px or 10 ppt + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + +bindsym $mod+r mode "resize" + + +# Widow Colours +# border background text indicator + client.focused $base01 $base01 $base07 $base0F + client.focused_inactive $base02 $base02 $base03 $base0F + client.unfocused $base02 $base02 $base03 $base0F + client.urgent $base02 $base08 $base00 $base0F + + +# Start i3bar to display a workspace bar (plus the system information i3status +# finds out, if available) +bar { + status_command i3status + #tray_output primary + colors { + separator $base03 + background $base01 + statusline $base05 + # border background text + focused_workspace $base01 $base01 $base07 + active_workspace $base01 $base02 $base03 + inactive_workspace $base01 $base01 $base03 + urgent_workspace $base01 $base01 $base08 + } +} + +#Use xfce4 panel instead of i3's +#exec --no-startup-id xfce4-panel --disable-wm-check + +bindsym control+mod1+c exec chromium, workspace $workspace1 +bindsym control+mod1+f exec thunar +bindsym XF86Mail exec thunderbird +bindsym $mod+z exec zeal + +# Pulse Audio controls +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% #increase sound volume +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% #decrease sound volume +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # mute sound + +# Sreen brightness controls +#bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness +#bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness + +# Touchpad controls +#bindsym XF86TouchpadToggle exec /some/path/toggletouchpad.sh # toggle touchpad + +# Media player controls +bindsym XF86AudioPlay exec playerctl play-pause +#bindsym XF86AudioPause exec playerctl pause +#bindsym XF86AudioNext exec playerctl next +#bindsym XF86AudioPrev exec playerctl previous + +#calculator button +bindsym XF86Calculator exec galculator + +#printscreen +bindsym Print exec xfce4-screenshooter -f +bindsym ctrl+Print exec xfce4-screenshooter -w +bindsym Shift+Print exec xfce4-screenshooter -r + + +bindsym $mod+x exec --no-startup-id ~/.config/i3/i3exit logout + + +set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown +mode "$mode_system" { + bindsym l exec --no-startup-id ~/.config/i3/i3exit lock, mode "default" + bindsym e exec --no-startup-id ~/.config/i3/i3exit logout, mode "default" + bindsym s exec --no-startup-id ~/.config/i3/i3exit suspend, mode "default" + bindsym h exec --no-startup-id ~/.config/i3/i3exit hibernate, mode "default" + bindsym r exec --no-startup-id~/.config/i3/i3exit reboot, mode "default" + bindsym Shift+s exec --no-startup-id ~/.config/i3/i3exit shutdown, mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} +bindsym ctrl+shift+l mode "$mode_system" +#bindsym ctrl+l exec "~/.config/i3/i3exit lock" + +################################################## +# # +# i3 Gaps # +# # +################################################## + +for_window [class="^.*"] border pixel 0 +gaps outer 0 +gaps inner 10 +smart_gaps on + +set $mode_gaps Gaps: (o) outer, (i) inner, (d) default +set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global) +bindsym $mod+Shift+g mode "$mode_gaps" + +mode "$mode_gaps" { + bindsym o mode "$mode_gaps_outer" + bindsym i mode "$mode_gaps_inner" + bindsym d gaps inner current set 10; gaps outer current set 0 + bindsym Shift+d gaps inner all set 10; gaps outer all set 0 + bindsym Return mode "default" + bindsym Escape mode "default" +} + +mode "$mode_gaps_inner" { + bindsym plus gaps inner current plus 5 + bindsym minus gaps inner current minus 5 + bindsym 0 gaps inner current set 0 + bindsym d gaps inner current set 10 + + bindsym Shift+plus gaps inner all plus 5 + bindsym Shift+minus gaps inner all minus 5 + bindsym Shift+0 gaps inner all set 0 + bindsym Shift+d gaps inner all set 10 + + bindsym Return mode "default" + bindsym Escape mode "default" +} +mode "$mode_gaps_outer" { + bindsym plus gaps outer current plus 5 + bindsym minus gaps outer current minus 5 + bindsym 0 gaps outer current set 0 + bindsym d gaps outer current set 0 + + bindsym Shift+plus gaps outer all plus 5 + bindsym Shift+minus gaps outer all minus 5 + bindsym Shift+0 gaps outer all set 0 + bindsym Shift+d gaps outer all set 0 + + bindsym Return mode "default" + bindsym Escape mode "default" +} + + + + +#exec --no-startup-id redshift-gtk + +#exec --no-startup-id redshift-gtk +#exec feh --bg-scale /home/jonathan/Pictures/Wallpapers/blueConky/ram_memory_chip-wallpaper-3554x1999.jpg +exec --no-startup-id compton -f -i 0.95 +exec_always --no-startup-id /usr/lib/kdeconnectd +exec_always --no-startup-id indicator-kdeconnect +#exec --no-startup-id nm-applet +#exec --no-startup-id blueman-applet +exec --no-startup-id xfce4-clipman +#exec --no-startup-id xfce4-power-manager +#exec_always --no-startup-id killall conky +#exec_always --no-startup-id sleep 1s; killall -9 conky +exec --no-startup-id xrandr --output HDMI-1 --auto --left-of DP-1 +exec_always --no-startup-id /usr/lib/xfce4/notifyd/xfce4-notifyd +exec --no-startup-id sh ~/.fehbg +exec_always --no-startup-id sh "/home/jonathan/.config/conky/conky-startup.sh" +#exec --no-startup-id conky -c "/home/jonathan/.config/conky/BibleVerse/bibleGateway" +#exec --no-startup-id conky -c "/home/jonathan/.config/conky/MyBlue/MyBlue" +exec --no-startup-id albert diff --git a/config/i3/fadeLockScreen b/config/i3/fadeLockScreen new file mode 100755 index 00000000..98c96d7b --- /dev/null +++ b/config/i3/fadeLockScreen @@ -0,0 +1,36 @@ +#!/bin/bash + +scrot -z /tmp/screen.png +convert /tmp/screen.png -scale 10% -scale 1000% /tmp/screen.png + +if [[ -f $HOME/.config/screen-lock.png ]] +then + # placement x/y + PX=0 + PY=0 + # lockscreen image info + R=$(file ~/.config/screen-lock.png | grep -o '[0-9]* x [0-9]*') + RX=$(echo $R | cut -d' ' -f 1) + RY=$(echo $R | cut -d' ' -f 3) + + + + SR=$(xrandr --query | grep ' connected' | cut -f4 -d' ') + echo $SR + for RES in $SR + do + echo $RES + # monitor position/offset + SRX=$(echo $RES | cut -d'x' -f 1) # x pos + SRY=$(echo $RES | cut -d'x' -f 2 | cut -d'+' -f 1) # y pos + SROX=$(echo $RES | cut -d'x' -f 2 | cut -d'+' -f 2) # x offset + SROY=$(echo $RES | cut -d'x' -f 2 | cut -d'+' -f 3) # y offset + PX=$(($SROX + $SRX/2 - $RX/2)) + PY=$(($SROY + $SRY/2 - $RY/2)) + convert /tmp/screen.png $HOME/.config/screen-lock.png -geometry +$PX+$PY -composite -matte /tmp/screen.png + echo "done" + done +fi +# dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Stop +# i3lock -I 10 -d -e -u -n -i /tmp/screen.png +i3lock -e -n -i /tmp/screen.png diff --git a/config/i3/i3exit b/config/i3/i3exit new file mode 100755 index 00000000..40556178 --- /dev/null +++ b/config/i3/i3exit @@ -0,0 +1,31 @@ +#!/bin/sh +lock() { + ~/.config/i3/fadeLockScreen + #i3lock +} + +case "$1" in + lock) + lock + ;; + logout) + i3-msg exit + ;; + suspend) + systemctl suspend && lock + ;; + hibernate) + systemctl hibernate && lock + ;; + reboot) + systemctl reboot + ;; + shutdown) + systemctl poweroff + ;; + *) + echo "Usage: $0 {lock|logout|suspend|hibernate|reboot|shutdown}" + exit 2 +esac + +exit 0 diff --git a/config/inkscape/preferences.xml b/config/inkscape/preferences.xml new file mode 100644 index 00000000..b0d3b118 --- /dev/null +++ b/config/inkscape/preferences.xml @@ -0,0 +1,1351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/powerline-shell/CHANGELOG.md b/config/powerline-shell/CHANGELOG.md new file mode 100644 index 00000000..2a1cef31 --- /dev/null +++ b/config/powerline-shell/CHANGELOG.md @@ -0,0 +1,86 @@ +# Changes + +2016-04-16 + +* Fix issue around unicode function for python 3 + +2016-04-01 + +* Refactor of the way the git segment manages data about git's state. + ([@b-ryan](https://github.com/milkbikis/powerline-shell/pull/221)) + +2015-12-26 + +* Beginnings of unit testing for segments. Included in this change was a + refactor of the way segments are added to powerline. Now, instead of looking + for a global `powerline` object, `powerline` is passed into the function to + add the segment. Segments will also no longer add the segments by calling the + `add` function themselves. + ([@b-ryan](https://github.com/milkbikis/powerline-shell/pull/212)) +* Python3 fixes for `lib/color_compliment.py`. + ([@ceholden](https://github.com/milkbikis/powerline-shell/pull/220)) + +2015-11-25 + +* `virtual_env` segment now supports environments made with `conda` + ([@ceholden](https://github.com/milkbikis/powerline-shell/pull/198)) + +2015-11-21 + +* Fixes for Python 3 compatibility + ([@b-ryan](https://github.com/milkbikis/powerline-shell/pull/211)) + +2015-11-18 + +* The git segment has gotten a makeover + ([@MartinWetterwald](https://github.com/milkbikis/powerline-shell/pull/136)) +* Fix git segment when git is not on the standard PATH + ([@andrejgl](https://github.com/milkbikis/powerline-shell/pull/153)) +* Fix `--cwd-max-depth` showing duplicates when it's <= 2 + ([@b-ryan](https://github.com/milkbikis/powerline-shell/pull/209)) +* Add padding around `exit_code` segment + ([@phatblat](https://github.com/milkbikis/powerline-shell/pull/205)) + +2015-10-02 + +* New option (`--cwd-max-dir-size`) which allows you to limit each directory + that is displayed to a number of characters. This currently does not apply + if you are using `--cwd-mode plain`. + ([@mart-e](https://github.com/milkbikis/powerline-shell/pull/127)) + +2015-08-26 + +* New `plain` mode of displaying the current working directory which can be + used by adding `--cwd-only plain` to `powerline-shell.py`. + This deprecates the `--cwd-only` option. `--cwd-mode dironly` can be used + instead. ([@paol](https://github.com/milkbikis/powerline-shell/pull/156)) + +2015-08-18 + +* New `time` segment + ([@filipebarros](https://github.com/milkbikis/powerline-shell/pull/107)) + +2015-08-01 + +* Use `print` function for some python3 compatibility + ([@strycore](https://github.com/milkbikis/powerline-shell/pull/195)) + +2015-07-31 + +* The current working directory no longer follows symbolic links +* New `exit_code` segment + ([@disruptek](https://github.com/milkbikis/powerline-shell/pull/129)) + +2015-07-30 + +* Fix ZSH root indicator + ([@nkcfan](https://github.com/milkbikis/powerline-shell/pull/150)) +* Add uptime segment + ([@marcioAlmada](https://github.com/milkbikis/powerline-shell/pull/139)) + +2015-07-27 + +* Use `python2` instead of `python` in hashbangs + ([@Undeterminant](https://github.com/milkbikis/powerline-shell/pull/100)) +* Add `node_version` segment + ([@mmilleruva](https://github.com/milkbikis/powerline-shell/pull/189)) diff --git a/config/powerline-shell/LICENSE b/config/powerline-shell/LICENSE new file mode 100644 index 00000000..271cb592 --- /dev/null +++ b/config/powerline-shell/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Shrey Banga and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/config/powerline-shell/README.md b/config/powerline-shell/README.md new file mode 100644 index 00000000..1bcec178 --- /dev/null +++ b/config/powerline-shell/README.md @@ -0,0 +1,170 @@ +A Powerline style prompt for your shell +======================================= + +A [Powerline](https://github.com/Lokaltog/vim-powerline) like prompt for Bash, ZSH and Fish: + +![MacVim+Solarized+Powerline+CtrlP](https://raw.github.com/milkbikis/dotfiles-mac/master/bash-powerline-screenshot.png) + +* Shows some important details about the git/svn/hg/fossil branch (see below) +* Changes color if the last command exited with a failure code +* If you're too deep into a directory tree, shortens the displayed path with an ellipsis +* Shows the current Python [virtualenv](http://www.virtualenv.org/) environment +* It's easy to customize and extend. See below for details. + +### Version Control + +All of the version control systems supported by powerline shell give you a +quick look into the state of your repo: + +* The current branch is displayed and changes background color when the + branch is dirty. +* When the local branch differs from the remote, the difference in number + of commits is shown along with `⇡` or `⇣` indicating whether a git push + or pull is pending + +In addition, git has a few extra symbols: + +* `✎` -- a file has been modified, but not staged for commit +* `✔` -- a file is staged for commit +* `✼` -- a file has conflicts + +FIXME + * A `+` appears when untracked files are present (except for git, which + uses `?` instead) + +Each of these will have a number next to it if more than one file matches. + +# Setup + +This script uses ANSI color codes to display colors in a terminal. These are +notoriously non-portable, so may not work for you out of the box, but try +setting your $TERM to `xterm-256color`, because that works for me. + +* Patch the font you use for your terminal: see https://github.com/Lokaltog/powerline-fonts + + * If you struggle too much to get working fonts in your terminal, you can use "compatible" mode. + * If you're using old patched fonts, you have to use the older symbols. Basically reverse [this commit](https://github.com/milkbikis/powerline-shell/commit/2a84ecc) in your copy + +* Clone this repository somewhere: + + git clone https://github.com/milkbikis/powerline-shell + +* Copy `config.py.dist` to `config.py` and edit it to configure the segments you want. Then run + + ./install.py + + * This will generate `powerline-shell.py` + +* (optional) Create a symlink to this python script in your home: + + ln -s ~/powerline-shell.py + + * If you don't want the symlink, just modify the path in the commands below + +* For python2.6 you have to install argparse + + pip install argparse + +### All Shells: +There are a few optional arguments which can be seen by running `powerline-shell.py --help`. + +``` + --cwd-mode {fancy,plain,dironly} + How to display the current directory + --cwd-max-depth CWD_MAX_DEPTH + Maximum number of directories to show in path + --cwd-max-dir-size CWD_MAX_DIR_SIZE + Maximum number of letters displayed for each directory + in the path + --colorize-hostname Colorize the hostname based on a hash of itself. + --mode {patched,compatible,flat} + The characters used to make separators between + segments +``` + +### Bash: +Add the following to your `.bashrc` (or `.profile` on Mac): + +``` +function _update_ps1() { + PS1="$(~/powerline-shell.py $? 2> /dev/null)" +} + +if [ "$TERM" != "linux" ]; then + PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND" +fi +``` + +### ZSH: +Add the following to your `.zshrc`: + +``` +function powerline_precmd() { + PS1="$(~/powerline-shell.py $? --shell zsh 2> /dev/null)" +} + +function install_powerline_precmd() { + for s in "${precmd_functions[@]}"; do + if [ "$s" = "powerline_precmd" ]; then + return + fi + done + precmd_functions+=(powerline_precmd) +} + +if [ "$TERM" != "linux" ]; then + install_powerline_precmd +fi +``` + +### Fish: +Redefine `fish_prompt` in ~/.config/fish/config.fish: + +``` +function fish_prompt + ~/powerline-shell.py $status --shell bare ^/dev/null +end +``` + +# Customization + +### Adding, Removing and Re-arranging segments + +The `config.py` file defines which segments are drawn and in which order. Simply +comment out and rearrange segment names to get your desired arrangement. Every +time you change `config.py`, run `install.py`, which will generate a new +`powerline-shell.py` customized to your configuration. You should see the new +prompt immediately. + +### Contributing new types of segments + +The `segments` directory contains python scripts which are injected as is into +a single file `powerline_shell_base.py`. Each segment script defines a function +that inserts one or more segments into the prompt. If you want to add a new +segment, simply create a new file in the segments directory and add its name to +the `config.py` file at the appropriate location. + +Make sure that your script does not introduce new globals which might conflict +with other scripts. Your script should fail silently and run quickly in any +scenario. + +Make sure you introduce new default colors in `themes/default.py` for every new +segment you create. Test your segment with this theme first. + +You should add tests for your segment as best you are able. Unit and +integration tests are both welcome. Run your tests with the `nosetests` command +after install the requirements in `dev_requirements.txt`. + +### Themes + +The `themes` directory stores themes for your prompt, which are basically color +values used by segments. The `default.py` defines a default theme which can be +used standalone, and every other theme falls back to it if they miss colors for +any segments. Create new themes by copying any other existing theme and +changing the values. To use a theme, set the `THEME` variable in `config.py` to +the name of your theme. + +A script for testing color combinations is provided at `themes/colortest.py`. +Note that the colors you see may vary depending on your terminal. When designing +a theme, please test your theme on multiple terminals, especially with default +settings. diff --git a/config/powerline-shell/bob b/config/powerline-shell/bob new file mode 100644 index 00000000..e69de29b diff --git a/config/powerline-shell/circle.yml b/config/powerline-shell/circle.yml new file mode 100644 index 00000000..7638a893 --- /dev/null +++ b/config/powerline-shell/circle.yml @@ -0,0 +1,5 @@ +dependencies: + pre: + - sudo pip install -r dev_requirements.txt + - git config --global user.email "tester@example.com" + - git config --global user.name "Tester McGee" diff --git a/config/powerline-shell/config.py b/config/powerline-shell/config.py new file mode 100644 index 00000000..0f04c74a --- /dev/null +++ b/config/powerline-shell/config.py @@ -0,0 +1,57 @@ +# This is the configuration file for your powerline-shell prompt +# Every time you make a change to this file, run install.py to apply changes +# +# For instructions on how to use the powerline-shell.py script, see the README + +# Add, remove or rearrange these segments to customize what you see on the shell +# prompt. Any segment you add must be present in the segments/ directory + +SEGMENTS = [ +# Set the terminal window title to user@host:dir + 'set_term_title', + +# Show current virtual environment (see http://www.virtualenv.org/) + 'virtual_env', + +# Show the current user's username as in ordinary prompts + 'username', + +# Show the machine's hostname. Mostly used when ssh-ing into other machines +# 'hostname', + +# Show a padlock when ssh-ing from another machine + 'ssh', + +# Show the current directory. If the path is too long, the middle part is +# replaced with ellipsis ('...') + 'cwd', + +# Show a padlock if the current user has no write access to the current +# directory + 'read_only', + +# Show the current git branch and status + 'git', + +# Show the current mercurial branch and status + 'hg', + +# Show the current svn branch and status + 'svn', + +# Show the current fossil branch and status + 'fossil', + +# Show number of running jobs + 'jobs', + +# Show the last command's exit code if it was non-zero +# 'exit_code', + +# Shows a '#' if the current user is root, '$' otherwise +# Also, changes color if the last command exited with a non-zero error code + 'root', +] + +# Change the colors used to draw individual segments in your prompt +THEME = 'default' diff --git a/config/powerline-shell/config.py.dist b/config/powerline-shell/config.py.dist new file mode 100644 index 00000000..a1e76272 --- /dev/null +++ b/config/powerline-shell/config.py.dist @@ -0,0 +1,57 @@ +# This is the configuration file for your powerline-shell prompt +# Every time you make a change to this file, run install.py to apply changes +# +# For instructions on how to use the powerline-shell.py script, see the README + +# Add, remove or rearrange these segments to customize what you see on the shell +# prompt. Any segment you add must be present in the segments/ directory + +SEGMENTS = [ +# Set the terminal window title to user@host:dir +# 'set_term_title', + +# Show current virtual environment (see http://www.virtualenv.org/) + 'virtual_env', + +# Show the current user's username as in ordinary prompts + 'username', + +# Show the machine's hostname. Mostly used when ssh-ing into other machines + 'hostname', + +# Show a padlock when ssh-ing from another machine + 'ssh', + +# Show the current directory. If the path is too long, the middle part is +# replaced with ellipsis ('...') + 'cwd', + +# Show a padlock if the current user has no write access to the current +# directory + 'read_only', + +# Show the current git branch and status + 'git', + +# Show the current mercurial branch and status + 'hg', + +# Show the current svn branch and status + 'svn', + +# Show the current fossil branch and status + 'fossil', + +# Show number of running jobs + 'jobs', + +# Show the last command's exit code if it was non-zero +# 'exit_code', + +# Shows a '#' if the current user is root, '$' otherwise +# Also, changes color if the last command exited with a non-zero error code + 'root', +] + +# Change the colors used to draw individual segments in your prompt +THEME = 'default' diff --git a/config/powerline-shell/dev_requirements.txt b/config/powerline-shell/dev_requirements.txt new file mode 100644 index 00000000..47a4588d --- /dev/null +++ b/config/powerline-shell/dev_requirements.txt @@ -0,0 +1,3 @@ +nose>=1.3.7 +mock>=1.3.0 +sh>=1.11 diff --git a/config/powerline-shell/install.py b/config/powerline-shell/install.py new file mode 100755 index 00000000..bf36f41e --- /dev/null +++ b/config/powerline-shell/install.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +from __future__ import print_function +import os +import stat + +try: + import config +except ImportError: + print('Created personal config.py for your customizations') + import shutil + shutil.copyfile('config.py.dist', 'config.py') + import config + +TEMPLATE_FILE = 'powerline_shell_base.py' +OUTPUT_FILE = 'powerline-shell.py' +SEGMENTS_DIR = 'segments' +THEMES_DIR = 'themes' + +def load_source(srcfile): + try: + return ''.join(open(srcfile).readlines()) + '\n\n' + except IOError: + print('Could not open', srcfile) + return '' + +if __name__ == "__main__": + source = load_source(TEMPLATE_FILE) + source += load_source(os.path.join(THEMES_DIR, 'default.py')) + + if config.THEME != 'default': + source += load_source(os.path.join(THEMES_DIR, config.THEME + '.py')) + + for segment in config.SEGMENTS: + source += load_source(os.path.join(SEGMENTS_DIR, segment + '.py')) + + # assumes each segment file will have a function called + # add_segment__[segment] that accepts the powerline object + source += 'add_{}_segment(powerline)\n'.format(segment) + + source += 'sys.stdout.write(powerline.draw())\n' + + try: + open(OUTPUT_FILE, 'w').write(source) + st = os.stat(OUTPUT_FILE) + os.chmod(OUTPUT_FILE, st.st_mode | stat.S_IEXEC) + print(OUTPUT_FILE, 'saved successfully') + except IOError: + print('ERROR: Could not write to powerline-shell.py. Make sure it is writable') + exit(1) diff --git a/config/powerline-shell/powerline-shell.py b/config/powerline-shell/powerline-shell.py new file mode 100755 index 00000000..64b7f2b6 --- /dev/null +++ b/config/powerline-shell/powerline-shell.py @@ -0,0 +1,704 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function + +import argparse +import os +import sys + +py3 = sys.version_info.major == 3 + + +def warn(msg): + print('[powerline-bash] ', msg) + + +if py3: + def unicode(x): + return x + + +class Powerline: + symbols = { + 'compatible': { + 'lock': 'RO', + 'network': 'SSH', + 'separator': u'\u25B6', + 'separator_thin': u'\u276F' + }, + 'patched': { + 'lock': u'\uE0A2', + 'network': u'\uE0A2', + 'separator': u'\uE0B0', + 'separator_thin': u'\uE0B1' + }, + 'flat': { + 'lock': '', + 'network': '', + 'separator': '', + 'separator_thin': '' + }, + } + + color_templates = { + 'bash': '\\[\\e%s\\]', + 'zsh': '%%{%s%%}', + 'bare': '%s', + } + + def __init__(self, args, cwd): + self.args = args + self.cwd = cwd + mode, shell = args.mode, args.shell + self.color_template = self.color_templates[shell] + self.reset = self.color_template % '[0m' + self.lock = Powerline.symbols[mode]['lock'] + self.network = Powerline.symbols[mode]['network'] + self.separator = Powerline.symbols[mode]['separator'] + self.separator_thin = Powerline.symbols[mode]['separator_thin'] + self.segments = [] + + def color(self, prefix, code): + if code is None: + return '' + else: + return self.color_template % ('[%s;5;%sm' % (prefix, code)) + + def fgcolor(self, code): + return self.color('38', code) + + def bgcolor(self, code): + return self.color('48', code) + + def append(self, content, fg, bg, separator=None, separator_fg=None): + self.segments.append((content, fg, bg, + separator if separator is not None else self.separator, + separator_fg if separator_fg is not None else bg)) + + def draw(self): + text = (''.join(self.draw_segment(i) for i in range(len(self.segments))) + + self.reset) + ' ' + if py3: + return text + else: + return text.encode('utf-8') + + def draw_segment(self, idx): + segment = self.segments[idx] + next_segment = self.segments[idx + 1] if idx < len(self.segments)-1 else None + + return ''.join(( + self.fgcolor(segment[1]), + self.bgcolor(segment[2]), + segment[0], + self.bgcolor(next_segment[2]) if next_segment else self.reset, + self.fgcolor(segment[4]), + segment[3])) + + +class RepoStats: + symbols = { + 'detached': u'\u2693', + 'ahead': u'\u2B06', + 'behind': u'\u2B07', + 'staged': u'\u2714', + 'not_staged': u'\u270E', + 'untracked': u'\u003F', + 'conflicted': u'\u273C' + } + + def __init__(self): + self.ahead = 0 + self.behind = 0 + self.untracked = 0 + self.not_staged = 0 + self.staged = 0 + self.conflicted = 0 + + @property + def dirty(self): + qualifiers = [ + self.untracked, + self.not_staged, + self.staged, + self.conflicted, + ] + return sum(qualifiers) > 0 + + def __getitem__(self, _key): + return getattr(self, _key) + + def n_or_empty(self, _key): + """Given a string name of one of the properties of this class, returns + the value of the property as a string when the value is greater than + 1. When it is not greater than one, returns an empty string. + + As an example, if you want to show an icon for untracked files, but you + only want a number to appear next to the icon when there are more than + one untracked files, you can do: + + segment = repo_stats.n_or_empty("untracked") + icon_string + """ + return unicode(self[_key]) if int(self[_key]) > 1 else u'' + + def add_to_powerline(self, powerline, color): + def add(_key, fg, bg): + if self[_key]: + s = u" {}{} ".format(self.n_or_empty(_key), self.symbols[_key]) + powerline.append(s, fg, bg) + add('ahead', color.GIT_AHEAD_FG, color.GIT_AHEAD_BG) + add('behind', color.GIT_BEHIND_FG, color.GIT_BEHIND_BG) + add('staged', color.GIT_STAGED_FG, color.GIT_STAGED_BG) + add('not_staged', color.GIT_NOTSTAGED_FG, color.GIT_NOTSTAGED_BG) + add('untracked', color.GIT_UNTRACKED_FG, color.GIT_UNTRACKED_BG) + add('conflicted', color.GIT_CONFLICTED_FG, color.GIT_CONFLICTED_BG) + + +def get_valid_cwd(): + """ We check if the current working directory is valid or not. Typically + happens when you checkout a different branch on git that doesn't have + this directory. + We return the original cwd because the shell still considers that to be + the working directory, so returning our guess will confuse people + """ + # Prefer the PWD environment variable. Python's os.getcwd function follows + # symbolic links, which is undesirable. But if PWD is not set then fall + # back to this func + try: + cwd = os.getenv('PWD') or os.getcwd() + except: + warn("Your current directory is invalid. If you open a ticket at " + + "https://github.com/milkbikis/powerline-shell/issues/new " + + "we would love to help fix the issue.") + sys.stdout.write("> ") + sys.exit(1) + + parts = cwd.split(os.sep) + up = cwd + while parts and not os.path.exists(up): + parts.pop() + up = os.sep.join(parts) + if cwd != up: + warn("Your current directory is invalid. Lowest valid directory: " + + up) + return cwd + + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--cwd-mode', action='store', + help='How to display the current directory', default='fancy', + choices=['fancy', 'plain', 'dironly']) + arg_parser.add_argument('--cwd-only', action='store_true', + help='Deprecated. Use --cwd-mode=dironly') + arg_parser.add_argument('--cwd-max-depth', action='store', type=int, + default=5, help='Maximum number of directories to show in path') + arg_parser.add_argument('--cwd-max-dir-size', action='store', type=int, + help='Maximum number of letters displayed for each directory in the path') + arg_parser.add_argument('--colorize-hostname', action='store_true', + help='Colorize the hostname based on a hash of itself.') + arg_parser.add_argument('--mode', action='store', default='patched', + help='The characters used to make separators between segments', + choices=['patched', 'compatible', 'flat']) + arg_parser.add_argument('--shell', action='store', default='bash', + help='Set this to your shell type', choices=['bash', 'zsh', 'bare']) + arg_parser.add_argument('prev_error', nargs='?', type=int, default=0, + help='Error code returned by the last command') + args = arg_parser.parse_args() + + powerline = Powerline(args, get_valid_cwd()) + + +class DefaultColor: + """ + This class should have the default colors for every segment. + Please test every new segment with this theme first. + """ + USERNAME_FG = 250 + USERNAME_BG = 240 + USERNAME_ROOT_BG = 124 + + HOSTNAME_FG = 250 + HOSTNAME_BG = 238 + + HOME_SPECIAL_DISPLAY = True + HOME_BG = 31 # blueish + HOME_FG = 15 # white + PATH_BG = 237 # dark grey + PATH_FG = 250 # light grey + CWD_FG = 254 # nearly-white grey + SEPARATOR_FG = 244 + + READONLY_BG = 124 + READONLY_FG = 254 + + SSH_BG = 166 # medium orange + SSH_FG = 254 + + REPO_CLEAN_BG = 148 # a light green color + REPO_CLEAN_FG = 0 # black + REPO_DIRTY_BG = 161 # pink/red + REPO_DIRTY_FG = 15 # white + + JOBS_FG = 39 + JOBS_BG = 238 + + CMD_PASSED_BG = 236 + CMD_PASSED_FG = 15 + CMD_FAILED_BG = 161 + CMD_FAILED_FG = 15 + + SVN_CHANGES_BG = 148 + SVN_CHANGES_FG = 22 # dark green + + GIT_AHEAD_BG = 240 + GIT_AHEAD_FG = 250 + GIT_BEHIND_BG = 240 + GIT_BEHIND_FG = 250 + GIT_STAGED_BG = 22 + GIT_STAGED_FG = 15 + GIT_NOTSTAGED_BG = 130 + GIT_NOTSTAGED_FG = 15 + GIT_UNTRACKED_BG = 52 + GIT_UNTRACKED_FG = 15 + GIT_CONFLICTED_BG = 9 + GIT_CONFLICTED_FG = 15 + + VIRTUAL_ENV_BG = 35 # a mid-tone green + VIRTUAL_ENV_FG = 00 + +class Color(DefaultColor): + """ + This subclass is required when the user chooses to use 'default' theme. + Because the segments require a 'Color' class for every theme. + """ + pass + + +def add_set_term_title_segment(powerline): + term = os.getenv('TERM') + if not (('xterm' in term) or ('rxvt' in term)): + return + + if powerline.args.shell == 'bash': + set_title = '\\[\\e]0;\\u@\\h: \\w\\a\\]' + elif powerline.args.shell == 'zsh': + set_title = '\033]0;%n@%m: %~\007' + else: + import socket + set_title = '\033]0;%s@%s: %s\007' % (os.getenv('USER'), socket.gethostname().split('.')[0], powerline.cwd or os.getenv('PWD')) + + powerline.append(set_title, None, None, '') + + + +add_set_term_title_segment(powerline) +import os + +def add_virtual_env_segment(powerline): + env = os.getenv('VIRTUAL_ENV') or os.getenv('CONDA_ENV_PATH') + if env is None: + return + + env_name = os.path.basename(env) + bg = Color.VIRTUAL_ENV_BG + fg = Color.VIRTUAL_ENV_FG + powerline.append(' %s ' % env_name, fg, bg) + + +add_virtual_env_segment(powerline) + +def add_username_segment(powerline): + import os + if powerline.args.shell == 'bash': + user_prompt = ' \\u ' + elif powerline.args.shell == 'zsh': + user_prompt = ' %n ' + else: + user_prompt = ' %s ' % os.getenv('USER') + + if os.getenv('USER') == 'root': + bgcolor = Color.USERNAME_ROOT_BG + else: + bgcolor = Color.USERNAME_BG + + powerline.append(user_prompt, Color.USERNAME_FG, bgcolor) + + +add_username_segment(powerline) +import os + +def add_ssh_segment(powerline): + + if os.getenv('SSH_CLIENT'): + powerline.append(' %s ' % powerline.network, Color.SSH_FG, Color.SSH_BG) + + +add_ssh_segment(powerline) +import os + +ELLIPSIS = u'\u2026' + + +def replace_home_dir(cwd): + home = os.getenv('HOME') + if cwd.startswith(home): + return '~' + cwd[len(home):] + return cwd + + +def split_path_into_names(cwd): + names = cwd.split(os.sep) + + if names[0] == '': + names = names[1:] + + if not names[0]: + return ['/'] + + return names + + +def requires_special_home_display(name): + """Returns true if the given directory name matches the home indicator and + the chosen theme should use a special home indicator display.""" + return (name == '~' and Color.HOME_SPECIAL_DISPLAY) + + +def maybe_shorten_name(powerline, name): + """If the user has asked for each directory name to be shortened, will + return the name up to their specified length. Otherwise returns the full + name.""" + if powerline.args.cwd_max_dir_size: + return name[:powerline.args.cwd_max_dir_size] + return name + + +def get_fg_bg(name): + """Returns the foreground and background color to use for the given name. + """ + if requires_special_home_display(name): + return (Color.HOME_FG, Color.HOME_BG,) + return (Color.PATH_FG, Color.PATH_BG,) + + +def add_cwd_segment(powerline): + cwd = powerline.cwd or os.getenv('PWD') + if not py3: + cwd = cwd.decode("utf-8") + cwd = replace_home_dir(cwd) + + if powerline.args.cwd_mode == 'plain': + powerline.append(' %s ' % (cwd,), Color.CWD_FG, Color.PATH_BG) + return + + names = split_path_into_names(cwd) + + max_depth = powerline.args.cwd_max_depth + if max_depth <= 0: + warn("Ignoring --cwd-max-depth argument since it's not greater than 0") + elif len(names) > max_depth: + # https://github.com/milkbikis/powerline-shell/issues/148 + # n_before is the number is the number of directories to put before the + # ellipsis. So if you are at ~/a/b/c/d/e and max depth is 4, it will + # show `~ a ... d e`. + # + # max_depth must be greater than n_before or else you end up repeating + # parts of the path with the way the splicing is written below. + n_before = 2 if max_depth > 2 else max_depth - 1 + names = names[:n_before] + [ELLIPSIS] + names[n_before - max_depth:] + + if (powerline.args.cwd_mode == 'dironly' or powerline.args.cwd_only): + # The user has indicated they only want the current directory to be + # displayed, so chop everything else off + names = names[-1:] + + for i, name in enumerate(names): + fg, bg = get_fg_bg(name) + + separator = powerline.separator_thin + separator_fg = Color.SEPARATOR_FG + is_last_dir = (i == len(names) - 1) + if requires_special_home_display(name) or is_last_dir: + separator = None + separator_fg = None + + powerline.append(' %s ' % maybe_shorten_name(powerline, name), fg, bg, + separator, separator_fg) + + +add_cwd_segment(powerline) +import os + +def add_read_only_segment(powerline): + cwd = powerline.cwd or os.getenv('PWD') + + if not os.access(cwd, os.W_OK): + powerline.append(' %s ' % powerline.lock, Color.READONLY_FG, Color.READONLY_BG) + + +add_read_only_segment(powerline) +import re +import subprocess +import os + +def get_PATH(): + """Normally gets the PATH from the OS. This function exists to enable + easily mocking the PATH in tests. + """ + return os.getenv("PATH") + +def git_subprocess_env(): + return { + # LANG is specified to ensure git always uses a language we are expecting. + # Otherwise we may be unable to parse the output. + "LANG": "C", + + # https://github.com/milkbikis/powerline-shell/pull/126 + "HOME": os.getenv("HOME"), + + # https://github.com/milkbikis/powerline-shell/pull/153 + "PATH": get_PATH(), + } + + +def parse_git_branch_info(status): + info = re.search('^## (?P\S+?)''(\.{3}(?P\S+?)( \[(ahead (?P\d+)(, )?)?(behind (?P\d+))?\])?)?$', status[0]) + return info.groupdict() if info else None + + +def _get_git_detached_branch(): + p = subprocess.Popen(['git', 'describe', '--tags', '--always'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=git_subprocess_env()) + detached_ref = p.communicate()[0].decode("utf-8").rstrip('\n') + if p.returncode == 0: + branch = u'{} {}'.format(RepoStats.symbols['detached'], detached_ref) + else: + branch = 'Big Bang' + return branch + + +def parse_git_stats(status): + stats = RepoStats() + for statusline in status[1:]: + code = statusline[:2] + if code == '??': + stats.untracked += 1 + elif code in ('DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'): + stats.conflicted += 1 + else: + if code[1] != ' ': + stats.not_staged += 1 + if code[0] != ' ': + stats.staged += 1 + + return stats + + +def add_git_segment(powerline): + try: + p = subprocess.Popen(['git', 'status', '--porcelain', '-b'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=git_subprocess_env()) + except OSError: + # Popen will throw an OSError if git is not found + return + + pdata = p.communicate() + if p.returncode != 0: + return + + status = pdata[0].decode("utf-8").splitlines() + stats = parse_git_stats(status) + branch_info = parse_git_branch_info(status) + + if branch_info: + stats.ahead = branch_info["ahead"] + stats.behind = branch_info["behind"] + branch = branch_info['local'] + else: + branch = _get_git_detached_branch() + + bg = Color.REPO_CLEAN_BG + fg = Color.REPO_CLEAN_FG + if stats.dirty: + bg = Color.REPO_DIRTY_BG + fg = Color.REPO_DIRTY_FG + + powerline.append(' %s ' % branch, fg, bg) + stats.add_to_powerline(powerline, Color) + + +add_git_segment(powerline) +import os +import subprocess + +def get_hg_status(): + has_modified_files = False + has_untracked_files = False + has_missing_files = False + + p = subprocess.Popen(['hg', 'status'], stdout=subprocess.PIPE) + output = p.communicate()[0].decode("utf-8") + + for line in output.split('\n'): + if line == '': + continue + elif line[0] == '?': + has_untracked_files = True + elif line[0] == '!': + has_missing_files = True + else: + has_modified_files = True + return has_modified_files, has_untracked_files, has_missing_files + +def add_hg_segment(powerline): + branch = os.popen('hg branch 2> /dev/null').read().rstrip() + if len(branch) == 0: + return False + bg = Color.REPO_CLEAN_BG + fg = Color.REPO_CLEAN_FG + has_modified_files, has_untracked_files, has_missing_files = get_hg_status() + if has_modified_files or has_untracked_files or has_missing_files: + bg = Color.REPO_DIRTY_BG + fg = Color.REPO_DIRTY_FG + extra = '' + if has_untracked_files: + extra += '+' + if has_missing_files: + extra += '!' + branch += (' ' + extra if extra != '' else '') + return powerline.append(' %s ' % branch, fg, bg) + + +add_hg_segment(powerline) +import subprocess + + +def _add_svn_segment(powerline): + is_svn = subprocess.Popen(['svn', 'status'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + is_svn_output = is_svn.communicate()[1].decode("utf-8").strip() + if len(is_svn_output) != 0: + return + + #"svn status | grep -c "^[ACDIMRX\\!\\~]" + p1 = subprocess.Popen(['svn', 'status'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + p2 = subprocess.Popen(['grep', '-c', '^[ACDIMR\\!\\~]'], + stdin=p1.stdout, stdout=subprocess.PIPE) + output = p2.communicate()[0].decode("utf-8").strip() + if len(output) > 0 and int(output) > 0: + changes = output.strip() + powerline.append(' %s ' % changes, Color.SVN_CHANGES_FG, Color.SVN_CHANGES_BG) + + +def add_svn_segment(powerline): + """Wraps _add_svn_segment in exception handling.""" + + # FIXME This function was added when introducing a testing framework, + # during which the 'powerline' object was passed into the + # `add_[segment]_segment` functions instead of being a global variable. At + # that time it was unclear whether the below exceptions could actually be + # thrown. It would be preferable to find out whether they ever will. If so, + # write a comment explaining when. Otherwise remove. + + try: + _add_svn_segment(powerline) + except OSError: + pass + except subprocess.CalledProcessError: + pass + + +add_svn_segment(powerline) +import os +import subprocess + +def get_fossil_status(): + has_modified_files = False + has_untracked_files = False + has_missing_files = False + output = os.popen('fossil changes 2>/dev/null').read().strip() + has_untracked_files = True if os.popen("fossil extras 2>/dev/null").read().strip() else False + has_missing_files = 'MISSING' in output + has_modified_files = 'EDITED' in output + + return has_modified_files, has_untracked_files, has_missing_files + +def _add_fossil_segment(powerline): + subprocess.Popen(['fossil'], stdout=subprocess.PIPE).communicate()[0] + branch = ''.join([i.replace('*','').strip() for i in os.popen("fossil branch 2> /dev/null").read().strip().split("\n") if i.startswith('*')]) + if len(branch) == 0: + return + + bg = Color.REPO_CLEAN_BG + fg = Color.REPO_CLEAN_FG + has_modified_files, has_untracked_files, has_missing_files = get_fossil_status() + if has_modified_files or has_untracked_files or has_missing_files: + bg = Color.REPO_DIRTY_BG + fg = Color.REPO_DIRTY_FG + extra = '' + if has_untracked_files: + extra += '+' + if has_missing_files: + extra += '!' + branch += (' ' + extra if extra != '' else '') + powerline.append(' %s ' % branch, fg, bg) + +def add_fossil_segment(powerline): + """Wraps _add_fossil_segment in exception handling.""" + + # FIXME This function was added when introducing a testing framework, + # during which the 'powerline' object was passed into the + # `add_[segment]_segment` functions instead of being a global variable. At + # that time it was unclear whether the below exceptions could actually be + # thrown. It would be preferable to find out whether they ever will. If so, + # write a comment explaining when. Otherwise remove. + + try: + _add_fossil_segment(powerline) + except OSError: + pass + except subprocess.CalledProcessError: + pass + + +add_fossil_segment(powerline) +import os +import re +import subprocess + +def add_jobs_segment(powerline): + pppid_proc = subprocess.Popen(['ps', '-p', str(os.getppid()), '-oppid='], + stdout=subprocess.PIPE) + pppid = pppid_proc.communicate()[0].decode("utf-8").strip() + + output_proc = subprocess.Popen(['ps', '-a', '-o', 'ppid'], + stdout=subprocess.PIPE) + output = output_proc.communicate()[0].decode("utf-8") + + num_jobs = len(re.findall(str(pppid), output)) - 1 + + if num_jobs > 0: + powerline.append(' %d ' % num_jobs, Color.JOBS_FG, Color.JOBS_BG) + + +add_jobs_segment(powerline) +def add_root_segment(powerline): + root_indicators = { + 'bash': ' \\$ ', + 'zsh': ' %# ', + 'bare': ' $ ', + } + bg = Color.CMD_PASSED_BG + fg = Color.CMD_PASSED_FG + if powerline.args.prev_error != 0: + fg = Color.CMD_FAILED_FG + bg = Color.CMD_FAILED_BG + powerline.append(root_indicators[powerline.args.shell], fg, bg) + + +add_root_segment(powerline) +sys.stdout.write(powerline.draw()) diff --git a/config/powerline-shell/powerline_shell_base.py b/config/powerline-shell/powerline_shell_base.py new file mode 100755 index 00000000..f6f1cdd6 --- /dev/null +++ b/config/powerline-shell/powerline_shell_base.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function + +import argparse +import os +import sys + +py3 = sys.version_info.major == 3 + + +def warn(msg): + print('[powerline-bash] ', msg) + + +if py3: + def unicode(x): + return x + + +class Powerline: + symbols = { + 'compatible': { + 'lock': 'RO', + 'network': 'SSH', + 'separator': u'\u25B6', + 'separator_thin': u'\u276F' + }, + 'patched': { + 'lock': u'\uE0A2', + 'network': u'\uE0A2', + 'separator': u'\uE0B0', + 'separator_thin': u'\uE0B1' + }, + 'flat': { + 'lock': '', + 'network': '', + 'separator': '', + 'separator_thin': '' + }, + } + + color_templates = { + 'bash': '\\[\\e%s\\]', + 'zsh': '%%{%s%%}', + 'bare': '%s', + } + + def __init__(self, args, cwd): + self.args = args + self.cwd = cwd + mode, shell = args.mode, args.shell + self.color_template = self.color_templates[shell] + self.reset = self.color_template % '[0m' + self.lock = Powerline.symbols[mode]['lock'] + self.network = Powerline.symbols[mode]['network'] + self.separator = Powerline.symbols[mode]['separator'] + self.separator_thin = Powerline.symbols[mode]['separator_thin'] + self.segments = [] + + def color(self, prefix, code): + if code is None: + return '' + else: + return self.color_template % ('[%s;5;%sm' % (prefix, code)) + + def fgcolor(self, code): + return self.color('38', code) + + def bgcolor(self, code): + return self.color('48', code) + + def append(self, content, fg, bg, separator=None, separator_fg=None): + self.segments.append((content, fg, bg, + separator if separator is not None else self.separator, + separator_fg if separator_fg is not None else bg)) + + def draw(self): + text = (''.join(self.draw_segment(i) for i in range(len(self.segments))) + + self.reset) + ' ' + if py3: + return text + else: + return text.encode('utf-8') + + def draw_segment(self, idx): + segment = self.segments[idx] + next_segment = self.segments[idx + 1] if idx < len(self.segments)-1 else None + + return ''.join(( + self.fgcolor(segment[1]), + self.bgcolor(segment[2]), + segment[0], + self.bgcolor(next_segment[2]) if next_segment else self.reset, + self.fgcolor(segment[4]), + segment[3])) + + +class RepoStats: + symbols = { + 'detached': u'\u2693', + 'ahead': u'\u2B06', + 'behind': u'\u2B07', + 'staged': u'\u2714', + 'not_staged': u'\u270E', + 'untracked': u'\u003F', + 'conflicted': u'\u273C' + } + + def __init__(self): + self.ahead = 0 + self.behind = 0 + self.untracked = 0 + self.not_staged = 0 + self.staged = 0 + self.conflicted = 0 + + @property + def dirty(self): + qualifiers = [ + self.untracked, + self.not_staged, + self.staged, + self.conflicted, + ] + return sum(qualifiers) > 0 + + def __getitem__(self, _key): + return getattr(self, _key) + + def n_or_empty(self, _key): + """Given a string name of one of the properties of this class, returns + the value of the property as a string when the value is greater than + 1. When it is not greater than one, returns an empty string. + + As an example, if you want to show an icon for untracked files, but you + only want a number to appear next to the icon when there are more than + one untracked files, you can do: + + segment = repo_stats.n_or_empty("untracked") + icon_string + """ + return unicode(self[_key]) if int(self[_key]) > 1 else u'' + + def add_to_powerline(self, powerline, color): + def add(_key, fg, bg): + if self[_key]: + s = u" {}{} ".format(self.n_or_empty(_key), self.symbols[_key]) + powerline.append(s, fg, bg) + add('ahead', color.GIT_AHEAD_FG, color.GIT_AHEAD_BG) + add('behind', color.GIT_BEHIND_FG, color.GIT_BEHIND_BG) + add('staged', color.GIT_STAGED_FG, color.GIT_STAGED_BG) + add('not_staged', color.GIT_NOTSTAGED_FG, color.GIT_NOTSTAGED_BG) + add('untracked', color.GIT_UNTRACKED_FG, color.GIT_UNTRACKED_BG) + add('conflicted', color.GIT_CONFLICTED_FG, color.GIT_CONFLICTED_BG) + + +def get_valid_cwd(): + """ We check if the current working directory is valid or not. Typically + happens when you checkout a different branch on git that doesn't have + this directory. + We return the original cwd because the shell still considers that to be + the working directory, so returning our guess will confuse people + """ + # Prefer the PWD environment variable. Python's os.getcwd function follows + # symbolic links, which is undesirable. But if PWD is not set then fall + # back to this func + try: + cwd = os.getenv('PWD') or os.getcwd() + except: + warn("Your current directory is invalid. If you open a ticket at " + + "https://github.com/milkbikis/powerline-shell/issues/new " + + "we would love to help fix the issue.") + sys.stdout.write("> ") + sys.exit(1) + + parts = cwd.split(os.sep) + up = cwd + while parts and not os.path.exists(up): + parts.pop() + up = os.sep.join(parts) + if cwd != up: + warn("Your current directory is invalid. Lowest valid directory: " + + up) + return cwd + + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--cwd-mode', action='store', + help='How to display the current directory', default='fancy', + choices=['fancy', 'plain', 'dironly']) + arg_parser.add_argument('--cwd-only', action='store_true', + help='Deprecated. Use --cwd-mode=dironly') + arg_parser.add_argument('--cwd-max-depth', action='store', type=int, + default=5, help='Maximum number of directories to show in path') + arg_parser.add_argument('--cwd-max-dir-size', action='store', type=int, + help='Maximum number of letters displayed for each directory in the path') + arg_parser.add_argument('--colorize-hostname', action='store_true', + help='Colorize the hostname based on a hash of itself.') + arg_parser.add_argument('--mode', action='store', default='patched', + help='The characters used to make separators between segments', + choices=['patched', 'compatible', 'flat']) + arg_parser.add_argument('--shell', action='store', default='bash', + help='Set this to your shell type', choices=['bash', 'zsh', 'bare']) + arg_parser.add_argument('prev_error', nargs='?', type=int, default=0, + help='Error code returned by the last command') + args = arg_parser.parse_args() + + powerline = Powerline(args, get_valid_cwd()) diff --git a/config/ranger/.gitignore b/config/ranger/.gitignore new file mode 100644 index 00000000..3cc04439 --- /dev/null +++ b/config/ranger/.gitignore @@ -0,0 +1,3 @@ +history +bookmarks +tagged diff --git a/config/ranger/commands.py b/config/ranger/commands.py new file mode 100644 index 00000000..1386e84e --- /dev/null +++ b/config/ranger/commands.py @@ -0,0 +1,61 @@ +# This is a sample commands.py. You can add your own commands here. +# +# Please refer to commands_full.py for all the default commands and a complete +# documentation. Do NOT add them all here, or you may end up with defunct +# commands when upgrading ranger. + +# You always need to import ranger.api.commands here to get the Command class: +from ranger.api.commands import * + +# A simple command for demonstration purposes follows. +# ----------------------------------------------------------------------------- + +# You can import any python module as needed. +import os + +# Any class that is a subclass of "Command" will be integrated into ranger as a +# command. Try typing ":my_edit" in ranger! + + +class my_edit(Command): + # The so-called doc-string of the class will be visible in the built-in + # help that is accessible by typing "?c" inside ranger. + """:my_edit + + A sample command for demonstration purposes that opens a file in an editor. + """ + + # The execute method is called when you run this command in ranger. + def execute(self): + # self.arg(1) is the first (space-separated) argument to the function. + # This way you can write ":my_edit somefilename". + if self.arg(1): + # self.rest(1) contains self.arg(1) and everything that follows + target_filename = self.rest(1) + else: + # self.fm is a ranger.core.filemanager.FileManager object and gives + # you access to internals of ranger. + # self.fm.thisfile is a ranger.container.file.File object and is a + # reference to the currently selected file. + target_filename = self.fm.thisfile.path + + # This is a generic function to print text in ranger. + self.fm.notify("Let's edit the file " + target_filename + "!") + + # Using bad=True in fm.notify allows you to print error messages: + if not os.path.exists(target_filename): + self.fm.notify("The given file does not exist!", bad=True) + return + + # This executes a function from ranger.core.acitons, a module with a + # variety of subroutines that can help you construct commands. + # Check out the source, or run "pydoc ranger.core.actions" for a list. + self.fm.edit_file(target_filename) + + # The tab method is called when you press tab, and should return a list of + # suggestions that the user will tab through. + # tabnum is 1 for and -1 for by default + def tab(self, tabnum): + # This is a generic tab-completion function that iterates through the + # content of the current directory. + return self._tab_directory_content() diff --git a/config/ranger/commands_full.py b/config/ranger/commands_full.py new file mode 100644 index 00000000..a384f427 --- /dev/null +++ b/config/ranger/commands_full.py @@ -0,0 +1,1486 @@ +# -*- coding: utf-8 -*- +# This file is part of ranger, the console file manager. +# This configuration file is licensed under the same terms as ranger. +# =================================================================== +# +# NOTE: If you copied this file to ~/.config/ranger/commands_full.py, +# then it will NOT be loaded by ranger, and only serve as a reference. +# +# =================================================================== +# This file contains ranger's commands. +# It's all in python; lines beginning with # are comments. +# +# Note that additional commands are automatically generated from the methods +# of the class ranger.core.actions.Actions. +# +# You can customize commands in the file ~/.config/ranger/commands.py. +# It has the same syntax as this file. In fact, you can just copy this +# file there with `ranger --copy-config=commands' and make your modifications. +# But make sure you update your configs when you update ranger. +# +# =================================================================== +# Every class defined here which is a subclass of `Command' will be used as a +# command in ranger. Several methods are defined to interface with ranger: +# execute(): called when the command is executed. +# cancel(): called when closing the console. +# tab(tabnum): called when is pressed. +# quick(): called after each keypress. +# +# tab() argument tabnum is 1 for and -1 for by default +# +# The return values for tab() can be either: +# None: There is no tab completion +# A string: Change the console to this string +# A list/tuple/generator: cycle through every item in it +# +# The return value for quick() can be: +# False: Nothing happens +# True: Execute the command afterwards +# +# The return value for execute() and cancel() doesn't matter. +# +# =================================================================== +# Commands have certain attributes and methods that facilitate parsing of +# the arguments: +# +# self.line: The whole line that was written in the console. +# self.args: A list of all (space-separated) arguments to the command. +# self.quantifier: If this command was mapped to the key "X" and +# the user pressed 6X, self.quantifier will be 6. +# self.arg(n): The n-th argument, or an empty string if it doesn't exist. +# self.rest(n): The n-th argument plus everything that followed. For example, +# if the command was "search foo bar a b c", rest(2) will be "bar a b c" +# self.start(n): Anything before the n-th argument. For example, if the +# command was "search foo bar a b c", start(2) will be "search foo" +# +# =================================================================== +# And this is a little reference for common ranger functions and objects: +# +# self.fm: A reference to the "fm" object which contains most information +# about ranger. +# self.fm.notify(string): Print the given string on the screen. +# self.fm.notify(string, bad=True): Print the given string in RED. +# self.fm.reload_cwd(): Reload the current working directory. +# self.fm.thisdir: The current working directory. (A File object.) +# self.fm.thisfile: The current file. (A File object too.) +# self.fm.thistab.get_selection(): A list of all selected files. +# self.fm.execute_console(string): Execute the string as a ranger command. +# self.fm.open_console(string): Open the console with the given string +# already typed in for you. +# self.fm.move(direction): Moves the cursor in the given direction, which +# can be something like down=3, up=5, right=1, left=1, to=6, ... +# +# File objects (for example self.fm.thisfile) have these useful attributes and +# methods: +# +# cf.path: The path to the file. +# cf.basename: The base name only. +# cf.load_content(): Force a loading of the directories content (which +# obviously works with directories only) +# cf.is_directory: True/False depending on whether it's a directory. +# +# For advanced commands it is unavoidable to dive a bit into the source code +# of ranger. +# =================================================================== + +from ranger.api.commands import * + + +class alias(Command): + """:alias + + Copies the oldcommand as newcommand. + """ + + context = 'browser' + resolve_macros = False + + def execute(self): + if not self.arg(1) or not self.arg(2): + self.fm.notify('Syntax: alias ', bad=True) + else: + self.fm.commands.alias(self.arg(1), self.rest(2)) + + +class echo(Command): + """:echo + + Display the text in the statusbar. + """ + def execute(self): + self.fm.notify(self.rest(1)) + + +class cd(Command): + """:cd [-r] + + The cd command changes the directory. + The command 'cd -' is equivalent to typing ``. + Using the option "-r" will get you to the real path. + """ + + def execute(self): + import os.path + if self.arg(1) == '-r': + self.shift() + destination = os.path.realpath(self.rest(1)) + if os.path.isfile(destination): + self.fm.select_file(destination) + return + else: + destination = self.rest(1) + + if not destination: + destination = '~' + + if destination == '-': + self.fm.enter_bookmark('`') + else: + self.fm.cd(destination) + + def tab(self, tabnum): + import os + from os.path import dirname, basename, expanduser, join + + cwd = self.fm.thisdir.path + rel_dest = self.rest(1) + + bookmarks = [v.path for v in self.fm.bookmarks.dct.values() + if rel_dest in v.path] + + # expand the tilde into the user directory + if rel_dest.startswith('~'): + rel_dest = expanduser(rel_dest) + + # define some shortcuts + abs_dest = join(cwd, rel_dest) + abs_dirname = dirname(abs_dest) + rel_basename = basename(rel_dest) + rel_dirname = dirname(rel_dest) + + try: + # are we at the end of a directory? + if rel_dest.endswith('/') or rel_dest == '': + _, dirnames, _ = next(os.walk(abs_dest)) + + # are we in the middle of the filename? + else: + _, dirnames, _ = next(os.walk(abs_dirname)) + dirnames = [dn for dn in dirnames + if dn.startswith(rel_basename)] + except (OSError, StopIteration): + # os.walk found nothing + pass + else: + dirnames.sort() + if self.fm.settings.cd_bookmarks: + dirnames = bookmarks + dirnames + + # no results, return None + if len(dirnames) == 0: + return + + # one result. since it must be a directory, append a slash. + if len(dirnames) == 1: + return self.start(1) + join(rel_dirname, dirnames[0]) + '/' + + # more than one result. append no slash, so the user can + # manually type in the slash to advance into that directory + return (self.start(1) + join(rel_dirname, dirname) for dirname in dirnames) + + +class chain(Command): + """:chain ; ; ... + + Calls multiple commands at once, separated by semicolons. + """ + def execute(self): + for command in [s.strip() for s in self.rest(1).split(";")]: + self.fm.execute_console(command) + + +class shell(Command): + escape_macros_for_shell = True + + def execute(self): + if self.arg(1) and self.arg(1)[0] == '-': + flags = self.arg(1)[1:] + command = self.rest(2) + else: + flags = '' + command = self.rest(1) + + if command: + self.fm.execute_command(command, flags=flags) + + def tab(self, tabnum): + from ranger.ext.get_executables import get_executables + if self.arg(1) and self.arg(1)[0] == '-': + command = self.rest(2) + else: + command = self.rest(1) + start = self.line[0:len(self.line) - len(command)] + + try: + position_of_last_space = command.rindex(" ") + except ValueError: + return (start + program + ' ' for program + in get_executables() if program.startswith(command)) + if position_of_last_space == len(command) - 1: + selection = self.fm.thistab.get_selection() + if len(selection) == 1: + return self.line + selection[0].shell_escaped_basename + ' ' + else: + return self.line + '%s ' + else: + before_word, start_of_word = self.line.rsplit(' ', 1) + return (before_word + ' ' + file.shell_escaped_basename + for file in self.fm.thisdir.files or [] + if file.shell_escaped_basename.startswith(start_of_word)) + + +class open_with(Command): + def execute(self): + app, flags, mode = self._get_app_flags_mode(self.rest(1)) + self.fm.execute_file( + files=[f for f in self.fm.thistab.get_selection()], + app=app, + flags=flags, + mode=mode) + + def tab(self, tabnum): + return self._tab_through_executables() + + def _get_app_flags_mode(self, string): + """Extracts the application, flags and mode from a string. + + examples: + "mplayer f 1" => ("mplayer", "f", 1) + "aunpack 4" => ("aunpack", "", 4) + "p" => ("", "p", 0) + "" => None + """ + + app = '' + flags = '' + mode = 0 + split = string.split() + + if len(split) == 0: + pass + + elif len(split) == 1: + part = split[0] + if self._is_app(part): + app = part + elif self._is_flags(part): + flags = part + elif self._is_mode(part): + mode = part + + elif len(split) == 2: + part0 = split[0] + part1 = split[1] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + elif self._is_mode(part1): + mode = part1 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + elif len(split) >= 3: + part0 = split[0] + part1 = split[1] + part2 = split[2] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + if self._is_mode(part2): + mode = part2 + elif self._is_mode(part1): + mode = part1 + if self._is_flags(part2): + flags = part2 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + return app, flags, int(mode) + + def _is_app(self, arg): + return not self._is_flags(arg) and not arg.isdigit() + + def _is_flags(self, arg): + from ranger.core.runner import ALLOWED_FLAGS + return all(x in ALLOWED_FLAGS for x in arg) + + def _is_mode(self, arg): + return all(x in '0123456789' for x in arg) + + +class set_(Command): + """:set