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
htop
Commits
11092662
Commit
11092662
authored
Sep 08, 2011
by
Hisham Muhammad
Browse files
incremental filtering
plus some fixes
parent
3f3213b2
Changes
4
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
11092662
...
...
@@ -6,6 +6,8 @@ What's new in version 0.9.1
* Meters update in every screen (no longer halting while on Setup, etc.)
* Stricter checks for command-line options
(thanks to Sebastian Pipping)
* Incremental filtering
(thanks to Seth Heeren for the idea and initial implementation)
* BUGFIX: Support larger numbers for process times.
(thanks to Tristan Nakagawa for the report.)
* BUGFIX: Segfault in BarMeterMode_draw() for small terminal widths
...
...
htop.1.in
View file @
11092662
...
...
@@ -67,7 +67,12 @@ Incremental process search: type in part of a process command line and
the selection highlight will be moved to it. While in search mode,
pressing this key will cycle through matching occurrences.
.TP
.B F4, I
.B F4, \
Incremental process filtering: type in part of a process command line and
only processes whose names match will be shown. To cancel filtering,
enter the Filter option again and press Esc.
.TP
.B I
Invert sort order: if sort order is increasing, switch to decreasing,
and vice-versa.
.TP
...
...
htop.c
View file @
11092662
...
...
@@ -118,7 +118,7 @@ static void showHelp(ProcessList* pl) {
mvaddstr
(
9
,
0
,
" Arrows: scroll process list F5 t: tree view"
);
mvaddstr
(
10
,
0
,
" Digits: incremental PID search u: show processes of a single user"
);
mvaddstr
(
11
,
0
,
" F3 /: incremental name search H: hide/show user threads"
);
mvaddstr
(
12
,
0
,
"
K: hide/show kernel threads"
);
mvaddstr
(
12
,
0
,
"
F4
\\
: incremental name filtering
K: hide/show kernel threads"
);
mvaddstr
(
13
,
0
,
" Space: tag processes F: cursor follows process"
);
mvaddstr
(
14
,
0
,
" U: untag all processes + -: expand/collapse tree"
);
mvaddstr
(
15
,
0
,
" F9 k: kill process/tagged processes P: sort by CPU%"
);
...
...
@@ -126,10 +126,10 @@ static void showHelp(ProcessList* pl) {
mvaddstr
(
17
,
0
,
" [ F8: lower priority (+ nice) T: sort by TIME"
);
#ifdef HAVE_PLPA
if
(
pl
->
cpuCount
>
1
)
mvaddstr
(
18
,
0
,
" a: set CPU affinity
F4
I: invert sort order"
);
mvaddstr
(
18
,
0
,
" a: set CPU affinity
I: invert sort order"
);
else
#endif
mvaddstr
(
18
,
0
,
"
F4
I: invert sort order"
);
mvaddstr
(
18
,
0
,
"
I: invert sort order"
);
mvaddstr
(
19
,
0
,
" F2 S: setup F6 >: select sort column"
);
mvaddstr
(
20
,
0
,
" F1 h: show this help screen l: list open files with lsof"
);
mvaddstr
(
21
,
0
,
" F10 q: quit s: trace syscalls with strace"
);
...
...
@@ -138,7 +138,7 @@ static void showHelp(ProcessList* pl) {
mvaddstr
(
9
,
0
,
" Arrows"
);
mvaddstr
(
9
,
40
,
" F5 t"
);
mvaddstr
(
10
,
0
,
" Digits"
);
mvaddstr
(
10
,
40
,
" u"
);
mvaddstr
(
11
,
0
,
" F3 /"
);
mvaddstr
(
11
,
40
,
" H"
);
mvaddstr
(
12
,
40
,
" K"
);
mvaddstr
(
12
,
0
,
" F4
\\
"
);
mvaddstr
(
12
,
40
,
" K"
);
mvaddstr
(
13
,
0
,
" Space"
);
mvaddstr
(
13
,
40
,
" F"
);
mvaddstr
(
14
,
0
,
" U"
);
mvaddstr
(
14
,
40
,
" + -"
);
mvaddstr
(
15
,
0
,
" F9 k"
);
mvaddstr
(
15
,
40
,
" P"
);
...
...
@@ -246,6 +246,17 @@ static inline void setSortKey(ProcessList* pl, ProcessField sortKey, Panel* pane
ProcessList_printHeader
(
pl
,
Panel_getHeader
(
panel
));
}
typedef
struct
IncBuffer_
{
char
buffer
[
INCSEARCH_MAX
];
int
index
;
FunctionBar
*
bar
;
}
IncBuffer
;
static
void
IncBuffer_reset
(
IncBuffer
*
inc
)
{
inc
->
index
=
0
;
inc
->
buffer
[
0
]
=
0
;
}
int
main
(
int
argc
,
char
**
argv
)
{
int
delay
=
-
1
;
...
...
@@ -334,12 +345,7 @@ int main(int argc, char** argv) {
Settings
*
settings
;
Panel
*
killPanel
=
NULL
;
char
incSearchBuffer
[
INCSEARCH_MAX
];
int
incSearchIndex
=
0
;
incSearchBuffer
[
0
]
=
0
;
bool
incSearchMode
=
false
;
ProcessList
*
pl
=
NULL
;
UsersTable
*
ut
=
UsersTable_new
();
...
...
@@ -364,13 +370,25 @@ int main(int argc, char** argv) {
pl
->
direction
=
1
;
}
ProcessList_printHeader
(
pl
,
Panel_getHeader
(
panel
));
const
char
*
searchFunctions
[]
=
{
"Next "
,
"Exit "
,
" Search: "
,
NULL
};
IncBuffer
incSearch
,
incFilter
;
bool
filtering
=
false
;
memset
(
&
incSearch
,
0
,
sizeof
(
IncBuffer
));
const
char
*
searchFunctions
[]
=
{
"Next "
,
"Cancel "
,
" Search: "
,
NULL
};
const
char
*
searchKeys
[]
=
{
"F3"
,
"Esc"
,
" "
};
int
searchEvents
[]
=
{
KEY_F
(
3
),
27
,
ERR
};
FunctionBar
*
searchBar
=
FunctionBar_new
(
searchFunctions
,
searchKeys
,
searchEvents
);
incSearch
.
bar
=
FunctionBar_new
(
searchFunctions
,
searchKeys
,
searchEvents
);
memset
(
&
incFilter
,
0
,
sizeof
(
IncBuffer
));
const
char
*
filterFunctions
[]
=
{
"Done "
,
"Clear "
,
" Filter: "
,
NULL
};
const
char
*
filterKeys
[]
=
{
"Enter"
,
"Esc"
,
" "
};
int
filterEvents
[]
=
{
13
,
27
,
ERR
};
incFilter
.
bar
=
FunctionBar_new
(
filterFunctions
,
filterKeys
,
filterEvents
);
const
char
*
defaultFunctions
[]
=
{
"Help "
,
"Setup "
,
"Search"
,
"Invert"
,
"Tree "
,
IncBuffer
*
incMode
=
NULL
;
const
char
*
defaultFunctions
[]
=
{
"Help "
,
"Setup "
,
"Search"
,
"Filter"
,
"Tree "
,
"SortBy"
,
"Nice -"
,
"Nice +"
,
"Kill "
,
"Quit "
,
NULL
};
FunctionBar
*
defaultBar
=
FunctionBar_new
(
defaultFunctions
,
NULL
,
NULL
);
...
...
@@ -397,6 +415,7 @@ int main(int argc, char** argv) {
if
(
recalculate
)
oldTime
=
newTime
;
if
(
doRefresh
)
{
int
currPos
=
Panel_getSelectedIndex
(
panel
);
pid_t
currPid
=
0
;
int
currScrollV
=
panel
->
scrollV
;
...
...
@@ -414,8 +433,15 @@ int main(int argc, char** argv) {
int
size
=
ProcessList_size
(
pl
);
int
idx
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
bool
hidden
=
false
;
Process
*
p
=
ProcessList_get
(
pl
,
i
);
if
(
p
->
show
&&
(
!
userOnly
||
(
p
->
st_uid
==
userId
)))
{
if
(
(
!
p
->
show
)
||
(
userOnly
&&
(
p
->
st_uid
!=
userId
))
||
(
filtering
&&
!
(
String_contains_i
(
p
->
comm
,
incFilter
.
buffer
)))
)
hidden
=
true
;
if
(
!
hidden
)
{
Panel_set
(
panel
,
idx
,
(
Object
*
)
p
);
if
((
!
follow
&&
idx
==
currPos
)
||
(
follow
&&
p
->
pid
==
currPid
))
{
Panel_setSelected
(
panel
,
idx
);
...
...
@@ -431,10 +457,11 @@ int main(int argc, char** argv) {
Panel_draw
(
panel
,
true
);
int
prev
=
ch
;
move
(
LINES
-
1
,
CRT_cursorX
);
ch
=
getch
();
if
(
ch
==
ERR
)
{
if
(
!
inc
Search
Mode
)
if
(
!
incMode
)
refreshTimeout
--
;
if
(
prev
==
ch
&&
!
recalculate
)
{
closeTimeout
++
;
...
...
@@ -446,7 +473,7 @@ int main(int argc, char** argv) {
continue
;
}
if
(
inc
Search
Mode
)
{
if
(
incMode
)
{
doRefresh
=
false
;
int
size
=
Panel_size
(
panel
);
if
(
ch
==
KEY_F
(
3
))
{
...
...
@@ -456,22 +483,40 @@ int main(int argc, char** argv) {
if
(
i
==
size
)
i
=
0
;
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
String_contains_i
(
p
->
comm
,
inc
SearchB
uffer
))
{
if
(
String_contains_i
(
p
->
comm
,
inc
Mode
->
b
uffer
))
{
Panel_setSelected
(
panel
,
i
);
break
;
}
i
++
;
}
continue
;
}
else
if
(
isprint
((
char
)
ch
)
&&
(
incSearchIndex
<
INCSEARCH_MAX
))
{
incSearchBuffer
[
incSearchIndex
]
=
ch
;
incSearchIndex
++
;
incSearchBuffer
[
incSearchIndex
]
=
0
;
}
else
if
((
ch
==
KEY_BACKSPACE
||
ch
==
127
)
&&
(
incSearchIndex
>
0
))
{
incSearchIndex
--
;
incSearchBuffer
[
incSearchIndex
]
=
0
;
}
else
if
(
isprint
((
char
)
ch
)
&&
(
incMode
->
index
<
INCSEARCH_MAX
))
{
incMode
->
buffer
[
incMode
->
index
]
=
ch
;
incMode
->
index
++
;
incMode
->
buffer
[
incMode
->
index
]
=
0
;
if
(
incMode
==
&
incFilter
)
{
doRefresh
=
true
;
if
(
incFilter
.
index
==
1
)
filtering
=
true
;
}
}
else
if
((
ch
==
KEY_BACKSPACE
||
ch
==
127
)
&&
(
incMode
->
index
>
0
))
{
incMode
->
index
--
;
incMode
->
buffer
[
incMode
->
index
]
=
0
;
if
(
incMode
==
&
incFilter
)
{
doRefresh
=
true
;
if
(
incFilter
.
index
==
0
)
{
filtering
=
false
;
IncBuffer_reset
(
incMode
);
}
}
}
else
{
incSearchMode
=
false
;
if
(
incMode
==
&
incFilter
)
{
doRefresh
=
true
;
if
(
ch
==
27
)
{
filtering
=
false
;
IncBuffer_reset
(
incMode
);
}
}
incMode
=
NULL
;
FunctionBar_draw
(
defaultBar
,
NULL
);
continue
;
}
...
...
@@ -479,16 +524,16 @@ int main(int argc, char** argv) {
bool
found
=
false
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
String_contains_i
(
p
->
comm
,
incSearch
B
uffer
))
{
if
(
String_contains_i
(
p
->
comm
,
incSearch
.
b
uffer
))
{
Panel_setSelected
(
panel
,
i
);
found
=
true
;
break
;
}
}
if
(
found
)
FunctionBar_draw
(
searchBar
,
incSearchB
uffer
);
FunctionBar_draw
(
incMode
->
bar
,
incMode
->
b
uffer
);
else
FunctionBar_drawAttr
(
searchBar
,
incSearchB
uffer
,
CRT_colors
[
FAILED_SEARCH
]);
FunctionBar_drawAttr
(
incMode
->
bar
,
incMode
->
b
uffer
,
CRT_colors
[
FAILED_SEARCH
]);
continue
;
}
if
(
isdigit
((
char
)
ch
))
{
...
...
@@ -527,7 +572,7 @@ int main(int argc, char** argv) {
continue
;
}
if
(
mevent
.
y
==
LINES
-
1
)
{
FunctionBar
*
bar
;
if
(
inc
Search
Mode
)
bar
=
searchB
ar
;
if
(
incMode
)
bar
=
incMode
->
b
ar
;
else
bar
=
defaultBar
;
ch
=
FunctionBar_synthesizeEvent
(
bar
,
mevent
.
x
);
}
...
...
@@ -544,8 +589,8 @@ int main(int argc, char** argv) {
switch
(
ch
)
{
case
KEY_RESIZE
:
Panel_resize
(
panel
,
COLS
,
LINES
-
headerHeight
-
1
);
if
(
inc
Search
Mode
)
FunctionBar_draw
(
searchBar
,
incSearchB
uffer
);
if
(
incMode
)
FunctionBar_draw
(
incMode
->
bar
,
incMode
->
b
uffer
);
else
FunctionBar_draw
(
defaultBar
,
NULL
);
break
;
...
...
@@ -653,11 +698,11 @@ int main(int argc, char** argv) {
if
(
picked
)
{
if
(
picked
==
allUsers
)
{
userOnly
=
false
;
break
;
}
else
{
setUserOnly
(
ListItem_getRef
(
picked
),
&
userOnly
,
&
userId
);
}
}
Panel_delete
((
Object
*
)
usersPanel
);
break
;
}
case
'+'
:
...
...
@@ -773,7 +818,6 @@ int main(int argc, char** argv) {
break
;
}
case
'I'
:
case
KEY_F
(
4
):
{
refreshTimeout
=
0
;
settings
->
changed
=
true
;
...
...
@@ -794,11 +838,17 @@ int main(int argc, char** argv) {
}
case
KEY_F
(
3
):
case
'/'
:
incSearchIndex
=
0
;
incSearchBuffer
[
0
]
=
0
;
incSearchMode
=
true
;
FunctionBar_draw
(
searchBar
,
incSearchBuffer
);
incMode
=
&
incSearch
;
IncBuffer_reset
(
incMode
);
FunctionBar_draw
(
incSearch
.
bar
,
incSearch
.
buffer
);
break
;
case
KEY_F
(
4
):
case
'\\'
:
incMode
=
&
incFilter
;
refreshTimeout
=
0
;
doRefresh
=
true
;
FunctionBar_draw
(
incFilter
.
bar
,
incFilter
.
buffer
);
continue
;
case
't'
:
case
KEY_F
(
5
):
refreshTimeout
=
0
;
...
...
@@ -837,9 +887,10 @@ int main(int argc, char** argv) {
Settings_write
(
settings
);
Header_delete
(
header
);
ProcessList_delete
(
pl
);
FunctionBar_delete
((
Object
*
)
searchBar
);
FunctionBar_delete
((
Object
*
)
incFilter
.
bar
);
FunctionBar_delete
((
Object
*
)
incSearch
.
bar
);
FunctionBar_delete
((
Object
*
)
defaultBar
);
((
Object
*
)
p
anel
)
->
delete
((
Object
*
)
panel
);
P
anel
_
delete
((
Object
*
)
panel
);
if
(
killPanel
)
((
Object
*
)
killPanel
)
->
delete
((
Object
*
)
killPanel
);
UsersTable_delete
(
ut
);
...
...
htop.h
View file @
11092662
...
...
@@ -43,6 +43,8 @@ in the source distribution for its full text.
#define COPYRIGHT "(C) 2004-2011 Hisham Muhammad"
typedef
struct
IncBuffer_
;
int
main
(
int
argc
,
char
**
argv
);
#endif
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