Re: Refresh List of Articles

"J.B. Nicholson" <[email protected]> Mon, 24 Jul 2017 18:08:42 -0500
Newsgroups gmane.network.slrn.user
Message-ID <[email protected]>
Jethro Tull wrote:
> This is a followup to a request made in this mailing list in 2004. It's about
> refreshing the list of articles while being in the headers display.

You can do this with a macro. What follows is a more elaborate macro to 
give the illusion that this only added articles (new articles) to the 
article list you're already looking at (which likely includes read 
articles) and preserving the thread display. Run that and press "G" (or 
change the keybinding at the end). I think there are enough comments and 
human-readable variable names for you to be able to see what's going on in 
the code.

A simpler version would have fewer lines of code but show you only the new 
articles (exiting to group mode, finding the group you were in, fetching 
new article counts, and re-entering that group) and not preserve the thread 
display. I consider this to be an undesirable side-effect so I don't do 
that. I'll leave it to you to implement this with a prefix argument.



define refresh_reenter_group ()
{
    if (is_group_mode ())
      throw UsageError, _function_name () + " only works in article mode!";

    % We don't want any prefix arguments to interfere with any call()s
    % we make. So we record the prefix argument, reset the prefix
    % argument, and restore the prefix argument at the end (in the
    % EXIT_BLOCK).
    variable prefix_arg = get_prefix_arg();
    reset_prefix_arg();
    EXIT_BLOCK
      {
	% Restore the state we modified.
	if (prefix_arg != -1) set_prefix_argument (prefix_arg);
	set_integer_variable ("query_read_group_cutoff", 
starting_query_read_group_cutoff);
      }

    variable
      % Settings we need to change and restore before this function
      % returns.
      starting_query_read_group_cutoff = get_variable_value 
("query_read_group_cutoff"),

      % Initialized for useful initial values.
      starting_article = extract_article_header ("Message-ID"),
      starting_newsgroup = current_newsgroup (),
      article_was_visible_and_current = (_is_article_visible () == 3),

      % Initialized later and generally initialized to indicate type.
      thread_collapse_status = Assoc_Type[Integer_Type],
      thread_was_collapsed = 0,
      article_was_zoomed = is_article_window_zoomed (),
      i = 0,
      t = 0,
      message_ID = "",
      message_ID_set = Assoc_Type[Integer_Type];

    % Store collapse status for unread articles. Threads with all-read
    % articles will disappear when we re-enter the group because read
    % articles won't be around to set collapse status on.
    call ("header_bob");
    do
      {
	t = thread_size ();
	thread_was_collapsed = is_thread_collapsed ();
	message_ID = "";
	message_ID_set = Assoc_Type[Integer_Type];

	uncollapse_thread ();
	for (i = 1; i <= t; i++)
	  {
	     % We track collapse status for all articles.
	     thread_collapse_status[extract_article_header ("Message-ID")] = 
thread_was_collapsed;

	     % We care about how we leave the thread because the user
	     % might be running something in a hook that tracks thread
	     % collapse status.
	     if (i != t) () = header_down (1);
	     else if (thread_was_collapsed) collapse_thread ();
	  }
      }
    % Go to the next thread.
    while (header_down (1));

    % Quit to group mode, refresh the newsgroup list, and re-enter the
    % newsgroup we were in.
    try
      {
	call ("quit");
	call ("refresh_groups");
	set_input_string (starting_newsgroup);
	call ("add_group");
	set_integer_variable ("query_read_group_cutoff", 0);
	call ("select_group");
      }
    catch AnyError:
      {
	if (is_group_mode ())
	  throw InternalError, "Something went horribly wrong and we could not 
re-enter " + starting_newsgroup;
      }

    % Working around a bug here: normally we'd restore the thread
    % display THEN replace the cursor where it was (switching the two
    % next stanzas). But locate_header_by_msgid(m, 1) collapses the
    % thread display. Therefore we restore the thread display /after/
    % all locate_header_by_msgid(m, 1) calls.

    % Put the cursor where it was and restore the article view only if
    % the article wasn't already in the header list.
    if (locate_header_by_msgid (starting_article, 1))
      {
	% Shows/hides the article if that's what we were looking at before.
	if (article_was_visible_and_current != (_is_article_visible () & 1))
	  call ("hide_article");

	% Zooms the article window if the article window was showing
	% the article.
	if ((_is_article_visible () & 1) && article_was_zoomed && 
(is_article_window_zoomed () == 0))
	  call ("zoom_article_window");
      }

    % Fetch from the server all of the articles that were in the
    % article list. This should help convey the illusion that the only
    % effect this macro has is adding new articles to the article list.
    foreach message_ID (thread_collapse_status) using ("keys")
      () = locate_header_by_msgid (message_ID, 1);

    % Restore the thread display and reposition the cursor on the
    % article we were on when this macro began.
    foreach message_ID,thread_was_collapsed (thread_collapse_status) using 
("keys", "values")
      {
	() = locate_header_by_msgid (message_ID, 0);
	if (thread_was_collapsed) collapse_thread ();
	else uncollapse_thread ();
      }
    () = locate_header_by_msgid (starting_article, 0);
}
definekey ("refresh_reenter_group", "G", "article");

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot