💄 selection count

This commit is contained in:
2026-05-22 22:07:17 +10:00
parent c56cc15207
commit 6b9eb388ba
4 changed files with 32 additions and 2 deletions

View File

@@ -697,7 +697,15 @@ export function MarkdownEditor(): JSX.Element {
} }
if (update.selectionSet) { if (update.selectionSet) {
const { from, to } = update.state.selection.main const { from, to } = update.state.selection.main
setHasSelection(from !== to) const hasNonEmpty = from !== to
setHasSelection(hasNonEmpty)
if (hasNonEmpty) {
const sel = update.state.sliceDoc(from, to)
const words = sel.trim() === '' ? 0 : sel.trim().split(/\s+/).length
useEditorStore.getState().setSelectionWordCount(words)
} else {
useEditorStore.getState().setSelectionWordCount(null)
}
} }
// When the user Cmd+Z's through an Apply, invertedEffects fires a // When the user Cmd+Z's through an Apply, invertedEffects fires a
// setAnnotationsEffect restoring the old list inside CM. Sync that // setAnnotationsEffect restoring the old list inside CM. Sync that

View File

@@ -79,7 +79,8 @@ export function AnalysisToolbar(): JSX.Element {
outlineOpen, outlineOpen,
toggleOutline, toggleOutline,
revisionPanelOpen, revisionPanelOpen,
toggleRevisionPanel toggleRevisionPanel,
selectionWordCount
} = useEditorStore() } = useEditorStore()
const [analyzeOpen, setAnalyzeOpen] = useState(false) const [analyzeOpen, setAnalyzeOpen] = useState(false)
@@ -381,6 +382,11 @@ export function AnalysisToolbar(): JSX.Element {
A+ A+
</button> </button>
</div> </div>
{selectionWordCount !== null && (
<span className="toolbar-selection-wordcount" title={`${selectionWordCount} words selected`}>
{formatWordCount(selectionWordCount)} sel
</span>
)}
{activeFilePath && ( {activeFilePath && (
<span <span
className="toolbar-wordcount" className="toolbar-wordcount"

View File

@@ -142,6 +142,17 @@
opacity: 0.5; opacity: 0.5;
} }
.toolbar-selection-wordcount {
color: var(--text-muted);
font-size: 11px;
font-family: var(--font-sans);
white-space: nowrap;
flex-shrink: 0;
cursor: default;
opacity: 0.6;
letter-spacing: 0.02em;
}
/* ── Outline toggle button ───────────────────────────────────────── */ /* ── Outline toggle button ───────────────────────────────────────── */
.toolbar-btn-outline { .toolbar-btn-outline {
padding: 4px 8px; padding: 4px 8px;

View File

@@ -63,6 +63,8 @@ interface EditorState {
// Word counts // Word counts
projectWordCount: number projectWordCount: number
setProjectWordCount: (count: number) => void setProjectWordCount: (count: number) => void
selectionWordCount: number | null
setSelectionWordCount: (count: number | null) => void
// Editor font size // Editor font size
fontSize: number fontSize: number
@@ -593,6 +595,9 @@ export const useEditorStore = create<EditorState>((set, get) => ({
projectWordCount: 0, projectWordCount: 0,
setProjectWordCount: (projectWordCount) => set({ projectWordCount }), setProjectWordCount: (projectWordCount) => set({ projectWordCount }),
selectionWordCount: null as number | null,
setSelectionWordCount: (count: number | null) => set({ selectionWordCount: count }),
revisionPanelOpen: false, revisionPanelOpen: false,
toggleRevisionPanel: () => set((s) => ({ revisionPanelOpen: !s.revisionPanelOpen })), toggleRevisionPanel: () => set((s) => ({ revisionPanelOpen: !s.revisionPanelOpen })),