@@ -275,18 +275,30 @@ linelen(has_tab)
275275static char_u * sortbuf1 ;
276276static char_u * sortbuf2 ;
277277
278- static int sort_ic ; /* ignore case */
279- static int sort_nr ; /* sort on number */
280- static int sort_rx ; /* sort on regex instead of skipping it */
278+ static int sort_ic ; /* ignore case */
279+ static int sort_nr ; /* sort on number */
280+ static int sort_rx ; /* sort on regex instead of skipping it */
281+ #ifdef FEAT_FLOAT
282+ static int sort_flt ; /* sort on floating number */
283+ #endif
281284
282- static int sort_abort ; /* flag to indicate if sorting has been interrupted */
285+ static int sort_abort ; /* flag to indicate if sorting has been interrupted */
283286
284287/* Struct to store info to be sorted. */
285288typedef struct
286289{
287290 linenr_T lnum ; /* line number */
288- long start_col_nr ; /* starting column number or number */
289- long end_col_nr ; /* ending column number */
291+ union {
292+ struct
293+ {
294+ long start_col_nr ; /* starting column number */
295+ long end_col_nr ; /* ending column number */
296+ } line ;
297+ long value ; /* value if sorting by integer */
298+ #ifdef FEAT_FLOAT
299+ float_T value_flt ; /* value if sorting by float */
300+ #endif
301+ } st_u ;
290302} sorti_T ;
291303
292304static int
@@ -319,19 +331,24 @@ sort_compare(s1, s2)
319331 /* When sorting numbers "start_col_nr" is the number, not the column
320332 * number. */
321333 if (sort_nr )
322- result = l1 .start_col_nr == l2 .start_col_nr ? 0
323- : l1 .start_col_nr > l2 .start_col_nr ? 1 : -1 ;
334+ result = l1 .st_u .value == l2 .st_u .value ? 0
335+ : l1 .st_u .value > l2 .st_u .value ? 1 : -1 ;
336+ #ifdef FEAT_FLOAT
337+ else if (sort_flt )
338+ result = l1 .st_u .value_flt == l2 .st_u .value_flt ? 0
339+ : l1 .st_u .value_flt > l2 .st_u .value_flt ? 1 : -1 ;
340+ #endif
324341 else
325342 {
326343 /* We need to copy one line into "sortbuf1", because there is no
327344 * guarantee that the first pointer becomes invalid when obtaining the
328345 * second one. */
329- STRNCPY (sortbuf1 , ml_get (l1 .lnum ) + l1 .start_col_nr ,
330- l1 .end_col_nr - l1 .start_col_nr + 1 );
331- sortbuf1 [l1 .end_col_nr - l1 .start_col_nr ] = 0 ;
332- STRNCPY (sortbuf2 , ml_get (l2 .lnum ) + l2 .start_col_nr ,
333- l2 .end_col_nr - l2 .start_col_nr + 1 );
334- sortbuf2 [l2 .end_col_nr - l2 .start_col_nr ] = 0 ;
346+ STRNCPY (sortbuf1 , ml_get (l1 .lnum ) + l1 .st_u . line . start_col_nr ,
347+ l1 .st_u . line . end_col_nr - l1 . st_u . line .start_col_nr + 1 );
348+ sortbuf1 [l1 .st_u . line . end_col_nr - l1 . st_u . line .start_col_nr ] = 0 ;
349+ STRNCPY (sortbuf2 , ml_get (l2 .lnum ) + l2 .st_u . line . start_col_nr ,
350+ l2 .st_u . line . end_col_nr - l2 . st_u . line .start_col_nr + 1 );
351+ sortbuf2 [l2 .st_u . line . end_col_nr - l2 . st_u . line .start_col_nr ] = 0 ;
335352
336353 result = sort_ic ? STRICMP (sortbuf1 , sortbuf2 )
337354 : STRCMP (sortbuf1 , sortbuf2 );
@@ -382,6 +399,9 @@ ex_sort(eap)
382399 goto sortend ;
383400
384401 sort_abort = sort_ic = sort_rx = sort_nr = 0 ;
402+ #ifdef FEAT_FLOAT
403+ sort_flt = 0 ;
404+ #endif
385405
386406 for (p = eap -> arg ; * p != NUL ; ++ p )
387407 {
@@ -393,9 +413,16 @@ ex_sort(eap)
393413 sort_rx = TRUE;
394414 else if (* p == 'n' )
395415 {
396- sort_nr = 2 ;
416+ sort_nr = 1 ;
397417 ++ format_found ;
398418 }
419+ #ifdef FEAT_FLOAT
420+ else if (* p == 'f' )
421+ {
422+ sort_flt = 1 ;
423+ ++ format_found ;
424+ }
425+ #endif
399426 else if (* p == 'b' )
400427 {
401428 sort_what = STR2NR_BIN + STR2NR_FORCE ;
@@ -460,7 +487,8 @@ ex_sort(eap)
460487 goto sortend ;
461488 }
462489
463- /* From here on "sort_nr" is used as a flag for any number sorting. */
490+ /* From here on "sort_nr" is used as a flag for any integer number
491+ * sorting. */
464492 sort_nr += sort_what ;
465493
466494 /*
@@ -494,7 +522,7 @@ ex_sort(eap)
494522 if (regmatch .regprog != NULL )
495523 end_col = 0 ;
496524
497- if (sort_nr )
525+ if (sort_nr || sort_flt )
498526 {
499527 /* Make sure vim_str2nr doesn't read any digits past the end
500528 * of the match, by temporarily terminating the string there */
@@ -503,27 +531,45 @@ ex_sort(eap)
503531 * s2 = NUL ;
504532 /* Sorting on number: Store the number itself. */
505533 p = s + start_col ;
506- if (sort_what & STR2NR_HEX )
507- s = skiptohex (p );
508- else if (sort_what & STR2NR_BIN )
509- s = skiptobin (p );
510- else
511- s = skiptodigit (p );
512- if (s > p && s [-1 ] == '-' )
513- -- s ; /* include preceding negative sign */
514- if (* s == NUL )
515- /* empty line should sort before any number */
516- nrs [lnum - eap -> line1 ].start_col_nr = - MAXLNUM ;
534+ if (sort_nr )
535+ {
536+ if (sort_what & STR2NR_HEX )
537+ s = skiptohex (p );
538+ else if (sort_what & STR2NR_BIN )
539+ s = skiptobin (p );
540+ else
541+ s = skiptodigit (p );
542+ if (s > p && s [-1 ] == '-' )
543+ -- s ; /* include preceding negative sign */
544+ if (* s == NUL )
545+ /* empty line should sort before any number */
546+ nrs [lnum - eap -> line1 ].st_u .value = - MAXLNUM ;
547+ else
548+ vim_str2nr (s , NULL , NULL , sort_what ,
549+ & nrs [lnum - eap -> line1 ].st_u .value , NULL , 0 );
550+ }
551+ #ifdef FEAT_FLOAT
517552 else
518- vim_str2nr (s , NULL , NULL , sort_what ,
519- & nrs [lnum - eap -> line1 ].start_col_nr , NULL , 0 );
553+ {
554+ s = skipwhite (p );
555+ if (* s == '+' )
556+ s = skipwhite (s + 1 );
557+
558+ if (* s == NUL )
559+ /* empty line should sort before any number */
560+ nrs [lnum - eap -> line1 ].st_u .value_flt = - DBL_MAX ;
561+ else
562+ nrs [lnum - eap -> line1 ].st_u .value_flt =
563+ strtod ((char * )s , NULL );
564+ }
565+ #endif
520566 * s2 = c ;
521567 }
522568 else
523569 {
524570 /* Store the column to sort at. */
525- nrs [lnum - eap -> line1 ].start_col_nr = start_col ;
526- nrs [lnum - eap -> line1 ].end_col_nr = end_col ;
571+ nrs [lnum - eap -> line1 ].st_u . line . start_col_nr = start_col ;
572+ nrs [lnum - eap -> line1 ].st_u . line . end_col_nr = end_col ;
527573 }
528574
529575 nrs [lnum - eap -> line1 ].lnum = lnum ;
0 commit comments