@@ -2823,24 +2823,25 @@ static char *block_def2str(struct block_def *bd)
2823
2823
return ret ;
2824
2824
}
2825
2825
2826
- /// "getregion()" function
2827
- static void f_getregion (typval_T * argvars , typval_T * rettv , EvalFuncData fptr )
2826
+ static int getregionpos (typval_T * argvars , typval_T * rettv , pos_T * p1 , pos_T * p2 ,
2827
+ bool * const inclusive , MotionType * region_type , oparg_T * oa ,
2828
+ int * const fnum )
2829
+ FUNC_ATTR_NONNULL_ALL
2828
2830
{
2829
2831
tv_list_alloc_ret (rettv , kListLenMayKnow );
2830
2832
2831
2833
if (tv_check_for_list_arg (argvars , 0 ) == FAIL
2832
2834
|| tv_check_for_list_arg (argvars , 1 ) == FAIL
2833
2835
|| tv_check_for_opt_dict_arg (argvars , 2 ) == FAIL ) {
2834
- return ;
2836
+ return FAIL ;
2835
2837
}
2836
2838
2837
2839
int fnum1 = -1 ;
2838
2840
int fnum2 = -1 ;
2839
- pos_T p1 , p2 ;
2840
- if (list2fpos (& argvars [0 ], & p1 , & fnum1 , NULL , false) != OK
2841
- || list2fpos (& argvars [1 ], & p2 , & fnum2 , NULL , false) != OK
2841
+ if (list2fpos (& argvars [0 ], p1 , & fnum1 , NULL , false) != OK
2842
+ || list2fpos (& argvars [1 ], p2 , & fnum2 , NULL , false) != OK
2842
2843
|| fnum1 != fnum2 ) {
2843
- return ;
2844
+ return FAIL ;
2844
2845
}
2845
2846
2846
2847
bool is_select_exclusive ;
@@ -2858,108 +2859,123 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
2858
2859
type = default_type ;
2859
2860
}
2860
2861
2861
- MotionType region_type = kMTUnknown ;
2862
2862
if (type [0 ] == 'v' && type [1 ] == NUL ) {
2863
- region_type = kMTCharWise ;
2863
+ * region_type = kMTCharWise ;
2864
2864
} else if (type [0 ] == 'V' && type [1 ] == NUL ) {
2865
- region_type = kMTLineWise ;
2865
+ * region_type = kMTLineWise ;
2866
2866
} else if (type [0 ] == Ctrl_V && type [1 ] == NUL ) {
2867
- region_type = kMTBlockWise ;
2867
+ * region_type = kMTBlockWise ;
2868
2868
} else {
2869
2869
semsg (_ (e_invargNval ), "type" , type );
2870
- return ;
2870
+ return FAIL ;
2871
2871
}
2872
2872
2873
2873
buf_T * findbuf = fnum1 != 0 ? buflist_findnr (fnum1 ) : curbuf ;
2874
+ * fnum = fnum1 != 0 ? fnum1 : curbuf -> b_fnum ;
2874
2875
if (findbuf == NULL || findbuf -> b_ml .ml_mfp == NULL ) {
2875
2876
emsg (_ (e_buffer_is_not_loaded ));
2876
- return ;
2877
+ return FAIL ;
2877
2878
}
2878
2879
2879
- if (p1 . lnum < 1 || p1 . lnum > findbuf -> b_ml .ml_line_count ) {
2880
- semsg (_ (e_invalid_line_number_nr ), p1 . lnum );
2881
- return ;
2880
+ if (p1 -> lnum < 1 || p1 -> lnum > findbuf -> b_ml .ml_line_count ) {
2881
+ semsg (_ (e_invalid_line_number_nr ), p1 -> lnum );
2882
+ return FAIL ;
2882
2883
}
2883
- if (p1 . col == MAXCOL ) {
2884
- p1 . col = ml_get_buf_len (findbuf , p1 . lnum ) + 1 ;
2885
- } else if (p1 . col < 1 || p1 . col > ml_get_buf_len (findbuf , p1 . lnum ) + 1 ) {
2886
- semsg (_ (e_invalid_column_number_nr ), p1 . col );
2887
- return ;
2884
+ if (p1 -> col == MAXCOL ) {
2885
+ p1 -> col = ml_get_buf_len (findbuf , p1 -> lnum ) + 1 ;
2886
+ } else if (p1 -> col < 1 || p1 -> col > ml_get_buf_len (findbuf , p1 -> lnum ) + 1 ) {
2887
+ semsg (_ (e_invalid_column_number_nr ), p1 -> col );
2888
+ return FAIL ;
2888
2889
}
2889
2890
2890
- if (p2 . lnum < 1 || p2 . lnum > findbuf -> b_ml .ml_line_count ) {
2891
- semsg (_ (e_invalid_line_number_nr ), p2 . lnum );
2892
- return ;
2891
+ if (p2 -> lnum < 1 || p2 -> lnum > findbuf -> b_ml .ml_line_count ) {
2892
+ semsg (_ (e_invalid_line_number_nr ), p2 -> lnum );
2893
+ return FAIL ;
2893
2894
}
2894
- if (p2 . col == MAXCOL ) {
2895
- p2 . col = ml_get_buf_len (findbuf , p2 . lnum ) + 1 ;
2896
- } else if (p2 . col < 1 || p2 . col > ml_get_buf_len (findbuf , p2 . lnum ) + 1 ) {
2897
- semsg (_ (e_invalid_column_number_nr ), p2 . col );
2898
- return ;
2895
+ if (p2 -> col == MAXCOL ) {
2896
+ p2 -> col = ml_get_buf_len (findbuf , p2 -> lnum ) + 1 ;
2897
+ } else if (p2 -> col < 1 || p2 -> col > ml_get_buf_len (findbuf , p2 -> lnum ) + 1 ) {
2898
+ semsg (_ (e_invalid_column_number_nr ), p2 -> col );
2899
+ return FAIL ;
2899
2900
}
2900
2901
2901
- buf_T * const save_curbuf = curbuf ;
2902
2902
curbuf = findbuf ;
2903
2903
curwin -> w_buffer = curbuf ;
2904
- const TriState save_virtual = virtual_op ;
2905
2904
virtual_op = virtual_active (curwin );
2906
2905
2907
- // NOTE: Adjust is needed.
2908
- p1 . col -- ;
2909
- p2 . col -- ;
2906
+ // NOTE: Adjustment is needed.
2907
+ p1 -> col -- ;
2908
+ p2 -> col -- ;
2910
2909
2911
- if (!lt (p1 , p2 )) {
2910
+ if (!lt (* p1 , * p2 )) {
2912
2911
// swap position
2913
- pos_T p = p1 ;
2914
- p1 = p2 ;
2915
- p2 = p ;
2912
+ pos_T p = * p1 ;
2913
+ * p1 = * p2 ;
2914
+ * p2 = p ;
2916
2915
}
2917
2916
2918
- oparg_T oa ;
2919
- bool inclusive = true;
2920
-
2921
- if (region_type == kMTCharWise ) {
2917
+ if (* region_type == kMTCharWise ) {
2922
2918
// handle 'selection' == "exclusive"
2923
- if (is_select_exclusive && !equalpos (p1 , p2 )) {
2924
- if (p2 . coladd > 0 ) {
2925
- p2 . coladd -- ;
2926
- } else if (p2 . col > 0 ) {
2927
- p2 . col -- ;
2928
- mark_mb_adjustpos (curbuf , & p2 );
2929
- } else if (p2 . lnum > 1 ) {
2930
- p2 . lnum -- ;
2931
- p2 . col = ml_get_len (p2 . lnum );
2932
- if (p2 . col > 0 ) {
2933
- p2 . col -- ;
2934
- mark_mb_adjustpos (curbuf , & p2 );
2919
+ if (is_select_exclusive && !equalpos (* p1 , * p2 )) {
2920
+ if (p2 -> coladd > 0 ) {
2921
+ p2 -> coladd -- ;
2922
+ } else if (p2 -> col > 0 ) {
2923
+ p2 -> col -- ;
2924
+ mark_mb_adjustpos (curbuf , p2 );
2925
+ } else if (p2 -> lnum > 1 ) {
2926
+ p2 -> lnum -- ;
2927
+ p2 -> col = ml_get_len (p2 -> lnum );
2928
+ if (p2 -> col > 0 ) {
2929
+ p2 -> col -- ;
2930
+ mark_mb_adjustpos (curbuf , p2 );
2935
2931
}
2936
2932
}
2937
2933
}
2938
2934
// if fp2 is on NUL (empty line) inclusive becomes false
2939
- if (* ml_get_pos (& p2 ) == NUL && !virtual_op ) {
2940
- inclusive = false;
2935
+ if (* ml_get_pos (p2 ) == NUL && !virtual_op ) {
2936
+ * inclusive = false;
2941
2937
}
2942
- } else if (region_type == kMTBlockWise ) {
2938
+ } else if (* region_type == kMTBlockWise ) {
2943
2939
colnr_T sc1 , ec1 , sc2 , ec2 ;
2944
- getvvcol (curwin , & p1 , & sc1 , NULL , & ec1 );
2945
- getvvcol (curwin , & p2 , & sc2 , NULL , & ec2 );
2946
- oa . motion_type = kMTBlockWise ;
2947
- oa . inclusive = true;
2948
- oa . op_type = OP_NOP ;
2949
- oa . start = p1 ;
2950
- oa . end = p2 ;
2951
- oa . start_vcol = MIN (sc1 , sc2 );
2940
+ getvvcol (curwin , p1 , & sc1 , NULL , & ec1 );
2941
+ getvvcol (curwin , p2 , & sc2 , NULL , & ec2 );
2942
+ oa -> motion_type = kMTBlockWise ;
2943
+ oa -> inclusive = true;
2944
+ oa -> op_type = OP_NOP ;
2945
+ oa -> start = * p1 ;
2946
+ oa -> end = * p2 ;
2947
+ oa -> start_vcol = MIN (sc1 , sc2 );
2952
2948
if (is_select_exclusive && ec1 < sc2 && 0 < sc2 && ec2 > ec1 ) {
2953
- oa . end_vcol = sc2 - 1 ;
2949
+ oa -> end_vcol = sc2 - 1 ;
2954
2950
} else {
2955
- oa . end_vcol = MAX (ec1 , ec2 );
2951
+ oa -> end_vcol = MAX (ec1 , ec2 );
2956
2952
}
2957
2953
}
2958
2954
2959
2955
// Include the trailing byte of a multi-byte char.
2960
- int l = utfc_ptr2len (ml_get_pos (& p2 ));
2956
+ int l = utfc_ptr2len (ml_get_pos (p2 ));
2961
2957
if (l > 1 ) {
2962
- p2 .col += l - 1 ;
2958
+ p2 -> col += l - 1 ;
2959
+ }
2960
+
2961
+ return OK ;
2962
+ }
2963
+
2964
+ /// "getregion()" function
2965
+ static void f_getregion (typval_T * argvars , typval_T * rettv , EvalFuncData fptr )
2966
+ {
2967
+ buf_T * const save_curbuf = curbuf ;
2968
+ const TriState save_virtual = virtual_op ;
2969
+
2970
+ pos_T p1 , p2 ;
2971
+ bool inclusive = true;
2972
+ MotionType region_type = kMTUnknown ;
2973
+ oparg_T oa ;
2974
+ int fnum ;
2975
+
2976
+ if (getregionpos (argvars , rettv ,
2977
+ & p1 , & p2 , & inclusive , & region_type , & oa , & fnum ) == FAIL ) {
2978
+ return ;
2963
2979
}
2964
2980
2965
2981
for (linenr_T lnum = p1 .lnum ; lnum <= p2 .lnum ; lnum ++ ) {
@@ -2983,6 +2999,80 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
2983
2999
tv_list_append_allocated_string (rettv -> vval .v_list , akt );
2984
3000
}
2985
3001
3002
+ // getregionpos() breaks curbuf and virtual_op
3003
+ curbuf = save_curbuf ;
3004
+ curwin -> w_buffer = curbuf ;
3005
+ virtual_op = save_virtual ;
3006
+ }
3007
+
3008
+ static void add_regionpos_range (typval_T * rettv , int bufnr , int lnum1 , int col1 , int coladd1 ,
3009
+ int lnum2 , int col2 , int coladd2 )
3010
+ {
3011
+ list_T * l1 = tv_list_alloc (2 );
3012
+ tv_list_append_list (rettv -> vval .v_list , l1 );
3013
+
3014
+ list_T * l2 = tv_list_alloc (4 );
3015
+ tv_list_append_list (l1 , l2 );
3016
+
3017
+ list_T * l3 = tv_list_alloc (4 );
3018
+ tv_list_append_list (l1 , l3 );
3019
+
3020
+ buf_T * findbuf = bufnr != 0 ? buflist_findnr (bufnr ) : curbuf ;
3021
+
3022
+ int max_col1 = ml_get_buf_len (findbuf , lnum1 );
3023
+ tv_list_append_number (l2 , bufnr );
3024
+ tv_list_append_number (l2 , lnum1 );
3025
+ tv_list_append_number (l2 , col1 > max_col1 ? max_col1 : col1 );
3026
+ tv_list_append_number (l2 , coladd1 );
3027
+
3028
+ int max_col2 = ml_get_buf_len (findbuf , lnum2 );
3029
+ tv_list_append_number (l3 , bufnr );
3030
+ tv_list_append_number (l3 , lnum2 );
3031
+ tv_list_append_number (l3 , col2 > max_col2 ? max_col2 : col2 );
3032
+ tv_list_append_number (l3 , coladd2 );
3033
+ }
3034
+
3035
+ /// "getregionpos()" function
3036
+ static void f_getregionpos (typval_T * argvars , typval_T * rettv , EvalFuncData fptr )
3037
+ {
3038
+ buf_T * const save_curbuf = curbuf ;
3039
+ const TriState save_virtual = virtual_op ;
3040
+
3041
+ pos_T p1 , p2 ;
3042
+ bool inclusive = true;
3043
+ MotionType region_type = kMTUnknown ;
3044
+ oparg_T oa ;
3045
+ int fnum ;
3046
+
3047
+ if (getregionpos (argvars , rettv ,
3048
+ & p1 , & p2 , & inclusive , & region_type , & oa , & fnum ) == FAIL ) {
3049
+ return ;
3050
+ }
3051
+
3052
+ for (linenr_T lnum = p1 .lnum ; lnum <= p2 .lnum ; lnum ++ ) {
3053
+ int start_col , end_col ;
3054
+
3055
+ if (region_type == kMTLineWise ) {
3056
+ start_col = 1 ;
3057
+ end_col = MAXCOL ;
3058
+ } else if (region_type == kMTBlockWise ) {
3059
+ struct block_def bd ;
3060
+ block_prep (& oa , & bd , lnum , false);
3061
+ start_col = bd .start_vcol + 1 ;
3062
+ end_col = bd .end_vcol ;
3063
+ } else if (p1 .lnum < lnum && lnum < p2 .lnum ) {
3064
+ start_col = 1 ;
3065
+ end_col = MAXCOL ;
3066
+ } else {
3067
+ start_col = p1 .lnum == lnum ? p1 .col + 1 : 1 ;
3068
+ end_col = p2 .lnum == lnum ? p2 .col + 1 : MAXCOL ;
3069
+ }
3070
+
3071
+ add_regionpos_range (rettv , fnum , lnum , start_col ,
3072
+ p1 .coladd , lnum , end_col , p2 .coladd );
3073
+ }
3074
+
3075
+ // getregionpos() may change curbuf and virtual_op
2986
3076
curbuf = save_curbuf ;
2987
3077
curwin -> w_buffer = curbuf ;
2988
3078
virtual_op = save_virtual ;
0 commit comments