Last active
February 27, 2017 12:54
-
-
Save xorian/be19359b644a33f9947480bc8e7c7be0 to your computer and use it in GitHub Desktop.
This file contains 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 zsh | |
# ---------------------------------------------------------------------- | |
# Send the standard input into a running emacs server, either on the | |
# kill ring, in a specified register, or in a new buffer. Examples: | |
# echo -n some text into the kill ring | into-emacs | |
# echo -n other text into register 1 | into-emacs -r 1 | |
# long_command | into-emacs -b "long command output" | |
# Caveats: | |
# - If -b (buffer name) is used, -r (register name) is ignored. | |
# - The name given to -m (mode) must match an emacs mode function | |
# - (i.e. -m foo will execute (foo-mode) in emacs). | |
# - Only the first character of the argument to the -r flag is | |
# significant (as emacs registers are named by a single character). | |
# Any more characters will be ignored. | |
# ---------------------------------------------------------------------- | |
# Buffer name to place the text into. | |
buffer_name= | |
# Mode to switch to for the buffer, if any | |
buffer_mode= | |
# Register to place the text into. If empty (the default), the text | |
# will be added to the kill ring. | |
register= | |
# Command-line flags: | |
# -r <register> : Put the text into a register instead of the kill ring | |
# -b <name> : Put the text into a buffer with the given name | |
# -m <mode> : When used with -b, switch the buffer to the given mode | |
while getopts r:b:m: opt; do | |
case "$opt" in | |
r) register=$OPTARG;; | |
b) buffer_name=$OPTARG;; | |
m) buffer_mode=$OPTARG;; | |
\?) # unknown flag | |
echo >&2 \ | |
"usage: $0 [-r register | -b name [-m mode]]" | |
exit 1;; | |
esac | |
done | |
# Create a temporary directory holding a named pipe which will be | |
# removed when this script exits | |
umask 077 | |
tmpdir=`mktemp -d /tmp/into-emacs-XXXXXX` | |
trap 'rm -rf "${tmpdir}"' EXIT INT TERM HUP | |
pipe="${tmpdir}/pipe" | |
mkfifo "${pipe}" | |
# Send the standard input of the script into the pipe (and on to | |
# emacs) in the background. (This requires some file descriptor | |
# gymnastics, as background processes often get /dev/null as their | |
# standard input rather than inheriting the standard input of the | |
# caller.) | |
exec 3<&0 | |
cat <&3 3<&- > $pipe & | |
exec 3<&- | |
# Build up elisp to have emacs evaluate | |
if [ -n "${buffer_name}" ]; then | |
# Create a buffer with the specified name, possibly uniquified. | |
# Read from the pipe, mark the buffer as unmodified and read only, | |
# and switch to it. If requested, set the mode of the buffer. | |
# Add a local keybinding for "C-x #" to kill the buffer and close | |
# the frame. (This isn't a normal edit server buffer, but this | |
# preserves the behaior as if it were.) | |
from_pipe="(insert-file-contents \"${pipe}\") (not-modified) (read-only-mode)" | |
show_buf="(switch-to-buffer (current-buffer))" | |
set_mode="" | |
if [ -n "${buffer_mode}" ]; then | |
set_mode="(${buffer_mode}-mode)" | |
fi | |
exit_key="(local-set-key (kbd \"C-x #\") (lambda () (interactive) (kill-buffer (current-buffer)) (delete-frame (selected-frame))))" | |
to_eval="(with-current-buffer (generate-new-buffer \"*${buffer_name}*\") ${from_pipe} ${set_mode} ${show_buf} ${exit_key})" | |
# Run emacsclient in the foreground (which it needs to be, since | |
# we will interact with it) | |
emacsclient -t --eval "${to_eval}" | |
else | |
# Read from our named pipe into a string value | |
read_pipe="(with-temp-buffer (insert-file-contents \"${pipe}\") (buffer-string))" | |
if [ -n "${register}" ]; then | |
# Put the text into the specified register | |
to_eval="(set-register (string-to-char \"${register}\") ${read_pipe})" | |
else | |
# No register specified: put the text on the kill ring | |
to_eval="(kill-new ${read_pipe})" | |
fi | |
# Have emacs read from the pipe but discard its output | |
emacsclient --eval "${to_eval}" < /dev/null > /dev/null | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment