Skip to content

Commit cb12927

Browse files
committed
Add user-configurable distribution path prefixes
Assisted-by: Claude (Anthropic)
1 parent 088e26d commit cb12927

6 files changed

Lines changed: 134 additions & 3 deletions

File tree

DisplayOptionsPanel.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
4545
}
4646

4747
NumberItem* numItem = (OptionItem_kind(selected) == OPTION_ITEM_NUMBER) ? (NumberItem*)selected : NULL;
48+
StringItem* strItem = (OptionItem_kind(selected) == OPTION_ITEM_STRING) ? (StringItem*)selected : NULL;
4849

4950
/* Helper: position the hardware cursor right after the edit buffer.
5051
* +1 on Y for the panel header row; +1 on X for the leading '[' bracket. */
@@ -54,8 +55,19 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
5455
super->cursorOn = true; \
5556
} while (0)
5657

58+
#define SET_STR_CURSOR() do { \
59+
super->cursorY = super->y + 1 + (super->selected - super->scrollV); \
60+
super->cursorX = super->x + 1 + (int)LineEditor_getCursor(&strItem->editor); \
61+
super->cursorOn = true; \
62+
} while (0)
63+
5764
switch (ch) {
5865
case 27: /* Escape: cancel editing */
66+
if (numItem && numItem->editing) {
67+
NumberItem_cancelEditing(numItem);
68+
super->cursorOn = false;
69+
return HANDLED;
70+
}
5971
if (numItem && numItem->editing) {
6072
NumberItem_cancelEditing(numItem);
6173
super->cursorOn = false;
@@ -64,6 +76,11 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
6476
break;
6577
case KEY_BACKSPACE:
6678
case KEY_DEL_MAC:
79+
if (strItem && strItem->editing) {
80+
LineEditor_handleKey(&strItem->editor, KEY_BACKSPACE);
81+
SET_STR_CURSOR();
82+
return HANDLED;
83+
}
6784
if (numItem) {
6885
if (!numItem->editing) {
6986
NumberItem_startEditingFromValue(numItem);
@@ -76,6 +93,19 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
7693
case '\n':
7794
case '\r':
7895
case KEY_ENTER:
96+
if (strItem && strItem->editing) {
97+
StringItem_applyEditing(strItem);
98+
super->cursorOn = false;
99+
settingsChanged = true;
100+
result = HANDLED;
101+
break;
102+
}
103+
if (strItem && !strItem->editing) {
104+
StringItem_startEditing(strItem);
105+
SET_STR_CURSOR();
106+
result = HANDLED;
107+
break;
108+
}
79109
if (numItem && numItem->editing) {
80110
if (NumberItem_applyEditing(numItem)) {
81111
settingsChanged = true;
@@ -219,6 +249,12 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
219249
SET_EDIT_CURSOR();
220250
return HANDLED;
221251
}
252+
} else if (strItem) {
253+
if (strItem->editing) {
254+
LineEditor_handleKey(&strItem->editor, ch);
255+
SET_STR_CURSOR();
256+
return HANDLED;
257+
}
222258
}
223259
break;
224260
}
@@ -282,6 +318,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
282318
Panel_add(super, (Object*) CheckItem_newByRef("Highlight program \"basename\"", &(settings->highlightBaseName)));
283319
Panel_add(super, (Object*) CheckItem_newByRef("Highlight out-dated/removed programs (red) / libraries (yellow)", &(settings->highlightDeletedExe)));
284320
Panel_add(super, (Object*) CheckItem_newByRef("Shadow distribution path prefixes", &(settings->shadowDistPathPrefix)));
321+
Panel_add(super, (Object*) StringItem_newByRef("- Custom path prefixes (colon-separated)", &(settings->distPathPrefixes), NULL));
285322
Panel_add(super, (Object*) CheckItem_newByRef("Merge exe, comm and cmdline in Command", &(settings->showMergedCommand)));
286323
Panel_add(super, (Object*) CheckItem_newByRef("- Try to find comm in cmdline (when Command is merged)", &(settings->findCommInCmdline)));
287324
Panel_add(super, (Object*) CheckItem_newByRef("- Try to strip exe from cmdline (when Command is merged)", &(settings->stripExeFromCmdline)));

OptionItem.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@ static void NumberItem_display(const Object* cast, RichString* out) {
7676
RichString_appendWide(out, CRT_colors[CHECK_TEXT], this->super.text);
7777
}
7878

79+
static void StringItem_display(const Object* cast, RichString* out) {
80+
const StringItem* this = (const StringItem*)cast;
81+
int labelAttr = CRT_colors[CHECK_TEXT];
82+
int boxAttr = CRT_colors[CHECK_BOX];
83+
int valAttr = this->valid ? CRT_colors[CHECK_MARK] : CRT_colors[FAILED_READ];
84+
85+
RichString_writeAscii(out, boxAttr, "[");
86+
if (this->editing) {
87+
RichString_appendAscii(out, valAttr, this->editor.buffer);
88+
} else {
89+
const char* val = (this->ref && *this->ref) ? *this->ref : NULL;
90+
if (val) {
91+
RichString_appendAscii(out, valAttr, val);
92+
} else {
93+
RichString_appendAscii(out, CRT_colors[PROCESS_SHADOW], "(empty)");
94+
}
95+
}
96+
RichString_appendAscii(out, boxAttr, "] ");
97+
RichString_appendWide(out, labelAttr, this->super.text);
98+
}
99+
79100
const OptionItemClass OptionItem_class = {
80101
.super = {
81102
.extends = Class(Object),
@@ -112,6 +133,15 @@ const OptionItemClass NumberItem_class = {
112133
.kind = OPTION_ITEM_NUMBER
113134
};
114135

136+
const OptionItemClass StringItem_class = {
137+
.super = {
138+
.extends = Class(OptionItem),
139+
.delete = OptionItem_delete,
140+
.display = StringItem_display
141+
},
142+
.kind = OPTION_ITEM_STRING
143+
};
144+
115145
TextItem* TextItem_new(const char* text) {
116146
TextItem* this = AllocThis(TextItem);
117147
this->super.text = xStrdup(text);
@@ -323,3 +353,40 @@ void NumberItem_deleteChar(NumberItem* this) {
323353
this->editBuffer[this->editLen] = '\0';
324354
}
325355
}
356+
StringItem* StringItem_newByRef(const char* text, char** ref, bool (*validate)(const char* text)) {
357+
StringItem* this = AllocThis(StringItem);
358+
this->super.text = xStrdup(text);
359+
this->ref = ref;
360+
this->editing = false;
361+
this->valid = true;
362+
this->validate = validate;
363+
LineEditor_init(&this->editor);
364+
if (ref && *ref)
365+
LineEditor_setText(&this->editor, *ref);
366+
return this;
367+
}
368+
369+
void StringItem_startEditing(StringItem* this) {
370+
this->editing = true;
371+
LineEditor_setText(&this->editor, (this->ref && *this->ref) ? *this->ref : "");
372+
}
373+
374+
void StringItem_cancelEditing(StringItem* this) {
375+
this->editing = false;
376+
LineEditor_setText(&this->editor, (this->ref && *this->ref) ? *this->ref : "");
377+
}
378+
379+
bool StringItem_applyEditing(StringItem* this) {
380+
this->editing = false;
381+
const char* text = this->editor.buffer;
382+
if (this->validate && !this->validate(text)) {
383+
this->valid = false;
384+
return false;
385+
}
386+
this->valid = true;
387+
if (this->ref) {
388+
free(*this->ref);
389+
*this->ref = (*text != '\0') ? xStrdup(text) : NULL;
390+
}
391+
return true;
392+
}

OptionItem.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ in the source distribution for its full text.
99

1010
#include <stdbool.h>
1111

12+
#include "LineEditor.h"
1213
#include "Object.h"
1314

1415
#define NUMBERITEM_EDIT_MAX 10
@@ -17,6 +18,7 @@ enum OptionItemType {
1718
OPTION_ITEM_TEXT,
1819
OPTION_ITEM_CHECK,
1920
OPTION_ITEM_NUMBER,
21+
OPTION_ITEM_STRING,
2022
};
2123

2224
typedef struct OptionItemClass_ {
@@ -62,10 +64,20 @@ typedef struct NumberItem_ {
6264
int savedValue;
6365
} NumberItem;
6466

67+
typedef struct StringItem_ {
68+
OptionItem super;
69+
char** ref;
70+
bool editing;
71+
bool valid;
72+
LineEditor editor;
73+
bool (*validate)(const char* text);
74+
} StringItem;
75+
6576
extern const OptionItemClass OptionItem_class;
6677
extern const OptionItemClass TextItem_class;
6778
extern const OptionItemClass CheckItem_class;
6879
extern const OptionItemClass NumberItem_class;
80+
extern const OptionItemClass StringItem_class;
6981

7082
TextItem* TextItem_new(const char* text);
7183

@@ -88,4 +100,9 @@ bool NumberItem_applyEditing(NumberItem* this);
88100
bool NumberItem_addChar(NumberItem* this, char c);
89101
void NumberItem_deleteChar(NumberItem* this);
90102

103+
StringItem* StringItem_newByRef(const char* text, char** ref, bool (*validate)(const char* text));
104+
void StringItem_startEditing(StringItem* this);
105+
void StringItem_cancelEditing(StringItem* this);
106+
bool StringItem_applyEditing(StringItem* this);
107+
91108
#endif

Process.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,18 @@ static inline char* stpcpyWithNewlineConversion(char* dstStr, const char* srcStr
174174
return dstStr;
175175
}
176176

177-
static size_t findDistPrefixLength(const char* str) {
177+
static size_t findDistPrefixLength(const char* str, const Settings* settings) {
178178
static const char* const builtinPrefixes =
179179
"/bin/:/sbin/:/lib/:/lib32/:/lib64/:/libx32/:"
180180
"/usr/bin/:/usr/sbin/:/usr/lib/:/usr/lib32/:/usr/lib64/:/usr/libx32/:"
181181
"/usr/libexec/:/usr/local/bin/:/usr/local/lib/:/usr/local/sbin/:"
182182
"/nix/store/:/run/current-system/";
183183

184-
const char* token = builtinPrefixes;
184+
const char* list = (settings->distPathPrefixes && settings->distPathPrefixes[0] != '\0')
185+
? settings->distPathPrefixes
186+
: builtinPrefixes;
187+
188+
const char* token = list;
185189
while (*token) {
186190
const char* end = String_strchrnul(token, ':');
187191
size_t len = end - token;
@@ -274,7 +278,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
274278

275279
#define CHECK_AND_MARK_DIST_PATH_PREFIXES(str_) \
276280
do { \
277-
size_t _plen = findDistPrefixLength(str_); \
281+
size_t _plen = findDistPrefixLength(str_, settings); \
278282
if (_plen > 0) { \
279283
WRITE_HIGHLIGHT(0, _plen, CRT_colors[PROCESS_SHADOW], \
280284
CMDLINE_HIGHLIGHT_FLAG_PREFIXDIR); \

Settings.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static void Settings_deleteScreens(Settings* this) {
5151
void Settings_delete(Settings* this) {
5252
free(this->filename);
5353
free(this->initialFilename);
54+
free(this->distPathPrefixes);
5455
Settings_deleteColumns(this);
5556
Settings_deleteScreens(this);
5657
free(this);
@@ -440,6 +441,8 @@ static bool Settings_read(Settings* this, const char* fileName, const Machine* h
440441
this->highlightDeletedExe = atoi(option[1]);
441442
} else if (String_eq(option[0], "shadow_distribution_path_prefix")) {
442443
this->shadowDistPathPrefix = atoi(option[1]);
444+
} else if (String_eq(option[0], "dist_path_prefixes")) {
445+
free_and_xStrdup(&this->distPathPrefixes, option[1]);
443446
} else if (String_eq(option[0], "highlight_megabytes")) {
444447
this->highlightMegabytes = atoi(option[1]);
445448
} else if (String_eq(option[0], "highlight_threads")) {
@@ -696,6 +699,8 @@ int Settings_write(const Settings* this, bool onCrash) {
696699
printSettingInteger("highlight_base_name", this->highlightBaseName);
697700
printSettingInteger("highlight_deleted_exe", this->highlightDeletedExe);
698701
printSettingInteger("shadow_distribution_path_prefix", this->shadowDistPathPrefix);
702+
if (this->distPathPrefixes && this->distPathPrefixes[0] != '\0')
703+
printSettingString("dist_path_prefixes", this->distPathPrefixes);
699704
printSettingInteger("highlight_megabytes", this->highlightMegabytes);
700705
printSettingInteger("highlight_threads", this->highlightThreads);
701706
printSettingInteger("highlight_changes", this->highlightChanges);

Settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct ScreenSettings_ {
5757
typedef struct Settings_ {
5858
char* filename;
5959
char* initialFilename;
60+
char* distPathPrefixes;
6061
bool writeConfig; /* whether to write the current settings on exit */
6162
int config_version;
6263
HeaderLayout hLayout;

0 commit comments

Comments
 (0)