-*- mode: text; mode: fold; -*-
The purpose of this note is to provide some instructions on extending
the newsreader in its macro language.  It consists of two parts: an
overview of macros and the reference manual for slrn intrinsic
functions.

{{{ Introduction 

The present implementation does not provide many hooks into the
newsreader.  More capabilities will be added in subsequent releases.
      
When slrn is started, it reads the .slrnrc user initialization file.
That file may contain one or more `interpret' commands causing the
newsreader to load the specified S-Lang scripts, e.g.,

    interpret ".slrn.sl"
    interpret "src/slrn/macros/search.sl"

Each script must obey the syntax of the S-Lang language.  See the
slang documentation from www.s-alng.org more more information about
the syntax.

Several pre-written macros are included in the slrn distribution in
the macro subdirectory.


---------------------------------------------------------------------------
Defining Key Macros
---------------------------------------------------------------------------

    Although one is able to bind keys to specific functions via lines
    of the form
    
         setkey group "refresh_groups"  "G"
	 
    in the .slrnrc file, it is not possible to defined more
    complicated actions in this manner.  However, macros can be
    defined by using a S-Lang script.  For example, the
    `refresh_groups' internal function refreshes the newsgroups but it
    does not cause the cursor to move to the top of the newsgroup
    list.  On the other hand, the internal function `bob' moves to the
    top of the list but it does not refresh the groups.  One can
    define a S-Lang function to perform both actions:
    
         define refresh_groups_bob ()
	 {
	     call ("refresh_groups");
	     call ("bob");
	 }
	 
    and bind it to a key:
    
         definekey ("refresh_groups_bob", "g", "group");
	 
    Note: It is not yet possible to write this as:
    
        define refresh_groups_bob ()
	{
	    refresh_groups ();
	    bob ();
	}

    This restriction will be lifted in the future.
    
    The `definekey' function takes 3 arguments:
    
         function to execute
	 keybinding
	 keymap name   ("article" or "group")
	 
    Here is another macro that may be used in article mode.  It
    performs a regular expression search for subjects.
	
	variable Last_Search_Str = "";
	define re_subject_search_forward ()
	{
	   variable str;
	   
	   ERROR_BLOCK
	     {
	       () = header_up (1);
	     }
	
	   !if (header_down (1)) return;
	
	   str = read_mini ("Subject re-search fwd", Last_Search_Str, "");
	
	   !if (strlen (str))
	     return;
	
	   Last_Search_Str = str;
	   !if (re_fsearch_subject (str))
	     error ("Not found.");
	}
	
    To bind it to, e.g., `s' in the article keymap, use:
   
	definekey ("re_subject_search_forward", "s", "article");
    

    Some slrn keyboard functions require a ``prefix argument''.
    Many people find the use of prefix arguments somewhat strange.
    For example, instead of typing `ESC 1 ESC p' to reconstruct a thread,
    one can simply use the function:
    
        define my_recreate_thread ()
	{
	    set_prefix_argument (1);
	    call ("get_parent_header");
	}
	
   Here is a function that pipes the current article to a
   command called `most' (a paging program similar to more/less):
   
        define pipe_to_most ()
	{
	    pipe_article ("most");
	}
	definekey ("pipe_to_most", "&", "article");
 
   Here it has been bound to the `&' key.  Most likely one will want
   to pipe the article to a shell script for further processing.
   
   Some of the built-in keyboard functions will prompt for a
   string.  For example, in article mode, pressing the `:' key will
   prompt for an filename.  The function `set_input_string' may be
   used to provide a response to such a prompt, e.g.,
   
      % The `:' command will prompt for a filename.
      set_input_string ("/tmp/decoded");
      call ("decode");

   For functions that prompt for a single character, such as 
   
      Do you really want to quit? [Y]es No
      
   a similar intrinsic function, set_input_chars, may be used to
   provide the answer.
   
   
---------------------------------------------------------------------------
Hooks
---------------------------------------------------------------------------
   
Currently, the newsreader
recognizes the following hooks:

   startup_hook
      This hook is called right after the newsreader is initialized
      and immediately before checking for news.  This hook allows
      the user to set variables on a server by server basis.
      
      Here is an example:
      
         define startup_hook ()
	 {
	   !if (strcmp (server_name (), "uhog"))
	     {
	       set_integer_variable ("lines_per_update", 20);
	       set_integer_variable ("read_active", 0);
	     }
	 }

      It simply sets the `lines_per_update' variable to 20 and turns
      off reading of the active file if the servername is `uhog' (it
      is a slow server).

   group_mode_startup_hook
      This hook is called after checking for news and immediately
      before entering the main keyboard loop.  When called, group mode
      will be active
      
   group_mode_hook
      This hook will be called whenever group mode is entered.  This
      includes the times when one exists article mode back to group
      mode.

   pre_article_mode_hook
      This hook is similar to `article_mode_hook' except that it is
      called before any headers for the group have been retrieved.

   article_mode_hook
      This hook is called during article mode after headers have been
      retrieved but before sorting them.  One can use this hook to set
      variables based on the group name.  For example,

      define article_mode_hook ()
      {
         variable sorting_method = 7;
	 variable author_display = 2;
         variable signature_file = ".signature";
	 
         if (is_substr (current_newsgroup (), "binaries")
	     or is_substr (current_newsgroup (), "pictures"))
	   {
	      sorting_method = 3;
	      author_display = 0;
	   }

	 if (0 == strncmp (current_newsgroup (), "comp.", 5))
	   signature_file = ".nerd-signature";
	   
	 set_integer_variable ("sorting_method", sorting_method);
	 set_integer_variable ("author_display", author_display);
	 set_string_variable ("signature", signature_file);
      }
      
     changes the `sorting_method' and `author_display' variables to
     something more appropriate for newgroups which contain encoded
     articles.

   article_mode_startup_hook
     Unlike article_mode_hook, which gets called prior to sorting the
     headers, this hook gets called after sorting has taken place.

   header_number_hook
     If defined, this function will be called after selecting a header
     via a header number.
  
   read_article_hook
     Function called after reading and processing an article. It may
     use the replace_article function to change it.

   reply_hook
     Function called when replying to poster.
  
   followup_hook
     Function called when following up to an article.
     
   post_hook
     Function called when posting an article.
     
   forward_hook
     Function called when forwarding an article to someone.
     
   resize_screen_hook
     This hook will be called whenever the screen size changes.
     
   post_filter_hook
     This hook may be called just before slrn attempts to post a file.
     The hook is only called if the user selects the filter option
     from the prompt:
     
         Post the message? Yes, No, Edit, poStpone, Filter

     This hook takes a single parameter: the name of the file that
     slrn is about to post.  Thus it must be declared as:
       
       define post_filter_hook (file);
       
     See macros/ispell.sl for an example.
	  
}}}

---------------------------------------------------------------------------
Command Reference
---------------------------------------------------------------------------
The above examples used ``intrinsic'' functions such as `call',
`set_integer_variable', etc.  This section describes all slrn
intrinsic functions that are available via the interpreter.  The code
S-Lang langauge includes many others such as `strcmp' and `is_substr'
which are not described here.

See slrnfuns.txt for detailed information about the slrn intrinsic
functions. 
