summaryrefslogtreecommitdiff
path: root/plugins/zsh-navigation-tools/doc/n-preview
blob: 2d8eea3fb59516d24d6d54c2a6b4a8e5d201c792 (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-preview` to .zshrc
#
# This is partially a test if n-list-draw and n-list-input can be
# used multiple times to create multiple lists. It might become
# more usable if someone adds more features like previewing of
# archive contents.

emulate -L zsh

zmodload zsh/curses

setopt typesetsilent extendedglob
trap "return" TERM INT QUIT
trap "_vpreview_exit" EXIT

local IFS="
"

[ -f ~/.config/znt/n-list.conf ] && . ~/.config/znt/n-list.conf

[[ "$colorpair" = "" ]] && colorpair="white/black"
local background="${colorpair#*/}"

# Drawing and input
autoload n-list-draw n-list-input

# Cleanup before any exit
_vpreview_exit() {
    zcurses 2>/dev/null delwin files
    zcurses 2>/dev/null delwin body 
    zcurses 2>/dev/null delwin status
    zcurses 2>/dev/null refresh
    zcurses end
}

# Outputs a message in the bottom of the screen
_vpreview_status_msg() {
    zcurses move status 1 2
    zcurses clear status eol
    zcurses string status "$1"
}

# Prefer tput, then module terminfo
_nlist_cursor_visibility() {
    if type tput 2>/dev/null 1>&2; then
        [ "$1" = "1" ] && tput cvvis
        [ "$1" = "0" ] && tput civis
    elif [ "$has_termcap" = "1" ]; then
        [ "$1" = "1" ] && [ -n $terminfo[cvvis] ] && echo -n $terminfo[cvvis]
        [ "$1" = "0" ] && [ -n $terminfo[civis] ] && echo -n $terminfo[civis]
    fi 
}

#
# Main code
#

integer term_height="$LINES"
integer term_width="$COLUMNS"
if [[ "$term_height" -lt 1 || "$term_width" -lt 1 ]]; then
    local stty_out=$( stty size )
    term_height="${stty_out% *}"
    term_width="${stty_out#* }"
fi

integer status_height=3
integer status_width=term_width
integer status_page_height=1
integer status_page_width=term_width-2

integer files_height=term_height-status_height
integer files_width=term_width/5
integer files_page_height=files_height-2
integer files_page_width=files_width-2

integer body_height=term_height-status_height
integer body_width=term_width-files_width
integer body_page_height=body_height-2
integer body_page_width=body_width

integer _from_what_idx_list_is_shown_1=1
integer current_1=1

integer _from_what_idx_list_is_shown_2=1
integer current_2=1
integer hscroll_2=0

integer active_window=0

local ansi_mode="ansi"
[ -f ~/.config/znt/n-preview.conf ] && . ~/.config/znt/n-preview.conf
typeset -a hcmd
#if type pygmentize 2>/dev/null 1>&2; then
#    hcmd=( pygmentize -g )
if type highlight 2>/dev/null 1>&2; then
    hcmd=( highlight -q --force -O ansi )
elif type source-highlight 2>/dev/null 1>&2; then
    # Warning: source-highlight can have problems
    hcmd=( source-highlight --failsafe -fesc -o STDOUT -i )
else
    ansi_mode="noansi"
fi

zcurses init
zcurses addwin status "$status_height" "$status_width" $(( term_height - status_height )) 0
zcurses addwin files "$files_height" "$files_width" 0 0
zcurses addwin body "$body_height" "$body_width" 0 "$files_width"
zcurses bg status white/black
zcurses bg files white/black
zcurses bg body white/black

#
# Listening for input
#

local key keypad

# Clear input buffer
zcurses timeout status 0
zcurses input status key keypad
zcurses timeout status -1
key=""
keypad=""

typeset -a filenames
integer last_element_1

typeset -a body
integer last_element_2

filenames=( *(N) )
filenames=( "${(@M)filenames:#(#i)*$1*}" )

local NLIST_GREP_STRING="$1"

integer last_element_1="$#filenames"
integer last_element_2=0

local selection action final_key

while (( 1 )); do
    # Output the lists
    integer end_idx=$(( _from_what_idx_list_is_shown_1 + files_page_height - 1 ))
    [ "$end_idx" -gt "$last_element_1" ] && end_idx=last_element_1

    n-list-draw "$(( (current_1 -1) % files_page_height + 1 ))" \
                    "$files_page_height" "$files_page_width" 1 2 0 files \
                    "${(@)filenames[_from_what_idx_list_is_shown_1, end_idx]}"

    if [ "$#body" -ge 1 ]; then
        end_idx=$(( _from_what_idx_list_is_shown_2 + body_page_height - 1 ))
        [ "$end_idx" -gt "$last_element_2" ] && end_idx=last_element_2

        n-list-draw "$(( (current_2 -1) % body_page_height + 1 ))" \
                        "$body_page_height" "$body_page_width" 1 0 "$hscroll_2" body \
                        "${(@)body[_from_what_idx_list_is_shown_2, end_idx]}"
    fi

    [[ "$active_window" -eq 0 ]] && zcurses border files
    zcurses border status
    zcurses refresh files body status 

    # Wait for input
    zcurses input status key keypad

    # Get the special (i.e. "keypad") key or regular key
    if [ -n "$key" ]; then
        final_key="$key" 
    elif [ -n "$keypad" ]; then
        final_key="$keypad"
    else
        _vpreview_status_msg "Inproper input detected"
        zcurses refresh status 
    fi

    if [ "$active_window" -eq 0 ]; then
        zcurses clear files
        n-list-input "$current_1" "$_from_what_idx_list_is_shown_1" "$files_page_height" \
            "$files_page_width" "$last_element_1" 0 "$final_key"

        selection="$reply[1]"
        action="$reply[2]"
        current_1="$reply[3]"
        _from_what_idx_list_is_shown_1="$reply[4]"

        if [ "$action" = "SELECT" ]; then
            # Load new file and refresh the displaying window
            local filename="$filenames[$selection]"
            if [ "$ansi_mode" = "ansi" ]; then
                body=( "${(@f)"$( "$hcmd[@]" "$filename" )"}" )
            else
                body=( "${(@f)"$(<$filename)"}" )
            fi
            last_element_2="$#body"
            current_2=1
            _from_what_idx_list_is_shown_2=1
            zcurses clear body
        fi
    elif [ "$active_window" -eq 1 ]; then
        zcurses clear body
        n-list-input "$current_2" "$_from_what_idx_list_is_shown_2" "$body_page_height" \
            "$body_page_width" "$last_element_2" "$hscroll_2" "$final_key"

        selection="$reply[1]"
        action="$reply[2]"
        current_2="$reply[3]"
        _from_what_idx_list_is_shown_2="$reply[4]"
        hscroll_2="$reply[5]"

    fi

    if [ "$action" = "LEAVE" ]; then
        active_window=1-active_window
    elif [ "$action" = "QUIT" ]; then
            break
    elif [ "$action" = "REDRAW" ]; then
        zcurses clear files redraw
        zcurses clear body redraw
        zcurses clear status redraw
    fi
done

# vim: set filetype=zsh: