Last active
May 5, 2018 15:46
-
-
Save petonic/87271b4a71d64d5429b5e6c7dd0d2da0 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
stub |
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 bash | |
# Name of my laptop to check if we're local editing | |
master_hostname="kaypro" | |
local_editor_cmd="atom" | |
# | |
# Petonic version {2016-11-20 SUN 12:54} | |
# Modified for ///READONLY/// auto -f {2016-11-26 SAT 10:01} | |
# Modified for USE_NFS mountpoint [2017-04-16 SUN 12:57] | |
# | |
# rmate | |
# Copyright (C) 2011-2015 by Harald Lapp <harald@octris.org> | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
# This script can be found at: | |
# https://github.com/aurora/rmate | |
# | |
# | |
# This script is a pure bash compatible shell script implementing remote | |
# textmate functionality | |
# | |
# | |
# Thanks very much to all users and contributors! All bug-reports, | |
# feature-requests, patches, etc. are greatly appreciated! :-) | |
# | |
# init | |
# | |
version="0.9.6" | |
version_date="2015-09-15" | |
version_string="rmate-sh $version ($version_date)" | |
# determine hostname | |
function hostname_command(){ | |
if command -v hostname >/dev/null 2>&1; then | |
echo "hostname" | |
else { | |
HOSTNAME_DESCRIPTOR="/proc/sys/kernel/hostname" | |
if test -r "$HOSTNAME_DESCRIPTOR"; then | |
echo "cat $HOSTNAME_DESCRIPTOR" | |
else | |
echo "hostname" | |
fi | |
} | |
fi | |
} | |
hostname=$($(hostname_command)) | |
readonly="" | |
[ -n "$SUDO_UID" ] && sudo_string=" ### " | |
# default configuration | |
host=localhost | |
port=52698 | |
function load_config { | |
local rc_file=$1 | |
local row | |
local host_pattern="^host(:[[:space:]]+|=)([^ ]+)" | |
local port_pattern="^port(:[[:space:]]+|=)([0-9]+)" | |
readonly="" | |
if [ -f "$rc_file" ]; then | |
while read row; do | |
if [[ "$row" =~ $host_pattern ]]; then | |
host=${BASH_REMATCH[2]} | |
elif [[ "$row" =~ $port_pattern ]]; then | |
port=${BASH_REMATCH[2]} | |
fi | |
done < "$rc_file" | |
fi | |
} | |
for i in "/etc/${0##*/}" ~/."${0##*/}/${0##*/}.rc" ~/."${0##*/}.rc"; do | |
load_config $i | |
done | |
host="${RMATE_HOST:-$host}" | |
port="${RMATE_PORT:-$port}" | |
logger "=--------------- Rmate: start of args" | |
for i in "$@"; do | |
logger "rmate arg is <$i>" | |
done | |
# misc initialization | |
filepaths=() | |
displaynames=() | |
selections=() | |
filetypes=() | |
verbose=false | |
nowait=true | |
force=false | |
check_only=false | |
use_nfs=true | |
# process command-line parameters | |
# | |
function showusage { | |
echo "usage: $(basename $0) [arguments] file-path edit specified file | |
or: $(basename $0) [arguments] - read text from stdin | |
-H, --host HOST Connect to HOST. Use 'auto' to detect the host from | |
SSH. Defaults to $host. | |
-p, --port PORT Port number to use for connection. Defaults to $port. | |
-w, --[no-]wait Wait for file to be closed by TextMate. | |
-l, --line LINE Place caret on line number after loading file. | |
-m, --name NAME The display name shown in TextMate. | |
-t, --type TYPE Treat file as having specified type. | |
-n, --new Open in a new window (Sublime Text). | |
-r, --remote Do not use .atom-nfs config files | |
-v, --verbose Verbose logging messages. | |
-h, --help Display this usage information. | |
-f, --force Force previous App to activate when editing is done | |
-c, --check Returns immediately. Status set whether RATOM is running. | |
--version Show version and exit. | |
" | |
} | |
function log { | |
if [[ $verbose = true ]]; then | |
echo "$@" 1>&2 | |
fi | |
logger "$@" | |
} | |
function dirpath { | |
(cd `dirname "$1"` >/dev/null 2>/dev/null; pwd -P) | |
} | |
function canonicalize { | |
filepath="$1" | |
dir=`dirpath "$filepath"` | |
if [ -L "$filepath" ]; then | |
relativepath=`cd "$dir"; readlink \`basename "$filepath"\`` | |
result=`dirpath "$relativepath"`/`basename "$relativepath"` | |
else | |
result=`basename "$filepath"` | |
if [ "$dir" = '/' ]; then | |
result="$dir$result" | |
else | |
result="$dir/$result" | |
fi | |
fi | |
echo $result | |
} | |
while test "${1:0:1}" = "-"; do | |
case $1 in | |
-) | |
break | |
;; | |
-H|--host) | |
host=$2 | |
shift | |
;; | |
-p|--port) | |
port=$2 | |
shift | |
;; | |
-w|--wait) | |
nowait=false | |
;; | |
--no-wait) | |
nowait=true | |
;; | |
-l|--line) | |
selections+=($2) | |
shift | |
;; | |
-r|--remote) | |
use_nfs=false | |
shift | |
;; | |
-m|--name) | |
displaynames+=("$2") | |
shift | |
;; | |
-t|--type) | |
filetypes+=($2) | |
shift | |
;; | |
-n|--new) | |
new=true | |
;; | |
-f|--force) | |
force=true | |
;; | |
-c|--check) | |
check_only=true | |
;; | |
-v|--verbose) | |
verbose=true | |
;; | |
--version) | |
echo $version_string | |
exit 1 | |
;; | |
-h|-\?|--help) | |
showusage | |
exit 1 | |
;; | |
*) | |
showusage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
if [[ "$host" = "auto" && "$SSH_CONNECTION" != "" ]]; then | |
host=${SSH_CONNECTION%% *} | |
fi | |
filepaths=("$@") | |
if [ "$filepaths" = "" ]; then | |
if [[ $nowait = false ]]; then | |
filepaths='-' | |
else | |
case "$-" in | |
*i*) | |
showusage | |
exit 1 | |
;; | |
*) | |
filepaths='-' | |
;; | |
esac | |
fi | |
fi | |
#------------------------------------------------------------ | |
# main | |
#------------------------------------------------------------ | |
function open_file { | |
index="$1" | |
filepath="${filepaths[$index]}" | |
selection="${selections[$index]}" | |
filetype="${filetypes[$index]}" | |
displayname="${displaynames[$index]}" | |
if [ "$filepath" != "-" ]; then | |
realpath=`canonicalize "$filepath"` | |
log $realpath | |
# Check to see if we're on my laptop | |
if [[ $hostname = $master_hostname ]]; then | |
$local_editor_cmd "$filepath" | |
else | |
if [ -d "$filepath" -a ! ${use_nfs} ]; then | |
log "$filepath is a directory and rmate is unable to handle directories." | |
exit 1 | |
fi | |
if [ -f "$realpath" -a ! -w "$realpath" ]; then | |
readonly="///READONLY/// - " | |
if [[ $verbose = true ]]; then | |
log "File $filepath is not writable! Opening anyway." | |
fi | |
fi | |
if [ "$displayname" = "" ]; then | |
displayname="$hostname:$filepath" | |
fi | |
fi | |
else | |
displayname="$hostname:untitled" | |
fi | |
displayname="${readonly}_SSH_${displayname}" | |
[ "$sudo_string" ] && displayname="${sudo_string} ${displayname} ${sudo_string}" | |
nfs_pathname="" | |
if ${use_nfs} ; then | |
nfs_map="`rnfs ${realpath} 2>/dev/null`" && nfs_pathname="${nfs_map}" | |
fi | |
# echo "use_nfs = <$use_nfs>" | |
# echo "nfs_map = <$nfsmap>" | |
# echo "nfs_pathname = <$nfs_pathname>" | |
echo "open" 1>&3 | |
echo "display-name: ///NFS/// $displayname" 1>&3 | |
echo "real-path: NFS_$realpath" 1>&3 | |
echo "data-on-save: yes" 1>&3 | |
echo "re-activate: yes" 1>&3 | |
if [ -n "${nfs_pathname}" ]; then | |
echo "nfs-open: ${nfs_pathname}" 1>&3 | |
echo "Using NFS-OPEN with <${nfs_pathname}>" | |
# exit 9 | |
fi | |
echo "token: $filepath" 1>&3 | |
if [[ $new = true ]]; then | |
echo "new: yes" 1>&3 | |
fi | |
if [ "$selection" != "" ]; then | |
echo "selection: $selection" 1>&3 | |
fi | |
if [ "$filetype" != "" ]; then | |
echo "file-type: $filetype" 1>&3 | |
fi | |
if [ "$filepath" != "-" ] && [ -f "$filepath" ]; then | |
filesize=`ls -lLn "$realpath" | awk '{print $5}'` | |
echo "data: $filesize" 1>&3 | |
cat "$realpath" 1>&3 | |
elif [ "$filepath" = "-" ]; then | |
if [ -t 0 ]; then | |
echo "Reading from stdin, press ^D to stop" | |
else | |
log "Reading from stdin" | |
fi | |
# preserve trailing newlines | |
data=`cat; echo x` | |
data=${data%x} | |
filesize=$(echo -ne "$data" | wc -c) | |
echo "data: $filesize" 1>&3 | |
echo -n "$data" 1>&3 | |
else | |
echo "data: 0" 1>&3 | |
fi | |
echo 1>&3 | |
} | |
function handle_connection { | |
local cmd | |
local name | |
local value | |
local token | |
local tmp | |
while read 0<&3; do | |
REPLY="${REPLY#"${REPLY%%[![:space:]]*}"}" | |
REPLY="${REPLY%"${REPLY##*[![:space:]]}"}" | |
cmd=$REPLY | |
token="" | |
tmp="" | |
while read 0<&3; do | |
REPLY="${REPLY#"${REPLY%%[![:space:]]*}"}" | |
REPLY="${REPLY%"${REPLY##*[![:space:]]}"}" | |
if [ "$REPLY" = "" ]; then | |
break | |
fi | |
name="${REPLY%%:*}" | |
value="${REPLY##*:}" | |
value="${value#"${value%%[![:space:]]*}"}" # fix textmate syntax highlighting: " | |
case $name in | |
"token") | |
token=$value | |
;; | |
"data") | |
if [ "$tmp" = "" ]; then | |
tmp="/tmp/rmate.$RANDOM.$$" | |
touch "$tmp" | |
fi | |
dd bs=1 count=$value <&3 >>"$tmp" 2>/dev/null | |
;; | |
*) | |
;; | |
esac | |
done | |
if [[ "$cmd" = "close" ]]; then | |
log "Closing $token" | |
if [[ "$token" == "-" ]]; then | |
echo -n "$CONTENT" | |
fi | |
if [[ "$nowait" != "" ]]; then | |
printf "\e]1337;StealFocus\a" | |
fi | |
elif [[ "$cmd" = "save" ]]; then | |
log "Saving $token" | |
if "$force"; then | |
# If nowait, then any save will restore focus | |
if [[ "$nowait" = "" ]]; then | |
printf "\e]1337;StealFocus\a" | |
fi | |
fi | |
if [ "$token" != "-" ]; then | |
cat "$tmp" > "$token" | |
else | |
CONTENT=`cat "$tmp"` | |
fi | |
rm "$tmp" | |
fi | |
done | |
if "$force"; then | |
printf "\e]1337;StealFocus\a" | |
# khd -p 'cmd - tab' > /dev/null | |
# khd -p '- return' > /dev/null | |
fi | |
log "Done" | |
} | |
# connect to textmate and send command | |
# | |
exec 3<> /dev/tcp/$host/$port | |
if [ $? -gt 0 ]; then | |
echo "Unable to connect to TextMate on $host:$port" | |
exit 1 | |
fi | |
# Petonic 2017-04-30: Added the -c flag to check for RMATE server | |
# connectivity | |
if "$check_only"; then | |
echo "check" 1>&3 | |
exit 0 | |
fi | |
read server_info 0<&3 | |
log $server_info | |
for i in "${!filepaths[@]}"; do | |
open_file "$i" | |
done | |
echo "." 1>&3 | |
if [[ $nowait = true ]]; then | |
exec </dev/null 2>/dev/null | |
( (handle_connection &) &) | |
else | |
force=true | |
handle_connection | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment