mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-03-27 12:28:11 +00:00
fix brewjump functions
This commit is contained in:
@@ -76,12 +76,12 @@ const createHighlightPlugin = (renderer, tab)=>{
|
||||
|
||||
} else {
|
||||
decos.push(Decoration.line({ class: `cm-${tok.type}` }).range(line.from));
|
||||
if(tok.type === 'pageLine' && tab === "brewText") {
|
||||
if(tok.type === 'pageLine' && tab === 'brewText') {
|
||||
pageCount++;
|
||||
line.from === 0 && pageCount--;
|
||||
decos.push(Decoration.widget({ widget: new countWidget(pageCount), side: 2 }).range(line.to));
|
||||
}
|
||||
if(tok.type === 'snippetLine' && tab === "brewSnippets") {
|
||||
if(tok.type === 'snippetLine' && tab === 'brewSnippets') {
|
||||
snippetCount++;
|
||||
decos.push(Decoration.widget({ widget: new countWidget(snippetCount), side: 2 }).range(line.to));
|
||||
}
|
||||
@@ -101,6 +101,8 @@ const CodeEditor = forwardRef(
|
||||
{
|
||||
value = '',
|
||||
onChange = ()=>{},
|
||||
onCursorChange = ()=>{},
|
||||
onViewChange = ()=>{},
|
||||
language = '',
|
||||
tab = 'brewText',
|
||||
editorTheme = 'default',
|
||||
@@ -121,6 +123,18 @@ const CodeEditor = forwardRef(
|
||||
if(update.docChanged) {
|
||||
onChange(update.state.doc.toString());
|
||||
}
|
||||
if(update.selectionSet) {
|
||||
const pos = update.state.selection.main.head;
|
||||
const line = update.state.doc.lineAt(pos).number;
|
||||
|
||||
onCursorChange(line);
|
||||
}
|
||||
if(update.viewportChanged) {
|
||||
const { from } = update.view.viewport;
|
||||
const line = update.state.doc.lineAt(from).number;
|
||||
|
||||
onViewChange(line);
|
||||
}
|
||||
});
|
||||
|
||||
const highlightExtension = renderer === 'V3'
|
||||
@@ -267,9 +281,29 @@ const CodeEditor = forwardRef(
|
||||
|
||||
getCursorPosition : ()=>viewRef.current.state.selection.main.head,
|
||||
|
||||
setCursorPosition : (pos)=>{
|
||||
viewRef.current.dispatch({ selection: { anchor: pos } });
|
||||
viewRef.current.focus();
|
||||
getScrollTop : ()=>viewRef.current.scrollDOM.scrollTop,
|
||||
|
||||
scrollToY : (y)=>{
|
||||
viewRef.current.scrollDOM.scrollTo({ top: y });
|
||||
},
|
||||
|
||||
getLineTop : (lineNumber)=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return 0;
|
||||
|
||||
const line = view.state.doc.line(lineNumber);
|
||||
return view.coordsAtPos(line.from)?.top ?? 0;
|
||||
},
|
||||
|
||||
setCursorToLine : (lineNumber)=>{
|
||||
const view = viewRef.current;
|
||||
const line = view.state.doc.line(lineNumber);
|
||||
|
||||
view.dispatch({
|
||||
selection : { anchor: line.from }
|
||||
});
|
||||
|
||||
view.focus();
|
||||
},
|
||||
|
||||
undo : ()=>undo(viewRef.current),
|
||||
|
||||
@@ -75,9 +75,6 @@ const Editor = createReactClass({
|
||||
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
|
||||
document.addEventListener('keydown', this.handleControlKeys);
|
||||
|
||||
this.codeEditor.current.codeMirror?.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
|
||||
this.codeEditor.current.codeMirror?.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
|
||||
|
||||
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
|
||||
if(editorTheme) {
|
||||
this.setState({
|
||||
@@ -130,15 +127,15 @@ const Editor = createReactClass({
|
||||
}
|
||||
},
|
||||
|
||||
updateCurrentCursorPage : function(cursor) {
|
||||
const lines = this.props.brew.text.split('\n').slice(1, cursor.line + 1);
|
||||
updateCurrentCursorPage : function(lineNumber) {
|
||||
const lines = this.props.brew.text.split('\n').slice(0, lineNumber);
|
||||
const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/;
|
||||
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
|
||||
this.props.onCursorPageChange(currentPage);
|
||||
},
|
||||
|
||||
updateCurrentViewPage : function(topScrollLine) {
|
||||
const lines = this.props.brew.text.split('\n').slice(1, topScrollLine + 1);
|
||||
updateCurrentViewPage : function(topLine) {
|
||||
const lines = this.props.brew.text.split('\n').slice(0, topLine);
|
||||
const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/;
|
||||
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
|
||||
this.props.onViewPageChange(currentPage);
|
||||
@@ -205,51 +202,41 @@ const Editor = createReactClass({
|
||||
|
||||
const textSplit = this.props.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/;
|
||||
const textString = this.props.brew.text.split(textSplit).slice(0, targetPage-1).join(textSplit);
|
||||
const targetLine = textString.match('\n') ? textString.split('\n').length - 1 : -1;
|
||||
const targetLine = textString.match('\n') ? textString.split('\n').length : 1;
|
||||
|
||||
let currentY = this.codeEditor.current.codeMirror?.getScrollInfo().top;
|
||||
let targetY = this.codeEditor.current.codeMirror?.heightAtLine(targetLine, 'local', true);
|
||||
const editor = this.codeEditor.current;
|
||||
|
||||
let currentY = editor.getScrollTop();
|
||||
const targetY = editor.getLineTop(targetLine);
|
||||
|
||||
let scrollingTimeout;
|
||||
const checkIfScrollComplete = ()=>{ // Prevent interrupting a scroll in progress if user clicks multiple times
|
||||
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
||||
scrollingTimeout = setTimeout(()=>{
|
||||
isJumping = false;
|
||||
this.codeEditor.current.codeMirror?.off('scroll', checkIfScrollComplete);
|
||||
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
|
||||
};
|
||||
|
||||
isJumping = true;
|
||||
checkIfScrollComplete();
|
||||
if(this.codeEditor.current?.codeMirror) {
|
||||
this.codeEditor.current.codeMirror?.on('scroll', checkIfScrollComplete);
|
||||
}
|
||||
|
||||
if(smooth) {
|
||||
//Scroll 1/10 of the way every 10ms until 1px off.
|
||||
const incrementalScroll = setInterval(()=>{
|
||||
currentY += (targetY - currentY) / 10;
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, currentY);
|
||||
editor.scrollToY(currentY);
|
||||
|
||||
// Update target: target height is not accurate until within +-10 lines of the visible window
|
||||
if(Math.abs(targetY - currentY > 100))
|
||||
targetY = this.codeEditor.current.codeMirror?.heightAtLine(targetLine, 'local', true);
|
||||
|
||||
// End when close enough
|
||||
if(Math.abs(targetY - currentY) < 1) {
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
|
||||
this.codeEditor.current.codeMirror?.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
editor.scrollToY(targetY);
|
||||
editor.setCursorToLine(targetLine);
|
||||
clearInterval(incrementalScroll);
|
||||
}
|
||||
}, 10);
|
||||
} else {
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
|
||||
this.codeEditor.current.codeMirror?.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
editor.scrollToY(targetY);
|
||||
editor.setCursorToLine(targetLine);
|
||||
}
|
||||
},
|
||||
|
||||
//Called when there are changes to the editor's dimensions
|
||||
update : function(){},
|
||||
|
||||
@@ -275,6 +262,8 @@ const Editor = createReactClass({
|
||||
view={this.state.view}
|
||||
value={this.props.brew.text}
|
||||
onChange={this.props.onBrewChange('text')}
|
||||
onCursorChange={(line)=>this.updateCurrentCursorPage(line)}
|
||||
onViewChange={(line)=>this.updateCurrentViewPage(line)}
|
||||
editorTheme={this.state.editorTheme}
|
||||
renderer={this.props.brew.renderer}
|
||||
rerenderParent={this.rerenderParent}
|
||||
|
||||
Reference in New Issue
Block a user