Manipulating texts in Eclipse
History
revision | changes | author |
---|---|---|
0.1 | initial version | Darren Ha |
0.2 | textBuffer.commit | Darren Ha |
Introduction
manipulating texts in Eclipse way can be hard for initial Eclipse plugin developers. I couldn't find any structured tutorial or articles. So this articles is born.
any comments about the contets are welcomed! I hope it helps you too.
Getting IDocument form a IPath
A FileBuffer represents a file that is being modified over time. Fille buffers for text files provide IDocument(a content model) and IAnnotationModel(a marker model). so IDdocument is essential for manipulating texts.
ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); IPath path = new Path("/sample/test.h"); try{ bufferManager.connect(path, LocationKind.IFILE, monitor); ITextFileBuffer textBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE); IDocument document = textBuffer.getDocument(); }finally{ bufferManager.disconnect(path, LocationKind.IFILE, monitor); }
Creating and applying TextEdit
We can modify IDocument using TextEdit subclasses: e.g. ReplaceEdit, InsertEdit, DeleteEdit
to apply those changed multiple times in a file, you should use MultiTextEdit which is tree container of TextEdits. MultiTextEdit::apply can produce an error if the changes made at the same location at multiple times.
MultiTextEdit::apply doesn't change file contetns immediately. to change file content you must call ITextFileBuffer::commit.
MultiTextEdit::apply doesn't change file contetns immediately. to change file content you must call ITextFileBuffer::commit.
ITextFileBuffer textBuffer = ...; IDocument document = ..; FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(document); IRegion regionReplace = finder.find(0, "textTobeReplaced", true, true, false, false); IRegion regionInsert = finder.find(0, "//TODO", true, true, false, false); MultiTextEdit multiEdit = new MultiTextEdit(); multiEdit.addChild( new ReplaceEdit(regionReplace.getOffset(), regionReplace.getLength(), "ReplacedText")); multiEdit.addChild( new InsertEdit(regionInsert.getOffset(), regionInsert.getLength())); multiEdit.apply(document); textBuffer.commit(monitor, true);
using CDT refactoring mechanism
You can use CDT built-in refactoring framework to change texts more elegant way. the following codes demonstrate invoking rename refactoring of CDT programtically.
You can invoke this by clicking Alt+Shift+R in eclipse source editor.
It's cool!
If the indexer has unresolved symbols , when build is broken, the refactoring operation can fail.
If the indexer has unresolved symbols , when build is broken, the refactoring operation can fail.
IFile file = new File("/sample/test.h"); IRegion region = ...; CRefactoringArgument arg = new CRefactoringArgument(file, region.getOffset(), region.getLength()); CRenameProcessor proc = new CRenameProcessor(CRefactory.getInstance(), arg); proc.setReplacementText("ReplacedText"); proc.setSelectedOptions(-1); proc.setScope(TextSearchWrapper.SCOPE_SINGLE_PROJECT); CRenameRefactoring refactor = new CRenameRefactoring(proc); ((CRenameProcessor)refactor.getProcessor()) .lockIndex(); try{ RefactoringStatus rs = refactor.checkInitialConditions(monitor); if (rs.hasFatalError()) { throw new Exception("checkInitialcondtion fail"); } rs = refactor.checkFinalConditions(monitor); if (rs.hasError()) { throw new Exception("checkFinalcondtion fail"); } Change change = refactor.createChange(monitor); change.perform(monitor); }finally{ ((CRenameProcessor)refactor.getProcessor()).unlockIndex(); }