commit 8758854a52c5835c27c024b4020cb953152a7f14 from: Omar Polo date: Sun May 20 09:10:32 2018 UTC Added custom prompt commit - 6da988820b4410d7a4a735cd78a33135d806942f commit + 8758854a52c5835c27c024b4020cb953152a7f14 blob - 7f09237cd9c8f5fdde0beafb622649617859876e blob + 47f25307e58c9bb40597a65b432f864f93fd59bc --- Xexample +++ Xexample @@ -1,5 +1,6 @@ -MyMenu.font: -misc-tamsyn-medium-r-normal--15-108-100-100-c-80-iso8859-1 +MyMenu.font: fixed MyMenu.layout: horizontal +MyMenu.prompt: "$ " MyMenu.width: 100% MyMenu.height: 30 blob - 8572eb423a8ba658eaf5e7b7b4260727c10626ae blob + 36cff68847fa11f57e6de4a6cb7762c3979a2ada --- mymenu.1 +++ mymenu.1 @@ -27,16 +27,18 @@ The layout of the menu. The possible values are "horiz "vertical", with the default being "horizontal". Every other value than "horizontal" is treated like "vertical", but this is kinda an implementation detail and not something to be relied on, since in the -future other layout could be added as well +future other layout could be added as well. +.It Mymenu.prompt +A string that is rendered before the user input. Default to "$ ". .It MyMenu.width The width of the menu. If a numeric value is given (e.g. 400) is interpreted as pixel, if it ends with a percentage symbol `%' (e.g. 40%) the relative percentage will be computed (relative to the -monitor width) +monitor width). .It MyMenu.height The height of the menu. Like MyMenu.width if a numeric value is given is interpreted as pixel, if it ends with a percentage symbol `%' the -relative percentage will be computed (relative to the monitor height) +relative percentage will be computed (relative to the monitor height). .It MyMenu.x The X coordinate of the topmost left corner of the window. Much like MyMenu.height and MyMenu.width both a pixel dimension and percentage @@ -47,17 +49,17 @@ The Y coordinate of the topmost left corner of the win coordinate, pixel dimension, percentage dimension and the special value "middle" could be supplied. .It MyMenu.prompt.background -The background of the prompt +The background of the prompt. .It MyMenu.prompt.foreground -The text color (foreground) of the prompt +The text color (foreground) of the prompt. .It MyMenu.completion.background -The background of the completions +The background of the completions. .It MyMenu.completion.foreground -The text color of the completions +The text color of the completions. .It MyMenu.completion_highlighted.background -The background of the selected completion +The background of the selected completion. .It MyMenu.completion_highlighted.foreground -The foreground of the selected completion +The foreground of the selected completion. .El .Sh KEYS blob - 75404a9f488ac60c33402ba2faa2076ea7ca4b3b blob + ace8989513debf93c111b8e42f36472347566019 --- mymenu.c +++ mymenu.c @@ -83,6 +83,8 @@ struct rendering { int height; XFontSet *font; bool horizontal_layout; + char *ps1; + int ps1len; }; struct completions { @@ -230,6 +232,39 @@ void popc(char *p, int maxlen) { } } +// If the string is surrounded by quotes (`"`) remove them and replace +// every `\"` in the string with `"` +char *normalize_str(const char *str) { + int len = strlen(str); + if (len == 0) + return nil; + + char *s = calloc(len, sizeof(char)); + check_allocation(s); + int p = 0; + while (*str) { + char c = *str; + if (*str == '\\') { + if (*(str + 1)) { + s[p] = *(str + 1); + p++; + str += 2; // skip this and the next char + continue; + } else { + break; + } + } + if (c == '"') { + str++; // skip only this char + continue; + } + s[p] = c; + p++; + str++; + } + return s; +} + // read an arbitrary long line from stdin and return a pointer to it // TODO: resize the allocated memory to exactly fit the string once // read? @@ -298,7 +333,10 @@ void draw_horizontally(struct rendering *r, char *text /* int start_at = XTextWidth(r->font, " ", 1) * prompt_width + padding; */ XRectangle rect; - int start_at = XmbTextExtents(*r->font, " ", 1, nil, &rect); + int ps1xlen = XmbTextExtents(*r->font, r->ps1, r->ps1len, nil, &rect); + int start_at = ps1xlen; + + start_at += XmbTextExtents(*r->font, " ", 1, nil, &rect); start_at = start_at * prompt_width + padding; int texty = (rect.height + r->height) >>1; @@ -309,7 +347,8 @@ void draw_horizontally(struct rendering *r, char *text if (text_len > prompt_width) text = text + (text_len - prompt_width); /* XDrawString(r->d, r->w, r->prompt, padding, texty, text, MIN(text_len, prompt_width)); */ - Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding, texty, text, MIN(text_len, prompt_width)); + Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding, texty, r->ps1, r->ps1len); + Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding + ps1xlen, texty, text, MIN(text_len, prompt_width)); XFillRectangle(r->d, r->w, r->completion_bg, start_at, 0, r->width, r->height); @@ -356,7 +395,9 @@ void draw_vertically(struct rendering *r, char *text, XFillRectangle(r->d, r->w, r->completion_bg, 0, 0, r->width, r->height); XFillRectangle(r->d, r->w, r->prompt_bg, 0, 0, r->width, start_at); - Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding, padding*2, text, strlen(text)); + int ps1xlen = XmbTextExtents(*r->font, r->ps1, r->ps1len, nil, nil); + Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding, padding*2, r->ps1, r->ps1len); + Xutf8DrawString(r->d, r->w, *r->font, r->prompt, padding + ps1xlen, padding*2, text, strlen(text)); while (cs != nil) { GC g = cs->selected ? r->completion_highlighted : r->completion; @@ -525,6 +566,9 @@ int main() { int x = 0; int y = 0; + char *ps1 = strdup("$ "); + check_allocation(ps1); + char *fontname = strdup("fixed"); check_allocation(fontname); @@ -605,6 +649,12 @@ int main() { else fprintf(stderr, "no layout defined, using horizontal\n"); + if (XrmGetResource(xdb, "MyMenu.prompt", "*", datatype, &value) == true) { + free(ps1); + ps1 = normalize_str(value.addr); + } else + fprintf(stderr, "no prompt defined, using \"%s\" as default\n", ps1); + if (XrmGetResource(xdb, "MyMenu.width", "*", datatype, &value) == true) width = parse_integer(value.addr, width, d_width); else @@ -743,7 +793,9 @@ int main() { .width = width, .height = height, .font = &font, - .horizontal_layout = horizontal_layout + .horizontal_layout = horizontal_layout, + .ps1 = ps1, + .ps1len = strlen(ps1) }; // load the colors in our GCs @@ -924,12 +976,13 @@ int main() { free(lines[i]); } + free(ps1); free(fontname); free(text); free(lines); compl_delete(cs); - /* XDestroyWindow(d, w); */ + XDestroyWindow(d, w); XCloseDisplay(d); return status == OK ? 0 : 1;