From: Michael D. Lowis Date: Fri, 8 Sep 2017 17:12:55 +0000 (-0400) Subject: Sketched out config option handling X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=f0ecc8edd80bdbfdafcc78216dc3afc559bb02d7;p=archive%2Ftide-ocaml.git Sketched out config option handling --- diff --git a/Makefile b/Makefile index 22c6baa..e0a96cb 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ BINS = edit LIBOBJS = \ lib/tide.$(OBJEXT) \ lib/x11.$(OBJEXT) \ + lib/cfg.$(OBJEXT) \ lib/x11_prims.o \ lib/utf8.o diff --git a/lib/cfg.ml b/lib/cfg.ml new file mode 100644 index 0000000..ea6b566 --- /dev/null +++ b/lib/cfg.ml @@ -0,0 +1,105 @@ +open X11 + +let boolvar name defval = + match (var_get name) with + | Bool v -> v + | _ -> defval + +let intvar name defval = + match (var_get name) with + | Int v -> v + | _ -> defval + +let strvar name defval = + match (var_get name) with + | String v -> v + | _ -> defval + +let clrvar name defval = + match (var_get name) with + | Int v -> ((v lsr 8), (v land 0xFF)) + | _ -> defval + +(* tags region default contents *) +let edit_tags = strvar "tide.ui.tags.edit" + "Quit Save Undo Redo Cut Copy Paste | Find " +let cmd_tags = strvar "tide.ui.font" + "Quit Undo Redo Cut Copy Paste | Send Find " + +(* font settings *) +let font = strvar "tide.ui.tags.edit" + "Liberation Mono:pixelsize=14:antialias=true:autohint=true" +let line_spacing = intvar "tide.ui.line_spacing" 1 + +(* user interface related options *) +let winwidth = intvar "tide.ui.width" 640 +let winheight = intvar "tide.ui.height" 480 +let line_nums = boolvar "tide.ui.line_numbers" true +let syntax_enabled = boolvar "tide.ui.syntax_enabled" true +let ruler_column = intvar "tide.ui.rulercolumn" 80 +let event_timeout = intvar "tide.ui.timeout" 50 + +(* input related options *) +let copy_indent = boolvar "tide.input.copy_indent" true +let trim_on_save = boolvar "tide.input.trim_on_save" true +let expand_tabs = boolvar "tide.input.expand_tabs" true +let tab_width = intvar "tide.input.tab_width" 4 +let scroll_lines = intvar "tide.input.scroll_lines" 4 +let dbl_click_time = intvar "tide.input.click_time" 500 +let max_scan_dist = intvar "tide.input.max_scan_dist" 0 + +module Color = struct + (* color palette *) + let palette = [| + intvar "tide.palette.00" 0xff002b36; + intvar "tide.palette.01" 0xff073642; + intvar "tide.palette.02" 0xff40565d; + intvar "tide.palette.03" 0xff657b83; + intvar "tide.palette.04" 0xff839496; + intvar "tide.palette.05" 0xff93a1a1; + intvar "tide.palette.06" 0xffeee8d5; + intvar "tide.palette.07" 0xfffdf6e3; + intvar "tide.palette.08" 0xffb58900; + intvar "tide.palette.09" 0xffcb4b16; + intvar "tide.palette.10" 0xffdc322f; + intvar "tide.palette.11" 0xffd33682; + intvar "tide.palette.12" 0xff6c71c4; + intvar "tide.palette.13" 0xff268bd2; + intvar "tide.palette.14" 0xff2aa198; + intvar "tide.palette.15" 0xff859900; + |] + + (* UI color index definitions *) + let scroll_nor = clrvar "tide.colors.scroll.normal" (3, 0) + let gutter_nor = clrvar "tide.colors.gutter.normal" (1, 4) + let gutter_sel = clrvar "tide.colors.gutter.selected" (2, 7) + let status_nor = clrvar "tide.colors.status.normal" (0, 5) + let tags_nor = clrvar "tide.colors.tags.normal" (1, 5) + let tags_sel = clrvar "tide.colors.tags.selected" (2, 5) + let tags_csr = intvar "tide.colors.tags.cursor" 7 + let edit_nor = clrvar "tide.colors.edit.normal" (0, 5) + let edit_sel = clrvar "tide.colors.edit.selected" (2, 5) + let edit_csr = intvar "tide.colors.edit.cursor" 7 + let edit_rul = intvar "tide.colors.edit.ruler" 1 + let borders = clrvar "tide.colors.borders" (3, 3) + + (* syntax color definitions *) + module Syntax = struct + let normal = intvar "tide.colors.syntax.normal" 5 + let comment = intvar "tide.colors.syntax.comment" 3 + let constant = intvar "tide.colors.syntax.constant" 14 + let number = intvar "tide.colors.syntax.number" 14 + let boolean = intvar "tide.colors.syntax.boolean" 14 + let float = intvar "tide.colors.syntax.float" 14 + let string = intvar "tide.colors.syntax.string" 14 + let char = intvar "tide.colors.syntax.character" 14 + let preproc = intvar "tide.colors.syntax.preproc" 9 + let typedef = intvar "tide.colors.syntax.typedef" 8 + let keyword = intvar "tide.colors.syntax.keyword" 15 + let statement = intvar "tide.colors.syntax.statement" 10 + let procedure = intvar "tide.colors.syntax.function" 11 + let variable = intvar "tide.colors.syntax.variable" 12 + let special = intvar "tide.colors.syntax.special" 13 + let operator = intvar "tide.colors.syntax.operator" 12 + end +end diff --git a/lib/x11.ml b/lib/x11.ml index 0ca8db8..e07c7a6 100644 --- a/lib/x11.ml +++ b/lib/x11.ml @@ -20,6 +20,13 @@ type xevent = (* rectangle description type *) type xrect = { x: int; y: int; w: int; h: int; c: int; } +(* configuration variable type *) +type xcfgvar = + | Bool of bool + | Int of int + | String of string + | NotSet + external connect : unit -> unit = "x11_connect" @@ -53,10 +60,10 @@ external prop_set : xwin -> xatom -> string -> unit external prop_get : xwin -> xatom -> string = "x11_prop_get" -(* to be implemented +external var_get : string -> xcfgvar + = "x11_var_get" -void x11_draw_rect(int color, int x, int y, int width, int height) -external draw_rect : int -> int -> int -> int -> int -> unit +(* to be implemented external sel_set : xatom -> string -> unit = "x11_sel_set" diff --git a/lib/x11_prims.c b/lib/x11_prims.c index 1b7f7c3..c370849 100644 --- a/lib/x11_prims.c +++ b/lib/x11_prims.c @@ -8,6 +8,7 @@ #include #include #include +#include /* The order of this enum should match the type specified in x11.ml. The variants are divided into two groups, those with args and those without. @@ -65,6 +66,8 @@ static void create_window(int height, int width); static value mkrecord(int tag, int n, ...); static int32_t special_keys(int32_t key); static void xftcolor(XftColor* xc, int c); +static void init_db(void); +static char* strmcat(char* first, ...); static value ev_focus(XEvent*); static value ev_keypress(XEvent*); @@ -94,6 +97,7 @@ static struct { XIC xic; XIM xim; GC gc; + XrmDatabase db; } X = {0}; static value (*EventHandlers[LASTEvent]) (XEvent*) = { @@ -244,6 +248,15 @@ CAMLprim value x11_prop_get(value win, value atom) { CAMLreturn(caml_copy_string(prop)); } +CAMLprim value x11_var_get(value name) { + CAMLparam1(name); + init_db(); + char* type; + XrmValue val; + XrmGetResource(X.db, String_val(name), NULL, &type, &val); + CAMLreturn(mkrecord(0,0)); +} + static char* readprop(Window win, Atom prop) { Atom rtype; unsigned long format = 0, nitems = 0, nleft = 0, nread = 0; @@ -467,3 +480,51 @@ static void xftcolor(XftColor* xc, int c) { xc->color.blue = COLOR((c & 0x000000FF) << 8); XftColorAllocValue(X.display, X.visual, X.colormap, &(xc->color), xc); } + +static void init_db(void) { + static bool loaded = false; + if (loaded) return; + XrmDatabase db; + char *homedir = getenv("HOME"), + *userfile = strmcat(homedir, "/.config/tiderc", 0), + *rootfile = strmcat(homedir, "/.Xdefaults", 0); + XrmInitialize(); + + /* load from xrdb or .Xdefaults */ + if (XResourceManagerString(X.display) != NULL) + db = XrmGetStringDatabase(XResourceManagerString(X.display)); + else + db = XrmGetFileDatabase(rootfile); + XrmMergeDatabases(db, &X.db); + + /* load user settings from ~/.config/tiderc */ + db = XrmGetFileDatabase(userfile); + (void)XrmMergeDatabases(db, &X.db); + + /* cleanup */ + free(userfile); + free(rootfile); + loaded = true; +} + +static char* strmcat(char* first, ...) { + va_list args; + /* calculate the length of the final string */ + size_t len = strlen(first); + va_start(args, first); + for (char* s = NULL; (s = va_arg(args, char*));) + len += strlen(s); + va_end(args); + + /* allocate the final string and copy the args into it */ + char *str = malloc(len+1), *curr = str; + while (first && *first) *(curr++) = *(first++); + va_start(args, first); + for (char* s = NULL; (s = va_arg(args, char*));) + while (s && *s) *(curr++) = *(s++); + va_end(args); + /* null terminate and return */ + *curr = '\0'; + return str; +} +