Skip to content

Instantly share code, notes, and snippets.

@opennomad
Forked from coderofsalvation/snippy.sh
Last active November 5, 2019 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save opennomad/15c4d624dce99066a82d to your computer and use it in GitHub Desktop.
Save opennomad/15c4d624dce99066a82d to your computer and use it in GitHub Desktop.
Snippy text expander
#!/usr/bin/env bash
# video demo at: http://www.youtube.com/watch?v=90xoathBYfk
# 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"
CONFIG=${HOME}/.snippy.conf
APPS="xdotool xsel dmenu zenity"
DIR=${HOME}/.snippy
MENU_ENGINE="dmenu"
DMENU_ARGS='-b'
ZENITY_ARGS='--list --hide-header --column=Snippet --text=snippy'
# 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
# source the config file if it exists
[[ -f ${CONFIG} ]] && source ${CONFIG}
# set the menu options depending on the engine
case ${MENU_ENGINE} in
'dmenu')
MENU_ARGS=${DMENU_ARGS}
;;
'zenity')
MENU_ARGS=${ZENITY_ARGS}
;;
'rofi')
MENU_ARGS=${ROFI_ARGS}
;;
*)
echo "incorrecty MENU_ENGINE: ${MENU_ENGINE} for snippy"
exit 1
esac
# 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}")
}
init(){
for APP in $APPS; do
command -v "$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 "$DIR";
printf "hi it is \$(date)" > "$DIR/test";
}
return 0
}
run(){
cd "${DIR}"
# Use the filenames in the snippy directory as menu entries.
# Get the menu selection from the user.
FILE=$(find -L . -type f | sort | grep -v '^\.$' | sed 's!\.\/!!' | ${MENU_ENGINE} ${MENU_ARGS})
# FILE=$(find -L . -type f | grep -v '^\.$' | sed 's!\.\/!!' | zenity )
# 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.
content="$(bashdown < "${DIR}/${FILE}")"
echo "::::${content}::::"
if [[ "${#content}" == 0 ]]; then
printf "%s" "${FILE}" > $TMPFILE
else
printf "%s" "$content" > $TMPFILE
fi
else
${FILE} &> $TMPFILE # execute as bashcommand
fi
xsel -b --input < $TMPFILE
# Paste into the current application.
if is_window; then
${GUIPASTE}
else
${CLIPASTE}
fi
}
is_window(){
name="$(xdotool getwindowname "$(xdotool getwindowfocus)" | tr '[:upper:]' '[:lower:]')"
[[ "$name" =~ term|tilda|@${HOSTNAME} ]] && return 1
return 0
}
init && run
@BarbUk
Copy link

BarbUk commented Nov 5, 2016

Hi,

I have made some modifications:

  • restore current clipboard
  • {clipboard} placeholder to use current clipboard in snippet
  • {cursor} placeholder to place the cursor

https://github.com/BarbUk/dotfiles/blob/master/bin/snippy

@masterdam79
Copy link

This snippy actually works best for me, other snippy.sh scripts keep pasting other clipboard content previously copied.

Thanks!

@BarbUk
Copy link

BarbUk commented Dec 22, 2018

New version available: 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
    • go left to the correct position for cli and gui paste
    • go up for block snippet for gui paste
  • ##noparse header in snippet to not parse
  • execute command begining by $

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment