selection char and line break count

This commit is contained in:
Matt Parker
2025-12-18 11:54:17 +10:00
parent a1cb792375
commit bc5468cd64
4 changed files with 47 additions and 0 deletions

View File

@@ -6,4 +6,5 @@
public class EditorCaretPositionService public class EditorCaretPositionService
{ {
public (int, int) CaretPosition { get; set; } = (1, 1); public (int, int) CaretPosition { get; set; } = (1, 1);
public (int characters, int lineBreaks)? SelectionInfo { get; set; }
} }

View File

@@ -6,13 +6,18 @@ namespace SharpIDE.Godot.Features.BottomBar;
public partial class EditorLineCharDisplay : HBoxContainer public partial class EditorLineCharDisplay : HBoxContainer
{ {
private Label _label = null!; private Label _label = null!;
private Label _selectionInfoLabel = null!;
[Inject] private readonly EditorCaretPositionService _editorCaretPositionService = null!; [Inject] private readonly EditorCaretPositionService _editorCaretPositionService = null!;
private (int, int) _currentPositionRendered = (1, 1); private (int, int) _currentPositionRendered = (1, 1);
private (int characters, int lineBreaks)? _currentSelectionInfo;
public override void _Ready() public override void _Ready()
{ {
_label = GetNode<Label>("Label"); _label = GetNode<Label>("Label");
_selectionInfoLabel = GetNode<Label>("%SelectionInfoLabel");
_label.Text = null;
_selectionInfoLabel.Text = null;
} }
// Not sure if we should check this every frame, or an event with debouncing? // Not sure if we should check this every frame, or an event with debouncing?
@@ -24,5 +29,20 @@ public partial class EditorLineCharDisplay : HBoxContainer
_currentPositionRendered = caretPosition; _currentPositionRendered = caretPosition;
_label.Text = $"{_currentPositionRendered.Item1}:{_currentPositionRendered.Item2}"; _label.Text = $"{_currentPositionRendered.Item1}:{_currentPositionRendered.Item2}";
} }
if (_editorCaretPositionService.SelectionInfo != _currentSelectionInfo)
{
_currentSelectionInfo = _editorCaretPositionService.SelectionInfo;
if (_currentSelectionInfo is not null)
{
var characters = _currentSelectionInfo.Value.characters;
var lineBreaks = _currentSelectionInfo.Value.lineBreaks;
_selectionInfoLabel.Text = lineBreaks > 0 ? $"({characters} chars, {lineBreaks} line breaks)" : $"({characters} chars)";
_selectionInfoLabel.Visible = true;
}
else
{
_selectionInfoLabel.Visible = false;
}
}
} }
} }

View File

@@ -15,3 +15,10 @@ layout_mode = 2
theme_override_colors/font_color = Color(0.67058825, 0.67058825, 0.67058825, 1) theme_override_colors/font_color = Color(0.67058825, 0.67058825, 0.67058825, 1)
theme_override_font_sizes/font_size = 14 theme_override_font_sizes/font_size = 14
text = "65:71" text = "65:71"
[node name="SelectionInfoLabel" type="Label" parent="."]
unique_name_in_owner = true
layout_mode = 2
theme_override_colors/font_color = Color(0.67058825, 0.67058825, 0.67058825, 1)
theme_override_font_sizes/font_size = 14
text = "(5 chars, 2 line breaks)"

View File

@@ -210,6 +210,25 @@ public partial class SharpIdeCodeEdit : CodeEdit
private void OnCaretChanged() private void OnCaretChanged()
{ {
var caretPosition = GetCaretPosition(startAt1: true); var caretPosition = GetCaretPosition(startAt1: true);
if (HasSelection())
{
// Probably should be debounced
var selectedText = GetSelectedText();
var lineBreakCount = 0;
var slashRsToRemove = 0;
foreach (var c in selectedText.AsSpan())
{
if (c is '\n') lineBreakCount++;
else if (c is '\r') slashRsToRemove++;
}
var charLength = selectedText.Length - lineBreakCount - slashRsToRemove;
_editorCaretPositionService.SelectionInfo = (charLength, lineBreakCount);
}
else
{
_editorCaretPositionService.SelectionInfo = null;
}
_editorCaretPositionService.CaretPosition = caretPosition; _editorCaretPositionService.CaretPosition = caretPosition;
} }