private CollectionListener createTokensListener()

in hybrid/src/main/java/jetbrains/jetpad/hybrid/BaseHybridSynchronizer.java [375:476]


  private CollectionListener<Token> createTokensListener() {
    return new CollectionAdapter<Token>() {
      @Override
      public void onItemAdded(CollectionItemEvent<? extends Token> event) {
        if (myPlaceholder != null) {
          removePlaceholder();
        }

        final Token token = event.getNewItem();
        Cell tokenCell = createTokenCell(token);

        int index = event.getIndex();
        if (index == 0) {
          if (tokenCell instanceof TextTokenCell) {
            ((TextTokenCell) tokenCell).setFirst(true);
          }
          if (!myTargetList.isEmpty()) {
            updateTokenCell(0, new Handler<TextTokenCell>() {
              @Override
              public void handle(TextTokenCell item) {
                item.setFirst(false);
              }
            });
          }
        }

        if (index > 0) {
          updateTokenCell(index - 1, new Handler<TextTokenCell>() {
            @Override
            public void handle(TextTokenCell item) {
              item.setNextToken(token);
            }
          });
        }
        if (index + 1 < tokens().size() && tokenCell instanceof TextTokenCell) {
          ((TextTokenCell) tokenCell).setNextToken(tokens().get(index + 1));
        }

        myTargetList.add(index, tokenCell);
      }

      @Override
      public void onItemRemoved(CollectionItemEvent<? extends Token> event) {
        final int index = event.getIndex();
        Cell removedCell = myTargetList.remove(index);

        if (myValueCellToMapper != null && myValueCellToMapper.containsKey(removedCell)) {
          Mapper<?, ? extends Cell> valueMapper = myValueCellToMapper.get(removedCell);
          myValueMappers.remove(valueMapper);
          myValueCellToMapper.remove(removedCell);
          if (myValueCellToMapper.isEmpty()) {
            myValueCellToMapper = null;
          }
        }

        if (myTargetList.isEmpty()) {
          addPlaceholder();
        } else {
          if (index == 0 && myTargetList.get(0) instanceof TextTokenCell) {
            updateTokenCell(0, new Handler<TextTokenCell>() {
              @Override
              public void handle(TextTokenCell item) {
                item.setFirst(true);
              }
            });
          }
          if (index == myTargetList.size()) {
            updateTokenCell(myTargetList.size() - 1, new Handler<TextTokenCell>() {
              @Override
              public void handle(TextTokenCell item) {
                item.setNextToken(null);
              }
            });
          } else if (index > 0 && myTargetList.get(index - 1) instanceof TextTokenCell) {
            updateTokenCell(index - 1, new Handler<TextTokenCell>() {
              @Override
              public void handle(TextTokenCell item) {
                item.setNextToken(tokens().get(index));
              }
            });
          }
        }
      }

      private void updateTokenCell(int index, Handler<TextTokenCell> handler) {
        Cell cell = myTargetList.get(index);
        if (cell instanceof TextTokenCell) {
          TextTokenCell textTokenCell = (TextTokenCell) cell;

          boolean wasNoSpaceToLeft = textTokenCell.noSpaceToLeft();
          boolean wasNoSpaceToRight = textTokenCell.noSpaceToRight();

          handler.handle(textTokenCell);

          if ((textTokenCell.noSpaceToLeft() != wasNoSpaceToLeft) || (textTokenCell.noSpaceToRight() != wasNoSpaceToRight)) {
            myTargetList.remove(index);
            myTargetList.add(index, cell);
          }
        }
      }
    };
  }