rlwrap

How do I stop rlwrap --remember from including version and copyright messages in the completion list?


Suppose I am using rlwrap like this: rlwrap --remember sml. That will start Standard ML of New Jersey:

Standard ML of New Jersey v110.79 [built: Sat Oct 26 12:27:04 2019]
- 

If I enter Jer at the prompt and press Tab, rlwrap will complete it to Jersey . I only want completion for the code I enter, not for the lines that contain version information (and/or copyright information). Is there a way to exclude such lines from rlwrap's completion when using --remember?


Solution

  • This is beyond the capabilities of a "vanilla" rlwrap. You can, however, easily achieve what you want with a with an rlwrap filter

    An rlwrap filter defines one or more callbacks ("handlers") that get called with e.g. the wrapped program's input and output lines. The filter can then modify those, or (in your case) feed them into the "completion list" (the list of possible completions). This makes it possible to fine-tune what to complete on:

    #!/usr/bin/env python3
    
    """A demo filter dat does the same as rlwrap's --remember option 
       with a few extra bells and whistles
    
       Save this script as 'remember.py' sowewhere in RLWRAP_FILTERDIR and invoke as follows:
       rlwrap -z remember.py sml 
       N.B. Don't use the --remember option in this case!  
    """
    
    import sys
    import os
    
    if 'RLWRAP_FILTERDIR' in os.environ:
        sys.path.append(os.environ['RLWRAP_FILTERDIR'])
    else:
        sys.path.append('.')
    
    import rlwrapfilter
    
    filter = rlwrapfilter.RlwrapFilter()
    
    filter.help_text = "Usage: rlwrap [-options] -z remember.py <command>\n"\
                       + "a filter to selectively add <command>s in- and output to the completion list "
    
    
    def feed_into_completion_list(message):
      for word in message.split():
        filter.add_to_completion_list(word)
    
    # Input handler: use everything
    def handle_input(message):
      feed_into_completion_list(message)
      return message
    
    filter.input_handler = handle_input
    
    # Output handler: use every output line not containing "Standard ML ..."
    def handle_output(message):
      if "Standard ML of New Jersey" not in message:
        feed_into_completion_list(message)
      return message
    
    filter.output_handler = handle_output
        
    # Start filter event loop:
    filter.run()
    

    In many use cases for --remember you might want to limit what goes into the completion list. If so, this is the way to do it.