/* -*- mode: C; mode: fold; -*- */ /* * Copyright (c) 1992, 1995 John E. Davis (davis@space.mit.edu) * All Rights Reserved. */ #include "config.h" #include "jed-feat.h" /*{{{ Include Files */ #include #include #include #include "jdmacros.h" #include "buffer.h" #include "replace.h" #include "search.h" #include "screen.h" #include "ins.h" #include "ledit.h" #include "misc.h" #include "paste.h" #include "cmds.h" /*}}}*/ int Replace_Preserve_Case = 0; #define USE_PRESERVE_CASE 0 /* returns the length of the region inserted. */ int replace_chars (int *np, char *neew) /*{{{*/ { int len; int n; #if USE_PRESERVE_CASE int preserve_case; char *old = NULL; int i; #endif CHECK_READ_ONLY n = *np; if (n < 0) return 0; len = strlen (neew); #if USE_PRESERVE_CASE preserve_case = (Replace_Preserve_Case && (len == n)); #endif push_mark (); #if USE_PRESERVE_CASE if (preserve_case) push_mark (); #endif n = forwchars (np); #if USE_PRESERVE_CASE if (preserve_case) { if (n == len) { if (NULL == (old = make_buffer_substring(&n))) return 0; } else { preserve_case = 0; pop_mark (&Number_Zero); } } #endif delete_region (); #if USE_PRESERVE_CASE if (preserve_case) { unsigned char ch; for (i = 0; i < len; i++) { ch = (unsigned char) old[i]; if (ch == UPPER_CASE(ch)) { if (ch == LOWER_CASE(ch)) old[i] = neew[i]; else old[i] = UPPER_CASE(neew[i]); } else old[i] = LOWER_CASE(neew[i]); } neew = old; } #endif ins_chars((unsigned char *) neew, len); #if USE_PRESERVE_CASE if (preserve_case) SLfree (old); #endif return len; } /*}}}*/ int replace_next(char *old, char *neew) /*{{{*/ { int n; if (search(old, 1, 0) == 0) return(0); n = strlen (old); (void) replace_chars (&n, neew); return(1); } /*}}}*/ /* This code implements a kill ring of sorts. It could be done in S-Lang but * S-Lang cannot handle strings with embedded NULL characters. I do not * want to lose compatability with C or I would allow S-Lang strings to handle * the NULL chars. */ #ifndef Sixteen_Bit_System # define MAX_KILL_ARRAY_SIZE 16 int Kill_Array_Size = MAX_KILL_ARRAY_SIZE; typedef struct /*{{{*/ { unsigned char *buf; int len; } /*}}}*/ Char_Array_Type; Char_Array_Type Kill_Array [MAX_KILL_ARRAY_SIZE]; void copy_region_to_kill_array (int *np) /*{{{*/ { int n = *np; if (n < 0) n = 0; n = n % MAX_KILL_ARRAY_SIZE; SLfree ((char *) Kill_Array[n].buf); Kill_Array[n].buf = (unsigned char *) make_buffer_substring (&Kill_Array[n].len); } /*}}}*/ void insert_from_kill_array (int *np) /*{{{*/ { int n = *np; unsigned char *buf; CHECK_READ_ONLY_VOID if (n < 0) n = 0; n = n % MAX_KILL_ARRAY_SIZE; if ((buf = Kill_Array[n].buf) == NULL) return; ins_chars (buf, Kill_Array[n].len); } /*}}}*/ void append_region_to_kill_array (int *np) /*{{{*/ { int n = *np, len, oldlen; unsigned char *buf, *newbuf; if (n < 0) n = 0; n = n % MAX_KILL_ARRAY_SIZE; buf = (unsigned char *) make_buffer_substring (&len); if (buf == NULL) return; oldlen = Kill_Array[n].len; newbuf = (unsigned char *) SLrealloc ((char *)Kill_Array[n].buf, oldlen + len + 1); if (newbuf != NULL) { SLMEMCPY ((char *) newbuf + oldlen, (char *) buf, len); Kill_Array[n].buf = newbuf; Kill_Array[n].len = oldlen + len; } SLfree ((char *)buf); } /*}}}*/ #endif /* NOT 16bit system */ static int bol_bsearch_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return bol_bsearch (buf); } /*}}}*/ static int bol_fsearch_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return bol_fsearch (buf); } /*}}}*/ static int fsearch_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return search_forward (buf); } /*}}}*/ static int bsearch_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return search_backward (buf); } /*}}}*/ static int ffind_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return forward_search_line (buf); } /*}}}*/ static int bfind_char (int *ch) /*{{{*/ { char buf[2]; buf[0] = (unsigned char) (*ch); buf[1] = 0; return backward_search_line (buf); } /*}}}*/ static void widen_this_buffer (void) /*{{{*/ { jed_widen_whole_buffer (CBuf); } /*}}}*/ static int is_visible_mark (void) /*{{{*/ { if ((CBuf->marks == NULL) || (0 == (CBuf->marks->flags & VISIBLE_MARK))) return 0; return 1; } /*}}}*/ static char *get_jed_library_path (void) { return Jed_Library; } static void set_jed_library_path (void) { char *s; if (SLang_pop_slstring (&s)) return; SLang_free_slstring (Jed_Library); Jed_Library = s; } static int set_buffer_umask (int *cmask) { int u = CBuf->umask; if (*cmask != -1) CBuf->umask = *cmask; return u; } SLang_Intrin_Fun_Type Jed_Other_Intrinsics [] = /*{{{*/ { MAKE_INTRINSIC_I("set_buffer_umask", set_buffer_umask, INT_TYPE), /* Prototype: Integer set_buffer_umask (Integer cmask); * The function may be used to set the process file creation mask * for the appropriate operations associated with the current * buffer. This makes it possible to have a buffer-dependent * umask setting. The function takes the desired umask setting and * returns the previous setting. If @cmask@ is zero, the default * process umask setting will be used for operations while the buffer * is current. If @cmask@ is -1, the umask associated with the buffer * will not be changed. */ MAKE_INTRINSIC_S("fsearch", search_forward, INT_TYPE), /* Prototype: Integer fsearch (String str); * This function may be used to search forward in buffer looking for the * string @str@. If not found, this functions returns zero. However, * if found, the length of the string is returned and the current point * is moved to the to the start of the match. It respects the setting * of the variable @CASE_SEARCH@. If the string that one is searching * for is known to be at the beginning of a line, the function * @bol_fsearch@ should be used instead. * * Note: This function cannot find a match that crosses lines. * Related Functions: @ffind@, @fsearch_char@, @bsearch@, @bol_fsearch@, @re_fsearch@, @looking_at@ * Related Variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_S("bsearch", search_backward, INT_TYPE), /* Prototype: Integer bsearch (String str); * The @bsearch@ function searches backward from the current position * for the string @str@. If @str@ is found, this function will return * the length of @str@ and move the current position to the beginning of * the matched text. If a match is not found, zero will be returned and * the position will not change. It respects the value of the variable * @CASE_SEARCH@. * * Related Functions: @fsearch@, @bol_bsearch@, @re_bsearch@ */ MAKE_INTRINSIC_S("bfind", backward_search_line, INT_TYPE), /* Prototype: Integer bfind (String str); * @bfind@ searches backward from the current position to the beginning * of the line for the string @str@. If a match is found, the length of * @str@ is returned and the current point is moved to the start of the * match. If no match is found, zero is returned. * Note: This function respects the setting of the @CASE_SEARCH@ variable. * Related Functions: @bsearch@, @ffind@, @bol_bsearch@, @re_bsearch@ * Related Variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_S("ffind", forward_search_line, INT_TYPE), /* Prototype: Integer ffind (String s); * @ffind@ searches forward from the current position to the end of the * line for the string @str@. If a match is found, the length of @str@ * is returned and the current point is moved to the start of the match. * If no match is found, zero is returned. * Note: This function respects the setting of the @CASE_SEARCH@ variable. * To perform a search that includes multiple lines, use the @fsearch@ * function. * Related Functions: @fsearch@, @bfind@, @re_fsearch@, @bol_fsearch@ */ MAKE_INTRINSIC_S("bol_fsearch", bol_fsearch, INT_TYPE), /* Prototype: Integer bol_fsearch (str); * @bol_fsearch@ searches forward from the current point until the end * of the buffer for occurrences of the string @str@ at the beginning of * a line. If a match is found, the length of @str@ is returned and the * current point is moved to the start of the match. If no match is * found, zero is returned. * Note: @bol_fsearch@ is much faster than using @re_fsearch@ to perform * a search that matches the beginning of a line. * * Related Functions: @bol_bsearch@, @fsearch@, @ffind@, @re_fsearch@ * Related Variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_S("bol_bsearch", bol_bsearch, INT_TYPE), /* Prototype: Integer bol_bsearch (str); * @bol_bsearch@ searches backward from the current point until the * beginning of the buffer for the occurrences of the string @str@ at * the beginning of a line. If a match is found, the length of @str@ is * returned and the current point is moved to the start of the match. If * no match is found, zero is returned. * * Note: @bol_bsearch@ is much faster than using @re_bsearch@ to perform * a search that matches the beginning of a line. * * Related Functions: @bol_fsearch@, @bsearch@, @bfind@, @re_bsearch@ * Related Variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("bol_fsearch_char", bol_fsearch_char, INT_TYPE), /* Prototype: Integer bol_fsearch_char (Integer ch); * This function searches forward for a character @ch@ at the beginning * of a line. If it is found, @1@ is returned; otherwise @0@ is returned. * Related functions: @bol_fsearch@, @bol_bsearch_char@, @fsearch_char@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("bol_bsearch_char", bol_bsearch_char, INT_TYPE), /* Prototype: Integer bol_fsearch_char (Integer ch); * This function searches backward for a character @ch@ at the beginning * of a line. If it is found, @1@ is returned; otherwise @0@ is returned. * Related functions: @bol_bsearch@, @bol_fsearch_char@, @bsearch_char@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("fsearch_char", fsearch_char, INT_TYPE), /* Prototype: Integer fsearch_char (Integer ch); * This function searches forward for a character @ch@. If it is * found, @1@ is returned; otherwise @0@ is returned. * Related functions: @fsearch@, @ffind_char@, @bsearch_char@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("bsearch_char", bsearch_char, INT_TYPE), /* Prototype: Integer fsearch_char (Integer ch); * This function searches backward for a character @ch@. If it is * found, @1@ is returned; otherwise @0@ is returned. * Related functions: @fsearch_char@, @ffind_char@, @fsearch@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("bfind_char", bfind_char, INT_TYPE), /* Prototype: Integer fsearch_char (Integer ch); * This function searches backward on the current line for a character * @ch@. If it is found, @1@ is returned; otherwise @0@ is returned. * Related functions: @fsearch_char@, @ffind_char@, @fsearch@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_I("ffind_char", ffind_char, INT_TYPE), /* Prototype: Integer fsearch_char (Integer ch); * This function searches forwardward on the current line for a character * @ch@. If it is found, @1@ is returned; otherwise @0@ is returned. * Related functions: @fsearch_char@, @bfind_char@, @fsearch@ * Related variables: @CASE_SEARCH@ */ MAKE_INTRINSIC_SS("replace", replace_cmd, VOID_TYPE), /* Prototype: Void replace(String old, String new); * This function may be used to replace all occurances of the string * @old@ with the string, @new@, from current editing point to the end * of the buffer. The editing point is returned to the initial location. * That is, this function does not move the editing point. * Related Functions: @replace_chars@, @fsearch@, @re_fsearch@, @bsearch@, @ffind@, @del@ * Related Variables: @REPLACE_PRESERVE_CASE@ */ MAKE_INTRINSIC_IS("replace_chars", replace_chars, INT_TYPE), /* Prototype: Void replace_chars (Integer n, String new); * This function may be used to replace the next @n@ characters at the * editing position by the string @new@. After the replacement, the editing * point will be moved to the end of the inserted string. The length of * the replacement string @new@ is returned. * Related Functions: @fsearch@, @re_fsearch@, @bsearch@, @ffind@, @del@ * Related Variables: @REPLACE_PRESERVE_CASE@ */ MAKE_INTRINSIC_I("regexp_nth_match", regexp_nth_match, VOID_TYPE), /* Prototype: String regexp_nth_match (Integer n); * This function returns the nth sub-expression matched by the last regular * expression search. If the parameter @n@ is zero, the entire match is * returned. * Note: The value returned by this function is meaningful only if the * editing point has not been moved since the match. * Related Functions: @re_fsearch@, @re_bsearch@ */ MAKE_INTRINSIC_SI("replace_match", replace_match, INT_TYPE), /* Prototype: Integer replace_match(String s, Integer how); * This function replaces text previously matched with @re_fsearch@ or * @re_bsearch@ at the current editing point with string @s@. If @how@ is * zero, @s@ is a specially formatted string of the form described below. * If @how@ is non-zero, @s@ is regarded as a simple string and is used * literally. If the replacement fails, this function returns zero * otherwise, it returns non-zero. */ MAKE_INTRINSIC_S("re_fsearch", re_search_forward, INT_TYPE), /* Prototype: Integer re_fsearch(String pattern); * Search forward for regular expression @pattern@. This function returns * the 1 + length of the string matched. If no match is found, it returns * 0. * * Related Functions: @fsearch@, @bol_fsearch@, @re_bsearch@ */ MAKE_INTRINSIC_S("re_bsearch", re_search_backward, INT_TYPE), /* Prototype: Integer re_bsearch(String pattern); * Search backward for regular expression @pattern@. This function returns * the 1 + length of the string matched. If no match is found, it returns * 0. * * Related Functions: @bsearch@, @bol_bsearch@, @re_fsearch@ */ MAKE_INTRINSIC("is_visible_mark", is_visible_mark, INT_TYPE, 0), /* Prototype: is_visible_mark (); * This function may be used to test whether or not the mark is a visible * mark. A visible mar is one which causes the region defined by it to * be highlighted. * It returns @1@ is the mark is visible, or @0@ if the mark * is not visible or does not exist. * * Related Functions: @markp@, @push_mark@ */ #if JED_HAS_SAVE_NARROW MAKE_INTRINSIC("push_narrow", jed_push_narrow, VOID_TYPE, 0), /* Prototype: Void push_narrow (); * This function saves the current narrow context. This is useful when * one wants to restore this context after widening the buffer. * Related Functions: @pop_narrow@, @narrow@, @widen@, @widen_buffer@ */ MAKE_INTRINSIC("pop_narrow", jed_pop_narrow, VOID_TYPE, 0), /* Prototype: Void pop_narrow (); * The purpose of this function is to restore the last narrow * context that was saved via @push_narrow@. * Related Functions: @push_narrow@, @widen@, @widen_buffer@ */ #endif #if JED_HAS_BUFFER_LOCAL_VARS MAKE_INTRINSIC("set_blocal_var", jed_set_blocal_var, VOID_TYPE, 0), /* Prototype: Void set_blocal_var (val, String v); * This function sets the value of the buffer local variable with name @v@ * to value @val@. The buffer local variable specified by @v@ must have * been previously created by the @create_blocal_var@ function. @val@ must * have the type that was declared when @create_blocal_var@ was called. * Related Functions: @get_blocal_var@, @create_blocal_var@ */ MAKE_INTRINSIC_S("get_blocal_var", jed_get_blocal_var, VOID_TYPE), /* Prototype: get_blocal_var (String name); * This function returns the value of the buffer local variable specified * by @name@. * Related Functions: @set_blocal_var@, @create_blocal_var@ */ MAKE_INTRINSIC("create_blocal_var", jed_make_blocal_var, VOID_TYPE, 0), /* Prototype: Void create_blocal_var (String name, Integer type); * This function is used to create a buffer local variable named @name@ * whose type is specified by @type@. A buffer local variable is a * variable whose value is local to the current buffer. Currently only * integer and string types are supported. An integer is specifed if the * parameter @type@ is @'i'@, and a string is specified if @type@ is @'s'@. * * Related Functions: @get_blocal_var@, @set_blocal_var@ */ #endif MAKE_INTRINSIC("count_narrows", jed_count_narrows, INT_TYPE, 0), /* Prototype: Integer count_narrows (); * This function returns the narrow depth of the current buffer. * Related Functions: @narrow@, @widen@, @widen_buffer@, @push_narrow@ */ MAKE_INTRINSIC("widen_buffer", widen_this_buffer, VOID_TYPE, 0), /* Prototype: Void widen_buffer (); * This function widens the whole buffer. If one intends to restore the * narrow context after calling this function, the narrow context should be * saved via @push_narrow@. * Related Functions: @narrow@, @widen@, @push_narrow@, @pop_narrow@ */ MAKE_INTRINSIC ("get_jed_library_path", get_jed_library_path, STRING_TYPE, 0), /* Prototype: String get_jed_library_path (); * This function returns the current search path for jed library files. * The path may be set using the function @set_jed_library_path@. * Related Functions: @set_jed_library_path@ */ MAKE_INTRINSIC ("set_jed_library_path", set_jed_library_path, VOID_TYPE, 0), /* Prototype: Void set_jed_library_path (String p); * This function may be used to set the search path for library files. * Its parameter @p@ may be a comma separated list of directories to * search. When the editor is first started, the path is initialized * from the @JED_ROOT@, or @JED_LIBRARY@ environment variables. * Related Functions: @get_jed_library_path@ */ SLANG_END_TABLE }; /*}}}*/