Index: C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/ConsolePathMatcher.java =================================================================== --- C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/ConsolePathMatcher.java (revision 0) +++ C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/ConsolePathMatcher.java (revision 0) @@ -0,0 +1,157 @@ +package org.tigris.subversion.subclipse.ui.console; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.IHyperlink; +import org.eclipse.ui.console.IPatternMatchListener; +import org.eclipse.ui.console.PatternMatchEvent; +import org.eclipse.ui.console.TextConsole; +import org.eclipse.ui.part.FileEditorInput; + +public class ConsolePathMatcher implements IPatternMatchListener { + + private TextConsole myConsole; + private Pattern[] myPatterns; + + public String getPattern() { + return ".+"; + } + + public int getCompilerFlags() { + return 0; + } + + public String getLineQualifier() { + return null; + } + + public void connect(TextConsole console) { + myConsole = null; + if (console != null && "svn".equalsIgnoreCase(console.getName())) { + myConsole = console; + myConsole.addPatternMatchListener(this); + } + } + + public void disconnect() { + if (myConsole != null) { + myConsole.removePatternMatchListener(this); + } + myConsole = null; + } + + public void matchFound(PatternMatchEvent event) { + if (myConsole != null) { + // all lines will be matched. + // select those: + // [AUCDGMR][wsp](path)[newline or end of input] + // \s+[AUCDGMR]\s+([a-zA-Z]:/[^\r\n]+) + // (Sending)(Replacing)(Deleting)(Adding)(Reverted)[wsp](path)[newline or end of input] + int offset = event.getOffset(); + int length = event.getLength(); + String path; + try { + path = myConsole.getDocument().get(offset, length); + if (path == null) { + return; + } + } catch (BadLocationException e) { + return; + } + Pattern[] patterns = getPatterns(); + int start = 0; + for (int i = 0; i < patterns.length; i++) { + Pattern pattern = patterns[i]; + Matcher matcher = pattern.matcher(path); + while(matcher.find(start)) { + length = matcher.end(1) - matcher.start(1); + String link = path.substring(matcher.start(1), matcher.end(1)); + if (link != null) { + try { + myConsole.addHyperlink(new Hyperlink(link), offset + matcher.start(1), length); + } catch (BadLocationException e) { + } + return; + } + start = matcher.end(); + } + } + } + } + + private Pattern[] getPatterns() { + if (myPatterns == null) { + myPatterns = new Pattern[] { + Pattern.compile(".*\\s+[AUCDGMR]\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + Pattern.compile(".*\\s+Sending\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + Pattern.compile(".*\\s+Adding\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + Pattern.compile(".*\\s+Deleting\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + Pattern.compile(".*\\s+Replacing\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + Pattern.compile(".*\\s+Reverted\\s+([a-zA-Z]?:?/[^\r\n]+).*"), + }; + } + return myPatterns; + } + + private static class Hyperlink implements IHyperlink { + + private String myPath; + + public Hyperlink(String path) { + myPath = path; + } + + public void linkEntered() { + } + + public void linkExited() { + } + + public void linkActivated() { + final IPath path = Path.fromOSString(myPath); + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null || window.getActivePage() == null) { + return; + } + IWorkbenchPage page = window.getActivePage(); + if (ResourcesPlugin.getWorkspace().getRoot() == null) { + return; + } + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); + if (file == null || !file.exists()) { + return; + } + IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); + if (registry == null) { + return; + } + IEditorDescriptor descriptor = registry.getDefaultEditor(path.lastSegment()); + if (descriptor == null) { + descriptor = registry.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID); + } + if (descriptor == null) { + return; + } + IEditorInput input = new FileEditorInput(file); + try { + page.openEditor(input, descriptor.getId()); + } catch (PartInitException e) { + } + } + + } + +} Property changes on: C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/ConsolePathMatcher.java ___________________________________________________________________ Name: svn:eol-style + native Index: C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/SVNOutputConsole.java =================================================================== --- C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/SVNOutputConsole.java (revision 2092) +++ C:/nautilus/org.tigris.subversion.subclipse.ui/src/org/tigris/subversion/subclipse/ui/console/SVNOutputConsole.java (working copy) @@ -108,6 +108,7 @@ SVNProviderPlugin.getPlugin().setConsoleListener(SVNOutputConsole.this); SVNUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(SVNOutputConsole.this); showConsole(false); + addPatternMatchListener(new ConsolePathMatcher()); } /* (non-Javadoc)