예제 #1
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static inline void
put_paragraph (WEdit * edit, unsigned char *t, off_t p, long indent, off_t size)
{
    off_t cursor;
    off_t i;
    int c = '\0';

    cursor = edit->buffer.curs1;
    if (indent != 0)
        while (strchr ("\t ", edit_buffer_get_byte (&edit->buffer, p)) != NULL)
            p++;
    for (i = 0; i < size; i++, p++)
    {
        if (i != 0 && indent != 0)
        {
            if (t[i - 1] == '\n' && c == '\n')
            {
                while (strchr ("\t ", edit_buffer_get_byte (&edit->buffer, p)) != NULL)
                    p++;
            }
            else if (t[i - 1] == '\n')
            {
                off_t curs;

                edit_cursor_move (edit, p - edit->buffer.curs1);
                curs = edit->buffer.curs1;
                edit_insert_indent (edit, indent);
                if (cursor >= curs)
                    cursor += edit->buffer.curs1 - p;
                p = edit->buffer.curs1;
            }
            else if (c == '\n')
            {
                edit_cursor_move (edit, p - edit->buffer.curs1);
                while (strchr ("\t ", edit_buffer_get_byte (&edit->buffer, p)) != NULL)
                {
                    edit_delete (edit, TRUE);
                    if (cursor > edit->buffer.curs1)
                        cursor--;
                }
                p = edit->buffer.curs1;
            }
        }

        c = edit_buffer_get_byte (&edit->buffer, p);
        if (c != t[i])
            replace_at (edit, p, t[i]);
    }
    edit_cursor_move (edit, cursor - edit->buffer.curs1);       /* restore cursor position */
}
예제 #2
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static GString *
get_paragraph (const edit_buffer_t * buf, off_t p, off_t q, gboolean indent)
{
    GString *t;

    t = g_string_sized_new (128);

    for (; p < q; p++)
    {
        if (indent && edit_buffer_get_byte (buf, p - 1) == '\n')
            while (strchr ("\t ", edit_buffer_get_byte (buf, p)) != NULL)
                p++;

        g_string_append_c (t, edit_buffer_get_byte (buf, p));
    }

    g_string_append_c (t, '\n');

    return t;
}
예제 #3
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static gboolean
bad_line_start (const edit_buffer_t * buf, off_t p)
{
    int c;

    c = edit_buffer_get_byte (buf, p);
    if (c == '.')
    {
        /* `...' is acceptable */
        return !(edit_buffer_get_byte (buf, p + 1) == '.'
                 && edit_buffer_get_byte (buf, p + 2) == '.');
    }
    if (c == '-')
    {
        /* `---' is acceptable */
        return !(edit_buffer_get_byte (buf, p + 1) == '-'
                 && edit_buffer_get_byte (buf, p + 2) == '-');
    }

    return (option_stop_format_chars != NULL && strchr (option_stop_format_chars, c) != NULL);
}
예제 #4
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static long
edit_indent_width (const WEdit * edit, off_t p)
{
    off_t q = p;

    /* move to the end of the leading whitespace of the line */
    while (strchr ("\t ", edit_buffer_get_byte (&edit->buffer, q)) != NULL
           && q < edit->buffer.size - 1)
        q++;
    /* count the number of columns of indentation */
    return (long) edit_move_forward3 (edit, p, 0, q);
}
예제 #5
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static inline long
test_indent (const WEdit * edit, off_t p, off_t q)
{
    long indent;

    indent = edit_indent_width (edit, p++);
    if (indent == 0)
        return 0;

    for (; p < q; p++)
        if (edit_buffer_get_byte (&edit->buffer, p - 1) == '\n'
            && indent != edit_indent_width (edit, p))
            return 0;
    return indent;
}
예제 #6
0
파일: wordproc.c 프로젝트: CyberShadow/mc
static off_t
line_start (const edit_buffer_t * buf, long line)
{
    off_t p;
    long l;

    l = buf->curs_line;
    p = buf->curs1;

    if (line < l)
        p = edit_buffer_move_backward (buf, p, l - line);
    else if (line > l)
        p = edit_buffer_move_forward (buf, p, line - l, 0);

    p = edit_buffer_get_bol (buf, p);
    while (strchr ("\t ", edit_buffer_get_byte (buf, p)) != NULL)
        p++;
    return p;
}
예제 #7
0
static void
apply_rules_going_right (WEdit * edit, off_t i)
{
    context_rule_t *r;
    int c;
    gboolean contextchanged = FALSE;
    gboolean found_left = FALSE, found_right = FALSE;
    gboolean keyword_foundleft = FALSE, keyword_foundright = FALSE;
    gboolean is_end;
    off_t end = 0;
    edit_syntax_rule_t _rule = edit->rule;

    c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
    if (c == 0)
        return;

    is_end = (edit->rule.end == i);

    /* check to turn off a keyword */
    if (_rule.keyword != 0)
    {
        if (edit_buffer_get_byte (&edit->buffer, i - 1) == '\n')
            _rule.keyword = 0;
        if (is_end)
        {
            _rule.keyword = 0;
            keyword_foundleft = TRUE;
        }
    }

    /* check to turn off a context */
    if (_rule.context != 0 && _rule.keyword == 0)
    {
        off_t e;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        if (r->first_right == c && (edit->rule.border & RULE_ON_RIGHT_BORDER) == 0
            && (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 = TRUE;
            _rule.border = RULE_ON_RIGHT_BORDER;
            if (r->between_delimiters)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
        {
            /* always turn off a context at 4 */
            found_left = TRUE;
            _rule.border = 0;
            if (!keyword_foundleft)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
        {
            /* never turn off a context at 2 */
            found_left = TRUE;
            _rule.border = 0;
        }
    }

    /* check to turn on a keyword */
    if (_rule.keyword == 0)
    {
        const char *p;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        p = r->keyword_first_chars;

        if (p != NULL)
            while (*(p = xx_strchr (edit, (const unsigned char *) p + 1, c)) != '\0')
            {
                syntax_keyword_t *k;
                int count;
                off_t e;

                count = p - r->keyword_first_chars;
                k = SYNTAX_KEYWORD (g_ptr_array_index (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)
                {
                    /* when both context and keyword terminate with a newline,
                       the context overflows to the next line and colorizes it incorrectly */
                    if (e > i + 1 && _rule._context != 0
                        && k->keyword[strlen (k->keyword) - 1] == '\n')
                    {
                        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule._context));
                        if (r->right != NULL && r->right[0] != '\0'
                            && r->right[strlen (r->right) - 1] == '\n')
                            e--;
                    }

                    end = e;
                    _rule.end = e;
                    _rule.keyword = count;
                    keyword_foundright = TRUE;
                    break;
                }
            }
    }

    /* check to turn on a context */
    if (_rule.context == 0)
    {
        if (!found_left && is_end)
        {
            if ((edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
            {
                _rule.border = 0;
                _rule.context = 0;
                contextchanged = TRUE;
                _rule.keyword = 0;

            }
            else if ((edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
            {
                r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule._context));
                _rule.border = 0;
                if (r->between_delimiters)
                {
                    _rule.context = _rule._context;
                    contextchanged = TRUE;
                    _rule.keyword = 0;

                    if (r->first_right == c)
                    {
                        off_t e;

                        e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                                   r->whole_word_chars_right, r->line_start_right);
                        if (e >= end)
                        {
                            _rule.end = e;
                            found_right = TRUE;
                            _rule.border = RULE_ON_RIGHT_BORDER;
                            _rule.context = 0;
                        }
                    }
                }
            }
        }

        if (!found_right)
        {
            size_t count;

            for (count = 1; count < edit->rules->len; count++)
            {
                r = CONTEXT_RULE (g_ptr_array_index (edit->rules, count));
                if (r->first_left == c)
                {
                    off_t 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 == 0 || keyword_foundright))
                    {
                        _rule.end = e;
                        found_right = TRUE;
                        _rule.border = RULE_ON_LEFT_BORDER;
                        _rule._context = count;
                        if (!r->between_delimiters && _rule.keyword == 0)
                        {
                            _rule.context = count;
                            contextchanged = TRUE;
                        }
                        break;
                    }
                }
            }
        }
    }

    /* check again to turn on a keyword if the context switched */
    if (contextchanged && _rule.keyword == 0)
    {
        const char *p;

        r = CONTEXT_RULE (g_ptr_array_index (edit->rules, _rule.context));
        p = r->keyword_first_chars;

        while (*(p = xx_strchr (edit, (const unsigned char *) p + 1, c)) != '\0')
        {
            syntax_keyword_t *k;
            int count;
            off_t e;

            count = p - r->keyword_first_chars;
            k = SYNTAX_KEYWORD (g_ptr_array_index (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;
            }
        }
    }

    edit->rule = _rule;
}
예제 #8
0
static off_t
compare_word_to_right (const WEdit * edit, off_t i, const char *text,
                       const char *whole_left, const char *whole_right, gboolean line_start)
{
    const unsigned char *p, *q;
    int c, d, j;

    if (*text == '\0')
        return -1;

    c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i - 1));
    if ((line_start && c != '\n') || (whole_left != NULL && strchr (whole_left, c) != NULL))
        return -1;

    for (p = (const unsigned char *) text, q = p + strlen ((const char *) p); p < q; p++, i++)
    {
        switch (*p)
        {
        case SYNTAX_TOKEN_STAR:
            if (++p > q)
                return -1;
            while (TRUE)
            {
                c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
                if (*p == '\0' && whole_right != NULL && strchr (whole_right, c) == NULL)
                    break;
                if (c == *p)
                    break;
                if (c == '\n')
                    return -1;
                i++;
            }
            break;
        case SYNTAX_TOKEN_PLUS:
            if (++p > q)
                return -1;
            j = 0;
            while (TRUE)
            {
                c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
                if (c == *p)
                {
                    j = i;
                    if (p[0] == text[0] && p[1] == '\0')        /* handle eg '+' and @+@ keywords properly */
                        break;
                }
                if (j != 0 && strchr ((const char *) p + 1, c) != NULL) /* c exists further down, so it will get matched later */
                    break;
                if (whiteness (c) || (whole_right != NULL && strchr (whole_right, c) == NULL))
                {
                    if (*p == '\0')
                    {
                        i--;
                        break;
                    }
                    if (j == 0)
                        return -1;
                    i = j;
                    break;
                }
                i++;
            }
            break;
        case SYNTAX_TOKEN_BRACKET:
            if (++p > q)
                return -1;
            c = -1;
            while (TRUE)
            {
                d = c;
                c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
                for (j = 0; p[j] != SYNTAX_TOKEN_BRACKET && p[j] != '\0'; j++)
                    if (c == p[j])
                        goto found_char2;
                break;
              found_char2:
                i++;
            }
            i--;
            while (*p != SYNTAX_TOKEN_BRACKET && p <= q)
                p++;
            if (p > q)
                return -1;
            if (p[1] == d)
                i--;
            break;
        case SYNTAX_TOKEN_BRACE:
            if (++p > q)
                return -1;
            c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
            for (; *p != SYNTAX_TOKEN_BRACE && *p != '\0'; p++)
                if (c == *p)
                    goto found_char3;
            return -1;
          found_char3:
            while (*p != SYNTAX_TOKEN_BRACE && p < q)
                p++;
            break;
        default:
            if (*p != xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i)))
                return -1;
        }
    }
    return (whole_right != NULL &&
            strchr (whole_right,
                    xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i))) != NULL) ? -1 : i;
}
예제 #9
0
파일: editdraw.c 프로젝트: ginggs/maemo-mc
static void
edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_col)
{
    Widget *w = WIDGET (edit);

    struct line_s line[MAX_LINE_LEN];
    struct line_s *p = line;

    off_t m1 = 0, m2 = 0, q;
    int col, start_col_real;
    int color;
    int abn_style;
    int book_mark = 0;
    char line_stat[LINE_STATE_WIDTH + 1] = "\0";

    if (row > w->lines - 1 - EDIT_TEXT_VERTICAL_OFFSET - 2 * (edit->fullscreen ? 0 : 1))
        return;

    if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_COLOR))
        book_mark = BOOK_MARK_COLOR;
    else if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_FOUND_COLOR))
        book_mark = BOOK_MARK_FOUND_COLOR;

    if (book_mark)
        abn_style = book_mark << 16;
    else
        abn_style = MOD_ABNORMAL;

    end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width;
    if (!edit->fullscreen)
    {
        end_col--;
        if (w->x + w->cols <= WIDGET (w->owner)->cols)
            end_col--;
    }

    color = edit_get_syntax_color (edit, b - 1);
    q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0);
    start_col_real = (col = (int) edit_move_forward3 (edit, b, 0, q)) + edit->start_col;

    if (option_line_state)
    {
        unsigned int cur_line;

        cur_line = edit->start_line + row;
        if (cur_line <= (unsigned int) edit->buffer.lines)
        {
            g_snprintf (line_stat, LINE_STATE_WIDTH + 1, "%7i ", cur_line + 1);
        }
        else
        {
            memset (line_stat, ' ', LINE_STATE_WIDTH);
            line_stat[LINE_STATE_WIDTH] = '\0';
        }
        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR))
        {
            g_snprintf (line_stat, 2, "*");
        }
    }

    if (col + 16 > -edit->start_col)
    {
        eval_marks (edit, &m1, &m2);

        if (row <= edit->buffer.lines - edit->start_line)
        {
            off_t tws = 0;
            if (tty_use_colors () && visible_tws)
            {
                unsigned int c;

                tws = edit_buffer_get_eol (&edit->buffer, b);
                while (tws > b
                       && ((c = edit_buffer_get_byte (&edit->buffer, tws - 1)) == ' ' || c == '\t'))
                    tws--;
            }

            while (col <= end_col - edit->start_col)
            {
                int char_length = 1;
                unsigned int c;
                gboolean wide_width_char = FALSE;
                gboolean control_char = FALSE;

                p->ch = 0;
                p->style = 0;
                if (q == edit->buffer.curs1)
                    p->style |= MOD_CURSOR;
                if (q >= m1 && q < m2)
                {
                    if (edit->column_highlight)
                    {
                        long x;
                        long c1, c2;

                        x = (long) edit_move_forward3 (edit, b, 0, q);
                        c1 = min (edit->column1, edit->column2);
                        c2 = max (edit->column1, edit->column2);
                        if (x >= c1 && x < c2)
                            p->style |= MOD_MARKED;
                    }
                    else
                        p->style |= MOD_MARKED;
                }
                if (q == edit->bracket)
                    p->style |= MOD_BOLD;
                if (q >= edit->found_start && q < (off_t) (edit->found_start + edit->found_len))
                    p->style |= MOD_BOLD;

#ifdef HAVE_CHARSET
                if (edit->utf8)
                    c = edit_buffer_get_utf (&edit->buffer, q, &char_length);
                else
#endif
                    c = edit_buffer_get_byte (&edit->buffer, q);

                /* we don't use bg for mc - fg contains both */
                if (book_mark)
                {
                    p->style |= book_mark << 16;
                }
                else
                {
                    color = edit_get_syntax_color (edit, q);
                    p->style |= color << 16;
                }
                switch (c)
                {
                case '\n':
                    col = end_col - edit->start_col + 1;        /* quit */
                    break;
                case '\t':
                    {
                        int tab_over;
                        int i;

                        i = TAB_SIZE - ((int) col % TAB_SIZE);
                        tab_over = (end_col - edit->start_col) - (col + i - 1);
                        if (tab_over < 0)
                            i += tab_over;
                        col += i;
                        if (tty_use_colors () &&
                            ((visible_tabs || (visible_tws && q >= tws)) && enable_show_tabs_tws))
                        {
                            if (p->style & MOD_MARKED)
                                c = p->style;
                            else if (book_mark)
                                c |= book_mark << 16;
                            else
                                c = p->style | MOD_WHITESPACE;
                            if (i > 2)
                            {
                                p->ch = '<';
                                p->style = c;
                                p++;
                                while (--i > 1)
                                {
                                    p->ch = '-';
                                    p->style = c;
                                    p++;
                                }
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                            else if (i > 1)
                            {
                                p->ch = '<';
                                p->style = c;
                                p++;
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                            else
                            {
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                        }
                        else if (tty_use_colors () && visible_tws && q >= tws
                                 && enable_show_tabs_tws)
                        {
                            p->ch = '.';
                            p->style |= MOD_WHITESPACE;
                            c = p->style & ~MOD_CURSOR;
                            p++;
                            while (--i)
                            {
                                p->ch = ' ';
                                p->style = c;
                                p++;
                            }
                        }
                        else
                        {
                            p->ch |= ' ';
                            c = p->style & ~MOD_CURSOR;
                            p++;
                            while (--i)
                            {
                                p->ch = ' ';
                                p->style = c;
                                p++;
                            }
                        }
                    }
                    break;
                case ' ':
                    if (tty_use_colors () && visible_tws && q >= tws && enable_show_tabs_tws)
                    {
                        p->ch = '.';
                        p->style |= MOD_WHITESPACE;
                        p++;
                        col++;
                        break;
                    }
                    /* fallthrough */
                default:
#ifdef HAVE_CHARSET
                    if (mc_global.utf8_display)
                    {
                        if (!edit->utf8)
                        {
                            c = convert_from_8bit_to_utf_c ((unsigned char) c, edit->converter);
                        }
                        else
                        {
                            if (g_unichar_iswide (c))
                            {
                                wide_width_char = TRUE;
                                col++;
                            }
                        }
                    }
                    else if (edit->utf8)
                        c = convert_from_utf_to_current_c (c, edit->converter);
                    else
                        c = convert_to_display_c (c);
#endif

                    /* Caret notation for control characters */
                    if (c < 32)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = c + 0x40;
                        p->style = abn_style;
                        p++;
                        col += 2;
                        control_char = TRUE;
                        break;
                    }
                    if (c == 127)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = '?';
                        p->style = abn_style;
                        p++;
                        col += 2;
                        control_char = TRUE;
                        break;
                    }
#ifdef HAVE_CHARSET
                    if (edit->utf8)
                    {
                        if (g_unichar_isprint (c))
                            p->ch = c;
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                        }
                        p++;
                    }
                    else
#endif
                    {
                        if ((mc_global.utf8_display && g_unichar_isprint (c)) ||
                            (!mc_global.utf8_display && is_printable (c)))
                        {
                            p->ch = c;
                            p++;
                        }
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                            p++;
                        }
                    }
                    col++;
                    break;
                }               /* case */

                q++;
                if (char_length > 1)
                    q += char_length - 1;

                if (col > (end_col - edit->start_col + 1))
                {
                    if (wide_width_char)
                    {
                        p--;
                        break;
                    }
                    if (control_char)
                    {
                        p -= 2;
                        break;
                    }
                }
            }
        }
    }
    else
    {
        start_col_real = start_col = 0;
    }

    p->ch = 0;

    print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark);
}
예제 #10
0
파일: syntax.c 프로젝트: GarothLongint/mc
static void
apply_rules_going_right (WEdit * edit, off_t i)
{
    struct context_rule *r;
    int c;
    gboolean contextchanged = FALSE;
    gboolean found_left = FALSE, found_right = FALSE;
    gboolean keyword_foundleft = FALSE, keyword_foundright = FALSE;
    gboolean is_end;
    off_t end = 0;
    edit_syntax_rule_t _rule = edit->rule;

    c = xx_tolower (edit, edit_buffer_get_byte (&edit->buffer, i));
    if (c == 0)
        return;

    is_end = (edit->rule.end == i);

    /* check to turn off a keyword */
    if (_rule.keyword != 0)
    {
        if (edit_buffer_get_byte (&edit->buffer, i - 1) == '\n')
            _rule.keyword = 0;
        if (is_end)
        {
            _rule.keyword = 0;
            keyword_foundleft = TRUE;
        }
    }

    /* check to turn off a context */
    if (_rule.context != 0 && _rule.keyword == 0)
    {
        off_t e;

        r = edit->rules[_rule.context];
        if (r->first_right == c && (edit->rule.border & RULE_ON_RIGHT_BORDER) == 0
            && (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 = TRUE;
            _rule.border = RULE_ON_RIGHT_BORDER;
            if (r->between_delimiters)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
        {
            /* always turn off a context at 4 */
            found_left = TRUE;
            _rule.border = 0;
            if (!keyword_foundleft)
                _rule.context = 0;
        }
        else if (is_end && (edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
        {
            /* never turn off a context at 2 */
            found_left = TRUE;
            _rule.border = 0;
        }
    }

    /* check to turn on a keyword */
    if (_rule.keyword == 0)
    {
        const char *p;

        r = edit->rules[_rule.context];
        p = r->keyword_first_chars;

        if (p != NULL)
            while (*(p = xx_strchr (edit, (unsigned char *) p + 1, c)) != '\0')
            {
                struct key_word *k;
                int count;
                off_t e;

                count = p - 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)
                {
                    end = e;
                    _rule.end = e;
                    _rule.keyword = count;
                    keyword_foundright = TRUE;
                    break;
                }
            }
    }

    /* check to turn on a context */
    if (_rule.context == 0)
    {
        if (!found_left && is_end)
        {
            if ((edit->rule.border & RULE_ON_RIGHT_BORDER) != 0)
            {
                _rule.border = 0;
                _rule.context = 0;
                contextchanged = TRUE;
                _rule.keyword = 0;

            }
            else if ((edit->rule.border & RULE_ON_LEFT_BORDER) != 0)
            {
                r = edit->rules[_rule._context];
                _rule.border = 0;
                if (r->between_delimiters)
                {
                    _rule.context = _rule._context;
                    contextchanged = TRUE;
                    _rule.keyword = 0;

                    if (r->first_right == c)
                    {
                        off_t e;

                        e = compare_word_to_right (edit, i, r->right, r->whole_word_chars_left,
                                                   r->whole_word_chars_right, r->line_start_right);
                        if (e >= end)
                        {
                            _rule.end = e;
                            found_right = TRUE;
                            _rule.border = RULE_ON_RIGHT_BORDER;
                            _rule.context = 0;
                        }
                    }
                }
            }
        }

        if (!found_right)
        {
            int count;
            struct context_rule **rules = edit->rules;

            for (count = 1; rules[count] != NULL; count++)
            {
                r = rules[count];
                if (r->first_left == c)
                {
                    off_t 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 == 0 || keyword_foundright))
                    {
                        _rule.end = e;
                        found_right = TRUE;
                        _rule.border = RULE_ON_LEFT_BORDER;
                        _rule._context = count;
                        if (!r->between_delimiters && _rule.keyword == 0)
                        {
                            _rule.context = count;
                            contextchanged = TRUE;
                        }
                        break;
                    }
                }
            }
        }
    }

    /* check again to turn on a keyword if the context switched */
    if (contextchanged && _rule.keyword == 0)
    {
        const char *p;

        r = edit->rules[_rule.context];
        p = r->keyword_first_chars;

        while (*(p = xx_strchr (edit, (unsigned char *) p + 1, c)) != '\0')
        {
            struct key_word *k;
            int count;
            off_t e;

            count = p - 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;
            }
        }
    }

    edit->rule = _rule;
}