selection_shortcuts.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { Plugin } from '@grafana/slate-react';
  2. import { Editor as CoreEditor } from 'slate';
  3. import { isKeyHotkey } from 'is-hotkey';
  4. const isSelectLeftHotkey = isKeyHotkey('shift+left');
  5. const isSelectRightHotkey = isKeyHotkey('shift+right');
  6. const isSelectUpHotkey = isKeyHotkey('shift+up');
  7. const isSelectDownHotkey = isKeyHotkey('shift+down');
  8. const isSelectLineHotkey = isKeyHotkey('mod+l');
  9. const handleSelectVertical = (editor: CoreEditor, direction: 'up' | 'down') => {
  10. const { focusBlock } = editor.value;
  11. const adjacentBlock =
  12. direction === 'up'
  13. ? editor.value.document.getPreviousBlock(focusBlock.key)
  14. : editor.value.document.getNextBlock(focusBlock.key);
  15. if (!adjacentBlock) {
  16. return true;
  17. }
  18. const adjacentText = adjacentBlock.getFirstText();
  19. editor
  20. .moveFocusTo(adjacentText.key, Math.min(editor.value.selection.anchor.offset, adjacentText.text.length))
  21. .focus();
  22. return true;
  23. };
  24. const handleSelectUp = (editor: CoreEditor) => handleSelectVertical(editor, 'up');
  25. const handleSelectDown = (editor: CoreEditor) => handleSelectVertical(editor, 'down');
  26. // Clears the rest of the line after the caret
  27. export default function SelectionShortcutsPlugin(): Plugin {
  28. return {
  29. onKeyDown(event: KeyboardEvent, editor: CoreEditor, next: Function) {
  30. if (isSelectLeftHotkey(event)) {
  31. event.preventDefault();
  32. if (editor.value.selection.focus.offset > 0) {
  33. editor.moveFocusBackward(1);
  34. }
  35. } else if (isSelectRightHotkey(event)) {
  36. event.preventDefault();
  37. if (editor.value.selection.focus.offset < editor.value.startText.text.length) {
  38. editor.moveFocusForward(1);
  39. }
  40. } else if (isSelectUpHotkey(event)) {
  41. event.preventDefault();
  42. handleSelectUp(editor);
  43. } else if (isSelectDownHotkey(event)) {
  44. event.preventDefault();
  45. handleSelectDown(editor);
  46. } else if (isSelectLineHotkey(event)) {
  47. event.preventDefault();
  48. const { focusBlock, document } = editor.value;
  49. editor.moveAnchorToStartOfBlock();
  50. const nextBlock = document.getNextBlock(focusBlock.key);
  51. if (nextBlock) {
  52. editor.moveFocusToStartOfNextBlock();
  53. } else {
  54. editor.moveFocusToEndOfText();
  55. }
  56. } else {
  57. return next();
  58. }
  59. return true;
  60. },
  61. };
  62. }