aboutsummaryrefslogtreecommitdiffstats
path: root/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors
diff options
context:
space:
mode:
Diffstat (limited to 'org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors')
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BBVariableTextHover.java119
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeDocumentProvider.java61
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeFileEditor.java86
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java193
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/CustomFunctionRule.java94
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeCompletionProcessor.java125
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorActionContributor.java47
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.java21
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.properties14
-rw-r--r--org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/VariableRule.java69
10 files changed, 829 insertions, 0 deletions
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BBVariableTextHover.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BBVariableTextHover.java
new file mode 100644
index 0000000..d98c305
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BBVariableTextHover.java
@@ -0,0 +1,119 @@
+/**
+ *
+ */
+package org.openembedded.bc.ui.editors.bitbake;
+
+import java.io.File;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.openembedded.bc.bitbake.BBRecipe;
+import org.openembedded.bc.bitbake.BBSession;
+import org.openembedded.bc.ui.Activator;
+
+
+/**
+ * Maps BB Variables in the editor to BBSession
+ * @author kgilmer
+ *
+ */
+class BBVariableTextHover implements ITextHover {
+ private final BBSession session;
+ private volatile Map envMap;
+
+ public BBVariableTextHover(BBSession session, String file) {
+ this.session = session;
+ envMap = session;
+ LoadRecipeJob loadRecipeJob = new LoadRecipeJob(getFilename(file), file);
+ loadRecipeJob.schedule();
+ }
+
+ private String getFilename(String file) {
+
+ String [] elems = file.split(File.separator);
+
+ return elems[elems.length - 1];
+ }
+
+ public IRegion getHoverRegion(ITextViewer tv, int off) {
+ return new Region(off, 0);
+ }
+
+ public String getHoverInfo(ITextViewer tv, IRegion r) {
+ try {
+ IRegion lineRegion = tv.getDocument().getLineInformationOfOffset(r.getOffset());
+
+ return getBBVariable(tv.getDocument().get(lineRegion.getOffset(), lineRegion.getLength()).toCharArray(), r.getOffset() - lineRegion.getOffset());
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+
+ private String getBBVariable(char[] line, int offset) {
+ // Find start of word.
+ int i = offset;
+
+ while (line[i] != ' ' && line[i] != '$' && i > 0) {
+ i--;
+ }
+
+ if (i < 0 || line[i] != '$') {
+ return ""; //this is not a BB variable.
+ }
+
+ // find end of word
+ int start = i;
+ i = offset;
+
+ while (line[i] != ' ' && line[i] != '}' && i <= line.length) {
+ i++;
+ }
+
+ if (line[i] != '}') {
+ return ""; //this bb variable didn't terminate as expected
+ }
+
+ String key = new String(line, start + 2, i - start - 2);
+ String val = (String) envMap.get(key);
+
+ if (val == null) {
+ val = "";
+ }
+
+ if (val.length() > 64) {
+ val = val.substring(0, 64) + '\n' + val.substring(65);
+ }
+
+ return val;
+ }
+
+ private class LoadRecipeJob extends Job {
+ private final String filePath;
+
+ public LoadRecipeJob(String name, String filePath) {
+ super("Extracting BitBake environment for " + name);
+ this.filePath = filePath;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor mon) {
+ try {
+ BBRecipe recipe = new BBRecipe(session, filePath);
+ recipe.initialize();
+ envMap = recipe;
+ } catch (Exception e) {
+ return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Unable to load session for " + filePath, e);
+ }
+
+ return Status.OK_STATUS;
+ }
+ }
+} \ No newline at end of file
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeDocumentProvider.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeDocumentProvider.java
new file mode 100644
index 0000000..dba29c2
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeDocumentProvider.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/package org.openembedded.bc.ui.editors.bitbake;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+
+/**
+ * Document provider for BB recipe.
+ * @author kgilmer
+ *
+ */
+public class BitBakeDocumentProvider extends FileDocumentProvider {
+ /**
+ * The recipe partitioning. It contains two partition types: {@link #RECIPE_CODE} and
+ * {@link #RECIPE_COMMENT}.
+ */
+ public static final String RECIPE_PARTITIONING= "org.recipeeditor.recipepartitioning"; //$NON-NLS-1$
+
+ public static final String RECIPE_CODE= IDocument.DEFAULT_CONTENT_TYPE;
+ public static final String RECIPE_COMMENT= "RECIPE_COMMENT"; //$NON-NLS-1$
+
+ private static final String[] CONTENT_TYPES= {
+ RECIPE_CODE,
+ RECIPE_COMMENT
+ };
+
+ private IDocumentPartitioner createRecipePartitioner() {
+ IPredicateRule[] rules= { new SingleLineRule("#", null, new Token(RECIPE_COMMENT), (char) 0, true, false) }; //$NON-NLS-1$
+
+ RuleBasedPartitionScanner scanner= new RuleBasedPartitionScanner();
+ scanner.setPredicateRules(rules);
+
+ return new FastPartitioner(scanner, CONTENT_TYPES);
+ }
+
+ @Override
+ protected void setupDocument(Object element,IDocument document) {
+ if (document instanceof IDocumentExtension3) {
+ IDocumentExtension3 ext= (IDocumentExtension3) document;
+ IDocumentPartitioner partitioner= createRecipePartitioner();
+ ext.setDocumentPartitioner(RECIPE_PARTITIONING, partitioner);
+ partitioner.connect(document);
+ }
+ }
+
+}
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeFileEditor.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeFileEditor.java
new file mode 100644
index 0000000..2e48c97
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeFileEditor.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.openembedded.bc.ui.Activator;
+import org.openembedded.bc.ui.builder.BitbakeCommanderNature;
+
+
+/**
+ * Editor for BB Recipe
+ *
+ * @author kgilmer
+ *
+ */
+public class BitBakeFileEditor extends AbstractDecoratedTextEditor {
+
+ public static final String EDITOR_ID = "org.openembedded.bc.ui.editors.BitBakeFileEditor";
+ static final String CONTENT_ASSIST = "ContentAssist";
+ private BitBakeSourceViewerConfiguration viewerConfiguration;
+ private String targetFilePath;
+
+ public BitBakeFileEditor() {
+ super();
+ viewerConfiguration = new BitBakeSourceViewerConfiguration(getSharedColors(), getPreferenceStore());
+ setSourceViewerConfiguration(viewerConfiguration);
+ setDocumentProvider(new BitBakeDocumentProvider());
+ }
+
+ @Override
+ protected void createActions() {
+ super.createActions();
+
+ ResourceBundle bundle = RecipeEditorMessages.getBundle();
+ ContentAssistAction action = new ContentAssistAction(bundle, "contentAssist.", this); //$NON-NLS-1$
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ setAction(CONTENT_ASSIST, action);
+ }
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+
+ if (input instanceof FileEditorInput) {
+ IProject p = ((FileEditorInput) input).getFile().getProject();
+ try {
+ if (p != null && p.isOpen() && p.hasNature(BitbakeCommanderNature.NATURE_ID)) {
+ targetFilePath = ((FileEditorInput) input).getFile().getLocationURI().getPath();
+ viewerConfiguration.setTargetFilePath(targetFilePath);
+ viewerConfiguration.setBBSession(Activator.getBBSession(p.getLocationURI().getPath()));
+ }
+ } catch (Exception e) {
+ throw new PartInitException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "On " + input.getClass().getName() + " input, nable to load editor.", e));
+ }
+ } else if (input instanceof FileStoreEditorInput) {
+ targetFilePath = ((FileStoreEditorInput)input).getURI().getPath();
+ System.out.println("Target path:" + targetFilePath);
+ } else {
+ if (input == null) {
+ System.out.println("The input is null!");
+ }
+ System.out.println("The input is not a FileEditorInput: " + input.getClass().getName());
+ }
+
+ super.init(site, input);
+ }
+} \ No newline at end of file
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java
new file mode 100644
index 0000000..e3cbeb4
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java
@@ -0,0 +1,193 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.openembedded.bc.bitbake.BBLanguageHelper;
+import org.openembedded.bc.bitbake.BBSession;
+
+
+public class BitBakeSourceViewerConfiguration extends TextSourceViewerConfiguration {
+
+ private static final class WordDetector implements IWordDetector {
+ public boolean isWordPart(char c) {
+ return !Character.isWhitespace(c);
+ }
+
+ public boolean isWordStart(char c) {
+ return !Character.isWhitespace(c);
+ }
+ }
+
+ private final ISharedTextColors fSharedColors;
+ private BBSession session;
+ private String targetFilePath;
+ private BBVariableTextHover textHover;
+
+ public BitBakeSourceViewerConfiguration(ISharedTextColors sharedColors, IPreferenceStore store) {
+ super(store);
+ fSharedColors = sharedColors;
+ }
+
+ protected void setTargetFilePath(String targetFilePath) {
+ this.targetFilePath = targetFilePath;
+ }
+
+ public ITextHover getTextHover(ISourceViewer sv, String contentType) {
+ if (textHover == null && session != null && targetFilePath != null) {
+ textHover = new BBVariableTextHover(session, targetFilePath);
+ }
+
+ return textHover;
+ }
+
+ private void addDamagerRepairer(PresentationReconciler reconciler, RuleBasedScanner commentScanner, String contentType) {
+ DefaultDamagerRepairer commentDamagerRepairer = new DefaultDamagerRepairer(commentScanner);
+ reconciler.setDamager(commentDamagerRepairer, contentType);
+ reconciler.setRepairer(commentDamagerRepairer, contentType);
+ }
+
+ private RuleBasedScanner createCommentScanner() {
+ Color green = fSharedColors.getColor(new RGB(16, 96, 16));
+ RuleBasedScanner commentScanner = new RuleBasedScanner();
+ commentScanner.setDefaultReturnToken(new Token(new TextAttribute(green, null, SWT.ITALIC)));
+ return commentScanner;
+ }
+
+ private IRule createCustomFunctionRule() {
+ Color blue = fSharedColors.getColor(new RGB(130, 0, 0));
+ IRule rule = new CustomFunctionRule(new Token(new TextAttribute(blue, null, SWT.BOLD)));
+
+ return rule;
+ }
+
+ private SingleLineRule createFunctionNameRule() {
+ Color red = fSharedColors.getColor(new RGB(150, 0, 96));
+ SingleLineRule stepRule = new SingleLineRule("do_", ")", new Token(new TextAttribute(red, null, SWT.BOLD))); //$NON-NLS-1$ //$NON-NLS-2$
+ stepRule.setColumnConstraint(0);
+ return stepRule;
+ }
+
+ private SingleLineRule createInlineVariableRule() {
+ Color blue = fSharedColors.getColor(new RGB(50, 50, 100));
+ SingleLineRule stepRule = new SingleLineRule("${", "}", new Token(new TextAttribute(blue, null, SWT.BOLD))); //$NON-NLS-1$ //$NON-NLS-2$
+ return stepRule;
+ }
+
+ private WordRule createKeywordRule() {
+ WordRule keywordRule = new WordRule(new WordDetector());
+ IToken token = new Token(new TextAttribute(fSharedColors.getColor(new RGB(96, 96, 0)), null, SWT.NONE));
+
+ for (int i = 0; i < BBLanguageHelper.BITBAKE_KEYWORDS.length; ++i) {
+
+ keywordRule.addWord(BBLanguageHelper.BITBAKE_KEYWORDS[i], token);
+ keywordRule.setColumnConstraint(0);
+ }
+
+ return keywordRule;
+ }
+
+ private RuleBasedScanner createRecipeScanner() {
+ RuleBasedScanner recipeScanner = new RuleBasedScanner();
+
+ IRule[] rules = { createKeywordRule(), createShellKeywordRule(), createStringLiteralRule(), createVariableRule(), createFunctionNameRule(), createCustomFunctionRule(),
+ createInlineVariableRule() };
+ recipeScanner.setRules(rules);
+ return recipeScanner;
+ }
+
+ private WordRule createShellKeywordRule() {
+ WordRule keywordRule = new WordRule(new WordDetector());
+ IToken token = new Token(new TextAttribute(fSharedColors.getColor(new RGB(0, 64, 92)), null, SWT.NONE));
+
+ for (int i = 0; i < BBLanguageHelper.SHELL_KEYWORDS.length; ++i) {
+ keywordRule.addWord(BBLanguageHelper.SHELL_KEYWORDS[i], token);
+ }
+
+ return keywordRule;
+ }
+
+ private SingleLineRule createStringLiteralRule() {
+ Color red = fSharedColors.getColor(new RGB(50, 50, 100));
+ SingleLineRule rule = new SingleLineRule("\"", "\"", new Token(new TextAttribute(red, null, SWT.NONE)), '\\');
+
+ return rule;
+ }
+
+ private IRule createVariableRule() {
+ Color blue = fSharedColors.getColor(new RGB(0, 0, 200));
+ IRule rule = new VariableRule(new Token(new TextAttribute(blue, null, SWT.NONE)));
+
+ return rule;
+ }
+
+ @Override
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ return new String[] { BitBakeDocumentProvider.RECIPE_CODE, BitBakeDocumentProvider.RECIPE_COMMENT };
+ }
+
+ @Override
+ public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+ return BitBakeDocumentProvider.RECIPE_PARTITIONING;
+ }
+
+ @Override
+ public IContentAssistant getContentAssistant(final ISourceViewer sourceViewer) {
+ ContentAssistant assistant = new ContentAssistant();
+ assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+ // assistant.setContentAssistProcessor(new HippieProposalProcessor(),
+ // BitBakeDocumentProvider.RECIPE_COMMENT);
+ assistant.setContentAssistProcessor(new RecipeCompletionProcessor(), BitBakeDocumentProvider.RECIPE_CODE);
+
+ return assistant;
+ }
+
+ public IReconciler getReconciler(ISourceViewer sourceViewer) {
+ return null;
+ }
+
+ @Override
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler = new PresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+ addDamagerRepairer(reconciler, createCommentScanner(), BitBakeDocumentProvider.RECIPE_COMMENT);
+ addDamagerRepairer(reconciler, createRecipeScanner(), BitBakeDocumentProvider.RECIPE_CODE);
+
+ return reconciler;
+ }
+
+ public void setBBSession(BBSession session) {
+ this.session = session;
+ }
+}
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/CustomFunctionRule.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/CustomFunctionRule.java
new file mode 100644
index 0000000..68bf076
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/CustomFunctionRule.java
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Rule for def_ BB Recipe functions
+ * @author kgilmer
+ *
+ */
+final class CustomFunctionRule implements IRule {
+
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new operator rule.
+ *
+ * @param token
+ * Token to use for this rule
+ */
+ public CustomFunctionRule(IToken token) {
+ fToken = token;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ if (scanner.getColumn() > 0) {
+ return Token.UNDEFINED;
+ }
+
+ int i = scanner.read();
+ int c = 1;
+
+ if (!Character.isLetter(i) && i != 10) {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ if (i == 'd' && scanAhead(scanner, "o_".toCharArray())) {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ while (i != ICharacterScanner.EOF && i != 10) {
+ i = scanner.read();
+ c++;
+
+ if (i == '(') {
+ readUntil(scanner, ')');
+
+ return fToken;
+ }
+ }
+
+ for (int t = 0; t < c; t++) {
+ scanner.unread();
+ }
+
+ return Token.UNDEFINED;
+ }
+
+ private void readUntil(ICharacterScanner scanner, int c) {
+ int i;
+ do {
+ i = scanner.read();
+ } while (! (i == ICharacterScanner.EOF) && ! (i == c));
+ }
+
+ private boolean scanAhead(ICharacterScanner scanner, char [] chars) {
+ boolean v = true;
+ for (int i = 0; i < chars.length; ++i) {
+ if (! (scanner.read() == chars[i])) {
+ v = false;
+ for (int j = 0; j < i; ++j) {
+ scanner.unread();
+ }
+ break;
+ }
+ }
+ return v;
+ }
+} \ No newline at end of file
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeCompletionProcessor.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeCompletionProcessor.java
new file mode 100644
index 0000000..c410124
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeCompletionProcessor.java
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateProposal;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.openembedded.bc.bitbake.BBLanguageHelper;
+import org.openembedded.bc.ui.Activator;
+
+
+class RecipeCompletionProcessor implements IContentAssistProcessor {
+
+ private static final String CONTEXT_ID= "bitbake_variables"; //$NON-NLS-1$
+ private final TemplateContextType fContextType= new TemplateContextType(CONTEXT_ID, "Common BitBake Variables"); //$NON-NLS-1$
+ //private final TemplateContextType fKeywordContextType= new TemplateContextType("bitbake_keywords", "BitBake Keywords"); //$NON-NLS-1$
+ private final TemplateContextType fFunctionContextType = new TemplateContextType("bitbake_functions", "BitBake Functions");
+
+ RecipeCompletionProcessor() {
+ }
+
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ IDocument document= viewer.getDocument();
+ Region region= new Region(offset, 0);
+
+ TemplateContext templateContext= new DocumentTemplateContext(fContextType, document, offset, 0);
+ //TemplateContext keywordContext = new DocumentTemplateContext(fKeywordContextType, document, offset, 0);
+ TemplateContext functionContext = new DocumentTemplateContext(fFunctionContextType, document, offset, 0);
+
+ List proposals = new ArrayList();
+
+ getVariableTemplateProposals(templateContext, region, proposals);
+ // getKeywordTemplateProposals(keywordContext, region, proposals);
+ getAddTaskTemplateProposals(templateContext, region, proposals);
+ getFunctionTemplateProposals(functionContext, region, proposals);
+
+ return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]);
+ }
+
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return null;
+ }
+
+ private Template generateVariableTemplate(String name, String description) {
+
+ return new Template(name, description, CONTEXT_ID, name + " = \"${" + name.toLowerCase() + "}\"", false);
+ }
+
+ private void getAddTaskTemplateProposals(TemplateContext templateContext, Region region, List p) {
+ p.add(new TemplateProposal(new Template("addtask", "addtask statement", CONTEXT_ID, "addtask ${task_name} after ${do_previous_task} before ${do_next_task}", false),templateContext, region, PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_BKMRK_TSK)));
+ }
+
+
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return null;
+ }
+
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+ public String getErrorMessage() {
+ return null;
+ }
+
+ private void getFunctionTemplateProposals(TemplateContext templateContext, Region region, List p) {
+ String [] keywords = BBLanguageHelper.BITBAKE_STANDARD_FUNCTIONS;
+ Image img = Activator.getDefault().getImageRegistry().get(Activator.IMAGE_FUNCTION);
+ Arrays.sort(keywords);
+
+ for (int i = 0; i < keywords.length; ++i) {
+ p.add(new TemplateProposal(new Template(keywords[i], keywords[i] + " function", CONTEXT_ID, "do_" + keywords[i] + "() {\n\n}", false), templateContext, region, img));
+ }
+ }
+
+ private void getKeywordTemplateProposals(TemplateContext templateContext, Region region, List p) {
+ String [] keywords = BBLanguageHelper.BITBAKE_KEYWORDS;
+
+ Arrays.sort(keywords);
+
+ for (int i = 0; i < keywords.length; ++i) {
+ p.add(new TemplateProposal(new Template(keywords[i], keywords[i] + " keyword", CONTEXT_ID, keywords[i] + " ", false),templateContext, region, null));
+ }
+ }
+
+ private void getVariableTemplateProposals(TemplateContext templateContext, Region region, List p) {
+ Map n = BBLanguageHelper.getCommonBitbakeVariables();
+ Image img = Activator.getDefault().getImageRegistry().get(Activator.IMAGE_VARIABLE);
+ for (Iterator i = n.keySet().iterator(); i.hasNext();) {
+ String name = (String) i.next();
+ String description = (String) n.get(name);
+ p.add(new TemplateProposal(generateVariableTemplate(name, description), templateContext, region, img));
+ }
+ }
+} \ No newline at end of file
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorActionContributor.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorActionContributor.java
new file mode 100644
index 0000000..b4ae491
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorActionContributor.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.editors.text.TextEditorActionContributor;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+public class RecipeEditorActionContributor extends TextEditorActionContributor {
+
+ private RetargetTextEditorAction fContentAssist;
+
+ public RecipeEditorActionContributor() {
+ fContentAssist= new RetargetTextEditorAction(RecipeEditorMessages.getBundle(), "contentAssist."); //$NON-NLS-1$
+ fContentAssist.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ }
+
+ @Override
+ public void contributeToMenu(IMenuManager menu) {
+ super.contributeToMenu(menu);
+
+ IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+ if (editMenu != null) {
+ editMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fContentAssist);
+ }
+ }
+
+ @Override
+ public void setActiveEditor(IEditorPart part) {
+ super.setActiveEditor(part);
+ if (part instanceof ITextEditor) {
+ fContentAssist.setAction(getAction((ITextEditor) part, BitBakeFileEditor.CONTENT_ASSIST));
+ }
+ }
+}
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.java
new file mode 100644
index 0000000..c1f80ba
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.java
@@ -0,0 +1,21 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import java.util.ResourceBundle;
+
+public class RecipeEditorMessages {
+
+ public static ResourceBundle getBundle() {
+ return ResourceBundle.getBundle(RecipeEditorMessages.class.getName());
+ }
+
+}
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.properties b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.properties
new file mode 100644
index 0000000..76c670b
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.properties
@@ -0,0 +1,14 @@
+#########################################################
+# Copyright (c) 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+##########################################################
+contentAssist.label=Content Assist
+contentAssist.tooltip=Content Assist
+contentAssist.image=
+contentAssist.description= Invokes content assist \ No newline at end of file
diff --git a/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/VariableRule.java b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/VariableRule.java
new file mode 100644
index 0000000..c615a9f
--- /dev/null
+++ b/org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/VariableRule.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Ken Gilmer
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ken Gilmer - initial API and implementation
+ *******************************************************************************/
+package org.openembedded.bc.ui.editors.bitbake;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+final class VariableRule implements IRule {
+
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new operator rule.
+ *
+ * @param token
+ * Token to use for this rule
+ */
+ public VariableRule(IToken token) {
+ fToken = token;
+ }
+
+ public IToken evaluate(ICharacterScanner scanner) {
+ if (scanner.getColumn() > 0) {
+ return Token.UNDEFINED;
+ }
+
+ int i = scanner.read();
+ int c = 1;
+
+ if (!Character.isLetter(i) && i != 10) {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ int p = i;
+
+ while (i != ICharacterScanner.EOF && i != 10) {
+ p = i;
+ i = scanner.read();
+ c++;
+
+ if (i == '=') {
+ scanner.unread();
+
+ if (p == '?' || p == '+') {
+ scanner.unread();
+ }
+ return fToken;
+ }
+ }
+
+ for (int t = 0; t < c; t++) {
+ scanner.unread();
+ }
+
+ return Token.UNDEFINED;
+ }
+} \ No newline at end of file