Skip to content

Fixes #5273. Code block partial selection should not include fence delimiters#5280

Closed
YourRobotOverlord wants to merge 2 commits into
gui-cs:developfrom
YourRobotOverlord:fix/5273-code-block-selection-fences
Closed

Fixes #5273. Code block partial selection should not include fence delimiters#5280
YourRobotOverlord wants to merge 2 commits into
gui-cs:developfrom
YourRobotOverlord:fix/5273-code-block-selection-fences

Conversation

@YourRobotOverlord
Copy link
Copy Markdown
Collaborator

Copilot Session

cc36ca80-1ae3-4e1c-a9f7-6230152a804e

Summary

Fixes #5273. When copying a partial selection from inside a fenced code block in MarkdownView, the copied text should not include fence delimiters (```lang / ```) unless the selection actually crosses a code-block boundary.

Behavior

Selection Result
Entirely inside code block No fences
Starts before block, ends inside Opening fence only
Starts inside block, ends after Closing fence only
Spans the full block Both fences

Root Cause

In GetSelectedText(), the opening fence was unconditionally injected when first entering a code block, and a trailing closing fence was always appended at the end. This caused partial selections inside a block to include unwanted fence delimiters.

Fix

Rewrote the fence-injection logic in MarkdownView.Selection.cs:

  • Added selectionHasNonCodeContent flag: the opening fence is only emitted when entering a code block after non-code content has been seen.
  • Mid-loop closing fence (code→non-code transition) is now unconditional.
  • Trailing fence (selection ends inside code block) was removed entirely.

Tests

Added/updated tests in MarkdownViewSelectionTests.cs covering all four scenarios:

  • PartialSelection_InsideCodeBlock_DoesNotIncludeFenceDelimiters
  • PartialSelection_StartBeforeCodeBlock_EndInside_HasOpeningFenceOnly
  • PartialSelection_StartInsideCodeBlock_EndAfter_HasClosingFenceOnly
  • PartialSelection_AllLinesOfCodeBlock_FromFirstLine_NoFences

…nce delimiters

When copying a partial selection that starts or ends inside a fenced code
block, the copied text should not include the fence delimiters unless the
selection actually crosses from non-code content into the code block.

Root cause: GetSelectedText() unconditionally injected the opening fence
whenever it first encountered a code-block line, and unconditionally
injected the closing fence at the end of the loop if still inside a code
block. This meant any selection touching a code block line would include
fences, even if the selection was entirely within the code block.

Fix: Replace the unconditional fence injection with two tracking flags:
- selectionHasNonCodeContent: set true when any non-code line is processed.
  Opening fence is only emitted when transitioning from non-code -> code.
- codeOpenFenceEmitted: tracks whether an opening fence was actually
  emitted for the current code block. Closing fence is only emitted when
  the matching opening fence was emitted.

This ensures:
- Selection entirely within a code block -> no fences (regardless of position)
- Selection starting before a code block -> opening fence included
- Selection ending after a code block -> closing fence included

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #5273 by adjusting MarkdownView partial-selection copy logic so fenced code-block delimiters are only included when the selection actually crosses into/out of a code-block boundary, matching expected clipboard behavior.

Changes:

  • Reworked GetSelectedText() fence injection to avoid emitting fences for selections entirely inside a code block.
  • Removed the unconditional trailing closing fence for selections ending mid-code-block.
  • Added/updated unit tests covering the four selection scenarios described in the issue.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
Terminal.Gui/Views/Markdown/MarkdownView.Selection.cs Updates fence injection logic for partial selections across code-block boundaries.
Tests/UnitTestsParallelizable/Views/Markdown/MarkdownViewSelectionTests.cs Adds regression tests for partial selection behavior inside/around fenced code blocks.

Comment thread Terminal.Gui/Views/Markdown/MarkdownView.Selection.cs Outdated
Comment thread Terminal.Gui/Views/Markdown/MarkdownView.Selection.cs Outdated
Comment on lines +860 to +868
// Regression guard: selecting all lines of a code block starting from its first line should
// produce NO fence delimiters — the selection is entirely within the fenced region.
[Fact]
public void PartialSelection_AllLinesOfCodeBlock_FromFirstLine_NoFences ()
{
// Three code lines; select only the first two to avoid triggering IsFullDocumentSelected().
string md = "```csharp\nline A\nline B\nline C\n```";
(IApplication app, Runnable window, Terminal.Gui.Views.Markdown mv) = CreateMv (md, width: 60, height: 10);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@YourRobotOverlord YourRobotOverlord marked this pull request as draft May 9, 2026 02:39
@YourRobotOverlord
Copy link
Copy Markdown
Collaborator Author

Moving this to #5282 - overlapping changes.

@YourRobotOverlord YourRobotOverlord deleted the fix/5273-code-block-selection-fences branch May 9, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Markdown - Copied partial selection from inside codeblock should not contain delimiters

2 participants