comparison src/search.c @ 12:bdeee1504ac1

updated for version 7.0004
author vimboss
date Fri, 02 Jul 2004 15:38:35 +0000
parents 4102fb4ea781
children 946da5994c01
comparison
equal deleted inserted replaced
11:4424b47a0797 12:bdeee1504ac1
3601 curwin->w_cursor.lnum = end_lnum; 3601 curwin->w_cursor.lnum = end_lnum;
3602 curwin->w_cursor.col = 0; 3602 curwin->w_cursor.col = 0;
3603 3603
3604 return OK; 3604 return OK;
3605 } 3605 }
3606 #endif 3606
3607 static int find_next_quote __ARGS((char_u *top_ptr, int col, int quotechar, char_u *escape));
3608 static int find_prev_quote __ARGS((char_u *line, int col_start, int quotechar, char_u *escape));
3609
3610 /*
3611 * Search quote char from string line[col].
3612 * Quote character escaped by one of the characters in "escape" is not counted
3613 * as a quote.
3614 * Returns column number of "quotechar" or -1 when not found.
3615 */
3616 static int
3617 find_next_quote(line, col, quotechar, escape)
3618 char_u *line;
3619 int col;
3620 int quotechar;
3621 char_u *escape; /* escape characters, can be NULL */
3622 {
3623 int c;
3624
3625 while (1)
3626 {
3627 c = line[col];
3628 if (c == NUL)
3629 return -1;
3630 else if (escape != NULL && vim_strchr(escape, c))
3631 ++col;
3632 else if (c == quotechar)
3633 break;
3634 #ifdef FEAT_MBYTE
3635 if (has_mbyte)
3636 col += (*mb_ptr2len_check)(line + col);
3637 else
3638 #endif
3639 ++col;
3640 }
3641 return col;
3642 }
3643
3644 /*
3645 * Search backwards in "line" from column "col_start" to find "quotechar".
3646 * Quote character escaped by one of the characters in "escape" is not counted
3647 * as a quote.
3648 * Return the found column or zero.
3649 */
3650 static int
3651 find_prev_quote(line, col_start, quotechar, escape)
3652 char_u *line;
3653 int col_start;
3654 int quotechar;
3655 char_u *escape; /* escape characters, can be NULL */
3656 {
3657 int n;
3658
3659 while (col_start > 0)
3660 {
3661 --col_start;
3662 #ifdef FEAT_MBYTE
3663 col_start -= (*mb_head_off)(line, line + col_start);
3664 #endif
3665 n = 0;
3666 if (escape != NULL)
3667 while (col_start - n > 0 && vim_strchr(escape,
3668 line[col_start - n - 1]) != NULL)
3669 ++n;
3670 if (n & 1)
3671 col_start -= n; /* uneven number of escape chars, skip it */
3672 else if (line[col_start] == quotechar)
3673 break;
3674 }
3675 return col_start;
3676 }
3677
3678 /*
3679 * Find quote under the cursor, cursor at end.
3680 * Returns TRUE if found, else FALSE.
3681 */
3682 int
3683 current_quote(oap, count, include, quotechar)
3684 oparg_T *oap;
3685 long count;
3686 int include; /* TRUE == include quote char */
3687 int quotechar; /* Quote character */
3688 {
3689 char_u *line = ml_get_curline();
3690 int col_end;
3691 int col_start = curwin->w_cursor.col;
3692 int inclusive = FALSE;
3693 #ifdef FEAT_VISUAL
3694 int vis_empty = TRUE; /* Visual selection <= 1 char */
3695 int vis_bef_curs = FALSE; /* Visual starts before cursor */
3696
3697 /* Correct cursor when 'selection' is exclusive */
3698 if (VIsual_active)
3699 {
3700 if (*p_sel == 'e' && vis_bef_curs)
3701 dec_cursor();
3702 vis_empty = equalpos(VIsual, curwin->w_cursor);
3703 vis_bef_curs = lt(VIsual, curwin->w_cursor);
3704 }
3705 if (!vis_empty && line[col_start] == quotechar)
3706 {
3707 /* Already selecting something and on a quote character. Find the
3708 * next quoted string. */
3709 if (vis_bef_curs)
3710 {
3711 /* Assume we are on a closing quote: move to after the next
3712 * opening quote. */
3713 col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
3714 if (col_start < 0)
3715 return FALSE;
3716 col_end = find_next_quote(line, col_start + 1, quotechar,
3717 curbuf->b_p_qe);
3718 if (col_end < 0)
3719 {
3720 /* We were on a starting quote perhaps? */
3721 col_end = col_start;
3722 col_start = curwin->w_cursor.col;
3723 }
3724 }
3725 else
3726 {
3727 col_end = find_prev_quote(line, col_start, quotechar, NULL);
3728 if (line[col_end] != quotechar)
3729 return FALSE;
3730 col_start = find_prev_quote(line, col_end, quotechar,
3731 curbuf->b_p_qe);
3732 if (line[col_start] != quotechar)
3733 {
3734 /* We were on an ending quote perhaps? */
3735 col_start = col_end;
3736 col_end = curwin->w_cursor.col;
3737 }
3738 }
3739 }
3740 else
3741 #endif
3742
3743 if (line[col_start] == quotechar
3744 #ifdef FEAT_VISUAL
3745 || !vis_empty
3746 #endif
3747 )
3748 {
3749 int first_col = col_start;
3750
3751 #ifdef FEAT_VISUAL
3752 if (!vis_empty)
3753 {
3754 if (vis_bef_curs)
3755 first_col = find_next_quote(line, col_start, quotechar, NULL);
3756 else
3757 first_col = find_prev_quote(line, col_start, quotechar, NULL);
3758 }
3759 #endif
3760 /* The cursor is on a quote, we don't know if it's the opening or
3761 * closing quote. Search from the start of the line to find out.
3762 * Also do this when there is a Visual area, a' may leave the cursor
3763 * in between two strings. */
3764 col_start = 0;
3765 while (1)
3766 {
3767 /* Find open quote character. */
3768 col_start = find_next_quote(line, col_start, quotechar, NULL);
3769 if (col_start < 0 || col_start > first_col)
3770 return FALSE;
3771 /* Find close quote character. */
3772 col_end = find_next_quote(line, col_start + 1, quotechar,
3773 curbuf->b_p_qe);
3774 if (col_end < 0)
3775 return FALSE;
3776 /* If is cursor between start and end quote character, it is
3777 * target text object. */
3778 if (col_start <= first_col && first_col <= col_end)
3779 break;
3780 col_start = col_end + 1;
3781 }
3782 }
3783 else
3784 {
3785 /* Search backward for a starting quote. */
3786 col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe);
3787 if (line[col_start] != quotechar)
3788 {
3789 /* No quote before the cursor, look after the cursor. */
3790 col_start = find_next_quote(line, col_start, quotechar, NULL);
3791 if (col_start < 0)
3792 return FALSE;
3793 }
3794
3795 /* Find close quote character. */
3796 col_end = find_next_quote(line, col_start + 1, quotechar,
3797 curbuf->b_p_qe);
3798 if (col_end < 0)
3799 return FALSE;
3800 }
3801
3802 /* When "include" is TRUE, include spaces after closing quote or before
3803 * the starting quote. */
3804 if (include)
3805 {
3806 if (vim_iswhite(line[col_end + 1]))
3807 while (vim_iswhite(line[col_end + 1]))
3808 ++col_end;
3809 else
3810 while (col_start > 0 && vim_iswhite(line[col_start - 1]))
3811 --col_start;
3812 }
3813
3814 /* Set start position */
3815 if (!include)
3816 ++col_start;
3817 curwin->w_cursor.col = col_start;
3818 #ifdef FEAT_VISUAL
3819 if (VIsual_active)
3820 {
3821 if (vis_empty)
3822 {
3823 VIsual = curwin->w_cursor;
3824 redraw_curbuf_later(INVERTED);
3825 }
3826 }
3827 else
3828 #endif
3829 {
3830 oap->start = curwin->w_cursor;
3831 oap->motion_type = MCHAR;
3832 }
3833
3834 /* Set end position. */
3835 curwin->w_cursor.col = col_end;
3836 if (include && inc_cursor() == 2)
3837 inclusive = TRUE;
3838 #ifdef FEAT_VISUAL
3839 if (VIsual_active)
3840 {
3841 if (vis_empty || vis_bef_curs)
3842 {
3843 /* decrement cursor when 'selection' is not exclusive */
3844 if (*p_sel != 'e')
3845 dec_cursor();
3846 }
3847 else
3848 {
3849 /* Cursor is at start of Visual area. */
3850 curwin->w_cursor.col = col_start;
3851 }
3852 if (VIsual_mode == 'V')
3853 {
3854 VIsual_mode = 'v';
3855 redraw_cmdline = TRUE; /* show mode later */
3856 }
3857 }
3858 else
3859 #endif
3860 {
3861 /* Set inclusive and other oap's flags. */
3862 oap->inclusive = inclusive;
3863 }
3864
3865 return OK;
3866 }
3867
3868 #endif /* FEAT_TEXTOBJ */
3607 3869
3608 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \ 3870 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \
3609 || defined(PROTO) 3871 || defined(PROTO)
3610 /* 3872 /*
3611 * return TRUE if line 'lnum' is empty or has white chars only. 3873 * return TRUE if line 'lnum' is empty or has white chars only.