mirror of
https://github.com/h3pdesign/Neon-Vision-Editor
synced 2026-04-21 13:27:16 +00:00
docs: automate new feature spotlight and roadmap sync
This commit is contained in:
parent
b9e0d2801c
commit
853fd400f3
4 changed files with 138 additions and 17 deletions
|
|
@ -361,7 +361,7 @@
|
|||
CODE_SIGNING_ALLOWED = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 527;
|
||||
CURRENT_PROJECT_VERSION = 528;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
@ -444,7 +444,7 @@
|
|||
CODE_SIGNING_ALLOWED = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 527;
|
||||
CURRENT_PROJECT_VERSION = 528;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ struct WelcomeTourView: View {
|
|||
"Stabilized first-open rendering from the project sidebar so file content and syntax highlighting appear on first click without requiring tab switches.",
|
||||
"Hardened startup/session behavior so `Reopen Last Session` reliably wins over conflicting blank-document startup states.",
|
||||
"Refined large-file activation and loading placeholders to avoid misclassifying smaller files as large-file sessions.",
|
||||
"Fixed a session-restore regression where previously open files could appear empty on first sidebar click until changing tabs."
|
||||
"Added Share Shot (`Code Snapshot`) creation flow with toolbar + selection-context actions (`camera.viewfinder`) and a styled share/export composer."
|
||||
],
|
||||
iconName: "sparkles.rectangle.stack",
|
||||
colors: [Color(red: 0.40, green: 0.28, blue: 0.90), Color(red: 0.96, green: 0.46, blue: 0.55)],
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -96,7 +96,7 @@
|
|||
<a href="#download-metrics">Download Metrics</a> ·
|
||||
<a href="#project-docs">Project Docs</a> ·
|
||||
<a href="#features">Features</a> ·
|
||||
<a href="#share-shot-code-snapshot-highlight">Share Shot</a> ·
|
||||
<a href="#new-feature-spotlight">New Feature</a> ·
|
||||
<a href="#platform-matrix">Platform Matrix</a><br>
|
||||
<a href="#roadmap-near-term">Roadmap (Near Term)</a> ·
|
||||
<a href="#troubleshooting">Troubleshooting</a> ·
|
||||
|
|
@ -312,7 +312,13 @@ Platform-specific availability is tracked in the [Platform Matrix](#platform-mat
|
|||
- Built-in theme collection: Dracula, One Dark Pro, Nord, Tokyo Night, Gruvbox, and Neon Glow.
|
||||
- Grouped settings, optional StoreKit support flow, and AI Activity Log diagnostics on macOS.
|
||||
|
||||
## Share Shot (Code Snapshot) Highlight
|
||||
## NEW FEATURE Spotlight
|
||||
|
||||
<p align="center">
|
||||
<img alt="New Feature Release" src="https://img.shields.io/badge/NEW%20FEATURE-v0.5.5-F97316?style=for-the-badge">
|
||||
</p>
|
||||
|
||||
**Featured in v0.5.5:** Share Shot (`Code Snapshot`) creation flow with toolbar + selection-context actions (`camera.viewfinder`) and a styled share/export composer.
|
||||
|
||||
Create polished share images directly from your selected code.
|
||||
|
||||
|
|
@ -323,7 +329,7 @@ Create polished share images directly from your selected code.
|
|||
<sub>Styled export preview for social sharing, changelogs, and issue discussions.</sub>
|
||||
</p>
|
||||
|
||||
- Toolbar button: click the `camera.viewfinder` icon in the top toolbar (`Create Code Snapshot`).
|
||||
- Toolbar button: click **📷 `camera.viewfinder`** in the top toolbar (`Create Code Snapshot`).
|
||||
- Selection menu: right-click selected text and choose `Create Code Snapshot`.
|
||||
- Composer controls: choose appearance, background, frame style, line numbers, and padding.
|
||||
- Export: use `Share` to generate a PNG snapshot and share/save it.
|
||||
|
|
@ -506,28 +512,27 @@ Most editor features are shared across macOS, iOS, and iPadOS.
|
|||
## Roadmap (Near Term)
|
||||
|
||||
<p align="center">
|
||||
<img alt="Now" src="https://img.shields.io/badge/NOW-v0.5.2%20to%20v0.5.4-22C55E?style=for-the-badge">
|
||||
<img alt="Next" src="https://img.shields.io/badge/NEXT-v0.5.5%20to%20v0.5.7-F59E0B?style=for-the-badge">
|
||||
<img alt="Now" src="https://img.shields.io/badge/NOW-v0.5.3%20to%20v0.5.5-22C55E?style=for-the-badge">
|
||||
<img alt="Next" src="https://img.shields.io/badge/NEXT-v0.5.6%20to%20v0.5.8-F59E0B?style=for-the-badge">
|
||||
<img alt="Later" src="https://img.shields.io/badge/LATER-v0.6.0-0A84FF?style=for-the-badge">
|
||||
</p>
|
||||
|
||||
### Now (v0.5.2 - v0.5.4)
|
||||
### Now (v0.5.3 - v0.5.5)
|
||||
|
||||
-  updater diagnostics, large-file mode parity, CSV/TSV table mode, performance presets.
|
||||
Tracking: [Milestone 0.5.2](https://github.com/h3pdesign/Neon-Vision-Editor/milestone/3) · [#24](https://github.com/h3pdesign/Neon-Vision-Editor/issues/24) · [#25](https://github.com/h3pdesign/Neon-Vision-Editor/issues/25) · [#26](https://github.com/h3pdesign/Neon-Vision-Editor/issues/26) · [#30](https://github.com/h3pdesign/Neon-Vision-Editor/issues/30)
|
||||
-  indexed project search and Open Recent favorites.
|
||||
Tracking: [Milestone 0.5.3](https://github.com/h3pdesign/Neon-Vision-Editor/milestone/4) · [#29](https://github.com/h3pdesign/Neon-Vision-Editor/issues/29) · [#31](https://github.com/h3pdesign/Neon-Vision-Editor/issues/31)
|
||||
-  large-file open mode, deferred/plain-text sessions, and stability work for huge documents.
|
||||
Tracking: [Milestone 0.5.4](https://github.com/h3pdesign/Neon-Vision-Editor/milestone/5)
|
||||
-  first-open/sidebar rendering stabilization, session-restore hardening, and Share Shot (`Code Snapshot`) workflow polish.
|
||||
Tracking: [Milestone 0.5.5](https://github.com/h3pdesign/Neon-Vision-Editor/milestone/6) · [Release v0.5.5](https://github.com/h3pdesign/Neon-Vision-Editor/releases/tag/v0.5.5)
|
||||
|
||||
### Next (v0.5.5 - v0.5.7)
|
||||
### Next (v0.5.6 - v0.5.8)
|
||||
|
||||
-  iOS file-handler QA matrix and UI tests.
|
||||
Tracking: [Milestone 0.5.5](https://github.com/h3pdesign/Neon-Vision-Editor/milestone/6) · [#23](https://github.com/h3pdesign/Neon-Vision-Editor/issues/23)
|
||||
-  Safe Mode startup.
|
||||
Tracking: [#27](https://github.com/h3pdesign/Neon-Vision-Editor/issues/27)
|
||||
-  incremental loading for huge files.
|
||||
Tracking: [#28](https://github.com/h3pdesign/Neon-Vision-Editor/issues/28)
|
||||
-  follow-up platform polish and release hardening.
|
||||
|
||||
### Later (v0.6.0)
|
||||
|
||||
|
|
@ -633,12 +638,12 @@ Latest stable: **v0.5.5** (2026-03-16)
|
|||
|
||||
| Version | Date | Highlights | Fixes | Breaking changes | Migration |
|
||||
|---|---|---|---|---|---|
|
||||
| [`v0.5.5`](https://github.com/h3pdesign/Neon-Vision-Editor/releases/tag/v0.5.5) | 2026-03-16 | Stabilized first-open rendering from the project sidebar so file content and syntax highlighting appear on first click without requiring tab switches; Hardened startup/session behavior so `Reopen Last Session` reliably wins over conflicting blank-document startup states; Refined large-file activation and loading placeholders to avoid misclassifying smaller files as large-file sessions; Added Share Shot (`Code Snapshot`) creation via toolbar/selection action (`camera.viewfinder`) with styled export composer | a session-restore regression where previously open files could appear empty on first sidebar click until changing tabs; highlight scheduling during document-state transitions (`switch`, `finish load`, external edits) on macOS, iOS, and iPadOS; startup-default conflicts by aligning defaults and runtime startup gating between `Reopen Last Session` and `Open with Blank Document` | None noted | None required |
|
||||
| [`v0.5.5`](https://github.com/h3pdesign/Neon-Vision-Editor/releases/tag/v0.5.5) | 2026-03-16 | Stabilized first-open rendering from the project sidebar so file content and syntax highlighting appear on first click without requiring tab switches; Hardened startup/session behavior so `Reopen Last Session` reliably wins over conflicting blank-document startup states; Refined large-file activation and loading placeholders to avoid misclassifying smaller files as large-file sessions; Share Shot (`Code Snapshot`) creation flow with toolbar + selection-context actions (`camera.viewfinder`) and a styled share/export composer | a session-restore regression where previously open files could appear empty on first sidebar click until changing tabs; highlight scheduling during document-state transitions (`switch`, `finish load`, external edits) on macOS, iOS, and iPadOS; startup-default conflicts by aligning defaults and runtime startup gating between `Reopen Last Session` and `Open with Blank Document` | None noted | None required |
|
||||
| [`v0.5.4`](https://github.com/h3pdesign/Neon-Vision-Editor/releases/tag/v0.5.4) | 2026-03-13 | a dedicated large-file open mode with deferred first paint, chunked text installation, and an optional plain-text session mode for ultra-large documents | large-file responsiveness regressions across project-sidebar reopen, tab switching, line-number visibility, status metrics, and large-file editor rendering stability | None noted | None required |
|
||||
| [`v0.5.3`](https://github.com/h3pdesign/Neon-Vision-Editor/releases/tag/v0.5.3) | 2026-03-10 | a new high-readability colorful light theme preset: `Prism Daylight` (also selectable while app appearance is set to dark); double-click-to-close behavior for tabs on macOS tab strips; custom theme vibrancy by applying the vivid neon syntax profile to `Custom`, so syntax colors remain bright and saturated | toolbar-symbol contrast edge cases in dark mode where gray/black variants could appear too similar | None noted | None required |
|
||||
|
||||
- Full release history: [`CHANGELOG.md`](CHANGELOG.md)
|
||||
- Compare recent changes: [v0.5.2...v0.5.4](https://github.com/h3pdesign/Neon-Vision-Editor/compare/v0.5.2...v0.5.4)
|
||||
- Compare recent changes: [v0.5.4...v0.5.5](https://github.com/h3pdesign/Neon-Vision-Editor/compare/v0.5.4...v0.5.5)
|
||||
|
||||
## Known Limitations
|
||||
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ def sorted_latest_tags(tags: list[str], limit: int, ensure_tag: str | None = Non
|
|||
|
||||
|
||||
def build_readme_release_row(tag: str, date: str, section_body: str) -> str:
|
||||
highlights_items = extract_heading_bullets(section_body, "Highlights", limit=3)
|
||||
highlights_items = extract_heading_bullets(section_body, "Highlights", limit=4)
|
||||
if not highlights_items:
|
||||
highlights_items = extract_heading_bullets(section_body, "Added", limit=2) + extract_heading_bullets(
|
||||
section_body, "Improved", limit=1
|
||||
|
|
@ -328,6 +328,119 @@ def update_readme_whats_new_heading(readme: str, previous_tag: str | None, curre
|
|||
)
|
||||
|
||||
|
||||
def parse_stable_semver(tag: str) -> tuple[int, int, int] | None:
|
||||
match = re.fullmatch(r"v(\d+)\.(\d+)\.(\d+)", tag)
|
||||
if not match:
|
||||
return None
|
||||
return int(match.group(1)), int(match.group(2)), int(match.group(3))
|
||||
|
||||
|
||||
def update_readme_roadmap_windows(readme: str, tag: str) -> str:
|
||||
stable = parse_stable_semver(tag)
|
||||
if stable is None:
|
||||
return readme
|
||||
|
||||
major, minor, patch = stable
|
||||
now_start = max(0, patch - 2)
|
||||
now_end = patch
|
||||
next_start = patch + 1
|
||||
next_end = patch + 3
|
||||
|
||||
now_badge = (
|
||||
f'<img alt="Now" src="https://img.shields.io/badge/NOW-v{major}.{minor}.{now_start}%20to%20'
|
||||
f'v{major}.{minor}.{now_end}-22C55E?style=for-the-badge">'
|
||||
)
|
||||
next_badge = (
|
||||
f'<img alt="Next" src="https://img.shields.io/badge/NEXT-v{major}.{minor}.{next_start}%20to%20'
|
||||
f'v{major}.{minor}.{next_end}-F59E0B?style=for-the-badge">'
|
||||
)
|
||||
|
||||
readme = re.sub(
|
||||
r'(?m)^ <img alt="Now" src="https://img\.shields\.io/badge/NOW-v[^"]+">$',
|
||||
f" {now_badge}",
|
||||
readme,
|
||||
)
|
||||
readme = re.sub(
|
||||
r'(?m)^ <img alt="Next" src="https://img\.shields\.io/badge/NEXT-v[^"]+">$',
|
||||
f" {next_badge}",
|
||||
readme,
|
||||
)
|
||||
readme = re.sub(
|
||||
r"(?m)^### Now \(v\d+\.\d+\.\d+ - v\d+\.\d+\.\d+\)$",
|
||||
f"### Now (v{major}.{minor}.{now_start} - v{major}.{minor}.{now_end})",
|
||||
readme,
|
||||
)
|
||||
readme = re.sub(
|
||||
r"(?m)^### Next \(v\d+\.\d+\.\d+ - v\d+\.\d+\.\d+\)$",
|
||||
f"### Next (v{major}.{minor}.{next_start} - v{major}.{minor}.{next_end})",
|
||||
readme,
|
||||
)
|
||||
return readme
|
||||
|
||||
|
||||
def update_readme_compare_link(readme: str, prev_tag: str | None, current_tag: str) -> str:
|
||||
if not prev_tag:
|
||||
return readme
|
||||
return re.sub(
|
||||
r"(?m)^- Compare recent changes: \[v[^]]+\.\.\.v[^]]+\]\(https://github\.com/h3pdesign/Neon-Vision-Editor/compare/v[^)]+\)$",
|
||||
(
|
||||
f"- Compare recent changes: [{prev_tag}...{current_tag}]"
|
||||
f"(https://github.com/h3pdesign/Neon-Vision-Editor/compare/{prev_tag}...{current_tag})"
|
||||
),
|
||||
readme,
|
||||
)
|
||||
|
||||
|
||||
def pick_feature_spotlight(section_body: str) -> str:
|
||||
highlight_items = extract_heading_bullets(section_body, "Highlights", limit=8)
|
||||
preferred_keywords = ("share shot", "code snapshot", "camera.viewfinder", "snapshot")
|
||||
for item in highlight_items:
|
||||
lowered = item.lower()
|
||||
if any(keyword in lowered for keyword in preferred_keywords):
|
||||
cleaned = clean_release_cell_item(item)
|
||||
if cleaned:
|
||||
return cleaned
|
||||
for item in highlight_items:
|
||||
cleaned = clean_release_cell_item(item)
|
||||
if cleaned:
|
||||
return cleaned
|
||||
|
||||
added_items = extract_heading_bullets(section_body, "Added", limit=8)
|
||||
for item in added_items:
|
||||
lowered = item.lower()
|
||||
if any(keyword in lowered for keyword in preferred_keywords):
|
||||
cleaned = clean_release_cell_item(item)
|
||||
if cleaned:
|
||||
return cleaned
|
||||
for item in added_items:
|
||||
cleaned = clean_release_cell_item(item)
|
||||
if cleaned:
|
||||
return cleaned
|
||||
|
||||
fallback = summarize_section(section_body, limit=1)
|
||||
if fallback:
|
||||
return clean_release_cell_item(fallback[0][2:].strip())
|
||||
return "See CHANGELOG.md release highlights."
|
||||
|
||||
|
||||
def update_readme_feature_spotlight(readme: str, tag: str, section_body: str) -> str:
|
||||
feature_text = pick_feature_spotlight(section_body).rstrip(".")
|
||||
badge = f'https://img.shields.io/badge/NEW%20FEATURE-{tag}-F97316?style=for-the-badge'
|
||||
featured_line = f"**Featured in {tag}:** {feature_text}."
|
||||
|
||||
readme = re.sub(
|
||||
r'(?m)^ <img alt="New Feature Release" src="https://img\.shields\.io/badge/NEW%20FEATURE-v[^"]+">$',
|
||||
f' <img alt="New Feature Release" src="{badge}">',
|
||||
readme,
|
||||
)
|
||||
readme = re.sub(
|
||||
r"(?m)^\*\*Featured in v[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9.]+)?:\*\* .*$",
|
||||
featured_line,
|
||||
readme,
|
||||
)
|
||||
return readme
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Prepare README and CHANGELOG for a release tag.")
|
||||
parser.add_argument("tag", help="Release tag, e.g. v0.4.6")
|
||||
|
|
@ -364,6 +477,9 @@ def main() -> int:
|
|||
readme = update_readme_release_refs(original_readme, tag)
|
||||
prev_tag = previous_release_tag(changelog, tag)
|
||||
readme = update_readme_whats_new_heading(readme, prev_tag, tag)
|
||||
readme = update_readme_roadmap_windows(readme, tag)
|
||||
readme = update_readme_compare_link(readme, prev_tag, tag)
|
||||
readme = update_readme_feature_spotlight(readme, tag, section)
|
||||
readme = update_readme_latest_stable_line(readme, tag, changelog)
|
||||
readme = rebuild_readme_changelog_table(readme, changelog, tag, limit=3)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue