💄 word number position
This commit is contained in:
@@ -4,10 +4,27 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codemirror-host {
|
.codemirror-host {
|
||||||
height: 100%;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-statusbar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 3px 14px;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
text-align: right;
|
||||||
|
opacity: 0.55;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codemirror-host .cm-editor {
|
.codemirror-host .cm-editor {
|
||||||
|
|||||||
@@ -622,6 +622,10 @@ function insertLink(view: EditorView): boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function countWords(text: string): number {
|
||||||
|
return text.trim() === '' ? 0 : text.trim().split(/\s+/).length
|
||||||
|
}
|
||||||
|
|
||||||
export function MarkdownEditor(): JSX.Element {
|
export function MarkdownEditor(): JSX.Element {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const viewRef = useRef<EditorView | null>(null)
|
const viewRef = useRef<EditorView | null>(null)
|
||||||
@@ -629,6 +633,8 @@ export function MarkdownEditor(): JSX.Element {
|
|||||||
const [hasSelection, setHasSelection] = useState(false)
|
const [hasSelection, setHasSelection] = useState(false)
|
||||||
const [pendingComment, setPendingComment] = useState<{ from: number; to: number; text: string } | null>(null)
|
const [pendingComment, setPendingComment] = useState<{ from: number; to: number; text: string } | null>(null)
|
||||||
const [commentDraft, setCommentDraft] = useState('')
|
const [commentDraft, setCommentDraft] = useState('')
|
||||||
|
const [wordStats, setWordStats] = useState<{ atCursor: number; total: number }>({ atCursor: 0, total: 0 })
|
||||||
|
const wordTotalRef = useRef(0)
|
||||||
const { activeFilePath, activeFileContent, setContent, annotations, fontSize, theme, focusMode, scrollPositions, pendingScrollToLine, clearPendingScrollToLine } = useEditorStore()
|
const { activeFilePath, activeFileContent, setContent, annotations, fontSize, theme, focusMode, scrollPositions, pendingScrollToLine, clearPendingScrollToLine } = useEditorStore()
|
||||||
|
|
||||||
function saveComment(): void {
|
function saveComment(): void {
|
||||||
@@ -694,6 +700,12 @@ export function MarkdownEditor(): JSX.Element {
|
|||||||
EditorView.updateListener.of((update) => {
|
EditorView.updateListener.of((update) => {
|
||||||
if (update.docChanged) {
|
if (update.docChanged) {
|
||||||
setContent(update.state.doc.toString())
|
setContent(update.state.doc.toString())
|
||||||
|
wordTotalRef.current = countWords(update.state.doc.toString())
|
||||||
|
}
|
||||||
|
if (update.selectionSet || update.docChanged) {
|
||||||
|
const head = update.state.selection.main.head
|
||||||
|
const atCursor = countWords(update.state.doc.sliceString(0, head))
|
||||||
|
setWordStats({ atCursor, total: wordTotalRef.current })
|
||||||
}
|
}
|
||||||
if (update.selectionSet) {
|
if (update.selectionSet) {
|
||||||
const { from, to } = update.state.selection.main
|
const { from, to } = update.state.selection.main
|
||||||
@@ -1008,6 +1020,11 @@ export function MarkdownEditor(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{activeFilePath && (
|
||||||
|
<div className="editor-statusbar">
|
||||||
|
word {wordStats.atCursor.toLocaleString()} of {wordStats.total.toLocaleString()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user