# HG changeset patch
# Parent 4a0bff3af444bd2f6c116fc4e5813f7b0da6fbe3
implement 'onselected' hook for dict form completion

diff -r 4a0bff3af444 runtime/doc/insert.txt
--- a/runtime/doc/insert.txt	Thu Sep 22 09:46:15 2011 +0900
+++ b/runtime/doc/insert.txt	Sat Sep 24 12:15:30 2011 +0900
@@ -1029,12 +1029,26 @@
 			The only value currently recognized is "always", the
 			effect is that the function is called whenever the
 			leading text is changed.
+	onselected	A |Funcref| which called when user have selected an
+			item from words (optional).  There are two arguments,
+			first is original text, second is a word which user
+			selected.  The function be able to implement learning
+			user selection, for optimizing words order by user's
+			habit.
 Other items are ignored.
 
 For example, the function can contain this: >
 	let matches = ... list of words ...
 	return {'words': matches, 'refresh': 'always'}
 <
+More example which use "onselected" hook: >
+	function! OnSelected(original, result)
+	   " study user's choice for good candidate words.
+	endfunction
+
+	return { 'onselected': function('OnSelected'),
+		\ ... same as previous example ... }
+<
 						*complete-items*
 Each list item can either be a string or a Dictionary.  When it is a string it
 is used as the completion.  When it is a Dictionary it can contain these
diff -r 4a0bff3af444 src/edit.c
--- a/src/edit.c	Thu Sep 22 09:46:15 2011 +0900
+++ b/src/edit.c	Sat Sep 24 12:15:30 2011 +0900
@@ -136,6 +136,7 @@
 static expand_T	  compl_xp;
 
 static int	  compl_opt_refresh_always = FALSE;
+static char_u	  *compl_opt_onselected_func = NULL;
 
 static void ins_ctrl_x __ARGS((void));
 static int  has_compl_option __ARGS((int dict_opt));
@@ -3309,6 +3310,8 @@
     vim_free(compl_orig_text);
     compl_orig_text = NULL;
     compl_enter_selects = FALSE;
+    vim_free(compl_opt_onselected_func);
+    compl_opt_onselected_func = NULL;
 }
 
 /*
@@ -3729,6 +3732,25 @@
 		ins_compl_fixRedoBufForLeader(ptr);
 	    }
 
+#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL)
+	    /*
+	     * Notify result of completion to "onselected" hook if available.
+	     */
+	    if (ptr != NULL && compl_opt_onselected_func != NULL)
+	    {
+		char_u	    *args[2];
+		typval_T    rettv;
+
+		args[0] = compl_orig_text;
+		args[1] = ptr;
+		if (call_vim_function(compl_opt_onselected_func, 2, args,
+			    FALSE, &rettv) == OK)
+		{
+		    clear_tv(&rettv);
+		}
+	    }
+#endif
+
 #ifdef FEAT_CINDENT
 	    want_cindent = (can_cindent && cindent_on());
 #endif
@@ -4004,6 +4026,7 @@
     dict_T	*dict;
 {
     dictitem_T	*refresh;
+    dictitem_T	*onselected;
     dictitem_T	*words;
 
     /* Check for optional "refresh" item. */
@@ -4017,6 +4040,19 @@
 	    compl_opt_refresh_always = TRUE;
     }
 
+    /* Check for optional "onselected" item. */
+    vim_free(compl_opt_onselected_func);
+    compl_opt_onselected_func = NULL;
+    onselected = dict_find(dict, (char_u*)"onselected", 10);
+    if (onselected != NULL && onselected->di_tv.v_type == VAR_FUNC)
+    {
+	char_u	*v = onselected->di_tv.vval.v_string;
+
+	if (v != NULL)
+	    compl_opt_onselected_func = vim_strsave(v);
+    }
+
+
     /* Add completions from a "words" list. */
     words = dict_find(dict, (char_u *)"words", 5);
     if (words != NULL && words->di_tv.v_type == VAR_LIST)
@@ -5183,6 +5219,8 @@
 	     * completion.
 	     */
 	    compl_opt_refresh_always = FALSE;
+	    vim_free(compl_opt_onselected_func);
+	    compl_opt_onselected_func = NULL;
 
 	    if (col < 0)
 		col = curs_col;
