-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathnlua
executable file
·92 lines (84 loc) · 2.8 KB
/
nlua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/bin/bash
###############################################################################
# Wrapper for Neovim that takes a lua (or vimscript) file as argument and #
# executes it. This essentially makes it possible to use Neovim as a #
# standalone interpreter and enables regular scripts to benefit from the #
# Neovim API (e.g. when used as a shebang). Without any arguments this #
# wrapper starts an interactive nvim lua REPL. #
###############################################################################
set -o errexit -o pipefail -o nounset
histfile=${XDG_DATA_HOME:-~/.local/share}/nvim/$(basename "$0")_history
function send(){
printf "%s\n" "$*" >& "${COPROC[1]}"
}
function hist(){
case "$1" in
load)
mkdir -p "$(dirname "$histfile")"
touch "$histfile"
history -r "$histfile"
;;
append)
history -s -- "$2"
history -a "$histfile"
esac
}
function repl(){
local cmd prefix
while [[ -z "${cmd:-}" ]]; do
read -rep '> ' -d $'\r' || exit 0
cmd=$REPLY prefix=""
# hack to find out if the line can be interpreted as an expression to print
# its value, similar to what lua 5.3 does (see
# http://www.lua.org/manual/5.3/manual.html#7).
if luajit -e "assert(function() return $cmd end)" 2>/dev/null; then
prefix="="
else
# Extremely ugly hack to find out if statement should continue on next
# line. Luajit error messages which expect statements to continue seem to
# end with "'<eof>'".
while [[ $(luajit -e "$cmd" 2>&1) == *"'<eof>'" ]]; do
read -rep '>> ' -d $'\r' || { cmd=''; break; }
cmd+=$'\n'$REPLY
done
fi
done
hist append "$cmd"
send verbose lua "${prefix:-}${cmd//$'\n'/ }"
# Use SIGUSR1 to find out when vim finished processing cmd to continue the
# repl
send "!kill -USR1 $BASHPID"
}
# https://stackoverflow.com/a/52944692
function get_cursor_pos(){
IFS='[;' read -p $'\e[6n' -d R -rs _ y x _
printf '%s\n' "$x:$y"
}
function add_newline(){
# vim doesn't insert newlines on eol, so we have to do it ourselves
if [[ $(get_cursor_pos) != 1:* ]]; then
printf '\n'
fi
}
case "${1:-}" in
"") # without arguments start interactive repl
hist load
nvim --version | sed '/^$/,$d'
coproc nvim -es -i NONE
trap "add_newline && repl" SIGUSR1
repl
# use a loop as wait returns when a signal with a trap is received
until wait; do
:
done
;;
--help|-h)
printf "%s\n%s\n %s\n" \
"usage: $(basename "$0") [options] [script [args]]" \
"Available options are:" \
"-h print this help message and exit (also --help)"
;;
*) # treat arg as a file
# use 'echo""' to append a final end-of-line indicator
exec nvim -c 'autocmd VimLeave * :echo ""' -l "$@"
esac