jed-users mailing list

[2003 Date Index] [2003 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

Template expansion


Hello!

Here is a mode that might be usefull. Instructions are in the code.
Two template file examples are appended.

Marko

-------------------temabbrv.sl----------------------------------------
%% temabbrv.sl - Template abbreviations
%%     Author: Marko Mahnič  <marko.mahnic@xxxxxxxx>
%%     Version: 0.9
%%     Create:  December 2002
%%     Change:  March 2003
%% 
%% Takes the current word (only at eol) and expands it if the word 
%% expansion is defined for current mode. If the same word is defined
%% many times, cycles thru all definitions.
%% 
%% If a template contains parameters, the user is prompted for 5 seconds
%% to press '!' and start expanding parameters. If any other key is pressed
%% parameter expansion is skipped.
%%
%% Some simple postprocessing of expanded text is supported:
%%    - indentation
%%    - parameter replacement
%%    - cursor positioning
%%    
%% You can define arbitrary templates in template files (.tem). The files
%% are stored in /template directories on library search path. Templates
%% for SLang mode are in .../template/SLang.tem.
%%
%% Template files can include other template files (but only from their
%%  own directory).
%% 
%% --------------------------------------------------------------------
%% Installation:
%% 
%% Put temabbrv.sl in any directory that is in get_jed_library_path()
%% In your jed.rc add:
%%     autoload ("temabbrev", "temabbrv");
%%     
%% To define the keybinding:
%%     local_setkey ("temabbrev", "\t");         % in mode startup hook
(preferred)
%%     or
%%     setkey   ("temabbrev", "\t");             % golobal keymap, jed.rc
%%     or
%%     definekey ("temabbrev", "\t", keymap);    % mode keymap, XXmode.sl
%% TAB key might be a good idea, but you can use your own keybinding.
%% 
%% eg. 
%%    slang_mode_hook ()
%%    {
%%       local_setkey ("temabbrev", "\t");
%%    }
%%       
%% Create the /template directory in .../jed/lib or in any directory that is
%% in get_jed_library_path().
%% 
%% Create the .tem files in /template directory for the modes you desire
%% (for SLang you create SLang.tem).
%%
%% --------------------------------------------------------------------
%% Template example (comments are not part of template):
%% 
%% @@#INCLUDE Something  % this will include Something.tem on current path
%% 
%% @@[if]                % Beginning of definition (@@[),  template name
(if)
%% if ($_)               % $_ after processing, place the cursor here ($_ is
deleted)
%% {
%%    sth = $1;
%% }
%% @@: I+, $1 sth value  % end of definition (@@:), options (comma
delimited): 
%%                       %   I+              indent after insertion
%%                       %   $1 sth value    Prompt for value of $1 during
expansion
%%
%% --------------------------------------------------------------------
%% In jed.rc you can use
%%    custom_variable ("temabbrevDefaultAction", "indent_line");
%% if you wish to indent the line when temabbev fails to expand the word.
%% This way you can have indentation and expansion on the same key (TAB).
custom_variable ("temabbrevDefaultAction", "");

static variable temBuf = "*templates*";
static variable temLastToken = "";
static variable temExpBegin_point = NULL;
static variable temExpEnd_point = NULL;
static variable temLoadedModes = ".";

static define tem_load_mode_template (mode)
{
   variable libpaths, aPaths, file, i, inc;
   variable tmpbuf = "*tmp*";
   
   if (is_substr (temLoadedModes, "." + mode + ".")) return;

   temLoadedModes = temLoadedModes + mode + ".";
   
   libpaths = get_jed_library_path ();
   aPaths = strtok (libpaths, ",");
   
   for (i = 0; i < length(aPaths); i++)
   {
      file = dircat(aPaths[i], "template/" + mode + ".tem");
      if (1 == file_status (file))
      {
	 setbuf (tmpbuf);
	 erase_buffer();
	 () = insert_file (file);
	 bob();
         
         %% Include other files
         while (re_fsearch ("@@#INCLUDE"))
         {
            go_right (10);
            push_mark();
            eol();
            inc = bufsubstr();
            delete_line();
            bol();
            inc = str_delete_chars(inc, " \t\n");
            inc = dircat (path_dirname(file), inc + ".tem");
            push_spot();
            () = insert_file (inc);
            pop_spot();
         }
         
         %% Mark abbrev tags
	 while (re_fsearch ("^@@\\["))
	 {
	    go_right (3);
	    insert (strlow (mode) + "->");
	    eol();
	 }
	 set_buffer_modified_flag (0);
	 setbuf (temBuf);
	 eob();
	 insert ("\n");
	 insbuf (tmpbuf);
      }
   }
   
   if (bufferp (tmpbuf)) delbuf(tmpbuf);
}

static define tem_find_expansion (token)
{
   variable mode, buf;
   (mode,) = what_mode();
   mode = strlow (mode);
   buf = whatbuf ();
   
   tem_load_mode_template(mode);
   
   !if (bufferp (temBuf))
   {
      setbuf (buf);
      return 0;
   }
   else setbuf (temBuf);

   if (LAST_KBD_COMMAND != "temabbrev") bob();
   
   token = "^@@\\[" + mode + "->" + token + "\\]";
   
   eol();
   if (re_fsearch (token)) 
   {
      setbuf (buf);
      return 1;
   }
   
   bob ();
   setbuf (buf);
   
   return 0;
}

static define tem_expand_template (token)
{
   variable mode, buf, i;
   variable options = "", expand = "", indent = 0;
   variable OptArray;
   variable bExpandArgs;
   
   (mode,) = what_mode();
   mode = strlow (mode);
   buf = whatbuf ();
   
   setbuf (temBuf);
   !if (looking_at ("@@[" + mode + "->" + token + "]"))
   {
      setbuf (buf);
      return 0;
   }

   %% Find expansion
   go_down (1);
   bol();
   push_mark();
   i = 0;
   while (not looking_at("@@:") and not eobp())
   {
      go_down (1);
      i++;
   }
   
   if (i > 0)
   {
      go_up(1);
      eol();
      expand = bufsubstr();
      go_down(1);
      bol();
   }
   else
   {
      expand = "";
      pop_mark(0);
   }
   
   %% Process options
   if (looking_at("@@:"))
   {
      go_right (3);
      push_mark ();
      eol ();
      options = bufsubstr();
      OptArray = strtok(options, ",");
      for (i = 0; i < length (OptArray); i++)
      {
	 OptArray[i] = strtrim (OptArray[i]);
	 if (OptArray[i] == "I+") indent = 1;
	 else if (OptArray[i] == "I-") indent = 0;
      }
   }
   
   setbuf (buf);
   push_mark();
   temExpBegin_point = create_user_mark();
   insert (expand);
   temExpEnd_point = create_user_mark();
   narrow_to_region ();
   bob ();

   bExpandArgs = 0;
   if (re_fsearch ("\\$[1-9]"))
   {
      bob(); push_mark(); eob(); widen_region();
      update(1);
      narrow_to_region ();
      flush("Press '!' to expand parameters");
      if (input_pending (50))
      {
         variable ch = getkey();
         if (ch == '!') bExpandArgs = 1;
         else ungetkey(ch);
      }
      message("");
   }
   
   %% Expand parameters
   if (bExpandArgs)
   {
      bob();
      while (re_fsearch ("\\$[1-9]"))
      {
         push_mark ();
         go_right (2);
         variable param = bufsubstr();
         variable prompt = param, repl = "";

         for (i = 0; i < length (OptArray); i++)
         {
            if (1 == is_substr (OptArray[i], param))
            {
               prompt = OptArray[i];
               break;
            }
         }

         repl = read_mini (prompt + ":", "", "");
         bob ();
         replace (param, repl);
      }
   }
   
   %% Place the cursor to the marked position or eob
   bob();
   if (fsearch ("$_")) deln(2);
   else eob();
   push_spot ();

   if (indent)
   {
      bob();
      push_mark ();
      eob();
   }
   
   widen_region();
   
   if (indent and markp()) % indent inserted region
   {
      check_region (0);
      variable endl = what_line();
      exchange_point_and_mark();
      variable line = what_line();
      pop_mark(0);
      
      do {
         indent_line ();
         eol(); trim();
         line++;
      }
      while (down(1) and line <= endl);
   }

   pop_spot();
   return 1;
}

define temabbrev ()
{
   variable first_time = 1;
   
   if (LAST_KBD_COMMAND == "temabbrev" and temLastToken != "")
   {
      if (temExpBegin_point != NULL and temExpEnd_point != NULL)
      {
         goto_user_mark(temExpBegin_point);
         push_mark();
         goto_user_mark(temExpEnd_point);
         del_region();
         temExpBegin_point = NULL;
         temExpEnd_point = NULL;
      }
      
      first_time = 0;
   }
   else
   {
      temLastToken = "";
      temExpBegin_point = NULL;
      temExpEnd_point = NULL;
      
      if (eolp ()) 
      {
         push_spot();
         push_mark();
         bskip_chars("a-z0-9_");
         temLastToken = bufsubstr();
         pop_spot();
      }
      
      first_time = 1;
   }

   if (temLastToken == "")
   {
      if (temabbrevDefaultAction != "") 
         call (temabbrevDefaultAction);
      return;
   }

   if (tem_find_expansion (temLastToken))
   {
      if (first_time)
      {
         push_mark();
         bskip_chars("a-z");
         del_region();
      }
      tem_expand_template (temLastToken);
   }
   else
   {
      vmessage ("No more completions for '%s'", temLastToken);
      
      !if (first_time) insert (temLastToken);

      temLastToken = "";
      temExpBegin_point = NULL;
      temExpEnd_point = NULL;
   }
}

provide ("temabbrv");
----------------------------------------------------------------------

-------------------template/SLang.tem------------------------------
@@#INCLUDE CSlang


@@[switch]
switch ($_)
   { case: ;}
   {} 
@@:I+


@@[def]
define $_()
{
}
@@:I+


@@[sdef]
static define $_()
{
}
@@:I+


@@[pdef]
public define $_()
{
}
@@:I+


@@[sldoc]
%!%+
%\function{$_}
%\synopsis{}
%\usage{}
%\description
%  
%!%-
@@:I+

----------------------------------------------------------------------

-------------------template/CSlang.tem--------------------------------
@@[for]
for ($_)
{
}
@@:I+

@@[for]
for ($_;;)
{
}
@@:I+

@@[if]
if ($_)
@@:I+

@@[if]
if ($_)
{
}
@@:I+

@@[if]
if ($_)
{
}
else
{
}
@@:I+

@@[while]
while ($_)
{
}
@@:I+
----------------------------------------------------------------------


--------------------------
To unsubscribe send email to <jed-users-request@xxxxxxxxxxx> with
the word "unsubscribe" in the message body.
Need help? Email <jed-users-owner@xxxxxxxxxxx>.


[2003 date index] [2003 thread index]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]