-*- mode: text; mode: fold; -*- The purpose of this note is to provide some instructions on extending the newsreader in its macro language. It also contains a list of all hooks that currently can be used. {{{ Introduction 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-lang.org more more information about the syntax. Several pre-written macros are included in the slrn distribution in the macro subdirectory and many more are available from various pages all over the web. }}} --------------------------------------------------------------------------- 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"); 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. article_mode_quit_hook This function is called whenever you leave article mode. 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. forward_hook Function called when forwarding an article to someone. followup_hook Function called when following up to an article. supersede_hook Function called when superseding an article. post_hook Function called when posting an article. 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); post_file_hook Function called after composing and filtering, but before posting article. See macros/ispell.sl for an example. make_from_string_hook This function is expected to leave a string on the stack which will be used to generate ``From'' header lines whenever one is needed. A simple example: define make_from_string_hook () { return "My Name <me@my.machine>" } cc_hook This hook is called when sending a "courtesy copy" of a followup -- it gets the author's email address as an argument and is expected to leave a string on the stack which will be used as the address the CC is actually sent to. If the returned string is empty, no CC is sent. resize_screen_hook This hook will be called whenever the screen size changes. subject_compare_hook slrn threads postings with identical subjects. This hook can be used to override slrn's decision that two subjects are not identical: In this case, it is called with both subjects as arguments. If it returns 0, the articles are put in the same thread. }}} --------------------------------------------------------------------------- Command Reference --------------------------------------------------------------------------- The above examples used ``intrinsic'' functions such as `call', `set_integer_variable', etc. A description of all slrn intrinsic functions that are available via the interpreter is included in slrnfuns.txt. The S-Lang language includes many others such as `strcmp' and `is_substr' which are described in the file slangfun.txt that comes with S-Lang itself.