|
From: Christopher W. <caw...@us...> - 2006-05-05 01:13:33
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13792/src/org/rubypeople/rdt/internal/ui/rubyeditor Modified Files: RubyAbstractEditor.java RubyEditor.java RubyDocumentProvider.java RubySourceViewer.java Added Files: IRubyScriptDocumentProvider.java Removed Files: TabExpander.java Log Message: fix formatting to respect tab conversion to spaces and tab/indentation size (from our new formatter page - I was still referring to old preferences that no longer are used/exist) Index: RubySourceViewer.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubySourceViewer.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RubySourceViewer.java 10 Feb 2006 20:14:31 -0000 1.5 --- RubySourceViewer.java 5 May 2006 01:13:27 -0000 1.6 *************** *** 9,14 **** import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; - import org.eclipse.jface.text.DocumentCommand; - import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.IVerticalRuler; --- 9,12 ---- *************** *** 24,38 **** import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; import org.eclipse.ui.texteditor.AbstractTextEditor; - import org.rubypeople.rdt.core.RubyCore; - import org.rubypeople.rdt.core.formatter.DefaultCodeFormatterConstants; - import org.rubypeople.rdt.core.formatter.Indents; - import org.rubypeople.rdt.internal.ui.RubyPlugin; - import org.rubypeople.rdt.ui.PreferenceConstants; public class RubySourceViewer extends ProjectionViewer implements IPropertyChangeListener { - private boolean isTabReplacing = false; private boolean fIgnoreTextConverters = false; - private TabExpander tabExpander; /** --- 22,29 ---- *************** *** 75,79 **** super(composite, verticalRuler, overviewRuler, overviewRulerVisible, styles); setPreferenceStore(store); - initializeTabReplace(); } --- 66,69 ---- *************** *** 248,296 **** public void doOperation(int operation) { if (getTextWidget() == null || !redraws()) { return; } - - switch (operation) { - case UNDO: - fIgnoreTextConverters = true; - break; - case REDO: - fIgnoreTextConverters = true; - break; - } - super.doOperation(operation); } - - protected void customizeDocumentCommand(DocumentCommand command) { - super.customizeDocumentCommand(command); - if (!fIgnoreTextConverters) { - convertTabs(command, getDocument()); - } - fIgnoreTextConverters = false; - } - - void initializeTabReplace() { - this.isTabReplacing = !RubyPlugin.getDefault().getPreferenceStore().getBoolean( - PreferenceConstants.FORMAT_USE_TAB); - if (this.isTabReplacing) { - int length = Indents.getTabWidth(RubyCore.getOptions()); - tabExpander = new TabExpander(length); - } - } - - protected void convertTabs(DocumentCommand command, IDocument document) { - if (!isTabReplacing) - return; - - if (command.text.equals("\t")) - tabExpander.expandTab(command, document); - } - - public boolean isTabReplacing() { - return isTabReplacing; - } - - public String getIndentString() { - return tabExpander.getFullIndent(); - } - } --- 238,242 ---- --- NEW FILE: IRubyScriptDocumentProvider.java --- /******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.rubypeople.rdt.internal.ui.rubyeditor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.source.IAnnotationModelListener; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IDocumentProviderExtension2; import org.eclipse.ui.texteditor.IDocumentProviderExtension3; import org.eclipse.ui.texteditor.IDocumentProviderExtension5; import org.rubypeople.rdt.core.IRubyScript; /** * @since 3.0 */ public interface IRubyScriptDocumentProvider extends IDocumentProvider, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension5 { /** * Shuts down this provider. */ void shutdown(); /** * Returns the working copy for the given element. * * @param element the element * @return the working copy for the given element */ IRubyScript getWorkingCopy(Object element); /** * Saves the content of the given document to the given element. This method has * only an effect if it is called when directly or indirectly inside <code>saveDocument</code>. * * @param monitor the progress monitor * @param element the element to which to save * @param document the document to save * @param overwrite <code>true</code> if the save should be enforced */ void saveDocumentContent(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException; /** * Creates a line tracker for the given element. It is of the same kind as the one that would be * used for a newly created document for the given element. * * @param element the element * @return a line tracker for the given element */ ILineTracker createLineTracker(Object element); /** * Sets the document provider's save policy. * * @param savePolicy the save policy */ void setSavePolicy(ISavePolicy savePolicy); /** * Adds a listener that reports changes from all compilation unit annotation models. * * @param listener the listener */ void addGlobalAnnotationModelListener(IAnnotationModelListener listener); /** * Removes the listener. * * @param listener the listener */ void removeGlobalAnnotationModelListener(IAnnotationModelListener listener); } Index: RubyDocumentProvider.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** RubyDocumentProvider.java 30 Mar 2006 03:16:39 -0000 1.22 --- RubyDocumentProvider.java 5 May 2006 01:13:27 -0000 1.23 *************** *** 10,21 **** --- 10,25 ---- import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; + import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.util.ListenerList; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; + import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; + import org.eclipse.jface.text.DefaultLineTracker; import org.eclipse.jface.text.IDocument; + import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.ISynchronizable; import org.eclipse.jface.text.Position; *************** *** 43,46 **** --- 47,51 ---- import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; import org.eclipse.ui.texteditor.IDocumentProvider; + import org.eclipse.ui.texteditor.IElementStateListener; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.MarkerUtilities; *************** *** 56,60 **** import org.rubypeople.rdt.ui.PreferenceConstants; ! public class RubyDocumentProvider extends TextFileDocumentProvider { /** --- 61,65 ---- import org.rubypeople.rdt.ui.PreferenceConstants; ! public class RubyDocumentProvider extends TextFileDocumentProvider implements IRubyScriptDocumentProvider { /** *************** *** 1062,1066 **** } } ! } \ No newline at end of file --- 1067,1079 ---- } } ! ! ! public ILineTracker createLineTracker(Object element) { ! return new DefaultLineTracker(); ! } ! ! public void setSavePolicy(ISavePolicy savePolicy) { ! fSavePolicy= savePolicy; ! } } \ No newline at end of file Index: RubyEditor.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyEditor.java,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** RubyEditor.java 23 Apr 2006 19:58:23 -0000 1.45 --- RubyEditor.java 5 May 2006 01:13:27 -0000 1.46 *************** *** 21,28 **** --- 21,30 ---- import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPositionCategoryException; + import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentExtension; import org.eclipse.jface.text.IDocumentListener; + import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.IPositionUpdater; import org.eclipse.jface.text.IRegion; *************** *** 47,51 **** import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; - import org.eclipse.jface.text.source.ISourceViewerExtension2; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewerConfiguration; --- 49,52 ---- *************** *** 227,231 **** public void createPartControl(Composite parent) { super.createPartControl(parent); ! ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); --- 228,232 ---- public void createPartControl(Composite parent) { super.createPartControl(parent); ! ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); *************** *** 646,664 **** super.handlePreferenceStoreChanged(event); String property = event.getProperty(); - - if (PreferenceConstants.FORMAT_USE_TAB.equals(property) - || PreferenceConstants.FORMAT_INDENTATION.equals(property)) { - // TODO Shouldn't the indent stuff really be in the source viewer - // configuration? - if (getSourceViewer() instanceof RubySourceViewer) { - ((RubySourceViewer) getSourceViewer()).initializeTabReplace(); - } - // for rereading the indentPrefixes for shift left/right from the - // RubySourceViewerConfiguration - if (getSourceViewer() instanceof ISourceViewerExtension2) { - ((ISourceViewerExtension2) getSourceViewer()).unconfigure(); - this.getSourceViewer().configure(this.getSourceViewerConfiguration()); - } - } if (CLOSE_BRACKETS.equals(property)) { --- 647,650 ---- *************** *** 1403,1405 **** --- 1389,1471 ---- public void partInputChanged(IWorkbenchPartReference partRef) {} } + + interface ITextConverter { + void customizeDocumentCommand(IDocument document, DocumentCommand command); + } + + static class TabConverter implements ITextConverter { + + private int fTabRatio; + private ILineTracker fLineTracker; + + public TabConverter() { + } + + public void setNumberOfSpacesPerTab(int ratio) { + fTabRatio= ratio; + } + + public void setLineTracker(ILineTracker lineTracker) { + fLineTracker= lineTracker; + } + + private int insertTabString(StringBuffer buffer, int offsetInLine) { + + if (fTabRatio == 0) + return 0; + + int remainder= offsetInLine % fTabRatio; + remainder= fTabRatio - remainder; + for (int i= 0; i < remainder; i++) + buffer.append(' '); + return remainder; + } + + public void customizeDocumentCommand(IDocument document, DocumentCommand command) { + String text= command.text; + if (text == null) + return; + + int index= text.indexOf('\t'); + if (index > -1) { + + StringBuffer buffer= new StringBuffer(); + + fLineTracker.set(command.text); + int lines= fLineTracker.getNumberOfLines(); + + try { + + for (int i= 0; i < lines; i++) { + + int offset= fLineTracker.getLineOffset(i); + int endOffset= offset + fLineTracker.getLineLength(i); + String line= text.substring(offset, endOffset); + + int position= 0; + if (i == 0) { + IRegion firstLine= document.getLineInformationOfOffset(command.offset); + position= command.offset - firstLine.getOffset(); + } + + int length= line.length(); + for (int j= 0; j < length; j++) { + char c= line.charAt(j); + if (c == '\t') { + position += insertTabString(buffer, position); + } else { + buffer.append(c); + ++ position; + } + } + + } + + command.text= buffer.toString(); + + } catch (BadLocationException x) { + } + } + } + } } \ No newline at end of file --- TabExpander.java DELETED --- Index: RubyAbstractEditor.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyAbstractEditor.java,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** RubyAbstractEditor.java 21 Apr 2006 21:13:29 -0000 1.28 --- RubyAbstractEditor.java 5 May 2006 01:13:24 -0000 1.29 *************** *** 10,14 **** --- 10,16 ---- import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.jface.preference.IPreferenceStore; + import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.ITextViewerExtension5; + import org.eclipse.jface.text.IWidgetTokenKeeper; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.contentassist.ContentAssistant; *************** *** 17,20 **** --- 19,23 ---- import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; + import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.ListenerList; *************** *** 32,39 **** --- 35,44 ---- import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; + import org.eclipse.ui.PlatformUI; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; import org.eclipse.ui.texteditor.ChainedPreferenceStore; + import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; import org.eclipse.ui.views.contentoutline.ContentOutline; *************** *** 51,55 **** --- 56,63 ---- import org.rubypeople.rdt.core.RubyModelException; import org.rubypeople.rdt.core.formatter.DefaultCodeFormatterConstants; + import org.rubypeople.rdt.internal.corext.util.CodeFormatterUtil; import org.rubypeople.rdt.internal.ui.RubyPlugin; + import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor.ITextConverter; + import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor.TabConverter; import org.rubypeople.rdt.internal.ui.text.ContentAssistPreference; import org.rubypeople.rdt.internal.ui.text.IRubyPartitions; *************** *** 58,61 **** --- 66,70 ---- import org.rubypeople.rdt.ui.IWorkingCopyManager; import org.rubypeople.rdt.ui.PreferenceConstants; + import org.rubypeople.rdt.ui.RubyUI; import org.rubypeople.rdt.ui.text.RubySourceViewerConfiguration; import org.rubypeople.rdt.ui.text.RubyTextTools; *************** *** 72,76 **** protected AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener(); private RubyOutlinePage fOutlinePage; ! /** Preference key for matching brackets */ --- 81,86 ---- protected AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener(); private RubyOutlinePage fOutlinePage; ! /** The editor's tab converter */ ! private TabConverter fTabConverter; /** Preference key for matching brackets */ *************** *** 78,81 **** --- 88,95 ---- /** Preference key for matching brackets color */ protected final static String MATCHING_BRACKETS_COLOR= PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR; + /** Preference key for code formatter tab size */ + private final static String CODE_FORMATTER_TAB_SIZE= DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE; + /** Preference key for inserting spaces rather than tabs */ + private final static String SPACES_FOR_TABS= DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR; protected final static char[] BRACKETS= { '{', '}', '(', ')', '[', ']' }; *************** *** 206,209 **** --- 220,224 ---- protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); + configureTabConverter(); setOutlinePageInput(fOutlinePage, input); } *************** *** 237,250 **** ((RubySourceViewerConfiguration)getSourceViewerConfiguration()).handlePropertyChangeEvent(event); ! if (DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE.equals(property) ! || DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE.equals(property) ! || DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR.equals(property)) { ! StyledText textWidget= sourceViewer.getTextWidget(); ! int tabWidth= getSourceViewerConfiguration().getTabWidth(sourceViewer); ! if (textWidget.getTabs() != tabWidth) ! textWidget.setTabs(tabWidth); return; } IContentAssistant c= sourceViewer.getContentAssistant(); if (c instanceof ContentAssistant) --- 252,269 ---- ((RubySourceViewerConfiguration)getSourceViewerConfiguration()).handlePropertyChangeEvent(event); ! if (SPACES_FOR_TABS.equals(property)) { ! if (isTabConversionEnabled()) ! startTabConversion(); ! else ! stopTabConversion(); return; } + if (CODE_FORMATTER_TAB_SIZE.equals(property)) { + sourceViewer.updateIndentationPrefixes(); + if (fTabConverter != null) + fTabConverter.setNumberOfSpacesPerTab(getTabSize()); + } + IContentAssistant c= sourceViewer.getContentAssistant(); if (c instanceof ContentAssistant) *************** *** 270,273 **** --- 289,361 ---- } } + + private int getTabSize() { + IRubyElement element= getInputRubyElement(); + IRubyProject project= element == null ? null : element.getRubyProject(); + return CodeFormatterUtil.getTabWidth(project); + } + + private void startTabConversion() { + if (fTabConverter == null) { + fTabConverter= new TabConverter(); + configureTabConverter(); + fTabConverter.setNumberOfSpacesPerTab(getTabSize()); + AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer(); + asv.addTextConverter(fTabConverter); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270 + asv.updateIndentationPrefixes(); + } + } + + private void configureTabConverter() { + if (fTabConverter != null) { + IDocumentProvider provider= getDocumentProvider(); + if (provider instanceof IRubyScriptDocumentProvider) { + IRubyScriptDocumentProvider cup= (IRubyScriptDocumentProvider) provider; + fTabConverter.setLineTracker(cup.createLineTracker(getEditorInput())); + } + } + } + + /** + * Returns the Ruby element wrapped by this editors input. + * + * @return the Ruby element wrapped by this editors input. + * @since 3.0 + */ + protected IRubyElement getInputRubyElement() { + IEditorInput editorInput= getEditorInput(); + if (editorInput == null) + return null; + return RubyUI.getEditorInputRubyElement(getEditorInput()); + } + + private void stopTabConversion() { + if (fTabConverter != null) { + AdaptedSourceViewer asv= (AdaptedSourceViewer) getSourceViewer(); + asv.removeTextConverter(fTabConverter); + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270 + asv.updateIndentationPrefixes(); + fTabConverter= null; + } + } + + public void createPartControl(Composite parent) { + super.createPartControl(parent); + + if (isTabConversionEnabled()) + startTabConversion(); + } + + private boolean isTabConversionEnabled() { + IRubyElement element= getInputRubyElement(); + IRubyProject project= element == null ? null : element.getRubyProject(); + String option; + if (project == null) + option= RubyCore.getOption(SPACES_FOR_TABS); + else + option= project.getOption(SPACES_FOR_TABS, true); + return RubyCore.SPACE.equals(option); + } protected void handleOutlinePageSelection(SelectionChangedEvent event) { *************** *** 844,847 **** --- 932,993 ---- return fContentAssistant; } + + public void addTextConverter(ITextConverter textConverter) { + if (fTextConverters == null) { + fTextConverters= new ArrayList(1); + fTextConverters.add(textConverter); + } else if (!fTextConverters.contains(textConverter)) + fTextConverters.add(textConverter); + } + + public void removeTextConverter(ITextConverter textConverter) { + if (fTextConverters != null) { + fTextConverters.remove(textConverter); + if (fTextConverters.size() == 0) + fTextConverters= null; + } + } + + /* + * @see TextViewer#customizeDocumentCommand(DocumentCommand) + */ + protected void customizeDocumentCommand(DocumentCommand command) { + super.customizeDocumentCommand(command); + if (!fIgnoreTextConverters && fTextConverters != null) { + for (Iterator e = fTextConverters.iterator(); e.hasNext();) + ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(), command); + } + } + + // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270 + public void updateIndentationPrefixes() { + SourceViewerConfiguration configuration= getSourceViewerConfiguration(); + String[] types= configuration.getConfiguredContentTypes(this); + for (int i= 0; i < types.length; i++) { + String[] prefixes= configuration.getIndentPrefixes(this, types[i]); + if (prefixes != null && prefixes.length > 0) + setIndentPrefixes(prefixes, types[i]); + } + } + + /* + * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper) + */ + public boolean requestWidgetToken(IWidgetTokenKeeper requester) { + if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed()) + return false; + return super.requestWidgetToken(requester); + } + + /* + * @see IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper, int) + * @since 3.0 + */ + public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) { + if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed()) + return false; + return super.requestWidgetToken(requester, priority); + } + } } \ No newline at end of file |