Skip to content

Instantly share code, notes, and snippets.

@pyriand3r
Forked from coderofsalvation/snippy.sh
Last active August 22, 2017 08:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyriand3r/7df1e653d0bb2d9428a43d08b7baf6b7 to your computer and use it in GitHub Desktop.
Save pyriand3r/7df1e653d0bb2d9428a43d08b7baf6b7 to your computer and use it in GitHub Desktop.
modified version of snippy which features easier installation, follows symlinks, bashdown templates and automatic detection of cli vs window. This version also combines snippy.sh and snippy_1line.sh, making it possible to use both with just one script. Default the file ~/.snippy/oneliner is used, if you start snippy with the paramter `multi` the…
#!/usr/bin/env bash
# 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)
# and the modified version by "coderofsalvation"
# (https://gist.github.com/coderofsalvation/46549e3788ade2f3a938)
#
# You will also need "dmenu", "xsel" and "xdotool". Get them from your linux
# distro in the usual way.
#
# To use:
# (On first start the folders and demo files are created)
# 1. Create the directory ~/.snippy
#
# 2. For single line snippets (default mode) add lines to the file ~/.snippy/oneliner
# in the format:
#
# [title] the snippet to insert
#
# 2. For multiline snippets create a file in the 'multi' subdirectory
# 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/multi.
#
# 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")
#
# For normal execution (oneliner) you only have to call the script (./snippy.sh). If
# you want to use the multiline snippets start snippy with the 'multi' parameter
# (./snippy multi)
#
DIR=${HOME}/.snippy
ONE_LINER=${DIR}/oneliner
MULTI_DIR=${DIR}/multi
APPS="xdotool xsel dmenu"
DMENU_ARGS="-b"
TMPFILE="/tmp/.snippy.tmp"; :>$TMPFILE
# if nothing happens, try "xdotool click 2", "xdotool key ctrl+v" or "xdotool key ctrl+shift+v"
GUIPASTE="xdotool click 2"
CLIPASTE="xdotool key ctrl+v"
MULTI="false"
if [ "$1" = "multi" ]; then
echo "multi"
MULTI="true"
fi
# 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(){
txt="$(cat - )"; lines="$(cat ${DIR}/${FILE} | wc -l )"
(( lines > 1 )) && enter="\n" || enter=""
IFS=''; echo "$txt" | while read line; do
[[ "$line" =~ '$' ]] && line="$(eval "printf \"$( printf "%s" "$line" | sed 's/"/\\"/g')\"")";
printf "$line""$enter"
done
}
init(){
for APP in $APPS; do
which $APP &>/dev/null || {
read -p "install the following required utils? : $APPS (y/n)" reply
[[ "$reply" == "y" ]] && sudo apt-get install ${APPS};
}
done
[[ ! -d "$DIR" ]] && {
echo -e "created $DIR\n";
mkdir -p "${MULTI_DIR}";
printf 'hi it is $(date)' > "${MULTI_DIR}""/test";
touch "${ONE_LINER}"
echo "[hello] hi it is $(date)" > ${ONE_LINER}
}
return 0
}
run(){
if [ "${MULTI}" = "true" ]; then
cd ${MULTI_DIR}
# Use the filenames in the snippy directory as menu entries.
# Get the menu selection from the user.
selection=`find -L . -type f | grep -v '^\.$' | sed 's!\.\/!!' | /usr/bin/dmenu ${DMENU_ARGS}`
else
selection=`sed 's/\].*/]/' ${ONE_LINER} | /usr/bin/dmenu ${DMENU_ARGS}`
fi
# If dmenu is closed with esc do nothing
if [ "$?" = "1" ]; then
exit
fi
if [ "${MULTI}" = "true" ]; then
if [ -f ${MULTI_DIR}/${selection} ]; then
# Put the contents of the selected file into the paste buffer.
content="$(cat ${MULTI_DIR}/${selection} | bashdown)"
[[ "${#content}" == 0 ]] && printf "${selection}" > $TMPFILE || printf "%s" "$content" > $TMPFILE
else
${selection} &> $TMPFILE # execute as bashcommand
fi
else
# Strip out the square brackets...
pattern=`echo ${selection} | tr -d "[]"`
# ...and put them back in, escaped with a backslash.
# Get the text associated with the selection.
text=`grep "\[$pattern\]" ${ONE_LINER} | sed "s/\[$pattern\] //" | bashdown`
printf "%s" "$text" > $TMPFILE
fi
xsel --input < $TMPFILE
# Paste into the current application.
[[ is_window ]] && ${GUIPASTE} || ${CLIPASTE} # cli or gui paste
}
is_window(){
name="$(xdotool getwindowname $(xdotool getwindowfocus) | tr '[:upper:]' '[:lower:]')"
[[ ! "$name" =~ term|tilda ]] && return 1
return 0
}
init && run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment