<commit_before>// handy text editor
// Copyright (c) 2016-2018 <NAME>
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#include "doc_view.h"

#include "clipboard.h"

#include <algorithm>

std::string DocView::clipboard;

DocView::DocView(const DocPtr& doc)
  : m_doc(doc) {
  m_cursor_ref = m_doc->cursors().add(0);
  m_sel_ref = -1;
  set_mode(Mode::Ins);
}

void DocView::set_doc(const DocPtr& doc) {
  m_doc = doc;
}

void DocView::set_cursor(cursor_t i) {
  m_doc->cursors().set(m_cursor_ref, i);
  update_scroll();
}

void DocView::set_scroll(const Pos& scroll) {
  m_scroll = scroll;
}

std::string DocView::get_status_text() const {
  char buf[2048];
  if (mode() == Mode::Cmd) {
    sprintf(buf, "Command? [s]ave [m]ore [q]uit");
  }
  else {
    Pos pos = calc_pos(cursor());
    sprintf(buf, "-- %d:%d -- %s%s%s --",
            pos.y+1, pos.x,
            doc()->filename().c_str(),
            doc()->modified() ? " (*)": "",
            mode() == Mode::Ins ? " -- editing":
            mode() == Mode::Sel ? " -- selecting": "");
  }
  return buf;
}

Pos DocView::calc_pos(cursor_t j) const {
  PanelPtr panel = this->panel();
  int w = panel->width();
  int h = panel->height();
  cursor_t i = 0;
  Pos p;

  for (auto ch : m_doc->str()) {
    if (i == j)
      break;

    if (ch == '\n') {
      p.x = 0;
      ++p.y;
    }
    else
      ++p.x;

    ++i;
  }

  return p;
}

void DocView::show(Ctx* ctx) {
  View::show(ctx);

  PanelPtr panel = this->panel();
  int w = panel->width();
  int h = panel->height();
  panel->clear();

  Pos p, cursor_p(-1, -1);
  cursor_t i = 0;
  cursor_t j = cursor();

  panel->attr_normal();
  bool reversed = false;
  for (auto ch : m_doc->str()) {
    // Cursor position
    if (i == j)
      cursor_p = p;

    if (m_sel_ref >= 0) {
      if (i >= std::min(cursor(), sel()) &&
          i < std::max(cursor(), sel())) {
        panel->attr_reverse();
        reversed = true;
      }
      else {
        panel->attr_normal();
        reversed = false;
      }
    }

    if (p.y >= m_scroll.y) {
      if (ch == '\n') {
        // Show a reversed char to show that the \n is selected
        if (reversed)
          panel->print(' ');
      }

      if (p.x >= m_scroll.x && p.x < m_scroll.x+w)
        panel->print(ch);
    }

    if (ch == '\n') {
      if (p.x < m_scroll.x)
        panel->print('\n');

      p.x = 0;
      ++p.y;
      if (p.y >= m_scroll.y+h)
        break;
    }
    else
      ++p.x;

    ++i;
  }
  panel->attr_normal();

  if (cursor_p.x < 0 ||
      cursor_p.y < 0)
    cursor_p = p;
  panel->move(cursor_p.x-m_scroll.x,
              cursor_p.y-m_scroll.y);
  panel->update();
}

