📄 core.c
字号:
static intl_xdialog(LS){ struct terminal *term = lua_ses->tab->term; struct dialog *dlg; struct lua_xdialog_data *data; int nargs, nfields, nitems; int i = 0; nargs = lua_gettop(S); nfields = nargs - 1; nitems = nfields + 2; if ((nfields < 1) || (nfields > XDIALOG_MAX_FIELDS)) goto lua_error; for (i = 1; i < nargs; i++) if (!lua_isstring(S, i)) goto lua_error; if (!lua_isfunction(S, nargs)) goto lua_error; dlg = calloc_dialog(nitems, sizeof(*data)); if (!dlg) return 0; data = (struct lua_xdialog_data *) get_dialog_offset(dlg, nitems); data->state = S; data->nfields = nfields; for (i = 0; i < nfields; i++) safe_strncpy(data->fields[i], (unsigned char *) lua_tostring(S, i+1), MAX_STR_LEN-1); lua_pushvalue(S, nargs); data->func_ref = lua_ref(S, 1); dlg->title = _("User dialog", term); dlg->layouter = generic_dialog_layouter; dlg->layout.maximize_width = 1; for (i = 0; i < nfields; i++) add_dlg_field(dlg, _("Name", term), 0, 0, NULL, MAX_STR_LEN, data->fields[i], NULL); add_dlg_ok_button(dlg, _("~OK", term), B_ENTER, xdialog_run_lua, data); add_dlg_button(dlg, _("~Cancel", term), B_ESC, cancel_dialog, NULL); add_dlg_end(dlg, nitems); do_dialog(term, dlg, getml(dlg, NULL)); lua_pushnumber(S, 1); return 1;lua_error: lua_pushnil(S); return 1;}/* End xdialog bit. *//* Set/get option */static intl_set_option(LS){ int nargs; struct option *opt, *current; const char *name; nargs = lua_gettop(S); if (nargs != 2) goto lua_error; /* Get option record */ name = lua_tostring(S, 1); opt = get_opt_rec(config_options, (unsigned char *) name); if (opt == NULL) goto lua_error; /* Set option */ switch (opt->type) { case OPT_BOOL: case OPT_INT: case OPT_LONG: { int value; value = lua_tonumber(S, 2); option_types[opt->type].set(opt, (unsigned char *) (&value)); break; } case OPT_STRING: case OPT_CODEPAGE: case OPT_LANGUAGE: case OPT_COLOR: option_types[opt->type].set(opt, (unsigned char *) lua_tostring(S, 2)); break; default: goto lua_error; } /* Call hook */ current = opt; while (current && (!current->change_hook || !current->change_hook(lua_ses, current, opt))) { if (current->root) current = current->root; else break; } return 1;lua_error: lua_pushnil(S); return 1;}static intl_get_option(LS){ int nargs; struct option *opt; const char *name; /* Get option record */ nargs = lua_gettop(S); if (nargs != 1) goto lua_error; name = lua_tostring(S, 1); opt = get_opt_rec(config_options, (unsigned char *) name); if (opt == NULL) goto lua_error; /* Convert to an appropriate Lua type */ switch (opt->type) { case OPT_BOOL:#ifdef HAVE_LUA5 lua_pushboolean(S, opt->value.number); break;#endif case OPT_INT: case OPT_LONG: lua_pushnumber(S, opt->value.number); break; case OPT_STRING: lua_pushstring(S, opt->value.string); break; case OPT_CODEPAGE: { unsigned char *cp_name; cp_name = get_cp_mime_name(opt->value.number); lua_pushstring(S, cp_name); break; } case OPT_LANGUAGE: { unsigned char *lang;#ifdef ENABLE_NLS lang = language_to_name(current_language);#else lang = "System";#endif lua_pushstring(S, lang); break; } case OPT_COLOR: { color_t color; unsigned char hexcolor[8]; unsigned char *strcolor; color = opt->value.color; strcolor = get_color_string(color, hexcolor); lua_pushstring(S, strcolor); break; } case OPT_COMMAND: default: goto lua_error; } return 1;lua_error: lua_pushnil(S); return 1;}/* End of set/get option *//* Initialisation */static voiddo_hooks_file(LS, unsigned char *prefix, unsigned char *filename){ unsigned char *file = straconcat(prefix, "/", filename, NULL); if (!file) return; /* Test file existence to avoid Lua error reporting (under version 5.x) * Fixes debian bug #231760 ('dbug 231760' using URI rewrite) */ if (file_can_read(file)) { int oldtop = lua_gettop(S); if (lua_dofile(S, file) != 0) sleep(3); /* Let some time to see error messages. */ lua_settop(S, oldtop); } mem_free(file);}static voidinit_lua(struct module *module){ L = lua_open(0); lua_baselibopen(L); lua_mathlibopen(L); lua_strlibopen(L); lua_register(L, LUA_ALERT, l_alert); lua_register(L, "current_url", l_current_url); lua_register(L, "current_link", l_current_link); lua_register(L, "current_title", l_current_title); lua_register(L, "current_document", l_current_document); lua_register(L, "current_document_formatted", l_current_document_formatted); lua_register(L, "enable_systems_functions", l_enable_systems_functions); lua_register(L, "bind_key", l_bind_key); lua_register(L, "edit_bookmark_dialog", l_edit_bookmark_dialog); lua_register(L, "xdialog", l_xdialog); lua_register(L, "set_option", l_set_option); lua_register(L, "get_option", l_get_option); lua_dostring(L, "function set_elinks_home(s) elinks_home = s end"); lua_getglobal(L, "set_elinks_home"); lua_pushstring(L, elinks_home ? elinks_home : (unsigned char *) CONFDIR); lua_call(L, 1, 0); do_hooks_file(L, CONFDIR, LUA_HOOKS_FILENAME); if (elinks_home) do_hooks_file(L, elinks_home, LUA_HOOKS_FILENAME);}static void free_lua_console_history_entries(void);static voidcleanup_lua(struct module *module){ free_lua_console_history_entries(); lua_close(L);}/* Attempt to handle infinite loops by trapping SIGINT. If we get a * SIGINT, we longjump to where prepare_lua was called. finish_lua() * disables the trapping. */static voidhandle_sigint(void *data){ finish_lua(); siglongjmp(errjmp, -1);}intprepare_lua(struct session *ses){ lua_ses = ses; errterm = lua_ses ? lua_ses->tab->term : NULL; /* XXX this uses the wrong term, I think */ install_signal_handler(SIGINT, (void (*)(void *)) handle_sigint, NULL, 1); return sigsetjmp(errjmp, 1);}voidfinish_lua(void){ /* XXX should save previous handler instead of assuming this one */ install_signal_handler(SIGINT, (void (*)(void *)) sig_ctrl_c, errterm, 0);}/* Error reporting. */voidalert_lua_error(unsigned char *msg){ if (errterm) { info_box(errterm, MSGBOX_NO_TEXT_INTL | MSGBOX_FREE_TEXT, N_("Lua Error"), ALIGN_LEFT, stracpy(msg)); return; } usrerror("Lua: %s", msg); sleep(3);}voidalert_lua_error2(unsigned char *msg, unsigned char *msg2){ unsigned char *tmp = stracpy(msg); if (!tmp) return; add_to_strn(&tmp, msg2); alert_lua_error(tmp); mem_free(tmp);}/* The following stuff is to handle the return values of * lua_console_hook and keystroke functions, and also the xdialog * function. It expects two values on top of the stack. */static voidhandle_ret_eval(struct session *ses){ const unsigned char *expr = lua_tostring(L, -1); if (expr) { int oldtop = lua_gettop(L); if (prepare_lua(ses) == 0) { lua_dostring(L, expr); lua_settop(L, oldtop); finish_lua(); } return; } alert_lua_error("bad argument for eval");}static voidhandle_ret_run(struct session *ses){ unsigned char *cmd = (unsigned char *) lua_tostring(L, -1); if (cmd) { exec_on_terminal(ses->tab->term, cmd, "", 1); return; } alert_lua_error("bad argument for run");}static voidhandle_ret_goto_url(struct session *ses){ unsigned char *url = (unsigned char *) lua_tostring(L, -1); if (url) { goto_url_with_hook(ses, url); return; } alert_lua_error("bad argument for goto_url");}static voidhandle_standard_lua_returns(unsigned char *from){ const unsigned char *act = lua_tostring(L, -2); if (act) { if (!strcmp(act, "eval")) handle_ret_eval(lua_ses); else if (!strcmp(act, "run")) handle_ret_run(lua_ses); else if (!strcmp(act, "goto_url")) handle_ret_goto_url(lua_ses); else alert_lua_error2("unrecognised return value from ", from); } else if (!lua_isnil(L, -2)) alert_lua_error2("bad return type from ", from); lua_pop(L, 2);}/* Console stuff. */static INIT_INPUT_HISTORY(lua_console_history);static voidlua_console(struct session *ses, unsigned char *expr){ lua_getglobal(L, "lua_console_hook"); if (lua_isnil(L, -1)) { lua_pop(L, 1); handle_ret_eval(ses); return; } lua_pushstring(L, expr); if (prepare_lua(ses) == 0) { int err = lua_call(L, 1, 2); finish_lua(); if (!err) handle_standard_lua_returns("lua_console_hook"); }}enum evhook_statusdialog_lua_console(va_list ap, void *data){ struct session *ses = va_arg(ap, struct session *); if (get_cmd_opt_bool("anonymous")) return EVENT_HOOK_STATUS_NEXT; input_dialog(ses->tab->term, NULL, N_("Lua Console"), N_("Enter expression"), ses, &lua_console_history, MAX_STR_LEN, "", 0, 0, NULL, (void (*)(void *, unsigned char *)) lua_console, NULL); return EVENT_HOOK_STATUS_NEXT;}static voidfree_lua_console_history_entries(void){ free_list(lua_console_history.entries);}enum evhook_statusfree_lua_console_history(va_list ap, void *data){ free_lua_console_history_entries(); return EVENT_HOOK_STATUS_NEXT;}struct module lua_scripting_module = struct_module( /* name: */ "Lua", /* options: */ NULL, /* hooks: */ lua_scripting_hooks, /* submodules: */ NULL, /* data: */ NULL, /* init: */ init_lua, /* done: */ cleanup_lua);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -