diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a8ed49 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +Toolkit Packages +================ + +This is a set of public packages for +[toolkit](https://github.com/greglook/toolkit). These packages contain +widely-used configuration (commonly known as 'dotfiles') and various utility +scripts I've written over the years. + +License +------- +This is free and unencumbered software released into the public domain. diff --git a/bash/bash_profile b/bash/bash_profile new file mode 100644 index 0000000..31e1daa --- /dev/null +++ b/bash/bash_profile @@ -0,0 +1,10 @@ +# ~/.bash_profile +# This file is sourced by bash for login shells. + +# source the system-wide bashrc +[[ -f /etc/bash/bashrc ]] && source /etc/bash/bashrc +[[ -f /etc/bashrc ]] && source /etc/bashrc + +# source the user's bashrc +[[ -f ~/.bashrc ]] && source ~/.bashrc + diff --git a/bash/bashrc b/bash/bashrc new file mode 100644 index 0000000..2dd041a --- /dev/null +++ b/bash/bashrc @@ -0,0 +1,27 @@ +# ~/.bashrc +# This file is sourced by bash for all interactive shells. + +# test for interactive shell. +[[ $- != *i* ]] && return + +# add ~/bin to $PATH +[[ -d $HOME/bin ]] && export PATH="$HOME/bin:$PATH" + +# ls with color +alias ls='ls --color=tty' + +# ignore common commands in history +export HISTIGNORE=$'[ \t]*:&:[fb]g:exit:ls' + +# make bash history play nicely with multiple terminals +shopt -s histappend + +# set command prompt +if [[ $USER == "root" ]]; then + export PS1="\[\033[01;31m\]\h \[\033[01;34m\]\W #\[\033[00m\] " +else + export PS1="\[\033[01;32m\]\u\[\033[01;34m\]@\[\033[01;31m\]\h \[\033[01;34m\]\W \$\[\033[00m\] " +fi + +# update terminal title and bash history whenever the prompt is displayed +#export PROMPT_COMMAND='echo -ne "\033]2;${USER}@${HOSTNAME}: ${PWD}\007" && history -a' diff --git a/cygwin/minttyrc b/cygwin/minttyrc new file mode 100644 index 0000000..ea7526d --- /dev/null +++ b/cygwin/minttyrc @@ -0,0 +1,10 @@ +BoldAsFont=yes +Font=Consolas +FontHeight=10 +Locale=en_US +Charset=UTF-8 +CursorType=block +Term=xterm-256color +Columns=120 +Rows=36 +CopyAsRTF=no diff --git a/gentoo/kernel-install b/gentoo/kernel-install new file mode 100755 index 0000000..7634e3b --- /dev/null +++ b/gentoo/kernel-install @@ -0,0 +1,87 @@ +#!/bin/sh + +# Ensure that the user is root. +if [[ $USER -ne "root" ]]; then + echo "Must be root to install a new kernel!" + exit 1 +fi + +# Kernel artifacts. +SRC_DIR="/usr/src/linux" +KERNEL_CONFIG=$SRC_DIR/.config +KERNEL_IMAGE=$SRC_DIR/arch/i386/boot/bzImage + +if [[ ! -f "$KERNEL_CONFIG" ]]; then + echo "Kernel has not been configured!" + exit 1 +fi + +# Parse kernel version from config file. +KERNEL_VERSION=$(head $KERNEL_CONFIG | grep -m 1 -i 'kernel' | grep -o -P '\d+\.\d+\.\d+\-\w+(\-r\d+)?') +if [[ -z $KERNEL_VERSION ]]; then + echo "Could not determine kernel version!" + exit 1 +fi + +# Build kernel. +echo "Building kernel $KERNEL_VERSION..." +cd $SRC_DIR && make + +if [[ $? != 0 || ! -f "$KERNEL_IMAGE" ]]; then + echo "Error building kernel!" + exit 1 +fi + +# Determine size of artifacts. +ARTIFACT_SIZE=$(ls -sL1 $KERNEL_CONFIG $KERNEL_IMAGE | awk '{ SIZE += $1 } END { print SIZE }') +echo "Built kernel image and config occupying $ARTIFACT_SIZE blocks" + +# Boot directory configuration. +BOOT_DIR="/boot" +BOOT_PARTITION=$(grep $BOOT_DIR /etc/fstab | awk '{ print $1 }') + +# Mount boot if needed. +if [[ -n $BOOT_PARTITION ]]; then + if [[ -z $(mount | grep $BOOT_PARTITION) ]]; then + echo "Mounting boot partition $BOOT_PARTITION..." + mount $BOOT_PARTITION + else + echo "$BOOT_PARTITION is already mounted" + fi + + # Check boot filesystem usage. + BOOT_FREE=$(df $BOOT_PARTITION | tail -n 1 | awk '{ print $4 }') + echo "Boot partition $BOOT_PARTITION has $BOOT_FREE blocks available" + if [[ $BOOT_FREE -le $ARTIFACT_SIZE ]]; then + echo "WARNING: $BOOT_PARTITION does not have enough space for kernel artifacts!" + exit 1 + fi +fi + +# Copy kernel image and config file. +echo "Copying kernel artifacts..." +cp $KERNEL_CONFIG $BOOT_DIR/config-$KERNEL_VERSION +cp $KERNEL_IMAGE $BOOT_DIR/kernel-$KERNEL_VERSION + +# Regenerate grub2 configuration. +grub2-mkconfig -o /boot/grub/grub.cfg + +# Unmount boot if needed. +if [[ -n $BOOT_PARTITION ]]; then + echo "Unmounting $BOOT_PARTITION..." + umount $BOOT_PARTITION +fi + +# Install built kernel modules. +echo "Installing modules..." +cd $SRC_DIR && make modules_install +if [[ $? != 0 ]]; then + echo "Error installing kernel modules!" + exit 1 +fi + +# Re-emerge packages with modules. +echo "Recompiling module-dependent packages..." +emerge @module-rebuild + +echo "Done installing new kernel!" diff --git a/gentoo/kernel-modules b/gentoo/kernel-modules new file mode 100755 index 0000000..fd88eca --- /dev/null +++ b/gentoo/kernel-modules @@ -0,0 +1,6 @@ +#!/bin/sh + +# use current kernel version if none provided +KERNEL=${1:-$(uname -r)} + +find /lib/modules/$KERNEL/ -type f -iname '*.o' -or -iname '*.ko' | ruby -lne 'puts $1 if /^(?:\/[^\/]+){3}\/(.+)\.k?o$/' | sort diff --git a/gentoo/stage4-backup.sh b/gentoo/stage4-backup.sh new file mode 100755 index 0000000..aabbbc8 --- /dev/null +++ b/gentoo/stage4-backup.sh @@ -0,0 +1,387 @@ +#!/bin/bash + +# Backup script for Gentoo Linux +# Copyright Reto Glauser aka Blinkeye +# Distributed under the terms of the GNU General Public License v2 +# Mailto: stage4 at blinkeye dot ch +# Forum post: http://forums.gentoo.org/viewtopic-t-312817.html +# Date: 2005-06-30 + +# To customize this script, you can set the following environment variables: +# +# Location to save the backup to: +# STAGE4_LOCATION="/mnt/storage/backups" +# +# List of paths to exclude: +# STAGE4_CUSTOM_EXCLUDE=" +# /home/mythtv/store/* +# /home/slake/media" + +version=v3.5 +basename=`basename $0` + +find=/usr/bin/find +tar=/bin/tar + +# these are the commands we actually need for the backup +command_list=(cut date echo $find grep hostname mount sh split $tar umount uname which) + +# verify that each command we use exists. if one can't be found use $PATH and make a suggestion if possible. +for command in ${command_list[@]}; do + if [ ! -x "`which $command 2>&1`" ]; then + echo -e "\nERROR: $command not found! " + base=`basename $command` + if [ "`which $base 2>&1 | grep "no \`basename $command\` in"`" != "" ]; then + echo -e "ERROR: $base is not in your \$PATH." + fi + exit -1 + fi +done + +help="\nUsage:\n\nsh `basename $0` [[-v]|[--verbose]] [[-s]|[--split]] \n\nTo run the script NOT in verbose mode comes in handy if you want to see only the errors that occur during the backup.\n" + +# Defaults to creating one tarball + +tar_output="--file" + +# split command +split_options="--suffix-length=1 --bytes=685m" + +# options for the tar command +tarOptions=" --preserve-permissions --create --absolute-names --totals --ignore-failed-read" + +# where to put the stage4 +stage4Location=${STAGE4_LOCATION:-$HOME/backups} + +# name prefix +stage4prefix=`hostname`-stage4-`date +\%Y.\%m.\%d` + +# patterns which should not be backed up (like iso files). +# example: default_exclude_pattern="*.iso *.divx" +# These pattern count only for files NOT listed in the $custom_include_list. +default_exclude_pattern="" + +# these files/directories are always excluded. don't add trailing slashes. +# don't touch it unless you know what you are doing! +# /var/db and /var/cache/edb are intentionally added here. they are listed +# in $default_include_folders +default_exclude_list=" +/dev +/lost+found +/mnt +/proc +/sys +/tmp +/usr/portage +/usr/src +/var/log +/var/tmp +/var/db +/var/cache/edb +$stage4Location +`echo $CCACHE_DIR`" + +# files/devices/folders, which need to be backed up (preserve folder structure). +# don't touch it unless you know what you are doing! no recursive backup of folders. +# use $default_include_folders instead. +default_include_files=" +/dev/null +/dev/console +/home +/mnt +/proc +/sys +/tmp +/usr/portage +/usr/src +/var/log/emerge.log" + +# folders, which need to be backed up recursively on every backup. +# don't touch it unless you know what you are doing! the reason for this +# variable is that some users add /var to the $default_exclude_list. here +# we ensure that portage's memory is backed up in any case. +default_include_folders=" +/var/db" + +# IMPORTANT: A minimal backup will EXCLUDE files/folders listed here. A custom backup will +# include/exclude these files/folders depening on your answer. +custom_include_list=" +/home/* +/usr/src/linux-`uname -r`" + +# add files/folders here which are subfolders of a folder listed in $custom_include_list which should NOT +# be backed up. eg. +#custom_exclude_list="/home/foo/mp3 /home/foo/downloads /home/foo/.*" +custom_exclude_list=$STAGE4_CUSTOM_EXCLUDE + +# Only files/folders within the $custom_include_list are checked against these patterns +# custom_exclude_pattern="*.mp3 *.iso" +custom_exclude_pattern="*.avi *.mkv *.mp3 *.mp4 *.mpeg *.mpg *.ogg *.wmv" + +# the find_command +find_command="$find /*" + +# don't backup anything which matches pattern listed in $default_exclude_pattern +for pattern in $default_exclude_pattern; do + find_command="$find_command -not -name $pattern" +done + +# assemble the find_command +function find_files() +{ + for folder in $default_exclude_list; do + find_command="$find_command -path $folder -prune -o" + done + + find_command="$find_command -print" + + for i in $default_include_files; do + find_command="echo $i; $find_command" + done + + for i in $default_include_folders; do + if [ -d $i ]; then + find_command="$find $i; $find_command" + else + find_command="echo $i; $find_command" + fi + done +} + +# check the exclude/include variables for non-existing entries +function verify() +{ + for i in $1; do + if [ ! -e "`echo "$i" | cut -d'=' -f2 | cut -d'*' -f1`" -a "$i" != "/lost+found" -a "$i" != "$stage4Location" ]; then + echo "ERROR: `echo "$i" | cut -d'=' -f2` not found! Check your "$2 + exit 0 + fi + done +} + +# check input parameters +while [ $1 ]; do + case $1 in + "-h" | "--help") + echo -e $help + exit 0;; + "-v" | "--verbose") + verbose=$1;; + "-s" | "--split") + tar_output="--split";; + "");; + *) + echo -e $help + exit 0;; + esac + shift +done + +echo "" + +# check folder/files listed in $default_exclude_list exist +verify "$default_exclude_list" "\$default_exclude_list" + +# check files listed in $default_include_files exist +verify "$default_include_files" "\$default_include_files" + +# check folder listed in $default_include_folders exist +verify "$default_include_folders" "\$default_include_folders" + +#check folder listed in $custom_include_list exist +verify "$custom_include_list" "\$custom_include_list" + +#check folder listed in $custom_exclude_list exist +verify "$custom_exclude_list" "\$custom_exclude_list" + +# print out the version +echo -e "\nBackup script $version" +echo -e "==================" + +# how do you want to backup? +echo -e "\nWhat do you want to do? (Use CONTROL-C to abort)\n +Fast (tar.gz): + (1) Minimal backup + (2) Interactive backup + + +Best (tar.bz2): + (3) Minimal backup + (4) Interactive backup\n" + +while [ "$option" != '1' -a "$option" != '2' -a "$option" != '3' -a "$option" != '4' ]; do + echo -en "Please enter your option: " + read option +done + +case $option in +[1,3]) + stage4Name=$stage4Location/$stage4prefix-minimal.tar;; + +[2,4]) + stage4Name=$stage4Location/$stage4prefix-custom.tar + + for folder in $custom_include_list; do + echo -en "\nDo you want to backup" `echo "$folder" | cut -d'=' -f2`"? (y/n) " + read answer + while [ "$answer" != 'y' -a "$answer" != 'n' ]; do + echo -en "Do you want to backup" `echo "$folder" | cut -d'=' -f2`"? (y/n) " + read answer + done + if [ "$answer" == 'n' ]; then + find_command="$find_command -path $folder -prune -o" + else + custom_find="$find $folder" + for i in $custom_exclude_pattern; do + custom_find="$custom_find -name $i -o" + done + for i in $custom_exclude_list; do + custom_find="$custom_find -path $i -prune -o" + done + find_command="$custom_find -print; $find_command" + fi + done ;; +esac + +# add $custom_include_list to the $default_exclude_list as we assembled +# $custom_find with $custom_include_list already. +default_exclude_list="$default_exclude_list $custom_include_list" + +case $option in +[1,2]) + stage4postfix="gz" + zip="--gzip";; + +[3,4]) + stage4postfix="bz2" + zip="--bzip2";; +esac + +# mount boot +echo -e "\n* mounting boot" +mount /boot >/dev/null 2>&1 + +# find the files/folder to backup +find_files +find_command="($find_command)" + +# create the final command +if [ "$tar_output" == "--file" ]; then + tar_command="$find_command | $tar $zip $tarOptions $verbose --file $stage4Name.$stage4postfix --no-recursion -T -" +else + tar_command="$find_command | $tar $zip $tarOptions $verbose --no-recursion -T - | split $split_options - "$stage4Name.$stage4postfix"_" +fi + +if [ "$verbose" ]; then + echo -ne "\n* creating the stage4 in $stage4Location with the following command:\n\n"$tar_command +fi + +# everything is set, are you sure to continue? +echo -ne "\nDo you want to continue? (y/n) " +read answer +while [ "$answer" != 'y' ] && [ "$answer" != 'n' ]; do + echo -ne "Do you want to continue? (y/n) " + read answer +done + +if [ "$answer" == 'y' ]; then + # check whether the file already exists. + if [ "$tar_output" == "--split" ]; then + overwrite="`ls "$stage4Name.$stage4postfix"_* 2>&1 | grep -v 'No such file'`" + else + overwrite="$stage4Name.$stage4postfix" + fi + + if [ -a "`echo "$overwrite" | grep "$overwrite" -m1`" ]; then + echo -en "\nDo you want to overwrite $overwrite? (y/n) " + read answer + while [ "$answer" != 'y' ] && [ "$answer" != 'n' ]; do + echo -en "Do you want to overwrite $overwrite? (y/n) " + read answer + done + if [ "$answer" == 'n' ]; then + echo -e "\n* There's nothing to do ... Exiting" + exit 0; + fi + fi + + # if necessary, create the stage4Location + if [ ! -d "$stage4Location" ] ; then + echo "* creating directory $stage4Location" + mkdir -p $stage4Location + fi + + echo -e "\n* Please wait while the stage4 is being created.\n" + + # do the backup. + sh -c "$tar_command" + + # finished, clean up + echo -e "\n* stage4 is done" + echo "* umounting boot" + umount /boot >/dev/null 2>&1 + + # Integrity check + echo -e "* Checking integrity" + if [ "$zip" == "--gzip" ]; then + zip="gzip" + else + zip="bzip2" + fi + + if [ "$tar_output" == "--split" ]; then + if [ "`cat "$stage4Name.$stage4postfix"_*"" | $zip --test 2>&1`" != "" ]; then + echo -e "* Integrity check failed. Re-run the script and check your hardware." + exit -1 + fi + else + if [ "`$zip --test $stage4Name.$stage4postfix 2>&1`" != "" ]; then + echo -e "* Integrity check failed. Re-run the script and check your hardware." + exit -1 + fi + fi + + # everything went smoothly" + echo -e "* Everything went smoothly. You successfully created a stage4." + +else + echo -e "\n* There's nothing to do ... Exiting" +fi + +# Split the archive into chunks - uncomment the 3 lines if you want to split the stage4 +# echo -e "* split $stage4Name.$stage4postfix" +# split $split_options $stage4Name.$stage4postfix "$stage4Name.$stage4postfix"_ +# echo "* splitting is done" + + +# Restore Instructions +# 1. boot off a live-cd and repartition and create filesystems as necessary +# 2. eventually reboot, using option: gentoo docache +# 3. umount /mnt/cdrom +# 4. remove the live-cd and insert the cd with the stage4 +# 5. mount /dev/cdrom /mnt/cdrom +# 6. mount /dev/hdaX /mnt/gentoo +# 7. mkdir /mnt/gentoo/boot +# 8. mount /dev/hdaX /mnt/gentoo/boot +# 9. tar xzvpf /mnt/cdrom/host-stage4-18.04.2005-custom.tar.gz -C /mnt/gentoo/ +# or +# 9. tar xjvpf /mnt/cdrom/host-stage4-18.04.2005-custom.tar.bz2 -C /mnt/gentoo/ +# 10. mount -t proc none /mnt/gentoo/proc +# 11. mount -o bind /dev /mnt/gentoo/dev +# 12. chroot /mnt/gentoo /bin/bash +# 13. env-update +# 14. source /etc/profile +# +# if in need adjust necessary files (/etc/fstab, /boot/grub/grub.conf) and/or install grub +# +# 15. emerge sync (rebuild portage tree) +# 16. exit +# 17. cd / +# 18. umount /mnt/cdrom +# 19. remove backup cd +# 20. umount /mnt/gentoo/boot +# 21. umount /mnt/gentoo/dev +# 22. umount /mnt/gentoo/proc +# 23 umount /mnt/gentoo +# 24. Reboot + diff --git a/git/gitconfig b/git/gitconfig index 71affb8..2032c75 100644 --- a/git/gitconfig +++ b/git/gitconfig @@ -5,20 +5,36 @@ email = kevin.litwack@gmail.com [core] pager = less editor = vim - excludesfile = /home/geeber/.gitignore_global + excludesfile = ~/.gitignore_global [alias] -co = checkout -ci = commit -st = status -#la = log --pretty=\"format:%ad %h (%an): %s\" --date=short -la = log --color --graph --date=short --pretty=\"format:%ad %Cred%h%C(bold yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr)%Creset\" + co = checkout + ci = commit + st = status + + ba = branch --all + bv = branch --all --verbose --verbose + + lg = log --color --graph --date=short --pretty=\"format:%ad %Cred%h%C(bold yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr)%Creset\" + ll = log --color --date=short --pretty=\"format:%ad %Cred%h%C(bold yellow)%d%Creset %s %C(bold blue)<%an>%Creset %Cgreen(%cr)%Creset\" --numstat + lu = log -u + + dw = diff --word-diff + dc = diff --cached + dl = diff --cached HEAD^ + dr = "!f() { git diff "$1"^.."$1"; }; f" + + sl = stash list + sp = stash pop [color] -branch = auto -diff = auto -interactive = auto -status = auto + branch = auto + diff = auto + interactive = auto + status = auto [push] - default = upstream + default = upstream + +[diff] + patience = true diff --git a/git/gitignore-global b/git/gitignore-global new file mode 100644 index 0000000..3adf853 --- /dev/null +++ b/git/gitignore-global @@ -0,0 +1,7 @@ +# Global list of files to ignore. + +# OS X +._* +.DS_Store +.DS_Store? +.Trashes diff --git a/gtd/vim/plugin/gtd.vim b/gtd/vim/plugin/gtd.vim new file mode 100644 index 0000000..431ca61 --- /dev/null +++ b/gtd/vim/plugin/gtd.vim @@ -0,0 +1,3 @@ +" Vim plugin to add detection of GTD file types + +au BufNewFile,BufRead *.gtd set filetype=gtd diff --git a/gtd/vim/syntax/gtd.vim b/gtd/vim/syntax/gtd.vim new file mode 100644 index 0000000..403f270 --- /dev/null +++ b/gtd/vim/syntax/gtd.vim @@ -0,0 +1,43 @@ +" Vim syntax file +" Language: Getting Things Done (gtd) organization files +" Maintainer: Greg Look +" Filenames: *.gtd +" Version: 1.0 + +" Quit when a syntax file was already loaded. +if exists("b:current_syntax") + finish +endif + +highlight gtdPerson ctermfg=Green +highlight gtdTag ctermfg=Cyan +highlight gtdContext ctermfg=Magenta +highlight gtdDate ctermfg=Yellow +highlight gtdUri term=underline ctermfg=DarkMagenta +highlight gtdList term=bold ctermfg=DarkCyan + +highlight gtdCategory term=bold ctermfg=Blue +highlight gtdProject term=bold ctermfg=Yellow +highlight gtdProjectBase ctermfg=DarkGrey +highlight gtdProjectItem ctermfg=White +highlight gtdAction term=bold ctermfg=Red +highlight gtdPending term=bold ctermfg=DarkRed + + +syntax match gtdPerson /@\w\+/ +syntax match gtdTag /#\w\+/ +syntax match gtdContext /:\w\+:/ +syntax match gtdDate /<\d\d\d\d-\d\d-\d\d.*>/ms=s+1,me=e-1 +syntax match gtdUri /\[\[.*\]\]/ms=s+2,me=e-2 +syntax match gtdList /^\s*-\s/ + +syntax match Comment /^\s*\/\/.*$/ +syntax match gtdCategory /^===.*$/ +syntax match gtdProject /^\*.*$/ contains=gtdPerson,gtdTag +syntax match gtdProjectBase /^\*\*.*$/ contains=gtdProjectItem +syntax match gtdProjectItem /\*[^*].*$/ contained +syntax match gtdAction /^! .*$/ contains=gtdPerson,gtdTag,gtdContext,gtdDate +syntax match gtdPending /^\~ .*$/ contains=gtdPerson,gtdTag,gtdContext,gtdDate + + +let b:current_syntax = "gtd" diff --git a/input/Xmodmap b/input/Xmodmap new file mode 100644 index 0000000..029e5ac --- /dev/null +++ b/input/Xmodmap @@ -0,0 +1,6 @@ +! X input modification map + +! rebind caps-lock as left-control +keycode 66 = Control_L +clear Lock +add Control = Control_L diff --git a/keychain/util/keychain/ssh-agent.sh b/keychain/util/keychain/ssh-agent.sh index 200c99e..62c49ea 100755 --- a/keychain/util/keychain/ssh-agent.sh +++ b/keychain/util/keychain/ssh-agent.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This script wraps the invocation of the ssh-agent to ensure that the # requested keys are loaded. @@ -15,7 +15,13 @@ agent_info="$HOME/.ssh/agent_info" # Gets the IDs of any running ssh-agent processes, separated by newlines. agent_pids() { - ps | grep ssh-agent | grep -v grep | awk '{print $1}' + #ps -u $USER -o pid,comm | grep -P '^\s*\d+ ssh-agent' | awk '{ print $1 }' + for proc in /proc/[0-9]*; do + pid=$(echo $proc | cut -d / -f 3) + if cat /proc/$pid/cmdline 2> /dev/null | grep -P '^ssh-agent' > /dev/null; then + echo $pid + fi + done } @@ -23,7 +29,7 @@ agent_pids() { agent_is_connected() { if [[ -n "$SSH_AUTH_SOCK" && -n "$SSH_AGENT_PID" ]]; then if [[ ! -S $SSH_AUTH_SOCK ]]; then - #echo "ssh-agent socket does not exist" + #echo "ssh-agent socket $SSH_AUTH_SOCK does not exist" return 1 fi if [[ -n "$(agent_pids | grep $SSH_AGENT_PID)" ]]; then @@ -52,38 +58,37 @@ start_agent() { } -# Ensures the shell is connected to a running ssh-agent. -connect_agent() { - # abort if already connected to an ssh-agent - if agent_is_connected; then - echo "Already connected to ssh-agent ($SSH_AGENT_PID)" - return - fi +##### AGENT INITIALIZATION ##### - # if there is a cached info file and a running agent, try to use it - if [[ -f $agent_info && -n "$(agent_pids)" ]]; then - #echo "Attempting to use cached ssh-agent info file" - load_agent_info - if agent_is_connected; then - echo "Connected to ssh-agent ($SSH_AGENT_PID)" - return - fi - fi +# abort if already connected to an ssh-agent +if agent_is_connected; then + echo "Already connected to ssh-agent ($SSH_AGENT_PID)" + exit +fi - # need to load the keychain - #echo "No ssh-agent connection info available, launching new agent" +# if there is a cached info file and a running agent, try to use it +if [[ -f $agent_info && -n "$(agent_pids)" ]]; then + #echo "Attempting to use cached ssh-agent info file" + load_agent_info + if agent_is_connected; then + echo "Connected to ssh-agent ($SSH_AGENT_PID)" + exit + fi +fi - # kill running agents - [[ -n "$(agent_pids)" ]] && agent_pids | xargs kill +# need to load the keychain +#echo "No ssh-agent connection info available, launching new agent" - # launch ssh-agent - start_agent && load_agent_info +# kill running agents +for pid in $(agent_pids); do + echo "Killing running ssh-agent ($pid)" + kill -KILL $pid +done +# launch ssh-agent +if start_agent && load_agent_info; then echo "Started ssh-agent ($SSH_AGENT_PID)" - -} - - -# ensure ssh-agent is active -connect_agent +else + echo "Failed to start ssh-agent!" +fi diff --git a/keychain/zsh/profile.d/keychain.sh b/keychain/zsh/profile.d/keychain.sh index e4c98a7..1f0df87 100644 --- a/keychain/zsh/profile.d/keychain.sh +++ b/keychain/zsh/profile.d/keychain.sh @@ -1,6 +1,10 @@ # Sets up keychain agents on login. +# Initialize the ssh key agent. $HOME/util/keychain/ssh-agent.sh source $HOME/.ssh/agent_info > /dev/null +# Add the default key if none are present. +ssh-add -l > /dev/null || ssh-add + # TODO: set up gpg-agent? diff --git a/lein/lein/profiles.d/user.clj b/lein/lein/profiles.d/user.clj new file mode 100644 index 0000000..7a0b29d --- /dev/null +++ b/lein/lein/profiles.d/user.clj @@ -0,0 +1,31 @@ +{:aliases + {"all" ["do" ["clean"] ["check"] ["test"] ["cloverage"] ["hiera"]] + "slamhound" ["run" "-m" "slam.hound"]} + + :dependencies + [[clj-stacktrace "0.2.7"] + [slamhound "1.5.5"] + [org.clojure/tools.trace "0.7.6"]] + + :plugins + [[lein-ancient "0.5.5"] + [lein-cloverage "1.0.2"] + [lein-cprint "1.0.0"] + [lein-hiera "0.9.0-SNAPSHOT"] + [lein-kibit "0.0.8"] + [lein-vanity "0.2.0"] + [com.jakemccrary/lein-test-refresh "0.3.9"] + [jonase/eastwood "0.1.0"]] + + :injections + [(let [orig (ns-resolve (doto 'clojure.stacktrace require) 'print-cause-trace) + new (ns-resolve (doto 'clj-stacktrace.repl require) 'pst+)] + (alter-var-root orig (constantly (deref new))))] + + :repl-options + {:init (do (require '[clj-stacktrace.repl :refer [pst+]]))} + + :hiera + {:show-external? true + :vertical? false + :ignore-ns #{clojure user}}} diff --git a/lein/zsh/functions/_lein b/lein/zsh/functions/_lein new file mode 100644 index 0000000..5f74099 --- /dev/null +++ b/lein/zsh/functions/_lein @@ -0,0 +1,69 @@ +#compdef lein + +# Lein ZSH completion function +# Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions) +# and rename it _lein + +_lein() { + if (( CURRENT > 2 )); then + # shift words so _arguments doesn't have to be concerned with second command + (( CURRENT-- )) + shift words + # use _call_function here in case it doesn't exist + _call_function 1 _lein_${words[1]} + else + _values "lein command" \ + "check[Check syntax and warn on reflection.]" \ + "classpath[Print the classpath of the current project.]" \ + "clean[Remove all files from project's target-path.]" \ + "cloverage[Run unit tests to generate coverage statistics.]" \ + "compile[Compile Clojure source into \.class files.]" \ + "deploy[Build jar and deploy to remote repository.]" \ + "deps[Download :dependencies.]" \ + "eastwood[Lint clojure source files.]" \ + "help[Display a list of tasks or help for a given task.]" \ + "install[Install current project to the local repository.]" \ + "jack-in[Jack in to a Clojure SLIME session from Emacs.]" \ + "jar[Package up all the project's files into a jar file.]" \ + "javac[Compile Java source files.]" \ + "new[Create a new project skeleton.]" \ + "plugin[Manage user-level plugins.]" \ + "pom[Write a pom.xml file to disk for Maven interoperability.]" \ + "profiles[List all available profiles or display one if given an argument.]" \ + "repl[Start a repl session either with the current project or standalone.]" \ + "retest[Run only the test namespaces which failed last time around.]" \ + "run[Run the project's -main function.]" \ + "search[Search remote repositories.]" \ + "swank[Launch swank server for Emacs to connect.]" \ + "test[Run the project's tests.]" \ + "trampoline[Run a task without nesting the project's JVM inside Leiningen's.]" \ + "uberjar[Package up the project files and all dependencies into a jar file.]" \ + "upgrade[Upgrade Leiningen to the latest stable release.]" \ + "version[Print version for Leiningen and the current JVM.]" \ + "with-profile[Apply the given task with the profile(s) specified.]" \ + "ns-dep-graph[Generate a graph of namespace dependencies.]" + fi +} + +_lein_plugin() { + _values "lein plugin commands" \ + "install[Download, package, and install plugin jarfile into ~/.lein/plugins]" \ + "uninstall[Delete the plugin jarfile: \[GROUP/\]ARTIFACT-ID VERSION]" +} + + +_lein_namespaces() { + if [ -d test ]; then + _values "lein valid namespaces" $(find $1 -type f -name "*.clj" -exec grep -E \ + '^\(ns[[:space:]]+\w+' '{}' ';' | awk '/\(ns[ ]*([A-Za-z\.]+)/ {print $2}') + fi +} + +_lein_run() { + _lein_namespaces "src/" +} + +_lein_test() { + _lein_namespaces "test/" +} + diff --git a/manifest.rb b/manifest.rb index 1e84b54..a4793de 100644 --- a/manifest.rb +++ b/manifest.rb @@ -7,19 +7,26 @@ package 'keychain', :dotfiles => ['zsh'] # shell configuration -package 'input', :dotfiles => true, :default => true -package 'zsh', :dotfiles => true, :when => ( File.basename(ENV['SHELL']) == 'zsh' ) -package 'cygwin', :dotfiles => true, :when => ( File.directory? '/cygdrive' ) +package 'input', :default => true, :dotfiles => true +package 'bash', :when => shell?('bash'), :dotfiles => true +package 'zsh', :when => shell?('zsh'), :dotfiles => true +package 'cygwin', :when => file?('/Cygwin.bat'), :dotfiles => true +package 'solarized', :dotfiles => ['vim', 'zsh'] # application settings -package 'git', :dotfiles => true, :default => true +package 'git', :when => installed?('git'), :dotfiles => true package 'gradle', :dotfiles => true, :when => ( File.directory? '~/gradle' ) -package 'tmux', :dotfiles => true -package 'vim', :dotfiles => true, :default => true -package 'vundle', :into => '.vim' +package 'tmux', :when => installed?('tmux'), :dotfiles => ['tmux.conf', 'zsh'] +package 'vim', :when => installed?('vim'), :dotfiles => true +package 'vundle', :into => '.vim' +package 'synergy', :into => 'util/synergy' -# langauges -package 'rbenv', :dotfiles => true, :when => ( File.directory?(ENV['HOME'] + '/.rbenv') ) +# programming languages package 'java', :into => 'util/java' +package 'lein', :when => installed?('lein'), :dotfiles => true +package 'rbenv', :when => file?(ENV['HOME'], '.rbenv'), :dotfiles => true package 'virtualenv', :dotfiles => true +# misc packages +package 'gentoo', :into => 'admin/gentoo' +package 'gtd', :dotfiles => ['vim'] diff --git a/rbenv/zsh/profile.d/rbenv.sh b/rbenv/zsh/profile.d/rbenv.sh index baa85c0..5797f1a 100644 --- a/rbenv/zsh/profile.d/rbenv.sh +++ b/rbenv/zsh/profile.d/rbenv.sh @@ -5,7 +5,7 @@ # $ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build if [[ -s "$HOME/.rbenv" ]]; then -unset RUBYOPT + unset RUBYOPT path=("$HOME/.rbenv/bin" $path) eval "$(rbenv init -)" fi diff --git a/riemann/etc/dash.rb b/riemann/etc/dash.rb new file mode 100644 index 0000000..2185155 --- /dev/null +++ b/riemann/etc/dash.rb @@ -0,0 +1,4 @@ +#set :bind, '192.168.248.1' +set :bind, '0.0.0.0' +set :port, 4567 +config[:ws_config] = '/var/lib/riemann/dash/layout.json' diff --git a/riemann/etc/riemann.config b/riemann/etc/riemann.config new file mode 100644 index 0000000..76d2872 --- /dev/null +++ b/riemann/etc/riemann.config @@ -0,0 +1,67 @@ +; vim: filetype=clojure + +(logging/init :file "/var/log/riemann/riemann.log") + +; Listen on the local interface over TCP (5555), UDP (5555), and websockets +; (5556) +(let [host "0.0.0.0"] + (tcp-server :host host) + (udp-server :host host) + (ws-server :host host)) + +; Expire old events from the index every N seconds. +(periodically-expire 10) + + +(defn pop-service + "Returns a new service with the last component removed." + [service] + (->> + (clojure.string/split service #"\s+") + butlast + (clojure.string/join \space))) + + +(defn alter-service + "Modifies events' service by replacing the last component with the one given." + [event suffix] + (assoc event :service + (-> event + :service + pop-service + (str \space suffix)))) + + +(defn bytes->kbps + "Convert byte count metrics into kbps. Rate is calculated every t seconds." + [t & children] + (scale (/ 8 1024) + (rate t + (apply smap #(alter-service % "kbps") + children)))) + + +; Keep events in the index for 5 minutes by default. +(let [index (default :ttl 300 (index))] + + ; Inbound events will be passed to these streams: + (streams + + ; Index all events immediately. + index + + ; Calculate network traffic in kbps + (where (and (tagged "net") (service #" bytes$")) + (by [:service] + (bytes->kbps 10 + (with {:ttl 30} + index)))) + + ; Calculate an overall rate of events. + (with {:metric 1 :host nil :state "ok" :service "events/sec" :ttl 20} + (rate 10 index)) + + ; Log expired events. + (expired + (fn [event] (info "expired" event))) +)) diff --git a/riemann/init/riemann b/riemann/init/riemann new file mode 100755 index 0000000..bed1928 --- /dev/null +++ b/riemann/init/riemann @@ -0,0 +1,56 @@ +#!/sbin/runscript + +# This script assumes that Riemann has a user and group set up, and that the +# service files have been extracted to `/var/lib/riemann/current`. +# +# Author: Greg Look (greg@mvxcvi.com) + +extra_started_commands="reload" + +CFG_DIR=/etc/riemann +LIB_DIR=/var/lib/riemann +RUN_DIR=/var/run/riemann +LOG_DIR=/var/log/riemann + +RIEMANN_DIR=$LIB_DIR/current +COMMAND=$RIEMANN_DIR/bin/riemann + +CONFIG_FILE=$CFG_DIR/riemann.config +PIDFILE=$RUN_DIR/riemann.pid + +start() { + checkpath -d -m 0755 -o riemann:riemann $RUN_DIR + checkpath -d -m 0755 -o riemann:riemann $LOG_DIR + ebegin "Starting riemann" + start-stop-daemon \ + --start \ + --user riemann:riemann \ + --pidfile $PIDFILE \ + --make-pidfile \ + --background \ + --exec $COMMAND \ + -- $CONFIG_FILE \ + 2>&1 > /dev/null + eend $? +} + +stop() { + ebegin "Stopping riemann" + start-stop-daemon \ + --stop \ + --pidfile $PIDFILE \ + --exec $COMMAND + eend $? +} + +reload() { + if [ ! -f $PIDFILE ]; then + eerror "$SVCNAME isn't running" + return 1 + fi + ebegin "Reloading riemann configuration" + start-stop-daemon \ + --signal HUP \ + --pidfile $PIDFILE + eend $? +} diff --git a/riemann/init/riemann-dash b/riemann/init/riemann-dash new file mode 100755 index 0000000..65ca94a --- /dev/null +++ b/riemann/init/riemann-dash @@ -0,0 +1,47 @@ +#!/sbin/runscript + +# This script assumes that Riemann has a user and group set up, and that the +# system gem `riemann-dash` has been installed. +# +# Author: Greg Look (greg@mvxcvi.com) + +CFG_DIR=/etc/riemann +RUN_DIR=/var/run/riemann +LOG_DIR=/var/log/riemann + +COMMAND=/usr/local/bin/riemann-dash + +CONFIG_FILE=$CFG_DIR/dash.rb +PIDFILE=$RUN_DIR/dash.pid +LOGFILE=$LOG_DIR/dash.log + +depend() { + use riemann net +} + +start() { + checkpath -d -m 0755 -o riemann:riemann $RUN_DIR + checkpath -d -m 0755 -o riemann:riemann $LOG_DIR + ebegin "Starting riemann dashboard" + start-stop-daemon \ + --start \ + --user riemann:riemann \ + --chdir $RUN_DIR \ + --pidfile $PIDFILE \ + --make-pidfile \ + --background \ + --stdout $LOGFILE \ + --stderr $LOGFILE \ + --exec $COMMAND \ + -- $CONFIG_FILE + eend $? +} + +stop() { + ebegin "Stopping riemann dashboard" + start-stop-daemon \ + --stop \ + --pidfile $PIDFILE \ + --exec $COMMAND + eend $? +} diff --git a/riemann/init/riemann.tool b/riemann/init/riemann.tool new file mode 100755 index 0000000..eeeb678 --- /dev/null +++ b/riemann/init/riemann.tool @@ -0,0 +1,54 @@ +#!/sbin/runscript + +# This script assumes that Riemann has a user and group set up, and that the +# system gem `riemann-tools` has been installed. This script should not be run +# directly; instead, link other scripts to this one like so: +# +# $ ln -s /etc/init.d/riemann.tool riemann.health +# +# Author: Greg Look (greg@mvxcvi.com) + +TOOL=${RC_SVCNAME:8} +COMMAND="riemann-$TOOL" + +RUN_DIR=/var/run/riemann/tool +PIDFILE=$RUN_DIR/${TOOL}.pid + +checktool() { + if [ 'tool' == "$TOOL" ]; then + eerror "The riemann.tool script is a meta-script!" + eerror "Instead, symlink other tool scripts to this one." + eend 1 + exit + fi +} + +depend() { + need riemann +} + +start() { + checktool + checkpath -d -m 0755 -o riemann:riemann $RUN_DIR + ebegin "Starting Riemann $TOOL metrics" + start-stop-daemon \ + --start \ + --user riemann:riemann \ + --pidfile $PIDFILE \ + --make-pidfile \ + --background \ + --exec $COMMAND -- \ + $RIEMANN_TOOL_ARGS \ + 2>&1 > /dev/null + eend $? +} + +stop() { + checktool + ebegin "Stopping Riemann $TOOL metrics" + start-stop-daemon \ + --stop \ + --pidfile $PIDFILE \ + --exec $COMMAND + eend $? +} diff --git a/riemann/tools/lib/solanum.rb b/riemann/tools/lib/solanum.rb new file mode 100644 index 0000000..b9d918b --- /dev/null +++ b/riemann/tools/lib/solanum.rb @@ -0,0 +1,26 @@ +$: << File.expand_path("..", __FILE__) + +require 'solanum/source' + + +# Namespace module with some handy utility methods. +# +# Author:: Greg Look +module Solanum + + # Collects metrics from the given sources, in order. Returns a merged map of + # metric data. + def self.collect(sources) + sources.reduce({}) do |metrics, source| + new_metrics = nil + begin + new_metrics = source.collect(metrics) + rescue => e + STDERR.puts "Error collecting metrics from #{source}: #{e}" + raise e + end + new_metrics || metrics + end + end + +end diff --git a/riemann/tools/lib/solanum/dsl.rb b/riemann/tools/lib/solanum/dsl.rb new file mode 100644 index 0000000..d6f5419 --- /dev/null +++ b/riemann/tools/lib/solanum/dsl.rb @@ -0,0 +1,80 @@ +# This file defines some helper methods for Solanum's monitoring DSL. + + +##### SOURCE DEFINITIONS ##### + +# A list of all registered metrics sources. +$sources = [] + + +# Registers a new source object. If a block is given, it is used to configure +# the source with instance_exec. +def register_source(source, config=nil) + source.instance_exec &config if config + $sources << source + source +end + + +# Registers a source which runs a command and matches against output lines. +def run(command, &config) + register_source Solanum::Source::Command.new(command), config +end + + +# Registers a source which matches against the lines in a file. +def read(path, &config) + register_source Solanum::Source::File.new(path), config +end + + +# Registers a source which computes metrics directly. +def compute(&block) + register_source Solanum::Source::Compute.new(block) +end + + + +##### HELPER METHODS ##### + +# Creates a state function based on thresholds. If the first argument is a +# symbol, it is taken as the default service state. Otherwise, arguments should +# be alternating numeric thresholds and state values to assign if the metric +# value exceeds the threshold. +# +# For example, for an 'availability' metric you often want to warn on low +# values. To assign a 'critical' state to values between 0% and 10%, +# 'warning' between 10% and 25%, and 'ok' above, use the following: +# +# thresholds(0.00, :critical, 0.10, :warning, 0.25, :ok) +# +# For 'usage' metrics it's the inverse, giving low values ok states and +# warning about high values: +# +# thresholds(:ok, 55, :warning, 65, :critical) +# +def thresholds(*args) + default_state = nil + default_state = args.shift unless args.first.kind_of? Numeric + + # Check arguments. + raise "Thresholds must be paired with state values" unless args.count.even? + args.each_slice(2) do |threshold| + limit, state = *threshold + raise "Limits must be numeric: #{limit}" unless limit.kind_of? Numeric + raise "State values must be strings or symbols: #{state}" unless state.instance_of?(String) || state.instance_of?(Symbol) + end + + # State block. + lambda do |v| + state = default_state + args.each_slice(2) do |threshold| + if threshold[0] < v + state = threshold[1] + else + break + end + end + state + end +end diff --git a/riemann/tools/lib/solanum/matcher.rb b/riemann/tools/lib/solanum/matcher.rb new file mode 100644 index 0000000..cd1c710 --- /dev/null +++ b/riemann/tools/lib/solanum/matcher.rb @@ -0,0 +1,32 @@ +module Solanum + +# This class maps a line-matching pattern to a set of calculations on the +# matched data. +# +# Author:: Greg Look +class Matcher + attr_reader :pattern, :fn + + # Creates a new Matcher + def initialize(pattern, &block) + raise "pattern must be provided" if pattern.nil? + raise "block must be provided" if block.nil? + + @pattern = pattern + @fn = block + end + + # Attempts to match the given line, calling it's recorder block with the + # given match and metrics if matched. Returns a (potentially) updated + # metrics map on match, or nil otherwise. + def match(metrics, line) + raise "line must be provided" if line.nil? + raise "metrics must be provided" if metrics.nil? + + if @pattern === line + @fn.call $~, metrics + end + end +end + +end diff --git a/riemann/tools/lib/solanum/source.rb b/riemann/tools/lib/solanum/source.rb new file mode 100644 index 0000000..491de42 --- /dev/null +++ b/riemann/tools/lib/solanum/source.rb @@ -0,0 +1,115 @@ +require 'solanum/matcher' + +module Solanum + +# This class represents a source of data, whether read from command output, +# a file on the system, or just calculated from other values. +# +# Author:: Greg Look +class Source + attr_reader :config, :matchers + + # Creates a new Source + def initialize(config) + @config = config + @matchers = [] + end + + # Collects or generates metrics and returns a potentially updated metrics + # map. + def collect(metrics) + metrics + end + + private + + def process(lines, metrics) + return metrics if lines.nil? + lines.reduce(metrics) do |metrics, line| + @matchers.each do |matcher| + new_metrics = matcher.match(metrics, line) + if new_metrics + metrics = new_metrics + break + end + end + metrics + end + end + + # Declares a matcher for a single line of input. + def match(pattern, options={}, &block) + raise "pattern must be provided" if pattern.nil? + + commands = 0 + commands += 1 if options[:record] + commands += 1 if block_given? + raise "Must specify :record or provide a block to execute" if commands == 0 + raise "Only one of :record or a block should be provided" if commands > 1 + + if options[:record] + block = lambda do |m, metrics| + value = m[1] + value = value.send(options[:cast]) if options[:cast] + value *= options[:scale] if options[:scale] + + metrics[options[:record]] = value + metrics + end + end + + @matchers << Solanum::Matcher.new(pattern, &block) + end + + + ### SOURCE TYPES ### + + public + + class Command < Source + def collect(metrics) + # Locate absolute command path. + command, args = @config.split(/\s/, 2) + abs_command = + if ::File.executable? command + command + else + %x{which #{command} 2> /dev/null}.chomp + end + + # Check, then execute command for line input. + if not ::File.exist?(abs_command) + raise "Command #{command} not found" + elsif not ::File.executable?(abs_command) + raise "Command #{abs_command} not executable" + else + lines = %x{#{abs_command} #{args}}.split("\n") + raise "Error executing command: #{abs_command} #{args}" unless $?.success? + process lines, metrics + end + end + end + + class File < Source + def collect(metrics) + raise "File does not exist: #{@config}" unless ::File.exists? @config + raise "File is not readable: #{@config}" unless ::File.readable? @config + + # Read lines from the file. + lines = ::File.open(@config) do |file| + file.readlines + end + + process lines, metrics + end + end + + class Compute < Source + def collect(metrics) + # Compute metrics directly. + @config.call(metrics) + end + end + +end +end diff --git a/riemann/tools/monitor/iptables.rb b/riemann/tools/monitor/iptables.rb new file mode 100644 index 0000000..1845157 --- /dev/null +++ b/riemann/tools/monitor/iptables.rb @@ -0,0 +1,72 @@ +##### IPTABLES SOURCE ##### + +class Solanum::Source::IPTables < Solanum::Source::Command + def initialize(args) + super("sudo -n iptables #{args}") + end + + # Records packet and byte metrics for a given serivce name. + def record_traffic(metrics, name, packets, bytes) + metrics["#{name} packets"] = packets.to_i + metrics["#{name} bytes"] = bytes.to_i + metrics + end + + # Matches an iptables chain header. + def match_chain(name, chain) + match /^Chain #{chain.upcase} \(policy \w+ (\d+) packets, (\d+) bytes\)/ do |m, metrics| + record_traffic metrics, "iptables #{name}", m[1], m[2] + end + end + + # Matches an iptables rule and records traffic statistics. + def match_rule(name, opts={}) + pattern = /^\s*(\d+)\s+(\d+)\s+#{opts[:target] || 'ACCEPT'}\s+#{opts[:proto] || 'all'}\s+\-\-\s+#{opts[:in] || 'any'}\s+#{opts[:out] || 'any'}\s+#{opts[:source] || 'anywhere'}\s+#{opts[:dest] || 'anywhere'}\s*#{opts[:match] || ''}/ + match pattern do |m, metrics| + record_traffic metrics, "iptables #{name}", m[1], m[2] + end + end +end + + +# Shorthand for running iptables through sudo. +def iptables(args, &config) + register_source Solanum::Source::IPTables.new(args), config +end + + + +##### METRIC DEFINITIONS ##### + +# FILTER:INPUT chain +iptables "--list INPUT --verbose --exact" do + match_chain "filter input DROP", "INPUT" # Dropped traffic + match_rule "filter input lan0", in: 'lan0' # Traffic to XVI from the LAN + match_rule "filter input established", in: 'wan0', # Established traffic to XVI from Internet + match: 'ctstate RELATED,ESTABLISHED' +end + +# FILTER:OUTPUT chain +iptables "--list OUTPUT --verbose --exact" do + match_chain "filter output", "OUTPUT" # Traffic sent by XVI +end + +# FILTER:FORWARD chain +iptables "--list FORWARD --verbose --exact" do + match_chain "filter forward DROP", "FORWARD" + match_rule "filter forward lan0", in: 'lan0' # Forwarded traffic from LAN to Internet + match_rule "filter forward established", # Forward established traffic + match: 'ctstate RELATED,ESTABLISHED' +end + +# MANGLE:mark_qos_band chain +iptables "--table mangle --list mark_qos_band --verbose --exact" do + match_rule "mangle qos band1", target: 'RETURN', match: 'mark match 0x1' + match_rule "mangle qos band2", target: 'RETURN', match: 'mark match 0x2' + match_rule "mangle qos band3", target: 'RETURN', match: 'mark match 0x3' + match_rule "mangle qos band4", target: 'RETURN', match: 'mark match 0x4' + match_rule "mangle qos band5", target: 'RETURN', match: 'mark match 0x5' +end + +# Define services. +service /^iptables /, diff: true, tags: ["net"] diff --git a/riemann/tools/monitor/meminfo.rb b/riemann/tools/monitor/meminfo.rb new file mode 100644 index 0000000..245bed5 --- /dev/null +++ b/riemann/tools/monitor/meminfo.rb @@ -0,0 +1,37 @@ +# Read memory usage. +read "/proc/meminfo" do + match /^MemTotal:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory total bytes" + match /^MemFree:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory free bytes" + match /^MemAvailable:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory available bytes" + match /^Buffers:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory buffers bytes" + match /^Cached:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory cached bytes" + match /^Active:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "memory active bytes" + match /^SwapTotal:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "swap total bytes" + match /^SwapFree:\s+(\d+) kB$/, cast: :to_i, scale: 1024, record: "swap free bytes" +end + +# Calculate percentages from total space. +compute do |metrics| + percentages = { + "memory" => %w{free available buffers cached active}, + "swap" => %w{free} + } + + percentages.each do |sys, stats| + total = metrics["#{sys} total bytes"] + if total && total > 0 + stats.each do |stat| + bytes = metrics["#{sys} #{stat} bytes"] + if bytes + pct = bytes.to_f/total + metrics["#{sys} #{stat} pct"] = pct + end + end + end + end + + metrics +end + +service "memory available pct", state: thresholds(0.00, :critical, 0.10, :warning, 0.25, :ok) +service "swap free pct", state: thresholds(0.00, :critical, 0.10, :warning, 0.25, :ok) diff --git a/riemann/tools/monitor/sensors.rb b/riemann/tools/monitor/sensors.rb new file mode 100644 index 0000000..7fd2768 --- /dev/null +++ b/riemann/tools/monitor/sensors.rb @@ -0,0 +1,14 @@ +# encoding: utf-8 + +# Hardware sensor data. +run "sensors" do + match /^Core 0:\s+\+(\d+\.\d+)°C/, record: "sensor coretemp", cast: :to_f + match /^temp1:\s+\+(\d+\.\d+)°C/, record: "sensor temp1", cast: :to_f + match /^temp2:\s+\+(\d+\.\d+)°C/, record: "sensor temp2", cast: :to_f + match /^temp3:\s+\+(\d+\.\d+)°C/, record: "sensor temp3", cast: :to_f +end + +service "sensor coretemp", state: thresholds(:ok, 45.0, :warning, 55.0, :critical) +service "sensor temp1", state: thresholds(:ok, 50.0, :warning, 60.0, :critical) +service "sensor temp2", state: thresholds(:ok, 65.0, :warning, 75.0, :critical) +service "sensor temp3", state: thresholds(:ok, 60.0, :warning, 70.0, :critical) diff --git a/riemann/tools/riemann-solanum b/riemann/tools/riemann-solanum new file mode 100755 index 0000000..15dc9f3 --- /dev/null +++ b/riemann/tools/riemann-solanum @@ -0,0 +1,114 @@ +#!/usr/bin/env ruby + +require 'optparse' + +$options = { + riemann_host: 'localhost', + riemann_port: 5555, + event_host: %x{hostname --fqdn}.chomp, + interval: 5, + tags: [], + ttl: 10, + verbose: false, +} + +# Parse command-line options. +options = OptionParser.new do |opts| + opts.banner = "Usage: #{File.basename($0)} [options] [monitor config] ..." + opts.separator "" + opts.separator "Options:" + opts.on('-h', '--host HOST', "Riemann host (default: #{$options[:riemann_host]})") {|v| $options[:riemann_host] = v } + opts.on('-p', '--port PORT', "Riemann port (default: #{$options[:riemann_port]})") {|v| $options[:riemann_port] = v.to_i } + opts.on('-e', '--event-host HOST', "Event hostname (default: #{$options[:event_host]})") {|v| $options[:event_host] = v } + opts.on('-i', '--interval SECONDS', "Seconds between updates (default: #{$options[:interval]})") {|v| $options[:interval] = v.to_i } + opts.on('-t', '--tag TAG', "Tag to add to events (may be given multiple times)") {|v| $options[:tags] << v } + opts.on('-l', '--ttl SECONDS', "Default TTL for events (default: #{$options[:ttl]})") {|v| $options[:ttl] = v.to_i } + opts.on('-v', '--verbose', "Print additional information to stdout") { $options[:verbose] = true } + opts.on( '--help', "Displays usage information") { print opts; exit } +end +options.parse! + +# check usage +if ARGV.empty? + print options + exit 1 +end + +$scripts = ARGV.dup + +def log(msg) + puts msg if $options[:verbose] +end + + + +##### SOLANUM DSL ##### + +require_relative 'lib/solanum' +require_relative 'lib/solanum/dsl' + + +# A list of pairs of [matcher, prototype] where matcher is generally a string +# or regex to match a service name, and prototype is a map of :ttl, :state, +# :tags, etc. +$services = [] + +# Registers a service event prototype. +def service(service, prototype={}) + $services << [service, prototype] +end + + + +##### MONITORING CONFIGS ##### + +$scripts.each do |path| + log "Loading monitor script #{path}" + load path +end + +if $sources.empty? + STDERR.puts "No sources loaded from configuration scripts: #{$scripts.join(' ')}" + exit 1 +end + + + +##### REPORT LOOP ##### + +require 'riemann/client' + +$riemann = Riemann::Client.new host: $options[:riemann_host], port: $options[:riemann_port] +$metrics = {} + +loop do + metrics = Solanum.collect($sources) + metrics.each do |service, value| + prototype = $services.select{|m| m[0] === service }.map{|m| m[1] }.reduce({}, &:merge) + state = prototype[:state] ? prototype[:state].call(value) : :ok + tags = ((prototype[:tags] || []) + $options[:tags]).uniq + ttl = prototype[:ttl] || $options[:ttl] + + if prototype[:diff] + last = $metrics[service] + if last && last <= value + value = value - last + else + value = nil + end + end + + if value + log "%-40s %5s (%s) %s" % [service, value, state.nil? ? "--" : state, tags.join(' ')] + $riemann << { + service: service, + metric: value, + state: state.to_s, + tags: tags, + ttl: ttl + } + end + end + $metrics = metrics + sleep $options[:interval] +end diff --git a/solarized/util/scripts/solarized.dark.sh b/solarized/util/scripts/solarized.dark.sh new file mode 100755 index 0000000..662bc0a --- /dev/null +++ b/solarized/util/scripts/solarized.dark.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +echo -ne '\e]10;#657B83\a' # Foreground -> base00 +echo -ne '\e]11;#002B36\a' # Background -> base03 +echo -ne '\e]12;#93A1A1\a' # Cursor -> base1 +echo -ne '\e]4;1;#DC322F\a' # red +echo -ne '\e]4;2;#859900\a' # green +echo -ne '\e]4;3;#B58900\a' # yellow +echo -ne '\e]4;4;#268BD2\a' # blue +echo -ne '\e]4;5;#D33682\a' # magenta +echo -ne '\e]4;6;#2AA198\a' # cyan +echo -ne '\e]4;7;#EEE8D5\a' # white (light grey really) -> Base2 +echo -ne '\e]4;8;#002B36\a' # bold black (i.e. dark grey -> Base03) +echo -ne '\e]4;9;#CB4B16\a' # bold red -> orange +echo -ne '\e]4;10;#586E75\a' # bold green -> base01 +echo -ne '\e]4;11;#657B83\a' # bold yellow -> base00 +echo -ne '\e]4;12;#839496\a' # bold blue -> base0 +echo -ne '\e]4;13;#6C71C4\a' # bold magenta -> violet +echo -ne '\e]4;14;#93A1A1\a' # bold cyan -> base1 +echo -ne '\e]4;15;#FDFDE3\a' # bold white -> Base3 diff --git a/solarized/util/scripts/solarized.light.sh b/solarized/util/scripts/solarized.light.sh new file mode 100755 index 0000000..8d1be5d --- /dev/null +++ b/solarized/util/scripts/solarized.light.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +echo -ne '\e]10;#657B83\a' # Foreground -> base00 +echo -ne '\e]11;#FDF6E3\a' # Background -> base3 +echo -ne '\e]12;#93A1A1\a' # Cursor -> base1 +echo -ne '\e]4;1;#DC322F\a' # red +echo -ne '\e]4;2;#859900\a' # green +echo -ne '\e]4;3;#B58900\a' # yellow +echo -ne '\e]4;4;#268BD2\a' # blue +echo -ne '\e]4;5;#D33682\a' # magenta +echo -ne '\e]4;6;#2AA198\a' # cyan +echo -ne '\e]4;7;#EEE8D5\a' # white (light grey really) -> Base2 +echo -ne '\e]4;8;#002B36\a' # bold black (i.e. dark grey -> Base03) +echo -ne '\e]4;9;#CB4B16\a' # bold red -> orange +echo -ne '\e]4;10;#586E75\a' # bold green -> base01 +echo -ne '\e]4;11;#657B83\a' # bold yellow -> base00 +echo -ne '\e]4;12;#839496\a' # bold blue -> base0 +echo -ne '\e]4;13;#6C71C4\a' # bold magenta -> violet +echo -ne '\e]4;14;#93A1A1\a' # bold cyan -> base1 +echo -ne '\e]4;15;#FDFDE3\a' # bold white -> Base3 diff --git a/solarized/util/scripts/solarized.rb b/solarized/util/scripts/solarized.rb new file mode 100755 index 0000000..0f77922 --- /dev/null +++ b/solarized/util/scripts/solarized.rb @@ -0,0 +1,112 @@ +#!/usr/bin/ruby + +# This script prints out examples of every terminal color for testing purposes. +# +# Author:: Greg Look + + +##### CONFIGURATION ##### + +$mapping = ARGV[0] || 'dark' +$depth = ARGV[1] || '16' + + +##### CONSTANTS ##### + +ANSI_COLORS = { } +%w{black red green yellow blue magenta cyan white}.each_with_index do |color, i| + ANSI_COLORS[color.intern] = i + ANSI_COLORS[("br" + color).intern] = 8 + i +end + +SOLARIZED_COLORS = { + '16' => { + :base03 => "1c1c1c", + :base02 => "262626", + :base01 => "585858", + :base00 => "626262", + :base0 => "808080", + :base1 => "8a8a8a", + :base2 => "e4e4e4", + :base3 => "ffffd7", + :yellow => "af8700", + :orange => "d75f00", + :red => "d70000", + :magenta => "af005f", + :violet => "5f5faf", + :blue => "0087ff", + :cyan => "00afaf", + :green => "5f8700", + }, + '256' => { + :base03 => "002b36", + :base02 => "073642", + :base01 => "586e75", + :base00 => "657b83", + :base0 => "839496", + :base1 => "93a1a1", + :base2 => "eee8d5", + :base3 => "fdf6e3", + :yellow => "b58900", + :orange => "cb4b16", + :red => "dc322f", + :magenta => "d33682", + :violet => "6c71c4", + :blue => "268bd2", + :cyan => "2aa198", + :green => "859900", + } +} + +COLOR_MAPS = { + 'light' => { + :brblack => :base03, + :black => :base02, + :brgreen => :base01, + :bryellow => :base00, + :brblue => :base0, + :brcyan => :base1, + :white => :base2, + :brwhite => :base3, + :yellow => :yellow, + :brred => :orange, + :red => :red, + :magenta => :magenta, + :brmagenta => :violet, + :blue => :blue, + :cyan => :cyan, + :green => :green, + }, + 'dark' => { + :black => :base03, + :brblack => :base02, + :green => :base01, + :yellow => :base00, + :blue => :base0, + :cyan => :base1, + :brwhite => :base2, + :white => :base3, + :bryellow => :yellow, + :red => :orange, + :brred => :red, + :brmagenta => :magenta, + :magenta => :violet, + :brblue => :blue, + :brcyan => :cyan, + :brgreen => :green, + } +} + + +##### EXECUTION ##### + +def set_color(color, hex) + puts "\033]P%x%s" % [color, hex] +end + +map = COLOR_MAPS[$mapping] +colors = SOLARIZED_COLORS[$depth] + +map.each do |ansi, sol| + set_color ANSI_COLORS[ansi], colors[sol] +end diff --git a/solarized/vim/colors/solarized.vim b/solarized/vim/colors/solarized.vim new file mode 100644 index 0000000..70f5223 --- /dev/null +++ b/solarized/vim/colors/solarized.vim @@ -0,0 +1,1117 @@ +" Name: Solarized vim colorscheme +" Author: Ethan Schoonover +" URL: http://ethanschoonover.com/solarized +" (see this url for latest release & screenshots) +" License: OSI approved MIT license (see end of this file) +" Created: In the middle of the night +" Modified: 2011 May 05 +" +" Usage "{{{ +" +" --------------------------------------------------------------------- +" ABOUT: +" --------------------------------------------------------------------- +" Solarized is a carefully designed selective contrast colorscheme with dual +" light and dark modes that runs in both GUI, 256 and 16 color modes. +" +" See the homepage above for screenshots and details. +" +" --------------------------------------------------------------------- +" OPTIONS: +" --------------------------------------------------------------------- +" See the "solarized.txt" help file included with this colorscheme (in the +" "doc" subdirectory) for information on options, usage, the Toggle Background +" function and more. If you have already installed Solarized, this is available +" from the Solarized menu and command line as ":help solarized" +" +" --------------------------------------------------------------------- +" INSTALLATION: +" --------------------------------------------------------------------- +" Two options for installation: manual or pathogen +" +" MANUAL INSTALLATION OPTION: +" --------------------------------------------------------------------- +" +" 1. Download the solarized distribution (available on the homepage above) +" and unarchive the file. +" 2. Move `solarized.vim` to your `.vim/colors` directory. +" 3. Move each of the files in each subdirectories to the corresponding .vim +" subdirectory (e.g. autoload/togglebg.vim goes into your .vim/autoload +" directory as .vim/autoload/togglebg.vim). +" +" RECOMMENDED PATHOGEN INSTALLATION OPTION: +" --------------------------------------------------------------------- +" +" 1. Download and install Tim Pope's Pathogen from: +" https://github.com/tpope/vim-pathogen +" +" 2. Next, move or clone the `vim-colors-solarized` directory so that it is +" a subdirectory of the `.vim/bundle` directory. +" +" a. **clone with git:** +" +" $ cd ~/.vim/bundle +" $ git clone git://github.com/altercation/vim-colors-solarized.git +" +" b. **or move manually into the pathogen bundle directory:** +" In the parent directory of vim-colors-solarized: +" +" $ mv vim-colors-solarized ~/.vim/bundle/ +" +" MODIFY VIMRC: +" +" After either Option 1 or Option 2 above, put the following two lines in your +" .vimrc: +" +" syntax enable +" set background=dark +" colorscheme solarized +" +" or, for the light background mode of Solarized: +" +" syntax enable +" set background=light +" colorscheme solarized +" +" I like to have a different background in GUI and terminal modes, so I can use +" the following if-then. However, I find vim's background autodetection to be +" pretty good and, at least with MacVim, I can leave this background value +" assignment out entirely and get the same results. +" +" if has('gui_running') +" set background=light +" else +" set background=dark +" endif +" +" See the Solarized homepage at http://ethanschoonover.com/solarized for +" screenshots which will help you select either the light or dark background. +" +" --------------------------------------------------------------------- +" COLOR VALUES +" --------------------------------------------------------------------- +" Download palettes and files from: http://ethanschoonover.com/solarized +" +" L\*a\*b values are canonical (White D65, Reference D50), other values are +" matched in sRGB space. +" +" SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B sRGB HSB +" --------- ------- ---- ------- ----------- ---------- ----------- ----------- +" base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21 +" base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26 +" base01 #586e75 10/7 brgreen 240 #4e4e4e 45 -07 -07 88 110 117 194 25 46 +" base00 #657b83 11/7 bryellow 241 #585858 50 -07 -07 101 123 131 195 23 51 +" base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59 +" base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63 +" base2 #eee8d5 7/7 white 254 #d7d7af 92 -00 10 238 232 213 44 11 93 +" base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99 +" yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71 +" orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80 +" red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86 +" magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83 +" violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77 +" blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82 +" cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63 +" green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60 +" +" --------------------------------------------------------------------- +" COLORSCHEME HACKING +" --------------------------------------------------------------------- +" +" Useful commands for testing colorschemes: +" :source $VIMRUNTIME/syntax/hitest.vim +" :help highlight-groups +" :help cterm-colors +" :help group-name +" +" Useful links for developing colorschemes: +" http://www.vim.org/scripts/script.php?script_id=2937 +" http://vimcasts.org/episodes/creating-colorschemes-for-vim/ +" http://www.frexx.de/xterm-256-notes/" +" +" }}} +" Environment Specific Overrides "{{{ +" Allow or disallow certain features based on current terminal emulator or +" environment. + +" Terminals that support italics +let s:terms_italic=[ + \"rxvt", + \"gnome-terminal" + \] +" For reference only, terminals are known to be incomptible. +" Terminals that are in neither list need to be tested. +let s:terms_noitalic=[ + \"iTerm.app", + \"Apple_Terminal" + \] +if has("gui_running") + let s:terminal_italic=1 " TODO: could refactor to not require this at all +else + let s:terminal_italic=0 " terminals will be guilty until proven compatible + for term in s:terms_italic + if $TERM_PROGRAM =~ term + let s:terminal_italic=1 + endif + endfor +endif + +" }}} +" Default option values"{{{ +" --------------------------------------------------------------------- +" s:options_list is used to autogenerate a list of all non-default options +" using "call SolarizedOptions()" or with the "Generate .vimrc commands" +" Solarized menu option. See the "Menus" section below for the function itself. +let s:options_list=[ + \'" this block of commands has been autogenerated by solarized.vim and', + \'" includes the current, non-default Solarized option values.', + \'" To use, place these commands in your .vimrc file (replacing any', + \'" existing colorscheme commands). See also ":help solarized"', + \'', + \'" ------------------------------------------------------------------', + \'" Solarized Colorscheme Config', + \'" ------------------------------------------------------------------', + \] +let s:colorscheme_list=[ + \'syntax enable', + \'set background='.&background, + \'colorscheme solarized', + \] +let s:defaults_list=[ + \'" ------------------------------------------------------------------', + \'', + \'" The following items are available options, but do not need to be', + \'" included in your .vimrc as they are currently set to their defaults.', + \'' + \] +let s:lazycat_list=[ + \'" lazy method of appending this onto your .vimrc ":w! >> ~/.vimrc"', + \'" ------------------------------------------------------------------', + \] + +function! s:SetOption(name,default) + if type(a:default) == type(0) + let l:wrap='' + let l:ewrap='' + else + let l:wrap='"' + let l:ewrap='\"' + endif + if !exists("g:solarized_".a:name) || g:solarized_{a:name}==a:default + exe 'let g:solarized_'.a:name.'='.l:wrap.a:default.l:wrap.'"' + exe 'call add(s:defaults_list, "\" let g:solarized_'.a:name.'='.l:ewrap.g:solarized_{a:name}.l:ewrap.'")' + else + exe 'call add(s:options_list, "let g:solarized_'.a:name.'='.l:ewrap.g:solarized_{a:name}.l:ewrap.' \"default value is '.a:default.'")' + endif +endfunction + +if ($TERM_PROGRAM ==? "apple_terminal" && &t_Co < 256) + let s:solarized_termtrans_default = 1 +else + let s:solarized_termtrans_default = 0 +endif +call s:SetOption("termtrans",s:solarized_termtrans_default) +call s:SetOption("degrade",0) +call s:SetOption("bold",1) +call s:SetOption("underline",1) +call s:SetOption("italic",1) " note that we need to override this later if the terminal doesn't support +call s:SetOption("termcolors",16) +call s:SetOption("contrast","normal") +call s:SetOption("visibility","normal") +call s:SetOption("diffmode","normal") +call s:SetOption("hitrail",0) +call s:SetOption("menu",1) + +"}}} +" Colorscheme initialization "{{{ +" --------------------------------------------------------------------- +hi clear +if exists("syntax_on") + syntax reset +endif +let colors_name = "solarized" + +"}}} +" GUI & CSApprox hexadecimal palettes"{{{ +" --------------------------------------------------------------------- +" +" Set both gui and terminal color values in separate conditional statements +" Due to possibility that CSApprox is running (though I suppose we could just +" leave the hex values out entirely in that case and include only cterm colors) +" We also check to see if user has set solarized (force use of the +" neutral gray monotone palette component) +if (has("gui_running") && g:solarized_degrade == 0) + let s:vmode = "gui" + let s:base03 = "#002b36" + let s:base02 = "#073642" + let s:base01 = "#586e75" + let s:base00 = "#657b83" + let s:base0 = "#839496" + let s:base1 = "#93a1a1" + let s:base2 = "#eee8d5" + let s:base3 = "#fdf6e3" + let s:yellow = "#b58900" + let s:orange = "#cb4b16" + let s:red = "#dc322f" + let s:magenta = "#d33682" + let s:violet = "#6c71c4" + let s:blue = "#268bd2" + let s:cyan = "#2aa198" + "let s:green = "#859900" "original + let s:green = "#719e07" "experimental +elseif (has("gui_running") && g:solarized_degrade == 1) + " These colors are identical to the 256 color mode. They may be viewed + " while in gui mode via "let g:solarized_degrade=1", though this is not + " recommened and is for testing only. + let s:vmode = "gui" + let s:base03 = "#1c1c1c" + let s:base02 = "#262626" + let s:base01 = "#4e4e4e" + let s:base00 = "#585858" + let s:base0 = "#808080" + let s:base1 = "#8a8a8a" + let s:base2 = "#d7d7af" + let s:base3 = "#ffffd7" + let s:yellow = "#af8700" + let s:orange = "#d75f00" + let s:red = "#af0000" + let s:magenta = "#af005f" + let s:violet = "#5f5faf" + let s:blue = "#0087ff" + let s:cyan = "#00afaf" + let s:green = "#5f8700" +elseif g:solarized_termcolors != 256 && &t_Co >= 16 + let s:vmode = "cterm" + let s:base03 = "8" + let s:base02 = "0" + let s:base01 = "10" + let s:base00 = "11" + let s:base0 = "12" + let s:base1 = "14" + let s:base2 = "7" + let s:base3 = "15" + let s:yellow = "3" + let s:orange = "9" + let s:red = "1" + let s:magenta = "5" + let s:violet = "13" + let s:blue = "4" + let s:cyan = "6" + let s:green = "2" +elseif g:solarized_termcolors == 256 + let s:vmode = "cterm" + let s:base03 = "234" + let s:base02 = "235" + let s:base01 = "239" + let s:base00 = "240" + let s:base0 = "244" + let s:base1 = "245" + let s:base2 = "187" + let s:base3 = "230" + let s:yellow = "136" + let s:orange = "166" + let s:red = "124" + let s:magenta = "125" + let s:violet = "61" + let s:blue = "33" + let s:cyan = "37" + let s:green = "64" +else + let s:vmode = "cterm" + let s:bright = "* term=bold cterm=bold" +" let s:base03 = "0".s:bright +" let s:base02 = "0" +" let s:base01 = "2".s:bright +" let s:base00 = "3".s:bright +" let s:base0 = "4".s:bright +" let s:base1 = "6".s:bright +" let s:base2 = "7" +" let s:base3 = "7".s:bright +" let s:yellow = "3" +" let s:orange = "1".s:bright +" let s:red = "1" +" let s:magenta = "5" +" let s:violet = "5".s:bright +" let s:blue = "4" +" let s:cyan = "6" +" let s:green = "2" + let s:base03 = "DarkGray" " 0* + let s:base02 = "Black" " 0 + let s:base01 = "LightGreen" " 2* + let s:base00 = "LightYellow" " 3* + let s:base0 = "LightBlue" " 4* + let s:base1 = "LightCyan" " 6* + let s:base2 = "LightGray" " 7 + let s:base3 = "White" " 7* + let s:yellow = "DarkYellow" " 3 + let s:orange = "LightRed" " 1* + let s:red = "DarkRed" " 1 + let s:magenta = "DarkMagenta" " 5 + let s:violet = "LightMagenta" " 5* + let s:blue = "DarkBlue" " 4 + let s:cyan = "DarkCyan" " 6 + let s:green = "DarkGreen" " 2 + +endif +"}}} +" Formatting options and null values for passthrough effect "{{{ +" --------------------------------------------------------------------- + let s:none = "NONE" + let s:none = "NONE" + let s:t_none = "NONE" + let s:n = "NONE" + let s:c = ",undercurl" + let s:r = ",reverse" + let s:s = ",standout" + let s:ou = "" + let s:ob = "" +"}}} +" Background value based on termtrans setting "{{{ +" --------------------------------------------------------------------- +if (has("gui_running") || g:solarized_termtrans == 0) + let s:back = s:base03 +else + let s:back = "NONE" +endif +"}}} +" Alternate light scheme "{{{ +" --------------------------------------------------------------------- +if &background == "light" + let s:temp03 = s:base03 + let s:temp02 = s:base02 + let s:temp01 = s:base01 + let s:temp00 = s:base00 + let s:base03 = s:base3 + let s:base02 = s:base2 + let s:base01 = s:base1 + let s:base00 = s:base0 + let s:base0 = s:temp00 + let s:base1 = s:temp01 + let s:base2 = s:temp02 + let s:base3 = s:temp03 + if (s:back != "NONE") + let s:back = s:base03 + endif +endif +"}}} +" Optional contrast schemes "{{{ +" --------------------------------------------------------------------- +if g:solarized_contrast == "high" + let s:base01 = s:base00 + let s:base00 = s:base0 + let s:base0 = s:base1 + let s:base1 = s:base2 + let s:base2 = s:base3 + let s:back = s:back +endif +if g:solarized_contrast == "low" + let s:back = s:base02 + let s:ou = ",underline" +endif +"}}} +" Overrides dependent on user specified values and environment "{{{ +" --------------------------------------------------------------------- +if (g:solarized_bold == 0 || &t_Co == 8 ) + let s:b = "" + let s:bb = ",bold" +else + let s:b = ",bold" + let s:bb = "" +endif + +if g:solarized_underline == 0 + let s:u = "" +else + let s:u = ",underline" +endif + +if g:solarized_italic == 0 || s:terminal_italic == 0 + let s:i = "" +else + let s:i = ",italic" +endif +"}}} +" Highlighting primitives"{{{ +" --------------------------------------------------------------------- + +exe "let s:bg_none = ' ".s:vmode."bg=".s:none ."'" +exe "let s:bg_back = ' ".s:vmode."bg=".s:back ."'" +exe "let s:bg_base03 = ' ".s:vmode."bg=".s:base03 ."'" +exe "let s:bg_base02 = ' ".s:vmode."bg=".s:base02 ."'" +exe "let s:bg_base01 = ' ".s:vmode."bg=".s:base01 ."'" +exe "let s:bg_base00 = ' ".s:vmode."bg=".s:base00 ."'" +exe "let s:bg_base0 = ' ".s:vmode."bg=".s:base0 ."'" +exe "let s:bg_base1 = ' ".s:vmode."bg=".s:base1 ."'" +exe "let s:bg_base2 = ' ".s:vmode."bg=".s:base2 ."'" +exe "let s:bg_base3 = ' ".s:vmode."bg=".s:base3 ."'" +exe "let s:bg_green = ' ".s:vmode."bg=".s:green ."'" +exe "let s:bg_yellow = ' ".s:vmode."bg=".s:yellow ."'" +exe "let s:bg_orange = ' ".s:vmode."bg=".s:orange ."'" +exe "let s:bg_red = ' ".s:vmode."bg=".s:red ."'" +exe "let s:bg_magenta = ' ".s:vmode."bg=".s:magenta."'" +exe "let s:bg_violet = ' ".s:vmode."bg=".s:violet ."'" +exe "let s:bg_blue = ' ".s:vmode."bg=".s:blue ."'" +exe "let s:bg_cyan = ' ".s:vmode."bg=".s:cyan ."'" + +exe "let s:fg_none = ' ".s:vmode."fg=".s:none ."'" +exe "let s:fg_back = ' ".s:vmode."fg=".s:back ."'" +exe "let s:fg_base03 = ' ".s:vmode."fg=".s:base03 ."'" +exe "let s:fg_base02 = ' ".s:vmode."fg=".s:base02 ."'" +exe "let s:fg_base01 = ' ".s:vmode."fg=".s:base01 ."'" +exe "let s:fg_base00 = ' ".s:vmode."fg=".s:base00 ."'" +exe "let s:fg_base0 = ' ".s:vmode."fg=".s:base0 ."'" +exe "let s:fg_base1 = ' ".s:vmode."fg=".s:base1 ."'" +exe "let s:fg_base2 = ' ".s:vmode."fg=".s:base2 ."'" +exe "let s:fg_base3 = ' ".s:vmode."fg=".s:base3 ."'" +exe "let s:fg_green = ' ".s:vmode."fg=".s:green ."'" +exe "let s:fg_yellow = ' ".s:vmode."fg=".s:yellow ."'" +exe "let s:fg_orange = ' ".s:vmode."fg=".s:orange ."'" +exe "let s:fg_red = ' ".s:vmode."fg=".s:red ."'" +exe "let s:fg_magenta = ' ".s:vmode."fg=".s:magenta."'" +exe "let s:fg_violet = ' ".s:vmode."fg=".s:violet ."'" +exe "let s:fg_blue = ' ".s:vmode."fg=".s:blue ."'" +exe "let s:fg_cyan = ' ".s:vmode."fg=".s:cyan ."'" + +exe "let s:fmt_none = ' ".s:vmode."=NONE". " term=NONE". "'" +exe "let s:fmt_bold = ' ".s:vmode."=NONE".s:b. " term=NONE".s:b."'" +exe "let s:fmt_bldi = ' ".s:vmode."=NONE".s:b. " term=NONE".s:b."'" +exe "let s:fmt_undr = ' ".s:vmode."=NONE".s:u. " term=NONE".s:u."'" +exe "let s:fmt_undb = ' ".s:vmode."=NONE".s:u.s:b. " term=NONE".s:u.s:b."'" +exe "let s:fmt_undi = ' ".s:vmode."=NONE".s:u. " term=NONE".s:u."'" +exe "let s:fmt_uopt = ' ".s:vmode."=NONE".s:ou. " term=NONE".s:ou."'" +exe "let s:fmt_curl = ' ".s:vmode."=NONE".s:c. " term=NONE".s:c."'" +exe "let s:fmt_ital = ' ".s:vmode."=NONE".s:i. " term=NONE".s:i."'" +exe "let s:fmt_stnd = ' ".s:vmode."=NONE".s:s. " term=NONE".s:s."'" +exe "let s:fmt_revr = ' ".s:vmode."=NONE".s:r. " term=NONE".s:r."'" +exe "let s:fmt_revb = ' ".s:vmode."=NONE".s:r.s:b. " term=NONE".s:r.s:b."'" +" revbb (reverse bold for bright colors) is only set to actual bold in low +" color terminals (t_co=8, such as OS X Terminal.app) and should only be used +" with colors 8-15. +exe "let s:fmt_revbb = ' ".s:vmode."=NONE".s:r.s:bb. " term=NONE".s:r.s:bb."'" +exe "let s:fmt_revbbu = ' ".s:vmode."=NONE".s:r.s:bb.s:u." term=NONE".s:r.s:bb.s:u."'" + +if has("gui_running") + exe "let s:sp_none = ' guisp=".s:none ."'" + exe "let s:sp_back = ' guisp=".s:back ."'" + exe "let s:sp_base03 = ' guisp=".s:base03 ."'" + exe "let s:sp_base02 = ' guisp=".s:base02 ."'" + exe "let s:sp_base01 = ' guisp=".s:base01 ."'" + exe "let s:sp_base00 = ' guisp=".s:base00 ."'" + exe "let s:sp_base0 = ' guisp=".s:base0 ."'" + exe "let s:sp_base1 = ' guisp=".s:base1 ."'" + exe "let s:sp_base2 = ' guisp=".s:base2 ."'" + exe "let s:sp_base3 = ' guisp=".s:base3 ."'" + exe "let s:sp_green = ' guisp=".s:green ."'" + exe "let s:sp_yellow = ' guisp=".s:yellow ."'" + exe "let s:sp_orange = ' guisp=".s:orange ."'" + exe "let s:sp_red = ' guisp=".s:red ."'" + exe "let s:sp_magenta = ' guisp=".s:magenta."'" + exe "let s:sp_violet = ' guisp=".s:violet ."'" + exe "let s:sp_blue = ' guisp=".s:blue ."'" + exe "let s:sp_cyan = ' guisp=".s:cyan ."'" +else + let s:sp_none = "" + let s:sp_back = "" + let s:sp_base03 = "" + let s:sp_base02 = "" + let s:sp_base01 = "" + let s:sp_base00 = "" + let s:sp_base0 = "" + let s:sp_base1 = "" + let s:sp_base2 = "" + let s:sp_base3 = "" + let s:sp_green = "" + let s:sp_yellow = "" + let s:sp_orange = "" + let s:sp_red = "" + let s:sp_magenta = "" + let s:sp_violet = "" + let s:sp_blue = "" + let s:sp_cyan = "" +endif + +"}}} +" Basic highlighting"{{{ +" --------------------------------------------------------------------- +" note that link syntax to avoid duplicate configuration doesn't work with the +" exe compiled formats + +exe "hi! Normal" .s:fmt_none .s:fg_base0 .s:bg_back + +exe "hi! Comment" .s:fmt_ital .s:fg_base01 .s:bg_none +" *Comment any comment + +exe "hi! Constant" .s:fmt_none .s:fg_cyan .s:bg_none +" *Constant any constant +" String a string constant: "this is a string" +" Character a character constant: 'c', '\n' +" Number a number constant: 234, 0xff +" Boolean a boolean constant: TRUE, false +" Float a floating point constant: 2.3e10 + +exe "hi! Identifier" .s:fmt_none .s:fg_blue .s:bg_none +" *Identifier any variable name +" Function function name (also: methods for classes) +" +exe "hi! Statement" .s:fmt_none .s:fg_green .s:bg_none +" *Statement any statement +" Conditional if, then, else, endif, switch, etc. +" Repeat for, do, while, etc. +" Label case, default, etc. +" Operator "sizeof", "+", "*", etc. +" Keyword any other keyword +" Exception try, catch, throw + +exe "hi! PreProc" .s:fmt_none .s:fg_orange .s:bg_none +" *PreProc generic Preprocessor +" Include preprocessor #include +" Define preprocessor #define +" Macro same as Define +" PreCondit preprocessor #if, #else, #endif, etc. + +exe "hi! Type" .s:fmt_none .s:fg_yellow .s:bg_none +" *Type int, long, char, etc. +" StorageClass static, register, volatile, etc. +" Structure struct, union, enum, etc. +" Typedef A typedef + +exe "hi! Special" .s:fmt_none .s:fg_red .s:bg_none +" *Special any special symbol +" SpecialChar special character in a constant +" Tag you can use CTRL-] on this +" Delimiter character that needs attention +" SpecialComment special things inside a comment +" Debug debugging statements + +exe "hi! Underlined" .s:fmt_none .s:fg_violet .s:bg_none +" *Underlined text that stands out, HTML links + +exe "hi! Ignore" .s:fmt_none .s:fg_none .s:bg_none +" *Ignore left blank, hidden |hl-Ignore| + +exe "hi! Error" .s:fmt_bold .s:fg_red .s:bg_none +" *Error any erroneous construct + +exe "hi! Todo" .s:fmt_bold .s:fg_magenta.s:bg_none +" *Todo anything that needs extra attention; mostly the +" keywords TODO FIXME and XXX +" +"}}} +" Extended highlighting "{{{ +" --------------------------------------------------------------------- +if (g:solarized_visibility=="high") + exe "hi! SpecialKey" .s:fmt_revr .s:fg_red .s:bg_none + exe "hi! NonText" .s:fmt_bold .s:fg_red .s:bg_none +elseif (g:solarized_visibility=="low") + exe "hi! SpecialKey" .s:fmt_bold .s:fg_base02 .s:bg_none + exe "hi! NonText" .s:fmt_bold .s:fg_base02 .s:bg_none +else + exe "hi! SpecialKey" .s:fmt_bold .s:fg_base00 .s:bg_base02 + exe "hi! NonText" .s:fmt_bold .s:fg_base00 .s:bg_none +endif +exe "hi! StatusLine" .s:fmt_none .s:fg_base1 .s:bg_base02 .s:fmt_revbb +exe "hi! StatusLineNC" .s:fmt_none .s:fg_base00 .s:bg_base02 .s:fmt_revbb +exe "hi! Visual" .s:fmt_none .s:fg_base01 .s:bg_base03 .s:fmt_revbb +exe "hi! Directory" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! ErrorMsg" .s:fmt_revr .s:fg_red .s:bg_none +exe "hi! IncSearch" .s:fmt_stnd .s:fg_orange .s:bg_none +exe "hi! Search" .s:fmt_revr .s:fg_yellow .s:bg_none +exe "hi! MoreMsg" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! ModeMsg" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! LineNr" .s:fmt_none .s:fg_base01 .s:bg_base02 +exe "hi! Question" .s:fmt_bold .s:fg_cyan .s:bg_none +if ( has("gui_running") || &t_Co > 8 ) + exe "hi! VertSplit" .s:fmt_none .s:fg_base00 .s:bg_base00 +else + exe "hi! VertSplit" .s:fmt_revbb .s:fg_base00 .s:bg_base02 +endif +exe "hi! Title" .s:fmt_bold .s:fg_orange .s:bg_none +exe "hi! VisualNOS" .s:fmt_stnd .s:fg_none .s:bg_base02 .s:fmt_revbb +exe "hi! WarningMsg" .s:fmt_bold .s:fg_red .s:bg_none +exe "hi! WildMenu" .s:fmt_none .s:fg_base2 .s:bg_base02 .s:fmt_revbb +exe "hi! Folded" .s:fmt_undb .s:fg_base0 .s:bg_base02 .s:sp_base03 +exe "hi! FoldColumn" .s:fmt_none .s:fg_base0 .s:bg_base02 +if (g:solarized_diffmode=="high") +exe "hi! DiffAdd" .s:fmt_revr .s:fg_green .s:bg_none +exe "hi! DiffChange" .s:fmt_revr .s:fg_yellow .s:bg_none +exe "hi! DiffDelete" .s:fmt_revr .s:fg_red .s:bg_none +exe "hi! DiffText" .s:fmt_revr .s:fg_blue .s:bg_none +elseif (g:solarized_diffmode=="low") +exe "hi! DiffAdd" .s:fmt_undr .s:fg_green .s:bg_none .s:sp_green +exe "hi! DiffChange" .s:fmt_undr .s:fg_yellow .s:bg_none .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_bold .s:fg_red .s:bg_none +exe "hi! DiffText" .s:fmt_undr .s:fg_blue .s:bg_none .s:sp_blue +else " normal + if has("gui_running") +exe "hi! DiffAdd" .s:fmt_bold .s:fg_green .s:bg_base02 .s:sp_green +exe "hi! DiffChange" .s:fmt_bold .s:fg_yellow .s:bg_base02 .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_bold .s:fg_red .s:bg_base02 +exe "hi! DiffText" .s:fmt_bold .s:fg_blue .s:bg_base02 .s:sp_blue + else +exe "hi! DiffAdd" .s:fmt_none .s:fg_green .s:bg_base02 .s:sp_green +exe "hi! DiffChange" .s:fmt_none .s:fg_yellow .s:bg_base02 .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_none .s:fg_red .s:bg_base02 +exe "hi! DiffText" .s:fmt_none .s:fg_blue .s:bg_base02 .s:sp_blue + endif +endif +exe "hi! SignColumn" .s:fmt_none .s:fg_base0 +exe "hi! Conceal" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! SpellBad" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_red +exe "hi! SpellCap" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_violet +exe "hi! SpellRare" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_cyan +exe "hi! SpellLocal" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_yellow +exe "hi! Pmenu" .s:fmt_none .s:fg_base0 .s:bg_base02 .s:fmt_revbb +exe "hi! PmenuSel" .s:fmt_none .s:fg_base01 .s:bg_base2 .s:fmt_revbb +exe "hi! PmenuSbar" .s:fmt_none .s:fg_base2 .s:bg_base0 .s:fmt_revbb +exe "hi! PmenuThumb" .s:fmt_none .s:fg_base0 .s:bg_base03 .s:fmt_revbb +exe "hi! TabLine" .s:fmt_undr .s:fg_base0 .s:bg_base02 .s:sp_base0 +exe "hi! TabLineFill" .s:fmt_undr .s:fg_base0 .s:bg_base02 .s:sp_base0 +exe "hi! TabLineSel" .s:fmt_undr .s:fg_base01 .s:bg_base2 .s:sp_base0 .s:fmt_revbbu +exe "hi! CursorColumn" .s:fmt_none .s:fg_none .s:bg_base02 +exe "hi! CursorLine" .s:fmt_uopt .s:fg_none .s:bg_base02 .s:sp_base1 +exe "hi! ColorColumn" .s:fmt_none .s:fg_none .s:bg_base02 +exe "hi! Cursor" .s:fmt_none .s:fg_base03 .s:bg_base0 +hi! link lCursor Cursor +exe "hi! MatchParen" .s:fmt_bold .s:fg_red .s:bg_base01 + +"}}} +" vim syntax highlighting "{{{ +" --------------------------------------------------------------------- +"exe "hi! vimLineComment" . s:fg_base01 .s:bg_none .s:fmt_ital +"hi! link vimComment Comment +"hi! link vimLineComment Comment +hi! link vimVar Identifier +hi! link vimFunc Function +hi! link vimUserFunc Function +hi! link helpSpecial Special +hi! link vimSet Normal +hi! link vimSetEqual Normal +exe "hi! vimCommentString" .s:fmt_none .s:fg_violet .s:bg_none +exe "hi! vimCommand" .s:fmt_none .s:fg_yellow .s:bg_none +exe "hi! vimCmdSep" .s:fmt_bold .s:fg_blue .s:bg_none +exe "hi! helpExample" .s:fmt_none .s:fg_base1 .s:bg_none +exe "hi! helpOption" .s:fmt_none .s:fg_cyan .s:bg_none +exe "hi! helpNote" .s:fmt_none .s:fg_magenta.s:bg_none +exe "hi! helpVim" .s:fmt_none .s:fg_magenta.s:bg_none +exe "hi! helpHyperTextJump" .s:fmt_undr .s:fg_blue .s:bg_none +exe "hi! helpHyperTextEntry".s:fmt_none .s:fg_green .s:bg_none +exe "hi! vimIsCommand" .s:fmt_none .s:fg_base00 .s:bg_none +exe "hi! vimSynMtchOpt" .s:fmt_none .s:fg_yellow .s:bg_none +exe "hi! vimSynType" .s:fmt_none .s:fg_cyan .s:bg_none +exe "hi! vimHiLink" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! vimHiGroup" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! vimGroup" .s:fmt_undb .s:fg_blue .s:bg_none +"}}} +" diff highlighting "{{{ +" --------------------------------------------------------------------- +hi! link diffAdded Statement +hi! link diffLine Identifier +"}}} +" git & gitcommit highlighting "{{{ +"git +"exe "hi! gitDateHeader" +"exe "hi! gitIdentityHeader" +"exe "hi! gitIdentityKeyword" +"exe "hi! gitNotesHeader" +"exe "hi! gitReflogHeader" +"exe "hi! gitKeyword" +"exe "hi! gitIdentity" +"exe "hi! gitEmailDelimiter" +"exe "hi! gitEmail" +"exe "hi! gitDate" +"exe "hi! gitMode" +"exe "hi! gitHashAbbrev" +"exe "hi! gitHash" +"exe "hi! gitReflogMiddle" +"exe "hi! gitReference" +"exe "hi! gitStage" +"exe "hi! gitType" +"exe "hi! gitDiffAdded" +"exe "hi! gitDiffRemoved" +"gitcommit +"exe "hi! gitcommitSummary" +exe "hi! gitcommitComment" .s:fmt_ital .s:fg_base01 .s:bg_none +hi! link gitcommitUntracked gitcommitComment +hi! link gitcommitDiscarded gitcommitComment +hi! link gitcommitSelected gitcommitComment +exe "hi! gitcommitUnmerged" .s:fmt_bold .s:fg_green .s:bg_none +exe "hi! gitcommitOnBranch" .s:fmt_bold .s:fg_base01 .s:bg_none +exe "hi! gitcommitBranch" .s:fmt_bold .s:fg_magenta .s:bg_none +hi! link gitcommitNoBranch gitcommitBranch +exe "hi! gitcommitDiscardedType".s:fmt_none .s:fg_red .s:bg_none +exe "hi! gitcommitSelectedType" .s:fmt_none .s:fg_green .s:bg_none +"exe "hi! gitcommitUnmergedType" +"exe "hi! gitcommitType" +"exe "hi! gitcommitNoChanges" +"exe "hi! gitcommitHeader" +exe "hi! gitcommitHeader" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! gitcommitUntrackedFile".s:fmt_bold .s:fg_cyan .s:bg_none +exe "hi! gitcommitDiscardedFile".s:fmt_bold .s:fg_red .s:bg_none +exe "hi! gitcommitSelectedFile" .s:fmt_bold .s:fg_green .s:bg_none +exe "hi! gitcommitUnmergedFile" .s:fmt_bold .s:fg_yellow .s:bg_none +exe "hi! gitcommitFile" .s:fmt_bold .s:fg_base0 .s:bg_none +hi! link gitcommitDiscardedArrow gitcommitDiscardedFile +hi! link gitcommitSelectedArrow gitcommitSelectedFile +hi! link gitcommitUnmergedArrow gitcommitUnmergedFile +"exe "hi! gitcommitArrow" +"exe "hi! gitcommitOverflow" +"exe "hi! gitcommitBlank" +" }}} +" html highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! htmlTag" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! htmlEndTag" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! htmlTagN" .s:fmt_bold .s:fg_base1 .s:bg_none +exe "hi! htmlTagName" .s:fmt_bold .s:fg_blue .s:bg_none +exe "hi! htmlSpecialTagName".s:fmt_ital .s:fg_blue .s:bg_none +exe "hi! htmlArg" .s:fmt_none .s:fg_base00 .s:bg_none +exe "hi! javaScript" .s:fmt_none .s:fg_yellow .s:bg_none +"}}} +" perl highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! perlHereDoc" . s:fg_base1 .s:bg_back .s:fmt_none +exe "hi! perlVarPlain" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! perlStatementFileDesc". s:fg_cyan.s:bg_back.s:fmt_none + +"}}} +" tex highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! texStatement" . s:fg_cyan .s:bg_back .s:fmt_none +exe "hi! texMathZoneX" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texMathMatcher" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texMathMatcher" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texRefLabel" . s:fg_yellow .s:bg_back .s:fmt_none +"}}} +" ruby highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! rubyDefine" . s:fg_base1 .s:bg_back .s:fmt_bold +"rubyInclude +"rubySharpBang +"rubyAccess +"rubyPredefinedVariable +"rubyBoolean +"rubyClassVariable +"rubyBeginEnd +"rubyRepeatModifier +"hi! link rubyArrayDelimiter Special " [ , , ] +"rubyCurlyBlock { , , } + +"hi! link rubyClass Keyword +"hi! link rubyModule Keyword +"hi! link rubyKeyword Keyword +"hi! link rubyOperator Operator +"hi! link rubyIdentifier Identifier +"hi! link rubyInstanceVariable Identifier +"hi! link rubyGlobalVariable Identifier +"hi! link rubyClassVariable Identifier +"hi! link rubyConstant Type +"}}} +" haskell syntax highlighting"{{{ +" --------------------------------------------------------------------- +" For use with syntax/haskell.vim : Haskell Syntax File +" http://www.vim.org/scripts/script.php?script_id=3034 +" See also Steffen Siering's github repository: +" http://github.com/urso/dotrc/blob/master/vim/syntax/haskell.vim +" --------------------------------------------------------------------- +" +" Treat True and False specially, see the plugin referenced above +let hs_highlight_boolean=1 +" highlight delims, see the plugin referenced above +let hs_highlight_delimiters=1 + +exe "hi! cPreCondit". s:fg_orange.s:bg_none .s:fmt_none + +exe "hi! VarId" . s:fg_blue .s:bg_none .s:fmt_none +exe "hi! ConId" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hsImport" . s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! hsString" . s:fg_base00 .s:bg_none .s:fmt_none + +exe "hi! hsStructure" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hs_hlFunctionName" . s:fg_blue .s:bg_none +exe "hi! hsStatement" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsImportLabel" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hs_OpFunctionName" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hs_DeclareFunction" . s:fg_orange .s:bg_none .s:fmt_none +exe "hi! hsVarSym" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsType" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hsTypedef" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsModuleName" . s:fg_green .s:bg_none .s:fmt_undr +exe "hi! hsModuleStartLabel" . s:fg_magenta.s:bg_none .s:fmt_none +hi! link hsImportParams Delimiter +hi! link hsDelimTypeExport Delimiter +hi! link hsModuleStartLabel hsStructure +hi! link hsModuleWhereLabel hsModuleStartLabel + +" following is for the haskell-conceal plugin +" the first two items don't have an impact, but better safe +exe "hi! hsNiceOperator" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsniceoperator" . s:fg_cyan .s:bg_none .s:fmt_none + +"}}} +" pandoc markdown syntax highlighting "{{{ +" --------------------------------------------------------------------- + +"PandocHiLink pandocNormalBlock +exe "hi! pandocTitleBlock" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocTitleBlockTitle" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocTitleComment" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocComment" .s:fg_base01 .s:bg_none .s:fmt_ital +exe "hi! pandocVerbatimBlock" .s:fg_yellow .s:bg_none .s:fmt_none +hi! link pandocVerbatimBlockDeep pandocVerbatimBlock +hi! link pandocCodeBlock pandocVerbatimBlock +hi! link pandocCodeBlockDelim pandocVerbatimBlock +exe "hi! pandocBlockQuote" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader1" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader2" .s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader3" .s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader4" .s:fg_red .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader5" .s:fg_base0 .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader6" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocListMarker" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocListReference" .s:fg_magenta.s:bg_none .s:fmt_undr + +" Definitions +" --------------------------------------------------------------------- +let s:fg_pdef = s:fg_violet +exe "hi! pandocDefinitionBlock" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocDefinitionTerm" .s:fg_pdef .s:bg_none .s:fmt_stnd +exe "hi! pandocDefinitionIndctr" .s:fg_pdef .s:bg_none .s:fmt_bold +exe "hi! pandocEmphasisDefinition" .s:fg_pdef .s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNestedDefinition" .s:fg_pdef .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisDefinition" .s:fg_pdef .s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNestedDefinition" .s:fg_pdef.s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisDefinition" .s:fg_pdef.s:bg_none.s:fmt_bldi +exe "hi! pandocStrikeoutDefinition" .s:fg_pdef .s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInlineDefinition" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocSuperscriptDefinition" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocSubscriptDefinition" .s:fg_pdef .s:bg_none .s:fmt_none + +" Tables +" --------------------------------------------------------------------- +let s:fg_ptable = s:fg_blue +exe "hi! pandocTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocTableStructure" .s:fg_ptable.s:bg_none .s:fmt_none +hi! link pandocTableStructureTop pandocTableStructre +hi! link pandocTableStructureEnd pandocTableStructre +exe "hi! pandocTableZebraLight" .s:fg_ptable.s:bg_base03.s:fmt_none +exe "hi! pandocTableZebraDark" .s:fg_ptable.s:bg_base02.s:fmt_none +exe "hi! pandocEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNestedTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNestedTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrikeoutTable" .s:fg_ptable.s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInlineTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocSuperscriptTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocSubscriptTable" .s:fg_ptable.s:bg_none .s:fmt_none + +" Headings +" --------------------------------------------------------------------- +let s:fg_phead = s:fg_orange +exe "hi! pandocHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocHeadingMarker" .s:fg_yellow.s:bg_none.s:fmt_bold +exe "hi! pandocEmphasisHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocEmphasisNestedHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocStrongEmphasisNestedHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisHeading".s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrikeoutHeading" .s:fg_phead .s:bg_none.s:fmt_revr +exe "hi! pandocVerbatimInlineHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocSuperscriptHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocSubscriptHeading" .s:fg_phead .s:bg_none.s:fmt_bold + +" Links +" --------------------------------------------------------------------- +exe "hi! pandocLinkDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocLinkLabel" .s:fg_blue .s:bg_none .s:fmt_undr +exe "hi! pandocLinkText" .s:fg_blue .s:bg_none .s:fmt_undb +exe "hi! pandocLinkURL" .s:fg_base00 .s:bg_none .s:fmt_undr +exe "hi! pandocLinkTitle" .s:fg_base00 .s:bg_none .s:fmt_undi +exe "hi! pandocLinkTitleDelim" .s:fg_base01 .s:bg_none .s:fmt_undi .s:sp_base00 +exe "hi! pandocLinkDefinition" .s:fg_cyan .s:bg_none .s:fmt_undr .s:sp_base00 +exe "hi! pandocLinkDefinitionID" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocImageCaption" .s:fg_violet .s:bg_none .s:fmt_undb +exe "hi! pandocFootnoteLink" .s:fg_green .s:bg_none .s:fmt_undr +exe "hi! pandocFootnoteDefLink" .s:fg_green .s:bg_none .s:fmt_bold +exe "hi! pandocFootnoteInline" .s:fg_green .s:bg_none .s:fmt_undb +exe "hi! pandocFootnote" .s:fg_green .s:bg_none .s:fmt_none +exe "hi! pandocCitationDelim" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocCitation" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocCitationID" .s:fg_magenta.s:bg_none .s:fmt_undr +exe "hi! pandocCitationRef" .s:fg_magenta.s:bg_none .s:fmt_none + +" Main Styles +" --------------------------------------------------------------------- +exe "hi! pandocStyleDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocEmphasis" .s:fg_base0 .s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNested" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasis" .s:fg_base0 .s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNested" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasis" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrikeout" .s:fg_base01 .s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInline" .s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! pandocSuperscript" .s:fg_violet .s:bg_none .s:fmt_none +exe "hi! pandocSubscript" .s:fg_violet .s:bg_none .s:fmt_none + +exe "hi! pandocRule" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocRuleLine" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocEscapePair" .s:fg_red .s:bg_none .s:fmt_bold +exe "hi! pandocCitationRef" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocNonBreakingSpace" . s:fg_red .s:bg_none .s:fmt_revr +hi! link pandocEscapedCharacter pandocEscapePair +hi! link pandocLineBreak pandocEscapePair + +" Embedded Code +" --------------------------------------------------------------------- +exe "hi! pandocMetadataDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocMetadata" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocMetadataKey" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocMetadata" .s:fg_blue .s:bg_none .s:fmt_bold +hi! link pandocMetadataTitle pandocMetadata + +"}}} +" Utility autocommand "{{{ +" --------------------------------------------------------------------- +" In cases where Solarized is initialized inside a terminal vim session and +" then transferred to a gui session via the command `:gui`, the gui vim process +" does not re-read the colorscheme (or .vimrc for that matter) so any `has_gui` +" related code that sets gui specific values isn't executed. +" +" Currently, Solarized sets only the cterm or gui values for the colorscheme +" depending on gui or terminal mode. It's possible that, if the following +" autocommand method is deemed excessively poor form, that approach will be +" used again and the autocommand below will be dropped. +" +" However it seems relatively benign in this case to include the autocommand +" here. It fires only in cases where vim is transferring from terminal to gui +" mode (detected with the script scope s:vmode variable). It also allows for +" other potential terminal customizations that might make gui mode suboptimal. +" +autocmd GUIEnter * if (s:vmode != "gui") | exe "colorscheme " . g:colors_name | endif +"}}} +" Highlight Trailing Space {{{ +" Experimental: Different highlight when on cursorline +function! s:SolarizedHiTrail() + if g:solarized_hitrail==0 + hi! clear solarizedTrailingSpace + else + syn match solarizedTrailingSpace "\s*$" + exe "hi! solarizedTrailingSpace " .s:fmt_undr .s:fg_red .s:bg_none .s:sp_red + endif +endfunction +augroup SolarizedHiTrail + autocmd! + if g:solarized_hitrail==1 + autocmd! Syntax * call s:SolarizedHiTrail() + autocmd! ColorScheme * if g:colors_name == "solarized" | call s:SolarizedHiTrail() | else | augroup! s:SolarizedHiTrail | endif + endif +augroup END +" }}} +" Menus "{{{ +" --------------------------------------------------------------------- +" Turn off Solarized menu by including the following assignment in your .vimrc: +" +" let g:solarized_menu=0 + +function! s:SolarizedOptions() + new "new buffer + setf vim "vim filetype + let failed = append(0, s:defaults_list) + let failed = append(0, s:colorscheme_list) + let failed = append(0, s:options_list) + let failed = append(0, s:lazycat_list) + 0 "jump back to the top +endfunction +if !exists(":SolarizedOptions") + command SolarizedOptions :call s:SolarizedOptions() +endif + +function! SolarizedMenu() + if exists("g:loaded_solarized_menu") + try + silent! aunmenu Solarized + endtry + endif + let g:loaded_solarized_menu = 1 + + if g:colors_name == "solarized" && g:solarized_menu != 0 + + amenu &Solarized.&Contrast.&Low\ Contrast :let g:solarized_contrast="low" \| colorscheme solarized + amenu &Solarized.&Contrast.&Normal\ Contrast :let g:solarized_contrast="normal" \| colorscheme solarized + amenu &Solarized.&Contrast.&High\ Contrast :let g:solarized_contrast="high" \| colorscheme solarized + an &Solarized.&Contrast.-sep- + amenu &Solarized.&Contrast.&Help:\ Contrast :help 'solarized_contrast' + + amenu &Solarized.&Visibility.&Low\ Visibility :let g:solarized_visibility="low" \| colorscheme solarized + amenu &Solarized.&Visibility.&Normal\ Visibility :let g:solarized_visibility="normal" \| colorscheme solarized + amenu &Solarized.&Visibility.&High\ Visibility :let g:solarized_visibility="high" \| colorscheme solarized + an &Solarized.&Visibility.-sep- + amenu &Solarized.&Visibility.&Help:\ Visibility :help 'solarized_visibility' + + amenu &Solarized.&Background.&Toggle\ Background :ToggleBG + amenu &Solarized.&Background.&Dark\ Background :set background=dark \| colorscheme solarized + amenu &Solarized.&Background.&Light\ Background :set background=light \| colorscheme solarized + an &Solarized.&Background.-sep- + amenu &Solarized.&Background.&Help:\ ToggleBG :help togglebg + + if g:solarized_bold==0 | let l:boldswitch="On" | else | let l:boldswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Bold\\ ".l:boldswitch." :let g:solarized_bold=(abs(g:solarized_bold-1)) \\| colorscheme solarized" + if g:solarized_italic==0 | let l:italicswitch="On" | else | let l:italicswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Italic\\ ".l:italicswitch." :let g:solarized_italic=(abs(g:solarized_italic-1)) \\| colorscheme solarized" + if g:solarized_underline==0 | let l:underlineswitch="On" | else | let l:underlineswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Underline\\ ".l:underlineswitch." :let g:solarized_underline=(abs(g:solarized_underline-1)) \\| colorscheme solarized" + + amenu &Solarized.&Diff\ Mode.&Low\ Diff\ Mode :let g:solarized_diffmode="low" \| colorscheme solarized + amenu &Solarized.&Diff\ Mode.&Normal\ Diff\ Mode :let g:solarized_diffmode="normal" \| colorscheme solarized + amenu &Solarized.&Diff\ Mode.&High\ Diff\ Mode :let g:solarized_diffmode="high" \| colorscheme solarized + + if g:solarized_hitrail==0 | let l:hitrailswitch="On" | else | let l:hitrailswitch="Off" | endif + exe "amenu &Solarized.&Experimental.&Turn\\ Highlight\\ Trailing\\ Spaces\\ ".l:hitrailswitch." :let g:solarized_hitrail=(abs(g:solarized_hitrail-1)) \\| colorscheme solarized" + an &Solarized.&Experimental.-sep- + amenu &Solarized.&Experimental.&Help:\ HiTrail :help 'solarized_hitrail' + + an &Solarized.-sep1- + + amenu &Solarized.&Autogenerate\ options :SolarizedOptions + + an &Solarized.-sep2- + + amenu &Solarized.&Help.&Solarized\ Help :help solarized + amenu &Solarized.&Help.&Toggle\ Background\ Help :help togglebg + amenu &Solarized.&Help.&Removing\ This\ Menu :help solarized-menu + + an 9999.77 &Help.&Solarized\ Colorscheme :help solarized + an 9999.78 &Help.&Toggle\ Background :help togglebg + an 9999.79 &Help.-sep3- + + endif +endfunction + +autocmd ColorScheme * if g:colors_name != "solarized" | silent! aunmenu Solarized | else | call SolarizedMenu() | endif + +"}}} +" License "{{{ +" --------------------------------------------------------------------- +" +" Copyright (c) 2011 Ethan Schoonover +" +" 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. +" +" vim:foldmethod=marker:foldlevel=0 +"}}} diff --git a/solarized/vim/plugin/solarized.vim b/solarized/vim/plugin/solarized.vim new file mode 100644 index 0000000..b02b4dc --- /dev/null +++ b/solarized/vim/plugin/solarized.vim @@ -0,0 +1,7 @@ +" local vim settings + +" enable solarized colors +set t_Co=16 +let g:solarized_termcolors=16 +"let g:solarized_visibility="high" +colorscheme solarized diff --git a/solarized/zsh/rc.d/solarized b/solarized/zsh/rc.d/solarized new file mode 100644 index 0000000..2fc321f --- /dev/null +++ b/solarized/zsh/rc.d/solarized @@ -0,0 +1,21 @@ +# Solarized colors + +# set solarized color scheme +echo -ne '\e]10;#657B83\a' # Foreground -> base00 +echo -ne '\e]11;#002B36\a' # Background -> base03 +echo -ne '\e]12;#93A1A1\a' # Cursor -> base1 +echo -ne '\e]4;1;#DC322F\a' # red +echo -ne '\e]4;2;#859900\a' # green +echo -ne '\e]4;3;#B58900\a' # yellow +echo -ne '\e]4;4;#268BD2\a' # blue +echo -ne '\e]4;5;#D33682\a' # magenta +echo -ne '\e]4;6;#2AA198\a' # cyan +echo -ne '\e]4;7;#EEE8D5\a' # white (light grey really) -> Base2 +echo -ne '\e]4;8;#002B36\a' # bold black (i.e. dark grey -> Base03) +echo -ne '\e]4;9;#CB4B16\a' # bold red -> orange +echo -ne '\e]4;10;#586E75\a' # bold green -> base01 +echo -ne '\e]4;11;#657B83\a' # bold yellow -> base00 +echo -ne '\e]4;12;#839496\a' # bold blue -> base0 +echo -ne '\e]4;13;#6C71C4\a' # bold magenta -> violet +echo -ne '\e]4;14;#93A1A1\a' # bold cyan -> base1 +echo -ne '\e]4;15;#FDFDE3\a' # bold white -> Base3 diff --git a/synergy/connect-desktop b/synergy/connect-desktop new file mode 100755 index 0000000..ab22d24 --- /dev/null +++ b/synergy/connect-desktop @@ -0,0 +1,36 @@ +#!/bin/sh + +##### Configuration ##### + +synergy_addr="127.0.0.1" +synergy_port=24800 +synergy_dir="util/synergy" + +client_name="laptop" +client_log="synergyc.log" + +server_name="desktop" +server_host="greglook-1.desktop.amazon.com" + + + +##### Connection ##### + +ssh_opts="-nf -L ${synergy_port}:${synergy_addr}:${synergy_port} ${server_host}" + +if [[ -n $(ps aux | grep synergyc | grep -v grep) ]]; then + echo "Killing running Synergy client..." + killall synergyc +fi + +if [[ -n $(ps aux | egrep "ssh ${ssh_opts}" | grep -v grep) ]]; then + echo "Killing extant Synergy connections..." + ps auxwww | grep "ssh ${ssh_opts}" | awk '{print $2}' | xargs kill +fi + +echo "Connecting to remote host..." +ssh ${ssh_opts} "cd ~/${synergy_dir} && ./start-server" +sleep 5 + +echo "Starting Synergy client..." +synergyc -f --debug DEBUG --name ${client_name} ${synergy_addr}:${synergy_port} > $HOME/${synergy_dir}/${client_log} 2>&1 & diff --git a/synergy/start-server b/synergy/start-server new file mode 100755 index 0000000..0fc0eaa --- /dev/null +++ b/synergy/start-server @@ -0,0 +1,14 @@ +#!/bin/sh + +# change to synergy directory +#cd $(dirname $(readlink -f $0)) + +# kill any old servers +if [[ -n $(ps aux | grep synergys | grep -v grep) ]]; then + echo "Killing old detached server..." + killall synergys + sleep 3 +fi + +echo "Starting Synergy server..." +synergys -f --config synergy.conf --name desktop --debug NOTE > synergys.log 2>&1 diff --git a/tmux/util/tmux/clojure.sh b/tmux/util/tmux/clojure.sh new file mode 100755 index 0000000..6c73c16 --- /dev/null +++ b/tmux/util/tmux/clojure.sh @@ -0,0 +1,52 @@ +#!/bin/zsh + +# Initialize a tmux workspace session for a Clojure project. The first argument +# should be an absolute path to the project's root directory. The session name +# defaults to the project directory name. If a namespace is given, the src and +# test editor panes will be started in the respective nested directories. + +if [[ -z "$1" ]]; then + echo "Usage: $0 [session name] [code namespace]" + exit 1 +fi + +PROJECT_ROOT=$1 +SESSION=${2:-$(basename $PROJECT_ROOT)} +NAMESPACE=$(echo $3 | tr '.-' '/_') + +# Don't run inside tmux! +if [[ -n "$TMUX" ]]; then + echo "Workspace must be set up from outside tmux!" + exit 1 +fi + +# Check if session already exists. +if tmux has-session -t $SESSION 2> /dev/null; then + echo "tmux already contains session: $SESSION" + exit 1 +fi + +echo "Initializing Clojure workspace '$SESSION' at $PROJECT_ROOT" + +# Initialize workspace +tmux -2 new-session -d -s $SESSION + +tmux new-window -t "$SESSION:0" -n 'misc' -c "$HOME" -k + +tmux new-window -t "$SESSION:1" -n 'git' -c "$PROJECT_ROOT" + +tmux new-window -t "$SESSION:2" -n 'repl' -c "$PROJECT_ROOT/src/$NAMESPACE" +tmux send-keys -t "$SESSION:2" "lein trampoline repl" # C-m + +tmux new-window -t "$SESSION:3" -n 'src' -c "$PROJECT_ROOT/src/$NAMESPACE" + +tmux new-window -t "$SESSION:4" -n 'test' -c "$PROJECT_ROOT/test/$NAMESPACE" +tmux split-window -t "$SESSION:4" -h -c "$PROJECT_ROOT" +tmux send-keys -t "$SESSION:4.1" "lein test-refresh" # C-m + +tmux new-window -t "$SESSION:5" -n 'doc' -c "$PROJECT_ROOT/doc" + +# Attach to session +tmux select-window -t "$SESSION:3" +tmux select-window -t "$SESSION:1" +tmux attach -t "$SESSION" diff --git a/tools/bin/findup b/tools/bin/findup new file mode 100755 index 0000000..afd433d --- /dev/null +++ b/tools/bin/findup @@ -0,0 +1,20 @@ +#!/bin/bash + +if [[ -z "$1" ]]; then + echo "Usage: $(basename $0) " + exit 1 +fi + +DIR=$PWD + +while [[ $(readlink -f $DIR) != "/" ]]; do + if [[ -n "$(find "$DIR" -maxdepth 1 -mindepth 1 -name "$1")" ]]; then + echo $DIR + exit + else + DIR=$(dirname $DIR) + fi +done + +echo "$1 not found in any parent directory of $PWD" >&2 +exit 1 diff --git a/tools/bin/histogram b/tools/bin/histogram index 83cbf0c..4a36a26 100755 --- a/tools/bin/histogram +++ b/tools/bin/histogram @@ -30,6 +30,7 @@ $boundaries = nil # display options $precision = 0 +$cumulative = false $bar_length = 60 # helper method to abort the script @@ -44,6 +45,7 @@ options = OptionParser.new do |opts| opts.on('-w', '--width VALUE', "Width of each histogram bucket") {|v| $width = v.to_f; fail "Bucket width must be positive" unless $width > 0.0 } opts.on('-n', '--count N', "Number of histogram buckets") {|v| $count = v.to_i; fail "Bucket count must be positive" unless $count > 0 } opts.on('-p', '--precision N', "Boundary display precision (default: #{$precision})") {|v| $precision = v.to_i } + opts.on('-c', '--cumulative', "Show cumulative frequency instead of per-bucket") { $cumulative = true } opts.on('-b', '--bar-length N', "Length of longest histogram bar (default: #{$bar_length})") {|v| $bar_length = v.to_i } opts.on('-h', '--help', "Print these options") { puts opts; exit } end @@ -120,8 +122,16 @@ unless $total == 0 max_pct = entries.map{|e| e[2] }.max + cum_freq = 0.0 entries.each do |entry| - bar = ($bar_length*entry[2]/max_pct).ceil - puts format % [entry[0], entry[1], 100*entry[2], '#'*bar] + value, count, freq = *entry + bar = ($bar_length*freq/max_pct).ceil + cum_freq = cum_freq + freq + puts format % [ + value, + count, + 100*($cumulative ? cum_freq : freq), + '#'*bar + ] end end diff --git a/tools/bin/notes b/tools/bin/notes index 808f34e..f95799f 100755 --- a/tools/bin/notes +++ b/tools/bin/notes @@ -1,5 +1,5 @@ #!/bin/sh -loc=${1:-.} +loc=${@:-.} find $loc -type d \( -name .svn -o -name .git \) -prune -o -type f -print0 | sort -z | xargs -0 grep -H -I -n --color=auto -P '(TODO|DEBUG|FIXME|REVIEW|XXX)' diff --git a/tools/bin/rest-util b/tools/bin/rest-util new file mode 100755 index 0000000..59927c1 --- /dev/null +++ b/tools/bin/rest-util @@ -0,0 +1,149 @@ +#!/usr/bin/env ruby + +# This is a utility script for making JSON/HTTP requests to a REST-style +# service endpoint. +# +# Author:: Greg Look + +require 'optparse' + + + +##### OPTIONS ##### + +CURL_BIN = "/usr/bin/curl" +SCRIPT_NAME = File.basename($0) +PROTOCOLS = [:http, :https] +HTTP_METHODS = [:HEAD, :GET, :PUT, :POST, :DELETE, :OPTIONS] +MIME_TYPES = { + :json => "application/json", + :edn => "application/edn", + :yaml => "application/yaml", + :html => "text/html" +} + +# default options +$options = { + :method => :GET, + :url => nil, + :accept => :json, + :content => :json, + :insecure => false +} + +# parse command-line options +opts = OptionParser.new do |opts| + opts.banner = "Usage: #{SCRIPT_NAME} [options] [method] [data]" + opts.separator "" + opts.separator "Connection Options:" + opts.on('-s', "--show-headers", "Show response header data") { $options[:show_headers] = true } + opts.on('-k', "--insecure", "Allow TLS connections which are not trusted by installed CAs") { $options[:insecure] = true } + opts.separator "" + opts.separator "Data Options:" + opts.on('-a', "--accept FORMAT", MIME_TYPES.keys, "Specifies the format of data to accept (default: #{$options[:accept]})") {|format| $options[:accept] = format } + opts.on('-c', "--content FORMAT", MIME_TYPES.keys, "Specifies the format of data being sent (default: #{$options[:content]})") {|format| $options[:content] = format } + opts.on('-i', "--input PATH", "Uploads the file contents as the request body") {|path| $options[:in_file] = path } + opts.on('-o', "--output PATH", "Writes the response data to a file") {|path| $options[:out_file] = path } + opts.separator "" + opts.separator "General Options:" + opts.on('-v', "--verbose", "Show detailed request information") { $options[:verbose] = true } + opts.on('-p', "--pretend", "Print curl command instead of executing it") { $options[:pretend] = true } + opts.on('-h', "--help", "Display usage information") { puts opts; exit } + opts.separator "" + opts.separator "Arguments:" + opts.separator "The URI path must be given and must begin with a forward slash." + opts.separator "The HTTP method defaults to GET. If specified, it must be one of: #{HTTP_METHODS.join(', ')}" + opts.separator "PUT and POST requests accept an additional argument, which is sent as the request body." + opts.separator "" + opts.separator "Examples:" + opts.separator " $ #{SCRIPT_NAME} http://host/resource/" + opts.separator " $ #{SCRIPT_NAME} -f json put http://host/resource/item '{\"description\":\"Test item\"}'" + opts.separator " $ #{SCRIPT_NAME} post http://host/resource/subresource/ -i path/to/data.txt" + opts.separator " $ #{SCRIPT_NAME} delete http://host/resource/item" +end +opts.parse! + +# helper method to report failures +def fail(msg, code=1) + STDERR.puts msg + exit code +end + +# determine method and URL +if ARGV.empty? + puts opts + exit 1 +else + # if there are multiple arguments, interpret the first as the method + $options[:method] = ARGV.shift.upcase.intern if ARGV.count > 1 + fail "Invalid HTTP method: #{$options[:method]}" unless HTTP_METHODS.include? $options[:method] + + # next arg is the resource location + fail "You must specify a URI or path" if ARGV.empty? + $options[:url] = ARGV.shift +end + +# build curl command +command = [] + +# common options +command << CURL_BIN +command << "--silent" +command << "--header 'Accept: #{MIME_TYPES[$options[:accept]]}'" +command << "--header 'Content-Type: #{MIME_TYPES[$options[:content]]}'" if [:PUT, :POST].include?($options[:method]) +command << "--insecure" if $options[:insecure] +command << "--include" if $options[:show_headers] +command << "--verbose" if $options[:verbose] + +# set method +command << case $options[:method] + when :HEAD then "--head" + else "-X #{$options[:method].to_s.upcase}" +end + +# input data +data_arg = ARGV.shift if ARGV.first && [:PUT, :POST].include?($options[:method]) +if $options[:in_file] || data_arg + #command << "--header 'Content-Type: #{MIME_TYPE_JSON}'" # this makes Coral respond with + if $options[:in_file] + fail "Cannot use both input file and argument data" if data_arg + command << "-T #{$options[:in_file]}" + else + command << "-d '#{data_arg}'" + end +end + +# output data +command << "-o #{$options[:out_file]}" if $options[:out_file] + +# format url +command << "\"#{$options[:url]}\"" + +# command execution +command = command.join(' ') +if $options[:pretend] + puts command +else + start = Time.now + output = %x{#{command}} + elapsed = 1000*(Time.now - start) + puts "%.1f ms" % elapsed if $options[:verbose] + + if $?.success? + puts output + else + message = case $?.exitstatus + when 3 then "URL malformed: #{url}" + when 6 then "Couldn't resolve host: #{$options[:host]}" + when 7 then "Couldn't connect to host: #{$options[:host]}" + when 28 then "Operation timed out after #{elapsed} ms" + when 35 then "SSL connection handshake failed" + when 47 then "Too many redirects" + when 51 then "Peer SSL certificate or MD5 fingerprint is invalid" + when 52 then "No response from server" + when 60 then "Peer certificate cannot be authenticated by known authorities" + else "Unknown curl error #{$?.exitstatus}" + end + fail message, $?.exitstatus + end +end diff --git a/tools/bin/serve-http b/tools/bin/serve-http new file mode 100755 index 0000000..59615e8 --- /dev/null +++ b/tools/bin/serve-http @@ -0,0 +1,11 @@ +#!/bin/sh + +python -m SimpleHTTPServer ${1:-3003} + +#!/usr/bin/env ruby +# vim: ft=ruby +#require 'webrick' +#server = WEBrick::HTTPServer.new :Port => 3003 +#server.mount '/', WEBrick::HTTPServlet::FileHandler, './' +#trap('INT') { server.stop } +#server.start diff --git a/tools/bin/tabulate b/tools/bin/tabulate index 8e03df8..f67524d 100755 --- a/tools/bin/tabulate +++ b/tools/bin/tabulate @@ -22,14 +22,14 @@ require 'optparse' # option defaults $delim = ' ' -$limit = 1 +$limit = 0 # parse command-line options options = OptionParser.new do |opts| opts.banner = "Usage: #{File.basename($0)} [options] [pattern ...]" opts.on('-j', '--join STRING', "String to join pattern captures") {|delim| $delim = delim } opts.on('-f', '--format STRING', "Format string for pattern captures") {|format| $format = format } - opts.on('-l', '--limit N', "Only display captures with at least N repetitions") {|n| $limit = n.to_i } + opts.on('-l', '--limit PERCENT', Float, "Only display captures with a minimum percent of the total") {|p| $limit = p } opts.on('-v', '--verbose', "Show extra information after tabulation") { $verbose = true } opts.on('-h', '--help', "Display usage information") { print opts; exit } end @@ -67,17 +67,21 @@ while line = STDIN.gets end end +# helper to calculate the proportion of the total. +def pct(count) + 100*count.to_f/$matched +end + # print results unless $matched == 0 width = 1 + (Math.log($matched)/Math.log(10)).floor puts "%#{width}d --------- Total" % $matched - counts = $entries.keys.reject{|k| $entries[k] < $limit }.map{|k| [$entries[k], k] }.sort.reverse - remainder = $entries.keys.select{|k| $entries[k] < $limit } + counts = $entries.keys.reject{|k| pct($entries[k]) < $limit }.map{|k| [$entries[k], k] }.sort.reverse + remainder = $entries.keys.select{|k| pct($entries[k]) < $limit } counts << [remainder.inject(0) {|sum,k| sum + $entries[k] }, "(%d more...)" % remainder.size] unless remainder.empty? counts.each do |entry| - pct = 100*entry[0].to_f/$matched - puts "%#{width}d (%6.2f%%) %s" % [entry[0], pct, entry[1]] + puts "%#{width}d (%6.2f%%) %s" % [entry[0], pct(entry[0]), entry[1]] end end diff --git a/tools/util/graph/java/classes.rb b/tools/util/graph/java/classes.rb new file mode 100755 index 0000000..8cbbd78 --- /dev/null +++ b/tools/util/graph/java/classes.rb @@ -0,0 +1,592 @@ +#!/usr/bin/ruby + +# This script analyzes a set of Java source files and produces a graph DOT +# file describing the class/interface inheritance hierarchy. +# +# Author:: Greg Look, Kevin Litwack + +require 'optparse' +require 'yaml' + + +SCRIPT_NAME = File.basename($0) + +$local_only = false +$exclude = [] +$group_types = true +$show_imports = false +$layout = nil + +# Parse command-line options. +opts = OptionParser.new do |opts| + opts.banner = "Usage: #{SCRIPT_NAME} [options] " + opts.on('-l', "--local-only", "Only show local entities") {|v| $local_only = true } + opts.on('-x', "--exclude ID", "Exclude a subtree prefix from the graph (may be provided multiple times)") {|v| $exclude << v } + opts.on('-g', "--[no-]group", "Group types together by package (default: #{$group_types})") {|v| $group_types = v } + opts.on('-i', "--[no-]imports", "Show import relationships (default: #{$show_imports})") {|v| $show_imports = v } + opts.on( "--horizontal", "Lay out nodes horizontally") { $layout = :horizontal } + opts.on('-v', "--verbose", "Show detailed processing information") { $verbose = true } + opts.on('-h', "--help", "Display usage information") { puts opts; exit } + opts.separator "" + opts.separator "Example:" + opts.separator "#{SCRIPT_NAME} -x java -x org.apache.commons src/**/*.java | dot -Tpng > classes.png" +end +opts.parse! + +# Reports a failure message and exits with an optional code. +def fail(msg, code=1) + STDERR.puts msg + exit code +end + +# Logs a message to stderr if the verbose flag is set. +def log(msg) + STDERR.puts msg if $verbose +end + +# Require at least one source argument. +fail opts if ARGV.empty? + + + +##### JAVA SYNTAX CLASSES ##### + +# Represents a Java type reference. +class JavaType + attr_reader :package, :name, :parameters + + include Comparable + + def initialize(package, name, parameters=nil) + @package = package + @name = name + @parameters = parameters + end + + # Fully-qualified class name. + def qualified_name + "#{@package}.#{@name}" + end + + # Parameterized type name. + def parameterized_name + @parameters && ("%s<%s>" % [@name, @parameters.join(', ')]) || @name + end + + # Fully-qualified and parameterized name. + def full_name + "#{@package}.#{parameterized_name}" + end + + # Returns the raw (un-parameterized) type for this entity. + def raw_type + JavaType.new(@package, @name) + end + + # Determines whether the given type has the same raw type as this one. + def type_of?(type) + type.raw_type == raw_type + end + + def <=>(other) + other.respond_to?(:full_name) && + (full_name <=> other.full_name) + end + + def ==(other) + other.respond_to?(:package) && (other.package == @package) && + other.respond_to?(:name) && (other.name == @name) && + other.respond_to?(:parameters) && (other.parameters == @parameters) + end + + def eql?(other) + other.kind_of?(JavaType) && + (self == other) + end + + def hash + [@package, @name, @parameters].hash + end +end + + +# Represents a Java class, interface, or enum declaration. +class JavaEntity < JavaType + attr_reader :visibility, :kind + attr_accessor :supertype, :interfaces + + # Initializes a new Java entity. + def initialize(kind, type, opts={}) + @kind = kind + @package = type.package + @name = type.name + @parameters = type.parameters + @visibility = opts[:visibility] + @modifiers = opts[:modifiers ] || [] + @interfaces = opts[:interfaces] || [] + @supertype = opts[:supertype ] + + if !@modifiers.empty? + raise "Interfaces cannot have modifiers" if @type == :interface + raise "Enumerations cannot have modifiers" if @type == :enum + end + + if @modifiers.include?(:abstract) && @modifiers.include?(:final) + raise "Classes cannot be abstract and final at the same time" + end + end + + # Determines whether the given type is a supertype of this entity. + def extends?(type) + @supertype && @supertype.type_of?(type) && @supertype + end + + # Determines whether the given type is implemented by this entity. + def implements?(type) + @interfaces.find do |interface| + interface.type_of? type + end + end + + # Determines whether the entity is abstract. + def abstract? + @modifiers.include? :abstract + end + + # Determines whether the entity is final. + def final? + @modifiers.include? :final + end + + # Determines whether the entity is static. + def static? + @modifiers.include? :static + end +end + + +# Represents a Java source file, which imports classes from other files and +# contains its own type definitions. +class SourceFile + attr_reader :name, :entities, :imports + attr_accessor :package + + ENTITY_KINDS = [:class, :enum, :interface] + VISIBILITIES = [:private, :protected, :public] + MODIFIERS = [:abstract, :final, :static] + + # Initializes a new source file object. + def initialize(path) + @name = File.basename(path) + @entities = [] + @imports = {} + end + + # Adds a new import available to this file. + def import(import) + parts = import.split('.') + package = parts[0...(parts.length-1)].join('.') + name = parts.last # NOTE: this fails for member classes, but is fixed later + @imports[name] = JavaType.new(package, name) + end + + # Adds a new entity declaration to this file. + def define(declaration) + unless /^\s*((?:\w+\s+)*)(class|enum|interface)\s+(.+)$/ === declaration + raise "Unprocessable declaration: #{declaration}" + end + + # Format regex captures. + keywords = $1.strip.split(' ').map { |k| k && k.strip.intern }.compact + kind = $2.strip.intern + remaining = $3 + + # Check entity kind. + unless ENTITY_KINDS.include? kind + raise "Unknown entity kind: #{kind}" + end + + opts = {} + + # Parse visibility and modifier keywords. + keywords.each do |keyword| + if VISIBILITIES.include? keyword + raise "Declaration contains multiple visibility keywords: #{declaration}" if opts[:visibility] + opts[:visibility] = keyword + elsif MODIFIERS.include? keyword + opts[:modifiers] ||= [] + opts[:modifiers] << keyword + else + raise "Unknown keyword: #{keyword}" + end + end + + # Parse entity type definition. + type, remaining = parse_type(remaining, true) + + # Detect and parse supertype. + if /^(.*)extends\s+(.+)/ === remaining + before = $1 + opts[:supertype], after = parse_type($2) + remaining = before && after && "#{before} #{after}" || before || after + end + + # Detect and parse implemented interfaces. + if /^\s*implements\s+(.+)/ === remaining + opts[:interfaces] = [] + remaining = $1 + until remaining.empty? + itype, remaining = parse_type(remaining) + opts[:interfaces] << itype + end + end + + @entities << JavaEntity.new(kind, type, opts) + end + + # Resolves all unqualified entity supertype and interface types. + # - packages is a map of package names => simple names => type objects + def resolve_types(packages) + # Build a hash of qualified names to type objects. + types = packages.values.map do |names| + names.values + end.flatten.inject(Hash.new) do |hash, type| + hash[type.qualified_name] = type + hash + end + + # Check if an import's "package" is itself an entity. + @imports.values.each do |import| + actual_type = types[import.qualified_name] + if actual_type && import != actual_type + @imports[import.name] = actual_type + end + end + + # Resolve all contained entity types. + @entities.each do |entity| + entity.supertype = resolve(packages, entity.supertype) + entity.interfaces = entity.interfaces.map do |interface| + resolve(packages, interface) + end + end + end + + private + + # Resolves the given simple name to a type. + def resolve(packages, type) + if type.nil? + nil + elsif type.package + type + elsif @imports.keys.include? type.name + import = @imports[type.name] + JavaType.new(import.package, type.name, type.parameters) + elsif packages[@package] && packages[@package][type.name] + JavaType.new(@package, type.name, type.parameters) + else + JavaType.new("java.lang", type.name, type.parameters) + end + end + + # Parses a Java type specification from a string, returning the type name, + # any template parameters, and the unparsed part of the string. + def parse_type(string, local=false) + #log "parse_type(#{string.inspect}, #{local})" + + tokens = string.strip.split(/\s+/) + token = tokens.shift + + unless /^([a-zA-Z]\w+)(<.+)?/ === token + raise "First token is not a valid Java identifier: #{token}" + end + + name = $1 + parameters = $2 + package = local && @package + + file_entity = @name.split('.').first + name = "#{file_entity}$#{name}" if local && name != file_entity + + #log " package: #{package.inspect}" + #log " name: #{name.inspect}" + #log " parameters: #{parameters.inspect}" + #log " tokens: #{tokens.inspect}" + + if parameters + while !tokens.empty? && parameters.count('<') != parameters.count('>') + parameters << " " << tokens.shift + end + unless parameters.count('<') == parameters.count('>') + raise "Unbalanced parameters in type: #{string}" if tokens.empty? + end + parameters = parameters[1...(parameters.length-1)].split(/,\s*/) + end + + [JavaType.new(package, name, parameters), tokens.join(' ')] + end +end + + + +##### PROCESSING ##### + +$start = Time.now +$sources = [] + +# Process input file arguments. +ARGV.each do |path| + log "Processing #{path}" + source = SourceFile.new(path) + File.open(path) do |file| + file.each do |line| + case line + when /^\s*package\s+([^;]+);/ + source.package = $1.strip + when /^\s*import\s+(?:static\s+)?([^;]+?)(?:\.\*)?\s*;/ + source.import $1.strip + when /^\s*(?:\w+\s+)*(?:class|enum|interface) / + declaration = line.strip + declaration << " " << file.readline.strip until declaration.include?('{') + declaration = declaration[0...declaration.index('{')].strip + source.define declaration + end + end + end + STDERR.puts "WARNING: #{source.name} does not appear to declare any entities!" if source.entities.empty? + $sources << source +end + +# Set of all local entity objects. +$entities = $sources.map { |source| source.entities }.flatten.sort + +# Map of local package names to simple names to contained types. +$local_packages = $entities.inject(Hash.new) do |hash, entity| + hash[entity.package] ||= Hash.new + hash[entity.package][entity.name] = entity.raw_type + hash +end + +# Resolve entity types. +$sources.each do |source| + source.resolve_types $local_packages +end + +# Set of local raw types. +$local_types = $entities.map { |entity| entity.raw_type } + +# Set of external raw types. +$external_types = $sources.map do |source| + imports = source.imports.values + supertypes = source.entities.map { |e| e.supertype } + interfaces = source.entities.map { |e| e.interfaces }.flatten + [imports, supertypes, interfaces].flatten +end.flatten.compact.map do |entity| + entity.raw_type +end.uniq - $local_types + +# Map of external package names to simple names to contained types. +$external_packages = $external_types.inject(Hash.new) do |hash, type| + hash[type.package] ||= Hash.new + hash[type.package][type.name] = type + hash +end + +# Set of types which are *implemented* by local entities. This helps determine +# whether external types are interfaces. +$implemented_types = $entities.map do |entity| + entity.interfaces.map do |interface| + interface.raw_type + end +end.flatten.uniq + +# Set of types which are *extended* by local entities and NOT implemented by +# any local entity. This helps etermine whether external types are classes. +$extended_types = $entities.map do |entity| + entity.supertype && entity.supertype.raw_type +end.compact.uniq - $implemented_types + +log "Processed %d files in %.3f sec" % [ARGV.size, Time.now - $start] +log " Local: %d types in %d packages" % [$local_types.size, $local_packages.size] +log " External: %d types in %d packages" % [$external_types.size, $external_packages.size] + + + +##### GRAPHING ##### + +# Determines whether the given type should be excluded from the graph. +def excluded?(type) + return true if $local_only && !$local_types.include?(type.raw_type) + $exclude.each do |prefix| + return true if type.qualified_name.index(prefix) == 0 + end + false +end + +# Print text indented by a certain amount. +def puts_indent(level, text) + print " "*level, text, "\n" +end + +# Sanitize a name to allow it to be used as a node identifier. +def sanitize(name) + #name.gsub(".", "_").gsub(/<.+>/, "") + name.gsub(".", "_").gsub("$", "_") +end + +# Opens a package subgraph. +def open_package_subgraph(level, package) + name = sanitize package + name = "cluster_#{name}" if $group_types + + puts_indent level, "subgraph #{name} {" + puts_indent (level + 1), "label = \"#{package}\";" +end + +# Draws a node for the given properties. +def draw_node(level, name, label, kind, styles=[]) + shape = case kind + when :class then "box" + when :enum then "hexagon" + when :interface then "ellipse" + else "rect" + end + + attrs = [] + attrs << "color=red" unless kind + attrs << "shape=#{shape}" if shape + attrs << "label=\"#{label}\"" + attrs << "style=#{styles.join(',')}" unless styles.empty? + + puts_indent level, "#{sanitize name} [#{attrs.join(',')}];" +end + +# Draws a local entity node. +def draw_local_entity(level, entity) + return if excluded? entity + + name = entity.qualified_name + label = entity.parameterized_name + kind = entity.kind + styles = [] + styles << "dashed" if entity.abstract? + styles << "bold" if entity.final? + styles << "diagonals" if entity.static? + + draw_node level, name, label, kind, styles +end + +# Draws an external type node. +def draw_external_type(level, type) + return if excluded? type + + name = type.qualified_name + label = type.name + kind = $implemented_types.include?(type) && :interface || $extended_types.include?(type) && :class + + draw_node level, name, label, kind +end + +# Draws an edge between two nodes. +def draw_edge(level, src, dst) + return if excluded?(src) || excluded?(dst) + + src_name = sanitize src.qualified_name + dst_name = sanitize dst.qualified_name + attrs = []; + + # Show parameterized type if present and not identical. + unless dst.parameters.nil? || dst.parameters.empty? || dst.parameters == src.parameters + attrs << "label=\"<#{dst.parameters.join(', ')}>\"" + end + + if attrs.empty? + puts_indent level, "#{src_name} -> #{dst_name};" + else + puts_indent level, "#{src_name} -> #{dst_name} [#{attrs.join(',')}];" + end +end + + +# Write graph file. +puts_indent 0, "digraph java_classes {" +puts_indent 1, "rankdir=LR;" if $layout == :horizontal +puts_indent 1, "node [shape=circle];" # this is for debugging any nodes which don't have an explicit shape set +puts "" + +# Draw local package clusters and nodes. +puts_indent 1, "subgraph local_entities {" +$local_packages.each do |package, types| + open_package_subgraph 2, package + puts_indent 3, "node [color=black];" + types.each do |name, type| + entity = $entities.find {|e| e.raw_type == type } + draw_local_entity 3, entity + end + puts_indent 2, "}" +end +puts_indent 1, "}" + +# Draw external package clusters and nodes. +unless $local_only + puts_indent 1, "subgraph external_types {" + puts_indent 2, "node [style=dotted];" + $external_packages.each do |package, types| + open_package_subgraph 2, package + puts_indent 3, "style = dashed;" + puts_indent 3, "node [color=black];" + types.each do |name, type| + draw_external_type 3, type + end + puts_indent 2, "}" + end + puts_indent 1, "}" +end + +# Draw supertype relationships. +puts_indent 1, "subgraph supertypes {" +puts_indent 2, "edge [color=red,weight=1];" +$entities.each do |entity| + draw_edge 2, entity, entity.supertype if entity.supertype +end +puts_indent 1, "}" + +# Draw interface relationships. +puts_indent 1, "subgraph interfaces {" +puts_indent 2, "edge [color=blue,weight=1];" +$entities.each do |entity| + entity.interfaces.each do |interface| + draw_edge 2, entity, interface + end +end +puts_indent 1, "}" + +# Draw member class relationships. +puts_indent 1, "subgraph members {" +puts_indent 2, "edge [color=darkgreen,weight=1,constraint=false];" +$entities.each do |entity| + qname = entity.qualified_name + if qname.include? '$' + parent_qname = qname[0...qname.index('$')] + parent = $entities.find { |e| e.qualified_name == parent_qname } + draw_edge 2, entity, parent + end +end +puts_indent 1, "}" + +# Draw import relationships. +if $show_imports + puts_indent 1, "subgraph imports {" + puts_indent 2, "edge [color=grey];" + $sources.each do |source| + source.entities.each do |entity| + source.imports.each do |name, import| + draw_edge 2, entity, import unless entity.extends?(import) || entity.implements?(import) + end + end + end + puts_indent 1, "}" +end + +puts_indent 0, "}" diff --git a/tools/util/graph/java/packages.rb b/tools/util/graph/java/packages.rb new file mode 100755 index 0000000..7b6fd13 --- /dev/null +++ b/tools/util/graph/java/packages.rb @@ -0,0 +1,213 @@ +#!/usr/bin/ruby + +# This script analyzes a set of Java source files and produces a graph DOT +# file describing the dependencies between the packages. +# +# Author:: Greg Look + +require 'optparse' + + +SCRIPT_NAME = File.basename($0) + +$prefix = nil +$local_only = false +$exclude = [] +$weight_edges = false +$group_packages = false +$group_by = 1 +$layout = nil + +# parse command-line options +opts = OptionParser.new do |opts| + opts.banner = "Usage: #{SCRIPT_NAME} [options] " + opts.on('-p', "--prefix STRING", "Prefix to remove from packages") {|v| $prefix = v } + opts.on('-l', "--local-only", "Only show local packages") {|v| $local_only = true } + opts.on('-x', "--exclude PACKAGE", "Exclude a package subgraph (may be provided multiple times)") {|v| $exclude << v } + opts.on('-w', "--[no-]weight", "Weight edges by the number of imports") {|v| $weight_edges = v } + opts.on('-g', "--[no-]group", "Group packages hierarchically") {|v| $group_packages = v } + opts.on( "--group-by N", Integer, "Use N segments to group top-level packages (default: #{$group_by})") {|n| $group_by = n.to_i } + opts.on( "--horizontal", "Lay out nodes horizontally") { $layout = :horizontal } + opts.on('-v', "--verbose", "Show detailed processing information") { $verbose = true } + opts.on('-h', "--help", "Display usage information") { puts opts; exit } + opts.separator "" + opts.separator "Example:" + opts.separator "#{SCRIPT_NAME} -p com.amazon.trms.data. -x java.util -x java.nio src/**/*.java | dot -Tpng > packages.png" +end +opts.parse! + +# helper method to report failures +def fail(msg, code=1) + STDERR.puts msg + exit code +end + +# logging helper method +def log(msg) + STDERR.puts msg if $verbose +end + +fail opts if ARGV.empty? + +$imports = Hash.new + +# canonicalizes a package name +def canonical(name) + name = $1 if name =~ /^(.*?)(?:\.\*)?$/ + name = "?" if name.empty? + name +end + +$start = Time.now + +# process input files +ARGV.each do |path| + log "Processing #{path}" + package = nil + + IO.readlines(path).each do |line| + if line =~ /^\s*package (.+);\s*$/ + package = canonical $1 + log " Belongs to #{package}" + + elsif line =~ /^\s*import (?:static )?(.+);\s*$/ + import = $1 + import, cname = $1, $2 if import =~ /^([a-z0-9\.]+)\.([A-Z].+)$/ + log " Imports #{cname} from #{import}" + + $imports[package] ||= Hash.new(0) + $imports[package][import] += 1 unless import == package + end + end +end + +log "Processed %d files in %.3f sec" % [ARGV.size, Time.now - $start] + +$packages = ($imports.values.map { |h| h.keys }.flatten + $imports.keys).uniq + +# filter excluded packages +$packages = $imports.keys if $local_only +$imports = $imports.delete_if do |package, imports| + $exclude.include? package +end +$imports.keys.each do |package| + $imports[package] = $imports[package].delete_if do |import, n| + $exclude.include?(import) || $local_only && !$imports[import] + end +end + +#log "All packages: #{$packages.join(' ')}" + +# helper method to indent some text +def puts_indent(level, text) + print " "*level, text, "\n" +end + +# helper method to sanitize node names +def sanitize(name) + name.gsub(".", "_") +end + +# trims a package name from its prefix to get a label +def prefixed_label(package) + label = ( package =~ /^#{$prefix}(.*)$/ ) && $1 || package + label = '.' if label.empty? + label +end + +# draw a package node and its imports at some indent level +def draw_node(package, level=1) + label = prefixed_label package + name = sanitize package + style = $imports[package] && 'rounded' || '"dashed,rounded"' + puts_indent level, "#{name} [shape=box,style=#{style},label=\"#{label}\"];" +end + +# draw a set of import edges +def draw_imports(package, imports, level=1) + imports && imports.each do |import, n| + width = (Math.log(n) + 1).ceil + style = $weight_edges && "[weight=#{n},penwidth=#{width}]" || "" + puts_indent level, "#{sanitize package} -> #{sanitize import} #{style};" + end +end + +# open a subgraph for the given package +def open_subgraph(package, parent, level) + name = sanitize package + name = "cluster_#{name}" if $group_packages + label = parent && (package =~ /^#{parent}\.(.+)$/) && $1 || package + puts_indent level, "subgraph #{name} {" + puts_indent (level + 1), "label = \"#{label}\";" +end + +# closes a subgraph at some level +def close_subgraph(level) + puts_indent level, "}" +end + +# Here `package` is fully qualified from the root, parent indicates the fully +# qualified next higher *subgraph* containing this one. +def write_package(package, parent=nil, level=1) + return if $exclude.include? package + + log "Writing package #{package}" + + # see if there are direct subpackages + subpackages = $packages.map { |p| $1 if p =~ /^#{package}\.(.+)$/ }.compact + direct_subpackages = subpackages.map { |p| p.split('.').first }.uniq + log " direct subpackages: #{direct_subpackages.join(' ')}" unless direct_subpackages.empty? + + # package is real and contains classes + if $packages.include? package + if direct_subpackages.empty? + draw_node package, level + else + open_subgraph package, parent, level + draw_node package, (level + 1) + direct_subpackages.each do |subpackage| + write_package "#{package}.#{subpackage}", package, level + 1 + end + close_subgraph level + end + + # package is a virtual container, like "java" in "java.util.regex" + else + case direct_subpackages.size + when 0: + # omit package + when 1: + write_package "#{package}.#{direct_subpackages.first}", parent, level + else + open_subgraph package, parent, level + direct_subpackages.each do |subpackage| + write_package "#{package}.#{subpackage}", package, level + 1 + end + close_subgraph level + end + end +end + +# write graph file +puts_indent 0, "digraph dependencies {" +puts_indent 1, "rankdir=LR;" if $layout == :horizontal +puts_indent 1, "node [shape=circle];" # this is for debugging any nodes which don't have an explicit style set +puts "" + +# write package hierarchy +roots = $packages.map do |package| + segments = package.split('.') + len = [[$group_by, segments.length].min, 1].max - 1 + segments[0..len].join('.') +end + +roots.uniq.each do |package| + write_package package +end + +# write edges +$imports.each do |package, imports| + draw_imports package, imports +end + +puts "}" diff --git a/tools/util/graph/ruby/rake-tasks.rb b/tools/util/graph/ruby/rake-tasks.rb new file mode 100755 index 0000000..9a3eb2f --- /dev/null +++ b/tools/util/graph/ruby/rake-tasks.rb @@ -0,0 +1,177 @@ +#!/usr/bin/env ruby + +# This script analyzes the output of the Rake build system to generate a +# graph of the available build tasks and their dependencies. +# +# The resulting graph specification is printed to stdout and is suitable for +# piping directly into a graph layout command such as `dot`: +# +# $ rake-tasks.rb | dot -Tpng > tasks.png +# +# Author:: Greg Look + + +# Fails the script and exits with an error code. +def fail(message=nil, code=1) + STDERR.puts(message) if message + exit code +end + + +# List of task names. +TASK_NAMES = [] +# Map of task names to their descriptions. +TASK_DESC = {} +# Map of task names to lists of their dependencies. +TASK_PREREQS = {} +# Task heirarchy. +TASK_NAMESPACES = {} + + + +##### DATA COLLECTION ##### + +# Collect task descriptions. +begin + descs = %x{rake --tasks} + fail unless $?.success? + + descs.split("\n").each do |line| + if line =~ /^rake (\S+)\s+# (.+)/ + TASK_DESC[$1] = $2 + end + end +end + +# Collect rake task prerequisites. +begin + prereqs = %x{rake --prereqs} + fail unless $?.success? + + task = nil + prereqs.split("\n").each do |line| + if line =~ /^rake (.+)/ + task = $1 + TASK_NAMES << task + else + TASK_PREREQS[task] ||= [] + TASK_PREREQS[task] << line.strip + end + end +end + + + +##### DATA PROCESSING ##### + +# Resolve namespace-relative prereqs. +TASK_NAMES.each do |task| + if TASK_PREREQS.has_key? task + TASK_PREREQS[task] = TASK_PREREQS[task].map do |prereq| + namespaces = task.split(':') + namespaces.pop # remove the task name + + until namespaces.empty? + fqtn = "#{namespaces.join(':')}:#{prereq}" + if TASK_NAMES.include? fqtn + prereq = fqtn + break + end + namespaces.pop + end + + prereq + end + end +end + +# Build namespaced task hierarchy. +TASK_NAMES.each do |task| + namespaces = task.split(':') + namespaces.pop # remove the task name + + ns = TASK_NAMESPACES + until namespaces.empty? + name = namespaces.shift + ns[name] ||= {} + ns = ns[name] + end +end + + + +##### GRAPH GENERATION ##### + +# Sanitizes node names. +def sanitize(name) + name.gsub(/[\/:\.]/, '_') +end + +# Prints indented text. +def puts_indent(level, text) + print " "*level, text, "\n" +end + +# Draws a task node. +def draw_task(task, level=1) + id = sanitize task + label = task.split(':').last + style = TASK_DESC.has_key?(task) ? "" : ",style=dashed" + puts_indent level, "#{id} [label=\"#{label}\"#{style}];" +end + +# Recursively draws a namespace subgraph. The first argument should be a fully +# qualified namespace string, separated with colons. The second is the hash +# containing the child namespaces. +def draw_namespace(name, children, level=1) + id = "cluster_#{sanitize name}" + label = name.split(':').last + + puts_indent level, "subgraph #{id} {" + puts_indent level + 1, "label = \"#{label}\";" + + # Draw child namespaces first. + children.keys.sort.each do |child| + draw_namespace child, children[child], level + 1 + end + + # Draw task nodes. + tasks = TASK_NAMES.select do |task| + ns = task.split(':') + ns.pop + name == ns.join(':') + end + + tasks.sort.each do |task| + draw_task task, level + 1 + end + + puts_indent level, "}" +end + + +# Generate output graph. +puts "digraph rake_tasks {" +puts " node [shape=box];" + +# Draw all tasks in namespace clusters. +TASK_NAMESPACES.each do |name, children| + draw_namespace name, children +end + +# Draw all top-level tasks. +puts_indent 1, "subgraph top_tasks {" +puts_indent 2, "rank = same;" +TASK_NAMES.each do |task| + draw_task task unless task.include? ':' +end +puts_indent 1, "}" + +# Draw dependencies between tasks. +TASK_PREREQS.keys.sort.each do |task| + TASK_PREREQS[task].each do |prereq| + puts_indent 1, "#{sanitize task} -> #{sanitize prereq};" + end +end + +puts "}" diff --git a/tools/util/termcolor b/tools/util/termcolor new file mode 100755 index 0000000..1311892 --- /dev/null +++ b/tools/util/termcolor @@ -0,0 +1,245 @@ +#!/usr/bin/ruby + +# This script prints out examples of every terminal color for testing purposes. +# See: http://en.wikipedia.org/wiki/ANSI_escape_code +# +# Author:: Greg Look + + + +##### COLOR CLASS ##### + +class Color + attr_reader :num, :names, :r, :g, :b, :hex + + def initialize(num, props={}) + @num = num + @names = props[:names] || [] + + if props[:hex] + @hex = props[:hex] + unless props[:rgb] + @r = @hex[0..1].to_i(16) + @g = @hex[2..3].to_i(16) + @b = @hex[4..5].to_i(16) + end + end + + if props[:rgb] + @r = props[:rgb][0] + @g = props[:rgb][1] + @b = props[:rgb][2] + unless @hex + @hex = "%02x%02x%02x" % [@r, @g, @b] + end + end + end + + def name + @names.first + end + + def diff(color) + dr = color.r - @r + dg = color.g - @g + db = color.b - @b + + Math.sqrt(dr**2 + dg**2 + db**2) + end + + def mag + Math.sqrt(@r**2 + @g**2 + @b**2) + end + + COLORS = [ + Color.new( 0, :hex => '000000', :names => ['black']), + Color.new( 1, :hex => 'cd0000', :names => ['red']), + Color.new( 2, :hex => '00cd00', :names => ['green']), + Color.new( 3, :hex => 'cdcd00', :names => ['yellow']), + Color.new( 4, :hex => '0000ee', :names => ['blue']), + Color.new( 5, :hex => 'cd00cd', :names => ['magenta']), + Color.new( 6, :hex => '00cdcd', :names => ['cyan']), + Color.new( 7, :hex => 'e5e5e5', :names => ['white', 'gray']), + Color.new( 8, :hex => '7f7f7f', :names => ['brightblack', 'darkgray']), + Color.new( 9, :hex => 'ff0000', :names => ['brightred']), + Color.new(10, :hex => '00ff00', :names => ['brightgreen']), + Color.new(11, :hex => '5c5cff', :names => ['brightyellow']), + Color.new(12, :hex => '0000ff', :names => ['brightblue']), + Color.new(13, :hex => 'ff00ff', :names => ['brightmagenta']), + Color.new(14, :hex => '00ffff', :names => ['brightcyan']), + Color.new(15, :hex => 'ffffff', :names => ['brightwhite']), + ] + + def self.[](i) + raise "#{i} is not a valid color number" if i < 0 || i > 255 + + # basic ansi color + if i < 16 + COLORS[i] + + # color cube + elsif i < 232 + # get cube coordinates + r = ((i - 16) )/36 + g = ((i - 16) % 36)/6 + b = ((i - 16) % 6) + + # translate to colors + r = ( r == 0 ) ? 0 : ( 55 + 40*r ) + g = ( g == 0 ) ? 0 : ( 55 + 40*g ) + b = ( b == 0 ) ? 0 : ( 55 + 40*b ) + + Color.new(i, :rgb => [r, g, b]) + + # grayscale ramp + else + v = 10*(i - 232) + 8 + + Color.new(i, :rgb => [v, v, v]) + end + end + + def self.match(target) + best = COLORS[0] + + 256.times do |i| + color = self[i] + best = color if target.diff(color) < target.diff(best) + end + + best + end +end + + + +##### COLORIZING METHODS ##### + +ANSI_SGR = "\e[%sm" + +SGR_NONE = 0 +SGR_BOLD = 1 +SGR_UNDERLINE = 3 +SGR_REVERSE = 7 +SGR_HIDDEN = 8 +SGR_FG_BASE = 30 +SGR_FG_256 = 38 +SGR_FG_RESET = 39 +SGR_BG_BASE = 40 +SGR_BG_256 = 48 +SGR_BG_RESET = 49 + +# select graphic rendition +def sgr(*codes) + ANSI_SGR % codes.join(';') +end + +# reset colors +def reset + sgr(SGR_NONE) +end + +# set 256-color foreground +def fg(i) + sgr(SGR_FG_256, 5, i) +end + +# set 256-color background +def bg(i) + sgr(SGR_BG_256, 5, i) +end + +# print a square block of solid color +def swatch(i) + print "#{bg(i)} #{reset}" +end + +# print detailed info about a color object +def detail(color) + invert = color.mag < 150 + block = "#{bg(color.num)}#{fg(invert ? 7 : 0)} %s #{reset}" % color.hex + rgb = "(#{fg(9)}%3d#{reset}, #{fg(10)}%3d#{reset}, #{fg(12)}%3d#{reset})" % [color.r, color.g, color.b] + puts "%4d %s %s %s" % [color.num, block, rgb, color.names.join(', ')] +end + + + +##### COLOR TESTS ##### + +def test_ansi_colors + puts "ANSI colors (0-15):" + Color::COLORS[0...8].each do |color| + puts "%8s: %sdark#{reset} %slight#{reset}" % [color.name, sgr(SGR_FG_BASE + color.num), sgr(1, SGR_FG_BASE + color.num)] + end + print "\n" +end + +def test_system_colors + puts "System colors (0-15):" + print " %3d " % 0 + 8.times {|i| swatch(i) } + print "\n %3d " % 8 + 8.times {|i| swatch(i+8) } + print "\n\n" +end + +def test_color_cube + puts "6x6x6 color cube (16-231):" + 6.times do |row| + 6.times do |layer| + offset = 36*layer + 6*row + 16 + print " %3d " % offset + 6.times do |col| + swatch(offset + col) + end + print " " + end + print "\n" + end + print "\n" +end + +def test_grayscale + puts "Grayscale (232-255):" + print " %3d " % 232 + 24.times do |i| swatch(i + 232) end + print "\n\n" +end + + + +##### EXECUTION ##### + +def fail(msg) + STDERR.puts(msg) + exit 1 +end + +# if no arguments, just output test colors +if ARGV.empty? + test_ansi_colors + test_system_colors + test_color_cube + test_grayscale + exit +end + +# otherwise, try to interpret arguments as a color name, number, or rgb hex string +ARGV.each do |arg| + search = arg.strip.downcase + + color = case search + when /^#?[0-9a-f]{6}$/ + hex = search.gsub(/^#/, '') + target = Color.new(nil, :hex => hex) + Color.match(target) + when /^\d+$/ + Color[search.to_i] + else + name = search.gsub(/^(bold|light)/, 'bright').gsub(' ', '') + Color::COLORS.find {|c| c.names.include? name } + end + + fail "#{arg} is not a valid hex value, color number, or color name" unless color + detail(color) +end diff --git a/vim/vim/after/ftplugin/markdown.vim b/vim/vim/after/ftplugin/markdown.vim new file mode 100644 index 0000000..a6e8959 --- /dev/null +++ b/vim/vim/after/ftplugin/markdown.vim @@ -0,0 +1,10 @@ +" Vim settings for markdown files. + +" use 1/2/3 to add headings +nnoremap 1 yypVr= +nnoremap 2 yypVr- +nnoremap 3 I### + +" wrap at 80 characters +set textwidth=80 +set wrapmargin=2 diff --git a/vim/vim/ftdetect/javascript.vim b/vim/vim/ftdetect/javascript.vim index 5739075..a2d216f 100644 --- a/vim/vim/ftdetect/javascript.vim +++ b/vim/vim/ftdetect/javascript.vim @@ -1,3 +1,3 @@ " Detection rules for javascript files -au! BufNewFile,BufRead *.json setfiletype javascript +au! BufNewFile,BufRead *.json set filetype=javascript diff --git a/vim/vim/ftdetect/markdown.vim b/vim/vim/ftdetect/markdown.vim index f68bfd9..799a046 100644 --- a/vim/vim/ftdetect/markdown.vim +++ b/vim/vim/ftdetect/markdown.vim @@ -1,5 +1,5 @@ " Detection rules for markdown files -au! BufNewFile,BufRead *.m*down setfiletype markdown -au! BufNewFile,BufRead *.md setfiletype markdown -au! BufNewFile,BufRead README setfiletype markdown +au! BufNewFile,BufRead *.m*down set filetype=markdown +au! BufNewFile,BufRead *.md set filetype=markdown +au! BufNewFile,BufRead README set filetype=markdown diff --git a/vim/vim/ftdetect/ruby.vim b/vim/vim/ftdetect/ruby.vim new file mode 100644 index 0000000..dbfa13b --- /dev/null +++ b/vim/vim/ftdetect/ruby.vim @@ -0,0 +1,4 @@ +" Detection rules for ruby files + +au! BufNewFile,BufRead Vagrantfile set filetype=ruby +au! BufNewFile,BufRead *.pp set filetype=ruby diff --git a/vim/vim/plugin/syntax-tools.vim b/vim/vim/plugin/syntax-tools.vim index fb7b1ac..8538518 100644 --- a/vim/vim/plugin/syntax-tools.vim +++ b/vim/vim/plugin/syntax-tools.vim @@ -27,4 +27,4 @@ function! SyntaxInfo() echo info endfunction -map :call SyntaxInfo() +nnoremap ` :call SyntaxInfo() diff --git a/vim/vimrc b/vim/vimrc index 0747c6d..15b1851 100644 --- a/vim/vimrc +++ b/vim/vimrc @@ -21,15 +21,13 @@ set backupdir=~/.vim/tmp/ "set undofile set nobackup -" Automatically wrap lines at 100 characters. -set textwidth=100 - -" Load Vundle if present +" Load Vundle if present. if filereadable($HOME . "/.vim/vundle.vim") source $HOME/.vim/vundle.vim endif + " ----- APPEARANCE ----- " enable syntax highlighting @@ -48,6 +46,9 @@ set showmode set showcmd "set visualbell +" Automatically wrap lines at 100 characters. +set textwidth=100 + " scroll when the cursor is within 5 lines of the edge of the window set scrolloff=5 set sidescroll=10 @@ -113,36 +114,32 @@ let mapleader = "," " quick shortcut to clear search highlights nnoremap :noh -" convert tabs to 4 spaces +" convert tabs to spaces nnoremap t :%s/\t/ / nnoremap T :%s/\t/ / " strip trailing whitespace from the file -nnoremap W :%s/\s\+$// +nnoremap s :%s/\s\+$// " add this to unhighlight things: :let @/='' " select text which was just pasted nnoremap v V`] +" reverse the highlighted lines +command! -bar -range=% Reverse ,g/^/m-1|nohl +vnoremap r :Reverse + " use tab to jump to matching enclosure pairs nnoremap % vnoremap % -" toggle line numbers with numbers.vim -nnoremap :NumbersToggle - -" fugitive shortcuts -nnoremap gs :Gstatus -nnoremap gd :Gdiff -nnoremap gl :Glog - " ----- AUTOCOMPLETION ----- " allow autocompletion for commands and menus +set wildmode=longest,list,full set wildmenu -set wildmode=list:longest " ignore VCS directories set wildignore+=.git,.svn diff --git a/vundle/vundle.vim b/vundle/vundle.vim index 929d8a0..c7c1568 100644 --- a/vundle/vundle.vim +++ b/vundle/vundle.vim @@ -1,13 +1,11 @@ " Loads the Vundle Vim plugin manager. To install: -" " 1) Clone the vundle repo: " $ git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle " " 2) Load Vundle in ~/.vimrc: " source ~/.vim/vundle.vim " -" 3) Run :BundleInstall in vim -" +" 3) Run :BundleInstall in vim. filetype off @@ -16,7 +14,6 @@ call vundle#rc() Bundle 'gmarik/vundle' -Bundle 'kchmck/vim-coffee-script' "Bundle 'myusuf3/numbers.vim' Bundle 'tpope/vim-fugitive' Bundle 'tpope/vim-surround' @@ -25,4 +22,24 @@ Bundle 'cakebaker/scss-syntax.vim' " Ledger Bundle 'ledger/vim-ledger' +" Coffeescript +Bundle 'kchmck/vim-coffee-script' + +" Clojure +Bundle 'guns/vim-clojure-static' +Bundle 'amdt/vim-niji' +Bundle 'paredit.vim' + +" SLIME +"Bundle 'jpalardy/vim-slime' +"let g:slime_target = "tmux" +"let g:slime_default_config = {"socket_name": "default", "target_pane": "1"} + filetype plugin indent on + +" Shortcuts + +" fugitive shortcuts +nnoremap gs :Gstatus +nnoremap gd :Gdiff +nnoremap gl :Glog diff --git a/zsh/zprofile b/zsh/zprofile index 0d05c2f..07ac1ba 100644 --- a/zsh/zprofile +++ b/zsh/zprofile @@ -16,3 +16,6 @@ local bin_dir="$HOME/bin" # ensure path only contains unique entries typeset -U path + +# block loading of global RC file +unsetopt global_rcs diff --git a/zsh/zsh/functions/.keep b/zsh/zsh/functions/.keep new file mode 100644 index 0000000..e69de29 diff --git a/zsh/zsh/functions/with_env b/zsh/zsh/functions/with_env new file mode 100644 index 0000000..9b0a3a3 --- /dev/null +++ b/zsh/zsh/functions/with_env @@ -0,0 +1,16 @@ +# Utility function to run a command using an environment provided by a local +# '.env' file. +# +# vim: ft=zsh + +with_env() { + ENV_FILE="$PWD/.env" + if [[ -f "$ENV_FILE" ]]; then + VARS=$(cat $ENV_FILE | grep -v "^#" | tr "\\n" " ") + env $VARS "$@" + else + "$@" + fi +} + +with_env "$@" diff --git a/zsh/zshrc b/zsh/zshrc index 2bed6ab..cfe8690 100644 --- a/zsh/zshrc +++ b/zsh/zshrc @@ -61,20 +61,26 @@ preexec() { +##### TIMING ##### + +# If a command takes more than 10 CPU seconds, automatically print the time it took. +REPORTTIME=10 + +# Format the output of the time command to be a little more human friendly. +TIMEFMT=" Elapsed: %*E User: %U Kernel: %*S" + + + ##### KEY BINDINGS ##### # use vim-style key bindings bindkey -v -# RHEL5 desktop -bindkey '^[OH' beginning-of-line -bindkey '^[OF' end-of-line - -# PuTTY +# home/end (PuTTY/OS X) bindkey '^[[1~' beginning-of-line bindkey '^[[4~' end-of-line -# MinTTY +# home/end (MinTTY) bindkey '^[[H' beginning-of-line bindkey '^[[F' end-of-line @@ -111,20 +117,19 @@ export PAGER='less' export EDITOR='vim' # common aliases +alias u='cd ..' +alias uu='cd ../..' +alias uuu='cd ../../..' +alias uuuu='cd ../../../..' +alias uuuuu='cd ../../../../..' alias d='dirs -v' alias ls='ls --color=auto' alias ll='ls -lh --color=auto' alias la='ls -lhA --color=auto' +alias bc='bc -lq' alias tmux='tmux -2' - - - -##### TIMING ##### - -# If a command takes more than 10 CPU seconds, automatically print the time it took. -REPORTTIME=10 -# Format the output of the time command to be a little more human friendly. -TIMEFMT=" Elapsed: %*E User: %U Kernel: %*S" +alias gd='git diff' +alias gs='git status'