/* * Copyright (c) 2002-2012, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. * * http://www.opensource.org/licenses/bsd-license.php */ package jline.console.completer; import jline.internal.Configuration; import java.io.File; import java.util.List; import static jline.internal.Preconditions.checkNotNull; /** * A file name completer takes the buffer and issues a list of * potential completions. *

* This completer tries to behave as similar as possible to * bash's file name completion (using GNU readline) * with the following exceptions: *

*

* * @author Marc Prud'hommeaux * @author Jason Dillon * @since 2.3 */ public class FileNameCompleter implements Completer { // TODO: Handle files with spaces in them private static final boolean OS_IS_WINDOWS; static { String os = Configuration.getOsName(); OS_IS_WINDOWS = os.contains("windows"); } public int complete(String buffer, final int cursor, final List candidates) { // buffer can be null checkNotNull(candidates); if (buffer == null) { buffer = ""; } if (OS_IS_WINDOWS) { buffer = buffer.replace('/', '\\'); } String translated = buffer; File homeDir = getUserHome(); // Special character: ~ maps to the user's home directory if (translated.startsWith("~" + separator())) { translated = homeDir.getPath() + translated.substring(1); } else if (translated.startsWith("~")) { translated = homeDir.getParentFile().getAbsolutePath(); } else if (!(new File(translated).isAbsolute())) { String cwd = getUserDir().getAbsolutePath(); translated = cwd + separator() + translated; } File file = new File(translated); final File dir; if (translated.endsWith(separator())) { dir = file; } else { dir = file.getParentFile(); } File[] entries = dir == null ? new File[0] : dir.listFiles(); return matchFiles(buffer, translated, entries, candidates); } protected String separator() { return File.separator; } protected File getUserHome() { return Configuration.getUserHome(); } protected File getUserDir() { return new File("."); } protected int matchFiles(final String buffer, final String translated, final File[] files, final List candidates) { if (files == null) { return -1; } int matches = 0; // first pass: just count the matches for (File file : files) { if (file.getAbsolutePath().startsWith(translated)) { matches++; } } for (File file : files) { if (file.getAbsolutePath().startsWith(translated)) { CharSequence name = file.getName() + (matches == 1 && file.isDirectory() ? separator() : " "); candidates.add(render(file, name).toString()); } } final int index = buffer.lastIndexOf(separator()); return index + separator().length(); } protected CharSequence render(final File file, final CharSequence name) { return name; } }