select.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { EditorView } from '@codemirror/view'
  2. import { EditorSelection, EditorState, StateCommand } from '@codemirror/state'
  3. import { SearchQuery, StringQuery, selectWord } from '@codemirror/search'
  4. export { selectNextOccurrence } from '@codemirror/search'
  5. const findPrevOccurence = (state: EditorState, search: string) => {
  6. const searchQuery = new SearchQuery({ search, literal: true })
  7. const query = new StringQuery(searchQuery)
  8. const { from, to } = state.selection.main
  9. return query.prevMatch(state, from, to)
  10. }
  11. export const selectPrevOccurrence: StateCommand = ({ state, dispatch }) => {
  12. const { ranges } = state.selection
  13. if (ranges.some(range => range.from === range.to)) {
  14. return selectWord({ state, dispatch })
  15. }
  16. const searchedText = state.sliceDoc(ranges[0].from, ranges[0].to)
  17. if (
  18. state.selection.ranges.some(
  19. range => state.sliceDoc(range.from, range.to) !== searchedText
  20. )
  21. ) {
  22. return false
  23. }
  24. const range = findPrevOccurence(state, searchedText)
  25. if (!range) {
  26. return false
  27. }
  28. dispatch(
  29. state.update({
  30. selection: state.selection.addRange(
  31. EditorSelection.range(range.from, range.to)
  32. ),
  33. effects: EditorView.scrollIntoView(range.to),
  34. })
  35. )
  36. return true
  37. }