📄 rc.c
字号:
/* * *rc file parser * Copyright * (C) 1992 Joseph H. Allen; * * This file is part of JOE (Joe's Own Editor) */#include "types.h"/* Commands which just type in variable values */int ucharset(BW *bw){ unsigned char *s; W *w=bw->parent->main; s=((BW *)w->object)->o.charmap->name; if (!s || !*s) return -1; while (*s) if (utypebw(bw,*s++)) return -1; return 0;}int ulanguage(BW *bw){ unsigned char *s; W *w=bw->parent->main; s=((BW *)w->object)->o.language; if (!s || !*s) return -1; while (*s) if (utypebw(bw,*s++)) return -1; return 0;}#define OPT_BUF_SIZE 300static struct context { struct context *next; unsigned char *name; KMAP *kmap;} *contexts = NULL; /* List of named contexts *//* Find a context of a given name- if not found, one with an empty kmap * is created. */KMAP *kmap_getcontext(unsigned char *name){ struct context *c; for (c = contexts; c; c = c->next) if (!zcmp(c->name, name)) return c->kmap; c = (struct context *) joe_malloc(sizeof(struct context)); c->next = contexts; c->name = zdup(name); contexts = c; return c->kmap = mkkmap();}/* JM - ngetcontext(name) - like getcontext, but return NULL if it * doesn't exist, instead of creating a new one. */KMAP *ngetcontext(unsigned char *name){ struct context *c; for(c=contexts;c;c=c->next) if(!zcmp(c->name,name)) return c->kmap; return 0;}/* Validate joerc file */int validate_rc(){ KMAP *k = ngetcontext(USTR "main"); int x; /* Make sure main exists */ if (!k) return -1; /* Make sure there is at least one key binding */ for (x = 0; x != KEYS; ++x) if (k->keys[x].value.bind) return 0; return -1;}unsigned char **get_keymap_list(){ unsigned char **lst = 0; struct context *c; for (c=contexts; c; c=c->next) lst = vaadd(lst, vsncpy(NULL,0,sz(c->name))); return lst;}OPTIONS *options = NULL;/* Set to use ~/.joe_state file */int joe_state;/* Default options for prompt windows */OPTIONS pdefault = { NULL, /* *next */ NULL, /* *name_regex */ NULL, /* *contents_regex */ 0, /* overtype */ 0, /* lmargin */ 76, /* rmargin */ 0, /* autoindent */ 0, /* wordwrap */ 8, /* tab */ ' ', /* indent char */ 1, /* indent step */ NULL, /* *context */ NULL, /* *lmsg */ NULL, /* *rmsg */ 0, /* line numbers */ 0, /* read only */ 0, /* french spacing */ 0, /* spaces */#ifdef __MSDOS__ 1, /* crlf */#else 0, /* crlf */#endif 0, /* Highlight */ NULL, /* Syntax name */ NULL, /* Syntax */ NULL, /* Name of character set */ NULL, /* Character set */ NULL, /* Language */ 0, /* Smart home key */ 0, /* Goto indent first */ 0, /* Smart backspace key */ 0, /* Purify indentation */ 0, /* Picture mode */ 0, /* single_quoted */ 0, /* c_comment */ 0, /* cpp_comment */ 0, /* pound_comment */ 0, /* vhdl_comment */ 0, /* semi_comment */ 0, /* hex */ NULL, /* text_delimiters */ NULL, /* Characters which can indent paragraphs */ NULL, /* macro to execute for new files */ NULL, /* macro to execute for existing files */ NULL, /* macro to execute before saving new files */ NULL, /* macro to execute before saving existing files */ NULL /* macro to execute on first change */};/* Default options for file windows */OPTIONS fdefault = { NULL, /* *next */ NULL, /* *name_regex */ NULL, /* *contents_regex */ 0, /* overtype */ 0, /* lmargin */ 76, /* rmargin */ 0, /* autoindent */ 0, /* wordwrap */ 8, /* tab */ ' ', /* indent char */ 1, /* indent step */ USTR "main", /* *context */ USTR "\\i%n %m %M", /* *lmsg */ USTR " %S Ctrl-K H for help", /* *rmsg */ 0, /* line numbers */ 0, /* read only */ 0, /* french spacing */ 0, /* spaces */#ifdef __MSDOS__ 1, /* crlf */#else 0, /* crlf */#endif 0, /* Highlight */ NULL, /* Syntax name */ NULL, /* Syntax */ NULL, /* Name of character set */ NULL, /* Character set */ NULL, /* Language */ 0, /* Smart home key */ 0, /* Goto indent first */ 0, /* Smart backspace key */ 0, /* Purity indentation */ 0, /* Picture mode */ 0, /* single_quoted */ 0, /* c_comment */ 0, /* cpp_comment */ 0, /* pound_comment */ 0, /* vhdl_comment */ 0, /* semi_comment */ 0, /* hex */ NULL, /* text_delimiters */ USTR ">;!#%/", /* Characters which can indent paragraphs */ NULL, NULL, NULL, NULL, NULL /* macros (see above) */};/* Update options */void lazy_opts(B *b, OPTIONS *o){ o->syntax = load_dfa(o->syntax_name); if (!o->map_name) { /* Guess encoding if it's not explicitly given */ unsigned char buf[1024]; int len = 1024; if (b->eof->byte < 1024) len = b->eof->byte; brmem(b->bof, buf, len); o->charmap = guess_map(buf, len); o->map_name = zdup(o->charmap->name); } else { o->charmap = find_charmap(o->map_name); } if (!o->charmap) o->charmap = locale_map; if (!o->language) o->language = zdup(locale_lang);}/* Set local options depending on file name and contents */void setopt(B *b, unsigned char *parsed_name){ OPTIONS *o; int x; unsigned char *pieces[26]; for (x = 0; x!=26; ++x) pieces[x] = NULL; for (o = options; o; o = o->next) if (rmatch(o->name_regex, parsed_name)) { if(o->contents_regex) { P *p = pdup(b->bof, USTR "setopt"); if (pmatch(pieces,o->contents_regex,zlen(o->contents_regex),p,0,0)) { prm(p); b->o = *o; lazy_opts(b, &b->o); goto done; } else { prm(p); } } else { b->o = *o; lazy_opts(b, &b->o); goto done; } } b->o = fdefault; lazy_opts(b, &b->o); done: for (x = 0; x!=26; ++x) vsrm(pieces[x]);}/* Table of options and how to set them *//* local means it's in an OPTION structure, global means it's in a global * variable */struct glopts { unsigned char *name; /* Option name */ int type; /* 0 for global option flag 1 for global option numeric 2 for global option string 4 for local option flag 5 for local option numeric 6 for local option string 7 for local option numeric+1, with range checking */ void *set; /* Address of global option */ unsigned char *addr; /* Local options structure member address */ unsigned char *yes; /* Message if option was turned on, or prompt string */ unsigned char *no; /* Message if option was turned off */ unsigned char *menu; /* Menu string */ int ofst; /* Local options structure member offset */ int low; /* Low limit for numeric options */ int high; /* High limit for numeric options */} glopts[] = { {USTR "overwrite",4, NULL, (unsigned char *) &fdefault.overtype, USTR _("Overtype mode"), USTR _("Insert mode"), USTR _("T Overtype ") }, {USTR "hex",4, NULL, (unsigned char *) &fdefault.hex, USTR _("Hex edit mode"), USTR _("Text edit mode"), USTR _(" Hex edit mode ") }, {USTR "autoindent", 4, NULL, (unsigned char *) &fdefault.autoindent, USTR _("Autoindent enabled"), USTR _("Autoindent disabled"), USTR _("I Autoindent ") }, {USTR "wordwrap", 4, NULL, (unsigned char *) &fdefault.wordwrap, USTR _("Wordwrap enabled"), USTR _("Wordwrap disabled"), USTR _("W Word wrap ") }, {USTR "tab", 5, NULL, (unsigned char *) &fdefault.tab, USTR _("Tab width (%d): "), 0, USTR _("D Tab width "), 0, 1, 64 }, {USTR "lmargin", 7, NULL, (unsigned char *) &fdefault.lmargin, USTR _("Left margin (%d): "), 0, USTR _("L Left margin "), 0, 1, 63 }, {USTR "rmargin", 7, NULL, (unsigned char *) &fdefault.rmargin, USTR _("Right margin (%d): "), 0, USTR _("R Right margin "), 0, 7, 255 }, {USTR "restore", 0, &restore_file_pos, NULL, USTR _("Restore cursor position when files loaded"), USTR _("Don't restore cursor when files loaded"), USTR _(" Restore cursor ") }, {USTR "square", 0, &square, NULL, USTR _("Rectangle mode"), USTR _("Text-stream mode"), USTR _("X Rectangle mode ") }, {USTR "icase", 0, &icase, NULL, USTR _("Search ignores case by default"), USTR _("Case sensitive search by default"), USTR _(" Case insensitivity ") }, {USTR "wrap", 0, &wrap, NULL, USTR _("Search wraps"), USTR _("Search doesn't wrap"), USTR _(" Search wraps ") }, {USTR "menu_explorer", 0, &menu_explorer, NULL, USTR _("Menu explorer mode"), USTR _("Simple completion mode"), USTR _(" Menu explorer ") }, {USTR "menu_above", 0, &menu_above, NULL, USTR _("Menu above prompt"), USTR _("Menu below prompt"), USTR _(" Menu position ") }, {USTR "search_prompting", 0, &pico, NULL, USTR _("Search prompting on"), USTR _("Search prompting off"), USTR _(" Search prompting ") }, {USTR "menu_jump", 0, &menu_jump, NULL, USTR _("Jump into menu is on"), USTR _("Jump into menu is off"), USTR _(" Jump into menu ") }, {USTR "autoswap", 0, &autoswap, NULL, USTR _("Autoswap ^KB and ^KK"), USTR _("Autoswap off "), USTR _(" Autoswap mode ") }, {USTR "indentc", 5, NULL, (unsigned char *) &fdefault.indentc, USTR _("Indent char %d (SPACE=32, TAB=9, ^C to abort): "), 0, USTR _(" Indent char "), 0, 0, 255 }, {USTR "istep", 5, NULL, (unsigned char *) &fdefault.istep, USTR _("Indent step %d (^C to abort): "), 0, USTR _(" Indent step "), 0, 1, 64 }, {USTR "french", 4, NULL, (unsigned char *) &fdefault.french, USTR _("One space after periods for paragraph reformat"), USTR _("Two spaces after periods for paragraph reformat"), USTR _(" French spacing ") }, {USTR "highlight", 4, NULL, (unsigned char *) &fdefault.highlight, USTR _("Highlighting enabled"), USTR _("Highlighting disabled"), USTR _("H Highlighting ") }, {USTR "spaces", 4, NULL, (unsigned char *) &fdefault.spaces, USTR _("Inserting spaces when tab key is hit"), USTR _("Inserting tabs when tab key is hit"), USTR _(" No tabs ") }, {USTR "mid", 0, &mid, NULL, USTR _("Cursor will be recentered on scrolls"), USTR _("Cursor will not be recentered on scroll"), USTR _("C Center on scroll ") }, {USTR "guess_crlf",0, &guesscrlf, NULL, USTR _("Automatically detect MS-DOS files"), USTR _("Do not automatically detect MS-DOS files"), USTR _(" Auto detect CR-LF ") }, {USTR "guess_indent",0, &guessindent, NULL, USTR _("Automatically detect indentation"), USTR _("Do not automatically detect indentation"), USTR _(" Guess indent ") }, {USTR "guess_non_utf8",0, &guess_non_utf8, NULL, USTR _("Automatically detect non-UTF-8 in UTF-8 locale"), USTR _("Do not automatically detect non-UTF-8"), USTR _(" Guess non-UTF-8 ") }, {USTR "guess_utf8",0, &guess_utf8, NULL, USTR _("Automatically detect UTF-8 in non-UTF-8 locale"), USTR _("Do not automatically detect UTF-8"), USTR _(" Guess UTF-8 ") }, {USTR "transpose",0, &transpose, NULL, USTR _("Menu is transposed"), USTR _("Menus are not transposed"), USTR _(" Transpose menus ") }, {USTR "crlf", 4, NULL, (unsigned char *) &fdefault.crlf, USTR _("CR-LF is line terminator"), USTR _("LF is line terminator"), USTR _("Z CR-LF (MS-DOS) ") }, {USTR "linums", 4, NULL, (unsigned char *) &fdefault.linums, USTR _("Line numbers enabled"), USTR _("Line numbers disabled"), USTR _("N Line numbers ") }, {USTR "marking", 0, &marking, NULL, USTR _("Anchored block marking on"), USTR _("Anchored block marking off"), USTR _(" Marking ") }, {USTR "asis", 0, &dspasis, NULL, USTR _("Characters above 127 shown as-is"), USTR _("Characters above 127 shown in inverse"), USTR _(" Meta chars as-is ") }, {USTR "force", 0, &force, NULL, USTR _("Last line forced to have NL when file saved"), USTR _("Last line not forced to have NL"), USTR _(" Force last NL ") }, {USTR "joe_state",0, &joe_state, NULL, USTR _("~/.joe_state file will be updated"), USTR _("~/.joe_state file will not be updated"), USTR _(" Joe_state file ") }, {USTR "nobackups", 0, &nobackups, NULL, USTR _("Backup files will not be made"), USTR _("Backup files will be made"), USTR _(" Disable backups ") }, {USTR "nolocks", 0, &nolocks, NULL, USTR _("Files will not be locked"), USTR _("Files will be locked"), USTR _(" Disable locks ") }, {USTR "nomodcheck", 0, &nomodcheck, NULL, USTR _("No file modification time check"), USTR _("File modification time checking enabled"), USTR _(" Disable mtime check ") }, {USTR "nocurdir", 0, &nocurdir, NULL, USTR _("No current dir"), USTR _("Current dir enabled"), USTR _(" Disable current dir ") }, {USTR "break_links", 0, &break_links, NULL, USTR _("Hardlinks will be broken"), USTR _("Hardlinks not broken"), USTR _(" Break hard links ") }, {USTR "lightoff", 0, &lightoff, NULL, USTR _("Highlighting turned off after block operations"), USTR _("Highlighting not turned off after block operations"), USTR _(" Auto unmark ") }, {USTR "exask", 0, &exask, NULL, USTR _("Prompt for filename in save & exit command"), USTR _("Don't prompt for filename in save & exit command"), USTR _(" Exit ask ") }, {USTR "beep", 0, &joe_beep, NULL, USTR _("Warning bell enabled"), USTR _("Warning bell disabled"), USTR _("B Beeps ") }, {USTR "nosta", 0, &staen, NULL, USTR _("Top-most status line disabled"), USTR _("Top-most status line enabled"), USTR _(" Disable status line ") }, {USTR "keepup", 0, &keepup, NULL, USTR _("Status line updated constantly"), USTR _("Status line updated once/sec"), USTR _(" Fast status line ") }, {USTR "pg", 1, &pgamnt, NULL, USTR _("Lines to keep for PgUp/PgDn or -1 for 1/2 window (%d): "), 0, USTR _(" No. PgUp/PgDn lines "), 0, -1, 64 }, {USTR "undo_keep", 1, &undo_keep, NULL, USTR _("No. undo records to keep, or (0 for infinite): "), 0, USTR _(" No. undo records "), 0, -1, 64 }, {USTR "csmode", 0, &csmode, NULL, USTR _("Start search after a search repeats previous search"), USTR _("Start search always starts a new search"), USTR _(" Continued search ") }, {USTR "rdonly", 4, NULL, (unsigned char *) &fdefault.readonly, USTR _("Read only"), USTR _("Full editing"), USTR _("O Read only ") }, {USTR "smarthome", 4, NULL, (unsigned char *) &fdefault.smarthome, USTR _("Smart home key enabled"), USTR _("Smart home key disabled"), USTR _(" Smart home key ") }, {USTR "indentfirst", 4, NULL, (unsigned char *) &fdefault.indentfirst, USTR _("Smart home goes to indentation first"), USTR _("Smart home goes home first"), USTR _(" To indent first ") }, {USTR "smartbacks", 4, NULL, (unsigned char *) &fdefault.smartbacks, USTR _("Smart backspace key enabled"), USTR _("Smart backspace key disabled"), USTR _(" Smart backspace ") }, {USTR "purify", 4, NULL, (unsigned char *) &fdefault.purify, USTR _("Indentation clean up enabled"), USTR _("Indentation clean up disabled"), USTR _(" Clean up indents ") }, {USTR "picture", 4, NULL, (unsigned char *) &fdefault.picture, USTR _("Picture drawing mode enabled"), USTR _("Picture drawing mode disabled"), USTR _("P Picture mode ") }, {USTR "backpath", 2, &backpath, NULL, USTR _("Backup files stored in (%s): "), 0, USTR _(" Path to backup files ") }, {USTR "syntax", 9, NULL, NULL, USTR _("Select syntax (^C to abort): "), 0, USTR _("Y Syntax") }, {USTR "encoding",13, NULL, NULL, USTR _("Select file character set (^C to abort): "), 0, USTR _("E Encoding ") }, {USTR "single_quoted", 4, NULL, (unsigned char *) &fdefault.single_quoted, USTR _("Single quoting enabled"), USTR _("Single quoting disabled"), USTR _(" ^G ignores '... ' ") }, {USTR "c_comment", 4, NULL, (unsigned char *) &fdefault.c_comment, USTR _("/* comments enabled"), USTR _("/* comments disabled"), USTR _(" ^G ignores /*...*/ ") }, {USTR "cpp_comment", 4, NULL, (unsigned char *) &fdefault.cpp_comment, USTR _("// comments enabled"), USTR _("// comments disabled"), USTR _(" ^G ignores //... ") }, {USTR "pound_comment", 4, NULL, (unsigned char *) &fdefault.pound_comment, USTR _("# comments enabled"), USTR _("# comments disabled"), USTR _(" ^G ignores #... ") }, {USTR "vhdl_comment", 4, NULL, (unsigned char *) &fdefault.vhdl_comment, USTR _("-- comments enabled"), USTR _("-- comments disabled"), USTR _(" ^G ignores --... ") }, {USTR "semi_comment", 4, NULL, (unsigned char *) &fdefault.semi_comment, USTR _("; comments enabled"), USTR _("; comments disabled"), USTR _(" ^G ignores ;... ") }, {USTR "text_delimiters", 6, NULL, (unsigned char *) &fdefault.text_delimiters, USTR _("Text delimiters (%s): "), 0, USTR _(" Text delimiters ") }, {USTR "language", 6, NULL, (unsigned char *) &fdefault.language, USTR _("Language (%s): "), 0, USTR _("V Language ") }, {USTR "cpara", 6, NULL, (unsigned char *) &fdefault.cpara, USTR _("Characters which can indent paragraphs (%s): "), 0, USTR _(" Paragraph indent chars ") }, {USTR "floatmouse", 0, &floatmouse, 0, USTR _("Clicking can move the cursor past end of line"), USTR _("Clicking past end of line moves cursor to the end"), USTR _(" Click past end ") }, {USTR "rtbutton", 0, &rtbutton, 0, USTR _("Mouse action is done with the right button"), USTR _("Mouse action is done with the left button"), USTR _(" Right button ") }, {USTR "nonotice", 0, &nonotice, NULL, 0, 0, 0 }, {USTR "help_is_utf8", 0, &help_is_utf8, NULL, 0, 0, 0 }, {USTR "noxon", 0, &noxon, NULL, 0, 0, 0 }, {USTR "orphan", 0, &orphan, NULL, 0, 0, 0 }, {USTR "help", 0, &help, NULL, 0, 0, 0 }, {USTR "dopadding", 0, &dopadding, NULL, 0, 0, 0 }, {USTR "lines", 1, &lines, NULL, 0, 0, 0, 0, 2, 1024 }, {USTR "baud", 1, &Baud, NULL, 0, 0, 0, 0, 50, 32767 }, {USTR "columns", 1, &columns, NULL, 0, 0, 0, 0, 2, 1024 }, {USTR "skiptop", 1, &skiptop, NULL, 0, 0, 0, 0, 0, 64 }, {USTR "notite", 0, ¬ite, NULL, 0, 0, 0 }, {USTR "mouse", 0, &xmouse, NULL, 0, 0, 0 }, {USTR "usetabs", 0, &usetabs, NULL, 0, 0, 0 }, {USTR "assume_color", 0, &assume_color, NULL, 0, 0, 0 }, {USTR "assume_256color", 0, &assume_256color, NULL, 0, 0, 0 }, {USTR "joexterm", 0, &joexterm, NULL, 0, 0, 0 }, { NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 0 }};/* Initialize .ofsts above. Is this really necessary? */int isiz = 0;HASH *opt_tab;static void izopts(void){ int x; opt_tab = htmk(128); for (x = 0; glopts[x].name; ++x) { htadd(opt_tab, glopts[x].name, glopts + x); switch (glopts[x].type) { case 4: case 5: case 6: case 7: case 8: glopts[x].ofst = glopts[x].addr - (unsigned char *) &fdefault; } } isiz = 1;}/* Set a global or local option: * 's' is option name * 'arg' is a possible argument string (taken only if option has an arg) * 'options' points to options structure to modify (can be NULL). * 'set'==0: set only in 'options' if it's given. * 'set'!=0: set global variable option. * return value: no. of fields taken (1 or 2), or 0 if option not found. * * So this function is used both to set options, and to parse over options * without setting them. * * These combinations are used: * * glopt(name,arg,NULL,1): set global variable option * glopt(name,arg,NULL,0): parse over option * glopt(name,arg,options,0): set file local option * glopt(name,arg,&fdefault,1): set default file options * glopt(name,arg,options,1): set file local option */int glopt(unsigned char *s, unsigned char *arg, OPTIONS *options, int set){ int val; int ret = 0; int st = 1; /* 1 to set option, 0 to clear it */ struct glopts *opt; /* Initialize offsets */ if (!isiz) izopts(); /* Clear instead of set? */ if (s[0] == '-') { st = 0; ++s; } opt = htfind(opt_tab, s); if (opt) { switch (opt->type) { case 0: /* Global variable flag option */ if (set) *(int *)opt->set = st; break; case 1: /* Global variable integer option */ if (set && arg) { sscanf((char *)arg, "%d", &val); if (val >= opt->low && val <= opt->high) *(int *)opt->set = val; } break; case 2: /* Global variable string option */ if (set) { if (arg) *(unsigned char **) opt->set = zdup(arg); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -