Last active
August 29, 2015 14:22
-
-
Save h-east/9842e6691559a1103f12 to your computer and use it in GitHub Desktop.
find select ex command (WIP. 100% implement done)
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 --git a/src/ex_cmds.h b/src/ex_cmds.h | |
--- a/src/ex_cmds.h | |
+++ b/src/ex_cmds.h | |
@@ -564,6 +564,9 @@ | |
EX(CMD_for, "for", ex_while, | |
EXTRA|NOTRLCOM|SBOXOK|CMDWIN, | |
ADDR_LINES), | |
+EX(CMD_fselect, "fselect", ex_fselect, | |
+ BANG|WORD1|EDITCMD|ARGOPT|TRLBAR, | |
+ ADDR_LINES), | |
EX(CMD_function, "function", ex_function, | |
EXTRA|BANG|CMDWIN, | |
ADDR_LINES), | |
@@ -1236,6 +1239,9 @@ | |
EX(CMD_sfirst, "sfirst", ex_rewind, | |
EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR, | |
ADDR_LINES), | |
+EX(CMD_sfselect, "sfselect", ex_fselect, | |
+ BANG|WORD1|EDITCMD|ARGOPT|TRLBAR, | |
+ ADDR_LINES), | |
EX(CMD_shell, "shell", ex_shell, | |
TRLBAR|CMDWIN, | |
ADDR_LINES), | |
diff --git a/src/ex_docmd.c b/src/ex_docmd.c | |
--- a/src/ex_docmd.c | |
+++ b/src/ex_docmd.c | |
@@ -495,6 +495,9 @@ | |
#ifndef FEAT_PROFILE | |
# define ex_profile ex_ni | |
#endif | |
+#ifndef FEAT_SEARCHPATH | |
+# define ex_fselect ex_ni | |
+#endif | |
/* | |
* Declare cmdnames[]. | |
@@ -3818,6 +3821,11 @@ | |
if (xp->xp_context == EXPAND_FILES) | |
xp->xp_context = EXPAND_FILES_IN_PATH; | |
break; | |
+ case CMD_fselect: | |
+ case CMD_sfselect: | |
+ xp->xp_context = EXPAND_DIRECTORIES; | |
+ xp->xp_pattern = arg; | |
+ break; | |
case CMD_cd: | |
case CMD_chdir: | |
case CMD_lcd: | |
diff --git a/src/ex_getln.c b/src/ex_getln.c | |
--- a/src/ex_getln.c | |
+++ b/src/ex_getln.c | |
@@ -4569,6 +4569,8 @@ | |
flags |= EW_SILENT; | |
if (options & WILD_ALLLINKS) | |
flags |= EW_ALLLINKS; | |
+ if (options & WILD_FILE_WITHOUT_DIR) | |
+ flags &= ~EW_DIR; | |
if (xp->xp_context == EXPAND_FILES | |
|| xp->xp_context == EXPAND_DIRECTORIES | |
@@ -5941,6 +5943,88 @@ | |
} | |
#endif | |
+#if defined(FEAT_SEARCHPATH) || defined(PROTO) | |
+/* | |
+ * ":fselect [+command] <file>" command. | |
+ */ | |
+ void | |
+ex_fselect(eap) | |
+ exarg_T *eap; | |
+{ | |
+ expand_T xpc; | |
+ char_u *pat_str; | |
+ int i; | |
+ garray_T ga; | |
+ int flags = WILD_FILE_WITHOUT_DIR; | |
+ char_u *file_pat, *dir_pat; | |
+ char_u *path_opt; | |
+ | |
+ ga_init2(&ga, (int)sizeof(char_u *), 10); | |
+ ExpandInit(&xpc); | |
+ xpc.xp_context = EXPAND_FILES; | |
+ dir_pat = vim_strsave(eap->arg); | |
+ | |
+ file_pat = gettail(dir_pat); | |
+ if (STRCMP(dir_pat, "**") == 0) | |
+ { | |
+ path_opt = dir_pat; | |
+ file_pat = ""; | |
+ } | |
+ else if (dir_pat == file_pat) | |
+ path_opt = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; | |
+ else | |
+ { | |
+ path_opt = dir_pat; | |
+ file_pat[-1] = NUL; | |
+ } | |
+ | |
+ pat_str = addstar(file_pat, (int)STRLEN(file_pat), xpc.xp_context); | |
+ | |
+ globpath(path_opt, pat_str, &ga, flags); | |
+ if (ga.ga_len > 0) | |
+ { | |
+ int num_files = ga.ga_len; | |
+ char_u **files = (char_u **)ga.ga_data; | |
+ | |
+ msg_start(); | |
+ MSG_PUTS_TITLE(" # file"); | |
+ msg_clr_eos(); | |
+ msg_putchar('\n'); | |
+ | |
+ for (i=0; i < num_files && !got_int; i++) | |
+ { | |
+ sprintf((char *)IObuff, " %3d %s\n", i + 1, files[i]); | |
+ msg_puts(IObuff); | |
+ ui_breakcheck(); | |
+ } | |
+ if (got_int) | |
+ got_int = FALSE; /* only stop the listing */ | |
+ i = prompt_for_number(NULL); | |
+ msg_putchar('\n'); | |
+ need_wait_return = FALSE; | |
+ if (i > 0 && i <= num_files && !got_int) | |
+ { | |
+ /* split window or create new tab page first */ | |
+ if (*eap->cmd == 's' || cmdmod.tab != 0) | |
+ { | |
+ if (win_split(0, 0) == FAIL) | |
+ goto end; | |
+ RESET_BINDING(curwin); | |
+ } | |
+ eap->arg = files[i - 1]; | |
+ do_exedit(eap, NULL); | |
+ } | |
+ } | |
+ else | |
+ EMSG2(_("E345: Can't find file \"%s\" in path"), eap->arg); | |
+ | |
+end: | |
+ vim_free(pat_str); | |
+ vim_free(dir_pat); | |
+ ga_clear_strings(&ga); | |
+} | |
+#endif | |
+ | |
#if defined(FEAT_CMDHIST) || defined(PROTO) | |
/* | |
* :history command - print a history | |
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro | |
--- a/src/proto/ex_getln.pro | |
+++ b/src/proto/ex_getln.pro | |
@@ -47,6 +47,7 @@ | |
int del_history_idx __ARGS((int histype, int idx)); | |
void remove_key_from_history __ARGS((void)); | |
int get_list_range __ARGS((char_u **str, int *num1, int *num2)); | |
+void ex_fselect __ARGS((exarg_T *eap)); | |
void ex_history __ARGS((exarg_T *eap)); | |
void prepare_viminfo_history __ARGS((int asklen, int writing)); | |
int read_viminfo_history __ARGS((vir_T *virp, int writing)); | |
diff --git a/src/vim.h b/src/vim.h | |
--- a/src/vim.h | |
+++ b/src/vim.h | |
@@ -824,6 +824,7 @@ | |
#define WILD_ESCAPE 0x80 | |
#define WILD_ICASE 0x100 | |
#define WILD_ALLLINKS 0x200 | |
+#define WILD_FILE_WITHOUT_DIR 0x400 | |
/* Flags for expand_wildcards() */ | |
#define EW_DIR 0x01 /* include directory names */ |
Known Bug
File name sometimes duplicated.Depending on the contents of 'path' option. This is Vim's specification.Unexpected reference to the 'path' option, when specify an absolute or relative(start from '.') path to the ex command argument. (2015-06-15 9:40 JST)fixed.
Unimplemented feature
Command line directory completion (, )Done.It does not include the directory to list.Done.
Overview
This patch to add :fselect
command for Vim.
fselect
is "find select". fselect
is a select version of the :find
command.
How to use
:fselect [file]
When file equals **
, list files an entire current directory tree.
When file does not contain the path-separator, search matches files name from path
option's directories.
And you select a number, open the selected file.
:sfselect [file]
Same :fselect
, but splits the window.
:tab sfselect [file]
Same :fselect
, but open the tabpage.
NOTE: In all results, List the file only. Directory does not list.
Sample
:fs
is similar to:echo globpath(&path, "*")
's result. (However, directory does not list.):fs file
is similar to:echo globpath(&path, "file*")
's result. (However, directory does not list.):fs **/file
is similar to:echo globpath("**", "file*")
's result. (However, directory does not list.):fs foo/bar/file
is similar to:echo globpath("foo/bar", "file*")
's result. (However, directory does not list.)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO:
and :tabfselect.(:tab fselect
can do this)