-
-
Save BarbUk/58e5adac253648d6385f961da95128e6 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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
# . execute command begining by $ | |
# | |
# 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="rofi" | |
DMENU_ARGS='-dmenu -i -sort -lines 25' | |
# 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 IFS= read -r line; do | |
line="$(eval "printf -- \"$( printf "%s" "$line" | sed 's/"/\\"/g')\"")"; | |
echo -e "$line" | |
done | |
} | |
is_gui(){ | |
name="$(xprop -id "$(xdotool getwindowfocus)" WM_CLASS | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')" | |
[[ "$name" =~ term|tilda ]] && return 1 | |
return 0 | |
} | |
run(){ | |
cd "${DIR}" || exit | |
# Use the filenames in the snippy directory as menu entries. | |
# Get the menu selection from the user. | |
# shellcheck disable=SC2086 | |
FILE=$(find -L . -type f | grep -v '^\.$' | sed 's!\.\/!!' | grep -vE '\.git/|\.gitconfig|\.gitkeep' | ${MENU_ENGINE} ${MENU_ARGS} -p '❯ ') | |
# 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} =~ ^$ ]] | |
${FILE##*$} 2>/dev/null > $TMPFILE # execute as bashcommand | |
fi | |
local current_clip cursor | |
current_clip=$(xsel -b) | |
# define cursor at 0, 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_gui; then | |
${GUIPASTE} | |
if [[ $cursor -gt 0 ]]; then | |
local keyup | |
until [ $cursor -eq 0 ]; do | |
keyup+="Up " | |
((cursor-=1)) | |
# shellcheck disable=SC2086 | |
xdotool key --delay -0.1 $keyup | |
done | |
fi | |
else | |
${CLIPASTE} | |
fi | |
echo -ne "$current_clip" | xsel -b --input | |
} | |
run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment