/* The srchlist command finds all occurences of a pattern in a file, and */
/* displays all lines which contain that pattern in another window. */

init()
{
  assign_key("srchlist", 19);   /* CTRL-S */
}


srchlist()
{
  string pattern;               /* pattern to search for */
  string foo, line;
  int temp_buf, old_buf;        /* buffer ids */
  int found;

  found = 0;                    /* boolean to record if we found any matches */
  old_buf = currbuf();
  temp_buf = create_buffer("$$$list$");   /* create a new buf to hold matches */

  /* Go to the beginning of the file in order to start the matching. */
  save_position();
  gobof();

  /* Prompt the user for the pattern to search for. */
  pattern = get_tty_str("Pattern : ");
  if (strlen(pattern) < 1)  return;

  while (fsearch(pattern))
  {
    found = found + 1;          /* found a match!!! */
    line = sprintf("%d: %s\n", currlinenum(), currline());

    /* Insert the matched line (with its line number) in the temp buffer */
    setcurrbuf(temp_buf);
    goeof();
    insert(line);

    /* Go back to the file and resume matching at the next line. */
    setcurrbuf(old_buf);
    if (!down())  break;
    gobol();
  }

  if (found == 0)
    foo = get_tty_str("Pattern not found");
  else
    interact(temp_buf, old_buf);

  /* Get rid of the temp buffer and go back to the file */
  delete_buffer(temp_buf);
  show_buffer(old_buf);
  clear_mark();         /* remove all line marks in the buffer */
  restore_position();
}


/* This is a nice little touch. The user can move up and down the temp buffer, */
/* and when the user hits <RETURN>, the corresponding line in the original */
/* file will be highlighted. */
interact(new_id, old_id)
  int new_id;
  int old_id;
{
  int c, n;

  /* Get rid of the blank last line, and move to the first line. */
  show_buffer(new_id);
  goeof();
  delline();
  gobof();
  show_line(new_id, old_id);
  show_help_message();

  while ((c = get_tty_char()) != '\E')          /* <ESC> ends it all */
  {
    if (c == 200)               /* <UP> */
      up();
    else if (c == 208)          /* <DOWN> */
      down();
    else if (c == '\n')         /* We picked a line to view */
      show_line(new_id, old_id);
    show_help_message();
  }
}


/* This routine goes to the old file, and highlights the line you picked. */
show_line(new_id, old_id)
  int new_id;
  int old_id;
{
  int n;

  n = atoi(currline());         /* extract the line number of the line */
  if (n > 0)
  {
    show_buffer(old_id);        /* Go to the original file */
    goline(n);                  /*  and move to the desired line. */
    clear_mark();               /* get rid of old highlighting */
    markline();                 /* Highlight the line */
    refresh();                  /* make sure the cursor line catches up */
    show_buffer(new_id);        /* Go back to the temp window. */
  }
}

show_help_message()
{
  message(
  "Use the UP and DOWN keys to navigate, <ENTER> to goto line, <ESC> to exit");
}
