Eclipse Editor - SWT StyledText CaretListener offset not corresponding to real file line number - eclipse

I am currently working on an Eclipse plugin. In order to do an action, I need to listen to the caret listener of the active tab.
public void partOpened(IWorkbenchPartReference partRef) {
AbstractTextEditor e = (AbstractTextEditor) ((IEditorReference) partRef).getEditor(false);
StyledText sText = ((StyledText) e.getAdapter(Control.class));
sText.addCaretListener(new CaretListener() {
#Override
public void caretMoved(CaretEvent event) {
IDocument d = e.getDocumentProvider().getDocument(e.getEditorInput());
...
int line = d.getLineOfOffset(event.caretOffset);
Point p = sText.getLocationAtOffset(event.caretOffset);
}
});
}
I use this code to add the CaretListener on the latest opened tab.
The variable line is correct only when no code blocks are collapsed.
In fact, the offset returned by the event is linked to the StyledText, but I'd like to get the line number of the file.
This picture shows an example of folded text. The StyledText caret offset will give me something like line 6, 7 and 8, instead of 6, 7 and 12 (like Eclipse does).
Is there a way to "transform" the StyledText offset to a "real file" offset ? I could retrieve the line as a String and find it in the file, but it sounds like a bad idea.
Thanks !

For folding editors the editor's source viewer will implement ITextViewerExtension5 which provides a widgetOffset2ModelOffset method to make this adjustment.
Get the caret position using something like:
ISourceViewer sourceViewer = e.getSourceViewer();
int caret;
if (sourceViewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension = (ITextViewerExtension5)sourceViewer;
caret = extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
} else {
int offset = sourceViewer.getVisibleRegion().getOffset();
caret = offset + styledText.getCaretOffset();
}

Related

How to set the initial message for SWT Combo

SWT Text has a method called setMessage which can be used with SWT.SEARCH to put an initial faded-out message in the text box.
Can something similar be done with SWT Combo? It seems it does not have the setMessage() method, so it seems like some other trick needs to be applied here.
You are right, the Combo does not have regular API to set a message like the text widget does.
You could try to use a PaintListener to draw the message text while the Combo text is empty.
combo.addPaintListener( new PaintListener() {
#Override
public void paintControl( PaintEvent event ) {
if( combo.getText().isEmpty() ) {
int x = ...; // indent some pixels
int y = ...; // center vertically
event.gc.drawText( "enter something", x, y );
}
}
} );
In addition, you would need several listeners that redraw the Combo after its native appearance was updated.
combo.addListener( SWT.Modify, event -> combo.redraw() );
A modify listener is certainly required to show/hide the message but there are probably more listeners necessary to redraw the message when it is invalidated. This answer may give further hints which events are necessary to capture: How to display a hint message in an SWT StyledText
Note, however, that drawing onto controls other than Canvas is unsupported and may not work on all platforms.
A simpler alternative to the paint listener that worked for my purposes involves programatically setting the text and text color using a FocusListener. Here is an example:
final String placeholder = "Placeholder";
combo.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
combo.setText(placeholder);
combo.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
String text = combo.getText();
if(text.isEmpty()) {
combo.setText(placeholder);
combo.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
}
}
#Override
public void focusGained(FocusEvent e) {
String text = combo.getText();
if(text.equals(placeholder)) {
combo.setText("");
combo.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
}
}
});

Custom go to line dialog eclipse

Is it possible to subclass the Go To Line dialog of the eclipse.
I want to create a similar dialog "Go To Index" with a custom "OK" action.
The Go to Line dialog is an inner class of org.eclipse.ui.texteditor.GotoLineAction so it cannot be subclassed.
However it is just an extension of InputDialog and the code to actually move to a line is simply:
int line = .... line number ...
ITextEditor editor = getTextEditor();
IDocumentProvider provider = editor.getDocumentProvider();
IDocument document = provider.getDocument(editor.getEditorInput());
try {
int start = document.getLineOffset(line);
editor.selectAndReveal(start, 0);
} catch (BadLocationException x) {
// ignore
}

