mirror of
https://github.com/xzeldon/htop.git
synced 2024-12-23 22:55:46 +00:00
Support for UTF-8 tree drawing
(thanks to Bin Guo)
This commit is contained in:
parent
b45b9e2b33
commit
ca6b9238a3
@ -2,6 +2,8 @@
|
||||
What's new in version 0.9.1
|
||||
|
||||
* Switch from PLPA, which is now deprecated, to HWLOC.
|
||||
* Support for UTF-8 tree drawing
|
||||
(thanks to Bin Guo)
|
||||
* Option for counting CPUs from zero
|
||||
(thanks to Sean Noonan)
|
||||
* Meters update in every screen (no longer halting while on Setup, etc.)
|
||||
|
25
Process.c
25
Process.c
@ -387,21 +387,26 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||
} else {
|
||||
char* buf = buffer;
|
||||
int maxIndent = 0;
|
||||
const char **treeStr = this->pl->treeStr;
|
||||
bool lastItem = (this->indent < 0);
|
||||
int indent = (this->indent < 0 ? -this->indent : this->indent);
|
||||
if (treeStr == NULL)
|
||||
treeStr = ProcessList_treeStrAscii;
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
if (this->indent & (1 << i))
|
||||
if (indent & (1 << i))
|
||||
maxIndent = i+1;
|
||||
for (int i = 0; i < maxIndent - 1; i++) {
|
||||
if (this->indent & (1 << i))
|
||||
snprintf(buf, n, " | ");
|
||||
int written;
|
||||
if (indent & (1 << i))
|
||||
written = snprintf(buf, n, "%s ", treeStr[TREE_STR_VERT]);
|
||||
else
|
||||
snprintf(buf, n, " ");
|
||||
buf += 4;
|
||||
n -= 4;
|
||||
written = snprintf(buf, n, " ");
|
||||
buf += written;
|
||||
n -= written;
|
||||
}
|
||||
if (this->pl->direction == 1)
|
||||
snprintf(buf, n, " `%s ", this->showChildren ? "-" : "+" );
|
||||
else
|
||||
snprintf(buf, n, " ,%s ", this->showChildren ? "-" : "+" );
|
||||
const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
|
||||
snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
|
||||
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
|
||||
Process_writeCommand(this, attr, baseattr, str);
|
||||
return;
|
||||
|
@ -57,9 +57,23 @@ in the source distribution for its full text.
|
||||
#ifndef ProcessList_cpuId
|
||||
#define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
|
||||
#endif
|
||||
}*/
|
||||
|
||||
/*{
|
||||
typedef enum TreeStr_ {
|
||||
TREE_STR_HORZ,
|
||||
TREE_STR_VERT,
|
||||
TREE_STR_RTEE,
|
||||
TREE_STR_BEND,
|
||||
TREE_STR_TEND,
|
||||
TREE_STR_OPEN,
|
||||
TREE_STR_SHUT,
|
||||
TREE_STR_COUNT
|
||||
} TreeStr;
|
||||
|
||||
typedef enum TreeType_ {
|
||||
TREE_TYPE_AUTO,
|
||||
TREE_TYPE_ASCII,
|
||||
TREE_TYPE_UTF8,
|
||||
} TreeType;
|
||||
|
||||
typedef struct CPUData_ {
|
||||
unsigned long long int totalTime;
|
||||
@ -132,12 +146,34 @@ typedef struct ProcessList_ {
|
||||
bool highlightThreads;
|
||||
bool detailedCPUTime;
|
||||
bool countCPUsFromZero;
|
||||
const char **treeStr;
|
||||
|
||||
} ProcessList;
|
||||
|
||||
}*/
|
||||
|
||||
static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||
|
||||
const char *ProcessList_treeStrAscii[TREE_STR_COUNT] = {
|
||||
"-", // TREE_STR_HORZ
|
||||
"|", // TREE_STR_VERT
|
||||
"`", // TREE_STR_RTEE
|
||||
"`", // TREE_STR_BEND
|
||||
",", // TREE_STR_TEND
|
||||
"+", // TREE_STR_OPEN
|
||||
"-", // TREE_STR_SHUT
|
||||
};
|
||||
|
||||
const char *ProcessList_treeStrUtf8[TREE_STR_COUNT] = {
|
||||
"\xe2\x94\x80", // TREE_STR_HORZ ─
|
||||
"\xe2\x94\x82", // TREE_STR_VERT │
|
||||
"\xe2\x94\x9c", // TREE_STR_RTEE ├
|
||||
"\xe2\x94\x94", // TREE_STR_BEND └
|
||||
"\xe2\x94\x8c", // TREE_STR_TEND ┌
|
||||
"+", // TREE_STR_OPEN +
|
||||
"\xe2\x94\x80", // TREE_STR_SHUT ─
|
||||
};
|
||||
|
||||
ProcessList* ProcessList_new(UsersTable* usersTable) {
|
||||
ProcessList* this;
|
||||
this = calloc(sizeof(ProcessList), 1);
|
||||
@ -194,6 +230,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
|
||||
this->highlightMegabytes = false;
|
||||
this->detailedCPUTime = false;
|
||||
this->countCPUsFromZero = false;
|
||||
this->treeStr = NULL;
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -282,7 +319,10 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
|
||||
assert(this->processes2->items == s+1); (void)s;
|
||||
int nextIndent = indent | (1 << level);
|
||||
ProcessList_buildTree(this, process->pid, level+1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
|
||||
process->indent = nextIndent;
|
||||
if (i == size - 1)
|
||||
process->indent = -nextIndent;
|
||||
else
|
||||
process->indent = nextIndent;
|
||||
}
|
||||
Vector_delete(children);
|
||||
}
|
||||
|
@ -60,6 +60,22 @@ in the source distribution for its full text.
|
||||
#define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
|
||||
#endif
|
||||
|
||||
typedef enum TreeStr_ {
|
||||
TREE_STR_HORZ,
|
||||
TREE_STR_VERT,
|
||||
TREE_STR_RTEE,
|
||||
TREE_STR_BEND,
|
||||
TREE_STR_TEND,
|
||||
TREE_STR_OPEN,
|
||||
TREE_STR_SHUT,
|
||||
TREE_STR_COUNT
|
||||
} TreeStr;
|
||||
|
||||
typedef enum TreeType_ {
|
||||
TREE_TYPE_AUTO,
|
||||
TREE_TYPE_ASCII,
|
||||
TREE_TYPE_UTF8,
|
||||
} TreeType;
|
||||
|
||||
typedef struct CPUData_ {
|
||||
unsigned long long int totalTime;
|
||||
@ -132,9 +148,15 @@ typedef struct ProcessList_ {
|
||||
bool highlightThreads;
|
||||
bool detailedCPUTime;
|
||||
bool countCPUsFromZero;
|
||||
const char **treeStr;
|
||||
|
||||
} ProcessList;
|
||||
|
||||
|
||||
extern const char *ProcessList_treeStrAscii[TREE_STR_COUNT];
|
||||
|
||||
extern const char *ProcessList_treeStrUtf8[TREE_STR_COUNT];
|
||||
|
||||
ProcessList* ProcessList_new(UsersTable* usersTable);
|
||||
|
||||
void ProcessList_delete(ProcessList* this);
|
||||
|
33
htop.c
33
htop.c
@ -263,6 +263,7 @@ int main(int argc, char** argv) {
|
||||
bool userOnly = false;
|
||||
uid_t userId = 0;
|
||||
int usecolors = 1;
|
||||
TreeType treeType = TREE_TYPE_AUTO;
|
||||
|
||||
int opt, opti=0;
|
||||
static struct option long_opts[] =
|
||||
@ -281,8 +282,10 @@ int main(int argc, char** argv) {
|
||||
char *lc_ctype = getenv("LC_CTYPE");
|
||||
if(lc_ctype != NULL)
|
||||
setlocale(LC_CTYPE, lc_ctype);
|
||||
else if ((lc_ctype = getenv("LC_ALL")))
|
||||
setlocale(LC_CTYPE, lc_ctype);
|
||||
else
|
||||
setlocale(LC_CTYPE, getenv("LC_ALL"));
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
/* Parse arguments */
|
||||
while ((opt = getopt_long(argc, argv, "hvCs:d:u:", long_opts, &opti))) {
|
||||
@ -361,6 +364,34 @@ int main(int argc, char** argv) {
|
||||
settings->delay = delay;
|
||||
if (!usecolors)
|
||||
settings->colorScheme = COLORSCHEME_MONOCHROME;
|
||||
|
||||
if (treeType == TREE_TYPE_AUTO) {
|
||||
#ifdef HAVE_LIBNCURSESW
|
||||
char *locale = setlocale(LC_ALL, NULL);
|
||||
if (locale == NULL || locale[0] == '\0')
|
||||
locale = setlocale(LC_CTYPE, NULL);
|
||||
if (locale != NULL &&
|
||||
(strstr(locale, "UTF-8") ||
|
||||
strstr(locale, "utf-8") ||
|
||||
strstr(locale, "UTF8") ||
|
||||
strstr(locale, "utf8")))
|
||||
treeType = TREE_TYPE_UTF8;
|
||||
else
|
||||
treeType = TREE_TYPE_ASCII;
|
||||
#else
|
||||
treeType = TREE_TYPE_ASCII;
|
||||
#endif
|
||||
}
|
||||
switch (treeType) {
|
||||
default:
|
||||
case TREE_TYPE_ASCII:
|
||||
pl->treeStr = ProcessList_treeStrAscii;
|
||||
break;
|
||||
case TREE_TYPE_UTF8:
|
||||
pl->treeStr = ProcessList_treeStrUtf8;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
CRT_init(settings->delay, settings->colorScheme);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user