summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-07-30 22:43:24 +0000
committerBram Moolenaar <Bram@vim.org>2005-07-30 22:43:24 +0000
commit5a8684e7821a35e371b845b60699df527a855a9f (patch)
treef43514fa375c03008e73c573c1d55d54c00e775e
parent3a6c56e422af98290f81592a1565991d912afcd3 (diff)
downloadvim-5a8684e7821a35e371b845b60699df527a855a9f.zip
updated for version 7.0120
-rw-r--r--runtime/doc/autocmd.txt4
-rw-r--r--runtime/doc/change.txt13
-rw-r--r--runtime/doc/eval.txt113
-rw-r--r--runtime/doc/options.txt62
-rw-r--r--runtime/doc/tags2
-rw-r--r--runtime/menu.vim20
-rw-r--r--src/edit.c139
-rw-r--r--src/proto/eval.pro1
-rw-r--r--src/version.h4
9 files changed, 180 insertions, 178 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index a99f1845a..5a9c36040 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt* For Vim version 7.0aa. Last change: 2005 Jul 21
+*autocmd.txt* For Vim version 7.0aa. Last change: 2005 Jul 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -487,7 +487,7 @@ VimLeave Before exiting Vim, just after writing the
VimLeavePre.
To detect an abnormal exit use |v:dying|.
*EncodingChanged*
-EncodingChanged Fires off when the 'encoding' option is
+EncodingChanged Fires off after the 'encoding' option has been
changed. Useful to set up fonts, for example.
*InsertEnter*
InsertEnter When starting Insert mode. Also for Replace
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 83f50f183..fc0b1c91f 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt* For Vim version 7.0aa. Last change: 2005 Jun 25
+*change.txt* For Vim version 7.0aa. Last change: 2005 Jul 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -682,8 +682,8 @@ For the definition of a pattern, see |pattern|.
*sub-replace-special* *:s\=*
When the {string} starts with "\=" it is evaluated as an expression, see
-|sub-replace-expression|. Otherwise these characters in {string} have a
-special meaning:
+|sub-replace-expression|. You can use that for any special characters.
+Otherwise these characters in {string} have a special meaning:
*:s%*
When {string} is equal to "%" and '/' is included with the 'cpotions' option,
then the {string} of the previous substitute command is used. |cpo-/|
@@ -771,9 +771,12 @@ Be careful: The separation character must not appear in the expression!
Consider using a character like "@" or ":". There is no problem if the result
of the expression contains the separation character.
-Example: >
+Examples: >
:s@\n@\="\r" . expand("$HOME") . "\r"@
-This replaces an end-of-line with a new line containing the value of $HOME.
+This replaces an end-of-line with a new line containing the value of $HOME. >
+
+ s/E/\="\<Char-0x20ac>"/g
+This replaces 'E' characters with an euro sign. Read more in |<Char->|.
4.3 Search and replace *search-replace*
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index d11b77de4..be0b0ec3b 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.0aa. Last change: 2005 Jul 29
+*eval.txt* For Vim version 7.0aa. Last change: 2005 Jul 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3341,14 +3341,14 @@ nr2char({expr}) *nr2char()*
printf({fmt}, {expr1} ...) *printf()*
Return a String with {fmt}, where "%" items are replaced by
the formatted form of their respective arguments. Example: >
- :echo printf("%4d: E%d %.30s", lnum, err, text)
+ printf("%4d: E%d %.30s", lnum, errno, msg)
< May result in:
- 99: E42 asdfasdfasdfasdfasdfasdfasdfas ~
+ " 99: E42 asdfasdfasdfasdfasdfasdfasdfas" ~
Often used items are:
%s string
%6s string right-aligned in 6 characters
- %c character
+ %c single byte
%d decimal number
%5d decimal number padded with spaces to 5 characters
%x hex number
@@ -3362,12 +3362,13 @@ printf({fmt}, {expr1} ...) *printf()*
the result.
The "%" starts a conversion specification. The following
- arguments appear in sequence. Overview:
+ arguments appear in sequence:
- % flags min-field-width .precision type
+ % [flags] [field-width] [.precision] type
+
+ flags
+ Zero or more of the following flags:
- - Zero or more of the following flags:
-
# The value should be converted to an "alternate
form". For c, d, and s conversions, this option
has no effect. For o conversions, the precision
@@ -3378,85 +3379,91 @@ printf({fmt}, {expr1} ...) *printf()*
For x and X conversions, a non-zero result has
the string "0x" (or "0X" for X conversions)
prepended to it.
-
+
0 (zero) Zero padding. For all conversions the converted
value is padded on the left with zeros rather
than blanks. If a precision is given with a
numeric conversion (d, o, x, and X), the 0 flag
is ignored.
-
+
- A negative field width flag; the converted value
is to be left adjusted on the field boundary.
The converted value is padded on the right with
blanks, rather than on the left with blanks or
zeros. A - overrides a 0 if both are given.
-
+
' ' (space) A blank should be left before a positive
number produced by a signed conversion (d).
-
+
+ A sign must always be placed before a number
produced by a signed conversion. A + overrides
a space if both are used.
-
- - An optional decimal digit string specifying a minimum
- field width. If the converted value has fewer characters
- than the field width, it will be padded with spaces on the
- left (or right, if the left-adjustment flag has been
- given) to fill out the field width.
-
- - An optional precision, in the form of a period '.'
- followed by an optional digit string. If the digit string
- is omitted, the precision is taken as zero. This gives
- the minimum number of digits to appear for d, o, x, and X
- conversions, or the maximum number of characters to be
- printed from a string for s conversions.
-
- - A character that specifies the type of conversion to be
- applied, see below.
-
+
+ field-width
+ An optional decimal digit string specifying a minimum
+ field width. If the converted value has fewer
+ characters than the field width, it will be padded
+ with spaces on the left (or right, if the
+ left-adjustment flag has been given) to fill out the
+ field width.
+
+ .precision
+ An optional precision, in the form of a period '.'
+ followed by an optional digit string. If the digit
+ string is omitted, the precision is taken as zero.
+ This gives the minimum number of digits to appear for
+ d, o, x, and X conversions, or the maximum number of
+ characters to be printed from a string for s
+ conversions.
+
+ type
+ A character that specifies the type of conversion to
+ be applied, see below.
+
A field width or precision, or both, may be indicated by an
asterisk '*' instead of a digit string. In this case, a
Number argument supplies the field width or precision. A
negative field width is treated as a left adjustment flag
followed by a positive field width; a negative precision is
treated as though it were missing. Example: >
- :echo printf("%d: %.*s", nr, columns, line)
+ :echo printf("%d: %.*s", nr, width, line)
< This limits the length of the text used from "line" to
- "columns" bytes.
+ "width" bytes.
The conversion specifiers and their meanings are:
-
+
doxX The Number argument is converted to signed decimal
(d), unsigned octal (o), or unsigned hexadecimal (x
and X) notation. The letters "abcdef" are used for
x conversions; the letters "ABCDEF" are used for X
- conversions. The precision, if any, gives the minimum
- number of digits that must appear; if the converted
- value requires fewer digits, it is padded on the left
- with zeros.
-
- c The Number argument is converted to a byte, and
- the resulting character is written.
-
- s The String argument is used. If a precision is
- specified, no more bytes than the number specified are
- written.
-
+ conversions.
+ The precision, if any, gives the minimum number of
+ digits that must appear; if the converted value
+ requires fewer digits, it is padded on the left with
+ zeros.
+ In no case does a non-existent or small field width
+ cause truncation of a numeric field; if the result of
+ a conversion is wider than the field width, the field
+ is expanded to contain the conversion result.
+
+ c The Number argument is converted to a byte, and the
+ resulting character is written.
+
+ s The text of the String argument is used. If a
+ precision is specified, no more bytes than the number
+ specified are used.
+
% A '%' is written. No argument is converted. The
complete conversion specification is "%%".
-
- Each argument can be Number or String and is converted
- automatically to fit the conversion specifier.
- In no case does a non-existent or small field width cause
- truncation of a numeric field; if the result of a conversion
- is wider than the field width, the field is expanded to
- contain the conversion result.
+ Each argument can be Number or String and is converted
+ automatically to fit the conversion specifier. Any other
+ argument type results in an error message.
*E766* *767*
The number of {exprN} arguments must exactly match the number
of "%" items. If there are not sufficient or too many
- arguments an error is given.
+ arguments an error is given. Up to 18 arguments can be used.
prevnonblank({lnum}) *prevnonblank()*
@@ -4242,7 +4249,7 @@ taglist({expr}) *taglist()*
information about these fields. For C code the fields
"struct", "class" and "enum" may appear, they give the name of
the entity the tag is contained in.
-
+
The ex-command 'cmd' can be either an ex search pattern, a
line number or a line number followed by a byte number.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 6c658b08c..b15d7c40f 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 7.0aa. Last change: 2005 Jul 29
+*options.txt* For Vim version 7.0aa. Last change: 2005 Jul 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1584,46 +1584,54 @@ A jump table for the options with a short description can be found at |Q_op|.
'completefunc' 'cfu' string (default: empty)
local to buffer
{not in Vi}
- This option specifies a completion function to be used for CTRL-X
- CTRL-U. The function will be invoked with four arguments:
- a:line the text of the current line
- a:base the text with which matches should match
- a:col column in a:line where the cursor is, first column is
- zero
+ {not available when compiled without the +eval
+ or +insert_expand feature}
+ This option specifies a function to be used for CTRL-X CTRL-U
+ completion. |i_CTRL-X_CTRL-U|
+
+ The function will be invoked with three arguments:
a:findstart either 1 or 0
+ a:col column in the cursor line where the completion ends,
+ first column is zero
+ a:base the text with which matches should match
+
When the a:findstart argument is 1, the function must return the
column of where the completion starts. It must be a number between
- zero and "a:col". This involves looking at the characters in a:line
- before column a:col and include those characters that could be part of
- the completed item.
- When the a:findstart argument is 0 the function must return a string
- with the matching words, separated by newlines. When there are no
- matches return an empty string.
+ zero and "a:col". This involves looking at the characters in the
+ cursor line before column a:col and include those characters that
+ could be part of the completed item. The text between this column and
+ a:col will be replaced with the matches. Return -1 if no completion
+ can be done.
+
+ When the a:findstart argument is 0 the function must return a List
+ with the matching words. These matches should include the "a:base"
+ text. When there are no matches return an empty List.
+
+ The function must not move the cursor!
+
An example that completes the names of the months: >
- fun! CompleteMonths(line, base, col, findstart)
+ fun! CompleteMonths(findstart, col, base)
if a:findstart
- " locate start column of word
+ " locate the start of the word
+ let line = getline('.')
let start = a:col
- while start > 0 && a:line[start - 1] =~ '\a'
- let start = start - 1
+ while start > 0 && line[start - 1] =~ '\a'
+ let start -= 1
endwhile
return start
else
" find months matching with "a:base"
- let res = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
- if a:base != ''
- let res = substitute(res, '\c\<\(\(' . a:base . '.\{-}\>\)\|.\{-}\>\)', '\2', 'g')
- endif
- let res = substitute(res, ' \+', "\n", 'g')
+ let res = []
+ for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
+ if m =~ '^' . a:base
+ call add(res, m)
+ endif
+ endfor
return res
endif
endfun
set completefunc=CompleteMonths
-< Note that a substitute() function is used to reduce the list of
- possible values and remove the ones that don't match the base. The
- part before the "\|" matches the base, the part after it is used
- when there is no match. The "\2" in the replacement is empty if the
- part before the "\|" does not match.
+<
*'confirm'* *'cf'* *'noconfirm'* *'nocf'*
'confirm' 'cf' boolean (default off)
diff --git a/runtime/doc/tags b/runtime/doc/tags
index ac15db663..2700fdc31 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -5162,7 +5162,6 @@ hebrew hebrew.txt /*hebrew*
hebrew.txt hebrew.txt /*hebrew.txt*
help various.txt /*help*
help-context help.txt /*help-context*
-help-tags tags 1
help-translated various.txt /*help-translated*
help-xterm-window various.txt /*help-xterm-window*
help.txt help.txt /*help.txt*
@@ -6752,7 +6751,6 @@ usr_44.txt usr_44.txt /*usr_44.txt*
usr_45.txt usr_45.txt /*usr_45.txt*
usr_90.txt usr_90.txt /*usr_90.txt*
usr_toc.txt usr_toc.txt /*usr_toc.txt*
-utf-16 options.txt /*utf-16*
utf-8 mbyte.txt /*utf-8*
utf-8-char-arg mbyte.txt /*utf-8-char-arg*
utf-8-in-xwindows mbyte.txt /*utf-8-in-xwindows*
diff --git a/runtime/menu.vim b/runtime/menu.vim
index 37bd11ac2..52607235c 100644
--- a/runtime/menu.vim
+++ b/runtime/menu.vim
@@ -2,7 +2,7 @@
" You can also use this as a start for your own set of menus.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2005 Jul 22
+" Last Change: 2005 Jul 30
" Note that ":an" (short for ":anoremenu") is often used to make a menu work
" in all modes and avoid side effects from mappings defined by the user.
@@ -424,22 +424,30 @@ if has("spell")
an 40.335.260 &Tools.&Spelling.Set\ language\ to\ "en_us" :set spl=en_us spell<CR>
an <silent> 40.335.270 &Tools.&Spelling.&Find\ More\ Languages :call <SID>SpellLang()<CR>
+ let s:undo_spellang = ['aun &Tools.&Spelling.&Find\ More\ Languages']
func! s:SpellLang()
- silent! aun &Tools.&Spelling.&Find\ More\ Languages
+ for cmd in s:undo_spellang
+ exe "silent! " . cmd
+ endfor
+ let s:undo_spellang = []
+
if &enc == "iso-8859-15"
let enc = "latin1"
else
let enc = &enc
endif
+
let found = 0
let s = globpath(&rtp, "spell/*." . enc . ".spl")
if s != ""
let n = 300
for f in split(s, "\n")
let nm = substitute(f, '.*spell[/\\]\(..\)\.[^/\\]*\.spl', '\1', "")
- if nm != "en"
- exe 'an 40.335.' . n . ' &Tools.&Spelling.Set\ language\ to\ "' . nm . '" :set spl=' . nm . ' spell<CR>'
+ if nm != "en" && nm !~ '/'
let found += 1
+ let menuname = '&Tools.&Spelling.Set\ language\ to\ "' . nm . '"'
+ exe 'an 40.335.' . n . ' ' . menuname . ' :set spl=' . nm . ' spell<CR>'
+ let s:undo_spellang += ['aun ' . menuname]
endif
let n += 10
endfor
@@ -451,6 +459,10 @@ if has("spell")
else
echomsg "Found " . found . " more spell files"
endif
+ " Need to redo this when 'encoding' is changed.
+ augroup spellmenu
+ au! EncodingChanged * call <SID>SpellLang()
+ augroup END
endfun
endif
diff --git a/src/edit.c b/src/edit.c
index 01a6591f7..26a9a7ca9 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2550,85 +2550,56 @@ ins_compl_next_buf(buf, flag)
}
#ifdef FEAT_COMPL_FUNC
-static char_u *call_completefunc __ARGS((char_u *line, char_u *base, int col, int preproc));
-static int expand_by_function __ARGS((linenr_T lnum, int col, char_u *base, char_u ***matches));
+static int expand_by_function __ARGS((int col, char_u *base, char_u ***matches));
/*
- * Execute user defined complete function 'completefunc'.
- * Return NULL if some error occurs.
+ * Execute user defined complete function 'completefunc', and get matches in
+ * "matches".
+ * Return value is number of matches.
*/
- static char_u *
-call_completefunc(line, base, col, preproc)
- char_u *line;
- char_u *base;
+ static int
+expand_by_function(col, base, matches)
int col;
- int preproc;
+ char_u *base;
+ char_u ***matches;
{
+ list_T *matchlist;
char_u colbuf[30];
- char_u *args[4];
+ char_u *args[3];
+ listitem_T *li;
+ garray_T ga;
+ char_u *p;
- /* Return NULL when 'completefunc' isn't set. */
if (*curbuf->b_p_cfu == NUL)
- return NULL;
+ return 0;
- sprintf((char *)colbuf, "%d", col + (base ? (int)STRLEN(base) : 0));
- args[0] = line;
- args[1] = base;
- args[2] = colbuf;
- args[3] = (char_u *)(preproc ? "1" : "0");
- return (char_u *)call_func_retstr(curbuf->b_p_cfu, 4, args, FALSE);
-}
+ /* Call 'completefunc' to obtain the list of matches. */
+ args[0] = (char_u *)"0";
+ sprintf((char *)colbuf, "%d", col + (int)STRLEN(base));
+ args[1] = colbuf;
+ args[2] = base;
-/*
- * Execute user defined complete function 'completefunc', and get candidates
- * are separeted with "\n". Return value is number of candidates and array
- * of candidates as "matches".
- */
- static int
-expand_by_function(lnum, col, base, matches)
- linenr_T lnum;
- int col;
- char_u *base;
- char_u ***matches;
-{
- char_u *matchstr = NULL;
- char_u *line_copy = vim_strsave(ml_get(lnum));
-
- /* Execute 'completefunc' and get the result */
- matchstr = call_completefunc(line_copy, base, col, 0);
- vim_free(line_copy);
+ matchlist = call_func_retlist(curbuf->b_p_cfu, 3, args, FALSE);
+ if (matchlist == NULL)
+ return 0;
- /* Parse returned string */
- if (matchstr != NULL)
+ /* Go through the List with matches and put them in an array. */
+ ga_init2(&ga, (int)sizeof(char_u *), 8);
+ for (li = matchlist->lv_first; li != NULL; li = li->li_next)
{
- garray_T ga;
- char_u *p, *pnext;
-
- ga_init2(&ga, (int)sizeof(char*), 8);
- for (p = matchstr; *p != NUL; p = pnext)
+ p = get_tv_string_chk(&li->li_tv);
+ if (p != NULL && *p != NUL)
{
- int len;
-
- pnext = vim_strchr(p, '\n');
- if (pnext == NULL)
- pnext = p + STRLEN(p);
- len = pnext - p;
- if (len > 0)
- {
- if (ga_grow(&ga, 1) == FAIL)
- break;
- ((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(p, len);
- ++ga.ga_len;
- }
- if (*pnext != NUL)
- ++pnext;
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+ ((char_u **)ga.ga_data)[ga.ga_len] = vim_strsave(p);
+ ++ga.ga_len;
}
- vim_free(matchstr);
- if (ga.ga_len > 0)
- *matches = (char_u**)ga.ga_data;
- return ga.ga_len;
}
- return 0;
+
+ list_unref(matchlist);
+ *matches = (char_u **)ga.ga_data;
+ return ga.ga_len;
}
#endif /* FEAT_COMPL_FUNC */
@@ -2868,8 +2839,8 @@ ins_compl_get_exp(ini, dir)
#ifdef FEAT_COMPL_FUNC
case CTRL_X_FUNCTION:
- num_matches = expand_by_function(first_match_pos.lnum,
- first_match_pos.col, compl_pattern, &matches);
+ num_matches = expand_by_function(first_match_pos.col,
+ compl_pattern, &matches);
if (num_matches > 0)
ins_compl_add_matches(num_matches, matches, dir);
break;
@@ -3477,31 +3448,33 @@ ins_complete(c)
else if (ctrl_x_mode == CTRL_X_FUNCTION)
{
/*
- * Call user defined function 'completefunc' with line content,
- * cursor column number and preproc is 1. Obtain length of text
- * to use for completion.
+ * Call user defined function 'completefunc' with "a:findstart" is
+ * 1 to obtain the length of text to use for completion.
*/
- char_u *lenstr;
- int keeplen = 0;
- char_u *line_copy = vim_strsave(line);
+ char_u colbuf[30];
+ char_u *args[3];
+ int col;
/* Call 'completefunc' and get pattern length as a string */
- lenstr = call_completefunc(line_copy, NULL, curs_col, 1);
- vim_free(line_copy);
- if (lenstr == NULL)
+ if (*curbuf->b_p_cfu == NUL)
return FAIL;
- keeplen = atoi((char *)lenstr);
- vim_free(lenstr);
- if (keeplen < 0)
+
+ args[0] = (char_u *)"1";
+ sprintf((char *)colbuf, "%d", (int)curs_col);
+ args[1] = colbuf;
+ args[2] = NULL;
+
+ col = call_func_retnr(curbuf->b_p_cfu, 3, args, FALSE);
+ if (col < 0)
return FAIL;
- if ((colnr_T)keeplen > curs_col)
- keeplen = curs_col;
+ compl_col = col;
+ if ((colnr_T)compl_col > curs_col)
+ compl_col = curs_col;
/* Setup variables for completion. Need to obtain "line" again,
* it may have become invalid. */
line = ml_get(curwin->w_cursor.lnum);
- compl_col = keeplen;
- compl_length = curs_col - keeplen;
+ compl_length = curs_col - compl_col;
compl_pattern = vim_strnsave(line + compl_col, compl_length);
if (compl_pattern == NULL)
return FAIL;
@@ -3510,7 +3483,7 @@ ins_complete(c)
else if (ctrl_x_mode == CTRL_X_OCCULT)
{
/* TODO: let language-specific function handle locating the text
- * to be completed or use 'coupler' option. */
+ * to be completed. */
while (--startcol >= 0 && vim_isIDc(line[startcol]))
;
compl_col += ++startcol;
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index db47458b1..7c0ca8402 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -24,6 +24,7 @@ list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
int get_spellword __ARGS((list_T *list, char_u **pp));
typval_T *eval_expr __ARGS((char_u *arg, char_u **nextcmd));
void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
+long call_func_retnr __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *call_func_retlist __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *save_funccal __ARGS((void));
void restore_funccal __ARGS((void *vfc));
diff --git a/src/version.h b/src/version.h
index 13f67c5d5..661dc4f29 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 29)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 29, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 30)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 30, compiled "