Highlighting text at specific location from IntelliJ plugin

I am developing an IntelliJ plugin and trying to highlight text programmatically at specific line and column but facing the following issue: the actual column in IntelliJ changes depending on the tab size in its configuration. Therefore column index of the specific location can change without any changes performed in the edited text.
In Eclipse for example tab is always counted as one character.
Can you point me to some example of how to highlight a specific code location independent of the configured tab size?
Currently it is implemented like this:
private static void showPsiFile(Project project, PsiFile file, int lineNumber, int column, int length) {
OpenFileDescriptor desc = new OpenFileDescriptor(project, file.getVirtualFile(), lineNumber - 1, column);
desc.navigate(true);
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
int caretLocation = editor.getCaretModel().getOffset();
int startOffset = caretLocation;
int endOffset = startOffset + length;
for (RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) {
highlighter.dispose();
}
editor.getMarkupModel().addRangeHighlighter(startOffset, endOffset, HighlighterLayer.ERROR, codeHighlightTextAttributes, HighlighterTargetArea.EXACT_RANGE);
}

Howto Highlight Code Background Color by line

I am working on a eclipse plugin and trying to highlight parts of the Code with a backround color. Is there any option to highlight to change the backround color in the editor by line numbers.
For Example:
editor.highlightLines(2,5,"red"); I i
There are so much informations when i googled for it. Annotations, Makers etc. but noone could give me a Tutorial or a link to and API which can do what i need. I only got informations for syntax highlighting, but i want to highlights parts of the code by line number.
You can do this as long as the editor implements ITextEditor:
IEditorPart editorPart = page.openEditor(new FileEditorInput(file), getEditorId() , true);
ITextEditor textEditor;
if (editorPart instanceof ITextEditor) {
textEditor = (ITextEditor)editorPart;
} else {
textEditor = (ITextEditor)editorPart.getAdapter(ITextEditor.class);
}
IEditorInput input = editorPart.getEditorInput();
IDocumentProvider provider = textEditor.getDocumentProvider();
provider.connect(input);
IDocument document = provider.getDocument(input);
IRegion region = document.getLineInformation(lineNumber - 1);
int fileOffset = region.getOffset();
int fileLength = region.getLength();
provider.disconnect(input);
textEditor.selectAndReveal(fileOffset, fileLength);
(extracted from org.eclipse.debug.ui.console.FileLink which the console code uses). I have left out many error checks of exception catches.

Eclipse: selection autocopy to clipboard

I love an Emacs feature to copy selection to clipboard automatically. Is it possible to do the same on Eclipse?
Environment: Windows XP, Helios
To copy a String from Eclipse to the clipboard, you can use
void copyToClipboard (String toClipboard, Display display){
String toClipboard = "my String";
Clipboard clipboard = new Clipboard(display);
TextTransfer [] textTransfer = {TextTransfer.getInstance()};
clipboard.setContents(new Object [] {toClipboard}, textTransfer);
clipboard.dispose();
}
Then you can call this method from a MouseAdapter or KeyAdapter, depending on where you want to get your String from. In your case it could be MouseAdapter, which listens to doubleclicks, gets the current cursor position of the text, marks the word and then adds the String to the clipboard.
edit to answer a question: You can set up your own MouseAdapater and attach it to buttons, text fields or whateer you like. Here's an example for a button:
Button btnGo1 = new Button(parent, SWT.NONE);
btnGo1.setText("Go");
btnGo1.addMouseListener(new MouseAdapter() {
#Override
public void mouseDoubleClick(MouseEvent e) {
//do what you want to do in here
}
});
If you want to implement mouseUp and mouseDown events, too, you can just add MouseListenerinstead of the Adapter. The only advantage of the Adapter is, that you don't have to override the other methods of the interface.
Since the original question was to automatically get the selection of the text of an editor: the way to get the selection from an editor is explained here.
You can try this plugin. Along with auto copy points mentioned in Eclipse show number of lines and/or file size also addressed.