This class serves as basis for all ZamiaCAD editors: VHDL, Verilog, Python and BuildPath. It provides 3 common features to these editors:
1. Displays error mark in the editor's title whenever there is an error in the file. It is achieved through getTitleImage
and resource change listener.
2. Common code coloring strategy for keywords, strings and comments which is provided through getSourceViewerCfg, which returns BasicViewerConfiguration.
3. occurrence selection.
The BasicViewerConfiguration also registers the Editor's toggle comment prefix, either //
, --
or #
. This prefix is used by org.zamia.plugin.editors.ToggleCommentAction which does the actual toggling when user presses Ctrl+/.
Once VHDL is saved in the Editor, it is parsed and outline page is produced. When user moves cursor in the Editor, from cursor pointing to one item into another item, outline page must reflect the transition. Similarly, editor must jump to the corresponding item whenever user clicks it in the outline.
The first is achieved installing AbstractSelectionChangedListener to the editor's selection provider when outline page is created
public Object getAdapter(@SuppressWarnings("rawtypes") Class aClass) { Object adapter; if (aClass.equals(IContentOutlinePage.class)) { if ((fOutlinePage == null) || fOutlinePage.isDisposed()) { fOutlinePage = new ZamiaOutlinePage(this); new AbstractSelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { IWorkbenchPart part= getSite().getWorkbenchWindow().getPartService().getActivePart(); boolean outlineIsActive = part instanceof ContentOutline && ((ContentOutline)part).getCurrentPage() == fOutlinePage; if (!outlineIsActive) { computeCursorPos(getDocument(), (TextSelection) event.getSelection()); fOutlinePage.select(new SourceLocation(fSF, fLine + 1, fCol+1)); } } }.install(getSelectionProvider());
It computes the cursor position and asks the outline to select the latest item that does not exceed the position. OutlinePage first finds the latest suitable module (i.e. entity or architecture)
public void select(SourceLocation target) { ZamiaOutlineContentProvider cp = (ZamiaOutlineContentProvider) fTreeViewer.getContentProvider(); IDesignModule[] modules = fEditor.getReconcilingStrategy().getRootElements(); if (modules.length == 0) return; Object sm = null; for (int i = 0 ; i != modules.length; i++) if (modules[i].getLocation().compareTo(target) <= 0) sm = modules[i];
and then recursively iterates module children
class Helper {void selectLastChild(Object parent) { Object lastChild = null; Object[] elements = cp.getChildren(parent) ; if (elements != null) for (int i = 0 ; i != elements.length; i++) if (elements[i] instanceof ASTNode) { ASTNode astEl = (ASTNode) elements[i]; if (astEl.getLocation().compareTo(target) <= 0) lastChild = astEl; }; if (lastChild == null) fTreeViewer.setSelection(new StructuredSelection(parent), true); else selectLastChild(lastChild); }} new Helper().selectLastChild(sm);
finding one whose position is closest to editor's selection.
The backward connection is simpler. Outline page registers OpenAndLinkWithEditorHelper
new OpenAndLinkWithEditorHelper(fTreeViewer) { {setLinkWithEditor(true);}
whose linkToEditor is called whenever new item is selected
@Override protected void linkToEditor(ISelection selection) { fEditor.outlineSelectionChanged(selection); }
Here, selection is VHDLNode with known location for the editor to navigate to.
Checking outlineIsActive
in the first snippet is necessary to break the loop when selecting an item in the outline, outline updates the editor position, which causes update of the outline and etc.