jed-users mailing list

[2002 Date Index] [2002 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

[PATCH] Filters for filename completion


This patch adds a new hook, which can be used to filter out
undesirable filenames during filename completion (for example
CVS directories or Java .class files). Tested only on Linux, 
but it should be completely system-agnostic. 

Example of usage: 

% Add to .jedrc or site.sl %%

% Takes two arguments. The first one is the item to be completed, 
% the second one the type of the item. For now, it's always "file". 
% If 0 is returned, the item is not considered during the completion
% process.
define completion_filter_hook(name, type) {
    % Filter out object files
    if (string_match(name, "/.*\\.o$", 1)) {       
       return 0;           
    }                   
                     
    return 1;                              
}                                  
                                  
set_completion_filter_hook("completion_filter_hook");       

%% End %%

Unified diff attached. 

-- 
Juho Snellman
"C:stä on kehitetty Massachusettsin teknillisessä korkeakoulussa kieli
 nimeltä BCPL."  
diff -u orig.jed-B0.99-15/src/intrin.c jed-B0.99-15/src/intrin.c
--- orig.jed-B0.99-15/src/intrin.c	Mon Oct  8 07:48:16 2001
+++ jed-B0.99-15/src/intrin.c	Tue Mar  5 20:03:35 2002
@@ -834,6 +834,7 @@
    MAKE_INTRINSIC_S("set_current_kbd_command", set_current_kbd_command, VOID_TYPE),
    MAKE_INTRINSIC("blink_match", blink_match, VOID_TYPE, 0),
    MAKE_INTRINSIC_S("set_expansion_hook", set_expansion_hook, VOID_TYPE),
+   MAKE_INTRINSIC_S("set_completion_filter_hook", set_completion_filter_hook, VOID_TYPE),
    MAKE_INTRINSIC("clear_message", clear_message, VOID_TYPE, 0),
    MAKE_INTRINSIC("flush_input", flush_input, VOID_TYPE, 0),
    MAKE_INTRINSIC_0("get_word_chars", jed_get_word_chars, STRING_TYPE),
diff -u orig.jed-B0.99-15/src/ledit.c jed-B0.99-15/src/ledit.c
--- orig.jed-B0.99-15/src/ledit.c	Mon Oct  8 07:48:16 2001
+++ jed-B0.99-15/src/ledit.c	Tue Mar  5 20:19:44 2002
@@ -1628,6 +1628,55 @@
 
 /*}}}*/
 
+static SLang_Name_Type *Filter_Completion_Hook;
+void set_completion_filter_hook (char *s) /*{{{*/
+{
+   if (NULL == (Filter_Completion_Hook = SLang_get_function (s)))
+     {
+	msg_error ("The filter hook has not been defined.");
+     }
+}
+
+/*}}}*/
+
+int filter_completion (int (*cfun)(char *), char *buf) /*{{{*/
+{
+    char prev[JED_MAX_PATH_LEN];
+    
+    /* Only use completion_filter_hook for filenames at this point. */
+    if (!(cfun == sys_findfirst || cfun == sys_findnext) || 
+	Filter_Completion_Hook == NULL)
+      return (*cfun)(buf);
+    
+    /* Save the original start of completion. */
+    safe_strcpy(prev, buf, sizeof(prev));
+    
+    while (1) {
+	int accept;
+	int comp = (*cfun)(buf);
+	/* Only use complete_open first time through the loop. */
+	cfun = complete_next;
+	
+	/* No more files. */
+	if (!comp) return comp;
+	
+	/* Accept everything by default. */
+	accept = 1;
+	
+	SLang_push_string (buf);
+	/* The type of the completion hard-coded for now. */
+	SLang_push_string ("file");
+	SLexecute_function (Filter_Completion_Hook);
+	if (SLang_Error == 0) 
+	  SLang_pop_integer (&accept);
+	
+	if (SLang_Error == 0 && accept) return comp;
+
+	strcpy(prev, buf);
+    }
+}
+/*}}}*/
+
 int mini_complete (void) /*{{{*/
 {
    char *pl, *pb;
@@ -1649,11 +1698,11 @@
    if ((last_key_char == ' ') && ((long) Last_Key_Function == (long) mini_complete))
      {
 	if (flag)
-	  flag = (*complete_next)(buf);
+	  flag = filter_completion(complete_next, buf);
 	if (flag == 0)
 	  {
 	     safe_strcpy(buf, prev, sizeof (buf));
-	     flag = (*complete_open)(buf);
+	     flag = filter_completion(complete_open, buf);
 	  }
 	strcpy(last, buf);
 	n = -1;
@@ -1668,7 +1717,7 @@
      {
 	if ((Repeat_Factor != NULL)
 	    || (complete_open != sys_findfirst) || (Expand_File_Hook == NULL))
-	  flag = (*complete_open)(buf);
+	  flag = filter_completion(complete_open, buf);
 	else
 	  {
 	     int do_free;
@@ -1679,7 +1728,7 @@
 	       {
 		  if (do_free == 0)
 		    {
-		       flag = (*complete_open) (buf);
+		       flag = filter_completion(complete_open, buf);
 		       goto start_loop;
 		    }
 	       }
@@ -1749,7 +1798,7 @@
 		  newline ();
 	       }
 	  }
-	while(0 != (flag = (*complete_next)(buf)));
+	while(0 != (flag = filter_completion(complete_next, buf)));
 	
 #if JED_FILE_PRESERVE_CASE
 	/* OS/2 uses case-insensitive search on buffer-names. Set the 
@@ -1759,7 +1808,7 @@
 	if (complete_open == open_bufflist) 
 	  {
 	     strcpy(buf, last);
-	     (*complete_open)(buf);
+	     filter_completion(complete_open, buf);
 	     do 
 	       {
 		  if (!strcmp(buf, last)) 
@@ -1767,7 +1816,7 @@
 		       flag = 1; break;
 		    }
 	       }
-	     while ((*complete_next)(buf));
+	     while (filter_completion(complete_next, buf));
 	  }
 #endif
      }
diff -u orig.jed-B0.99-15/src/ledit.h jed-B0.99-15/src/ledit.h
--- orig.jed-B0.99-15/src/ledit.h	Mon Oct  8 07:48:16 2001
+++ jed-B0.99-15/src/ledit.h	Tue Mar  5 20:03:57 2002
@@ -81,6 +81,7 @@
 extern FILE *jed_open_slang_file(char *, char *);
 extern char *Completion_Buffer;
 extern void set_expansion_hook (char *);
+extern void set_completion_filter_hook (char *);
 
 extern int jed_vget_y_n (char *, char *);
 extern int jed_get_y_n (char *);

[2002 date index] [2002 thread index]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]