2 * FILECOMP.C - handles filename completion.
7 * 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
8 * moved from command.c file
9 * made second TAB display list of filename matches
10 * made filename be lower case if last character typed is lower case
12 * 25-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
13 * Cleanup. Unicode safe!
15 * 30-Apr-2004 (Filip Navara <xnavara@volny.cz>)
16 * Make the file listing readable when there is a lot of long names.
31 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
33 VOID
CompleteFilename (LPTSTR str
, INT charcount
)
40 BOOL found_dot
= FALSE
;
41 BOOL perfectmatch
= TRUE
;
43 TCHAR fname
[MAX_PATH
];
44 TCHAR maxmatch
[MAX_PATH
] = _T("");
45 TCHAR directory
[MAX_PATH
];
48 /* expand current file name */
49 count
= charcount
- 1;
53 /* find front of word */
54 if (str
[count
] == _T('"'))
57 while (count
> 0 && str
[count
] != _T('"'))
62 while (count
> 0 && str
[count
] != _T(' '))
66 /* if not at beginning, go forward 1 */
67 if (str
[count
] == _T(' '))
72 if (str
[count
] == _T('"'))
73 count
++; /* don't increment start */
75 /* extract directory from word */
76 _tcscpy (directory
, &str
[count
]);
77 curplace
= _tcslen (directory
) - 1;
79 if (curplace
>= 0 && directory
[curplace
] == _T('"'))
80 directory
[curplace
--] = _T('\0');
82 _tcscpy (path
, directory
);
84 while (curplace
>= 0 && directory
[curplace
] != _T('\\') &&
85 directory
[curplace
] != _T(':'))
87 directory
[curplace
] = 0;
91 /* look for a '.' in the filename */
92 for (count
= _tcslen (directory
); path
[count
] != _T('\0'); count
++)
94 if (path
[count
] == _T('.'))
102 _tcscat (path
, _T("*"));
104 _tcscat (path
, _T("*.*"));
109 hFile
= FindFirstFile (path
, &file
);
110 if (hFile
!= INVALID_HANDLE_VALUE
)
115 /* ignore "." and ".." */
116 if (!_tcscmp (file
.cFileName
, _T(".")) ||
117 !_tcscmp (file
.cFileName
, _T("..")))
120 _tcscpy (fname
, file
.cFileName
);
122 if (file
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
123 _tcscat (fname
, _T("\\"));
125 if (!maxmatch
[0] && perfectmatch
)
127 _tcscpy(maxmatch
, fname
);
131 for (count
= 0; maxmatch
[count
] && fname
[count
]; count
++)
133 if (tolower(maxmatch
[count
]) != tolower(fname
[count
]))
135 perfectmatch
= FALSE
;
141 if (maxmatch
[count
] == _T('\0') &&
142 fname
[count
] != _T('\0'))
143 perfectmatch
= FALSE
;
146 while (FindNextFile (hFile
, &file
));
150 /* only quote if the filename contains spaces */
151 if (_tcschr(directory
, _T(' ')) ||
152 _tcschr(maxmatch
, _T(' ')))
154 str
[start
] = _T('\"');
155 _tcscpy (&str
[start
+1], directory
);
156 _tcscat (&str
[start
], maxmatch
);
157 _tcscat (&str
[start
], _T("\"") );
161 _tcscpy (&str
[start
], directory
);
162 _tcscat (&str
[start
], maxmatch
);
165 /* append a space if last word is not a directory */
168 curplace
= _tcslen(&str
[start
]);
169 if(str
[start
+curplace
-1] == _T('"'))
172 if(str
[start
+curplace
-1] != _T('\\'))
173 _tcscat(&str
[start
], _T(" "));
186 /* no match found - search for internal command */
187 for (cmds_ptr
= cmds
; cmds_ptr
->name
; cmds_ptr
++)
189 if (!_tcsnicmp (&str
[start
], cmds_ptr
->name
,
190 _tcslen (&str
[start
])))
192 /* return the mach only if it is unique */
193 if (_tcsnicmp (&str
[start
], (cmds_ptr
+1)->name
, _tcslen (&str
[start
])))
194 _tcscpy (&str
[start
], cmds_ptr
->name
);
209 * returns 1 if at least one match, else returns 0
212 BOOL
ShowCompletionMatches (LPTSTR str
, INT charcount
)
214 WIN32_FIND_DATA file
;
216 BOOL found_dot
= FALSE
;
220 TCHAR path
[MAX_PATH
];
221 TCHAR fname
[MAX_PATH
];
222 TCHAR directory
[MAX_PATH
];
223 INT longestfname
= 0;
226 /* expand current file name */
227 count
= charcount
- 1;
231 /* find front of word */
232 if (str
[count
] == _T('"'))
235 while (count
> 0 && str
[count
] != _T('"'))
240 while (count
> 0 && str
[count
] != _T(' '))
244 /* if not at beginning, go forward 1 */
245 if (str
[count
] == _T(' '))
250 if (str
[count
] == _T('"'))
251 count
++; /* don't increment start */
253 /* extract directory from word */
254 _tcscpy (directory
, &str
[count
]);
255 curplace
= _tcslen (directory
) - 1;
257 if (curplace
>= 0 && directory
[curplace
] == _T('"'))
258 directory
[curplace
--] = _T('\0');
260 _tcscpy (path
, directory
);
262 while (curplace
>= 0 &&
263 directory
[curplace
] != _T('\\') &&
264 directory
[curplace
] != _T(':'))
266 directory
[curplace
] = 0;
270 /* look for a . in the filename */
271 for (count
= _tcslen (directory
); path
[count
] != _T('\0'); count
++)
273 if (path
[count
] == _T('.'))
281 _tcscat (path
, _T("*"));
283 _tcscat (path
, _T("*.*"));
288 hFile
= FindFirstFile (path
, &file
);
289 if (hFile
!= INVALID_HANDLE_VALUE
)
291 /* Get the size of longest filename first. */
294 if (_tcslen(file
.cFileName
) > longestfname
)
296 longestfname
= _tcslen(file
.cFileName
);
297 /* Directories get extra brackets around them. */
298 if (file
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
302 while (FindNextFile (hFile
, &file
));
305 hFile
= FindFirstFile (path
, &file
);
307 /* Count the highest number of columns */
308 GetScreenSize(&screenwidth
, 0);
310 /* For counting columns of output */
313 /* Increase by the number of spaces behind file name */
317 ConOutChar (_T('\n'));
320 /* ignore . and .. */
321 if (!_tcscmp (file
.cFileName
, _T(".")) ||
322 !_tcscmp (file
.cFileName
, _T("..")))
325 if (file
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
326 _stprintf (fname
, _T("[%s]"), file
.cFileName
);
328 _tcscpy (fname
, file
.cFileName
);
330 ConOutPrintf (_T("%*s"), - longestfname
, fname
);
332 /* output as much columns as fits on the screen */
333 if (count
>= (screenwidth
/ longestfname
))
335 /* print the new line only if we aren't on the
336 * last column, in this case it wraps anyway */
337 if (count
* longestfname
!= screenwidth
)
338 ConOutPrintf (_T("\n"));
342 while (FindNextFile (hFile
, &file
));
347 ConOutChar (_T('\n'));
364 #ifdef FEATURE_4NT_FILENAME_COMPLETION
366 //static VOID BuildFilenameMatchList (...)
368 // VOID CompleteFilenameNext (LPTSTR, INT)
369 // VOID CompleteFilenamePrev (LPTSTR, INT)
371 // VOID RemoveFilenameMatchList (VOID)