blob: a4b3e0c8e2ba360e085ae44c551901601fc5306b [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.text.ui.presentation;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
@NonNullByDefault
public class FixTokenScanner implements ITokenScanner {
private final TextStyleManager<?> textStyles;
private final IToken defaultToken;
private ImList<ITypedRegion> styleRegions;
private int documentStartOffset;
private int documentEndOffset;
private int regionIdx;
private int tokenOffset;
private int tokenLength;
public FixTokenScanner(final TextStyleManager<?> textStyles, final String defaultTokenKey) {
this.textStyles= textStyles;
this.defaultToken= textStyles.getToken(defaultTokenKey);
this.styleRegions= ImCollections.emptyList();
}
public void setStyleRegions(final ImList<ITypedRegion> regions) {
this.styleRegions= regions;
this.regionIdx= 0;
}
@Override
public void setRange(final IDocument document, final int offset, final int length) {
this.documentStartOffset= offset;
this.documentEndOffset= length;
this.regionIdx= 0;
this.tokenOffset= offset;
this.tokenLength= 0;
}
@Override
public IToken nextToken() {
this.tokenOffset+= this.tokenLength;
if (this.tokenOffset == this.documentEndOffset) {
return Token.EOF;
}
final ITypedRegion region= nextRegion();
if (region != null) {
if (this.tokenOffset >= region.getOffset()) {
setTokenEndOffset(region.getOffset() + region.getLength());
return this.textStyles.getToken(region.getType());
}
setTokenEndOffset(region.getOffset());
return this.defaultToken;
}
else {
setTokenEndOffset(Integer.MAX_VALUE);
return this.defaultToken;
}
}
private @Nullable ITypedRegion nextRegion() {
for (int idx= this.regionIdx; idx < this.styleRegions.size(); idx++) {
final ITypedRegion region= this.styleRegions.get(idx);
if (this.tokenOffset < region.getOffset() + region.getLength()) {
this.regionIdx= idx;
return region;
}
}
return null;
}
private void setTokenEndOffset(final int offset) {
this.tokenLength= Math.min(offset, this.documentEndOffset) - this.tokenOffset;
}
@Override
public int getTokenOffset() {
return this.tokenOffset;
}
@Override
public int getTokenLength() {
return this.tokenLength;
}
}