📄 shell.c
字号:
{ int i; i = (CIdent ("menu.scripts"))->current - N_ITEMS; run_shell_dialog (edit[current_edit]->editor, scripts[i]);}/* this is called from edit_translate_key.c */int get_script_number_from_key (unsigned int state, KeySym keysym){ int i; for (i = 0; i < MAX_NUM_SCRIPTS; i++) { if (!scripts[i]) break; if (keysym < 256) keysym = my_lower_case (keysym); if (scripts[i]->keyboard_state == state && scripts[i]->key == keysym) return i; } return -1;}/* This is called from the editor: see main.c: edit_set_user_command (execute_script); */void execute_script (WEdit * e, int i){ run_shell_dialog (e, scripts[i]);}/* Updates updates the menu when a new shell has been added or removed */void update_script_menu_items (){ int i, n; n = (CIdent ("menu.scripts"))->numlines + 2; for (i = N_ITEMS; i < n; i++) CRemoveMenuItemNumber ("menu.scripts", N_ITEMS); for (n = 0; n < MAX_NUM_SCRIPTS; n++) { if (!scripts[n]) break; CAddMenuItem ("menu.scripts", scripts[n]->menu, scripts[n]->menu_hot_key, script_menu_callback, 0); }}#define NUM_OPTS 14/* Edits a scripts: returns 1 on cancel, 0 on success, -1 on error */int edit_scripts_dialog (Window parent, int x, int y, struct shell_cmd *s){ int i, r = 0; CState state; struct { char *name; char *toolhint; int flag; CWidget *w; } options[] = { { gettext_noop ("Save block on commence"), gettext_noop ("Save the current highlighted text to %b before executing"), SHELL_OPTION_SAVE_BLOCK, 0 }, { gettext_noop ("Save editor file on commence"), gettext_noop ("Save the entire edit buffer to %f before executing"), SHELL_OPTION_SAVE_EDITOR_FILE, 0 }, { gettext_noop ("Prompt for arguments on commence"), gettext_noop ("Prompt the user for a string to be replaced with %a"), SHELL_OPTION_REQUEST_ARGUMENTS, 0 }, { gettext_noop ("Display script's stdout continuously"), gettext_noop ("Dynamically view the scripts output"), SHELL_OPTION_DISPLAY_STDOUT_CONTINUOUS, 0 }, { gettext_noop ("Display script's stderr continuously"), gettext_noop ("Dynamically view the scripts output"), SHELL_OPTION_DISPLAY_STDERR_CONTINUOUS, 0 }, { gettext_noop ("Run in background"), "", SHELL_OPTION_RUN_IN_BACKGROUND, 0 }, { gettext_noop ("Delete block on commence"), gettext_noop ("Use when you want to replace highlighted text"), SHELL_OPTION_DELETE_BLOCK, 0 }, { gettext_noop ("Insert temp file on completion"), gettext_noop ("Types out file %t's contents on completion of the script"), SHELL_OPTION_INSERT_TEMP_FILE, 0 }, { gettext_noop ("Insert block file on completion"), gettext_noop ("Types out file %b's contents on completion of the script"), SHELL_OPTION_INSERT_BLOCK_FILE, 0 }, { gettext_noop ("Insert clip file on completion"), gettext_noop ("Types out file %c's contents on completion of the script"), SHELL_OPTION_INSERT_CLIP_FILE, 0 }, { gettext_noop ("Insert stdout on completion"), gettext_noop ("Types out the script's output"), SHELL_OPTION_INSERT_STDOUT, 0 }, { gettext_noop ("Insert stderr on completion"), gettext_noop ("Types out the script's output"), SHELL_OPTION_INSERT_STDERR, 0 }, { gettext_noop ("Display error file"), gettext_noop ("Displays %e on completion of the script"), SHELL_OPTION_DISPLAY_ERROR_FILE, 0 }, { gettext_noop ("Subs only if error file is empty"), gettext_noop ("Only replace the highlighted text if %e is empty"), SHELL_OPTION_CHECK_ERROR_FILE, 0 } }; int xs, ys, x2, o, yu; char hot[2] = "\0\0"; Window win; CWidget *w; CEvent cw; hot[0] = s->menu_hot_key; CBackupState (&state); CDisable ("*"); win = CDrawHeadedDialog ("shellopt", parent, x, y, " Script Control "); CGetHintPos (&x, &y); yu = y; CDrawText ("shellopt.namet", win, x, y, " Name : "); CGetHintPos (&x2, 0); CDrawTextInput ("shellopt.name", win, x2, y, FONT_MEAN_WIDTH * 27, AUTO_HEIGHT, 39, s->name);/* Toolhint */ CSetToolHint ("shellopt.namet", _ ("Name to appear in the listbox")); CSetToolHint ("shellopt.name", _ ("Name to appear in the listbox")); CGetHintPos (0, &y); CDrawText ("shellopt.menut", win, x, y, " Menu item : "); CGetHintPos (&x2, 0); CDrawTextInput ("shellopt.menu", win, x2, y, FONT_MEAN_WIDTH * 27, AUTO_HEIGHT, 39, s->menu);/* Toolhint */ CSetToolHint ("shellopt.menut", _ ("Menu item entry with hot-key")); CSetToolHint ("shellopt.menu", _ ("Menu item entry with hot-key")); CGetHintPos (0, &y); CDrawText ("shellopt.hott", win, x, y, " Menu hotkey : "); CGetHintPos (&x2, 0); CDrawTextInput ("shellopt.hot", win, x2, y, FONT_MEAN_WIDTH * 10, AUTO_HEIGHT, 3, hot);/* Toolhint */ CSetToolHint ("shellopt.hott", _ ("Letter to underline")); CSetToolHint ("shellopt.hot", _ ("Letter to underline")); CGetHintPos (0, &y); CDrawText ("shellopt.promptt", win, x, y, " Argument prompt : "); CGetHintPos (&x2, 0); CDrawTextInput ("shellopt.prompt", win, x2, y, FONT_MEAN_WIDTH * 24, AUTO_HEIGHT, 159, s->prompt);/* Toolhint */ CSetToolHint ("shellopt.promptt", _ ("Message for %a prompting")); CSetToolHint ("shellopt.prompt", _ ("Message for %a prompting")); CGetHintPos (0, &y); xs = x; ys = y; o = (32 - (FONT_PIX_PER_LINE + 2 + TEXT_RELIEF * 2)) / 2; for (i = 0; i < NUM_OPTS / 2; i++) { options[i].w = CDrawSwitch (catstrs ("shellopt.", itoa (i), 0), win, x, y, (s->options & options[i].flag) ? 1 : 0, _ (options[i].name), 0); CSetToolHint (options[i].w->ident, _ (options[i].toolhint)); CSetToolHint (catstrs (options[i].w->ident, ".label", 0), _ (options[i].toolhint)); CGetHintPos (0, &y); } x = xs + CImageStringWidth (_ (options[3].name)) + 32 + WIDGET_SPACING * 2 + 10; y = ys; for (i = NUM_OPTS / 2; i < NUM_OPTS; i++) { options[i].w = CDrawSwitch (catstrs ("shellopt.", itoa (i), 0), win, x, y, (s->options & options[i].flag) ? 1 : 0, _ (options[i].name), 0); CSetToolHint (options[i].w->ident, _ (options[i].toolhint)); CSetToolHint (catstrs (options[i].w->ident, ".label", 0), _ (options[i].toolhint)); CGetHintPos (0, &y); } CPushFont ("editor", 0); w = CDrawEditor ("shellopt.edit", win, xs, y, 77 * FONT_MEAN_WIDTH, 10 * FONT_PIX_PER_LINE, s->script, 0, 0, EDITOR_NO_TEXT | EDITOR_NO_FILE, strlen (s->script)); CPopFont ();/* Toolhint */ CSetToolHint ("shellopt.edit", _ ("Enter your shell script here")); get_hint_limits (&x, &y); x -= WIDGET_SPACING * 2 + TICK_BUTTON_WIDTH * 2; CDrawPixmapButton ("shellopt.ok", win, x, yu, PIXMAP_BUTTON_TICK);/* Toolhint */ CSetToolHint ("shellopt.ok", _ ("Press to accept. You will then be\nprompted for the hot-key combination")); CGetHintPos (&x, 0); CDrawPixmapButton ("shellopt.cancel", win, x, yu, PIXMAP_BUTTON_CROSS);/* Toolhint */ CSetToolHint ("shellopt.cancel", _ ("Abort operation")); CSetSizeHintPos ("shellopt"); CFocus (CIdent ("shellopt.name")); CMapDialog ("shellopt"); while (1) { CNextEvent (0, &cw); if (!CIdent ("shellopt")) /* destroyed by WM close */ break; if (!strcmp (cw.ident, "shellopt.cancel")) { r = 1; break; } if (!strcmp (cw.ident, "shellopt.ok")) { XEvent *p;#ifdef USE_XIM XIC ic = 0;#endif p = CRawkeyQuery ((CIdent ("shellopt.ok"))->mainid, 20, 20, _ (" Script Edit "), _ (" Press the key combination to envoke the script : ")); if (!p) continue;#ifdef USE_XIM ic = CIC; CIC = 0; s->key = CKeySym (p); CIC = ic;#else s->key = CKeySym (p);#endif s->keyboard_state = p->xkey.state; s->options = 0; for (i = 0; i < NUM_OPTS; i++) if (options[i].w->keypressed) s->options |= options[i].flag; strncpy (s->name, (CIdent ("shellopt.name"))->text, 39); strncpy (s->menu, (CIdent ("shellopt.menu"))->text, 39); strncpy (s->prompt, (CIdent ("shellopt.prompt"))->text, 159); s->menu_hot_key = (CIdent ("shellopt.hot"))->text[0]; if (s->script) free (s->script); s->script = edit_get_buffer_as_text (w->editor); break; } } CDestroyWidget ("shellopt"); CRestoreState (&state); return r;}int edit_script (Window parent, int x, int y, int which_script){ return edit_scripts_dialog (parent, x, y, scripts[which_script]);}static char *get_a_line (void *data, int line){ static char t[128]; struct shell_cmd **s; s = data; strcpy (t, s[line]->name); return t;}int script_list_box_dialog (Window parent, int x, int y, char *heading){ int n; for (n = 0; n < MAX_NUM_SCRIPTS; n++) if (!scripts[n]) break; return CListboxDialog (parent, x, y, 30, 10, heading, 0, 0, n, get_a_line, scripts);}/* straight from menu */void edit_a_script_cmd (unsigned long ignored){ int i; i = script_list_box_dialog (main_window, 40, 40, _ (" Pick a Script to Edit ")); if (i >= 0) { if (!edit_script (CRoot, 20, 20, i)) save_scripts (); update_script_menu_items (); }}void delete_script (int i){ if (scripts[i]) { if (scripts[i]->script) free (scripts[i]->script); if (scripts[i]->last_options) free (scripts[i]->last_options); free (scripts[i]); scripts[i] = 0; memmove (scripts + i, scripts + i + 1, (MAX_NUM_SCRIPTS - i - 1) * sizeof (struct shell_cmd *)); }}/* called on application shutdown */void free_all_scripts (void){ while (scripts[0]) delete_script (0);}/* straight from menu */void delete_a_script_cmd (unsigned long ignored){ int i; i = script_list_box_dialog (main_window, 20, 20, _ (" Pick a Script to Delete ")); if (i >= 0) { delete_script (i); save_scripts (); update_script_menu_items (); }}/* straight from menu */void new_script_cmd (unsigned long ignored){ int n; for (n = 0; n < MAX_NUM_SCRIPTS; n++) if (!scripts[n]) break; if (n > MAX_NUM_SCRIPTS - 2) { CErrorDialog (0, 0, 0, _ (" New Script "), \ _ (" Max number of scripts has been reached, \n" \ " increase MAX_NUM_SCRIPTS in the file shell.h ")); return; } scripts[n] = CMalloc (sizeof (struct shell_cmd)); memset (scripts[n], 0, sizeof (struct shell_cmd)); scripts[n]->script = (char *) strdup ("#!/bin/sh\n"); if (edit_script (main_window, 20, 20, n)) { free (scripts[n]); scripts[n] = 0; } else save_scripts (); update_script_menu_items ();}static CWidget *CDrawMiniSwitch (const char *identifier, Window parent, int x, int y, int d, int on){ CWidget *w; w = CSetupWidget (identifier, parent, x, y, d, d, C_SWITCH_WIDGET, INPUT_BUTTON, COLOR_FLAT, 1); w->fg = COLOR_BLACK; w->bg = COLOR_FLAT; w->keypressed = on; w->render = render_switch; w->options |= WIDGET_TAKES_FOCUS_RING; return w;}pid_t open_under_pty (int *in, int *out, char *line, const char *file, char *const argv[]);int option_shell_command_line_sticky = 0;int option_shell_command_line_pty = 0;void shell_output_add_job (WEdit * edit, int in, int out, pid_t pid, char *name, int close_on_error);static struct shell_job *get_job (WEdit * edit, int n){ struct shell_job *j; int i; for (i = 0, j = edit->jobs; j && i < n; j = j->next, i++); return j;}static char *list_jobs_get_line (void *data, int line){ struct shell_job *j; j = get_job ((WEdit *) data, line); if (j) return j->name; return "";}static int list_jobs (void){ struct shell_job *j; int i, c, n; WEdit *e; e = edit[current_edit]->editor; c = max (20, e->num_widget_columns - 5); for (n = 0, j = e->jobs; j; j = j->next, n++); i = CListboxDialog (edit[current_edit]->mainid, 20, 20, c, 10, 0, 0, 0, n, list_jobs_get_line, (void *) e); if (i >= 0) { j = get_job (e, i); if (j) shell_output_kill_job (e, j->pid); } return 0;}void edit_insert_shell_output (WEdit * edit){ char id[33], q[1024], *p; CWidget *w, *v, *i, *b, *h, *c; int tolong = 0, done = 0; CState s; while (!done) { strcpy (id, CIdentOf (edit->widget)); strcat (id, ".text"); w = CIdent (id); if (!w) return; CBackupState (&s); CDisable ("*"); p = getenv ("PWD"); get_current_wd (q, 1023); q[1023] = '\0'; p = q; CPushFont ("widget", 0); while (*p && CImageStringWidth (p) > CWidthOf (w) * 2 / 3 - 20) { tolong = 1; p++; } CPopFont (); h = CDrawButton ("status_button", edit->widget->parentid, CXof (w), CYof (w), CHeightOf (w), CHeightOf (w), 0); CSetToolHint (h->ident, _("Click for list of running jobs.")); b = CDrawMiniSwitch ("status_switch", edit->widget->parentid, CXof (w) + CWidthOf (h), CYof (w), CHeightOf (w), option_shell_command_line_sticky); CSetToolHint (b->ident, _("If not depressed then input line will close on Enter.")); c = CDrawMiniSwitch ("status_switch2", edit->widget->parentid, CXof (w) + CWidthOf (h) + CWidthOf (b), CYof (w), CHeightOf (w), option_shell_command_line_pty); CSetToolHint (c->ident, _("If depressed then opens under a tty.")); v = CDrawText ("status_prompt", edit->widget->parentid, CXof (w) + CWidthOf (b) + CWidthOf (c) + CWidthOf (h), CYof (w), "[%s%s]#", tolong ? "..." : "", p); CSetToolHint (v->ident, _("Current directory. This is the global current directory as set from the Command menu.")); i = CDrawTextInput ("status_input", edit->widget->parentid, CXof (w) + CWidthOf (b) + CWidthOf (c) + CWidthOf (v) + CWidthOf (h), CYof (w), CWidthOf (edit->widget) - CWidthOf (v) - CWidthOf (h) - CWidthOf (b) - CWidthOf (c), AUTO_HEIGHT, 32768, TEXTINPUT_LAST_INPUT); CSetToolHint (i->ident, _ ("Enter shell command. Input will be piped to this command from\nselected text. Output will be inserted at editor cursor.")); CFocus (i); edit->force |= REDRAW_PAGE; edit_render_keypress (edit); edit_push_action (edit, KEY_PRESS + edit->start_display); for (;;) { XEvent xev; CEvent cev; CNextEvent (&xev, &cev); option_shell_command_line_pty = c->keypressed; if (xev.type == KeyPress && cev.command == CK_Enter && cev.kind == C_TEXTINPUT_WIDGET) { char *t; for (t = i->text; *t && isspace (*t); t++); if (!strncmp (t, "cd ", 3)) { for (t = t + 3; *t && isspace (*t); t++); if (change_directory (t) < 0) CErrorDialog (main_window, 20, 20, _(" Change directory "), get_sys_error (_(" Error return from chdir. "))); done = !b->keypressed; } else { int in, out; pid_t pid; char *arg[5]; char line[80]; arg[0] = "/bin/sh"; arg[1] = "-c"; arg[2] = i->text; arg[3] = 0; if (option_shell_command_line_pty) { pid = open_under_pty (&in, &out, line, "/bin/sh", arg); } else { pid = triple_pipe_open (&in, &out, 0, 1, "/bin/sh", arg); } shell_output_add_job (edit, in, out, pid, i->text, !option_shell_command_line_pty); done = !b->keypressed; } break; } if (xev.type == KeyPress && cev.command == CK_Cancel) { done = 1; break; } if (xev.type == ButtonPress && cev.window != v->winid && cev.window != i->winid && cev.window != b->winid && cev.window != c->winid && cev.window != h->winid) { done = 1; break; } if (!strcmp (cev.ident, "status_button")) list_jobs (); } option_shell_command_line_sticky = b->keypressed; CDestroyWidget ("status_prompt"); CDestroyWidget ("status_input"); CDestroyWidget ("status_button"); CDestroyWidget ("status_switch"); CDestroyWidget ("status_switch2"); CRestoreState (&s); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -