blob: c0625f53c2068e79873dfc50da2f59324af9f858 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2017 SAP AG and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Lazar Kirchev, SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.console.completion;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.equinox.console.completion.common.Completer;
/**
* This class implements completion of file names. It provides completion both for
* files with absolute filenames, as well as with names, relative to the current
* directory.
*/
public class FileNamesCompleter implements Completer {
private static final String FILE = "file:";
@Override
public Map<String, Integer> getCandidates(String buffer, int cursor) {
Map<String, Integer> result = new HashMap<>();
String currentToken = CommandLineParser.getCurrentToken(buffer, cursor);
if(currentToken == null || currentToken.equals("")) {
return new HashMap<>();
}
// if current token contains file:, then use URL class to parse the filename
if(currentToken.contains(FILE)) {
String fileName = currentToken.substring(currentToken.indexOf(FILE));
try {
URL url = new URL(fileName);
String canonicalFileName = url.getPath();
File file = new File(canonicalFileName);
File parent = file.getParentFile();
if ((file.isDirectory() && canonicalFileName.endsWith("/") )|| parent == null) {
// the entered filename is a directory name, ending with file separator character - here
// all files in the directory will be returned as completion candidates;
// or, if parent is null, the file is in the root directory and
// the names of all files in this directory should be used to search for completion candidates
return checkChildren(file, "", cursor, false);
} else {
// there is a filename for completion, and the names of all files in the same directory will be used
// to search for completion candidates
return checkChildren(parent, file.getName(), cursor, false);
}
} catch (MalformedURLException e) {
return result;
}
}
// the file name for completion is only the file separator character, so all files
// in the current directory will be returned as completion candidates
if (currentToken.equals("\\\\") || currentToken.equals("/")) {
File file = new File(".");
return checkChildren(file, "", cursor, false);
}
// if the current token contains file separator character, then its parent directory can be extracted
if (currentToken.contains("\\\\") || currentToken.contains("/")) {
File file = new File(currentToken);
File parent = file.getParentFile();
if ((file.isDirectory() && (currentToken.endsWith("/") || currentToken.endsWith("\\\\")))
|| parent == null) {
// the entered filename is a directory name, ending with file separator character - here
// all files in the directory will be returned as completion candidates;
// or, if parent is null, the file is in the root directory and
// the names of all files in this directory should be used to search for completion candidates
return checkChildren(file, "", cursor, false);
} else {
// there is a filename for completion, and the names of all files in the same directory will be used
// to search for completion candidates
return checkChildren(parent, file.getName(), cursor, false);
}
}
// if the current token does not contain file separator character,
// then search for candidates in the current directory
return checkChildren(new File("."), currentToken, cursor, false);
}
private Map<String, Integer> checkChildren(File parent, String nameToComplete, int cursor, boolean absolute) {
Map<String, Integer> result = new HashMap<>();
if(parent.exists()) {
File[] children = parent.listFiles();
for(File child : children) {
if(child.getName().startsWith(nameToComplete)) {
if(absolute == true) {
result.put(child.getAbsolutePath(), cursor - nameToComplete.length());
} else {
result.put(child.getName(), cursor - nameToComplete.length());
}
}
}
}
return result;
}
}