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);