joplin-snippy/snippy
2018-04-22 09:50:52 +04:00

138 lines
4.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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="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 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} &> $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