blob: d5a1cc60f25b314c86a8a351385a31f504ee58d7 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2011, 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.ltk.ui.sourceediting.assist;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.ecommons.ui.actions.UIActions.NO_COMMAND_ID;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension6;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.ecommons.text.ui.DefaultBrowserInformationInput;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;
import org.eclipse.statet.ltk.ui.sourceediting.CommandAccess;
@NonNullByDefault
public abstract class CommandAssistProposal<TContext extends AssistInvocationContext>
implements AssistProposal, CommandAccess, ICompletionProposalExtension5, ICompletionProposalExtension6 {
public static class ProposalParameters<TContext extends AssistInvocationContext> {
public final TContext context;
public final String commandId;
public final String label;
public final @Nullable String description;
public int relevance;
public ProposalParameters(final TContext context, final String commandId,
final String label, final @Nullable String description,
final int relevance) {
this.context= nonNullAssert(context);
this.commandId= nonNullAssert(commandId);
this.label= nonNullAssert(label);
this.description= description;
this.relevance= relevance;
}
}
protected static class ApplyData {
private @Nullable TextRegion selectionToSet;
private @Nullable IContextInformation contextInformation;
public ApplyData() {
}
public void setSelection(final TextRegion region) {
this.selectionToSet= region;
}
public void setSelection(final int offset) {
this.selectionToSet= new BasicTextRegion(offset, offset);
}
public void setSelection(final int offset, final int length) {
assert (length >= 0);
this.selectionToSet= new BasicTextRegion(offset, offset + length);
}
public void clearSelection() {
this.selectionToSet= null;
}
public @Nullable TextRegion getSelection() {
return this.selectionToSet;
}
public void setContextInformation(final IContextInformation info) {
this.contextInformation= info;
}
public @Nullable IContextInformation getContextInformation() {
return this.contextInformation;
}
}
protected static StyledString addAcceleratorStyled(final String message,
final @Nullable KeySequence binding) {
final StyledString styledString= new StyledString(message);
if (binding != null) {
styledString.append(" (", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
styledString.append(binding.format(), StyledString.QUALIFIER_STYLER);
styledString.append(')', StyledString.QUALIFIER_STYLER);
}
return styledString;
}
private final TContext context;
private final String commandId;
private final String label;
private final @Nullable String description;
private final int relevance;
private @Nullable ApplyData applyData;
public CommandAssistProposal(final ProposalParameters<TContext> parameters) {
this.context= parameters.context;
this.commandId= parameters.commandId;
this.label= parameters.label;
this.description= parameters.description;
this.relevance= parameters.relevance;
}
@SuppressWarnings("null")
protected CommandAssistProposal(final TContext invocationContext, final String commandId,
final String label, final @Nullable String description) {
this.context= nonNullAssert(invocationContext);
this.commandId= nonNullAssert(commandId);
this.label= label;
this.description= description;
this.relevance= 0;
}
@Override
public final String getCommandId() {
return this.commandId;
}
protected final TContext getInvocationContext() {
return this.context;
}
protected final ApplyData getApplyData() {
ApplyData applyData= this.applyData;
if (applyData == null) {
applyData= createApplyData();
this.applyData= applyData;
}
return applyData;
}
protected ApplyData createApplyData() {
return new ApplyData();
}
@Override
public int getRelevance() {
return this.relevance;
}
@Override
public String getSortingString() {
return this.label;
}
@Override
public @Nullable Image getImage() {
return null;
}
@Override
public String getDisplayString() {
return this.label;
}
@Override
public StyledString getStyledDisplayString() {
return addAcceleratorStyled(getDisplayString(), (this.commandId != NO_COMMAND_ID) ?
WorkbenchUIUtils.getBestKeyBinding(this.commandId) :
null );
}
@Override
public boolean validate(final IDocument document, final int offset,
final @Nullable DocumentEvent event) {
return false;
}
@Override
public @Nullable String getAdditionalProposalInfo() {
return this.description;
}
@Override
public @Nullable Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
final var description= this.description;
if (description == null) {
return null;
}
return new DefaultBrowserInformationInput(getDisplayString(),
description, DefaultBrowserInformationInput.FORMAT_TEXT_INPUT );
}
@Override
public void apply(final IDocument document) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable Point getSelection(final IDocument document) {
final var applyData= this.applyData;
if (applyData != null) {
final TextRegion selection= applyData.getSelection();
if (selection != null) {
return new Point(selection.getStartOffset(), selection.getLength());
}
}
return null;
}
@Override
public @Nullable IContextInformation getContextInformation() {
return null;
}
}