#!/usr/bin/env bash # video demo at: http://www.youtube.com/watch?v=90xoathBYfk # augmented by barbuk: https://github.com/BarbUk/dotfiles/blob/master/bin/snippy # . restore current clipboard # . {clipboard} placeholder to use current clipboard in snippet # . {cursor} placeholder to place the cursor # . ##noparse header in snippet to not parse # augmented by "opennomad": https://gist.github.com/opennomad/15c4d624dce99066a82d # originally written by "mhwombat": https://bbs.archlinux.org/viewtopic.php?id=71938&p=2 # Based on "snippy" by "sessy" # (https://bbs.archlinux.org/viewtopic.php?id=71938) # # You will also need "dmenu", "zenity", "xsel" and "xdotool". Get them from your linux # distro in the usual way. # # To use: # 1. Create the directory ~/.snippy # # 2. Create a file in that directory for each snippet that you want. # The filename will be used as a menu item, so you might want to # omit the file extension when you name the file. # # TIP: If you have a lot of snippets, you can organise them into # subdirectories under ~/.snippy. # # TIP: The contents of the file will be pasted asis, so if you # don't want a newline at the end when the text is pasted, don't # put one in the file. # # 3. Bind a convenient key combination to this script. # # TIP: If you're using XMonad, add something like this to xmonad.hs # ((mod4Mask, xK_s), spawn "/path/to/snippy") # # 4. Set variables in ~/.snippy.conf. for example # MENU_ENGINE="dmenu" # DMENU_ARGS=' -p snippy -fn arial -sf green' # ZENITY_ARGS='--list --hide-header --column=Snippet --text=snippy' # GUIPASTE="xdotool key ctrl+v" # CLIPASTE="xdotool key ctrl+shift+v" DIR=${HOME}/.snippy MENU_ENGINE="dmenu" . "$HOME/.dmenurc" DMENU_ARGS="$DMENU_CONF -l 10 -p Snippets:" # if nothing happens, try "xdotool click 2", "xdotool key ctrl+v" or "xdotool key ctrl+shift+v" GUIPASTE="xdotool key ctrl+v" CLIPASTE="xdotool key ctrl+shift+v" TMPFILE="/tmp/.snippy.tmp"; :>$TMPFILE MENU_ARGS=${DMENU_ARGS} # smarty like template engine which executes inline bash in (bashdown) strings (replaces variables with values e.g.) # @link http://github.com/coderofsalvation/bashdown # @dependancies: sed cat # @example: echo 'hi $NAME it is $(date)' | bashdown # fetches a document and interprets bashsyntax in string (bashdown) templates # @param string - string with bash(down) syntax (usually surrounded by ' quotes instead of ") bashdown(){ while read -r line; do line="$(eval "printf -- \"$( printf "%s" "$line" | sed 's/"/\\"/g')\"")"; echo -e "$line" done < <(cat "${DIR}/${FILE}") } run(){ cd "${DIR}" || exit # Use the filenames in the snippy directory as menu entries. # Get the menu selection from the user. FILE=$(find -L . -type f | grep -v '^\.$' | sed 's!\.\/!!' | grep -v .git/ | ${MENU_ENGINE} ${MENU_ARGS}) # just return if nothing was selected [[ -z "${FILE}" ]] && return 1 if [ -f "${DIR}/${FILE}" ]; then # Put the contents of the selected file into the paste buffer. # don't parse file with the ##noparse header if grep -qE "^##noparse" "${FILE}"; then content="$(tail -n +2 "${DIR}/${FILE}")" else content="$(bashdown < "${DIR}/${FILE}")" fi printf "%s" "$content" > $TMPFILE else ${FILE} &> $TMPFILE # execute as bashcommand fi local current_clip cursor current_clip=$(xsel -b) # define cursor at -1, we don't need to go up if there is no {cursor} cursor=0 # replace {clipboard} by the cliboard comtent sed -i -e "s_{clipboard}_${current_clip}_g" "$TMPFILE" # Check if there is a {cursor} placeholder if grep -qF '{cursor}' "$TMPFILE";then local file_lines # retrieve the line cursor=$(grep -n '{cursor}' "$TMPFILE" | cut -d: -f1) # calculate snippet total lines file_lines=$(wc -l < "$TMPFILE") # determine the number of line to go cursor=$((file_lines - cursor)) # remove the placeholder sed -i -e "s/{cursor}//g" "$TMPFILE" fi xsel -b --input < "$TMPFILE" # Paste into the current application. if is_window; then ${GUIPASTE} if [[ $cursor -gt 0 ]]; then local keyup until [ $cursor -eq 0 ]; do keyup+="Up " let cursor-=1 xdotool key --delay -0.1 $keyup done fi else ${CLIPASTE} fi echo -ne "$current_clip" | xsel -b --input } is_window(){ name="$(xprop -id "$(xdotool getwindowfocus)" WM_CLASS | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')" [[ "$name" =~ term|tilda ]] && return 1 return 0 } run