jedmodes-2.5.7/0000775000175400017500000000000011702652706011612 5ustar mildegmjedmodes-2.5.7/brief/0000755000175400017500000000000010611416274012673 5ustar mildegmjedmodes-2.5.7/brief/briefmsc.sl0000664000175400017500000003150310567017712015035 0ustar mildegm% utility functions used mostly in BRIEF mode % % 2007-02-11 Marko Mahnic % - moved all functions from brief.sl to briefmsc.sl % provide("briefmsc"); private variable Brief_HomeEnd_Count = 0; % Move the cursor based on the count of succesive function invocation: % 1: move to beginning of line % 2: move to beginning of window % 3: move to beginning of buffer define brief_home () { if (LAST_KBD_COMMAND != "brief_home") { Brief_HomeEnd_Count = 0; bol (); } else { Brief_HomeEnd_Count++; switch (Brief_HomeEnd_Count) {case 1: goto_top_of_window (); } {case 2: bob (); } {bol (); } } } % Move the cursor based on the count of succesive function invocation: % 1: move to end of line % 2: move to end of window % 3: move to end of buffer define brief_end () { if (LAST_KBD_COMMAND != "brief_end") { Brief_HomeEnd_Count = 0; eol (); } else { Brief_HomeEnd_Count++; switch (Brief_HomeEnd_Count) {case 1: goto_bottom_of_window (); eol (); } {case 2: eob (); } {eol (); } } } % Scroll current line to end of window define brief_line_to_eow () { recenter (window_info ('r')); } % Scroll current line to beginning of window define brief_line_to_bow () { recenter (1); } % Scroll current line to center of window define brief_line_to_mow () { recenter (window_info ('r') / 2); } % Set bookmark number n define brief_set_bkmrk_cmd (n) { ungetkey (n + '0'); bkmrk_set_mark (); } % Delete from current position to end of line define brief_delete_to_bol () { push_mark (); bol(); del_region (); } % Open a blank line below the current line define brief_open_line () { eol (); newline (); indent_line (); } private define onoff(val) { if (val) return "on"; else return "off"; } % Toggle the case-sensitive search mode define brief_toggle_case_search () { CASE_SEARCH = not (CASE_SEARCH); vmessage ("Case sensitive search is %s.", onoff(CASE_SEARCH)); } variable Brief_Regexp_Search = 1; % Toggle regular expression search define brief_toggle_regexp () { Brief_Regexp_Search = not (Brief_Regexp_Search); vmessage ("Regular expression search is %s.", onoff(Brief_Regexp_Search)); } variable Brief_Search_Forward = 1; % The main search function define brief_search_cmd () { if (Brief_Search_Forward) { if (Brief_Regexp_Search) re_search_forward (); else search_forward (); } else { if (Brief_Regexp_Search) re_search_backward (); else search_backward (); } } % Reverse the search direction and start the search define brief_reverse_search () { Brief_Search_Forward = not (Brief_Search_Forward); brief_search_cmd (); } % The main replace function. % When a region is marked the buffer is narrowed to the region % before search/replace and widened afterwards. define brief_replace_cmd() { variable bWiden = 0; if (markp()) { push_spot (); narrow_to_region(); bob(); bWiden = 1; } if (Brief_Regexp_Search) query_replace_match (); else replace_cmd(); if (bWiden) { widen_region (); pop_spot(); } } %% 0 - No mark %% 1 - Normal 3 - Line %% 2 - Column 4 - Noninclusive variable Brief_Mark_Type = 0; #ifdef HAS_BLOCAL_VAR private variable Brief_Scrap_Type = "Brief_Scrap_Type"; private define brief_get_scrap_type(scbuf) { variable b, v = 1; !if (bufferp(scbuf)) return 1; b = whatbuf(); setbuf(scbuf); if (blocal_var_exists(Brief_Scrap_Type)) v = get_blocal_var(Brief_Scrap_Type); setbuf(b); return v; } private define brief_set_scrap_type(scbuf, sctype) { variable b; !if (bufferp(scbuf)) return; b = whatbuf(); setbuf(scbuf); create_blocal_var(Brief_Scrap_Type); set_blocal_var(sctype, Brief_Scrap_Type); setbuf(b); } #else private variable Brief_Scrap_Type = 0; private define brief_get_scrap_type(scbuf) { return Brief_Scrap_Type; } private define brief_set_scrap_type(scbuf, sctype) { Brief_Scrap_Type = sctype; } #endif %% HAS_BLOCAL_VAR private variable Brief_Scrap_Buf_Format = " "; private define brief_get_scrap_name () { variable b, scrps; scrps = ""; loop (buffer_list ()) { b = (); if (1 == is_substr(b, " "); if (scrps == "") scrps = b; else scrps = scrps + "," + b; } } variable name = read_with_completion (scrps, "Scrap name:", "", "", 's'); name = strtrim (name); if (name == "") name = NULL; return name; } % Yanking whole lines from the pastebuffer define brief_yank_lines () { call ("mark_spot"); bol (); call ("yank"); pop_spot (); } % Select the yank mode based on the type of data stored % in the pastebuffer. define brief_yank () { switch (brief_get_scrap_type(" ")) { case 2: insert_rect (); message ("Columns inserted."); } { case 3: brief_yank_lines (); message ("Lines inserted."); } { call ("yank"); message ("Scrap inserted.");} } % Select the yank mode based on the type of data stored % in the named buffer. define brief_yank_named () { variable sctype, scbuf, b; variable scrapname = brief_get_scrap_name(); if (scrapname == NULL) return; scbuf = sprintf(Brief_Scrap_Buf_Format, scrapname); !if (bufferp(scbuf)) { message ("No such scrap."); return; } b = whatbuf(); sctype = brief_get_scrap_type(scbuf); if (sctype == 2) setbuf(" "); else setbuf(" "); erase_buffer(); insbuf(scbuf); setbuf(b); switch (sctype) { case 2: insert_rect (); vmessage ("Columns from scrap '%s' inserted.", scrapname); } { case 3: brief_yank_lines (); vmessage ("Lines from scrap '%s' inserted.", scrapname);} { call ("yank"); vmessage ("Scrap '%s' inserted.", scrapname);} } % Prototype: brief_complete_line_region () % Makes a line region complete including whole first line % and whole last line (with newline character). define brief_complete_line_region () { check_region (0); %% region is canonical exchange_point_and_mark (); %% mark entire first line bol (); check_region (0); eol(); !if (eobp ()) { go_down_1 (); bol (); } } % Check if a marked region exists. If it does not, mark the current line. % Returns 1 if the region was automarked, 0 otherwise. define brief_check_marked_automark () { if (markp() == 0) { % not marked --> copy line if (eobp() and bolp()) return (0); set_mark_cmd (); Brief_Mark_Type = 3; return (1); } else if (Brief_Mark_Type == 0) { % marked, but wrong type --> copy region Brief_Mark_Type = 1; } return (0); } private define brief_region_to_scrap(opinfo, macro, rectmacro, namedscrap) { variable b, what = NULL; if (brief_check_marked_automark()) what = "Line"; if (Brief_Mark_Type == 2) { if (is_internal(rectmacro)) call (rectmacro); else eval(rectmacro); what = "Columns"; } else if (Brief_Mark_Type == 3) { push_spot (); brief_complete_line_region (); if (is_internal(macro)) call (macro); else eval(macro); pop_spot (); if (what == NULL) what = "Lines"; } else { if (is_internal(macro)) call (macro); else eval(macro); what = "Region"; } if (namedscrap == NULL or namedscrap == "") { vmessage ("%s %s to scrap.", what, opinfo); brief_set_scrap_type(" ", Brief_Mark_Type); } else { vmessage ("%s %s to scrap '%s'.", what, opinfo, namedscrap); b = whatbuf(); what = sprintf(Brief_Scrap_Buf_Format, namedscrap); setbuf(what); erase_buffer(); if (Brief_Mark_Type == 2) insbuf(" "); else insbuf(" "); brief_set_scrap_type(what, Brief_Mark_Type); setbuf(b); } Brief_Mark_Type = 0; } % Copy the region to pastebuffer based on current mark type (normal, lines, columns) define brief_copy_region () { brief_region_to_scrap("copied", "copy_region", "copy_rect", NULL); } % Cut the region to pastebuffer based on current mark type (normal, lines, columns) define brief_kill_region () { brief_region_to_scrap("cut", "kill_region", "kill_rect", NULL); } % Copy the region to a named buffer based on current mark type (normal, lines, columns) define brief_copy_region_named () { variable name = brief_get_scrap_name(); if (name != NULL) brief_region_to_scrap("copied", "copy_region", "copy_rect", name); } % Cut the region to a named buffer based on current mark type (normal, lines, columns) define brief_kill_region_named () { variable name = brief_get_scrap_name(); if (name != NULL) brief_region_to_scrap("cut", "kill_region", "kill_rect", name); } % Delete the next charactre. % If a region is marked, delete it based on current mark type (normal, lines, columns) define brief_delete () { if (markp ()) { if (Brief_Mark_Type == 2) { kill_rect (); } else if (Brief_Mark_Type == 3) { brief_complete_line_region (); del_region (); } else { del_region (); } Brief_Mark_Type = 0; return; } del (); Brief_Mark_Type = 0; } % int brief_unmark (int MarkType) % If a region is marked and it is of type MarkType, % the region is unmarked, 1 is returned. It returns % 0 otherwise. define brief_unmark (n) { if (markp ()) { if (Brief_Mark_Type == n) { smart_set_mark_cmd (); message ("Mark unset"); Brief_Mark_Type = 0; return (1); } } return (0); } % Start marking a region and set region type to Lines. % If a region is already marked and is not of type Lines, % change region type to Lines. define brief_line_mark () { !if (brief_unmark (3)) { Brief_Mark_Type = 3; push_spot (); eol (); goto_column (what_column () / 2); set_mark_cmd (); pop_spot (); message ("Line mark set."); } } % void brief_set_mark_cmd (int MarkType) define brief_set_mark_cmd (n) { !if (brief_unmark (n)) { Brief_Mark_Type = n; if (Brief_Mark_Type == 1) { set_mark_cmd (); } else { smart_set_mark_cmd (); } } } % Start marking a region and set region type to Columns. % If a region is already marked and is not of type Columns, % change region type to Columns. define brief_set_column_mark () { !if (brief_unmark (2)) { Brief_Mark_Type = 2; set_mark_cmd (); message ("Column mark set."); } } % Start macro recording. If recording is already in progress, stop recording. define brief_record_kbdmacro () { if (DEFINING_MACRO) { call ("end_macro"); } else !if (EXECUTING_MACRO or DEFINING_MACRO) { call ("begin_macro"); } } % Prototype: brief_next_buffer (int direction) % This function changes the current buffer depending on value of % direction: % if direction >= 0 ==> next buffer % if direction < 0 ==> prev buffer % It skips system buffers and buffers with names beginning with '*'. define brief_next_buffer (direction) { variable n, buf; if (MINIBUFFER_ACTIVE) return; n = buffer_list (); %/* buffers on stack */ if (direction < 0) { _stk_roll (-n); pop (); n--; } loop (n) { if (direction < 0) _stk_roll (-n); buf = (); n--; if (buf[0] == ' ') continue; if (buf[0] == '*' and buf != "*scratch*") continue; sw2buf (buf); loop (n) pop (); return; } } % int Brief_Last_Column % Records the last column position before PageUp/PageDown commands. % Used in brief_pageup () and brief_page_down () to restore the % column position after movement. private variable Brief_Last_Column = 0; private define brief_store_last_column () { if (LAST_KBD_COMMAND == "brief_pagedown" or LAST_KBD_COMMAND == "brief_pageup") return; Brief_Last_Column = what_column (); } % Prototype: brief_pageup () % Moves one page up leaving the cursor on the same position in the % window. define brief_pageup () { variable woffs; if (MINIBUFFER_ACTIVE) { call ("page_up"); return; } brief_store_last_column (); woffs = window_line (); go_up (window_info ('r')); while (is_line_hidden() and not bobp()) go_up_1(); recenter (woffs); () = goto_column_best_try (Brief_Last_Column); } % Prototype: brief_pagedown () % Moves one page down leaving the cursor on the same position in the % window. define brief_pagedown () { variable woffs; if (MINIBUFFER_ACTIVE) { call ("page_down"); return; } brief_store_last_column (); woffs = window_line (); go_down (window_info ('r')); while (is_line_hidden() and not eobp()) go_down_1(); recenter (woffs); () = goto_column_best_try (Brief_Last_Column); } % Prototype: brief_delete_buffer () % Deletes the current buffer if it is not the minibuffer. define brief_delete_buffer () { if (MINIBUFFER_ACTIVE) return; delbuf (whatbuf ()); brief_next_buffer (1); } jedmodes-2.5.7/brief/brief.sl0000644000175400017500000001443110611416274014325 0ustar mildegm% brief.sl: Brief editor emulation % % This will not work well on konsole or in an x-terminal % because of the heavy dependence on "exotic" keys. % Try with DOS, MS-Windows, or X-Windows and an IBMPC keyboard % % Copyright (c) 2005 John E Davis, Gnter Milde, Marko Mahnic % Released under the terms of the GNU General Public License (ver. 2 or later) % % 2003-08-18 Guenter Milde % - work with X-windows and a IBMPC keyboard using keydefs.sl % % 2005-10-11 Marko Mahnic % - double/triple home/end handling % - more Brief keybindings (based on emacs brief.el) % - more Brief-like region marking, copying, yanking % - page up/dn (mostly) leaves cursor on same screen line % - Brief-like macro recording (F7) % % 2005-10-12 Guenter Milde % - fixed dependency on x-keydefs (kp_keydefs is obsolete) % % 2006-03-07 Marko Mahnic % - added support for named scraps with region type info in blocal vars % % 2006-03-15 Marko Mahnic % - disabled the "\em" keybinding that prevented menu access % - disabled the "\es" keybinding (Search menu) % % 2007-02-11 Marko Mahnic % - moved all functions to briefmsc.sl % - functions marked "public" % - documentation added % _Jed_Emulation = "brief"; % load the extended set of symbolic key definitions (variables Key_*) require("x-keydefs"); require("briefmsc"); autoload ("scroll_up_in_place", "emacsmsc"); autoload ("scroll_down_in_place", "emacsmsc"); set_status_line("(Jed %v) Brief: %b (%m%a%n%o) %p %t", 1); Help_File = Null_String; unsetkey ("^F"); unsetkey ("^K"); unsetkey ("^R"); unsetkey ("^X"); unsetkey ("^W"); setkey ("scroll_up_in_place", "^D" ); setkey ("scroll_down_in_place", "^E" ); setkey ("brief_delete_to_bol", "^K" ); setkey ("goto_match", "^Q[" ); setkey ("goto_match", "^Q\e" ); setkey ("goto_match", "^Q]" ); setkey ("goto_match", "^Q^]" ); setkey ("isearch_forward", "^S" ); setkey ("brief_line_to_bow", "^T" ); setkey ("brief_line_to_mow", "^C" ); setkey ("brief_line_to_eow", "^B" ); %setkey ("brief_next_error", "^N" ); %setkey ("brief_error_window", "^P" ); _for (0, 9, 1) { $0 = (); setkey("digit_arg", "^R" + string($0)); } %setkey ("redo", "^U" ); %setkey ("brief_toggle_backup", "^W" ); %setkey ("save_buffers_and_exit","^X" ); %setkey ("one_window", "^Z" ); setkey ("brief_yank", Key_Ins ); setkey ("brief_delete", Key_Del ); setkey ("brief_home", Key_Home ); setkey ("brief_end", Key_End ); setkey ("brief_pagedown", Key_PgDn ); setkey ("brief_pageup", Key_PgUp ); setkey ("scroll_left", Key_Shift_End ); % should be: right of window setkey ("scroll_right", Key_Shift_Home ); % should be: left of window setkey ("bskip_word", Key_Ctrl_Left ); setkey ("skip_word", Key_Ctrl_Right ); setkey ("bob", Key_Ctrl_PgUp ); setkey ("eob", Key_Ctrl_PgDn ); setkey ("goto_top_of_window", Key_Ctrl_Home ); setkey ("goto_bottom_of_window", Key_Ctrl_End ); setkey ("bdelete_word", Key_Ctrl_BS ); setkey ("delete_word", Key_Alt_BS ); setkey ("brief_open_line", Key_Ctrl_Return); setkey ("undo", Key_KP_Multiply ); setkey ("brief_copy_region", Key_KP_Add ); setkey ("brief_kill_region", Key_KP_Subtract ); % setkey ("brief_copy_region_named", Key_Ctrl_KP_Add); % setkey ("brief_kill_region_named", Key_Ctrl_KP_Subtract); % setkey ("brief_yank_named", Key_Ctrl_Ins); setkey ("other_window", Key_F1 ); setkey ("one_window", Key_Alt_F2 ); setkey ("split_window", Key_F3 ); setkey ("delete_window", Key_F4 ); setkey ("brief_search_cmd", Key_F5 ); setkey ("brief_reverse_search", Key_Alt_F5 ); setkey ("brief_search_cmd", Key_Shift_F5 ); setkey ("brief_toggle_case_search", Key_Ctrl_F5 ); setkey ("brief_replace_cmd", Key_F6 ); setkey ("brief_toggle_regexp", Key_Ctrl_F6 ); setkey ("brief_record_kbdmacro", Key_F7 ); %setkey ("brief_pause_kbdmacro", Key_Shift_F7 ); setkey ("execute_macro", Key_F8 ); setkey ("emacs_escape_x", Key_F10 ); setkey ("compile", Key_Alt_F10 ); setkey (". 4 brief_set_mark_cmd","\ea" ); % Alt A %setkey ("list_buffers", "\eb" ); % Alt B Buffers menu setkey ("brief_set_column_mark", "\ec" ); % Alt C setkey ("delete_line", "\ed" ); % Alt D %setkey ("find_file", "\ee" ); % Alt E Edit menu %setkey ("display_file_name", "\ef" ); % Alt F File menu setkey ("goto_line_cmd", "\eg" ); % Alt G %setkey ("help_prefix", "\eh" ); % Alt H Help menu %setkey ("toggle_overwrite", "\ei" ); % Alt I Windows menu setkey ("bkmrk_goto_mark", "\ej" ); % Alt J setkey ("kill_line", "\ek" ); % Alt K setkey ("brief_line_mark", "\el" ); % Alt L %setkey (". 1 brief_set_mark_cmd","\em" ); % Alt M Menu access prefix setkey ("brief_next_buffer(1)", "\en" ); % Alt N %setkey ("write_buffer", "\eo" ); % Alt O Mode menu setkey ("brief_next_buffer(-1)", "\ep" ); % Alt P; should be: print region %setkey ("quote_next_key", "\eq" ); % Alt Q setkey ("insert_file", "\er" ); % Alt R %setkey ("brief_search_cmd", "\es" ); % Alt S Search menu setkey ("brief_replace_cmd", "\et" ); % Alt T setkey ("undo", "\eu" ); % Alt U %setkey ("brief_show_version", "\ev" ); % Alt V setkey ("save_buffer", "\ew" ); % Alt W setkey ("exit_jed", "\ex" ); % Alt X % setkey (".0 brief_set_bkmrk_cmd", "\e0" ); % Alt 0 setkey (".1 brief_set_bkmrk_cmd", "\e1" ); % Alt 1 setkey (".2 brief_set_bkmrk_cmd", "\e2" ); % Alt 2 setkey (".3 brief_set_bkmrk_cmd", "\e3" ); % Alt 3 setkey (".4 brief_set_bkmrk_cmd", "\e4" ); % Alt 4 setkey (".5 brief_set_bkmrk_cmd", "\e5" ); % Alt 5 setkey (".6 brief_set_bkmrk_cmd", "\e6" ); % Alt 6 setkey (".7 brief_set_bkmrk_cmd", "\e7" ); % Alt 7 setkey (".8 brief_set_bkmrk_cmd", "\e8" ); % Alt 8 setkey (".9 brief_set_bkmrk_cmd", "\e9" ); % Alt 9 runhooks ("keybindings_hook", _Jed_Emulation); jedmodes-2.5.7/txtutils/0000755000175400017500000000000011137355652013512 5ustar mildegmjedmodes-2.5.7/txtutils/txtutils.sl0000644000175400017500000003607211137355652015762 0ustar mildegm% txtutils.sl: % Tools for text processing (marking, picking, formatting) % % Copyright (c) 2005 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % VERSIONS % 2.0 * get_word(), bget_word() now "region aware" % * new functions mark_line(), get_line(), autoinsert() % * bugfix for indent_region_or_line() (used to leave stuff % on stack) % 2.1 * mark_word(), bmark_word() test for buffer local variable % "Word_Chars" (using get_blocal from sl_utils.sl) % 2.2 2003-11 * removed indent_region_or_line() (now in cuamisc.sl) % * changed mark_/get_word: added 2nd opt arg skip % -1 skip backward, if not in a word % 0 don't skip % 1 skip forward, if not in a word % Attention: get_word now returns last word, if the point is % just behind a word (that is the normal way jed treats % word boundaries) % 2.3 2004-11-24 * New function insert_markup(beg_tag, end_tag) % 2.3.1 2005-05-26 bugfix: missing autoload (report PB) % 2.3.2 2005-06-09 * reintroduced indent_region_or_line() % jed99-17's cuamisc.sl doesnot have it % 2.3.3 2005-10-14 * added documentation % 2.3.3 2005-11-21 * removed "public" from definitions of functions % returning a value % 2.4 2005-11-24 * new function local_word_chars() that also probes % mode_get_mode_info("word_chars") % new (optional) arg 'lines' for get_buffer() % 2.5 2006-01-19 New functions mark_paragraph(), % mark_paragraph_from_point(), format_paragraph_from_point() % 2.6 2006-09-14 New function newline_indent() (fix pasting in x-terminal) % 2.6.1 2006-10-04 fix spurious spot in indent_region_or_line() % 2.6.2 2006-11-10 indent_region_or_line() did not indent a regions last line % 2.6.3 2007-05-14 * documentation update % * insert_block_markup() inserts newline if region|word % doesnot start at bol % 2.7 2007-12-11 * new function re_replace() % 2.7.1 2008-02-25 * update help for newline_indent() % 2.7.2 2009-01-26 * documentation example for re_replace() (M. Mahnič) provide("txtutils"); % Requirements % ------------ autoload("get_blocal", "sl_utils"); autoload("push_defaults", "sl_utils"); % Marking and Regions % ------------------- %!%+ %\function{local_word_chars} %\synopsis{Return the locally valid set of word chars} %\usage{String local_word_chars()} %\description % Returns the currently defined set of characters that constitute a word in % the local context: (in order of preference) % % * the buffer local variable "Word_Chars" % * the mode-info field "word_chars" (with \sfun{mode_get_mode_info}) % * the global definition (with \sfun{get_word_chars}). %\example % Define a global set of word_chars with e.g. %#v+ % define_word("a-zA-Z") %#v- % Define a mode-specific set of word_chars with e.g. %#v+ % mode_set_mode_info("word_chars", "a-zA-Z") %#v- % Define a buffer-specific set of word_chars with e.g. %#v+ % define_blocal_var("word_chars", "a-zA-Z") %#v- %\seealso{} %!%- define local_word_chars() { variable word_chars = get_blocal("Word_Chars"); if (word_chars != NULL) return word_chars; word_chars = mode_get_mode_info("word_chars"); if (word_chars != NULL) return word_chars; return get_word_chars(); } %!%+ %\function{mark_word} %\synopsis{Mark a word} %\usage{ mark_word(word_chars=local_word_chars(), skip=0)} %\description % Mark a word as visible region. Get the idea of the characters % a word is made of from the optional argument \var{word_chars} % or \var{local_word_chars}. The optional argument \var{skip} tells how to % skip non-word characters: % % -1 skip backward % 0 don't skip (default) % 1 skip forward % %\seealso{mark_line, get_word, define_word, define_blocal_var, push_visible_mark} %!%- public define mark_word() % (word_chars=local_word_chars(), skip=0) { variable word_chars, skip; (word_chars, skip) = push_defaults( , 0, _NARGS); if (word_chars == NULL) word_chars = local_word_chars(); switch (skip) { case -1: skip_chars(word_chars); bskip_chars("^"+word_chars); } { case 1: skip_chars("^"+word_chars); if(eolp()) { push_visible_mark(); return; } } % Find word boundaries bskip_chars(word_chars); push_visible_mark(); skip_chars(word_chars); } % % mark a word (skip forward if between two words) % public define fmark_word() % fmark_word(word_chars=local_word_chars()) % { % variable args = __pop_args (_NARGS); % mark_word(__push_args(args), 1); % } % % mark a word (skip backward if not in a word) % public define bmark_word () % (word_chars=local_word_chars()) % { % variable args = __pop_args (_NARGS); % mark_word(__push_args(args), -1); % } %!%+ %\function{get_word} %\synopsis{Return the word at point as string} %\usage{String get_word(word_chars=local_word_chars(), skip=0)} %\description % Return the word at point (or a visible region) as string. % % See \sfun{mark_word} for the "word finding algorithm" % and meaning of the optional arguments. %\seealso{bget_word, mark_word, define_word, push_visible_mark} %!%- define get_word() % (word_chars=local_word_chars(), skip=0) { % pass on optional arguments variable args = __pop_args(_NARGS); push_spot; !if (is_visible_mark) mark_word (__push_args(args)); bufsubstr(); pop_spot(); } % % return the word at point as string (skip forward if between two words) % public define fget_word() % (word_chars=local_word_chars()) % { % variable word_chars = push_defaults( , _NARGS); % get_word(word_chars(args), 1); % } %!%+ %\function{bget_word} %\synopsis{Return the word at point as string, skip back if not in a word} %\usage{String get_word([String word_chars], skip=0)} %\description % Return the word at point (or a visible region) as string. % Skip back over non-word characters when not in a word. % This is a shorthand for get_word(-1). % See \sfun{mark_word} for the "word finding algorithm" %\seealso{get_word, mark_word, define_word} %!%- define bget_word() % (word_chars=local_word_chars()) { variable word_chars = push_defaults( , _NARGS); get_word(word_chars, -1); } %!%+ %\function{mark_line} %\synopsis{Mark the current line} %\usage{mark_line()} %\description % Mark the current line as an invisible region %\seealso{push_mark_eol} %!%- public define mark_line() { bol(); push_mark_eol(); } %!%+ %\function{get_line} %\synopsis{Return the current line as string} %\usage{String get_line()} %\description % Return the current line as string. In contrast to the standard % \sfun{line_as_string}, this keeps the point at place. %\seealso{line_as_string, mark_line, bufsubstr} %!%- define get_line() { push_spot(); line_as_string(); % leave return value on stack pop_spot(); } define mark_paragraph_from_point() { push_visible_mark(); forward_paragraph(); } define mark_paragraph() { backward_paragraph(); mark_paragraph_from_point(); } define format_paragraph_from_point() { mark_paragraph_from_point(); exchange_point_and_mark(); narrow (); call ("format_paragraph"); widen (); } %!%+ %\function{get_buffer} %\synopsis{Return buffer as string} %\usage{String get_buffer(kill=0, lines=0)} %\description % Return buffer as string. % If a visible region is defined, return it instead. % If \var{kill} is not zero, the buffer/region will be deleted in the process. % If \var{lines} is not zero, whole lines will be returned %\seealso{bufsubstr, push_visible_mark} %!%- define get_buffer() % (kill=0, lines=0) { variable str, kill, lines; (kill, lines) = push_defaults(0, 0, _NARGS); push_spot(); !if(is_visible_mark()) mark_buffer(); else if (lines) { check_region(0); eol(); go_right_1(); exchange_point_and_mark(); bol(); } if (kill) str = bufsubstr_delete(); else str = bufsubstr(); pop_spot(); return(str); } % Formatting % ---------- %!%+ %\function{indent_region_or_line} %\synopsis{Indent the current line or (if visible) the region} %\usage{Void indent_region_or_line ()} %\description % Call the indent_line_hook for every line in a region. % If no region is defined, call it for the current line. %\seealso{indent_line, set_buffer_hook, is_visible_mark} %!%- public define indent_region_or_line() { !if(is_visible_mark()) { indent_line(); return; } % narrow() doesnot work, as indent_line() needs the context! check_region(0); % make sure the mark comes first variable end_line = what_line(); pop_mark_1(); % go there loop (end_line - what_line() + 1) { indent_line(); go_down_1(); } } %!%+ %\function{indent_buffer} %\synopsis{Format a buffer with \sfun{indent_line}} %\usage{indent_buffer()} %\description % Call \sfun{indent_line} for all lines of a buffer. %\seealso{indent_line, indent_region_or_line} %!%- public define indent_buffer() { push_spot; bob; do indent_line; while (down_1); pop_spot; } %!%+ %\function{newline_indent} %\synopsis{Correct mouse-pasting problem for for Jed in an x-terminal} %\usage{newline_indent()} %\description % Jed's default binding for the Return key is \sfun{newline_and_indent}. In % an x-terminal, this can result in a staircase effect when mulitple lines % are pasted with the mouse, as indentation is doubled. % % As workaround, \sfun{newline_indent} guesses, whether the input comes from % the keyboard or the mouse and only indents in the first case. % %\example % Many editing modes (c_mode, slang_mode, perl_mode, php_mode, to name but a % few) bind the return key to newline_and_indent() in their local keymap. % Therefore you will need to change this binding in the global_mode_hook. % % In your jed.rc, write e.g. %#v+ % #ifndef XWINDOWS IBMPC_SYSTEM % % Fix staircase effect with mouse-pasting in an x-terminal % setkey("newline_indent", "^M"); % % Some modes overwrite the Key_Return binding. Restore it: % define global_mode_hook (hook) % { % if (wherefirst(what_keymap() == ["C", "DCL", "IDL", "perl", "PHP"]) % != NULL) % local_setkey("newline_indent", "^M"); % } % #endif %#v- % or add the setkey() line to an already existing global_mode_hook() % definition. % %\notes % Jed receives its input as a sequence of characters and cannot easily tell % whether this input is generated by keypesses, pasting from the mouse or a % remote application. % % \sfun{newline_indent} uses \sfun{input_pending} for the guessing: % % In normal typing, jed can process a newline faster than the next char is % pressed. When pasting from the mouse, the pasted string goes to the % input buffer and is processed one character a time, thus pending input % indicates a paste operation. %\seealso{newline, newline_and_indent, Help>Browse_Doc>hooks.txt} %!%- public define newline_indent() { if (input_pending(0)) newline(); else call("newline_and_indent"); } %!%+ %\function{number_lines} %\synopsis{Insert line numbers} %\usage{number_lines()} %\description % Precede all lines in the buffer (or a visible region) with line numbers % % The numbers are not just shown, but actually inserted into the buffer. %\notes % Use \var{toggle_line_number_mode} (Buffers>Toggle>Line_Numbers) to show % line numbers without inserting them in the buffer. %\seealso{set_line_number_mode, toggle_line_number_mode} %!%- define number_lines() { variable visible_mark = is_visible_mark(); push_spot; if(visible_mark) narrow; eob; variable i = 1, digits = strlen(string(what_line())), format = sprintf("%%%dd ", digits); bob; do { bol; insert(sprintf(format, i)); i++; } while (down_1); if (visible_mark) widen; pop_spot; } %!%+ %\function{autoinsert} %\synopsis{Auto insert text in a rectangle} %\usage{autoinsert()} %\description % Insert the content of the first line into a rectangle defined by % point and mark. This is somewhat similar to \sfun{open_rect} but for % arbitrary content. % % If you have to fill out collumns with identical content, write the content % in the first line, then mark the collumn and call \sfun{autoinsert}. %\seealso{open_rect} %!%- public define autoinsert() { () = dupmark(); narrow; % get string to insert check_region(0); variable end_col = what_column(); bob(); goto_column(end_col); variable str = bufsubstr(); variable beg_col = end_col - strlen(str); while (down_1) { goto_column(beg_col); insert(str); } widen; } %!%+ %\function{insert_markup} %\synopsis{Insert markup around region or word} %\usage{Void insert_markup(Str beg_tag, Str end_tag)} %\description % Inserts beg_tag and end_tag around the region or current word. %\example % Marking a region and %#v+ % insert_markup("", ""); %#v- % will highlight it as bold in html, while %#v+ % insert_markup("{\textbf{", "}"); %#v- % will do the same for LaTeX. %\seealso{mark_word} %!%- define insert_markup(beg_tag, end_tag) { !if (is_visible_mark) mark_word(); variable region = bufsubstr_delete(); insert(beg_tag + region + end_tag); % put cursor in the markup tags if the region is void if (region == "") go_left(strlen(end_tag)); } %!%+ %\function{insert_block_markup} %\synopsis{Insert markup around region and (re) indent} %\usage{insert_block_markup(beg_tag, end_tag)} %\description % Insert beg_tag and end_tag around the region or current word. % Insert a newline before the region|word if it is not the first non-white % token of the line. % Indent region or line (according to the mode's syntax rules). %\seealso{insert_markup} %!%- define insert_block_markup(beg_tag, end_tag) { !if (is_visible_mark) mark_word(); () = dupmark(); variable region = bufsubstr_delete(); insert(beg_tag + region + end_tag); % insert newline if there is something except whitespace before the start % of the region exchange_point_and_mark(); bskip_white(); !if (bolp) newline(); exchange_point_and_mark(); indent_region_or_line(); % put cursor inside the markup tags if the region is void if (region == "") go_left(strlen(end_tag)); } %!%+ %\function{re_replace} %\synopsis{Replace all occurences of regexp \var{pattern} with \var{rep}} %\usage{re_replace(pattern, rep)} %\description % Regexp equivalent to \sfun{replace}. % Replaces all occurences of of regexp \var{pattern} with \var{rep} % from current editing point to the end of the buffer. % The editing point is returned to the initial location. % The regexp syntax is the same as in \sfun{re_fsearch} % (currently S-Lang regular expressions). %\example % before: ad e cf %#v+ % re_replace ("\([abc]\)\([def]\)"R, "\0:\2\1"R) %#v- % after: ad:da e cf:fc %\seealso{replace, re_search_forward, str_re_replace, query_replace_match} %!%- define re_replace(pattern, rep) { push_spot(); while (re_fsearch(pattern)) { !if (replace_match(rep, 0)) error ("replace_match failed."); } pop_spot(); } jedmodes-2.5.7/ChangeLog0000664000175400017510000025115511702652706014065 0ustar mildemilde2011-06-25 10:48 boekholt * email/email.sl: removed misplaced parentheses that break email.sl in slang 2.2 (should fix debian bug 626412) 2011-01-01 22:01 milde * cua/cua.sl: Fix assignment of forward/backward_paragraph(). 2010-12-08 13:05 milde * rst/rst.sl: XHTML (html4_strict) and XeTeX export. 2010-12-08 12:54 milde * pymode/pymode.sl: py_untab() restores point, adapt to 2.6 doc paths 2010-12-08 12:51 milde * listing/listing.sl: * list_concat() -> list_extend() (matching datutils 2.3) 2010-12-08 12:49 milde * datutils/datutils.sl: name list_concat() to list_extend() (clash with S-Lang >= 2.2.3 2010-01-19 14:27 milde * ch_table/ch_table.sl: Fix ct_describe_character() before "holes" in Unicode. 2010-01-18 15:02 milde * ch_table/ch_table.sl: 2.6 Make combining chars visible by NBSP as base char. 2009-12-09 21:26 milde * ch_table/ch_table.sl: fix missing quotation mark 2009-12-09 00:07 milde * rst/: rst.sl, rst-outline.sl: care for the changed require() behaviour in Jed 0.99.19 2009-12-09 00:00 milde * diffmode/diffmode.sl: adapt to the changed require() behaviour in Jed 0.99.19 2009-12-08 23:54 milde * listing/listing.sl, bufutils/bufutils.sl, ch_table/ch_table.sl, ding/ding.sl, filelist/filelist.sl, gnuplot/gnuplot.sl: Care for the changed require() behaviour in Jed 0.99.19 Bugfix commit: overwriting the function with a private version works in Python but not in S-Lang. 2009-11-20 21:04 milde * README, README.html, bufutils/bufutils.sl, diffmode/diffmode.sl, ding/ding.sl, filelist/filelist.sl, gnuplot/gnuplot.sl, listing/listing.sl, rst/rst.sl: Care for the changed require() behaviour in Jed 0.99.19 2009-10-05 16:37 milde * datutils/datutils.sl: fix fallback defs of __push_list(), __pop_list() 2009-10-05 15:02 milde * svn/svn.sl: * fixed autoloads 2009-10-05 15:02 milde * pylit/pylit.sl: fix autoloads 2009-10-05 15:01 milde * diffmode/diffmode.sl: fix autoloads (requires bufutils) 2009-10-05 13:57 milde * svn/svn.sl: * Moved reopen_file() to bufutils.sl. 2009-10-05 13:56 milde * strutils/strutils.sl: 1.7 new: str_unicode_escape(). 2009-10-05 13:55 milde * navigate/navigate.sl: 1.4 * define named namespace, remove debugging function 2009-10-05 13:54 milde * filelist/filelist.sl: 1.8.1 * bugfix: pass name of calling buffer to _open_file() 2009-10-05 13:53 milde * cuamisc/cuamisc.sl: 1.6.4 * documentation update for cua_escape_handler() 2009-10-05 13:53 milde * ch_table/ch_table.sl: 2.5.4 Insert to original buf after search with "find character". 2009-10-05 13:53 milde * bufutils/bufutils.sl: 1.19 New function reopen_file() 2009-10-05 13:51 milde * tm/tmtools.sl: return instead of break outside loop 2009-09-04 09:18 milde * diffmode/diffmode.sl: prepend buffer_dir to relative source file paths 2009-08-31 12:42 milde * svn/svn.sl: BUGFIX: "subtract file" removed the local copy with SVN! 2009-08-02 18:17 boekholt * jedscape/jedscape.sl: use keyword1 color for anchors 2009-03-21 17:26 boekholt * jedscape/jedscape.sl: downloading binary files didn't work 2009-03-14 16:35 boekholt * ispell/: ispell.otl, ispell.sl, ispell_common.sl, ispell_init.sl: undo previous change add support for hunspell 2009-03-07 18:23 boekholt * hyperman/hyperman.sl: set MAN_KEEP_FORMATTING=1 2009-02-16 18:29 milde * make/make.sl: documentation update. 2009-02-16 18:26 milde * listing/listing.sl: 3.1.2 * code cleanup 2009-02-16 18:24 milde * libdir/libdir.sl: documentation update 2009-02-16 18:19 milde * hyperhelp/help.sl: use UTF-8 encoding 2009-02-16 18:11 milde * gnuplot/gnuplot.sl: 1.1.7 clearer names for mode menu entries, gnuplot_view: If no output file defined, call gnuplot_plot, 2009-02-16 17:52 milde * ding/ding.sl: 1.5 ding(): an empty string arg triggers an interactive request for a word the same way as no optional arg does, custom var Ding_Case_Search, failsave formatting. 2009-02-16 17:39 milde * dictmode/dictmode.sl, dict-backend/dict-cli.sl: minor code cleanup 2009-02-16 17:34 milde * diagnose/diagnose.sl: use UTF-8 encoding 2009-02-16 17:32 milde * datutils/datutils.sl: fallback defs of __push_list(), __pop_list(), deprecated push_list(), pop2list(), favour literal constructs for array<->list conversion 2009-02-07 12:19 boekholt * zip/zip.sl: 'file modified' flag gets set in svn version of JED 2009-01-30 08:43 milde * print/: print.sl, simpleprint.sl: rename to simpleprint.sl, as there is another print.sl coming with slsh 2009-01-30 07:56 milde * boxquote/boxquote.sl: add boxquote.sl to the Jedmodes repository 2009-01-27 12:34 milde * rst/rst.sl: * reset cwd after rst_export() 2009-01-27 12:33 milde * unittest/unittest.sl: warn if a test changes the cwd 2009-01-27 12:16 milde * unittest/unittest.sl: expand Unittest_Reportfile to absolute path 2009-01-27 11:36 milde * unittest/unittest.sl: test_files(): add summary to testreport (with report==1) 2009-01-27 10:51 milde * tests/: csvutils-test.sl, cuamark-test.sl, cuamouse-test.sl, datutils-test.sl, ishell-test.sl, listing-test.sl, pymode-test.sl, rst-outline-test.sl, rst-test.sl, structured_text-test.sl, strutils-test.sl, test-browse_url.sl, test-calc.sl, test-console_keys.sl, test-css1.sl, test-dict-cli.sl, test-dict-curl.sl, unittesttest.sl, utf8helper-autoconvert-test.sl, utf8helper-test.sl: Switch to UTF8 encoding for test files, remove obsolete display commands 2009-01-27 10:32 milde * browse_url/browse_url.sl: added "www-browser" to Browse_Url_Browser defaults list 2009-01-27 10:27 milde * unittest/unittest.sl: new optional argument "report" to test_files(), 2009-01-26 16:50 milde * utf8helper/utf8helper.sl: Convert LaTeX inputenc options 2009-01-26 16:50 milde * txtutils/txtutils.sl: * documentation example for re_replace() (M. Mahnič) 2009-01-26 16:49 milde * diffmode/diffmode.sl: do not hightlight whitespace in first (±) column 2009-01-26 16:32 milde * ch_table/ch_table.sl: 2.5.3 Better Fallback if Unicode Data files are missing 2009-01-26 16:10 milde * tests/rst-test.sl: disable test_rst_to_pdf in automatic testing 2009-01-26 16:05 milde * cuamark/cuamark.sl: .3.2 Work around rxvt-unicode bug (Debian bug #446444) 2009-01-26 14:55 milde * folding-keypad-bindings/folding-keypad-bindings.sl: Fix syntax error in test code 2009-01-11 10:28 boekholt * rfcview/rfcview.sl: fetch rfc's using curl 2009-01-05 09:48 milde * tests/utf8helper-test.sl: utf8helper-test.sl: update and bugfix 2009-01-05 09:25 milde * tests/strutils-test.sl: add unit test for strutils.sl 2009-01-05 09:06 milde * rst/structured_text.sl: 0.6.2 * add heading underline to paragraph separators 2009-01-05 08:53 milde * cuamark/cuamark.sl: Bind Shift_Ins to cua_insert_clipboard(), fix xclip-using functions. 2008-12-22 16:54 boekholt * complete/complete.sl: rewritten to use a before_key_hook added functions to generate a completions file for S-Lang and Perl 2008-12-16 19:55 boekholt * newsflash/newsflash.sl: tagsoup cleaner didn't work right for utf-8 text don't display the summary (is usually a duplicate of the content) 2008-12-16 08:16 milde * strutils/strutils.sl: 1.6.3 bugfix: regexp search uses byte semantics (P. Boekholt) 2008-12-16 08:16 milde * rst/rst.sl: * chdir() in rst_export(), 2008-12-16 08:15 milde * filter-buffer/filter-buffer.sl: 0.4.3 Fix pcre_fsearch() for utf8 multibyte chars (P. Boekholt) 2008-12-16 08:14 milde * filelist/filelist.sl: 1.8 * use `trash` cli for deleting (if available and set) 2008-12-16 08:11 milde * cuamouse/cuamouse.sl: 1.6.3 * fix `xclip` insertion, 2008-12-16 08:10 milde * ch_table/ch_table.sl: 2.5.2 Trim Edit>Char_Table menu 2008-12-14 14:19 boekholt * sqlited/sqlited.sl: use slang 2.1 syntax 2008-12-12 08:32 milde * pymode/pymode.sl: added missing autoload, new mode-menu item and special output and help modes 2008-11-27 18:30 boekholt * dict/dict.sl: 'define' command is now on 'd' like in dictmode 2008-11-25 15:21 milde * pylit/pylit.sl: fix typo in message 2008-11-20 17:33 boekholt * info/: info.sl, info_look.sl: if node "Top" is not found, try node "top" 2008-11-15 12:04 boekholt * fileview/fileview_cmds.sl: use info_reader instead of info_mode 2008-11-06 15:38 milde * ch_table/ch_table.sl: 2.5.1 Highlight NamesList.txt, 2008-10-27 18:07 boekholt * zip/jedzip.rb: sort the zip entries 2008-10-25 13:30 boekholt * zip/: jedzip.rb, zip.sl: zip.sl and jedzip.rb added 2008-10-22 20:28 boekholt * info/: info.sl, infomisc.sl: use slang 2.1 syntax 2008-10-21 20:52 boekholt * pcre/jedpcre.sl: The search and replace functions didn't work right in utf-8 mode, so these have been dropped. 2008-10-16 21:31 boekholt * hyperman/hyperman.sl: pcre_nth_match gebruikt byte semantics 2008-10-11 16:02 boekholt * jedscape/jedscape.sl: fixed some problems with the history feature 2008-10-10 19:38 boekholt * ruby/ruby.sl: Deep indenting of parentheses levels didn't work right, so parentheses now indent by two spaces. You can make GNU Emacs' indentation compatible by adding "# -*- mode: ruby; ruby-deep-indent-paren: nil -*-" at the top of your source file. 2008-09-20 19:30 boekholt * ruby/ruby.sl: tweaked heredoc highlighting and indentation 2008-08-25 15:44 milde * utf8helper/utf8helper.sl: name has_invalid_chars() -> utf8helper_find_invalid_char() 2008-08-21 20:50 boekholt * rfcview/rfcview.sl: added delim arg to search_path_for_file() 2008-08-21 08:50 milde * temabbrv/temabbrv.sl: fix one more search_path_for_file() call 2008-08-20 11:41 milde * temabbrv/temabbrv.sl: added delim arg to search_path_for_file() 2008-08-20 11:34 milde * po_mode/po_mode.sl: added delim arg to search_path_for_file 2008-08-20 11:25 milde * templates/templates.sl: 08-20 add delim arg to search_path_for_file 2008-08-19 15:35 milde * folding-keypad-bindings/folding-keypad-bindings.sl, tests/ch_table-test.sl: use UTF8 encoding 2008-08-16 08:39 boekholt * jedscape/jedscape.sl: history didn't work right with the Search Engine feature 2008-07-29 16:05 milde * ch_table/ch_table.sl: 2.5 Replace Chartable_Blocks_File and Chartable_NameList_File with a common Chartable_Unicode_Data_Dir custom var. Autogess value for Debian defaults if invalid. 2008-07-23 11:17 milde * ch_table/ch_table.sl: 2.4.2 better handling of missing NamesList.txt and 2008-07-12 15:45 boekholt * ispell/ispell.sl: ispell_offset was wrong when there were no suggestions 2008-07-07 10:59 milde * utf8helper/utf8helper.sl: correct typo 2008-07-07 10:58 milde * utf8helper/utf8helper.sl: F8Helper_Read_Autoconvert == -2 (warn) setting 2008-07-07 10:55 milde * cuamark/cuamark.sl: 1.3.1 Bind Shift_Ins to cua_insert_clipboard(), 2008-06-19 18:26 boekholt * ffap/ffap.sl: use 'delim' argument of search_path_for_file() 2008-06-19 17:12 milde * cuamouse/cuamouse.sl: 1.6.2 * re-introduce `xclip` workaround for X-selection bug 2008-06-18 17:07 milde * tests/: cuamouse-test.sl, rst-outline-test.sl, rst-test.sl, utf8helper-autoconvert-test.sl, utf8helper-test.sl: Update test scripts to Jedmodes 2.4.4 versions of modes 2008-06-18 15:56 milde * rst/rst.sl: * line_block() 2008-06-18 15:56 milde * filelist/filelist.sl: 1.7.10 * use call_function() instead of runhooks() 2008-06-18 15:55 milde * dictmode/dictmode.sl: 0.6.4 use call_function() instead of runhooks() 2008-06-18 15:55 milde * bufutils/bufutils.sl: 1.18 New function get_local_var() 2008-05-26 16:45 milde * unittest/unittest.sl: gfixes: view_mode() autoload, _Jed_Emulation can be NULL 2008-05-26 16:44 milde * filter-buffer/filter-buffer.sl: 0.4.2 move pcre-fold code to pcre-fold.sl, add generic hiding/folding functions 2008-05-25 13:02 boekholt * jedscape/jedscape.sl: goto_column_best_try cluttered the stack 2008-05-25 12:48 boekholt * jedscape/jedscape.sl: goto_column could cause a 'Buffer is read only' error 2008-05-20 12:31 milde * rst/rst.sl: re-enable DFA cache (disabled for testing the last change) 2008-05-20 08:17 milde * utf8helper/utf8helper.sl: Fix encoding comment conversion 2008-05-20 08:16 milde * rst/rst.sl: one more DFA tweak 2008-05-16 20:46 boekholt * jedscape/jedscape.sl: use 'w3m -halfdump' to render the page 2008-05-13 15:25 milde * utf8helper/utf8helper.sl: Convert Python (and Emacs) special encoding comment 2008-05-08 19:19 boekholt * tar/tar.sl: write tar members in binary mode 2008-05-05 16:31 milde * utf8helper/utf8helper.sl: no more dependencies patches by Paul Boekholt: reset CASE_SEARCH also after failure, strtrans_utf8_to_latin1("") now works, has_invalid_chars(): initialize return value. 2008-05-05 16:30 milde * svn/svn.sl: * Use -u option for SVN status (show externally updated files) 2008-05-05 16:30 milde * rst/rst.sl: * DFA fix for interpreted text 2008-05-05 16:29 milde * recent/recent.sl: * use call_function() instead of runhooks() 2008-05-05 16:28 milde * navigate/navigate.sl: 1.3.1 * simplified testing appendix 2008-05-05 16:28 milde * make_ini/make_ini.sl: 2.13 * code cleanup, documentation update 2008-05-05 16:27 milde * libdir/libdir.sl: libdir initialisation: load ini.slc, ini.sl or pass 2008-05-05 16:21 milde * ishell/ishell.sl: * ishell_send_input() send region line-wise, with subsequent lines sent in ishell_insert_output() after receiving a response (prompt). (Please report if this creates problems, e.g. with a process that does not return a prompt in some cases). * no CR cleaning by default (define an Ishell_output_filter for offending programs or a generic one #ifdef UNIX) 2008-05-05 16:19 milde * hyperhelp/help.sl: use call_function() instead of runhooks() 2008-05-05 16:19 milde * gnuplot/gnuplot.sl: * gnuplot_help(): filter spurious output * new gnuplot_view(): run gnuplot and open (e.g. *.eps) output file (if it is defined) with default cmd * mode menu item to browse HTML doc, (active, if variable Gnuplot_Html_Doc is defined) 2008-05-05 16:17 milde * filelist/filelist.sl: * filelist_list_dir(): do not sort empty array * filelist_open_with() bugfix: do not set a default when asking for cmd to open, as this prevents opening in Jed. * separate function filelist->get_default_cmd(String filename) 2008-05-05 16:12 milde * cuamouse/cuamouse.sl: * use x_insert_selection() in cuamouse_insert() (os.sl defines it, if it does not exist) * remove `xclip` workaround, as PRIMARY selection interaction should be ok by now (but see cuamark.sl for CLIPBOARD selection handling). 2008-05-05 16:11 milde * cuamark/cuamark.sl: * X-Clipboard interaction (using xclip) following http://www.freedesktop.org/standards/clipboards.txt * hack to prevent "inkonsistent key definition error" with rxvt-unicode that defines Key_Shift_Ins as "\e2$" but uses it internally to paste the CLIPBOARD x-selection 2008-05-05 16:09 milde * bufutils/bufutils.sl: reload_buffer(): backup buffer before re-loading 2008-04-21 12:44 milde * filter-buffer/filter-buffer.sl: do not load unfinished code from pcre-fold project 2008-04-18 17:19 boekholt * ruby/ruby.sl: tweaked heredoc highlighting to support <<"END" constructs 2008-04-05 09:26 boekholt * newsflash/newsflash.sl: support xml:base attribute for Atom feeds 2008-04-02 08:38 milde * ch_table/ch_table.sl: bugfix in ct_update(): skip lines 1...3, Edit>Char_Tables menu popup for UTF8-enabled Jed, re-order mode-menu, only fit ch-table window if too small (avoids flicker), Add "Musical Symbols" block. Menu binding for describe_character (under Help) ct_goto_char(): choose from all available chars, switching unicode table if needed. "active links" (i.e. goto given char if click on number) 2008-03-22 15:34 boekholt * gdbmrecent/gdbmrecent.sl: use slang 2.1 syntax removed dependency on bufutils.sl 2008-03-15 06:57 boekholt * dict/dict.sl: now requires slang 2.1 and the iconv module 2008-03-11 15:57 milde * folding-keypad-bindings/folding-keypad-bindings.sl: first evaluation version 2008-03-08 12:43 boekholt * tar/: tar.sl, tarhook.sl: use run_mode_hooks use open_filter_process 2008-03-07 19:55 boekholt * ruby/ruby.sl: tweaked the DFA rules and color_region_hook 2008-02-25 09:21 milde * txtutils/txtutils.sl: * update help for newline_indent() 2008-02-24 09:50 boekholt * hyperman/hyperman.sl: use run_mode_hooks use slang 2.1 syntax 2008-02-23 08:11 boekholt * email/email.sl: use run_mode_hooks() 2008-02-21 14:17 milde * ruby/ruby.sl: use run_mode_hooks() instead of runhooks() 2008-02-19 14:26 milde * svn/svn.sl: next try to fix vc_commit_finish() 2008-02-19 14:21 milde * svn/svn.sl: next try to fix update after commit # --- diese und die folgenden Zeilen werden ignoriert --- Dir: /home/milde/.jed/jedmodes/src/mode/svn/ Files: svn.sl 2008-02-19 13:24 milde * svn/svn.sl: fix update after commit 2008-02-19 11:17 milde * svn/svn.sl: fix in file_p 2008-02-19 10:28 milde * svn/svn.sl: CVS keyword fix 2008-02-19 10:17 milde * svn/svn.sl: add CVS keywords for this file bury output buffer after commit (show last line in minibuffer) re-open instead of reload buffers to avoid "file changed on disk" questions 2008-02-06 18:01 milde * tests/cuamouse-test.sl: adapt click_in_region_test() to new return values 2008-02-06 16:52 milde * svn/svn.sl: bugfixes: diff_filenames holds Integer_Type values, add missing autoloads, get_blocal --> get_blocal_var() 2008-02-06 15:42 milde * unittest/unittest.sl: removed (direct) dependency on datutils 2008-02-06 15:36 milde * cuamouse/cuamouse.sl: 1.6 * fix swapped args to click_in_region() in cuamouse_left_down_hook() * support for scroll-wheel * button-specific hooks with return values 2008-02-01 19:21 boekholt * jedscape/jedscape.sl: use SQLite for bookmarks 2008-02-01 16:24 milde * tests/datutils-test.sl: added tests for array() 2008-01-27 23:39 boekholt * newsflash/newsflash.sl: removed Content-Type header (it's probably not needed) 2008-01-27 16:26 boekholt * rfcview/rfcview.sl: now requires slang 2 2008-01-27 15:26 boekholt * newsflash/newsflash.sl: tweaked HTTP headers (John E. Davis) now requires slang 2.1 2008-01-27 11:11 boekholt * hyperman/hyperman.sl: use PCRE regexps now requires slang 2 2008-01-26 11:40 boekholt * hyperman/hyperman.sl: revision 1.7 reverted the change of 1.6 2008-01-26 11:32 boekholt * hyperman/hyperman.sl: improvements to whatis function (G. Milde) improvements to documentation (G. Milde) 2008-01-25 16:09 milde * utf8helper/utf8helper.sl: remove dependency on datutils.sl and sl_utils.sl 2008-01-25 09:46 milde * uri/services.sl: move services.sl to directory uri/ 2008-01-22 13:03 milde * rst/rst.sl: remove umlaut 2008-01-22 13:02 milde * rst/rst.sl: * made export_cmds static for better testing 2008-01-22 12:07 milde * rst/rst-outline.sl: * KP keybindings require x-keydefs 2008-01-22 12:06 milde * unittest/unittest.sl: test_files(): better report formatting 2008-01-22 12:05 milde * utf8helper/utf8helper.sl: helper fun register_autoconvert_hooks() 2008-01-22 11:31 boekholt * ruby/ruby.sl: cleaned up DFA rules 2008-01-21 17:06 milde * tests/utf8helper-test.sl: new formatting, "active encoding" -> "native encoding" 2008-01-21 17:04 milde * tests/utf8helper-autoconvert-test.sl: Ensure the autoconvert hooks are set New setup logic new testfun for new autoconvert() helper function new testfun for loading a file in native encoding (nothing to do) 2008-01-21 16:59 milde * tests/unittesttest.sl: clarify testmessages 2008-01-21 16:59 milde * tests/rst-test.sl: test_set_export_cmd in a loop over export_type arguments 2008-01-21 16:56 milde * tests/ch_table-test.sl: simpler code, add 2 lines of documentation 2008-01-21 16:48 milde * unittest/unittest.sl: Unittest_Skip_Patterns replaced by Unittest_Skip_Pattern, code cleanup, better testreporting 2008-01-21 16:48 milde * filelist/filelist.sl: 1.7.8 * fix stack leftovers in filelist_open_file() 2008-01-21 16:47 milde * ch_table/ch_table.sl: 2.4 variable upper limit, as unicode has more than 255 chars, 2008-01-21 16:46 milde * bufutils/bufutils.sl: 1.17 fit_window(): recenter if window contains whole buffer 2008-01-17 20:27 boekholt * ispell/ispell.sl: use Ispell_Program_Name in messages (G. Milde) 2008-01-17 09:45 milde * tests/rst-test.sl: "_long suffix" to the testing functions dropped, as set_export_cmd() is no longer slow, 2008-01-16 13:42 milde * rst/rst-outline.sl: * bugfix in heading() 2008-01-11 15:44 milde * tokenlist/tokenlist.sl: popup_buffer() was used in the wrong place: put it in tkl_display_results() 2008-01-11 15:42 milde * sl_utils/sl_utils.sl: 1.5.6 Documentation update for run_function() and get_blocal() 2008-01-11 15:09 milde * rst/rst-outline.sl: outsourced from rst.sl 2008-01-11 14:26 milde * rst/rst.sl: * section headings: allow for adorning with overline * split outline and section functions to rst-outline.sl * implement Jörg Sommer's fix for DFA under UTF-8 2008-01-11 14:24 milde * pylit/pylit.sl: update last-changed date 2008-01-11 14:22 milde * pylit/pylit.sl: ) 2008-01-11 14:22 milde * bufutils/bufutils.sl: 1.16 reload_buffer(): insert disk version, delete content later 2008-01-10 15:37 milde * x-keydefs/x-keydefs.sl: documentation formatting 2008-01-07 10:19 milde * x-keydefs/x-keydefs.sl: do not change the keystring of the [Esc] key to Key_Escape 2008-01-04 10:51 milde * svn/svn.sl: vc_commit_finish() left the window open 2008-01-04 10:29 milde * x-keydefs/x-keydefs.sl: bugfix: set default for Key_Esc to "\e\e\e" 2008-01-04 08:24 milde * strutils/strutils.sl: 1.6.2 docu fix in strsplit(), max_n not functional yet; bugfix for n_max=0 in str_re_replace() 2008-01-03 14:42 milde * svn/svn.sl: bugfix in vc_commit_buffer 2008-01-03 13:40 milde * svn/svn.sl: small documentation fixes 2007-12-30 19:58 boekholt * email/email.sl: tweaked DFA highlighting to work with flyspell mode (J. Sommer) 2007-12-23 11:48 boekholt * sqlited/sqlited.sl: use sqlite_get_array 2007-12-20 12:26 milde * hyperhelp/help.sl: add Jörg Sommer's fix for DFA highlight under UTF-8 new highlight rules for keyword and headings 2007-12-20 12:25 milde * grep/grep.sl: rename grep->grep_replace_cmd() to grep->replace_cmd() rebind also cua_replace_cmd() to grep->replace_cmd() apply Jörg Sommer's DFA-UTF-8 fix and re-enable highlight 2007-12-20 12:24 milde * filter-buffer/filter-buffer.sl: generic (un)folding of blocks; use PCRE regexps; re_fold_buffer() 2007-12-20 12:22 milde * filelist/filelist.sl: add Jörg Sommer's fix for DFA highlight under UTF-8 2007-12-20 12:21 milde * ding/ding.sl: * ding(): an empty string arg triggers an interactive request for a word the same way as no optional arg does. * custom var Ding_Case_Search, * failsave formatting. 2007-12-20 12:19 milde * diffmode/diffmode.sl: use standard color-name 'trailing_whitespace', implement Jörg Sommer's fix for DFA highlight under UTF-8 2007-12-20 12:18 milde * cuamouse/cuamouse.sl: formatting documentation 2007-12-20 12:16 milde * ch_table/ch_table.sl: implement Jörg Sommer's fix for DFA highlight under UTF-8 2007-12-19 09:43 milde * gnuplot/gnuplot.sl: 1.1.5 fixed view_mode() autoload 2007-12-18 15:30 milde * svn/svn.sl: * New functions: vc_subtract_selected(), vc_delete_selected, vc_commit_dir() * remove spurious arg in vc_commit_finish() * bugfixes in marking and committing 2007-12-15 10:20 boekholt * ruby/ruby.sl: the color_region_hook broke query_replace regexp indent "else if" block by two levels 2007-12-13 11:41 boekholt * ffap/ffap.sl: try to parse "file:line number" (G. Milde) 2007-12-12 12:01 boekholt * hyperman/hyperman.sl: updated for bufutils 1.15 (G. Milde) 2007-12-12 11:57 boekholt * pcre/jedpcre.sl: pcre_match isn't needed (G. Milde) 2007-12-12 11:10 milde * sl_utils/sl_utils.sl: Documentation update for run_function() 2007-12-12 11:03 milde * dictmode/dictmode.sl: optional extensions with #if ( ) 2007-12-11 16:32 milde * txtutils/txtutils.sl: * new function re_replace() 2007-12-11 16:31 milde * ishell/ishell.sl: new output_placement "l": Log (input and output) in outbuf 2007-12-11 16:22 milde * svn/svn.sl: * Key_Ins selects and moves down one line * vc_list_dir() did open a buffer even if dir not under vc * basic support for SVK (http://svk.bestpractical.com/) * edit log-message in a dedicated buffer * after commit, update all buffers that changed on disk 2007-12-11 15:07 milde * tests/: test-csvutils.sl, test-ishell.sl: remove obsolete procedural tests (test-*.sl replaced by *-test.sl) 2007-12-11 14:57 milde * tests/: csvutils-test.sl, cuamouse-test.sl, ishell-test.sl: csvutils-test.sl: fix change date ishell-test.sl: test availability of public functions, code cleanup cuamouse-test.sl: add changelog 2007-12-09 12:51 boekholt * ruby/ruby.sl: use wherefirst instead of any use list2array if __push_list isn't defined 2007-12-09 11:01 boekholt * email/email.sl: Added Joerg Sommer's DFA fix for utf-8 2007-12-08 08:24 boekholt * cal/: cal.otl, cal.sl, calendar.sl, diary.sl: added calendar.sl added DFA fix for utf-8 (Joerg Sommer) cal now requires slang 2 2007-12-07 17:57 boekholt * ispell/flyspell.sl: use DFA even in utf-8 mode added Joerg Sommer's DFA rule to fix display in utf-8' 2007-12-07 17:07 milde * tests/: ch_table-test.sl, test-ch_table.sl: remove obsolete procedural test file 2007-12-07 15:51 milde * tests/: ch_table-lat1-decimal.txt, ch_table-test.sl, ch_table-utf8-decimal.txt, csvutils-test.sl, cuamark-test.sl, cuamouse-test.sl, datutils-test.sl, ishell-test.sl, listing-test.sl, pymode-test.sl, rst-outline-test.sl, rst-test.sl, structured_text-test.sl, test-browse_url.sl, test-calc.sl, test-ch_table.sl, test-console_keys.sl, test-css1.sl, test-csvutils.sl, test-dict-cli.sl, test-dict-curl.sl, test-ishell.sl, unittesttest.sl, utf8helper-autoconvert-test.sl, utf8helper-test.sl: Unit tests for some of the jedmodes modes. Work in progress, some test are only partial. Needs the unittest.sl mode. 2007-12-05 11:32 milde * pymode/pymode.sl: - implement Jörg Sommer's fix for DFA highlight under UTF-8 2007-12-04 19:32 boekholt * ruby/ruby.sl: added Joerg's workaround for DFA bug in utf-8 tweaked the heredoc highlighting 2007-12-01 09:34 boekholt * newsflash/newsflash.sl: use sqlite_get_array() instead of sqlite_get_table() 2007-11-27 20:57 boekholt * ruby/ruby.sl: added heredoc support (experimental) tweaked the indentation and DFA rules 2007-11-25 18:39 boekholt * ispell/: flyspell.sl, ispell.otl: Always turn DFA off if a blocal flyspell_syntax_table is set 2007-11-23 12:20 milde * cuamark/cuamark.sl: cua_insert_clipboard(): make insertion visible by updating 2007-11-18 16:21 boekholt * ispell/: flyspell.sl, ispell.sl: more informative error message if ispell can't be run 2007-11-15 17:35 milde * rst/rst.sl: custom colors, re-enable dfa cache 2007-11-13 14:28 milde * rst/rst.sl: * rewrite syntax highlight rules with ""$ string replacement (Attention! can lead to segfaults with older, buggy S-Lang versions: update S-Lang or downgrade rst.sl) 2007-11-06 12:21 milde * rst/rst.sl: * highlight simple table rules 2007-11-02 17:13 boekholt * ruby/ruby.sl: rewrote some of the indentation and keybindings code 2007-10-27 18:04 boekholt * ruby/ruby.sl: improved the DFA syntax rules 2007-10-23 11:03 milde * cua/cua.sl: use cua_replace_cmd() (needs cuamisc.sl >= 1.6.3) 2007-10-23 11:00 milde * rst/rst.sl: Add admonitions popup to the Directives menu, use hard-coded TAB in non-expanded (R) syntax rules, add '.' to chars allowed in crossreference marks 2007-10-23 10:59 milde * make_ini/make_ini.sl: documentation update, create DFA cache files 2007-10-23 10:57 milde * grep/grep.sl: no DFA highlight cache (it's just one rule) 2007-10-23 10:54 milde * filelist/filelist.sl: 1.7.7 * no DFA highlight caching 2007-10-23 10:43 milde * diffmode/diffmode.sl: switch on highlight caching 2007-10-23 10:42 milde * cuamouse/cuamouse.sl: provide("mouse") as mouse.sl does not do so 2007-10-23 10:41 milde * cuamisc/cuamisc.sl: new fun cua_replace_cmd() 2007-10-23 10:39 milde * ch_table/ch_table.sl: do not cache the dfa highlight table 2007-10-21 20:49 boekholt * ruby/ruby.sl: fixed two bugs in the indentation 2007-10-18 19:56 milde * rst/rst.sl: make rst_list_routines_extract static 2007-10-18 19:53 milde * datutils/datutils.sl: fix array_value_exists() for Any_Type arrays, documentation update 2007-10-18 18:48 milde * tokenlist/tokenlist.sl: fix opional use of popup_buffer() 2007-10-18 17:18 milde * hyperhelp/help.sl: re-introduce the sprint_variable() autoload 2007-10-18 16:09 milde * libdir/libdir.sl: add|append doc-file to doc_files list 2007-10-18 12:08 milde * tokenlist/tokenlist.sl: help text for public functions 2007-10-18 11:42 milde * svn/svn.sl: vc_add_dir(): Non-recursive also under SVN 2007-10-18 11:41 milde * cua/cua.sl: optional extensions with #if ( ) 2007-10-18 11:36 milde * ch_table/ch_table.sl: code cleanup 2007-10-18 10:23 milde * tokenlist/tokenlist.sl: fix optional use of popup_buffer if bufutils.sl is present 2007-10-18 10:20 milde * rst/rst.sl: update to work with tokenlist.sl newer than 2007-05-09 2007-10-15 10:42 milde * hyperhelp/help.sl: reenable DFA for utf-8 as help normally has no multibyte chars 2007-10-04 18:17 boekholt * dict/dict.sl: now requires slang 2.0.7 2007-10-04 14:42 milde * hyperhelp/help.sl: [no log message] 2007-10-02 12:04 milde * ishell/ishell.sl: fix documentation typos 2007-10-02 10:47 milde * apsmode/apsmode.sl: bugfix 2007-10-01 17:49 milde * svn/svn.sl: bugfix (missing variable declaration) 2007-10-01 17:12 milde * tokenlist/tokenlist.sl: autoload bufutils.sl if present 2007-10-01 16:59 milde * diffmode/diffmode.sl, filelist/filelist.sl, hyperhelp/help.sl, make_ini/make_ini.sl: optional extensions with #if ( ) 2007-09-29 20:54 boekholt * ispell/: ispell.otl, ispell_common.sl, ispell_init.sl: added an aspell_add_dictionary() function use aspell by default if it's installed 2007-09-24 12:26 milde * utf8helper/utf8helper.sl: latin1_to_utf8(): did not convert two (or more) high-bit chars in a row in non-UTF8 mode. 2007-09-24 11:49 milde * utf8helper/utf8helper.sl: bugfix in utf8_to_latin1() (report P. Boekholt). 2007-09-21 12:20 milde * rst/structured_text.sl: fix Text_List_Patterns 2007-09-21 09:33 milde * view/view.sl: bugfix in enable_edit(): fall back to no_mode(). 2007-09-20 16:54 milde * filter-buffer/filter-buffer.sl: copy_visible_lines() now works also for readonly buffers 2007-09-20 16:53 milde * ding/ding.sl: reset blocal var "encoding" with buffer re-use 2007-09-20 16:52 milde * utf8helper/utf8helper.sl: convert region instead of buffer if visible region is defined 2007-09-18 21:08 boekholt * gdbmrecent/gdbmrecent.sl: the open_hook was broken by a change in sscanf in S-Lang 2.1.1 2007-09-15 08:18 boekholt * sqlited/sqlited.sl: new functions sqlited_table() and sqlited_view() for opening a sqlited table or view from another mode 2007-09-08 18:08 boekholt * tm/tm.sed: added some new tm macros 2007-09-06 22:17 boekholt * ruby/ruby.sl: modernized the code a bit fixed a few bugs 2007-09-03 15:26 milde * diffmode/diffmode.sl: highlight trailing whitespace; bugfixes after report by P. Boekholt 2007-09-03 13:20 milde * cua/cua.sl: bind eol() instead of eol_cmd() to Key_End 2007-09-01 13:34 boekholt * newsflash/newsflash.sl: use placeholders in sqlite commands 2007-08-31 13:10 milde * filter-buffer/filter-buffer.sl: bugfix in delete_hidden_lines() (J. Sommer, GM) 2007-08-02 08:56 milde * svn/svn.sl: Revised layout and hotkeys of vc and vc_list_mode menu 2007-07-27 16:25 milde * diffmode/diffmode.sl: bugfix in diff_juimp_to() 2007-07-26 16:06 milde * utf8helper/utf8helper.sl: utf8helper_read_hook(): reset buffer_modified_flag 2007-07-25 16:57 milde * utf8helper/utf8helper.sl: customizable activation of hooks 2007-07-25 16:53 milde * x-keydefs/x-keydefs.sl: renamed set_keyvar() to _keystr() 2007-07-25 16:52 milde * unittest/unittest.sl: added test_unequal() 2007-07-24 10:03 milde * svn/svn.sl: adapt to SVN 1.4 entries file format 2007-07-24 09:47 milde * diffmode/diffmode.sl: bugfix in diff_buffer, documentation fix 2007-07-23 16:05 milde * ding/ding.sl: convert iso-latin1 <-> UTF-8 if not in UTF-8 mode. 2007-07-23 15:16 milde * utf8helper/utf8helper.sl: first public version 2007-07-23 13:40 milde * diffmode/: diffmode.sl, treemode.sl: first publication on jedmodes 2007-07-23 11:40 milde * svn/svn.sl: Set default of SVN_set_reserved_keybindings to 0 to prevent clashes with mode-specific bindings, code reorganisation, Mode menu for listings, Removed SVN_help: Keybindings are shown in mode menu 2007-07-23 11:37 milde * rst/rst.sl: rename section_markup() to section_header(), allow integer arguments (section level), new functions rst_view() and rst_view_html(), rst_view_pdf, rst_view_latex obsoleting rst_browse() 2007-07-02 18:18 milde * rst/structured_text.sl: rename line_is_empty() -> line_is_blank, as it may contain whitespace new function st_format_paragraph() with correct formatting of multi-line list-items relax match-requirement in line_is_list to allow UTF-8 multi-byte chars in Text_List_Patterns. (request Joerg Sommer) 2007-06-21 11:33 milde * pymode/pymode.sl: add autoload for fit_window() 2007-06-09 14:45 boekholt * jedscape/jedscape.sl: gettext is now optional xml and atom content types can now be opened in newsflash 2007-06-06 15:16 milde * view/view.sl: view_mode: folding_mode() -> fold_mode() to respect the setting of `Fold_Mode_Ok without asking. Moved definition of set_view_mode_if_readonly() to Customization documentation. 2007-06-03 12:37 boekholt * hyperman/hyperman.sl: moved 'require' above 'implements' to fix namespace issue fixed some problems with the bold and italic markers - I can't test this since man doesn't give me any in Etch - see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=340673 The next version will probably use DFA highlighting again. 2007-05-31 17:24 milde * hyperhelp/help.sl: bugfix in where_is(), removed spurious line 2007-05-31 14:35 milde * ch_table/ch_table.sl: bugfix in ct_update: did mark too much if at eol, disable dfa syntax highlighting in UTF8 mode to make ch_table.sl UTF8 safe, documentation for public functions. 2007-05-31 10:57 milde * cuamisc/cuamisc.sl: fix documentation of jbol() 2007-05-25 15:56 milde * svn/svn.sl: Use buffer_dirname() instead of getcwd() as default for project directory 2007-05-25 15:55 milde * strutils/strutils.sl: optimised str_re_replace() by Paul Boekholt 2007-05-25 15:50 milde * pymode/pymode.sl: [no log message] 2007-05-25 15:48 milde * filelist/filelist.sl: bugfix in filelist_open_file() 2007-05-16 09:34 milde * svn/svn.sl: require_buffer_dir_in_svn() now also returns "entries" dir as its path differs between CVS and SVN 2007-05-14 11:34 milde * txtutils/txtutils.sl: documentation update, insert_block_markup() inserts newline if region|word, doesnot start at bol 2007-05-14 11:33 milde * rst/rst.sl: removed leading \n from Markup_Tags, simplified dfa rules using ""R string suffix, rst_levels: use String_Type instead of list 2007-05-14 11:31 milde * pymode/pymode.sl: simplified browse_pydoc_server(), added info about DFA syntax highlight to pymode_hook doc 2007-05-14 11:22 milde * ishell/ishell.sl: cleanup in ishell() 2007-05-14 11:15 milde * cuamisc/cuamisc.sl: removed ``add_completion("cua_save_as")``, added Joergs Sommers jbol() 2007-05-13 10:29 boekholt * bufed/: bufed.sl, bufed_srch.sl: improved error handling with try-catch semantics search_tagged and replace_tagged functions are now static 2007-05-11 18:47 milde * hyperhelp/help.sl: edited help_string, removed use of prompt_for_argument(), fix in help_search(), handle "namespace->object" notation 2007-05-11 11:40 milde * bufutils/bufutils.sl: run_local_function(): try mode-info also with normalized_modename(), use mode_info instead of global var for help_message() 2007-05-10 22:25 boekholt * newsflash/newsflash.sl: links didn't work in Atom feeds autoload for browse_url was missing provide was missing 2007-05-10 08:57 milde * strutils/strutils.sl: new function strsplit() 2007-05-09 10:01 manicm * tokenlist/tokenlist.sl: version change 2007-05-09 09:51 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl, tokenlist_sl.html: - renamed list_regex -> list_regexp - removed the old list_routines interface. Use _list_routines_setup. - added "construcotr" New_Tokenlist_Operation_Type 2007-05-08 17:13 manicm * tokenlist/tokenlist.sl: moccur comment 2007-05-08 17:03 manicm * tokenlist/tokenlist.sl: no message 2007-05-04 17:37 milde * svn/svn.sl: Support both SVN and CVS 2007-05-04 17:06 milde * pylit/pylit.sl: literate version 2007-05-02 09:14 milde * filelist/filelist.sl: documentation update 2007-04-30 18:45 milde * svn/svn.sl: syntax highlight (DFA) in directory listing, auto-determine if cvs or svn is used (check for .SVN or .svn dir), fit_window() for popup buffers 2007-04-27 16:11 milde * svn/svn.sl: bugfix: wrong namespace name 2007-04-27 11:25 milde * svn/svn.sl: % * block replacing the evaluation of svn.sl at startup % * bugfix: return to directory listing before postprocessing % * use popup_buffer instead of pop2buf: % - closing with close_buffer() closes the window as well % (if it wasn't open before). 2007-04-27 11:23 milde * svn/svn.sl: Juho Snellman's cvs mode with svn patch 2007-04-23 13:51 milde * filelist/filelist.sl: filelist_view_file(): never close calling filelist 2007-04-21 12:27 boekholt * ispell/: flyspell.sl, ispell.otl, ispell.sl, ispell_common.sl, ispell_init.sl, look.sl, vispell.sl: now requires slang 2 2007-04-19 12:42 milde * listing/listing.sl: added a "Save Listing" entry to the mode menu 2007-04-19 12:34 milde * grep/grep.sl: mini doc edit 2007-04-19 11:57 milde * grep/grep.sl: added mode menu and more Customisation hints 2007-04-18 16:41 milde * filelist/filelist.sl: filelist_open_file() improvements, filelist_open_in_otherwindow() (request by Lechee Lai) 2007-04-18 16:04 milde * bufutils/bufutils.sl: new function run_local_function() (used in help.sl), example for "Fit Window" menu entry, TODO: (should this become an INITIALIZATION block?) 2007-04-18 15:39 milde * tokenlist/tokenlist.sl: non-maintainer upload with bugfix in tkl_list_tokens() preventing an infinite loop if there is a match on the last line of a buffer 2007-04-18 15:26 milde * ruby/ruby.sl: added "public" to ruby_mode definition 2007-04-17 13:21 milde * listing/listing.sl: removed the dired-style Key_BS binding (tag&up) as this overrides the default (page_up) of the basic "view" mode 2007-04-17 12:03 milde * ding/ding.sl: replaced custom variable Wordlists with private one and auxiliary function ding->add_dictionary Documentation update, cleanup, bugfixes: Case sensitivity, Ding_Dictionary 2007-04-16 14:51 milde * ding/ding.sl: bugfix in Ding_Wordlists initialization 2007-04-16 10:35 milde * filelist/filelist.sl: Changed the keybinding for (i)search from '^S' to 's' to match the one in tokenlist and keep the original '^S'. 2007-04-16 10:11 milde * ding/ding.sl: renamed Wordlists -> Ding_Wordlists, error message, if no dictionaries found 2007-04-09 14:05 boekholt * ffap/ffap.sl, rimini/rimini.sl: fixed a few bugs in ffap.sl and rimini.sl 2007-03-30 15:19 milde * rst/rst.sl: unit tests and fixes 2007-03-10 13:50 manicm * m_history/history.sl: bugfix: save_history_at_exit sometimes prevented exiting jed (pboekholt) 2007-03-07 11:40 milde * numbuf/numbuf.sl: patches by Sangoi Dino Leonardo: number_buffer() and Numbered_Buffer_List made private, fix message in goto_numbered_buffer(n) 2007-03-07 09:25 milde * numbuf/numbuf.sl: numbuf_menu_callback() depended on Global.sw2buf() from bufutils. Report Sangoi Dino Leonardo 2007-03-01 18:23 boekholt * newsflash/newsflash.sl: fixed a few issues 2007-02-26 13:28 milde * rst/rst.sl: new Rst2Pdf_Cmd 2007-02-23 14:03 milde * grep/grep.sl: bugfix: grep() did recursive grep for empty basename in grep pattern 2007-02-21 11:32 manicm * brief/briefmsc.sl: public declarations removed since the functions are specific to BRIEF emulation and should not be loaded at startup (via make_ini). If needed, they can still be autoloaded from jedrc. 2007-02-15 12:01 manicm * m_history/mini.sl: added a TODO comment 2007-02-14 14:33 manicm * m_history/mini.sl: exit_mini was not called on empty entries 2007-02-14 12:33 manicm * m_history/: hist-cls.sl, history.sl, mini.sl: no message 2007-02-11 11:54 manicm * brief/: brief.sl, briefmsc.sl: functions moved from brief.sl to briefmsc.sl functions marked public and scarsely documented 2007-02-10 18:11 manicm * tokenlist/tokenlist.sl: fixed a while loop followed by else (new in slang 2.1) 2007-02-07 18:59 boekholt * gdbmrecent/gdbmrecent.sl: forgot to apply the exit_hook fix 2007-02-07 10:14 milde * ruby/ruby.sl: new upload to jedmodes 2007-02-06 19:08 boekholt * gdbmrecent/gdbmrecent.sl: Missing requires added (Rafael Laboissiere) exit_hook() left garbage on the stack (Rafael Laboissiere) Requires S-Lang 2 2007-02-06 13:03 milde * pylit/pylit.sl: call rst_mode() if the output buffer is text 2007-02-06 13:00 milde * rst/rst.sl: Removed Rst2*_Options custom variables, PDF export, small additions and fixes 2007-02-06 11:52 milde * datutils/datutils.sl: new function list_inject(), new versions of assoc_get_key() and array_sum() (JED) 2007-02-06 11:50 milde * unittest/unittest.sl: removed _lists_equal() and is_equal(), using _eqs() instead 2007-02-06 10:55 milde * pymode/pymode.sl: use sprintf() instead of ""$ for `outbuf` string in py_exec() 2007-01-28 13:40 boekholt * info/: info.sl, info_look.sl, infomisc.sl, treemode.sl: info now requires slang 2 info_mode() renamed to info_reader() 2007-01-24 17:26 milde * pylit/pylit.sl: bugfix in pylit_check() 2007-01-23 15:13 milde * pylit/pylit.sl: first public release 2007-01-23 10:54 milde * css1/css1.sl: bugfix in call to run_mode_hooks(), comments with comments.sl 2007-01-15 16:11 milde * strutils/strutils.sl: bugfix in str_re_replace_all() by M. Johansen 2007-01-15 11:35 milde * pymode/pymode.sl: various bugfixes and extensions 2007-01-15 09:46 milde * strutils/strutils.sl: added str_re_replace_by_line() after a report by Morten Bo Johansen that str_re_replace_all is dead slow for large strings. 2006-12-20 12:53 manicm * tokenlist/: tokenlist.sl, tokenlist_sl.html: documentation updated removed the first call to tokenlist_routine_setup_hook 2006-12-19 20:18 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl: - hook for delayed and customizable loading of tkl-modes.sl - INITIALIZATION section (for make_ini() or manual copy to .jedrc) - tm documentation for TokenList_Startup_Mode - changed the interface to use _list_routines_setup 2006-12-12 15:26 milde * datutils/datutils.sl: new function list_inject(), new versions of assoc_get_key() and array_sum() (JED) 2006-12-02 12:55 boekholt * newsflash/newsflash.sl: RRS/Atom reader. 2006-11-28 18:19 milde * rst/rst.sl: use do_shell_cmd() for error redirection 2006-11-28 18:10 milde * rst/rst.sl: Drop the .py ending from the Rst2* custom variables defaults 2006-11-27 17:33 milde * datutils/datutils.sl: removed array_reverse() 2006-11-23 17:51 milde * pymode/pymode.sl: major code cleanup and many bugfixes after unit-testing 2006-11-23 14:37 milde * ishell/ishell.sl: bugfix in shell_cmd_on_region_or_buffer() 2006-11-23 12:24 milde * bufutils/bufutils.sl: bugfix in reload_buffer(): reset "changed on disk" flag before erasing buffer (to prevent asking befor edit) 2006-11-10 16:39 milde * ishell/ishell.sl: shell_cmd_on_region_or_buffer() now saves the buffer to a temporary file if there is no file associated to the buffer (and no visible region) 2006-11-10 15:38 milde * txtutils/txtutils.sl: bugfix: indent_region_or_line() did not indent a regions last line 2006-10-23 11:29 milde * bufutils/bufutils.sl: bugfix in bufsubfile() by Paul Boekholt "\\/ " specifies a character class / 2006-10-21 19:56 boekholt * info/info.sl: "\\?" was an invalid character class 2006-10-09 15:17 milde * ishell/ishell.sl: [no log message] 2006-10-08 16:45 boekholt * jedscape/jedscape.sl: fixed a few bugs 2006-10-06 08:47 milde * listing/listing.sl: use the new (SLang2) "list" datatype 2006-10-05 17:29 milde * unittest/testscript-wizard.sl: added experimental testscript-wizard 2006-10-05 17:21 milde * unittest/unittest.sl: added requirements 2006-10-05 17:15 milde * cuamouse/cuamouse.sl: bugfixes after testing, use mark_word() from txtutils.sl (new dependency!) 2006-10-05 15:18 milde * ch_table/ch_table.sl: bugfix in ct_insert_and_close(), return to calling buf 2006-10-05 14:44 milde * csvutils/csvutils.sl: replaced spaces2tab with an optional arg to buffer_compress 2006-10-04 15:30 milde * ishell/ishell.sl: bugfix in shell_command: set_readonly(1) before writing 2006-10-04 10:19 milde * txtutils/txtutils.sl: fix spurious spot in indent_region_or_line() 2006-10-04 10:14 milde * sprint_var/sprint_var.sl: bugfix in sprint_list() 2006-10-04 10:06 milde * ishell/ishell.sl: shell_cmd_on_region_or_buffer: use bufsubfile() only if *visible* mark is set 2006-10-04 10:03 milde * datutils/datutils.sl: added list_concat() 2006-10-04 10:00 milde * bufutils/bufutils.sl: bufsubfile() uses make_tmp_file(), documentation update 2006-10-03 12:23 boekholt * rimini/rimini.sl: [no log message] 2006-09-30 09:36 boekholt * server/server.sl: editing server. Uses the emacsserver and emacsclient programs. 2006-09-29 20:25 boekholt * jedscape/jedscape.sl: url_file variable no longer includes the host part added jedscape_curlopt_hook 2006-09-29 17:41 milde * pymode/pymode.sl: bugfix and update, still not tested 2006-09-29 17:38 milde * unittest/unittest.sl: test discovery analogue to the python nose test framework 2006-09-28 20:40 boekholt * email/email.sl: Fixed DFA highlighting in UTF-8 implements("email") won't let me autoload("email->requote_buffer") requote_buffer left point on the previous line if it was at bol 2006-09-28 17:11 boekholt * dict-backend/dict-curl.sl: Removed quoting of multi word keywords again (is not needed and does not work in curl 7.15) 2006-09-27 09:53 boekholt * dict-backend/dict-curl.sl: removed dollar strings (cause segfaults in slang 2.0.6 fixed lookup of multiword terms 2006-09-26 15:04 milde * dictmode/dictmode.sl: bugfix for {multi word keywords} (report Paul Boekholt) 2006-09-26 11:56 milde * dictmode/dictmode.sl: bugfix for {multi word keywords} (Paul Boekholt) 2006-09-25 17:55 milde * dict-backend/dict-cli.sl: use do_shell_cmd() for error redirection 2006-09-22 18:36 milde * grep/grep.sl: removed spurious debug output (report P Boekholt) 2006-09-21 17:49 milde * hyperhelp/help.sl: patches by P. Boekholt and J. Sommer 2006-09-20 11:38 milde * grep/grep.sl: grep_fsearch() did not find matches right after the colon 2006-09-16 20:38 boekholt * pcre/: jedpcre.sl, pcre.sl: renamed pcre.sl to jedpcre.sl 2006-09-15 15:49 milde * pymode/pymode.sl: first version at jedmodes 2006-09-14 10:20 milde * txtutils/txtutils.sl: New function newline_indent() (fix pasting in x-terminal) 2006-09-07 18:06 milde * hyperhelp/help.sl: Added Slang 2 keywords for exception handling, fix help-string for internal functions, fix help_display_list() 2006-08-22 08:13 boekholt * sqlited/sqlited.sl: SQLite administration mode 2006-08-14 18:02 milde * rst/: rst.sl, structured_text.sl: bugfix: rename text_mode_hook() to structured_text_hook() to avoid name clashes. 2006-07-30 15:30 boekholt * jedscape/jedscape.sl: removed dollar strings (they're buggy in some versions of S-Lang) downloading was messing up the history and other settings 2006-07-20 11:21 milde * cuamark/cuamark.sl: bugfix: cua_insert_clipboard() returned a value; removed call to cuamark_hook(); removed CuaCopyToClipboard 2006-07-12 11:20 milde * unittest/unittest.sl: first experimental release 2006-07-10 17:31 milde * csvutils/csvutils.sl: doc update and bugfixes after basic testing 2006-07-06 15:59 milde * apsmode/: SLang.ssh, apsconf.template, apsmode.hlp: Update to version 2.2, apsconf directory no longer used 2006-07-05 09:35 milde * apsmode/apsmode.sl: [no log message] 2006-06-28 13:33 milde * grep/grep.sl: fixed deletion of last empty line in grep() output 2006-06-23 09:52 milde * datutils/datutils.sl: added list functions, full tm documentation 2006-06-22 11:18 milde * sprint_var/sprint_var.sl: added list printing 2006-06-19 17:00 milde * bufutils/bufutils.sl: fit_window(): abort if there is only one open window 2006-06-19 16:52 milde * sl_utils/sl_utils.sl: Documentation fix for push_defaults() 2006-06-14 15:29 boekholt * dict/dict.sl: typo fixed 2006-06-14 15:21 boekholt * dict/dict.sl: Works with the socket module in s-lang 2.0.7 Menu for selecting the dictionary and search strategy added 2006-06-09 13:19 milde * filter-buffer/filter-buffer.sl: INITIALIZATION: moved the menu entries to a popup 2006-06-07 15:13 boekholt * info/info.sl: cleaned up the code 2006-06-05 14:43 boekholt * rfcview/rfcview.sl: some bugfixes 2006-06-03 19:59 boekholt * ispell/: flyspell.sl, ispell.sl, ispell_common.sl, ispell_init.sl: Fixed some bugs in flyspell ispell_init requires sl_utils 2006-06-01 14:42 milde * datutils/datutils.sl: provide("datutils"); 2006-06-01 14:10 milde * strutils/strutils.sl: added provide() added autoload for push_defaults() 2006-06-01 12:02 milde * apsmode/apsmode.sl: made user-definable variables custom_variables 2006-06-01 11:07 milde * bufutils/bufutils.sl: run_local_hook() tries mode_get_mode_info(hook) before get_blocal(hook) custom var Jed_Temp_Dir renamed to Jed_Tmp_Directory (which is new in site.sl since 0.99.17.165) 2006-06-01 10:32 milde * ding/ding.sl: forward def needs to be public 2006-05-31 14:18 milde * make_ini/make_ini.sl: update_ini(): evaluate new ini.sl (test, add autoloads) 2006-05-31 13:16 milde * make_ini/make_ini.sl: missing end tag of INITIALIZATION block triggers error. added missing break in make_ini_look_for_functions() 2006-05-30 16:50 boekholt * cal/: cal.sl, ncal.sl: Added require for keydefs (J. Sommer) added calendar marking functions added ncal.sl 2006-05-30 10:13 milde * README.html: Html version of the REAMDE file 2006-05-30 10:12 milde * README, cuamark/cuamark.sl: removed the require("yankpop"), (autoloads in site.sl) 2006-05-29 09:23 milde * mtools/mtools.sl: renamed Jed_Temp_Dir to Jed_Tmp_Directory as this is what make_tmp_file() uses since 0.99.17-165 2006-05-29 09:18 milde * console_keys/console_keys.sl: [no log message] 2006-05-26 14:42 milde * rst/rst.sl, tm/tmtools.sl: fixed autoloads 2006-05-26 14:38 milde * gnuplot/gnuplot.sl, ishell/ishell.sl: fixed autoloads 2006-05-26 14:34 milde * cuamouse/cuamouse.sl, diagnose/diagnose.sl, ding/ding.sl: added missing autoload 2006-05-26 14:31 milde * browse_url/browse_url.sl: added missing autoloads 2006-05-26 11:51 milde * ding/ding.sl: bugfix: missing forward def. for ding() (J. Sommer) 2006-05-26 10:07 milde * browse_url/browse_url.sl: documentation update, added curl to list of download commands 2006-05-25 16:29 boekholt * hyperman/hyperman.sl: fix hyphens in UTF-8 mode 2006-05-24 10:12 milde * README: Move README: basic information and usage instructions 2006-05-23 16:25 milde * browse_url/browse_url.sl: dropped implementing of a named namespace 2006-05-23 15:58 milde * moby-thesaurus/moby-thesaurus.sl: bugfix in the INITIALIZATION block (changed order) 2006-05-22 15:28 milde * make_ini/make_ini.sl: documentation cleanup, tighten the rules for block: now it must be a preprocessor cmd ("#" at bol) 2006-05-21 14:33 boekholt * gdbmrecent/gdbmrecent.sl: Recent files expire time is now customizable. 2006-05-18 11:49 milde * rst/structured_text.sl: code cleanup 2006-05-18 11:33 milde * rst/rst.sl: fix syntax for sub- and supscript, conservative highlight of list markers 2006-05-17 13:16 milde * libdir/libdir.sl: added remove_libdir() 2006-05-17 10:35 milde * rst/rst.sl: separated Html and Latex output options, improved syntax highlight, removed dependency on ishell.sl, merged export help into set_rst2*_options(), nagivation buffer with tokenlist, 2006-05-17 10:33 milde * ishell/ishell.sl: bugfix: added missing autoload for normalized_modename() 2006-05-17 10:32 milde * brief/brief.sl: added Marko Mahnic to the copyright holders 2006-05-07 09:15 boekholt * jedscape/jedscape.sl: Jedscape now uses the curl module. 2006-04-11 14:52 manicm * window/window.sl: bugfix in do_create_windows applied patch by G. Milde added more tets 2006-04-10 13:41 manicm * window/window.sl: no message 2006-04-10 13:40 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl: tokenlist menu moccur; prepared for mlist_routines simple syntax coloring 2006-04-10 13:21 milde * x-keydefs/x-keydefs.sl: renamed KP_Return to KP_Enter (Thei Wejnen) 2006-04-05 13:12 milde * libdir/libdir.sl: added year to copyright statement 2006-03-29 19:22 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl, tokenlist_sl.html: tokenlist_routine_setup_hook Tokenlist_Operation_Type structure definitions moved to tkl-modes.sl HTML documentation added 2006-03-24 17:11 milde * moby-thesaurus/moby-thesaurus.sl: first public version 2006-03-23 09:48 milde * uri/uri.sl: bugfix in write_uri() 2006-03-23 09:46 milde * cuamisc/cuamisc.sl: cua_repeat_search() now searches across lines and has optional arg direction 2006-03-22 10:16 milde * uri/uri.sl: bugfix in write_uri() 2006-03-22 10:02 boekholt * ffap/ffap.sl: Removed Ffap_Dir_Reader if you want to open a directory in dired or filelist mode, use the _jed_find_file_before_hooks 2006-03-21 18:21 milde * uri/uri.sl: write_uri() uses now save_buffer_as() as fallback function 2006-03-21 16:46 milde * sl_utils/sl_utils.sl: Documentation update for run_function mentioning call_function 2006-03-20 16:28 milde * grep/grep.sl: fixed cleanup in zero-output handling in grep() 2006-03-17 16:16 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl: bugfix for rst routines 2006-03-16 09:38 manicm * brief/brief.sl: disabled "\em" and "\es" keybindings to fix menu access 2006-03-13 19:39 boekholt * ffap/ffap.sl: Patches to work with uri.sl and tm documentation by G. Milde 2006-03-13 16:48 milde * dictmode/dictmode.sl: first public version 2006-03-13 16:44 milde * dict-backend/: dict-cli.sl, dict-curl.sl: first public release 2006-03-13 11:27 manicm * tokenlist/tkl-modes.sl: rst list routines 2006-03-13 10:07 manicm * tokenlist/tokenlist.sl: filter command is now interactive 2006-03-10 19:07 manicm * tokenlist/tokenlist.sl: Prepared for make_ini 2006-03-09 13:48 manicm * tokenlist/tokenlist.sl: make_line_visible 2006-03-09 12:44 milde * grep/grep.sl: provide for --include pattern with recursive grep, escape the "what" argument with quotes, change name of the custom var to "Grep_Cmd" 2006-03-09 12:27 manicm * tokenlist/tokenlist.sl: bugfix: list_routines 2006-03-08 19:47 manicm * tokenlist/tokenlist.sl: no message 2006-03-08 19:22 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl: * _list_routines_regexp can also be a list and it may contain references to functions * TokenList_Startup_Mode custom variable * keybindings slightly changed * alternative C routine search (not enabled, iffalse) 2006-03-08 12:27 manicm * tokenlist/tokenlist.sl: no message 2006-03-08 12:19 manicm * tokenlist/: tkl-modes.sl, tokenlist.sl: added isearch and filter commands documented static -> private some modes moved to tkl-modes.sl 2006-03-07 20:52 manicm * brief/brief.sl: added support for named scraps with region type info in blocal vars 2006-03-03 11:03 milde * console_keys/: console_keys.map, console_keys.sl: first public version 2006-02-17 17:01 milde * sprint_var/sprint_var.sl: added special cases to sprint_char 2006-02-17 15:34 milde * recent/recent.sl: new values for Recent_Use_Local_Cache: {-1, 0, 1} -> {0, 1, 2} rename Restore_Last_Session --> Recent_Restore_Last_Session to have all custom variables start with "Recent_" bugfix: reopen-flag was 1 for every new record. 2006-02-16 14:37 milde * recent/recent.sl: code cleanup, bugfix new function recent_file_goto_point() 2006-02-16 09:14 milde * filelist/filelist.sl: added fit_window() to autoloads (report Mirko Rzehak) 2006-02-15 10:42 milde * tm/tm.sl: added support for the \sfun{} attribute in tm2ascii 2006-02-14 17:52 milde * hyperhelp/help.sl: rewrite of help history feature, provide("hyperhelp") 2006-02-03 12:09 milde * tm/tmtools.sl: bugfix: wrong source file name for string_nth_match() 2006-02-03 09:11 milde * listing/listing.sl: removed the "listing_return_hook" again, as set_buffer_hook("newline_indent_hook", &my_return_hook); can be used instead. (tip by Paul Boekholt) 2006-02-03 08:50 milde * rst/structured_text.sl: structured_text.sl: bugfix in the Text_List_Patterns (* needs to be escaped) 2006-02-02 16:47 milde * listing/listing.sl: new keybinding: Key_Return calls "listing_return_hook" 2006-02-02 16:34 milde * grep/grep.sl: bugfix and code cleanup in grep_replace_* 2006-02-01 14:18 milde * sprint_var/sprint_var.sl: added provide() in sprint_var.sl 2006-01-25 10:47 milde * hyperhelp/help.sl: rewrite of help history feature using #ifexists, removing the custom_variable Help_with_history, provide("hyperhelp") 2006-01-22 15:47 boekholt * info/: info_look.sl, infospace.sl: [no log message] 2006-01-22 15:45 boekholt * info/: info.sl, infomisc.sl: works with slang2 some bugs fixed infotree removed 2006-01-19 21:56 boekholt * tar/: INSTALL, tar.sl, tarhook.sl, tarlib.sl: removed INSTALL and tarlib.sl some bugfixes 2006-01-19 16:04 milde * x-keydefs/x-keydefs.sl: updated IBMPC values 2006-01-19 12:50 milde * x-keydefs/x-keydefs.sl: added termcap entries for keypad keys (where possible) 2006-01-17 14:22 milde * x-keydefs/x-keydefs.sl: jed compatible default for Key_Esc ("\e" not "\e\e\e") 2006-01-17 09:15 milde * cuamisc/cuamisc.sl: bugfixes and merge with version 1.1.1 from jed 0.99-17 2006-01-17 09:00 milde * cua/cua.sl: some more adaptions to the version of jed 0.99.17 2006-01-16 20:20 boekholt * bufed/: bufed.sl, bufed_srch.sl: updated to be compatible with slang 2 and jed 0.99-17 2006-01-15 18:41 boekholt * ispell/: flyspell.sl, ispell_common.sl, vispell.sl: Switching buffers didn't always set the syntax table Vispell didn't work with aspell Errors in the after_key_hook weren't caught 2006-01-13 17:43 boekholt * ispell/: ispell.sl, ispell_init.sl: Added a 'q' binding to quit spellchecking (G. Milde) 2006-01-12 17:32 boekholt * ispell/ispell.otl: [no log message] 2006-01-11 17:09 milde * bufutils/bufutils.sl: bugfix for close_and_*_word(), new scheme for active buffer after closing popup_buffer 2006-01-11 15:38 boekholt * ispell/: ispell.sl, ispell_common.sl, ispell_init.sl: [no log message] 2006-01-11 15:32 boekholt * ispell/flyspell.sl: Added experimental utf-8 support to flyspell.sl ispell_region now checks from the current point if no region defined (G. Milde) 2005-12-07 10:15 boekholt * fileview/fileview.sl: [no log message] 2005-12-05 09:13 milde * po_mode/po_mode.sl: added block 2005-11-30 08:42 milde * po_mode/: po_mode.hlp, po_mode.sl: added po_mode to CVS 2005-11-29 11:41 milde * bufutils/bufutils.sl: bugfix in close_buffer(): switch back to current buffer if closing an different one 2005-11-29 11:39 milde * filelist/filelist.sl: bugfix: mark directories and cleanup again, code cleanup 2005-11-28 12:31 milde * csvutils/csvutils.sl: bugfix in goto_max_column() 2005-11-26 18:10 boekholt * cal/: cal.otl, cal.sl, calmisc.sl, diary.sl: [no log message] 2005-11-26 18:07 boekholt * cal/: cal.sl, calmisc.sl, diary.sl, cal.otl: import of cal 2005-11-26 18:06 boekholt * occur/occur.sl: Initial revision 2005-11-26 18:06 boekholt * occur/occur.sl: import of occur 2005-11-25 12:20 milde * csvutils/csvutils.sl: new functions max_column() and goto_max_column() 2005-11-24 10:42 milde * csvutils/csvutils.sl: "wizard" for format_table(), new function format_table_rect() 2005-11-24 09:42 milde * txtutils/txtutils.sl: new function local_word_chars() that also probes mode_get_mode_info("word_chars"), (optional) arg lines for get_buffer() 2005-11-23 16:45 milde * filelist/filelist.sl: documentation, new function filelist_open_tagged(), removed dependency on grep.sl 2005-11-23 15:13 milde * listing/listing.sl: docu bugfix in listing_list_tags 2005-11-23 15:10 milde * listing/listing.sl: docu fix 2005-11-23 14:00 milde * apsmode/apsmode.sl: new version with dpatch included 2005-11-23 09:33 milde * manedit/manedit.sl: added public definition for manedit_mode 2005-11-22 15:30 milde * make_ini/make_ini.sl: code cleanup 2005-11-22 11:22 milde * hyperhelp/help.sl: [no log message] 2005-11-22 09:55 milde * window/window.sl: declared M-x callable functions public 2005-11-22 09:53 milde * sql/sql.sl: declared public functions 2005-11-22 09:49 milde * temabbrv/temabbrv.sl: made temabbrev() public 2005-11-22 09:48 milde * jedasp/jedasp.sl: made asp_run_scripts() public 2005-11-22 09:46 milde * custmode/custmode.sl: made custom_mode() public 2005-11-22 09:44 milde * calc/calc.sl: added section 2005-11-21 14:50 milde * txtutils/txtutils.sl: removed "public" from definitions of functions returning a value 2005-11-21 14:26 milde * bufutils/bufutils.sl: removed public from popup_buffer() definition 2005-11-21 10:58 milde * x-keydefs/x-keysyms.sl: code from x-keysyms.sl is now included in x-keydefs.sl 2005-11-21 10:48 milde * strutils/strutils.sl: no autoload for str_repeat() and get_keystring() with make_ini() 2005-11-21 10:43 milde * print/print.sl: no autoload with make_ini() to avoid conflicts with other print modes 2005-11-21 10:39 milde * mupad/mupad.sl: let make-ini include mupad_shell() in autoloads 2005-11-21 10:36 milde * make/make.sl: let make-ini include make_mode() in autoloads 2005-11-21 10:33 milde * life/life.sl: added INITIALIZATION block 2005-11-18 14:30 milde * browse_url/browse_url.sl: correct bugfix in find_program() 2005-11-18 14:21 milde * ishell/ishell.sl: added documentation 2005-11-18 12:08 milde * mtools/mtools.sl: move mtools.sl to cvs 2005-11-18 09:33 milde * make_ini/make_ini.sl: removed the if(BATCH) clause 2005-11-14 11:06 milde * make/make.sl: new function names dfa_* 2005-11-14 11:05 milde * ding/ding.sl: bugfix 2005-11-14 09:42 milde * make_ini/make_ini.sl: added missing autoload for buffer_dirname() 2005-11-08 10:55 milde * recent/recent.sl, rst/rst.sl, tm/tm.sl: changed _implements() to implements() 2005-11-08 10:49 milde * filelist/filelist.sl, hyperhelp/help.sl, listing/listing.sl: changed _implements() to implements() 2005-11-08 10:15 milde * bufutils/bufutils.sl: reverted reload_buffer() workaround 2005-11-07 12:31 milde * libdir/libdir.sl: added provide() statement 2005-11-07 08:56 milde * ch_table/ch_table.sl: changed _implements() to implements() 2005-11-07 08:53 milde * grep/grep.sl: change _implements() to implements() 2005-11-03 09:50 milde * libdir/libdir.sl: evaluation of ini.sl now customizable with optional arg 2005-11-03 09:21 milde * tm/tmtools.sl: docu fix 2005-11-03 09:16 milde * tm/tmtools.sl: fixed missing requirement in tmtools 2005-11-02 16:48 milde * sl_utils/sl_utils.sl: Simplified _implements(). Developers working with SLang2 should switch to using the standard implements(). 2005-11-02 16:36 milde * rst/rst.sl: hide "public" in some functions 2005-11-02 16:17 milde * numbuf/numbuf.sl: Fix "public" statements 2005-11-02 16:11 milde * mupad/mupad.sl: fix public definiton of mupad_mode() 2005-11-02 16:08 milde * make_ini/make_ini.sl: [no log message] 2005-11-02 15:41 milde * listing/listing.sl: [no log message] 2005-11-02 15:35 milde * gnuplot/gnuplot.sl: fixed the "public" statements 2005-11-02 15:22 milde * datutils/datutils.sl: removed "public" keyword from all functions 2005-11-02 15:16 milde * csvutils/csvutils.sl: documentation update, fixed "public" declarations 2005-11-02 14:39 milde * cua/cua.sl: [no log message] 2005-11-01 13:55 milde * circle/circle.sl: documentation typo fix, no explicitely public functions 2005-11-01 12:43 milde * hyperhelp/help.sl: bugfix in help_for_object 2005-11-01 12:19 milde * hyperhelp/help.sl: bugfix in describe_bindings 2005-10-30 14:56 boekholt * hyperman/hyperman.sl: back in CVS use slang 2 escape sequences for coloring 2005-10-29 23:50 boekholt * email/email.sl: added GPL statement 2005-10-23 13:18 boekholt * gdbmrecent/gdbmrecent.sl: A recent mode 2005-10-22 20:22 boekholt * ispell/ispell_common.sl: run ispell_switch_buffer_hook at startup 2005-10-14 14:33 milde * uri/uri.sl: Bugfix in write_uri() and documentation update 2005-10-14 14:28 milde * bufutils/bufutils.sl: [no log message] 2005-10-14 13:00 milde * css1/css1.sl: added copyright notice 2005-10-14 11:28 milde * manedit/manedit.sl: added copyright notice 2005-10-14 11:02 milde * browse_url/browse_url.sl: bugfix in find_program 2005-10-14 10:21 milde * txtutils/txtutils.sl: documentation update 2005-10-14 10:19 milde * txtutils/txtutils.sl: added documentation 2005-10-13 16:25 milde * vi/vi.sl: added copyright notice 2005-10-12 21:27 boekholt * email/email.sl: added initialization section 2005-10-12 21:19 boekholt * email/email.sl: included some patches from Joerg Sommer works with slang 2 2005-10-12 21:18 boekholt * email/: gpg.sl, mailcrypt.sl: renamed gpg.sl to mailcrypt.sl 2005-10-12 12:21 milde * brief/brief.sl: fixed dependency on x-keydefs 2005-10-12 11:45 milde * x-keydefs/x-keydefs.sl: (re) use the definitions in standard keydefs.sl, let it work on "non-X" jed versions 2005-10-12 10:49 manicm * brief/brief.sl: minor fixes: digit_arg, scroll_in_place, next_buffer, window 2005-10-11 19:58 manicm * brief/brief.sl: % - double/triple home/end handling - more Brief keybindings (based on emacs brief.el) - more Brief-like region marking, copying, yanking - page up/dn (mostly) leaves cursor on same screen line - Brief-like macro recording (F7) - some new functions 2005-10-05 09:08 milde * sl_utils/sl_utils.sl: added documentation for _implements 2005-10-05 08:51 milde * sl_utils/sl_utils.sl: make _implements() work with SLang 2.0.4 2005-09-30 18:18 milde * browse_url/browse_url.sl: made SLang2 proof 2005-09-30 18:18 milde * sl_utils/sl_utils.sl: _implements also for SLang2 2005-09-29 12:06 milde * libdir/libdir.sl: first public version. Obsoletes home-lib 2005-09-29 11:59 milde * COPYING, md5/md5.sl, recent/recent.sl, sl_utils/sl_utils.sl: added libdir directory 2005-09-20 16:24 milde * x-keydefs/x-keydefs.sl: bugfix 2005-09-20 11:16 milde * x-keydefs/x-keydefs.sl: set Key_Alt_* in a loop 2005-09-18 09:22 boekholt * ispell/look.sl: pop any arguments only do partial completion if all matches were found 2005-08-03 11:43 milde * scrnhelp/scrnhelp.sl: corrected copyright notice 2005-08-03 11:29 milde * minued/minued.sl: corrected copyright notice 2005-08-02 18:15 milde * md5/md5.sl, minued/minued.sl, scrnhelp/scrnhelp.sl: added copyright note 2005-08-02 18:13 milde * life/life.sl, make/make.sl: corrected copyright note 2005-08-02 18:11 milde * life/life.sl: added copyright note 2005-08-02 18:08 milde * css1/css1.sl: added copyright note 2005-08-01 09:07 milde * make_ini/make_ini.sl: bugfix in update_ini() 2005-07-26 13:09 milde * home-lib/home-lib.sl: further code cleanup % shedding of the *_Library custom variables 2005-07-19 09:55 milde * make_ini/make_ini.sl: critical bugfix-fix: make_ini_look_for_functions(): use path_concat(dir, "") to normalize the dir-path. 2005-07-11 08:55 milde * numbuf/numbuf.sl: cleaned up code; new custom variable Numbuf_number_all: number also buffers not bound to a file 2005-07-11 08:52 milde * navigate/navigate.sl: Reopen autogenerated buffers with blocal "generating_function", independend of recent.sl 2005-07-11 08:35 milde * make_ini/make_ini.sl: bugfix in make_ini_look_for_functions(), strip trailing slash from libdir name. 2005-07-07 11:24 milde * home-lib/home-lib.sl: make the script less "aggresive", so it can be evaluated without side-effects. !! new way of invocation, see INITIALIZATION !! 2005-07-05 14:50 milde * make_ini/make_ini.sl: renamed byte_compile_library() to byte_compile_libdir 2005-07-05 13:48 milde * COPYING: added COPY of GPL 2 2005-07-05 12:04 milde * cuamouse/cuamouse.sl: added `xclip` workaround for interaction with QT applications % (idea by Jaakko Saaristo) 2005-07-04 13:03 milde * make_ini/make_ini.sl: separated function byte_compile_library() 2005-07-04 12:02 milde * filelist/filelist.sl: added copyright notice 2005-07-04 11:47 milde * txtutils/txtutils.sl: added copyright notice 2005-07-04 11:41 milde * templates/templates.sl: [no log message] 2005-07-04 11:33 milde * print/print.sl: added copyright notice 2005-07-04 11:29 milde * kp_keydefs/kp_keydefs.sl: added copyright notice 2005-07-04 11:23 milde * datutils/datutils.sl, ding/ding.sl: added copyright notice 2005-07-04 11:15 milde * csvutils/csvutils.sl, cuamark/cuamark.sl: added copyright notice 2005-07-04 11:12 milde * brief/brief.sl: added copyright notice 2005-06-16 10:54 boekholt * ispell/: flyspell.sl, ispell.otl, ispell.sl, ispell_common.sl, ispell_init.sl, look.sl, vispell.sl: [no log message] 2005-06-01 21:39 boekholt * rfcview/rfcview.sl: works with slang 2.0.2 2005-06-01 13:51 boekholt * pcre/pcre.sl: works with slang 2.0.2 requires the JMR occur 2005-05-31 11:45 milde * filter-buffer/filter-buffer.sl: bugfix, added tm documentation 2005-05-27 20:17 boekholt * menutils/menutils.sl: updated to work in slang 2.0.2 2005-05-27 19:19 boekholt * snake/snake.sl: [no log message] 2005-05-26 16:49 milde * txtutils/txtutils.sl: bugfix: missing autoload for indent_region_or_line() (report PB) 2005-05-25 12:57 milde * view/view.sl: bugfix: view_mode() now tries view_mode_hook() (PB) 2005-05-25 12:52 milde * make_ini/make_ini.sl: bugfix: andelse -> orelse (report Paul Boekholt) 2005-05-25 12:39 milde * home-lib/home-lib.sl: windows bugfix by Dino Sangoi 2005-05-23 17:33 milde * ch_table/ch_table.sl, ding/ding.sl, filelist/filelist.sl, grep/grep.sl, hyperhelp/help.sl, listing/listing.sl, make_ini/make_ini.sl, recent/recent.sl, rst/rst.sl, tm/tm.sl: use new version of _implements 2005-05-23 17:32 milde * sl_utils/sl_utils.sl: bugfix in _implements (PB) 2005-05-23 13:03 milde * sl_utils/sl_utils.sl: changed order of provide and implements in _implements() 2005-05-20 15:20 milde * browse_url/browse_url.sl, ch_table/ch_table.sl, circle/circle.sl, ding/ding.sl, filelist/filelist.sl, grep/grep.sl, listing/listing.sl, recent/recent.sl, rst/rst.sl, tm/tm.sl: changed order of requirements and implements() to be SLang2 save 2005-05-20 14:23 milde * sl_utils/sl_utils.sl: new function _implements(): implement a "named" namespace but allow re-evaluation if `_debug_info` is TRUE 2005-05-19 16:16 milde * home-lib/home-lib.sl: removed Jed_Debian_Library and introduced Jed_Local_Library 2005-05-13 13:23 milde * filelist/filelist.sl: bugfix in filelist_open_file_with() 2005-04-28 16:23 milde * filelist/filelist.sl: bugfix, new INITALIZATION block for cooperation with make_ini 2005-04-25 13:11 milde * mupad/mupad.sl: bugfix to work with SLang2 2005-04-25 11:13 milde * make_ini/make_ini.sl: added missing autoload for push_array() 2005-04-20 11:26 milde * sprint_var/sprint_var.sl: print user defined data types as struct 2005-04-13 13:09 milde * tm/: tm.sed, tm.sl, tmtools.sl: first public version 2005-04-08 10:28 milde * bufutils/bufutils.sl: bugfix: messed slang 1 and slang 2 part in strread_file 2005-04-08 09:47 milde * bufutils/bufutils.sl: made preparse-proof #if(_slang_version < 2000) cannot be preparsed 2005-04-07 16:19 milde * view/view.sl: bugfix: added require("keydefs") (Rafael Laboissiere) 2005-04-07 16:14 milde * ishell/ishell.sl: bugfix: autoload for view_mode 2005-04-07 16:06 milde * gnuplot/gnuplot.sl: Added doc for custom variables, code cleanup after getting version 1.5 of ishell 2005-04-07 15:55 milde * ding/ding.sl: added missing autoloads 2005-04-06 11:13 milde * txtutils/txtutils.sl: New function insert_markup(beg_tag, end_tag) 2005-04-06 11:08 milde * strutils/strutils.sl: removed the string_get_last_match() alias, call string_nth_match() instead. Added tm documentation 2005-04-05 12:22 milde * view/view.sl: merge of GM and PB versions, bugfix in enable edit 2005-04-01 18:16 milde * filter-buffer/filter-buffer.sl: first public version 2005-04-01 17:50 milde * bufutils/bufutils.sl: added doc for strread_file 2005-04-01 17:46 milde * bufutils/bufutils.sl: [no log message] 2005-04-01 17:41 milde * bufutils/bufutils.sl: fast strread_file() (Paul Boekholt) 2005-03-31 16:22 milde * bufutils/bufutils.sl, csvutils/csvutils.sl, listing/listing.sl: made slang-2 proof: A[[0:-2]] --> A[[:-2]] 2005-03-31 15:42 milde * strutils/strutils.sl: new function str_re_replace_all() 2005-03-24 10:31 milde * recent/recent.sl: made slang-2 proof: A[[0:-2]] --> A[[:-2]] (P. Boekholt) 2005-03-24 09:02 milde * bufutils/bufutils.sl: bufsubfile() now always writes a temp-file 2005-03-21 11:22 milde * diagnose/diagnose.sl: added tm documentation to public functions 2005-03-18 14:53 milde * make_ini/make_ini.sl: removed make_libfun_doc() (now in tm.sl as tm_make_ascii_doc()) 2005-03-18 14:07 milde * make_ini/make_ini.sl: "%" in vinsert needs to be doubled (Dino Sangoi) 2005-03-18 14:02 milde * make_ini/make_ini.sl: removed the need for a chdir() in make_ini 2005-03-18 11:44 milde * make_ini/make_ini.sl: bugfix: documentation comments did not work, list_slang_files() did only work, if dir == current working dir (report Dino Sangoi) 2005-03-17 14:28 milde * server/server.sl: Deleted mode server (moved to misc) 2005-03-17 14:02 milde * hyperman/hyperman.hlp, hyperman/hyperman.sl, hyperman/man.hlp, jedscape/jedscape.html, jedscape/jedscape.sl, jedscape/jedscape_look.sl, jedscape/jedscapemisc.sl: Deleted outdated modes hyperman, jedscape and outline (now at FRS) 2005-03-14 11:12 milde * bufed/bufed_srch.sl, email/gpg.sl, email/keyring, hyperman/hyperman.hlp: Initial revision 2005-03-14 11:12 milde * autotext/autotext.sl, bufed/bufed.sl, bufed/bufed_srch.sl, cdecl/cdecl.sl, email/email.sl, email/gpg.sl, email/keyring, ffap/ffap.sl, fileview/fileview.sl, hyperman/hyperman.hlp, hyperman/hyperman.sl, info/info.sl, info/info_look.sl, ispell/flyspell.sl, ispell/ispell.sl, ispell/vispell.sl, ispell/ispell_common.sl, ispell/ispell_init.sl, ispell/look.sl, jedscape/jedscape.sl, jedscape/jedscape_look.sl, jedscape/jedscapemisc.sl, life/life.sl, make/make.sl, md5/md5.sl, menutils/menutils.sl, minued/minued.sl, rfcview/rfcview.sl, scrnhelp/scrnhelp.sl, snake/snake.sl, tar/tar.sl: Re-import with -ko option to keep the RCS keywords intact 2005-03-14 09:31 milde * rimini/rimini.sl: Removed "misc" sources (see mode "misc"'s homepage for where to find them now) 2005-03-14 09:17 milde * cal/: cal.otl, cal.sl, calendar.sl, calmisc.sl, diary.sl: removed cal from CVS (has its own release now) 2005-03-11 12:31 milde * rst/rst.sl: bugfix release 2005-03-09 10:11 milde * home-lib/home-lib.sl: cleanup of code and documentation + bugfix: custom_variable for Jed_Site_Library and Jed_Home_Library 2005-01-11 10:36 manicm * calc/: calc_sl.html, calc.sl: no message 2005-01-07 09:06 milde * bufutils/bufutils.sl: small bugfix in bufsubfile() 2004-12-23 16:34 milde * rst/rst.sl: removed dependency on view mode (called by runhooks now) 2004-12-17 15:36 milde * subpar/subpar.sl: paragraph reformatter 2004-12-17 11:22 milde * pcre/pcre.sl: Perl-compatible regular expressions 2004-12-17 10:51 milde * complete/complete.sl: keyword completion function 2004-12-13 09:35 manicm * window/window.sl: no message 2004-12-13 09:27 manicm * window/window.sl: what_window, select_window 2004-12-11 21:05 manicm * window/window_sl.html: no message 2004-12-11 20:57 manicm * window/window.sl: no message 2004-12-10 09:55 manicm * sql/sql_sl.html: use of custom_variable 2004-12-09 13:59 manicm * custmode/custmode.sl, keywords/keywords.sl, keywords/keywords_sl.html: strlow_keywords() for a case-insensitive syntax 2004-12-09 13:41 manicm * custmode/custmode_sl.html, sql/sql_sl.html: minor modifications 2004-12-09 13:31 manicm * custmode/custmode_sl.html: installation 2004-12-09 13:22 manicm * sql/sql.sl: oracle keywords more mssql keywords 2004-12-09 13:21 manicm * custmode/: custmode.sl, custmode_sl.html: no message 2004-12-08 20:20 manicm * sql/sql.sl: More complete keyword lists: sql92, sql99, pgsql, mysql 2004-12-08 09:24 manicm * keywords/: keywords.sl, keywords_sl.html: documentation 2004-12-08 09:12 manicm * sql/sql.sl: no message 2004-12-07 09:47 manicm * calc/: calc.sl, calc_sl.html: no message 2004-12-06 20:21 manicm * calc/: calc.sl, calc_sl.html: no message 2004-12-06 19:43 manicm * jedasp/jedasp.sl, jedasp/jedasp_sl.html, keywords/keywords.sl, keywords/keywords_sl.html, temabbrv/temabbrv_sl.html: no message 2004-12-06 10:34 manicm * temabbrv/: temabbrv.sl: no message 2004-12-03 12:33 milde * rst/: rst.sl, structured_text.sl: Mode for reStructured Text (from python-docutils) 2004-12-03 12:32 milde * templates/templates.sl: Open templates and do some replacements 2004-12-03 12:25 milde * x-keydefs/: x-keydefs.sl, x-keysyms.sl: merged x-keydefs and x-keysyms 2004-12-03 12:00 milde * uri/uri.sl: % 1.2 2004-11-25 bugfix: find_uri returned a value if the uri did not % contain a scheme: part 2004-12-03 11:59 milde * make_ini/make_ini.sl: % 2004-11-26 2.2 * code cleanup (hopefully without introducing bugs) % * look for a block 2004-12-03 11:58 milde * ishell/ishell.sl: % 1.6 20004-11-30 % * added new optional argument postfile_args to shell_cmd_on_region 2004-12-03 11:57 milde * colors/: light-terminal-default.sl, white-gm.sl, yellow.sl: color schemes: initial release 2004-12-03 11:44 milde * ch_table/ch_table.sl: % 2004-11-27 2.2 new format of the INITIALIZATION block allows % auto-initialisation with make-ini >= 2.2 2004-11-22 15:56 milde * filelist/filelist.sl: % 2004-11-22 1.2 * FileList_Trash_Bin now defaults to "" (delete files) 2004-11-22 13:19 milde * dabbrev/dabbrev.sl: % 2.4.2 2004-04-05 bugfix (code cleanup) in check_mark. % dabbrev accepts integer argument and uses get_buflist % to convert to a buffer list. (actual change in dab_reset) % get_buflist becomes static 2004-11-15 16:59 milde * cd: removed empty file 2004-11-15 14:16 milde * grep/grep.sl: % 0.9.3 2004-01-30 % * solved bug with only one file (using -H option) [Peter Bengtson] % * recursive grep with special filename bang (!) (analog to kpathsea) % -> grep("pat" "dir/!") gets translated to `grep -r "pat" "dir/"` % 0.9.4 2004-04-28 % * close grep buffer, if the return value of the grep cmd is not 0 2004-11-15 14:13 milde * hyperhelp/help.sl: 1.4.2 - window-bugfix in grep-definition: the w32 subshell needs an additional set of \\ to escape the quotes (Thomas Koeckritz) (TODO: how is this on DOS?) 1.4.3 - grep_definition adapted to new grep command (needs grep.sl >= 0.9.4) 1.4.4 2004-11-09 grep_definition() expanded for variables (experimental) corrected typo Help_file -> Help_File 2004-11-15 13:35 milde * cd, apsmode/apsmode.sl, autotext/autotext.sl, brief/brief.sl, browse_url/browse_url.sl, bufed/bufed.sl, bufutils/bufutils.sl, cal/cal.otl, cal/cal.sl, cal/calendar.sl, cal/calmisc.sl, cal/diary.sl, cdecl/cdecl.sl, ch_table/ch_table.sl, circle/circle.sl, css1/css1.sl, csvutils/csvutils.sl, cua/cua.hlp, cua/cua.sl, cuamark/cuamark.sl, cuamisc/cuamisc.sl, cuamouse/cuamouse.sl, dabbrev/dabbrev.sl, datutils/datutils.sl, diagnose/diagnose.sl, ding/ding.sl, email/email.sl, ffap/ffap.sl, filelist/filelist.sl, fileview/fileview.sl, fileview/fileview_cmds.sl, gnuplot/gnuplot.sl, grep/grep.sl, home-lib/home-lib.sl, hyperhelp/help.hlp, hyperhelp/help.sl, hyperman/hyperman.sl, hyperman/man.hlp, info/info.sl, info/info_look.sl, info/infomisc.sl, info/infospace.sl, info/treemode.sl, ishell/ishell.sl, ispell/flyspell.sl, ispell/ispell.otl, ispell/ispell.sl, ispell/ispell_common.sl, ispell/ispell_init.sl, ispell/look.sl, ispell/vispell.sl, jedscape/jedscape.html, jedscape/jedscape.sl, jedscape/jedscape_look.sl, jedscape/jedscapemisc.sl, kp_keydefs/kp_keydefs.sl, listing/listing.sl, make/make.sl, make_ini/make_ini.sl, manedit/manedit.sl, md5/md5.sl, menutils/menutils.sl, minued/minued.sl, mupad/mupad.sl, navigate/navigate.sl, numbuf/numbuf.sl, print/print.sl, recent/recent.sl, rfcview/rfcview.sl, rimini/rimini.sl, scrnhelp/scrnhelp.sl, server/server.sl, sl_utils/sl_utils.sl, snake/snake.sl, sprint_var/sprint_var.sl, strutils/strutils.sl, tar/INSTALL, tar/tar.sl, tar/tarhook.sl, tar/tarlib.sl, txtutils/txtutils.sl, uri/uri.sl, view/view.sl, vi/vi.hlp, vi/vi.sl, vi/vimisc.sl: Initial revision 2004-11-15 13:35 milde * cd, apsmode/apsmode.sl, autotext/autotext.sl, brief/brief.sl, browse_url/browse_url.sl, bufed/bufed.sl, bufutils/bufutils.sl, cal/cal.otl, cal/cal.sl, cal/calendar.sl, cal/calmisc.sl, cal/diary.sl, cdecl/cdecl.sl, ch_table/ch_table.sl, circle/circle.sl, css1/css1.sl, csvutils/csvutils.sl, cua/cua.hlp, cua/cua.sl, cuamark/cuamark.sl, cuamisc/cuamisc.sl, cuamouse/cuamouse.sl, dabbrev/dabbrev.sl, datutils/datutils.sl, diagnose/diagnose.sl, ding/ding.sl, email/email.sl, ffap/ffap.sl, filelist/filelist.sl, fileview/fileview.sl, fileview/fileview_cmds.sl, gnuplot/gnuplot.sl, grep/grep.sl, home-lib/home-lib.sl, hyperhelp/help.hlp, hyperhelp/help.sl, hyperman/hyperman.sl, hyperman/man.hlp, info/info.sl, info/info_look.sl, info/infomisc.sl, info/infospace.sl, info/treemode.sl, ishell/ishell.sl, ispell/flyspell.sl, ispell/ispell.otl, ispell/ispell.sl, ispell/ispell_common.sl, ispell/ispell_init.sl, ispell/look.sl, ispell/vispell.sl, jedscape/jedscape.html, jedscape/jedscape.sl, jedscape/jedscape_look.sl, jedscape/jedscapemisc.sl, kp_keydefs/kp_keydefs.sl, listing/listing.sl, make/make.sl, make_ini/make_ini.sl, manedit/manedit.sl, md5/md5.sl, menutils/menutils.sl, minued/minued.sl, mupad/mupad.sl, navigate/navigate.sl, numbuf/numbuf.sl, print/print.sl, recent/recent.sl, rfcview/rfcview.sl, rimini/rimini.sl, scrnhelp/scrnhelp.sl, server/server.sl, sl_utils/sl_utils.sl, snake/snake.sl, sprint_var/sprint_var.sl, strutils/strutils.sl, tar/INSTALL, tar/tar.sl, tar/tarhook.sl, tar/tarlib.sl, txtutils/txtutils.sl, uri/uri.sl, view/view.sl, life/life.sl, vi/vi.hlp, vi/vi.sl, vi/vimisc.sl: Move sources to cvs 2000-12-05 18:22 rocher * life/life.sl: Imported sources. 2000-12-05 18:22 rocher * life/life.sl: Initial revision jedmodes-2.5.7/recent/0000755000175400017500000000000011007614676013072 5ustar mildegmjedmodes-2.5.7/recent/recent.sl0000644000175400017500000005007511007614676014721 0ustar mildegm% Provide easy access to recently opened/saved files. % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version: % 1.0.1. by Guido Gonzato, % % 2.0 by Gnter Milde % * Use a circular array -> no hidden recent buffer % * Save to file only at exit -> less writing % * Save last cursor position when saving a file % * Support for "restore last session" (bug fixed) % * Saving cursor position for open buffers at exit (report G. Gonzato) % 2.1 15. Okt 2002 patch by Paul Boekholt % * correct linecounting in folds % * goto_column -> goto_column_best_try % * custom variable RECENT_FILES_EXCLUDE (by GM, based on PB) % * if the line we jump to is in a fold, open it % 2.2 12. 11. 2002 % * documentation error cleared (Joachim Schmitz) % * local recent-files enabled (patch by Andree Borrmann) % * restore_session moved to jed_startup_hooks so the custom settings % are valid when the last open files will be opened % (bug report Andree Borrmann) % * auxiliary fun save_integer removed, as integer() is % already error save when feeded a string % 2.2.1 * if a file is already open, dont goto line (Paul Boekholt) % * made exclude default more save "^/tmp/" (Adam Byrtek) % 2.2.2 * add path info to the popup menu (idea by Marko Mahnic) % (recent now depends on circle.sl and sl_utils.sl (> 1.1) % 2.2.3 04-2003 % * renamed some custom variables according to J E Davies suggestions % * parse the recent_files_file without loading to a buffer % (with arrayread_file() and a bugfix by Paul Boekholt) % * new function recent_get_files() % 3.0 15-01-2004 % * removed dependency on circle.sl -> store the file records % in a "\n" delimited stringlist (like P. Boekholts sfrecent) % * all custom variables start with "Recent_" % (except Restore_Last_Session) % (renamed Local_Recent_List to Recent_Use_Local_Cache) % * new menu option "Clear Cache" % * empty cache files will be deleted (if permitted) % 3.1 2005-03-34 % * made slang-2 proof: A[[0:-2]] --> A[[:-2]] (P. Boekholt) % 3.2 2005-04-02 % * code cleanup and reorganisation % * recent_load_file is now static (was public) % * synchronize recent files file between different running sessions % 3.2.1 2005-11-08 % * changed _implements() to implements() % 3.3 2006-02-16 % * code cleanup (introduced bug fixed in 3.4!) % * bugfix: pop spurious save_cache() return value in recent_toggle_local() % * new function recent_file_goto_point() (idea by Lechee Lai) % 3.4 2006-02-17 % * new values for Recent_Use_Local_Cache: {-1, 0, 1} -> {0, 1, 2} % * rename Restore_Last_Session --> Recent_Restore_Last_Session % to have all custom variables start with "Recent_" % * bugfix: reopen-flag was 1 for every new record. % 3.4.1 2006-02-17 * documentation fixes % 3.4.2 2008-05-05 * use call_function() instead of runhooks() % % USAGE: % % To activate the recent files feature, load recent.sl from your % init file (.jedrc or jed.rc) with require("recent") % or by including the following more elaborated example % % % Optionally set custom variables (here the defaults are given) : % % variable Recent_Files_Cache_File = ".jedrecent"; % % variable Recent_Max_Cached_Files = 15; % % variable Recent_Files_Exclude_Pattern = "/tmp"; % don't add tmp files % % variable Recent_Use_Local_Cache = 1; % use local if existent % % variable Recent_Restore_Last_Session = 0; % reopen files from last session % % % Load recent.sl (assuming it is in the jed library path) % require("recent"); % % go to the stored position also if file is opened by other means % % add_to_hook("_jed_find_file_after_hooks", &recent_file_goto_point); % _debug_info=1; % Requirements "what_line_if_wide", "sl_utils"; "contract_filename", "sl_utils"; "strread_file", "bufutils"; _autoload(3); % --- name it provide("recent"); implements("recent"); private variable mode = "recent"; % --- custom variables: user-settable ---------------------------------- % (Will be appended to Jed_Home_Directory if no absolute path is given.) %!%+ %\variable{Recent_Files_Cache_File} %\synopsis{Name of the recent files file} %\usage{String_Type Recent_Files_Cache_File = ".jedrecent"} %\description % The file to save the recent files list to. %\seealso{Recent_Use_Local_Cache, Recent_Files_Synchronize_Cache} %!%- #ifdef IBMPC_SYSTEM custom_variable("Recent_Files_Cache_File", "_jedrcnt"); #else custom_variable("Recent_Files_Cache_File", ".jedrecent"); #endif %!%+ %\variable{Recent_Use_Local_Cache} %\synopsis{Do you want a local recent list? } %\usage{Int_Type Recent_Use_Local_Cache = 1} %\description % Should recent.sl use a local recent Recent_Files_Cache_File? % (i.e. stored in directory where jed was started) % % 0 -- no, % 1 -- local if local cache file is present at jed startup, % 2 -- always local. % % Toggle (0/1) with \sfun{recent_toggle_local} or the menu entry %\seealso{Recent_Files_Cache_File, Recent_Restore_Last_Session} %!%- custom_variable("Recent_Use_Local_Cache", 1); %!%+ %\variable{Recent_Max_Cached_Files} %\synopsis{Number of recent files to remember} %\usage{Int_Type Recent_Max_Cached_Files = 15} %\description % How many recent opened files should be stored in the % Recent_Files_Cache_File? %\seealso{Recent_Files_Cache_File, Recent_Files_Exclude_Pattern} %!%- custom_variable("Recent_Max_Cached_Files", 15); %!%+ %\variable{Recent_Files_Exclude_Pattern} %\synopsis{Which files shall not be added to the recent files list?} %\usage{String_Type Recent_Files_Exclude_Pattern = "/tmp"} %\description % Wildcard for files that shall not be added to the recent files list % (e.g. temporary files) % % The value is a regexp pattern that is matched to the full path. %\seealso{Recent_Files_Cache_File, Recent_Use_Local_Cache} %!%- custom_variable("Recent_Files_Exclude_Pattern", "/tmp"); %!%+ %\variable{Recent_Restore_Last_Session} %\synopsis{Reopen the buffers that were open in the last session?} %\usage{Int_Type Recent_Restore_Last_Session = 0} %\description % Should recent.sl reopen the buffers that were open in the last session? % % 0 -- no, % 1 -- yes, % 2 -- only files in working directory, % 3 -- only if local recent list % % If \var{Recent_Use_Local_Cache} is True, \sfun{recent->restore_session} % restores the last session from the local \var{Recent_Files_Cache_File}. % % \sfun{recent->restore_session} will not open files still open in another % running session, even if \var{Recent_Files_Synchronize_Cache} is TRUE. %\seealso{Recent_Files_Exclude_Pattern, Recent_Max_Cached_Files} %!%- custom_variable("Recent_Restore_Last_Session", 0); %!%+ %\variable{Recent_Files_Column_Width} %\synopsis{Max space reserved for alignment of paths in the recent files menu} %\usage{Int_Type Recent_Files_Column_Width = 20} %\seealso{Recent_Files_Cache_File} %!%- custom_variable("Recent_Files_Column_Width", 20); %!%+ %\variable{Recent_Files_Synchronize_Cache} %\synopsis{Recent files synchronization level} %\usage{Int_Type Recent_Files_Synchronize_Cache = 1} %\description % Should the Recent_Files_Cache_File be read/saved during runtime to % synchronize different instances of jed? % 0 -- read at startup, save at exit % (save|read also with \sfun{recent_toggle_local}) % 1 -- read with every call, save with every find|save file operation % % If it is not likely that you will run several instances of Jed in % parallel (e.g. on DOS), setting this variable to 0 saves resources. %\seealso{Recent_Files_Cache_File, Recent_Use_Local_Cache, Recent_Restore_Last_Session} %!%- custom_variable("Recent_Files_Synchronize_Cache", 1); % Deprecated: if recent-files-list is not wanted, don't evaluate this skript! % custom_variable ("WANT_RECENT_FILES_LIST", 1); if (__get_reference("WANT_RECENT_FILES_LIST") != NULL) if (@__get_reference("WANT_RECENT_FILES_LIST") == 0) error("Use Recent_Files_Exclude_Pattern to stop adding of files to the recent files list"); % internal Variables % ------------------ % expand the cache file path !if (path_is_absolute(Recent_Files_Cache_File)) Recent_Files_Cache_File = dircat(Jed_Home_Directory, Recent_Files_Cache_File); #ifdef IBMPC_SYSTEM !if (path_is_absolute (Recent_Files_Cache_File)) if (getenv("TEMP") != NULL) Recent_Files_Cache_File = dircat(getenv("TEMP"), Recent_Files_Cache_File); #endif % Filename of the cache files [global, local] static variable recent_cachefile_name = [Recent_Files_Cache_File, dircat(getcwd(), extract_filename(Recent_Files_Cache_File))]; % decrease local_session Recent_Use_Local_Cache if there is no local cache file % and make it boolean (as we use it as array index) if (file_status(recent_cachefile_name[1]) != 1) Recent_Use_Local_Cache--; Recent_Use_Local_Cache = Recent_Use_Local_Cache > 0; % Cache of recent files % (a "\n" delimited stringlist of recent file records (latest last)) % * initialized|update with load_cache() % * saved with save_cache() static variable recent_files_cache; % -------------------------------------------------------------------------- % Load, Save, Append % ------------------ % Load the recent files list from file % % Return "", if the Cache file doesnot exist or is inaccessible % (e.g. after a new value of Recent_Files_Cache_File or with % "use local cache files" on. static define load_cache() { ERROR_BLOCK { _clear_error; return ""; } return strread_file(recent_cachefile_name[Recent_Use_Local_Cache]); } % Parse the filerecord(s) string % ------------------------------ % Parse a file record of the recent files cache and return as array % result = ["filename", "line", "column", "reopen"] static define chop_filerecord(filerecord) { variable fields = strchop(filerecord, ':', 0); % Backwards compatibility (old jedrecent files without line/column info) if (length(fields) < 4) return [strjoin(fields,":"),"0", "0", "0"]; return [strjoin(fields[[:-4]],":"), fields[[-3:]]]; } % Parse a string with list of filerecords, return array of filerecord arrays % (newest record first) static define chop_filerecords(filerecords) { if (filerecords == "") return String_Type[0]; % split filerecords (newest record first) variable records = strchopr(strtrim(filerecords), '\n', 0); return array_map(Array_Type, &chop_filerecord, records); } % Return the filename part of a filerecord string % "filename:line:col:open" static define get_record_filename(filerecord) { filerecord = strchop(filerecord, ':', 0); if (length(filerecord) < 4) % Backwards compatibility / error save ... return strjoin(filerecord,":"); else return strjoin(filerecord[[:-4]],":"); } % Return array of filenames from a "\n" delimited filerecords list static define get_record_filenames(filerecords) { variable records = strchopr(strtrim(filerecords), '\n', 0); return array_map(String_Type, &get_record_filename, records); } % Cache maintenance % ----------------- % Return a filerecord string for the current buffer (cf. getbuf_info) % result == "filename:line:col" % (result == "", if file matches Exclude Pattern or no file is % associated with the buffer) static define getbuf_filerecord() { variable filename = buffer_filename(); if (orelse {filename == ""} {string_match(filename, Recent_Files_Exclude_Pattern, 1)} ) return ""; return sprintf("%s:%d:%d", filename, what_line_if_wide(), what_column()); } % Add a filerecord for the current buffer to the cache % % This function will be called when loading or saving to a file % _jed_find_file_after_hooks 0 args, no return value % _jed_save_buffer_after_hooks 1 arg, no return value static define add_buffer_to_cache() { _pop_n(_NARGS); % remove spurious arguments from stack (when used as hook) variable fp, filerecord_str = getbuf_filerecord(); if (filerecord_str == "") return; % add the "open at exit flag (only at exit it might be set to 1) filerecord_str = strcat(filerecord_str, ":0\n"); if (Recent_Files_Synchronize_Cache) { variable file = recent_cachefile_name[Recent_Use_Local_Cache]; fp = fopen(file, "a+"); if (fp == NULL) verror("%s could not be opened", file); () = fputs(filerecord_str, fp); () = fclose(fp); } else recent_files_cache += filerecord_str; } % purge doublettes in the cache and reduce to Recent_Max_Cached_Files % update the cache's line/col info static define update_cache() { if (Recent_Files_Synchronize_Cache) recent_files_cache = load_cache(); % update line/col info for open buffers variable openfiles = Assoc_Type[String_Type]; loop(buffer_list) { sw2buf(()); openfiles[buffer_filename()] = strcat(getbuf_filerecord(), ":1"); } % there will be a spurious element openfiles[""] == "" % (for buffers with filename == "") % This does not matter, as only buffers already listed in the cache % will be updated below % update and purge the cache variable record, filename, i=0, new_cache = "\n"; % initialize for is_substr() search (see below) foreach(chop_filerecords(recent_files_cache)) { record = (); % ["filename", "line", "column", "reopen"] filename = record[0]; % show(record); % skip empty filenames (cleanup of corrupt .jedrecent files) if (filename == "") continue; % skip doublettes if (is_substr(new_cache, strcat("\n", filename, ":"))) continue; % (fails for "/path/foo", if "/path/foo:bar" is on the list, % but this might be tolerable (given the needed effort to correct)) % update file flags and convert to string if (assoc_key_exists(openfiles, filename)) record = openfiles[filename]; else record = strjoin(record,":"); % prepend to cache new_cache = strcat("\n", record, new_cache); if (i >= Recent_Max_Cached_Files) break; i++; } recent_files_cache = strtrim_beg(new_cache); } % Save the recent files list to a file, delete the file if the cache is empty % Return 1 to tell _jed_exit_hooks to continue static define save_cache() { update_cache(); ERROR_BLOCK { _clear_error; } if (recent_files_cache != "") () = write_string_to_file(recent_files_cache, recent_cachefile_name[Recent_Use_Local_Cache]); else () = delete_file(recent_cachefile_name[Recent_Use_Local_Cache]); return 1; } % goto point indicated in filerecord, open folds static define goto_point(filerecord) { goto_line(integer(filerecord[1])); () = goto_column_best_try(integer(filerecord[2])); % open folds loop (10) % while (is_line_hidden) might cause an infinite loop! { !if (is_line_hidden) break; call_function("fold_open_fold"); } } % Find a file and goto given positon % filerecord == ["filename", "line", "column", "reopen"] static define recent_load_file(filerecord) { % show("loading record", filerecord); () = find_file(filerecord[0]); % goto saved position if (what_line() != 1) % file was already open return; goto_point(filerecord); % update line-collum information in the recent-cache add_buffer_to_cache(); } % reopen the files that were open in the last session of jed % (i.e. files with the 'reopen' flag == 1 static define restore_session() { variable record, records = chop_filerecords(recent_files_cache); foreach record (records) { if (andelse { record[3] == "1" } { orelse { Recent_Restore_Last_Session != 2 } { path_dirname(getcwd()) != path_dirname(record[0]) } } { file_status(record[0]) } ) recent_load_file(record); } % goto first opened buffer if (bufferp(path_basename(records[0][0]))) sw2buf(path_basename(records[0][0])); } % Functions for the File>Recent_Files menu % ---------------------------------------- % clear the cache static define clear_cache() { recent_files_cache = ""; if (Recent_Files_Synchronize_Cache) () = delete_file(recent_cachefile_name[Recent_Use_Local_Cache]); } % Toggle the use of a local recent files file public define recent_toggle_local() { () = save_cache(); % save the current state Recent_Use_Local_Cache = not(Recent_Use_Local_Cache); % toggle recent_files_cache = load_cache(); % load the new recent-file menu_select_menu("Global.&File.&Recent Files"); % reopen menu } static define recent_files_menu_callback(popup) { variable menu, n, i = '1', record, filename, dir, toggle_str = ["&Use local filelist", "&Use global filelist"], format_str = strcat("&%c %-", string(Recent_Files_Column_Width), "s %s"); update_cache(); foreach record (chop_filerecords(recent_files_cache)) { % show(record); filename= path_basename(record[0]); dir = contract_filename(path_dirname(record[0]), ""); menu_append_item (popup, sprintf (format_str, i, filename, dir), &recent_load_file, record); % menu index: 1-9, then a-z, then A-Z, then restart switch (i) { case '9': i = 'a'; } { case 'z': i = 'A'; } { case 'Z': i = '1'; } { i++; } } menu_append_separator(popup); menu_append_item(popup, "Clear Cache", "recent->clear_cache"); menu_append_item(popup, toggle_str[Recent_Use_Local_Cache], "recent_toggle_local"); } static define add_recent_files_popup_hook(menubar) { variable menu = "Global.&File"; % menu_append_separator (menu); menu_insert_popup("Canc&el Operation", menu, "&Recent Files"); menu_set_select_popup_callback(menu+".&Recent Files", &recent_files_menu_callback); } % Interface functions % ------------------- % Return the recent files as an array (last saved file first) % (e.g. for use in the minibuffer with rimini.sl) public define recent_get_files() { update_cache(); return get_record_filenames(recent_files_cache); } %!%+ %\function{recent_file_goto_point} %\synopsis{Go to the position stored in the recent-files cache} %\usage{recent_file_goto_point()} %\description % If there is info about the current buffer in the recent_files_cache, % move the point to the stored position. % % If added to "_jed_find_file_after_hooks", the restoration of % the last position will not only be done for files opened via the % File>Recent_Files menu, but for all. This allows e.g. to start jed % with a filename and restore the last position of this file. %\example %#v+ % autoload("recent_file_goto_point", "recent"); % append_to_hook("_jed_find_file_after_hooks", &recent_file_goto_point); %#v- % (The autoload is not needed if you already \sfun{require}d "recent".) %\seealso{Recent_Max_Cached_Files, Recent_Files_Cache_File, Recent_Files_Synchronize_Cache} %!%- public define recent_file_goto_point() { !if (__is_initialized(&recent_files_cache)) recent_files_cache = load_cache(); variable files = get_record_filenames(recent_files_cache); variable records = chop_filerecords(recent_files_cache); variable i = where(buffer_filename() == files); if (length(i)) goto_point(records[i[0]]); } % Code run at evaluation time (usually startup) % --------------------------------------------- % Load the filerecords list if (Recent_Restore_Last_Session or not(Recent_Files_Synchronize_Cache)) recent_files_cache = load_cache(); % Hooks % update the cache_file when loading and saving a buffer % 1. opening a file (no arguments, no return value) append_to_hook("_jed_find_file_after_hooks", &recent->add_buffer_to_cache); % 2. saving to a file (one argument, no return value) append_to_hook("_jed_save_buffer_after_hooks", &recent->add_buffer_to_cache); % Save the list of recent files at exit append_to_hook("_jed_exit_hooks", &recent->save_cache); % Create the recent-files menu topic append_to_hook ("load_popup_hooks", &add_recent_files_popup_hook); % Restore the last session % !! A strange bug considers only the last line (instead of AND) when % the arguments of andelse are on several lines and _debug_info is 1 !! if ( andelse {__argc == 1} {not BATCH} {Recent_Restore_Last_Session} {Recent_Restore_Last_Session != 3 or Recent_Use_Local_Cache}) add_to_hook("_jed_startup_hooks", &restore_session); jedmodes-2.5.7/cal/0000755000175400017500000000000010727504117012345 5ustar mildegmjedmodes-2.5.7/cal/calendar.sl0000775000175400017500000000543610726443301014467 0ustar mildegm#!/usr/bin/env slsh % calendar.sl -*- mode: Slang; mode: Fold -*- % slsh replacement of the calendar program % % $Id: calendar.sl,v 1.3 2007/12/08 07:14:21 paul Exp paul $ % Keywords: calendar % % Copyright (c) 2004, 2005, 2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This is a calendar script to show your appointments at login. Currently % it works like the diary function in JED - it shows the appointments for % today, or for tomorrow if it's after 9 pm. % % This script will also work in JED, but that's just for debugging purposes - % the definitions in this file conflict with those in cal.sl. #ifnexists _jed_version require("custom"); #endif require("pcre"); %{{{ custom variables % weekday names for inserting weekly reminders custom_variable ("CalWeekdays", ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]); % the file where you keep all your appointments. % According to Emacs it should be ~/diary, but in my version of calendar % it's ~/calendar. custom_variable ("DiaryFile", path_concat(getenv("HOME"), "calendar")); % Should the diary be in the European format dd/mm/yyyy? custom_variable ("DiaryEuropeanFormat", 0); %}}} %{{{ helper functions private define strread_file(file) { variable str, fp = fopen (file, "r"); if (fp == NULL) throw RunTimeError, sprintf("Unable to open %s: %s", file, errno_string (errno)); () = fread_bytes(&str, 1000000, fp); str = typecast(str, String_Type); () = fclose(fp); return str; } %}}} public define calendar() { variable cal = strread_file(DiaryFile); variable now = localtime(10800 + _time()), month, day, year, wday; (month, day, year, wday) = 1 + now.tm_mon, now.tm_mday, 1900 + now.tm_year, CalWeekdays[now.tm_wday mod 7]; variable pos = 0, pat; if (DiaryEuropeanFormat) pat= sprintf ("^(?:%s\\t|%s\\+%d\\t|%d(?:/\\*\\t|/%d(?:\\t|/%d\\t))).*(?:\\n[\\t ].*)*", wday, wday, 1 + (day - 1) / 7, day, month, year); % This will also match */5/2004 as the 5th of every month in 2004 % JED's and BSD calendar don't support that, but Emacs' calendar does else pat = sprintf ("^(?:%s|%s\\+%d|(?:%d|\\*)/%d(?:/%d)?)\\t.*(?:\\n[\\t ].*)*", wday, wday, 1 + (day - 1) / 7, month, day, year); variable cal_re = pcre_compile(pat, PCRE_MULTILINE); #ifexists _jed_version variable buf = whatbuf; pop2buf("*appointments*"); erase_buffer; while(pcre_exec(cal_re, cal, pos)) { insert (pcre_nth_substr(cal_re, cal, 0) + "\n"); pos = pcre_nth_match(cal_re, 0)[1]; } pop2buf(buf); #else while(pcre_exec(cal_re, cal, pos)) { message (pcre_nth_substr(cal_re, cal, 0)); pos = pcre_nth_match(cal_re, 0)[1]; } #endif } public define slsh_main () { calendar(); exit (0); } jedmodes-2.5.7/cal/ncal.sl0000644000175400017500000000777310437055652013643 0ustar mildegm% ncal.sl % % This provides an ncal layout for the JED calendar, similar to the % layout of ncal and gcal -i. It should look like this: % % Apr 2004 May 2004 Jun 2004 % 5 12 19 26 3 10 17 24 31 7 14 21 28 Monday % 6 13 20 27 4 11 18 25 1 8 15 22 29 Tuesday % 7 14 21 28 5 12 19 26 2 9 16 23 30 Wednesday % 1 8 15 22 29 6 13 20 27 3 10 17 24 Thursday % 2 9 16 23 30 7 14 21 28 4 11 18 25 Friday % 3 10 17 24 1 8 15 22 29 5 12 19 26 Saturday % 4 11 18 25 2 9 16 23 30 6 13 20 27 Sunday % % 14 15 16 17 18 18 19 20 21 22 23 23 24 25 26 27 week % % Weeks start on Monday, it's an ISO thing. To use this % instead of the standard calendar, add % % autoload("calendar", "ncal"); % % to .jedrc require("cal"); require("calmisc"); use_namespace("calendar"); % ISO calendar always starts on Monday CalStartWeek = 1; CalWeekdays = weekdaynames[ (CalStartWeek + [0:6]) mod 7 ]; cal_nlines = 10; define generate_calendar (month, year) { today_visible = 0; set_readonly(0); erase_buffer(); (displayed_month, displayed_year) = (month, year); % output a month to the stack variable first, max, white = " "; variable day_array = strchop(" , 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ", ',', 0), white_array = strchop(" , , , , , , , , , , , , , , ", ',', 0); variable month_name, month_len, month_line; USER_BLOCK0 { if (month == this_month and year == this_year) today_visible = 1; month_name = extract_element(CalMonths, month - 1, ','); month_len = strlen(month_name) + 5; first = (18 - month_len) / 2; month_line = sprintf("%s%s%5d%s",white[[1:first]], month_name, year, white[[1:18 - first - month_len]]); % get days in month first = cal_day_of_week(month, 1, year); max = last_day_of_month(month, year); % now make the line of ISO week numbers variable i, number, weekline; ""; _for (0, 5, 1) { i = (); if (1 + i * 7 <= max + first) { (,number,) = cal_iso_date(month, 1+i*7, year); sprintf("%3d", number); } else " "; } weekline = create_delimited_string(6); variable c = [white_array[[1:first]], day_array[[1:max]], white_array[[1:42 - max - first]]]; [month_line, c[[0:6]] + c[[7:13]] + c[[14:20]] + c[[21:27]] + c[[28:34]] + c[[35:41]], " ", weekline]; } % output three months % each month is an array of 10 lines of 18 characters. --month; if (month == 0) { month = 12; --year; } X_USER_BLOCK0; " "; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; " "; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; insert(strjoin(" " + [" ", CalWeekdays, " ", "week"] + () + () + () + () + (), "\n")); bob; recenter(1); if (today_visible) { cal_cursor_to_visible_date (this_month, this_day, this_year); if(this_day < 10) { del(); insert ("*"); } else { go_left_1; deln(2); insert("**"); } runhooks ("calendar_today_visible_hook"); } else runhooks ("calendar_today_invisible_hook"); set_readonly(1); set_buffer_modified_flag(0); } define cal_cursor_to_visible_date (month, day, year) { goto_line (2 + cal_day_of_week (month, day, year)); goto_column (3 * (1 + (day + cal_day_of_week (month, 1, year) - 1) / 7) + 22 * (1 + 12 * (year - displayed_year) + month - displayed_month)); } definekey( "calendar->forward_day( -7)", Key_Left , "Calendar_Map"); definekey( "calendar->forward_day( 7)", Key_Right, "Calendar_Map"); definekey( "calendar->forward_day( -1)", Key_Up , "Calendar_Map"); definekey( "calendar->forward_day( 1)", Key_Down , "Calendar_Map"); jedmodes-2.5.7/cal/cal.otl0000644000175400017500000001147610727504117013635 0ustar mildegm* The JED calendar -*- mode: outline -*- * installing put cal.sl, calmisc.sl and diary.sl in your path before the original cal.sl and add #v+ autoload("diary", "diary"); #v- to your .jedrc. If you want to view your appointments for the day on starting JED, add #v+ diary(); #v- to your .jedrc. ** ncal Ncal redefines some functions to provide a calendar in the columnar layout some of you may have seen at work. The weekday names are shown on the left, and below are the ISO week numbers. It should look like this: #v+ Apr 2004 May 2004 Jun 2004 5 12 19 26 3 10 17 24 31 7 14 21 28 Monday 6 13 20 27 4 11 18 25 1 8 15 22 29 Tuesday 7 14 21 28 5 12 19 26 2 9 16 23 30 Wednesday 1 8 15 22 29 6 13 20 27 3 10 17 24 Thursday 2 9 16 23 30 7 14 21 28 4 11 18 25 Friday 3 10 17 24 1 8 15 22 29 5 12 19 26 Saturday 4 11 18 25 2 9 16 23 30 6 13 20 27 Sunday 14 15 16 17 18 18 19 20 21 22 23 23 24 25 26 27 week #v- This assumes the weeks start on Monday, otherwise the week numbers wouldn't make sense. To use this instead of the standard calendar, add #v+ autoload("calendar", "ncal"); #v- to .jedrc ** installing calendar.sl You can use calendar.sl as a replacement for BSD calendar to remind you of your appointments when you log in. It should be useful for Europeans, since BSD calendar does not support the European date format. You need slsh and the pcre module. Put custom.sl in your slsh load path (/usr/share/slsh/local-packages/ might be a good place), put calendar.sl anywhere, make it executable and call it from .bashrc. Calendar.sl should support the same date patterns as cal.sl. * using See the tm documentation in the source for the keybindings. Or look at the mode menu. * the diary The format of the diary is similar to that used by Emacs and the calendar program, but to keep the diary functions simple, cal.sl is stricter about date patterns. -date patterns must end with a tab -we only recognise -mm/dd/yyyy (not July 10 2003) -mm/dd (not the variant mm/dd/*) -*/dd (dd/* for Europeans) -Sunday etc. (not Sun, but you can set the customvar CalWeekdays if you want) -Sunday+1 for first Sunday of every month. etc. (but not Sunday-1) If you have DiaryEuropeanFormat set to 1, exchange the mm and the dd. If you make your appointments from within calendar, you'll stand the best chance that they will show up. To help spot problems with your diary, the diary file has a higlighting scheme that should highlight only dates I can understand. ** marking appointments In the calendar window, press `m' to mark dates on which you have appointments. Cal can only mark non-recurring appointments, but unlike Emacs' calendar it has a configurable feature to mark different appointments in different colors. Of course this works best if you don't have more than one appointment per day. You have add to .jedrc something like #v+ variable diary_colors = {["Tom", "Dick", "Harry", "Operator"], ["eeting", "String"], ["reakfast", "unch", "inner", "Comment"]}; #v- If an appointment with Tom, Dick or Harry is more important than a meeting or a lunch apppointment. This is a list of arrays. It should also work with an array of arrays, but a list of arrays is easier to create (it doesn't work with a list of lists, because list[[:-2]] doesn't work). All appointments for a day are compared in a substring match and the color first listed that has a match is selected. "eeting" should match both "Meeting" and "meeting". * hooks -calendar_mode_hook: this hook is run when you start the calendar. Use it to set keybindings, to mark diary entries, show diary entries, whatever. -calendar_today_visible_hook: run when the calendar is drawn and the current day is/becomes visible in one of the three months. As an example #v+ define calendar_today_visible_hook() { mark_diary_entries; } #v- will mark your diary entries when the current date becomes visible. -calendar_today_invisible_hook: run when the calendar is drawn and the current day is/becomes invisible. To always have your appointments marked, use both hooks, if you only want them marked when the date is invisible use just the invisible hook. -calendar_move_hook: run when you move to another day. Example #v+ define calendar_move_hook() { show_diary_entries(1); } #v- * changes ** version 1.14 -Added DFA fix for UTF-8 (Joerg Sommer) -Tweaked DFA rules for dates -Now requires Slang 2 jedmodes-2.5.7/cal/diary.sl0000644000175400017500000001205710727504117014022 0ustar mildegm% diary.sl % % $Id: diary.sl,v 1.6 2007/12/08 07:26:18 paul Exp paul $ % Keywords: calendar, Emacs % % Copyright (c) 2003, 2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides the diary function that can be used to view your % appointments on starting JED. To keep this file small, diary() has no % facilities for viewing appointments for another date than today (or % tomorrow after 9 pm) or for looking ahead. If you want to do that, start % calendar and run show_diary_entries (bound to d) or use the BSD calendar % program - or Emacs. provide("diary"); implements("calendar"); variable dbuf = " *diary*"; % sunday=0, monday=1... custom_variable ("CalStartWeek", 0); % weekday names for inserting weekly reminders variable weekdaynames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; custom_variable ("CalWeekdays", weekdaynames[ (CalStartWeek + [0:6]) mod 7 ]); % the file where you keep all your appointments. % According to Emacs it should be ~/diary, but in my version of calendar % it's ~/calendar. custom_variable ("DiaryFile", dircat(getenv("HOME"), "calendar")); % Should the diary be in the European format dd/mm/yyyy?. To % convert your calendar file between European and American style, try % regexp-replacing \([^\/]+\)/\([0-9\*]+\) by \2\/\1 custom_variable ("DiaryEuropeanFormat", 0); #ifdef HAS_DFA_SYNTAX create_syntax_table ("diary"); %%% DFA_CACHE_BEGIN %%% define setup_dfa_callback_diary (mode) { variable dayname; dfa_enable_highlight_cache("diary.dfa", mode); dfa_define_highlight_rule ("^[1-9]?[0-9\\*]/[1-9]?[0-9\\*]?\t", "comment", mode); dfa_define_highlight_rule ("^[1-9]?[0-9]/[1-9]?[0-9]/20[0-9][0-9]\t", "comment", mode); foreach dayname (weekdaynames) dfa_define_highlight_rule (sprintf("^%s\\+?[1-5]?\t", dayname), "string", mode); dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); } dfa_set_init_callback (&setup_dfa_callback_diary, "diary"); %%% DFA_CACHE_END %%% #endif public define diary_mode() { #ifdef HAS_DFA_SYNTAX use_syntax_table("diary"); use_dfa_syntax(1); #endif } % open the diary define open_diary() { () = read_file(DiaryFile); diary_mode; rename_buffer(dbuf); set_buffer_no_autosave(); % Don't want an "autosaved is newer" message on startup } define show_matching_entries(string) { bob(); while (bol_fsearch(string + "\t")) { do { set_line_hidden(0); !if (down_1) return; } while (looking_at_char(' ') or looking_at_char('\t') or eolp); } } % show diary entries for this date define show_entries_for_day (month, day, year) { if (DiaryEuropeanFormat) { show_matching_entries(sprintf("%d/%d/%d", day, month, year)); show_matching_entries(sprintf("%d/%d", day, month)); show_matching_entries(sprintf("%d/*", day)); } else { show_matching_entries(sprintf("%d/%d/%d", month, day, year)); show_matching_entries(sprintf("%d/%d", month, day)); show_matching_entries(sprintf("*/%d", day)); } bob(); } % Show the diary for today, or for tomorrow if it's % after 9.00 pm. You may put this in your .jedrc. %!%+ %\function{diary} %\synopsis{view appointments for today} %\usage{diary()} %\description % Open the \var{DiaryFile} and show appointments for today, or, % after 9.00 pm, for tomorrow. % If \var{DiaryEuropeanFormat} == 1, the diary file looks like %#v+ % 19/3/2003 appointment with Fate % 07/04 happy birthday! % 25/* Payday % Friday Thank God! % Continued line, starts with whitespace % Friday+1 the first Friday of the month %#v- % and should be mostly compatible with Emacs' diary and the BSD calendar % program except Emacs does not recognize Friday+1, BSD calendar does % not recognize European dates, and this function doesn't recognize lots % of things (it is however lightning fast compared to Emacs' diary). % There \em{must} be a tab after the date pattern. If you make appointments % from within \var{calendar}, that should be all right. % %\notes % This function only shows appointments for today, use % \var{show_diary_entries} from within the \var{calendar} to view % appointments for other days and for more than one day %\seealso{calendar, show_diary_entries} %!%- public define diary() { variable now = localtime(10800 + _time()), month, day, year, wday; (month, day, year, wday) = 1 + now.tm_mon, now.tm_mday, 1900 + now.tm_year, CalWeekdays[(now.tm_wday - CalStartWeek) mod 7]; variable buf = whatbuf; open_diary(); mark_buffer(); set_region_hidden(1); show_entries_for_day(month, day, year); show_matching_entries(wday); show_matching_entries(sprintf("%s+%d", wday, 1 + (day - 1) / 7)); % uncomment this to show floating diary entries in Emacs format % show_matching_entries(sprintf("&%%%%(diary-float t %d +%d)", now.tm_wday, 1 + (day - 1) / 7)); bob; skip_hidden_lines_forward(1); if(is_line_hidden) { setbuf(buf); bury_buffer(dbuf); message("no diary entries"); } else { pop2buf(dbuf); otherwindow; } } jedmodes-2.5.7/cal/cal.sl0000644000175400017500000004706210727504117013455 0ustar mildegm% cal.sl -*- mode: Slang; mode: fold -*- % % $Id: cal.sl,v 1.15 2007/12/08 07:14:21 paul Exp paul $ % Keywords: calendar, Emacs % % Copyright (c) 2000-2006 JED, Eero Tamminen, Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % This is a clone of the Emacs calendar package. You can move around, % insert diary entries and view diary entries for the day at point. You % can bind your own keys with the calendar_mode_hook. provide("cal"); _autoload("cal_print_iso_date", "calmisc.sl", "cal_goto_iso_date", "calmisc.sl", "cal_print_day_of_year", "calmisc.sl", 3); require("diary"); require("keydefs"); use_namespace("calendar"); variable mode = "calendar"; %{{{ customization % each month name may be at max. 15 characters custom_variable ("CalMonths", "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"); % each day is two characters, separated with space $1 = " S M Tu W Th F S "; % CalDays gets rotated for CalStartWeek custom_variable ("CalDays", $1 [ (CalStartWeek * 3 + [0:20]) mod 21]); % prompt custom_variable ("CalPrompt", "Month Year:"); % the number of days to look ahead when viewing appointments. % By default, if you press "d" on Sunday + CalStartWeek, you should see % the appointments for the following week. The arithmetic is such that % the customvar looks ahead n days, like the calendar program, but the % numeric prefix looks at n days including the current day, like Emacs. % The diary() function does not look ahead. custom_variable ("DiaryLookahead", [6,0,0,0,0,0,0]); % This is a list of arrays of strings that assigns different colors to % different appointments. It should look like % {["meeting", "String"], ["breakfast", "lunch", "Comment"], ...} custom_variable ("diary_colors", {}); % more custom_variables in diary.sl %}}} variable displayed_month, displayed_year; % the displayed month / yr % same as cursor_month and cursor_year, but maybe someone likes Emacs' % motion better. variable this_month, this_day, this_year; % today's date variable cursor_month, cursor_day, cursor_year, cursor_absolute_date; % cursor date variable cal_nlines = 8; %{{{ calendar functions % is yearnum a leap year % if it's not divisible by 4, it won't be divisible by 100 or 400 define cal_leap_year_p (year) { andelse {not(year & 3)} {orelse {0 != year mod 100} {not (year mod 400)}}; } variable days_in_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; variable days_to_month =[0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; % The last day in MONTH during YEAR define last_day_of_month(month, year) { if (andelse {month == 2} {cal_leap_year_p(year)}) return 29; else return days_in_month[month]; } % calculate day of year for given date define cal_day_number(month, day, year) { day + days_to_month[month] + (andelse {month > 2} {cal_leap_year_p(year)}); } % calculate day of week for given date, from Sunday + CalStartWeek define cal_day_of_week(month, day, year) { variable c, a; cal_day_number(month, day, year); --year; a = () + year + year/4; c = year/100 * 3; if (c & 3) a--; return (a - c/4 - CalStartWeek) mod 7; } % return current (month, day, year) as integers define cal_get_date() { variable now = localtime(_time()); return 1 + now.tm_mon, now.tm_mday, 1900 + now.tm_year; } % convert month number or localized name string into integer define cal_convert_month (month_name) { variable m; m = is_list_element(strlow(CalMonths), strlow(month_name), ','); if (m) return m; % presume it's an integer return atoi(month_name); } % The number of days elapsed between the Gregorian date 12/31/1 BC and DATE. % The Gregorian date Sunday, December 31, 1 BC is imaginary. % This won't work with 16 bit integers. define absolute_from_gregorian (month, day, year) { cal_day_number(month, day, year); --year; return () + 365 * year + year / 4 - year / 100 + year / 400; } define gregorian_from_absolute (day) { variable n400, n100, n4, n1, month, year, mdays; day--; n400 = day / 146097; day = day mod 146097; n100 = day / 36524; day = day mod 36524; n4 = day / 1461; day = day mod 1461; n1 = day / 365; day = day mod 365; day++; year = 400 * n400 + 100 * n100 + 4 * n4 + n1; if (n100 == 4 or n1 == 4) return (12, 31, year); year++; for (month = 1; mdays = last_day_of_month(month,year), mdays < day; month++) day -= mdays; return month, day, year; } %}}} %{{{ calendar drawing functions variable today_visible; define cal_cursor_to_visible_date (month, day, year); define generate_calendar (month, year) { today_visible = 0; set_readonly(0); erase_buffer(); (displayed_month, displayed_year) = (month, year); % output a month to the stack variable first, max, daystring = " 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ", white = " "; variable month_name, month_len, month_line; USER_BLOCK0 { if (month == this_month and year == this_year) today_visible = 1; month_name = extract_element(CalMonths, month - 1, ','); month_len = strlen(month_name) + 5; first = (21 - month_len) / 2; month_line = sprintf("%s%s%5d%s",white[[1:first]], month_name, year, white[[1: 21 - first - month_len]]); % get days in month first = 3 * cal_day_of_week(month, 1, year); max = 3 * last_day_of_month(month, year); variable c = white[[1:first]] + daystring[[1:max]] + white[[1:126 - max - first]]; [month_line,CalDays,c[[0:20]],c[[21:41]],c[[42:62]],c[[63:83]],c[[84:104]],c[[105:125]]]; } % output three months % each month is an array of 8 lines of 21 characters, the '+' operator % works transparently on arrays. --month; if (month == 0) { month = 12; --year; } X_USER_BLOCK0; " "; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; " "; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; insert(strjoin(() + () + () + () + (), "\n")); bob; recenter(1); if (today_visible) { cal_cursor_to_visible_date (this_month, this_day, this_year); if(this_day < 10) { del(); insert ("*"); } else { go_left_1; deln(2); insert("**"); } runhooks ("calendar_today_visible_hook"); } else runhooks ("calendar_today_invisible_hook"); set_readonly(1); set_buffer_modified_flag(0); } %}}} %{{{ calendar movement functions % save a few tokens define cursor_date() { return cursor_month, cursor_day, cursor_year; } % This function will actually move to any of the 3 visible months, like in % Emacs, but I find Emacs' calendar motion confusing. I can still use this % for marking diary entries. define cal_cursor_to_visible_date (month, day, year) { goto_line ((day + 20 + cal_day_of_week (month, 1, year)) / 7); goto_column (2 + 25 * (1 + 12 * (year - displayed_year) + month - displayed_month) + 3 * (cal_day_of_week(month, day, year))); } define cal_goto_date (month, day, year) { !if (month == displayed_month and year == displayed_year) generate_calendar (month, year); cal_cursor_to_visible_date (month, day, year); runhooks("calendar_move_hook"); } define goto_absolute_date(date) { cursor_absolute_date=date; (cursor_month, cursor_day, cursor_year) = gregorian_from_absolute (date); cal_goto_date (cursor_date()); } define goto_gregorian_date() % (month, day, year) { (cursor_month, cursor_day, cursor_year) = (); cursor_absolute_date = absolute_from_gregorian(cursor_date()); cal_goto_date (cursor_date()); } % Move the cursor forward ARG days. % Moves backward if ARG is negative. define forward_day (arg) { variable prefix = prefix_argument(-1); if (prefix == -1) prefix = 1; goto_absolute_date(cursor_absolute_date + arg * prefix); } %}}} %{{{ calendar mark functions variable marked_date; define cal_set_mark() { marked_date = cursor_absolute_date; } define cal_exchange_point_and_mark() { if (marked_date == NULL) throw RunTimeError, "calendar mark is not set"; variable this_date = cursor_absolute_date; goto_absolute_date(marked_date); marked_date = this_date(); } define cal_count_days_region() { if (marked_date == NULL) throw RunTimeError, "calendar mark is not set"; vmessage("region has %d days (inclusive)", 1 + abs(cursor_absolute_date - marked_date)); } %}}} %{{{ diary functions % show diary entries for this date %!%+ %\function{show_diary_entries} %\synopsis{view appointments for day in calendar} %\usage{show_diary_entries()} %\description % Open the \var{DiaryFile} and show appointments for the day selected % in the \var{calendar} buffer and \var{DiaryLookAhead}[day of week] % days after, or for the number of days of the prefix argument %\seealso{calendar, diary} %!%- public define show_diary_entries() { variable lookahead = prefix_argument(-1), date = cursor_absolute_date, month, day, year, wday = cal_day_of_week(cursor_date()); if (_NARGS) lookahead = (); else if (lookahead == -1) lookahead = 1 + DiaryLookahead[wday]; open_diary(); pop2buf(dbuf); mark_buffer(); set_region_hidden(1); loop (lookahead) { (month, day, year) = gregorian_from_absolute(date); show_entries_for_day(month, day, year); show_matching_entries (CalWeekdays[wday]); show_matching_entries(sprintf("%s+%d", CalWeekdays[wday], 1 + (day - 1) / 7)); % uncomment this to show floating diary entries in Emacs format % if you want backward floating entries, ask % show_matching_entries(sprintf("&%%%%(diary-float t %d +%d)", (day + CalStartWeek) mod 7, 1 + (day - 1) / 7)); wday = (wday + 1) mod 7; date++; } % show_matching_entries left point at bob. It makes sense to list % recurring appointments first and then non-recurring ones, so go to % the last visible line. eob; skip_hidden_lines_backward(1); pop2buf("*calendar*"); } define show_all_diary_entries() { open_diary; push_spot; mark_buffer; set_region_hidden(0); pop_spot; pop2buf(dbuf); pop2buf("*calendar*"); } % calendar requires continuation lines to begin with a tab. define diary_indent_hook() { !if (looking_at_char('\t')) insert_char ('\t'); } define diary_wrap_hook() { push_spot_bol(); diary_indent_hook(); pop_spot(); } public define mark_diary_entries(); % insert a string in the diary file define make_diary_entry (s) { open_diary(); pop2buf(dbuf); eob(); !if(bolp()) newline(); set_line_hidden(0); insert(s + "\t"); set_buffer_hook("wrap_hook", &diary_wrap_hook); set_buffer_hook("indent_hook", &diary_indent_hook); setbuf("*calendar*"); mark_diary_entries; pop2buf(dbuf); } % insert a diary entry for date at point define insert_diary_entry () { if (DiaryEuropeanFormat) make_diary_entry(sprintf("%d/%d/%d", cursor_day, cursor_month, cursor_year)); else make_diary_entry(sprintf("%d/%d/%d", cursor_date())); } % and for this day of the week define insert_weekly_diary_entry () { make_diary_entry (CalWeekdays[cal_day_of_week(cursor_date())]); } % and for this day of every month define insert_monthly_diary_entry () { if (DiaryEuropeanFormat) make_diary_entry(string(cursor_day) + "/*"); else make_diary_entry("*/" + string(cursor_day)); } % and for this day of every year define insert_yearly_diary_entry () { if (DiaryEuropeanFormat) make_diary_entry(string(cursor_day) + "/" + string(cursor_month)); else make_diary_entry(string(cursor_month) + "/" + string(cursor_day)); } variable default_color = length(diary_colors) + 1; define extract_color_number(color_entry) { return color_number(diary_colors[color_entry][-1]); } % This doesn't work on lists. % variable diary_color_numbers = array_map(Integer_Type, &extract_color_number, diary_colors); define assign_colors(month_colors, mark_pattern, month, year) { month_colors[*]=0; variable mark_re = sprintf(mark_pattern, month, year); variable appt, i, day, appt_pattern; bob(); while (re_fsearch(mark_re)) { day = atoi(regexp_nth_match(1)); !if (month_colors[day]) month_colors[day] = default_color; ()=ffind_char('\t'); while (looking_at_char('\t')) { appt=line_as_string(); for (i = 1; i < month_colors[day]; i++) { foreach appt_pattern (diary_colors[i-1][[:-2]]) { if (is_substr(appt, appt_pattern)) { month_colors[day] = i; break; } } } !if(down_1()) return; } } } define insert_colors(month_colors, month, year) { variable color, day; foreach day (where(month_colors)) { cal_cursor_to_visible_date(month, day, year); if (month_colors[day] == default_color) color = color_number("keyword"); else color = extract_color_number(month_colors[day]-1); bskip_chars("0-9*"); insert(sprintf("\e[%d]", color)); skip_chars("0-9*"); insert("\e[0]"); } } % mark days for which there are appointments. public define mark_diary_entries() { set_readonly(0); bob; replace("\t", " "); variable mark_pattern, mark_re, month, day, year; variable month_colors = Integer_Type[32]; if (DiaryEuropeanFormat) mark_pattern = "^\\([0-9][0-9]?\\)/0?%d/%d\t"; else mark_pattern = "^0?%d/\\([0-9][0-9]\\)?/%d\t"; (month, year) = (cursor_month, cursor_year); open_diary(); USER_BLOCK0 { setbuf(dbuf); push_spot(); assign_colors(month_colors, mark_pattern, month, year); pop_spot(); setbuf("*calendar*"); insert_colors(month_colors, month, year); } --month; if (month == 0) { month = 12; --year; } X_USER_BLOCK0; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; ++month; if (month == 13) { month = 1; ++year; } X_USER_BLOCK0; pop_spot(); set_readonly(1); set_buffer_modified_flag(0); cal_cursor_to_visible_date(cursor_date); } %}}} %{{{ other functions % read a month and year define read_date () { variable t, default, month, year; default = sprintf ("%s %d", extract_element(CalMonths, this_month-1, ','), this_year); t = strtrim (read_mini (CalPrompt, default, Null_String)); month = cal_convert_month(extract_element(t, 0, ' ')); year = integer(extract_element(t, 1, ' ')); if (month < 1 or month > 12 or year < 1) throw RunTimeError, "not a valid date"; return month, year; } define other_month () { variable month, day, year; (month, year) = read_date(); if (month == displayed_month) day = cursor_day; else if (month == this_month and year == this_year) day = this_day; else day = 1; goto_gregorian_date (month, day, year); } define quit() { otherwindow(); if (whatbuf() == dbuf) { bury_buffer(dbuf); otherwindow; } onewindow(); delbuf ("*calendar*"); } %}}} %{{{ calendar mode define cal_menu(menu) { menu_append_item (menu, "view appointments", "show_diary_entries"); menu_append_item (menu, "mark diary entries", "mark_diary_entries"); menu_append_item (menu, "&show all entries", "calendar->show_all_diary_entries"); menu_append_separator(menu); menu_append_item (menu, "insert &diary entry", "calendar->insert_diary_entry"); menu_append_item (menu, "insert &weekly entry", "calendar->insert_weekly_diary_entry"); menu_append_item (menu, "insert &monthly entry", "calendar->insert_monthly_diary_entry"); menu_append_item (menu, "insert &yearly entry", "calendar->insert_yearly_diary_entry"); menu_append_separator(menu); menu_append_item (menu, "&other month", "calendar->other_month"); menu_append_item (menu, "day of year", "cal_print_day_of_year"); menu_append_item (menu, "iso date", "cal_print_iso_date"); menu_append_item (menu, "go to iso date", "cal_goto_iso_date"); menu_append_item (menu, "&quit", "calendar->quit"); } define calendar_mode() { set_mode("calendar", 0); use_keymap ("Calendar_Map"); _set_buffer_flag(0x1000); mode_set_mode_info(mode, "init_mode_menu", &cal_menu); run_mode_hooks("calendar_mode_hook"); } % output three month calendar into separate buffer %!%+ %\function{calendar} %\synopsis{calendar and diary} %\usage{public define calendar ()} %\description % \var{calendar} opens a three month calendar window. % The asterisk denotes the current day. % The arrow keys move by day and week, PgUp and PgDn move by 91 days % (close enough to 3 months). % These commands accept a numeric argument as a repeat count. For % convenience, the digit keys specify numeric arguments in Calendar % mode even without the Meta modifier. % \var{o} move to an other month % \var{p d} show the daynumber in the minibuffer % \var{p c} show the ISO commercial date % \var{g c} go to an ISO commercial date % % Diary functions: % % \var{i d} insert diary entry % \var{i w} insert weekly diary entry % \var{i m} insert monthly diary entry % \var{i y} insert yearly diary entry % \var{d} view diary entries for day at point % \var{s} show the entire diary file % \var{m} mark dates this month for which there are appointments % (only non-recurring appointments) % %\notes % slsh also has a calendar function, which is similar to JED's % \var{diary} function and can be used as a replacement for the BSD % calendar program. % %\seealso{diary, show_diary_entries} %!%- public define calendar () { variable month, day, year; variable obuf = whatbuf(); % ask user for month / year (this_month, this_day, this_year) = cal_get_date(); (cursor_month, cursor_day, cursor_year) = (this_month, this_day, this_year); (month, year) = this_month, this_year; % read_date(); % I want the calendar in the bottom window onewindow(); sw2buf("*calendar*"); _set_buffer_flag(0x1000); bob(); splitwindow(); % when I do this manually I end up in top % window, but when done from slang in the bottom? % I need 8 lines variable nlines = window_info('r'); if (nlines > cal_nlines) { otherwindow(); loop (nlines - cal_nlines) enlargewin(); } else { loop (cal_nlines - nlines) enlargewin(); otherwindow(); } sw2buf(obuf); otherwindow(); generate_calendar(month, year); if (month == this_month and year == this_year) day = this_day; else day = 1; goto_gregorian_date(month, day, year); % what the heck, give current time message(time); calendar_mode (); } $2 = "Calendar_Map"; !if (keymap_p($2)) make_keymap($2); definekey( "calendar->forward_day( -1)", Key_Left , $2); definekey( "calendar->forward_day( 1)", Key_Right, $2); definekey( "calendar->forward_day( -7)", Key_Up , $2); definekey( "calendar->forward_day( 7)", Key_Down , $2); definekey( "calendar->forward_day(-91)", Key_PgUp , $2); definekey( "calendar->forward_day( 91)", Key_PgDn , $2); #ifdef IBMPC_SYSTEM definekey( "calendar->cal_set_mark", "^@^C", $2); #else definekey( "calendar->cal_set_mark", "^@", $2); #endif definekey( "calendar->cal_exchange_point_and_mark", "^x^x", $2); definekey( "calendar->cal_count_days_region", "\e=", $2); definekey( "calendar->quit" , "q", $2); definekey( "show_diary_entries", "d", $2); definekey( "calendar->show_all_diary_entries", "s", $2); definekey( "calendar->insert_diary_entry", "id", $2); definekey( "calendar->insert_weekly_diary_entry", "iw", $2); definekey( "calendar->insert_monthly_diary_entry","im", $2); definekey( "calendar->insert_yearly_diary_entry", "iy", $2); definekey( "calendar->other_month", "o", $2); definekey( "mark_diary_entries", "m", $2); definekey( "cal_print_iso_date", "pc", $2); definekey( "cal_goto_iso_date", "gc", $2); definekey( "cal_print_day_of_year", "pd", $2); % treat number keys as numeric prefix . 1 9 1 {string "digit_arg" exch $2 definekey} _for %}}} jedmodes-2.5.7/cal/calmisc.sl0000644000175400017500000000603010342113406014305 0ustar mildegm% calmisc.sl % % $Id: calmisc.sl,v 1.3 2005/06/18 11:53:18 paul Exp paul $ % % Copyright (c) 2003 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides some autoloaded functions for the calendar % that are not always needed. provide("calmisc"); require("cal"); use_namespace("calendar"); % Compute the `ISO commercial date' for point. The ISO year corresponds % approximately to the Gregorian year, but weeks start on Monday and end % on Sunday. The first week of the ISO year is the first such week in % which at least 4 days are in a year. The idea is to compute the number % of days before this week began, the number of complete weeks elapsed % this year before this week, add 1 to that, and if there were more than 3 % days before that, add one more. If the day in the year is smaller than 7 % and the week has less than 4 days in this year, this day in the year, % plus 3, will be smaller than the day of the week, etc. define cal_iso_date(month, day, year) { variable iso_wday, days_before_this_week, weeks; % subtract 1 because iso weeks start on day 1; % -1 mod 7 = -1 so add 7 to stay positive; % add 1 to start counting from 1 iso_wday = 1 + (cal_day_of_week(month, day, year) + CalStartWeek + 6) mod 7; days_before_this_week = cal_day_number(month, day, year) - iso_wday; % maybe this week goes with last year if (cal_day_number(month, day, year) - iso_wday < -3) { year--; days_before_this_week += 365 + cal_leap_year_p(year); } weeks = 1 % add one for the first week of the year + days_before_this_week / 7 % add completed week + ((days_before_this_week mod 7) > 3); % add one for first % week if more than 3 days % maybe this should go with the next year if (cal_day_number(month, day, year) > iso_wday + 361 + cal_leap_year_p(year)) { year++; weeks = 1; } return iso_wday, weeks, year; } public define cal_print_iso_date () { vmessage("ISO date: day %d of week %d of %d", cal_iso_date(cursor_date())); } % go to an iso date. The idea is to go to year + weeks + 7 * days, % and go to the nearest matching weekday from there. public define cal_goto_iso_date() { variable iweek, iday, iyear, absdate, daydiff; iyear = integer(read_mini("year", "", string(this_year))); iweek = integer(read_mini("week", "1", "")); iday = integer(read_mini("day", "1", "")); iday--; iweek--; % I count from 0 absdate = absolute_from_gregorian(1,1,iyear) + 7 * (iweek) + iday; daydiff = (cal_day_of_week(gregorian_from_absolute(absdate)) + CalStartWeek - 1) mod 7 - iday; % this maps [1,2,3,4,5 6] and [-6,-5,-4,-3,-2,-1] to [-1,-2,-3,3,2,1] absdate += 7 * (daydiff / 4) - daydiff; goto_absolute_date(absdate); % testing ... cal_print_iso_date; } public define cal_print_day_of_year() { variable day = cal_day_number(cursor_date()); vmessage ("day %d of %d; %d days remaining in the year", day, cursor_year, 365 - day + cal_leap_year_p(cursor_year)); } jedmodes-2.5.7/datutils/0000755000175400017500000000000011477670241013444 5ustar mildegmjedmodes-2.5.7/datutils/datutils.sl0000644000175400017500000003515011477670240015640 0ustar mildegm% datutils.sl: convenience functions for several Data_Types % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % VERSIONS % 1.0 first public release % 1.1 new functions pop2array, array, null_fun, array_repeat, % array_fill_missing % 1.2 removed array_concat, array_append, array_insert % after learning about [[1,2],3] == [1,2,3] % removed array_fill_missing (buggy) % 1.2.1 reincluded array_append % (as [[1,2],[3,4]] -> 2d Array in SLang < 1.16) % moved string_repeat and string_reverse to strutils.sl % 1.2.2 bugfix in array_max(), the definition in sl_utils contradicted % the intrinsic one which resembles array_max() (report PB) % 1.2.3 removed "public" keyword from all functions % 1.2.3 added provide("datutils"); % 2.0 2006-06-22 added list functions, full tm documentation % 2.1 2006-10-04 added list_concat() % 2.2 2006-11-27 removed array_reverse(): it is not used anywhere and % conflicts with the internal SLang function of the same % name (activated by default in Jed >= 0.99.19-51) % 2.2.1 2007-02-06 new function list_inject(), % new versions of assoc_get_key() and array_sum() (JED) % 2.2.2 2007-10-18 fix array_value_exists() for Any_Type arrays % documentation update % 2.2.3 2009-10-05 fallback defs of __push_list(), __pop_list() % deprecated push_list(), pop2list(), % favour literal constructs for array<->list conversion % 2.3 2010-12-08 name list_concat() to list_extend() to avoid % clash with intrinsic added in S-Lang 2.2.3 (report PB) _autoload( "push_defaults", "sl_utils", "push_array", "sl_utils", 2); % --- Array functions ------------------------------------------ % helper functions define null_fun() {} static define dereference(arg) { return @arg; } static define typeof_ref(ref) { return typeof(@ref); } %!%+ %\function{pop2array} %\synopsis{Return N stack-items as an array of type \var{type}} %\usage{Array_Type pop2array(N=_stkdepth, [type])} %\description % Return an array that consists of the N topmost stack elements. % The top element becomes element arr[N-1]. % If \var{type} is not given, autodetermine it (fall back to \var{Any_Type} % if the element types differ). %\notes % Attention: never use \sfun{pop2array} in a function call with optional % arguments , i.e. not %#v+ % show(pop2array()) %#v- % but %#v+ % $1 = pop2array(); % show($1); %#v- %\seealso{array, pop2list, push_array} %!%- define pop2array() % (N=_stkdepth, [type]) { variable n, type; (n, type) = push_defaults(_stkdepth(), Any_Type, _NARGS); variable i, a = type[n]; for (i=n-1; i>=0; i--) a[i] = (); if (_NARGS >= 2 or n == 0) % type argument given or no elements return a; % autodetermine type variable types = array_map(DataType_Type, &typeof_ref, a); if(length(where(types == types[0])) == n) % all args of same type return array_map(types[0], &dereference, a); return a; % i.e. _typeof(a) == Any_Type } %!%+ %\function{array} %\synopsis{Return an array containing the arguments} %\usage{Array_Type array([args])} %\description % Pack the arguments into an array and return it. % The type is autodetermined (defaulting to \var{Any_Type} % if the element types differ). %\notes % If you are sure that all arguments are of the same type (or want to % throw an error, if not), you can replace % the call to \sfun{array} with a literal construct like e.g. %#v+ % variable a = [__push_list(liste)]; %#v- %\seealso{pop2array, push_array, list2array} %!%- define array() %([args]) { return pop2array(_NARGS); } %!%+ %\function{array_append} %\synopsis{Append a value to an array or concatenate \var{a} and \var{b}} %\usage{Array = array_append(a, b)} %\description % \sfun{array_append} provides a means to use 1d-arrays like lists. It % concatenates \var{a} and \var{b}. % % The arguments may be of any type and will be converted to Array_Type (if % the not already are) before the concatenation. %\example % The following statemants are all TRUE: %#v+ % array_append(1,2) == [1,2] % array_append(1, [2,3,4]) == [1,2,3,4] % array_append([1,2], [3,4]) == [1,2,3,4] % array_append([1,2,3], 4) == [1,2,3,4] %#v- %\notes % Deprecated. This function might disappear in later versions of datutils! % % Since SLang 1.16, the effect can be savely achieved by the % syntax: % [1,2] == [1,2] % [1, [2,3,4]] == [1,2,3,4] % [[1,2], [3,4]] == [1,2,3,4] % [[1,2,3], 4] == [1,2,3,4] % which is also internally used by array_append in SLang 2. % % For arrays with 1000 values, array_append() becomes time-consuming (0.13 s), % for 2000 values annoying (0.5 s) and for 5000 values prohibitive (3 s) % (CPU-time on a AMD-Duron 700MHz under Linux) %\seealso{list_append} %!%- #ifexists _slang_utf8_ok define array_append (a, b) { return [a,b]; } #else define array_append(a, b) { if (typeof(a) != Array_Type) a = [a]; if (typeof(b) != Array_Type) b = [b]; !if (length(a)) % empty array return b; variable c = _typeof(a)[length(a)+length(b)]; c[[:length(a)-1]] = a; c[[length(a):]] = b; return c; } #endif %!%+ %\function{array_delete} %\synopsis{Delete the element(s) at position(s) \var{N}} %\usage{Array_Type array_delete(Array_Type a, Integer_Type N)} %\usage{Array_Type array_delete(Array_Type a, Array_Type N)} %\description % Return a slice of all positions not in \var{N}. % This provides a means to use 1d-arrays like lists. %\example %#v+ % array_delete([1,2,3,4], 0) == [2,3,4] % array_delete([1,2,3,4], [0,1]) == [3,4] % array_delete([1,2,3,4], [0,-1]) == [2,3] % array_delete([1,2,3,4], -1) == [1,2,3] %#v- %\notes % For arrays with 1000 values, it becomes time-consuming (0.09 s), % for 2000 values annoying (0.32 s) and for 5000 values prohibitive (1.83 s). % With SLang 2, consider using the new List_Type instead. %\seealso{array_append, where, list_delete} %!%- define array_delete(a, n) { variable i = Int_Type[length(a)]; i[n] = 1; i = where(not(i)); return a[i]; } %!%+ %\function{array_max} %\synopsis{Return the maximal value of an array} %\usage{result = array_max(Array_Type a)} %\description % The \sfun{array_max} function examines the elements of a numeric array and % returns the value of the largest element. %\example %#v+ % array_max([1,2,30,4] == 30 %#v- %\notes % \sfun{max} is a slang intrinsic since 1.4.6. (but must be activated manually) % It is activated in Jed by default since 0.99.19-51. %\seealso{array_sum, array_product, max, min, sum} %!%- define array_max(a) { #ifexists max return max(a); #else variable maximum = a[0], element; foreach element (a) { if (element > maximum) maximum = element; } return maximum; #endif } %!%+ %\function{array_sum} %\synopsis{Return the sum of the array elements} %\usage{result = array_sum(a)} %\description % Sum up the values of a numeric array and return the result. %\notes % \sfun{sum} is a slang intrinsic since 1.4.6. (but must be activated manually) % It is activated in Jed by default since 0.99.19-51. %\seealso{array_max, array_product, sum, min, max} %!%- define array_sum(a) { #ifexists sum return sum(a); #else variable result = 0; foreach (a) result += (); return result; #endif } %!%+ %\function{array_product} %\synopsis{Return the product of the array elements} %\usage{result = array_product(a)} %\description % Multiply the values of a numeric array and return the result. %\notes % There are considerations to introduce \sfun{prod} and \sfun{cumprod} % funtions in SLang. %\seealso{array_sum, array_max} %!%- define array_product(a) { variable product = 1; foreach (a) product *= (); return product; } %!%+ %\function{array_value_exists} %\synopsis{Return the number of occurences of \var{value} in array \var{a}} %\usage{Integer_Type array_value_exists(a, value)} %\description % Count, how many times \var{value} is present in array \var{a}. % For normal arrays, this is equal to %#v+ % length(where(a == value)) %#v- % while special care is taken to get meaningfull results with arrays of % \var{Any_Type}. %\seealso{where, wherefirst, wherelast, assoc_value_exists} %!%- define array_value_exists(a, value) { if (_typeof(a) != Any_Type) return length(where(a == value)); variable element, i=0; foreach element (a) { if (element == NULL) { if (value == NULL) i++; } else { if (_eqs(@element, value)) i++; } } return (i); } %!%+ %\function{array_repeat} %\synopsis{Repeat an array \var{N} times} %\usage{Array_Type array_repeat(a, N)} %\description % Concatenate an array N-1 times to itself and return the result. %\seealso{string_repeat, array_append} %!%- define array_repeat(a, n) { variable i, len_a = length(a); variable aa = _typeof(a)[n*len_a]; for (i=0; i <= length(aa)-1; i +=len_a) aa[[i:i+len_a-1]] = a; return aa; } %!%+ %\function{array_transpose} %\synopsis{Swap the axes of a 2d array} %\usage{Array_Type array_transpose(a)} %\description % Swap rows and columns of a 2dimensional array. %\seealso{array_info, reshape} %!%- define array_transpose(a) { variable i, dim, dimensionality, type; (dim, dimensionality, type) = array_info(a); !if (dimensionality == 2) error("array_transpose expects a 2d-array"); variable b = @Array_Type(type, [dim[1], dim[0]]); for (i=0; i 2.2.3 returns a new % list instead of appending to the first argument. %\seealso{list_append, list_insert} %!%- define list_extend(l1, l2) { variable element; foreach element (l2) list_append(l1, element, -1); } %!%+ %\function{list_inject} %\synopsis{Insert list elements at position \var{i}} %\usage{list_inject(List_Type l1, List_Type l2, Int_Type i)} %\description % Merge two lists by inserting the elements of \var{l2} into % \var{l1} at position \var{i}. %\example %#v+ % variable l1 = {1, 2, 3, 4}; % list_inject(l1, {2.5, 2.6, 2.7}, 2); % l1 == {1, 2, 2.5, 2.6, 2.7, 3, 4}; %#v- %\seealso{list_extend, list_insert} %!%- define list_inject(l1, l2, i) { variable element; if (i >= 0) list_reverse(l2); foreach element (l2) list_insert(l1, element, i); } #endif provide("datutils"); jedmodes-2.5.7/css1/0000755000175400017500000000000010555355322012460 5ustar mildegmjedmodes-2.5.7/css1/css1.sl0000644000175400017500000003146110555355310013673 0ustar mildegm% -*- mode: slang; mode: folding -*- % %{{{ Documentation % % Description % % CSS1 (Cascading Style Sheet - level 1) mode for JED containing a "Mode" % menu with a lot of items to help you write css files. It also defines % two syntax highlighting schemes; one based on the attributes and values % of CSS1 and one pattern based (DFA). % % N.B. It is not wise to use the DFA scheme, since it doesn't correctly % highlight one-line declarations and there's no visual feedback to whether % a typed attribute or value is correct spelled or not. % % Usage % % Put this file in your JED_LIBRARY path and add the following lines to your % startup file (.jedrc or jed.rc): % % autoload ("css1_mode", "css1"); % add_mode_for_extension ("css1", "css"); % add_mode_for_extension ("css1", "css1"); % % Every time you open a file called 'style.css', css1_mode will % automatically be loaded. % % Changelog % % 1.6 - 2001/12/19 (JG): % - Moved and completed the syntax definitions and added attributes and % values as keyword and keyword1 to be used without DFA highlighting. % - Added string and delimiter classes to the DFA rules. % - Updated the DFA functions to use the newer dfa_* names. % - Corrected two typos in the attribute names in the "Mode" menu. % - Updated the documentation in this file. % % 1.5 - 2001/01/07 (FR): % - First public release. % 1.5.1 2007-01-23 (GM): % - bugfix in call to run_mode_hooks() % - comments with comments.sl % % Authors % % Johann Gerell % Francesc Rocher % %}}} $0 = "css1"; %{{{ Comments require("comments"); % Jed standard mode but not autoloaded by default set_comment_info("css1", "/* ", " */", 2|4); %}}} %{{{ Syntax definition create_syntax_table($0); define_syntax("/*", "*/", '%', $0); % comment define_syntax("//", "", '%', $0); % comment define_syntax(";:{},.", ',', $0); % delimiters define_syntax("{", "}", '(', $0); % matched braces define_syntax("#\\-0-9a-zA-Z_", 'w', $0); % words define_syntax('"', '"', $0); % string set_syntax_flags($0, 0x80); % strings don't span multiple lines %}}} %{{{ DFA highlighting #ifdef HAS_DFA_SYNTAX dfa_enable_highlight_cache("css1.dfa", $0); dfa_define_highlight_rule("^.*//.*$", "Qcomment", $0); dfa_define_highlight_rule("^.*/\\*.*\\*/$", "Qcomment", $0); dfa_define_highlight_rule ("^[^;{}/\\*]*$", "keyword", $0); dfa_define_highlight_rule ("^[^:]*:", "keyword1", $0); dfa_define_highlight_rule("{|}|;", "delimiter", $0); dfa_define_highlight_rule("\".*\"", "string", $0); dfa_build_highlight_table($0); #endif %}}} %{{{ Keywords: attributes () = define_keywords_n($0, "clearcolorfloatwidth", 5, 0); () = define_keywords_n($0, "bordermargin", 6, 0); () = define_keywords_n($0, "displaypadding", 7, 0); () = define_keywords_n($0, "font-size", 9, 0); () = define_keywords_n($0, "font-stylemargin-toptext-align", 10, 0); () = define_keywords_n($0, "font-familyfont-weightline-heightmargin-leftpadding-toptext-indentwhite-space", 11, 0); () = define_keywords_n($0, "border-colorborder-styleborder-widthmargin-rightpadding-left", 12, 0); () = define_keywords_n($0, "margin-bottompadding-right", 13, 0); () = define_keywords_n($0, "padding-bottomtext-transform", 14, 0); () = define_keywords_n($0, "list-style-typetext-decoration", 15, 0); () = define_keywords_n($0, "background-colorbackground-imageborder-top-width", 16, 0); () = define_keywords_n($0, "border-left-width", 17, 0); () = define_keywords_n($0, "border-right-width", 18, 0); () = define_keywords_n($0, "border-bottom-width", 19, 0); %}}} %{{{ Keywords: values () = define_keywords_n($0, "pre", 3, 1); () = define_keywords_n($0, "boldbothdiscleftnone", 4, 1); () = define_keywords_n($0, "blinkblockinsetlargeserifsmallright", 5, 1); () = define_keywords_n($0, "boldercentercircledoublegrooveinlineitaliclargermediumnormaloutsetsquare", 6, 1); () = define_keywords_n($0, "cursivedecimalfantasyjustifylightersmallerx-largex-small", 7, 1); () = define_keywords_n($0, "xx-largexx-small", 8, 1); () = define_keywords_n($0, "list-itemlowercasemonospaceunderlineuppercase", 9, 1); () = define_keywords_n($0, "capitalizesans-serif", 10, 1); () = define_keywords_n($0, "lower-alphalower-romanupper-alphaupper-roman", 11, 1); () = define_keywords_n($0, "line-through", 12, 1); %}}} private define css1_menu(menu) { %{{{ menu_append_popup (menu, "&Font Properties"); $0 = menu + ".&Font Properties"; { menu_append_item ($0, "&Size", "insert (\"font-size: \")"); menu_append_popup ($0, "&Absolute Size"); $1 = $0 + ".&Absolute Size"; { menu_append_item ($1, "xx-sm&all", "insert (\"font-size: xx-small;\")"); menu_append_item ($1, "x-s&mall", "insert (\"font-size: x-small;\")"); menu_append_item ($1, "&small", "insert (\"font-size: small;\")"); menu_append_item ($1, "me&dium", "insert (\"font-size: medium;\")"); menu_append_item ($1, "la&rge", "insert (\"font-size: large;\")"); menu_append_item ($1, "x-lar&ge", "insert (\"font-size: x-large;\")"); menu_append_item ($1, "xx-larg&e", "insert (\"font-size: xx-large;\")"); } menu_append_popup ($0, "&Relative Size"); $1 = $0 + ".&Relative Size"; { menu_append_item ($1, "&smaller", "insert (\"font-size: smaller;\")"); menu_append_item ($1, "&larger", "insert (\"font-size: larger;\")"); } menu_append_separator ($0); menu_append_item ($0, "&Family", "insert (\"font-family: \")"); menu_append_popup ($0, "Fon&tFamily"); $1 = $0 + ".Fon&tFamily"; { menu_append_item ($1, "&cursive", "insert (\"font-family: cursive;\")"); menu_append_item ($1, "&fantasy", "insert (\"font-family: fantasy;\")"); menu_append_item ($1, "&serif", "insert (\"font-family: serif;\")"); menu_append_item ($1, "s&ans-serif", "insert (\"font-family: sans-serif;\")"); menu_append_item ($1, "&monospace", "insert (\"font-family: monospace;\")"); } menu_append_separator ($0); menu_append_popup ($0, "St&yle"); $1 = $0 + ".St&yle"; { menu_append_item ($1, "&normal", "insert (\"font-style: normal;\")"); menu_append_item ($1, "&italic", "insert (\"font-style: italic;\")"); } menu_append_popup ($0, "&Weight"); $1 = $0 + ".&Weight"; { menu_append_item ($1, "&normal", "insert (\"font-weight: normal;\")"); menu_append_item ($1, "&bold", "insert (\"font-weight: bold;\")"); menu_append_item ($1, "b&older", "insert (\"font-weight: bolder;\")"); menu_append_item ($1, "&lighter", "insert (\"font-weight: lighter;\")"); menu_append_item ($1, "&other", "insert (\"font-weight: \")"); } } menu_append_popup (menu, "&Text Properties"); $0 = menu + ".&Text Properties"; { menu_append_item ($0, "&Line Height", "insert (\"line-height: \")"); menu_append_popup ($0, "&Alignment"); $1 = $0 + ".&Alignment"; { menu_append_item ($1, "&left", "insert (\"text-align: left;\")"); menu_append_item ($1, "&right", "insert (\"text-align: right;\")"); menu_append_item ($1, "¢er", "insert (\"text-align: center;\")"); menu_append_item ($1, "&justify", "insert (\"text-align: justify;\")"); } menu_append_popup ($0, "&Decoration"); $1 = $0 + ".&Decoration"; { menu_append_item ($1, "&none", "insert (\"text-decoration: none;\")"); menu_append_item ($1, "&blink", "insert (\"text-decoration: blink;\")"); menu_append_item ($1, "&line-through", "insert (\"text-decoration: line-through;\")"); menu_append_item ($1, "&underline", "insert (\"text-decoration: underline;\")"); } menu_append_item ($0, "&Indent", "insert (\"text-indent: \")"); menu_append_popup ($0, "&Transform"); $1 = $0 + ".&Transform"; { menu_append_item ($1, "&none", "insert (\"text-transform: none;\")"); menu_append_item ($1, "&capitalize", "insert (\"text-transform: capitalize;\")"); menu_append_item ($1, "&lowercase", "insert (\"text-transform: lowercase;\")"); menu_append_item ($1, "&uppercase", "insert (\"text-transform: uppercase;\")"); } } menu_append_popup (menu, "&Block Formatting"); $0 = menu + ".&Block Formatting"; { menu_append_popup ($0, "&Margins"); $1 = $0 + ".&Margins"; { menu_append_item ($1, "&left", "insert (\"margin-left: \")"); menu_append_item ($1, "&right", "insert (\"margin-right: \")"); menu_append_item ($1, "&top", "insert (\"margin-top: \")"); menu_append_item ($1, "&bottom", "insert (\"margin-bottom: \")"); menu_append_item ($1, "&all", "insert (\"margin: \")"); } menu_append_popup ($0, "&Padding"); $1 = $0 + ".&Padding"; { menu_append_item ($1, "&left", "insert (\"padding-left: \")"); menu_append_item ($1, "&right", "insert (\"padding-right: \")"); menu_append_item ($1, "&top", "insert (\"padding-top: \")"); menu_append_item ($1, "&bottom", "insert (\"padding-bottom: \")"); menu_append_item ($1, "&all", "insert (\"padding: \")"); } menu_append_separator ($0); menu_append_popup ($0, "Border &Style"); $1 = $0 + ".Border &Style"; { menu_append_item ($1, "&none", "insert (\"border-style: none;\")"); menu_append_item ($1, "&solid", "insert (\"border-style: solid;\")"); menu_append_item ($1, "&double", "insert (\"border-style: double;\")"); menu_append_item ($1, "&inset", "insert (\"border-style: inset;\")"); menu_append_item ($1, "&outset", "insert (\"border-style: outset;\")"); menu_append_item ($1, "&groove", "insert (\"border-style: groove;\")"); } menu_append_popup ($0, "Border &Width"); $1 = $0 + ".Border &Width"; { menu_append_item ($1, "&left", "insert (\"border-left-width: \")"); menu_append_item ($1, "&right", "insert (\"border-right-width: \")"); menu_append_item ($1, "&top", "insert (\"border-top-width: \")"); menu_append_item ($1, "&bottom", "insert (\"border-bottom-width: \")"); menu_append_item ($1, "&all", "insert (\"border-width: \")"); } menu_append_item ($0, "Border &Color", "insert (\"border-color: \")"); menu_append_separator ($0); menu_append_popup ($0, "C&lear"); $1 = $0 + ".C&lear"; { menu_append_item ($1, "&none", "insert (\"clear: none;\")"); menu_append_item ($1, "&left", "insert (\"clear: left;\")"); menu_append_item ($1, "&right", "insert (\"clear: right;\")"); menu_append_item ($1, "&both", "insert (\"clear: both;\")"); } menu_append_popup ($0, "&Float"); $1 = $0 + ".&Float"; { menu_append_item ($1, "&none", "insert (\"float: none;\")"); menu_append_item ($1, "&left", "insert (\"float: left;\")"); menu_append_item ($1, "&right", "insert (\"float: right;\")"); } menu_append_item ($0, "W&idth", "insert (\"width: \")"); } menu_append_popup (menu, "&Color Properties"); $0 = menu + ".&Color Properties"; { menu_append_item ($0, "&color", "insert (\"color: \")"); menu_append_item ($0, "&background-color", "insert (\"background-color: \")"); menu_append_item ($0, "background-&image", "insert (\"background-image: \")"); } menu_append_popup (menu, "C&lassification Properties"); $0 = menu + ".C&lassification Properties"; { menu_append_popup ($0, "&Display"); $1 = $0 + ".&Display"; { menu_append_item ($1, "&none", "insert (\"display: none;\")"); menu_append_item ($1, "&block", "insert (\"display: block;\")"); menu_append_item ($1, "&inline", "insert (\"display: inline;\")"); menu_append_item ($1, "&list-item", "insert (\"display: list-item;\")"); } menu_append_popup ($0, "&List Style Type"); $1 = $0 + ".&List Style Type"; { menu_append_item ($1, "&none", "insert (\"list-style-type: none;\")"); menu_append_item ($1, "&disc", "insert (\"list-style-type: disc;\")"); menu_append_item ($1, "&circle", "insert (\"list-style-type: circle;\")"); menu_append_item ($1, "&square", "insert (\"list-style-type: square;\")"); menu_append_item ($1, "&decimal", "insert (\"list-style-type: decimal;\")"); menu_append_item ($1, "lower-&roman", "insert (\"list-style-type: lower-roman;\")"); menu_append_item ($1, "upper-r&oman", "insert (\"list-style-type: upper-roman;\")"); menu_append_item ($1, "lower-&alpha", "insert (\"list-style-type: lower-alpha;\")"); menu_append_item ($1, "upper-a&lpha", "insert (\"list-style-type: upper-alpha;\")"); } menu_append_popup ($0, "&White Space"); $1 = $0 + ".&White Space"; { menu_append_item ($1, "&normal", "insert (\"white-space: normal;\")"); menu_append_item ($1, "&pre", "insert (\"white-space: pre;\")"); } } } %}}} public define css1_mode() { $0 = "css1"; set_mode($0, 0); use_syntax_table($0); mode_set_mode_info($0, "init_mode_menu", &css1_menu); run_mode_hooks($0 + "_mode_hook"); } jedmodes-2.5.7/filter-buffer/0000755000175400017500000000000011121652632014335 5ustar mildegmjedmodes-2.5.7/filter-buffer/filter-buffer.sl0000644000175400017500000002654511121652632017445 0ustar mildegm% Filter buffer: show/hide lines that match a pattern % =================================================== % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % 2005-04-01 0.1 first public version % 2005-05-31 0.2 bugfix in INITIALIZATION block and set_comments_hidden() % (escaping special chars in regexp pattern) report P. Boekholt % added tm documentation % 2005-09-11 0.3 added delete_hidden_lines() and copy_visible_lines() % 2006-06-09 0.3.1 INITIALIZATION: moved the menu entries to a popup % 2007-08-31 0.3.2 bugfix in delete_hidden_lines() (J. Sommer, GM) % 2007-09-20 0.3.3 copy_visible_lines() now works also for readonly buffers % 2007-12-20 0.4 generic (un)folding of blocks; use PCRE regexps; % re_fold_buffer() % 2008-04-21 0.4.1 do not load unfinished code from pcre-fold project % 2008-05-26 0.4.2 move pcre-fold code to pcre-fold.sl % add generic hiding/folding functions % 2008-12-16 0.4.3 Fix pcre_fsearch() for utf8 multibyte chars (P. Boekholt) % % Usage % ----- % % put in the jed_library_path and make available by a keybinding or % via the following menu entry in your .jedrc % (make-ini >= 2.2 will do this for you) % % Beware: hidden lines are still part of a defined region, thus % copying a region will copy the hidden lines as well. % (And evaluating a region will evaluate the hidden lines.) % Use copy_visible_lines() to exclude hidden lines. # define filter_buffer_load_popup_hook(menubar) { variable menu = "Global.&Buffers"; menu_insert_popup(5, menu, "F&ilter Buffer"); menu += ".F&ilter Buffer"; menu_append_item(menu, "&Hide Matching Lines", "set_matching_hidden"); % menu_append_item(menu, "&Show Matching Lines", "set_matching_hidden(0)"); menu_append_item(menu, "Show &Only Matching Lines", "set_buffer_hidden(1); set_matching_hidden(0)"); menu_append_item(menu, "Show &All Lines", "set_buffer_hidden(0)"); menu_append_item(menu, "&Toggle Line Hiding", "toggle_hidden_lines"); menu_append_item(menu, "&Copy Hidden Lines", "copy_hidden_lines"); menu_append_item(menu, "&Delete Hidden Lines", "delete_hidden_lines"); } append_to_hook ("load_popup_hooks", &filter_buffer_load_popup_hook); "set_buffer_hidden", "filter-buffer.sl"; "set_matching_hidden", "filter-buffer.sl"; "toggle_hidden_lines", "filter-buffer.sl"; "set_comments_hidden", "filter-buffer.sl"; _autoload(4); # provide("filter-buffer"); % Requirements % ------------ % standard modes require("pcre"); autoload("get_comment_info", "comments"); % modes from http://jedmodes.sf.net/ autoload("push_defaults", "sl_utils"); % Functions % ========= % PCRE regexp matching % -------------------- % Search forward for compiled PCRE regular expression \var{re} % (use \sfun{pcre_compile} to compile a pattern) % Place point at bol of first matching line % Return whether a match is found define pcre_fsearch_line(re) { push_mark(); do { push_mark_eol(); if (pcre_exec(re, bufsubstr())) { pop_mark_0(); bol(); return 1; } } while (down_1()); pop_mark_1(); return 0; } % Search backward for compiled PCRE regular expression \var{pat} % Place point at bol of first matching line % Return whether a match is found public define pcre_bsearch_line(re) { push_mark(); do { push_mark(); bol(); if (pcre_exec(re, bufsubstr())) { pop_mark_0(); return 1; } } while (up_1()); pop_mark_1(); return 0; } % Search forward for PCRE regular expression \var{pat} % Place point at begin of the match % Return whether a match is found % Other than the variant in jedpcre.sl by Paul Boekholt, this function does % not find matches across lines. OTOH, it works correct with the '^' bol % anchor. public define pcre_fsearch(pat) { variable re = pcre_compile(pat); !if (pcre_fsearch_line(re)) return 0; variable match_pos = pcre_nth_match(re, 0); % On 14.12.08, Paul Boekholt wrote: % > I've noticed that pcre_nth_match also returns byte offsets, even in utf-8 % > mode. This means that the pcre_fsearch function in jedpcre.sl did not work % > right in utf-8 mode. Since there's no good way to fix this, I had to remove % > the function. I just noticed you have a pcre_fsearch defined in % > filter-buffer.sl. I guess that creates a name conflict, but that's resolved % > now. Your version also has this problem, but not as severe as mine had. I % > think you can fix it using a scheme % > pcre_nth_match -> (byte offset) -> substrbytes -> (string) -> strlen % > -> (character offset) -> go_right. % convert byte position to char position: variable line = line_as_string(); bol(); variable prefix_str = substrbytes(line, 1, match_pos[0]); match_pos[0] = strlen(prefix_str); % Move to start of match (don't use goto_column() to count for TABs). go_right(match_pos[0]); return 1; } % Hide and show lines % -------------------- %!%+ %\function{set_buffer_hidden} %\synopsis{Hide/unhide the whole buffer} %\usage{Void set_buffer_hidden(hide=1)} %\description % Set or remove the "hidden line" flag for the whole buffer. % If a visible region is defined, act on it instead. %\notes % set_buffer_hidden is called by set_matching_hidden(".*") % for performace reasons %\seealso{set_region_hidden, set_matching_hidden, toggle_hidden_lines} %!%- public define set_buffer_hidden() % (hide=1) { variable hide = push_defaults(1, (_NARGS)); push_spot(); !if (is_visible_mark()) mark_buffer(); set_region_hidden(hide); pop_spot(); } %!%+ %\function{set_matching_hidden} %\synopsis{Hide all lines that match the regexp \var{pat}} %\usage{Void set_matching_hidden() %(hide=1, [pat])} %\description % Filter all lines matching the PCRE regular expression (pcre) % \var{pat}. The argument \var{hide} decides what to do with matching % lines: % 1: hide % 0: unhide (make visible) matching lines. % If called without optional argument \var{pat}, ask for a pattern in % the minibuffer. %\example %#v+ % set_matching_hidden() % ask for pattern, hide matching lines % set_matching_hidden(1) % ask for pattern, unhide matching lines % set_matching_hidden(0, "$%") % hide lines starting with "%" %#v- %\notes % Beware: hidden lines are still part of a defined region, thus % copying a region will copy the hidden lines as well. % Use \sfun{copy_visible_lines} instead. %\seealso{set_line_hidden, toggle_hidden_lines, delete_hidden_lines} %!%- public define set_matching_hidden() %(hide=1, [pat]) { variable hide, pat; (hide, pat) = push_defaults(1, NULL, _NARGS); variable prompt = ["Show only", "Hide all"]; prompt = prompt[hide] + " lines containing (pcre) regexp:"; if (pat == NULL) pat = read_mini(prompt, "", ""); push_spot_bob(); % speadup for "matchall" if (pat == ".*" or pat == "") { set_buffer_hidden(hide); pop_spot(); return; } variable re = pcre_compile(pat); while (andelse{not(eobp())}{pcre_fsearch_line(re)}) { set_line_hidden(hide); eol(); } pop_spot(); } %!%+ %\function{toggle_hidden_lines} %\synopsis{Toggle the hidden attribute of all lines} %\usage{Void toggle_hidden_lines()} %\description % Toggle the hidden attribute of all lines in a buffer, i.e. % inverse the visibility of the lines. %\seealso{set_line_hidden, set_buffer_hidden, set_matching_hidden} %!%- public define toggle_hidden_lines() { push_spot_bob(); do set_line_hidden(not(is_line_hidden())); while (down_1); pop_spot(); } % Handle hidden lines % ------------------- %!%+ %\function{delete_hidden_lines} %\synopsis{Delete lines with the hidden attribute} %\usage{Void delete_hidden_lines()} %\description % Scan the entire buffer for hidden lines and delete these. %\seealso{set_line_hidden, set_matching_hidden, toggle_hidden_lines} %!%- public define delete_hidden_lines() { push_spot_bob(); do while (is_line_hidden() and not(eobp())) delete_line(); while (down_1); pop_spot(); } %!%+ %\function{copy_visible_lines} %\synopsis{Copy only visible lines of the region/buffer} %\usage{ copy_visible_lines()} %\description % Normal (yp) copy does not distinguish hidden lines from visible ones but % copies everything in the region. % Use copy_visible_lines if you want to permanently separate visible and % hidden lines (without deleting the hidden ones). %\seealso{yp_copy_region_as_kill, set_matching_hidden, toggle_hidden_lines} %!%- public define copy_visible_lines() { variable str = ""; push_spot(); !if (is_visible_mark()) mark_buffer(); narrow(); bob(); % collect in string do if (not(is_line_hidden())) str += line_as_string() + "\n"; while (down_1); widen(); pop_spot(); % move string to kill-ring % (use tmp buffer as the current one might be read-only) sw2buf(make_tmp_buffer_name("visible_lines")); push_mark(); insert(str); yp_kill_region(); set_buffer_modified_flag(0); delbuf(whatbuf); } % TODO: search in visible lines % Hide Comments % ------------- %!%+ %\function{set_comments_hidden} %\synopsis{Set hidden attribute for all comment lines} %\usage{Void set_comments_hidden(hide=1)} %\description % Hide (or make visible) all comment lines in a buffer by setting the % hidden attribute. % % Calls \sfun{set_matching_hidden} with a regular expression derived from % the cbeg and cend strings obtained with \sfun{get_comment_info}. %\notes % A comment line is a line that contains only commented out text % and optional whitespace. % % \sfun{set_comments_hidden} doesnot work for multiline comments. % % Beware: hidden lines are still part of a defined region, thus % % * copying a region will copy the hidden lines as well, % * evaluating a region will evaluate the hidden lines, % * search and replace will replace in the hidden lines, ... % % Use \sfun{copy_visible_lines} or \sfun{delete_hidden_lines}. %\seealso{set_matching_hidden, get_comment_info, comment_line} %!%- public define set_comments_hidden() % (hide=1) { variable hide = push_defaults(1, _NARGS); % optional argument variable cbeg, cend, pattern, white = "[ \\t]*", re_chars = "\\^$[]*.+?", cinfo = get_comment_info(); % prepare regexp pattern if (cinfo == NULL) verror("no comments defined for mode %s", get_mode_name()); cbeg = str_quote_string (strtrim(cinfo.cbeg), re_chars, '\\'); cend = str_quote_string (strtrim(cinfo.cend), re_chars, '\\'); pattern = "^" + white + cbeg + ".*" + cend + white + "$"; set_matching_hidden(hide, pattern); } % Generic (un)folding % """"""""""""""""""" % :: % Hide a sequence of non-hidden lines % or unhide a sequence of hidden lines static define set_block_hidden(hide) { push_spot(); skip_hidden_lines_forward(not(hide)); push_mark(); skip_hidden_lines_backward(not(hide)); set_region_hidden(hide); pop_spot(); } % Is the point in or above a hidden line? % Return value: % 2 in a hidden line % 1 above hidde line (at end of a line followed by a hidden line) static define in_fold() { push_spot(); EXIT_BLOCK { pop_spot(); } if (is_line_hidden()) return 2; !if (right(1)) return 0; return is_line_hidden(); } % Unhide the next block of hidden lines, if inside or at start of it % call newline_and_indent() otherwise. public define newline_or_unfold() { if (in_fold()) set_block_hidden(0); else call("newline_and_indent"); } jedmodes-2.5.7/boxquote/0000755000175400017500000000000011140522252013442 5ustar mildegmjedmodes-2.5.7/boxquote/boxquote.sl0000644000175400017500000000534011140522252015652 0ustar mildegm% -*- SLang -*- % $Id: boxquote.sl,v 1.1 2009/01/30 06:56:42 milde Exp $ % Copyright (c) Philipp Grau % Released under the terms of the GNU GPL (version 2 or later). % boxquote.sl % % Inspired by boxquote.el for emacs % Stolen code shamelessly from mail_mode.sl % by Thomas Roessler % % First version on 13.03.2002 % Philipp Grau % % Improvements by Paul Boekholt % Currently there are tree usefull functions: % boxquote_insert_file: inserts a file in boxquotes % boxquote_region: boxquotes a region % boxquote_region_with_comment(); boxquotes a region with a comment % % ToDo: % - make boxes cutomizable % - improve some things % - triming of the filename? % for cut&paste insertions? % - write a deboxquote % - fix bugs % - ... % Usage: put something like the next line in your .jedrc % () = evalfile("~/share/slang/boxquote.sl"); % % or use % _autoload("boxquote_region", "boxquote" % "boxquote_region_with_comment", "boxquote" % "boxquote_insert_file", "boxquote", % 3); % % % And the you can do something like M-x boxquote_insert_file % An you will be asked for a file name. % Or mark a region and call M-x boxquote_region % _debug_info = 1; %%%%% PROTOTYPES define boxquote(name); define boxquote_buffer(ntags); public define boxquote_region(); public define boxquote_region_with_comment(); define boxquote_region_with_comment_jump(); public define boxquote_insert_file(); %%%%%% real stuff define boxquote_region() { boxquote(""); } define boxquote_region_with_comment() { variable comment = read_mini ("Comment:", "",""); boxquote(comment); } define boxquote_region_with_comment_jump() { variable comment = read_mini ("Comment:", "",""); boxquote(" "); } define boxquote_insert_file() { % insert_file(); variable file = read_with_completion ("File:", Null_String, Null_String, 'f'); push_spot (); push_mark(); () = insert_file (file); boxquote(file); pop_spot (); } define boxquote(name) { % vmessage("Name=%s",name); !if (bolp) go_down_1; push_spot(); narrow(); bob(); insert(",----"); if (name != "") { insert("[ "); insert(name); insert(" ]---"); } insert("\n"); boxquote_buffer(1); eob(); bol(); if (what_char () == '|') { del ();del(); insert ("`----\n"); } widen(); pop_spot(); down(1); % eol(); insert("\n"); } define boxquote_buffer(ntags) { variable tags; push_spot(); % bob(); tags = ""; loop (ntags) tags = strcat (tags, "| "); do { insert (tags); } while (down_1 ()); % up(1); pop_spot(); } % So M-x finds the functions $0 = _stkdepth; . "boxquote_insert_file" "boxquote_region" "boxquote_region_with_comment" _add_completion(_stkdepth - $0); jedmodes-2.5.7/libdir/0000755000175400017500000000000011146322470013047 5ustar mildegmjedmodes-2.5.7/libdir/libdir.sl0000644000175400017500000001460311146322444014661 0ustar mildegm% libdir.sl: Support for library directories with jed extensions % % Copyright © 2005 Günter Milde and released under the terms % of the GNU General Public License (version 2 or later). % % Versions % -------- % 0.9 2005-09-19 first public version, based on home-lib.sl % 0.9.1 2005-09-29 removed custom_variable stuff % 0.9.2 2005-10-12 documentation fix % 0.9.3 2005-11-03 evaluation of ini.sl now customizable with optional arg % 0.9.4 2005-11-06 added provide() statement % 0.9.5 2006-04-05 added year to copyright statement % 0.9.6 2006-04-13 replaced continue with return % and binary string ops with strcat % 0.9.7 2006-05-17 added remove_libdir() % 0.9.8 2007-10-18 add|append doc-file to doc_files list (report J. Sommer) % 0.9.9 2008-05-05 libdir initialisation: load ini.slc, ini.sl or pass % % Features % -------- % The functions add_libdir(path) and append_libdir(path) declare % additional library directories: % % * prepend|append `path' to the jed-library-path (searched for modes) % * set Color_Scheme_, dfa-cache- and documentation- path % * evaluate (if existent) the file ini.sl in path % (ini.sl files can be autocreated by make_ini.sl) % % Together with make_ini.sl, this provides a convenient way of extending % jed with contributed or home-made scripts. :: provide("libdir"); % Usage % ----- % Write in your jed.rc file e.g. :: % % () = evalfile("/FULL_PATH_TO/libdir"); % %add_libdir("/usr/local/share/jed/lib")); % add_libdir(path_concat(Jed_Home_Directory, "lib")); % Functions % --------- %!%+ %\function{add_libdir} %\synopsis{Register a library dir for use by jed} %\usage{add_libdir(lib, initialize=1)} %\description % Perform the following actions if the relevant paths are valid: % * Prepend \var{lib} to the library path and the \var{Jed_Highlight_Cache_Path} % * Add \var{lib}/colors to \var{Color_Scheme_Path} and % \var{lib}/libfuns.txt to \var{Jed_Doc_Files} or using \sfun{add_doc_file}. % * If \var{initialize} is TRUE, evaluate the file \var{lib}/ini.sl % to enable initialization (autoloads etc) %\example % The following lines in jed.rc %#v+ % () = evalfile("/FULL_PATH_TO/libdir.sl"); % add_libdir("usr/local/jed/lib/", 0)); % do not initialize % add_libdir(path_concat(Jed_Home_Directory, "lib")); %#v- % will register the local and user-specific library-dir %\notes % The function \sfun{make_ini} (from jedmodes.sf.net/mode/make_ini/) % can be used to auto-create an ini.sl file for a library dir. %\seealso{append_libdir, set_jed_library_path} %!%- define add_libdir() { variable lib, path, initialize; if (_NARGS == 2) initialize = (); else initialize = 1; % backwards compatibility lib = (); % abort, if directory doesnot exist if (orelse{lib == ""}{2 != file_status(lib)}) return; % jed library path set_jed_library_path(strcat(lib, ",", get_jed_library_path())); % colors path = path_concat(lib, "colors"); if (2 == file_status(path)) Color_Scheme_Path = strcat(path, ",", Color_Scheme_Path); % documentation path = path_concat(lib, "libfuns.txt"); if (1 == file_status(path)) { #ifexists Jed_Doc_Files Jed_Doc_Files = strcat(path, ",", Jed_Doc_Files); #endif #ifexists set_doc_files set_doc_files ([path, get_doc_files ()]); % add_doc_file(path); % actually appends!! #endif } % dfa cache #ifdef HAS_DFA_SYNTAX % Jed_Highlight_Cache_Dir = lib; Jed_Highlight_Cache_Path = strcat(lib, ",", Jed_Highlight_Cache_Path); #endif % Evaluate initialisation code if (initialize) { try { () = evalfile(path_concat(lib, "ini")); } catch OpenError; } } %!%+ %\function{append_libdir} %\synopsis{Register a library dir for use by jed} %\usage{append_libdir(lib, initialize=1)} %\description % This function is similar to \sfun{add_libdir} but appends the library % dir to the paths. %\seealso{add_libdir, set_jed_library_path} %!%- define append_libdir() { variable lib, path, initialize; if (_NARGS == 2) initialize = (); else initialize = 1; % backwards compatibility lib = (); % abort, if directory doesnot exist if (orelse{lib == ""}{2 != file_status(lib)}) return; % jed library path set_jed_library_path(strcat(get_jed_library_path(), ",", lib)); % colors path = path_concat(lib, "colors"); if (2 == file_status(path)) Color_Scheme_Path = strcat(Color_Scheme_Path, ",", path); % documentation path = path_concat(lib, "libfuns.txt"); if (1 == file_status(path)) { #ifexists Jed_Doc_Files Jed_Doc_Files = strcat(Jed_Doc_Files, ",", path); #endif #ifexists add_doc_file add_doc_file(path); % actually appends #endif } % dfa cache #ifdef HAS_DFA_SYNTAX % Jed_Highlight_Cache_Dir = lib; Jed_Highlight_Cache_Path = strcat(Jed_Highlight_Cache_Path, ",", lib); #endif % Evaluate initialisation code if (initialize) { try { () = evalfile(path_concat(lib, "ini")); } catch AnyError; } } %!%+ %\function{remove_libdir} %\synopsis{Remove a library dir from search paths} %\usage{remove_libdir(lib)} %\description % Revert the actions of \sfun{add_libdir} or \sfun{append_libdir}. % * Remove \var{lib} from the jed library path and the \var{Jed_Highlight_Cache_Path} % * Remove \var{lib}/colors from \var{Color_Scheme_Path} % * Remove \var{lib}/libfuns.txt from \var{Jed_Doc_Files}. %\notes % As it is impossibly to revert the evaluation of \var{lib}/ini.sl, % only add_libdir(dir, 0); or append_libdir(dir, 0) % can be fully reversed. %\seealso{set_jed_library_path, add_libdir, append_libdir, str_replace_all} %!%- define remove_libdir(lib) { variable path, dir; % jed library path dir = strcat(",", lib, ","); path = strcat(",", get_jed_library_path(), ","); path = str_replace_all(path, dir, ","); set_jed_library_path(strtrim(path, ",")); % colors dir = strcat(",", path_concat(lib, "colors"), ","); path = strcat(",", Color_Scheme_Path, ","); path = str_replace_all(path, dir, ","); Color_Scheme_Path = strtrim(path, ","); % documentation dir = strcat(",", path_concat(lib, "libfuns.txt"), ","); path = strcat(",", Jed_Doc_Files, ","); path = str_replace_all(path, dir, ","); Jed_Doc_Files = strtrim(path, ","); % dfa cache #ifdef HAS_DFA_SYNTAX dir = strcat(",", lib, ","); path = strcat(",", Jed_Highlight_Cache_Path, ","); path = str_replace_all(path, dir, ","); Jed_Highlight_Cache_Path = strtrim(path, ","); #endif } jedmodes-2.5.7/ding/0000755000175400017500000000000011307553774012537 5ustar mildegmjedmodes-2.5.7/ding/ding.sl0000644000175400017500000002732311307553774014027 0ustar mildegm% ding.sl Ding dictionary lookup % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % inspired by the tcl/tk program "ding" for german-english translation % % Version 0.8 first draft % Version 1 Adapted to the new format of the ding dictionary % 2005-04-07 1.1 bugfix: added missing autoloads % 2005-11-07 1.2 changed _implements() to implements() % 2006-05-26 1.2.1 missing autoload and forward def. for ding() (J. Sommer) % 2006-06-01 1.2.2 forward def needs to be public % 2007-04-16 1.3 error message, if no dictionary found % 2007-04-17 1.3.1 replaced custom variable Wordlists with private one and % auxiliary function ding->add_dictionary % Documentation update, cleanup, % bugfixes: Case sensitivity, Ding_Dictionary % 2007-06-03 1.4 convert iso-latin1 <-> UTF-8 if not in UTF-8 mode. % 2007-09-20 1.4.1 reset blocal var "encoding" with buffer re-use, % use List for blocal var "generating_function" % 2009-02-16 1.5 ding(): an empty string arg triggers an interactive % request for a word the same way as no optional arg does, % custom var Ding_Case_Search, % failsave formatting. % 2009-12-08 1.8.1 Adapt to new require() syntax in Jed 0.99.19 % % Usage % ----- % % * Place "ding.sl" in the jed_library_path % % * Add autoload("ding", "ding") to your .jedrc (or use update_ini() % from make_ini.sl) % % * Add your dictionaries % "de-en" is automatically set, if the file is found in a standard location % % Proposed scheme for keys is lang1-lang2 with abbreviations from 'locale' % settings, say "de-en" == German::English, e.g.:: % % autoload("ding->add_dictionary", "ding"); % define ding_setup_hook() % { % % ding->add_dictionary("de-en", "/usr/share/trans/de-en"); % ding->add_dictionary("se-de", "~/dictionaries/swedish-german.txt"); % } % % * Optionally change custom variables % Requirements % ------------ % % * A bilingual wordlist in ASCII format (e.g. the one that comes % with "ding" http://www.tu-chemnitz.de/~fri/ding/ (German-English) % or the ones from the "magic dic" http://magic-dic.homeunix.net/ ) % % * the grep command (with support for the -w argument, e.g. GNU grep) % % * extensions from http://jedmodes.sf.net/ % #if (_jed_version > 9918) require("keydefs", "Global"); % standard mode not loaded by default require("view", "Global"); % readonly-keymap require("sl_utils", "Global"); % basic stuff require("bufutils", "Global"); #else require("keydefs"); require("view"); require("sl_utils"); require("bufutils"); #endif autoload("get_word", "txtutils"); autoload("bget_word", "txtutils"); autoload("get_buffer", "txtutils"); autoload("get_table", "csvutils"); autoload("insert_table", "csvutils"); autoload("strtrans_latin1_to_utf8", "utf8helper"); autoload("utf8_to_latin1", "utf8helper"); % Customisation % ------------- % The default wordlist, given as language pair custom_variable("Ding_Dictionary", "de-en"); % Translating Direction: 0 to, 1 from, 2 both ["->", "<-", "<->"] custom_variable("Ding_Direction", 2); % what to look for (0,1) == ["substring", "word"] custom_variable("Ding_Word_Search", 1); % do a case-sensitive lookup for the word? custom_variable("Ding_Case_Search", CASE_SEARCH_DEFAULT); % Initialization % -------------- % name and namespace provide("ding"); implements("ding"); private variable mode = "ding"; % private variables % ''''''''''''''''' private variable Default_Sep = "::"; private variable Dingbuf = "*dictionary lookup*"; private variable Direction_Names = ["->", "<-", "<->"]; private variable help_string = "i:Insert r:Replace l:new_Lookup c:Case d:Direction w:Word_search"; % map of known dictionaries private variable Dictionaries = Assoc_Type[String_Type]; % add a new dictionary to the map of known dictionaries % % TODO: Interaktive... ask in minibuffer? % custom separator-string (Dictionaries as Assoc_Type[List_Type]) % add_dictionary(key, file, sep=Default_Sep, word_chars=get_word_chars()) % Dictionaries[key] = {file, sep, word_chars); static define add_dictionary(key, file) { Dictionaries[key] = file; } % Set default (works for Debian and SuSE Linux) !if (assoc_key_exists(Dictionaries, "de-en")) { foreach $1 (["/usr/share/trans/de-en", "/usr/X11R6/lib/ding/ger-eng.txt"]) if (file_status($1)) add_dictionary("de-en", $1); } % sanity check, provide an clear error message !if (assoc_key_exists(Dictionaries, Ding_Dictionary)) verror("Default dictionary (%s) not defined.", Ding_Dictionary); % Functions % --------- private define ding_status_line() { variable languages, str; languages = str_replace_all(Ding_Dictionary, "-", Direction_Names[Ding_Direction]); str = sprintf("Look up[%s] %s (Case %d, Word_Search %d)", languages, get_blocal("generating_function")[1], Ding_Case_Search, Ding_Word_Search); set_status_line(str + " (%p)", 0); } static define toggle_direction() { Ding_Direction++; if (Ding_Direction > 2) Ding_Direction = 0; ding_status_line(); } static define toggle_case() { Ding_Case_Search = not(Ding_Case_Search); ding_status_line(); } static define toggle_word_search() { Ding_Word_Search = not(Ding_Word_Search); ding_status_line(); } % % TODO: Interaktive... ask in minibuffer, save where??? % public define ding_add_dictionary() %(key, file, sep=ding->Default_Sep) % { % variable key, file, sep; % (key, file, sep) = push_defaults( , , Default_Sep, _NARGS); % Wordlists[key] = file+\n+sep; % } % Switch focus to side: 0 left, 1 right, 2 toggle static define switch_sides(side) { variable len = ffind(get_blocal_var("delimiter")); % len == 0: right, len >0: left !if(len * side) bol; else { go_right(len); skip_white(); } } % Do we need customizable comment strings? private define delete_comments() { push_spot(); while (bol_fsearch("#")) call("kill_line"); pop_spot(); } % count the number of words in a string private define string_wc(str) { if(str == NULL) return 0; % TODO: filter additions like {m} or [Am] % use only part until first '|' return length(strtok(str)); } % format the output buffer static define format_output() { variable e, str = get_buffer(); % enable undoing in case something goes wrong: try (e) { variable sep = get_blocal("delimiter", Default_Sep); variable a1, a2, a = get_table(sep, 1); % read results into a 2d-array % show(a); % Sort by length of result % TODO word-count on first alternative (until first |) in source lang % flush(sprintf("sorting %d results", what_line)); % variable wc = array_map(Int_Type, &strlen, a); % % variable wc = array_map(Int_Type, &string_wc, a); % a = a[array_sort(wc[*, source_lang]), *]; % Replace the | (alternative-bars) with newlines % tricky, as we need this independently for the two sides sep = sprintf(" %s ", sep); % first language insert_table(a[*,[0]], "n", sep); bob(); replace("|", "\n|"); a1 = get_table(sep, 1)[*,0]; % show("a1", a1); % second language insert_table(a[*,[1]], "n", sep); bob(); replace("|", "\n"); a2 = get_table(sep, 1)[*,0]; % show("a2", a2); a = String_Type[length(a1), 2]; a[*,0] = a1; a[*,1] = a2; % show("a", a); % show("a1,a2", a); insert_table(a, "n", sep); } catch AnyError: { insert(str); % show(e); throw e.error, e.message; } } public define ding_mode(); % forward definition public define ding() % ([word], direction=Ding_Direction) { variable word, direction; (word, direction) = push_defaults("", Ding_Direction, _NARGS); word = strtrim(word); if (word == "") word = read_mini("word to translate:", bget_word(), ""); % poor mans utf-8 conversion !if (_slang_utf8_ok) word = strtrans_latin1_to_utf8(word); variable pattern, lookup_cmd = "grep", file = extract_element(Dictionaries[Ding_Dictionary], 0, '\n'), sep = extract_element(Dictionaries[Ding_Dictionary],1,'\n'); if (sep == NULL) sep = Default_Sep; % Assemble command !if (Ding_Case_Search) lookup_cmd += " -i "; if (Ding_Word_Search) % Whole word search lookup_cmd += " -w"; switch (direction) % Translating direction [0:"->", 1:"<-", 2:"<->"] {case 0: pattern = word + ".*" + sep;} {case 1: pattern = sep + ".*" + word;} {case 2: pattern = word;} lookup_cmd = sprintf("%s '%s' %s", lookup_cmd, pattern, file); % Prepare the output buffer popup_buffer(Dingbuf); set_readonly(0); erase_buffer(); % call the grep command flush("calling " + lookup_cmd); shell_perform_cmd(lookup_cmd, 1); % post-process output delete_comments(); trim_buffer(); define_blocal_var("delimiter", sep); define_blocal_var("generating_function", {_function_name, word, direction}); define_blocal_var("encoding", "utf8"); !if (_slang_utf8_ok) utf8_to_latin1(); if (bobp and eobp) { vinsert("No results for '%s'", word); % insert("\n\n" + lookup_cmd); } else { eob; % show(lookup_cmd, what_line, "results"); if (what_line < 1000) % do not format too long buffers as this takes time format_output(); bob; } % find out which language the word is from fsearch(word); variable source_lang = not(ffind(sep)); switch_sides(not(source_lang)); ding_mode(); fit_window(get_blocal("is_popup", 0)); } % follow up lookup, normally started with Enter static define ding_follow() { variable word = get_word(), direction = Ding_Direction; % adapt lookup direction if(direction < 2) direction = not(ffind(get_blocal("delimiter", ' '))); % 0 left, 1 right ding(word, direction); } static define double_click_hook(line, col, but, shift) { ding_follow(); return (0); } % --- Keybindings !if (keymap_p(mode)) copy_keymap(mode, "view"); definekey("ding->toggle_case", "c", mode); definekey("ding->toggle_direction", "d", mode); definekey("ding->ding_follow", "f", mode); definekey("close_and_insert_word", "i", mode); definekey("ding", "l", mode); % Lookup definekey("close_and_replace_word", "r", mode); definekey("ding", "t", mode); % Translate definekey("ding->toggle_word_search", "w", mode); definekey("ding->switch_sides(2)", "^I", mode); % TAB definekey("ding->ding_follow", "^M", mode); % Enter % TODO (Alt)-Left/Right - History (comes with the generalized navigage mode.) % --- the mode menu private define ding_menu (menu) { menu_append_item (menu, "New &Lookup", "ding"); menu_append_item (menu, "&Insert", "close_and_insert_word"); menu_append_item (menu, "&Replace", "close_and_replace_word"); menu_append_item (menu, "Toggle &Case", "ding->toggle_case"); menu_append_item (menu, "Toggle &Direction", "ding->toggle_direction"); menu_append_item (menu, "Toggle &Word Search", "ding->toggle_word_search"); menu_append_item (menu, "&Quit", "close_buffer"); % TODO: popup_menu "Set &Wordlist", list assoc_get_keys(Dictionaries) % set Dictionary % better feedback in toggle Case/Direction } % --- Create and initialize the syntax tables. create_syntax_table (mode); define_syntax("::", "", '%', mode); % Comments (2nd language as comment) % define_syntax("::", '>', mode); % keyword define_syntax('|', '#', mode); % examples % define_syntax("|", '+', mode); % examples set_syntax_flags (mode, 0); public define ding_mode() { set_mode(mode, 0); % use_syntax_table (mode); set_readonly(1); set_buffer_modified_flag(0); use_keymap (mode); use_syntax_table(mode); mode_set_mode_info (mode, "init_mode_menu", &ding_menu); set_buffer_hook ("mouse_2click", &ding->double_click_hook); ding_status_line(); run_mode_hooks(mode + "_mode_hook"); message(help_string); } jedmodes-2.5.7/strutils/0000755000175400017500000000000011262357374013505 5ustar mildegmjedmodes-2.5.7/strutils/strutils.sl0000644000175400017500000003240011262357374015735 0ustar mildegm% Utilities for processing of strings % % Copyright (c) 2005 Günter Milde (milde@users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 0.9 first public version % 1.0 moved here string_repeat(), string_reverse() from datutils % new: strwrap(), strbreak(), string_get_last_match() % (the latter suggested as string_nth_match() by PB) % 1.1 new functions get_keystring() and unget_string() % 1.2 removed unget_string() after learning about % buffer_keystring() (standard fun, which does the same) % 1.3 new function str_re_replace_all() % 2005-01-01 1.4 removed the string_get_last_match() alias, call % string_nth_match() instead. % added tm documentation % 2005-11-21 1.4.1 removed the public from define str_repeat() and % define get_keystring() % 2006-03-01 1.4.2 added provide() % added autoload for push_defaults() % 2007-01-15 1.5 added str_re_replace_by_line() after a report by % Morten Bo Johansen that str_re_replace_all is dead slow % for large strings. % 1.5.1 bugfix in str_re_replace_all() by M. Johansen % 2007-05-09 1.6 new function strsplit() % 2007-05-25 1.6.1 optimized str_re_replace() by Paul Boekholt % 2008-01-04 1.6.2 docu fix in strsplit(), max_n not functional yet % bugfix for n_max=0 in str_re_replace() % 2008-12-16 1.6.3 bugfix: regexp search uses byte semantics (P. Boekholt) % 2009-10-05 1.7 new: str_unicode_escape(). % % (projects for further functions in projects/str_utils.sl) autoload("array_append", "datutils"); autoload("push_defaults", "sl_utils"); provide("strutils"); %!%+ %\function{string_nth_match} %\synopsis{Return the (nth) substring of the last call to string_match} %\usage{String = string_nth_match(str, n)} %\description % After matching a string against a regular expression with % \sfun{string_match}, \sfun{string_nth_match} can be used to extract % the exact match. % % By convention, \var{nth} equal to zero means the entire match. % Otherwise, \var{nth} must be an integer with a value 1 through 9, % and refers to the set of characters matched by the \var{nth} regular % expression enclosed by the pairs \var{\(, \)}. %\notes % Calls \sfun{substr} on \var{str} using the (adapted) result of % \sfun{string_match_nth} as offsets. %\seealso{string_match, string_match_nth, string_get_match, str_re_replace} %!%- define string_nth_match(str, n) { variable pos, len; try { (pos, len) = string_match_nth(n); } catch RunTimeError: { return ""; } return substrbytes(str, pos+1, len); } %!%+ %\function{string_get_match} %\synopsis{Return a substring matching a regexp pattern} %\usage{String string_get_match(String str, String pattern, pos=1, nth=0)} %\description % Use string_match() to do a regexp matching on a string and return % the matching substring % % Performs the match starting at position \var{pos} (numbered from 1) % % By convention, \var{nth} equal to zero means the entire match. % Otherwise, \var{nth} must be an integer with a value 1 through 9, % and refers to the set of characters matched by the \var{nth} regular % expression enclosed by the pairs \var{\(, \)}. %\seealso{string_match, string_nth_match, str_re_replace, substr} %!%- define string_get_match() % (str, pattern, pos=1, nth=0) { variable str, pattern, pos, nth; (str, pattern, pos, nth) = push_defaults( , , 1, 0, _NARGS); if (string_match (str, pattern, pos)) return string_nth_match(str, nth); else return ""; } %!%+ %\function{str_re_replace} %\synopsis{Regexp replace max_n occurences of \var{pattern} with \var{rep}} %\usage{(String, Integer) str_re_replace(str, pattern, rep, max_n)} %\description % Regexp equivalent to \sfun{strreplace}. Replaces up to max_n occurences % of \var{pattern} with \var{rep}. % % Returns the string with replacements and the number of replacements done. %\notes % Currently, rep may contain 1 backref '\1' % TODO: allow up to 9 expansions %\seealso{str_re_replace_all, strreplace, string_get_match} %!%- define str_re_replace(str, pattern, rep, max_n) { variable n, pos = 1, next_pos, len, outstr=String_Type[1], match, backref, x_rep; % do replacements one-by-one, caching results in array for(n = 0; n < max_n; n++) { % add 100 elements to cache if it is full !if (n mod 100) outstr = [outstr, String_Type[100]]; % Match against regexp `pattern' starting at `pos' !if (string_match(str, pattern, pos)) break; % get the backref, i.e. the part matching pattern in \( \) backref = string_nth_match(str, 1); % expand replacement pattern (x_rep, ) = strreplace(rep, "\\1", backref, 1); % get position of next match (next_pos, len) = string_match_nth(0); next_pos++; % cache the string-part with replacement in an array outstr[n] = strcat(substrbytes(str, pos, next_pos - pos), x_rep); % advance position pos = next_pos + len; } outstr[n] = substrbytes(str, pos, -1); return (strjoin(outstr[[:n]], ""), n); } %!%+ %\function{str_re_replace_all} %\synopsis{Regexp replace all occurences of \var{pattern} with \var{rep}} %\usage{String str_re_replace_all(str, pattern, rep)} %\description % Regexp equivalent to \sfun{str_replace_all}. Replaces all occurences % of \var{pattern} with \var{rep} and returns the resulting string. % % Other than using \sfun{query_replace_match}, this function % will find and replace across line boundaries. %\notes % As the whole string is searched as one piece, \sfun{str_re_replace_all} % will become *very* slow for larger strings. If there is no need to find % matches across lines, \sfun{str_re_replace_by_line} should be used. %\seealso{str_re_replace, str_replace_all, str_re_replace_by_line} %!%- define str_re_replace_all(str, pattern, rep) { (str, ) = str_re_replace(str, pattern, rep, strlen(str)); return str; } %!%+ %\function{str_re_replace_by_line} %\synopsis{Regexp replace \var{pattern} with \var{rep}} %\usage{str_re_replace_by_line(str, pattern, rep)} %\description % Replace all occurences of the regular expression \var{pattern} with % \var{rep}. In contrast to \sfun{str_re_replace_all}, this function % will not find matches across lines (similar to a regexp replace in a % buffer). %\notes % This function splits \var{str} into an array of lines, calls % \sfun{str_re_replace_all} on them and joins the result. As result, it % takes 4 seconds to make 15000 replacements in a 10 MB string on a 2 GHz % cpu/1 GB ram computer (where str_re_replace_all took hours). %\seealso{str_re_replace, str_re_replace_all} %!%- public define str_re_replace_by_line(str, pattern, rep) { variable lines = strchop(str, '\n', 0); lines = array_map(String_Type, &str_re_replace_all, lines, pattern, rep); return strjoin(lines, "\n"); } %!%+ %\function{str_unicode_escape} %\synopsis{Convert escape sequence "\uHHHH" to the S-Lang syntax} %\usage{str_unicode_escape(str)} %\description % Many programs use the escape sequence "\uHHHH" for a Unicode character % with the hexadecimal number 0xHHHH. Therefore, some drag-and-drop of % text from another application might result in strings like % "the program\u2019s \u201cweb-like\u201d structure". % % The corresponding S-Lang syntax is "\x{HHHH}". This function returns % a string where all occurences of "\uHHHH" are converted to the S-Lang % equivalent. No conversion to unicode characters takes place unless the % result is interpreted as a string literal by S-Lang. %\seealso{str_re_replace_all} %!%- public define str_unicode_escape(str) { str = str_re_replace_all(str, "\\u\([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\)"R, "\x{\1}"R); return str; } %!%+ %\function{strcap} %\synopsis{Capitalize a string} %\usage{String strcap(String str)} %\description % Convert a string to a capitalized version (first character upper case, % other characters lower case) and return the result. %\seealso{strlow, strup, xform_region, capitalize_word, define_case} %!%- define strcap(str) { return strup(substr(str, 1, 1)) + strlow(substr(str, 2, strlen(str))); } %!%+ %\function{string_reverse} %\synopsis{Reverse the order of characters in a string} %\usage{String string_reverse(String s)} %\description % Reverse the order of characters in a string %\example %#v+ % string_reverse("abcd") == "dcba" %#v- %\seealso{array_reverse} %!%- define string_reverse(s) { variable i = strlen (s) - 1; if (i < 1) return s; __tmp(s)[[i:0:-1]]; } %!%+ %\function{string_repeat} %\synopsis{Repeat a string n times} %\usage{String string_repeat(String str, Integer n)} %\description % Concatenate \var{n} replicas of string \var{str} and return the result. %\example %#v+ % string_repeat("+-", 4) == "+-+-+-+-" %#v- %\notes % This is equivalent to str*n in Python %\seealso{array_repeat} %!%- define string_repeat(str, n) { variable strings = String_Type[n]; strings[*] = str; return strjoin(strings, ""); } %!%+ %\function{strwrap} %\synopsis{Split a string into chunks of maximal \var{wrap} chars} %\usage{Array strwrap(String str, wrap=WRAP, delim=' ', quote = 0)} %\description % Line wrapping for strings: Split a string into chunks of maximal % \var{wrap} chars, breaking at \var{delim} (if not quoted, cv. \sfun{strchop}). % Return array of strings. %\seealso{strbreak, strtok, WRAP} %!%- define strwrap() % (str, wrap=WRAP, delim=' ', quote = 0) { variable str, wrap, delim, quote; (str, wrap, delim, quote) = push_defaults( , WRAP, ' ', 0, _NARGS); variable word, words= strchop(strtrim(str, char(delim)), delim, quote), line, lines; !if (length(words)) return words; lines = words[[0]]; foreach word (words[[1:]]) { if ( strlen(lines[-1]) + strlen(word) < wrap) lines[-1] += char(delim) + word; else lines = array_append(lines, word); } return lines; } %!%+ %\function{strbreak} %\synopsis{} %\usage{(String, String) strbreak(String str, wrap=WRAP, delim=' ')} %\description % One-time string wrapping: Split a string at a breakpoint defined by delim, % so that the first part is no longer than \var{wrap} characters. % Return two strings. % % The delimiter is left at the end of the first return string. %\seealso{strwrap, WRAP} %!%- define strbreak() % (str, wrap=WRAP, delim=' ') { variable str, wrap, delim; (str, wrap, delim) = push_defaults( , WRAP, ' ', _NARGS); if (strlen(str) <= wrap) return (str, ""); variable breakpoints, i; % Get breakpoint breakpoints = where(bstring_to_array(str[[:wrap]]) == delim); % try within allowed range i = length(where(breakpoints <= wrap)) - 1; if (i<0) % no breakpoint in allowed range, take first possible breakpoint { breakpoints = where(bstring_to_array(str) == delim); i = 0; !if (length(breakpoints)) % no breakpoint at all return (str, ""); } return (str[[:breakpoints[i]]], str[[breakpoints[i]+1:]]); } %!%+ %\function{get_keystring} %\synopsis{Get the keystring of the next keypress event} %\usage{ get_keystring()} %\description % Wait for the next keypress and return all waiting input. % This is the opposite of buffer_keystring. %\example %#v+ % define showkey_literal() % { % flush ("Press key:"); % variable key = get_keystring(); % if (prefix_argument(0)) % insert (key); % else % { % #ifdef XWINDOWS % key += sprintf(" X-Keysym: %X", X_LAST_KEYSYM); % #endif % message ("Key sends " + key); % } % } %#v- %\notes % This may err for fast typing on slow terminals. %\seealso{getkey, ungetkey, input_pending, buffer_keystring} %!%- define get_keystring() { variable ch, key = ""; do { ch = char(getkey()); !if (strlen(ch)) % Null character \000 ch = "^@"; key = strcat(key, ch); } while (input_pending(0)); return key; } %!%+ %\function{strsplit} %\synopsis{Split a string in tokens.} %\usage{strsplit(str, sep, max_n=0)} %\description % Return a list of the words in the string \var{str}, using \var{sep} as the % delimiter string. %\seealso{strchop, strtok, strreplace, is_substr} %!%- define strsplit() % (str, sep, max_n=0) { variable str, sep, max_n; (str, sep, max_n) = push_defaults( , , 0, _NARGS); if (max_n == 0) max_n = strlen(str); variable sep_char; if (strlen(sep) == 1) sep_char = sep[0]; else { % find an unused character -> use it as delimiter sep_char = 0; while (is_substr(str, char(sep_char))) { sep_char++; if (sep_char > 255) error ("strsplit: did not find unique replacement for multichar sep"); } (str, ) = strreplace(str, sep, char(sep_char), max_n); } return strchop(str, sep_char, 0); % TODO % If \var{max_n} is given, at most \var{max_n} splits are % done. (Counting from the end, if \var{max_n} is negative.) %\example %#v+ % strsplit("1, 2, 3,5, 4 5. 6", ", ") == ["1", "2", "3,5", "4 5. 6"] % strsplit("1, 2, 3,5, 4 5. 6", ", ", 1) == ["1", "2, 3,5, 4 5. 6"] % strsplit("1, 2, 3,5, 4 5. 6", ", ", -1) == ["1, 2, 3,5", "4 5. 6"] %#v- } jedmodes-2.5.7/unittest/0000755000175400017500000000000011137570372013467 5ustar mildegmjedmodes-2.5.7/unittest/unittest.sl0000644000175400017500000004131111137570353015705 0ustar mildegm% unittest.sl: Framework for testing jed extensions % % Copyright (c) 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % This script needs SLang 2 % % Versions: % 0.1 2006-07-12 first experimental release % 0.2 2006-09-19 test_function() now saves the result in unittest->Last_Result % 0.3 2006-09-29 test discovery analogue to the python nose test framework % (http://somethingaboutorange.com/mrl/projects/nose/) and % py.test (http://codespeak.net/py/current/doc/test.html) % find and evaluate all functions matching % Unittest_Function_Pattern % 0.3.1 2006-10-05 added requirements % 0.4 2007-02-06 removed _lists_equal() and is_equal(), using _eqs() instead % 0.4.1 2007-07-25 added test_unequal(), as this gives better feedback than % test_true(a != b); % 0.5 2008-01-21 Unittest_Skip_Patterns replaced by Unittest_Skip_Pattern % (String instead of Array of Strings). % code cleanup, better reporting % 0.5.1 2008-01-22 test_files(): better testreport formatting % 0.5.2 2008-02-06 removed (direct) dependency on datutils % 0.5.3 2008-05-26 fixes: view_mode() autoload, _Jed_Emulation can be NULL % (report Jörg Sommer). % 0.6 2009-01-27 new optional argument "report" to test_files(), % test_files_and_exit() appends testreports separately, % expand Unittest_Reportfile to absolute path, % warn if a test changes the cwd. require("sl_utils"); % push_defaults, ... autoload("popup_buffer", "bufutils"); autoload("buffer_dirname", "bufutils"); autoload("sprint_variable", "sprint_var"); autoload("view_mode", "view"); provide("unittest"); implements("unittest"); % Customization % ------------- custom_variable("Unittest_Reportfile", "testreport.txt"); % expand now, so that changes of the cwd during the tests do not % lead to different expansions. Unittest_Reportfile = expand_filename(Unittest_Reportfile); % The regexp pattern for test-file detection % % Test or test as word in a file with ".sl" extension custom_variable("Unittest_File_Pattern", "\C\.*\.sl$"R); % The regexp pattern for test-function detection (Test_ or test_ as substring) custom_variable("Unittest_Function_Pattern", "\Ctest_"R); %!%+ %\variable{Unittest_Skip_Pattern} %\synopsis{Skip test based on regexp pattern.} %\usage{variable Unittest_Skip_Patterns = "interactive"} %\description % Tests matching this regexp pattern are skipped, even if they match the % \var{Unittest_Function_Pattern}. % % The default will skip tests that have the string "interactive" somewhere % in their name. %\seealso{test_buffer, test_file, test_files, test_files_and_exit} %!%- custom_variable("Unittest_Skip_Pattern", "interactive"); % Global variables (for internal use) % ----------------------------------- static variable reportbuf = "*test report*"; % number of errors in one file static variable Error_Count = 0; % list of return value(s) of the last function tested with test_function static variable Last_Result = {}; % plural 's' or not? usage: sprintf("%d noun%s", num, plurals(num!=1)); private variable plurals = ["", "s"]; %!%+ %\variable{AssertionError} %\synopsis{Exception class for failed assertions} %\usage{throw AssertionError, "message"} %\description % Exception class to mark the failure of an assertion. % Based on RunTimeError. % % Use this for critical assertions where it doesnot make sense to continue % evaluating the script or the test-function (because of follow-on errors). %\example % Make an assertion that \var{a} is true: %#v+ % !if (a) % throw AssertionError, "$a not TRUE"$; %#v- %\notes % One could be tempted to put the example code in an \sfun{assert} % definition. However, the error message would then give the function % definition as place where the error occured. Therefore it is better to % throw the AssertionError directly in the test script. % TODO: could the line of the assert() fun be extracted from the backtrace? %\seealso{test_equal, test_true, try, catch, new_exception, RunTimeError} %!%- !if (is_defined("AssertionError")) new_exception("AssertionError", RunTimeError, "Assertion failed"); % Auxiliary functions % ------------------- % Print a list to a string (simple version, see sprint_variable.sl for full) % (Also, this version doesnot add the {} around the elements) private define _sprint_list(lst) { variable element, str = ""; foreach element (lst) { if (NULL != wherefirst(typeof(element) == [String_Type, BString_Type])) str += ", " + make_printable_string(element); else str += ", " + string(element); } return str[[2:]]; } % _sprint_list({1,2,"3", NULL}); % _sprint_list({}); % _sprint_list({{8}}); public define sprint_error(err) { return sprintf("'%s' %s in %s() %s:%d ", err.descr, err.message, err.function, err.file, err.line); } % The test functions % ------------------ %!%+ %\function{testmessage} %\synopsis{Show a message string and log it in the "*test report*" buffer} %\usage{testmessage(fmt, ...)} %\description % Show a message (with \var{vmessage}) and insert a copy into a "*test % report*" buffer using \sfun{vinsert}. Return to the previous buffer. %\example % Report if a function is defined: %#v+ % !if (is_defined(fun)) % testmessage("%s E: not defined!\n", fun); %#v- %\notes % This test for existence is part of \sfun{test_function}. %\seealso{vmessage, vinsert, test_function} %!%- public define testmessage() % (fmt, ...) { variable buf = whatbuf(), args = __pop_list(_NARGS); sw2buf(reportbuf); set_readonly(0); eob; vinsert(__push_list(args)); set_buffer_modified_flag(0); % view_mode(); sw2buf(buf); args[0] = str_replace_all(args[0], "\n", " "); vmessage(__push_list(args)); } %!%+ %\function{test_true} %\synopsis{Test if \var{a} is true} %\usage{test_true(a, comment="")} %\description % Test if \var{a} is true, report if not. %\seealso{_eqs, test_equal} %!%- public define test_true() % (a, comment="") { variable a, comment; (a, comment) = push_defaults( , "", _NARGS); if (a) return; testmessage("\n E: '%S' is not true. %s", a, comment); Error_Count++; } %!%+ %\function{test_equal} %\synopsis{Test if \var{a} equals \var{b}} %\usage{ test_equal(a, b, comment="")} %\description % Test if \var{a} equals \var{b}, report if not. %\seealso{_eqs, test_unequal, test_true} %!%- public define test_equal() % (a, b, comment="") { variable a, b, comment; (a, b, comment) = push_defaults( , , "", _NARGS); !if (_eqs(a, b)) { testmessage("\n E: %s==%s failed. %s", sprint_variable(a), sprint_variable(b), comment); Error_Count++; } } %!%+ %\function{test_unequal} %\synopsis{Test if \var{a} differs from \var{b}} %\usage{ test_unequal(a, b, comment="")} %\description % Compare \var{a} and \var{b}, fail if they are equal. %\seealso{_eqs, test_equal, test_true} %!%- public define test_unequal() % (a, b, comment="") { variable a, b, comment; (a, b, comment) = push_defaults( , , "", _NARGS); if (_eqs(a, b)) { testmessage("\n E: %s!=%s failed. %s", sprint_variable(a), sprint_variable(b), comment); Error_Count++; } } % test the stack for leftovers public define test_stack() % (comment="") { variable comment = push_defaults("", _NARGS); variable leftovers = __pop_list(_stkdepth); if (length(leftovers) > 0) { testmessage("\n E: garbage on stack: %s, %s", _sprint_list(leftovers), comment); Error_Count++; } } % try a function and return exception or NULL % store list of return value(s) in Last_Result public define test_for_exception() % (fun, [args]) { variable args = __pop_list(_NARGS-1); variable fun = (); % convert string to function reference if (typeof(fun) == String_Type) fun = __get_reference(fun); % test-run the function variable err = NULL, stack_before = _stkdepth(); try (err) { if (fun == NULL) throw UndefinedNameError, "tested function not defined"; @fun(__push_list(args)); } catch AnyError: {} % store return value(s) Last_Result = __pop_list(_stkdepth()-stack_before); return err; } %!%+ %\function{test_function} %\synopsis{Test a SLang function} %\usage{Void test_function(fun, [args])} %\description % Test a function in a try-catch environment and report success. % % The return value(s) of the function is saved as a list in % \var{unittest->Last_Result} and reported in the report buffer. %\example %#v+ % test_function("eval", "3+4"); %#v- % reports %#v+ % eval(3+4): OK (7) %#v- % and sets \var{unittest->Last_Result} to {7}, while %#v+ % test_function("message", NULL); %#v+ % reports %#v+ % message(NULL): 'Type Mismatch' in /home/milde/.jed/lib/unittest.sl:-1, Unable to typecast Null_Type to String_Type %#v- % and sets \var{unittest->Last_Result} to {}. %\notes % If execution of the function throws an exeption, \var{unittest->Error_Count} % is increased by 1. %\seealso{run_function, testmessage, test_file, test_files} %!%- public define test_function() % (fun, [args]) { variable args = __pop_list(_NARGS-1); variable fun = (); variable err, error_count_before = Error_Count; % test-run the function testmessage("\n %S(%s): ", fun, _sprint_list(args)); err = test_for_exception(fun, __push_list(args)); if (err != NULL) { testmessage("E: %s", sprint_error(err)); Error_Count++; } % report return value(s) if (length(Last_Result)) testmessage(" => (%s)", str_replace_all(_sprint_list(Last_Result), "\n", "\\n")); if (Error_Count == error_count_before) testmessage(" OK"); } % Test if the return value of a tested function equals the expected % result (This is basically a list comparision of __pop_list(args) with % unittest->Last_Result and with special report settings) public define test_last_result() % args { variable expected_result = __pop_list(_NARGS); % silently pass if Last_Result meets expectations if (_eqs(Last_Result, expected_result)) return; testmessage("\n E: return value is not (%s) ", _sprint_list(expected_result)); Error_Count++; } %!%+ %\function{test_file} %\synopsis{Evaluate \var{file}, report exceptions, return their number} %\usage{test_file(file)} %\description % * Evaluate a test file its own namespace. % * Run the setup() function if it exists % * Test all static functions matching \var{Unittest_Function_Pattern}. % * Run the teardown() function if it exists % * Report exceptions in the "*test report*" buffer. % setup(), teardown(), and test functions must be defined as \var{static}. %\notes % If the last reported error is an exception, there might be % more hidden errors after it. %\seealso{test_files, test_function, test_stack, AssertionError} %!%- public define test_file(file) { variable err, testfuns, testfun, skips, skipped_tests, cwd=getcwd(); variable namespace = "_" + path_sans_extname(path_basename(file)); namespace = str_replace_all(namespace, "-", "_"); variable old_namespace = current_namespace(); if (old_namespace == "") old_namespace = "Global"; % Clean stack and input buffer test_stack(); while (input_pending(0)) testmessage("\n input pending: %c", getkey()); % Reset the error count with every compilation unit Error_Count = 0; % Evaluate the file/buffer in its own namespace ("_") testmessage("\n %s: ", path_basename(file)); try (err) () = evalfile(file, namespace); catch AnyError: { testmessage("\n E: %s ", sprint_error(err)); Error_Count++; if (err.error == OpenError) return; } test_stack(); call_function(namespace+"->mode_setup"); % Get names of test functions matching the test pattern testfuns = _apropos(namespace, Unittest_Function_Pattern, 2); testfuns = testfuns[array_sort(testfuns)]; skipped_tests = array_map(Int_Type, &string_match, testfuns, Unittest_Skip_Pattern, 1); skips = length(where(skipped_tests)); % show("testfuns", testfuns[where(not(skipped_tests))]); if (skips) testmessage("\n skipping: %s", strjoin(testfuns[where(skipped_tests)]+"()", " ")); % Run the testfuns in their namespace use_namespace(namespace); foreach testfun (testfuns[where(not(skipped_tests))]) { call_function(namespace+"->setup"); test_function(testfun); test_stack(); call_function(namespace+"->teardown"); } use_namespace(old_namespace); % Cleanup and sum up call_function(namespace+"->mode_teardown"); if (cwd != getcwd()) testmessage("\n Warning: current working dir changed to %s", getcwd()); if (Error_Count) testmessage("\n "); testmessage("\n %d error%s", Error_Count, plurals[Error_Count!=1] ); if (skips) testmessage(", %d test%s skipped (matching '%s')", skips, plurals[skips!=1], Unittest_Skip_Pattern); } % test the current buffer public define test_buffer() { save_buffer(); test_file(buffer_filename()); popup_buffer(reportbuf); view_mode(); % goto last error () = bsearch("E:"); } % forward declaration public define test_files(); %!%+ %\function{test_files} %\synopsis{Evaluate test-scripts in \var{dir}} %\usage{test_files(dir="", report=0)} %\description % * Evaluate directory-wide fixture script setup.sl if it exists % * Run \slfun{test_file} on all files in \var{dir} that match the given % basename pattern (globbing) or the regexp \var{Unittest_File_Pattern} % * Evaluate directory-wide fixture script teardown.sl if it exists %\notes % TODO: % globbing of dirname part. %\seealso{test_file, test_buffer, test_function, Unittest_File_Pattern} %!%- public define test_files() % (dir="", report=0) { variable path, report; (path, report) = push_defaults("", 0, _NARGS); variable dir = path_concat(buffer_dirname(), path_dirname(path)); variable pattern = path_basename(path); variable files = listdir(dir); variable setup_file = path_concat(dir, "setup.sl"); variable teardown_file = path_concat(dir, "teardown.sl"); variable file, match, no_of_errors = 0, no_of_files; variable time_struct = localtime(_time); variable buf = whatbuf(); % mark position in reportbuf sw2buf(reportbuf); push_mark(); sw2buf(buf); % insert time stamp testmessage("\n%d-%02d-%02d %02d:%02d ", time_struct.tm_year+1900, time_struct.tm_mon+1, time_struct.tm_mday, time_struct.tm_hour, time_struct.tm_min); % insert jed version and flavour variable utf8support = ["", " (utf8)"]; testmessage("Jed %s%s, S-Lang %s, Emulation '%S'", _jed_version_string, utf8support[_slang_utf8_ok], _slang_version_string, _Jed_Emulation); % separate and preprocess file list if (pattern == "") pattern = Unittest_File_Pattern; else pattern = glob_to_regexp(pattern); testmessage("\ntest_files in '%s' matching '%s': ", dir, pattern); if ((files == NULL) or (length(files) == 0)) { if (file_status(dir) != 2) { testmessage("\n E: directory '%s' doesnot exist ", dir); return 1; } testmessage("\n no matching files found in '%s' ", dir); return 0; } match = array_map(Int_Type, &string_match, files, pattern, 1); files = files[where (match)]; files = files[array_sort(files)]; files = array_map(String_Type, &path_concat, dir, files); no_of_files = length(files); variable plural = plurals[no_of_files!=1]; testmessage("testing %d file%s|dir%s ", no_of_files, plural, plural); update_sans_update_hook(1); % flush message if (1 == file_status(setup_file)) evalfile(setup_file); foreach file (files) { switch (file_status(file)) { case 1: test_file(file); no_of_errors += Error_Count; if (report) { popup_buffer(reportbuf); eob(); () = append_region_to_file(Unittest_Reportfile); push_mark(); } } { case 2: % directory: recurse no_of_errors += test_files(path_concat(file, "", report)); } } testmessage("\n%d file%s|dir%s, %d error%s\n", no_of_files, plural, plural, no_of_errors, plurals[no_of_errors!=1]); if (1 == file_status(teardown_file)) evalfile(teardown_file); popup_buffer(reportbuf); if (report) { eob(); () = append_region_to_file(Unittest_Reportfile); } else pop_mark(0); view_mode(); return no_of_errors; } public define test_files_and_exit() { variable args = __pop_list(_NARGS), no_of_errors; % test files writing report no_of_errors = test_files(__push_list(args), 1); exit(no_of_errors); } jedmodes-2.5.7/unittest/testscript-wizard.sl0000644000175400017500000001204010511221517017513 0ustar mildegm% testscript-wizard.sl: Generate a test script template for a sl mode % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % 0.3 2006-10-04 * adapted to unittest 0.3 (test function detection, fixtures) % 0.3.1 2006-10-05 * bugfixes, requirements require("strutils"); require("hyperhelp", "help.sl"); autoload("insert_template", "templates"); custom_variable("Unittest_Test_Directory", "~/.jed/lib/unit-tests"); % valid chars in function and variable definitions static variable Slang_word_chars = "A-Za-z0-9_"; private variable tmpbuf = make_tmp_buffer_name("*testscript-parse*"); % generate a testscript template for \var{file} public define testscript_wizard() % (file=buffer_filename()) { variable file = push_defaults(buffer_filename(), _NARGS); % try on jed-library path, if not found directly if (file_status(file) != 1) file = expand_jedlib_file(file); variable public_functions = {}, definitions = {}, definition, definition_line, tokens, fun, help_str, usage_str, namespace_name = ""; % Parse the file % -------------- sw2buf(tmpbuf); erase_buffer(); () = insert_file(file); set_buffer_modified_flag(0); define_blocal_var("Word_Chars", Slang_word_chars); % named namespace? bob(); if (orelse{bol_fsearch("implements")} {bol_fsearch("_implements")} {bol_fsearch("use_namespace")}) namespace_name = strtrim(strtok(line_as_string(), "( ")[1], "\");"); % does the mode contain explicitely public functions? bob(); while (bol_fsearch("public define "), right()) { list_append(public_functions, get_word()); % get_y_or_n("funs " + sprint_list(public_functions) + " continue?"); } % collect definitions of public accessible functions bob(); while (fsearch("define ")) { push_spot_bol(); if (looking_at("public") or looking_at("define") or (looking_at("static") and namespace_name != "") ) { eol(); push_mark(); while (up_1() and looking_at("% ")) ; list_append(definitions, bufsubstr(), -1); } pop_spot(); eol(); } delbuf(tmpbuf); % Set up the test script buffer % ----------------------------- () = find_file(expand_filename(path_concat(Unittest_Test_Directory, path_sans_extname(path_basename(file))+ "-test.sl"))); % if this is an empty file and templates are set up correctly, the standard % template for slang files will be used. % adapt the slang code template for test scripts bob(); eol(); insert(" Test " + path_basename(file)); eob(); insert("require(\"unittest\");\n\n"); if (length(public_functions)) insert("% test availability of public functions (comment to skip)\n"); foreach (public_functions) { fun = (); vinsert("test_true(is_defined(\"%s\"), \"public fun %s undefined\");\n", fun, fun); } % preface insert("\n% Fixture\n"); insert("% -------\n\n"); vinsert("require(\"%s\");\n\n", path_sans_extname(path_basename(file))); insert("private variable testbuf = \"*bar*\";\n"); insert("private variable teststring = \"a test line\";\n\n"); insert("static define setup()\n"); insert("{\n"); insert(" sw2buf(testbuf);\n"); insert(" insert(teststring);\n"); insert("}\n\n"); insert("static define teardown()\n"); insert("{\n"); insert(" sw2buf(testbuf);\n"); insert(" set_buffer_modified_flag(0);\n"); insert(" close_buffer(testbuf);\n"); insert("}\n\n"); if (namespace_name != "") insert("% private namespace: `" + namespace_name + "'\n\n"); % function test templates insert("% Test functions\n"); insert("% --------------\n\n"); foreach (definitions) { definition = (); % extract definition line definition = strtok(definition, "\n")[-1]; % extract function name tokens = strtok(definition, " \t("); try fun = tokens[wherefirst(tokens == "define")+1]; catch AnyError: continue; % documentation (online help or comments) if (tokens[0] == "static") fun = namespace_name + "->" + fun; help_str = help->help_for_object(fun); if (is_substr(help_str, "Undocumented")) help_str = definition + "\n"; usage_str = help->extract_usage(help_str); if (usage_str == "") usage_str = "$fun()"$; else usage_str = strtrim_end(usage_str, ";"); push_mark(); insert(help_str); comment_region(); % test function vinsert("static define test_%s()\n", strtok(fun, ">")[-1]); insert("{\n"); insert(" $usage_str;\n"$); insert("}\n\n"); } % trailer insert("sw2buf(\"*test report*\");\n"); insert("view_mode();\n"); bob(); fsearch("sw2buf"); } jedmodes-2.5.7/cdecl/0000755000175400017500000000000010461125567012663 5ustar mildegmjedmodes-2.5.7/cdecl/cdecl.sl0000664000175400017500000000325110215264655014277 0ustar mildegm% File: cdecl.sl -*- mode: SLang -*- % % $Id: cdecl.sl,v 1.3 2003/09/16 16:51:57 paul Exp paul $ % Keywords: c, tools % % Copyright (c) 2002, 2003 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This is a SLang translation of the `dcl' program from % the book `The C programming language' static variable name, out, datatype, word_chars = "0-9A-Za-z_"; static define dcl(); static define dirdcl(); static define dirdcl() { if (looking_at_char( '(')) % dcl { go_right_1; dcl; !if (looking_at_char( ')')) error("missing \)"); go_right_1; } else % name { push_mark; skip_chars(word_chars); name = bufsubstr; !if (strlen(name)) error ("expected name or dcl"); } forever { skip_white; if (looking_at_char( '(')) % function { !if (ffind_char( ')')) % skip the arguments error("missing \)"); out += " function returning"; } else if (looking_at_char('[')) % array { out += " array"; push_mark; !if (ffind_char( ']')) error("missing \]"); out += bufsubstr + "] of"; } else break; go_right_1; } } static define dcl() { variable ns = 0; skip_white; while (looking_at_char( '*')) % pointer { ns++; go_right_1; skip_white; } dirdcl; loop (ns) out += " pointer to"; } public define cdecl() { out = ""; push_spot_bol; skip_white; push_mark; skip_chars(word_chars); % datatype. I don't know 'const' etc datatype = " " + bufsubstr; dcl; pop_spot; message (name + ":" + out + datatype); } provide("cdecl"); jedmodes-2.5.7/home-lib/0000755000175400017500000000000010461125567013305 5ustar mildegmjedmodes-2.5.7/home-lib/home-lib.sl0000644000175400017500000001305710270210264015332 0ustar mildegm% Extended support for a user-specific directory with private extensions % % % Copyright (c) 2003 Gnter Milde and released under the terms % of the GNU General Public License (version 2 or later). % % Versions % 0.9 first public version % 0.9.1 Jed_Highlight_Cache_Path += Jed_Home_Library; % 0.9.2 cleanup of code and documentation + bugfix % custom_variable for Jed_Site_Library and Jed_Home_Library % 0.9.3 documentation bugfix: "%!%" -> "%!%-" % 0.9.4 outsourcing of the registration -> register_library(dir) % added custom_variable Jed_Debian_Library = "" % 0.9.5 removed the adding of Jed_Home_Directory/doc/txt/libfuns.txt % to Jed_Doc_Files % removed Jed_Debian_Library and introduced Jed_Local_Library % (thanks to Dino Sangoi for a Windows default). % 0.9.5 renamed register_library() to register_libdir() % 2005-07-11 % 1.0 make the script less "aggresive", so it can be evaluated without % side-effects. % * !! new way of invocation, see INITIALIZATION !! % * no automatic change of Jed_Home_Directory (do this in % the configuration file instead) % * do not change Default_Jedrc_Startup_File % * prepend (instead of append) /colors to Color_Scheme_Path % (report J. Sommer) % UNIX home-lib default without trailing "/" % 1.1 2005-07-22 further code cleanup % shedding of the *_Library custom variables, added % Jed_Local_Directory instead (in line with Jed_Home_Directory) % % FEATURES % % the function register_libdir(path): % % * prepends path to the jed-library-path (searched for modes) % * sets Color_Scheme_, dfa-cache- and documentation- path % * evaluates (if existent) the file ini.sl in path % (ini.sl files can be autocreated by make_ini.sl) % % Together with make-ini.sl, this provides a convenient way of extending % jed with contributed or home-made scripts. % % INITIALIZATION % % Write in your .jedrc (or jed.rc on winDOS) e.g. % require("home-lib", "/FULL_PATH_TO/home-lib.sl"); % register_libdir(path_concat(Jed_Local_Directory, "lib")); % register_libdir(path_concat(Jed_Home_Directory, "lib")); % Jed_Home_Directory % ------------------ % % Jed_Home_Directory is defined in site.sl, defaulting to $HOME % previous versions contained code to change this to ~/.jed/ % % With the code below in jed.conf (or defaults.sl), Jed looks for .jedrc % in "~/.jed/". % % % If Jed_Home_Directory/.jed/ exists, point Jed_Home_Directory there, % $1 = path_concat(Jed_Home_Directory, ".jed"); % if(2 == file_status($1)) % Jed_Home_Directory = $1; % % Alternatively, place .jedrc in HOME and set there % Jed_Home_Directory = path_concat(Jed_Home_Directory, ".jed"); %!%+ %\variable{Jed_Local_Directory} %\synopsis{Directory for local site-wide jed extensions} %\description %\description % The value of this variable specifies the systems local "jed directory" % where system-wide non-standard jed-related files are assumed to be found. % Normally, this corresponds to "/usr/local/share/jed" on UNIX and % "$ALLUSERSPROFILE\\$APPDATA\\Jedsoft\\JED" on Windows % unless an alternate directory is specified via the \var{JED_LOCAL} % environment variable. % % As it is a custom_variable, it can be set/changed in defaults.sl, jed.conf, % and/or .jedrc, of course. % % It is set to "" if the specified directory does not exist. %\seealso{JED_ROOT, Jed_Home_Directory} %!%- custom_variable("Jed_Local_Directory", getenv("JED_LOCAL")); if (Jed_Local_Directory == NULL) % no custom or environment var set { #ifdef IBMPC_SYSTEM $2 = getenv("ALLUSERSPROFILE"); $3 = getenv("APPDATA"); if ($2 == NULL or $3 == NULL) Jed_Local_Directory = ""; else Jed_Local_Directory = path_concat(path_concat($2, path_basename($3)), "Jedsoft\\JED"); #else Jed_Local_Directory = "/usr/local/share/jed"; #endif } if (file_status(Jed_Local_Directory) != 2) % no directory Jed_Local_Directory = ""; %!%+ %\function{register_libdir} %\synopsis{Register a library dir for use by jed} %\usage{register_libdir(path)} %\description % * Prepend \var{path} to the library path % * Set \var{Color_Scheme_Path}, \var{Jed_Doc_Files}, % \var{Jed_Highlight_Cache_Dir}, and \var{Jed_Highlight_Cache_Path} % * Evaluate (if existent) the file \var{ini.sl} in this library % to enable initialization (autoloads etc) %\example %#v+ % register_libdir(path_concat(Jed_Local_Directory, "lib")); % register_libdir(path_concat(Jed_Home_Directory, "lib")); %#v- % will register the local and user-specific library-dir %\seealso{make_ini, set_jed_library_path, Color_Scheme_Path, Jed_Doc_Files} %\seealso{Jed_Highlight_Cache_Dir, Jed_Highlight_Cache_Path} %!%- define register_libdir(lib) { % abort, if directory doesnot exist if (orelse{lib == ""}{2 != file_status(lib)}) continue; variable path; % jed library path set_jed_library_path(lib + "," + get_jed_library_path()); % colors path = path_concat(lib, "colors"); if (2 == file_status(path)) Color_Scheme_Path = path + "," + Color_Scheme_Path; % documentation path = path_concat(lib, "libfuns.txt"); if (1 == file_status(path)) Jed_Doc_Files = path + "," + Jed_Doc_Files; % dfa cache #ifdef HAS_DFA_SYNTAX Jed_Highlight_Cache_Dir = lib; Jed_Highlight_Cache_Path = lib + "," + Jed_Highlight_Cache_Path; #endif % Check for a file ini.sl containing initialization code % (e.g. autoload declarations) and evaluate it. path = path_concat(lib, "ini.sl"); if (1 == file_status(path)) () = evalfile(path); } jedmodes-2.5.7/cua/0000755000175400017500000000000011507713047012357 5ustar mildegmjedmodes-2.5.7/cua/cua.hlp0000664000175400017500000000060110214064406013623 0ustar mildegmBasic Commands in CUA mode: File: Region: Search/Replace: Edit: Emergency: ^Q exit ^C copy ^FF find forward ^A mark all ^H/F1 help ^O open ^X kill ^L/F3 find next ^B format paragraph ^Z undo ^S/F2 save ^V paste ^FE regexp search ^K kill line ^D abort ^P print ^FR replace ^J goto line jedmodes-2.5.7/cua/cua.sl0000644000175400017500000002172011507713047013471 0ustar mildegm%% CUA (Windows/Mac/CDE/KDE-like) bindings for Jed. %% %% Copyright © 2001 Reuben Thomas, 2003 Günter Milde (milde users.sf.net) %% Released under the terms of the GNU General Public License (ver. 2 or later) %% %% Versions: %% 1 first version by GM %% 1.1 2003-05 triple (optional single) ESC-keypress aborts functions %% fixed missing definition of Key_Ins %% Key_Ctrl_Del calls cua_delete_word (was delete_word) %% F3 bound to repeat_search (tip by Guido Gonzato) %% removed definitions for F4...F10 %% ^Q exits without asking for confirmation %% 1.2 07-2003 better support for older jed versions with %% if (_jed_version >= 9916) around new functions %% 1.3 2004-01-23 Key_Del and Key_BS "region aware" (needs cuamisc >= 1.3) %% 1.4 2005-05-26 Merge with the version of jed 0.99-17 %% 1.4.1 bugfix: check for XWINDOWS before loading cuamouse.sl %% 1.5 2005-06-07 load backwards compatibility code from compat17-16.sl %% and compat16-15.sl (if needed) %% 1.5.1 2005-11-02 bugfix: bind ESC to "back_menu" in menu map %% 1.5.2 2006-01-17 more adaptions to the version of jed 0.99-17 %% 1.6 2006-06-16 remove the (optional) File>Print menu entry, so that %% the user can decide whether to use apsmode.sl (with its %% Print menu popup or print.sl) %% 1.6.1 2007-09-03 bind eol() instead of eol_cmd() to Key_End, as eol_cmd %% deletes trailing white which confuses moving and editing %% and might not be desired. %% 1.6.2 2007-10-18 optional extensions with #if ( ) %% 1.6.3 2007-10-23 use cua_replace_cmd() (needs cuamisc.sl >= 1.6.3) %% 1.6.4 2011-01-01 Fix assignment of forward/backward_paragraph(). %% %% %% USAGE: %% %% put somewhere in your path and uncomment the line %% % () = evalfile ("cua"); % CUA-like key bindings %% in your .jedrc/jed.rc file %% %% ESC-Key: unfortunately, some function keys return "\e\e" %% as keystring. To have a single ESC-press aborting, add in jed.rc %% either %% %% #ifdef XWINDOWS %% x_set_keysym(0xFF1B, 0, Key_Esc); % one-press-escape %% #endif %% %% to get the one-press escape for xjed, or the experimental %% %% cua_one_press_escape(); %% %% **Attention**, except for xjed, this is an experimental %% feature that can cause problems with functions that use getkey(), %% (e.g. isearch(), showkey(), wmark.sl (before jed 99.16), ...) %% %% Enhancements (optional helper modes from http://jedmodes.sf.net/): %% x-keydefs.sl: even more symbolic constants for function and arrow keys %% cuamouse.sl: cua-like mouse bindings %% cuamark.sl: cua-like marking/copy/paste using yp_yank.sl (a ring of %% kill-buffers) %% numbuf.sl: fast switch between buffers via ALT + Number %% ch_table.sl: popup_buffer with character table (special chars) % --- Requirements ------------------------------------------------------ % S-Lang >= 2.0 % backwards compatibility code (for older Jed versions) if (_jed_version < 9915) require("compat16-15"); if (_jed_version < 9916) require("compat17-16"); require("cuamisc"); % >= 1.6.3 "Outsourced" helper functions require("keydefs"); % symbolic constants for many function and arrow keys #if (expand_jedlib_file("cuamark.sl") != "") require("cuamark"); % mark regions with Shift-Arrow #else require("wmark"); % cua-like marking, standard version #endif require("recent"); % save a list of recent files % Announce % -------- provide("cua"); _Jed_Emulation = "cua"; % --- Variables -------------------------------------------------------- set_status_line(" %b mode: %m %n (%p) %t ", 1); menu_set_menu_bar_prefix ("Global", " "); Help_File = "cua.hlp"; %--- Keybindings -------------------------------------------------------- % This key will be used by the extension modes (e.g. c_mode.sl) to bind % additional functions to _Reserved_Key_Prefix = "^E"; % Extended functionality :-) % ESC key % unfortunately, some keys return strings starting with "\e\e", % see USAGE above for workaround variable Key_Esc = "\e\e\e"; setkey ("cua_escape_cmd", Key_Esc); % Triple-Esc -> abort definekey("back_menu", Key_Esc, "menu"); % close (sub-)menus % Function keys setkey("menu_select_menu(\"Global.&Help\")", Key_F1); if (is_defined("context_help")) % from jedmodes.sf.net/mode/hyperhelp/ setkey("context_help", Key_Shift_F1); setkey("cua_save_buffer", Key_F2); setkey("save_buffer_as", Key_Shift_F2); setkey("cua_repeat_search", Key_F3); % setkey("menu_select_menu(\"Global.&Search\")", Key_F3); % open Search menu % The "named" keys setkey("cua_bdelete_char", Key_BS); setkey("cua_delete_char", Key_Del); setkey("toggle_overwrite", Key_Ins); setkey("beg_of_line", Key_Home); setkey("eol", Key_End); setkey("page_up", Key_PgUp); setkey("page_down", Key_PgDn); setkey("cua_bdelete_word", Key_Ctrl_BS); setkey("cua_delete_word", Key_Ctrl_Del); setkey("beg_of_buffer", Key_Ctrl_Home); setkey("eob; recenter(window_info('r'));", Key_Ctrl_End); setkey("bskip_word", Key_Ctrl_Left); setkey("skip_word", Key_Ctrl_Right); setkey("backward_paragraph", Key_Ctrl_Up); setkey("forward_paragraph", Key_Ctrl_Down); %setkey("pop_mark(0)", Key_Ctrl_Up); %setkey("push_mark", Key_Ctrl_Down); % define region % The Control Chars unset_ctrl_keys(); % unset to get a clear start #ifdef UNIX enable_flow_control(0); %turns off ^S/^Q processing (Unix only) #endif setkey("mark_buffer", "^A"); % mark All %setkey("dabbrev", "^A"); % abbreviation expansion %setkey("format_paragraph", "^B"); % (ide default) setkey("smart_set_mark_cmd", "^B"); % Begin region setkey("yp_copy_region_as_kill","^C"); % Copy (cua default) set_abort_char(''); % "logout" % ^E == _Reserved_Key_Prefix Extra functionality % ^F map: Find setkey("search_backward", "^FB"); setkey("isearch_backward", "^F^B"); setkey("toggle_case_search", "^FC"); setkey("re_search_forward", "^FE"); % rEgexp search setkey("search_forward", "^FF"); setkey("isearch_forward", "^F^F"); setkey("re_search_backward", "^FG"); setkey("isearch_forward", "^FI"); % Incremental search setkey("occur", "^FO"); % find all Occurences setkey("query_replace_match", "^FP"); % regexp rePlace setkey("cua_replace_cmd", "^FR"); setkey("goto_line_cmd", "^G"); % Goto line % set_abort_char(''); % Jed Default, now on ^D % ^H map: Help ... setkey("apropos", "^HA"); setkey("describe_function", "^HF"); setkey("help", "^HH"); setkey("info_mode", "^HI"); setkey("showkey", "^HK"); setkey("describe_mode", "^HM"); setkey ("unix_man", "^HU"); setkey("describe_variable", "^HV"); setkey("where_is", "^HW"); setkey("menu_select_menu(\"Global.&Help\")", "^H?"); setkey("indent_line", "^I"); % Key_Tab % setkey("self_insert_cmd", "^I"); % setkey("", "^J"); % Free! setkey("del_eol", "^K"); % Kill line setkey("cua_repeat_search", "^L"); % ^M = Key_Enter setkey("next_buffer", "^N"); % Next buffer setkey("find_file", "^O"); % Open file (cua default) %setkey ("print_buffer", "^P"); % Print (with print.sl) %setkey("exit_with_query", "^Q"); % Quit (ask for confirmation) setkey("exit_jed", "^Q"); % Quit (without asking) % ^R: Rectangles setkey("copy_rect", "^RC"); setkey("insert_rect", "^RV"); setkey("kill_rect", "^RX"); % delete and copy to rect-buffer setkey("open_rect", "^R "); % ^R Space: insert whitespace setkey("blank_rect", "^RY"); % delete (replace with spaces) setkey("blank_rect", "^R" + Key_Del); setkey("cua_save_buffer", "^S"); % Save % ^T % still free setkey("yp_yank", "^V"); % insert/paste setkey("delbuf(whatbuf)", "^W"); setkey("yp_kill_region", "^X"); % cut setkey("redo", "^Y"); setkey("undo", "^Z"); runhooks("keybindings_hook", "cua"); % user modifications % --- menu additions -------------------------------------------------- private define cua_load_popup_hook (menubar) { menu_delete_item ("Global.&File.&Close"); menu_insert_item("&Save", "Global.&File", "&Close Buffer", "delbuf(whatbuf)"); menu_insert_item (2, "Global.&Search", "Repeat &Search", "cua_repeat_search"); menu_insert_item (3, "Global.&Search", "&Incremental Search Forward", "isearch_forward"); menu_insert_item (4, "Global.&Search", "I&ncremental Search Backward", "isearch_backward"); menu_insert_item ("&Replace", "Global.&Search", "Toggle &Case Search", "toggle_case_search"); } append_to_hook ("load_popup_hooks", &cua_load_popup_hook); jedmodes-2.5.7/sl_utils/0000755000175400017500000000000010741700074013440 5ustar mildegmjedmodes-2.5.7/sl_utils/sl_utils.sl0000644000175400017500000002721710741700074015647 0ustar mildegm% Various programming utils that are used by most of my other modes. % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 1.0 first public release % 1.1 new: max(), contract_filename() % 1.2 new: normalize_modename(), what_line_if_wide() % 1.3 backwards compatibility: emulate run_program() if not % existent (works only in xjed) % 2004-03-22 1.3.1 bugfix in contract_filename() error if HOME % environment variable is missing (report Thomas Koeckritz) % 1.3.2 removed max(), as it contradicts the intrinsic max() % definition (which resembles array_max() from datutils.sl) % 2005-04-11 1.4 new function prompt_for_argument() % added provide("sl_utils") % 1.5 new function _implements(): implement a "named" namespace % but allow re-evaluation if `_debug_info` is TRUE % 2005-05-23 1.5.1 bugfix in _implements(): separate _implement and provide, % do not rely on _featurep() % 2005-06-07 1.5.2 moved run_program emulation to compat16-15.sl % 2005-10-05 1.5.3 Simplified _implements(). Developers working with SLang2 % should switch to using the standard implements(). % (Normal users will will usually not re-evaluate.) % 1.5.4 Documentation update for run_function mentioning call_function % 1.5.5 Documentation fix for push_defaults() % 2008-01-11 1.5.6 Documentation update for run_function() and get_blocal() % _debug_info = 1; provide("sl_utils"); %!%+ %\function{push_defaults} %\synopsis{Push N args to the stack} %\usage{(a_1, ..., a_N) = push_defaults(d_1, ..., d_N, N)} %\description % Push N args to the stack. Together with \var{_NARGS} this enables the % definition of slang functions with optional arguments. %\example % A function with one compulsory and two optional arguments %#v+ % define fun() % (a1, a2="d2", a3=whatbuf()) % { % variable a1, a2, a3; % (a1, a2, a3) = push_defaults( , "d2", whatbuf(), _NARGS-1); % vmessage("(%S, %S, %S)", a1, a2, a3); % } %#v- % results in: % fun(1) % --> (1, d2, *scratch*) % fun(1, 2) % --> (1, 2, *scratch*) % fun(1, 2, 3) % --> (1, 2, 3) % but % fun() % --> !!compulsory arg missing!! % fun(1, , ) % --> (1, NULL, NULL) !!empty args replaced with NULL!! %\notes % Never forget the _NARGS argument to \sfun{push_defaults}! % % Mixed compulsory-optional arguments can be defined somewhat simpler, if % the compulsory argument comes last: %#v+ % define fun2(a2) % (a1="d1", a2) % { % variable a1 = push_defaults("d1", _NARGS-1); % vmessage("(%S, %S)", a1, a2); % } %#v- % (To the author, the compulsory-first ordering appears more "natural", % though. Maybe this is due to the Python experience where compulsory % arguments need to precede optional ones.) % % The arguments to push_defaults will always be evaluated. If time is an issue, % use a placeholder (e.g. NULL) or a construct like %#v+ % define fun() % (a=time_consuming_fun()) % { % !if (_NARGS) % time_consuming_fun(); % variable a = (); % ... % } %#v- %\seealso{__push_args, __pop_args, _NARGS } %!%- define push_defaults() % args, n { variable n = (); variable args = __pop_args(_NARGS-1); __push_args(args[[n:]]); } %!%+ %\function{prompt_for_argument} %\synopsis{Prompt for an optional argument if it is not given.} %\usage{Str prompt_for_argument(Ref prompt_function, [args], Int use_stack)} %\description % This function facilitates the definition of function with optional % arguments. % % The first argument is a prompt function (e.g. \sfun{read_mini} or % \sfun{read_with_completion}, followed by its arguments and the % \var{use_stack} argument. % % If \var{use_stack} is non-zero, this function simply returns and % the calling code picks up the top element from stack. % Otherwise, \var{prompt_function} is called with the given arguments % (except when the minibuffer is already active, in which case an error % is risen). %\example %#v+ % define prompt_for_message() % ([str]) % { % variable str = prompt_for_argument(&read_mini, % "Message:", "", "", _NARGS); % message(str); % } %#v- %\seealso{push_defaults, _NARGS, read_mini, read_with_completion} %!%- define prompt_for_argument() % (fun, [args], use_stack) { variable use_stack = (); variable args = __pop_args(_NARGS-2); variable fun = (); if (use_stack) return (); % argument is already on stack else { if (MINIBUFFER_ACTIVE) % cannot use minibuffer for prompting error("missing argument"); return @fun(__push_args(args)); } } %!%+ %\function{push_array} %\synopsis{Push an ordinary array on stack} %\usage{(a[0], ..., a[-1]) push_array(Array a)} %\description % Push the elements of an array to the stack. This works like % __push_args(args) but with an ordinary array (all types) %\example %#v+ % variable a = ["message", "hello world"]; % runhooks(push_array(a)); %#v- %\notes % Elements of an Any_Type-array are references. They are dereferenced % in order to get type-independend behaviour. %\seealso{array, pop2array, __push_args, __pop_args} %!%- define push_array(a) { if (_typeof(a) == Any_Type) foreach (a) if (dup == NULL) (); else @(); else foreach (a) (); } %!%+ %\function{get_blocal} %\synopsis{Return value of blocal variable or default} %\usage{Any get_blocal(String name, [Any default=NULL])} %\description % Deprecated: use the standard function \var{get_blocal_var} with a second % argument. % % This function is similar to get_blocal_var, but if the local variable % "name" doesnot exist, it returns NULL or the default value instead % of an error. %\example % Since some time (which Jed version??), \var{get_blocal_var} also takes an % optional default value: %#v+ % !if (get_blocal_var(foo), 0) % message("this buffer lacks foo"); %#v- % prints the message if the blocal variable "foo" is zero or does not exist. %\note % There is no "default default" in \var{get_blocal_var}. Instead, it will % throw an error, if there is no blocal_variable with \var{name} and no % \var{default} argument is specified. %\seealso{get_blocal_var, blocal_var_exists, set_blocal_var, define_blocal_var} %!%- define get_blocal() % (name, default=NULL) { variable name, default; (name, default) = push_defaults( , NULL, _NARGS); if (blocal_var_exists(name)) return get_blocal_var(name); return default; } %!%+ %\function{run_function} %\synopsis{Run a function if it exists, return if fun is found.} %\usage{Int_Type run_function(fun, [args])} %\description % Run a function (if it exists) pushing \var{args} as argument list. % In contrast to \sfun{call_function}, there is a return value % (pushed on the stack after the function call): % % 1 the function was found (is_defined or internal) % 0 the function was not found % % The \var{fun} can be a function name or reference (this allows both: % yet undefined functions (as string) as well as private or static functions % (as reference). %\example %#v+ % % if (run_function("foo")) % message("\"foo\" successfull called"); % % !if (run_function(&foo)) % message("\"foo\" is not defined"); %#v- % The return value can be used to decide whether to take up a return value: %#v+ % % if (run_function("filter", str)) % str = (); %#v- %\notes % If fun is (solely) an internal function, the optional arguments will be % silently popped. If there are both, an internal and an intrinsic or library % variant of a function, the non-internal takes precedence. Use \sfun{call} to % explicitely call an internal function. %\seealso{call_function, runhooks, run_local_hook, call} %!%- define run_function() % (fun, [args]) { variable args = __pop_args(_NARGS-1); variable fun = (); if (typeof(fun) == String_Type) { if (is_defined(fun) > 0) fun = __get_reference(fun); else if (is_internal(fun)) { call(fun); return 1; } } if (typeof(fun) == Ref_Type) { @fun(__push_args(args)); return 1; } return 0; } %!%+ %\function{contract_filename} %\synopsis{Make a filename as short as possible without ambiguity} %\usage{contract_filename(file, cwd=getcwd())} %\description % The opposite of \sfun{expand_filename} (in some case of view) % Make a filename as short as possible without loss of information. % % * If the path starts with \var{cwd}, strip it. % (This maight fail on case insensitive filesystems). % * If the path starts with the home-dir, replace it with "~". %\notes % \sfun{expand_filname} will restore the original value. %\seealso{expand_filename} %!%- define contract_filename() % (file, cwd=getcwd()) { variable file, cwd; (file, cwd) = push_defaults( , getcwd(), _NARGS); variable home = getenv("HOME"); % strip leading cwd cwd = path_concat(cwd, ""); % ensure that cwd has a trailing dirsep if (is_substr(file, cwd) == 1) file = file[[strlen(cwd):]]; % or replace HOME with ~ else if (andelse{home != NULL}{strlen(home)}) { home = path_concat(home, ""); % ensure home has a trailing dirsep if (is_substr(file, home) == 1) file = path_concat("~", file[[strlen(home):]]); } return file; } % when a buffer is folded what_line may give the false number define what_line_if_wide () { if (count_narrows ()) { push_narrow (); widen_buffer (); what_line (); pop_narrow (); } else what_line (); } %!%+ %\function{_implements} %\synopsis{Create or reuse a new static namespace} %\usage{_implements(Str name)} %\description % The \sfun{_implements} function creates a new static namespace % and associates it with the current compilation unit. % % If a namespace with the specified name already exists, the the current % static namespace is changed to \var{name} with \sfun{use_namespace}. % % This alows re-evaluation of files in debugging|development mode. % %\notes % Since SLang 2 the standard implements() (re)uses a namespace if it was % defined in the same file. If defined in another file, it still throws a % namespace error. %\example % To allow easy re-evaluation of a mode during development, write %#v+ % autoload("_implements", "sl_utils"); % % other autoloads that should bind to the "Global" namespace % _implements("foo"); % % autoloads, require, and function and variable definitions now go to the % % namespace "foo" %#v- %\seealso{implements, use_namespace} %!%- define _implements(name) { if (length(where(name == _get_namespaces()))) use_namespace(name); else implements(name); } %!%+ %\function{autoloads} %\synopsis{Load functions from a file} %\usage{autoloads(String funct, [String funct2 , ...], String file)} %\description % The `autoloads' function is used to declare a variable number of % functions `funct' to the interpreter and indicate that they should be % loaded from `file' when actually used. % It does so by calling autoload(funct, file) for all \var{funct} arguments. %\notes % A future version of \sfun{autload} might provide for mulitple funct % arguments and render \sfun{autoloads} obsolete. % % _autoload(funct, file, funct2, file, ..., functN, file, N) is faster, % (albeit less convenient to write and needing an explicit number argument). % Use this for time-critical cases. %\seealso{_autoload, autoload, require, evalfile} %!%- define autoloads(file) % (funct, [funct2 , ...], file) { loop(_NARGS - 1) autoload((), file); } jedmodes-2.5.7/folding-keypad-bindings/0000755000175400017500000000000011137340345016273 5ustar mildegmjedmodes-2.5.7/folding-keypad-bindings/folding-keypad-bindings.sl0000644000175400017500000001302611137340345023325 0ustar mildegm% folding-keypad-bindings.sl: Numpad Keybindings for Folding Mode % =============================================================== % % Copyright © 2007 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % ======== % 0.1 2008-03-10 First evaluation version. Keybindings and behaviour are % subject to change after "road testing". % 0.1.1 2009-01-26 Fix syntax error in test code % % Usage % ===== % Place in the jed library path. % % Set the keybindings in a hook, e.g. in jed.rc: % % | autoload("folding_keypad_bindings", "folding-keypad-bindings"); % | define fold_mode_hook(mode) % | { % | folding_keypad_bindings(); % | } % % Bindings % ======== % % All key-bindings are on the numeric keypad (Key_KP_*). % % Motion Commands % --------------- % :2/Down: Move down to the next visible fold heading. % :8/Up: moves similarly backward. % :4/Left: Move up to the fold heading of the containing fold. % (not implemented yet). % :6/Right: Move down to the next (maybe ivisible) fold heading and unhide it. % % Outline Visibility Commands % --------------------------- % Global commands % """"""""""""""" % folding the whole buffer. % With a numeric argument n, they hide everything except the % top n levels of heading lines. % % local_setkey("fold_whole_buffer", Key_KP_Delete); % hide-body % local_setkey("fold_open_buffer", Key_KP_0); % show-all % % % :,/Del: Fold whole buffer. % :0/Ins: Unfold buffer (make all lines visible). % % Subtree commands % """""""""""""""" % Not implemented yet. % % :+: increase, and % :-: decrease the "verbosity" (level of headings shown). % % Local commands % """""""""""""" % % Apply only to the body lines of that heading. % Sub-folds are not affected. % % :5: Hide or show body under this heading (fold_toggle_fold). % :Enter: Open fold and narrow the buffer to it. (fold_enter_fold). % % % Requirements % ------------ % :: _autoload("fold_whole_buffer", "folding", "fold_open_buffer", "folding", "fold_close_fold", "folding", "fold_open_fold", "folding", "fold_search_backward", "folding", "fold_search_forward", "folding", "fold_get_marks", "folding", 7); % Auxiliary functions % ------------------- % :: % variable Test; # ifexists Test autoload("pcre_fsearch", "filter_buffer"); % get (or guess) the current fold-level private define get_fold_level() { variable fold_start, fold_end; (fold_start, fold_end, , ) = fold_get_marks(); variable max_level=1, level=1; push_spot_bob(); while (pcre_fsearch(sprintf("(%s|%s)", fold_start, fold_end))) { if (is_line_hidden()) continue; go_down_1(); if (is_line_hidden()) { skip_hidden_lines_forward(1); continue; } if (ffind(fold_start)) level++; else max_level = nint(_max(max_level, level)); level--; } pop_spot(); % show(nint(_max(max_level, level))); return nint(_max(max_level, level)); } % Change the fold-leve of the current buffer by `incr' define fold_increment_level(incr) { variable level = get_fold_level() + incr; set_prefix_argument(level); fold_whole_buffer(); vmessage("fold-level %d", level); } #endif % close fold if open, open fold if closed define fold_toggle_fold() { !if (down_1()) return; variable is_hidden = is_line_hidden(); go_up_1(); if (is_hidden) fold_open_fold(); else fold_close_fold(); } % find next fold marker, return success private define fold_fsearch_start() { % TODO: regexp search for "fold_start ... end_of_start" variable fold_start, end_of_start; (fold_start, , end_of_start, ) = fold_get_marks(); eol(); return fsearch(fold_start); } % find previous fold marker, return success private define fold_bsearch_start() { % TODO: regexp search for "fold_start ... end_of_start" variable fold_start, end_of_start; (fold_start, , end_of_start, ) = fold_get_marks(); return bsearch(fold_start); } % goto next fold-mark starte and make it visible define fold_next_fold() { !if (fold_fsearch_start()) eob(); set_line_hidden(0); } % goto next visible fold-start marker define fold_next_visible_fold() { while (fold_fsearch_start()) { !if (is_line_hidden()) return; } % message("Last fold"); eob(); } % goto previous visible fold marker define fold_previous_visible_fold() { while (fold_bsearch_start) !if (is_line_hidden()) return; % message("First fold"); bob(); } % Bind Keypad Keys % ---------------- % :: define folding_keypad_bindings() { % Motion Commands local_setkey("fold_next_visible_fold", Key_KP_2); % Down local_setkey("fold_previous_visible_fold", Key_KP_8); % Up % local_setkey("fold_up_fold", Key_KP_4); % Left local_setkey("fold_next_fold", Key_KP_6); % % Outline Visibility Commands % global local_setkey("fold_whole_buffer", Key_KP_Delete); % hide-body local_setkey("fold_open_buffer", Key_KP_0); % show-all % subtree % local_setkey("fold_increment_level(-1)", Key_KP_Subtract); % decrease level % local_setkey("fold_increment_level(1)", Key_KP_Add); % increase level % local local_setkey("fold_toggle_fold", Key_KP_5); % hide-entry|show-entry local_setkey("fold_enter_fold", Key_KP_Enter); % local_setkey("", Key_KP_6); % > } jedmodes-2.5.7/grep/0000755000175400017500000000000010732450370012540 5ustar mildegmjedmodes-2.5.7/grep/grep.sl0000644000175400017500000003130510732450370014037 0ustar mildegm% JED interface to the grep command % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % -------- % % 0.9.1 2003/01/15 % * A remake of Dino Sangois jedgrep under use of the new listing % and filelist modes. (Which are inspired by the old jedgrep by Dino!) % * grep_replace_cmd: Replace in the grep results % (both, result display and source files!) % 0.9.2 2003/07/09 % * bugfix contract_filename did not work properly (needs chdir() first) % 0.9.3 2004-01-30 % * solved bug with only one file (using -H option) [Peter Bengtson] % * recursive grep with special filename bang (!) (analog to kpathsea), % i.e. grep("pat", "dir/!") gets translated to `grep -r pat dir/` % 0.9.4 2004-04-28 % * close grep buffer, if the return value of the grep cmd is not 0 % 0.9.5 2005-11-07 % * change _implements() to implements() (this will only affect re-evaluating % sl_utils.sl in a JED < 0.99.17, so if you are not a developer on an older % jed version, it will not harm). % 0.9.6 2006-02-02 bugfix and code cleanup in grep_replace_* % (using POINT instead of what_column(), as TAB expansion % might differ between grep output and referenced buffer) % 1.0 2006-03-09 % * provide for --include pattern with recursive grep, % * escape the `what' argument with quotes % (this prevents ugly surprises with shell expansion but disables the % trick to put command line options into `what'). % grep("pat", "dir/*.sl!") --> `grep -r --include='*.sl', 'pat' dir/` % * change name of the custom var to Grep_Cmd to adhere to the % "_*" convention. % 1.1 2006-03-20 fixed cleanu p in zero-output handling in grep(). % 1.1.1 2006-06-28 fixed deletion of last empty line in grep() output % 1.1.2 2006-09-20 bugfix in grep_fsearch(): did not find matches right % after the separator % 1.1.3 2006-09-22 removed spurious debug output (report P Boekholt) % 1.1.4 2007-02-23 bugfix: grep() did recursive grep for empty basename % in grep pattern % 1.1.5 2007-04-19 added mode menu and more Customisation hints % 1.1.6 2007-10-04 no DFA highlight in UTF-8 mode (it's broken) % 2007-10-23 no DFA highlight cache (it's just one rule) % 1.1.7 2007-12-20 name grep->grep_replace_cmd() to grep->replace_cmd() % rebind also cua_replace_cmd() to grep->replace_cmd() % apply Jörg Sommer's DFA-UTF-8 fix and re-enable highlight % Usage % ----- % % * from jed: `M-x grep` (or bind to a key) % % * from the command line: `grep -nH "sometext" * | jed --grep_mode` % % - You should have grep_mode in your autoload list for this to work. % - Does not work for xjed, use e.g. `xjed -f "grep(\"sometext\", \"*\")"` % or the X selection. % % * To open a file on a result line, go to the line press ENTER or double click % on it % % * To replace text across the matches (both, grep output buffer and source % files), use the keybinding for the replace_cmd() or the Mode menu. % % (Find it with 'Help>Where is Command' replace_cmd, in any buffer but the % *grep-output*) % % Customisation % ------------- % % You can % % * set the grep command to use with grep(), e.g in your .jedrc:: % % variable Grep_Cmd = "rgrep -nH"; % % * customize the jedgrep_mode using the "grep_mode_hook", e.g.:: % % % give the result-buffer a number % autoload("number_buffer", "numbuf"); % jedmodes.sf.net/mode/numbuf/ % define grep_mode_hook(mode) % { % number_buffer(); % } % % * use current word as default pattern : % % If you want the word at the cursor position (point) as pattern (without % asking in the minibuffer), use something like % % definekey("^FG", "grep(get_word())") % % If you want the current word as default pattern (instead of the LAST_GREP % pattern), define a wrapper (and bind this to a key), e.g. % % define grep_word_at_point() % { % grep(read_mini("String to grep: ", get_word, "")); % } % % Or, with the word at point as init string (so it can be modified) % % define grep_word_at_point2() % { % grep(read_mini("String to grep: ", "", get_word,)); % } % % TODO: use search_file and list_dir if grep is not available % make it Windows-secure (filename might contain ":") % _debug_info=1; % --- Requirements --------------------------------------------- %{{{ % standard modes require("keydefs"); autoload("replace_with_query", "srchmisc"); % nonstandard modes (from jedmodes.sf.net) require("bufutils"); % autoloads "txtutils" require("filelist"); % which requires "listing", "view", and "datutils" autoload("contract_filename", "sl_utils"); autoload("get_word", "txtutils"); %}}} % --- name it provide("grep"); implements("grep"); private variable mode = "grep"; % --- Variables -------------------------------------------------%{{{ % the grep command %!%+ %\variable{Grep_Cmd} %\synopsis{shell command used by \slfun{grep}} %\usage{variable Grep_Cmd = "grep -nH"} %\description % The shell command which is called by \slfun{grep}. % Customize this to provide command line options or use a variant of grep % like `agrep`, `egrep`, or `fgrep`. %\notes % In order to go to the filename and line-number, grep_mode assumes the % -n and -H argument set. %\seealso{grep, grep_mode} %!%- custom_variable("Grep_Cmd", "grep -nH"); % remember the string to grep (as default for the next run) (cf. LAST_SEARCH) static variable LAST_GREP = ""; %}}} % --- Replace across files ------------------------------------- %{{{ % Return the number of open buffers static define count_buffers() { variable n = buffer_list(); % returns names and number of buffers _pop_n(n); % pop the buffer names return n; } % Compute the length of the statistical data in the current line % (... as we have to skip spurious search results in this area) static define grep_prefix_length() { push_spot_bol(); EXIT_BLOCK { pop_spot(); } loop(2) { () = ffind_char(get_blocal("delimiter", ':')); go_right_1(); } return POINT; % POINT starts with 0, this offsets the go_right_1 } % fsearch in the grep results, skipping grep's statistical data % return the length of the pattern found or -1 private define grep_fsearch(pat) { variable pat_len; do { pat_len = fsearch(pat); !if(pat_len) break; if (POINT >= grep_prefix_length()) return pat_len; } while(right(1)); return -1; } % The actual replace function % (replace in both, the grep output and the referenced file) private define grep_replace(new, len) { variable buf = whatbuf(), no_of_bufs = count_buffers(), pos = POINT - grep_prefix_length(), old; % get (and delete) the string to be replaced push_mark(); () = right(len); old = bufsubstr_delete(); push_spot(); ERROR_BLOCK { % close referenced buffer, if it was not open before if (count_buffers > no_of_bufs) { save_buffer(); delbuf(whatbuf); } % insert the replacement into the grep buffer sw2buf(buf); pop_spot(); set_readonly(0); insert(old); } % open the referenced file and goto the right line and pos filelist_open_file(); bol; go_right(pos); % abort if looking at something different !if (looking_at(old)) { push_mark(); () = right(len); verror("File differs from grep output (looking at %s)", bufsubstr()); } len = replace_chars(len, new); old = new; EXECUTE_ERROR_BLOCK; % close newly opened buffer, return to grep results return len; } % Replace across files found by grep (interactive function) static define replace_cmd() { variable old, new; % find default value (region or word under cursor) % and set point to begin of region if (is_visible_mark) check_region(0); else mark_word(); exchange_point_and_mark; % set point to begin of region old = read_mini("Grep-Replace:", "", bufsubstr()); !if (strlen (old)) return; new = read_mini(sprintf("Grep-Replace '%s' with:", old), "", ""); ERROR_BLOCK { REPLACE_PRESERVE_CASE_INTERNAL = 0; set_readonly(1); set_buffer_modified_flag(0); } set_readonly(0); REPLACE_PRESERVE_CASE_INTERNAL = REPLACE_PRESERVE_CASE; replace_with_query (&grep_fsearch, old, new, 1, &grep_replace); EXECUTE_ERROR_BLOCK; message ("done."); } %}}} % grep mode % --------- % %{{{ create_syntax_table(mode); #ifdef HAS_DFA_SYNTAX dfa_define_highlight_rule("^[^:]*:[0-9]+:", "keyword", mode); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); enable_dfa_syntax_for_mode(mode); #endif !if(keymap_p(mode)) { copy_keymap(mode, "filelist"); rebind("replace_cmd", "grep->replace_cmd", mode); rebind("cua_replace_cmd", "grep->replace_cmd", mode); } % --- the mode dependend menu static define grep_menu(menu) { filelist->filelist_menu(menu); menu_insert_item("&Grep", menu, "&Replace across matches", "grep->replace_cmd"); menu_delete_item(menu + ".&Grep"); menu_delete_item(menu + ".Tar"); } %}}} % Interface: %{{{ %!%+ %\function{grep_mode} %\synopsis{Mode for results of the grep command} %\usage{grep_mode()} %\description % A mode for the file listing as returned by \sfun{grep} or the "grep -Hn" % command line tool. Provides highlighting and convenience functions. %\seealso{grep, grep_replace, filelist_mode} %!%- public define grep_mode() { define_blocal_var("delimiter", ':'); define_blocal_var("line_no_position", 1); filelist_mode(); set_mode(mode, 0); use_syntax_table (mode); use_keymap(mode); mode_set_mode_info(mode, "init_mode_menu", &grep_menu); run_mode_hooks("grep_mode_hook"); } % TODO: What does gnu grep expect on DOS, What should this be on VMS and OS2 ? %!%+ %\function{grep} %\synopsis{Grep interface} %\usage{grep(String what=NULL, String path=NULL)} %\description % Grep for "what" in the file(s) "path". % % If the optional arguments are missing, they will be asked for in % the minibuffer. % % \sfun{grep} adds an extension to the shell pattern replacement mechanism: % the special filename bang (!) indicates a recursive grep in subdirs % (analog to kpathsea), i.e. grep("pat" "path/*.sl!") translates to % `$Grep_Cmd -r --include='*.sl', 'pat' path` % % Other than this, normal shell expansion is applied to "path". % % The grep command and options can be set with the custom % variable \var{Grep_Cmd}. % % The buffer is set to \sfun{grep_mode}, so you can go to the matching % lines or find-and-replace accross the matches. % %\seealso{grep_mode, grep_replace, Grep_Cmd} %!%- public define grep() % ([what], [path]) { % optional arguments, ask if not given variable what, path; (what, path) = push_defaults( , , _NARGS); if (what == NULL) { what = read_mini("String to grep: ", LAST_GREP, ""); LAST_GREP = what; } if (path == NULL) path = read_with_completion ("Where to grep: ", "", "", 'f'); variable cmd, options = "", dir = buffer_dirname(), allfiles, status, basename = path_basename(path); #ifdef UNIX allfiles = "*"; #elifdef IBMPC_SYSTEM allfiles = "*.*"; #else allfiles = ""; #endif % set the working directory () = chdir(dir); % Build the command string: % The output buffer will be set to the active buffer's dir % If the path starts with dir, we can strip it. % (Note: this maight fail on case insensitive filesystems). path = contract_filename(path); % recursive grep with special char '!' (analog to kpathsea) if (andelse{basename != ""} {substr(basename, strlen(basename), 1 ) == "!"}) { options = "-r"; path = path_dirname(path); basename = strtrim_end(basename, "!"); if (basename != "") options += sprintf(" --include='%s'", basename); } % append wildcard, if no filename (or pattern) is given if (basename == "") path = path_concat(path, allfiles); cmd = strjoin([Grep_Cmd, options, what, path], " "); % Prepare the output buffer popup_buffer("*grep-output*", FileList_max_window_size); setbuf_info("", dir, "*grep-output*", 0); erase_buffer(); set_buffer_modified_flag(0); % call the grep command flush("calling " + cmd); status = run_shell_cmd(cmd); switch (status) { case 0: message("matches found"); } { case 1: vinsert("No results for `%s`", cmd); } { case 2: vinsert("Error (or file not found) in `%s`", cmd); } { vinsert("`%s` returned %d", cmd, status); } if (bolp() and eolp()) delete_line(); fit_window(get_blocal("is_popup", 0)); bob(); set_status_line("Grep: " + cmd + " (%p)", 0); define_blocal_var("generating_function", [_function_name, what, path]); grep_mode(); } %}}} provide(mode); jedmodes-2.5.7/jedscape/0000755000175400017500000000000011262367306013366 5ustar mildegmjedmodes-2.5.7/jedscape/jedscape.sl0000644000175400017510000005431511262367306016204 0ustar mildemilde% jedscape.sl % % $Id: jedscape.sl,v 1.18 2009/08/02 16:13:34 paul Exp paul $ % % Copyright (c) 2003-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Mode for browsing the web in JED. % % This uses the 'w3m -halfdump' command to parse the html, like Emacs-w3m % does. To get w3m to output UTF-8 output with this option, you have to set % some options: start w3m, press 'o', go down to 'Charset Settings' % and set % Display charset [Unicode (UTF-8) ] % Output halfdump with display charset (*)YES ( )NO % go down, and press '[OK]' % Or you can set these options in ~/.w3m/config: % ext_halfdump 1 % display_charset UTF-8 provide("jedscape"); require("curl"); require("pcre"); require("sqlite"); require("bufutils"); require("view"); autoload("read_rss_data", "newsflash"); autoload("sqlited_table", "sqlited"); autoload("list2array", "datutils"); try { require("gettext"); eval("define _(s) {dgettext(\"lynx\", s);}", "jedscape"); } catch OpenError: { eval("define _(s) {s;}", "jedscape"); } use_namespace("jedscape"); private variable reference_marker=sprintf("\e[%dm", color_number("keyword1")); define jedscape_mode(); define find_page(); %!%+ %\variable{Jedscape_Home} %\synopsis{the file name of the jedscape home page} %\description % file opened by \var{jedscape} %\seealso{jedscape} %!%- custom_variable("Jedscape_Home", dircat (Jed_Home_Directory, "jed_home.html")); %!%+ %\variable{Jedscape_DB} %\synopsis{filename of the jedscape database} %\description % The database has one table bookmarks(name, url) and a table for search % engines. Search Engines work more or less like in Firefox - e.g. type % 'wp foo' at the 'open' prompt to search for 'foo' in Wikipedia. %\seealso{jedscape} %!%- custom_variable("Jedscape_DB", dircat (Jed_Home_Directory, "jedscape_db")); %!%+ %\variable{Jedscape_Emulation} %\synopsis{jedscape key bindings scheme} %\usage{String_Type Jedscape_Emulation = "w3"} %\description % this may be lynx, netscape or w3 %\seealso{jedscape} %!%- custom_variable("Jedscape_Emulation", "w3"); private variable mode="jedscape"; private variable version="$Revision: 1.18 $", title="", url_file ="", % /dir/file.html url_host="", % http://host url_root, % /dir href_list, href_begin_marks, href_end_marks, % hyperlinks href_anchor_list, % part between and anchor_marks, % anchors links= struct{ previous, next, up, contents}; % links in %{{{ database $1 = file_status(Jedscape_DB); variable db = sqlite_open(Jedscape_DB); ifnot ($1) { sqlite_exec(db, "CREATE TABLE bookmarks (name TEXT PRIMARY KEY, url TEXT)"); sqlite_exec(db, "CREATE TABLE searchengines (name TEXT PRIMARY KEY, url TEXT)"); sqlite_exec(db, "INSERT INTO searchengines (name, url) VALUES ('wp', 'http://en.wikipedia.org/wiki/Special:Search?&search=%s')"); sqlite_exec(db, "INSERT INTO searchengines (name, url) VALUES ('php', 'http://php.net/search.php?pattern=%s&show=quickref')"); sqlite_exec(db, "INSERT INTO searchengines (name, url) VALUES ('cpan', 'http://cpan.uwinnipeg.ca/search?query=%s&mode=dist')"); sqlite_exec(db, "INSERT INTO searchengines (name, url) VALUES ('perl', 'http://cpan.uwinnipeg.ca/cgi-bin/docperl?query=%s&si=2')"); } %}}} %{{{ html parsing private define bufsubstr_compress() { strcompress(strtrim(bufsubstr()), " \n"); } %{{{ % get the header links and title private define get_links() { variable href, rel; for (bob(); re_fsearch("'}, {"lt", '<'}, {"amp", '&'}, {"quot", '\''}, {"apos", '\''}, {"circ", '^'}, {"tilde", '~'}, {"mdash", '-'}]) { entities[$1[0]] = $1[1]; } private variable jedscape_temp=path_concat(Jed_Home_Directory, "jedscape_temp.html"); private define filter_html() { bob(); (href_list, href_anchor_list) = ({}, Assoc_Type[String_Type]); href_begin_marks = {}; href_end_marks = {}; anchor_marks = Assoc_Type[Mark_Type]; set_struct_fields(links, NULL, NULL, NULL, NULL); flush("filtering"); mark_buffer(); ()=write_region_to_file(jedscape_temp); erase_buffer(); setbuf("*jedscape*"); set_readonly(0); erase_buffer(); ()=run_shell_cmd(sprintf("w3m -cols %d -halfdump %s", window_info('w') - 5, jedscape_temp)); %%% process links flush("marking links"); get_links(); %%% hrefs bob(); while (re_fsearch("]*href=\\([\"']\\)\\([^\"]*\\)\\1[^>]*>")) { list_append(href_list, str_replace_all(regexp_nth_match(2), "&", "&")); ()=replace_match("", 0); list_append(href_begin_marks, create_user_mark()); insert(reference_marker); if (re_fsearch("")) ()=replace_match("\e[0]", 0); else throw RunTimeError, "missing closing tag"; list_append(href_end_marks, create_user_mark()); } href_begin_marks = list2array(href_begin_marks, Mark_Type); href_end_marks = list2array(href_end_marks, Mark_Type); %%% anchors for (bob(); re_fsearch("]*>")) ()=replace_match("", 0); bob(); while(re_fsearch("&\([a-z]+\);"R)) { if (assoc_key_exists(entities, regexp_nth_match(1))) ()=replace_match(char(entities[regexp_nth_match(1)]), 0); else ()=replace_match("?", 0); } bob(); while(re_fsearch("&#\([0-9]+\);"R)) ()=replace_match(char(atoi(regexp_nth_match(1))), 0); clear_message(); } %}}} %}}} %{{{ browsing private define goto_anchor(anchor) { if (assoc_key_exists(anchor_marks, anchor)) { goto_user_mark(anchor_marks[anchor]); recenter(3); } } private define write_callback (v, data) { insert(data); return 0; } private define push_position(); define find_page(url) { variable file, anchor, v=""; file=extract_element (url, 0, '#'); anchor=extract_element (url, 1, '#'); USER_BLOCK0 { if (anchor != NULL) goto_anchor(anchor); } % texi2html generated pages superfluously add the filename to #links if (file == url_file && bufferp("*jedscape*")) return sw2buf("*jedscape*"), X_USER_BLOCK0; setbuf(" jedscape_buffer"); erase_buffer(); ifnot (strncmp(file, "http://", 7)) { variable c = curl_new (file); curl_setopt(c, CURLOPT_FOLLOWLOCATION, 1); curl_setopt(c, CURLOPT_WRITEFUNCTION, &write_callback, &v); % You can use this hook to set a proxy server, e.g: % if (strncmp(curl_get_url(c), "http://localhost", 16)) % { % curl_setopt(c, CURLOPT_PROXY, "localhost:8080"); % curl_setopt(c, CURLOPT_HTTPHEADER, "Pragma:"); % } runhooks("jedscape_curlopt_hook", c); flush(sprintf(_("Getting %s"), file)); curl_perform (c); variable content_type=curl_get_info(c, CURLINFO_CONTENT_TYPE); file=curl_get_info(c, CURLINFO_EFFECTIVE_URL); if ((not strncmp(content_type, "text/xml", 8) || not strncmp(content_type, "application/atom", 16)) && get_y_or_n(sprintf("Content type=%s. View in newsflash", content_type, url))) { mark_buffer(); variable contents = bufsubstr(); read_rss_data(url, contents); return; } if(strncmp(content_type, "text/html", 9)) { switch(get_mini_response(sprintf("Content type=%s. (D)isplay (S)ave (C)ancel", content_type))) {case 's' or case 'S': variable dest=read_with_completion(_("Enter name of file to create:"), "", path_concat(getcwd(), path_basename(file)), 'f'); setbuf_info(getbuf_info() | 0x200); variable state; auto_compression_mode(0, &state); try { ()=write_buffer(dest); delbuf(whatbuf()); } finally { auto_compression_mode(state); } } {case 'd' or case 'D': pop2buf(file); erase_buffer(); insbuf(" jedscape_buffer"); } return; } variable separator = is_substr(file[[7:]], "/"); if (separator) { (url_host, url_file) = str_split(file, 7 + separator); } else % http://localhost { url_host=file; url_file="/"; } } else { url_host=""; url_file=file; switch(file_status(url_file)) { case 1: ()=insert_file(url_file);} { case 2: return dired_read_dir(url_file); } { throw OpenError, _("File does not exist.");} } url_root=path_dirname(url_file); filter_html(); sw2buf("*jedscape*"); setbuf_info(getbuf_info(), _stk_roll(-3), pop, path_dirname(url_file), _stk_roll(3)); set_buffer_modified_flag(0); set_readonly(1); jedscape_mode(); bob(); set_status_line(sprintf ("Jedscape: %s %%p", title), 0); if (qualifier_exists("last_position")) push_position(qualifier("last_position")); X_USER_BLOCK0; } %{{{ file download private define download_callback (fp, data) { variable len = bstrlen (data); if (len != fwrite (data, fp)) return -1; return 0; } private define progress_callback (fp, dltotal, dlnow, ultotal, ulnow) { if (dltotal > 0.0) flush(sprintf("Downloading... %d bytes of %d bytes received", int(dlnow), int(dltotal))); else flush(sprintf("Downloading... %d bytes received", int(dlnow))); return 0; } private define download(url) { variable c = curl_new (url); variable dest=read_file_from_mini(_("Enter name of file to create:")); variable fp=fopen(dest, "w"); if (fp == NULL) throw OpenError; curl_setopt(c, CURLOPT_FOLLOWLOCATION, 1); curl_setopt (c, CURLOPT_WRITEFUNCTION, &download_callback, fp); curl_setopt (c, CURLOPT_PROGRESSFUNCTION, &progress_callback, stdout); runhooks("jedscape_curlopt_hook", c); curl_perform (c); } %}}} %{{{ history stack ifnot (is_defined ("jedscape_position_type")) { typedef struct { hostname, filename, line_number, column } jedscape_position_type; } private define create_position(hostname, filename, line_number, column) { variable p = @jedscape_position_type; p.hostname = hostname; p.filename = filename; p.line_number = line_number; p.column = column; return p; } variable jedscape_history = jedscape_position_type[16], jedscape_history_rotator = [[1:15],0], jedscape_stack_depth = -1, forward_stack_depth = 0; private define push_position(position) { if (jedscape_stack_depth == 16) { --jedscape_stack_depth; jedscape_history = jedscape_history [jedscape_history_rotator]; } jedscape_history [jedscape_stack_depth] = position; ++jedscape_stack_depth; forward_stack_depth = 0; } private define goto_stack_position() { variable pos, file, n; pos = jedscape_history [jedscape_stack_depth]; file = strcat(pos.hostname, pos.filename); n = pos.line_number; if (file != strcat(url_host, url_file)) find_page(file); goto_line(n); ()=goto_column_best_try(pos.column); } private define goto_last_position () { if (jedscape_stack_depth < 0) return message(_("You are already at the first document")); ifnot (forward_stack_depth) { push_position(create_position(url_host, url_file, what_line, what_column())); --jedscape_stack_depth; } --jedscape_stack_depth; ++forward_stack_depth; goto_stack_position; } private define goto_next_position() { ifnot (forward_stack_depth) return message("Can't go forward"); ++jedscape_stack_depth; --forward_stack_depth; goto_stack_position; } %}}} private variable se_re = pcre_compile("([^ ]+?) (.*)"); %!%+ %\function{jedscape_get_url} %\synopsis{Open a file or url in jedscape} %\usage{ jedscape_get_url() [url]} %\description % Opens the file or url argument in \var{jedscape}. Without argument it prompts % for a file or url. %\seealso{jedscape} %!%- public define jedscape_get_url() % url { variable url; if (_NARGS) url = (); else url = read_mini("open", "", ""); variable last_host, last_file, last_line, last_column; (last_host, last_file, last_line, last_column) = (url_host, url_file, what_line, what_column()); if (pcre_exec(se_re, url)) { variable se, term; (se, term) = pcre_nth_substr(se_re, url, 1), pcre_nth_substr(se_re, url, 2); se = sqlite_get_array(db, String_Type, "select url from searchengines where name = ?", se); if (length(se)) url = sprintf(se[0,0], curl_easy_escape(curl_new(""), term)); } find_page(url; last_position = create_position(last_host, last_file, last_line, last_column)); } define open_local() { variable file=read_file_from_mini ("open local"); variable last_host, last_file, last_line, last_column; (last_host, last_file, last_line, last_column) = (url_host, url_file, what_line, what_column()); find_page(file; last_position = create_position(last_host, last_file, last_line, last_column)); } %{{{ view history private define get_url_this_line() { variable url = line_as_string(); close_buffer(); jedscape_get_url(url); } define view_history() { popup_buffer("*jedscape history*"); set_readonly(0); erase_buffer(); variable i = 0, file = ""; loop(jedscape_stack_depth + forward_stack_depth) { file; file = strcat(jedscape_history[i].hostname, jedscape_history[i].filename); i++; if (file == ()) continue; insert (file + "\n"); } fit_window(); view_mode(); set_buffer_hook("newline_indent_hook", &get_url_this_line); } define quit() { push_position(create_position(url_host, url_file, what_line, what_column())); url_file=""; delbuf("*jedscape*"); } %}}} %{{{ follow hyperlink define get_href() { variable place, href; place = create_user_mark(); href = wherefirst(href_end_marks >= place); if (href != NULL && href_begin_marks[href] <= place) return href_list[href]; else return ""; } define follow_href() % href { ifnot (_NARGS) get_href(); variable href = (); ifnot (strlen(href)) return; if (url_host !="" && not strncmp(href, "//", 2)) href = "http:" + href; if (is_substr(href, ":")) { variable url_type = extract_element(href, 0, ':'); switch (url_type) { case "mailto": mail(); eol(); insert(extract_element(href, 1, ':')); } { case "http": jedscape_get_url(href); } { case "file": href = extract_element(href, 1, ':'); ifnot (strncmp (href, "//localhost", 11)) href = href[[11:]]; jedscape_get_url(href); } { message (strcat(_("Unsupported URL scheme!"), url_type)); } return; } if (href[0] == '#') { push_position(create_position(url_host, url_file, what_line, what_column())); goto_anchor(href[[1:]]); } else { jedscape_get_url(url_host + expand_filename(path_concat(url_root,href))); } } define download_href() { ifnot (_NARGS) get_href(); variable href = (); ifnot (strlen(href)) return; if (url_host !="" && not strncmp(href, "//", 2)) href = "http:" + href; if (is_substr(href, ":")) { download(href); } else { download(url_host + expand_filename(path_concat(url_root,href))); } } %}}} %!%+ %\function{jedscape} %\synopsis{start jedscape} %\usage{ jedscape()} %\description % opens the \var{Jedscape_Home} page %\seealso{jedscape_get_url, jedscape_mode} %!%- public define jedscape() { find_page(Jedscape_Home); } %{{{ info-like navigation % next, previous, up, top = "contents" define follow_link(link) { variable url = get_struct_field(links, link); if (url == NULL) { % Many docs have no links, but ordinary hrefs called "next" if (assoc_key_exists(href_anchor_list, link)) url = href_anchor_list[link]; else throw RunTimeError, sprintf("page has no %s", link); } if (strncmp(url, "http://", 7)) jedscape_get_url(url_host + path_concat(url_root,url)); else jedscape_get_url(path_concat(url_root,url)); } % menu define complete_link() { variable url = read_string_with_completion("Link", "", strjoin(assoc_get_keys(href_anchor_list), ",")); if (assoc_key_exists(href_anchor_list, url)) { follow_href(href_anchor_list[url]); } } %}}} %}}} %{{{ other interactive functions private define reread() { variable line=what_line(), host=url_host, file=url_file; (url_host, url_file)="", ""; find_page(strcat(host, file)); goto_line(line); } define view_source() { if (strlen(url_host)) return message ("viewing a remote file is not supported yet"); ()=find_file(url_file); } define next_reference() { go_right (fsearch(reference_marker)); } define previous_reference() { if (bsearch("\e[0]")) { go_right(bsearch(reference_marker)); } } private define view_url() { message(strcat(url_host, url_file)); } %}}} %{{{ mode stuff %{{{ mouse private variable mouse_href=-1; private define mouse_hook(line, col, button, shift) { switch(button) { case 1: variable place, this_href; place = create_user_mark(); this_href = wherefirst(href_begin_marks <= place <= href_end_marks); if (NULL != this_href) { if (mouse_href == this_href) follow_href(href_list[this_href]); else { message(href_list[this_href]); mouse_href=this_href; } } else mouse_href=-1; } { case 2: follow_href;} { goto_last_position;} -1; } private define mouse_2click_hook(line, col, button, shift) { follow_href(); 1; } %}}} %{{{ keymap define add_bookmark(); ifnot (keymap_p(mode)) copy_keymap(mode, "view"); $1 = _stkdepth; switch (Jedscape_Emulation) { case "lynx": &next_reference, Key_Down; &previous_reference, Key_Up; &follow_href, Key_Right; &goto_last_position, Key_Left; "page_up", "b"; &view_source, "\\"; &view_history, Key_BS; "write_buffer", "p"; &view_history, "V"; } { case "netscape": "scroll_down_in_place", Key_Up; "scroll_up_in_place", Key_Down; &view_source, "\eu"; &goto_last_position, Key_Alt_Left; &goto_next_position, Key_Alt_Right; } { case "w3": &goto_last_position, "B"; &goto_next_position, "F"; &previous_reference, "b"; &next_reference, "f"; &jedscape_get_url, "^o"; &open_local, "o"; &view_source, "s"; &view_url, "v"; "message(jedscape->get_href())", "V"; &view_history, "^c^b"; } &add_bookmark, "a"; &jedscape_get_url, "g"; &follow_href, "^M"; &download_href, "d"; &goto_last_position, "l"; &goto_next_position, ";"; &goto_last_position, ","; &goto_next_position, "."; &next_reference, "\t"; ". 5 set_prefix_argument \"scroll_right\" call", "}"; ". 5 set_prefix_argument \"scroll_left\" call", "{"; ". 5 set_prefix_argument \"scroll_right\" call", "["; ". 5 set_prefix_argument \"scroll_left\" call", "]"; "jedscape->follow_link(\"previous\")", "p"; "jedscape->follow_link(\"next\")", "n"; "jedscape->follow_link(\"up\")", "u"; "jedscape->follow_link(\"contents\")", "t"; &complete_link, "m"; &view_history, "\eh"; &reread, "^r"; &quit, "q"; loop ((_stkdepth - $1)/2) definekey(mode); %}}} private define links_popup(menu) { variable name, value; foreach name (get_struct_field_names(links)) { value = get_struct_field(links, name); if (value != NULL) menu_append_item(menu, sprintf("%s: %s", name, value), &follow_link, name); } } %{{{ bookmarks private define bookmark_callback(bm) { if (is_substr(bm, "%s")) { variable parameter = read_mini("bookmark parameter", "", ""); bm = sprintf(bm, parameter); } jedscape_get_url(bm); } private define jedscape_bookmark_popup(menu) { variable name, url; foreach name, url (db) using ("select name, url from bookmarks order by name") { menu_append_item(menu, name, &bookmark_callback, url); } } define add_bookmark() { variable name = read_mini(_("name:"), title, ""); sqlite_exec(db, "insert into bookmarks (name, url) values (?, ?)", name, strcat(url_host, url_file)); message ("bookmark added"); } define edit_bookmarks() { sqlited_table(db, Jedscape_DB, "bookmarks"); } %}}} %{{{ search engines define add_searchengine() { variable name = read_mini(_("name:"), title, ""); variable url = read_mini("url:", "", ""); sqlite_exec(db, "insert into searchengines (name, url) values (?, ?)", name, url); message ("search engine added"); } define edit_searchengines() { sqlited_table(db, Jedscape_DB, "searchengines"); } %}}} define jedscape_menu(menu) { variable item; foreach item ({ ["&Dir", "jedscape"], ["&Open local page", "jedscape->open_local"], ["&Go to URL", "jedscape_get_url"], [_("History Page"), "jedscape->view_history"], ["&Source", "jedscape->view_source"], ["&Add Bookmark", "jedscape->add_bookmark"], ["Edit bookmarks", "jedscape->edit_bookmarks"], ["Add search engine", "jedscape->add_searchengine"], ["Edit search engines", "jedscape->edit_searchengines"]}) menu_append_item(menu, item[0], item[1]); menu_append_popup(menu, "&Links"); menu_set_select_popup_callback(menu+".&Links", &links_popup); menu_append_popup(menu, "&Bookmarks"); menu_set_select_popup_callback(menu+".&Bookmarks", &jedscape_bookmark_popup); } %!%+ %\function{jedscape_mode} %\synopsis{web browser} %\usage{ jedscape_mode()} %\description % Jedscape is a simple web browser in JED. It requires the curl module % to fetch documents from the web and w3m to render html markup. You % can open a document in \var{jedscape_mode} with \var{jedscape} or % \var{jedscape_get_url}. You can customize \var{jedscape mode} in a % jedscape_hook.sl file. %\seealso{Jedscape_Home, Jedscape_DB, Jedscape_Html_Filter, Jedscape_Emulation} %!%- define jedscape_mode() { use_keymap(mode); _set_buffer_flag(0x1000); set_mode(mode, 0); set_buffer_hook("mouse_up", &mouse_hook); set_buffer_hook("mouse_2click", &mouse_2click_hook); mode_set_mode_info(mode, "init_mode_menu", &jedscape_menu); run_mode_hooks("jedscape_mode_hook"); } $1 = expand_jedlib_file("jedscape_hook.sl"); if ($1 != "") () = evalfile ($1); %}}} jedmodes-2.5.7/gnuplot/0000755000175400017500000000000011307554040013271 5ustar mildegmjedmodes-2.5.7/gnuplot/gnuplot.sl0000644000175400017500000004332411307554040015327 0ustar mildegm% gnuplot.sl: Editing mode for the Gnuplot plotting program % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % based on a gnuplot highligting mode by Michele Dondi % % version 1.0 gnuplot_run: run gnuplot on skripts % gnuplot_shell: interactive use % call info(gnuplot) as online help % comments with comments.sl % version 1.1 interface for gnuplot online help (on UNIX) % keybindings via definekey_reserved % 1.1.1 gnuplot-help uses view-mode (from bufutils) % 2004-05-06 1.1.2 documentation for custom variables % code cleanup after getting version 1.5 of ishell % 2005-11-02 1.1.3 fixed the "public" statements % 2006-05-26 1.1.4 fixed autoloads (J. Sommer) % 2007-12-19 1.1.5 fixed view_mode() autoload % 2008-05-05 1.1.6 gnuplot_help(): filter spurious output, % new gnuplot_view(): run gnuplot and open output file % with default cmd (if it is defined), % mode menu item to browse HTML doc, % (active, if variable Gnuplot_Html_Doc is defined) % 2009-02-16 1.1.7 clearer names for mode menu entries, % gnuplot_view: If no output file defined, call gnuplot_plot. % 2009-12-08 1.8.1 Adapt to new require() syntax in Jed 0.99.19. % % % TODO % ---- % * gnuplot_print % * set Terminal via read_with_completion if prefix_argument given, % otherwise use default/last choice. % Then, invocation from menu can be with asking, via ^P without asking. % * set extension according to terminal % * add some more keywords, sort keywords (basic vs. extensions) % % Usage % ----- % To use gnuplot mode automatically for gnuplot files put the lines % autoload ("gnuplot_mode", "gnuplot.sl"); % and (depending on your use) % add_mode_for_extension ("gnuplot", "gnuplot"); % add_mode_for_extension ("gnuplot", "gp"); % ... % in your .jedrc. % % To customize the terminal and output setting for printing, % define the custom variables % % Gnuplot_Print_Terminal, % Gnuplot_Output_Extension. % % The actual command called for calling gnuplot is set by % % Gnuplot_Command % % You can change keybindings with the gnuplot_mode_hook(), e.g. % % define gnuplot_mode_hook() % { % local_setkey ("gnuplot_help", "^H"); % Help % local_setkey ("gnuplot_print", "^P"); % Print plot % local_setkey ("gnuplot_plot", "^D"); % Display plot % } % Requirements % ------------ % from jed's standard library #if (_jed_version > 9918) require("comments", "Global"); require("keydefs", "Global"); #else require("comments"); require("keydefs"); #endif autoload("info_find_dir", "info"); autoload("info_find_node", "info"); % Extensions from http://jedmodes.sourceforge.net/ autoload("popup_buffer", "bufutils"); autoload("close_buffer", "bufutils"); autoload("get_blocal", "sl_utils"); autoload("fit_window", "bufutils"); autoload("view_mode", "view"); autoload("ishell_mode", "ishell"); autoload("shell_cmd_on_region", "ishell"); % --- user adjustable settings ------------------------------------ % -- Variables %!%+ %\variable{Gnuplot_Print_Terminal} %\synopsis{Terminal option used by the gnuplot_print command} %\usage{String_Type Gnuplot_Print_Terminal = "postscript eps enhanced"} %\description % The terminal option handed to gnuplot by the gnuplot_print command. % The default value will print an eps file suited for inlcusion in a % LaTeX document. %\seealso{gnuplot_mode, gnuplot_print, Gnuplot_Output_Extension} %!%- custom_variable("Gnuplot_Print_Terminal", "postscript eps enhanced"); %!%+ %\variable{Gnuplot_Output_Extension} %\synopsis{Extension to add to gnuplot print files} %\usage{String_Type Gnuplot_Output_Extension = ".eps"} %\description % When gnuplot prints to a file, the default filename is the buffer-files % basename + "." + Gnuplot_Output_Extension. %\seealso{gnuplot_mode, gnuplot_print, Gnuplot_Print_Terminal} %!%- custom_variable("Gnuplot_Output_Extension", ".eps"); %!%+ %\variable{Gnuplot_Command} %\synopsis{Command for running gnuplot.} %\usage{String_Type Gnuplot_Command = "gnuplot -persist"} %\description % Command for running gnuplot. You might need to add a path or switches. %\seealso{gnuplot_mode, gnuplot_run, gnuplot_shell, gnuplot_plot, gnuplot_print} %!%- custom_variable("Gnuplot_Command", "gnuplot -persist"); % Location of Gnuplot Html documentation source. % The default is valid for the gnuplot-doc package of Debian GNU/Linux #if (file_status("/usr/share/doc/gnuplot-doc/gnuplot.html/index.html")) custom_variable("Gnuplot_Html_Doc", "/usr/share/doc/gnuplot-doc/gnuplot.html/index.html"); #else custom_variable("Gnuplot_Html_Doc", ""); #endif % ---------------------------------------------------------------------------- private variable mode = "gnuplot"; private variable tmp_buf = "gnuplot_tmp"; % do commenting with comments.sl set_comment_info (mode, "# ", "", 7); % --- Keybindings (change with gnuplot_mode_hook) !if (keymap_p (mode)) make_keymap (mode); definekey_reserved("gnuplot_help", "H", mode); % Help definekey_reserved("gnuplot_run", "R", mode); % Run buffer/region definekey_reserved("gnuplot_run", "^M",mode); % Return: Run buffer/region definekey_reserved("gnuplot_print", "P", mode); % Print plot definekey_reserved("gnuplot_plot", "D", mode); % Display plot % --- Functions ------------------------------------ %!%+ %\function{gnuplot_info } %\synopsis{gnuplot help via info file } %\usage{Void gnuplot_info (); } %\description % open info and goto node (gnuplot), an optional argument is subnode %\seealso{info_find_dir, info_find_node, gnuplot_mode} %!%- define gnuplot_info () { info_find_dir(); info_find_node("(gnuplot)"); if (_NARGS) % optional argument present { info_find_node( () ); % recurse further down } pop2buf("*Info*"); } %!%+ %\function{gnuplot_help} %\synopsis{Run gnoplots help feature on topic} %\usage{ Void gnuplot_help(topic=Ask)} %\description % Call gnuplot with "help topic" and display the help text in a window. % If the topic is not given, ask in the minibuffer. %\notes % Only tested on UNIX %\seealso{gnuplot_mode, gnuplot_info} %!%- define gnuplot_help() %([topic]) { !if (_NARGS) read_mini("Gnuplot Help for: ", "", ""); variable topic = (); popup_buffer("*gnuplot help*"); set_readonly(0); erase_buffer(); insert("help " + topic + "\n"); shell_cmd_on_region (Gnuplot_Command, 2); % output replaces input % filter needless instructions set_readonly(0); bob(); replace("Press return for more: ", ""); set_readonly(1); % do highlighting of keywords view_mode(); use_syntax_table(mode); % primitive sort of linking define_blocal_var("help_for_word_hook", "gnuplot_help"); if (is_defined("help_for_word_at_point")) set_buffer_hook("newline_indent_hook", "help_for_word_at_point"); if (is_defined("help_2click_hook")) set_buffer_hook ( "mouse_2click", "help_2click_hook"); fit_window(get_blocal("is_popup", 0)); } % ---Run Gnuplot with the buffer/region as argument ------------------------- %!%+ %\function{gnuplot_run} %\synopsis{Runs the gnuplot plotting program} %\usage{Void gnuplot_run()} %\description % The \sfun{gnuplot_run} function starts gnuplot in a subshell. The region % will be handed over as skript-file. % if no region is defined, the whole buffer is taken instead. By default, % a new buffer *gnuplot-output* is opened for the output (if there is any). %!%- define gnuplot_run() { % variable cbuf = whatbuf(); shell_cmd_on_region_or_buffer(Gnuplot_Command, "*gnuplot-output*"); recenter(window_info('r')); % pop2buf(cbuf); } %!%+ %\function{gnuplot_shell} %\synopsis{open an interactive gnuplot session in the current buffer } %\usage{Void gnuplot_shell()} %\description % This command calls ishell_mode with gnuplot as argument %\seealso{ishell, ishell_mode} %!%- public define gnuplot_shell() { ishell_mode(Gnuplot_Command); } %!%+ %\function{gnuplot_plot} %\synopsis{Plots a gnuplot skript to the display} %\usage{Void gnuplot_plot(hardcopy=0)} %\description % The \sfun{gnuplot_plot} function uses gnuplot to plot a skript to % gnuplots default display. To achive this, the buffer is copied to a temporal % buffer and the lines % set terminal ... % set output ... % are deleted before invocation of gnuplot_run. % If the optional argument hardcopy is non-zero, the plot % will be printed: The terminal defined in the variable % "Gnuplot_Print_Terminal" will be used and the output file has the % same basename as the skript and the extension "Gnuplot_Output_Extension", % overriding the values in the skript (actually, you will be asked for the % output filename with the above default). % If you want other output options either change the custom variables or set % terminal and output in the skript and use \sfun{gnuplot_run} %\seealso{gnuplot_mode, gnuplot_run, Gnuplot_Print_Terminal, Gnuplot_Output_Extension} %!%- define gnuplot_plot () % (hardcopy = 0) { variable hardcopy = 0; if (_NARGS) hardcopy = (); variable buf = whatbuf(); variable file_exists = 0; variable output_name; if (hardcopy) do { output_name = read_with_completion("Output file:", "", path_sans_extname(buf)+Gnuplot_Output_Extension, 'f'); if (file_status(output_name) == 1) file_exists = not(get_y_or_n("File exists, overwrite?")); else file_exists = 0; } while (file_exists); % copy to temporal buffer and delete set terminal and set output sw2buf(tmp_buf); erase_buffer(); insbuf (buf); bob; if (bol_fsearch("set terminal")) call("kill_line"); bob; if (bol_fsearch("set output")) call("kill_line"); if (hardcopy) { insert ("set terminal " + Gnuplot_Print_Terminal + "\n"); insert ("set output '" + output_name + "'\n"); } % run gnuplot shell_cmd_on_region(Gnuplot_Command, -1); % ignore output % clean up sw2buf(tmp_buf); set_buffer_modified_flag(0); % so delbuf doesnot ask whether to save first delbuf(tmp_buf); if (hardcopy) flush ("Plot written to " + output_name); } %!%+ %\function{gnuplot_view} %\synopsis{Run gnuplot and open output file} %\usage{gnuplot_view()} %\description % Run gnuplot and open output file (if it is defined) with the a default % command taken from \var{filelist->FileList_Default_Commands} or asked % for in the minibuffer. % If there is no output file defined, call gnuplot_plot(). %\notes %\seealso{gnuplot_mode, gnuplot_run, gnuplot_plot} %!%- define gnuplot_view() { variable quote, outfile = "", cmd = ""; % search output file definition push_spot_bob(); if (bol_fsearch("set output")) { foreach quote (['"', '\'']) { % show("quote", quote); if (ffind_char(quote)) { go_right_1(); push_mark(); () = ffind_char(quote); outfile = bufsubstr(); break; } } } pop_spot(); % show(outfile); % if there is no outfile define, display with default terminal if (outfile == "") { gnuplot_plot(); return; } % run gnuplot and open the outfile with default viewer: gnuplot_run(); if (is_defined("filelist->get_default_cmd")) cmd = call_function("filelist->get_default_cmd", outfile); if (cmd == "") cmd = read_mini(sprintf("Open %s with (Leave blank to open in Jed):", outfile), "", ""); if (cmd == "") return find_file(outfile); if (getenv("DISPLAY") != NULL) % assume X-Windows running () = system(cmd + " " + outfile + " &"); else () = run_program(cmd + " " + outfile); } %!%+ %\function{gnuplot_print} %\synopsis{Prints a gnuplot skript to a file)} %\usage{Void gnuplot_print()} %\description % Run the buffer/region. The terminal is set to \var{Gnuplot_Print_Terminal}, % the output file has the same basename as the skript and the extension % "Gnuplot_Output_Extension", overriding the values in the skript. If you % want other output options either change these variables or set terminal and % output in the skript and use \sfun{gnuplot_run}. %\seealso{gnuplot_run, gnuplot_plot, Gnuplot_Print_Terminal, Gnuplot_Output_Extension} %!%- define gnuplot_print() { gnuplot_plot(1); } %!%+ %\function{gnuplot_get_defaults} %\synopsis{opens a new buffer with the default values of gnuplot} %\usage{Void gnuplot_get_defaults()} %\description % opens a new buffer *gnuplot_defaults* with the default values % as returned by a run of gnuplot's save command. % Good to see what options there are. %!%- define gnuplot_get_defaults() { variable buf = whatbuf; variable gnuplot_defaults_file= make_tmp_file("gp_defaults"); variable tmp_buf = make_tmp_buffer_name ("*gnuplot-tmp*"); variable flags; % for setbuf_info % copy to temporal buffer and delete set terminal and set output sw2buf( tmp_buf ); insert ("save \"" + gnuplot_defaults_file + "\""); % run gnuplot, ignore output shell_cmd_on_region (Gnuplot_Command, -1); % clean up set_buffer_modified_flag (0); % so delbuf doesnot ask whether to save first delbuf (tmp_buf); () = find_file (gnuplot_defaults_file); () = delete_file (gnuplot_defaults_file); % rename_buffer("*gnuplot-defaults*"); % set also file and dir to "" (,,, flags) = getbuf_info (); setbuf_info ("", "","*gnuplot-defaults*", flags); } % * function that removes all default values from the script: % insert default file to buffer, % del_dup_lines_unsorted () from Marco Mahnics mmutils define gnuplot_strip_defaults () { variable buf = whatbuf; variable line = Null_String; push_spot (); trim_buffer (); % trim both to make them compatible %get default values gnuplot_get_defaults (); trim_buffer (); bob (); do { bol; push_mark_eol; % mark line line = bufsubstr (); !if (line == Null_String) { setbuf(buf); bob; % regexp does not work if line contains special characters % if (re_fsearch ("^" + line + "$")) if (bol_fsearch (line)) { right(strlen(line)); if (eolp) delete_line (); } setbuf("*gnuplot-defaults*"); } } while (down_1); set_buffer_modified_flag(0); % so delbuf doesnot ask whether to save first delbuf(whatbuf); sw2buf(buf); pop_spot(); } % --- Create and initialize the syntax tables. create_syntax_table (mode); define_syntax ("#", "", '%', mode); % Comments define_syntax ("([{", ")]}", '(', mode); % Delimiters define_syntax ("0-9a-zA-Z", 'w', mode); % Words define_syntax ("-+0-9.", '0', mode); % Numbers define_syntax (",", ',', mode); % Delimiters define_syntax (";", ',', mode); % Delimiters define_syntax ("-+/&*=<>|!~^", '+', mode); % Operators define_syntax ('\'', '"', mode); % Strings define_syntax ('\"', '"', mode); % Strings set_syntax_flags (mode, 0); % % Type 0 keywords % () = define_keywords_n(mode, "allbarkeyvarvia", 3, 0); () = define_keywords_n(mode, "axesclipdatagridsizethruticsviewwithzero", 4, 0); () = define_keywords_n(mode, "arrowdummyeveryindexlabelnokeypolarstyletitleusingxdataxticsydatayticszdataztics", 5, 0); () = define_keywords_n(mode, "anglesbinaryborderclabelformatlocalemarginmatrixmxticsmyticsmzticsnoclipnogridoriginoutputrrangesmoothtrangeurangevrangex2datax2ticsxdticsxlabelxmticsxrangey2datay2ticsydticsylabelymticsyrangezdticszlabelzmticszrange", 6, 0); () = define_keywords_n(mode, "bmargincontourdgrid3dlmarginmappingmissingmx2ticsmy2ticsnoarrownolabelnopolarnotitlenoxticsnoyticsnozticsoffsetsrmarginsamplessurfacetimefmttmarginversionx2dticsx2labelx2mticsx2rangey2dticsy2labely2mticsy2range", 7, 0); () = define_keywords_n(mode, "boxwidthencodingfunctionhidden3dlogscalenobordernoclabelnomxticsnomyticsnomzticsnox2ticsnoxdticsnoxmticsnoy2ticsnoydticsnoymticsnozdticsnozmticsterminalticscalezeroaxis", 8, 0); () = define_keywords_n(mode, "autoscalecntrparamfunctionslinestylemultiplotnocontournodgrid3dnomx2ticsnomy2ticsnosurfacenox2dticsnox2mticsnoy2dticsnoy2mticspointsizeticsleveltimestampvariablesxzeroaxisyzeroaxis", 9, 0); () = define_keywords_n(mode, "isosamplesnohidden3dnologscalenozeroaxisparametricx2zeroaxisy2zeroaxis", 10, 0); () = define_keywords_n(mode, "noautoscalenolinestylenomultiplotnotimestampnoxzeroaxisnoyzeroaxis", 11, 0); () = define_keywords_n(mode, "noparametricnox2zeroaxisnoy2zeroaxis", 12, 0); % % Type 1 keywords % () = define_keywords_n(mode, "!", 1, 1); () = define_keywords_n(mode, "cdif", 2, 1); () = define_keywords_n(mode, "fitpwdset", 3, 1); () = define_keywords_n(mode, "callexithelploadplotquitsaveshowtest", 4, 1); () = define_keywords_n(mode, "clearprintpauseresetshellsplot", 5, 1); () = define_keywords_n(mode, "replotrereadupdate", 6, 1); % mode menu static define gnuplot_menu(menu) { menu_append_item(menu, "&Gnuplot Region/Buffer", "gnuplot_run"); menu_append_item(menu, "Gnuplot &Shell", "gnuplot_shell"); menu_append_item(menu, "&View", "gnuplot_view"); menu_append_item(menu, sprintf("&Print to %s", Gnuplot_Print_Terminal), "gnuplot_print"); menu_append_item(menu, "&New File(defaults)", "gnuplot_get_defaults"); menu_append_item(menu, "&Strip Defaults", "gnuplot_strip_defaults"); menu_append_item(menu, "Gnuplot &Help", "gnuplot_help"); if (Gnuplot_Html_Doc != "") menu_append_item(menu, "&Browse Gnuplot Doc", "browse_url", Gnuplot_Html_Doc); } % --- now define the mode --------------------------------------------- public define gnuplot_mode () { set_mode(mode, 4); use_syntax_table(mode); use_keymap(mode); mode_set_mode_info(mode, "fold_info", "#{{{\r#}}}\r\r"); mode_set_mode_info(mode, "init_mode_menu", &gnuplot_menu); define_blocal_var("help_for_word_hook", &gnuplot_help); define_blocal_var("run_buffer_hook", &gnuplot_run); run_mode_hooks("gnuplot_mode_hook"); } provide(mode); jedmodes-2.5.7/jedasp/0000755000175400017500000000000010461125576013057 5ustar mildegmjedmodes-2.5.7/jedasp/jedasp.sl0000644000175400017500000000711410340557500014660 0ustar mildegm%% -*- mode:slang; mode:fold; -*- %% JED ASP %% Author: Marko Mahnic %% Version 1.1 %% %% AUTOLOAD: %% asp_run_scripts %% %% This code tries to simulate MS IIS Active Server Pages with JED. %% %% The script is defined with arbitrary BEGIN and END tag, they are both %% passed to the asp_run_scripts function. %% %% The scripts are executed while there are any in the file. %% %% If you need to insert raw text into the buffer within the script, %% use the %T comment. You can use SLang escape sequences in raw text. %% If tou need to insert the value of some SLang variable into raw text, %% you can do it using the (%F, X%) format, where F is the format, X is an %% arbitrary expression whose result has a valid type for F. The expression %% may not contain string constants. %% static variable asp_buf = "*ASP_CODE_BUF*"; static variable asp_begin_tag = ""; static variable asp_end_tag = asp_begin_tag; static define asp_error (text) { error (text); } % \usage{Void asp_transform_raw_text()} static define asp_transform_raw_text() { bob (); variable str; while (re_fsearch ("^[ \t]*%T[ \t]")) { push_mark(); narrow(); bol(); () = ffind_char ('%'); skip_chars("^ \t"); skip_chars(" \t"); push_mark(); eol(); str = bufsubstr_delete(); push_mark(); bol(); del_region(); str = str_quote_string (str, "\"", '\\'); insert ("insert (\"" + str + "\");"); % replace all the substrings Y\\X, where Y is not '\' and X is not '"' nor '\', with Y\X % with this we allow the use of all SLang escape sequences in raw text % PROBLEM: when I want to get '\n' I actually get '\\n' in output. bol(); while (re_fsearch ("[^\\\\]\\\\\\\\[^\"\\\\]")) { go_right(1); del(); } bol(); if (re_fsearch("(%.+,.+%)")) { bol(); insert ("v"); while (re_fsearch("(%[^,]+,.+%)")) { del(); () = ffind_char(','); push_mark(); ffind ("%)"); deln(2); str = bufsubstr_delete(); push_spot(); eol(); go_left(2); insert (str); pop_spot(); } } widen(); } } % \usage{Int asp_exec_marked_script (String ScriptBeginTag)} static define asp_exec_marked_script (ScriptBeginTag) { variable script; !if (markp()) { asp_error ("Script not marked."); return (-1); } () = dupmark(); script = bufsubstr(); % Detect script within script if (is_substr (script, ScriptBeginTag)) { pop_mark(0); asp_error ("Script within script."); return (-2); } del_region(); variable buf = whatbuf(); setbuf (asp_buf); erase_buffer(); insert (script); asp_transform_raw_text(); mark_buffer(); script = bufsubstr(); set_buffer_modified_flag(0); setbuf (buf); eval (script); return (0); } % \usage{Void asp_run_scripts (String ScriptBeginTag, String ScriptEndTag)} public define asp_run_scripts (ScriptBeginTag, ScriptEndTag) { variable buf = whatbuf(); asp_begin_tag = ScriptBeginTag; asp_end_tag = ScriptEndTag; % setbuf (DocBuffer); bob (); while (fsearch (ScriptBeginTag)) { deln(strlen(ScriptBeginTag)); %% Do not try to run the script twice push_mark(); !if (fsearch (ScriptEndTag)) { pop_mark(1); eol(); asp_error ("End of script not found."); break; } go_right (strlen (ScriptEndTag)); if (not 0 == asp_exec_marked_script (ScriptBeginTag)) { break; } bob (); } setbuf (buf); if (bufferp (asp_buf)) delbuf (asp_buf); } provide("jedasp"); jedmodes-2.5.7/jedasp/jedasp_sl.html0000664000175400017500000000531210214064440015700 0ustar mildegm JED Macro: jedasp.sl

jedasp.sl

tries to simulate Active Server Pages (MS IIS). The function asp_run_scripts searches for SLang code declared between arbitrary tags and executes it. It allways searches from the beginning of the buffer for the first occurence of tagged code and executes it.

Scripts

The script is defined with arbitrary BEGIN and END tag, they are both passed to the asp_run_scripts function:
  asp_run_scripts ("<%", "%>")

The scripts are executed while there are any in the file.

If you need to insert raw text into the buffer within the script, use the %T comment. You can use SLang escape sequences in raw text. To insert the value of some SLang variable into raw text, you can do it using the (%F, X%) format, where F is the format, X is an arbitrary expression whose result has a valid type for F. The expression X may not contain string constants.

Example

The file that we want to process:
    HTML table <BR>
    <% 
       % SLang comment inside script
       %T <TABLE BORDER="2"> \n
       variable i;
       for (i = 0; i < 3; i++) {
          %T <TR>
          %T <TD> (%d, i %) * (%d, i %) </TD><TD> (%05d, i*i %) </TD>
          if (i mod 2 == 0) {
             %T <TD> (%d, i%) mod 2 is "0" </TD>
          }
          else {
             %T <TD> (%d, i%) mod 2 is "not 0" </TD>
          }
          %T </TR> \n
       }
       %T </TABLE>
    %>
When we call asp_run_scripts ("<%", "%>"), the file is transformed into:
    HTML table <BR>
    <TABLE BORDER="2"> 
 <TR><TD> 0 * 0 </TD><TD> 00000 </TD><TD> 0 mod 2 is "0" </TD></TR> 
 <TR><TD> 1 * 1 </TD><TD> 00001 </TD><TD> 1 mod 2 is "not 0" </TD></TR> 
 <TR><TD> 2 * 2 </TD><TD> 00004 </TD><TD> 2 mod 2 is "0" </TD></TR> 
 </TABLE>
and the final result looks like this:

HTML table
0 * 0 00000 0 mod 2 is "0"
1 * 1 00001 1 mod 2 is "not 0"
2 * 2 00004 2 mod 2 is "0"
jedmodes-2.5.7/csvutils/0000755000175400017500000000000010511177022013452 5ustar mildegmjedmodes-2.5.7/csvutils/csvutils.sl0000644000175400017500000003740710511177022015701 0ustar mildegm% csvutils.sl: work with comma (or tabulator) separated values (csv files) % % Copyright (c) 2003 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Utilities to work with comma (or tabulator) separated values (csv files) % We will call such a 2d-array of values a table % % Version 1.0 First public version % 2005-03-31 1.1 made slang-2 proof: A[[0:-2]] --> A[[:-2]] % 2005-11-24 1.2 new default "" for col_sep in get_table(), format_table() % indent to beg-of-region and "wizard" for format_table() % new function format_table_rect(): format the rectangular % region as table. % 2005-11-25 1.2.1 new functions max_column() and goto_max_column() % 2005-11-28 1.2.2 bugfix in goto_max_column() (report P. Boekholt) % 1.2.3 code cleanup in get_lines() % 2006-07-10 1.2.4 doc update, bugfix in format_table_rect(), % do not remove trailing whitespace in strjoin2d if % align==NULL % disabled format_table_rect(), it doesnot work % 1.2.5 docu update % 2006-10-05 1.3 replaced spaces2tab with an optional arg to buffer_compress % documentation fixes % requirements autoload("push_defaults", "sl_utils"); autoload("array_max", "datutils"); autoload("array_product", "datutils"); autoload("array_transpose", "datutils"); autoload("string_repeat", "strutils"); autoload("get_buffer", "txtutils"); % --- static functions ------------------------------------------------------- % replace x with value, if x == NULL static define fill_missing(x, value) { if (x == NULL) return value; else return x; } static define align_fields(a, align) { % expand the align argument to the number of columns variable dims; (dims, , ) = array_info(a); if (strlen(align) < dims[1]) align = string_repeat(align, dims[1])[[:dims[1]-1]]; % TODO: wrap fields for columns in uppercase ("LMCR") % wrap_cols = where (bstring_to_array(str) == bstring_to_array(strlow(str))); % trim fields variable b = array_map(String_Type, &strtrim, a); % Pad the fields to get aligned columns variable i, j, pad; % indizes, required padding variable field_width = array_map(Int_Type, &strlen, b); variable col_width; % the width of the table columns for (j=0; j < dims[1]; j++) { col_width = array_max(field_width[*,j]); for (i=0; i < dims[0]; i++) { pad = col_width - field_width[i,j]; switch (align[j]) {case 'l': b[i,j] += string_repeat(" ", pad);} {case 'r': b[i,j] = string_repeat(" ", pad) + b[i,j];} {case 'c': b[i,j] = string_repeat(" ", pad/2) + b[i,j] + string_repeat(" ", (pad+1)/2);} {case 'm': b[i,j] = string_repeat(" ", (pad+1)/2) + b[i,j] + string_repeat(" ", pad/2);} } } return b; } % --- public functions ------------------------------------------------ % Return the buffer/region as an string-array of lines define get_lines() % (kill=0) { variable kill = push_defaults(0, _NARGS); variable str = get_buffer(kill); % trim trailing newline(s) str = strtrim_end(str, "\n"); return strchop(str, '\n', 0); } % --- convert spaces to single tab %!%+ %\function{buffer_compress} %\synopsis{"Normalize" whitespace delimited data} %\usage{Void buffer_compress(white="\t ")} %\description % Change all in-line whitespace (" " and "\t") to single tabs % (also trims lines). This is configurable with the \var{white} % argument. % % Calls \sfun{strcompress} on the buffer lines or (if visible) region. %\notes % As buffer_compress acts on the lines, newline chars are not compressed, % even if included in the argument string. %\seealso{strcompress, trim_buffer, untab_buffer} %!%- public define buffer_compress() % (white="\t ") { variable white = push_defaults("\t ", _NARGS); % (strcompress also trimms, therefore do it on lines!) variable lines = get_lines(1); lines = array_map(String_Type, &strcompress, lines, white); insert(strjoin(lines, "\n")); } % Tables % ------ %!%+ %\function{strchop2d} %\synopsis{Chop a string into a 2d-array (lines and columns)} %\usage{Array strchop2d(str, col_sep='\t', line_sep='\n', quote=0) % Array strchop2d(String str, String col_sep, line_sep='\n')} %\description % The 2d equivalent to strchop and strtok. Split the string first into % lines (or equivalent with line_sep != '\n') and then into fields. % Return the result as a 2d-array with missing values set to NULL % % The datatype of col_sep determines which function is used to split % the lines: % if typeof(col_sep) == String_Type, use strtok, else use strchop %\example %#v+ % strchop2d(bufsubstr, " \t") %#v- % will return the data in the region interpreted as a white-space % delimited table. %\seealso{strchop, strtok, read_table} %!%- define strchop2d() % (str, col_sep='\t', line_sep='\n', quote=0) { variable str, col_sep, line_sep, quote; (str, col_sep, line_sep, quote) = push_defaults( , '\t', '\n', 0, _NARGS); variable i, no_cols, table; % -> array of lines str = strchop(str, line_sep, quote); % show("Lines", str); % split lines: -> array of arrays of fields if (typeof(col_sep) == String_Type) str = array_map(Array_Type, &strtok, str, col_sep); else str = array_map(Array_Type, &strchop, str, col_sep, quote); % show("Table", str); no_cols = array_max(array_map(Int_Type, &length, str)); % show("Number of columns", no_cols); % insert into a 2d array table = String_Type[length(str), no_cols]; for (i = 0; i < length(str); i++) table[i,[0:length(str[i])-1]] = str[i]; return(table); } %!%+ %\function{get_table} %\synopsis{Return a 2d-string-array with csv data in the region/buffer} %\usage{String get_table(col_sep="", kill=0)} %\description % Return a 2d-string-array with the data in the region/buffer % The default col_sep=="" means whitespace (any number of spaces or tabs). % The optional argument \var{kill} tells, whether the table should be % deleted after reading. % %\example %#v+ % get_table(" "); % columns are separated by single spaces % get_table(" | "); % columns are separated by space-sourounded bars % get_table(""); % columns are separated by any whitespace (default) %#v- %\seealso{strchop2d, format_table, insert_table} %!%- define get_table() % (col_sep="", kill=0) { variable col_sep, kill; (col_sep, kill) = push_defaults("", 0, _NARGS); variable cs, str; % get visible region (expanded to full lines) or buffer str = get_buffer(kill, 1); % trim trailing newline(s) str = strtrim_end(str, "\n"); if (col_sep == "") col_sep = "\t "; % white-space delimited columns else if (strlen(col_sep) == 1) col_sep = col_sep[0]; % convert to Char_Type else { % find an unused character -> use it as delimiter cs = '~'; while (is_substr(str, char(cs))) { cs++; if (cs > 255) error ("get_table: did not find unique replacement for multichar col_sep"); } str = str_replace_all(str, col_sep, char(cs)); col_sep = cs; } return strchop2d(str, col_sep, '\n', 0); } %!%+ %\function{strjoin2d} %\synopsis{Print 2d-array as a nicely formatted table to a string} %\usage{Str strjoin2d(Array a, col_sep="\t", line_sep="\n", align=NULL)} %\description % The function takes an 2d-array and returns a string that represents % the data as an csv-table. It can be seen as a 2d-variant of % strjoin(Array_Type a, String_Type delim). %\seealso{strjoin, strchop2d, insert_table, get_table} %!%- define strjoin2d() %(a, col_sep="\t", line_sep="\n", align=NULL) { % get arguments variable a, col_sep, line_sep, align; (a, col_sep, line_sep, align) = push_defaults( , "\t", "\n", , _NARGS); variable b; % copy of array a % get the array metadata variable dims, nr_dims, type; (dims, nr_dims, type) = array_info(a); % show("dims", dims, "nr_dims", nr_dims, "type", type); !if (nr_dims == 2) error("first argument to strjoin2d must be a 2d-array"); !if (length(a)) % empty array return ""; % Convert array elements to strings if (type != String_Type) b = array_map(String_Type, &string, a); else % fill missing values (NULL) with "" b = array_map(String_Type, &fill_missing, a, ""); % align columns if (align != NULL) b = align_fields(b, align); % build the lines by joining the fields variable i, lines = String_Type[dims[0]]; for (i=0; i < dims[0]; i++) % lines[i] = strtrim_end(strjoin(b[i,*], col_sep)); lines[i] = strjoin(b[i,*], col_sep); % join the lines return strjoin(lines, line_sep); } %!%+ %\function{insert_table} %\synopsis{Print 2d-array as a nicely formatted table} %\usage{Void insert_table(Array a, align="l", col_sep=" ")} %\description % The function takes an 2d-array and writes it as an aligned table. % \var{col_sep} is the string separating the items on a line. It defaults % to " " (space). % \var{align} is a format string formed of the key charaters: % "l": left align, % "r": right align, % "c": center align, or % "n": no align (actually every character other than "lrc"), % one for each column. If the string is shorter than the number of columns, % it will be repeated, i.e. if it contains only one character, the % align is the same for all columns) %\example % The call %#v+ % insert_table(a, " | ", "llrn"); %#v- % inserts \var{a} as a table with elements separated by " | " and % first and second columns left aligned, third column right aligned % and last column not aligned. %\seealso{get_table, strjoin2d, strjoin} %!%- define insert_table() %(a, align="l", col_sep=" ") { variable a, align, col_sep; (a, align, col_sep) = push_defaults( , "l", " ", _NARGS); insert(strjoin2d(a, col_sep, "\n", align)); newline(); } %!%+ %\function{format_table} %\synopsis{Adjust a table to evenly spaced columns} %\usage{format_table((col_sep=NULL, align=NULL, new_sep=NULL)} %\description % Read visible region or buffer as grid data into a 2d array, reformat and % insert again. The indention of the whole table is determined by the point % or mark (whichever is more left) if a visible region is defined. % If the arguments are not given, they will be asked for in the minibuffer: % \var{col_sep}: the string separating columns (default "" means whitespace) % \var{align}: string of "l", "r", "c", or "n" (see \sfun{insert_table}) % \var{new_col_sep}: string to separate the columns in the output. %\seealso{get_table, insert_table} %!%- public define format_table() % (col_sep=NULL, align=NULL, new_sep=NULL) { % optional arguments variable col_sep, align, new_sep; (col_sep, align, new_sep) = push_defaults( , , , _NARGS); if (col_sep == NULL) col_sep = read_mini("Column separator (leave empty for 'whitespace'):", "", ""); if (align == NULL) align = strlow(read_mini("Column alignment (Left Right Center None):", "", "l")); if (new_sep == NULL) { % set default if (col_sep != "") new_sep = col_sep; else new_sep = " "; new_sep = read_mini("Output column separator:", "", new_sep); } % get indention (least indention of region) variable indent = 1; if (is_visible_mark){ indent = what_column(); exchange_point_and_mark(); if (what_column() < indent) indent = what_column(); } variable a = get_table(col_sep, 1); % delete after reading push_mark(); insert_table(a, align, new_sep); goto_column(indent); open_rect(); } %!%+ %\function{max_column() } %\synopsis{Return maximal column number of the buffer (or region)} %\usage{Integer max_column(trim=0)} %\description % Returns 1+length of the longest line of the buffer (or, if visible, % region). If the optional parameter \var{trim} is nonzero, trailing % whitespace will be removed during the scan. %\seealso{goto_max_column, what_column} %!%- define max_column() { variable trim = push_defaults(0, _NARGS); variable max_col = 0, mark_visible = is_visible_mark(); if (mark_visible) narrow(); push_spot_bob(); do { eol(); if (trim) trim(); if (what_column() > max_col) max_col = what_column(); } while (down_1); pop_spot; if (mark_visible) widen(); return (max_col); } %!%+ %\function{goto_max_column} %\synopsis{Goto the maximal column of the buffer (or region)} %\usage{goto_max_column()} %\description % Goto the column of the longest line of the buffer (or, if visible, region). % Insert whitespace if needed. The region stays marked. % % If the optional parameter \var{trim} is nonzero, trailing % whitespace will be removed during the scan. %\notes % This function comes handy, if you want to mark a rectagle but % the last line is shorter than preceding lines. %\seealso{max_column, goto_column, copy_rect} %!%- public define goto_max_column() { variable trim = push_defaults(0, _NARGS); if (is_visible_mark) { % duplicate visible mark push_spot(); pop_mark_1(); loop (2) push_visible_mark(); pop_spot(); } goto_column(max_column(trim)); } % Buggy, not needed anywhere, so commented out % %!%+ % %\function{format_table_rect} % %\synopsis{Format the contents of the rectangle as table} % %\usage{ format_table_rect([[[col_sep], align], new_sep])} % %\description % % This functions calls \sfun{format_table} on a rectangle. A rectangle is % % defined by the diagonal formed by the mark and the current point. % %\seealso{format_table, kill_rect, insert_rect} % %!%- % public define format_table_rect() % ([[[col_sep], align], new_sep]) % { % variable args = __pop_args(_NARGS), buf = whatbuf(), % tmpbuf = make_tmp_buffer_name("*format_table_rect*"); % check_region(0); % exchange_point_and_mark(); % kill_rect(); % sw2buf(tmpbuf); % erase_buffer(); % paranoia % insert_rect(); % % format_table(__push_args(args)); % % % bob(); % % push_visible_mark(); % % eob(); % % goto_max_column(); % mark_buffer(); % copy_recyt(); % set_buffer_modified_flag(0); % % delbuf(tmpbuf); % % sw2buf(buf); % insert_rect(); % } % Compute number of columns that fit into \var{width} % when a list \var{a} is rearranged as aligned 2d array define compute_columns() % (a, width=SCREEN_WIDTH, col_sep_length=1) { variable a, width, col_sep_length; (a, width, col_sep_length) = push_defaults( ,SCREEN_WIDTH, 1, _NARGS); variable i, lines, cols = 0; % index, number of lines/columns variable table_width, field_width = array_map(Int_Type, &strlen, a); variable pad; % number of elements missing to make the reshape possible variable fw; % reshaped field width do { cols++; pad = cols-1 - (length(a)+cols-1) mod cols; lines = (length(a)+pad)/cols; % show("fields", length(a), "pad", pad, "lines", lines, "cols", cols); fw = [field_width, Int_Type[pad]]; reshape(fw, [cols, lines]); % show_string(strjoin2d(fw, " ", "\n", "r")); table_width=cols * col_sep_length; for (i=0; i < cols; i++) table_width += array_max(fw[i,*]); % show("width", width, "table_width", table_width); } while (table_width < width); return cols-1; % as we stopped when it did no longer fit } % arrange a 1d-array as a table (2d-array) with cols columns define list2table() % (a, cols=compute_columns(a)) { variable a, cols; (a, cols) = push_defaults(, 0, _NARGS); !if (cols) cols = compute_columns(a); variable pad=0, lines=0, pad_strings, table; if (length(a)) { pad = cols-1 - (length(a)+cols-1) mod cols; lines = (length(a)+pad)/cols; } % Transform the list to a 2d array with n columns pad_strings = String_Type[pad]; pad_strings[*] = ""; table = [a, pad_strings]; % pad to make reshapable reshape(table, [cols, lines]); table = array_transpose(table); return table; } provide("csvutils"); jedmodes-2.5.7/ch_table/0000755000175400017500000000000011325331413013337 5ustar mildegmjedmodes-2.5.7/ch_table/ch_table.sl0000644000175400017500000007322611325331361015454 0ustar mildegm% A "popup_buffer" with a table of characters % % Copyright (c) 2005 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % with additions by Dino Leonardo Sangoi. % % Version 1.0 first public version % 1.1 standardization: abandonment of helper-function custom % 2003-04-16 2.0 use readonly-map from bufutils (some new bindings) % code cleanup % 2003-03-07 2.1 ch_table calls ch_table_mode_hook instead of ct_mode_hook % 2004-11-27 2.2 new format of the INITIALIZATION block allows % auto-initialisation with make-ini >= 2.2 % 2005-11-07 2.3 changed _implements() to implements() % 2006-01-10 2.3.1 minor code cleanup % 2006-06-29 2.3.2 bugfix in ch_table: set_readonly(0) before erase_buffer() % 2006-10-05 2.3.3 bugfix in ct_insert_and_close(), return to calling buf % 2007-05-31 2.3.4 bugfix in ct_update: did mark too much if at eol, % disable dfa syntax highlighting in UTF8 mode to make % ch_table.sl UTF8 safe. % documentation for public functions % 2007-10-18 2.3.5 cosmetics (require() instead of autoloads, push_default()) % 2007-10-23 2.3.6 do not cache the dfa highlight table % 2007-12-20 2.3.7 implement Jörg Sommer's fix for DFA highlight under UTF-8 % 2008-01-21 2.4 variable upper limit, as unicode has more than 255 chars, % ch_table_unicode_block(), % new menu name Edit>Char Table, % menu popup with several "blocks" under UTF8, % do not mark the current char as region, % mode menu, % describe character (using unicode's NamesList.txt). % 2008-04-02 2.4.1 bugfix in ct_update(): skip lines 1...3, % Edit>Char_Tables menu popup for UTF8-enabled Jed, % re-order mode-menu, % only fit ch-table window if too small (avoids flicker), % Add "Musical Symbols" block. % Menu binding for describe_character (under Help) % ct_goto_char(): choose from all available chars, % switching unicode table if needed. % "active links" (i.e. goto given char if click on number) % 2008-07-23 2.4.2 better handling of missing NamesList.txt and % Blocks.txt files % 2008-07-29 2.5 Replace Chartable_Blocks_File and Chartable_NameList_File % with a common Chartable_Unicode_Data_Dir custom var. % Autogess value (with Debian defaults) if invalid. % 2008-11-06 2.5.1 Highlight NamesList.txt, % New public functions ct_list_unicode_blocks(), % ct_find_unicode_character, ct_list_unicode_characters(), % and describe_character() % 2008-12-16 2.5.2 Trim Edit>Char_Table menu % (use "List Unicode Blocks" for not so often needed blocks). % 2009-01-26 2.5.3 Better Fallback if Unicode Data files are missing % 2009-10-05 2.5.4 Insert to original buf after search with "find character". % 2009-12-08 2.5.5 Adapt to new require() syntax in Jed 0.99.19. % 2010-01-18 2.6 Make combining chars visible by NBSP as base char. % 2010-01-19 2.6.1 Fix ct_describe_character() before "holes" in Unicode. % Remove spurious debugging output % % % TODO: * apropos for character names and table names % % % Functions and Functionality % % ch_table() characters 000...255 % ch_table(min) characters min...255 % ch_table(min,max) characters min...max % special_chars() characters 160...255 % % - Arrow keys move by collumn % - copy the character to the calling buffer and close % - Mouse click goto character % - Double-click goto character, copy to calling buffer and close % - q close % % USAGE: % put in the jed_library_path and make available e.g. by a keybinding or % via the following menu entry (make-ini.sl >= 2.2 will do this for you) # autoload("ch_table", "ch_table.sl"); autoload("special_chars", "ch_table.sl"); autoload("ch_table->ct_menu_callback", "ch_table.sl"); autoload("describe_character", "ch_table.sl"); add_completion("special_chars"); static define ct_load_popup_hook(menubar) { variable pos = "&Key Macros", menu = "Global.&Edit"; if (_slang_utf8_ok) { menu_insert_popup(pos, menu, "Char &Table"); menu_set_select_popup_callback(menu+".Char &Table", &ch_table->ct_menu_callback); } else { menu_insert_item(pos, menu, "Char &Table", "special_chars"); } menu_insert_item("&Describe Key Bindings", "Global.&Help", "Describe &Character", "describe_character"); } append_to_hook("load_popup_hooks", &ct_load_popup_hook); # % Requirements % ------------ % from slsh library (should be also in the jed library path) autoload("glob", "glob"); % modes from http://jedmodes.sf.net #if (_jed_version > 9918) require("keydefs", "Global"); % from standard lib but not always loaded require("bufutils", "Global"); require("sl_utils", "Global"); #else require("keydefs"); % symbolic constants for many function and arrow keys require("bufutils"); % pop up buffer, rebind, close_buffer... require("sl_utils"); % small helpers #endif autoload("get_word", "txtutils"); % Name % ---- provide("ch_table"); try implements("ch_table"); catch NamespaceError: use_namespace("ch_table"); % Customisation % ------------- custom_variable("ChartableStartChar", 0); custom_variable("ChartableNumBase", 10); custom_variable("ChartableCharsPerLine", ChartableNumBase); custom_variable("ChartableTabSpacing", 5); % Unicode blocks listed in the Edit>Char_Tables popup custom_variable("Chartable_Tables", [ % "Basic &Latin", "Latin-&1 Supplement", % "Latin Extended-A", % "Latin Extended-B", % "&IPA Extensions", "&Greek and Coptic", "C&yrillic", % "&Hebrew", "General &Punctuation", "&Superscripts and Subscripts", % "&Currency Symbols", "&Arrows", "&Mathematical Operators", "Miscellaneous &Technical", % "Box &Drawing", % "&Block Elements", "&Geometric Shapes", "Miscellaneous &Symbols", % "Dingbats", % "&Musical Symbols" ]); %!%+ %\variable{Chartable_Unicode_Data_Dir} %\synopsis{Directory with Unicode data files} %\usage{variable Chartable_Unicode_Data_Dir = "~/.unicode")} %\description % Full path to a directory with local copies of the files % `Blocks.txt' and `NamesList.txt' from % http://unicode.org/Public/UNIDATA/ % containing the names and description of all Unicode blocks and % code points. %\notes % On Debian GNU/Linux, these files are provided by the packages perl-modules % (in /usr/share/perl/*/unicore/) or unicode-data (in /usr/share/unicode/). % If the specified dir is invalid but not the empty string "", these % locations are probed during the evaluation of ch_table.sl. %\seealso{ch_table, ct_describe_character, ch_table->ct_unicode_block} %!%- custom_variable("Chartable_Unicode_Data_Dir", "~/.unicode"); % Check for the unicode data dir from unicode-data and perl-modules if (andelse{Chartable_Unicode_Data_Dir != ""} {file_status(Chartable_Unicode_Data_Dir) != 2}) { private variable unidata_dir, unidata_dirs = ["/usr/share/unicode"]; % add versioned dir from perl-modules(failsave in case glob() is undefined) try unidata_dirs = [glob("/usr/share/perl/*/unicore"), unidata_dirs]; catch UndefinedNameError: ; foreach unidata_dir (unidata_dirs) if (file_status(unidata_dir) == 2) { Chartable_Unicode_Data_Dir = unidata_dir; break; } % show (unidata_dirs, Chartable_Unicode_Data_Dir); } % Global variables % ---------------- % diplay options private variable StartChar = ChartableStartChar; private variable EndChar = 255; private variable BlockNr = 1; % Index in UnicodeBlocks array private variable NumBase = ChartableNumBase; private variable CharsPerLine = ChartableCharsPerLine; % quasi constants private variable mode = "ch_table"; private variable listmode = "NamesList"; private variable Digits = "0123456789abcdef"; private variable hex = "[0-9A-F]"; % regexp for hexadecimal digit % List of unicode blocks % in UTF-8 mode this is extended via parse_unicode_block_file() later private variable UnicodeBlocks = [{0, 127, "Basic Latin"}, {128, 255, "Latin-1 Supplement"}]; % Unicode data files: private variable NamesList_File = path_concat(Chartable_Unicode_Data_Dir, "NamesList.txt"); private variable Blocks_File = path_concat(Chartable_Unicode_Data_Dir, "Blocks.txt"); % Combining Unicode chars private variable Combining_Chars = [[0x0300:0x036F], [0x0483:0x0489], [0x07EB:0x07F3], [0x135F ], [0x1B6B:0x1B73], [0x1DC0:0x1DE6], [0x1DFE:0x1DFF], [0x20D0:0x20F0], [0x2DE0:0x2DFF], [0x3099:0x309A], [0xA66F:0xA672], [0xA67C:0xA67D], [0xFE20:0xFE26], [0x101FD ], [0x1D165:0x1D169], [0x1D16D:0x1D172], [0x1D172:0x1D182], [0x1D185:0x1D18B], [0x1D1AA:0x1D1AD], [0x1D242:0x1D244] ]; % Functions % ========= static define ct_unicode_block(); % forward definition % Functions to revert a positive integer to a string representation % and vice versa static define int2string(i, base) { variable j, s = ""; variable digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; while (i) { j = i mod base; s = char(digits[j]) + s; i = (i - j) / base; } if (s == "") s = "0"; return s; } static define string2int(s, base) { variable v, r = 0, i = 0, c; while (s[i] > ' ') { c = toupper(s[i]); if (c >= 'A') v = c - 'A' + 10; else v = c - '0'; if ((v < 0) or (v >= base)) error("Invalid input (" + s + ")"); r = r * base + v; i++; } return r; } % Character description % --------------------- % return current character (translating TAB, NL and ESC) private define ct_what_char() { variable s; if (looking_at("\t"R)) return '\t'; if (looking_at("\n"R)) return '\n'; if (looking_at("\e"R)) return '\e'; if (looking_at("\x{00A0}\t")) % NBSP without combining char return what_char(); if (looking_at("\x{00A0}")) { % NBSP [+ combining char] % go to the combining char (go_right|_left skip combining chars): skip_chars("\x{00A0}"); bskip_chars("^\x{00A0}"); return what_char(); } return what_char(); } % insert character description into current buffer static define ct_describe_character(ch) { variable ch_nr = sprintf("%04X", ch); variable ch_nr1 = sprintf("%04X", ch)[[:0]]; if (-1 == insert_file_region(NamesList_File, ch_nr, ch_nr1)) vinsert("No description.\n\n" + "Check the variable `Chartable_Unicode_Data_Dir' \n" + "(current value: \"%s\")\n", Chartable_Unicode_Data_Dir); call("backward_delete_char"); % del last newline while (bol, looking_at_char('@')) { delete_line(); call("backward_delete_char"); % del last newline } } public define describe_character() % (ch=what_char) { variable ch = push_defaults(what_char(), _NARGS); popup_buffer("*character description*"); set_readonly(0); erase_buffer(); vinsert("Character '%c' (%d, 0x%X)\n", ch, ch, ch); ct_describe_character(ch); bob(); fit_window(get_blocal("is_popup", 0)); call_function("view_mode"); use_syntax_table(listmode); % "active links" set_buffer_hook("mouse_up", "ch_table->ct_active_link_hook"); } static define ct_update() { % Ensure point is in char table % normalize position bskip_chars("^\t"); % top if (what_line() < 3) goto_line(3); % left if (bolp) () = fsearch("\t"); % skip empty slots while (looking_at_char('\t')) go_right_1(); % bottom push_spot(); variable too_low = not(bol_fsearch_char('-')); pop_spot(); if (too_low) { () = bol_bsearch_char('-'); bskip_chars("^\t"); } % Get current char variable ch = ct_what_char(); % Update description push_spot(); set_readonly(0); % delete description eob(); push_mark(); () = bol_bsearch_char('-'); go_down_1(); del_region(); % write new one vinsert("'%c' ", ch); ct_describe_character(ch); if (what_line() > window_info('r')) fit_window(get_blocal("is_popup", 0)); set_buffer_modified_flag(0); set_readonly(1); pop_spot(); % give the Unicode-number of current char in the status line variable name = UnicodeBlocks[BlockNr-1][2]; variable fmt = " Block %d: %s '%c' (%d, 0x%X)"; set_status_line(sprintf(fmt, BlockNr, name, ch, ch, ch), 0); % write again to minibuffer (as messages don't persist) vmessage("Goto char (0 ... %s, base: %d): ", int2string(UnicodeBlocks[-1][1], NumBase), NumBase); } % Movement functions % ------------------ % Move only in the ch_table, skipping the tabs static define ct_up() { call("previous_line_cmd"); ct_update; } static define ct_down() { call("next_line_cmd"); ct_update(); } static define ct_right() { () = fsearch("\t"); go_right_1(); % skip_chars("\t"); ct_update(); } static define ct_left() { () = bsearch("\t"); bskip_chars("^\t"); if(bolp) call("previous_char_cmd"); ct_update; } static define ct_page_up() { call("page_up"); ct_update(); } static define ct_page_down() { call("page_down"); ct_update(); } static define ct_bob() { bob(); ct_update(); } % parse Unicode Block description file static define parse_unicode_block_file(file) { % read file into array of lines variable line, lines = arrayread_file(file); % show(lines); % parse the lines variable block, blocks = {}; variable n, beg, end, name; foreach line (lines) { n = sscanf (line, "%x..%x; %[-a-zA-Z0-9 ]", &beg, &end, &name); % vshow("%s, [%X, %X]", name, beg, end); if (n == 3) list_append(blocks, {beg, end, name}); } return blocks; } % insert current char into calling buffer static define ct_insert() { variable ch = ct_what_char(); pop2buf(get_blocal_var("calling_buf")); insert_char(ch); } % insert current char and return to char table static define ct_insert_and_return() { variable buf = whatbuf(); ct_insert(); pop2buf(buf); } static define ct_insert_and_close() { ct_insert_and_return(); close_buffer(); } % goto character by input of Unicode-Nr. static define ct_goto_char() % ([ch]) { !if (bufferp("*ch_table*")) ct_unicode_block(1); else if (whatbuf() != "*ch_table*") { sw2buf("*ch_table*"); % popup_buffer(); } variable max_ch = UnicodeBlocks[-1][1]; !if (_NARGS) { variable msg = sprintf("Goto char (0 ... %s, base: %d): ", int2string(max_ch, NumBase), NumBase); variable str = read_mini(msg, "", char(LAST_CHAR)); string2int(str, NumBase); % push on stack } variable ch = (); % get from stack if( (ch < 0) or (ch > max_ch) ) verror("%s not in range (0 ... %s)", int2string(ch, NumBase) , int2string(max_ch, NumBase)); % switch unicode block if ch is outside of currently displayed table if( (ch < StartChar) or (ch > EndChar) ) { variable n; for (n=0; n ch) break; } ct_unicode_block(n); } else ct_bob; loop(ch - StartChar) { skip_chars("^\t"); go_right_1(); } ct_update(); } % insert the table into the buffer and fit window size static define insert_ch_table() { variable i, j; % Set TAB for buffer TAB = ChartableTabSpacing; while (TAB * CharsPerLine > WRAP) TAB--; % j = lengt of number on first column j = strlen(int2string(EndChar+1-CharsPerLine, NumBase))+1; if (j < TAB) j = TAB; % heading vinsert("[% *d]", j-2, NumBase); for (i=0; ict_goto_char", char(Digits[i]), mode); % adapt CharsPerLine, if it matched NumBase if (CharsPerLine == NumBase) CharsPerLine = numbase; % set private variable NumBase = numbase; } % change the number base static define ct_change_base() { variable num_base = push_defaults( ,_NARGS); % optional argument if (num_base == NULL) num_base = integer(read_mini("New number base (2..16):", "", "")); use_base(num_base); set_readonly(0); erase_buffer(); insert_ch_table(); set_readonly(1); } % Mode menu % --------- % menu popup for unicode blocks static define ct_menu_callback(menu) { variable block, block_nr = 0, entry, entry_nr; variable selected_blocks = array_map(String_Type, &str_delete_chars, Chartable_Tables, "&"); % show(selected_blocks); foreach block (UnicodeBlocks) { block_nr++; entry_nr = wherefirst(block[2] == selected_blocks); if (entry_nr == NULL) continue; entry = Chartable_Tables[entry_nr]; % show(entry); menu_append_item(menu, entry, &ct_unicode_block, block_nr); } menu_append_separator(menu); menu_append_item(menu, "List Unicode &Blocks", "ct_list_unicode_blocks"); menu_append_item(menu, "&Find Character", "ct_find_unicode_character"); } private define ch_table_menu(menu) { % select unicode block if (_slang_utf8_ok) { menu_append_item(menu, "&Find Character", "ct_find_unicode_character"); menu_append_item(menu, "&Describe Character", "describe_character"); menu_append_item(menu, "&List Characters", "ct_list_unicode_characters"); menu_append_separator(menu); menu_append_item(menu, "List &Blocks", "ct_list_unicode_blocks"); menu_append_item(menu, "Next Block", "ch_table->ct_next_block"); menu_append_item(menu, "Previous Block", "ch_table->ct_previous_block"); menu_append_separator(menu); } menu_append_item(menu, "Scroll Up", "ch_table->ct_page_up"); menu_append_item(menu, "Scroll Down", "ch_table->ct_page_down"); % menu_append_item(menu, "&Describe character", "describe_character"); menu_append_item(menu, "&Insert", "ch_table->ct_insert"); menu_append_item(menu, "Insert and &return", "ch_table->ct_insert_and_return"); menu_append_item(menu, "Insert and &close", "ch_table->ct_insert_and_close"); menu_append_popup(menu, "&Number base"); variable popup = menu + ".&Number base"; menu_append_item(popup, "&Binary", &ct_change_base, 2); menu_append_item(popup, "&Octal", &ct_change_base, 8); menu_append_item(popup, "&Decimal", &ct_change_base, 10); menu_append_item(popup, "&Hexadecimal", &ct_change_base, 16); menu_append_item(popup, "&Custom", "ch_table->ct_change_base"); menu_append_item(menu, "&Quit", "close_buffer"); } % colorize numbers create_syntax_table(mode); define_syntax("0-9", '0', mode); set_syntax_flags(mode, 0); #ifdef HAS_DFA_SYNTAX % numbers in first column dfa_define_highlight_rule("^ *[0-9A-Z]+\t", "number", mode); % header line dfa_define_highlight_rule("^\[.*$"R, "number", mode); % separator dfa_define_highlight_rule("^----+", "number", mode); % unicode numbers in description dfa_define_highlight_rule(" $hex$hex$hex$hex$hex?"$, "keyword", mode); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); enable_dfa_syntax_for_mode(mode); #endif % Highlight NamesList.txt % ----------------------- create_syntax_table(listmode); % define_syntax("0-9", '0', listmode); set_syntax_flags(listmode, 0); #ifdef HAS_DFA_SYNTAX % Unicode Numbers at bol dfa_define_highlight_rule("^$hex+"$, "keyword", listmode); % ALL CAPITAL unicode names dfa_define_highlight_rule("[A-Z][A-Z\\- ]+$", "keyword1", listmode); % unicode numbers in description dfa_define_highlight_rule("$hex$hex$hex$hex"$, "url", listmode); % Comments dfa_define_highlight_rule("^@.*$"R, "comment", listmode); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 % dfa_define_highlight_rule("[^ -~]+", "normal", listmode); dfa_build_highlight_table(listmode); enable_dfa_syntax_for_mode("view"); #endif % Keybindings % ----------- !if (keymap_p(mode)) make_keymap(mode); % numerical input for goto_char is dynamically defined by function ct_use_base definekey("ch_table->ct_up", Key_Up, mode); definekey("ch_table->ct_down", Key_Down, mode); definekey("ch_table->ct_right", Key_Right, mode); definekey("ch_table->ct_left", Key_Left, mode); definekey("bol; ch_table->ct_right;", Key_Home, mode); definekey("eol; ch_table->ct_update;", Key_End, mode); definekey("bob(); ch_table->ct_update;", "<", mode); definekey("eob(); ch_table->ct_update;", ">", mode); definekey("ch_table->ct_page_up", Key_BS, mode); definekey("ch_table->ct_page_down;", " ", mode); definekey("ch_table->ct_previous_block", Key_PgUp, mode); definekey("ch_table->ct_next_block;", Key_PgDn, mode); definekey("ch_table->ct_unicode_block(0)", Key_Ctrl_PgUp, mode); definekey(sprintf("ch_table->ct_unicode_block(%d)", length(UnicodeBlocks)-1), Key_Ctrl_PgDn, mode); definekey("ch_table->ct_change_base()", "N", mode); % generic case definekey("ch_table->ct_change_base(2)", "B", mode); definekey("ch_table->ct_change_base(8)", "O", mode); definekey("ch_table->ct_change_base(10)", "D", mode); definekey("ch_table->ct_change_base(16)", "H", mode); definekey("close_buffer", "\e\e\e", mode); % Escape definekey("ch_table->ct_insert_and_close", "^M", mode); % Return definekey("ct_list_unicode_blocks", "b", mode); definekey("ch_table->ct_describe_character", "d", mode); definekey("ct_find_unicode_character", "f", mode); definekey("ch_table->ct_insert", "i", mode); definekey("close_buffer", "q", mode); definekey("ch_table->ct_insert_and_return", "r", mode); definekey("ct_list_unicode_characters", "l", mode); definekey("help_message", "?", mode); set_help_message( ":Insert q:Quit, B:Binary, O:Octal, D:Decimal, H:hex N:Number_Base", mode); % Mouse bindings % -------------- % goto "link" (codepoint-number in char description) static define ct_active_link_hook(line, col, but, shift) { variable nr, word = get_word("0-9A-Z"); variable is_nr = sscanf (word, "%x", &nr); !if (((strlen(word) == 4) or (strlen(word) == 5)) and is_nr) return -1; % vshow("%d == %x", nr, nr); switch (whatbuf()) { case "*character description*": describe_character(nr); } { case "*Unicode Character Names*": bob(); bol_fsearch(word);} { ct_goto_char(nr); } return 1; } static define ct_mouse_up_hook(line, col, but, shift) { if (ct_active_link_hook(line, col, but, shift) == -1) ct_update; % move point inside character table return (1); } static define ct_mouse_2click_hook(line, col, but, shift) { ct_insert(); return (0); } % main function % ------------------------------------------------------ %!%+ %\function{ch_table} %\synopsis{} %\usage{ch_tablech_table(min=ChartableStartChar, max=255)} %\description % Display characters in the range \var{min} ... \var{max} % in a table with indizes indicating the "char-value". %\seealso{special_chars, digraph_cmd, Chartable_Unicode_Data_Dir} %!%- public define ch_table() % (min = ChartableStartChar, max=255) { % (re) set static variables variable min, max; (min, max) = push_defaults(ChartableStartChar, 255, _NARGS); StartChar = min; EndChar = max; use_base(NumBase); % Pop up ch_table in upper part (preferably) if (nwindows() - MINIBUFFER_ACTIVE == 1) % Scroll current line to lower half of window recenter (3 * window_info('r') / 4); % else if (window_info('t') <= 2) { % % make sure we are in lower window % variable buf = whatbuf(); % otherwindow(); % sw2buf(buf); % } update_sans_update_hook(1); popup_buffer("*ch_table*"); set_readonly(0); erase_buffer(); insert_ch_table(); set_readonly(1); set_mode(mode, 0); use_keymap(mode); use_syntax_table(mode); mode_set_mode_info(mode, "init_mode_menu", &ch_table_menu); set_buffer_hook("mouse_up", &ct_mouse_up_hook); set_buffer_hook("mouse_2click", &ct_mouse_2click_hook); run_mode_hooks(mode + "_mode_hook"); } %!%+ %\function{special_chars} %\synopsis{Open a table of special characters for insertion} %\usage{special_chars()} %\description % Display special characters of the current font (characters 160...255 in % 1-byte encodings) in a table with indizes indicating the "char-value". % % Keybindings: % % Arrow keys move by collumn and mark the character % [Enter] copy the character to the calling buffer and close % Mouse click goto character and mark % Double-click goto character, copy to calling buffer and close % q close %\seealso{ch_table, digraph_cmd} %!%- public define special_chars() { BlockNr = 2; ch_table(160); } % List by Unicode block % -------------------------------- % Open a Unicode block (see Blocks.txt) by block-number (starting at 1) static define ct_unicode_block(n) { variable min = UnicodeBlocks[n-1][0], max = UnicodeBlocks[n-1][1]; BlockNr = n; ch_table(min, max); } % Block selection static define ct_next_block() { if (BlockNr >= length(UnicodeBlocks)) error("already at last block"); ct_unicode_block(BlockNr+1); } static define ct_previous_block() { if (BlockNr <= 1) error("already at first block"); ct_unicode_block(BlockNr-1); } % List Unicode blocks % ------------------- % go to Unicode block of current line static define ct_goto_listed_block() { variable block_nr = what_line(); close_buffer(); ct_unicode_block(block_nr); } %!%+ %\function{ct_list_unicode_blocks} %\synopsis{List Unicode blocks by name} %\usage{ct_list_unicode_blocks()} %\description % List Unicode blocks by name in a "Unicode Blocks" buffer. % Pressing Enter will open the current block with \sfun{ch_table}. %\seealso{ch_table, ct_list_unicode_characters} %!%- public define ct_list_unicode_blocks() { variable block; popup_buffer("*Unicode Blocks*"); if (bobp() and eobp()) { foreach block (UnicodeBlocks) { vinsert(" %s\n", block[2]); } call("backward_delete_char"); set_line_number_mode(1); bob(); call_function("view_mode"); set_buffer_hook("newline_indent_hook", "ch_table->ct_goto_listed_block"); } goto_line(BlockNr); message("Press [Return] to open Block"); } % List all Unicode characters (NamesList.txt) % ------------------------------------------- % go to Unicode character described at current line(s) static define ct_goto_listed_char() { variable buf = whatbuf(); variable calling_buf = get_blocal_var("calling_buf", ""); push_spot(); % Go to the number eol(); % alternative: if(bolp) go_left_1(); !if (re_bsearch("^$hex"$)) return; % Read and convert number variable nr, word = get_word("0-9A-F"); variable is_nr = sscanf (word, "%x", &nr); pop_spot(); % Jump to given character % show(nr, word); if (is_nr) { ct_goto_char(nr); if (get_blocal_var("calling_buf", "") == buf) set_blocal_var(calling_buf, "calling_buf"); delbuf(buf); } } %!%+ %\function{ct_list_unicode_characters} %\synopsis{Open description file for Unicode characters} %\usage{ct_list_unicode_characters()} %\description % Open the NamesList.txt file in a buffer % (so that the common search and filter operations work). % % Pressing enter will go to the described character in the char-table. % Clicking on a reference will jump to the referenced character. %\seealso{ch_table, ct_find_unicode_character, ct_list_unicode_blocks} %\seealso{Chartable_Unicode_Data_Dir} %!%- public define ct_list_unicode_characters() { !if (bufferp("*ch_table*")) ct_unicode_block(1); if (whatbuf() == "*ch_table*") otherwindow(); popup_buffer("*Unicode Character Names*"); if (bobp() and eobp()) { () = insert_file(NamesList_File); bob(); bol_fsearch("0000"); call_function("view_mode"); set_buffer_hook("newline_indent_hook", "ch_table->ct_goto_listed_char"); set_buffer_hook("mouse_up", "ch_table->ct_active_link_hook"); use_syntax_table(listmode); } } % Incremental search in the NamesList unicode character description public define ct_find_unicode_character() { ct_list_unicode_characters(); bob(); bol_fsearch("0000"); isearch_forward(); } % Initialization % -------------- if (_slang_utf8_ok) { if (file_status(Blocks_File) == 1) UnicodeBlocks = parse_unicode_block_file(Blocks_File); else vmessage("Failed to open `Chartable_Blocks_File' %s", Blocks_File); } % show(UnicodeBlocks); jedmodes-2.5.7/hyperhelp/0000755000175400017500000000000011146322062013577 5ustar mildegmjedmodes-2.5.7/hyperhelp/help.hlp0000664000175400017500000000115310214064425015237 0ustar mildegm Help commands: Navigation: Close ---------------------- ------------------------- -------- a Apropos Return Help for word q Close d Grep Definition Tab Next link i Insert word f Describe Function Shift Tab Previous link h Basic Help I Info Reader History: k Show Key ------------------------- s Set Variable Alt Right Next topic u Man page (Unix only) Alt Left Previous topic v Describe Variable w Where is ... ? This Help jedmodes-2.5.7/hyperhelp/help.sl0000644000175400017500000012750311146322013015073 0ustar mildegm% help.sl % % Hypertext help browser as drop-in replacement for the standard help.sl % % Copyright © 2006 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % -------- % % 1.0 - added Guido Gonzatos function_help (renamed to % help_for_word_at_point()) % - when no documentation is available, give message in minibuffer % instead of popping up a help window (customizable) % - help-mode % 1.1 - set variable % - grep the definition of a library function % - mini-help: a one-line help string for display in the minibuffer % - help_for_help (aka help.hlp) % - documentation of global functions % 1.2 - use blocal_hooks for mode-dependent context help % - better formatting of apropos output (optional, with csvutils.sl) % - showkey with Key_* Variables % - Help_Topic type replaced by array % - save version of set_variable: ask if type changed % 1.2.1 - bugfix for describe_bindings and describe_mode % 1.2.2 - new binding: i = insert_word_and_close, I = info_mode % - adapted to changes in csvutils.sl(1.0) % 1.2.3 - describe_mode: if a .hlp list is in the jed_library_path, % do help(.hlp). This way non-standard modes can supply % online-help. % - siplified due to change in csvutils.sl(1.1) % 1.3 - use readonly-map from view.sl % - describe_mode: one more fallback: if no online-help available % nor a mode.hlp file, use help_message() (from bufutils) % 1.3.1 - bugfix in grep_definition() % 1.4 - str = extract_mini_doc(str) now takes a string argument % instead of working on a buffer % 1.4.1 - added provide("hyperhelp"), so other modes depending on the % "hyperhelp"-version of help.sl can do require("hyperhelp") % 1.4.2 - window-bugfix in grep_definition: the w32 subshell needs an % additional set of \\ to escape the quotes (Thomas Koeckritz) % (TODO: how is this on DOS?) % 1.4.3 - grep_definition() adapted to new grep() command % (needs grep.sl >= 0.9.4) % 1.4.4 2004-11-09 grep_definition() expanded for variables (experimental) % corrected typo Help_file -> Help_File % 1.5 2005-04-01 new fun grep_slang_sources() "outsourced" from grep_definition() % 1.6 2005-04-11 dfa highlighting to reduce "visual clutter" (Paul Boekholt) % help_search(): Search for a string in on-line documentation (PB) % removed where_is_word_at_point(), as where_is() already % has word_at_point as default. % 1.6.1 2005-11-01 bugfix in describe_bindings() % 1.6.2 2005-11-08 changed _implements() to implements() % 1.6.3 2005-11-22 hide functions with autoloads in site.sl from make_ini() % 1.7 2006-01-25 rewrite of help history feature using #ifexists % removing the custom_variable `Help_with_history' % provide("hyperhelp") so modes depending on stuff not in % the standard help could require("hyperhelp") % 1.8 2006-03-02 new function help->get_mini_help() % use the internal doc files list for Jed >= 0.99.17 % (this means that the source file name is no longer % appended to the help text) % 1.8.1 2006-09-07 Added Slang 2 keywords for exception handling % fix help-string for internal functions % fix help_display_list() % 1.8.2 2006-09-21 trim buffer in help_display_list() % patches by Paul Boekholt: % append Jed_Doc_Files to doc_files instead of overwriting % keybindings can now also be references, adapt showkey() % sort inherited and new keys in describe_bindings() % (Jörg Sommer) % 1.9 2007-04-19 edited help_string, removed use of prompt_for_argument() % fix in help_search(), handle "namespace->object" notation % 1.9.1 2007-05-31 bugfix in where_is(), removed spurious line % 1.9.2 2007-10-01 optional extensions with #if ( ) % 1.9.3 2007-10-04 no DFA highlight in UTF-8 mode (it's broken) % 1.9.4 2007-10-15 re-enable DFA highlight, as it is rather unlikely that % help text contains multibyte chars (hint P. Boekholt) % 1.9.5 2007-10-18 re-introduce the sprint_variable() autoload % 1.9.6 2007-12-20 add Jöörg Sommer's fix for DFA highlight under UTF-8 % new highlight rules for keyword and headings % 1.9.7 2008-05-05 use call_function() instead of runhooks() % % Usage % ----- % % Place help.sl, txtutils.sl, bufutils.sl (and optional grep.sl, filelist.sl, % and circle.sl) in the "jed library path" (use get_jed_library_path() to see % what your "jed library path" is) % % (I recommend a separate directory for the local extensions -- % so they won't be overwritten by upgrading to a new jed version. % See http://jedmodes.sf.net/mode/libdir/ for a more info on how to do this) % % To increase the comfort, you can replace the "help_prefix" binding (^H in % emacs emulation) with menu_select_menu("Global.&Help") so it pops up the % Help menu for better visual feedback or define your own help-map, e.g. % % % ^H map: Help ... % setkey("apropos", "^HA"); % setkey("grep_definition", "^HD"); % setkey("describe_function", "^HF"); % setkey("help", "^HH"); % setkey("info_mode", "^HI"); % setkey("showkey", "^HK"); % setkey("describe_mode", "^HM"); % setkey("set_variable", "^HS"); % setkey("unix_man", "^HU"); % setkey("describe_variable", "^HV"); % setkey("where_is", "^HW"); % % (these bindings will then show up in the Help menu) and optionally bind % another key to open the help menu, e.g. % % setkey("menu_select_menu(\"Global.&Help\")", Key_F1); % Jed >= 99.16 % or % setkey("ungetkey('h'); call(\"select_menubar\")", Key_F1); % Jed <= 99.15 % % you will need autoloads for all functions you want to bind % that are not present in the standard help.sl # _autoload("help_for_help", "help", "grep_definition", "help", "grep_slang_sources", "help", "context_help", "help", "help_for_word_at_point", "help", "set_variable", "help", "help_search", "help", 7); _add_completion("grep_definition", "set_variable", "help_search", 3); define hyperhelp_load_popup_hook(menubar) { menu_insert_item("&Info Reader", "Global.&Help", "&Grep Definition", "grep_definition"); menu_insert_item("&Info Reader", "Global.&Help", "&/ Search in Help Docs", "help_search"); menu_insert_separator("&Info Reader", "Global.&Help"); } append_to_hook ("load_popup_hooks", &hyperhelp_load_popup_hook); # % Requirements % ------------ % Standard modes, distributed with jed but not loaded by default autoload("add_keyword_n", "syntax.sl"); require("keydefs"); % Functions from utility modes at http://jedmodes.sourceforge.net/ require("view"); % readonly-keymap autoload("run_function", "sl_utils"); autoload("get_blocal", "sl_utils"); autoload("push_array", "sl_utils"); autoload("push_defaults", "sl_utils"); autoload("get_word", "txtutils"); autoload("bget_word", "txtutils"); autoload("popup_buffer", "bufutils"); autoload("close_buffer", "bufutils"); autoload("strread_file", "bufutils"); autoload("set_help_message", "bufutils"); autoload("help_message", "bufutils"); autoload("string_get_match", "strutils"); autoload("strsplit", "strutils"); % >= 1.6 % Optional modes from http://jedmodes.sourceforge.net/ % (not really needed but nice to have) % % Detection of files fails with preparse for SLang1 (leaves '^A' on stack) ! % formatting of apropos list #if (expand_jedlib_file("csvutils.sl") != "") autoload("list2table", "csvutils.sl"); autoload("strjoin2d", "csvutils.sl"); % dummy autoload for byte-compiling #if (autoload("list2table", "csvutils.sl"), 1) #endif #endif % Help History: walk for and backwards in the history of help items #if (expand_jedlib_file("circle.sl") != "") require("circle"); % dummy autoload for byte-compiling #if (autoload("create_circ", "circle"), 1) #endif #endif % sprint_variable(): nice formatting of compound data types #if (expand_jedlib_file("sprint_var.sl") != "") autoload("sprint_variable", "sprint_var"); #endif % Announcement and namespace % -------------------------- % This help browser (with "hyperlinks") is a drop-in replacement for the % standard help. Modes depending on extensions in this file should % require "hyperhelp", e.g. via:: % % #if (_jed_version < 9919) % require("hyperhelp", "help.sl"); % #else % new syntax introduced in Jed 0.99.19 % require("hyperhelp", "Global", "help.sl"); % #endif provide("help"); provide("hyperhelp"); implements("help"); private variable mode = "help"; % Custom variables % ---------------- % How big shall the help window be maximal % (set this to 0 if you don't want it to be fitted) custom_variable("Help_max_window_size", 0.7); % for one line help texts, just give a message instead of open up a buffer custom_variable("Help_message_for_one_liners", 0); % Do you want full- or mini-help with help_for_word_at_point? custom_variable("Help_mini_help_for_word_at_point", 0); % The standard help file to display with help(). custom_variable("Help_File", "generic.hlp"); % Variables % --------- % valid chars in function and variable definitions static variable Slang_word_chars = "A-Za-z0-9_"; % the name of the syntax table for help listings (apropos, help_search) private variable helplist = "helplist"; % The symbolic names for keystrings defined in keydefs.sl % filled when needed by expand_keystring() private variable Keydef_Keys; static variable current_topic; % ["fun", "subject"] % adapt help-message (defined in site.sl) extended help help_for_help_string = "a:Apropos f:Function h:Help k:Key q:Quit u:Unix-man v:Var w:Where /:Search"; set_help_message(help_for_help_string, mode); % reserved keywords, taken from Klaus Schmidt's sltabc %{{{ static variable Keywords = [ "ERROR_BLOCK", % !if not used here "EXECUTE_ERROR_BLOCK", % from syntax table "EXIT_BLOCK", "NULL", % from syntax table "USER_BLOCK0", "USER_BLOCK1", "USER_BLOCK2", "USER_BLOCK3", "USER_BLOCK4", "__tmp", "_for", "abs", "and", "andelse", "break", "case", "catch", "chs", "continue", "define", "do", "do_while", "else", "exch", "finally", "for", "foreach", "forever", "if", "loop", "mod", "mul2", "not", "or", "orelse", "pop", "private", "public", "return", "shl", "shr", "sign", "sqr", "static", "struct", "switch", "throw", "try", "typedef", "using", "variable", "while", "xor" ]; %}}} % backwards compatibility: feed Jed_Doc_Files to the internal doc files list #ifexists set_doc_files #ifexists Jed_Doc_Files % might become obsoleted in 0.99.19 private variable docfile; foreach (strchop(Jed_Doc_Files, ',', 0)) { docfile=(); !if (length(where(docfile == get_doc_files()))) add_doc_file(docfile); } #endif #endif % Auxiliary Functions % ------------------- % forward declarations public define help_mode(); static define help_for_object(); static define read_object_from_mini(prompt, default, flags) { if (MINIBUFFER_ACTIVE) return; variable objs = _apropos("Global", "", flags); objs = strjoin(objs[array_sort (objs)], ","); return read_string_with_completion(prompt, default, objs); } public define read_function_from_mini(prompt, default) { return read_object_from_mini(prompt, default, 0x3); } public define read_variable_from_mini(prompt, default) { return read_object_from_mini(prompt, default, 0xC); } % Return function or variable object at cursor position as string % works also for static objects in "namespace->object" notation static define get_object() { mark_word(Slang_word_chars, -1); if (looking_at("->")) { go_right(2); skip_chars(Slang_word_chars); } exchange_point_and_mark(); if (blooking_at("->")) { go_left(2); bskip_chars(Slang_word_chars); } exchange_point_and_mark(); return bufsubstr(); } % from sltabc.sl by Klaus Schmidt: filter array by regexp pattern private define re_filter(a, pat) { variable i = array_map(Integer_Type, &string_match, a, pat, 1); return a[where(i)]; } % History #ifexists create_circ variable Help_History = create_circ(Array_Type, 30, "linear"); define previous_topic() { call_function(push_array(circ_previous(Help_History))); } define next_topic() { call_function(push_array(circ_next(Help_History))); } #endif % Open a help buffer, insert str, set to help mode, and add to history list define help_display(str) { % if help_str is just one line, display in minibuffer if (Help_message_for_one_liners and is_substr(str, "\n") == 0) return message(str); popup_buffer("*help*", Help_max_window_size); set_readonly(0); erase_buffer(); TAB = TAB_DEFAULT; % in case it is set differently by apropos... insert(str); bob(); fit_window(get_blocal("is_popup", 0)); help_mode(); #ifexists create_circ if (length(where(current_topic != circ_get(Help_History)))) circ_append(Help_History, @current_topic); #endif } static define help_display_list(a) { #ifexists list2table % insert as formatted table (using csvutils.sl) a = list2table(a); help_display(strjoin2d(a, " ", "\n", "l")); set_readonly(0); trim_buffer(); #else % align columns by setting TAB help_display(strjoin(a, "\n")); set_readonly(0); buffer_format_in_columns(); fit_window(get_blocal("is_popup", 0)); #endif % define_blocal_var("Word_Chars", Slang_word_chars + "->"); use_syntax_table(helplist); set_buffer_modified_flag(0); set_readonly(1); } % Basic Help % ---------- %!%+ %\function{help} %\synopsis{Pop up a window containing a help file.} %\usage{help(help_file=Help_File)} %\description % Displays help_file in the help buffer. % The file read in is given by the optional argument or the % (custom) variable \var{Help_File}. %\seealso{help_for_help, help_mode, Help_File} %!%- public define help() % (help_file=Help_File) { variable help_file; help_file = push_defaults(Help_File, _NARGS); current_topic = [_function_name, help_file]; variable path = help_file; !if (path_is_absolute (path)) path = expand_jedlib_file(path); if (file_status(path) != 1) verror ("Help error: File %s not found", help_file); % get the file and display in the help buffer help_display(strread_file(path)); } %!%+ %\function{help_for_help} %\synopsis{Display the help for help.} %\usage{help_for_help()} %\description % Displays help.hlp in the help buffer. %\seealso{help, help_mode} %!%- define help_for_help() {help("help.hlp");} %!%+ %\function{apropos} %\synopsis{List all defined objects that match a regular expression} %\usage{apropos ([pattern])} %\description % Apropos searches for defined functions and variables in the % global namespace that match a given regular expression. If the % optional search-string is missing, the user will be prompted for % a pattern in the minibuffer. %\seealso{_apropos, help_mode, describe_function, describe_variable} %!%- public define apropos() % ([pattern]) { !if (_NARGS) read_mini("apropos:", get_object(), ""); % push to stack variable pattern = (); variable namespace, namespaces, namespace_pattern, object_pattern, objects = String_Type[0]; if (is_substr(pattern, "->")) { namespace_pattern = strsplit(pattern, "->")[0]; object_pattern = strsplit(pattern, "->")[-1]; } else { namespace_pattern = "Global"; object_pattern = pattern; } namespaces = re_filter(_get_namespaces(), namespace_pattern); foreach namespace (namespaces) { if (namespace == "Global") objects = [objects, _apropos(namespace, object_pattern, 0xF)]; else objects = [objects, namespace + "->" + _apropos(namespace, object_pattern, 0xF)]; } vmessage ("Found %d matches.", length(objects)); !if (length(objects)) objects = ["No results for \"" + pattern + "\""]; current_topic = [_function_name, pattern]; help_display_list(objects[array_sort(objects)]); } % Search for \var{str} in the internal doc files list (or \var{Jed_Doc_Files}) define _do_help_search(str) { variable result = String_Type[100], i=0; !if(strlen(str)) error("nothing to search for"); variable this_str, strs = strchop(str, ' ', '\\'); variable docfile, matches_p; variable fp, buf="", pos=1, buffer, beg=0, len=0, entry; foreach ( #ifexists get_doc_files % get_doc_files() is not defined in jed <= 99.16 get_doc_files() #else strchop(Jed_Doc_Files, ',', 0) #endif ) { docfile=(); fp = fopen(docfile, "r"); if (fp == NULL) continue; forever { % read a help entry in chunks of 1000 bytes if (string_match(buf, "\n--*\n", pos)) { (beg, len) = string_match_nth(0); } else { buf = buf[[pos-1:]]; pos = 1; #ifnexists _slang_utf8_ok % #if (_slang_version < 2000) doesnot preparse if (-1 == fread(&buffer, Char_Type, 1000, fp)) #else if (-1 == fread_bytes(&buffer, 1000, fp)) #endif break; buf +=buffer; continue; } entry=buf[[pos-1:beg]]; matches_p=1; foreach (strs) { this_str=(); !if (is_substr(entry, this_str)) matches_p=0; } if (matches_p) { result[i]=string_get_match(entry, "[^\n]+\n"); i++; if (i==100) return result; } pos=beg+len; if(feof(fp)) break; } } !if (i> 0) return @String_Type[0]; return result[[:i-1]]; } %!%+ %\function{help_search} %\synopsis{Search for \var{str} in the \var{Jed_Doc_Files}} %\usage{help_search([str])} %\description % This function does a full text search in the online help documents % and returns the function/variable names where \var{str} occures in % the help text. %\seealso{apropos, describe_function, describe_variable, Jed_Doc_Files} %!%- public define help_search() % ([str]) { !if (_NARGS) read_mini("Search in help docs:", "", ""); % push to stack variable str = (); variable list = _do_help_search(str); vmessage ("Found %d matches.", length(list)); !if (length(list)) list = ["No results for \"" + str + "\""]; current_topic = [_function_name, str]; help_display_list(list[array_sort(list)]); } % Show Key % -------- % Convert string into array of 1-char strings. % % In contrast to bstring_to_array() or foreach str), the array elements are % of String_Type and in UTF-8 can contain several bytes. define string_to_array(str) { variable i, a = String_Type[strlen(str)]; for (i = 0; i = 0.99.17, we do not determine the source file name % help_str += sprintf("\n\n(Obtained from file %s)", file); } return help_str; } %!%+ %\function{describe_function} %\synopsis{Give help for a jed-function} %\usage{describe_function ()} %\description % Display the online help for \var{function} in the % help buffer. %\seealso{describe_variable, help_for_help, help_mode} %!%- public define describe_function () % ([fun]) { !if (_NARGS) read_function_from_mini("Describe Function:", get_object()); variable fun = (); current_topic = [_function_name, fun]; help_display(help_for_object(fun)); } %!%+ %\function{describe_variable} %\synopsis{Give help for a jed-variable} %\usage{describe_variable([var])} %\description % Display the online help for \var{variable} in the % help buffer. %\seealso{describe_function, help_for_help, help_mode} %!%- public define describe_variable() % ([var]) { !if (_NARGS) read_variable_from_mini("Describe Variable:", get_object()); variable var = (); current_topic = [_function_name, var]; help_display(help_for_object(var)); } %!%+ %\function{describe_mode} %\synopsis{Give help for the current mode} %\usage{describe_mode ()} %\description % Display the online help for the current editing mode % in the help buffer. %\seealso{describe_function, help_for_help, help_mode} %!%- public define describe_mode () { variable modstr = normalized_modename(); current_topic = [_function_name, modstr]; variable helpstr = help_for_object(modstr + "_mode"); ERROR_BLOCK { _clear_error(); help_message(); } if (helpstr[[-12:]] != "Undocumented") help_display(helpstr); else help(modstr + ".hlp"); } %!%+ %\function{describe_bindings} %\synopsis{Show a list of all keybindings} %\usage{describe_bindings ()} %\description % Show a list of all keybindings in the help buffer %\seealso{showkey, where_is, help_mode} %!%- public define describe_bindings() % (keymap=what_keymap()) { !if (_NARGS) read_mini("Keymap:", what_keymap(), ""); variable keymap = (); flush("Building bindings.."); variable buf = whatbuf(); current_topic = [_function_name, keymap]; help_display(""); set_readonly(0); dump_bindings(keymap); if (keymap != "global") { insert("\nInherited from the global keymap:\n"); push_spot(); dump_bindings("global"); pop_spot(); variable global_map = Assoc_Type[String_Type]; while ( not eobp() ) { push_mark(); () = ffind("\t\t\t"); variable key = bufsubstr(); () = right(3); push_mark(); eol(); global_map[key] = bufsubstr(); delete_line(); } bob(); forever { push_mark(); () = ffind("\t\t\t"); key = bufsubstr(); if (key == "") break; if ( assoc_key_exists(global_map, key) ) { () = right(3); push_mark(); eol(); if (bufsubstr() == global_map[key]) { delete_line(); push_spot(); eob(); insert(key + "\t\t\t" + global_map[key] + "\n"); pop_spot(); } else () = down(1); } else () = down(1); } } bob; insert("Keymap: " + keymap + "\n"); % TODO: % variable old_case_search = CASE_SEARCH; % CASE_SEARCH = 1; % do % expand_keystring; % while (down(1)) % bob; set_buffer_modified_flag(0); set_readonly(1); % use_syntax_table(helplist); This also colours the keybindings fit_window(get_blocal("is_popup", 0)); } % grep commands (need grep.sl) #ifexists grep %!%+ %\function{grep_slang_sources} %\synopsis{Grep in the Slang source files of the jed library path} %\usage{grep_slang_sources([what])} %\description % If the grep.sl mode is installed, grep_slang_sources does a % grep for the regexp pattern \var{what} in all *.sl files in the % jed library path. %\notes % Needs the grep.sl mode and the grep system command % %\seealso{grep, grep_definition, get_jed_library_path} %!%- public define grep_slang_sources() % ([what]) { !if (_NARGS) read_mini("Grep in Slang sources:", "", get_object()); variable what = (); % build the search string and filename mask variable files = strchop(get_jed_library_path, ',', 0); files = files[where(files != ".")]; % filter the current dir files = array_map(String_Type, &path_concat, files, "*.sl"); files = strjoin(files, " "); grep(what, files); } %!%+ %\function{grep_definition} %\synopsis{Grep source code of definition} %\usage{grep_definition([function])} %\description % If the \sfun{grep} function is defined, grep_definition does a % grep for a function/variable definition in all directories of the % jed_library_path. %\notes % The \sfun{grep} function is provided by grep.sl and needs the 'grep' % system command. It is checked for at evaluation (or byte_compiling) % time of help.sl by a preprocessor directive. %\seealso{describe_function, grep, grep_slang_sources, get_jed_library_path} %!%- public define grep_definition() % ([obj]) { !if (_NARGS) read_object_from_mini("Grep Definition:", get_object(), 0xF); variable obj = (); variable type = is_defined(obj); if (abs(type) != 2) if (get_y_or_n(obj + ": not a library function|variable. Grep anyway?") != 1) return; variable what, lib, files, results, grep_buf = "*grep_output*"; % build the grep-pattern obj = strsplit(obj, "->")[-1]; % remove the namspace part if (type >= 0) % function or undefined what = sprintf("-s 'define %s[ (]'", obj ); else % variable what = sprintf("-s 'variable *(*\"*%s[\" ,=]'", obj ); % grep in the Slang source files of the jed library path grep_slang_sources(what); % find number of hits !if (bufferp(grep_buf)) results = 0; else { eob; results = what_line; bob; } % if there is a unique find, go there directly if(results == 1) { define_blocal_var("FileList_Cleanup", 1); call_function("filelist_open_file"); close_buffer(grep_buf); } message(sprintf("Grep for \"%s\": %d definition(s) found", obj, results)); } % grep a function definition, % defaults to the word under cursor or the current help topic define grep_current_definition() { variable obj = get_object(); if (is_defined(obj) == 2) % library function grep_definition(obj); else if (current_topic[0] == "describe_function") grep_definition(current_topic[1]); else grep_definition(); } #endif %!%+ %\function{set_variable} %\synopsis{Set a variable value} %\usage{set_variable() % ([name])} %\description % Set a variable to a new value, define the variable if undefined. % If the current word is no variable, ask for the variable name. % The new value must be a valid slang expression that will be evaluated % in the global namespace. % % WARNING: Setting variables to unsensible values might cause jed % to stop working %\seealso{eval, read_variable_from_mini} %!%- public define set_variable() { variable name = get_object(); if (andelse {whatbuf()=="*help*"} {is_substr(name, "_Type")} ) name = current_topic[1]; !if (is_defined(name) < 0) % variable name = read_variable_from_mini("Set Variable:", name); if (name == "") error("set_variable: Aborted"); variable new = 0, var, value, def_string = ""; % ensure var is globally defined if (is_defined (name) == 0) { new = 1; if (get_y_or_n("Variable "+name+" undefined, define") > 0) eval("variable " + name); else error("set_variable: Aborted"); } % get pointer var = __get_reference(name); % evaluate value value = read_mini(variable_value_str(name) + " New value:","",""); value = eval(value); % check for same datatype if (andelse {__is_initialized(var)} {typeof(@var) != typeof(value)}) if ( get_y_or_n( sprintf("Variable %s: change datatype from %S to %S?", name, typeof(@var), typeof(value)) ) != 1) error("set_variable: Aborted"); % now set the variable @var = value; % display new value message(variable_value_str(name)); % redisplay help window if (current_topic[0] == "describe_variable") describe_variable(name); } %!%+ %\function{extract_synopsis} %\synopsis{return concise USAGE and SYNOPSIS info from the help_string} %\usage{String help->extract_synopsis(help_str)} %\description % Extract the USAGE and SYNOPSIS lines of the help_string % (assumning a documention string according to the format used in % Jed Help, e.g. jedfuns.txt). Convert to a more concise format and % return as string. %\seealso{help_for_function, mini_help_for_object} %!%- define extract_synopsis(help_str) { variable i, synopsis, word = extract_element(help_str, 0, ':'); help_str = strchop(help_str, '\n', 0); % get index of synopsis line i = (where(help_str == " SYNOPSIS") + 1); % no SYNOPSIS !if (length(i)) return ""; % get the actual line synopsis = strtrim(help_str[i[0]]); if (synopsis == word) % Phony synopsis return ""; return synopsis; } %!%+ %\function{extract_usage} %\synopsis{return concise USAGE and SYNOPSIS info from the help_string} %\usage{String help->extract_usage(help_str)} %\description % Extract the USAGE and SYNOPSIS lines of the help_string % (assumning a documention string according to the format used in % Jed Help, e.g. jedfuns.txt). Convert to a more concise format and % return as string. %\seealso{help_for_function, mini_help_for_object} %!%- define extract_usage(help_str) { variable i, usage; help_str = strchop(help_str, '\n', 0); % get index of usage line i = (where(help_str == " USAGE") + 1); % abort if not found !if (length(i)) return ""; % get the actual line usage = strtrim(help_str[i[0]]); % Replacements % insert "=" !if (is_substr(usage, "=")) (usage, ) = strreplace (usage, " ", " = ", 1); % strip Void/void usage = str_replace_all(usage, "Void = ", ""); usage = str_replace_all(usage, "void = ", ""); usage = str_replace_all(usage, "Void ", ""); usage = str_replace_all(usage, "void ", ""); % simple types -> small letters usage = str_replace_all(usage, "Integer_Type", "i"); usage = str_replace_all(usage, "Int_Type", "i"); usage = str_replace_all(usage, "Integer", "i"); usage = str_replace_all(usage, "Double_Type", "x"); usage = str_replace_all(usage, "Double", "x"); % compound types -> capital letters usage = str_replace_all(usage, "String_Type", "Str"); usage = str_replace_all(usage, "String", "Str"); usage = str_replace_all(usage, "Array_Type", "Arr "); usage = str_replace_all(usage, "Array", "Arr"); usage = str_replace_all(usage, "Assoc_Type", "Ass"); usage = str_replace_all(usage, "Assoc", "Ass"); % strip ";" and return return strtrim_end(usage, ";"); } static define get_mini_help(obj) { variable help_str = help_for_object(obj); % Help is already one-liner (e.g. "Undefined") !if (is_substr(help_str, "\n")) return help_str; return sprintf("%s; %s", extract_usage(help_str), extract_synopsis(help_str)); } %!%+ %\function{mini_help_for_object} %\synopsis{Show concise help information in the minibuffer} %\usage{mini_help_for_object(obj)} %\description % Show the synopsis of the online help in the minibuffer. %\seealso{describe_function, describe_variable} %!%- public define mini_help_for_object(obj) { message(get_mini_help(obj)); } %!%+ %\function{help_for_word_at_point} %\synopsis{Give (mode dependend) help for word under cursor} %\usage{help_for_word_at_point()} %\description % Find the word under the cursor and give mode-dependend help using the % function defined in the blocal variable "help_for_word_hook". %\notes % If a mode needs a different set of word_chars (like including the point % for object help in python), it can either set the buffer-local variable % "word_chars", use mode_set_mode_info("word_chars") or, if this is % not desired, its help_for_word_hook can discard the provided word and % call e.g. bget_word("mode_word_chars"). %\seealso{describe_function, describe_variable, context_help} %!%- public define help_for_word_at_point() { variable word_at_point = get_object(); if (word_at_point == "") run_local_hook("context_help_hook"); else run_local_hook("help_for_word_hook", word_at_point); } %!%+ %\function{context_help} %\synopsis{Give context sensitive help} %\usage{context_help()} %\description % Give a mode-dependend help for the current context, e.g. % find the word under the cursor and give mode-dependend help. %\notes % Uses \sfun{run_local_hook} to give a mode- or buffer local help. % It is up to the language modes to define a context_help_hook. % "hyperhelp" defines a \sfun{slang_context_help_hook} that calls % \sfun{describe_function} on the word-at-point. %\seealso{run_local_hook, describe_function, bget_word} %!%- public define context_help() { !if (run_local_function("context_help_hook")) run_local_hook("help_for_word_hook", bget_word()); } public define slang_context_help_hook() { variable word_at_point = get_object(); if (word_at_point == "") describe_function(); else describe_function(word_at_point); } public define help_2click_hook (line, col, but, shift) { context_help(); return(0); } % fast moving in the help buffer (link to link skipping) % ------------------------------------------------------ % skip forward to beg of next word (move this to txtutils.sl?) define skip_word() % ([word_chars]) { variable word_chars, skip; (word_chars, skip) = push_defaults(NULL, 0, _NARGS); if (word_chars == NULL) word_chars = get_blocal("Word_Chars", get_word_chars()); skip_chars(word_chars); while (skip_chars("^"+word_chars), eolp()) { !if (right(1)) break; } } % skip backwards to end of last word (move this to txtutils.sl?) define bskip_word() % ([word_chars]) { variable word_chars, skip; (word_chars, skip) = push_defaults(NULL, 0, _NARGS); if (word_chars == NULL) word_chars = get_blocal("Word_Chars", get_word_chars()); bskip_chars(word_chars); while (bskip_chars("^"+word_chars), bolp()) { !if (left(1)) break; } } % search forward for a defined word enclosed in ` ' static define fsearch_defined_word() { variable word; push_mark; while (fsearch_char('`')) { go_right_1(); word = get_word(Slang_word_chars); if (is_defined(word) and word != current_topic[1]) { pop_mark_0; return 1; } } pop_mark_1; return 0; } % goto next word that is a defined function or variable define goto_next_object() { if (is_list_element("help_search,apropos", current_topic[0], ',')) skip_word(); else if (fsearch_defined_word()) return; else if(push_spot, re_bsearch("^ +SEE ALSO"), pop_spot) skip_word(); else if (re_fsearch("^ +SEE ALSO")) { eol(); skip_word(); } % wrap if (eobp) bob(); } % goto previous word that is a defined function or variable define goto_prev_object () { if (is_list_element("help_search,apropos", current_topic[0], ',')) return bskip_word(); !if(andelse {push_spot, re_bsearch("^ +SEE ALSO"), pop_spot} {bskip_word(), not looking_at("ALSO")}) { push_mark; while (andelse {bsearch_char('\'')} % skip back over word at point if any {re_bsearch("`[_a-zA-Z]+'")}) { go_right_1; if (is_defined(get_word())) { pop_mark_0; return; } } pop_mark_1; } } % Highlighting of "Links" (defined objects) % ----------------------------------------- #ifdef HAS_DFA_SYNTAX create_syntax_table(mode); set_syntax_flags(mode, 0); % dfa_define_highlight_rule("\\\".*\\\"", "Qstring", mode); dfa_define_highlight_rule("->", "operator", mode); % Help topic (only word that starts on bol in standar help texts) %dfa_define_highlight_rule("^[a-zA-Z0-9_]+", "Kbold", mode); dfa_define_highlight_rule("`[^']+'", "QKstring", mode); dfa_define_highlight_rule(" [a-zA-Z0-9_]+,", "Knormal", mode); % last item in SEE ALSO but not a heading dfa_define_highlight_rule(" [a-zA-Z0-9_]+[a-z0-9_][a-zA-Z0-9_]*$", "Knormal", mode); dfa_define_highlight_rule("^ +[A-Z ]+$", "underline", mode); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); enable_dfa_syntax_for_mode(mode); % keywords will be added by the function help_mark_keywords() % special syntax table for listings (highlight all words in keyword colour) create_syntax_table(helplist); set_syntax_flags(helplist, 0); dfa_define_highlight_rule("[A-Za-z0-9_]*", "keyword", helplist); dfa_define_highlight_rule("->", "operator", helplist); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", helplist); dfa_build_highlight_table(helplist); enable_dfa_syntax_for_mode(helplist); #endif private define _add_keyword(keyword) { variable word = strtrim(keyword, "`',(): \t"); % show("adding keyword", keyword, is_defined(word)); if( is_defined(word) > 0) % function add_keyword(mode, keyword); if( is_defined(word) < 0) % variable add_keyword_n(mode, keyword, 1); } % mark adorned words that match defined objects static define help_mark_keywords() { variable keyword, word, pattern, patterns = ["\\\`[_a-zA-Z0-9]+\\\'", " [_a-zA-Z0-9]+,", "[, ][_a-zA-Z0-9]+ ?$" ]; push_spot_bob(); _add_keyword(get_word(Slang_word_chars)); % help object foreach pattern (patterns) { while (re_fsearch(pattern)) { keyword = regexp_nth_match(0); _add_keyword(keyword); skip_word(); } % test for a SEE ALSO section (for second and third pattern) bob(); !if (re_fsearch("^ *SEE ALSO")) break; } pop_spot(); } % Help Mode % --------- % Keybindings (customize with help_mode_hook) !if (keymap_p (mode)) copy_keymap (mode, "view"); definekey("context_help", "^M", mode); % Return definekey("help->goto_next_object", "^I", mode); % Tab definekey("help->goto_prev_object", Key_Shift_Tab, mode); definekey("help->goto_next_object", "n", mode); definekey("help->goto_prev_object", "p", mode); definekey("help->goto_prev_object", "b", mode); definekey("help_search", "/", mode); definekey("apropos", "a", mode); definekey("help->grep_current_definition", "d", mode); definekey("describe_function", "f", mode); definekey("close_and_insert_word", "i", mode); definekey("close_and_replace_word", "r", mode); definekey("info_mode", "I", mode); definekey("showkey", "k", mode); definekey("unix_man", "u", mode); definekey("set_variable", "s", mode); definekey("describe_variable", "v", mode); definekey("where_is", "w", mode); #ifexists create_circ definekey ("help->next_topic", ".", mode); % dillo-like definekey ("help->previous_topic", ",", mode); % dillo-like definekey ("help->next_topic", Key_Alt_Right, mode); % Browser-like definekey ("help->previous_topic", Key_Alt_Left, mode); % Browser-like #endif public define help_mode() { set_readonly(1); set_buffer_modified_flag(0); set_mode(mode, 0); use_keymap(mode); help_mark_keywords(); use_syntax_table(mode); set_buffer_hook("mouse_2click", &help_2click_hook); define_blocal_var("context_help_hook", &slang_context_help_hook); define_blocal_var("generating_function", current_topic); define_blocal_var("Word_Chars", Slang_word_chars); set_status_line(sprintf( " %s %s: %s ", whatbuf, current_topic[0], current_topic[1]), 0); run_mode_hooks("help_mode_hook"); message(help_for_help_string); } provide(mode); provide("hyperhelp"); jedmodes-2.5.7/sqlited/0000755000175400017500000000000011130344610013240 5ustar mildegmjedmodes-2.5.7/sqlited/sqlited.sl0000644000175400017500000003403711130344610015254 0ustar mildegm% sqlited.sl % % $Id: sqlited.sl,v 1.5 2008/12/14 13:16:30 paul Exp paul $ % % Copyright (c) 2006,2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % SQLite administration utility. Sqlited prompts for a database to open. The % tables and views in the database are shown in an index buffer. From there % you can open open tables, views, SQL commands and SQL query results in other % buffers. The database handle is passed to the table and sql buffers in a % blocal var, so it's possible to open multiple SQLite files and open multiple % tables in those files, as long as the files have different names. Get the % SQLite module from http://www.cheesit.com/downloads/slang/slsqlite provide("sqlited"); require("sqlite"); require("bufutils"); require("csvutils"); require("listing"); autoload("add_keyword_n", "syntax"); private variable mode = "sqlited"; %{{{ prototypes define sqlited(); %}}} %{{{ table viewer private define extract_rowid(line) { return strtok(line)[0]; } private define list_tagged_records() { variable tag_lines = listing_list_tags(2); tag_lines = array_map(String_Type, &extract_rowid, tag_lines); return strjoin(tag_lines, ","); } private define delete_tagged_line() { return 2; } private define delete_tagged() { % make sure the first line is not tagged push_spot_bob(); listing->tag(0); pop_spot(); variable db = get_blocal_var("db"), tablename = get_blocal_var("tablename"); sqlite_exec(db, sprintf("delete from '%s' where _ROWID_ in (%s)", tablename, list_tagged_records())); listing_map(2, &delete_tagged_line); } private define edit() { variable column = read_with_completion(get_blocal_var("columns"), "column", "", "", 's'); variable db = get_blocal_var("db"), tablename = get_blocal_var("tablename"), rowid = extract_rowid(line_as_string()); variable default = sqlite_get_array(db, String_Type, sprintf("select \"%s\" from '%s' where _ROWID_ = ?", column, tablename), rowid); default = default[0,0]; variable new_value = read_mini("new value", "", default); sqlite_exec(db, sprintf("update '%s' set '%s'= ? where _ROWID_ = ?", tablename, column), new_value, rowid); % Todo: update the line in the buffer. } private define index() { variable db = get_blocal_var("db"), filename = get_blocal_var("filename"); variable indexbuf = sprintf("*sqlited:%s*", filename); if (bufferp(indexbuf)) sw2buf (indexbuf); else sqlited(filename, db); } ifnot (keymap_p(mode)) copy_keymap(mode, "listing"); definekey(&delete_tagged, "x", mode); definekey(&edit, "e", mode); definekey(&index, "i", mode); %!%+ %\function{sqlite_table_mode} %\synopsis{mode for editing SQLite tables} %\usage{sqlite_table_mode()} %\description % This is a mode for editing tables in a SQLite database. The following % keys are defined: % \var{d} Mark record for deletion % \var{x} Delete marked records % \var{e} Edit the record at point. Prompts for a field to change and a % value to change it to. The change is not reflected in the buffer. % \var{i} Return to the index buffer %\seealso{sqlited, sqlite_table} %!%- private define sqlite_table_mode() { listing_mode(); use_keymap(mode); set_mode("sqlite_table", 0); } private define popup_view_or_table(db, filename, table, tablename, align) { table[where(_isnull(table))] = ""; % trim multiline fields - maybe csvutils should do this table = array_map(String_Type, &extract_element, table, 0, '\n'); % truncate to 50 chars table = array_map(String_Type, &substr, table, 1, 50); popup_buffer(sprintf("*sqlited:%s/%s*", path_basename(filename), tablename)); set_readonly(0); erase_buffer(); variable columns="", column, type; foreach (db) using (sprintf("PRAGMA table_info('%s')", tablename)) { (,column,type,,,) = (); if (type == "INTEGER") align += "r"; else align += "l"; columns = sprintf("%s,%s", columns, column); } insert_table(table, align, " "); eob(); push_mark(); bskip_chars("\n"); del_region(); bob(); define_blocal_var("db", db); define_blocal_var("columns", columns); define_blocal_var("tablename", tablename); define_blocal_var("filename", filename); } %!%+ %\function{sqlited_table} %\synopsis{edit a SQLite database table} %\usage{sqlited_table(db, filename, tablename)} %\description % This opens a table of an open SQLite database in the \var{sqlited} table % editing mode. %\notes % %\seealso{sqlited, sqlite_mode, sqlited_view} %!%- public define sqlited_table(db, filename, tablename) { variable table; table = sqlite_get_table(db, sprintf("select _ROWID_, * from '%s'", tablename)); ifnot (length(table)) return message("table is empty"); popup_view_or_table(db, filename, table, tablename, "l"); sqlite_table_mode(); } %!%+ %\function{sqlited_view} %\synopsis{open a SQLite database view} %\usage{sqlited_view(db, filename, tablename)} %\description % This a view of an open SQLite database in view_mode. %\seealso{sqlited, sqlite_mode, sqlited_table} %!%- public define sqlited_view(db, filename, tablename) { variable table; table = sqlite_get_table(db, sprintf("select * from '%s'", tablename)); ifnot (length(table)) return message("view is empty"); popup_view_or_table(db, filename, table, tablename, ""); view_mode(); } private define view_table() { variable db = get_blocal_var("db"); variable indexbuf=whatbuf(); variable tabletype, tablename, align = "", table; (tabletype, tablename) = str_split(line_as_string(), 9); variable filename=get_blocal_var("filename"); if (tabletype == "table: ") { sqlited_table(db, filename, tablename); } else if (tabletype == "view: ") { sqlited_view(db, filename, tablename); } } %}}} %{{{ sqlite buffer % adapted from sql.sl create_syntax_table("sqlite"); define_syntax("--", "", '%', "sqlite"); define_syntax("/*", "*/", '%', "sqlite"); define_syntax('"', '"', "sqlite"); define_syntax('\'', '"', "sqlite"); define_syntax("(", ")", '(', "sqlite"); define_syntax("0-9a-zA-Z_", 'w', "sqlite"); % words define_syntax("-+0-9.", '0', "sqlite"); % Numbers define_syntax(",;", ',', "sqlite"); define_syntax("|*/%+-<>&=!~", '+', "sqlite"); set_syntax_flags ("sqlite", 0x01 | 0x20); % case insensitive % define_keywords_n("sqlite", "asbyifinisofonorto", 2, 0); ()=define_keywords_n("sqlite", "addallandascendforkeynotrowset", 3, 0); ()=define_keywords_n("sqlite", "casecastdescdropeachelsefailfromfullglobintojoinleftlikenullplantempthenviewwhen", 4, 0); ()=define_keywords_n("sqlite", "abortafteralterbegincheckcrossgroupindexinnerlimitmatchorderouterqueryraiserighttableunionusingwhere", 5, 0); ()=define_keywords_n("sqlite", "attachbeforecolumncommitcreatedeletedetachescapeexceptexistshavingignoreinsertisnulloffsetpragmaregexprenameselectuniqueupdatevacuumvalues", 6, 0); ()=define_keywords_n("sqlite", "analyzebetweencascadecollatedefaultexplainforeigninsteadnaturalnotnullprimaryreindexreplacetrigger", 7, 0); ()=define_keywords_n("sqlite", "conflictdatabasedeferreddistinctrestrictrollback", 8, 0); ()=define_keywords_n("sqlite", "exclusiveimmediateinitiallyintersectstatementtemporary", 9, 0); ()=define_keywords_n("sqlite", "constraintdeferrablereferences", 10, 0); ()=define_keywords_n("sqlite", "transaction", 11, 0); ()=define_keywords_n("sqlite", "current_datecurrent_time", 12, 0); ()=define_keywords_n("sqlite", "autoincrement", 13, 0); ()=define_keywords_n("sqlite", "current_timestamp", 17, 0); ()=define_keywords_n("sqlite", "absavgmaxminsum", 3, 1); ()=define_keywords_n("sqlite", "countlowerquoteroundtotalupper", 5, 1); ()=define_keywords_n("sqlite", "ifnulllengthnullifrandomsubstrtypeof", 6, 1); ()=define_keywords_n("sqlite", "changessoundex", 7, 1); ()=define_keywords_n("sqlite", "coalesce", 8, 1); ()=define_keywords_n("sqlite", "total_changes", 13, 1); ()=define_keywords_n("sqlite", "sqlite_version", 14, 1); ()=define_keywords_n("sqlite", "last_insert_rowid", 17, 1); %!%+ %\function{sqlite_mode} %\synopsis{sql mode for sqlite} %\usage{sqlite_mode()} %\description % This is a mode for the SQLite dialect of SQL. If the buffer was opened % from \sfun{sqlited}, \sfun{run_buffer} executes the buffer's contents on % the database. Table and column names of files opened with \sfun{sqlited} % are added to the keyword2 syntax table, though you may not see this in your % color scheme. %\seealso{sqlited, run_buffer} %!%- define sqlite_mode() { use_syntax_table("sqlite"); set_mode("sqlite", 4); } private define sqlite_run() { variable e, db = get_blocal_var("db"); mark_buffer(); sqlite_exec(db, "begin"); try (e) sqlite_exec(db, bufsubstr()); catch SqliteError: { sqlite_exec(db, "rollback"); throw; } sqlite_exec(db, "commit"); vmessage("%d rows affected", sqlite_changes(db)); } %}}} %{{{ index buffer private define sqlite_query() { variable db = get_blocal_var("db"); variable query = read_mini("query", "", ""); variable table = sqlite_get_table(db, query); ifnot(length(table)) return message("no matching records"); popup_buffer("*sqlite result*"); set_readonly(0); erase_buffer(); vinsert ("results of \"%s\"\n", query); table[where(_isnull(table))] = ""; table = array_map(String_Type, &extract_element, table, 0, '\n'); table = array_map(String_Type, &substr, table, 1, 50); insert_table(table); view_mode(); } private define sqlite_command() { variable db = get_blocal_var("db"); pop2buf(sprintf("*sqlite:%s*", path_basename(get_blocal_var("filename")))); sqlite_mode(); define_blocal_var("db", db); define_blocal_var("run_buffer_hook", &sqlite_run); } private define edit_view() { variable db = get_blocal_var("db"), type, table; (type, table) = str_split(line_as_string(), 9); if (type != "view: " && type != "trigger:") throw RunTimeError, "not looking at a view or trigger"; pop2buf(sprintf("*sqlite:%s/%s*", path_basename(get_blocal_var("filename"), table))); erase_buffer(); if (type == "view: ") vinsert("drop view '%s';\n", table); else vinsert("drop trigger '%s';\n", table); insert(sqlite_get_row(db, "select sql from sqlite_master where name = ?", table)); set_buffer_modified_flag(0); sqlite_mode(); define_blocal_var("db", db); define_blocal_var("view", table); define_blocal_var("run_buffer_hook", &sqlite_run); } private define drop_table() { variable db = get_blocal_var("db"), table, type; (type, table)= str_split(line_as_string(), 9); if (type == "table: ") { ifnot (get_y_or_n(sprintf("really drop table %s", table))) return; sqlite_exec(db, sprintf("drop table '%s'", table)); } else if (type == "view: ") { ifnot (get_y_or_n(sprintf("really drop view %s", table))) return; sqlite_exec(db, sprintf("drop view '%s'", table)); } else if (type == "trigger:") { ifnot (get_y_or_n(sprintf("really drop trigger %s", table))) return; sqlite_exec(db, sprintf("drop trigger '%s'", table)); } else throw RunTimeError, "not looking at a view or table"; set_readonly(0); delete_line(); set_buffer_modified_flag(0); set_readonly(1); } private define rename_table() { variable db = get_blocal_var("db"), table, type; (type, table) = str_split(line_as_string(), 9); if (type != "table: ") throw RunTimeError, "not looking at a table"; variable name = read_mini("rename to ", "", ""); sqlite_exec(db, sprintf("alter table '%s' rename to '%s';", table, name)); set_readonly(0); bol; go_right(8); del_eol(); insert(name); set_buffer_modified_flag(0); set_readonly(1); } private define read_index() { variable db = get_blocal_var("db"); create_syntax_table("sqlite"); set_readonly(0); erase_buffer(); variable name, type, column; foreach name, type (db) using ("SELECT name, type FROM sqlite_master WHERE type in ('table', 'view', 'trigger')" +" AND name NOT LIKE 'sqlite_%' ORDER BY 1") { add_keyword_n("sqlite", name, 2); if (type == "table") { foreach (db) using (sprintf("PRAGMA table_info('%s')", name)) { (,column,,,,) = (); add_keyword_n("sqlite", column, 2); } vinsert("table: %s\n", name); } else if (type == "trigger") vinsert("trigger:%s\n", name); else vinsert("view: %s\n", name); } set_buffer_modified_flag(0); set_readonly(1); } ifnot (keymap_p("sqlite_index")) copy_keymap("sqlite_index", "view"); definekey(&sqlite_command, "c", "sqlite_index"); definekey(&edit_view, "e", "sqlite_index"); definekey(&sqlite_query, "?", "sqlite_index"); definekey(&drop_table, Key_Del, "sqlite_index"); definekey(&rename_table, "r", "sqlite_index"); definekey(&read_index, "^r", "sqlite_index"); definekey(&view_table, "^M", "sqlite_index"); %!%+ %\function{sqlited} %\synopsis{SQLite database viewer and editor} %\usage{sqlited()} %\description % Mode for SQLite database administration. Sqlited prompts for a database % filename and shows the tables and views in sqlited mode. The following keys % are defined: % % \var{c} opens a sql buffer in \sfun{sqlite_mode}. % \var{delete} drop the table or view at point % \var{e} edit the view at point. \var{sqlited} inserts the drop view % statement for you, to update the view just call \sfun{run_buffer}. % \var{?} prompts for a query in the minibuffer, and shows the result of the % query in its own buffer. % \var{C-r} reread the index % \var{enter} open the table at point in \var{sqlite_table_mode}. %\seealso{sqlite_table_mode, sqlite_mode} %!%- define sqlited() { variable filename, db; if (_NARGS == 2) { (filename, db) = (); } else { filename = read_file_from_mini("sqlite file"); db = sqlite_open(filename); } variable bufname = sprintf("*sqlited:%s*", path_basename(filename)); pop2buf(bufname); setbuf_info(path_basename(filename), path_dirname(filename), bufname, 0); define_blocal_var("db", db); define_blocal_var("filename", filename); read_index(); use_keymap("sqlite_index"); set_mode("sqlited", 0); set_buffer_hook("newline_indent_hook", &view_table); } %}}} jedmodes-2.5.7/cuamisc/0000755000175400017500000000000011262357102013225 5ustar mildegmjedmodes-2.5.7/cuamisc/cuamisc.sl0000644000175400017500000002540411262357102015216 0ustar mildegm% cuamisc.sl: helper functions for the cua suite % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Changelog: % 1 first public version % 1.1 repeat search opens the Search menu if LAST_SEARCH is empty % 1.2 menu_select_menu to keep bw compatibility with jed < 0.9.16 % 2004-01-23 1.3 "region aware" functions delete_cmd, bdelete_cmd % 1.3.1 new implementation of redo by JED % 1.4 next_buffer cycles in two directions (Dave Kuhlman) % 2004-08-26 1.4.1 fixed small documentation typo in bdelete_cmd % 2005-03-21 1.4.2 added missing tm-documentation block marker % 2005-05-25 1.5 bugfixes and merge with version 1.1.1 from jed 0.99-17 % * generally, let function names start with "cua_" % * removed optional arg 'force_overwrite' from % save_buffer_as() (use call("write_buffer") instead) % * improved redo() no longer toggles last undo % 2005-06-07 1.5.1 * removed the "generic" functions % (for older jed versions, they are now accessible % in compat17-16.sl, compat16-15.sl) % 2006-01-17 1.5.2 * some more tweaks and upload to jedmodes % 2006-03-20 1.6 * name change: cua_meta_escape_cmd() -> cua_escape_handler() % * [cua_]indent_region_or_line() moved to txtutils.sl % (http://jedmodes.sf.net/mode/txtutils/) % 2006-03-23 1.6.1 * cua_repeat_search() now searches across lines and has % optional arg `direction' % 2007-05-14 1.6.2 * removed ``add_completion("cua_save_as")`` % * new fun jbol() (by Joerg Sommer) % 2007-10-23 1.6.3 * new fun cua_replace_cmd() % 2009-10-05 1.6.4 * documentation update for cua_escape_handler() provide ("cuamisc"); %!%+ %\function{cua_delete_char} %\synopsis{Delete current character (or a visible region)} %\usage{Void cua_delete_char()} %\description % Bind to the Key_Delete, if you want it to work "region aware" %\seealso{bcua_delete_char, del, del_region} %!%- public define cua_delete_char() { if (is_visible_mark) del_region; else del; } %!%+ %\function{cua_bdelete_char} %\synopsis{Delete the char before the cursor (or a visible region)} %\usage{Void cua_bdelete_char ()} %\description % Bind to the Key_BS, if you want it to work "region aware" %\seealso{cua_delete_char, backward_delete_char, backward_delete_char_untabify} %!%- public define cua_bdelete_char() { if (is_visible_mark) del_region; else call("backward_delete_char_untabify"); } %!%+ %\function{cua_delete_word} %\synopsis{Delete the current word (or a visible region)} %\usage{ Void cua_delete_word ()} %\description % Delete either % * a visible region, % * from the current position to the end of a word, % * whitespace following the editing point, or % * one non-word char. % This way, you can do a "piecewise" deletion by repeatedly pressing % the same key-combination. %\notes % This is a modified version of \sfun{ide_delete_word} from Guido Gonzatos % ide emulation, put here to be usable with other emulations too. %\seealso{delete_word, cua_bdelete_word, cua_delete_char, cua_kill_region} %!%- public define cua_delete_word () % ^T, Key_Ctrl_Del { !if (is_visible_mark) { variable m = create_user_mark (); push_mark (); skip_chars (get_word_chars()); if (create_user_mark () == m) skip_chars (" \n\t"); if (create_user_mark () == m) go_right (1); } del_region (); } %!%+ %\function{cua_bdelete_word} %\synopsis{Backwards delete the current word (or a visible region)} %\usage{ cua_bdelete_word ()} %\description % Delete either % * a visible region, % * from the current position to the start of a word, % * whitespace preceding the editing point, or % * one non-word char. % This way, you can do a "piecewise" deletion by repeatedly pressing % the same key-combination. %\notes % This is a modified version of \sfun{ide_bdelete_word}, put here to be usable % with other emulations too. %\seealso{cua_delete_word, cua_delete_char} %!%- define cua_bdelete_word () % Key_Ctrl_BS { push_mark (); variable m = create_user_mark (); bskip_chars ("a-zA-Z0-9"); if (create_user_mark () == m) bskip_chars (" \n\t"); if (create_user_mark () == m) go_left (1); del_region (); } % Seach extensions % ---------------- autoload("search_across_lines", "search"); autoload("search_search_function", "search"); autoload("replace_do_replace", "search"); autoload("replace_with_query", "search"); %!%+ %\function{cua_repeat_search} %\synopsis{continue searching with last searchstring} %\usage{cua_repeat_search(direction=1)} %\description % Search for the next occurence of \var{LAST_SEARCH}. % If \var{direction} => 0, search forward, % else search backward. %\notes % I'd like to see this function as repeat_search() in search.sl. % It could be used in ide_repeat_search, ws_repeat_search and most. %\seealso{search_forward, search_backward, isearch_forward} %!%- public define cua_repeat_search() % (direction=1) { variable steps, direction = 1; if (_NARGS) direction = (); !if (strlen(LAST_SEARCH)) return menu_select_menu("Global.&Search"); steps = right(1); if (search_across_lines (LAST_SEARCH, direction) < 0) { go_left(steps); error ("Not found."); } } %!%+ %\function{cua_replace_cmd} %\synopsis{Search and Replace} %\usage{cua_replace_cmd()} %\description % A version of the standard replace_cmd() that sets the % default search pattern from the region or word under cursor. %\notes % Defining this as a wrapper around replace_cmd() fails, as % buffer_keystring() will not work as expected if the region contains % newlines. %\seealso{replace_cmd, cua_repeat_search, search_forward, isearch_forward} %!%- public define cua_replace_cmd() { variable pat, prompt, rep; % find default value: region or word under cursor if(is_visible_mark) % region marked: set point to beg of region { check_region(0); exchange_point_and_mark(); } else { skip_word_chars(); push_mark; bskip_word_chars(); } variable default = bufsubstr(); pat = read_mini("Replace:", "", default); !if (strlen (pat)) return; prompt = strcat (strcat ("Replace '", pat), "' with:"); rep = read_mini(prompt, "", ""); variable cs = CASE_SEARCH; if (strlow (pat) != pat) CASE_SEARCH = 1; ERROR_BLOCK { CASE_SEARCH = cs; } replace_with_query (&search_search_function, pat, rep, 1, &replace_do_replace); EXECUTE_ERROR_BLOCK; message ("done."); } % --- Use the ESC key as abort character (still experimental) custom_variable("Key_Esc", "\e\e\e"); %!%+ %\function{cua_escape_cmd} %\synopsis{Escape from a command/aktion} %\usage{cua_escape_cmd()} %\description % Undo/Stop an action. If a (visible) region is defined, undefine it. Else % call kbd_quit. %\seealso{kbd_quit, is_visible_mark} %!%- define cua_escape_cmd() { if (is_visible_mark) pop_mark(0); else call ("kbd_quit"); } %!%+ %\function{cua_escape_handler} %\synopsis{Distinguish the ESC key from other keys starting with "\e"} %\usage{Void cua_escape_handler()} %\description % If there is input pending (i.e. if the keycode is multi-character), "\\e" % will be put back to the input stream. Otherwise (assuming the ESC key % is pressed), the value of \var{Key_Esc} is pushed back. % % With ALT_CHAR = 27, the Alt key can be used as Meta-key as usual (i.e. % press both ALT + to get the equivalent of the ESC % key sequence. %\seealso{cua_escape_cmd, cua_one_press_escape, Key_Esc} %!%- define cua_escape_handler() { if (input_pending(0)) ungetkey (27); else buffer_keystring(Key_Esc); } %!%+ %\function{cua_one_press_escape} %\synopsis{Let the ESC key issue the value of \var{Key_Esc}} %\usage{cua_one_press_escape()} %\description % Dependend on the jed-version, either \sfun{x_set_keysym} or % \sfun{meta_escape_cmd} is used to map the ESC key to the value of % \var{Key_Esc}. %\example % To let the ESC key abort functions but retain bindings for % keystrings that start with "\\e" do %#v+ % cua_one_press_escape(); % setkey("cua_escape_cmd", Key_Esc); % Esc -> abort %#v- %\notes % The function is experimental and has sideeffects if not using xjed. % For not-x-jed: % % It uses the "^^" character for temporarily remapping, i.e. Ctrl-^ will % call cua_escape_handler(). % % In order to work, it must be loaded before any mode-specific keymaps are % defined -- otherwise this modes will be widely unusable due to not % working cursor keys...! % % It breaks functions that rely on getkey() (e.g. isearch, showkey, old % wmark(pre 99.16), ...). These functions see ctrl-^ instead of \\e. % % It will not work in keybord macros and might fail on slow terminal links. %\seealso{cua_escape_cmd, cua_escape_handler, getkey, setkey, x_set_keysym} %!%- define cua_one_press_escape() { if (is_defined("x_set_keysym")) call_function ("x_set_keysym", 0xFF1B, 0, "\e\e\e"); % one-press-escape else { map_input(27, 30); % "\e" -> "^^" ("^6" on most keybords, undo in wordstar) setkey ("cua_escape_handler", "^^"); } } %!%+ %\function{cua_save_buffer} %\synopsis{Save the current buffer} %\usage{cua_save_buffer()} %\description % Save current buffer to the associated file. Asks for a filename if there is % no file associated to the buffer. %\seealso{save_buffer, buffer_filename, save_buffer_as} %!%- define cua_save_buffer() { variable file; file = buffer_filename(); if (file == "") % buffer was never saved { save_buffer_as(); return; } !if (buffer_modified()) { message("Buffer not modified."); return; } () = write_buffer(file); } %!%+ %\function{jbol} %\synopsis{Jumps to the begin of line or the first non-space character} %\usage{jbol(skip_white)} %\description % Move the point to either the first column or the first non-white character % of a line. The first call to \sfun{jbol} calls either \sfun{bol} or % \sfun{bol_skip_white}, depending on the setting of the \var{skip_white} % argument. Subsequent calls will jump between column 1 and the first % non-white character. %\example % Get the behaviour of gedit with %#v+ % setkey("jbol(0)", Key_Home); % move to bol first %#v- % or the behaviour of jEdit, NetBeans, SciTe, or Boa Constructor with %#v+ % setkey("jbol(1)", Key_Home); % bol-skip-white first %#v- %\notes % It's really handy if you use indention. %\seealso{beg_of_line, bol, LAST_KBD_COMMAND} %!%- public define jbol(skip_white) { if (skip_white) bol_skip_white(); else bol(); if (LAST_KBD_COMMAND == "jbol") { if (bolp()) skip_white(); else bol(); } } jedmodes-2.5.7/pcre/0000755000175400017500000000000011130344607012532 5ustar mildegmjedmodes-2.5.7/pcre/jedpcre.sl0000644000175400017500000000205411130344607014507 0ustar mildegm% jedpcre.sl % % $Id: jedpcre.sl,v 1.4 2008/10/21 18:48:25 paul Exp paul $ % % Copyright (c) 2004-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This provides a pcre occur function. provide("jedpcre"); require("pcre"); require("occur"); % this requires the occur from jedmodes.sf.net/mode/occur %{{{ occur public define pcre_occur() { variable pat, str, tmp, n; if (_NARGS) pat = (); else pat = read_mini("Find All (Regexp):", LAST_SEARCH, Null_String); variable occur_re = pcre_compile(pat); tmp = "*occur*"; occur->obuf = whatbuf(); occur->nlines=0; occur->mbuffers=0; push_spot_bob; push_mark_eob; str = strchop(bufsubstr, '\n', 0); pop_spot; variable index = where(array_map(Integer_Type, &pcre_exec, occur_re, str)); ifnot (length(index)) return message("no matches"); pop2buf(tmp); erase_buffer(); foreach n (index) { vinsert ("%*d: %s\n", occur->line_number_width, 1+n, str[n]); } bob(); set_buffer_modified_flag(0); occur_mode(); } %}}} jedmodes-2.5.7/scrnhelp/0000755000175400017500000000000010461125576013427 5ustar mildegmjedmodes-2.5.7/scrnhelp/scrnhelp.sl0000644000175400017500000000420110274112110015560 0ustar mildegm% --------------------------------------------------------------- -*- SLang -*- % % SCRNHELP % % Copyright (c) 2001 Francesc Rocher % Released under the terms of the GNU General Public License (ver. 2 or later) % % $Id: scrnhelp.sl,v 1.4 2001/01/14 08:15:43 rocher Exp $ % % ----------------------------------------------------------------------------- % % DESCRIPTION % This file contains a couple of functions to show/hide a help buffer % associated to a JED mode. % % USAGE % From some JED mode, autoload these functions and call them from some % particular functions. 'scrnhelp' function will show the help file % associated to that mode. It must be invoked as follows: % % scrnhelp ("*myMode*", "*myMode help*", "mymode.hlp", 10); % % where "*myMode*" is the name of the JED mode, "*myMode help*" is the % name of the help buffer, "mymode.hlp" is the filename containing some % help and '10' is the number of lines of such file. To hide the help % buffer, simply call % % scrnhelp_quit ("*myMode help*"); % % NOTE: The last line of the help file should not end with '\n'. % % AUTHOR % Francesc Rocher % Feel free to send comments, suggestions or improvements. % % ----------------------------------------------------------------------------- define scrnhelp_quit (hbuf) { pop2buf (hbuf); delbuf (hbuf); otherwindow (); onewindow (); } define scrnhelp (cbuf, hbuf, file, lines) { % Shows a help screen. % % Parameters: % cbuf: name of the 'calling' buffer % hbuf: name of the 'help' buffer % file: filename to insert into the help buffer % lines: number of lines of the help file variable rows; !if (bufferp (hbuf)) { setbuf (hbuf); set_readonly (0); () = insert_file (expand_jedlib_file (file)); set_readonly (1); set_buffer_modified_flag (0); } else { scrnhelp_quit (hbuf); return; } !if (buffer_visible (hbuf)) { onewindow (); pop2buf (hbuf); bob (); rows = window_info ('r') - lines; pop2buf (cbuf); loop (rows) enlargewin (); } } jedmodes-2.5.7/browse_url/0000755000175400017500000000000011137552160013766 5ustar mildegmjedmodes-2.5.7/browse_url/browse_url.sl0000644000175400017500000002077011137552160016517 0ustar mildegm% browse_url -*- mode: Slang; mode: Fold -*- % % $Id$ % Keywords: WWW, processes, unix % % Copyright (c) 2003 Paul Boekholt, Günter Milde. % Released under the terms of the GNU GPL (version 2 or later). % % Functions for display of web pages from within JED. % Like Emacs' links.el and browse-url.el. Unix only. % see also uri.sl % % Versions % 1.0 first public version (outsourced from jedscape by PB % and modified by GM) % 1.1 changed the Browse_Url_Viewer default, as html2txt has problems % downloading "complicated" URLs (no negotiating with the server) % that can be avoided by using a text mode browser with --dump % 1.2 made SLang2 proof % 1.2.1 2005-10-13 bugfix in find_program() % 1.2.1 2005-11-18 correct bugfix in find_program() (changed order of redirections) % 1.3 2006-05-23 dropped implementing of a named namespace % 1.3.1 2006-05-26 documentation update, added curl to list of download commands % added missing autoloads (J. Sommer) % 1.4 2009-01-27 added "www-browser" to Browse_Url_Browser defaults list % code cleanup in find_program() % % TODO: use the curl module % There is code for downloading functions using the curl module in % http://ruptured-duck.com/jed-users/msg01757.html % _debug_info=1; autoload("push_defaults", "slutils"); autoload("popup_buffer", "bufutils"); autoload("close_buffer", "bufutils"); provide("browse_url"); % implements("browse_url"); %{{{ finding the programs % This should be in a separate library (say sl-utils?) %!%+ %\function{find_program} %\synopsis{Check a list of program names for the first installed one} %\usage{String = find_program(String programs)} %\description % Take a comma-separated list of command lines and return the first % for which the program is in the path, or "" % If a list element is a program with options, these options will be % omitted for the availability test but turn up in the return value. %\example %#v+ % find_program("wget -O -, w3c -n, dog") %#v- % returs "w3c -n", if w3c is in the PATH but wget not %\notes % Uses the Unix system command 'which'. % (Simply returns "" if the call to `which` fails) % Newer versions of jed (or slang?) come with a similar function % (but what is its name?) %\seealso{} %!%- static define find_program(programs) { variable program; foreach program (strtok(programs, ",")) { program = strtrim(program); program = extract_element(program, 0, ' '); !if(system(sprintf("which %s > /dev/null 2>&1", program))) return program; } return ""; } %}}} %{{{ custom variables % Helper programs %!%+ %\variable{Browse_Url_Browser} %\synopsis{Text-mode browser} %\description % Text mode browser called from browse_url %\note % On Debian, www-browser is a symlink to the preferred browser on the % system. %\seealso{browse_url, Browse_Url_Viewer} %!%- custom_variable("Browse_Url_Browser", find_program("www-browser, links, lynx, w3m")); %!%+ %\variable{Browse_Url_Download_Cmd} %\synopsis{Download app} %\description % Helper app for web downloads via find_url(). % Must take a URL and dump it to stdout. %\seealso{find_url, Browse_Url_Browser} %!%- custom_variable("Browse_Url_Download_Cmd", find_program("wget --output-document=-, curl, w3c -n, dog")); if (Browse_Url_Download_Cmd == "") Browse_Url_Download_Cmd = Browse_Url_Browser + " -source"; %!%+ %\variable{Browse_Url_Viewer} %\synopsis{Web viewer} %\description % Helper app for viewing an URL-s ASCII rendering with view_url(). % Must dump an ASCII-rendering of the given URL to stdout. %\notes % While html2txt accepts URLs as input, it has problems % downloading "redirected" URLs (no negotiating with the server) % that can be avoided by using a text mode browser with --dump %\seealso{view_url, Browse_Url_Browser} %!%- custom_variable("Browse_Url_Viewer", Browse_Url_Browser + " -dump"); %!%+ %\variable{Browse_Url_X_Browser} %\synopsis{X-windows browser} %\description % Web browser called from browse_url (if jed runs under X-Windows) %\notes % * Set to "", if you want the Browse_Url_Browser in a x-terminal. % * Browsers, that understand the -remote option could be "reused" % with gnome-moz-remote. It can be configured to open any browser % and (other than netscape-remote) fires up a browser % if none is open (as does galeon -x) or firefox. %\seealso{browse_url, browse_url_x, Browse_Url_Browser} %!%- custom_variable("Browse_Url_X_Browser", find_program("firefox, galeon -x, gnome-moz-remote, opera, dillo, mozilla, netscape")); % ------------------- Functions ------------------------------ %!%+ %\function{find_url} %\synopsis{Find a file by URL} %\usage{ find_url(url="", cmd = Browse_Url_Download_Cmd)} %\description % Fetch a file from the web and put in a buffer as-is. Needs a % helper application like wget or lynx to do the actual work. % If the url is not given, it will be asked for in the minibuffer. % If the helper app is not given, it defaults to the value of the % custom variable Browse_Url_Download_Cmd. %\seealso{view_url, find_file, Browse_Url_Download_Cmd} %!%- public define find_url() %(url="", cmd = Browse_Url_Download_Cmd) { variable status, url, cmd; (url, cmd) = push_defaults(, Browse_Url_Download_Cmd, _NARGS); if (url == NULL) url = read_mini("url: ", "", ""); popup_buffer(url); erase_buffer(); flush(sprintf("calling %s %s", cmd, url)); status = run_shell_cmd(sprintf("%s %s", cmd, url)); if (status) { close_buffer(); verror("%s returned %d, %s", cmd, status, errno_string(status)); } set_buffer_modified_flag(0); bob(); } %!%+ %\function{view_url} %\synopsis{View an ASCII rendering of a URL} %\usage{ view_url(String url="", String cmd= Browse_Url_Viewer)} %\description % View the ASCII-rendering of a URL in a buffer. % Depends on a suitable helper app % If the url is not given, it will be asked for in the minibuffer. % If the helper app is not given, it defaults to the value of the % custom variable Browse_Url_Viewer %\seealso{find_url, Browse_Url_Viewer} %!%- public define view_url() %(url="", cmd= Browse_Url_Viewer) { variable status, url, cmd; (url, cmd) = push_defaults(, Browse_Url_Viewer, _NARGS); if (url == NULL) url = read_mini("url: ", "", ""); popup_buffer("*"+url+"*"); erase_buffer; flush(sprintf("calling %s %s", cmd, url)); status = run_shell_cmd(sprintf("%s %s", cmd, url)); if (status) { close_buffer(); verror("%s returned %d, %s", cmd, status, errno_string(status)); } set_buffer_modified_flag(0); bob; view_mode(); } %{{{ X-windows %!%+ %\function{browse_url_x} %\synopsis{Open a URL in a browser} %\usage{browse_url_x(String url=ask, String cmd=Browse_Url_X_Browser)} %\description % Open the url in a browser (defaulting to Browse_Url_X_Browser) % as background process in a separate window. %\seealso{browse_url, find_url, view_url, Browse_Url_X_Browser} %!%- public define browse_url_x() %(url, cmd=Browse_Url_X_Browser) { variable status, url, cmd; (url, cmd) = push_defaults(, Browse_Url_X_Browser, _NARGS); if (url == NULL) url = read_mini("url: ", "", ""); flush(sprintf("calling %s %s", cmd, url)); cmd = strcat(cmd, " ", url); #ifdef UNIX cmd += " &> /dev/null &"; % run cmd in background #endif status = system(cmd); if (status) verror("%s returned %d, %s", cmd, status, errno_string(status)); } %}}} %!%+ %\function{browse_url} %\synopsis{Open the url in a browser} %\usage{ browse_url() %(url="", cmd=Browse_Url_Browser)} %\description % Open the url in a browser (default Browse_Url_Browser/Browse_Url_X_Browser) % Without X-windows running, jed is suspended as long as the browser runs, % otherwise run the browser as background process in a separate window. %\seealso{browse_url_x, view_url, find_url, Browse_Url_Browser} %!%- public define browse_url() %(url="", cmd=Browse_Url_Browser) { variable status, url, cmd; (url, cmd) = push_defaults(, Browse_Url_Browser, _NARGS); if (url == NULL) url = read_mini("url: ", "", ""); % use the X-Browser only with xjed % if (is_defined("x_server_vendor") and Browse_Url_X_Browser != "") % check for a running X-Win via the DISPLAY variable if (getenv("DISPLAY") != NULL and Browse_Url_X_Browser != "") { if (_NARGS == 2) browse_url_x(url, cmd); else browse_url_x(url); } else { flush(sprintf("calling %s %s", cmd, url)); status = run_program(sprintf("%s %s", cmd, url)); if (status) verror("%s returned %d, %s", cmd, status, errno_string(status)); } } jedmodes-2.5.7/rfcview/0000755000175400017500000000000011137341464013253 5ustar mildegmjedmodes-2.5.7/rfcview/rfcview.sl0000644000175400017500000002210511137341464015260 0ustar mildegm% rfcview.sl -*- mode: Slang; mode: Fold -*- % RFC viewer % % $Id: rfcview.sl,v 1.7 2009/01/11 09:26:44 paul Exp paul $ % Keywords: docs % % Copyright (c) 2003-2009 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Not as pretty as Emacs' rfcview, but more features. % -Pick rfc's from the rfc-index % -follow links to other rfc's % -try to display ToC in separate buffer % -pop up references with mouse % -selectively display only headers, or sections matching any of a list % of regexps. provide("rfcview"); require("curl"); require("view"); % A comma separated list of directories to search for RFC's custom_variable ("Rfc_Path", "/usr/doc/rfc"); private variable mode = "rfcview"; %{{{ syntax table create_syntax_table(mode); #ifdef HAS_DFA_SYNTAX %%% DFA_CACHE_BEGIN %%% static define setup_dfa_callback (mode) { dfa_define_highlight_rule ("RFC ?[0-9]+", "keyword1", mode); dfa_define_highlight_rule ("^[0-9\\.]+", "preprocess", mode); dfa_define_highlight_rule ("\\[RFC ?[0-9]+\\]", "QKkeyword1", mode); dfa_define_highlight_rule ("\\[.*\\]", "QKnormal", mode); dfa_build_highlight_table(mode); } dfa_set_init_callback (&setup_dfa_callback, mode); %%% DFA_CACHE_END %%% enable_dfa_syntax_for_mode(mode); #endif %}}} %{{{ rfc fetcher private define write_callback (v, data) { insert(data); return 0; } private define get_rfc(rfc) { rfc = strtrim_beg(rfc, "0"); variable c = curl_new (sprintf("ftp://ftp@ftp.ietf.org/rfc/rfc%s.txt", rfc)); ()=read_file(sprintf("%s/rfc%s.txt", extract_element(Rfc_Path, 0, ','), rfc)); variable v; curl_setopt(c, CURLOPT_WRITEFUNCTION, &write_callback, &v); curl_perform (c); save_buffer(); } %}}} %{{{ find rfc by number public define rfc_mode(); private define open_rfc(rfc) { variable file; foreach file ([sprintf("rfc%s.txt", rfc), sprintf("rfc%s.txt.gz", rfc), sprintf("rfc%s.txt", strtrim_beg(rfc, "0")), sprintf("rfc%s.txt.gz", strtrim_beg(rfc, "0"))]) { file = search_path_for_file(Rfc_Path, file, ','); if (file != NULL) { ()=read_file(file); break; } } then { get_rfc(rfc); } return whatbuf(); } private define find_rfc(rfc) { % if there are three digits, prepend a 0 if (strlen(rfc) == 3) rfc = "0" + rfc; variable buf = whatbuf(); pop2buf(open_rfc(rfc)); rfc_mode; pop2buf(buf); } %}}} %{{{ index % get RFC from rfc-index private define get_rfc_from_index() { ifnot (re_bsearch("^[0-9]")) throw RunTimeError, "not looking at rfc"; push_mark; skip_chars("0-9"); find_rfc(bufsubstr); } %}}} %{{{ outline #ifdef HAS_LINE_ATTR private define hide_body() { set_matching_hidden(0, "^[0-9]"); message("a: show all s: show section d: hide section"); } % (un)hide a section, unhide the first line private define hide_show_section(hide) { push_spot; eol; EXIT_BLOCK { pop_spot; } ifnot(re_bsearch("^[0-9]")) return; variable first_mark = create_user_mark; push_mark; go_down_1; if(re_fsearch("^[0-9]")) go_left_1; else eob; set_region_hidden(hide); goto_user_mark(first_mark); set_line_hidden(0); } private define hide_section() { hide_show_section(1); } private define show_section() { hide_show_section(0); } private variable last_pattern = ""; % rolo for a pattern, or a | separated list of patterns, in the index or % in the rfc, if its section headers begin with a number private define rolo() { variable pattern, subpattern; ifnot (_NARGS) read_mini("pattern to rolo for", "", last_pattern); pattern = (); if (pattern == "") return set_buffer_hidden(0); last_pattern = pattern; push_spot_bob; ifnot (re_fsearch("^[0-9]")) return pop_spot, message ("no section separators"); push_spot; push_mark_eob; set_region_hidden(1); foreach subpattern (strchop(pattern, '|', '\\')) { goto_spot; while (re_fsearch(subpattern)) { set_line_hidden(0); show_section(); skip_hidden_lines_forward(0); } } pop_spot; pop_spot; message("type 'a' to cancel selective display"); } #endif %}}} %{{{ follow RFC link private define follow_rfc() { bskip_chars("0-9"); bskip_white; bskip_chars("RFC"); push_mark; skip_chars("RFC 0-9"); variable rfc = string_get_match(bufsubstr, "RFC ?\\([0-9]+\\)", 1, 1); if (strlen(rfc)) find_rfc(rfc); else if (is_substr(whatbuf, "index")) get_rfc_from_index; } %}}} %{{{ ToC % from toc or index window, scroll other window private define scroll_other(cmd) { variable buf = whatbuf; otherwindow; try { call(cmd); } finally { pop2buf(buf); } } private define scroll_other_down() { scroll_other("page_down"); } private define scroll_other_up() { scroll_other("page_up"); } % go to a page from the ToC private define goto_page() { variable pages = get_blocal_var("pages"), mark, buf = whatbuf; eol; push_mark; bskip_chars("0-9"); variable page = bufsubstr; if (strlen(page) && assoc_key_exists(pages, page)) { mark = pages[page]; pop2buf(user_mark_buffer(mark)); goto_user_mark(mark); recenter(1); } pop2buf(buf); } % kill other buffer private define rfc_close_buffer_hook(buf) { variable obuf = get_blocal_var("otherbuffer"); if (bufferp(obuf)) delbuf(obuf); } %}}} %{{{ show bibliographic reference private define show_reference(l,c,b,s) { variable ref, ref_mark, first_line, lines = 10; push_spot; EXIT_BLOCK { pop_spot; 1; } ifnot (bfind_char('[')) return; push_mark; ifnot (ffind_char(']')) return pop_mark_0; go_right_1; ref = bufsubstr; eob; ifnot (re_bsearch("^[0-9.]*[ \t]*references") && fsearch(ref)) return; ref_mark = create_user_mark; goto_spot; onewindow(); splitwindow(); if (window_info ('t') < 3) otherwindow(); goto_user_mark(ref_mark); push_spot; push_mark; first_line = what_line; eol; if (re_fsearch("^[ \t]*\\[")) lines = what_line - first_line; set_region_hidden(0); if (lines > 10) lines = 10; pop_spot; window_info('r') - lines; otherwindow; loop () enlargewin; otherwindow; recenter(1); otherwindow; message ("o: switch to reference window 1: close reference window 0: close this window"); } %}}} %{{{ mode for index and rfc public define rfc_mode() { variable line, page, pages = Assoc_Type[Mark_Type], body, toc; % remove form feeds bob; push_mark(); while (bol_fsearch("\f")) { delete_line; bskip_chars("\n"); line = line_as_string; delete_line; page = string_get_match(line, "Page +\\([0-9]+\\)", 1, 1); exchange_point_and_mark(); if (strlen(page)) pages[page] = create_user_mark; pop_mark_1(); push_mark(); skip_chars("\n"); if (looking_at("RFC")) delete_line; bskip_chars("\n"); push_mark; skip_chars("\n"); del_region; insert("\n\n\n"); } pop_mark_0(); set_buffer_modified_flag(0); view_mode; use_keymap("rfcview"); set_mode(mode, 0); use_syntax_table(mode); set_buffer_hook("newline_indent_hook", &follow_rfc); set_buffer_hook("mouse_up", &show_reference); #ifdef HAS_DFA_SYNTAX % try to highlight references eob; if (re_bsearch("^[0-9\\.]*[ \t]*references")) { while (re_fsearch("^[ \t]*\\(\\[[^\\]]{1,20}\\]\\)")) { add_keyword(mode, regexp_nth_match(1)); eol; } } #endif % try to find the table of contents bob; ifnot (fsearch("table of contents")) return; push_mark; ifnot (re_fsearch("^[ \t]*\\(1[.0-9]*\\)")) return pop_mark_0, bob; % try to find end of ToC body = regexp_nth_match(1); eol; ifnot (bol_fsearch(body)) return pop_mark_0, bob; go_left_1; toc = bufsubstr; bob; variable buffer = whatbuf, otherbuffer = sprintf("*ToC for %s*", whatbuf); define_blocal_var("otherbuffer", otherbuffer); define_blocal_var("close_buffer_hook", &rfc_close_buffer_hook); if (bufferp(otherbuffer)) delbuf(otherbuffer); sw2buf(otherbuffer); define_blocal_var("close_buffer_hook", &rfc_close_buffer_hook); define_blocal_var("otherbuffer", buffer); insert (toc); bob; define_blocal_var("pages", pages); view_mode; use_keymap("rfc_toc"); set_buffer_hook("newline_indent_hook", &goto_page); } %}}} %{{{ keymaps ifnot (keymap_p("rfcview")) copy_keymap("rfcview", "view"); $1= _stkdepth; "delete_window", "0"; "one_window", "1"; "split_window", "2"; "enlarge_window", "^"; "other_window", "o"; ". eol \"^[0-9]\" re_fsearch pop 2 recenter", "n"; ". bol \"^[0-9]\" re_bsearch pop 2 recenter", "p"; ". \"Enter: follow link n: next section p: previous section ? search sections\" message", "h"; #ifdef HAS_LINE_ATTR &rolo, "?"; % outline-like bindings &hide_body, "t"; "set_buffer_hidden(0)", "a"; &hide_section, "d"; &show_section, "s"; #endif loop ((_stkdepth - $1) /2) definekey ("rfcview"); % keymap for ToC and index ifnot (keymap_p("rfc_toc")) copy_keymap("rfc_toc", "rfcview"); definekey(&scroll_other_down, " ", "rfc_toc"); definekey(&scroll_other_up, Key_BS, "rfc_toc"); %}}} public define rfcview() { sw2buf(open_rfc("-index")); rfc_mode(); use_keymap("rfc_toc"); } jedmodes-2.5.7/diffmode/0000755000175400017500000000000011307555203013360 5ustar mildegmjedmodes-2.5.7/diffmode/treemode.sl0000644000175400017500000007752210651111703015533 0ustar mildegm% Tree viewer for JED. % -*- mode: SLang; mode: fold -*- % % Copyright (C) 2003-2004 by Dino Leonardo Sangoi % Released under the terms of the GNU GPL (version 2 or later). % % Version 1.99b % $Revision: 1.1 $ % $Author: milde $ % $Date: 2007/07/23 11:40:51 $ % % This is not a standalone mode, but is used by other modes that need a % tree visualization. % %%%implements("Tree"); % _debug_info=1; _traceback=1; _boseos_info=3; require("keydefs"); static variable TreeMode = "TreeMode"; % Events public variable TREE_OPEN = 1; public variable TREE_CLOSE = 2; public variable TREE_TOGGLE = 4; public variable TREE_MOVE = 8; public variable TREE_OPEN_PLACEHOLDER = 16; %{{{ Tree Helpers % a simple function to set current buffer, and return old buffer private define whatbuf_setbuf(buf) { whatbuf(); %on stack setbuf(buf); } % convert all tabs to spaces. private define _tree_untab_buffer() { push_spot(); bob(); push_mark(); eob(); untab(); pop_spot(); } % run a user defined function on tree actions. private define _tree_send_event(event) { variable ret = 1; variable func = get_blocal_var("TreeEventFunc"); variable mask; if (func != NULL) { mask = get_blocal_var("TreeEventMask"); if ((event & mask) > 0) { variable umark = create_user_mark(); ret = @func(event); % return to tree buffer, to allow func to move freely around setbuf(user_mark_buffer(umark)); goto_user_mark(umark); } } return ret; } % put the point on the tree mark. private define _tree_goto_line_start() { bol_skip_white(); } %}}} %{{{ Private tree functions % private, fast version of tee_elem_state() (assumes currently on a tree buffer) private define _tree_elem_state() { bol;skip_white;%_tree_goto_line_start(); what_char(); } % get start column for this element (i.e. tree depth) private define _tree_elem_get_column() { bol(); skip_white();%_tree_goto_line_start(); what_column(); % Return value on stack } % get element name private define _tree_elem_get_name() { bol;skip_white;%_tree_goto_line_start(); push_spot(); go_right(2); push_mark_eol(); bufsubstr(); % result on stack pop_spot(); % return string on stack } % get data attached to this element. private define _tree_elem_get_data() { variable v = NULL; variable treedata = get_blocal_var("TreeUserData"); if (treedata != NULL) { variable pos = what_line() - 1; if (pos < treedata.pos) v = treedata.array[pos]; } return v; } %}}} %{{{ Private add/remove functions and helpers % put an element, and the placeholder (if required) private define __tree_insert_elem(name, col, indent, placeholder) { goto_column(col); if (strlen(placeholder) > 0) { insert("+ " + name); newline(); goto_column(col+indent); insert(". "+placeholder); set_line_hidden(1); } else insert(". " + name); } % low level delete node. private define _tree_delete_element() { % very simple right now, but keep abstract % delete_line(); % I can't use 'delete_line' as it does weird things with 'line hidden' flag. bol(); del_eol(); !if (bobp()) { go_left_1(); del(); go_right_1(); } else !if (eobp()) del(); } %}}} %{{{ Private movement functions private define _tree_goto_child() { variable col = _tree_elem_get_column(); variable child = 0; push_mark(); if (down(1)) if (_tree_elem_get_column() > col) child = 1; pop_mark(1 - child); return child; } % move to next or prev sibling ('move_func' can be &down_1 pr &up_1) private define _tree_goto_sibling(move_func) { variable col2, col = _tree_elem_get_column(); variable sibling = 0; push_mark(); while (@move_func()) { col2 = _tree_elem_get_column(); if (col2 == col) sibling = 1; if (col2 <= col) break; } pop_mark(1 - sibling); return sibling; } private define _tree_goto_parent() { variable col = _tree_elem_get_column(); variable parent = 0; push_mark(); while (up(1)) if (_tree_elem_get_column() < col) { parent = 1; break; } pop_mark(1 - parent); return parent; } % this is a low level function that skips all the nodes below the current node. private define __tree_skip_children() { variable col = _tree_elem_get_column(); % skip children. need if I'm adding a sibling. If this is a child, % this will put it at the end. while (down(1)) if (_tree_elem_get_column() <= col) break; } %}}} %{{{ Tree node data manipulation % Creates a treedata structure and set BLocal var. private define _tree_data_create(type) { variable treedata = get_blocal_var("TreeUserData"); if (treedata != NULL) error("treemode: TreeData already present."); treedata = @struct { array, pos, type }; treedata.pos = 0; % first free pos treedata.type = type; treedata.array = treedata.type[100]; set_blocal_var(treedata, "TreeUserData"); return treedata; } % grows 'treedata', so that 'pos' fits in. private define _tree_data_grow(treedata, pos) { variable size = length(treedata.array); variable growsize = 100; if (pos >= size+growsize) growsize = pos + 1 - size; % this may fail using slang 1.4.5 or older. treedata.array = [ treedata.array, treedata.type[growsize] ]; } % put 'data' in 'treedata', at 'pos'. private define _tree_data_set(treedata, pos, data) { if (pos >= length(treedata.array)) _tree_data_grow(treedata, pos); treedata.array[pos] = data; if (pos >= treedata.pos) treedata.pos = pos+1; } % put 'data' in 'treedata', at 'pos', opening place for the new element. private define _tree_data_set_open(treedata, pos, data) { if (pos >= treedata.pos) { % at the end, easy: simply set it _tree_data_set(treedata, pos, data); } else { % treedata.pos is always < length(treedata.array), so there's no need to % check for grow here. treedata.array = [ treedata.array[[:pos-1]], data, treedata.array[[pos:]] ]; treedata.pos++; } } % add data to current node, opening space at 'pos'. private define _tree_elem_add_data(data) { variable treedata = get_blocal_var("TreeUserData"); if (treedata == NULL) { if (data == NULL) return; error("treemode: can't set data, tree_set_user_datatype() not called."); } _tree_data_set_open(treedata, what_line() - 1, data); } define printarr(name, arr) { variable s, S = "["+string(length(arr))+"]"; whatbuf(); setbuf("*array*"); insert("- array: "+name+", type = "+string(arr)+"\n"); foreach (arr) { s = string(()); insert(" <"+s+">\n"); } setbuf(); } % add an array of data to the current position, and following elements. % datas is an array filled with data to insert, and len should be equal % to length(datas). But datas can be NULL, if so an array of length 'len' % is generated. if 'placeholder' is an array of placeholder markers. % 'datas' contains elements only for real elements, elements for placeholders % is generated for every placeholder element not empty. private define _tree_data_add_datas(datas, len, placeholder) { variable treedata = get_blocal_var("TreeUserData"); variable pos = what_line() - 1; if (treedata == NULL) { if (datas == NULL) return; error("treemode: can't set data, tree_set_user_datatype() not called."); } if (datas == NULL) datas = treedata.type[len]; else if (len != length(datas)) verror("treemode: data len (%d) != requested len (%d).", length(datas), len); if (placeholder != NULL) { variable ph = Integer_Type[2*len]; variable d = treedata.type[2*len]; % ph contains 1 for every element that is a placeholder ph[*] = 1; ph[2*where(placeholder == "")+1] = 0; d[ [0:2*len-1:2] ] = datas; datas = d[where(ph == 1)]; len = length(datas); } if (pos >= treedata.pos) { treedata.array = [ treedata.array[[:pos-1]], datas ]; if (pos+len > treedata.pos) treedata.pos = pos+len; } else { treedata.array = [ treedata.array[[:pos-1]], datas, treedata.array[[pos:]] ]; treedata.pos+=len; } } % remove data for element, shrinking the array. private define _tree_elem_remove_data() { variable treedata = get_blocal_var("TreeUserData"); if (treedata == NULL) return; variable pos = what_line() - 1; variable lastelem = length(treedata.array)-1; if (pos == 0) treedata.array = treedata.array[[1:]]; else if (pos == lastelem) treedata.array = treedata.array[[:pos-1]]; else if (pos < lastelem) treedata.array = [ treedata.array[[:pos-1]], treedata.array[[pos+1:]] ]; else % ??? verror("can't remove elem %d, max %d!", pos, lastelem); treedata.pos --; } %}}} %{{{ Tree set mark % if you really know the exact mark to place, use this fast function. private define __tree_set_mark(mark) { del(); insert(mark); } % set the mark to 'mark' (should be "+" or "-") if this node has % at least a child, elsewhere set mark to '.'. % This is an internal function, so it expects to be already on the tree buffer. static define tree_set_mark(mark) { variable col1, col2 = 0; col1 = _tree_elem_get_column(); push_spot(); if (down(1)) col2 = _tree_elem_get_column(); pop_spot(); if (col2 <= col1) mark = "."; del(); insert(mark); } %}}} %{{{ Private Open/Close subtree functions % hides all children lines. if 'all' requested, set tree marks to 'close' state. static define _tree_close(all) { variable state = _tree_elem_state(); % Allow 'close all' on a closed subtree. if ((state == '-') or ((state == '+') and (all != 0))) { if (_tree_send_event(TREE_CLOSE) == 0) return 0; % vetoed by user function push_spot(); variable col = _tree_elem_get_column(); while (down(1) and (_tree_elem_get_column() > col)) { if (andelse { all } { _tree_elem_state() != '.' }) { if (_tree_send_event(TREE_CLOSE) == 1) tree_set_mark("+"); } set_line_hidden(1); } pop_spot(); tree_set_mark("+"); } } % tree open is a bit more complex: here are some helpers. private define _tree_has_placeholder(ph) { if (_tree_goto_child()) if (_tree_elem_state() == '.') if (strcmp(_tree_elem_get_name(), ph) == 0) return 1; return 0; } % send a TREE_OPEN or TREE_OPEN_PLACEHOLDER event. private define __tree_send_open_event(ph) { variable event = TREE_OPEN; if (ph != NULL) { push_spot(); if (_tree_has_placeholder(ph)) { _tree_delete_element(); _tree_elem_remove_data(); event = TREE_OPEN_PLACEHOLDER; } pop_spot(); } return _tree_send_event(event); } % open current node and all the children marked as opened (restore from a 'tree_close'). % if 'all' is set, open all the closed nodes. private define _tree_open(all) { variable state = _tree_elem_state(); % Allow 'open all' on a opened subtree. if ((state == '+') or ((state == '-') and (all != 0))) { variable ph = get_blocal_var("TreePlaceholder"); if (__tree_send_open_event(ph) == 0) return; push_spot(); variable col = _tree_elem_get_column(); while (down(1) and (_tree_elem_get_column() > col)) { set_line_hidden(0); if (_tree_elem_state() == '+') { if (andelse { all } {__tree_send_open_event(ph) == 1}) tree_set_mark("-"); else { % let it closed: skip to next sibling.. __tree_skip_children(); () = up(1); } } } pop_spot(); tree_set_mark("-"); } } %}}} %{{{ Tree Creation helpers (all private) % put the cursor on tree mark at every move, and send TREE_MOVE event if % the line changed %%%%private variable JGLine = NULL; private define _tree_update_hook() { variable oldline = get_blocal_var("TreeOldLine"); variable line = what_line(); %%%% JGLine = create_line_mark(color_number("menu_selection")); bol;skip_white;%_tree_goto_line_start(); if (line != oldline) () = _tree_send_event(TREE_MOVE); set_blocal_var(line, "TreeOldLine"); } % this puts a new mark on *OLD* line. private define _tree_create_mark(oldcol) { variable mark = ". "; variable col; bol;skip_white;%_tree_goto_line_start(); col = what_column; if (oldcol < col) mark = "- "; () = up(1); bol;skip_white;%_tree_goto_line_start(); insert(mark); () = down(1); return col; } % put tree marks on all the lines in the buffer private define _mark_all_buffer() { variable col; bob(); col = _tree_elem_get_column(); while(down_1) col = _tree_create_mark(col); } %}}} %%%% -------------- end of private functions --------------------- %{{{ Public Movement functions %!%+ %\function{tree_goto_child} % %\usage{Integer tree_goto_child([String buffer])} % %\description % % Try to go to the first child of current node. % Returns 1 if successful, 0 if this node has no children (in this % case, the cursor is not moved). % % Together with \var{tree_goto_next_sibling}, this can be used to % iterate through all the children of a node. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_goto_next_sibling, tree_goto_parent} %!%- public define tree_goto_child() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_goto_child(); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_goto_next_sibling} % %\usage{Integer tree_goto_next_sibling([String buffer])} % %\description % % Try to go to the next sibling node. % Returns 1 if successful, 0 if this node has no (more) siblings (in this % case, the cursor is not moved). % % Together with \var{tree_goto_child}, this can be used to % iterate through all the children of a node: % %%v+ % % place on the parent node, then do % if (tree_goto_child()) % do % { % % do whatever you want on current node % } % while (tree_goto_next_sibling()); %%v- % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_goto_child, tree_goto_parent, tree_goto_prev_sibling} %!%- public define tree_goto_next_sibling() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_goto_sibling(&down_1); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_goto_prev_sibling} % %\usage{Integer tree_goto_prev_sibling([String buffer])} % %\description % % Try to go to the previous sibling node. % Returns 1 if successful, 0 if this node has no (more) siblings (in this % case, the cursor is not moved). % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_goto_child, tree_goto_parent, tree_goto_next_sibling} %!%- public define tree_goto_prev_sibling() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_goto_sibling(&up_1); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_goto_parent} % %\usage{Integer tree_goto_parent([String buffer])} % %\description % % Try to go to the parent of current node. % Returns 1 if successful, 0 if this node has no parent (is the root node). % In this case, the cursor is not moved. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_goto_parent() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_goto_parent(); if (_NARGS == 1) setbuf(()); % from stack return c; } %}}} %{{{ Public Open/Close subtree functions %!%+ %\function{tree_close} % %\usage{Void tree_close([String buffer], Integer all)} % %\description % % Close the current node. If \var{all} is zero, leave all children % in their current state, Otherwise close also all children. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_open, tree_close_inside, tree_toggle} %!%- public define tree_close(all) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack _tree_close(all); if (_NARGS == 2) setbuf(()); % from stack } %!%+ %\function{tree_open} % %\usage{Void tree_open([String buffer], Integer all)} % %\description % % Open the current node, if \var{all} is zero, preserves the state of % all children, otherwise open all children recursively. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_close, tree_close_inside, tree_toggle} %!%- public define tree_open(all) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack _tree_open(all); if (_NARGS == 2) setbuf(()); % from stack } %!%+ %\function{tree_toggle} % %\usage{Void tree_toggle([String buffer], Integer all)} % %\description % % If the current node is open, closes it, else opens it. % This calls \var{tree_open} or \var{tree_close}. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_open, tree_close, tree_close_inside} %!%- public define tree_toggle(all) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack switch (_tree_elem_state()) { case '+' : _tree_open(all); } { case '-' : _tree_close(all); } { () = _tree_send_event(TREE_TOGGLE); } if (_NARGS == 2) setbuf(()); % from stack } %!%+ %\function{tree_close_inside} % %\usage{Void tree_close_inside([String buffer], Integer all)} % %\description % % If the current node is an open node, simply closes that node, % else closes the parent node of the current node. % % This calls \var{tree_close} to do the work. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_open, tree_close, tree_toggle} %!%- public define tree_close_inside(all) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack if (_tree_elem_state() != '-') !if (_tree_goto_parent()) return; _tree_close(all); if (_NARGS == 2) setbuf(()); % from stack } %}}} %{{{ Tree management: add/remove nodes %!%+ %\function{tree_add_element} % %\usage{Void tree_add_element([String buffer], String child, String name, data)} % %\description % % This functions adds a new node to a tree. % \var{child} indicates if the new node will be a sibling of current node % (in this case, it must by an empty string), or a child of current node, % (in this case \var{child} is used to indent the new node). % In both cases the new node will be put at the end of its level. % \var{name} is the string that will be shown on tree. % \var{data} is some user data associated to this tree node. You should call % \var{tree_set_user_datatype()} before any call with \var{data} != NULL. % % On exit the current node will be the newly inserted node. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_delete_element, tree_set_user_datatype} %!%- public define tree_add_element(child, name, data) { if (_NARGS == 4) whatbuf_setbuf(()); % on stack variable col = _tree_elem_get_column(); variable parentstate = ' '; % skip children. need if I'm adding a sibling. If this is a child, % this will put it at the end. __tree_skip_children(); () = up(1); % this also puts the point at eol. newline(); if (eobp()) { () = up(1); % allow insertion on an empty buffer child = ""; % and ignore child info! } goto_column(col); insert(child + ". " + name); bol;skip_white;%_tree_goto_line_start(); % redo tree mark on parent push_spot(); if (_tree_goto_parent()) { parentstate = _tree_elem_state(); % this is the first child, set mark to close if (parentstate == '.') { if (get_blocal_var("TreeInsertClose")) __tree_set_mark("+"); else __tree_set_mark("-"); parentstate = _tree_elem_state(); } } pop_spot(); % if parent is closed, hide the new element if (parentstate == '+') set_line_hidden(1); _tree_elem_add_data(data); if (_NARGS == 4) setbuf(()); %from stack } private define __tree_get_ph(have_placeholder, names) { variable ph = get_blocal_var("TreePlaceholder"); variable placeholder = String_Type[length(names)]; if (ph != NULL) { if (typeof(have_placeholder) == Array_Type) { if (length(have_placeholder) != length(names)) error("treemode: bad placeholder size"); placeholder[where(have_placeholder != 0)] = ph; placeholder[where(have_placeholder == 0)] = ""; return placeholder; } if (typeof(have_placeholder) == Integer_Type) if (have_placeholder != 0) { placeholder[*] = ph; return placeholder; } } placeholder[*] = ""; return placeholder; } %!%+ %\function{tree_add_children} % %\usage{Void tree_add_children([String buffer], Int indent, Int have_placeholder, String[] names, datas)} % %\description % % This functions adds some new nodes to an existing node on a tree. % \var{indent} indicates the indentation to apply to these nodes. % The new nodes will be put at the end of its level. % \var{names} is an array of strings that will be shown on tree. % \var{datas} is some user data associated to these tree nodes. You should call % \var{tree_set_user_datatype()} before any call with \var{datas} != NULL. % % On exit the current node will be the starting node. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_add_element, tree_delete_element, tree_set_user_datatype} %!%- public define tree_add_children(indent, have_placeholder, names, datas) { if (_NARGS == 5) whatbuf_setbuf(()); % on stack if (length(names) > 0) { variable col = _tree_elem_get_column(); variable parentstate = ' '; variable has_parent = 1; variable name; variable placeholder; variable i; placeholder = __tree_get_ph(have_placeholder, names); push_spot(); % on parent % skip children. __tree_skip_children(); () = up(1); % this also puts the point at eol. newline(); if (eobp()) { has_parent = 0; () = up(1); % allow insertion on an empty buffer } else col += indent; push_spot(); % on first child added __tree_insert_elem(names[0], col, indent, placeholder[0]); for (i = 1; i < length(names) ; i++) { newline(); __tree_insert_elem(names[i], col, indent, placeholder[i]); } pop_spot(); % return to first child % add data. %%%% if (__eqs(have_placeholder, 0)) if (andelse { typeof(have_placeholder) == Integer_Type } { have_placeholder == 0 }) _tree_data_add_datas(datas, length(names), NULL); % speed up else _tree_data_add_datas(datas, length(names), placeholder); pop_spot(); % return to parent if (has_parent) { if (get_blocal_var("TreeInsertClose")) { __tree_set_mark("-"); _tree_close(0); } else { __tree_set_mark("+"); _tree_open(0); } } } if (_NARGS == 5) setbuf(()); %from stack } %!%+ %\function{tree_delete_element} % %\usage{Void tree_delete_element([String buffer])} % %\description % % This functions deletes the current node on buffer \var{handle}. % If it has children, those are also deleted, recursively. % % On exit the current node will be set to the parent node of the deleted node. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_add_element} %!%- public define tree_delete_element() { if (_NARGS == 1) whatbuf_setbuf(()); % on stack variable state; variable col = _tree_elem_get_column(); % find the parent push_mark(); () = _tree_goto_parent(); state = _tree_elem_state(); exchange_point_and_mark(); % mark on parent, point on starting element %%% FIXME: this works only when removing leaves !!! %%% TODO: speed up(?): push_mark; __tree_skip_children; del_region. _tree_elem_remove_data(); % delete this node and all children do { _tree_delete_element(); } while (_tree_elem_get_column() > col); % return to parent, and rebuild mark pop_mark_1(); tree_set_mark(char(state)); if (_NARGS == 1) setbuf(()); %from stack } %}}} %{{{ Public element functions %!%+ %\function{tree_elem_state} % %\usage{Char tree_elem_state([String buffer])} % %\description % % Return the state of current tree element. \var{buffer} parameter % may be used if current buffer is not the wanted tree buffer. % % state is one of: % '+': is a tree 'folder', currently closed. % '-': is a tree 'folder', currently opened. % '.': is a tree 'leaf'. % %!%- public define tree_elem_state() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_elem_state(); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_elem_get_column} % %\usage{Integer tree_elem_get_column([String buffer])} % %\description % % Return the indentation (in chars) of current tree element. % TreeMode doesn't enforce a fixed indentation, it's up to the caller mode % to interpret this value. % TreeMode used this function internally to check if a node is a child % of the previous node. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_elem_get_column() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_elem_get_column(); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_elem_get_name} % %\usage{String tree_elem_get_name([String buffer])} % %\description % % Return the name of current tree element. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_elem_get_name() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_elem_get_name(); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_elem_get_data} % %\usage{(User type) tree_elem_get_data([String buffer])} % %\description % % Return the data associated with current tree element. The % type of data returned is the type defined using \var{tree_set_user_datatype()} % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_set_user_datatype} % %!%- public define tree_elem_get_data() { variable c; if (_NARGS == 1) whatbuf_setbuf(()); % on stack c = _tree_elem_get_data(); if (_NARGS == 1) setbuf(()); % from stack return c; } %!%+ %\function{tree_elem_set_data} % %\usage{Void tree_elem_set_data([String buffer,] data)} % %\description % % Set data for current tree element. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_elem_set_data(data) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack variable treedata = get_blocal_var("TreeUserData"); variable pos = what_line() - 1; if (treedata == NULL) error("treemode: can't set data, tree_set_user_datatype() not called."); _tree_data_set(treedata, pos, data); if (_NARGS == 2) setbuf(()); % from stack } %}}} %{{{ Tree interface %!%+ %\function{tree_build} % %\usage{Void tree_build([String buffer])} % %\description % % Given a buffer layered out as a tree, this functions add % tree marks and set up everything to handle this buffer % as a tree. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\seealso{tree_mode} %!%- public define tree_build() { if (_NARGS == 1) whatbuf_setbuf(()); % on stack flush("treemode: preparing tree..."); %%%%%%set_readonly(0); % rename current buffer, prepending "tree-" rename_buffer("tree-"+whatbuf()); _tree_untab_buffer(); _mark_all_buffer(); %%%%%%set_readonly(1); message("treemode: preparing tree... Done."); if (_NARGS == 1) setbuf(()); % from stack } %!%+ %\function{tree_set_user_func} % %\usage{Void tree_set_user_func([String buffer,] Ref func, Integer mask)} % %\description % % This functions sets a slang function to be called on tree events. % When an event occurs and it is present in \var{mask}, the \var{func} % function will be called with a parameter indicating % the event. \var{func} must return an integer, with value '0' if not futher % action should be taken, any other value if normal action should continue. % % Valid Actions are: % TREE_OPEN tree_open() called. % TREE_CLOSE tree_close() called. % TREE_TOGGLE tree_toggle() called on a leaf node. % TREE_MOVE a tree movement(). % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %\notes % More event may be added, test for equality when checking for an event. % %!%- public define tree_set_user_func(func, mask) { if (_NARGS == 3) whatbuf_setbuf(()); % on stack set_blocal_var(func, "TreeEventFunc"); set_blocal_var(mask, "TreeEventMask"); if (_NARGS == 3) setbuf(()); % from stack } %!%+ %\function{tree_set_user_datatype} % %\usage{Void tree_set_user_datatype([String buffer,] DataType datatype)} % %\description % % This functions sets a the type for the internal data array. It fails if % some data was already inserted in the tree (But elements without data are % allowed). % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_set_user_datatype(datatype) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack () = _tree_data_create(datatype); if (_NARGS == 2) setbuf(()); % from stack } %!%+ %\function{tree_set_close_on_insert} % %\usage{Void tree_set_close_on_insert([String buffer,] Integer close)} % %\description % % This functions sets a the flag for closing subtrees when inserting elements % (via \var{tree_add_element}. If \var{close} is zero, the parent node of the % new node will be opened. If \var{close} is not zero, the parent node will % be closed. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_set_close_on_insert(close) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack set_blocal_var(close, "TreeInsertClose"); if (_NARGS == 2) setbuf(()); % from stack } %!%+ %\function{tree_set_placeholder} % %\usage{Void tree_set_placeholder([String buffer,] String placeholder)} % %\description % % Defines a placeholder to use when \var{tree_add_children()} is called with % \var{have_placeholder} set to TRUE. % If a placeholder is present when trying to open a node, the placeholder % will be removed, and the user function (defined using \var{tree_set_user_func()}) % will be called with TREE_OPEN_PLACEHOLDER instead of TREE_OPEN. % % \var{buffer} parameter may be used if current buffer is % not the wanted tree buffer. % %!%- public define tree_set_placeholder(placeholder) { if (_NARGS == 2) whatbuf_setbuf(()); % on stack set_blocal_var(placeholder, "TreePlaceholder"); if (_NARGS == 2) setbuf(()); % from stack } %}}} %{{{ mode stuff %!%+ %\function{tree_build_kmap} % %\usage{Int tree_build_kmap(String kmap)} % %\description % % This function builds a base keymap for a generic tree mode. This is % NOT called by tree_mode(), You are free to call this and add your % own keys, or build a keymap from scratch. % Returns 1 if a new keymap was built, 0 otherwise. % %!%- public define tree_build_kmap(kmap) { !if (keymap_p(kmap)) { make_keymap(kmap); _for (32, 127, 1) undefinekey(char(()), kmap); definekey("tree_open(0)", " ", kmap); definekey("tree_toggle(0)", " ", kmap); definekey("tree_close(0)", Key_BS, kmap); definekey("tree_close_inside(0)", "/", kmap); definekey("tree_close_inside(0)", Key_Del, kmap); return 1; } return 0; } create_syntax_table(TreeMode); #ifdef HAS_DFA_SYNTAX static define setup_dfa_callback (name) { dfa_enable_highlight_cache("treemode.dfa", name); dfa_define_highlight_rule("^[ \t]*\\+\\ ", "keyword", name); dfa_define_highlight_rule("^[ \t]*\\-\\ ", "number", name); dfa_define_highlight_rule("^[ \t]*\\.\\ ", "comment", name); dfa_build_highlight_table(name); } dfa_set_init_callback(&setup_dfa_callback, TreeMode); %%% DFA_CACHE_END %%% #endif %!%+ %\function{tree_mode} % %\usage{Void tree_mode()} % %\description % % This functions enables tree mode on current buffer. It % expects an already marked tree (as built with \var{tree_build}), % or an empty buffer. % %\seealso{tree_build} %!%- public define tree_mode() { set_overwrite(1); set_buffer_modified_flag(0); () = tree_build_kmap("Treemode"); use_keymap("Treemode"); #ifdef HAS_DFA_SYNTAX enable_dfa_syntax_for_mode(TreeMode); #endif set_mode(TreeMode, 0); use_syntax_table(TreeMode); set_buffer_hook("update_hook", &_tree_update_hook); define_blocal_var("TreeEventFunc", NULL); % User Event Function define_blocal_var("TreeEventMask", NULL); % User Event Mask define_blocal_var("TreeUserData", NULL); % User Data Array define_blocal_var("TreeOldLine", -1); % Old line (to avoid extra TREE_MOVE events) define_blocal_var("TreeInsertClose", 1); % Insert will try to keep nodes closed define_blocal_var("TreePlaceholder", NULL); % Placeholder bob(); } public define tree_convert() { tree_build(); tree_mode(); () = tree_build_kmap("TreeConverted"); } %}}} provide("treemode"); jedmodes-2.5.7/diffmode/diffmode.sl0000644000175400017500000006727711307553145015523 0ustar mildegm% diff_mode.sl -*- mode: Slang; mode: fold -*- % %%exts:%% diff, patch % Unified diff mode viewer and editor for Jed %{{{ % % Written by Dino Leonardo Sangoi on a shiny day. % % It does highlighting a bit like mcedit (the midnight commander editor) does. % (It uses dfa syntax highlighting). % % It also helps editing diffs, usually an unsafe operation. Not that you % can do it blindly now, but at least this script can rebuild diff markers % after editing. You can also remove a whole block, adjusting the offsets % accordingly. Since version 2.1 you can also apply just one block. % % Editing works only on unified diffs right now, and probably forever (mostly % because I always use unified diffs). % % Versions % -------- % % 1.0.0pre2 2005-10-10 by sangoid % 2.0 2007-04-27 "Jedmodes" branch by GM % * set default colors re-using existing color definitions % (better defaults for non-black color schemes but still customisable) % * removed pre Jed 0.99.16 compatibility hack % * diff_top_of_file(), diff_top_of_block(): try below if there is no top % above -> lets diff_jump_to() also work from the top of the diff buffer % * diff_jump_to(): ask for path if file not found % * new: diff_jump() (after a patch by Lechee Lai) % 2.1 2007-07-21 % * frontend commands: diff(), diff_buffer(), diff_dir_files() % * use of walk.sl now optional % 2.1.1 2007-07-24 bugfix in diff_buffer, documentation fix % 2.1.2 2007-07-27 bugfix: diff_jump_to(): pop_spot after computing destination % 2.2 2007-09-03 % * highlight trailing whitespace (too often this makes all of the difference) % * bugfixes after report by P. Boekholt: % - use of diff() before declaration % - hidden dependency on shell_command() % - spurious arg to pop2puf() in diff() % - test for files in both dirs in diff_dir_files() % 2.2.1 2007-10-01 optional extensions with #if ( ) % 2.2.2 2007-10-04 no DFA highlight in UTF-8 mode (broken for multi-byte chars) % enable it with enable_dfa_syntax_for_mode("Diff"); % 2.2.3 2007-10-23 switch on highlight caching % 2.3 2007-12-20 standard color-name "trailing_whitespace" % implement Jörg Sommer's fix for DFA highlight under UTF-8 % 2.3.1 2009-01-26 don't hightlight whitespace in first (diff's ±) column % 2.3.2 2009-09-04 prepend buffer_dir to relative source file paths % 2.3.3 2009-10-05 fix autoloads (requires bufutils) % 2.3.4 2009-11-20 adapt to the changed require() behaviour in Jed 0.99.19 % % Usage % ----- % % Put diffmode.sl, treemode.sl, (and optionally walk.sl) in your % Jed library path (cf. get_jed_library_path()). % % Add to your .jedrc or jed.rc file something like % % autoload("diff_mode", "diffmode"); % add_mode_for_extension("diff", "diff"); % add_mode_for_extension("diff", "patch"); % % and every file with extension '.diff' or '.patch' will automagically % get the "diff" mode applied. % % Customization % ------------- % % Optionally you can set these variables: % % Diff_Use_Tree -> whether to use the (experimental) tree mode viewer for % patches containing more than one file. If zero, tree mode % is not used, else the value is the minimum number of files % needed inside a patch to trigger the tree mode viewer. % (default = 4, just a randomly choosen number) % % DiffTree_Indent -> how much to indent lines in tree mode viewer. Default = 8 % % You can customize the syntax highlight colors for "diff_block", "diff_junk", % "diff_deleted", "diff_added", "diff_oldfile", "diff_newfile", "diff_cmd" in % jed.rc, e.g. % % set_color("diff_deleted", "blue", "red"); % % Thanks to: % - John Davis, for this great editor. % - Abraham van der Merwe, I took some ideas (and maybe also some code...) % from his diff.sl. % - Guenter Milde, for the long emails we exchanged about jed modes (and for % a lot of slang code I'm using) %}}} % Requirements % ------------ %{{{ % Jed >= 0.99.16 % custom_color() % S-Lang 2 % "raw string literal"R #if (_jed_version > 9918) require("keydefs", "Global"); % standard mode, not loaded by default require("treemode", "Global"); % bundled with diffmode #else require("keydefs"); require("treemode"); #endif autoload("bufsubfile", "bufutils.sl"); autoload("close_buffer", "bufutils"); % Use walk.sl (for returning to buffers) if it is found in the library path % Alternatively, http://jedmodes.sf.net/mode/navigate can be used for this. #if (expand_jedlib_file("walk.sl") != "") require("walk"); #endif %}}} % Customizable settings % --------------------- %{{{ % Set Diff_Use_Tree to 0 to avoid using a tree view for the diff. % Otherwise, set it to the minimun number of files covered by the diff % needed to use the tree view. custom_variable("Diff_Use_Tree", 4); custom_variable("DiffTree_Indent", 8); % should tree pack single child nodes? custom_variable("DiffTree_Pack", 1); custom_variable("Diff_Cmd", "diff -u"); % command for diff-s % Default color scheme custom_color("diff_cmd", get_color("operator")); % diff custom_color("diff_oldfile", get_color("bold")); % --- custom_color("diff_newfile", get_color("number")); % +++ custom_color("diff_block", get_color("preprocess")); % @@ custom_color("diff_deleted", get_color("error")); % - custom_color("diff_added", get_color("keyword")); % + custom_color("diff_junk", get_color("comment")); % Only / Binary %}}} %%%% Diff low level helpers %{{{ % return true if I'm looking_at() a header marker. static define _diff_is_marker() { orelse { looking_at("+++ ") } { looking_at("--- ") } { looking_at("diff ") } { looking_at("Only in ") } { looking_at("Binary files ") }; } % extract information from a block header line: returns: % (position on old file, length on old file, position on new file, length on new file) % [ this heavily uses the stack features of slang ]. static define _diff_parse_block_info(l) { variable pos, len; % Uhmm, there's a better way to do this? if (string_match(l, "@@ \-\(\d+\),\(\d+\) \+\(\d+\),\(\d+\) @@"R, 1) == 0) error("malformed block header <"+l+">"); (pos, len) = string_match_nth(1); integer(l[[pos:pos+len-1]]); (pos, len) = string_match_nth(2); integer(l[[pos:pos+len-1]]); (pos, len) = string_match_nth(3); integer(l[[pos:pos+len-1]]); (pos, len) = string_match_nth(4); integer(l[[pos:pos+len-1]]); % return (oldpos,oldlen,newpos,newlen) } % count the added, deleted, and common lines in a block (is up to the caller % to narrow a region to a block, and to put the point at the start). % returns (added lines, deleted lines, common lines) static define _diff_count_block() { variable countplus = 0; variable countminus = 0; variable countspace = 0; while (down_1) { bol(); if (eobp) break; switch(what_char()) { case '+' : countplus++; } { case '-' : countminus++; } { countspace++; } } return (countplus, countminus, countspace); } % skip a marker in the given direction (dir = 1 -=> down, dir = -1 -=> up) static define _diff_skip_header(dir) { variable f = &up_1; if (dir > 0) f = &down_1; while (bol(), _diff_is_marker()) !if (@f()) break; } %%%%}}} %%%% Fast movement functions: these are a bit like c_{top,end}_of_function(). %{{{ % Go to the top of diffed file define diff_top_of_file() { % push mark instead of spot to be able to pop it without going there push_mark(); % search the diff marker. if (andelse{bol_bsearch("--- ") == 0}{bol_fsearch("--- ") == 0}) { pop_mark(1); error("start of file not found."); } % found, see if there's a diff command line before. if (up_1()) { bol(); if (looking_at("diff ") == 0) go_down_1(); } pop_mark(0); } % Go to the end of diffed file define diff_end_of_file() { % Skip Junk AND first marker go_down_1(); _diff_skip_header(1); if (bol_fsearch("--- ") == 0) { % I can only assume this is the last file-block. eob(); % if point is on a void line, this is the last line in the file, so % skip it. if (bolp()) go_up_1(); } _diff_skip_header(-1); go_down_1(); } % Go to the top of diffed block define diff_top_of_block() { push_mark(); if (andelse{bol_bsearch("@@ ") == 0}{bol_fsearch("@@ ") == 0}) { pop_mark(1); error("start of block not found."); } pop_mark(0); } % Go to the end of diffed block define diff_end_of_block() { % Skip Junk _diff_skip_header(1); go_down_1(); if (bol_fsearch("@@ ") != 0) { go_up_1; _diff_skip_header(-1); go_down_1; } else { % uhm, maybe this is the last block diff_end_of_file(); } } %%%%}}} %%%% Mark and narrow blocks %{{{ % mark the current file. if 'skipheader' is != 0, don't mark the header. define diff_mark_file(skipheader) { % if the point is in a header, mark the *next* file, not the previous. _diff_skip_header(1); diff_top_of_file(); if (skipheader) _diff_skip_header(1); push_visible_mark(); diff_end_of_file(); } % mark the current block. define diff_mark_block(skipheader) { % if the point is in a header, mark the *next* block, not the previous. !if (looking_at("@@ ")) diff_top_of_block(); if (skipheader) { go_down_1(); bol(); } push_visible_mark(); diff_end_of_block(); } % mark the +++ --- header lines static define mark_file_header() { diff_top_of_file(); push_visible_mark(); _diff_skip_header(1); } % narrows the current file. define diff_narrow_to_file(skipheader) { diff_mark_file(skipheader); eol(); !if (eobp()) go_up_1(); % don't get the last line narrow(); } % narrows the current block. define diff_narrow_to_block(skipheader) { diff_mark_block(skipheader); eol(); !if (eobp()) go_up_1(); % don't get the last line narrow(); } %%%%}}} %%%% Redo diff markers after editing %{{{ % Rewrite a block header after editing it. 'old_off' is the offset to apply % to line numbers for 'old' side. 'new_off' is the offset to apply to line % numbers on the 'new' side. % returns two values: old_off and new_off modified accordinly to changes on % this block (so returned values can be passed again to diff_redo_block for % the next block in this file. define diff_redo_block(old_off, new_off) { variable countminus = 0; variable countplus = 0; variable countspace = 0; variable oldpos, oldsize, newpos, newsize; variable c; variable oldheader, newheader; push_spot(); diff_narrow_to_block(0); bob(); oldheader = line_as_string(); (oldpos, oldsize, newpos, newsize) = _diff_parse_block_info(oldheader); (countplus, countminus, countspace) = _diff_count_block(); countplus += countspace; countminus += countspace; newheader = sprintf("@@ -%d,%d +%d,%d @@", oldpos+old_off, countminus, newpos+new_off, countplus); flush(sprintf("@@ -%d,%d +%d,%d @@ --> %s", oldpos, oldsize, newpos, newsize, newheader)); if (strcmp(oldheader, newheader) != 0) { bob(); delete_line(); insert(newheader + "\n"); } widen(); pop_spot(); return (old_off + countminus - oldsize, new_off + countplus - newsize); } % redo all blocks of this file, starting at block containing the cursor. static define _diff_redo_from_here(oldoff, newoff) { variable done; diff_end_of_block(); diff_top_of_block(); do { (oldoff, newoff) = diff_redo_block(oldoff, newoff); diff_end_of_block(); } while (looking_at("@@ ")); } % redo all blocks on this file. define diff_redo_file() { push_spot(); diff_narrow_to_file(0); bob(); _diff_redo_from_here(0, 0); widen(); pop_spot(); } %%%%}}} %%%% Remove junk routines %{{{ % Remove "Only in..." lines (from diffs without -N) define diff_remove_only_lines() { push_spot(); bob(); while (bol_fsearch("Only in ")) delete_line(); pop_spot(); } % Remove "Binary files..." lines define diff_remove_binary_lines() { push_spot(); bob(); while (bol_fsearch("Binary files ")) delete_line(); pop_spot(); } define diff_remove_junk_lines() { diff_remove_only_lines(); diff_remove_binary_lines(); } %%%%}}} %%%% Remove block, optionally rebuilding markers %{{{ define diff_remove_block(redo) { variable countplus, countminus; push_spot(); % Ensure that we don't cross a file-block boundary diff_narrow_to_file(0); pop_spot(); eol(); diff_narrow_to_block(0); diff_top_of_block(); % calculate deltas to apply to following blocks (countplus, countminus, ) = _diff_count_block(); mark_buffer(); del_region(); widen(); % block if (eobp()) { if (what_line <= 4) { % This is the last block in this file, delete also the file header mark_buffer(); del_region(); } } else { if (redo) { push_spot(); diff_end_of_block(); _diff_redo_from_here(0, countminus-countplus); pop_spot(); } } widen(); % file % All this leaves an extra void line, kill it !if (eobp()) delete_line(); % place the point at the beginning of the next block !if (looking_at("@@ ")) { diff_end_of_block(); diff_top_of_block(); } } % remove a whole file block (far easier than a single block) define diff_remove_file() { diff_mark_file(0); del_region(); } % Get path of source file (If 'new' is true, new file, else old file. define diff_get_source_file_name(new) { variable marker, endcol, name, dir; if (new) marker = "+++ "; else marker = "--- "; push_spot(); diff_top_of_file(); () = bol_fsearch(marker); name = line_as_string()[[4:]]; % trim leading marker name = strtrim(strtok(name, "\t")[0]); % trim trailing date pop_spot(); % prepend buffer dir to relative path names ( , dir, , ) = getbuf_info(); name = path_concat(dir, name); !if (file_status(name) == 1) name = read_with_completion("Please adjust path:", "", name, 'f'); return name; } % apply just one block #ifexists bufsubfile define diff_apply_block() { variable patchfile, oldfile = diff_get_source_file_name(0); variable buf = whatbuf(); push_spot(); mark_file_header(); patchfile = bufsubfile(); pop_spot(); push_spot(); diff_mark_block(0); () = append_region_to_file(patchfile); do_shell_cmd(sprintf("patch %s %s", oldfile, patchfile)); pop2buf(buf); pop_spot(); diff_remove_block(1); } #endif %%%%}}} %%%% Standard mode things: keymap, syntax, highlighting %{{{ private variable mode = "Diff"; define diff_add_saurus_bindings() { definekey("diff_top_of_file", Key_Shift_F11, mode); definekey("diff_end_of_file", Key_Shift_F12, mode); definekey("diff_top_of_block", Key_Ctrl_F11, mode); definekey("diff_end_of_block", Key_Ctrl_F12, mode); definekey("(,) = diff_redo_block(0,0)", Key_F12, mode); definekey("diff_redo_file()", Key_F11, mode); definekey("diff_remove_block(1)", Key_F8, mode); definekey("diff_remove_only_lines()", Key_F9, mode); definekey("diff_jump_to(1)", "^V", mode); definekey("diff_jump", "\r", mode); % Return: "intelligent" jump %% Other Functions % diff_mark_file(skipheader); % diff_mark_block(skipheader); % diff_narrow_to_file(skipheader); % diff_narrow_to_block(skipheader); } !if (keymap_p(mode)) { make_keymap(mode); diff_add_saurus_bindings(); } create_syntax_table(mode); % Highlighting % ------------ % NEEDS dfa for this mode to work. #ifdef HAS_DFA_SYNTAX dfa_define_highlight_rule("^diff .*", "diff_cmd", mode); dfa_define_highlight_rule("^\+\+\+ .*"R, "diff_newfile", mode); dfa_define_highlight_rule("^--- .*", "diff_oldfile", mode); % + or - eventually followed by something ending in non-whitespace: dfa_define_highlight_rule("^\\+(.*[^ \t])?", "diff_added", mode); dfa_define_highlight_rule("^-(.*[^ \t])?", "diff_deleted", mode); % dfa_define_highlight_rule("^Only .*", "diff_junk", mode); dfa_define_highlight_rule("^Binary .*", "diff_junk", mode); dfa_define_highlight_rule("^@@ .*", "diff_block", mode); % non-unified diffs: dfa_define_highlight_rule("^> .*", "diff_added", mode); dfa_define_highlight_rule("^< .*", "diff_deleted", mode); % trailing whitespace dfa_define_highlight_rule("^ $", "Qnormal", mode); % not in the first column dfa_define_highlight_rule("[ \t]+$", "Qtrailing_whitespace", mode); % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); enable_dfa_syntax_for_mode(mode); #endif %%%%}}} %%%% Jump to functions %{{{ % Open diff source file. If 'new' is true, open the new version, else open the % old version. define diff_jump_to(new) { variable name, pos, newpos; variable delta = what_line(); % TODO: Improve computation of line to jump to. % Eventually consider manually added and removed lines while computing % delta (or manually call diff_redo_file() befor jumping). #ifexists walk_forward walk_mark_current_position(); #endif push_spot(); % save current position diff_top_of_block(); delta -= what_line(); line_as_string(); % on stack (pos, , newpos, ) = _diff_parse_block_info(); if (new) pos = newpos; pos += delta; name = diff_get_source_file_name(new); pop_spot(); () = read_file(name); goto_line(pos); vmessage("%s:%d", name, pos); #ifexists walk_forward walk_goto_current_position(); walk_store_marked_position(); #else sw2buf(whatbuf()); #endif } %%%%}}} %%%% Jump to "right" source, ('+' to new, '-' to old) %{{{ define diff_jump() { variable ch; push_spot(); bol(); ch = what_char(); pop_spot(); switch (ch) { case '-': diff_jump_to(0); } { case '+': diff_jump_to(1); } % { message ("not on a -/+ marked line"); } { diff_jump_to(0); } % there is a binding for jump_to(1) % TODO: ask in minibuffer for new/old? } %%%%}}} %%%% Menu %{{{ %%%% % Adds to the assoc array 'names' all the file names in this diff % (taking the 'new' versions, i.e. those with '+++'). % key is the name, value is the line in diff where the file-block starts. static define _get_files_names(names, func) { variable s; bob; while (bol_fsearch("+++ ")) { % grab the name goto_column(5); push_mark(); if (ffind("\t") == 0) eol(); % error("invalid diff"); s = bufsubstr(); % find the top of this block, to get the correct line number. push_spot(); _diff_skip_header(-1); go_down_1(); names[s] = @func; pop_spot(); } } static define get_files_names(names) { _get_files_names(names, &what_line); } static define get_files_names_as_marks(names) { _get_files_names(names, &create_user_mark); } % Adds to the assoc array 'names' all lines containing % "Only in " and "Binary files " lines. % (taking the 'new' versions, i.e. those with '+++'). % key is the name, value is -1 (we don't care where these are) % TODO: Add those as 'real' files to tree, do some parsing to get the full % name from 'Only in', and pick only the first (or last?) name in % 'Binary files'. static define get_files_markers(names) { variable s; bob; while (re_fsearch("^[OB][ni][ln][ya][ r][iy][n ][ f]")) { if (looking_at("Only in ") or looking_at("Binary files ")) { push_mark(); eol; s = bufsubstr(); names[s] = -1; } } } static define files_popup_callback(popup) { variable key, line, names = Assoc_Type[Int_Type]; push_spot(); get_files_names(names); pop_spot(); variable keys = assoc_get_keys(names); keys = keys[array_sort(keys)]; foreach key (keys) { line = names[key]; menu_append_item(popup, key, &goto_line, line); } } public define diff_init_menu(menu) { menu_append_popup(menu, "&File Blocks"); menu_set_select_popup_callback(strcat(menu, ".&File Blocks"), &files_popup_callback); menu_append_separator(menu); menu_append_item(menu, "&top of block", "diff_top_of_block"); menu_append_item(menu, "&end of block", "diff_end_of_block"); menu_append_item(menu, "&Top of file block", "diff_top_of_file"); menu_append_item(menu, "&End of file block", "diff_end_of_file"); menu_append_separator(menu); menu_append_item(menu, "&mark block", "diff_mark_block", 0); menu_append_item(menu, "&Mark file block", "diff_mark_file", 0); #ifexists bufsubfile menu_append_item(menu, "&Apply block", "diff_apply_block"); #endif menu_append_item(menu, "&Delete Block", "diff_remove_block", 1); menu_append_separator(menu); menu_append_item(menu, "Goto &old file", "diff_jump_to", 0); menu_append_item(menu, "Goto &new file", "diff_jump_to", 1); menu_append_separator(menu); menu_append_item(menu, "Re&write block &header", "(,) = diff_redo_block(0,0)"); menu_append_item(menu, "Re&Write all headers", "diff_redo_file"); menu_append_item(menu, "Delete &junk lines", "diff_remove_junk_lines"); menu_append_item(menu, "&Rerun diff", "diff_rerun"); menu_append_item(menu, "Rerun re&versed", "diff_rerun_reversed"); } %%%%}}} %%%% Tree View %{{{ % This variable contains a mark considered not valid static variable InvMark; define difftree_goto_pos() { variable l = what_line, mode; variable li; li = tree_elem_get_data(); if (li == NULL) error("diffmode: cannot show this item."); if (li == InvMark) error("diffmode: mark"); #ifexists walk_forward walk_mark_current_position(); #endif setbuf(user_mark_buffer(li)); widen(); % just in case... goto_user_mark(li); diff_narrow_to_file(0); bob; #ifexists walk_forward walk_goto_current_position(); walk_store_marked_position(); #endif } define difftree_goto_pos_event(event) { difftree_goto_pos(); return 1; } % Recursive function: % for every row of 'aa' between 'start' and 'end', check the element % at column 'depth', until finds a different element. static define _build_section(base, aa, start, end, depth, km); static define _build_section(base, aa, start, end, depth, km) { variable child = " "; variable i, firststart = start; flush("depth " +string(depth)+", range ["+string(start)+":"+string(end)+"]"); for (i = start; i < end; i++) { if (aa[start][depth] != aa[i][depth]) { % this element is different % insert base if (base != "") tree_add_element(child, base, InvMark); base = aa[start][depth]; if (depth == length(aa[start])-1) % this is the last element in this row, insert it. tree_add_element(child, base, km[start]); else % run on next depth _build_section(base, aa, start, i, depth+1, km); % turn back to parent, clear base, and set new start. () = tree_goto_parent(); base = ""; start = i; } } % here we are at the end of our run, handle the last element if ((firststart == start) and DiffTree_Pack) { % all the block has the same column, pack it with the next if (base != "") base += "/"; base += aa[start][depth]; } else { % put base on tree if (base != "") tree_add_element(child, base, InvMark); base = aa[start][depth]; } if (depth == length(aa[start])-1) tree_add_element(child, base, km[start]); else _build_section(base, aa, start, end, depth+1, km); % goto parent, but not if I have packed the tree. !if ((firststart == start) and DiffTree_Pack) () = tree_goto_parent(); } % fill the tree static define insert_lines(names, marks) { variable i = 0; variable count = 0; variable oldnode, node; variable aa; variable depth = 0; % 'depth' is the element for every line that % _build_section() should handle. variable I; % array sort index. variable ks = assoc_get_keys(names); % only the names. variable km = assoc_get_values(names); % sort the names,keeping ks and km in synch I = array_sort(ks); ks = ks[I]; km = km[I]; % SLang powerfulness: build an array of arrays containing each % a path element. e.g. if: % ks[0] == "/home/sauro/.jedrc" % ks[1] == "/home/sauro/.jed/home-lib.sl" % this builds: % aa[0] = [ "", "home", "sauro", ".jedrc" ]; (length = 4) % aa[1] = [ "", "home", "sauro", ".jed", "home-lib.sl" ]; (length = 5) % note the first void element, this is because of absolute paths % but usually patches use relative ones aa = array_map(Array_Type, &strchop, ks, '/', 0); % handle absolute paths, setting 'depth' to 1 to tell % _build_depth() to skip first column if (strcmp(aa[0][0], "") == 0) depth = 1; %%% tree_set_user_datatype(Integer_Type); InvMark = create_user_mark(); _build_section("", aa, 0, length(aa), depth, km); % that's all folks. } public define difftree() { variable names = Assoc_Type[Mark_Type]; variable marks = Assoc_Type[Int_Type]; variable diffbuf, difftreebuf; get_files_names_as_marks(names); get_files_markers(marks); diffbuf = whatbuf(); difftreebuf = "*tree of "+diffbuf+"*"; if (bufferp(difftreebuf)) delbuf(difftreebuf); setbuf(difftreebuf); tree_mode(); tree_set_user_datatype(Mark_Type); if (tree_build_kmap("TreeDiff")) { definekey("tree_open(1)", "[", "TreeDiff"); definekey("tree_close(1)", "]", "TreeDiff"); definekey("tree_toggle(0)", " ", "TreeDiff"); definekey("difftree_goto_pos", "^M", "TreeDiff"); } insert_lines(names, marks); sw2buf(difftreebuf); tree_set_user_func(&difftree_goto_pos_event, TREE_TOGGLE); use_keymap("TreeDiff"); run_mode_hooks("difftree_mode_hook"); } %%%%}}} static define check_num_files(c) { bob(); while ((not eobp()) and (c > 0)) { diff_end_of_file(); c--; } bob(); return c; } public define diff_mode() { set_mode(mode, 0); use_syntax_table(mode); use_keymap(mode); mode_set_mode_info(mode, "init_mode_menu", &diff_init_menu); set_buffer_undo(1); run_mode_hooks("diff_mode_hook"); if ((Diff_Use_Tree > 0) and (check_num_files(Diff_Use_Tree) == 0)) { flush("Building diff tree..."); difftree(); flush("Building diff tree... Done."); } } % Frontend commands % ----------------- %{{{ % diff 'wizard': call diff system command and display result in diff_mode public define diff() % (old, new) { variable old, new; (old, new) = push_defaults( , , _NARGS); variable prompt = sprintf("Compare (%s) ", Diff_Cmd); if (old == NULL) old = read_with_completion(prompt, "", "", 'f'); if (new == NULL) new = read_with_completion(prompt + old + " to", "", "", 'f'); % Prepare the output buffer #ifexists popup_buffer popup_buffer("*diff*", 1.); % use up to 100% of screen size #else pop2buf("*diff*"); #endif set_readonly(0); erase_buffer(); % call the diff command flush("calling " + Diff_Cmd); shell_perform_cmd(strjoin([Diff_Cmd, old, new], " "), 1); set_buffer_modified_flag(0); if (bobp() and eobp()) { close_buffer(); message("no differences found"); return; } fit_window(get_blocal("is_popup", 0)); diff_mode(); define_blocal_var("generating_function", [_function_name, old, new]); } % save the buffer to a tmp file and get the diff to a second file #ifexists bufsubfile public define diff_buffer() { variable prompt = sprintf("Compare (%s) buffer to ", Diff_Cmd); variable file1 = read_with_completion(prompt, "", "", 'f'); variable file2 = bufsubfile(); diff(file1, file2); } # endif % list the differences between all equally named files in both dir1 and dir2 define diff_dir_files(dir1, dir2) { variable file, cmd; dir1 = expand_filename(dir1); dir2 = expand_filename(dir2); sw2buf("*diff*"); erase_buffer(); vinsert("Comparing equally named files in '%s'\n", dir1); vinsert("and '%s'\n", dir2); foreach file (listdir(dir1)) { if(file_status(path_concat(dir2, file)) != 1) continue; % file does not exist in dir2 cmd = sprintf("diff -u %s %s", path_concat(dir1, file), path_concat(dir2, file)); % Insert a separating header for every file pair % TODO: Add a syntax highlight rule??? vinsert("*** diff '%s'\n", file); insert("===============================================================\n"); set_prefix_argument(1); do_shell_cmd(cmd); eob(); newline; } diff_mode; } %}}} %%%% Re-run the diff command %{{{ define diff_rerun() { variable line = what_line(), oldfile = diff_get_source_file_name(0), newfile = diff_get_source_file_name(1); diff(oldfile, newfile); goto_line(line); } % swap the order of the diffed files define diff_rerun_reversed() { variable line = what_line(), oldfile = diff_get_source_file_name(0), newfile = diff_get_source_file_name(1); diff(newfile, oldfile); goto_line(line); } %%%%}}} jedmodes-2.5.7/email/0000755000175400017500000000000011702651666012703 5ustar mildegmjedmodes-2.5.7/email/mailcrypt.sl0000644000175400017500000000545510323260560015243 0ustar mildegm% mailcrypt.sl % Interface to GnuPG % % $Id: mailcrypt.sl,v 1.1 2005/10/12 19:18:08 boekholt Exp $ % Keywords: mail % % Copyright (c) 2003,2005 Paul Boekholt. No warranty. % Released under the terms of the GNU GPL (version 2 or later). % % This was formerly gpg.sl, but that name conflicts with a gpg.sl in the % standard library. provide ("mailcrypt"); private variable password = ""; private variable pw_time = 0; custom_variable("Mailcrypt_Comment", "processed by mailcrypt.sl "); % comma separated list of recipients custom_variable("Mailcrypt_Recipients", ""); private define read_password() { variable str = "enter password: ", password = " ", c; forever { c = get_mini_response (str); if (c == '\r') return password[[1:]]; % p[[:-2]] wraps around or something when p has len 1 if (c == 127) % backspace { password = password[[:-2]]; str = str[[:-2]]; } else { password += char(c); str += "*"; } } } private define gpg(options, give_password, comment) { variable cmd, tmp_file, err_file, buf = whatbuf, gbuf = " *mailcrypt*"; push_narrow; if (is_visible_mark) narrow; mark_buffer; variable contents = bufsubstr; if (bufferp(gbuf)) delbuf(gbuf); setbuf(gbuf); tmp_file = dircat (Jed_Home_Directory, "gpgpipe"); err_file = dircat (Jed_Home_Directory, "gpgerr"); cmd = strcat ("gpg ", options, " > ", tmp_file, " 2> ", err_file); ERROR_BLOCK { () = delete_file (tmp_file); delbuf(gbuf); sw2buf(buf); pop_narrow; pop2buf("*gpg errors*"); erase_buffer; ()=insert_file(err_file); password = ""; pop2buf(buf); } if(give_password) { if (password == "" or _time - pw_time > 360) password = read_password; pw_time = _time(); insert(password + "\n"); } insert(contents); mark_buffer; if(pipe_region (cmd) > 1) { error ("GPG returned an error."); } delbuf(gbuf); setbuf(buf); erase_buffer; () = insert_file(tmp_file); () = delete_file (tmp_file); bob; if (andelse {comment} {bol_fsearch("Comment:")}) { go_right(9); del_eol; insert(Mailcrypt_Comment); } pop_narrow; } public define mc_encrypt() { variable Bob = read_with_completion (Mailcrypt_Recipients, "Recipients", "", "", 's'); if (get_y_or_n("Sign the message")) gpg (sprintf ("-sea --batch --always-trust --no-tty --quiet --passphrase-fd 0 -r %s", Bob), 1, 1); else gpg(sprintf("-ea --batch --always-trust --no-tty -r %s", Bob), 0, 1); } public define mc_decrypt() { gpg("--no-tty --quiet --passphrase-fd 0", 1, 0); } public define mc_sign() { gpg(sprintf("--clearsign --no-tty --quiet --passphrase-fd 0"), 1, 1); } % In case you take a break, or typed a wrong password public define mc_forget_password() { password = ""; } jedmodes-2.5.7/email/email.sl~0000644000175400017510000003476111702651461015224 0ustar mildemilde% email.sl -*- mode: SLang; mode: Fold -*- % % $Id: email.sl,v 1.8 2008/02/23 07:21:21 paul Exp paul $ % Keywords: mail % % Copyright (c) 2003-2008 Paul Boekholt, Morten Bo Johansen % Released under the terms of the GNU GPL (version 2 or later). % % This file was written by the following people: % Ulli "Framstag" Horlacher -> mail_mode % Thomas Roessler -> mail_mode light % Abraham vd Merwe % Johann Botha -> muttmail % Ulli Horlacher -> mailmode (muttmail light) % Paul Boekholt % Morten Bo Johanssen -> email % 2005 Joerg Sommer % % This mail mode should work with both sendmail.sl and Mutt. # autoload("mail_mode", "email.sl"); add_completion("mail_mode"); # provide("email"); require("keydefs"); _autoload ("rebind", "bufutils", "string_nth_match", "strutils", "mc_encrypt", "mailcrypt", "mc_sign", "mailcrypt", "ispell_region", "ispell", 5); if ("" == current_namespace()) implements ("email"); % Set the threshold for the number of quote levels beyond which you % consider it a waste of time to deal with them. E.g. setting the value % to 2 would delete all quote levels beyond the second level. The number % includes the level you create yourself when you reply. A value of 0 % disables deletion. custom_variable ("Email_Quote_Level_Threshold", 0); % Your quoting string custom_variable ("Mail_Quote_String", "> "); % Do we recognize mbox style "From " lines as headers? % for backwards compatibility ... custom_variable ("mail_mode_have_mbox", 1); custom_variable ("Email_Have_Mbox", mail_mode_have_mbox); % Since mailedit.sl calls this MailEdit_Quote_Chars, we might as well follow % suit. custom_variable ("MailEdit_Quote_Chars", ">:|"); %{{{ static variables variable mode = "email"; % List of things that look like non-nested quotes (as Emacs' supercite % makes) in this buffer. We assume that you don't try to edit two emails % at once. variable sc_quotes = Assoc_Type[Integer_Type]; %}}} %{{{ keymap ifnot (keymap_p(mode)) make_keymap (mode); rebind("format_paragraph", "email_reformat", mode); definekey_reserved ("kill_this_level_around_point", " ", mode); definekey_reserved ("email_delete_quoted_sigs", "", mode); definekey_reserved ("remove_excess_quote_levels", "", mode); definekey_reserved ("email_attach_file", "", mode); definekey_reserved ("email_sign", "/s", mode); definekey_reserved ("email_encrypt", "/e", mode); definekey_reserved ("ispell_message", "i", mode); %}}} %{{{ syntax highlighting create_syntax_table (mode); define_syntax ("-a-zA-Z",'w',mode); % words define_syntax ("0-9",'0',mode); % numbers define_syntax (",;:",',',mode); % delimiters define_syntax ('*', '\'', mode); % *bold* define_syntax('>', '#', mode); % quotes set_syntax_flags(mode, 0x20 | 0x80); static variable color_from = "comment"; static variable color_to = "keyword1"; static variable color_subject = "number"; static variable color_header = "..."; static variable color_url = "keyword"; static variable color_email = "keyword"; static variable color_signature = "comment"; static variable color_reply1 = "preprocess"; static variable color_reply2 = "string"; static variable color_smiley = "operator"; static variable color_bold = "string"; static variable color_underline = "delimiter"; static variable color_italic = "delimiter"; #ifdef HAS_DFA_SYNTAX % The highlighting copes with email addresses and url's dfa_enable_highlight_cache ("email.dfa",mode); dfa_define_highlight_rule("[^ -@\[-`{-~]+"R, "Knormal", mode); dfa_define_highlight_rule ("^(To|Cc|Newsgroups): .*",color_to,mode); dfa_define_highlight_rule ("^Date: .*",color_header,mode); dfa_define_highlight_rule ("^From: .*",color_from,mode); dfa_define_highlight_rule ("^Subject: .*",color_subject,mode); dfa_define_highlight_rule ("(http|ftp|file|https)://[^ \t\n>]+",color_url,mode); dfa_define_highlight_rule ("[^ \t\n<]*@[^ \t\n>]+",color_email,mode); dfa_define_highlight_rule ("^-- $",color_signature,mode); dfa_define_highlight_rule ("^> ?> ?> ?> ?> ?>.*",color_reply2,mode); dfa_define_highlight_rule ("^> ?> ?> ?> ?>.*", color_reply1,mode); dfa_define_highlight_rule ("^> ?> ?> ?>.*", color_reply2,mode); dfa_define_highlight_rule ("^> ?> ?>.*", color_reply1,mode); dfa_define_highlight_rule ("^> ?>.*", color_reply2,mode); dfa_define_highlight_rule ("^>.*", color_reply1,mode); dfa_define_highlight_rule ("[\\(\\)]+-?[:;P\\^]|[:;P\\^]-?[\\(\\)]+","color_smiley",mode); dfa_define_highlight_rule ("[^ ]_[a-zA-Z]+_","normal",mode); dfa_define_highlight_rule ("_[a-zA-Z]+_[^ ]","normal",mode); dfa_define_highlight_rule ("_[a-zA-Z]+_",color_underline,mode); dfa_define_highlight_rule ("\\*[a-zA-Z]+\\*",color_bold,mode); dfa_define_highlight_rule ("[^ ]/[a-zA-Z]+/","normal",mode); dfa_define_highlight_rule ("/[a-zA-Z]+/[^ ]","normal",mode); dfa_define_highlight_rule ("/[a-zA-Z]+/",color_italic,mode); dfa_build_highlight_table (mode); enable_dfa_syntax_for_mode(mode); #endif %}}} %{{{ static functions %{{{ mostly header stuff static define email_is_tag () { push_spot_bol (); (Email_Have_Mbox && bobp () && looking_at ("From ") || 1 == re_looking_at ("^[A-Za-z][^: ]*:")); pop_spot (); } % I don't want to set a user mark in mail_mode(), because maybe headers etc. % are added after mail_mode() is run static define email_have_header () { push_spot_bob (); email_is_tag (); pop_spot (); } static define email_is_body () { ifnot (email_have_header()) return 1; push_spot (); (bol_bsearch("\n") || bol_bsearch("--- Do not modify this line. Enter your message below")); pop_spot (); } static define email_parsep () { push_spot_bol (); (looking_at("-- ") || email_is_body() && (skip_chars(MailEdit_Quote_Chars+" \t"), eolp()) || email_is_tag () || (skip_white(), eolp())); pop_spot (); } static define reformat_header () { push_spot (); while (not email_is_tag()) { ifnot (up_1()) { pop_spot (); return; } } bol (); ()=ffind_char(':'); go_right_1 (); push_spot (); insert ("\n"); bol_trim (); insert (" "); call ("format_paragraph"); pop_spot (); del (); pop_spot (); } static define goto_end_of_headers() { bob(); ifnot (bol_fsearch("--- Do not modify this line. Enter your message below") || bol_fsearch ("\n")) { eob(); newline(); newline(); } go_up_1; } static define narrow_to_body() { push_spot; ifnot(email_have_header) mark_buffer(); else { goto_end_of_headers; go_down(2); push_mark_eob; } narrow; pop_spot; } %}}} %{{{ quote reformatting % check if we're looking at a non-nested quote. static define check_sc_quote() { variable sc_quote; foreach sc_quote (sc_quotes) using ("keys") { if (looking_at(sc_quote)) return sc_quote; } return ""; } static define requote_buffer(quote) { bob(); do { insert(quote); } while (down_1()); } % reformat quoted text static define reformat_quote() { variable quotes, qlen; USER_BLOCK0 { not looking_at(quotes) % If more quote-like stuff follows, it's a deeper quoting level % Might as well test for -lists || (go_right(qlen), skip_white(), eolp()) || check_sc_quote() != "" || is_substr(MailEdit_Quote_Chars+"-", char(what_char())); } push_spot_bol; push_mark; skip_chars(MailEdit_Quote_Chars+" \t"); quotes = bufsubstr; quotes += check_sc_quote; qlen = strlen(quotes); % narrow to comment while (up_1) { bol; if (X_USER_BLOCK0) { go_down_1; break; } } push_mark; goto_spot; while (down_1) { if (X_USER_BLOCK0) { go_up_1; break; } } narrow; % unquote bob; deln(qlen); while (down(1)) deln(qlen); goto_spot; % reformat variable wrap = WRAP; WRAP=75 - strlen(strreplace(quotes, "\t", " ", qlen), pop); call("format_paragraph"); WRAP = wrap; % requote requote_buffer(quotes); pop_spot; widen; } %}}} %{{{ ispell quote hook static define ispell_is_quote_hook() { not looking_at(Mail_Quote_String); } %}}} %}}} %{{{ public functions % Fix broken Outlook quoting. % This is based on Tomasz 'tsca' Sienicki's oe_quot.sl for slrn. public define un_oe_quote () { variable rtk, hvr,len, cregexp = "\(\n[|:> ]*\)"R % line 1: quotes + "\([|:>] ?\)[^\n]\{60,\}"R % extra quote, line of text + "\1\([^|:>]\{1,15\}\)"R % line 2: quotes, some text -> BROKEN! + "\1\2"R, % line 3: first and extra quote line = what_line; bob; if (email_have_header) { ifnot (bol_fsearch("--- Do not modify this line.")) ()= bol_fsearch("\n"); go_down_1; } push_mark_eob; rtk = bufsubstr_delete; while (string_match(rtk,cregexp,2)) { (hvr,len) = string_match_nth(3); insert(substr(rtk,1,hvr)); insert(string_nth_match(rtk,2)); rtk = substr(rtk,hvr+1,-1); } insert(rtk); goto_line(line); } % check for non-nested quotes as Emacs' supercite makes. This only works % after the quoted text is inserted into the buffer of course, so this is % called from rmail_reply(). public define check_sc_quotes() { variable sc_quote, pos = 1, len; sc_quotes = Assoc_Type[Integer_Type]; push_spot(); mark_buffer; variable buffer = bufsubstr; pop_spot; while (string_match (buffer,"\n\\(["+MailEdit_Quote_Chars+" \t]*\\)" % quotes + "\\([a-zA-Z]\\{2,5\\}> ?\\)" % maybe sc quote + "[^\n]*\n" % rest of line + "\\1\\2" % next line starts with quotes and sc quote , pos)) { sc_quotes[string_nth_match(buffer, 2)] = 1; (pos, len) = string_match_nth (0); pos += len + 1; } } public define email_reformat () { if (email_is_body ()) reformat_quote (); else reformat_header (); } % If standing in the middle of a quoted paragraph, split the line at % point, insert three empty lines, prepend contextual number of quote % characters to remainder of split line and move two lines up. Run % email_reformat on the second paragraph. public define email_split_quoted_paragraph () { if (bolp() || eolp()) return newline(), indent_line(); push_spot_bol(); ifnot (re_looking_at(sprintf("^[%s]+", MailEdit_Quote_Chars))) { pop_spot (); return newline(), indent_line(); } push_mark; skip_chars(MailEdit_Quote_Chars+" "); "\n\n\n" + bufsubstr + check_sc_quote; pop_spot; trim; insert (); email_reformat (); <<<<<<< email.sl go_up(2); ======= go_up (2); >>>>>>> 1.9 } % Remove quote levels beyond a user defined number public define remove_excess_quote_levels () { variable threshold = prefix_argument(-1); if (threshold == -1) threshold = Email_Quote_Level_Threshold; push_spot_bob (); while (re_fsearch (sprintf("^\\(%s[%s ]+\\)", Mail_Quote_String, MailEdit_Quote_Chars))) { variable qlen = strlen (strtrans (regexp_nth_match(0)," ","")); if (qlen > threshold) delete_line (); else eol; } pop_spot (); } % Delete text this quoting level around point, possibly skipping quoted % empty lines. This is not SC-aware yet. public define kill_this_level_around_point () { variable ins_dots = prefix_argument(-1) != -1; push_spot_bol; push_mark; skip_chars(MailEdit_Quote_Chars+" \t"); bskip_white(); variable quotes = bufsubstr; quotes=strtrim_end(quotes); variable qlen = strlen (quotes); ifnot (qlen) return pop_spot; while (up_1) { bol; if (not looking_at(quotes) || (go_right(qlen), not eolp()) && is_substr(MailEdit_Quote_Chars, char(what_char()))) { go_down_1; break; } } push_mark; pop_spot; while (down_1) { if (not looking_at(quotes) || (go_right(qlen), not eolp()) && is_substr(MailEdit_Quote_Chars, char(what_char()))) { go_up_1; break; } } del_region; if (ins_dots) insert(quotes+"\n"+quotes+" [...]\n"+quotes+"\n"); } public define email_delete_quoted_sigs() { variable quotes, qlen; bob; while (re_fsearch("^\\([>|: \t]+\\)-- ?[a-zA-Z]\\{0,7\\}$")) { quotes = regexp_nth_match(1); qlen = strlen(quotes); push_mark; while (down_1) { if (not looking_at(quotes) || (go_right(qlen), not eolp()) && (skip_white(), is_substr(MailEdit_Quote_Chars, char(what_char())))) { go_up_1; break; } } del_region; } } % clean up reply body:delete quoted signature, remove empty quoted lines public define email_prepare_reply() { push_spot; eob; % delete a quoted signature if (bol_bsearch(strcat(Mail_Quote_String, "-- "))) { push_mark; % Don't delete my own signature ifnot (bol_fsearch("-- ")) eob; del_region; } % remove empty quoted lines without removing the line itself bob; while (re_fsearch (sprintf("^[%s]+[ \t]*$", MailEdit_Quote_Chars))) del_eol (); % trim trailing whitespace (if any) eob (); push_mark; bskip_chars (" \t\n"); % leave a newline, avoid error with read-only line in mail() if (looking_at_char('\n')) go_right_1; % and another if (looking_at_char('\n')) go_right_1; del_region (); pop_spot; } % Clean up message before editing: position cursor, if quote_string is % found call email_prepare_reply(). You may call this from % email_mode_hook. public define email_prepare_body () { if (bol_fsearch(Mail_Quote_String)) email_prepare_reply; else ifnot (bol_fsearch("\n")) eob; } % This only works with timbera.pl, and with Mutt. public define email_attach_file() { ifnot (email_have_header) throw RunTimeError, "no headers!"; variable attachment = read_with_completion("Attach", "", "", 'f'); push_spot; goto_end_of_headers; vinsert("\nAttach: %s", attachment); pop_spot; } static define fun_on_body(fun) { variable line = what_line, wline = window_line; narrow_to_body; @fun; widen; goto_line(line); recenter(wline); } % encrypt a message public define email_encrypt() { fun_on_body(&mc_encrypt); } % sign a message public define email_sign() { fun_on_body(&mc_sign); } % spell check a message % To do: check the subject line too. public define ispell_message() { fun_on_body(&ispell_region); } public define mail_mode () { no_mode (); set_mode (mode,1); use_keymap (mode); use_syntax_table (mode); set_buffer_hook ("par_sep", &email_parsep); set_buffer_hook ("newline_indent_hook", "email_split_quoted_paragraph"); define_blocal_var("flyspell_syntax_table", mode); define_blocal_var("ispell_region_hook", &ispell_is_quote_hook); check_sc_quotes; run_mode_hooks ("email_mode_hook"); if (Email_Quote_Level_Threshold > 0) remove_excess_quote_levels (); } %}}} jedmodes-2.5.7/email/email.sl0000644000175400017510000003467711702651666015043 0ustar mildemilde% email.sl -*- mode: SLang; mode: Fold -*- % % $Id: email.sl,v 1.8 2008/02/23 07:21:21 paul Exp paul $ % Keywords: mail % % Copyright (c) 2003-2008 Paul Boekholt, Morten Bo Johansen % Released under the terms of the GNU GPL (version 2 or later). % % This file was written by the following people: % Ulli "Framstag" Horlacher -> mail_mode % Thomas Roessler -> mail_mode light % Abraham vd Merwe % Johann Botha -> muttmail % Ulli Horlacher -> mailmode (muttmail light) % Paul Boekholt % Morten Bo Johanssen -> email % 2005 Joerg Sommer % % This mail mode should work with both sendmail.sl and Mutt. # autoload("mail_mode", "email.sl"); add_completion("mail_mode"); # provide("email"); require("keydefs"); _autoload ("rebind", "bufutils", "string_nth_match", "strutils", "mc_encrypt", "mailcrypt", "mc_sign", "mailcrypt", "ispell_region", "ispell", 5); if ("" == current_namespace()) implements ("email"); % Set the threshold for the number of quote levels beyond which you % consider it a waste of time to deal with them. E.g. setting the value % to 2 would delete all quote levels beyond the second level. The number % includes the level you create yourself when you reply. A value of 0 % disables deletion. custom_variable ("Email_Quote_Level_Threshold", 0); % Your quoting string custom_variable ("Mail_Quote_String", "> "); % Do we recognize mbox style "From " lines as headers? % for backwards compatibility ... custom_variable ("mail_mode_have_mbox", 1); custom_variable ("Email_Have_Mbox", mail_mode_have_mbox); % Since mailedit.sl calls this MailEdit_Quote_Chars, we might as well follow % suit. custom_variable ("MailEdit_Quote_Chars", ">:|"); %{{{ static variables variable mode = "email"; % List of things that look like non-nested quotes (as Emacs' supercite % makes) in this buffer. We assume that you don't try to edit two emails % at once. variable sc_quotes = Assoc_Type[Integer_Type]; %}}} %{{{ keymap ifnot (keymap_p(mode)) make_keymap (mode); rebind("format_paragraph", "email_reformat", mode); definekey_reserved ("kill_this_level_around_point", " ", mode); definekey_reserved ("email_delete_quoted_sigs", "", mode); definekey_reserved ("remove_excess_quote_levels", "", mode); definekey_reserved ("email_attach_file", "", mode); definekey_reserved ("email_sign", "/s", mode); definekey_reserved ("email_encrypt", "/e", mode); definekey_reserved ("ispell_message", "i", mode); %}}} %{{{ syntax highlighting create_syntax_table (mode); define_syntax ("-a-zA-Z",'w',mode); % words define_syntax ("0-9",'0',mode); % numbers define_syntax (",;:",',',mode); % delimiters define_syntax ('*', '\'', mode); % *bold* define_syntax('>', '#', mode); % quotes set_syntax_flags(mode, 0x20 | 0x80); static variable color_from = "comment"; static variable color_to = "keyword1"; static variable color_subject = "number"; static variable color_header = "..."; static variable color_url = "keyword"; static variable color_email = "keyword"; static variable color_signature = "comment"; static variable color_reply1 = "preprocess"; static variable color_reply2 = "string"; static variable color_smiley = "operator"; static variable color_bold = "string"; static variable color_underline = "delimiter"; static variable color_italic = "delimiter"; #ifdef HAS_DFA_SYNTAX % The highlighting copes with email addresses and url's dfa_enable_highlight_cache ("email.dfa",mode); dfa_define_highlight_rule("[^ -@\[-`{-~]+"R, "Knormal", mode); dfa_define_highlight_rule ("^(To|Cc|Newsgroups): .*",color_to,mode); dfa_define_highlight_rule ("^Date: .*",color_header,mode); dfa_define_highlight_rule ("^From: .*",color_from,mode); dfa_define_highlight_rule ("^Subject: .*",color_subject,mode); dfa_define_highlight_rule ("(http|ftp|file|https)://[^ \t\n>]+",color_url,mode); dfa_define_highlight_rule ("[^ \t\n<]*@[^ \t\n>]+",color_email,mode); dfa_define_highlight_rule ("^-- $",color_signature,mode); dfa_define_highlight_rule ("^> ?> ?> ?> ?> ?>.*",color_reply2,mode); dfa_define_highlight_rule ("^> ?> ?> ?> ?>.*", color_reply1,mode); dfa_define_highlight_rule ("^> ?> ?> ?>.*", color_reply2,mode); dfa_define_highlight_rule ("^> ?> ?>.*", color_reply1,mode); dfa_define_highlight_rule ("^> ?>.*", color_reply2,mode); dfa_define_highlight_rule ("^>.*", color_reply1,mode); dfa_define_highlight_rule ("[\\(\\)]+-?[:;P\\^]|[:;P\\^]-?[\\(\\)]+","color_smiley",mode); dfa_define_highlight_rule ("[^ ]_[a-zA-Z]+_","normal",mode); dfa_define_highlight_rule ("_[a-zA-Z]+_[^ ]","normal",mode); dfa_define_highlight_rule ("_[a-zA-Z]+_",color_underline,mode); dfa_define_highlight_rule ("\\*[a-zA-Z]+\\*",color_bold,mode); dfa_define_highlight_rule ("[^ ]/[a-zA-Z]+/","normal",mode); dfa_define_highlight_rule ("/[a-zA-Z]+/[^ ]","normal",mode); dfa_define_highlight_rule ("/[a-zA-Z]+/",color_italic,mode); dfa_build_highlight_table (mode); enable_dfa_syntax_for_mode(mode); #endif %}}} %{{{ static functions %{{{ mostly header stuff static define email_is_tag () { push_spot_bol (); (Email_Have_Mbox && bobp () && looking_at ("From ") || 1 == re_looking_at ("^[A-Za-z][^: ]*:")); pop_spot (); } % I don't want to set a user mark in mail_mode(), because maybe headers etc. % are added after mail_mode() is run static define email_have_header () { push_spot_bob (); email_is_tag (); pop_spot (); } static define email_is_body () { ifnot (email_have_header()) return 1; push_spot (); (bol_bsearch("\n") || bol_bsearch("--- Do not modify this line. Enter your message below")); pop_spot (); } static define email_parsep () { push_spot_bol (); (looking_at("-- ") || email_is_body() && (skip_chars(MailEdit_Quote_Chars+" \t"), eolp()) || email_is_tag () || (skip_white(), eolp())); pop_spot (); } static define reformat_header () { push_spot (); while (not email_is_tag()) { ifnot (up_1()) { pop_spot (); return; } } bol (); ()=ffind_char(':'); go_right_1 (); push_spot (); insert ("\n"); bol_trim (); insert (" "); call ("format_paragraph"); pop_spot (); del (); pop_spot (); } static define goto_end_of_headers() { bob(); ifnot (bol_fsearch("--- Do not modify this line. Enter your message below") || bol_fsearch ("\n")) { eob(); newline(); newline(); } go_up_1; } static define narrow_to_body() { push_spot; ifnot(email_have_header) mark_buffer(); else { goto_end_of_headers; go_down(2); push_mark_eob; } narrow; pop_spot; } %}}} %{{{ quote reformatting % check if we're looking at a non-nested quote. static define check_sc_quote() { variable sc_quote; foreach sc_quote (sc_quotes) using ("keys") { if (looking_at(sc_quote)) return sc_quote; } return ""; } static define requote_buffer(quote) { bob(); do { insert(quote); } while (down_1()); } % reformat quoted text static define reformat_quote() { variable quotes, qlen; USER_BLOCK0 { not looking_at(quotes) % If more quote-like stuff follows, it's a deeper quoting level % Might as well test for -lists || (go_right(qlen), skip_white(), eolp()) || check_sc_quote() != "" || is_substr(MailEdit_Quote_Chars+"-", char(what_char())); } push_spot_bol; push_mark; skip_chars(MailEdit_Quote_Chars+" \t"); quotes = bufsubstr; quotes += check_sc_quote; qlen = strlen(quotes); % narrow to comment while (up_1) { bol; if (X_USER_BLOCK0) { go_down_1; break; } } push_mark; goto_spot; while (down_1) { if (X_USER_BLOCK0) { go_up_1; break; } } narrow; % unquote bob; deln(qlen); while (down(1)) deln(qlen); goto_spot; % reformat variable wrap = WRAP; WRAP=75 - strlen(strreplace(quotes, "\t", " ", qlen), pop); call("format_paragraph"); WRAP = wrap; % requote requote_buffer(quotes); pop_spot; widen; } %}}} %{{{ ispell quote hook static define ispell_is_quote_hook() { not looking_at(Mail_Quote_String); } %}}} %}}} %{{{ public functions % Fix broken Outlook quoting. % This is based on Tomasz 'tsca' Sienicki's oe_quot.sl for slrn. public define un_oe_quote () { variable rtk, hvr,len, cregexp = "\(\n[|:> ]*\)"R % line 1: quotes + "\([|:>] ?\)[^\n]\{60,\}"R % extra quote, line of text + "\1\([^|:>]\{1,15\}\)"R % line 2: quotes, some text -> BROKEN! + "\1\2"R, % line 3: first and extra quote line = what_line; bob; if (email_have_header) { ifnot (bol_fsearch("--- Do not modify this line.")) ()= bol_fsearch("\n"); go_down_1; } push_mark_eob; rtk = bufsubstr_delete; while (string_match(rtk,cregexp,2)) { (hvr,len) = string_match_nth(3); insert(substr(rtk,1,hvr)); insert(string_nth_match(rtk,2)); rtk = substr(rtk,hvr+1,-1); } insert(rtk); goto_line(line); } % check for non-nested quotes as Emacs' supercite makes. This only works % after the quoted text is inserted into the buffer of course, so this is % called from rmail_reply(). public define check_sc_quotes() { variable sc_quote, pos = 1, len; sc_quotes = Assoc_Type[Integer_Type]; push_spot(); mark_buffer; variable buffer = bufsubstr; pop_spot; while (string_match (buffer,"\n\\(["+MailEdit_Quote_Chars+" \t]*\\)" % quotes + "\\([a-zA-Z]\\{2,5\\}> ?\\)" % maybe sc quote + "[^\n]*\n" % rest of line + "\\1\\2" % next line starts with quotes and sc quote , pos)) { sc_quotes[string_nth_match(buffer, 2)] = 1; (pos, len) = string_match_nth (0); pos += len + 1; } } public define email_reformat () { if (email_is_body ()) reformat_quote (); else reformat_header (); } % If standing in the middle of a quoted paragraph, split the line at % point, insert three empty lines, prepend contextual number of quote % characters to remainder of split line and move two lines up. Run % email_reformat on the second paragraph. public define email_split_quoted_paragraph () { if (bolp() || eolp()) return newline(), indent_line(); push_spot_bol(); ifnot (re_looking_at(sprintf("^[%s]+", MailEdit_Quote_Chars))) { pop_spot (); return newline(), indent_line(); } push_mark; skip_chars(MailEdit_Quote_Chars+" "); "\n\n\n" + bufsubstr + check_sc_quote; pop_spot; trim; insert (); email_reformat (); go_up (2); } % Remove quote levels beyond a user defined number public define remove_excess_quote_levels () { variable threshold = prefix_argument(-1); if (threshold == -1) threshold = Email_Quote_Level_Threshold; push_spot_bob (); while (re_fsearch (sprintf("^\\(%s[%s ]+\\)", Mail_Quote_String, MailEdit_Quote_Chars))) { variable qlen = strlen (strtrans (regexp_nth_match(0)," ","")); if (qlen > threshold) delete_line (); else eol; } pop_spot (); } % Delete text this quoting level around point, possibly skipping quoted % empty lines. This is not SC-aware yet. public define kill_this_level_around_point () { variable ins_dots = prefix_argument(-1) != -1; push_spot_bol; push_mark; skip_chars(MailEdit_Quote_Chars+" \t"); bskip_white(); variable quotes = bufsubstr; quotes=strtrim_end(quotes); variable qlen = strlen (quotes); ifnot (qlen) return pop_spot; while (up_1) { bol; if (not looking_at(quotes) || (go_right(qlen), not eolp()) && is_substr(MailEdit_Quote_Chars, char(what_char()))) { go_down_1; break; } } push_mark; pop_spot; while (down_1) { if (not looking_at(quotes) || (go_right(qlen), not eolp()) && is_substr(MailEdit_Quote_Chars, char(what_char()))) { go_up_1; break; } } del_region; if (ins_dots) insert(quotes+"\n"+quotes+" [...]\n"+quotes+"\n"); } public define email_delete_quoted_sigs() { variable quotes, qlen; bob; while (re_fsearch("^\\([>|: \t]+\\)-- ?[a-zA-Z]\\{0,7\\}$")) { quotes = regexp_nth_match(1); qlen = strlen(quotes); push_mark; while (down_1) { if (not looking_at(quotes) || (go_right(qlen), not eolp()) && (skip_white(), is_substr(MailEdit_Quote_Chars, char(what_char())))) { go_up_1; break; } } del_region; } } % clean up reply body:delete quoted signature, remove empty quoted lines public define email_prepare_reply() { push_spot; eob; % delete a quoted signature if (bol_bsearch(strcat(Mail_Quote_String, "-- "))) { push_mark; % Don't delete my own signature ifnot (bol_fsearch("-- ")) eob; del_region; } % remove empty quoted lines without removing the line itself bob; while (re_fsearch (sprintf("^[%s]+[ \t]*$", MailEdit_Quote_Chars))) del_eol (); % trim trailing whitespace (if any) eob (); push_mark; bskip_chars (" \t\n"); % leave a newline, avoid error with read-only line in mail() if (looking_at_char('\n')) go_right_1; % and another if (looking_at_char('\n')) go_right_1; del_region (); pop_spot; } % Clean up message before editing: position cursor, if quote_string is % found call email_prepare_reply(). You may call this from % email_mode_hook. public define email_prepare_body () { if (bol_fsearch(Mail_Quote_String)) email_prepare_reply; else ifnot (bol_fsearch("\n")) eob; } % This only works with timbera.pl, and with Mutt. public define email_attach_file() { ifnot (email_have_header) throw RunTimeError, "no headers!"; variable attachment = read_with_completion("Attach", "", "", 'f'); push_spot; goto_end_of_headers; vinsert("\nAttach: %s", attachment); pop_spot; } static define fun_on_body(fun) { variable line = what_line, wline = window_line; narrow_to_body; @fun; widen; goto_line(line); recenter(wline); } % encrypt a message public define email_encrypt() { fun_on_body(&mc_encrypt); } % sign a message public define email_sign() { fun_on_body(&mc_sign); } % spell check a message % To do: check the subject line too. public define ispell_message() { fun_on_body(&ispell_region); } public define mail_mode () { no_mode (); set_mode (mode,1); use_keymap (mode); use_syntax_table (mode); set_buffer_hook ("par_sep", &email_parsep); set_buffer_hook ("newline_indent_hook", "email_split_quoted_paragraph"); define_blocal_var("flyspell_syntax_table", mode); define_blocal_var("ispell_region_hook", &ispell_is_quote_hook); check_sc_quotes; run_mode_hooks ("email_mode_hook"); if (Email_Quote_Level_Threshold > 0) remove_excess_quote_levels (); } %}}} jedmodes-2.5.7/email/keyring0000664000175400017500000000501210215261616014264 0ustar mildegm-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org mQGiBD2yx2QRBAD9VK8O3YdX7gp9I7EJHqiiGRITCW5/PGohS91aA+fgr1VAAwaJ bzikLcJ1HIhFehk4LwND1t2w5TYMRbAPkKu7JDqvxB2nx6869+cfMwFht813FFPs 7Jj9reKP2p/mws1y+0ZW9lYq+68e0ubzTq++BOatQkcwC8kdlKWj49lL2wCg08w6 /VNdR+RKcov3wiz0p+XWcMED/RNYKTuYIDIUh7AXLY5qiWPM9/xADMHOBBxs90Sv XX3LBOvv0BXCRFBC8vFtLLYDLP0H2Zf6j9W21dWtrsgS49D8QHF0HpyfDbR7nvL+ LtzvyKtbB267fT7VyExgYFthCXekbsPDX195/ZvPXvc0ZFRGd2V60C0u3XB3ytL9 0fZ4A/0dopUHSQw2uuzbTzAraGSloo1XyjXYOqC1qpu1yDq6PF/zIJFhi+4PlfA5 AdDgwWPUBBZm1n7wliyXOH5G0mye643BjgdqVhRwH3yhFJGxZWQH06m2D+2Au/x6 mtlbkVGI0QfkT1K0NfS9XbnH3Ki74ttJYOspxdQVlso5F69nZLQkUGF1bCBCb2Vr aG9sdCA8cC5ib2VraG9sdEBoZXRuZXQubmw+iFcEExECABcFAj2yx2QFCwcKAwQD FQMCAxYCAQIXgAAKCRDVFOoVR7tvM3ZNAJ9wnsocV3FKVFXeaSpDxDgLIoIkgACe Iae/7jxrlV+acj6Xk80Hfi/cyXG5AQ0EPbLHbhAEAJvuHvfsQZ9h6EnuKEzFdBAY erUcniFBPR6tBRzEib7FI2PWSA7MRAS41AUtFLUKZGE/51FZuTDgph0UQYyomyUm VIfaJPkN90nmcjmrObuZgOryFNKG5ZzLA9juPq16JiqoLGMjK+apvDlKBdsjctVk zVWlXbkrg7TpMnTGy197AAMFA/0bYdPxDl4ORfZPIvdstgYusOjjY2u+Px61qTBd iS2POZk2X+0b469NIuq3rxWb5+HlLyfNYqduALf4nvPA5ueOGjIz0sn5eZ268spm R8eu80u3GKH+nh85MvQapAYZMupAiq+/u4BVubENt/77xlWIO9fLrmI56lhEv3mN K2R5M4hGBBgRAgAGBQI9ssduAAoJENUU6hVHu28zTo4AoNOmyVu8KoMLxQR86jTP hkP0rk6rAJ9fxZDVbldoDth+5jfe8N8V6AYQhZkBogQ7R00PEQQAupi7F855xwDq S6WWpQF+7QUb9W9KSmQ1SOEWoJARFatEGX5CZE/xan8BbZ62uxxtKEQ8dL+S0WYy QKPeCArqks5n9KO005NrF++mdPuZo/RGuCzL4WN7c0WMQzgi4e/xGn0ClIlyz9Ft EXTykFRsUqiiN6Ul7oHqJUamUSihEO8AoMcYvPCHmLSGa898lK/jArrFEgGZA/sF sMvUe9FW8jkXsOD0XGkaJM5vLMlmtO3++Owa4dk6MEgLJ5xN5J3rn+BES4K9Pego UW/ItHDGXmLom/x9sOdbdNzevWXphnTeRCVeD1xcus8W4kjP2BFvRlwwnmlYpwbR kSqeotrpPHCNiz79Q5UfG0jqFEVQCiQ0Lqm6sxYyXAP/eIZyt0MqYG8oCnupdK3/ /lh3Lz6Wf7U64mOVeTvgw8FdXxU9K8O+2ZU/VTtwCZrH7H14Q11L/M506BVs3vDW q8y1hUxsuwnEGimNOHL/Q3ZZ0TBfbBR9CwZcF1SxXwX+JtFtqmCmoFmyWG7SUYwe WMZsADkjolnNKZIBXZjLSf+0Ik1vcnRlbiBCbyBKb2hhbnNlbiA8bW9qb0BpbWFn ZS5kaz6IVwQTEQIAFwUCO0dNDwULBwoDBAMVAwIDFgIBAheAAAoJECOWvTlJB+R1 LIsAoIlYO4F0m3twaR3vsDQJWXZibmFpAKCsZspgZkErQH3XZ+xV7+HuvBwBB7kB DQQ7R00lEAQAl12nhU/9E/iAxeqINXmLJ36FfOXqFv2CPkCPgR7AJCCXzIe0fZDu dEiQ0FXw3MqYWUe5P5oc1Ioq0TZC6ZLS3TL5SQU/7GO0ZuHzI1SzmS/rwSQnRrHS HTIKgiMRYjfuQKpNhcu+tfhMjGsGQOznaPKKvrkFDwngGvg/EqypPVMAAwYD/1iO 4QKZh36hFxDFVv3MW80FB67NWketueG5KVcRyUQ26m+3DfzOxbv0rfhN1H+8mzBr MXpFQY8a7x0hoMlIM72rbvsPWwvyh6Nft5+t5pS+/lyzMkONQDXAAYidtZwRyF1D dQ9NQPSM5ui2lGnxczzZkgHCS8OItnuMJd23wREFiEYEGBECAAYFAjtHTSUACgkQ I5a9OUkH5HXZ4QCghudI6vybXFcuxgoUa09uWAUYL+IAnRkwvacqTyMCqddK5aod g+pylBIl =SFLg -----END PGP PUBLIC KEY BLOCK----- jedmodes-2.5.7/pylit/0000755000175400017500000000000011262367115012747 5ustar mildegmjedmodes-2.5.7/pylit/pylit.sl0000644000175400017500000001115111262367115014447 0ustar mildegm% pylit.sl: Helper functions for literal programming with PyLit % % Copyright (c) 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % % ===== ========== ========================================================== % 0.1 2006-03-03 as part of gmisc.sl (2008-01-11 ) % 0.2 2007-01-23 added pylit_check, public release as pylit.sl % 0.2.1 2007-01-24 bugfix in pylit_check(): do nothing if both files are of % same age % 0.2.2 2007-03-09 call rst_mode() if the output buffer is text % literate version % 0.3 2008-01-11 set matching mode in pylit_diff and pylit_doctest % 0.3.1 2009-10-05 fix autoloads % ===== ========== ========================================================== % % % Requirements % ------------ % helper modes from http://jedmodes.sf.net/ :: autoload("push_defaults", "sl_utils"); autoload("shell_cmd_on_region_or_buffer", "ishell"); autoload("python_output_mode", "pymode"); autoload("close_buffer", "bufutils"); % Customization % ------------- % % the `pylit` command % % * give a full path if pylit is not in your PATH % * specify as ``python pylit.py`` (with needed paths) if it does not self-exec % % :: custom_variable("Pylit_Cmd", "pylit"); % Functions % --------- % % :: private variable output_buffer = "*PyLit output*"; private variable doctest_buffer = "*doctest output*"; % switch to `outfile` and place cursor in the corresponding line private define pylit_switch_to_output(outfile) { variable line = what_line(); close_buffer(); () = find_file(outfile); goto_line(line); if (path_extname(outfile) == ".txt") call_function("rst_mode"); % if it exists } %!%+ %\function{pylit_check} %\synopsis{Check for a more recent version of the current file} %\usage{pylit_check()} %\description % PyLit (http://pylit.berlios.de/) converts between text and code format % of a source file. % % There is the possibility of data loss, if edits are done in parallel on % both versions. % % \sfun{pylit_check} checks, if there is a more recent (text or code) % source version of the current buffer's associated file and recommends to % load this instead. %\example % To check for newer versions in the not-openend format add to your jed.rc %#v+ % define rst_mode_hook() { pylit_check(); } % define python_mode_hook() {pylit_check(); } %#v- % (or extend the mode hooks if they already exist). Repeat this for all % programming languages where you do literate programming in. %\notes % \sfun{pylit_check} handles only the case with default filename extensions % (".txt" added for the text source and stripped for the code source). %\seealso{pylit_buffer, pylit_view, pylit_diff} %!%- public define pylit_check() { variable outfile, file = buffer_filename(); if (file == "") return; % mimic PyLit's outfile name generation if (path_extname(file) == ".txt") outfile = path_sans_extname(file); else outfile = file + ".txt"; if (file_time_compare(file, outfile) >= 0) return; % buffer-file is newer or same age (e.g. both nonexistant) if (get_y_or_n(path_basename(outfile)+" is more recent. Load it instead")) pylit_switch_to_output(outfile); } %!%+ %\function{pylit_buffer} %\synopsis{Convert the current buffer with PyLit} %\usage{pylit_buffer()} %\description % PyLit (http://pylit.berlios.de/) converts between text and code format % of a source file. % % \sfun{pylit_buffer} calls `pylit` on the current buffer, closes it % (if successfull) and opens the output file instead. %\seealso{pylit_check, pylit_view, pylit_diff} %!%- public define pylit_buffer() { variable buf = whatbuf(); shell_cmd_on_region_or_buffer(Pylit_Cmd, output_buffer); % switch to converted version !if (re_fsearch("extract written to \\(.*\\)")) return; variable outfile = regexp_nth_match(1); close_buffer(output_buffer); sw2buf(buf); pylit_switch_to_output(outfile); } % call pylit to convert buffer, do not produce a file, view result in a buffer public define pylit_view() { variable line = what_line(); shell_cmd_on_region_or_buffer(Pylit_Cmd + " -o -", output_buffer); goto_line(line); } % view the differences introduced by a PyLit round-trip public define pylit_diff() { shell_cmd_on_region_or_buffer(Pylit_Cmd + " --diff ", output_buffer); bob(); call_function("diff_mode"); } % do a doctest of the buffer (using the text format to get test in comments) public define pylit_doctest() { shell_cmd_on_region_or_buffer(Pylit_Cmd + " --doctest ", doctest_buffer); !if (bsearch("------------------------------")) bob(); recenter(1); python_output_mode(); } jedmodes-2.5.7/gdbmrecent/0000755000175400017500000000000011026441132013706 5ustar mildegmjedmodes-2.5.7/gdbmrecent/gdbmrecent.sl0000644000175400017500000001717511026441132016373 0ustar mildegm% gdbmrecent.sl % % $Id: gdbmrecent.sl,v 1.8 2008/03/22 14:44:00 paul Exp paul $ % Keywords: convenience % % Copyright (c) 2004-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Yet another recent mode. This one was written to test my gdbm module. % You should get slgdbm version 1.7 or later from % http://www.cheesit.com/downloads/slang/slgdbm.html % or if you're on Debian install the slang-gdbm package. % % Features: % -delayed synchronization of the database. It should still be possible % to work in multiple instances at the same time % -stores line and column information % -goes to last line and column even when file is not opened from recent menu % -recent menu shows only the most recent `Recent_Max_Cached_Files' files, but line and % column information is remembered for Recent_Files_Expire_Time days. % -Make buffer-local variables persistent. For now this can be used to make % a buffer's ispell dictionary setting persist. require("gdbm"); provide("recent"); provide("gdbmrecent"); require ("sl_utils"); % customvariables. % where to store the list custom_variable("Recent_Db", dircat(Jed_Home_Directory, "recent_db")); % length of the recent popup menu custom_variable("Recent_Max_Cached_Files", 15); % regexp for files not to be added to the recent list (/tmp/mutt-1234) custom_variable("Recent_Files_Exclude_Pattern", "/tmp"); % Time before entries expire (in days) custom_variable("Recent_Files_Expire_Time", 7); % This is a comma-separated list of blocal variables that are stored in the % recent files database. The entry is still purged if a file is not opened % for a week. The blocal's values have to be strings, and for now `=' and `:' % are not allowed in them. custom_variable("Gdbm_Pvars", "ispell_dictionary"); % the idea of the recent_flag is that when a script opens a file that should % not be added to the recent list it should say % public variable recent_flag; % ... % recent_flag = 0; % () = find_file("/some/file"); public variable recent_flag=1; private variable recent_files=Assoc_Type[String_Type]; % Return a cache entry for the current buffer (see getbuf_info) % (NULL if file matches Exclude Pattern or no file % associated with buffer) private define getbuf_filemark() { if(blocal_var_exists("no_recent")) return NULL; variable entry = buffer_filename(); if (not strlen(entry) || string_match(entry, Recent_Files_Exclude_Pattern, 1)) return NULL; variable varname, val=sprintf("%d:%d:%d",_time(), what_line_if_wide(), what_column()); foreach varname (strchop(Gdbm_Pvars, ',', 0)) { if (blocal_var_exists(varname)) val = sprintf("%s:%s=%s", val, varname, get_blocal_var(varname)); } return [entry, val]; } % find_file_after_hook % goto line, column % update date in assoc private define open_hook () { ifnot (recent_flag) { create_blocal_var("no_recent"); recent_flag = 1; return; } variable date, line=1, column=1, pvars="", pvar; variable filename = buffer_filename(); if (not strlen(filename) || string_match(filename, Recent_Files_Exclude_Pattern, 1)) return; variable val = NULL, db=gdbm_open(Recent_Db, GDBM_READER, 0600); if (db != NULL) val = db[filename]; if (val != NULL && 3 <= sscanf(val, "%d:%d:%d%s", &date, &line, &column, &pvars)) { % goto saved position goto_line(line); () = goto_column_best_try(column); % open folds loop(10) % while (is_line_hidden) might cause an infinite loop! { ifnot(is_line_hidden) break; runhooks("fold_open_fold"); } if (strlen(pvars)) { foreach pvar (strchop(pvars, ':', 0)) { pvar=strchop(pvar, '=', 0); if (2==length(pvar)) define_blocal_var(pvar[0], pvar[1]); } } } recent_files[filename] = sprintf("%d:%d:%d:%s", _time(), what_line(), what_column(), pvars); } % save hook % update assoc private define save_hook() { _pop_n (_NARGS); % remove spurious arguments from stack variable filemark = getbuf_filemark(); if (filemark == NULL) return; recent_files[filemark[0]] = filemark[1]; } % save the recent files assoc to the database private define update_db(db) { variable k, v; foreach k, v (recent_files) using ("keys", "values") { % if write fails, stop trying if (gdbm_store(db, k, v, GDBM_REPLACE)) break; } recent_files=Assoc_Type[String_Type]; } private define _get_files(db) { variable keys, values, dates; (keys, values) = gdbm_get_keys_and_values(db); dates = array_map(Integer_Type, &atoi, values); keys = keys[array_sort(-dates)]; return keys; } public define recent_get_files() { variable db=gdbm_open(Recent_Db, GDBM_READER, 0600); if (db != NULL) _get_files(db); } % build the menu private define menu_callback (popup) { variable db=gdbm_open(Recent_Db, GDBM_WRCREAT, 0600); if (db == NULL) return vmessage("gdbm: %s", gdbm_error()); update_db(db); variable keys, l, i; keys = _get_files(db); l = length(keys); if (l > Recent_Max_Cached_Files) l = Recent_Max_Cached_Files; _for i (0, l - 1, 1) { menu_append_item (popup, keys[i], sprintf ("() = find_file (\"%s\")", keys[i])); } } % this shows a menu of at most Recent_Max_Cached_Files that were opened in the % current buffer's directory or a subdirectory thereof. private define recent_here_callback (popup) { variable dir; ( , dir, , ) = getbuf_info(); variable dirlen = strlen(dir); ifnot(dirlen) return; variable db=gdbm_open(Recent_Db, GDBM_WRCREAT, 0600); if (db == NULL) return vmessage("gdbm: %s", gdbm_error()); update_db(db); variable keys, l, i; keys = _get_files(db); keys = keys[where(not array_map(Integer_Type, &strncmp, keys, dir, dirlen))]; l = length(keys); if (l > Recent_Max_Cached_Files) l = Recent_Max_Cached_Files; _for i (0, l - 1, 1) { menu_append_item (popup, keys[i], sprintf ("() = find_file (\"%s\")", keys[i])); } } private define purge_not_so_recent(db) { variable key, keys, values, dates; (keys, values) = gdbm_get_keys_and_values(db); variable cutoff_date = _time() - 86400 * Recent_Files_Expire_Time; dates = array_map(Integer_Type, &atoi, values); keys = keys[where(dates < cutoff_date)]; % it's not possible to use foreach(db) here % see info:(gdbm)Sequential foreach key (keys) { ()=gdbm_delete(db, key); } } % update the cache's line/col info % purge entries older than a week private define exit_hook() { try { variable db=gdbm_open(Recent_Db, GDBM_WRCREAT, 0600); variable filemark, buf; if (db != NULL) { % update line/col info loop (buffer_list()) { buf = (); ifnot(strlen(buf)) continue; sw2buf(buf); filemark = getbuf_filemark(); if (filemark != NULL) recent_files[filemark[0]] = filemark[1]; } update_db(db); purge_not_so_recent(db); variable st=stat_file(Recent_Db); if (st.st_size > 50000) ()=gdbm_reorganize(db); } } catch AnyError; return 1; % tell _jed_exit_hooks to continue } private define add_recent_files_popup_hook (menubar) { variable menu = "Global.&File"; menu_insert_popup (0, menu, "&Recent Files"); menu_set_select_popup_callback (strcat (menu, ".&Recent Files"), &menu_callback); menu_insert_popup (1, menu, "&Recent Here"); menu_set_select_popup_callback (strcat (menu, ".&Recent Here"), &recent_here_callback); } append_to_hook ("_jed_find_file_after_hooks", &open_hook); append_to_hook("_jed_save_buffer_after_hooks", &save_hook); % update list at exit append_to_hook("_jed_exit_hooks", &exit_hook); append_to_hook ("load_popup_hooks", &add_recent_files_popup_hook); jedmodes-2.5.7/circle/0000755000175400017500000000000010461125567013052 5ustar mildegmjedmodes-2.5.7/circle/circle.sl0000644000175400017500000003740510331664603014657 0ustar mildegm% circular array (i.e. array with periodic boundary conditions) % % Copyright (c) 2005 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Defines a new data type Circ_Type, a "circular" array with relational % indexing via a set of functions. "Circular" (or cyclic, looped, closed) % means that the first element is regarded the successor of the last element. % This can also be seen as a "periodic boundary condition". % % used by e.g. navigate.sl, help.sl and man.sl ("hyper-versions from Jedmodes) % % USAGE: just place in your jed library path % % VERSIONS % % 1.0 first public version % 1.1 2005-20-04 added copyright and leading documentation % removed the testing appendix (the new sprint_var.sl can % handle user-defined data types) % use the "standard way" of defining an array with type set % at run time in create_circ() % 1.2 2005-11-01 documentation typo fix, no explicitely public functions %!%+ %\variable{Circ_Type} %\synopsis{A "circular" array with relational indexing via a set of functions.} %\description % % "Circular" (or "cyclic", "looped", "closed") means that the first element % counts as successor of the last element. This can also be seen as a % periodic boundary condition (as known from crystal theory), % i.e. a circular array of size N looks like % % .. N-2 N-1 0 1 2 .. N-2 N-1 0 1 2 .. N-2 N-1 0 1 2 .. N-2 N-1 0 .. % % The circuar array is implemented as a structure with the fields % Array_Type .values: a "normal" array holding the values % Int_Type .pointer: the actual position for relative indexing % Int_Type .first: the position of the first valid entry % Int_Type .last: the position of the last valid entry % String_Type .step_mode: the mode of relative indexing % % Indexing is done relative to the position of the pointer. % The pointer can be moved using the functions circ_fstep(arr), % circ_bstep(arr), and circ_step(arr, n), where % n might be negative - moving the pointer backwards (left in the above % picture). % % There are three step-modes (for relative indexing and moving the pointer): % % circle_all: The pointer circles the whole array: % % If the pointer is at element N-1, the next step % sets it to 0. If the pointer is at element 0, the % next back-step sets it to N-1 % % circle_values: The pointer circles only the part of the array, % that is filled with valid values. % % Valid values are the ones added with circ_append % (and their possible replacements by circ_set). % The range of valid values is stored in the fields % .first and .last and adjusted by circ_append(var, value) % % If the pointer is at the last valid element, the next % step sets it to the first valid element. If the pointer % is at the first valid element, the next back-step sets % it to the last valid element. % % % linear: The pointer moves only in the part of the array, % that is filled with valid values. % % If the pointer is at the last valid element, an attempt % to step further will not move it but just issue a % warning: % "attempt to step past last/first valid entry" % If the pointer is at the first valid element, an attempt % to step further back will not move it but just issue a % warning: "First element reached". % % In pictures: % Pointers: * pointer, f first, l last % Mode at boundry: <--> step/skip, | stay % % Full circle: % % .. N-2 N-1 0 1 2 .. N-2 N-1 0 1 2 .. N-2 N-1 0 1 2 .. N-2 N-1 0 .. % *<->* % Limited_circle: % % .. N-2 N-1 0 1 2 3 4 .. N-2 N-1 0 1 2 3 4 .. N-2 N-1 0 1 2 3 .. % --------l f--valid-range--l f---------------l f-------- % *<------>* % Linear: % % .. N-2 N-1 0 1 2 3 4 .. N-2 N-1 0 1 2 3 4 .. N-2 N-1 0 1 2 3 .. % --------l f--valid-range--l f---------------l f-------- % | *| % % The difference between a circular array in linear mode and the standard % linear array is, that the "filling" is still circular, i.e. circ_append % will not stop at N-1, but continue with 0, sacrifying the first % value. This is similar to a stack with a limited number of levels, where % the first item will fall of the stack if there are more pushes than levels. % Therefore, a circular array in linear mode is e.g. best suited for a % history stack with a limited number of stored positions/commands % % The dereference operator @ may be used to create an instance of the % circular array: % variable a = @Circ_Type; % but typically one wants to initialize it as well, e.g.: % variable a = create_circ(Integer_Type, 30, "circle_all"); % % \seealso{cicr_append, circ_get, circ_set} %!%- !if (_featurep("circle")) typedef struct{ values, pointer, first, last, step_mode } Circ_Type; %!%+ %\function{create_circ} %\synopsis{Return an instance of a circular array} %\usage{Circ_Type create_circ(data_type, N, step_mode)} %\description % Create an circular array of size N with elements of Data_Type_Type % data_type. % For an explanation of step_mode see Circ_Type. % %\seealso{Circ_Type, create_circ, cicr_append, circ_set, circ_get, circ_fstep, circ_next} %!%- define create_circ(type, N, step_mode) { variable circ = @Circ_Type; circ.values = @Array_Type(type,[N]); circ.pointer = 0; % circ.first/last % remain NULL until circ_append sets them circ.step_mode = step_mode; return(circ); } % --- "circular arithmetic" --- %!%+ %\function{circ_add} %\synopsis{Add m and n, "fold" the result back to [0,...,N-1]} %\usage{Number circ_add(Number m, Number n, Integer N)} %\description % circ_add does an "circular addition" of two numbers (Integer or Float). % Use a negative number for b if you want a subtraction. %\seealso{Circ_Type, , } %!%- define circ_add(m, n, N) { variable sum; sum = (m + n) mod N; if (sum < 0) sum += N; return(sum); } % move pointer one step forward, using full circle define circ_increment(var) { var.pointer++; if (var.pointer == length(var.values)) var.pointer = 0; } % move pointer one step backward, using full circle define circ_decrement(var) { var.pointer--; if (var.pointer < 0) var.pointer = length(var.values)-1; } % move the pointer one step forward, considering step_mode define circ_fstep(var) { % cannot step in valid range, if there is no valid range if (var.first == NULL and var.step_mode != "circle_all") error("no valid entries [circular array]"); if (var.step_mode == "circle_values") if (var.pointer == var.last) { var.pointer = var.first; % skip non-valid elements return(); } if (var.step_mode == "linear") if (var.pointer == var.last) error("attempt to step past last valid entry [circular array]"); circ_increment(var); } % move the pointer one step backward, considering step_mode define circ_bstep(var) { % we cannot step in valid range, if there is no valid range if (var.first == NULL and var.step_mode != "circle_all") error("no valid entries [circular array]"); if (var.step_mode == "circle_values") if (var.pointer == var.first) { var.pointer = var.last; % skip non-valid elements return(); } if (var.step_mode == "linear") if (var.pointer == var.first) error("attempt to bstep before first valid entry [circular array]"); circ_decrement(var); } % move the pointer n steps, considering step_mode define circ_step(var, n) { if (n > 0) loop (n) circ_fstep(var); if (n < 0) loop (-n) circ_bstep(var); } %!%+ %\function{circ_get} %\synopsis{Return the value [pointer+offset] of the circular array var} %\usage{value = circ_get(Circ var, Int offset=0)} %\description % Get the value at the actual position (var.pointer) or (if the % optional argument is given) at pointer "+" offset % ("+" means "circular addition" according to var.step_mode). % The return value is of course of the type defined by the creation of % var. %\seealso{Circ_Type, circ_set, circ_next, circ_previous} %!%- define circ_get() % (var, offset=0) { % get arguments: last is top on stack variable offset = 0; if (_NARGS == 2) offset = (); variable var = (); variable value, p = var.pointer; % save current position circ_step(var, offset); if (_typeof(var.values) == Any_Type) value = @var.values[var.pointer]; else value = var.values[var.pointer]; var.pointer = p; % restore position return(value); } %!%+ %\function{circ_set} %\synopsis{Set the value [pointer+offset] of the circular array var} %\usage{Void circ_set(Circ var, value, Int offset=0)} %\description % Set the value at the actual position (var.pointer) or (if the % optional argument is given) at pointer "+" offset % ("+" means "circular addition" according to var.step_mode). %\notes % circ_set does not use/affect the first-last pair, to change the range of % "valid entries" as well, use the functions circ_append or circ_insert % %\seealso{Circ_Type, circ_get, circ_append} %!%- define circ_set() % circ_set(var, value, [offset = 0]) { % get arguments: last is top on stack variable offset = 0; if (_NARGS == 3) offset = (); variable value = (); variable var = (); variable p = var.pointer; % save current position circ_step(var, offset); var.values[var.pointer] = value; var.pointer = p; % restore position } % just for conveniency, some often used combinations: %!%+ %\function{circ_step_and_get} %\synopsis{Move the actual position n steps and return the value} %\usage{value = circ_step_and_get(Circ var, Int n)} %\description % Move the pointer to the actual position n steps and get the value %\seealso{Circ_Type, circ_step, circ_get, circ_next, circ_previous} %!%- define circ_step_and_get(var, n) { circ_step(var, n); return(circ_get(var)); } %!%+ %\function{circ_next} %\synopsis{Move the actual position 1 step and return the value} %\usage{value = circ_next(Circ var)} %\description % Move the pointer to the actual position one step and return % the value of var[pointer] %\seealso{Circ_Type, circ_step_and_get, circ_step, circ_get, circ_previous} %!%- define circ_next(var) { circ_fstep(var); return(circ_get(var)); } %!%+ %\function{circ_previous} %\synopsis{Move the actual position 1 step back and return the value} %\usage{value = circ_previous(Circ var)} %\description % Move the pointer to the actual position one step backwards and % return the value of var[pointer] %\seealso{Circ_Type, circ_step, circ_get, circ_previous} %!%- define circ_previous(var) { circ_bstep(var); return(circ_get(var)); } %!%+ %\function{circ_append} %\synopsis{Append the value to the actual position} %\usage{circ_append(var, value, [at_end = 0])} %\description % Set the value at the actual positions successor (circling round the full % circle) and adjust the "range of valid entries" to end at this value. % % If the array is already full, the first entry will be overwritten. % % The optional argument "at_end" tells circ_append to append the % value not to the current position but at the end of the array. % %\seealso{Circ_Type, circ_set, circ_get} %!%- define circ_append() % circ_append(var, value, [at_end = 0]) { % get arguments: last is top on stack variable at_end = 0; if (_NARGS == 3) at_end = (); variable value = (); variable var = (); % if at_end is TRUE and list not empty: goto end of list if (at_end and var.last != NULL) var.pointer = var.last; % append the value circ_increment(var); % move pointer one step, using full circle circ_set(var, value); % set .last var.last = var.pointer; % two cases where we need to set .first if(var.first == NULL) % array empty var.first = var.pointer; else if(var.first == var.pointer) % array full { var.first++; % -> increment .first if (var.first == length(var.values)) var.first = 0; } } % TODO circ_insert(var, value) insert value at position, "moving the others up" %!%+ %\function{circ_delete} %\synopsis{remove current entry and let rest "close the gap"} %\usage{Void circ_delete(Circ var, offset=0)} %\description % Remove the current entry from the range of valid entries. % % If step-mode == circle_all or no valid entries: do nothing % If pointer is at last position: % * the value is not deleted, but var.last is decrememted to mark it as % outside of the valid range. var.pointer is decremented as well %\seealso{Circ_Type, circ_append, circ_set} %!%- define circ_delete() % (var, offset=0) { % get arguments variable offset = 0; if (_NARGS == 2) offset = (); variable var = (); % no valid entries if (var.first == NULL) return; % just one valid entry if (var.first == var.last) { var.first = NULL; % \_ means: "NO VALID ENTRIES" var.last = NULL; % / return; } % remember position variable p = var.pointer; % consider offset (might abort due to errro with "linear" mode) circ_step(var, offset); % "delete": entries above the deleted slide one position down while (var.pointer != var.last) { circ_set(var, circ_get(var,1)); circ_fstep(var); } % restore position var.pointer = p; % make sure pointer stays on a valid value if (var.pointer == var.last) % at last valid entry circ_bstep(var); % decrement .last var.last = circ_add(var.last, -1, length(var.values)); } %!%+ %\function{circ_length} %\synopsis{return the number of valid elements of a circular array} %\usage{Int circ_length(Circ var)} %\notes % Returns the length of var.values, if var.step_mode is circle_all) %\seealso{Circ_Type, create_circ, circ_append, circ_get_values } %!%- define circ_length(var) { if (var.step_mode == "circle_all") return(length(var.values)); if (var.first == NULL) % no valid entries return(0); variable ve_length = var.last - var.first + 1; if (ve_length < 1) ve_length += length(var.values); return(ve_length); } %!%+ %\function{circ_get_values} %\synopsis{Return an ordinary array with the valid values of var} %\usage{Array circ_get_values (Circ var)} %\description % Return valid values (the ones added with circ_append) % (return all values if var.mode == circle_all). % if ("circle_all" or "circle_values"), element 0 is the current element % if ("linear"), element 0 is var.first and element N is var.last %\notes % the name is adopted to assoc_get_values(ass) %\seealso{Circ_Type, circ_append, circ_get} %!%- define circ_get_values() % (var, direction = 1) % 1=forward, -1=backward { % get arguments: last is top on stack variable direction = 1; if (_NARGS == 2) direction = (); variable var = (); variable i, arr = _typeof(var.values)[circ_length(var)]; % No valid entries if (var.first == NULL and var.step_mode != "circle_all") return(arr); % array of length 0 % if "linear": return [first, ..., last] if (var.step_mode == "linear") { variable pointer = var.pointer; % save current position if (direction == 1) var.pointer = var.first; else var.pointer = var.last; } % fill array for (i=0; ioccur_goto_line" "g" . "occur->next" "n" . "occur->prev" "p" . "occur->scroll" " " . "occur->scroll_up" Key_BS . "occur->occur_pop_to_line" "\t" loop(6) definekey($1); %}}} %{{{ static variables variable buf = "*occur*", % The buffer that's searched obuf = Null_String, % How many lines of context to show % In occur mode, it should not be assumed that the entry really has % `nlines' lines of context, but if this is not 0 entries are separated by % "^-----" nlines = 0, % flag indicating that we're occurring in multiple buffers mbuffers=0, % were there any matches? matches_flag = 0; % Width of line number prefix without the colon. Choose a width that's a % multiple of `tab-width' so that lines in *Occur* appear right. variable line_number_width=(4 / TAB_DEFAULT + 1) * TAB_DEFAULT - 1, line_number_format = sprintf("%%%dd:", line_number_width), empty =sprintf("%*s", line_number_width + 1, ":"); #ifexists _slang_utf8_ok variable match_marker = sprintf("\e[%d]", color_number("keyword")); #endif %}}} %{{{ occur mode %{{{ moving around static define next() { if (nlines) ()=bol_fsearch("---"); eol; () = re_fsearch ("^ *[0-9]"); bol; if (nlines) recenter(nlines+2); } static define prev() { if (nlines) ()=bol_bsearch("---"); bol; () = re_bsearch ("^ *[0-9]"); if (nlines) { if(bol_bsearch("---")) { () = re_fsearch ("^ *[0-9]"); recenter(nlines+2); } } } %}}} %{{{ jumping to the match static define occur_goto_line() { if (mbuffers) obuf = get_buffer_name(); !if (bufferp (obuf)) return vmessage("buffer: <%s> doesn't exist anymore", obuf); push_spot (); if (nlines) { % goto nearest of separator or matching line eol (); push_spot; !if (bol_bsearch ("---")) bob; push_mark; pop_spot; !if(re_bsearch ("^ *[0-9]+:")) bob; check_region(0); pop_mark_0; } bol; if (re_fsearch ("^ *\\([0-9]+\\):")) integer(regexp_nth_match(1)); else return pop_spot; . pop_spot obuf pop2buf goto_line } static define occur_pop_to_line() { occur_goto_line(); pop2buf(buf); } %}}} %{{{ scrolling the other window static define scroll() { !if (bufferp (obuf)) return; pop2buf (obuf); call("page_down"); pop2buf (buf); } static define scroll_up() { !if (bufferp (obuf)) return; pop2buf (obuf); call("page_up"); pop2buf (buf); } %}}} %{{{ syntax table create_syntax_table($1); #ifdef HAS_DFA_SYNTAX dfa_enable_highlight_cache ("occur.dfa",$1); dfa_define_highlight_rule("^Buffer", "keyword0", $1); dfa_define_highlight_rule("^-+$", "keyword1", $1); dfa_define_highlight_rule("^ *[0-9]+", "number", $1); dfa_define_highlight_rule(":.*$", "normal", $1); dfa_build_highlight_table($1); enable_dfa_syntax_for_mode("occur"); #endif %}}} %!%+ %\function{occur_mode} %\synopsis{mode of the *occur* buffer} %\usage{occur_mode()} %\description % Mode of the \var{*occur*} buffer. The following keys are defined: % \var{RET} go to the source buffer and visit the line % this entry points to % \var{TAB} Visit this line, but stay in the \var{*occur*} buffer % \var{n} Next entry % \var{p} Previous entry % \var{SPC} Scroll source buffer down % \var{DEL} Scroll backward in the source buffer. %\seealso{occur, moccur} %!%- public define occur_mode() { use_keymap ("Occur"); set_mode ("occur", 0); use_syntax_table("Occur"); #ifexists _slang_utf8_ok _set_buffer_flag(0x1000); #endif set_buffer_hook ("newline_indent_hook", &occur_goto_line); set_help_message("RET:goto match TAB:popup match n:next p:prev SPC: scroll source buffer"); run_mode_hooks ("occur_mode_hook"); } %}}} %{{{ search a buffer % This is complicated, but it should always highlight the correct part of the line % even when doing a case insensitive or anchored regexp search. static define search_buffer(obuf, str) { if (buf == obuf) return; if (andelse {mbuffers}{is_substr("* ", obuf[[0]])}) return; variable n, line; setbuf(obuf); push_spot_bob (); variable this_line, next_line, match_len; match_len = re_fsearch (str); !if (match_len) return pop_spot; #ifexists _slang_utf8_ok push_spot; #endif this_line = what_line(); matches_flag=1; setbuf (buf); !if (bobp) newline; vinsert("Buffer: %s\n", obuf); if (nlines) insert ("------\n"); setbuf (obuf); %%% get line and context variable c; % context variable sd = _stkdepth; variable beg, len; USER_BLOCK0 { #ifexists _slang_utf8_ok . "" . bol push_mark pop_spot . bufsubstr . push_mark . match_len 1 - go_right . match_marker . bufsubstr . "\e[0]" . push_mark_eol . bufsubstr . 5 create_delimited_string #else . line_as_string #endif } while (this_line) { % before n = up (nlines); loop (n) { . empty line_as_string go_down_1 } % line sprintf(line_number_format, this_line); X_USER_BLOCK0; ++n; % if context overlaps with next line, merge forever { go_down_1; match_len = re_fsearch (str); !if (match_len) { next_line=0; goto_line(this_line); break; } #ifexists _slang_utf8_ok push_spot; #endif next_line=what_line(); if (next_line - this_line > 2 * nlines) { goto_line(this_line); break; } goto_line(this_line +1); loop(next_line - this_line - 1) { . empty line_as_string go_down_1 ++n } this_line = what_line(); sprintf(line_number_format, this_line); X_USER_BLOCK0; ++n; } % after loop (nlines) { !if(down_1) break; . empty line_as_string ++n } _stk_reverse (_stkdepth-sd); %%% insert in the *occur* buffer setbuf (buf); loop (n) { insert (); insert (); newline (); } if (nlines) insert ("------\n"); setbuf (obuf); this_line=next_line; goto_line(this_line); } pop_spot (); } %}}} %{{{ occur %!%+ %\function{occur} %\synopsis{occur} %\usage{Void occur ([regexp, nlines]);} %\description % This function may be used to search for all occurrences of a string in % the current buffer. Without arguments, it prompts for a string to search % for, defaulting to the word at point. It creates a separate buffer called % \var{*occur*} and associates a keymap called \var{Occur} with the new % buffer. In this buffer, the \var{g} and \var{enter} key may be used to go % to the line described by the match. % % Each line is displayed with \var{nlines} lines before and after. % \var{Nlines} defaults to \var{Occur_Context}. Interactively it is the % prefix arg. %\seealso{occur_mode, moccur} %!%- public define occur() { variable str, n; (str, nlines) = push_defaults (, Occur_Context, _NARGS); if (str == NULL) { nlines = prefix_argument (nlines); str = read_mini ("Find All (Regexp):", get_word (), Null_String); } if (whatbuf() == buf) { if (mbuffers) obuf = get_buffer_name(); % else obuf = previous obuf } else obuf = whatbuf (); mbuffers=0; setbuf (buf); erase_buffer (); matches_flag=0; search_buffer(obuf, str); setbuf (buf); set_buffer_modified_flag (0); !if (matches_flag) { message ("no matches"); return; } popup_buffer (buf); bob (); occur_mode(); } %}}} %{{{ moccur static define get_buffer_name() { push_spot(); eol(); !if (bol_bsearch("Buffer: ")) error("What did you do with the header?!"); ()=ffind_char(' '); . go_right_1 push_mark_eol bufsubstr pop_spot } %!%+ %\function{moccur} %\synopsis{occur multiple buffers} %\usage{moccur([regexp, nlines])} %\description % This function may be used to search for all occurrences of a string in % all buffers except those whose names start with "*" or " ". Otherwise % it works pretty much like \var{occur} %\seealso{occur, occur_mode} %!%- public define moccur() { variable str, n; (str, nlines) = push_defaults (, Occur_Context, _NARGS); if (str == NULL) { nlines = prefix_argument (nlines); str = read_mini ("Find All (Regexp):", get_word (), Null_String); } mbuffers=1; setbuf(buf); erase_buffer (); matches_flag=0; loop(buffer_list()) search_buffer(str); setbuf (buf); set_buffer_modified_flag (0); !if (matches_flag) return message ("no matches"); popup_buffer (buf); bob (); occur_mode(); } %}}} jedmodes-2.5.7/autotext/0000755000175400017500000000000010461125567013466 5ustar mildegmjedmodes-2.5.7/autotext/autotext.sl0000664000175400017500000001322210215264654015703 0ustar mildegm% File: autotext.sl -*- mode: SLang; mode: fold -*- % % $Id: autotext.sl,v 1.20 2003/09/16 12:46:22 paul Exp paul $ % % Copyright (c) 2002, 2003 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % This file provides autotext a la MS Word #iffalse %add this to .jedrc require("autotext"); setkey("complete_autotext", "[[C"); % f3 #endif public variable autotext = Assoc_Type[String_Type]; custom_variable("Autotext_File", dircat(Jed_Home_Directory, #ifdef UNIX ".autotext")); #else "autotext")); #endif static variable autotext_has_changed = 0; %{{{ inserting autotext % Insert() does not wrap, so here is a hack to insert some text and wrap it % by formatting the first paragraph (up to the first empty line). % If you don't want wrapping, define your autotext to begin with an empty line % or switch to no_mode public define insert_wrap(string) { variable flags; ( , flags) = what_mode(); !if (flags & 1) % wrap-flag { insert(string); return; } %{{{ see if we are in an indented paragraph push_spot(); bol(); skip_white(); what_column(); pop_spot(); %}}} what_column(); push_mark(); insert("\n\n\n\n"); push_spot(); %{{{ create the wrapped text ()=up(2); goto_column(); insert("X"); % the first line of a paragraph may be indented push_spot(); insert("\n"); push_spot(); goto_column(); % indentation for the rest of the paragraph insert(string); push_mark(); pop_spot(); call("format_paragraph"); pop_spot(); if (looking_at_char(' ')) call("next_char_cmd"); % extra space bufsubstr(); % got it! %}}} pop_spot(); del_region(); insert(); } %}}} %{{{ Adding autotext items % This is to define a new autotext item. public define new_autotext_item() { variable key, text; !if(markp()) { flush("no region is defined"); return; } text = bufsubstr(); !if(strlen(text)) return; key = strtrim_end(substr(extract_element(strtrim_beg(text), 0,'\n'), 1,40)); forever { key = read_mini("Keyword? ", "", key); !if(assoc_key_exists(autotext, key)) break; if(1 == get_y_or_n("Keyword exists. Overwrite")) break; } !if(strlen(key)) return; autotext[key]=text; autotext_has_changed = 1; } %}}} %{{{ Building the menus %menu for removing autotext items static define autotext_remove_callback(popup) { variable k; foreach (autotext) using ("keys") { k = (); menu_append_item(popup, k, sprintf ("assoc_delete_key(autotext, %s)",make_printable_string(k))); } autotext_has_changed = 1; } %menu for inserting autotext static define autotext_menu_callback(popup) { variable key, cmd; menu_append_item(popup, "new", "new_autotext_item"); menu_append_popup(popup, "&Remove"); menu_set_select_popup_callback(popup+".&Remove", &autotext_remove_callback); menu_append_separator(popup); foreach (autotext) using ("keys") { key = (); cmd = sprintf("insert_wrap(autotext[%s])", make_printable_string(key)); menu_append_item(popup, "&" + key, cmd); } } %create the menu static define add_autotext_popup_hook(menubar) { variable menu = "Global.&Edit"; menu_append_separator(menu); menu_append_popup(menu, "&Autotext"); menu_set_select_popup_callback(menu+".&Autotext", &autotext_menu_callback); } %}}} %{{{ completion on autotext define complete_autotext() { bskip_word_chars(); push_mark(); push_mark(); skip_word_chars(); variable word = bufsubstr(); !if(strlen(word)) { pop_mark_0(); return; } variable vals = assoc_get_values(autotext) [where(array_map(Integer_Type, &is_substr, assoc_get_keys(autotext), word))]; variable valslen = length(vals); !if(valslen) { message("no autotext found"); pop_mark_0(); return; } del_region(); push_mark(); %{{{ cyclic inserting, stolen from dabbrev.sl variable fun_type, fun, i = 0; forever { if(i == valslen) { insert(word); i=0; } else { insert_wrap(vals[i]); i++; } update_sans_update_hook(1); (fun_type, fun) = get_key_binding(); !if(fun == "complete_autotext") break; del_region(); push_mark(); } pop_mark_0(); if(fun_type) call(fun); else eval(fun); %}}} } %}}} %{{{ file stuff. % the autotext file is evaluated as slang code, and since a slang literal % string is limited to 256 char, we need to split it up define slang_string(string) { variable outstring = make_printable_string(substr(string, 1, 100)); variable i = 101; loop(strlen(string) / 100) { outstring += "\n+ " + make_printable_string(substr(string, i, 100)); i+=100; } return outstring; } public define save_autotext_file() { variable key, value, fp; if(0 == autotext_has_changed) return 1; fp = fopen(Autotext_File, "w"); if(fp == NULL) { flush("could not save autotext"); return 1; } ERROR_BLOCK { flush("I failed to save your autotext"); () = getkey(); _clear_error(); } foreach (autotext) using ("keys", "values") { (key, value) = (); () = fputs("autotext[" + make_printable_string(key) + "] = \n" + slang_string(value) + ";\n", fp); } return 1; } public define read_autotext_file() { !if(1 == file_status(Autotext_File)) return; ERROR_BLOCK { flush("error reading the autotext in " + Autotext_File); _clear_error(); } () = evalfile(Autotext_File); } %}}} append_to_hook("load_popup_hooks", &add_autotext_popup_hook); add_to_hook("_jed_exit_hooks", &save_autotext_file); read_autotext_file(); provide("autotext"); jedmodes-2.5.7/make/0000755000175400017500000000000011146323114012513 5ustar mildegmjedmodes-2.5.7/make/make.sl0000644000175400017500000001602311146323114013772 0ustar mildegm% -------------------------------------------- -*- mode:SLang; mode:folding -*- % % MAKE MODE FOR JED % % Copyright (c) 2000 Gerell, Francesc Rocher % Released under the terms of the GNU General Public License (ver. 2 or later) % % 2005-11-11 define_highlight_rule -> dfa_define_highlight_rule % (implemented dpatch by Rafael Laboissiere) % 2009-02-16 documentation update. % % $Id: make.sl,v 1.14 2000/12/30 01:04:50 rocher Exp $ % % -------------------------------------------------------------------- %{{{ % % DESCRIPTION % A very simple mode to write 'Makefile' files. % % USAGE % You can add the line % % autoload ("make_mode", "make"); % % somewhere in your startup file. % % To set the mode automatically, have a look at the custom var % `Mode_Hook_Pointer' and the function mode_hook() and write e.g.: % % % set modes based on filename or more complicated patterns % private variable old_Mode_Hook_Pointer = Mode_Hook_Pointer; % static define set_modes_hook(ext) % { % switch (path_basename(buffer_filename())) % { case ".pycmailrc": python_mode(); return 1; } % { case "Makefile": make_mode(); return 1; } % % chain mode-hook pointers % if (@old_Mode_Hook_Pointer(ext)) return; % return(0); % } % Mode_Hook_Pointer = &set_modes_hook; % % AUTHOR % Francesc Rocher (f.rocher@computer.org) % Feel free to send comments, suggestions or improvements. % % ------------------------------------------------------------------------ %}}} % _debug_info = 1; implements("Make"); private define is_comment_line () %{{{ { push_spot_bol (); skip_white (); $0 = 0; if (what_char () == '#') $0 = what_column (); pop_spot (); return $0; } %}}} private define in_comment () %{{{ { push_spot (); $0 = 0; if (bfind_char ('#')) $0 = what_column (); pop_spot (); return $0; } %}}} private define is_continuation_line () %{{{ { push_spot (); $0 = 0; if (up (1)) { eol (); bskip_white (); !if(bolp ()) { () = left (1); if (what_char () == '\\') { bol_skip_white (); $0 = what_column (); } } } pop_spot (); return $0; } %}}} private define is_rule_head () %{{{ { push_spot_bol (); $0 = 0; while (ffind_char (':')) { $0 = 1; () = right (1); } () = left (1); if (andelse {$0} {in_comment () == 0} {looking_at (":=") == 0}) $0 = 1; else $0 = 0; pop_spot (); return $0; } %}}} private define is_rule_body (); private define is_rule_body () %{{{ { if (is_comment_line ()) return 0; $0 = is_rule_head (); !if ($0) { push_spot (); if (andelse {up (1)} {not bolp ()}) $0 = is_rule_body (); else $0 = 0; pop_spot (); } return $0; } %}}} public define make_indent_line () %{{{ { $0 = is_continuation_line (); if ($0) { push_spot (); bol_skip_white (); if (what_column () < $0) { bol_trim (); insert_char ('\t'); while (what_column () < $0-TAB+1) insert_char ('\t'); whitespace ($0 - what_column ()); } else { while (what_column () > $0) call ("backward_delete_char_untabify"); } pop_spot (); if (what_column () < $0) skip_white (); return; } if (in_comment ()) { % insert_char ('\t'); % This is a possibility ... return; } if (is_rule_head ()) { push_spot_bol (); trim (); pop_spot (); return; } if (is_rule_body ()) { push_spot_bol (); !if (what_char () == '\t') { trim (); insert_char ('\t'); } pop_spot (); if (bolp ()) () = right (1); return; } } %}}} public define make_newline () %{{{ { $1 = is_comment_line (); if ($1) { insert_char ('\n'); whitespace ($1-1); insert ("# "); return; } else { insert_char ('\n'); make_indent_line (); } } %}}} % Syntax highlighting %{{{ $0 = "make"; create_syntax_table ($0); define_syntax ("#", "", '%', $0); define_syntax ('"', '"', $0); define_syntax ('\'', '\'', $0); define_syntax ("(", ")", '(', $0); define_syntax ("0-9a-zA-Z_", 'w', $0); #ifdef HAS_DFA_SYNTAX % % This does not works fine. It seems like the DFA mechanism % in JED is seriously damaged. Or, alternatively (and probably), % I don't know how to write good rules :( % dfa_define_highlight_rule("\"[^\"]*\"", "string", $0); dfa_define_highlight_rule("'[^']*'", "string", $0); %dfa_define_highlight_rule("\"([^\"\\\\]|\\\\.)*\"", "string", $0); %dfa_define_highlight_rule("\"([^\"\\\\]|\\\\.)*\\\\?$", "string", $0); %dfa_define_highlight_rule("'([^'\\\\]|\\\\.)*'", "Qstring", $0); %dfa_define_highlight_rule("'([^'\\\\]|\\\\.)*\\\\?$", "string", $0); dfa_define_highlight_rule ("^[ \t]*@", "string", $0); dfa_define_highlight_rule ("[ \t]*\\\\[ \t]*$", "string", $0); dfa_define_highlight_rule ("[ \t]*#.*$", "comment", $0); dfa_define_highlight_rule ("[A-Za-z_][A-Za-z_0-9]*", "Knormal", $0); %dfa_define_highlight_rule ("[ \t]*[A-Za-z_][A-Za-z_0-9]*", "Knormal", $0); %dfa_define_highlight_rule ("^[ \t]*[A-Za-z_][A-Za-z_0-9]*", "Knormal", $0); dfa_define_highlight_rule ("^[^\"']*\\:$", "keyword1", $0); dfa_define_highlight_rule ("^[^\"']*\\:[ \t]+", "keyword1", $0); %dfa_define_highlight_rule ("[ \t]*\.PHONY.*", "keyword1", $0); dfa_define_highlight_rule ("/include", "normal", $0); dfa_build_highlight_table ($0); enable_dfa_syntax_for_mode ($0); #endif () = define_keywords_n ($0, "ARASCCCOCPFCPCRMfiif", 2, 0); () = define_keywords_n ($0, "CPPCXXGETLEXTEX", 3, 0); () = define_keywords_n ($0, "YACCelseifeq", 4, 0); () = define_keywords_n ($0, "PHONYWEAVEYACCRendefendififdefifneqvpath", 5, 0); () = define_keywords_n ($0, "CFLAGSCWEAVEFFLAGSGFLAGSIGNORELFLAGSPFLAGSRFLAGSSILENTTANGLEYFLAGSdefineexportifndef", 6, 0); () = define_keywords_n ($0, "ARFLAGSASFLAGSCOFLAGSCTANGLEDEFAULTLDFLAGSinclude", 7, 0); () = define_keywords_n ($0, "CPPFLAGSCXXFLAGSMAKEINFOPRECIOUSSUFFIXESTEXI2DVIoverrideunexport", 8, 0); () = define_keywords_n ($0, "SECONDARY", 9, 0); () = define_keywords_n ($0, "INTERMEDIATE", 12, 0); () = define_keywords_n ($0, "EXPORT_ALL_VARIABLES", 20, 0); set_syntax_flags ($0, 0x10|0x80); %}}} public define make_mode () %{{{ { $0 = "make"; !if (keymap_p ($0)) { make_keymap ($0); definekey ("make_indent_line", "^I", $0); definekey ("make_newline", " ", $0); } set_mode ($0, 4); use_keymap ($0); use_syntax_table ($0); run_mode_hooks ("make_mode_hook"); } %}}} jedmodes-2.5.7/menutils/0000755000175400017500000000000010461125576013451 5ustar mildegmjedmodes-2.5.7/menutils/menutils.sl0000664000175400017500000000721110246562004015644 0ustar mildegm% menutils.sl -*- mode: Slang; mode: Fold -*- % popup menu extensions % % $Id: menutils.sl,v 1.1 2005/05/27 18:24:00 paul Exp paul $ % Keywords: slang, ui % % Copyright (c) 2004, 2005 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). provide("menutils"); static define menu_do_toggle(var) { @var = not @var; } %!%+ %\function{menu_checkbox} %\synopsis{make a 'checkbox' menu item} %\usage{menu_checkbox(String menu, String name, Ref or Integer var, [String or Ref fun1, [String or Ref fun2]])} % %\description % define a menu item that works as a checkbox. When \var{var} != 0, % the menu will have an '[X]', else a '[ ]' in front. When called % with 3 arguments, \var{var} should be a reference to the variable. % The menu item will toggle \var{var} (if it's 0 it will become 1, % else 0). With 4 arguments, \var{fun1} is a name or reference to a % 'toggle' function. \var{Var} is an integer indicating the state % that is toggled by \var{fun1}. With 5 arguments, \var{fun1} should % toggle \var{var} on and \var{fun2} should toggle it off. %\notes % %\seealso{menu_radio} %!%- public define menu_checkbox() % menu, name, var, fun1, [fun2] { variable menu, name, var, fun1, fun2; (menu, name, var, fun1, fun2) = push_defaults(,,,,, _NARGS); variable menu_item; if (fun1 == NULL) { if (@var) menu_item = "[X] " + name; else menu_item = "[ ] " + name; menu_append_item (menu, menu_item, &menu_do_toggle, var); } else { if (var) menu_item = "[X] " + name; else menu_item = "[ ] " + name; if (fun2 == NULL or not var) menu_append_item (menu, menu_item, fun1); else menu_append_item (menu, menu_item, fun2); } } static define menu_do_radio(); static define menu_make_radio(menu, var, names, values, fun) { variable i = 0; loop (length(names)) { variable a = __pop_args(menu, var, names[i], values[i], names, values, fun, 7); if (@var == values[i]) menu_append_item(menu, "(*) " + names[i], &menu_do_radio, a); else menu_append_item(menu, "( ) " + names[i], &menu_do_radio, a); i++; } } static define menu_do_radio(a) { variable menu, var, name, value, names, values, fun; (menu, var, name, value, names, values, fun) = __push_args(a); @var = value; if (fun != NULL) @fun(value); menu_delete_items(menu); menu_make_radio(menu, var, names, values, fun); } %!%+ %\function{menu_radio} %\synopsis{make a 'radio buttons' popup menu} %\usage{public define menu_radio(String menu, String popup, Ref var, String names, [String values], [Ref fun])} %\description % With 3 arguments: % % Make a popup menu \var{popup} under menu \var{menu}, with items in % the comma-separated list \var{names}, like: % %#v+ % ( ) apples % ( ) pears % (*) beer %#v- % % The item that is equal to the value of \var{var} is checked. Select an % item to assign another value to \var{var}. % % If there is a 4th parameter and it's not NULL, it is a % comma-separated list of values that correspond 1:1 to the % \var{names}. To assign a value to \var{var}, check the % corresponding item in \var{names} in the popup. % % The 5th parameter is a function that is called when an item is % selected. % %\notes % %\seealso{menu_checkbox} %!%- public define menu_radio() % menu, popup, var, names, [values], [fun] { variable menu, popup, var, names, values, fun; (menu, popup, var, names, values, fun) = push_defaults(,,,,,, _NARGS); if (typeof(names) == String_Type) names = strchop(names, ',', '\\'); if (values == NULL) values = names; menu_append_popup (menu, popup); menu_make_radio (menu + "." + popup, var, names, values, fun); } jedmodes-2.5.7/ispell/0000755000175400017500000000000011262367306013100 5ustar mildegmjedmodes-2.5.7/ispell/ispell.sl0000644000175400017510000002254711262367306015432 0ustar mildemilde% ispell.sl -*- mode: SLang; mode: fold -*- % % $Id: ispell.sl,v 1.26 2009/03/14 15:21:29 paul Exp paul $ % % Copyright (c) 2001-2009 Guido Gonzato, John Davis, Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Thanks to Günter Milde. provide("ispell"); require("ispell_common"); require("bufutils"); use_namespace("ispell"); ifnot (is_defined("ispell_process")) public variable ispell_process = -1; static variable buf, obuf, num_win; static variable ibuf = " *ispell*", corbuf = "*corrections*"; % This is just to unwind the call stack if you press 'q' new_exception("IspellError", RunTimeError, "Quit!"); %{{{ ispell process define kill_ispell() { if (-1 != ispell_process) kill_process(ispell_process); ispell_process = -1; } static define wait_for_ispell_output (secs) { variable max_time = _time () + secs; variable this_line = what_line (), line; do { get_process_input(1); line = what_line; if (line > this_line ) { if (bolp and eolp) % last line of output is empty { go_up_1; if (bolp and eolp) return 0; eob; } this_line = line; } } while (max_time > _time ()); return -1; } static define start_ispell_process () { variable cbuf = whatbuf (); variable args = strtok (ispell_command + " -a"); setbuf(ibuf); erase_buffer; vmessage ("starting %s process....", Ispell_Program_Name); foreach (args) ; length (args) - 1; #ifexists open_process_pipe ispell_process = open_process_pipe (); #else ispell_process = open_process (); #endif if (ispell_process == -1) throw RunTimeError, "Could not start " + Ispell_Program_Name; % () = wait_for_ispell_output (5); % The header is NOT followed by a blank line... sleep(1); get_process_input(2); bob (); if (looking_at_char ('@')) % ispell header del_through_eol (); else { pop2buf(whatbuf); ispell_process = -1; if (looking_at("execvp")) { pop2buf(buf); throw RunTimeError, "Could not start " + Ispell_Program_Name; } else { pop2buf(buf); throw RunTimeError, Ispell_Program_Name + " crashed!"; } } send_process(ispell_process, "!\n"); process_query_at_exit (ispell_process, 0); setbuf (cbuf); } %}}} %{{{ checking a word static define send_string_to_ispell_process (word) { setbuf (ibuf); if (ispell_process == -1) start_ispell_process (); erase_buffer (); send_process (ispell_process, strcat ("^", word, "\n")); if (wait_for_ispell_output (5) == -1) throw RunTimeError, "ispell process is not responding"; } define get_ispell_command(word, key_array, corrections) { variable n, num; forever { num = get_mini_response("Enter choice. "); switch (num) {case 'r': return read_mini("correct word:", "", word);} {case ' ': return NULL;} {case 'a': send_process (ispell_process, strcat ("@", word, "\n")); return NULL;} {case 'i': send_process (ispell_process, strcat ("*", word, "\n#\n")); return NULL;} {case 'u': send_process (ispell_process, strcat ("*", strlow(word), "\n#\n")); return NULL;} {case 'n': return -1;} {case 'x' or case 'X' or case 'q': throw IspellError;} if (corrections != NULL) { if (num == ' ') return corrections[0]; n = wherefirst (key_array == num); if (n != NULL) return corrections[n]; } } } static variable start_column; static define ispell_line(); % check a word % is_auto = 0: called from ispell() % 1: called from autoispell() - gone % 2: called from ispell_region() define ispell_parse_output (is_auto) { variable num_win, old_buf, corrections = NULL; variable word, n, new_word; variable keys = "0123456789!@#$%^&*()", key_array = Char_Type[20]; variable ispell_offset; %% %% parse output %% bob(); if (looking_at_char('@')) % ispell header { del_through_eol (); } EXIT_BLOCK { setbuf (buf); } if (bolp and eolp) { ifnot (is_auto) message ("Correct"); return; } variable line = line_as_string; if (line[0] == '&') { ispell_offset = atoi (strtok (line, " :")[3]); corrections = strchop(extract_element(line, 1, ':'), ',', 0); if (length(corrections) > 20) corrections = corrections[[:19]]; corrections = array_map (String_Type, &strtrim, corrections); erase_buffer(); init_char_array (key_array, keys); n = length(corrections); key_array = key_array[[:n - 1]]; variable i = 0; setbuf (corbuf); erase_buffer(); loop (n) { vinsert("(%c) %s\n", key_array[i], corrections[i]); ++i; } buffer_format_in_columns(); } else % there was no '&' so it was a '#' { ispell_offset = atoi (extract_element(line, 2, ' ')); setbuf (corbuf); erase_buffer(); insert ("no suggestions"); } word = extract_element(line, 1, ' '); bob(); insert(strcat ("Misspelled: ", word, "\tKey: select correction\t r: enter correction\n", "space: skip\t a: accept this session\t n: next line\n", "i: insert into dictionary\tu: uncapitalized insert\tx: quit\n")); pop2buf(buf); % start_column expands tabs, but ispell_offset is the column info from % ispell, which counts tabs as one character (we gave ispell the line % starting at start_column). Aspell 0.60 counts multibyte characters % as one character in utf-8 mode, we can use go_right() which does not % expand tabs, but is utf-8 aware. goto_column(start_column); go_right(ispell_offset - 1); % we prepended a '^' to keep ispell % from interpreting the line as a command, this is included in % ispell's column info push_visible_mark(); go_right(strlen(word)); num_win = nwindows() - MINIBUFFER_ACTIVE; if (num_win == 1) { old_buf = buf; sw2buf(corbuf); pop2buf(buf); otherwindow; } else old_buf = pop2buf_whatbuf (corbuf); bob; if (num_win == 1) window_set_rows(8); set_buffer_modified_flag(0); try { new_word = get_ispell_command(word, key_array, corrections); } catch IspellError: { sw2buf(old_buf); pop2buf(buf); if (num_win == 1) onewindow(); pop_mark_0(); throw IspellError; } sw2buf(old_buf); pop2buf(buf); if (num_win == 1) onewindow(); if (typeof(new_word) == Integer_Type && new_word == -1) return pop_mark_0; if (new_word != NULL) { del_region(); insert(new_word); if (is_auto == 2) go_left(strlen(new_word)); % new word is doublechecked } else pop_mark_0(); if (is_auto == 2) { ispell_line(); % check rest of line } } %!%+ %\function{ispell} %\synopsis{spell-check a word} %\usage{ispell ()} %\description % Spell-check the word at point. If the word is misspelled, pop up a % buffer with suggestions for correction and wait for a command. % Commands: % \var{DIGIT} Select a correction % \var{i} Insert into private dictionary % \var{u} Insert into private dictionary in lowercase % \var{a} Accept for this session % \var{SPC} Skip this time % \var{r} Replace with one or more words % These commands apply when checking a region: % \var{n} Skip this line % \var{x}, \var{X}, \var{q} Stop spell-checking %\seealso{ispell_region, flyspell_mode, ispell_change_dictionary} %!%- public define ispell () { skip_chars(ispell_letters); variable n = POINT; ispell_beginning_of_word(); if (POINT == n) return; start_column = what_column; push_mark(); ispell_end_of_word(); buf = whatbuf(); variable word = bufsubstr(); send_string_to_ispell_process (word); ispell_parse_output(0); } %}}} %{{{ checking a region % If I check % % get it at http://jedmodes.sourceforge.net! % % ispell_region will stop at "jedmodes", but skip "sourceforge.net". The % reason is that after "jedmodes" is accepted, ispell sees % ".sourceforge.net", interprets it as a troff command, and skips it. % Since internet addresses should not be checked anyway, that's OK. define ispell_line() { start_column = what_column; push_spot; push_mark_eol; bufsubstr; pop_spot; send_string_to_ispell_process(); ispell_parse_output(2); } %!%+ %\function{ispell_region} %\synopsis{spell-check a region} %\usage{ispell_region()} %\description % If there is a visible mark, spell-check the region. Otherwise, % spell-check the buffer from the current point. %\notes % For checking html, it's better to use vispell or flyspell %\seealso{ispell, flyspell_region} %!%- public define ispell_region() { buf = whatbuf; if (ispell_process == -1) { start_ispell_process (); update_sans_update_hook(1); get_process_input(10); } push_narrow(); if (is_visible_mark) { narrow(); bob(); } if (is_list_element("TeX,LaTeX", get_mode_name(), ',')) send_process (ispell_process, "+\n"); else send_process (ispell_process, "-\n"); try { if (blocal_var_exists("ispell_region_hook")) { variable ispell_hook = get_blocal_var("ispell_region_hook"); forever { if (@ispell_hook) ispell_line; ifnot (down_1) break; skip_chars("\n"); } } else { forever { ispell_line; ifnot (down_1) break; skip_chars("\n"); } } } catch IspellError; pop_narrow(); if (bufferp(corbuf)) delbuf(corbuf); } %}}} jedmodes-2.5.7/ispell/look.sl0000644000175400017500000000772510616631075014416 0ustar mildegm% look.sl % % $Id: look.sl,v 1.10 2007/04/21 10:14:47 paul Exp paul $ % % Copyright (c) 2003-2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides completion of words from the system dictionary. This % was adapted from the BSD look program. provide ("look"); require("ispell_common"); use_namespace("ispell"); private variable fp, word, l; private variable keys_string = "0123456789abcdefghijklmnopqrstuvwxyz"; private variable look_max_hits = strlen(keys_string); private variable keys = Char_Type[look_max_hits]; init_char_array(keys, keys_string); private define skip_past_newline(p) { variable s; ()=fseek(fp, p, SEEK_SET); ()=fgets(&s, fp); return ftell(fp); } private define compare(p) { variable s; ()=fseek(fp, p, SEEK_SET); ()=fgets(&s, fp); return strncmp(word, strlow(s), l); } private define binary_search(front, back) { ()=fseek(fp, front, SEEK_SET); variable p = (back - front) / 2; p = skip_past_newline(p); while (p < back and back > front) { if (compare(p) > 0) front = p; else back = p; p = front + (back - front) / 2; p=skip_past_newline(p); } return front; } private define linear_search(front) { variable c, s, result = 0; ()=fseek(fp, front, SEEK_SET); loop (look_max_hits) { if (-1 == fgets(&s, fp)) break; c = (strncmp(word, strlow(s), l)); if (c > 0) continue; if (c < 0) break; s; } } % Case insensitive binary search dictionary lookup. Returns matches as an % array of words. define look(w, file) { word=w; l=strlen(w); fp = fopen(file, "r"); if (fp == NULL) throw RunTimeError, sprintf("could not open file %s", file); variable front, back, result; ()=fseek(fp, 0, SEEK_SET); front = ftell(fp); ()=fseek(fp, 0, SEEK_END); back = ftell(fp); front = binary_search(front, back); result = [w, linear_search(front)]; result = result[[1:]]; ()=fclose(fp); return result; } % Complete word by looking it up in the system dictionary. % Has little to do with ispell, but in Emacs it's called ispell-complete. public define ispell_complete() { variable word, new_word, buf = whatbuf, cbuf = "*completions*", num_win = nwindows, obuf, completions, i, wordlen; _pop_n(_NARGS); push_spot(); push_mark(); ispell_beginning_of_word(); % The Dutch dictionary does have % "-'" chars in words word = strlow(bufsubstr()); wordlen = strlen(word); pop_spot(); if (ispell_wordlist == "") return message ("no wordlist"); completions = look(word, ispell_wordlist); !if (length(completions)) return message ("no completions"); % try to complete a part variable first_completion = completions[0]; variable last_completion = completions[-1]; if (length(completions) < look_max_hits - 1 and not strncmp (first_completion, last_completion, 1 + strlen (word))) { % is there a simple way to find a common beginning of two strings? variable len = strlen (first_completion); % Either first_completion is a substring of last_completion, % or they differ somewhere, so this won't give an array range error _for i (0, strlen(first_completion), 1) { if (first_completion[i] != last_completion[i]) break; } i--; insert (strtrim_end(first_completion[[wordlen:i]], "\n")); return; } obuf = pop2buf_whatbuf(cbuf); erase_buffer; _for i (0, length(completions) - 1, 1) { vinsert ("(%c) %s", keys[i], completions[i]); } buffer_format_in_columns; bob; insert ("completions for " + word + "\n"); set_buffer_modified_flag(0); message ("Enter choice (SPACE to leave unchanged)"); update_sans_update_hook(0); try { i = getkey(); } finally { sw2buf(obuf); pop2buf(buf); if (num_win == 1) onewindow(); bury_buffer(cbuf); } if (i != ' ') { i = wherefirst (i == keys); if (i != NULL) if (i < length(completions)) insert (strtrim_end(completions[i][[wordlen:]])); } } jedmodes-2.5.7/ispell/ispell_common.sl0000644000175400017510000001570611262367306017001 0ustar mildemilde% ispell_common.sl % % $Id: ispell_common.sl,v 1.19 2009/03/14 15:21:29 paul Exp paul $ % % Copyright (c) 2003-2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides some definitions common to ispell, flyspell and % vispell. It is not part of JED. % The JMR ispell package can be found at http://jedmodes.sf.net provide ("ispell_common"); require ("ispell_init"); require("menutils"); implements("ispell"); variable ispell_letters, ispell_non_letters, ispell_otherchars, % otherchars are chars that % may appear inside words, in .aff files they're called boundarychars. ispell_wordchars, ispell_wordlist, ispell_command; variable ispell_current_dictionary = Ispell_Dictionary; variable flyspell_current_dictionary = Ispell_Dictionary; define flyspell_switch_active_buffer_hook(); define flyspell_change_syntax_table(); define kill_ispell(); define kill_flyspell(); % make the ispell command (except for options only needed by some modes) % and set the ispell_language settings private define make_ispell_command() { variable ispell_options = ""; variable hash; switch(strtok(Ispell_Program_Name)[0]) { case "ispell" : hash = Ispell_Languages; } { case "aspell" : hash = Aspell_Languages; } { case "hunspell": hash = Hunspell_Languages; } { throw RunTimeError, "spell program should be ispell, aspell or hunspell"; } variable language = hash[ispell_current_dictionary]; ispell_letters = language.letters; ispell_otherchars = language.otherchars; ispell_wordlist = Ispell_Wordlist [ispell_current_dictionary]; if (ispell_current_dictionary != "default") ispell_options += " -d " + language.hash_name; if (language.extchar != "") ispell_options += " -T " + language.extchar; % extra options come last ispell_options += " " + language.options; ispell_wordchars = ispell_otherchars+ispell_letters; ispell_non_letters = "^" + ispell_letters; % we don't set a '-[thn]' option here because an ispell/flyspell % process may work on different buffers, and probably doesn't need it ispell_command = strcompress (strcat (Ispell_Program_Name, " ", ispell_options), " "); } %{{{ set language %{{{ change the current language private define ispell_change_current_dictionary(new_language) { if (new_language != ispell_current_dictionary) { ispell_current_dictionary = new_language; make_ispell_command(); kill_ispell(); if (get_blocal_var("flyspell", 0) and flyspell_current_dictionary != ispell_current_dictionary) { kill_flyspell(); flyspell_current_dictionary = ispell_current_dictionary; flyspell_change_syntax_table(new_language); } } } %}}} %{{{ get dictionaries private define dictionaries() { switch(strtok(Ispell_Program_Name)[0]) { case "ispell" : return assoc_get_keys(Ispell_Languages); } { case "aspell" : return assoc_get_keys(Aspell_Languages); } { case "hunspell": return assoc_get_keys(Hunspell_Languages); } } %}}} %{{{ change the global language %!%+ %\function{ispell_change_dictionary} %\synopsis{cange the ispell dictionary} %\usage{ispell_change_dictionary([new_language])} %\description % Change \var{Ispell_Dictionary} and the ispell-internal variable % \var{ispell_current_dictionary} to \var{new_language} and kill old % ispell and flyspell process if this means a change in % \var{ispell_current_dictionary}. A new one will be started as % soon as necessary. %\notes % Setting Ispell_Dictionary to "ask" will cause ispell to prompt % for a language the first time an ispell function is called. %\seealso{ispell_change_local_dictionary, ispell, flyspell_mode} %!%- public define ispell_change_dictionary() % ([new_language]) { variable new_language; if (_NARGS) new_language = (); else { new_language = read_with_completion (strjoin(dictionaries(), ","), "new language", Ispell_Dictionary, "", 's'); } Ispell_Dictionary = new_language; ispell_change_current_dictionary(new_language); } % kludge to get _NARGS right with menu selection public define ispell_dictionary_menu_item(language) { ispell_change_dictionary(language); } %}}} %{{{ change blocal language % Change the language %!%+ %\function{ispell_change_local_dictionary} %\synopsis{change the bufferlocal ispell dictionary} %\usage{ispell_change_local_dictionary([new_language])} %\description % Change the bufferlocal variable \var{ispell_dictionary} and the % ispell-internal variable \var{ispell_current_dictionary} to % \var{new_language} and kill old ispell and flyspell process if this % means a change in \var{ispell_current_dictionary}. A new one will % be started as soon as necessary. %\notes % There is only one \var{ispell_current_dictionary}. When switching % between flyspelled buffers in different languages, the ispell % process has to be restarted. %\seealso{ispell_change_dictionary, ispell, flyspell_mode} %!%- public define ispell_change_local_dictionary() % ([new_language]) { variable new_language; if (_NARGS) new_language = (); else { new_language = read_with_completion (strjoin(dictionaries(), ","), "new language", get_blocal_var("ispell_dictionary", Ispell_Dictionary), "", 's'); } define_blocal_var("ispell_dictionary", new_language); ispell_change_current_dictionary(new_language); } % kludge to get _NARGS right with menu selection public define ispell_local_dictionary_menu_item(language) { ispell_change_local_dictionary(language); } define ispell_switch_buffer_hook(old_buffer) { ispell_change_current_dictionary(get_blocal_var("ispell_dictionary", Ispell_Dictionary)); flyspell_switch_active_buffer_hook(); } % The blocal may have been set from e.g. gdbmrecent.sl or a modehook ispell_switch_buffer_hook(""); add_to_hook("_jed_switch_active_buffer_hooks", &ispell_switch_buffer_hook); %}}} %}}} %{{{ menu private variable menu_local_dummy; % menu_radio can't use blocals public define ispell_change_dictionary_callback (popup) { menu_append_item (popup, "&Word", "ispell"); menu_append_item (popup, "&Region", "ispell_region"); menu_append_item (popup, "&Flyspell", "flyspell_mode"); menu_append_separator(popup); variable lang, languages = dictionaries(); languages = languages[array_sort(languages)]; menu_radio (popup, "dictionary", &Ispell_Dictionary, languages, , &ispell_change_dictionary); menu_local_dummy= get_blocal_var("ispell_dictionary", Ispell_Dictionary); menu_radio (popup, "&buffer dictionary", &menu_local_dummy, languages, , &ispell_change_local_dictionary); } %}}} %{{{ some helper functions % this only works right if you're on a word of course define ispell_beginning_of_word() { bskip_chars(ispell_wordchars); skip_chars(ispell_otherchars); } define ispell_end_of_word() { skip_chars(ispell_wordchars); bskip_chars(ispell_otherchars); } %}}} if (Ispell_Dictionary == "ask") ispell_change_dictionary(); make_ispell_command; jedmodes-2.5.7/ispell/ispell.otl0000644000175400017510000001143511262367306015604 0ustar mildemildeispell mode * installation Simply put it all in your load path, add require ("ispell_init"); to your .jedrc, and any keybindings you want. And set up your dictionaries. * dictionaries On Debian the dictionaries should be automatically initialised by the dictionaries-common package. On other systems, use ispell_add_dictionary(), aspell_add_dictionary() or hunspell_add_dictionary(). hash_name: the name by which ispell knows the language (a .hash file in /usr/lib/ispell) letters: letters that constitute words. For latin1 languages, the default should be all right. otherchars: chars that may appear inside words, or outside words. In English it's "'", in other languages it may be "-'". Old versions of dictionaries_common don't provide this argument, so you have to update. ext_char: something that's put in the ispell command line after a "-T" flag and should match a stringtype defined in /usr/lib/ispell/(language).aff. So it's not the same as Emacs ispell's extended-character-mode or character-set. If you're European try latin1. Dutch doesn't seem to need it but in German an 'ä' will be turned into an '"a' without it. This option is only for ispell_add_dictionary(), not for aspell_add_dictionary(). options: any other args you want to pass. wordlist: just needed for ispell_complete, it would be annoying to have to set the language for ispell AND a wordlist for completions. For Debian users, this one is not automatically filled in. * ispell and utf-8 For checking utf-8, it's recommended to use aspell. Ispell.sl does not work with ispell in utf-8 mode, though flyspell.sl should. * using (i|fly)spell with other modes ** checking TeX When in TeX mode, ispell_region() will tell the ispell process to switch to TeX mode. Ispell will not check the markup. However, when a word is misspelled, the rest of the line is again sent to ispell like this: check out this fomrula $ A^2 + B^2 = C^2 $ First it will stop at fomrula, then "formula $ A^2 +" will be sent again to re-check the correction and check the rest of the line (much easier to program that way). The problem is that in TeX, "$" starts and ends a math environment which ispell does not check, and ispell does not see its input as unrelated lines, but tries to keep track of the environment. The first "$" is seen twice, so the third "$" will start a new math environment for ispell, and the rest of the buffer will not be checked. I don't know how much of a problem this is, since I don't use TeX. BTW I read somewhere that the `$' to delimit math environments is deprecated. *** flyspelling TeX To flyspell TeX while keeping your syntax highlighting use a hook like this: define latex_mode_hook() { define_blocal_var("flyspell_syntax_table", "TeX-Mode"); } Flyspell doesn't always work with DFA, so it turns DFA mode off when a blocal flyspell_syntax_table is set. ** checking html Doesn't work. Since ispell does not have an interactive command for turning html parsing on, you would have to create a dictionary entry for html: ispell_add_dictionary("html", "british", NULL, "-'", "/home/paul/htmlwords.txt", " -h"); Htmlwords.txt would be a list of html keywords for word-completion. You can set this in the html mode hook: define html_mode_hook() { ispell_change_local_dictionary("html"); define_blocal_var("flyspell_syntax_table", "html"); } This could be expected to have the same shortcomings as [checking TeX]. If you'd check get more kool jedmodez from
you could expect it to complain about "kool" but skip over "jedmodez" since it would think this is part of a HTML tag. As it turns out, html parsing works differently between a full-screen ispell and ispell -a. The full-screen ispell deals correctly with tags that span lines, but ispell -a will echo the lines between the opening and closing bracket without an empty line to indicate it has finished processing the line. Ispell.sl does not know how to deal with this and crashes. ** checking email Email.sl has an ispell_message() function that will check the body of of the message, and an ispell_region_hook that will skip past quoted text. Get it from http://jedmodes.sf.net. * FAQ ** Undefined Name: ispell_region: Function did not autoload You installed ispell.sl in jed's lib/ directory and didn't remove ispell.slc. Put non-standard modes in their own directory. ** Invalid UTF-8 encoded string You're running in utf-8 mode, and the 'letters' and/or 'otherchars' arguments of your ispell_add_dictionary or aspell_add_dictionary calls are not encoded in utf-8. Use something like if (_slang_utf8_ok) { % utf-8 settings } else { % latin1 settings } * license This package is GPL'ed. No warranty. You can get the latest version at http://jedmodes.sf.net/mode/ispell * thanks Kudos to Günter Milde, Rafael Laboissiere, Agustin Martin and JED. jedmodes-2.5.7/ispell/vispell.sl0000644000175400017500000000270310616631075015117 0ustar mildegm% vispell.sl % % $Id: vispell.sl,v 1.10 2007/04/21 10:22:00 paul Exp paul $ % % Copyright (c) 2003-2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides a full-screen interface to ispell, like in joe or vi. % Thanks to Romano Giannetti and John Davis. autoload ("vrun_program_fg", "runpgm"); provide ("vispell"); require("ispell_common"); use_namespace("ispell"); public define vispell() { variable cmd, tmp = "/tmp/jedispell", mode, mask; cmd = ispell_command; (mode,) = what_mode(); % set the format depending on the mode (troff/TeX/html) switch (mode) { case "TeX" or case "LaTeX" : cmd += " -t";} { case "nroff": cmd += " -n";} { case "html" or case "sgml" : cmd += " -h";} if(Ispell_Program_Name == "aspell") cmd += " check"; cmd += " -x"; tmp = make_tmp_file(tmp); !if (is_visible_mark) mark_buffer(); () = dupmark; mask = umask(0x600); try { () = write_region_to_file(tmp); sleep(2); cmd = strcat (cmd, " ", tmp); if (is_defined("x_server_vendor")) { system (strcat ("rxvt -e ", cmd)); 0; % how do I get the return status of a program running in an xterm? } else run_program (cmd); !if () { del_region(); () = insert_file(tmp); } else { message("ispell failed to run"); pop_mark_0(); } call("redraw"); } finally { () = umask(mask); () = delete_file(tmp); } } jedmodes-2.5.7/ispell/flyspell.sl0000644000175400017500000002243610727504120015271 0ustar mildegm% flyspell.sl % % $Id: flyspell.sl,v 1.23 2007/12/07 17:01:47 paul Exp paul $ % % Copyright (c) 2003-2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This file provides a minor mode for on-the-fly spell checking. require("syntax"); require("ispell_common"); use_namespace("ispell"); % The DFA trick used in this file does not work with "-" as an otherchar, % so we trim it. variable flyspell_otherchars = strtrim_beg(ispell_otherchars, "-"); variable flyspell_wordchars = flyspell_otherchars + ispell_letters; variable flyspell_syntax_table; private variable accumulator = ""; % do you want to use keyword2 to have red misspellings? custom_variable("flyspell_use_keyword2", 1); variable flyspell_chars = " "; !if (is_defined("flyspell_process")) public variable flyspell_process = -1; %{{{ Flyspell process % This will also restart flyspell, through the flyspell_is_dead() function define kill_flyspell() { if (-1 != flyspell_process) kill_process(flyspell_process); } private define flyspell_parse_output (pid, output) { accumulator += output; variable name = flyspell_syntax_table; variable lines = strchop(accumulator, '\n', 0); if (length(lines) < 2) { return; } accumulator = lines[-1]; variable line; foreach line (lines[[:-2]]) { line = strtok(strtrim(line)); if (length(line) < 2) continue; line = line[1]; try { if (flyspell_use_keyword2) add_keyword_n(name, line, 2); else add_keyword(name, line); } catch AnyError; } } private define flyspell_is_dead (pid, flags, status) { if (flags & 14) flyspell_process = -1; } private define toggle_local_flyspell(); private define flyspell_init_process () { % we need to redefine these in case this process was started % by switching to a buffer in another language flyspell_otherchars = strtrim_beg(ispell_otherchars, "-"); flyspell_wordchars = flyspell_otherchars + ispell_letters; variable buf, ibuf = " *flyspell*"; % JED has problems with asynchronous processes that are stopped and % immediately restarted so we make sure that we kill the process when % the dictionary changes, and start it when it's needed. if (flyspell_process != -1) return; buf = whatbuf(); variable args = strtok (ispell_command + " -a"); setbuf(ibuf); erase_buffer; message ("starting flyspell process...."); foreach (args) ; length (args) - 1; flyspell_process = open_process (); sleep(0.5); get_process_input(2); if (flyspell_process == -1) throw RunTimeError, "could not start ispell"; % Give ispell a chance to start. Maybe I should use % wait_for_ispell_output() here. variable flyspell_started = 0; loop (5) { bob (); if (looking_at_char ('@')) % ispell header { flyspell_started = 1; del_through_eol (); break; } else get_process_input(2); } !if (flyspell_started) % if we're not looking at the ispell header, there was probably an % error. For some reason flyspell does not exit (or maybe the % signal handler can't run) before this function returns so telling % if a process has started successfully is a bit difficult. { pop2buf(whatbuf); flyspell_process = -1; if (looking_at("execvp")) { pop2buf(buf); throw RunTimeError, "Could not start ispell!"; } else { pop2buf(buf); throw RunTimeError, "Flyspell crashed!"; } } send_process(flyspell_process, "!\n"); set_process (flyspell_process, "signal", &flyspell_is_dead); set_process (flyspell_process, "output", &flyspell_parse_output); process_query_at_exit(flyspell_process, 0); accumulator = ""; setbuf(buf); } %}}} %{{{ Flyspelling variable lastword = "", lastpoint = 0; public define flyspell_word() { variable word, point; if (flyspell_process == -1) { try { flyspell_init_process(); } catch AnyError: { toggle_local_flyspell(0); return; } } push_spot(); bskip_chars(ispell_non_letters); push_mark(); bskip_chars(flyspell_wordchars); skip_chars(flyspell_otherchars); point = _get_point(); word = bufsubstr(); if (word == "") return pop_spot(); EXIT_BLOCK { (lastword, lastpoint) = word, point; pop_spot(); } if (word == lastword) { if (point != lastpoint) { bskip_chars(ispell_non_letters); bskip_chars(flyspell_wordchars); skip_chars(flyspell_otherchars); if (looking_at(word)) { message("double word"); beep(); } } return; } if (strlen(word) < 3) return; clear_message; send_process( flyspell_process, strcat ("^", word, "\n")); } private define after_key_hook () { try { if (is_substr(flyspell_chars, LASTKEY)) flyspell_word(); } catch AnyError: { toggle_local_flyspell(0); } } %}}} %{{{ Turning flyspell mode on/off define flyspell_switch_active_buffer_hook() { remove_from_hook ("_jed_after_key_hooks", &after_key_hook); if (get_blocal_var("flyspell", 0)) add_to_hook ("_jed_after_key_hooks", &after_key_hook); flyspell_syntax_table = get_blocal_var("flyspell_syntax_table", "Flyspell_" + flyspell_current_dictionary); } private define toggle_local_flyspell() % on/off { variable flyspell; !if (_NARGS) not get_blocal_var("flyspell", 0); flyspell = (); define_blocal_var("flyspell", flyspell); if (flyspell) { set_status_line(str_replace_all(Status_Line_String, "%m", "%m fly"), 0); if (flyspell_current_dictionary != ispell_current_dictionary) { kill_flyspell; flyspell_current_dictionary = ispell_current_dictionary; } } else { set_status_line(Status_Line_String, 0); } flyspell_switch_active_buffer_hook(); } %}}} #ifdef HAS_DFA_SYNTAX %%% DFA_CACHE_BEGIN %%% define setup_dfa_callback (name) { dfa_define_highlight_rule (sprintf("[%s][%s]*[%s]",ispell_letters, flyspell_wordchars, ispell_letters), "Knormal", name); dfa_define_highlight_rule("[^ -~%s]+", "normal", name); dfa_build_highlight_table (name); } %%% DFA_CACHE_END %%% #endif private variable syntax_tables = Assoc_Type[Integer_Type, 0]; define flyspell_make_syntax_table(name) { flyspell_otherchars = strtrim_beg(ispell_otherchars, "-"); flyspell_wordchars = flyspell_otherchars + ispell_letters; if (syntax_tables[name]) return; syntax_tables[name] = 1; create_syntax_table(name); set_syntax_flags(name, 0); define_syntax(flyspell_wordchars, 'w', name); dfa_set_init_callback (&setup_dfa_callback, name); } % A change in syntax table is from starting flyspell in a buffer with % another language, or from changing the language while flyspelling. If % you just switch to a buffer with a different setting for language, it % should continue to use its own syntax table. define flyspell_change_syntax_table(language) { variable table = get_blocal_var("flyspell_syntax_table", NULL); if(table != NULL) { use_syntax_table(table); define_syntax(ispell_wordchars, 'w', table); use_dfa_syntax(0); flyspell_syntax_table=table; } else { % this will get confused when you change the global language from a % buffer that has a blocal language. table = "Flyspell_" + language; flyspell_make_syntax_table(table); flyspell_syntax_table = table; use_syntax_table(table); use_dfa_syntax(1); } } %!%+ %\function{flyspell_mode} %\synopsis{toggle flyspell mode} %\usage{flyspell_mode()} %\description % This toggles flyspell mode for the buffer. In flyspell mode, % misspelled words are highlighted as you type. If you're in doubt % whether flyspell mode is on, look at the statusbar - it should say % something like "(text fly)" %\notes % Flyspell works by adding the misspellings to a flyspell syntax table % asynchronously, which means that JED's flyspell mode does not give % the slow responsiveness of Emacs' flyspell mode and other similar % products. It also means that mode-dependent syntax highlighting is % turned off while you flyspell. You can make flyspell write its % misspellings to a syntax table of your choice by setting the % bufferlocal variable \var{flyspell_syntax_table} (\var{mail_mode} does this) %\seealso{ispell, flyspell_region} %!%- public define flyspell_mode() { flyspell_init_process(); flyspell_change_syntax_table(ispell_current_dictionary); toggle_local_flyspell(); if (flyspell_use_keyword2) set_color("keyword2", "brightred", get_color("normal"), exch(), pop); } %!%+ %\function{flyspell_region} %\synopsis{highlight misspellings in the region} %\usage{flyspell_region()} %\description % Send the region, or the buffer if there is no visible mark, to the % flyspell process. If the buffer is not in flyspell mode, flyspell % mode is turned on. %\seealso{flyspell_mode, ispell_region} %!%- public define flyspell_region() { variable line; flyspell_current_dictionary = ispell_current_dictionary; !if (get_blocal_var("flyspell", 0)) flyspell_mode(); push_spot(); !if (is_visible_mark()) mark_buffer(); flush ("flyspelling..."); try { foreach line (strchop(bufsubstr(), '\n', 0)) { send_process( flyspell_process, "^" + line + "\n"); } } finally { pop_spot(); } flush("flyspelling...done"); } provide("flyspell"); jedmodes-2.5.7/ispell/ispell_init.sl0000644000175400017510000001053611262367306016450 0ustar mildemilde% ispell_init.sl -*- mode: SLang; mode: fold -*- % % $Id: ispell_init.sl,v 1.15 2009/03/14 15:21:29 paul Exp paul $ % % Copyright (c) 2003-2007 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This defines global variables and functions for the ispell package. % You may evaluate this on starting JED. require("sl_utils"); provide ("ispell_init"); %{{{ autoloads _autoload("ispell_change_dictionary", "ispell_common", "ispell_dictionary_menu_item", "ispell_common", "ispell_change_local_dictionary", "ispell_common", "ispell_local_dictionary_menu_item", "ispell_common", "ispell_complete", "look", "flyspell_mode","flyspell", "flyspell_region", "flyspell", "ispell_region", "ispell", "vispell", "vispell", 9); _add_completion("ispell_change_dictionary", "ispell_change_local_dictionary", "flyspell_mode", "ispell_region", "flyspell_region", 5); %}}} %{{{ custom variables % Your spell program. This could be ispell or aspell. ifnot (is_defined("Ispell_Program_Name")) { variable Ispell_Program_Name; if (1 == file_status("/usr/bin/aspell") || 1 == file_status("/usr/local/bin/aspell")) Ispell_Program_Name = "aspell"; else if (1 == file_status("/usr/bin/hunspell") || 1 == file_status("/usr/local/bin/hunspell")) Ispell_Program_Name = "hunspell"; else Ispell_Program_Name = "ispell"; } % your default dictionary. "default" means use system default custom_variable("Ispell_Dictionary", "default"); %}}} %{{{ public variables typedef struct { hash_name, letters, otherchars, extchar, options } Ispell_Dictionary_Type; private define make_ispell_dictionary() { variable name, hash, letters, otherchars, opts; (name, hash, letters, otherchars, opts) = push_defaults ( , , "", "", "", _NARGS); if (hash == NULL) hash = name; variable language = @Ispell_Dictionary_Type; set_struct_fields(language, hash, strcat ("a-zA-Z",letters), otherchars, strtrim_beg (qualifier("ext_chr", ""), "~"), opts); return language; } variable Ispell_Languages = Assoc_Type[Ispell_Dictionary_Type]; variable Ispell_Wordlist = Assoc_Type [String_Type,"/usr/share/dict/words"]; public define ispell_add_dictionary() % (name, hash=name, letters = a-z etc., % otherchars = "'", extchr = "", opts = "") { variable args = __pop_list(_NARGS - 1); variable name = (); variable extchar; if (length(args) >= 4) extchar = list_pop(args, 4); else extchar = ""; Ispell_Languages [name] = make_ispell_dictionary(name, __push_list(args); ext_char=extchar); } ispell_add_dictionary ("default"); variable Aspell_Languages = Assoc_Type[Ispell_Dictionary_Type]; public define aspell_add_dictionary() % (name, hash=name, letters = a-z etc., % otherchars = "'", opts = "") { variable args = __pop_list(_NARGS - 1); variable name = (); Aspell_Languages [name] = make_ispell_dictionary(name, __push_list(args)); } aspell_add_dictionary ("default"); variable Hunspell_Languages = Assoc_Type[Ispell_Dictionary_Type]; public define hunspell_add_dictionary() % (name, hash=name, letters = a-z etc., % otherchars = "'", opts = "") { variable args = __pop_list(_NARGS - 1); variable name = (); Hunspell_Languages [name] = make_ispell_dictionary(name, __push_list(args)); } hunspell_add_dictionary ("default"); % This will set up the dictionaries on your system, if you are a Debian Unstable user. custom_variable("Ispell_Cache_File", "/var/cache/dictionaries-common/jed-ispell-dicts.sl"); if (1 == file_status (Ispell_Cache_File)) () = evalfile (Ispell_Cache_File); % else % otherwise, add your dictionaries here, or in your .jedrc after loading this file. % { % ispell_add_dictionary("deutsch", "german", "", "", "latin1"); % ispell_add_dictionary("british"); % % if you're using utf-8, try something like % ispell_add_dictionary("nederlands", "nl", "a-zA-ZÄËÏÖÜäëïöüáéíóú", "-'", "", "-B"); % } %}}} %{{{ menu autoload("ispell_change_dictionary_callback", "ispell_common"); static define ispell_load_popup_hook (menubar) { variable menu = "Global.S&ystem"; menu_delete_item (menu + ".&Ispell"); menu_append_popup (menu, "&Ispell"); menu = "Global.S&ystem.&Ispell"; menu_set_select_popup_callback(menu, &ispell_change_dictionary_callback); } append_to_hook ("load_popup_hooks", &ispell_load_popup_hook); %}}} jedmodes-2.5.7/fileview/0000755000175400017500000000000011130344607013413 5ustar mildegmjedmodes-2.5.7/fileview/fileview_cmds.sl0000644000175400017500000000624711130344607016604 0ustar mildegm. "fileview_cmds" provide . "fileview" use_namespace . _stkdepth =$1 % This list reflects what I (Paul Boekholt) have on my disk and what % Fransesc Rocher had back in '97. Ideally there should be a cmds file % for Gnome users, another one for KDE users, one for Windows users... % (does this thing work in Windows?). % % The order of the wild-cards in the next table is VERY important. % Generic wild-cards MUST appear later: for example "*.gz" must appear % after "*.tar.gz", "*.ps.gz", etc. If you want to use xv in X and zgv % in the console, list xv first. % % Pushing everything on the stack and then popping it reverses the % order, so generic wild-cards are listed first here. % % These wild-cards are NOT case sensitive. % ----------------------------------------------------------- % 'MOD' values: 'b' View results in a buffer % 'f' Use a function and view results in a buffer % 'X' Use an external program, requires X % 'T' Requires a terminal - use run_program % % % MOD WILD-CARDS COMMANDS % --- ------------ % ...any more? . "b" "*.uue" "uudecode -o /dev/stdout" . "b" "*.html.gz" "lynx -dump" . "b" "*.htm.gz" "lynx -dump" . "f" "*.html" "jedscape_get_url(\"%s\")" . "f" "*.htm" "jedscape_get_url(\"%s\")" % Image formats ... % ...any more? . "T" "*.pcx" "zgv" . "T" "*.pbm" "zgv" . "T" "*.jpeg" "zgv" . "T" "*.jpg" "zgv" . "T" "*.gif" "zgv" . "T" "*.bmp" "zgv" . "DISPLAY" getenv NULL != { % pdf, postscript . "X" "*.pdf.z" "xpdf" . "X" "*.pdf.gz" "xpdf" . "X" "*.pdf" "xpdf" . "X" "*.eps.z" "gv" . "X" "*.eps.gz" "gv" . "X" "*.eps" "gv" . "X" "*.ps.z" "gv" . "X" "*.ps.gz" "gv" . "X" "*.ps" "gv" . "X" "*.dvi" "xdvi" . "X" "*.fig" "xfig" . "X" "*.lyx" "lyx" % images . "X" "*.xcf" "gimp --no-splash --no-splash-image --no-data > /dev/null 2>&1" . "X" "*.xwd" "xwud -in " . "X" "*.xpm" "xli" . "X" "*.xbm" "xli" . "X" "*.tiff" "xli" . "X" "*.tif" "xli" . "X" "*.tga" "xli" . "X" "*.ppm" "xli" . "X" "*.png" "xli" . "X" "*.pnm" "xli" . "X" "*.pm" "xli" . "X" "*.pgm" "xli" . "X" "*.pcx" "xli" . "X" "*.pbm" "xli" . "X" "*.jpeg" "xli" . "X" "*.jpg" "xli" . "X" "*.gif" "xli" . "X" "*.bmp" "xli" % Movie formats . "X" "*.qt" "xanim +q" . "X" "*.rp" "realplay" . "X" "*.mpeg" "xanim +q" . "X" "*.mpg" "xanim +q" . "X" "*.avi" "xanim +q" . } if % sources - try to extract documentation . "b" "*.pm" "pod2text" % python - if the directory is writable, pydoc bytecompiles the file? . "b" "*.py" "pydoc" . "f" "*.sl" "tm_view(\"%s\")" % documents . "b" "*.ms" "groff -Tascii -ms" . "b" "*.man" "unix_man (\"-l %s\")" . "f" "*.info.gz" ". \"(%s)\" info_find_node info_reader" . "f" "*.info" ". \"(%s)\" info_find_node info_reader" . "f" "*.[1-9][tTxX]" "unix_man (\"-l %s\")" . "f" "*.[1-9nlpo]" "unix_man (\"-l %s\")" . "b" "*.doc" "antiword" % archives . "b" "*.jar" "jar tvf" . "b" "*.rpm" "rpm -qRp" . "b" "*.zip" "unzip -l" . "b" "*.bz2" "bzip2 -dc" . "f" "*.tar.bz2" "tar (\"%s\")" . "f" "*.tar.z" "tar (\"%s\")" . "f" "*.tar.gz" "tar (\"%s\")" . "f" "*.t[ag]z" "tar (\"%s\")" . "f" "*.tar" "tar (\"%s\")" . _stkdepth $1 - 3 / {fileview_add_pipe} loop jedmodes-2.5.7/fileview/fileview.sl0000644000175400017500000001007510346302336015571 0ustar mildegm% fileview.sl -*- mode: Slang; mode: Fold -*- % configurable file viewing function % % $Id: fileview.sl,v 1.1 2004/02/25 21:41:57 paul Exp paul $ % Keywords: slang % % Copyright (c) 1997 Francesc Rocher; (c) 2004, 2005 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This is a simplified version of the treepipe filtered viewer from % tree.sl. It should also be useful with dired or filelist. % This version requires the wildcard module. provide("fileview"); require("wildcard"); implements("fileview"); variable fileview_pipe = String_Type[100, 3], fileview_pipe_last = 0; private variable in_x = (NULL != getenv("DISPLAY")); %!%+ %\function{fileview_add_pipe} %\synopsis{add an entry to the fileview table} %\usage{fileview_add_pipe(mode, wildcard, command)} %\description % Adds an entry to the fileview table which associates wildcard % patterns with viewers. The parameters are: % % \var{mode} values: % 'b' View results in a buffer % 'f' Use a function and view results in a buffer % 'X' Use an external program, requires X % 'T' Requires a terminal - use run_program % % \var{wildcard} the pattern to match % This should be a lowercase glob pattern. The filename is lowercased % before being matched. % % \var{command} % the command to view the file. % If \var{mode} is 'f' this is the name of a S-Lang function. Should look % like "tar (\"%s\")". The filename will be substituted for the %s. % % Otherwise it's a program name. If there is a "%s" in the command, % the filename is substituted, otherwise it is appended to the % command. % %\seealso{fileview_view_pipe} % %!%- define fileview_add_pipe(mode, wildcard, command) { if (mode == "X" and not in_x) return; if (3 * fileview_pipe_last >= length(fileview_pipe)) { fileview_pipe = [fileview_pipe, @String_Type[99]]; reshape (fileview_pipe, [length(fileview_pipe) / 3, 3]); } fileview_pipe[fileview_pipe_last, *] = [mode, wildcard, command]; fileview_pipe_last++; } %!%+ %\function{fileview_view_pipe} % %\synopsis{view a file through a pipe} % %\usage{fileview_view_pipe(String file)} % %\description % Tries to match the filename \var{file} with a table of wildcard % patterns. When a match is found, the associated action is taken. % %\seealso{add_to_fileview_pipe} % %!%- public define fileview_view_pipe (file) { % Show a file through a pipe. variable i, m = 0; _for (0, fileview_pipe_last, 1) { i = (); if (fileview_pipe[i,0]==NULL) break; m = wildcard_match (strlow(path_basename(file)), fileview_pipe[i,1]); if (m) break; } !if (m) return message ("no viewer found"); if (fileview_pipe[i,0] == "b") { pop2buf ("*fileview*"); } flush ("Processing file "+file+" ..."); % --- Command ------------------------------------------------ switch (fileview_pipe[i,0]) { case "b": % Send output to buffer if (is_substr(fileview_pipe[i,2], "%")) () = run_shell_cmd (sprintf(fileview_pipe[i,2], file) + " 2> /dev/null"); else () = run_shell_cmd (fileview_pipe[i,2]+" "+file+" 2> /dev/null"); } { case "f": % Use a function eval (sprintf(fileview_pipe[i,2],file)); } { case "X": % Use an X-windows program if (is_substr(fileview_pipe[i,2], "%")) () = system (sprintf(fileview_pipe[i,2], file) + " 2> /dev/null"); else () = system (fileview_pipe[i,2]+" "+file+" 2> /dev/null &"); } { case "T": % terminal program if (is_substr(fileview_pipe[i,2], "%")) () = run_program (sprintf(fileview_pipe[i,2], file)); else () = run_program(fileview_pipe[i,2]+" "+file); call("redraw"); } % --- Finally ------------------------------------------------ if (fileview_pipe[i,0] == "b") { bob (); set_buffer_modified_flag (0); most_mode (); } flush ("Processing file "+file+" ... done"); } % edit fileview_cmds.sl to define your own pipe commands require("fileview_cmds"); jedmodes-2.5.7/complete/0000755000175400017500000000000011130344607013411 5ustar mildegmjedmodes-2.5.7/complete/complete.sl0000644000175400017500000001230511130344607015562 0ustar mildegm# =pod ; # % complete.sl % % $Id: complete.sl,v 1.2 2008/12/22 15:49:22 paul Exp paul $ % % Copyright (c) 2004-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This defines a function called "complete" that runs the blocal hook % "complete_hook", and a function to find completions in a file. The idea % is to bind complete() to a key (M-tab say), make a keywords file, and % set some blocal variables. The keywords file is just a sorted file of % keywords or function names, one per line. For example in php, write a % php file like % % % % save the output to the file php_words in your Jed_Home_Directory, and add % this to .jedrc: % % define php_mode_hook() % { % define_blocal_var("Word_Chars", "a-zA-Z_0-9"); % local_setkey("complete_word", "\e\t"); % define_blocal_var("complete_hook", "complete_from_file"); % } % % To do partial completion, press M-tab. To cycle through completions, % press M-tab again. % % For S-Lang, run this script as % jed-script complete.sl % to make a completions file. % % For Perl, run Perl on this file to get a completions file: % perl complete.sl % To add functions from additional modules, add them as extra parameters, % appending the export tags like in perl's -M option (see perlrun): % perl complete.sl 'CGI=:standard' 'Debian::DictionariesCommon=:all' if (__argv[0] == path_basename(__FILE__)) { ()=find_file(dircat(Jed_Home_Directory, "slang_words")); erase_buffer(); variable words = _apropos("Global", "...", 15); variable word; foreach word (words[array_sort(words)]) { insert(word); newline(); } save_buffer(); exit(0); } require("txtutils"); private variable context = NULL; % find the completions of WORD in FILE % The file should be sorted! private define before_key_hook(); private define before_key_hook (fun) { if (typeof (fun) == Ref_Type) fun = "&"; ifnot (is_substr (fun, "complete_word")) { if (context.n) pop_mark_0(); remove_from_hook ("_jed_before_key_hooks", &before_key_hook); context = NULL; } } private define next_completion() { if (context.n) del_region(); if (context.n == context.n_completions) { remove_from_hook ("_jed_before_key_hooks", &before_key_hook); context = NULL; flush("no more completions"); } else { push_mark(); insert(substr(context.completions[context.n], context.i, -1)); flush (strjoin(context.completions[[context.n:]], " ")); context.n++; } } define complete_from_file() % (word [file]) { variable word, file; (word, file) = push_defaults(,, _NARGS); if (context != NULL) return next_completion(); if (word == NULL || word == "") return message("no word"); % shouldn't happen if (file == NULL) file = dircat(Jed_Home_Directory, strlow (sprintf("%s_words", what_mode(), pop))); if (1 != file_status(file)) return message ("no completions file"); variable n_completions, len = strlen(word); word = str_quote_string (word, "\\^$[]*.+?", '\\'); n_completions= search_file(file, sprintf("\\c^%s", word), 50); switch (n_completions) {case 0: return message ("no completions");} {case 50: return _pop_n(50);} % we can't do a partial completion {case 1: variable completion = strtrim(); insert (substr(completion, len+1, -1)); return;}; variable completions = __pop_args(n_completions); completions = array_map(String_Type, &strtrim, [__push_args(completions)]); variable first_completion, last_completion, i, n = 0; first_completion = completions[0]; last_completion = completions[-1]; _for i (len, strlen(first_completion), 1) { if (strncmp(first_completion, last_completion, i)) break; } then { i++; } insert (substr(first_completion, len+1, i - len - 1)); message (strjoin(completions, " ")); context = struct { completions, n_completions, n, i }; set_struct_fields(context, completions, n_completions, n, i); add_to_hook ("_jed_before_key_hooks", &before_key_hook); } define complete_word() { variable word = get_word(); ifnot (strlen(word)) return message("nothing to complete"); run_blocal_hook("complete_hook", word); } provide("complete"); # =cut use strict; # adapted from perl.sl sub find_keywords { local @ARGV = "perldoc -u perlfunc|"; while (<>) { last if /^=head2\s+Alphabetical/ } # cue up my %kw = map { $_ => 1 } ( # language elements + carp qw( else elsif foreach unless until while carp cluck croak confess ), # keywords map { /^=item\s+([a-z\d]+)/ } <>, ); return \%kw; } sub find_module_symbols { my ($kw, $module) = @_; my $fh; my ($module_sans_tags)=split(/[ =]/, $module); my @command = ( "perl", "-M" . $module, "-e", 'map {print "$_\n" if *$_{CODE} } keys %main::'. $module_sans_tags . '::' ); my $fh; open($fh, "-|") or exec @command; while (<$fh>) { chomp; next if length($_) < 4; next if /^_/ or not /[a-z]/; $kw->{$_} = 1; } } my $kw = find_keywords; while (my $module = shift @ARGV) { find_module_symbols($kw, $module); } map {print "$_\n" if length > 3 } sort keys %$kw; # jedmodes-2.5.7/cuamouse/0000755000175400017500000000000011121652254013422 5ustar mildegmjedmodes-2.5.7/cuamouse/cuamouse.sl0000644000175400017500000003115411121652254015607 0ustar mildegm% cuamouse.sl: CUA-compatible mouse mode % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 1 1998 (published 15. 01. 03) % 1.1 mark_word does no longer skip back to next word % implemented mark_by_lines for right drag % 2005-03-18 1.2 added some tm documentation % 2005-07-05 1.3 added `xclip` workaround for interaction with QT % applications (tip by Jaakko Saaristo) % 2006-02-15 1.4 made auxiliary variables static % 2006-05-26 1.4.1 added missing autoload (J. Sommer) % 2006-10-05 1.5 bugfixes after testing, % use mark_word() from txtutils.sl (new dependency!) % use private variables instead of static ones % 2007-10-23 1.5.1 provide("mouse") as mouse.sl does not do so % 2008-02-06 1.6 * fix swapped args to click_in_region() % in cuamouse_left_down_hook() % * support for scroll-wheel % * button-specific hooks with return values % 2008-05-05 1.6.1 * use x_insert_selection() in cuamouse_insert() % (os.sl defines it, if it does not exist) % * remove `xclip` workaround, as PRIMARY selection % interaction should be ok by now % (but see cuamark.sl for CLIPBOARD selection handling). % 2008-06-19 1.6.2 * re-introduce `xclip` workaround for X-selection bug % as the fix is only complete in 0.99.19 % 2008-12-16 1.6.3 * fix `xclip` insertion, % take pipe_region() return value from stack. % % % Actions % ======== % % In the Text: % % Left click: % - no region defined: move point to mouse-cursor (mouse_goto_position) % - outside a region: undefine region % - inside a region: copy to selection and delete region ("pick") % + Shift: copy to (yp)-yankbuffer % % Middle click: % - insert selection at mouse-cursor % Shift: % insert (yp)-yankbuffer (yank_from_jed) % % Right click: % - region defined: extend region to mouse-cursor (ggf exchange_point_and_mark first) % - no region defined: move point to mouse-cursor % % Left drag: % - define a region and copy to selection % Middle drag: % - insert selection at mouse-point instead of point % Right drag: % - mark by lines (or, as original left drag: mark but leave point) % % Statusline: % % Left click: % - next buffer (jed default) % Right click: % - split window (jed default) % TODO: % Left drag: enlarge/shrink window % %---------------------------------------------------------------------------- % Requirements % ------------ autoload("cua_mark", "cuamark"); autoload("mark_word", "txtutils"); % mouse.sl does not have a provide("mouse") line % require("mouse"); () = evalfile("mouse"); provide("mouse"); provide("cuamouse"); % Customisation % ------------- % Mouse_Wheel_Scroll_Lines is defined in mouse.sl but not documented: %!%+ %\variable{Mouse_Wheel_Scroll_Lines} %\synopsis{Number of lines to scroll per mouse-wheel event} %\usage{variable Mouse_Wheel_Scroll_Lines = 3} %\description % Number of lines a mouse whell event shall scroll at a time. %\seealso{mouse_set_default_hook} %!%- %!%+ %\variable{CuaMouse_Use_Xclip} %\synopsis{Use `xclip` instead of Jed's X selection interaction functions} %\usage{Int_Type CuaMouse_Use_Xclip = 0} %\description % Currently, a xjed selection doesnot paste into applications using the % QT toolkit (all KDE applications including Klipper, lyx-qt). % % This workaround uses the command line tool `xclip` to copy the selected % text to the X selection and to insert from the X selection. % % As it introduces a dependency on `xclip` and some overhead, it is disabled % by default. %\seealso{x_copy_region_to_selection, x_insert_selection} %!%- custom_variable("CuaMouse_Use_Xclip", 0); % more customisation can be done by overruling the default hooks (see % mouse_set_default_hook() and set_buffer_hook()). % % To quote the helpf for mouse_set_default_hook() % % The meaning of these names should be obvious. The second parameter, % `fun' must be defined as % % define fun (line, column, btn, shift) % % and it must return an integer. % % `btn' indicates the button pressed and can take on the values % `1' left, % `2' middle, % `4' right, % 8 wheel-up % 16 wheel-down % % `shift' can take on values % `0' no modifier key was pressed, % `1' SHIFT key was pressed, and % `2' CTRL key was pressed. % % For more detailed information about the modifier keys, use the function % `mouse_get_event_info'. % % When the hook is called, the editor will automatically change % to the window where the event occured. The return value of % the hook is used to dictate whether or not hook handled the % event or whether the editor should switch back to the window % prior to the event. Specifically, the return value is interpreted % as follows: % % -1 Event not handled, pass to default hook. % 0 Event handled, return [to GM] active window prior to event % 1 Event handled, stay in current window. % Private Variables % ----------------- private variable Drag_Mode = 0; % 0 no previous drag, 1 drag private variable Clipboard = ""; % string where a mouse-drag is stored % Functions % --------- %!%+ %\function{click_in_region} %\synopsis{determine whether the mouse_click is in a region} %\usage{Int click_in_region(line, col)} %\description % Given the mouse click coordinates (line, col), the function % returns an Integer denoting: % -2 click "after" region % -1 click "before" region % 0 no region defined % 1 click in region % 2 click in region but "void space" (i.e. past eol) %\seealso{cuamouse_left_down_hook, cuamouse_right_down_hook} %!%- define click_in_region(line, col) { !if(is_visible_mark()) return 0; % Determine region boundries (region goes from (l_0, c_0) to (l_1, c_1) check_region(0); variable l_1 = what_line(); variable c_1 = what_column(); exchange_point_and_mark(); variable l_0 = what_line(); variable c_0 = what_column(); exchange_point_and_mark(); % vshow("region: [(%d,%d), (%d,%d)]", l_0, c_0, l_1, c_1); % Click before the region? if(orelse{line < l_0} {(line == l_0) and (col < c_0)}) return -1; % click after the region (except last line)? if(line > l_1) return -2; % click in void space of region (past eol) or l_1 past endcol? push_spot(); goto_line(line); variable eolcolumn = goto_column_best_try(col); pop_spot(); if ((line == l_1) and (col >= c_1) and eolcolumn == col) return -2; if (eolcolumn < col) return 2; return 1; } % copy region to X-selection and internal clipboard (The region stays marked) define copy_region_to_clipboard() { % no copy if the region is void () = dupmark(); if (bufsubstr() == "") return; % copy to PRIMARY x-selection or Windows clipboard () = dupmark(); if (CuaMouse_Use_Xclip) { () = pipe_region("xclip"); } else x_copy_region_to_selection(); % copy to Jed-internal clipboard () = dupmark(); Clipboard = bufsubstr(); } % Insert x-selection (or, if (from_jed == 1), Clipboard) at point. % wjed will insert the Windows clipboard define cuamouse_insert(from_jed) { if (from_jed) insert(Clipboard); else if (CuaMouse_Use_Xclip) { () = run_shell_cmd("xclip -o"); update_sans_update_hook(1); % call("redraw"); } else x_insert_selection(); } % cursor follows mouse, scroll if pointer is outside window. define cuamouse_drag(line, col) { variable top, bot; variable y; mouse_goto_position(col, line); top = window_info ('t'); bot = top + window_info('r'); (,y, ) = mouse_get_event_info(); if ((y < top) or (y > bot)) x_warp_pointer(); } % mark word define cuamouse_2click_hook(line, col, but, shift) { if (but == 1) { mouse_goto_position(col, line); mark_word(); copy_region_to_clipboard(); % only if non-empty return 1; % stay in current window } return -1; } % scroll with mouse-wheel events (but == 8 up, but == 16 down) % see also Mouse_Wheel_Scroll_Lines define cuamouse_wheel_hook(line, col, but, shift) { % Variant with continuous point movement (as in mouse.sl) % variable l = window_line(); % loop (Mouse_Wheel_Scroll_Lines) % { % switch (but) % { case 8: skip_hidden_lines_backward (1); } % { case 16: skip_hidden_lines_forward (1); } % } % bol(); % recenter(l); % Variant with point-wrap if it "falls of the screen" variable l = window_line(); variable rows = window_info('r'); switch (but) { case 8: l += Mouse_Wheel_Scroll_Lines; } % wheel up { case 16: l -= Mouse_Wheel_Scroll_Lines; } % wheel down % wrap point if it leaves window if (l <= 0) { l += Mouse_Wheel_Scroll_Lines; loop (Mouse_Wheel_Scroll_Lines) skip_hidden_lines_forward(1); } if (l > rows) { l -= Mouse_Wheel_Scroll_Lines; loop (Mouse_Wheel_Scroll_Lines) skip_hidden_lines_backward(1); bol(); } recenter(l); return 0; } % Button specific down hooks % -------------------------- % Left button: goto position of pointer, if click-in-region, pick it define cuamouse_left_down_hook(line, col, shift) { switch (click_in_region(line, col)) { case 1: if (shift == 1) yp_kill_region(); else { copy_region_to_clipboard(); del_region(); } } { % default if (is_visible_mark()) % undefine region if existent pop_mark(0); } mouse_goto_position(col, line); return 1; % stay in current window } define cuamouse_middle_down_hook(line, col, shift) { if (is_visible_mark()) % undefine region if existent pop_mark(0); mouse_goto_position(col, line); !if (input_pending(1)) cuamouse_insert(shift); % shift == 1: insert jed-clipboard % else % show("input pending, maybe you scrolled too fast"); return 1; % stay in current window } define cuamouse_right_down_hook(line, col, shift) { if (click_in_region(line, col) == -1) % click "before" region exchange_point_and_mark(); mouse_goto_position(col, line); return 1; % stay in current window } % Button specific drag hooks % argument drag: Begin_Middle_End of drag: 0 Begin, 1 Middle, 2 End (up) % mark region define cuamouse_left_drag_hook(line, col, drag, shift) { if (drag == 0) cua_mark(); cuamouse_drag(line, col); % cursor follows mouse if (drag == 2) % last drag (button up) copy_region_to_clipboard(); return 1; } define cuamouse_middle_drag_hook(line, col, drag, shift) { return -1; } % mark region by lines define cuamouse_right_drag_hook(line, col, drag, shift) { if (drag == 0) % first drag { pop_mark_0(); bol(); cua_mark(); } cuamouse_drag(line, col); eol(); if (drag == 2) % last drag (button up) copy_region_to_clipboard(); return 1; } % Generic mouse hooks (down, drag, up) % ------------------------------------ % down hook: calls the button specific ones define cuamouse_down_hook(line, col, but, shift) { switch (but) { case 1: return cuamouse_left_down_hook(line, col, shift); } { case 2: return cuamouse_middle_down_hook(line, col, shift); } { case 4: return cuamouse_right_down_hook(line, col, shift); } { case 8 or case 16: return cuamouse_wheel_hook(line, col, but, shift); } } % generic drag hook: calls the button specific ones % with third argument Drag_Mode: 0 first drag, 1 subsequent drag define cuamouse_drag_hook(line, col, but, shift) { variable rv; switch (but) { case 1: rv = cuamouse_left_drag_hook(line, col, Drag_Mode, shift); } { case 2: rv = cuamouse_middle_drag_hook(line, col, Drag_Mode, shift);} { case 4: rv = cuamouse_right_drag_hook(line, col, Drag_Mode, shift); } Drag_Mode = 1; return rv; } % generic up hook: calls the button specific drag (!) hooks % with third argument set to 2 (up = end of drag) define cuamouse_up_hook(line, col, but, shift) { if (Drag_Mode) { switch (but) { case 1: cuamouse_left_drag_hook(line, col, 2, shift); } { case 2: cuamouse_middle_drag_hook(line, col, 2, shift); } { case 4: cuamouse_right_drag_hook(line, col, 2, shift); } Drag_Mode = 0; } return 1; } mouse_set_default_hook("mouse_2click", "cuamouse_2click_hook"); mouse_set_default_hook("mouse_down", "cuamouse_down_hook"); mouse_set_default_hook("mouse_drag", "cuamouse_drag_hook"); mouse_set_default_hook("mouse_up", "cuamouse_up_hook"); %mouse_set_default_hook("mouse_status_down", "mouse_status_down_hook"); %mouse_set_default_hook("mouse_status_up", "mouse_status_up_hook"); jedmodes-2.5.7/ffap/0000755000175400017500000000000011034361300012505 5ustar mildegmjedmodes-2.5.7/ffap/ffap.sl0000644000175400017500000001616311034361300013770 0ustar mildegm% ffap.sl % % $Id: ffap.sl,v 1.9 2008/06/19 16:37:00 paul Exp paul $ % % Copyright (c) 2003-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Find File At Point, something like Emacs' ffap. You can use this as a % replacement for find_file() by adding % require("ffap"); % setkey("ffap", "^x^f); or whatever you use for find_file % to .jedrc require("pcre"); %!%+ %\variable{Ffap_URL_Reader} %\synopsis{Function to open a URL} %\usage{variable Ffap_URL_Reader = "find_url"} %\description % "browse_url" open the URL in an external browser % "find_url" open the URL in a jed buffer (as is) % "view_url" open an ASCII rendering of the URL in a jed buffer %\seealso{ffap} %!%- custom_variable("Ffap_URL_Reader", "find_url"); %!%+ %\variable{Ffap_Prompt_Level} %\synopsis{Should a file|dir|URL be opened with prompt?} %\usage{variable Ffap_Prompt_Level = 3} %\description % 0: no (if file|dir|URL could be guessed from the word-at-point) % 1: only when the extension is added from the Ext-list % 2: always except for an URL % 3: always (even for an URL) %\seealso{ffap} %!%- custom_variable("Ffap_Prompt_Level", 3); autoload("get_word", "txtutils"); autoload("dired_read_dir", "dired"); variable rimini_array; %{{{ helper fun private define add_list_element(list, elem, delim) { if (strlen(elem) and not is_list_element(list, elem, delim)) { if (strlen(list)) return sprintf("%s%c%s", elem, delim, list); else return elem; } return list; } %}}} %{{{ ffap data % This struct holds the mode-specific info !if (is_defined("ffapvars")) typedef struct { ext, path, always } ffapvars; variable ffap_info = Assoc_Type [ffapvars]; %!%+ %\function{ffap_set_info} %\synopsis{set the ffap custom variables for a mode} %\usage{ ffap_set_info(mode, ext, path, always)} %\description % Use \sfun{ffap_set_info} to customize the behavior of \sfun{ffap} when the buffer % is in mode \sfun{mode}. % \var{ext}: a list of extensions that may have been left out % e.g. in SLang ".sl" as in %#v+ % autoload("get_word", "txtutils"); % -> txtutils.sl % autoload("dired_read_dir","dired"); % autoload("recent_get_files", "recent"); %#v- % \var{Path}: the search path (I always look in the buffer dir at least, % but not in subdirectories). For SLang: your library path. % \var{Always}: determines if you want a new file if the file doesn't % exist. % 0: no % 1: yes % 2: only if word ends in one of the exts. May make sense in html mode. % 3: Open a new file appending the extension listed first in exts to word. %\example % for C mode, you'll use something like %#v+ % ffap_set_info("C",".h,.c,.C", "/usr/include,/usr/local/include/", 2); %#v- % %\seealso{ffap} %!%- public define ffap_set_info(mode, ext, path, always) { ffap_info[mode] = @ffapvars; ffap_info[mode].ext = ext; ffap_info[mode].path = path; ffap_info[mode].always = always; } ffap_set_info("SLang", ".sl", get_jed_library_path(), 2); %}}} %{{{ finding the file at point % Try to match `word' to a valid file|dir|URL % Return the guess and a status indicator % USAGE (file, status) = ffap_find(word) % status: -1 no valid file found % 0 file is found after some guessing % 1 'file' is a valid file % 2 'file' is a directory % 3 'file' is a URL private define ffap_find(word) { !if (strlen(word)) return("", -1); variable mode, path = "", exts= "", always = 0, file, this_file, dir, ext; (mode, ) = what_mode(); if (assoc_key_exists(ffap_info, mode)) { exts = ffap_info[mode].ext; path = ffap_info[mode].path; always = ffap_info[mode].always; } % check for URI if ((is_substr(word, "http://")==1) or (is_substr(word, "ftp://")==1)) return(word, 3); (this_file, dir, ,) = getbuf_info(); switch (file_status(dircat(dir, word))) { case 1: return (dircat(dir, word), 1); } % file in buffer-dir or absolute filename { case 2: return(dircat(dir, word), 2); } % dir in buffer-dir or absolute dirname if(path_is_absolute(word)) { path = path_dirname(word); word = path_basename(word); } else { path = add_list_element(path, strtrim_end(dir, "/"), ','); !if (strncmp(word, ".", 1)) % this is to look for dotfile in HOME path = add_list_element(path, getenv("HOME"), ','); } !if (strlen(word)) return ("", -1); % exts = add_list_element(exts, path_extname(this_file), ','); file = search_path_for_file(path, word, ','); % try file 'as is' if (file != NULL) return (file, 1); % found with original extension foreach ext (strchop(exts, ',', 0)) % try with ext { file = search_path_for_file(path, word + ext, ','); if (file != NULL) break; if (path_extname(word) == ext) { if (always > 1) always = 1; break; } } if (file != NULL) return (file, 0); % eventually open a new (empty) file switch (always) { case 1: file = word; } { case 3: file = word + extract_element(exts, 0, ','); } { file = ""; } return (file, -1); } private variable file_line_re=pcre_compile("^(.*?):([0-9]+)(:.*)?$"); %!%+ %\function{ffap} %\synopsis{Find File At Point} %\usage{ffap()} %\description % \sfun{ffap} is meant as an extension of \sfun{find_file}. It checks if % the word at point is a filename, or can be expanded to a filename. It % then prompts for a filename, with the expanded filename if any as default, % and opens the file using the intrinsic \sfun{find_file}, not the internal % one. The difference is that when the user enters a directory, the internal % \sfun{find_file} will expand it to the filename of the working buffer in % the directory entered, with the intrinsic \sfun{find_file} you can set % your own handling of directories in the _jed_find_file_before_hooks. %\seealso{ffap_set_info, Ffap_Prompt_Level, Ffap_URL_Reader, filelist_list_dir} %!%- public define ffap() { variable file, status, word, line = 0; % Simple scheme to separate a path or URL from context % will not work for filenames|URLs with spaces or "strange" characters. word = get_word("-a-zA-z_.0-9~/+:?=&\\"); word = strtrim_end(word, ".+:?"); (file, status) = ffap_find(word); % try whether there is a line number appended: if (andelse {status == -1} {pcre_exec(file_line_re, word)}) { (word, line) = (pcre_nth_substr(file_line_re, word, 1), atoi(pcre_nth_substr(file_line_re, word, 2))); (file, status) = ffap_find(word); } if (status == 3) % URL { if (is_defined(Ffap_URL_Reader)) { if (Ffap_Prompt_Level >= 3) file = read_mini("Find URL:", "", file); runhooks(Ffap_URL_Reader, file); return; } file = ""; status = -1; } if (Ffap_Prompt_Level - status > 0) { if (is_defined("recent_get_files")) { rimini_array=__get_reference("recent_get_files"); } try { file = read_with_completion("Find file:", "", file, 'f'); } finally { rimini_array = NULL; } } () = find_file(file); if (status == 1 and line > 0) goto_line(line); } %}}} provide("ffap"); jedmodes-2.5.7/kp_keydefs/0000755000175400017500000000000010461125576013735 5ustar mildegmjedmodes-2.5.7/kp_keydefs/kp_keydefs.sl0000644000175400017500000000611510262201654016413 0ustar mildegm% kp_keydefs.sl % % Extends keydefs.sl with symbolic keynames for the numeric keypad % Only tested under Linux with PC Keyboard and X-Windows. % % Copyright (c) 2003 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 1.1 2005-07-04 % Define symbolic keynames static define set_keyvar (ibmpc, termcap, default) { #ifdef IBMPC_SYSTEM return ibmpc; #endif #ifdef XWINDOWS return default; #endif #ifexists get_termcap_string variable s = get_termcap_string (termcap); if (s == "") return default; return s; #else return default; #endif } % Numeric Keypad (without Num Lock) variable Key_KP_0 = set_keyvar ("\eOp", "", "\eOp"); variable Key_KP_1 = set_keyvar ("\eOq", "K4", "\eOq"); variable Key_KP_2 = set_keyvar ("\eOr", "", "\eOr"); variable Key_KP_3 = set_keyvar ("\eOs", "K5", "\eOs"); variable Key_KP_4 = set_keyvar ("\eOt", "", "\eOt"); variable Key_KP_5 = set_keyvar ("\eOu", "K2", "\eOu"); variable Key_KP_6 = set_keyvar ("\eOv", "", "\eOv"); variable Key_KP_7 = set_keyvar ("\eOw", "K1", "\eOw"); variable Key_KP_8 = set_keyvar ("\eOx", "K3", "\eOx"); variable Key_KP_9 = set_keyvar ("\eOy", "", "\eOy"); variable Key_KP_Enter = set_keyvar ("\eOM", "", "\eOM"); variable Key_KP_Separator = set_keyvar ("\eOn", "", "\eOn"); variable Key_KP_Add = set_keyvar ("\eOm", "", "\eOm"); variable Key_KP_Subtract = set_keyvar ("\eOS", "", "\eOS"); variable Key_KP_Multiply = set_keyvar ("\eOR", "", "\eOR"); variable Key_KP_Divide = set_keyvar ("/", "", "\eOT"); % TODO: find sensible XWin default values for these variable Key_Shift_Tab = set_keyvar ("^@^O", "bt", "\e[Z"); % reverse_tab variable Key_Shift_BS = set_keyvar ("\x08", "", "\e[16$"); variable Key_Ctrl_Tab = set_keyvar ("^@\d148", "", "\e[009^"); variable Key_Ctrl_BS = set_keyvar ("\e@", "", "\e[16^" ); % We no longer need this static define set_keyvar (); #ifdef XWINDOWS % On X-Windows, for otherwise unindentified keys we can set the keysyms % via x_set_keysysm. % DEL (see also the original .jedrc for this topic) x_set_keysym (0xFFFF, 0, Key_Del); x_set_keysym (0xFFFF, '$', Key_Shift_Del); x_set_keysym (0xFFFF, '^', Key_Ctrl_Del); % Backspace: I just used a "spare" string. is there a sensible default string? x_set_keysym (0xFF08, '$', Key_Shift_BS); x_set_keysym (0xFF08, '^', Key_Ctrl_BS); % TAB: unfortunately, Shift-Tab doesnot send any keystring in my % X-Windows as it is set to ISO_Left_Tab. A line % keycode 23 = Tab % in ~/.Xmodmap cures this problem. Now the following works % x_set_keysym (0xFF09, '$', Key_Shift_Tab); % (reverse tab) x_set_keysym (0xFF09, '^', Key_Ctrl_Tab); % (is there a default?) % Keypad: On Unix, KP +, * , / come through as-is x_set_keysym(0xFFAB, 0, Key_KP_Add); x_set_keysym(0xFFAA, 0, Key_KP_Multiply); x_set_keysym(0xFFAF, 0, Key_KP_Divide); #endif provide ("kp_keydefs"); jedmodes-2.5.7/temabbrv/0000755000175400017500000000000011137571337013414 5ustar mildegmjedmodes-2.5.7/temabbrv/temabbrv_sl.html0000664000175400017500000001620510214064476016604 0ustar mildegm JED Macro: temabbrv.sl

temabbrv.sl

provides a function that takes the word before the cursor and expands it if that word is defined in a template file. It works much like dabbrev. The function can be bound to any key. For example when you type
   if
at end of line and press TAB (and the function temabbrev is bound to that key), the result is
   if (_) {
   }
and it is correctly indented (_ marks the position of the cursor).

JED temabbrv mode

This mode provides a function that takes the word before the cursor and expands it if that word is defined in a template file. It works much like dabbrev. The function can be bound to any key. For example when you type
   if
at end of line and press TAB (and the function temabbrev is bound to that key), the result is
   if (_) {
   }
and it is correctly indented (_ marks the position of the cursor).

In this case the word if was defined in a template file:

@@[if]
if ($_) {
}
@@:I+
where $_ denotes the position of the cursor after expansion.

The same word can have multiple definitions. When you press TAB again, temabbrev searches for the next definition of if and you get:

   if ($_) {
   }
   else
   {
   }

The whole template file looks like this:

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

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

You can also add parameters ($1 - $9 and $_) to macros:

@@[class]
class $1$_
{
private:
protected:
public:
  $1 ();
  ~$1 ();
};
@@:I+,$1 Class name

In this case when you press TAB (at eol after word class), temabbrev displays

class $1$_
{
private:
protected:
public:
  $1 ();
  ~$1 ();
};
and waits for 5 seconds for te user to press '!' or any other key. If the user presses '!', temabbrev asks for the value of each parameter and replaces its tag with its definition. In the former case temabbrev would display (in minibuffer):
$1 Class name:
If the user enters CMyClass, the overall result is:
class CMyClass_
{
private:
protected:
public:
  CMyClass ();
  ~CMyClass ();
};

If the user does not press '!', temabbrev leaves the inserted text as displayed or finds another expansion for class if the user pressed TAB.

Templates

A template is defined with an opening tag (@@[...]) and a closing tag (@@:). Both tags must be at the beginning of line. The opening tag contains the word to be expanded:
@@[if]
The closing tag may contain a comma separated list of flags and prompts for parameter replacement:
@@:I+,$1 Class name

Possible flags:

  • I+ Indent all lines after inserting the expansion
  • I- Do not Indent lines after inserting the expansion (default)

Each prompt for parameter replacement must contain the tag of the parameter to be replaced. An expansion may have up to 9 different parameters with tags $1 - $9:

$1 Class name
means: Read the value of paramater $1 from minibuffer with prompt string "Class name".

You can put arbitrary text between the opening/closing tags. You can use the following 'macros' in the body:

$1 - $9Replace with the value of parameter $N
$_Leave the cursor at this position after expansion
$(varname)Replace with the value of SLang variable or with '?' if the variable is not defined

$(varname) also works for functions without parameters that leave a value on the stack.

Template files

A template file can contain any number of templates. A template file can include another template file with the @@#INCLUDE directive.
@@#INCLUDE cslang.inc

The template file for a certain mode must have the same name as the mode that uses it with all characters in lower-case and with '.tem' suffix. For example in "SLang" mode temabbrev will search for the file named "slang.tem".

An included file can have an arbitrary name.

Locations for template files

By default, template files are stored in a directory named 'template' which is in any directory in get_jed_library_path() or in the Jed home directory (variable Jed_Home_Directory).

You can add more directories with tem_add_template_dir() in your .jedrc.

For example, if the following are the default directories:

   get_jed_library_path():         '/usr/local/jed/lib'
   Jed_Home_Directory:             '~/jed'
and you put this code in .jedrc:
   tem_add_template_dir('~/mytemplates/jed')
the resulting list of directories to search for template files will be:
  '~/mytemplates/jed'
  '~/jed/template'             
  '/usr/local/jed/lib/template'

When temabbrev searches for the mode template file it will stop searching at the first file it finds. The order of direcories to search is:

  1. directories added with tem_add_template_dir(), in reverse order
  2. Jed_Home_Directory
  3. directories from get_jed_library_path()
The same is true for the files that you include with the @@#INCLUDE directive, if the filename does not include any path specifications. You can also include files with realtive and absolute paths and you can also use environment variables to secify the root path. Examples:
@@#INCLUDE cslang.inc
will search all the directories for the first occurence of cslang.inc,
@@#INCLUDE .\cslang.inc
will search for cslang.inc in the directory of the file that includes it,
@@#INCLUDE ~/jed/template/cslang.inc
will search for ~/jed/template/cslang.inc, and
@@#INCLUDE $JED_ROOT/lib/template/slang.tem
will search for /usr/local/jed/lib/template/slang.tem if the environment variable JED_ROOT is '/usr/local/jed'. This way you can put your own templates for SLang in a template file in your home directory, and still use the templates that are defined in /usr/local/jed/lib/template/slang.tem.
jedmodes-2.5.7/temabbrv/temabbrv.sl0000600000175400017500000004112311053207567015545 0ustar mildegm%%----temabbrv.sl-------------------------------------------------------- %% Author: Marko Mahnic %% Version: 0.99 %% %%----------------------------------------------------------------------- %% History: %% 0.99 December 2004 %% * $(variable) inserts the value of a variable %% or "?" if not is_defined(variable) %% 0.98 Jul 2004 %% * Custom variable TEMABBRV_EOL_ONLY %% 0.97 Nov 2003 %% * A list of possible template tags is displayed when the %% word on the left of the cursor is too short. %% * Improved the search for template files (suggested by PB) %% 0.96 Nov 2003 %% * A cleaner implemntation of tem_default_search_path() %% (Paul Boekholt) %% 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 with $_ %% - variable insetion with $(varanme) %% %% 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. %% %% -------------------------------------------------------------------- %% 1. Installation: %% %% Put temabbrv.sl in any directory that is in get_jed_library_path(), %% for example ~/jed/. %% %% In your jed.rc add: %% require ("temabbrv"); %% %% 2. Template files: %% %% Create a directory named 'template' in any directory that is %% in get_jed_library_path(), for example ~/jed/template %% and put your template files in it. %% %% Create the .tem files in /template directory for the modes you desire %% (for SLang you create slang.tem). All filenames are lowercase. %% %% You could also put your template files in an arbitrary directroy %% and call: %% tem_add_template_dir ("~/mytemplates/jed"); %% %% 3. Keybindings: %% %% 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"); %% } %% ---------------------------------------------------------------------------- %% Template example (comments are not part of template): %% %% @@#INCLUDE Something.inc % this will include Something.inc %% %% @@[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); %% temabbrv active on EOL only custom_variable ("TEMABBRV_EOL_ONLY", 1); static variable temLastToken = ""; static variable temExpBegin_point = NULL; static variable temExpEnd_point = NULL; static variable temLoadedModes = ""; static variable loadedfiles_this_mode = ""; static define get_template_buffer(mode) { return sprintf (" *%s*templates*", strlow(mode)); } static define get_token_header_prefix(token) { return "@@["+ token; } static define get_token_header(token) { return "@@["+ token + "]"; } static define extract_token(tokheader) { return strtrim(tokheader, "[]@ \t"); } %% Defalut template search path: JED_HOME and Jed library path static define tem_default_search_path() { variable libpaths = sprintf("%s,%s", Jed_Home_Directory, get_jed_library_path); variable dir, tempaths = ""; foreach(strtok(libpaths, ",")) { dir = dircat("template"); if (2 == file_status(dir)) tempaths = sprintf ("%s,%s", tempaths, dir); } return strtrim_beg(tempaths, ","); } define tem_add_template_dir(dir) { if (TEMABBRV_TEMPLATE_DIRS == NULL) TEMABBRV_TEMPLATE_DIRS = tem_default_search_path(); if (2 == file_status(dir)) TEMABBRV_TEMPLATE_DIRS = sprintf ("%s,%s", dir, TEMABBRV_TEMPLATE_DIRS); } %!%+ %\description % Tries to determine if the file incfile exists. %!%- static define expand_include_file(incfile, fromfile) { variable root, path; incfile = strtrans (incfile, "\\", "/"); root = extract_element(incfile, 0, '/'); if (strncmp (root, "$", 1) == 0) % environment variable; JED_ROOT, JED_HOME, ... { path = getenv(substr(root, 2, -1)); if (path == NULL and root == "$JED_HOME") path = Jed_Home_Directory; (incfile, ) = strreplace(incfile, root, path, 1); } else if (strncmp (root, ".", 1) == 0) % relative to base file { incfile = path_concat(path_dirname(fromfile), incfile); } else if (not is_substr(incfile, "/")) { incfile = search_path_for_file(TEMABBRV_TEMPLATE_DIRS, incfile, ','); } if (incfile == NULL) return NULL; if (1 != file_status (incfile)) return NULL; return (incfile); } static define insert_template_file (); static define insert_template_file (file) { variable incfile; if (is_list_element (loadedfiles_this_mode, file, ',')) return; loadedfiles_this_mode = sprintf("%s,%s", loadedfiles_this_mode, file); if (1 == file_status (file)) { push_mark(); narrow(); %% vinsert("-------- file '%s'\n", file); () = insert_file (file); bob(); %% Include other files while (bol_fsearch ("@@#INCLUDE")) { go_right (10); push_mark(); eol(); incfile = str_delete_chars(bufsubstr(), " \t\n"); incfile = expand_include_file(incfile, file); delete_line(); bol(); if (incfile != NULL) insert_template_file(incfile); bob(); } widen(); } set_buffer_modified_flag (0); eob(); } static define tem_load_mode_template (mode) { variable file; if (is_list_element (temLoadedModes, mode, ',')) return; temLoadedModes = sprintf("%s,%s", temLoadedModes, mode); if (TEMABBRV_TEMPLATE_DIRS == NULL) TEMABBRV_TEMPLATE_DIRS = tem_default_search_path(); file = search_path_for_file(TEMABBRV_TEMPLATE_DIRS, strlow(mode) + ".tem", ','); if (file == NULL) return; loadedfiles_this_mode = ""; setbuf (get_template_buffer(mode)); insert_template_file(file); loadedfiles_this_mode = ""; } #iffalse % Replaced static define tem_load_mode_template (mode) { variable aPaths, file, i, inc; variable temBuf, tmpbuf = "*tmp*"; variable loadedFiles = ""; if (is_list_element (temLoadedModes, mode, ',')) return; temLoadedModes = sprintf ("%s,%s", temLoadedModes, mode); if (TEMABBRV_TEMPLATE_DIRS == NULL) TEMABBRV_TEMPLATE_DIRS = tem_default_search_path(); % ! This includes only the first file found % file = search_path_for_file(TEMABBRV_TEMPLATE_DIRS, % strlow(mode) + ".tem", ','); % if (file == NULL) return; % ! This way I can include all files aPaths = strtok (TEMABBRV_TEMPLATE_DIRS, ","); for (i = 0; i < length(aPaths); i++) { file = dircat(aPaths[i], strlow(mode) + ".tem"); % if (is_list_element(loadedFiles, file, ',')) continue; if (1 == file_status (file)) { % loadedFiles = sprintf("%s,%s", loadedFiles, file); setbuf (tmpbuf); erase_buffer(); () = insert_file (file); bob(); %% Include other files while (bol_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(); % !if (is_list_element(loadedFiles, inc, ',')) { () = insert_file (inc); % loadedFiles = sprintf("%s,%s", loadedFiles, file); } pop_spot(); } set_buffer_modified_flag (0); setbuf (get_template_buffer(mode)); eob(); insert ("\n"); insbuf (tmpbuf); } } if (bufferp (tmpbuf)) delbuf(tmpbuf); } #endif 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_header(token); eol(); if (bol_fsearch (token)) { setbuf (buf); return 1; } bob (); setbuf (buf); return 0; } define tem_find_possible_tokens(prefix) { variable mode, buf, temBuf; variable toklist = ""; (mode,) = what_mode(); mode = strlow (mode); buf = whatbuf (); tem_load_mode_template(mode); temBuf = get_template_buffer(mode); !if (bufferp (temBuf)) { setbuf (buf); return ""; } else setbuf (temBuf); prefix = get_token_header_prefix(prefix); bob(); while (bol_fsearch(prefix)) { if (toklist == "") toklist = extract_token(line_as_string()); else { variable token = extract_token(line_as_string()); variable pos = is_list_element(toklist, token, '|'); !if (pos) toklist = toklist + "|" + token; else { % TODO: count instances of token } } eol(); } bob (); setbuf (buf); return toklist; } static define tem_eval_variables() { bob(); while (fsearch ("$(")) { push_mark(); go_right(2); push_mark(); if ( not ffind(")")) { pop_mark(1); pop_mark(0); } else { variable var = bufsubstr(); variable res; go_right(1); del_region(); ERROR_BLOCK { _clear_error(); } if (not is_defined(var)) insert ("?"); else { res = eval(var); insert(string(res)); } } } } static define tem_expand_parameters(OptArray) { bob(); while (re_fsearch ("\\$[1-9]")) { push_mark (); go_right (2); variable param = bufsubstr(); variable prompt = param, repl = ""; variable i; 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); } } %!%+ %\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 (); tem_eval_variables(); 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) { tem_expand_parameters(OptArray); } %% 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; } public 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 () or (not eolp() and not TEMABBRV_EOL_ONLY)) { 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); } else { variable toklist = tem_find_possible_tokens(temLastToken); if (toklist == "") vmessage ("No completions for '%s'", temLastToken); else vmessage (toklist); } 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"); jedmodes-2.5.7/m_history/0000755000175400017500000000000010651662402013621 5ustar mildegmjedmodes-2.5.7/m_history/hist-cls.sl0000644000175400017500000001700610564571571015724 0ustar mildegm% % A structure that handles a list of recently used strings. % The values are added to the list using different strategies concerning % duplicate entries in the list. % % The code was taken from mini.sl and packed in a structure. This way the code % can be reused for different purposes. % % History: % 2006-03-13: Marko Mahnic % - initial version % 2006-09-21: Marko Mahnic % - added set_values % 2007-02-11: Marko Mahnic % - added is_empty provide("hist-cls"); % The structure/class for history list manipulation. % Members whose names start with an underscore should be considered private. !if (is_defined ("HISTORY_Type")) { typedef struct { % Array of strings _Values, % The oldest line _first_idx, % The future line, should be considered empty on startup _last_idx, % The current line, used for navigation in the history (prev, next) _next_idx, % Currently unused; will be used if _Values will grow dynamically max_length, % if -2, never store duplicates, move Most-Recently-Used to first position % If -1, store only if not equal to last entered value % If 0, never store duplicates strategy, % ------- methods init, % (max_values); Clears the history _do_store_value, % (value); Stores the value store_value, % (value); Stores the value using strategy value_exists, % (value); returns 1 if falue exists in history set_last_value, % (value); Sets the last value, but only when eohp get_current_value, % : value; get_values, % ( &nValues ): array of values; set_values, % ( aValues ); Sets the array of values bohp, % : integer; Nonzero if at beginning of history eohp, % : integer; Nonzero if at end of history is_empty, % : integer; Nonzero if empty next, prev } HISTORY_Type; }; private define mm_hist_init(self, maxvalues) { self.max_length = maxvalues; self._Values = String_Type[maxvalues]; self._Values[[:]] = ""; self._first_idx = 0; self._last_idx = 0; self._next_idx = 0; } % True if at the last (newest) entry in the history. private define mm_hist_eohp(self) { return self._next_idx == self._last_idx; } % True if at the first (oldest) entry in the history. private define mm_hist_bohp(self) { return self._next_idx == self._first_idx; } % Move forward in history, from oldest to newest private define mm_hist_next(self) { if (self.eohp()) return; % error ("End of list!"); variable MX = length(self._Values); self._next_idx = (self._next_idx + 1) mod MX; } % Move backwards in history, from newest to oldest. private define mm_hist_prev(self) { if (self.bohp()) return; % error ("Top of list!"); variable MX = length(self._Values); variable prev = (self._next_idx + MX - 1) mod MX; if (self._last_idx == self._next_idx and prev != self._first_idx) { if (self._Values[prev] == self._Values[self._next_idx]) prev = (prev + MX - 1) mod MX; } self._next_idx = prev; } % Store the nonempty value s to the end of history array. % _last_idx is increased and if it becomes same as _first_idx % then _first_idx is increased. % _next_idx becomes _last_idx and eohp() becomes true. private define mm_hist_do_store_value (self, s) { if ((s == NULL) or (s == Null_String)) return; variable MX = length(self._Values); self._Values[self._last_idx] = s; self._last_idx = (self._last_idx + 1) mod MX; if (self._last_idx == self._first_idx) self._first_idx = (self._first_idx + 1) mod MX; self._next_idx = self._last_idx; self._Values[self._last_idx] = ""; } %% This should usually happen before first call to self.prev %% Works only if at end of history (next_idx = last_idx) private define mm_hist_set_last_value(self, value) { !if (self.eohp()) return; self._Values[self._last_idx] = value; } % Get the value that is currently selected in the history list private define mm_hist_get_current_value(self) { return self._Values[self._next_idx]; } % Returns nonzero when the history is empty. private define mm_hist_is_empty(self) { return self._last_idx == self._first_idx; } % Returns true when value exists in the history array, between _first_idx and % _last_idx - 1. private define mm_hist_value_exists(self, value) { if (self.is_empty()) return 0; variable MX = length(self._Values); variable i = (self._last_idx + MX - 1) mod MX; do { if (value == self._Values[i]) return 1; i = (i + MX - 1) mod MX; } while (i != self._first_idx); return 0; } % Depending on the strategy used, add value to the history array and/or % move the other values accordingly. private define mm_hist_store_value(self, value) { variable MX = length(self._Values); self._next_idx = self._last_idx; switch (self.strategy) { case 0: % never if (length (where (value == self._Values))) value = NULL; } { case -1: % sometimes variable i = (self._next_idx + MX - 1) mod MX; if (self._Values[i] == value) value = NULL; } { case -2: % never, use MRU variable il, delta, la = self._last_idx; if (la < self._first_idx) la = la + MX; delta = 0; il = self._first_idx; while (il < la) { if (self._Values[il mod MX] == value) delta++; if (delta) { if ((il + delta) > la) break; else self._Values[il mod MX] = self._Values[(il + delta) mod MX]; } il++; } if (delta) { self._last_idx = (self._last_idx + MX - delta) mod MX; self._next_idx = self._last_idx; } } self._do_store_value (value); } % Return an array of valid stored values. % If num_p is not NULL, set its value to the maximum length of history entries. private define mm_hist_get_values (self, num_p) { variable MX = length(self._Values); variable n = self._last_idx - self._first_idx; if (num_p != NULL) @num_p = MX; if (n < 0) n += (MX+1); variable values = String_Type [n]; n = self._last_idx - self._first_idx; if (n < 0) { n = MX - self._first_idx; values[[0:n-1]] = self._Values[[self._first_idx:]]; values[[n:]] = self._Values[[0:self._last_idx]]; return values; } return self._Values[[0:n-1]]; } % Set the history array to aValues. % aValues[0] represents the oldest value in the history array. private define mm_hist_set_values (self, aValues) { variable n = length(aValues); variable MX = length(self._Values); if (n >= MX) n = MX-1; self._Values[[0:n-1]] = aValues; self._first_idx = 0; self._last_idx = n; self._next_idx = self._last_idx; } % Create a history list structure/object that will hold at most % maxvalues items. public define New_History_Type(maxvalues) { variable hist = @HISTORY_Type; hist.init = &mm_hist_init; hist.next = &mm_hist_next; hist.prev = &mm_hist_prev; hist._do_store_value = &mm_hist_do_store_value; hist.value_exists = &mm_hist_value_exists; hist.store_value = &mm_hist_store_value; hist.set_last_value = &mm_hist_set_last_value; hist.get_current_value = &mm_hist_get_current_value; hist.get_values = &mm_hist_get_values; hist.set_values = &mm_hist_set_values; hist.eohp = &mm_hist_eohp; hist.bohp = &mm_hist_bohp; hist.is_empty = &mm_hist_is_empty; hist.init(maxvalues); hist.strategy = -2; return hist; } jedmodes-2.5.7/m_history/history.sl0000644000175400017500000001345210574524570015676 0ustar mildegm% % Installation % a) Global % 1. add hist-cls.sl somewhere on your jed library path % 2. replace jed/lib/mini.sl with mini.sl % 3. replace jed/lib/history.sl with this file % b) Local % 1. Create a subdirecory named in the directory of .jedrc % 2. Copy the above mentioned files to % 3. Add the following to .jedrc: % () = evalfile("jedhist/mini.sl"); % autoload("history_load", "jedhist/history"); % % History: % 2000: Created by Rocher, Francesc % 2007: Modified by Marko Mahnic to enable saving multiple histories % 2007-03-10: Paul Boekholt % - bugfix: save_history_at_exit sometimes prevented exiting jed %!%+ %\variable{History_File} %\synopsis{History_File} %\usage{String_Type History_File = "jed.his";} %\description % The variable \var{History_File} is used by the function \var{history_save} % to know the file name in which to store all non-blank lines of the % mini-buffer. Its default value is "~/.jed-history" under Unix and % "~/jed.his" on other platforms. %\seealso{history_load, history_save} %!%- custom_variable ("History_File", #ifdef UNIX expand_filename ("~/.jed-history") #elifdef VMS "sys$login:jed.his" #else expand_filename ("~/jed.his") #endif ); %!%+ %\function{history_load} %\synopsis{history_load} %\usage{Void_Type history_load ();} %\description % This function reads a history file, i.e. each line of the file is % stored in the mini-buffer, but not evaluated. By default, historical % records are kept in a file whose name is stored in the \var{History_file} % variable. This file is written in the current working directory % associated with jed, i.e. the directory from which you started the jed % process. For example, to read your history file every time you start % jed and give an alternative name to the history file, put: %#v+ % variable History_File; % if (BATCH == 0) % { % () = evalfile ("history"); % History_File = ".my-jed-history"; % history_load (); % } %#v- % in your .jedrc (or jed.rc) file. The \var{History_File} variable can be % assigned either a file name or an absolute path+filename. In the first % case, a file will be saved in the current working directory (the one % you were in when you started jed), so you will find a history file in % every directory you work in. In the second one, only one file will be % created, but you can handle 'local' history files easily (see % \var{history_local_save} to know how to do it). %\seealso{history_save, history_local_save, minued_mode} %\seealso{History_File} %!%- define history_load () { variable histfile, fp; % First look at the current working directory histfile = path_concat (getcwd (), path_basename (History_File)); fp = fopen (histfile, "r"); % If this didn't work, try using History_File. if (fp == NULL) { histfile = History_File; fp = fopen (histfile, "r"); } if (fp == NULL) return; mini_load_history(fp); () = fclose(fp); } %!%+ %\function{history_save} %\synopsis{history_save} %\usage{Int_Type history_save ()} %\description % This function saves the contents of the mini-buffer (see \var{history_load} % for more information) to the file specified by the variable \var{History_File} % or to the local history file (see \var{history_local_save} for more % information). It returns -1 upon failure, or 0 upon success. %\notes % When history.sl is loaded, \var{history_save} will automatically get attached % to the editors exit hooks. As a result, it is really not necessary to call % this function directly. %\seealso{history_load, history_local_save} %\seealso{History_File} %!%- define history_save () { variable lines = mini_get_lines (NULL), not_blank; variable fp = NULL, file, st; if (_NARGS) { file = (); fp = fopen (file, "w"); if (fp == NULL) { verror ("Unable to open `%s' for writing.", file); return -1; } } else { file = path_concat (getcwd (), path_basename (History_File)); st = stat_file (file); if (st != NULL) fp = fopen (file, "w"); if (fp == NULL) { file = History_File; fp = fopen (file, "w"); if (fp == NULL) { verror ("Unable to open `%s' for writing.", file); return -1; } } } () = chmod (file, 0600); mini_save_history(fp); () = fclose(fp); return 0; } %!%+ %\function{history_local_save} %\synopsis{history_local_save} %\usage{Void_Type history_local_save ()} %\description % This function saves the contents of the mini-buffer at some arbitrary file. % If you give the same filename as in \var{History_File} but use a different % path, then \var{history_load} will load this file into the mini-buffer every % time you start jed from that (and only from that) directory. This behavior is % only useful when the value of \var{History_File} is an absoulte filename % and you want a local history when you start jed from some specific directory. %\seealso{history_load, history_save} %\seealso{History_File} %!%- define history_local_save () { variable file, st; file = read_with_completion ("Save local history as:", "", path_basename (History_File), 'f'); st = stat_file (file); if (st != NULL) { variable yn = get_y_or_n ("File `" + file + "' already exists, overwrite it"); if (yn <= 0) error ("history_local_save canceled."); } !if (history_save (file)) flush (sprintf ("History saved in '%s'", file)); } private define save_history_at_exit () { try { () = history_save (); } catch AnyError; return 1; } add_to_hook ("_jed_exit_hooks", &save_history_at_exit); jedmodes-2.5.7/m_history/mini.sl0000644000175400017500000001400710565036642015124 0ustar mildegm% % Recall previous commands in MiniBuffer % % Enables different histories for different minibuffer prompts, % for example: % % mini_use_history("filename"); % file = read_file_from_mini("Open:"); % mini_use_history(NULL); % restore default history % % ... % % mini_use_history("search"); % srch = read_mini("Find:", "", ""); % mini_use_history(NULL); % % Installation: % a) Global % 1. add hist-cls.sl somewhere on your jed library path % 2. replace jed/lib/mini.sl with this file % b) Local % 1. Create a subdirecory named in the directory of .jedrc % 2. Copy the above mentioned files to % 3. Add the following to .jedrc: % () = evalfile("jedhist/mini.sl"); % % History: % 2006-09-21: Marko Mahnic % - initial version, based on mini.sl, modified to use HISTORY_Type % 2007-02-11: Marko Mahnic % - mini_load_history and mini_save_history added % % TODO: % The history list could switch automatically based on the current % minibuffer prompt. % % define _minibuffer_prompt_changed_hook(prompt) % { % variable hist; % % The regex/histname pairs could be stored in a list % if (0 <= string_match(prompt, "^M-x", 1)) hist = "slangname"; % else if (0 <= string_match(prompt, "^apropos", 1)) hist = "slangname"; % else if (0 <= string_match(prompt, "^S-Lang>", 1)) hist = "slangexpr"; % else if (0 <= string_match(prompt, "file", 1)) hist = "filename"; % else if (0 <= string_match(prompt, "Save as", 1)) hist = "filename"; % else if (0 <= string_match(prompt, "Search", 1)) hist = "search"; % else if (0 <= string_match(prompt, "Find", 1)) hist = "search"; % else if (0 <= string_match(prompt, "Regexp", 1)) hist = "search"; % ... % else hist = "default"; % mini_use_history(hist); % } % require("hist-cls"); require("keydefs"); % If -2, never store duplicates, use Least-Recently-Used strategy % If -1, store only if not equal to last entered value % If 0, never store duplicates custom_variable ("Mini_Store_Duplicates", -2); % Number of lines for each history table custom_variable ("Mini_Max_History_Lines", 32); private variable history = NULL; private variable aHistory = NULL; public define mini_use_history(histname) { if (Mini_Max_History_Lines < 8) Mini_Max_History_Lines = 8; if (Mini_Max_History_Lines > 64) Mini_Max_History_Lines = 64; if (aHistory == NULL) aHistory = Assoc_Type[HISTORY_Type]; if (histname == NULL) histname = "default"; else { histname = strtrans(histname, "[]", " "); (,) = strreplace(histname, " ", "", strlen(histname)); if (histname == "") histname = "default"; } if (assoc_key_exists(aHistory, histname)) history = aHistory[histname]; else { history = New_History_Type(Mini_Max_History_Lines); history.strategy = Mini_Store_Duplicates; aHistory[histname] = history; } } private define mini_use_this_line () { erase_buffer (); insert (history.get_current_value()); } define next_mini_command () { try history.next(); catch AnyError: return; mini_use_this_line(); } define prev_mini_command () { if (history.eohp()) history.set_last_value(line_as_string ()); try history.prev(); catch AnyError: return; mini_use_this_line (); } public define mini_exit_minibuffer () { bol_skip_white (); !if (eolp ()) { try history.store_value (line_as_string ()); catch AnyError: ; } call ("exit_mini"); } public define mini_store_lines (lines) { history.set_values(lines); } public define mini_set_lines (lines) { history.set_values(lines); } public define mini_get_lines (num_p) { return history.get_values(num_p); } % This function is called from site.sl AFTER jed.rc has been read but % before other command line arguments have been parsed. public define mini_init_minibuffer () { mini_use_history(NULL); variable mini = "Mini_Map"; !if (keymap_p (mini)) make_keymap (mini); definekey ("next_mini_command", Key_Down, mini); definekey ("prev_mini_command", Key_Up, mini); #ifdef IBMPC_SYSTEM definekey ("next_mini_command", "\eOr", mini); definekey ("prev_mini_command", "\eOx", mini); #else definekey ("next_mini_command", "\eOB", mini); definekey ("prev_mini_command", "\eOA", mini); #endif definekey ("mini_exit_minibuffer", "\r", mini); definekey ("exit_mini", "\e\r", mini); definekey ("mini_complete", "\t", mini); definekey ("mini_complete", " ", mini); % Now that we are initialized, remove this function eval (".() mini_init_minibuffer"); } % Save the history to an open text file fp. public define mini_save_history(fp) { variable keys = assoc_get_keys(aHistory); variable lines, k, l, hist, count, not_blank; () = fprintf (fp, "%%%% JED: History generated by 'mini_save_history' on %s\n", time ()); foreach (keys) { k = (); hist = aHistory[k]; () = fprintf (fp, "[%s]\n", k); lines = hist.get_values(&count); not_blank = where (array_map (Integer_Type, &strlen, lines) > 0); foreach (lines [not_blank]) { l = (); () = fprintf (fp, ".%s\n", l); } } () = fprintf (fp, "%%%% JED: History end\n"); } % Load the history from an open text file fp. public define mini_load_history(fp) { variable hist, line, lines, nonblank; % recreate the array of histories aHistory = NULL; mini_use_history(NULL); % TODO: Search for History tag (eg. %% JED: History) hist = NULL; while (fgets(&line, fp) > 0) { if (line[0] == '[') { hist = strtrim(line, "[]\n\r"); if (hist == "") hist = NULL; else mini_use_history(hist); } else if (hist != NULL) { if (line[0] == '.') { line = strtrim(line, "\n\r")[[1:]]; if (line != "") history.store_value(line); } } } % use the default history mini_use_history(NULL); } jedmodes-2.5.7/jedmodes/0000755000175400017500000000000011146322240013367 5ustar mildegmjedmodes-2.5.7/jedmodes/jedmodes.sl0000644000175400017500000002650711146322240015533 0ustar mildegm% jedmodes.sl % Utilities for the publication of modes at Jedmodes % % Keywords: tools % Authors: Günter Milde, Paul Boekholt % % Contains a script for generating a JMR dcdata file from a template, with % some information extracted from your S-Lang source, a function to upload % files with scp and new-mode and new-version wizards. % % Copy the dcdata.txt template to Jed_Home. % You should make a directory structure in your Jed_Home_Directory % that shadows your JMR directories. % % Example illustrating the use with cal.sl: (This is how I, Paul Boekholt % do it) % % Jed-Home % |--mode-index.php % | % `--jedmodes % | % |--cal/ % | |--dcdata.txt % | |--index.php -> ../../mode-index.php % |--bufed/ % | % ... % % The script creates the cal directory, the dcdata.txt, and the index.php % symlink. Simply open cal.sl in JED and type M-x make_dcdata_file. The % dcdata.txt file will pop up, edit it as necessary and save. % % As an example, here is what the generated dcdata file for this script % looks like for me: % % # See also http://jedmodes.sf.net/doc/DC-Metadata/dcmi-terms-for-jedmodes.txt % # Compulsory Terms % title: jedmodes % abstract: Script for creating dcdata % creator: Boekholt, Paul % description: % subject: tools.slang % requires: templates % rights: Copyright (c) 2003 Paul Boekholt % Released under the terms of the GNU General Public License (v. 2 or later) % # Terms with auto-guesses at Jedmodes % ..... % % Notes: % % - though this mode has two authors, only Paul Boekholt is in the % 'creator' field. This is because this field is not guessed from the % slang source - it comes from the get_username() function. % % - neither is the description or the version % % You can use the jedmodes_upload() and jedmodes_new_version() % functions to upload the mode from within JED. % % Or you create the src/mode/cal/ subdirectory and copy cal.sl (or % cal.tgz) there. Repeat the process for any other modes you % wish to create or update. Then leave JED, chdir to Jed_Home and do % % $> tar -czvf modes.tgz `find . -cnewer modes.tgz` % $> scp modes.tgz boekholt@ssh.sf.net://home/groups/j/je/jedmodes/htdocs/mode % $> ssh ssh.sf.net % % sf> cd /home/groups/j/je/jedmodes/htdocs/mode % sf> tar -xzvf modes.tgz. % % sf> exit % % Changes % ------- % % 2004-12-16 Some bugfixes in jedmodes_new_mode() % 2006-05-23 jedmodes_diff: Compare whatbuf() and version in Jedmodes CVS copy % 2007-01-24 removed insert_dcdata(), as it is outdated and never used % 2007-05-14 clean up jedmodes_new_mode(), new fun jedmodes_fetch_dcdata() % commit_mode(): replace placeholder "2009-02-16 with current date provide("jedmodes"); % Requirements % ------------ % modes from % http://jedmodes.sf.net require("templates"); autoload("get_line", "txtutils"); require("ishell"); require("browse_url"); % maybe some more hidden ones... % Variables % --------- % the directory where you shadow your JMR directories. Has to be % called "jedmodes" - leave as is. custom_variable("Jedmodes_Dir", dircat(Jed_Home_Directory, "jedmodes")); custom_variable("Jedmodes_CVS_Root", dircat(Jed_Home_Directory, "jedmodes/src/mode/")); % the line no where you usually write a summary of what the mode does. % In this script, it's on line two. custom_variable("Jedmodes_Abstract_Line_No", 2); % if you use the dabbrev from jedmodes, you may want to set public variable Dabbrev_Default_Buflist=1; % to have dabbrev() expand from all visible buffers % --- Functions --- % scan current buffer for requirements (require() and autoload() calls). define jedmodes_get_requirements() { variable pattern, requirement, requirements = Assoc_Type[Int_Type]; push_spot_bob(); foreach pattern (["^require ?(\"\\([^)]+\\)\");", "^[ \t]*autoload ?(\"[^\"]+\" ?, ?\"\\([^)]+\\)\");"]) { while (re_fsearch(pattern)) { requirement = path_basename(regexp_nth_match(1)); % add requirement, if it is not in the standard library !if (file_status(path_concat( path_concat(JED_ROOT, "lib"), requirement + ".sl"))) % use assoc to throw out doublettes requirements[requirement] = 1; go_right_1(); } bob; } pop_spot(); return strjoin(assoc_get_keys(requirements), "; "); } % simple praragraph formatting logic for dcdata.txt files: % a line with colon marks the start of a new paragraph static define dc_parsep() { bol; ffind_char(':'); } % Assuming the current buffer is a Jed mode, try to open its "dcdata.txt" file public define jedmodes_find_dcdata() { variable mode_dir = path_concat(Jedmodes_Dir, path_sans_extname(whatbuf())); !if(file_status(mode_dir)) mode_dir = path_concat(Jedmodes_Dir, read_mini("Mode Directory", path_sans_extname(whatbuf()), "")); read_file(dircat (mode_dir, "dcdata.txt")); pop2buf("dcdata.txt"); set_buffer_hook("par_sep", &dc_parsep); } % create a dcdata.txt file for the current buffer from template and guesses public define jedmodes_make_dcdata() { variable dcdata_template = expand_template_file("dcdata.txt"); if (file_status(dcdata_template) != 1) dcdata_template = dircat(Jedmodes_Dir, "../doc/mode-template/dcdata.txt"); variable dc_replacements = Assoc_Type[String_Type]; dc_replacements[""] = path_sans_extname(whatbuf()); dc_replacements["<REQUIRES>"] = jedmodes_get_requirements(); dc_replacements["<SUBJECT>"]=""; bob; if (bol_fsearch("% Keywords:")) { ()=ffind(":"); go_right_1; skip_white; push_mark_eol; bufsubstr; ()=strreplace(",",";",100); dc_replacements["<SUBJECT>"]=(); } bob; go_down(Jedmodes_Abstract_Line_No-1); dc_replacements["<ABSTRACT>"] = strtrim(get_line(), "% \t"); variable mode_dir = dircat(Jedmodes_Dir, dc_replacements["<TITLE>"]); mkdir (mode_dir, 0755); % make it world searchable chdir (mode_dir); write_string_to_file("<?php\n" + "// Index file for mode directories, reads mode-index.php with mode argument\n" + "$jedmodes_root = dirname(dirname(dirname(__FILE__)));\n" + "$title = basename(dirname(__FILE__));\n"+ "include(\"$jedmodes_root/mode-index.php\");\n?>\n", "index.php"); % system("ln -s ../../mode-index.php index.php"); % make the file world readable chmod("index.php", 0644); jedmodes_find_dcdata(); if (bobp and eobp()) insert_template_file(dcdata_template); bob; foreach(dc_replacements) using ("keys", "values") replace(); } % upload a file from the private jedmodes mirror to sourceforge public define jedmodes_upload() { variable from = buffer_filename(), to = "milde,jedmodes@web.sf.net:" + path_dirname(from[[is_substr(from, "jedmodes")+8:]]); save_buffer(); ishell(); eob; vinsert("\n\n#upload %s to jedmodes\nscp -p %s %s/\n", path_basename(from), from, to); } % find the path of the current (or given) mode in the CVS working copy define jedmodes_find_cvs_path() % (mode=whatbuf(), mode_dir=path_sans_extname(whatbuf())) { variable mode, mode_dir = path_sans_extname(whatbuf()); (mode, mode_dir) = push_defaults(whatbuf(), mode_dir, _NARGS); return path_concat(path_concat(Jedmodes_CVS_Root, mode_dir), mode); } #ifexists diff % compare the current (or given) file with the version in the CVS copy public define jedmodes_diff() % (mode=whatbuf(), mode_dir=path_sans_extname(whatbuf())) { variable mode, mode_dir = path_sans_extname(whatbuf()); (mode, mode_dir) = push_defaults(whatbuf(), mode_dir, _NARGS); variable path = jedmodes_find_cvs_path(mode, mode_dir); !if (file_status(path) == 1) error("Jedmodes file doesnot exist: " + path); diff(path, buffer_filename()); } #endif % commit a new mode version to the CVS static define commit_mode() { variable file, dir, name, flags; (file, dir, name, flags) = getbuf_info(); variable comment, cvs_dir = path_dirname(jedmodes_find_cvs_path()); !if(file_status(cvs_dir)) cvs_dir = path_concat(Jedmodes_CVS_Root, read_mini("Mode Sources Directory", path_sans_extname(name), "")); !if(file_status(cvs_dir)) { if (get_y_or_n("Create " + cvs_dir) != 1) return; % set the umask to 0, so we can have searchable dirs variable old_umask = umask(0); () = mkdir(cvs_dir, 0755); % world searchable () = umask(old_umask); } % comment out the debug_info bob(); if (bol_fsearch("_debug_info")) comment_line(); bob(); % Replace UNPUBLISHED with current date bob(); if (re_fsearch("UNP[U ].......")) { () = replace_match(get_iso_date()+" ", 1); % Get CVS log entry skip_white(); push_mark(); eol_trim(); comment = bufsubstr(); } else comment = read_mini("CVS Comment:", "", ""); % Copy to the jedmodes mirror save_buffer(); % copy to mode directory (doesnot ask for overwrite) if (-1 == copy_file(buffer_filename(), path_concat(cvs_dir, whatbuf())) ) error("could not copy the mode"); % assure the file is world-readable chmod(path_concat(cvs_dir, whatbuf()), 0644); % prepare the upload via ishell % chdir(cvs_dir); ishell(); eob; insert("\n\n#commit to cvs\n"); push_visible_mark(); % so that the whole new region can be transmitted vinsert("cd %s", path_dirname(cvs_dir)); vinsert("\ncvs commit -m '%s' %s", comment, path_basename(cvs_dir)); go_up_1(); } % upload a new mode version from the personal library (CVS and dcdata.txt) public define jedmodes_new_version() { variable name = whatbuf(); % commit new version to CVS commit_mode(); % update the dcdata file sw2buf(name); jedmodes_find_dcdata(); if (fsearch("date:")) { skip_word(); skip_non_word_chars(); del_eol(); insert_iso_date(); } jedmodes_upload(); pop2buf("dcdata.txt"); } % Add a new mode from the personal library % Best called from the open buffer of the new mode public define jedmodes_new_mode() { % Description file dcdata.txt variable buf = whatbuf(); variable mode_dir = dircat(Jedmodes_Dir, read_mini("Mode Home Directory", path_sans_extname(whatbuf()), "")), to = "milde,jedmodes@web.sf.net:" + (mode_dir[[is_substr(mode_dir, "jedmodes")+8:]]); % create dcdata.txt file in the jedmodes mirror % set the umask to 0, so we can have searchable dirs variable old_umask = umask(0); !if(file_status(mode_dir)) () = mkdir(mode_dir, 0755); % world searchable () = umask(old_umask); jedmodes_make_dcdata(); save_buffer_as(); % assure the file is world-readable chmod(dircat(mode_dir, "dcdata.txt"), 0644); % prepare the dcdata upload via ishell (creating the directory) ishell(); eob; insert("\n\n#upload the mode description\ncd " + mode_dir); vinsert("\nscp -pr %s %s", ".", to); % copy the source to the CVS tree and prepare the commit via ishell sw2buf(buf); % % add mode to CVS and commit commit_mode(); sw2buf("*ishell*"); bol_bsearch("cvs commit"); bol(); vinsert("cvs add %s", path_basename(mode_dir)); vinsert("\ncvs add %s\n", path_concat(path_basename(mode_dir), buf)); sw2buf("dcdata.txt"); } % download 'expanded' dc metadata for a Jedmodes mode from the sf website public define jedmodes_fetch_dcdata() % ([mode]) { !if (_NARGS) read_mini("Fetch metadata for mode:", "", ""); variable mode = (); find_url(sprintf("jedmodes.sf.net/mode-index.php?mode=%s&format=text/plain", mode)); rename_buffer(mode + "-dcdata.txt"); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/COPYING������������������������������������������������������������������������������0000644�0001754�0001750�00000035360�10264411034�012637� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/colors/������������������������������������������������������������������������������0000755�0001754�0001750�00000000000�10461125576�013112� 5����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/colors/light-terminal-default.sl�����������������������������������������������������0000664�0001754�0001750�00000002703�10214064404�020004� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% A color scheme for a terminal with a light background % % Copyright (c) 2003 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % A light color scheme, that doesnot set the background color but uses % the terminals default. Uses only the basic color set, so it should work % with all flavours of jed (tested with jed in rxvt). % % This allows nice colors in a x terminal window with a light background % (e.g. LightYellow). static variable bg = "default"; set_color("normal", "default", bg); set_color("status", "yellow", "blue"); set_color("region", "yellow", "blue"); set_color("operator", "blue", bg); % +, -, etc.. set_color("number", "blue", bg); % 10, 2.71, etc.. set_color("comment", "magenta", bg);% /* comment */ set_color("string", "blue", bg); % "string" or 'char' set_color("keyword", "blue", bg); % if, while, unsigned, ... set_color("keyword1", "red", bg); % malloc, exit, etc... set_color("delimiter", "blue", bg); % {}[](),.;... set_color("preprocess", "green", bg); set_color("message", "blue", bg); set_color("error", "red", bg); set_color("dollar", "red", bg); set_color("...", "red", bg); % folding indicator set_color ("menu_char", "yellow", "blue"); set_color ("menu", "white", "blue"); set_color ("menu_popup", "white", "blue"); set_color ("menu_shadow", "blue", "black"); set_color ("menu_selection", "white", "cyan"); �������������������������������������������������������������jedmodes-2.5.7/colors/yellow.sl���������������������������������������������������������������������0000664�0001754�0001750�00000002773�10214064404�014764� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% Light yellow color scheme for xjed % % Copyright (c) 2003 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % This scheme uses colors only available in xjed, will not work with jed in % a console or X terminal. static variable bg = "LightYellow"; set_color("normal", "black", bg); set_color("status", "yellow", "blue"); set_color("operator", "black", bg); % +, -, etc.. set_color("number", "darkblue", bg); % 10, 2.71, etc.. set_color("comment", "magenta", bg); % /* comment */ set_color("region", "yellow", "blue"); set_color("string", "darkblue", bg); % "string" or 'char' set_color("keyword", "blue", bg); % if, while, unsigned, ... set_color("keyword1", "brightblue",bg); % malloc, exit, etc... set_color("keyword2", "darkblue", bg); set_color("keyword3", "red", bg); set_color("delimiter", "blue", bg); % {}[](),.;... set_color("preprocess", "darkgreen", bg); set_color("message", "blue", bg); set_color("error", "brightred", bg); set_color("dollar", "brightred", bg); set_color("...", "red", bg); % folding indicator set_color ("menu_char", "yellow", "blue"); set_color ("menu", "white", "blue"); set_color ("menu_popup", "white", "blue"); set_color ("menu_shadow", "blue", "black"); set_color ("menu_selection", "white", "darkblue"); set_color ("menu_selection_char","yellow", "darkblue"); %set_color ("mouse", "black", bg); �����jedmodes-2.5.7/colors/white-gm.sl�������������������������������������������������������������������0000664�0001754�0001750�00000002506�10214064404�015164� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% A color scheme for the terminal/console with white background % % Copyright (c) 2003 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % This scheme uses only the basic color set, so it should work with all % flavours of jed (tested with jed in rxvt and Linux console). % static variable bg = "white"; set_color("normal", "black", bg); set_color("status", "yellow", "blue"); set_color("region", "yellow", "blue"); set_color("operator", "blue", bg); % +, -, etc.. set_color("number", "blue", bg); % 10, 2.71, etc.. set_color("comment", "magenta", bg);% /* comment */ set_color("string", "blue", bg); % "string" or 'char' set_color("keyword", "blue", bg); % if, while, unsigned, ... set_color("keyword1", "red", bg); % malloc, exit, etc... set_color("delimiter", "blue", bg); % {}[](),.;... set_color("preprocess", "green", bg); set_color("message", "blue", bg); set_color("error", "red", bg); set_color("dollar", "red", bg); set_color("...", "red", bg); % folding indicator set_color ("menu_char", "yellow", "blue"); set_color ("menu", "white", "blue"); set_color ("menu_popup", "white", "blue"); set_color ("menu_shadow", "blue", "black"); set_color ("menu_selection", "white", "cyan"); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/tokenlist/���������������������������������������������������������������������������0000755�0001754�0001750�00000000000�11034426766�013627� 5����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/tokenlist/tkl-modes.sl���������������������������������������������������������������0000644�0001754�0001750�00000007151�10651112137�016056� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������% tkl-modes.sl: Customization for the list_routines() function % from tokenlist.sl % % Copyright (c) 2006 Marko Mahnic % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 2006-03-29 outsourced from tokenlist.sl % 2006-11-17 G. Milde % removed rst definitions (in rst.sl since version 1.4) % added php definitions % use raw strings for latex definitions % 2006-12-19 Marko Mahnic % changed the interface to use _list_routines_setup % (the old interface still works) % 2007-05-09 Marko Mahnic % renamed list_regex -> list_regexp % fixed PHP and Python setup autoload("tkl_sort_by_value", "tokenlist"); autoload("tkl_sort_by_line", "tokenlist"); provide("tkl-modes"); %% %% C %% private define c_list_routines_extract (nRegexp) { push_spot(); if (ffind_char(';')) { pop_spot(); return Null_String; } pop_spot(); if (nRegexp == 0) { () = ffind_char ('('); % Extract function name bskip_chars (" \t"); () = bfind ("::"); % Skip operator header bskip_chars ("a-zA-Z0-9_:"); push_mark(); eol(); return (bufsubstr()); } else if (nRegexp == 1) { push_mark(); eol(); return (bufsubstr()); } else return (line_as_string()); return Null_String; } define c_list_routines_setup (opt) { opt.list_regexp = { "^[a-zA-Z_][a-zA-Z0-9_]*[ \t*&].*(", % Ordinary function or method "^[a-zA-Z_][a-zA-Z0-9_]*::~.+(" % Destructor }; opt.fn_extract = &c_list_routines_extract; opt.onlistcreated = &tkl_sort_by_value; } %% %% SLang %% % Discard the public|static|private part of the definition private define slang_list_routines_extract (nRegexp) { bol(); % skip static, public if (nRegexp >= 2) { skip_chars ("a-z"); skip_chars (" "); } push_mark(); eol(); return (strtrim(bufsubstr())); } define slang_list_routines_setup(opt) { opt.list_regexp = { "^define[ \t]", "^variable[ \t]", "^public[ \t]+[dv]", "^private[ \t]+[dv]", "^static[ \t]+[dv]" }; opt.fn_extract = &slang_list_routines_extract; opt.onlistcreated = &tkl_sort_by_value; } %% %% HTML %% define html_list_routines_setup(opt) { opt.list_regexp = { "^[ \t]*<H[1-9][ \t>]", "^[ \t]*<TABLE[ \t>]", "^[ \t]*<FORM[ \t>]" }; } %% %% LaTeX %% define latex_list_routines_setup(opt) { opt.list_regexp = { "\\section"R, "\\\(sub\)*section"R, "\\subsubsection"R }; } %% %% PHP %% define php_list_routines_setup(opt) { opt.list_regexp = { "^class[ \t]", "^function[ \t]" }; } %% %% Python %% define python_list_routines_setup(opt) { opt.list_regexp = { "^[ \t]*def[ \t]", "^[ \t]*class[ \t]" }; opt.onlistcreated = &tkl_sort_by_line; } #iffalse %% %% New C %% Might work better for C %% Works worse for C++ %% autoload("c_bskip_over_comment", "cmode"); private define do_c_find_candidate(i) { return bol_fsearch("{"); } variable c_list_routines_regexp = { &do_c_find_candidate }; define c_list_routines_extract (nRegexp) { if (0 != parse_to_point ()) return Null_String; c_bskip_over_comment (1); if (blooking_at (")")) { go_left_1 (); if (1 == find_matching_delimiter (')')) { c_bskip_over_comment (1); bskip_white(); if (bolp()) go_up(1); return line_as_string(); } } return Null_String; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jedmodes-2.5.7/tokenlist/tokenlist_sl.html����������������������������������������������������������0000644�0001754�0001750�00000022550�10651112137�017217� 0����������������������������������������������������������������������������������������������������ustar �milde���������������������������gm���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<html> <head> <title>

Tokenlist installation

First you have to copy tokenlist.sl somewhere on your jed_library_path. Optionally you can also copy tkl-modes.sl if you will use the default settings for some modes (SLang, C, python, PHP, HTML, LaTeX). Insert the content of the INITIALIZATION block (from tokenlist.sl) or just
  require("tokenlist");
into your jed.rc (or .jedrc) file (or use the "make_ini" and "home-lib" modes from jedmodes.sf.net). Optionally add some keybindings, e.g.:
  setkey("list_routines", "^R");
  setkey("occur", "^O");
The function list_routines is very simple in its default implementation and is conditionally useful for C and SLang mode. To extend its capabilities you have to add some macros to search for routines and extract them into the list-buffer. Extensions are provided for more modes in the file tkl-modes.sl which can be loaded in tokenlist_hook() which you define in .jedrc (jed.rc):
  define tokenlist_hook()
  {
     if (expand_jedlib_file("tkl-modes"))
       require("tkl-modes");
  }
If you use require("tokenlist") to load tokenlist.sl then you should put the definition of tokenlist_hook() before require("tokenlist").

You can add more definitions to tkl-modes.sl but it is better to write a separate file like mytklist.sl and change tokenlist_hook() to:

  define tokenlist_hook()
  {
     if (expand_jedlib_file("tkl-modes"))
       require("tkl-modes");
     if (expand_jedlib_file("mytklist"))
       require("mytklist");
  }

Defining your own routine-search

You can write the macros for routine-search directly into .jedrc but it is better to add them to a separate file so they will be loaded only when needed. Here is a minimal example for mytklist.sl:
% ----------- mytklist.sl ------
provide("mytklist");
Let us now define a special X-TEXT mode where the titles on the first level start with '::', on the second with '==' an and on the third level with '--'. In the result list the titles should be indented depending on the level of the title.

For the new mode to work we have to define the function x_text_list_routines_setup(opt) where opt is a structure that defines the behaviour of list_routines. It has the following fields:

FieldDescriptionDefault
mode The name of the mode.  
list_regexp A list of regular expressions to search for. list_routines will take every item from the list and search for all the occurences in the active buffer that match the item (regular expression). After an expression is found, some text is extracted from the buffer with a call to fn_extract.

An item from the list can be a function reference instead of a regular expression. In this case the function will be called by list_routines until it returns 0. The function takes an integer parameter which is the current index and looks like this:

    % Int_Type searc_fn(Int_Type array_index)
    define searc_fn(idx)
    {
       return fsearch("something");
    }
{"^[a-zA-Z].*("};
fn_extract A reference to a (private) function that extracts some text at the current point in the active buffer and returns it as a string. It is called after every match that list_routines finds. The function takes an integer parameter which is the current index and looks like this:
    % String extract_fn(Int_Type array_index)
    define extract_fn(idx)
    {
       return line_as_string();
    }
&_list_routines_extract

The function is defined in tokenlist and returns the current line (line_as_string).

onlistcreated A reference to a (private) function that is called after all the items from list_regexp have been processed. The active buffer is the list of matches and it is narrowed to the matches found in the last buffer.

You can use this hook to sort the matched lines or do any other processing of the buffer. There are two helper functions defined in tokenlist.sl to sort the lines by line number (tkl_sort_by_line) or by content (tkl_sort_by_value).

NULL

Here is the code for the "X-TEXT" mode:

% ----------- mytklist.sl ------
autoload("tkl_sort_by_value", "tokenlist");
autoload("tkl_sort_by_line", "tokenlist");
provide("mytklist");

private define x_text_list_routines_extract(n)
{
  variable chars  = [":", "=", "-"];
  variable prefix = ["", "..", "...."];
  if (n < 3) {
    bol(); 
    skip_chars(chars[n]); 
    push_mark();
    eol();
    return (prefix[n] + strtrim(bufsubstr()));
  }
  return "";
}

define x_text_list_routines_setup(opt)
{
  opt.list_regexp = {
    '^::',
    '^==',
    '^--'
  };
  opt.fn_extract = &x_text_list_routines_extract;
  opt.onlistcreated = &tkl_sort_by_line;
}

If have a buffer TestBufer.xtxt with the content like

::Heading 1
...
==Heading 2
...
--Heading 3
..
==Heading 4
list_routines would generate the following list:
Buffer: TestBufer.xtxt
     3 : Heading 1
    27 : ..Heading 2
    33 : ....Heading 3
    43 : ..Heading 4
You can see that the list is sorted by line number. This is because we set opt.onlistcreated to &tkl_sort_by_line. If we set it to NULL we get the following list:
Buffer: TestBufer.xtxt
     3 : Heading 1
    27 : ..Heading 2
    43 : ..Heading 4
    33 : ....Heading 3
If we wanted to sort the titles by value, we could use tkl_sort_by_value. Unfortunately it would not sort the titles alphabetically because the titles in the buffer are indented.

Mode writers are encouraged to add _list_routines_setup definitions to their modes.

Extending existing modes

Suppose you would like to list all the special blocks like #<INITIALIZATION> in SLang mode. You could change the function slang_list_routines_setup in tkl-modes.sl or copy the contents from tkl-modes.sl to mytklist.sl and change it there. This would be hard to maintain.

That is why another hook was added to tokenlist:

  Void  tokenlist_routine_setup_hook(opt)
This hook is not defiend by default. You can add it to a file like mytklist.sl. In our example we add a new regular expression and modify the extraction function. We store some values from the structure opt for later use.
private variable slang_nregex = NULL;
private variable slang_fn_extract = NULL;
private variable slang_onlistcreated = NULL;

private define my_slang_fn_extract(idx)
{
   if (idx < slang_nregex && slang_fn_extract != NULL)
      return (@slang_fn_extract)(idx);
   else
      return strtrim(line_as_string());
}
  
define tokenlist_routine_setup_hook(opt)
{
   if (opt.mode == "slang")
   {
      slang_nregex = length(opt.list_regexp);
      slang_fn_extract = opt.fn_extract;
      slang_onlistcreated = opt.onlistcreated;
      list_append(opt.list_regexp, "^#\\<[a-zA-Z]");
      opt.fn_extract = &my_slang_fn_extract;
   }
}
my_slang_fn_extract will use the original extraction function for the original regular expressions and extract the current line for the new regular expression.

Imagine that you woud like to sometimes list only functions and at other times only variables. You would define a global variable and prepare the members of the parameter opt according to the value of the variable:

% 0 - all; 1 - variables; 2 - macros
variable slang_routine_mode = 0;

private define my_slang_extract_variable(n)
{
  return(strtrim(line_as_string()));
}

private define my_slang_extract_macro(n)
{
  return(strtrim(line_as_string()));
}

define tokenlist_routine_setup_hook(opt)
{
   if (opt.mode == "slang")
   {
      if (slang_routine_mode == 1)
      {
         opt.list_regexp = { "^variable[ \t]" };
         opt.fn_extract = &my_slang_extract_variable;
      }
      if (slang_routine_mode == 2)
      {
         opt.list_regexp = { "^define[ \t]" };
         opt.fn_extract = &my_slang_extract_macro;
      }
   }
}

Future

The structure opt could have more members so tokenlist could be made extremely configurable:
  • what to do when user presses Enter (replacing tkl_goto_token)
  • what to do when user presses Space (replacing tkl_display_token)
  • what other keybindings do we want in the list
  • what to do when the current line is changed in the list (extending the tkl_update_token_hook)
  • ...
jedmodes-2.5.7/tokenlist/tokenlist.sl0000644000175400017500000005506310741700256016205 0ustar mildegm% -*- mode:SLang; mode:fold; -*- % % file: tokenlist.sl v1.10 % Author: Marko Mahnic % % Copyright (c) 2006 Marko Mahnic % Released under the terms of the GNU General Public License (ver. 2 or later) %% INSTALLATION %% %% Put on your jed_library_path. %% %% Insert the content of the INITIALIZATION block (see below) or just %% require("tokenlist"); % evaluate at startup %% into your jed.rc (or .jedrc) file. %% (or use the "make_ini" and "home-lib" modes from jedmodes.sf.net) %% %% Optionally add some keybindings, e.g.: %% setkey("list_routines", "^R"); %% setkey("occur", "^O"); %% %% USAGE %% %% Use your keybindings, M-x occure or M-x list_routines, or the Search %% menu entries to open a tokenlist buffer with search results. %% %% Keybindings in the tokenlist buffer: %% %% d, SPACE: display selected line in other buffer %% g, RETURN: goto selected line, close token list %% /, s: isearch_forward %% :, f: filter the displayed results (hides nonmatching lines) %% q: hide results %% w: other window %% %% CUSTOMIZATION %% %% Custom Variables: %% TokenList_Startup_Mode -- Initial mode of the tokenlist %% 0 - normal mode %% 1 - start in isearch mode %% 2 - start in filter mode %% %% Hooks: %% tokenlist_hook() -- called after this file is evaluated. %% %% The default is defined in the INITALIZATION block. It loads %% mode definitions for list_routines() from tkl-modes.sl. %% %% Users of make_ini (e.g. via the jed-extra Debian package) can %% also overwrite the tokenlist_hook in their jed.rc file, e.g. %% %% define tokenlist_hook() %% { %% % load prepared definitions %% require("tkl-modes"); %% % overwrite some definitons with custom version %% eval("define slang_list_routines_extract(nRegexp)" %% + "{ return line_as_string(); }"); %% eval("define slang_list_routines_done()" %% + "{ tkl_sort_by_line; }"); %% % customize keybindings %% definekey ("tkl_quit", "^W", "tokenlist"); %% } %% %% EXTENSION %% %% A set of mode definitions for list_routines is defined in the file %% tkl-modes.sl. They are loaded by the default tokenlist_hook(). %% %% To use list_routines in a new mode MODENAME, define a function %% %% Void MODENAME_list_routines_setup(Tokenlist_Operation_Type opt) %% %% and fill the fields of the structure opt: %% %% opt.list_regexp = {"regexp0", "regexp1", &search_fn}; %% A set of regular expressions or references to function like: %% %% % Int_Type searc_fn(Int_Type array_index) %% % returns 0 when no more matches %% define searc_fn(idx) %% { %% return fsearch("something"); %% } %% %% opt.fn_extract = &MODENAME_list_routines_extract; %% A reference to a (private) function like: %% %% String MODENAME_list_routines_extract (Integer I) %% Extractor function to extract the match from the currnet %% buffer. I is the index of the regexp in the array. %% When the function is called the point in the buffer %% is at the current match. When the function returns %% the point should be restored. %% Optional. If it is not defined, the default %% _list_routines_extract extracts the whole current line. %% %% opt.onlistcreated = &MODENAME_list_routines_done; %% A reference to a (private) function like: %% %% Void MODENAME_list_routines_done (Void) %% When this hook is called, the buffer with %% the extracted lines is the current buffer. %% You can use tkl_sort_by_value or tkl_sort_by_line %% instead of a custom function. %% Optional. Default is NULL. %% %% These definitions can be done in %% jed.rc, %% (a private copy of) tkl-modes.sl, %% a second mode-definition file (modify tokenlist_hook() to require it), %% or by modifying the tokenlist_hook(), using eval() as you normally %% cannot define functions or global variables in a function. %% %% CHANGES: %% 2000: Marko Mahnic %% First version %% 2006-03-08: Marko Mahnic %% - added isearch and filter commands %% - documented %% - _list_routines_regexp can also be a list %% and it may contain references to functions %% - TokenList_Startup_Mode custom variable %% - keybindings slightly changed %% 2006-03-10: Guenter Milde, Marko Mahnic %% - prepared for make_ini() %% 2006-03-13: Marko Mahnic %% - filter command is now interactive %% 2006-03-29: Marko Mahnic %% - tokenlist_routine_setup_hook %% - Tokenlist_Operation_Type structure %% - definitions moved to tkl-modes.sl %% - HTML documentation added %% 2006-03-30 Marko Mahnic %% - tokenlist menu %% - moccur; prepared for mlist_routines %% - simple syntax coloring %% 2006-11-17 Guenter Milde %% - hook for delayed and customizable loading of tkl-modes.sl %% - INITIALIZATION section (for make_ini() or manual copy to .jedrc) %% - tm documentation for TokenList_Startup_Mode %% 2006-12-19 Marko Mahnic %% - changed the interface to use _list_routines_setup %% (the old interface still works) %% 2007-04-18 G. Milde %% - bugfix in tkl_list_tokens() preventing an infinite loop if there is a %% match on the last line of a buffer %% 2007-05-09 Marko Mahnic %% - renamed list_regex -> list_regexp %% - removed the old list_routines interface. Use _list_routines_setup. %% - added "construcotr" New_Tokenlist_Operation_Type %% 2007-10-01 G. Milde %% - autoload popup_buffer() if bufutils.sl present %% 2007-10-18 G. M. %% - help text for public functions, fix optional use of popup_buffer() %% 2008-01-11 G. M. %% - popup_buffer() was used in the wrong place: put it in tkl_display_results() # autoload("list_routines", "tokenlist"); autoload("occur", "tokenlist"); autoload("moccur", "tokenlist"); add_completion("list_routines"); % Add menu entry define tokenlist_load_popup_hook(menubar) { menu_insert_item("Se&t Bookmark", "Global.&Search", "&List Routines", "list_routines"); } append_to_hook("load_popup_hooks", &tokenlist_load_popup_hook); % default hook to add prepared mode definitions for list_routines: define tokenlist_hook() { if (expand_jedlib_file("tkl-modes") != "") require("tkl-modes"); } # %!%+ %\variable{TokenList_Startup_Mode} %\synopsis{Initial mode of the tokenlist} %\usage{variable TokenList_Startup_Mode = 0} %\description % Controls what happens right after the list is displayed: % 0 - normal mode % 1 - start in isearch mode % 2 - start in filter mode %\seealso{occur, moccur, list_routines} %!%- custom_variable ("TokenList_Startup_Mode", 0); % Recommendations % --------------- #if (expand_jedlib_file("bufutils.sl") != "") autoload("popup_buffer", "bufutils"); % dummy autoload for byte-compiling #if (autoload("popup_buffer", "bufutils"), 1) #endif #endif private variable tkl_TokenBuffer = "*TokenList*"; private variable tkl_ExtractMacro = "_list_routines_extract"; private variable tkl_DoneMacro = "_list_routines_done"; private variable tkl_SetupMacro = "_list_routines_setup"; private variable tkl_mode = "tokenlist"; private variable tkl_BufferMark = "[Buffer]:"; %% Default extraction routine define _list_routines_extract (nRegexp) { return line_as_string(); } !if (is_defined("Tokenlist_Operation_Type")) %{{{ { typedef struct { mode, % mode identifier list_regexp, % list of regex / search function pointers fn_extract, % a function to extract what was found onlistcreated % a function that is run when the list is created } Tokenlist_Operation_Type; } define New_Tokenlist_Operation_Type() { variable tkopt = @Tokenlist_Operation_Type; tkopt.mode = NULL; tkopt.list_regexp = NULL; tkopt.fn_extract = NULL; tkopt.onlistcreated = NULL; return tkopt; } %}}} %% Function: tkl_list_tokens %% \usage{Void tkl_list_tokens (String[] arr_regexp, String fn_extract)} %% Parameters: %% arr_regexp: a string or an array of strings representing regular expression(s) %% to search for %% fn_extract: a string with the name of a function which takes one integer parameter %% and returns a string (usually the extracted line). %% %% tkl_list_tokens searches for a set of regular expressions defined %% by an array of strings arr_regexp. For every match tkl_list_tokens %% calls the function defined in the string fn_extract with an integer %% parameter that is the index of the matched regexp. At the time of the %% call, the point is at the beginning of the match. %% %% The called function should return a string that it extracts from %% the current line. %% define tkl_list_tokens (opt) %{{{ { variable buf = whatbuf(), line, token; variable found = 0; if (List_Type != typeof(opt.list_regexp) and Array_Type != typeof(opt.list_regexp)) opt.list_regexp = { opt.list_regexp }; if (opt.fn_extract == NULL) opt.fn_extract = &_list_routines_extract; variable i, rv, rtype, extype; extype = typeof(opt.fn_extract); if (extype != Ref_Type and extype != String_Type) return; if (extype == String_Type) if (opt.fn_extract == Null_String) { extype = Ref_Type; opt.fn_extract = &_list_routines_extract; } setbuf (tkl_TokenBuffer); set_readonly (0); setbuf (buf); push_spot(); for (i = 0; i < length(opt.list_regexp); i++) { % The array may be larger than the number of needed regular expressions. % We can end the search with a Null_String or NULL. if (opt.list_regexp[i] == NULL) break; rtype = typeof(opt.list_regexp[i]); if (rtype != Ref_Type and rtype != String_Type) continue; if (rtype == String_Type) if (opt.list_regexp[i] == Null_String) break; bob(); do { bol(); if (rtype == Ref_Type) rv = (@opt.list_regexp[i])(i); else rv = re_fsearch (opt.list_regexp[i]); if (not rv) break; push_spot(); if (extype == Ref_Type) (@opt.fn_extract)(i); else eval (sprintf ("%s(%ld)", opt.fn_extract, i)); token = (); pop_spot(); while (str_replace(token, "\n", " ")) token = (); if (strtrim(token) != Null_String) { line = what_line(); setbuf (tkl_TokenBuffer); if ( not found) { found = 1; vinsert ("%s %s\n", tkl_BufferMark, buf); } vinsert ("%7d: %s\n", line, token); setbuf (buf); } } while (down(1)); } pop_spot(); setbuf (tkl_TokenBuffer); if (opt.onlistcreated != NULL) { try call_function(opt.onlistcreated); catch AnyError:; } bob (); set_buffer_modified_flag (0); set_readonly (1); setbuf (buf); } %}}} %% ####################################################################### %% ##################### DISPLAY OF RESULTS ############################# %% ####################################################################### %{{{ !if (keymap_p (tkl_mode)) { make_keymap (tkl_mode); definekey ("tkl_display_token", " ", tkl_mode); definekey ("tkl_display_token", "d", tkl_mode); definekey ("tkl_goto_token", "\r", tkl_mode); definekey ("tkl_goto_token", "g", tkl_mode); definekey ("isearch_forward", "s", tkl_mode); definekey ("isearch_forward", "/", tkl_mode); definekey ("tkl_filter_list", "f", tkl_mode); definekey ("tkl_filter_list", ":", tkl_mode); definekey ("tkl_quit", "q", tkl_mode); definekey ("other_window", "w", tkl_mode); } create_syntax_table(tkl_mode); define_syntax(tkl_BufferMark, "", '%', tkl_mode); private define tkl_menu(menu) { menu_append_item (menu, "&Display", "tkl_display_token"); menu_append_item (menu, "&Go To", "tkl_goto_token"); menu_append_item (menu, "Incremental &search", "isearch_forward"); menu_append_item (menu, "&Filter buffer", "tkl_filter_list"); menu_append_item (menu, "Other &window", "other_window"); menu_append_item (menu, "&Quit", "tkl_quit"); } private define tkl_erase_buffer() { variable buf = whatbuf(); setbuf (tkl_TokenBuffer); set_readonly (0); erase_buffer (); set_readonly (1); setbuf(buf); } % \usage{(String, Int) tkl_get_token_info()} private define tkl_get_token_info() { variable line, buf; setbuf (tkl_TokenBuffer); push_spot(); if (not bol_bsearch(tkl_BufferMark)) bob(); () = ffind_char (':'); go_right (2); push_mark(); eol (); buf = bufsubstr(); pop_spot(); bol (); if (re_looking_at (" *[0-9]*:")) { push_mark(); () = ffind_char (':'); line = integer (bufsubstr()); } else { setbuf (buf); line = what_line(); setbuf (tkl_TokenBuffer); beep (); } return (buf, line); } define tkl_filter_list() { variable c, curflt, flt = ""; push_spot(); bob(); while (down_1) set_line_hidden(0); pop_spot(); message("Filter buffer (Esc to exit):"); while(input_pending(0)) () = getkey(); update_sans_update_hook (0); forever { c = getkey(); curflt = flt; switch(c) { case 0x08 or case 0x7F: if (flt != "") flt = substr(flt, 1, strlen(flt)-1); } { case '\e': if (input_pending (3)) ungetkey (c); break; } #ifdef IBMPC_SYSTEM { case 0xE0: if (input_pending (3)) { ungetkey(c); break; } } #endif { c < 32 and c >= 0: ungetkey (c); break; } { flt += char(c); } vmessage("Filter buffer (Esc to exit): %s", flt); if (curflt != flt) { push_spot(); bob(); if (flt == "") { while (down_1) set_line_hidden(0); } else { while (down_1) { bol(); if (looking_at(tkl_BufferMark)) continue; else if (ffind(flt)) set_line_hidden(0); else set_line_hidden(1); if (input_pending(0)) break; } } pop_spot(); try if (is_line_hidden()) call("previous_line_cmd"); catch AnyError: ; try if (what_line() <= 1) call("next_line_cmd"); catch AnyError: ; update(0); } } message(""); } private define tkl_make_line_visible() { if (is_line_hidden()) { if (2 == is_defined("fold_open_fold")) { try { variable n = 5; % foldnig depth do { push_spot(); eval("fold_open_fold"); pop_spot(); n--; } while (n > 0 and is_line_hidden()); if (is_line_hidden()) { if (2 == is_defined("fold_open_buffer")) eval("fold_open_buffer"); } } catch AnyError: { } } else set_line_hidden(0); } } % \usage{Void tkl_display_token()} define tkl_display_token() { variable line, buf; (buf, line) = tkl_get_token_info(); pop2buf (buf); goto_line (line); tkl_make_line_visible(); pop2buf (tkl_TokenBuffer); } % \usage{Void tkl_goto_token()} define tkl_goto_token() { variable line, buf; (buf, line) = tkl_get_token_info(); onewindow(); sw2buf (buf); goto_line (line); tkl_make_line_visible(); } define tkl_quit() { otherwindow(); onewindow(); } private variable Line_Mark; % \usage{Void tkl_update_token_hook ()} private define tkl_update_token_hook () { Line_Mark = create_line_mark (color_number ("menu_selection")); } % \usage{Void tkl_two_windows (Int bottom_size)} %% Splits the screen into two windows with the bottom one having %% bottom_size lines. %% Bottom window becomes current. private define tkl_two_windows (bottom_size) { if (bottom_size < 0) bottom_size = 0; if (bottom_size > SCREEN_HEIGHT) bottom_size = SCREEN_HEIGHT; onewindow(); splitwindow(); variable scrtop = window_info ('t'); if (scrtop < 3) otherwindow(); %% we are in the bottom window variable cursize = window_info ('r'); variable nenlarge = bottom_size - cursize; if (nenlarge >= 0) { loop (nenlarge) enlargewin(); } else { otherwindow(); loop (-nenlarge) enlargewin(); otherwindow(); } } define tkl_display_results() { Line_Mark = NULL; #ifexists popup_buffer popup_buffer(tkl_TokenBuffer); #else tkl_two_windows (SCREEN_HEIGHT / 2); sw2buf (tkl_TokenBuffer); #endif set_mode(tkl_mode, 0); set_buffer_hook ("update_hook", &tkl_update_token_hook); mode_set_mode_info (tkl_mode, "init_mode_menu", &tkl_menu); use_keymap (tkl_mode); use_syntax_table(tkl_mode); switch (TokenList_Startup_Mode) { case 0: return; } { case 1: isearch_forward(); } { case 2: tkl_filter_list(); } } define tkl_sort_by_value () { !if (bufferp(tkl_TokenBuffer)) return; variable buf = whatbuf(); setbuf (tkl_TokenBuffer); set_readonly (0); push_spot(); eob(); if (re_bsearch ("^ *[0-9]*:")) { () = ffind_char (':'); push_mark(); bob (); go_down (1); eol(); if (what_column() < 60) insert_spaces (60 - what_column()); sort (); } pop_spot(); set_buffer_modified_flag (0); set_readonly (1); setbuf(buf); } define tkl_sort_by_line () { !if (bufferp(tkl_TokenBuffer)) return; variable buf = whatbuf(); setbuf (tkl_TokenBuffer); set_readonly (0); push_spot(); bob(); go_down(1); push_mark(); eob(); if (bolp()) go_up(1); eol(); sort(); pop_spot(); set_buffer_modified_flag (0); set_readonly (1); setbuf(buf); } %}}} %% ####################################################################### %% ############## override the default occur ############################ %% ####################################################################### #iftrue %% Function: occur %% \usage{Void occur ([regexp])} %% Search for a regexp in current buffer. %% %% If the parameter regexp is not supplied the value can %% be entered interactively. %% %% tokenlist_occur_setup_hook(tkopt) is called before the search %% is started so the user has a chance to modify the search %% parameters and display. tkopt.mode is set to "@occur". public define occur () { variable tkopt = New_Tokenlist_Operation_Type(); if (_NARGS == 0) tkopt.list_regexp = read_mini("Find All (Regexp):", LAST_SEARCH, Null_String); else tkopt.list_regexp = (); tkopt.mode = "@occur"; runhooks("tokenlist_occur_setup_hook", tkopt); tkl_erase_buffer(); tkl_list_tokens(tkopt); tkl_display_results(); } %!%+ %\function{moccur} %\synopsis{Search for a regexp in all loaded buffers.} %\usage{Void moccur ([regexp])} %\description % Search for \var{regexp} in all loaded buffers and display all hits % in a *Tokenlist* buffer. % % Does not search in internal and temporary buffers. % % If the parameter regexp is not supplied the value can % be entered interactively. %\notes % tokenlist_occur_setup_hook(tkopt) is called before the search % is started so the user has a chance to modify the search % parameters and display. tkopt.mode is set to "@moccur". %\seealso{occur, list_routines, TokenList_Startup_Mode} %!%- public define moccur () { variable buf; variable tkopt = New_Tokenlist_Operation_Type(); if (_NARGS == 0) tkopt.list_regexp = read_mini("Find All (Regexp):", LAST_SEARCH, Null_String); else tkopt.list_regexp = (); tkopt.mode = "@moccur"; runhooks("tokenlist_occur_setup_hook", tkopt); tkl_erase_buffer(); loop(buffer_list()) { buf = (); if (buf == tkl_TokenBuffer) continue; if (is_substr("* ", buf[[0]])) continue; setbuf(buf); tkl_list_tokens(tkopt); } tkl_display_results(); } #endif %% ####################################################################### %% ##################### LIST ROUTINES ################################## %% ####################################################################### %!%+ %\function{list_routines} %\synopsis{List routines defined in the current buffer} %\usage{Void list_routines()} %\description % Perform a regexp search depending on the current mode and list % 'tokens' or 'routine definitions' in a *TokenList* buffer. % % A typical use is to list function, variable, and class definitions in % a source code file. But, e.g., section headers in reStructuredText % or another markup language can be found too. % % Keybindings in the tokenlist buffer: % % d, SPACE: display selected line in other buffer % g, RETURN: goto selected line, close token list % /, s: isearch_forward % :, f: filter the displayed results (hides nonmatching lines) % q: hide results % w: other window %\notes % For configuration, see the documentation in tokenlist.sl %\seealso{occur, moccur, TokenList_Startup_Mode} %!%- public define list_routines() { variable buf, mode, fn; variable tkopt = New_Tokenlist_Operation_Type(); (mode,) = what_mode(); mode = strlow(mode); tkopt.mode = strtrans(mode, "-", "_"); tkopt.list_regexp = {"^[a-zA-Z].*("}; tkopt.fn_extract = &_list_routines_extract; fn = sprintf ("%s%s", tkopt.mode, tkl_SetupMacro); if (+2 == is_defined (fn)) call_function (fn, tkopt); #iffalse else { % the old interface if (-2 == is_defined (sprintf ("%s_list_routines_regexp", tkopt.mode))) { eval (sprintf ("%s_list_routines_regexp;", tkopt.mode)); tkopt.list_regexp = (); } fn = sprintf ("%s%s", tkopt.mode, tkl_ExtractMacro); if (+2 == is_defined (fn)) tkopt.fn_extract = __get_reference(fn); fn = sprintf ("%s%s", tkopt.mode, tkl_DoneMacro); if (+2 == is_defined (fn)) tkopt.onlistcreated = __get_reference(fn); } #endif % Setup routine for current mode, % give the user a chance to modify default behaviour. runhooks("tokenlist_routine_setup_hook", tkopt); tkl_erase_buffer(); tkl_list_tokens (tkopt); tkl_display_results(); } %% Run the tokenlist_hook hook %% (for delayed and customizable loading of tkl-modes.sl) runhooks("tokenlist_hook"); jedmodes-2.5.7/README0000600000175400017500000000373711130357256012467 0ustar mildegmJedmodes README =============== This are the source files of the CVS repository of the Jed Modes Repository, a collection of S-Lang scripts (modes) contributed by Jed users. Some of the modes are experimental (while others work stable for their authors for ages), so **USE AT YOUR OWN RISK**. Copyright --------- The modes at Jedmodes are `free software`__. If not stated otherwise in the individual file, all modes at Jedmodes are copyrighted by their respective creator and released under the *GNU General Public License* (`GPL`_) __ http://www.gnu.org/philosophy/free-sw.html No Warranty ----------- The modes are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the `GPL`_ for more details. .. _GPL: http://www.gnu.org/copyleft/gpl.html Usage ----- * Place the files you want to use in the search path for jed library files (cf. Help>Describe_Function get_jed_library_path) * See the individual modes for detailled usage instructions. The `libdir`_ and `make_ini`_ modes provide an jed extension framework. * The functions ``add_libdir(dir, initialize=1)`` and ``append_libdir(dir, initialize=1)`` register a library dir for use by Jed * Prepend|Append ``path`` to the library path * Set ``Color_Scheme_Path``, ``Jed_Doc_Files``, and ``Jed_Highlight_Cache_Path`` * Evaluate (if existent) the file ``ini.sl`` in this directory to enable initialization (autoloads etc.). This is customizable by the optional second argument. * The functions in `make_ini`_ can be used to create such an ini.sl file. They can also preparse SLang files and create dfa syntax tables. .. _libdir: http://jedmodes.sourceforge.net/mode/libdir/ .. _make_ini: http://jedmodes.sourceforge.net/mode/make_ini/ Contact ------- Mail hints, bug reports, praise and ideas to jed-users@jedsoft.org or direcly to the mode's authors. Günter Milde last change 2009-01-05 jedmodes-2.5.7/newsflash/0000755000175400017500000000000011130344607013573 5ustar mildegmjedmodes-2.5.7/newsflash/newsflash.sl0000644000175400017500000003637011130344607016136 0ustar mildegm% newsflash.sl % % $Id: newsflash.sl,v 1.8 2008/12/16 18:52:09 paul Exp paul $ % % Copyright (c) 2006-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This is a RSS+Atom reader for JED. It uses the expat module. % Expat outputs UTF-8, so this works best in UTF-8 mode. require("curl"); require("expat"); require("pcre"); require("sqlite"); require("strutils"); require("view"); autoload("jedscape_get_url", "jedscape"); autoload("browse_url", "browse_url"); provide("newsflash"); implements("newsflash"); variable mode = "newsflash"; private variable uri_re=NULL; private define uri_parse(url) { if (uri_re == NULL) uri_re = pcre_compile("http://([^/]+)/(.*)"); if (pcre_exec(uri_re, url)) { return struct { host = pcre_nth_substr(uri_re, url, 1), path = pcre_nth_substr(uri_re, url, 2)}; } return NULL; } variable item_struct = struct { title, link, description, date, is_read, line }; variable userdata = struct { is_atom, % will be an item_struct channel, % not used base, % base URI for atom feeds url, cleanlevel, % reference to characterdata element being read cdataref, % s item, items, % parser state state, states, % reader-specific data buffer, lines, itemhandler, is_read }; variable debug_mode=0; %{{{ database variable db, dbfile = dircat(Jed_Home_Directory, "rss.db"); $1 = file_status(dbfile); db = sqlite_open(dbfile); ifnot ($1) { % Some fields (e.g. description and date in the items table) are currently not used sqlite_exec(db, "CREATE TABLE feeds (feed_id INTEGER PRIMARY KEY, name TEXT UNIQUE, url TEXT UNIQUE, cleanlevel INTEGER default '3')"); sqlite_exec(db, "CREATE TABLE items (item_id INTEGER PRIMARY KEY, feed TEXT, title TEXT, link TEXT, description TEXT, is_read INTEGER default 0, date INTEGER, UNIQUE (feed, title, link))"); foreach $2 ({ {"BBC world news", "http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/world/rss.xml"}, {"Cadenhead", "http://www.cadenhead.org/workbench/rss"}, {"CNET News.com", "http://export.cnet.com/export/feeds/news/rss/1,11176,,00.xml"}, {"Debian Security Advisories", "http://www.debian.org/security/dsa.en.rdf"}, {"Debian Security Advisories - Long format", "http://www.debian.org/security/dsa-long.en.rdf"}, {"Debian Jed Group", "http://alioth.debian.org/export/rss20_news.php?group_id=30638"}, {"Freshmeat.net", "http://freshmeat.net/backend/fm.rdf"}, {"JED checkins", "http://cia.navi.cx/stats/project/jed/.rss?ver=2&medium=unquoted"}, {"JMR file releases", "http://sourceforge.net/export/rss2_projfiles.php?group_id=14968"}, {"Joel on Software", "http://www.joelonsoftware.com/rss.xml"}, {"Kuro5hin.org", "http://www.kuro5hin.org/backend.rdf"}, {"LWN (Linux Weekly News)", "http://lwn.net/headlines/rss"}, {"Motley fool", "http://www.fool.com/xml/foolnews_rss091.xml"}, {"NewsForge", "http://newsforge.com/index.rss"}, {"NY Times: Technology", "http://partners.userland.com/nytRss/technology.xml"}, {"NY Times", "http://partners.userland.com/nytRss/nytHomepage.xml"}, {"Quote of the day", "http://www.quotationspage.com/data/qotd.rss"}, {"The Register", "http://www.theregister.co.uk/tonys/slashdot.rdf"}, {"Slashdot", "http://slashdot.org/index.rss"}, {"Tweakers.net (Dutch)", "http://tweakers.net/feeds/mixed.xml"}, {"Wired News", "http://www.wired.com/news_drop/netcenter/netcenter.rdf"}, {"xml.com (rss 1.0)", "http://www.oreillynet.com/pub/feed/20?format=rss1"}, {"xml.com (rss 2.0)", "http://www.oreillynet.com/pub/feed/20?format=rss2"}, {"xml.com (Atom)", "http://www.oreillynet.com/pub/feed/20"} }) sqlite_exec(db, "INSERT OR IGNORE INTO feeds ('name', 'url') VALUES (?, ?)", $2[0], $2[1]); sqlite_exec(db, "UPDATE feeds SET cleanlevel=0 WHERE name='JED checkins'"); } sqlite_exec(db, "PRAGMA synchronous = OFF;"); %}}} %{{{ rss parser define push_state(p, s) { list_insert(p.userdata.states, s); p.userdata.state = s; } define pop_state(p) { ()=list_pop(p.userdata.states); if (length(p.userdata.states)) p.userdata.state = p.userdata.states[0]; else p.userdata.state = ""; } define read_characterdata(p, s) { if (p.userdata.cdataref != NULL) @p.userdata.cdataref += s; } define startElement(p, name, atts) { variable att; if (name == "item" || name == "entry") { p.userdata.item = @item_struct; p.userdata.item.title = ""; p.userdata.item.link = ""; p.userdata.item.description = ""; p.userdata.item.is_read = 0; p.userdata.item.date = ""; } else if (name == "channel" || name == "feed") { if (name == "feed") { p.userdata.is_atom = 1; foreach att (atts) { if (att.name=="xml:base") { p.userdata.base = uri_parse(att.value); break; } } } else p.userdata.is_atom = 0; p.userdata.channel = @item_struct; p.userdata.channel.title = ""; p.userdata.channel.description = ""; p.userdata.channel.link = ""; } else if (p.userdata.state == "item" || p.userdata.state == "entry") { switch (name) { case "title": p.userdata.cdataref = &p.userdata.item.title; } { case "link": % In Atom feeds, the url is in a "href" attribute like in html. % Also Atom feeds can have more than one link per item, but I % can't deal with that. if (p.userdata.is_atom) { foreach att (atts) { if (att.name=="href") { if (p.userdata.base != NULL && uri_parse(att.value) == NULL) { p.userdata.item.link = +"http://" + p.userdata.base.host + path_concat(p.userdata.base.path, att.value); } else p.userdata.item.link = att.value; break; } } } else p.userdata.cdataref = &p.userdata.item.link; } { case "description" or case "content": % or case "summary" p.userdata.cdataref = &p.userdata.item.description; } { case "dc:date": p.userdata.cdataref = &p.userdata.item.date; } } else if (p.userdata.state == "channel" || p.userdata.state == "feed") { switch (name) { case "title": p.userdata.cdataref = &p.userdata.channel.title; } { case "link": p.userdata.cdataref = &p.userdata.channel.link; } { case "description" or case "summary": p.userdata.cdataref = &p.userdata.channel.description; } } if (p.userdata.cdataref != NULL) p.characterdatahandler = &read_characterdata; push_state(p, name); } define endElement(p, name) { p.userdata.cdataref = NULL; p.characterdatahandler = NULL; switch (name) { case "dc:date": % dc:data may occur outside an item if (is_struct_type(p.userdata.item)) p.userdata.item.date = extract_element(p.userdata.item.date, 0, 'T'); } { case "item" or case "entry": p.userdata.itemhandler(); list_append(p.userdata.items, p.userdata.item); } pop_state(p); } %}}} %{{{ get the feed define write_callback(p, data) { xml_parse(p, data, 0); if (debug_mode) { setbuf("XML source"); insert(data); setbuf(p.userdata.buffer); } return 0; } define rss_new(url) { if (debug_mode) { setbuf("XML source"); erase_buffer(); } variable p = xml_new(); p.userdata = @userdata; p.userdata.items={}; p.userdata.states={}; p.userdata.state=""; p.userdata.item=""; p.userdata.cdataref=NULL; p.characterdatahandler = &read_characterdata; p.startelementhandler = &startElement; p.endelementhandler = &endElement; p.userdata.url = url; return p; } define get_rss(p) { variable c = curl_new(p.userdata.url); curl_setopt(c, CURLOPT_FOLLOWLOCATION, 1); curl_setopt(c, CURLOPT_WRITEFUNCTION, &write_callback, p); curl_setopt(c, CURLOPT_HTTPHEADER, ["User-Agent: firefox", "Accept-Charset: ISO-8859-1,utf-8"]); runhooks("jedscape_curlopt_hook", c); curl_perform (c); xml_parse(p, "", 1); } %}}} %{{{ store the feed % For now this only stores the name of the feed and the link % The database is only used as a bookmark manager for feeds % and to mark items as read. % Actually, storing the unread items is not really necessary. define store_feed(feed, items) { variable item; % We know what items are in the feed now, presumably old items % won't come back so we can erase them from the database sqlite_exec(db, "delete from items where feed = ?", feed); foreach item (items) { sqlite_exec (db, "insert or ignore into items (feed, title, link, is_read) values (?, ?, ?, ?)", feed, item.title, item.link, item.is_read); } } %}}} %{{{ rss mode %{{{ html tagsoup cleaner private variable entities = Assoc_Type[Char_Type]; foreach $1 ([{"nbsp", ' '}, {"gt", '>'}, {"lt", '<'}, {"amp", '&'}, {"quot", '\''}, {"apos", '\''}, {"circ", '^'}, {"tilde", '~'}, {"mdash", '-'}]) { entities[$1[0]] = $1[1]; } define clean_tagsoup() { mark_buffer(); variable newstr = str_re_replace_all(bufsubstr(), "<[^>]+>", ""); mark_buffer(); del_region(); insert(newstr); bob(); while(re_fsearch("&\([a-z]+\);"R)) { if (assoc_key_exists(entities, regexp_nth_match(1))) ()=replace_match(char(entities[regexp_nth_match(1)]), 0); else ()=replace_match("?", 0); } bob(); while(re_fsearch("&#\([0-9]+\);"R)) ()=replace_match(char(atoi(regexp_nth_match(1))), 0); } %}}} define next_unread_item() { push_mark(); while (down(1)) { if (get_line_color == color_number("keyword")) { pop_mark_0(); return; } } pop_mark_1(); message("no more unread items"); } define item_at_point() { variable feed = get_blocal_var("feed"); variable i = wherefirst(what_line() < feed.lines); if (i == NULL) i = -1; else i--; return feed.items[i]; } % Read in an item and mark it as read. Return 1 if the message is % already in the window, -1 if it had to be read in. define get_item() { variable u = get_blocal_var("feed"); variable item = item_at_point(); variable buf = whatbuf(); if (buffer_visible("news description")) pop2buf("news description"); else { onewindow(); splitwindow(); if (TOP_WINDOW_ROW != window_info('t')) otherwindow(); variable n1 = window_info('r'); otherwindow(); sw2buf("news description"); loop (n1 - 5) enlargewin(); } variable visible_item = get_blocal_var("item", NULL); if (visible_item == item) return 1; define_blocal_var("item", item); erase_buffer(); insert(item.description); bob(); push_mark(); skip_chars(" \n"); del_region(); if (u.cleanlevel & 1) { clean_tagsoup(); bob(); } if (u.cleanlevel & 2) { do { skip_chars(" \t\n"); call("format_paragraph"); } while (bol_fsearch("\n")); bob(); } set_buffer_modified_flag(0); sqlite_exec(db, "update items set is_read='1' where link= ?", item.link); pop2buf(buf); set_line_color(color_number("normal")); variable next_line = wherefirst(u.lines > item.line); if (next_line==NULL) return -1; next_line=u.lines[next_line]; loop(next_line - item.line - 1) { go_down_1(); set_line_color(color_number("normal")); } return -1; } define view_item() { variable buf = whatbuf(); ()=get_item(); pop2buf(buf); } define scroll() { variable buf = whatbuf(); variable item = item_at_point(); ifnot (buffer_visible("news description")) return view_item(); pop2buf("news description"); if (item == get_blocal_var("item", NULL)) { push_spot(); eob(); if (what_line() - (pop_spot(), what_line()) > window_info('r') - window_line()) { call("page_down"); pop2buf(buf); return; } else { pop2buf(buf); next_unread_item(); ()=get_item(); pop2buf(buf); } } else { pop2buf(buf); ()= get_item(); pop2buf(buf); } } define rss_goto_page() { variable item = item_at_point(); browse_url(item.link); } define rss_jedscape() { variable item = item_at_point(); jedscape_get_url(item.link); } ifnot (keymap_p(mode)) { copy_keymap(mode, "view"); definekey(&rss_goto_page, "g", mode); definekey(&onewindow, "h", mode); definekey(&rss_jedscape, "j", mode); definekey(&next_unread_item, "n", mode); definekey(&scroll, " ", mode); } define rss_mode() { view_mode(); use_keymap(mode); set_buffer_hook("newline_indent_hook", &view_item); } %}}} %{{{ start reading news define get_is_read(feed) { variable links, is_read = struct {titles, links}; variable t =sqlite_get_array(db, String_Type, "select title, link from items where feed=? and is_read='1'", feed); if (length(t)) { is_read.titles = t[*,0]; is_read.links = t[*,1]; } return is_read; } define item_handler(u) { setbuf(u.buffer); u.item.line = what_line(); if (NULL == wherefirst(u.item.title == u.is_read.titles and u.item.link == u.is_read.links)) { set_line_color(color_number("keyword")); } else { u.item.is_read=1; set_line_color(color_number("normal")); } if (u.item.date != "") { insert(u.item.date); insert(" "); } variable line; foreach line (strchop(u.item.title, '\n', 0)) { insert(line); newline(); } update(1); } public define newsflash() { variable feeds = sqlite_get_array(db, String_Type, "select name, url from feeds"); variable names = feeds[*, 0], urls = feeds[*, 1]; variable feed = read_with_completion(strjoin(feeds[*, 0], ","), "feed to read", "", "", 's'); variable url = wherefirst(feed == names); if (url == NULL) { url = read_mini("New feed! URL", "", ""); sqlite_exec(db, "insert into feeds (name, url) values (?, ?)", feed, url); } else url = urls[url]; variable p = rss_new(url); p.userdata.is_read = get_is_read(feed); p.userdata.cleanlevel = sqlite_get_row(db, "select cleanlevel from feeds where name=?", feed); p.userdata.itemhandler = &item_handler; p.userdata.buffer = feed; pop2buf(feed); get_rss(p); store_feed(feed, p.userdata.items); p.userdata.lines = Integer_Type[length(p.userdata.items)]; variable item, i = 0; foreach item (p.userdata.items) { p.userdata.lines[i] = item.line; i++; } setbuf(feed); define_blocal_var("feed", p.userdata); rss_mode(); } % This parses already fetched RSS data for reading an XML file from % jedscape.sl public define read_rss_data(url, data) { variable feed = sqlite_get_array(db, String_Type, "select name, url from feeds where url=?", url); if (length(feed)) { feed = feed[0, 0]; } else { feed = read_mini("name for this feed", "", ""); sqlite_exec(db, "insert into feeds (name, url) values (?, ?)", feed, url); } variable p = rss_new(url); p.userdata.is_read = get_is_read(feed); p.userdata.cleanlevel = sqlite_get_row(db, "select cleanlevel from feeds where name=?", feed); p.userdata.itemhandler = &item_handler; p.userdata.buffer = feed; pop2buf(feed); xml_parse(p, data, 1); store_feed(feed, p.userdata.items); p.userdata.lines = Integer_Type[length(p.userdata.items)]; variable item, i = 0; foreach item (p.userdata.items) { p.userdata.lines[i] = item.line; i++; } define_blocal_var("feed", p.userdata); rss_mode(); } %}}} jedmodes-2.5.7/ruby/0000755000175400017500000000000011130344610012554 5ustar mildegmjedmodes-2.5.7/ruby/ruby.sl0000644000175400017500000002233111130344610014076 0ustar mildegm% ruby.sl % % $Id: ruby.sl,v 1.16 2008/10/10 17:38:37 boekholt Exp $ % % Copyright (c) ca. % 2000 Shugo Maeda % 2002 Johann Gerell % 2003 Karl-Heinz Wild % 2007 Guenter Milde % 2007-2008 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % [Install] % % Please add these lines to your `jed.rc' file % (e.g. ~/.jedrc or ~/.jed/jed.rc). % % % Load ruby mode when opening `.rb' files. % autoload("ruby_mode", "ruby"); % add_mode_for_extension ("ruby", "rb"); % % [Customization] % % % amount of space to indent within block. % variable ruby_indent_level = 2; require("comments"); require("pcre"); #ifnexists __push_list autoload("list2array", "datutils"); #endif custom_variable("ruby_indent_level", 2); private define ruby_indent_to(n) { push_spot(); try { bol_skip_white(); if (what_column() != n) { bol_trim (); whitespace (n - 1); } } finally { pop_spot(); if (bolp()) goto_column(n); } } private define looking_at_block_end () { return orelse { andelse { looking_at_char('e') } { orelse { looking_at("end") } { looking_at("else") } { looking_at("elsif") } { looking_at("ensure") }}} { looking_at("}") } { looking_at("rescue") } { looking_at("when") }; } private variable block_start_re= pcre_compile("^(?:(?:begin|case|class|def|else( if)?|elsif|ensure|for|if|module|rescue" + "|unless|until|when|while)\b(?!.*\bend$))|(?:(?:(?:\bdo|{)(?: *\|.*\|)?) *$)"R); private define ruby_calculate_indent() { variable indent = 0; variable extra_indent = 0; variable par_level; variable case_search = CASE_SEARCH; CASE_SEARCH = 1; push_spot(); try { bol_skip_white(); indent = what_column(); if (looking_at_block_end()) { extra_indent -= ruby_indent_level; } !if (up_1()) return indent; eol(); par_level = 0; forever { if (eolp()) { forever { bol(); if (looking_at("#")) { !if (up_1()) return indent; eol(); } else { eol(); break; } } } !if(left(1)) break; if (0 == parse_to_point()) { if (looking_at_char(')')) { par_level--; } else if (looking_at_char('(')) { par_level++; } } bskip_chars("^()\n"); if (bolp()) { skip_white(); indent = what_column(); break; } } if (looking_at("#")) return what_column() + extra_indent; push_mark_eol(); exchange_point_and_mark(); return indent + extra_indent + ruby_indent_level * (par_level + pcre_exec(block_start_re, bufsubstr())); } finally { pop_spot(); CASE_SEARCH = case_search; } } private define ruby_indent_line() { if (get_line_color()) return; ruby_indent_to(ruby_calculate_indent()); } private define check_endblock(); private define check_endblock() { remove_from_hook("_jed_after_key_hooks", &check_endblock); if (get_line_color()) return; push_spot(); try { bskip_white(); if (bolp()) return; % you may be trying to fix the indentation manually bol_skip_white(); if (looking_at_block_end()) { ruby_indent_line(); add_to_hook("_jed_after_key_hooks", &check_endblock); } } finally { pop_spot(); } } private define insert_ket() { insert_char('}'); ruby_indent_line(); } define ruby_newline_and_indent() { check_endblock(); newline(); ruby_indent_line(); } define ruby_self_insert_cmd() { insert_char(LAST_CHAR); check_endblock(); } % Define keymap. private variable mode = "ruby"; !if (keymap_p (mode)) make_keymap (mode); definekey ("ruby_self_insert_cmd", "d", mode); definekey ("ruby_self_insert_cmd", "e", mode); definekey ("ruby_self_insert_cmd", "f", mode); definekey ("ruby_self_insert_cmd", "n", mode); definekey (&insert_ket, "}", mode); % Create syntax table. create_syntax_table (mode); define_syntax ("#", Null_String, '%', mode); define_syntax ("([{", ")]}", '(', mode); define_syntax ('"', '"', mode); define_syntax ('\'', '"', mode); define_syntax ('\\', '\\', mode); define_syntax ("$0-9a-zA-Z_", 'w', mode); define_syntax ("-+0-9a-fA-F.xXL", '0', mode); define_syntax (",;.?:", ',', mode); define_syntax ("%-+/&*=<>|!~^", '+', mode); set_syntax_flags (mode, 4); #ifdef HAS_DFA_SYNTAX dfa_enable_highlight_cache("ruby.dfa", mode); dfa_define_highlight_rule("#.*$", "comment", mode); dfa_define_highlight_rule("[A-Za-z_][A-Za-z_0-9]*[\?!]?"R, "Knormal", mode); dfa_define_highlight_rule("[0-9]+(\.[0-9]+)?([Ee][\+\-]?[0-9]*)?"R, "number", mode); dfa_define_highlight_rule("0[xX][0-9A-Fa-f]*", "number", mode); dfa_define_highlight_rule("\?[^ ]"R, "number", mode); dfa_define_highlight_rule("[\(\[\{\<\>\}\]\),;\.\?:]"R, "delimiter", mode); dfa_define_highlight_rule("[%\-\+/&\*=<>\|!~\^]"R, "operator", mode); dfa_define_highlight_rule("-[A-Za-z]", "keyword0", mode); dfa_define_highlight_rule("'([^'\\]|\\.)*'"R, "string", mode); dfa_define_highlight_rule("`([^`\\]|\\.)*`"R, "string", mode); dfa_define_highlight_rule("\"([^\"\\\\]|\\\\.)*\"", "string", mode); % parse_to_point() doesn't take DFA rules into account so % %r{...} can mess up the indentation - consider using %r'...' % or Regexp.new("...") instead dfa_define_highlight_rule("%[rwWqQx]?({.*}|<.*>|\(.*\)|\[.*\]|\$.*\$|\|.*\||!.*!|/.*/|#.*#|"R, "Qstring", mode); dfa_define_highlight_rule("%[rwWqQx]?'([^'\\]|\\.)*'"R, "string", mode); dfa_define_highlight_rule("%[rwWqQx]?\"([^\"\\\\]|\\\\.)*\"", "string", mode); dfa_define_highlight_rule("m?/([^/\\]|\\.)*/[gio]*"R, "string", mode); dfa_define_highlight_rule("m/([^/\\]|\\.)*\\?$"R, "string", mode); dfa_define_highlight_rule("s/([^/\\]|\\.)*(/([^/\\]|\\.)*)?/[geio]*"R, "string", mode); dfa_define_highlight_rule("s/([^/\\]|\\.)*(/([^/\\]|\\.)*)?\\?$"R, "string", mode); dfa_define_highlight_rule("(tr|y)/([^/\\]|\\.)*(/([^/\\]|\\.)*)?/[cds]*"R, "string", mode); dfa_define_highlight_rule("(tr|y)/([^/\\]|\\.)*(/([^/\\]|\\.)*)?\\?$"R, "string", mode); dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table (mode); #endif % Type 0 keywords () = define_keywords_n(mode, "doifinor", 2, 0); () = define_keywords_n(mode, "anddefendfornilnot", 3, 0); () = define_keywords_n(mode, "caseelsefailloadloopnextredoselfthenwhen", 4, 0); () = define_keywords_n(mode, "aliasbeginbreakclasselsifraiseretrysuperundefuntilwhileyield", 5, 0); () = define_keywords_n(mode, "ensuremodulerescuereturnunless", 6, 0); () = define_keywords_n(mode, "includerequire", 7, 0); () = define_keywords_n(mode, "autoload", 8, 0); % Type 1 keywords () = define_keywords_n(mode, "TRUE", 4, 1); () = define_keywords_n(mode, "FALSE", 5, 1); set_comment_info(mode, "# ", "", 4); private define last_line() { push_spot(); eob(); what_line(); pop_spot(); } private define search_heredoc_end(indent, end) { if (strlen(indent)) return re_fsearch(sprintf("\\c^[ \t]*%s$", end)); return re_fsearch(sprintf("\\c^%s$", end)); } private define color_buffer(min_line, max_line) { !if (max_line) return; if (is_visible_mark()) return; variable string_color = color_number("string"); push_spot(); try { variable begin = {}; variable end = {}; variable in_heredoc = 0; goto_line(min_line); while (re_bsearch("\\c<<\\(-?\\)\\(\"?\\)\\([A-Z]+\\)\\2\\>")) { if (bfind_char('#')) continue; list_append(begin, what_line()); eol(); if (search_heredoc_end(regexp_nth_match(1), regexp_nth_match(3))) { list_append(end, what_line()); if (what_line() > max_line) { in_heredoc = 1; } } else { list_append(end, 1 + last_line()); in_heredoc = 1; } break; } !if (in_heredoc) { while (re_fsearch("\\c^[^#]*<<\\(-?\\)\\(\"?\\)\\([A-Z]+\\)\\2\\>")) { if (what_line() > max_line) break; eol(); list_append(begin, what_line()); if (andelse{search_heredoc_end(regexp_nth_match(1), regexp_nth_match(3))} {what_line() < max_line}) { list_append(end, what_line()); } else { list_append(end, last_line()); break; } } } goto_line(min_line); if (length(begin)) { #ifexists __push_list begin = [__push_list(begin)]; end = [__push_list(end)]; #else begin = list2array(begin, Integer_Type); end = list2array(end, Integer_Type); #endif loop(max_line - min_line + 1) { if (wherefirst(begin < what_line() and end >= what_line()) != NULL) set_line_color(string_color); else set_line_color(0); go_down_1(); } } else { loop(max_line - min_line + 1) { set_line_color(0); go_down_1(); } } } catch RunTimeError: { unset_buffer_hook("color_region_hook"); } finally { pop_spot(); } } public define ruby_mode() { set_mode(mode, 2); use_keymap(mode); use_syntax_table(mode); set_buffer_hook("color_region_hook", &color_buffer); set_buffer_hook("indent_hook", &ruby_indent_line); set_buffer_hook("newline_indent_hook", "ruby_newline_and_indent"); run_mode_hooks("ruby_mode_hook"); } provide("ruby"); jedmodes-2.5.7/apsmode/0000755000175400017500000000000011702652675013245 5ustar mildegmjedmodes-2.5.7/apsmode/apsconf.template0000644000175400017500000003276410445536175016446 0ustar mildegm% apsconf.sl -*- mode: slang; mode: fold; -*- % % apsconf.sl is the configurable part of apsmode. % Here you can modify some global settings as temp directory, % default printer id, style sheet usage, ... % some of them are OS specific % % requires apsmode version >=2.2 % % 2005-11-21 GM : use path_concat() for Apsmode_tmp_dir % 2006-06-02 TKO: adapted to apsmode V2.0 % 2006-06-19 TKO: adapted to apsmode V2.2 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % name : Apsmode_menu % description : defines, whether a popup menu should be created % by apsmode.sl % be aware that quickprint settings are only available % via menu % wmenu will not be supported % (0 = no menu, 1 = popup menu) % value : path % % name : Apsmode_del_ps_file % description : delete created ps file after printing/viewing % (0 = keep, 1 = delete) % value : 0 or 1 % % name : Apsmode_tmp_dir % description : directory for temporary files and ps file % value : path % % name : Apsmode_a2ps_cmd % description : OS specific command to run a2ps % value : a2ps programm call (with path) % % name : Apsmode_default_printer % description : id of the default printer % id = 0 is reserved for QuickPrint, don't use it ! % the configuration file handles UNIX and Windows % printers separately % value : aps_max_no_printers > Apsmode_default_printer > 0 % % name : Apsmode_tmp_file % description : name of the ps file, which will be created by a2ps % value : *.ps % % name : Apsmode_style_sheet % description : array containing all jed mode names (as index), for which a % jed specific style sheet for a2ps should be used % style sheets must be available in jed library path % can be created by function % value : Apsmode_style_sheet[] = 1; % %Apsmode_menu = 1; %Apsmode_del_ps_file = 1; %#ifdef UNIX %Apsmode_tmp_dir = path_concat(getenv("TMPDIR"), ""); % ensure trailing "/" %if (Apsmode_tmp_dir == "") % Apsmode_tmp_dir = "/home/wtb3_tko/tmp/"; %Apsmode_a2ps_cmd = "a2ps"; %Apsmode_default_printer = 5; %#endif % %#ifdef MSWINDOWS %Apsmode_tmp_dir = "C:\\temp\\"; %Apsmode_a2ps_cmd = "D:\\Programs\\a2ps\\bin\\a2ps.exe"; %Apsmode_default_printer = 1; %#endif % %Apsmode_tmp_file = path_concat(Apsmode_tmp_dir, "print_from_jed.ps"); % %Apsmode_style_sheet["SLang"] = 1; %Apsmode_style_sheet["awk"] = 1; %%%%%%%%%%%%%%%%%% Define printers %%%%%%%%%%%%%%%%%%%%%%%%%%% %{{{ % % This structure contains the printer settings for apsmode.sl % Most of the settings are directly copied from a2ps options % See a2ps documentation for further details. % These settings have been tested with: % - UNIX : a2ps v4.12 % - MSWINDOWS : a2ps v4.13b % % The printer settings have been "divided" for UNIX/Windows. so that only % the relevant printers will show up under the specific OS. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % JED variables used as placeholder for print options % % name : JEDFILENAME % description: use this variable in footer/header definitions to print % the path/name of the buffer to be printed % do not use "$f" option of a2ps, because this will print % the name of the temporary print file instead of the name of % the buffer % % name : JEDDATETIME % description: use this variable in footer/header definitions to print % the current date, time of the buffer print formatted % as YYYY-MMM-DD, HH:MM:SS % this is a replacement for the "%e %*" option of a2ps % which seems to not work correctly under MSWINDOWS % Correction: with apsmode V1.4 options for Windows are % correctly send to a2ps, so "%e %*" should work % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % name : setup % description: printer id % local variable % will be used as program internal identifier for % the print setup % value(s) : integer, incremented by 1 % % name : setupname % description: that's the name of the printer setup, which will be used as % identifier % should not be too long, because it will be used within % the menus % value(s) : text % example : "code 2x1x1, A4" % % name : name % description: physical printer name as known by the OS % value(s) : text % example : "114_f004" % % name : description % description: Your information about the printer setup % value(s) : text % example : "This is an example description" % % name : columns % description: specify the number of columns of virtual pages per physical page % value(s) : integer (1...n) % example : "2" % % name : rows % description: specify the number of rows of virtual pages per physical page % value(s) : integer (1...n) % example : "2" % % name : fontsize % description: defines fontsize in points % if other formats than points needs to be supported % by QuickPrint then function has to be % modified accordingly % value(s) : 8,...,72 points, anything your printer and a2ps supports % example : "8points" % % name : chars % description: number of characters to be printed on one line % format = min:max % min - minimum of characters to be printed % max - maximum of characters to be printed % value(s) : Integer:Integer % example : "80:100" % % name : borders % description: switches border printing around each page on/off % value(s) : on,off % example : "on" % % name : orientation % description: defines sheet orientation % value(s) : portrait,landscape % example : "portrait" % % name : medium % description: defines print medium (sheet size) % if other formats than a3, a4, letter needs to be supported % by QuickPrint then function has to be % modified accordingly % value(s) : a4, a3, letter, ..., anything your printer and a2ps supports % example : "a4" % % name : sides % description: printing on one/both sides of a sheet % value(s) : 1,2 % example : "2" % % name : truncate % description: truncate lines, if they are longer than maximum number of % printing characters % !!! ATTENTION !!! % try on/off values with your a2ps installation % there seems to be a bug in different a2ps version % and/or OS version % UNIX , a2ps v4.12 : truncate=on does not truncate % MSWINDOWS, a2ps v4.13b : truncate=off does not truncate % value(s) : on,off % example : "on" % % name : linenumbers % description: add linenumbers every x line to your printout % helpful for program code % switch off with value 0 % value(s) : 0...n % example : "5" % % name : copies % description: number of copies to be printed % value(s) : 1...n % example : "1" % % name : major % description: specify whether the virtual pages should be first filled in % rows (direction = rows) or in columns (direction = columns). % value(s) : rows,columns % example : "columns" % % name : margin % description: Specify the size of the margin (num PostScript points, % or 12 points without arguments) to leave in the inside % (i.e. left for the front side page, and right for the back % side). This is intended to ease the binding. % value(s) : 0...n % example : "5" % % name : header % description: sets the page header % value(s) : text % example : "Your Page header" % % name : title_left % description: Set virtual page left title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%e %*" % % name : title_center % description: Set virtual page center title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "$f", "JEDFILENAME" % % name : title_right % description: Set virtual page right title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%s./%s#" % % name : footer_left % description: Set virtual page left footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%e %*" % % name : footer_center % description: Set virtual page center footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "$f" % % name : footer_right % description: Set virtual page right footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%s./%s#" % % name : color % description: switches color printing on/off % bw - Style is plain: pure black and white, with standard fonts % color - Colors are used to highlight the keywords % value(s) : bw,color % example : "color" % % name : pretty % description: switches pretty printing feature of a2ps on/off % value(s) : on,off % example : "on" % % name : print_cmd % description: string containing the OS specific command to send the created % postscript file to the physical printer % could also be a ghostview command if direct printing % is somehow not supported % value(s) : text % example : strcat("lpr -P ", Apsmode_Printers[setup].name, " ", Apsmode_tmp_file) % strcat("gsview32.exe ", Apsmode_tmp_file); % % name : view_cmd % description: string containing the OS specific command to view the created % postscript file (ghostview preferred) % value(s) : text % example : strcat("gv ", Apsmode_tmp_file) % strcat("gsview32.exe ", Apsmode_tmp_file); % % name : copy_of % description: internal variable, which is needed for QuickPrint settings % has to be 0, don't change it % value(s) : 0 % example : "0" % % evaluate apsmode if this is not already done require("apsmode"); % reset index for printer setting private variable setup = 0; #ifdef UNIX setup++; Apsmode_Printers[setup].setupname = "code, A4, 6pt, 2x1, duplex"; Apsmode_Printers[setup].name = "lp"; Apsmode_Printers[setup].description = "Default Printer (code, duplex, 2 on 1)"; Apsmode_Printers[setup].columns = "2"; Apsmode_Printers[setup].rows = "1"; Apsmode_Printers[setup].fontsize = "6points"; Apsmode_Printers[setup].chars = "80:100"; Apsmode_Printers[setup].borders = "on"; Apsmode_Printers[setup].orientation = "landscape"; Apsmode_Printers[setup].medium = "A4"; Apsmode_Printers[setup].sides = "2"; Apsmode_Printers[setup].truncate = "on"; Apsmode_Printers[setup].linenumbers = "5"; Apsmode_Printers[setup].copies = "1"; Apsmode_Printers[setup].major = "columns"; Apsmode_Printers[setup].margin = "5"; Apsmode_Printers[setup].header = ""; Apsmode_Printers[setup].title_left = ""; Apsmode_Printers[setup].title_center = ""; Apsmode_Printers[setup].title_right = ""; %Apsmode_Printers[setup].footer_left = "%e %*"; Apsmode_Printers[setup].footer_left = "JEDDATETIME"; %Apsmode_Printers[setup].footer_center = "$f"; Apsmode_Printers[setup].footer_center = "JEDFILENAME"; Apsmode_Printers[setup].footer_right = "%s./%s#"; Apsmode_Printers[setup].color = "bw"; Apsmode_Printers[setup].pretty = "on"; Apsmode_Printers[setup].print_cmd = strcat("lpr -P ", Apsmode_Printers[setup].name, " ", Apsmode_tmp_file); Apsmode_Printers[setup].view_cmd = strcat("gv ", Apsmode_tmp_file); Apsmode_Printers[setup].copy_of = 0; #endif %%%%%%%%%%%%%%%%%% MS Windows Printers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef MSWINDOWS setup++; Apsmode_Printers[setup].setupname = "code, 2x1x2"; Apsmode_Printers[setup].name = "PrinterWINDOWS"; Apsmode_Printers[setup].description = "MS WINDOWS Printer"; Apsmode_Printers[setup].columns = "2"; Apsmode_Printers[setup].rows = "1"; Apsmode_Printers[setup].fontsize = "8points"; Apsmode_Printers[setup].chars = "80:100"; Apsmode_Printers[setup].borders = "on"; Apsmode_Printers[setup].orientation = "landscape"; Apsmode_Printers[setup].medium = "A4"; Apsmode_Printers[setup].sides = "2"; Apsmode_Printers[setup].truncate = "off"; Apsmode_Printers[setup].linenumbers = "5"; Apsmode_Printers[setup].copies = "1"; Apsmode_Printers[setup].major = "columns"; Apsmode_Printers[setup].margin = "5"; Apsmode_Printers[setup].header = ""; Apsmode_Printers[setup].title_left = ""; Apsmode_Printers[setup].title_center = ""; Apsmode_Printers[setup].title_right = ""; %Apsmode_Printers[setup].footer_left = "%e %*"; %Apsmode_Printers[setup].footer_left = "%e"; Apsmode_Printers[setup].footer_left = "JEDDATETIME"; %Apsmode_Printers[setup].footer_center = "$f"; Apsmode_Printers[setup].footer_center = "JEDFILENAME"; Apsmode_Printers[setup].footer_right = "%s./%s#"; Apsmode_Printers[setup].color = "bw"; Apsmode_Printers[setup].pretty = "on"; Apsmode_Printers[setup].print_cmd = strcat("D:\\Programs\\gstools\\gsview\\gsview32.exe ", Apsmode_tmp_file); Apsmode_Printers[setup].view_cmd = strcat("D:\\Programs\\gstools\\gsview\\gsview32.exe ", Apsmode_tmp_file); Apsmode_Printers[setup].copy_of = 0; #endif jedmodes-2.5.7/apsmode/apsmode.sl0000644000175400017500000026376710700402617015244 0ustar mildegm% apsmode -*- mode: slang; mode: fold; -*- % apsmode % Copyright (c) 2003-2006 Thomas Koeckritz (tkoeckritz at gmx dot de) % Released under the terms of the GNU General Public License (ver. 2 or later) % % ChangeLog % --------- % 0.1 2003-07-01 started as "lunch-hour" project % quick and dirty printing via hardcoded a2ps-command % 0.2 2003-07-31 most a2ps options included % 0.3 2003-08-12 QuickPrint added % 0.4 2003-08-27 a2ps style-sheet support added % 1.0 2003-09-18 Initial (stable) version % 1.1 2004-01-05 JEDFILENAME, JEDDATETIME added, minor modifications % 1.2 2004-02-20 apsmode.hlp written % 1.3 2004-03-09 region stays highlighted after preview/printing % internal documentation enhanced % 1.4 2004-03-22 printer.conf renamed to apsconf.sl % all user-definable variables moved to apsconf.sl % add variable to choose menu-support (Apsmode_menu) % add variable to choose deletion of ps-file (Apsmode_del_ps_file) % handling of options for WINDOWS corrected/improved % 1.5 2005-04-14 added handling of font size % added saving of current parameters in apsconf format % 1.5.1 2005-11-21 modified apsconf.sl: GM: use path_concat() for Apsmode_tmp_dir % 1.5.2 2006-06-01 made user-definable variables custom_variables (G Milde) % 2.0 2006-06-02 lot of modifications done to integrate apsmode better into % jed-libraries (triggered by G.Milde for usability with % debian) % - include apsconf.sl into apsmode.sl % apsconf.sl could be still be used optional with % () = evalfile("apsconf.sl"); % - make more variables custom_variable % - rename custom-variables to "Apsmode_" % - make aps_pid a private variable % - rename directory /apsconf to /apsmode % - rename aps.hlp to apsmode.hlp % - Apsmode_a2ps_sheet_dir removed (style sheets have to be % in the jed library path) % - make Apsmode_help_file a private variable % help file must be located in jed library path % - make aps_max_no_printers a private variable % - function path_rel removed % - apsmode.hlp adapted % - apsconf.sl has always to be loaded separately by the user % Therefore variable Apsmode_config_file has been removed. % (also editing/reloading of apsconf.sl via Print-Menu % will not be supported anymore) % - function show_apsmode_settings added % 2.1 2006-06-15 some more proposals by GM % - make Apsmode_Printer, Apsmode_style_sheet public variables % - redefine position of popup-menu % 2.2 2006-06-19 - jed_date_time modified % - QuickPrint menu entries show now current settings % - change Apsmode_Printers[].setup --> Apsmode_Printers[].setupname % - change aps_pid --> setup % - more QuickPrint menu entries added % 2.2.1 2007-10-02 bugfix (GM) % % Description % ----------- % JED-mode to support printing from jed using a2ps and ghostview. % This mode has been designed for and successfully tested % under % - UNIX (SunOS 5.8) % - WINDOWS (Windows NT 4.0, Windows 2000, Windows ME) % see also apsmode.hlp % % Features % -------- % - creation of a postscript file of the current buffer or marked region % - preview/printing of the created postscript file % - printing with syntax highlighting (acc. to JED mode and/or a2ps style % sheets) % - print preview mode (with ghostview) % - supports printing of several pages on one sheet, borders, % title, footer definitions... % - new menu entries for printing % - printer definitions in a separate configuration file possible (apsconf.sl) % covering most of a2ps layout features % - QuickPrint: modification of a printer setting for the open jed session % allows quick (small) changes of a defined printer setting, % changes will not be saved! % - basic support for creation of a2ps style sheets from JED modes % (scans xyz-mode.sl for keywords) % % Requirements % ------------ % jed 0.99.18 % a2ps installed and running on your OS % - UNIX : a2ps v4.12 (tested) % - MSWINDOWS : a2ps v4.13b (tested) % see http://www.inf.enst.fr/~demaille/a2ps or % http://www.gnu.org/software/a2ps/ or % http://sourceforge.net/project/showfiles.php?group_id=23617 % a2ps-4.13b-bin.zip (for windows version) % % ghostview for viewing installed on your OS % - UNIX : gv v3.0.4 (tested) % - MSWINDOWS : GSview 4.4 (tested) % see http://www.cs.wisc.edu/~ghost % % popup menues enabled within your jed % % Modifications to do for installation % ------------------------------------ % jed.rc: Add the following line to enable text menus in WINGUI % () = evalfile("menus"); % Load the apsmode % require("apsmode"); % Append and customize personal a2ps/printer settings from % apsconf.sl or customize apsconf.sl and eval with % () = evalfile("apsconf"); % Maybe you have to copy the file to your personal % jed files first, in Unix this could be "~/.jed/lib/" % in this case, make sure it is in the jed-library-path (see % set_jed_library_path()) % see also apsmode.hlp for details (esp. conversion from V1.5 to V2.0) % % Implemented Functions (main functions) % -------------------------------------- % The functions of apsmode are designed to be executable from menu entries. % Nevertheless the main print functions can also be used from jed commandline % and/or your personal keybindings. % - print_buffer() % - print_region() % - print_buffer_preview() % - print_region_preview() % - show_print_log() % - aps_help() % Functions to define special print settings (QuickPrint) are only accessible % via the menu. % % Global Variables % ---------------- % for description see below in the coding % Apsmode_a2ps_cmd % Apsmode_default_printer % Apsmode_del_ps_file % Apsmode_menu % Apsmode_Printers % Apsmode_style_sheet % Apsmode_tmp_dir % Apsmode_tmp_file % % Notes % ----- % - if no postscript printer is installed on your system use ghostview % for printing % - error handling under WINDOWS is not working properly, % if something strange happened during printing, look at the % print-log buffer (via function show_print_log() ) % % ToDo % ---- % no ideas left for now % % Known Bugs % ---------- % For creating an a2ps style sheet, the exact mode name as defined for the % syntax table has to be given. % Look for lines like % $1 = "TCL"; % create_syntax_table ($1); % in the .sl file to catch the real mode name. % If the wrong name will be given function create_a2ps_style_sheet(mode) % will crash. % There seems to be no slang function to test, whether a mode exists. % % Windows version (14.3b) of a2ps seems to have some bugs: % - line truncating works opposite to UNIX version % - If a header string is defined, then automatically date, filename, pagecount % will be inserted in title and footer, if the strings for that are empty. % To prevent printing the same information twice, define strings for % title and footer as " " instead of "" % e.g. Apsmode_Printers[setup].footer_left = " "; % % (Windows only?): If the path to the a2ps/gsview executables contains blanks, % apsmode can't access them. % So prevent installation of executables in Directories containing blanks % in name or add the a2ps directory to the path. % (a2ps Windows version (14.3b)): % For a2ps.exe I encountered this problem. a2ps.exe requested to be % in C:\Program Files\a2ps. So I did a "double" installation, one a2ps in % C:\Program Files\a2ps, the other in C:\Programs\a2ps. % In apsconf.sl I referenced the a2ps command in C:\Programs\a2ps, which then % takes it config files and other stuff from C:\Program Files\a2ps. % Or adding the a2ps directory to the path will also help. % # % Add the Print menu popup. % apsmode.sl will only be evaluated when the popup is opened autoload("apsmode_menu_callback", "apsmode"); custom_variable("Apsmode_menu", "Global.&File.&Print"); define apsmode_load_popup_hook(menubar) { if (Apsmode_menu == "") return; $2 = strtok(Apsmode_menu, "."); menu_insert_popup(7, strjoin($2[[:-2]], "."), $2[-1]); menu_set_select_popup_callback(Apsmode_menu, &apsmode_menu_callback); } append_to_hook("load_popup_hooks", &apsmode_load_popup_hook); # % Helper functions for Postscript printing %{{{ % global variables, settings % printer properties definition !if (is_defined("Printer_Type")) typedef struct { setupname, name, description, columns, rows, fontsize, chars, borders, orientation, medium, sides, truncate, linenumbers, copies, major, margin, header, title_left, title_center, title_right, footer_left, footer_center, footer_right, color, pretty, print_cmd, view_cmd, copy_of } Printer_Type; %%%%%%%%%%%%%%% private variables begin %%%%%%%%%%%%% % % do'nt change this block % % this variable will be used to give the path/filename of the buffer to a2ps private variable aps_jedfilename = ""; % this variable will be used to give the date/time of printing to a2ps private variable aps_jeddatetime = ""; private variable setup = 0; private variable aps_preview = "off"; private variable aps_help_file = expand_jedlib_file("apsmode.hlp"); % number of printers which can be defined in apsconf.sl % (default = 50 should be sufficient in most cases) private variable aps_max_no_printers = 50; private variable menu_entry = ""; % do not change the definitions for Apsmode_Printers and Apsmode_style_sheet % here, but you can define new values for these structures later (see below) % e.g. % Apsmode_Printers[setup].description = "Default Printer"; % or % Apsmode_style_sheet["awk"] = 1; % public variable Apsmode_Printers = Printer_Type[aps_max_no_printers]; public variable Apsmode_style_sheet = Assoc_Type[Integer_Type]; % version information private variable aps_version = "2.2"; private variable aps_creation_date = "2006-06-19"; private variable aps_jed_tested = "0.99-18"; private variable aps_creator = "tkoeckritzatgmxdotde"; %%%%%%%%%%%%%%% private variables end %%%%%%%%%%%%% %}}} %%%%%%%%%%%%%%% custom_variables begin %%%%%%%%%%%%% % define custom variables and set default values which % could be configured in jed.rc or a local|private apsconf.sl % % Directory used to hold temporary files (defined in site.sl since jed 0.99.18) custom_variable("Jed_Tmp_Directory", getenv("TEMP")); if (Jed_Tmp_Directory == NULL) Jed_Tmp_Directory = getenv("TMP"); if (Jed_Tmp_Directory == NULL) #ifdef MSWINDOWS Jed_Temp_Dir = "C:\\temp"; #elseif Jed_Tmp_Directory = "/tmp"; #endif % OS specific command to run a2ps (a2ps programm call (with path)) #ifdef UNIX custom_variable("Apsmode_a2ps_cmd", "a2ps"); #endif #ifdef MSWINDOWS custom_variable("Apsmode_a2ps_cmd", "D:\\Programs\\a2ps\\bin\\a2ps.exe"); #endif % directory for temporary files and ps file custom_variable("Apsmode_tmp_dir", path_concat(Jed_Tmp_Directory, "")); % ensure trailing separator % name of the ps file, which will be created by a2ps %custom_variable("Apsmode_tmp_file", strcat(Apsmode_tmp_dir, "print_from_jed.ps")); custom_variable("Apsmode_tmp_file", path_concat(Apsmode_tmp_dir, "print_from_jed.ps")); % id of the default printer % id = 0 is reserved for QuickPrint, don't use it ! % aps_max_no_printers > id of Apsmode_default_printer > 0 custom_variable("Apsmode_default_printer", 1); % defines, where the Print popup menu should be created % alternatives: "Global.&File.&Print" CUA compatible % "Global.&Print" top level (add a keybinding for Alt-P) % "Global.S&ystem.&Print" % "" no print menu % be aware that quickprint settings are only available via menu % wmenu is not supported custom_variable("Apsmode_menu", "Global.&File.&Print"); % delete created ps file after printing/viewing (0 = keep, 1 = delete) custom_variable("Apsmode_del_ps_file", 1); % define a default printer here % initially no real printer is defined % could be done by a jed admin locally in a config file (defaults.sl or % /etc/jed.conf on UNIX) or by the user in jed.rc (or .jedrc) % print_cmd and view_cmd are examples for UNIX/MSWINDOWS % for details see printer definition description in apsmode.hlp % for more printer setups (or user defined ones ), add the definitions in % .jedrc or use a separate apsconf.sl file evaluated from .jedrc setup++; Apsmode_Printers[setup].setupname = "default printer not defined yet"; Apsmode_Printers[setup].name = "default_printer_name"; Apsmode_Printers[setup].description = "Default Printer"; Apsmode_Printers[setup].columns = "2"; Apsmode_Printers[setup].rows = "1"; Apsmode_Printers[setup].fontsize = "6points"; Apsmode_Printers[setup].chars = "80:100"; Apsmode_Printers[setup].borders = "on"; Apsmode_Printers[setup].orientation = "landscape"; Apsmode_Printers[setup].medium = "A4"; Apsmode_Printers[setup].sides = "2"; Apsmode_Printers[setup].truncate = "on"; Apsmode_Printers[setup].linenumbers = "5"; Apsmode_Printers[setup].copies = "1"; Apsmode_Printers[setup].major = "columns"; Apsmode_Printers[setup].margin = "5"; Apsmode_Printers[setup].header = ""; Apsmode_Printers[setup].title_left = ""; Apsmode_Printers[setup].title_center = ""; Apsmode_Printers[setup].title_right = ""; Apsmode_Printers[setup].footer_left = "JEDDATETIME"; Apsmode_Printers[setup].footer_center = "JEDFILENAME"; Apsmode_Printers[setup].footer_right = "%s./%s#"; Apsmode_Printers[setup].color = "bw"; Apsmode_Printers[setup].pretty = "on"; Apsmode_Printers[setup].print_cmd = ""; Apsmode_Printers[setup].view_cmd = ""; #ifdef UNIX Apsmode_Printers[setup].print_cmd = strcat("lpr -P ", Apsmode_Printers[setup].name, " ", Apsmode_tmp_file); Apsmode_Printers[setup].view_cmd = strcat("gv ", Apsmode_tmp_file); #endif #ifdef MSWINDOWS Apsmode_Printers[setup].print_cmd = strcat("D:\\Programs\\gstools\\gsview\\gsview32.exe ", Apsmode_tmp_file); Apsmode_Printers[setup].view_cmd = strcat("D:\\Programs\\gstools\\gsview\\gsview32.exe ", Apsmode_tmp_file); #endif Apsmode_Printers[setup].copy_of = 0; % array containing all jed mode names (as index), for which a % jed specific style sheet for a2ps should be used % style sheets must be available in jed library path % can be created by function Apsmode_style_sheet["SLang"] = 1; %%%%%%%%%%%%%%% custom_variables variables end %%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % There is no need to change something below this line ! % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % define QuickPrint settings as copy of default printer %!%+ %\function{qp_is_copy_of} %\synopsis{fill QuickPrint data with a predefined printer setup} %\usage{qp_is_copy_of (Integer_Type pid_in)} %\description % This function is used to fill QuickPrint data with a predefined printer % setup given by \var{pid_in}. % The QuickPrint setup uses index=0 in \var{Apsmode_Printers}. % This function returns nothing. %!%- define qp_is_copy_of(pid_in) %{{{ { variable setup = 0; Apsmode_Printers[setup].setupname = "QuickPrint"; Apsmode_Printers[setup].name = Apsmode_Printers[pid_in].name; Apsmode_Printers[setup].description = Apsmode_Printers[pid_in].description; Apsmode_Printers[setup].columns = Apsmode_Printers[pid_in].columns; Apsmode_Printers[setup].rows = Apsmode_Printers[pid_in].rows; Apsmode_Printers[setup].fontsize = Apsmode_Printers[pid_in].fontsize; Apsmode_Printers[setup].chars = Apsmode_Printers[pid_in].chars; Apsmode_Printers[setup].borders = Apsmode_Printers[pid_in].borders; Apsmode_Printers[setup].orientation = Apsmode_Printers[pid_in].orientation; Apsmode_Printers[setup].medium = Apsmode_Printers[pid_in].medium; Apsmode_Printers[setup].sides = Apsmode_Printers[pid_in].sides; Apsmode_Printers[setup].truncate = Apsmode_Printers[pid_in].truncate; Apsmode_Printers[setup].linenumbers = Apsmode_Printers[pid_in].linenumbers; Apsmode_Printers[setup].copies = Apsmode_Printers[pid_in].copies; Apsmode_Printers[setup].major = Apsmode_Printers[pid_in].major; Apsmode_Printers[setup].margin = Apsmode_Printers[pid_in].margin; Apsmode_Printers[setup].header = Apsmode_Printers[pid_in].header; Apsmode_Printers[setup].title_left = Apsmode_Printers[pid_in].title_left; Apsmode_Printers[setup].title_center = Apsmode_Printers[pid_in].title_center; Apsmode_Printers[setup].title_right = Apsmode_Printers[pid_in].title_right; Apsmode_Printers[setup].footer_left = Apsmode_Printers[pid_in].footer_left; Apsmode_Printers[setup].footer_center = Apsmode_Printers[pid_in].footer_center; Apsmode_Printers[setup].footer_right = Apsmode_Printers[pid_in].footer_right; Apsmode_Printers[setup].color = Apsmode_Printers[pid_in].color; Apsmode_Printers[setup].pretty = Apsmode_Printers[pid_in].pretty; Apsmode_Printers[setup].print_cmd = Apsmode_Printers[pid_in].print_cmd; Apsmode_Printers[setup].view_cmd = Apsmode_Printers[pid_in].view_cmd; Apsmode_Printers[setup].copy_of = pid_in; return; } %}}} %!%+ %\function{jed_date_time} %\synopsis{create a Date/Time string} %\usage{String_Type jed_date_time ()} %\description % This function is used to create Date/Time string to be used as value % for \var{aps_jeddatetime}. % This function returns a date/time string. % \example % aps_jeddatetime = jed_date_time(); % value of aps_jeddatetime will be "2004-Feb-29, 14:03:57" %!%- static define jed_date_time() %{{{ { return strftime("%Y-%b-%d, %H:%M:%S"); } %}}} %%%%%%%%%%%%%%%%%%%%% Menu Entries Begin %%%%%%%%%%%%%%%%%%%%%%% %{{{ % append a new popup to menu and return the handle static define new_popup(menu, popup) { menu_append_popup(menu, popup); return strcat(menu, ".", popup); } % pad a string to get nice collum line up in the menus static define create_menu_string (menu_string, value) { variable menu_entry; % & will be used to highlight a menu letter % so do not take its length into account if (is_substr(menu_string, "&")) { menu_string = sprintf("%-19s(",menu_string); } else { menu_string = sprintf("%-18s(",menu_string); } value = str_delete_chars(value,"\."); if (strlen(value) > 12) { menu_entry = strcat(menu_string, substr(value,1,12), " >>)"); } else { menu_entry = strcat(menu_string, value, ")"); } return menu_entry; } static define default_printer_callback (popup) { menu_append_item (popup, string(Apsmode_Printers[Apsmode_default_printer].setupname), strcat("show_printer_settings(",string(Apsmode_default_printer),",1)")); } define show_default_printer_menu(setting, menu) { eval(setting); menu_select_menu(strcat(Apsmode_menu, menu)); } static define set_default_printer_callback (popup) { variable i; for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (i == Apsmode_default_printer) { menu_append_item (popup, strcat("* ", sprintf("%2s ",string(i)), Apsmode_Printers[i].setupname), strcat("show_default_printer_menu(\"set_default_printer(", string(i),")\",)")); } else { menu_append_item (popup, strcat(" ", sprintf("%2s ",string(i)), Apsmode_Printers[i].setupname), strcat("show_default_printer_menu(\"set_default_printer(", string(i),")\",\"\")")); } } } return; } static define show_default_printer_callback (popup) { variable i; for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (i == Apsmode_default_printer) { menu_append_item (popup, strcat("* ", sprintf("%2s ",string(i)), string(Apsmode_Printers[i].setupname)), strcat("show_printer_settings(",string(i),",1)")); } else { menu_append_item (popup, strcat(" ", sprintf("%2s ",string(i)), string(Apsmode_Printers[i].setupname)), strcat("show_printer_settings(",string(i),",1)")); } } } return; } %!%+ %\function{set_qp} %\synopsis{execute QuickPrint settings from menu} %\usage{set_qp (String_Type setting)} %\description % This function is used to define new settings for QuickPrint. % \var{setting} is a string containing slang-code, which % will be executed by this function. % \var{setting} will be defined via menu entries. % This function returns nothing, but opens the QuickPrint menu again % \example % The following command appends a menu item (called "A4") % Clicking on that item will execute the code % "Apsmode_Printers[0].medium=\"A4\"" % menu_append_item (popup, strcat("* ", "A&4"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A4\\\"\")")); %!%- define set_qp(setting) { eval(setting); % intention is to open QuickPrint menu again menu_select_menu(strcat(Apsmode_menu, ".&QuickPrint")); return; } static define set_qp_orientation_callback (popup) { if (strup(Apsmode_Printers[0].orientation) == "PORTRAIT") { menu_append_item (popup, strcat("* ", "&portrait"), strcat("set_qp(\"Apsmode_Printers[0].orientation=\\\"portrait\\\"\")")); menu_append_item (popup, strcat(" ", "&landscape"), strcat("set_qp(\"Apsmode_Printers[0].orientation=\\\"landscape\\\"\")")); } if (strup(Apsmode_Printers[0].orientation) == "LANDSCAPE") { menu_append_item (popup, strcat(" ", "&portrait"), strcat("set_qp(\"Apsmode_Printers[0].orientation=\\\"portrait\\\"\")")); menu_append_item (popup, strcat("* ", "&landscape"), strcat("set_qp(\"Apsmode_Printers[0].orientation=\\\"landscape\\\"\")")); } return; } static define set_qp_no_columns_callback (popup) { variable i; for (i = 1; i <= 4; i++) { if (Apsmode_Printers[0].columns == string(i)) { menu_append_item (popup, strcat("* ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].columns=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].columns=\\\"", string(i), "\\\"\")")); } } return; } static define set_qp_no_rows_callback (popup) { variable i; for (i = 1; i <= 4; i++) { if (Apsmode_Printers[0].rows == string(i)) { menu_append_item (popup, strcat("* ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].rows=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].rows=\\\"", string(i), "\\\"\")")); } } return; } static define set_qp_no_sides_callback (popup) { variable i; for (i = 1; i <= 2; i++) { if (Apsmode_Printers[0].sides == string(i)) { menu_append_item (popup, strcat("* ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].sides=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].sides=\\\"", string(i), "\\\"\")")); } } return; } static define set_qp_borders_callback (popup) { if (strup(Apsmode_Printers[0].borders) == "ON") { menu_append_item (popup, strcat("* ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].borders=\\\"on\\\"\")")); menu_append_item (popup, strcat(" ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].borders=\\\"off\\\"\")")); } if (strup(Apsmode_Printers[0].borders) == "OFF") { menu_append_item (popup, strcat(" ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].borders=\\\"on\\\"\")")); menu_append_item (popup, strcat("* ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].borders=\\\"off\\\"\")")); } return; } static define set_qp_no_copies_callback (popup) { variable i; for (i = 1; i <= 10; i++) { if (Apsmode_Printers[0].copies == string(i)) { menu_append_item (popup, strcat("* ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].copies=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].copies=\\\"", string(i), "\\\"\")")); } } return; } static define set_qp_linenumbers_callback (popup) { variable i; for (i = 0; i <= 10; i++) { if (Apsmode_Printers[0].linenumbers == string(i)) { menu_append_item (popup, strcat("* ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].linenumbers=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i)), strcat("set_qp(\"Apsmode_Printers[0].linenumbers=\\\"", string(i), "\\\"\")")); } } return; } static define set_qp_truncate_callback (popup) { if (strup(Apsmode_Printers[0].truncate) == "ON") { menu_append_item (popup, strcat("* ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].truncate=\\\"on\\\"\")")); menu_append_item (popup, strcat(" ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].truncate=\\\"off\\\"\")")); } if (strup(Apsmode_Printers[0].truncate) == "OFF") { menu_append_item (popup, strcat(" ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].truncate=\\\"on\\\"\")")); menu_append_item (popup, strcat("* ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].truncate=\\\"off\\\"\")")); } return; } static define set_qp_medium_callback (popup) { if (strup(Apsmode_Printers[0].medium) == "A4") { menu_append_item (popup, strcat("* ", "A&4"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A4\\\"\")")); menu_append_item (popup, strcat(" ", "A&3"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A3\\\"\")")); menu_append_item (popup, strcat(" ", "&Letter"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"Letter\\\"\")")); } if (strup(Apsmode_Printers[0].medium) == "A3") { menu_append_item (popup, strcat(" ", "A&4"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A4\\\"\")")); menu_append_item (popup, strcat("* ", "A&3"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A3\\\"\")")); menu_append_item (popup, strcat(" ", "&Letter"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"Letter\\\"\")")); } if (strup(Apsmode_Printers[0].medium) == "LETTER") { menu_append_item (popup, strcat(" ", "A&4"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A4\\\"\")")); menu_append_item (popup, strcat(" ", "A&3"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"A3\\\"\")")); menu_append_item (popup, strcat("* ", "&Letter"), strcat("set_qp(\"Apsmode_Printers[0].medium=\\\"Letter\\\"\")")); } return; } static define set_qp_color_callback (popup) { if (strup(Apsmode_Printers[0].color) == "BW") { menu_append_item (popup, strcat("* ", "&bw"), strcat("set_qp(\"Apsmode_Printers[0].color=\\\"bw\\\"\")")); menu_append_item (popup, strcat(" ", "&color"), strcat("set_qp(\"Apsmode_Printers[0].color=\\\"color\\\"\")")); } if (strup(Apsmode_Printers[0].color) == "COLOR") { menu_append_item (popup, strcat(" ", "&bw"), strcat("set_qp(\"Apsmode_Printers[0].color=\\\"bw\\\"\")")); menu_append_item (popup, strcat("* ", "&color"), strcat("set_qp(\"Apsmode_Printers[0].color=\\\"color\\\"\")")); } return; } static define set_qp_printer_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter print command\\\",\\\"", Apsmode_Printers[0].print_cmd,"\\\",\\\"", Apsmode_Printers[0].print_cmd,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].print_cmd=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Print Command", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[0].print_cmd == Apsmode_Printers[i].print_cmd) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].print_cmd), strcat("set_qp(\"Apsmode_Printers[0].print_cmd=\\\"", Apsmode_Printers[i].print_cmd, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].print_cmd), strcat("set_qp(\"Apsmode_Printers[0].print_cmd=\\\"", Apsmode_Printers[i].print_cmd, "\\\"\")")); } } } return; } static define set_qp_view_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter view command\\\",\\\"", Apsmode_Printers[0].view_cmd,"\\\",\\\"", Apsmode_Printers[0].view_cmd,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].view_cmd=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary View Command", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[0].view_cmd == Apsmode_Printers[i].view_cmd) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].view_cmd), strcat("set_qp(\"Apsmode_Printers[0].view_cmd=\\\"", Apsmode_Printers[i].view_cmd, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].view_cmd), strcat("set_qp(\"Apsmode_Printers[0].view_cmd=\\\"", Apsmode_Printers[i].view_cmd, "\\\"\")")); } } } return; } static define set_qp_header_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter header string\\\",\\\"", Apsmode_Printers[0].header,"\\\",\\\"", Apsmode_Printers[0].header,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].header=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Header String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].header != "") { if (Apsmode_Printers[0].header == Apsmode_Printers[i].header) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].header), strcat("set_qp(\"Apsmode_Printers[0].header=\\\"", Apsmode_Printers[i].header, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].header), strcat("set_qp(\"Apsmode_Printers[0].header=\\\"", Apsmode_Printers[i].header, "\\\"\")")); } } } } return; } static define set_qp_title_left_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Left Title string\\\",\\\"", Apsmode_Printers[0].title_left,"\\\",\\\"", Apsmode_Printers[0].title_left,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].title_left=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Left Title String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].title_left != "") { if (Apsmode_Printers[0].title_left == Apsmode_Printers[i].title_left) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].title_left), strcat("set_qp(\"Apsmode_Printers[0].title_left=\\\"", Apsmode_Printers[i].title_left, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].title_left), strcat("set_qp(\"Apsmode_Printers[0].title_left=\\\"", Apsmode_Printers[i].title_left, "\\\"\")")); } } } } return; } static define set_qp_title_center_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Center Title string\\\",\\\"", Apsmode_Printers[0].title_center,"\\\",\\\"", Apsmode_Printers[0].title_center,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].title_center=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Center Title String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].title_center != "") { if (Apsmode_Printers[0].title_center == Apsmode_Printers[i].title_center) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].title_center), strcat("set_qp(\"Apsmode_Printers[0].title_center=\\\"", Apsmode_Printers[i].title_center, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].title_center), strcat("set_qp(\"Apsmode_Printers[0].title_center=\\\"", Apsmode_Printers[i].title_center, "\\\"\")")); } } } } return; } static define set_qp_title_right_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Right Title string\\\",\\\"", Apsmode_Printers[0].title_right,"\\\",\\\"", Apsmode_Printers[0].title_right,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].title_right=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Right Title String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].title_right != "") { if (Apsmode_Printers[0].title_right == Apsmode_Printers[i].title_right) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].title_right), strcat("set_qp(\"Apsmode_Printers[0].title_right=\\\"", Apsmode_Printers[i].title_right, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].title_right), strcat("set_qp(\"Apsmode_Printers[0].title_right=\\\"", Apsmode_Printers[i].title_right, "\\\"\")")); } } } } return; } static define set_qp_footer_left_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Left Footer string\\\",\\\"", Apsmode_Printers[0].footer_left,"\\\",\\\"", Apsmode_Printers[0].footer_left,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].footer_left=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Left Footer String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].footer_left != "") { if (Apsmode_Printers[0].footer_left == Apsmode_Printers[i].footer_left) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].footer_left), strcat("set_qp(\"Apsmode_Printers[0].footer_left=\\\"", Apsmode_Printers[i].footer_left, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].footer_left), strcat("set_qp(\"Apsmode_Printers[0].footer_left=\\\"", Apsmode_Printers[i].footer_left, "\\\"\")")); } } } } return; } static define set_qp_footer_center_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Center Footer string\\\",\\\"", Apsmode_Printers[0].footer_center,"\\\",\\\"", Apsmode_Printers[0].footer_center,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].footer_center=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Center Footer String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].footer_center != "") { if (Apsmode_Printers[0].footer_center == Apsmode_Printers[i].footer_center) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].footer_center), strcat("set_qp(\"Apsmode_Printers[0].footer_center=\\\"", Apsmode_Printers[i].footer_center, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].footer_center), strcat("set_qp(\"Apsmode_Printers[0].footer_center=\\\"", Apsmode_Printers[i].footer_center, "\\\"\")")); } } } } return; } static define set_qp_footer_right_callback (popup) { variable i; variable action; action = strcat("read_mini\\\(\\\"Enter Right Footer string\\\",\\\"", Apsmode_Printers[0].footer_right,"\\\",\\\"", Apsmode_Printers[0].footer_right,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].footer_right=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Add temporary Right Footer String", action); for (i = 0; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[i].footer_right != "") { if (Apsmode_Printers[0].footer_right == Apsmode_Printers[i].footer_right) { menu_append_item (popup, strcat("* ", Apsmode_Printers[i].footer_right), strcat("set_qp(\"Apsmode_Printers[0].footer_right=\\\"", Apsmode_Printers[i].footer_right, "\\\"\")")); } else { menu_append_item (popup, strcat(" ", Apsmode_Printers[i].footer_right), strcat("set_qp(\"Apsmode_Printers[0].footer_right=\\\"", Apsmode_Printers[i].footer_right, "\\\"\")")); } } } } return; } static define set_qp_is_copy_of_callback (popup) { variable i; for (i = 1; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { if (Apsmode_Printers[0].copy_of == i) { menu_append_item (popup, strcat("* ", sprintf("%2s ",string(i)), Apsmode_Printers[i].setupname), strcat("set_qp(\"qp_is_copy_of(", string(i), ")\")")); } else { menu_append_item (popup, strcat(" ", sprintf("%2s ",string(i)), Apsmode_Printers[i].setupname), strcat("set_qp(\"qp_is_copy_of(", string(i), ")\")")); } } } return; } static define set_qp_fontsize_callback (popup) { variable i; variable increment = 1; if (Apsmode_Printers[0].fontsize == "none") { menu_append_item (popup, strcat("* ", "don't care"), strcat("set_qp(\"Apsmode_Printers[0].fontsize=\\\"", "none", "\\\"\")")); } else { menu_append_item (popup, strcat(" ", "don't care"), strcat("set_qp(\"Apsmode_Printers[0].fontsize=\\\"", "none", "\\\"\")")); } % add fontsize in points for (i = 6; i <= 72; i = i + increment) { if (Apsmode_Printers[0].fontsize == strcat(string(i), "points")) { menu_append_item (popup, strcat("* ", string(i), "points"), strcat("set_qp(\"Apsmode_Printers[0].fontsize=\\\"", string(i), "points", "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i), "points"), strcat("set_qp(\"Apsmode_Printers[0].fontsize=\\\"", string(i), "points", "\\\"\")")); } if ( i == 12) { increment = 2; } if ( i == 28) { increment = 8; } if ( i == 36) { increment = 12; } if ( i == 48) { increment = 24; } } return; } static define set_qp_max_chars_callback (popup) { variable action; action = strcat("read_mini\\\(\\\"Enter min:max characters\\\",\\\"", Apsmode_Printers[0].chars,"\\\",\\\"", Apsmode_Printers[0].chars,"\\\"\\\)"); action = strcat("Apsmode_Printers[0].chars=", action); action = strcat("set_qp(\"", action, "\")"); menu_append_item (popup, "&Change Max Characters", action); menu_append_item (popup, "0:80", strcat("set_qp(\"Apsmode_Printers[0].chars=\\\"0:80\\\"\")")); menu_append_item (popup, "0:100", strcat("set_qp(\"Apsmode_Printers[0].chars=\\\"0:100\\\"\")")); menu_append_item (popup, "0:132", strcat("set_qp(\"Apsmode_Printers[0].chars=\\\"0:132\\\"\")")); menu_append_item (popup, "80:100", strcat("set_qp(\"Apsmode_Printers[0].chars=\\\"80:100\\\"\")")); menu_append_item (popup, "80:132", strcat("set_qp(\"Apsmode_Printers[0].chars=\\\"80:132\\\"\")")); return; } static define set_qp_margin_callback (popup) { variable i; variable increment = 1; % add margin in points for (i = 0; i <= 12; i = i + increment) { if (Apsmode_Printers[0].margin == string(i)) { menu_append_item (popup, strcat("* ", string(i), " points"), strcat("set_qp(\"Apsmode_Printers[0].margin=\\\"", string(i), "\\\"\")")); } else { menu_append_item (popup, strcat(" ", string(i), " points"), strcat("set_qp(\"Apsmode_Printers[0].margin=\\\"", string(i), "\\\"\")")); } % this code has been left here in case of more than 12 points needed. if ( i == 12) { increment = 2; } if ( i == 28) { increment = 8; } if ( i == 36) { increment = 12; } if ( i == 48) { increment = 24; } } return; } static define set_qp_major_callback (popup) { if (strup(Apsmode_Printers[0].major) == "COLUMNS") { menu_append_item (popup, strcat("* ", "&columns"), strcat("set_qp(\"Apsmode_Printers[0].major=\\\"columns\\\"\")")); menu_append_item (popup, strcat(" ", "&rows"), strcat("set_qp(\"Apsmode_Printers[0].major=\\\"rows\\\"\")")); } if (strup(Apsmode_Printers[0].major) == "ROWS") { menu_append_item (popup, strcat(" ", "&columns"), strcat("set_qp(\"Apsmode_Printers[0].major=\\\"columns\\\"\")")); menu_append_item (popup, strcat("* ", "&rows"), strcat("set_qp(\"Apsmode_Printers[0].major=\\\"rows\\\"\")")); } return; } static define set_qp_pretty_callback (popup) { if (strup(Apsmode_Printers[0].pretty) == "ON") { menu_append_item (popup, strcat("* ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].pretty=\\\"on\\\"\")")); menu_append_item (popup, strcat(" ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].pretty=\\\"off\\\"\")")); } if (strup(Apsmode_Printers[0].pretty) == "OFF") { menu_append_item (popup, strcat(" ", "o&n"), strcat("set_qp(\"Apsmode_Printers[0].pretty=\\\"on\\\"\")")); menu_append_item (popup, strcat("* ", "o&ff"), strcat("set_qp(\"Apsmode_Printers[0].pretty=\\\"off\\\"\")")); } return; } static define set_qp_context_callback (popup) { variable menu_entry = ""; % QuickPrint settings (as copy of Apsmode_default_printer) % if not yet defined if (Apsmode_Printers[0].orientation == NULL) { qp_is_copy_of(Apsmode_default_printer); } % Orientation menu_entry = strcat("&Orientation (", Apsmode_Printers[0].orientation, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_orientation_callback); % Paper Format menu_entry = strcat("&Paper Format (", Apsmode_Printers[0].medium, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_medium_callback); % Number of columns menu_entry = strcat("Number of &Columns (", Apsmode_Printers[0].columns, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_no_columns_callback); % Number of rows menu_entry = strcat("Number of &Rows (", Apsmode_Printers[0].rows, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_no_rows_callback); % 2 Sides menu_entry = strcat("2 &Sides (", Apsmode_Printers[0].sides, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_no_sides_callback); % Copies menu_entry = strcat("Cop&ies (", Apsmode_Printers[0].copies, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_no_copies_callback); menu_append_separator (popup); % Fontsize menu_entry = strcat("&Fontsize (", Apsmode_Printers[0].fontsize, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_fontsize_callback); % Max Characters menu_entry = strcat("&Max Characters (", Apsmode_Printers[0].chars, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_max_chars_callback); % Truncate Lines menu_entry = strcat("&Truncate Lines (", Apsmode_Printers[0].truncate, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_truncate_callback); % Linenumbers menu_entry = strcat("Line&numbers (", Apsmode_Printers[0].linenumbers, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_linenumbers_callback); menu_append_separator (popup); % Borders menu_entry = strcat("&Borders (", Apsmode_Printers[0].borders, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_borders_callback); % Margin menu_entry = strcat("M&argin (", Apsmode_Printers[0].margin, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_margin_callback); % Major Print Direction menu_entry = strcat("Print &Direction (", Apsmode_Printers[0].major, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_major_callback); % Color menu_entry = strcat("Co&lor (", Apsmode_Printers[0].color, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_color_callback); % Pretty Printing menu_entry = strcat("Pr&etty Printing (", Apsmode_Printers[0].pretty, ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_pretty_callback); menu_append_separator (popup); % Header menu_entry = create_menu_string ("&Header", Apsmode_Printers[0].header); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_header_callback); % Title Left menu_entry = create_menu_string ("Title Left", Apsmode_Printers[0].title_left); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_title_left_callback); % Title Center menu_entry = create_menu_string ("Title Center", Apsmode_Printers[0].title_center); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_title_center_callback); % Title Right menu_entry = create_menu_string ("Title Right", Apsmode_Printers[0].title_right); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_title_right_callback); % Footer Left menu_entry = create_menu_string ("Footer Left", Apsmode_Printers[0].footer_left); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_footer_left_callback); % Footer Center menu_entry = create_menu_string ("Footer Center", Apsmode_Printers[0].footer_center); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_footer_center_callback); % Footer Right menu_entry = create_menu_string ("Footer Right", Apsmode_Printers[0].footer_right); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_footer_right_callback); menu_append_separator (popup); % Print Command menu_entry = create_menu_string ("Pri&nt Command", Apsmode_Printers[0].print_cmd); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_printer_callback); % View Command menu_entry = create_menu_string ("&View Command", Apsmode_Printers[0].view_cmd); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_view_callback); menu_append_separator (popup); % QP is copy of menu_entry = strcat("Set QP as Cop&y of setup (", string(Apsmode_Printers[0].copy_of), ")"); menu_append_popup (popup, menu_entry); menu_set_select_popup_callback (strcat (popup, strcat(".", menu_entry)), &set_qp_is_copy_of_callback); % set QP as default printer, if necessary if (Apsmode_default_printer != 0) { menu_append_item (popup, "Set QP as default printer", strcat("show_default_printer_menu(\"set_default_printer(0)\",\".&QuickPrint\")")); } else { menu_append_item (popup, "QP is default printer", strcat("show_default_printer_menu(\"set_default_printer(0)\",\".&QuickPrint\")")); } return; } % populate the Print menu popup when opened public define apsmode_menu_callback(menu) { variable popup; % name of sub popups menu_append_item(menu, "Print &Buffer", "print_buffer"); menu_append_item(menu, "Print &Region", "print_region"); menu_append_separator(menu); menu_append_item(menu, "Print B&uffer Preview", "print_buffer_preview"); menu_append_item(menu, "Print R&egion Preview", "print_region_preview"); menu_append_separator(menu); if (Apsmode_default_printer == 0) popup = new_popup(menu, "Show &Default Printer (QuickPrint)"); else popup = new_popup(menu, sprintf("Show &Default Printer (setup %d)", Apsmode_default_printer)); menu_set_select_popup_callback(popup, &default_printer_callback); popup = new_popup(menu, "Set Default &Printer"); menu_set_select_popup_callback(popup, &set_default_printer_callback); menu_append_separator(menu); % add the context sensitive QuickPrint entries popup = new_popup(menu, "&QuickPrint"); menu_set_select_popup_callback(popup, &set_qp_context_callback); menu_append_separator(menu); popup = new_popup(menu, "Show Printer &Settings"); menu_set_select_popup_callback(popup, &show_default_printer_callback); menu_append_item(menu, "Show Print &Logfile", "show_print_log()"); menu_append_separator(menu); menu_append_item(menu, "Current Settings in apsconf format", strcat("show_printer_settings(\"default\",2)")); menu_append_item(menu, "&Create Style Sheet", "create_a2ps_style_sheet(\"\")"); menu_append_separator(menu); menu_append_item(menu, "Show apsmode Settings", "show_apsmode_settings()"); menu_append_item(menu, "&Help apsmode", "aps_help"); popup = new_popup(menu, "&About apsmode"); menu_append_item(popup, "apsmode", "menu_select_menu(Apsmode_menu)"); menu_append_item(popup, strcat("Version ", aps_version), "menu_select_menu(Apsmode_menu)"); menu_append_item(popup, strcat("created ", aps_creation_date), "menu_select_menu(Apsmode_menu)"); %menu_append_item(popup, strcat("by ", aps_creator), "menu_select_menu(Apsmode_menu)"); menu_append_item(popup, strcat("tested with JED ", aps_jed_tested), "menu_select_menu(Apsmode_menu)"); } %%%%%%%%%%%%%%%%%%%%% Menu Entries End %%%%%%%%%%%%%%%%%%%%%%% %}}} %!%+ %\function{get_a2ps_cmd} %\synopsis{create a2ps command} %\usage{String_Type get_a2ps_cmd (Integer_Type id, Integer_Type max_char)} %\description % This function is used to create an a2ps command, which will be used later to % create a postscript file. % \var{id} will be used as index for the \var{printer}-array. Values of this % array will be taken to create the a2ps command. % \var{max_char} defines the maximum number of characters per line in % the printout. % This function returns the a2ps command. %!%- static define get_a2ps_cmd(id, max_char) %{{{ { variable cmd = strcat(Apsmode_a2ps_cmd, " "); variable no_header = ""; variable chars = Integer_Type [2]; cmd = strcat(cmd, " --output=", Apsmode_tmp_file); cmd = strcat(cmd, " --columns=", Apsmode_Printers[id].columns); cmd = strcat(cmd, " --rows=", Apsmode_Printers[id].rows); % now determine , how much characters have to be printed per line % first extract min/max values from printer setting chars = strchop(Apsmode_Printers[id].chars,':',0); switch (max_char) { max_char < integer(chars[0]) : cmd = strcat(cmd, " --chars-per-line=", string(chars[0])); } { max_char > integer(chars[1]) : cmd = strcat(cmd, " --chars-per-line=", string(chars[1])); } { cmd = strcat(cmd, " --chars-per-line=", string(max_char)); }; if (Apsmode_Printers[id].fontsize != "none") { cmd = strcat(cmd, " --font-size=", Apsmode_Printers[id].fontsize); } cmd = strcat(cmd, " --borders=", Apsmode_Printers[id].borders); cmd = strcat(cmd, " --", Apsmode_Printers[id].orientation); cmd = strcat(cmd, " --medium=", Apsmode_Printers[id].medium); cmd = strcat(cmd, " --sides=", Apsmode_Printers[id].sides); cmd = strcat(cmd, " --truncate-line=", Apsmode_Printers[id].truncate); cmd = strcat(cmd, " --line-numbers=", Apsmode_Printers[id].linenumbers); cmd = strcat(cmd, " --copies=", Apsmode_Printers[id].copies); cmd = strcat(cmd, " --major=", Apsmode_Printers[id].major); cmd = strcat(cmd, " --margin=", Apsmode_Printers[id].margin); % string settings must be differently defined for UNIX and Windows % Windows needs some extra \\ for hashing, otherwise only parts of % the defined strings will be considered #ifdef UNIX if ( Apsmode_Printers[id].header != "" ) { cmd = strcat(cmd, " --header=\"", Apsmode_Printers[id].header, "\""); no_header = "1"; } if ( Apsmode_Printers[id].title_left != "" ) { cmd = strcat(cmd, " --left-title=\"", Apsmode_Printers[id].title_left, "\""); no_header = "1"; } if ( Apsmode_Printers[id].title_center != "" ) { cmd = strcat(cmd, " --center-title=\"", Apsmode_Printers[id].title_center, "\""); no_header = "1"; } if ( Apsmode_Printers[id].title_right != "" ) { cmd = strcat(cmd, " --right-title=\"", Apsmode_Printers[id].title_right, "\""); no_header = "1"; } if (no_header == "") { cmd = strcat(cmd, " --no-header"); } if ( Apsmode_Printers[id].footer_left != "" ) { cmd = strcat(cmd, " --left-footer=\"", Apsmode_Printers[id].footer_left, "\""); } if ( Apsmode_Printers[id].footer_center != "" ) { cmd = strcat(cmd, " --footer=\"", Apsmode_Printers[id].footer_center, "\""); } if ( Apsmode_Printers[id].footer_right != "" ) { cmd = strcat(cmd, " --right-footer=\"", Apsmode_Printers[id].footer_right, "\""); } #endif #ifdef MSWINDOWS if ( Apsmode_Printers[id].header != "" ) { cmd = strcat(cmd, " --header=\\\"", Apsmode_Printers[id].header, "\\\""); no_header = "1"; } if ( Apsmode_Printers[id].title_left != "" ) { cmd = strcat(cmd, " --left-title=\\\"", Apsmode_Printers[id].title_left, "\\\""); no_header = "1"; } if ( Apsmode_Printers[id].title_center != "" ) { cmd = strcat(cmd, " --center-title=\\\"", Apsmode_Printers[id].title_center, "\\\""); no_header = "1"; } if ( Apsmode_Printers[id].title_right != "" ) { cmd = strcat(cmd, " --right-title=\\\"", Apsmode_Printers[id].title_right, "\\\""); no_header = "1"; } if (no_header == "") { cmd = strcat(cmd, " --no-header"); } if ( Apsmode_Printers[id].footer_left != "" ) { cmd = strcat(cmd, " --left-footer=\\\"", Apsmode_Printers[id].footer_left, "\\\""); } if ( Apsmode_Printers[id].footer_center != "" ) { cmd = strcat(cmd, " --footer=\\\"", Apsmode_Printers[id].footer_center, "\\\""); } if ( Apsmode_Printers[id].footer_right != "" ) { cmd = strcat(cmd, " --right-footer=\\\"", Apsmode_Printers[id].footer_right, "\\\""); } #endif cmd = strcat(cmd, " --prologue=", Apsmode_Printers[id].color); % pretty-print must be the last entry to have a chance to append % local a2ps style sheet later if (strup(Apsmode_Printers[id].pretty) == "ON") { cmd = strcat(cmd, " --pretty-print"); } else { cmd = strcat(cmd, " --pretty-print=\"plain\""); } % remove the placeholders for filename and date/time cmd = str_replace_all(cmd, "JEDFILENAME", aps_jedfilename); cmd = str_replace_all(cmd, "JEDDATETIME", aps_jeddatetime); return cmd; } %}}} %!%+ %\function{show_printer_settings} %\synopsis{show current printer settings} %\usage{show_printer_settings (String_Type/Integer_Type id, Integer_Type format)} %\description % This function is used to show the current printer settings in a % separate buffer. % \var{id} will be used as index for the \var{Apsmode_Printers}-array, which % contains the settings. Value "default" will use the settings of the currently % defined default printer. % \var{format} will be used to format the output either as % - human readable text or % - as configuration data for apsconf.sl % This function returns nothing. %!%- define show_printer_settings(id,format) %{{{ { variable bufname = strcat("*Printer-settings-for-Printer-", string(id), "*"); sw2buf(bufname); set_readonly(0); erase_buffer(); bob(); % set id to the default printer id (if requested) if (string(id) == "default") { id = Apsmode_default_printer; } % print settings in a readable format if (format == 1) { insert(sprintf("\nSettings for %s\n", Apsmode_Printers[id].setupname)); insert("==========================================\n\n"); insert("\nPrint options\n"); insert("------------------------------------------\n"); insert(sprintf("Printer Name : %s\n", Apsmode_Printers[id].name)); insert(sprintf("Printer Description : %s\n", Apsmode_Printers[id].description)); insert(sprintf("Number of Columns : %s\n", Apsmode_Printers[id].columns)); insert(sprintf("Number of Rows : %s\n", Apsmode_Printers[id].rows)); insert(sprintf("Fontsize : %s\n", Apsmode_Printers[id].fontsize)); insert(sprintf("Characters per Line : %s\n", Apsmode_Printers[id].chars)); insert(sprintf("Orientation : %s\n", Apsmode_Printers[id].orientation)); insert(sprintf("Paper Format : %s\n", Apsmode_Printers[id].medium)); insert(sprintf("One/Two Sides Print : %s\n", Apsmode_Printers[id].sides)); insert(sprintf("Truncate Lines : %s\n", Apsmode_Printers[id].truncate)); insert(sprintf("Number of copies : %s\n", Apsmode_Printers[id].copies)); insert(sprintf("Major Print Direction : %s\n", Apsmode_Printers[id].major)); insert(sprintf("\nPrint Linenumbers every %s row(s)\n", Apsmode_Printers[id].linenumbers)); insert("\nLayout options\n"); insert("------------------------------------------\n"); insert(sprintf("Print Borders : %s\n", Apsmode_Printers[id].borders)); insert(sprintf("Margin [points] : %s\n", Apsmode_Printers[id].margin)); insert(sprintf("Header : %s\n", Apsmode_Printers[id].header)); insert(sprintf("Left Title : %s\n", Apsmode_Printers[id].title_left)); insert(sprintf("Center Title : %s\n", Apsmode_Printers[id].title_center)); insert(sprintf("Right Title : %s\n", Apsmode_Printers[id].title_right)); insert(sprintf("Left Footer : %s\n", Apsmode_Printers[id].footer_left)); insert(sprintf("Center Footer : %s\n", Apsmode_Printers[id].footer_center)); insert(sprintf("Right Footer : %s\n", Apsmode_Printers[id].footer_right)); insert(sprintf("Color : %s\n", Apsmode_Printers[id].color)); insert(sprintf("Syntax Highlighting : %s\n", Apsmode_Printers[id].pretty)); insert("------------------------------------------\n\n"); insert("a2ps command:\n"); insert(get_a2ps_cmd(id,0)); insert("\n\n"); insert("print command:\n"); insert(Apsmode_Printers[id].print_cmd); insert("\n\n"); insert("view command:\n"); insert(Apsmode_Printers[id].view_cmd); insert("\n"); } % print settings in a apsconf format if (format == 2) { insert("% You can use this definition in your local apsconf.sl file.\n"); insert("% Don't forget to define a private variable 'setup'\n"); insert("% in your local apsconf file;\n"); insert("% private variable aps_id = 0;\n\n"); insert("setup++;\n"); insert(sprintf("Apsmode_Printers[setup].setupname = \"%s\";\n",Apsmode_Printers[id].setupname)); insert(sprintf("Apsmode_Printers[setup].name = \"%s\";\n",Apsmode_Printers[id].name)); insert(sprintf("Apsmode_Printers[setup].description = \"%s\";\n",Apsmode_Printers[id].description)); insert(sprintf("Apsmode_Printers[setup].columns = \"%s\";\n",Apsmode_Printers[id].columns)); insert(sprintf("Apsmode_Printers[setup].rows = \"%s\";\n",Apsmode_Printers[id].rows)); insert(sprintf("Apsmode_Printers[setup].fontsize = \"%s\";\n",Apsmode_Printers[id].fontsize)); insert(sprintf("Apsmode_Printers[setup].chars = \"%s\";\n",Apsmode_Printers[id].chars)); insert(sprintf("Apsmode_Printers[setup].borders = \"%s\";\n",Apsmode_Printers[id].borders)); insert(sprintf("Apsmode_Printers[setup].orientation = \"%s\";\n",Apsmode_Printers[id].orientation)); insert(sprintf("Apsmode_Printers[setup].medium = \"%s\";\n",Apsmode_Printers[id].medium)); insert(sprintf("Apsmode_Printers[setup].sides = \"%s\";\n",Apsmode_Printers[id].sides)); insert(sprintf("Apsmode_Printers[setup].truncate = \"%s\";\n",Apsmode_Printers[id].truncate)); insert(sprintf("Apsmode_Printers[setup].linenumbers = \"%s\";\n",Apsmode_Printers[id].linenumbers)); insert(sprintf("Apsmode_Printers[setup].copies = \"%s\";\n",Apsmode_Printers[id].copies)); insert(sprintf("Apsmode_Printers[setup].major = \"%s\";\n",Apsmode_Printers[id].major)); insert(sprintf("Apsmode_Printers[setup].margin = \"%s\";\n",Apsmode_Printers[id].margin)); insert(sprintf("Apsmode_Printers[setup].header = \"%s\";\n",Apsmode_Printers[id].header)); insert(sprintf("Apsmode_Printers[setup].title_left = \"%s\";\n",Apsmode_Printers[id].title_left)); insert(sprintf("Apsmode_Printers[setup].title_center = \"%s\";\n",Apsmode_Printers[id].title_center)); insert(sprintf("Apsmode_Printers[setup].title_right = \"%s\";\n",Apsmode_Printers[id].title_right)); insert(sprintf("Apsmode_Printers[setup].footer_left = \"%s\";\n",Apsmode_Printers[id].footer_left)); insert(sprintf("Apsmode_Printers[setup].footer_center = \"%s\";\n",Apsmode_Printers[id].footer_center)); insert(sprintf("Apsmode_Printers[setup].footer_right = \"%s\";\n",Apsmode_Printers[id].footer_right)); insert(sprintf("Apsmode_Printers[setup].color = \"%s\";\n",Apsmode_Printers[id].color)); insert(sprintf("Apsmode_Printers[setup].pretty = \"%s\";\n",Apsmode_Printers[id].pretty)); insert(sprintf("Apsmode_Printers[setup].print_cmd = \"%s\";\n",Apsmode_Printers[id].print_cmd)); insert(sprintf("Apsmode_Printers[setup].view_cmd = \"%s\";\n",Apsmode_Printers[id].view_cmd)); insert("Apsmode_Printers[setup].copy_of = 0;\n"); } set_buffer_modified_flag(0); set_readonly(1); bob(); return; } %}}} static define get_max_chars(file) %{{{ { % scan the input file and determine the maximum length of rows variable max = 0, col = 0; find_file(file); bob(); do { eol(); col = what_column(); if ( col > max) { max = col; } } while (down_1()); delbuf(whatbuf()); return max; } %}}} %!%+ %\function{print_log} %\synopsis{log a string in print log buffer} %\usage{print_log (String_Type prompt, String_Type string_in)} %\description % This function is used to log the given \var{string_in} into the current % buffer. % \var{prompt} will be used as prompt (or identifier) of \var{string_in}. % This function returns nothing. %!%- static define print_log(prompt, string_in) %{{{ { variable string_out = strcat(string(prompt), " : ", string(string_in), "\n"); insert(string_out); return; } %}}} %!%+ %\function{show_print_log} %\synopsis{show print log buffer} %\usage{show_print_log ()} %\description % This function is used to switch to the print log buffer % This function returns nothing. %!%- define show_print_log() %{{{ { sw2buf ("*print-output*"); return; } %}}} %!%+ %\function{show_apsmode_settings} %\synopsis{show apsmode settings} %\usage{show_apsmode_settings ()} %\description % This function is used to show some apsmode settings, e.g. global variables % This function returns nothing. %!%- define show_apsmode_settings() %{{{ { variable key = ""; variable keys = ""; variable use_style = 0; variable i = 0; variable printer_count = 0; jed_easy_help(""); set_buffer_modified_flag(0); erase_buffer(); insert("Global Variables\n----------------\n"); print_log("Apsmode_a2ps_cmd ",Apsmode_a2ps_cmd); print_log("Apsmode_default_printer",Apsmode_default_printer); print_log("Apsmode_del_ps_file ",Apsmode_del_ps_file); print_log("Apsmode_menu ",Apsmode_menu); print_log("Apsmode_tmp_dir ",Apsmode_tmp_dir); print_log("Apsmode_tmp_file ",Apsmode_tmp_file); insert("\n\napsmode Settings\n----------------\n"); print_log("apsmode File ", expand_jedlib_file("apsmode.sl")); print_log("apsmode Help ", expand_jedlib_file("apsmode.hlp")); % i= 0 is for Quickprint and will therefore not be counted for (i = 1; i <= aps_max_no_printers-1; i++) { if (Apsmode_Printers[i].setupname != NULL) { printer_count ++; } } print_log("No Printer Setups", printer_count); insert("\n\nStyle Sheets\n------------\n"); keys = assoc_get_keys (Apsmode_style_sheet); keys = keys[array_sort (keys)]; foreach (keys) { key = (); use_style = Apsmode_style_sheet[key]; if (use_style == 1) { print_log(key, expand_jedlib_file(strcat(key, ".ssh"))); } } insert("\n\napsmode Version\n---------------\n"); print_log("apsmode Version", aps_version); print_log("Creation Date ", aps_creation_date); print_log("tested with jed", aps_jed_tested); insert("\n"); bob(); return; } %}}} %!%+ %\function{print_region} %\synopsis{print a defined region} %\usage{print_region ()} %\description % This function is the major function for printing/previewing. % It will create a postscript file from the marked region using the settings % in \var{Apsmode_Printers}-array. % Printing/Previewing will be determined via global variable \var{aps_preview}. % A marked region will stay highlighted after preview/printing. % This function returns nothing. %!%- define print_region() %{{{ { variable pfile; variable bufname; variable bufdir; variable buffile; variable file; variable msg; variable cmd; variable mode_name; variable sheet_file; variable max_char=0; variable rc; variable region_highlighted = is_visible_mark; variable redirect; if ( region_highlighted == 1) { narrow_to_region(); bob(); push_visible_mark(); eob(); } pfile = strcat(Apsmode_tmp_dir,"#"); % Find out the name of the buffer (buffile,bufdir,bufname,) = getbuf_info (); % if it is an internal buffer replace filename with buffer name if (buffile == "") { buffile = bufname; bufdir = ""; } % set aps_jedfilename variable aps_jedfilename = sprintf("%s%s", bufdir, buffile); #ifdef MSWINDOWS aps_jedfilename = str_replace_all(aps_jedfilename,"\\","\\\\"); #endif aps_jeddatetime = jed_date_time(); % extract mode name to check later, whether local a2ps style sheet % should be used mode_name = get_mode_name(); sheet_file = expand_jedlib_file(strcat(mode_name, ".ssh")); msg = sprintf("Formatting %s...", bufname); flush (msg); % Save region in temporary file named pfile pfile = strcat(pfile,bufname); % replace special characters in filename pfile = strtrans(pfile, " ","_"); pfile = strtrans(pfile, "*",""); pfile = strtrans(pfile, "<",""); pfile = strtrans(pfile, ">",""); pfile = strtrans(pfile, "(",""); pfile = strtrans(pfile, ")",""); write_region_to_file (pfile); max_char = get_max_chars(pfile); % switch to print-log buffer for logging purposes sw2buf ("*print-output*"); eob(); print_log("Max Chars ", max_char); % create the a2ps command cmd = get_a2ps_cmd(Apsmode_default_printer, max_char); if (strup(Apsmode_Printers[Apsmode_default_printer].pretty) == "ON") { print_log("Pretty Print Mode", mode_name); % now check whether jed-created a2ps style sheets should be used % if yes append them to "pretty-print=jed-style.ssh" if ( assoc_key_exists (Apsmode_style_sheet, mode_name) == 1 ) { print_log("Sheet File", sheet_file); if (file_status(sheet_file) == 1) { cmd = strcat(cmd, "=", sheet_file); } } } % Format the file by executing a2ps, creating a second temporary (ps) file cmd = strcat(cmd, " ", pfile); % do some logging print_log("a2ps cmd ", cmd); print_log("view cmd ", Apsmode_Printers[Apsmode_default_printer].view_cmd); print_log("print cmd ", Apsmode_Printers[Apsmode_default_printer].print_cmd); % use " 2>&1" to re-direct stderr as well #ifdef UNIX redirect = "2>&1"; #endif #ifdef MSWINDOWS redirect = ""; #endif insert ("\n--------------------- a2ps preprocessing --- (a2ps cmd) -------------------------\n"); rc = run_shell_cmd (sprintf ("%s %s", cmd, redirect)); insert ("--------------------------------------------------------------------------------\n\n"); % return code under MSWINDOWS seems not to work very well, always 0 ? % so error handling works only correct under UNIX if (rc == 0) { if (aps_preview == "on") { % View the temporary file insert ("\n--------------------- Viewing --- (view cmd) -------------------------\n"); msg = sprintf("Viewing %s...", bufname); flush(msg); rc = run_shell_cmd (sprintf ("%s %s", Apsmode_Printers[Apsmode_default_printer].view_cmd, redirect)); msg = sprintf("Viewing done (%s)", bufname); flush(msg); } else { % Print the temporary file insert ("\n--------------------- Printing --- (print cmd) -----------------------\n"); msg = sprintf("Printing %s...", bufname); flush(msg); rc = run_shell_cmd (sprintf ("%s %s", Apsmode_Printers[Apsmode_default_printer].print_cmd, redirect)); msg = sprintf("Printing done (%s --> %s)", bufname, Apsmode_Printers[Apsmode_default_printer].name); flush(msg); } } insert ("\n\n"); set_buffer_modified_flag(0); if (rc == 0) { % if all was ok, switch back to the original buffer sw2buf(bufname); % restore previous selection, if there was one if ( region_highlighted == 1) { bob(); push_visible_mark(); eob(); widen_region(); } } else { error ("An error occured!"); } % Clean up delete_file (pfile); if (Apsmode_del_ps_file = 1) { delete_file (Apsmode_tmp_file); } return; } %}}} %!%+ %\function{print_buffer} %\synopsis{print the buffer} %\usage{print_buffer ()} %\description % This function is called to print the whole buffer. It calls function % \var{print_region} for printing. % This function returns nothing. % \seealso{print_region} %!%- define print_buffer() %{{{ { aps_preview = "off"; push_spot (); mark_buffer (); print_region (); pop_spot (); } %}}} %!%+ %\function{print_buffer_preview} %\synopsis{print preview of the buffer} %\usage{print_buffer_preview ()} %\description % This function is called to preview the whole buffer. It sets variable % \var{aps_preview} to \var{on} and calls then function \var{print_region} % for previewing. After that \var{aps_preview} will be reset to \var{off}. % This function returns nothing. % \seealso{print_region} %!%- define print_buffer_preview() %{{{ { aps_preview = "on"; push_spot (); mark_buffer (); print_region (); pop_spot (); aps_preview = "off"; } %}}} %!%+ %\function{print_region_preview} %\synopsis{print preview of the marked region} %\usage{print_region_preview ()} %\description % This function is called to preview the marked region. It sets variable % \var{aps_preview} to \var{on} and calls then function \var{print_region} % for previewing. After that \var{aps_preview} will be reset to \var{off}. % This function returns nothing. % \seealso{print_region} %!%- define print_region_preview() %{{{ { aps_preview = "on"; print_region(); aps_preview = "off"; } %}}} %!%+ %\function{set_default_printer} %\synopsis{define default printer} %\usage{set_default_printer (Integer_Type id)} %\description % This function is called to set the default printer, which will be used % for preview/printing. % This function returns nothing. %!%- define set_default_printer(id) %{{{ { Apsmode_default_printer = id; } %}}} % taken from jed help for strchop() static define sort_string_list (a) %{{{ { variable i, b, c; b = strchop (a, ',', 0); i = array_sort (b, &strcmp); b = b[i]; % rearrange % Convert array back into comma separated form return strjoin (b, ","); } %}}} %!%+ %\function{extract_comment_definition} %\synopsis{scan a jed mode for comment definition} %\usage{extract_comment_definition (String_Type file)} %\description % This function is called to scan the given mode file (\var{file}) for % comment definition. It searches for the string "define syntax" and % extracts the comment definition. This definition will be used in % \var{create_a2ps_style_sheet} % This function returns the comment definition format for a2ps style sheets. % \example % SLang mode : define_syntax ("%", "", '%', $1); % return value : "%" Comment % \seealso{create_a2ps_style_sheet} %!%- static define extract_comment_definition(file) %{{{ { variable pos=0; variable syn=""; variable parts = String_Type[10]; variable nth = 0; variable part; variable comment_str = "", comment1, comment2; find_file(file); bob(); do { bol(); pos = ffind("define_syntax"); if (pos != 0) { syn = substr(line_as_string,pos+1, -1); parts = strchop(syn,',',0); nth = 0; while (NULL != extract_element (syn, nth, ',')) { nth++; } if (nth == 4) { part = extract_element (syn, 2, ','); part = strtrans(part, " ",""); if (strcmp(part,string("'%'")) == 0) { comment1 = extract_element (syn, 0, ','); comment1 = strtrans(comment1, " ",""); comment1 = strtrans(comment1, "(",""); comment2 = extract_element (syn, 1, ','); comment2 = strtrans(comment2, " ",""); if (strcmp(comment2,string("\"\"")) == 0) { comment2 = ""; } comment_str = strcat(comment_str, comment1, " Comment ", comment2, "\n"); } } } } while (down_1()); delbuf(whatbuf()); return comment_str; } %}}} %!%+ %\function{create_a2ps_style_sheet} %\synopsis{Create an a2ps style sheet from existing jed mode definition} %\usage{create_a2ps_style_sheet (String_Type mode)} %\description % This function is called to create an a2ps style sheet (*.ssh) for % a given (existing) jed mode. % % If \var{mode} is empty, the function will ask for a mode name. The modename % has to be exactly the string used for the syntax table definition of % the mode. % % Look for lines like (example for tcl mode): % $1 = "TCL"; % create_syntax_table ($1); % in the .sl file to catch the real mode name. % % The created style sheet will contain the a2ps style sheet header, % definition for comment lines and all keywords defined for the jedmode % (via define_keywords_n). %!%- define create_a2ps_style_sheet(mode) %{{{ { variable sheet_file; variable sheet_dir; variable kws, kws_str="", kws_substr=""; variable len; variable n=0; variable i, j; variable mode_file = ""; variable comment_str; if (mode == "") { mode = read_mini("Enter exact(!) mode name (e.g. TCL, SLang, awk)",get_mode_name,""); } % SLang mode uses syntax table SLANG (instead of SLang, % maybe to be changed in slmode.sl ?) % therefore sheet_file name has to be created before mode name modification % get a default sheet_dir from SLang.ssh sheet_dir = path_dirname(expand_jedlib_file("SLang.ssh")); sheet_file = strcat(mode, ".ssh"); % ask the user for the directory, where the new style sheet should be saved sheet_dir = read_with_completion(strcat("Enter directory for new style sheet (", sheet_file, "): "),"",sheet_dir,'f'); sheet_file = path_concat(sheet_dir, sheet_file); if (mode == "SLang") { mode = strup(mode); } #ifdef UNIX mode_file = strcat(JED_ROOT,"/lib/",mode,"mode.sl"); #endif #ifdef MSWINDOWS mode_file = strcat(JED_ROOT,"\\lib\\",mode,"mode.sl"); #endif mode_file = read_with_completion("Enter mode filename:","",mode_file,'f'); if (file_status(mode_file) != 1) { flush(strcat(mode_file, " does not exist!")); return; } % load mode_file, necessary for evaluation of syntax table % ERROR_BLOCK necessary, if a mode file couldn't be loaded two times ERROR_BLOCK { _clear_error(); } require(mode_file); comment_str = extract_comment_definition(mode_file); if (file_status(sheet_file) == 1) { if ( get_yes_no(strcat("Overwrite ", sheet_file)) == 0 ) { return; } } find_file(sheet_file); erase_buffer(); insert(strcat("# ", mode, ".ssh --- Sheet definitions for ", strup(mode), " scripts\n")); insert("# This style sheet is based on stylesheets provided by Edward Arthur, Akim Demaille, Miguel Santana\n"); insert("# Copyright (c) 1999 Edward Arthur, Akim Demaille, Miguel Santana\n"); insert("#\n"); insert("\n"); insert("#\n"); insert("# This file is not part of a2ps.\n"); insert("# It is automatically created from within jed using functions\n"); insert(strcat("# in apsmode.sl (V",aps_version, ").\n")); insert("#\n"); insert("# This program is free software; you can redistribute it and/or modify\n"); insert("# it under the terms of the GNU General Public License as published by\n"); insert("# the Free Software Foundation; either version 2, or (at your option)\n"); insert("# any later version.\n"); insert("#\n"); insert("# This program is distributed in the hope that it will be useful,\n"); insert("# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); insert("# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); insert("# GNU General Public License for more details.\n"); insert("#\n"); insert("# You should have received a copy of the GNU General Public License\n"); insert("# along with this program; see the file COPYING. If not, write to\n"); insert("# the Free Software Foundation, 59 Temple Place - Suite 330,\n"); insert("# Boston, MA 02111-1307, USA.\n"); insert("\n"); insert(strcat("## 1.0 ", get_realname(), "\n")); insert("# Initial implementation.\n"); insert("\n"); insert(strcat("style ", strup(mode), " is\n")); insert("\n"); insert(strcat("written by \"", get_realname(), ", ", get_emailaddress, "\"\n")); insert("version is 1.0\n"); insert("requires a2ps version 4.9.7\n"); insert("\n"); insert(" \n"); insert("\n"); insert("documentation is\n"); insert(strcat(" \"This style is devoted to the ", strup(mode), " language.\n")); insert(" It has been automatically created from within editor jed\n"); insert(strcat(" using apsmode.sl (V",aps_version, ")\"\n")); insert("end documentation\n"); insert("\n"); insert("alphabets are\n"); insert(" \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0\"\n"); insert("case sensitive\n"); insert("\n"); % if syntax table is not defined as it could happen for dfa highlighting % don't grep for keywords, otherwise it would lead to an error if (( NULL != what_syntax_table()) & ("DEFAULT" != what_syntax_table())) { insert("keywords in Keyword_strong are\n"); for (i = 1; i <= 30; i++) { kws = define_keywords_n (mode, "", i, n); len = strlen(kws); if (len > 0) { for (j = 1; j <= len; j=j+i) { kws_substr = substr(kws,j,i); % there are several keywords in a2ps keyword list, which % needs to be quoted switch (kws_substr) { kws_substr == "alphabet" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "alphabets" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "are" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "case" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "documentation" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "end" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "exceptions" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "first" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "in" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "insensitive" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "is" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "keywords" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "operators" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "optional" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "second" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "sensitive" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "sequences" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "style" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Comment" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Comment_strong" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Encoding" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Error" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Index1" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Index2" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Index3" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Index4" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Invisible" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Keyword" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Keyword_strong" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Label" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Label_strong" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Plain" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "String" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Symbol" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Tag1" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Tag2" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Tag3" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "Tag4" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "C-char" : kws_substr = strcat("\"", kws_substr, "\"");} { kws_substr == "C-string" : kws_substr = strcat("\"", kws_substr, "\"");}; if (kws_str == "") { kws_str = kws_substr; } else { kws_str = strcat(kws_str, ",", kws_substr); } } } } sort_string_list(kws_str); insert(kws_str); insert("\n"); insert("end keywords\n"); insert("\n"); } insert("sequences are\n"); insert(comment_str); insert("\n"); insert("end sequences\n"); insert("\n"); insert("end style\n"); bob(); return; } %}}} %!%+ %\function{aps_help} %\synopsis{apsmode help} %\usage{aps_help ()} %\description % This function opens the aps help file % This function returns nothing. %!%- define aps_help () %{{{ { jed_easy_help(aps_help_file); } %}}} % Keybindings % (none) provide("apsmode"); %---8<------- (end of apsmode.sl)-------- jedmodes-2.5.7/apsmode/apsmode.hlp0000644000175400017500000004747310446203324015404 0ustar mildegmThis is the help file for the apsmode (Version 2.2) =================================================== TOC: - General - Directories, Files - Installation - Menu Description - QuickPrint - QuickPrint Menu Description - apsconf.sl - Create a new printer setup with the help of QuickPrint - a2ps Style Sheets - Variable Definition for Printer Settings - Printer Definition Example - apsconf: Changes from V1.5 --> 2.2 General ------- apsmode has been created to support printing directly from jed. The mode should fullfill the following requirements: - syntax-highlighting (as in jed) - printing directly from jed - menu support - available under UNIX, Windows - selection of printers - selection of print options In fact apsmode serves as a frontend to a2ps/ghostview. In this context "printer" means here rather a printer setup or setting than a real (physical) printer. Real (physical) printer names are part of a printer setup. See "Printer Definition Example" or apsconf.template for details. Directory, Files ---------------- The following files have to be included in your jed library path: - apsmode.sl - apsmode.hlp - SLang.ssh - .ssh apsmode.hlp and *.ssh files could be stored in a separate subdirectory (e.g. /apsmode) as long as this subdirectory is also in the jed library path. (Use set_jed_library_path, see site.sl) - apsconf.template is a printer setup template. This can be modified by the single user and loaded via jed.rc. apsconf.sl has always to be loaded by the user itself. apsmode will not load it. Installation ------------ - Copy apsmode.sl, apsmode.hlp, *.ssh to your jed-lib-directory - maybe modify some custom_variables in apsmode.sl (for system wide usage) Change only variable values in section %%%%%%%%%%%%%% custom_variables begin %%%%%%%%%%%%% ... %%%%%%%%%%%%%% custom_variables variables end %%%%%%%%%%%%% - jed.rc: Add the following line to enable text menus in WINGUI () = evalfile("menus"); Load the apsmode () = evalfile("apsmode"); - apsconf.sl: edit the file apsconf.template for your personal a2ps/printer settings (see there for details) Maybe you have to copy the file to your personal jed files first, in Unix this could be "~/.jed/lib/" in this case, make sure it is in the jed-library-path (see set_jed_library_path()) add to jed.rc () = evalfile("apsconf.sl"); - For conversion of existing apsconf.sl files see "apsconf: Changes from V1.5 --> 2.0" below. Menu Description ---------------- Note: Already selected values will be marked by "*" in the menues. - Print Buffer print the whole buffer at once - Print Region print the marked region at once - Print Buffer Preview preview, what will be sent to the printer (whole buffer) - Print Region Preview preview, what will be sent to the printer (marked region) - Default Printer shows, which printer setting is the default one click on the shown printer to list its settings in a separate buffer - Set Default Printer select a new default printer from the list of all defined printers - QuickPrint see below - Show Printer Settings select a printer to list its settings in a separate buffer - Show Print Log File shows a separate buffer containing log information generated by a2ps and print/preview commands should be helpful in case of errors Note: If an error occurs during printing this buffer will be shown automatically (not under Windows). Windows users should check this log file manually, because error handling in Windows seems not to work properly. - Current Settings in apsconf format list settings of the current printer in a separate buffer The data format of the settings is the same as to be used in apsconf.sl - Create Style Sheet see below - Show apsmode Settings shows current apsmode settings, e.g. global variables - Help apsmode this help - About apsmode shows apsmode version QuickPrint ---------- Sometimes it is necessary to change some printer settings "on the fly" in jed. This can be done by using QuickPrint as printer setup. QuickPrint settings can be copied from a defined printer setting (see apsconf.sl), but will not be saved after leaving jed. Example: Suppose your printer settings creates double-sided output, but you need a single-sided one. - Menu: QuickPrint --> Set QP as Copy of setup --> select a printer setup (this copies the printer settings to QuickPrint) - Menu: QuickPrint --> Set QP as default printer --> select QuickPrint as the default printer - Menu: QuickPrint --> 2 Sides --> select 1 Now the printout will be single sided. QuickPrint Menu Description --------------------------- Since apsmode V2.2 QuickPrint menus are context sensitiv. That means, that the current defined settings will be shown in the QuickPrint menu. - Orientation defines the paper orientation portrait, landscape - Paper Format defines the paper format A4, A3, Letter - No Columns defines number of page columns paper side could be 1,2,3,4 - No Rows defines number of page rows per paper side could be 1,2,3,4 - 2 Sides defines single-sided/double-sided printing 1 - single-sided, 2 - double-sided - Copies defines number of copies to be printed 1-10 - Fontsize defines the fontsize in points 6, 7, 8, 9, 10, 11, 12 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 - Max Characters defines min:max number of characters per line 0:80 0:100 0:132 80:100 80:132 - Truncate Lines defines, whether long lines should be truncated or not (check esp. with your MS Windows a2ps, what the correct value is) on, off - Linenumbers print linenumbers every nth line 0-10 - Borders defines, whether borders should be used per page on, off - Margin define the margin in points 0...12 - Print Direction defines print direction for multi-pages on one paper sheet columns, rows - Color defines, whether to print in black/white or color bw, color - Pretty Printing defines, whetehr a2ps should use pretty-printing on, off - Header defines the header printed by a2ps - Title Left defines the left title to be printed - Title Center defines the center title to be printed - Title Right defines the right title to be printed - Footer Left defines the left footer to be printed - Footer Center defines the center footer to be printed - Footer Right defines the right footer to be printed - Print Command defines the print command directly (e.g. can be used to access another printer in the network) commands depends on operating system (will be derived from printer setups) - View Command defines the view command directly commands depends on operating system (will be derived from printer setups) - Set QP as Copy of setup copy printer settings to QuickPrint (will be derived from printer setups) - Set QP as default printer sets QuickPrint as the default printer apsconf.sl -------------- This is a separate sl file, containing printer settings as array entries. The entries itself will be described in apsconf.sl or in "Printer Definition Example". (see there for more information). In general these settings define a2ps parameters. So see also a2ps documentation for more details (e.g. title definitions). Create a new printer setup with the help of QuickPrint ------------------------------------------------------ An easy way to create a new printer setup would be the usage of QuickPrint settings: - Set QuickPrint as the default printer via menu "Set Default Printer --> QuickPrint" - Modify QuickPrint Settings via menu "QuickPrint --> Orientation, Number of..." - get the current settings in apsconf format via menu "Current Settings in apsconf format" - Copy the contents of this buffer in your local apsconf.sl file (and do further adaptions there if necessary). a2ps Style Sheets ----------------- a2ps uses style sheets for syntax-highligthing of the printout. Not for every jed language mode a corresponding a2ps style sheet exists by default. If syntax-highlighting of a jed language mode is required an a2ps style sheet has to be created. apsmode supports this by extracting keywords and comment definition from the language mode definition. (It scans the sl mode file for syntax definitions. DFA syntax highlighting will not be taken into account!) After extracting the keywords and/or comment definition an a2ps style sheet will be created, named .ssh. The directory can be selected by the user. This is a very basic (rudimentary) a2ps style sheet, which can be enhanced manually by adding a2ps instructions (see a2ps documentation for details). To be able to use this style sheet apsconf.sl has to be modified. Add a new entry to the following array (near the beginning of apsconf.sl) Apsmode_style_sheet[""] = 1; where is the mode name of the mode for which jed-generated style sheet should be used. has to be exactly the mode name (take care of upper/lower case). - included style sheets apsmode includes a SLang.ssh style sheet. This is a very basic one. Paul Boekholt provided a much better one with his a2ps-mode (see below). - additional style sheets created by Paul Boekholt Paul provided an a2ps jedmode for editing a2ps style sheets, which requires a2ps v4.13. (http://jedmodes.sourceforge.net/mode/a2ps). It includes already style sheets for slang and tm. * SLang.ssh You can use his style sheet by copying it into jed_library_path. Be sure to name it SLang.ssh. * tm.ssh slangtm.ssh is another style from Paul for printing tm documentation. For usage copy it into jed_library_path and rename it to tm.ssh. Add a new entry in apsconf.sl Apsmode_style_sheet["tm"] = 1; Variable Definition for Printer Settings ---------------------------------------- %%%%%%%%%%%%%%%%%% Define printers %%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This structure contains the printer settings for apsmode.sl % Most of the settings are directly copied from a2ps options % See a2ps documentation for further details. % These settings have been tested with: % - UNIX : a2ps v4.12 % - MSWINDOWS : a2ps v4.13b % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % JED variables used as placeholder for print options % % name : JEDFILENAME % description: use this variable in footer/header definitions to print % the path/name of the buffer to be printed % do not use "$f" option of a2ps, because this will print % the name of the temporary print file instead of the name of % the buffer % % name : JEDDATETIME % description: use this variable in footer/header definitions to print % the current date, time of the buffer print formatted % as YYYY-MMM-DD, HH:MM:SS % this is a replacement for the "%e %*" option of a2ps % which seems to not work correctly under MSWINDOWS % Correction: with apsmode V1.4 options for Windows are % correctly send to a2ps, so "%e %*" should work % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % name : setup % description: printer id % this will be used as program internal identifier for % the print setup % value(s) : integer, incremented by 1 % % name : setupname % description: that's the name of the printer setup, which will be used as % identifier % should not be too long, because it will be used within % the menus % value(s) : text % example : "code 2x1x1, A4" % % name : name % description: physical printer name as known by the OS % value(s) : text % example : "114_f004" % % name : description % description: Your information about the printer setup % value(s) : text % example : "This is an example description" % % name : columns % description: specify the number of columns of virtual pages per physical page % value(s) : integer (1...n) % example : "2" % % name : rows % description: specify the number of rows of virtual pages per physical page % value(s) : integer (1...n) % example : "2" % % name : fontsize % description: defines fontsize in points % if other formats than points needs to be supported % by QuickPrint then function has to be % modified accordingly % value(s) : 8,...,72 points, anything your printer and a2ps supports % example : "8points" % % name : chars % description: number of characters to be printed on one line % format = min:max % min - minimum of characters to be printed % max - maximum of characters to be printed % value(s) : Integer:Integer % example : "80:100" % % name : borders % description: switches border printing around each page on/off % value(s) : on,off % example : "on" % % name : orientation % description: defines sheet orientation % value(s) : portrait,landscape % example : "portrait" % % name : medium % description: defines print medium (sheet size) % if other formats than a3, a4, letter needs to be supported % by QuickPrint then function has to be % modified accordingly % value(s) : a4, a3, letter, ..., anything your printer and a2ps supports % example : "a4" % % name : sides % description: printing on one/both sides of a sheet % value(s) : 1,2 % example : "2" % % name : truncate % description: truncate lines, if they are longer than maximum number of % printing characters % !!! ATTENTION !!! % try on/off values with your a2ps installation % there seems to be a bug in different a2ps version % and/or OS version % UNIX , a2ps v4.12 : truncate=on does not truncate % MSWINDOWS, a2ps v4.13b : truncate=off does not truncate % value(s) : on,off % example : "on" % % name : linenumbers % description: add linenumbers every x line to your printout % helpful for program code % switch off with value 0 % value(s) : 0...n % example : "5" % % name : copies % description: number of copies to be printed % value(s) : 1...n % example : "1" % % name : major % description: specify whether the virtual pages should be first filled in % rows (direction = rows) or in columns (direction = columns). % value(s) : rows,columns % example : "columns" % % name : margin % description: Specify the size of the margin (num PostScript points, % or 12 points without arguments) to leave in the inside % (i.e. left for the front side page, and right for the back % side). This is intended to ease the binding. % value(s) : 0...n % example : "5" % % name : header % description: sets the page header % value(s) : text % example : "Your Page header" % % name : title_left % description: Set virtual page left title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%e %*" % % name : title_center % description: Set virtual page center title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "$f", "JEDFILENAME" % % name : title_right % description: Set virtual page right title to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%s./%s#" % % name : footer_left % description: Set virtual page left footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%e %*" % % name : footer_center % description: Set virtual page center footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "$f" % % name : footer_right % description: Set virtual page right footer to text % see a2ps documentation for more detailed options % value(s) : text and/or a2ps options % example : "%s./%s#" % % name : color % description: switches color printing on/off % bw - Style is plain: pure black and white, with standard fonts % color - Colors are used to highlight the keywords % value(s) : bw,color % example : "color" % % name : pretty % description: switches pretty printing feature of a2ps on/off % value(s) : on,off % example : "on" % % name : print_cmd % description: string containing the OS specific command to send the created % postscript file to the physical printer % could also be a ghostview command if direct printing % is somehow not supported % value(s) : text % example : strcat("lpr -P ", Apsmode_Printers[setup].name, " ", Apsmode_tmp_file) % % name : view_cmd % description: string containing the OS specific command to view the created % postscript file (ghostview preferred) % value(s) : text % example : strcat("gv ", Apsmode_tmp_file) % strcat("gsview32.exe ", Apsmode_tmp_file); % % name : copy_of % description: internal variable, which is needed for QuickPrint settings % has to be 0, don't change it % value(s) : 0 % example : "0" % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Printer Definition Example -------------------------- create your own apsconf.sl file from apsconf.template similar to the example below and load it via () = evalfile("apsconf.sl"); % full path or % relative to jed-library-path % Don't forget to define a private variable 'setup' in your local apsconf file; % private variable aps_id = 0; setup++; Apsmode_Printers[setup].setupname = "code, A4, 6pt, 2x1, duplex, CCB_3_F008"; Apsmode_Printers[setup].name = "CCB_3_F008"; Apsmode_Printers[setup].description = "Printer 1"; Apsmode_Printers[setup].columns = "2"; Apsmode_Printers[setup].rows = "1"; Apsmode_Printers[setup].fontsize = "6points"; Apsmode_Printers[setup].chars = "80:100"; Apsmode_Printers[setup].borders = "on"; Apsmode_Printers[setup].orientation = "landscape"; Apsmode_Printers[setup].medium = "A4"; Apsmode_Printers[setup].sides = "2"; Apsmode_Printers[setup].truncate = "on"; Apsmode_Printers[setup].linenumbers = "5"; Apsmode_Printers[setup].copies = "1"; Apsmode_Printers[setup].major = "columns"; Apsmode_Printers[setup].margin = "5"; Apsmode_Printers[setup].header = ""; Apsmode_Printers[setup].title_left = ""; Apsmode_Printers[setup].title_center = ""; Apsmode_Printers[setup].title_right = ""; Apsmode_Printers[setup].footer_left = "JEDDATETIME"; Apsmode_Printers[setup].footer_center = "JEDFILENAME"; Apsmode_Printers[setup].footer_right = "%s./%s#"; Apsmode_Printers[setup].color = "bw"; Apsmode_Printers[setup].pretty = "on"; Apsmode_Printers[setup].print_cmd = strcat("lpr -P ", Apsmode_Printers[setup].name, " ", Apsmode_tmp_file); Apsmode_Printers[setup].view_cmd = strcat("gv ", Apsmode_tmp_file); Apsmode_Printers[setup].copy_of = 0; apsconf: Changes from V1.5 --> 2.2 ---------------------------------- In apsmode V2.2 a lot of variable names have been changed. Global variables are now named "Apsmode_". For existing apsconf.sl files the following variable name changes have to be applied: a2ps_cmd --> Apsmode_a2ps_cmd aps_del_ps_file --> Apsmode_del_ps_file aps_menu --> Apsmode_menu aps_tmp_dir --> Apsmode_tmp_dir aps_tmp_file --> Apsmode_tmp_file default_printer --> Apsmode_default_printer printer --> Apsmode_Printers use_jed_a2ps_style_sheet --> Apsmode_style_sheet printer[].setup --> Apsmode_Printers[].setupname aps_pid --> setup setup has to be a private variable in apsconf.sl (see apsconf.template) jedmodes-2.5.7/apsmode/SLang.ssh0000644000175400017500000000336110446230222014753 0ustar mildegm# SLANG.ssh --- Sheet definitions for SLANG scripts # This style sheet is based on stylesheets provided by Edward Arthur, Akim Demaille, Miguel Santana # Copyright (c) 1999 Edward Arthur, Akim Demaille, Miguel Santana # # # This file is not part of a2ps. # It is automatically created from within jed using functions in a2psmode.sl. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. ## 1.0 Thomas Koeckritz # Initial implementation. style SLANG is written by "Thomas Koeckritz" version is 1.0 requires a2ps version 4.9.7 documentation is "This style is devoted to the SLANG language." It has been automatically created from within jed. end documentation alphabets are "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0" case sensitive keywords in Keyword_strong are do,if,or,and,chs,for,mod,not,pop,shl,shr,sqr,xor,NULL,_for,"case",else,exch,loop,mul2,sign,__tmp,break,using,while,define,orelse,public,return,static,struct,switch,andelse,foreach,forever,private,typedef,continue,variable,EXIT_BLOCK,ERROR_BLOCK,EXECUTE_ERROR_BLOCK end keywords sequences are "%" Comment end sequences end style jedmodes-2.5.7/cuamark/0000755000175400017500000000000011137350473013231 5ustar mildegmjedmodes-2.5.7/cuamark/cuamark.sl0000644000175400017500000002540511137350473015222 0ustar mildegm% cuamark.sl: CUA/Windows style of marking "volatile" regions % % Copyright (c) 2003, 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 0.9 % 0.9.1 use _jed_before_key_hooks (needs jed 0.99.16) % after the example by JED in wmarks.sl % 1.0 added support for Dave Kuhlhard's yank_repop command % 1.1 * removed the require("yankpop"), (autoloads in site.sl) % 2006-07-20 1.2 * bugfix: cua_insert_clipboard() returned a value % * removed the call to cuamark_hook(): place your % customization just after the `require("cuamark");' line. % * removed CuaCopyToClipboard: use yp_copy_region() and % yp_kill_region() if you do not like to copy to the X % selection % 2008-05-05 1.3 * X-Clipboard interaction (using xclip) following % http://www.freedesktop.org/standards/clipboards.txt % 2009-01-05 1.3.1 Bind Shift_Ins to cua_insert_clipboard(), % Make the xclip-using functions failsave. % 2009-01-26 .3.2 Work around rxvt-unicode bug (Debian bug #446444) % % % TODO % ---- % % * Extend the Shift+navigation marking to wordwise moving via Ctrl-Left/Right. % Problem: with Unix/Linux Shift-Ctrl-Left/Right == Ctrl-Left/Right % % Workaround: Currently, "skip_word, bskip_word" are not listed as unmarking % functions -> Start the region using Shift-Left/Right and then extend it % with Ctrl-Left/Right. % % Mark regions the CUA style % -------------------------- % % * Holding down Shift key and using navigation keys defines a region % % * Arrow keys without Shift undefine the region, if defined with % Shift- % % * The custom variable `Cua_Replacing_Functions' holds all functions that % will replace a cua-region. By default this includes % self_insert_cmd (typing "normal" text), yank, yp_yank, and cua_yank. % % (The cua emulation binds the key to cua_delete_char(), which % deletes a character or any visible region). % % * You can still define a "non-cua"-region with push_visible_mark(). % Such a "permanent-region" will behave the "normal" Jed way (i.e it can % be extended by nonshifted navigation and will not be replaced with % typed text) % % The following bindings affect all visible regions: % % Shift- cut region % Ctrl- copy region % Shift- inserts the systen clipboard (or yank buffer) % % Usage % ----- % % Insert a line % require("cuamark") % into your .jedrc/jed.rc file. Optionally customize using custom variables % and|or change keybindings. % % Some keybinding suggestions: % % setkey("cua_kill_region", "^X"); % setkey("cua_copy_region", "^C"); % setkey("cua_yank", "^V"); % % if you do not like to place a copy into the system clipboard % or are never using Jed under X-windows: % % setkey("yp_kill_region", Key_Shift_Del); % setkey("yp_copy_region", Key_Ctrl_Ins); % setkey("yp_yank", Key_Shift_Ins); % % Notes % ----- % % If you are having problems with Shift-arrow keys under % the Linux console, you can use the "console_keys" mode % (http://jedmodes.sourceforge.net/mode/console_keys/) % Requirements % ------------ require ("keydefs"); % symbolic constants for "special" keys % Workaround for rxvt-unicode bug (Debian bug #446444) resulting in % inkonsistent keydef error #ifndef XWINDOWS if (Key_Shift_Ins == "\e2$") Key_Shift_Ins = "\e[2$"; #endif % Customization % ------------- % Comma separated list of functions that unmark a cua-region (movement functions) %!%+ %\variable{Cua_Replacing_Functions} %\synopsis{Functions that unmark a cua-region (movement functions)} %\usage{variable Cua_Unmarking_Functions = "beg_of_line,eol_cmd,..."} %\description % Comma separated string of functions that unmark a region defined via % \sfun{cua_mark} (insert-functions). %\example % If you want to unmark a cua-region by wordwise movement, write %#v+ % Cua_Unmarking_Functions += ",skip_word, bskip_word "; %#v- % in your jed.rc (or .jedrc) file after the `require("cuamark")' line. %\seealso{cua_mark} %!%- custom_variable("Cua_Unmarking_Functions", "beg_of_line,eol_cmd," + "previous_char_cmd,next_char_cmd," + "previous_line_cmd,next_line_cmd," + "page_up,page_down,bob,eob," % + "skip_word, bskip_word" % Shift_Ctrl_Right/Left ); %!%+ %\variable{Cua_Replacing_Functions} %\synopsis{Functions that replace the cua-region (insert-functions)} %\usage{variable Cua_Replacing_Functions = "self_insert_cmd,yank,yp_yank,cua_yank"} %\description % Comma separated string of functions that replace a region started with % \sfun{cua_mark} (insert-functions). %\example % If you don't want the region replaced by inserting, define %#v+ % variable Cua_Replacing_Functions = ""; %#v- % in your jed.rc (or .jedrc) file. %\seealso{cua_mark, Cua_Unmarking_Functions} %!%- custom_variable("Cua_Replacing_Functions", "self_insert_cmd,yank,yp_yank,cua_yank"); custom_variable("Cuamark_Pop_Key", "^P"); custom_variable("Cuamark_Repop_Key", "^N"); % --- Functions ------------------------------------------------------------ static define before_key_hook(fun) { if (is_substr(Cua_Unmarking_Functions, fun + ",")) pop_mark_0(); else if (is_substr(Cua_Replacing_Functions, fun + ",")) del_region(); } static define after_key_hook(); % forward definition static define after_key_hook() { !if (is_visible_mark()) { remove_from_hook("_jed_before_key_hooks", &before_key_hook); remove_from_hook("_jed_after_key_hooks", &after_key_hook); } } %!%+ %\function{cua_mark} %\synopsis{Mark a cua-region (usually, with Shift-Arrow keys)} %\usage{cua_mark()} %\description % if no visible region is defined, set visible mark and key-hooks % so that Cua_Unmarking_Functions unmark the region and % Cua_Deleting_Functions delete it. %\seealso{cua_kill_region, cua_copy_region, Cua_Unmarking_Functions, Cua_Deleting_Functions} %!%- define cua_mark() { !if (is_visible_mark) { push_visible_mark (); add_to_hook("_jed_before_key_hooks", &before_key_hook); add_to_hook("_jed_after_key_hooks", &after_key_hook); } } % X Clipboard interaction % ----------------------- % From xclip's README: % % For a good overview of what selections are about, have a look at % . Short version: % % * XA_PRIMARY contains the last text you highlighted % * Middle click pastes XA_PRIMARY % * XA_CLIPBOARD contains text explicitly copied with Edit | Copy, Ctrl-C etc. % * Edit | Paste pastes XA_CLIPBOARD % * xclip uses XA_PRIMARY unless you specify otherwise with -selection % * never ever use CUTBUFFERS, they are obsolete and problematic % which means on X-Windows (xjed or jed in X-terminal): % * cuamark copy/kill/insert should use CLIPBOARD instead of PRIMARY % However, % * x_copy_region_to_selection() and x_insert_selection() use PRIMARY % * there are no S-Lang functions to work with CLIPBOARD %!%+ %\function{cua_copy_region_to_clipboard} %\synopsis{Copy region to the system clipboard.} %\usage{cua_copy_region_to_clipboard()} %\description % Copy region to the CLIPBOARD selection in X-Windows % and to the system clibboard in Windows. % % Allows to paste the content in another application (if that app uses the % system clipboard). %\notes % %\seealso{x_copy_region_to_selection, cua_insert_clipboard} %!%- public define cua_copy_region_to_clipboard() { #ifdef WIN32 x_copy_region_to_cutbuffer(); #elifdef UNIX try { () = pipe_region("xclip -selection clipboard"); } catch RunTimeError: { message("xclip not available: can not write to clipboard"); } #else pop_mark_0(); #endif } %!%+ %\function{cua_insert_clipboard} %\synopsis{Insert system CLIPBOARD selection at point} %\usage{Void cua_insert_clipboard()} %\description % Insert the content of the "clipboard" X selection at point. % % Works also for wjed (using \sfun{x_insert_cutbuffer}) and % jed in an x-terminal. %\notes % This function does not return the number of characters inserted so it can % be bound to a key easily. % % The intrinsic \sfun{x_insert_selection} will insert the content of the % PRIMARY selection (analogue to a middle click) but only after the next % "EVENT" (keypress, -release or mouse click). %\seealso{cua_copy_region, cua_kill_region} %!%- public define cua_insert_clipboard() { #ifdef WIN32 () = x_insert_cutbuffer(); #else if (run_shell_cmd("xclip -o -selection clipboard")) % failure yp_yank(); #endif } %!%+ %\function{cua_kill_region} %\synopsis{Kill region (and copy to yp-yankbuffer and system clipboard)} %\usage{Void cua_kill_region()} %\description % Kill region. Copies are placed in the yp-yankbuffer and in the system % clipboard. %\seealso{yp_kill_region, cua_copy_region, cua_copy_region_to_clipboard} %!%- define cua_kill_region () { () = dupmark(); cua_copy_region_to_clipboard(); yp_kill_region(); } %!%+ %\function{cua_copy_region} %\synopsis{Copy region to yp-yankbuffer and system clipboard} %\usage{Void cua_copy_region()} %\description % Copy the region to the yp-yankbuffer and the system clipboard. % % If \sfun{x_copy_region_to_selection} or \sfun{x_copy_region_to_cutbuffer} % exist, a copy is pushed to the X selection as well. %\seealso{yp_copy_region_as_kill, cua_kill_region, cua_copy_region_to_clipboard} %!%- define cua_copy_region() { () = dupmark(); cua_copy_region_to_clipboard(); yp_copy_region_as_kill; } % % yp_yank wrapper with temporary rebinding of yank-pop keys % % ------------------------------_-------------------------- % % static define cua_yank_pop_hook(fun); % forward definition % static define cua_yank_pop_hook(fun) % { % show("function, key(s)", fun, which_key(fun)); % % if (fun == yank_repop_key_fun) % % set_prefix_argument(1); % % yp_yank_pop(); % show(LASTKEY, char(LAST_CHAR), CURRENT_KBD_COMMAND, LAST_KBD_COMMAND); % % remove_from_hook("_jed_before_key_hooks", &cua_yank_pop_hook); % } % % % yank from yankpop kill-buffer-ring and temporarily rebind yank-pop keys % define cua_yank() % { % yp_yank(); % add_to_hook("_jed_before_key_hooks", &cua_yank_pop_hook); % vmessage("Press %s or %s to cycle among replacements", % Cuamark_Pop_Key, Cuamark_Repop_Key); % } % --- Keybindings setkey("cua_mark; go_up_1", Key_Shift_Up); setkey("cua_mark; go_down_1", Key_Shift_Down); setkey("cua_mark; go_left_1", Key_Shift_Left); setkey("cua_mark; go_right_1", Key_Shift_Right); setkey("cua_mark; call(\"page_up\")", Key_Shift_PgUp); setkey("cua_mark; call(\"page_down\")", Key_Shift_PgDn); setkey("cua_mark; bol", Key_Shift_Home); setkey("cua_mark; eol", Key_Shift_End); setkey("cua_insert_clipboard", Key_Shift_Ins); setkey("cua_kill_region", Key_Shift_Del); setkey("cua_copy_region", Key_Ctrl_Ins); provide ("cuamark"); jedmodes-2.5.7/subpar/0000755000175400017500000000000010461125576013105 5ustar mildegmjedmodes-2.5.7/subpar/subpar.sl0000664000175400017500000001075710214064474014750 0ustar mildegm% subpar.sl % paragraph reformatter % % $Id: subpar.sl,v 1.1 2004/05/27 21:24:49 paul Exp paul $ % Keywords: wp % % Copyright (c) 2004 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % Uses a dynamic programming algorithm like Adam Costello's "par" program. It % chooses linebreaks so that the paragraph satisfies the following properties: % % 1) No line contains more than characters. % % 2) The sum of the squares of the differences between % and the lengths of the lines is as small as possible. %!%+ %\variable{Par_Bullets} %\synopsis{Bullet characters} %\usage{String_Type Par_Bullets = "*\\-"} %\description % The \var{par} paragraph formatter will avoid breaking a line at a bullet % character. The '-' is escaped because this is used in a regexp character % list. %\seealso{par} %!%- custom_variable("Par_Bullets", "*\\-"); require("comments"); % Get the spaces on this line, and return their positions on the stack, % skipping double spaces. Avoid possible line breaks at comment characters. static define get_spaces(comment_chars) { variable line = line_as_string, pos = 0, len; % Skip indentation of first line if (string_match(line, "^ +", 1)) (,pos) = string_match_nth(0); pos++; variable re = sprintf("\\( +\\)[^ %s%s]", Par_Bullets, comment_chars); while (string_match(line, re, pos)) { (pos ,len) = string_match_nth(1); if (len == 1) pos; pos += len + 1; } strlen(line); } static variable indent; % Chooses line breaks in a list of words which maximize the sum of squares % of differences between line lengths and the maximum line length. Pushes % the locations of linebreaks on the stack and returns the number of % linebreaks. This is actually more like Costello's simplebreaks() than his % normalbreaks(). static define normalbreaks(s) { variable i = length(s), j; variable L = WRAP - indent; if (i < 2) return 0; variable wordlengths = s - [indent-1, s[[0:i-2]]]; % these are actually wordlengths + 1 variable linelen, score, scores = Integer_Type[i], next = Integer_Type[i]; next[*] = -1; for (i--, linelen = wordlengths[i] - 1; i !=-1 and linelen <= L; i--, linelen += wordlengths[i]) ; variable scores_i, next_i; for ( ; i != -1; i--) { scores_i = 0; for (linelen = wordlengths[i] - 1, j = i, j++; linelen <= L; linelen += wordlengths[j], j++) { score = scores[j] + sqr(L - linelen); if (orelse {score < scores_i}{not scores_i} ) { next_i = j; scores_i = score; } } scores[i] = scores_i; next[i] = next_i; } variable n = 0; for (i = next[0]; i != -1; i = next[i]) n++, s[i-1]; n; } %!%+ %\function{par} %\synopsis{paragraph reformatter} %\usage{ par()} %\description % A S-Lang paragraph reformatter. Unlike \var{format_paragraph} it leaves % double spaces alone. It can reformat newline-terminated commments in % S-Lang, C++, and SH using the mode's comment_info. %\seealso{Par_Bullets, set_comment_info} %!%- define par() { variable is_comment = 0, comment_chars = ""; push_spot; % get indentation bol; push_mark; skip_white; variable comment = get_comment_info; if (andelse {comment != NULL} {comment.cend == ""} {comment_chars = str_quote_string(comment.cbeg, "[]^\\-", '\\'), re_looking_at(sprintf ("[%s]", comment_chars))}) { skip_chars(comment.cbeg); is_comment = 1; skip_white; } indent = what_column -1; variable prefix = bufsubstr, prefix_length = strlen(prefix); if (is_comment) % narrow to the comment { variable re = sprintf("^%s[^%s]", prefix, comment_chars); while (up_1) { bol; if (not re_looking_at(re)) { go_down_1; break; } } push_mark; while (down_1) { if (not re_looking_at(re)) { go_up_1; break; } } narrow; } else % narrow to the paragraph { backward_paragraph; !if (bobp) go_down_1; push_mark; forward_paragraph; !if (eobp) go_up_1; narrow; } bob; eol; while (not eobp) { del; if(is_comment) deln(prefix_length); trim; insert_char(' '); eol; } % paragraph is one line now, look for spaces bol; [get_spaces(comment_chars)]; % get linebreaks variable newlines = normalbreaks(); % insert linebreaks backwards loop (newlines) { _set_point(); del; newline; insert(prefix); go_up_1; } widen; pop_spot; } provide ("subpar"); jedmodes-2.5.7/mtools/0000755000175400017500000000000010461125576013126 5ustar mildegmjedmodes-2.5.7/mtools/mtools.sl0000644000175400017500000001045710436520557015012 0ustar mildegm% Interface to mtools (http://mtools.linux.lu/) % for easy floppy read/write under UNIX % % Copyright (c) 2006 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 1.0 2003-xx-xx first public version % 1.1 2004-02-16 use a temp-file for mtools_find_file to preserve the CR-LFs % (bugreport P. Boekholt) % separate the directory listing to mtools_list_dir() % 1.1.1 2004-06-03 bugfix in mtools_find_file (normalize pathname) % 1.2 2006-05-29 renamed Jed_Temp_Dir to Jed_Tmp_Directory as this is what % make_tmp_file() uses since 0.99.17-165 % % USAGE: % % Put in your jed_library_path and add autoloads for the functions % (or run make_ini from jedmodes.sf.net/mode/make_ini/). % Optionally set the custom variable Mtools_Write_Args. % variable Mtools_Write_Args = "-D o"; % overwrite existing files % % See extensive mtools documentation with info. % % EXAMPLE: % mtools_find_file("a:") -> get a listing of the floppy dir (mdir) % mtools_find_file("a:test") -> load file "test" from floppy into buffer % mtools_write("a:test") -> write buffer/region to floppy % % RECOMMENDS: % uri.sl (http://jedmodes.sf.net/mode/uri) to access the floppy using % the normal find_file/write_buffer/write_region functions (via hooks) % _debug_info = 1; % requirements % autoload("filelist_mode", "filelist"); % --- Variables % mtools_write doesnot work interactive, so nameclashes result in an error, % if no solution scheme is set: % custom_variable("Mtools_Write_Args", "-D o"); % overwrite existing file custom_variable("Mtools_Write_Args", "-D a"); % autorename the new file % Directory for temporary files custom_variable("Jed_Tmp_Directory", getenv("TEMP")); if (Jed_Tmp_Directory == NULL) Jed_Tmp_Directory = getenv("TMP"); if (Jed_Tmp_Directory == NULL) Jed_Tmp_Directory = "/tmp"; % call mdir for path define mtools_list_dir(path) { variable status; sw2buf(path); set_readonly(0); erase_buffer(); status = run_shell_cmd("mdir " + path); % directory listing set_buffer_modified_flag(0); % error handling if (status) { delbuf(whatbuf); verror("mdir returned %d, %s", status, errno_string(status)); } setbuf_info("", path, path, 8); define_blocal_var("filename_position", 5); % filelist_mode(); return(not(status)); % success } % Find a file using (usually on a floppy) using mtools % If the filename has no basepart or is just "a:", do a directory listing % Return success define mtools_find_file(path) { variable status, flags, tmp_file = make_tmp_file(path_concat(Jed_Tmp_Directory, path)) + path_extname(path); % (to get the mode right) % standardize the name of the root dir (so path_basename() works) !if (is_substr(path, "a:/")) (path, ) = strreplace (path, "a:", "a:/", 1); % show(_function_name, path, path_basename(path)); % return a listing if the path is a directory if (path_basename(path) == "") return mtools_list_dir(path); % copy file to tmp_file status = system(strjoin(["mcopy", path, tmp_file], " ")); if (status) verror("mtools returned %d, %s", status, errno_string(status)); % open the temp file, delete it and correct buffer settings () = find_file(tmp_file); delete_file(tmp_file); (, , , flags) = getbuf_info(); % the dirname is always expanded, so I cannot set it to a: :-( % setbuf_info(path_basename(path), path_dirname(path), tmp_file, flags); % set to empty file and dir names, so save_buffer asks where to save % TODO: do not reopen if buffer exists. setbuf_info("", "", tmp_file, flags); rename_buffer(path); % be sure not to have 2 buffers % with the same name return(not(status)); % success } % Write buffer (or if defined region) to a file (usually on a floppy) % using mtools % Return success define mtools_write(path) { % show("mtools-write", path); variable status; push_spot(); !if (is_visible_mark()) mark_buffer(); flush ("Saving to " + path ); status = pipe_region(sprintf("mcopy %s - %s", Mtools_Write_Args, path)); !if (status) set_buffer_modified_flag(0); else verror("mtools returned %d, %s", status, errno_string(status)); return(not(status)); % success } jedmodes-2.5.7/manedit/0000755000175400017500000000000010461125576013232 5ustar mildegmjedmodes-2.5.7/manedit/manedit.sl0000644000175400017500000004140010341026025015174 0ustar mildegm% -*- mode: slang; mode: fold -*- % %{{{ Documentation % % Description % % JED mode for editing Linux manpages. % % This mode implements a syntax highlighting scheme for editing Linux % manpages with groff macros, as described in the man(7) and groff_man(7) % manpages in any decent Linux distribution. % % There are also some utility functions that can make life much easier for % the developer. Via the "Template" menu option one can even craft a manpage % without knowing the theory behind such magic. The functions should, % preferably, be chosen from the mode menu, but can of course also be bound % to key combination of ones personal preference. % % Implementation notes % % Since I wanted to highlight escape sequences and that had to be done by % enabling TeX-like keywords, those are highlighted using the keyword color % and regular nroff macros using the keyword1 color. % % Some things are still missing (see Todo below), but the mode is already % very useful, at least to me. Important documentation on section and font % standards is included in their respective function definitions. % % I borrowed a piece of code from the standard nroff mode, which is very % limited in features. % % Usage % % Put this file in your JED_LIBRARY path and add the following lines to your % startup file (.jedrc or jed.rc): % % autoload("manedit_mode", "manedit"); % add_mode_for_extension("manedit", "man"); % add_mode_for_extension("manedit", "1"); % ... % add_mode_for_extension("manedit", "8"); % % Every time you open a file called something.man or something.1 etc., % manedit_mode will automatically be loaded. % % There are also a couple of variables that can be changed in .jedrc like % this (default values are shown): % % variable manedit_par_macro = ".PP"; % .PP, .LP or .P are synonyms % variable manedit_dot_section = "1"; % 1 puts a '.' before sections % % Changelog % % 1.0.1 - 2002/02/21: % - Bugfix: Default size in the mode menu outputted *S instead of \*S. % % 1.0 - 2002/01/16: % - First public release. % % Todo % % - DFA patterns. % - "Transform region" functionality. % % Author % % Johann Gerell, johann dot gerell at home dot se % % Copyright (c) 2002 Johann Gerell % Released under the terms of the GNU General Public License (ver. 2 or later) % %}}} $0 = "manedit"; %{{{ Syntax definition create_syntax_table($0); define_syntax(".\\\"", "", '%', $0); % comment define_syntax('\\', '\\', $0); % quote character define_syntax(".a-zA-Z0-9(){}*$-%\"'`[]", 'w', $0); % word chars set_syntax_flags($0, 0x08); % highlight quoted words %}}} %{{{ Keywords: the macros described in the man(7) manpage () = define_keywords_n($0, ".", 1, 1); () = define_keywords_n($0, ".B.I.P", 2, 1); () = define_keywords_n($0, ".BI.BR.HP.IB.IP.IR.LP.PP.RB.RE.RI.RS.SB.SH.SM.SS.TH.TP.UE.UN.UR", 3, 1); %}}} custom_variable("manedit_par_macro", ".PP"); % one of .LP, .P or .PP custom_variable("manedit_dot_section", 1); % dot before section, 0 or 1 define manedit_parsep() { %{{{ bol(); (looking_at_char('.') or looking_at_char('\\') or (skip_white(), eolp())); } %}}} define manedit_insert_title() { %{{{ bol; !if(_NARGS) { variable t = read_mini("Title:", "", "APPNAME"), se = read_mini("Section:", "", "1"), d = read_mini("Date:", "", "2002-01-01"), so = read_mini("Source:", "", "GNU"), m = read_mini("Manual:", "", "The Application Manual"), sep = "\" \""; insert(".TH \"" + t + sep + se + sep + d + sep + so + sep + m + "\"\n"); } else insert(".TH \"APPNAME\" \"1\" \"2002-01-01\" \"GNU\" \"The Application Manual\"\n"); } %}}} define manedit_insert_section(name) { %{{{ % The only required heading is NAME, which should be the first section and % be followed on the next line by a one line description of the program: % % .SH NAME % chess \- the game of chess % % It is extremely important that this format is followed, and that there is % a backslash before the single dash which follows the command name. This % syntax is used by the makewhatis(8) program to create a database of short % command descriptions for the whatis(1) and apropos(1) commands. % % Some other traditional sections have the following contents: % % SYNOPSIS briefly describes the command or function's interface. For % commands, this shows the syntax of the command and its arguments % (including options); boldface is used for as-is text and italics are used % to indicate replaceable arguments. Brackets ([]) surround optional % arguments, vertical bars (|) separate choices, and ellipses (...) can be % repeated. For functions, it shows any required data declarations or % #include directives, followed by the function declaration. % % DESCRIPTION gives an explanation of what the command, function, or format % does. Discuss how it interacts with files and standard input, and whhat it % produces on standard output or standard error. Omit internals and % implementation details unless they're critical for understanding the % interface. Describe the usual case; for information on options use the % OPTIONS section. If there is some kind of input grammar or complex set of % subcommands, consider describing them in a separate USAGE section (and % just place an overview in the DESCRIPTION section). % % RETURN VALUE gives a list of the values the library routine will return to % the caller and the conditions that cause these values to be returned. % % EXIT STATUS lists the possible exit status values or a program and the % conditions that cause these values to be returned. % % OPTIONS describes the options accepted by the program and how they change % its behavior. % % USAGE describes the grammar of any sublanguage this implements. % % FILES lists the files the program or function uses, such as configuration % files, startup files, and files the program directly operates on. Give the % full pathname of these files, and use the installation process to modify % the directory part to match user preferences. For many programs, the % default installation location is in /usr/local, so your base manual page % should use /usr/local as the base. % % ENVIRONMENT lists all environment variables that affect your program or % function and how they affect it. % % DIAGNOSTICS gives an overview of the most common error messages and how to % cope with them. You don't need to explain system error messages or fatal % signals that can appear during execution of any program unless they're % special in some way to your program. % % SECURITY discusses security issues and implications. Warn about % configurations or environments that should be avoided, commands that may % have security implications, and so on, especially if they aren't obvious. % Discussing security in a separate section isn't necessary; if it's easier % to understand, place security information in the other sections (such as % the DESCRIPTION or USAGE section). However, please include security % information somewhere! % % CONFORMING TO describes any standards or conventions this implements. % % NOTES provides miscellaneous notes. % % BUGS lists limitations, known defects or inconveniences, and other % questionable activities. % % AUTHOR lists authors of the documentation or program so you can mail in % bug reports. % % SEE ALSO lists related man pages in alphabetical order, possibly followed % by other related pages or documents. Conventionally this is the last % section. !if(bolp()) bol(); if(manedit_dot_section) insert(".\n"); if(name == "NAME") insert(".SH NAME\nappname \- short description\n"); else if(name == "SS") insert(".SS Subsection name\n"); else insert(".SH " + name + "\n"); } %}}} define manedit_insert_font(font) { %{{{ % For functions, the arguments are always specified using italics, even in % the SYNOPSIS section, where the rest of the function is specified in bold: % % Filenames are always in italics, except in the SYNOPSIS section, where % included files are in bold. % % Special macros, which are usually in upper case, are in bold. % % When enumerating a list of error codes, the codes are in bold (this list % usually uses the .TP macro). % % Any reference to another man page (or to the subject of the current man % page) is in bold. If the manual section number is given, it is given in % Roman (normal) font, without any spaces. % % The commands to select the type face are: % % .B Bold % .BI Bold alternating with italics (function specifications) % .BR Bold alternating with Roman (for referring to other manual pages) % .I Italics % .IB Italics alternating with bold % .IR Italics alternating with Roman % .RB Roman alternating with bold % .RI Roman alternating with italics % .SB Small alternating with bold % .SM Small (useful for acronyms) % % Traditionally, each command can have up to six arguments, but the GNU % implementation removes this limitation (you might still want to limit % yourself to 6 arguments for portability's sake). Arguments are delimited % by spaces. Double quotes can be used to specify an argument which contains % spaces. All of the arguments will be printed next to each other without % intervening spaces, so that the .BR command can be used to specify a word % in bold followed by a mark of punctuation in Roman. If no arguments are % given, the command is applied to the following line of text. bol(); insert(font + " \n"); up_1; eol; } %}}} define manedit_insert_paragraph() { %{{{ bol; insert(manedit_par_macro + "\n"); } %}}} define manedit_insert_relative_indent(start) { %{{{ bol; if(start) insert(".RS " + read_mini("Length [default is the prevailing indent]:", "", "") + "\n"); else insert(".RE\n"); } %}}} define manedit_insert_indented_paragraph(type) { %{{{ bol; if(type == 1) insert(".HP " + read_mini("Length [default is the prevailing indent]:", "", "") + "\n"); else if(type == 2) insert(".IP " + read_mini("Tag:", "", "") + read_mini("Length [default is the prevailing indent]:", "", "") + "\n"); else if(type == 3) insert(".TP " + read_mini("Length [default is the prevailing indent]:", "", "") + "\n...tagline...\n"); else if(type == 4) insert(".IP \\(bu\nitem\n.IP \\(bu\nitem\n.IP \\(bu\nitem\n"); else if(type == 5) insert(".IP \\(em\nitem\n.IP \\(em\nitem\n.IP \\(em\nitem\n"); else if(type == 6) insert(".IP 1.\nitem\n.IP 2.\nitem\n.IP 3.\nitem\n"); else if(type == 7) insert(".IP a.\nitem\n.IP b.\nitem\n.IP c.\nitem\n"); } %}}} define manedit_insert_hypertext(type) { %{{{ bol; if(type == 1) insert(".UR " + read_mini("URL:", "", "") + "\n.UE\n"); else if(type == 2) insert(".UN " + read_mini("Name:", "", "") + "\n"); } %}}} define manedit_insert_template() { %{{{ manedit_insert_title(1); manedit_insert_section("NAME"); manedit_insert_section("SYNOPSIS"); manedit_insert_section("DESCRIPTION"); manedit_insert_section("OPTIONS"); manedit_insert_section("USAGE"); manedit_insert_section("FILES"); manedit_insert_section("NOTES"); manedit_insert_section("BUGS"); manedit_insert_section("AUTHOR"); manedit_insert_section("SEE ALSO"); bob; if(manedit_dot_section) go_down(6); else go_down(4); insert("\n"); up_1; } %}}} define manedit_menu(menu) { %{{{ menu_append_item(menu, "&Title", "manedit_insert_title"); %{{{ Section menu_append_popup(menu, "&Section"); menu_append_item(menu + ".&Section", "&NAME", "manedit_insert_section(\"NAME\")"); menu_append_item(menu + ".&Section", "&SYNOPSIS", "manedit_insert_section(\"SYNOPSIS\")"); menu_append_item(menu + ".&Section", "&DESCRIPTION", "manedit_insert_section(\"DESCRIPTION\")"); menu_append_item(menu + ".&Section", "&RETURN VALUE", "manedit_insert_section(\"RETURN VALUE\")"); menu_append_item(menu + ".&Section", "E&XIT STATUS", "manedit_insert_section(\"EXIT STATUS\")"); menu_append_item(menu + ".&Section", "ERR&OR HANDLING", "manedit_insert_section(\"ERROR HANDLING\")"); menu_append_item(menu + ".&Section", "&ERRORS", "manedit_insert_section(\"ERRORS\")"); menu_append_item(menu + ".&Section", "O&PTIONS", "manedit_insert_section(\"OPTIONS\")"); menu_append_item(menu + ".&Section", "&USAGE", "manedit_insert_section(\"USAGE\")"); menu_append_item(menu + ".&Section", "&FILES", "manedit_insert_section(\"FILES\")"); menu_append_item(menu + ".&Section", "EN&VIRONMENT", "manedit_insert_section(\"ENVIRONMENT\")"); menu_append_item(menu + ".&Section", "D&IAGNOSTICS", "manedit_insert_section(\"DIAGNOSTICS\")"); menu_append_item(menu + ".&Section", "SECURIT&Y", "manedit_insert_section(\"SECURITY\")"); menu_append_item(menu + ".&Section", "CONFOR&MING TO", "manedit_insert_section(\"CONFORMING TO\")"); menu_append_item(menu + ".&Section", "NO&TES", "manedit_insert_section(\"NOTES\")"); menu_append_item(menu + ".&Section", "&BUGS", "manedit_insert_section(\"BUGS\")"); menu_append_item(menu + ".&Section", "&AUTHOR", "manedit_insert_section(\"AUTHOR\")"); menu_append_item(menu + ".&Section", "SEE A&LSO", "manedit_insert_section(\"SEE ALSO\")"); menu_append_separator(menu + ".&Section"); menu_append_popup(menu + ".&Section", "Mis&c"); menu_append_item(menu + ".&Section.Mis&c", "&Generic", "manedit_insert_section(\"Section name\")"); menu_append_item(menu + ".&Section.Mis&c", "&Subsection", "manedit_insert_section(\"SS\")"); %}}} %{{{ Font menu_append_popup(menu, "&Font"); menu_append_item(menu + ".&Font", "&Bold", "manedit_insert_font(\".B\")"); menu_append_item(menu + ".&Font", "B&old/Italics", "manedit_insert_font(\".BI\")"); menu_append_item(menu + ".&Font", "Bo&ld/Roman", "manedit_insert_font(\".BR\")"); menu_append_separator(menu + ".&Font"); menu_append_item(menu + ".&Font", "&Italics", "manedit_insert_font(\".I\")"); menu_append_item(menu + ".&Font", "I&talics/Bold", "manedit_insert_font(\".IB\")"); menu_append_item(menu + ".&Font", "It&alics/Roman", "manedit_insert_font(\".IR\")"); menu_append_separator(menu + ".&Font"); menu_append_item(menu + ".&Font", "&Roman/Bold", "manedit_insert_font(\".RB\")"); menu_append_item(menu + ".&Font", "Ro&man/Italics", "manedit_insert_font(\".RI\")"); menu_append_separator(menu + ".&Font"); menu_append_item(menu + ".&Font", "Small/Bol&d", "manedit_insert_font(\".SB\")"); menu_append_item(menu + ".&Font", "&Small", "manedit_insert_font(\".SM\")"); menu_append_separator(menu + ".&Font"); menu_append_item(menu + ".&Font", "&Default size", "insert(\"\\\\*S\")"); %}}} %{{{ Indent menu_append_popup(menu, "&Indent"); menu_append_popup(menu + ".&Indent", "&Relative indent"); menu_append_item(menu + ".&Indent.&Relative indent", "&Start", "manedit_insert_relative_indent(1)"); menu_append_item(menu + ".&Indent.&Relative indent", "&End", "manedit_insert_relative_indent(0)"); menu_append_popup(menu + ".&Indent", "&Hanging indent"); menu_append_item(menu + ".&Indent.&Hanging indent", "&Normal", "manedit_insert_indented_paragraph(1)"); menu_append_item(menu + ".&Indent.&Hanging indent", "&Short tag", "manedit_insert_indented_paragraph(2)"); menu_append_item(menu + ".&Indent.&Hanging indent", "&Long tag", "manedit_insert_indented_paragraph(3)"); %}}} %{{{ Lists menu_append_popup(menu, "&Lists"); menu_append_item(menu + ".&Lists", "&Bullet", "manedit_insert_indented_paragraph(4)"); menu_append_item(menu + ".&Lists", "&Dash", "manedit_insert_indented_paragraph(5)"); menu_append_item(menu + ".&Lists", "&Number", "manedit_insert_indented_paragraph(6)"); menu_append_item(menu + ".&Lists", "&Alpha", "manedit_insert_indented_paragraph(7)"); %}}} %{{{ Hypertext menu_append_popup(menu, "&Hypertext"); menu_append_item(menu + ".&Hypertext", "&URL", "manedit_insert_hypertext(1)"); menu_append_item(menu + ".&Hypertext", "&Name", "manedit_insert_hypertext(2)"); %}}} %{{{ Symbol menu_append_popup(menu, "S&ymbol"); menu_append_item(menu + ".S&ymbol", "&Registration", "insert(\"\\\\*R\")"); menu_append_item(menu + ".S&ymbol", "&Trademark", "insert(\"\\\\*(Tm\")"); menu_append_item(menu + ".S&ymbol", "&Left quotemark", "insert(\"\\\\*(lq\")"); menu_append_item(menu + ".S&ymbol", "R&ight quotemark", "insert(\"\\\\*(rq\")"); menu_append_item(menu + ".S&ymbol", "&Backslash", "insert(\"\\\\e\")"); %}}} menu_append_item(menu, "&Paragraph", "manedit_insert_paragraph"); menu_append_separator(menu); menu_append_item(menu, "Te&mplate", "manedit_insert_template"); } %}}} public define manedit_mode() { set_mode("manedit", 1); use_syntax_table("manedit"); set_buffer_hook("par_sep", "manedit_parsep"); set_comment_info("manedit", ".\\\" ", "", 0); mode_set_mode_info("manedit", "init_mode_menu", &manedit_menu); run_mode_hooks("manedit_mode_hook"); } jedmodes-2.5.7/README.html0000644000175400017510000002215611301573545014127 0ustar mildemilde Jedmodes README

Jedmodes README

This are the source files of the CVS repository of the Jed Modes Repository, a collection of S-Lang scripts (modes) contributed by Jed users.

Some of the modes are experimental (while others work stable for their authors for ages), so USE AT YOUR OWN RISK.

No Warranty

The modes are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPL for more details.

Usage

  • Place the files you want to use in the search path for jed library files (cf. Help>Describe_Function get_jed_library_path)
  • See the individual modes for detailled usage instructions.

The libdir and make_ini modes provide an jed extension framework.

  • The functions add_libdir(dir, initialize=1) and append_libdir(dir, initialize=1) register a library dir for use by Jed
    • Prepend|Append path to the library path
    • Set Color_Scheme_Path, Jed_Doc_Files, and Jed_Highlight_Cache_Path
    • Evaluate (if existent) the file ini.sl in this directory to enable initialization (autoloads etc.). This is customizable by the optional second argument.
  • The functions in make_ini can be used to create such an ini.sl file. They can also preparse SLang files and create dfa syntax tables.

Contact

Mail hints, bug reports, praise and ideas to jed-users@jedsoft.org or direcly to the mode's authors.

Günter Milde

last change 2009-01-05

jedmodes-2.5.7/rst/0000755000175400017500000000000011477672140012423 5ustar mildegmjedmodes-2.5.7/rst/rst.sl0000644000175400017510000011454211477672140014272 0ustar mildemilde% rst.sl: Mode for reStructured Text % ********************************** % % Copyright (c) 2004, 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % ReStructuredText_ (from Python docutils_) is a revision of Structured % Text, a simple markup language that can be translated to Html and LaTeX (and % more, if someone writes a converter). % This mode turns Jed into an IDE for reStructured Text. % % .. _ReStructuredText: http://docutils.sourceforge.net/docs/rst/quickref.html % .. _docutils: http://docutils.sourceforge.net/ % % .. contents:: % % Versions % ======== % % .. class:: borderless % % ===== ========== ============================================================ % 1.1 2004-10-18 initial attempt % 1.2 2004-12-23 removed dependency on view mode (called by runhooks now) % 1.2.1 2005-03-11 bugfix in Mode>Layout>Hrule % bugfix remove spurious ":" from anonymous target markup % 1.3 2005-04-14 restructuring of the export and view functions % 1.3.1 2005-11-02 hide "public" in some functions % 1.3.2 2005-11-08 changed _implements() to implements() % 1.3.3 2006-01-09 separated Html and Latex output options % 1.4 2006-03-29 improved syntax highlight % removed dependency on ishell.sl % merged export help into set_rst2*_options() % nagivation buffer with tokenlist % 1.4.1 2006-05-18 fix syntax for sub- and supscript % conservative highlight of list markers % 1.4.2 2006-05-26 fixed autoloads (J. Sommer) % 1.5 new menu entry names matching the docutils use of terms % 1.5.1 2006-08-14 Adapted to structured_text v. 0.5 (do not call text_mode()). % 1.5.2 2006-11-27 Bugfix: let rst_mode() really call the structured_text_hook % 1.6 2006-11-28 Drop the .py ending from the Rst2* custom variables defaults % use do_shell_cmd() for error redirection % 1.7 2007-02-06 * Removed the Rst2*_Options custom variables. % (Set the command line options in Rst2*_Cmd and change % with set_export_options(cmd) (or from Mode menu)) % * "Directives" menu entry (incomplete) % * Support PDF export with rst2pdf.py % * Menu entries to browse docutils html documentation with % browse_url() (you probabely need to set % Rst_Documentation_Path on non Debian systems) % * goto error line from export output buffer (with filelist) % * section_markup(): go up if standing at the underline % * Erase the export output buffer before exporting % * rename rst_list_routines_hook() to % rst_list_routines_done() to match the new tokenlist.sl % 1.7.1 2007-02-26 * the rst2pdf.py script did not work. It is replaced by % `py.rest --topdf`. % 1.8 2007-03-13 Replace set_export_options() with set_export_cmd() % 1.8.1 2007-03-30 Unit testing and fixes % 1.8.2 2007-05-14 * removed leading \n from Markup_Tags, % (handled by insert_block_markup() since textutils 2.6.3) % * simplified dfa rules using ""R string suffix % * rst_levels: use String instead of List % 1.9 2007-07-23 * rename section_markup() to section_header(), allow % integer arguments (section level) % * new functions rst_view() and rst_view_html(), % rst_view_pdf, rst_view_latex obsoleting rst_browse() % 1.9.1 2007-10-18 * update to work with tokenlist.sl newer than 2007-05-09 % 1.9.2 2007-10-23 * Add admonitions popup to the Directives menu % * use hard-coded TAB in non-expanded (""R) syntax rules % * add '.' to chars allowed in crossreference marks % 2.0 2007-11-06 * highlight simple table rules % * fix fold info % * outline functionality (fold sections, fast moving) % 2.1 2007-11-13 * rewrite syntax highlight rules with ""$ string % replacement (Attention! can lead to segfaults with older, % buggy S-Lang versions: update S-Lang or downgrade rst.sl) % * more work on "rst-fold" % 2.2 2007-11-15 * custom colors. % 2.3 2008-01-11 * section headings: allow for adorning with overline, % * split outline and section functions to rst-outline.sl, % * implement J. Sommer's fix for DFA under UTF-8, % 2.3.1 2008-01-22 * made export_cmds static for better testing % and configuring. % 2.3.2 2008-05-05 * DFA fix for interpreted text % 2.3.3 2008-05-20 * one more DFA tweak % 2.4 2008-06-18 * line_block() % 2.4.1 2008-12-16 * chdir() in rst_export(), % as style-sheets are searched relative to the pwd. % 2.4.2 2009-01-27 * reset cwd after rst_export(), % 2.4.3 2009-10-05 * use reopen_file() in rst_view() (don't ask before reload) % 2.4.4 2009-12-09 * adapt to the changed require() behaviour in Jed 0.99.19 % 2.5 2010-12-08 XHTML (html4_strict) and XeTeX export. % ===== ========== ============================================================ % % TODO % ==== % % * jump from reference to target and back again % * "link creation wizard" % * Look at demo.txt and refine the syntax highlight % % Requirements % ============ % % from http://jedmodes.sf.net/mode/:: #if (_jed_version > 9918) require("structured_text", "Global"); % >= 0.5 require("rst-outline", "Global"); % outline with rst section markup #else require("structured_text"); % >= 0.5 require("rst-outline"); % outline with rst section markup #endif autoload("push_defaults", "sl_utils"); autoload("push_array", "sl_utils"); autoload("prompt_for_argument", "sl_utils"); autoload("get_blocal", "sl_utils"); autoload("popup_buffer", "bufutils"); autoload("buffer_dirname", "bufutils"); autoload("close_buffer", "bufutils"); autoload("fit_window", "bufutils"); autoload("run_buffer", "bufutils"); autoload("reopen_file", "bufutils"); % >= 1.19 autoload("insert_markup", "txtutils"); % >= 2.3 autoload("insert_block_markup", "txtutils"); % >= 2.3 autoload("mark_paragraph", "txtutils"); % Recommendations % =============== % % Jump to the error locations from output buffer:: #if (expand_jedlib_file("filelist.sl") != "") autoload("filelist_mode", "filelist"); #endif % Browse documentation:: #if (expand_jedlib_file("browse_url.sl") != "") autoload("browse_url", "browse_url"); #endif % Initialization % -------------- % % Name and Namespace % =================== % Namespace "rst" is defined in rst-outline.sl already required by this file:: provide("rst"); use_namespace("rst"); private variable mode = "rst"; % Customizable Defaults % ===================== % :: %!%+ %\variable{Rst2Html_Cmd} %\synopsis{ReStructured Text to Html converter} %\usage{String_Type Rst2Html_Cmd = "rst2html"} %\description % Shell command and options for the ReStructured Text to Html converter % % Command and options can be changed from the "Mode>Set Export Cmd >>>" menu % popup. However, these changes are only valid for the current jed session. % Permanent changes should be done by defining the variable in the jed.rc % file. %\notes % The default works if the executable `rst2html` is installed in the % PATH (e.g. with the Debian package python-docutils.deb). %\seealso{rst_mode, Rst2Latex_Cmd, Rst2Pdf_Cmd} %!%- custom_variable("Rst2Html_Cmd", "rst2html"); custom_variable("Rst2Xhtml_Cmd", "rst2html_strict"); %!%+ %\variable{Rst2Latex_Cmd} %\synopsis{ReStructured Text to LaTeX converter} %\usage{String_Type Rst2Latex_Cmd = "rst2latex"} %\description % Shell command and options for the ReStructured Text to LaTeX converter. % % Command and options can be changed from the "Mode>Set Export Cmd >>>" menu % popup. However, these changes are only valid for the current jed session. % Permanent changes should be done by defining the variable in the jed.rc % file. %\notes % The default works if the executable `rst2latex` is installed in the % PATH (e.g. with the Debian package python-docutils.deb). %\seealso{rst_mode, Rst2Pdf_Cmd, Rst2Html_Cmd} %!%- custom_variable("Rst2Latex_Cmd", "rst2latex"); %!%+ %\variable{Rst2XeTeX_Cmd} %\synopsis{ReStructured Text to LaTeX converter} %\usage{String_Type Rst2XeTeX_Cmd = "rst2latex"} %\description % Shell command and options for the ReStructured Text to LaTeX converter. % % Command and options can be changed from the "Mode>Set Export Cmd >>>" menu % popup. However, these changes are only valid for the current jed session. % Permanent changes should be done by defining the variable in the jed.rc % file. %\notes % The default works if the executable `rst2latex` is installed in the % PATH (e.g. with the Debian package python-docutils.deb). %\seealso{rst_mode, Rst2Pdf_Cmd, Rst2Html_Cmd} %!%- custom_variable("Rst2XeTeX_Cmd", "rst2xetex"); %!%+ %\variable{Rst2Pdf_Cmd} %\synopsis{ReStructured Text to LaTeX converter} %\usage{String_Type Rst2Pdf_Cmd = "rst2pdf.py"} %\description % Shell command and options for the ReStructured Text to LaTeX converter. % % Command and options can be changed from the "Mode>Set Export Cmd >>>" menu % popup. However, these changes are only valid for the current jed session. % Permanent changes should be done by defining the variable in the jed.rc % file. %\notes % The default works if the executable `py.rest` is installed in the % PATH (e.g. with the Debian package `python-codespeak-lib`). %\seealso{rst_mode, Rst2Pdf_Cmd, Rst2Html_Cmd} %!%- custom_variable("Rst2Pdf_Cmd", "py.rest --topdf"); %!%+ %\variable{Rst_Documentation_Path} %\synopsis{Base URL of the Docutils Project Documentation} %\usage{variable Rst_Documentation_Path = "file:/usr/share/doc/python-docutils/docs/"} %\description % Pointer to the Docutils Project Documentation % which will be opened by the Mode>Help>Doc Overview menu entry. % % The default works with the Debian "python-docutils" package. % Set to your local documentation mirror or "http://docutils.sf.net/docs/" %\seealso{rst_mode} %!%- custom_variable("Rst_Documentation_Path", "file:/usr/share/doc/python-docutils/docs/"); %!%+ %\variable{Rst_Html_Viewer} %\synopsis{External program to view HTML rendering of rst documents} %\usage{variable Rst_Html_Viewer = "firefox"} %\description % The command started by \sfun{rst_view_html} %\seealso{Rst_Pdf_Viewer, Rst2Html_Cmd, rst->rst_view, rst_to_html} %!%- custom_variable("Rst_Html_Viewer", "firefox"); custom_variable("Rst_Xhtml_Viewer", Rst_Html_Viewer); %!%+ %\variable{Rst_Pdf_Viewer} %\synopsis{External program to view PDF rendering of rst documents} %\usage{variable Rst_Pdf_Viewer = "xpdf"} % The command started by \sfun{rst_view_pdf} %\seealso{Rst_Html_Viewer, Rst2Pdf_Cmd, rst->rst_view, rst_to_pdf} %!%- custom_variable("Rst_Pdf_Viewer", "xpdf"); % Color Definitions % ----------------- % :: % defined since Jed 0-99.18 custom_color("bold", get_color("error")); custom_color("italic", get_color("operator")); custom_color("url", get_color("keyword")); custom_color("underline", get_color("delimiter")); % local extensions custom_color("rst_literal", get_color("bold")); custom_color("rst_interpreted", get_color("string")); custom_color("rst_substitution", get_color("preprocess")); custom_color("rst_list_marker", get_color("number")); % operator? custom_color("rst_line", get_color("underline")); custom_color("rst_reference", get_color("keyword")); custom_color("rst_target", get_color("keyword1")); custom_color("rst_directive", get_color("keyword2")); % Internal Variables % ------------------ % :: private variable helpbuffer = "*rst export help*"; % Pointer to the export command string for a given file extension static variable export_cmds = Assoc_Type[Ref_Type]; export_cmds["html"] = &Rst2Html_Cmd; export_cmds["xhtml"] = &Rst2Xhtml_Cmd; export_cmds["tex"] = &Rst2Latex_Cmd; export_cmds["xetex"] = &Rst2XeTeX_Cmd; export_cmds["pdf"] = &Rst2Pdf_Cmd; % Markup strings :: static variable Markup_Tags = Assoc_Type[Array_Type]; % Layout Character (inline) Markup_Tags["strong"] = ["**", "**"]; % bold Markup_Tags["emphasis"] = ["*", "*"]; % usually typeset as italics Markup_Tags["literal"] = ["``", "``"]; % usually fixed width Markup_Tags["interpreted"] = ["`", "`"]; Markup_Tags["subscript"] = [":sub:`", "`"]; Markup_Tags["superscript"] = [":sup:`", "`"]; % Layout Pragraph (block) Markup_Tags["hrule"] = ["\n-------------\n", ""]; % transition Markup_Tags["preformatted"] = ["::\n ", "\n"]; % References (outgoing links, occure in the text) Markup_Tags["hyperlink_ref"] = ["`", "`_"]; % hyperlink, anchor Markup_Tags["anonymous_hyperlink_ref"] = ["`", "`__"]; Markup_Tags["hyperlink_embedded"] = ["`<", ">`_"]; Markup_Tags["anonymous_hyperlink_embedded"] = ["`<", ">`__"]; % "one-off" hyperlink Markup_Tags["numeric_footnote_ref"] = ["", " [#]_"]; % automatic numbering Markup_Tags["symbolic_footnote_ref"] = ["", " [*]_"]; % automatic numbering Markup_Tags["citation_ref"] = ["[", "]_"]; % also for footnotes Markup_Tags["substitution_ref"] = ["|", "|"]; % Reference Targets Markup_Tags["hyperlink"] = [".. _", ":"]; % URL, crossreference Markup_Tags["anonymous_hyperlink"] = ["__ ", ""]; Markup_Tags["numeric_footnote"] = [".. [#] ", ""]; % automatic numbering Markup_Tags["symbolic_footnote"] = [".. [*] ", ""]; % automatic numbering Markup_Tags["citation"] = [".. [", "]"]; Markup_Tags["directive"] = [".. ", "::"]; Markup_Tags["substitution"] = [".. |", "|"]; % Functions % ========= % % Export % ------ % :: private define get_outfile(format) { if (format == "xetex") format = "tex"; % else if (format == "html") % format = "xhtml"; variable outfile = path_sans_extname(whatbuf())+ "." + format; outfile = path_concat(buffer_dirname(), outfile); return outfile; } % export the buffer/region to outfile using export_cmds[] static define rst_export() % (format, outfile=get_outfile(format)) { variable format, outfile, cwd=getcwd(); (format, outfile) = push_defaults( , , _NARGS); if (format == NULL) format = read_with_completion(strjoin(assoc_get_keys(export_cmds), ","), "Export buffer to ", "html", "", 's'); if (outfile == NULL) outfile = get_outfile(format); else if (outfile != "") % complete path if relative path is given outfile = path_concat(buffer_dirname(), outfile); % Assemble export command line: variable cmd = @export_cmds[format]; % do not specify outfile for `py.rest` if (extract_element(cmd, 0, ' ') == "py.rest") outfile = ""; cmd = strjoin([cmd, buffer_filename(), outfile], " "); save_buffer(); () = chdir(buffer_dirname()); % style-sheets are found relative to the pwd flush("exporting to " + format); popup_buffer("*rst export output*"); set_readonly(0); erase_buffer(); set_prefix_argument(1); do_shell_cmd(cmd); set_buffer_modified_flag(0); if (bobp and eobp) close_buffer(); else { fit_window(get_blocal("is_popup", 0)); #ifexists filelist_mode % jump to the error locations define_blocal_var("delimiter", ':'); define_blocal_var("line_no_position", 1); filelist_mode(); #endif } chdir(cwd); message("exported to " + outfile); } % export to html public define rst_to_html() { rst_export("html"); } public define rst_to_xhtml() { rst_export("xhtml"); } % export to LaTeX public define rst_to_latex() { rst_export("tex"); } % export to XeTeX public define rst_to_xetex() { rst_export("xetex"); } % export to PDF public define rst_to_pdf() { rst_export("pdf"); } % View output files % ----------------- % :: % View the rst document in `format' static define rst_view() % (format, outfile=get_outfile(format), viewer) { variable format, outfile, viewer; (format, outfile, viewer) = push_defaults( , , , _NARGS); if (format == NULL) format = read_with_completion(strjoin(assoc_get_keys(export_cmds), ","), "Export buffer to ", "html", "", 's'); if (outfile == NULL) outfile = get_outfile(format); else % complete path if relative path is given outfile = path_concat(buffer_dirname(), outfile); if (viewer == NULL) variable cmd_var = sprintf("Rst_%s_Viewer", strup(format[[:0]])+strlow(format[[1:]])); if (is_defined(cmd_var)) viewer = @(__get_reference(cmd_var)); else viewer = ""; % recreate outfile, if the buffer is newer save_buffer(); if (file_time_compare(buffer_filename(), outfile) > 0) rst_export(format, outfile); % open outfile with viewer (or in a new buffer, if viewer is empty string) if (viewer == "") { reopen_file(outfile); () = find_file(outfile); return; } % work around file loading bug in midori browser: % (expecting "file://" + relative file name !) if (viewer == "midori") outfile = "file://" + outfile; if (getenv("DISPLAY") != NULL) % assume X-Windows running () = system(viewer + " " + outfile + " &"); else () = run_program(viewer + " " + outfile); } % View the html conversion of the current buffer in an external browser public define rst_view_html() { rst_view("html"); } public define rst_view_xhtml() { rst_view("xhtml"); } % Find the LaTeX conversion of the current buffer public define rst_view_latex() % (outfile=*.tex, viewer="") { rst_view("tex"); } % Find the XeTeX conversion of the current buffer public define rst_view_xetex() % (outfile=*.tex, viewer="") { rst_view("xetex"); } % View the pdf conversion of the current buffer with Rst_Pdf_Viewer public define rst_view_pdf() % (outfile=*.pdf, viewer=Rst_Pdf_Viewer) { rst_view("pdf"); } % open popup-buffer with help for cmd % TODO: this is of more general interest. where to put it? static define command_help(cmd) { popup_buffer(helpbuffer, 1.0); set_prefix_argument(1); do_shell_cmd(extract_element(cmd, 0, ' ') + " --help"); fit_window(get_blocal("is_popup", 0)); set_buffer_modified_flag(0); call_function("view_mode"); bob(); } % set Rst2* (export command) command and options for export_type % (see private variable export_cmds for available export types, % e.g. "html", "tex", pdf") static define set_export_cmd(export_type) { variable cmd_var = export_cmds[export_type]; % variable reference @cmd_var = read_mini(strup(export_type)+" export cmd and options:", "", @cmd_var); } % Markup % ------ % :: % insert a markup static define markup(type) { insert_markup(Markup_Tags[type][0], Markup_Tags[type][1]); } % insert markup and (re) indent static define block_markup(type) { insert_block_markup(Markup_Tags[type][0], Markup_Tags[type][1]); } static define insert_directive(name) { !if (bolp()) newline(); vinsert(".. %s:: ", name); } % convert a region to a line block, i.e. prepend all lines with "| " % uses comment_region on visible region or paragraph static define line_block() { variable mode, flags; !if (is_visible_mark) mark_paragraph(); % switch to special mode to "fool" comment_region: (mode, flags) = what_mode(); set_mode("rst-line-block", 0); comment_region(); set_mode(mode, flags); } % Syntax Highlight % ================ % Sample files (on my box): % ~/Code/Python/docutils-svn/docutils/docs/user/rst/cheatsheet.txt % ~/Code/Python/docutils-svn/docutils/docs/user/rst/demo.txt % :: create_syntax_table (mode); define_syntax( '\\', '\\', mode); % escape character set_syntax_flags (mode, 0); % keywords % admonitions () = define_keywords_n(mode, "hintnote", 4, 0); () = define_keywords_n(mode, "attention", 9, 0); #ifdef HAS_DFA_SYNTAX %%% DFA_CACHE_BEGIN %%% % Inline Markup % % The rules for inline markup are stated in quickref.html. They cannot be % easily and fully translated to DFA syntax, as % % * in JED, DFA patterns do not cross lines % * excluding visible patterns outside the to-be-highlighted region via % e.g. [^a-z] will erroneously color allowed chars. % * also, [-abc.] must be written [\\-abc\\.] % % Therefore only a subset of inline markup will be highlighted correctly. % % Felix Wiemann recommendet in a mail at Docutils-users: % % You can have a look at docutils/parsers/rst/states.py. It contains all % the regular expressions needed to parse reStructuredText, even though % they may not be in the format in which you need them. % % :: private define dfa_rule(rule, color) { dfa_define_highlight_rule(rule, color, $1); } % Inline markup start-string and end-string recognition rules % ----------------------------------------------------------- % % If any of the conditions are not met, the start-string or end-string % will not be recognized or processed. % % 1. start-strings must start a text block or be immediately % preceded by whitespace or one of: ' " ( [ { < - / : % 2. start-strings must be immediately followed by non-whitespace. % 3. end-strings must be immediately preceded by non-whitespace. % 4. end-strings must end a text block or be immediately followed % by whitespace or one of: ' " ) ] } > - / : . , ; ! ? \ % 5. If a start-string is immediately preceded by a single or % double quote, "(", "[", "{", or "<", it must not be immediately followed % by the corresponding single or double quote, ")", "]", "}", or ">". % 6. An end-string must be separated by at least one character % from the start-string. % 7. An unescaped backslash preceding a start-string or end-string will % disable markup recognition, except for the end-string of inline literals. % See Escaping Mechanism above for details. % % Return a regexp pattern for inline markup with string `s`. % Due to limitations in Jed's DFA syntax, only a part of the algorithm can % be reproduced: % % * 1 and 5 not implemented: % % * matching char would be highlighted % * start|end of line or white (^|[ \t]) and ($|[ \t]) seems not to work % % * 2 and 3 extended: must not be followed by char of the start- end string % so **strong emphasis** is not highlit as *emphasis* % * 6 OK % * 7 only implemented for end-string (cf. 1, 4, and 5). % % Multi-line inline-markup will not be highlighted! % :: private define inline_rule(pat) { variable blank = " \t"; variable del = blank; % also tried: = "$blank'\")\]}>\-/:\.,;!\\?"R$; % boundaries variable rechts = "$pat[^$blank$pat]"R$; variable links = "[^$blank$pat]$pat"R$; % content % variable mitte = "[^$pat]+($pat[^$del][^$pat]+)*"R$; variable mitte = "([^$pat]|($pat[^$del$pat]))+"R$; return "$rechts$mitte$links"R$; } private define setup_dfa_callback(mode) { dfa_enable_highlight_cache("rst.dfa", mode); $1 = mode; % used by dfa_rule() % Character Classes: variable blank = " \t"; % white space variable alpha = "a-zA-Z"; % alphabetic characters variable alnum = "a-zA-Z0-9"; % alphanumeric characters % simple reference names (alphanumeric + internal [.-_]) variable label = "[$alnum]+([\.\-_][$alnum]+)*"R$; % Inline Markup dfa_rule(inline_rule("\*"R), "Qitalic"); dfa_rule(inline_rule("\|"R), "Qrst_substitution"); % dfa_rule(inline_rule(":", "rst_list_marker"); dfa_rule(inline_rule("\*\*"R), "Qbold"); dfa_rule(inline_rule("``"), "Qrst_literal"); % interpreted text, maybe with a role variable role_re = ":$label:"$; dfa_rule( inline_rule("`")+role_re, "Qrst_interpreted"); dfa_rule(role_re+inline_rule("`"), "Qrst_interpreted"); % cannot be defined as "Q", as this prevents `link`_ highlight dfa_rule( inline_rule("`"), "rst_interpreted"); % Literal Block marker dfa_rule("::[$blank]*$"$, "rst_literal"); % Doctest Block marker dfa_rule("^[$blank]*>>>"$, "rst_literal"); % Reference Marks % URLs and Email dfa_rule("(https?|ftp|file)://[^ \t>]+", "url"); dfa_rule("(mailto:)?$label@$label"$, "url"); % simple crossreferences dfa_rule("${label}__?"R$, "rst_reference"); % revert false positives dfa_rule("${label}_${label}"R$, "normal"); % reference with backticks dfa_rule("`(\\`|[^`])*`__?", "Qrst_reference"); % footnotes and citations dfa_rule("\[([#\*]|#?$label)\]_"R$, "rst_reference"); % Reference Targets % inline target dfa_rule("_`[^`]+`"R, "rst_target"); dfa_rule("_${label}"R$, "rst_target"); % named crosslinks dfa_rule("^[$blank]*\.\.[$blank]+_[^:]+:[$blank]"R$, "rst_target"); dfa_rule("^[$blank]*\.\.[$blank]+_[^:]+:$"R$, "rst_target"); % anonymous dfa_rule("^__[$blank]"$, "rst_target"); % footnotes and citations dfa_rule("^[$blank]*\.\.[$blank]+\[([#\*]|#?$label)\]"R$, "rst_target"); % substitution definitions dfa_rule("^[$blank]*\.\.[$blank]+\|.*\|[$blank]+$label::"R$, "rst_directive"); % Comments dfa_rule("^[$blank]*\.\.[$blank]"R$, "Pcomment"); dfa_rule("^[$blank]*\.\.$"R, "comment"); % Directives dfa_rule("^\.\.[$blank][^ ]+[$blank]?::"R$, "rst_directive"); % Lists % itemize dfa_rule("^[$blank]*[\-\*\+][$blank]+"R$, "Qrst_list_marker"); % enumerate: number, single letter, roman or #; formatting: #. #) (#) variable enumerator = "([0-9]+|[a-zA-Z]|[ivxlcdmIVXLCDM]+|#)"; dfa_rule("^[$blank]*$enumerator[\)\.][$blank]+"R$, "rst_list_marker"); dfa_rule("^[$blank]*\($enumerator\)[$blank]+"R$, "rst_list_marker"); % field list dfa_rule("^[$blank]*:[^ ].*[^ ]:[$blank]"R$, "Qrst_list_marker"); dfa_rule("^[$blank]*:[^ ].*[^ ]:$$"R$, "Qrst_list_marker"); % option list variable option = "([\-/][a-zA-Z0-9]|--[a-zA-Z=]+)([\-= ][a-zA-Z0-9]+)*"R$; dfa_rule("^[$blank]*$option(, $option)* "R$, "rst_list_marker"); dfa_rule("^[$blank]*$option(, $option)* ?$$"R$, "rst_list_marker"); % dfa_rule("^[$blank]*$option(, $option)*( +|$$)"R$, "rst_list_marker"); % definition list % doesnot work as jed's DFA regexps span only one line % Line Block and Table VLines % false positives (any `` | ``), as otherwise table vlines would not work dfa_rule("[$blank]\|[$blank]"R$, "rst_line"); dfa_rule("^\|[$blank]"R$, "rst_line"); dfa_rule("[$blank]\|$"R$, "rst_line"); dfa_rule("^\|$"R$, "rst_line"); % Tables % simple tables dfa_rule("^[$blank]*=+( +=+)*[$blank]*$"$, "rst_line"); dfa_rule("^[$blank]*-+( +-+)*[$blank]*$"$, "rst_line"); % grid tables dfa_rule("^[$blank]*\+-+\+"R$, "rst_line"); dfa_rule("^[$blank]*\+-+\+(-+\+)*"R$, "rst_line"); dfa_rule("^[$blank]*\+=+\+(=+\+)*"R$, "rst_line"); % Hrules and Sections % dfa_rule(Underline_Regexp, "rst_transition"); % doesnot work, as DFA regexps do not support "\( \) \1"-syntax. % So we have to resort to separate rules foreach $2 ("*=-~\"'`^:+#<>_") % Rst_Underline_Chars (verbatim, to enable cache generation) { $2 = str_quote_string(char($2), "^$[]*.+?", '\\'); $2 = sprintf("^%s%s+[$blank]*$"$, $2, $2); dfa_rule($2, "rst_line"); } % Special Unicode characters dfa_rule(" ", "Qtrailing_whitespace"); % no-break space dfa_rule("­", "Qtrailing_whitespace"); % soft hyphen % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_rule("[^ -~]+", "normal"); dfa_build_highlight_table(mode); } dfa_set_init_callback(&setup_dfa_callback, "rst"); %%% DFA_CACHE_END %%% enable_dfa_syntax_for_mode(mode); #else % define_syntax( '`', '"', mode); % strings define_syntax ("..", "", '%', mode); % Comments define_syntax ("[", "]", '(', mode); % Delimiters define_syntax ("0-9a-zA-Z", 'w', mode); % Words % define_syntax ("-+*=", '+', mode); % Operators % define_syntax ("-+0-9.", '0', mode); % Numbers % define_syntax (",", ',', mode); % Delimiters % define_syntax (";", ',', mode); % Delimiters #endif % Keymap % ====== % :: !if (keymap_p(mode)) make_keymap(mode); % the backtick is is needed too often to be bound to quoted insert definekey("self_insert_cmd", "`", mode); % I recommend "°" but this might not be everyones favourite % definekey("self_insert_cmd", "°", mode); % Fallback: _Reserved_Key_Prefix+"`": definekey_reserved("quoted_insert", "`", mode); % % "&Layout"); "l", mode); definekey_reserved("rst->heading", "ls", mode); % "&Section" definekey_reserved("rst->block_markup(\"preformatted\")", "lp", mode); % "P&reformatted" definekey_reserved("rst->markup(\"emphasis\")", "le", mode); % "&Emphasis" definekey_reserved("rst->markup(\"strong\")", "ls", mode); % "&Strong" definekey_reserved("rst->markup(\"literal\")", "ll", mode); % "&Literal" definekey_reserved("rst->markup(\"subscript\")", "lb", mode); % "Su&bscript" definekey_reserved("rst->markup(\"superscript\")", "lp", mode); % "Su&bscript" definekey_reserved("rst->markup(\"hrule\")", "lh", mode); % "&Hrule" definekey_reserved("comment_region_or_line\")", "lc", mode); % "&Comment" % "&References\")", % "", mode); definekey_reserved("rst->markup(\"hyperlink_ref\")", "rh", mode); % "&Reference (link)" definekey_reserved("rst->markup(\"anonymous_hyperlink_ref\")", "ra", mode); % "&Anonymous Reference" definekey_reserved("rst->markup(\"numeric_footnote_ref\")", "rf", mode); % "&Footnote" definekey_reserved("rst->markup(\"symbolic_footnote_ref\")", "rs", mode); % "&Symbolic Footnote" definekey_reserved("rst->markup(\"citation_ref\")", "rc", mode); % "&Citation" definekey_reserved("rst->markup(\"substitution_ref\")", "rs", mode); % "&Substitution" % "Reference &Targets\")", % "", mode); definekey_reserved("rst->markup(\"hyperlink\")", "tr", mode); % "&Reference (link)" definekey_reserved("rst->markup(\"anonymous_hyperlink\")", "ta", mode); % "&Anonymous Reference" definekey_reserved("rst->markup(\"numeric_footnote\")", "tf", mode); % "&Footnote" definekey_reserved("rst->markup(\"symbolic_footnote\")", "ts", mode); % "&Symbolic Footnote" definekey_reserved("rst->markup(\"citation\")", "tc", mode); % "&Citation" definekey_reserved("rst->markup(\"directive\")", "td", mode); % "&Directive" definekey_reserved("rst->markup(\"substitution\")", "ts", mode); % "&Substitution" % "&Export\")", % "", mode); definekey_reserved("rst_to_html", "eh", mode); % "&HTML" definekey_reserved("rst_to_latex", "el", mode); % "&LaTeX" definekey_reserved("rst_to_xetex", "ex", mode); % "&XeTeX" definekey_reserved("rst_to_pdf", "ep", mode); % "&PDF" % "Set Export &Cmd" definekey_reserved("rst->set_export_cmd(\"html\")", "oh", mode); % "&HTML" definekey_reserved("rst->set_export_cmd(\"tex\")", "ol", mode); % "&LaTeX" definekey_reserved("rst->set_export_cmd(\"xetex\")", "ox", mode); % "&XeTeX" definekey_reserved("rst->set_export_cmd(\"pdf\")", "op", mode); % "&PDF" % "&View\")", % "", mode); definekey_reserved("rst_view_html", "vh", mode); % "&HTML" definekey_reserved("rst_view_latex", "vl", mode); % "&LaTeX" definekey_reserved("rst_view_xetex", "vx", mode); % "&XeTeX" definekey_reserved("rst_view_pdf", "vp", mode); % "&PDF" % "", mode); #ifexists list_routines definekey_reserved("list_routines", "n", mode); % &Navigator" #endif % Mode Menu % ========= % :: % append a new popup to menu and return the handle static define new_popup(menu, popup) { menu_append_popup(menu, popup); return strcat(menu, ".", popup); } static define rst_menu(menu) { variable popup; popup = new_popup(menu, "Block &Markup"); % ^CP... Paragraph styles, etc. (

,
,


,
, etc.) menu_append_item(popup, "&Section", "rst->heading"); menu_append_item(popup, "P&reformatted", &block_markup, "preformatted"); menu_append_item(popup, "&Hrule", &markup, "hrule"); menu_append_item(popup, "&Directive", &markup, "directive"); menu_append_item(popup, "&Comment", "comment_region_or_line"); menu_append_item(popup, "&Line Block", "rst->line_block"); % ^CS... Character styles (, , , , etc.) popup = new_popup(menu, "&Inline Markup"); menu_append_item(popup, "&Emphasis", &markup, "emphasis"); menu_append_item(popup, "&Literal", &markup, "literal"); menu_append_item(popup, "&Interpreted", &markup, "interpreted"); menu_append_item(popup, "&Strong", &markup , "strong"); menu_append_item(popup, "Su&bscript", &markup, "subscript"); menu_append_item(popup, "Su&perscript", &markup, "superscript"); % References (outgoing links) popup = new_popup(menu, "&References (outgoing links)"); menu_append_item(popup, "&Hyperlink", &markup, "hyperlink_ref"); menu_append_item(popup, "&Anonymous Hyperlink", &markup, "anonymous_hyperlink_ref"); menu_append_item(popup, "&Embedded Hyperlink", &markup, "hyperlink_embedded"); menu_append_item(popup, "&One-off Hyperlink", &markup, "anonymous_hyperlink_embedded"); menu_append_item(popup, "Numeric &Footnote", &markup, "numeric_footnote_ref"); menu_append_item(popup, "&Symbolic Footnote", &markup, "symbolic_footnote_ref"); menu_append_item(popup, "&Citation", &markup, "citation_ref"); menu_append_item(popup, "&Substitution", &markup, "substitution_ref"); % Reference Targets popup = new_popup(menu, "&Targets"); menu_append_item(popup, "&Hyperlink (URL)", &markup, "hyperlink"); menu_append_item(popup, "&Anonymous Hyperlink", &markup, "anonymous_hyperlink"); menu_append_item(popup, "Numeric &Footnote", &markup, "numeric_footnote"); menu_append_item(popup, "&Symbolic Footnote", &markup, "symbolic_footnote"); menu_append_item(popup, "&Citation", &markup, "citation"); menu_append_item(popup, "&Substitution", &markup, "substitution"); % Directives popup = new_popup(menu, "&Directives"); menu_append_item(popup, "Table of &Contents", &insert_directive, "contents"); menu_append_item(popup, "&Number Sections", &insert_directive, "sectnum"); menu_append_item(popup, "Ima&ge", &insert_directive, "image"); menu_append_item(popup, "&Figure", &insert_directive, "figure"); menu_append_item(popup, "T&able", &insert_directive, "table"); menu_append_item(popup, "&CSV Table", &insert_directive, "csv-table"); menu_append_item(popup, "&Title", &insert_directive, "title"); menu_append_item(popup, "&Include", &insert_directive, "include"); menu_append_item(popup, "&Raw", &insert_directive, "raw"); popup = new_popup(popup, "&Admonitions"); menu_append_item(popup, "&Admonition", &insert_directive, "admonition"); menu_append_item(popup, "&attention", &insert_directive, "attention"); menu_append_item(popup, "&caution", &insert_directive, "caution"); menu_append_item(popup, "&danger", &insert_directive, "danger"); menu_append_item(popup, "&error", &insert_directive, "error"); menu_append_item(popup, "&hint", &insert_directive, "hint"); menu_append_item(popup, "&important", &insert_directive, "important"); menu_append_item(popup, "¬e", &insert_directive, "note"); menu_append_item(popup, "&tip", &insert_directive, "tip"); menu_append_item(popup, "&warning", &insert_directive, "warning"); menu_append_separator(menu); % Navigation #ifexists list_routines menu_append_item(menu, "&Navigator", "list_routines"); menu_append_separator(menu); #endif % Export to a target file popup = new_popup(menu, "&Export"); menu_append_item(popup, "X&html", "rst_to_xhtml"); menu_append_item(popup, "&HTML", "rst_to_html"); menu_append_item(popup, "&LaTeX", "rst_to_latex"); menu_append_item(popup, "&XeTeX", "rst_to_xetex"); menu_append_item(popup, "&PDF", "rst_to_pdf"); % View target file popup = new_popup(menu, "&View"); menu_append_item(popup, "X&html", "rst_view_xhtml"); menu_append_item(popup, "&HTML", "rst_view_html"); menu_append_item(popup, "&LaTeX", "rst_view_latex"); menu_append_item(popup, "&XeTeX", "rst_view_xetex"); menu_append_item(popup, "&PDF", "rst_view_pdf"); % Set export command popup = new_popup(menu, "Set Export &Cmd"); menu_append_item(popup, "X&html", &set_export_cmd, "xhtml"); menu_append_item(popup, "&HTML", &set_export_cmd, "html"); menu_append_item(popup, "&LaTeX", &set_export_cmd, "tex"); menu_append_item(popup, "&XeTeX", &set_export_cmd, "xetex"); menu_append_item(popup, "&PDF", &set_export_cmd, "pdf"); % Help commands menu_append_separator(menu); popup = new_popup(menu, "&Help"); #ifexists browse_url menu_append_item(popup, "Doc &Index", "browse_url", path_concat(Rst_Documentation_Path, "index.html")); menu_append_item(popup, "&Quick Reference", "browse_url", path_concat(Rst_Documentation_Path, "user/rst/quickref.html")); menu_append_item(popup, "&Directives", "browse_url", path_concat(Rst_Documentation_Path, "ref/rst/directives.html")); menu_append_separator(popup); #endif menu_append_item(popup, "rst2x&html Help", &command_help, Rst2Xhtml_Cmd); menu_append_item(popup, "rst2&Html Help", &command_help, Rst2Html_Cmd); menu_append_item(popup, "rst2&latex Help", &command_help, Rst2Latex_Cmd); menu_append_item(popup, "rst2&xetex Help", &command_help, Rst2XeTeX_Cmd); % Default conversion and browse menu_append_item(menu, "&Run Buffer", "run_buffer"); } % Rst Mode % ======== % % :: % set the comment string set_comment_info(mode, ".. ", "", 0); % "comment string" for line-block: set_comment_info("rst-line-block", "| ", "", 1|4); % Modify line_is_blank() from structured_text.sl % let section heading underlines separate paragraphs % (rst does not require a blank line after a section title) define line_is_blank() { bol_skip_white(); if (eolp()) return 1; return is_heading_underline(); } public define rst_mode() { set_mode(mode, 1); % indent|format with structured_text_hook from structured_text.sl structured_text_hook(); use_syntax_table(mode); % use_keymap (mode); mode_set_mode_info(mode, "fold_info", ".. {{{\r.. }}}\r\r"); mode_set_mode_info(mode, "init_mode_menu", &rst_menu); mode_set_mode_info("run_buffer_hook", &rst_to_html); mode_set_mode_info("dabbrev_word_chars", get_word_chars()); % define_blocal_var("help_for_word_hook", &rst_help); run_mode_hooks(mode + "_mode_hook"); } jedmodes-2.5.7/rst/rst-outline.sl0000664000175400017500000007155311307555454015265 0ustar mildegm% rst-outline.sl: Outline with `reStructuredText` section markup % ============================================================== % % Copyright (c) 2007 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % .. contents:: % % Usage % ----- % % Place in the jed library path. % % * rst.sl will require() this file, % * other modes can use it for outlining according to reStructured Text % section markup in comments. % % TODO: describe activation and bindings. % % Versions % -------- % % .. class:: borderless % % ===== ========== ========================================================== % 0.1 2007-11-20 * split from rst.sl % * allow for overline chars % 0.1.1 2008-01-16 * bugfix in heading() % (for numerical arg without existing adornments) % 0.1.2 2008-01-22 * bugfix: KP keybindings require x-keydefs % ===== ========== ========================================================== % % Requirements % ------------ % % standard modes:: require("comments"); % extra modes (from http://jedmodes.sf.net/mode/):: autoload("string_repeat", "strutils"); #if (_jed_version > 9918) require("x-keydefs", "Global"); #else require("x-keydefs"); #endif % Navigation buffer (navigable table of contents) with % http://jedmodes.sf.net/mode/tokenlist :: #if (expand_jedlib_file("tokenlist.sl") != "") autoload("list_routines", "tokenlist"); % >= 2006-12-19 #endif % Initialization % ============== % % Name and Namespace % ------------------ % :: provide("rst-outline"); implements("rst"); % Customizable Defaults % --------------------- % :: %!%+ %\variable{Rst_Underline_Chars} %\synopsis{Characters used for underlinign of section titles} %\usage{variable Rst_Underline_Chars = "*=-~\"'`^:+#<>_"} %\description % String of non-alphanumeric characters that serve as underlining chars % (adornments) for section titles. % Order is important - as default oder for the section level (overwritten % by existing use of adornment chars in the current buffer). %\seealso{rst->heading} %!%- custom_variable("Rst_Underline_Chars", "*=-~\"'`^:+#<>_"); % Internal Variables % ------------------ % :: private variable Last_Adornment = "="; private variable blank = " \t"; private variable uchars = str_replace_all(Rst_Underline_Chars, "-", "\-"R); static variable Underline_Regexp = "^\([$uchars]\)\1+[$blank]*$"R$; % static variable Underline_PcRegexp = "^([$uchars])\1+$blank*$"R$; % String of sorted adornment codes, e.g. "** * = - ~ _" % An adornment code is a 2-char string with "" % Used and amended with section_level() % (re)set from existing section titles with update_adornments() % :: private variable adornments = ""; % Functions % ========= % % Auxiliary functions % ------------------- % % % Return the length of the line (excluding whitespace). % auxiliary fun for is_heading_underline() and heading():: private define get_line_len() { eol(); bskip_white(); what_column() - 1; % push return value on stack bol(); } % Go down exactly n lines, appending newlines if reaching end of buffer. % Point is left at bol. :: static define go_down_exactly(n) { loop (n - down(n)) { eol(); newline(); } } % Go to the title line of a heading if on either title line or adornment lines % % Used by heading(), so there could be % * no adornment or "wrong" adornment when called. % * blank title line (transition) % * underline only or under and overline static define goto_heading_title() { bol(); !if (re_looking_at(Underline_Regexp)) return; % assume we are at title line (or blank line) % Try if there is a title line above variable n = up_1(); bol(); if (re_looking_at(".*[a-zA-Z0-9]")) return; % there is some text, assume this is the title % Try if there is a title line below the adornment line push_mark(); go_down(n+1); % go back to line over start-line if there is no title here pop_mark(not(re_looking_at(".*[a-zA-Z0-9]"))); } % Check whether the point is in a line underlining a section title. % (underline is equal or longer than previous line and previous line is % no adornment line and non-blank). % Leave point at bol of underline. define is_heading_underline() { !if (up(1)) % already on first line return 0; % Get length of heading variable heading_len = get_line_len(); if (not(re_looking_at(".*[a-zA-Z0-9]"))) heading_len = 0; go_down_1(); !if (heading_len) % blank line, no heading return 0; % Compare to length of adornment return get_line_len() >= heading_len; } % Test whether the current heading has a valid overline adornment % Call with point at underline. static define has_overline() { push_spot(); EXIT_BLOCK { pop_spot(); } variable underline = strtrim_end(line_as_string()); if (underline == "") return 0; % no adornment at all if (up(2) < 2) return 0; % bob reached, no overline !if (bol(), looking_at(underline)) return 0; % line is not identic (fails to detect a longer overline) return not(is_heading_underline()); } % Return symbol for current section heading adornment, e.g. % " *" underlined with "*", % "**" over- and underlined with "*" % Point must be at bol of underline and will stay there. private define what_adornment() { !if (re_looking_at(Underline_Regexp)) return " "; if (has_overline()) return string_repeat(char(what_char()), 2); else return " " + char(what_char()); } static define bsearch_heading(); % forward declaration % Return level of section heading adorned with `adornment' % (starting with level 1 == H1) % Add adornment to list of adornments if not found there. static define section_level(adornment) { variable i = is_substr(adornments, adornment); if (i) return (i+1)/2; if (adornment == " " or adornment == " \n") { push_spot(); i = bsearch_heading() + 1; % maximal allowed level pop_spot(); return i+1; % one more than max-level } adornments += adornment; return strlen(adornments)/2; } % Search next section title, return section level or 0. % Point is placed at the bol of the underline. % Skip current line. (This way, repeating the command will find next heading.) % Skip sections titles with a level higher than \var{max_level} if != 0. % Skip hidden headings if \var{skip_hidden} is TRUE. static define fsearch_heading() % (max_level=0, skip_hidden=0) { variable level, max_level, skip_hidden; (max_level, skip_hidden) = push_defaults(0, 0, _NARGS); !if (max_level) max_level = 1000; while (eol(), re_fsearch(Underline_Regexp)) { if (skip_hidden and is_line_hidden()) continue; !if (is_heading_underline) continue; % get adornment and compute section level level = section_level(what_adornment()); if (level <= max_level) return level; } return 0; } % search previous section title, return level or 0 static define bsearch_heading() % (max_level=0, skip_hidden=0) { variable level, max_level, skip_hidden; (max_level, skip_hidden) = push_defaults(0, 0, _NARGS); !if (max_level) max_level = 1000; while (re_bsearch(Underline_Regexp)) { if (skip_hidden and is_line_hidden()) continue; !if (is_heading_underline) continue; level = section_level(what_adornment()); if (level <= max_level) return level; } return 0; } % update the sorted listing of section title adornment codes, % An adornment code is a 2-char string with "" static define update_adornments() { variable l_max, ch; adornments = ""; % reset private var % List underline characters used for sections in the document push_spot_bob(); while (fsearch_heading()) !if (down_1()) break; pop_spot(); % show("adornments", adornments); } % extract adornment code for given level from the static var adornments % or the next unused one from Rst_Underline_Chars that follows adornment of % heading level-1 private define get_adornment_code(level) ; % forward declaration private define get_adornment_code(level) { % Look in already defined heading adornments variable adornment = strtrim(substr(adornments, level*2-1, 2)); if (adornment != "") return adornment; % New level: get a new adornment code if (level == 1) % no headings in present document return Rst_Underline_Chars[[0]]; % Return "best choice" for next level adornment % get a sorted tuple of all "canonical" adornments, % starting with the one that follows the adornment of level-1 heading variable ads = Rst_Underline_Chars+Rst_Underline_Chars; variable current_ad = get_adornment_code(level-1)[[0]]; variable ch, start = is_substr(ads, current_ad); ads = substr(ads, start, -1); % return the first un-used foreach ch (ads) { adornment = char(ch); !if (is_substr(adornments, adornment)) { return adornment; } } } % Navigation % ---------- % :: % Go to the next section title. % Skip headings with level above max_level and hidden headings % Place point at bol of title line. static define next_heading() % (max_level=100) { variable max_level = push_defaults(100, _NARGS); go_down_1(); if (fsearch_heading(max_level, 1)) { go_up_1(); bol(); } else eob; } % Go to the previous section title. % Skip headings with level above max_level and hidden headings % Place point at bol of title line. static define previous_heading() % (max_level=100) { variable max_level = push_defaults(100, _NARGS); if (bsearch_heading(max_level, 1)) { go_up_1(); bol(); } else bob; } %!%+ %\function{rst->skip_section} %\synopsis{Go to the next heading of same level or above} %\usage{skip_section()} %\description % Skip content, hidden headings and sub-headings. %\notes % Point is placed at bol of heading line or eob %\seealso{rst_mode; rst->heading} %!%- static define skip_section() { update_adornments(); go_down(2); variable level = bsearch_heading(); if (level == 0) next_heading(); else next_heading(level); } % Go to the previous section title of same level or above, % skip content and sub-sections. static define bskip_section() { update_adornments(); go_down(2); previous_heading(bsearch_heading()); } % Go to section title of containing section (one level up) static define up_section() { update_adornments(); go_down(2); previous_heading(bsearch_heading()-1); } static define mark_section() { update_adornments(); go_down(2); variable level = bsearch_heading(); if (level == 0) error("there is no section to mark"); push_visible_mark(); next_heading(level); } % Editing % ------- % :: %!%+ %\function{rst->heading} %\synopsis{Mark up current line as section title} %\usage{heading([level])} %\description % Mark up current line as section title by adorning it with underline (and % possibly overline) according to \var{level}. Replace existing adornments. % % If \var{level} is an Integer (or a String convertible to an Integer), use % the adornment for this section level. Valid levels range from 1 to `level % of the previous heading` + 1 (this is a restriction of reStructured Text % syntax). % % Otherwise, \var{level} must be a String containing the adornment code, e.g. % "*", " *", or "* ": underline with "*", % "**" : over- and underline with "*" % %\notes % If the argument is not supplied, it is read from the minbuffer: % * "canonical" adornments are listed starting with already used ones % sorted by level. % % "Canonical" adornment characters are defined in Rst_Underline_Chars. % Only these are highlited and only these work with the section visibility % and movement functions. % %\seealso{rst_mode, Rst_Underline_Chars} %!%- static define heading() % ([level]) { % Get and convert optional argument % --------------------------------- variable level = push_defaults( , _NARGS); variable ch, adornment, l_max=0; % Update defaults if (typeof(level) == Integer_Type or level == NULL) { % update the listing of adornment characters used in the document update_adornments(); % get level of previous heading, as rst-headings cannot skip levels push_spot(); l_max = bsearch_heading() + 1; pop_spot(); } % Read from minibuffer if (level == NULL) { level = read_mini(sprintf("Specify adornment [%s] or level [1-%d]:", Rst_Underline_Chars, l_max), Last_Adornment, ""); } % Convert numeral to Integer if (andelse{typeof(level) == String_Type} {string_match(level,"^[0-9]+$" , 1)}) level = integer(level); % Convert level to adornment code: if (typeof(level) == Integer_Type) { % check if level is allowed if (level < 1) verror("Level %d not supported. Top level is 1.", level); else if (level > l_max) { vmessage("Level %d not supported at this place (not in [1,%d])", level, l_max); adornment = ""; } else adornment = get_adornment_code(level); } else adornment = strtrim(level); % Store as default Last_Adornment = adornment; % Replace adornments % ------------------ % Go to bol of the (maybe blank) underline. Append line if necessary. % Point can be at any of: overline, heading line, underline goto_heading_title(); go_down_exactly(1); % Delete matching overline if (has_overline()) { go_up(2); delete_line(); go_down_1(); } % Delete underline if (re_looking_at(Underline_Regexp)) delete_line(); % Abort if there is nothing new to insert if (strtrim(adornment) == "") { go_down_1(); return; } % Get the title length go_up_1(); variable len = get_line_len(); % point is left at bol !if (len) % transition len = WRAP; % New overline if (strlen(adornment) == 2) insert(string_repeat(substr(adornment, 1, 1), len) + "\n"); % New underline go_down_1(); insert(string_repeat(substr(adornment, 1, 1), len) + "\n"); } % increase (or decrease) section level by `n' static define promote_heading(n) { update_adornments(); % move point to bol of adornment line bol(); !if (re_looking_at(Underline_Regexp)) go_down_exactly(1); % get current level, add n variable level = section_level(what_adornment()) + n; go_up_1(); if (level < 1) error("Cannot promote above top-level"); % change adornment heading(level); go_up(2); } % Rewrite heading adornments to follow the level-ordering given in a sample % string (default Rst_Underline_Chars) static define normalize_headings() { update_adornments(); variable chars = read_mini("New adornment list", "", Rst_Underline_Chars[[:strlen(adornments)/2]]); push_spot_bob(); variable level = fsearch_heading(); while (level) { heading(substr(chars, level, 1)); level = fsearch_heading; } pop_spot(); } % Navigator (outline buffer) % ========================== % % Use Marko Mahnics tokenlist.sl to create a navigation buffer with all section % titles. % % TODO: navigator mode with bindings for re-ordering of sections % :: #ifexists list_routines % message("tokenlist present"); % rst mode's hook for tkl_list_tokens(): % % tkl_list_tokens searches for a set of regular expressions defined % by an array of strings arr_regexp. For every match tkl_list_tokens % calls the function defined in the string fn_extract with an integer % parameter that is the index of the matched regexp. At the time of the % call, the point is at the beginning of the match. % % The called function should return a string that it extracts from % the current line. % % :: % extract section title and format for tokenlist static define extract_heading(regexp_index) { variable adornment, title, level, indent; % point is, where fsearch_heading() leaves it % (at first matching adornment character) % Get adornment code adornment = what_adornment(); % Get section title go_up_1(); title = strtrim(line_as_string()); go_down_1(); % show(what_line, adornment, title); % Format % do not indent at all (simple, missing information) % return(sprintf("%s %s", adornment, title)); level = section_level(adornment); % indent = string_repeat(" ", (level-1)*2); indent = string_repeat(" ", (level-1)); % indent by 2 spaces/level, adornment as marker (best) return sprintf("%s%s %s", indent, adornment, title); } % Set up list_routines for rst mode public define rst_list_routines_setup(opt) { adornments = ""; % reset, will be updated by fsearch_heading opt.list_regexp = &fsearch_heading; opt.fn_extract = &extract_heading; } #endif % Folding % ======= % :: % Fold whole buffer % % Hide section content and headings with a level above max_level % % 0: unfold (show all lines) % n: hide section headings with level > n % % * use with narrow() to fold a sub-tree (or see fold_section()) % * a prefix argument will override \var{max_level} static define fold_buffer(max_level) { max_level = prefix_argument(max_level); push_spot(); % Undo previous hiding mark_buffer(); set_region_hidden(0); % Abort now, if we want to unfold if (max_level == 0) { pop_spot(); return; } update_adornments(); % Start: place point below first heading % (we cannot use next_heading() as this skips heading in line) bob(); if (fsearch_heading(max_level)) go_down_1(); else eob; % Set section content hidden but % leave headings and underlines with a level below max-level visible while (not(eobp())) { push_mark(); next_heading(max_level); !if (eobp()) go_up_1(); % leave the next heading line visible set_region_hidden(1); go_down(3); % skip heading line and underline } pop_spot(); } % Find out up to which level headings are hidden % Return: % % n<0 -n levels of headings in document, none hidden % 0 no hidden lines % n>0 headings with level > n are hidden % % Leaves the point at first hidden heading or last non-hidden heading private define get_fold_level() { variable level, max_level=0; bob(); do { level = fsearch_heading(); if (level and is_line_hidden()) return level-1; max_level = int(_max(max_level, level)); } while (level != 0); % no hidden heading % test for hidden content lines bob(); skip_hidden_lines_forward(0); if (is_line_hidden()) return -max_level; else return 0; } % Increment buffer fold by `increment': % increment > 0: increase fold-level (hide more headings) % increment < 0: decrease fold-level (show more headings) % Calls rst->fold_buffer() and hence hides all section content. % % * If the minimal fold level (1) is reached, decrementing is without effect. % * If all headings are already visible, incrementing unhides section content. % * If the buffer has no hidden lines, decrementing hides section content. static define fold_buffer_incr(increment) { push_spot(); variable level = get_fold_level(); variable new_level = level + increment; % Special cases: % no hidden lines or no hidden headings: increase unhides all lines if (level <= 0 and increment > 0) new_level = 0; % no hidden headings: decrease hides lowest level headings else if (level < 0 and increment < 0) new_level = increment - level; % no hidden lines: decrease hides section content else if (level == 0 and increment < 0) new_level = 1000; % minimal fold level: always show at least main headings else if (new_level < 1) new_level = 1; vmessage("Fold_level: %d, New level: %d", level, new_level); fold_buffer(new_level); pop_spot(); } % Fold current section % (Un)Hide section content. % (Un)hide also sub-headings below max_level. % max_level is relative to section level: % -n: toggle folding % 0: unfold (show content) % 1: hide all sub-headings % n: show n-1 levels of sub-headings static define fold_section(max_level) { push_spot(); % goto top of section go_down(2); previous_heading(); % Toggle, if \var{max_level} is negative. if (max_level < 0) { $1 = down(2); max_level *= -not(is_line_hidden()); go_up($1); } % Narrow to section and fold push_mark(); skip_section(); go_up_1(); narrow(); fold_buffer(max_level); widen(); pop_spot(); } % Keybindings % =========== % % Emacs outline mode bindings % --------------------------- % % emulate emacs outline bindings:: static define emacs_outline_bindings() % (pre = _Reserved_Key_Prefix) { variable pre = push_defaults(_Reserved_Key_Prefix, _NARGS); local_unsetkey(pre); % Outline Motion Commands % ~~~~~~~~~~~~~~~~~~~~~~~ % :^C^n: (outline-next-visible-heading) moves down to the next heading line. % :^C^p: (outline-previous-visible-heading) moves similarly backward. % :^C^u: (outline-up-heading) Move point up to a lower-level (more % inclusive) visible heading line. % :^C^f: (outline-forward-same-level) and % :^C^b: (outline-backward-same-level) move from one heading line to another % visible heading at the same depth in the outline. % % :: local_setkey("rst->next_heading", pre+"^N"); local_setkey("rst->previous_heading", pre+"^P"); local_setkey("rst->up_section", pre+"^U"); local_setkey("rst->skip_section", pre+"^F"); local_setkey("rst->bskip_section", pre+"^B"); % Outline Visibility Commands % ~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Global commands % """"""""""""""" % folding the whole buffer. % With a numeric argument n, they hide everything except the % top n levels of heading lines. % % :^C^t: (hide-body) you see just the outline. (fold.txt: ^C^W) % :^C^a: (show-all) makes all lines visible. (fold.txt: ^C^O) % :^C^q: (hide-sublevels) hides all but the top level headings. % % :: local_setkey("rst->fold_buffer(100)", pre+"^T"); local_setkey("rst->fold_buffer(0)", pre+"^A"); local_setkey("rst->fold_buffer(1)", pre+"^Q"); % TODO % % :^C^o: (hide-other) hides everything except the heading or body text that % point is in, plus its parents (the headers leading up from there to top % level in the outline). % % Subtree commands % """""""""""""""" % that apply to all the lines of that heading's subtree % its body, all its subheadings, both direct and indirect, and all of their % bodies. In other words, the subtree contains everything following this % heading line, up to and not including the next heading of the same or % higher rank. % :: % :^C^d: (hide-subtree) Make everything under this heading invisible. local_setkey("rst->fold_section(1)", pre+"^D"); % :^C^s: (show-subtree). Make everything under this heading visible. local_setkey("rst->fold_section(0)", pre+"^C"); % Intermediate between a visible subtree and an invisible one is having all % the subheadings visible but none of the body. % :^C^l: (hide-leaves) Hide the body of this section, including subheadings. local_setkey("rst->fold_section(1)", pre+"^L"); % TODO: what is the difference to (hide-subtree)? % :^C^k: (show-branches) Make all subheadings of this heading line visible. local_setkey("rst->fold_section(100)", pre+"^K"); % :^C^i: (show-children) Show immediate subheadings of this heading. local_setkey("rst->fold_section(2)", pre+"^I"); % Local commands % """""""""""""" % % Used with point on a heading line, and apply only to the body lines of that % heading. Subheadings and their bodies are not affected. % % :^C^c: (hide-entry) hide body under this heading and % :^C^e: (show-entry) show body of this heading. % :^C^q: Hide everything except the top n levels of heading lines (hide-sublevels). % :^C^o: Hide everything except for the heading or body that point is in, plus the headings leading up from there to the top level of the outline (hide-other). % % When incremental search finds text that is hidden by Outline mode, it makes % that part of the buffer visible. If you exit the search at that position, % the text remains visible. % % Structure editing. % ~~~~~~~~~~~~~~~~~~ % % Using M-up, M-down, M-left, and M-right, you can easily move entries % around % % .. parsed-literal:: % % move up % ^ % (level up) promote <- + -> demote (level down) % v % move down % % TODO: add Alt-Cursor bindings:: % local_setkey("rst->move_section_up", Key_Alt_Up); % ... } % end of emacs_outline_bindings() % Emacs fold mode bindings % ------------------------ % from fold.txt (consistent with the Emacs bindings) % % :^C^W: fold_whole_buffer % :^C^O: fold_open_buffer % unfold-buffer % :^C>: fold_enter_fold % :^C<: fold_exit_fold % :^C^F: fold_fold_region % add fold marks and narrow % :^C^S: fold_open_fold % :^C^X: fold_close_fold % :^Cf: fold_search_forward % :^Cb: fold_search_backward % % Emacs outline mode bindings % --------------------------- % % Entry: a heading and its body % Subtree: entry and those below it % % outline-minor-mode-prefix: key prefix for Outline minor mode % % outline-regexp: the regexp that matches a heading; if one uses the default % value for `outline-level` (the function that computes the depth of the % heading based on the match), the length of the match determines the depth % of the heading and its topic, unless there exists an overriding value in % `outline-heading-alist`. % % :C-c C-n/p: move to next/previous heading line, irrespective of scope % :C-c C-f/b: move to next/previous heading line at same level % :C-c C-u: move up a level % :C-c C-t: like zM in Vim; show collapsed structure of headings of currently % showing entries, nothing more % :C-c C-a: like zR in Vim; show everything % :C-c C-d: hides everything below the current header including its body % :C-c C-s: show everything below current level, inclusive % :C-c C-l: reduce everything below current level to collapsed headings, if % currently showing -- like C-c C-t in microcosm % :C-c C-k: show all headings below current level % there is a subtle difference from the previous command in that % this one shows and the other hides, arriving at more or less % the same end. (Open bodies will remain open with this command.) % :C-c C-i: show immediate subheadings (those directly below current level) % :C-c C-c: hide entry % :C-c C-e: show entry % :C-c C-q: hide everything except the top N levels of heading lines (use C-u) % :C-c C-o: hide other (everything but this and the headings of the parents) % :C-c C-@: mark current subtree % % from ttp://frontier.userland.com/tutorial/writingInOutlines % Outliner Basics % % To create a new line, hit the Return key. (On Windows, that's the main Enter % key, not the keypad Enter key.) % % To toggle between editing a line and selecting a line, use the keypad Enter % key. (On Windows, you can also use F2.) % % To collapse and expand a line that has subordinate lines, double-click its % triangle, or use the + and - keys on the keypad. % % To move a line to the right, you can drag it with the mouse (grab the triangle % to drag it), use the Tab key, or use ctrl-R. (That's cmd-R on Macintosh -- % read cmd when you see ctrl.) % % To move a line to the left, you can drag it, use shift-Tab, or ctrl-L. % % To move a line up, drag it or use ctrl-U. % % To move a line down, drag it or use ctrl-D. % % To move the cursor up and down in an outline, use the arrow keys while in % selection mode. The left and right arrow keys treat the outline as if it's % flat, the up and down arrow keys move within the current level. % % To delete a line, select it and hit the Delete key, or choose the Clear % command from the Edit menu. % % For more outliner commands check out the Outliner menu in Frontier's menubar. % % % % Numerical Keypad bindings % ------------------------- % :: static define rst_outline_bindings() { local_setkey("rst->bskip_section", Key_KP_9); % Bild ↑ local_setkey("rst->previous_heading", Key_KP_8); % ↑ local_setkey("rst->promote_heading(-1)", Key_KP_4); % ← promote % local_setkey("rst->hide_other", Key_KP_5); % - local_setkey("rst->promote_heading(1)", Key_KP_6); % → demote local_setkey("rst->next_heading", Key_KP_2); % ↓ local_setkey("rst->skip_section", Key_KP_3); % Bild ↓ % Fold section local_setkey("rst->fold_section(-1)", Key_KP_Enter); % toggle section fold % Fold buffer local_setkey("rst->fold_buffer_incr(1)", Key_KP_Add); local_setkey("rst->fold_buffer_incr(-1)", Key_KP_Subtract); % local_setkey("rst->fold_buffer(100)", Key_KP_Delete); % fold % local_setkey("rst->fold_buffer(0)", Key_KP_0); % unfold } jedmodes-2.5.7/rst/structured_text.sl0000644000175400017500000002205211130337534016223 0ustar mildegm% structured_text.sl: formatting hooks for "ASCII markup" % ======================================================= % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % -------- % % 0.1 first version published together with rst.sl % 2006-01-20 0.2 including the regular expressions from JED % documentation % 2006-01-23 0.3 added st_backward_paragraph() and st_mark_paragraph() % set "mark_paragraph_hook" to format first line of list item % 2006-02-03 0.4 bugfix in the Text_List_Patterns (* needs to be escaped) % 2006-05-17 0.4.1 code cleanup % 2006-08-14 0.5 * bugfix: rename text_mode_hook() to structured_text_hook() % to avoid name clashes. To activate the st formatting in % text mode, define an alias as described in the function % doc. (report J. Sommmer) % 2007-07-02 0.6 * rename line_is_empty() -> line_is_blank, as it may % contain whitespace % * new function st_format_paragraph() with correct % formatting of multi-line list-items % * relax match-requirement in line_is_list to allow % UTF-8 multi-byte chars in Text_List_Patterns. % (jed-extra bug #431418, Joerg Sommer) % 2007-09-21 0.6.1 * fix Text_List_Patterns % 2009-01-05 0.6.2 * add heading underline to paragraph separators % Usage % ----- % % Place in the jed-library-path. % % To enable the structured text formatting in e.g. text_mode(), define (or % extend) the text_mode_hook in your jed.rc config file: % % autoload("structured_text_hook", "structured_text"); % define text_mode_hook() % { % structured_text_hook(); % % % } % Requirements % ------------ % % None provide("structured_text"); % Customization % ------------- % the set of regular expressions matching a list mark % (leading whitespace is stripped from the line before matching) custom_variable("Text_List_Patterns", {"^[0-9]+\\.[ \t]+", % enumeration %"^[a-z]+\\)[ \t]+", % alpha enumeration (many false positives) "^[a-z]\\)[ \t]+", % alpha enumeration (just one small letter) "^[-*+|][ \t]+", % itemize (bullet list) + line blocks "^:.+:[ \t]+", % field list (ReST syntax) "^\\.\\. " % comment (ReST syntax) }); private variable uchars = "*=-~\-\"'`^:+#<>_"R; private variable blank = " \t"; private variable Underline_Regexp = "^\([$uchars]\)\1+[$blank]*$"R$; % Functions % --------- %!%+ %\function{line_is_list} %\synopsis{Return length of a list marker} %\usage{ line_is_list()} %\description % Check if the current line starts with a list marker matching one of the % regular expressions defined in \var{Rst_List_Patterns}. % Return length of the list marker (excluding leading whitespace) % % Leaves the editing point at first non-whitespace or eol %\notes % Thanks to JED for the regular expressions variant %\seealso{line_is_empty, Text_List_Patterns} %!%- define line_is_list() { variable len = 0, re; % get the current line without leading whitespace variable line = strtrim_beg(line_as_string()); bol_skip_white(); foreach re (Text_List_Patterns) { if (string_match(line, re, 1) < 1) continue; (,len) = string_match_nth(0); } return len; } %!%+ %\function{line_is_blank} %\synopsis{Check if the line is blank (not counting whitespace)} %\usage{ line_is_blank()} %\description % This is the same as the default is_paragraph_separator test. % Leaves the editing point at first non-white space or eol. %\notes % rst-outline.sl overwrites this definition with one including a test for % section title underlines, as these separate paragraphs analogue to blank % lines. %\seealso{line_is_list, st_is_paragraph_separator} %!%- define line_is_blank() { bol_skip_white(); return eolp(); } %!%+ %\function{st_is_paragraph_separator} %\synopsis{paragraph separator hook for structured text} %\usage{st_is_paragraph_separator()} %\description % Return 1 if the current line separates a paragraph, i.e. it % is blank or a list item %\notes % Actually, this misses an important difference between blank lines and % first lines of a list item: While an blank line must not be filled % when reformatting, a list item should. % This is why Emacs has 2 Variables, paragraph-separator and paragraph-start. %\seealso{line_is_blank, line_is_list} %!%- define st_is_paragraph_separator() { % show("line", what_line, "calling st_is_paragraph_separator"); return orelse{line_is_blank()}{line_is_list()>0} {re_looking_at(Underline_Regexp)}; % attention: there is a segfault if the paragraph_separator_hook returns % values higher than 1! } % go to the beginning of the current paragraph define st_backward_paragraph() { if (line_is_blank()) go_up_1(); do { if (line_is_list()) break; if (line_is_blank()) { eol(); go_right_1(); break; } } while (up(1)); } % Mark the current paragraph % This can also be used for format_paragraph's % "mark_paragraph_hook" define st_mark_paragraph() { st_backward_paragraph(); push_visible_mark; forward_paragraph(); } %!%+ %\function{st_indent} %\synopsis{indent-line for structured text} %\usage{st_indent()} %\description % Indent the current line, taking care of list markers as defined in % \var{Text_List_Patterns}. %\notes % Expanded from example in hooks.txt %\seealso{st_is_paragraph_separator, line_is_list, Text_List_Patterns} %!%- define st_indent() { variable indent; % show("line", what_line, "calling st_indent"); % get indendation of previous line push_spot(); go_up_1; bol_skip_white(); indent = what_column-1 + line_is_list(); go_down_1; indent -= line_is_list(); % de-dent the list marker bol_trim(); whitespace(indent); pop_spot(); if (bolp) skip_white(); } %!%+ %\function{st_newline_and_indent} %\synopsis{newline_and_indent for structured text} %\usage{ st_newline_and_indent ()} %\description % Indent to level of preceding line %\notes % We need a separate definition, as by default newline_and_indent() uses the % indent_hook (which structured_text.sl sets to st_indent (considering list % markers) while with Enter we want more likely to start a new list topic. %\seealso{st_indent, st_indent_relative} %!%- define st_newline_and_indent() { % show("line", what_line, "calling st_newline_and_indent"); variable indent, col = what_column(); % get number of leading spaces push_spot(); bol_skip_white(); indent = what_column(); pop_spot(); newline(); if (indent > col) % more whitespace than the calling points column indent = col; whitespace(indent-1); } define st_format_paragraph(); % forward definition % Use the internal paragraph formatting function instead of the buffer local % hook. (code from c_format_paragraph()) static define global_format_paragraph() { unset_buffer_hook("format_paragraph_hook"); call("format_paragraph"); set_buffer_hook("format_paragraph_hook", &st_format_paragraph); } % format structured text, take care of list formatting define st_format_paragraph() { message("st_format"); push_spot(); global_format_paragraph(); % Fix formatting of lines following a list-item forward_paragraph(); variable line_no = what_line(); backward_paragraph(); if (line_is_list and line_no != what_line()) { go_down_1(); st_indent(); global_format_paragraph(); } pop_spot(); } %!%+ %\function{structured_text_hook} %\synopsis{Formatting hook for "ASCII markup"} %\usage{structured_text_hook()} %\description % This function calls a list of buffer hooks (see Help>Browse-Docs>Hooks) % suitable for proper indenting and paragraph formatting of documents using % "ASCII markup". % % Paragraphs are separated by blank lines and indented to the same column % as the first line of the paragraph. % % List items that start with a special list marker (e.g. '* ' or '3.') are % considered paragraphs as well, even when not preceded by an blank line. % Continuation lines are indented to the column that matches the start of the % list text.% %\example % To enable the structured text formatting in \sfun{text_mode}, set an alias: %#v+ % define text_mode_hook() { structured_text_hook(); } %#v- %\notes % \sfun{rst_mode} calls \sfun{structured_text_hook} by default. %\seealso{st_indent, st_backward_paragraph, st_mark_paragraph} %!%- public define structured_text_hook() { set_buffer_hook("wrap_hook", &st_indent); set_buffer_hook("indent_hook", &st_indent); set_buffer_hook("backward_paragraph_hook", &st_backward_paragraph); set_buffer_hook("mark_paragraph_hook", "st_mark_paragraph"); set_buffer_hook("format_paragraph_hook", "st_format_paragraph"); set_buffer_hook("newline_indent_hook", &st_newline_and_indent); set_buffer_hook("par_sep", &st_is_paragraph_separator); } jedmodes-2.5.7/tar/0000755000175400017500000000000011026441200012356 5ustar mildegmjedmodes-2.5.7/tar/tar.sl0000644000175400017500000003174111026441200013512 0ustar mildegm% File: tar.sl -*- mode: SLang -*- % % $Id: tar.sl,v 1.12 2008/05/08 17:25:35 paul Exp paul $ % % Copyright (c) 2003-2008 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % this is a jed interface to GNU tar % It works like emacs' tar-mode or dired. % Except that in emacs' tar-mode, changes do not become permanent until you % save them. % You can view the contents of a tar file, view and extract % members and delete them if the tar is not compressed. % If you want want tar archives to be opened automatically in tar-mode, add % add_to_hook("_jed_find_file_before_hooks", &check_for_tar_hook); % to .jedrc % Thanks to Gnter Milde for his ideas, comments, patches and bug reports. require("view"); require("syncproc"); % binding scheme may be dired or mc. We use a variable from filelist.sl % for consistency. custom_variable("FileList_KeyBindings", "mc"); % A structure for setting some bufferlocal variables. ifnot (is_defined("Tarvars")) typedef struct { file, % tar filename (w/ path) base_file, % base of filename root, % where to extract to options, % z for tgz, &c readonly } Tarvars; public variable help_string = Assoc_Type[String_Type]; help_string["mc"] = "1Help 2Menu 3View 4Edit 5Copy 6__ 7__ 8Delete 9PullDn 10Quit"; help_string["dired"] = "e:edit C:copy v:view d:tag u:untag x:delete tagged r:rescan h:help q:quit"; %{{{ set the member's mode % This is from site.sl - I don't want the modeline from tar members processed % because script kiddies can use it for evil. private define set_mode_from_extension (ext) { variable n, mode; if (@Mode_Hook_Pointer(ext)) return; n = is_list_element (Mode_List_Exts, ext, ','); if (n) { n--; mode = extract_element (Mode_List_Modes, n, ',') + "_mode"; if (is_defined(mode) > 0) { eval (mode); return; } } mode = strcat (strlow (ext), "_mode"); if (is_defined (mode) > 0) { eval (mode); return; } } %}}} %{{{ reading a tar private define tar_init_menu (); private define tar_mode () { set_mode( "tar", 0); use_keymap("Tar"); #ifdef HAS_DFA_SYNTAX use_syntax_table("tar"); #endif run_mode_hooks("tar_mode_hook"); mode_set_mode_info( "tar", "init_mode_menu", &tar_init_menu); message(help_string[FileList_KeyBindings]); bob; } private define tar_options (file) { variable exts = strchopr(file, '.', 0); if (1 == length(exts)) throw RunTimeError, "file doesn't have a tar extension"; switch (exts[0]) { case "tar" : return String_Type[0];} { case "tgz" : return "-z";} { case "tZ" or case "tz" : return "-Z";} { case "tbz" : return "--bzip2";} % they changed the short form if (2 == length(exts) || exts[1] != "tar") throw RunTimeError, "file doesn't have a tar extension"; switch (exts[0]) { case "gz" : return "-z";} { case "Z" or case "compress" : return "-Z";} { case "bz2" or case "bz" : return "--bzip2";} { throw RunTimeError, "file doesn't have a tar extension";} } private define tar_get_vars () { ifnot (blocal_var_exists("tar")) throw RunTimeError, "not a tar buffer?"; return get_blocal_var("tar"); } private define tar_get_member () { return line_as_string[[2:]]; } public define tar_list () { variable tar = tar_get_vars; set_readonly(0); erase_buffer; variable pid = open_filter_process(["tar", "-t", tar.options, "-f", tar.file], "@"); variable status = close_filter_process(pid); if (status) { throw RunTimeError, "tar exited with $status"$; } do { insert(" "); } while (down(1)); trim_buffer; set_buffer_modified_flag(0); set_readonly(1); message(help_string[FileList_KeyBindings]); } %!%+ %\function{tar} %\synopsis{tar [ filename [readonly]] } %\usage{public define tar ()} %\description % A mode for viewing the contents of tar archives. It resembles % Emacs' tar-mode, but works by calling the GNU tar program. You % can mark archive members with the 'd' key, like in dired. Set % \var{FileList_KeyBindings} to "mc" if you want keybindings like % in Midnight Commander. When you mark a directory member, its % submembers are also marked. Delete tagged members with 'x'. %\notes % Unlike in Emacs' tar-mode, when you delete members they are gone - no % need to save the file. To protect unwary users, there is the % readonly argument. %\seealso{tar_copy, check_for_tar_hook} %!%- public define tar () % [ filename [ RO ] ] { variable tar = @Tarvars; if (_NARGS == 2) (tar.file, tar.readonly) = ( , ); else if (_NARGS == 1) (tar.file, tar.readonly) = ( , 0); else tar.file = read_with_completion("file to read", "", "", 'f'); ifnot (1 == file_status(tar.file)) return message("file \" "+tar.file+" \"doesn't exist"); tar.base_file = path_basename(tar.file); tar.options = tar_options(tar.base_file); tar.root = ""; variable bufname ="*tar: " + tar.base_file + "*"; sw2buf(bufname); setbuf_info("",path_dirname(tar.file),bufname,8); define_blocal_var("tar", tar); tar_list; tar_mode; } %}}} %{{{ working with the tar public define tar_set_root (tar) { do { tar.root = read_file_from_mini("what directory to extract to?"); } while (2 != file_status(tar.root)); set_blocal_var(tar, "tar"); return tar.root; } private define extract_to_buf (buf) { variable tar, member, buffer; tar = tar_get_vars; member = tar_get_member; if (member[-1] == '/') throw RunTimeError, "this is a directory"; setbuf(buf); erase_buffer; variable pid = open_filter_process(["tar", "-xO", tar.options, "-f", tar.file, member], "@"); variable status = close_filter_process(pid); if (status) { throw RunTimeError, "tar exited with $status"$; } set_buffer_modified_flag(0); } public define tar_view_member () { variable tar, member, buffer; tar = tar_get_vars; member = tar_get_member; buffer = sprintf("%s (%s)", path_basename(member), path_basename(tar.file)); if(bufferp(buffer)) sw2buf(buffer); else { extract_to_buf(buffer); sw2buf(buffer); set_mode_from_extension (file_type (member)); view_mode(); } } private define tar_copy_member () { variable tar = tar_get_vars(), member = tar_get_member(); if (member[-1] == '/') throw RunTimeError, "this is a directory"; variable name = read_file_from_mini("where to copy this file to"); if (2 == file_status(name)) name = dircat(name, path_basename(member)); variable state; auto_compression_mode(0, &state); try { extract_to_buf(" *tar_copy_buffer*"); setbuf_info(getbuf_info() | 0x200); ()=write_buffer(name); delbuf(whatbuf()); } finally { auto_compression_mode(state); } } %{{{ tagging members private define set_tag (tag) { bol; go_right_1; insert_char(tag); del; } private define tag_submembers (path, tag) { for (bob; re_fsearch("^ [ xD]" + path + ".+"); go_down_1) set_tag(tag); } private define tag_member (on) { push_spot; variable member = tar_get_member(); variable tag, subtag; if (on) (tag,subtag) = 'D','x'; else (tag,subtag) = ' ',' '; bol; go_right_1; if (looking_at_char('x')) return; set_readonly(0); set_tag(tag); % tag any other members with this name for (bob; re_fsearch("^ [x ]" + member + "$"); go_down_1) set_tag(subtag); if (member[-1] == '/') tag_submembers(member, subtag); pop_spot; set_readonly(1); set_buffer_modified_flag(0); } public define tar_tag_member(dir) % (on/off) { if (_NARGS != 2) % toggle on/off (line_as_string[1] == ' '); tag_member(); if (dir) go_down_1; else go_up_1; } public define tar_untag_all () { push_spot_bob; set_readonly(0); do { bol; go_right_1; if (looking_at_char('D') || looking_at_char('x')) { insert_char(' '); del; } } while (down_1); pop_spot; set_readonly(1); set_buffer_modified_flag (0); } public define tar_tag_all() { push_spot_bob; set_readonly(0); while (bol_fsearch (" ")) tar_tag_member(1); pop_spot; set_readonly(1); set_buffer_modified_flag (0); } private define get_tagged_members () { variable members = "", allmembers=""; push_spot_bob; do { if (looking_at(" D")) members += tar_get_member() + "\n"; else if (looking_at(" x")) allmembers += tar_get_member() + "\n"; } while (down_1); pop_spot; return members, allmembers; } %}}} %{{{ working with tagged members public define tar_delete () { variable tar, member; tar = tar_get_vars; if (tar.readonly) throw RunTimeError, "archive is opened read-only"; if (tar.options != "") throw RunTimeError, "I can't delete from a compressed archive"; variable members, allmembers; (members, allmembers) = get_tagged_members; if (members == "") return; variable buf=whatbuf; sw2buf(" *Deletions*"); erase_buffer(); insert(members + allmembers); buffer_format_in_columns(); ifnot (1 == get_yes_no("Do you wish to PERMANENTLY delete these members")) return sw2buf(buf); setbuf("*tar output*"); erase_buffer(); variable pid = open_filter_process(["tar", "--delete", "-f", tar.file, "-T", "-"], "."); send_process(pid, members); send_process_eof(pid); variable status = close_filter_process(pid); if (status) { pop2buf(whatbuf()); throw RunTimeError, "tar exited with $status"$; } sw2buf(buf); variable line=what_line; tar_list; goto_line(line); } private define tar_extract (all) { variable tar, members =""; tar = tar_get_vars; if (tar.root == "") tar.root = tar_set_root(tar); ifnot (all) (members, ) = get_tagged_members; setbuf("*tar output*"); variable pid = open_filter_process(["tar", "-x", tar.options, "-C", tar.root, "-f", tar.file, "-T", "-"], "."); send_process(pid, members); send_process_eof(pid); variable status = close_filter_process(pid); if (status) { pop2buf(whatbuf()); throw RunTimeError, "tar exited with $status"$; } } % are there tagged members? private define are_there_tagged() { push_spot_bob; bol_fsearch (" D"); pop_spot; } %!%+ %\function{tar_copy} %\description % If there are tagged tar members, copy them. Otherwise copy the % member at point. %\seealso{tar} %!%- public define tar_copy() { if (are_there_tagged) tar_extract(0); else tar_copy_member; } %}}} %}}} %{{{ DFA highlighting, keybindings, menu #ifdef HAS_DFA_SYNTAX create_syntax_table ("tar"); %%% DFA_CACHE_BEGIN %%% private define setup_dfa_callback(mode) { dfa_enable_highlight_cache(mode + ".dfa", mode); dfa_define_highlight_rule("^ .*/$", "keyword", mode); dfa_define_highlight_rule("^ D.*$", "string", mode); dfa_define_highlight_rule("^ x.*$", "comment", mode); dfa_build_highlight_table(mode); } dfa_set_init_callback(&setup_dfa_callback, "tar"); %%% DFA_CACHE_END %%% enable_dfa_syntax_for_mode("tar"); #endif % Keybindings: ifnot (keymap_p ("Tar")) copy_keymap("Tar", "view"); % dired bindings do not do any harm (as we are in readonly) so they % should be available also to mc-Freaks (so the menu gives keybindings) definekey("tar_tag_all", "a", "Tar"); definekey("tar_untag_all", "z", "Tar"); definekey("tar_list", "g", "Tar"); definekey("tar_view_member", "v", "Tar"); definekey("tar_copy", "C", "Tar"); definekey("tar_copy", "c", "Tar"); definekey("tar_tag_member(1,1)", "d", "Tar"); definekey("tar_tag_member(0,1)", "u", "Tar"); definekey("tar_tag_member(0,0)", _Backspace_Key, "Tar"); definekey("tar_delete", "x", "Tar"); definekey("message(help_string[FileList_KeyBindings])", "h", "Tar"); definekey("message(help_string[FileList_KeyBindings])", "?", "Tar"); definekey("delbuf(whatbuf())", "q", "Tar"); definekey("tar_view_member", "^M", "Tar"); if (FileList_KeyBindings == "mc") { require("keydefs"); undefinekey("^R", "Tar"); % I had an error, as ^R was a keymap (^RA...^RZ) definekey("tar_list", "^R", "Tar"); % keep Key_F1 for the general help, or (with hyperhelp) let it do % help_mode (tries to open tar.hlp in the help buffer) definekey("menu_select_menu(\"Global.M&ode\")", Key_F2, "Tar"); definekey("tar_view_member", Key_F3, "Tar"); definekey("tar_copy", Key_F5, "Tar"); definekey("tar_delete", Key_F8, "Tar"); definekey("delbuf(whatbuf())", Key_F10, "Tar"); definekey("tar_tag_member(1)", Key_Ins, "Tar"); } private define tar_init_menu (menu) { menu_append_item(menu, "&view", "tar_view_member"); menu_append_item(menu, "&tag", "tar_tag_member(1,1)"); menu_append_item(menu, "&untag", "tar_tag_member(0,1)"); menu_append_item(menu, "tag &all", "tar_tag_all"); menu_append_item(menu, "untag all", "tar_untag_all"); menu_append_item(menu, "©", "tar_copy"); menu_append_item(menu, "copy all", &tar_extract, 1); menu_append_item(menu, "e&xpunge (delete) tagged", "tar_delete"); menu_append_item(menu, "&set extract dir", "tar_set_root"); menu_append_item(menu, "&rescan", "tar_list"); menu_append_item(menu, "&quit tar", "delbuf(whatbuf())"); } %}}} provide("tar"); jedmodes-2.5.7/tar/tarhook.sl0000644000175400017500000000215711026441200014372 0ustar mildegm% usually, you will have tar.sl if you have this file autoload("tar", "tar"); % This checks if the file has a tar extension. % To be used from e.g. filelist.sl public define check_for_tar (file) { variable exts = strchopr( path_basename( file), '.', 0); if ( 1 == length( exts)) return 0; if ( is_list_element( "tgz,tar,tZ,tbz", exts[0], ',')) return 1; return (2 != length(exts) && exts[1] == "tar" && is_list_element( "gz,Z,bz2,bz", exts[0], ',')); } % This checks if file is a tar, and if so opens it read-only. % %!%+ %\function{check_for_tar_hook} %\synopsis{hook for opening a tar archive in tar mode} %\usage{public define check_for_tar_hook (file)} %\description % If the filename argument has a tar extension, open it in \var{tar} % mode and return 1, otherwise return 0. To be added to % _jed_find_file_before_hooks. %\notes % This hook opens the archive read-only - you can't delete members. %\seealso{tar} %!%- public define check_for_tar_hook (file) { if (check_for_tar( file)) { tar( file, 1); % open read-only return 1; } else return 0; } provide("tarhook"); jedmodes-2.5.7/window/0000755000175400017500000000000010461125576013120 5ustar mildegmjedmodes-2.5.7/window/window.sl0000644000175400017500000003013410437314224014761 0ustar mildegm% Window management routines. % % Copyright (c) 2004 Marko Mahnic % Released under the terms of the GNU General Public License (ver. 2 or later) % % 2004-12-11: Marko Mahnic % - first version % % 2006-04-11: Marko Mahnic % - bugfix in do_create_windows % - applied patch by G. Milde % - added more tets provide("window"); %!%+ %\variable{WindowInfo_Type} %\synopsis{struct WindowInfo_Type} %\usage{list = @WindowInfo_Type} %\description % A linked list that describes each window. % % The head element describes the screen (the biggest window). % Each 'line' of the screen represents a window. % % The following elements describe the windows in top-down order. % The minibuffer is not included in the list. %!%- !if (is_defined ("WindowInfo_Type")) { typedef struct { height, buffer, line, offs, next } WindowInfo_Type; } static variable Windows = NULL; %!%+ %\function{select_top_window} %\synopsis{Select the window at the top of the screen} %\usage{select_top_window()} %\description % Select the window at the top of the screen. %\seealso{select_prev_window, select_next_window, select_bottom_window} %!%- public define select_top_window() { variable i; loop (nwindows()) { if (TOP_WINDOW_ROW == window_info('t')) break; otherwindow(); } } %!%+ %\function{select_bottom_window} %\synopsis{Select the window at the bottom of the screen} %\usage{select_bottom_window()} %\description % Select the window at the bottom of the screen. % The minibuffer is never selected even if it is active. % %\seealso{select_prev_window, select_next_window, select_top_window} %!%- public define select_bottom_window() { variable togo = nwindows() - 1; if (MINIBUFFER_ACTIVE) togo--; select_top_window(); if (togo > 0) loop (togo) otherwindow(); } %!%+ %\function{select_next_window} %\synopsis{Select the next window} %\usage{select_next_window()} %\description % Select the next window. Same as otherwindow(). % %\seealso{select_prev_window, select_top_window, select_bottom_window} %!%- define select_next_window() { otherwindow(); } %!%+ %\function{select_prev_window} %\synopsis{Select the previous window} %\usage{select_prev_window()} %\description % Select the previous window. % %\seealso{select_next_window, select_top_window, select_bottom_window} %!%- public define select_prev_window() { variable i; for (i = nwindows() - 1; i > 0; i--) otherwindow(); } %!%+ %\function{select_window} %\synopsis{Select the nth. window from top} %\usage{select_window(Integer_Type n)} %\description % Select the nth. window from top. % The top window is 1. % \seealso{what_window, nwindows} %!%- define select_window(n) { while (n < 1) n += nwindows(); n = (n - 1) mod nwindows(); select_top_window(); loop(n) otherwindow(); } %!%+ %\function{what_window} %\synopsis{Return the number of the current window} %\usage{Integer_Type what_window()} %\description % Return the number of the current window. Windows are numbered % from 1 to nwindows(). The top window is 1. % \seealso{select_window, nwindows} %!%- define what_window() { variable curwin = window_info('t'); variable n = 1; select_top_window(); while (window_info('t') != curwin) { otherwindow(); n++; } return n; } %!%+ %\function{save_windows} %\synopsis{Return window configuration with buffer positions} %\usage{WindowInfo_Type save_windows ()} %\description % Return window configuration with buffer positions. %\returns % Return a linked list of window information (WindowInfo_Type). %\seealso{restore_windows} %!%- define save_windows () { variable curwin = what_window(); variable list, pwin; % Save screen list = @WindowInfo_Type; list.height = SCREEN_HEIGHT; list.line = what_window(); list.next = @WindowInfo_Type; select_top_window(); % Save first window pwin = list.next; pwin.next = NULL; pwin.height = window_info('r'); pwin.buffer = whatbuf(); pwin.line = what_line(); pwin.offs = window_line(); % Save other windows otherwindow(); while (window_info('t') != TOP_WINDOW_ROW) { if (window_info('t') >= SCREEN_HEIGHT - 1) % minibuffer { otherwindow(); continue; } pwin.next = @WindowInfo_Type; pwin = pwin.next; pwin.next = NULL; pwin.height = window_info('r'); pwin.buffer = whatbuf(); pwin.line = what_line(); pwin.offs = window_line(); otherwindow(); } % Activate current window select_window(curwin); return list; } %!%+ %\function{restore_windows} %\synopsis{Restore a previously saved configuration of windows} %\usage{restore_windows(WindowInfo_Type list)} %\description % Restore a configuration of windows that was previously stored % with save_windows(). %\seealso{save_windows} %!%- define restore_windows(list) { if (list == NULL) return; if (list.next == NULL) { onewindow(); return; } variable pwin; variable i, diff; pwin = list.next; % create all windows onewindow(); while (pwin.next != NULL) { splitwindow(); pwin = pwin.next; } select_bottom_window(); diff = (SCREEN_HEIGHT - nwindows()) - window_info('r'); for (i = 0; i < diff; i++) enlargewin(); % restore window state select_top_window(); pwin = list.next; while (pwin != NULL) { diff = pwin.height - window_info('r'); if (diff > 0) for (i = 0; i < diff; i++) enlargewin(); if (bufferp(pwin.buffer)) { sw2buf(pwin.buffer); goto_line(pwin.line); recenter(pwin.offs); } otherwindow(); pwin = pwin.next; } % Restore active window select_window(list.line); } %!%+ %\function{save_windows_cmd} %\synopsis{Save window configuration with buffer positions into a static variable} %\usage{Void save_windows_cmd()} %\description % Save window configuration with buffer positions into a static variable. % % Suitable for a menu entry. % \seealso{restore_windows_cmd, save_windows} %!%- public define save_windows_cmd() { Windows = save_windows(); } %!%+ %\function{restore_windows_cmd} %\synopsis{Restore a previously saved configuration of windows} %\usage{Void restore_windows_cmd()} %\description % Restore a previously saved configuration of windows. The configuration % must have been stored with save_windows_cmd(). % Suitable for a menu entry. % % \seealso{save_windows_cmd, restore_windows} %!%- public define restore_windows_cmd() { restore_windows(Windows); } static define do_create_windows(nwin) { variable i, s, diff, ifill; variable wins; onewindow(); if (nwin == 1) pop(); if (nwin < 2) return; wins = Integer_Type[nwin]; % Create windows for (i = 0; i < nwin - 1; i++) splitwindow(); % Read window info and find the 'elastic' window ifill = -1; for (i = 0; i < nwin; i++) { s = (); wins[nwin - 1 - i] = s; if (ifill < 0 and s == 0) ifill = nwin - 1 - i; } if (ifill < 0) ifill = nwin - 1; % Enlarge the elastic window to max size select_top_window(); for (i = 0; i < ifill; i++) otherwindow(); for (i = 0; i < SCREEN_HEIGHT - nwindows(); i++) enlargewin(); % Enlarge other windows otherwindow(); if (window_info('t') >= SCREEN_HEIGHT - 1) otherwindow(); ifill = (ifill + 1) mod nwin; for (i = 0; i < nwin; i++) { if (wins[ifill] > 1) { diff = wins[ifill] - window_info('r'); while (diff > 0) { enlargewin(); diff--; } } otherwindow(); if (window_info('t') >= SCREEN_HEIGHT - 1) % minibuffer otherwindow(); ifill = (ifill + 1) mod nwin; } } % Create windows with sizes passed in parameters. % 0 means: whatever is left %!%+ %\function{create_windows} %\synopsis{Create a configuration of windows with the desired sizes} %\usage{Void create_windows(Integer_Type s0, Integer_Type s1 [, ...]) } %\description % Create a configuration of windows with the desired sizes. % Window sizes are defined top to bottom (s0 for topmost window). % % The first window with a desired size of 0 will be 'elastic' - % it's size will shrink or grow so that other windows. % % If none of the parameters sX is 0, the bottom window will be % elastic. % %\example %#v+ % create_windows(7, 0, 3) %#v- % will create 3 windows: % * the topmost will have 7 lines % * the bottom one will have 3 lines % * the middle window will take whatever is left % %\notes % If the screen is too small, the function may fail. %\seealso{create_windows_rel, save_windows, restore_windows} %!%- public define create_windows() { do_create_windows(_NARGS); } %!%+ %\function{create_windows_rel} %\synopsis{Create a configuration of windows with the desired relative sizes } %\usage{Void create_windows_rel(Integer_Type s0, Integer_Type s1 [, ...]) } %\description % Create a configuration of windows with the desired relative sizes. All sizes % must be equal or greater than 1. % %\example %#v+ % create_windows(30, 60, 10) %#v- % will create 3 windows: % * the topmost one will be 30% of total height % * the middle one will be 60% of total height % * the bottom one will be 10% of total height % %\seealso{create_windows, save_windows, restore_windows} %!%- define create_windows_rel() { variable wins, sum, i, vislines, nwin; if (_NARGS == 0) onewindow(); if (_NARGS == 1) { pop(); onewindow(); } if (_NARGS < 2) return; % Read parameters from stack - only values >= 1 wins = Integer_Type[_NARGS]; _stk_reverse(_NARGS); nwin = 0; for (i = 0; i < _NARGS; i++) { wins[nwin] = (); if (wins[nwin] >= 1) nwin++; } if (nwin < 2) { onewindow(); return; } % Calculate window sizes vislines = SCREEN_HEIGHT - 1 - (TOP_WINDOW_ROW - 1) - nwin; sum = 0; for (i = 0; i < nwin; i++) sum += wins[i]; for (i = 0; i < nwin; i++) { wins[i] = int(1.0 * vislines * wins[i] / sum + 0.5); if (wins[i] < 2) wins[i] = 2; } % Fixup sum = 0; for (i = 0; i < nwin; i++) sum += wins[i]; while (sum > vislines) { variable max = 2, imax; for (i = 0; i < nwin; i++) { if (wins[i] > max) { imax = i; max = wins[i]; } } if (max <= 2) break; else { wins[imax]--; sum--; } } % Create windows for (i = 0; i < nwin; i++) wins[i]; do_create_windows(nwin); } % ---------------------------------------------------------- % Demo/Testing code % ---------------------------------------------------------- #stop #iffalse define pause(m) { vmessage("Pause: %s", m); update(1); () = getkey(); } define dump_windows(list) { variable pwin = list; variable buf = whatbuf(); setbuf("*scratch*"); eob(); insert ("\n"); while (pwin != NULL) { vinsert("%d (L:%d C:%d B:%s) ", pwin.height, pwin.line, pwin.offs, pwin.buffer); pwin = pwin.next; } setbuf(buf); } define Test() { variable Current; variable TestWin1; variable TestWin2; Current = save_windows(); dump_windows(Current); create_windows_rel (30, 30, 30); select_top_window(); bob(); select_next_window(); eob(); TestWin1 = save_windows(); create_windows_rel (20, 20, 60); TestWin2 = save_windows(); create_windows_rel (10, 20, 30, 40); save_windows_cmd(); % dump_windows(TestWin1); % dump_windows(TestWin2); % dump_windows(Windows); onewindow(); pause("onewindow"); create_windows(10, 0); pause("create_windows: 10, 0"); create_windows(0, 10); pause("create_windows: 0, 10"); create_windows(10, 0, 10); pause("create_windows: 10, 0, 10"); restore_windows(TestWin1); pause("Saved create_windows_rel, TestWin1: 30, 30, 30"); restore_windows(TestWin2); pause("Saved create_windows_rel, TestWin1: 20, 20, 60"); restore_windows_cmd(); pause("Saved create_windows_rel, Static: 10, 20, 30, 40"); restore_windows(Current); pause("restored"); } Test(); #endif jedmodes-2.5.7/window/window_sl.html0000664000175400017500000000712410214064511016004 0ustar mildegm JED Macro: window.sl

window.sl

Window management routines for programmers.

Installation

Put the file somewhere on your jed_library_path and

   autoload ("save_windows_cmd", "window.sl");
   autoload ("restore_windows_cmd", "window.sl");
   
in your .jedrc file.

If you need to use the functions in your modes, use


  require("window");
  

create_windows(Integer_Type s0, Integer_Type s1 [, ...])

Create a configuration of windows with the desired sizes. Window sizes are defined top to bottom (first param is for topmost window).

The first window with a desired size of 0 will be 'elastic' - it's size will shrink or grow so that other windows. If none of the parameters is 0, the bottom window will be elastic. If the screen is too small, the function may fail.

Example:


   create_windows(4, 0, 2) 
   
will create 3 windows:
 File   Edit   Mode   Search   Buffers   Windows   System   Help 
 [EOB]
 
 
 
 -**-----|V0.99.16| Buffer1 () | 1/9,1------------------------- 



 
 -**-----|V0.99.16| Buffer1 () | 9/9,1------------------------- 
 [EOB]
 
 -**-----|V0.99.16| Buffer1 () | 9/9,1------------------------- 

The top one has 4 lines, the bottom one 2 lines and the middle has the rest.

create_windows_rel(Integer_Type s0, Integer_Type s1 [, ...])

Create a configuration of windows with the desired relative sizes. All sizes must be equal or greater than 1.

Example:


   create_windows(40, 60) 
   
will create 2 windows:
 File   Edit   Mode   Search   Buffers   Windows   System   Help 
 [EOB]
 
 
 -**-----|V0.99.16| Buffer1 () | 9/9,1------------------------- 


 [EOB]
 
 

 -**-----|V0.99.16| Buffer1 () | 9/9,1------------------------- 

The top one is 40% of total height, the bottom one will is 60% of total height.

WindowInfo_Type save_windows ()

Save window configuration with buffer positions.

Returns a linked list of window information (WindowInfo_Type).

restore_windows(WindowInfo_Type list)

Restore a configuration of windows that was previously stored with save_windows().

save_windows_cmd()

Save window configuration with buffer positions into a local variable.

Suitable for a menu entry.

restore_windows_cmd()

Restore a previously saved configuration of windows. The configuration must have been stored with save_windows_cmd().

Suitable for a menu entry.

select_top_window()

Select the window at the top of the screen.

select_bottom_window()

Select the window at the bottom of the screen. The minibuffer is never selected even if it is active.

select_next_window()

Select the next window. Same as otherwindow().

select_prev_window()

Select the previous window. jedmodes-2.5.7/svn/0000755000175400017500000000000011262367147012421 5ustar mildegmjedmodes-2.5.7/svn/svn.sl0000644000175400017510000011654311262367145014267 0ustar mildemilde% svn.sl: Utilities for SVN and CVS access from jed. % -*- mode: slang -*- % % :Date: $Date: 2009/10/05 13:02:29 $ % :Version: $Revision: 1.28 $ % :Copyright: © 2003,2006 Juho Snellman % 2007 Günter Milde % % (Standard MIT/X11 license follows) % % Permission is hereby granted, free of charge, to any person obtaining % a copy of this software and associated documentation files (the % "Software"), to deal in the Software without restriction, including % without limitation the rights to use, copy, modify, merge, publish, % distribute, sublicense, and/or sell copies of the Software, and to % permit persons to whom the Software is furnished to do so, subject to % the following conditions: % % The above copyright notice and this permission notice shall be % included in all copies or substantial portions of the Software. % % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. % % Installation % ============ % % Add this file into a directory that's in your "Jed library path" (try % M-X get_jed_library_path() to see what this is). % % After that, copy the block into your .jedrc (or run % update_ini() from jedmodes.sf.net/mode/make_ini/) % % Functionality % ============= % % Only the most common (for me) CVS|SVN operations are supported (add, commit, % diff, update). The operations can be targeted at a single buffer, a bunch of % files that have been marked, or at whole directories. % % Operations on buffers % --------------------- % % In general, the buffer operations will save the buffer before % doing the operation. % % C-c a 'svn add' file % C-c c 'svn commit' file % C-c u 'svn update' file % C-c d 'svn diff' file % C-c m m Mark the file for batch operations % % % Operations on marked files % -------------------------- % % The easiest way to operate on marked files is to use the following % command to open the marked file list buffer, from where you can easily % start the other operations using keybindings specific to that % buffer. % % C-c l show list of marked files % % The commands for operating on marked files are also available as % general keyboard commands, for those who find them more convenient. % % C-c m a 'svn add' all marked files % C-c m c 'svn commit' all marked files % C-c m u 'svn update' all marked files % C-c m d 'svn diff' all marked files % % For convenience, committing all marked files also unmarks the files. % % % Operation on directories % ------------------------ % % The directory operations ask the user for a directory before % executing. The question defaults to the previous directory given. % % C-c C-a 'svn add' directory % C-c C-c 'svn commit' directory % C-c C-u 'svn update' directory % % C-c C-l open directory view (basically a 'svn -qnf update') % % Directory level commit is not supported. % % % Diff/directory views % -------------------- % % Operations on single/marked files can also be applied from inside % a *SVN diff* or *SVN dirlist* buffer, using the same keybindings % as in a *SVN marked files* buffer. These views are probably the % most convenient methods for committing a large number of files, % or doing only selective updates on a project. % % % Most of the above commands are also accessible from % the File>Version_Control menu. % % % Customization % ============= % % The following custom variables are available for modifying the behaviour % of this module. % % Variable Default value % ---------------------------- --------------- % SVN_executable "svn" % CVS_executable "cvs" % GIT_executable "git" % VC_set_reserved_keybindings 0 % % See the definition below or 'Help>Describe Variable' for details. % % % Changelog % ========= % % 2003-05-31 / Juho Snellman % * First public release % 2003-05-31 * Run diff with -q % * Protect the Cvs_Mark_Type declaration inside "!if (reloading)" % 2003-06-02 * Switch the commands affecting selected file to lowercase % letters, since they seem to get used a lot more. % * Add revert (cvs update -C) % 2003-12-09 * Fix find_marked_common_root % 2006-11-21 * Rough SVN port % 2007-04-27 / Guenter Milde % * block: no need to evaluate svn.sl at startup % * bugfix: return to directory listing before postprocessing % * use popup_buffer instead of pop2buf: % - closing with close_buffer() closes the window as well % (if it wasn't open before). % 2007-04-30 * bugfix in dirlist_extract_filename(): strip spurious whitespace % (Joachim Schmitz) % * replace CVS with SVN in names and documentation % 2007-05-04 * Support both SVN and CVS (checking for CVS or .svn subdir) % * removed otherwindow_if_messagebuffer_active() -- its not used % 2007-05-16 * require_buffer_dir_in_svn() now also returns "entries" dir % as its path differs between CVS and SVN % 2007-05-25 * Use buffer_dirname() instead of getcwd() for project directory % default % 2007-07-23 * Set default of SVN_set_reserved_keybindings to 0 to prevent % clashes with mode-specific bindings % * code reorganisation % * Mode menu for listings % * Removed SVN_help: Keybindings are shown in mode menu % 2007-07-24 * Since svn version 1.4, the .svn/entries file is no longer XML: % adapted require_buffer_file_in_vc() (report J. Schmitz) % 2007-08-02 * Revised layout and hotkeys of vc and vc_list_mode menu % 2007-10-01 Bugfix (missing variable declaration) % 2007-10-18 * vc_add_dir(): Non-recursive also under SVN % 2007-12-11 * Key_Ins selects and moves down one line % * vc_list_dir() did open a buffer even if dir not under vc % * basic support for SVK (http://svk.bestpractical.com/) % * edit log-message in a dedicated buffer % * after commit, update all buffers that changed on disk % 2007-12-18 * New functions: vc_subtract_selected(), vc_delete_selected, % vc_commit_dir() % * remove spurious arg in vc_commit_finish() % 2008-01-03 * bugfix: swapped arguments in vc_commit_buffer() % 2008-01-04 * bugfix: vc_commit_finish() left the window open % 2008-01-07 * bugfix: diff_filenames holds Integer_Type values % bugfix: add missing autoloads, get_blocal --> get_blocal_var() % 2008-02-19 * add CVS keywords for this file % * bury output buffer after commit (show last line in minibuffer) % * re-open instead of reload buffers to avoid % "file changed on disk" questions % 2008-05-05 * Use -u option for SVN status (show externally updated files) % 2009-08-31 * Add GIT support, % * rename SVN_set_reserved_keybindings to VC_*, % * add display filter(s) to mode menu, % * BUGFIX: "subtract file" removed the local copy with SVN! % 2009-10-05 * Moved reopen_file() to bufutils.sl. % 2009-10-05 * fixed autoloads % % % TODO % ==== % % * Document public variables/functions % * insert (and filter) a status report into the log-message buffer % * use listings.sl for the listings % * syntax highlight (DFA) in directory listing % * Add support for 'diff -r HEAD' # % Add a "File>Version Control" menu popup autoload("vc_menu_callback", "svn"); define vc_load_popup_hook(menubar) { variable menu = "Global.&File"; menu_insert_popup("Canc&el Operation", menu, "&Version Control"); menu_set_select_popup_callback(menu+".&Version Control", &vc_menu_callback); } append_to_hook("load_popup_hooks", &vc_load_popup_hook); # % Requirements % ============ % from http://jedmodes.sourceforge.net/ autoload("reopen_file", "bufutils"); autoload("popup_buffer", "bufutils"); autoload("buffer_dirname", "bufutils"); autoload("close_buffer", "bufutils"); autoload("fit_window", "bufutils"); autoload("strread_file", "bufutils"); autoload("push_array", "sl_utils"); autoload("run_function", "sl_utils"); autoload("get_line", "txtutils"); % >= 2.7 autoload("re_replace", "txtutils"); % >= 2.7 require("x-keydefs"); % symbolic keyvars, including Key_Esc % require("listing"); implements("svn"); provide("svn"); %% Variables %{{{ %!%+ %\variable{SVN_executable} %\synopsis{The location of the svn executable} %\usage{variable SVN_executable = "/usr/bin/svn"} %\description % Name or path to the SVN command line client %\seealso{vc_list_dir, vc_diff_buffer} %!%- custom_variable("SVN_executable", "svn"); %!%+ %\variable{CVS_executable} %\synopsis{The location of the svn executable} %\usage{variable CVS_executable = "/usr/bin/svn"} %\description % Name or path to the CVS command line client %\seealso{vc_list_dir, vc_diff_buffer} %!%- custom_variable("CVS_executable", "cvs"); % command string for the SVK version control system custom_variable("SVK_executable", "svk"); % root of the local SVK version control system repository custom_variable("SVK_root", expand_filename("~/.svk")); if (file_status(SVK_root) != 2 and getenv("SVKROOT") != NULL) SVK_root = getenv("SVKROOT"); %!%+ %\variable{GIT_executable} %\synopsis{The location of the GIT executable} %\usage{variable GIT_executable = "git"} %\description % Name or path to the GIT command line client %\seealso{vc_list_dir, vc_diff_buffer} %!%- custom_variable("GIT_executable", "git"); %!%+ %\variable{VC_set_reserved_keybindings} %\synopsis{Set up reserved keybindings for SVN actions in the Global map?} %\usage{variable VC_set_reserved_keybindings = 0} %\description % By default, the initialization routines set up Global keybindings, % using the reserved prefix (defaults to C-c). Setting this % variable to zero *before the file is evaluated* prevents the % keybindings from being created. %\notes % If set up as shown in the "Installation" section on top of the svn.sl file, % the SVN functions are accessible via the "File>Version Control" menu popup. %\seealso{vc_list_dir, vc_diff_dir} %!%- custom_variable("VC_set_reserved_keybindings", 0); private variable diff_buffer = "*VC diff*"; private variable dirlist_buffer = "*VC directory list*"; private variable list_buffer = " *VC marked files*"; % normally hidden private variable cmd_output_buffer = "*VC output*"; private variable project_root = ""; % cache for get_op_dir() %}}} %% Prototypes %{{{ public define vc_add_buffer(); public define vc_list_mode(); static define vc_log_mode(); private define update_list_buffer(); private define update_diff_buffer(); private define update_dirlist_buffer(); private define init_diff_buffer(); private define postprocess_diff_buffer(); private define diff_extract_filename(); private define list_extract_filename(); private define dirlist_extract_filename(); %}}} % Auxiliary functions that maybe belong elsewhere % =============================================== % set the buffer directory to dir (-> bufutils.sl ?) private define set_buffer_dirname(dir) { variable file, name, flags; (file, , name, flags) = getbuf_info(); setbuf_info(file, dir, name, flags); } % Executing version control commands % ================================== % find out whether `dir' is under svk version control % * checks in the SVKROOT/config file (format as in svk version v2.0.1 ) % * `dir' should be a valid absolute path static define is_svk_dir(dir) { variable line, buf = whatbuf(); EXIT_BLOCK { delbuf("*svk-config-tmp*"); sw2buf(buf); } sw2buf ("*svk-config-tmp*"); erase_buffer (); if (-1 == insert_file_region(path_concat(SVK_root, "config"), " hash: ", " sep: ")) return 0; % could not open config file set_buffer_modified_flag(0); bob(); while (down_1()) { skip_white(); !if (what_column() == 5) continue; push_mark(); () = ffind(":"); if (is_substr(dir, bufsubstr())) return 1; } return 0; } % find out how version control is managed for `dir' private define get_vc_system(dir) { if (file_status(path_concat(dir, ".svn")) == 2) return "svn"; if (file_status(path_concat(dir, "CVS")) == 2) return "cvs"; if (0 == system(sprintf("cd %s; git log -1", dir))) return "git"; if (is_svk_dir(dir)) return "svk"; % verror("Directory '%s' is not under version control", dir); } private define require_buffer_file_in_vc() { %{{{ % get buffer file and dir variable file, dir; (file, dir,,) = getbuf_info(whatbuf()); if (file == "") error("No file attached to this buffer. Please save buffer first."); % check if file is under version control variable entries, file_under_vc = 0; switch (get_vc_system(dir)) { case "cvs": entries = strread_file( path_concat(path_concat(dir, "CVS"), "Entries")); file_under_vc = is_substr(entries, sprintf("/%s/", file)); } { case "svn": entries = strread_file( path_concat(path_concat(dir, ".svn"), "entries")); file_under_vc = orelse{ is_substr(entries, sprintf("name=\"%s\"", file)) % svn < 1.4 }{ is_substr(entries, sprintf("\n%s\n", file)) }; % svn >= 1.4 } { case "svk": % there is no quick-check under svk, just try file_under_vc = 1; } { case "git": % where is a list of git return values? file_under_vc = (shell_command(GIT_executable +" status " + file) != 256); } !if (file_under_vc) { if (get_y_or_n("File " + file + " not found in VC entries. Add it?")) vc_add_buffer(); else verror("File '%s' is not under version control", file); } return (file, dir); } %}}} private define escape_arg(str) { %{{{ return "'" + str_quote_string(str, "\\'$@", '\\') + "'"; } %}}} % Run vc-executable. % % \var{args} list of commands and options (will be shell-escaped) % \var{dir} dir to chdir() to before calling the command. % \var{use_message_buf} Insert report into " *VC output*" buffer % (else into current buffer) % \var{signal_error} throw an error if the command fails % define do_vc(args, dir, use_message_buf, signal_error) %{{{ { variable executable, cmd, msg, result, buf = whatbuf(), cwd = getcwd(); switch (get_vc_system(dir)) % Errors if dir not under version control { case "cvs": executable = CVS_executable; } { case "svn": executable = SVN_executable; } { case "svk": executable = SVK_executable; } { case "git": executable = GIT_executable; } % Quote arguments and join to command string args = array_map(String_Type, &escape_arg, args); cmd = strjoin([executable, args], " "); #ifdef OS2 UNIX cmd += " 2>&1"; % re-direct stderr #endif % Prepare output buffer if (use_message_buf) { popup_buffer(cmd_output_buffer); set_readonly(0); erase_buffer(); } % set working dir if (chdir(dir) == -1) { error("Couldn't chdir to '" + dir + "': " + errno_string(errno)); } set_buffer_dirname(dir); % Run command msg = "Exec: " + cmd + "\nDir: " + dir; flush(msg); insert(msg + "\n\n"); result = run_shell_cmd(cmd); if (bsearch("revision")) flush(get_line()); else flush("done"); % bob(); set_buffer_modified_flag(0); set_readonly(1); fit_window(get_blocal_var("is_popup", 0)); % resize popup window % Restore buffer and working dir % show cmd output if return value != 0 () = chdir(cwd); if (use_message_buf) { !if (result) bury_buffer(cmd_output_buffer); % close_buffer(cmd_output_buffer); else pop2buf(buf); } % throw error if return value != 0 if (result and signal_error) error(sprintf("svn returned error code %d", result)); } %}}} %% Commit files %{{{ private variable end_of_log_str = "# === Targets to commit ==="; % "=== Targets to commit (you may delete items from it) ==="; % Prepare commit of files in array `files' in working dir `dir'. % Edit Log message in a dedicated buffer. % Do the 'real' commit with vc_commit_finish() bound in the "svn-log" keymap. private define vc_commit_start(dir, files) { popup_buffer("*Log Message*"); set_buffer_dirname(dir); define_blocal_var("files", files); vc_log_mode(); % insert info vinsert("\n%s\n", end_of_log_str); vinsert("Dir: %s\n", dir); if (length(files)) vinsert("Files:\n%s", strjoin(files, "\n")); bob(); variable msg = "Edit log message, commit with ESC or %s c"; flush(sprintf(msg, _Reserved_Key_Prefix)); } static define vc_commit_finish() { variable dir = buffer_dirname(); variable file, files = get_blocal_var("files"); variable buf = whatbuf(); % TODO: parse the files list so it can be edited like in SVK % get message (buffer-content up to info area) bob(); push_mark(); bol_fsearch(end_of_log_str); go_left_1(); variable msg = bufsubstr(); set_buffer_modified_flag(0); msg = str_quote_string(msg, "\\'", '\\'); % show(msg); % now commit to VC do_vc(["commit", "-m", msg, files], dir, 1, 1); % Re-load commited buffers to update changes (e.g. to $Keywords$) foreach file (dir + files) { reopen_file(file); } % if everything went fine, close the "*Log Message*" buffer sw2buf(buf); % make active so close_buffer closes the window as well close_buffer(); } %}}} %% Marking files %{{{ !if (is_defined("Cvs_Mark_Type")) typedef struct { filename, diff_line_mark, list_line_mark, dirlist_line_mark } Cvs_Mark_Type; variable marks = Assoc_Type[Cvs_Mark_Type]; private define make_line_mark () { %{{{ return create_line_mark(color_number("menu_selection")); } %}}} private define mark_file(file) { %{{{ variable new = @Cvs_Mark_Type; new.filename = file; variable buf = whatbuf(); update_list_buffer(new); update_diff_buffer(new); update_dirlist_buffer(new); sw2buf(buf); marks[file] = new; %% recenter(0); % call("redraw"); message("Marked " + file); } %}}} private define unmark_file(file) { %{{{ assoc_delete_key(marks, file); %% recenter(0); call("redraw"); message("Unmarked " + file); } %}}} public define vc_unmark_all() { %{{{ marks = Assoc_Type[Cvs_Mark_Type]; } %}}} public define vc_mark_buffer() { %{{{ mark_file(buffer_filename()); } %}}} public define vc_unmark_buffer() { %{{{ unmark_file(buffer_filename()); } %}}} % define have_marked_files() { %{{{ % return length(marks); % } %}}} define toggle_marked_file(file) %{{{ { if (file == "") return; % prepend buffer dir file = path_concat(buffer_dirname(), file); if (assoc_key_exists(marks, file)) { unmark_file(file); } else { mark_file(file); } } %}}} %}}} %% SVN operations on a single buffer %{{{ public define vc_add_buffer() { %{{{ variable file, dir, entries; (file, dir,,) = getbuf_info(whatbuf()); do_vc(["add", file], dir, 1, 1); } %}}} public define vc_commit_buffer() { %{{{ variable file, dir; (file, dir) = require_buffer_file_in_vc(); save_buffer(); vc_commit_start(dir, [file]); } %}}} public define vc_diff_buffer() { %{{{ variable file, dir; (file, dir) = require_buffer_file_in_vc(); save_buffer(); init_diff_buffer(dir, 1); do_vc([ "diff", file ], dir, 0, 0); postprocess_diff_buffer(); } %}}} public define vc_update_buffer() { %{{{ variable file, dir; (file, dir) = require_buffer_file_in_vc(); save_buffer(); do_vc([ "update", file ], dir, 1, 1); if (bol_fsearch("retrieving")) { message("Updated"); } else { message("Not updated (no new version available)"); } find_file(path_concat(dir, file)); } %}}} %}}} %% Functions common to the marked files, diff, and directory list buffers %{{{ private define extract_filename() { %{{{ switch (whatbuf()) { case diff_buffer: return diff_extract_filename(); } { case list_buffer: return list_extract_filename(); } { case dirlist_buffer: return dirlist_extract_filename(); } { error("can only extract files from *SVN diff* and *SVN marked files*");} } %}}} define toggle_marked() { %{{{ toggle_marked_file(extract_filename()); } %}}} %}}} %% "SVN diff" view %{{{ private variable diff_filenames = Assoc_Type[Integer_Type, 0]; private define init_diff_buffer(dir, new_window) { %{{{ if (new_window) popup_buffer(diff_buffer); else sw2buf(diff_buffer); set_readonly(0); erase_buffer(); % reset "global" (private) variable diff_filenames = Assoc_Type[Integer_Type, 0]; set_buffer_dirname(dir); } %}}} private define update_diff_buffer (mark) { %{{{ variable buf = whatbuf(); sw2buf(diff_buffer); variable line = diff_filenames [mark.filename]; if (line != 0) { push_spot(); goto_line(line); mark.diff_line_mark = make_line_mark(); pop_spot(); } sw2buf(buf); } %}}} private define diff_extract_filename() %{{{ { push_spot(); !if (bol_bsearch("Index: ")) error("No file selected (call the command between 'Index: '- lines)"); variable filename = line_as_string()[[7:]]; pop_spot(); return filename; } %}}} private define postprocess_diff_buffer() %{{{ { popup_buffer(diff_buffer); bob(); () = down(2); set_readonly(0); while (bol_fsearch("Index: ")) { variable filename = line_as_string()[[7:]]; variable dir = buffer_dirname(); if (dir != NULL) { filename = path_concat(dir, filename); diff_filenames[filename] = what_line(); if (assoc_key_exists(marks, filename)) { update_diff_buffer(marks[filename]); } } () = down(1); } set_readonly(1); % set to diff mode, if diff_mode is globally defined call_function("diff_mode"); vc_list_mode(); bob(); } %}}} private define diff_extract_linenumber() { %{{{ push_spot(); EXIT_BLOCK { pop_spot(); } if (andelse {bol_bsearch("@@ ")} {ffind_char('+')}) { push_mark(); ffind_char(','); return integer(bufsubstr()); } else { return 0; } } %}}} %}}} %% "SVN marked files" view %{{{ private define list_extract_filename() %{{{ { push_spot(); EXIT_BLOCK { pop_spot(); } variable line = line_as_string(); !if (andelse {line != ""} {line[[0]] != " "} {path_is_absolute(line)}) error("Line doesn't contain a valid filename\n"); % return (path_dirname(line), path_basename(line)); return strtrim(line); } %}}} private define init_list_buffer(erase) { %{{{ vc_list_mode(); set_readonly(0); if (erase) erase_buffer(); push_spot(); bob(); if (eobp()) { insert("The following files have been marked by SVN mode. "); } else { pop_spot(); } } %}}} public define vc_list_marked() { %{{{ variable file; popup_buffer(list_buffer); init_list_buffer(1); insert(" ----- \n"); push_spot(); foreach file (marks) using ("keys") { marks[file].list_line_mark = make_line_mark(); insert(file + "\n"); } pop_spot(); set_readonly(1); } %}}} private define update_list_buffer (mark) { %{{{ sw2buf(list_buffer); init_list_buffer(0); push_spot(); bob(); if (re_fsearch("^" + mark.filename + "$")) { mark.list_line_mark = make_line_mark(); } else { eob(); mark.list_line_mark = make_line_mark(); insert(mark.filename + "\n"); } pop_spot(); set_readonly(1); } %}}} %}}} %% "SVN directory list" view %{{{ private variable dirlist_filenames = Assoc_Type[Integer_Type]; private define dirlist_extract_filename() %{{{ { variable line = get_line(), dir = buffer_dirname(), flag_cols = Assoc_Type[Integer_Type]; flag_cols["cvs"] = 1; flag_cols["svn"] = 19; flag_cols["svk"] = 3; flag_cols["git"] = 3; % get number of leading info columns for used VC system flag_cols = flag_cols[get_vc_system(dir)]; if (orelse{strlen(line) <= flag_cols} {line[flag_cols] != ' '}) { % show(line, line[flag_cols], "no valid filename"); return ""; } return strtrim(line[[flag_cols:]]); } %}}} private define update_dirlist_buffer(mark) { %{{{ sw2buf(dirlist_buffer); push_spot(); if (assoc_key_exists(dirlist_filenames, mark.filename)) { variable line = dirlist_filenames [mark.filename]; push_spot(); goto_line(line); mark.dirlist_line_mark = make_line_mark(); pop_spot(); } } %}}} % Set dirctory for VC operations. % TODO: cache default (current behaviour) or use dir of current buffer? private define get_op_dir() { %{{{ if (project_root == "") { project_root = buffer_dirname(); } project_root = read_with_completion("Enter dir for operation: ", "", project_root, 'f'); return project_root; } %}}} public define vc_list_dir() % (dir=get_op_dir())%{{{ { !if (_NARGS) get_op_dir(); % push on stack variable dir = (); % get vc system, abort if dir is not under version control variable vc_system = get_vc_system(dir); sw2buf(dirlist_buffer); vc_list_mode(); % set buffer directory and unset readonly flag setbuf_info("", dir, dirlist_buffer, 0); define_blocal_var("generating_function", [_function_name, dir]); set_readonly(0); erase_buffer(); % cvs returns a very verbose list with the status command % the info recommends a dry-run of 'update' for a short list switch (vc_system) { case "cvs": do_vc(["-n", "-q", "update"], dir, 0, 0); } { case "svn": do_vc(["status", "-u"], dir, 0, 0); } { do_vc(["status"], dir, 0, 0); } % postprocess dirlist buffer variable file; bob(); re_replace("cvs update: warning: \(.*\) was lost"R, "! \1"R); bob(); () = down(2); while (down(1)) { file = dirlist_extract_filename(); if (file == "") continue; file = path_concat(dir, file); dirlist_filenames[file] = what_line(); if (assoc_key_exists(marks, file)) { update_dirlist_buffer(marks[file]); } } set_readonly(1); bob(); } %}}} %!%+ %\function{vc_reread} %\synopsis{Re-read the current file listing} %\usage{vc_list_reread()} %\description % Re run the function that generated the current file list to % update the view. %\seealso{vc_list_mode} %!%- public define vc_list_reread() { variable line = what_line(); () = run_function(push_array(get_blocal_var("generating_function"))); goto_line(line); } %}}} %% Operations on all marked files %{{{ private define find_marked_common_root() { %{{{ variable afiles = assoc_get_keys(marks); if (length(afiles) == 0) { error("No files marked"); } variable dir, dirs = array_map(String_Type, &path_dirname, afiles); variable rfiles = String_Type [length(afiles)]; variable prefix = ""; foreach dir (dirs) { if (strcmp(dir, "") != 0) { if (strcmp(prefix, "") == 0) { prefix = dir; } else { while (strcmp(dir, prefix) != 0 and strlen(prefix) > 1) { if (strlen(dir) == strlen(prefix)) { prefix = path_dirname(prefix); dir = path_dirname(dir); } else if (strlen(dir) < strlen(prefix)) { prefix = path_dirname(prefix); } else { dir = path_dirname(dir); } } } } } % +1 to get rid of leading slash in unix. This assumption might % be invalid on other platforms variable prefixlen = strlen(prefix) + 1; variable i; for (i = 0; i < length(rfiles); i++) { rfiles[i] = afiles[i][[prefixlen:]]; } return (dir, rfiles); } %}}} public define vc_add_marked() { %{{{ variable dir, rfiles; (dir, rfiles) = find_marked_common_root(); do_vc(["add", rfiles], dir, 1, 1); } %}}} public define vc_commit_marked() { %{{{ variable dir, files; (dir, files) = find_marked_common_root(); vc_commit_start(dir, files); vc_unmark_all(); } %}}} public define vc_diff_marked() { %{{{ variable dir, rfiles; (dir, rfiles) = find_marked_common_root(); init_diff_buffer(dir, 1); do_vc(["diff", rfiles], dir, 0, 0); postprocess_diff_buffer(); } %}}} public define vc_update_marked() { %{{{ variable dir, rfiles; (dir, rfiles) = find_marked_common_root(); do_vc(["update", rfiles], dir, 1, 1); } %}}} %}}} %% Operations on single files (valid only in marked files, diff, or %% directory list buffers). %{{{ public define vc_add_selected() { %{{{ variable dir = buffer_dirname(), file = extract_filename(); do_vc(["add", file], dir, 1, 1); } %}}} % take file out of version control, keep local copy public define vc_subtract_selected() %{{{ { variable dir = buffer_dirname(), file = extract_filename(), tmpfile, prompt = "Remove '%s' from VC (keep local copy)"; if (get_y_or_n(sprintf(prompt, file)) != 1) return; switch(get_vc_system(dir)) { case "svn": tmpfile = make_tmp_file(dir+file); () = rename_file(file, tmpfile); do_vc(["remove", "--force", "--keep-local", file], dir, 1, 1); () = rename_file(tmpfile, file); } { case "svk": do_vc(["remove", "--force", "--keep-local", file], dir, 1, 1); } { case "cvs": error("TODO: not implemented yet"); % move to backup, remove from vc, restore } } %}}} % take file out of version control, delete local copy public define vc_delete_selected() %{{{ { variable dir = buffer_dirname(), tmpfile, file = extract_filename(); if (get_y_or_n(sprintf("Delete '%s' from VC and local copy", file)) != 1) return; switch(get_vc_system(dir)) { case "svn": do_vc(["remove", "--force", file], dir, 1, 1); } { case "svk": do_vc(["remove", "--force", file], dir, 1, 1); } { case "cvs": error("TODO: not implemented yet"); % delete from working cpy, remove from vc } } %}}} % commit one selected file public define vc_commit_selected() { %{{{ variable file = extract_filename(); vc_commit_start(buffer_dirname(), [file]); } %}}} public define vc_diff_selected() { %{{{ variable dir = buffer_dirname(), file = extract_filename(); init_diff_buffer(dir, 1); do_vc(["diff", file], dir, 0, 0); postprocess_diff_buffer(); } %}}} public define vc_update_selected() { %{{{ variable file = extract_filename(); do_vc(["update", file], buffer_dirname(), 1, 1); } %}}} public define vc_revert_selected() %{{{ { variable file = extract_filename(), dir = buffer_dirname(); !if (get_y_or_n(sprintf("Revert '%s'", file)) == 1) return; switch(get_vc_system(dir)) { case "cvs": do_vc(["update", "-C", file], dir, 1, 1); } { do_vc(["revert", file], dir, 1, 1); } } %}}} public define vc_open_selected() { %{{{ variable linenum, file = extract_filename(); if (whatbuf() == diff_buffer) { linenum = diff_extract_linenumber(); } else { linenum = 0; } find_file(path_concat(buffer_dirname, file)); if (linenum) { goto_line(linenum); } } %}}} %}}} %% SVN directory-level operations %{{{ public define vc_add_dir() { %{{{ %% Kludge to get rid of a possible trailing separator variable dir = path_dirname(path_concat(get_op_dir(), "")); variable parent = path_dirname(dir); variable name = path_basename(dir); switch (get_vc_system(parent)) { case "cvs": do_vc(["add", name], parent, 1, 1); } { case "svn" or case "svk": do_vc(["add", "--non-recursive", name], parent, 1, 1); } } %}}} % commit all modified files in dir and subdirs public define vc_commit_dir() %{{{ { variable dir = get_op_dir(); % commit with empty files list vc_commit_start(dir, String_Type[0]); } public define vc_diff_dir() { %{{{ variable dir = get_op_dir(); init_diff_buffer(dir, 0); do_vc(["diff"], dir, 0, 0); postprocess_diff_buffer(); } %}}} public define vc_update_dir() { %{{{ variable dir = get_op_dir(); do_vc(["-q", "update"], dir, 1, 1); } %}}} %}}} %}}} %% Initialization %{{{ private define vc_commom_menu_callback(menu) { menu_append_item(menu, "&Add marked", "vc_add_marked"); menu_append_item(menu, "&Commit marked", "vc_commit_marked"); menu_append_item(menu, "&Diff marked", "vc_diff_marked"); menu_append_item(menu, "Unmark all", "vc_unmark_all"); menu_append_item(menu, "&Update marked", "vc_update_marked"); menu_append_separator(menu); menu_append_item(menu, "Add directory", "vc_add_dir"); menu_append_item(menu, "Commit directory", "vc_commit_dir"); menu_append_item(menu, "Diff directory", "vc_diff_dir"); menu_append_item(menu, "Update directory", "vc_update_dir"); menu_append_item(menu, "&Open directory list", "vc_list_dir"); } public define vc_menu_callback(menu) { %{{{ menu_append_item(menu, "&add buffer", "vc_add_buffer"); menu_append_item(menu, "&commit buffer", "vc_commit_buffer"); menu_append_item(menu, "&diff buffer", "vc_diff_buffer"); menu_append_item(menu, "&mark buffer", "vc_mark_buffer"); menu_append_item(menu, "unmark buffer", "vc_unmark_buffer"); menu_append_item(menu, "&update buffer", "vc_update_buffer"); menu_append_separator(menu); menu_append_item(menu, "&List marked", "vc_list_marked"); vc_commom_menu_callback(menu); } %}}} #ifexists set_matching_hidden static define hide_unknown_files() { set_matching_hidden(1, "^\?"R); } static define vc_list_menu_callback(menu) { %{{{ menu_append_item(menu, "&add file", "vc_add_selected"); menu_append_item(menu, "&commit file", "vc_commit_selected"); menu_append_item(menu, "&diff file", "vc_diff_selected"); menu_append_item(menu, "&update file", "vc_update_selected"); menu_append_item(menu, "&revert file", "vc_revert_selected"); menu_append_item(menu, "&subtract file (keep local copy)", "vc_subtract_selected"); menu_append_item(menu, "delete file (also local copy)", "vc_delete_selected"); menu_append_separator(menu); if (is_defined("svn->hide_unknown_files")) menu_append_item(menu, "&hide unknown files", "svn->hide_unknown_files"); menu_append_item(menu, "&toggle Mark", "svn->toggle_marked"); menu_append_item(menu, "Unmark all", "vc_unmark_all"); menu_append_separator(menu); vc_commom_menu_callback(menu); menu_append_separator(menu); menu_append_item(menu, "&Quit", "close_buffer"); menu_insert_item("&Open directory list", menu, "Re&generate list", "vc_list_reread"); } %}}} private define keymap_init() { %{{{ setkey_reserved("vc_add_buffer", "a"); setkey_reserved("vc_add_marked", "ma"); setkey_reserved("vc_add_dir", "^a"); setkey_reserved("vc_commit_buffer", "c"); setkey_reserved("vc_commit_marked", "mc"); setkey_reserved("vc_diff_buffer", "d"); setkey_reserved("vc_diff_marked", "md"); setkey_reserved("vc_diff_dir", "^d"); setkey_reserved("vc_list_marked", "l"); setkey_reserved("vc_list_marked", "ml"); setkey_reserved("vc_list_dir", "^l"); setkey_reserved("vc_mark_buffer", "mm"); setkey_reserved("vc_unmark_buffer", "m^m"); setkey_reserved("vc_unmark_all", "m^u"); setkey_reserved("vc_update_buffer", "u"); setkey_reserved("vc_update_marked", "mu"); setkey_reserved("vc_update_dir", "^u"); setkey_reserved("vc_re_eval", "r"); } variable kmap = "svn-list"; !if (keymap_p(kmap)) { make_keymap(kmap); definekey("vc_add_marked", "A", kmap); definekey("vc_commit_marked", "C", kmap); definekey("vc_diff_marked", "D", kmap); definekey("vc_update_marked", "U", kmap); definekey("vc_add_selected", "a", kmap); definekey("vc_commit_selected", "c", kmap); definekey("vc_diff_selected", "d", kmap); definekey("vc_list_reread", "g", kmap); % dired like definekey("vc_update_selected", "u", kmap); definekey("vc_open_selected", "\r", kmap); definekey("vc_revert_selected", "r", kmap); definekey("svn->toggle_marked; go_down_1", Key_Ins, kmap); definekey("svn->toggle_marked", "t", kmap); % definekey("svn->toggle_marked", " ", kmap); definekey("vc_unmark_all", "U", kmap); definekey("close_buffer", "q", kmap); } %}}} if (VC_set_reserved_keybindings) { keymap_init(); } %}}} % Log Mode % ======== % % mode for the buffer where the commit log is edited. private variable log_mode = "vc-log"; % >> User Survey: Which key should close this buffer and trigger the commit? % > _Reserved_Key_Prefix + c % Jörg Sommer % > Key_Esc or ^W % Joachim Schmitz % % IMO, Key_Esc is not suited as it is usually an "abort" key % Maybe it should open the mode-menu to give a choice? !if (keymap_p(log_mode)) { make_keymap(log_mode); definekey_reserved("svn->vc_commit_finish", "c", log_mode); % keep ^W as close_buffer (in CUA mode) definekey("close_buffer", Key_Esc, log_mode); } % context menu static define log_mode_menu(menu) { menu_append_item(menu, "&Commit", "svn->vc_commit_finish"); menu_append_item(menu, "&Quit", "close_buffer"); } static define vc_log_mode() { set_mode(log_mode, 1); mode_set_mode_info(log_mode, "init_mode_menu", &log_mode_menu); mode_set_mode_info(log_mode, "run_buffer_hook", &vc_commit_finish); use_keymap(log_mode); } % VC list mode % ============ % a common mode for all vc listings private variable list_mode = "vc-list"; % Highlighting % ------------ % NEEDS dfa for this mode to work. create_syntax_table(list_mode); #ifdef HAS_DFA_SYNTAX dfa_define_highlight_rule("^[^ ]+: .*", "operator", list_mode); dfa_define_highlight_rule("^\? .*"R, "comment", list_mode); % not under vc dfa_define_highlight_rule("^A .*", "string", list_mode); % added dfa_define_highlight_rule("^C .*", "error", list_mode); % conflict dfa_define_highlight_rule("^D .*", "preprocess", list_mode); % delete dfa_define_highlight_rule("^R .*", "preprocess", list_mode); % delete (CVS) dfa_define_highlight_rule("^M .*", "keyword", list_mode); % modified dfa_define_highlight_rule("^~ .*", "delimiter", list_mode); % different object dfa_define_highlight_rule("^! .*", "error", list_mode); % missing % render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_define_highlight_rule("[^ -~]+", "normal", list_mode); dfa_build_highlight_table(list_mode); enable_dfa_syntax_for_mode(list_mode); #endif public define vc_list_mode() { set_mode(list_mode, 0); % For some reason, DFA syntax highlight does overwrite the line-marks % (it works well in filelist_mode() though). % use_syntax_table(list_mode); mode_set_mode_info(list_mode, "init_mode_menu", &svn->vc_list_menu_callback); use_keymap("svn-list"); } jedmodes-2.5.7/dict-backend/0000755000175400017500000000000011146315764014122 5ustar mildegmjedmodes-2.5.7/dict-backend/dict-cli.sl0000644000175400017500000000710211146315536016147 0ustar mildegm% dict-cli.sl: dict backend using the command line interface `dict` % % Copyright © 2005 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-13 first public version % 0.1.1 2006-09-25 use do_shell_cmd() for error redirection provide("dict-backend"); provide("dict-cli"); % Requirements % ------------ % * `dict` command line dict-client (see Dict_Cmd) %!%+ %\variable{Dict_Cmd} %\synopsis{Command line program for dict lookup} %\usage{variable Dict_Cmd = "dict"} %\description % The command line program for dict lookup (on most systems this will be % "dict"). An alternative is "dictl", a wrapper for conversion of|from UTF8 % into the users locale) %\example % To use the "dictl" wrapper if the current locale is not utf8 aware put in % ~/.jed/jed.rc (or ~/.jedrc) %#v+ % if (_slang_utf8_ok) % variable Dict_Cmd = "dict"; % else % variable Dict_Cmd = "dictl"; %#v- %\seealso{dict, dict_mode, Dict_Server, Dict_DB} %!%- custom_variable("Dict_Cmd", "dict"); % cache for dict_show results static variable show_cache = Assoc_Type[String_Type]; static variable last_host = ""; % transform host argument to command line option(s) % "host" --> "--host " % "host:port" --> "--host --port " private define parse_host(host) { host = strtok(host, ":"); return "--host " + strjoin(host, " --port "); } define dict_define(word, database, host) { variable db, cmd; foreach db (strtok(database, ",")) { cmd = sprintf("%s --database '%s' %s '%s'", Dict_Cmd, db, parse_host(host), word); set_prefix_argument(1); do_shell_cmd(cmd); } } % insert the result of the MATCH command into the current buffer define dict_match(word, strategy, database, host) { variable db, cmd; foreach db (strtok(database, ",")) { cmd = sprintf("%s --database '%s' %s --match --strategy %s '%s'", Dict_Cmd, db, parse_host(host), strategy, word); set_prefix_argument(1); do_shell_cmd(cmd); } } % insert the result of the SHOW command into the current buffer define dict_show(what, host) { if (host != last_host) { show_cache = Assoc_Type[String_Type]; % reset cache last_host = host; } % if the result is cashed, insert and return if (assoc_key_exists(show_cache, what)) return insert(show_cache[what]); % what --> option switch (what) { case "db": what = "--dbs"; } { case "strat": what = "--strats"; } { case "server": what = "--serverinfo"; } { is_substr(what, "info"): % convert "info:" to "-- info " what = strtok(what, ":"); what = "--info " + strjoin(what, " "); } { error("argument must be one of 'db', 'strat', 'server', info:"); } set_prefix_argument(1); do_shell_cmd(sprintf("%s %s %s", Dict_Cmd, parse_host(host), what)); % cache result mark_buffer(); show_cache[what] = bufsubstr(); } #iffalse % Build a dict:// URL for the query defined by the arguments in the form % dict://host:port/d:word:database % dict://host:port/m:word:database:strategy % (see `man dict` or section 5. "URL Specification" of RFC2229) variable db, urls, url; if (is_substr(word, "dict://") == 1) urls = [word]; else if (strategy == NULL) % definition lookup urls = array_map(String_Type, &sprintf, "dict://%s/d:%s:%s", Dict_Server, word, strtok(database, ",")); else urls = array_map(String_Type, &sprintf, "dict://%s/m:%s:%s:%s", Dict_Server, word, strtok(database, ","), strategy); #endif jedmodes-2.5.7/dict-backend/dict-curl.sl0000644000175400017500000000517010512704365016346 0ustar mildegm% dict-curl.sl: a backend to dict mode using the curl module % % Copyright (c) 2006 Paul Boekholt % Released under the terms of the GNU General Public License (ver. 2 or later) % % Usage % ----- % % Place in the jed library path. If dict-cli.sl is in the path as % well but you prefer the curl interface, set the custom variable % Dict_Backends, e.g. in jed.rc % % variable Dict_Backends = "dict-curl.sl"; % % Versions: % --------- % % 0.1 2006-03-03 First public version % 0.2 2006-09-27 dollar strings caused segfaults with slang 2.0.6 % fized lookup of multi word keywords % 0.3 2006-09-28 Removed quoting of multi word keywords again after % upgrading to libcurl 7.15 require("curl"); provide("dict-backend"); provide("dict-curl"); private define write_callback (v, data) { insert(data); return 0; } private define do_curl() { variable args=__pop_args(_NARGS); variable v; variable c = curl_new (sprintf(__push_args(args))); curl_setopt (c, CURLOPT_WRITEFUNCTION, &write_callback, &v); curl_perform (c); } define dict_define(word, database, host) { variable db, line; foreach db (strtok(database, ",")) do_curl("dict://%s/d:%s:%s", host, word, db); bob(); replace("\r", ""); push_mark(); forever { !if (bol_fsearch("151 ")) { eob(); del_region(); bob(); return; } % convert % 151 "mode" jargon "Jargon File (4.4.4, 14 Aug 2003)" % to % From "Jargon File (4.4.4, 14 Aug 2003)" [jargon]: push_mark_eol(); line = strtok(bufsubstr_delete(), " "); db = line[2]; line = strjoin(line[[3:]], " "); go_down_1(); del_region(); vinsert("From %s [%s]:\n", line, db); while (bol_fsearch(".")) { if (looking_at("..")) { del(); eol(); } else { push_mark(); break; } } } } define dict_match(word, strategy, database, host) { variable db; foreach db (strtok(database, ",")) do_curl("dict://%s/m:%s:%s:%s", host, word, db, strategy); bob(); replace("\r", ""); push_mark(); forever { !if (bol_fsearch("152 ")) { eob(); del_region(); bob(); return; } go_down_1(); del_region(); push_spot(); while (bol_fsearch(".")) { if (looking_at("..")) { del(); eol(); } else { push_mark(); break; } } } } define dict_show(what, host) { do_curl("dict://%s/show:%s", host, what); bob(); replace("\r", ""); bob(); if(bol_fsearch("110")) delete_line(); bob(); while(bol_fsearch(".")) del(); bob(); while(bol_fsearch("2")) delete_line(); } jedmodes-2.5.7/sprint_var/0000755000175400017500000000000010510665672014001 5ustar mildegmjedmodes-2.5.7/sprint_var/sprint_var.sl0000644000175400017500000001672310510665660016536 0ustar mildegm% sprint_var.sl: Formatted info about variable values % % Copyright (c) 2005, 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Provides the function sprint_variable() that can handle complex variables % such as arrays, associative arrays, and structures. % % USAGE % % Place in your jed library path and do things like % message(sprint_variable([1, 2, 3, 5])); % % NOTES % % Newer versions of slsh come with a print.sl library file that does many % of the things sprint_var.sl does: % % print.sl sprint_var.sl % ======== ============= % struct_to_string sprint_struct % print_array sprint_array % print sprint_variable % % % VERSIONS % 1.0 first public version % 1.1 2005-04-20 print user defined data types as struct % (test with is_struct_type that also works for structures of % types other than Struct_Type) % added tm documentation % 1.2 2006-02-01 added provide() % 1.3 2006-02-17 added special cases to sprint_char % 1.4 2006-06-22 added sprint_list() % 1.4.1 2006-10-04 bugfix in sprint_list() % Requirements % ------------ autoload("array_product", "datutils"); autoload("array_repeat", "datutils"); #ifexists _slang_utf8_ok autoload("list2array", "datutils"); autoload("str_re_replace", "strutils"); #endif provide("sprint_var"); %!%+ %\variable{Sprint_Indent} %\synopsis{Indendation string used by sprint_variable() for complex variables} %\usage{String_Type Sprint_Indent = " "} %\description % How much shall a sub-list be indented in a variable listing with % \sfun{sprint_variable}? % % Set as literal string of spaces. %\seealso{sprint_variable} %!%- custom_variable("Sprint_Indent", " "); % newline + absolute indendation (used/set by sprint_...) static variable Sprint_NL = "\n"; define sprint_struct(); % forward definition %!%+ %\function{sprint_variable} %\synopsis{Print a variable to a string (verbosely)} %\usage{String_Type sprint_variable(var)} %\description % A more verbose variant of \sfun{string} that recurses into elements % of compound data types. %\notes % The latest snapshot of slang 2 has a print.sl library file that does many % of the things sprint_var.sl does: % % print.sl sprint_var.sl % ======== ============= % struct_to_string sprint_struct % print_array sprint_array % print sprint_variable %\seealso{show, shoe_message, Sprint_Indent, print} %!%- public define sprint_variable(var) { variable type, sprint_hook; type = extract_element(string(typeof(var)), 0, '_'); sprint_hook = __get_reference("sprint_"+strlow(type)); if (sprint_hook != NULL) { % show_string("printing using sprint_"+strlow(type)); return @sprint_hook(var); } % Test for user defined types (struct-like) if (is_struct_type(var)) return sprint_struct(var); return string(var); } % Return a 1d array of indices for multidim-array with dimensions dims define multidimensional_indices(dims) { variable i, j, N = length(dims); % dimensionality variable L = array_product(dims); variable index = Array_Type[L], a = Integer_Type[N,L]; for (i=0; i 1} {strlen(str) > WRAP} {is_substr(str, "\n")}) { indices = multidimensional_indices(dims); indices = array_map(String_Type, &sprint_variable, indices); reshape(strarray, length(strarray)); strarray = indices + " " + strarray; str = string(a) + Sprint_NL + strjoin(strarray, Sprint_NL); (str, ) = strreplace(str, "\n", "\n"+Sprint_Indent, strlen(str)); } return (str); } define sprint_list(list) { variable n, str = sprint_array(list2array(list)); (str, n) = str_re_replace(str, "^[a-zA-Z]+_Type", "List_Type", 1); str = str_replace_all(str, "Any_Type: ", ""); if (n) return str; else return strcat("{", substr(str, 2, strlen(str)-2), "}"); } % print to a string all keys and elements of an associative array: define sprint_assoc(ass) { if (typeof(ass) != Assoc_Type) return(string(ass)+ "is no associative array"); variable str = string(ass); % get and sort keys variable keys = assoc_get_keys(ass); variable I = array_sort(keys); % returns the indices in sort order keys = keys[I]; % array as index returns array of values % get values and append key-value-pairs to str Sprint_NL += Sprint_Indent; variable key; foreach (keys) { key = (); str += sprintf("%s[%s]\t%s", Sprint_NL, string(key), sprint_variable(ass[key])); } % the default value: ERROR_BLOCK {_clear_error; "not defined";} % in case no default is defined variable default = sprint_variable(ass["?_*_!"]); % (hopefully) never used key str += Sprint_NL + "DEFAULT\t " + default; Sprint_NL = Sprint_NL[[:-1-strlen(Sprint_Indent)]]; return(str); } % print to a string all fields of a structure define sprint_struct(s) { variable field, value; variable str = string(s); Sprint_NL += Sprint_Indent; foreach (get_struct_field_names(s)) { field = (); value = get_struct_field(s, field); str += Sprint_NL + "." + field + "\t" + sprint_variable(value); } Sprint_NL = Sprint_NL[[:-1-strlen(Sprint_Indent)]]; return(str); } % Why is there no easy way to access .line and .column of a Mark? define mark_info(mark) { variable b, l, c; variable currbuf = whatbuf(); ERROR_BLOCK { _clear_error; pop; return("deleted buffer", 0, 0); } b = user_mark_buffer(mark); sw2buf(b); push_spot(); goto_user_mark(mark); l = what_line(); c = what_column(); pop_spot(); sw2buf(currbuf); return (b, l, c); } % print to a string nicely formatted info about a user_mark: define sprint_mark(m) { if (typeof(m) != Mark_Type) return(string(m) + "is no user mark"); variable buf, line, column; return sprintf("User_Mark: %s(%d,%d)", mark_info(m)); } % surround with "" to make clear it is a string define sprint_string(str) { (str, ) = strreplace(str, "\n", "\\n", strlen(str)); (str, ) = strreplace(str, "\t", "\\t", strlen(str)); (str, ) = strreplace(str, "\e", "\\e", strlen(str)); return ("\"" + str + "\""); } define sprint_char(ch) { switch (ch) { case '\'': return "'\''";} % single quote { case '\\': return "'\\'";} % backslash { case '\a': return "'\a'";} % bell character (ASCII 7) { case '\t': return "'\t'";} % tab character (ASCII 9) { case '\n': return "'\n'";} % newline character (ASCII 10) { case '\e': return "'\e'";} % escape character (ASCII 27) { case 0: return "'\000'";} % binary zero return strcat("'", char(ch), "'"); } define sprint_any(any) { return("Any_Type: " + sprint_variable(@any)); } jedmodes-2.5.7/dabbrev/0000755000175400017500000000000010461125567013216 5ustar mildegmjedmodes-2.5.7/dabbrev/dabbrev.sl0000664000175400017500000003227210214064413015157 0ustar mildegm% Complete the current word looking for similar word-beginnings % % Versions % 1 May 1994 Adrian Savage (afs@jumper.mcc.ac.uk) % Extensively modified by JED % 2.0 2003-05-01 rewrite by G.Milde % added support for scanning in a list of buffers % 2.1 added customizability % 2.2 look at last finding first % (as emacs does, tip P. Boekholt) % 2.2.1 bugfix: invalid mark when buffer of last % expansion killed (P. Boekholt) % 2.3 2003-12-01 prevent flooding the undo-buffer (using getkey for % subsequent invocations) % 2.3.1 2003-12-05 replaced unget_keystring with buffer_keystring % 2.4 2004-03-15 dabbrev() takes a prefix argument for the % buflist-scope (this is checked in dab_reset()) % clearer documentation (open_buffers -> all buffers) % (hints by J. E. Davis) % 2.4.1 2004-03-30 new custom var Dabbrev_Case_Search % added documentation for custom vars and get_buflist % 2.4.2 2004-04-05 bugfix (code cleanup) in check_mark. % dabbrev accepts integer argument and uses get_buflist % to convert to a buffer list. (actual change in dab_reset) % get_buflist becomes static % % USAGE: % Put in path und bind to a key, e.g. % setkey("dabbrev", "^A"); % expand from Dabbrev_Default_Buflist % setkey("dabbrev(get_buflist(1))", "\ea"); % expand from visible buffers % % You can use any function that returns a list of buffers as argument, % make sure it is declared, e.g. with autoload("get_buflist", "dabbrev"); % % You could even define your own metafunction that does something usefull % (e.g. open a buffer) and then calls dabbrev("buf1\nbuf2\n ...") to expand % from listed buffers. % % CUSTOMIZATION % % Some custom variables can be used to tune the behaviour of dabbrev: % (The defaults are set to make dabbrev work as version 1) % % "Dabbrev_delete_tail", 0 % replace the existing completion % "Dabbrev_Default_Buflist", 0 % default to whatbuf() % "Dabbrev_Look_in_Folds", 1 % open folds when scanning for completions % --------------------------------------------------------------------------- % debug info, uncomment to trace down bugs % _traceback = 1; % _debug_info = 1; % --- Variables % %!%+ %\variable{Dabbrev_delete_tail} %\synopsis{Let completion replace word tail?} %\usage{Int_Type Dabbrev_delete_tail = 0} %\description % Should the completion replace the part of the word behind the cursor? %\seealso{dabbrev} %!%- custom_variable("Dabbrev_delete_tail", 0); %!%+ %\variable{Dabbrev_Default_Buflist} %\synopsis{Which buffers should dabbrev expand from?} %\usage{Int_Type Dabbrev_Default_Buflist = 0} %\description % The buffer-list when dabbrev is called without argument % 0 = current buffer, % 1 = visible buffers (including the current), % 2 = all buffers of same mode, % 3 = all buffers, % 4 = other visible buffers (excluding the current), % 5 = all other buffers of same mode (excluding the current), % 6 = all other buffers (excluding the current) %\seealso{dabbrev, get_buflist} %!%- custom_variable("Dabbrev_Default_Buflist", 0); %!%+ %\variable{Dabbrev_Look_in_Folds} %\synopsis{Scan folds for expansions} %\usage{Int_Type Dabbrev_Look_in_Folds = 1} %\description % Should dabbrev scan folded parts of the source buffer(s) % for expansions too? %\seealso{dabbrev} %!%- custom_variable("Dabbrev_Look_in_Folds", 1); %!%+ %\variable{Dabbrev_Case_Search} %\synopsis{Let dabbrev stick to case} %\usage{Int_Type Dabbrev_Case_Search = 1} %\description % Should dabbrev consider the case of words when looking for expansions? %\seealso{dabbrev} %!%- custom_variable("Dabbrev_Case_Search", 1); static variable BufList = NULL, BufList_Index, % list of source buffers Word_Chars, % characters that make up a word (for dabbrev) Core_Pattern, % the actual word to complete Pattern = "", % preceding word + non-word-chars + Core_Pattern Completion_List = "", % list of already suggested completions Scan_Mark = create_user_mark(), % position of last hit, Scan_Direction = 0; % 0 backward, 1 forward % --- Functions %!%+ %\function{get_buflist} %\synopsis{Return a newline-delimited list of buffers.} %\usage{String get_buflist(Integer scope)} %\description % Return a list of buffers suited as (optional) argument for the % \var{dabbrev} function. % The argument \var{scope} means: % 0 = current buffer, % 1 = visible buffers (including the current), % 2 = all buffers of same mode, % 3 = all buffers, % 4 = other visible buffers (excluding the current), % 5 = all other buffers of same mode (excluding the current), % 6 = all other buffers (excluding the current) %\example % You can use get_buflist to have keybindings to different % "flavours" of dabbrev %#v+ % setkey("dabbrev", "^A"); % expand from Dabbrev_Default_Buflist % setkey("dabbrev(get_buflist(1))", "\ea"); % expand from visible buffers %#v- %\seealso{dabbrev, Dabbrev_Default_Buflist} %!%- static define get_buflist(scope) { !if(scope) return whatbuf; variable buf, buflist = "", curbuf = whatbuf(), mode = get_mode_name(); variable exclude_whatbuf = scope > 3; if (exclude_whatbuf) scope -= 3; loop (buffer_list() - exclude_whatbuf) { buf = (); % skip hidden buffers !if (strncmp(buf, " <", 2)) % strncmp returns 0 if equal! continue; % filter switch (scope) {case 1: !if (buffer_visible(buf)) continue;} {case 2: sw2buf(buf); !if (get_mode_name() == mode) continue;} buflist = strcat(buf, "\n", buflist); } _pop_n(exclude_whatbuf); sw2buf(curbuf); return strtrim_end(buflist); } % replace an invalid mark with a mark at current point static define check_mark(markp) { ERROR_BLOCK { @markp = create_user_mark(); _clear_error; return; } () = (@markp).buffer_name; % dummy call to test mark validity } % get the word tail static define dab_get_word_tail(kill) { push_mark; skip_chars(Word_Chars); exchange_point_and_mark(); if (kill) return bufsubstr_delete(); else return bufsubstr(); } % Switch to buf, mark position, widen if narrowed % TODO: How about hidden lines? static define dab_sw2buf(buf) { % show("switching to ", buf); !if (bufferp(buf)) return; sw2buf(buf); push_spot(); if (count_narrows() and Dabbrev_Look_in_Folds) { push_narrow (); widen_buffer (); } } % Save position for next completion-search, return to position and % restore previous narrow-state, return to buf static define dab_return2buf(buf) { Scan_Mark = create_user_mark(); % update pop_spot(); pop_narrow(); % does nothing if not narrowed before sw2buf(buf); } % reset the static variables static define dab_reset() % (buflist = whatbuf()) { % List of buffers to scan for completions if (_NARGS) { BufList = (); if (typeof(BufList) != String_Type) BufList = get_buflist(BufList); } else { variable buflist_scope = prefix_argument(-1); if (buflist_scope == -1) buflist_scope = Dabbrev_Default_Buflist; % buflist_scope = get_blocal("Dabbrev_Default_Buflist", % Dabbrev_Default_Buflist; BufList = get_buflist(buflist_scope); } BufList = strchop(BufList, '\n', 0); BufList_Index = -2; % get word_chars from: 1. mode_info, 2. blocal_var, 3. get_word_chars Word_Chars = mode_get_mode_info("dabbrev_word_chars"); if (Word_Chars == NULL) { if (blocal_var_exists("Word_Chars")) Word_Chars = get_blocal_var("Word_Chars"); else Word_Chars = "_" + get_word_chars(); } % Get patterns to expand from (keep cursor position) push_mark(); push_mark(); bskip_chars(Word_Chars); Core_Pattern = bufsubstr(); % current word bskip_chars("^" + Word_Chars); bskip_chars(Word_Chars); exchange_point_and_mark(); Pattern = bufsubstr(); % current + previous word !if (strlen(Pattern)) error("nothing to expand"); % Exclude current completion and empty string Completion_List = dab_get_word_tail(Dabbrev_delete_tail) + "\n"; % create a new scan-mark if it is invalid or nonexistent. check_mark(&Scan_Mark); } % search in Scan_Direction for Pattern, return success static define dab_search() { variable found; variable old_case_search = CASE_SEARCH; CASE_SEARCH = Dabbrev_Case_Search; ERROR_BLOCK {CASE_SEARCH = old_case_search;} do { if (Scan_Direction) { go_right_1(); found = fsearch(Pattern); } else found = bsearch(Pattern); !if (found) return 0; % test whether at begin of a word push_spot(); bskip_chars(Word_Chars); POINT; % push current column-position on stack pop_spot(); } while (POINT != ()); CASE_SEARCH = old_case_search; return found; } static define dab_expand() { variable heureka = 0, completion, return_mark = create_user_mark(); % if reset, find completion at place of last hit dab_sw2buf(Scan_Mark.buffer_name); goto_user_mark(Scan_Mark); if (BufList_Index == -2) % first call after reset { heureka = looking_at(Pattern) * strlen(Pattern); BufList_Index++; } % Find completion in BufList[BufList_Index] forever { if (BufList_Index >= 0) heureka = dab_search(); else heureka = 0; % Pattern found, get completion if (heureka) { push_spot(); go_right(heureka); % heureka contains strlen of Pattern completion = dab_get_word_tail(0); pop_spot(); % is it new? !if(is_list_element(Completion_List, completion, '\n')) { Completion_List += "\n" + completion; break; } else continue; } % look forwards else if(BufList_Index >= 0 and not(Scan_Direction)) { % show("switch to forward scan in buffer Nr", BufList_Index); Scan_Direction = 1; goto_spot(); % goto initial position in Scan-Buffer } % try next buffer from list else if (BufList_Index < length(BufList)-1) { pop_spot(); pop_narrow(); BufList_Index++; % show("switching to", BufList[BufList_Index]); dab_sw2buf(BufList[BufList_Index]); Scan_Direction = 0; } % all given buffers scanned else { % try again with only core pattern if (strlen(Pattern) > strlen(Core_Pattern) and strlen(Core_Pattern)) { % show(Pattern, " not found, look for ", Core_Pattern); Pattern = Core_Pattern; BufList_Index = -1; Scan_Direction = 1; } % give up else { vmessage("No more completions for \"%s\" in [%s]", Pattern, strjoin(BufList, ", ")); % insert original completion, if deleted if (Dabbrev_delete_tail) { dab_return2buf(return_mark.buffer_name); goto_user_mark(return_mark); insert(extract_element(Completion_List, 0, '\n')); } Completion_List = ""; break; } } } % save position for next completion-search, % restore scan-buffer to previous state and return to calling buffer dab_return2buf(return_mark.buffer_name); goto_user_mark(return_mark); % Insert completion % show("inserting last of ", Completion_List); insert(strchop(Completion_List, '\n', 0)[-1]); } % ----- main function -------------------------------------------------- %!%+ %\function{dabbrev} %\synopsis{Complete the current word looking for similar words} %\usage{dabbrev(String buflist=get_buflist(Dabbrev_Default_Buflist))} %\description % Takes the current stem (part of word before the cursor) % and scans the buffers given in the newline-delimited String buflist % for words that begin with this stem. The current word is expanded by % the non-stem part of the finding. Subsequent calls to dabbrev replace % the last completion with the next guess. % % The scan proceeds % foreach buffer in buflist % from cursor backwards to bob % from cursor forwards to eob %\example % The current buffer contains the line %#v+ % foo is better than foobar, foobase or foo %#v- % with the cursor at eol. % dabbrev completes foo with foobase. % If called again (immediately) foobase is changed to foobar % If called once again, foobase is changed to foo and a message is % given: No more completions. % %\notes % You can use any function that returns a list of buffers as argument, % make sure it is declared, e.g. with autoload("get_buflist", "dabbrev"); % %\seealso{get_buflist, Dabbrev_Default_Buflist, Dabbrev_delete_tail, Dabbrev_Look_in_Folds} %!%- public define dabbrev() %(buflist=whatbuf()) { variable type, fun, key, args = __pop_args(_NARGS); Completion_List = ""; do { % Reset static variables if (strchop(Completion_List, '\n', 0)[-1] == "") dab_reset(__push_args(args)); else % delete old completion { push_mark(); go_left(strlen(strchop(Completion_List, '\n', 0)[-1])); del_region(); } % find (next) completion dab_expand(); update_sans_update_hook(1); % force update (show insertion) % Check next keypress: (type, fun) = get_key_binding(); % show(fun, _function_name, LASTKEY); } while (andelse {type >= 0} % key bound ... {is_substr(fun, _function_name) == 1}); % ... to "dabbrev.*" % Last keypress was no call to dabbrev -> Push back the keystring buffer_keystring(LASTKEY); } jedmodes-2.5.7/filelist/0000755000175400017500000000000011307554022013414 5ustar mildegmjedmodes-2.5.7/filelist/filelist.sl0000644000175400017510000010757311307554022016274 0ustar mildemilde% filelist.sl % A special mode for file listings (ls, ls -a, locate) % -> replace/extend dired mode % % Copyright (c) 2005 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Changelog % --------- % % 0.9 * initial version (beta) % 0.9.1 (based on report by Paul Boekholt) % * added USAGE documentation (including ...find_file_hook) % * filelist_list_dir: % + directories end in "/" ("\" with DOS-like OS-es) % when listing with listdir % + If no dir argument given, ask in minibuffer % * filelist_open_file: % use filelist_list_dir, if filename is a directory, % goto line of child-dir if stepping up with ".." % * bugfixes (and maybe new bugs =:-( ) % * color syntax (DFA: mark directories) % * Mode directory % * dired-bindings (Paul Boekholt) % * works with PB-s tar_mode: a tar file is opened in tar-mode % 2003-08-18 0.9.2 * bugfix to filelist_list_dir % 2003-12-19 0.9.3 several fixes by Paul Boekholt, including % * new functions for regexp-rename, tar and grep bindings % 2004-02-19 0.9.4 * bugfix: filelist_delete_file now deletes also % (empty) directories. (PB) % 2004-07-07 1.0 if a file ends in .gz, check for another extension % 2004-10-11 1.1 bugfix in filelist_list_base_dir() % 2004-11-22 1.2 FileList_Trash_Bin now defaults to "" (delete files) % 2005-03-18 1.2.1 added definition of filelist_find_file_hook() (was in doc) % 2005-04-28 1.3 moved definition and call of filelist_find_file_hook() to % INITALIZATION block, i.e. with make_ini and home-lib % modes you will have this hook as default. % bugfix: extract_line_no gave error with filenames like % 00debian.sl. % 2005-05-13 1.3.1 filelist_open_file_with() now checks whether the file is % a directory and calls filelist_list_dir in this case. % Thus, a directory ".lyx" will not be opened as a lyx file % 2005-06-01 1.4 extract_filename() now uses whitespace as default delimiter % 2005-11-08 1.4.1 changed _implements() to implements() % 2005-11-23 1.5 added documentation for public functions and custom vars % new function filelist_open_tagged() (initiated by T. Koeckritz) % removed dependency on grep.sl (now recommandation) % 2005-11-25 1.5.1 bugfix: mark directories and cleanup again % code cleanup regarding FileList_Cleanup % 2006-02-16 1.5.2 added fit_window() to autoloads (report Mirko Rzehak) % 2006-03-13 1.5.3 USAGE docu fix % 2006-05-23 1.6 Copy and delete instead of rename if the destination is % on a different filesystem. % 2007-04-16 1.7 Changed the keybinding for (i)search from '^S' to 's' % (match the one in tokenlist and keep the original '^S') % 2007-04-18 1.7.1 * filelist_open_file() improvements % - close the calling buffer before opening new % (keeps the right order for navigate_back()) % - "smart" fit_window() for files openend from filelist % - localise `FileList_Cleanup' with blocal var % and optional argument `close' % - return to the filelist, if a buffer % opened from there is closed with close_buffer() % * filelist_open_in_otherwindow() (request by Lechee Lai) % open file, return focus to filelist % * highlight rule for directories listed with `ls -l` % * locate(): dont't close list if going to a directory % 2007-04-23 1.7.2 * filelist_view_file(): never close calling filelist % 2007-05-02 1.7.3 * documentation update % 2007-05-25 1.7.4 * bugfix in filelist_open_file(): went to wrong buffer if % file with same basename already open % 2007-10-01 1.7.5 * optional extensions with #if ( ) % 2007-10-04 1.7.6 * no DFA highlight in UTF-8 mode (it's broken) % 2007-10-23 1.7.7 * no DFA highlight caching % 2008-01-21 1.7.8 * fix stack leftovers in filelist_open_file() % * add Jörg Sommer's fix for DFA highlight under UTF-8 % 2008-05-05 1.7.9 * filelist_list_dir(): do not sort empty array % * filelist_open_with() bugfix: do not set a default when asking % for cmd to open, as this prevents opening in Jed. % * separate function filelist->get_default_cmd(String filename) % 2008-06-18 1.7.10 use call_function() instead of runhooks() % 2008-12-16 1.8 * use `trash` cli for deleting (if available and set) % 2009-10-05 1.8.1 * bugfix: pass name of calling buffer to _open_file() % as it may be already closed. % 2009-12-08 1.8.1 * adapt to new require() syntax in Jed 0.99.19 % TODO % ---- % * write a trash.sl mode (based on the `trash` Python utility % and the FreeDesktop.org Trash Specification e.g. at % http://www.ramendik.ru/docs/trashspec.html) % % * more bindings of actions: filelist_cua_bindings % * copy from filelist to filelist ... % ^C copy : cua_copy_region und copy_tagged (in separaten buffer) % ^X kill: yp_kill_region und kill_tagged "" "" "" % ^V filelist_insert (im filelist modus) % bzw die bindungen abfragen. % * detailed directory listing (ls -l) % * custom_variable("dir_ls_cmd", "ls -la --quoting-style=shell") % * quoting of special file names % * give error reason with errno/errno_string (if not automatically done) % * use MIME_types and mailcap (view and edit commands) for % FileList_Default_Commands % hint: `mimedb -a` returns default app for a file % `xdg-open` opens an URL with default app (opendesktop.org) % % Usage % ----- % % * Place filelist.sl and required files in your library path. % % * Use filelist_list_dir() to open a directory in the "jed-file-manager" % % * To make file finding functions list the directory contents % if called with a directory path as argument (instead of reporting an % error), copy the content of the INITALIZATION block below % (without the preprocessor # lines) into your % .jedrc (or jed.rc) (or use the "make_ini" and "home-lib" modes from % jedmodes.sf.net) # "filelist_list_dir", "filelist.sl"; "filelist_mode", "filelist.sl"; "locate", "filelist.sl"; _autoload(3); _add_completion("locate", "filelist_mode", 2); define filelist_find_file_hook(filename) { if (file_status(filename) == 2) { filelist_list_dir(filename); return 1; % abort hook chain, do not use the function actually called } return 0; % try other hooks or use opening function } append_to_hook("_jed_find_file_before_hooks", &filelist_find_file_hook); # % Requirements % ------------ % extensions from http://jedmodes.sf.net/ #if (_jed_version > 9918) require("listing", "Global"); % depends on datutils, view, bufutils require("bufutils", "Global"); require("sl_utils", "Global"); #else require("listing"); % the listing widget, depends on datutils, view, bufutils require("bufutils"); require("sl_utils"); #endif autoload("string_get_match", "strutils"); % optional extensions #if (expand_jedlib_file("filelistmsc") != "") autoload("filelist_do_rename_regexp", "filelistmsc"); #endif % Recommended for Trash-can compliance: http://www.andreafrancia.it/trash/ % An interface to the FreeDesktop.org Trash Specification (used by % KDE and XFCE) provided via the `trash` CLI % (used if found on the system PATH). % Name and namespace % ------------------ provide("filelist"); implements("filelist"); variable mode = "filelist"; % Custom Variables % ---------------- %!%+ %\variable{FileList_Action_Scope} %\synopsis{What files should filelist actions be applied to} %\usage{Int_Type FileList_Action_Scope = 1} %\description % What files should actions like move, delete, open_with be applied to % 0 current line (MC-macro "%f") % 1 tagged lines or current line, if no line is tagged. (MC-macro "%s") % 2 tagged lines (MC-macro "%t") %\seealso{filelist_mode, filelist_open_tagged, filelist_rename_tagged, filelist_delete_tagged} %!%- custom_variable("FileList_Action_Scope", 1); %!%+ %\variable{FileList_KeyBindings} %\synopsis{Keybinding set for the filelist mode} %\usage{String_Type FileList_KeyBindings = "mc"} %\description % Which set of keybindings should the filelist mode emulate? % ("mc" or "dired") %\seealso{filelist_mode} %!%- custom_variable("FileList_KeyBindings", "mc"); %!%+ %\variable{FileList_Cleanup} %\synopsis{Close a filelist when leaving?} %\usage{Int_Type FileList_Cleanup = 1} %\description % Close the directory listing when opening a file/dir from it? % 0 keep open, % 1 close when going to a new directory, % 2 always close %\notes % The global default will be overridden by a buffer local variable of % the same name. %\seealso{filelist_mode} %!%- custom_variable("FileList_Cleanup", 1); %!%+ %\variable{FileList_max_window_size} %\synopsis{} %\usage{FileList_max_window_size = 1.0} %\description % How big shall the filelist window be maximal % Integer: no. of rows, % 0 do not fit to content size % Float: screen-fraction, % 1.0 no limit %\seealso{filelist_mode, fit_window} %!%- custom_variable("FileList_max_window_size", 1.0); % my default is full screen %!%+ %\variable{FileList_Trash_Bin} %\synopsis{Trash bin for files deleted in \sfun{filelist_mode}} %\usage{String_Type FileList_Trash_Bin = "trash-cli"} %\description % Directory, where deleted files are moved to or the special string % "trash-cli" (to call the `trash` command line utility). % The empty string "" means real deleting. % \notes % Desktop users might want to set this to "trash-cli" or % "~/local/share/Trash/files" (see the Desktop Trash Can Specification % http://freedesktop.org/wiki/Standards_2ftrash_2dspec). % % A path value will be expanded with \sfun{expand_filename}. % It is checked for existence in \sfun{filelist_delete_tagged}. %\seealso{filelist_mode, filelist_delete_tagged} %!%- custom_variable("FileList_Trash_Bin", "~/local/share/Trash/files"); % Check and expand: if (andelse{FileList_Trash_Bin == "trash-cli"} {search_path_for_file(getenv("PATH"), "trash", ':') == NULL}) % trash CLI not available, try Trash dir: FileList_Trash_Bin = "~/.local/share/Trash/files"; if (wherefirst(FileList_Trash_Bin == ["", "trash-cli"]) == NULL) FileList_Trash_Bin = expand_filename(FileList_Trash_Bin); % --- Static Variables ---------------------------------------------------- % Add to/Change in the filelist_mode_hook % Default values for command opening a file with a certain extension % The command is called via system(command + file + "&") static variable FileList_Default_Commands = Assoc_Type[String_Type, ""]; % under xjed and jed in xterm use X programs if (getenv("DISPLAY") != NULL) % assume X-Windows running { FileList_Default_Commands[".dia"] = "dia"; FileList_Default_Commands[".doc"] = "abiword"; FileList_Default_Commands[".dvi"] = "xdvi"; FileList_Default_Commands[".dvi.gz"] = "xdvi"; FileList_Default_Commands[".eps"] = "gv"; FileList_Default_Commands[".gnumeric"] = "gnumeric"; FileList_Default_Commands[".gif"] = "display"; % FileList_Default_Commands[".gnuplot"] = "gnuplot -persist"; FileList_Default_Commands[".html"] = "firefox"; FileList_Default_Commands[".xhtml"] = "firefox"; FileList_Default_Commands[".htm"] = "firefox"; FileList_Default_Commands[".ico"] = "display"; FileList_Default_Commands[".jpg"] = "display"; FileList_Default_Commands[".jpeg"] = "display"; FileList_Default_Commands[".lyx"] = "lyx-remote"; FileList_Default_Commands[".odt"] = "ooffice"; FileList_Default_Commands[".png"] = "display"; FileList_Default_Commands[".pdf"] = "xpdf"; FileList_Default_Commands[".pdf.gz"] = "zxpdf"; FileList_Default_Commands[".ps"] = "gv"; FileList_Default_Commands[".ps.gz"] = "gv"; FileList_Default_Commands[".sk"] = "sketch"; FileList_Default_Commands[".svg"] = "inkscape"; FileList_Default_Commands[".xpm"] = "display"; } static variable listing = "listing"; static variable FileListBuffer = "*file-listing*"; static variable LAST_LOCATE = ""; static variable Dir_Sep = path_concat("a", "")[[1:]]; % path separator % ------ Function definitions ------------------------------------------- public define filelist_mode(); % forward definition % truncate a string to the n last characters (prepending "..." if n >= 4) static define strtail(str, n) { if (strlen(str) <= n) return str; if (n >= 4) return "..." + str[[-(n-3):]]; return str[[-n:]]; } % Extract the filename out of a string (with position given as blocal-var) % Str = extract_filename(Str line) static define extract_filename(line) { % some listings refer to only one file, omitting it in the list variable filename = get_blocal("filename", ""); !if (strlen(filename)) { variable position = get_blocal("filename_position", 0); variable del = get_blocal("delimiter"); if (del == NULL) % use any whitespace filename = strtok(line)[position]; else filename = extract_element(line, position, del); } % remove trailing path-separator return strtrim_end(filename, Dir_Sep); } % Return array of tagged filenames static define get_tagged_files() % (scope, untag) { variable args = __pop_args(_NARGS); variable lines = listing_list_tags(__push_args(args)); return array_map(String_Type, &extract_filename, lines); } % Return the filenames of the tagged lines as a space separated string static define list_tagged_files() % (scope, untag) { variable args = __pop_args(_NARGS); return strjoin(get_tagged_files(__push_args(args)), " "); } % Extract the line number out of a string (with position given as blocal-var) static define extract_line_no(str) { variable np = get_blocal("line_no_position", -1); variable nr_str = extract_element(str, np, get_blocal("delimiter", ' ')); if (nr_str == NULL) return 0; ERROR_BLOCK { _clear_error(); return 0; } return integer(nr_str); } % Move file/files static define filelist_rename_file(line, dest) { variable result, file = extract_filename(line); file = expand_filename(file); if (file_status(dest) == 2) % directory dest = path_concat(dest, path_basename(file)); % vshow("moving %s to %s", file, dest); if (andelse{file_status(dest) > 0} {listing->get_confirmation(sprintf("'%s' exists, overwrite", strtail(dest, 30))) != 1}) return 0; result = rename_file(file, dest); if (result == 0) % success return 2; % if dest is on a different filesystem, copy and delete % show("rename_file failed, try copy and delete", errno_string (errno)); result = copy_file(file, dest); % -1 -> failure if (result != 0) verror ("copy '%s' to '%s' failed: %s", strtail(file, 10), strtail(dest, 20), errno_string (errno)); result = delete_file(file); % 0 -> failure if (result != 0) return 2; if (get_y_or_n(sprintf("Delete %s failed (%s), remove copy? ", file, errno_string(errno))) == 1) result = delete_file(dest); % verror ("cannot delete '%s': %s", strtail(file, 10), errno_string (errno)); return 1; } %!%+ %\function{filelist_rename_tagged} %\synopsis{Rename/Move tagged files} %\usage{filelist_rename_tagged()} %\description % Move/Rename current or tagged files. % Ask in the minibuffer for the destination %\seealso{filelist_mode, FileList_Action_Scope} %!%- public define filelist_rename_tagged() { () = chdir(buffer_dirname()); variable dest = read_with_completion("Move/Rename file(s) to:", "", "", 'f'); listing_map(FileList_Action_Scope, &filelist_rename_file, dest); help_message(); } % Copy file/files static define filelist_copy_file(line, dest) { variable result, file = extract_filename(line); if (file_status(dest) == 2) % directory dest = path_concat(dest, path_basename(file)); if (andelse{file_status(dest) > 0} {listing->get_confirmation(sprintf("'%s' exists, overwrite", strtail(dest, 30))) != 1}) return 0; % show("copying", file, "to", dest); result = copy_file(extract_filename(line), dest); if(result == 0) % success return 1; if (get_y_or_n(sprintf("Copy failed %s, continue? ", errno_string(errno))) != 1) verror("copy failed: %s", errno_string(errno)); return 0; } %!%+ %\function{filelist_copy_tagged} %\synopsis{Copy tagged files} %\usage{filelist_copy_tagged()} %\description % Copy current or tagged files. % Ask in the minibuffer for the destination %\seealso{filelist_mode, FileList_Action_Scope} %!%- public define filelist_copy_tagged() { () = chdir(buffer_dirname()); variable dest = read_with_completion("Copy file(s) to:", "", "", 'f'); listing_map(FileList_Action_Scope, &filelist_copy_file, dest); help_message(); } %!%+ %\function{filelist_make_directory} %\synopsis{Create a new directory} %\usage{ filelist_make_directory()} %\description % Create a new directory. % Ask the user for the name. %\seealso{filelist_mode} %!%- public define filelist_make_directory() { () = chdir(buffer_dirname()); variable dest = read_with_completion("Create the directory:", "", "", 'f'); if (mkdir(dest, 0777)) verror ("mkdir failed: %s", errno_string (errno)); help_message(); } % Delete file whose path is given on `line' % % Depending on the value of FileList_Trash_Bin, the file or dir is either % a) put to the trash bin via `trash` % b) copied to the trash folder % c) deleted immediately % The user is asked for confirmation first. static define filelist_delete_file(line) { variable file = extract_filename(line); if (listing->get_confirmation("Delete " + file) != 1) return 0; % a) use the `trash` cli: if (FileList_Trash_Bin == "trash-cli") { if (system("trash " + file) == 0) % success return 2; % (deleted) } % b) copy to Trash Bin: else if (strlen(FileList_Trash_Bin)) { try { return filelist_rename_file(line, FileList_Trash_Bin); } catch RunTimeError: { % Check Trash Bin directory for existence and offer re-setting if (file_status(FileList_Trash_Bin)!=2) FileList_Trash_Bin = read_with_completion("Trash Bin (leave empty for real delete)", "", FileList_Trash_Bin, 'f'); } } % c) delete immediately % delete directory else if (file_status(file) == 2) { if (rmdir(file) == 0) % successfully removed dir return 2; % delete normal file if (delete_file(file) != 0) % success return 2; if (get_y_or_n(sprintf("Delete failed %s, continue? ", errno_string(errno))) != 1) verror("Delete failed %s", errno_string(errno)); } return 1; % (not deleted) } %!%+ %\function{filelist_delete_tagged} %\synopsis{Rename/Move tagged files} %\usage{filelist_delete_tagged()} %\description % Delete (or move to Trash_Bin) current or tagged files. %\notes % If \var{FileList_Trash_Bin} is "" (default), directories can only be % deleted if they are empty. %\seealso{filelist_mode, filelist_rename_tagged, FileList_Action_Scope} %!%- public define filelist_delete_tagged() { () = chdir(buffer_dirname()); listing_map(FileList_Action_Scope, &filelist_delete_file); help_message(); } %!%+ %\function{filelist_do_tar} %\synopsis{Make a tgz of the tagged files} %\usage{filelist_do_tar()} %\description % Pack the tagged files in a gzipped tar archive. %\notes % Needs the `tar` system command. %\seealso{filelist_mode} %!%- public define filelist_do_tar() { variable tar = read_with_completion("Name of tgz to create", "", "", 'f'); switch (file_status(tar)) {case 2: error ("this is a directory");} {case 1: !if (get_y_or_n("file exists, overwrite")) return;} {case 0: ;} {error("can't stat this");} shell_perform_cmd(strcat("tar -czvf ", tar, " ", list_tagged_files()), 0); } %!%+ %\function{filelist_reread} %\synopsis{Re-read the current file listing} %\usage{filelist_reread()} %\description % Re run the function that generated the current file list to % update the view. %\seealso{filelist_mode} %!%- public define filelist_reread() { variable line = what_line(); () = run_function(push_array(get_blocal("generating_function"))); goto_line(line); } %!%+ %\function{filelist_list_dir} %\synopsis{List all files in \var{dir}} %\usage{filelist_list_dir([dir], ls_cmd="listdir")} %\description % List all files in the current (or given) directory and set the buffer to % \sfun{filelist_mode}. %\notes % With the filelist_find_file_hook() as proposed in the INITIALIZATION % block of filelist.sl, Jed will open directories as a file listing instead % of issuing an error. %\seealso{filelist_mode, FileList_Cleanup, listdir} %!%- public define filelist_list_dir() % ([dir], ls_cmd="listdir") { % get arguments variable dir, ls_cmd; (dir, ls_cmd) = push_defaults( , "listdir", _NARGS); if (dir == NULL) dir = read_with_completion("Open directory:", "", "", 'f'); % make sure there is a trailing directory separator dir = path_concat(dir, ""); % expand relative paths dir = expand_filename(path_concat(buffer_dirname(), dir)); if (file_status(dir) != 2) error(dir + " is not a directory"); % create (or reuse) the buffer popup_buffer(dir, FileList_max_window_size); setbuf_info("", dir, dir, 0); erase_buffer(); % show(ls_cmd); if (ls_cmd == "listdir") { variable files = listdir(dir); if (length(files)) { files = files[array_sort(files)]; % quote spaces and stars % files = array_map(String_Type, &str_quote_string, files, "* ", '\\'); } insert(strjoin(["..", files], "\n")); do if (file_status(dir + line_as_string()) == 2) insert(Dir_Sep); while (up_1()); } else { shell_perform_cmd(ls_cmd,1); % write_table([[8,[0:7],[9:length($1)-1]],*]) } bob; define_blocal_var("generating_function", [_function_name, dir]); fit_window(get_blocal("is_popup", 0)); filelist_mode(); } %!%+ %\function{filelist_list_base_dir} %\synopsis{List the directory of the current file} %\usage{filelist_list_base_dir()} %\description % List the base directory of the current file. This is usefull e.g. in % \sfun{locate} or \sfun{grep} listings, where the files come from different % directories. %\seealso{filelist_mode} %!%- public define filelist_list_base_dir() { variable filename = extract_filename(line_as_string()); filelist_list_dir(path_dirname(filename)); } % return to the filelist, if a buffer opened from there is closed with % close_buffer() static define filelist_close_buffer_hook(buf) { !if (buffer_visible(buf)) return; variable calling_buf = get_blocal("calling_buf", ""); if (bufferp(calling_buf)) { go2buf(calling_buf); fit_window(get_blocal("is_popup", 0)); % resize popup window } } % open file|directory|tar-archive, goto line number % return success private define _open_file(filename, line_no, calling_buf) { variable newbuf, fit = (get_blocal("is_popup", 0) != 0); try { % directory if (file_status(filename) == 2) { filelist_list_dir(filename); % set point to the previous directory (when going up) variable last_dir = path_basename(strtrim_end(calling_buf, Dir_Sep)); () = fsearch(last_dir + Dir_Sep); } % tar archive #ifexists check_for_tar else if (check_for_tar(filename)) tar(filename, 0); % open in tar-mode, read-write #endif % normal file else { % open file in second window () = find_file(filename); newbuf = whatbuf(); % save return data in blocal variables define_blocal_var("close_buffer_hook", &filelist_close_buffer_hook); define_blocal_var("calling_buf", calling_buf); % fit window (eventually closing the filelists window) if (fit) { fit_window(FileList_max_window_size); % Shrink the filelist buffer, if there is excess space if (nwindows > 1) { pop2buf(calling_buf); fit_window(window_info('r')); pop2buf(newbuf); } } } if (line_no) % line_no == 0 means don't goto line goto_line(line_no); return 1; } catch AnyError: return 0; } %!%+ %\function{filelist_open_file} %\synopsis{Open current file} %\usage{filelist_open_file(scope=0)} %\description % Open the file (or directory) in the current line in a buffer. % If scope != 0, open tagged files (see \var{FileList_Action_Scope}) %\notes % If the filename is not the first whitespace delimited token in the line, % the function generating the list must set the blocal variables % "filename_position" (counting from 0) and % "delimiter" (Char_Type, default == NULL, meaning 'whitespace') %\seealso{filelist_mode, FileList_Cleanup} %!%- public define filelist_open_file() % (scope=0, close=FileList_Cleanup) { variable scope, close; (scope, close) = push_defaults(0, get_blocal("FileList_Cleanup", FileList_Cleanup), _NARGS); variable buf = whatbuf(), bufdir = buffer_dirname(); variable lines = listing_list_tags(scope, 1); % get and untag variable filenames = array_map(String_Type, &extract_filename, lines); filenames = array_map(String_Type, &path_concat, bufdir, filenames); filenames = array_map(String_Type, &expand_filename, filenames); variable file_states = array_map(Int_Type, &file_status, filenames); variable line_numbers = array_map(Int_Type, &extract_line_no, lines); % close the calling buffer (see also FileList_Cleanup) % (Do this before opening the new one to keep Navigation_List in % correct order). switch (close) % case 0: do not close calling buffer { case 1: if (wherefirst(file_states == 2) != NULL) close_buffer(buf); } { case 2: close_buffer(buf);} () = array_map(Int_Type, &_open_file, filenames, line_numbers, buf); } public define filelist_open_in_otherwindow() { % open file on current line, don't close current buffer filelist_open_file(0, 0); % go back to calling buffer, splitting window in 2 popup_buffer(get_blocal_var("calling_buf")); } %!%+ %\function{filelist_open_tagged} %\synopsis{Open all tagged files in jed} %\usage{filelist_open_tagged()} %\description % This function calls \sfun{filelist_open_file} with % the \var{FileList_Action_Scope} argument to open % the set of tagged files (or the current) % in JED. %\seealso{filelist_mode} %!%- public define filelist_open_tagged() { filelist_open_file(FileList_Action_Scope); } %!%+ %\function{filelist_view_file} %\synopsis{Open the file in view mode} %\usage{ filelist_view_file()} %\description % Open the file in \sfun{view_mode} (readonly). %\seealso{filelist_mode, view_mode} %!%- public define filelist_view_file() { filelist_open_file(FileList_Action_Scope, 0); set_readonly(1); view_mode(); } static define get_default_cmd(filename) { variable extension = path_extname(filename); % double extensions: if (extension == ".gz") % some programs can handle gzipped files extension = path_extname(path_sans_extname(filename)) + extension; return FileList_Default_Commands[extension]; } %!%+ %\function{filelist_open_file_with} %\synopsis{Open the current file with a shell command} %\usage{filelist_open_file_with(ask = 1)} %\description % Open the file with a shell command in a background process. % The command is taken from \var{FileList_Default_Commands} or asked % for in the minibuffer. % If \var{ask} = 0, use default without asking. %\seealso{filelist_mode, filelist_open_file, system, run_program} %!%- public define filelist_open_file_with() % (ask=1) { variable ask = push_defaults(1, _NARGS); variable filename = extract_filename(listing_list_tags(0)[0]); variable cmd = get_default_cmd(filename); if (ask) cmd = read_mini(sprintf("Open %s with (Leave empty to open in jed):", filename), "", cmd); if (cmd == "") return filelist_open_file(); () = chdir(buffer_dirname()); if (getenv("DISPLAY") != NULL) % assume X-Windows running () = system(cmd + " " + filename + " &"); else () = run_program(cmd + " " + filename); } #ifexists ffap public define ffap_with() % (ask=1) { variable ask = push_defaults(1, _NARGS); % Simple scheme to separate a path or URL from context % will not work for filenames|URLs with spaces or "strange" characters. variable filename = get_word("-a-zA-z_.0-9~/+:?=&\\"); filename = strtrim_end(filename, ".+:?"); if (filename == "") return; variable cmd = get_default_cmd(filename); if (ask) cmd = read_mini(sprintf("Open %s with (Leave empty to open in jed):", filename), "", cmd); if (cmd == "") return ffap(); () = chdir(buffer_dirname()); if (getenv("DISPLAY") != NULL) % assume X-Windows running () = system(cmd + " " + filename + " &"); else () = run_program(cmd + " " + filename); } #endif #ifexists grep %!%+ %\function{filelist_do_grep} %\synopsis{Grep for a string in tagged files} %\usage{ filelist_do_grep()} %\description % Grep for a string in the tagged files. % Prompts for the pattern in the minibuffer. %\notes % This function is only available, when \sfun{grep} is defined at % the time of evaluation or preparsing of filelist.sl %\seealso{grep, filelist_mode} %!%- public define filelist_do_grep() { grep( , list_tagged_files(FileList_Action_Scope, 1)); } #endif % --- The filelist mode ----------------------------------------- #ifdef HAS_DFA_SYNTAX create_syntax_table(mode); % set_syntax_flags (mode, 0); % define_syntax ("-+0-9.", '0', mode); % Numbers % directories dfa_define_highlight_rule(".*" + Dir_Sep + "$", "keyword", mode); dfa_define_highlight_rule("^d[\\-r][\\-w]x.*$", "keyword", mode); % with "ls -l" % backup copies dfa_define_highlight_rule(".*~$", "comment", mode); % Bugfix for high-bit chars in UTF-8 % render every char outside the range of printable ASCII chars as normal dfa_define_highlight_rule("[^ -~]+", "normal", mode); dfa_build_highlight_table(mode); enable_dfa_syntax_for_mode(mode); #endif static define mc_bindings() { definekey("menu_select_menu(\"Global.M&ode\")", Key_F2, mode); % Menu definekey("filelist_view_file", Key_F3, mode); % View definekey("filelist_open_file", Key_F4, mode); % Edit definekey("filelist_copy_tagged", Key_F5, mode); % Copy definekey("filelist_rename_tagged", Key_F6, mode); % Ren/Move definekey("filelist_make_directory", Key_F7, mode); % Mkdir definekey("filelist_delete_tagged", Key_F8, mode); % Delete definekey("select_menubar", Key_F9, mode); % PullDn definekey("close_buffer", Key_F10, mode); % Quit definekey("filelist_open_file_with(0)", "^M", mode); % Return definekey("filelist_open_in_otherwindow", "o", mode); % show("call set_help_message", "1Help...", mode); set_help_message( "1Help 2Menu 3View 4Edit 5Copy 6RenMov 7Mkdir 8Delete 9PullDn 10Quit", mode); } static define dired_bindings() { definekey("filelist_copy_tagged", "C", mode); % Copy definekey("filelist_delete_tagged", "x", mode); % Delete definekey("filelist_make_directory", "+", mode); % Mkdir definekey("filelist_open_file", "e", mode); % Edit definekey("filelist_open_file", "^M", mode); % Return definekey("filelist_open_file_with(0)", "X", mode); % shell cmd definekey("filelist_rename_tagged", "R", mode); % Ren/Move definekey("filelist_do_rename_regexp", "%r", mode); % rename regexp definekey("filelist_reread", "g", mode); % reread definekey("filelist_view_file", "v", mode); % View definekey("listing->tag_matching(1)", "%d", mode); % tag regexp definekey("filelist_open_in_otherwindow", " ", mode); definekey("listing->tag(0); go_up_1", _Backspace_Key, mode); set_help_message( "Enter:Open t/Ins:Tag +/-:Tag-Matching s:search ^R:Reread q:Quit", mode); } % Create the keymap !if (keymap_p(mode)) { copy_keymap(mode, listing); undefinekey("^R", mode); definekey ("filelist_reread", "^R", mode); call_function(FileList_KeyBindings + "_bindings"); } % --- the mode dependend menu static define filelist_menu(menu) { % Re-use the listing mode menu listing->listing_menu(menu); % Insert extensions before the "Edit Listing" entry menu_insert_separator("&Edit Listing", menu); menu_insert_item("&Edit Listing", menu, "&Open", "filelist_open_file"); menu_insert_item("&Edit Listing", menu, "Open &With", "filelist_open_file_with(1)"); menu_insert_item("&Edit Listing", menu, "Open in other window", "filelist_open_in_otherwindow"); menu_insert_item("&Edit Listing", menu, "&View (read-only)", "filelist_view_file"); menu_insert_item("&Edit Listing", menu, "Open &Directory", "filelist_list_base_dir"); menu_insert_item("&Edit Listing", menu, "Open Tagged &Files", "filelist_open_tagged"); menu_insert_separator("&Edit Listing", menu); menu_insert_item("&Edit Listing", menu, "&Copy", "filelist_copy_tagged"); menu_insert_item("&Edit Listing", menu, "Rename/&Move", "filelist_rename_tagged"); menu_insert_item("&Edit Listing", menu, "&Rename/ regexp", "filelist_do_rename_regexp"); menu_insert_item("&Edit Listing", menu, "Make Di&rectory", "filelist_make_directory"); menu_insert_item("&Edit Listing", menu, "Delete", "filelist_delete_tagged"); menu_insert_separator("&Edit Listing", menu); menu_insert_item("&Edit Listing", menu, "&Grep", "filelist_do_grep"); menu_insert_item("&Edit Listing", menu, "Tar", "filelist_do_tar"); menu_insert_separator("&Edit Listing", menu); } static define filelist_mouse_2click_hook (line, col, but, shift) { filelist_open_file(); return 1; % stay in window } %!%+ %\function{filelist_mode} %\synopsis{Interactive mode for file listings} %\usage{filelist_mode()} %\description % This mode transforms JED into a file manager (somewhat similar to % the Midnight commander, MC). It can be used as a \sfun{dired} replacement % and gives (IMHO) a superiour look and feel. It works for directory listings % as well as the result of \sfun{locate}, \sfun{grep} or \sfun{find} actions. % Files can be listed, tagged, copied, moved, deleted, viewed, and opened % with ease. %\seealso{filelist_list_dir, filelist_open_tagged} %\seealso{FileList_KeyBindings, FileList_Action_Scope, FileList_max_window_size} %!%- public define filelist_mode() { listing_mode(); set_mode(mode, 0); use_syntax_table(mode); use_keymap(mode); mode_set_mode_info(mode, "init_mode_menu", &filelist_menu); set_buffer_hook("mouse_2click", &filelist_mouse_2click_hook); run_mode_hooks("filelist_mode_hook"); help_message(); } % --------------------------------------------------------------------------- %!%+ %\function{locate} %\synopsis{Search for a file with the `locate` command} %\usage{ locate(what=)} %\description % The `locate` command performs a fast file lookup using a database. % This function is a backend to `locate` that presents the result % in a filelist buffer for easy browsing. %\seealso{filelist_mode, grep} %!%- public define locate() % (what=) { % read pattern from minibuffer if not given as optional argument variable what = push_defaults("", _NARGS); if (what == "") { what = read_mini("Locate: ", "", LAST_LOCATE); !if ( strlen(what) ) return; LAST_LOCATE = what; } popup_buffer("*locate*", FileList_max_window_size); set_readonly(0); erase_buffer(); set_prefix_argument(1); % insert result in current buffer do_shell_cmd("locate " + what); if (bobp and eobp) { set_buffer_modified_flag(0); delbuf(whatbuf); return message("Locate: No results"); } fit_window(get_blocal("is_popup", 0)); filelist_mode(); set_status_line("locate:" + what + " (%p)", 0); define_blocal_var("generating_function", [_function_name, what]); define_blocal_var("FileList_Cleanup", 0); bob(); } jedmodes-2.5.7/po_mode/0000755000175400017500000000000011137571337013234 5ustar mildegmjedmodes-2.5.7/po_mode/po_mode.hlp0000644000175400017500000004737510334413251015367 0ustar mildegm ***KEYBINDINGS FOR PO_MODE*** NAVIGATION: MODIFICATION: b - scroll up one page _ - undo f - next fuzzy TAB - edit entry F - previous fuzzy ENTER - edit entry @ - show current entry no. w - copy msgstr g - go to entry number y - insert msgstr l - toggle limited view Backspace - flag entry fuzzy or n - next entry obsolete entry if already o - next obsolete fuzzy O - previous obsolete ESC-Backspace - remove fuzzy flag p - previous entry ctrl-? F - flag all entries fuzzy t - next translated ESC-Enter - copy msgid to msgstr T - previous translated DEL - delete obsolete entry u - next untranslated E - edit entire file U - previous untranslated H - replace headers ESC-# - next translator comment K - cut msgstr . - top justify entry R - replace in msgstrs # - edit translator comment ctrl-? # - remove translator comment COMPENDIUMS: B - add buffer to comp. MISC: I - init. w/compendium(s) + - make current translation c - compile *.po -> *.mo preferred in compendium C - decompile *.mo -> *.po * - get fuzzily matching G - grep in source dir translation from comp. ctrl-? s - spell check po-file ctrl-? d - add dir to compendium M - mail team or robot s - view source reference S - set source path WORDLISTS: V - validate file ctrl-? E - change encoding d - look up word in ctrl-? u - update po-file wordlist(s) \ - toggle wrapping D - look up all words in = - po statistics wordlists(s) ? - show this help file ctrl-d - look up definitions for a word in all DICT dictionaries ***KEYBINDINGS FOR PO_EDIT_MODE*** TAB - finish editing entry ctrl-? ctrl-c - finish editing entry ctrl-? ctrl-k - discard changes ESC + - increase msgstr window ESC - - decrease msgstr window NOTE: The question mark in the ctrl-? sequence refers to the binding for the letter in the reserved key prefix which varies with emulations. For Emacs and Jed emulations it is 'c' so you can exchange ctrl-? with ctrl-c in the key bindings above. ***MOUSE ACTIONS IN PO_MODE*** - left button double click: look up translation for word at mouse point in wordlist. May only work in xjed. 2. Optional Helper Programs: - spellutils (http://home.worldonline.dk/byrial/spellutils/) usually available as a rpm/deb package. - aspell or ispell - the gettext package (msgfmt, msgcat, msgmerge, msgconv, etc.) - grep.sl (necessary for grepping in source directory) available from http://jedmodes.sourceforge.net/mode/grep/ - the dict client and server programs plus one or more dictionaries - the file(1) utility 3. Notes on Customization: You should copy/paste the following block of variables into your .jedrc and edit their values to match your own settings. Here they are exemplified with mine: ---- copy/paste begin ----- %% User variables specific for po_mode variable Translator = "Morten Bo Johansen ", Language = "Danish", Team_Email = "", Charset = "iso-8859-1", Nplurals = "2", Plural = "(n != 1)", Spell_Prg = "aspell", Spell_Dict = "dansk", Compendium = "/home/mojo/l10n/compendium_pomode", Compendium_Gettext = "/home/mojo/l10n/compendium_gettext", Custom_Wordlist = "/home/mojo/l10n/wordlist_pomode", Dict_Dictionary = "fd-eng-swe", Revise_Date = 1, Gettext_Use_Fuzzy = 0, Use_Compendium = 3, Use_Wordlist = 3, Dict_Minimum_Wordsize = 4; %% Other useful variables variable GrepCommand = "grep -H -n -r -i", Dabbrev_Default_Buflist = 1, Dabbrev_Look_in_Folds = 1; ---- copy/paste end ----- Explanation of the user variables: - Translator: full name and email address of you, the translator. - Language: your language - use English adjective, e.g. "German". - Team_Email: email address of your language team. - Charset: the default character set encoding in the header of the po-file also used as encoding in the gettext compendium. - Nplurals: if po-file has plural forms: how many plural forms does your language have? See /usr/share/doc/gettext-doc/gettext_10.html#SEC1. - Plural: See /usr/share/doc/gettext-doc/gettext_10.html#SEC1. - Spell_Prg: program to use for spell checking, use "ispell" or "aspell". - Spell_Dict: language dictionary for ispell/aspell, (e.g. "deutsch" for German). - Compendium: path to native compendium file. - Compendium_Gettext: path to gettext compendium file, created with msgcat. - Custom_Wordlist: name and path of custom wordlist. - Dict_Dictionary: you must set the dict dictionary to use, you can get a listing of installed dictionaries with the shell command "dict -D". - Revise_Date: set revision date when saving: 0 = ask, 1 = always. - Gettext_Use_Fuzzy: if fuzzy matching is used with gettext compendiums. - Use_Compendium: what compendium(s) to use: 1 = native po_mode compendium 2 = gettext compendium 3 = both - Use_Wordlist: what wordlist(s) to use: 1 = custom wordlist 2 = dict freedict translation dictionary 3 = both - Dict_Minimum_Wordsize: do not query dictd server for words less than n characters. 4. Mode Hooks: There are two mode_hooks that may be used to control some settings relating to the po_mode and po_edit_mode buffers respectively. Thus in your .jedrc you might insert e.g.: define po_mode_hook () { use_dfa_syntax (1); } define po_edit_mode_hook () { ispell_change_dictionary ("deutsch"); flyspell_mode; } The former enables DFA syntax highlighting that conveniently draws attention to important things like blank space at beginning/end of lines and newline literals. 5. Notes On Editing (po_edit mode): To a large extent this mode is emulating the Emacs po-mode, and as you may see from the key bindings above, the library actually contains two modes: when you read the po-file into the editor, you are in "po_mode" and the file is read-only. When you edit an entry, a new buffer is opened and you enter "po_edit_mode" where you are actually filling in the translation or editing an existing translation. The entries are either single-line or multi-line strings. Multi-line strings are always terminated at the point at which they are to be wrapped by the C-like newline escape character "\n". If there is one or more of these escape sequences in the msgid, it is a multi-line string. Thus the two types of strings may look like this: Example single-line string: msgid "" "You may also specify modifaction to the actions which will be taken. To do " "so, type an action character followed by one or more package names (or " "patterns). The action will be applied to all the packages that you list. " "The following actions are available:" Example multi-line string: msgid "" "Usage: %s [OPTION]... [FILE]...\n" "\n" "Convert FILE(s) or standard input to PostScript.\n" "\n" "Mandatory arguments to long options are mandatory for short options too.\n" "Long options marked with * require a yes/no argument, corresponding\n" "short options stand for `yes'.\n" For single-line strings, just type along with the line being wrapped at column 78 and with a single space being inserted automatically at the end of the line, so you can follow what you're typing in. Do not use the enter-key here at all (it is disabled actually). For multi-line strings always use the enter-key to break the line at the point where you want the newline literal "\n" to be inserted. Do not insert trailing newline literals or spaces. They are inserted automatically when you leave the po_edit buffer. For multi-line strings a hyphen (-) is inserted into the end of the po_edit buffer to draw your attention to where this is. To repeat: In general you do not need to worry about anything relating to the formatting of the message string, it is all taken care of automatically which means that newline literals "\n" are inserted in the right places, embedded double quotes are escaped and word-delimiting whitespace at the end of wrapped lines is inserted. 6. Spell Checking: Keeping your work free from misspellings is an essential part of the work of a translator, and if you installed spellutils as mentioned above, you can spell check the entire po-file, isolating the msgstrs from within po_mode (typing ctrl-c s). Alternatively there is a cool mode called flyspell.sl available from http://jedmodes.sourceforge.net/ that will highlight misspelled words as you go ("on the fly"). Installing this mode and translating into e.g. German, you can put these two lines into your po_edit_mode_hook: ispell_change_dictionary ("deutsch"); flyspell_mode; 7. Compendiums: Compendiums are files with translatable strings and their accompanying translations. They are used as a reference whence to fetch translations and merge them into the current po-buffer. Gettext compendiums are in the gettext po-file format and the msgmerge program from the gettext utilities is being used to fetch translations from the compendium and merge them with a po-file. Msgmerge's matching of msgids can be exact and/or fuzzy. I think the fuzzy matching is too far off the mark so as to be really usable and it is also slow. Therefore I have added a native compendium which is in a different format. It is reasonably fast both to update and to fetch translations from and has a sort of fuzzy matching which leaves out punctuation, special characters, whitespace and newline literals in the comparison, in addition to being case-insensitive. So I should recommend the following settings in your .jedrc variable Gettext_Use_Fuzzy = 0; variable Use_Compendium = 3; The first ensures that only exact matching is used when getting translations from the gettext compendium, and the second ensures that both the gettext and the native compendiums are updated as well as translations being fetched from both. Entries filled out with translations fetched from the native compendium are flagged fuzzy. Thus, translations for all exactly matching msgids found in the gettext compendium are entered, in addition to all fuzzily matching msgids found in the native compendium. The exact matches will always take precedence. Menu items are available to update compendiums with the contents of the current buffer or to update the compendium with a directory of po-files. In the latter case only files with the ".po" extension will be added and an integrity check will be done on each file before it is added to the list of files to go into the compendium. When updating the Gettext compendium, you will be asked if you want to overwrite matching entries in the compendium. Answering yes here will let translations in the updating file(s) for msgids matching those in the compendium be overwritten. Conversely, answering no will keep translations in the compendium for matching msgids intact. If you feel that a translation fetched from the compendium is annoying, you can either edit the compendium manually or you can just modify the translation to your liking and then hit '+' in po-mode, then the new translation will overwrite the old one in the compendium and be used for the future. You can also update the compendium as per above by letting the entries be overwritten when you have finished editing the file. Fuzzily matching translations from the gettext compendium for a single entry may be fetched by typing "*". The matching is rather crude; it only matches the 20 first characters in the msgid as a substring in msgids in the compendium and stops at the first match. 8. Wordlists: Translations for words or phrases can be looked up either in a custom wordlist or in a freedict translation dictionary. Lookups in the two types of wordlists can be combined. You make the lookup by double clicking on a word with the mouse or by typing 'd' on a word. Double clicking may only work in xjed. If you have marked a region, a lookup for the phrase in that region will be performed. If a translation is found, you will be presented with a default translation. If you hit you will see a list of possible translations in case there is more than one. You can cycle between them with . Hitting will then insert the translation into the msgstr or into the po_edit buffer if you are in po_edit mode. Ctrl-g cancels. 8.1. Format of the Custom Wordlist: The custom wordlist assumes the following line format: word_to_translate: translation_1, translation_2, translation_3, [...] i.e. the word to translate followed by a colon followed by one or more spaces and/or tabs followed by a comma-separated list of translations. Entries might look like this in a wordlist with some Danish translations: memory: hukommelse, internt lager memory exhausted: hukommelse opbrugt memory leak: hukommelseslk The custom wordlist is chiefly meant to be a compilation of translations of technical or special words/terms that you or your language team maintain yourself. 8.2. Freedict Translation Dictionaries: The dict lookup function is designed to work with the freedict translation dictionaries. Currently (as of October 2005) the following English- dictionaries exist - with the Debian package names to the left: dict-freedict-eng-deu - Dict package for English-German dict-freedict-eng-fra - Dict package for English-French dict-freedict-eng-hun - Dict package for English-Hungarian dict-freedict-eng-iri - Dict package for English-Irish dict-freedict-eng-ita - Dict package for English-Italian dict-freedict-eng-lat - Dict package for English-Latin dict-freedict-eng-nld - Dict package for English-Netherlands dict-freedict-eng-por - Dict package for English-Portuguese dict-freedict-eng-rus - Dict package for English-Russian dict-freedict-eng-spa - Dict package for English-Spanish dict-freedict-eng-swe - Dict package for English-Swedish dict-freedict-eng-wel - Dict package for English-Welsh NB! At least in the Ubuntu packages, as of October 2005, the index files are not sorted correctly. If you experience that several words lack a translation where one should be, then do this (assuming that the index files are in /usr/share/dictd: # cd /usr/share/dictd # LC_ALL=C sort -t $'\t' -k1,1 -bdf freedict-eng-deu.index | \ tee freedict-eng-deu.index > /dev/null to sort e.g. the English-German freedict index file. You can combine lookups in both the custom wordlist and in a freedict dictionary. If a translation is found in both, the translation from the custom wordlist will be presented as the default. 8.3 Auto-translating From Wordlists: You can look up a translation for every word in every msgid in a po-file in a batch run by typing 'D'. The default translations for every matching word are then inserted into the msgstrs automatically. Again you can choose to use the custom wordlist, the freedict dictionaries or both. Using the freedict dictionaries will probably yield some occasionally strange results. The variable "Dict_Minimum_Wordsize" controls how many characters a word must consist of before querying the dictd server. Setting it to a reasonably high number, like e.g. 5, is probably a good idea. 8.4. Lexicographical lookup in all installed Dict dictionaries: This will pop up a buffer with all available definitions for the word at point. The function is bound to ctrl-d and comes in handy where you want an in-depth explanation of a word from e.g. the dict-gcide dictionary. 9. View Source Files or Grep in Source Files: In addition to viewing the source file(s) referenced in the current entry, you can also grep for a string in the source files and get a window with a listing of all files that contain that expression which you can then select for easy viewing: If you have highlighted a string, e.g. with the mouse, this string will be seached for, otherwise the word at point will be seached for. The highlighting must be done with Jed's mark_region function, i.e. you should see an 'm' on the status line. The function is bound to 'G'. It also comes in handy when you have an archive with other language translations of the current po-file and want to see how a tricky translation was done by others. I recommend putting this line into your .jedrc: variable GrepCommand = "grep -H -n -r -i"; for a recursive, case-insensitive search. You must get grep.sl from http://jedmodes.sourceforge.net/grep/ 10. Limit Display to Entries Containing Expression: If you are familiar with the mail user agent Mutt, you will probably have cherished its "limit" function whereby you can narrow the index of mail messages to a list containing a specified expression. A limit function is also useful in the context of editing po-files. The limit function in this mode lets you narrow the display to a list of entries containing a certain expression. Like for the grep function mentioned above the limit function also acts on either the word at point, a highlighted string or a typed in expression. The function is bound to 'l' by default (like in Mutt), and typing 'l' again in the limited view toggles off the limitation. It is of course useful, because it lets you see a uniform list of entries containing your expression, so you can e.g. easily compare translations containing this expression to see if it is translated consistently in all of them, or you can limit the display to similarly looking msgid in order to copy translations between them. 11. Gettext Functions: Various wrapper functions using the gettext utilities are included for convenience, these are: - validation: parse po-file for syntax errors with msgfmt. - compile: compile current buffer into a binary mo-file with msgfmt. - decompile: decompile a binary mo-file into a po-file with msgunfmt - wrap/unwrap: wrap/unwrap entries with msgcat. - update: update current po-buffer to a newer version with msgmerge. - convert: convert character encoding with msgconv - flag all entries fuzzy with msgattrib - replace words in message strings using msgfilter and sed. They are all available from the menu. -------- Otherwise the explanation of the keybindings above should, I hope, make it clear what functionality is available. Send comments or suggestions to Morten Bo Johansen jedmodes-2.5.7/po_mode/po_mode.sl0000644000175400017500000032435611052762423015225 0ustar mildegm%% po_mode.sl -*- mode: slang; mode: fold -*- %% %% po_mode.sl -- an Emacs-like Jed editing mode for %% portable object files (*.po) %% %% Copyright: http://www.fsf.org/copyleft/gpl.html %% Author : Morten Bo Johansen %% %% Thanks to Paul Boekholt for some general hints relating to S-Lang %% scripting. %% %% Tested with Jed 0.99.16/17 on Linux, compiled against both slang1 %% and slang2. Tested with emulations, cua, edt, emacs, ide, jed and %% wordstar. You must edit several functions to make it usable on %% non-Unix systems. %% %% Installation %% ------------ %% %% Copy this file and po_mode.hlp to a directory in your jed library path, %% e.g. /usr/share/jed/lib. For initialization, either use make_ini() %% (from jedmodes.sf.net/mode/make_ini/) or copy the content of the %% INITIALIZATION block to your .jedrc. %% %% For the rest, please refer to the po_mode.hlp file for the ins and outs %% of this mode. There is some rather important information therein, so you %% should read it ;-). If you copied it to the same place as this file, it %% should be available in po_mode by typing '?'. %% %% $Log: po_mode.sl,v $ %% Revision 1.3 2008/08/20 09:34:11 milde %% added delim arg to search_path_for_file %% %% Revision 1.2 2005/12/05 08:13:10 milde %% added block %% %% Revision 1.8 2005/11/10 09:15:25 mojo %% - A substantial (4x!) speedup in wordlist_lookup_all (), %% courtesy of Paul Boekholt. %% - Redefined some keys to avoid more of the reserved_key bindings. %% - Added function to toggle wrapping. %% %% Revision 1.7 2005/10/26 14:20:33 mojo %% - New user function: jump to any next fuzzy or untranslated entry, %% bound to space like in Emacs. %% - Much improved wordlist functions: It is now possible to look up words %% in both the custom wordlist as well as in the Freedict Translation %% Dictionaries and to combine lookups in the two. Also added function to %% prefill all msgstrs with translations from above wordlists. %% - added choice to mail file to Debian BTS. %% - Improved documentation. %% - Various bug fixes. %% %% Revision 1.6 2005/01/10 19:37:50 mojo %% - New user function: Limit display to entries matching an expression. %% - Improved validation command: The output window now contains a warning %% if there is a mismatch between charset encoding in header and the actual %% encoding of the document. Requires the file(1) utility. %% %% Revision 1.5 2005/01/02 19:06:18 mojo %% - New user function: Grep for a word/string in source directory, %% using grep.sl from Jedmodes. %% - When updating the gettext compendium, user can choose to overwrite %% translations for matching msgids. %% - Added function to add a directory of po-files to native compendium. %% - Many minor improvements and fixes. %% %% Revision 1.4 2004/11/23 21:31:37 mojo %% - Modification of plural form strings should work correctly now. %% - Simplified get_msgid_line_format (). %% - New user functions: mark_fuzzy_all and replace_in_msgstrs. %% - Redefined key for rejecting changes in po_edit buffer to avoid conflicts. %% %% Revision 1.3 2004/11/12 16:53:27 mojo %% - A fix in format_msgstr_before () wrt. to the removal of %% surrounding double quotes. %% %% Revision 1.2 2004/11/11 16:35:55 mojo %% - Time zone in revision date was wrong in many instances. %% Now use the date cmd to get it. %% %% Revision 1.1 2004/11/07 22:35:42 mojo %% - strreplace -> str_replace_all %% - small changes in mail and comependium functions %% - other minor cosmetic changes %% Thanks to Paul Boekholt for most of these. %% %% Revision 1.0 2004/11/06 16:37:30 mojo %% First public release # autoload ("po_mode", "po_mode"); add_mode_for_extension ("po", "po"); add_mode_for_extension ("po", "pot"); # %{{{ static variables static variable mode = "PO", View_Limit = 0, Wrap_Status = 1, translator_cmt_re = "^#[^.:,~]*[\n ]+", str_any_re = "^#?~? ?msg", msgid_re = "^#?~? ?msgid ", msgstr_re = "^#?~? ?msgstr ", msgid_any_re = "^#?~? ?msgid", msgstr_any_re = "^#?~? ?msgstr\\[?", msgid_plural_re = "^#?~? ?msgid_", po_edit_buf = "*Translate*", Edit_Mode = "po_edit", Translation_Status = 0, Multi_Line = 0, po_cmt_buf = "", dict_checks = 0, dict_error_msg = "", Overwrite_Compendium = 0, entry_number; %}}} %{{{ autoloads autoload ("grep", "grep"); %}}} %{{{ requirements require ("keydefs"); %}}} %{{{ customization %% Name and email address of you, the translator custom_variable ("Translator", "Full Name "); %% Your language - use adjective in English, e.g. "German", "Danish" etc. custom_variable ("Language", "My Language"); %% Email address of your language team custom_variable ("Team_Email", ""); % Default character encoding of po-file. Note that Jed 0.99.16/17 does not yet % handle utf-8 encoded files. custom_variable ("Charset", "iso-8859-1"); %% If po-file has plural forms: how many plural forms does your language %% have? See /usr/share/doc/gettext-doc/gettext_10.html#SEC1. custom_variable ("Nplurals", "2"); %% See /usr/share/doc/gettext-doc/gettext_10.html#SEC1 custom_variable ("Plural", "(n != 1)"); %% Program to use for spell checking; use ispell or aspell custom_variable ("Spell_Prg", "ispell"); %% Language dictionary for ispell/aspell, e.g. "deutsch" for German custom_variable ("Spell_Dict", "dansk"); %% What compendiums to use: %% 1 = native po_mode compendium %% 2 = gettext compendium %% 3 = both custom_variable ("Use_Compendium", 3); %% Path to native compendium file: custom_variable ("Compendium", dircat (getenv ("HOME"), ".compendium_pomode")); %% Path to compendium file, created with msgcat: custom_variable ("Compendium_Gettext", dircat (getenv ("HOME"), ".compendium_gettext")); %% If fuzzy matching is used with gettext compendiums 0 = no, 1 = yes: custom_variable ("Gettext_Use_Fuzzy", 0); %% Path to wordlist custom_variable ("Custom_Wordlist", dircat (getenv ("HOME"), ".wordlist_pomode")); %% What wordlist(s) to use for word translation lookups?: %% 1 = custom %% 2 = dict freedict translation dictionary %% 3 = both custom_variable ("Use_Wordlist", 3); %% If you use dict, you must set the dict dictionary to use, %% this one is English -> German custom_variable ("Dict_Dictionary", "fd-eng-deu"); %% Do not look up translations for words less than n chars custom_variable ("Dict_Minimum_Wordsize", 4); private variable Language_Team = sprintf ("%s %s", Language, Team_Email); %}}} %{{{ prototypes public define po_mode(); %}}} %{{{ auxiliary functions %% Search for a file in $PATH static define prg_found_in_path (file) { variable path = getenv ("PATH"); return search_path_for_file (path, file, ':'); } static define write_tmp_buffer (file) { push_spot (); mark_buffer (); () = write_region_to_file (file); pop_spot (); } %% The example function from the S-Lang documentation static define file_size (file) { variable st; st = stat_file(file); if (st == NULL) verror ("unable to stat %s", file); return st.st_size; } %% Mark a word and return it (and with argument return and delete it). static define po_mark_word (delete) { variable word = ""; push_spot (); bskip_word_chars (); push_mark (); skip_word_chars (); if (delete) word = bufsubstr_delete (); else word = bufsubstr (); pop_spot (); return word; } %% Strip word of n chars and return it. Also return nth char. static define strip_chars (word, n) { variable char = ""; variable len = strlen (word)-1; if (n <= len) { word = word [[:len-n]]; char = word [[len-n:len-n]]; } return word, char; } %% Sort a string array removing duplicate members and return result static define sort_uniq (str) { variable i, a = "", b = ""; str = str [array_sort (str)]; _for (0, length (str)-1, 1) { i = (); a = str [i]; !if (0 == strcmp (a, b)) str [i] = a; else str [i] = Null_String; b = a; } return str; } %% Remove some characters from a string. static define format_string (str) { str = strcompress (str, " "); str = str_replace_all (str, "\\n", ""); str = str_delete_chars (str, "\n\(\)\"\^`',\.\?\!;<>[]\*/{}\+#:&\\"); str = strtrim_beg (str); return str; } %}}} %{{{ delimitation % All sorts of quaint syntactical variations -- all legal to gettext have been % taken into account, which is why this section looks somewhat patchy. E.g.: % Entries seperated by blank line or no blank line in between, various types % of comments in between entries or not, blank lines in between comments and % message strings or not, trailing quotes in comment lines, handling of obsolete % entries, plural entries wrapped on several lines, etc. -- it should all work. % If only a well formed standard gettext format was assumed, it could of course % have been written in just a few lines. %% Determine if an entry is untranslated. Could have been simplified %% with the pcre-module which can search across lines, but this is faster %% Thanks to Gnter Milde for suggesting this. static define is_untranslated () { EXIT_BLOCK { pop_spot (); } () = ffind ("\""); push_spot (); !if (looking_at ("\"\"")) return 0; if (down (1)) not looking_at ("\""); else return 1; } static define is_translated () { not is_untranslated (); } static define is_comment () { bol (); orelse {looking_at ("#\n") } {looking_at ("##") } {looking_at ("#,") } {looking_at ("#.") } {looking_at ("#:") } {looking_at ("# ") } {looking_at ("#~ #")}; } static define search_any_msgid () { while (re_fsearch ("msgid_?")) { if (bolp ()) return 1; else if (bfind ("#~")) return 1; else { eol (); continue; } } return 0; } define position_on (pos); % for recursion define position_on (pos) { bol (); switch (pos) { case "msgid": if (is_comment () or eolp () or re_looking_at (msgid_any_re)) { if (search_any_msgid ()); else { () = re_bsearch (msgid_any_re); } return; } if (re_looking_at ("#?~? ?\"")) { () = re_bsearch (str_any_re); } if (re_looking_at (msgstr_any_re + "1")) { () = re_bsearch (msgid_plural_re); return; } if (re_looking_at (msgstr_any_re + "0") or re_looking_at (msgstr_re)) { () = re_bsearch (msgid_re); return; } } { case "msgstr": if (re_looking_at (msgstr_any_re)) return; position_on ("msgid"); if (re_looking_at (msgid_re)) { () = re_fsearch (msgstr_any_re + "0?"); } else { () = re_fsearch (msgstr_any_re + "1"); } } { case "entry_start": position_on ("msgstr"); () = re_bsearch (msgid_re); while (up (1)) { if (blooking_at ("\"")) { bol (); if (is_comment ()) continue; else break; } } bol (); if (bobp ()) return; while (down (1)) { if (is_comment () or re_looking_at (msgid_re)) return; } } { case "entry_end": position_on ("msgstr"); if (re_fsearch (msgid_re)); else { eob (); bskip_chars ("\n\t "); return; } position_on ("entry_start"); bskip_chars ("\n\t "); } } static define mark (str) { switch (str) { case "entry": position_on ("entry_start"); push_mark (); position_on ("entry_end"); } { case "strings": position_on ("msgid"); push_mark (); position_on ("entry_end"); } { case "msgid": position_on ("msgid"); () = ffind ("\""); if (looking_at ("\"\"")) { () = down (1); } push_mark (); () = re_fsearch (str_any_re); () = up (1); } { case "msgstr": position_on ("msgstr"); if (is_untranslated ()) return push_mark_eol (); else { push_mark (); while (down (1)) { if (re_looking_at (str_any_re) or is_comment () or eolp ()) break; if (re_looking_at ("#?~? ?\"")) continue; } eol (); if (eobp ()) return; else { () = up (1); } } } } static define is_header () { push_spot (); position_on ("msgid"); !if (bol_bsearch ("msgid")) 1; else 0; pop_spot (); } %% Narrow to msgstr and msgid, excluding comments. static define narrow_to_strings () { mark ("strings"); narrow_to_region (); bob (); } static define narrow_to_entry () { mark ("entry"); narrow_to_region (); bob (); } %% Return either the msgid or the msgstr as a string. static define msg_as_string (str) { variable msg = ""; push_spot (); if (str) mark ("msgstr"); else mark ("msgid"); msg = bufsubstr (); pop_spot (); return msg; } static define is_fuzzy () { EXIT_BLOCK { position_on ("entry_end"); } position_on ("entry_start"); do { if (looking_at ("msgid")) return 0; if (looking_at ("#, fuzzy")) return 1; } while (down (1)); } %}}} %{{{ statistics %% Make all count variables local to the buffer static define count (i) { switch (i) { case "t": get_blocal_var ("translated"); } { case "u": get_blocal_var ("untranslated"); } { case "f": get_blocal_var ("fuzzy"); } { case "o": get_blocal_var ("obsolete"); } { case "t+": set_blocal_var (get_blocal_var ("translated") + 1, "translated"); } { case "t-": set_blocal_var (get_blocal_var ("translated") - 1, "translated"); } { case "u+": set_blocal_var (get_blocal_var ("untranslated") + 1, "untranslated"); } { case "u-": set_blocal_var (get_blocal_var ("untranslated") - 1, "untranslated"); } { case "f+": set_blocal_var (get_blocal_var ("fuzzy") + 1, "fuzzy"); } { case "f-": set_blocal_var (get_blocal_var ("fuzzy") - 1, "fuzzy"); } { case "o+": set_blocal_var (get_blocal_var ("obsolete") + 1, "obsolete"); } { case "o-": set_blocal_var (get_blocal_var ("obsolete") - 1, "obsolete"); } } %% The status line that shows the counts for translated, untranslated, fuzzy %% and obsolete entries static define set_po_status_line () { if (View_Limit == 1) { set_status_line (" (PO) ", 0); return; } variable t, u, f, o, s, n, p; t = count ("t"); u = count ("u"); f = count ("f"); o = count ("o"); n = t + f + u; if (n == 0) n = 1; p = Sprintf ("(%S%s) ", (t*100)/n, "%%", 2); s = Sprintf ("%dt/%du/%df/%do", t, u, f, o, 4); set_status_line (" %b " + p + s + " (%m%a%n%o) %p %t", 0); } %% The actual counting of the various entries. Could be done in %% one pass, but this is faster. static define po_statistics () { variable t, u, f, o; create_blocal_var ("translated"); set_blocal_var (0, "translated"); create_blocal_var ("untranslated"); set_blocal_var (0, "untranslated"); create_blocal_var ("fuzzy"); set_blocal_var (0, "fuzzy"); create_blocal_var ("obsolete"); set_blocal_var (0, "obsolete"); create_blocal_var ("total_entries"); set_blocal_var (0, "total_entries"); t = count ("t"); u = count ("u"); f = count ("f"); o = count ("o"); ERROR_BLOCK { pop_spot (); _clear_error (); error ("Maybe po-file has syntax errors? Try to validate .."); } flush ("counting entries ..."); push_spot_bob (); () = bol_fsearch ("\""); loop (2) push_mark (); while (re_fsearch ("^msgstr.[^1]")) { if (is_untranslated ()) u++; else t++; } pop_mark (1); while (bol_fsearch ("#~ msgid")) { eol (); o++; } pop_mark (1); while (bol_fsearch ("#, fuzzy")) { () = down (1); !if (looking_at ("#~")) f++; } t = t - f; % translated count doesn't exlude fuzzies so deduct them here set_blocal_var (t, "translated"); set_blocal_var (u, "untranslated"); set_blocal_var (f, "fuzzy"); set_blocal_var (o, "obsolete"); set_blocal_var (t + u + f + o, "total_entries"); pop_spot (); set_po_status_line (); update (1); } define get_current_entry_number () { push_spot (); position_on ("msgid"); variable n = 0; while (re_bsearch (msgid_re)) n++; pop_spot (); return n; } %% Shows the counts in the message area, including total counts and current %% position define show_po_statistics () { variable t, u, f, o; variable n = get_blocal_var ("total_entries"); variable cn = get_current_entry_number (); t = count ("t"); u = count ("u"); f = count ("f"); o = count ("o"); po_statistics (); vmessage ("%s %d/%d; %d translated, %d untranslated, %d fuzzy, %d obsolete", "Position:", cn, n, t, u, f, o); } %}}} %{{{ navigation static define restore_entry_position (n) { bob (); loop (n+1) { () = re_fsearch (msgstr_re); eol (); } position_on ("msgid"); } define show_current_entry_number () { push_spot (); variable n = get_current_entry_number (); vmessage ("# %d", n); pop_spot (); } %% Go to next entry which is either untranslated or fuzzy define any_next_unfinished () { if (count ("u") == 0 and count ("f") == 0) return flush ("no unfinished entries"); forever { position_on ("entry_end"); while (down (1)) { if (looking_at ("msgstr ")) { if (is_untranslated ()) { () = bol_bsearch ("msgstr "); return; } } if (looking_at ("#, fuzzy")) { () = down (1); if (looking_at ("#~")) continue; else return; } } bob (); flush ("wrapping search around buffer"); continue; } } define po_next_entry () { position_on ("msgid"); eol (); if (re_fsearch (msgid_any_re)); else return bol (); if (is_line_hidden ()) { skip_hidden_lines_forward (1); () = re_fsearch (msgid_re); } } define po_previous_entry () { position_on ("entry_start"); () = re_bsearch (msgid_re); if (is_line_hidden ()) { skip_hidden_lines_backward (1); () = re_bsearch (msgid_re); } } define top_justify_entry () { position_on ("entry_start"); recenter (1); } %% Go to the next untranslated entry and wrap search around buffer define find_untranslated () { if (count ("u") == 0) return flush ("no untranslated entries"); EXIT_BLOCK { () = bol_bsearch ("msgid"); } () = bol_fsearch ("msgstr"); eol (); while (bol_fsearch ("msgstr")) if (is_untranslated) return; flush ("wrapping search around buffer"); bob (); while (bol_fsearch ("msgstr")) if (is_untranslated) return; } %% Go to the next translated entry and wrap search around buffer define find_translated () { if (count ("t") == 0) return flush ("no translated entries"); EXIT_BLOCK { () = bol_bsearch ("msgid"); } forever { position_on ("entry_end"); while (bol_fsearch ("msgstr")) { if (is_untranslated () or is_fuzzy ()) continue; else return; } bob (); flush ("wrapping search around buffer"); continue; } } define find_fuzzy () { if (count ("f") == 0) return flush ("no fuzzy entries"); forever { while (bol_fsearch ("#, fuzzy")) { () = down (1); !if (looking_at ("#~")) { () = bol_fsearch ("msgid"); return; } else continue; } bob (); flush ("wrapping search around buffer"); continue; } } %% Find the next obsolete entry and wrap search around buffer define find_obsolete () { if (count ("o") == 0) return flush ("no obsolete entries"); forever { position_on ("entry_end"); while (bol_fsearch ("#~ msgid")) return; flush ("wrapping search around buffer"); bob (); continue; } } %% Find the previous untranslated msgstr. define bfind_untranslated () { if (count ("u") == 0) return message ("no untranslated entries"); push_mark (); while (bol_bsearch ("msgstr")) { if (is_untranslated ()) { () = bol_bsearch ("msgid"); return pop_mark (0); } () = bol_bsearch ("msgid"); } flush ("no untranslated strings above this point"); pop_mark (1); } %% Find the previous translated entry define bfind_translated () { if (count ("t") == 0) return flush ("no translated entries"); while (bol_bsearch ("msgstr")) { if (is_untranslated ()) { () = bol_bsearch ("msgid "); continue; } else if (is_fuzzy ()) { () = bol_bsearch ("msgid "); continue; } else { () = bol_bsearch ("msgid "); return; } } } %% Find the previous entry with fuzzy flag. define bfind_fuzzy () { push_mark (); position_on ("entry_start"); !if (bol_bsearch ("#, fuzzy")) { flush ("no fuzzy entries above this point"); pop_mark (1); } pop_mark (0); } %% Find the previous obsolete entry. define bfind_obsolete () { push_mark (); position_on ("entry_start"); !if (bol_bsearch ("#~ msgid")) { flush ("no obsolete entries above this point"); pop_mark (1); } pop_mark (0); } %% Find the next entry with a translator comment and wrap search around buffer define find_translator_comment () { push_mark (); while (re_fsearch (translator_cmt_re)) { () = re_fsearch (msgid_re); return pop_mark (0); } flush ("wrapping search around buffer"); bob (); while (re_fsearch (translator_cmt_re)) { () = re_fsearch (msgid_re); return pop_mark (0); } pop_mark (1); flush ("no more translator comments"); } define goto_entry () { variable entry_number = read_mini ("Go to entry number:", "", ""); if (integer (entry_number) > get_blocal_var ("total_entries") or integer (entry_number) < 1) return flush ("no such entry"); bob (); loop (integer (entry_number) + 1) { eol (); () = re_fsearch (msgid_re); } } %}}} %{{{ flagging %% Flag translation as "fuzzy", or obsolete entry if already fuzzy define fuzzy_or_obsolete_entry () { EXIT_BLOCK { set_readonly (1); set_po_status_line (); pop_spot (); } position_on ("msgstr"); push_spot (); if (looking_at ("#~") or is_untranslated ()) return; () = bol_bsearch ("msgid "); if (up (1)) bol (); set_readonly (0); if (looking_at ("#, fuzzy")) { !if (get_y_or_n ("Make entry obsolete")) return; narrow_to_entry (); do { insert ("#~ "); } while (down (1)); widen_region (); count ("f-"); count ("o+"); return; } if (looking_at ("#,")) { skip_chars ("#, "); insert ("fuzzy, "); } else { () = down (1); insert ("#, fuzzy\n"); } !if (bol_bsearch ("msgid")) return; count ("f+"); count ("t-"); } define remove_fuzzy_flag () { EXIT_BLOCK { pop_spot (); } push_spot (); position_on ("entry_start"); () = bol_fsearch ("msgid "); if (up (1)) bol (); !if (looking_at ("#, fuzzy")) return; else { set_readonly (0); push_mark (); skip_chars ("#, fuzy"); del_region (); if (eolp ()) del (); else insert ("#, "); } set_readonly (1); if (is_header ()) return; if (count ("f") > 0) count ("f-");; count ("t+"); set_po_status_line (); } define flag_fuzzy_all () { !if (get_y_or_n ("Flag all entries fuzzy")) return; push_spot_bob (); po_next_entry (); while (bol_fsearch ("msgstr")) { if (is_fuzzy ()) continue; else fuzzy_or_obsolete_entry (); } pop_spot (); } %}}} %{{{ po-header %% Insert a default header static define insert_po_header () { set_readonly (0); bob (); insert ("# SOME DESCRIPTIVE TITLE.\n" + "# Copyright (C) YEAR Free Software Foundation, Inc.\n" + "# FIRST AUTHOR , YEAR.\n" + "#\n" + "#, fuzzy\n" + "msgid \"\"\n" + "msgstr \"\"\n" + "\"Project-Id-Version: PACKAGE VERSION\\n\"\n" + "\"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\\n\"\n" + "\"Last-Translator: FULL NAME \\n\"\n" + "\"Language-Team: LANGUAGE \\n\"\n" + "\"MIME-Version: 1.0\\n\"\n" + "\"Content-Type: text/plain; charset=CHARSET\\n\"\n" + "\"Content-Transfer-Encoding: 8bit\\n\"\n" + "\"Plural-Forms: nplurals=2; plural=\(n != 1\)\\n\"\n\n"); set_readonly (1); } % Set the revision date. It should insert time strings in the format of % e.g. "2004-06-28 20:11-0400" where the last part is the users time zone. % The use of the date command to get the time zone is perhaps a little % ugly, but I cannot figure out how to get the right time zone at all times % across all time zones with S-Lang's built-in time functions. Maybe you can % help? static define set_po_revision_date () { !if (mode == get_mode_name) return; variable tm = localtime (_time ()); variable day, month, year; variable rev_str; variable t = sprintf ("%d-%02d-%02d %02d:%02d", 1900 + tm.tm_year, 1+tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min); rev_str = sprintf ("%s%s", "\"PO-Revision-Date: ", t); push_spot_bob (); narrow_to_strings (); if (re_fsearch ("^\"PO-Revision-Date.*$")) { set_readonly (0); () = replace_match (rev_str, 1); () = run_shell_cmd (sprintf ("%s%s", "date +%z", "'\\n\"'")); del (); } widen_region (); pop_spot (); set_readonly (1); } append_to_hook ("_jed_save_buffer_before_hooks", &set_po_revision_date); %% Adjust the po-header to user's settings. define replace_headers () { !if (get_y_or_n ("Replace headers")) return; variable team, name, charset, plural_str, project; name = sprintf ("\"Last-Translator: %s\\n\"", Translator); team = sprintf ("\"Language-Team: %s\\n\"", Language_Team); project = sprintf ("\"Project-Id-Version: %s\\n\"", whatbuf ()); charset = sprintf ("\"Content-Type: text/plain; charset=%s\\n\"", Charset); plural_str = sprintf ("\"Plural-Forms: nplurals=%s; plural=%s\\n\"", Nplurals, Plural); push_spot_bob (); set_readonly (0); narrow_to_strings (); if (re_fsearch ("^\"Project-Id-Version.*")) { () = replace_match (project, 1); } if (re_fsearch ("^\"Last-Translator.*")) { () = replace_match (name, 1); } if (re_fsearch ("^\"Language-Team.*")) { () = replace_match (team, 1); } if (re_fsearch ("^\"Content-Type.*")) { () = replace_match (charset, 1); } if (re_fsearch ("^\"Plural-Forms.*")) { () = replace_match (plural_str, 1); } else { eob (); insert ("\n" + plural_str); } widen_region (); remove_fuzzy_flag (); pop_spot (); set_readonly (1); } %}}} %{{{ po_edit buffer % Here is an outline of the rationale behind the way editing of gettext % message strings is handled in this mode. % % - Upon loading a po-file, the buffer where the editing of the message % string (msgstr) is to be done is created and the po_edit_mode is set % for it. This buffer is kept open all of the time. % % The function pre_format_msgstr () is then called which converts the % C-like printable string format of the message string into a user-friendly % editing format, surrounding double quotes and newline literals are % expanded. % % The message-id (msgid), which is the text to be translated, is narrowed in % a fold in the top of a split window and the po_edit buffer is popped up % as the bottom window where the formatted message string is inserted for % editing. The number of lines in the top window is approx. fit to the % number of lines in the message id to get the editing point closer to the % text to be translated. % % Finally the function setup_edit_buf () is called to set up the editing % environment for the po_edit buffer: if the string is multi-line an eob % (end-of-buffer) marker is inserted. For single-line strings wrapping is % set at 78 characters, a wrap_hook is set which ensures that % word-delimiting white space is inserted at the end of each line at wrap % point. The enter-key is disabled. % % - When the user presses key to finish editing, the function % post_format_msgstr () is called which converts the message string % back into the C-like printable format: all lines are surrounded in % double quotes, embedded double quotes are escaped, for multi-line % strings embedded newline literals are inserted at every actual % newline character. % % The contents of the po_edit buffer are erased and its window is put % in the background and the old message string is replaced by the new % one. Statistics are updated. % % All of this should hopefully make editing completely transparent, with % the user not having to worry about anything relating to the formatting % of the message string. static define po_edit_menu (menu) { menu_append_item (menu, "Finish Editing", "po_end_edit"); menu_append_item (menu, "Enlarge Msgstr Window", "enlargewin"); menu_append_item (menu, "Decrease Msgstr Window", "decreasewin"); menu_append_item (menu, "Discard Changes", "del_editbuf"); } %% Mode for the editing buffer. static define po_edit_mode () { use_keymap (Edit_Mode); set_abbrev_mode (1); if (abbrev_table_p (Edit_Mode)) use_abbrev_table (Edit_Mode); run_mode_hooks ("po_edit_mode_hook"); mode_set_mode_info (Edit_Mode, "init_mode_menu", &po_edit_menu); set_buffer_modified_flag (0); set_buffer_undo (1); } static define create_po_edit_buf () { variable po_buf = whatbuf (); setbuf (po_edit_buf); po_edit_mode (); setbuf (po_buf); } static define restore_po_buffer_window () { otherwindow (); onewindow(); widen_region (); bury_buffer (po_edit_buf); } static define po_edit_parsep () { bol_skip_white (); if (eolp ()) return 1; else if (re_looking_at ("^-$")) return 1; else return 0; } %% Thanks to John E. Davis for this solution. static define po_edit_wrap_hook () { push_spot (); bol (); go_left (1); insert (" "); pop_spot (); } static define single_line_newline_hook () { flush ("single-line format"); } % Setup of the edit buffer static define setup_edit_buf () { if (Multi_Line == 1) { eob (); insert ("\n-"); set_line_readonly (1); set_buffer_hook ("par_sep", &po_edit_parsep); unset_buffer_hook ("newline_indent_hook"); set_mode (Edit_Mode, 0); } else { set_buffer_hook ("newline_indent_hook", &single_line_newline_hook); WRAP = 78; set_buffer_hook ("wrap_hook", &po_edit_wrap_hook); set_mode (Edit_Mode, 1); % wrap_mode } bob (); } % Simulate a gettext unwrapping of a multi-line msgid in order to get % the right pattern for newline literals in get_msgid_line_format (). static define po_unwrap (str) { variable len, pos = 1; while (string_match (str, "[^\\\\].\n", pos)) { (pos, len) = string_match_nth (0); str = strsub (str, pos + len, ' '); } return str; } % The formatting done to the msgstr before it is read into the po_edit % buffer static define pre_format_msg (str) { variable s, i, alen; % detect if msgid has embedded newline literals if (is_substr (msg_as_string (0), "\\n") or is_header ()) Multi_Line = 1; else Multi_Line = 0; str = str_replace_all (str, "\"\"\n", Null_String); str = str_replace_all (str, "\\\"", "\""); str = strchop (str, '\n', 0); alen = length (str)-1; % remove enclosing double quotes _for (0, alen, 1) { i = (); s = str [i]; s = s [[1:strlen (s)-2]]; if (Multi_Line == 1) { s = strtrim_end (s, " "); % expand newline literal of the last line if (i == alen) { if (string_match (s, "\\\\n$", 1)) { s = str_replace_all (s, "\\n", "\\n\n"); } } } str [i] = s; } str = strjoin (str, "\n"); % make sure that possibly wrapped multi-line strings are unwrapped if (Multi_Line == 1) { str = po_unwrap (str); } str = str_replace_all (str, "\\n", Null_String); !if (strlen (str)) Translation_Status = 0; else Translation_Status = 1; return str; } % The formatting done to the msgstr before it is read back into the po buffer static define post_format_msgstr () { variable str, len, alen; % remove the eob marker if (Multi_Line == 1) { eob (); set_line_readonly (0); () = up (1); push_mark (); eob (); del_region (); } mark_buffer (); str = bufsubstr (); % escape embedded double quotes str = str_replace_all (str, "\"", "\\\""); % insert newline literals if (Multi_Line == 1) { str = str_replace_all (str, "\n", "\\n\n"); } str = strchop (str, '\n', 0); % remove empty lines str = str [where (array_map (Integer_Type, &strlen, str))]; alen = length (str)-1; % surround lines in double quotes str [[:alen]] = "\"" + str + "\""; if (length (str) == 0) str = "\"\""; str = strjoin (str, "\n"); len = strlen (str); if (len > 72 or alen > 0) str = "\"\"\n" + str; return str, len; } define decreasewin () { otherwindow (); enlargewin (); otherwindow (); } define cancel_editbuf () { erase_buffer (); restore_po_buffer_window (); set_po_status_line (); } % A split window is shown with the msgid to be translated in the top window % and the translation to be filled in is in the bottom window. define po_edit () { if (is_line_hidden ()) return; variable n, wn, nlines, msgstr, po_buf; !if (bufferp (po_edit_buf)) create_po_edit_buf (); if (nwindows == 2 and mode == get_mode_name) { otherwindow (); return; } set_status_line (" ", 0); msgstr = pre_format_msg (msg_as_string (1)); mark ("msgid"); recenter (1); pop2buf (po_edit_buf); insert (msgstr); otherwindow (); narrow_to_region (); % msgid fold n = what_line (); bob (); wn = window_info ('r'); nlines = wn - n; % alert user to msgid not being fully shown if (n > wn) set_status_line (" -- more -- ", 0); otherwindow (); loop (nlines-2) enlargewin (); setup_edit_buf (); set_buffer_modified_flag (0); } %% The finished translation is read back into the po-file define po_end_edit () { !if (buffer_modified) { cancel_editbuf (); position_on ("msgid"); return; } variable msgstr, len; (msgstr, len) = post_format_msgstr (); erase_buffer (); restore_po_buffer_window (); set_readonly (0); mark ("msgstr"); del_region (); insert (msgstr); position_on ("msgstr"); if (re_looking_at ("^msgstr.[^1]")) { % msgstr was untranslated but is now translated so increment % translated count by one. if (Translation_Status == 0 and len > 2) { count ("t+"); if (count ("u") > 0) count ("u-"); } % msgstr was translated but is now untranslated so decrement % translated count by one. if (Translation_Status == 1 and len == 2) { remove_fuzzy_flag (); if (count ("t") > 0) count ("t-"); count ("u+"); } } set_po_status_line (); set_readonly (1); recenter (0); } %}}} %{{{ translator comments static define po_comment_mode () { set_mode ("po_comment", 0); use_keymap ("po_comment"); set_buffer_undo (1); } static define mark_translator_comment () { narrow_to_entry (); if (orelse { re_fsearch (translator_cmt_re) } { bol_fsearch ("#,") } { re_fsearch (msgid_re)}); push_mark (); while (re_looking_at (translator_cmt_re)) { () = down (1); } widen_region (); } static define strip_comments () { bob (); while (re_looking_at (translator_cmt_re)) { do { bol (); push_mark (); skip_chars ("# \t"); del_region (); } while (down (1)); } } static define add_comments () { if (eobp () and bobp ()) return; bob (); do { bol (); insert ("# "); } while (down (1)); eob (); newline (); } define del_translator_comment () { set_readonly (0); mark_translator_comment (); del_region (); set_readonly (1); } %% Insert a translator comment or edit an existing one define po_edit_comment () { variable po_buf; po_cmt_buf = "*" + whatbuf () + "*"; mark_translator_comment (); exchange_point_and_mark (); recenter (1); po_buf = pop2buf_whatbuf (po_cmt_buf); setbuf (po_buf); copy_region (po_cmt_buf); setbuf (po_cmt_buf); strip_comments (); po_comment_mode (); set_buffer_modified_flag (0); bob (); } define po_end_edit_comment () { !if (buffer_modified) { delbuf (po_cmt_buf); restore_po_buffer_window (); return; } eob (); bskip_chars (" \t\n"); while (not eobp ()) del (); add_comments (); mark_buffer (); set_buffer_modified_flag (0); restore_po_buffer_window (); del_translator_comment (); set_readonly (0); insbuf (po_cmt_buf); delbuf (po_cmt_buf); position_on ("msgid"); set_readonly (1); } %}}} %{{{ modification of entries outside of po_edit buffer static define trim_buf () { do { trim (); eol (); trim (); } while (down (1)); bob (); } static define delete_entry () { narrow_to_entry (); mark_buffer (); del_region (); widen_region (); } static define del_msgstr () { mark ("msgstr"); del_region (); } %% Delete an obsolete entry define del_obsolete () { position_on ("msgid"); !if (looking_at ("#~")) error ("not an obsolete entry"); else { set_readonly (0); delete_entry (); if (eolp () and bolp ()) del (); set_readonly (1); if (count ("o") > 0) count ("o-"); set_po_status_line (); } } %% Remove contents of msgstr (leaving it unstranslated) define cut_msgstr () { push_spot (); position_on ("msgstr"); if (looking_at ("#~") or is_untranslated ()) return pop_spot (); remove_fuzzy_flag (); set_readonly (0); del_msgstr (); insert ("\"\""); bol (); if (re_looking_at ("^msgstr.[^1]")) { count ("t-"); count ("u+"); } set_po_status_line (); set_readonly (1); pop_spot (); } %% Copy contents of msgid to msgstr define copy_msgid_to_msgstr () { if (is_header ()) return; variable msgid, msgstr; msgid = msg_as_string (0); msgstr = msg_as_string (1); position_on ("msgstr"); if (re_looking_at ("^msgstr.[^1]")) { if (strlen (msgstr) == 2) % untranslated { count ("u-"); count ("t+"); set_po_status_line (); } else { !if (get_y_or_n ("Overwrite previous translation")) return; } } set_readonly (0); push_spot (); del_msgstr (); if (strlen (msgid) > 72 or is_substr (msgid, "\n")) insert ("\"\"\n" + msgid); else insert (msgid); pop_spot (); set_readonly (1); } define copy_msgstr () { create_blocal_var ("msgstr_dup"); push_spot (); mark ("msgstr"); set_blocal_var (bufsubstr (), "msgstr_dup"); pop_spot (); flush ("msgstr copied"); } define insert_msgstr () { !if (blocal_var_exists ("msgstr_dup")) error ("nothing to insert"); variable str = get_blocal_var ("msgstr_dup"); position_on ("msgstr"); if (is_untranslated ()) { if (count ("u") > 0) count ("u-"); count ("t+"); set_po_status_line (); } else { !if (get_y_or_n ("Overwrite previous translation")) return; } set_readonly (0); del_msgstr (); insert (str); set_readonly (1); } %% Search and replace strings within msgstrs define replace_in_msgstrs () { variable pat, rep, prompt, word; pat = read_mini ("Replace in msgstrs:", Null_String, Null_String); !if (strlen (pat)) return; prompt = strcat (strcat ("Replace '", pat), "' with:"); rep = read_mini (prompt, "", ""); push_spot_bob (); while (fsearch (pat)) { po_edit (); while (fsearch (pat)) { word = po_mark_word (1); if (string_match (word, sprintf ("^%s$", pat), 1)) insert (rep); else insert (word); } po_end_edit (); position_on ("entry_end"); } pop_spot (); flush ("done"); } define po_undo () { variable n = get_current_entry_number (); set_readonly (0); call ("undo"); restore_entry_position (n); po_statistics (); set_readonly (1); } %}}} %{{{ various gettext functions static define check_enc () { if (NULL == prg_found_in_path ("file")) return -1; variable header_enc, cmd; push_spot_bob (); () = fsearch ("charset="); skip_chars ("charset="); push_mark (); () = ffind ("\\"); header_enc = bufsubstr (); cmd = sprintf ("file -i - | grep -i %s", header_enc); mark_buffer (); !if (0 == pipe_region (cmd)) { pop_spot (); return 0; } else { pop_spot (); return 1; } } static define check_integrity (file) { variable msg = sprintf ("checking integrity of %s ...", file); variable buf = whatbuf (); flush (msg); !if (1 == file_status (file)) { flush (sprintf ("file not found", file)); return 0; } if (0 == system (sprintf ("%s %s 2>/dev/null", "msgfmt -c -o /dev/null", file)) and 0 == system (sprintf ("%s%s %s 2>/dev/null", "msgcat -o /dev/null --to-code=", Charset, file))) { flush (sprintf ("%s %s", msg, "(ok)")); sleep (0.2); return 1; } else { flush (sprintf ("%s %s", msg, "(failed)")); sleep (0.2); return 0; } } %% Check po-file for syntax errors and character set conversion errors define po_validate_command () { if (NULL == prg_found_in_path ("msgfmt")) error ("gettext utilities not installed"); variable tmpfile = make_tmp_file ("/tmp/po_validate"); variable cmd_v, cmd_c; cmd_v = sprintf ("%s >> %s %s", "msgfmt - --statistics -c -v -o /dev/null", tmpfile, "2>&1"); cmd_c = sprintf ("%s%s >>%s %s", "msgcat - -o /dev/null --to-code=", Charset, tmpfile, "2>&1"); flush ("validating file ..."); push_spot (); mark_buffer (); () = dupmark (); () = append_string_to_file ("*** Output from validation with msgfmt ***:\n\n", tmpfile); () = pipe_region (cmd_v); () = append_string_to_file ("\n-----\n", tmpfile); () = append_string_to_file ("\n*** Output from encoding conversion test ***:\n", tmpfile); () = pipe_region (cmd_c); () = append_string_to_file ("\n-----\n", tmpfile); if (0 == check_enc ()) () = append_string_to_file ("\nNB: Charset encoding in header does not match that of the document.", tmpfile); pop_spot (); recenter (1); pop2buf ("*Validation Output*"); () = insert_file (tmpfile); set_buffer_modified_flag (0); most_mode (); bob (); () = delete_file (tmpfile); % update (1); call ("redraw"); } %% Compile the po-file *.po -> *.mo define po_compile () { if (NULL == prg_found_in_path ("msgfmt")) error ("msgfmt program not found in $PATH"); variable dir = dircat (getenv ("HOME"), Null_String); variable cmd = read_mini ("Compile command: ", "", "msgfmt" + " -o " + dir + path_sans_extname (whatbuf()) + ".mo " + whatbuf()); if (strlen (cmd)) compile (cmd); } %% Use the gettext program 'msgunfmt' to decompile a *.mo file and read it %% into the editor define po_decompile () { if (NULL == prg_found_in_path ("msgunfmt")) error ("msgunfmt program not found in $PATH"); variable mo_file = read_with_completion ("*.mo-file:", "", "", 'f'); variable po_file = dircat (getenv ("HOME"), strcat (path_sans_extname (path_basename (mo_file)) + ".po")); if (1 == file_status (po_file)) { vmessage ("File %s exists, overwrite? (y/n)", po_file); update (1); if ('y' == getkey ()); else return; } () = system (strcat ("msgunfmt ", mo_file, " > ", po_file)); () = find_file (po_file); } %% Use msgcat to wrap/unwrap entries static define wrap_entries (wrap) { if (NULL == prg_found_in_path ("msgcat")) error ("msgcat program not found in $PATH"); variable n = get_current_entry_number (); variable status; variable tmpfile = make_tmp_file ("/tmp/po_tmpfile"); variable newfile = make_tmp_file ("/tmp/po_newfile"); write_tmp_buffer (tmpfile); if (wrap) { flush ("wrapping entries ..."); status = system (sprintf ("%s %s > %s 2>/dev/null", "msgcat", tmpfile, newfile)); } else { flush ("unwrapping entries ..."); status = system (sprintf ("%s %s > %s 2>/dev/null", "msgcat --no-wrap", tmpfile, newfile)); } !if (status == 0) { () = delete_file (tmpfile); () = delete_file (newfile); return flush ("error in file"); } set_readonly (0); erase_buffer (); () = insert_file (newfile); () = delete_file (tmpfile); () = delete_file (newfile); set_readonly (1); restore_entry_position (n); flush ("done"); } define toggle_wrap () { if (Wrap_Status) { wrap_entries (0); Wrap_Status = 0; } else { wrap_entries (1); Wrap_Status = 1; } } %% Update current po-file to newer version with gettext msgmerge define po_file_update () { if (NULL == prg_found_in_path ("msgmerge")) error ("msgmerge program not found in $PATH"); variable oldfile = make_tmp_file ("/tmp/oldfile"); variable merged_file = make_tmp_file ("/tmp/newfile"); variable pot_file = read_with_completion ("Path to newer file:", "", "", 'f'); write_tmp_buffer (oldfile); if (buffer_modified ()) save_buffer (); flush ("updating po-file ..."); !if (0 == system (sprintf ("%s %s %s -o %s >/dev/null 2>&1", "msgmerge" , oldfile, pot_file, merged_file))) { delete_file (oldfile); delete_file (merged_file); error ("could not merge files, syntax errors probably"); } set_readonly (0); erase_buffer (); () = insert_file (merged_file); delete_file (oldfile); delete_file (merged_file); bob (); po_statistics (); flush ("save under a new name if you want to keep the old version"); set_readonly (1); } %% Use gettext msgconv to apply a different character set encoding define conv_charset () { if (NULL == prg_found_in_path ("msgconv")) error ("msgconv program not found in $PATH"); variable oldfile = make_tmp_file ("/tmp/conv_charset_old"); variable newfile = make_tmp_file ("/tmp/conv_charset_new"); variable charset; variable n = get_current_entry_number (); variable encodings = "ascii,iso-8859-1,iso-8859-2,iso-8859-3,iso-8859-4,iso-8859-5,"+ "iso-8859-6,iso-8859-7,iso-8859-8,iso-8859-9,iso-8859-13,iso-8859-14,"+ "iso-8859-15,koi8-r,koi8-u,koi8-t,cp850,cp866,cp874,cp932,cp949,"+ "cp950,cp1250,cp1251,cp1252,cp1253,cp1254,cp1255,cp1256,cp1257,gb2312,"+ "euc-jp,euc-kr,euc-tw,big5,big5-hkscs,gbk,gb18030,shift_jis,johab,tis-620,"+ "viscii,georgian-ps,utf-8"; charset = read_with_completion (encodings, "Convert to? :", Charset, "", 's'); write_tmp_buffer (oldfile); vmessage ("converting to %s ...", charset); update (1); !if (0 == system (sprintf ("%s%s %s > %s", "msgconv --to-code=", charset, oldfile, newfile))) { () = delete_file (oldfile); () = delete_file (newfile); error ("syntax errors or locale not installed, could not convert"); } set_readonly (0); erase_buffer (); () = insert_file (newfile); () = delete_file (oldfile); () = delete_file (newfile); set_readonly (1); restore_entry_position (n); } define mark_fuzzy_all () { !if (get_y_or_n ("Flag all entries fuzzy")) return; if (NULL == prg_found_in_path ("msgattrib")) error ("msgattrib program not found in $PATH"); variable n = get_current_entry_number (); variable tmpfile = make_tmp_file ("/tmp/po_fuzzy_all"); variable cmd = sprintf ("%s > %s 2>/dev/null","msgattrib --set-fuzzy", tmpfile); flush ("flagging all translations fuzzy ..."); mark_buffer (); !if (0 == pipe_region (cmd)) { flush ("errors in current file"); restore_entry_position (n); () = delete_file (tmpfile); return; } set_readonly (0); erase_buffer (); () = insert_file (tmpfile); () = delete_file (tmpfile); set_readonly (1); restore_entry_position (n); po_statistics (); flush ("done"); } %}}} %{{{ source view, grep source, mail, spell check, help window, limit %% Get source references and return them as a formatted string static define po_mark_src_str () { push_spot (); narrow_to_entry (); !if (bol_fsearch ("#:")) { widen_region (); pop_spot (); error ("no source reference"); } push_mark (); while (looking_at ("#:")) { () = down (1); } bufsubstr (); str_replace_all("\n", " "); str_replace_all ("#: ", Null_String); strtrim (); % leave on stack widen_region (); pop_spot (); } %% Exit po_mode define edit_whole_buffer () { no_mode (); use_keymap ("global"); set_readonly (0); call ("redraw"); set_status_line ("", 0); flush ("use \"M-x po_mode\" to return"); } %% Set the path to source files define set_source_path () { variable s = read_with_completion ("Source dir:", "", "", 'f'); if (strlen (s)) { create_blocal_var ("Source_Dir"); set_blocal_var (s, "Source_Dir"); } } %% Pop up windows containing files from source references for viewing define view_source () { variable str, buf, ln, line, srcfile; variable cnt = 1; str = po_mark_src_str (); ln = length (strchop (str, ' ', 0)); foreach (strchop (str, ' ', 0)) { $0 = (); $1 = strchop ($0, ':', 0); buf = $1[0]; line = $1[1]; !if (blocal_var_exists ("Source_Dir")) { set_source_path (); } srcfile = path_concat (get_blocal_var ("Source_Dir"), buf); !if (1 == file_status (srcfile)) { vmessage ("Source file %s not found (use 'S' to set the path)", srcfile); return; } variable oldbuf = pop2buf_whatbuf (buf); () = insert_file (srcfile); set_buffer_modified_flag (0); set_readonly (1); goto_line (integer (line)); local_setkey ("close_file", "q"); c_mode (); onewindow (); if (ln > 1) { vmessage ("%s %d %s %d %s", "Source reference", cnt, "of", ln, "(space cycles, 'q' closes window, other key to scroll)"); while (cnt == ln) { vmessage ("%s %d %s %d %s", "Source reference", cnt, "of", ln, "(space or 'q' closes window, other key to scroll)"); break; } } else vmessage ("%s %d %s %d %s", "Source reference", cnt, "of", ln, "(space or 'q' closes window, other key to scroll)"); update (1); variable ch = getkey (); switch (ch) { ch == ' ': delbuf (buf); sw2buf (oldbuf); cnt++; } { ch == 'q': delbuf (buf); return; } { ch != ' ' or 'q': flush ("'q' closes window"); return; } } } %% Grep for a string in the source directory. Requires grep.sl define grep_src () { !if (blocal_var_exists ("Source_Dir")) { set_source_path (); } variable str, srcdir; if (markp ()) str = bufsubstr (); else str = po_mark_word (0); str = read_mini ("Search for:", str, ""); str = str_quote_string (str, "\\^$[]*.+\"", '\\'); str = "'" + str + "'"; srcdir = get_blocal_var ("Source_Dir"); grep (str, srcdir); call ("redraw"); } %% Toggle limitation of display to entries containing word or a string of words. define limit_view () { variable expr, matches = 0; if (View_Limit == 0) { entry_number = get_current_entry_number (); if (markp ()) expr = bufsubstr (); else expr = po_mark_word (0); expr = read_mini ("Limit to:", expr, ""); !if (strlen (expr)) return; push_spot_bob (); push_mark (); while (fsearch (expr)) { if (bfind ("#: ")) { eol (); continue; } position_on ("entry_start"); () = up (1); set_region_hidden (1); position_on ("entry_end"); () = down (1); push_mark (); matches++; } eob (); set_region_hidden (1); set_status_line (sprintf (" (PO) Limit: %d entries matching \"%s\"", matches, expr), 0); pop_spot (); flush ("'l' unlimits"); View_Limit = 1; } else { mark_buffer (); set_region_hidden (0); View_Limit = 0; set_po_status_line (); restore_entry_position (entry_number); recenter (0); } } %% Send po-file to the translation robot, language team or Debian BTS. define mail_po_file () { if (orelse { count ("u") != 0 } { count ("f") != 0 } { count ("o") != 0 }) !if (get_y_or_n ("Unprocessed entries remain, continue")) return; variable buf = whatbuf (); variable cmd = "gzip -9 | uuencode -m"; variable po_robot, debian_bts, recipient; variable file = strcat (buf + ".gz"); variable tmpfile = make_tmp_file ("/tmp/pomail"); variable package_file, package, version; po_robot = "The Free Translation Project "; debian_bts = "Debian Bug Tracking System "; % a canonical Debian file name is e.g. geneweb_4.10-4_da.po, where the first % part corresponds to the package name in the package database and the % second part to its version number. package_file = strchop (buf, '_', 0); if (length (package_file) == 3) { if (string_match (package_file[1], "[0-9]+", 1)) { package = package_file[0]; version = package_file[1]; } } else { package = ""; version = ""; } switch (get_mini_response ("Mail your team[t], translation robot[r] or Debian BTS[d] ?")) { case 't': recipient = 1; } { case 'r': recipient = 2; } { case 'd': recipient = 3; } { case not 't' or 'r' or 'd': flush ("no recipient!"); return; } !if (1 == recipient) { wrap_entries (0); % unwrap entries for robot write_tmp_buffer (tmpfile); !if (check_integrity (tmpfile)) { () = delete_file (tmpfile); error ("errors in file, use (V)alidate to find and then correct"); } !if (NULL == prg_found_in_path ("uuencode")) { push_spot (); mark_buffer (); () = pipe_region (sprintf ("%s > %s %s", cmd, tmpfile, file)); pop_spot (); } else { () = delete_file (tmpfile); error ("uuencode program not found"); } } else { wrap_entries (1); write_tmp_buffer (tmpfile); } recenter (1); mail (); switch (recipient) { case 1: insert (Language_Team); () = bol_fsearch ("Subject:"); eol (); insert (read_mini ("Subject:", buf, "")); } { case 2: insert (po_robot); () = bol_fsearch ("Subject:"); eol (); % mandatory subject when submitting files to robot vinsert ("%s %s", "TP-Robot", buf); } { case 3: insert (debian_bts); () = bol_fsearch ("Subject:"); eol (); insert (read_mini ("Subject:", "", "")); eob (); newline (); package = read_mini ("Package name:", package, ""); !if (strlen (package)) { () = delete_file (tmpfile); error ("you must specify the name of the package"); } flush (sprintf ("looking up \"%s\" in package database ...", package)); !if (0 == system (sprintf ("dpkg -l %s >/dev/null 2>&1", package))) { () = delete_file (tmpfile); verror ("package \"%s\" does not exist in package database", package); } vinsert ("Package: %s\n", package); version = read_mini ("Version number? (ok to leave blank):", version, ""); if (strlen (version)) vinsert ("Version: %s\n", version); insert ("Severity: wishlist\nTags: patch l10n"); } eob (); newline (); push_spot (); if (3 == recipient) { insert ("\nUuencoded file follows. Please pipe mail to\n" + "uudeview or uudecode program to extract file.\n\n"); } () = insert_file (tmpfile); () = delete_file (tmpfile); flush ("type \"M-x mail_send\" to send"); pop_spot (); } %% Display help window define show_help () { variable file = expand_jedlib_file ("po_mode.hlp"); !if (1 == file_status (file)) { vmessage ("The file %s was not found in Jed's library path", file); return; } () = find_file (file); most_mode (); flush ("scroll down for more. 'q' closes help window"); } %% Send a bug report define reportbug () { mail (); insert ("Morten Bo Johansen "); () = bol_fsearch ("Subject:"); eol (); insert ("[po_mode] "); } %% Interactively spell check msgstrs with ispell or aspell. If xjed is used, %% the interactive spelling process will be opened in a separate terminal %% window define po_spellcheck () { if (count ("t") == 0) return flush ("nothing to spell check"); if (NULL == prg_found_in_path ("pospell")) return flush ("spellutils not installed or $PATH is incomplete"); if (NULL == prg_found_in_path (Spell_Prg)) return vmessage ("%s %s", Spell_Prg, "not found in $PATH"); variable TermPrg; !if (NULL == prg_found_in_path ("rxvt")) TermPrg = "rxvt -e "; else TermPrg = "xterm -e "; variable tmpfile, aspell_cmd, ispell_cmd, line, status; variable n = get_current_entry_number (); tmpfile = make_tmp_file ("/tmp/spellfile"); aspell_cmd = strcat ("pospell -n ", tmpfile, " -p ", Spell_Prg, " -- -c -d ", Spell_Dict, " %f"); ispell_cmd = strcat ("pospell -n ", tmpfile, " -p ", Spell_Prg, " -- -x -C -d ", Spell_Dict, " %f"); write_tmp_buffer (tmpfile); if (Spell_Prg == "ispell") { if (is_defined ("x_server_vendor")) status = system (strcat (TermPrg, ispell_cmd)); else status = run_program (ispell_cmd); } if (Spell_Prg == "aspell") { if (is_defined ("x_server_vendor")) status = system (strcat (TermPrg, aspell_cmd)); else status = run_program (aspell_cmd); } set_readonly (0); erase_buffer (); () = insert_file (tmpfile); set_readonly (1); restore_entry_position (n); () = delete_file (tmpfile); () = system (sprintf ("%s %s", "rm >/dev/null 2>&1", "/tmp/newsbody*")); if (status > 11) flush ("spell checking failed"); } %}}} %{{{ wordlists %% Strip regular verbs of conjugations so they appear in the infinitive form, %% nouns of plural endings so they appear in singular and adjectives of %% their adverbial endings. The rules have been checked against about 10 MB of %% po-files and litterature text from the Gutenberg project and they get it %% right about 99.5% of the time. Nontheless a few of the rules are somewhat %% crude, so in the actual lookup in the wordlist, lookup is performed for %% word in both verbatim and stripped forms. static define strip_word (word) { word = strlow (word); variable word_1, word_2, word_3, word_4, char_1, char_2, char_3, char_4; (word_1, char_1) = strip_chars (word, 1); (word_2, char_2) = strip_chars (word, 2); (word_3, char_3) = strip_chars (word, 3); (word_4, char_4) = strip_chars (word, 4); forever { % e.g. ponies -> pony, tried -> try if (string_match (word, "ie[ds]$", 1)) { if (is_list_element ("series", word, ',')) break; if (strlen (word) < 5) { word = word_1; break; } word = word_3 + "y"; break; } % ****** PLURAL NOUNS AND THIRD PERSON SINGULAR VERBS ****** if (string_match (word, "[^aious]s$", 1)) { word = word_1; break; } % ****** ING FORM ****** if (string_match (word, "ing$", 1)) { if (0 == strcmp (char_3, char_4)) { word = word_4; break; } word = word_3 + "e"; break; } % ****** ADVERBS ****** if (string_match (word, "ly$", 1)) { word = word_2; break; } % ****** (mostly) REGULAR PAST TENSE VERBS ******* if (string_match (word, "[^e]ed$", 1)) { if (string_match (word, "^un", 1)) break; if (is_list_element ("bled,fed,bred,sped", word, ',')) { word = word_2 + "eed";; break; } % double consonant words like "begged", "hopped" etc. if (0 == strcmp (char_2, char_3) and char_2 != "l") { if (orelse {char_3 == "f"}{char_3 == "o"}{char_3 == "s"}) { word = word_2; break; } word = word_3; break; } if (is_list_element ("y,w,x", char_2, ',')) { word = word_2; break; } if (is_list_element ("c,u,v,z", char_2, ',')) { word = word_1; break; } switch (char_2) { case "b": if (is_list_element ("bed,deathbed,embed", word, ',')) break; if (string_match (word, "[aeiou]bed$", 1)) word = word_1; else word = word_2; break; } { case "d": if (string_match (word, "[^aeo][aeiou]ded$", 1)) word = word_1; else word = word_2; break; } { case "f": if (string_match (word, "[^a]fed$", 1)) word = word_2; else word = word_1; break; } { case "g": if (orelse { is_list_element ("clanged,fanged,hanged,ringed", word, ',') } { string_match (word, "onged$", 1) } ) { word = word_2; break; } word = word_1; break; } { case "h": if (is_list_element ("shed,bloodshed,openmouthed", word, ',')) break; if (string_match (word, "[aei]thed$", 1)) { word = word_1; break; } if (string_match (word, "[^eot][ae]ched$", 1)) { word = word_1; break; } word = word_2; break; } { case "k": if (is_list_element ("crooked,naked", word, ',')) break; if (string_match (word, "[^eo][aio]ked$", 1)) word = word_1; else word = word_2; break; } { case "l": if (is_list_element ("led,fled,sled", word, ',')) break; if (0 == strcmp (char_2, char_3)) { if (strlen (word) <= 8 ) { word = word_2; break; } if (string_match (word, "[^ctw][aeiou]lled$", 1)) word = word_3; else word = word_2; break; } if (string_match (word, "[bcdfgkpstz]led$", 1)) { word = word_1; break; } if (string_match (word, "[^aeno][aciouy]led$", 1)) word = word_1; else word = word_2; break; } { case "m": if (string_match (word, "[^aeot][aeiou]med$", 1)) word = word_1; else word = word_2; break; } { case "n": if (string_match (word, "[^adeikost][aiou]ned$", 1)) word = word_1; else word = word_2; break; } { case "o": if (string_match (word, "[^t]oed$", 1)) word = word_2; else word = word_1; break; } { case "p": if (string_match (word, "[^e][aiy]ped$", 1)) word = word_1; else word = word_2; break; } { case "r": if (is_list_element ("goodnatured,red,hatred,hundred,kindred,sacred,shred", word, ',')) break; if (string_match (word, "[acinou][bhlnpst]ored$", 1)) { word = word_2; break; } if (string_match (word, "[^ameov][aiovu]red$", 1)) word = word_1; else word = word_2; break; } { case "s": if (is_list_element ("aliased,biased,antialiased", word, ',')) { word = word_2; break; } if (string_match (word, "sed$", 1)) word = word_1; break; } { case "t": if (string_match (word, "[^aeko][aeou]ted$", 1)) word = word_1; else word = word_2; break; } } break; } return word; } static define run_dict_checks (word) { if (NULL == prg_found_in_path ("iconv")) dict_error_msg = "iconv program not present"; else if (NULL == prg_found_in_path ("dict")) dict_error_msg = "dict client program not installed"; else !if (string_match (Dict_Dictionary, "^fd-.*", 1)) dict_error_msg = "you must use one of the Freedict translation" + "dictionaries, e.g \"fd-eng-deu\""; variable dict_cmd = "dict -P - -C -d"; variable status; status = run_shell_cmd (sprintf ("%s %s %s >/dev/null 2>&1", dict_cmd, Dict_Dictionary, word)); switch (status) { case 22: dict_error_msg = "No databases available"; } { case 30: dict_error_msg = "Unexpected response code from server"; } { case 31: dict_error_msg = "Server is temporarily unavailable"; } { case 37: dict_error_msg = "Access denied"; } { case 39: dict_error_msg = "Invalid database"; } { case 41: dict_error_msg = "Connection to server failed"; } dict_checks = 1; } %% Look up a word translation in a freedict dictionary and return the result. static define dict_lookup_word (word) { variable trans = "", def = "", cmd = ""; variable grep_cmd = "egrep \" [a-zA-Z\\(]\""; variable dict_cmd = "dict -P - -C -d"; variable fp, status; variable word_stripped = strip_word (word); % At least in the English/German dict wordlist, sometimes the % verbs are listed as "to " and searches will fail if you % omit the "to" prefix, so search for word both with and % without the "to" prefix, as well as word in stripped form. % This will create some duplicates in the output , but they are % removed again in lookup_word () !if (is_substr (word, " ")) word = sprintf ("%s %s \"to %s\"", word, word_stripped, word_stripped); if (dict_checks == 0) { run_dict_checks (word); if (strlen (dict_error_msg)) { return Null_String; } } cmd = sprintf ("%s %s %s | %s | iconv -f utf8 -t %s", dict_cmd, Dict_Dictionary, word, grep_cmd, Charset); fp = popen (cmd, "r"); if (fp != NULL) { () = fread (&trans, String_Type, 1000, fp); } () = pclose (fp); trans = str_replace_all (trans, "\n", ","); return trans; } %% Look up word in a custom wordlist. Look up word both verbatim and stripped static define custom_lookup_word (word) { variable buf = whatbuf (); variable wordlist_buf = path_basename (Custom_Wordlist); variable trans = "", word_stripped = ""; !if (1 == file_status (Custom_Wordlist)) { vmessage ("wordlist %s not found", Custom_Wordlist); return trans; } word = strtrim (word, "\""); word_stripped = strip_word (word); if (bufferp (wordlist_buf)) { setbuf (wordlist_buf); bob (); } else { () = read_file (Custom_Wordlist); } bury_buffer (wordlist_buf); while (bol_fsearch (word + ":")) { () = ffind (":"); skip_chars (": \t"); push_mark_eol (); trans += bufsubstr () + ","; } bob (); while (bol_fsearch (word_stripped + ":")) { () = ffind (":"); skip_chars (": \t"); push_mark_eol (); trans += bufsubstr () + ","; } setbuf (buf); return trans; } %% Look up translation for a word in a custom wordlist. If word is not %% found there, then look it up in a dict dictionary of choice. It is bound %% to a double click with the mouse or 'd'. See po_mode.hlp on format of %% custom wordlist. define lookup_word (word, auto) { variable def = "", tran = "", trans = "", ctrans = "", dtrans = ""; variable word_stripped = strip_word (word); variable prompt; !if (strlen (word)) { if (markp ()) word = sprintf ("\"%s\"", bufsubstr ()); else word = po_mark_word (0); } word = strlow (word); prompt = sprintf ("%s ->:", word); switch (Use_Wordlist) { case 1: ctrans = custom_lookup_word (word); } { case 2: if (strlen (word) >= Dict_Minimum_Wordsize) { dtrans = dict_lookup_word (word); if (strlen (dict_error_msg)) error (dict_error_msg); } } { case 3: !if (strlen (dict_error_msg)) { if (strlen (word) >= Dict_Minimum_Wordsize) { dtrans = dict_lookup_word (word); } } ctrans = custom_lookup_word (word); } ERROR_BLOCK { if (nwindows == 2 and "PO" == get_mode_name) otherwindow (); error ("quit"); } trans = strcat (ctrans, ",", dtrans); trans = strcompress (trans, " "); trans = str_replace_all (trans, ", ", ","); trans = strtrim (trans, ","); trans = strchop (trans, ',', 0); def = trans [0]; trans = sort_uniq (trans); % sort and remove duplicates trans = strjoin (trans, ","); if (auto) return def; !if (strlen (def)) verror ("no translation for \"%s\"", word); tran = read_with_completion (trans, prompt, def, "", 's'); if (nwindows == 2 and "PO" == get_mode_name) { otherwindow (); insert (tran + " "); } else { po_edit (); insert (tran + " "); po_end_edit (); !if (is_fuzzy ()) fuzzy_or_obsolete_entry (); recenter (0); } if (strlen (dict_error_msg)) { flush (sprintf ("dict: %s", dict_error_msg)); } } static define po_mouse_2click_hook (line, col, but, shift) { lookup_word (Null_String, 0); return (0); } %% Look up translation for every word in every msgid define wordlist_lookup_all () { flush ("Use Wordlist(s)?: 1 = custom, 2 = dict, 3 = both, q = abort" ); switch (getkey ()) { case '1': Use_Wordlist = 1; } { case '2': Use_Wordlist = 2; } { case '3': Use_Wordlist = 3; } { case 'q': return flush ("quit"); } variable all_translations = Assoc_Type[String_Type]; variable idword = "", idwords = "", tran = ""; variable u = get_blocal_var ("untranslated"); variable n = 0; push_spot_bob (); po_next_entry (); set_readonly (0); while (bol_fsearch ("msgstr ")) { !if (is_untranslated ()) continue; n++; flush (sprintf ("getting translations for words in msgid %d of %d ...", n, u)); variable translations = ""; idwords = strlow (format_string (msg_as_string (0))); foreach (strchop (idwords, ' ', 0)) { idword = (); % if word has a "-" prepended it will act as an "argument" to dict idword = strtrim (idword, "-"); if (assoc_key_exists(all_translations, idword)) tran=all_translations[idword]; else { tran = lookup_word (idword, 1); all_translations[idword]=tran; } if (strlen (tran)) translations += tran + " "; } position_on ("msgstr"); () = ffind ("\""); () = right (1); insert (translations); fuzzy_or_obsolete_entry (); eol (); set_readonly (0); } pop_spot (); po_statistics (); set_po_status_line (); set_readonly (1); if (strlen (dict_error_msg)) { flush (sprintf ("dict: %s", dict_error_msg)); } } %% Pop up a buffer with all available dict definitions on word at point define dict_lookup_all_def () { variable word = po_mark_word (0); !if (strlen (word)) return; pop2buf ("*DICT DEFINITIONS*"); onewindow; if (20 == run_shell_cmd (sprintf ("dict %s", word))) { set_buffer_modified_flag (0); delbuf (whatbuf ()); error ("No matches found"); } set_buffer_modified_flag (0); most_mode (); bob (); create_syntax_table ("dict"); dfa_define_highlight_rule ("^From.*:$", "keyword", "dict"); dfa_build_highlight_table ("dict"); use_syntax_table ("dict"); use_dfa_syntax (1); } %}}} %{{{ compendiums variable good_files, bad_files; static define del_msgid_ext_ascii () { set_readonly (0); variable msgid = ""; while (bol_fsearch ("msgid")) { msgid = msg_as_string (0); if (string_match (msgid, "[^A-Za-z0-9!\\[\\]\^\|\?\.\\-\"\*\+\(\)#\$%&',/:;<=>@`{}~_ \t\n\r\\\\]", 1)) { mark ("entry"); del_region (); loop (2) del (); } else { eol (); continue; } } } %% Create string arrays of po-files in a directory and check their integrity %% with the gettext tools, possibly resulting in one array containing good %% files and another containing bad/corrupt files. static define po_listdir () { variable dir, file, filelist, nfiles, po_files; variable exts, po_matches, ok; variable i; dir = read_with_completion ("directory with po-files:", "", "", 'f'); filelist = listdir (dir); exts = array_map (String_Type, &path_extname, filelist); po_matches = where (0 == array_map (Int_Type, &strcmp, exts, ".po")); nfiles = length (po_matches); if (nfiles == 0) { flush (sprintf ("no po-files in %s", dir)); return 0; } switch (Use_Compendium) { case 1: flush (sprintf ("Add %d files to %s? [y/n]", nfiles, Compendium)); } { case 2: flush (sprintf ("Add %d files to %s? [y/n]", nfiles, Compendium_Gettext)); } { case 3: flush (sprintf ("Add %d files to %s and %s? [y/n]", nfiles, Compendium, Compendium_Gettext)); } if ('y' == getkey ()); else { update (1); return 0; } po_files = filelist [po_matches]; po_files = po_files [array_sort (po_files)]; _for (0, nfiles-1, 1) { i = (); file = po_files [i]; po_files [i] = dircat (dir, file); } ok = array_map (Int_Type, &check_integrity (), po_files); good_files = po_files [where (ok)]; bad_files = po_files [where (not ok)]; nfiles = length (good_files); if (nfiles == 0) { flush ("found no good files to add to compendium"); return 0; } return 1; } %% Creates a native compendium file from current buffer with comments, fuzzy %% and untranslated entries removed, formatted and sorted. define update_native_compendium (sort) { if (count ("t") == 0) return flush ("no translated entries"); if (search_file (Compendium, "msgid \"\"", 1)) return flush ("looks like a gettext compendium, not used"); variable file, str; variable i = 0, n = 0; (file,,,) = getbuf_info (whatbuf); flush (sprintf ("adding %s to %s ...", file, Compendium)); push_spot_bob (); po_next_entry (); while (bol_fsearch ("msgstr ")) { if (is_untranslated () or is_fuzzy ()) continue; else n++; } str = String_Type[n]; bob (); po_next_entry (); while (bol_fsearch ("msgstr ")) { if (is_untranslated () or is_fuzzy ()) continue; else { mark ("strings"); str[i] = bufsubstr (); i++; } } str = array_map (String_Type, &str_replace_all, str, "msgid ", Null_String); str = array_map (String_Type, &str_replace_all, str, "msgstr ", ""); str = array_map (String_Type, &format_string, str); str = strjoin (str, "\n"); () = append_string_to_file (str + "\n", Compendium); if (sort) { flush ("sorting native compendium ..."); variable tmpfile = make_tmp_file ("/tmp/update_native_compendium"); () = system (sprintf ("%s %s > %s", "sort -uf", Compendium, tmpfile)); () = copy_file (tmpfile, Compendium); () = delete_file (tmpfile); } update (1); pop_spot (); } static define prep_gettext_compendium () { if (NULL == prg_found_in_path ("msgcat")) { flush ("gettext utilities not installed"); return 0; } variable flags, name, buf; buf = whatbuf (); !if (1 == file_status (Compendium_Gettext)) { () = read_file (Compendium_Gettext); (,, name, flags) = getbuf_info (); if (flags & 8) { delbuf (name); flush (sprintf ("writing to %s not allowed", Compendium_Gettext)); return 0; } else { insert_po_header (); replace_headers (); save_buffer (); delbuf (name); sw2buf (buf); } } else { !if (search_file (Compendium_Gettext, "msgid \"\"", 1)) { flush ("does not look like a gettext compendium, not used"); return 0; } flush (sprintf ("Overwrite matching entries in %s [y/n]", Compendium_Gettext)); if ('y' == getkey ()) { Overwrite_Compendium = 1; } else { Overwrite_Compendium = 0; } } update (1); return 1; } %% Add a directory of po-files to native compendium. static define add_dir_to_native_compendium () { variable file; variable tmpfile = make_tmp_file ("/tmp/update_native_compendium"); variable nfiles = length (good_files); foreach (good_files) { file = (); () = read_file (file); update_native_compendium (0); nfiles--; flush (sprintf ("%d file(s) remaining ..", nfiles)); sleep (0.2); delbuf (whatbuf ()); } flush ("sorting compendium ..."); () = system (sprintf ("%s %s > %s", "sort -uf", Compendium, tmpfile)); () = copy_file (tmpfile, Compendium); () = delete_file (tmpfile); flush (sprintf ("%d files added to %s", length (good_files), Compendium)); } %% Fill in translations from native compendium file static define init_with_native_compendium () { !if (1 == file_status (Compendium)) verror ("compendium file \"%s\" not found.", Compendium); variable msgid, msgstr_cmpd; variable buf = whatbuf (); variable cbuf = path_basename (Compendium); () = read_file (Compendium); setbuf (buf); vmessage ("getting translations from %s ...", Compendium); update (1); push_spot_bob (); po_next_entry (); forever { msgid = msg_as_string (0); msgid = format_string (msgid); setbuf (cbuf); bob (); if (bol_fsearch (msgid+"")) { () = ffind (""); () = right (1); push_mark_eol (); msgstr_cmpd = bufsubstr (); setbuf (buf); () = bol_fsearch ("msgstr "); if (is_translated ()) { if (bol_fsearch ("msgid ")) continue; else break; } else { () = right (1); if (strlen (msgstr_cmpd)) { insert (msgstr_cmpd); fuzzy_or_obsolete_entry (); set_readonly (0); } if (bol_fsearch ("msgid ")) continue; else break; } } else { setbuf (buf); eol (); if (bol_fsearch ("msgid ")) continue; else break; } } pop_spot (); delbuf (cbuf); } %% Update the compendium with contents of the current buffer static define update_gettext_compendium () { if (count ("t") == 0) return flush ("no translated entries"); !if (prep_gettext_compendium) return; variable oldfile, newfile; variable msgcat_cmd, msgattrib_cmd, cmd; newfile = make_tmp_file ("/tmp/po_newfile"); oldfile = make_tmp_file ("/tmp/po_oldfile"); msgcat_cmd = "msgcat 2>/dev/null --sort-output --use-first --no-location --to-code="; msgattrib_cmd = "msgattrib --no-location --translated --no-fuzzy --clear-obsolete 2>/dev/null"; if (Overwrite_Compendium == 1) { cmd = sprintf ("%s%s %s %s | %s >%s", msgcat_cmd, Charset, oldfile, Compendium_Gettext, msgattrib_cmd, newfile); } else { cmd = sprintf ("%s%s %s %s | %s >%s", msgcat_cmd, Charset, Compendium_Gettext, oldfile, msgattrib_cmd, newfile); } write_tmp_buffer (oldfile); !if (check_integrity (oldfile)) { () = delete_file (oldfile); error ("errors in this file, compendium not updated"); } vmessage ("updating %s ...", Compendium_Gettext); update (1); !if (0 == system (cmd)) error ("some error occured, perhaps syntax errors?"); if (file_size (newfile) == 0) { flush ("some error occurred, gettext compendium not updated ..."); return; } else { () = copy_file (newfile, Compendium_Gettext); () = read_file (Compendium_Gettext); replace_headers (); save_buffer (); delbuf (whatbuf ()); flush ("gettext compendium succesfully updated"); } () = delete_file (oldfile); () = delete_file (newfile); } %% Add a directory of po-files to the gettext compendium. static define add_dir_to_gettext_compendium () { !if (prep_gettext_compendium) return; variable msgattrib_file, ctemp_file, str_good_files; variable msgcat_cmd, msgattrib_cmd; variable nfiles = length (good_files); variable status; msgattrib_file = make_tmp_file ("/tmp/po_msgattrib"); ctemp_file = make_tmp_file ("/tmp/po_ctempfile"); msgcat_cmd = "msgcat 2>/dev/null --sort-output --use-first --no-location --to-code="; msgattrib_cmd = "msgattrib 2>/dev/null --no-location --translated --no-fuzzy --clear-obsolete"; str_good_files = strjoin (good_files, " "); flush (sprintf( "adding %d files to %s ...", nfiles, Compendium_Gettext)); if (Overwrite_Compendium == 1) { status = system (sprintf ("%s%s %s %s > %s", msgcat_cmd, Charset, str_good_files, Compendium_Gettext, ctemp_file)); } else { status = system (sprintf ("%s%s %s %s > %s", msgcat_cmd, Charset, Compendium_Gettext, str_good_files, ctemp_file)); } !if (status == 0) error ("could not concatenate files"); flush ("cleaning up gettext compendium ..."); status = system (sprintf ("%s %s > %s", msgattrib_cmd, ctemp_file, msgattrib_file)); if (status == 0) { () = copy_file (msgattrib_file, Compendium_Gettext); () = read_file (Compendium_Gettext); replace_headers (); save_buffer (); delbuf (whatbuf ()); flush ("gettext compendium succesfully updated"); } else flush ("error, gettext compendium not updated"); () = delete_file (msgattrib_file); () = delete_file (ctemp_file); } %% Merge translations from a compendium file into po-file, using the gettext %% msgmerge program. static define init_with_gettext_compendium () { !if (1 == file_status (Compendium_Gettext)) verror ("\"%s\" not found.", Compendium_Gettext); variable status, oldfile, newfile; variable n = get_current_entry_number (); oldfile = make_tmp_file ("/tmp/po_oldfile"); newfile = make_tmp_file ("/tmp/po_newfile"); if (count ("o") > 0) { flush ("removing obsolete entries ..."); push_spot (); mark_buffer (); !if (0 == pipe_region (sprintf ("%s > %s", "msgattrib --no-obsolete", oldfile))) { flush ("errors in current file"); pop_spot (); return; } pop_spot (); } else { write_tmp_buffer (oldfile); } vmessage ("getting translations from %s ...", Compendium_Gettext); update (1); if (Gettext_Use_Fuzzy == 0) status = system (sprintf ("%s%s -o %s /dev/null %s >/dev/null 2>&1", "msgmerge -q --no-fuzzy-matching --compendium=", Compendium_Gettext, newfile, oldfile)); else status = system (sprintf ("%s%s -o %s /dev/null %s >/dev/null 2>&1", "msgmerge -q --compendium=", Compendium_Gettext, newfile, oldfile)); if (status != 0) error ("some error occured, perhaps syntax errors in compendium?"); erase_buffer (); () = insert_file (newfile); () = delete_file (oldfile); () = delete_file (newfile); restore_entry_position (n); } %% Overwrite a translation in the gettext compendium with translation for %% current msgid if it exists, else add entry to compendium define make_preferred_gettext () { if (Use_Compendium == 1) { flush ("not implemented"); return; } variable po_buf = whatbuf (); variable compendium_buf = path_basename (Compendium_Gettext); variable msgstr, msgid, msgid_compendium, entry, str; msgstr = msg_as_string (1); if (strlen (msgstr) == 2) { flush ("untranslated entry"); return; } !if (bufferp (compendium_buf)) { () = read_file (Compendium_Gettext); } setbuf (po_buf); msgid = msg_as_string (0); str = substr (msgid, 1, 20); pop_spot (); setbuf (compendium_buf); bob (); forever { if (fsearch (str)) { msgid_compendium = msg_as_string (0); if (0 == strcmp (msgid, msgid_compendium)) { del_msgstr (); insert (msgstr); () = save_buffer (); vmessage ("msgstr in %s overwritten", Compendium_Gettext); return; } else { eol (); continue; } } else break; } setbuf (po_buf); narrow_to_strings (); mark_buffer (); widen_region (); entry = "\n" + bufsubstr (); setbuf (compendium_buf); eob (); insert (entry); () = save_buffer (); vmessage ("entry added to %s", Compendium_Gettext); } define gettext_fuzzy_match () { if (Use_Compendium == 1) { flush ("not implemented"); return; } variable po_buf = whatbuf (); variable compendium_buf = path_basename (Compendium_Gettext); variable msgid, msgstr, str; !if (bufferp (compendium_buf)) { !if (read_file (Compendium_Gettext)) verror ("could not read %s", Compendium_Gettext); } setbuf (po_buf); push_spot (); msgid = msg_as_string (0); str = format_string (msgid); str = substr (str, 1, 20); setbuf (compendium_buf); bob (); if (fsearch (str)) { mark ("msgstr"); msgstr = bufsubstr (); setbuf (po_buf); set_readonly (0); del_msgstr (); insert (msgstr); fuzzy_or_obsolete_entry (); set_readonly (1); } else flush ("not found"); setbuf (po_buf); pop_spot (); set_po_status_line (); } define edit_compendium () { switch (Use_Compendium) { case 1: () = find_file (Compendium); } { case 2: () = find_file (Compendium_Gettext); } { case 3: () = find_file (Compendium); () = find_file (Compendium_Gettext); } } define init_with_compendiums () { flush ("Initialize with translations from compendium(s)? [y/n]"); !if ('y' == getkey ()) return update (1); set_readonly (0); switch (Use_Compendium) { case 1: init_with_native_compendium (); } { case 2: init_with_gettext_compendium (); } { case 3: init_with_gettext_compendium (); sleep (1); init_with_native_compendium (); } set_readonly (1); po_statistics (); flush ("done"); } define update_compendiums () { switch (Use_Compendium) { case 1: vmessage ("Update %s? [y/n]", Compendium); update (1); !if ('y' == getkey ()) return; update_native_compendium (1); } { case 2: vmessage ("Update %s? [y/n]", Compendium_Gettext); update (1); !if ('y' == getkey ()) return; update_gettext_compendium (); } { case 3: vmessage ("Update %s and %s? [y/n]", Compendium, Compendium_Gettext); update (1); !if ('y' == getkey ()) return; update_native_compendium (1); update_gettext_compendium (); } } define add_dir_to_compendium () { !if (po_listdir ()) return; variable str_bad_files = strjoin (bad_files, "\n"); switch (Use_Compendium) { case 1: add_dir_to_native_compendium (); } { case 2: add_dir_to_gettext_compendium (); } { case 3: add_dir_to_gettext_compendium (); add_dir_to_native_compendium (); } if (strlen (str_bad_files)) { pop2buf ("*corrupt files*"); insert ("The following file(s) either had syntax errors or " + "errors in\ncharacter set conversion and were not " + "added to the compendium(s):\n\n" + str_bad_files); bob (); most_mode (); !if (get_y_or_n ("Load file(s) to check for errors with the (V)alidate command")) return; variable file; foreach (bad_files) { file = (); () = find_file (file); onewindow (); } } } %}}} %{{{ dfa syntax and colors static variable bg = ""; #ifdef HAS_DFA_SYNTAX %%% DFA_CACHE_BEGIN %%% create_syntax_table (mode); static define setup_dfa_callback (mode) { (, bg) = get_color ("normal"); % that dfa backgr. fits with user's color add_color_object ("strings"); add_color_object ("srccomment"); add_color_object ("flagcomment"); add_color_object ("autocomment"); add_color_object ("usercomment"); add_color_object ("lbreak"); add_color_object ("begblank"); add_color_object ("endblank"); % For Xjed. You could use RGB color codes here if you wanted. if (is_defined ("x_server_vendor")) { set_color ("strings", "magenta", bg); set_color ("srccomment", "gray", bg); set_color ("flagcomment", "red", bg); set_color ("autocomment", "gray", bg); set_color ("usercomment", "black", "green"); set_color ("lbreak","magenta", bg); set_color ("begblank","black", "cyan"); set_color ("endblank","black", "cyan"); } else { set_color ("strings", "magenta", bg); set_color ("srccomment", "gray", bg); set_color ("flagcomment", "red", bg); set_color ("autocomment", "gray", bg); set_color ("usercomment", "black", "green"); set_color ("lbreak","magenta", bg); set_color ("begblank","black", "cyan"); set_color ("endblank","black", "cyan"); } dfa_enable_highlight_cache ("po.dfa", mode); dfa_define_highlight_rule ("^msg(id|str)", "strings", mode); dfa_define_highlight_rule ("^#[,]+.*", "flagcomment", mode); dfa_define_highlight_rule ("^#[:]+.*", "srccomment", mode); dfa_define_highlight_rule ("^#[\\.]+.*", "autocomment", mode); dfa_define_highlight_rule ("^#[ \t]+.*", "usercomment", mode); dfa_define_highlight_rule ("\"[ ]+", "begblank", mode); dfa_define_highlight_rule ("[ \t]+\\\\?n?\"$", "endblank", mode); dfa_define_highlight_rule ("\\\\n", "lbreak", mode); dfa_build_highlight_table (mode); enable_dfa_syntax_for_mode (mode); } dfa_set_init_callback (&setup_dfa_callback, mode); %%% DFA_CACHE_END %%% #endif %}}} %{{{ menu static define po_menu (menu) { menu_append_popup (menu, "&Navigate"); $0 = menu + ".&Navigate"; { menu_append_item ($0, "Top Justify Entry", "top_justify_entry"); menu_append_item ($0, "Go to Entry Number", "goto_entry"); menu_append_item ($0, "Show Current Entry Number", "show_current_entry_number"); menu_append_item ($0, "Next Entry", "po_next_entry"); menu_append_item ($0, "Previous Entry", "po_previous_entry"); menu_append_item ($0, "Next Untranslated", "find_untranslated"); menu_append_item ($0, "Previous Untranslated", "bfind_untranslated"); menu_append_item ($0, "Next Translated", "find_translated"); menu_append_item ($0, "Previous Translated", "bfind_translated"); menu_append_item ($0, "Next Fuzzy", "find_fuzzy"); menu_append_item ($0, "Previous Fuzzy", "bfind_fuzzy"); menu_append_item ($0, "Next Obsolete", "find_obsolete"); menu_append_item ($0, "Previous Obsolete", "bfind_obsolete"); menu_append_item ($0, "Next Translator Comment", "find_translator_comment"); } menu_append_popup (menu, "&Modify"); $1 = menu + ".&Modify"; { menu_append_item ($1, "Undo", "po_undo"); menu_append_item ($1, "Edit Msgstr", "po_edit"); menu_append_item ($1, "Replace Headers", "replace_headers"); menu_append_item ($1, "Copy Msgstr", "copy_msgstr"); menu_append_item ($1, "Insert Msgstr", "insert_msgstr"); menu_append_item ($1, "Copy Msgid To Msgstr", "copy_msgid_to_msgstr"); menu_append_item ($1, "Cut Msgstr", "cut_msgstr"); menu_append_item ($1, "Flag Entry As Fuzzy", "fuzzy_or_obsolete_entry"); menu_append_item ($1, "Flag All Entries Fuzzy", "flag_fuzzy_all"); menu_append_item ($1, "Remove Fuzzy Flag", "remove_fuzzy_flag"); menu_append_item ($1, "Delete Obsolete Entry", "del_obsolete"); menu_append_item ($1, "Remove Obsolete Flag", "unobsolete_entry"); menu_append_item ($1, "Edit Comment", "edit_comment"); menu_append_item ($1, "Delete Comment", "del_translator_comment"); menu_append_item ($1, "Edit Entire File", "edit_whole_buffer"); menu_append_item ($1, "Spell Check", "po_spellcheck"); menu_append_item ($1, "Replace in Msgstrs", "replace_in_msgstrs"); } menu_append_popup (menu, "&Gettext functions"); $2 = menu + ".&Gettext functions"; { menu_append_item ($2, "Compile *.po -> *.mo", "po_compile"); menu_append_item ($2, "Decompile *.mo -> *.po", "po_decompile"); menu_append_item ($2, "Validate", "po_validate_command"); menu_append_item ($2, "Update", "po_file_update"); menu_append_item ($2, "Unwrap Entries", "wrap_entries (0)"); menu_append_item ($2, "Wrap Entries", "wrap_entries (1)"); menu_append_item ($2, "Change Encoding", "conv_charset"); } menu_append_popup (menu, "&Compendiums and Wordlists"); $3 = menu + ".&Compendiums and Wordlists"; { menu_append_item ($3, "Add Buffer To Compendium(s)", "update_compendiums"); menu_append_item ($3, "Add Dir to Compendium(s)", "add_dir_to_compendium"); menu_append_item ($3, "Initialize w/Compendium(s)", "init_with_compendiums"); menu_append_item ($3, "Make Translation Preferred", "make_preferred_gettext"); menu_append_item ($3, "Fetch Fuzzy Translation", "gettext_fuzzy_match"); menu_append_item ($3, "Edit Compendium(s)", "edit_compendium"); menu_append_item ($3, "Look up word in wordlist", "lookup_word (Null_String, 0)"); menu_append_item ($3, "Look up all words in wordlist", "wordlist_lookup_all"); } menu_append_item (menu, "Show Help", "show_help"); menu_append_item (menu, "Statistics", "show_po_statistics"); menu_append_item (menu, "Mail Robot or Team", "mail_po_file"); menu_append_item (menu, "Set Source Path", "set_source_path"); menu_append_item (menu, "View Source Reference", "view_source"); menu_append_item (menu, "Grep in Source Directory", "grep_src"); menu_append_item (menu, "Toggle Limited View", "limit_view"); menu_append_item (menu, "Send Bug Report", "reportbug"); } %}}} %{{{ keymaps % Emulations "edt" and "wordstar" have no _Reserved_Key_Prefix, % set it to Ctrl-C if (_Jed_Emulation == "edt" or _Jed_Emulation == "wordstar") { _Reserved_Key_Prefix = "\003"; } !if (keymap_p ("po_comment")) { make_keymap ("po_comment"); definekey ("enlargewin", "^[-", "po_comment"); % esc + definekey ("decreasewin", "^[/", "po_comment"); % esc - if (NULL != getenv ("DISPLAY")) { definekey ("enlargewin", "^[+", "po_comment"); definekey ("decreasewin", "^[-", "po_comment"); } definekey ("po_end_edit_comment", "\t", "po_comment"); definekey_reserved ("po_end_edit_comment", "^C", "po_comment"); definekey_reserved ("cancel_editbuf", "^K", "po_comment"); } !if (keymap_p ("po_edit")) { make_keymap ("po_edit"); definekey_reserved ("cancel_editbuf", "^K", Edit_Mode); % emacs-like definekey_reserved ("po_end_edit", "^C", Edit_Mode); % emacs-like definekey ("po_end_edit", "\t", Edit_Mode); definekey ("enlargewin", "\e-", Edit_Mode); definekey ("decreasewin", "\e/", Edit_Mode); if (NULL != getenv ("DISPLAY")) { definekey ("enlargewin", "\e+", Edit_Mode); definekey ("decreasewin", "\e-", Edit_Mode); } } !if (keymap_p (mode)) { make_keymap (mode); definekey ("show_current_entry_number", "@", mode); definekey ("make_preferred_gettext", "+", mode); definekey ("gettext_fuzzy_match", "*", mode); definekey ("top_justify_entry", ".", mode); definekey ("page_up", "b", mode); definekey ("update_compendiums", "B", mode); definekey ("po_undo", "_", mode); definekey ("po_edit_comment", "#", mode); definekey ("show_po_statistics", "=", mode); definekey ("show_help", "?", mode); definekey ("find_fuzzy", "f", mode); definekey ("bfind_fuzzy", "F", mode); definekey ("goto_entry", "g", mode); definekey ("grep_src", "G", mode); definekey ("limit_view", "l", mode); definekey ("po_next_entry", "n", mode); definekey ("any_next_unfinished", " ", mode); definekey ("po_previous_entry", "p", mode); definekey ("po_compile", "c", mode); definekey ("lookup_word (Null_String, 0)", "d", mode); definekey ("wordlist_lookup_all", "D", mode); definekey ("po_decompile", "C", mode); definekey ("copy_msgstr", "w", mode); definekey ("insert_msgstr", "y", mode); definekey ("edit_whole_buffer", "E", mode); definekey ("replace_headers", "H", mode); definekey ("init_with_compendiums", "I", mode); definekey ("cut_msgstr", "K", mode); definekey ("mail_po_file", "M", mode); definekey ("find_obsolete", "o", mode); definekey ("bfind_obsolete", "O", mode); definekey ("view_source", "s", mode); definekey ("replace_in_msgstrs", "R", mode); definekey ("set_source_path", "S", mode); definekey ("find_translated", "t", mode); definekey ("bfind_translated", "T", mode); definekey ("find_untranslated", "u", mode); definekey ("bfind_untranslated", "U", mode); definekey ("po_validate_command", "V", mode); definekey ("po_edit", "\t", mode); % tab definekey ("dict_lookup_all_def", "^D", mode); definekey ("po_edit", "^M", mode); % enter definekey ("del_obsolete", Key_Del, mode); % del definekey ("fuzzy_or_obsolete_entry", Key_BS, mode); % backspace definekey ("remove_fuzzy_flag", Key_Alt_BS, mode); definekey ("find_translator_comment", "\e#", mode); definekey ("copy_msgid_to_msgstr", "\e^m", mode); definekey ("toggle_wrap", "\\", mode); definekey_reserved ("del_translator_comment", "#", mode); definekey_reserved ("edit_compendium", "ce", mode); definekey_reserved ("cut_msgstr", "k", mode); definekey_reserved ("add_dir_to_compendium", "d", mode); definekey_reserved ("po_spellcheck", "s", mode); definekey_reserved ("conv_charset", "E", mode); definekey_reserved ("flag_fuzzy_all", "F", mode); definekey_reserved ("po_file_update", "U", mode); } %}}} %{{{ mode definition define po_mode () { set_mode (mode, 0); use_keymap (mode); use_syntax_table (mode); mode_set_mode_info (mode, "init_mode_menu", &po_menu); set_buffer_hook ("mouse_2click", &po_mouse_2click_hook ()); use_dfa_syntax (1); run_mode_hooks ("po_mode_hook"); trim_buf (); create_po_edit_buf (); po_statistics (); if (eobp () and bobp ()) insert_po_header (); set_buffer_modified_flag (0); set_readonly (1); message ("F10 -> Mode, gives you access to menu functions. Type '?' for help"); } provide (mode); %}}} jedmodes-2.5.7/dictmode/0000755000175400017500000000000011146315764013402 5ustar mildegmjedmodes-2.5.7/dictmode/dict-cli.sl~0000644000175400017500000000710211146315425015622 0ustar mildegm% dict-cli.sl: dict backend using the command line interface `dict` % % Copyright © 2005 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-13 first public version % 0.1.1 2006-09-25 use do_shell_cmd() for error redirection provide("dict-backend"); provide("dict-cli"); % Requirements % ------------ % * `dict` command line dict-client (see Dict_Cmd) %!%+ %\variable{Dict_Cmd} %\synopsis{Command line program for dict lookup} %\usage{variable Dict_Cmd = "dict"} %\description % The command line program for dict lookup (on most systems this will be % "dict"). An alternative is "dictl", a wrapper for conversion of|from UTF8 % into the users locale) %\example % To use the "dictl" wrapper if the current locale is not utf8 aware put in % ~/.jed/jed.rc (or ~/.jedrc) %#v+ % if (_slang_utf8_ok) % variable Dict_Cmd = "dict"; % else % variable Dict_Cmd = "dictl"; %#v- %\seealso{dict, dict_mode, Dict_Server, Dict_DB} %!%- custom_variable("Dict_Cmd", "dict"); % cache for dict_show results static variable show_cache = Assoc_Type[String_Type]; static variable last_host = ""; % transform host argument to command line option(s) % "host" --> "--host " % "host:port" --> "--host --port " private define parse_host(host) { host = strtok(host, ":"); return "--host " + strjoin(host, " --port "); } define dict_define(word, database, host) { variable db, cmd; foreach db (strtok(database, ",")) { cmd = sprintf("%s --database '%s' %s '%s'", Dict_Cmd, db, parse_host(host), word); set_prefix_argument(1); do_shell_cmd(cmd); } } % insert the result of the MATCH command into the current buffer define dict_match(word, strategy, database, host) { variable db, cmd; foreach db (strtok(database, ",")) { cmd = sprintf("%s --database '%s' %s --match --strategy %s '%s'", Dict_Cmd, db, parse_host(host), strategy, word); set_prefix_argument(1); do_shell_cmd(cmd); } } % insert the result of the SHOW command into the current buffer define dict_show(what, host) { if (host != last_host) { show_cache = Assoc_Type[String_Type]; % reset cache last_host = host; } % if the result is cashed, insert and return if (assoc_key_exists(show_cache, what)) return insert(show_cache[what]); % what --> option switch (what) { case "db": what = "--dbs"; } { case "strat": what = "--strats"; } { case "server": what = "--serverinfo"; } { is_substr(what, "info"): % convert "info:" to "-- info " what = strtok(what, ":"); what = "--info " + strjoin(what, " "); } { error("argument must be one of 'db', 'strat', 'server', info:"); } set_prefix_argument(1); do_shell_cmd(sprintf("%s %s %s", Dict_Cmd, parse_host(host), what)); % cache result mark_buffer(); show_cache[what] = bufsubstr(); } #iffalse % Build a dict:// URL for the query defined by the arguments in the form % dict://host:port/d:word:database % dict://host:port/m:word:database:strategy % (see `man dict` or section 5. "URL Specification" of RFC2229) variable db, urls, url; if (is_substr(word, "dict://") == 1) urls = [word]; else if (strategy == NULL) % definition lookup urls = array_map(String_Type, &sprintf, "dict://%s/d:%s:%s", Dict_Server, word, strtok(database, ",")); else urls = array_map(String_Type, &sprintf, "dict://%s/m:%s:%s:%s", Dict_Server, word, strtok(database, ","), strategy); #endif jedmodes-2.5.7/dictmode/dictmode.sl0000644000175400017500000006016111146315614015530 0ustar mildegm% dictmode.sl dict dictionary lookup % % Copyright © 2006 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % This 'jed dict mode' provides an interface to the `dict` command line % program. See dict.sl and dict-lookup.sl for alternatives % % Version % 2006-01-11 0.1 first draft % 2006-01-24 0.2 lots of tips from Paul Boekholt % less dependencies % added thesaurus function % dict calls "dict_client_hook" and "dict_show_databases_hook" % for alternative client % syntax highlighting (non DFA as DFA has problems with UTF8) % INITIALIZATION block with popup hook % 2006-02-06 0.3 bugfixes [PB], % 2006-02-07 0.4 multiple databases % 2006-02-20 0.5 "dict API" to use a dict-backend mode % 2006-03-10 0.6 match (Paul Boekholt) % 2006-03-13 first public version % 2006-03-14 0.6.1 bugfix for zero-length keywords % 2006-09-26 0.6.2 bugfix for {multi word keywords} (report Paul Boekholt) % 2007-10-18 0.6.3 optional extensions with #if ( ) % 2008-06-18 0.6.4 use call_function() instead of runhooks() % % Usage % ----- % % * Place "dictmode.sl" and required|recommended files in the % jed_library_path % * Add the INITIALIZATION block to your .jedrc or use make_ini() % (http://jedmodes.sf.net/mode/make_ini/) % * Optionally define custom variables and hooks # _autoload("dict", "dictmode", "thesaurus", "dictmode", "dict_lookup", "dictmode", "dict_menu_callback", "dictmode", 4); _add_completion("dict", "thesaurus", 2); static define dict_load_popup_hook(menubar) { variable menu = "Global.S&ystem"; menu_insert_popup ("&Ispell", menu, "&Dict"); menu_set_select_popup_callback(menu+".&Dict", &dict_menu_callback); } append_to_hook("load_popup_hooks", &dict_load_popup_hook); # % debug information, uncomment to locate errors % _debug_info = 1; % Requirements % ============ % dict-backend % ------------ %!%+ %\variable{Dict_Backends} %\synopsis{List of SLang files providing a dict interface} %\usage{variable Dict_Backends = "dict-cli.sl,dict-curl.sl,dict-socket.sl"} %\description % When evaluated, dictmode.sl searches the files in this comma % delimited list in the jed library path and evaluates the first % found. %\example % To choose the dict-curl.sl backend, set in jed.rc %#v+ % variable Dict_Backends = "dict-curl.sl"; %#v- %\seealso{dict, dictmode, Dict_Server, Dict_DB, Dict_Cmd} %!%- custom_variable("Dict_Backends", "dict-cli.sl,dict-curl.sl,dict-socket.sl"); !if (_featurep("dict-backend")) { foreach $1 (strchop(Dict_Backends, ',', 0)) { if (expand_jedlib_file($1) != "") if (evalfile(path_sans_extname($1))) break; } !if (_featurep("dict-backend")) verror("dictmode needs a backend, e.g. one of %s.", Dict_Backends); } require("keydefs"); % >= jed 99.17 or x-keydefs (symbolic names for keys) % modes from jedmodes.sf.net/ require("view"); % readonly-keymap require("sl_utils"); % push_defaults(), get_blocal(), run_function, ... require("bufutils"); % >= 1.9 (as there was a bug in close_and_*_word()) % popup_buffer(), help_message(), ... autoload("bget_word", "txtutils"); % Recommendations % --------------- % listing widget #if (strlen(expand_jedlib_file("listing.sl"))) autoload("listing_mode", "listing"); autoload("listing_list_tags", "listing"); #endif % History: walk for and backwards in the history of lookups #if (strlen(expand_jedlib_file("circle.sl"))) require("circle"); % dummy autoload for byte-compiling #if (autoload("create_circ", "circle"), 1) #endif #endif % Table formatting #if (strlen(expand_jedlib_file("csvutils.sl"))) autoload("list2table", "csvutils"); autoload("get_lines", "csvutils"); autoload("strjoin2d", "csvutils"); % dummy autoload for byte-compiling #if (autoload("list2table", "csvutils.sl"), 1) #endif #endif % Custom variables % ---------------- %!%+ %\variable{Dict_Server} %\synopsis{Server for Dict lookups} %\usage{variable Dict_Server = "localhost"} %\description % The server that should be contacted by \sfun{dict}. % % Most common values are "localhost" and "dict.org" but any server that % understands the DICT protocoll as specified in RFC2229 may be given. % % If the port is different from the default (2628), it should be appended % as in e.g. "localhost:2777". %\seealso{dict, dict->set_server, Dict_Cmd} %!%- custom_variable("Dict_Server", "localhost"); % custom_variable("Dict_Server", "dict.org"); %!%+ %\variable{Dict_DB} %\synopsis{Default database(s) for dict lookup} %\usage{variable Dict_DB = "*"} %\description % A comma separated list of default dictionaries used with \sfun{dict}. % % The Dict_DB can be changed with \sfun{dict->select_database} for a % running Jed session or customized in jed.rc. % dict->show("db") lists all available databases. %\example % To get only the first matching entry, write in your jed.rc file %#v+ % variable Dict_DB = "!"; %#v- % To use "The Free On-line Dictionary of Computing" and the "Jargon File" write %#v+ % variable Dict_DB = "foldoc,jargon"; %#v- %\seealso{dict, select_database, Dict_Thesaurus_DB, Dict_Translation_DB} %!%- custom_variable("Dict_DB", "*"); % "*" == default %!%+ %\variable{Dict_Thesaurus_DB} %\synopsis{Thesaurus database of the dict server} %\usage{variable Dict_Thesaurus_DB = "moby-thes"} %\description % The database(s) used for \sfun{thesaurus} lookups using the dict protocoll. % On dict.org, the only thesaurus database is "moby-thes". %\notes % On Debian, this database is installed under the name "moby-thesaurus". %\seealso{thesaurus, Dict_DB, Dict_Server} %!%- if (Dict_Server == "localhost") custom_variable("Dict_Thesaurus_DB", "moby-thesaurus"); else custom_variable("Dict_Thesaurus_DB", "moby-thes"); %!%+ %\variable{Dict_Translation_DB} %\synopsis{Bilingual database for translations} %\usage{variable Dict_Translation_DB = "trans"} %\description % An internal "virtual database" for translations. % Comma separated list of bilingual databases. %\example % dict.org defines the (virtual) dictionary "trans" comprising of % all bilingual dictionaries. % To choose a different set, write in your jed.rc something like %#v+ % Dict_Translation_DB = "fd-deu-eng,fd-deu-fra,fd-eng-deu,fd-fra-deu"; %#v- % To set a key to look up a word in the bilinugal databases, add: %#v+ % setkey("dict(, Dict_Translation_DB)", "^FT"); %#v- %\notes % As there is a separate lookup for every database in the list, using % a server-side "virtual database" saves resources, especially if the % Dict_Server is not "localhost". %\seealso{dict, dict_reverse_lookup, Dict_DB} %!%- custom_variable("Dict_Translation_DB", "trans"); %!%+ %\variable{Dict_Strat} %\synopsis{Strategy for Dict match lookups} %\usage{variable Dict_Strat = "."} %\description % The strategy for listing matching words. % % The default "." means use the server's default strategy. %\seealso{dict, dict_DB, Dict_Server} %!%- custom_variable("Dict_Strat", "."); % Namespace % --------- provide("dictmode"); provide("dict"); implements("dict"); private variable mode = "dict"; % static variables static variable dictbuf = "*dict*"; % Functions % ========= % compatibility for Jed < 0.99.17 #ifnexists strbytelen define strbytelen() { strlen(); } #endif % Navigation % ---------- #ifexists create_circ variable Dict_History = create_circ(Array_Type, 30, "linear"); define previous_lookup() { % runhooks fails with functions like "dict->match" () = run_function(push_array(circ_previous(Dict_History))); } define next_lookup() { () = run_function(push_array(circ_next(Dict_History))); } #endif define next_link() { if (fsearch("{")) go_right_1(); else { skip_word_chars(); skip_non_word_chars(); } } define previous_link() { if(bsearch("}")) go_right(bsearch("{")); else bskip_word(); } % get word or (if inside of {}) word group static define dict_get_word() { if (get_mode_name != mode) % not in a dict buffer, use default return bget_word(); switch(parse_to_point()) { case -2: () = bsearch("{"); go_right_1(); push_visible_mark(); () = fsearch("}"); } % Doesnot work with unbalanced string chars in [gcide] % { % case -1: % () = bsearch("\""); % go_right_1(); % push_visible_mark(); % () = fsearch("\""); % } return strjoin(strtok(bget_word()), " "); % normalize whitespace } % parse an URL following the DICT protocoll and return % (word, strategy, database, host) static define parse_dict_url(url) { % Parse a dict:// URL for the query defined by the arguments in the form % dict://host:port/d:word:database % dict://host:port/m:word:database:strategy % (see `man dict` or section 5. "URL Specification" of RFC2229) variable word, strategy, database, host; url = strtok(url, "/"); host = url[1]; url = strjoin(url[[2:]], "/"); url = strtok(url, ":"); word = url[1]; database = url[2]; if (url[0] == "m") strategy = url[3]; else strategy = NULL; return word, strategy, database, host; } % Test % show(parse_dict_url("dict://host:port/m:word:database:strategy")); % show(parse_dict_url("dict://host:port/d:word:database:strategy")); % Lookup % ------ static define dict_mode(); % forward definition %!%+ %\function{dict} %\synopsis{Lookup a word using the Dict protocol (RFC2229)} %\usage{dict(word=NULL, database=Dict_DB, strategy=NULL, host=Dict_Server)} %\description % Interface for a RFC2229 dictionary lookup. The actual lookup is done % by a backend function (see \var{Dict_Backends}) and the result shown % in a \sfun{popup_buffer} in \sfun{dict_mode}. If \var{word} is a % "dict://" URL it will be parsed for database, strategy, and host. %\example % Interactive lookup (you will be asked for a word): M-x dict or %#v+ % dict(); %#v- % Find translations for the word at point by pressing "Ctrl-F T": %#v+ % setkey("dict(bget_word(), Dict_Translation_DB)", "^FT"); %#v- %\seealso{dict_lookup, dict_reverse_lookup, dict_mode, thesaurus, dict->match} %\seealso{Dict_Server, Dict_DB} %!%- public define dict() % (word=NULL, database=Dict_DB, strategy=NULL, host=Dict_Server) { variable word, database, strategy, host; (word, database, strategy, host) = push_defaults( , Dict_DB, , Dict_Server, _NARGS); if (word == NULL) word = read_mini("word to look up:", "", bget_word()); % parse url if (is_substr(word, "dict://") == 1) (word, strategy, database, host) = parse_dict_url(); % prepare buffer popup_buffer(dictbuf); set_readonly(0); erase_buffer(); % insert result of dict lookup (using function provided by a "dict-backend") flush(sprintf("calling Dict %s [%s]", word, database)); if (strategy == NULL) dict_define(word, database, host); else dict_match(word, strategy, database, host); % filter repeating header lines variable last_header = "Start"; bob(); while(bol_fsearch("From")) { if(looking_at(last_header)) { % call("backward_delete_char"); delete_line(); while (bol_skip_white(), eolp() or looking_at(word)) delete_line(); } else last_header = line_as_string(); } bob(); fit_window(get_blocal("is_popup", 0)); % delete old keyword, define new variable old_keywordlen = strbytelen(get_blocal("generating_function", ["", ""])[1]); if ((old_keywordlen > 0) and (old_keywordlen < 48)) () = define_keywords_n(mode, "", old_keywordlen, 1); if ((strbytelen(word) > 0) and (strbytelen(word) < 48)) () = define_keywords_n(mode, word, strbytelen(word), 1); % store the data for buffer (re)generation variable generator = [_function_name, word, database]; if (strategy != NULL) generator = [_function_name, word, database, strategy]; define_blocal_var("generating_function", generator); #ifexists create_circ % Global->show(CURRENT_KBD_COMMAND); if (CURRENT_KBD_COMMAND != "dict->previous_lookup" and CURRENT_KBD_COMMAND != "dict->next_lookup") circ_append(Dict_History, get_blocal("generating_function")); #endif dict_mode(); () = fsearch(word); } % If you want to specify strategy, database and/or host, % use dict(pattern, db, strat, host) %!%+ %\function{dict->match} %\synopsis{Look up matches with dict} %\usage{dict->match()} %\description % Wrapper around \sfun{dict} to look up matches using \var{Dict_Strat} % as strategy. %\seealso{dict, dict_lookup, dict->show, thesaurus, Dict_DB, Dict_Server} %!%- define match() { variable pattern = read_mini("Search pattern:", dict_get_word(), ""), fun = mode+"->"+_function_name; dict(pattern, Dict_DB, Dict_Strat); } %!%+ %\function{dict_lookup} %\synopsis{Non-interactive dictionary lookup} %\usage{dict_lookup()} %\description % Look up word at point (non-interactive) using the current database. %\notes % Exception: The \var{Dict_DB} default database is used, if the current % lookup function is "thesaurus". This way it is easy to get detailled % definitions for word from the thesaurus results (simply pressing enter or % double clicking on the word). %\seealso{dict, dict_reverse_lookup} %!%- public define dict_lookup() { variable database, generator = get_blocal("generating_function", ["dict"]); if (generator[0] == "thesaurus" or length(generator) < 3) database = Dict_DB; else database = generator[2]; dict(dict_get_word(), database); } static define double_click_hook(line, col, but, shift) { dict_lookup(); return(0); } %!%+ %\function{dict->reverse_lookup} %\synopsis{Reverse dictionary lookup} %\usage{dict->reverse_lookup()} %\description % Look up the word at point in the reverse database, if the current % definition comes from a bilingual database (denoted by a hyphen in the % database key e.g. deu-eng -> eng-deu. % % If the current database is monolingual (doesnot contain a hyphen), the % default bilingual database (\var{Dict_Translation_DB}) is used. %\notes % dict->reverse_lookup uses the banner line, e.g. % From English - German Dictionary 1.4 [english-german]: % to find out the current database % % The reversal lookup works fine for most bilingual % databases but is not fail proof (e.g. 'moby-thes' becomes 'thes-moby'!) %\seealso{dict, dict_lookup, Dict_Translation_DB} %!%- define reverse_lookup() { variable database, word = dict_get_word(), generator = get_blocal("generating_function", ["dict", "", ""]); bol_bsearch("From"); if (re_fsearch("\\[\\(.*\\)\\]")) database = regexp_nth_match(1); else database = generator[2]; % show("reverse lookup", database); database = strtok(database, "-"); if (length(database) > 1) % also consider cases like "fd-deu-eng" database = strjoin([database[[:-3]], database[-1], database[-2]], "-"); else database = Dict_Translation_DB; call_function(generator[0], word, database); } % Thesaurus % --------- %!%+ %\function{thesaurus} %\synopsis{Thesaurus lookup using the Dict protocoll} %\usage{thesaurus(word=bget_word())} %\description % Do a lookup using \sfun{dict} and the \var{Dict_Thesaurus_DB}. % Format the output in columns. %\notes % If you prefer the more dense standard output of the moby-thesaurus, % bind dict(, Dict_Thesaurus_DB) to a key. %\seealso{dict, dict_lookup, dict_mode, Dict_Thesaurus_DB} %!%- public define thesaurus() % (word=bget_word()) { variable word, database; (word, database) = push_defaults( , Dict_Thesaurus_DB, _NARGS); if (word == NULL) word = read_mini("Thesaurus lookup for:", dict_get_word(), ""); dict(word, database); % overwrite some settings from dict-mode % define_blocal_var("word_chars", get_word_chars() + " "); define_blocal_var("generating_function", [_function_name, word, database]); #ifexists create_circ if (CURRENT_KBD_COMMAND != "dict->previous_lookup" and CURRENT_KBD_COMMAND != "dict->next_lookup") circ_set(Dict_History, [_function_name, word, database]); #endif % Format the output set_readonly(0); bob(); % delete the headers if (fsearch(word)) { go_down_1(); bol(); push_mark(); bob(); del_region(); } do trim(); while (down_1); bob(); replace(", ", "\n"); replace(",\n", "\n"); % format thesaurus output in collumns #ifexists list2table variable words = get_lines(1); words = list2table(words); insert(strjoin2d(words, " ", "\n", "l")); #else buffer_format_in_columns(); #endif bob; set_readonly(1); set_buffer_modified_flag(0); } % what is one of ["db", "strat", "info", "server", info:] %!%+ %\function{dict->show} %\synopsis{Interface to the SHOW command in RFC2229} %\usage{dict->show(what=NULL)} %\description % Show info about the current \var{Dict_Server}. % What is one of % "db" -- available databases % "strat" -- available strategies % "server" -- info|help for the server % "info:" -- info about the database %\seealso{dict, dict->match, dict->select_database, dict->select_strategy} %!%- static define show() % (what=NULL) { !if (_NARGS) read_with_completion("db,strat,server,info:", "Show what:", "db", "", 's'); variable what = (); popup_buffer("*dict show*"); set_readonly(0); erase_buffer(); dict_show(what, Dict_Server); view_mode(); bob(); } % Set custom variables % -------------------- %!%+ %\function{dict->set_server} %\synopsis{set the Dict Server} %\usage{dict->set_server()} %\description % Set the server that should be contacted by \sfun{dict}. % % The most common values "localhost" and "dict.org" are available with % TAB or SPACE completion, but any server that % understands the DICT protocoll as specified in RFC2229 may be given. % % If the port is different from the default (2628), it should be appended % as in e.g. "localhost:2777". %\seealso{Dict_Server, dict, dict_mode} %!%- define set_server() { Dict_Server = read_with_completion("dict.org,localhost", "Set Dict server:", Dict_Server, "", 's'); } % Database selection % ------------------ % set a new value for Dict_DB define set_database() % (database=NULL) { variable database = push_defaults(, _NARGS); if (database == NULL) database = read_mini("New Dict database:", Dict_DB, ""); Dict_DB = extract_element(strtrim(database), 0, ' '); vmessage("Dict_DB set to '%s'", Dict_DB); } % this function is called by pressing "Return" in the buffer opened by select_database() private define select_database_return_hook() { #ifexists listing_mode variable db = listing_list_tags(1); #else variable db = [line_as_string()]; #endif close_buffer(); db = array_map(String_Type, &strtrim, db); db = array_map(String_Type, &extract_element, db, 0, ' '); set_database(strjoin(db, ",")); } % Show a list of databases and let the user select one (or several) define select_database() { show("db"); % Formatting % Databases available: % foldoc The Free On-line Dictionary of Computing (19 Sep 2003) % ... set_readonly(0); bob(); if (ffind("available")) delete_line(); % chop first line % add symbolic databases insert(" * Default search\n"); insert(" ! First matching dictionary\n"); bob(); () = fsearch(strtok("Dict_DB", ",")[0]); #ifexists listing_mode listing_mode(); #else view_mode(); #endif set_buffer_hook("newline_indent_hook", &select_database_return_hook); message("Select database(s), press [Return] to apply"); } % set a new value for Dict_Strat define set_strategy() % (strategy=NULL) { variable strategy = push_defaults(, _NARGS); if (strategy == NULL) strategy = read_mini("New Dict strategy:", Dict_Strat, ""); Dict_Strat = extract_element(strtrim(strategy), 0, ' '); vmessage("Dict_Strat set to '%s'", Dict_Strat); } % this function is called by pressing "Return" in the buffer opened by % select_strategy() private define select_strategy_return_hook() { variable strat = line_as_string(); close_buffer(); set_strategy(strat); } % Show a list of strategies and let the user select one (or several) define select_strategy() { show("strat"); % Formatting set_readonly(0); bob(); if (ffind("available")) delete_line(); % chop first line insert(". Server default\n"); ()=bol_fsearch(Dict_Strat); #ifexists listing_mode listing_mode(); #else view_mode(); #endif set_buffer_hook("newline_indent_hook", &select_strategy_return_hook); message("Select strategy, press [Return] to apply"); } % Dict mode % ========= static define dict_status_line() { variable generator = get_blocal("generating_function"); variable str = sprintf(" %s %s [%s]", whatbuf(), generator[1], generator[2]); set_status_line(str + " (%p)", 0); } % Keybindings % ----------- !if (keymap_p(mode)) copy_keymap(mode, "view"); definekey(mode+"->next_link", "\t", mode); definekey(mode+"->previous_link", Key_Shift_Tab, mode); definekey("dict", "d", mode); % definition lookup definekey(mode+"->select_database", "D", mode); definekey("close_and_insert_word", "i", mode); definekey(mode+"->match", "m", mode); definekey(mode+"->select_strategy", "M", mode); definekey("close_and_replace_word", "r", mode); definekey(mode+"->set_server", "S", mode); definekey("thesaurus", "t", mode); definekey("dict(, Dict_Translation_DB)", "u", mode); % uebersetzen definekey(mode+"->reverse_lookup", "v", mode); #ifexists create_circ definekey(mode+"->next_lookup", ".", mode); % "non-shift >" (dillo-like) definekey(mode+"->previous_lookup", ",", mode); % "non-shift <" (dillo-like) #endif definekey("dict_lookup", "\r", mode); % Return set_help_message( "D)efinition lookup I)nsert R)eplace T)hesaurus [RET]:follow up Alt-O: menu" , mode); % Menu % ---- public define dict_menu_callback(menu) { % Lookups menu_append_item(menu, "&definition lookup", "dict"); menu_append_item(menu, "&Match", mode+"->match"); menu_append_item(menu, "&Thesaurus", "thesaurus"); menu_append_item(menu, "Translate (&Uebersetzen)", "dict(, Dict_Translation_DB)"); % Settings menu_append_separator(menu); menu_append_item(menu, "Set &Database", mode+"->select_database"); menu_append_item(menu, "Strateg&y", mode+"->select_strategy"); menu_append_item(menu, "Set &Server", mode+"->set_server"); } static define mode_menu(menu) { dict_menu_callback(menu); % Navigation menu_append_separator(menu); #ifexists create_circ menu_append_item(menu, "Lookup Current Word", "dict_lookup"); menu_append_item(menu, "Re&verse Lookup", mode+"->reverse_lookup"); menu_append_item(menu, "&> Next Lookup", mode+"->next_lookup"); menu_append_item(menu, "&< Previous Lookup", mode+"->previous_lookup"); #endif menu_append_item(menu, "&Insert", "close_and_insert_word"); menu_append_item(menu, "&Replace", "close_and_replace_word"); menu_append_item(menu, "&Quit", "close_buffer"); } % Syntax tables % ------------- % definitions create_syntax_table(mode); define_syntax(get_word_chars, 'w', mode); % Words define_syntax("[]<>", ',', mode); % Delimiter define_syntax('F', '#', mode); % Headers (preprocess) define_syntax("{", "}", '%', mode); % Links (comments, enables parse_to_point()) % Strings (enables parse_to_point()), doesnot work with [gcide] % define_syntax('"', '"', mode); set_syntax_flags(mode, 0x20); %!%+ %\function{dict_mode} %\synopsis{Mode for Dict lookup results} %\usage{dict_mode()} %\description % A mode for results of a dictionary lookup according to RFC2229 as e.g. done % by \sfun{dict} and \sfun{thesaurus}. % % Provides a Mode menu, syntax highlight, navigation and command history. % % For keybindings, have a look at the Mode menu (Alt-O) or use % Help>Describe_Keybindings (or M-x describe_bindings). % % Customization can be done defining a \sfun{dict_mode_hook}. %\seealso{dict, thesaurus, dict_lookup} %!%- define dict_mode() { set_mode(mode, 0); set_readonly(1); set_buffer_modified_flag(0); use_keymap (mode); use_syntax_table(mode); mode_set_mode_info (mode, "init_mode_menu", &mode_menu); set_buffer_hook ("mouse_2click", &double_click_hook); dict_status_line(); run_mode_hooks(mode + "_mode_hook"); help_message(); } jedmodes-2.5.7/minued/0000755000175400017500000000000010461125576013072 5ustar mildegmjedmodes-2.5.7/minued/minued.sl0000644000175400017500000002212610274110402014676 0ustar mildegm% ------------------------------------------- -*- mode:SLang; mode:folding; -*- % % MINUED-MODE FOR JED % % Copyright (c) 2000 Francesc Rocher % Released under the terms of the GNU General Public License (ver. 2 or later) % % $Id: minued.sl,v 2.15 2000/09/09 22:16:42 rocher Exp $ % % --------------------------------------------------------------------- %{{{ % % DESCRIPTION % 'Minued' is a MINi-bUffer EDitor with wich you can view all % previously lines entered in it. Select and modify one of them, press % press return and that line will be updated and evaluated. % % USAGE % Simply add the line: % % autoload ("minued_mode", "minued"); % % somewhere in your startup file (.jedrc or jed.rc). You can optionally % bind 'minued_mode' to "Ctrl-X Ctrl-E" (quite useful in emacs mode) with % % setkey ("minued_mode", "^X^E"); % % See the 'COLORS' section to see how you can customize colors % used by minued. % % CHANGELOG % 2000/09/09: 'minued_mode' is now called 'minued_mode' (as it should % be). Some minor changes added. % % 2000/05/30: Modified by JED for inclusion into 0.99-11. Until % Francesc's is_color has been implemented, the menu_selection colors % are used. % % AUTHOR % Francesc Rocher % Feel free to send comments, suggestions or improvements. % % ------------------------------------------------------------------------ %}}} implements ("Minued"); % PRIVATE VARIABLES %{{{ private variable minued_cbuf, % Current buffer before minued-mode was called minued_nwin, % Number of windows (before minued) minued_ncoms, % Number of commands minued_mark, minued_lnum = 1, % Line number minued_line, % Line contents minued_cnums, % Color used for numbers minued_cline, % Color used in the current line Max_Num_Lines = 32; % The same as in 'mini.sl' %}}} % USER VARIABLES %!%+ %\variable{Minued_Lines} %\synopsis{Minued_Lines} %\usage{Integer_Type Minued_Lines = 0;} %\description % This variable controls the number of lines shown in the minued % buffer. If the value of \var{Minued_Lines} is -1, then the entire % screen is used. If it is 0, the window splits vertically. A positive % value selects the exact number of lines to show. This value shouldn't % be greater than \var{SCREEN_HEIGHT}-4, and is only useful while you are % working with one window. % % Default value is 0. %\seealso{minued} %\seealso{SCREEN_HEIGHT} %!%- custom_variable ("Minued_Lines", 0); % PRIVATE FUNCTIONS private define insert_mini_commands () %{{{ { % Returns the number of inserted lines. variable l, line = mini_get_lines (NULL), n = 0; foreach (line) { l = (); if (strlen (l)) { n++; vinsert ("%3d %s\n", n, l); } } return n; } %}}} private define remove_mini_command (n) %{{{ { % Remove the n-th Mini_Previous_Line % ('n' is the n-th line from the user point of view) variable lines = mini_get_lines (NULL); variable i = [0:length (lines)-1]; mini_set_lines (lines [where (i != n-1)]); } %}}} private define update_mini_command (n, cmd) %{{{ { % Replace n-th Mini_Previous_Line with 'cmd' % ('n' is the n-th line from the user point of view) if (n > minued_ncoms) { variable c = String_Type [1]; c [0] = cmd; mini_store_lines (c); } else { variable l = mini_get_lines (NULL); l [n-1] = cmd; mini_set_lines (l); } } %}}} private define minued_eval () %{{{ { variable mtr; if (is_defined (minued_line)) { eval (minued_line); return; } mtr = strtrans (minued_line, "-", "_"); if (is_internal (mtr)) { call (mtr); return; } if (is_defined (mtr)) { eval (mtr); return; } eval (minued_line); } %}}} private define minued_get_line () %{{{ { minued_line = line_as_string (); minued_line = strtrim (minued_line [[5:]]); } %}}} private define minued_show () %{{{ { erase_buffer (); minued_ncoms = insert_mini_commands (); if (minued_ncoms == Max_Num_Lines) { minued_ncoms--; () = up (1); delete_line (); } insert ("add> "); goto_line (minued_lnum); set_column_colors (minued_cnums,1,5); set_buffer_modified_flag (0); } %}}} private define minued_adjust_window () %{{{ { if (Minued_Lines == -1) onewindow (); if (Minued_Lines) { if (Minued_Lines > SCREEN_HEIGHT-4) onewindow (); else { variable n = window_info ('r'); if (n < Minued_Lines) Minued_Lines - n; else { otherwindow (); n - Minued_Lines; } loop () enlargewin (); pop2buf ("*minued*"); } } } %}}} private define minued_update () %{{{ { update_mini_command (minued_lnum, minued_line); } %}}} private define minued_update_hook () %{{{ { minued_mark = create_line_mark (minued_cline); if (what_column () < 6) goto_column (6); if (andelse {what_line () <= minued_ncoms} {buffer_modified ()}) { push_spot (); goto_column (4); del (); insert_char ('*'); pop_spot (); set_buffer_modified_flag (0); } minued_lnum = what_line (); } %}}} % PUBLIC FUNCTIONS ------------------------------------------------------------ %!%+ %\function{minued_mode} %\synopsis{minued_mode} %\usage{Void minued_mode ();} %\description % \var{minued_mode} is a mini-buffer's contents editor with which you can view all % previously entered lines in it. Select and modify one of them. Press return % and that line will be updated in the mini-buffer and evaluated in the buffer % from which minued was called. % % All lines appears numbered, in the same order that they are stored in the % mini-buffer. Use the last line of minued if you want to add a new one. % Instead of a number, that line shows "add> ". % % The following key-bindings are defined in \var{minued_mode}: %#v+ % Return Update and evaluate the current line. % Meta-Return Evaluate the current line. % Ctrl-U Update the current line, don't leave 'minued_mode'. % Meta-R Remove the current line, don't leave 'minued_mode'. % Ctrl-C Quit. %#v- % Note: Minued cannot be invoked from the mini-buffer. %\seealso{history_load, history_save} %\seealso{Minued_Lines} %!%- public define minued_mode () %{{{ { if (MINIBUFFER_ACTIVE or (whatbuf () == "*minued*")) return; minued_nwin = nwindows (); minued_cbuf = pop2buf_whatbuf ("*minued*"); minued_adjust_window (); minued_show (); set_buffer_undo (1); set_mode ("minued", 0); use_keymap ("minued"); set_buffer_hook ("update_hook", &minued_update_hook); run_mode_hooks ("minued_mode"); } %}}} public define minued_cancel () %{{{ { setbuf ("*minued*"); set_buffer_modified_flag (0); sw2buf (minued_cbuf); delbuf ("*minued*"); if (minued_nwin == 1) onewindow (); else otherwindow (); } %}}} public define minued_eval_line () %{{{ { minued_get_line (); minued_cancel (); if (strlen (minued_line)) minued_eval (); } %}}} public define minued_remove_line () %{{{ { if (orelse {minued_lnum > minued_ncoms} {minued_ncoms == 1}) return; remove_mini_command (minued_lnum); minued_show (); } %}}} public define minued_update_line () %{{{ { if (what_line () > minued_ncoms) return; variable c = what_column (); minued_get_line (); if (strlen (minued_line)) { minued_update (); delete_line (); vinsert ("%3dU %s\n", minued_lnum, minued_line); () = up (1); goto_column (c); set_buffer_modified_flag (0); flush ("Line updated."); } } %}}} public define minued_update_eval_line () %{{{ { minued_get_line (); minued_cancel (); !if (strlen (minued_line)) return; minued_update (); minued_eval (); } %}}} % COLORS %{{{ % DISABLED while 'is_color' and 'set_color' are not available % % !if (is_color ("minued_nums")) % set_color ("minued_nums", "brightred", "black"); % % !if (is_color ("minued_line")) % set_color ("minued_line", "black", "green"); % % minued_cnums = color_number ("minued_nums"); % minued_cline = color_number ("minued_line"); % Temporary solution #iftrue minued_cline = color_number ("menu_selection"); minued_cnums = color_number ("menu_selection_char"); #else set_color_object (100, "brightred", "black"); set_color_object (101, "black", "green"); minued_cnums = 100; minued_cline = 101; #endif %}}} % KEYMAP %{{{ $0 = "minued"; !if (keymap_p ($0)) { make_keymap ($0); undefinekey ("^C", $0); definekey ("minued_cancel", "^C", $0); definekey ("minued_eval_line", "\e\r", $0); definekey ("minued_remove_line", "\er", $0); definekey ("minued_update_eval_line", "\r", $0); definekey ("minued_update_line", "^U", $0); } %}}} jedmodes-2.5.7/numbuf/0000755000175400017500000000000010573513152013100 5ustar mildegmjedmodes-2.5.7/numbuf/numbuf.sl0000644000175400017500000001150410573506205014736 0ustar mildegm% Number the buffers and bind Alt-1 .. Alt-9 to go to numbered_buffer % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % VERSIONS % 1.0 first public version % 1.1 removed hidden dependency on datutils % cleaned up code % 1.2 bugfix: buffer number did not show up when buffername was still % present in Numbered_Buffer_List when (re)loading the buffer % Numbered_Buffer_List[0] now used as well (was kept empty) % (buffer-numbers and keybindings start at 1) % 1.3 new custom variable Numbuf_number_all % 1.3.1 2005-11-02 Fix "public" statements % 1.3.2 2007-03-07 patches by Sangoi Dino Leonardo % numbuf_menu_callback() called sw2buf() from bufutils, % number_buffer() and Numbered_Buffer_List made private, % fix message in goto_numbered_buffer(n) % % USAGE % % Put in jed_library_path and insert a line % require("numbuf") % into your jed rc file. Optionally set (custom) variables. % _debug_info=1; % --- custom variables ---------------------------------------------------- % Keybindings: Default is to bind Alt-1 to Alt-9 to goto_numbered_buffer. % (With ALT_CHAR = 27) By default these are bound to digit_arg, make sure you % bind another keyset to digit_arg. % Use the following to change this. (Set to NULL if you don't want keybindings) custom_variable("Numbuf_key_prefix", "\e"); % Escape (Alt/Meta) % Set this to 0 to have only Alt-0 bound to open_buffer_list() custom_variable("Numbuf_show_list_when_failing", 1); % Do you want to number all buffers? (using switch_active_buffer_hook) custom_variable("Numbuf_number_all", 0); % --- Internal variables --------------------------------------------------- private variable chbuf_menu = "Global.&Buffers.&Change Buffer"; private variable Numbered_Buffer_List = String_Type[10]; Numbered_Buffer_List[*] = ""; % initialize % --- Functions ------------------------------------------------------------ % number the buffer if not done private define number_buffer() { _pop_n(_NARGS); % remove possible arguments from stack variable buf = whatbuf(), free_numbers; % don't number hidden buffers and the ".jedrecent" auxiliary buffer if (buf[0] == ' ' or buf == ".jedrecent") return; % Find reusable numbers free_numbers = where(Numbered_Buffer_List == buf); % buf is still in list !if (length(free_numbers)) free_numbers = where(not(array_map(Int_Type, &bufferp, Numbered_Buffer_List))); if (length(free_numbers)) { % add to list of numbered buffers and set status line Numbered_Buffer_List[free_numbers[0]] = buf; set_status_line("["+ string(free_numbers[0]+1)+ "]" + Status_Line_String, 0); } } % this is also defined in bufutils.sl but we don't want dependencies private define go2buf(buf) { if(buffer_visible(buf)) pop2buf(buf); % goto window where buf is visible else sw2buf(buf); % open in current window } % Build the menu of numbered buffers define numbuf_menu_callback (popup) { variable menu, buf, entry, i = 1; foreach (Numbered_Buffer_List) { buf = (); if (bufferp(buf)) menu_append_item (popup, "&"+string(i)+" "+buf, &go2buf, buf); i++; } % append the unnumbered buffers loop (buffer_list()) { buf = (); if (orelse{buf[0] == ' '}{length(where(Numbered_Buffer_List == buf))}) continue; (entry, ) = strreplace("&"+buf, "&*", "*&", 1); menu_append_item (popup, entry, &go2buf, buf); } } % Change the callback of the Change Buffer menu entry private define numbuf_popup_hook(menubar) { menu_set_select_popup_callback(chbuf_menu, &numbuf_menu_callback); } append_to_hook("load_popup_hooks", &numbuf_popup_hook); define goto_numbered_buffer(n) { variable buf = Numbered_Buffer_List[n-1]; % Arrays start with element 0 if (andelse {buf != NULL} { bufferp(buf) }) go2buf(buf); else if (Numbuf_show_list_when_failing) menu_select_menu(chbuf_menu); else message("Buffer "+string(n)+" doesn't exist."); } % Keybindings: Default is to bind Alt-1 to Alt-9 to goto_numbered_buffer % See the custom variable Numbuf_key_prefix for changing this. if (Numbuf_key_prefix != NULL) { setkey(sprintf("menu_select_menu(\"%s\")", chbuf_menu), Numbuf_key_prefix + "0"); for($1=1; $1<10; $1++) setkey(sprintf("goto_numbered_buffer(%d)",$1), Numbuf_key_prefix+string($1)); } % Hooks: if (Numbuf_number_all) append_to_hook("_jed_switch_active_buffer_hooks", &number_buffer); else % number buffers associated to a file { % either when opening a file (no arguments, no return value) add_to_hook("_jed_find_file_after_hooks", &number_buffer); % or when saving to a file (one argument, no return value) add_to_hook("_jed_save_buffer_after_hooks", &number_buffer); } provide("numbuf"); jedmodes-2.5.7/navigate/0000755000175400017500000000000011262357223013403 5ustar mildegmjedmodes-2.5.7/navigate/navigate.sl0000644000175400017500000001460211262357223015544 0ustar mildegm% navigate.sl: "history feature" known from many browsers. % % Store info about the last visited buffer with any buffer switch. % Navigate between the recently visited buffers with Alt+Arrow. % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % ======== % 1.0 % 1.1 * Open closed buffers with recent.sl % 1.2 * ... ask before reopening % * bugfix in navigate: skip closed buffers % * bugfix: use CURRENT_KBD_COMMAND instead of % LAST_KBD_COMMAND (Adam Byrtek) % * do not overwrite existing keybindings % -> set keybindings in your .jedrc % 1.3 * Reopen autogenerated buffers with blocal var % "generating_function" % * new datatype BufferMark (save restoring information) % * independend of recent.sl % 2007-08-02 1.3.1 * blocal "generating_function" might now be % Ref_Type, String_Type: function without args, or % List_Type, Array_Type: function with args. % 2008-05-05 1.3.1 * simplified testing appendix (the new sprint_var.sl can % handle user-defined data types) % 2009-10-05 1.4 * define named namespace, remove debugging function % % USAGE Put in the jed-library-path and do % require("navigate") % in your .jedrc % % CUSTOMIZATION % Bind navigate_back() and navigate_forward() to some keys % Example: % setkey ("navigate_forward()", Key_Alt_Right); % setkey ("navigate_back()", Key_Alt_Left); % will give you bindings as in Firefox or Konqueror. % Custom variables: Default % Navigate_Stack_Size 10 % Navigate_Restore_Buffers 2 (0 No, 1 Always, 2 Ask) % Navigate_Append_at_End" 0 % % TODO code cleanup % _debug_info = 1; % --- Requirements ------------------------------------------------------ require("keydefs"); % symbolic constants for many function and arrow keys require("circle"); % "circular array" datatype for the history stack autoload("get_blocal", "sl_utils"); autoload("push_defaults", "sl_utils"); autoload("run_function", "sl_utils"); autoload("what_line_if_wide", "sl_utils"); autoload("push_array", "sl_utils"); autoload("push_list", "datutils"); autoload("fold_open_fold", "folding"); % --- Custom Variables -------------------------------------------------- % Size of the navigation stack (won't change after loading navigate.sl) custom_variable("Navigate_Stack_Size", 10); % Do you want to restore closed buffers when passing by? % 0 No, 1 Always, 2 Ask custom_variable("Navigate_Restore_Buffers", 2); % Do you want the new entries always appended at the end of the stack? custom_variable("Navigate_Append_at_End", 0); % if 0, entries will be appended at current stack position, clipping % the ones one stepped back % if 1, no entries will be lost (at the cost of inconsistent manoeuvring) % Name and Namespace % ------------------ provide("navigate"); implements("navigate"); % Internal (static) Variables % --------------------------- !if (is_defined("BufferMark_Type")) typedef struct { name, % buffer name file, % full filename generating_function, % for autogenerated buffers, % saved in blocal("generating_function") line, % \_ Last editing point position column, % / } BufferMark_Type; % a circular array of recently visited buffers (History Stack) % updated with every buffer switch (switch_active_buffer_hook) static variable Navigation_Stack = create_circ(BufferMark_Type, Navigate_Stack_Size, "linear"); % --- Functions --------------------------------------------------------- % Return a BufferMark with restoring information define buffermark() % (buf=whatbuf) { variable buf, dir, bmark = @BufferMark_Type; buf = push_defaults(whatbuf, _NARGS); (bmark.file, dir, bmark.name, ) = getbuf_info(buf); if (strlen(bmark.file)) bmark.file = path_concat(dir, bmark.file); bmark.generating_function = get_blocal("generating_function", NULL); bmark.line = what_line_if_wide(); bmark.column = what_column(); return bmark; } % restore a closed buffer from the buffermark, return success define reopen_buffer(bmark, ask) { variable result; % is there information for reopening? if (andelse{bmark.file == ""}{bmark.generating_function == NULL}) return 0; if(ask) { flush("Buffer " + bmark.name + " no longer open. Press Enter to reopen!"); variable key = getkey(); if (key != '\r') % Enter { ungetkey(key); return 0; } } % recreate the buffer if (strlen(bmark.file)) result = find_file(bmark.file); else if (typeof(bmark.generating_function) == Array_Type) result = run_function(push_array(bmark.generating_function)); else if (typeof(bmark.generating_function) == List_Type) result = run_function(push_list(bmark.generating_function)); else result = run_function(bmark.generating_function); % goto saved position if (result and what_line() == 1) { goto_line(bmark.line); () = goto_column_best_try(bmark.column); % open folds loop(count_narrows) % while (is_line_hidden) might cause an infinite loop! if(is_line_hidden) fold_open_fold(); } !if (result) vmessage("Sorry. Cannot reopen %s", bmark.name); return result; } % argument is the buffer last visited % (provided by _jed_switch_active_buffer_hooks but not used) define navigate_append_buffermark(oldbuf) { % show("navigate_append", whatbuf(), CURRENT_KBD_COMMAND); % no action if switch is caused by a navigate command if (CURRENT_KBD_COMMAND == "navigate_back" || CURRENT_KBD_COMMAND == "navigate_forward") return; circ_append(Navigation_Stack, buffermark(), Navigate_Append_at_End); } static define navigate(bmark) { if (buffer_visible(bmark.name)) return pop2buf(bmark.name); if (bufferp(bmark.name)) return sw2buf(bmark.name); if (Navigate_Restore_Buffers) !if(reopen_buffer(bmark, Navigate_Restore_Buffers - 1)) circ_delete(Navigation_Stack); } public define navigate_back() { navigate(circ_previous(Navigation_Stack)); } public define navigate_forward() { navigate(circ_next(Navigation_Stack)); } append_to_hook("_jed_switch_active_buffer_hooks", &navigate_append_buffermark); jedmodes-2.5.7/tests/0000775000175400017500000000000011477666673012775 5ustar mildegmjedmodes-2.5.7/tests/datutils-test.sl0000664000175400017500000002524711137545466016142 0ustar mildegm% Test the functions in datutils.sl Test datutils.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 _debug_info = 1; require("unittest"); % Fixture % ------- require("datutils"); private variable testbuf = "*bar*"; private variable teststring = "a test line"; private variable intlist = {1,2,3,4}, intarray = [1,2,3,4]; private variable strlist = {"hello", "world"}, strarray = ["hello", "world"]; static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % define null_fun() {} static define test_null_fun() { null_fun(); test_equal(23, null_fun(23)); } % array_max: library function % % SYNOPSIS % Return the maximal value of an array % % USAGE % result = array_max(Array_Type a) % % DESCRIPTION % The `array_max' function examines the elements of a numeric array and % returns the value of the largest element. % % EXAMPLE % % array_max([1,2,30,4] == 30 % % % NOTES % `max' is a slang intrinsic since 1.4.6. (but must be activated manually) % % SEE ALSO % array_sum, array_product, max, min static define test_array_max() { test_equal(6, array_max([1,2,6,3])); test_equal(12, array_max([1.4, 12, 3, 5.7])); test_equal(-1, array_max([-12, -3,-1])); test_equal(-1, array_max([-1])); } % array_sum: library function % % SYNOPSIS % Return the sum of the array elements % % USAGE % result = array_sum(a) % % DESCRIPTION % Sum up the values of a numeric array and return the result. % % NOTES % `sum' is a slang intrinsic since 1.4.6. (but must be activated manually) % % SEE ALSO % array_max, array_product, sum static define test_array_sum() { test_equal(1+2+3+4+5, array_sum([1:5])); } % array_product: library function % % SYNOPSIS % Return the product of the array elements % % USAGE % result = array_product(a) % % DESCRIPTION % Multiply the values of a numeric array and return the result. % % SEE ALSO % array_sum, array_max static define test_array_product() { test_equal(2*3*4*5, array_product([2:5])); test_equal(2, array_product([2])); } % list2array: library function % Convert a list to an array % % EXAMPLE % `list2array' enables the use of lists in places that require an % array, e.g.: % % message(strjoin(list2array({"hello", "world"}, String_Type), " ")); % 23 + list2array({1, 2, 3}) == [24, 25, 26] static define test_list2array() { % list2array with optional arg test_equal(intarray, list2array(intlist, Integer_Type)); test_equal(strarray, list2array(strlist, String_Type)); % list2array without otional arg test_equal(intarray, list2array(intlist)); test_equal(strarray, list2array(strlist)); % examples test_equal("hello world", strjoin(list2array({"hello", "world"}), " ")); test_equal(23 + list2array({1, 2, 3}), [24, 25, 26]); } % array_append: library function % % SYNOPSIS % Append a value to an array or concatenate `a' and `b' % % USAGE % Array = array_append(a, b) % % DESCRIPTION % `array_append' provides a means to use 1d-arrays like lists. It % concatenates `a' and `b'. % % The arguments may be of any type and will be converted to Array_Type (if % the not already are) before the concatenation. % % EXAMPLE % The following statemants are all TRUE: % % array_append(1,2) == [1,2] % array_append(1, [2,3,4]) == [1,2,3,4] % array_append([1,2], [3,4]) == [1,2,3,4] % array_append([1,2,3], 4) == [1,2,3,4] % % % NOTES % For arrays with 1000 values, it becomes time-consuming (0.13 s), % for 2000 values annoying (0.5 s) and for 5000 values prohibitive (3 s) % (CPU-time on a AMD-Duron 700MHz under Linux) % % SEE ALSO % list_append static define test_array_append() { test_equal(array_append(1,2) , [1,2]); test_equal(array_append(1, [2,3,4]) , [1,2,3,4]); test_equal(array_append([1,2], [3,4]) , [1,2,3,4]); test_equal(array_append([1,2,3], 4) , [1,2,3,4]); } % array_value_exists: library function % Return the number of occurences of `value' in array `a' static define test_array_value_exists() { % trivial ones (translate to length(where(a == value)) ) test_equal(0, array_value_exists([1,2,3], 4)); test_equal(1, array_value_exists([1,2,3], 2)); test_equal(3, array_value_exists(["1", "1", "1", "W"], "1")); % Any_Type arrays: variable a = Any_Type[4]; test_equal(0, array_value_exists(a, 3)); test_equal(4, array_value_exists(a, NULL)); a[1] = 3; a[2] = "3"; a[3] = 3; test_equal(1, array_value_exists(a, NULL)); test_equal(2, array_value_exists(a, 3)); test_equal(1, array_value_exists(a, "3")); } % assoc_get_key: library function % Return the key of a value of an Associative Array static define test_assoc_get_key() { variable ass = Assoc_Type[Integer_Type]; ass["5"] = 5; ass["3"] = 3; % testmessage("ass %s\n", sprint_variable(ass)); % testmessage("values %s\n", sprint_variable(assoc_get_values(ass))); % testmessage("keys %s\n", sprint_variable(assoc_get_keys(ass))); test_equal(NULL, assoc_get_key(ass, 1)); test_equal("5", assoc_get_key(ass, 5)); } % Array_Type array([args]) % Return an array containing the arguments static define test_array__integer() { test_equal(array(0, 1, 2, 3), [0, 1, 2, 3]); } static define test_array__string() { test_equal(array("0", "1"), ["0","1"]); } static define test_array__empty() { test_equal(array(), Any_Type[0]); } static define test_array__mixed() { variable a = Any_Type[3], a1 = array(0, "1", '2'); a[0] = 0; a[1] = "1"; a[2] = '2'; test_equal(length(a1), 3); test_equal(_typeof(a1), Any_Type); } #stop % pop2array: library function % % SYNOPSIS % Return N stack-items as an array of type `type' % % USAGE % Array_Type pop2array(N=_stkdepth, [type]) % % DESCRIPTION % Return an array that consists of the N topmost stack elements. % The top element becomes element arr[N-1]. % If `type' is not given, autodetermine it (fall back to `Any_Type' % if the element types differ). % % NOTES % Attention: dont use `pop2array' in a function call with optional % arguments , i.e. not % % show(pop2array()) % % but % % $1 = pop2array(); % show($1); % % % SEE ALSO % array, pop2list, push_array static define test_pop2array() { Arr pop2array(N=_stkdepth, [type]); } % array_delete: library function % % SYNOPSIS % Delete the element(s) at position(s) `N' % % USAGE % Array_Type array_delete(Array_Type a, Integer_Type N) % % USAGE % Array_Type array_delete(Array_Type a, Array_Type N) % % DESCRIPTION % Return a slice of all positions not in `N'. % This provides a means to use 1d-arrays like lists. % % EXAMPLE % % array_delete([1,2,3,4], 0) == [2,3,4] % array_delete([1,2,3,4], [0,1]) == [3,4] % array_delete([1,2,3,4], [0,-1]) == [2,3] % array_delete([1,2,3,4], -1) == [1,2,3] % % % NOTES % For arrays with 1000 values, it becomes time-consuming (0.09 s), % for 2000 values annoying (0.32 s) and for 5000 values prohibitive (1.83 s). % With SLang 2, consider using the new List_Type instead. % % SEE ALSO % array_append, where, list_delete static define test_array_delete() { Arr = array_delete(Arr a, i N); } % array_repeat: library function % % SYNOPSIS % Repeat an array `N' times % % USAGE % Array_Type array_repeat(a, N) % % DESCRIPTION % Concatenate an array N-1 times to itself and return the result. % % SEE ALSO % string_repeat, array_append static define test_array_repeat() { Arr = array_repeat(a, N); } % array_transpose: library function % % SYNOPSIS % Swap the axes of a 2d array % % USAGE % Array_Type array_transpose(a) % % DESCRIPTION % Swap rows and columns of a 2dimensional array. % % SEE ALSO % array_info, reshape static define test_array_transpose() { Arr = array_transpose(a); } % assoc_value_exists: library function % % SYNOPSIS % Return the number of occurences of `value' in `ass' % % USAGE % Integer_Type assoc_value_exists(Assoc_Type ass, value) % % DESCRIPTION % Count, how many times `value' is present in the associative % array `ass'. % % SEE ALSO % array_value_exists, assoc_key_exists, assoc_get_key, assoc_get_values static define test_assoc_value_exists() { i = assoc_value_exists(Ass ass, value); } % push_list: library function % % SYNOPSIS % Push the list elements on the stack % % USAGE % push_list(List_Type lst) % % DESCRIPTION % Push all elements of a list to the stack. % Very convenient for converting a list to an argument list. % % EXAMPLE % % variable args = {"foo ", "bar ", "uffe "}; % variable str = strjoin(push_list(args)); % % % SEE ALSO % pop2list, push_array static define test_push_list() { push_list(List_Type = lst); } % pop2list: library function % % SYNOPSIS % Return list with N topmost stack-items % % USAGE % List_Type lst = pop2list(N=_stkdepth) % % DESCRIPTION % Return a list that consists of the N topmost stack elements. The default % is to return all elements currently on the stack. % The top element becomes lst[N-1]. % % EXAMPLE % Together with `push_list', this is a convenient way to manipulate or % pass on an argument list. Compared to `__pop_args'/`__push_args', % it has the advantage that the args are easily accessible via the normal % index syntax and list functions: % % define silly() % ([args]) % { % variable args = pop2list(_NARGS); % list_append(args, "42", -1); % args[1] = 3; % show(push_list(args)); % } % % % NOTES % Attention: dont use `pop2list' in a function call with optional % arguments. % % SEE ALSO % push_list, pop2array, _stkdepth static define test_pop2list() { List_Type lst = pop2list(N=_stkdepth); } % array2list: library function % % SYNOPSIS % Convert an array to a list % % USAGE % List_Type array2list(a) % % DESCRIPTION % Return a list of the elements of `a'. % % EXAMPLE % % array2list([1, 2, 3]) == {1, 2, 3} % % % SEE ALSO % list2array, push_array, pop2list static define test_array2list() { List_Type = array2list(a); } % list_concat: library function % % SYNOPSIS % Concatenate 2 lists % % USAGE % list_concat(l1, l2) % % DESCRIPTION % Concatenate 2 lists by appending the elements of `l2' to `l1'. % % NOTES % As this function uses a foreach loop over `l2', it can also be an % Array_Type object. % % SEE ALSO % list_append, list_insert, push_list static define test_list_concat() { list_concat(l1, = l2); } % define list_inject(l1, l2, i) static define test_list_inject() { list_inject(); } jedmodes-2.5.7/tests/ch_table-test.sl0000600000175400017500000001106211052555406016015 0ustar mildegm% ch_table-test.sl: % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % Test ch_table.sl % private namespace: `ch_table' % set fixture: require("unittest"); private variable teststring = "bar\n"; private variable testbuf = "*bar*"; static define setup() { popup_buffer(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % test the public defined functions: test_equal(is_defined("ch_table"), 2, "ch_table() should be defined"); test_equal(is_defined("special_chars"), 2, "special_chars() should be defined"); require("ch_table"); % ch_table: library function Undocumented % public define ch_table () % ch_table(StartChar = 0) static define test_ch_table() { ch_table(); test_equal(whatbuf(), "*ch_table*"); close_buffer("*ch_table*"); } % special_chars: library function Undocumented % public define special_chars () static define test_special_chars() { special_chars(); test_equal(whatbuf(), "*ch_table*"); close_buffer("*ch_table*"); } % ct_load_popup_hook: library function Undocumented % define ct_load_popup_hook (menubar) % test_function("ct_load_popup_hook"); % int2string: undefined Undocumented % static define int2string(i, base) test_function("ch_table->int2string", 32, 10); test_last_result("32"); test_function("ch_table->int2string", 32, 16); test_last_result("20"); test_function("ch_table->int2string", 32, 8); test_last_result("40"); test_function("ch_table->int2string", 32, 2); test_last_result("100000"); % string2int: undefined Undocumented % static define string2int(s, base) test_function("ch_table->string2int", "32", 10); test_last_result(32); test_function("ch_table->string2int", "20", 16); test_last_result(32); test_function("ch_table->string2int", "40", 8); test_last_result(32); test_function("ch_table->string2int", "100000", 2); test_last_result(32); % ct_status_line: undefined Undocumented % static define ct_status_line() % test_function("ch_table->ct_status_line"); % ct_update: undefined Undocumented % static define ct_update () % test_function("ch_table->ct_update"); % ct_up: undefined Undocumented % static define ct_up () % test_function("ch_table->ct_up"); % ct_down: undefined Undocumented % static define ct_down () static define test_ct_down() { variable cc; special_chars(); ch_table->ct_down(); test_equal(170, what_char(), "special_chars(); ct_down() should set point to char 170"); close_buffer("*ch_table*"); } % ct_right: undefined Undocumented % static define ct_right () % test_function("ch_table->ct_right"); % ct_left: undefined Undocumented % static define ct_left () % test_function("ch_table->ct_left"); % ct_bol: undefined Undocumented % static define ct_bol () { bol; ct_right;} % test_function("ch_table->ct_bol"); % ct_eol: undefined Undocumented % static define ct_eol () { eol; ct_update;} % test_function("ch_table->ct_eol"); % ct_bob: undefined Undocumented % static define ct_bob () { goto_line(3); ct_right;} % test_function("ch_table->ct_bob"); % ct_eob: undefined Undocumented % static define ct_eob () { eob; ct_update;} % test_function("ch_table->ct_eob"); % ct_mouse_up_hook: undefined Undocumented % static define ct_mouse_up_hook (line, col, but, shift) % test_function("ch_table->ct_mouse_up_hook"); % ct_mouse_2click_hook: undefined Undocumented % static define ct_mouse_2click_hook (line, col, but, shift) % test_function("ch_table->ct_mouse_2click_hook"); % ct_goto_char: undefined Undocumented % static define ct_goto_char () % test_function("ch_table->ct_goto_char"); % insert_ch_table: undefined Undocumented % static define insert_ch_table () % test_function("ch_table->insert_ch_table"); % use_base: undefined Undocumented % static define use_base (numbase) % test_function("ch_table->use_base"); % ct_change_base: undefined Undocumented % static define ct_change_base () % test_function("ch_table->ct_change_base"); % setup_dfa_callback: undefined Undocumented % static define setup_dfa_callback (mode) % test_function("ch_table->setup_dfa_callback"); % ct_insert_and_close: undefined Undocumented % static define ct_insert_and_close () static define test_ct_insert_and_close() { % open char-table, go to second line, insert-and-close special_chars(); ch_table->ct_down(); ch_table->ct_insert_and_close(); % get inserted char push_mark(); go_left_1(); test_equal(bufsubstr(), char(170), "should insert char nr 170"); } jedmodes-2.5.7/tests/cuamouse-test.sl0000664000175400017500000001026311137541400016102 0ustar mildegm% cuamouse-test.sl: Test cuamouse.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % 02 2007-12-11 Define test-functions instead of procedural script require("unittest"); #ifndef XWINDOWS testmessage("\n I: cuamouse only works with xjed, skipping"); #stop #endif % Fixture % ------- require("cuamouse"); private variable testbuf = "*bar*"; private variable teststring = "a test line\n"; static define setup() { sw2buf(testbuf); % create a region from (2,2) to (4,6) loop(3) { insert("\n"); insert(teststring); } goto_line(2); goto_column(2); push_visible_mark(); goto_line(4); goto_column(7); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % click_in_region: library function % % SYNOPSIS % determine whether the mouse_click is in a region % % USAGE % Int click_in_region(line, col) % % DESCRIPTION % Given the mouse click coordinates (line, col), the function % returns an Integer denoting: % -1 - click "before" region % -2 - click "after" region % 0 - no region defined % 1 - click in region % 2 - click in region but "void space" (i.e. past eol) % % SEE ALSO % cuamouse_left_down_hook, cuamouse_right_down_hook static define test_click_in_region() { test_equal(click_in_region(2, 2), 1, "click in the region should return 1"); test_equal(click_in_region(2, 9), 1, "click in the region should return 1"); test_equal(click_in_region(3, 1), 1, "click in the region should return 1"); test_equal(click_in_region(4, 6), 1, "click in the region should return 1"); } % "before" region static define test_click_in_region_before() { test_equal(click_in_region(1, 3), -1, "click before region should return -1"); test_equal(click_in_region(2, 1), -1, "click before region should return -1"); } % "after" region static define test_click_in_region_after() { test_equal(click_in_region(4, 7), -2, "click after region should return -2"); test_equal(click_in_region(4, 12), -2, "click after region should return -2"); test_equal(click_in_region(5, 1), -2, "click after region should return -2"); } % in region but after eol static define test_click_in_region_after_eol() { test_equal(click_in_region(2, 13), 2, "click after eol should return 2"); test_equal(click_in_region(3, 2), 2, "click after eol should return 2"); } % no region static define test_click_in_region_no_region() { pop_mark(0); test_equal(click_in_region(1, 1), 0, "no region should return 0"); test_equal(click_in_region(2, 5), 0, "no region should return 0"); } % copy_region_to_clipboard: static static define test_copy_region_to_clipboard() { copy_region_to_clipboard(); } % define cuamouse_insert(from_jed) static define test_cuamouse_insert() { dupmark(); variable str = bufsubstr(); copy_region_to_clipboard(); push_mark(); cuamouse_insert(1); test_equal(bufsubstr(), str, "should insert the copied text"); } % define cuamouse_2click_hook(line, col, but, shift) %mark word static define test_cuamouse_2click_hook() { pop_mark(0); cuamouse_2click_hook(1,1,1,0); test_true(is_visible_mark(), "double click should mark the word"); } % internal use, test later #stop % define cuamouse_drag(line, col) static define test_cuamouse_drag() { cuamouse_drag(); } % define cuamouse_left_down_hook(line, col, shift) static define test_cuamouse_left_down_hook() { cuamouse_left_down_hook(); } % define cuamouse_middle_down_hook(line, col, shift) static define test_cuamouse_middle_down_hook() { cuamouse_middle_down_hook(); } % define cuamouse_right_down_hook(line, col, shift) static define test_cuamouse_right_down_hook() { cuamouse_right_down_hook(); } % define cuamouse_down_hook(line, col, but, shift) static define test_cuamouse_down_hook() { cuamouse_down_hook(); } % define cuamouse_drag_hook(line, col, but, shift) static define test_cuamouse_drag_hook() { cuamouse_drag_hook(); } % define cuamouse_up_hook(line, col, but, shift) static define test_cuamouse_up_hook() { cuamouse_up_hook(); } jedmodes-2.5.7/tests/unittesttest.sl0000664000175400017500000001151411477666673016116 0ustar mildegm% unittesttest.sl: test the SLang unittest framework % % This self-testing is quite verbose and out of line with the remaining unit % tests so it deliberately named not to match the "-test" % Unittest_File_Pattern. % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % 0.3 2006-09-25 * adapted to unittest version 0.3 % * undo Error_Count increase in case of correct behaviour % of the test functions #if (_jed_version > 9918) require("unittest", "Global"); require("sprint_var", "Global"); #else require("unittest"); require("sprint_var"); #endif static variable results, err, a=1, b=3, last_error_count; testmessage("\n\nAssertions"); % ---------- % here, we put the AssertionError in a try-catch phrase to keep on % evaluating the unittest test script try (err) { if (a != b) throw AssertionError, "$a != $b"$; % this code should not be reached: testmessage("E: AssertionError not thrown "); unittest->Error_Count++; } catch AssertionError: { testmessage("OK: wrong assertion threw AssertionError."); } testmessage("\n\nTruth and Equality\n"); % ------------------------------------ testmessage("\ntest_true(): true args must not show in the report"); test_true(1+1 == 2, "# 1+1 should be 2, test_true failed"); last_error_count = unittest->Error_Count; test_true(1+1 == 3); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: 1+1 == 3 is FALSE, so test_true() works fine"); unittest->Error_Count--; } testmessage("\ntest_equal(): should not show in the report if passing"); test_equal(1+1, 2, "# test_equal failed: 1+1 should be 2"); testmessage("\ntest_equal(): should show in the report if failing"); last_error_count = unittest->Error_Count; test_equal(1+1, 3); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: 1+1 != 3, so test_equal() works fine"); unittest->Error_Count--; } testmessage("\n\nStack hygiene\n"); % ------------------------------- testmessage("\n empty stack, so there should be no response"); test_stack(); testmessage("\n now push 2 values on stack"); 42, "baa"; last_error_count = unittest->Error_Count; test_stack(); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: garbage on stack detected"); unittest->Error_Count--; } testmessage("\n\ntest for exceptions:\n"); % ---------------------------------------- private define zero_division() { return 23/0; } testmessage("\n non defined function:"); err = test_for_exception("foo"); testmessage("\n result: %S %s", typeof(err), sprint_variable(err)); testmessage("\n no exception:"); err = test_for_exception("what_line"); testmessage("\n result: " + sprint_variable(err)); testmessage("\n zero division:"); err = test_for_exception(&zero_division); testmessage("\n result: " + sprint_error(err)); testmessage("\n\nFunction testing:\n"); % ------------------------------------- testmessage(" working cases"); test_function("sprintf", "%d", 8); test_last_result("8"); test_function("eval", "3+4"); test_last_result(7); test_function(&bol); test_last_result(); testmessage(" catching bugs"); last_error_count = unittest->Error_Count; test_function("sprintf", "%d", 8); test_last_result("8"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched wrong return value"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("non_defined"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched non defined function"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("message", NULL); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched wrong usage"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("zero_division"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched buggy function"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function(&what_line); test_last_result(); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched unexpected return value"); unittest->Error_Count--; } testmessage("\n\nRun a test script:\n"); % ------------------------------------ % () = test_file(path_concat(path_dirname(__FILE__), "datutils-test.sl")); % () = test_file("uffe.sl"); % not present testmessage("\n\nRun a test suite:\n"); % ------------------------------------ () = test_files("fooli/"); % invalid dir () = test_files("/home/milde/.jed/lib/test/*datutils*.sl"); testmessage("\n\nRun a test suite and exit Jed:\n"); % -------------------------------------------------- testmessage("\n skipped"); % () = test_files_and_exit("/home/milde/.jed/lib/test/*datutils*.sl"); message("Done"); jedmodes-2.5.7/tests/ishell-test.sl0000600000175400017500000001253111137546740015543 0ustar mildegm% Test ishell.sl: Interactive shell mode (based on ashell.sl by J. E. Davis) % Copyright © 2007 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % Versions % -------- % 0.2 2007-11-30 * merge with template from testscript wizard % * test log buffer % currently, this tests function calls for errors but does only a partial % test of advertised functionality require("unittest"); % test availability of public functions (comment to skip) test_true(is_defined("ishell_mode"), "public fun ishell_mode undefined"); test_true(is_defined("ishell"), "public fun ishell undefined"); test_true(is_defined("terminal"), "public fun terminal undefined"); test_true(is_defined("shell_command"), "public fun shell_command undefined"); test_true(is_defined("shell_cmd_on_region_or_buffer"), "public fun shell_cmd_on_region_or_buffer undefined"); test_true(is_defined("shell_cmd_on_region"), "public fun shell_cmd_on_region undefined"); test_true(is_defined("filter_region"), "public fun filter_region undefined"); % Fixture % ------- require("ishell"); % custom_variable("Ishell_default_output_placement", ">"); % custom_variable("Ishell_logout_string", ""); % default is Ctrl-D % custom_variable("Ishell_Max_Popup_Size", 10); % custom_variable("Shell_Default_Shell", getenv ("COMSPEC")); % custom_variable("Ishell_Default_Shell", Shell_Default_Shell); % custom_variable("Shell_Default_Shell", getenv ("SHELL")); % custom_variable("Ishell_Default_Shell", Shell_Default_Shell+" -i"); private variable cmd = "echo 'hello world'"; private variable testbuf = "*bar*"; private variable teststring = "a test line\n"; static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % ishell_mode(cmd=Ishell_Default_Shell); Open a process and attach it to the current buffer. % test_function("ishell_mode"); static define test_ishell_mode() { ishell_mode(); % attach a shell to the buffer % test the attached shell % % to test the proper working, we would need a way to synchronize the % assynchron working (i.e. wait for a response from the command.) % % Maybe input_pending() can be (ab)used in conjunction with an output handler % pushing a string back on the input-stream (ungetkey()). (Maybe a special % blocal "Ishell_output_filter"?) usleep(2000); % wait for the startup insert("pwd"); ishell_send_input(); usleep(1000); % wait for the result % logout ishell_logout(); usleep(1000); % wait for the result } static define test_ishell() { ishell(); % Interactive shell if (whatbuf() != "*ishell*") throw AssertionError, " not in *ishell* buffer"; % % logout % ishell_logout(); % usleep(1000); % wait for the result % close set_buffer_modified_flag(0); delbuf("*ishell*"); } % terminal(cmd = Ishell_Default_Shell); Run a command in a terminal static define test_terminal() { % terminal(); % doesnot close! terminal("exit"); } % shell_command(cmd="", output_handling=0); Run a shell command static define test_shell_command_0() { shell_command(cmd, 0); % output to "*shell-output*" test_equal(get_buffer(), "hello world\n"); test_equal(whatbuf(), "*shell-output*"); close_buffer("*shell-output*"); } static define test_shell_command_named_buffer() { shell_command(cmd, "*foo*"); % output to buffer "*foo*" test_equal(get_buffer(), "hello world\n"); test_equal(whatbuf(), "*foo*"); close_buffer("*foo*"); } static define test_shell_command_1() % insert at point { shell_command(cmd, 1); test_equal(get_buffer(), teststring+"hello world\n"); } static define test_shell_command_2() % replace region/buffer at point { shell_command(cmd, 2); test_equal(get_buffer(), "hello world\n"); } static define test_shell_command_3() % return output { test_equal("hello world\n", shell_command(cmd, 3)); } static define test_shell_command_4() % message output { shell_command(cmd, 4); test_equal("hello world\n", MESSAGE_BUFFER); } static define test_shell_command_ignore() { shell_command(cmd, -1); % ignore output } static define test_shell_command_no_output() { variable modename1, modename2; (modename1, ) = what_mode(); if (bufferp("*shell-output*")) { sw2buf("*shell-output*"); set_buffer_modified_flag(0); close_buffer(); } shell_command(" "); % null-command -> no output test_equal(whatbuf(), testbuf, "output buffer should close if empty"); (modename2, ) = what_mode(); test_equal(modename1, modename2, "must not change modename"); } % shell_cmd_on_region_or_buffer: library function Undocumented static define test_shell_cmd_on_region_or_buffer() { push_visible_mark(); bob(); test_equal(shell_cmd_on_region_or_buffer("cat", 3), teststring); } % shell_cmd_on_region(cmd="", output_handling=0, postfile_args=""); Save region to a temp file and run a command on it static define test_shell_cmd_on_region() { test_equal(shell_cmd_on_region("cat", 3), teststring); } % filter_region(cmd=NULL); Filter the region through a shell command static define test_filter_region() { filter_region("wc"); bob(); push_mark(); fsearch("/tmp"); test_equal(bufsubstr(), " 1 3 12 ", "filter_region output differs from expected value"); } jedmodes-2.5.7/tests/test-console_keys.sl0000644000175400017500000000123711137541402016757 0ustar mildegm% test-console_keys.sl: Test console_keys.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 just test evaluating the file require("unittest"); test_function("evalfile", "console_keys"); test_last_result(1); testmessage("\n console_keys.sl needs interactive testing in a Linux console"); #stop % define set_console_keys() % set_console_keys: undefined Undocumented test_function("set_console_keys"); test_last_result(); % define restore_console_keys() % restore_console_keys: undefined Undocumented test_function("restore_console_keys"); test_last_result(); jedmodes-2.5.7/tests/utf8helper-autoconvert-test.sl0000664000175400017500000001061511137541402020721 0ustar mildegm% utf8helper-test.sl: Test utf8helper.sl % % Copyright © 2006 Guenter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 1.1 2007-06-02 % 1.2 2008-01-20 require("unittest"); % Fixture % ------- require("utf8helper"); % Save default values private variable read_autoconvert = UTF8Helper_Read_Autoconvert; private variable write_autoconvert = UTF8Helper_Write_Autoconvert; % now set to YES % UTF8Helper_Read_Autoconvert = 1; % UTF8Helper_Write_Autoconvert = 1; % Set the _jed_*_hooks % """""""""""""""""""" % make sure the hooks are appended but do not re-append if % already done in utf8helper.sl !if (read_autoconvert) append_to_hook("_jed_find_file_after_hooks", "utf8helper->utf8helper_read_hook"); !if (write_autoconvert) { append_to_hook("_jed_save_buffer_before_hooks", "utf8helper->utf8helper_write_hook"); append_to_hook("_jed_save_buffer_after_hooks", "utf8helper->utf8helper_restore_hook"); } % Test buffers and strings % """""""""""""""""""""""" % encoding[_slang_utf8_ok] is in native encoding private variable encoding = ["latin1", "utf8"]; % testbufs[_slang_utf8_ok] is in native encoding private variable base_dir = path_dirname(__FILE__); private variable teststrings, testbufs = array_map(String_Type, &path_concat, base_dir, ["ch_table-lat1-decimal.txt", "ch_table-utf8-decimal.txt"]); % set up test-strings and Autoconvert custom-vars static define setup() { teststrings = array_map(String_Type, &strread_file, testbufs); } % close test buffers and re-set Autoconvert variables static define teardown() { variable buf; foreach buf (testbufs) { () = find_file(buf); set_buffer_modified_flag(0); close_buffer(); } UTF8Helper_Read_Autoconvert = read_autoconvert; UTF8Helper_Write_Autoconvert = write_autoconvert; } % Test functions % -------------- static define test_read_autoconvert_0() { % do not autoconvert the test buffer: UTF8Helper_Read_Autoconvert = 0; % testbufs[_slang_utf8_ok] is in native encoding % load file in "wrong" encoding () = find_file(testbufs[not(_slang_utf8_ok)]); % look for encoding: test_equal(get_blocal("encoding"), NULL, "do not autoconvert file"); % manually call autoconvert to native encoding utf8helper->autoconvert(1); % (to_native == 1) % test registered encoding: test_equal(get_blocal("encoding"), encoding[_slang_utf8_ok], "should convert to native encoding"); % and content mark_buffer(); test_equal(bufsubstr(), teststrings[_slang_utf8_ok], "content should be in native encoding" + encoding[_slang_utf8_ok]); % re-convert to original encoding utf8helper->autoconvert(0); % look for encoding: test_equal(get_blocal("encoding"), encoding[not(_slang_utf8_ok)], "should re-convert to original encoding"); % look for content: mark_buffer(); test_equal(bufsubstr(), teststrings[not(_slang_utf8_ok)], "should re-convert to " + encoding[not(_slang_utf8_ok)]); } static define test_read_autoconvert_1() { % do autoconvert the test buffers: UTF8Helper_Read_Autoconvert = 1; % load file in "wrong" encoding (should autoconvert) () = find_file(testbufs[not(_slang_utf8_ok)]); % test registered encoding: test_equal(get_blocal("encoding"), encoding[_slang_utf8_ok], "should convert to native " + encoding[_slang_utf8_ok]); mark_buffer(); test_equal(bufsubstr(), teststrings[_slang_utf8_ok], "should convert content to native encoding"); } static define test_read_autoconvert_nothing_to_do() { % do autoconvert the test buffers: UTF8Helper_Read_Autoconvert = 1; % load file in "native" encoding (no autoconvert) () = find_file(testbufs[_slang_utf8_ok]); % test registered encoding: test_equal(get_blocal("encoding"), NULL, "should already be in native " + encoding[_slang_utf8_ok]); mark_buffer(); test_equal(bufsubstr(), teststrings[_slang_utf8_ok], "should convert content to native encoding"); } static define test_read_autoconvert_interactive() { % do not autoconvert the test buffers: UTF8Helper_Read_Autoconvert = -1; % testbufs[_slang_utf8_ok] is in native encoding % load file in "wrong" encoding () = find_file(testbufs[not(_slang_utf8_ok)]); update_sans_update_hook(1); flush("Press any key to continue"); () = getkey(); testmessage("\n buffer encoding is '%S'", get_blocal("encoding")); } jedmodes-2.5.7/tests/test-dict-curl.sl0000664000175400017500000000306511137545560016164 0ustar mildegm% test-dict-curl.sl: Test dict-curl.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % This test requires the curl slang module as well as % an internet connection (to reach "dict.org") or a running % dictd on localhost (don't forget to customize the host variable). % % Is there a way to test the inserted results? require("unittest"); % testmessage("at my site, dict-curl crashs ('Speicherzugriffsfehler') Jed" + % "Jed Version: 0.99.18, S-Lang Version: 2.0.6, slang-curl 0.1.1-5"); % throw AssertionError, "() = evalfile(\"dict-curl\"); crashs Jed"; () = evalfile("dict-curl"); % fixture private variable word = "line"; private variable host = "dict.org"; % public dict server % private variable host = "localhost"; % local dict server private variable database = "!"; % server default private variable strategy = "."; % server default private variable what = "db"; sw2buf("*scratch*"); erase_buffer(); while(markp()) pop_mark_0(); % define dict_define(word, database, host) % dict_define: library function Undocumented test_function("dict_define", word, database, host);test_last_result(); erase_buffer(); % define dict_match(word, strategy, database, host) % dict_match: library function Undocumented test_function("dict_match", word, strategy, database, host); test_last_result(); erase_buffer(); % define dict_show(what, host) % dict_show: library function Undocumented test_function("dict_show", what, host); test_last_result(); erase_buffer(); jedmodes-2.5.7/tests/csvutils-test.sl0000664000175400017500000001735511137545246016162 0ustar mildegm% csvutils-test.sl: Test csvutils.sl Test csvutils.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % Versions: % 0.1 2006-03-03 basic test, check public functions % 0.2 2006-10-05 use test function discovery require("unittest"); require("txtutils"); require("datutils"); % uncomment if you do not want to test default activation test_true(is_defined("buffer_compress"), "public function buffer_compress undefined"); test_true(is_defined("format_table"), "public function format_table undefined"); test_true(is_defined("goto_max_column"), "public function goto_max_column undefined"); testmessage(" only basic test, arguments not tested completely"); % Fixture % ------- require("csvutils"); private variable testbuf = "*bar*"; private variable teststring = "first line \n second line" ; private variable testtable = strtok(teststring); reshape(testtable, [2,2]); private variable linelength = array_map(Int_Type, &strlen, strtok(teststring,"\n")); private variable max_linelength = array_max(linelength); static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % define get_lines() % (kill=0) static define test_get_lines() { variable lines = get_lines(); test_equal(lines, strtok(teststring, "\n")); } % buffer_compress: library function % % SYNOPSIS % Remove excess whitespace characters from the buffer % % USAGE % Void buffer_compress(white="\t ") % % DESCRIPTION % Calls `strcompress' on the buffer or (if visible) region. % % SEE ALSO % trim_buffer, strcompress, get_lines, get_buffer static define test_buffer_compress() { buffer_compress(); test_equal(get_buffer(), strjoin2d(testtable), "buffer_compress() should replace in-line whithespace with tabs"); buffer_compress(" \t"); test_equal(get_buffer(), strjoin2d(testtable, " "), "buffer_compress should call strcompress() on the buffer"); } % strchop2d: undefined % % SYNOPSIS % Chop a string into a 2d-array (lines and columns) % \usage{Array strchop2d(str, col_sep='\t', line_sep='\n', quote=0) % Array strchop2d(String str, String col_sep, line_sep='\n')} % % DESCRIPTION % The 2d equivalent to strchop and strtok. Split the string first into % lines (or equivalent with line_sep != '\n') and then into fields. % Return the result as a 2d-array with missing values set to NULL % % The datatype of col_sep determines which function is used to split % the lines: % if typeof(col_sep) == String_Type, use strtok, else use strchop % % EXAMPLE % % strchop2d(bufsubstr, " \t") % % will return the data in the region interpreted as a white-space % delimited table. % % SEE ALSO % strchop, strtok, read_table static define test_strchop2d() { variable table = strchop2d(teststring, " "); test_equal(table, testtable, "strchop2d should return a 2d array"); } % get_table: undefined % % SYNOPSIS % Return a 2d-string-array with csv data in the region/buffer % % USAGE % String get_table(col_sep="", kill=0) % % DESCRIPTION % Return a 2d-string-array with the data in the region/buffer % The default col_sep=="" means whitespace (any number of spaces or tabs). % The optional argument `kill' tells, whether the table should be % deleted after reading. % % % EXAMPLE % % get_table(" "); % columns are separated by single spaces % get_table(" | "); % columns are separated by space-sourounded bars % get_table(""); % columns are separated by any whitespace (default) % % % SEE ALSO % strchop2d, format_table, insert_table static define test_get_table() { variable table = get_table(); test_equal(table, testtable, "get_table should return a 2d array"); } % strjoin2d: library function % % SYNOPSIS % Print 2d-array as a nicely formatted table to a string % % USAGE % Str strjoin2d(Array a, col_sep="\t", line_sep="\n", align=NULL) % % DESCRIPTION % The function takes an 2d-array and returns a string that represents % the data as an csv-table. It can be seen as a 2d-variant of % strjoin(Array_Type a, String_Type delim). % % SEE ALSO % strjoin, strchop2d, insert_table, get_table static define test_strjoin2d() { variable str = strjoin2d(testtable); test_equal(str, "first\tline\nsecond\tline"); } % insert_table: undefined % % SYNOPSIS % Print 2d-array as a nicely formatted table % % USAGE % Void insert_table(Array a, align="l", col_sep=" ") % % DESCRIPTION % The function takes an 2d-array and writes it as an aligned table. % `col_sep' is the string separating the items on a line. It defaults % to " " (space). % `align' is a format string formed of the key charaters: % "l": left align, % "r": right align, % "c": center align, or % "n": no align (actually every character other than "lrc"), % one for each column. If the string is shorter than the number of columns, % it will be repeated, i.e. if it contains only one character, the % align is the same for all columns) % % EXAMPLE % The call % % insert_table(a, " | ", "llrn"); % % inserts `a' as a table with elements separated by " | " and % first and second columns left aligned, third column right aligned % and last column not aligned. % % SEE ALSO % get_table, strjoin2d, strjoin static define test_insert_table() { erase_buffer(); insert_table(testtable); test_equal(get_buffer(), "first line\n" +"second line\n"); } % format_table: library function % % SYNOPSIS % Adjust a table to evenly spaced columns % % USAGE % format_table(col_sep=NULL, align=NULL, new_sep=NULL) % % DESCRIPTION % Read visible region or buffer as grid data into a 2d array, reformat and % insert again. The indention of the whole table is determined by the point % or mark (whichever is more left) if a visible region is defined. % % If the arguments are not given, they will be asked for in the minibuffer: % `col_sep': the string separating columns (default "" means whitespace) % `align': string of "l", "r", "c", or "n" (see `insert_table') % `new_sep': string to separate the columns in the output. % % SEE ALSO % get_table, insert_table static define test_format_table() { format_table("", "n", "|"); test_equal(get_buffer(), "first|line\nsecond|line\n"); } % define max_column() static define test_max_column() { test_equal(max_column(), max_linelength+1); } % goto_max_column: library function % % SYNOPSIS % Goto the maximal column of the buffer (or region) % % USAGE % goto_max_column() % % DESCRIPTION % Goto the column of the longest line of the buffer (or, if visible, region). % Insert whitespace if needed. The region stays marked. % % If the optional parameter `trim' is nonzero, trailing % whitespace will be removed during the scan. % % NOTES % This function comes handy, if you want to mark a rectagle but % the last line is shorter than preceding lines. % % SEE ALSO % max_column, goto_column, copy_rect static define test_goto_max_column() { goto_max_column(); test_equal(what_column(), max_linelength+1, "point should be at the column of the longest line in the buffer"); } % define compute_columns() % (a, width=SCREEN_WIDTH, col_sep_length=1) static define test_compute_columns() { test_equal(compute_columns(strtok(teststring), 14, 1), 2, "2 columns should fit"); } % define list2table() % (a, cols=compute_columns(a)) static define test_list2table() { variable table = list2table(strtok(teststring), 2); test_equal(table[0,*], testtable[*,0]); test_equal(table[1,*], testtable[*,1]); } jedmodes-2.5.7/tests/structured_text-test.sl0000664000175400017500000001406311137545521017543 0ustar mildegm% structured_text-test.sl: Test structured_text.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); % test availability of public functions (comment to skip) test_true(is_defined("structured_text_hook"), "public fun structured_text_hook undefined"); % Fixture % ------- require("structured_text"); private variable testbuf = "*bar*"; private variable teststring = "a test line"; private variable enumerated_list = ["1. das ist es", "2. auch noch", " 3. drittens", "45.\tlast"]; private variable itemize_list = ["* so", "+ geht's", "* auch", "- nicht", "+\tbesser"]; private define insert_lists() { insert(strjoin(enumerated_list, "\n")+"\n"+strjoin(itemize_list, "\n")); } static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % line_is_list: library function % % SYNOPSIS % Return length of a list marker % % USAGE % line_is_list() % % DESCRIPTION % Check if the current line starts with a list marker matching one of the % regular expressions defined in `Rst_List_Patterns'. % Return length of the list marker (excluding leading whitespace) % % Leaves the editing point at first non-whitespace or eol % % NOTES % Thanks to JED for the regular expressions variant % % SEE ALSO % line_is_empty, Text_List_Patterns static define test_line_is_list() { test_equal(line_is_list(), 0, "text line is no list"); erase_buffer(); insert_lists(); bob(); do test_true(line_is_list(), "should recognize list line"); while (down_1()); % should return the length of the list marker: bob(); variable len, marker_lengths = [3, % "1. das ist es", 4, % "2. auch noch", 3, % " 3. drittens", 4, % "45.\tlast" 2, % "* so", 2, % "+ geht's", 3, % "* auch", 3, % "- nicht", 2]; % "+\tbesser" foreach len (marker_lengths) { test_equal(line_is_list(), len, sprintf("should return list marker length (%d) '%s'", len, get_line())); go_down_1(); } } % define line_is_blank() static define test_line_is_blank() { test_equal(line_is_blank(), 0, "text is not blank"); erase_buffer(); insert("\n \n\t\t\n\n \t\n\n"); bob(); do test_true(line_is_blank(), sprintf("line %d is blank", what_line)); while (down_1()); } % TODO: the remainder is still raw testscript_wizard output #stop % st_is_paragraph_separator: library function % % SYNOPSIS % paragraph separator hook for structured text % % USAGE % st_is_paragraph_separator() % % DESCRIPTION % Return 1 if the current line separates a paragraph, i.e. it % is empty or a list item % % NOTES % Actually, this misses an important difference between empty lines and % first lines of a list item: While an empty line must not be filled % when reformatting, a list item should. % This is why Emacs has 2 Variables, paragraph-separator and paragraph-start. % % SEE ALSO % line_is_empty, line_is_list static define test_st_is_paragraph_separator() { st_is_paragraph_separator(); } % define st_backward_paragraph() static define test_st_backward_paragraph() { st_backward_paragraph(); } % define st_mark_paragraph() static define test_st_mark_paragraph() { st_mark_paragraph(); } % st_indent: library function % % SYNOPSIS % indent-line for structured text % % USAGE % st_indent() % % DESCRIPTION % Indent the current line, taking care of list markers as defined in % `Text_List_Patterns'. % % NOTES % Expanded from example in hooks.txt % % SEE ALSO % st_is_paragraph_separator, line_is_list, Text_List_Patterns static define test_st_indent() { st_indent(); } % st_newline_and_indent: library function % % SYNOPSIS % newline_and_indent for structured text % % USAGE % st_newline_and_indent () % % DESCRIPTION % Indent to level of preceding line % % NOTES % We need a separate definition, as by default newline_and_indent() uses the % indent_hook (which structured_text.sl sets to st_indent (considering list % markers) while with Enter we want more likely to start a new list topic. % % SEE ALSO % st_indent, st_indent_relative static define test_st_newline_and_indent() { st_newline_and_indent(); } % define st_format_paragraph(); % forward definition static define test_st_format_paragraph() { st_format_paragraph(); } % define st_format_paragraph() static define test_st_format_paragraph() { st_format_paragraph(); } % structured_text_hook: library function % % SYNOPSIS % Formatting hook for "ASCII markup" % % USAGE % structured_text_hook() % % DESCRIPTION % This function calls a list of buffer hooks (see Help>Browse-Docs>Hooks) % suitable for proper indenting and paragraph formatting of documents using % "ASCII markup". % % Paragraphs are separated by blank lines and indented to the same column % as the first line of the paragraph. % % List items that start with a special list marker (e.g. '* ' or '3.') are % considered paragraphs as well, even when not preceded by an empty line. % Continuation lines are indented to the column that matches the start of the % list text.% % % EXAMPLE % To enable the structured text formatting in `text_mode', set an alias: % % define text_mode_hook() { structured_text_hook(); } % % % NOTES % `rst_mode' calls `structured_text_hook' by default. % % SEE ALSO % st_indent, st_backward_paragraph, st_mark_paragraph static define test_structured_text_hook() { structured_text_hook(); } jedmodes-2.5.7/tests/test-css1.sl0000644000175400017500000000112611137541402015130 0ustar mildegm% test-css1.sl: Test css1.sl % % Copyright © 2006 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); sw2buf("*scratch*"); % public define css1_mode() { % css1_mode: library function Undocumented test_function("css1_mode"); test_last_result(); test_equal(get_mode_name(), "css1"); no_mode(); % test the automatic mode setting at loading a file test_function("find_file", "test.css"); % new file, empty buffer test_equal(get_mode_name(), "css1"); if (bufferp("test.css")) delbuf("test.css"); jedmodes-2.5.7/tests/listing-test.sl0000644000175400017500000002404211137541401015731 0ustar mildegm% test-listing-list.sl: Test listing-list.sl Test listing.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); autoload("get_buffer", "txtutils"); % test availability of public functions (comment to skip) % test_true(is_defined("listing_mode"), "public fun listing_mode undefined"); require("listing"); % private namespace: `listing' % fixture static define setup() { sw2buf("*bar*"); insert("three\ntest\nlines"); } static define teardown() { sw2buf("*bar*"); set_buffer_modified_flag(0); close_buffer("*bar*"); } private define clear_input() { while (input_pending(0)) { () = getkey(); } } % static define null_fun() { } % null_fun: just return the arguments static define test_null_fun() { variable result, result2; listing->null_fun(); test_stack(); result = listing->null_fun(1); test_equal(result, 1); (result, result2) = listing->null_fun(1, "2"); test_equal({result, result2}, {1, "2"}); test_stack(); } % static define get_confirmation() % (prompt, [default]) % y: yes, % n: no, % !: all, % q:quit, % Int listing->get_confirmation(Str prompt, Str default=""); Ask whether a list of actions should go on static define test_get_confirmation_yes() { listing->Dont_Ask = 0; clear_input(); ungetkey('y'); test_equal(1, listing->get_confirmation("Prompt"), "key 'y' should result in 1"); test_equal(listing->Dont_Ask, 0, "key 'y' should not change Dont_Ask"); clear_input(); } static define test_get_confirmation_no() { listing->Dont_Ask = 0; clear_input(); ungetkey('n'); test_equal(0, listing->get_confirmation("Prompt"), "key 'n' should result in 0"); test_equal(listing->Dont_Ask, 0, "key 'n' should not change Dont_Ask"); clear_input(); } static define test_get_confirmation_with_default() { listing->Dont_Ask = 0; clear_input(); ungetkey('\r'); test_equal(1, listing->get_confirmation("Prompt", "y"), "key Return should use default ('y')"); ungetkey('\r'); test_equal(0, listing->get_confirmation("Prompt", "n"), "key Return should use default ('n')"); test_equal(listing->Dont_Ask, 0, "key Return should not change Dont_Ask"); ungetkey('n'); test_equal(0, listing->get_confirmation("Prompt", "y"), "key 'n' should override default 'y'"); ungetkey('y'); test_equal(1, listing->get_confirmation("Prompt", "n"), "key 'y' should override default 'n'"); clear_input(); } static define test_get_confirmation_all() { listing->Dont_Ask = 0; clear_input(); ungetkey('!'); test_equal(1, listing->get_confirmation("Prompt"), "key '!' should result in 1"); ungetkey('n'); test_equal(1, listing->get_confirmation("Prompt"), "Dont_Ask 1 should ignore key (not wait for it)"); test_equal('n', getkey(), "Dont_Ask 1 should ignore key"); clear_input(); } static define test_get_confirmation_abort() { variable err; listing->Dont_Ask = 0; clear_input(); ungetkey('q'); !if (input_pending(0)) throw ApplicationError, "there should be a 'q' waiting at input"; err = test_for_exception("listing->get_confirmation", "Prompt"); if (err == NULL) throw AssertionError, "key 'q' should abort get_confirmation()"; if (err.error != UserBreakError) throw AssertionError, "key 'q' should throw UserBreakError not " + err.descr; clear_input(); } static define test_get_confirmation_wrong_key() { variable err; listing->Dont_Ask = 0; clear_input(); buffer_keystring("eeeee"); % five nonaccepted keys !if (input_pending(0)) throw ApplicationError, "there should be waiting input"; err = test_for_exception("listing->get_confirmation", "Prompt"); if (err == NULL) throw AssertionError, "three wrong keys should abort get_confirmation()"; if (err.error != UserBreakError) throw AssertionError, "three wrong keys should throw UserBreakError not " + err.descr; clear_input(); } % public define listing_mode() % listing_mode: library function Undocumented static define test_listing_mode() { listing_mode(); test_equal(pop2list(what_mode(),2 ), {"listing", 0}); test_equal(what_keymap, "listing"); } % static define tags_length() % (scope=2) % Int tags_length(scope=2); Return the number of tagged lines. static define test_tags_length() { listing_mode(); test_equal(0, listing->tags_length(), "no tagged line"); } static define test_tags_length_0() { listing_mode(); test_equal(1, listing->tags_length(0), "one current line"); } static define test_tags_length_1() { listing_mode(); test_equal(1, listing->tags_length(1), "one current line"); } static define test_tags_length_2() { listing_mode(); test_equal(0, listing->tags_length(2), "no tagged line"); } % static define line_is_tagged() % line_is_tagged: Return 0 or (index of tagged line +1) static define test_line_is_tagged() { listing_mode(); test_equal(0, listing->line_is_tagged()); } % static define tag() % (how = 1) % tag(how = 1); Mark the current line and append to the Tags list static define test_tag() { listing_mode(); listing->tag(); test_stack(); % now there should be 1 tagged line test_equal(1, listing->line_is_tagged(), "current line is tagged"); test_equal(1, listing->tags_length, "one tagged line"); % tag a second line bob(); listing->tag(); test_equal(2, listing->tags_length(), "2 tagged lines"); test_equal(2, listing->line_is_tagged(), "current line should be second tag"); % untag current line listing->tag(0); test_stack(); test_equal(0, listing->line_is_tagged(), "current line not tagged"); test_equal(1, listing->tags_length, "one tagged line"); % toggle current line tag listing->tag(2); test_equal(2, listing->tags_length(), "2 tagged lines"); } % static define tag_all() % (how = 1) % tag_all(how = 1); (Un)Tag all lines static define test_tag_all() { listing_mode(); bob(); listing->tag_all(); test_stack(); test_equal(3, listing->tags_length(), "3 tagged lines"); test_true(bobp(), "tag_all() should not move the point"); % untag current line listing->tag(0); test_equal(0, listing->line_is_tagged(), "current line not tagged"); test_equal(2, listing->tags_length, "should be 2 tagged lines"); % toggle listing->tag_all(2); test_equal(1, listing->line_is_tagged(), "current line should be tagged"); test_equal(1, listing->tags_length, "should be 1 tagged line"); % untag listing->tag_all(0); test_equal(0, listing->tags_length(2), "no tagged line"); } % static define tag_matching() %(how) % tag_matching: undefined Undocumented static define test_tag_matching() { clear_input(); listing_mode(); buffer_keystring("th\r"); % simulate keyboard input update_sans_update_hook(1); listing->tag_matching(); test_equal(1, listing->tags_length, "should be 1 tagged line"); clear_input(); buffer_keystring("t\r"); update_sans_update_hook(1); listing->tag_matching(); test_equal(2, listing->tags_length, "should be 2 tagged lines"); clear_input(); } % public define listing_list_tags() % (scope=2, untag=0) % scope: 0 current line, 1 tagged or current line(s), 2 tagged lines % Arr[Str] listing_list_tags(scope=2, untag=0); Return an array of tagged lines. static define test_listing_list_tags() { listing_mode(); listing->tag_all(); test_equal(3, listing->tags_length, "there should be 3 tagged lines"); test_equal(["three", "test", "lines"], listing_list_tags(), "listing_list_tags() should return the tagged lines as String array"); } static define test_listing_list_tags_0() { listing_mode(); listing->tag_all(); !if (_eqs(["lines"], listing_list_tags(0))) throw AssertionError, "listing_list_tags(0) should return the current line as String array"; !if (3 == listing->tags_length) throw AssertionError, "there should be 3 tagged lines"; } static define test_listing_list_tags_1_non_tagged() { listing_mode(); !if (_eqs(["lines"], listing_list_tags(1))) throw AssertionError, "listing_list_tags(1) should return the tagged lines as String array"; !if (0 == listing->tags_length) throw AssertionError, "there should be no tagged line"; } static define test_listing_list_tags_1_tagged() { listing_mode(); listing->tag_all(); !if (_eqs(["three", "test", "lines"], listing_list_tags(1))) throw AssertionError, "listing_list_tags(1) should return the tagged lines as String array"; !if (3 == listing->tags_length) throw AssertionError, "there should be 3 tagged lines"; } static define test_listing_list_tags_2_1() { listing_mode(); listing->tag_all(); !if (_eqs(["three", "test", "lines"], listing_list_tags(2, 1))) throw AssertionError, "listing_list_tags should return the tagged lines as String array"; !if (0 == listing->tags_length) throw AssertionError, "all lines should be untagged"; } static define test_listing_list_tags_2_2() { listing_mode(); listing->tag_all(); !if (_eqs(["three", "test", "lines"], listing_list_tags(2, 2))) throw AssertionError, "listing_list_tags should return the tagged lines as String array"; !if (bobp and eobp) { testmessage("buffer content: '%s'", get_buffer()); throw AssertionError, "all lines should be deleted"; } } % public define listing_map() % (scope, fun, [args]) % listing_map(Int scope, Ref fun, Any [args]); Call a function for marked lines. % % this is implicitely tested by listing_list_tags() % static define listing_update_hook() % listing_update_hook: undefined Undocumented % % this is interactively tested % static define listing_menu (menu) % listing_menu: undefined Undocumented % static define test_listing_menu() % { % listing_mode(); % menu_select_menu("Global.M&ode.Tag &All"); % !if (3 == listing->tags_length) % throw AssertionError, "there should be 3 tagged lines"; % } % static define edit() % edit: undefined Undocumented % test_function("listing->edit"); % test_last_result(); jedmodes-2.5.7/tests/test-browse_url.sl0000664000175400017500000000320611137541402016445 0ustar mildegm% test-browse_url.sl: Test browse_url.sl with unittest.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); variable test_url = "http://www.example.org"; % find_url(url=read_mini, cmd = Browse_Url_Download_Cmd); Find a file by URL % public define find_url() %(url=read_mini, cmd = Browse_Url_Download_Cmd) test_function("find_url", test_url); test_last_result(); test_equal(whatbuf(), test_url); delbuf(test_url); % view_url(Str url=read_mini, Str cmd= Browse_Url_Viewer); View an ASCII rendering of a URL % public define view_url() %(url=read_mini, cmd= Browse_Url_Viewer) test_function("view_url", test_url); test_last_result(); test_equal(whatbuf(), "*"+test_url+"*"); delbuf("*"+test_url+"*"); % public define browse_url_x() %(url, cmd=Browse_Url_X_Browser) % browse_url_x(Str url=ask, Str cmd=Browse_Url_X_Browser); Open a URL in a browser testmessage("\n browse_url_x() needs interactive testing,"); testmessage("\n (opens a document in an external browser with system())"); % test_function("browse_url_x", test_url); % test_last_result(); % browse_url_x(): OK () % public define browse_url() %(url=read_mini, cmd=Browse_Url_Browser) % browse_url() %(url=read_mini, cmd=Browse_Url_Browser); Open the url in a browser testmessage("\n browse_url() needs interactive testing,"); testmessage("\n (opens a document in an external browser with system())"); % (commented out to prevent side effects) % test_function("browse_url", test_url); % test_last_result(); % browse_url(http://jedmodes.sourceforge.net/mode/cua/index.php): OK () jedmodes-2.5.7/tests/test-calc.sl0000644000175400017500000001017011137541446015170 0ustar mildegm% test-calc.sl: % Test calc.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 basic test for errors with call of public functions require("unittest"); % private namespace: `calc' % Open the calc buffer % calc: library function Undocumented % public define calc () test_function("calc"); test_last_result(); test_equal(whatbuf(), "Calculator"); % calc2: library function Undocumented % public define calc2 () test_function("calc2"); test_last_result(); % clean up and abort (TODO test remaining functions) sw2buf("Calculator"); set_buffer_modified_flag(0); delbuf("Calculator"); delbuf("*calcres*"); #stop % calc_select_expression_buf: undefined Undocumented % static define calc_select_expression_buf () test_function("calc->calc_select_expression_buf"); test_last_result(); % history_next: undefined Undocumented % static define history_next () test_function("calc->history_next"); test_last_result(); % history_prev: undefined Undocumented % static define history_prev () test_function("calc->history_prev"); test_last_result(); % calc_next_expression: undefined Undocumented % public define calc_next_expression () test_function("calc_next_expression"); test_last_result(); % calc_format_binary: undefined Undocumented % static define calc_format_binary (val) test_function("calc->calc_format_binary"); test_last_result(); % calc_display_value: undefined Undocumented % static define calc_display_value(val, linepref); test_function("calc->calc_display_value"); test_last_result(); % calc_display_value: undefined Undocumented % static define calc_display_value(val, linepref) test_function("calc->calc_display_value"); test_last_result(); % calc_display_stack: undefined Undocumented % static define calc_display_stack () test_function("calc->calc_display_stack"); test_last_result(); % calc_display_variables: undefined Undocumented % public define calc_display_variables () test_function("calc_display_variables"); test_last_result(); % calc_result_window: undefined Undocumented % public define calc_result_window () test_function("calc_result_window"); test_last_result(); % calc_make_calculation: undefined Undocumented % public define calc_make_calculation () test_function("calc_make_calculation"); test_last_result(); % calc_find_max_id: undefined Undocumented % static define calc_find_max_id () test_function("calc->calc_find_max_id"); test_last_result(); % calc_read_file: undefined Undocumented % public define calc_read_file () test_function("calc_read_file"); test_last_result(); % calc_write_file: undefined Undocumented % public define calc_write_file () test_function("calc_write_file"); test_last_result(); % calc_float_format: undefined Undocumented % public define calc_float_format () test_function("calc_float_format"); test_last_result(); % calc_help: undefined Undocumented % public define calc_help () test_function("calc_help"); test_last_result(); % calc_prepare_keymap: undefined Undocumented % static define calc_prepare_keymap () test_function("calc->calc_prepare_keymap"); test_last_result(); % calc_reset_buffer: undefined Undocumented % public define calc_reset_buffer() test_function("calc_reset_buffer"); test_last_result(); % init_menu: undefined Undocumented % static define init_menu (menu) test_function("calc->init_menu"); test_last_result(); % calc_start: undefined Undocumented % static define calc_start () test_function("calc->calc_start"); test_last_result(); % calc_mode_dec: undefined Undocumented % public define calc_mode_dec() test_function("calc_mode_dec"); test_last_result(); % calc_mode_hex: undefined Undocumented % public define calc_mode_hex() test_function("calc_mode_hex"); test_last_result(); % calc_mode_oct: undefined Undocumented % public define calc_mode_oct() test_function("calc_mode_oct"); test_last_result(); % calc_mode_bin: undefined Undocumented % public define calc_mode_bin() test_function("calc_mode_bin"); test_last_result(); % calc_mode_all: undefined Undocumented % public define calc_mode_all() test_function("calc_mode_all"); test_last_result(); jedmodes-2.5.7/tests/rst-outline-test.sl0000664000175400017500000001567211137545505016571 0ustar mildegm% rst-outline-test.sl: Test rst-outline.sl % % Copyright © 2007 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % Usage % ----- % Place in the jed library path. % % Versions % -------- % 0.1 2007-11-20 require("unittest"); % Fixture % ------- require("rst-outline"); private variable testbuf = "*bar*"; private variable teststring = "a test line"; static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % private namespace: `rst' % Test functions % -------------- % static define heading() % ([underline_character]) % as string static define test_heading() { variable ul_string = string_repeat("+", strlen(teststring)); rst->heading("+"); go_up_1(); test_equal(ul_string, line_as_string(), "should underline with given character"); insert(ul_string + "\t"); rst->heading(ul_string[[0]]); test_true(eobp(), "should replace existing section markup"); go_up_1(); test_equal(ul_string, line_as_string(), "should adapt length of underline"); ul_string = string_repeat("-", strlen(teststring)); rst->heading(ul_string[[0]]); test_true(eobp(), "should replace existing section markup"); go_up_1(); test_equal(ul_string, line_as_string(), "should change section markup"); } static define test_heading_replace() { variable ul_string = string_repeat("+", strlen(teststring)); newline(); insert(ul_string + " " + ul_string); bob(); rst->heading(ul_string[[0]]); go_up_1(); test_equal(ul_string, line_as_string(), "should insert section markup"); eob(); test_equal(ul_string + " " + ul_string, line_as_string(), "should keep next line if it is not section markup"); } static define test_heading_numeric() { variable level, ul_string; for (level = 1; level < 2; level++) { ul_string = string_repeat(Rst_Underline_Chars[[level-1]], strlen(teststring)); rst->heading(level); go_up_1(); test_equal(ul_string, line_as_string(), "should underline with given level, replacing existing markup"); } } #ifexists list_routines % extract section title and format for tokenlist % static define extract_heading (nRegexp) % static define test_extract_heading() { variable adornment = string_repeat("+", strlen(teststring)); % testmessage("\n" + line_as_string); insert("\n" + adornment); % testmessage("\n" + line_as_string); bol(); test_equal(" + a test line", rst->extract_heading(0), "should return section header preceded by adornment character"); } static define test_extract_heading_subheading() { erase_buffer(); insert("section\n"); insert("+++++++\n"); insert("subsection\n"); insert("----------"); % extract first heading and update level-list bol(); % point is at first matching adornment char when extract_heading is called () = rst->extract_heading(0); bol(); test_equal(" - subsection", rst->extract_heading(0), "should return subsection header"); } #endif % TODO: move this to the relevant places as % check for well formatted heading is now in fsearch_heading() #iffalse static define test_extract_heading_1() { test_equal("", rst->extract_heading(0), "should return empty string if not on a section header"); } static define test_extract_heading_3() { insert("\n------"); bol(); test_equal("", rst->extract_heading(0), "should return empty string if underline too short"); } static define test_extract_heading_4() { insert("\n\n\n------"); bol(); test_equal("", rst->extract_heading(0), "should return empty string if on a transition"); } static define test_extract_heading_5() { insert("\n\n\n::"); bol(); test_equal("", rst->extract_heading(0), "should return empty string if on a literal block marker"); } #endif #stop % define is_heading_underline() static define test_is_heading_underline() { is_heading_underline(); } % static define has_overline() static define test_has_overline() { rst->has_overline(); } % static define section_level(adornment) static define test_section_level() { rst->section_level(); } % static define fsearch_heading() % (max_level=100, skip_hidden=0) static define test_fsearch_heading() { rst->fsearch_heading(); } % static define bsearch_heading() % (max_level=100, skip_hidden=0) static define test_bsearch_heading() { rst->bsearch_heading(); } % define update_adornments() static define test_update_adornments() { update_adornments(); } % static define next_heading() % (max_level=100) static define test_next_heading() { rst->next_heading(); } % static define previous_heading() % (max_level=100) static define test_previous_heading() { rst->previous_heading(); } % rst->skip_section: library function % % SYNOPSIS % Go to the next heading of same level or above % % USAGE % skip_section() % % DESCRIPTION % Skip content and sub-sections. % % NOTES % Point is placed at bol of next heading or eob % % SEE ALSO % rst_mode; rst->heading static define test_skip_section() { skip_section(); } % static define bskip_section() static define test_bskip_section() { rst->bskip_section(); } % static define up_section() static define test_up_section() { rst->up_section(); } % rst->heading: library function % % SYNOPSIS % Mark up current line as section title % % USAGE % heading([adornment]) % % DESCRIPTION % Mark up current line as section title by underlining it. % Replace eventually existing underline. % % If `adornment' is an integer (or a string convertible to an % integer), use the adornment for this section level. % % Read argument if not given % * "canonical" adornments are listed starting with already used ones % sorted by level % * integer argument level can range from 1 to `no of already defined levels` % % NOTES % % SEE ALSO % rst_mode, Rst_Underline_Chars static define test_heading() { heading([adornment]); } % static define promote_heading(n) static define test_promote_heading() { rst->promote_heading(); } % static define normalize_headings() static define test_normalize_headings() { rst->normalize_headings(); } % static define extract_heading(regexp_index) static define test_extract_heading() { rst->extract_heading(); } % public define rst_list_routines_setup(opt) static define test_rst_list_routines_setup() { rst_list_routines_setup(); } % static define fold_buffer(max_level) static define test_fold_buffer() { rst->fold_buffer(); } % static define fold_section(max_level) static define test_fold_section() { rst->fold_section(); } % static define emacs_outline_bindings() % (pre = _Reserved_Key_Prefix) static define test_emacs_outline_bindings() { rst->emacs_outline_bindings(); } % static define rst_outline_bindings() static define test_rst_outline_bindings() { rst->rst_outline_bindings(); } jedmodes-2.5.7/tests/strutils-test.sl0000664000175400017500000001706311137545527016175 0ustar mildegm% : Test strutils.sl % % Copyright © 2007 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % Usage % ----- % Place in the jed library path. % % Versions % -------- % 0.1 2008-12-15 require("unittest"); % test availability of public functions (comment to skip) test_true(is_defined("str_re_replace_by_line"), "public fun str_re_replace_by_line undefined"); % Fixture % ------- require("strutils"); private variable testbuf = "*bar*"; private variable teststring = "a test line"; static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % string_nth_match: library function % Return the (nth) substring of the last call to string_match static define test_string_nth_match() { variable str = "affenstark"; test_equal(3, string_match(str, "f\\(.n\\)" , 1)); test_equal("fen", string_nth_match(str, 0)); test_equal("en", string_nth_match(str, 1)); } static define test_string_nth_match_unicode() { variable str = "Wärmebrücke"; % string_match uses byte semantics, so match is at byte 4 test_equal(4, string_match(str, "r\\(.e\\)" , 1)); test_equal("rme", string_nth_match(str, 0)); test_equal("me", string_nth_match(str, 1)); } static define test_string_nth_match_unicode2() { variable str = "Wärmebrücke"; test_equal(2, string_match(str, "är\\(.e\\)" , 1)); test_equal("ärme", string_nth_match(str, 0)); test_equal("me", string_nth_match(str, 1)); } % string_get_match: library function % Return a substring matching a regexp pattern % String string_get_match(String str, String pattern, pos=1, nth=0) static define test_string_get_match() { variable str = "Wärmebrücke", pat = "är\\(.e\\)"; test_equal("ärme", string_get_match(str, pat, 1, 0)); test_equal("ärme", string_get_match(str, pat)); test_equal("me", string_get_match(str, pat, 1, 1)); } #stop % TODO: add tests for the remaining functions % str_re_replace: library function % % SYNOPSIS % Regexp replace max_n occurences of `pattern' with `rep' % % USAGE % (String, Integer) str_re_replace(str, pattern, rep, max_n) % % DESCRIPTION % Regexp equivalent to `strreplace'. Replaces up to max_n occurences % of `pattern' with `rep'. % % Returns the string with replacements and the number of replacements done. % % NOTES % Currently, rep may contain 1 backref '\1' % TODO: allow up to 9 expansions % % SEE ALSO % str_re_replace_all, strreplace, string_get_match static define test_str_re_replace() { (Str, = i) str_re_replace(str, pattern, rep, max_n); } % str_re_replace_all: library function % % SYNOPSIS % Regexp replace all occurences of `pattern' with `rep' % % USAGE % String str_re_replace_all(str, pattern, rep) % % DESCRIPTION % Regexp equivalent to `str_replace_all'. Replaces all occurences % of `pattern' with `rep' and returns the resulting string. % % Other than using `query_replace_match', this function % will find and replace across line boundaries. % % NOTES % As the whole string is searched as one piece, `str_re_replace_all' % will become *very* slow for larger strings. If there is no need to find % matches across lines, `str_re_replace_by_line' should be used. % % SEE ALSO % str_re_replace, str_replace_all, str_re_replace_by_line static define test_str_re_replace_all() { Str = str_re_replace_all(str, pattern, rep); } % str_re_replace_by_line: library function % % SYNOPSIS % Regexp replace `pattern' with `rep' % % USAGE % str_re_replace_by_line(str, pattern, rep) % % DESCRIPTION % Replace all occurences of the regular expression `pattern' with % `rep'. In contrast to `str_re_replace_all', this function % will not find matches across lines (similar to a regexp replace in a % buffer). % % NOTES % This function splits `str' into an array of lines, calls % `str_re_replace_all' on them and joins the result. As result, it % takes 4 seconds to make 15000 replacements in a 10 MB string on a 2 GHz % cpu/1 GB ram computer (where str_re_replace_all took hours). % % SEE ALSO % str_re_replace, str_re_replace_all static define test_str_re_replace_by_line() { str_re_replace_by_line(str, = pattern, rep); } % strcap: library function % % SYNOPSIS % Capitalize a string % % USAGE % String strcap(String str) % % DESCRIPTION % Convert a string to a capitalized version (first character upper case, % other characters lower case) and return the result. % % SEE ALSO % strlow, strup, xform_region, capitalize_word, define_case static define test_strcap() { Str = strcap(Str str); } % string_reverse: library function % % SYNOPSIS % Reverse the order of characters in a string % % USAGE % String string_reverse(String s) % % DESCRIPTION % Reverse the order of characters in a string % % EXAMPLE % % string_reverse("abcd") == "dcba" % % % SEE ALSO % array_reverse static define test_string_reverse() { Str = string_reverse(Str s); } % string_repeat: library function % % SYNOPSIS % Repeat a string n times % % USAGE % String string_repeat(String str, Integer n) % % DESCRIPTION % Concatenate `n' replicas of string `str' and return the result. % % EXAMPLE % % string_repeat("+-", 4) == "+-+-+-+-" % % % NOTES % This is equivalent to str*n in Python % % SEE ALSO % array_repeat static define test_string_repeat() { Str = string_repeat(Str str, i n); } % strwrap: library function % % SYNOPSIS % Split a string into chunks of maximal `wrap' chars % % USAGE % Array strwrap(String str, wrap=WRAP, delim=' ', quote = 0) % % DESCRIPTION % Line wrapping for strings: Split a string into chunks of maximal % `wrap' chars, breaking at `delim' (if not quoted, cv. `strchop'). % Return array of strings. % % SEE ALSO % strbreak, strtok, WRAP static define test_strwrap() { Arr strwrap(Str str, wrap=WRAP, delim=' ', quote = 0); } % strbreak: library function % % USAGE % (String, String) strbreak(String str, wrap=WRAP, delim=' ') % % DESCRIPTION % One-time string wrapping: Split a string at a breakpoint defined by delim, % so that the first part is no longer than `wrap' characters. % Return two strings. % % The delimiter is left at the end of the first return string. % % SEE ALSO % strwrap, WRAP static define test_strbreak() { (Str, Str) strbreak(Str str, wrap=WRAP, delim=' '); } % get_keystring: library function % % SYNOPSIS % Get the keystring of the next keypress event % % USAGE % get_keystring() % % DESCRIPTION % Wait for the next keypress and return all waiting input. % This is the opposite of buffer_keystring. % % EXAMPLE % % define showkey_literal() % { % flush ("Press key:"); % variable key = get_keystring(); % if (prefix_argument(0)) % insert (key); % else % { % #ifdef XWINDOWS % key += sprintf(" X-Keysym: %X", X_LAST_KEYSYM); % #endif % message ("Key sends " + key); % } % } % % % NOTES % This may err for fast typing on slow terminals. % % SEE ALSO % getkey, ungetkey, input_pending, buffer_keystring static define test_get_keystring() { get_keystring(); } % strsplit: library function % % SYNOPSIS % Split a string in tokens. % % USAGE % strsplit(str, sep, max_n=0) % % DESCRIPTION % Return a list of the words in the string `str', using `sep' as the % delimiter string. % % SEE ALSO % strchop, strtok, strreplace, is_substr static define test_strsplit() { strsplit(str, sep, max_n=0); } jedmodes-2.5.7/tests/test-dict-cli.sl0000644000175400017500000000246511137545550015766 0ustar mildegm% test-dict-cli.sl: Test dict-cli.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % This test requires an internet connection (to reach "dict.org") or a running % dictd on localhost (customize by (un)commenting the right host variable). % % Is there a way to test the returned results? require("unittest"); require("dict-cli"); % fixture private variable word = "line"; private variable host = "dict.org"; % public dict server % private variable host = "localhost"; % local dict server private variable database = "!"; % server default private variable strategy = "."; % server default private variable what = "db"; sw2buf("*scratch*"); erase_buffer(); while(markp()) pop_mark_0(); % define dict_define(word, database, host) % dict_define: library function Undocumented test_function("dict_define", word, database, host); test_last_result(); erase_buffer(); % define dict_match(word, strategy, database, host) % dict_match: library function Undocumented test_function("dict_match", word, strategy, database, host); test_last_result(); erase_buffer(); % define dict_show(what, host) % dict_show: library function Undocumented test_function("dict_show", what, host); test_last_result(); erase_buffer(); jedmodes-2.5.7/tests/utf8helper-test.sl0000664000175400017500000001060611137541447016363 0ustar mildegm% utf8helper-test.sl: Test utf8helper.sl % % Copyright © 2006 Guenter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 1.1 2007-06-02 require("unittest"); % test availability of public functions (comment to skip) test_true(is_defined("latin1_to_utf8"), "public fun latin1_to_utf8 undefined"); test_true(is_defined("utf8_to_latin1"), "public fun utf8_to_latin1 undefined"); test_true(is_defined("strtrans_latin1_to_utf8"), "public fun strtrans_latin1_to_utf8 undefined"); test_true(is_defined("strtrans_utf8_to_latin1"), "public fun strtrans_utf8_to_latin1 undefined"); % Fixture % ------- require("utf8helper"); % testbufs[_slang_utf8_ok] is in native encoding private variable teststrings = {}, base_dir = path_dirname(__FILE__), testbufs = ["ch_table-lat1-decimal.txt", "ch_table-utf8-decimal.txt"]; static define setup() { % do not autoconvert the test buffers: UTF8Helper_Read_Autoconvert = 0; variable buf; foreach buf (testbufs) { % load file () = find_file(path_concat(base_dir, buf)); % unset readonly flag (and unset file binding), % so that we can edit without further questions. variable file, dir, name, flags; (file, dir, name, flags) = getbuf_info(); setbuf_info("", dir, name, flags & ~0x8); % extract teststring mark_buffer(); list_append(teststrings, bufsubstr()); } } static define teardown() { variable buf; foreach buf (testbufs) { sw2buf(buf); set_buffer_modified_flag(0); close_buffer(); } } % Test functions % -------------- % public define latin1_to_utf8() static define test_latin1_to_utf8() { % transform buffer; sw2buf(testbufs[0]); latin1_to_utf8(); test_equal(get_blocal_var("encoding"), "utf8", "should set blocal var 'encoding'"); mark_buffer(); variable str = bufsubstr(); test_equal(str, teststrings[1]); test_unequal(str, teststrings[0]); } % public define utf8_to_latin1 () static define test_utf8_to_latin1() { sw2buf(testbufs[1]); utf8_to_latin1(); test_equal(get_blocal_var("encoding"), "latin1", "should set blocal var 'encoding'"); mark_buffer(); variable str = bufsubstr(); test_unequal(str, teststrings[1]); test_equal(str, teststrings[0]); } static define test_utf8_to_latin1_reset_CASE_SEARCH() { variable old_case_search = CASE_SEARCH; CASE_SEARCH = 0; sw2buf(testbufs[1]); set_readonly(1); try { utf8_to_latin1(); } catch RunTimeError: { } test_equal(CASE_SEARCH, 0, "should reset CASE_SEARCH"); CASE_SEARCH = old_case_search; } % public define strtrans_latin1_to_utf8(str) static define test_strtrans_latin1_to_utf8() { test_unequal(strtrans_latin1_to_utf8(teststrings[0]), teststrings[0]); test_equal(strtrans_latin1_to_utf8(teststrings[0]), teststrings[1]); } static define test_strtrans_latin1_to_utf8_empty() { test_equal(strtrans_latin1_to_utf8(""), ""); } % public define strtrans_utf8_to_latin1(str) static define test_strtrans_utf8_to_latin1() { test_unequal(strtrans_latin1_to_utf8(teststrings[1]), teststrings[1]); test_equal(strtrans_utf8_to_latin1(teststrings[1]), teststrings[0]); } static define test_strtrans_utf8_to_latin1_empty() { test_equal(strtrans_utf8_to_latin1(""), ""); } % scan for non-printable characters in current buffer % static define has_invalid_chars() static define test_find_invalid_char() { sw2buf(testbufs[not(_slang_utf8_ok)]); % testbuffer in other encoding bob(); test_true(utf8helper_find_invalid_char()); } static define test_has_invalid_char_false() { sw2buf(testbufs[_slang_utf8_ok]); % testbuffer in native encoding bob(); test_equal(0, utf8helper_find_invalid_char()); } #stop #if (_slang_utf8_ok) % define insert_after_char(char) static define test_insert_after_char() { insert_after_char(); } % define stroke() { insert_after_char(0x336); } static define test_stroke() { stroke(); } % define underline() { insert_after_char(0x332); } static define test_underline() { underline(); } % define double_underline() { insert_after_char(0x333); } static define test_double_underline() { double_underline(); } % define overline() { insert_after_char(0x305); } static define test_overline() { overline(); } % define double_overline() { insert_after_char(0x33f); } static define test_double_overline() { double_overline(); } #endif jedmodes-2.5.7/tests/pymode-test.sl0000664000175400017500000004657411137541401015575 0ustar mildegm% pymode-test.sl: Test pymode.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); % test availability of public functions (comment to skip) test_true(is_defined("python_shell"), "public fun python_shell undefined"); test_true(is_defined("python_mode"), "public fun python_mode undefined"); % Fixture % ------- require("pymode"); private variable testbuf = "*pymode test*"; private variable teststring = strjoin( ["import sys", "from os.path import dirname, exists, \\", " lexists", "# a comment", "def unindent(self,", " indent=None):", " \"\"\"Return unindented list of lines", "", " Unindents by the least (or given) indentation level\"\"\"", " if indent is None:", " indent = self.min_indent()", " else:", " indent = 0", " par = [line[indent:] ", " for line in self]", " return PylitParagraph(par)", "" ], "\n"); % show_string(teststring); private variable literal_strings__teststring = strjoin( ["''' 'in' ''' out", "\"\"\" \"in\" \"\"\" out", "''' in ", "in ''' out", "\"\"\" in ", "in \"\"\" out", "''' in \"\"\" in ''' out", "\"\"\" in ", "''' in", "\"\"\" out ''' in ''' out", "' in \"\"\" in \\\' in \" in ' out", "\" in ''' in \\\" in ' in \" out", "\" ' in", "out '''", " in \"\"\" in "], "\n"); % show_string(literal_strings__teststring); static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % test whether the point is inside a long string literal (""" """ or ''' ''') % static define in_literal_string() static define test_in_literal_string() { erase_buffer(); insert(literal_strings__teststring); bob; while (fsearch("in")) { test_true(python->in_literal_string(), sprintf("inside string literal: %d %s", what_line, line_as_string())); go_right(2); } bob; while (fsearch("out")) { test_true(not(python->in_literal_string()), sprintf("outside string literal: %d %s", what_line, line_as_string())); go_right(3); } } % define py_is_continuation_line() % recognize continuation lines (after \, inside """ """, (), [], and {}) static define test_py_is_continuation_line() { variable continuation_lines = [3, 6, 8, 9, 15]; bob(); do { % vshow("line %d: continues at %d", % what_line, py_is_continuation_line()); if (wherefirst(what_line() == continuation_lines) != NULL) test_true(python->is_continuation_line(), sprintf("line %d '%s' is a continuation line", what_line(), line_as_string())); else test_true(not(python->is_continuation_line()), sprintf("line %d '%s' is no continuation line", what_line(), line_as_string())); } while (down_1()); } static define test_py_is_indented_code_line() { % line-numbers of indented code lines in the teststring variable indented_code_lines = [7, 10, 11, 12, 13, 14, 16]; bob(); do { % testmessage(sprintf("\n line %d: continues at %d", % what_line, python->is_continuation_line())); if (wherefirst(what_line() == indented_code_lines) != NULL) test_true(python->is_indented_code_line(), sprintf("line %d '%s' is an indented_code line", what_line(), line_as_string())); else test_true(not(python->is_indented_code_line()), sprintf("line %d '%s' is no indented_code line", what_line(), line_as_string())); } while (down_1()); } % Determine the buffer-local indentation level % % Try the blocal variable "Py_Indent_Level", % the first indented code line, or % the global Py_Indent_Level. % store in blocal variable static define test_get_indent_level() { test_equal(python->get_indent_level(), 4, "default is 4 spaces"); goto_line(2); insert("\t"); test_equal(python->get_indent_level(), 4, "value should be cached"); } static define test_get_indent_level_tab() { goto_line(2); insert("\t"); % () = get_y_or_n("continue"); test_equal(python->get_indent_level(), 0, "tab use should return 0"); } static define test_get_indent_level_default() { erase_buffer(); test_equal(python->get_indent_level(), Py_Indent_Level , "should return Py_Indent_Level if there are no indented code lines"); } % get the width of the expanded indent string (indent_level or TAB) static define test_get_indent_width() { test_equal(python->get_indent_width(), 4, "should return get_indent_level() if it is > 0"); define_blocal_var("Py_Indent_Level", 0); test_equal(python->get_indent_width(), TAB, "should return TAB if indent-level is 0 (tab use)"); } % static define check_indentation() % Test whether code indentation mixes tabs and spaces % Leave point at the first non-white char in the offending line static define test_check_indentation() { test_equal(' ', python->check_indentation(), "false alarm: is there really a tab in '" + line_as_string() + "' ?"); % tab in continuation line goto_line(3); bol(); insert("\t"); test_equal(' ', python->check_indentation(), "should ignore tab in continuation line"); % tab in code line goto_line(7); insert("\t"); eob(); test_equal(0, python->check_indentation(), "should find tab in indented code line"); test_equal(what_line(), 7, "should place point in first offending line"); % convert spaces to tabs: bob(); replace(" ", "\t"); define_blocal_var("Py_Indent_Level", 0); test_equal('\t', python->check_indentation(), "false alarm: is there really a space in " + line_as_string()); } % static define calculate_indent_col() % Parse last line(s) to estimate the correct indentation for the current line % % Used in py_indent_line, indent_line_hook (for indent_line() and % newline_and_indent(), and electric_colon() static define test_calculate_indent() { variable i=1, indent, indents = [0,0,0,0,0,13,4,4,0,4,8,4,8,8,11,4,0]; bob(); foreach indent (indents) { test_equal(indent, python->calculate_indent(), sprintf("wrong estimate in line %d", i)); go_down_1(); i++; } } % define py_indent_line() static define test_py_indent_line() { bob(); % indent by given amount py_indent_line(7); bol_skip_white(); test_equal(what_column()-1, 7, "should indent to given amount"); test_equal(bfind("\t"), 0, "must not use tabs for indentation if indent-level != 0"); % Indent to calculated column % no indent py_indent_line(); bol_skip_white(); test_equal(what_column()-1, 0, "should remove spurious indentation"); % indented line (1 level) () = fsearch("if indent is None:"); bol_trim(); py_indent_line(); bol_skip_white(); test_equal(what_column()-1, Py_Indent_Level, "should indent to previous line"); % more variants are tested via test_calculate_indent_col() % indent with tabs define_blocal_var("Py_Indent_Level", 0); py_indent_line(2*TAB); bol_skip_white(); test_equal(what_column()-1, 2*TAB, "should indent to given amount also if using tabs"); test_equal(bfind(" "), 0, "must not use spaces indentation if indent-level == 0 and width is multiple of TAB"); } %\function{python->py_shift_line_right} %Increase the indentation level of the current line static define test_py_shift_line_right() { % define_blocal_var("Py_Indent_Level", 4); % calculated from teststring TAB = 8; bob; % Indent one level variable i; foreach i ([0,1,2,3]) { bol_trim(); whitespace(i); python->py_shift_line_right(); bol_skip_white(); test_equal(what_column()-1, Py_Indent_Level, sprintf("should indent from %d to next Py_Indent_Level", i)); } % Indent one more level foreach i ([4,5,6,7]) { bol_trim(); whitespace(i); python->py_shift_line_right(); bol_skip_white(); test_equal(what_column()-1, 2*Py_Indent_Level, sprintf("should indent from %d to next Py_Indent_Level", i)); } % Indent with spaces (test now, as TAB is 2*Py_Indent_Level) test_equal(0, bfind("\t"), "should indent with spaces"); % Indent several levels at once with prefix argument bol_trim(); set_prefix_argument(3); python->py_shift_line_right(); bol_skip_white(); test_equal(what_column()-1, 3*Py_Indent_Level, "should indent by prefix-arg * Py_Indent_Level"); } static define test_py_shift_line_right_with_tabs() { bob; % Indent with tabs if get_indent_level returns 0 define_blocal_var("Py_Indent_Level", 0); python->py_shift_line_right(); test_equal(what_column(), TAB+1, "should indent by TAB"); test_true(blooking_at("\t"), "should indent with tabs"); } % py_shift_region_right: undefined % Increase the indentation level of the region static define test_py_shift_region_right() { bob(); push_mark(); python->py_shift_region_right(); bol_skip_white(); test_equal(what_column()-1, Py_Indent_Level, "should indent by Py_Indent_Level"); test_equal(count_narrows(), 0, "still narrowed"); test_equal(markp(), 0, "mark left"); } % py_shift_right: undefined % Increase code indentation level % If a `prefix_argument' is set, indent the number of levels % given in the prefix argument. static define test_py_shift_right() { bob(); set_prefix_argument(3); py_shift_right(); bol_skip_white(); test_equal(what_column()-1, 3*Py_Indent_Level, "should indent by 3*Py_Indent_Level"); } % define py_shift_line_left() static define test_py_shift_line_left() { % set indent leve because we fiddle with the teststring! define_blocal_var("Py_Indent_Level", 4); TAB = 8; bob; % Unindent to bol variable i; foreach i ([1,2,3,4]) { bol_trim(); whitespace(i); python->py_shift_line_left(); bol_skip_white(); test_equal(what_column()-1, 0, sprintf("should unindent from %d to bol", i)); } % Unindent to first level foreach i ([5,6,7,8]) { bol_trim(); whitespace(i); python->py_shift_line_left(); bol_skip_white(); test_equal(what_column()-1, 4, sprintf("should unindent from %d to first Py_Indent_Level", i)); } % test the saveguard error bol_trim(); variable err = test_for_exception("python->py_shift_line_left"); if (orelse{err == NULL}{err.error != RunTimeError}) throw AssertionError, "should abort if there is not enough indentation"; } % define py_shift_region_left() static define test_py_shift_region_left() { bol_trim(); whitespace(Py_Indent_Level); push_mark(); python->py_shift_region_left(); bol_skip_white(); test_equal(what_column()-1, 0, "should dedent by Py_Indent_Level"); test_equal(count_narrows(), 0, "still narrowed"); test_equal(markp(), 0, "mark left"); } % define py_shift_left() { %\synopsis{Decrease code indentation level} static define test_py_shift_left() { bol_trim(); whitespace(Py_Indent_Level); py_shift_left(); bol_skip_white(); test_equal(what_column()-1, 0, "should dedent by Py_Indent_Level"); bol_trim(); whitespace(3*Py_Indent_Level); set_prefix_argument(3); py_shift_left(); bol_skip_white(); test_equal(what_column()-1, 0, "should dedent by 3*Py_Indent_Level"); } % public define py_untab() % Convert tabs to `Py_Indent_Level' spaces or % spaces to tabs (with prefix argument) % Replace all hard tabs ("\\t") with spaces % NOTES % Other than `untab', `py_untab' acts on the whole buffer, not on a % region. static define test_py_untab() { % spaces to tabs (with prefix argument) set_prefix_argument(1); py_untab(); bob(); test_equal('\t', python->check_indentation(), "there should be only tabs in code indentation" +"(if the indents are a multipel of TAB)"); test_equal(0, python->get_indent_level, "set local indent level to 0 (indent with tabs)"); % tabs to spaces py_untab(); bob(); test_equal(0, fsearch("\t"), "there should be no tabs in the buffer"); test_equal(TAB, python->get_indent_level, "set local indent level to TAB"); } % static define reindent_buffer() % Reindent buffer using `Py_Indent_Level' % DESCRIPTION % Reformat current buffer to consistent indentation levels. using the current % relative indentation and the value of get_indent_width(). % Abort if the current indentation violates the Python syntax. static define test_reindent_buffer() { define_blocal_var("Py_Indent_Level", 0); TAB=8; python->reindent_buffer(); test_equal('\t', python->check_indentation(), "there should be only tabs in code indentation"); % reindent with given value python->reindent_buffer(4); test_equal(4, python->get_indent_level, "should set local indent level to 4"); test_equal(0, fsearch("\t"), "there should be no tabs in the buffer"); % mark_buffer(); % show(bufsubstr()); % show(teststring); mark_buffer(); test_equal(bufsubstr(), teststring, "should be back to original indent"); } static define test_reindent_buffer_zero_TAB() { TAB=0; % reindent_buffer should set TAB to 4 to prevent indent by 0 spaces! python->reindent_buffer(0); test_equal('\t', python->check_indentation(), "there should be only tabs in code indentation"); % reindent with given value python->reindent_buffer(4); test_equal(4, python->get_indent_level, "should set local indent level to 4"); test_equal(0, fsearch("\t"), "there should be no tabs in the buffer"); mark_buffer(); test_equal(bufsubstr(), teststring, "should be back to original indent"); } % static define reindent_block() % reindent the current block or all blocks that overlap with a visible region static define test_reindent_block() { eob(); insert("def ulf():\n"); insert(" quatsch()\n"); insert(" batch()\n"); insert("\n"); insert("# last comment\n"); define_blocal_var("Py_Indent_Level", 0); % call reindent_block on last line set_buffer_modified_flag(0); python->reindent_block(); test_equal(0, buffer_modified(), "should do nothing if on non-indented line that doesnot start a block"); % call on last block () = bsearch("quatsch"); python->reindent_block(); bol(); test_true(looking_at_char('\t'), "should indent block with tabs"); % this should move the point into the first block test_equal(0, python->check_indentation(), "now tabs and spaces are mixed"); python->reindent_block(); % as there are only 2 blocks, indentation should be clean again test_equal('\t', python->check_indentation(), "should be only tabs"); } % Magic keys % ---------- % define electric_colon() % dedent a line one level, if it is the start of a new block static define test_electric_colon() { insert("\n else"); python->electric_colon(); bol_skip_white(); test_equal(what_column(), 1); insert("\n elise"); % not a subblock starter python->electric_colon(); bol_skip_white(); test_equal(what_column(), 4); } % define electric_delim(ch) % Currently not used due to unsolved problems static define test_electric_delim() { python->electric_delim(')'); } % define py_backspace_key() % shift line right if we are at the first non-white space in an indented % line, normal action else static define test_py_backspace_key() { variable line, col; % inside code: just delete prev char bob; () = fsearch("self.min_indent"); line = what_line(), col = what_column(); python->py_backspace_key(); test_equal(col-1, what_column(), "should delete prev char normally"); % goto first non-white char bol_skip_white(); col = what_column(); python->py_backspace_key(); test_equal(col-Py_Indent_Level, what_column, "should dedent line if at first non-white space"); bol; python->py_backspace_key(); test_equal(line-1, what_line(), "should del prev newline if at bol"); } % define py_exec() % Run python interpreter on current region or the whole buffer. % Display output in *python-output* buffer window. static define test_py_exec() { bob(); insert("print 2 + 2 #"); py_exec(); % () = get_y_or_n("continue"); test_true(bufferp("*python output*"), "should open output buffer (if there is output from python)"); close_buffer("*python output*"); } % public define python_shell() % attach python session to buffer static define test_python_shell_interactive() { python_shell(); testmessage("test interactive!"); } % define py_help_on_word() % #ifdef MSWINDOWS % static define test_py_help_on_word() % { % py_help_on_word(); % } % #endif % define get_import_lines() % find lines with global imports (import ... and from ... import ...) static define test_get_import_lines() { % get the teststring up to the comment (minus the newline) variable import_lines = teststring[[:is_substr(teststring, "#")-2]]; test_equal(import_lines, python->get_import_lines()); erase_buffer(); test_equal("", python->get_import_lines()); } % py_help: undefined % % SYNOPSIS % Run python's help feature on topic % % USAGE % Void py_help([String topic]) % % DESCRIPTION % Call python help on topic and display the help text in a window. % If the topic is not given, ask in the minibuffer. % % NOTES % Only tested on UNIX % % SEE ALSO % py_mode static define test_py_help() { py_help("string.whitespace"); test_true(bufferp("*python-help*"), "should open help buffer"); test_true(fsearch("string.whitespace"), "should display help on 'string.whitespace'"); close_buffer("*python-help*"); } % define py_help_for_word_hook(word) % (add "." to word chars); static define test_python_help_for_word_hook() { insert(" string.whitespace"); python->python_help_for_word_hook("dummy"); test_true(bufferp("*python-help*"), "should open help buffer"); setbuf("*python-help*"); bob(); test_true(fsearch("string.whitespace"), "should display help on 'string.whitespace'"); % () = get_y_or_n("continue"); close_buffer("*python-help*"); } % define py_browse_module_doc() % (module=NULL) static define test_py_browse_module_doc_interactive() { message("should open help for module 'os' in browser"); py_browse_module_doc("os"); testmessage("needs interactive testing (opens external browser)"); } % python_mode: library function % % SYNOPSIS % Mode for editing Python files. % % USAGE % Void python_mode() % % DESCRIPTION % A major mode for editing scripts written in Python (www.python.org). % % The following keys have python specific bindings: % % Backspace deletes to previous indentation level % : (colon) dedents appropriately % (the next assume `_Reserved_Key_Prefix' == "^C") % ^C# comments region or current line % ^C> shifts line or region right % ^C< shifts line or region left % ^C^C executes the region, or the buffer if region not marked. % ^C| executes the region % % % SEE ALSO % Py_Indent_Level, Py_Use_Tabs, py_reindent, python->py_untab static define test_python_mode() { python_mode(); } jedmodes-2.5.7/tests/rst-test.sl0000664000175400017500000001110011137541445015071 0ustar mildegm% rst-test.sl: Test rst.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 require("unittest"); % Customization % ------------- % % Set % Unittest_Skip_Patterns = [Unittest_Skip_Patterns, "long"]; % to skip long running tests. % test availability of public functions (comment to skip) test_true(is_defined("rst_mode"), "public fun rst_mode undefined"); % Fixture % ------- require("rst"); private variable testfile = make_tmp_file("rst-testfile.txt"); private variable testbuf = path_basename(testfile); private variable teststring = "a test line"; static define setup() { () = find_file(testfile); insert(teststring); save_buffer(); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); test_true(delete_file(testfile), "cleanup failed"); } % private namespace: `rst' % Test functions % -------------- % static define rst_export() % (to, outfile=path_sans_extname(whatbuf())+"."+to) static define test_rst_export_long() { variable to = "html"; variable outfile = path_sans_extname(buffer_filename()) + "." + to; rst->rst_export(to); test_true(delete_file(outfile), "should create output file"); } % public define rst_to_html() static define test_rst_to_html_long() { variable outfile = path_sans_extname(buffer_filename()) + ".html"; rst_to_html(); test_true(delete_file(outfile), "should create html output"); } % public define rst_to_latex() % (outfile=path_sans_extname(whatbuf())+".tex") static define test_rst_to_latex_long() { variable outfile = path_sans_extname(buffer_filename()) + ".tex"; rst_to_latex(); test_true(delete_file(outfile), "should create latex output"); } % public define rst_to_pdf() % (outfile=path_sans_extname(whatbuf())+".pdf") % Needs a non-standard addition, therefore disabled in automatic testing static define test_rst_to_pdf_interactive() { variable outfile = path_sans_extname(buffer_filename()) + ".pdf"; rst_to_pdf(); test_true(delete_file(outfile), "should create pdf output"); } % static define command_help(cmd) static define test_command_help() { rst->command_help("ls foo"); test_equal(whatbuf(), "*rst export help*", "should open help buffer"); close_buffer("*rst export help*"); } % test the dictionary mapping filename extensions to export cmd pointers static define test_export_cmds() { test_equal(rst->export_cmds["html"] , &Rst2Html_Cmd); test_equal(rst->export_cmds["pdf"] , &Rst2Pdf_Cmd); test_equal(rst->export_cmds["tex"] , &Rst2Latex_Cmd); } % static define set_export_cmd(export_type) static define test_set_export_cmd() { variable export_type, cmd_p, cmd, addition = " --test"; foreach export_type (["html", "pdf", "tex"]) { % get pointer to export cmd custom var cmd_p = rst->export_cmds[export_type]; cmd = @cmd_p; % simulate keyboard input (adding `addition` to the default value) buffer_keystring(addition + "\r"); rst->set_export_cmd(export_type); test_equal(@cmd_p, cmd + addition, "should be changed by set_export_cmd()"); @cmd_p = cmd; } } % public define rst_view_html() % (browser=Browse_Url_Browser)) % Needs interactive testing. static define test_rst_view_html_interactive() { rst_view_html(); } % static define markup(type) static define test_markup() { rst->markup("strong"); test_equal("a test **line**", line_as_string(), "should mark up last word"); } % static define block_markup(type) static define test_block_markup() { insert("\n strong"); rst->block_markup("strong"); test_equal("**strong**", line_as_string(), "should mark up last word and (re) indent"); } % static define insert_directive(directive_type) static define test_insert_directive() { rst->insert_directive("test"); test_equal(".. test:: ", line_as_string(), "should insert directive on a line on its own"); } % static define new_popup(menu, popup) static define test_new_popup() { variable popup = rst->new_popup("Global", "test"); test_equal("Global.test", popup, "should return identifier of popup"); menu_delete_item(popup); } % static define rst_menu(menu) static define test_rst_menu() { % simple test for errors while executing, % TODO: test of functionality variable popup = "Global.test"; menu_append_popup("Global", "test"); rst->rst_menu(popup); menu_delete_item(popup); } % public define rst_mode() static define test_rst_mode() { % simple test for errors while executing, % TODO: test of functionality rst_mode(); } jedmodes-2.5.7/tests/ch_table-utf8-decimal.txt0000664000175400017500000000152310675714300017534 0ustar mildegm[ 10] 0 1 2 3 4 5 6 7 8 9 0         TAB 10 NL       20        ESC   30   ! " # $ % & ' 40 ( ) * + , - . / 0 1 50 2 3 4 5 6 7 8 9 : ; 60 < = > ? @ A B C D E 70 F G H I J K L M N O 80 P Q R S T U V W X Y 90 Z [ \ ] ^ _ ` a b c 100 d e f g h i j k l m 110 n o p q r s t u v w 120 x y z { | } ~  €  130 ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ 140 Œ  Ž   ‘ ’ “ ” • 150 – — ˜ ™ š › œ  ž Ÿ 160   ¡ ¢ £ ¤ ¥ ¦ § ¨ © 170 ª « ¬ ­ ® ¯ ° ± ² ³ 180 ´ µ ¶ · ¸ ¹ º » ¼ ½ 190 ¾ ¿ À Á Â Ã Ä Å Æ Ç 200 È É Ê Ë Ì Í Î Ï Ð Ñ 210 Ò Ó Ô Õ Ö × Ø Ù Ú Û 220 Ü Ý Þ ß à á â ã ä å 230 æ ç è é ê ë ì í î ï 240 ð ñ ò ó ô õ ö ÷ ø ù 250 ú û ü ý þ ÿ High-bit chars in a row: ähä öö üÜ ßßß jedmodes-2.5.7/tests/unittesttest.sl~0000664000175400017500000001133511477666466016315 0ustar mildegm% unittesttest.sl: test the SLang unittest framework % % This self-testing is quite verbose and out of line with the remaining unit % tests so it deliberately named not to match the "-test" % Unittest_File_Pattern. % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % 0.3 2006-09-25 * adapted to unittest version 0.3 % * undo Error_Count increase in case of correct behaviour % of the test functions require("unittest"); require("sprint_var"); static variable results, err, a=1, b=3, last_error_count; testmessage("\n\nAssertions"); % ---------- % here, we put the AssertionError in a try-catch phrase to keep on % evaluating the unittest test script try (err) { if (a != b) throw AssertionError, "$a != $b"$; % this code should not be reached: testmessage("E: AssertionError not thrown "); unittest->Error_Count++; } catch AssertionError: { testmessage("OK: wrong assertion threw AssertionError."); } testmessage("\n\nTruth and Equality\n"); % ------------------------------------ testmessage("\ntest_true(): true args must not show in the report"); test_true(1+1 == 2, "# 1+1 should be 2, test_true failed"); last_error_count = unittest->Error_Count; test_true(1+1 == 3); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: 1+1 == 3 is FALSE, so test_true() works fine"); unittest->Error_Count--; } testmessage("\ntest_equal(): should not show in the report if passing"); test_equal(1+1, 2, "# test_equal failed: 1+1 should be 2"); testmessage("\ntest_equal(): should show in the report if failing"); last_error_count = unittest->Error_Count; test_equal(1+1, 3); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: 1+1 != 3, so test_equal() works fine"); unittest->Error_Count--; } testmessage("\n\nStack hygiene\n"); % ------------------------------- testmessage("\n empty stack, so there should be no response"); test_stack(); testmessage("\n now push 2 values on stack"); 42, "baa"; last_error_count = unittest->Error_Count; test_stack(); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: garbage on stack detected"); unittest->Error_Count--; } testmessage("\n\ntest for exceptions:\n"); % ---------------------------------------- private define zero_division() { return 23/0; } testmessage("\n non defined function:"); err = test_for_exception("foo"); testmessage("\n result: %S %s", typeof(err), sprint_variable(err)); testmessage("\n no exception:"); err = test_for_exception("what_line"); testmessage("\n result: " + sprint_variable(err)); testmessage("\n zero division:"); err = test_for_exception(&zero_division); testmessage("\n result: " + sprint_error(err)); testmessage("\n\nFunction testing:\n"); % ------------------------------------- testmessage(" working cases"); test_function("sprintf", "%d", 8); test_last_result("8"); test_function("eval", "3+4"); test_last_result(7); test_function(&bol); test_last_result(); testmessage(" catching bugs"); last_error_count = unittest->Error_Count; test_function("sprintf", "%d", 8); test_last_result("8"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched wrong return value"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("non_defined"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched non defined function"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("message", NULL); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched wrong usage"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function("zero_division"); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched buggy function"); unittest->Error_Count--; } last_error_count = unittest->Error_Count; test_function(&what_line); test_last_result(); if (unittest->Error_Count == last_error_count + 1) { testmessage("\n OK: catched unexpected return value"); unittest->Error_Count--; } testmessage("\n\nRun a test script:\n"); % ------------------------------------ % () = test_file(path_concat(path_dirname(__FILE__), "datutils-test.sl")); % () = test_file("uffe.sl"); % not present testmessage("\n\nRun a test suite:\n"); % ------------------------------------ () = test_files("fooli/"); % invalid dir () = test_files("/home/milde/.jed/lib/test/*datutils*.sl"); testmessage("\n\nRun a test suite and exit Jed:\n"); % -------------------------------------------------- testmessage("\n skipped"); % () = test_files_and_exit("/home/milde/.jed/lib/test/*datutils*.sl"); message("Done"); jedmodes-2.5.7/tests/cuamark-test.sl0000644000175400017500000001060711137545461015717 0ustar mildegm% test-cuamark.sl: Test cuamark.sl % % Copyright © 2006 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-03-03 % 0.2 2007-12-07 transformed from procedural script to test-functions require("unittest"); % Fixture % ------- require("cuamark"); private variable testbuf = "*bar*"; private variable teststring = "a test line"; static define setup() { sw2buf(testbuf); insert(teststring); } static define teardown() { sw2buf(testbuf); set_buffer_modified_flag(0); close_buffer(testbuf); } % Test functions % -------------- % cua_mark: library function % % SYNOPSIS % Mark a cua-region (usually, with Shift-Arrow keys) % % USAGE % cua_mark() % % DESCRIPTION % if no visible region is defined, set visible mark and key-hooks % so that Cua_Unmarking_Functions unmark the region and % Cua_Deleting_Functions delete it. % % SEE ALSO % cua_kill_region, cua_copy_region, Cua_Unmarking_Functions, Cua_Deleting_Functions static define test_cua_mark() { bob(); cua_mark(); eol(); % this should not cancel the mark (see Cua_Unmarking_Functions) test_true(is_visible_mark(), "there should be a visible mark"); test_equal(bufsubstr(), teststring); } % TODO: This test doesnot work, as the unmarking is done in a keypress hook % (we would need to simulate a keypress, how?) % bob(); % test_function("cua_mark"); % test_last_result(); % call("eol_cmd"); % this should cancel the mark (see Cua_Unmarking_Functions) % test_true(not is_visible_mark(), "cua_mark(): there should be no visible mark "+ % "after (no-shifted) movement"); % cua_insert_clipboard: library function % % SYNOPSIS % Insert X selection at point % % USAGE % Void cua_insert_clipboard() % % DESCRIPTION % Insert the content of the X selection at point. % Use, if you want to have a keybinding for the "middle click" action. % % NOTES % This function doesnot return the number of characters inserted so it can % be bound to a key easily. % % SEE ALSO % x_insert_selection, x_insert_cutbuffer static define test_cua_insert_clipboard() { % TODO: how to trigger an X event? testmessage("currently, the insertion happens at 'random' times. \n" +"Sometimes only after the test-buf is closed again \n" +"triggering errors for this test as well as the next!"); return; % kill the buffer content and place in the selection mark_buffer(); cua_kill_region(); % Test that this is true test_true(bobp() and eobp(), "cua_kill_region error prevents test of cua_insert_clipboard"); % Re-insert selection cua_insert_clipboard(); % the buffer content should be restored if (is_defined("x_insert_selection") or is_defined("x_insert_cutbuffer")) { mark_buffer(); test_equal(bufsubstr(), teststring, "inserting the selection should restore content"); } } % cua_kill_region: library function % % SYNOPSIS % Kill region (and copy to yp-yankbuffer [and X selection]) % % USAGE % Void cua_kill_region() % % DESCRIPTION % Kill region. A copy is placed in the yp-yankbuffer. % % If `x_copy_region_to_selection' or `x_copy_region_to_cutbuffer' % exist, a copy is pushed to the X selection as well. % % SEE ALSO % yp_kill_region, cua_copy_region, yp_yank static define test_cua_kill_region() { mark_buffer(); cua_kill_region(); % the buffer should now be empty test_true(bobp() and eobp(), "After killing the buffer, it should be empty"); % inserting the yp-yankbuffer should restore the content yp_yank(); mark_buffer(); test_equal(bufsubstr(), teststring, "yp_yank() shoule re-insert the killed region"); } % cua_copy_region: library function % % SYNOPSIS % Copy region to yp-yankbuffer [and X selection]) % % USAGE % Void cua_copy_region() % % DESCRIPTION % Copy the region to the yp-yankbuffer. % % If `x_copy_region_to_selection' or `x_copy_region_to_cutbuffer' % exist, a copy is pushed to the X selection as well. % % SEE ALSO % yp_copy_region_as_kill, cua_kill_region, yp_yank static define test_cua_copy_region() { mark_buffer(); cua_copy_region(); % the buffer content should be untouched mark_buffer(); test_equal(bufsubstr(), teststring); % the yp_yankbuffer should have a copy erase_buffer(); yp_yank(); mark_buffer(); test_equal(bufsubstr(), teststring); } jedmodes-2.5.7/tests/ch_table-lat1-decimal.txt0000664000175400017500000000131210675714354017514 0ustar mildegm[ 10] 0 1 2 3 4 5 6 7 8 9 0         TAB 10 NL       20        ESC   30   ! " # $ % & ' 40 ( ) * + , - . / 0 1 50 2 3 4 5 6 7 8 9 : ; 60 < = > ? @ A B C D E 70 F G H I J K L M N O 80 P Q R S T U V W X Y 90 Z [ \ ] ^ _ ` a b c 100 d e f g h i j k l m 110 n o p q r s t u v w 120 x y z { | } ~  130 140 150 160 170 180 190 200 210 220 230 240 250 High-bit chars in a row: h jedmodes-2.5.7/bufed/0000755000175400017500000000000010651112130012655 5ustar mildegmjedmodes-2.5.7/bufed/bufed.sl0000644000175400017500000002312210651112130014302 0ustar mildegm% bufed.sl % % $Id: bufed.sl,v 1.5 2007/05/13 08:25:55 paul Exp paul $ % % Copyright (c) Mark Olesen; (c) 2003-2007 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % Bufed is a simple buffer manager -- patterned somewhat after dired. % Provides easy, interactive switching, saving and killing of buffers. % % To invoke Bufed, do `M-x bufed'. % Or re-bind to the key sequence which is normally bound to the % `list_buffers' function `C-x C-b' (emacs) % % Modified by Paul Boekholt to use listing.sl. Now you can tag buffers, % kill, save, and search or replace through tagged buffers. The search and % replacement functions are in bufed_srch.sl. require("listing"); require("bufutils"); implements("bufed"); autoload ("search_tagged", "bufed_srch"); autoload ("replace_tagged", "bufed_srch"); variable Bufed_buf = "*BufferList*"; % as used by `list_buffers' (buf.sl) %{{{ extract buffername % extract the buffer name associated with the current line % Note: The details of this routine will depend upon how buf.sl formats % the line. Currently, this looks like: % ----------- 0000 "*scratch*" /aluche/h1/davis/src/jed/lib/ define bufed_get () { variable buf; push_spot_bol (); try { !if (ffind_char ('"')) return Null_String; go_right_1 (); push_mark (); !if (ffind_char ('"')) { pop_mark_1 (); return Null_String; } buf = bufsubstr (); !if (bufferp (buf)) { set_readonly(0); delete_line(); set_readonly(1); set_buffer_modified_flag(0); buf = ""; } return buf; } finally { pop_spot(); } } %}}} %{{{ listing buffers public define list_buffers () { variable i, j, tmp, this, name, flags, flag_chars, skip; variable umask; variable name_col, dir_col, mode_col; name_col = 21; mode_col = 13; dir_col = 45; skip = 0; if (prefix_argument(-1) == -1) skip = 1; tmp = "*BufferList*"; this = whatbuf(); pop2buf(tmp); set_readonly(0); erase_buffer(); TAB = 8; flag_chars = "CBKN-UORDAM"; insert (" Flags"); goto_column (mode_col); insert ("umask"); goto_column (name_col); insert ("Buffer Name"); goto_column(dir_col); insert("Dir/File\n"); loop (buffer_list()) { name = (); if (skip and (int(name) == ' ')) continue; %% internal buffers begin with a space flags = getbuf_info (name); % more on stack setbuf(name); umask = set_buffer_umask (-1); setbuf(tmp); bol(); i = 0x400; j = 0; while (i) { if (flags & i) flag_chars[j]; else '-'; insert_char (()); i = i shr 1; j++; } goto_column (mode_col); vinsert (" %03o", umask); goto_column (name_col); % Since the buffername may contain whitespace, enclose it in quotes insert_char ('"'); insert(()); %% buffer name insert_char ('"'); goto_column(dir_col); !if (eolp()) { eol(); insert_single_space(); } insert(()); insert(()); %% dir/file newline(); } insert("\nU:Undo O:Overwrite R:Readonly D:Disk File Changed, A:Autosave, M:Modified\n"); insert("C:CRmode, B:Binary File, K:Not backed up, N:No autosave"); bob (); set_buffer_modified_flag (0); set_readonly (1); pop2buf(this); } define bufed_list () { check_buffers (); list_buffers (); pop2buf (Bufed_buf); set_readonly (0); bob(); insert ("Press '?' for help. Press ENTER to select a buffer.\n\n"); set_readonly (0); set_buffer_modified_flag(0); go_down (1); %goto_column (21); } %}}} %{{{ killing buffers % kill a buffer, if it has been modified then pop to it so it's obvious define bufed_kill (line) { variable flags, buf = extract_element (line, 1, '"'); if (buf == NULL) return 0; !if (bufferp (buf)) return 2; (,,,flags) = getbuf_info (buf); if (flags & 1) % modified { pop2buf (buf); pop2buf (Bufed_buf); update (1); } try { delbuf (buf); } catch AnyError: { pop2buf (Bufed_buf); return 1; % untag line } return 2; % kill line } define kill_line () { listing_map(0, &bufed_kill); } define kill_tagged () { listing_map(2, &bufed_kill); } %}}} %{{{ saving buffers % save the buffer define bufed_save (line) { variable file, dir, ch, this_buf; variable flags, buf = extract_element (line, 1, '"'); !if (bufferp (buf)) return 2; ch = int (buf); if ((ch == 32) or (ch == '*')) return 1; % internal buffer or special (file,dir,,flags) = getbuf_info (buf); if (strlen (file) and (flags & 1)) % file associated with it { setbuf (buf); save_buffer(); setbuf (Bufed_buf); return 1; } } define save_tagged () { listing_map(1, &bufed_save); } %}}} %{{{ switching to a buffer % try to re-load the file from disk define bufed_update () { variable file, dir, flags; (file,dir,,flags) = getbuf_info (); if (flags & 2) % file on disk modified? { !if (find_file (dircat (dir, file))) throw RunTimeError, "Error reading file"; } } define bufed_pop2buf () { variable buf = bufed_get (); !if (int (buf)) return; % if the buffer is already visible, scroll down buffer_visible (buf); % leave on the stack pop2buf (buf); if (() and not(eobp ())) call ("page_down"); bufed_update (); pop2buf (Bufed_buf); } define bufed_sw2buf (one) { variable buf = bufed_get (); !if (int (buf)) return; sw2buf (buf); bufed_update (); if (one) onewindow (); } %}}} %{{{ change flags % to do: we might as well update the flags in the bufferlist define bufed_toggle_flag(line, flag, value) { variable buf = extract_element(line, 1, '"'); !if (bufferp (buf)) return 2; switch (value) {case -1: setbuf_info (buf, getbuf_info(buf) xor flag);} {case 0: setbuf_info (buf, getbuf_info(buf) & ~flag);} {setbuf_info (buf, getbuf_info(buf) | flag);} return 0; } define change_flag_map() { variable prefix = prefix_argument(-1), flagstring="CBKN-UORDAM", flag, flagindex; message ("Cr, Binary, no bacKup, Undo, Ovwrt, Rdonly, Disk changed, Autosave, Modified?"); update_sans_update_hook(0); flagindex = wherefirst(toupper(getkey()) == bstring_to_array(flagstring)); if (flagindex != NULL) { flag = 0x400 shr flagindex; listing_map(1, &bufed_toggle_flag, flag, prefix); } } define bury_tagged () { listing_map(1, &bufed_toggle_flag, 0x040, 1); } %}}} %{{{ keybindings variable Bufed_help = "k:kill, s:save, g:refresh, SPC,f:pop2buf, CR,TAB:sw2buf, q:quit, h:help, ?:this help"; define help () { message (Bufed_help); } $1 = "bufed"; !if (keymap_p ($1)) copy_keymap($1, "listing"); definekey ("listing->tag_all(0); bufed_list", "g", $1); definekey ("describe_mode", "h", $1); definekey ("bufed->kill_line", "k", $1); definekey ("bufed->kill_tagged", "x", $1); definekey ("bufed->save_tagged", "s", $1); definekey ("bufed->bufed_pop2buf", "f", $1); definekey ("bufed->bufed_pop2buf", " ", $1); definekey ("bufed->bufed_sw2buf(0)", "\r", $1); definekey ("bufed->bufed_sw2buf(1)", "\t", $1); definekey ("bufed->help", "?", $1); definekey ("bufed->bury_tagged", "b", $1); definekey_reserved ("bufed->change_flag_map", "f", $1); % Analogous to Emacs' dired-do-search. definekey ("bufed->search_tagged","A", $1); definekey ("bufed->replace_tagged", "Q", $1); rebind_reserved("search_forward", "bufed->search_tagged", $1); % Emacs has no binding for search_forward, so bind ^c^s too rebind_reserved("isearch_forward", "bufed->search_tagged", $1); rebind_reserved("replace_cmd", "bufed->replace_tagged", $1); %}}} %{{{ menu define bufed_menu(menu) { listing->listing_menu(menu); menu_append_separator(menu); menu_append_item (menu, "&Kill Buffer", "bufed->kill_line"); menu_append_item (menu, "Kill Tagged", "bufed->kill_tagged"); menu_append_item (menu, "&Save", "bufed->save_tagged"); menu_append_item (menu, "&Bury", "bufed->bury_tagged"); menu_append_separator(menu); menu_append_item (menu, "Search &Forward", "bufed->search_tagged"); menu_append_item (menu, "R&egexp Search", ". 1 set_prefix_argument bufed_search_tagged"); menu_append_item (menu, "&Replace", "bufed->replace_tagged"); menu_append_item (menu, "Regexp Re&place", ". 1 set_prefix_argument bufed_replace_tagged"); } %}}} %!%+ %\function{bufed} %\synopsis{bufed} %\description % Mode designed to aid in navigating through multiple buffers % patterned somewhat after dired. % % To invoke Bufed, do \var{M-x bufed} or bind to \var{C-x C-b} (emacs) % % \var{g} Update the buffer listing. % \var{d} Tag a buffer % \var{u} Untag a buffer % \var{k} Kill the buffer described on the current % line, like typing \var{M-x kill_buffer} and supplying that % buffer name. % % \var{x} Kill the tagged buffers. % \var{s} Save the tagged buffers or the buffer described on the current line. % \var{b} Bury buffers. % \var{C-c f} % Change buffer flags. Without prefix, toggle. % With prefix 0, turn flag off. Other prefix, turn on. % \var{A} Search across tagged buffers. With prefix, do a regexp search. % \var{Q} Replace across tagged buffers. With prefix, do a regexp replace. % % \var{f}, \var{SPC}, \var{CR}, \var{TAB} % Visit the buffer described on the current line. % \var{f} and \var{SPC} will create a new window if required. % \var{CR} will use the current window. % \var{TAB} will revert to a single window. % \var{q} Quit bufed mode. %!%- public define bufed () { variable mode = "bufed"; variable this_buf = sprintf ("\"%s\"", whatbuf ()); bufed_list (); () = fsearch (this_buf); help (); listing_mode(); set_mode (mode, 0); use_keymap (mode); mode_set_mode_info(mode, "init_mode_menu", &bufed_menu); run_mode_hooks ("bufed_hook"); } provide ("bufed"); jedmodes-2.5.7/bufed/bufed_srch.sl0000644000175400017500000001276110651112130015330 0ustar mildegm% bufed_srch.sl % % $Id: bufed_srch.sl,v 1.4 2007/05/13 08:25:55 paul Exp paul $ % % (c) 2003-2007 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % The search functions for bufed.sl, placed in a % separate file to make bufed load faster. provide ("bufed_srch"); require ("search"); require ("srchmisc"); () = evalfile ("regexp"); use_namespace("bufed"); % this is now a private function in regexp.sl private define research_search_function (pat) { re_fsearch (pat) - 1; } variable last_search_replace_cmd = "", continued = 0; %{{{ search through marked buffers variable search_fun, pat; % This function says that the line is ok, I also use it % to pop to the buffer if the string is found static define bufed_srch_ok_fun() { pop2buf(whatbuf); return 1; } static define bufed_search_buffer(line) { variable buf = extract_element (line, 1, '"'); if (buf == NULL) return 0; !if (bufferp (buf)) return 2; % buffer doesn't exist -> kill line setbuf(buf); variable buf_mark = create_user_mark; !if (continued) bob(); continued = 0; if (search_maybe_again (search_fun, pat, 1, &bufed_srch_ok_fun)) { listing->Dont_Ask = -1; setbuf (Bufed_buf); throw UserBreakError, "Quit"; } goto_user_mark(buf_mark); pop2buf (Bufed_buf); return 1; % untag line } % Search the tagged buffers. With prefix, do a regexp search. define search_tagged () { continued = 0; last_search_replace_cmd="search"; if (-1 == prefix_argument (-1)) search_fun = &search_across_lines; else search_fun = &re_search_dir; LAST_SEARCH = read_mini("Search", LAST_SEARCH, ""); pat = LAST_SEARCH; try { listing_map(2, &bufed_search_buffer); } catch UserBreakError; } %}}} %{{{ replacing through marked buffers variable rep_fun, rep_pat, rep_rep; % this is replace_with_query from srchmisc.sl, the main difference % being we need to raise an error on 'q' % The undo function only works within a buffer. static define bufed_replace_with_query (line) { variable buf = extract_element (line, 1, '"'); if (buf == NULL) return 0; !if (bufferp (buf)) return 2; % buffer doesn't exist -> kill line setbuf(buf); variable buf_mark = create_user_mark(); !if (continued) bob(); continued = 0; variable n, prompt, doit, err, ch, pat_len; variable undo_stack_type = struct { rep_len, prev_string, user_mark, next }; variable undo_stack = NULL; variable tmp; variable replacement_length = strlen (rep_rep); prompt = sprintf ("Replace '%s' with '%s'? (y/n/!/+/q/h)", rep_pat, rep_rep); while (pat_len = @rep_fun (rep_pat), pat_len >= 0) { pop2buf (buf); if (listing->Dont_Ask) % from listing.sl { tmp = create_user_mark (); () = replace_do_replace (rep_rep, pat_len); if ((pat_len == 0) and (tmp == create_user_mark ())) go_right_1 (); continue; } do { message(prompt); mark_next_nchars (pat_len, -1); ch = getkey (); if (ch == 'r') { recenter (window_info('r') / 2); } } while (ch == 'r'); switch(ch) { case 'u' and (undo_stack != NULL) : goto_user_mark (undo_stack.user_mark); push_spot (); () = replace_do_replace (undo_stack.prev_string, undo_stack.rep_len); pop_spot (); undo_stack = undo_stack.next; } { case 'y' : tmp = @undo_stack_type; tmp.next = undo_stack; undo_stack = tmp; push_spot(); push_mark (); go_right (pat_len); undo_stack.prev_string = bufsubstr (); pop_spot (); undo_stack.user_mark = create_user_mark (); undo_stack.rep_len = replace_do_replace (rep_rep, pat_len); } { case 'n' : go_right_1 ();} { case '+' : () = replace_do_replace (rep_rep, pat_len); listing->Dont_Ask = -1; setbuf (Bufed_buf); throw UserBreakError, "Quit"; break; } { case '!' : listing->Dont_Ask = 1; } { case 'q' : % Don't bother with the remaining buffers listing->Dont_Ask = -1; setbuf (Bufed_buf); throw UserBreakError, "Quit"; } { flush ("y:replace, n:skip, !:replace all, u: undo last, +:replace then quit, q:quit"); () = input_pending (30); } } goto_user_mark(buf_mark); pop2buf (Bufed_buf); return 1; % untag line } % Replace across the tagged buffers. With prefix, do a regexp search. define replace_tagged () { variable prompt; continued = 0; last_search_replace_cmd="replace"; if (-1 == prefix_argument (-1)) rep_fun = &search_search_function; else rep_fun = &research_search_function; rep_pat = read_mini("Replace:", Null_String, Null_String); !if (strlen (rep_pat)) return; prompt = strcat ("Replace '", rep_pat, "' with:"); rep_rep = read_mini(prompt, "", ""); try { listing_map(2, &bufed_replace_with_query); } catch UserBreakError; } %}}} %{{{ continue searching or replacing % Continue with last search or replace where we are in the buffer where we % were without going back to bob. % You may setkey this to M-, in global keymap, like in Emacs' dired. public define bufed_search_or_replace_continue() { continued = 1; setbuf(Bufed_buf); if (last_search_replace_cmd == "search") { try { listing_map(2, &bufed_search_buffer); } catch UserBreakError; } else if (last_search_replace_cmd == "replace") { try { listing_map(2, &bufed_replace_with_query); } catch UserBreakError; } } %}}} jedmodes-2.5.7/ishell/0000755000175400017500000000000011007613706013063 5ustar mildegmjedmodes-2.5.7/ishell/ishell.sl0000644000175400017500000006241711007613706014715 0ustar mildegm% Interactive shell mode (based on ashell.sl by J. E. Davis) % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Features % -------- % % Run interactive programs (e.g. mupad/python/gnuplot) in a "workbook mode". % Keep in- and output easy editable, great for experimenting with scripts. % % ishell([cmd]) open a shell in a buffer on its own % ishell_mode([cmd]) attach an interactive process (default % `Shell_Default_Shell') to the current buffer % % Features not present in ashell: % * a region (if defined) is sent to the command at one stroke % * _Reserved_Key_Prefix+ starts evaluation of line/region % * behaves as normal % * undo is enabled % * optional argument to ishell_mode: start any process % * Adjustable output via function ishell_set_output_placement(key) % * blocal hook "Ishell_output_filter" -> format process output % % Supplement (belongs rather to shell.sl): % % shell_cmd_on_region() non-interactive cmd with region as argument % % !!! Beta Code. Only tested with Linux. !!! % There are known problems with ishell under Windows. If you want to use % ishell with windows, and are ready to help in bugfixing, get in contact % with the author. % % Versions % -------- % % 1.0 * first public version % 1.1 * new option for IShell_Output_Placement: "o" separate output buffer % * keybindings go to an own map with push/pop_keymap % * default keybindings use definekey_reserved(...) % * Under UNIX: bg-process creates one buffer for all bg-processes % 1.2 * Cleanup, do_shell_cmd_on_region -> shell_cmd_on_region(cmd, output=0) % 1.3 May 2003 % * minor-Mode menu, % * IShell_output_placement: changed "end of buffer from "" to "_", % * replaced bg_process with terminal() after learning about % run_program() and system(cmd + "&") % * new: blocal hook "Ishell_output_filter" (the hook should take a % string, process it and return. % 1.4 * Large input (>4090 bytes) went missing % an input cache tries to solve this (see also cached-process.sl) % * New blocal var Process_Handle holds "metadata" for the attached % process, replacing most "IShell_*" blocal vars % 1.4.1 2003-12-08 * ishell-version of process_region() deleted (was buggy) % (take the original one from pipe.sl or use % shell_cmd_on_region(cmd, 2) % * shell_cmd_on_region: new output option 4: message % * ishell_mode sets the blocal run_buffer_hook % * new function bufsubfile (might rather go to bufutils?) % * renamed custom variables IShell_* to Ishell_* % 1.5 2004-04-17 * moved bufsubfile() to bufutils % * filter_region() convenience-function equal to % shell_cmd_on_region(,2) % 1.5.1 2004-05-07 shell_cmd_on_region: code cleanup; added a sw2buf(buf); % 1.5.2 2004-06-03 added ^M-Filter in ishell_insert_output() (tip P. Boekholt) % 1.5.3 2004-09-17 bugfix: do not set blocal_var run_buffer, % as this will not work with push_mode()|pop_mode() % 1.6 2004-11-30 optional argument "postfile_args" to shell_cmd_on_region() % 1.6.1 2005-04-07 bugfix: autoload for view_mode % 1.7 2005-04-14 new command do_shell_cmd() replacing the one from shell.sl % with a more configurable one by using code % from shell_cmd_on_region() % 1.7.1 2005-07-08 as the reuse of the do_shell_cmd() name lead to conflicts, % ishell's version is renamed to shell_command(). % 1.8 2005-07-28 new function shell_cmd_on_region_or_buffer(): % Doesnot save to a temporary file if no region is defined % 1.8.1 2005-11-18 added documentation for custom variables and all % public functions % 1.8.2 2006-05-10 bugfix: added missing autoload for normalized_modename() % 1.8.3 2006-05-19 better cursor placement in shell_command(cmd, 0) % 1.8.4 2006-05-26 fixed autoloads (J. Sommer) % 1.8.5 2006-10-04 shell_cmd_on_region_or_buffer: use bufsubfile() only if % *visible* mark is set % 1.8.6 2006-10-09 bugfix in shell_command (did set the current buffer to % view-mode if there was no output from the command) % 1.9 2006-11-10 shell_cmd_on_region_or_buffer() now saves the buffer to a % temporary file (instead of asking for a filename) if there % is no file associated to the buffer (and no visible region) % 1.9.1 2006-11-23 bugfix in shell_cmd_on_region_or_buffer() % (`output_handling' can be string or integer) % 1.9.2 2007-05-14 cleanup in ishell() % 1.10 2007-12-11 new output_placement "l": Log (input and output) in outbuf % fix autoloads % 2.0 2008-05-05 ishell_send_input() send region line-wise, % with subsequent lines sent in ishell_insert_output() % after receiving a response (prompt). % (Please report if this creates problems, e.g. with a % process that does not return a prompt in some cases). % no CR cleaning by default (define an Ishell_output_filter % for offending programs or a generic one #ifdef UNIX) provide("ishell"); % Requirements % ------------ autoload("push_keymap", "bufutils"); autoload("pop_keymap", "bufutils"); autoload("rebind", "bufutils"); autoload("buffer_dirname", "bufutils"); autoload("popup_buffer", "bufutils"); autoload("close_buffer", "bufutils"); autoload("normalized_modename", "bufutils"); autoload("fit_window", "bufutils"); autoload("get_blocal", "sl_utils"); autoload("push_defaults", "sl_utils"); autoload("run_local_function", "bufutils"); autoload("bufsubfile", "bufutils"); autoload("view_mode", "view"); autoload("get_buffer", "txtutils"); % Customisation % ------------- % % * custom variables: Help>Apropos ^Ishell % * ishell_mode_hook, e.g. for nicer keybindings % * local hook "Ishell_output_filter" -> format process output % % Examples for output filters: % % % Some programs put out ^M-s also in their UNIX version, % % Jed does not expect them (regardless of the crmode). % define ishell_remove_CRs(str) % { % return str_delete_chars (str, "\r"); % } % define_blocal_var("Ishell_output_filter", "ishell_remove_CRs") % % % Output commenting: % define ishell_comment_output(str) % { % variable c = get_comment_info() % return strreplace_all (str, "\n", \n"+c.cbeg); % } % define_blocal_var("Ishell_output_filter", "ishell_comment_output") % % % Give a message instead of inserting anything: % define ishell_output_message(str) % { % vmessage("%d bytes of output", strlen(str)); % return ""; % empty string % } % define_blocal_var("Ishell_output_filter", "ishell_output_message") % example for an ishell_mode_hook: evaluate lines between % marks or from bob() to % % public define ishell_mode_hook() % { % variable str, handle = get_blocal_var("Ishell_Handle"); % push_spot(); % bob(); % if (fsearch("")) % go_down_1(); % push_visible_mark(); % if(fsearch("")) { % bol(); % ishell_send_input(); % } % else % pop_mark_0(); % pop_spot(); % move_user_mark(handle.mark); % } % Custom Variables % ~~~~~~~~~~~~~~~~ %!%+ %\variable{Ishell_default_output_placement} %\synopsis{Customize output placement of interactive shell commands} %\usage{String_Type Ishell_default_output_placement = ">"} %\description % Where is output from the process placed: % "_" or "" end of buffer % "@" end of buffer (return to point) % ">" new line below corresponding input % "." current point position % "o" separate output buffer % "log" log input and output in a separate buffer % The default for not listed strings is "." %\notes % This is an extended version of the options for \sfun{set_process} %\seealso{ishell, ishell_mode, set_process} %!%- custom_variable("Ishell_default_output_placement", ">"); %!%+ %\variable{Ishell_logout_string} %\synopsis{interactive shell logout string} %\usage{String_Type Ishell_logout_string = ""} %\description % The string sent to the process for logout. %\seealso{ishell, ishell_mode} %!%- custom_variable("Ishell_logout_string", ""); %!%+ %\variable{Ishell_Max_Popup_Size} %\synopsis{Size of ishell output buffer} %\usage{Int_Type Ishell_Max_Popup_Size = 0.3} %\description % Maximal size for resizing the ishell output buffer %\seealso{ishell, ishell_mode, Ishell_default_output_placement} %!%- custom_variable("Ishell_Max_Popup_Size", 0.3); %!%+ %\variable{Ishell_Default_Shell} %\synopsis{Default interactive shell} %\usage{Int_Type Ishell_Default_Shell = getenv ("SHELL")} %\description % The default process started by \sfun{ishell_mode}. % % In UNIX, the interactive shell has the interacitve flag but might also be a % completely different one (say `sh` for normal but `bash -i` for interactive. % If you want this, set the variable Ishell_Default_Shell %\notes % in ashell.sl, \var{Shell_Default_Interactive_Shell} is misleadingly named % as it contains just the 'interactive' flag) %\seealso{Shell_Default_Shell, ishell, ishell_mode} %!%- #ifdef WIN32 custom_variable("Shell_Default_Shell", getenv ("COMSPEC")); if (Shell_Default_Shell == NULL) Shell_Default_Shell = "cmd.exe"; % in windoof these are the same custom_variable("Ishell_Default_Shell", Shell_Default_Shell); #else % in UNIX, the interactive shell has the interacitve flag but might also be a % completely different one (say sh for normal but bash -i for interactive % if you want this, set the variable Ishell_Default_Shell custom_variable("Shell_Default_Shell", getenv ("SHELL")); if (Shell_Default_Shell == NULL) Shell_Default_Shell = "sh"; custom_variable("Ishell_Default_Shell", Shell_Default_Shell+" -i"); #endif % --- static variables % There is a restriction on the length of the string that can be fed % to an attached process at once as well as on the length of the return-string % these are the testresults with xjed 0.99.16 on a PC running Linux % Output: string of 512 characters % static variable Process_Output_Size = 512; % maximum - 1 (for savety) % Input: string of 4096 chars % % obsoleted by line-wise input feeding since version 1.11 % static variable Process_Input_Size = 4096; % --- Functions ------------------------------------------------------ % (Re)set process handle to default values static define initialize_process_handle() { variable handle = struct{id, name, input, output_placement, prompt, mark}; handle.id = -1; handle.name = ""; % process name (+ arguments) handle.input = {}; % cache for input data handle.output_placement = Ishell_default_output_placement; handle.prompt = ""; handle.mark = create_user_mark(); %for output positioning define_blocal_var("Ishell_Handle", handle); } % append str to the corresponding output buffer of buffer `buf' static define append_to_outbuf(str) { variable buf = whatbuf(); variable outbuf = sprintf("*%s Output*", buf); popup_buffer(outbuf, Ishell_Max_Popup_Size); eob(); set_readonly(0); insert(str); eob(); fit_window(get_blocal("is_popup", 0)); view_mode(); pop2buf(buf); return; } % (try to) send first line of handle.input to attached process static define send_input_line(handle) { try variable line = list_pop(handle.input); catch IndexError: { return; % list is empty } if (handle.output_placement == "l") % log append_to_outbuf(line); send_process(handle.id, line); } % send region or current line to attached process define ishell_send_input() { variable str, handle = get_blocal_var("Ishell_Handle"); push_spot(); if (is_visible_mark) % if there is a visible region, take it as input { check_region(0); str = bufsubstr(); % remove trailing newline % (cannot use strtrim_end("\n"), as this kills also several \n-s % while e.g. the python interpreter uses a blank line as end-of-block sign if (str[-1] == '\n') str = str[[:-2]]; } else str = line_as_string(); if (handle.output_placement == ">") % below corresponding input newline(); move_user_mark(handle.mark); pop_spot(); % remove prompt if present % TODO: strip prompt for all lines? if (is_substr(str, handle.prompt) == 1) str = str[[strlen(handle.prompt):]]; % split into lines and cache in handle.input foreach str (strchop(str, '\n', 0)) list_append(handle.input, strcat(str, "\n")); % Send to attached process (line-wise) send_input_line(handle); } % insertion of output define ishell_insert_output(pid, str) { variable buf = whatbuf(), handle = get_blocal_var("Ishell_Handle"); % find out what the prompt is (normally the last line of output) handle.prompt = strchop(str, '\n', 0)[-1]; % Filter the output string (call a filter-output-hook) % show("ispell_output:", str); if (run_local_function("Ishell_output_filter", str)) str = (); % Insert output string switch(handle.output_placement) { case "_": eob; insert(str);} { case "@": push_spot; eob; insert(str); pop_spot();} { case ">": goto_user_mark(handle.mark); insert(str); } { case "." : insert(str); } % (insert at current buffer position) { case "o" or case "l": append_to_outbuf(str); } % { case "m" : message(strtrim(str)); } % does this work at all? move_user_mark(handle.mark); % for subsequent output chunks % Send next input line to attached process % (if there are more lines in the cache) send_input_line(handle); % make the insertion visible update_sans_update_hook(0); % does not work some times call("redraw"); % is this better?? } % abort process (keybord abort) define ishell_send_intr () { signal_process (get_blocal_var("Ishell_Handle").id, 2); } % abort process (send Ishell_logout_string default(Ctrl-D)) define ishell_logout () { send_process (get_blocal_var("Ishell_Handle").id, Ishell_logout_string); } % feedback on signals, tidy up after exit define ishell_signal_handler (pid, flags, status) { variable handle = get_blocal_var("Ishell_Handle"); variable msg = aprocess_stringify_status(pid, flags, status); flush(handle.name + ": " + msg); if (flags > 2) % Process Exited { initialize_process_handle(); pop_keymap(); % pop ishell minor mode } } define ishell_open_process(command_line) { !if (blocal_var_exists("Ishell_Handle")) initialize_process_handle(); variable handle = get_blocal_var("Ishell_Handle"); handle.name = command_line; flush ("starting " + command_line + " ..."); command_line = strtok (command_line); foreach (command_line) ; % push on stack handle.id = open_process (length(command_line) - 1); set_process (handle.id, "signal", &ishell_signal_handler); set_process (handle.id, "output", &ishell_insert_output); } define ishell_set_output_placement(key) { get_blocal_var("Ishell_Handle").output_placement = key; } % ishell menu, appended to an existing mode menu static define ishell_menu(menu) { variable init_menu = mode_get_mode_info(normalized_modename(), "init_mode_menu"); if (init_menu != NULL) { @init_menu(menu); menu_append_separator(menu); } variable submenu = "Set Output &Placement"; menu_append_item(menu, "&Logout (quit ishell)", "ishell_logout"); menu_append_item(menu, "&Enter input", "ishell_send_input"); menu_append_item(menu, "&Interrupt", "ishell_send_intr"); menu_append_popup(menu, submenu); menu += "." + submenu; menu_append_item(menu, "&_ End of buffer", "ishell_set_output_placement", "_"); menu_append_item(menu, "&@ eob (return to point)", "ishell_set_output_placement", "@"); menu_append_item(menu, "&. Point", "ishell_set_output_placement", "."); menu_append_item(menu, "&> Line below input", "ishell_set_output_placement", ">"); menu_append_item(menu, "&o Output buffer", "ishell_set_output_placement", "o"); menu_append_item(menu, "&l Log buffer", "ishell_set_output_placement", "l"); } %!%+ %\function{ishell_mode} %\synopsis{Open a process and attach it to the current buffer.} %\usage{ ishell_mode(cmd=Ishell_Default_Shell)} %\description % Open an interactive process and attach to the current buffer. % By default, the process is \var{Ishell_Default_Shell}, % the optional argument String "cmd" overrides this. %\example % Open an interactive python session in a new buffer: %#v+ % sw2buf("*python*"); % ishell_mode("python"); %#v- %\seealso{ishell, Ishell_default_output_placement, Ishell_Max_Popup_Size} %!%- public define ishell_mode() % (cmd=Ishell_Default_Shell) { variable cmd = push_defaults(Ishell_Default_Shell, _NARGS); % set the working dir to the active buffers dir () = chdir(buffer_dirname()); #ifdef UNIX putenv("PAGER=cat"); % jed has more or less problems otherwise ;-) #endif % start the process ishell_open_process(cmd); % wait for the process prompt get_process_input(10); % wait up to 1 second % modifiy keybindings (use an own keymap): variable ishell_map = what_keymap()+" ishell"; !if (keymap_p(ishell_map)) { copy_keymap(ishell_map, what_keymap()); definekey_reserved("ishell_send_intr", "G", ishell_map); definekey_reserved("ishell_logout", "D", ishell_map); definekey_reserved("ishell_send_input", "^M", ishell_map); % Enter rebind("run_buffer", "ishell_send_input", ishell_map); } push_keymap(ishell_map); %this also changes the modename % set/modify the mode-menu mode_set_mode_info(get_mode_name(), "init_mode_menu", &ishell_menu); run_mode_hooks("ishell_mode_hook"); } %!%+ %\function{ishell} %\synopsis{Interactive shell} %\usage{ ishell()} %\description % Open an interactive shell in buffer *ishell* and set to \sfun{ishell_mode}. %\seealso{ishell_mode, Ishell_Default_Shell} %!%- public define ishell() { variable buf = "*ishell*"; pop2buf (buf); set_buffer_undo(1); !if(blocal_var_exists("Ishell_Handle")) { sh_mode(); % syntax highlight, keybindings ishell_mode(); } } %!%+ %\function{terminal} %\synopsis{Run a command in a terminal} %\usage{terminal(cmd = Ishell_Default_Shell)} %\description % Run \var{cmd} in a terminal with the current buffer's dir as working % directory. %\notes % The terminal is the one jed runs on or (with xjed) given by the custom % variable \var{XTerm_Pgm} (defaulting to "xterm"). %\seealso{run_program, ishell_mode, Ishell_Default_Shell} %!%- public define terminal() % (cmd = Ishell_Default_Shell) { variable cmd = push_defaults(Ishell_Default_Shell, _NARGS); () = chdir(buffer_dirname); () = run_program(cmd); } % --- run a shell command (with flexible output setting) --------------------- % % (This section should rather go to shell.sl.) % the last command as default for the next call, also used by shell.sl, % so we use custom_variable to not overwrite it when evaluating ishell custom_variable("Shell_Last_Shell_Command", ""); %!%+ %\function{shell_command} %\synopsis{Run a shell command} %\usage{Void shell_command(cmd="", output_handling=0)} %\usage{Void shell_command(cmd="", String output_buffer)} %\description % Executes \var{cmd} in a shell. % If no argument is given, the user will be prompted for a command to execute. % % Output handling is controled by the second argument % -1 ignore the output, % 0 a new buffer is opened for the output (if there is output). % 1 output will be inserted on the edition point, % 2 output replaces the region/buffer. % 3 return output as string % 4 message output % "" name of a new buffer for the output %\notes % The default is set using prefix_argument(0), i.e. you can set the output % handling tag via \sfun{set_prefix_argument}, too. %\seealso{run_shell_cmd, shell_cmd, filter_region, shell_cmd_on_region} %!%- public define shell_command() % (cmd="", output_handling=0) { % optional arguments variable cmd, output_handling; (cmd, output_handling) = push_defaults("", prefix_argument(0), _NARGS); variable status, buf = whatbuf(), outbuf = "*shell-output*", output = ""; variable file, dir= buffer_dirname(), name, flags; % change working dir to buffer dir if ( change_default_dir(dir) ) error ("Unable to chdir!"); % ask for command in minibuffer if (cmd == "") { cmd = read_mini(sprintf ("(%s) Shell Cmd:", dir), "", Shell_Last_Shell_Command); if (cmd == "") return; Shell_Last_Shell_Command = cmd; } % if second arg is a String, it is the name of the output buffer if (typeof(output_handling) == String_Type) { outbuf = output_handling; output_handling = 0; } if (output_handling == 2) % replace region or buffer { if(is_visible_mark()) del_region(); else erase_buffer(); } % open the output buffer with popup_buffer() !if (output_handling == 1 or output_handling == 2) % insert in same buffer { popup_buffer(outbuf); (file, ,name, flags) = getbuf_info(); setbuf_info (file, dir,name, flags); set_readonly(0); eob; } % Run the command set_prefix_argument(1); do_shell_cmd(cmd); % Output processing % not needed, if output inserted in same buffer if (output_handling == 1 or output_handling == 2) return; if (output_handling != 0) { push_mark(); % point is at start of output after do_shell_cmd() eob(); output = bufsubstr_delete(); } % close empty output buffer set_buffer_modified_flag(0); if(bobp and eobp) { close_buffer(); sw2buf(buf); if(output == "") message(MESSAGE_BUFFER + ": no output"); } switch (output_handling) % { case -1 } % ignore { case 0: % open in new buffer (if there is output) if (bufferp(outbuf)) { !if (bobp()) insert("\n------------------------------------\n\n"); if (eobp) insert(cmd + ": no output"); fit_window(get_blocal("is_popup", 0)); view_mode(); } } % { case 1 or case 2: } % insert in same buf: already returned { case 3: return output; } % return as string { case 4: if (output != "") message(output); } } public define shell_cmd_on_region_or_buffer() % (cmd="", output_handling=0, postfile_args="") { variable cmd, output_handling, postfile_args; (cmd, output_handling, postfile_args) = push_defaults("", 0, "", _NARGS); % read command from minibuffer if not given as optional argument if (cmd == NULL or cmd == "") % NULL test for backwards compatibility { cmd = read_mini(sprintf("(%s) Shell Cmd:", getcwd()), "", Shell_Last_Shell_Command); Shell_Last_Shell_Command = cmd; } if (cmd == "") return; variable file = buffer_filename(); if (file == "" or is_visible_mark()) % save region/buffer to file (delete if output_handling == 2) file = bufsubfile(typecast(output_handling, Integer_Type) == 2); else { save_buffer(); if (_eqs(2, output_handling)) % can be a string or integer erase_buffer(); } % Run the command on the file shell_command(strjoin([cmd, file, postfile_args], " "), output_handling); } %!%+ %\function{shell_cmd_on_region} %\synopsis{Save region to a temp file and run a command on it} %\usage{Void shell_cmd_on_region(cmd="", output_handling=0, postfile_args="")} %\usage{Void shell_cmd_on_region(cmd="", String output_buffer, postfile_args="")} %\description % Run \var{cmd} in a shell. (If \var{cmd}=="", the user will be prompted for % a command to execute.) % % Output handling is controlled by the second argument (see \var{shell_command}) % % The region will be saved to a temporary file and the filename appended to % the arguments. If no region is defined, the whole buffer is saved. % % The third argument \var{postfile_args} will be appended to the command % string after the filename argument. Use it e.g. for the outfile in commands % like "rst2html infile outfile". % \seealso{shell_command, filter_region, run_shell_cmd} %!%- public define shell_cmd_on_region() % (*args) { variable args = __pop_args(_NARGS); !if (is_visible_mark()) { !if (markp()) mark_buffer(); % replace mark by a visible mark push_spot(); pop_mark_1(); push_visible_mark(); pop_spot(); } shell_cmd_on_region_or_buffer(__push_args(args)); } %!%+ %\function{filter_region} %\synopsis{Filter the region through a shell command} %\usage{filter_region(cmd=NULL)} %\description % Start cmd in a sub-shell. If no argument is given, the user will be % prompted for one. % The region will be saved to a temporary file and its name appended to the % arguments. If no region is defined, the whole buffer is taken instead. % The command output will replace the region/buffer. %\seealso{shell_cmd_on_region, shell_command} %!%- public define filter_region() % (cmd=NULL) { variable cmd = push_defaults(, _NARGS); shell_cmd_on_region(cmd, 2); } %!%+ %\function{shell_cmd2string} %\synopsis{Run a shell cmd and return the output} %\usage{String shell_cmd2string(String cmd)} %\description % Run a shell cmd and return the output as a string. % This is an alias for shell_command(cmd, 3) %\example %#v+ % insert(shell_cmd2string(date)); %#v- % would insert the current date as returned by the `date` command %\seealso{shell_command, shell_cmd_on_region} %!%- define shell_cmd2string(cmd) { return shell_command(cmd, 3); } jedmodes-2.5.7/custmode/0000755000175400017500000000000010461125576013434 5ustar mildegmjedmodes-2.5.7/custmode/custmode.sl0000644000175400017500000001206410340557314015615 0ustar mildegm% Created : 08 Oct 2004 % Author : Marko Mahnic % % Create a custom syntax table for the current buffer. % The syntax is defined after the modeline. % Each custom_mode buffer creates its own syntax table named custom_N. % The name of the syntax table is stored in a buffer-local variable. % % % % require ("keywords"); static variable custom_syn="custom"; static variable blvar_modename="custom_mode"; static variable blvar_modeflgs="custom_flags"; static variable custom_count = 0; static define extract_eol(eq_char) { () = ffind_char(eq_char); go_right(1); push_mark(); eol(); return strtrim(bufsubstr()); } static define extract_char(eq_char) { () = ffind_char(eq_char); go_right(1); skip_white(); return what_char(); } static define prepare_syntax_table(modename) { variable n = 0, kwds1 = NULL, kwds2 = NULL; variable modeflags = 2; variable kwdflags; create_syntax_table(modename); bob(); n = re_fsearch ("-\\*- *mode: *custom"); if (n < 1) return; if (what_line() > 4) return; go_down(1); bol(); n = ffind ("###"); while (n) { go_right(3); skip_white(); if (looking_at("%")) { if (looking_at("%keywords1=")) { if (kwds1 == NULL) kwds1 = keywords->new_keyword_list (); keywords->add_keywords (kwds1, extract_eol('=')); } else if (looking_at("%keywords2=")) { if (kwds2 == NULL) kwds2 = keywords->new_keyword_list (); keywords->add_keywords (kwds2, extract_eol('=')); } else if (looking_at("%words=")) define_syntax (extract_eol('='), 'w', modename); else if (looking_at("%numbers=")) define_syntax (extract_eol('='), '0', modename); else if (looking_at("%commenteol=")) define_syntax (extract_eol('='), "", '%', modename); else if (looking_at("%string1=")) define_syntax (extract_char('='), '\'', modename); else if (looking_at("%string2=")) define_syntax (extract_char('='), '\"', modename); else if (looking_at("%preprocessor=")) define_syntax (extract_char('='), '#', modename); else if (looking_at("%quote=")) define_syntax (extract_char('='), '\\', modename); else if (looking_at("%parens=")) { variable parens = extract_eol('='); variable len = strlen(parens); if ((len > 1) and ((len mod 2) == 0) ) define_syntax (substr(parens, 1, len/2), substr(parens, len/2+1, len/2), '(', modename); } else if (looking_at("%modeflags=")) { kwdflags = strlow(extract_eol('=')); modeflags = 0; if (is_substr(kwdflags, "wrap")) modeflags |= 0x01; if (is_substr(kwdflags, "c")) modeflags |= 0x02; if (is_substr(kwdflags, "language")) modeflags |= 0x04; if (is_substr(kwdflags, "slang")) modeflags |= 0x08; if (is_substr(kwdflags, "fortran")) modeflags |= 0x10; if (is_substr(kwdflags, "tex")) modeflags |= 0x20; } else if (looking_at("%syntaxflags=")) { kwdflags = strlow(extract_eol('=')); variable syntax = 0; if (is_substr(kwdflags, "nocase")) syntax |= 0x01; if (is_substr(kwdflags, "comfortran")) syntax |= 0x02; if (is_substr(kwdflags, "nocmodeldspc")) syntax |= 0x04; if (is_substr(kwdflags, "tex")) syntax |= 0x08; if (is_substr(kwdflags, "comeolspc")) syntax |= 0x10; if (is_substr(kwdflags, "preprocline")) syntax |= 0x20; if (is_substr(kwdflags, "preprocldspc")) syntax |= 0x40; if (is_substr(kwdflags, "nostrspan")) syntax |= 0x80; set_syntax_flags(modename, syntax); } } go_down(1); if (eobp()) break; bol(); n = ffind ("###"); } if (kwds1 != NULL) { keywords->sort_keywords(kwds1); if (syntax & 0x01) keywords->strlow_keywords(kwds1); keywords->define_keywords(kwds1, modename, 0); } if (kwds2 != NULL) { keywords->sort_keywords(kwds2); if (syntax & 0x01) keywords->strlow_keywords(kwds1); keywords->define_keywords(kwds2, modename, 1); } return modeflags; } % -------------------------------------------------------------- % Main entry % public define custom_mode () { variable custom_id, modename, modeflags = 2; if (blocal_var_exists(blvar_modename)) { modename = get_blocal_var(blvar_modename); } else { create_blocal_var(blvar_modename); modename = sprintf("%s_%d", custom_syn, custom_count); set_blocal_var(modename, blvar_modename); custom_count++; modeflags = prepare_syntax_table(modename); create_blocal_var(blvar_modeflgs); set_blocal_var(modeflags, blvar_modeflgs); } if (blocal_var_exists(blvar_modeflgs)) modeflags = get_blocal_var(blvar_modeflgs); set_mode(modename, modeflags); use_syntax_table(modename); } jedmodes-2.5.7/custmode/custmode_sl.html0000664000175400017500000001264110214064411016633 0ustar mildegm JED Macro: custmode.sl

custmode.sl

Have you ever needed to syntax highlight a file but you did not have the appropriate mode for it? With this set of macros you can define a custom syntax in the highlighted file.

Example

You have a simple text file. You decide that you want to higlight the words: @Title, @Author, @Date. The case of the words does not matter. You would also like to see the numbers in a different color. Also the strings should be highlighted. You put this at the beginning of your file:

  ;; -*- mode: custom; -*-
  ;; ### %words= @0-9a-zA-Z_
  ;; ### %keywords1= @Title @Author @Date
  ;; ### %numbers= -+0-9.
  ;; ### %string1= '
  ;; ### %string2= "
  ;; ### %syntaxflags= nocase
  
When you save the file and reopen it, you will see the desired effect.

Syntax

The first thing to do is to add the modeline:

  ;; -*- mode: custom; -*-

The syntax definition must follow the modeline immediately. Each line must start with an optional comment symbol followed by ###. Then there can be an arbitrary number of spaces and a tag: %tagname=.

  ;; ### %tagname= values

The syntax definition ends at the first line without ###.

Known tags

Tag Type Description Value example
%keywords1= list of keywords List of keywords to be highlited; if the list is too long it can be split into multiple lines beginning with %keywords1= if then else
%keywords2= list of keywords Defines the second set of keywords (see %keywords1=) sin cos tan
%words= set of characters Defines the characters that compose a word a-zA-Z_0-9
%numbers= set of characters Defines the characters that compose a number -+0-9.
%string1= character Defines the single quote character '
%string2= character Defines the double quote character "
%commenteol= string Defines the end-of-line comment marker //
%preprocessor= character Defines the preprocessor character #
%quote= character Defines the 'Escape' character \
%parens= string Defines the matching parenthesis [({])}
%modeflags= list of flags Defines the flags for the mode (see a separate table for the list of possible flags) language fortran
%syntaxflags= list of flags Defines the flags for the syntax (see a separate table for the list of possible flags) tex nocase
See also define_syntax().

List of flags for %modeflags=

wrap 0x01
c 0x02
language 0x04
slang 0x08
fortran 0x10
tex 0x20
See also set_mode().

List of flags for %syntaxflags=

nocase 0x01
comfortran 0x02
nocmodeldspc 0x04
tex 0x08
comeolspc 0x10
preprocline 0x20
preprocldspc 0x40
nostrspan 0x80
See also set_syntax_flags().

Installation

Put the file somewhere on your jed_library_path and

   autoload ("custom_mode", "custmode.sl");
   
in your .jedrc file. jedmodes-2.5.7/info/0000755000175400017500000000000011130344607012534 5ustar mildegmjedmodes-2.5.7/info/info_look.sl0000644000175400017500000000246211130344607015057 0ustar mildegm% info_look.sl % mode-sensitive Info index lookup facility. % % $Id: info_look.sl,v 1.4 2008/11/20 16:27:09 paul Exp paul $ % Keywords: help languages % % Copyright (c) 2003-2008 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % Some functions to use hyperhelp's help_for_word_hook with % hyperman and info. autoload("unix_apropos", "hyperman"); require("info"); use_namespace("info"); % Look up word in manpage in mode-dependent section public define manpage_lookup(word) { try { ifnot (blocal_var_exists("man_section")) unix_man(word); else unix_man(sprintf("%s(%s)", word, get_blocal_var("man_section"))); } catch RunTimeError: { unix_apropos(word); } } % Look up word in info in index if it exists, as node otherwise public define info_lookup() % word { ifnot (_NARGS) get_word(); variable word = (); ifnot (blocal_var_exists("info_page")) throw RunTimeError, "Don't know what info page to look in"; variable buf = whatbuf(), page = get_blocal_var("info_page"); variable e; try (e) { info_reader(); info_find_node(sprintf("(%s)Top", page)); if(re_fsearch("^* \\(.*[Ii]ndex\\):")) info_index(word); else info_find_node(word); pop2buf(buf); } catch RunTimeError: { sw2buf(buf); throw; } } jedmodes-2.5.7/info/infomisc.sl0000644000175400017500000000770611130344607014715 0ustar mildegm% infomisc.sl -*- mode: SLang; mode: fold -*- % autoloaded functions for info require("info"); use_namespace("info"); %{{{ full search public define info_search () { variable this_line, this_file, str, err_str, file, wline, ifile, ext; err_str = "String not found."; str = read_mini("Re-Search:", LAST_SEARCH, Null_String); ifnot (strlen(str)) return; save_search_string(str); widen(); go_right_1 (); if (re_fsearch(str)) { info_narrow(); return; } % % Not found. Look to see if this is split. % if (indirect == NULL) { info_narrow(); throw RunTimeError, err_str; } this_file = Info_This_Filename; this_line = what_line(); wline = window_line(); %need this so state can be restored after a failure. variable is_later=0; foreach file (indirect.files) { ifnot (is_later) { if (file == extract_filename(this_file)) is_later = 1; continue; } flush("Searching " + file); (ifile, ext) = info_make_file_name(file); #ifdef UNIX OS2 if (strlen(ext)) { variable re = str; % Not all greps support -e option. So, try this: if (re[0] == '-') re = "\\" + re; setbuf(" *Info*zcat*"); erase_buffer(); () = run_shell_cmd(sprintf("%s %s%s | grep -ci '%s'", make_unzip_cmd (ext), ifile, ext, re)); bob(); if (looking_at_char ('0')) { % what's this for? continue; } } else #endif ifnot (search_file(ifile, str, 1)) { continue; } info_find_file(file); ()=fsearch(str); info_narrow(); info_push_position(this_file, indirect, this_line); return; } widen(); info_find_file (this_file); goto_line(this_line); eol(); info_narrow(); recenter(wline); throw RunTimeError, err_str; } %}}} %{{{ index search private variable index = NULL; public define info_index_next() { if (index==NULL) throw RunTimeError, "do an index search first"; ifnot (length(index.matches)) throw RunTimeError, "no matches"; if (index.file != info_extract_pointer("File")) info_find_node(sprintf("(%s)Top",index.file)); info_find_node(index.matches[index.index]); vmessage("found %s (%d more)", index.matches[index.index], length(index.matches) - index.index -1); index.index++; if (index.index == length(index.matches)) index.index = 0; } % Do index search on an info file. The optional arg is % used by info_lookup. public define info_index() % [topic] { variable matches = Assoc_Type[Integer_Type], this_match = "", next_node, have_index = 0, wline; index = struct { matches, index, file }; index.file=info_extract_pointer("File"); if (bufferp("*Info*")) { sw2buf("*Info*"); } ifnot (_NARGS) read_mini("index: ", "", ""); variable s = (); wline = window_line(); info_find_node("Top"); index.matches = {}; index.index = 0; variable e; try (e) { ifnot(re_fsearch("^* .*[Ii]ndex:")) throw RunTimeError, "no index"; info_keep_history = 0; follow_menu; if (s == "") { info_keep_history = 1; return; } forever { ifnot(fsearch(s)) { ifnot(have_index) break; next_node = info_extract_pointer("Next"); if (next_node != NULL && is_substr(next_node, "Index")) { info_find_node(next_node); continue; } break; } eol; push_mark; () = bfind_char(':'); skip_chars(": \t"); this_match = strtrim_end(bufsubstr, " \t."); this_match = extract_element(this_match, 0, '.'); eol; if (strlen(this_match) && not assoc_key_exists(matches, this_match)) { matches[this_match]=1; list_append(index.matches, this_match); } } index.index = 0; info_index_next(); info_keep_history = 1; } catch RunTimeError: { info_keep_history = 1; pop_position; recenter(wline); throw RunTimeError, e.message; } } %}}} jedmodes-2.5.7/info/info.sl0000644000175400017500000005666011130344607014044 0ustar mildegm% info.sl -*- mode: SLang; mode: fold -*- % Info reader for JED % % $Id: info.sl,v 1.15 2008/11/20 16:26:36 paul Exp paul $ % Keywords: help % % Copyright (c) 2000-2008 JED, Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). _autoload("info_search", "infomisc", "info_index", "infomisc", "info_index_next", "infomisc", "browse_url", "browse_url", 4); require("pcre"); provide("info"); implements("info"); variable Info_This_Filename = Null_String; variable Info_This_Filedir = Null_String; variable indirect = NULL; %{{{ info file #ifndef VMS % returns compression extension if file is compressed or "" if not define info_is_compressed (file) { variable ext; foreach ext ([".Z", ".z", ".gz", ".bz2"]) { if (1 == file_status(file + ext)) return ext; } return ""; } #endif define info_make_file_name (file) { variable n=0, dir, dirfile, df, df_low; variable cext = "", path; % compressed extension if (strlen(Info_This_Filedir) and not is_list_element(Info_Directory, Info_This_Filedir, ',')) path = sprintf("%s,%s", Info_This_Filedir, Info_Directory); else path = Info_Directory; EXIT_BLOCK { (Info_This_Filedir, ) = parse_filename(dirfile); dirfile, cext; } USER_BLOCK0 { if (1 == file_status(dirfile)) return; #ifndef VMS cext = info_is_compressed(dirfile); if (strlen(cext)) return; #endif } forever { dir = extract_element(path, n, ','); if (dir == NULL) dir = ""; df = expand_filename(dircat(dir,file)); % try with first with info extension #ifdef VMS dirfile = df + "info"; % VMS adds a '.' upon expansion #else dirfile = df + ".info"; #endif X_USER_BLOCK0; df_low = expand_filename(dircat(dir,strlow(file))); #ifdef VMS dirfile = df_low + "info"; % VMS adds a '.' upon expansion #else dirfile = df_low + ".info"; #endif X_USER_BLOCK0; % try next with inf extension, since .info causes problems on FAT % In addition, Unix and VMS distributions may have been derived from % PC 8+3 distributions. % % Also Windows 95 supports long filenames. Since that OS is also % considered to be MSDOS, we need to try this for MSDOS as well % even though it has no effect under a true MSDOS system. dirfile = df_low + ".inf"; X_USER_BLOCK0; % repeat without extension dirfile = df; X_USER_BLOCK0; dirfile = df_low; X_USER_BLOCK0; ifnot (strlen(dir)) { throw RunTimeError, "Info file not found: " + file; } ++n; } } define make_unzip_cmd (ext) { switch (ext) { case ".gz": "gzip -dc"; } { case ".bz2": "bzip2 -dc"; } { "uncompress -c"; } } define info_mode_menu(); define info_find_file (file) { variable dirfile, ext; (dirfile, ext) = info_make_file_name(file); setbuf("*Info*"); set_readonly(0); widen(); erase_buffer(); #ifndef VMS if (strlen(ext)) () = run_shell_cmd (sprintf("%s %s%s", make_unzip_cmd (ext), dirfile, ext)); else #endif () = insert_file(dirfile); bob(); Info_This_Filename = dirfile; set_readonly(1); set_buffer_modified_flag(0); set_mode("info", 0); mode_set_mode_info("info", "init_mode_menu", &info_mode_menu); use_keymap("Infomap"); #ifdef HAS_DFA_SYNTAX use_syntax_table("info"); #endif } %}}} %{{{ navigation %{{{ finding the node define info_find_node_split_file(); % extern define info_search_marker(dir) { if (dir > 0) return bol_fsearch_char(0x1F); else return bol_bsearch_char(0x1F); } define info_extract_pointer(); define narrow_to_node() { push_mark(); if (info_search_marker(1)) go_up_1(); else eob(); narrow(); bob(); go_down_1(); recenter(1); variable current_filename = path_sans_extname(info_extract_pointer("File")); set_status_line(sprintf("Jed Info: (%%m) (%s)%s (%%p) %%t", current_filename, info_extract_pointer("Node")), 0); } % find the node. define info_find_node_this_file (the_node) { widen(); bob(); forever { ifnot (re_fsearch(sprintf("\\c^File:.*Node: ?%s[,\t]", str_quote_string (the_node, "\\^$[]*.+?", '\\')))) { % dont give up, maybe this is a split file if (indirect == NULL) throw RunTimeError, "Marker not found!. Node: " + the_node; info_find_node_split_file(the_node); return; } go_up_1(); bol(); ifnot (looking_at_char(0x1F)) { go_down_1 (); eol(); continue; } go_down_1(); break; } narrow_to_node(); } define make_indirect() { variable mark = create_user_mark(); bob (); ()=bol_fsearch("Indirect:"); push_mark(); ifnot (info_search_marker(1)) eob(); narrow(); variable re=pcre_compile("^(.*): ([\\d]+)"); variable entry, i=0; indirect = struct{files, bytes, tag_table}; indirect.files=String_Type[what_line()]; indirect.bytes=Integer_Type[what_line()]; bob(); while (down_1()) { entry=line_as_string(); if (pcre_exec(re, entry)) { indirect.files[i]=pcre_nth_substr(re, entry, 1); indirect.bytes[i]=atoi(pcre_nth_substr(re, entry, 2)); i++; } } indirect.files=indirect.files[[:i-1]]; indirect.bytes=indirect.bytes[[:i-1]]; eob(); widen(); push_mark(); eob(); indirect.tag_table=bufsubstr(); goto_user_mark(mark); } define info_find_node_split_file (node) { variable tag, tagpos, pos, pos_len, tag_len, file; variable re, offset = 0; if (indirect == NULL) make_indirect(); re = pcre_compile(strcat("^Node: \\Q", node, "\\E[\t \x7F](\\d+)[ \t]*$"), PCRE_MULTILINE); if (pcre_exec(re, indirect.tag_table)) { tagpos = pcre_nth_substr(re, indirect.tag_table, 1); } else { % This finds footnotes hidden in special footnote nodes such as in % the groff info page re = pcre_compile(strcat("^Node: *(.*)\x7F(\\d+)[ \t]*\n(?:^Ref:.*\n)*^Ref: \\Q", node, "\\E[\t \x7F](\\d+)[ \t]*$"), PCRE_MULTILINE | PCRE_UNGREEDY); if (pcre_exec(re, indirect.tag_table)) { node = pcre_nth_substr(re, indirect.tag_table, 1); tagpos = pcre_nth_substr(re, indirect.tag_table, 2); offset = atoi(pcre_nth_substr(re, indirect.tag_table, 3)) - atoi(tagpos); } else throw RunTimeError, "could not find node in tag table"; } file = wherelast (indirect.bytes <= atoi(tagpos)); if (file == NULL) throw RunTimeError, "tag before any nodes?"; file = dircat(Info_This_Filedir, indirect.files[file]); info_find_file(file); info_find_node_this_file(node); if (offset) { bob(); go_right(offset); } } %}}} %{{{ history define info_narrow() { push_spot(); () = info_search_marker(-1); go_down_1 (); narrow_to_node(); pop_spot(); } % stack for last position ifnot (is_defined ("Info_Position_Type")) { typedef struct { filename, indirect, line_number } Info_Position_Type; } variable Info_Position_Stack = Info_Position_Type [16], Info_Position_Rotator = [[1:15],0], Info_Stack_Depth = 0, Forward_Stack_Depth = 0; define info_push_position(file, indirect, line) { if (Info_Stack_Depth == 16) { --Info_Stack_Depth; Info_Position_Stack = Info_Position_Stack [Info_Position_Rotator]; } variable pos = Info_Position_Stack [Info_Stack_Depth]; pos.filename = file; pos.indirect = indirect; pos.line_number = line; ++Info_Stack_Depth; Forward_Stack_Depth = 0; } variable info_keep_history = 1; define info_record_position () { if (whatbuf() != "*Info*") return; ifnot (info_keep_history) return; widen(); info_push_position(Info_This_Filename, indirect, what_line()); info_narrow(); } define goto_stack_position() { variable pos = Info_Position_Stack [Info_Stack_Depth]; indirect = pos.indirect; if ((pos.filename == Info_This_Filename) && bufferp("*Info*")) { widen(); goto_line(pos.line_number); bol(); info_narrow(); return; } ifnot (strlen(pos.filename)) return; info_find_file(pos.filename); goto_line(pos.line_number); bol(); info_narrow(); } define pop_position() { --Info_Stack_Depth; goto_stack_position; } % increment forward depth and move back; if this is is our first step % back, record the current position. define goto_last_position () { if (Info_Stack_Depth <= 0) return; ifnot (Forward_Stack_Depth) { info_record_position; --Info_Stack_Depth; } ++Forward_Stack_Depth; pop_position; } % move forward again define goto_next_position() { ifnot (Forward_Stack_Depth) return; ++Info_Stack_Depth; --Forward_Stack_Depth; if (Info_Stack_Depth == 16) return; goto_stack_position; } %}}} %{{{ moving around define find_dir(); define follow_current_xref(); public define info_find_node(node) { variable file, n = 0; variable current_filename = path_sans_extname(info_extract_pointer("File")); % Replace \n and \t characters in name by spaces node = strcompress (node, " \t\n"); info_record_position(); variable old_indirect = indirect; try { % if it looks like (file)node, extract file, node if (is_substr(node, "(") == 1 && (n = is_substr(node, ")"), n) && (file = substr(node, 2, n - 2), node = substr(node, n+1, strlen(node)), file != current_filename)) { indirect = NULL; info_find_file(file); } node = strtrim (node); widen(); variable mark = create_user_mark(); bob (); ifnot (info_search_marker(1)) throw RunTimeError, "Marker not found."; go_down_1 (); USER_BLOCK0 { if (looking_at("Indirect:"), goto_user_mark(mark)) info_find_node_split_file(node); else info_find_node_this_file(node); } if (strlen(node)) { X_USER_BLOCK0; } else { node = "Top"; try { X_USER_BLOCK0; } catch RunTimeError: { node="top"; X_USER_BLOCK0; } } sw2buf("*Info*"); } catch AnyError: { indirect = old_indirect; sw2buf("*Info*"); info_reader (); pop_position(); throw; } } % If buffer has a menu, point is put on line after menu marker if argument % is non-zero, otherwise leave point as is. % signals error if no menu. define info_find_menu(save) { push_spot_bob (); ifnot (re_fsearch("^\\c\\* Menu:")) { pop_spot(); throw RunTimeError, "Node has no menu."; } ifnot (save) { pop_spot(); return; } go_down_1 (); push_mark(); pop_spot(); pop_mark_1 (); } % Move the cursor to the start of the next nearest menu item or % note reference in this node if possible. define next_xref () { push_mark (); go_right_1 (); for (; fsearch_char('*'); skip_chars("*")) { if ((bolp() && looking_at ("* ")) || re_looking_at("\\C\\*note")) { if (re_looking_at("\\C^* menu")) continue; exchange_point_and_mark(); break; } } pop_mark_1(); } % Move the cursor to the start of the previous nearest menu item or % note reference in this node if possible. define prev_xref () { push_mark (); go_left_1 (); for (; bsearch_char('*'); bskip_chars("*")) { if ((bolp() && looking_at ("* ")) || re_looking_at("\\C\\*note")) { if (re_looking_at("\\C^* menu")) continue; exchange_point_and_mark(); break; } } pop_mark_1(); } % menu references define follow_current_xref () { variable node; push_spot(); ifnot (fsearch_char (':')) { pop_spot(); throw RunTimeError, "Corrupt File?"; } if (looking_at("::")) { push_mark(); pop_spot(); node = bufsubstr(); } else { go_right_1 (); skip_white(); if (eolp()) { go_right_1 (); skip_white(); } push_mark(); if (looking_at_char('(')) () = ffind_char (')'); % xrefs may be split across two lines, also I've seen xrefs terminated by '(' skip_chars("^,\t.("); % does not skip newlines if (eolp) { go_down_1(); skip_chars("^,\t.("); } node = strcompress(bufsubstr(), " \n"); pop_spot(); } info_find_node(node); } % follow the menu item on this line. We are at bol. define follow_menu() { ifnot (ffind_char(':')) throw RunTimeError, "Corrupt File?"; if (looking_at("::")) { push_mark(); bol(); go_right(2); } else { go_right_1 (); skip_white(); push_mark(); if (looking_at_char('(')) { () = ffind_char (')'); } % comma, tab, '.', or newline terminates skip_chars("^,.\t\n"); bskip_chars(" "); } info_find_node(bufsubstr()); } % This reads the menu items into a comma-delimited string define get_menu_items() { push_spot_bob(); ifnot (re_fsearch("^\\c\\* Menu:")) return pop_spot, NULL; eol(); variable n = 0; ","; while (bol_fsearch("* ")) { go_right(2); push_mark(); ()=ffind_char(':'); bufsubstr(); n++; } pop_spot(); return create_delimited_string(n); } define menu () { variable node = Null_String; info_find_menu (0); variable items = get_menu_items(); bol (); if (looking_at("* ") && ffind(":")) { push_mark(); bol(); go_right(2); node = bufsubstr(); bol(); } node = read_string_with_completion("Menu item:", node, items); info_find_menu (1); ifnot (bol_fsearch(sprintf("* %s:", node))) throw RunTimeError, "Menu Item not found."; follow_menu(); } define follow_nearest_node () { variable colon = ":", colons = "::"; % This is the "enter" action, should be a separate function if (re_looking_at ("\\C*Note[ \t\n]")) { go_right (5); skip_chars (" \t\n"); follow_current_xref (); return; } info_find_menu (0); bol(); follow_menu(); } define find_dir() { if ("*Info*" == whatbuf()) { variable file = "* " + path_sans_extname(info_extract_pointer("File")); info_find_node ("(DIR)Top"); () = bol_fsearch(file); } else info_find_node ("(DIR)Top"); } define info_extract_pointer() { variable name, errorname = NULL; if (_NARGS == 2) errorname = (); push_spot_bob(); go_down_1(); variable len = re_bsearch(() + ":"); if (len) go_right(len - 1); else { pop_spot(); if (errorname != NULL) throw RunTimeError, "node has no " + errorname; else return ""; } skip_white(); push_mark(); skip_chars("^,\t\n"); bskip_white(); bufsubstr(); pop_spot(); } define info_up () { variable upnode = info_extract_pointer("Up"); if(upnode == NULL || upnode == "(dir)") find_dir (); else { "* " + info_extract_pointer("Node"); info_find_node(upnode); () = bol_fsearch(); } } define info_prev() { info_find_node(info_extract_pointer("Prev[ious]*", "PREVIOUS")); } define info_next () { info_find_node(info_extract_pointer("Next", "NEXT")); } define info_top() { info_find_node("Top"); } %}}} %}}} %{{{ help for info define quick_help() { message("q:quit, h:tutorial, SPC:next screen, DEL:prev screen, m:menu, s: search"); } define tutorial() { info_find_node("(info)help"); } %}}} %{{{ menu, keys, mouse, bookmarks define info_mode_menu(menu) { $1= _stkdepth; "&Add Bookmark", "info->add_bookmark"; "&Help", "info->tutorial"; "&Search", "info_search"; "&Index", "info_index"; "&Top", "info->top"; "&Dir", "info->find_dir"; loop ((_stkdepth - $1)/2) menu_append_item(menu, _stk_roll(3)); } define add_bookmark() { menu_append_popup("Global.M&ode", "&Bookmark"); variable bookmark = sprintf("(%s)%s", path_sans_extname(info_extract_pointer("File")), info_extract_pointer("Node")); menu_append_item("Global.M&ode.&Bookmark", bookmark, sprintf ("info_find_node(\"%s\")", bookmark)); message ("bookmark added"); } $2 = "Infomap"; ifnot (keymap_p($2)) { make_keymap($2); $1 = _stkdepth; "info->quick_help", "?"; "info->tutorial", "h"; "info->tutorial", "H"; "info->follow_nearest_node", "^M"; "info->menu", "m"; "info->next_xref", "\t"; #ifdef MSDOS MSWINDOWS "info->prev_xref", "^@^O"; #endif "info->info_next", "N"; "info->info_next", "n"; "info->info_prev", "P"; "info->info_prev", "p"; "info->info_up", "U"; "info->info_up", "u"; "info->info_top", "t"; "info->scroll", " "; "page_up", "^?"; "bob", "B"; "bob", "b"; "info->goto_node", "G"; "info->goto_node", "g"; "info->quit", "q"; "info->quit", "Q"; "info->goto_last_position", "l"; "info->goto_last_position", "L"; "info->goto_next_position", ";"; "info_search", "S"; "info_search", "s"; "info_search", "/"; "info->follow_reference", "f"; "info->follow_reference", "F"; "info->find_dir", "D"; "info->find_dir", "d"; "info_index", "i"; "info_index_next", ","; "info->add_bookmark", "a"; "info->forward_node", "]"; loop((_stkdepth() - $1) /2) definekey ($2); _for (1, 9, 1) { $1 = (); definekey("info->menu_number", string($1), $2); } runhooks ("info_binding_hook"); } define mouse_hook(line, col, but, shift) { if (bfind_char('*')) { follow_nearest_node(); } else if (bfind("http://")) { push_mark(); go_right(7); skip_chars("-a-zA-Z0-9~/.+&#=?"); bskip_chars(".?"); browse_url(bufsubstr); } 1; } %}}} %{{{ DFA #ifdef HAS_DFA_SYNTAX create_syntax_table ("info"); %%% DFA_CACHE_BEGIN %%% define setup_dfa_callback (mode) { % dfa_enable_highlight_cache(mode +".dfa", mode); % this should highlight both long and short menu items, % but not the *menu: line dfa_define_highlight_rule ("^\\*[^:]+:[: ]", "keyword0", mode); dfa_define_highlight_rule ("\\*[Nn]ote", "keyword0", mode); dfa_define_highlight_rule ("http://[\\-a-zA-Z0-9~/\\\.]+[a-zA-Z0-9/]", "string", mode); dfa_build_highlight_table(mode); } dfa_set_init_callback (&setup_dfa_callback, "info"); %%% DFA_CACHE_END %%% enable_dfa_syntax_for_mode("info"); #endif %}}} %{{{ (mostly) interactive functions %{{{ info mode % The tm documentation has been adapted from Emacs' documentation. I hope % all the info is correct. %!%+ %\function{info_mode} % %\usage{define info_mode ()} %\description % % Info mode provides commands for browsing through the Info documentation % tree. Documentation in Info is divided into "nodes", each of which % discusses one topic and contains references to other nodes which discuss % related topics. Info has commands to follow the references and show you % other nodes. % % \var{h} Invoke the Info tutorial. % \var{q} Quit Info % % Selecting other nodes: % \var{mouse-1} % Follow a node reference you click on. % \var{RET} Follow a node reference near point, like mouse-1. % \var{n} Move to the "next" node of this node. % \var{p} Move to the "previous" node of this node. % \var{u} Move "up" from this node. % \var{m} Pick menu item specified by name % Picking a menu item causes another node to be selected. % \var{d} Go to the Info directory node. % \var{f} Follow a cross reference. Reads name of reference. % \var{l} Move to the last node you were at. % \var{;} Move forward in the history stack % \var{i} Look up a topic in this file's Index and move to that node. % \var{,} Move to the next match from a previous `i' command. % \var{t} Go to the Top node of this file. % % Moving within a node: % \var{SPC} Normally, scroll forward a full screen. % When at the end of the node, the next scroll moves into its % first subnode. When after all menu items (or if there is no % menu), move up to the parent node. % \var{DEL} Scroll backward. % \var{b} Go to beginning of node. % % Advanced commands: % \var{1} Pick first item in node's menu. % \var{2} ... \var{9} Pick second ... ninth item in node's menu. % \var{g} Move to node specified by name. % You may include a filename as well, as (FILENAME)NODENAME. % \var{s} Search through this Info file for specified regexp, % and select the node in which the next occurrence is found. % \var{TAB} Move cursor to next cross-reference or menu item. % %\notes % To start JED as an info reader, type "jed -info \var{TOPIC}. JED will % look for info page \var{TOPIC}, if not found it will look for a man % page. Pressing \var{q} quits JED. % %\seealso{help_for_word_at_point, unix_man} %!%- private define start_info_reader () { variable ibuf = "*Info*"; if (bufferp(ibuf)) return sw2buf(ibuf); if (Info_Stack_Depth) pop_position (); ifnot (bufferp(ibuf)) find_dir(); sw2buf(ibuf); onewindow(); run_mode_hooks ("info_mode_hook"); set_buffer_hook("mouse_up", &mouse_hook); define_blocal_var("generating_function", ["info_reader"]); } %}}} define quit () { info_record_position(); widen(); delbuf("*Info*"); } define goto_node() { info_find_node (read_mini("Node:", Null_String, Null_String)); } %{{{ follow reference define info_looking_at (ref) { push_mark (); ref = strcompress(strlow(ref), " "); go_down_1(); eol(); exchange_point_and_mark(); not strncmp(strcompress(strlow(bufsubstr()), " \t\n"), ref, strlen(ref)); } define follow_reference () { variable ref; push_spot_bob(); ifnot (fsearch("*Note"), pop_spot()) throw RunTimeError, "No cross references."; ref = read_mini("Follow *Note", Null_String, Null_String); push_spot_bob (); forever { ifnot (fsearch("*Note")) { pop_spot(); throw RunTimeError, "Bad reference."; } go_right (5); skip_chars (" \t\n"); if (info_looking_at(ref)) break; } push_mark(); pop_spot(); %info_record_position pop_mark_1 (); follow_current_xref (); } %}}} %{{{ menu number define menu_number () { variable n = LAST_CHAR; if ((n < '1') || (n > '9')) return beep(); n -= '0'; info_find_menu(1); while (n) { ifnot (bol_fsearch("* ")) return beep(); if (ffind(":")) --n; else eol(); } bol(); follow_menu(); } %}}} %{{{ scrolling define up() { variable upnode = info_extract_pointer("Up"); if(upnode == NULL || upnode == "(dir)" || upnode == "Top") throw RunTimeError, "this is the end"; else info_find_node(upnode); } define next_up(); define next_up() { variable pointer; pointer = info_extract_pointer("Node"); if (string_match(info_extract_pointer("Node"), ".*Index$", 1)) { throw RunTimeError, "this is the end"; } pointer = info_extract_pointer("Next"); if (pointer == "Top") throw RunTimeError, "this is the end"; if (pointer == "") { up(); next_up(); } else info_find_node(pointer); } define forward_node() { . % indexes have a menu, we don't want to cycle forever . "Node" info_extract_pointer ".*Index$" 1 string_match . { "this is the end" message return } if . bob "^\\c\\* Menu:" re_fsearch . { next_up return } ifnot . eol "* " bol_fsearch pop . follow_menu } define scroll() { . what_line window_line - . push_spot eob . what_line 'r' window_info - < pop_spot . { "page_down" call return } if . forward_node } %}}} %}}} %{{{ info reader %Type jed -info SUBJECT to start jed as an info reader. public define info_reader () { variable file, node; start_info_reader (); if (_NARGS == 0) return; variable args = (); variable nargs = length (args); local_setkey ("exit_jed", "q"); local_setkey ("exit_jed", "Q"); if (nargs > 0) { file = args[0]; #ifdef UNIX if (path_basename (file) != file) { variable dir = path_dirname (file); file = path_basename (file); Info_Directory = strcat (dir, "," + Info_Directory); } #endif % Goto top incase the requested node does not exist. info_find_node (sprintf ("(%s)top", file)); if (nargs > 1) info_find_node (sprintf ("(%s)%s", file, args[1])); } } public define info_mode() { info_reader(); } %}}} jedmodes-2.5.7/vi/0000755000175400017500000000000010461125576012227 5ustar mildegmjedmodes-2.5.7/vi/vi.sl0000644000175400017500000004046710323470437013214 0ustar mildegm% vi.sl vi emulation mode % % Copyright (c) 2001 Kyle Wheeler % Released under the terms of the GNU General Public License (ver. 2 or later) % % USAGE % put in the jed library path and evaluate from your jed.rc (or .jedrc) Help_File = "vi.hlp"; _Jed_Emulation = "vi"; % While starting off in command mode is more vi-like, % because of the way JED does things, it's difficult to make perfect % emulation (specifically, you can type while in command mode). So, to % make it at least more logical, I have to have it start in INSERT mode. variable BEGIN_IN_COMMAND = 0; if (BEGIN_IN_COMMAND) set_status_line("(Jed %v) Vi: -COMMAND- : %b (%m%a%n%o) %p %t", 1); else set_status_line("(Jed %v) Vi: -INSERT- : %b (%m%a%n%o) %p %t", 1); % Global variables variable numbuf = 0; variable copylines = 0; variable commandbuf = ""; variable readonly = 0; variable last_search = ""; % Standard defines !if (is_defined ("Key_F1")) () = evalfile ("keydefs"); !if (is_defined ("mark_next_nchars")) () = evalfile ("search"); !if (is_defined ("full_kbd")) () = evalfile ("vimisc"); % For switching between the two modes if (BEGIN_IN_COMMAND) { com_to_edit_modeswitchers(&setkey, &unsetkey); } else { edit_to_com_modeswitchers(&setkey, &unsetkey); } % Prevent all the non-command keys in command mode if (BEGIN_IN_COMMAND) set_readonly(1); % The default binding for the quote keys (", ') is 'text_smart_quote'. % Most users do not seem to like this so it is unset here. setkey("self_insert_cmd", "\""); setkey("self_insert_cmd", "'"); if (BEGIN_IN_COMMAND) { full_commandset(&setkey); } else { full_kbd(&setkey, &unsetkey); setkey("newline_and_indent", "^M"); } % This is for folding mode (I'm making the keybindings up, but they seem ok) define fold_mode_hook () { local_setkey ("fold_whole_buffer", "w"); local_setkey ("fold_enter_fold", "^Fl"); local_setkey ("fold_exit_fold", "^Fj"); local_setkey ("fold_open_buffer", "^Fp"); local_setkey ("fold_fold_region", "^Fi"); local_setkey ("fold_open_fold", "^Fo"); local_setkey ("fold_close_fold", "^Fu"); local_setkey ("fold_search_forward", "^Fs"); local_setkey ("fold_search_backward", "^Fr"); } % On some systems, the default keybindings are a little insane. % Little? nay, VERY. This attempts to fix some of it. setkey("delete_char_cmd", Key_Del); setkey("backward_delete_char", Key_BS); setkey("beg_of_line", Key_Home); setkey("eol_cmd", Key_End); setkey("newline_and_indent", "^M"); setkey("newline", "\eOM"); setkey("sys_spawn_cmd", "^Z"); % Why is the number pad not implemented properly? setkey("insert(\".\")","\eOn"); setkey("insert(\"0\")","\eOp"); setkey("insert(\"1\")","\eOq"); setkey("insert(\"2\")","\eOr"); setkey("insert(\"3\")","\eOs"); setkey("insert(\"4\")","\eOt"); setkey("insert(\"5\")","\eOu"); setkey("insert(\"6\")","\eOv"); setkey("insert(\"7\")","\eOw"); setkey("insert(\"8\")","\eOx"); setkey("insert(\"9\")","\eOy"); setkey("insert(\"0\")","\eOz"); % These are the small functions associated with keydowns define vi_colon () { numbuf = 0; variable str = "", ch = ' ', force = 0, go = 0, temp = "", i = 0; message (commandbuf); % This little while loop, however, is 100% mine - faults and all while (go != 1) { vmessage (":%s", str); call ("redraw"); ch = getkey (); if (ch == '\r') go = 1; % There's gotta be an easier way than this to delete something else if (sprintf("%c", ch) == Key_BS) { if (strlen(str)) { temp = ""; for (i=0;i 4) { args = strchop(str, ';', '\\'); if (length(args) < 3 or length(args) > 4) { args = strchop(str, ':', '\\'); if (length(args) < 3 or length(args) > 4) { args = strchop(str, '*', '\\'); if (length(args) < 3 or length(args) > 4) { args = strchop(str, '%', '\\'); if (length(args) < 3 or length(args) > 4) { args = strchop(str, '@'); if (length(args) < 3 or length(args) > 4) { error("Malformed search/replace string."); return 1; } } } } } } if (length(args) > 3) { if (string_match(args[3], ".*g.*")) bob(); if (string_match(args[3], ".*c.*")) confirm = 1; } % vmessage ("here = %s", args[0]); % return 1; if (strcmp(args[0], "%s")) { error("That search form is not supported yet."); return 1; } variable replacements = 0, lines = 0, curline = 0, response = 0; while (found) { found = re_fsearch(args[1]); if (found) { if (curline != what_line()) { lines++; curline = what_line(); } if (confirm) { response = get_y_or_n ("Replace?"); if (response == -1) return 1; if (response == 1) { found = replace_match(args[2], 0); replacements ++; } } else { found = replace_match(args[2], 0); replacements++; } } } set_readonly(1); pop_spot(); if (replacements > 2) vmessage("%i substitutions on %i lines.", replacements, lines); } } % These are the functions associated with the number buffer define vi_kill_line () { variable here = what_line (), bot = 0; variable ch = getkey(); if (ch != '^' and ch != '$' and ch != 'w' and ch != 'd') return 1; if (ch == 'd') { bol (); push_mark (); if (numbuf > 0) down (numbuf - 1); eol (); } else if (ch == '^') { push_mark (); if (numbuf > 0) up (numbuf - 1); bol (); } else if (ch == '$') { push_mark (); if (numbuf > 0) down (numbuf - 1); eol (); } else if (ch == 'w') { push_mark (); if (numbuf == 0) numbuf = 1; for (;numbuf > 0; numbuf --) skip_word (); } else { return; } if (readonly == 0) set_readonly(0); check_region (1); bot = what_line(); yp_kill_region (); if (ch == '$' or ch == 'd') del (); if (here - bot > 0) numbuf = here - bot + 1; else numbuf = bot - here + 1; if (numbuf > 2) vmessage ("%i fewer lines.", numbuf); pop_mark(0); copylines = numbuf; numbuf = 0; set_readonly(1); } define vi_yank () { variable here = what_line (), bot = 0; variable ch = getkey(); if (ch != '^' and ch != '$' and ch != 'w' and ch != 'y') return 1; push_spot(); if (ch == 'y') { bol (); push_mark (); if (numbuf > 0) down (numbuf - 1); eol (); } else if (ch == '^') { push_mark (); if (numbuf > 0) up (numbuf - 1); bol (); } else if (ch == '$') { push_mark (); if (numbuf > 0) down (numbuf - 1); eol (); } else if (ch == 'w') { push_mark (); if (numbuf == 0) numbuf = 1; for (;numbuf > 0; numbuf --) skip_word(); } % check_region (1); bot = what_line(); yp_copy_region_as_kill (); if (bot - here > 0) numbuf = bot - here + 1; else numbuf = here - bot + 1; if (numbuf > 2) vmessage ("%i lines yanked.", numbuf); pop_mark(0); pop_spot(); % if (numbuf > 1) { % up (numbuf - 1); % bol(); % } copylines = numbuf; numbuf = 0; } define vi_push_line () { if (readonly == 0) set_readonly(0); eol (); insert ("\n"); yp_yank (); if (copylines > 2) vmessage ("%i more lines.", copylines); numbuf = 0; set_readonly(1); } define vi_push_line_before () { if (readonly == 0) set_readonly (0); bol (); yp_yank (); insert ("\n"); if (numbuf > 2) vmessage ("%i more lines.", copylines); numbuf = 0; set_readonly(1); } define vi_fwd_del () { if (readonly != 0) set_readonly(0); if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("delete_char_cmd"); set_readonly(1); } define vi_down_endline () { if (numbuf > 1) down (numbuf - 1); eol(); } define vi_down () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("next_line_cmd"); } define vi_up () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("previous_line_cmd"); } define vi_left () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("previous_char_cmd"); } define vi_right () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("next_char_cmd"); } define vi_bskip_word () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) bskip_word (); } define vi_skip_word () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) skip_word (); } define vi_forward_paragraph () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("forward_paragraph"); } define vi_backward_paragraph () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("backward_paragraph"); } define vi_page_down () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("page_down"); } define vi_page_up () { if (numbuf == 0) numbuf = 1; for (; numbuf > 0; numbuf --) call ("page_up"); } define vi_goto () { if (numbuf == 0) { eob(); return 1; } goto_line (numbuf); numbuf = 0; } % This is based on the search in search.sl define vi_search_across_lines (str, dir) { variable n, s, s1, fun, len; len = strlen (str); fun = &re_fsearch; if (dir < 1) fun = &re_bsearch; n = is_substr (str, "\n"); !if (n) { if (@fun (str)) return len; return -1; } s = substr (str, 1, n); s1 = substr (str, n + 1, strlen (str)); n = strlen(s); push_mark (); while (@fun(s)) { % we are matched at end of the line. go_right (n); if (looking_at(s1)) { go_left(n); pop_mark_0 (); return len; } if (dir < 0) go_left (n); } pop_mark_1 (); -1; } % This is based on the search in srchmisc.sl define vi_search_maybe_again (fun, str, match_ok_fun, stype) { variable ch, len, found = 1, mssg=0; if (stype != 0 and stype != 1) stype = 1; while (found > 0) { while (len = @fun(str, stype), len >= 0) { found = 3; if (@match_ok_fun ()) { if (EXECUTING_MACRO or DEFINING_MACRO) return 1; if (mssg == 0) message ("Press n or N to continue searching."); else mssg = 0; mark_next_nchars (len, -1); ch = getkey (); if (ch != 'n' and ch != 'N') { ungetkey (ch); return 1; } else if (ch == 'n') { stype = 1; } else stype = 0; } if (stype == 1) go_right_1 (); else go_left_1 (); } if (found == 2) found = 0; if (found == 1) found = 2; if (found > 1) { if (stype == 1) { bob (); message ("search hit BOTTOM, continuing at TOP"); } else { eob (); message ("search hit TOP, continuing at BOTTOM"); } mssg = 1; } } return 0; } define vi_simple_search (searchtype) { variable not_found = 1; if (searchtype != 0 and searchtype != 1) searchtype = 1; ERROR_BLOCK { pop_mark (not_found); } if (looking_at (last_search)) go_right_1 (); not_found = not (vi_search_maybe_again (&vi_search_across_lines, last_search, &_function_return_1, searchtype)); if (not_found) verror ("%s: not found.", last_search); EXECUTE_ERROR_BLOCK; } % I found some of this function in the jed documentation define vi_search (prompt, stype) { variable str = "", not_found = 1, ch = 0, go = 0, temp; if (stype != 1 and stype != 0) stype = 1; % This little while loop, however, is 100% mine - faults and all while (go != 1) { vmessage ("%s%s", prompt, str); call ("redraw"); ch = getkey (); if (ch == '\r') go = 1; % There's gotta be an easier way than this else if (sprintf("%c", ch) == Key_BS) { if (strlen(str)) { variable i = 0; temp = ""; for (;i|.|-}"); } numbuf = 0; } % This is not, technically, perfectly true to VI. I don't care. :-) define vi_c_search (prompt) { variable ch, ch2, str, ret; vmessage("%c",prompt); call ("redraw"); ch = getkey(); str = sprintf ("%c", ch); if (prompt == 'f' or prompt == 't') ch2 = '1'; else ch2 = '0'; if (ch == '\r' or str == Key_BS) return 1; else { do { if (ch2 == ',') { left(1); ret = bfind(str); } else if (ch2 == ';') { if (prompt == 't' or prompt == 'T') right(2); else right(1); ret = ffind(str); } else if (ch2 == '1') ret = ffind(str); else ret = bfind(str); if (ret == 0) { message("Not found."); return 1; } else { if (prompt == 't' or prompt == 'T') left(1); message("Press ';' (fwd) or ',' (bk) to continue searching."); } call ("redraw"); ch2 = getkey(); } while (ch2 == ',' or ch2 == ';'); ungetkey(ch2); } } define vi_join () { if (numbuf == 0) numbuf = 1; for(;numbuf>0;numbuf --) { eol(); call("next_char_cmd"); call("backward_delete_char"); } } jedmodes-2.5.7/vi/vimisc.sl0000664000175400017500000002362210214064507014060 0ustar mildegmdefine full_kbd (skey, uskey) { if (skey != &local_setkey and skey != &setkey) skey = &local_setkey; if (uskey != &local_unsetkey and uskey != &unsetkey) uskey = &local_unsetkey; @uskey("ZZ"); @uskey(">>"); @skey("self_insert_cmd", "I"); @skey("self_insert_cmd", "u"); @skey("self_insert_cmd", "C"); @skey("self_insert_cmd", "S"); @skey("self_insert_cmd", "i"); @skey("self_insert_cmd", "a"); @skey("self_insert_cmd", "A"); @skey("self_insert_cmd", "d"); @skey("self_insert_cmd", "D"); @skey("self_insert_cmd", "y"); @skey("self_insert_cmd", "Y"); @skey("self_insert_cmd", "O"); @skey("self_insert_cmd", "o"); @skey("self_insert_cmd", "e"); @skey("self_insert_cmd", "E"); @skey("self_insert_cmd", "$"); @skey("self_insert_cmd", "%"); @skey("self_insert_cmd", "h"); @skey("self_insert_cmd", "H"); @skey("self_insert_cmd", "l"); @skey("self_insert_cmd", "L"); @skey("self_insert_cmd", "f"); @skey("self_insert_cmd", "F"); @skey("self_insert_cmd", "t"); @skey("self_insert_cmd", "T"); @skey("self_insert_cmd", "M"); @skey("self_insert_cmd", "B"); @skey("self_insert_cmd", "j"); @skey("self_insert_cmd", "J"); @skey("self_insert_cmd", "k"); @skey("self_insert_cmd", "x"); @skey("self_insert_cmd", "X"); @skey("self_insert_cmd", "b"); @skey("self_insert_cmd", "/"); @skey("self_insert_cmd", "?"); @skey("self_insert_cmd", "w"); @skey("self_insert_cmd", "W"); @skey("self_insert_cmd", "z"); @skey("self_insert_cmd", "!"); if (is_defined("c_insert_ket")) { @skey("c_insert_ket", "}"); @skey("c_insert_bra", "{"); } else { @skey("self_insert_cmd", "}"); @skey("self_insert_cmd", "{"); } @skey("self_insert_cmd", "G"); @skey("self_insert_cmd", "n"); @skey("self_insert_cmd", "N"); if (is_defined("c_insert_colon")) @skey("c_insert_colon" , ":"); else @skey("self_insert_cmd", ":"); @skey("self_insert_cmd" , "^"); @skey("self_insert_cmd" , "+"); if (is_defined("tex_ldots")) @skey("tex_ldots","."); else @skey("self_insert_cmd" , "."); @skey("self_insert_cmd" , "-"); @skey("self_insert_cmd" , "_"); @skey("self_insert_cmd" , "|"); @uskey("ggvG"); @skey("message(\"JED does not support REPLACE mode\")", "\e[2~"); @skey("self_insert_cmd", "^R"); @skey("self_insert_cmd", "^L"); @skey("self_insert_cmd", "^G"); @skey("self_insert_cmd", "^B"); @skey("self_insert_cmd", "^D"); @skey("self_insert_cmd", "^E"); @skey("self_insert_cmd", "^Y"); @uskey("^Fb"); @uskey("^Ff"); @skey("self_insert_cmd", "^F"); @skey("self_insert_cmd", "^H"); @skey("self_insert_cmd", "^J"); @skey("self_insert_cmd", "^N"); @skey("self_insert_cmd", "^P"); @skey("self_insert_cmd", "^U"); @skey("newline", "^M"); @skey("self_insert_cmd", "1"); @skey("self_insert_cmd", "2"); @skey("self_insert_cmd", "3"); @skey("self_insert_cmd", "4"); @skey("self_insert_cmd", "5"); @skey("self_insert_cmd", "6"); @skey("self_insert_cmd", "7"); @skey("self_insert_cmd", "8"); @skey("self_insert_cmd", "9"); @skey("self_insert_cmd", "0"); @skey("self_insert_cmd", "p"); @skey("self_insert_cmd", "P"); @skey("next_line_cmd", Key_Down); @skey("previous_line_cmd", Key_Up); @skey("next_char_cmd", Key_Right); @skey("previous_char_cmd", Key_Left); @skey("page_down", Key_PgDn); @skey("page_up", Key_PgUp); if (is_defined("tex_insert_quote")) { @skey("tex_insert_quote" , "\""); @skey("tex_insert_quote", "'"); } else { @skey("self_insert_cmd", "'"); @skey("self_insert_cmd", "\""); } % On some systems, the default keybindings are a little insane, % so this fixes some of it. @skey("newline_and_indent", "^M"); % Until I figure out a way to let me intercept pure ESC hits, I have % to emulate it with the ` key - which means I can't insert it. So, % this is a stopgap measure. (I can't just undefine all other command % sequences that begin with ESC, because that involves a lot of the % menu commands (mousedown, that kind of thing). @skey("quoted_insert", "\e`"); } define full_commandset (skey) { if (skey != &local_setkey and skey != &setkey) skey = &local_setkey; @skey("eol_cmd", "C"); @skey("vi_down_endline", "$"); @skey("vi_match()", "%"); @skey("skip_white()", "^"); @skey("down(1); bol(); skip_white()", "+"); @skey("up(1); bol(); skip_white()", "-"); @skey("bol(); skip_white()", "_"); @skey("goto_top_of_window(); bol(); skip_white()", "H"); @skey("goto_bottom_of_window(); bol(); skip_white()", "L"); @skey("vi_goto_middle_of_window ();skip_white()", "M"); @skey("redraw", "^L"); % These are the basic editing commands in vi that % cannot happen multiple times @skey("if (readonly == 0) set_readonly(0); call(\"undo\"); set_readonly(1)", "u"); @skey("message(\"JED does not support the REDO feature.\")", "^R"); @skey("bob(); push_mark(); eob();", "ggvG"); @skey("whatpos", "^G"); @skey("vi_simple_search(1)", "n"); @skey("vi_simple_search(0)", "N"); @skey("indent_line", ">>"); @skey("if (readonly == 0) set_readonly(0); call(\"kill_line\"); set_readonly(1)", "D"); @skey("if (readonly == 0) set_readonly(0); call(\"backward_delete_char\"); set_readonly(1)", "X"); @skey("bol();push_mark();eol();yp_copy_region_as_kill();pop_mark(0);copylines=1", "Y"); @skey("vi_colon", ":"); @skey("vi_redraw", "z"); % These are the basic file manipulation commands % and cannot happen multiple times @skey("save_buffer; exit_jed", "ZZ"); % These modify the number buffer for commands @skey("numbuf = (numbuf * 10) + 1", "1"); @skey("numbuf = (numbuf * 10) + 2", "2"); @skey("numbuf = (numbuf * 10) + 3", "3"); @skey("numbuf = (numbuf * 10) + 4", "4"); @skey("numbuf = (numbuf * 10) + 5", "5"); @skey("numbuf = (numbuf * 10) + 6", "6"); @skey("numbuf = (numbuf * 10) + 7", "7"); @skey("numbuf = (numbuf * 10) + 8", "8"); @skey("numbuf = (numbuf * 10) + 9", "9"); % I'm not including the "move to first column" part of 0 for simplicity % There's more than enough ways to do that, and it's complicated % to implement. If anyone complains, I may change my mind, but... @skey("numbuf = (numbuf * 10)", "0"); % These are commands that can be executed multiple times, or % are affected in some other way by the number buffer @skey("vi_kill_line", "d"); @skey("vi_yank", "y"); @skey("vi_push_line", "p"); @skey("vi_push_line_before", "P"); @skey("vi_goto_column", "|"); @skey("vi_up", Key_Up); @skey("previous_line_cmd", "k"); @skey("vi_up", "^P"); @skey("vi_down", Key_Down); @skey("next_line_cmd", "j"); @skey("vi_down", "^J"); @skey("vi_down", "^N"); @skey("down(1);bol()", "^M"); @skey("vi_left", Key_Left); @skey("previous_char_cmd", "h"); @skey("vi_left", "^H"); @skey("vi_right", Key_Right); @skey("next_char_cmd", "l"); @skey("vi_page_down", Key_PgDn); @skey("vi_page_down", "^F"); @skey("vi_scroll_half_fwd", "^D"); @skey("vi_page_up", Key_PgUp); @skey("vi_page_up", "^B"); @skey("vi_scroll_half_bck", "^U"); @skey("vi_search (\"/\", 1)", "/"); @skey("vi_search (\"?\", 0)", "?"); @skey("vi_c_search ('f')", "f"); @skey("vi_c_search ('F')", "F"); @skey("vi_c_search ('t')", "t"); @skey("vi_c_search ('T')", "T"); @skey("vi_bskip_word", "b"); @skey("vi_bskip_word", "B"); % This isn't precisely correct, but there is no Jed equivalent. @skey("vi_skip_word", "w"); @skey("vi_skip_word", "W"); % This isn't precisely correct @skey("vi_skip_word", "E"); % This isn't precisely correct either, but hey. @skey("vi_skip_word", "e"); % neither is this % I'm not implementing ( and ) because there's not Jed equivalent, % and it's a lot of work. @skey("vi_forward_paragraph", "}"); @skey("vi_backward_paragraph", "{"); @skey("vi_goto", "G"); @skey("message(\"Filtering regions through external commands not yet supported.\")", "!"); @skey("vi_fwd_del", "x"); @skey("vi_scroll_fwd", "^E"); @skey("vi_scroll_bck", "^Y"); @skey("vi_join", "J"); @skey("message(\"Keeping track of which commands modify the buffer is not supported.\")", "."); } define com_to_edit_modeswitchers (skey, uskey) { if (skey != &local_setkey and skey != &setkey) skey = &local_setkey; if (uskey != &local_unsetkey and uskey != &unsetkey) uskey = &local_unsetkey; @skey("edit_mode()", "i"); @skey("edit_mode()", "S"); @skey("edit_mode()", "\e[2~"); @skey("next_char_cmd; edit_mode())", "a"); @skey("bol(); edit_mode()", "I"); @skey("eol(); edit_mode()", "A"); @skey("bol();insert(\"\n\");up(1);edit_mode()", "O"); @skey("eol();insert(\"\n\");edit_mode()", "o"); @skey("quoted_insert", "`"); } define edit_to_com_modeswitchers (skey, uskey) { if (skey != &local_setkey and skey != &setkey) skey = &local_setkey; if (uskey != &local_unsetkey and uskey != &unsetkey) uskey = &local_unsetkey; @skey("command_mode()", "`"); @skey("self_insert_cmd", "i"); } define command_mode () { set_status_line("(Jed %v) Vi: -COMMAND- : %b (%m%a%n%o) %p %t", 1); % For switching between the two modes com_to_edit_modeswitchers(&local_setkey, &local_unsetkey); % Re-initialize the global variables numbuf = 0; commandbuf = ""; readonly = is_readonly(); % Lock it down to prevent keys that aren't commands set_readonly(1); % And pull up the command keys... full_commandset(&local_setkey); } define edit_mode () { set_status_line("(Jed %v) Vi: -INSERT- : %b (%m%a%n%o) %p %t", 1); % For switching between the two modes edit_to_com_modeswitchers(&local_setkey, &local_unsetkey); % Get the full keyboard full_kbd (&local_setkey, &local_unsetkey); local_setkey("newline_and_indent", "^M"); % If the file is supposed to be readonly, let's not unset that - but % if it's ok to be written to, unlock it if (readonly == 0) { set_readonly(0); } } jedmodes-2.5.7/vi/vi.hlp0000664000175400017500000000024510214064506013344 0ustar mildegmJED Vi keybindings: `^' means to use Ctrl key (e.g., ^X = Ctrl-X). :q exit u Undo :w write to file ^L redraw dd delete :e open a file ^E end of line jedmodes-2.5.7/make_ini/0000755000175400017500000000000011007614547013363 5ustar mildegmjedmodes-2.5.7/make_ini/make_ini.sl0000644000175400017500000005250111007614547015502 0ustar mildegm% make_ini.sl: functions to set up extensions (modes and tools) for Jed. % % Copyright (c) 2003, 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Usage % ===== % % M-x make_ini create a buffer with the autoload commands (and helpfull % comments) for viewing/editing and subsequent saving % M-x update_ini update the ini.sl file in the current buffers working % dir without user interaction % % Versions % ======== % 0.9 initial release % 1.0 non-interactive functions and support for batch use % 1.1 08/07/03 made compatible to txtutils 2.2 (change in get_word) % 1.2 only write _autoload statements, do not add_completion % 1.3 * make_ini_look_for_functions made public: % add autoloads for specified file (request P. Boekholt) % * parse the files in a special buffer (avoiding mode-sets % and problems with currently open files) % 2004-03-08 2.0 * added support for documentation extraction with tm.sl % * make_ini no longer bytecompiles (use update_ini for that) % 2004-06-10 2.1 * fixed a bug that prevented bytecompiling % * added tm documentation for public functions and variables % * provisions for a section with custom code in ini.sl % 2004-11-26 2.2 * code cleanup (hopefully without introducing bugs) % * look for a block % Use this for custom initialization code (menu addings, etc) % If such a block is found, no search for functions is done! % 2005-03-18 2.3 * bugfixes: list_slang_files() did only work, if % dir == current working dir (report Dino Sangoi) % "%" in vinsert needs to be doubled (Dino Sangoi) % documentation comments did not work % removed the need for a chdir() alltogether % 2005-03-31 2.4 * windows bugfix: quote backslashes in add_autoload_fun() (Dino) % * bugfix in list_slang_files(): skip jed lock files % 2005-04-01 2.5 * cleanup in make_ini_look_for_functions(): do not insert % library path in autoload commands % 2005-04-07 2.6 * provide add_completion commands (with Make_ini_Add_Completions) % 2005-04-25 2.7 * bugfix: list_slang_files() failed for directories without % slang files or nonexisting directories. % make_libfun_doc() failed if there was no documentation % * Test for existing tm.sl with #ifexists: % the function tm_parse() must be defined/declared at % evaluation/preparse time of make_ini.sl in order to enable % the documentation extract feature. % 2005-05-25 2.7.1 * bugfix: andelse -> orelse (report Paul Boekholt) % 2005-07-04 2.8 * separated function byte_compile_library() % 2005-07-04 2.8.1 * renamed byte_compile_library() to byte_compile_libdir % 2005-07-11 2.8.2 * bugfix in make_ini_look_for_functions(), strip trailing % slash from libdir name. % 2005-07-15 2.8.3 * critical bugfix-fix: make_ini_look_for_functions(): use % path_concat(dir, "") to normalize the dir-path. % 2005-07-22 2.9 * adapted to home-lib 1.1 % (removed reference to Jed_Home_Library and Jed_Site_Library) % 2005-07-30 2.9.1 bugfix in update_ini() % 2005-11-02 2.9.2 * adapted to libdir 0.9.1 (removed update_site_lib()) % * new custom variable Make_ini_Bytecompile_Exclusion_List % 2005-11-14 2.9.3 * added missing autoload for buffer_dirname() % 2005-11-18 2.9.4 * removed the if(BATCH) clause as it does not work as expected % and prevents the use from another script with jed-script % 2005-11-22 2.9.5 * code cleanup % 2006-01-10 2.9.6 * documentation cleanup % 2006-03-15 2.10 * tighten the rules for block: now it must % be a preprocessor cmd ("#" at bol) % 2006-05-31 2.11 * added missing break in make_ini_look_for_functions() % * missing end tag of INITIALIZATION block triggers error % * update_ini(): evaluate new ini.sl (test, add autoloads) % 2007-10-01 2.11.1 * optional extensions with #if ( ) % 2007-10-23 2.12 * documentation update % * create DFA cache files % 2008-05-05 2.13 * code cleanup, documentation update % TODO: * Consider preprocessor options (How?) autoload("get_word", "txtutils"); autoload("push_array", "sl_utils"); autoload("buffer_dirname", "bufutils"); provide("make_ini"); % Customisation % ============= %!%+ %\variable{Make_ini_Scope} %\synopsis{Scope for automatic generation of autoload commands} %\usage{Int_Type Make_ini_Scope = 1} %\description % Set the scope for automatic generation of \sfun{autoload} commands % 0 no autoloads % 1 only explicitly public definitions: bol_fsearch("public define ") % 2 all global definitions %\seealso{make_ini, make_ini_look_for_functions} %!%- custom_variable("Make_ini_Scope", 1); %!%+ %\variable{Make_ini_Verbose} %\synopsis{Comment the ini-file} %\usage{Int_Type Make_ini_Verbose = 1} %\description % Comment the ini.sl file generated by make_ini(). % n == 0: no comments % n > 0: n lines of global comments + list of custom variables %\seealso{make_ini} %!%- custom_variable("Make_ini_Verbose", 0); %!%+ %\variable{Make_ini_Bytecompile} %\synopsis{Bytecompile the files with update_ini()} %\usage{Int_Type Make_ini_Bytecompile = 1} %\description % Let \sfun{update_ini} and \sfun{update_home_lib} bytecompile % the files as well. % This gives considerable evalutation speedup but might introduce problems. %\notes % Attention: byte-compiling can give problems % * with constructs like #ifdef XWINDOWS % when xjed and jed are used in parallel % * with constructs like % #ifndefined my_new_function() % define my_new_function() % { ... } % #endif %\seealso{update_ini, update_home_lib} %!%- custom_variable("Make_ini_Bytecompile", 1); %!%+ %\variable{Make_ini_Exclusion_List} %\synopsis{Array of files to exclude from make_ini()} %\usage{String_Type[] Make_ini_Exclusion_List = ["ini.sl"]} %\description % Exclusion list: do not scan these files. %\seealso{make_ini, update_ini, Make_ini_Bytecompile_Exclusion_List} %!%- custom_variable("Make_ini_Exclusion_List", ["ini.sl"]); %!%+ %\variable{Make_ini_Bytecompile_Exclusion_List} %\synopsis{Array of files to exclude from bytecompiling} %\usage{Int_Type Make_ini_Bytecompile_Exclusion_List = []} %\description % Exlude these files from bytecompiling with \sfun{byte_compile_libdir}, % \sfun{update_ini}, and \sfun{update_home_lib}. %\seealso{Make_ini_Exclusion_List} %!%- custom_variable("Make_ini_Bytecompile_Exclusion_List", String_Type[0]); %!%+ %\variable{Make_ini_DFA_Exclusion_List} %\synopsis{Array of files to exclude from DFA caching} %\usage{Int_Type Make_ini_DFA_Exclusion_List = []} %\description % Exlude these files from DFA highlight cache creation with % \sfun{update_dfa_cache_files}, \sfun{ \sfun{update_ini}, % and \sfun{update_home_lib}. %\seealso{Make_ini_Exclusion_List} %!%- custom_variable("Make_ini_DFA_Exclusion_List", String_Type[0]); %!%+ %\variable{Make_ini_Extract_Documentation} %\synopsis{Extract documentation with update_ini} %\usage{Int_Type Make_ini_Extract_Documentation = 1} %\description % Let update_ini() also extract documentation and save in libfuns.txt file. %\notes % Documentation extraction requires tm_parse() from the tm.sl mode. % If tm_parse() is not defined at evaluation (or byt-compile) time of % make_ini.sl, Make_ini_Extract_Documentation will be set to 0. %\seealso{update_ini, tm_parse, tm_view} %!%- custom_variable("Make_ini_Extract_Documentation", 1); !if (is_defined("tm_parse")) Make_ini_Extract_Documentation = 0; %!%+ %\variable{Make_ini_Add_Completions} %\synopsis{Insert add_completion commands into ini.sl} %\usage{Int_Type Make_ini_Add_Completions = 1} %\description % Should \sfun{make_ini} insert \sfun{add_completion} commands into ini.sl? % 0 no % 1 only explicitly public definitions % 2 all global definitions %\seealso{Make_ini_Scope, Make_ini_Extract_Documentation, Make_ini_Verbose} %!%- custom_variable("Make_ini_Add_Completions", 1); % Internal Variables % ================== % valid chars in function and variable definitions static variable Slang_word = "A-Za-z0-9_"; static variable Ini_File = "ini.sl"; private variable Parsing_Buffer = "*make_ini tmp*"; static variable Tm_Doc_File = "libfuns.txt"; % Functions % ========= static define _get_function_name() { variable str, fun; !if (ffind("define")) return ""; skip_word(); return get_word(Slang_word, 1); % (Slang_word, skip=True) } %!%+ %\function{make_ini_look_for_functions} %\synopsis{Insert initialisation code for a slang file} %\usage{Str = make_ini_look_for_functions(file)} %\description % Browse file and insert % either the # # block % or autoload commands for function definitions % in the current buffer. The variables \var{Make_ini_Scope} and % \var{Make_ini_Add_Completions} can be used to control which function % definitions are handled %\notes % If there is an INITIALIZATION block, no automatic search for function % definitions is done. You must explicitely list the required autoload() % commands! (This way, people not using make_ini can copy the content of the % INITIALIZATION block directly to their .jedrc file. % % The preprocessor directives %#v+ % # % ... initialisation block ... % # %#v- % will hide the initialisation block from normal slang processing/preparsing % (see slang documentation file "preprocess.txt"). %\seealso{make_ini, update_ini, Make_ini_Scope,} %!%- define make_ini_look_for_functions(file) { variable str = "", public_funs = "", simple_funs = "", funs, funs_n_files, named_namespace = 0, currbuf = whatbuf(); % show("processing", whatbuf(), file); % Parse the file in a temp buffer, without setting the mode % (saves time and does not interfere with open files) sw2buf(Parsing_Buffer); erase_buffer(); % paranoia () = insert_file(file); set_buffer_modified_flag(0); % if `file' is in the jed library path, remove the library-path from it: variable dir, libdirs = strchop(get_jed_library_path, ',' , 0); libdirs = libdirs[where(libdirs != ".")]; % filter the current dir foreach dir (libdirs) { dir = path_concat(dir, ""); % ensure trailing path-separator if (is_substr(file, dir) == 1) { file = file[[strlen(dir):]]; break; } } % global comment bob(); loop(Make_ini_Verbose) % max as many lines as Make_ini_Verbose indicates { !if (looking_at("%")) break; push_mark(); go_down_1(); str += bufsubstr(); } % list custom variables (assuming the definition starts at bol) if (Make_ini_Verbose) while (bol_fsearch("custom_variable")) { push_mark_eol(); str += "% " + bufsubstr() + "\n"; } % find out if the mode defines/uses a namespace bob(); if (orelse{bol_fsearch("implements")} {bol_fsearch("_implements")} {bol_fsearch("use_namespace")}) { named_namespace = 1; str += "% private namespace: " + line_as_string + "\n"; } % Look for an # block bob(); if (bol_fsearch("#")) { go_down_1(); bol(); push_mark(); !if (bol_fsearch("#")) { pop_mark(0); error("no end tag in " + file); } str += bufsubstr(); } else { % Search function definitions % 1. explicitly public definitions while (bol_fsearch("public define ")) public_funs += _get_function_name() + "\n"; bob; % 2. "simple" (i.e. unspecified) definitions !if (named_namespace) while (bol_fsearch("define ")) simple_funs += _get_function_name() + "\n"; % autoloads switch (Make_ini_Scope) { case 0: funs = String_Type[0]; } { case 1: funs = strtok(public_funs, "\n"); } { case 2: funs = strtok(public_funs+simple_funs, "\n"); } if (length(funs)) { funs = "\"" + funs + "\""; funs_n_files = funs + sprintf(", \"%s\";", str_quote_string(file, "", '\\')); str += strjoin(funs_n_files, "\n") + "\n" + sprintf("_autoload(%d);\n", length(funs)); } % add_completions switch (Make_ini_Add_Completions) { case 0: funs = String_Type[0]; } { case 1: funs = strtok(public_funs, "\n"); } { case 2: funs = strtok(public_funs+simple_funs, "\n"); } if (length(funs)) { funs = "\"" + funs + "\";"; str += "\n" + strjoin(funs, "\n") + "\n" + sprintf("_add_completion(%d);\n", length(funs)); } } % cleanup delbuf(Parsing_Buffer); sw2buf(currbuf); insert(str); } % Return sorted array of full path names of all *.sl files in dir static define list_slang_files(dir) { variable files = listdir(dir); if (files == NULL or length(files) == 0) return String_Type[0]; % Skip files that are no slang-source (test for extension ".sl") files = files[where(array_map(String_Type, &path_extname, files) == ".sl")]; !if (length(files)) return String_Type[0]; % Skip jed lock files files = files[where(array_map(Integer_Type, &is_substr, files, ".#") != 1)]; !if (length(files)) return String_Type[0]; % Prepend the directory to the path files = array_map(String_Type, &path_concat, dir, files); % Sort alphabetically and return return files[array_sort(files)]; } %!%+ %\function{make_ini} %\synopsis{} %\usage{make_ini([dir])} %\description % Scan all slang files in \var{dir} for function definitions and % place autoload commands in a buffer ini.sl. % After customizing, it can be saved and serve as an initialization % for a slang-library. The libdir mode at jedmodes.sf.net will % automatically evaluate this ini.sl files at startup, making the % installation of additional modes easy. %\seealso{update_ini, Make_ini_Scope, Make_ini_Exclusion_List, Make_ini_Verbose} %!%- public define make_ini() % ([dir]) { % optional argument !if (_NARGS) read_file_from_mini("Make ini.sl for:"); variable dir = (); variable files = list_slang_files(dir), file; % find old ini file () = find_file(path_concat(dir, Ini_File)); slang_mode(); bob(); % skip customized part, write header !if (bol_fsearch("% [code below will be replaced")) vinsert("%% ini.sl: initialization file for the library dir %s\n" + "%% automatically generated by make_ini()\n\n" + "%% --- Place customized code above this line ---\n" + "%% [code below will be replaced by the next run of make_ini()]\n" , dir); % blank rest of buffer go_down_1; bol(); push_mark_eob(); del_region(); foreach file (files) { % show(file, file_type(file), file_status(file)); % Skip files from the exclusion list if (length(where(path_basename(file) == Make_ini_Exclusion_List))) continue; insert("\n% " + path_basename(file) + "\n"); make_ini_look_for_functions(file); } } %!%+ %\function{byte_compile_libdir} %\synopsis{Byte compile all *.sl files in a directory} %\usage{ byte_compile_libdir(dir)} %\description % Call \sfun{byte_compile_file} on all files returned by % \sfun{list_slang_files}(dir). %\seealso{byte_compile_file, update_home_lib, Make_ini_Bytecompile_Exclusion_List} %!%- define byte_compile_libdir(dir) { variable file, files = list_slang_files(dir); foreach file (files) { % Skip files from the exclusion list if (length(where(path_basename(file) == Make_ini_Bytecompile_Exclusion_List))) continue; byte_compile_file(file, 0); } } % Online Documentation % ==================== #ifexists tm_parse %!%+ %\function{make_libfun_doc} %\synopsis{Write tm documentation in dir to "libfuns.txt"} %\usage{ make_libfun_doc([dir])} %\description % Extract tm documentation for all Slang files in \var{dir}, % convert to ascii format and write to file "libfuns.txt". %\notes % requires tm.sl (jedmodes.sf.net/mode/tm/) %\seealso{tm_parse, update_ini, Make_ini_Extract_Documentation} %!%- public define make_libfun_doc() % ([dir]) { !if (_NARGS) read_file_from_mini("Extract tm Documentation from dir:"); variable dir = (); % extract tm documentation blocks variable docstrings, str, files=list_slang_files(dir); !if (length(files)) return vmessage("no slang files in %s", dir); docstrings = array_map(String_Type, &tm_parse, files); str = strjoin(docstrings, ""); if (str == "") return vmessage("no tm documentation in %s", dir); () = write_string_to_file(str, path_concat(dir, Tm_Doc_File)); } #endif % DFA syntax highlight cache files % ================================ #ifdef HAS_DFA_SYNTAX % create a DFA cache file for `file` % % The cache file is removed from Jed_Highlight_Cache_Dir and re-created % if no matching cache file is found in the Jed_Highlight_Cache_Path %\seealso{update_dfa_cache_files} define make_dfa_cache_file(file) { variable buf = whatbuf(); sw2buf(Parsing_Buffer); EXIT_BLOCK { set_buffer_modified_flag(0); delbuf(Parsing_Buffer); sw2buf(buf); } % load relevant part of a file into parsing buffer erase_buffer(); % paranoia if (0 >= insert_file_region(file, "%%% DFA_CACHE_BEGIN %%%", "%%% DFA_CACHE_END %%%")) { % show(file," not found or no '%%% DFA_CACHE' section"); return; } % Remove and re-create the cache file bob (); !if (re_fsearch ("[ \t]*dfa_enable_highlight_cache[ \t]*([ \t]*\"\\(.+\\)\"")) { % vshow("did not find DFA cache file in %s", file); return; } variable cache_file = dircat(Jed_Highlight_Cache_Dir, regexp_nth_match(1)); % show("Cache file", cache_file); if (file_status(cache_file) == 1) () = remove(cache_file); % Check whether dfa cache is enabled and get the name of the dfa table eob (); !if (re_bsearch ("[ \t]*dfa_set_init_callback[ \t]*([ \t]*&[ \t]*\\([^,]+\\),[ \t]*\\(.+\\))")) { % show("no matching callback set in ", file); return; } variable line = regexp_nth_match(0); variable fun = regexp_nth_match (1); variable mode = regexp_nth_match (2); if (mode == strtrim(mode, "\"")) { vmessage("%s: dfa caching needs string-literal in %s", path_basename(file), line); return; } % Replace the setting of the callback function with a call to it: delete_line(); vinsert("create_syntax_table(%s);\n", mode); vinsert("%s(%s);", fun, mode); % (Re)-create the cache file if (file_status(cache_file) == 1) () = remove(cache_file); evalbuffer (); } % Remove *.dfa files in `dir' and re-create them. define update_dfa_cache_files() % ([dir]) { % optional argument !if (_NARGS) read_file_from_mini("Make|Update DFA cache files in:"); variable dir = (); variable file, files = list_slang_files(dir); % Restrict updating to `dir' variable cache_dir = Jed_Highlight_Cache_Dir; variable cache_path = Jed_Highlight_Cache_Path; Jed_Highlight_Cache_Dir = dir; Jed_Highlight_Cache_Path = dir; foreach file (files) { % Skip files from the exclusion list if (length(where(path_basename(file) == Make_ini_DFA_Exclusion_List))) continue; make_dfa_cache_file(file); } % restore settings Jed_Highlight_Cache_Dir = cache_dir; Jed_Highlight_Cache_Path = cache_path; } #endif % Update initialization files % =========================== % Front-end functions for ini.sl generation, byte-compiling, % and documentation extraction % % DFA cache generation is left out, as it ist susceptible to faults % Use update_dfa_cache_files([dir]) if you think it is sure. %!%+ %\function{update_ini} %\synopsis{Update the ini.sl initialization file} %\usage{update_ini(directory=buffer_dir())} %\description % Create or update the ini.sl initialization file with \sfun{make_ini}. % Bytecompile the files with \sfun{byte_compile_libdir}. % Extract online help text (tm documentation) with \sfun{make_libfun_doc}. % % Customise behaviour with the the Make_ini_* custom variables % (hint: try Help>Apropos Make_ini). %\seealso{update_home_lib} %!%- public define update_ini() % (directory=buffer_dirname()) { variable dir, buf = whatbuf(); if (_NARGS) dir = (); else dir = buffer_dirname(); % default !if (length(list_slang_files(dir))) return vmessage("no SLang files in %s", dir); make_ini(dir); save_buffer(); % evaluate to test and add new autoloads evalbuffer(); delbuf(whatbuf()); % bytecompile (the ini-file as well) if(Make_ini_Bytecompile) { flush("byte compiling files in " + dir); byte_compile_libdir(dir); } #ifexists tm_parse % extract the documentation and put in file libfuns.txt if(Make_ini_Extract_Documentation) { flush("extracting on-line documentation in " + dir); make_libfun_doc(dir); } #endif sw2buf(buf); % message("update_ini completed"); } #ifexists Jed_Home_Directory %!%+ %\function{update_home_lib} %\synopsis{update Jed_Home_Directory/lib/ini.sl} %\usage{update_home_lib()} %\description % Run \sfun{update_ini} for the users "Jed library dir" %\seealso{update_ini, make_ini, Jed_Home_Directory} %!%- public define update_home_lib() { update_ini(path_concat(Jed_Home_Directory, "lib")); message("done"); } #endif jedmodes-2.5.7/diagnose/0000755000175400017500000000000011146315245013375 5ustar mildegmjedmodes-2.5.7/diagnose/diagnose.sl0000644000175400017500000002200511146315245015525 0ustar mildegm% Diagnostic functions for SLang programmers % show the value of variables (nice for debugging) % % Copyright © 2006 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 1.0 2003-07-09 * first public version % Version 1.1 2005-03-21 * added tm documentation to public functions autoload("popup_buffer", "bufutils"); autoload("fit_window", "bufutils"); autoload("view_mode", "view"); require("sprint_var"); %!%+ %\variable{Diagnose_Buffer} %\synopsis{Name of the buffer used by show() and related diagnostic functions} %\description % The show* diagnostic functions show their output in a special popup % buffer. Diagnose_Buffer sets the name of this buffer (defaulting to % "*debug*"). %\seealso{show_string, show, vshow, show_object, show_stack, show_eval} %!%- custom_variable("Diagnose_Buffer", "*debug*"); % popup the diagnose buffer with n lines / using n+100 percent of space % (set to 0 for don't fit) custom_variable("Diagnose_Popup", 0.3); %!%+ %\function{show_string} %\synopsis{Insert the argument at the end of the Diagnose_Buffer} %\usage{show_string(Str str)} %\description % Open a popup buffer and insert \var{str}. %\seealso{pop2buf, show, Diagnose_Buffer} %!%- public define show_string(str) { variable calling_buf = whatbuf(); popup_buffer(Diagnose_Buffer, Diagnose_Popup); set_readonly(0); eob; insert(strcat("\n", str, "\n")); set_buffer_modified_flag (0); view_mode(); fit_window(get_blocal_var("is_popup")); pop2buf(calling_buf); } %!%+ %\function{sprint_args} %\synopsis{Return a formatted string of the argument list} %\usage{Str sprint_args(args)} %\description % Take a variable number of arguments, convert to a strings with % \sfun{sprint_variable()} and return the concatenated strings. %\seealso{show, mshow} %!%- public define sprint_args() % args { variable arg, n=_NARGS, sep=" ", strarray = String_Type[n]; loop(n) { n--; arg = sprint_variable(()); % convert to a string if(is_substr(arg, "\n")) sep = "\n"; strarray[n] = arg; } return strjoin(strarray, sep) + sep; } %!%+ %\function{show} %\synopsis{Show the content of the argument list in the \var{Diagnose_Buffer}.} %\usage{show(args)} %\description % Take a variable number of arguments, convert to strings with % sprint_variable() and show in the \var{Diagnose_Buffer}. %\example %#v+ % show(TAB, [1, 2, 3, 4]) %#v- %\notes % This is my basic debugging tool. show_object() shows even more info, % but in most cases show() will suffice. % % Using sprint_variable() instead of string for the "anything -> string" % conversion results in the verbose representation of composite variables % (arrays, associative-arrays, etc). % %\seealso{show_string, vshow, mshow, show_object, show_stack, show_eval} %!%- public define show() % args { variable args = __pop_args(_NARGS); show_string(sprint_args(__push_args(args))); } %!%+ %\function{vshow} %\synopsis{Show a sprintf style argument list in the diagnose buffer} %\usage{vshow(args)} %\description % Convert the argument list to a string using sprintf() and show it % in the \var{Diagnose_Buffer} using show_string(). %\seealso{sprintf, vmessage, verror, show_string} %!%- public define vshow() % args { variable args = __pop_args(_NARGS); show_string(sprintf(__push_args(args))); } %!%+ %\function{mshow} %\synopsis{Show the content of the argument list in the minibuffer} %\usage{mshow(args)} %\description % Convert the arguments to a string with sprint_args() and % show as message in the minibuffer. %\notes % For output that spans several lines and for a more permanent record use % show() instead of mshow() %\seealso{show, sprint_args, message} %!%- public define mshow() % args { variable args = __pop_args(_NARGS); message(sprint_args(__push_args(args))); } public define show_in_scratch() % args { variable args = __pop_args(_NARGS); variable buf = whatbuf(); sw2buf("*scratch*"); insert(sprint_args(__push_args(args))); sw2buf(buf); } %!%+ %\function{show_object} %\synopsis{put debug information in a debug buffer } %\usage{Void show_object (String item [, String hint]);} %\usage{Void show_object (Ref_Type item [, String hint]);} %\description % Inserts the actual value of item (or "not defined") into a diagnose buffer. % An optional argument hint is appended to the output. % The hint string may contain valid sprint format specifiers % (like %s) with the appropriate variables as additional arguments. % If the first argument is "", only the hint is written. %\example % For example % variable CA; % variable CU = "kuckuck"; % show_object ("CA"); % show_object ("cu"); % show_object ("CU", "a hint"); % show_object ("", "I'm here at %s", time ()); % show_object ("foo"); % show_object ("bol"); % show_object ("center_line"); % result in the following diagnose buffer % CA: not initialized % cu: not defined % CU == kuckuck % a hint % % I'm here at 07:21 % foo: user defined function % bol: intrinsic function % center_line: internal function % TODO: Currently only globally defined variables and functions are detected % if given as strings. Use the second format with reference (pointer) % for static variables or functions and function-local variables. % blocal variables need to be given as strings. % %\seealso{show, vshow} %!%- public define show_object() % (object, [hint= ""]) { % get arguments variable hint = ""; % optional second argument variable object; % name of object to output info about if (_NARGS > 1) { variable args = __pop_args(_NARGS-1); hint = sprintf (__push_args(args)); } object = (); % take 1st arg from stack (might be String or Reference) variable ref = NULL; % reference to object variable str = ""; % output string variable value = " "; % variable value EXIT_BLOCK { if (hint != "") str += "\t% " + hint; show_string(str); } % Get String_Type object and Ref_Type ref if (typeof(object) == Ref_Type) % Reference given, convert to a string { ref = object; object = string(object)[[1:]]; % without leading '&' if (object == "ocal Variable Reference") % for local Variables object = "Local variable "; } else % object is already a string { object = string(object); ref = __get_reference(object); } % determine type of object switch (is_defined(object)) { case +1 : str = object + ": intrinsic function"; return;} { case +2 : str = object + ": library function"; return;} { case 0 : % not globally defined if (is_internal(object)) { str = object + ":\t internal function"; return; } else if (blocal_var_exists(object)) { str = "Blocal variable " + object + " == " + sprint_variable(get_blocal_var(object)); return; } else if (ref == NULL) { str = object + " (or local/static given as string)"; return; } else str = object; } { case -1 : str = "Intrinsic variable " + object;} { case -2 : str = "Library variable " + object;} % add variable value if (__is_initialized(ref)) value = " == " + sprint_variable(@ref); str += value; } %!%+ %\function{show_stack} %\synopsis{Show a listing of the stack, emptying the stack } %\usage{show_stack()} %\description % Pop all items from the stack and show them in the Diagnose_Buffer. %\notes % This is a nice tool to find out about functions leaving rubbish on % the stack. %\seealso{show, _pop_n, _stkdepth, pop, stack_check} %!%- public define show_stack() { variable element; if (_stkdepth) { show_string("Stack listing: "); loop(_stkdepth) { element = (); show(element); } } else show_string("Stack empty"); } %!%+ %\function{show_eval} %\synopsis{Show the (String_Type) argument(s) and the result of their evaluation.} %\usage{show_eval(String args)} %\description % Take a variable number of strings and show the string and the result of % its evaluation in the Diagnose_Buffer %\example %#v+ % show_eval("TAB", "WRAP") %#v- %\notes % The string will be evaluated in the global namespace, so static % variables and functions are only accessible in a "named namespace" % via the usual "namespace_name->variable_name" notation. %\seealso{show, vshow, mshow} %!%- public define show_eval() % args { variable arg; _stk_reverse(_NARGS); loop(_NARGS) { arg = (); show(arg, eval(arg)); } } private variable last_stkdepth = 0; % modus: 0 set, 1 warn, 2 error define stack_check(modus) { variable str, change = _stkdepth - last_stkdepth; if (modus == 0) { last_stkdepth = _stkdepth(); return; } str = sprintf("stackcheck: Stack changed by %d", change); if (modus == 1) message(str); else if (modus == 2 and (_stkdepth() != last_stkdepth)) error(str); } provide("diagnose"); jedmodes-2.5.7/x-keydefs/0000755000175400017500000000000010740370067013505 5ustar mildegmjedmodes-2.5.7/x-keydefs/x-keydefs.sl0000644000175400017500000002502110740370040015733 0ustar mildegm% x-keydefs.sl: Extended set of key variables % ******************************************* % % * add key definitions % (Key_Esc, Key_Alt, Key_*_Return, Key_*_Tab, Key_KP_*) % * On xjed, call x_set_keysym for "special_keys" % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % ======== % % 1.1 2004-12-01 first public version % 1.2 2004-12-03 merged files x-keydefs.sl and x-keysyms.sl % with call to x_keydefs_hook for customization % 1.3 2005-09-20 set Key_Alt_* in a loop % 1.4 2005-10-12 (re) use the definitions in standard keydefs.sl, % let it work on "non-X" jed versions % 1.5 prepare IBMPC support (incomplete, untested) % set Key_Shift_Tab for xjed % 1.5.1 2005-11-21 documentation fix (autoload get_keystring from strutils) % 1.5.2 2006-01-17 documentation fix (warn about ESC redefinition, workaround) % 1.5.3 2006-01-17 jed compatible default for Key_Esc ("\e" not "\e\e\e") % 1.5.4 2006-01-18 added termcap entries for keypad keys (where possible) % 1.5.5 2006-01-19 updated the IBMPC definitions (not fully tested yet) % 1.5.6 2006-01-20 changed back IBMPC for Key_Alt_Return after report by % M Mahnic that it works in wjed. (it will not harm in DOS % or jed in a DOS window). % 1.6 2006-03-29 renamed KP_Return to KP_Enter (Thei Wejnen) % 1.6.1 2007-07-25 renamed set_keyvar() to _keystr() % 1.7 2008-01-04 bugfix: set default for Key_Esc to "\e\e\e" % (triple escape) this is: % + compatible with cuamisc.sl and cua.sl % + save (a lot of keys emit "\e" and some "\e\e" as % leading part of their keystring). % In xjed, pressing [Esc] will emit Key_Escape. In % (non-x) jed, distinguishing these is tricky but can % be achieved with cua_one_press_escape() from cuamisc.sl % 1.7.1 2008-01-07 do not change the keystring of the [Esc] key to Key_Escape % as this breaks compatibility in non-CUA emulation modes. % (See cuamisc.sl for functions and documentation to % configure it for other modes.) % % Usage % ===== % % Place in the jed library path. % % Do not byte-compile, if you plan to use this file for both, Unix and % DOS/Windows from one libdir! Byte compiling is OK for xjed and jed on a % console or terminal emulator. % % To make the Key_Vars available, write (e.g. in your jed.rc or .jedrc file) % % require("x-keydefs"); % % x-keydefs in turn do require("keydefs"), so the full set of key variables % is available. % % !! Attention !! % % On xjed, `x_set_keysym' is used to make sure the keys send the % strings as defined here (or in the x_keydefs_hook() described below). % % While generally this leads to the expected behaviour with a % simple require("x-keydefs"), some modes that define keybindings % without use of Key_* variables may break. % % Customisation and Extension % =========================== % % If you want to use alternative key strings, define x_keydefs_hook(). e.g. % :: % % define x_keydefs_hook() % { % % Alternative keystring values: % Key_Return = "\e[8~"; % Key_BS = "\e[16~"; % Key_Tab = "\e[z"; % % new definitions: % global variable Key_Shift_Ctrl_Right = "\e[^c" % } % % In xjed, additional bindings can be enabled with x_set_keysym(): % % Get the keysyms from the file keysymdef.h or the Jed variable X_LAST_KEYSYM % e.g. with:: % % autoload("get_keystring", "strutils"); % from jedmodes.sf.net % public define showkey_literal() % { % flush ("Press key:"); % variable key = get_keystring(); % if (prefix_argument(0)) % insert (key); % else % { % #ifdef XWINDOWS % key += sprintf(" X-Keysym: %X", X_LAST_KEYSYM); % #endif % message ("Key sends " + key); % } % } % % Attention: In JED <= 99.16, x_set_keysym() works only for keysyms in the % range `0xFF00' to `0xFFFF'. Since JED 99.17 this restriction is % gone. % % Shift-Tab on X-Windows % ---------------------- % % Unfortunately, Shift-Tab doesnot send any keystring in most X-Window setups % as it is bound to "ISO_Left_Tab", Keysym 0xFE20 % % This is fixed by x-keydefs using x_set_keysym(). % % For jed < 99.17, x_set_keysym() does not work for Shift-Tab. A line % keycode 23 = Tab % in ~/.Xmodmap can cure this problem. However, this doesnot work % with the XKB keyboard driver % % % TODO: test IBMPC keystrings, % find keystrings for Ctrl-Shift Movement keys % Definitions % =========== % make sure we have the basic definitions loaded: require("keydefs"); provide("x-keydefs"); % eXtended set of key definitions % Auxiliary function to define symbolic keynames to count for different % operating systems. (Extended version of the auxiliary fun in keydefs.sl % including the ibmpc string.) private variable Is_Xjed = is_defined("x_server_vendor"); static define _keystr(ibmpc, termcap, default) { #ifdef IBMPC_SYSTEM return ibmpc; #endif if (Is_Xjed) return default; #ifexists get_termcap_string variable s = get_termcap_string(termcap); if (s == "") return default; return s; #else return default; #endif } #ifdef Test putenv("TERM=foo"); vmessage("TERM is '%s'", getenv("TERM")); show("Key_Up", get_termcap_string("ku")); show("Key_Shift_Tab", get_termcap_string("bt")); #endif % Numeric Keypad % -------------- % * variable names are chosen to match X-Window's keysymdef.h % % * default strings as in rxvt without active Num Lock % and in X-Windows (where Num Lock only affects the string sent by [,|Del]) % % * By default, KP_Divide, KP_Multiply, and KP_Add send "/", "*", and "+" in % xjed (their keysym does not change with Num Lock). % x-keydefs.sl uses x_set_keysym to change this to the variables values % (therefore you should use the x_keydefs_hook() to change the value so xjed % will see the changes) % % * ibmpc strings correspond to VT220 codes % % TODO: check IBMPC keystrings, if different use _keystr() variable Key_KP_Enter = "\eOM"; variable Key_KP_Divide = _keystr("\eOQ", "", "\eOo"); variable Key_KP_Multiply = _keystr("\eOR", "", "\eOj"); variable Key_KP_Add = _keystr("\eOm", "", "\eOk"); variable Key_KP_Subtract = _keystr("\eOS", "", "\eOm"); variable Key_KP_Separator = "\eOl"; % Key [./Del] with Num Lock in Xjed variable Key_KP_Delete = "\eOn"; % Key [./Del] without Num Lock in Xjed variable Key_KP_0 = "\eOp"; variable Key_KP_1 = _keystr("\eOq", "K4", "\eOq"); variable Key_KP_2 = "\eOr"; variable Key_KP_3 = _keystr("\eOs", "K5", "\eOs"); variable Key_KP_4 = "\eOt"; variable Key_KP_5 = _keystr("\eOu", "K2", "\eOu"); variable Key_KP_6 = "\eOv"; variable Key_KP_7 = _keystr("\eOw", "K1", "\eOw"); variable Key_KP_8 = "\eOx"; variable Key_KP_9 = _keystr("\eOy", "K3", "\eOy"); % Alt and Escape % -------------- % (Some jed versions (console) don' set ALT_CHAR) custom_variable("ALT_CHAR", 27); % '\e' variable Key_Alt = _keystr("", "", char(ALT_CHAR)); % see also cuamisc.sl custom_variable("Key_Esc", _keystr("", "", "\e\e\e")); % Tab % --- variable Key_Tab = _keystr("^I", "", "^I"); % alternative "\e[z" variable Key_Shift_Tab = _keystr("^@^O", "", "\e[Z"); % reverse_tab variable Key_Ctrl_Tab = _keystr("", "", "\e[^Z"); variable Key_Alt_Tab = _keystr("", "", strcat(Key_Alt, Key_Tab)); % Return % ------ variable Key_Return = _keystr("^M", "", "^M"); % alternative "\e[8~" variable Key_Shift_Return = _keystr("", "", "\e[8$"); variable Key_Ctrl_Return = _keystr("^J", "", "\e[8^"); variable Key_Alt_Return = strcat(Key_Alt, Key_Return); % Shift-Control Movement Keys % --------------------------- % TODO: find keystrings % variable Key_Ctrl_Shift_Up = _keystr("", "", "\e[%A"); % variable Key_Ctrl_Shift_Down = _keystr("", "", "\e[%B"); % variable Key_Ctrl_Shift_Right = _keystr("", "", "\e[%C"); % variable Key_Ctrl_Shift_Left = _keystr("", "", "\e[%D"); variable Key_Ctrl_Shift_Home = _keystr("", "", "\e[1%"); variable Key_Ctrl_Shift_End = _keystr("", "", "\e[4%"); variable Key_Ctrl_Shift_PgUp = _keystr("", "", "\e[5%"); variable Key_Ctrl_Shift_PgDn = _keystr("", "", "\e[6%"); % Customziation by hook % --------------------- runhooks("x_keydefs_hook"); % abort here, if we are on DOS or Windows #ifdef IBMPC_SYSTEM #stop #endif % Additional keystrings with Xjed % ------------------------------- % We need to trick the function check for non-X jed (we cannot use #ifdef % XWINDOWS, as the byte-compiled file should be usable with jed on a console % as well.) private variable x_set_keysym_p = __get_reference("x_set_keysym"); if (is_defined("x_server_vendor")) { % ESC already emits a recognized keystring ("\e"). As some users or % emulations prefer it this way (to use the ESC as a prefix key) changing % this to let the key ESC emit Key_Esc is left to the emulation or a users % jed.rc (see cuamisc.sl for more details). %@x_set_keysym_p(0xFF1B, 0, Key_Esc); % DEL (see also .jedrc for this topic) % (on my system it did not distinguish modifiers) @x_set_keysym_p(0xFFFF, 0, Key_Del); @x_set_keysym_p(0xFFFF , '$', Key_Shift_Del); @x_set_keysym_p(0xFFFF , '^', Key_Ctrl_Del); % Backspace: @x_set_keysym_p(0xFF08 , 0, Key_BS); @x_set_keysym_p(0xFF08 , '$', Key_Shift_BS); @x_set_keysym_p(0xFF08 , '^', Key_Ctrl_BS); % Return: (make it distinguishable from ^M) @x_set_keysym_p(0xFF0D , 0, Key_Return); @x_set_keysym_p(0xFF0D , '^', Key_Ctrl_Return); @x_set_keysym_p(0xFF0D , '$', Key_Shift_Return); % TAB: @x_set_keysym_p(0xFF09 , 0, Key_Tab); @x_set_keysym_p(0xFF09 , '^', Key_Ctrl_Tab); #ifeval (_jed_version >= 9917) @x_set_keysym_p(0xFE20, '$', Key_Shift_Tab); #endif % numeric keypad (keys whose keysym do not change with Num Lock) @x_set_keysym_p(0xFFAA , 0, Key_KP_Multiply); @x_set_keysym_p(0xFFAB , 0, Key_KP_Add); @x_set_keysym_p(0xFFAF , 0, Key_KP_Divide); % Shift-Control Movement Keys @x_set_keysym_p(0xFF50 , '%', Key_Ctrl_Shift_Home); % @x_set_keysym_p(0xFF51 , '%', Key_Ctrl_Shift_Left); % @x_set_keysym_p(0xFF52 , '%', Key_Ctrl_Shift_Up); % @x_set_keysym_p(0xFF53 , '%', Key_Ctrl_Shift_Right); % @x_set_keysym_p(0xFF54 , '%', Key_Ctrl_Shift_Down); @x_set_keysym_p(0xFF55 , '%', Key_Ctrl_Shift_PgUp); @x_set_keysym_p(0xFF56 , '%', Key_Ctrl_Shift_PgDn); @x_set_keysym_p(0xFF57 , '%', Key_Ctrl_Shift_End); } jedmodes-2.5.7/keywords/0000755000175400017500000000000010461125576013460 5ustar mildegmjedmodes-2.5.7/keywords/keywords_sl.html0000664000175400017500000001222010214064454016703 0ustar mildegm JED Macro: keywords.sl

keywords.sl

A set of macros to make lists of keywords for language modes more manageable.

Create keyword lists to be used in define_keywords_n. You can add keywords to the keyword lists in multiple steps. Keywords are separated by whitespace. You can mix words of different sizes. The sort order of keywords is not important.

Very helpful when you define syntaxes for similar languages or language variants. (SQL: sql92, postgresql, mysql, oracle, mssql; some keywords are the same in all variants, but some are dbms-specific)

Installation

Put the file somewhere on your jed_library_path. See the example below.

Remark

Use of this system is slower than use of define_keywords_n calls, but the difference might be noticeable only when first using a mode in a session. You can also use write_keywords to prepare a list of define_keywords_n calls.

Examples of use

Example 1: A "simple" mode with simple set of keywords
 % ----- file: simplemode.sl -----
 require("keywords");

 define simple_mode(mode)
 {
    K = keywords->new_keyword_list();
    keywords->add_keywords(K, "if then else while do until");
    keywords->add_keywords(K, "cos sin tan acos asin atan");
    keywords->sort_keywords(K);
    keywords->strlow_keywords(K);
    keywords->define_keywords(K, "simple", 0);

    set_mode("simple", 2 | 8);
    use_syntax_table ("simple");
 }
If the mode is case-insensitive (set_syntax_flags, flag 0x01), all the keywords must be in lower-case. We can obtain this by calling keywords->strlow_keywords(K).

Example 2: Prepare define_keywords_n calls for "simple" mode and write them into buffer "temp_buffer":

 % ----- file: prep_simplemode.sl -----
 require("keywords");

 K = keywords->new_keyword_list();
 keywords->add_keywords(K, "if then else while do until");
 keywords->add_keywords(K, "cos sin tan acos asin atan");
 keywords->sort_keywords(K);
 
 write_keywords(K, "simple", 0, "temp_buffer");
Example 3: SLang mode with 2 alternative color sets.

Notice: keyword-set might also be extended using runhooks ("xxx_define_keyword_hook").

 % ----- file: slangmode.sl -----
 require("keywords");
 
 % size and order of keywords in a string are irrelevant
 
 static variable kwds_control = 
    "if else loop do while for _for foreach using forever switch case " +
    "orelse andelse break return continue";                              
 static variable kwds_struct  = "define variable struct typedef public private static";
 static variable kwds_logic   = "or and not xor";                                        
 static variable kwds_math    = "chs mod shl shr sqr mul2 sign";                         
 static variable kwds_stack   = "pop exch";                                              
 static variable kwds_block   = "EXIT_BLOCK ERROR_BLOCK EXECUTE_ERROR_BLOCK";            
 static variable kwds_other   = "NULL __tmp";                                            
                                                                         
 define create_mode(mode)
 {
    variable mode;
    !if (keywords->check_language(mode))
    {
       variable K;
       % CreateSyntaxTable();
     
       K = keywords->new_keyword_list();
       keywords->add_keywords(K, kwds_control);
       keywords->add_keywords(K, kwds_struct);
       keywords->add_keywords(K, kwds_logic);
       % runhooks("slang_define_keyword_hook", K, 0); %% User could add more keywords!
       keywords->sort_keywords(K);
       keywords->define_keywords(K, mode, 0);

       K = keywords->new_keyword_list();
       keywords->add_keywords(K, kwds_math);
       keywords->add_keywords(K, kwds_stack);
       if (mode == "SLANG")
       {
          keywords->add_keywords(K, kwds_block);
          keywords->add_keywords(K, kwds_other);
       }
       % runhooks("slang_define_keyword_hook", K, 1);
       keywords->sort_keywords(K);
       keywords->define_keywords(K, mode, 1);
       
       if (mode == "SLANG2")
       {
          K = keywords->new_keyword_list();
          keywords->add_keywords(K, kwds_block);
          keywords->add_keywords(K, kwds_other);
          % runhooks("slang_define_keyword_hook", K, 2);
          keywords->sort_keywords(K);
          keywords->define_keywords(K, mode, 2);
       }
       
       keywords->add_language(mode);
    }
    
    set_mode("SLang", 2 | 8);
    c_mode_common ();
    use_syntax_table (mode);
    mode_set_mode_info ("SLang", "fold_info", "%{{{\r%}}}\r\r");
    run_mode_hooks("slang_mode_hook");
 }
 
 define slang_mode ()  { create_mode ("SLANG", 0); }
 define slang2_mode () { create_mode ("SLANG2", 1); }
jedmodes-2.5.7/keywords/keywords.sl0000664000175400017500000001122010214064452015654 0ustar mildegm% keywords.sl % % @author: Marko Mahnic % @version: 1.0 % @created: 2004-07-29 % % A set of macros to make lists of keywords for language modes more manageable. % % Create keyword lists to be used in define_keywords_n. % You can add keywords to the keyword lists in multiple % steps. Keywords are separated by whitespace. % You can mix words of different sizes. The sort order of % keywords is not important. % % Very helpful when you define syntaxes for similar languages or language variants. % (SQL: sql92, postgresql, mysql, oracle, mssql; some keywords are % the same in all variants, but some are dbms-specific) % % Remark: % Use of this system is slower than use of define_keywords_n calls, % but the difference might be noticeable only when first using a % mode in a session. % You can also use write_keywords to prepare a list of define_keywords_n % call. % % Installation: % Put the file somewhere on your jed_library_path. % See keywords_sl.html % implements("keywords"); static variable languages = "."; % Check if keywords for a language have already been defined define check_language (langId) { variable lng = "." + langId + "."; !if (is_substr (languages, lng)) return 0; return 1; } define add_language (langId) { languages = languages + langId + "."; } % Extend the array A to a minimum of minsize elements % If the array is extended, its size is a multiple of 8. static define extend_array (A, minsize) { variable round = 8; % if (_NARGS == 3) round = int( () ); % if (round < 2) round = 2; variable asize = ((int(minsize) / round) + 1) * round; if (length(A) < asize) { variable B, i; B = @Array_Type(_typeof(A), asize); for (i = length(A) - 1; i >= 0; i--) B[i] = A[i]; for (i = length(A); i < asize ; i++) B[i] = ""; return B; } return A; } typedef struct { keywords } _KeywordList_Type; % Create a new structure to hold the keywords. % The structure is an array of strings. Each string is a list of % space delimited keywords of the same length. define new_keyword_list () { variable i, a; a = @_KeywordList_Type; a.keywords = @Array_Type(String_Type, 1); a.keywords[0] = ""; return a; } % Add new keywords to the corresponding lists. % The lists are not sorted. define add_keywords (kwdlst, strKeywords) { variable akwd = strtok(strKeywords); variable n, i, s; n = length(akwd); for (i = 0; i < n; i++) { s = strlen(akwd[i]); if (s < 1) continue; if (s >= length(kwdlst.keywords)) kwdlst.keywords = extend_array(kwdlst.keywords, s); kwdlst.keywords[s-1] = kwdlst.keywords[s-1] + " " + akwd[i]; } } % Sort all keyword lists. define sort_keywords (kwdlst) { variable i; for (i = length(kwdlst.keywords) - 1; i >= 0; i--) { if (kwdlst.keywords[i] != "") { variable akwd = strtok(kwdlst.keywords[i]); variable II = array_sort(akwd); akwd = akwd[II]; kwdlst.keywords[i] = strjoin(akwd, " "); } } } % Convert all keywords to lower case - for case insensitive syntaxes define strlow_keywords (kwdlst) { variable i; for (i = length(kwdlst.keywords) - 1; i >= 0; i--) { if (kwdlst.keywords[i] != "") { kwdlst.keywords[i] = strlow(kwdlst.keywords[i]); } } } % Merge two structures into a third one and return it. define merge_keywords (akwd, bkwd) { variable i, mrg; if (length(akwd.keywords) > length(bkwd.keywords)) { mrg = akwd; for (i = length(bkwd.keywords) - 1; i >= 0; i--) add_keywords(mrg, bkwd.keywords[i]); } else { mrg = bkwd; for (i = length(akwd.keywords) - 1; i >= 0; i--) add_keywords(mrg, akwd.keywords[i]); } return mrg; } % Call define_keywords_n for each list in the structure. define define_keywords (kwdlst, strTable, colorN) { variable i; for (i = length(kwdlst.keywords) - 1; i >= 0 ; i--) { variable wrds = str_delete_chars(kwdlst.keywords[i], " "); if (wrds == "") continue; () = define_keywords_n (strTable, wrds, i + 1, colorN); } } % insert define_keywords_n calls into buffer buf. define write_keywords (kwdlst, strTable, colorN, buf) { if (buf != NULL) setbuf(buf); !if (bolp()) { eol(); insert("\n"); } variable i; for (i = 0; i < length(kwdlst.keywords); i++) { variable wrds = str_delete_chars(kwdlst.keywords[i], " "); if (wrds == "") continue; vinsert("() = define_keywords_n (\"%s\", ", strTable); vinsert("\"%s\"", wrds); vinsert(", %d, %d);\n", i + 1, colorN); } } provide("keywords"); jedmodes-2.5.7/view/0000755000175400017500000000000010674672122012563 5ustar mildegmjedmodes-2.5.7/view/view.sl0000644000175400017500000001230310674672122014074 0ustar mildegm% view.sl: A generic view mode for readonly buffers % % Copyright (c) 2006 Gnter Milde and Paul Boekholt % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions % -------- % 1.0 first public release % 2005-04-05 1.1 merge of GM and PB versions, bugfix in enable edit % 2005-04-07 1.2 added require("keydefs") (Rafael Laboissiere) % 2006-03-20 1.3 repeat_search() only defined if not already existent % 2006-09-07 1.4 bugfix in enable_edit() if there is no buffer_filename % 2007-06-06 1.5 view_mode: folding_mode() -> fold_mode() to respect the % setting of `Fold_Mode_Ok' without asking. % Moved definition of set_view_mode_if_readonly() to % Customization documentation. % 2007-09-21 1.5.1 bugfix in enable_edit(): fall back to no_mode(). % % Customization % ------------- % % If you want to change the keybindings for all readonly buffers based % on the "view" keymap you either just change this file, or insert in your % jed.rc file something like % % require("view"); % definekey("close_and_insert_word", "i", "view"); % % After that, in all modes that copy the view keymap, pressing key 'i' % closes the buffer and inserts the current word into the calling buffer % (if the binding is not overwritten in the mode). % % To use view mode as default for readonly buffers, insert lines similar to % % define set_view_mode_if_readonly() % { % if (is_readonly) % % if ((what_mode(), pop) == "") % no mode % view_mode; % } % append_to_hook("_jed_find_file_after_hooks", &set_view_mode_if_readonly); private variable mode = "view"; % requirements autoload("close_buffer", "bufutils"); autoload("set_help_message", "bufutils"); autoload("help_message", "bufutils"); autoload("close_and_insert_word", "bufutils"); autoload("close_and_replace_word", "bufutils"); require("keydefs"); % in stadandard library but not loaded by all emulations % customization % Ask before going to edit mode? custom_variable("View_Edit_Ask", 1); % --- helper functions --- % Make a readonly buffer editable (based on the same function in most.sl) define enable_edit() { if(View_Edit_Ask) !if (get_y_or_n("Edit this buffer") == 1) return; set_readonly(0); set_status_line("", 0); % reset to global if (strlen(file_type(buffer_filename))) runhooks("mode_hook", file_type(buffer_filename)); else no_mode(); } #ifnexists repeat_search % this one is also in cuamisc.sl (and hopefully one day in site.sl)! define repeat_search() { go_right (1); !if (fsearch(LAST_SEARCH)) error ("Not found."); } #endif % --- the mode --- % a generic keymap for readonly buffers (use for view-mode or % as base for your specific map with copy_keymap(mode, "view")) !if (keymap_p(mode)) { make_keymap(mode); % _for ('a', 'z', 1) % definekey(char, "error(help_message)", _stk_roll(2), mode); definekey("close_buffer", "\e\e\e", mode); % Escape definekey("page_up", Key_BS, mode); definekey("page_down", " ", mode); % TODO: Key_Return/Key_BS scroll one line down/up definekey("bob", "<", mode); definekey("eob; recenter(window_info('r'));", ">", mode); definekey("re_search_forward", "/", mode); definekey("repeat_search", "\\", mode); definekey("help_message", "?", mode); definekey("search_backward", "b", mode); definekey("enable_edit", "e", mode); definekey("search_forward", "f", mode); definekey("goto_line", "g", mode); % definekey("close_and_insert_word", "i", mode); definekey("describe_mode", "h", mode); % definekey("page_down", "n", mode); % definekey("page_up", "p", mode); definekey("close_buffer", "q", mode); % definekey("close_and_replace_word", "r", mode); definekey("isearch_forward", "s", mode); _for (0, 9, 1) definekey("digit_arg", string(exch()), mode); } % view menu (appended to an possibly existing mode menu) static define view_menu(); static define view_menu(menu) { variable init_menu = get_blocal_var("init_mode_menu"); if (andelse{init_menu != NULL}{init_menu != &view_menu}) { @init_menu(menu); menu_append_separator(menu); } menu_append_item(menu, "&Edit", "enable_edit"); menu_append_item(menu, "&Close", "close_buffer"); } public define view_mode() { % If it's folded and Fold_Mode_Ok is True, % add the folding keybindings to the view map if(blocal_var_exists("fold_start")) { use_keymap(mode); fold_mode; } set_readonly(1); set_buffer_modified_flag(0); define_blocal_var("init_mode_menu", mode_get_mode_info("init_mode_menu")); use_keymap(mode); set_mode(mode, 0); mode_set_mode_info(mode, "init_mode_menu", &view_menu); set_help_message( "SPC:pg_dn BS:pg_up f:search_fw b:search_bw q:quit e:edit ?:this_help"); run_mode_hooks(mode); } provide(mode); jedmodes-2.5.7/snake/0000755000175400017500000000000010461125576012712 5ustar mildegmjedmodes-2.5.7/snake/snake.sl0000664000175400017500000001213210246562005014345 0ustar mildegm% snake.sl % Eat the apples and stay away from the walls % % $Id: snake.sl,v 1.2 2005/05/27 17:28:01 paul Exp paul $ % Keywords: games % % Copyright (c) 2004, 2005 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). provide("snake"); implements("snake"); custom_variable("Snake_Use_DFA", 1); custom_variable("Snake_Initial_Number_Apples", 50); %{{{ Syntax Highlighting #ifdef HAS_DFA_SYNTAX create_syntax_table ("snake"); custom_color("snake", "green", "green"); custom_color("snake_border", "blue", "blue"); %%% DFA_CACHE_BEGIN %%% static define setup_dfa_callback (mode) { dfa_define_highlight_rule("O", "snake", mode); dfa_define_highlight_rule("[\\-\\|\\+\\`\\'\\,]", "snake_border", mode); dfa_build_highlight_table(mode); } dfa_set_init_callback (&setup_dfa_callback, "snake"); %%% DFA_CACHE_END %%% #endif %}}} %{{{ snake variables % It is a little known fact of herpetology that snakes are made of % segments. static variable Segment_Type = struct { next, prev, x, y }; variable the_snake = @Segment_Type, tail, score=0, grow=0, number_apples = 0; %}}} %{{{ drawing % Create a segment. define draw_segment(segment) { variable update_score = 0; goto_line(segment.y); goto_column(segment.x); !if (looking_at_char(' ')) { if (looking_at_char('*')) { score++; update_score = 1; grow += 3; } else return 0; } del; insert_char('O'); if (update_score) { number_apples--; eob; bol; del_eol; vinsert("Score: %04d\t apples: %d", score, number_apples); !if (number_apples) return -1; } bob; return 1; } define place_apple() { do { goto_line(2 + random(0, 19)); goto_column(11 + random(0, 59)); } while (not(looking_at_char(' '))); del(); insert_char('*'); number_apples++; } %}}} %{{{ moving % Move the snake. This is achieved by moving the snake's tail segment to % its head. This was inspired by a National Geographic Channel special % on the hidden life of snakes. define snake_move(x,y) { variable segment; if (grow) { segment = @Segment_Type; grow--; } else { goto_line(tail.y); goto_column(tail.x); del; insert_char(' '); segment = tail; tail = segment.prev; segment.prev = NULL; } segment.next = the_snake; the_snake.prev = segment; the_snake = segment; segment.x=x; segment.y=y; return draw_segment(segment); } %}}} %{{{ initialisation % Place some apples. define draw_apples() { () = random(-1, 10); loop(Snake_Initial_Number_Apples) place_apple; } define init_snake(x,y) { the_snake.x = x; the_snake.y = y; tail = the_snake; ()=draw_segment(the_snake); } %}}} %{{{ snake %!%+ %\function{snake} %\synopsis{race against time eating apples} %\usage{snake()} %\description % A snake game with a twist: every 5 seconds, an apple is placed on the % field. To win, you have to eat all the apples and avoid banging into % the wall. You can run by keeping the arrow keys pressed. % Custom Variables: % \var{Snake_Initial_Number_Apples} = 50; The number of apples the game starts with. % \var{Snake_Use_Dfa} = 1: determines if the snake should be drawn % using DFA syntax highlighting % You can set the color of the snake and the wall with %#v+ % custom_color("snake", "red", "red"); % custom_color("snake_border", "black", "black"); %#v- %\seealso{custom_color} %!%- public define snake() { score = 0; grow = 5; number_apples = 0; sw2buf("*snake*"); onewindow; erase_buffer; if (Snake_Use_DFA) { use_syntax_table("snake"); use_dfa_syntax(1); } % grid is 20 * 60 insert (" ,------------------------------------------------------------+\n"); loop(20)insert (" | |\n"); insert (" `------------------------------------------------------------'\n"); % draw some apples. The playing field runs from column 10 to 69 % and line 4 to 24 draw_apples(); eob; vinsert("Score: %04d", score); bob; recenter(1); variable x = 20, y = 15, ch, dir = 1, delay, timer = _time; init_snake(x,y); EXIT_BLOCK { set_buffer_modified_flag(0); } forever { switch(dir) {case 1: x++;} {case -1: x--;} {case 2: y++;} {case -2: y--;} if ((_time > timer + 5)) { place_apple; timer = _time; } switch (snake_move(x,y)) { case -1: eob; insert ("\t\tyou win!");return;} { case 0: eob; insert ("\t\tyou lose!"); return;} update_sans_update_hook(1); if (dir == 2 or dir == -2) delay = 2; else delay = 1; !if (input_pending(delay)) continue; ch = get_keystring; % debug % message(ch); % ch; % switch (ch) % {case Key_Left: dir = -1;} % {case Key_Right: dir = 1;} % {case Key_Up: dir = -2;} % {case Key_Down: dir = 2;} % {case "q": return;} if (ch == "q") return; (,ch) = get_key_binding (ch); switch (ch) {case "previous_char_cmd": dir = -1;} {case "next_char_cmd": dir = 1;} {case "previous_line_cmd": dir = -2;} {case "next_line_cmd": dir = 2;} } } %}}} jedmodes-2.5.7/moby-thesaurus/0000755000175400017500000000000010461125576014600 5ustar mildegmjedmodes-2.5.7/moby-thesaurus/moby-thesaurus.sl0000644000175400017500000001544610434612336020134 0ustar mildegm%% moby-thesaurus.sl %% %% This script provides an interface for listing and selecting synonyms %% for a word by querying the moby-thesaurus dictionary, residing on %% either a local or a remote DICT server. %% %% Authors: Morten Bo johansen, Paul Boekholt %% Released under the terms of the GNU General Public License (ver. 2 or later) %% %% Required software: %% %% - datutils.sl (http://jedmodes.sourceforge.net/mode/datutils/) %% - sl_utils.sl (http://jedmodes.sourceforge.net/mode/sl_utils/) %% - txtutils.sl (http://jedmodes.sourceforge.net/mode/txtutils/) %% - the dict client program. %% %% Optional software: %% %% - the dict server program for local queries %% - the dict moby-thesaurus dictionary for local queries. %% %% Quick Installation: %% %% - Copy this file and the required *.sl files to your Jed Library Path, %% usually ~/.jed/lib/ or /usr/share/jed/lib %% %% - Activate the mode in your jed.rc file (~/.jedrc): %% %% * Copy/paste the lines between # and # %% %% * add a keybinding, e.g. %% %% unsetkey ("\e1"); %% setkey ("thesaurus_popup_completions ()", "\e1"); % Alt-1 %% %% (replace "\e1" with your favourite key binding and remember to remove %% the "%%" characters) %% %% * Optionally modify the custom variables %% %% Thesaurus_Charset = "iso-8859-1" %% Dict_Server = "localhost" %% Dict_DB = "moby-thesaurus" %% %% e.g. to: %% %% variable %% Dict_Server = "dict.org", %% Dict_DB = "moby-thes"; %% %% if you have a broadband connection and you do not want to have %% a DICT server running locally. Note that the names of the Dict_DB %% might differ for local and remote servers. %% %% Alternative (automatic) way of installing: %% %% - Install the files %% libdir.sl (http://jedmodes.sourceforge.net/mode/libdir/) %% make_ini.sl (http://jedmodes.sourceforge.net/mode/make_ini/) %% and follow the instructions there %% %% %% Use: There are two interfaces for selecting a synonym: %% %% 1) In the menubar accessible with F10 -> System -> Thesaurus %% Invoking this menu item will pop up a list of synonyms for the %% word at point. Hitting on one of them will replace the %% original word with the selected one. %% %% 2) A completions popup buffer, that can be invoked on a keypress. %% If you inserted the setkey line above it will be available with %% ALT-1. From the list of completions you can choose a synonym by %% typing in as many characters of that word as neccessary to make %% it the unambiguous choice and then hit to complete it. %% Hitting will replace the original word. %% %% In both cases the word at the editing point or immediately preceding %% it will be looked up. # autoload("thesaurus_popup_menu", "thesaurus.sl"); autoload("thesaurus_popup_completions", "thesaurus.sl"); private define thesaurus_load_popup_hook(menubar) { variable menu = "Global.S&ystem"; menu_append_popup(menu, "&Thesaurus"); menu="Global.S&ystem.&Thesaurus"; menu_set_select_popup_callback(menu, &thesaurus_popup_menu ()); } append_to_hook("load_popup_hooks", &thesaurus_load_popup_hook); # custom_variable ("Thesaurus_Charset", "iso-8859-1"); custom_variable ("Dict_Server", "localhost"); custom_variable("Dict_Thesaurus_DB", "moby-thesaurus"); autoload ("array_max", "datutils"); autoload ("mark_word", "txtutils"); autoload ("get_word", "txtutils"); implements ("thesaurus"); % string_match isn't utf-8 aware, but this only tries to get some ascii % characters from the beginning of the string, so it should work private define get_indent(str) { variable len; if (string_match(str, "^[ \t]+", 1)) { (,len)=string_match_nth(0); return len; } else return 0; } private define insert_syn (syn) { mark_word (); del_region (); insert (syn); } %% Unfortunately there is no standard for formatting the dict output %% and a variety of formats exists which may differ with various %% distributions, depending on how the dictionary was converted into %% dict format, and since there is no option to the dict command that %% will spit out just the translations, something must be done to %% isolate them in the output. The following assumes that the lines with %% the translations always have some indentation, and preferably more %% indentation than the headword. If the lines with the translations %% have no indentation, this lookup function will fail. private define thesaurus_list_synonyms (word) { variable indent, syns = "", syn, cmd; variable len, fp, max_indent = 0; variable dict_cmd = sprintf ("dict -h %s -P - -C -d", Dict_Server); cmd = sprintf ("%s \"%s\" '%s' | iconv -f utf-8 -t %s", dict_cmd, Dict_Thesaurus_DB, word, Thesaurus_Charset); fp = popen (cmd, "r"); if (fp == NULL) verror("popen failed"); #ifexists _slang_utf8_ok () = fread (&syns, String_Type, 50000, fp); #else () = fread (&syns, Char_Type, 50000, fp); #endif () = pclose (fp); syns = strchop (syns, '\n', 0); indent=array_map(Integer_Type, &get_indent, syns); max_indent=array_max(indent); syns=syns[where(indent == max_indent)]; !if (length(syns) and max_indent) { % this is to close the menu in case there is no match, % but surely there must be a less crude solution? call ("kbd_quit"); } % in case there is information about word class, domain or % pronunciation in square or angle brackets like eg. [bot.], % then filter them out from the output. syns=array_map(String_Type, &str_uncomment_string, syns, "[<", ">]"); syns = strjoin (syns, "\n"); syns = strcompress (syns, ",,\n"); syns = strcompress (syns, " "); syns = str_replace_all (syns, ", ", ","); return word, syns; } public define thesaurus_popup_menu (popup) { variable syn, syns, word; word = get_word (); (word, syns) = thesaurus_list_synonyms (word); syns = strchop (syns, ',', 0); word = strup (word) + ":"; foreach (syns) { syn = (); menu_append_item(popup, syn, &insert_syn, syn); } menu_insert_item (0, popup, word, ""); menu_set_object_available (popup + "." + word, 0); menu_insert_separator (1, popup); } public define thesaurus_popup_completions () { variable syn, syns, word, prompt; word = get_word (); (word, syns) = thesaurus_list_synonyms (word); prompt = sprintf ("Synonym for \"%s\":", word); recenter (1); ungetkey ('\t'); syn = read_with_completion (syns, prompt, "", "", 's'); !if (strlen (syn)) return; insert_syn (syn); } private define thesaurus_mouse_2click_hook (line, col, but, shift) { thesaurus_popup_completions (); return (0); } jedmodes-2.5.7/hyperman/0000755000175400017500000000000011262367306013433 5ustar mildegmjedmodes-2.5.7/hyperman/hyperman.sl0000644000175400017510000004060711262367306016315 0ustar mildemilde% hyperman.sl % % $Id: hyperman.sl,v 1.34 2009/03/07 17:22:17 paul Exp paul $ % Keywords: help, hypermedia, unix % % Copyright (c) 2000-2008 JED, Paul Boekholt, Gnter Milde % Released under the terms of the GNU GPL (version 2 or later). % hypertextish man pager provide ("hyperman"); provide ("man"); require("pcre"); require("bufutils"); require("view"); implements("man"); %{{{ customvariables %!%+ %\variable{Man_Clean_Headers} %\synopsis{Set whether or not manpage headers are cleaned up} %\usage{Int_Type Man_Clean_Headers = 0} %\description % Set Man_Clean_Headers to 1, if you have an old man that gives you headers, % footers, and blank lines %\seealso{unix_man} %!%- custom_variable("Man_Clean_Headers", 0); %!%+ %\variable{Man_Use_Extensions} %\synopsis{Set whether or not unix_man looks for extended section numbers} %\usage{Int_Type Man_Use_Extensions = 1} %\description % If a link looks like Tk::TList (3pm) we can try man -e pm Tk::Tlist % instead of man 3 Tk::Tklist, that may be more reliable. This differs % from Emacs, where man xvidtune(1x) is translated to man 1x xvidtune, % but the latter means "man 1x and xvidtune" to my man. %\seealso{unix_man} %!%- custom_variable("Man_Use_Extensions", 1); %!%+ %\variable{Man_Complete_Whatis} %\synopsis{Set whether or not unix_man should build a list of completions} %\usage{Int_Type Man_Complete_Whatis = 1} %\description % Set whether or not to complete in the man prompt. The list of completions % is read in from the file \var{man_completions} in the \var{Jed_Home_Directory}. % If the file does not exist, it is generated from the output of "man -w '*'". %\seealso{unix_man} %!%- custom_variable("Man_Complete_Whatis", 1); %}}} static variable mode = "man", man_word_chars = "-A-Za-z0-9_.:+()\e[]"; % pcre patterns variable page_pattern = "([-A-Za-z0-9_\e\[\]][-A-Za-z0-9_.:+\e\[\]]*)"R, sec_pattern = "\(([0-9no\e\[\]]|-k)([a-zA-Z+\e\[\]]*)\)"R, man_pattern = sprintf("%s ?%s", page_pattern, sec_pattern); variable man_re = pcre_compile(man_pattern); % slang patterns page_pattern = "\\([-A-Za-z0-9_\e\\[\\]][-A-Za-z0-9_.:+\e\\[\\]]*\\)"; sec_pattern = "(\\([0-9no\e\\[\\]]\\)\\([a-zA-Z+\e\\[\\]]*\\))"; man_pattern = sprintf("%s ?%s", page_pattern, sec_pattern); static variable Man_History = String_Type[16], keep_history = 1, this_manpage; % ---- Functions ----------------------------------------------------------- %{{{ escape sequences variable escape_re=pcre_compile("\e\\[[0-9]+\\]"); define purge_escapes(str); define purge_escapes(str) { if(pcre_exec(escape_re, str)) { variable m = pcre_nth_match(escape_re, 0); str = str[[0:m[0]-1]] + purge_escapes(str[[m[1]:]]); } return str; } variable bold_marker = sprintf("\e[%d]", color_number("keyword")), italic_marker = sprintf("\e[%d]", color_number("keyword1")); %}}} %{{{ parsing references static define parse_ref(word) { if (pcre_exec(man_re, word)) % e.g. man(5) { variable sec, page, ext; page = pcre_nth_substr(man_re, word, 1); sec = pcre_nth_substr(man_re, word, 2); ext = pcre_nth_substr(man_re, word, 3); if (strlen(ext) && Man_Use_Extensions) sec = "-e " + ext; word = sec + " " + page; } else word = strcompress(word, " "); return word; % "5 man", "-e tcl list", } % transform: "5 man" to "man(5)" % "-e tcl exit" to "exit(3tcl)" % "man" to "man" static define make_ref(subj) { if (pcre_exec(man_re, subj)) return subj; subj = strtok(subj, " "); % ["5", "man"] , ["-e", "tcl", "exit"] switch (length(subj)) { case 2: return sprintf("%s(%s)",subj[1], subj[0]);} { case 3 && (subj[0] == "-e "): return sprintf("%s(%s)",subj[2], subj[1]); } { return subj[-1];} } %}}} %{{{ read a subject % see below for initialization of this variable variable man_completions=""; % Read a subject from the minibuffer. % Can be in the n exit or exit(n) or exit(3tcl) format. static define man_read_subject() { variable word= purge_escapes(get_word(man_word_chars)); if (is_substr(word, "(") && not pcre_exec(man_re, word)) % maybe it's a C function { word = strchop(word, '(', 0)[0]; } if (Man_Complete_Whatis) word= read_string_with_completion ("man", word, man_completions); else word = read_mini("man", word, ""); return word; } %}}} %{{{ clean the page static define man_mode(); static define man_push_position(); static define man_clean_manpage () { variable clean = "Cleaning man page..."; variable section_alist=String_Type[25, 2], sections = 0, line; bob (); flush (clean); % fix hyphens if in utf-8 mode if (_slang_utf8_ok) { while(fsearch_char(173)) { del; insert_char(173); } bob(); } variable ch; while(re_fsearch("[^_]\010")) { % This is needed for multibyte characters such as \u{2018} % in the sed manpage if (_slang_utf8_ok) ()=left(right(1)); insert(bold_marker); ch = what_char(); right(1); while(looking_at(sprintf("\010%c", ch))) { deln(2); ch = what_char(); right; } ()=left; insert("\e[0]"); } bob; while(fsearch("_\010")) { insert(italic_marker); 1; while(looking_at("_\010")) { deln(2); right; } pop; insert("\e[0]"); } if (Man_Clean_Headers) { variable header; % remove headers bob (); skip_chars ("\n"); header = line_as_string (); go_down_1 (); bol (); while (bol_fsearch (header)) delete_line (); % remove footers eob (); bskip_chars ("\n"); bol (); push_mark_eol (); bskip_chars ("1234567890"); header = bufsubstr (); % get rid of spurious empty lines around headers and footers bol (); while (bol_bsearch (header)) { delete_line (); go_up (3); loop (10) { bol(); ifnot (eolp()) break; delete_line (); } } } % remove multiple blank lines trim_buffer (); % build the sections-list bob(); variable alist_index; while (sections < 25) { ifnot (re_fsearch ("^[\e0-9\\[\\]]*[A-Z]")) break; line = line_as_string; if (strlen(line) > 50) continue; % header or footer section_alist[sections, 0] = purge_escapes(line); section_alist[sections, 1] = string(what_line()); sections++; } define_blocal_var("section_list", section_alist); define_blocal_var("sections", sections -1); bob(); sw2buf(whatbuf()); set_buffer_modified_flag (0); man_mode; man_push_position(this_manpage); define_blocal_var("generating_function", ["unix_man", this_manpage]); flush (strcat (clean, "done")); update (1); } %}}} %{{{ move in the page public define man_next_section () { go_down_1 (); () = re_fsearch ("^[\e0-9\\[\\]]*[A-Z]"); recenter (1); } public define man_previous_section () { () = re_bsearch ("^[\e0-9\\[\\]]*[A-Z]"); recenter (1); } % Go to a section. In Emacs this is on 'g' but I use that key for % going to another page like in lynx, so it's on 's' public define man_goto_section () { variable section_list = get_blocal_var("section_list"), sections = get_blocal_var("sections"); section_list = section_list[[:sections],*]; variable names = section_list[*,0], lines = section_list[*,1]; variable section = read_with_completion (strjoin(names, ","), "Go to section", "SEE ALSO", "", 's'); variable n = wherefirst(section == names); if (n != NULL) { goto_line(atoi(lines[n])); recenter(1); } } public define man_next_reference () { skip_chars (man_word_chars); go_right_1; % weirdness in searching w/ escape sequences () = re_fsearch (man_pattern); } public define man_previous_reference () { bskip_chars (man_word_chars); if (re_bsearch (man_pattern)) { bskip_chars("\e[]0-9"); bskip_chars("-a-zA-Z0-9"); } } %}}} %{{{ Close all man-Buffers public define man_cleanup() { variable buf; loop (buffer_list ()) { buf = (); if (is_substr(buf, "*Man")) delbuf(buf); } } %}}} %{{{ get the page static variable man_stack_depth = -1, this_manpage; static define man(subj) { subj = parse_ref(subj); % ["man(3)"|"3 man"] -> "3 man" this_manpage = subj; variable buf = "*Man " + subj + "*"; if (bufferp (buf)) return sw2buf (buf); % get the manpage setbuf (buf); set_readonly (0); erase_buffer (); flush ("Getting man page "+ subj); variable man_cmd; #ifdef OS2 man_cmd = sprintf("man %s 2> nul", subj); #else man_cmd = sprintf("MAN_KEEP_FORMATTING=1 MANWIDTH=%d man %s 2> /dev/null", SCREEN_WIDTH, subj); #endif variable return_status = run_shell_cmd (man_cmd); if (return_status && bobp() && eobp()) { delbuf(whatbuf); if (16 == return_status) throw RunTimeError, "manpage $subj not found"$; else throw RunTimeError, "man returned an error (return status $return_status)"$; } man_clean_manpage; } %}}} %{{{ jump to another page %{{{ history stack variable man_history_rotator = [[1:15],0], forward_stack_depth = 0; static define man_push_position(subj) { ifnot (keep_history) return; ++man_stack_depth; if (man_stack_depth == 16) { --man_stack_depth; Man_History = Man_History [man_history_rotator]; } Man_History [man_stack_depth] = make_ref(subj); forward_stack_depth = 0; } public define man_go_back () { ifnot (man_stack_depth) return message("Can't go back"); --man_stack_depth; ++forward_stack_depth; keep_history = 0; man(Man_History[man_stack_depth]); } public define man_go_forward() { ifnot (forward_stack_depth) return message("Can't go forward"); ++man_stack_depth; --forward_stack_depth; keep_history = 0; man(Man_History[man_stack_depth]); } %}}} % get: page(sec) or page (sec) static define man_get_ref () { variable word = ""; % get word under cursor and neighbours too (to catch page (sec)) push_spot (); push_mark(); bskip_chars(man_word_chars); go_left_1; % maybe this is a " " bskip_chars(man_word_chars); % get beginning of hyphenated link push_spot; bskip_white; if (bolp) { go_left(2); if(looking_at_char(']')) {bskip_chars("\e[]0-9"); go_left_1;} if (looking_at_char('')) { push_mark; bskip_chars(man_word_chars); word = bufsubstr; } } pop_spot; exchange_point_and_mark(); skip_chars(man_word_chars); go_right_1; % maybe this is a " " skip_chars(man_word_chars); word += strtrim (bufsubstr()); pop_spot (); ifnot (string_match(word, man_pattern, 1)) { message (word + " is not a man-page"); return ""; } return parse_ref(purge_escapes(word)); % extract and normalize reference } public define man_follow() { variable ref = man_get_ref(); if (ref == "") return; keep_history = 1; man(ref); } %}}} %{{{ start reading manpages %!%+ %\function{unix_man} %\synopsis{Display a man page entry} %\usage{unix_man([subject])} %\description % Retrieve a man page entry, use clean_manpage to clean it up and % display in a buffer in man_mode. % %\seealso{man_mode, unix_apropos, Man_Clean_Headers, Man_Use_Extensions, Man_Complete_Whatis} % %!%- public define unix_man () { variable subj; if (_NARGS) subj = (); else subj = man_read_subject(); ifnot (strlen (subj)) return; keep_history = 1; man (subj); } %}}} %{{{ apropos, whatis %!%+ %\function{unix_apropos} %\synopsis{search the manual page names and descriptions} %\usage{unix_apropos([subject])} %\description % Runs "man -k" to get a list of manpages whose names match \var{subject} % and display the result in a buffer in \sfun{man_mode} %\seealso{unix_man} %!%- public define unix_apropos() { variable subj; if (1 == _NARGS) subj = (); else subj = read_mini ("apropos", "", ""); subj = "-k " + subj; keep_history = 1; man (subj); } public define unix_whatis() { push_spot; variable ro = is_readonly(), mo = buffer_modified(), word = purge_escapes(get_word("-A-Za-z0-9_.:\e[]0-9")); eol; set_readonly(0); push_visible_mark; newline; word = strtrim_beg(word, "-"); % strip '-' from options () = run_shell_cmd(strcat("whatis ", word)); message("hit any key to continue"); update_sans_update_hook(0); % wait for any key and discard the key sequence ( , ) = get_key_binding(); del_region; set_readonly(ro); set_buffer_modified_flag(mo); pop_spot; } %}}} %{{{ keybindings & menu ifnot (keymap_p (mode)) { copy_keymap (mode, "view"); definekey ("man_follow", "^M", mode); definekey ("man_go_back", "l", mode); definekey ("man_go_forward", ";", mode); definekey ("unix_man", "g", mode); definekey ("unix_man", "m", mode); definekey ("unix_man", "u", mode); definekey ("unix_apropos", "i", mode); definekey ("unix_apropos", "a", mode); definekey ("unix_whatis", "w", mode); definekey ("man_next_section", "n", mode); definekey ("man_previous_section", "p", mode); definekey ("man_next_reference", "\t", mode); definekey ("man_previous_reference", Key_Shift_Tab, mode); definekey ("man_next_reference", "f", mode); definekey ("man_previous_reference", "b", mode); definekey ("man_goto_section", "s", mode); } set_help_message("(M)anpage, (A)propos, (W)hatis, (L)ast page, (N)ext section, (P)revious section", "man"); static variable numbers = "123456789abcdefghijklmnop"; static define man_jump_callback(popup) { variable section_list= get_blocal_var("section_list"), sections = get_blocal_var("sections"), number; _for number (0, sections, 1) { menu_append_item (popup, strlow (sprintf("&%c %s", numbers[number], section_list[number,0])), &goto_line, atoi(section_list[number,1])); } pop_spot(); } static define man_page_callback(popup) { variable buf; loop (buffer_list ()) { buf = (); if (is_substr(buf, "*Man")) menu_append_item(popup, buf[[5:-2]], &sw2buf, buf); } } static define man_menu(menu) { menu_append_popup (menu, "man pages"); menu_set_select_popup_callback (menu + ".man pages", &man_page_callback); menu_append_popup (menu, "§ion"); menu_set_select_popup_callback(menu+".§ion", &man_jump_callback); menu_append_item (menu, "&go to page", "unix_man"); menu_append_item (menu, "&apropos", "unix_apropos"); menu_append_item (menu, "&what is", "unix_whatis"); menu_append_item (menu, "&close man buffers", "man_cleanup"); } %}}} %{{{ mouse support static define man_mouse(line, col, but, shift) { switch (but) { case 1: if (re_looking_at (man_pattern)) man_follow; } { case 4: unix_whatis; } { return -1; } % pass wheel scrolling events to the default hook 1; } %}}} %!%+ %\function{man_mode} %\synopsis{Mode for reading man pages} %\usage{man->man_mode()} %\description % The following man commands are available in the buffer. % \var{TAB} move to next manpage reference % \var{ENTER} follow a manpage reference % \var{g} Prompt to retrieve a new manpage. % \var{l} Go back to last visited manpage in history. % \var{;} Go forward in history. % \var{p} Jump to previous manpage section. % \var{n} Jump to next manpage section. % \var{s} Go to a manpage section. % \var{w} Run \sfun{whatis} on the word at point % \var{a} Call \sfun{unix_apropos} % \var{q} Deletes the manpage window, kill its buffer. % \var{h} Give help for man_mode %\seealso{unix_man} %!%- static define man_mode() { view_mode (); use_keymap (mode); _set_buffer_flag(0x1000); set_mode(mode, 0); set_buffer_hook("mouse_up", &man_mouse); mode_set_mode_info(mode, "init_mode_menu", &man_menu); run_mode_hooks("man_mode_hook"); } %{{{ completions initialisation static define man_read_completions() { variable fp = fopen(dircat(Jed_Home_Directory, "man_completions"), "r"); if (fp == NULL) return; () = fread_bytes(&man_completions, 1000000, fp); () = fclose(fp); } public define man_make_completions() { flush("initializing completions"); variable fp = popen ("(whatis -w '*' | sed -e 's/).*/),/' | tr -d '\n') 2> /dev/null", "r"); if (fp == NULL) return; () = fread_bytes(&man_completions, 1000000, fp); () = pclose(fp); fp = fopen(dircat(Jed_Home_Directory, "man_completions"), "w"); if (fp == NULL) return; ()=fputs(man_completions, fp); () = fclose(fp); } runhooks("man_init_hook"); if(Man_Complete_Whatis) { if(1 != file_status (dircat(Jed_Home_Directory, "man_completions"))) man_make_completions(); else man_read_completions(); } %}}} jedmodes-2.5.7/utf8helper/0000755000175400017500000000000011137355700013672 5ustar mildegmjedmodes-2.5.7/utf8helper/utf8helper.sl0000644000175400017500000003740011137355700016324 0ustar mildegm% utf8-helper.sl: converting latin1 <-> utf8. % % Copyright (c) 2007 John E. Davis, Joerg Sommer, Guenter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Code based on examples in Help>Browse Docs>utf8 by JED and a posting % by Joerg Sommer to the jed-users list. % % The functions in this mode require slang2 to work properly but % should also work without UTF-8 support. % % Currently, only utf8 and latin1 encodings are supported. % Other encodings need an external recoding tool (e.g. `recode` or `iconv` % (see `recode --list` or `iconv --list` for a list of supported encodings)). % % Auto-detection of the character encoding is possible with e.g. the % Python chardet module (python-chardet Debian package). % % % Usage % ----- % % Place in the jed library path. % % To activate the auto-conversion, set the custom variables (see online % help for UTF8Helper_Read_Autoconvert and UTF8Helper_Write_Autoconvert) % and require the mode in your jed.rc file. % % A nontrivial customization would be:: % % % convert all files to active encoding % variable UTF8Helper_Read_Autoconvert = 1; % % reconvert auto-converted files, ask if Jed runs in UTF-8 mode % if (_slang_utf8_ok) % variable UTF8Helper_Write_Autoconvert = -1; % else % variable UTF8Helper_Write_Autoconvert = 1; % require("utf8helper"); % % Versions % -------- % % 1.1 2007-06-01 first public version % 1.2 2007-07-25 customizable activation of hooks, % renamed *lat1* to *latin1*, % 1.2.1 2007-07-26 utf8helper_read_hook(): reset buffer_modified_flag % 1.2.2 2007-09-20 convert region instead of buffer if visible region is % defined % 1.2.3 2007-09-24 bugfix in utf8_to_latin1(): did not convert two (or more) % high-bit chars in a row in UTF8 mode (report P. Boekholt) % and latin1_to_utf8(): similar problem in non-UTF8 mode. % 1.2.4 2008-01-22 helper fun register_autoconvert_hooks() % (called at end of script if evaluated first time). % 1.2.5 2008-01-25 remove dependency on datutils.sl and sl_utils.sl % 1.2.6 2008-05-05 no more dependencies % patches by Paul Boekholt: % reset CASE_SEARCH also after failure, % strtrans_utf8_to_latin1("") now works, % has_invalid_chars(): initialize return value. % 1.2.7 2008-05-13 Convert Python (and Emacs) special encoding comment. % 1.2.8 2008-05-20 Fix encoding comment conversion. % 1.2.9 2008-08-25 name has_invalid_chars() -> utf8helper_find_invalid_char() % and make it public, % UTF8Helper_Read_Autoconvert == -2 (warn) setting % 1.2.10 2009-01-26 Convert LaTeX inputenc options % TODO: use the iconv module (which is unfortunately undocumented) % Customisation % ------------- %!%+ %\variable{UTF8Helper_Read_Autoconvert} %\synopsis{Convert new-found file to active encoding?} %\usage{variable UTF8Helper_Read_Autoconvert = 0} %\description % Should a file be converted to the active encoding after opening? % (in a "_jed_find_file_after_hooks" hook) % % Possible values: % 0 -- never % 1 -- always % -1 -- ask user if file contains invalid chars % -2 -- warn user if file contains invalid chars %\notes % The "native encoding" is utf8 if Jed runs in UTF-8 mode. % It is assumed to be latin1 else. % % If this variable has a non-zero value when utf8helper is evaluated, % a hook is added to _jed_find_file_after_hooks (see Help>Browse Docs>hooks) %\seealso{UTF8Helper_Write_Autoconvert, latin1_to_utf8, utf8_to_latin1, _slang_utf8_ok} %!%- custom_variable("UTF8Helper_Read_Autoconvert", 0); %!%+ %\variable{UTF8Helper_Write_Autoconvert} %\synopsis{Reconvert file to original encoding before writing?} %\usage{variable UTF8Helper_Write_Autoconvert = 0} %\description % Should a file be reconverted in a "_jed_save_buffer_before_hooks" hook, % if it was auto-converted after reading? % % Possible values: % 0 -- never % 1 -- always % -1 -- ask user % %\seealso{UTF8Helper_Read_Autoconvert, latin1_to_utf8, utf8_to_latin1} %!%- custom_variable("UTF8Helper_Write_Autoconvert", 0); % Namespace % --------- % provide("utf8helper"); % put at end, to enable the idempotent behaviour of % hook-setting implements("utf8helper"); % Functions % --------- %!%+ %\function{latin1_to_utf8} %\synopsis{Convert a buffer from latin-1 to UTF-8 encoding} %\usage{latin1_to_utf8()} %\description % Scan the active buffer or visible region and convert latin1 encoded % characters into their utf8 encoded unicode equivalent. % % If no visible region is defined, set the buffer local variable "encoding" % to "utf8". %\notes % To prevent to overshoot the mark, no conversion is done if the "encoding" % blocal var is already "utf8". This check is skipped if a visible region % is defined: take care for yourself! %\seealso{utf8_to_latin1} %!%- public define latin1_to_utf8() { variable ch, convert_region = is_visible_mark(); if (convert_region) narrow_to_region(); else if (get_blocal_var("encoding", "") == "utf8") { message("Buffer is already UTF-8 encoded"); return; } push_spot_bob(); if (_slang_utf8_ok) { do { skip_chars("[[:print:][:cntrl:]]"); ch = what_char(); if (ch < 0) { del(); insert_char(-ch); go_left_1(); } } while (right(1)); } else { do { skip_chars("\d001-\d127"); ch = what_char(); if (andelse{ch >= 128}{ch < 192}) { del(); insert_char(194); insert_char(ch); go_left_1(); } else if (andelse{ch >= 192}{ch < 256}) { del(); insert_char(195); insert_char(ch-64); go_left_1(); } } while (right(1)); } % LaTeX inputenc pattern: bob(); % replace("\\usepackage[latin1]{inputenc}", % "\\usepackage[utf8]{inputenc}"); if (re_fsearch("\(\\usepackage ?\[.*\)latin1\(.*\] ?{inputenc}\)"R)) () = replace_match("\1utf8\2"R, 0); % Python code comment pattern: "coding[=:]\s*([-\w.]+)" % aliases: iso-8859-1, iso8859-1, 8859, cp819, latin, latin_1, latin1, L1 bob(); if (orelse {re_fsearch("coding[:=] *iso-?8859-1")} {re_fsearch("coding[:=] *8859")} {re_fsearch("coding[:=] *cp819")} {re_fsearch("coding[:=] *latin[-_]?1")} {re_fsearch("coding[:=] *latin")} {re_fsearch("coding[:=] *L1")} ) () = replace_match("coding: utf8", 1); pop_spot(); if (convert_region) widen_region(); else define_blocal_var("encoding", "utf8"); } %!%+ %\function{utf8_to_latin1} %\synopsis{Convert a buffer from utf8 to latin1 encoding} %\usage{utf8_to_latin1()} %\description % Scan the active buffer or visible region and convert latin1 encoded % characters into their utf8 equivalent. % % Set the buffer-local variable "encoding" to "latin1". %\notes % If Jed is not in utf8 mode, data loss can occure if the buffer or region is % not in utf8 encoding (and the buffer-local variable "encoding" is not set): % characters '\d194' and '\d195' are deleted. %\seealso{latin1_to_utf8} %!%- public define utf8_to_latin1 () { variable ch, convert_region = is_visible_mark(); if (convert_region) narrow_to_region(); else if (get_blocal_var("encoding", "utf8") != "utf8") throw RunTimeError, "Buffer is not utf8 encoded"; push_spot_bob(); if (_slang_utf8_ok) { do { ch = what_char(); if ((ch >= 128) and (ch < 256)) { del(); insert_byte(ch); go_left_1(); } } while ( right(1) ); } else { variable old_case_search = CASE_SEARCH; CASE_SEARCH = 1; try { while (fsearch_char(194)) % '‚' del(); bob(); while (fsearch_char(195)) { % 'ƒ' del(); ch = what_char(); del(); insert_byte(ch+64); } } finally { CASE_SEARCH = old_case_search; } } bob(); % LaTeX inputenc pattern: % replace("\\usepackage[utf8]{inputenc}", % "\\usepackage[latin1]{inputenc}"); if (re_fsearch("\(\\usepackage ?\[.*\)utf8\(.*\] ?{inputenc}\)"R)) () = replace_match("\1latin1\2"R, 0); % Python code comment pattern: "coding[=:]\s*([-\w.]+)" % aliases: utf_8, U8, UTF, utf8 % we support just the most frequently used: if (orelse {re_fsearch("coding[:=] *utf_?8")} {re_fsearch("coding[:=] *UTF")} {re_fsearch("coding[:=] *U8")} ) () = replace_match("coding: utf8", 1); pop_spot (); if (convert_region) widen_region(); else define_blocal_var("encoding", "latin1"); } % String conversion % ----------------- % Taken from digraph.sl (where it is private), renamed and generalized by GM % It now works also outside utf8 mode public define strtrans_latin1_to_utf8(str) { variable ch, new_str = "", charlist = {}; % simpler and faster implementation if UTF-8 support is active: if (_slang_utf8_ok) { foreach ch (str) new_str += char(ch); return new_str; } % failsave version else: foreach ch (str) { if (andelse{ch >= 128}{ch < 192}) new_str += char(194) + char(ch); else if (andelse{ch >= 192}{ch < 256}) new_str += char(195) + char(ch-64); else new_str += char(ch); } return new_str; } public define strtrans_utf8_to_latin1(str) { if (str == "") return ""; variable ch, shift = 0, charlist = {}; foreach ch (str) { switch (ch) { case 194: continue; } { case 195: shift = 64; continue; } list_append(charlist, ch+shift); shift = 0; } return array_to_bstring(typecast([__push_list(charlist)], UChar_Type)); } % Hooks for automatic conversion % ------------------------------ % From David Goodger in http://www.pycheesecake.org/wiki/ZenOfUnicode: % % - The first byte of a non-ASCII character encoded in UTF-8 is % always in the range 0xC0 to 0xFD, and all subsequent bytes are in % the range 0x80 to 0xBF. The bytes 0xFE and 0xFF are never used. %!%+ %\function{utf8helper_find_invalid_char} %\synopsis{Check for non-printable characters in current buffer} %\usage{utf8helper_find_invalid_char()} %\description % Check the current buffer for "invalid" (wrong encoded) characters. % % Can be used to test if a file is valid UTF8 (in utf8-mode) or % if it is (most likely) UTF8 encoded when Jed is not in utf8-mode. % % Leaves the point at the first "invalid" char or bob. %\seealso{latin1_to_utf8, utf8_to_latin1, _slang_utf8_ok} %!%- public define utf8helper_find_invalid_char() { variable ch, result = 0; if (_slang_utf8_ok) { % bob(); skip_chars("[[:print:][:cntrl:]]"); result = not(eobp()); % bob(); return result; } % Jed with latin-* encoding: % poor mans test: '\194' == '\x82' == 'Â' or '\195' == '\x83' == 'Ã' % followed by high-bit character (ch >= 128). % While this is a completely valid string sequence in latin-1 encoding, % is is highly indicative of utf8 encoded strings. foreach ch ([194, 195]) { bob(); if (fsearch_char(ch) and right(1)) { result = what_char() >= 128; break; } } return result; } % convert encoding to native encoding (or vice versa) static define autoconvert(to_native) { % unset readonly flag and file binding, % so that we can edit without further questions. variable file, dir, name, flags; (file, dir, name, flags) = getbuf_info(); setbuf_info("", dir, name, flags & ~0x8); if (to_native) { if (_slang_utf8_ok) latin1_to_utf8(); else utf8_to_latin1(); } else { % convert from native encoding to alternative if (_slang_utf8_ok) utf8_to_latin1(); else latin1_to_utf8(); } % reset the buffer info setbuf_info(file, dir, name, flags); } static define utf8helper_read_hook() { variable msg, read_autoconvert = get_blocal_var("utf8helper_read_autoconvert", UTF8Helper_Read_Autoconvert); % show("utf8helper_read_hook() called. read_autoconvert == ", read_autoconvert); % read_autoconvert == 0 means "do not convert": !if (read_autoconvert) return; % Check for out of place encoding - no need to convert if there is no % invalid character. % utf8helper_find_invalid_char() moves point to first invalid char push_spot_bob(); !if (utf8helper_find_invalid_char()) { % message("no offending chars"); read_autoconvert = 0; } % ask user if read_autoconvert is -1, warn if it is -2 if (read_autoconvert == -1) { msg = ["Buffer seems to contain UTF-8 chars. Convert to iso-latin-1", "Buffer contains high-bit chars. Convert to UTF-8"]; read_autoconvert = get_y_or_n(msg[_slang_utf8_ok]); % and store the answer define_blocal_var("utf8helper_read_autoconvert", read_autoconvert); } else if (read_autoconvert == -2) { msg = ["Buffer seems to contain UTF-8 char", "Buffer contains high-bit char"]; vmessage(msg[_slang_utf8_ok] + " in line %d! (and maybe more)", what_line()); read_autoconvert = 0; } pop_spot(); % abort if no invalid chars or user decided to skip autoconversion !if (read_autoconvert) return; % convert encoding (to_native = 1) autoconvert(1); % mark for re-conversion before writing: if (not(blocal_var_exists("utf8helper_write_autoconvert"))) define_blocal_var("utf8helper_write_autoconvert", UTF8Helper_Write_Autoconvert); } static define utf8helper_write_hook(file) { % Get autoconvert option: % Default is 0, so do not convert if it is not autoconverted % TODO: consider the case where the user always wants a definite encoding. variable write_autoconvert = get_blocal_var("utf8helper_write_autoconvert", 0); % ask user if default is -1 if (write_autoconvert == -1) { write_autoconvert = get_y_or_n("Re-convert buffer encoding before saving"); % and store the result define_blocal_var("utf8helper_write_autoconvert", write_autoconvert); } if (write_autoconvert) autoconvert(0); } static define utf8helper_restore_hook(file) { if (get_blocal_var("utf8helper_write_autoconvert", 0)) autoconvert(1); } % register the autoconvert hooks % ------------------------------ % % If % * this file is evaluated the first time and % * the custom variables are non-zero % :: !if (_featurep("utf8helper")) { if (UTF8Helper_Read_Autoconvert) append_to_hook("_jed_find_file_after_hooks", &utf8helper_read_hook); if (UTF8Helper_Write_Autoconvert) { append_to_hook("_jed_save_buffer_before_hooks", &utf8helper_write_hook); append_to_hook("_jed_save_buffer_after_hooks", &utf8helper_restore_hook); } } % announce the feature now provide("utf8helper"); % Joerg Sommer also wrote: % And I've written some functions for UTF-8 features. Maybe they get a menu % entry "Edit->UTF-8 specials". % % Suggestion: (place them under Edit>Re&gion Ops, as they act on regions) % static define insert_after_char(char) { narrow_to_region(); try { bob(); while (right(1)) insert_char(char); } finally { widen_region(); } } % http://www.utf8-zeichentabelle.de/unicode-utf8-table.pl static define stroke() { insert_after_char(0x336); } static define underline() { insert_after_char(0x332); } static define double_underline() { insert_after_char(0x333); } static define overline() { insert_after_char(0x305); } static define double_overline() { insert_after_char(0x33f); } % the menu: static define utf8helper_load_popup_hook(menubar) { menu_insert_item(4, "Global.&Edit.Re&gion Ops", "&O Double Overline", "utf8helper->double_overline"); menu_insert_item(4, "Global.&Edit.Re&gion Ops", "&o Overline", "utf8helper->overline"); menu_insert_item(4, "Global.&Edit.Re&gion Ops", "&= Double Underline", "utf8helper->double_underline"); menu_insert_item(4, "Global.&Edit.Re&gion Ops", "&- Underline", "utf8helper->underline"); menu_insert_item(4, "Global.&Edit.Re&gion Ops", "&x Stroke", "utf8helper->stroke"); } if (_slang_utf8_ok) append_to_hook("load_popup_hooks", &utf8helper_load_popup_hook); jedmodes-2.5.7/life/0000755000175400017500000000000010611415721012517 5ustar mildegmjedmodes-2.5.7/life/life.sl0000644000175400017500000001255410340314130013774 0ustar mildegm% -*- mode:Slang; mode:folding -*- % % CONWAY'S GAME OF LIFE % % Copyright (c) 2000 John E. Davis, Francesc Rocher % Released under the terms of the GNU General Public License (ver. 2 or later) % $Id: life.sl,v 1.13 2000/04/07 12:36:30 rocher Exp $ % % %{{{ % % DESCRIPTION % An implementation of the Game of Life for jed. % # autoload("life", "life"); add_completion("life"); # % % AUTHORS % John E. Davis % Francesc Rocher % Feel free to send comments, suggestions or improvements. % % ------------------------------------------------------------------------ %}}} implements ("life"); % PRIVATE VARIABLES %{{{ private variable height = SCREEN_HEIGHT-4, width = SCREEN_WIDTH-2, cell = Char_Type[width, height], top_line = "", bottom_line = "", msg = "space:start/stop n:next c:clear o:draw r:random -,0,+:delay q:quit", dollar = 0, delay = 150, left, right, up, down; %}}} % PRIVATE FUNCTIONS private define life_dump () %{{{ { variable y, s = Char_Type [width, height]; s [*,*] = ' '; s [where (cell)] = 'o'; set_readonly (0); erase_buffer (); insert (top_line); for (y = 0; y < height; y++) { insert_char ('|'); foreach (s [*,y]) insert_char (); insert ("|\n"); } insert (sprintf ("`-:%04d:-", delay)); insert (bottom_line); bob (); set_readonly (1); update (1); message (msg); } %}}} private define make_left (n) %{{{ { variable a = Int_Type [n]; a [0] = n-1; a [[1:]] = [0:n-2]; return a; } %}}} private define make_right (n) %{{{ { variable a = Int_Type [n]; a [[0:n-2]] = [1:n-1]; a [-1] = 0; return a; } %}}} % PUBLIC FUNCTIONS public define life_quit () %{{{ { set_buffer_modified_flag (0); delbuf ("*LIFE*"); DOLLAR_CHARACTER = dollar; local_unsetkey ("0"); local_unsetkey ("-"); local_unsetkey ("+"); local_unsetkey ("c"); local_unsetkey ("."); local_unsetkey ("o"); local_unsetkey (" "); local_unsetkey ("n"); local_unsetkey ("r"); local_unsetkey ("q"); } %}}} public define life_clear () %{{{ { cell [*,*] = 0; life_dump (); } %}}} public define life_state () %{{{ { variable x = what_column () - 2; variable y = what_line () - 2; if ((0 <= x) and (x < width) and (0 <= y) and (y < height)) { variable c = what_char (); if (c == 'o') { c = ' '; cell [x,y] = 0; } else { c = 'o'; cell [x,y] = 1; } set_readonly (0); del (); insert (sprintf ("%c",c)); set_readonly (1); } } %}}} public define life_next () %{{{ { variable b, i; variable middle = [:]; b = (cell [left,up] + cell [middle,up] + cell [right,up] + cell [left,middle] + cell [right,middle] + cell [left,down] + cell [middle,down] + cell [right,down]); b = typecast (b, Char_Type); i = where ((b < 2) or (b > 3) or ((b == 2) and (cell == 0))); b [i] = 0; b [where (b)] = 1; cell = b; life_dump (); } %}}} public define life_delay (d) %{{{ { if (d) { delay += d * 25; if (delay < 0) delay = 0; } else delay = 0; } %}}} public define life_random () %{{{ { variable x, y; () = random (-1,100); for (x = 0; x < width; x++) for (y = 0; y < height; y++) cell [x,y] = typecast ((random (0,99) < 15), Char_Type); life_dump (); } %}}} public define life_start () %{{{ { variable stop = 0, k, q = 0; while (stop == 0) { life_next (); if (input_pending (0)) { k = getkey (); switch (k) { case 'q': stop = 1; q = 1; } { case 'r': life_random (); } { case ' ': stop = 1; } { case '0': life_delay (0); } { case '-': life_delay (-1); } { case '+': life_delay (1); } } usleep (delay); } if (q) life_quit (); } %}}} %!%+ %\function{life} %\synopsis{Conway's Game of Life} %\usage{Void_Type life ();} %\description % This is an implementation of the Conway's Game of Life for jed. %!%- public define life () %{{{ { dollar = DOLLAR_CHARACTER; DOLLAR_CHARACTER = 0; left = make_left (width); right = make_right (width); up = make_left (height); down = make_right (height); pop2buf ("*LIFE*"); onewindow (); !if (strlen (top_line)) { life_random (); top_line = ".--- Conway's Game of Life "; loop (width-26) top_line += "-"; top_line += ".\n"; bottom_line = ""; loop (width-8) bottom_line += "-"; bottom_line += "'"; local_setkey ("life_delay(0)", "0"); local_setkey ("life_delay(-1)", "-"); local_setkey ("life_delay(1)", "+"); local_setkey ("life_clear", "c"); local_setkey ("life_state", "."); local_setkey ("life_state", "o"); local_setkey ("life_start", " "); local_setkey ("life_next", "n"); local_setkey ("life_random", "r"); local_setkey ("life_quit", "q"); } life_start (); } %}}} jedmodes-2.5.7/print/0000755000175400017500000000000011262360626012742 5ustar mildegmjedmodes-2.5.7/print/simpleprint.sl0000664000175400017500000000434011140527375015654 0ustar mildegm% print.sl --- a printing mode for jed ---% print.sl % % Copyright (c) 2005 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % very basic, but allows to send the buffer content to the printer % with a key shortcut or menu item. % % Versions % % 2004-11-15 0.1 first published version % 2005-11-21 0.2 no autoload with make_ini() % to avoid conflicts with other print modes % 2009-01-30 0.3 rename to simpleprint.sl, as there is another print.sl % coming with slsh % % Usage % ----- % % Example:: % % autoload("print_buffer", "print.sl"); % setkey("print_buffer", "^P"); % setkey("print_buffer", Key_F9); % % define print_popup_hook(menubar) { % menu_insert_separator(6, "Global.&File"); % menu_insert_item(7, "Global.&File", "&Print Buffer", "print_buffer"); % } % append_to_hook ("load_popup_hooks", &print_popup_hook); %!%+ %\function{print_buffer} %\synopsis{sends the buffer content to the lineprinter} %\usage{Void print_buffer ()} %\description % The print_buffer command prints the content of the active buffer. % It does not do any formatting except sending an initializating string % "PrintInitString" to the printer, if this custom variable is defined. %\notes % print_buffer uses the 'lpr' command on unix and the 'print' command on DOS %\seealso{shell_perform_cmd} %!%- custom_variable("PrintInitString", ""); #ifdef IBMPC_SYSTEM custom_variable("PrintCommand", "print"); shell_perform_cmd("print /D:PRN", 0); % initialize printer #else custom_variable("PrintCommand", "lpr"); #endif define print_buffer () { variable print_command = read_mini("Print the current buffer with:", "", PrintCommand); !if (strlen(print_command)) return; push_spot (); #ifdef IBMPC_SYSTEM variable dir = getenv ("TMP"); if (dir == NULL) dir = "C:"; variable printfile = dircat (dir, "print.tmp"); () = write_string_to_file (PrintInitString, printfile); mark_buffer; () = append_region_to_file(printfile); shell_perform_cmd("print c:\\temp\\print.tmp", 0); #else variable status; mark_buffer (); status = pipe_region ("lpr"); if (status) error ("lpr failed."); #endif pop_spot (); } jedmodes-2.5.7/print/simpleprint.sl~0000664000175400017500000000434011140527321016041 0ustar mildegm% print.sl --- a printing mode for jed ---% print.sl % % Copyright (c) 2005 Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % very basic, but allows to send the buffer content to the printer % with a key shortcut or menu item. % % Versions % % 2004-11-15 0.1 first published version % 2005-11-21 0.2 no autoload with make_ini() % to avoid conflicts with other print modes % UNPUB 0.3 rename to simpleprint.sl, as there is another print.sl % coming with slsh % % Usage % ----- % % Example:: % % autoload("print_buffer", "print.sl"); % setkey("print_buffer", "^P"); % setkey("print_buffer", Key_F9); % % define print_popup_hook(menubar) { % menu_insert_separator(6, "Global.&File"); % menu_insert_item(7, "Global.&File", "&Print Buffer", "print_buffer"); % } % append_to_hook ("load_popup_hooks", &print_popup_hook); %!%+ %\function{print_buffer} %\synopsis{sends the buffer content to the lineprinter} %\usage{Void print_buffer ()} %\description % The print_buffer command prints the content of the active buffer. % It does not do any formatting except sending an initializating string % "PrintInitString" to the printer, if this custom variable is defined. %\notes % print_buffer uses the 'lpr' command on unix and the 'print' command on DOS %\seealso{shell_perform_cmd} %!%- custom_variable("PrintInitString", ""); #ifdef IBMPC_SYSTEM custom_variable("PrintCommand", "print"); shell_perform_cmd("print /D:PRN", 0); % initialize printer #else custom_variable("PrintCommand", "lpr"); #endif define print_buffer () { variable print_command = read_mini("Print the current buffer with:", "", PrintCommand); !if (strlen(print_command)) return; push_spot (); #ifdef IBMPC_SYSTEM variable dir = getenv ("TMP"); if (dir == NULL) dir = "C:"; variable printfile = dircat (dir, "print.tmp"); () = write_string_to_file (PrintInitString, printfile); mark_buffer; () = append_region_to_file(printfile); shell_perform_cmd("print c:\\temp\\print.tmp", 0); #else variable status; mark_buffer (); status = pipe_region ("lpr"); if (status) error ("lpr failed."); #endif pop_spot (); } jedmodes-2.5.7/md5/0000755000175400017500000000000010461125576012276 5ustar mildegmjedmodes-2.5.7/md5/md5.sl0000644000175400017500000002107010274106646013322 0ustar mildegm% ------------------------------------------- -*- mode:SLang; mode:folding; -*- % % MD5 FOR JED % % Copyright (c) 2002 Francesc Rocher % Released under the terms of the GNU General Public License (ver. 2 or later) % % $Id: md5.sl,v 1.5 2002/03/03 12:50:06 rocher Exp $ % % --------------------------------------------------------------------- %{{{ % % DESCRIPTION % MD5 message digest algorithm implemented in SLang. It can compute % the MD5 finger print of a string, a region or the entire current % buffer. For a really accurate description of how it works, see RFC % 1321 at http://www.ietf.org/rfc/rfc1321.txt. % % INSTALLATION % Copy this file on a place where JED can load it, e.g. JED_ROOT/lib, % and issue the command 'require( "md5" );'. You can also put the % 'require' command on your '.jedrc' file. % % USAGE % Once installed, simply invoke any of the public functions defined % below: % % o String_Type md5_string( String_Type ) % o String_Type md5_region() % o String_Type md5_buffer() % % CHANGELOG % % March 2002 % o First public release. % % AUTHOR % Francesc Rocher % Feel free to send comments, suggestions or improvements. % % ------------------------------------------------------------------------ %}}} implements( "md5" ); % % Convert a string to an array of 16-word blocks. % Append padding bits and the length of the original string (see the RFC1321, % "The MD5 Message-Digest Algorithm"). % private define get_blocks( str ) %{{{ { variable n = (( strlen( str ) + 8 ) shr 6 ) + 1; variable block = Integer_Type[n*16]; variable i, k; block[*] = 0; i=0; loop( strlen( str )) { k = int( substr( str, 1+i, 1 )); block[i shr 2] |= k shl (( i mod 4 ) * 8 ); i++; } block[i shr 2] |= 0x80 shl (( i mod 4 ) * 8 ); block[n*16 - 2] = strlen( str ) * 8; return( block ); } %}}} % % Bitwise rotate a 32-bit number to the left. % private define rotate_left( x, n ) %{{{ { ( x shr ( 32 - n )) & ~( 0xFFFFFFFF shl n ); return(( x shl n ) | () ); } %}}} % % Transformations. % private define FF( a, b, c, d, Xi, s, ac ) %{{{ { a + (( b & c ) | ( ~b & d )) + Xi + ac; return( rotate_left( (), s ) + b ); } %}}} private define GG( a, b, c, d, Xi, s, ac ) %{{{ { a + (( b & d ) | ( c & ~d )) + Xi + ac; return( rotate_left( (), s ) + b ); } %}}} private define HH( a, b, c, d, Xi, s, ac ) %{{{ { a + ( b xor c xor d ) + Xi + ac; return( rotate_left( (), s ) + b ); } %}}} private define II( a, b, c, d, Xi, s, ac ) %{{{ { a + ( c xor ( b | ~d )) + Xi + ac; return( rotate_left( (), s ) + b ); } %}}} % % Print a message digest in hexadecimal. % private define digest( a, b, c, d ) %{{{ { variable i, j, str = ""; variable x = [ a, b, c, d ]; $0 = "0123456789abcdef"; for( i = 0; i < 4; ++i ) { for( j = 0; j < 4; j++ ) { $1 = substr( $0, 1 + (( x[i] shr ( j * 8 + 4 )) & 0x0F ), 1 ); $2 = substr( $0, 1 + (( x[i] shr ( j * 8 )) & 0x0F ), 1 ); str += $1 + $2; } } return( str ); } %}}} %!%+ %\function{md5} %\synopsis{md5} %\usage{String_Type md5( String_Type );} %\description % Return the hex representation of the MD5 of the given string. %\seealso{md5_region, md5_buffer} %!%- public define md5( str ) %{{{ { variable X = get_blocks( str ); variable a = 0x67452301; variable b = 0xefcdab89; variable c = 0x98badcfe; variable d = 0x10325476; variable a0, b0, c0, d0; variable i; for( i = 0; i < length( X ); i += 16 ) { a0 = a; b0 = b; c0 = c; d0 = d; % Round 1 a = FF( a, b, c, d, X[i+ 0], 7, 0xd76aa478 ); d = FF( d, a, b, c, X[i+ 1], 12, 0xe8c7b756 ); c = FF( c, d, a, b, X[i+ 2], 17, 0x242070db ); b = FF( b, c, d, a, X[i+ 3], 22, 0xc1bdceee ); a = FF( a, b, c, d, X[i+ 4], 7, 0xf57c0faf ); d = FF( d, a, b, c, X[i+ 5], 12, 0x4787c62a ); c = FF( c, d, a, b, X[i+ 6], 17, 0xa8304613 ); b = FF( b, c, d, a, X[i+ 7], 22, 0xfd469501 ); a = FF( a, b, c, d, X[i+ 8], 7, 0x698098d8 ); d = FF( d, a, b, c, X[i+ 9], 12, 0x8b44f7af ); c = FF( c, d, a, b, X[i+10], 17, 0xffff5bb1 ); b = FF( b, c, d, a, X[i+11], 22, 0x895cd7be ); a = FF( a, b, c, d, X[i+12], 7, 0x6b901122 ); d = FF( d, a, b, c, X[i+13], 12, 0xfd987193 ); c = FF( c, d, a, b, X[i+14], 17, 0xa679438e ); b = FF( b, c, d, a, X[i+15], 22, 0x49b40821 ); % Round 2 a = GG( a, b, c, d, X[i+ 1], 5, 0xf61e2562 ); d = GG( d, a, b, c, X[i+ 6], 9, 0xc040b340 ); c = GG( c, d, a, b, X[i+11], 14, 0x265e5a51 ); b = GG( b, c, d, a, X[i+ 0], 20, 0xe9b6c7aa ); a = GG( a, b, c, d, X[i+ 5], 5, 0xd62f105d ); d = GG( d, a, b, c, X[i+10], 9, 0x2441453 ); c = GG( c, d, a, b, X[i+15], 14, 0xd8a1e681 ); b = GG( b, c, d, a, X[i+ 4], 20, 0xe7d3fbc8 ); a = GG( a, b, c, d, X[i+ 9], 5, 0x21e1cde6 ); d = GG( d, a, b, c, X[i+14], 9, 0xc33707d6 ); c = GG( c, d, a, b, X[i+ 3], 14, 0xf4d50d87 ); b = GG( b, c, d, a, X[i+ 8], 20, 0x455a14ed ); a = GG( a, b, c, d, X[i+13], 5, 0xa9e3e905 ); d = GG( d, a, b, c, X[i+ 2], 9, 0xfcefa3f8 ); c = GG( c, d, a, b, X[i+ 7], 14, 0x676f02d9 ); b = GG( b, c, d, a, X[i+12], 20, 0x8d2a4c8a ); % Round 3 a = HH( a, b, c, d, X[i+ 5], 4, 0xfffa3942 ); d = HH( d, a, b, c, X[i+ 8], 11, 0x8771f681 ); c = HH( c, d, a, b, X[i+11], 16, 0x6d9d6122 ); b = HH( b, c, d, a, X[i+14], 23, 0xfde5380c ); a = HH( a, b, c, d, X[i+ 1], 4, 0xa4beea44 ); d = HH( d, a, b, c, X[i+ 4], 11, 0x4bdecfa9 ); c = HH( c, d, a, b, X[i+ 7], 16, 0xf6bb4b60 ); b = HH( b, c, d, a, X[i+10], 23, 0xbebfbc70 ); a = HH( a, b, c, d, X[i+13], 4, 0x289b7ec6 ); d = HH( d, a, b, c, X[i+ 0], 11, 0xeaa127fa ); c = HH( c, d, a, b, X[i+ 3], 16, 0xd4ef3085 ); b = HH( b, c, d, a, X[i+ 6], 23, 0x4881d05 ); a = HH( a, b, c, d, X[i+ 9], 4, 0xd9d4d039 ); d = HH( d, a, b, c, X[i+12], 11, 0xe6db99e5 ); c = HH( c, d, a, b, X[i+15], 16, 0x1fa27cf8 ); b = HH( b, c, d, a, X[i+ 2], 23, 0xc4ac5665 ); % Round 4 a = II( a, b, c, d, X[i+ 0], 6, 0xf4292244 ); d = II( d, a, b, c, X[i+ 7], 10, 0x432aff97 ); c = II( c, d, a, b, X[i+14], 15, 0xab9423a7 ); b = II( b, c, d, a, X[i+ 5], 21, 0xfc93a039 ); a = II( a, b, c, d, X[i+12], 6, 0x655b59c3 ); d = II( d, a, b, c, X[i+ 3], 10, 0x8f0ccc92 ); c = II( c, d, a, b, X[i+10], 15, 0xffeff47d ); b = II( b, c, d, a, X[i+ 1], 21, 0x85845dd1 ); a = II( a, b, c, d, X[i+ 8], 6, 0x6fa87e4f ); d = II( d, a, b, c, X[i+15], 10, 0xfe2ce6e0 ); c = II( c, d, a, b, X[i+ 6], 15, 0xa3014314 ); b = II( b, c, d, a, X[i+13], 21, 0x4e0811a1 ); a = II( a, b, c, d, X[i+ 4], 6, 0xf7537e82 ); d = II( d, a, b, c, X[i+11], 10, 0xbd3af235 ); c = II( c, d, a, b, X[i+ 2], 15, 0x2ad7d2bb ); b = II( b, c, d, a, X[i+ 9], 21, 0xeb86d391 ); a += a0; b += b0; c += c0; d += d0; } return( digest( a, b, c, d )); } %}}} %!%+ %\function{md5_region} %\synopsis{md5_region} %\usage{String_Type md5_region();} %\description % Return the hex representation of the MD5 of the selected region. %\seealso{md5, md5_buffer} %!%- public define md5_region() %{{{ { !if( markp ) { error( "Set mark first." ); } else { return( md5( bufsubstr())); } } %}}} %!%+ %\function{md5_buffer} %\synopsis{md5_buffer} %\usage{String_Type md5_buffer();} %\description % Return the hex representation of the MD5 of the current buffer. %\seealso{md5, md5_region} %!%- public define md5_buffer() %{{{ { push_spot(); bob(); push_mark(); eob(); $0 = md5_region(); pop_spot(); return( $0 ); } %}}} % % MD5 Test suite (see RFC1321). It should be: % % md5( "" ) = d41d8cd98f00b204e9800998ecf8427e % % md5( "a" ) = 0cc175b9c0f1b6a831c399e269772661 % % md5( "abc" ) = 900150983cd24fb0d6963f7d28e17f72 % % md5( "message digest" ) = f96b697d7cb7938d525a2f31aaf161d0 % % md5( "abcdefghijklmnopqrstuvwxyz" ) = c3fcd3d76192e4007dfb496cca67e13b % % md5( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) = % d174ab98d277d9f5a5611c2c9f419d9f % % md5( "12345678901234567890123456789012345678901234567890123456789012345678901234567890" ) = % 57edf4a22be3c955ac49da2e2107b67a % provide( "md5" ); % md5 of this file (not including this line): e615244d73ab7bccab96de5b2938d71c jedmodes-2.5.7/tm/0000755000175400017500000000000011262356614012230 5ustar mildegmjedmodes-2.5.7/tm/tm.sed0000644000175400017500000000254610700212455013342 0ustar mildegm#!/bin/sed -f # # $Id: tm.sed,v 1.2 2007/09/08 16:08:53 boekholt Exp $ # # copyright (c) 2004, 2007 Paul Boekholt # Released under the terms of the GNU GPL (version 2 or later). # # This is a sed script to extract tm documentation from S-Lang sources and # render it as ASCII text. # This matches beginning and end of a tm entry. The entire script # is in this block. /^%!%[+]/,/^%!%-/{ s/%!%[+]// s/%!%[-]/--------------------------------------------------------------/ s/^%/ / # verbatim /^ #v+/,/ #v-/{ s/^ #v+// s/^ #v-// s/^/ / p d } # \var, \ivar, \svar, \ifun, \sfun, \exmp # { and } characters inside parameter lists are escaped # this scripts supports at most one such character s/\\\(var\|ivar\|svar\|ifun\|sfun\|exmp\){\([^}]*\)\\}\([^}]*\)}/`\2}\3'/g s/\\\(var\|ivar\|svar\|ifun\|sfun\|exmp\){\([^}]*\)\\{\([^}]*\)}/`\2{\3'/g s/\\\(var\|ivar\|svar\|ifun\|sfun\|exmp\){\(\(\\}\|[^}]\)*\)}/`\2'/g # \em s/\\em{\(\(\\}\|[^}]\)*\)}/_\1_/g # \NULL, \slang s/\\NULL/NULL/g s/\\slang/S-Lang/g # \function, \variable s/ \\function{\([^}]*\)}/\1/ s/ \\variable{\([^}]*\)}/\1/ # sections s/\\seealso{\([^}]*\)}/\ SEE ALSO\ \1/ s/\\synopsis{\([^}]*\)}/\ SYNOPSIS\ \1/ s/\\usage{\([^}]*\)}/\ USAGE\ \1/ s/\\description/\ DESCRIPTION/ s/\\example/\ EXAMPLE/ s/\\notes/\ NOTES/ # undouble \-es s/\\\\/\\/g # print it! p } # don't print the rest d jedmodes-2.5.7/tm/tm.sl0000644000175400017500000002047010374573636013223 0ustar mildegm% tm.sl % tm documentation parser % % $Id: tm.sl,v 1.5 2006/02/15 09:42:54 milde Exp $ % Keywords: slang, doc, tools % % Copyright (c) 2004 Paul Boekholt, Gnter Milde % Released under the terms of the GNU GPL (version 2 or later). % % This extracts tm documentation from S-Lang sources the *hard* way. It % uses string operations, so it should be easy to port to slrn and slsh. % The tm.sed sed-script is *much* simpler and probably much faster, but % this may be useful for: % % - windows users who don't have sed % - jed hackers who want to preview their tm documentation. % - incorporating into other slang scripts (make_ini) % % 2005-03-18 added tm documentation % new function tm_make_ascii_doc (transfered from make_ini()) % 2005-03-21 rework of tm_make_ascii_doc, tm2ascii called file-wise % -> speedup by factor 3...6 (PB) % 2005-03-22 tm_extract with array_map instead of regexp parsing (GM) % 2005-03-23 block-wise tm2ascii conversion in tm_get_block() % replaced tm_parse() with parse-argument in tm_extract (GM) % 2005-03-31 restructuring code: (avoid temp file for tm-preview) % tm_get_blocks() -- return array of tm-documentation blocks % tm_parse() -- reintroduced % tm_make_ascii_doc() and tm_preview() united to % tm_view([args]) -- args are filenames to extract doc from % no arg: extract from current buffer/region % 2005-11-08 changed _implements() to implements() % 2006-02-15 added support for the \sfun{} attribute % % TODO: let this work for tm-documented C-code too % _debug_info=1; autoload("str_re_replace_all", "strutils"); autoload("arrayread_file", "bufutils"); autoload("get_lines", "csvutils"); autoload("view_mode", "view"); % --- name it provide("tm"); implements("tm"); private variable mode = "tm"; static variable Tm_Doc_Buffer = "*tm doc*"; % convert a string with tm-markup to ASCII representation static define tm2ascii(str) { % indent by 2 spaces. Usually there are already some spaces. % Maybe this should be a regexp replace. % str = str_replace_all(str, "\n", "\n "); variable pos, len; % Blocks (function or variable descriptions) str = str_replace_all(str, "\\done", "-----------------------------------"); % \function or \variable str = str_re_replace_all (str, "\\\\function{\\([^\}]+\\)}", "\\1"); str = str_re_replace_all (str, "\\\\variable{\\([^\}]+\\)}", "\\1"); % \var, \sfun, \em str = str_re_replace_all (str, "\\\\var\{\\([^\}]+\\)\}", "`\\1'"); str = str_re_replace_all (str, "\\\\sfun\{\\([^\}]+\\)\}", "`\\1'"); % this breaks generated doc and tm_preview in jed <= 99.17 % (str, "\\\\var\{\\([^\}]+\\)\}", "\e[1m\\1\e[0m"); str = str_re_replace_all (str, "\\\\em{\\([^\}]+\\)}", "_\\1_"); % sections str = str_re_replace_all (str, "\\\\synopsis{\\([^\}]+\\)}", "\n SYNOPSIS\n \\1"); str = str_replace_all(str, "\n\\synopsis{}", ""); str = str_re_replace_all (str, "\\\\usage{\\([^\}]+\\)}", "\n USAGE\n \\1"); str = str_replace_all(str, "\n\\usage{}", ""); str = str_re_replace_all (str, "\\\\seealso{\\([^\}]+\\)}", "\n SEE ALSO\n \\1"); str = str_replace_all(str, "\n\\seealso{}", ""); str = str_replace_all(str, "\\example", "\n EXAMPLE"); str = str_replace_all(str, "\\description", "\n DESCRIPTION"); str = str_replace_all(str, "\\notes", "\n NOTES"); % verbatim - it's not likely that there's tm markup in verbatim sections, % otherwise we'd have to split and parse the tm verbatim-wise. variable pos2, len2; while(string_match(str, "\n[ \t]*#v+", 1)) { (pos, len) = string_match_nth(0); !if (string_match(str, "\n[ \t]*#v-", pos + len)) break; (pos2, len2) = string_match_nth(0); variable v_str = str[[pos + len + 1: pos2 - 1]]; v_str = str_replace_all(v_str, "\n", "\n "); v_str = str_replace_all(v_str, "\\", "\\\\"); str = strcat(str[[:pos]], % "\n", % no double empty line above examples [GM] v_str, "\n", str[[pos2+len2:]]); } str = str_replace_all(str, "\\\\", "\\"); return str; } % extract a tm-documentation block from an array of lines % the lines-array is given as pointer, so that the function will work in % an array_map (it would fail else because of the different size of lines % and beg_index/end_index). static define tm_get_block(beg_index, end_index, linesref) { variable lines = @linesref; % show(length(@lines), beg_index, end_index); % show(lines[[beg_index:end_index]]); variable block = lines[[beg_index+1:end_index-1]]; % remove comments block = array_map(String_Type, &strtrim_beg, block, "%"); block = strjoin(block, "") + "\\done\n\n"; return block; } % Extract tm-documentation blocks from an array of lines % Return as String-array of blocks static define tm_get_blocks(lines) { variable tmmarks, beg_marks, end_marks, blocks; % get the line numbers of all tm-marks tmmarks = array_map(Int_Type, &strncmp, lines, "%!%", 3); tmmarks = where(tmmarks == 0); % show(tmmarks, lines[[tmmarks]]); !if (length(tmmarks)) return String_Type[0]; % get the line-numbers of beg and end tmmarks beg_marks = array_map(Integer_Type, &strncmp, lines[[tmmarks]], "%!%+", 4); beg_marks = tmmarks[[where(beg_marks == 0)]]; end_marks = array_map(Integer_Type, &strncmp, lines[[tmmarks]], "%!%-", 4); end_marks = tmmarks[[where(end_marks == 0)]]; if (length(beg_marks) == 0 or length(end_marks) == 0) return String_Type[0]; if (length(beg_marks) != length(end_marks)) error("tm-block marks don't match"); % show(beg_marks, end_marks); return array_map(String_Type, &tm_get_block, beg_marks, end_marks, &lines); } %!%+ %\function{tm_extract} %\synopsis{Extract tm documentation blocks from a file} %\usage{String tm_extract(String filename)} %\description % Return a string with the tm documentation contained in file % \var{filename} in the \var{tm} format used by the *.tm files % of jed and slang documentation. %\example % To get the tm-doc of a file, do e.g. %#v+ % variable tm_doc_str = tm_extract("tm.sl", 0); %#v- %\notes % Currently, this only works with SLang files. % TODO: let it work for tm blocks in C files too. %\seealso{tm_parse, tm_mode, tm_make_doc, tm->tm2ascii} %!%- public define tm_extract(filename) { variable blocks = tm_get_blocks(arrayread_file(filename)); return strjoin(blocks, ""); } %!%+ %\function{tm_parse} %\synopsis{Return ASCII-version of a files tm-documentation blocks} %\usage{String tm_parse(String filename)} %\description % Parse a file for tm-documentation blocks and convert them to % ASCII with tm2ascii. %\example %#v+ % variable doc_str = tm_parse("tm.sl"); %#v- %\seealso{tm_view, tm_extract} %!%- public define tm_parse(filename) { % extract documentation blocks variable blocks = tm_get_blocks(arrayread_file(filename)); !if (length(blocks)) return ""; % convert to ASCII blocks = array_map(String_Type, &tm2ascii, blocks); % return as string return strjoin(blocks, ""); } %!%+ %\function{tm_view} %\synopsis{Extract tm documentation, convert to ASCII and show in a buffer} %\usage{tm_view([args])} %\description % Extract tm documentation from given files or (with emty argument list) % the current buffer or (if defined) region. % Convert to ASCII and show in a buffer. %\example % View tm-documentation from current buffer (or region): %#v+ % tm_view(); %#v- % View tm-documentation from all Slang files in the current directory: %#v+ % tm_view(directory("*.sl"), pop()); %#v- %\seealso{tm_parse, tm_extract, tm->tm2ascii} %!%- public define tm_view() % ([args]) { variable filename, str=""; flush("extracting documentation"); !if (_NARGS) { % extract documentation blocks variable blocks = tm_get_blocks(get_lines()+"\n"); % convert to ASCII if (length(blocks)) blocks = array_map(String_Type, &tm2ascii, blocks); % insert str = strjoin(blocks, ""); } else loop(_NARGS) { filename = (); str += tm_parse(filename); } vmessage("extracted documentation from %d files", _NARGS); if (str == "") return message("no tm-documentation found"); sw2buf(Tm_Doc_Buffer); set_readonly(0); erase_buffer(); insert(str); % bob(); view_mode(); } _add_completion("tm_parse", "tm_view", 2); jedmodes-2.5.7/tm/tmtools.sl0000644000175400017500000001302311262356577014300 0ustar mildegm% tmtools.sl: Some semi-automatic tm style documentation generation. % % Copyright (c) 2005 Dino Leonardo Sangoi, Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % 0.1 first public release (as part of mode/tm) % 2006-01-24 0.2 bugfix: missing autoload for bget_word() % 2006-02-03 0.3 bugfix: wrong source file name for string_nth_match() % 2006-05-26 0.3.1 fixed autoloads (J. Sommer) % 2009-10-05 0.3.2 bugfix: return instead of break outside loop % % _debug_info=1; % Requirements % ------------ % If you have Dinos cext.sl, uncomment the next line and % exchange c_top_of_function with new_top_of_function. %require("cext"); require("comments"); autoload("get_word", "txtutils"); autoload("bget_word", "txtutils"); autoload("insert_markup", "txtutils"); autoload("string_nth_match", "strutils"); autoload("c_top_of_function", "cmisc"); % Uhm, the word should be defined by mode, I guess (but currently is not) % More accurate: it should be mode specific: when I edit a latin1 encoded % text after calling tm_make_doc, I get trouble with Umlauts. Therefore: private variable word_chars = "A-Za-z0-9_"; % valid tm attributes (subset understood by tm2ascii() in tm.sl) static variable tm_attributes = "var,em,sfun"; static define tm_make_var_doc() { variable line = line_as_string, name, value, tm; !if (string_match(line, "custom_variable ?(\"\\(.*\\)\", ?\\(.*\\));", 1)) return; (name, value) = (string_nth_match(line,1), string_nth_match(line, 2)); tm = ["%%!%%+", "%%\\variable{%s}", "%%\\synopsis{}", "%%\\usage{variable %s = %s}", "%%\\description", "%% ", "%%\\example", "%%#v+", "%% ", "%%#v-", "%%\\seealso{}", "%%!%%-\n"]; tm = sprintf(strjoin(tm, "\n"), name, name, value); bol; insert(tm); } %!%+ %\function{tm_make_doc} %\synopsis{Create documentation comments for a function or custom variable} %\usage{tm_make_doc()} %\description % When this function is called from inside a C or SLang function, it % creates right above the function itself a set of commented lines % formatted as expected by tm2txt. Some data will be generated % automagically from the function definition and comments. % % When it is called on a line starting with "custom_variable", % appropriate variable documentation is created instead. %\notes % Bind to a key or call via M-x tm_make_doc %\seealso{tm_set_attr} %!%- public define tm_make_doc() { variable name, name_with_args; variable c = get_comment_info(); variable cb, cm, ce; if (c == NULL) verror("No comment strings defined for %s mode", get_mode_name()); cb = strtrim(c.cbeg); ce = strtrim(c.cend); cm = strtrim(c.cbeg); if (c.cend != "") { if (strlen(cm) > 1) cm = " " + cm[[1:]]; } % if we're looking at a custom_variable, document it bol; if (looking_at("custom_variable")) return tm_make_var_doc; % new_top_of_function(); % find the top of function down_1(); % dont't jump to last fun, if in first line of function c_top_of_function(); % goes to first opening { !if (re_bsearch("[]\\)\\}\\;\\>\\\"]")) return; if (what_char != ')') return; right(1); % leave on Stack push_mark(); go_left(()); % get from stack call("goto_match"); bskip_chars(" \t\n"); name = bget_word(word_chars); bol(); name_with_args = bufsubstr(); % may contain static, local, global, and define keywords: if(get_mode_name() == "SLang") { (name_with_args, ) = strreplace(name_with_args, "static ", "", 1); (name_with_args, ) = strreplace(name_with_args, "local ", "", 1); (name_with_args, ) = strreplace(name_with_args, "public ", "", 1); (name_with_args, ) = strreplace(name_with_args, "define ", "", 1); % uncomment the next line, if you like to insert Void by default % (name_with_args, ) = strreplace(name_with_args, "define ", "Void ", 1); % optional arguments written as foo() % (bar=1, zaff=0) (name_with_args, ) = strreplace(name_with_args, "() % ", "", 1); } % TODO: % % Check existing comments % push_mark(); % do % {go_up_1; bol;} % while(looking_at("%")); % % exchange_point_and_mark(); % message(bufsubstr); % Grrr, Wy C uses " *%+" while slang uses "%!%+" ??? if (cb == "%") insert ("%!%+\n"); else insert (cb + "%+\n"); vinsert("%s\\function{%s}\n", cm, name); insert (cm + "\\synopsis{}\n"); % TODO: check for a return value vinsert("%s\\usage{%s}\n", cm, name_with_args); insert (cm + "\\description\n"); insert (cm + " \n"); insert (cm + "\\example\n"); insert (cm + "#v+\n"); insert (cm + " \n"); insert (cm + "#v-\n"); insert (cm + "\\notes\n"); insert (cm + " \n"); insert (cm + "\\seealso{}\n"); % comma separated list if (cm == "%") insert ("%!%-\n"); else insert (cm + "%-\n"); if (ce != "") insert(" "+ce+"\n"); } %!%+ %\function{tm_set_attr} %\synopsis{Add attribute around a word in tm format} %\usage{tm_set_attr(String_Type attr)} %\description % This function adds '\\attr{' and '}' around the word at the point. % (attr is replaced with the actual parameter). %\notes % Bind this to a key. For example, I bind "tm_set_attr(\"var\")" to "^Wv". %\seealso{tm_make_doc} %!%- public define tm_set_attr() % ([attr]) { !if (_NARGS) read_string_with_completion ("Attribute", "var", tm_attributes); variable attr = (); insert_markup(sprintf("\\%s{", attr), "}"); } provide("tmtools"); jedmodes-2.5.7/mupad/0000755000175400017500000000000010461125576012717 5ustar mildegmjedmodes-2.5.7/mupad/mupad.sl0000644000175400017500000001270410340314717014362 0ustar mildegm% Mode for editing Mupad files. % (MuPad is a computer algebra system, see http://www.mupad.de) % % Copyright (c) 2003 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Based on Guido Gonzatos matlab.sl % Enables interactive work using ishell.sl % % 0.9 19 May 1999 first public version % 0.9.1 2005-04-25 bugfix to work with SLang2 (report Jrg Sommer) % 0.9.2 2005-11-02 fix public definiton of mupad_mode() % requirements require("comments"); autoload ("ishell_send_input", "ishell.sl"); autoload ("ishell_mode", "ishell.sl"); private variable modename = "Mupad"; custom_variable ("Mupad_Command", "mupad"); % do commenting with comments.sl set_comment_info (modename, "# ", " #", 7); % Now create and initialize a simple syntax table. create_syntax_table (modename); % (only two comment definitions work at the same time, MuPad has three) define_syntax ("#", "#", '%', modename); % comments %define_syntax ("/*", "*/", '%', modename); % comments define_syntax ("//", "", '%', modename); % comments define_syntax ("([{", ")]}", '(', modename); % parentheses define_syntax ('"', '"', modename); % strings define_syntax ('\\', '\\', modename); % escape character define_syntax ("0-9a-zA-Z_", 'w', modename); % identifiers define_syntax ("0-9a-fA-F.xXL", '0', modename); % numbers define_syntax (",;", ',', modename); % delimiters define_syntax ("!&+-.*^;<>\|~='/:", '+', modename); % operators define_syntax ('>', '#', modename); % preprocess (used for output) set_syntax_flags (modename, 4); % Mupad reserved words. Are there more? () = define_keywords_n (modename, "doifinofto", 2, 0); () = define_keywords_n (modename, "for", 3, 0); () = define_keywords_n (modename, "caseelifelsefromholdnextprocthen", 4, 0); () = define_keywords_n (modename, "beginbreaklocaluntilwhile", 5, 0); () = define_keywords_n (modename, "end_ifrepeatreturn", 6, 0); () = define_keywords_n (modename, "end_for", 7, 0); () = define_keywords_n (modename, "end_procend_case", 8, 0); () = define_keywords_n (modename, "end_whileotherwise", 9, 0); () = define_keywords_n (modename, "end_repeat", 10, 0); %() = define_keywords_n (modename, "edit_history", 12, 0); %() = define_keywords_n (modename, "end_try_catch", 13, 0); variable Mupad_Indent = 2; % Mupad indent routine. define mupad_indent () { variable goal = 1; variable cs = CASE_SEARCH; variable ch; % goto beginning of line and skip past continuation char USER_BLOCK0 { bol (); skip_white (); } push_spot (); push_spot (); CASE_SEARCH = 1; % Mupad is case sensitive while (up_1 ()) { bol_skip_white(); if ( eolp() ) continue; X_USER_BLOCK0 (); goal = what_column (); % if (looking_at("switch")) % goal += 2 * Mupad_Indent; % to account for 'case' if (looking_at ("if") or looking_at ("else") or looking_at ("elif") or looking_at ("case") or looking_at ("for") or looking_at ("while") or looking_at ("repeat") or looking_at ("proc") or looking_at ("begin") ) goal += Mupad_Indent; break; } % now check the current line pop_spot (); push_spot (); X_USER_BLOCK0 (); % if (looking_at ("end_procswitch")) % goal -= 2 * Mupad_Indent; if (looking_at ("end_if") or looking_at ("else") or looking_at ("elif") or looking_at ("end_case") or looking_at ("end_for") or looking_at ("end_while") or looking_at ("end_repeat") or looking_at ("end_proc") ) goal -= Mupad_Indent; CASE_SEARCH = cs; % done getting indent if (goal < 1) goal = 1; pop_spot (); bol_skip_white (); ch = char(what_char()); bol_trim (); goal--; insert_spaces (goal); pop_spot (); skip_white (); } % mupad_indent define mupad_newline () { if (bolp ()) { newline (); return; } mupad_indent (); newline (); mupad_indent (); } % interactive MuPad session with the actual document as template public define mupad_shell() { ishell_mode(Mupad_Command); } define mupad_help() { !if(is_substr(get_mode_name(), "ishell")) error("Currently help only works in mupad-shell mode"); variable topic = ""; if (_NARGS) topic = (); if (topic == "") topic = read_mini("Gnuplot Help for: ", "", ""); set_blocal_var("o", "IShell_output_placement"); % closing NL needed by send_process send_process(get_blocal_var("IShell_Id"), "?" + topic + "\n"); } % --- the mode dependend menu static define init_menu (menu) { % menu_append_item (menu, "&Evaluate Region/Buffer", "mupad_run"); menu_append_item (menu, "Mupad &Shell", "mupad_shell"); menu_append_item (menu, "Mupad &Help", "mupad_help"); } % --- keybindings %!if (keymap_p (modename)) make_keymap (modename); % TODO %!%+ %\function{mupad_mode} %\synopsis{a mode for edition of mupad skripts} %\description % Protoytype: Void mupad_mode (); % This is a mode that is dedicated to facilitate the editing of % Mupad language files. % Hooks: \var{mupad_mode_hook} %!%- public define mupad_mode () { set_mode(modename, 2); % use_keymap(modename); use_syntax_table (modename); set_buffer_hook ("indent_hook", "mupad_indent"); set_buffer_hook ("newline_indent_hook", "mupad_newline"); mode_set_mode_info (modename, "init_mode_menu", &init_menu); define_blocal_var("help_for_word_hook", "mupad_help"); run_mode_hooks("mupad_mode_hook"); } provide("mupad"); % --- End of file mupad.sl --- jedmodes-2.5.7/console_keys/0000755000175400017500000000000010461125576014306 5ustar mildegmjedmodes-2.5.7/console_keys/console_keys.sl0000644000175400017500000000512010436517333017337 0ustar mildegm% console_keys.sl: make shift-arrow etc. work under linux-console % % Copyright (c) 2005 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Versions: % 0.1 2006-02-02 proof of concept (works for me) % 0.2 2006-05-29 remove custom-var Jed_Temp_Dir % after learning that make_tmp_file() uses Jed_Tmp_Directory % since 0.99.17-165. % % USAGE % ----- % % put in your in jed.rc something like % % #ifndef XWINDOWS IBMPC_SYSTEM % autoload("set_console_keys", "console_keys"); % if (getenv("DISPLAY") == NULL and BATCH == 0) % set_console_keys(); % #endif % % `loadkeys` permissions % ---------------------- % % On some systems (e.g. SuSE), loadkeys requires superuser privileges. % % The sysadmin could provide a wrapper, a "console" group or some sudo % configuration to share the privileges with trustworthy users. % % In any case, on such systems console_keys.sl will fail if you do not have % access to the "root" account. % % Drawbacks % --------- % % console_keys.sl changes the keysyms for all virtual konsoles, which % might break other programs % % Workaraound: console_keys saves you previous settings % (with dumpkeys) and loads them after finishing jed % However, while jed is running, shifted movement keys behave % differently from the standard. % Idea: Trap the konsole-switching keys as well and write a function % that resets the keys and switches the console (as well as % loads the console_keys after coming back with a _before_key_hook static variable keymap_cache = make_tmp_file("console_keys_"); % restore the keymap to previous state define restore_console_keys() { variable cmd, status; % load the saved keymap cmd = "loadkeys " + keymap_cache; status = system(cmd); if (status) verror("%s returned %d, %s", cmd, status, errno_string(status)); return 1; } % save the current keymap and set the special keymap define set_console_keys() { variable cmd, status, keymap = expand_jedlib_file("console_keys.map"); if (keymap == NULL) verror("console_keys.map not found on '%s'", get_jed_library_path); % save the current keymap cmd = "dumpkeys > " + keymap_cache; status = system(cmd); if (status) verror("%s returned %d, %s", cmd, status, errno_string(status)); % load the special keymap cmd = "loadkeys " + keymap; status = system(cmd); if (status) verror("%s returned %d, %s", cmd, status, errno_string(status)); add_to_hook("_jed_exit_hooks", &restore_console_keys); } jedmodes-2.5.7/console_keys/console_keys.map0000644000175400017500000000412010402011742017457 0ustar mildegm# console_keys.map # # make shift-arrow etc. work under linux-console # original by Matti-Oskari Leppnen # Adopted to keydefs.sl order and extended by Guenter Milde # USAGE # # use console_keys.sl or call # loadkeys console_keys.map # (maybe in a jed wrapper script) to get the keysyms expected in keydefs.sl # # Drawbacks: this changes the keysyms for all virtual konsoles and might # break other programs # Workaraound: save you previous setting with # dumpkeys > standard_keys.map # and load after finishing jed # On some distributions, loadkeys needs root privilegues # TODO: * add TAB and BS # Keymaps may not contain "\e" for escape, therefore "\033" is used # Shifted Keys: # Key_Shift_Up shift keycode 103 = F100 string F100 = "\033[a" # Key_Shift_Down shift keycode 108 = F101 string F101 = "\033[b" # Key_Shift_Right shift keycode 106 = F102 string F102 = "\033[c" # Key_Shift_Left shift keycode 105 = F103 string F103 = "\033[d" # Key_Shift_Ins shift keycode 110 = F104 string F104="\033[2$" # Key_Shift_Del shift keycode 111 = F105 string F105 = "\033[3$" # Key_Shift_Home shift keycode 102 = F106 string F106 = "\033[1$" # Key_Shift_End shift keycode 107 = F107 string F107 = "\033[4$" # Key_Shift_PgUp shift keycode 104 = F108 string F108 = "\033[5$" # Key_Shift_PgDn shift keycode 109 = F109 string F109 = "\033[6$" # Ctrl Keys: # Key_Ctrl_Up control keycode 103 = F110 string F110 = "\033[" # Key_Ctrl_Down control keycode 108 = F111 string F111 = "\033[" # Key_Ctrl_Right control keycode 106 = F112 string F112 = "\033[" # Key_Ctrl_Left control keycode 105 = F113 string F113 = "\033[" # Key_Ctrl_Ins control keycode 110 = F114 string F114="\033[2^" # Key_Ctrl_Del control keycode 111 = F115 string F115 = "\033[3^" # Key_Ctrl_Home control keycode 102 = F116 string F116 = "\033[1^" # Key_Ctrl_End control keycode 107 = F117 string F117 = "\033[4^" # Key_Ctrl_PgUp control keycode 104 = F118 string F118 = "\033[5^" # Key_Ctrl_PgDn control keycode 109 = F119 string F119 = "\033[6^" jedmodes-2.5.7/calc/0000755000175400017500000000000010461125576012513 5ustar mildegmjedmodes-2.5.7/calc/calc.sl0000644000175400017500000003561010332147325013753 0ustar mildegm%------------------calc.sl------------------------------------- %% Simple SLang calculator %% Version: 1.35 %% Author: Marko Mahnic %% %%------------------------------------------------------------- %% History: %% 1.35 Nov 2003 %% * Switch between "Calculator" and "*calcres*" in single-wnidow mode %% 1.3 Nov 2003 %% * Changed by Guenter Milde to use definekey_reserved %% * Added "calc" namespace (GM) %% 1.25 Oct 2002 %% * Added integer display mode %% * Menu updated %% 1.2 May 2001 %% * 1-D and 2-D array dump %% * "SLangCalc" mode, keymap %% * SLangCalc mode menu (text version only) %% * a call to calc_mode_hook() %% 1.1 May 2001 %% * Single and double window mode %% 1.0 May 2001 %% * First release to the public at jed-users@yahoogroups.com %%------------------------------------------------------------- %% %% To install put in .jedrc: %% autoload ("calc", "calc.sl"); %% autoload ("calc2", "calc.sl"); %% %% Usage: %% M-x calc %% or %% M-x calc2 %% for two-window mode. %% %% To get a Calc menu entry insert in your .jedrc: %% %% if you have jed 99.13: %% %% static define load_popups_hook (menubar) %% { %% % %% menu_insert_item (3, "Global.S&ystem", "Ca&lculate", "calc"); %% } %% variable Menu_Load_Popups_Hook = &load_popups_hook; %% %% if you have a newer version than jed 99.13: %% %% define calc_load_popup_hook (menubar) %% { %% menu_insert_item (7, "Global.S&ystem", "Ca&lculate", "calc"); %% } %% append_to_hook ("load_popup_hooks", &calc_load_popup_hook); %% %% or insert the menu_insert_item() function to an already defined %% *_load_popup_hook. %% %% %% A simple calculator that takes a SLang expression, evaluates %% it and prints the result in the form of a comment after the %% expression. %% %% If you use it with two windows, one window (Calculator) is used %% to edit expressions, in the other one (*calcres*) the results %% are displayed. %% %% The evaluation is started with calc_make_calculation() (^C^A if ^C is %% your _Reserved_Key_Prefix). %% Use the calc_mode_hook to define your own bindings e.g. in your .jedrc: %% %% define calc_mode_hook () %% { %% local_setkey ("calc_make_calculation", "^[^M"); % Alt-Return %% } %% %% %% The result of an expression is everything that is left on the %% SLang stack after the expression is evaluated. %% The result of evaluation of %% 1+1; 2+2; %% would be %% 2 %% 4, %% but only 4 is written into the expression buffer. The other %% results can be found in the result buffer using calc_result_window() (^C^W). %% %% %% An expression can be any valid SLang code. Multiple expressions %% can be divided by a tag with calc_next_expression() (^C^N). %% %% There are 25 predefined variables ([a-z]) that can be used without %% declaration and displayed with calc_display_variables() (^C^V). %% %% Use calc_help (^C^H) (or look at the mode menu) for help on keys. # _autoload("calc", "calc", "calc2", "calc", 2); _add_completion("calc", "calc2", 2); # % set up a named namespace implements("calc"); static variable buf_expr = "Calculator"; static variable buf_result = "*calcres*"; static variable history_tag = "%-------------- :-)"; static variable history_file = ""; static variable format = "%.6f"; static variable exprid = 0; static variable kmp_calc = "SLangCalc"; static variable use_result_win = 0; static variable use_result_comment = 1; % 0 never, 1 not for arrays, 2 always static variable int_mode = 0; % 0 = dec, 1 = hex, 2 = oct, 3 = bin, 9 = all static variable a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0; static define calc_select_expression_buf () { pop2buf (buf_expr); } static define history_next () { re_fsearch ("^" + history_tag); } static define history_prev () { re_bsearch ("^" + history_tag); } public define calc_next_expression () { eob(); !if (bobp()) { variable empty = 0; while (not empty) { go_up(1); bol(); empty = (re_looking_at("^[ \t]*$")); eob(); !if (empty) insert ("\n"); } } exprid++; vinsert ("%s E%d\n", history_tag, exprid); } static define calc_format_binary (val) { variable hex = strup(sprintf("%x", val)); variable len = strlen(hex); variable ch, i, bin = ""; for (i = 0; i < len; i++) { ch = hex[i]; if (ch < '8') { if (ch < '4') { if (ch == '0') bin = bin + "0000"; else if (ch == '1') bin = bin + "0001"; else if (ch == '2') bin = bin + "0010"; else if (ch == '3') bin = bin + "0011"; } else { if (ch == '4') bin = bin + "0100"; else if (ch == '5') bin = bin + "0101"; else if (ch == '6') bin = bin + "0110"; else if (ch == '7') bin = bin + "0111"; } } else { if (ch < 'C') { if (ch == '8') bin = bin + "1000"; else if (ch == '9') bin = bin + "1001"; else if (ch == 'A') bin = bin + "1010"; else if (ch == 'B') bin = bin + "1011"; } else { if (ch == 'C') bin = bin + "1100"; else if (ch == 'D') bin = bin + "1101"; else if (ch == 'E') bin = bin + "1110"; else if (ch == 'F') bin = bin + "1111"; } } if (i < len - 1) bin = bin + " "; } return bin; } static define calc_display_value(val, linepref); static define calc_display_value(val, linepref) { if (typeof (val) == String_Type) { vinsert ("%s\"%s\"", linepref, string (val)); return; } else if (typeof (val) != Array_Type) { if (int_mode != 0 and typeof (val) == Integer_Type) { if (int_mode == 1) vinsert ("%s0x%02x hex", linepref, val); else if (int_mode == 2) vinsert ("%s0%o oct", linepref, val); else if (int_mode == 3) vinsert ("%s%s bin", linepref, calc_format_binary(val)); else if (int_mode == 9) vinsert ("%s%d dec, 0%o oct, 0x%02x hex, %s bin", linepref, val, val, val, calc_format_binary(val)); return; } vinsert ("%s%s", linepref, string (val)); return; } variable i, j; variable dims, num_dims, data_type; (dims, num_dims, data_type) = array_info (val); vinsert ("%sArray: %s\n", linepref, string (val)); if (num_dims == 1) { calc_display_value (val[0], linepref); for (i = 1; i < dims[0]; i++) { calc_display_value (val[i], ", "); } } else if (num_dims == 2) { for (i = 0; i < dims[0]; i++) { calc_display_value (val[i, 0], linepref + "> "); for (j = 1; j < dims[1]; j++) { calc_display_value (val[i, j], ", "); } if (i < dims[0]-1) insert("\n"); } } else if (num_dims > 2) { calc_display_value (sprintf (" :( %d-D array ", num_dims), linepref); } } static define calc_display_stack () { variable res; if (_stkdepth () < 1) { insert ("\t---\n"); res = "---"; } else { _stk_reverse (_stkdepth()); while (_stkdepth ()) { % res = string (()); % insert ("\t" + res + "\n"); res = (); calc_display_value (res, "\t"); insert ("\n"); } } insert("\n"); recenter (window_info ('r')); return (res); } public define calc_display_variables () { pop2buf (buf_result); eob (); variable iii, sss, ccc, www = SCREEN_WIDTH / 2 + 2; insert ("Variables:\n"); for (iii = 'a'; iii <= 'm'; iii++) { insert(sprintf(" %c: %s", iii, string(eval(sprintf("use_namespace(\"calc\"); %c",iii))))); ccc = what_column(); if (ccc < www) insert_spaces (www - ccc); else insert (" | "); insert (sprintf ("%c: %s\n", iii+13, string(eval(sprintf("use_namespace(\"calc\"); %c",iii+13))))); } insert("\n"); recenter (window_info ('r')); calc_select_expression_buf(); } public define calc_result_window () { if (use_result_win) { pop2buf (buf_result); eob(); recenter (window_info ('r')); calc_select_expression_buf(); } else { if (whatbuf() != buf_result) { sw2buf (buf_result); recenter (window_info ('r')); use_keymap (kmp_calc); } else { sw2buf (buf_expr); } } } public define calc_make_calculation () { variable expr, id = ""; _pop_n (_stkdepth()); sw2buf (buf_expr); push_spot(); eol (); !if (history_prev()) bob(); else { go_right (strlen(history_tag)); skip_white(); !if (eolp()) { push_mark(); eol(); id = strtrim (bufsubstr()); } bol(); } push_mark(); eol (); !if (history_next()) eob(); expr = bufsubstr(); pop_spot(); eval ("use_namespace(\"calc\");" + expr); if (use_result_win) pop2buf (buf_result); else setbuf (buf_result); eob (); if (id == "") insert ("R:\n"); else vinsert ("R(%s):\n" ,id); variable nResults = _stkdepth(); variable lastres = calc_display_stack(); calc_select_expression_buf(); %% Display the last result in expression buffer if (not use_result_win or use_result_comment) { push_spot(); !if (history_next()) { pop_spot(); calc_next_expression(); push_spot(); history_prev(); } go_up(1); bol(); while (not bobp() and (re_looking_at("^[ \t]*$"))) { go_up(1); bol(); } eol(); % vinsert ("\n\t%%R: %s", lastres); insert ("\n"); if (use_result_comment < 2 and typeof(lastres) == Array_Type) calc_display_value ("Array...", "\t%R: "); else calc_display_value (lastres, "\t%R: "); if (not use_result_win and nResults > 1) vinsert (" ... (%d results)", nResults); pop_spot(); } } static define calc_find_max_id () { variable id = 0; setbuf (buf_expr); push_spot(); bob(); exprid = 0; while (history_next()) { go_right (strlen(history_tag)); skip_white(); !if (eolp()) { push_mark(); eol(); if (1 == sscanf (strtrim (bufsubstr()), "E%d", &id)) if (id > exprid) exprid = id; } } pop_spot(); } public define calc_read_file () { setbuf (buf_expr); history_file = read_with_completion("Read file:", "", history_file, 'f'); erase_buffer(); () = insert_file (history_file); set_buffer_modified_flag (0); bob(); calc_find_max_id(); } public define calc_write_file () { setbuf (buf_expr); history_file = read_with_completion("Write to file:", "", history_file, 'f'); push_spot(); mark_buffer(); () = write_region_to_file (history_file); pop_spot(); } public define calc_float_format () { if (_NARGS > 0) format = (); else format = read_mini ("Float format:", format, ""); set_float_format (format); } public define calc_help () { variable RKP = _Reserved_Key_Prefix; variable shlp = "Alt-Enter Evaluate $rkp$F Format $rkp$V Variables $rkp$N New $rkp$S Save $rkp$R Read"; !if (use_result_win) shlp = shlp + " $rkp$^W Results"; shlp = str_replace_all(shlp, "$rkp$", RKP); message (shlp); } % changed by GM to use definekey_reserved % so it doesnot break existing keybindings % The actual bindings are a concatenation of the variable % _Reserved_Key_Prefix [RKP] and what is defined here static define calc_prepare_keymap () { !if (keymap_p (kmp_calc)) { $1 = kmp_calc; copy_keymap ($1, "C"); definekey_reserved ("calc_make_calculation", "^A", $1); definekey_reserved ("calc_make_calculation", "A", $1); definekey_reserved ("calc_make_calculation", "^M", $1); % Return definekey_reserved ("calc_float_format", "^F", $1); definekey_reserved ("calc_float_format", "F", $1); definekey_reserved ("calc_help", "^H", $1); definekey_reserved ("calc_help", "H", $1); definekey_reserved ("calc_next_expression", "^N", $1); definekey_reserved ("calc_next_expression", "N", $1); definekey_reserved ("calc_read_file", "^R", $1); definekey_reserved ("calc_read_file", "R", $1); definekey_reserved ("calc_write_file", "^S", $1); definekey_reserved ("calc_write_file", "S", $1); definekey_reserved ("calc_display_variables", "^V", $1); definekey_reserved ("calc_display_variables", "V", $1); definekey_reserved ("calc_result_window", "^W", $1); definekey_reserved ("calc_result_window", "W", $1); } use_keymap (kmp_calc); } public define calc_reset_buffer() { erase_buffer(); exprid = 0; calc_next_expression(); } static define init_menu (menu) { variable menu_mode; menu_append_item (menu, "&Evalute", "calc_make_calculation"); menu_append_item (menu, "&Variables", "calc_display_variables"); menu_append_item (menu, "Result &window", "calc_result_window"); menu_append_item (menu, "&New expression", "calc_next_expression"); menu_append_item (menu, "&Read expressions", "calc_read_file"); menu_append_item (menu, "&Save expressions", "calc_write_file"); menu_append_item (menu, "&Y - Reset buffer", "calc_reset_buffer"); menu_append_separator(menu); menu_append_popup(menu, "&Integer format"); menu_append_item (menu, "&Float format", "calc_float_format"); menu_mode = menu + ".&Integer format"; menu_append_item (menu_mode, "&Bin mode", "calc_mode_bin"); menu_append_item (menu_mode, "&Oct mode", "calc_mode_oct"); menu_append_item (menu_mode, "&Dec mode", "calc_mode_dec"); menu_append_item (menu_mode, "&Hex mode", "calc_mode_hex"); menu_append_item (menu_mode, "&Combined mode", "calc_mode_all"); } static define calc_start () { if (_NARGS > 0) use_result_win = (); if (use_result_win) { onewindow(); splitwindow(); % Bottom window: results if (window_info('t') == 1) otherwindow(); sw2buf (buf_result); % Top window: expressions } pop2buf (buf_expr); slang_mode(); set_mode ("SLangCalc", 2 |8); mode_set_mode_info ("SLangCalc", "init_mode_menu", &init_menu); calc_prepare_keymap(); run_mode_hooks ("calc_mode_hook"); set_float_format (format); if (bobp() and eobp()) { calc_next_expression(); } } public define calc_mode_dec() { int_mode = 0; } public define calc_mode_hex() { int_mode = 1; } public define calc_mode_oct() { int_mode = 2; } public define calc_mode_bin() { int_mode = 3; } public define calc_mode_all() { int_mode = 9; } public define calc () { calc_start (0); } public define calc2 () { calc_start (1); } jedmodes-2.5.7/calc/calc_sl.html0000664000175400017500000000731610214064402014774 0ustar mildegm JED Macro: calc.sl

calc.sl

A simple calculator that takes a SLang expression, evaluates it and prints the result in the form of a comment after the expression.

If you use it with two windows, one window (Calculator) is used to edit expressions, in the other one (*calcres*) the results are displayed.

 File   Edit   Mode   Search   Buffers   Windows   System   Help 
 R(E1):
         45
 
 R(E2):
         "0: 0"
         "1: 1"
         "2: 4"
 
 [EOB]
 -**-----|V0.99.16| *calcres* () | 9/9,1------------------------- 
 %-------------- :-)   E1
 a=0; for (i=0; i<10; i++) a+=i;
 a;
         %R:  45
 
 %-------------- :-)   E2
 for (i=0; i<3; i++) sprintf ("%d: %d", i, i*i);
         %R:  "2: 4"
 
 %-------------- :-)   E3
 [EOB]
 -**-----|V0.99.16| Calculator (SLangCalc) | 11/11,1------------- 

The evaluation is started with calc_make_calculation() (^C^A if ^C is your _Reserved_Key_Prefix). Use the calc_mode_hook to define your own bindings e.g. in your .jedrc:

   define calc_mode_hook ()
   {
      local_setkey ("calc_make_calculation", "^[^M");  % Alt-Return
   }
The result of an expression is everything that is left on the SLang stack after the expression is evaluated. The result of evaluation of
   1+1; 2+2;
would be
   2
   4
but only 4 is written into the expression buffer. The other results can be found in the result buffer using calc_result_window() (^C^W).

An expression can be any valid SLang code. Multiple expressions can be divided by a tag with calc_next_expression() (^C^N).

There are 25 predefined variables ([a-z]) that can be used without declaration and displayed with calc_display_variables() (^C^V).

Use calc_help() (^C^H) (or look at the mode menu) for help on keys.

Other operations

Expressions can be saved (^C^S) to a file and loaded (^C^R) later.

The display format for integer and float results can be changed from the mode menu. The combined mode displays integer results in dec, oct, hex and bin format.

Installation

Put the file somewhere on your jed_library_path and
   autoload ("calc", "calc.sl");
   autoload ("calc2", "calc.sl");
in your .jedrc file.

Then you can invoke the calculator with M-x calc or M-x calc2 for two-window mode.

To get a Calc menu entry insert in your .jedrc:

if you have jed 99.13:

     static define load_popups_hook (menubar)
     {
        %
        menu_insert_item (3, "Global.S&ystem", "Ca&lculate", "calc");
     }            
     variable Menu_Load_Popups_Hook = &load_popups_hook;
if you have a newer version than jed 99.13:
     define calc_load_popup_hook (menubar)
     {
        menu_insert_item (7, "Global.S&ystem", "Ca&lculate", "calc");
     }
     append_to_hook ("load_popup_hooks", &calc_load_popup_hook);
or insert the menu_insert_item() function to an already defined _load_popup_hook. jedmodes-2.5.7/listing/0000755000175400017500000000000011477670420013263 5ustar mildegmjedmodes-2.5.7/listing/listing.sl0000644000175400017500000003307711477670420015306 0ustar mildegm% listing.sl: A list widget for modes like dired, grep, locate, ... % % Copyright © 2006 Dino Sangoi, Günter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % Version 0.1 Dino Sangoi first version % 0.9 Günter Milde % * "outsourcing" of the linklist datatype % * Tags list is now buffer-local % 0.9.1 * Tags list implemented as array % 0.9.2 * Use array_map for most mappings % * introduced the scope-argument % 0.9.3 * Mode menu, more keybindings % * new functions: edit, listing_list_tags % 0.9.4 * replaced use of obsolete function array_concat % 0.9.5 * optional argument "default" for get_confirmation() % 2004-02-05 0.9.6 * bugfix: listing_mode no longer tries to delete % empty lines (P. Boekholt) % 2005-03-31 1.9.7 * made slang-2 proof: A[[0:-2]] --> A[[:-2]] % 2005-11-08 1.9.8 * changed _implements() to implements() % 2005-11-23 1.9.9 * docu bugfix in listing_list_tags % 2006-01-24 2.0 * new keybinding: Key_Return calls "listing_return_hook" % 2006-02-03 2.1 * removed the "listing_return_hook" again, as % set_buffer_hook("newline_indent_hook", &my_return_hook); % can be used instead. (tip by Paul Boekholt) % 2006-10-05 3.0 * use the new (SLang2) "list" datatype, % removed obsolete static functions get_tag() and % delete_tagged_lines() % 2007-04-17 3.1 * removed the dired-style Key_BS binding (tag&up) as this % overrides the default (page_up) of the basic "view" mode % 2007-04-19 3.1.1 * added a "Save Listing" entry to the mode menu % 2009-02-16 3.1.2 * code cleanup % 2009-12-08 3.1.3 * adapt to new require() syntax in Jed 0.99.19 % 2010-12-08 * list_concat() -> list_extend() (datutils 2.3) % % TODO: * Shift-Click tags from point to Mousepoint % may be also: right-drag tags lines % Requirements % ------------ % % * S-Lang >= 2.0 (introduces the List_Type datatype) % * extensions from http://jedmodes.sf.net/ #if (_jed_version > 9918) require("keydefs", "Global"); % from jed's standard library require("view", "Global"); % readonly-keymap depends on bufutils.sl #else require("keydefs"); require("view"); #endif autoload("list_extend", "datutils"); % >= 2.3 autoload("push_defaults", "sl_utils"); % --- name it provide("listing"); provide("listing-list"); implements("listing"); private variable mode = "listing"; % --- Variables ------------------------------------------------------- custom_variable("ListingSelectColor", color_number("menu_selection")); custom_variable("ListingMarkColor", color_number("region")); % this one is for communication between different calls to % get_confirmation static variable Dont_Ask = 0; % --- Functions -------------------------------------------------- % --- Helper Functions (static) % helper function: just return the arguments static define null_fun() { } %!%+ %\function{get_confirmation} %\synopsis{Ask whether a list of actions should go on} %\usage{Int listing->get_confirmation(Str prompt, Str default="")} %\description % If an action (e.g. deleting) on tagged lines needs a user confirmation, % the function in question can use get_confirmation(prompt) instead of % get_y_or_n(prompt) to offer more choices. The keybindings are a subset % from jed's replace command: % y: yes, return 1 % n: no, return 0 % !: all, return 1, set Dont_Ask % q: quit, throw UserBreakError % and also % r: recenter window, ask again % Return: enter, default action if \var{default} == "y" or "n". %\notes % The static variable listing->Dont_Ask saves the "!: all" decision (so % the next invocation of get_confirmation doesnot ask but returns always % 1.) The function that starts the mapping of the action on the list must % reset listing->Dont_Ask to 0. (\sfun{listing_map} does this, so it is % save to use \sfun{get_confirmation} in a function that gets called from % \sfun{listing_map}.) %\seealso{listing_map, get_y_or_n} %!%- static define get_confirmation() % (prompt, [default]) { variable key, prompt, default; (prompt, default) = push_defaults( , "", _NARGS); if (Dont_Ask == 1) return 1; flush(prompt + " (y/n/!/q): " + default); loop(3) { key = getkey(); if (key == '\r') key = default[0]; switch(key) { case 'y' : return 1; } { case 'n' : return 0; } { case '!' : Dont_Ask = 1; return 1; } { case 'q' or case '\e': throw UserBreakError, "Quit"; } { case 'r' : recenter (window_info('r') / 2); } { flush(prompt + " y:yes n:no !:yes to all q:quit r:recenter"); } } throw UserBreakError, "3x wrong key"; } %!%+ %\function{tags_length} %\synopsis{Return the number of tagged lines.} %\usage{Int tags_length(scope=2)} %\description % Return the number of tagged lines, considering scope. % For a discussion of the scope parameter see \var{listing_map} %\seealso{listing_map, listing_mode, list_tags} %!%- static define tags_length() % (scope=2) { variable scope = push_defaults(2, _NARGS); variable taglength = length(get_blocal_var("Tags")); switch (scope) { case 0: return 1; } % 0 current line { case 1 and taglength: return taglength; } % 1 tagged lines { case 1 and not(taglength): return 1; } % or current line, if no line is tagged. { case 2: return taglength; } % 2 tagged lines } % find out if the current line is tagged. % If so, return the index of the mark + 1, else return 0 static define line_is_tagged() { variable tag_mark, n = 1; variable line = what_line(); push_spot(); % remember position foreach tag_mark (get_blocal_var("Tags")) { goto_user_mark(tag_mark); % only way to find out mark.line if (line == what_line()) { pop_spot(); return(n); } n++; } pop_spot(); return(0); } %!%+ %\function{tag} %\synopsis{Mark the current line and append to the Tags list} %\usage{Void tag(how = 1)} %\description % Tag/untag the current line according to the (optional) argument how: % 0 untag, % 1 tag (default), % 2 toggle %\seealso{listing_mode, listing_map} %!%- static define tag() % (how = 1) { variable how = push_defaults(1, _NARGS); variable tags = get_blocal_var("Tags"); % see whether the line is already tagged variable is_tagged = line_is_tagged(); % toggle: change the tag status if (how == 2) how = not(is_tagged); % already as we wish it if (how == (is_tagged > 0)) return; if (how) % tag list_append(tags, create_line_mark(ListingMarkColor), -1); else % untag list_delete(tags, is_tagged-1); } %!%+ %\function{tag_all} %\synopsis{(Un)Tag all lines} %\usage{Void tag_all(how = 1)} %\description % Tag/untag all lines according to the (optional) argument how. %\seealso{tag, listing_mode, listing_map} %!%- static define tag_all() % (how = 1) { variable how = push_defaults(1, _NARGS); variable on_region = is_visible_mark(); if(on_region) narrow(); push_spot_bob(); switch (how) { case 0: set_blocal_var({}, "Tags"); } { case 1: variable tags = {}; do list_append(tags, create_line_mark(ListingMarkColor), -1); while (down_1()); set_blocal_var(tags, "Tags"); } { case 2: do tag(how); while (down_1()); } pop_spot(); if (on_region) widen(); } % Tag all lines that match a regex pattern static define tag_matching() %(how) { variable how = push_defaults(1, _NARGS); variable prompt = ["Untag", "Tag"][how==1] + " all lines containing regexp:"; variable pat = read_mini(prompt, "", ".*"); push_spot_bob(); while (re_fsearch(pat) and not(eobp)) { tag(how); eol(); go_right_1(); } pop_spot(); } % Switch to normal editing mode (text_mode) static define edit() { set_readonly(0); set_blocal_var({}, "Tags"); % untag set_blocal_var(NULL, "Current_Line"); % remove highlight from current line text_mode(); % set_status_line("", 0); } % --- Public Functions %!%+ %\function{listing_map} %\synopsis{Call a function for tagged lines.} %\usage{Void listing_map(Int scope, Ref fun, [args])} %\description % Call fun (given as reference) for marked lines, i.e. tagged lines or % the current line depending on the value of the first argument scope % 0 current line % 1 tagged lines or current line, if no line is tagged. % 2 tagged lines % The function will receive the tagged line as String as first argument and % must return an integer, with the meaning: % 0 leave tag % 1 untag line % 2 delete line % %\seealso{listing_mode, tag, list_tags} %!%- public define listing_map() % (scope, fun, [args]) { % get arguments variable scope, fun, args, buf = whatbuf(); args = __pop_args(_NARGS - 2); (scope, fun) = ( , ); variable tag, tags = (get_blocal_var("Tags")), newtags = {}, result; scope -= not(length(tags)); % -> if (scope <= 0) use current line % tag current line, if we are to use it if (scope <= 0) tags = {create_user_mark()}; !if (length(tags)) throw UsageError, "No tags set"; % Reset the static variable used by get_confirmation() Dont_Ask = 0; % now do the actual mapping set_readonly(0); loop (length(tags)) { tag = list_pop(tags); goto_user_mark(tag); if (is_line_hidden) { list_append(newtags, tag, -1); continue; } update(1); % show("calling", fun, tag); try result = @fun(line_as_string(), __push_args(args)); catch UserBreakError: { set_readonly(1); set_buffer_modified_flag(0); !if (scope <= 0) % not current line { list_append(newtags, tag, -1); list_extend(newtags, tags); set_blocal_var(newtags, "Tags"); } throw UserBreakError, "Quit"; } switch (result) { case 0: list_append(newtags, tag, -1); } % { case 1: ;} % nothing to do { case 2: setbuf(buf); delete_line(); } } set_readonly(1); set_buffer_modified_flag(0); % clean up !if (scope <= 0) % not current line (but tags) set_blocal_var(newtags, "Tags"); } %!%+ %\function{listing_list_tags} %\synopsis{Return an array of tagged lines.} %\usage{Array[String] listing_list_tags(scope=2, untag=0)} %\description % Return an array of tagged lines. % For a discussion of the \var{scope} and \var{untag} parameters % see \sfun{listing_map} %\example % Pop up a listing and let the user select some items. %#v+ % private define select_database_return_hook() % { % variable database = listing_list_tags(1); % close_buffer(); % return strjoin(database, ","); % } % define select_database() % { % dictionary_list = shell_command(dict_cmd + " --dbs", 3); % popup_buffer("*dict database*"); % insert(dictionary_list); % bob(); % listing_mode(); % set_buffer_hook("newline_indent_hook", &select_database_return_hook); % message("Select and press Return to apply"); %#v- %\seealso{listing_map, listing_mode, tag, tags_length} %!%- public define listing_list_tags() % (scope=2, untag=0) { variable scope, untag; (scope, untag) = push_defaults(2, 0, _NARGS); return [listing_map(scope, &null_fun, untag)]; } % ---- The listing mode ---------------------------------------------------- % Update hook to highlight current line. static define listing_update_hook() { move_user_mark(get_blocal_var("Current_Line")); } % --- Keybindings !if (keymap_p(mode)) copy_keymap(mode, "view"); definekey("listing->edit", "e", mode); definekey("listing->tag(2)", "t", mode); % toggle tag definekey("listing->tag(1); go_down_1", "d", mode); % dired-like definekey("listing->tag(0); go_down_1", "u", mode); % untag (dired-like) definekey("listing->tag_matching(1)", "+", mode); definekey("listing->tag_matching(0)", "-", mode); definekey("listing->tag_all(2)", "*", mode); % toggle all tags definekey("listing->tag_all(1)", "a", mode); definekey("listing->tag_all(0)", "z", mode); definekey("listing->tag_all(0)", "\e\e\e", mode); % "meta-escape" definekey("listing->tag(2); go_down_1", Key_Ins, mode); % MC like % this overwrites the page-up binding of the view map: % definekey("go_up_1; listing->tag(2)", Key_BS, mode); % Dired definekey("listing->tag(2); go_down_1", Key_Shift_Down, mode); % CUA style definekey("listing->tag(2); go_up_1", Key_Shift_Up, mode); % CUA style % --- the mode dependend menu static define listing_menu(menu) { menu_append_item(menu, "&Tag/Untag", "listing->tag(2)"); menu_append_item(menu, "Tag &All", "listing->tag_all(1)"); menu_append_item(menu, "Untag A&ll", "listing->tag_all(0)"); menu_append_item(menu, "Tag &Matching", "listing->tag_matching(1)"); menu_append_item(menu, "&Untag Matching", "listing->tag_matching(0)"); menu_append_item(menu, "&Invert Tags", "listing->tag_all(2)"); menu_append_item(menu, "&Edit Listing", "listing->edit"); % menu_append_item(menu, "&Save Listing", "save_buffer_as"); menu_append_item(menu, "&Quit", "close_buffer"); } public define listing_mode() { set_buffer_modified_flag (0); % so delbuf does not ask whether to save set_readonly(1); set_mode(mode, 0); use_keymap(mode); mode_set_mode_info(mode, "init_mode_menu", &listing_menu); % TODO set_buffer_hook("mouse_2click", &listing_mouse_2click_hook); define_blocal_var("Current_Line", create_line_mark(ListingSelectColor)); define_blocal_var("Tags", {}); % list of tagged lines set_buffer_hook("update_hook", &listing_update_hook); % mark current line run_mode_hooks(mode+"_mode_hook"); } jedmodes-2.5.7/templates/0000755000175400017500000000000011052760644013605 5ustar mildegmjedmodes-2.5.7/templates/templates.sl0000644000175400017500000002107311052760644016146 0ustar mildegm% Open templates and do some replacements % % Copyright © 2004 Günter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % 1.0 Based on template (without s) modes % from Audun Ytterdal and Dino Leonardo Sangoi % 1.1 compatibility with Mikael Hultgren's template.sl % added by Paul Boekholt % 1.1.1 2004-02-23 extension to insert_template() % 1.1.2 2004-10-11 fix: changed order of find_template and insert_template % 1.1.3 2004-11-18 fix: find_template should call insert_template_file % 1.1.4 2005-03-01 fix: insert_template_file_hook did insert an empty line % find_template now asks for both, new name and template name % 1.2 2005-04-21 new functions get_iso_date(), insert_date() % fix: replacement lagged 1 month behind real date % (as localtime().tm_mon is in the range 0...11) % 1.2.1 2005-06-03 renamed insert_date to insert_iso_date % 1.3 2005-06-10 code cleanup and reorganizing % Templates_Path is now a comma separated list of directories % Added tm documentation % 2008-08-20 08-20 add `delim' arg to search_path_for_file % as the default changes in 0.99.19 % % USAGE % % * Copy templates.sl to your Library-Path % % * Place your templates into Templates_Path % % * For a Templates menu entry, add something like this to your ~/.jedrc % % autoload("find_template", "templates"); % define templates_load_popup_hook (menubar) % { % menu_insert_item ("Save &Buffers", "Global.&File", % "&New from Template", "find_template"); % } % append_to_hook ("load_popup_hooks", &templates_load_popup_hook); % % Alternatively, add something like this to your modehooks: % % autoload("insert_template", "templates"); % define slang_mode_hook () % { % insert_template(); % } % provide("templates"); % Requirements % ============ % none % Variables % ========= % backwards compatibility (versions < 1.3 had Templates_Dir) #ifexists Templates_Dir custom_variable("Templates_Path", "Templates_Dir"); #endif %!%+ %\variable{Templates_Path} %\synopsis{Comma-separated list of template directories} %\description % List of directories where template files are stored. %\notes % This is a comma separated list similar to Color_Scheme_Path. % KDE usrers might want to set % variable Templates_Path = "~/.jed/templates,~/Desktop/Templates"; %\seealso{insert_template_file, insert_template, find_template} %!%- custom_variable("Templates_Path", path_concat(Jed_Home_Directory, "templates")); % special strings that get replaced with autogenerated values private variable replacements = Assoc_Type[String_Type]; % Functions % ========= % Return a string with current date in YYYY-MM-DD format define get_iso_date() { variable time_struct = localtime(_time); return sprintf("%d-%02d-%02d", time_struct.tm_year+1900, time_struct.tm_mon+1, time_struct.tm_mday); } public define insert_iso_date() { insert(get_iso_date()); } static define update_replacements() { replacements[""] = extract_element(get_realname(), 0, ','); replacements[""] = get_username(); replacements[""] = get_emailaddress(); replacements[""] = get_iso_date(); replacements[""] = path_basename(buffer_filename); replacements[""] = path_sans_extname(replacements[""]); % for compatibility with Mikael Hultgren's template.sl replacements["@author@"] = replacements[""]; replacements["@mail@"] = replacements[""]; replacements["@filename@"] = replacements[""]; replacements["@filename_sans@"] = replacements[""]; } define templates_add_replacement(key, repl) { replacements[key] = repl; } %!%+ %\function{expand_template_file} %\synopsis{Expand a template filename} %\usage{String expand_template_file(String name)} %\description % Search for FILE in \var{Templates_Path} and return % expanded pathname if found or the Null string otherwise. %\seealso{insert_template_file, find_template, insert_template} %!%- define expand_template_file(name) { name = search_path_for_file(Templates_Path, name, ','); if (name == NULL) return ""; return name; } % return comma separated list of all template files matching \var{glob} define list_templates() { variable dir, dirlist, list = String_Type[0]; foreach dir (strtok(Templates_Path, ",")) { dirlist = listdir(expand_filename(dir)); if (dirlist != NULL) list = [list, dirlist]; } return list; } %!%+ %\function{insert_template_file} %\synopsis{Insert a template file and replace tags} %\usage{Integer insert_template_file(String name)} %\description % Insert a template file into the buffer. The template file is % searched on the \var{Templates_Path}. % The following tags are expanded: %#v+ % = extract_element(get_realname(), 0, ','); % = get_username(); % = get_emailaddress(); % = get_iso_date(); % = path_basename(buffer_filename); % = path_sans_extname() % for compatibility with Mikael Hultgren's template.sl % @author@ = % @mail@ = % @filename@ = % @filename_sans@ = %#v- % The cursor (point) is placed at the tag or @point@. % % The return value is identical to insert file: % the number of lines inserted or -1 (if no file was found) %\seealso{find_template, insert_template, insert_file, templates_add_replacement} %!%- public define insert_template_file(name) { variable result; % insert the file push_mark(); result = insert_file(expand_template_file(name)); narrow(); % replace tags bob; update_replacements(); foreach(replacements) using ("keys", "values") replace(); % place cursor/point if (fsearch("")) deln(strlen("")); else if (fsearch("@point@")) deln(strlen("@point@")); else eob(); widen(); return result; } %!%+ %\function{insert_template} %\synopsis{Insert matching template into an empty buffer} %\usage{Void insert_template()} %\description % Hook for inserting a matching template into an empty buffer. % % A match is the first file on \var{Templates_Path} with name % modename + ".tpl" (downcased first part of modename) % "template" + extension % "template" + extension + ".tpl" % % The following filenames all match the buffername "cua.sl" %#v+ % slang.tpl, template.sl, template.sl.tpl %#v- %\example % To insert a template for every new file, %#v+ % add_to_hook("_jed_find_file_after_hooks", "insert_template"); %#v- % If you only need a template in html_mode say, add it to html_mode_hook. %\notes % This provides compatibility with Mikael Hultgren's template.sl. Put % template.sl.tpl, template.html.tpl etc. in the \var{Templates_Path}. %\seealso{insert_template, find_template} %!%- public define insert_template() { !if(bobp() and eobp()) % Return if the buffer is not empty return; variable template_file, ext = path_extname(buffer_filename()); variable modename = strlow(extract_element(get_mode_name(), 0, ' ')); % get the template file name % it looks like modename.tpl, template.cc.tpl, or template.cc template_file = expand_template_file(modename + ".tpl"); if (template_file == "" and strlen(ext)) template_file = expand_template_file("template" + ext); if (template_file == "" and strlen(ext)) template_file = expand_template_file("template" + ext + ".tpl"); % insert template file, if found if (template_file != "") () = insert_template_file(template_file); else message("no matching template found"); } %!%+ %\function{find_template} %\synopsis{Open a new buffer and insert a template} %\usage{find_template([template_name])} %\description % Opens a new buffer and asks for a template file name to insert (if not % given as optional argument) %\notes % For automatic insertion of a template into an empty buffer % a la Hultgren see \sfun{insert_template} %\seealso{Templates_Path, insert_template, insert_template_file} %!%- public define find_template() { variable newbuf = "*newfile*", template; if (bufferp(newbuf)) newbuf += "+"; template = read_with_completion(strjoin(list_templates(), ","), "Find template:", "", "", 's'); sw2buf(newbuf); () = insert_template_file(template); % set the mode (works if the template file has name "template."+ext) call_function("mode_hook", file_type(template)); set_buffer_modified_flag(0); } jedmodes-2.5.7/uri/0000755000175400017500000000000010746320360012402 5ustar mildegmjedmodes-2.5.7/uri/services.sl0000644000175400017500000000347110700205743014567 0ustar mildegm% Services, uri_hooks for some common URI schemes. % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms of the GNU General Public License (ver. 2 or later) % % This file provides some basic "*_uri_hook"s for the find|write_uri_hook % and the find|write_uri functions provided by uri.sl. % % 0.2 2007-10-01 % 0.2.1 2007-10-01 optional extensions with #if ( ) % recommends: mtools; browse_url; filelist; grep % file: local file public define file_uri_hook(path) {find_file(path);} % Universal Ressource Locators (URLs) % http: hypertext transfer protocoll % ftp: file transfer protocoll #if (expand_jedlib_file("browse_url.sl") != "") autoload("find_url", "browse_url"); public define http_uri_hook(path) { find_url("http:" + path); } public define ftp_uri_hook(path) { find_url("ftp:" + path); } #endif #ifdef UNIX % floppy: access a floppy using mtools % a: alternative shortform (used by mtools and familiar from (Win)DOS) #if (expand_jedlib_file("mtools.sl") != "") autoload("mtools_find_file", "mtools"); autoload("mtools_write", "mtools"); public define floppy_uri_hook(path) { mtools_find_file("a:"+path); } public define a_uri_hook(path) { mtools_find_file("a:"+path); } public define floppy_write_uri_hook(path) { mtools_write("a:"+path); } public define a_write_uri_hook(path) { mtools_write("a:"+path); } #endif % man: Unix man pages public define man_uri_hook(path) {unix_man(path);} % locate: locate system command interface #if (expand_jedlib_file("filelist.sl") != "") autoload("locate", "filelist"); public define locate_uri_hook(path) {locate(path);} #endif % grep: grep for a pattern % Problem: how to pass 2 arguments ("what" and "where")? % public define grep_uri_hook(path) {grep(path);} #endif % Unix provide("services"); jedmodes-2.5.7/uri/uri.sl0000644000175400017500000002114410410457627013550 0ustar mildegm% URI -- let jed handle Universal Ressource Indicators % % Copyright (c) 2006 Gnter Milde % Released under the terms of the GNU General Public License (ver. 2 or later) % % This mode parses the filename and if it forms an URI (scheme:path), calls % the appropriate _uri_hook or _write_uri_hook. % Drawbacks: % a colon [:] in the path can lead to misinterpretation % % An easily extensible set of such uri_hooks is provided by services.sl. % % see also http://www.w3.org/Addressing/ % http://www.w3.org/Addressing/URL/URI_Overview.html % http://www.w3.org/Addressing/schemes.html % % % Versions: % 1.0 first public version % 1.1 outsourced the definition of services to the services.sl % file (for faster startup) % added the provide("uri") % 1.2 2004-11-25 bugfix: find_uri returned a value if the uri did not % contain a scheme: part % 1.2.1 2005-04-21 parse_uri() code cleanup and additional check: % if there is a path-separator before the colon, % assume the path to be no URI but a simple path % containing a colon. % 1.3 2005-10-14 Bugfix in write_uri() and documentation update % 1.3.1 2006-03-21 write_uri() uses now save_buffer_as() as fallback fun % (thus asking before overwriting a file). % % USAGE: % % Put in the jed_library_path and write in .jedrc/jed.rc: % % * if you only want to use the find_uri/write_uri % autoload("find_uri", "uri"); % autoload("write_uri", "uri"); % % bind to keys of your choice or use rebind from bufutils.sl % rebind("find_file", "find_uri"); % rebind("save_buffer_as", "write_uri"); % % * if you want find_file and related functions to be URI-aware % (e.g. to be able to start jed with 'jed locate:foo.sl') % autoload("find_uri_hook", "uri"); % autoload("write_uri_hook", "uri"); % add_to_hook("_jed_write_region_hooks", &write_uri_hook); % add_to_hook("_jed_find_file_before_hooks", &find_uri_hook); % or (to check other write|find-file-hooks first) % append_to_hook("_jed_write_region_hooks", &write_uri_hook); % append_to_hook("_jed_find_file_before_hooks", &find_uri_hook); % % Problem: Currently, a relative filename is expanded before passing % it to the _jed_find_file_before_hooks, with the sideeffect of % "http://host.domain" becoming "/host.domain" % -> find_file doesnot work for URIs with a double slash % % If you want to be able to start jed with e.g. % jed http://jedmodes.sf.net/mode/uri/ % you can copy the 194 lines of the command_line_hook from site.sl % to your .jedrc and modify the 6.-last line from % () = find_file (next_file_arg); % to % () = find_uri (next_file_arg); % % CAUTION: hooks.txt says that this hook should not be customized by % the user. provide("uri"); % Requirements autoload("run_function", "sl_utils"); % _debug_info = 1; % parse uri and return (scheme, path) static define parse_uri(uri) { % currently, a filename is expanded before passing it to the % _jed_find_file_before_hooks :-( % hack to undo the change (as far as possible) if(is_substr(uri, getcwd) == 1) uri = uri[[strlen(getcwd):]]; % show("parse uri", uri); % URI = scheme:path (path can be any argument to scheme) variable fields = strchop(uri, ':', 0); % show(fields); % no scheme given if (length(fields) == 1) return("", uri); % no scheme given and ":" in a later component of the path % (the scheme must not contain a directory separator ("/" or "\") if (fields[0] != path_basename(fields[0])) return("", uri); return fields[0], strjoin(fields[[1:]],":"); } %!%+ %\function{find_uri_hook} %\synopsis{Open a universal ressource indicator} %\usage{Int_Type find_uri_hook(String_Type uri)} %\description % Open a Universal Ressource Indicator (URI) consisting of a scheme and % a path separated by a colon (":"). % % Calls a hook for the scheme with the path as argument. % Defining the appropriate hooks, it is possible to let jed % handle an extensible choice of URI schemes. % % If no matching _uri_hook is found or the argument doesnot % contain a colon, 0 is returned, otherwise 1 is returned. With %#v+ % add_to_hook("_jed_find_file_before_hooks", &find_uri_hook); %#v- % the usual file-finding functions become URI-aware. % %\example %#v+ % find_uri_hook("floppy:uri.sl"); %#v- % calls %#v+ % floppy_uri_hook("uri.sl"); %#v- % which would load uri.sl from the floppy disk (e.g. using mtools) %\notes % Unfortunately, currently, a relative filename is expanded before % passing it to the _jed_find_file_before_hooks, with the sideeffect of % "http://example.org" becoming "/example.org" (and no uri opened) % A partial workaround is to bind find_uri() or ffap() from ffap.sl % to the key used for find_file() (e.g. using \sfun{rebind}). %\seealso{find_uri, ffap, find_file, write_uri_hook} %!%- define find_uri_hook(uri) { variable scheme, path; (scheme, path) = parse_uri(uri); % show("find_uri_hook", scheme, path); % call a scheme_uri_hook with the path argument return run_function(scheme + "_uri_hook", path); } %!%+ %\function{find_uri} %\synopsis{Open a universal ressource indicator} %\usage{find_uri(String_Type uri)} %\description % A transparent expansion of find_file to Universal Ressource Indicators % (URIs, http://www.w3.org/Addressing/URL/URI_Overview.html) % Open a URI consisting of a scheme and a path separated by % a colon (":"). % % If no matching _uri_hook is found, a warning message is given. % If the argument doesnot contain a colon (i.e. is no URI), it is assumed % to be a filename and handed to find_file(). % %\notes % find_uri() does not return a value, so it can be bound to a key easily. % % While the intrinsic find_file returns an integer (success or not), % the internal find_file (as called from setkey()) has no return value. % %\seealso{write_uri, ffap, find_file, find_uri_hook} %!%- public define find_uri() % (uri=ask) { variable uri; if (_NARGS) uri = (); else uri = read_mini("Find URI", "", ""); !if (find_uri_hook(uri)) message("No scheme found to open URI " + uri); % fallback !if(is_substr(uri, ":")) () = find_file(uri); } %!%+ %\function{write_uri_hook} %\synopsis{Write to an Universal Ressource Indicator (URI)} %\usage{Integer write_uri_hook(uri)} %\description % Write to a Universal Ressource Indicator (URI) of the form % "scheme:path". % % Calls a scheme-hook for "scheme" with "path" as argument. % If no scheme-hook is found or the argument doesnot contain % a colon, 0 is returned, otherwise 1 is returned. % % The scheme-hook is a function whose name consists of the parts % "scheme" and "_uri_hook", i.e. a http-hook must be called % "http_uri_hook". It must return 1 on success and 0 otherwise. % % Defining the appropriate hooks, it is possible to let jed % handle an extensible choice of URI schemes. %\notes % With %#v+ % append_to_hook("_jed_write_region_hooks", &write_uri_hook); %#v- % jed can be made "URI aware". % % However: % Unfortunately, currently, a relative filename is expanded before % passing it to the _jed_write_region_hooks, with the sideeffect of % "http://example.org" becoming "/example.org" (and thus an attempt % is made to write example.org to the root directory). %\seealso{write_uri, write_buffer, find_uri_hook} %!%- define write_uri_hook(uri) { variable scheme, path; (scheme, path) = parse_uri(uri); % % debugging % show("write_uri_hook", uri, scheme, path); % show("run_function", scheme + "_write_uri_hook", path); % return 1; return run_function(scheme + "_write_uri_hook", path); } %!%+ %\function{write_uri} %\synopsis{Write buffer to a URI} %\usage{write_uri(String_Type uri)} %\description % Save the buffer to a universal resource indicator (URI). %\notes % Uses \sfun{save_buffer_as} from Jed >= 0.99.17 % or cuamisc.sl (http://jedmodes.sf.net/mode/cuamisc/)) %\seealso{find_uri, write_uri_hook, write_buffer, save_buffer_as} %!%- public define write_uri() % (uri=ask) { variable uri; if (_NARGS) uri = (); else uri = read_with_completion ("Write to URI:", "", whatbuf, 'f'); !if (write_uri_hook(uri)) { !if(is_substr(uri, ":")) { % push back uri + ^M (Key_Return) to simulate minibuffer input buffer_keystring(uri+"\r"); save_buffer_as(); } else message("No scheme found for writing URI " + uri); } } jedmodes-2.5.7/rimini/0000755000175400017500000000000010611416275013074 5ustar mildegmjedmodes-2.5.7/rimini/rimini.sl0000644000175400017500000001305210611416275014724 0ustar mildegm% rimini.sl % % $Id: rimini.sl,v 1.8 2007/04/09 12:01:50 paul Exp paul $ % % Copyright (c) 2003,2006,2007 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % Bash-like reverse-isearch function for the minibuffer. % To install add the following to .jedrc: % autoload ("mini_isearch", "rimini"); % !if (keymap_p ("Mini_Map")) % make_keymap ("Mini_Map"); % definekey ("mini_isearch", "^r","Mini_Map"); private variable last_isearch = ""; % don't overwrite this variable when this is autoloaded by ffap.sl custom_variable("rimini_array", NULL); % %!%+ %\function{mini_isearch} %\synopsis{Reverse incremental search the minibuffer history} %\usage{ mini_isearch ()} %\description % Does a reverse incremental search in the minibuffer history, like % the Bash shell's \var{^R} command. It can also search in some other % array, depending on what keyboard command is being executed. If you % have recent.sl, \var{find_file()} will reverse isearch the recent file % history. \var{Switch_to_buffer()} will search the buffer list, a % bit like Emacs' iswitchb. This uses the LAST_KBD_COMMAND, so % \var{^R} must be the first thing you type in the minibuffer. You must % set \var{switch_buffer_binding} to the keystring \var{switch_to_buffer()} % is bound to, if this is not \var{^X b} % % If a command sets the variable \var{rimini_array}, that will be used % instead. Make sure it gets set to NULL again. You can give a % reference to a function too, this is used in ffap.sl since it's % not necessary to run \var{recent_get_files()} until you press \var{^R}. % This file redefines \var{read_string_with_completion()} to set the % rimini_array to the list of completions. % % Press \var{^R} and type some characters to do i-searching. % Press \var{^R} twice to search for the last saved search. % Press \var{backspace} to backspace over your search string. % Press \var{^R} again to search next occurrence. % Press \var{^S} to go back to previous occurrence. % Press \var{^G} to abort. % Any other key is stuffed back into the keystroke buffer and puts the % found entry in the minibuffer (so \var{^M} will enter it immediately). % %\seealso{ffap} %!%- public define mini_isearch () { variable lines, c, s = "", n; if (rimini_array != NULL) { try { if (Array_Type == typeof(rimini_array)) lines = rimini_array; else if (Ref_Type == typeof(rimini_array)) { lines = @rimini_array; lines = lines[[::-1]]; } else lines = mini_get_lines(NULL); } finally { rimini_array = NULL; } } else if (andelse {is_defined("recent_get_files")} % get a version of recent with recent_get_files! {is_list_element("find_file insert_file", get_key_binding(LAST_KBD_COMMAND), exch, pop, ' ')}) { lines = @__get_reference("recent_get_files"); lines = lines[[::-1]]; } else if (get_key_binding(LAST_KBD_COMMAND), exch, pop == "switch_to_buffer") lines = [buffer_list(), pop]; else lines = mini_get_lines(NULL); variable matches = NULL; bol(); push_mark_eol(); variable default = bufsubstr(); erase_buffer(); insert ("isearch `':"); update(0); USER_BLOCK0 { n = 0; matches = lines[where(array_map(Integer_Type, &is_substr, lines, s))]; if (length(matches)) { erase_buffer(); insert(strcat ("isearch `", s, "': ", matches[-1])); bol(); () = ffind (":"); () = ffind (s); update(1); } else { erase_buffer(); insert(strcat ("isearch `", s, "': no match")); update(1); } } try { forever { c = getkey(); switch (c) { case 18: % ^r - search next occurrence if (s == "") { % pressing ^r twice gives you the last saved isearch s = last_isearch; X_USER_BLOCK0; } else if (length (matches) == 1 + n) beep(); else { n++; erase_buffer(); insert(strcat ("isearch `", s, "': ", matches[-1 -n])); bol; () = ffind (":"); () = ffind (s); update(1); } } { case 19: % ^s - previous occurrence if (n == 0) beep(); else { n--; erase_buffer(); insert(strcat ("isearch `", s, "': ", matches[-1 -n])); bol(); () = ffind (":"); () = ffind (s); update(1); } } { case 127 : % backspace if (strlen(s) > 1) { s = s[[:-2]]; X_USER_BLOCK0; } else { s = ""; matches = NULL; erase_buffer(); insert ("isearch `':"); update(0); } } % Do we need something for '\e'? (See isearch.sl) { #ifdef IBMPC_SYSTEM % This OK? I don't have an IBM. case 0xE0 or % \224: prefix for cursor keys on IBM #endif (c < 32) : % stop searching, ungetkey (if you pressed % enter it will be entered immediately) erase_buffer(); if (andelse { matches != NULL} {length(matches)}) { last_isearch = s; insert(matches[-1 -n]); } else insert(default); ungetkey(c); break; } { % add to search string s += char(c); X_USER_BLOCK0; } } } catch AnyError: { erase_buffer(); insert(default); } } define read_string_with_completion (prompt, dflt, list) { rimini_array=strchop(list, ',', 0); try { read_with_completion (list, prompt, dflt, Null_String, 's'); } finally { rimini_array = NULL; } } jedmodes-2.5.7/sql/0000755000175400017500000000000010461125576012410 5ustar mildegmjedmodes-2.5.7/sql/sql_sl.html0000664000175400017500000000364710214064474014602 0ustar mildegm JED Macro: sql.sl

sql.sl

creates syntax tables for SQL language. It supports most of the keywords defined in the following SQL variants: Sql92, Sql99, PostgreSql, MySql, MS SQL, Oracle PL/SQL. Each language variant has it's own set of keywords.

The comments are highlighted the same in all SQL variants:

 
  /* 
    Multiline Comment
  */
  
  -- End Of Line comment
  
If a mode should support different comments, please report.

Installation

Put the file somewhere on your jed_library_path and
   autoload ("sql_mode", "sql");
   autoload ("sql92_mode", "sql");
   autoload ("sql99_mode", "sql");
   autoload ("mssql_mode", "sql");
   autoload ("mysql_mode", "sql");
   autoload ("pgsql_mode", "sql");
   autoload ("orsql_mode", "sql");
   add_mode_for_extension ("sql", "sql");
in your .jedrc file.

When you open a file with the .sql extension, the function sql_mode() will be called which defaults to "sql92". If you wish to use a different default mode you can define the custom variable sql_default_mode in the .jedrc file:


   variable sql_default_mode = "mysql";
   
Now all files with the .sql extension (and without a mode defined in the 'modeline') will be treated as MySql files.

If you edit a file that has a syntax different than the default, you can use the modeline (a comment at the beginning of the file) to select the appropriate mode:


  -- -*- mode: pgsql; -*- 
  
The file will be treated as a PostgreSql file. jedmodes-2.5.7/sql/sql.sl0000644000175400017500000004356410340560132013546 0ustar mildegm% % Syntax coloring for SQL % % Create : 2004-02-23 % Update : 2004-12-08 % Author : Marko Mahnic % % Installation: % * put the file in a directory on jed_library_path % * to your .jedrc add: % autoload ("sql_mode", "sql"); % autoload ("sql92_mode", "sql"); % autoload ("sql99_mode", "sql"); % autoload ("mssql_mode", "sql"); % autoload ("mysql_mode", "sql"); % autoload ("pgsql_mode", "sql"); % autoload ("orsql_mode", "sql"); % add_mode_for_extension ("sql", "sql"); % % * Use the mode-line to choose a particular SQL varaint: % -*- mode: pgsql; -*- % % TODO: Analyse various SQL versions and modify keyword sets require("keywords"); % If the mode is not specified in modeline, use this mode % as default for .sql files custom_variable ("sql_default_mode", "sql92"); static define CreateSyntaxTable(sqlmode) { create_syntax_table(sqlmode); define_syntax("--", "", '%', sqlmode); define_syntax("/*", "*/", '%', sqlmode); define_syntax('"', '"', sqlmode); define_syntax('\'', '\'', sqlmode); define_syntax ('\\', '#', sqlmode); % preprocessor define_syntax ("([", ")]", '(', sqlmode); define_syntax ("0-9a-zA-Z_", 'w', sqlmode); % words define_syntax ("-+0-9.", '0', sqlmode); % Numbers define_syntax (",;.?", ',', sqlmode); define_syntax ("%$()[]-+/*=<>^#", '+', sqlmode); set_syntax_flags (sqlmode, 0x01 | 0x20); % case insensitive } static variable kwds_common = "having case null when cascade order user from float procedure table close commit " + "only decimal create grant primary rows double delete rollback then authorization " + "set foreign by constraints at as escape read execute real group of language else " + "not or on level is alter in exists fetch session to key constraint char using unique " + "insert write with time declare some asc option union add any and distinct revoke " + "all end where dec natural transaction view schema between like character begin for " + "desc cursor references int update smallint check numeric work varchar column select " + "values drop default into integer next intersect privileges except precision "; static variable kwds_9299 = "temporary table_name more c open schema_name lower cast collation collation_catalog " + "row_count constraint_catalog scale varying whenever scroll catalog_name goto returned_length " + "subclass_origin pascal output condition_number found character_set_schema diagnostics " + "count match datetime_interval_precision connection_name unnamed indicator names current " + "translation cursor_name global uncommitted sql insensitive message_octet_length input " + "pad number cobol character_length trailing action go pli octet_length allocate timezone_hour " + "section connect length system_user upper disconnect national bit_length min convert " + "avg server_name repeatable preserve are public data date nullif size external overlaps " + "column_name immediate ada exec sqlstate cascaded exception identity end-exec value " + "deferrable leading returned_sqlstate module datetime_interval_code session_user prior " + "assertion mumps position space collate connection command_function describe continue " + "class_origin deferred name fortran message_length serializable translate get max " + "partial char_length committed zone returned_octet_length dynamic_function corresponding " + "sum message_text character_set_name collation_schema extract constraint_schema nullable " + "collation_name character_set_catalog coalesce interval initially deallocate current_user " + "descriptor timezone_minute catalog constraint_name "; static variable kwds_99 = "free blob breadth parameter_name g k m called localtime static implementation call " + "trigger_name transforms ignore routine completion scope transactions_rolled_back " + "each method system user_defined_type_catalog parameter_mode referencing transaction_active " + "final array user_defined_type_schema source rollup dispatch deterministic cycle checked " + "routine_name overriding before routine_schema current_path nclob parameter large " + "path invoker parameters granted than binary key_type modify sqlexception simple parameter_specific_name " + "hold every constructor host similar alias ordinality row contains clob infix sublist " + "deref reads class security ref inout without specifictype role sets atomic limit " + "off modifies parameter_ordinal_position depth variable preorder new mod specific_name " + "transactions_committed self out operation parameter_specific_catalog overlay old " + "assignment none locator cardinality style generated object iterate start trigger_catalog " + "key_member savepoint instantiable state dynamic_function_code unnest abs options " + "aggregate defined definer postfix search existing treat asensitive localtimestamp " + "structure routine_catalog trigger under grouping destroy symmetric sequence initialize " + "boolean specific prefix destructor sensitive command_function_code current_role hierarchy " + "statement less dynamic admin transform map dictionary user_defined_type_name result " + "instance function chain bitvar after general terminate cube equals parameter_specific_schema " + "return asymmetric returns sqlwarning lateral recursive trigger_schema "; static variable kwds_92 = "sqlcode sqlerror "; static variable kwds_My = "nosort seconds append longfile selectivity atan disable java diagnose buffer rfill " + "locate open dbproc backup_pages wait sapr3 tablespace lower static selupd call ucase " + "asin ignore resource nolog pipe cosh vargraphic timezone reject snapshot synonym " + "indexname optimistic dayname tabid parse fversion whenever beginload minus ifnull " + "range degree subtime dayofmonth logfull label sysdba microsecond costlimit writer " + "usergroup variance page save initrans bufferpool week least verify maxtrans nominvalue " + "validproc log10 sqlmode curdate inproc volume lcase next_day address switch pages " + "error radians alterin modify floor count fixed toidentifier sinh defaultcode dsetpass " + "makedate tan indicator flush event sin current lfill instr get_schema sign format " + "alpha hours false raw autosave weekofyear nls_date_format container psm param minutes " + "tape shutdown clear costwarning monthname restore freepage number proc percent initcap " + "standby break pi role norewind adddate same now compute ln greatest unicode editproc " + "atan2 ascii if nls_sort dbprocedure zoned mod block nextval expand high pctused sqrt " + "months_between prev trunc pos stop decode overwrite timeout num connect obid length " + "hextoraw upper nvl optimize true priv migrate serverdb packed substr file vsize ceiling " + "topic nocycle min package soundex rowno userid replication extended addtime log subpages " + "jis object archive nls_date_language vtrace avg to_number ceil rtrim iso days currval " + "subtrans savepoint public identified state data sqlid date stat cachelimit noround " + "rowid round db_above_limit dayofweek rownum device bad abs curtime power unload lpad " + "medium add_months auto concat release to_char sysdate startpos stamp while dropin " + "bwhierarchy div cos cot synchronize blocksize quick oracle years trace monitor mapchar " + "pctfree ltrim value duplicates degrees acos log_above_limit db2 beginproc ansi reuse " + "dba chr explicit nowait dimension medianame long caches createin mbcs list subdate " + "nocache estimate space normal last_day serial timediff describe to_date get_objectname " + "continue endload unused nlssort remove db_below_limit name utcdiff months init hex " + "register fact tanh dynamic exp byte translate get max new_time digits rpad low internal " + "instance resume stddev endproc graphic try sum info uid catch dayofyear eur standard " + "enable remote debug rawtohex suspend nomaxvalue usa sounds parseid nls_language cancel " + "varchar2 microseconds config utcdate maketime sample current_schema return datediff " + "ping unlock catalog logwriter takeover recursive noorder "; static variable kwds_Ms = "isdate nvarchar substring atan kill top money right lower cast rowguidcol collation " + "month bigint atn2 asin disk parsename second setuser unknown join getansinull domain " + "openquery varying newid isolation scroll over save nocheck distributed host_name " + "current_timestamp raiserror cross inner pascal output log10 first binary radians " + "last app_name image freetext diagnostics floor dummy both match identitycol tan datetime " + "hour nchar contains sin names rule translation getutcdate sign global insensitive " + "input shutdown datename restore pad proc openxml percent local break no character_length " + "compute getdate trailing action patindex bulk octet_length sqrt offsets readtext " + "timezone_hour host_id system_user upper permissions rand textvalid disconnect current_date " + "national bit_length include lineno ceiling tran text containstable trim replication " + "prepare log convert timestamp minute relative preserve year textsize are charindex " + "bit errlvl nullif round external overlaps freetexttable usage fillfactor ada abs " + "holdlock power dbcc uniqueidentifier stats_date opendatasource formatmessage sqlca " + "outer cos cascaded cot tsequal identity clustered identity_insert ntext value deferrable " + "leading absolute degrees acos waitfor left session_user smallmoney day isnull print " + "assertion load position collate openrowset connection user_name describe reconfigure " + "nonclustered restrict deny deferred checksum updatetext writetext rowcount varbinary " + "exp translate get partial smalldatetime ident_seed char_length browse dateadd zone " + "current_time corresponding tinyint square extract coalesce interval initially deallocate " + "current_user descriptor full textptr datediff datalength sqlwarning timezone_minute " + "catalog ident_incr isnumeric "; static variable kwds_Pg = "nocreateuser temporary encoding unlisten called localtime cast trusted bigint oids " + "reset copy move each stable vacuum varying scroll excluding array inherits instead " + "procedural stdout path invoker simple freeze match offset similar ilike defaults " + "encrypted names listen rule global insensitive class security notnull input without " + "nothing recheck limit trailing action strict overlay old sysid handler assignment " + "national delimiter convert volatile stdin preserve reindex characteristics nullif " + "validator external overlaps immediate aggregate definer forward treat localtimestamp " + "owner pendant toast placing deferrable leading setof valid session_user isnull prior " + "assertion notify position createdb conversion collate template analyse statement " + "deferred backward immutable serializable abort unencrypted partial committed zone " + "lancompiler chain delimiters extract nocreatedb createuser coalesce interval initially " + "location verbose deallocate current_user operator access including "; static variable kwds_Or = "minvalue nosort increment maxlogmembers minextents groups online disable columns " + "thread tablespace share logfile colauth maxlogfiles resource manage mount each snapshot " + "synonym successful restricted system raise lists minus crash range referencing array " + "pragma resetlogs variance tabauth initrans maxextents rowlabel cycle dismount before " + "force maxtrans nominvalue maxloghistory initial base_table switch explain elsif subtype " + "modify triggers noresetlogs noarchivelog assert entry archivelog layer extent flush " + "row run limited delay body do rowtype raw delta controlfile partition remr exception_init " + "statement_id number change task scn cobol role assign storage pli cluster clusters " + "new mod block nextval out pctused compile offline audit stop own manual comment validate " + "old until reverse externally record nocycle package debugoff sqlerrm archive quota " + "start tables currval savepoint identified rowid exclusive rownum sort optimal mlslabel " + "roles compress unlimited release debugon sysdate maxinstances views under segment " + "nocompress pctfree form maxdatafiles pctincrease sequence binary_integer profile " + "number_base boolean reuse dba nowait long loop freelists parallel char_base nocache " + "link lock events normal cache analyze type positive dispose others datafile statement " + "recover freelist shared sqlbuf abort admin notfound constant digits generic maxvalue " + "instance stddev contents noaudit uid indexes become enable after separate nomaxvalue " + "xor tracing terminate exceptions cancel mode private varchar2 definition rename data_base " + "accept access including arraylen noorder "; static variable kwds_9299PgMy = "substring right month second unknown join domain isolation current_timestamp cross " + "inner first last both hour nchar local no current_date trim prepare timestamp minute " + "relative year bit usage outer absolute left day type restrict current_time full "; static variable kwds_PgMy = "minvalue increment share cycle before index force restart explain binary password " + "hold statistics row do version inout show off storage cluster new out comment until " + "none start temp exclusive replace implicit trigger database sequence boolean lock " + "load cache analyze maxvalue checkpoint function after truncate mode rename returns "; static variable kwds_MsOr = "temporary open plan sqlcode whenever goto sqlerror index found count statistics indicator " + "current false sql off dump go if allocate section connect true none file min avg " + "public date size immediate exec exit sqlstate while trigger exception database module " + "prior space continue backup fortran max checkpoint sum function use truncate return "; public define sql92_mode () { variable sql = "sql92"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_9299PgMy); keywords->add_keywords(K, kwds_9299); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_92); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } public define sql99_mode () { variable sql = "sql99"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_9299PgMy); keywords->add_keywords(K, kwds_9299); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_99); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } % PostgreSql public define pgsql_mode () { variable sql = "pgsql"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_9299PgMy); keywords->add_keywords(K, kwds_PgMy); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_Pg); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } % MySql public define mysql_mode () { variable sql = "mysql"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_9299PgMy); keywords->add_keywords(K, kwds_PgMy); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_My); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } % MS SQL mode public define mssql_mode () { variable sql = "mssql"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_MsOr); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_Ms); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } % Oracle public define orsql_mode () { variable sql = "orsql"; !if (keywords->check_language(sql)) { variable K; CreateSyntaxTable(sql); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_common); keywords->add_keywords(K, kwds_MsOr); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 0); K = keywords->new_keyword_list(); keywords->add_keywords(K, kwds_Or); keywords->sort_keywords(K); keywords->define_keywords(K, sql, 1); keywords->add_language(sql); } set_mode(sql, 4); use_syntax_table(sql); } public define sql_mode () { variable mode; mode = sprintf("%s_mode", sql_default_mode); if (is_defined(mode) > 0) eval(mode); else sql92_mode(); } jedmodes-2.5.7/zip/0000775000175400017500000000000011262367306012414 5ustar mildegmjedmodes-2.5.7/zip/jedzip.rb0000664000175400017500000000227511101372542014222 0ustar mildegm# jedzip.rb # # $Id: jedzip.rb,v 1.3 2008/10/27 17:05:21 paul Exp paul $ # # Copyright (c) 2008 Paul Boekholt. # Released under the terms of the GNU GPL (version 2 or later). require 'zip/zipfilesystem' SLang.import_namespace "listing", "Listing" class Zip::Jed < Zip::ZipFile include SLang include SLang::Listing def list set_readonly 0 begin erase_buffer entries.sort.each{|f| insert(f.to_s + "\n")} set_buffer_modified_flag 0 bob ensure set_readonly 1 end end def view_member(filename) buffername = "Zip: #{filename}" if bufferp(buffername)[0] == 1 pop2buf buffername return end pop2buf buffername contents = file.open(filename) {|f| f.read} if contents =~ /\r\n/ contents.gsub!(/\r\n/, "\n") # Set CR mode info = getbuf_info info[3] |= 0x400 setbuf_info *info end insert contents bob end def extract_member(filename, dest) dest = File.join(dest, File.basename(filename)) if File.directory? dest begin extract(filename, dest) { get_confirmation("#{dest} exists. Overwrite") } rescue Zip::ZipDestinationFileExistsError end end end jedmodes-2.5.7/zip/zip.sl0000644000175400017510000000700211262367306014243 0ustar mildemilde% zip.sl % % $Id: zip.sl,v 1.3 2009/02/07 11:16:52 paul Exp paul $ % % Copyright (c) 2008,2009 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). % % This is a mode for browsing zip archives similar to dired or filelist. % Requirements: % the Ruby module (http://www.cheesit.com/downloads/slang/slruby.html) % the RubyZip library (http://rubyzip.sourceforge.net) # autoload("zip", "zip"); define zip_find_file_hook(filename) { if (path_extname(filename) == ".zip") { zip(filename); return 1; } return 0; } append_to_hook("_jed_find_file_before_hooks", &zip_find_file_hook); # require("slruby"); require("listing"); private variable mode="zip"; rb_load_file(dircat(path_dirname(__FILE__), "jedzip.rb")); private variable Zip = rb_eval("Zip::Jed"); custom_variable("FileList_KeyBindings", "mc"); %{{{ set the member's mode private define set_mode_from_extension (ext) { variable n, mode; if (@Mode_Hook_Pointer(ext)) return; n = is_list_element (Mode_List_Exts, ext, ','); if (n) { n--; mode = extract_element (Mode_List_Modes, n, ',') + "_mode"; if (is_defined(mode) > 0) { eval (mode); return; } } mode = strcat (strlow (ext), "_mode"); if (is_defined (mode) > 0) { eval (mode); return; } } %}}} %{{{ working with the zip private define zip_open() { variable zip = get_blocal_var("Zip"); variable member = line_as_string(); if (member[[-1:]] == "/") { throw RunTimeError, "this is a directory"; } () = zip.view_member(member); set_mode_from_extension (file_type (member)); view_mode(); } private define zip_open_otherwindow() { variable buf = whatbuf(); zip_open(); pop2buf(buf); } public define zip_extract_member(line, dest, zip) { if (line[[-1:]] == "/") { throw RunTimeError, "this is a directory"; } () = zip.extract_member(line, dest); return 1; } private define zip_extract_tagged() { variable zip = get_blocal_var("Zip"); variable dest = read_with_completion("Extract file(s) to:", "", "", 'f'); listing_map(1, &zip_extract_member, dest, zip); } %}}} %{{{ keybindings, menu ifnot (keymap_p(mode)) { copy_keymap(mode, "listing"); definekey(&zip_open, "^M", mode); if (FileList_KeyBindings == "mc") { % MC bindings definekey(&zip_open, Key_F3, mode); definekey(&zip_open, Key_F4, mode); definekey(&zip_extract_tagged, Key_F5, mode); definekey(&zip_open_otherwindow, "o", mode); } else { % dired bindings definekey(&zip_extract_tagged, "C", mode); definekey(&zip_open_otherwindow, "^o", mode); definekey("listing->tag_matching(1)", "%d", mode); % tag regexp definekey("listing->tag(0); go_up_1", _Backspace_Key, mode); } } private define zip_mode() { listing_mode(); set_mode(mode, 0); use_keymap(mode); mode_set_mode_info(mode, "init_mode_menu", &listing->listing_menu); } %}}} public define zip () % [ filename ] { variable zipfile; if (_NARGS == 1) zipfile = (); else zipfile = read_with_completion("file to read", "", "", 'f'); if (1 != file_status(zipfile)) throw RunTimeError, "file zipfile$ doesn't exist"$; variable buffer = "*zip: $zipfile*"$; if (bufferp(buffer)) return pop2buf(buffer); variable zip = Zip.new(zipfile); pop2buf(buffer); erase_buffer(); define_blocal_var("Zip", zip); setbuf_info(path_basename(zipfile), path_dirname(zipfile),buffer,8); setbuf_info(getbuf_info() & ~4); () = zip.list(); zip_mode(); } provide("zip"); jedmodes-2.5.7/dict/0000755000175400017500000000000011130344607012524 5ustar mildegmjedmodes-2.5.7/dict/dict.sl0000644000175400017500000002403011130344607014006 0ustar mildegm% dict.sl % A dict client. % % $Id: dict.sl,v 1.5 2008/11/27 17:30:49 boekholt Exp $ % % Copyright (c) 2005-2008 Paul Boekholt. % Released under the terms of the GNU GPL (version 2 or later). require("socket"); require("select"); require("pcre"); require("iconv"); provide("dict"); require("bufutils"); require("view"); implements("dict"); custom_variable("Dict_Server", "localhost"); custom_variable("Dict_DB", "*"); custom_variable("Dict_Strat", "."); ifnot (keymap_p("dict")) copy_keymap("dict", "view"); $0 =_stkdepth; "dict->follow_link", "\r"; "dict->next", "\t"; "dict->previous", Key_Shift_Tab; "dict->next", "n"; "dict->previous", "p"; "dict->next", "f"; "dict->previous", "b"; "dict", "d"; "dict->back", "l"; "dict_match", "m"; loop((_stkdepth() - $0)/2) definekey("dict"); variable s, connected=0, status, line="", buf=""; variable history = NULL; variable ic; ifnot (_slang_utf8_ok) ic = iconv_open("iso-8859-1", "utf-8"); %{{{ socket define dict_close(); define dict_connect(); % This appends some data from the socket to buf, and reads one line from that % into line. define get_line() { ifnot (connected) throw RunTimeError, "I'm not connected to a dict server"; variable more, nl = is_substr(buf, "\n"), buf2; while (not nl) { more = select([s], NULL, NULL, 1); ifnot (more.nready) { dict_close(); throw RunTimeError, "Dict server is not talking."; } % Dictd will hang up after 10 minutes of inactivity. How do I check % if a connection is still open? ifnot(read(s, &buf2, 8192)) { dict_close(); throw RunTimeError, "Dict server hung up. Try again"; } buf += buf2; nl = is_substr(buf, "\n"); } line = strtrim_end(substr(buf, 1, nl)); % get rid of \r as well ifnot (_slang_utf8_ok) { try { line = iconv(ic, line); } catch RunTimeError; } buf = substr(buf, nl + 1 , -1); } define dict_write(str) { % Check if the connection is still open. variable buf2, more = select([s], NULL, NULL, 0.1); if (more.nready) { ifnot(read(s, &buf2, 8192)) { dict_close(); dict_connect(); } buf += buf2; } if (-1 == write(s, str)) throw RunTimeError, "error writing to socket"; } %}}} %{{{ server interaction define get_status() { variable p = pcre_compile("^[0-9]+"); status = ""; get_line(); if (pcre_exec(p, line)) status = pcre_nth_substr(p, line, 0); } define dict_close() { ()=close(s); line=""; buf=""; connected=0; } define dict_error() { variable msg = line; dict_close(); throw RunTimeError, msg; } define dict_connect() { if (connected) return; variable server, port, colon = is_substr(Dict_Server, ":"); if (colon) (server, port) = substr(Dict_Server, 1, colon - 1), atoi(substr(Dict_Server, colon + 1, -1)); else (server, port) = Dict_Server, 2628; s = socket (PF_INET, SOCK_STREAM, 0); connect(s, server, port); connected=1; get_status(); if(status != "220") return dict_error(); } % read and insert an answer delimited by a . on a single line define read_answer() { forever { get_line(); ifnot (strncmp(line, ".", 1)) { if (strncmp(line, "..", 2)) return; else line = substr(line, 2, -1); } insert(line); newline(); } } %}}} %{{{ history variable Def_Type= struct { prev, def, line, column, type % 0: search 1: match }; define back() { if (history == NULL || history.prev == NULL) throw RunTimeError, "can't go back"; history = history.prev; set_readonly(0); erase_buffer(); insert(history.def); fit_window(); goto_line(history.line); goto_column(history.column); set_readonly(1); set_buffer_modified_flag(0); } define history_add(t) { mark_buffer(); history; history = @Def_Type; history.prev = (); history.def = bufsubstr(); history.type = t; history.line = 1; history.column = 1; } define store_position() { if ("*dict*" != whatbuf() || history == NULL) return; history.line = what_line(); history.column = what_column(); } %}}} %{{{ menu define set_db_callback(db) { Dict_DB = db; } define database_popup(menu) { dict_connect(); dict_write("show db\r\n"); get_status(); if(strncmp(line, "110", 3)) throw RunTimeError, sprintf("dict error: %s", line); variable item; foreach item (["* All dictionaries", "! First matching dictionary\n"]) { menu_append_item(menu, item, &set_db_callback, strtok(item)[0]); } forever { get_line(); ifnot (strncmp(line, ".", 1)) { if (strncmp(line, "..", 2)) break; else line = line[[1:]]; } menu_append_item(menu, line, &set_db_callback, strtok(line)[0]); } get_status(); if(status != "250") dict_error(); } define set_strategy_callback(strategy) { Dict_Strat = strategy; } define strategy_popup(menu) { dict_connect(); dict_write("show strat\r\n"); get_status(); if(strncmp(line, "111", 3)) throw RunTimeError, sprintf("dict error: %s", line); menu_append_item(menu, ". Server default", &set_strategy_callback, "."); forever { get_line(); ifnot (strncmp(line, ".", 1)) { if (strncmp(line, "..", 2)) break; else line = line[[1:]]; } menu_append_item(menu, line, &set_strategy_callback, strtok(line)[0]); } get_status(); if(status != "250") dict_error(); } define dict_menu(menu) { menu_append_item(menu, "define", "dict"); menu_append_item(menu, "match", "dict_match"); menu_append_popup(menu, "&database"); menu_set_select_popup_callback(menu + ".&database", &database_popup); menu_append_popup(menu, "&strategy"); menu_set_select_popup_callback(menu + ".&strategy", &strategy_popup); menu_append_item(menu, "&Quit", "close_buffer"); } %}}} %{{{ dict mode variable begin_marker = sprintf("\e[%d]", color_number("keyword")), end_marker = "\e[0]"; define next() { go_right(fsearch(begin_marker)); } define previous() { if(bsearch(end_marker)) go_right(bsearch(begin_marker)); } define query(); define search(); define follow_link() { if (history.type) return query(sprintf("DEFINE %s\r\n", line_as_string())); push_spot; variable db = Dict_DB; if (re_bsearch("^From .* \\[\\([a-zA-Z]+\\)\\]$")) db = regexp_nth_match(1); goto_spot(); ifnot (bsearch(begin_marker)) return; push_mark; while(re_bsearch("\e\\[[0-9]+\\]")) { if (regexp_nth_match(0) == end_marker) { pop_mark_1(); break; } else { pop_mark_0(); push_mark(); } } go_right(5); push_mark(); pop_spot(); ifnot (fsearch(end_marker)) return pop_mark_0(); variable word = bufsubstr(); variable pos, re=pcre_compile("\e\\[[0-9]+\\]"); while (pcre_exec(re, word)) { word = str_replace_all(word, pcre_nth_substr(re, word, 0), ""); } search(db, strcompress(word, " \r\n")); } % When closing the *dict* buffer, also close the connection. define dict_close_buffer(buf) { popup_close_buffer_hook(buf); history = NULL; dict_close(); } %!%+ %\function{dict_mode} %\synopsis{Mode of the *dict* buffer} %\usage{Void dict_mode ();} %\description % This is a mode for searching a dictionary server implementing % the protocol defined in RFC 2229. % \var{q} close the dictionary buffer % \var{h} display this help information % \var{d} ask for a new word to look up % \var{n}, \var{f}, \var{Tab} place point to the next link % \var{p}, \var{b}, \var{S-Tab} place point to the prev link % \var{Return} follow link % \var{l} go back % \var{m} ask for a pattern and list all matching words. %!%- define dict_mode() { view_mode(); use_keymap("dict"); _set_buffer_flag(0x1000); define_blocal_var("close_buffer_hook", &dict_close_buffer); mode_set_mode_info ("dict", "init_mode_menu", &dict_menu); run_mode_hooks("dict_mode_hook"); set_mode("dict", 0); } define dict_buffer() { dict_connect(); popup_buffer("*dict*"); dict_mode(); } variable re_152 = pcre_compile("^152 (\\d+)"); define match(word) { dict_connect(); store_position(); dict_write(sprintf("MATCH %s %s \"%s\"\r\n", Dict_DB, Dict_Strat, word)); get_status(); set_readonly(0); erase_buffer(); set_line_color(0); if(pcre_exec(re_152, line)) { vinsert("%s matches for %s\n", pcre_nth_substr(re_152, line, 1), word); read_answer(); get_status(); if(status != "250") dict_error(); } else insert(line); fit_window(); history_add(1); bob(); set_readonly(1); set_buffer_modified_flag(0); } variable re_150 = pcre_compile("^150 (\\d+)"), re_151 = pcre_compile("151 \".*\" (.*) \"(.*)\"$"); define query(q) { dict_connect(); store_position(); dict_write(q); get_status(); if(status=="552") return message ("no match"); set_readonly(0); erase_buffer(); set_line_color(0); if(pcre_exec(re_150, line)) { loop(atoi(pcre_nth_substr(re_150, line, 1))) { get_status(); if (pcre_exec(re_151, line)) { set_line_color(color_number("keyword1")); vinsert("From %s [%s]", pcre_nth_substr(re_151, line, 2), pcre_nth_substr(re_151, line, 1)); newline(); set_line_color(0); } else insert(line); read_answer(); } get_status(); if(status != "250") dict_error(); } else insert(line); bob(); while(re_fsearch("^[^{]+}")) % escape-sequence coloring does not span lines { insert(begin_marker); ifnot(down_1) break; } bob(); replace("{", begin_marker); replace("}", end_marker); fit_window(); history_add(0); bob(); set_readonly(1); set_buffer_modified_flag(0); } define search(word) % [db] { if (_NARGS < 2) Dict_DB; variable db = (); query(sprintf("DEFINE %s \"%s\"\r\n", db, word)); } %}}} public define dict_lookup() { ifnot (_NARGS) get_word(); dict_buffer(); search(); } public define dict() { read_mini("word", get_word(), ""); dict_buffer(); search(); } public define dict_match() { read_mini("word", get_word(), ""); dict_buffer(); match(); } jedmodes-2.5.7/bufutils/0000755000175400017500000000000011307553726013450 5ustar mildegmjedmodes-2.5.7/bufutils/bufutils.sl0000644000175400017500000007334511307553726015661 0ustar mildegm% bufutils.sl Tools for buffer and windows handling % % Copyright (c) 2006 Guenter Milde (milde users.sf.net) % Released under the terms% of the GNU General Public License (version 2 or later). % % Versions % -------- % % 1.0 first public version % 1.1 bugfix: restore_buffer now resets the "changed on disk" flag % 1.2 new: "blocal_hooks" % 1.2.2 "outsourcing" of window_set_rows (hint by Thomas Clausen) % 1.3 moved most often used programming helpers to sl_utils.sl % new: (key_prefix="") argument to rebind, rebind_reserved % (hint and bugfix Paul Boekholt) % rework of popup_buffer % - do not reuse popups % - reload old buffer when closing (Paul Boekholt) % 1.4 new: help_message(): Give mode-dependend help message % arrayread_file(name): read file to array (P. Boekholt) % changed: close_buffer calls blocal_hook % popup_buffer uses this % moved next_buffer() to cuamisc.sl % renamed restore_buffer() to reload_buffer() % 1.4.1 bugfix popup_buffer/close_buffer/popup_close_buffer_hook % bugfix reload_buffer() % 2004-03-17 1.5 new function bufsubfile() (save region|buffer to a tmp-file) % 2004-03-23 1.5.1 bugfix: spurious ";" in delete_temp_files() % 1.6 moved untab_buffer() from recode.sl here % 1.6.1 small bugfix in bufsubfile() % 2005-03-24 1.7 bufsubfile() always writes a temp-file (hint P. Boekholt) % (-> more consistency, no asking) % removed custom var Bufsubfile_Save_Ask) % bufsubfile() takes an optional argument `base` % 2005-03-31 1.7.1 made slang-2 proof: A[[0:-2]] --> A[[:-2]] % 2005-04-01 1.8 fast strread_file() (Paul Boekholt) % 2005-04-08 1.8.1 made preparse-proof % "#if (_slang_version < 2000)" cannot be preparsed % 1.8.2 bugfix in bufsubfile(): use path_basename() of whatbuf() % (important, if the buffer name is e.g. % "http://jedmodes.sf.net") % 2005-10-13 1.8.3 bugfix reload_buffer(): reset the changed on disk argument % permanently % 2005-11-08 1.8.4 simplified reload_buffer() again, as jed 0.99.17.135 % will reset the buffer's ctime field if the changed-on-disk % flag is reset % 2005-11-21 1.8.5 removed public from popup_buffer() definition % 2005-11-25 1.8.6 bugfix in close_buffer(): % switch back to current buffer if closing a different one % 2006-01-11 1.9 bugfix in close_and_insert_word and close_and_replace_word % (report Paul Boekholt) % revised approach to "backswitching" after a buffer is closed % 2006-05-29 1.10 run_local_hook() tries mode_get_mode_info(hook) before % get_blocal(hook) % custom var Jed_Temp_Dir renamed to Jed_Tmp_Directory % (which is new in site.sl since 0.99.17.165) % 2006-06-19 1.11 fit_window(): abort if there is only one open window % 2006-10-04 1.12 bufsubfile() uses make_tmp_file(), documentation update % 2006-10-23 1.13 bugfix in bufsubfile() by Paul Boekholt % "\\/ " specifies a character class '/' % 2006-11-23 1.13.1 bugfix in reload_buffer(): reset "changed on disk" flag % before erasing buffer (to prevent asking befor edit) % 2007-04-18 1.14 new function run_local_function() (used in help.sl) % example for "Fit Window" menu entry % TODO: (should this become an INITIALIZATION block?) % 2007-05-11 1.15 removed non-standard fun latex_compose() from documentation % run_local_function(): try mode-info also with % normalized_modename() % use mode_info instead of global var for help_message() % 2008-01-11 1.16 reload_buffer(): insert disk version, delete content later % preventing an empty buffer after undo(), % Minor code and doc edits (cleanup). % 2008-01-21 1.17 fit_window(): recenter if window contains whole buffer % 2008-05-05 1.17.1 reload_buffer(): backup buffer (if modified and backups % are not disabled) before re-loading) % 2008-06-18 1.18 New function get_local_var() % 2009-10-05 1.19 New function reopen_file() % 2009-12-08 1.19.1 adapt to new require() syntax in Jed 0.99.19 provide("bufutils"); % Requirements % ------------ % Jed >= 0.99.17.135 for proper working of reload_buffer() % but at least Jed >= 0.99.16 (mode_set_mode_info() with arbitrary fields) % standard (but not loaded by default): #if (_jed_version > 9918) require("keydefs", "Global"); #else require("keydefs"); % symbolic constants for many function and arrow keys #endif % jedmodes.sf.net modes: autoload("get_blocal", "sl_utils"); autoload("push_defaults", "sl_utils"); autoload("run_function", "sl_utils"); autoload("get_word", "txtutils"); autoload("mark_word", "txtutils"); % Functions % --------- % Convert the modename to a canonic form (the donwcased first part) % This can be used for mode-dependend help, variables, ... define normalized_modename() % (mode=get_mode_name()) { variable mode = push_defaults(get_mode_name, _NARGS); mode = extract_element(mode, 0, ' '); if (mode == "") mode = "no"; return strlow (mode); } % Local variables, functions, and hooks % ------------------------------------- % % Tools for the definition and use of mode- or buffer local settings -- just like % the indent_hook or the newline_and_indent_hook jed already provides. Extend % this idea to additional settings that can be set by a mode and used by another. % Allows customisation to be split in a "language" mode that provides % functionality and an "emulation" mode that does the keybinding. % % Implementation is done via blocal vars and the mode_*_mode_info functions. % % A hook can be defined either a pointer (reference) to a function or the function % name as string. %!%+ %\function{get_local_var} %\synopsis{Return value of either buffer-local or mode-local variable.} %\usage{get_local_var(name, default=NULL)} %\description % Return the value of variable/setting \var{name}, either % * buffer-local (blocal) variable \var{name}, % * mode-local (\sfun{with mode_get_mode_info}), or % * \var{default} (defaulting to \var{NULL}) %\notes % The value of a buffer- or mode-local setting is tested against % \var{NULL}, so e.g. a buffer-local variable with value NULL is treated % like a non-existing blocal variable. %\seealso{get_blocal_var, mode_get_mode_info, run_local_function, run_local_hook} %!%- define get_local_var() % (name, default=NULL) { variable name, default; (name, default) = push_defaults( , NULL, _NARGS); variable value = get_blocal_var(name, NULL); if (value == NULL) { value = mode_get_mode_info(name); if (value == NULL) { value = mode_get_mode_info(normalized_modename(), name); if (value == NULL) { value = default; } } } return value; } %!%+ %\function{run_local_function} %\synopsis{Run a local function if it exists, return if fun is found} %\usage{Int_Type run_local_function(fun, [args])} %\description % Similar to \sfun{run_local_hook}, but return an Integer indicating % whether a local function was found. %\seealso{run_local_hook, run_function} %!%- define run_local_function() % (fun, [args]) { variable args = __pop_args(_NARGS-1); variable fun = (); variable lfun = get_local_var(fun); if (lfun == NULL) lfun = sprintf("%s_%s", normalized_modename(), fun); return run_function(lfun, __push_args(args)); } %!%+ %\function{run_local_hook} %\synopsis{Run a local hook if it exists} %\usage{ Void run_local_hook(String hook, [args])} %\description % The hook is looked for in the following places: % % * the blocal variable \var{hook}, % * the mode info field \var{hook}, or % * a function with name _\var{hook} % [i.e. sprintf("%s_%s", normalized_modename(), hook)] % % and can be defined with one of %#v+ % define_blocal_var("", &); % define_blocal_var("", ""); % mode_set_mode_info("", ""); % mode_set_mode_info("", "", ""); % define _() { } %#v- % This way a mode can set a mode- or buffer-dependent function to a common % keybinding. %\example % Set up a key to do a default action on a buffer ("run it"): %#v+ % define run_buffer() { run_local_hook("run_buffer_hook"); } % setkey("run_buffer", "^[^M"); % Alt-Return % mode_set_mode_info("SLang", "run_buffer_hook", "evalbuffer"); % mode_set_mode_info("python", "run_buffer_hook", "py_exec"); %#v- %\seealso{runhooks, run_local_function, get_blocal, run_buffer} %!%- define run_local_hook() % (hook, [args]) { variable args = __pop_args(_NARGS); % call run_local_function and discard the return value () = run_local_function(__push_args(args)); } % deprecated, use run_local_hook instead define run_blocal_hook() % (hook, [args]) { variable args = __pop_args(_NARGS-1); variable hook = (); () = run_function(get_blocal(hook, NULL), __push_args(args)); } %!%+ %\function{run_buffer} %\synopsis{"Run" the current buffer} %\usage{Void run_buffer()} %\description % "Run" the current buffer. The actual function performed is defined by % the local "run_buffer_hook" (see \sfun{run_local_hook}). %\example % Some modes set the "run_buffer_hook" by themself, for others you can use % \sfun{mode_set_mode_info} (since Jed 0.99.17), e.g. %#v+ % mode_set_mode_info("SLang", "run_buffer_hook", "evalbuffer"); %#v- % or using mode_hooks (this variant is also proof for Jed <= 0.99.16) %#v+ % define calc_mode_hook () % { % define_blocal_var("run_buffer_hook", "calc_make_calculation"); % set_buffer_undo(1); % } %#v- %\seealso{run_local_hook, evalbuf} %!%- public define run_buffer() { run_local_hook("run_buffer_hook"); } % Set the mode-dependend string with help (e.g. on keybindings) define set_help_message() % (str, mode=get_mode_name()) { variable str, mode; % optional argument (str, mode) = push_defaults(get_mode_name(), _NARGS-1); mode_set_mode_info(mode, "help_message", str); } % Show a mode-dependend string with help (e.g. on keybindings) define help_message() { variable str = get_local_var("help_message"); if (str == NULL) str = sprintf("no help available for '%s' mode", get_mode_name()); message(str); } % --- window operations ---------------------------------------------- %!%+ %\function{window_set_rows} %\synopsis{Make the current window \var{n} rows big} %\usage{window_set_rows(Int n)} %\usage{window_set_rows(Double_Type n)} %\description % Resizes the current window: % If \var{n} is of Double_Type (e.g. 0.5), the window is rezized to % this fraction of the screen. % If there is only one window, a new window is created. % If \var{n} is zero, the window is deleted % If \var{n} is negative, the window is reduced by \var{n} lines. % (Use loop(n) enlargewin(); to get relative enlargement.) %\notes % If there are more than two windows open, the function might not work as % desired. %\seealso{fit_window, enlargewin, splitwindow, onewindow} %!%- define window_set_rows(n) { % convert n from fraction to absolute if Double_Type: if (typeof(n) == Double_Type) n = int((SCREEN_HEIGHT - TOP_WINDOW_ROW - 2) * n); if (n == 0) call("delete_window"); if (n < 0) n += window_info('r'); if (nwindows() - MINIBUFFER_ACTIVE == 1) splitwindow(); if (n >= SCREEN_HEIGHT - TOP_WINDOW_ROW - 2) onewindow(); variable misfit = n - window_info('r'); if (misfit > 0) { % window too small loop(misfit) enlargewin(); } if (misfit < 0) { % window too large otherwindow(); loop(-misfit) enlargewin (); loop(nwindows() - 1) otherwindow(); } if (eobp) recenter(n); } %!%+ %\function{fit_window} %\synopsis{Fit the window size to the lenght of the buffer} %\usage{fit_window (max_rows=1.0)} %\description % If there is more than one window open, the size of the current window is % adapted to the length of the buffer it contains. The optional argument % \var{max_rows} gives the upper limit for the window size, either as % proportion of the total space (\var{Double_Type}) or as number of lines % (\var{Integer_Type}). The default max_rows=1.0 means no limit, max_rows=0 % means: don't fit. %\example % To add a "Fit Window" entry to the "Windows" menu, you can define (or amend) % a popup-hook e.g. %#v+ % autoload("fit_window", "bufutils"); % define fit_window_load_popup_hook(menubar) % { % menu_insert_item(4, "Global.W&indows", "&Fit Window", "fit_window"); % } % append_to_hook("load_popup_hooks", &fit_window_load_popup_hook); %#v- %\seealso{window_set_rows, enlargewin, popup_buffer} %!%- public define fit_window () % fit_window(max_rows = 1.0) { variable max_rows = push_defaults(1.0, _NARGS); % abort, if there is only one window (or max_rows is 0) if (nwindows() - MINIBUFFER_ACTIVE == 1 or max_rows == 0) return; % convert max_rows from fraction to absolute if Double_Type: if (typeof(max_rows) == Double_Type) max_rows = int((SCREEN_HEIGHT - TOP_WINDOW_ROW - 1) * max_rows); % get the number of lines in the current buffer push_spot(); eob; variable wanted_rows = what_line; pop_spot(); % limit to max_rows if (wanted_rows > max_rows) wanted_rows = max_rows; % fit window window_set_rows(wanted_rows); % if window contains whole buffer, put last line at bottom line if (wanted_rows <= max_rows) recenter(what_line()); } % --- closing the buffer ------------------------------------------------- %!%+ %\function{close_buffer} %\synopsis{Close the current (or given) buffer} %\usage{ Void close_buffer(buf = whatbuf())} %\description % Close the current (or given) buffer. % Run the blocal "close_buffer_hook" %\seealso{delbuf, close_window, popup_buffer, set_blocal_var} %!%- public define close_buffer() % (buf = whatbuf()) { variable buf = push_defaults(whatbuf(), _NARGS); variable currbuf = whatbuf(); sw2buf(buf); run_local_hook("close_buffer_hook", buf); delbuf(buf); % make sure to stay in the current buffer after closing a different one if (currbuf != buf) sw2buf(currbuf); } % close buffer in second window if there are two windows define close_other_buffer () { if (nwindows () - MINIBUFFER_ACTIVE > 1) { otherwindow(); close_buffer(); } } %!%+ %\function{close_and_insert_word} %\synopsis{Close buffer, insert current word in calling buffer} %\usage{close_and_insert_word()} %\description % Close buffer, insert current word in the buffer indicated by % the buffer-local ("blocal") variable "calling_buffer". %\notes % The \sfun{popup_buffer} function automatically records the calling % buffer. %\seealso{close_and_replace_word, get_word, popup_buffer, close_buffer} %!%- define close_and_insert_word() { variable word = get_word(), calling_buf = get_blocal("calling_buf", ""); close_buffer(); if (bufferp(calling_buf)) sw2buf(calling_buf); else verror("calling buffer \"%s\" does not exist", calling_buf); insert(word); } %!%+ %\function{close_and_replace_word} %\synopsis{Close buffer, replace current word in calling buffer} %\usage{close_and_replace_word()} %\description % Close buffer, insert current word into the buffer indicated by the blocal % variable "calling_buffer" replacing the current word (or visible region) % there. %\notes % The \sfun{popup_buffer} function automatically records the calling % buffer. %\seealso{close_and_insert_word, popup_buffer, close_buffer, get_blocal} %!%- define close_and_replace_word() { variable word = get_word(), calling_buf = get_blocal("calling_buf", ""); close_buffer(); if (bufferp(calling_buf)) sw2buf(calling_buf); else verror("calling buffer \"%s\" does not exist", calling_buf); !if (is_visible_mark) mark_word; del_region(); insert(word); } % go to the buffer, if it is already visible (maybe in another window) % open it in the current window otherwise define go2buf(buf) { if(buffer_visible(buf)) pop2buf(buf); % open in other window else sw2buf(buf); % open in current window } % Popup Buffer % ------------ custom_variable("Max_Popup_Size", 0.7); % max size of one popup window % TODO: do we want support for more than 1 popup window in parrallel % (i.e. more than 2 open windows): % custom_variable("Popup_max_popups", 2); % max number of popup windows % custom_variable("Popup_max_total_size", 0.7); % max size of all popup windows % close popup window, if the buffer is visible and resizable define popup_close_buffer_hook(buf) { % abort if buffer is not attached to a window !if (buffer_visible(buf)) return; variable replaced_buf = get_blocal("replaced_buf", ""); variable calling_buf = get_blocal("calling_buf", ""); % resizable popup window: close it if (get_blocal_var("is_popup") != 0) call("delete_window"); else { if (bufferp(replaced_buf)) { sw2buf(replaced_buf); fit_window(get_blocal("is_popup", 0)); % resize popup window } } % Return to the minibuffer line, if opened from there if (calling_buf == " " and MINIBUFFER_ACTIVE) loop (nwindows()) { otherwindow(); if (whatbuf() == " ") break; } % Return to calling buffer (if it is visible, it might be annoying if % closing a help buffer pops up some buffer no longer in active use). else if (buffer_visible(calling_buf)) sw2buf(calling_buf); } %!%+ %\function{popup_buffer} %\synopsis{Open a "popup" buffer} %\usage{popup_buffer(buf=whatbuf(), max_rows=Max_Popup_Size)} %\description % The "popup" buffer opens in a second window (using pop2buf). % Closing with close_buffer closes the popup window (if new) % or restores the previous buffer (if reused). % % The blocal variable "is_popup" marks the buffer as "popup". % It contains the upper limit when fitting the window or 0 if the window % should not be resized. % %\example % Open a popup window and fit (if applicable) after inserting stuff: %#v+ % popup_buffer(buf); % insert("hello world"); % % insert_file("hello.txt"); % fit_window(get_blocal("is_popup", 0)); %#v- % %\seealso{setbuf, sw2buf, close_buffer, fit_window, delete_window} %!%- define popup_buffer() % (buf=whatbuf(), max_rows = Max_Popup_Size) { % get arguments variable buf, max_rows; (buf, max_rows) = push_defaults(whatbuf(), Max_Popup_Size, _NARGS); variable replaced_buf, calling_buf = whatbuf(); variable open_windows = nwindows() - MINIBUFFER_ACTIVE; % before opening new % Open/go_to the buffer, store the replaced buffers name replaced_buf = pop2buf_whatbuf(buf); % The buffer is displayed % a) in a new window or reusing a popup window % -> we can savely fit the window and close it when closing the buffer % or % b) in an existing "permanent" (non-popup) window. % -> set max_rows to 0 to prevent meddling in existing split schemes. if (open_windows > 1) { sw2buf(replaced_buf); if (get_blocal("is_popup", 0) == 0) max_rows = 0; sw2buf(buf); } define_blocal_var("is_popup", max_rows); define_blocal_var("close_buffer_hook", &popup_close_buffer_hook); define_blocal_var("replaced_buf", replaced_buf); if (buf != calling_buf) define_blocal_var("calling_buf", calling_buf); } % --- push_keymap/pop_keymap --- (turn on/off a minor mode) ---------------- % % see also push_mode/pop_mode from pushmode.sl private variable _stack_name = "keymap_stack"; % temporarily push the keymap define push_keymap(new_keymap) { !if (blocal_var_exists(_stack_name)) define_blocal_var(_stack_name, {}); variable keymaps = get_blocal_var(_stack_name); variable old_keymap = what_keymap(); variable mode, flag; (mode, flag) = what_mode(); use_keymap(new_keymap); % push the old keymap and mode name on blocal stack list_append(keymaps, mode); list_append(keymaps, old_keymap); % append the new keymap to the modename set_mode(sprintf("%s (%s)", mode, new_keymap), flag); %Test show("keymap stack is:", get_blocal(_stack_name)); %Test show("current keymap is:", what_keymap()); } define pop_keymap() { variable keymaps = get_blocal_var(_stack_name); variable old_keymap = list_pop(keymaps, -1); variable old_mode = list_pop(keymaps, -1); variable flag; (, flag) = what_mode(); use_keymap(old_keymap); set_mode(old_mode, flag); %Test show("keymap stack is:", get_blocal(_stack_name)); %Test show("current keymap is:", what_keymap()); } %!%+ %\function{rebind} %\synopsis{Rebind all keys bound to \var{old_fun} to \var{new_fun}.} %\usage{rebind(old_fun, new_fun, keymap=what_keymap(), prefix="")} %\description % The function acts on the local keymap (if not told otherwise by the % \var{keymap} argument. It scans for all bindings to \var{old_fun} with % \sfun{which_key} and sets them to \var{new_fun}. %\example % The email mode (email.sl) uses rebind to bind the mode-specific formatting % function to the key(s) used for format_paragraph: %#v+ % rebind("format_paragraph", "email_reformat", mode); %#v- %\notes % If the optional argument \var{prefix} is not empty, the prefix will be % prepended to the key to bind to. Use this to create "maps" of bindings % that reflect the users normal binding, e.g. with \var{_Reserved_Key_Prefix} % (this is what \sfun{rebind_reserved} does). %\seealso{setkey, local_setkey, definekey, definekey_reserved} %!%- define rebind() % (old_fun, new_fun, keymap=what_keymap(), prefix="") { variable old_fun, new_fun, keymap, prefix; (old_fun, new_fun, keymap, prefix) = push_defaults( , , what_keymap(),"", _NARGS); variable key; loop (which_key(old_fun)) { key = (); definekey(new_fun, prefix + key, keymap); } } %!%+ %\function{rebind_reserved} %\synopsis{Rebind a function prepending the \var{_Reserved_Key_Prefix}} %\usage{ rebind_reserved(old_fun, new_fun, keymap)} %\description % Call \sfun{rebind} with \var{prefix} set to \var{_Reserved_Key_Prefix}. %\notes % The action is more a remodelling than a rebinding, the name should reflect % the close relation to the \sfun{rebind} function. %\seealso{rebind, definekey_reserved, setkey_reserved} %!%- define rebind_reserved(old_fun, new_fun, keymap) { rebind(old_fun, new_fun, keymap, _Reserved_Key_Prefix); } % --- some more buffer related helpers ---------------------------------- %!%+ %\function{buffer_dirname} %\synopsis{Return the directory associated with the buffer} %\usage{Str buffer_dirname(buf=whatbuf())} %\description % Return the directory associated with the buffer %\seealso{getbuf_info, buffer_filename} %!%- define buffer_dirname() { variable dir, args = __pop_args(_NARGS); ( , dir, , ) = getbuf_info(__push_args(args)); return dir; } %!%+ %\function{arrayread_file} %\synopsis{Read a file and return it as array of lines.} %\usage{Array[String] arrayread_file(name)} %\description % Read a file and return it as a String_Type array of lines. % Newlines are preserved. %\notes % To get rid of the newlines, you can do %#v+ % result = array_map(String_Type, &strtrim_end, arrayread_file(name), "\n"); %#v- %\seealso{strread_file, fgetslines} %!%- define arrayread_file(name) { variable fp = fopen (name, "r"); if (fp == NULL) verror ("File %s not found", name); fgetslines(fp); () = fclose (fp); } %!%+ %\function{strread_file} %\synopsis{Read a file and return as (binary) string} %\usage{BString strread_file(String name)} %\description % Read a file and return as string (\var{BString_Type}). %\notes % If the file size exceeds the internal limit (currently 5MB), % an error is returned. %\seealso{arrayread_file, find_file, fread, fread_bytes} %!%- define strread_file(name) { % return strjoin(arrayread_file(name), ""); variable size_limit = 5000000; % this should be a custom var variable fp = fopen(name, "r"), str; if (fp == NULL) verror ("Failed to open \"%s\"", name); #ifnexists _slang_utf8_ok % (_slang_version < 2000) if (-1 == fread(&str, Char_Type, size_limit, fp)) #else if (-1 == fread_bytes(&str, size_limit, fp)) #endif error("could not read file"); !if (feof(fp)) verror("file exceedes limit (%d bytes)", size_limit); return str; } %!%+ %\function{reload_buffer} %\synopsis{Restore (or update) a buffer to the version on disk} %\usage{reload_buffer()} %\description % Replace the buffer contents with the content of the associated file. % This will restore the last saved version or update (if the file changed % on disk). %\seealso{insert_file, find_file, write_buffer, make_backup_filename} %!%- public define reload_buffer() { variable file, dir, name, flags; (file, dir, name, flags) = getbuf_info(); variable col = what_column(), line = what_line(); % save to backup file if (flags & 0x001 % buffer modified and not(flags & 0x100)) % backups (not) disabled { % use write_region_to_file() to prevent attaching buffer to backup file mark_buffer(); () = write_region_to_file(make_backup_filename(dir, file)); } % Variant: only update (make this an option?) % !if (flags & 4) % return; % reset the changed-on-disk flag setbuf_info(file, dir, name, flags & ~0x004); erase_buffer(whatbuf()); () = insert_file(path_concat(dir, file)); goto_line(line); goto_column_best_try(col); set_buffer_modified_flag(0); } %!%+ %\function{reopen_file} %\synopsis{Re-open file \var{file}.} %\usage{reopen_file(file)} %\description % In contrast to \sfun{reload_buffer}, \sfun{reopen_file} takes a % (full) filename as argument. % % To prevent questions about changed versions on disk, it avoids switching % to the buffer. Instead, it closes the buffer and re-loads the file with % find_file(). % % Does nothing if file is up-to-date or not attached to any buffer. %\seealso{} %!%- define reopen_file(file) { % Put the list of buffers in an array instead of looping over % buffer_list(). This way leftovers after a `break` or `return` are % automatically removed from the stack. variable buffers = [buffer_list(), pop]; variable buf, dir, f, flags; foreach buf (buffers) { (f, dir, ,flags) = getbuf_info(buf); if (dir + f == file and flags & 4) { % file that changed on disk delbuf(buf); () = find_file(file); % try to restore the point position from the recent files cache call_function("recent_file_goto_point"); break; } } } % ------- Write the region to a file and return its name. ----------------- % Directory for temporary files % Backwards compatibility to earlier versions of bufutils.sl #ifexists Jed_Temp_Dir custom_variable("Jed_Tmp_Directory", Jed_Temp_Dir); #endif custom_variable("Jed_Tmp_Directory", getenv("TEMP")); if (Jed_Tmp_Directory == NULL) Jed_Tmp_Directory = getenv("TMP"); if (Jed_Tmp_Directory == NULL) Jed_Tmp_Directory = "/tmp"; % list of files to delete at exit % (defined with custom_variable, so a reevaluation of bufutils will not % delete the existing list.) custom_variable("Bufsubfile_Tmp_Files", ""); % cleanup at exit static define delete_temp_files() { variable file; foreach file (strchop(strtrim_beg(Bufsubfile_Tmp_Files), '\n', 0)) if (file_status(file) == 1) delete_file(file); return 1; } add_to_hook("_jed_exit_hooks", &delete_temp_files); %!%+ %\function{bufsubfile} %\synopsis{Write region|buffer to a temporary file and return its name.} %\usage{String = bufsubfile(delete=0, base=NULL)} %\description % Write the region to a temporary file. If no visible region is defined, % write the whole buffer. % % If \var{base} is not absolute, the file is written to the \var{Jed_Tmp_Directory}. % If \var{base} == NULL (default), the buffer-name is taken as basename % If \var{delete} != 0, delete the region|buffer after writing. % % Return the full filename. % % The temporary file will be deleted at exit of jed (if the calling % function doesnot delete it earlier). %\notes % bufsubfile() enables shell commands working on files % to act on the current buffer and return the command output. % * run_shell_cmd() returns output but doesnot take input from jed, % * pipe_region() only takes input but outputs to stdout, but % * shell_cmd_on_region() uses bufsubfile() and run_shell_cmd() for % bidirectioal interaction % As some commands expect a certain file extension, the extension of % \var{base} is added to the temporary file's name. %\seealso{make_tmp_file, is_visible_mark, push_visible_mark, %\seealso{run_shell_cmd, shell_cmd_on_region, filter_region} %!%- define bufsubfile() % (delete=0, base=NULL) { variable delete, base, filename, extension; (delete, base) = push_defaults(0, NULL, _NARGS); push_spot (); !if (is_visible_mark) mark_buffer(); if (delete) () = dupmark(); % create a unique filename (keeping the extension) if (base == NULL) base = str_delete_chars(path_basename(whatbuf()), "*+<>:/ \\"); extension = path_extname(base); base = path_sans_extname(base); do { filename = strcat(make_tmp_file(base), extension); } while (file_status(filename)); % write region/buffer to temporary input file () = write_region_to_file(filename); if (delete) del_region(); % delete the file at exit Bufsubfile_Tmp_Files += "\n" + filename; pop_spot(); % show("bufsubfile:", filename, Bufsubfile_Tmp_Files); return filename; } %!%+ %\function{untab_buffer} %\synopsis{Untab the whole buffer} %\usage{Void untab_buffer()} %\description % Convert all hard tabs ("\\t") in the current buffer into spaces. The % buffer-local value of \var{TAB} determines how many spaces are used for the % substitution. %\notes % Whether hard Tabs will be used for editing is defined by the % global variable \var{USE_TABS} and the buffer-local variable \var{TAB}. %\seealso{untab} %!%- public define untab_buffer () { push_spot(); mark_buffer(); untab (); pop_spot(); } jedmodes-2.5.7/pymode/0000755000175400017500000000000011477670704013114 5ustar mildegmjedmodes-2.5.7/pymode/pymode.sl0000644000175400017510000014170011477670704015444 0ustar mildemilde% pymode.sl: Python editing mode for Jed % % For editing source code written in the Python programming language. % Provides basic compatibility with Python mode under real Emacs % % Authors: Harri Pasanen % Brien Barton % Guenter Milde % % The following keys have python specific bindings: % (assuming _Reserved_Key_Prefix == "^C") % % Backspace deletes to previous indent level % : (colon) dedents appropriately % ^C# comments region or current line % ^C> shifts line or region right % ^C< shifts line or region left % ^C^C executes the region, or the buffer if region not marked. % ^C| executes the region % % Use the python_mode_hook() for customization. % See the online doc for python_mode() and python_mode_hook(). % % Shortcomings: Does not highligt triple-quoted strings well: % % * No highlight for multi-line string literals with DFA syntax highlight. % * It works OK with """ (but NOT with ''') if DFA syntax highlight is off. % % Versions % -------- % % 1.0 first public version (Harri Pasanen, Brien Barton) % 1.1 Major improvements, mostly done by Brien Barton: % - execution of python code from JED % - DFA syntax support % - improved indent - dedent. % 1.2 Minor fixes, by Tom Culliton % - corrected a syntax error % - fixed non-DFA syntax hilighting tables to work better % - added the new assert keyword % 1.3 - autoindent correction % 1.4 - Better indenting of function arguments and tuples % - New keywords and builtins added (TJC) % - An attempt to do pretty indenting of data structures and % parameter lists % - Try to keep the lines under 80 columns and make formatting consistent % 1.5 (JED) % - discard return value from run_shell_cmd % - avoid use of create_array and explicit loop for initializing it. % 2.0 2006-09-29 (Guenter Milde) % - detect use of Tabs or Spaces for indentation % - py_reindent() now honours continuation lines % - declared python_mode explicitely a public function % - new function py_help (needs the pydoc module) % - interactive python session with ishell % - py_line_starts_block(), py_line_starts_subblock(), py_endblock_cmd(): % fix false positives with lines starting with e.g. "passport" % (words that start with a keyword). (modified patch by Peter Bengtson % and Jörg Sommer) % - use indent_hook instead of binding the TAB key % - various small twiddles % - use comments.sl instead of special commenting functions % - added mode menu % 2.1 2006-11-23 % - Auto-determine the indent-string from first indented code line % (as emacs does and PEP 0008 recommends) % The custom variable Py_Indent_Level is the fallback value, giving the % number of spaces per indent-level or 0 for "indent with tabs". % - py_indent_line() honours continuation lines % - major code cleanup % named namespace "pymode" (reduces namespace pollution), % drop "py_" prefix of some static functions % made some static functions inline code % - many bugfixes after unit testing, e.g. % electric_colon - return 0 if colon is in a comment % dfa error flagging: allow imaginary numbers (1j or 1J) % - added and updated documentation % - leave the TAB value as is (so hard-tabs will not show as '^I' if % indentation uses spaces) % 2.1.1 2007-01-18 % - catch errors and widen in py_shift_region_left() % - new function browse_pydoc_server() % - added browse_url() autoload and require("keydefs") % - replaced calculate_indent_col() with calculate_indent % - define in_literal_string() without narrow_to_region, as this % does a "spurious" update. % - added True and False keywords % - py_indent_line() keeps point % - bugfix in reindent_block() % 2.1.2 2007-02-06 % - use sprintf() instead of ""$ for `outbuf` string in py_exec() % 2.1.3 2007-05-14 % - simplified browse_pydoc_server() % - added info about DFA syntax highlight to pymode_hook doc % 2.1.4 2007-05-25 - add StopIteration keyword, formatting % 2.1.5 2007-06-21 - add autoload for fit_window() (report Michael Johnson) % 2.1.6 2007-12-05 - implement Jörg Sommer's fix for DFA highlight under UTF-8 % - set_highlight_scheme() function and mode menu entry % - Python_Use_DFA custom variable % - cleanup and fix of DFA rules % 2.2 2008-12-12 - Special modes for Python help and Python output, % - new mode-menu item "Fold by indentation", % - added autoload for view_mode() (report P. Bengtson) % 2.2.1 2010-12-08 - py_untab() restores point. % - Adapt py_browse_module_doc() to 2.6 doc paths. % TODO % ---- % % Allow wrapping of continuation lines and in comments: % % "wrapok_hook" % This hook may be used to enable automatic wrapping on a % line-by-line basis. Jed will call this hook prior to wrapping a % line, and if it returns a non-zero value, the line will be % wrapped. See lib/slmode.sl for an example of its use. % % Wrapping of code: wrap point is ", " behind a "(" provide("pymode"); % Requirements % ------------ % SLang 2 (`List_Type', `throw' keyword, and `foreach' loop with variable) require("comments"); % (un-)commenting lines and regions require("keydefs"); % symbolic constants for many function and arrow keys % utilities from http://jedmodes.sf.net/ autoload("browse_url", "browse_url"); autoload("fit_window", "bufutils"); autoload("popup_buffer", "bufutils"); autoload("untab_buffer", "bufutils"); autoload("run_local_hook", "bufutils"); autoload("ishell_mode", "ishell"); autoload("shell_command", "ishell"); autoload("ishell_send_input", "ishell"); autoload("ishell_set_output_placement", "ishell"); autoload("shell_cmd_on_region_or_buffer", "ishell"); autoload("get_blocal", "sl_utils"); autoload("string_get_match", "strutils"); autoload("str_re_replace_all", "strutils"); autoload("get_word", "txtutils"); autoload("bget_word", "txtutils"); autoload("view_mode", "view"); implements("python"); private variable mode = "python"; % Custom variables and settings % ============================= %!%+ %\variable{Py_Indent_Level} %\synopsis{Number of spaces to indent a code block} %\usage{variable Py_Indent_Level = 4} %\description % \sfun{python->get_indent_level} determines the buffer-local indentation % level from the first indented code line. \var{Py_Indent_Level} is the % default, used for the buffer-local indent-level, for a buffer % without indented code lines (e.g. a new one). % % The pre-set value of 4 spaces corresponds to the "Style Guide for Python % Code" (http://www.python.org/dev/peps/pep-0008/) % % The special value 0 means use hard tabs ("\\t") for indentation. %\example % To have tab-indentation by default with visible tab-width of 3, write in % jed.rc something like %#v+ % Py_Indent_Level = 0; % TAB_DEFAULT = 3; %#v- % If the global \var{TAB_DEFAULT} should not be touched, set the buffer local % TAB in a \sfun{python_mode_hook}. %\seealso{python->get_indent_level, python->get_indent_width, TAB} %!%- custom_variable("Py_Indent_Level", 4); %!%+ %\variable{Python_Doc_Root} %\synopsis{Root directory of the Python html documentation.} %\usage{variable Python_Doc_Root = "/usr/share/doc/python/html/"} %\description % Path to the base dir of the Python html documentation. % The default setting works for a Debian installation. %\seealso{py_browse_module_doc, py_help} %!%- custom_variable("Python_Doc_Root", "/usr/share/doc/python/html/"); %!%+ %\variable{Python_Use_DFA} %\synopsis{Use DFA syntax highlight for \var{python_mode}?} %\usage{variable Python_Use_DFA = 0} %\description % Choose the syntax highlight scheme. % % Syntax highlight could use either a DFA syntax highlight scheme or the % "traditional" one. Advantages are: % % traditional: highlights muliti-line string literals (if enclosed in """) % % dfa: highlights some syntax errors (e.g. invalid number formats, % mix of Spaces and Tab in code indention, or quote with trailing % whitespace at eol) %\seealso{python->set_highlight_scheme, enable_dfa_syntax_for_mode} %!%- custom_variable("Python_Use_DFA", 0); %!%+ %\function{python_mode_hook} %\synopsis{Customization hook called by \sfun{python_mode}} %\usage{Void python_mode_hook()} %\description % If \sfun{python_mode_hook} is defined by the user, it will be called by % \sfun{python_mode}. This provides a very flexible way for user % customization. This can be used for e.g. setting of the TAB value, code % indentation check or fix, buffer reformatting, or customizing the % keybindings or syntax highlight scheme. %\example % * Check the code indentation at startup: % - warn in minibuffer if tabs and spaces are mixed %#v+ % define python_mode_hook() { py_check_indentation() } %#v- % - untab: replace all hard tabs if indentation uses spaces % This is more efficient than re-indenting to get rid of tabs. % (Not only in code indentation but in the whole buffer.) % % (Conversion of spaces to tabs is possible with % a \sfun{prefix_argument} and \sfun{py_untab}. However, this does not % guarantee a non-mixed indentation, as spaces remain in places where the % whitespace does not end at a multiple of TAB. This is why py_reindent() % is recommended in this case.) %#v+ % define python_mode_hook() { % if (python->get_indent_level()) % py_untab(); % % more customization... % } %#v- % - ask: in case of mixed whitespace, ask for fixing by re-indentation %#v+ % define python_mode_hook() { % !if (python->check_indentation()) % py_reindent(); % % more customization... % } %#v- % - auto: in case of mixed whitespace, reindent with global \var{Py_Indent_Level} %#v+ % define python_mode_hook() { % !if (python->check_indentation()) % python->reindent_buffer(Py_Indent_Level); % % more customization... % } %#v- %\seealso{py_untab, py_reindent, python->check_indentation} %!%- % Custom colours (pre-defined since Jed 0-99.18) % Make sure they have a different background as there is no foreground to see. custom_color("trailing_whitespace", get_color("menu")); custom_color("tab", get_color("menu")); % Functions % ========= % Get/Set/Check code indentation data % ----------------------------------- % Skip literal string % % Skip literal string if point is at begin-quote. % Needed in the test if the point is in a long literal % string and hence in the test for continuation lines. % % Skips behind the literal string which is either % one place after the end-quote, or % end of buffer (unclosed long string), or % end of line (unclosed short string) % % There are 4 kinds of quotes: ''', """, ', and " which might be nested % Return value: % 0 no end quote found % 1 skipped over short string (', ") % 3 skipped over long string (''', """) % % If the point is not at a begin-quote, move right one place % (to prevent e.g. an infinite `while' loop). static define skip_string() { variable quote, quotes = ["'''", "\"\"\"", "'", "\"", ""], quotelen, search_fun = [&ffind, &fsearch]; % determine starting quote foreach quote (quotes) if (looking_at(quote)) break; quotelen = strlen(quote); go_right_1(); % search for matching quote, check escaping while (@search_fun[quotelen > 1](quote)) { blooking_at("\\"); % check for quote (push on stack) go_right(quotelen); if () % quoted (get from stack) continue; return quotelen; } % no end quote found, skip to "natural end" switch (quotelen) { case 1: eol(); } { case 3: eob(); } return 0; } % Test if point is "behind" the position saved in (col, line) static define is_behind(line, col) { return orelse{what_line() > line} {andelse{what_line() == line} {what_column() > col} }; } % Test if point is inside string literal % % parse_to_point() doesnot work, as Python allows long (i.e. line % spanning) strings. % Complicated, because there are 4 ways to mark literal strings: % single and triple quotes or double-quotes, (', ", ''', or """) which might % be nested. Therefore all string-literals before the point need to be % searched and skipped. % % The optional start_mark is used to shortcut the search. It must point to a % place known to be outside a string. static define in_literal_string() % [Mark_Type start_mark] { variable col = what_column(), line = what_line(), in_string = 0; push_spot(); EXIT_BLOCK { pop_spot(); } % Scan for literal strings. If quotes are unbalanced, we are inside % % % Alternative: Narrow the search space ... % narrow_to_region() has the side-effect, that an undo() after % any function that used it (directly or indirectly) will move the % cursor to the beginning of the region (in this case bob or the % start_mark()) % start outside a literal string: if (_NARGS) goto_user_mark(()); % get arg from stack else bob(); % the scanning loop while (re_fsearch("['\"]")) % find the next begin-quote { % skip if escaped or in a comment if (orelse{blooking_at("\\")}{parse_to_point() == -2}) { skip_chars("'\""); continue; } % now at string-opening quote, abort if we passed the original point if (is_behind(line,col)) return 0; % skip to end of literal string () = skip_string(); % False, if no matching end-quote found % check if we passed the original point if (is_behind(line,col)) return 1; } return 0; } % Test if point is in a continuation line % (after line ending with \, inside long string literals, (), [], and {}) % return zero or recommended indentation column static define is_continuation_line() { variable delim, line = what_line(), col; push_spot(); EXIT_BLOCK { pop_spot(); } % goto previous line, determine indentation !if (up_1()) return 0; % first line cannot be a continuation bol_skip_white(); col = what_column(); % Check the various variants of continuation lines: % explicit (previous line ending in \) eol(); go_left_1(); if (looking_at_char('\\') and (parse_to_point() != -2)) % not in comment return col; % long literal string (test for balance of """ """ and ''' ''') goto_spot(); bol(); if (in_literal_string) return col; % parentheses, brackets and braces foreach delim (")]}") { goto_spot(); bol(); !if (find_matching_delimiter(delim) == 1) % goto (, [, or { continue; col = what_column(); switch (find_matching_delimiter(0)) % goto ), ], or } { case 0: return col + 1; } % unbalanced { case 1 and (what_line() > line): % spans current line return col + 1; } { case 1 and (what_line() == line): % ends at current line bol_skip_white(); return col + not(looking_at_char(delim)); } } return 0; % test negative } % Test if current line is an indented code line % % (use for detection, reindent, fixing) % The point is left at the first non-white space static define is_indented_code_line() { bol_skip_white(); if (bolp()) % no indent return 0; if (eolp()) % empty line return 0; if (looking_at_char('#')) % comment return 0; if (is_continuation_line()) return 0; return 1; } %!%+ %\function{python->get_indent_level} %\synopsis{Determine the buffer-local indentation level} %\usage{python->get_indent_level()} %\description % Return the buffer local indent level setting (number of spaces or 0 for % "use tabs"). The value is determined from % the cached value (blocal variable "Py_Indent_Level"), % the first indented code line, or % the custom variable \var{Py_Indent_Level}. % It is cached in the blocal variable "Py_Indent_Level" %\seealso{py_indent_line, py_reindent, py_shift_right, py_shift_left} %!%- static define get_indent_level() { variable name = "Py_Indent_Level", value = NULL; % use cached value if (blocal_var_exists(name)) return get_blocal_var(name); push_spot_bob(); % guess from indented code line while (re_fsearch("^[ \t]")) { if (is_indented_code_line()) % moves to first non-white char { if (blooking_at("\t")) value = 0; else value = what_column - 1; break; } } % use default value if (value == NULL) value = Py_Indent_Level; pop_spot(); define_blocal_var(name, value); return value; } % get the width of the expanded indent string (indent_level or TAB) static define get_indent_width() { variable indent = get_indent_level(); if (indent) return indent; else return TAB; } %!%+ %\function{python->check_indentation} %\synopsis{Check whitespace in code indentation} %\usage{Int_Type|Char_Type = python->check_indentation()} %\description % Test whitespace in python code indentation and return: % 0 mix of tabs and spaces % ' ' indent with spaces % '\t' indent with tabs % % Doesnot keep the point! If a mix of tabs and spaces is found, it % leaves the point at the first non-white char in the offending line. % (This might also be a continuation line so no mix is reported.) % Calling \sfun{py_indent_line} at this line (most simply by pressing Key_Tab), % will fix this line indentation. %\example %% Check whitespace before saving. %% In case of mixed whitespace, ask for fixing by re-indentation %#v+ % define python_save_buffer_hook(filename) { % !if ((what_mode(), pop) == "python") % return; % !if (python->check_indentation()) % py_reindent(); % } % append_to_hook("_jed_save_buffer_before_hooks", &python_save_buffer_hook); % } %#v- %\seealso{py_check_indentation, py_reindent, python_mode_hook} %!%- static define check_indentation() { variable pattern, indent_level = get_indent_level(); if (indent_level) % indent with spaces pattern = "^ *\t"; % leading whitespace containing tab else % indent with tabs pattern = "^\t* "; % leading whitespace containing space bob(); % check for 'wrong' character in code indentation whitespace while (re_fsearch(pattern)) if (is_indented_code_line()) % leaves point at first non-white char return 0; % no 'wrong' character found if (indent_level) return ' '; else return '\t'; } %!%+ %\function{py_check_indentation} %\synopsis{Check whitespace in code indentation} %\usage{py_check_indentation()} %\description % Tell, whether code indentation uses tabs or spaces. % Throw an error if it contains a mix of tabs and spaces. % % If a mix of tabs and spaces is found, the point is left at the first % non-white char in the offending line. %\example % Check whitespace before saving. %#v+ % define python_save_buffer_hook(filename) { % !if ((what_mode(), pop) == "python") % return; % py_check_indentation(); % } % append_to_hook("_jed_save_buffer_before_hooks", &python_save_buffer_hook); % } %#v- %\seealso{py_check_indentation, py_reindent, python_mode_hook} %!%- public define py_check_indentation() { push_spot(); switch (check_indentation()) { case 0: throw RunTimeError, "Code indentation mixes spaces and tabs!"; } { case ' ': message("Code indent uses spaces."); } { case '\t': message("Code indent uses tabs."); } pop_spot(); } % Calculate indent (parsing last line(s)) % --------------------------------------- % this function moves the point to somewhere near eol! static define line_ends_with_colon() { eol(); !if (bfind_char(':')) return 0; if (parse_to_point() == -2) % in comment return 0; go_right_1(); skip_white(); if (eolp() or looking_at_char('#')) return 1; return 0; } % is the current line the last of a block? (should the next line unindent?) static define endblock_cmd() { % TODO: do we want empty lines to mark a block-end? % no because this doesnot work well with trim_buffer() [GM] % if (bolp() and eolp()) % empty line (not even whitespace) % return 1; bol_skip_white(); return is_list_element("return,raise,break,pass,continue", get_word(), ','); } static define line_starts_subblock() { bol_skip_white(); return is_list_element("else,elif,except,finally", get_word(), ','); } static define line_starts_block() { bol_skip_white(); return (is_list_element("if,try", get_word(), ',') or line_starts_subblock()); } % Parse last line(s) to estimate the correct indentation for the current line % % Used in py_indent_line, indent_line_hook (for indent_line() and % newline_and_indent(), and electric_colon() static define calculate_indent() { variable col, new_subblock, has_colon, indent_width = get_indent_width(); push_spot_bol(); % Check for continuation line col = is_continuation_line(); if (col > 0) { pop_spot(); return col-1; } % Parse current and preceding lines for indentation clues new_subblock = line_starts_subblock(); % go to preceding line !if (up_1) return 0; % first column: do not indent has_colon = line_ends_with_colon(); % bskip continuation lines while (is_continuation_line()) go_up_1(); % no infinite recursion: line 1 is no continuation line % get indentation bol_skip_white(); col = what_column(); % modify according to parse result if (has_colon) col += indent_width; if (endblock_cmd() or (new_subblock and not line_starts_block())) col -= indent_width; pop_spot(); return col-1; } % Indent current line % % Change the indentation of the current line using given or calculated amount % of whitespace. % Tab- or space-use is determined by get_indent_level() (0 -> use tabs) public define py_indent_line() % (width = calculate_indent()) { !if (_NARGS) calculate_indent(); variable width = (); push_spot(); bol_trim(); if (get_indent_level()) insert_spaces(width); else whitespace(width); pop_spot(); if (bolp()) skip_white(); } %!%+ %\function{python->py_shift_line_right} %\synopsis{Increase the indentation level of the current line} %\usage{Void python->py_shift_line_right(levels)} %\description % Increase the indentation of the current line to the next % indent level. % % A \sfun{prefix_argument} can be used to repeat the action. %\seealso{py_shift_right, py_shift_left, set_prefix_argument} %!%- static define py_shift_line_right() { variable steps = prefix_argument(1); variable indent_width = get_indent_width(); bol_skip_white(); variable level = (what_column-1)/indent_width + steps; vmessage("old-indent=%d, old-level=%d, new-level=%d, new-indent=%d", what_column-1, (what_column-1)/indent_width, level, level*indent_width); py_indent_line(level * indent_width); } %!%+ %\function{python->py_shift_region_right} %\synopsis{Increase the indentation level of the region} %\usage{Void python->py_shift_region_right()} %\description % Call \sfun{python->py_shift_line_right} for all lines in the current region. % % A \sfun{prefix_argument} can be used to repeat the action. %\seealso{py_shift_rigth, py_shift_left, set_prefix_argument} %!%- static define py_shift_region_right() { variable prefix = prefix_argument(1); check_region(0); % push spot, point at end of region narrow(); do { set_prefix_argument(prefix); py_shift_line_right(); } while (up_1()); widen(); } %!%+ %\function{py_shift_right} %\synopsis{Increase indentation level of current line or region} %\usage{py_shift_right()} %\description % Increase the indentation of the current line to the next indent level. % (Similar to a simulated tabbing). % % The buffer local spacing of the indent levels is determined with % \sfun{python->get_indent_width}. % % A \sfun{prefix_argument} can be used to repeat the action. %\example % With default emacs keybindings, %#v+ % ESC 4 Ctrl-C > %#v- % will indent the line or region by 4 levels. %\notes % Calls \sfun{py_shift_line_right} or \sfun{py_shift_region_right}, % depending on the outcome of \sfun{is_visible_mark}. %\seealso{py_shift_left, set_prefix_argument} %!%- public define py_shift_right() { if (is_visible_mark()) { py_shift_region_right(); } else { py_shift_line_right(); } } % decrease the indentation of the current line one level static define py_shift_line_left() { variable steps = prefix_argument(1); variable indent_width = get_indent_width(); bol_skip_white(); variable level = (what_column()-2+indent_width)/indent_width - steps; vmessage("old-indent=%d, old-level=%d, new-level=%d, new-indent=%d", what_column-1, (what_column-2+indent_width)/indent_width, level, level*indent_width); if (level < 0) { if (eolp) return trim(); % empty line, trim and return else throw RunTimeError, sprintf("Line is indented less than %d level(s)", steps); } py_indent_line(level * indent_width); } static define py_shift_region_left() { variable e, steps = prefix_argument(1); check_region(1); narrow(); do { set_prefix_argument(steps); try (e) { py_shift_line_left(); } catch AnyError: { widen(); % show(e); throw e.error, e.message; } } while (up_1()); widen(); pop_spot(); } %!%+ %\function{py_shift_left} %\synopsis{Decrease indentation level of the current line or region} %\usage{py_shift_left()} %\description % Decrease the indentation of the current line or (visible) region % to the previous indent level. (Similar to a simulated tabbing). % % The buffer local spacing of the indent levels is determined with % \sfun{python->get_indent_width}. % % A \sfun{prefix_argument} can be used to repeat the action. % % Abort if a line is less indented than it should be unindented. %\example % With default emacs keybindings, %#v+ % ESC 4 Ctrl-C < %#v- % will unindent the line or region by 4 * \var{Py_Indent_Level}. %\notes % Calls \sfun{py_shift_line_left} or \sfun{py_shift_region_left}, % depending on the outcome of \sfun{is_visible_mark}. %\seealso{py_shift_right, set_prefix_argument} %!%- public define py_shift_left() { push_spot(); if (is_visible_mark()) { py_shift_region_left(); } else { py_shift_line_left(); } pop_spot(); } %!%+ %\function{py_untab} %\synopsis{Convert tabs to spaces or vice versa} %\usage{py_untab()} %\description % Replace all hard tabs ("\t") by one to eight spaces such that the total % number of characters up to and including the replacement is a multiple of % eight (this is also Python's TAB replacement rule). % % With prefix argument, convert spaces to tabs and set \var{TAB} to the % buffer local Py_Indent_Level. %\notes % Other than \sfun{untab}, \sfun{py_untab} acts on the whole buffer, not on a % region. %\seealso{py_reindent, TAB, untab} %!%- public define py_untab() { variable indent, convert_to_tabs = prefix_argument(0); push_spot(); mark_buffer(); if (convert_to_tabs) { set_prefix_argument(1); TAB = get_indent_width(); } else TAB = 8; untab(); if (convert_to_tabs) { vmessage("Converted spaces to tabs."); define_blocal_var("Py_Indent_Level", 0); } else { vmessage("Converted all tabs to spaces."); define_blocal_var("Py_Indent_Level", TAB); } pop_spot(); } %!%+ %\function{python->reindent_buffer} %\synopsis{Reindent buffer using \var{Py_Indent_Level}} %\usage{Void python->reindent_buffer(indent_level=get_indent_level())} %\description % Normalize indentation based on the current relative indentation and % \var{indent_width}. %\notes % In many computer languages (like C and SLang), indentation is redundant % (just a matter of style) and may therefore be completely automatized. % In Python, indentation bears information (defining blocks of code) % and can not always be determined automatically. % % While \sfun{py_indent_line} parses the preceding lines to estimate the % indentation for the current (or new) line, \sfun{python->reindent_buffer} % reformats syntactically correct indented code and cannot extrapolate to a % new line. It will abort if the indentation violates the Python syntax. %\seealso{py_indent_line, py_untab} %!%- static define reindent_buffer() % (indent_level=get_indent_level()) { if (_NARGS) { variable indent_level = (); define_blocal_var("Py_Indent_Level", indent_level); } variable col, offset, comment, indent_width = get_indent_width(), indent_levels = {1}; % list of distinct start columns if (indent_width == 0) % convert to tabs and TAB == 0 { TAB = 8; indent_width = 8; } bob(); while (re_fsearch("^[ \t]")) % leading whitespace { skip_white(); if (eolp()) % empty line continue; col = what_column(); comment = looking_at_char('#'); % continuation line: shift by the same amount as previous line if (is_continuation_line()) { % get deviation from last non-continuation line offset = col - indent_levels[0]; bol_trim(); % no problem, if the new indent is negative: % indent of continuation lines is redundant and % a negative value for py_indent_line() indents to column 1. py_indent_line((length(indent_levels)-1)*indent_width + offset); continue; } % indent if (col > indent_levels[0]) list_insert(indent_levels, col); else % no change or dedent while (col < indent_levels[0]) list_delete(indent_levels, 0); % Test if indent value is wrong (dedent to non-previous level) if ((col != indent_levels[0]) and not comment) throw RunTimeError, "Inconsistent indention: unindent to non-matching level"; % now re-indent bol_trim(); py_indent_line((length(indent_levels)-1)*indent_width); } } % reindent the current block or all blocks that overlap with a visible region % % no provision for indent-level specification, as this would lead to % inconsistent indents (you can of course still % define_blocal_var("Py_Indent_Level", ) % before the call to python->reindent_block static define reindent_block() { % push spot at end of current line or last line of visible region if (is_visible_mark()) () = check_region(0); eol(); % this way the current line is also found by the bsearch push_spot(); if (is_visible_mark) % and go to beg of region pop_mark_1(); % mark the start of current code block do !if (re_bsearch("^[^ \t]")) throw UsageError, "Start of code block not found"; while (is_continuation_line()); push_mark(); % go to the end of current code block goto_spot(); do !if (re_fsearch("^[^ \t]")) { % code block ends at eob if no non-indented code line is found eob(); break; } while (andelse{is_continuation_line()}{down_1()}); % now narrow the buffer and reindent narrow(); reindent_buffer(); widen(); pop_spot(); } %!%+ %\function{py_reindent} %\synopsis{Reindent buffer/region to uniform indent levels} %\usage{Void py_reindent()} %\description % Normalize indentation based on the current relative indentation. % Asks for the new indent level (0 for indenting with tabs). % % Calls \sfun{python->reindent_buffer} or, if a visible region is defined, % \sfun{python->reindent_block}. %\seealso{py_indent_line, py_untab} %!%- public define py_reindent() { variable new_indent = integer(read_mini("Reindent with indent-level (0 for tabs)", string(python->get_indent_level), "")); if (is_visible_mark) reindent_block(new_indent); else reindent_buffer(new_indent); } % "Magic" keys % ------------ % shift line right if we are at the first non-white space in an indented % line, normal action else static define py_backspace_key() { push_spot(); bol_skip_white(); variable first_non_white = what_column(); pop_spot(); if (first_non_white == what_column() and not bolp()) py_shift_line_left(); else call("backward_delete_char_untabify"); } % insert a colon and fix indentation static define electric_colon() { variable indent; insert(":"); push_spot(); if (line_starts_subblock()) % else:, elif:, except:, finally: { bol_skip_white(); indent = calculate_indent(); if (indent < what_column()) % Ensure dedent only py_indent_line(indent); % use already calculated value } pop_spot(); } % TODO: what is the sens of an electric delim?. % TODO: complains about spurious mismatches when fixing them. static define electric_delim(ch) { insert(char(ch)); push_spot(); py_indent_line(); pop_spot(); blink_match(); } % Run python code % --------------- % search back for a Python error message and return file and line number % return "" and 0 if no error found. static define parse_error_message() { variable file = "", line = 0; variable error_regexp = "^ *File \"\\([^\"]+\\)\", line \\(\\d+\\).*"; if (re_bsearch(error_regexp) != 0) { file = regexp_nth_match(1); line = integer(regexp_nth_match(2)); } return file, line; } % Search the current buffer backwards for a Python error message, % open the source file and goto line static define goto_error_source() { variable file, line; eol(); % ... to let the backward search find an error at the current line (file, line) = parse_error_message(); if (file_status(file)) { () = find_file(file); goto_line(line); } } % mode for python output % Return tries to open the file where an error occured % no need for own keymap, as newline_indent_hook is re-mapped % TODO: "traditional" compiler output bindings? public define python_output_mode() { view_mode(); set_mode("python-output", 0); % navigating set_buffer_hook("newline_indent_hook", "python->goto_error_source"); define_blocal_var("context_help_hook", "python_context_help_hook"); if (is_defined("help_2click_hook")) set_buffer_hook( "mouse_2click", "help_2click_hook"); } %!%+ %\function{py_exec} %\synopsis{Run python on current region or buffer} %\usage{py_exec(cmd="python")} %\description % Run python interpreter on current region or the whole buffer. % Display output in *python output* buffer window. % Parse for errors and goto foulty line. %\seealso{python_shell} %!%- public define py_exec() % (cmd="python") { variable cmd = push_defaults("python", _NARGS); variable buf = whatbuf(), py_source = buffer_filename(); variable outbuf = sprintf("*%s output*", cmd); variable exception_file, line, start_line = 1; % remove old output buffer if (bufferp(outbuf)) delbuf(outbuf); if (is_visible_mark()) { check_region(0); exchange_point_and_mark(); start_line = what_line(); % % Workaround in case block is indented % bol_skip_white(); % if (what_column() > 1) % { % insert "if True:\n" % start_line--; % offset for this extra line % } exchange_point_and_mark(); } shell_cmd_on_region_or_buffer(cmd, outbuf); % no output? we are done if (buf == whatbuf()) return; python_output_mode(); % Check for error message eob(); do { (exception_file, line) = parse_error_message(); } while (exception_file != py_source and line != 0); pop2buf(buf); % Move to line in source that generated the error if (exception_file == py_source) { goto_line(line + start_line - 1); } } % output filter for use with ishell-mode static define python_output_filter(str) { % Remove the "poor man's bold" in python helptexts str = str_re_replace_all(str, ".", ""); % Append a newline to the prompt if output goes to separate buffer if (str == ">>> " and get_blocal_var("Ishell_Handle").output_placement == "o") str += "\n"; return str; } public define python_shell() { define_blocal_var("Ishell_output_filter", &python_output_filter); define_blocal_var("Ishell_Wait", 10); % wait up to 1 s/line for response ishell_mode("python"); ishell_set_output_placement("l"); % log in separate-buffer } % Python help % ----------- #ifdef MSWINDOWS define py_help_on_word() { variable tag = "0-9A-Z_a-z"; push_spot(); skip_white(); bskip_chars(tag); push_mark(); skip_chars(tag); tag = bufsubstr(); % leave on the stack pop_spot(); message( strcat("Help on ", tag) ); msw_help( getenv("PYLIBREF"), tag, 0); } #else static define browse_pydoc_server() { flush("starting Python Documentation Server"); variable result = system("pydoc -p 1200 &"); % sleep(0.5); browse_url("http://localhost:1200"); } #endif % find lines with global imports (import ... and from ... import ...) % (needed for python help on imported objects) static define get_import_lines() { variable tag, import_lines="", case_search_before=CASE_SEARCH; CASE_SEARCH = 1; % python keywords are case sensitive foreach tag (["import", "from"]) { push_spot_bob(); while (bol_fsearch(tag)) { if (ffind("__future__")) { eol(); continue; } !if (ffind("import")) { eol(); continue; } if (in_literal_string) continue; do { % get line and continuation lines import_lines += line_as_string()+"\n"; } while (bskip_white(), blooking_at("\\") and down_1()); } pop_spot(); } CASE_SEARCH = case_search_before; return import_lines; } % mode for python help output % no need for own keymap, as newline_indent_hook is re-mapped to bind Return public define python_help_mode() { view_mode(); set_mode("python-help", 0); % navigating set_buffer_hook("newline_indent_hook", "python_context_help_hook"); define_blocal_var("context_help_hook", "python_context_help_hook"); if (is_defined("help_2click_hook")) set_buffer_hook( "mouse_2click", "help_2click_hook"); } %!%+ %\function{py_help} %\synopsis{Run python's help feature on topic} %\usage{Void py_help([String topic])} %\description % Uses pythons own 'help' command to display a help text in a separate % window. If \var{topic} is not given, ask in the minibuffer. %\notes % Only tested on UNIX %\seealso{py_mode} %!%- public define py_help() %(topic=NULL) { % get optional argument or ask !if (_NARGS) read_mini("Python Help for: ", "", ""); variable topic = (); variable str, module, object_list, help_cmd; % % if interactive session is open, use it: % if (is_substr(get_mode_name(), "ishell")) % { % variable handle = get_blocal_var("Ishell_Handle"); % send_process(handle.id, sprintf("help(%s)\n", topic)); % return; % } % % prepend imported module + "." to names in a line like % % from module import name, name2, name3 % push_spot_bob(); % while (bol_fsearch("from"), dup) % { % go_right(()+1); % module = get_word("A-Za-z0-9_."); % go_right(ffind("import")); % push_mark_eol(); % while (blooking_at("\\")) % { % go_down_1(); % eol(); % } % object_list = bufsubstr(); % object_list = strchop(object_list, ',', 0); % object_list = array_map(String_Type, &strtrim, object_list, " \t\r\n\\"); % if (length(where(object_list == topic))) % topic = module + "." + topic; % } % pop_spot(); help_cmd = sprintf("python -c '%shelp('%s')'", get_import_lines(), topic); popup_buffer("*python-help*"); set_readonly(0); erase_buffer(); set_prefix_argument(1); % insert output at point % show(help_cmd); flush("Calling: " + help_cmd); do_shell_cmd(help_cmd); fit_window(get_blocal("is_popup", 0)); python_help_mode(); } % context help: public define python_context_help_hook() { py_help(bget_word("A-Za-z0-9_.")); } % we need a special help for word hook that includes the . in word_chars static define python_help_for_word_hook(word) { python_context_help_hook(); } % Browse the html documentation for a specific module public define py_browse_module_doc() % (module=NULL) { variable module = push_defaults( , _NARGS); variable lib_doc_dir = path_concat(Python_Doc_Root, "library"); if (module == NULL) module = read_mini("Browse doc for module (empty for index):", "", ""); if (module == "") module = "modindex.html"; else module = sprintf("%s.html", module); browse_url("file:" + path_concat(lib_doc_dir, module)); } % Syntax highlighting % ------------------- create_syntax_table(mode); define_syntax("#", "", '%', mode); % comments define_syntax("([{", ")]}", '(', mode); % delimiters define_syntax('\'', '\'', mode); % quoted strings define_syntax('"', '"', mode); % quoted strings define_syntax('\'', '\'', mode); % quoted characters define_syntax('\\', '\\', mode); % continuations define_syntax("0-9a-zA-Z_", 'w', mode); % words define_syntax("-+0-9a-fA-FjJlLxX.", '0', mode); % Numbers define_syntax(",;.:", ',', mode); % punctuation define_syntax("%-+/&*=<>|!~^`", '+', mode); % operators set_syntax_flags(mode, 0); % keywords ARE case-sensitive () = define_keywords(mode, "asifinisor", 2); % all keywords of length 2 () = define_keywords(mode, "anddefdelfornottry", 3); % of length 3 .... () = define_keywords(mode, "elifelseexecfrompass", 4); () = define_keywords(mode, "breakclassprintraisewhileyield", 5); () = define_keywords(mode, "assertexceptglobalimportlambdareturn", 6); () = define_keywords(mode, "finally", 7); () = define_keywords(mode, "continue", 8); % Type 1 keywords (actually these are most of what is in __builtins__) () = define_keywords_n(mode, "id", 2, 1); () = define_keywords_n(mode, "abschrcmpdirhexintlenmapmaxminoctordpowstrzip", 3, 1); () = define_keywords_n(mode, "NoneTruedictevalfilehashiterlistlongopenrepr" + "typevars", 4, 1); () = define_keywords_n(mode, "Falseapplyfloatinputrangeroundslicetuple", 5, 1); () = define_keywords_n(mode, "buffercoercedivmodfilterinternlocalsreducereload" + "unichrxrange", 6, 1); () = define_keywords_n(mode, "IOErrorOSError__doc__compilecomplexdelattr" + "getattrglobalshasattrsetattrunicode", 7, 1); () = define_keywords_n(mode, "EOFErrorKeyErrorTabError__name__callable" + "execfile", 8, 1); () = define_keywords_n(mode, "ExceptionNameErrorTypeErrorraw_input", 9, 1); () = define_keywords_n(mode, "IndexErrorSystemExitValueError__import__" + "isinstanceissubclass", 10, 1); () = define_keywords_n(mode, "ImportErrorLookupErrorMemoryErrorSyntaxError" + "SystemError", 11, 1); () = define_keywords_n(mode, "RuntimeErrorUnicodeError", 12, 1); () = define_keywords_n(mode, "ConflictErrorOverflowErrorStandardError" + "StopIteration", 13, 1); () = define_keywords_n(mode, "AssertionErrorAttributeErrorReferenceError", 14, 1); () = define_keywords_n(mode, "ArithmeticError", 15, 1); () = define_keywords_n(mode, "EnvironmentError", 16, 1); () = define_keywords_n(mode, "KeyboardInterruptUnboundLocalError" + "ZeroDivisionError", 17, 1); () = define_keywords_n(mode, "FloatingPointError", 18, 1); () = define_keywords_n(mode, "NotImplementedError", 19, 1); #ifdef HAS_DFA_SYNTAX %%% DFA_CACHE_BEGIN %%% private define dfa_rule(rule, color) { dfa_define_highlight_rule(rule, color, $1); } private define setup_dfa_callback(mode) { % dfa_enable_highlight_cache("pymode.dfa", mode); $1 = mode; % used by dfa_rule() % Strings %% "normal" string literals dfa_rule("\"[^\"]*\"", "string"); dfa_rule("'[^']*'", "string"); %% "long" string literals dfa_rule("\"\"\".+\"\"\"", "Qstring"); dfa_rule("'''.+'''", "Qstring"); %% string delimiters of multi-line string dfa_rule("\"\"\"|'''", "string"); % Comments dfa_rule("#.*", "comment"); % Keywords (identifier) dfa_rule("[A-Za-z_][A-Za-z_0-9]*", "Knormal"); % Delimiters and operators dfa_rule("[\(\[{}\]\),:\.\"`'=;]"R, "delimiter"); dfa_rule("[\+\-\*/%<>&\|\^~]"R, "operator"); % 1 char dfa_rule("<<|>>|==|<=|>=|<>|!=", "operator"); % 2 char dfa_rule("\\$"R, "operator"); % line continuation %% Flag line continuation with trailing whitespace dfa_rule("\\[ \t]+$"R, "Qtrailing_whitespace"); % Numbers dfa_rule("[1-9][0-9]*[lLjJ]?", "number"); % decimal int/complex dfa_rule("0[0-7]*[lL]?", "number"); % octal int dfa_rule("0[xX][0-9a-fA-F]+[lL]?", "number"); % hex int dfa_rule("[1-9][0-9]*\.?[0-9]*([Ee][\+\-]?[0-9]+)?[jJ]?"R, "number"); % float/complex n.[n] dfa_rule("0?\.[0-9]+([Ee][\+\-]?[0-9]+)?[jJ]?"R, "number"); % float/complex n.[n] %% Flag badly formed numeric literals or identifiers. %% This is more effective if you change the error colors so they stand out. dfa_rule("[1-9][0-9]*[lL]?[0-9A-Za-z\.]+"R, "error"); % bad decimal dfa_rule("0[0-7]+[lL]?[0-9A-Za-z\.]+"R, "error"); % bad octal dfa_rule("0[xX][0-9a-fA-F]+[lL]?[0-9A-Za-z\.]+"R, "error"); % bad hex dfa_rule("\.[0-9]+([Ee][\+\-]?[0-9]+)?[A-Za-z]+"R, "error"); % bad float dfa_rule("[A-Za-z_][A-Za-z_0-9]*\.[0-9]+[A-Za-z]*"R, "error"); % bad identifier % Whitespace dfa_rule(" ", "normal"); % normal whitespace dfa_rule("\t", "tab"); %% Flag mix of Spaces and Tab in code indention dfa_rule("^ +\t+[^ \t#]", "menu_selection"); % distinctive background colour dfa_rule("^\t+ +[^ \t#]", "menu_selection"); % distinctive background colour % Render non-ASCII chars as normal to fix a bug with high-bit chars in UTF-8 dfa_rule("[^ -~]+", "normal"); dfa_build_highlight_table(mode); } dfa_set_init_callback(&setup_dfa_callback, "python"); %%% DFA_CACHE_END %%% #endif static define set_highlight_scheme() { if (_NARGS) Python_Use_DFA = (); else Python_Use_DFA = not(Python_Use_DFA); variable schemes = ["DFA", "traditional"]; mode_set_mode_info (mode, "use_dfa_syntax", Python_Use_DFA); use_syntax_table("python"); % activate the DFA/non-DFA syntax vmessage("using %s highlight scheme", schemes[not(Python_Use_DFA)]); } % Folding % ------- % % by indention % ~~~~~~~~~~~~ % % On 21.04.08, John E. Davis wrote: % > > Is there a possibility to autmatic fold any Python file, like many of % > > the Python-IDE's do ? % % > You might try using the set_selective_display function, which is bound % > to "Ctrl-X $" in emacs mode. This will allow you to hide any lines % > indented beyond the column containing the cursor. % % TODO: also hide comments if "#" at bol but comment indented? % % by pcre pattern % ~~~~~~~~~~~~~~~ % see pcre-fold.sl % % by rst-section % ~~~~~~~~~~~~~~ % see rst-fold.sl % Keybindings % ----------- !if (keymap_p(mode)) make_keymap(mode); definekey_reserved("py_shift_right", ">", mode); definekey_reserved("py_shift_left", "<", mode); definekey_reserved("set_selective_display", "f", mode); definekey_reserved("py_exec", "^C", mode); % Execute buffer, or region if defined definekey("python->py_backspace_key", Key_BS, mode); definekey("python->electric_colon", ":", mode); % These work, but act a bit odd when rebalancing delimiters from the inside. % Clues? %definekey("python->electric_delim(')')", ")", mode); %definekey("python->electric_delim(']')", "]", mode); %definekey("python->electric_delim('}')", "}", mode); #ifdef MSWINDOWS definekey("py_help_on_word", "^@;", mode); #endif % --- the mode dependend menu static define python_menu(menu) { menu_append_item(menu, "Shift line|region &left", "py_shift_left"); menu_append_item(menu, "Shift line|region &right", "py_shift_right"); menu_append_separator(menu); menu_append_item(menu, "&Check indentation", "py_check_indentation"); menu_append_item(menu, "Re&indent buffer|region", "py_reindent"); menu_append_item(menu, "Reindent &block|region", "python->reindent_block"); menu_append_item(menu, "&Untab buffer", "py_untab"); menu_append_item(menu, "&Toggle syntax highlight scheme", "python->set_highlight_scheme"); menu_append_separator(menu); menu_append_item(menu, "&Fold by indentation", "set_selective_display"); menu_append_separator(menu); menu_append_item(menu, "&Run Buffer", &run_local_hook, "run_buffer_hook"); menu_append_item(menu, "Python &Shell", "python_shell"); menu_append_separator(menu); menu_append_item(menu, "Python &Help", "py_help"); menu_append_item(menu, "Python &Documentation Server", "python->browse_pydoc_server"); menu_append_item(menu, "Browse Python &Module Doc", "py_browse_module_doc"); } %!%+ %\function{python_mode} %\synopsis{Mode for editing Python files.} %\usage{Void python_mode()} %\description % A major mode for editing scripts written in Python (www.python.org). % % The following keys have python specific bindings: % (assuming \var{_Reserved_Key_Prefix} == "^C") %#v+ % Key_BS deletes to previous indentation level if the % point is at the first non-white character of a line % : (colon) dedents appropriately % ^C> shifts line or region right % ^C< shifts line or region left % ^C^C executes the region, or the buffer if region not marked. % ^C| executes the region %#v- %\seealso{Py_Indent_Level, python_mode_hook, py_reindent, py_untab} %!%- public define python_mode() { set_mode(mode, 0x4); % flag value of 4 is generic language mode use_keymap(mode); use_syntax_table(mode); C_BRA_NEWLINE = 0; set_buffer_hook("indent_hook", "py_indent_line"); define_blocal_var("help_for_word_hook", "py_help_for_word_hook"); mode_set_mode_info("run_buffer_hook", "py_exec"); mode_set_mode_info(mode, "init_mode_menu", &python_menu); % set_buffer_hook("newline_indent_hook", "py_newline_and_indent"); set_highlight_scheme(Python_Use_DFA); run_mode_hooks("python_mode_hook"); } jedmodes-2.5.7/server/0000755000175400017500000000000011052557064013115 5ustar mildegmjedmodes-2.5.7/server/server.sl0000644000175400017500000001042710507417140014761 0ustar mildegm% server.sl % Run JED as editing server % % $Id: server.sl,v 1.5 2006/09/30 07:48:48 paul Exp paul $ % Keywords: processes, mail, Emacs % % Copyright (c) 2003-2006 Paul Boekholt % Released under the terms of the GNU GPL (version 2 or later). % % This mode should work with the Emacs tools emacsclient and emacsserver. % Emacsserver is a subprocess listening to a socket. Emacsclient sends a % request to the socket and then waits for the server to say "done". % See 2.1 of the Mail-User-HOWTO. % % To install add the following lines to .jedrc: % variable Server_Pgm="/path/to/emacsserver"; % require ("server"); % server_start(); % setkey("server_done", "^X#"); % % caveats: % -Never open the same file from two emacsclients, or JED will forget to % notify the first client when finished. % -Don't try to open two files from one emacsclient. provide("server"); require("pcre"); implements("server"); custom_variable ("Server_Pgm", "/usr/share/emacs/lib/emacsserver"); static variable server_process = -1, server_input; variable pattern = "^Client: ([0-9]+) (?:-nowait )?(?:\\+([0-9]+)(?::([0-9]+))?)? *([^ ]+) *$"; variable cpattern = pcre_compile(pattern); % This emulates a kill_buffer_after_hook try { typedef struct { client } Client_Type; } catch DuplicateDefinitionError; define destroy_client(Client) { send_process(server_process, sprintf("Close: %s Done\n", Client.client)); } __add_destroy(Client_Type, &destroy_client); % This is needed because it's not possible to switch buffers in a subprocess % output handler. variable client_buf; define before_key_hook(); define before_key_hook(fun) { remove_from_hook ("_jed_before_key_hooks", &before_key_hook); sw2buf(client_buf); } % Execute an emacsclient request. Emacsserver output looks like % Client: number [-nowait] {[+line[:column]] file} ... % I can deal with lines and columns, but not with multiple files. define server_parse_output (pid, output) { !if(pcre_exec(cpattern, output)) throw RunTimeError, "I don't understand that"; variable buf = whatbuf(); () = find_file(pcre_nth_substr(cpattern, output, 4)); variable Client = @Client_Type; Client.client = pcre_nth_substr(cpattern, output, 1); define_blocal_var("client", Client); if (pcre_nth_match(cpattern, 2) != NULL) goto_line(atoi(pcre_nth_substr(cpattern, output, 2))); if (pcre_nth_match(cpattern, 3) != NULL) ()=goto_column_best_try(atoi(pcre_nth_substr(cpattern, output, 3))); runhooks("server_visit_hook"); client_buf=whatbuf(); variable client_keymap=what_keymap(); update(1); setbuf(buf); % Set the client buffer's keymap in the " *server*" buffer. % The first keyboard command will be interpreted there. use_keymap(client_keymap); add_to_hook ("_jed_before_key_hooks", &before_key_hook); } % Tell the emacsclient I'm finished %!%+ %\function{server_done} %\synopsis{Tell the emacsclient to return} %\usage{ server_done()} %\description % This saves a server buffer, and tells the emacslient to return. %\seealso{server_start} %!%- public define server_done() { if (blocal_var_exists("client")) { save_buffer; delbuf(whatbuf); } else message ("not a server buffer!"); } %!%+ %\function{server_start} %\synopsis{start an emacsserver subprocess} %\usage{ server_start()} %\description % Allow this JED process to be a server for client processes. This starts % a server communications subprocess through which client "editors" can % send your editing commands to this JED. To use the server, set up the % program \var{emacsclient} in the \var{Emacs} distribution as your standard % "editor". %\example % In .muttrc: %#v+ % set editor="emacsclient %s || jed %s" %#v- % when you edit a message, Mutt will give control to emacsclient, you'll % see %#v+ % "waiting for Emacs..." %#v- % now suspend Mutt/emacsclient, and bring JED to the foregeround. Edit your % message and call \var{server_done} when finished. Bring Mutt back to the % foreground, emacsclient will return and you should be back in Mutt. %\seealso{server_done} %!%- public define server_start() { variable buf = whatbuf; setbuf(" *server*"); server_process = open_process (Server_Pgm, 0); set_process (server_process, "output", &server_parse_output); process_query_at_exit(server_process, 0); setbuf(buf); flush("done"); }