bool DocView::on_key(Ctx* ctx, int ch) {
  // Globals
  switch (ch) {
    case 6:                   // Ctrl+F
      search_text(ctx);
      return true;
    case 17:                // Ctrl+Q
      quit(ctx);
      return true;
    case 19:                // Ctrl+S
      doc()->save();
      return true;
  }

  if (mode() == Mode::Nav ||
      mode() == Mode::Sel) {
    switch (ch) {
      case 'j':
      case KEY_LEFT:
        prev_char();
        return true;
      case 'l':
      case KEY_RIGHT:
        next_char();
        return true;
      case 'i':
      case KEY_UP:
        prev_line();
        return true;
      case 'k':
      case KEY_DOWN:
        next_line();
        return true;
      case 'I':
        prev_page();
        return true;
      case 'K':
        next_page();
        return true;
      case 'J':
        prev_expr();
        return true;
      case 'L':
        next_expr();
        return true;
      case 'u':
        prev_word();
        return true;
      case 'o':
        next_word();
        return true;
      case 'U':
        prev_block();
        return true;
      case 'O':
        next_block();
        return true;
    }
  }

  if (mode() == Mode::Nav) {
    switch (ch) {
      case 'q':
        quit(ctx);
        return true;
      case 'm':
        set_mode(Mode::Cmd);
        return true;
      case 's':
        set_mode(Mode::Sel);
        m_sel_ref = m_doc->cursors().add(cursor());
        return true;
      case 10: // Enter starts ins mode
        set_mode(Mode::Ins);
        return true;
      case 15:
        ctx->set_view(ViewPtr(new OpenFileView));
        return true;
      case ' ':
      case 127: // Space and backspace start ins mode modifying the doc
        set_mode(Mode::Ins);
        break;
      case 'f':
        search_text(ctx);
        return true;
      case 'h':
        if (!beg_of_line())
          beg_of_file();
        break;
      case 'H':
        if (!end_of_line())
          end_of_file();
        break;
      case 'v':               // Paste
      case 22:                // Ctrl+V
        m_doc->insert(cursor(), Clipboard::get_content());
        break;
      case 'z':               // Undo
        m_doc->undo();
        set_cursor(m_doc->last_modified_pos());
        break;
      case 'Z':               // Redo
        m_doc->redo();
        set_cursor(m_doc->last_modified_pos());
        break;
    }
  }

  if (mode() == Mode::Ins) {<commit_msg>Change d/f keys to delete chars and y to find<commit_after>// handy text editor
// Copyright (c) 2016-2018 <NAME>
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#include "doc_view.h"

#include "clipboard.h"

#include <algorithm>

std::string DocView::clipboard;

DocView::DocView(const DocPtr& doc)
  : m_doc(doc) {
  m_cursor_ref = m_doc->cursors().add(0);
  m_sel_ref = -1;
  set_mode(Mode::Ins);
}

void DocView::set_doc(const DocPtr& doc) {
  m_doc = doc;
}

void DocView::set_cursor(cursor_t i) {
  m_doc->cursors().set(m_cursor_ref, i);
  update_scroll();
}

void DocView::set_scroll(const Pos& scroll) {
  m_scroll = scroll;
}

std::string DocView::get_status_text() const {
  char buf[2048];
  if (mode() == Mode::Cmd) {
    sprintf(buf, "Command? [s]ave [m]ore [q]uit");
  }
  else {
    Pos pos = calc_pos(cursor());
    sprintf(buf, "-- %d:%d -- %s%s%s --",
            pos.y+1, pos.x,
            doc()->filename().c_str(),
            doc()->modified() ? " (*)": "",
            mode() == Mode::Ins ? " -- editing":
            mode() == Mode::Sel ? " -- selecting": "");
  }
  return buf;
}

Pos DocView::calc_pos(cursor_t j) const {
  PanelPtr panel = this->panel();
  int w = panel->width();
  int h = panel->height();
  cursor_t i = 0;
  Pos p;

  for (auto ch : m_doc->str()) {
    if (i == j)
      break;

    if (ch == '\n') {
      p.x = 0;
      ++p.y;
    }
    else
      ++p.x;

    ++i;
  }

  return p;
}

void DocView::show(Ctx* ctx) {
  View::show(ctx);

  PanelPtr panel = this->panel();
  int w = panel->width();
  int h = panel->height();
  panel->clear();

  Pos p, cursor_p(-1, -1);
  cursor_t i = 0;
  cursor_t j = cursor();

  panel->attr_normal();
  bool reversed = false;
  for (auto ch : m_doc->str()) {
    // Cursor position
    if (i == j)
      cursor_p = p;

    if (m_sel_ref >= 0) {
      if (i >= std::min(cursor(), sel()) &&
          i < std::max(cursor(), sel())) {
        panel->attr_reverse();
        reversed = true;
      }
      else {
        panel->attr_normal();
        reversed = false;
      }
    }

    if (p.y >= m_scroll.y) {
      if (ch == '\n') {
        // Show a reversed char to show that the \n is selected
        if (reversed)
          panel->print(' ');
      }

      if (p.x >= m_scroll.x && p.x < m_scroll.x+w)
        panel->print(ch);
    }

    if (ch == '\n') {
      if (p.x < m_scroll.x)
        panel->print('\n');

      p.x = 0;
      ++p.y;
      if (p.y >= m_scroll.y+h)
        break;
    }
    else
      ++p.x;

    ++i;
  }
  panel->attr_normal();

  if (cursor_p.x < 0 ||
      cursor_p.y < 0)
    cursor_p = p;
  panel->move(cursor_p.x-m_scroll.x,
              cursor_p.y-m_scroll.y);
  panel->update();
}

bool DocView::on_key(Ctx* ctx, int ch) {
  // Globals
  switch (ch) {
    case 6:                   // Ctrl+F
      search_text(ctx);
      return true;
    case 17:                // Ctrl+Q
      quit(ctx);
      return true;
    case 19:                // Ctrl+S
      doc()->save();
      return true;
  }

  if (mode() == Mode::Nav ||
      mode() == Mode::Sel) {
    switch (ch) {
      case 'j':
      case KEY_LEFT:
        prev_char();
        return true;
      case 'l':
      case KEY_RIGHT:
        next_char();
        return true;
      case 'i':
      case KEY_UP:
        prev_line();
        return true;
      case 'k':
      case KEY_DOWN:
        next_line();
        return true;
      case 'I':
        prev_page();
        return true;
      case 'K':
        next_page();
        return true;
      case 'J':
        prev_expr();
        return true;
      case 'L':
        next_expr();
        return true;
      case 'u':
        prev_word();
        return true;
      case 'o':
        next_word();
        return true;
      case 'U':
        prev_block();
        return true;
      case 'O':
        next_block();
        return true;
    }
  }

  if (mode() == Mode::Nav) {
    switch (ch) {
      case 'q':
        quit(ctx);
        return true;
      case 'm':
        set_mode(Mode::Cmd);
        return true;
      case 's':
        set_mode(Mode::Sel);
        m_sel_ref = m_doc->cursors().add(cursor());
        return true;
      case 10: // Enter starts ins mode
        set_mode(Mode::Ins);
        return true;
      case 15:
        ctx->set_view(ViewPtr(new OpenFileView));
        return true;
      case ' ':
      case 127: // Space and backspace start ins mode modifying the doc
        set_mode(Mode::Ins);
        break;
      case 'd':
        delete_prev_char();
        return true;
      case 'f':
        delete_next_char();
        return true;
      case 'y':
        search_text(ctx);
        return true;
      case 'h':
        if (!beg_of_line())
          beg_of_file();
        break;
      case 'H':
        if (!end_of_line())
          end_of_file();
        break;
      case 'v':               // Paste
      case 22:                // Ctrl+V
        m_doc->insert(cursor(), Clipboard::get_content());
        break;
      case 'z':               // Undo
        m_doc->undo();
        set_cursor(m_doc->last_modified_pos());
        break;
      case 'Z':               // Redo
        m_doc->redo();
        set_cursor(m_doc->last_modified_pos());
        break;
    }
  }

  if (mode() == Mode::Ins) {
{'fraction_non_alphanumeric': 0.16416349809885933, 'fraction_numerical': 0.007224334600760456, 'mean_word_length': 1.6750572082379862, 'pattern_counts': {'":': 6, '<': 17, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2699363', 'n_tokens_mistral': 3777, 'n_tokens_neox': 3653, 'n_words': 881}