From a7e84830627e50adac5c81ae4dad69aa350933fb Mon Sep 17 00:00:00 2001 From: Ken Gilmer Date: Tue, 18 May 2010 21:53:22 -0400 Subject: org.openembedded.bc.ui: initial commit --- .../bc/ui/editors/bitbake/BBVariableTextHover.java | 119 +++++++++++++ .../editors/bitbake/BitBakeDocumentProvider.java | 61 +++++++ .../bc/ui/editors/bitbake/BitBakeFileEditor.java | 86 +++++++++ .../bitbake/BitBakeSourceViewerConfiguration.java | 193 +++++++++++++++++++++ .../bc/ui/editors/bitbake/CustomFunctionRule.java | 94 ++++++++++ .../editors/bitbake/RecipeCompletionProcessor.java | 125 +++++++++++++ .../bitbake/RecipeEditorActionContributor.java | 47 +++++ .../ui/editors/bitbake/RecipeEditorMessages.java | 21 +++ .../bitbake/RecipeEditorMessages.properties | 14 ++ .../bc/ui/editors/bitbake/VariableRule.java | 69 ++++++++ 10 files changed, 829 insertions(+) create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BBVariableTextHover.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeDocumentProvider.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeFileEditor.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/CustomFunctionRule.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeCompletionProcessor.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorActionContributor.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.java create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/RecipeEditorMessages.properties create mode 100644 org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors/bitbake/VariableRule.java (limited to 'org.openembedded.bc.ui/src/org/openembedded/bc/ui/editors') 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 -- cgit 1.2.3-korg