static char rcsid[] = "$Id: mmfcn.c,v 1.2 1992/11/08 23:29:54 mike Exp $"; /* $Log: mmfcn.c,v $ * Revision 1.2 1992/11/08 23:29:54 mike * - Added view mode. * * Revision 1.1 1992/09/05 01:13:32 mike * Initial revision * */ /* * mmfcn.c : Main loop for external Mutt (ME2) functions. * Craig Durland 6/87 */ /* Copyright 1990, 1991, 1992 Craig Durland * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind, but comments, * suggestions and bug reports are welcome. */ #include #include "me2.h" #include "mm.h" #include "bind.h" extern Bag *id_to_bag(); extern Buffer *bfind(), *Mid_to_buffer(); extern char current_directory[], /* in os.c */ result[], /* in mm.c */ **zargv, /* in main.c */ *strcpy(), *getenv(); extern int currow, zargc, MMask_pgm, /* in mm.c */ arg_flag, arg_prefix, pgm_flag, pgm_prefix, /* in mmaux.c */ svsize; /* in mmaux.c */ extern KeyCode key_pressed, to_keycode(); extern MuttCmd sysvars[]; /* in mmaux.c */ extern PKey pkeys[]; /* in bind.c */ extern MMDatum RV, TV; /* in mm.c */ extern Window *Mnth_window(), *nthwindow(); #define BIT_AND 0 #define BIT_OR 1 #define BIT_XOR 2 static void bitop(op) /* (bit-op x [y ...] */ { int j; get1arg(NUMBER,"bit-"); for (j = 1; maybearg(j++,NUMBER,"bit-"); ) { switch (op) { case BIT_XOR: RV.val.num ^= TV.val.num; break; case BIT_AND: RV.val.num &= TV.val.num; break; case BIT_OR : RV.val.num |= TV.val.num; break; } } } void Mdomutt(t) { Bag *bag; Buffer *bp; char *ptr; int x, n; KeyCode kc; Window *wp; switch(t) { /* ************ Misc ************************** */ case 579: /* (do-undo) */ if (curbp->b_flags & BFVIEW) { view_mode_violation(); RV.val.num = 2; /* Problems */ } else RV.val.num = undo(); RV.type = NUMBER; break; case 546: /* (modify-syntax-entry "???") */ get1arg(STRING,"modify-syntax-entry"); { char c = *RV.val.str; if (c == '\0') MMbitch("invalid string format"); for (ptr = RV.val.str+1; *ptr; ptr++) switch (c) { case 'w': add_cinfo(*ptr,_W); break; case 'W': remove_cinfo(*ptr,_W); break; } } break; case 501: /* (sysvar name [val]) */ get1arg(STRING,"sysvar"); if ((n = lookupmut(RV.val.str,sysvars,svsize)) == -1) MMbitch("That ain't no sysvar"); Msys_var(n,1); break; case 524: /* (insert-text text) */ if (curbp->b_flags & BFVIEW) view_mode_violation(); else { MMconcat(); if (!insert_text(result,strlen(result))) MMabort_pgm(2); } RV.type = VOID; break; case 533: /* (to-col n) */ get1arg(NUMBER,"to-col"); to_col((int)RV.val.num -1); break; case 525: /* (is-space), newline!=space */ RV.val.num = (the_dot->offset == llength(the_dot->line)) ? FALSE : isspace(lgetc(the_dot->line,the_dot->offset)); RV.type = BOOLEAN; break; case 516: /* (arg-prefix [n]) */ if (maybearg(0,NUMBER,"arg-prefix")) { arg_flag = pgm_flag = TRUE; arg_prefix = pgm_prefix = TV.val.num; } RV.type = NUMBER; RV.val.num = pgm_prefix; break; case 521: /* (arg-flag) */ RV.type = BOOLEAN; RV.val.num = pgm_flag; break; case 530: /* (file-exists name) */ get1arg(STRING,"file-exists"); RV.type = BOOLEAN; RV.val.num = file_exists(RV.val.str); break; case 515: /* (pgm-exists name) */ get1arg(STRING,"pgm-exists"); RV.type = BOOLEAN; RV.val.num = (-1 != MMpgm_lookup(RV.val.str)); break; /* *********** Math ************************************* */ case 527: bitop(BIT_AND); break; /* (bit-and x [y ...] */ case 528: bitop(BIT_OR); break; /* (bit-or x [y ...] */ case 529: bitop(BIT_XOR); break; /* (bit-xor x [y ...] */ /* *********** Query the User *************************** */ case 551: /* (complete selector prompt) */ get2args(NUMBER,STRING,"complete"); MMset_ask_frame(); mlreply(TV.val.str,result,RSIZ,(int)RV.val.num); RV.type = STRING; RV.val.str = result; MMreset_ask_frame(); break; case 512: /* (yesno prompt[s]) */ MMconcat(); MMset_ask_frame(); RV.val.num = mlyesno(result); MMreset_ask_frame(); RV.type = BOOLEAN; break; case 522: /* (getchar) */ get_McKc(&kc,FALSE); *result = kc; *(result+1) = '\0'; RV.type = STRING; RV.val.str = result; break; /* ***************** Cursor related stuff ******************* */ case 511: /* (current-column [n]) */ if (maybearg(0,NUMBER,"current-column")) { the_dot->offset = getgoal(the_dot->line,(int)TV.val.num -1); } RV.val.num = getccol() +1; RV.type = NUMBER; break; case 519: /* (forward-line n) */ get1arg(NUMBER,"forward-line"); RV.val.num = next_line((int)RV.val.num); RV.type = BOOLEAN; break; case 576: /* (goto-line n) */ get1arg(NUMBER,"goto-line"); RV.val.num = goto_line((int)RV.val.num); RV.type = BOOLEAN; break; case 557: /* (move-cursor row col) */ get2args(NUMBER,NUMBER,"move-cursor"); t_move((int)RV.val.num,(int)TV.val.num); RV.type = VOID; break; case 505: /* (EoB) */ RV.type = BOOLEAN; RV.val.num = (the_dot->line == BUFFER_LAST_LINE(curbp)); break; /* ******** Marks ********************** */ case 526: /* (create-mark [immortal]) */ x = FALSE; if (maybearg(0,BOOLEAN,"create-mark")) x = TV.val.num; if (-1 == (RV.val.num = alloc_buffer_mark(x))) MMbitch("No memory!"); RV.type = NUMBER; break; case 553: /* (free-mark mark-id ...) */ n = 0; while (maybearg(n++,NUMBER,"free-mark")) free_buffer_mark((int)TV.val.num); RV.type = VOID; break; case 550: /* (set-mark [mark-id]) */ n = THE_MARK; if (maybearg(0,NUMBER,"set-mark")) n = TV.val.num; #if 0 /* ??? die on bad mark??? */ RV.val.num = set_mark(n); RV.type = BOOLEAN; #else if (!set_mark(n)) MMbitch("set-mark: Bad mark."); #endif break; case 547: /* (goto-mark mark-id) */ get1arg(NUMBER,"goto-mark"); RV.val.num = goto_mark((int)RV.val.num); RV.type = BOOLEAN; /* ??? die if bad mark? */ break; case 583: Mswap_marks(); break; /* (swap-marks [mark-id mark-id])) */ case 540: Mcompare_marks(); break; /* (compare-marks [mark-id mark-id]) */ /* ******** Keys ********************** */ case 514: /* (key-pressed [kc]) */ /*??? if (maybearg(0,NUMBER,"key-pressed")) key_pressed = TV.val.num; */ RV.val.num = key_pressed; RV.type = NUMBER; break; case 502: /* (get-key) */ get_McKc(&kc,TRUE); RV.type = NUMBER; RV.val.num = kc; break; case 503: /* (exe-key int) */ get1arg(NUMBER,"exe-key"); n = MMask_pgm; MMask_pgm = FALSE; RV.val.num = do_key((KeyCode)RV.val.num,arg_flag,arg_prefix); MMask_pgm = n; arg_flag = FALSE; arg_prefix = 1; if (RV.val.num == ABORT) MMabort_pgm(0); RV.type = BOOLEAN; break; case 504: /* (key-waiting [seconds]) */ n = 0; if (maybearg(0,NUMBER,"key-waiting")) n = TV.val.num; RV.type = BOOLEAN; RV.val.num = wait_for_key(n); break; case 562: /* (key-bound-to key-string) */ get1arg(STRING,"key-bound-to"); dscrib_key(RV.val.str,result); RV.val.str = result; break; case 567: /* (prefix-key n [string]) */ n = get1num(0,PKEYS,"prefix-key"); if (maybearg(1,STRING,"prefix-key")) pkeys[n] = to_keycode(TV.val.str,FALSE); RV.type = STRING; RV.val.str = result; *result = '\0'; xpandkey(result,pkeys[n]); break; /* **************** Windows ************************** */ case 559: /* (windows) */ RV.type = NUMBER; RV.val.num = cntwindows((Window *)NULL); break; case 558: /* (current-window [n]) */ if (maybearg(0,NUMBER,"current-window")) /* move to nth window */ use_window(nthwindow(first_window,(int)TV.val.num)); RV.type = NUMBER; RV.val.num = cntwindows(curwp); break; case 555: /* (window-row) */ RV.type = NUMBER; RV.val.num = currow -curwp->w_toprow +1; break; case 556: /* (free-window n) */ get1arg(NUMBER,"free-window"); RV.type = BOOLEAN; RV.val.num = free_window(Mnth_window((int)RV.val.num)); break; case 564: /* (window-ledge n [left-edge]) */ get1arg(NUMBER,"window-ledge"); wp = Mnth_window((int)RV.val.num); if (maybearg(1,NUMBER,"window-ledge")) { wp->lmargin = imax(0,(int)TV.val.num); wp->w_flag |= WFHARD; } RV.val.num = wp->lmargin; break; case 520: /* (window-height n [rows]) */ get1arg(NUMBER,"window-height"); wp = Mnth_window((int)RV.val.num); if (maybearg(1,NUMBER,"window-height")) change_window_size(wp,(int)TV.val.num); RV.val.num = wp->w_ntrows; break; case 534: /* (update [update-screen]) */ sync_dot(); n = TRUE; if (maybearg(0,BOOLEAN,"update")) n = TV.val.num; if (n) update(); RV.type = VOID; break; /* ******************** Buffers *********************** */ case 543: /* (free-buffer buffer-id) */ get1arg(NUMBER,"free-buffer"); free_buffer(Mid_to_buffer((int)RV.val.num)); break; case 541: Mcreate_buffer(); break; /* (create-buffer name [flags]) */ case 542: Mnth_buffer(); break; /* (nth-buffer n [id [flags]]) => id */ case 560: /* (attached-buffer window-id | "name") => buffer-id */ if (!MMpull_nth_arg(&RV,0) || (RV.type != NUMBER && RV.type != STRING)) arg_bitch("attached-buffer"); if (RV.type == NUMBER) RV.val.num = Mnth_window((int)RV.val.num)->wbuffer->id; else RV.val.num = (bp = bfind(RV.val.str,FALSE,0)) ? (int)bp->id : -2; RV.type = NUMBER; break; case 554: /* (buffer-stats buffer-id (array INT stats 6)) */ Mbuffer_stats(); break; case 508: /* (buffer-name buffer-id [name]) */ get1arg(NUMBER,"buffer-name"); RV.val.str = strcpy(result, get_dString(Mid_to_buffer((int)RV.val.num)->b_bname)); RV.type = STRING; break; case 507: /* (buffer-modified [buffer-id [bool]]) */ #if 0 bp = maybearg(0,NUMBER,"buffer-modified") ? Mid_to_buffer((int)TV.val.num) : curbp; #else get1arg(NUMBER,"buffer-modified"); bp = Mid_to_buffer((int)RV.val.num); #endif if (maybearg(1,BOOLEAN,"buffer-modified")) set_buffer_modified(bp, (int)TV.val.num); RV.type = BOOLEAN; RV.val.num = is_buffer_modified(bp); break; case 566: /* (buffer-flags buffer-id [flags]) */ get1arg(NUMBER,"buffer-flags"); bp = Mid_to_buffer((int)RV.val.num); if (maybearg(1,NUMBER,"buffer-flags")) set_buffer_flags(bp,TV.val.num); RV.type = NUMBER; RV.val.num = bp->b_flags; break; case 509: /* (buffers [skip-flags]) */ RV.type = NUMBER; RV.val.num = cntbufs((Buffer *)NULL); break; case 513: /* (current-buffer [buffer-id [display-it]]) */ if (maybearg(0,NUMBER,"current-buffer")) { bp = Mid_to_buffer((int)TV.val.num); x = FALSE; if (maybearg(1,BOOLEAN,"current-buffer")) x = TV.val.num; use_buffer(bp,x); } RV.val.num = curbp->id; RV.type = NUMBER; break; case 561: /* (clear-buffer) */ if (curbp->b_flags & BFVIEW) view_mode_violation(); else clear_buffer(curbp); RV.type = VOID; break; case 510: /* (file-name buffer-id [name]) */ get1arg(NUMBER,"file-name"); bp = Mid_to_buffer((int)RV.val.num); if (maybearg(1,STRING,"file-name")) /* rename the file */ { RV.type = BOOLEAN; RV.val.num = newfilename(bp,TV.val.str); } else /* return the name of the file attached to the buffer */ { RV.type = STRING; RV.val.str = strcpy(result,get_dString(bp->b_fname)); } break; /* ******************** Buffer Variables *********************** */ case 577: /* (create-buffer-var type name ...) */ get1arg(NUMBER,"create-buffer-var"); /* type */ for (n = 0; maybearg(++n,STRING,"create-buffer-var"); ) if (!alloc_bvar(TV.val.str,(int)RV.val.num)) MMbitch("create-buffer-var: bad type or no memory."); RV.type = VOID; break; case 578: /* (buffer-var name [val]) */ get1arg(STRING,"buffer-var"); TV = RV; x = MMpull_nth_arg(&RV,1) ? TRUE : FALSE; if (!access_bvar(TV.val.str,x)) /* sets RV */ MMbitch("buffer-var: bad name or type mismatch."); break; /* ******************* Regular Expressions ******************** */ case 548: /* (looking-at RE-pattern) */ MMconcat(); if ((RV.val.num = looking_at(result)) == ABORT) MMabort_pgm(0); RV.type = BOOLEAN; break; case 506: /* (re-string re-pattern string) */ get2args(STRING,STRING,"re-string"); if ((RV.val.num = REstring(RV.val.str,TV.val.str)) ==ABORT) MMabort_pgm(0); RV.type = BOOLEAN; break; case 549: /* (get-matched RE-sub) */ get1arg(STRING,"get-matched"); if (!re_subs(RV.val.str,result)) MMbitch("get-matched failed."); RV.val.str = result; break; /* *************** Bags ********************************** */ case 537: /* (create-bag [immortal]) */ x = maybearg(0,BOOLEAN,"create-bag") ? TV.val.num : FALSE; if (!(bag = alloc_bag(x))) MMbitch("Create-bag: out of memory"); RV.type = NUMBER; RV.val.num = bag->id; break; case 538: /* (free-bag bag-id ...) */ n = 0; while (maybearg(n++,NUMBER,"free-bag")) { if (!(bag = id_to_bag((int)TV.val.num))) arg_bitch("free-bag"); free_bag(bag); } TV.type = VOID; break; case 518: /* (bag-stats bag-id blob) */ get2args(NUMBER,BLOB,"bag-stats"); if (!(bag = id_to_bag((int)RV.val.num))) arg_bitch("bag-stats"); PUT_UINT8(TV.val.blob, bag_type(bag)); put_int16(TV.val.blob+1, bag->width); put_int16(TV.val.blob+3, bag->height); put_int32(TV.val.blob+5, (int32)sizeof_dTable(&bag->text)); RV.type = VOID; break; case 569: Mappend_to_bag(); break; /* (append-to-bag bag-id [text]) */ case 570: /* (clear-bag bag-id) */ get1arg(NUMBER,"clear-bag"); if (!(bag = id_to_bag((int)RV.val.num))) arg_bitch("clear-bag"); clear_bag(bag); break; case 571: /* (insert-bag bag-id) */ if (curbp->b_flags & BFVIEW) view_mode_violation(); else { get1arg(NUMBER,"clear-bag"); if (!(bag = id_to_bag((int)RV.val.num))) arg_bitch("insert-bag"); if (!insert_bag(bag)) MMabort_pgm(0); } RV.type = VOID; break; case 532: /* (bag-to-file bag-id file-name) */ get2args(NUMBER,STRING,"bag-to-file"); if (!(bag = id_to_bag((int)RV.val.num))) arg_bitch("bag-to-file"); RV.val.num = bag_to_file(bag,TV.val.str); RV.type = BOOLEAN; break; case 535: /* (file-to-bag file-name bag-id) */ get2args(STRING,NUMBER,"register-to-file"); if (!(bag = id_to_bag((int)TV.val.num))) arg_bitch("file-to-bag"); RV.val.num = file_to_bag(RV.val.str,bag); RV.type = BOOLEAN; break; case 580: /* (case-bag op bag-id ...) */ get2args(NUMBER,NUMBER,"case-bag"); if (!(bag = id_to_bag((int)TV.val.num))) arg_bitch("case-bag"); case_text(bag->text.table, sizeof_dTable(&bag->text), (int)RV.val.num); RV.type = VOID; break; case 582: Mbag_to_string(); break; /* (bag-to-string bag-id) */ /* *************** Rectangles **************************** */ case 523: /* (erase-rectangle delete-it) */ if (curbp->b_flags & BFVIEW) view_mode_violation(); else { get1arg(BOOLEAN,"erase-rectangle"); if (!erase_rect((int)RV.val.num)) MMabort_pgm(0); } RV.type = VOID; break; /* *************** Regions ********************************* */ case 517: Mregion_stats(); break; /* (region-stats blob) */ /* ************* OS related stuff ************************* */ case 531: /* (puts strings) string to terminal */ MMconcat(); t_puts(result); RV.type = STRING; RV.val.str = result; break; case 544: RV.type = NUMBER; RV.val.num = zargc; break; /* (argc) */ case 545: /* (argv n) */ RV.val.str = zargv[get1num(0,zargc,"argv")]; RV.type = STRING; break; case 565: /* (current-directory [newdir]) */ if (maybearg(0,STRING,"current-directory")) { RV.type = BOOLEAN; RV.val.num = change_directory(TV.val.str); } else { strcpy(result, current_directory); RV.type = STRING; RV.val.str = result; } break; case 568: /* (getenv name) */ get1arg(STRING,"getenv"); if ((ptr = getenv(RV.val.str)) == NULL) *result = '\0'; else strcpy(result,ptr); RV.type = STRING; RV.val.str = result; break; case 536: Mfilter(); break; /* (OS-filter ...) */ case 581: /* (create-process ...) */ create_process(); break; /* ****************** Searching *************************** */ case 552: /* (search-forward pattern) */ get1arg(STRING,"search-forward"); RV.val.num = search_forward(RV.val.str); RV.type = BOOLEAN; break; case 563: /* (search-reverse pattern) */ get1arg(STRING,"search-reverse"); RV.val.num = search_reverse(RV.val.str); RV.type = BOOLEAN; break; case 572: /* (re-search-forward pattern) */ get1arg(STRING,"re-search-forward"); RV.val.num = re_search_forward(RV.val.str); if (RV.val.num == ABORT) MMabort_pgm(0); RV.type = BOOLEAN; break; case 573: /* (re-search-reverse pattern) */ get1arg(STRING,"re-search-reverse"); RV.val.num = re_search_reverse(RV.val.str); if (RV.val.num == ABORT) MMabort_pgm(0); RV.type = BOOLEAN; break; case 574: /* (search-replace pattern replace-with) */ if (curbp->b_flags & BFVIEW) { view_mode_violation(); RV.val.num = FALSE; } else { get2args(STRING,STRING,"search-replace"); RV.val.num = search_replace(RV.val.str,TV.val.str); if (RV.val.num == ABORT) MMabort_pgm(0); } RV.type = BOOLEAN; break; case 575: /* (re-search-replace pattern replace-with) */ if (curbp->b_flags & BFVIEW) { view_mode_violation(); RV.val.num = FALSE; } else { get2args(STRING,STRING,"re-search-replace"); RV.val.num = re_search_replace(RV.val.str,TV.val.str); if (RV.val.num == ABORT) MMabort_pgm(0); } RV.type = BOOLEAN; break; default: MMbitch("Invalid Mutt token"); } }