|
|
1.1 ! root 1: /* Call a Lisp function interactively. ! 2: Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU Emacs. ! 5: ! 6: GNU Emacs is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GNU Emacs is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU Emacs; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: #include "config.h" ! 22: #include "lisp.h" ! 23: #include "buffer.h" ! 24: #include "commands.h" ! 25: #include "window.h" ! 26: ! 27: extern Lisp_Object global_map; ! 28: ! 29: extern int num_input_chars; ! 30: ! 31: Lisp_Object Vprefix_arg, Vcurrent_prefix_arg, Qminus; ! 32: Lisp_Object Qcall_interactively; ! 33: Lisp_Object Vcommand_history; ! 34: ! 35: extern Lisp_Object ml_apply (); ! 36: extern Lisp_Object Fread_buffer (), Fread_key_sequence (), Fread_file_name (); ! 37: ! 38: /* This comment supplies the doc string for interactive, ! 39: for make-docfile to see. We cannot put this in the real DEFUN ! 40: due to limits in the Unix cpp. ! 41: ! 42: DEFUN ("interactive", Ffoo, Sfoo, 0, 0, 0, ! 43: "Specify a way of parsing arguments for interactive use of a function.\n\ ! 44: For example, write\n\ ! 45: (defun fun (arg) \"Doc string\" (interactive \"p\") ...use arg...)\n\ ! 46: to make arg be the prefix numeric argument when foo is called as a command.\n\ ! 47: This is actually a declaration rather than a function;\n\ ! 48: it tells call-interactively how to read arguments\n\ ! 49: to pass to the function.\n\ ! 50: When actually called, interactive just returns nil.\n\ ! 51: \n\ ! 52: The argument of interactive is usually a string containing a code letter\n\ ! 53: followed by a prompt. (Some code letters do not use I/O to get\n\ ! 54: the argument and do not need prompts.) To prompt for multiple arguments,\n\ ! 55: give a code letter, its prompt, a newline, and another code letter, etc.\n\ ! 56: If the argument is not a string, it is evaluated to get a list of\n\ ! 57: arguments to pass to the function.\n\ ! 58: Just (interactive) means pass no args when calling interactively.\n\ ! 59: \nCode letters available are:\n\ ! 60: a -- Function name: symbol with a function definition.\n\ ! 61: b -- Name of existing buffer.\n\ ! 62: B -- Name of buffer, possibly nonexistent.\n\ ! 63: c -- Character.\n\ ! 64: C -- Command name: symbol with interactive function definition.\n\ ! 65: d -- Value of point as number. Does not do I/O.\n\ ! 66: D -- Directory name.\n\ ! 67: f -- Existing file name.\n\ ! 68: F -- Possibly nonexistent file name.\n\ ! 69: k -- Key sequence (string).\n\ ! 70: m -- Value of mark as number. Does not do I/O.\n\ ! 71: n -- Number read using minibuffer.\n\ ! 72: N -- Prefix arg converted to number, or if none, do like code `n'.\n\ ! 73: p -- Prefix arg converted to number. Does not do I/O.\n\ ! 74: P -- Prefix arg in raw form. Does not do I/O.\n\ ! 75: r -- Region: point and mark as 2 numeric args, smallest first. Does no I/O.\n\ ! 76: s -- Any string.\n\ ! 77: S -- Any symbol.\n\ ! 78: v -- Variable name: symbol that is user-variable-p.\n\ ! 79: x -- Lisp expression read but not evaluated.\n\ ! 80: X -- Lisp expression read and evaluated.\n\ ! 81: In addition, if the first character of the string is '*' then an error is\n\ ! 82: signaled if the buffer is read-only.\n\ ! 83: This happens before reading any arguments.") ! 84: */ ! 85: ! 86: /* ARGSUSED */ ! 87: DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, ! 88: 0 /* See immediately above */) ! 89: (args) ! 90: Lisp_Object args; ! 91: { ! 92: return Qnil; ! 93: } ! 94: ! 95: /* Quotify EXP: if EXP is constant, return it. ! 96: If EXP is not constant, return (quote EXP). */ ! 97: Lisp_Object ! 98: quotify_arg (exp) ! 99: register Lisp_Object exp; ! 100: { ! 101: if (XTYPE (exp) != Lisp_Int && XTYPE (exp) != Lisp_String ! 102: && !NULL (exp) && !EQ (exp, Qt)) ! 103: return Fcons (Qquote, Fcons (exp, Qnil)); ! 104: ! 105: return exp; ! 106: } ! 107: ! 108: /* Modify EXP by quotifying each element (except the first). */ ! 109: Lisp_Object ! 110: quotify_args (exp) ! 111: Lisp_Object exp; ! 112: { ! 113: register Lisp_Object tail; ! 114: register struct Lisp_Cons *ptr; ! 115: for (tail = exp; CONSP (tail); tail = ptr->cdr) ! 116: { ! 117: ptr = XCONS (tail); ! 118: ptr->car = quotify_arg (ptr->car); ! 119: } ! 120: return exp; ! 121: } ! 122: ! 123: char *callint_argfuns[] ! 124: = {"", "point", "mark", "region-beginning", "region-end"}; ! 125: ! 126: static void ! 127: check_mark () ! 128: { ! 129: Lisp_Object tem = Fmarker_buffer (current_buffer->mark); ! 130: if (NULL (tem) || (XBUFFER (tem) != current_buffer)) ! 131: error ("The mark is not set now"); ! 132: } ! 133: ! 134: ! 135: DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 2, 0, ! 136: "Call FUNCTION, reading args according to its interactive calling specs.\n\ ! 137: The function contains a specification of how to do the argument reading.\n\ ! 138: In the case of user-defined functions, this is specified by placing a call\n\ ! 139: to the function `interactive' at the top level of the function body.\n\ ! 140: See `interactive'.\n\ ! 141: \n\ ! 142: Optional second arg RECORD-FLAG non-nil\n\ ! 143: means unconditionally put this command in the command-history.\n\ ! 144: Otherwise, this is done only if an arg is read using the minibuffer.") ! 145: (function, record) ! 146: Lisp_Object function, record; ! 147: { ! 148: Lisp_Object *args, *visargs; ! 149: unsigned char **argstrings; ! 150: Lisp_Object fun; ! 151: Lisp_Object funcar; ! 152: Lisp_Object specs; ! 153: Lisp_Object teml; ! 154: ! 155: Lisp_Object prefix_arg; ! 156: unsigned char *string; ! 157: unsigned char *tem; ! 158: int *varies; ! 159: register int i, j; ! 160: int count, foo; ! 161: char prompt[100]; ! 162: char prompt1[100]; ! 163: char *tem1; ! 164: int arg_from_tty = 0; ! 165: struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; ! 166: extern char *index (); ! 167: ! 168: /* Save this now, since use ofminibuffer will clobber it. */ ! 169: prefix_arg = Vcurrent_prefix_arg; ! 170: ! 171: retry: ! 172: ! 173: for (fun = function; ! 174: XTYPE (fun) == Lisp_Symbol && !EQ (fun, Qunbound); ! 175: fun = XSYMBOL (fun)->function) ! 176: { ! 177: QUIT; ! 178: } ! 179: ! 180: if (XTYPE (fun) == Lisp_Subr) ! 181: { ! 182: string = (unsigned char *) XSUBR (fun)->prompt; ! 183: if (!string) ! 184: { ! 185: lose: ! 186: function = wrong_type_argument (Qcommandp, function, 0); ! 187: goto retry; ! 188: } ! 189: else if ((int) string == 1) ! 190: return call0 (function); ! 191: } ! 192: else if (!CONSP (fun)) ! 193: goto lose; ! 194: else if (funcar = Fcar (fun), EQ (funcar, Qautoload)) ! 195: { ! 196: GCPRO2 (function, prefix_arg); ! 197: do_autoload (fun, function); ! 198: UNGCPRO; ! 199: goto retry; ! 200: } ! 201: else if (EQ (funcar, Qlambda)) ! 202: { ! 203: specs = Fassq (Qinteractive, Fcdr (Fcdr (fun))); ! 204: if (NULL (specs)) ! 205: goto lose; ! 206: specs = Fcar (Fcdr (specs)); ! 207: if (XTYPE (specs) == Lisp_String) ! 208: { ! 209: /* Make a copy of string so that if a GC relocates specs, ! 210: `string' will still be valid. */ ! 211: string = (unsigned char *) alloca (XSTRING (specs)->size + 1); ! 212: bcopy (XSTRING (specs)->data, string, XSTRING (specs)->size + 1); ! 213: } ! 214: else ! 215: { ! 216: i = num_input_chars; ! 217: specs = Feval (specs); ! 218: if (i != num_input_chars || !NULL (record)) ! 219: Vcommand_history ! 220: = Fcons (Fcons (function, quotify_args (Fcopy_sequence (specs))), ! 221: Vcommand_history); ! 222: return apply1 (function, specs); ! 223: } ! 224: } ! 225: else if (EQ (funcar, Qmocklisp)) ! 226: return ml_apply (fun, Qinteractive); ! 227: else ! 228: goto lose; ! 229: ! 230: /* Here if function specifies a string to control parsing the defaults */ ! 231: ! 232: /* First character '*' means barf if buffer read-only */ ! 233: if (*string == '*') ! 234: { ! 235: string++; ! 236: if (!NULL (current_buffer->read_only)) ! 237: Fbarf_if_buffer_read_only (); ! 238: } ! 239: ! 240: tem = string; ! 241: for (j = 0; *tem; j++) ! 242: { ! 243: if (*tem == 'r') j++; ! 244: tem = (unsigned char *) index (tem, '\n'); ! 245: if (tem) tem++; ! 246: else tem = (unsigned char *) ""; ! 247: } ! 248: count = j; ! 249: ! 250: args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); ! 251: visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object)); ! 252: argstrings = (unsigned char **) alloca ((count + 1) * sizeof (char *)); ! 253: varies = (int *) alloca ((count + 1) * sizeof (int)); ! 254: ! 255: for (i = 0; i < (count + 1); i++) ! 256: { ! 257: args[i] = Qnil; ! 258: visargs[i] = Qnil; ! 259: varies[i] = 0; ! 260: } ! 261: ! 262: GCPRO4 (prefix_arg, function, *args, *visargs); ! 263: gcpro3.nvars = (count + 1); ! 264: gcpro4.nvars = (count + 1); ! 265: ! 266: tem = string; ! 267: for (i = 1; *tem; i++) ! 268: { ! 269: strncpy (prompt1, tem + 1, sizeof prompt1 - 1); ! 270: prompt1[sizeof prompt1 - 1] = 0; ! 271: tem1 = index (prompt1, '\n'); ! 272: if (tem1) *tem1 = 0; ! 273: /* Fill argstrings with a vector of C strings ! 274: corresponding to the Lisp strings in visargs. */ ! 275: for (j = 1; j < i; j++) ! 276: argstrings[j] ! 277: = EQ (visargs[j], Qnil) ! 278: ? (unsigned char *) "" ! 279: : XSTRING (visargs[j])->data; ! 280: ! 281: doprnt (prompt, sizeof prompt, prompt1, j - 1, argstrings + 1); ! 282: ! 283: switch (*tem) ! 284: { ! 285: case 'a': /* Symbol defined as a function */ ! 286: visargs[i] = Fcompleting_read (build_string (prompt), ! 287: Vobarray, Qfboundp, Qt, Qnil); ! 288: /* Passing args[i] directly stimulates compiler bug */ ! 289: teml = visargs[i]; ! 290: args[i] = Fintern (teml, Qnil); ! 291: break; ! 292: ! 293: case 'b': /* Name of existing buffer */ ! 294: args[i] = Fcurrent_buffer (); ! 295: if (EQ (selected_window, minibuf_window)) ! 296: args[i] = Fother_buffer (args[i]); ! 297: args[i] = Fread_buffer (build_string (prompt), args[i], Qt); ! 298: break; ! 299: ! 300: case 'B': /* Name of buffer, possibly nonexistent */ ! 301: args[i] = Fread_buffer (build_string (prompt), ! 302: Fother_buffer (Fcurrent_buffer ()), Qnil); ! 303: break; ! 304: ! 305: case 'c': /* Character */ ! 306: message1 (prompt); ! 307: args[i] = Fread_char (); ! 308: /* Passing args[i] directly stimulates compiler bug */ ! 309: teml = args[i]; ! 310: visargs[i] = Fchar_to_string (teml); ! 311: break; ! 312: ! 313: case 'C': /* Command: symbol with interactive function */ ! 314: visargs[i] = Fcompleting_read (build_string (prompt), ! 315: Vobarray, Qcommandp, Qt, Qnil); ! 316: /* Passing args[i] directly stimulates compiler bug */ ! 317: teml = visargs[i]; ! 318: args[i] = Fintern (teml, Qnil); ! 319: break; ! 320: ! 321: case 'd': /* Value of point. Does not do I/O. */ ! 322: XFASTINT (args[i]) = point; ! 323: /* visargs[i] = Qnil; */ ! 324: varies[i] = 1; ! 325: break; ! 326: ! 327: case 'D': /* Directory name. */ ! 328: args[i] = Fread_file_name (build_string (prompt), Qnil, ! 329: current_buffer->directory, Qlambda); ! 330: break; ! 331: ! 332: case 'f': /* Existing file name. */ ! 333: /* On VMS, treat 'f' like 'F', because 'f' fails to work ! 334: for multivalued logical names or for explicit versions. */ ! 335: #ifndef VMS ! 336: args[i] = Fread_file_name (build_string (prompt), ! 337: Qnil, Qnil, Qlambda); ! 338: break; ! 339: #endif ! 340: ! 341: case 'F': /* Possibly nonexistent file name. */ ! 342: args[i] = Fread_file_name (build_string (prompt), ! 343: Qnil, Qnil, Qnil); ! 344: break; ! 345: ! 346: case 'k': /* Key sequence (string) */ ! 347: args[i] = Fread_key_sequence (build_string (prompt)); ! 348: teml = args[i]; ! 349: visargs[i] = Fkey_description (teml); ! 350: break; ! 351: ! 352: case 'm': /* Value of mark. Does not do I/O. */ ! 353: check_mark (); ! 354: /* visargs[i] = Qnil; */ ! 355: XFASTINT (args[i]) = marker_position (current_buffer->mark); ! 356: varies[i] = 2; ! 357: break; ! 358: ! 359: case 'N': /* Prefix arg, else number from minibuffer */ ! 360: if (!NULL (prefix_arg)) ! 361: goto have_prefix_arg; ! 362: case 'n': /* Read number from minibuffer. */ ! 363: do ! 364: args[i] = Fread_minibuffer (build_string (prompt), Qnil); ! 365: while (XTYPE (args[i]) != Lisp_Int); ! 366: visargs[i] = last_minibuf_string; ! 367: break; ! 368: ! 369: case 'P': /* Prefix arg in raw form. Does no I/O. */ ! 370: args[i] = prefix_arg; ! 371: /* visargs[i] = Qnil; */ ! 372: varies[i] = -1; ! 373: break; ! 374: ! 375: case 'p': /* Prefix arg converted to number. No I/O. */ ! 376: have_prefix_arg: ! 377: args[i] = Fprefix_numeric_value (prefix_arg); ! 378: /* visargs[i] = Qnil; */ ! 379: varies[i] = -1; ! 380: break; ! 381: ! 382: case 'r': /* Region, point and mark as 2 args. */ ! 383: check_mark (); ! 384: /* visargs[i+1] = Qnil; */ ! 385: foo = marker_position (current_buffer->mark); ! 386: /* visargs[i] = Qnil; */ ! 387: XFASTINT (args[i]) = point < foo ? point : foo; ! 388: varies[i] = 3; ! 389: XFASTINT (args[++i]) = point > foo ? point : foo; ! 390: varies[i] = 4; ! 391: break; ! 392: ! 393: case 's': /* String read via minibuffer. */ ! 394: args[i] = Fread_string (build_string (prompt), Qnil); ! 395: break; ! 396: ! 397: case 'S': /* Any symbol. */ ! 398: visargs[i] = read_minibuf (Vminibuffer_local_ns_map, ! 399: Qnil, ! 400: build_string (prompt), ! 401: 0); ! 402: /* Passing args[i] directly stimulates compiler bug */ ! 403: teml = visargs[i]; ! 404: args[i] = Fintern (teml, Qnil); ! 405: break; ! 406: ! 407: case 'v': /* Variable name: symbol that is ! 408: user-variable-p. */ ! 409: args[i] = Fread_variable (build_string (prompt)); ! 410: visargs[i] = last_minibuf_string; ! 411: break; ! 412: ! 413: case 'x': /* Lisp expression read but not evaluated */ ! 414: args[i] = Fread_minibuffer (build_string (prompt), Qnil); ! 415: visargs[i] = last_minibuf_string; ! 416: break; ! 417: ! 418: case 'X': /* Lisp expression read and evaluated */ ! 419: args[i] = Feval_minibuffer (build_string (prompt), Qnil); ! 420: visargs[i] = last_minibuf_string; ! 421: break; ! 422: ! 423: default: ! 424: error ("Invalid control letter \"%c\" (%03o) in interactive calling string", ! 425: *tem, *tem); ! 426: } ! 427: ! 428: if (varies[i] == 0) ! 429: arg_from_tty = 1; ! 430: ! 431: if (NULL (visargs[i]) && XTYPE (args[i]) == Lisp_String) ! 432: visargs[i] = args[i]; ! 433: ! 434: tem = (unsigned char *) index (tem, '\n'); ! 435: if (tem) tem++; ! 436: else tem = (unsigned char *) ""; ! 437: } ! 438: ! 439: QUIT; ! 440: ! 441: args[0] = function; ! 442: ! 443: if (arg_from_tty || !NULL (record)) ! 444: { ! 445: visargs[0] = function; ! 446: for (i = 1; i < count + 1; i++) ! 447: if (varies[i] > 0) ! 448: visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil); ! 449: else ! 450: visargs[i] = quotify_arg (args[i]); ! 451: Vcommand_history = Fcons (Flist (count + 1, visargs), ! 452: Vcommand_history); ! 453: } ! 454: ! 455: teml = Ffuncall (count + 1, args); ! 456: UNGCPRO; ! 457: return teml; ! 458: } ! 459: ! 460: DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value, ! 461: 1, 1, 0, ! 462: "Return numeric meaning of raw prefix argument ARG.\n\ ! 463: A raw prefix argument is what you get from (interactive \"P\").") ! 464: (raw) ! 465: Lisp_Object raw; ! 466: { ! 467: Lisp_Object val; ! 468: ! 469: if (NULL (raw)) ! 470: XFASTINT (val) = 1; ! 471: else if (XTYPE (raw) == Lisp_Symbol) ! 472: { ! 473: XFASTINT (val) = 0; ! 474: XSETINT (val, -1); ! 475: } ! 476: else if (CONSP (raw)) ! 477: val = XCONS (raw)->car; ! 478: else if (XTYPE (raw) == Lisp_Int) ! 479: val = raw; ! 480: else ! 481: XFASTINT (val) = 1; ! 482: ! 483: return val; ! 484: } ! 485: ! 486: syms_of_callint () ! 487: { ! 488: Qminus = intern ("-"); ! 489: staticpro (&Qminus); ! 490: ! 491: Qcall_interactively = intern ("call-interactively"); ! 492: staticpro (&Qcall_interactively); ! 493: ! 494: DEFVAR_LISP ("prefix-arg", &Vprefix_arg, ! 495: "The value of the prefix argument for the next editing command.\n\ ! 496: It may be a number, or the symbol - for just a minus sign as arg,\n\ ! 497: or a list whose car is a number for just one or more C-U's\n\ ! 498: or nil if no argument has been specified.\n\ ! 499: \n\ ! 500: You cannot examine this variable to find the argument for this command\n\ ! 501: since it has been set to nil by the time you can look.\n\ ! 502: Instead, you should use the variable current-prefix-arg, although\n\ ! 503: normally commands can get this prefix argument with (interactive \"P\")."); ! 504: Vprefix_arg = Qnil; ! 505: ! 506: DEFVAR_LISP ("current-prefix-arg", &Vcurrent_prefix_arg, ! 507: "The value of the prefix argument for this editing command.\n\ ! 508: It may be a number, or the symbol - for just a minus sign as arg,\n\ ! 509: or a list whose car is a number for just one or more C-U's\n\ ! 510: or nil if no argument has been specified.\n\ ! 511: This is what (interactive \"P\") returns."); ! 512: Vcurrent_prefix_arg = Qnil; ! 513: ! 514: DEFVAR_LISP ("command-history", &Vcommand_history, ! 515: "List of recent commands that read arguments from terminal.\n\ ! 516: Each command is represented as a form to evaluate."); ! 517: Vcommand_history = Qnil; ! 518: ! 519: defsubr (&Sinteractive); ! 520: defsubr (&Scall_interactively); ! 521: defsubr (&Sprefix_numeric_value); ! 522: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.