1
/*******************************************************************************
2
* Copyright (c) 2007, 2009 Red Hat, Inc.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Red Hat - initial API and implementation
11
*******************************************************************************/
13
package org.eclipse.linuxtools.internal.rpm.ui.editor;
15
import java.util.regex.Matcher;
16
import java.util.regex.Pattern;
18
import org.eclipse.jface.text.BadLocationException;
19
import org.eclipse.jface.text.DefaultInformationControl;
20
import org.eclipse.jface.text.IDocument;
21
import org.eclipse.jface.text.IInformationControl;
22
import org.eclipse.jface.text.IInformationControlCreator;
23
import org.eclipse.jface.text.IRegion;
24
import org.eclipse.jface.text.ITextHover;
25
import org.eclipse.jface.text.ITextHoverExtension;
26
import org.eclipse.jface.text.ITextViewer;
27
import org.eclipse.jface.text.Region;
28
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileSource;
29
import org.eclipse.linuxtools.internal.rpm.ui.editor.preferences.PreferenceConstants;
30
import org.eclipse.linuxtools.rpm.ui.editor.SpecfileEditor;
31
import org.eclipse.linuxtools.rpm.ui.editor.parser.Specfile;
32
import org.eclipse.linuxtools.rpm.ui.editor.parser.SpecfileDefine;
33
import org.eclipse.swt.graphics.Point;
34
import org.eclipse.swt.widgets.Shell;
36
public class SpecfileHover implements ITextHover, ITextHoverExtension {
38
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
39
private SpecfileEditor editor;
41
public SpecfileHover(SpecfileEditor editor) {
45
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
46
if (hoverRegion == null || hoverRegion.getLength() == 0)
49
Specfile spec = editor.getSpecfile();
52
String currentSelection;
54
currentSelection = textViewer.getDocument().get(hoverRegion.getOffset() + 1, hoverRegion.getLength() - 1);
55
} catch (BadLocationException e) {
60
// First we try to get a define based on the given name
61
SpecfileDefine define = spec.getDefine(currentSelection);
63
String value = currentSelection + ": "; //$NON-NLS-1$
66
value += define.getStringValue();
70
String macroLower = currentSelection.toLowerCase();
72
// If there's no such define we try to see if it corresponds to
73
// a Source or Patch declaration
74
String retrivedValue = getSourceOrPatchValue(spec, macroLower);
75
if (retrivedValue != null)
76
return value += retrivedValue;
78
// If it does not correspond to a Patch or Source macro, try to find it
79
// in the macro proposals list.
80
retrivedValue = getMacroValueFromMacroList(currentSelection);
81
if (retrivedValue != null)
82
return value += retrivedValue;
84
// If it does not correspond to a macro in the list, try to find it
86
retrivedValue = Activator.getDefault().getRpmPackageList().getValue(currentSelection.replaceFirst(":",EMPTY_STRING)); //$NON-NLS-1$
87
if (retrivedValue != null)
91
// We return null in other cases, so we don't show hover information
92
// for unrecognized macros and RPM packages.
96
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
98
if (textViewer != null) {
100
* If the hover offset falls within the selection range return the
101
* region for the whole selection.
103
Point selectedRange = textViewer.getSelectedRange();
104
if (selectedRange.x >= 0 && selectedRange.y > 0
105
&& offset >= selectedRange.x
106
&& offset <= selectedRange.x + selectedRange.y)
107
return new Region(selectedRange.x, selectedRange.y);
109
IRegion region = findWord(textViewer.getDocument(), offset);
110
if (region.equals(new Region(offset, 0))) {
111
region = findPackages(textViewer.getDocument(), offset);
119
public IInformationControlCreator getHoverControlCreator() {
120
return new IInformationControlCreator() {
121
public IInformationControl createInformationControl(Shell parent) {
122
return new DefaultInformationControl(parent, false);
128
public static IRegion findWord(IDocument document, int offset) {
131
boolean beginsWithBrace = false;
138
c = document.getChar(pos);
140
if (document.getChar(pos + 1) == '{')
141
beginsWithBrace = true;
144
else if (c == '\n' || c == '}'){
145
// if we hit the beginning of the line, it's not a macro
146
return new Region(offset, 0);
151
if (!beginsWithBrace)
157
int length = document.getLength();
159
while (pos < length) {
160
c = document.getChar(pos);
161
if (beginsWithBrace && (c == '}')) {
164
else if (c == '\n' || c == '%' || c == '('){ // '(' is needed for the %deffatt( case
166
// Do not return empty region here. We have a work.
167
// return new Region(offset, 0);
168
} else if (!beginsWithBrace && c == ' ') {
176
} catch (BadLocationException x) {
179
if (start >= -1 && end > -1) {
181
return new Region(start, end - start);
183
return new Region(start + 1, end - start - 1);
189
public static IRegion findPackages(IDocument document, int offset) {
192
boolean beginsWithSpace = false;
197
c = document.getChar(pos);
198
if (c == ' ' || c =='\t' || c==':') {
199
if (Character.isLetter(document.getChar(pos + 1))) {
200
beginsWithSpace = true;
202
} else if (c == '\n'){
203
return new Region(offset, 0);
211
int length = document.getLength();
212
while (pos < length) {
213
c = document.getChar(pos);
214
if (beginsWithSpace && (!Character.isLetter(c) && !Character.isDigit(c) && c != '-')) {
218
return new Region(offset, 0);
224
} catch (BadLocationException x) {
227
if (start > -1 && end > -1) {
228
return new Region(start, end - start);
233
public static String getSourceOrPatchValue(Specfile spec, String patchOrSourceName) {
235
Pattern p = Pattern.compile("(source|patch)(\\d*)"); //$NON-NLS-1$
236
Matcher m = p.matcher(patchOrSourceName);
239
String digits = m.group(2);
241
SpecfileSource source = null;
244
if (digits != null && digits.equals(EMPTY_STRING)) {
246
} else if (digits != null && !digits.equals(EMPTY_STRING)) {
247
number = Integer.parseInt(digits);
251
if (m.group(1).equals("source")) //$NON-NLS-1$
252
source = spec.getSource(number);
253
else if (m.group(1).equals("patch")) //$NON-NLS-1$
254
source = spec.getPatch(number);
256
if (source != null) {
257
value = source.getFileName();
264
public static String getMacroValueFromMacroList(String macroName) {
266
if (Activator.getDefault().getRpmMacroList().findKey("%" + macroName)) { //$NON-NLS-1$
267
String currentConfig = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_MACRO_HOVER_CONTENT);
268
// Show content of the macro according with the configuration set
269
// in the macro preference page.
270
if (currentConfig.equals(PreferenceConstants.P_MACRO_HOVER_CONTENT_VIEWDESCRIPTION))
271
value = Activator.getDefault().getRpmMacroList().getValue(macroName);
273
value = RpmMacroProposalsList.getMacroEval("%" + macroName); //$NON-NLS-1$