public void LineSwap() {
    if (caret.row == sel.row) {
      if (caret.row == 0) {
        return;
      }
      UndoPatch up = new UndoPatch(caret.row - 1, caret.row);
      StringBuilder swb = code.getsb(caret.row - 1);
      code.get(caret.row - 1).sbuild = code.get(caret.row).sbuild;
      code.get(caret.row).sbuild = swb;
      up.realize(caret.row);
      storeUndo(up, OPT.SWAP);
      if (sel.type != ST.RECT) {
        sel.col = caret.col = line_offset_from(caret.row, caret.colw);
      }
    } else {
      UndoPatch up = new UndoPatch();
      int srow = Math.min(sel.row, caret.row), erow = Math.max(sel.row, caret.row);
      StringBuilder swb = code.getsb(srow);
      for (int i = srow; i < erow; i++) {
        code.get(i).sbuild = code.get(i + 1).sbuild;
      }
      code.get(erow).sbuild = swb;
      up.realize(erow);
      if (sel.type != ST.RECT) {
        sel.col = caret.col = line_offset_from(caret.row, caret.colw);
      }
      storeUndo(up, OPT.SWAP);
    }
  }