Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Oh My Zsh
Commits
afd28bf1
Commit
afd28bf1
authored
Nov 30, 2015
by
Marc Cornellà
Browse files
Merge pull request #4368 from psprint/master
Update Zsh Navigation Tools plugin
parents
fea74b4b
4c292ea2
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
plugins/zsh-navigation-tools/.config/znt/README.txt
0 → 100644
View file @
afd28bf1
These are skeletons, configuration is read from ~/.config/znt/*
plugins/zsh-navigation-tools/.config/znt/n-aliases.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
plugins/zsh-navigation-tools/.config/znt/n-cd.conf
0 → 100644
View file @
afd28bf1
# Hotlist
local
hotlist
hotlist
=(
/
usr
/
share
/
zsh
/
site
-
functions
/
usr
/
share
/
zsh
/
usr
/
local
/
share
/
zsh
/
site
-
functions
/
usr
/
local
/
share
/
zsh
/
usr
/
local
/
bin
/
usr
/
lib
)
# Suppress adding (to directory stack) directories visited by n-cd
# Value 0 is the default (directories will be added to dirstack)
local
NCD_DONT_PUSHD
=
0
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
# Colorize last segments of the paths
# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
local
NLIST_COLORING_PATTERN
=
"[a-zA-Z0-9 ._-]##/#(#e)"
local
NLIST_COLORING_COLOR
=$
'\x1b[00;33m'
plugins/zsh-navigation-tools/.config/znt/n-env.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
local
NLIST_COLORING_PATTERN
=
"[a-zA-Z0-9_]##"
local
NLIST_COLORING_MATCH_MULTIPLE
=
0
plugins/zsh-navigation-tools/.config/znt/n-functions.conf
0 → 100644
View file @
afd28bf1
# Which editor to use, zed or vared
# vared is the default
local
feditor
=
"zed"
# local feditor="vared"
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
plugins/zsh-navigation-tools/.config/znt/n-history.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
local
active_text
=
underline
plugins/zsh-navigation-tools/.config/znt/n-kill.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
# Colorize first number column and last path segment
# This doesn't cover scripts named "[0-9]## *", which should be very rare
# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
# | is alternative, but only in ()
local
NLIST_COLORING_PATTERN
=
"((#s) #[0-9]## |[[][^]]#](#e)|[^ 0-9/?\\\\][^/\\\\]#(#e)|[^ /\\\\]##[^0-9/\\\\ ]##[^/\\\\]#(#e))"
local
NLIST_COLORING_COLOR
=$
'\x1b[00;33m'
local
NLIST_COLORING_MATCH_MULTIPLE
=
1
plugins/zsh-navigation-tools/.config/znt/n-list.conf
0 → 100644
View file @
afd28bf1
# Should the list (text, borders) be drawn in bold
# Value 1 is the default
local
bold
=
1
plugins/zsh-navigation-tools/.config/znt/n-options.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
plugins/zsh-navigation-tools/.config/znt/n-panelize.conf
0 → 100644
View file @
afd28bf1
# How should be current element of the list drawn. Possible values: reverse,
# underline. Default (without option set) is reverse
# On Linux virtual terminal this will be enforced to reverse (because of poor
# underline support on that terminal)
# local active_text=underline
plugins/zsh-navigation-tools/LICENSE
0 → 100644
View file @
afd28bf1
This diff is collapsed.
Click to expand it.
plugins/zsh-navigation-tools/README.txt
0 → 100644
View file @
afd28bf1
# Zsh Navigation Tools
http://imageshack.com/a/img633/7967/ps6rKR.png
A tool generating a selectable curses-based list of elements that has access to
current Zsh session, i.e. has broad capabilities to work together with it.
That's n-list. The files n-cd, n-env, n-kill, etc. are applications of
the tool. Feature highlights include incremental multi-word searching, ANSI
coloring, unique mode, horizontal scroll, non-selectable elements, grepping and
various integrations with Zsh.
## History Widget
To have n-history as the incremental searcher bound to Ctrl-R copy znt-*
files into the */site-functions dir (unless you use Oh My Zsh) and
add:
autoload znt-history-widget
zle -N znt-history-widget
bindkey "^R" znt-history-widget
to .zshrc. This is done automatically when using Oh My Zsh. Two other
widgets exist, znt-cd-widget and znt-kill-widget, they can be too assigned
to key combinations:
zle -N znt-cd-widget
bindkey "^T" znt-cd-widget
zle -N znt-kill-widget
bindkey "^Y" znt-kill-widget
## Introduction
The tools are:
- n-aliases - browses aliases, relegates editing to vared
- n-cd - browses dirstack and bookmarked directories, allows to enter selected directory
- n-functions - browses functions, relegates editing to zed or vared
- n-history - browses history, allows to edit and run commands from it
- n-kill - browses processes list, allows to send signal to selected process
- n-env - browses environment, relegates editing to vared
- n-options - browses options, allows to toggle their state
- n-panelize - loads output of given command into the list for browsing
All tools support horizontal scroll with <,>, {,}, h,l or left and right
cursors. Other keys are:
- [,] - jump directory bookmarks in n-cd and typical signals in n-kill
- Ctrl-d, Ctrl-u - half page up or down
- Ctrl-p, Ctrl-n - previous and next (also done with vim's j,k)
- Ctrl-l - redraw of whole display
- g, G - beginning and end of the list
- Ctrl-o, o - enter uniq mode (no duplicate lines)
- / - start incremental search
- Enter - finish incremental search, retaining filter
- Esc - exit incremental search, clearing filter
- Ctrl-w (in incremental search) - delete whole word
- Ctrl-k (in incremental search) - delete whole line
## Programming
The function n-list is used as follows:
n-list {element1} [element2] ... [elementN]
This is all that is needed to be done to have the features like ANSI coloring,
incremental multi-word search, unique mode, horizontal scroll, non-selectable
elements (grepping is done outside n-list, see the tools for how it can be
done). To set up non-selectable entries add their indices into array
NLIST_NONSELECTABLE_ELEMENTS:
typeset -a NLIST_NONSELECTABLE_ELEMENTS
NLIST_NONSELECTABLE_ELEMENTS=( 1 )
Result is stored as $reply[REPLY] ($ isn't needed before REPLY because
of arithmetic context inside []). The returned array might be different from
input arguments as n-list can process them via incremental search or uniq
mode. $REPLY is the index in that possibly processed array. If $REPLY
equals -1 it means that no selection have been made (user quitted via q
key).
To set up entries that can be jumped to with [,] keys add their indices to
NLIST_HOP_INDEXES array:
typeset -a NLIST_HOP_INDEXES
NLIST_HOP_INDEXES=( 1 10 )
n-list can automatically colorize entries according to a Zsh pattern.
Following example will colorize all numbers with blue:
local NLIST_COLORING_PATTERN="[0-9]##"
local NLIST_COLORING_COLOR=$'\x1b[00;34m'
local NLIST_COLORING_END_COLOR=$'\x1b[0m'
local NLIST_COLORING_MATCH_MULTIPLE=1
n-list "This is a number 123" "This line too has a number: 456"
Blue is the default color, it doesn't have to be set. See zshexpn man page
for more information on Zsh patterns. Briefly, comparing to regular
expressions, (#s) is ^, (#e) is $, # is *, ## is +. Alternative
will work when in parenthesis, i.e. (a|b). BTW by using this method you can
colorize output of the tools, via their config files (check out e.g. n-cd.conf,
it uses this).
plugins/zsh-navigation-tools/n-aliases
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-aliases` to .zshrc
#
# This function allows to choose an alias for edition with vared
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob
zmodload zsh/curses
zmodload zsh/parameter
local
IFS
=
"
"
unset
NLIST_COLORING_PATTERN
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-aliases.conf
]
&&
.
~/.config/znt/n-aliases.conf
local
list
local
selected
NLIST_REMEMBER_STATE
=
0
list
=(
"
${
(@k)aliases
}
"
)
list
=(
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
if
[
"
$#list
"
-eq
0
]
;
then
echo
"No matching aliases"
return
1
fi
list
=(
"
${
(@i)list
}
"
)
n-list
"
$list
[@]"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
echo
"Editing
\`
$selected
':"
print
-rs
"vared aliases
\\
[
$selected
\\
]"
vared aliases
\[
$selected
\]
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-cd
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-cd` to .zshrc
#
# This function allows to choose a directory from pushd stack
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob pushdignoredups
zmodload zsh/curses
local
IFS
=
"
"
# Unset before configuration is read
unset
NLIST_COLORING_PATTERN
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-cd.conf
]
&&
.
~/.config/znt/n-cd.conf
local
list
local
selected
NLIST_REMEMBER_STATE
=
0
list
=(
`
dirs
-p
`
)
list
=(
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
[
"
$#list
"
-eq
0
]
&&
echo
"No matching directories"
if
[
"
$#hotlist
"
-ge
1
]
;
then
typeset
-a
NLIST_NONSELECTABLE_ELEMENTS NLIST_HOP_INDEXES
local
tmp_list_size
=
"
$#list
"
NLIST_NONSELECTABLE_ELEMENTS
=(
$((
tmp_list_size+1
))
$((
tmp_list_size+2
))
)
list
=(
"
$list
[@]"
""
$'
\x
1b[00;31m'
"Hotlist"
$'
\x
1b[00;00m'
:
"
$hotlist
[@]"
)
((
tmp_list_size+
=
3
))
local
middle_hop
=
$((
(
tmp_list_size+
$#list
)
/
2
))
[[
"
$middle_hop
"
-eq
$tmp_list_size
||
"
$middle_hop
"
-eq
$#list
]]
&&
middle_hop
=
""
[
"
$tmp_list_size
"
-eq
$#list
]
&&
tmp_list_size
=
""
NLIST_HOP_INDEXES
=(
1
$tmp_list_size
$middle_hop
$#list
)
else
[
"
$#list
"
-eq
0
]
&&
return
1
fi
n-list
"
${
list
[@]
}
"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
selected
=
"
${
selected
/#\~/
$HOME
}
"
((
NCD_DONT_PUSHD
))
&&
setopt NO_AUTO_PUSHD
cd
"
$selected
"
((
NCD_DONT_PUSHD
))
&&
setopt AUTO_PUSHD
# ZLE?
if
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
;
then
zle
-M
"You have selected
$selected
"
else
echo
"You have selected
$selected
"
fi
else
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
&&
zle redisplay
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-env
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-env` to .zshrc
#
# This function allows to choose an environment variable
# for edition with vared
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob
unsetopt equals
zmodload zsh/curses
local
IFS
=
"
"
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-env.conf
]
&&
.
~/.config/znt/n-env.conf
local
list
local
selected
NLIST_REMEMBER_STATE
=
0
list
=(
`
env
`
)
list
=(
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
if
[
"
$#list
"
-eq
0
]
;
then
echo
"No matching variables"
return
1
fi
list
=(
"
${
(@i)list
}
"
)
n-list
"
$list
[@]"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
selected
=
"
${
selected
%%=*
}
"
echo
"Editing
\`
$selected
':"
print
-rs
"vared
\"
$selected
\"
"
vared
"
$selected
"
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-functions
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-functions` to .zshrc
#
# This function allows to choose a function for edition with vared
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob
zmodload zsh/curses
zmodload zsh/parameter
local
IFS
=
"
"
unset
NLIST_COLORING_PATTERN
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-functions.conf
]
&&
.
~/.config/znt/n-functions.conf
local
list
local
selected
NLIST_REMEMBER_STATE
=
0
list
=(
"
${
(@k)functions
}
"
)
list
=(
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
if
[
"
$#list
"
-eq
0
]
;
then
echo
"No matching functions"
return
1
fi
list
=(
"
${
(@i)list
}
"
)
n-list
"
$list
[@]"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
if
[
"
$feditor
"
=
"zed"
]
;
then
echo
"Editing
\`
$selected
' (ESC ZZ or Ctrl-x-w to finish):"
autoload zed
print
-rs
"zed -f --
\"
$selected
\"
"
zed
-f
--
"
$selected
"
else
echo
"Editing
\`
$selected
':"
print
-rs
"vared functions
\\
[
$selected
\\
]"
vared functions
\[
$selected
\]
fi
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-history
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-history` to .zshrc
#
# This function allows to browse Z shell's history and use the
# entries
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob
zmodload zsh/curses
local
IFS
=
"
"
unset
NLIST_COLORING_PATTERN
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-history.conf
]
&&
.
~/.config/znt/n-history.conf
local
list
local
selected
NLIST_REMEMBER_STATE
=
0
list
=(
`
builtin history
-rn
1
`
)
list
=(
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
if
[
"
$#list
"
-eq
0
]
;
then
echo
"No matching history entries"
return
1
fi
n-list
"
${
list
[@]
}
"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
# ZLE?
if
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
;
then
zle redisplay
zle kill-whole-line
zle
-U
"
$selected
"
else
print
-zr
"
$selected
"
fi
else
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
&&
zle redisplay
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-kill
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-kill` to .zshrc
#
# This function allows to choose a process and a signal to send to it
#
# Uses n-list
emulate
-L
zsh
setopt extendedglob
zmodload zsh/curses
local
IFS
=
"
"
[
-f
~/.config/znt/n-list.conf
]
&&
.
~/.config/znt/n-list.conf
[
-f
~/.config/znt/n-kill.conf
]
&&
.
~/.config/znt/n-kill.conf
typeset
-A
signals
signals
=(
1
"1 - HUP"
2
"2 - INT"
3
"3 - QUIT"
6
"6 - ABRT"
9
"9 - KILL"
14
"14 - ALRM"
15
"15 - TERM"
17
"17 - STOP"
19
"19 - CONT"
)
local
list
local
selected
local
signal
local
-a
signal_names
local
title
NLIST_REMEMBER_STATE
=
0
typeset
-a
NLIST_NONSELECTABLE_ELEMENTS
NLIST_NONSELECTABLE_ELEMENTS
=(
1
)
type
ps 2>/dev/null 1>&2
||
{
echo
>
&2
"Error:
\`
ps' not found"
;
return
1
}
case
"
$(
uname
)
"
in
CYGWIN
*
)
list
=(
`
command
ps
-Wa
`
)
;;
*
)
list
=(
`
command
ps
-o
pid,uid,command
-A
`
)
;;
esac
# Ask of PID
title
=
$'
\x
1b[00;31m'
"
${
list
[1]
}
"
$'
\x
1b[00;00m
\0
'
shift
list
list
=(
"
$title
"
"
${
(@M)list
:#
(#i)*
$1
*
}
"
)
local
NLIST_GREP_STRING
=
"
$1
"
if
[
"
$#list
"
-eq
1
]
;
then
echo
"No matching processes"
return
1
fi
n-list
"
$list
[@]"
# Got answer? (could be Ctrl-C or 'q')
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
selected
=
"
${
selected
## #
}
"
pid
=
"
${
selected
%% *
}
"
# Now ask of signal
signal_names
=(
${
(vin)signals
}
)
typeset
-a
NLIST_HOP_INDEXES
NLIST_HOP_INDEXES
=(
3 6 8
)
unset
NLIST_COLORING_PATTERN
n-list
$'
\x
1b[00;31mSelect signal:
\x
1b[00;00m'
"
$signal_names
[@]"
if
[
"
$REPLY
"
-gt
0
]
;
then
selected
=
"
$reply
[REPLY]"
signal
=
"
${
(k)signals[(r)
$selected
]
}
"
# ZLE?
if
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
;
then
zle redisplay
zle kill-whole-line
zle
-U
"kill -
$signal
$pid
"
else
print
-zr
"kill -
$signal
$pid
"
fi
else
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
&&
zle redisplay
fi
else
[
"
${
(t)CURSOR
}
"
=
"integer-local-special"
]
&&
zle redisplay
fi
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-list
0 → 100644
View file @
afd28bf1
# $1, $2, ... - elements of the list
# $NLIST_NONSELECTABLE_ELEMENTS - array of indexes (1-based) that cannot be selected
# $REPLY is the output variable - contains index (1-based) or -1 when no selection
#
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-list` to .zshrc
#
# This function outputs a list of elements that can be
# navigated with keyboard. Uses curses library
emulate
-LR
zsh
setopt typesetsilent extendedglob noshortloops
_nlist_has_terminfo
=
0
zmodload zsh/curses
zmodload zsh/terminfo 2>/dev/null
&&
_nlist_has_terminfo
=
1
trap
"REPLY=-2; reply=(); return"
TERM INT QUIT
trap
"_nlist_exit"
EXIT
# Drawing and input
autoload n-list-draw n-list-input
# Cleanup before any exit
_nlist_exit
()
{
setopt localoptions
setopt extendedglob
[[
"
$REPLY
"
=
-
(
#c0,1)[0-9]## ]] || REPLY="-1"
zcurses 2>/dev/null delwin inner
zcurses 2>/dev/null delwin main
zcurses 2>/dev/null refresh
zcurses end
_nlist_alternate_screen 0
_nlist_cursor_visibility 1
unset
_nlist_has_terminfo
}
# Outputs a message in the bottom of the screen
_nlist_status_msg
()
{
# -1 for border, -1 for 0-based indexing
zcurses move main
$((
term_height
-
1
-
1
))
2
zcurses clear main eol
zcurses string main
"
$1
"
#status_msg_strlen is localized in caller
status_msg_strlen
=
$#1
}
# Prefer tput, then module terminfo
_nlist_cursor_visibility
()
{
if
type
tput 2>/dev/null 1>&2
;
then
[
"
$1
"
=
"1"
]
&&
{
tput cvvis
;
tput cnorm
}
[
"
$1
"
=
"0"
]
&&
tput civis
elif
[
"
$_nlist_has_terminfo
"
=
"1"
]
;
then
[
"
$1
"
=
"1"
]
&&
{
[
-n
$terminfo
[
cvvis]
]
&&
echo
-n
$terminfo
[
cvvis]
;
[
-n
$terminfo
[
cnorm]
]
&&
echo
-n
$terminfo
[
cnorm]
}
[
"
$1
"
=
"0"
]
&&
[
-n
$terminfo
[
civis]
]
&&
echo
-n
$terminfo
[
civis]
fi
}
# Reason for this function is that on some systems
# smcup and rmcup are not knowing why left empty
_nlist_alternate_screen
()
{
[
"
$_nlist_has_terminfo
"
-ne
"1"
]
&&
return
[[
"
$1
"
=
"1"
&&
-n
"
$terminfo
[smcup]"
]]
&&
return
[[
"
$1
"
=
"0"
&&
-n
"
$terminfo
[rmcup]"
]]
&&
return
case
"
$TERM
"
in
*
rxvt
*
)
[
"
$1
"
=
"1"
]
&&
echo
-n
$'
\x
1b7
\x
1b[?47h'
[
"
$1
"
=
"0"
]
&&
echo
-n
$'
\x
1b[2J
\x
1b[?47l
\x
1b8'
;;
*
)
[
"
$1
"
=
"1"
]
&&
echo
-n
$'
\x
1b[?1049h'
[
"
$1
"
=
"0"
]
&&
echo
-n
$'
\x
1b[?1049l'
# just to remember two other that work: $'\x1b7\x1b[r\x1b[?47h', $'\x1b[?47l\x1b8'
;;
esac
}
_nlist_compute_user_vars_difference
()
{
if
[[
"
${
(t)NLIST_NONSELECTABLE_ELEMENTS
}
"
!=
"array"
&&
"
${
(t)NLIST_NONSELECTABLE_ELEMENTS
}
"
!=
"array-local"
]]
then
last_element_difference
=
0
current_difference
=
0
else
last_element_difference
=
$#NLIST_NONSELECTABLE_ELEMENTS
current_difference
=
0
local
idx
for
idx
in
"
${
(n)NLIST_NONSELECTABLE_ELEMENTS[@]
}
"
;
do
[
"
$idx
"
-le
"
$NLIST_CURRENT_IDX
"
]
&&
current_difference+
=
1
||
break
done
fi
}
# List was processed, check if variables aren't off range
_nlist_verify_vars
()
{
[
"
$NLIST_CURRENT_IDX
"
-gt
"
$last_element
"
]
&&
NLIST_CURRENT_IDX
=
"
$last_element
"
[[
"
$NLIST_CURRENT_IDX
"
-eq
0
&&
"
$last_element
"
-ne
0
]]
&&
NLIST_CURRENT_IDX
=
1
((
NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
=
0+
((
NLIST_CURRENT_IDX-1
)
/page_height
)
*
page_height+1
))
}
# Compute the variables which are shown to the user
_nlist_setup_user_vars
()
{
if
[
"
$1
"
=
"1"
]
;
then
# Basic values when there are no non-selectables
NLIST_USER_CURRENT_IDX
=
"
$NLIST_CURRENT_IDX
"
NLIST_USER_LAST_ELEMENT
=
"
$last_element
"
else
_nlist_compute_user_vars_difference
NLIST_USER_CURRENT_IDX
=
$((
NLIST_CURRENT_IDX
-
current_difference
))
NLIST_USER_LAST_ELEMENT
=
$((
last_element
-
last_element_difference
))
fi
}
_nlist_coloring_list_into_col_list
()
{
local
col
=
$'
\x
1b[00;34m'
reset
=
$'
\x
1b[0m'
[
-n
"
$NLIST_COLORING_COLOR
"
]
&&
col
=
"
$NLIST_COLORING_COLOR
"
[
-n
"
$NLIST_COLORING_END_COLOR
"
]
&&
reset
=
"
$NLIST_COLORING_END_COLOR
"
if
[
"
$NLIST_COLORING_MATCH_MULTIPLE
"
-eq
1
]
;
then
col_list
=(
"
${
(@)list//(#mi)
$~NLIST_COLORING_PATTERN
/
$col
${
MATCH
}
$reset
}
"
)
else
col_list
=(
"
${
(@)list/(#mi)
$~NLIST_COLORING_PATTERN
/
$col
${
MATCH
}
$reset
}
"
)
fi
}
#
# Main code
#
# Check if there is proper input
if
[
"$#"
-lt
1
]
;
then
echo
"Usage: n-list element_1 ..."
return
1
fi
REPLY
=
"-1"
reply
=()
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
inner_height
=
term_height-3
integer
inner_width
=
term_width-3
integer
page_height
=
inner_height
integer
page_width
=
inner_width
typeset
-a
list col_list disp_list
integer
last_element
=
$#
local
action
local
final_key
integer selection
integer
last_element_difference
=
0
integer
current_difference
=
0
local
prev_search_buffer
=
""
integer
prev_uniq_mode
=
0
integer
prev_start_idx
=
-1
# Ability to remember the list between calls
if
[[
-z
"
$NLIST_REMEMBER_STATE
"
||
"
$NLIST_REMEMBER_STATE
"
-eq
0
||
"
$NLIST_REMEMBER_STATE
"
-eq
2
]]
;
then
NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
=
1
NLIST_CURRENT_IDX
=
1
NLIST_IS_SEARCH_MODE
=
0
NLIST_SEARCH_BUFFER
=
""
NLIST_TEXT_OFFSET
=
0
NLIST_IS_UNIQ_MODE
=
0
# Zero - because it isn't known, unless we
# confirm that first element is selectable
NLIST_USER_CURRENT_IDX
=
0
[[
${
NLIST_NONSELECTABLE_ELEMENTS
[(r)1]
}
!=
1
]]
&&
NLIST_USER_CURRENT_IDX
=
1
NLIST_USER_LAST_ELEMENT
=
$((
last_element
-
$#NLIST_NONSELECTABLE_ELEMENTS
))
# 2 is init once, then remember
[
"
$NLIST_REMEMBER_STATE
"
-eq
2
]
&&
NLIST_REMEMBER_STATE
=
1
fi
if
[
"
$NLIST_START_IN_SEARCH_MODE
"
-eq
1
]
;
then
NLIST_START_IN_SEARCH_MODE
=
0
NLIST_IS_SEARCH_MODE
=
1
fi
if
[
"
$NLIST_START_IN_UNIQ_MODE
"
-eq
1
]
;
then
NLIST_START_IN_UNIQ_MODE
=
0
NLIST_IS_UNIQ_MODE
=
1
fi
_nlist_alternate_screen 1
zcurses init
zcurses delwin main 2>/dev/null
zcurses delwin inner 2>/dev/null
zcurses addwin main
"
$term_height
"
"
$term_width
"
0 0
zcurses addwin inner
"
$inner_height
"
"
$inner_width
"
1 2
zcurses
bg
main white/black
zcurses
bg
inner white/black
if
[
"
$NLIST_IS_SEARCH_MODE
"
-ne
1
]
;
then
_nlist_cursor_visibility 0
fi
#
# Listening for input
#
local
key keypad
# Clear input buffer
zcurses
timeout
main 0
zcurses input main key keypad
zcurses
timeout
main
-1
key
=
""
keypad
=
""
list
=(
"
$@
"
)
last_element
=
"
$#list
"
integer
is_colored
=
0
if
[[
-z
"
$NLIST_SEARCH_BUFFER
"
&&
-n
"
$NLIST_COLORING_PATTERN
"
]]
;
then
is_colored
=
1
_nlist_coloring_list_into_col_list
fi
while
((
1
))
;
do
# Do searching (filtering with string)
if
[
-n
"
$NLIST_SEARCH_BUFFER
"
]
;
then
# Compute new list, col_list ?
if
[[
"
$NLIST_SEARCH_BUFFER
"
!=
"
$prev_search_buffer
"
||
"
$NLIST_IS_UNIQ_MODE
"
-ne
"
$prev_uniq_mode
"
]]
;
then
prev_search_buffer
=
"
$NLIST_SEARCH_BUFFER
"
prev_uniq_mode
=
"
$NLIST_IS_UNIQ_MODE
"
# regenerating list -> regenerating disp_list
prev_start_idx
=
-1
# Take all elements, including duplicates and non-selectables
typeset
+U list
list
=(
"
$@
"
)
# Remove non-selectable elements
[
"
$#NLIST_NONSELECTABLE_ELEMENTS
"
-gt
0
]
&&
for
i
in
"
${
(nO)NLIST_NONSELECTABLE_ELEMENTS[@]
}
"
;
do
list[
$i
]=()
done
# Remove duplicates
[
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]
&&
typeset
-U
list
last_element
=
"
$#list
"
# Next do the filtering
local
search_buffer
=
"
${
NLIST_SEARCH_BUFFER
%% ##
}
"
search_buffer
=
"
${
search_buffer
## ##
}
"
search_buffer
=
"
${
search_buffer
//(#m)[][*?|#~^()><\\]/\\
$MATCH
}
"
if
[
-n
"
$search_buffer
"
]
;
then
# Patterns will be *foo*~^*bar* and foo|bar)
local
search_pattern
=
"
${
search_buffer
// ##/*~^*
}
"
local
colsearch_pattern
=
"
${
search_buffer
// ##/|
}
"
list
=(
"
${
(@M)list
:#
(#i)*
$~search_pattern
*
}
"
)
last_element
=
"
$#list
"
local
red
=
$'
\x
1b[00;31m'
reset
=
$'
\x
1b[00;00m'
col_list
=(
"
${
(@)list//(#mi)(
$~colsearch_pattern
)/
$red
${
MATCH
}
$reset
}
"
)
else
col_list
=(
"
$list
[@]"
)
fi
# Called after processing list
_nlist_verify_vars
fi
_nlist_setup_user_vars 1
integer
end_idx
=
$((
NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+
page_height
-
1
))
[
"
$end_idx
"
-gt
"
$last_element
"
]
&&
end_idx
=
last_element
if
[
"
$prev_start_idx
"
-ne
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
]
;
then
prev_start_idx
=
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
disp_list
=(
"
${
(@)col_list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]
}
"
)
fi
# Output colored list
n-list-draw
"
$((
(
NLIST_CURRENT_IDX-1
)
%
page_height
+
1
))
"
\
"
$page_height
"
"
$page_width
"
0 0
"
$NLIST_TEXT_OFFSET
"
inner
\
"
$disp_list
[@]"
else
# There is no search, but there was in previous loop
# OR
# Uniq mode was entered or left out
# -> compute new list (maybe also col_list)
if
[[
-n
"
$prev_search_buffer
"
||
"
$NLIST_IS_UNIQ_MODE
"
-ne
"
$prev_uniq_mode
"
]]
;
then
prev_search_buffer
=
""
prev_uniq_mode
=
"
$NLIST_IS_UNIQ_MODE
"
# regenerating list -> regenerating disp_list
prev_start_idx
=
-1
# Take all elements, including duplicates and non-selectables
typeset
+U list
list
=(
"
$@
"
)
# Remove non-selectable elements only when in uniq mode
[
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]
&&
[
"
$#NLIST_NONSELECTABLE_ELEMENTS
"
-gt
0
]
&&
for
i
in
"
${
(nO)NLIST_NONSELECTABLE_ELEMENTS[@]
}
"
;
do
list[
$i
]=()
done
# Remove duplicates when in uniq mode
[
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]
&&
typeset
-U
list
# Apply coloring pattern (when not with search query)
is_colored
=
0
if
[
-n
"
$NLIST_COLORING_PATTERN
"
]
;
then
is_colored
=
1
_nlist_coloring_list_into_col_list
fi
last_element
=
"
$#list
"
# Called after processing list
_nlist_verify_vars
fi
# "1" - shouldn't bother with non-selectables
_nlist_setup_user_vars
"
$NLIST_IS_UNIQ_MODE
"
integer
end_idx
=
$((
NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+
page_height
-
1
))
[
"
$end_idx
"
-gt
"
$last_element
"
]
&&
end_idx
=
last_element
if
[
"
$is_colored
"
-eq
0
]
;
then
if
[
"
$prev_start_idx
"
-ne
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
]
;
then
prev_start_idx
=
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
disp_list
=(
"
${
(@)list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]
}
"
)
fi
else
if
[
"
$prev_start_idx
"
-ne
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
]
;
then
prev_start_idx
=
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
disp_list
=(
"
${
(@)col_list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]
}
"
)
fi
fi
# Output the list
n-list-draw
"
$((
(
NLIST_CURRENT_IDX-1
)
%
page_height
+
1
))
"
\
"
$page_height
"
"
$page_width
"
0 0
"
$NLIST_TEXT_OFFSET
"
inner
\
"
$disp_list
[@]"
fi
local
status_msg_strlen
if
[
"
$NLIST_IS_SEARCH_MODE
"
=
"1"
]
;
then
local
_txt2
=
""
[
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]
&&
_txt2
=
"[-UNIQ-] "
_nlist_status_msg
"
${
_txt2
}
Filtering with:
${
NLIST_SEARCH_BUFFER
// /+
}
"
elif
[[
${
NLIST_NONSELECTABLE_ELEMENTS
[(r)
$NLIST_CURRENT_IDX
]
}
!=
$NLIST_CURRENT_IDX
||
-n
"
$NLIST_SEARCH_BUFFER
"
||
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]]
;
then
local
_txt
=
""
_txt2
=
""
[
-n
"
$NLIST_GREP_STRING
"
]
&&
_txt
=
" [
$NLIST_GREP_STRING
]"
[
"
$NLIST_IS_UNIQ_MODE
"
-eq
1
]
&&
_txt2
=
"[-UNIQ-] "
_nlist_status_msg
"
${
_txt2
}
Current #
$NLIST_USER_CURRENT_IDX
(of #
$NLIST_USER_LAST_ELEMENT
entries)
$_txt
"
else
_nlist_status_msg
""
fi
zcurses border main
zcurses refresh main inner
zcurses move main
$((
term_height
-
1
-
1
))
$((
status_msg_strlen
+
2
))
# Wait for input
zcurses input main 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
_nlist_status_msg
"Inproper input detected"
zcurses refresh main inner
fi
n-list-input
"
$NLIST_CURRENT_IDX
"
"
$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
"
\
"
$page_height
"
"
$page_width
"
"
$last_element
"
"
$NLIST_TEXT_OFFSET
"
\
"
$final_key
"
"
$NLIST_IS_SEARCH_MODE
"
"
$NLIST_SEARCH_BUFFER
"
\
"
$NLIST_IS_UNIQ_MODE
"
selection
=
"
$reply
[1]"
action
=
"
$reply
[2]"
NLIST_CURRENT_IDX
=
"
$reply
[3]"
NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
=
"
$reply
[4]"
NLIST_TEXT_OFFSET
=
"
$reply
[5]"
NLIST_IS_SEARCH_MODE
=
"
$reply
[6]"
NLIST_SEARCH_BUFFER
=
"
$reply
[7]"
NLIST_IS_UNIQ_MODE
=
"
$reply
[8]"
if
[
"
$action
"
=
"SELECT"
]
;
then
REPLY
=
"
$selection
"
reply
=(
"
$list
[@]"
)
break
elif
[
"
$action
"
=
"QUIT"
]
;
then
REPLY
=
-1
reply
=(
"
$list
[@]"
)
break
elif
[
"
$action
"
=
"REDRAW"
]
;
then
zcurses clear main redraw
zcurses clear inner redraw
fi
done
# vim: set filetype=zsh:
plugins/zsh-navigation-tools/n-list-draw
0 → 100644
View file @
afd28bf1
# Copy this file into /usr/share/zsh/site-functions/
# and add 'autoload n-list-draw` to .zshrc
#
# This is an internal function not for direct use
emulate
-L
zsh
zmodload zsh/curses
setopt typesetsilent extendedglob
_nlist_print_with_ansi
()
{
local
win
=
"
$1
"
text
=
"
$2
"
out col chunk Xout
integer
text_offset
=
"
$3
"
max_text_len
=
"
$4
"
text_len
=
0
no_match
=
0 nochunk_text_len to_skip_from_chunk to_chop_off_from_chunk before_len
# 1 - non-escaped text, 2 - first number in the escaped text, with ;
# 3 - second number, 4 - text after whole escape text
typeset
-a
c
c
=(
black red green yellow blue magenta cyan white
)
while
[[
-n
"
$text
"
&&
"
$no_match
"
-eq
0
]]
;
do
if
[[
"
$text
"
=
(
#b)([^$'\x1b']#)$'\x1b'\[([0-9](#c0,2))(#B)(\;|)(#b)([0-9](#c0,2))m(*) ]]; then
# Text for further processing
text
=
"
$match
[4]"
# Text chunk to output now
out
=
"
$match
[1]"
# Save color
col
=
"
$match
[2]"
((
match[3]
>=
30
&&
match[3] <
=
37
))
&&
col
=
"
$match
[3]"
else
out
=
"
$text
"
no_match
=
1
fi
if
[
-n
"
$out
"
]
;
then
################ Expand tabs ################
chunk
=
"
$out
"
before_len
=
"
$text_len
"
Xout
=
""
while
[
-n
"
$chunk
"
]
;
do
[[
"
$chunk
"
=
(
#b)([^$'\t']#)$'\t'(*) ]] && {
((
all_text_len
=((
before_len+
${#
match
[1]
}
)
/8+1
)
*
8
))
Xout+
=
"
${
(r
:all_text_len-before_len::
:
)match[1]
}
"
before_len+
=
all_text_len-before_len
chunk
=
"
$match
[2]"
}
||
{
Xout+
=
"
$chunk
"
break
}
done
#############################################
# Input text length without the current chunk
nochunk_text_len
=
text_len
# Input text length up to current chunk
text_len+
=
"
$#Xout
"
# Should start displaying with this chunk?
# I.e. stop skipping left part of the input text?
if
((
text_len
>
text_offset
))
;
then
to_skip_from_chunk
=
text_offset-nochunk_text_len
# LEFT - is chunk off the left skip boundary? +1 for 1-based index in string
((
to_skip_from_chunk
>
0
))
&&
Xout
=
"
${
Xout
[to_skip_from_chunk+1,-1]
}
"
# RIGHT - is text off the screen?
if
((
text_len-text_offset
>
max_text_len
))
;
then
to_chop_off_from_chunk
=
0+
(
text_len-text_offset
)
-max_text_len
Xout
=
"
${
Xout
[1,-to_chop_off_from_chunk-1]
}
"
fi
[
-n
"
$Xout
"
]
&&
zcurses string
"
$win
"
"
$Xout
"
fi
fi
if
((
no_match
==
0
))
;
then
if
((
col
>=
30
&&
col <
=
37
))
;
then
zcurses attr
"
$win
"
$c
[
col-29]/black
elif
[[
"
$col
"
-eq
0
]]
;
then
zcurses attr
"
$win
"
white/black
fi
fi
done
}
integer
highlight
=
"
$1
"
integer
page_height
=
"
$2
"
integer
page_width
=
"
$3
"
local
y_offset
=
"
$4
"
local
x_offset
=
"
$5
"
local
text_offset
=
"
$6
"
local
win
=
"
$7
"
shift
7
integer
max_text_len
=
page_width-x_offset
[
"
$bold
"
=
"0"
]
&&
bold
=
""
||
bold
=
"+bold"
[[
"
$active_text
"
=
"underline"
||
"
$active_text
"
=
"reverse"
]]
||
active_text
=
"reverse"
# With Linux terminal underline won't work properly
[
"
$TERM
"
=
"linux"
]
&&
active_text
=
"reverse"
integer
max_idx
=
page_height
integer
end_idx
=
max_idx
[
"
$end_idx
"
-gt
"$#"
]
&&
end_idx
=
"$#"
integer
y
=
y_offset
zcurses attr
"
$win
"
$bold
white/black
integer i text_len
local
text
for
((
i
=
1
;
i<
=
end_idx
;
i++
))
;
do
zcurses move
"
$win
"
$y
"
$x_offset
"
[
"
$i
"
=
"
$highlight
"
]
&&
zcurses attr
"
$win
"
+
"
$active_text
"
_nlist_print_with_ansi
"
$win
"
"
$@
[i]"
"
$text_offset
"
"
$max_text_len
"
zcurses clear
"
$win
"
eol
[
"
$i
"
=
"
$highlight
"
]
&&
zcurses attr
"
$win
"
-
"
$active_text
"
y+
=
1
done
if
[
"
$end_idx
"
-lt
"
$max_idx
"
]
;
then
zcurses move
"
$win
"
$y
"
$x_offset
"
zcurses clear
"
$win
"
eol
fi
zcurses attr
"
$win
"
white/black
# vim: set filetype=zsh:
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment