mirror of https://github.com/xzeldon/htop.git
Improve String_contains_i to allow for multiple terms
This enables: * Multiple filters in the main panel and strace etc. views * Multiple search terms The search terms are separated by "|" and are still fixed strings matched case-insensitive. Added a multi flag at request of BenBE.
This commit is contained in:
parent
a2ca7583a9
commit
7c43e02591
6
IncSet.c
6
IncSet.c
|
@ -85,7 +85,7 @@ static void updateWeakPanel(const IncSet* this, Panel* panel, Vector* lines) {
|
||||||
const char* incFilter = this->modes[INC_FILTER].buffer;
|
const char* incFilter = this->modes[INC_FILTER].buffer;
|
||||||
for (int i = 0; i < Vector_size(lines); i++) {
|
for (int i = 0; i < Vector_size(lines); i++) {
|
||||||
ListItem* line = (ListItem*)Vector_get(lines, i);
|
ListItem* line = (ListItem*)Vector_get(lines, i);
|
||||||
if (String_contains_i(line->value, incFilter)) {
|
if (String_contains_i(line->value, incFilter, true)) {
|
||||||
Panel_add(panel, (Object*)line);
|
Panel_add(panel, (Object*)line);
|
||||||
if (selected == (Object*)line) {
|
if (selected == (Object*)line) {
|
||||||
Panel_setSelected(panel, n);
|
Panel_setSelected(panel, n);
|
||||||
|
@ -108,7 +108,7 @@ static void updateWeakPanel(const IncSet* this, Panel* panel, Vector* lines) {
|
||||||
static bool search(const IncSet* this, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
static bool search(const IncSet* this, Panel* panel, IncMode_GetPanelValue getPanelValue) {
|
||||||
int size = Panel_size(panel);
|
int size = Panel_size(panel);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (String_contains_i(getPanelValue(panel, i), this->active->buffer)) {
|
if (String_contains_i(getPanelValue(panel, i), this->active->buffer, true)) {
|
||||||
Panel_setSelected(panel, i);
|
Panel_setSelected(panel, i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ static bool IncMode_find(const IncMode* mode, Panel* panel, IncMode_GetPanelValu
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
|
if (String_contains_i(getPanelValue(panel, i), mode->buffer, true)) {
|
||||||
Panel_setSelected(panel, i);
|
Panel_setSelected(panel, i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
|
||||||
void InfoScreen_addLine(InfoScreen* this, const char* line) {
|
void InfoScreen_addLine(InfoScreen* this, const char* line) {
|
||||||
Vector_add(this->lines, (Object*) ListItem_new(line, 0));
|
Vector_add(this->lines, (Object*) ListItem_new(line, 0));
|
||||||
const char* incFilter = IncSet_filter(this->inc);
|
const char* incFilter = IncSet_filter(this->inc);
|
||||||
if (!incFilter || String_contains_i(line, incFilter)) {
|
if (!incFilter || String_contains_i(line, incFilter, true)) {
|
||||||
Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
|
Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ void InfoScreen_appendLine(InfoScreen* this, const char* line) {
|
||||||
ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
|
ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
|
||||||
ListItem_append(last, line);
|
ListItem_append(last, line);
|
||||||
const char* incFilter = IncSet_filter(this->inc);
|
const char* incFilter = IncSet_filter(this->inc);
|
||||||
if (incFilter && Panel_get(this->display, Panel_size(this->display) - 1) != (Object*)last && String_contains_i(line, incFilter)) {
|
if (incFilter && Panel_get(this->display, Panel_size(this->display) - 1) != (Object*)last && String_contains_i(line, incFilter, true)) {
|
||||||
Panel_add(this->display, (Object*)last);
|
Panel_add(this->display, (Object*)last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,7 +394,7 @@ void ProcessList_rebuildPanel(ProcessList* this) {
|
||||||
|
|
||||||
if ( (!p->show)
|
if ( (!p->show)
|
||||||
|| (this->userId != (uid_t) -1 && (p->st_uid != this->userId))
|
|| (this->userId != (uid_t) -1 && (p->st_uid != this->userId))
|
||||||
|| (incFilter && !(String_contains_i(Process_getCommand(p), incFilter)))
|
|| (incFilter && !(String_contains_i(Process_getCommand(p), incFilter, true)))
|
||||||
|| (this->pidMatchList && !Hashtable_get(this->pidMatchList, p->tgid)) )
|
|| (this->pidMatchList && !Hashtable_get(this->pidMatchList, p->tgid)) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
18
XUtils.c
18
XUtils.c
|
@ -94,8 +94,22 @@ void* xReallocArrayZero(void* ptr, size_t prevmemb, size_t newmemb, size_t size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool String_contains_i(const char* s1, const char* s2) {
|
inline bool String_contains_i(const char* s1, const char* s2, bool multi) {
|
||||||
return strcasestr(s1, s2) != NULL;
|
// we have a multi-string search term, handle as special case for performance reasons
|
||||||
|
if (multi && strstr(s2, "|")) {
|
||||||
|
size_t nNeedles;
|
||||||
|
char** needles = String_split(s2, '|', &nNeedles);
|
||||||
|
for (size_t i = 0; i < nNeedles; i++) {
|
||||||
|
if (strcasestr(s1, needles[i]) != NULL) {
|
||||||
|
String_freeArray(needles);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String_freeArray(needles);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return strcasestr(s1, s2) != NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* String_cat(const char* s1, const char* s2) {
|
char* String_cat(const char* s1, const char* s2) {
|
||||||
|
|
2
XUtils.h
2
XUtils.h
|
@ -40,7 +40,7 @@ static inline bool String_startsWith(const char* s, const char* match) {
|
||||||
return strncmp(s, match, strlen(match)) == 0;
|
return strncmp(s, match, strlen(match)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool String_contains_i(const char* s1, const char* s2);
|
bool String_contains_i(const char* s1, const char* s2, bool multi);
|
||||||
|
|
||||||
static inline bool String_eq(const char* s1, const char* s2) {
|
static inline bool String_eq(const char* s1, const char* s2) {
|
||||||
return strcmp(s1, s2) == 0;
|
return strcmp(s1, s2) == 0;
|
||||||
|
|
|
@ -85,7 +85,7 @@ char* Generic_uname(void) {
|
||||||
|
|
||||||
if (uname_result == 0) {
|
if (uname_result == 0) {
|
||||||
size_t written = xSnprintf(savedString, sizeof(savedString), "%s %s [%s]", uname_info.sysname, uname_info.release, uname_info.machine);
|
size_t written = xSnprintf(savedString, sizeof(savedString), "%s %s [%s]", uname_info.sysname, uname_info.release, uname_info.machine);
|
||||||
if (!String_contains_i(savedString, distro) && sizeof(savedString) > written)
|
if (!String_contains_i(savedString, distro, false) && sizeof(savedString) > written)
|
||||||
snprintf(savedString + written, sizeof(savedString) - written, " @ %s", distro);
|
snprintf(savedString + written, sizeof(savedString) - written, " @ %s", distro);
|
||||||
} else {
|
} else {
|
||||||
snprintf(savedString, sizeof(savedString), "%s", distro);
|
snprintf(savedString, sizeof(savedString), "%s", distro);
|
||||||
|
|
|
@ -50,7 +50,8 @@ Start
|
||||||
in monochrome mode
|
in monochrome mode
|
||||||
.TP
|
.TP
|
||||||
\fB\-F \-\-filter=FILTER
|
\fB\-F \-\-filter=FILTER
|
||||||
Filter processes by command
|
Filter processes by terms matching the commands. The terms are matched
|
||||||
|
case-insensitive and as fixed strings (not regexs). You can separate multiple terms with "|".
|
||||||
.TP
|
.TP
|
||||||
\fB\-h \-\-help
|
\fB\-h \-\-help
|
||||||
Display a help message and exit
|
Display a help message and exit
|
||||||
|
@ -175,6 +176,8 @@ bindings take precedence.
|
||||||
Incremental process filtering: type in part of a process command line and
|
Incremental process filtering: type in part of a process command line and
|
||||||
only processes whose names match will be shown. To cancel filtering,
|
only processes whose names match will be shown. To cancel filtering,
|
||||||
enter the Filter option again and press Esc.
|
enter the Filter option again and press Esc.
|
||||||
|
The matching is done case-insensitive. Terms are fixed strings (no regex).
|
||||||
|
You can separate multiple terms with "|".
|
||||||
.TP
|
.TP
|
||||||
.B F5, t
|
.B F5, t
|
||||||
Tree view: organize processes by parenthood, and layout the relations
|
Tree view: organize processes by parenthood, and layout the relations
|
||||||
|
|
Loading…
Reference in New Issue