editor status bar with behaviour
This commit is contained in:
parent
eb2520fa40
commit
e82d3e90b4
@ -101,7 +101,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-status-chip-type-pbs {
|
.editor-workspace-status-chip-type-pbs {
|
||||||
-fx-background-color: #1e2d3b;
|
-fx-background-color: #2c2140;
|
||||||
-fx-border-color: #4aa3ff;
|
-fx-border-color: #a47dff;
|
||||||
-fx-text-fill: #dce9f8;
|
-fx-text-fill: #efe6ff;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public final class EditorStatusBar extends HBox {
|
public final class EditorStatusBar extends HBox {
|
||||||
|
private static final String DEFAULT_INDENTATION = "Spaces: 4";
|
||||||
private final HBox breadcrumb = new HBox(6);
|
private final HBox breadcrumb = new HBox(6);
|
||||||
private final Label position = new Label();
|
private final Label position = new Label();
|
||||||
private final Label lineSeparator = new Label();
|
private final Label lineSeparator = new Label();
|
||||||
@ -61,9 +62,8 @@ public final class EditorStatusBar extends HBox {
|
|||||||
final EditorDocumentPresentation presentation) {
|
final EditorDocumentPresentation presentation) {
|
||||||
showBreadcrumb(projectReference, fileBuffer.path());
|
showBreadcrumb(projectReference, fileBuffer.path());
|
||||||
showMetadata(true);
|
showMetadata(true);
|
||||||
bindDefault(position, I18n.CODE_EDITOR_STATUS_POSITION);
|
showPosition(fileBuffer.editable(), 1, 1);
|
||||||
setText(lineSeparator, fileBuffer.lineSeparator());
|
showDocumentFormatting(fileBuffer.lineSeparator(), fileBuffer.content());
|
||||||
bindDefault(indentation, I18n.CODE_EDITOR_STATUS_INDENTATION);
|
|
||||||
setText(language, fileBuffer.typeId());
|
setText(language, fileBuffer.typeId());
|
||||||
EditorDocumentPresentationStyles.applyToStatusChip(language, presentation);
|
EditorDocumentPresentationStyles.applyToStatusChip(language, presentation);
|
||||||
showAccessMode(fileBuffer.readOnly());
|
showAccessMode(fileBuffer.readOnly());
|
||||||
@ -72,7 +72,7 @@ public final class EditorStatusBar extends HBox {
|
|||||||
public void showPlaceholder(final EditorDocumentPresentation presentation) {
|
public void showPlaceholder(final EditorDocumentPresentation presentation) {
|
||||||
breadcrumb.getChildren().clear();
|
breadcrumb.getChildren().clear();
|
||||||
showMetadata(false);
|
showMetadata(false);
|
||||||
bindDefault(position, I18n.CODE_EDITOR_STATUS_POSITION);
|
showPosition(false, 1, 1);
|
||||||
bindDefault(lineSeparator, I18n.CODE_EDITOR_STATUS_LINE_SEPARATOR);
|
bindDefault(lineSeparator, I18n.CODE_EDITOR_STATUS_LINE_SEPARATOR);
|
||||||
bindDefault(indentation, I18n.CODE_EDITOR_STATUS_INDENTATION);
|
bindDefault(indentation, I18n.CODE_EDITOR_STATUS_INDENTATION);
|
||||||
bindDefault(language, I18n.CODE_EDITOR_STATUS_LANGUAGE);
|
bindDefault(language, I18n.CODE_EDITOR_STATUS_LANGUAGE);
|
||||||
@ -81,6 +81,18 @@ public final class EditorStatusBar extends HBox {
|
|||||||
accessMode.getStyleClass().removeAll("editor-workspace-status-chip-editable", "editor-workspace-status-chip-read-only");
|
accessMode.getStyleClass().removeAll("editor-workspace-status-chip-editable", "editor-workspace-status-chip-read-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showCaretPosition(final int line, final int column) {
|
||||||
|
if (!position.isManaged()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setText(position, line + ":" + column);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDocumentFormatting(final String separator, final String content) {
|
||||||
|
setText(lineSeparator, separator);
|
||||||
|
setText(indentation, detectIndentation(content));
|
||||||
|
}
|
||||||
|
|
||||||
private void bindDefault(final Label label, final I18n key) {
|
private void bindDefault(final Label label, final I18n key) {
|
||||||
bindText(label, key);
|
bindText(label, key);
|
||||||
}
|
}
|
||||||
@ -168,13 +180,21 @@ public final class EditorStatusBar extends HBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showMetadata(final boolean visible) {
|
private void showMetadata(final boolean visible) {
|
||||||
setVisibleManaged(position, visible);
|
|
||||||
setVisibleManaged(lineSeparator, visible);
|
setVisibleManaged(lineSeparator, visible);
|
||||||
setVisibleManaged(indentation, visible);
|
setVisibleManaged(indentation, visible);
|
||||||
setVisibleManaged(language, visible);
|
setVisibleManaged(language, visible);
|
||||||
setVisibleManaged(accessMode, visible);
|
setVisibleManaged(accessMode, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPosition(final boolean visible, final int line, final int column) {
|
||||||
|
setVisibleManaged(position, visible);
|
||||||
|
if (!visible) {
|
||||||
|
bindDefault(position, I18n.CODE_EDITOR_STATUS_POSITION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setText(position, line + ":" + column);
|
||||||
|
}
|
||||||
|
|
||||||
private void showAccessMode(final boolean readOnlyMode) {
|
private void showAccessMode(final boolean readOnlyMode) {
|
||||||
accessMode.getChildren().setAll(readOnlyMode
|
accessMode.getChildren().setAll(readOnlyMode
|
||||||
? EditorWorkspaceIcons.lockClosed()
|
? EditorWorkspaceIcons.lockClosed()
|
||||||
@ -195,4 +215,58 @@ public final class EditorStatusBar extends HBox {
|
|||||||
label.getStyleClass().add("editor-workspace-status-chip");
|
label.getStyleClass().add("editor-workspace-status-chip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String detectIndentation(final String content) {
|
||||||
|
final String normalized = content == null ? "" : content.replace("\r\n", "\n").replace('\r', '\n');
|
||||||
|
int spaceGcd = 0;
|
||||||
|
boolean sawTabs = false;
|
||||||
|
for (final String line : normalized.split("\n", -1)) {
|
||||||
|
if (line.isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int spaces = 0;
|
||||||
|
int tabs = 0;
|
||||||
|
while (spaces + tabs < line.length()) {
|
||||||
|
final char ch = line.charAt(spaces + tabs);
|
||||||
|
if (ch == ' ') {
|
||||||
|
if (tabs > 0) {
|
||||||
|
spaces = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spaces++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '\t') {
|
||||||
|
tabs++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tabs > 0 && spaces == 0) {
|
||||||
|
sawTabs = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (spaces > 1) {
|
||||||
|
spaceGcd = spaceGcd == 0 ? spaces : gcd(spaceGcd, spaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sawTabs) {
|
||||||
|
return "Tabs: 1";
|
||||||
|
}
|
||||||
|
if (spaceGcd > 0) {
|
||||||
|
return "Spaces: " + spaceGcd;
|
||||||
|
}
|
||||||
|
return DEFAULT_INDENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int gcd(final int left, final int right) {
|
||||||
|
int a = Math.abs(left);
|
||||||
|
int b = Math.abs(right);
|
||||||
|
while (b != 0) {
|
||||||
|
final int next = a % b;
|
||||||
|
a = b;
|
||||||
|
b = next;
|
||||||
|
}
|
||||||
|
return a == 0 ? 1 : a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,8 +75,11 @@ public final class EditorWorkspace extends Workspace {
|
|||||||
codeArea.setEditable(false);
|
codeArea.setEditable(false);
|
||||||
codeArea.setWrapText(false);
|
codeArea.setWrapText(false);
|
||||||
codeArea.textProperty().addListener((ignored, previous, current) -> syncActiveDocumentToVfs(current));
|
codeArea.textProperty().addListener((ignored, previous, current) -> syncActiveDocumentToVfs(current));
|
||||||
codeArea.caretPositionProperty().addListener((ignored, previous, current) ->
|
codeArea.caretPositionProperty().addListener((ignored, previous, current) -> {
|
||||||
updateActiveGuides(current == null ? 0 : current.intValue()));
|
final int caretOffset = current == null ? 0 : current.intValue();
|
||||||
|
updateActiveGuides(caretOffset);
|
||||||
|
refreshStatusBarCaret();
|
||||||
|
});
|
||||||
codeArea.getStyleClass().add("editor-workspace-code-area");
|
codeArea.getStyleClass().add("editor-workspace-code-area");
|
||||||
codeArea.addEventFilter(KeyEvent.KEY_PRESSED, this::guardInlineHintMutation);
|
codeArea.addEventFilter(KeyEvent.KEY_PRESSED, this::guardInlineHintMutation);
|
||||||
codeArea.addEventFilter(KeyEvent.KEY_TYPED, this::guardInlineHintMutation);
|
codeArea.addEventFilter(KeyEvent.KEY_TYPED, this::guardInlineHintMutation);
|
||||||
@ -229,6 +232,7 @@ public final class EditorWorkspace extends Workspace {
|
|||||||
EditorDocumentPresentationStyles.applyToCodeArea(codeArea, presentation);
|
EditorDocumentPresentationStyles.applyToCodeArea(codeArea, presentation);
|
||||||
refreshCommandSurfaces(fileBuffer);
|
refreshCommandSurfaces(fileBuffer);
|
||||||
statusBar.showFile(projectReference, fileBuffer, presentation);
|
statusBar.showFile(projectReference, fileBuffer, presentation);
|
||||||
|
refreshStatusBarCaret();
|
||||||
refreshSemanticOutline(fileBuffer, analysis);
|
refreshSemanticOutline(fileBuffer, analysis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +374,7 @@ public final class EditorWorkspace extends Workspace {
|
|||||||
final String sourceContent = inlineHintProjection.stripDecorations(content);
|
final String sourceContent = inlineHintProjection.stripDecorations(content);
|
||||||
final VfsDocumentOpenResult.VfsTextDocument updatedDocument = vfsProjectDocument.updateDocument(activeFile.path(), sourceContent);
|
final VfsDocumentOpenResult.VfsTextDocument updatedDocument = vfsProjectDocument.updateDocument(activeFile.path(), sourceContent);
|
||||||
openFileSession.open(bufferFrom(updatedDocument));
|
openFileSession.open(bufferFrom(updatedDocument));
|
||||||
|
statusBar.showDocumentFormatting(updatedDocument.lineSeparator(), updatedDocument.content());
|
||||||
tabStrip.showOpenFiles(
|
tabStrip.showOpenFiles(
|
||||||
openFileSession.openFiles(),
|
openFileSession.openFiles(),
|
||||||
openFileSession.activeFile().map(EditorOpenFileBuffer::path).orElse(null));
|
openFileSession.activeFile().map(EditorOpenFileBuffer::path).orElse(null));
|
||||||
@ -473,6 +478,14 @@ public final class EditorWorkspace extends Workspace {
|
|||||||
refreshParagraphGraphics();
|
refreshParagraphGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshStatusBarCaret() {
|
||||||
|
openFileSession.activeFile()
|
||||||
|
.filter(EditorOpenFileBuffer::editable)
|
||||||
|
.ifPresent(ignored -> statusBar.showCaretPosition(
|
||||||
|
codeArea.getCurrentParagraph() + 1,
|
||||||
|
codeArea.getCaretColumn() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
private void guardInlineHintMutation(final KeyEvent event) {
|
private void guardInlineHintMutation(final KeyEvent event) {
|
||||||
if (syncingEditor || !codeArea.isEditable()) {
|
if (syncingEditor || !codeArea.isEditable()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user