require("view");
require("slruby");
ifnot(_featurep("rbhelp"))
{
   rb_load_file(dircat(path_dirname(__FILE__), "rb_help.rb"));
}
provide("rbhelp");
private variable ridriver = rb_call_function("rubyhelp");
private variable the_class = "";
private define mouse_hook();
private variable history = {};
private variable mode="rbhelp";

private define rb_help_mode();

define rb_help(subj)
{
   if (typeof(subj) != String_Type)
     throw RunTimeError, "Usage: rb_help(string)";
   variable tmpbuf = make_tmp_buffer_name("rb_help");
   setbuf(tmpbuf);
   try
     {
	()=ridriver.get_info_for(subj);
	set_buffer_modified_flag(0);
	pop2buf("Ruby help");
	set_readonly(0);
	mark_buffer();
	del_region();
	insbuf(tmpbuf);
	the_class=subj;
	list_insert(history, subj);
	rb_help_mode();
	bob();
     }
   finally
     {
	delbuf(tmpbuf);
     }
}

private define back()
{
   if (length(history) > 1)
     {
	list_delete(history, 0);
	rb_help(list_pop(history));
     }
}

private define rb_follow()
{
   _pop_n(_NARGS);
   push_spot();
   bskip_chars("a-zA-Z#:_.?");
   push_mark();
   pop_spot();
   push_spot();
   skip_chars("a-zA-Z#:_.?");
   variable word = bufsubstr();
   pop_spot();
   if (strlen(the_class)
       && not is_substr(word, "#")
       && not is_substr(word, "::"))
     {
	try
	  {
	     rb_help(sprintf("%s::%s", the_class, word));
	  }
	catch RunTimeError:
	  {
	     try
	       {
		  rb_help(sprintf("%s#%s", the_class, word));
	       }
	     catch RunTimeError:
	       {
		  rb_help(word);
	       }
	  }
     }
   else
     rb_help(word);
   return 0;
}

private define mouse_hook(l,c,b,s)
{
   rb_follow();
   return 0;
}

!if (keymap_p(mode))
{
   copy_keymap(mode, "view");
   definekey(&back, "l", mode);
   definekey(&rb_follow, "^M", mode);
}

private define rb_help_mode()
{
   set_readonly(1);
   set_buffer_modified_flag(0);
   set_mode(mode, 0);
   use_keymap(mode);

   _set_buffer_flag(0x1000);
   set_buffer_hook("mouse_up", &mouse_hook);
}
