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
4c292ea2
Commit
4c292ea2
authored
Sep 20, 2015
by
Sebastian Gniazdowski
Browse files
Initial commit of Zsh Navigation Tools
parent
9c08641d
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
plugins/zsh-navigation-tools/.config/znt/README.txt
0 → 100644
View file @
4c292ea2
These are skeletons, configuration is read from ~/.config/znt/*
plugins/zsh-navigation-tools/.config/znt/n-aliases.conf
0 → 100644
View file @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
This diff is collapsed.
Click to expand it.
plugins/zsh-navigation-tools/README.txt
0 → 100644
View file @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# 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 @
4c292ea2
# $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 @
4c292ea2
# 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