Last active
December 17, 2015 22:49
-
-
Save mattn/5684747 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r b792349dc858 runtime/doc/eval.txt | |
--- a/runtime/doc/eval.txt Thu May 30 22:44:02 2013 +0200 | |
+++ b/runtime/doc/eval.txt Fri May 31 22:28:00 2013 +0900 | |
@@ -1477,6 +1477,8 @@ | |
in a different language than what is used for character | |
encoding. See |multi-lang|. | |
+v:lhs Left hand side of compareing for |sort()|. | |
+ | |
*v:lc_time* *lc_time-variable* | |
v:lc_time The current locale setting for time messages of the runtime | |
environment. This allows Vim scripts to be aware of the | |
@@ -1558,6 +1560,9 @@ | |
'*' or '+'. | |
Also see |getreg()| and |setreg()| | |
+v:rhs Right hand side of compareing for |sort()|. | |
+ | |
+ *v:lc_time* *lc_time-variable* | |
*v:scrollstart* *scrollstart-variable* | |
v:scrollstart String describing the script or function that caused the | |
screen to scroll up. It's only set when it is empty, thus the | |
@@ -5438,13 +5443,15 @@ | |
Numbers sort after Strings, |Lists| after Numbers. | |
For sorting text in the current buffer use |:sort|. | |
When {func} is given and it is one then case is ignored. | |
- {dict} is for functions with the "dict" attribute. It will be | |
- used to set the local variable "self". |Dictionary-function| | |
- When {func} is a |Funcref| or a function name, this function | |
- is called to compare items. The function is invoked with two | |
- items as argument and must return zero if they are equal, 1 or | |
- bigger if the first one sorts after the second one, -1 or | |
- smaller if the first one sorts before the second one. | |
+ {dict} is for functions with the "dict" attribute. It will b | |
+ e used to set the local variable "self". |Dictionary-function| | |
+ When {func} is a |Funcref| or a function name, or expression. | |
+ The {func} is called/evaluate to compare items. The function | |
+ is invoked with two items as argument and must return zero if | |
+ they are equal, 1 or bigger if the first one sorts after th | |
+ e second one, -1 or smaller if the first one sorts before the | |
+ second one. | |
+ Example: > | |
Example: > | |
func MyCompare(i1, i2) | |
return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1 | |
@@ -5455,6 +5462,10 @@ | |
func MyCompare(i1, i2) | |
return a:i1 - a:i2 | |
endfunc | |
+< If {func} is expression, |v:lhs| and |v:rhs| are given to | |
+ compareing: > | |
+ let mylist = [{"foo":3},{"foo":2},{"foo":4}] | |
+ :echo sort(mylist, "v:lhs.foo - v:rhs.foo") | |
< | |
*soundfold()* | |
soundfold({word}) | |
diff -r b792349dc858 src/eval.c | |
--- a/src/eval.c Thu May 30 22:44:02 2013 +0200 | |
+++ b/src/eval.c Fri May 31 22:28:00 2013 +0900 | |
@@ -355,6 +355,8 @@ | |
{VV_NAME("searchforward", VAR_NUMBER), 0}, | |
{VV_NAME("oldfiles", VAR_LIST), 0}, | |
{VV_NAME("windowid", VAR_NUMBER), VV_RO}, | |
+ {VV_NAME("lhs", VAR_UNKNOWN), VV_RO}, | |
+ {VV_NAME("rhs", VAR_UNKNOWN), VV_RO}, | |
}; | |
/* shorthand */ | |
@@ -16831,6 +16833,7 @@ | |
item_compare2 __ARGS((const void *s1, const void *s2)); | |
static int item_compare_ic; | |
+static int item_compare_expr; | |
static char_u *item_compare_func; | |
static dict_T *item_compare_selfdict; | |
static int item_compare_func_err; | |
@@ -16891,7 +16894,23 @@ | |
copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); | |
rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ | |
- res = call_func(item_compare_func, (int)STRLEN(item_compare_func), | |
+ | |
+ if (item_compare_expr) | |
+ { | |
+ char_u *expr = item_compare_func; | |
+ typval_T save_lhs, save_rhs; | |
+ prepare_vimvar(VV_LHS, &save_lhs); | |
+ prepare_vimvar(VV_RHS, &save_rhs); | |
+ vimvars[VV_LHS].vv_type = VAR_UNKNOWN; | |
+ vimvars[VV_LHS].vv_tv = argv[0]; | |
+ vimvars[VV_RHS].vv_type = VAR_UNKNOWN; | |
+ vimvars[VV_RHS].vv_tv = argv[1]; | |
+ res = eval1(&expr, &rettv, TRUE); | |
+ restore_vimvar(VV_LHS, &save_lhs); | |
+ restore_vimvar(VV_RHS, &save_rhs); | |
+ } | |
+ else | |
+ res = call_func(item_compare_func, (int)STRLEN(item_compare_func), | |
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, | |
item_compare_selfdict); | |
clear_tv(&argv[0]); | |
@@ -16938,6 +16957,7 @@ | |
return; /* short list sorts pretty quickly */ | |
item_compare_ic = FALSE; | |
+ item_compare_expr = FALSE; | |
item_compare_func = NULL; | |
item_compare_selfdict = NULL; | |
if (argvars[1].v_type != VAR_UNKNOWN) | |
@@ -16968,6 +16988,17 @@ | |
} | |
item_compare_selfdict = argvars[2].vval.v_dict; | |
} | |
+ | |
+ if (item_compare_func != NULL && item_compare_selfdict == NULL) | |
+ { | |
+ char_u* name; | |
+ if ((name = get_expanded_name(item_compare_func, | |
+ vim_strchr(item_compare_func, AUTOLOAD_CHAR) == NULL)) | |
+ == NULL) | |
+ { | |
+ item_compare_expr = TRUE; | |
+ } | |
+ } | |
} | |
/* Make an array with each entry pointing to an item in the List. */ | |
diff -r b792349dc858 src/vim.h | |
--- a/src/vim.h Thu May 30 22:44:02 2013 +0200 | |
+++ b/src/vim.h Fri May 31 22:28:00 2013 +0900 | |
@@ -1862,7 +1862,9 @@ | |
#define VV_SEARCHFORWARD 53 | |
#define VV_OLDFILES 54 | |
#define VV_WINDOWID 55 | |
-#define VV_LEN 56 /* number of v: vars */ | |
+#define VV_LHS 56 | |
+#define VV_RHS 57 | |
+#define VV_LEN 58 /* number of v: vars */ | |
#ifdef FEAT_CLIPBOARD | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment