static void showCompletion()

in cell/src/main/java/jetbrains/jetpad/cell/completion/CompletionSupport.java [86:193]


  static void showCompletion(final TextCell editor, Async<Iterable<CompletionItem>> items,
      final Runnable restoreCompletionState, final Runnable restoreFocusState) {

    if (!editor.focused().get()) {
      throw new IllegalArgumentException();
    }

    final CompletionMenuModel menuModel = new CompletionMenuModel();
    menuModel.loading.set(true);

    final CompositeRegistration completionReg = new CompositeRegistration();

    final ReadableProperty<String> prefixText = prefixText(editor);
    completionReg.add(PropertyBinding.bindOneWay(prefixText, menuModel.text));

    final Handler<CompletionItem> completer = new Handler<CompletionItem>() {
      @Override
      public void handle(CompletionItem item) {
        completionReg.remove();
        restoreFocusState.run();
        item.complete(prefixText.get()).run();
      }
    };

    final CompositeRegistration disposeMenuMapper = new CompositeRegistration();
    final Cell completionCell = CompletionMenu.createCell(menuModel, completer, disposeMenuMapper);

    completionReg.add(editor.focused().addHandler(new EventHandler<PropertyChangeEvent<Boolean>>() {
      @Override
      public void onEvent(PropertyChangeEvent<Boolean> event) {
        if (!event.getNewValue()) {
          completionReg.remove();
        }
      }
    }));
    completionReg.add(editor.addTrait(new CellTrait() {
      @Override
      public void onKeyPressed(Cell cell, KeyEvent event) {
        CompletionItem selectedItem = menuModel.selectedItem.get();

        if (event.is(Key.ESCAPE)) {
          completionReg.remove();
          restoreFocusState.run();
          event.consume();
          return;
        }

        if (selectedItem == null) return;

        if (event.is(Key.ENTER)) {
          completer.handle(selectedItem);
          event.consume();
          cell.dispatch(new Event(), Cells.AFTER_COMPLETED);
          return;
        }

        if (event.is(Key.UP)) {
          menuModel.up();
          event.consume();
          return;
        }

        if (event.is(Key.DOWN)) {
          menuModel.down();
          event.consume();
          return;
        }

        if (event.is(Key.PAGE_UP) || event.is(Key.PAGE_DOWN)) {
          int pageHeight = completionCell.getBounds().dimension.y / editor.dimension().y;
          for (int i = 0; i < pageHeight; i++) {
            if (event.is(Key.PAGE_DOWN)) {
              menuModel.down();
            } else {
              menuModel.up();
            }
          }
          event.consume();
        }
      }
    }));

    completionReg.add(new Registration() {
      @Override
      protected void doRemove() {
        completionCell.removeFromParent();
        disposeMenuMapper.remove();
        restoreCompletionState.run();
      }
    });

    items.onSuccess(new Handler<Iterable<CompletionItem>>() {
      @Override
      public void handle(Iterable<CompletionItem> items) {
        menuModel.loading.set(false);
        menuModel.items.addAll(FluentIterable.from(items).toList());
      }
    });
    items.onFailure(new Handler<Throwable>() {
      @Override
      public void handle(Throwable item) {
        menuModel.loading.set(false);
      }
    });

    editor.bottomPopup().set(completionCell);
    completionCell.scrollTo();
  }