Hi all,

I've extended :sort command in vim - now it can sort by floating point
values as well as dec/hex/oct. Submitting the change for review.

Kind regards,

Alex

>>>>>>>>>>>>>>>>  BEGIN OF HG EXPORT
# HG changeset patch
# User Alex Jakushev <[email protected]>
# Date 1288482264 -3600
# Node ID a31735077986cf251235d6a007c6552acf5e77d6
# Parent  b6ba81f1258fc53fcb030868229971e239d43aee
Help updated for "sort f"

diff -r b6ba81f1258f -r a31735077986 runtime/doc/change.txt
--- a/runtime/doc/change.txt    Sun Oct 31 00:17:20 2010 +0100
+++ b/runtime/doc/change.txt    Sun Oct 31 00:44:24 2010 +0100
@@ -1585,7 +1585,7 @@
 found here: |sort()|.

                                                        *:sor* *:sort*
-:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
+:[range]sor[t][!] [i][u][r][n][x][o][f] [/{pattern}/]
                        Sort lines in [range].  When no range is given all
                        lines are sorted.

@@ -1605,6 +1605,14 @@
                        With [o] sorting is done on the first octal number in
                        the line (after or inside a {pattern} match).

+                       With [f] sorting is done on the Float in the line.
+                       The value of Float is determined similar to passing
+                       the text (after or inside a {pattern} match) to
+                       str2float() function. This option is available only
+                       if Vim was compiled with Floating point support.
+
+                       Options [n][x][o][f] are mutually exclusive.
+
                        With [u] only keep the first of a sequence of
                        identical lines (ignoring case when [i] is used).
                        Without this flag, a sequence of identical lines
# HG changeset patch
# User Alex Jakushev <[email protected]>
# Date 1288480640 -3600
# Node ID b6ba81f1258fc53fcb030868229971e239d43aee
# Parent  df6b12c84b2359415cd987c016f5de135c680100
Support of sorting by floating point numbers

diff -r df6b12c84b23 -r b6ba81f1258f src/ex_cmds.c
--- a/src/ex_cmds.c     Wed Oct 27 18:36:36 2010 +0200
+++ b/src/ex_cmds.c     Sun Oct 31 00:17:20 2010 +0100
@@ -17,6 +17,9 @@

 #include "vim.h"
 #include "version.h"
+#ifdef FEAT_FLOAT
+#include <float.h>
+#endif

 #ifdef FEAT_EX_EXTRA
 static int linelen __ARGS((int *has_tab));
@@ -282,6 +285,9 @@
 static int     sort_ic;                /* ignore case */
 static int     sort_nr;                /* sort on number */
 static int     sort_rx;                /* sort on regex instead of skipping it 
*/
+#ifdef FEAT_FLOAT
+static int     sort_flt;               /* sort on floating number */
+#endif

 static int     sort_abort;             /* flag to indicate if sorting has been
interrupted */

@@ -289,8 +295,17 @@
 typedef struct
 {
     linenr_T   lnum;                   /* line number */
-    long       start_col_nr;           /* starting column number or number */
-    long       end_col_nr;             /* ending column number */
+    union {
+       struct
+       {
+           long        start_col_nr;           /* starting column number */
+           long        end_col_nr;             /* ending column number */
+       } line;
+       long value;  // value if sorting by number (n/o/x)
+#ifdef FEAT_FLOAT
+       float_T value_flt; // value if sorting by float
+#endif
+    } st_u;
 } sorti_T;

 static int
@@ -320,22 +335,25 @@
     if (got_int)
        sort_abort = TRUE;

-    /* When sorting numbers "start_col_nr" is the number, not the
column
-     * number. */
     if (sort_nr)
-       result = l1.start_col_nr == l2.start_col_nr ? 0
-                                : l1.start_col_nr > l2.start_col_nr ? 1 : -1;
+       result = l1.st_u.value == l2.st_u.value ? 0
+                                : l1.st_u.value > l2.st_u.value ? 1 : -1;
+#ifdef FEAT_FLOAT
+    else if (sort_flt)
+       result = l1.st_u.value_flt == l2.st_u.value_flt ? 0
+                                : l1.st_u.value_flt > l2.st_u.value_flt ? 1 : 
-1;
+#endif
     else
     {
        /* We need to copy one line into "sortbuf1", because there is no
         * guarantee that the first pointer becomes invalid when obtaining
the
         * second one. */
-       STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.start_col_nr,
-                                        l1.end_col_nr - l1.start_col_nr + 1);
-       sortbuf1[l1.end_col_nr - l1.start_col_nr] = 0;
-       STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.start_col_nr,
-                                        l2.end_col_nr - l2.start_col_nr + 1);
-       sortbuf2[l2.end_col_nr - l2.start_col_nr] = 0;
+       STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
+                                        l1.st_u.line.end_col_nr - 
l1.st_u.line.start_col_nr + 1);
+       sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = 0;
+       STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
+                                        l2.st_u.line.end_col_nr - 
l2.st_u.line.start_col_nr + 1);
+       sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;

        result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
                                                 : STRCMP(sortbuf1, sortbuf2);
@@ -371,6 +389,7 @@
     colnr_T    end_col;
     int                sort_oct;               /* sort on octal number */
     int                sort_hex;               /* sort on hex number */
+    int                sort_special_all;       /* sort on any possible numeric 
value */

     /* Sorting one line is really quick! */
     if (count <= 1)
@@ -386,6 +405,9 @@
        goto sortend;

     sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex =
0;
+#ifdef FEAT_FLOAT
+    sort_flt = 0;
+#endif

     for (p = eap->arg; *p != NUL; ++p)
     {
@@ -401,6 +423,10 @@
            sort_oct = 2;
        else if (*p == 'x')
            sort_hex = 2;
+#ifdef FEAT_FLOAT
+       else if (*p == 'f')
+           sort_flt = 2;
+#endif
        else if (*p == 'u')
            unique = TRUE;
        else if (*p == '"')     /* comment start */
@@ -436,14 +462,19 @@
        }
     }

-    /* Can only have one of 'n', 'o' and 'x'. */
-    if (sort_nr + sort_oct + sort_hex > 2)
+    sort_special_all = sort_nr + sort_oct + sort_hex;
+#ifdef FEAT_FLOAT
+    sort_special_all += sort_flt;
+#endif
+
+    /* Can only have one of 'f', 'n', 'o' and 'x'. */
+    if (sort_special_all > 2)
     {
        EMSG(_(e_invarg));
        goto sortend;
     }

-    /* From here on "sort_nr" is used as a flag for any number
sorting. */
+    /* From here on "sort_nr" is used as a flag for any *int* number
sorting. */
     sort_nr += sort_oct + sort_hex;

     /*
@@ -477,7 +508,7 @@
            if (regmatch.regprog != NULL)
                end_col = 0;

-       if (sort_nr)
+       if (sort_special_all)
        {
            /* Make sure vim_str2nr doesn't read any digits past the end
             * of the match, by temporarily terminating the string there */
@@ -486,25 +517,44 @@
            *s2 = NUL;
            /* Sorting on number: Store the number itself. */
            p = s + start_col;
-           if (sort_hex)
-               s = skiptohex(p);
-           else
-               s = skiptodigit(p);
-           if (s > p && s[-1] == '-')
-               --s;  /* include preceding negative sign */
-           if (*s == NUL)
-               /* empty line should sort before any number */
-               nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
-           else
-               vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
-                                 &nrs[lnum - eap->line1].start_col_nr, NULL);
+
+           if (sort_nr)
+           {
+               if (sort_hex)
+                   s = skiptohex(p);
+               else
+                   s = skiptodigit(p);
+               if (s > p && s[-1] == '-')
+                   --s;  /* include preceding negative sign */
+               if (*s == NUL)
+                   /* empty line should sort before any number */
+                   nrs[lnum - eap->line1].st_u.value = -MAXLNUM;
+               else
+                   vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
+                                     &nrs[lnum - eap->line1].st_u.value, NULL);
+           }
+#ifdef FEAT_FLOAT
+           else if (sort_flt)
+           {
+               s = skipwhite(p);
+               if (*s == '+')
+                   s = skipwhite(s + 1);
+
+               if (*s == NUL)
+                   /* empty line should sort before any number */
+                   nrs[lnum - eap->line1].st_u.value_flt = -DBL_MAX;
+               else
+                   nrs[lnum - eap->line1].st_u.value_flt = atof(s);
+           }
+#endif
+
            *s2 = c;
        }
        else
        {
            /* Store the column to sort at. */
-           nrs[lnum - eap->line1].start_col_nr = start_col;
-           nrs[lnum - eap->line1].end_col_nr = end_col;
+           nrs[lnum - eap->line1].st_u.line.start_col_nr = start_col;
+           nrs[lnum - eap->line1].st_u.line.end_col_nr = end_col;
        }

        nrs[lnum - eap->line1].lnum = lnum;
>>>>>>>>>>>>>>>>  END OF HG EXPORT

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui