-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheditor.sh
More file actions
executable file
·119 lines (97 loc) · 4.32 KB
/
editor.sh
File metadata and controls
executable file
·119 lines (97 loc) · 4.32 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env bash
# examples/editor.sh — Interactive multiline text editor using shellframe
#
# Usage: ./editor.sh [file]
# With no arguments, starts with a blank buffer.
# With a file argument, loads the file content for editing.
# On Ctrl-D, exits and prints the final text to stdout.
# On Ctrl-C, exits without output.
#
# Keys:
# ↑ ↓ ← → — navigate
# Home / End — start / end of line (also Ctrl-A / Ctrl-E)
# Enter — insert newline
# Backspace — delete before cursor; joins lines at col 0
# Delete — delete at cursor; joins lines at EOL
# Ctrl-K — clear to end of line
# Ctrl-U — clear to start of line
# Ctrl-W — clear last word
# Ctrl-D — submit (prints text to stdout, exits)
# Ctrl-C — quit without output
set -u
SHELLFRAME_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SHELLFRAME_DIR/shellframe.sh"
# ── Load initial content ───────────────────────────────────────────────────────
SHELLFRAME_EDITOR_LINES=()
if [[ "${1:-}" != "" && -f "$1" ]]; then
while IFS= read -r _line; do
SHELLFRAME_EDITOR_LINES+=("$_line")
done < "$1"
fi
# ── Terminal setup ─────────────────────────────────────────────────────────────
#
# All terminal escape sequences write to /dev/tty directly so they reach the
# real terminal even if stdout is redirected. The result is printed to stdout
# after cleanup so callers can capture it with $().
saved_stty=$(shellframe_raw_save)
_cleanup() {
shellframe_raw_exit "$saved_stty"
printf '\033[?25h' >/dev/tty # show cursor
printf '\033[?1049l' >/dev/tty # exit alternate screen buffer
}
# EXIT fires on every exit path (normal, error, Ctrl-C).
# INT/TERM just trigger exit so the EXIT trap handles cleanup.
trap '_cleanup' EXIT
trap 'exit 1' INT TERM
# Enter the TUI
printf '\033[?1049h\033[H\033[3J\033[2J' >/dev/tty # alt screen + clear
printf '\033[?25l' >/dev/tty # hide cursor
shellframe_raw_enter
# ── Init widget ────────────────────────────────────────────────────────────────
SHELLFRAME_EDITOR_CTX="main"
SHELLFRAME_EDITOR_FOCUSED=1
shellframe_editor_init "main"
# ── Draw ───────────────────────────────────────────────────────────────────────
_draw() {
local cols rows
cols=$(tput cols)
rows=$(tput lines)
local count row col
count=$(shellframe_editor_line_count "main")
row=$(shellframe_editor_row "main")
col=$(shellframe_editor_col "main")
# Header bar (row 1)
printf '\033[1;1H\033[2K\033[7m%-*s\033[0m' "$cols" \
" shellframe editor | ln $(( row + 1 ))/$count col $(( col + 1 )) | Ctrl-D submit Ctrl-C quit" \
>/dev/tty
# Editor body (rows 2 .. rows-1)
local body_rows=$(( rows - 2 ))
shellframe_editor_render 2 1 "$cols" "$body_rows"
# Footer bar (last row)
printf '\033[%d;1H\033[2K\033[2m%-*s\033[0m' "$rows" "$cols" \
" ↑↓←→ navigate Enter newline Bksp/Del delete Ctrl-K/U/W clear Ctrl-D submit" \
>/dev/tty
}
_draw
# ── Input loop ─────────────────────────────────────────────────────────────────
result=""
key=""
while true; do
shellframe_read_key key
shellframe_editor_on_key "$key"
case $? in
2) # Ctrl-D: submit
result="$SHELLFRAME_EDITOR_RESULT"
break
;;
*) # Ctrl-C is caught by the INT trap above
;;
esac
_draw
done
# Disable EXIT trap before controlled exit so _cleanup isn't called twice.
trap - EXIT INT TERM
_cleanup
# Print result to stdout (on a fresh line so it doesn't run into shell prompt)
printf '\n' >/dev/tty
[[ -n "$result" ]] && printf '%s\n' "$result"