package feathereditor include texteditor/TextEditor.feather import texteditor.TextEditorBehaviour class FeatherTextEditor( file : File) : TextEditorBehaviour( file ) { class val packagePattern = Pattern.compile( "\\s*package\\s(.+)" ) class val importPattern = Pattern.compile( "\\s*import\\s+(static)?\\s*([^\\s]*)\\s*(?:(?:as)\\s+([^\\s]*))?" ) class val classPattern = Pattern.compile( "\\s*((?:class)|(?:interface))(.*)" ) override meth attached(container: Container) { super.attached(container) attachFeatherSyntaxHighlighter() } override meth caretToSelection(row: int, column: int, line: String): List { return lookup( line.wordAt( column ) ) } override meth selectionToSelection(selection: TextSelection): List { return lookup( selection.selection ) } meth lookup( simpleName : String ) : List { // Look for the class using just its name val klass2 = findClass( simpleName ) if (klass2 != null) { return listOf( Context("Class", klass2) ) } // Parse package and import. Stop at class or interface keyword val packages = listOf() val aliases = mapOf() // Key == simpleName, value = qualified name. for (line in lines()) { val stripped = line.strip() val packageMatcher = packagePattern.matcher( line ) if (packageMatcher.find()) { packages.add( packageMatcher.group(1) ) } val importMatcher = importPattern.matcher( line ) if (importMatcher.find()) { val group2 = importMatcher.group(2) val isStatic = importMatcher.group(1) == "static" val isDotStar = group2.endsWith( ".*" ) val qualName = if (isDotStar) group2.substring(0, group2.size()-2) else group2 val alias = importMatcher.group(3) if (isStatic && isDotStar) continue if (isDotStar) { packages.add( qualName ) } else { if ( alias == null ) { val lastDot = qualName.lastIndexOf(".") val lastPart = if (lastDot > 0) { qualName.substring( lastDot+1 ) } else { qualName } aliases.put(lastPart, qualName ) } else { aliases.put(alias, qualName) } } } if ( classPattern.matcher(line).find() ) { break } } // Finished parsing package and import statements val className = aliases[simpleName] if (className != null) { val klass = findClass( className ) if (klass != null) { return listOf( Context("Class", klass) ) } } for (pack in packages) { val className2 = "$pack.$simpleName" val klass = findClass( className2 ) if (klass != null) { return listOf( Context("Class", klass) ) } } return null } }