Mercurial > octave-nkf
comparison src/oct-hist.cc @ 64:bd04d91a7a4a
[project @ 1993-08-15 05:08:48 by jwe]
(mk_tmp_hist_file): New function, extracted from do_edit_history.
(do_edit_history): Simplify using mk_tmp_hist_file.
(do_run_history): New function.
(edit_history_repl_hist): New function.
author | jwe |
---|---|
date | Sun, 15 Aug 1993 05:08:48 +0000 |
parents | 78fd87e624cb |
children | a500c60e8f23 |
comparison
equal
deleted
inserted
replaced
63:91ab99b0dbae | 64:bd04d91a7a4a |
---|---|
333 line[lindex++] = '\n'; | 333 line[lindex++] = '\n'; |
334 line[lindex++] = '\0'; | 334 line[lindex++] = '\0'; |
335 return line; | 335 return line; |
336 } | 336 } |
337 | 337 |
338 extern "C" | |
339 { | |
340 HIST_ENTRY *history_get (); | |
341 } | |
342 | |
343 /* | |
344 * Use `command' to replace the last entry in the history list, which, | |
345 * by this time, is `run_history blah...'. The intent is that the | |
346 * new command become the history entry, and that `fc' should never | |
347 * appear in the history list. This way you can do `run_history' to | |
348 * your heart's content. | |
349 */ | |
350 static void | |
351 edit_history_repl_hist (char *command) | |
352 { | |
353 if (command == (char *) NULL || *command == '\0') | |
354 return; | |
355 | |
356 HIST_ENTRY **hlist = history_list (); | |
357 | |
358 if (hlist == (HIST_ENTRY **) NULL) | |
359 return; | |
360 | |
361 for (int i = 0; hlist[i]; i++) | |
362 ; // Count 'em. | |
363 i--; | |
364 | |
365 /* History_get () takes a parameter that should be | |
366 offset by history_base. */ | |
367 | |
368 // Don't free this. | |
369 HIST_ENTRY *histent = history_get (history_base + i); | |
370 if (histent == (HIST_ENTRY *) NULL) | |
371 return; | |
372 | |
373 char *data = (char *) NULL; | |
374 if (histent->data != (char *) NULL) | |
375 { | |
376 int len = strlen (histent->data); | |
377 data = (char *) malloc (len); | |
378 strcpy (data, histent->data); | |
379 } | |
380 | |
381 int n = strlen (command); | |
382 | |
383 if (command[n - 1] == '\n') | |
384 command[n - 1] = '\0'; | |
385 | |
386 if (command != (char *) NULL && *command != '\0') | |
387 { | |
388 HIST_ENTRY *discard = replace_history_entry (i, command, data); | |
389 if (discard != (HIST_ENTRY *) NULL) | |
390 { | |
391 if (discard->line != (char *) NULL) | |
392 free (discard->line); | |
393 | |
394 free ((char *) discard); | |
395 } | |
396 } | |
397 } | |
398 | |
338 static void | 399 static void |
339 edit_history_add_hist (char *line) | 400 edit_history_add_hist (char *line) |
340 { | 401 { |
341 if (line != (char *) NULL) | 402 if (line != (char *) NULL) |
342 { | 403 { |
351 | 412 |
352 #define histline(i) (hlist[(i)]->line) | 413 #define histline(i) (hlist[(i)]->line) |
353 | 414 |
354 #define EDIT_COMMAND "${EDITOR:-vi}" | 415 #define EDIT_COMMAND "${EDITOR:-vi}" |
355 | 416 |
356 void | 417 static char * |
357 do_edit_history (int argc, char **argv) | 418 mk_tmp_hist_file (int argc, char **argv, int insert_curr, char *warn_for) |
358 { | 419 { |
359 HIST_ENTRY **hlist; | 420 HIST_ENTRY **hlist; |
360 | 421 |
361 hlist = history_list (); | 422 hlist = history_list (); |
362 | 423 |
367 | 428 |
368 // The current command line is already part of the history list by the | 429 // The current command line is already part of the history list by the |
369 // time we get to this point. Delete it from the list. | 430 // time we get to this point. Delete it from the list. |
370 | 431 |
371 hist_count -= 2; | 432 hist_count -= 2; |
372 remove_history (hist_count); | 433 if (! insert_curr) |
434 remove_history (hist_count); | |
373 hist_count--; | 435 hist_count--; |
374 | 436 |
375 // If no numbers have been specified, the default is to edit the last | 437 // If no numbers have been specified, the default is to edit the last |
376 // command in the history list. | 438 // command in the history list. |
377 | 439 |
407 } | 469 } |
408 | 470 |
409 if (hist_beg < 0 || hist_end < 0 || hist_beg > hist_count | 471 if (hist_beg < 0 || hist_end < 0 || hist_beg > hist_count |
410 || hist_end > hist_count) | 472 || hist_end > hist_count) |
411 { | 473 { |
412 error ("history specification out of range"); | 474 error ("%s: history specification out of range", warn_for); |
413 return; | 475 return (char *) NULL; |
414 } | 476 } |
415 | 477 |
416 if (usage_error) | 478 if (usage_error) |
417 { | 479 { |
418 usage ("edit_history [first] [last]"); | 480 usage ("%s [first] [last]", warn_for); |
419 return; | 481 return (char *) NULL; |
420 } | 482 } |
421 | 483 |
422 if (hist_end < hist_beg) | 484 if (hist_end < hist_beg) |
423 { | 485 { |
424 int t = hist_end; | 486 int t = hist_end; |
428 } | 490 } |
429 | 491 |
430 char *name = tmpnam ((char *) NULL); | 492 char *name = tmpnam ((char *) NULL); |
431 | 493 |
432 fstream file (name, ios::out); | 494 fstream file (name, ios::out); |
495 | |
433 if (! file) | 496 if (! file) |
434 { | 497 { |
435 error ("edit_history: couldn't open temporary file `%s'", name); | 498 error ("%s: couldn't open temporary file `%s'", warn_for, name); |
436 return; | 499 return (char *) NULL; |
437 } | 500 } |
438 | 501 |
439 if (reverse) | 502 if (reverse) |
440 { | 503 { |
441 for (int i = hist_end; i >= hist_beg; i--) | 504 for (int i = hist_end; i >= hist_beg; i--) |
446 for (int i = hist_beg; i <= hist_end; i++) | 509 for (int i = hist_beg; i <= hist_end; i++) |
447 file << histline (i) << "\n"; | 510 file << histline (i) << "\n"; |
448 } | 511 } |
449 | 512 |
450 file.close (); | 513 file.close (); |
514 | |
515 return name; | |
516 } | |
517 | |
518 void | |
519 do_edit_history (int argc, char **argv) | |
520 { | |
521 char *name = mk_tmp_hist_file (argc, argv, 0, "edit_history"); | |
522 | |
523 if (name == (char *) NULL) | |
524 return; | |
451 | 525 |
452 // Call up our favorite editor on the file of commands. | 526 // Call up our favorite editor on the file of commands. |
453 | 527 |
454 ostrstream buf; | 528 ostrstream buf; |
455 buf << EDIT_COMMAND << " " << name << ends; | 529 buf << EDIT_COMMAND << " " << name << ends; |
456 char *cmd = buf.str (); | 530 char *cmd = buf.str (); |
457 | 531 |
458 // Ignore interrupts while we are off editing commands. Should we | 532 // Ignore interrupts while we are off editing commands. Should we |
459 // maybe avoid using system()? There still seems to be a problem with | 533 // maybe avoid using system()? |
460 // properly waiting for emacsclient. | |
461 | 534 |
462 volatile sig_handler *saved_sigint_handler = signal (SIGINT, SIG_IGN); | 535 volatile sig_handler *saved_sigint_handler = signal (SIGINT, SIG_IGN); |
463 system (cmd); | 536 system (cmd); |
464 signal (SIGINT, saved_sigint_handler); | 537 signal (SIGINT, saved_sigint_handler); |
465 | 538 |
466 // Write the commands to the history file since parse_and_execute | 539 // Write the commands to the history file since parse_and_execute |
467 // disables command line history while it executes. | 540 // disables command line history while it executes. |
468 | 541 |
469 file.open (name, ios::in); | 542 fstream file (name, ios::in); |
470 | 543 |
471 char *line; | 544 char *line; |
545 int first = 1; | |
472 while ((line = edit_history_readline (file)) != NULL) | 546 while ((line = edit_history_readline (file)) != NULL) |
473 { | 547 { |
474 | 548 |
475 // Skip blank lines | 549 // Skip blank lines |
476 | 550 |
478 { | 552 { |
479 delete [] line; | 553 delete [] line; |
480 continue; | 554 continue; |
481 } | 555 } |
482 | 556 |
483 edit_history_add_hist (line); | 557 if (first) |
558 { | |
559 first = 0; | |
560 edit_history_repl_hist (line); | |
561 } | |
562 else | |
563 edit_history_add_hist (line); | |
484 } | 564 } |
485 | 565 |
486 file.close (); | 566 file.close (); |
487 | 567 |
488 // Turn on command echo, so the output from this will make better sense. | 568 // Turn on command echo, so the output from this will make better sense. |
492 echo_input = 1; | 572 echo_input = 1; |
493 | 573 |
494 parse_and_execute (name, 1); | 574 parse_and_execute (name, 1); |
495 | 575 |
496 run_unwind_frame ("do_edit_history"); | 576 run_unwind_frame ("do_edit_history"); |
577 | |
578 // Delete the temporary file. Should probably be done with an | |
579 // unwind_protect. | |
580 | |
581 unlink (name); | |
582 } | |
583 | |
584 void | |
585 do_run_history (int argc, char **argv) | |
586 { | |
587 char *name = mk_tmp_hist_file (argc, argv, 1, "run_history"); | |
588 | |
589 if (name == (char *) NULL) | |
590 return; | |
591 | |
592 // Turn on command echo, so the output from this will make better sense. | |
593 | |
594 begin_unwind_frame ("do_run_history"); | |
595 unwind_protect_int (echo_input); | |
596 echo_input = 1; | |
597 | |
598 parse_and_execute (name, 1); | |
599 | |
600 run_unwind_frame ("do_run_history"); | |
497 | 601 |
498 // Delete the temporary file. Should probably be done with an | 602 // Delete the temporary file. Should probably be done with an |
499 // unwind_protect. | 603 // unwind_protect. |
500 | 604 |
501 unlink (name); | 605 unlink (name); |