- Subject: Template expansion
- From: Marko Mahnič <mmarko.dfg@xxxxxxx>
- Date: Thu, 6 Mar 2003 09:01:22 +0100
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]