📄 command.vtc
字号:
cmds ?:= make_tree(.stricmp);macros ?:= make_tree(.stricmp);Tcmd ?:= new_assoc(); // List if a pattern or empty string, print otherwisefunc print_or_list(s, pf, lf) { (*((*s && !s[strcspn(s, "*?")]) ? pf : lf))(s);}func efind(fptr, thing, s) { return (*fptr)(s) ? : (printf("Can't find %s %s\n", thing, s), abort());}func add_cmd(name, args, fptr, fmt) [cmd] { cmd = alloc(4, Tcmd); cmd->name = name; cmd->args = args; cmd->fptr = fptr; cmd->fmt = fmt; insert_tree(cmds, name, cmd);}func find_cmd(name) --> find_tree(cmds, name)func Find_cmd(name) --> efind(.find_cmd, "command", name)func help(s) { traverse_tree(cmds, .print_cmd_fmt, s); }func print_cmd_fmt(n, c, s) { if (!*s || smatch(s, n)) output(c->fmt + "\n"); }func add_macro(name, cmd) { insert_tree(macros, name, cmd); }func del_macro(pattern) { del_smatches(macros, pattern); }func find_macro(name) --> find_tree(macros, name)func Find_macro(name) --> efind(.find_macro, "macro", name)func macro_cmd_str(c) --> type(c) == T_FPTR ? func_name(c) : cfunc run_macro(cmd, line, args) { if (type(cmd) == T_FPTR) (*cmd)(line, args); else process_cmdline(cmd, line, args);}func list_macros(s) { traverse_tree(macros, .list_macro, s); }func list_macro(n, c, s) { if (!*s || smatch(s, n)) printf("%10s %s\n", n, macro_cmd_str(c));}func print_macro(name) [cmd] { cmd = Find_macro(name); printf("Name: %s\n", name); printf("Command: %s\n", macro_cmd_str(cmd));}func save_macros(fp) { traverse_tree(macros, .save_macros_internal, fp); }func save_macros_internal(name, m, fp) { fprintf(fp, "add_macro(%s);\n", arglist(name, m));}func get_arg_list(line) --> explo(line, " ")func std_termread(line) { process_cmdline(line, NULL, NULL, 1);}reserved_list ?:= table("def", "trig", "hilite", "gag", "repeat");func should_not_be_subbed(line) [p] { if (*line != '/' || line[1] == '/') return 1; for (p = reserved_list; *p && strcmp(line + 1, *p, strlen(*p)); p++); return *p;}func process_cmdline(line / full, args, iskbd) [p, buf, tmp, i] { if (!args && should_not_be_subbed(line)) { handle_line(line, iskbd); return; } if (args) *args = full; buf = ""; for (p = strchr(line, '%'); p; p = strchr(line = p + 1, '%')) { strcat(buf, line, p - line); if (*++p == '%') strcat(buf, "%"); else if (args && *p == '*') strcat(buf, full); else if (args && isdigit(*p)) strcat(buf, args[*p - '0'] ? : ""); else if (args && *p == '+' && isdigit(p[1])) { for (i = *++p - '0'; args[i]; i++) { strcat(buf, args[i]); strcat(buf, args[i + 1] ? " " : ""); } } else if (args && *p == '"' && p[1] == '*') { strcat(buf, stringconst(full)); p++; } else if (args && *p == '"' && isdigit(p[1])) strcat(buf, stringconst(args[*++p - '0'])); else if (args && *p == '"' && p[1] == '+' && isdigit(p[2])) { tmp = ""; for (i = p[2] - '0'; args[i]; i++) { strcat(buf, args[i]); strcat(buf, args[i + 1] ? " " : ""); } strcat(buf, stringconst(tmp)); p += 2; } else if (*p == ';' || *p == '\\') { handle_line(buf, iskbd); process_cmdline(p + 1, full, args); return; } else if (*p == '{') { strcat(buf, get_histline(atoi(p + 1)) ? : ""); p = strchr(p, '}') ? : ""; } else buf[strlen(buf)] = *--p; } strcat(buf, line); handle_line(buf, iskbd);}func handle_line(line / iskbd) { if (*line == '/' && line[1] != '/') do_cmd(line + 1); else if (*line == '\\' && line[1] != '\\') parse(line + 1); else dispatch(strchr("/\\", *line) ? line + 1 : line, NULL, iskbd);}func do_cmd(line) [astr, name, cmd, args, cargs] { if (strchr(":\"", *line)) return dispatch(line); if (!*line) return; astr = strchr(line, ' ') ? : line + strlen(line); strcpy(name = "", line, astr - line); for (; *astr == ' '; astr++); cmd = find_cmd(name); if (!cmd) { cmd = find_macro(name); if (cmd) run_macro(cmd, astr, get_arg_list(astr)); else printf("Not a command or macro: %s\n", name); return; } cargs = cmd->args; if (cargs == -1) return (*cmd->fptr)(astr); args = get_arg_list(astr); if (cargs != args[0]) return printf("Too %s arguments (%d expected) to %s\n", cargs > args[0] ? "few" : "many", cargs, cmd->name); callv(cmd->fptr, cargs, args + 1);}func Def(s) [n, name] { n = strcspn(s, "= ") ? : strlen(s); strcpy(name = "", s, n); s = skipspaces(s + n); if (*s == '=') s = skipspaces(s + 1); add_macro(name, s);}func Undef(s) { del_macro(s); }func List_defs(s) { print_or_list(s, .print_macro, .list_macros); }func Help(s) { help(s); }add_cmd("def", -1, .Def, "/def <name> <body>");add_cmd("undef", 1, .Undef, "/undef <name>");add_cmd("list_defs", -1, .List_defs, "/list_defs [<name>]");add_cmd("help", -1, .Help, "/help");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -