jed-users mailing list

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

JED temabbrv doc


Hi!

I prepared some documentation for temabbrv. You can find it here:

http://www.geocities.com/mmarko.geo/jedmacros/temabbrv.html

Also a minor fix to temabbrv.

I would need some suggestions for the kind of macros that should
be defined for temabbrev by default, for any mode.
A small number of macros can be found here:

http://www.geocities.com/mmarko.geo/jedmacros/template.zip

Any idea is wellcome.

I would also like some ideas about how to improve temabbrv.


Marko

%%----temabbrv.sl--------------------------------------------------------
%%     Author: Marko Mahnič  <marko.mahnic@xxxxxx>
%%     Version: 0.95
%%
%%-----------------------------------------------------------------------

%% History:
%%   0.95 Nov 2003
%%     * Search path for template files fixed
%%   0.92 Apr 2003
%%     * Cycle thru multiple expansions
%%     * Template file format changed
%%   0.90 Dec 2002
%%     * First version
%%-----------------------------------------------------------------------

%%
%% 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 ($1, $2, ...)
%%    - cursor positioning ($_)
%%
%% You can define arbitrary templates in template files (.tem).
%% For example, templates for SLang mode are in 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().
%% Create the template directory and put the template files in it:
%%   for example: ~/jed/template/
%%
%% In your jed.rc add:
%%     TEMABBRV_TEMPLATE_DIRS = "~/jed/template";
%%     require ("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.inc  % this will include Something.inc 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
%%    variable TEMABBRV_DEFAULT_ACTION = "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 ("TEMABBRV_DEFAULT_ACTION", "");

%% A comma separated list of directories to search for templates
custom_variable ("TEMABBRV_TEMPLATE_DIRS", NULL);

static variable temLastToken = "";
static variable temExpBegin_point = NULL;
static variable temExpEnd_point = NULL;
static variable temLoadedModes = ".";

static define get_template_buffer(mode)
{
  return sprintf (" %s*templates*", strlow(mode));
}

static define get_token_regexp(token)
{
  return "^@@\\["+ token + "\\]";
}

static define get_token_header(token)
{
  return "@@["+ token + "]";
}

%% Defalut template search path: JED_ROOT and/or JED_HOME, or .
static define tem_default_search_path()
{
  variable libpaths = "";
  variable i, aPaths, tempaths = "";
  if (getenv("JED_ROOT") != NULL)
  {
     libpaths = getenv("JED_ROOT");
     if (strlen(libpaths) > 0)
        libpaths = dircat(libpaths, "lib");
  }
  if (getenv("JED_HOME") != NULL)
     libpaths = getenv("JED_HOME") + "," + libpaths;

  if (libpaths == "") libpaths = ".";

  aPaths = strtok (libpaths, ",");

  for (i = 0; i < length(aPaths); i++)
  {
     tempaths = tempaths + dircat(aPaths[i], "template,");
  }

  return strtrim_end(tempaths, ",");
}

static define tem_load_mode_template (mode)
{
  variable aPaths, file, i, inc;
  variable temBuf, tmpbuf = "*tmp*";

  if (is_substr (temLoadedModes, "." + mode + ".")) return;

  temLoadedModes = temLoadedModes + mode + ".";

  if (TEMABBRV_TEMPLATE_DIRS == NULL)
     TEMABBRV_TEMPLATE_DIRS = tem_default_search_path();

  aPaths = strtok (TEMABBRV_TEMPLATE_DIRS, ",");

  for (i = 0; i < length(aPaths); i++)
  {
     file = dircat(aPaths[i], strlow(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);
           push_spot();
           () = insert_file (inc);
           pop_spot();
        }

    set_buffer_modified_flag (0);
    setbuf (get_template_buffer(mode));
    eob();
    insert ("\n");
    insbuf (tmpbuf);
     }
  }

  if (bufferp (tmpbuf)) delbuf(tmpbuf);
}

static define tem_find_expansion (token, findfirst)
{
  variable mode, buf, temBuf;
  (mode,) = what_mode();
  mode = strlow (mode);
  buf = whatbuf ();

  tem_load_mode_template(mode);
  temBuf = get_template_buffer(mode);

  !if (bufferp (temBuf))
  {
     setbuf (buf);
     return 0;
  }
  else setbuf (temBuf);

  if (findfirst) bob();

  token = get_token_regexp(token);

  eol();
  if (re_fsearch (token))
  {
     setbuf (buf);
     return 1;
  }

  bob ();
  setbuf (buf);

  return 0;
}

%!%+
%\function{tem_expand_template}
%\synopsis{Integer_Type tem_expand_template (token)}
%\description
%   Expands the last found template
%\returns
%   0 error
%   1 template expanded
%   2 template expanded, parameters inserted
%!%-
static define tem_expand_template (token)
{
  variable mode, buf, i, temBuf;
  variable options = "", expand = "", indent = 0;
  variable OptArray;
  variable bExpandArgs;

  (mode,) = what_mode();
  mode = strlow (mode);
  buf = whatbuf ();

  temBuf = get_template_buffer(mode);
  !if (bufferp(temBuf)) return 0;

  setbuf (temBuf);
  !if (looking_at (get_token_header(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_sans_update_hook(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();

  if (bExpandArgs) return 2;

  return 1;
}

static define remove_last_expansion ()
{
  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;
}

define temabbrev()
{
  variable fun_type, fun, rvExpand;
  variable first_time = 1;
  variable tokenChars = "a-z0-9_";

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

  if (eolp ())
  {
     push_spot();
     push_mark();
     bskip_chars(tokenChars);
     temLastToken = bufsubstr();
     pop_spot();
  }

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

  forever
  {
     fun_type = -1;

     !if (tem_find_expansion (temLastToken, first_time))
     {
        !if (first_time)
        {
           remove_last_expansion();
           insert (temLastToken);
           update_sans_update_hook (1);   %  force update
        }

        vmessage ("No more completions for '%s'", temLastToken);

        break; % forever
     }
     else
     {
        if (first_time)
        {
           push_mark();
           bskip_chars(tokenChars);
           del_region();
        }
        else remove_last_expansion();

        rvExpand = tem_expand_template (temLastToken);
        update_sans_update_hook (1);      %  force update

        if (rvExpand == 2) break;
     }

     (fun_type, fun) = get_key_binding ();

     if (fun != "temabbrev")
        break; % forever

     first_time = 0;
  }


  if (fun_type > 0) call (fun);
  else if (fun_type == 0) eval (fun);
}

provide ("temabbrv");






--------------------------
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]