Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nccf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
702
Provoz
nccf
Commits
d1eb7ba0
"src/mol-model/git@gitlab.cesnet.cz:madcatxster/molstar.git" did not exist on "28fab6a53c39b2eb4a23a97d61ddb6ec77fb1560"
Commit
d1eb7ba0
authored
3 years ago
by
Yorhel
Browse files
Options
Downloads
Patches
Plain Diff
Initial keyboard input handling + item&sort selection
parent
27cb599e
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/browser.zig
+74
-3
74 additions, 3 deletions
src/browser.zig
src/main.zig
+30
-49
30 additions, 49 deletions
src/main.zig
src/ui.zig
+27
-0
27 additions, 0 deletions
src/ui.zig
with
131 additions
and
52 deletions
src/browser.zig
+
74
−
3
View file @
d1eb7ba0
...
...
@@ -11,6 +11,9 @@ var dir_items = std.ArrayList(?*model.Entry).init(main.allocator);
// Currently opened directory and its parents.
var
dir_parents
=
model
.
Parents
{};
var
cursor_idx
:
usize
=
0
;
var
window_top
:
usize
=
0
;
fn
sortIntLt
(
a
:
anytype
,
b
:
@TypeOf
(
a
))
?
bool
{
return
if
(
a
==
b
)
null
else
if
(
main
.
config
.
sort_order
==
.
asc
)
a
<
b
else
a
>
b
;
}
...
...
@@ -93,6 +96,8 @@ pub fn open(dir: model.Parents) !void {
dir_parents
=
dir
;
try
loadDir
();
window_top
=
0
;
cursor_idx
=
0
;
// TODO: Load view & cursor position if we've opened this dir before.
}
...
...
@@ -145,6 +150,11 @@ const Row = struct {
}
fn
draw
(
self
:
*
Self
)
!
void
{
if
(
self
.
bg
==
.
sel
)
{
self
.
bg
.
fg
(.
default
);
ui
.
move
(
self
.
row
,
0
);
ui
.
hline
(
' '
,
ui
.
cols
);
}
try
self
.
flag
();
try
self
.
size
();
try
self
.
name
();
...
...
@@ -175,10 +185,18 @@ pub fn draw() !void {
ui
.
addstr
(
try
ui
.
shorten
(
try
ui
.
toUtf8
(
model
.
root
.
entry
.
name
()),
saturateSub
(
ui
.
cols
,
5
)));
ui
.
addch
(
' '
);
const
numrows
=
saturateSub
(
ui
.
rows
,
3
);
if
(
cursor_idx
<
window_top
)
window_top
=
cursor_idx
;
if
(
cursor_idx
>=
window_top
+
numrows
)
window_top
=
cursor_idx
-
numrows
+
1
;
var
i
:
u32
=
0
;
while
(
i
<
saturateSub
(
ui
.
rows
,
3
))
:
(
i
+=
1
)
{
if
(
i
>=
dir_items
.
items
.
len
)
break
;
var
row
=
Row
{
.
row
=
i
+
2
,
.
item
=
dir_items
.
items
[
i
]
};
while
(
i
<
numrows
)
:
(
i
+=
1
)
{
if
(
i
+
window_top
>=
dir_items
.
items
.
len
)
break
;
var
row
=
Row
{
.
row
=
i
+
2
,
.
item
=
dir_items
.
items
[
i
+
window_top
],
.
bg
=
if
(
i
+
window_top
==
cursor_idx
)
.
sel
else
.
default
,
};
try
row
.
draw
();
}
...
...
@@ -193,3 +211,56 @@ pub fn draw() !void {
ui
.
addstr
(
" Items: "
);
ui
.
addnum
(.
hd
,
dir_parents
.
top
().
total_items
);
}
fn
sortToggle
(
col
:
main
.
SortCol
,
default_order
:
main
.
SortOrder
)
void
{
if
(
main
.
config
.
sort_col
!=
col
)
main
.
config
.
sort_order
=
default_order
else
if
(
main
.
config
.
sort_order
==
.
asc
)
main
.
config
.
sort_order
=
.
desc
else
main
.
config
.
sort_order
=
.
asc
;
main
.
config
.
sort_col
=
col
;
sortDir
();
}
pub
fn
key
(
ch
:
i32
)
!
void
{
switch
(
ch
)
{
'q'
=>
main
.
state
=
.
quit
,
// Selection
'j'
,
ui
.
c
.
KEY_DOWN
=>
{
if
(
cursor_idx
+
1
<
dir_items
.
items
.
len
)
cursor_idx
+=
1
;
},
'k'
,
ui
.
c
.
KEY_UP
=>
{
if
(
cursor_idx
>
0
)
cursor_idx
-=
1
;
},
ui
.
c
.
KEY_HOME
=>
cursor_idx
=
0
,
ui
.
c
.
KEY_END
,
ui
.
c
.
KEY_LL
=>
cursor_idx
=
saturateSub
(
dir_items
.
items
.
len
,
1
),
ui
.
c
.
KEY_PPAGE
=>
cursor_idx
=
saturateSub
(
cursor_idx
,
saturateSub
(
ui
.
rows
,
3
)),
ui
.
c
.
KEY_NPAGE
=>
cursor_idx
=
std
.
math
.
min
(
saturateSub
(
dir_items
.
items
.
len
,
1
),
cursor_idx
+
saturateSub
(
ui
.
rows
,
3
)),
// Sort & filter settings
'n'
=>
sortToggle
(.
name
,
.
asc
),
's'
=>
sortToggle
(
if
(
main
.
config
.
show_blocks
)
.
blocks
else
.
size
,
.
desc
),
'C'
=>
sortToggle
(.
items
,
.
desc
),
'M'
=>
if
(
main
.
config
.
extended
)
sortToggle
(.
mtime
,
.
desc
),
'e'
=>
{
main
.
config
.
show_hidden
=
!
main
.
config
.
show_hidden
;
try
loadDir
();
},
't'
=>
{
main
.
config
.
sort_dirsfirst
=
!
main
.
config
.
sort_dirsfirst
;
sortDir
();
},
'a'
=>
{
main
.
config
.
show_blocks
=
!
main
.
config
.
show_blocks
;
if
(
main
.
config
.
show_blocks
and
main
.
config
.
sort_col
==
.
size
)
{
main
.
config
.
sort_col
=
.
blocks
;
sortDir
();
}
if
(
!
main
.
config
.
show_blocks
and
main
.
config
.
sort_col
==
.
blocks
)
{
main
.
config
.
sort_col
=
.
size
;
sortDir
();
}
},
else
=>
{}
}
}
This diff is collapsed.
Click to expand it.
src/main.zig
+
30
−
49
View file @
d1eb7ba0
...
...
@@ -9,6 +9,9 @@ const c = @cImport(@cInclude("locale.h"));
pub
const
allocator
=
std
.
heap
.
c_allocator
;
pub
const
SortCol
=
enum
{
name
,
blocks
,
size
,
items
,
mtime
};
pub
const
SortOrder
=
enum
{
asc
,
desc
};
pub
const
Config
=
struct
{
same_fs
:
bool
=
true
,
extended
:
bool
=
false
,
...
...
@@ -17,7 +20,7 @@ pub const Config = struct {
exclude_kernfs
:
bool
=
false
,
exclude_patterns
:
std
.
ArrayList
([:
0
]
const
u8
)
=
std
.
ArrayList
([:
0
]
const
u8
).
init
(
allocator
),
update_delay
:
u
32
=
100
,
update_delay
:
u
64
=
100
*
std
.
time
.
ns_per_ms
,
si
:
bool
=
false
,
nc_tty
:
bool
=
false
,
ui_color
:
enum
{
off
,
dark
}
=
.
off
,
...
...
@@ -25,8 +28,8 @@ pub const Config = struct {
show_hidden
:
bool
=
true
,
show_blocks
:
bool
=
true
,
sort_col
:
enum
{
name
,
blocks
,
size
,
items
,
mtime
}
=
.
blocks
,
sort_order
:
enum
{
asc
,
desc
}
=
.
desc
,
sort_col
:
SortCol
=
.
blocks
,
sort_order
:
SortOrder
=
.
desc
,
sort_dirsfirst
:
bool
=
false
,
read_only
:
bool
=
false
,
...
...
@@ -36,6 +39,8 @@ pub const Config = struct {
pub
var
config
=
Config
{};
pub
var
state
:
enum
{
browse
,
quit
}
=
.
browse
;
// Simple generic argument parser, supports getopt_long() style arguments.
// T can be any type that has a 'fn next(T) ?[:0]const u8' method, e.g.:
// var args = Args(std.process.ArgIteratorPosix).init(std.process.ArgIteratorPosix.init());
...
...
@@ -112,46 +117,6 @@ fn Args(T: anytype) type {
};
}
// For debugging
fn
writeTree
(
out
:
anytype
,
e
:
*
model
.
Entry
,
indent
:
u32
)
@TypeOf
(
out
).
Error
!
void
{
var
i
:
u32
=
0
;
while
(
i
<
indent
)
{
try
out
.
writeByte
(
' '
);
i
+=
1
;
}
try
out
.
print
(
"{s} blocks={d} size={d}"
,
.
{
e
.
name
(),
e
.
blocks
,
e
.
size
});
if
(
e
.
dir
())
|
d
|
{
try
out
.
print
(
" blocks={d}-{d} size={d}-{d} items={d}-{d} dev={x}"
,
.
{
d
.
total_blocks
,
d
.
shared_blocks
,
d
.
total_size
,
d
.
shared_size
,
d
.
total_items
,
d
.
shared_items
,
d
.
dev
});
if
(
d
.
err
)
try
out
.
writeAll
(
" err"
);
if
(
d
.
suberr
)
try
out
.
writeAll
(
" suberr"
);
}
else
if
(
e
.
file
())
|
f
|
{
if
(
f
.
err
)
try
out
.
writeAll
(
" err"
);
if
(
f
.
excluded
)
try
out
.
writeAll
(
" excluded"
);
if
(
f
.
other_fs
)
try
out
.
writeAll
(
" other_fs"
);
if
(
f
.
kernfs
)
try
out
.
writeAll
(
" kernfs"
);
if
(
f
.
notreg
)
try
out
.
writeAll
(
" notreg"
);
}
else
if
(
e
.
link
())
|
l
|
{
try
out
.
print
(
" ino={x} nlinks={d}"
,
.
{
l
.
ino
,
l
.
nlink
});
}
if
(
e
.
ext
())
|
ext
|
try
out
.
print
(
" mtime={d} uid={d} gid={d} mode={o}"
,
.
{
ext
.
mtime
,
ext
.
uid
,
ext
.
gid
,
ext
.
mode
});
try
out
.
writeByte
(
'\n'
);
if
(
e
.
dir
())
|
d
|
{
var
s
=
d
.
sub
;
while
(
s
)
|
sub
|
{
try
writeTree
(
out
,
sub
,
indent
+
4
);
s
=
sub
.
next
;
}
}
}
fn
version
()
noreturn
{
std
.
io
.
getStdOut
().
writer
().
writeAll
(
"ncdu "
++
program_version
++
"
\n
"
)
catch
{};
std
.
process
.
exit
(
0
);
...
...
@@ -218,7 +183,7 @@ pub fn main() anyerror!void {
}
if
(
opt
.
is
(
"-h"
)
or
opt
.
is
(
"-?"
)
or
opt
.
is
(
"--help"
))
help
()
else
if
(
opt
.
is
(
"-v"
)
or
opt
.
is
(
"-V"
)
or
opt
.
is
(
"--version"
))
version
()
else
if
(
opt
.
is
(
"-q"
))
config
.
update_delay
=
2
000
else
if
(
opt
.
is
(
"-q"
))
config
.
update_delay
=
2
*
std
.
time
.
ns_per_s
else
if
(
opt
.
is
(
"-x"
))
config
.
same_fs
=
true
else
if
(
opt
.
is
(
"-e"
))
config
.
extended
=
true
else
if
(
opt
.
is
(
"-r"
)
and
config
.
read_only
)
config
.
can_shell
=
false
...
...
@@ -244,19 +209,35 @@ pub fn main() anyerror!void {
if
(
std
.
builtin
.
os
.
tag
!=
.
linux
and
config
.
exclude_kernfs
)
ui
.
die
(
"The --exclude-kernfs tag is currently only supported on Linux.
\n
"
,
.
{});
event_delay_timer
=
try
std
.
time
.
Timer
.
start
();
try
scan
.
scanRoot
(
scan_dir
orelse
"."
);
try
browser
.
open
(
model
.
Parents
{});
ui
.
init
();
defer
ui
.
deinit
();
try
browser
.
draw
();
// TODO: Handle OOM errors
// TODO: Confirm quit
while
(
state
!=
.
quit
)
try
handleEvent
(
true
,
false
);
}
var
event_delay_timer
:
std
.
time
.
Timer
=
undefined
;
_
=
ui
.
c
.
getch
();
// Draw the screen and handle the next input event.
// In non-blocking mode, screen drawing is rate-limited to keep this function fast.
pub
fn
handleEvent
(
block
:
bool
,
force_draw
:
bool
)
!
void
{
if
(
block
or
force_draw
or
event_delay_timer
.
read
()
>
config
.
update_delay
)
{
_
=
ui
.
c
.
erase
();
try
browser
.
draw
();
_
=
ui
.
c
.
refresh
();
event_delay_timer
.
reset
();
}
//var out = std.io.bufferedWriter(std.io.getStdOut().writer());
//try writeTree(out.writer(), &model.root.entry, 0);
//try out.flush();
var
ch
=
ui
.
getch
(
block
);
if
(
ch
==
0
)
return
;
if
(
ch
==
-
1
)
return
handleEvent
(
block
,
true
);
try
browser
.
key
(
ch
);
}
...
...
This diff is collapsed.
Click to expand it.
src/ui.zig
+
27
−
0
View file @
d1eb7ba0
...
...
@@ -279,6 +279,7 @@ pub fn init() void {
updateSize
();
_
=
c
.
cbreak
();
_
=
c
.
noecho
();
_
=
c
.
nonl
();
_
=
c
.
curs_set
(
0
);
_
=
c
.
keypad
(
c
.
stdscr
,
true
);
...
...
@@ -376,3 +377,29 @@ pub fn addnum(bg: Bg, v: u64) void {
pub
fn
hline
(
ch
:
c
.
chtype
,
len
:
u32
)
void
{
_
=
c
.
hline
(
ch
,
@intCast
(
i32
,
len
));
}
// Returns 0 if no key was pressed in non-blocking mode.
// Returns -1 if it was KEY_RESIZE, requiring a redraw of the screen.
pub
fn
getch
(
block
:
bool
)
i32
{
_
=
c
.
nodelay
(
c
.
stdscr
,
!
block
);
// getch() has a bad tendency to not set a sensible errno when it returns ERR.
// In non-blocking mode, we can only assume that ERR means "no input yet".
// In blocking mode, give it 100 tries with a 10ms delay in between,
// then just give up and die to avoid an infinite loop and unresponsive program.
var
attempts
:
u8
=
0
;
while
(
attempts
<
100
)
:
(
attempts
+=
1
)
{
var
ch
=
c
.
getch
();
if
(
ch
==
c
.
KEY_RESIZE
)
{
updateSize
();
return
-
1
;
}
if
(
ch
==
c
.
ERR
)
{
if
(
!
block
)
return
0
;
std
.
os
.
nanosleep
(
0
,
10
*
std
.
time
.
ns_per_ms
);
continue
;
}
return
ch
;
}
die
(
"Error reading keyboard input, assuming TTY has been lost.
\n
(Potentially nonsensical error message: {s})
\n
"
,
.
{
c
.
strerror
(
std
.
c
.
getErrno
(
-
1
))
});
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment