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
