private void handleKeyPress()

in projectional/src/main/java/jetbrains/jetpad/projectional/util/CellNavigationController.java [200:316]


  private void handleKeyPress(Cell cell, KeyEvent event) {
    Cell current = focusedCell().get();
    Integer currentOffset = null;

    if (event.is(Key.UP) || event.is(Key.DOWN) || event.is(Key.PAGE_UP) || event.is(Key.PAGE_DOWN)) {
      currentOffset = myPrevXOffset.get();
      if (currentOffset == null) {
        currentOffset = selectedXOffset();
      }
    }

    Rectangle visibleRect = focusedCell().get().getContainer().visibleRect();

    Cell next = null;
    boolean restoreOffset = false;

    if (event.is(Key.RIGHT)) {
      next = nextFocusable(current);
      moveToHome(next);
    } else if (event.is(KeyStrokeSpecs.NEXT_WORD)) {
      next = nextFocusable(current);
      if (next != null) {
        moveToHome(next);
      } else if (!current.get(PositionHandler.PROPERTY).isEnd()) {
        next = current;
        moveToEnd(next);
      }
    } else if (event.is(KeyStrokeSpecs.NEXT_EDITABLE)) {
      next = next(current, EDITABLE);
      if (next != null) {
        moveToHome(next);
      } else if (!current.get(PositionHandler.PROPERTY).isEnd()) {
        next = current;
        moveToEnd(next);
      }
    } else if (event.is(Key.LEFT)) {
      next = prevFocusable(current);
      moveToEnd(next);
    } else if (event.is(KeyStrokeSpecs.PREV_WORD)) {
      next = prevFocusable(current);
      moveToHome(next);
    } else if (event.is(KeyStrokeSpecs.PREV_EDITABLE)) {
      next = prev(current, EDITABLE);
      moveToHome(next);
    } else if (event.is(Key.UP)) {
      next = WITH_BOUNDS.upperFocusable(current, currentOffset);
      restoreOffset = true;
    } else if (event.is(Key.DOWN)) {
      next = WITH_BOUNDS.lowerFocusable(current, currentOffset);
      restoreOffset = true;
    } else if (event.is(Key.PAGE_UP)) {
      next = new PageUpDown(current, currentOffset, visibleRect.dimension.y) {
        @Override
        protected Cell next(Cell current, int offset) {
          return WITH_BOUNDS.upperFocusable(current, offset);
        }
      }.execute();
      restoreOffset = true;
    } else if (event.is(Key.PAGE_DOWN)) {
      next = new PageUpDown(current, currentOffset, visibleRect.dimension.y) {
        @Override
        protected Cell next(Cell current, int offset) {
          return WITH_BOUNDS.lowerFocusable(current, offset);
        }
      }.execute();
      restoreOffset = true;
    } else if (event.is(KeyStrokeSpecs.HOME)) {
      next = WITH_BOUNDS.homeElement(current);
      moveToHome(next);
    } else if (event.is(KeyStrokeSpecs.END)) {
      next = WITH_BOUNDS.endElement(current);
      moveToEnd(next);
    } else if (event.is(KeyStrokeSpecs.FILE_HOME)) {
      next = Composites.firstFocusable(cell, true);
      moveToHome(next);
    } else if (event.is(KeyStrokeSpecs.FILE_END)) {
      next = Composites.lastFocusable(cell, true);
      moveToEnd(next);
    } else if (event.is(KeyStrokeSpecs.SELECT_UP)) {
      Cell focusableParent = Composites.focusableParent(current);
      if (focusableParent != null) {
        mySelectionStack.push(current);
        next = focusableParent;
        myStackResetEnabled.set(false);
      }
    } else if (event.is(KeyStrokeSpecs.SELECT_DOWN)) {
      if (mySelectionStack.isEmpty()) {
        next = Composites.firstFocusable(current, false);
      } else {
        next = mySelectionStack.pop();
      }
      myStackResetEnabled.set(false);
    } else if (event.is(KeyStrokeSpecs.MATCHING_CONSTRUCTS) && current.get(PAIR_CELL) != null) {
      next = current.get(PAIR_CELL);
      if (Composites.isBefore(next, current)) {
        moveToHome(next);
      } else {
        moveToEnd(next);
      }
      restoreOffset = false;
    }

    if (next != null) {
      focusedCell().set(next);
      if (restoreOffset) {
        moveCaretTo(next, currentOffset - next.getBounds().origin.x);
        myPrevXOffset.set(currentOffset);
      }
      if (next instanceof TextCell) {
        ((TextCell) next).scrollToCaret();
      } else {
        scrollTo(next);
      }
      event.consume();
    }
    myStackResetEnabled.set(true);
  }