diff --git a/gtkedit/bookmark.c b/gtkedit/bookmark.c index 5cf5b0266..1ed660449 100644 --- a/gtkedit/bookmark.c +++ b/gtkedit/bookmark.c @@ -23,6 +23,9 @@ #include #include "edit.h" +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif /* note, if there is more than one bookmark on a line, then they are appended after each other and the last one is always the one found @@ -138,23 +141,30 @@ void book_mark_insert (WEdit * edit, int line, int c) if (p->next) p->next->prev = q; p->next = q; +#if !defined (GTK) && !defined (MIDNIGHT) + render_scrollbar (edit->widget->vert_scrollbar); +#endif } /* remove a bookmark if there is one at this line matching this colour - c of -1 clear all */ -void book_mark_clear (WEdit * edit, int line, int c) +/* returns non-zero on not-found */ +int book_mark_clear (WEdit * edit, int line, int c) { struct _book_mark *p, *q; + int r = 1; + int rend = 0; if (!edit->book_mark) - return; + return r; for (p = book_mark_find (edit, line); p; p = q) { q = p->prev; if (p->line == line && (p->c == c || c == -1)) { + r = 0; edit->force |= REDRAW_LINE; edit->book_mark = p->prev; p->prev->next = p->next; if (p->next) p->next->prev = p->prev; - memset (p, 0, sizeof (struct _book_mark)); + rend = 1; free (p); break; } @@ -164,12 +174,18 @@ void book_mark_clear (WEdit * edit, int line, int c) free (edit->book_mark); edit->book_mark = 0; } +#if !defined (GTK) && !defined (MIDNIGHT) + if (rend) + render_scrollbar (edit->widget->vert_scrollbar); +#endif + return r; } /* clear all bookmarks matching this colour, if c is -1 clears all */ void book_mark_flush (WEdit * edit, int c) { struct _book_mark *p, *q; + int rend = 0; if (!edit->book_mark) return; edit->force |= REDRAW_PAGE; @@ -181,7 +197,7 @@ void book_mark_flush (WEdit * edit, int c) q->prev->next = q->next; if (p) p->prev = q->prev; - memset (q, 0, sizeof (struct _book_mark)); + rend = 1; free (q); } } @@ -189,28 +205,46 @@ void book_mark_flush (WEdit * edit, int c) free (edit->book_mark); edit->book_mark = 0; } +#if !defined (GTK) && !defined (MIDNIGHT) + if (rend) + render_scrollbar (edit->widget->vert_scrollbar); +#endif } /* shift down bookmarks after this line */ void book_mark_inc (WEdit * edit, int line) { + int rend = 0; if (edit->book_mark) { struct _book_mark *p; p = book_mark_find (edit, line); - for (p = p->next; p; p = p->next) + for (p = p->next; p; p = p->next) { p->line++; + rend = 1; + } } +#if !defined (GTK) && !defined (MIDNIGHT) + if (rend) + render_scrollbar (edit->widget->vert_scrollbar); +#endif } /* shift up bookmarks after this line */ void book_mark_dec (WEdit * edit, int line) { + int rend = 0; if (edit->book_mark) { struct _book_mark *p; p = book_mark_find (edit, line); - for (p = p->next; p; p = p->next) + for (p = p->next; p; p = p->next) { p->line--; + rend = 1; + } } +#if !defined (GTK) && !defined (MIDNIGHT) + if (rend) + render_scrollbar (edit->widget->vert_scrollbar); +#endif } diff --git a/gtkedit/edit.c b/gtkedit/edit.c index 7ebfebf67..df8ddb992 100644 --- a/gtkedit/edit.c +++ b/gtkedit/edit.c @@ -26,8 +26,6 @@ #if defined(NEEDS_IO_H) # include # include -#endif -#ifdef NEEDS_CR_LF_TRANSLATION # define CR_LF_TRANSLATION #endif #include "edit.h" @@ -36,6 +34,9 @@ # include #endif /* SCO_FLAVOR */ #include /* for ctime() */ +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif /* * @@ -257,10 +258,10 @@ int edit_load_file (WEdit * edit, const char *filename, const char *text, unsign /* Lastbyte calculation in TEXT mode FRANCO */ #if defined CR_LF_TRANSLATION - if(file && (!text)) { + if(file && (!text)){ real_size=0; tmp_buf[sizeof (tmp_buf) - 1] = 0; - while ((bytes_read = read (file, tmp_buf, 1024)) > 0) { + while((bytes_read = read(file,tmp_buf,1024)) > 0){ real_size += bytes_read; } s.st_size = real_size; @@ -336,8 +337,8 @@ WEdit *edit_init (WEdit * edit, int lines, int columns, const char *filename, co filename = catstrs (dir, filename, 0); edit_split_filename (edit, (char *) filename); } else { - edit->filename = strdup (""); - edit->dir = strdup(dir); + edit->filename = (char *) strdup (""); + edit->dir = (char *) strdup(dir); } edit->stack_size = START_STACK_SIZE; edit->stack_size_mask = START_STACK_SIZE - 1; @@ -394,7 +395,7 @@ int edit_renew (WEdit * edit) char *dir; if (edit->dir) - dir = strdup (edit->dir); + dir = (char *) strdup (edit->dir); else dir = 0; @@ -444,7 +445,7 @@ int edit_reload (WEdit * edit, const char *filename, const char *text, const cha set edit->mark1 position. 700'000'000 through 1400'000'000 is to set edit->mark2 position. - The only way the curser moves or the buffer is changed is through the routines: + The only way the cursor moves or the buffer is changed is through the routines: insert, backspace, insert_ahead, delete, and cursor_move. These record the reverse undo movements onto the stack each time they are called. @@ -745,26 +746,22 @@ int edit_backspace (WEdit * edit) #ifdef FAST_MOVE_CURSOR -#define memqcpy(edit,d,s,i) \ - { \ - unsigned long next; \ - char *dest = d; \ - char *src = s; \ - int n = i; \ - while ((next = \ - (unsigned long) memccpy (dest, src, '\n', n))) { \ - edit->curs_line--; \ - next -= (unsigned long) dest; \ - n -= next; \ - src += next; \ - dest += next; \ - } \ - } +static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) +{ + unsigned long next; + while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { + edit->curs_line--; + next -= (unsigned long) dest; + n -= next; + src += next; + dest += next; + } +} int edit_move_backward_lots (WEdit * edit, long increment) { int r, s, t; - char *p; + unsigned char *p; if (increment > edit->curs1) increment = edit->curs1; @@ -845,7 +842,7 @@ int edit_move_backward_lots (WEdit * edit, long increment) #endif /* ! FAST_MOVE_CURSOR */ -/* moves the curser right or left: increment positive or negative respectively */ +/* moves the cursor right or left: increment positive or negative respectively */ int edit_cursor_move (WEdit * edit, long increment) { /* this is the same as a combination of two of the above routines, with only one push onto the undo stack */ @@ -1158,7 +1155,7 @@ int is_blank (WEdit * edit, long offset) f = edit_eol (edit, offset) - 1; while (s <= f) { c = edit_get_byte (edit, s++); - if ((c > ' ' && c <= '~') || c >= 160) /* non-printables on a line are considered "blank" */ + if (!isspace (c)) return 0; } return 1; @@ -1169,7 +1166,7 @@ int is_blank (WEdit * edit, long offset) long edit_find_line (WEdit * edit, int line) { int i, j = 0; - int m = 1000000000; + int m = 2000000000; if (!edit->caches_valid) { for (i = 0; i < N_LINE_CACHES; i++) edit->line_numbers[i] = edit->line_offsets[i] = 0; @@ -1435,75 +1432,118 @@ void edit_mark_cmd (WEdit * edit, int unmark) } } -int my_type_of (int c) +static unsigned long my_type_of (int c) { - if (c < ' ' && c > 0) - return 1; - if (strchr ("+_-.", c)) - if (strchr (option_whole_chars_move, c)) - return 3; - if (!strcasechr (option_whole_chars_move, c)) - return 2; - if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 160) - return 3; - return c; + int x, r = 0; + char *p, *q; + if (!c) + return 0; + if (c == '!') { + if (*option_chars_move_whole_word == '!') + return 2; + return 0x80000000UL; + } + if (isupper (c)) + c = 'A'; + else if (islower (c)) + c = 'a'; + else if (isalpha (c)) + c = 'a'; + else if (isdigit (c)) + c = '0'; + else if (isspace (c)) + c = ' '; + q = strchr (option_chars_move_whole_word, c); + if (!q) + return 0xFFFFFFFFUL; + do { + for (x = 1, p = option_chars_move_whole_word; (unsigned long) p < (unsigned long) q; p++) + if (*p == '!') + x <<= 1; + r |= x; + } while ((q = strchr (q + 1, c))); + return r; } -void edit_left_word_move (WEdit * edit) +void edit_left_word_move (WEdit * edit, int s) { - do { + for (;;) { + int c1, c2; edit_cursor_move (edit, -1); if (!edit->curs1) break; - } while (my_type_of (edit_get_byte (edit, edit->curs1)) - == - my_type_of (edit_get_byte (edit, edit->curs1 - 1))); + c1 = edit_get_byte (edit, edit->curs1 - 1); + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; + if (isspace (c1) && !isspace (c2)) + break; + if (s) + if (!isspace (c1) && isspace (c2)) + break; + } } static void edit_left_word_move_cmd (WEdit * edit) { - edit_left_word_move (edit); - if (strchr (option_whole_chars_move, ' ')) - if (strchr ("\t ", edit_get_byte (edit, edit->curs1))) - edit_left_word_move (edit); + edit_left_word_move (edit, 0); edit->force |= REDRAW_PAGE; } -void edit_right_word_move (WEdit * edit) +void edit_right_word_move (WEdit * edit, int s) { - do { + for (;;) { + int c1, c2; edit_cursor_move (edit, 1); if (edit->curs1 >= edit->last_byte) break; - } while (my_type_of (edit_get_byte (edit, edit->curs1 - 1)) - == - my_type_of (edit_get_byte (edit, edit->curs1))); + c1 = edit_get_byte (edit, edit->curs1 - 1); + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; + if (isspace (c1) && !isspace (c2)) + break; + if (s) + if (!isspace (c1) && isspace (c2)) + break; + } } static void edit_right_word_move_cmd (WEdit * edit) { - edit_right_word_move (edit); - if (strchr (option_whole_chars_move, ' ')) - if (strchr ("\t ", edit_get_byte (edit, edit->curs1))) - edit_right_word_move (edit); + edit_right_word_move (edit, 0); edit->force |= REDRAW_PAGE; } static void edit_right_delete_word (WEdit * edit) { - int c; - do { - c = edit_delete (edit); - } while (my_type_of (c) == my_type_of (edit_get_byte (edit, edit->curs1))); + int c1, c2; + for (;;) { + if (edit->curs1 >= edit->last_byte) + break; + c1 = edit_delete (edit); + c2 = edit_get_byte (edit, edit->curs1); + if ((isspace (c1) == 0) != (isspace (c2) == 0)) + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; + } } static void edit_left_delete_word (WEdit * edit) { - int c; - do { - c = edit_backspace (edit); - } while (my_type_of (c) == my_type_of (edit_get_byte (edit, edit->curs1 - 1))); + int c1, c2; + for (;;) { + if (edit->curs1 <= 0) + break; + c1 = edit_backspace (edit); + c2 = edit_get_byte (edit, edit->curs1 - 1); + if ((isspace (c1) == 0) != (isspace (c2) == 0)) + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; + } } extern int column_highlighting; @@ -1661,21 +1701,21 @@ void edit_insert_indent (WEdit * edit, int indent) indent -= TAB_SIZE; } } - while (indent--) + while (indent-- > 0) edit_insert (edit, ' '); } -static void edit_auto_indent (WEdit * edit, int always) +void edit_auto_indent (WEdit * edit, int extra, int no_advance) { long p; int indent; p = edit->curs1; - while (strchr ("\t\n\r ", edit_get_byte (edit, p - 1)) && p > 0) /* move back/up to a line with text */ + while (isspace (edit_get_byte (edit, p - 1)) && p > 0) /* move back/up to a line with text */ p--; indent = edit_indent_width (edit, edit_bol (edit, p)); - if (edit->curs_col < indent) + if (edit->curs_col < indent && no_advance) indent = edit->curs_col; - edit_insert_indent (edit, indent); + edit_insert_indent (edit, indent + (option_fake_half_tabs ? HALF_TAB_SIZE : TAB_SIZE) * space_width * extra); } static void edit_double_newline (WEdit * edit) @@ -1930,6 +1970,7 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) edit->prev_col = edit_get_col (edit); edit->search_start = edit->curs1; edit_find_bracket (edit); + edit_check_spelling (edit); return 1; } switch (command) { @@ -2004,11 +2045,11 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) if (option_auto_para_formatting) { edit_double_newline (edit); if (option_return_does_auto_indent) - edit_auto_indent (edit, 0); + edit_auto_indent (edit, 0, 1); format_paragraph (edit, 0); } else if (option_return_does_auto_indent) { edit_insert (edit, '\n'); - edit_auto_indent (edit, 0); + edit_auto_indent (edit, 0, 1); } else { edit_insert (edit, '\n'); } @@ -2294,6 +2335,7 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) case CK_Sort: case CK_Mail: case CK_Find_File: + case CK_Ctags: #endif case CK_Complete: case CK_Cancel: @@ -2332,18 +2374,24 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) /* CK_Pipe_Block */ if ((command / 1000) == 1) /* a shell command */ edit_block_process_cmd (edit, shell_cmd[command - 1000], 1); -#else - if ((command / 1000) == 1) /* a user defined command */ - if (user_commamd) - (*user_commamd) (edit, command - 1000); -#endif - if (command > CK_Macro (0) && command <= CK_Last_Macro) { /* a macro command */ struct macro m[MAX_MACRO_LENGTH]; int nm; if ((result = edit_load_macro_cmd (edit, m, &nm, command - 2000))) edit_execute_macro (edit, m, nm); } +#else + if (IS_USER_COMMAND (command)) /* a user defined command */ + if (user_commamd) + (*user_commamd) (edit, command & 0xFFFF); + if (IS_MACRO_COMMAND (command)) { /* a macro command */ + struct macro m[MAX_MACRO_LENGTH]; + int nm; + if ((result = edit_load_macro_cmd (edit, m, &nm, command & 0xFFFF))) + edit_execute_macro (edit, m, nm); + } +#endif + /* keys which must set the col position, and the search vars */ switch (command) { case CK_Find: @@ -2376,6 +2424,7 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) edit->search_start = edit->curs1; edit->found_len = 0; edit_find_bracket (edit); + edit_check_spelling (edit); return 1; break; default: @@ -2384,6 +2433,7 @@ int edit_execute_cmd (WEdit * edit, int command, int char_for_insertion) edit->search_start = edit->curs1; } edit_find_bracket (edit); + edit_check_spelling (edit); if (option_auto_para_formatting) { switch (command) { diff --git a/gtkedit/edit.h b/gtkedit/edit.h index facb023b9..e9d0c20c9 100644 --- a/gtkedit/edit.h +++ b/gtkedit/edit.h @@ -36,6 +36,8 @@ # include # endif # include +# include +# include # include "src/tty.h" # include # include @@ -61,6 +63,8 @@ #else # include #endif +# include +# include # include # ifdef HAVE_FCNTL_H @@ -81,11 +85,7 @@ # endif # endif -#ifdef GTK -# include -#else # include "regex.h" -#endif #endif @@ -274,55 +274,58 @@ struct selection { int len; }; +struct syntax_rule { + unsigned short keyword; + unsigned char end; + unsigned char context; + unsigned char _context; +#define RULE_ON_LEFT_BORDER 1 +#define RULE_ON_RIGHT_BORDER 2 + unsigned char border; +}; -#define RULE_CONTEXT 0x00FFF000UL -#define RULE_CONTEXT_SHIFT 12 -#define RULE_WORD 0x00000FFFUL -#define RULE_WORD_SHIFT 0 -#define RULE_ON_LEFT_BORDER 0x02000000UL -#define RULE_ON_RIGHT_BORDER 0x01000000UL +#define MAX_WORDS_PER_CONTEXT 1024 +#define MAX_CONTEXTS 128 struct key_word { char *keyword; - char first; - char last; + unsigned char first; char *whole_word_chars_left; char *whole_word_chars_right; -#define NO_COLOR 0xFFFFFFFF + time_t time; +#define NO_COLOR 0x7FFFFFFF +#define SPELLING_ERROR 0x7EFEFEFE int line_start; int bg; int fg; }; struct context_rule { - int rule_number; char *left; - char first_left; - char last_left; - char line_start_left; + unsigned char first_left; char *right; - char first_right; - char last_right; + unsigned char first_right; + char line_start_left; char line_start_right; int single_char; int between_delimiters; char *whole_word_chars_left; char *whole_word_chars_right; char *keyword_first_chars; - char *keyword_last_chars; + int spelling; /* first word is word[1] */ struct key_word **keyword; }; struct _syntax_marker { long offset; - unsigned long rule; + struct syntax_rule rule; struct _syntax_marker *next; }; struct _book_mark { int line; /* line number */ -#define BOOK_MARK_COLOR ((5 << 8) + 26) /* cyan on white */ +#define BOOK_MARK_COLOR ((0 << 8) | 26) /* black on white */ int c; /* colour */ struct _book_mark *next; struct _book_mark *prev; @@ -349,7 +352,7 @@ struct editor_widget { char *filename; /* Name of the file */ char *dir; /* current directory */ -/* dynamic buffers and curser position for editor: */ +/* dynamic buffers and cursor position for editor: */ long curs1; /*position of the cursor from the beginning of the file. */ long curs2; /*position from the end of the file */ unsigned char *buffers1[MAXBUFF + 1]; /*all data up to curs1 */ @@ -365,7 +368,7 @@ struct editor_widget { long start_display; /* First char displayed */ long start_col; /* First displayed column, negative */ long max_column; /* The maximum cursor position ever reached used to calc hori scroll bar */ - long curs_row; /*row position of curser on the screen */ + long curs_row; /*row position of cursor on the screen */ long curs_col; /*column position on screen */ int force; /* how much of the screen do we redraw? */ unsigned char overwrite; @@ -377,7 +380,7 @@ struct editor_widget { or saved */ #endif unsigned char highlight; - long prev_col; /*recent column position of the curser - used when moving + long prev_col; /*recent column position of the cursor - used when moving up or down past lines that are shorter than the current line */ long curs_line; /*line number of the cursor. */ long start_line; /*line nummber of the top of the page */ @@ -410,7 +413,7 @@ struct editor_widget { struct _syntax_marker *syntax_marker; struct context_rule **rules; long last_get_rule; - unsigned long rule; + struct syntax_rule rule; char *syntax_type; /* description of syntax highlighting type being used */ int explicit_syntax; /* have we forced the syntax hi. type in spite of the filename? */ @@ -547,8 +550,8 @@ void edit_word_wrap (WEdit * edit); unsigned char *edit_get_block (WEdit * edit, long start, long finish, int *l); int edit_sort_cmd (WEdit * edit); void edit_help_cmd (WEdit * edit); -void edit_left_word_move (WEdit * edit); -void edit_right_word_move (WEdit * edit); +void edit_left_word_move (WEdit * edit, int s); +void edit_right_word_move (WEdit * edit, int s); void edit_get_selection (WEdit * edit); int edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n); @@ -572,13 +575,14 @@ void edit_set_syntax_change_callback (void (*callback) (CWidget *)); void edit_load_syntax (WEdit * edit, char **names, char *type); void edit_free_syntax_rules (WEdit * edit); void edit_get_syntax_color (WEdit * edit, long byte_index, int *fg, int *bg); +int edit_check_spelling (WEdit * edit); void book_mark_insert (WEdit * edit, int line, int c); int book_mark_query_color (WEdit * edit, int line, int c); int book_mark_query_all (WEdit * edit, int line, int *c); struct _book_mark *book_mark_find (WEdit * edit, int line); -void book_mark_clear (WEdit * edit, int line, int c); +int book_mark_clear (WEdit * edit, int line, int c); void book_mark_flush (WEdit * edit, int c); void book_mark_inc (WEdit * edit, int line); void book_mark_dec (WEdit * edit, int line); @@ -666,6 +670,9 @@ extern char *edit_init_error_msg; # define FONT_PIX_PER_LINE (FONT_OVERHEAD + FONT_HEIGHT) # define FONT_MEAN_WIDTH gtk_edit_option_font_mean_width +# define EDIT_FRAME_H 3 +# define EDIT_FRAME_W 3 + # define FONT_OFFSET_X 0 # define FONT_OFFSET_Y FONT_BASE_LINE @@ -772,7 +779,7 @@ enum { extern char *home_dir; -#define NUM_SELECTION_HISTORY 32 +#define NUM_SELECTION_HISTORY 64 #ifndef MAX_PATH_LEN #ifdef PATH_MAX @@ -841,7 +848,7 @@ int option_editor_bg_highlighted = 12; int option_editor_fg_cursor = 18; char *option_whole_chars_search = "0123456789abcdefghijklmnopqrstuvwxyz_"; -char *option_whole_chars_move = "0123456789abcdefghijklmnopqrstuvwxyz_; ,[](){}"; +char *option_chars_move_whole_word = "!=&|<>^~ !:;, !'!`!.?!\"!( !) !Aa0 !+-*/= |<> ![ !] !\\#! "; char *option_backup_ext = "~"; #else /* ! _EDIT_C */ @@ -889,7 +896,7 @@ extern int option_editor_bg_highlighted; extern int option_editor_fg_cursor; extern char *option_whole_chars_search; -extern char *option_whole_chars_move; +extern char *option_chars_move_whole_word; extern char *option_backup_ext; extern int edit_confirm_save; diff --git a/gtkedit/editcmd.c b/gtkedit/editcmd.c index 0defac9ef..51e940f8a 100644 --- a/gtkedit/editcmd.c +++ b/gtkedit/editcmd.c @@ -63,7 +63,7 @@ int edit_confirm_save = 0; static inline int my_lower_case (int c) { - return tolower(c); + return tolower(c & 0xFF); } char *strcasechr (const unsigned char *s, int c) @@ -76,6 +76,8 @@ char *strcasechr (const unsigned char *s, int c) #ifdef MIDNIGHT #include "../src/mad.h" +#elif !defined (GTK) +#include "mad.h" #endif #ifndef HAVE_MEMMOVE @@ -257,13 +259,12 @@ int edit_save_file (WEdit * edit, const char *filename) if (this_save_mode > 0) { char *savedir = ".", *slashpos = strrchr (filename, '/'); if (slashpos != 0) { - savedir = strdup (filename); + savedir = (char *) strdup (filename); if (savedir == 0) return 0; savedir[slashpos - filename + 1] = '\0'; } - savename = tempnam (savedir, "cooledit"); - + savename = (char *) tempnam (savedir, "cooledit"); if (slashpos) free (savedir); if (!savename) @@ -336,13 +337,13 @@ void menu_save_mode_cmd (void) N_("Do backups -->")}; static QuickWidget widgets[] = { - {quick_button, 20, DLG_X, 7, DLG_Y, N_("&Cancel"), 0, + {quick_button, 18, DLG_X, 7, DLG_Y, N_("&Cancel"), 0, B_CANCEL, 0, 0, XV_WLAY_DONTCARE, "c"}, {quick_button, 6, DLG_X, 7, DLG_Y, N_("&Ok"), 0, B_ENTER, 0, 0, XV_WLAY_DONTCARE, "o"}, - {quick_input, 24, DLG_X, 5, DLG_Y, 0, 10, + {quick_input, 23, DLG_X, 5, DLG_Y, 0, 9, 0, 0, &str_result, XV_WLAY_DONTCARE, "i"}, - {quick_label, 24, DLG_X, 4, DLG_Y, N_("Extension:"), 0, + {quick_label, 22, DLG_X, 4, DLG_Y, N_("Extension:"), 0, 0, 0, 0, XV_WLAY_DONTCARE, "savemext"}, {quick_radio, 4, DLG_X, 3, DLG_Y, "", 3, 0, &save_mode_new, str, XV_WLAY_DONTCARE, "t"}, @@ -380,10 +381,10 @@ void edit_split_filename (WEdit * edit, char *f) { if (edit->filename) free (edit->filename); - edit->filename = strdup (f); + edit->filename = (char *) strdup (f); if (edit->dir) free (edit->dir); - edit->dir = strdup (""); + edit->dir = (char *) strdup (""); } #else @@ -456,9 +457,9 @@ void edit_split_filename (WEdit * edit, char *longname) if (edit->dir) free (edit->dir); p = strrchr (exp, '/'); - edit->filename = strdup (++p); + edit->filename = (char *) strdup (++p); *p = 0; - edit->dir = strdup (exp); + edit->dir = (char *) strdup (exp); free (exp); } @@ -475,11 +476,11 @@ int edit_save_as_cmd (WEdit * edit) exp = edit_get_save_file (edit->dir, edit->filename, _(" Save As ")); edit_push_action (edit, KEY_PRESS + edit->start_display); - edit->force |= REDRAW_COMPLETELY; if (exp) { if (!*exp) { free (exp); + edit->force |= REDRAW_COMPLETELY; return 0; } else { if (strcmp(catstrs (edit->dir, edit->filename, 0), exp)) { @@ -490,8 +491,10 @@ int edit_save_as_cmd (WEdit * edit) if (edit_query_dialog2 (_(" Warning "), _(" A file already exists with this name. "), /* Push buttons to over-write the current file, or cancel the operation */ - _("Overwrite"), _("Cancel"))) + _("Overwrite"), _("Cancel"))) { + edit->force |= REDRAW_COMPLETELY; return 0; + } } } if (edit_save_file (edit, exp)) { @@ -503,15 +506,18 @@ int edit_save_as_cmd (WEdit * edit) #endif if (different_filename && !edit->explicit_syntax) edit_load_syntax (edit, 0, 0); + edit->force |= REDRAW_COMPLETELY; return 1; } else { free (exp); edit_error_dialog (_(" Save as "), get_sys_error (_(" Error trying to save file. "))); + edit->force |= REDRAW_COMPLETELY; return 0; } } - } else - return 0; + } + edit->force |= REDRAW_COMPLETELY; + return 0; } /* {{{ Macro stuff starts here */ @@ -670,12 +676,12 @@ int edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n) FILE *f; int s, i; - edit->force |= REDRAW_COMPLETELY; edit_push_action (edit, KEY_PRESS + edit->start_display); /* This heads the 'Macro' dialog box */ s = edit_raw_key_query (_(" Macro "), /* Input line for a single key press follows the ':' */ _(" Press the macro's new hotkey: "), 1); + edit->force |= REDRAW_COMPLETELY; if (s) { if (edit_delete_macro (edit, s)) return 0; @@ -703,23 +709,23 @@ void edit_delete_macro_cmd (WEdit * edit) int command; #ifdef MIDNIGHT - command = CK_Macro (edit_raw_key_query (_(" Delete Macro "), _(" Press macro hotkey: "), 1)); + command = CK_Macro (edit_raw_key_query (_ (" Delete Macro "), _ (" Press macro hotkey: "), 1)); #else /* This heads the 'Delete Macro' dialog box */ #ifdef GTK /* *** */ command = 0; #else - command = CK_Macro (CKeySymMod (CRawkeyQuery (0, 0, 0, _(" Delete Macro "), + command = CKeySymMod (CRawkeyQuery (0, 0, 0, _ (" Delete Macro "), /* Input line for a single key press follows the ':' */ - _(" Press macro hotkey: ")))); + _ (" Press macro hotkey: "))); #endif #endif - if (command == CK_Macro (0)) + if (!command) return; - edit_delete_macro (edit, command - 2000); + edit_delete_macro (edit, command); } /* return 0 on error */ @@ -789,9 +795,9 @@ int edit_save_confirm_cmd (WEdit * edit) /* returns 1 on success */ int edit_save_cmd (WEdit * edit) { - edit->force |= REDRAW_COMPLETELY; if (!edit_save_file (edit, catstrs (edit->dir, edit->filename, 0))) return edit_save_as_cmd (edit); + edit->force |= REDRAW_COMPLETELY; edit->modified = 0; #if defined(MIDNIGHT) || defined(GTK) edit->delete_file = 0; @@ -804,10 +810,13 @@ int edit_save_cmd (WEdit * edit) /* returns 1 on success */ int edit_new_cmd (WEdit * edit) { - edit->force |= REDRAW_COMPLETELY; - if (edit->modified) - if (edit_query_dialog2 (_ (" Warning "), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("Continue"), _ ("Cancel"))) + if (edit->modified) { + if (edit_query_dialog2 (_ (" Warning "), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("Continue"), _ ("Cancel"))) { + edit->force |= REDRAW_COMPLETELY; return 0; + } + } + edit->force |= REDRAW_COMPLETELY; edit->modified = 0; return edit_renew (edit); /* if this gives an error, something has really screwed up */ } @@ -833,11 +842,13 @@ int edit_load_file_from_filename (WEdit *edit, char *exp) int edit_load_cmd (WEdit * edit) { char *exp; - edit->force |= REDRAW_COMPLETELY; - if (edit->modified) - if (edit_query_dialog2 (_ (" Warning "), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("Continue"), _ ("Cancel"))) + if (edit->modified) { + if (edit_query_dialog2 (_ (" Warning "), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("Continue"), _ ("Cancel"))) { + edit->force |= REDRAW_COMPLETELY; return 0; + } + } exp = edit_get_load_file (edit->dir, edit->filename, _ (" Load ")); @@ -846,6 +857,7 @@ int edit_load_cmd (WEdit * edit) edit_load_file_from_filename (edit, exp); free (exp); } + edit->force |= REDRAW_COMPLETELY; return 0; } @@ -1122,10 +1134,11 @@ int edit_block_delete_cmd (WEdit * edit) #define SEARCH_DLG_HEIGHT 10 #define REPLACE_DLG_WIDTH 58 #define REPLACE_DLG_HEIGHT 15 -#define CONFIRM_DLG_WIDTH 66 +#define CONFIRM_DLG_WIDTH 79 #define CONFIRM_DLG_HEIGTH 6 #define B_REPLACE_ALL B_USER+1 -#define B_SKIP_REPLACE B_USER+2 +#define B_REPLACE_ONE B_USER+2 +#define B_SKIP_REPLACE B_USER+3 int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) { @@ -1133,23 +1146,25 @@ int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) QuickWidget quick_widgets[] = { /* NLS for hotkeys? */ - {quick_button, 50, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Cancel"), - 0, B_CANCEL, 0, 0, XV_WLAY_DONTCARE, NULL}, - {quick_button, 37, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("al&L"), - 0, B_REPLACE_ALL, 0, 0, XV_WLAY_DONTCARE, NULL}, - {quick_button, 21, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Skip"), - 0, B_SKIP_REPLACE, 0, 0, XV_WLAY_DONTCARE, NULL}, - {quick_button, 4, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Replace"), - 0, B_ENTER, 0, 0, XV_WLAY_DONTCARE, NULL}, - {quick_label, 2, CONFIRM_DLG_WIDTH, 2, CONFIRM_DLG_HEIGTH, 0, + {quick_button, 63, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Cancel"), + 0, B_CANCEL, 0, 0, XV_WLAY_DONTCARE, NULL}, + {quick_button, 50, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("o&Ne"), + 0, B_REPLACE_ONE, 0, 0, XV_WLAY_DONTCARE, NULL}, + {quick_button, 37, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("al&L"), + 0, B_REPLACE_ALL, 0, 0, XV_WLAY_DONTCARE, NULL}, + {quick_button, 21, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Skip"), + 0, B_SKIP_REPLACE, 0, 0, XV_WLAY_DONTCARE, NULL}, + {quick_button, 4, CONFIRM_DLG_WIDTH, 3, CONFIRM_DLG_HEIGTH, N_("&Replace"), + 0, B_ENTER, 0, 0, XV_WLAY_DONTCARE, NULL}, + {quick_label, 2, CONFIRM_DLG_WIDTH, 2, CONFIRM_DLG_HEIGTH, 0, 0, 0, 0, XV_WLAY_DONTCARE, 0}, {0}}; - quick_widgets[4].text = catstrs (_(" Replace with: "), replace_text, 0); + quick_widgets[5].text = catstrs (_(" Replace with: "), replace_text, 0); { QuickDialog Quick_input = - {CONFIRM_DLG_WIDTH, CONFIRM_DLG_HEIGTH, 0, 0, N_(" Confirm replace "), + {CONFIRM_DLG_WIDTH, CONFIRM_DLG_HEIGTH, 0, 0, N_(" Confirm replace "), "[Input Line Keys]", "quick_input", 0 /*quick_widgets */ }; Quick_input.widgets = quick_widgets; @@ -1162,8 +1177,6 @@ int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) return 0; } - - void edit_replace_dialog (WEdit * edit, char **search_text, char **replace_text, char **arg_order) { int treplace_scanf = replace_scanf; @@ -1319,7 +1332,8 @@ void edit_search_dialog (WEdit * edit, char **search_text) #define B_ENTER 0 #define B_SKIP_REPLACE 1 #define B_REPLACE_ALL 2 -#define B_CANCEL 3 +#define B_REPLACE_ONE 3 +#define B_CANCEL 4 extern CWidget *wedit; @@ -1346,22 +1360,22 @@ void edit_search_replace_dialog (Window parent, int x, int y, char **search_text (CDrawText ("replace.t1", win, xh, h, _(" Enter search text : ")))->hotkey = 'E'; CGetHintPos (0, &yh); - (m = CDrawTextInput ("replace.sinp", win, xh, yh, 10, AUTO_HEIGHT, 256, *search_text))->hotkey = 'E'; + (m = CDrawTextInput ("replace.sinp", win, xh, yh, 10, AUTO_HEIGHT, 8192, *search_text))->hotkey = 'E'; if (replace_text) { CGetHintPos (0, &yh); (CDrawText ("replace.t2", win, xh, yh, _(" Enter replace text : ")))->hotkey = 'n'; CGetHintPos (0, &yh); - (CDrawTextInput ("replace.rinp", win, xh, yh, 10, AUTO_HEIGHT, 256, *replace_text))->hotkey = 'n'; - CSetToolHint ("replace.t2", _("You can enter regexp substrings with %s (not \\1, \\2 like sed) then use \"Enter...order\"")); - CSetToolHint ("replace.rinp", _("You can enter regexp substrings with %s (not \\1, \\2 like sed) then use \"Enter...order\"")); + (CDrawTextInput ("replace.rinp", win, xh, yh, 10, AUTO_HEIGHT, 8192, *replace_text))->hotkey = 'n'; + CSetToolHint ("replace.t2", _("You can enter regexp substrings with %s\n(not \\1, \\2 like sed) then use \"Enter...order\"")); + CSetToolHint ("replace.rinp", _("You can enter regexp substrings with %s\n(not \\1, \\2 like sed) then use \"Enter...order\"")); CGetHintPos (0, &yh); (CDrawText ("replace.t3", win, xh, yh, _(" Enter argument (or substring) order : ")))->hotkey = 'o'; CGetHintPos (0, &yh); (CDrawTextInput ("replace.ainp", win, xh, yh, 10, AUTO_HEIGHT, 256, *arg_order))->hotkey = 'o'; /* Tool hint */ - CSetToolHint ("replace.ainp", _("Enter the order of replacement of your scanf format specifiers or regexp substrings")); - CSetToolHint ("replace.t3", _("Enter the order of replacement of your scanf format specifiers or regexp substrings")); + CSetToolHint ("replace.ainp", _("Enter the order of replacement of your scanf\nformat specifiers or regexp substrings, eg 3,1,2")); + CSetToolHint ("replace.t3", _("Enter the order of replacement of your scanf\nformat specifiers or regexp substrings, eg 3,1,2")); } CGetHintPos (0, &yh); ys = yh; @@ -1372,8 +1386,8 @@ void edit_search_replace_dialog (Window parent, int x, int y, char **search_text yc = yh; CGetHintPos (0, &yh); CDrawSwitch ("replace.reg", win, xh, yh, replace_regexp, _(" Regular expression "), 1); - CSetToolHint ("replace.reg", _("See the regex man page for how to compose a regular expression")); - CSetToolHint ("replace.reg.label", _("See the regex man page for how to compose a regular expression")); + CSetToolHint ("replace.reg", _("See the regex man page for how\nto compose a regular expression")); + CSetToolHint ("replace.reg.label", _("See the regex man page for how\nto compose a regular expression")); yb = yh; CGetHintPos (0, &yh); CGetHintPos (&xb, 0); @@ -1404,7 +1418,7 @@ void edit_search_replace_dialog (Window parent, int x, int y, char **search_text } CDrawSwitch ("replace.scanf", win, xb, yr, replace_scanf, _(" Scanf expression "), 1); /* Tool hint */ - CSetToolHint ("replace.scanf", _("Allows entering of a C format string, see the scanf man page")); + CSetToolHint ("replace.scanf", _("Allows entering of a C format string,\nsee the scanf man page")); get_hint_limits (&x, &y); CDrawPixmapButton ("replace.ok", win, x - WIDGET_SPACING - TICK_BUTTON_WIDTH, h, PIXMAP_BUTTON_TICK); @@ -1446,10 +1460,10 @@ void edit_search_replace_dialog (Window parent, int x, int y, char **search_text if (replace_text) { replace_all = CIdent ("replace.all")->keypressed; replace_prompt = CIdent ("replace.pr")->keypressed; - *replace_text = strdup (CIdent ("replace.rinp")->text); - *arg_order = strdup (CIdent ("replace.ainp")->text); + *replace_text = (char *) strdup (CIdent ("replace.rinp")->text); + *arg_order = (char *) strdup (CIdent ("replace.ainp")->text); } - *search_text = strdup (CIdent ("replace.sinp")->text); + *search_text = (char *) strdup (CIdent ("replace.sinp")->text); replace_whole = CIdent ("replace.ww")->keypressed; replace_case = CIdent ("replace.case")->keypressed; replace_scanf = CIdent ("replace.scanf")->keypressed; @@ -1539,15 +1553,17 @@ int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) char *s; s = gtk_dialog_cauldron ( "Replace", GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB, - " ( (Replace with:)d %Ld )xf / ( %Bxfrq || %Bxfq || %Bxfq || %Bxfgq )f", + " ( (Replace with:)d %Ld )xf / ( %Bxfrq || %Bxfq || %Bxfq || %Bxfq || %Bxfgq )f", replace_text, - "Replace", "Skip", "Replace All", + "Replace", "Skip", "Replace all", "Replace one", GNOME_STOCK_BUTTON_CANCEL ); if (s == GTK_CAULDRON_ESCAPE || !s || s == GNOME_STOCK_BUTTON_CANCEL) return B_CANCEL; - if (!strcmp (s, "Replace All")) + if (!strcmp (s, "Replace all")) return B_REPLACE_ALL; + if (!strcmp (s, "Replace one")) + return B_REPLACE_ONE; if (!strcmp (s, "Skip")) return B_SKIP_REPLACE; if (!strcmp (s, "Replace")) @@ -1561,34 +1577,14 @@ int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) int edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos) { if (replace_prompt) { - int q; - char *p, *r = 0; - r = p = malloc (strlen (replace_text) + NUM_REPL_ARGS * 2); - strcpy (p, replace_text); - while ((p = strchr (p, '%'))) { /* convert "%" to "%%" so no convertion is attempted */ - memmove (p + 2, p + 1, strlen (p) + 1); - *(++p) = '%'; - p++; - } + int q, x[] = + { + B_CANCEL, B_ENTER, B_SKIP_REPLACE, B_REPLACE_ALL, B_REPLACE_ONE, B_CANCEL + }; + q = CQueryDialog (WIN_MESSAGES + (edit->curs_line < 8 ? edit->num_widget_lines / 2 * FONT_PIX_PER_LINE + CYof (edit->widget) : 0), + _ (" Replace "), catstrs (_ (" Replace with: "), replace_text, 0), _ ("Replace"), _ ("Skip"), _ ("Replace all"), _ ("Replace one"), _ ("Cancel"), 0); edit->force |= REDRAW_COMPLETELY; - q = edit_query_dialog4 (_(" Replace "), -/* This is for the confirm replace dialog box. The replaced string comes after the ':' */ - catstrs (_(" Replace with: "), r, 0), -/* Buttons for the confirm replace dialog box. */ - _("Replace"), _("Skip"), _("Replace all"), _("Cancel")); - if (r) - free (r); - switch (q) { - case 0: - return B_ENTER; - case 1: - return B_SKIP_REPLACE; - case 2: - return B_REPLACE_ALL; - case -1: - case 3: - return B_CANCEL; - } + return x[q + 1]; } return 0; } @@ -1634,7 +1630,7 @@ int string_regexp_search (char *pattern, char *string, int len, int match_type, *found_len = 0; return -3; } - old_pattern = strdup (pattern); + old_pattern = (char *) strdup (pattern); old_type = match_type; old_icase = icase; } @@ -1994,9 +1990,9 @@ void edit_replace_cmd (WEdit * edit, int again) if (again) { if (!old1 || !old2) return; - exp1 = strdup (old1); - exp2 = strdup (old2); - exp3 = strdup (old3); + exp1 = (char *) strdup (old1); + exp2 = (char *) strdup (old2); + exp3 = (char *) strdup (old3); } else { edit_push_action (edit, KEY_PRESS + edit->start_display); edit_replace_dialog (edit, &exp1, &exp2, &exp3); @@ -2017,9 +2013,9 @@ void edit_replace_cmd (WEdit * edit, int again) free (old2); if (old3) free (old3); - old1 = strdup (exp1); - old2 = strdup (exp2); - old3 = strdup (exp3); + old1 = (char *) strdup (exp1); + old2 = (char *) strdup (exp2); + old3 = (char *) strdup (exp3); { char *s; @@ -2084,7 +2080,7 @@ void edit_replace_cmd (WEdit * edit, int again) edit_push_key_press (edit); switch (edit_replace_prompt (edit, exp2, /*and prompt 2/3 down */ - edit->num_widget_columns / 2 - 33, edit->num_widget_lines * 2 / 3)) { + edit->num_widget_columns / 2 - 39, edit->num_widget_lines * 2 / 3)) { case B_ENTER: break; case B_SKIP_REPLACE: @@ -2094,6 +2090,9 @@ void edit_replace_cmd (WEdit * edit, int again) replace_prompt = 0; replace_continue = 1; break; + case B_REPLACE_ONE: + replace_continue = 0; + break; case B_CANCEL: replace_yes = 0; replace_continue = 0; @@ -2187,7 +2186,7 @@ void edit_search_cmd (WEdit * edit, int again) if (again) { /*ctrl-hotkey for search again. */ if (!old) return; - exp = strdup (old); + exp = (char *) strdup (old); } else { edit_search_dialog (edit, &exp); edit_push_action (edit, KEY_PRESS + edit->start_display); @@ -2198,7 +2197,7 @@ void edit_search_cmd (WEdit * edit, int again) int len = 0; if (old) free (old); - old = strdup (exp); + old = (char *) strdup (exp); if (edit->found_len && edit->search_start == edit->found_start + 1 && replace_backwards) edit->search_start--; @@ -2248,8 +2247,8 @@ void edit_quit_cmd (WEdit * edit) if (edit->modified) { #ifdef GTK char *r; - r = gtk_dialog_cauldron (_(" Quit "), GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB, " [ ( %Lxf )xf ]xf / ( %Bgxfq || %Bgxfq || %Bgxfq ) ", - _(" Current text was modified without a file save. \n Save with exit? "), GNOME_STOCK_BUTTON_CANCEL, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO); + r = gtk_dialog_cauldron (_ (" Quit "), GTK_CAULDRON_TOPLEVEL | GTK_CAULDRON_GRAB, " [ ( %Lxf )xf ]xf / ( %Bgxfq || %Bgxfq || %Bgxfq ) ", + _ (" Current text was modified without a file save. \n Save with exit? "), GNOME_STOCK_BUTTON_CANCEL, GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO); if (!strcmp (r, GNOME_STOCK_BUTTON_YES)) { edit_push_markers (edit); edit_set_markers (edit, 0, 0, 0, 0); @@ -2263,11 +2262,11 @@ void edit_quit_cmd (WEdit * edit) } #else #ifdef MIDNIGHT - switch (edit_query_dialog3 (_(" Quit "), _(" File was modified, Save with exit? "), _("Cancel quit"), _("&Yes"), _("&No"))) { + switch (edit_query_dialog3 (_ (" Quit "), _ (" File was modified, Save with exit? "), _ ("Cancel quit"), _ ("&Yes"), _ ("&No"))) { #else /* Confirm 'Quit' dialog box */ - switch (edit_query_dialog3 (_(" Quit "), - _(" Current text was modified without a file save. \n Save with exit? "), _(" &Cancel quit "), _(" &Yes "), _(" &No "))) { + switch (edit_query_dialog3 (_ (" Quit "), + _ (" Current text was modified without a file save. \n Save with exit? "), _ (" &Cancel quit "), _ (" &Yes "), _ (" &No "))) { #endif case 1: edit_push_markers (edit); @@ -2296,10 +2295,10 @@ void edit_quit_cmd (WEdit * edit) #else #ifdef GTK { - extern char *edit_one_file; + extern char *edit_one_file; - if (edit_one_file) - gtk_main_quit (); + if (edit_one_file) + gtk_main_quit (); } #endif edit->stopped = 1; @@ -2405,13 +2404,42 @@ char *selection_get_line (void *data, int line) int c, j; for (j = 0; j < s[line].len; j++) { c = *p++; - if ((c < ' ' || (c > '~' && c < 160)) && c != '\t') { - t[i++] = '.'; + if (!isprint (c)) { + t[i++] = '_'; t[i++] = '\b'; - t[i++] = '.'; + t[i++] = '\\'; + t[i++] = '_'; + t[i++] = '\b'; + switch (c) { + case '\a': + t[i++] = 'a'; + break; + case '\b': + t[i++] = 'b'; + break; + case '\t': + t[i++] = 't'; + break; + case '\n': + t[i++] = 'n'; + break; + case '\v': + t[i++] = 'v'; + break; + case '\f': + t[i++] = 'f'; + break; + case '\r': + t[i++] = 'r'; + break; + default: + i -= 3; + t[i++] = '.'; + break; + } } else t[i++] = c; - if (i > 1020) + if (i > 1000) break; } } @@ -2523,8 +2551,8 @@ void edit_paste_from_X_buf_cmd (WEdit * edit) #endif else #ifdef GTK - gtk_selection_convert (GTK_WIDGET (edit->widget), GDK_SELECTION_PRIMARY, - gdk_atom_intern ("COMPOUND_TEXT", FALSE), GDK_CURRENT_TIME); + gtk_selection_convert (GTK_WIDGET (edit->widget), GDK_SELECTION_PRIMARY, + gdk_atom_intern ("COMPOUND_TEXT", FALSE), GDK_CURRENT_TIME); #else XConvertSelection (CDisplay, XA_PRIMARY, XA_STRING, XInternAtom (CDisplay, "VT_SELECTION", False), @@ -2589,7 +2617,7 @@ void edit_goto_cmd (WEdit *edit) char s [12]; sprintf (s, "%d", l); - f = input_dialog (_(" Goto line "), _(" Enter line: "), l ? s : ""); + f = (char *) input_dialog (_(" Goto line "), _(" Enter line: "), l ? s : ""); #endif #else f = CInputDialog ("goto", WIN_MESSAGES, 150, l ? itoa (l) : "", _(" Goto line "), _(" Enter line: ")); @@ -2607,17 +2635,14 @@ void edit_goto_cmd (WEdit *edit) } /*returns 1 on success */ -int edit_save_block_cmd (WEdit * edit) { +int edit_save_block_cmd (WEdit * edit) +{ long start_mark, end_mark; char *exp; if (eval_marks (edit, &start_mark, &end_mark)) return 1; - - exp = edit_get_save_file (edit->dir, catstrs (home_dir, CLIP_FILE, 0), _(" Save Block ")); - - edit->force |= REDRAW_COMPLETELY; + exp = edit_get_save_file (edit->dir, catstrs (home_dir, CLIP_FILE, 0), _ (" Save Block ")); edit_push_action (edit, KEY_PRESS + edit->start_display); - if (exp) { if (!*exp) { free (exp); @@ -2629,13 +2654,14 @@ int edit_save_block_cmd (WEdit * edit) { return 1; } else { free (exp); + edit_error_dialog (_ (" Save Block "), get_sys_error (_ (" Error trying to save file. "))); edit->force |= REDRAW_COMPLETELY; - edit_error_dialog (_(" Save Block "), get_sys_error (_(" Error trying to save file. "))); return 0; } } - } else - return 0; + } + edit->force |= REDRAW_COMPLETELY; + return 0; } @@ -2663,12 +2689,10 @@ int edit_insert_file (WEdit * edit, const char *filename) /* returns 1 on success */ -int edit_insert_file_cmd (WEdit * edit) { - char *exp = edit_get_load_file (edit->dir, catstrs (home_dir, CLIP_FILE, 0), _(" Insert File ")); - edit->force |= REDRAW_COMPLETELY; - +int edit_insert_file_cmd (WEdit * edit) +{ + char *exp = edit_get_load_file (edit->dir, catstrs (home_dir, CLIP_FILE, 0), _ (" Insert File ")); edit_push_action (edit, KEY_PRESS + edit->start_display); - if (exp) { if (!*exp) { free (exp); @@ -2676,15 +2700,18 @@ int edit_insert_file_cmd (WEdit * edit) { } else { if (edit_insert_file (edit, exp)) { free (exp); + edit->force |= REDRAW_COMPLETELY; return 1; } else { free (exp); - edit_error_dialog (_(" Insert file "), get_sys_error (_(" Error trying to insert file. "))); + edit_error_dialog (_ (" Insert file "), get_sys_error (_ (" Error trying to insert file. "))); + edit->force |= REDRAW_COMPLETELY; return 0; } } - } else - return 0; + } + edit->force |= REDRAW_COMPLETELY; + return 0; } #ifdef MIDNIGHT @@ -2784,6 +2811,7 @@ void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block) edit_error_dialog (_(" Process block "), /* Not essential to translate */ get_sys_error (_(" Error trying to stat file "))); + edit->force |= REDRAW_COMPLETELY; return; } } diff --git a/gtkedit/editcmddef.h b/gtkedit/editcmddef.h index b7d789f92..702c12a06 100644 --- a/gtkedit/editcmddef.h +++ b/gtkedit/editcmddef.h @@ -87,6 +87,7 @@ #define CK_Util 417 #define CK_Type_Load_Python 418 #define CK_Find_File 419 +#define CK_Ctags 420 /* application control */ #define CK_Save_Desktop 451 @@ -136,7 +137,7 @@ #define CK_XPaste 703 #define CK_Selection_History 704 -#ifdef MIDNIGHT /* cooledit now has its own full-featured script editor and executor */ +#ifdef MIDNIGHT /* cooledit now has its own full-featured script editor and executor */ /* Process a block through a shell command: CK_Pipe_Block(i) executes shell_cmd[i]. shell_cmd[i] must process the file ~/cooledit.block and output ~/cooledit.block @@ -148,14 +149,15 @@ */ #define CK_Pipe_Block(i) (1000+(i)) #define SHELL_COMMANDS_i {"/.cedit/edit.indent.rc", "/.cedit/edit.spell.rc", /* and so on */ 0}; -#else -#define CK_User_Command(i) (1000+(i)) -#endif - -/* execute a macro */ #define CK_Macro(i) (2000+(i)) #define CK_Last_Macro CK_Macro(0x7FFF) +#else +#define CK_User_Command(i) ((i) | (1 << 16)) +#define IS_USER_COMMAND(i) ((i) & (1 << 16)) +#define CK_Macro(i) ((i) | (1 << 17)) +#define IS_MACRO_COMMAND(i) ((i) & (1 << 17)) +#endif #endif diff --git a/gtkedit/editdraw.c b/gtkedit/editdraw.c index b4fff9ce9..6bcd9a88b 100644 --- a/gtkedit/editdraw.c +++ b/gtkedit/editdraw.c @@ -25,20 +25,21 @@ #define MAX_LINE_LEN 1024 -#ifndef MIDNIGHT -#ifndef GTK +#if ! defined (MIDNIGHT) && ! defined (GTK) #include "app_glob.c" #include "coollocal.h" -#endif -#else -#include "../src/mad.h" +#include "mad.h" #endif extern int column_highlighting; +#if defined (MIDNIGHT) || defined (GTK) + void status_string (WEdit * edit, char *s, int w, int fill, int font_width) { +#ifdef MIDNIGHT int i; +#endif char t[160]; /* 160 just to be sure */ /* The field lengths just prevents the status line from shortening to much */ sprintf (t, "[%c%c%c%c] %2ld:%3ld+%2ld=%3ld/%3ld - *%-4ld/%4ldb=%3d", @@ -49,19 +50,24 @@ void status_string (WEdit * edit, char *s, int w, int fill, int font_width) edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte, edit->curs1 < edit->last_byte ? edit_get_byte (edit, edit->curs1) : -1); +#ifdef MIDNIGHT sprintf (s, "%.*s", w + 1, t); i = strlen (s); s[i] = ' '; i = w; do { - if (strchr (" +-*=/:b", s[i])) /* chop off the last word/number */ + if (strchr ("+-*=/:b", s[i])) /* chop off the last word/number */ break; s[i] = fill; } while (i--); s[i] = fill; s[w] = 0; +#else + strcpy (s, t); +#endif } +#endif #ifdef MIDNIGHT @@ -101,7 +107,7 @@ void edit_status (WEdit * edit) extern int fixed_font; #endif -void rerender_text (CWidget * wdt); +void render_status (CWidget * wdt, int expose); #ifdef GTK @@ -138,40 +144,45 @@ void edit_status (WEdit *edit) void edit_status (WEdit * edit) { - if ((COptionsOf (edit->widget) & EDITOR_NO_TEXT)) { + long start_mark, end_mark; + CWidget *wdt; + mode_t m; + char *p; + char id[33]; + char s[256]; + if (eval_marks (edit, &start_mark, &end_mark)) + end_mark = start_mark = 0; + if ((COptionsOf (edit->widget) & EDITOR_NO_TEXT)) return; - } else { - int w, i, t; - CWidget *wdt; - char id[33]; - char s[160]; - w = edit->num_widget_columns - 1; - if (w > 150) - w = 150; - if (w < 0) - w = 0; - memset (s, 0, w); - if (w > 1) { - i = w > 24 ? 18 : w - 6; - i = i < 13 ? 13 : i; - sprintf (s, "%s", name_trunc (edit->filename ? edit->filename : "", i)); - i = strlen (s); - s[i] = ' '; - s[i+1] = ' '; - t = w - i - 2; - if (t < 0) - t = 0; - status_string (edit, s + i + 2, t, 0, FONT_MEAN_WIDTH); - } - s[w] = 0; - strcpy (id, CIdentOf (edit->widget)); - strcat (id, ".text"); - wdt = CIdent (id); - free (wdt->text); - wdt->text = strdup (s); - CSetWidgetSize (id, CWidthOf (edit->widget), CHeightOf (wdt)); - rerender_text (wdt); - } + m = edit->stat.st_mode; + p = edit->filename ? edit->filename : ""; + sprintf (s, "\034%c%s\033\035 \034-%c%c%c%c%c%c%c%c%c\035 \034%s%s%s%c\035 \034\030%02ld\033\035 \034%-4ld+%2ld=\030%4ld\033/%3ld\035 \034*%-5ld/%5ldb=%c%3d\035%c \034\001%ld\033\035", + *p ? '\033' : '\003', *p ? (char *) name_trunc (p, max (edit->num_widget_lines / 3, 16)) : _ (""), + m & S_IRUSR ? 'r' : '-', + m & S_IWUSR ? 'w' : '-', + m & S_IXUSR ? 'x' : '-', + m & S_IRGRP ? 'r' : '-', + m & S_IWGRP ? 'w' : '-', + m & S_IXGRP ? 'x' : '-', + m & S_IROTH ? 'r' : '-', + m & S_IWOTH ? 'w' : '-', + m & S_IXOTH ? 'x' : '-', + end_mark - start_mark || (edit->mark2 == -1 && !edit->highlight) ? (column_highlighting ? "\032C\033" : "\001B\033") : "-", + edit->modified ? "\012M\033" : "-", edit->macro_i < 0 ? "-" : "\023R\033", + edit->overwrite == 0 ? '-' : 'O', + edit->curs_col / FONT_MEAN_WIDTH, edit->start_line + 1, edit->curs_row, + edit->curs_line + 1, edit->total_lines + 1, edit->curs1, + edit->last_byte, edit->curs1 == edit->last_byte ? '\014' : '\033', edit->curs1 < edit->last_byte + ? edit_get_byte (edit, edit->curs1) : -1, + end_mark - start_mark && !column_highlighting ? ' ' : '\0', + end_mark - start_mark); + strcpy (id, CIdentOf (edit->widget)); + strcat (id, ".text"); + wdt = CIdent (id); + free (wdt->text); + wdt->text = (char *) strdup (s); + CSetWidgetSize (id, CWidthOf (edit->widget), CHeightOf (wdt)); + render_status (wdt, 0); } #endif @@ -216,32 +227,50 @@ int edit_width_of_long_printable (int c); /* this scrolls the text so that cursor is on the screen */ void edit_scroll_screen_over_cursor (WEdit * edit) { - int p, l; + int p; int outby; + int b_extreme, t_extreme, l_extreme, r_extreme; + r_extreme = EDIT_RIGHT_EXTREME; + l_extreme = EDIT_LEFT_EXTREME; + b_extreme = EDIT_BOTTOM_EXTREME; + t_extreme = EDIT_TOP_EXTREME; + if (edit->found_len) { + b_extreme = max (edit->num_widget_lines / 4, b_extreme); + t_extreme = max (edit->num_widget_lines / 4, t_extreme); + } + if (b_extreme + t_extreme + 1 > edit->num_widget_lines) { + int n; + n = b_extreme + t_extreme; + b_extreme = (b_extreme * (edit->num_widget_lines - 1)) / n; + t_extreme = (t_extreme * (edit->num_widget_lines - 1)) / n; + } + if (l_extreme + r_extreme + 1 > edit->num_widget_columns) { + int n; + n = l_extreme + t_extreme; + l_extreme = (l_extreme * (edit->num_widget_columns - 1)) / n; + r_extreme = (r_extreme * (edit->num_widget_columns - 1)) / n; + } p = edit_get_col (edit); edit_update_curs_row (edit); #ifdef MIDNIGHT - outby = p + edit->start_col - edit->num_widget_columns + 1 + (EDIT_RIGHT_EXTREME + edit->found_len); + outby = p + edit->start_col - edit->num_widget_columns + 1 + (r_extreme + edit->found_len); #else - outby = p + edit->start_col - CWidthOf (edit->widget) + 7 + (EDIT_RIGHT_EXTREME + edit->found_len) * FONT_MEAN_WIDTH + edit_width_of_long_printable (edit_get_byte (edit, edit->curs1)); + outby = p + edit->start_col - CWidthOf (edit->widget) + 7 + (r_extreme + edit->found_len) * FONT_MEAN_WIDTH + edit_width_of_long_printable (edit_get_byte (edit, edit->curs1)); #endif if (outby > 0) edit_scroll_right (edit, outby); #ifdef MIDNIGHT - outby = EDIT_LEFT_EXTREME - p - edit->start_col; + outby = l_extreme - p - edit->start_col; #else - outby = EDIT_LEFT_EXTREME * FONT_MEAN_WIDTH - p - edit->start_col; + outby = l_extreme * FONT_MEAN_WIDTH - p - edit->start_col; #endif if (outby > 0) edit_scroll_left (edit, outby); p = edit->curs_row; - l = 0; - if (edit->found_len != 0) - l = edit->num_widget_lines / 5; - outby = p - edit->num_widget_lines + 1 + EDIT_BOTTOM_EXTREME + l; + outby = p - edit->num_widget_lines + 1 + b_extreme; if (outby > 0) edit_scroll_downward (edit, outby); - outby = EDIT_TOP_EXTREME - p + l; + outby = t_extreme - p; if (outby > 0) edit_scroll_upward (edit, outby); edit_update_curs_row (edit); @@ -440,11 +469,20 @@ int edit_mouse_pending (Window win); static int key_pending (WEdit * edit) { + static int flush = 0, line = 0; #ifdef GTK /* ******* */ #else - if (!(edit->force & REDRAW_COMPLETELY) && !EditExposeRedraw) - return CKeyPending (); + if (!edit) { + flush = line = 0; + } else if (!(edit->force & REDRAW_COMPLETELY) && !EditExposeRedraw) { +/* this flushes the display in logarithmic intervals - so both fast and + slow machines will get good performance vs nice-refreshing */ + if ((1 << flush) == ++line) { + flush++; + return CKeyPending (); + } + } #endif return 0; } @@ -478,6 +516,10 @@ void render_edit_text (WEdit * edit, long start_row, long start_column, long end int force = edit->force; long b; +#ifndef MIDNIGHT + key_pending (0); +#endif + /* if the position of the page has not moved then we can draw the cursor character only. This will prevent line flicker when using arrow keys. @@ -708,8 +750,8 @@ void edit_render_expose (WEdit * edit, XExposeEvent * xexpose) { int row_start, col_start, row_end, col_end; EditExposeRedraw = 1; - edit->num_widget_lines = (CHeightOf (edit->widget) - 6) / FONT_PIX_PER_LINE; - edit->num_widget_columns = (CWidthOf (edit->widget) - 7) / FONT_MEAN_WIDTH; + edit->num_widget_lines = (CHeightOf (edit->widget) - EDIT_FRAME_H) / FONT_PIX_PER_LINE; + edit->num_widget_columns = (CWidthOf (edit->widget) - EDIT_FRAME_W) / FONT_MEAN_WIDTH; if (edit->force & (REDRAW_PAGE | REDRAW_COMPLETELY)) { edit->force |= REDRAW_PAGE | REDRAW_COMPLETELY; edit_render_keypress (edit); diff --git a/gtkedit/editmenu.c b/gtkedit/editmenu.c index b7e796147..ebaa37b36 100644 --- a/gtkedit/editmenu.c +++ b/gtkedit/editmenu.c @@ -25,6 +25,10 @@ #include "editcmddef.h" +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif + #ifdef MIDNIGHT #include "../src/mad.h" @@ -67,14 +71,14 @@ void edit_wrap_cmd () void edit_about_cmd () { - edit_message_dialog (wedit->mainid, 20, 20, _(" About "), - _("\n" - " Cooledit v2.1\n" + edit_message_dialog (wedit->mainid, 20, 20, " About ", + "\n" + " Cooledit v3.11.5\n" "\n" " Copyright (C) 1996 the Free Software Foundation\n" "\n" " A user friendly text editor written\n" - " for the Midnight Commander.\n") + " for the Midnight Commander.\n" ); } @@ -400,7 +404,7 @@ void CDrawEditMenuButtons (const char *ident, Window parent, Window focus_return _("Copy to file...\tC-f"), '~', menu_cmd, (unsigned long) CK_Save_Block ); /* Tool hint */ - CSetToolHint (catstrs (ident, ".filemenu", 0), _("Disk operations")); + CSetToolHint (catstrs (ident, ".filemenu", 0), _("Disk operations and file indexing/searching")); CGetHintPos (&x, &d); diff --git a/gtkedit/editwidget.c b/gtkedit/editwidget.c index 9709f1b5a..a02f7d77d 100644 --- a/gtkedit/editwidget.c +++ b/gtkedit/editwidget.c @@ -20,7 +20,6 @@ 02111-1307, USA. */ - #include #include "edit.h" @@ -32,7 +31,9 @@ #include "editcmddef.h" #include "mousemark.h" #endif - +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif #ifndef MIDNIGHT @@ -142,9 +143,12 @@ static void release_mark (WEdit * edit, XEvent * event) if (edit->mark1 != edit->mark2 && event) { edit_get_selection (edit); XSetSelectionOwner (CDisplay, XA_PRIMARY, CWindowOf (edit->widget), event->xbutton.time); - } else { + } +#ifdef GTK + else { edit->widget->editable.has_selection = TRUE; } +#endif } static char *get_block (WEdit * edit, long start_mark, long end_mark, int *type, int *l) @@ -166,9 +170,9 @@ static void move (WEdit *edit, long click, int y) static void dclick (WEdit *edit, XEvent *event) { edit_mark_cmd (edit, 1); - edit_right_word_move (edit); + edit_right_word_move (edit, 1); edit_mark_cmd (edit, 0); - edit_left_word_move (edit); + edit_left_word_move (edit, 1); release_mark (edit, event); } @@ -265,6 +269,7 @@ struct mouse_funcs edit_mouse_funcs = mime_majors }; +static void render_book_marks (CWidget *w); extern int option_editor_bg_normal; void edit_tri_cursor (Window win); @@ -273,7 +278,7 @@ CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y, int width, int height, const char *text, const char *filename, const char *starting_directory, unsigned int options, unsigned long text_size) { - static made_directory = 0; + static int made_directory = 0; int extra_space_for_hscroll = 0; CWidget *w; WEdit *e; @@ -282,7 +287,7 @@ CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y, extra_space_for_hscroll = 8; wedit = w = CSetupWidget (identifier, parent, x, y, - width + 7, height + 6, C_EDITOR_WIDGET, + width + EDIT_FRAME_W, height + EDIT_FRAME_H, C_EDITOR_WIDGET, ExposureMask | ButtonPressMask | ButtonReleaseMask | \ KeyPressMask | KeyReleaseMask | ButtonMotionMask | \ PropertyChangeMask | StructureNotifyMask | \ @@ -296,9 +301,9 @@ CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y, w->destroy = edit_destroy_callback; if (filename) - w->label = strdup (filename); + w->label = (char *) strdup (filename); else - w->label = strdup (""); + w->label = (char *) strdup (""); if (!made_directory) { mkdir (catstrs (home_dir, EDIT_DIR, 0), 0700); @@ -323,22 +328,45 @@ CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y, e->macro_i = -1; e->widget = w; - set_hint_pos (x + width + 7 + WIDGET_SPACING, y + height + 6 + WIDGET_SPACING + extra_space_for_hscroll); + set_hint_pos (x + width + EDIT_FRAME_W + WIDGET_SPACING, y + height + EDIT_FRAME_H + WIDGET_SPACING + extra_space_for_hscroll); if (extra_space_for_hscroll) { w->hori_scrollbar = CDrawHorizontalScrollbar (catstrs (identifier, ".hsc", 0), parent, - x, y + height + 6, width + 6, 12, 0, 0); + x, y + height + EDIT_FRAME_H, width + EDIT_FRAME_W, 12, 0, 0); CSetScrollbarCallback (w->hori_scrollbar->ident, w->ident, link_hscrollbar_to_editor); } if (!(options & EDITOR_NO_TEXT)) - CDrawText (catstrs (identifier, ".text", 0), parent, x, y + height + 6 + WIDGET_SPACING + extra_space_for_hscroll, "%s", e->filename); + CDrawStatus (catstrs (identifier, ".text", 0), parent, x, y + height + 3 + EDIT_FRAME_H + WIDGET_SPACING + extra_space_for_hscroll, width + EDIT_FRAME_W, e->filename); if (!(options & EDITOR_NO_SCROLL)) { w->vert_scrollbar = CDrawVerticalScrollbar (catstrs (identifier, ".vsc", 0), parent, - x + width + 7 + WIDGET_SPACING, y, height + 6, 20, 0, 0); + x + width + EDIT_FRAME_W + WIDGET_SPACING, y, height + EDIT_FRAME_H, 20, 0, 0); CSetScrollbarCallback (w->vert_scrollbar->ident, w->ident, link_scrollbar_to_editor); + w->vert_scrollbar->scroll_bar_extra_render = render_book_marks; } return w; } +static void render_book_marks (CWidget * w) +{ + struct _book_mark *p; + WEdit *edit; + int l; + char i[32]; + if (!w) + return; + strcpy (i, CIdentOf (w)); + *(strstr (i, ".vsc")) = '\0'; + edit = (CIdent (i))->editor; + if (!edit->book_mark) + return; + l = CHeightOf (w) - 10 * CWidthOf (w) / 3 - 10; + for (p = edit->book_mark; p->next; p = p->next); + for (; p->prev; p = p->prev) { + int y = (CWidthOf (w) + 2 * CWidthOf (w) / 3 + 4) + (int) ((double) l * p->line / edit->total_lines); + CSetColor (color_palette (p->c & 0xFF)); + CLine (CWindowOf (w), 5, y, CWidthOf (w) - 6, y); + } +} + void update_scroll_bars (WEdit * e) { int i, x1, x2; @@ -571,6 +599,7 @@ void paste_prop (void *data, void (*insert) (void *, int), Window win, unsigned Atom actual_type; int actual_fmt, i; unsigned long nitems; + if (XGetWindowProperty (CDisplay, win, prop, nread / 4, 65536, delete, AnyPropertyType, &actual_type, &actual_fmt, @@ -633,7 +662,6 @@ void edit_update_screen (WEdit * e) } } - extern int space_width; #ifdef HAVE_DND diff --git a/gtkedit/gtkedit.c b/gtkedit/gtkedit.c index ec3f81d45..d03a7499e 100644 --- a/gtkedit/gtkedit.c +++ b/gtkedit/gtkedit.c @@ -665,9 +665,9 @@ static gint gtk_edit_button_press_release (GtkWidget * widget, case GDK_2BUTTON_PRESS: dragging = 0; edit_cursor_move (e, mouse_pos - e->curs1); - edit_right_word_move (e); + edit_right_word_move (e, 1); mouse_pos = e->curs1; - edit_left_word_move (e); + edit_left_word_move (e, 1); button_down_pos = e->curs1; gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos); gtk_edit_mouse_redraw (e, mouse_pos); @@ -911,7 +911,7 @@ static void gtk_edit_class_init (GtkEditClass * class) static void gtk_edit_init (GtkEdit * edit) { - static made_directory = 0; + static int made_directory = 0; GTK_WIDGET_SET_FLAGS (edit, GTK_CAN_FOCUS); diff --git a/gtkedit/propfont.c b/gtkedit/propfont.c index 2a078d3ff..c115a1619 100644 --- a/gtkedit/propfont.c +++ b/gtkedit/propfont.c @@ -19,6 +19,9 @@ #include #include "edit.h" +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif /* this file definatively relies on int being 32 bits or more */ @@ -51,26 +54,28 @@ extern unsigned long edit_cursor_color; extern int EditExposeRedraw; extern int EditClear; -void set_style_color ( +int set_style_color ( #ifdef GTK Window win, #endif cache_type s, unsigned long *fg, unsigned long *bg) { - int fgp, bgp; + int fgp, bgp, underlined = 0; fgp = (s & 0xFF000000UL) >> 24; /* NO_COLOR would give fgp == 255 */ - if (fgp < 255) + if (fgp < 0xFF) *fg = color_palette (fgp); else *fg = edit_normal_foreground_color; bgp = (s & 0x00FF0000) >> 16; - if (bgp < 255) + if (bgp == 0xFE) + underlined = 1; + if (bgp < 0xFD) *bg = color_palette (bgp); else *bg = edit_normal_background_color; if (!(s & 0xFFFFFF00UL)) /* check this first as an optimization */ - return; + return underlined; if (s & (MOD_ABNORMAL * 256)) { *bg = edit_abnormal_color; if (s & (MOD_MARKED * 256)) @@ -92,6 +97,7 @@ void set_style_color ( if (*bg == COLOR_BLACK) *bg = color_palette (1); } + return underlined; } #ifdef GTK @@ -105,30 +111,13 @@ static inline int next_tab_pos (int x) return x += tab_width - x % tab_width; } -/* For Ryan: */ -/* converts a possibly unprintable character to a string, - returning the string's width in pixels, t must have space for 4 chars */ +/* this now properly uses ctypes */ static inline int convert_to_long_printable (int c, unsigned char *t) { - if (c > ' ') { - if (c <= '~') { - t[0] = c; - t[1] = 0; - return per_char[c]; - } - if (c >= 160) - if (option_international_characters) { - t[0] = c; - t[1] = 0; - return per_char[c]; - } - if (c > '~') { - t[0] = ("0123456789ABCDEF")[c >> 4]; - t[1] = ("0123456789ABCDEF")[c & 0xF]; - t[2] = 'h'; - t[3] = 0; - return per_char[t[0]] + per_char[t[1]] + per_char[t[2]]; - } + if (isgraph (c)) { + t[0] = c; + t[1] = 0; + return per_char[c]; } if (c == ' ') { if (option_long_whitespace) { @@ -142,6 +131,18 @@ static inline int convert_to_long_printable (int c, unsigned char *t) return per_char[' ']; } } + if (option_international_characters && per_char[c]) { + t[0] = c; + t[1] = 0; + return per_char[c]; + } + if (c > '~') { + t[0] = ("0123456789ABCDEF")[c >> 4]; + t[1] = ("0123456789ABCDEF")[c & 0xF]; + t[2] = 'h'; + t[3] = 0; + return per_char[t[0]] + per_char[t[1]] + per_char[t[2]]; + } t[0] = '^'; t[1] = c + '@'; t[2] = 0; @@ -151,21 +152,18 @@ static inline int convert_to_long_printable (int c, unsigned char *t) /* same as above but just gets the length */ static inline int width_of_long_printable (int c) { - if (c > ' ') { - if (c <= '~') - return per_char[c]; - if (c >= 160) - if (option_international_characters) - return per_char[c]; - if (c > '~') - return per_char[(unsigned char) ("0123456789ABCDEF")[c >> 4]] + per_char[(unsigned char) ("0123456789ABCDEF")[c & 0xF]] + per_char['h']; - } + if (isgraph (c)) + return per_char[c]; if (c == ' ') { if (option_long_whitespace) return per_char[' '] + per_char[' ']; else return per_char[' ']; } + if (option_international_characters && per_char[c]) + return per_char[c]; + if (c > '~') + return per_char[(unsigned char) ("0123456789ABCDEF")[c >> 4]] + per_char[(unsigned char) ("0123456789ABCDEF")[c & 0xF]] + per_char[(unsigned char) 'h']; return per_char['^'] + per_char[c + '@']; } @@ -249,6 +247,18 @@ long edit_move_forward3 (WEdit * edit, long current, int pixels, long upto) extern int column_highlighting; +/* gets the characters style (eg marked, highlighted) from its position in the edit buffer */ +static inline cache_type get_style_fast (WEdit * edit, long q, int c) +{ + cache_type s = 0; + unsigned int fg, bg; + if (!(isprint (c) || (option_international_characters && per_char[c]))) + if (c != '\n' && c != '\t') + s |= MOD_ABNORMAL * 256; + edit_get_syntax_color (edit, q, (int *) &fg, (int *) &bg); + return s | ((fg & 0xFF) << 24) | ((bg & 0xFF) << 16); +} + /* gets the characters style (eg marked, highlighted) from its position in the edit buffer */ static inline cache_type get_style (WEdit * edit, long q, int c, long m1, long m2, int x) { @@ -269,13 +279,9 @@ static inline cache_type get_style (WEdit * edit, long q, int c, long m1, long m s |= MOD_BOLD * 256; if (q >= edit->found_start && q < edit->found_start + edit->found_len) s |= MOD_HIGHLIGHTED * 256; - if (option_international_characters) { - if ((c < ' ' || (c > '~' && c < 160)) && c != '\t' && c != '\n') + if (!(isprint (c) || (option_international_characters && per_char[c]))) + if (c != '\n' && c != '\t') s |= MOD_ABNORMAL * 256; - } else { - if ((c < ' ' || c > '~') && c != '\t' && c != '\n') - s |= MOD_ABNORMAL * 256; - } edit_get_syntax_color (edit, q, (int *) &fg, (int *) &bg); return s | ((fg & 0xFF) << 24) | ((bg & 0xFF) << 16); } @@ -284,72 +290,151 @@ void convert_text (WEdit * edit, long q, cache_type * p, int x, int x_max, int r { int c; cache_type s; - long m1, m2; + long m1, m2, last; unsigned char *r, text[4]; - int book_mark_colors[10], book_mark, book_mark_cycle = 0, the_end = 0; - + int book_mark_colors[10], book_mark; eval_marks (edit, &m1, &m2); - book_mark = book_mark_query_all (edit, edit->start_line + row, book_mark_colors); - - for (;;) { - c = edit_get_byte (edit, q); - if (!the_end) - *p = get_style (edit, q, c, m1, m2, x); - if (book_mark) { + last = q + (x_max - x) / 2 + 2; /* for optimization, we say that the last character + of this line cannot have an offset greater than this. + This can be used to rule out uncommon text styles, + like a character with a cursor, or selected text */ + if (book_mark) { + int the_end = 0, book_mark_cycle = 0; + for (;;) { + c = edit_get_byte (edit, q); + if (!the_end) + *p = get_style (edit, q, c, m1, m2, x); if (the_end) *p = 0; *p = (*p & 0x0000FFFF) | (book_mark_colors[book_mark_cycle++ % book_mark] << 16); - } - switch (c) { - case '\n': - if (book_mark) { /* bookmarks must show right across the screen */ + switch (c) { + case '\n': the_end = 1; c = ' '; q--; goto the_default; - } else { + case '\t': + if (fixed_font) { + int t; + t = next_tab_pos (x); + t = min (t, x_max); + s = *p; + while (x < t) { + x += per_char[' ']; + *p++ = s | ' '; + } + } else { + *p++ |= '\t'; + x = next_tab_pos (x); + } + break; + default: + the_default: + x += convert_to_long_printable (c, text); + r = text; + s = *p; + *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + break; + } + if (x >= x_max) + break; + q++; + } + } else if ((m2 < q || m1 > last) && (edit->curs1 < q || edit->curs1 > last) && \ + (edit->found_start + edit->found_len < q || edit->found_start > last) && + (edit->bracket < q || edit->bracket > last)) { + for (;;) { + c = edit_get_byte (edit, q); + *p = get_style_fast (edit, q, c); + switch (c) { + case '\n': *p++ |= ' '; *p = 0; if (x > edit->max_column) edit->max_column = x; return; - } - case '\t': - if (fixed_font) { - int t; - t = next_tab_pos (x); - t = min (t, x_max); - s = *p; - while (x < t) { -#if 0 - if (book_mark) - *p = (*p & 0x0000FFFF) | (book_mark_colors[book_mark_cycle++ % book_mark] << 16); -#endif - x += per_char[' ']; - *p++ = s | ' '; + case '\t': + if (fixed_font) { + int t; + t = next_tab_pos (x); + t = min (t, x_max); + s = *p; + while (x < t) { + x += per_char[' ']; + *p++ = s | ' '; + } + } else { + *p++ |= '\t'; + x = next_tab_pos (x); } - } else { - *p++ |= '\t'; - x = next_tab_pos (x); - } - break; - default: - the_default: - x += convert_to_long_printable (c, text); - r = text; - s = *p; - *p++ = s | *r++; - if (*r) { + break; + default: + x += convert_to_long_printable (c, text); + r = text; + s = *p; *p++ = s | *r++; - if (*r) - *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + break; } - break; + if (x >= x_max) + break; + q++; + } + } else { + for (;;) { + c = edit_get_byte (edit, q); + *p = get_style (edit, q, c, m1, m2, x); + switch (c) { + case '\n': + *p++ |= ' '; + *p = 0; + if (x > edit->max_column) + edit->max_column = x; + return; + case '\t': + if (fixed_font) { + int t; + t = next_tab_pos (x); + t = min (t, x_max); + s = *p; + while (x < t) { + x += per_char[' ']; + *p++ = s | ' '; + } + } else { + *p++ |= '\t'; + x = next_tab_pos (x); + } + break; + default: + x += convert_to_long_printable (c, text); + r = text; + s = *p; + *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + if (!*r) + break; + *p++ = s | *r++; + break; + } + if (x >= x_max) + break; + q++; } - if (x >= x_max) - break; - q++; } if (x > edit->max_column) edit->max_column = x; @@ -488,6 +573,7 @@ int draw_string (Window win, int x, int y, cache_type s, unsigned char *text, in GdkColor fg, bg; #else unsigned long fg, bg; + int underlined, l; #endif #ifdef GTK set_style_color (s, &fg.pixel, &bg.pixel); @@ -495,12 +581,24 @@ int draw_string (Window win, int x, int y, cache_type s, unsigned char *text, in gdk_gc_set_foreground (win->gc, &fg); gdk_draw_image_text (win->text_area, GTK_WIDGET (win)->style->font, win->gc, x + FONT_OFFSET_X, y + FONT_OFFSET_Y, text, length); #else - set_style_color (s, &fg, &bg); + underlined = set_style_color (s, &fg, &bg); CSetBackgroundColor (bg); CSetColor (fg); CImageString (win, x + FONT_OFFSET_X, y + FONT_OFFSET_Y, (char *) text, length); + l = CTextWidth (win, (char *) text, length); + if (underlined) { + int i, h, inc; + inc = FONT_MEAN_WIDTH * 2 / 3; + CSetColor (color_palette (18)); + h = (x / inc) & 1; + CLine (win, x, y + FONT_HEIGHT + FONT_OVERHEAD - 1 - h, x + min (l, inc - (x % inc) - 1), y + FONT_HEIGHT + FONT_OVERHEAD - 1 - h); + h = h ^ 1; + for (i = inc - min (l, (x % inc)); i < l; i += inc) { + CLine (win, x + i, y + FONT_HEIGHT + FONT_OVERHEAD - 1 - h, x + min (l, i + inc - 1), y + FONT_HEIGHT + FONT_OVERHEAD - 1 - h); + h = h ^ 1; + } + } #endif - /* if we printed a cursor: */ #ifdef GTK if (s & (MOD_CURSOR * 256)) @@ -509,19 +607,18 @@ int draw_string (Window win, int x, int y, cache_type s, unsigned char *text, in #else if (s & (MOD_CURSOR * 256)) edit_set_cursor (win, x, y, bg, fg, per_char[*text], *text); - return x + CTextWidth (win, (char *) text, length); + return x + l; #endif } -#define STYLE_DIFF (cache[i] != line[i] \ - || ((cache[i] | line[i]) & (MOD_CURSOR * 256)) \ - || !cache[i] || !line[i] \ - ) +#define STYLE_DIFF (*cache != *line \ + || ((*cache | *line) & (MOD_CURSOR * 256)) \ + || !*cache || !*line) int get_ignore_length (cache_type *cache, cache_type *line) { int i; - for (i = 0; i < CACHE_WIDTH; i++) { + for (i = 0; i < CACHE_WIDTH; i++, line++, cache++) { if (STYLE_DIFF) return i; } @@ -554,7 +651,7 @@ int get_ignore_trailer (cache_type *cache, cache_type *line, int length) if (line[i] != ' ') return i + 1; - for (i = cache_len - 1; i > length; i--) + for (i = cache_len - 1, line = line + i, cache = cache + i; i > length; i--, line--, cache--) if (STYLE_DIFF) return i + 1; @@ -562,19 +659,32 @@ int get_ignore_trailer (cache_type *cache, cache_type *line, int length) } /* erases trailing bit of old line if a new line is printed over a longer old line */ -void cover_trail (Window win, int x_new, int x_old, int y) +static void cover_trail (Window win, int x_start, int x_new, int x_old, int y) { if (x_new < EDIT_TEXT_HORIZONTAL_OFFSET) - x_new = EDIT_TEXT_HORIZONTAL_OFFSET; - if (x_new >= x_old) /* no need to print */ - return; + x_new = EDIT_TEXT_HORIZONTAL_OFFSET; + if (x_new < x_old) { /* no need to print */ #ifdef GTK - gdk_gc_set_foreground (win->gc, &win->color[1]); - gdk_draw_rectangle (win->text_area, win->gc, 1, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT); + gdk_gc_set_foreground (win->gc, &win->color[1]); + gdk_draw_rectangle (win->text_area, win->gc, 1, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT); #else - CSetColor (edit_normal_background_color); -/* CSetColor (color_palette(12)); */ - CRectangle (win, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT); + CSetColor (edit_normal_background_color); + CRectangle (win, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT + (FONT_OVERHEAD != 0 && !fixed_font)); +#endif + } else { +#ifdef GTK + gdk_gc_set_foreground (win->gc, &win->color[1]); +#else + CSetColor (edit_normal_background_color); +#endif + } +/* true type fonts print stuff out of the bounding box (aaaaaaaaarrrgh!!) */ + if (!fixed_font) + if (FONT_OVERHEAD && x_new > EDIT_TEXT_HORIZONTAL_OFFSET) +#ifdef GTK + gdk_draw_line (win->text_area, win->gc, max (x_start, EDIT_TEXT_HORIZONTAL_OFFSET), y + FONT_HEIGHT + FONT_OVERHEAD, x_new - 1, y + FONT_HEIGHT + FONT_OVERHEAD); +#else + CLine (win, max (x_start, EDIT_TEXT_HORIZONTAL_OFFSET), y + FONT_HEIGHT + FONT_OVERHEAD, x_new - 1, y + FONT_HEIGHT + FONT_OVERHEAD); #endif } @@ -688,7 +798,7 @@ void edit_draw_proportional (void *data, x = min (x, x_max); if (!EditExposeRedraw || EditClear) - cover_trail (win, x, lines[row].x1, y); + cover_trail (win, x0, x, lines[row].x1, y); memcpy (&(lines[row].data[ignore_text]), &(line[ignore_text]), (min (j, CACHE_WIDTH) - ignore_text) * sizeof (cache_type)); @@ -711,7 +821,7 @@ void edit_draw_this_line_proportional (WEdit * edit, long b, int row, int start_ return; if (row + edit->start_line > edit->total_lines) - b = 2000000000; /* force b out of range of the edit buffer for blanks lines */ + b = edit->last_byte + 1; /* force b out of range of the edit buffer for blanks lines */ if (end_column > CWidthOf (edit->widget)) end_column = CWidthOf (edit->widget); @@ -733,7 +843,7 @@ void edit_draw_this_line_proportional (WEdit * edit, long b, int row, int start_ static inline int nroff_printable (int c) { - return ((c >= ' ' && c <= '~') || c >= 160); + return isprint (c); } diff --git a/gtkedit/syntax.c b/gtkedit/syntax.c index fde237304..8ce3524c7 100644 --- a/gtkedit/syntax.c +++ b/gtkedit/syntax.c @@ -26,13 +26,29 @@ #else #include "coolwidget.h" #endif +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif /* bytes */ #define SYNTAX_MARKER_DENSITY 512 +/* + Mispelled words are flushed from the syntax highlighting rules + when they have been around longer than + TRANSIENT_WORD_TIME_OUT seconds. At a cursor rate of 30 + chars per second and say 3 chars + a space per word, we can + accumulate 450 words absolute max with a value of 60. This is + below this limit of 1024 words in a context. + */ +#define TRANSIENT_WORD_TIME_OUT 60 + +#define UNKNOWN_FORMAT "unknown" + #if !defined(MIDNIGHT) || defined(HAVE_SYNTAXH) int option_syntax_highlighting = 1; +int option_auto_spellcheck = 1; /* these three functions are called from the outside */ void edit_load_syntax (WEdit * edit, char **names, char *type); @@ -49,29 +65,33 @@ static void *syntax_malloc (size_t x) #define syntax_free(x) {if(x){free(x);(x)=0;}} -static int compare_word_to_right (WEdit * edit, long i, char *text, char *whole_left, char *whole_right, int line_start) +static long compare_word_to_right (WEdit * edit, long i, char *text, char *whole_left, char *whole_right, int line_start) { - char *p; + unsigned char *p, *q; int c, d, j; if (!*text) - return 0; + return -1; c = edit_get_byte (edit, i - 1); if (line_start) if (c != '\n') - return 0; + return -1; if (whole_left) if (strchr (whole_left, c)) - return 0; - for (p = text; *p; p++, i++) { + return -1; + for (p = (unsigned char *) text, q = p + strlen ((char *) p); (unsigned long) p < (unsigned long) q; p++, i++) { switch (*p) { case '\001': p++; for (;;) { c = edit_get_byte (edit, i); + if (!*p) + if (whole_right) + if (!strchr (whole_right, c)) + break; if (c == *p) break; if (c == '\n') - return 0; + return -1; i++; } break; @@ -80,20 +100,31 @@ static int compare_word_to_right (WEdit * edit, long i, char *text, char *whole_ j = 0; for (;;) { c = edit_get_byte (edit, i); - if (c == *p) + if (c == *p) { j = i; - if (j && strchr (p + 1, c)) /* c exists further down, so it will get matched later */ + if (*p == *text && !p[1]) /* handle eg '+' and @+@ keywords properly */ + break; + } + if (j && strchr ((char *) p + 1, c)) /* c exists further down, so it will get matched later */ break; if (c == '\n' || c == '\t' || c == ' ') { + if (!*p) { + i--; + break; + } if (!j) - return 0; + return -1; i = j; break; } if (whole_right) if (!strchr (whole_right, c)) { + if (!*p) { + i--; + break; + } if (!j) - return 0; + return -1; i = j; break; } @@ -102,14 +133,6 @@ static int compare_word_to_right (WEdit * edit, long i, char *text, char *whole_ break; case '\003': p++; -#if 0 - c = edit_get_byte (edit, i++); - for (j = 0; p[j] != '\003'; j++) - if (c == p[j]) - goto found_char1; - return 0; - found_char1: -#endif c = -1; for (;; i++) { d = c; @@ -127,304 +150,177 @@ static int compare_word_to_right (WEdit * edit, long i, char *text, char *whole_ if (p[1] == d) i--; break; -#if 0 case '\004': p++; - c = edit_get_byte (edit, i++); - for (j = 0; p[j] != '\004'; j++) - if (c == p[j]) - return 0; - for (;; i++) { - c = edit_get_byte (edit, i); - for (j = 0; p[j] != '\004'; j++) - if (c == p[j]) - goto found_char4; - continue; - found_char4: - break; - } - i--; - while (*p != '\004') - p++; + c = edit_get_byte (edit, i); + for (; *p != '\004'; p++) + if (c == *p) + goto found_char3; + return -1; + found_char3: + for (; *p != '\004'; p++); break; -#endif default: if (*p != edit_get_byte (edit, i)) - return 0; + return -1; } } if (whole_right) if (strchr (whole_right, edit_get_byte (edit, i))) - return 0; - return 1; + return -1; + return i; } -static int compare_word_to_left (WEdit * edit, long i, char *text, char *whole_left, char *whole_right, int line_start) +#define XXX \ + if (*s < '\005' || *s == (unsigned char) c) \ + goto done; \ + s++; + +static inline char *xx_strchr (const unsigned char *s, int c) { - char *p; - int c, d, j; - if (!*text) - return 0; - if (whole_right) - if (strchr (whole_right, edit_get_byte (edit, i + 1))) - return 0; - for (p = text + strlen (text) - 1; (unsigned long) p >= (unsigned long) text; p--, i--) { - switch (*p) { - case '\001': - p--; - for (;;) { - c = edit_get_byte (edit, i); - if (c == *p) - break; - if (c == '\n') - return 0; - i--; - } - break; - case '\002': - p--; - for (;;) { - c = edit_get_byte (edit, i); - if (c == *p) - break; - if (c == '\n' || c == '\t' || c == ' ') - return 0; - if (whole_right) - if (!strchr (whole_right, c)) - return 0; - i--; - } - break; - case '\003': - while (*(--p) != '\003'); - p++; -#if 0 - c = edit_get_byte (edit, i--); - for (j = 0; p[j] != '\003'; j++) - if (c == p[j]) - goto found_char1; - return 0; - found_char1: -#endif - c = -1; - d = '\0'; - for (;; i--) { - d = c; - c = edit_get_byte (edit, i); - for (j = 0; p[j] != '\003'; j++) - if (c == p[j]) - goto found_char2; - break; - found_char2: - j = c; /* dummy command */ - } - i++; - p--; - if (*(p - 1) == d) - i++; - break; -#if 0 - case '\004': - while (*(--p) != '\004'); - d = *p; - p++; - c = edit_get_byte (edit, i--); - for (j = 0; p[j] != '\004'; j++) - if (c == p[j]) - return 0; - for (;; i--) { - c = edit_get_byte (edit, i); - for (j = 0; p[j] != '\004'; j++) - if (c == p[j] || c == '\n' || c == d) - goto found_char4; - continue; - found_char4: - break; - } - i++; - p--; - break; -#endif - default: - if (*p != edit_get_byte (edit, i)) - return 0; - } - } - c = edit_get_byte (edit, i); - if (line_start) - if (c != '\n') - return 0; - if (whole_left) - if (strchr (whole_left, c)) - return 0; - return 1; + repeat: + XXX XXX XXX XXX XXX XXX XXX XXX; + XXX XXX XXX XXX XXX XXX XXX XXX; + goto repeat; + done: + return (char *) s; } - -#if 0 -#define debug_printf(x,y) fprintf(stderr,x,y) -#else -#define debug_printf(x,y) -#endif - -static inline unsigned long apply_rules_going_right (WEdit * edit, long i, unsigned long rule) +static inline struct syntax_rule apply_rules_going_right (WEdit * edit, long i, struct syntax_rule rule) { struct context_rule *r; - int context, contextchanged = 0, keyword, c1, c2; - int found_right = 0, found_left = 0, keyword_foundleft = 0; - int done = 0; - unsigned long border; - context = (rule & RULE_CONTEXT) >> RULE_CONTEXT_SHIFT; - keyword = (rule & RULE_WORD) >> RULE_WORD_SHIFT; - border = rule & (RULE_ON_LEFT_BORDER | RULE_ON_RIGHT_BORDER); - c1 = edit_get_byte (edit, i - 1); - c2 = edit_get_byte (edit, i); - if (!c2 || !c1) + int contextchanged = 0, c; + int found_right = 0, found_left = 0, keyword_foundleft = 0, keyword_foundright = 0; + int is_end; + long end = 0; + struct syntax_rule _rule = rule; + if (!(c = edit_get_byte (edit, i))) return rule; - - debug_printf ("%c->", c1); - debug_printf ("%c ", c2); - + is_end = (rule.end == (unsigned char) i); /* check to turn off a keyword */ - if (keyword) { + if (_rule.keyword) { struct key_word *k; - k = edit->rules[context]->keyword[keyword]; - if (c1 == '\n') - keyword = 0; - if (k->last == c1 && compare_word_to_left (edit, i - 1, k->keyword, k->whole_word_chars_left, k->whole_word_chars_right, k->line_start)) { - keyword = 0; + k = edit->rules[_rule.context]->keyword[_rule.keyword]; + if (edit_get_byte (edit, i - 1) == '\n') + _rule.keyword = 0; + if (is_end) { + _rule.keyword = 0; keyword_foundleft = 1; - debug_printf ("keyword=%d ", keyword); } } - debug_printf ("border=%s ", border ? ((border & RULE_ON_LEFT_BORDER) ? "left" : "right") : "off"); - /* check to turn off a context */ - if (context && !keyword) { - r = edit->rules[context]; - if (r->first_right == c2 && compare_word_to_right (edit, i, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right) \ - &&!(rule & RULE_ON_RIGHT_BORDER)) { - debug_printf ("A:3 ", 0); + if (_rule.context && !_rule.keyword) { + long e; + r = edit->rules[_rule.context]; + if (r->first_right == c && !(rule.border & RULE_ON_RIGHT_BORDER) && (e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right)) > 0) { + _rule.end = e; found_right = 1; - border = RULE_ON_RIGHT_BORDER; + _rule.border = RULE_ON_RIGHT_BORDER; if (r->between_delimiters) - context = 0; - } else if (!found_left) { - if (r->last_right == c1 && compare_word_to_left (edit, i - 1, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right) \ - &&(rule & RULE_ON_RIGHT_BORDER)) { + _rule.context = 0; + } else if (is_end && rule.border & RULE_ON_RIGHT_BORDER) { /* always turn off a context at 4 */ - debug_printf ("A:4 ", 0); - found_left = 1; - border = 0; - if (!keyword_foundleft) - context = 0; - } else if (r->last_left == c1 && compare_word_to_left (edit, i - 1, r->left, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_left) \ - &&(rule & RULE_ON_LEFT_BORDER)) { + found_left = 1; + _rule.border = 0; + if (!keyword_foundleft) + _rule.context = 0; + } else if (is_end && rule.border & RULE_ON_LEFT_BORDER) { /* never turn off a context at 2 */ - debug_printf ("A:2 ", 0); - found_left = 1; - border = 0; - } + found_left = 1; + _rule.border = 0; } } - debug_printf ("\n", 0); - /* check to turn on a keyword */ - if (!keyword) { + if (!_rule.keyword) { char *p; - p = (r = edit->rules[context])->keyword_first_chars; - while ((p = strchr (p + 1, c2))) { + p = (r = edit->rules[_rule.context])->keyword_first_chars; + while (*(p = xx_strchr ((unsigned char *) p + 1, c))) { struct key_word *k; int count; + long e; count = (unsigned long) p - (unsigned long) r->keyword_first_chars; k = r->keyword[count]; - if (compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left, k->whole_word_chars_right, k->line_start)) { - keyword = count; - debug_printf ("keyword=%d ", keyword); + e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left, k->whole_word_chars_right, k->line_start); + if (e > 0) { + end = e; + _rule.end = e; + _rule.keyword = count; + keyword_foundright = 1; break; } } } /* check to turn on a context */ - if (!context) { - int count; - for (count = 1; edit->rules[count] && !done; count++) { - r = edit->rules[count]; - if (!found_left) { - if (r->last_right == c1 && compare_word_to_left (edit, i - 1, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right) \ - &&(rule & RULE_ON_RIGHT_BORDER)) { - debug_printf ("B:4 count=%d", count); - found_left = 1; - border = 0; - context = 0; + if (!_rule.context) { + if (!found_left && is_end) { + if (rule.border & RULE_ON_RIGHT_BORDER) { + _rule.border = 0; + _rule.context = 0; + contextchanged = 1; + _rule.keyword = 0; + } else if (rule.border & RULE_ON_LEFT_BORDER) { + r = edit->rules[_rule._context]; + _rule.border = 0; + if (r->between_delimiters) { + long e; + _rule.context = _rule._context; contextchanged = 1; - keyword = 0; - } else if (r->last_left == c1 && compare_word_to_left (edit, i - 1, r->left, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_left) \ - &&(rule & RULE_ON_LEFT_BORDER)) { - debug_printf ("B:2 ", 0); - found_left = 1; - border = 0; - if (r->between_delimiters) { - context = count; - contextchanged = 1; - keyword = 0; - debug_printf ("context=%d ", context); - if (r->first_right == c2 && compare_word_to_right (edit, i, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right)) { - debug_printf ("B:3 ", 0); - found_right = 1; - border = RULE_ON_RIGHT_BORDER; - context = 0; - } + _rule.keyword = 0; + if (r->first_right == c && (e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_right)) >= end) { + _rule.end = e; + found_right = 1; + _rule.border = RULE_ON_RIGHT_BORDER; + _rule.context = 0; } - break; } } - if (!found_right) { - if (r->first_left == c2 && compare_word_to_right (edit, i, r->left, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_left)) { - debug_printf ("B:1 ", 0); - found_right = 1; - border = RULE_ON_LEFT_BORDER; - if (!r->between_delimiters) { - debug_printf ("context=%d ", context); - if (!keyword) - context = count; + } + if (!found_right) { + int count; + struct context_rule **rules = edit->rules; + for (count = 1; rules[count]; count++) { + r = rules[count]; + if (r->first_left == c) { + long e; + e = compare_word_to_right (edit, i, r->left, r->whole_word_chars_left, r->whole_word_chars_right, r->line_start_left); + if (e >= end && (!_rule.keyword || keyword_foundright)) { + _rule.end = e; + found_right = 1; + _rule.border = RULE_ON_LEFT_BORDER; + _rule._context = count; + if (!r->between_delimiters) + if (!_rule.keyword) + _rule.context = count; + break; } - break; } } } } - if (!keyword && contextchanged) { +/* check again to turn on a keyword if the context switched */ + if (contextchanged && !_rule.keyword) { char *p; - p = (r = edit->rules[context])->keyword_first_chars; - while ((p = strchr (p + 1, c2))) { + p = (r = edit->rules[_rule.context])->keyword_first_chars; + while (*(p = xx_strchr ((unsigned char *) p + 1, c))) { struct key_word *k; - int coutner; - coutner = (unsigned long) p - (unsigned long) r->keyword_first_chars; - k = r->keyword[coutner]; - if (compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left, k->whole_word_chars_right, k->line_start)) { - keyword = coutner; - debug_printf ("keyword=%d ", keyword); + int count; + long e; + count = (unsigned long) p - (unsigned long) r->keyword_first_chars; + k = r->keyword[count]; + e = compare_word_to_right (edit, i, k->keyword, k->whole_word_chars_left, k->whole_word_chars_right, k->line_start); + if (e > 0) { + _rule.end = e; + _rule.keyword = count; break; } } } - debug_printf ("border=%s ", border ? ((border & RULE_ON_LEFT_BORDER) ? "left" : "right") : "off"); - debug_printf ("keyword=%d ", keyword); - - debug_printf (" %d#\n\n", context); - - return (context << RULE_CONTEXT_SHIFT) | (keyword << RULE_WORD_SHIFT) | border; + return _rule; } -static unsigned long edit_get_rule (WEdit * edit, long byte_index) +static struct syntax_rule edit_get_rule (WEdit * edit, long byte_index) { long i; - if (byte_index < 0) { - edit->last_get_rule = -1; - edit->rule = 0; - return 0; - } if (byte_index > edit->last_get_rule) { for (i = edit->last_get_rule + 1; i <= byte_index; i++) { edit->rule = apply_rules_going_right (edit, i, edit->rule); @@ -441,7 +337,7 @@ static unsigned long edit_get_rule (WEdit * edit, long byte_index) struct _syntax_marker *s; for (;;) { if (!edit->syntax_marker) { - edit->rule = 0; + memset (&edit->rule, 0, sizeof (edit->rule)); for (i = -1; i <= byte_index; i++) edit->rule = apply_rules_going_right (edit, i, edit->rule); break; @@ -461,27 +357,25 @@ static unsigned long edit_get_rule (WEdit * edit, long byte_index) return edit->rule; } -static void translate_rule_to_color (WEdit * edit, unsigned long rule, int *fg, int *bg) +static void translate_rule_to_color (WEdit * edit, struct syntax_rule rule, int *fg, int *bg) { struct key_word *k; - k = edit->rules[(rule & RULE_CONTEXT) >> RULE_CONTEXT_SHIFT]->keyword[(rule & RULE_WORD) >> RULE_WORD_SHIFT]; + k = edit->rules[rule.context]->keyword[rule.keyword]; *bg = k->bg; *fg = k->fg; } void edit_get_syntax_color (WEdit * edit, long byte_index, int *fg, int *bg) { - unsigned long rule; - if (!edit->rules || byte_index >= edit->last_byte || !option_syntax_highlighting) { + if (edit->rules && byte_index < edit->last_byte && option_syntax_highlighting) { + translate_rule_to_color (edit, edit_get_rule (edit, byte_index), fg, bg); + } else { #ifdef MIDNIGHT *fg = EDITOR_NORMAL_COLOR; #else *fg = NO_COLOR; *bg = NO_COLOR; #endif - } else { - rule = edit_get_rule (edit, byte_index); - translate_rule_to_color (edit, rule, fg, bg); } } @@ -498,6 +392,8 @@ static int read_one_line (char **line, FILE * f) for (;;) { c = fgetc (f); if (c == -1) { + if (errno == EINTR) + continue; r = 0; break; } else if (c == '\n') { @@ -522,11 +418,8 @@ static int read_one_line (char **line, FILE * f) static char *strdup_convert (char *s) { -#if 0 - int e = 0; -#endif char *r, *p; - p = r = strdup (s); + p = r = (char *) strdup (s); while (*s) { switch (*s) { case '\\': @@ -556,25 +449,11 @@ static char *strdup_convert (char *s) break; case '[': case ']': - if ((unsigned long) p == (unsigned long) r || strlen (s) == 1) - *p = *s; - else { -#if 0 - if (!strncmp (s, "[^", 2)) { - *p = '\004'; - e = 1; - s++; - } else { - if (e) - *p = '\004'; - else -#endif - *p = '\003'; -#if 0 - e = 0; - } -#endif - } + *p = '\003'; + break; + case '{': + case '}': + *p = '\004'; break; default: *p = *s; @@ -582,17 +461,10 @@ static char *strdup_convert (char *s) } break; case '*': -/* a * or + at the beginning or end of the line must be interpreted literally */ - if ((unsigned long) p == (unsigned long) r || strlen (s) == 1) - *p = '*'; - else - *p = '\001'; + *p = '\001'; break; case '+': - if ((unsigned long) p == (unsigned long) r || strlen (s) == 1) - *p = '+'; - else - *p = '\002'; + *p = '\002'; break; default: *p = *s; @@ -601,7 +473,7 @@ static char *strdup_convert (char *s) s++; p++; } - *p = 0; + *p = '\0'; return r; } @@ -707,21 +579,21 @@ static FILE *open_include_file (char *filename) FILE *f; char p[MAX_PATH_LEN]; syntax_free (error_file_name); - error_file_name = strdup (filename); + error_file_name = (char *) strdup (filename); if (*filename == '/') return fopen (filename, "r"); strcpy (p, home_dir); strcat (p, EDIT_DIR "/"); strcat (p, filename); syntax_free (error_file_name); - error_file_name = strdup (p); + error_file_name = (char *) strdup (p); f = fopen (p, "r"); if (f) return f; strcpy (p, LIBDIR "/syntax/"); strcat (p, filename); syntax_free (error_file_name); - error_file_name = strdup (p); + error_file_name = (char *) strdup (p); return fopen (p, "r"); } @@ -735,7 +607,7 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) char whole_left[512]; char *args[1024], *l = 0; int save_line = 0, line = 0; - struct context_rule **r, *c; + struct context_rule **r, *c = 0; int num_words = -1, num_contexts = -1; int argc, result = 0; int i, j; @@ -745,7 +617,7 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) strcpy (whole_left, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); - r = edit->rules = syntax_malloc (256 * sizeof (struct context_rule *)); + r = edit->rules = syntax_malloc (MAX_CONTEXTS * sizeof (struct context_rule *)); for (;;) { char **a; @@ -807,8 +679,8 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) } a++; c = r[0] = syntax_malloc (sizeof (struct context_rule)); - c->left = strdup (" "); - c->right = strdup (" "); + c->left = (char *) strdup (" "); + c->right = (char *) strdup (" "); num_contexts = 0; } else { c = r[num_contexts] = syntax_malloc (sizeof (struct context_rule)); @@ -819,14 +691,14 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) check_a; if (!strcmp (*a, "whole")) { a++; - c->whole_word_chars_left = strdup (whole_left); - c->whole_word_chars_right = strdup (whole_right); + c->whole_word_chars_left = (char *) strdup (whole_left); + c->whole_word_chars_right = (char *) strdup (whole_right); } else if (!strcmp (*a, "wholeleft")) { a++; - c->whole_word_chars_left = strdup (whole_left); + c->whole_word_chars_left = (char *) strdup (whole_left); } else if (!strcmp (*a, "wholeright")) { a++; - c->whole_word_chars_right = strdup (whole_right); + c->whole_word_chars_right = (char *) strdup (whole_right); } check_a; if (!strcmp (*a, "linestart")) { @@ -834,21 +706,22 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) c->line_start_left = 1; } check_a; - c->left = strdup (*a++); + c->left = (char *) strdup (*a++); check_a; if (!strcmp (*a, "linestart")) { a++; c->line_start_right = 1; } check_a; - c->right = strdup (*a++); - c->last_left = c->left[strlen (c->left) - 1]; - c->last_right = c->right[strlen (c->right) - 1]; + c->right = (char *) strdup (*a++); c->first_left = *c->left; c->first_right = *c->right; c->single_char = (strlen (c->right) == 1); } - c->keyword = syntax_malloc (1024 * sizeof (struct key_word *)); + c->keyword = syntax_malloc (MAX_WORDS_PER_CONTEXT * sizeof (struct key_word *)); +#if 0 + c->max_words = MAX_WORDS_PER_CONTEXT; +#endif num_words = 1; c->keyword[0] = syntax_malloc (sizeof (struct key_word)); fg = *a; @@ -865,9 +738,15 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) c->keyword[0]->fg = this_allocate_color (edit, fg); c->keyword[0]->bg = this_allocate_color (edit, bg); #endif - c->keyword[0]->keyword = strdup (" "); + c->keyword[0]->keyword = (char *) strdup (" "); check_not_a; num_contexts++; + } else if (!strcmp (args[0], "spellcheck")) { + if (!c) { + result = line; + break; + } + c->spelling = 1; } else if (!strcmp (args[0], "keyword")) { struct key_word *k; if (num_words == -1) @@ -876,14 +755,14 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) k = r[num_contexts - 1]->keyword[num_words] = syntax_malloc (sizeof (struct key_word)); if (!strcmp (*a, "whole")) { a++; - k->whole_word_chars_left = strdup (whole_left); - k->whole_word_chars_right = strdup (whole_right); + k->whole_word_chars_left = (char *) strdup (whole_left); + k->whole_word_chars_right = (char *) strdup (whole_right); } else if (!strcmp (*a, "wholeleft")) { a++; - k->whole_word_chars_left = strdup (whole_left); + k->whole_word_chars_left = (char *) strdup (whole_left); } else if (!strcmp (*a, "wholeright")) { a++; - k->whole_word_chars_right = strdup (whole_right); + k->whole_word_chars_right = (char *) strdup (whole_right); } check_a; if (!strcmp (*a, "linestart")) { @@ -895,8 +774,7 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) *a = 0; check_a; } - k->keyword = strdup (*a++); - k->last = k->keyword[strlen (k->keyword) - 1]; + k->keyword = (char *) strdup (*a++); k->first = *k->keyword; fg = *a; if (*a) @@ -930,6 +808,9 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) free_args (args); syntax_free (l); + if (!edit->rules[0]) + syntax_free (edit->rules); + if (result) return result; @@ -939,28 +820,281 @@ static int edit_read_syntax_rules (WEdit * edit, FILE * f) } { - char first_chars[1024], *p; - char last_chars[1024], *q; + char first_chars[MAX_WORDS_PER_CONTEXT + 2], *p; for (i = 0; edit->rules[i]; i++) { c = edit->rules[i]; p = first_chars; - q = last_chars; *p++ = (char) 1; - *q++ = (char) 1; - for (j = 1; c->keyword[j]; j++) { + for (j = 1; c->keyword[j]; j++) *p++ = c->keyword[j]->first; - *q++ = c->keyword[j]->last; - } *p = '\0'; - *q = '\0'; - c->keyword_first_chars = strdup (first_chars); - c->keyword_last_chars = strdup (last_chars); + c->keyword_first_chars = malloc (strlen (first_chars) + 2); + strcpy (c->keyword_first_chars, first_chars); } } return result; } +#if !defined (GTK) && !defined (MIDNIGHT) + +/* strdup and append c */ +static char *strdupc (char *s, int c) +{ + char *t; + int l; + strcpy (t = malloc ((l = strlen (s)) + 3), s); + t[l] = c; + t[l + 1] = '\0'; + return t; +} + +static void edit_syntax_clear_keyword (WEdit * edit, int context, int j) +{ + struct context_rule *c; + struct _syntax_marker *s; + c = edit->rules[context]; +/* first we clear any instances of this keyword in our cache chain (we used to just clear the cache chain, but this slows things down) */ + for (s = edit->syntax_marker; s; s = s->next) + if (s->rule.keyword == j) + s->rule.keyword = 0; + else if (s->rule.keyword > j) + s->rule.keyword--; + free (c->keyword[j]->keyword); + free (c->keyword[j]->whole_word_chars_left); + free (c->keyword[j]->whole_word_chars_right); + free (c->keyword[j]); + memcpy (&c->keyword[j], &c->keyword[j + 1], (MAX_WORDS_PER_CONTEXT - j) * sizeof (struct keyword *)); + strcpy (&c->keyword_first_chars[j], &c->keyword_first_chars[j + 1]); +} + + +FILE *spelling_pipe_in = 0; +FILE *spelling_pipe_out = 0; +pid_t ispell_pid = 0; + + +/* adds a keyword for underlining into the keyword list for this context, returns 1 if too many words */ +static int edit_syntax_add_keyword (WEdit * edit, char *keyword, int context, time_t t) +{ + int j; + char *s; + struct context_rule *c; + c = edit->rules[context]; + for (j = 1; c->keyword[j]; j++) { +/* if a keyword has been around for more than TRANSIENT_WORD_TIME_OUT + seconds, then remove it - we don't want to run out of space or makes syntax highlighting to slow */ + if (c->keyword[j]->time) { + if (c->keyword[j]->time + TRANSIENT_WORD_TIME_OUT < t) { + edit->force |= REDRAW_PAGE; + edit_syntax_clear_keyword (edit, context, j); + j--; + } + } + } +/* are we out of space? */ + if (j >= MAX_WORDS_PER_CONTEXT - 1) + return 1; +/* add the new keyword and date it */ + c->keyword[j + 1] = 0; + c->keyword[j] = syntax_malloc (sizeof (struct key_word)); +#ifdef MIDNIGHT + c->keyword[j]->fg = SPELLING_ERROR; +#else + c->keyword[j]->fg = c->keyword[0]->fg; + c->keyword[j]->bg = SPELLING_ERROR; +#endif + c->keyword[j]->keyword = (char *) strdup (keyword); + c->keyword[j]->first = *c->keyword[j]->keyword; + c->keyword[j]->whole_word_chars_left = (char *) strdup ("-'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ¡¢£¤¥¦§§¨©©ª«¬­®®¯°±²³´µ¶¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"); + c->keyword[j]->whole_word_chars_right = (char *) strdup ("-'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ¡¢£¤¥¦§§¨©©ª«¬­®®¯°±²³´µ¶¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"); + c->keyword[j]->time = t; + s = strdupc (c->keyword_first_chars, c->keyword[j]->first); + free (c->keyword_first_chars); + c->keyword_first_chars = s; + return 0; +} + +/* checks spelling of the word at offset */ +static int edit_check_spelling_at (WEdit * edit, long byte_index) +{ + int context; + long p1, p2; + unsigned char *p, *q; + int r, c1, c2, j; + int ch; + time_t t; + struct context_rule *c; +/* sanity check */ + if (!edit->rules || byte_index > edit->last_byte) + return 0; +/* in what context are we */ + context = edit_get_rule (edit, byte_index).context; + c = edit->rules[context]; +/* does this context have `spellcheck' */ + if (!edit->rules[context]->spelling) + return 0; +/* find word start */ + for (p1 = byte_index - 1;; p1--) { + ch = edit_get_byte (edit, p1); + if (isalpha (ch) || ch == '-' || ch == '\'') + continue; + break; + } + p1++; +/* find word end */ + for (p2 = byte_index;; p2++) { + ch = edit_get_byte (edit, p2); + if (isalpha (ch) || ch == '-' || ch == '\'') + continue; + break; + } + if (p2 <= p1) + return 0; +/* create string */ + q = p = malloc (p2 - p1 + 2); + for (; p1 < p2; p1++) + *p++ = edit_get_byte (edit, p1); + *p = '\0'; + if (q[0] == '-' || strlen ((char *) q) > 40) { /* if you are using words over 40 characters, you are on your own */ + free (q); + return 0; + } + time (&t); + for (j = 1; c->keyword[j]; j++) { +/* if the keyword is present, then update its time only. if it is a fixed keyword from the rules file, then just return */ + if (!strcmp (c->keyword[j]->keyword, (char *) q)) { + if (c->keyword[j]->time) + c->keyword[j]->time = t; + free (q); + return 0; + } + } +/* feed it to ispell */ + fprintf (spelling_pipe_out, "%s\n", (char *) q); + fflush (spelling_pipe_out); +/* what does ispell say? */ + do { + r = fgetc (spelling_pipe_in); + } while (r == -1 && errno == EINTR); + if (r == -1) { + free (q); + return 1; + } + if (r == '\n') { /* ispell sometimes returns just blank line if it is given bad characters */ + free (q); + return 0; + } +/* now read ispell output untill we get two blanks lines - we are not intersted in this part */ + do { + c1 = fgetc (spelling_pipe_in); + } while (c1 == -1 && errno == EINTR); + for (;;) { + if (c1 == -1) { + free (q); + return 1; + } + do { + c2 = fgetc (spelling_pipe_in); + } while (c2 == -1 && errno == EINTR); + if (c1 == '\n' && c2 == '\n') + break; + c1 = c2; + } +/* spelled ok */ + if (r == '*' || r == '+' || r == '-') { + free (q); + return 0; + } +/* not spelled ok - so add a syntax keyword for this word */ + edit_syntax_add_keyword (edit, (char *) q, context, t); + free (q); + return 0; +} + +char *option_alternate_dictionary = ""; + +int edit_check_spelling (WEdit * edit) +{ + if (!option_auto_spellcheck) + return 0; +/* magic arg to close up shop */ + if (!edit) { + option_auto_spellcheck = 0; + goto close_spelling; + } +/* do we at least have a syntax rule struct to put new wrongly spelled keyword in for highlighting? */ + if (!edit->rules && !edit->explicit_syntax) + edit_load_syntax (edit, 0, UNKNOWN_FORMAT); + if (!edit->rules) { + option_auto_spellcheck = 0; + return 0; + } +/* is ispell running? */ + if (!spelling_pipe_in) { + int in, out, a = 0; + char *arg[10]; + arg[a++] = "ispell"; + arg[a++] = "-a"; + if (option_alternate_dictionary) + if (*option_alternate_dictionary) { + arg[a++] = "-d"; + arg[a++] = option_alternate_dictionary; + } + arg[a++] = "-a"; + arg[a++] = 0; +/* start ispell process */ + ispell_pid = triple_pipe_open (&in, &out, 0, 1, arg[0], arg); + if (ispell_pid < 1) { + option_auto_spellcheck = 0; +#if 0 + CErrorDialog (0, 0, 0, _ (" Spelling Message "), "%s", _ (" Fail trying to open ispell program. \n Check that it is in your path and works with the -a option. \n Alternatively, disable spell checking from the Options menu. ")); +#endif + return 1; + } +/* prepare pipes */ + spelling_pipe_in = (FILE *) fdopen (out, "r"); + spelling_pipe_out = (FILE *) fdopen (in, "w"); + if (!spelling_pipe_in || !spelling_pipe_out) { + option_auto_spellcheck = 0; + CErrorDialog (0, 0, 0, _ (" Spelling Message "), "%s", _ (" Fail trying to open ispell pipes. \n Check that it is in your path and works with the -a option. \n Alternatively, disable spell checking from the Options menu. ")); + return 1; + } +/* read the banner message */ + for (;;) { + int c1; + c1 = fgetc (spelling_pipe_in); + if (c1 == -1 && errno != EINTR) { + option_auto_spellcheck = 0; + CErrorDialog (0, 0, 0, _ (" Spelling Message "), "%s", _ (" Fail trying to read ispell pipes. \n Check that it is in your path and works with the -a option. \n Alternatively, disable spell checking from the Options menu. ")); + return 1; + } + if (c1 == '\n') + break; + } + } +/* spellcheck the word under the cursor */ + if (edit_check_spelling_at (edit, edit->curs1)) { + CMessageDialog (0, 0, 0, 0, _ (" Spelling Message "), "%s", _ (" Error reading from ispell. \n Ispell is being restarted. ")); + close_spelling: + fclose (spelling_pipe_in); + spelling_pipe_in = 0; + fclose (spelling_pipe_out); + spelling_pipe_out = 0; + kill (ispell_pid, SIGKILL); + } + return 0; +} + +#else /* ! GTK && ! MIDNIGHT*/ + +int edit_check_spelling (WEdit * edit) +{ + return 0; +} + +#endif + void (*syntax_change_callback) (CWidget *) = 0; void edit_set_syntax_change_callback (void (*callback) (CWidget *)) @@ -975,6 +1109,7 @@ void edit_free_syntax_rules (WEdit * edit) return; if (!edit->rules) return; + edit_get_rule (edit, -1); syntax_free (edit->syntax_type); edit->syntax_type = 0; if (syntax_change_callback) @@ -998,7 +1133,6 @@ void edit_free_syntax_rules (WEdit * edit) syntax_free (edit->rules[i]->whole_word_chars_right); syntax_free (edit->rules[i]->keyword); syntax_free (edit->rules[i]->keyword_first_chars); - syntax_free (edit->rules[i]->keyword_last_chars); syntax_free (edit->rules[i]); } for (;;) { @@ -1012,7 +1146,7 @@ void edit_free_syntax_rules (WEdit * edit) syntax_free (edit->rules); } -#define CURRENT_SYNTAX_RULES_VERSION "48" +#define CURRENT_SYNTAX_RULES_VERSION "61" char *syntax_text[] = { "# syntax rules version " CURRENT_SYNTAX_RULES_VERSION, @@ -1053,13 +1187,13 @@ char *syntax_text[] = { "file ..\\*\\\\.lsm$ LSM\\sFile", "include lsm.syntax", "", -"file ..\\*\\\\.sh$ Shell\\sScript ^#!\\s\\*/.\\*/(ksh|bash|sh|pdkzsh)$", +"file ..\\*\\\\.sh$ Shell\\sScript ^#!\\s\\*/.\\*/(ksh|bash|sh|pdkzsh)", "include sh.syntax", "", -"file ..\\*\\\\.(pl|PL])$ Perl\\sProgram ^#!\\s\\*/.\\*/perl$", +"file ..\\*\\\\.(pl|PL])$ Perl\\sProgram ^#!\\s\\*/.\\*/perl", "include perl.syntax", "", -"file ..\\*\\\\.(py|PY])$ Python\\sProgram ^#!\\s\\*/.\\*/python$", +"file ..\\*\\\\.(py|PY])$ Python\\sProgram ^#!\\s\\*/.\\*/python", "include python.syntax", "", "file ..\\*\\\\.(man|[0-9n]|[0-9]x)$ NROFF\\sSource", @@ -1068,15 +1202,24 @@ char *syntax_text[] = { "file ..\\*\\\\.(htm|html|HTM|HTML)$ HTML\\sFile", "include html.syntax", "", -"file ..\\*\\\\.(pp|PP|pas|PAS)$ Pascal Program", +"file ..\\*\\\\.(pp|PP|pas|PAS)$ Pascal\\sProgram", "include pascal.syntax", "", +"file ..\\*\\\\.(ada|adb|ADA|ADB)$ Ada\\sProgram", +"include ada95.syntax", +"", "file ..\\*\\\\.tex$ LaTeX\\s2.09\\sDocument", "include latex.syntax", "", +"file ..\\*\\.(texi|texinfo|TEXI|TEXINFO)$ Texinfo\\sDocument", +"include texinfo.syntax", +"", "file ..\\*\\\\.([chC]|CC|cxx|cc|cpp|CPP|CXX)$ C/C\\+\\+\\sProgram", "include c.syntax", "", +"file ..\\*\\\\.i$ SWIG\\sSource", +"include swig.syntax", +"", "file ..\\*\\\\.(java|JAVA|Java|jav)$ Java\\sProgram", "include java.syntax", "", @@ -1092,9 +1235,13 @@ char *syntax_text[] = { "file .\\*Makefile[\\\\\\.a-z]\\*$ Makefile", "include makefile.syntax", "", +"file Don_t_match_me Mail\\sfolder ^From\\s", +"include mail.syntax", +"", "file .\\*syntax$ Syntax\\sHighlighting\\sdefinitions", "", "context default", +" keyword whole spellch\\eck yellow/24", " keyword whole keyw\\ord yellow/24", " keyword whole whole\\[\\t\\s\\]l\\inestart brightcyan/17", " keyword whole whole\\[\\t\\s\\]l\\inestart brightcyan/17", @@ -1165,12 +1312,16 @@ char *syntax_text[] = { "", "context linestart # \\n brown/22", "", +"file .\\* " UNKNOWN_FORMAT, +"include unknown.syntax", +"", 0}; FILE *upgrade_syntax_file (char *syntax_file) { FILE *f; + char *p; char line[80]; f = fopen (syntax_file, "r"); if (!f) { @@ -1185,31 +1336,26 @@ FILE *upgrade_syntax_file (char *syntax_file) } memset (line, 0, 79); fread (line, 80, 1, f); - if (!strstr (line, "syntax rules version")) { + if (!strstr (line, "syntax rules version")) goto rename_rule_file; - } else { - char *p; - p = strstr (line, "version") + strlen ("version") + 1; - if (atoi (p) < atoi (CURRENT_SYNTAX_RULES_VERSION)) { - char s[1024]; - rename_rule_file: - strcpy (s, syntax_file); - strcat (s, ".OLD"); - unlink (s); - rename (syntax_file, s); - unlink (syntax_file); /* might rename() fail ? */ + p = strstr (line, "version") + strlen ("version") + 1; + if (atoi (p) < atoi (CURRENT_SYNTAX_RULES_VERSION)) { + char s[1024]; + rename_rule_file: + strcpy (s, syntax_file); + strcat (s, ".OLD"); + unlink (s); + rename (syntax_file, s); + unlink (syntax_file); /* might rename() fail ? */ #if defined(MIDNIGHT) || defined(GTK) - edit_message_dialog (" Load Syntax Rules ", " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. "); + edit_message_dialog (" Load Syntax Rules ", " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. "); #else - CMessageDialog (0, 20, 20, 0, " Load Syntax Rules ", " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. "); + CMessageDialog (0, 20, 20, 0, " Load Syntax Rules ", " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. "); #endif - return upgrade_syntax_file (syntax_file); - } else { - rewind (f); - return (f); - } + return upgrade_syntax_file (syntax_file); } - return 0; /* not reached */ + rewind (f); + return f; } /* returns -1 on file error, line number on error in file syntax */ @@ -1249,7 +1395,7 @@ static int edit_read_syntax_file (WEdit * edit, char **names, char *syntax_file, break; } if (names) { - names[count++] = strdup (args[2]); + names[count++] = (char *) strdup (args[2]); names[count] = 0; } else if (type) { if (!strcmp (type, args[2])) @@ -1266,17 +1412,19 @@ static int edit_read_syntax_file (WEdit * edit, char **names, char *syntax_file, result = line_error; } else { syntax_free (edit->syntax_type); - edit->syntax_type = strdup (args[2]); + edit->syntax_type = (char *) strdup (args[2]); +/* if there are no rules then turn off syntax highlighting for speed */ + if (!edit->rules[1]) + if (!edit->rules[0]->keyword[1] && !edit->rules[0]->spelling) { + edit_free_syntax_rules (edit); + break; + } if (syntax_change_callback) #ifdef MIDNIGHT (*syntax_change_callback) (&edit->widget); #else (*syntax_change_callback) (edit->widget); #endif -/* if there are no rules then turn off syntax highlighting for speed */ - if (!edit->rules[1]) - if (!edit->rules[0]->keyword[1]) - edit_free_syntax_rules (edit); } break; } diff --git a/gtkedit/wordproc.c b/gtkedit/wordproc.c index edca1af8a..ed438df3e 100644 --- a/gtkedit/wordproc.c +++ b/gtkedit/wordproc.c @@ -20,6 +20,9 @@ #include #include "edit.h" +#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK) +#include "mad.h" +#endif #ifdef MIDNIGHT #define tab_width option_tab_spacing @@ -107,7 +110,11 @@ static long end_paragraph (WEdit * edit, long p, int force) static char *get_paragraph (WEdit * edit, long p, long q, int indent, int *size) { char *s, *t; +#if 0 t = malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + 10); +#else + t = malloc (2 * (q - p) + 100); +#endif if (!t) return 0; for (s = t; p < q; p++, s++) {