1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-26 18:58:21 +02:00

Desktop: Fixed scrolling issue when editing while searching in CodeMirror (#3593)

Only scroll to search matchs when the user changes the search or
explicitly changes the search index
https://discourse.joplinapp.org/t/codemirror-feedback/10397
This commit is contained in:
Caleb John 2020-08-08 03:11:55 -06:00 committed by GitHub
parent 5c5cb0f781
commit e1144c098e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ export default function useEditorSearch(CodeMirror: any) {
const [overlay, setOverlay] = useState(null); const [overlay, setOverlay] = useState(null);
const [scrollbarMarks, setScrollbarMarks] = useState(null); const [scrollbarMarks, setScrollbarMarks] = useState(null);
const [previousKeywordValue, setPreviousKeywordValue] = useState(null); const [previousKeywordValue, setPreviousKeywordValue] = useState(null);
const [previousIndex, setPreviousIndex] = useState(null);
const [overlayTimeout, setOverlayTimeout] = useState(null); const [overlayTimeout, setOverlayTimeout] = useState(null);
const overlayTimeoutRef = useRef(null); const overlayTimeoutRef = useRef(null);
overlayTimeoutRef.current = overlayTimeout; overlayTimeoutRef.current = overlayTimeout;
@ -49,12 +50,10 @@ export default function useEditorSearch(CodeMirror: any) {
// Highlights the currently active found work // Highlights the currently active found work
// It's possible to get tricky with this fucntions and just use findNext/findPrev // It's possible to get tricky with this fucntions and just use findNext/findPrev
// but this is fast enough and works more naturally with the current search logic // but this is fast enough and works more naturally with the current search logic
function highlightSearch(cm: any, searchTerm: RegExp, index: number) { function highlightSearch(cm: any, searchTerm: RegExp, index: number, scrollTo: boolean) {
const marks: any = [];
const cursor = cm.getSearchCursor(searchTerm); const cursor = cm.getSearchCursor(searchTerm);
let match = null; let match: any = null;
for (let j = 0; j < index + 1; j++) { for (let j = 0; j < index + 1; j++) {
if (!cursor.findNext()) { if (!cursor.findNext()) {
// If we run out of matches then just highlight the final match // If we run out of matches then just highlight the final match
@ -64,11 +63,11 @@ export default function useEditorSearch(CodeMirror: any) {
} }
if (match) { if (match) {
marks.push(cm.markText(match.from, match.to, { className: 'cm-search-marker-selected' })); if (scrollTo) cm.scrollIntoView(match);
cm.scrollIntoView(match); return cm.markText(match.from, match.to, { className: 'cm-search-marker-selected' });
} }
return marks; return null;
} }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
@ -98,7 +97,7 @@ export default function useEditorSearch(CodeMirror: any) {
// HIGHLIGHT KEYWORDS // HIGHLIGHT KEYWORDS
// When doing a global search it's possible to have multiple keywords // When doing a global search it's possible to have multiple keywords
// This means we need to highlight each one // This means we need to highlight each one
let marks: any = []; const marks: any = [];
for (let i = 0; i < keywords.length; i++) { for (let i = 0; i < keywords.length; i++) {
const keyword = keywords[i]; const keyword = keywords[i];
@ -106,10 +105,15 @@ export default function useEditorSearch(CodeMirror: any) {
const searchTerm = getSearchTerm(keyword); const searchTerm = getSearchTerm(keyword);
marks = marks.concat(highlightSearch(this, searchTerm, options.selectedIndex)); // We only want to scroll the first keyword into view in the case of a multi keyword search
const scrollTo = i === 0 && (previousKeywordValue !== keyword.value || previousIndex !== options.selectedIndex);
const match = highlightSearch(this, searchTerm, options.selectedIndex, scrollTo);
if (match) marks.push(match);
} }
setMarkers(marks); setMarkers(marks);
setPreviousIndex(options.selectedIndex);
// SEARCHOVERLAY // SEARCHOVERLAY
// We only want to highlight all matches when there is only 1 search term // We only want to highlight all matches when there is only 1 search term