|
| 1 | +import { EditorView } from '@codemirror/view'; |
1 | 2 | import type { LanguageName } from '@uiw/codemirror-extensions-langs'; |
2 | 3 | import type { Extension, ReactCodeMirrorRef } from '@uiw/react-codemirror'; |
3 | 4 | import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; |
@@ -38,6 +39,7 @@ export const useCollab = (roomId: string) => { |
38 | 39 | const [code, setCode] = useState(''); |
39 | 40 | const [language, _setLanguage] = useState<LanguageName>('python'); |
40 | 41 | const [members, _setMembers] = useState<Array<IYjsUserState['user']>>([]); |
| 42 | + const [cursorPosition, setCursorPosition] = useState({ lineNum: 1, colNum: 0 }); |
41 | 43 | const setMembers = useCallback(_setMembers, [members]); |
42 | 44 | const setLanguage = useCallback( |
43 | 45 | (lang: LanguageName) => { |
@@ -92,9 +94,19 @@ export const useCollab = (roomId: string) => { |
92 | 94 | }; |
93 | 95 | awareness.setLocalStateField('user', userState); |
94 | 96 |
|
| 97 | + const lNumExt = EditorView.updateListener.of((up) => { |
| 98 | + if (up.selectionSet) { |
| 99 | + const { head } = up.state.selection.main; |
| 100 | + const curline = up.state.doc.lineAt(head); |
| 101 | + const lineNum = Math.max(curline.number, 1); |
| 102 | + const colNum = head - curline.from; |
| 103 | + setCursorPosition({ lineNum, colNum }); |
| 104 | + } |
| 105 | + }); |
| 106 | + |
95 | 107 | const collabExt = yCollab(yText, awareness, { undoManager }); |
96 | 108 | setCode(yText.toString()); |
97 | | - setExtensions([...extensions, collabExt]); |
| 109 | + setExtensions([...extensions, collabExt, lNumExt]); |
98 | 110 |
|
99 | 111 | // Initialise room preferences |
100 | 112 | const yState = doc.getMap('state'); |
@@ -127,5 +139,6 @@ export const useCollab = (roomId: string) => { |
127 | 139 | setCode, |
128 | 140 | members, |
129 | 141 | isLoading, |
| 142 | + cursorPosition, |
130 | 143 | }; |
131 | 144 | }; |
0 commit comments