💄 display number of words in sentence

This commit is contained in:
TC
2026-06-14 20:58:38 +10:00
parent 2f584f669c
commit 57673d5d65

View File

@@ -677,6 +677,22 @@ function countWords(text: string): number {
return text.trim() === '' ? 0 : text.trim().split(/\s+/).length
}
function getSentenceWordCount(text: string, pos: number): number {
// Scan back to find sentence start (after .!? followed by space, or paragraph break, or doc start)
let start = 0
for (let i = pos - 1; i >= 0; i--) {
if (text[i] === '\n' && i > 0 && text[i - 1] === '\n') { start = i + 1; break }
if (/[.!?]/.test(text[i]) && i + 1 < text.length && /\s/.test(text[i + 1])) { start = i + 1; break }
}
// Scan forward to find sentence end
let end = text.length
for (let i = pos; i < text.length; i++) {
if (text[i] === '\n' && i + 1 < text.length && text[i + 1] === '\n') { end = i; break }
if (/[.!?]/.test(text[i])) { end = i + 1; break }
}
return countWords(text.slice(start, end))
}
export function MarkdownEditor(): JSX.Element {
const containerRef = useRef<HTMLDivElement>(null)
const viewRef = useRef<EditorView | null>(null)
@@ -685,6 +701,7 @@ export function MarkdownEditor(): JSX.Element {
const [pendingComment, setPendingComment] = useState<{ from: number; to: number; text: string } | null>(null)
const [commentDraft, setCommentDraft] = useState('')
const [wordStats, setWordStats] = useState<{ atCursor: number; total: number }>({ atCursor: 0, total: 0 })
const [sentenceWordCount, setSentenceWordCount] = useState<number>(0)
const wordTotalRef = useRef(0)
const { activeFilePath, activeFileContent, setContent, annotations, fontSize, theme, focusMode, scrollPositions, pendingScrollToLine, clearPendingScrollToLine, selectionWordCount, projectWordCount } = useEditorStore()
@@ -836,6 +853,8 @@ export function MarkdownEditor(): JSX.Element {
useEditorStore.getState().setSelectionWordCount(words)
} else {
useEditorStore.getState().setSelectionWordCount(null)
const text = update.state.doc.toString()
setSentenceWordCount(getSentenceWordCount(text, to))
}
}
// When the user Cmd+Z's through an Apply, invertedEffects fires a
@@ -1147,9 +1166,11 @@ export function MarkdownEditor(): JSX.Element {
{activeFilePath && (
<div className="editor-statusbar">
<span>word {wordStats.atCursor.toLocaleString()} of {wordStats.total.toLocaleString()}</span>
{selectionWordCount !== null && (
{selectionWordCount !== null ? (
<span className="statusbar-selection-wordcount">{selectionWordCount.toLocaleString()} selected</span>
)}
) : sentenceWordCount > 0 ? (
<span className="statusbar-selection-wordcount">{sentenceWordCount} in sentence</span>
) : null}
<div className="statusbar-right">
{(() => {
const docWc = countWords(activeFileContent)