<commit_before>#include "coco.hh"

#include <algorithm>
#include <functional>
#include <iostream>
#include <regex>
#include <numeric>
#include <stdexcept>
#include <string>
#include <vector>
#include <tuple>

#include <nanojson.hpp>
#include <cmdline.h>
#include "filter.hh"
#include "ncurses.hh"
#include "utf8.hh"

using curses::Window;
using curses::Event;
using curses::Key;

enum class Coco::Status {
  Selected,
  Escaped,
  Continue,
};

constexpr size_t y_offset = 1;

void Config::parse_args(int argc, char const** argv)
{
  cmdline::parser parser;
  parser.set_program_name("coco");
  parser.add<std::string>("query", 0, "initial value for query", false, "");
  parser.add<std::string>("prompt", 0, "specify the prompt string", false, "QUERY> ");
  parser.add<std::size_t>("max-buffer", 'b', "maximum length of lines", false, 4096);
  parser.add<double>("score-min", 's', "threshold of score", false, 0.01);
  parser.add<std::string>("filter", 'f', "type of filter", false, "SmartCase",
                          cmdline::oneof<std::string>("CaseSensitive", "SmartCase", "Regex"));
  parser.footer("filename...");
  parser.parse_check(argc, argv);

  query = parser.get<std::string>("query");
  prompt = parser.get<std::string>("prompt");
  score_min = parser.get<double>("score-min");
  max_buffer = parser.get<std::size_t>("max-buffer");

  std::stringstream ss{parser.get<std::string>("filter")};
  ss >> filter_mode;

  if (parser.rest().size() > 0) {
    file = parser.rest()[0];
  }
}

Coco::Coco(Config const& config, Candidates candidates) : config(config), candidates(candidates)
{
  query = config.query;
  filter_mode = config.filter_mode;

  choices.resize(candidates.lines.read().get().size());
  std::generate(choices.begin(), choices.end(), [n = 0]() mutable { return Choice(n++); });
  update_filter_list();
}

std::vector<std::string> Coco::select_line()
{
  // initialize ncurses screen.
  Window term;
  render_screen(term);

  while (true) {
    auto result = handle_key_event(term);

    if (result == Status::Selected) {
      std::vector<std::string> lines;
      for (std::size_t i = 0; i < filtered_len; ++i) {
        if (choices[i].selected)
          lines.push_back(candidates.lines.read().get()[choices[i].index]);
      }
      if (lines.empty()) {
        return {candidates.lines.read().get()[cursor + offset]};
      }
      else {
        return lines;
      }<commit_msg>modify selection<commit_after>#include "coco.hh"

#include <algorithm>
#include <functional>
#include <iostream>
#include <regex>
#include <numeric>
#include <stdexcept>
#include <string>
#include <vector>
#include <tuple>

#include <nanojson.hpp>
#include <cmdline.h>
#include "filter.hh"
#include "ncurses.hh"
#include "utf8.hh"

using curses::Window;
using curses::Event;
using curses::Key;

enum class Coco::Status {
  Selected,
  Escaped,
  Continue,
};

constexpr size_t y_offset = 1;

void Config::parse_args(int argc, char const** argv)
{
  cmdline::parser parser;
  parser.set_program_name("coco");
  parser.add<std::string>("query", 0, "initial value for query", false, "");
  parser.add<std::string>("prompt", 0, "specify the prompt string", false, "QUERY> ");
  parser.add<std::size_t>("max-buffer", 'b', "maximum length of lines", false, 4096);
  parser.add<double>("score-min", 's', "threshold of score", false, 0.01);
  parser.add<std::string>("filter", 'f', "type of filter", false, "SmartCase",
                          cmdline::oneof<std::string>("CaseSensitive", "SmartCase", "Regex"));
  parser.footer("filename...");
  parser.parse_check(argc, argv);

  query = parser.get<std::string>("query");
  prompt = parser.get<std::string>("prompt");
  score_min = parser.get<double>("score-min");
  max_buffer = parser.get<std::size_t>("max-buffer");

  std::stringstream ss{parser.get<std::string>("filter")};
  ss >> filter_mode;

  if (parser.rest().size() > 0) {
    file = parser.rest()[0];
  }
}

Coco::Coco(Config const& config, Candidates candidates) : config(config), candidates(candidates)
{
  query = config.query;
  filter_mode = config.filter_mode;

  choices.resize(candidates.lines.read().get().size());
  std::generate(choices.begin(), choices.end(), [n = 0]() mutable { return Choice(n++); });
  update_filter_list();
}

std::vector<std::string> Coco::select_line()
{
  // initialize ncurses screen.
  Window term;
  render_screen(term);

  while (true) {
    auto result = handle_key_event(term);

    if (result == Status::Selected) {
      std::vector<std::string> lines;
      for (std::size_t i = 0; i < filtered_len; ++i) {
        if (choices[i].selected)
          lines.push_back(candidates.lines.read().get()[choices[i].index]);
      }
      if (lines.empty()) {
        return {candidates.lines.read().get()[choices[cursor + offset].index]};
      }
      else {
        return lines;
      }
{'fraction_non_alphanumeric': 0.18693322341302557, 'fraction_numerical': 0.006183017312448475, 'mean_word_length': 4.410256410256411, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 59, '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': '5027662', 'n_tokens_mistral': 1692, 'n_tokens_neox': 1658, 'n_words': 343}