%% help.sl

%% apropos function
define apropos()
{
   variable n, cbuf, s;
   if (MINIBUFFER_ACTIVE) return;

   s = read_mini("apropos:", Null_String, Null_String);
   n = slapropos(s);
   cbuf = whatbuf();
   pop2buf("*apropos*");
   erase_buffer();
   loop (n) 
     {
	insert(());
	newline();
     }
   buffer_format_in_columns();   
   bob();
   set_buffer_modified_flag(0);
   pop2buf(cbuf);
}



. ( [key] =key
.   [n str] key strlen =n
.   [i ch key_string] 1 =i Null_String =key_string
  
.   {i n <=}
.   {
.      key i 1 substr int =ch
.      ++i
.      ch {'^' == i n <= and ch 32 < or:  %% control char
          %% common cases are '^[, ^[[?, ^[O?'
	  
. 	  ch 32 < {ch '@' + char key i 2 substr strcat =str --i}
. 	          {key i 3 substr =str}
. 		else
		
. 	  str int '[' == 
. 	  {
. 	     3 +=i
. 	     str { "[[A" strcmp not : "UP" }
. 	         { "[[B" strcmp not : "DOWN" }
. 		 { "[[C" strcmp not : "RIGHT" }
. 		 { "[[D" strcmp not : "LEFT" }
. 		 { "[OP" strcmp not : "GOLD" }
. 		 { "[OA" strcmp not : "UP" }
. 		 { "[OB" strcmp not : "DOWN" }
. 		 { "[OC" strcmp not : "RIGHT" }
. 		 { "[OD" strcmp not : "LEFT" }
. 		 { pop "ESC" 2 -=i}
. 	       switch
. 	  }{
. 	     ++i
. 	     "Control-" str int char strcat
. 	  } else
. 	}{ char } 
.       switch
.       key_string strlen {key_string " " strcat =key_string} if
.       key_string exch strcat =key_string
.     } while
.   key_string
. ) expand_keystring


%% show key
define showkey()
{
   variable f, type;
   flush("Show Key: ");
   f = get_key_function();        %% also, type is on stack (if defined)
   !if (strlen(f)) {message("Key is undefined."); return; }
   =type;
   
   strcat("Key \"", expand_keystring(LASTKEY));
   strcat( (), "\" runs ");
   if (type) "internal "; else "S-Lang ";
   strcat ((), ());
   strcat ((), "function ");
   strcat ((), f);
   message(());
}

. (
.    [n cmd]
.    MINIBUFFER_ACTIVE {return} if
.    "Where is command:" Null_String Null_String 'F' read_with_completion =cmd
.    cmd strlen { return } !if
.    cmd which_key =n
.    n {"Not on any keys." message return} !if
.    expand_keystring message
.    --n
.    n { pop } loop
. ) where_is

%%
%%  This next functions requires a doc file to be produced.  This is made
%%  by running the executable mkdoc which comes with the distribution.
%%
%%  to produce it. It should be placed in JED_LIBRARY.
%%

. ( %% clean up %%% stuff
.   bob
.   {1 down}{bol skip_white "%!%" looking_at {del del del} if} while
.   0 set_buffer_modified_flag
.   1 set_readonly
.   bob
. ) help_cleanup

