@Override protected void formatMaster(IFormattingContext context, IDocument document, int offset, int length) { // Reset error state masterFormatterHadError = false; // Save the entire doc text before we run the master formatter premasterDocumentText = document.get(); // Create the document clone tempDocument = documentCloner.clone(document); if (tempDocument == null) { masterFormatterHadError = true; return; } recordSlavePartitionsText(); if (replaceSlavePartitionsDuringMasterFormat) { replaceSlavePartitionsWithDummyText(); } // Ensure the superclass works off the temp document setToTempDocument(context); super.formatMaster(context, tempDocument, offset, length); }
@Override public void formatterStarts(final IFormattingContext context) { super.formatterStarts(context); final IDocument document = (IDocument) context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM); final TypedPosition partition = (TypedPosition) context .getProperty(FormattingContextProperties.CONTEXT_PARTITION); final IProject project = (IProject) context.getProperty(ScriptFormattingContextProperties.CONTEXT_PROJECT); final String formatterId = (String) context.getProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_ID); final Boolean isSlave = (Boolean) context .getProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_IS_SLAVE); final Boolean canConsumeIndentation = isSlave != null && isSlave && (Boolean) context .getProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_CAN_CONSUME_INDENTATION); final Boolean isSelection = !(Boolean) context.getProperty(FormattingContextProperties.CONTEXT_DOCUMENT); IRegion selectionRegion = null; if (isSelection != null && isSelection) { selectionRegion = (IRegion) context.getProperty(FormattingContextProperties.CONTEXT_REGION); } fJobs.addLast(new FormatJob(context, document, partition, project, formatterId, isSlave, canConsumeIndentation, isSelection, selectionRegion)); }
/** * Update the fomatting context to reflect to the script formatter that should be used with the given content-type. * * @param context * @param region * @param lastContentType */ private void updateContex(IFormattingContext context, String contentType, int offset, int length) { IScriptFormatterFactory factory = ScriptFormatterManager.getSelected(contentType); if (factory != null) { factory.setMainContentType(contentType); if (context != null) { context.setProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_ID, factory.getId()); context.setProperty(FormattingContextProperties.CONTEXT_PARTITION, new TypedPosition(offset, length, contentType)); context.setProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_CAN_CONSUME_INDENTATION, factory.canConsumePreviousIndent()); } } }
@Override public IFormattingContext createFormattingContext() { IFormattingContext context= new JavaFormattingContext(); Map<String, String> preferences; IJavaElement inputJavaElement= getInputJavaElement(); IJavaProject javaProject= inputJavaElement != null ? inputJavaElement.getJavaProject() : null; if (javaProject == null) preferences= new HashMap<String, String>(JavaCore.getOptions()); else preferences= new HashMap<String, String>(javaProject.getOptions(true)); context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, preferences); return context; }
/** * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext) */ public void formatterStarts(final IFormattingContext context) { super.formatterStarts(context); documents.addLast(context .getProperty(FormattingContextProperties.CONTEXT_MEDIUM)); }
@Override public void formatterStarts(IFormattingContext context) { super.formatterStarts(context); IDocument document = (IDocument) context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM); TypedPosition position = (TypedPosition) context.getProperty(FormattingContextProperties.CONTEXT_PARTITION); partitions.addLast(position); documents.addLast(document); }
/** * @param context * @param document * @param partition * @param project * @param formatterId * @param isSlave * @param canConsumeIndentation * @param isSelection * @param selectedRegion * - Should be valid when isSelection is true. */ public FormatJob(IFormattingContext context, IDocument document, TypedPosition partition, IProject project, String formatterId, Boolean isSlave, Boolean canConsumeIndentation, Boolean isSelection, IRegion selectedRegion) { this.context = context; this.document = document; this.partition = partition; this.project = project; this.formatterId = formatterId; this.canConsumeIndentation = canConsumeIndentation; this.isSlave = (isSlave != null) ? isSlave : false; this.isSelection = (isSelection != null) ? isSelection : false; this.selectedRegion = selectedRegion; }
/** * Detects the indentation level. */ public int detectIndentationLevel(IDocument document, int offset, boolean isSelection, IFormattingContext formattingContext) { String source = document.get(); int indent = 0; try { IParseState parseState = new HTMLParseState(source); IParseRootNode parseResult = ParserPoolFactory.parse(getMainContentType(), parseState).getRootNode(); if (parseResult != null) { final HTMLFormatterNodeBuilder builder = new HTMLFormatterNodeBuilder(); final FormatterDocument formatterDocument = createFormatterDocument(source); IFormatterContainerNode root = builder.build(parseResult, formatterDocument); new HTMLFormatterNodeRewriter().rewrite(root); IFormatterContext context = new HTMLFormatterContext(0); FormatterIndentDetector detector = new FormatterIndentDetector(offset); try { root.accept(context, detector); return detector.getLevel(); } catch (Exception e) { // ignore } } } catch (Throwable t) { return super.detectIndentationLevel(document, offset); } return indent; }
@Override public IFormattingContext createFormattingContext() { // it's ok to use instance preferences here as subclasses replace // with project dependent versions (see CompilationUnitEditor.AdaptedSourceViewer) IFormattingContext context= new JavaFormattingContext(); Map<String, String> map= new HashMap<String, String>(JavaCore.getOptions()); context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, map); return context; }
@Override public void formatterStarts(final IFormattingContext context) { super.formatterStarts(context); fPartitions.addLast((TypedPosition) context.getProperty(FormattingContextProperties.CONTEXT_PARTITION)); fDocuments.addLast((IDocument) context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM)); }
@Override protected void doFormatPreview() { if (fPreviewText == null) { fPreviewDocument.set(""); //$NON-NLS-1$ return; } fPreviewDocument.set(fPreviewText); fSourceViewer.setRedraw(false); final IFormattingContext context = new JavaFormattingContext(); try { final IContentFormatter formatter = fViewerConfiguration.getContentFormatter(fSourceViewer); if (formatter instanceof IContentFormatterExtension) { final IContentFormatterExtension extension = (IContentFormatterExtension) formatter; context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, fWorkingValues); context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.valueOf(true)); extension.format(fPreviewDocument, context); } else formatter.format(fPreviewDocument, new Region(0, fPreviewDocument.getLength())); } catch (Exception e) { final IStatus status= new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, FormatterMessages.JavaPreview_formatter_exception, e); JavaPlugin.log(status); } finally { context.dispose(); fSourceViewer.setRedraw(true); } }
@Override protected void formatSlaves(IFormattingContext context, IDocument document, int offset, int length) { try { if (masterFormatterHadError) { // Do not proceed if the master formatter had an error return; } // Revert any master changes of partitions for which we have a slave // formatting strategy try { ITypedRegion[] partitions = TextUtilities.computePartitioning( tempDocument, partitioning, 0, tempDocument.getLength(), false); if (partitions.length == savedPartitionText.length) { for (int i = 0; i < savedPartitionText.length; i++) { if (savedPartitionText[i] == null) { continue; } tempDocument.replace(partitions[i].getOffset(), partitions[i].getLength(), savedPartitionText[i]); if (partitions[i].getLength() != savedPartitionText[i].length()) { // Recompute partitions since our replacement affects subsequent // offsets partitions = TextUtilities.computePartitioning(tempDocument, partitioning, 0, tempDocument.getLength(), false); } } } } catch (BadLocationException e) { // This will never happen, according to super.formatSlaves } if (length > tempDocument.getLength()) { // Safeguard against the master formatter shortening the document length = tempDocument.getLength(); } // Ensure the superclass works off the temp document setToTempDocument(context); super.formatSlaves(context, tempDocument, offset, length); String tempText = tempDocument.get(); if (!tempText.equals(premasterDocumentText)) { if (!checkForNonwhitespaceChanges || StringUtilities.equalsIgnoreWhitespace(tempText, premasterDocumentText, true)) { // Replace the text since it is different than what we started the // with document.set(tempText); } else { CorePluginLog.logWarning("Not applying formatting since it would cause non-whitespace changes."); } } } finally { /* * This will always be called. The super.format method tries calling * formatMaster, and in a finally block calls formatSlaves. We try-finally * on entry into formatSlaves. */ documentCloner.release(tempDocument); } }
private void setToTempDocument(IFormattingContext context) { context.setProperty(FormattingContextProperties.CONTEXT_MEDIUM, tempDocument); }
/** * Detects the indentation level. */ public int detectIndentationLevel(IDocument document, int offset, boolean isSelection, IFormattingContext formattingContext) { int indent = 0; try { // detect the indentation offset with the parser, only if the given offset is not the first one in the // current partition. ITypedRegion partition = document.getPartition(offset); if (partition != null && partition.getOffset() == offset) { return super.detectIndentationLevel(document, offset); } String source = document.get(); IParseRootNode parseResult = ParserPoolFactory.parse(getMainContentType(), source).getRootNode(); if (parseResult != null) { final XMLFormatterNodeBuilder builder = new XMLFormatterNodeBuilder(); final FormatterDocument formatterDocument = createFormatterDocument(source, offset); IFormatterContainerNode root = builder.build(parseResult, formatterDocument); new XMLFormatterNodeRewriter().rewrite(root); IFormatterContext context = new XMLFormatterContext(0); FormatterIndentDetector detector = new FormatterIndentDetector(offset); try { root.accept(context, detector); return detector.getLevel(); } catch (Exception e) { // ignore } } } catch (Throwable t) { return super.detectIndentationLevel(document, offset); } return indent; }
/** * Detects the indentation level. */ public int detectIndentationLevel(IDocument document, int offset, boolean isSelection, IFormattingContext formattingContext) { int indent = 0; try { // detect the indentation offset with the parser, only if the given offset is not the first one in the // current partition. ITypedRegion partition = document.getPartition(offset); if (partition != null && partition.getOffset() == offset) { return super.detectIndentationLevel(document, offset); } String source = document.get(); IParseRootNode parseResult = ParserPoolFactory.parse(getMainContentType(), source).getRootNode(); if (parseResult != null) { final CSSFormatterNodeBuilder builder = new CSSFormatterNodeBuilder(); final FormatterDocument formatterDocument = createFormatterDocument(source, offset); IFormatterContainerNode root = builder.build(parseResult, formatterDocument); new CSSFormatterNodeRewriter(parseResult, formatterDocument).rewrite(root); IFormatterContext context = new CSSFormatterContext(0); FormatterIndentDetector detector = new FormatterIndentDetector(offset); try { root.accept(context, detector); return detector.getLevel(); } catch (Exception e) { // ignore } } } catch (Throwable t) { return super.detectIndentationLevel(document, offset); } return indent; }
/** * Detects the indentation level. */ public int detectIndentationLevel(IDocument document, int offset, boolean isSelection, IFormattingContext formattingContext) { int indent = 0; try { // detect the indentation offset with the parser, only if the given offset is not the first one in the // current partition. ITypedRegion partition = document.getPartition(offset); if (partition != null && partition.getOffset() == offset) { return super.detectIndentationLevel(document, offset); } String source = document.get(); IParseRootNode parseResult = ParserPoolFactory.parse(getMainContentType(), source).getRootNode(); if (parseResult != null) { final JSFormatterNodeBuilder builder = new JSFormatterNodeBuilder(); final FormatterDocument formatterDocument = createFormatterDocument(source, offset); IFormatterContainerNode root = builder.build(parseResult, formatterDocument); new JSFormatterNodeRewriter(parseResult, formatterDocument).rewrite(root); IFormatterContext context = new JSFormatterContext(0); FormatterIndentDetector detector = new FormatterIndentDetector(offset); try { root.accept(context, detector); return detector.getLevel(); } catch (Exception e) { // ignore } } } catch (Throwable t) { return super.detectIndentationLevel(document, offset); } return indent; }
@SuppressWarnings("rawtypes") @Override public IFormattingContext createFormattingContext() { final IFormattingContext context = super.createFormattingContext(); try { QualifiedContentType contentType = CommonEditorPlugin.getDefault().getDocumentScopeManager() .getContentType(getDocument(), 0); if (contentType != null && contentType.getPartCount() > 0) { for (String ct : contentType.getParts()) { String mainContentType = ct; // We need to make sure that in case the given content type is actually a nested language in // HTML, we look for the HTML formatter factory because it should be the 'Master' formatter. if (mainContentType.startsWith(CommonSourceViewerConfiguration.CONTENTTYPE_HTML_PREFIX)) { mainContentType = CommonSourceViewerConfiguration.CONTENTTYPE_HTML_PREFIX; } final IScriptFormatterFactory factory = ScriptFormatterManager.getSelected(mainContentType); if (factory != null) { // The code above might change the content type that is used to // get the formatter, but we still need to save the original content-type so that the // IScriptFormatter instance will handle the any required parsing by calling the right // IParser. factory.setMainContentType(contentType.getParts()[0]); ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class); if (textEditor != null) { IResource file = (IResource) textEditor.getEditorInput().getAdapter(IResource.class); context.setProperty(ScriptFormattingContextProperties.CONTEXT_FORMATTER_ID, factory.getId()); IProject project = (file != null) ? file.getProject() : null; Map preferences = factory.retrievePreferences(new PreferencesLookupDelegate(project)); context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, preferences); } break; } } } } catch (BadLocationException e) { } return context; }
/** * Detects the indentation level at the specified offset * * @param document * @param offset * @param context * @param isSelection * @return */ int detectIndentationLevel(IDocument document, int offset, boolean isSelection, IFormattingContext context);
/** * Format <code>source</code>, and returns a text edit that correspond to the difference between the given string * and the formatted string. * <p> * It returns null if the given string cannot be formatted. * </p> * * @param source * full source module content * @param offset * the offset of the region to format * @param length * the length of the region to format * @param indentationLevel * the additional indent level * @param isSelection * Indicate that we are formatting selected text. * @param context * {@link IFormatterContext} * @param indentSufix * Extra string indent to insert into the end of the formatter text (may be empty) */ TextEdit format(String source, int offset, int length, int indentationLevel, boolean isSelection, IFormattingContext context, String indentSufix) throws FormatterException;