#include /* I wrote this functions to be useful to me, I hope they're useful to you. No strings attached: Do what you want with this code and distribute it where you please. (Process_enter, in particular, I think should be added to the standard distribution.) -- David S. Bakin */ /* Contents of this file: establish_aliases() -- establish CED style aliases subst_alias() -- substitute word at point from aliases command substitute_alias() -- subst_alias as a command command process_mode() -- enable aliases in a process buffer. -- replaces version in proc.e. command process_enter() -- electric-enter for process buffer: -- enter key now means execute currrent -- line; current line is copied to end -- of process buffer and executed. Also -- does alias expansion of first word on -- line. (replaces version in proc.e.) command switch_to_process() -- switches to process buffer, starting -- it if necessary. command compile_buffer() -- runs EEL on current buffer command load_buffer() -- loads .e file corresponding to current -- buffer command find_file_other_window() -- like find-file, but in another -- window, like it says. */ /* The "alias" function provided here allow users of CED alias files to get their aliases expanded in the process shell. (DOS users, anyway.) Although this could be turned into a general abbrev. facility, its current goal is to substitute for the CED alias facility since CED is not functional in the process buffer. If you aren't using CED, then a CED file has a bunch of lines of the following types: REM SYN synonym replacement IGNORE command This file ignores all lines that start with REM or IGNORE. Lines that start with SYN are converted into a simple table by establish_aliases(). When subst_alias() is called, if the word surrounding point is in the table it is replaced by its replacement. This was enough for me to use in process buffers. Other improvements could be made, including regex-replacement text, and restoring the line in the command buffer back to its pre-expanded state. -- David S. Bakin */ char ced_file[20] = "C:\\CED.CFG"; char word_pattern[20] = "[a-zA-Z0-9_]+"; /* in format.e */ /* Read the alias file and turn it into something easily searched. */ command establish_aliases() { int i; char *oldbuf = bufname; if (!exist("-aliases")) { zap("-aliases"); bufname = "-aliases"; i = file_read(ced_file, 1 /* strip ^M */); bufname = oldbuf; if (i != 0) { delete_buffer("-aliases"); file_error(i, ced_file, "Can't read CED.CFG for some reason."); return; } bufname = "-aliases"; if (character(size()-1) != '\n') { point = size(); enter_key(); } point = 0; case_fold = 1; /* ignore case in match */ /* Strip out REM lines */ point = 0; while (re_search(1,"^REM")) { nl_forward(); delete(matchstart,point); } /* Strip out IGNORE lines */ point = 0; while (re_search(1,"^IGNORE")) { nl_forward(); delete(matchstart, point); } /* Strip SYN, replace separator whitespace with tabs */ point = 0; while (re_search(1,"^SYN")) { i = matchstart; re_search(1,"[ \t]+"); delete(i, point); re_search(1,word_pattern); re_search(1,"[ \t]+"); delete(matchstart, point); insert('\t'); } point = 0; modified = 0; bufname = oldbuf; } } /* Replace the alias at point (if any), return true if there was an alias. */ subst_alias() { int eow, bow, boa; char alias[42]; char *oldbuf = bufname; /* Make sure the aliases are defined. */ if (!exist("-aliases")) establish_aliases(); /* Delimit the current word */ re_search(1,word_pattern); eow = point; re_search(-1,word_pattern); bow = point; /* If the word is short enough, search for its alias */ if (eow - bow < 40) { alias[0] = '^'; grab(bow, eow, &alias[1]); strcat (alias, "\t"); bufname = "-aliases"; point = 0; if (!re_search (1, alias)) { /* Not found */ bufname = oldbuf; return 0; } /* Go back and delete the alias name */ bufname = oldbuf; delete(bow, eow); /* Insert the alias substitution */ bufname = "-aliases"; boa = point; to_end_line(); xfer(oldbuf, boa, point); bufname = oldbuf; /* OK */ return 1; } /* No substitution attempted */ return 0; } command substitute_alias() { int i = subst_alias(); if (!i) say ("Alias not found."); } /* Replaces (proc.e)process_enter: */ /* Inserts an enter keystroke in the process buffer, which causes Epsilon to send the line to DOS. But if hit anywhere except the last character of the last line, copies the line it is on to the end of the buffer. Good for repeating commands! */ /* ?? If the last line doesn't contain only a prompt, should do what? Perhaps erase it before copying the new line down?? */ char prompt_pattern[25]="^[A-Z]>"; buffer int do_aliasing = 0; /* Should only be 1 in the process buffer */ /* From (proc.e), modified to turn on aliasing in the process buffer */ char process_mode_name[] = "Process"; command process_mode() { mode_keys = index_table(find_index("process-tab")); major_mode = process_mode_name; do_aliasing = 1; make_mode(); } /* Handle the enter key in the process buffer. Special processing enables you to go back to a previous command line, edit it (or not), hit enter there, and have the command copied to the end of the process buffer and executed. (Or you can simply edit the current command line and hit enter with point anywhere on the line and it will be executed.) */ command process_enter() { int eol, start, szline; char captured_line[81]; char *pcaptured_line; if (point < size()) { /* First see if we're on the last line. */ start = point; point = size(); to_begin_line(); if (point <= start) /* On last line, just move to end. */ point = size(); else { /* Not on last line, move the line (after the prompt) to the end of the buffer. */ point = start; to_end_line(); eol = point; to_begin_line(); re_search (1 /*forward*/, prompt_pattern); szline = eol - point; if (szline <= 80) { grab(point, eol, captured_line); point = size(); stuff(captured_line); } else { pcaptured_line = malloc(szline+1); grab(point, eol, pcaptured_line); point = size(); stuff(pcaptured_line); free(pcaptured_line); } } } if (do_aliasing) { to_begin_line(); re_search (1, prompt_pattern); subst_alias(); point = size(); } enter_key(); if (error_spot && (*error_spot <= point)) *error_spot = point; } /* Switch to a concurrent process, and if it doesn't exist, create it. */ command switch_to_process() { /* Could define it to switch to process buffer in another window on the screen, popping one up if necessary. */ if (!another) start_process(); else { locate_window("process", ""); point = size(); } } /* Similar to (proc.e)make(): */ /* Saves buffers, and then runs eel on the file the buffer is visiting. */ command compile_buffer() { char eel_cmd[120]; int err = 0; /* Command is : eel filename */ strcpy (eel_cmd, "eel "); strcat (eel_cmd, filename); maybe_save_all(); if (no_running()) { /* goes to end of proc buffer */ if (error_spot) *error_spot = point; bprintf("%s\n", eel_cmd); iter = 1; delay(-1, COND_PROC | COND_KEY); if (!another || !process_input()) return; /* else assume it's compiled */ } else err = do_push(eel_cmd, 1, 0); if (!do_next_error(1) && err) say("Process returned %d", err); iter = 0; } /* Similar to (load.e)load_bytes */ /* Load the bytecode file which corresponds to the eel file in the current buffer. */ command load_buffer() { char fname[80], rel[80]; strcpy(fname, filename); strcpy(get_extension(fname), byte_extension); load_commands(fname); relative(fname, rel); say("%s loaded.", rel); iter = 0; } /* Does a find file, but in another window. Splits the only window if necessary. */ command find_file_other_window() { char fname[FNAMELEN]; /* From (file.e)find_file: */ iter = 0; get_file_dir(fname, "Find file (other window): ", filename); /* Make sure a valid filename was entered: */ if (fname[0] == '\0' || strcmp(filename, fname) == 0) return; /* Now move to another window or split the windows: */ if (number_of_windows() == 1) { window_split(); window_number = 1; } else { int nw = window_number + 1; if (nw == number_of_windows()) nw = 0; window_number = nw; } /* Move to the file's buffer or read the file: */ find_it (fname, !has_arg); } when_loading() { /* The following might not be necessary, does the new process_enter get the same index as the previous process_enter?? */ short *p_tab = index_table(find_index("process-tab")); *(p_tab + '\r') = (short)process_enter; }