%% gets help for a function
. (
.   [f] =f
.   [cbuf] whatbuf =cbuf
.   [flen tmp help full_f cbuf]  " *jed-help*" =tmp 
 
.   f strlen =flen
.   "*function-help*" =help  
.   [docfile] "jed_funs.hlp" =docfile
.   [p n]
  
.   docfile expand_jedlib_file =docfile 
.   docfile strlen  { "Unable to read docfile!" error} !if

.   f is_defined 
.     { f 1 }
.     { f slapropos }
.    else
.    =n
.   n 1 > {"Building list..." flush} if
.   help pop2buf 0 set_readonly erase_buffer
  
.   n {
.       =full_f
.       f full_f flen strncmp %%flen and 
.       {continue} if
  
.       full_f is_defined 1 < {continue} if
.       "F" full_f strcat docfile get_doc_string 
.         {  
. 	   push_spot
. 	   insert  %% help string
. 	   pop_spot
. 	   ":" ffind  %% function:cfun:T:n  where T is type and n is number of args
. 	     {
. 	       1 right pop "\tC function: " insert
. 	       POINT =p ":" ffind {"Corrupt doc file?" error} !if
. 	       push_spot 1 right pop 
. 	       what_char
. 	         { 'V' == : "void "}   % V
. 		 { 'S' == : "string "} % S
. 		 { pop "int "}            % I default
. 	       switch p =POINT insert pop_spot
       
.                del del del  % :T: deleted
. 	       " (" insert eol trim " args)" insert
. 	     } if
. 	} { full_f insert} 
.       else
.       eob newline 50 {'-' insert_char} loop newline
.     } loop
      
.   n 1 > {"Building list...done." flush} if
.   help_cleanup
.   cbuf pop2buf  
. ) help_for_function

. (  
.   MINIBUFFER_ACTIVE {return} if
.   "Describe Function:" Null_String Null_String read_mini help_for_function
. ) describe_function


. (
.   [tmp help f full_f cbuf]  " *jed-help*" =tmp 
.   "*function-help*" =help  
.   whatbuf =cbuf
.   [docfile] "jed_funs.hlp" =docfile
.   [p flen n]

.   MINIBUFFER_ACTIVE {return} if
.   "Describe Variable:" Null_String Null_String read_mini =f
.   f strlen =flen %%flen {return} !if
  
.   docfile expand_jedlib_file =docfile 
.   docfile strlen  { "Unable to read docfile!" error} !if
  
.   f slapropos =n
.   n 1 > {"Building list..." flush} if
.   help pop2buf 0 set_readonly erase_buffer
  
.   n {
.       =full_f
.       f full_f flen strncmp %%flen and 
.       {continue} if
  
.       full_f is_defined -1 > {continue} if
.       "V" full_f strcat " " strcat docfile get_doc_string
.         {  
. 	   push_spot
. 	   insert  %% help string
. 	   pop_spot
. 	} { full_f insert} 
.       else
       
.       eol trim "\tvalue: " insert full_f eval string insert
      
.       eob newline 50 {'-' insert_char} loop newline
.     } loop
    
    
.   newline
.   help_cleanup
.   cbuf pop2buf
. ) describe_variable


. (
.   [flags modstr]
.   whatmode =flags =modstr
.   modstr {strlen not : "no_mode" =modstr}
.          {is_defined not : 
. 	        modstr strlow =modstr
. 		modstr is_defined
. 		 {
. 		   modstr "_mode" strcat =modstr
. 		 } !if
. 	  }
.        switch 
.   modstr is_defined 
.    {
.      flags  { 1 == :  "text_mode" }
.             { 2 & :  "c_mode" }
.             { pop "no_mode" =modstr} 
. 	 switch
.    } !if
   
.   modstr help_for_function
. ) describe_mode


define describe_bindings ()
{
   flush("Building bindings..");
   variable map = what_keymap ();
   variable buf = whatbuf ();
   variable case = CASE_SEARCH;  CASE_SEARCH = 1;
   pop2buf("*KeyBindings*");
   erase_buffer ();
   dump_bindings (map);
   bob(); replace ("ESC [ A", "UP");
   bob(); replace ("ESC [ B", "DOWN");
   bob(); replace ("ESC [ C", "RIGHT");
   bob(); replace ("ESC [ D", "LEFT");
   bob(); replace ("ESC O P", "GOLD");
   bob();
   CASE_SEARCH = case;
   set_buffer_modified_flag(0);
   pop2buf (buf);
   message ("done");
}

	    
   
