aboutsummaryrefslogtreecommitdiff
path: root/src/Main.c
blob: e941921408fbcf827602fff2e5fae781fc2293d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>

#include "Globals.h"
#include "Terminal.h"
#include "Draw.h"
#include "Input.h"

Options opts = {
  .prompt = "",
  .insensitive = 0,
  .fuzzy = 0
};

ItemList all_items = {0};
ItemList filtered = {0};
char *input = NULL;
size_t input_len = 0;
size_t input_capacity = 0;
int cursor = 0;
int scroll = 0;
int needs_redraw = 1;

static void ensure_item_capacity(ItemList *list) {
  if (list->count >= list->capacity) {
    size_t new_cap = list->capacity == 0 ? INITIAL_CAPACITY : list->capacity * 2;
    list->items = realloc(list->items, new_cap * sizeof(char *));
    list->capacity = new_cap;
  }
}

void read_items(void) {
  char *line = NULL;
  size_t len = 0;
  ssize_t n;
  while ((n = getline(&line, &len, stdin)) != -1) {
    if (n > 0 && line[n-1] == '\n') line[n-1] = '\0';
    ensure_item_capacity(&all_items);
    all_items.items[all_items.count++] = strdup(line);
  }
  free(line);
  filter_items();
}

void version(void) {
  puts("insel 1.1");
  puts("'those who select their inputs'\n");
  puts("GNU GPL version 2 <https://gnu.org/licenses/old-licenses/gpl-2.0.html>.\n"
     "This is free software: you are free to change and redistribute it.\n"
     "There is NO WARRANTY, to the extent permitted by law.");
  exit(0);
}

void help(void) {
  puts("Usage: insel [-i] [-F] [-p prompt]"
          "\n"
          "Options:"
          "\n"
          "  -i          Case-insensitive matching"
          "\n"
          "  -F          Fuzzy matching (implies -i)"
          "\n"
          "  -v          Show version"
          "\n"
          "  -p prompt   Prompt to display"
          "\n"
          "  --help      Show this help message");
  exit(0);
}

int main(int argc, char *argv[]) {
  stdin_is_tty = isatty(STDIN_FILENO);
  orig_stdout = dup(STDOUT_FILENO);

  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-v") == 0) version();
    else if (strcmp(argv[i], "--help") == 0) help();
    else if (strcmp(argv[i], "-i") == 0) opts.insensitive = 1;
    else if (strcmp(argv[i], "-F") == 0) {
      opts.fuzzy = 1;
      opts.insensitive = 1;
    }
    else if (strcmp(argv[i], "-b") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-f") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
      if (opts.prompt[0] != '\0') free(opts.prompt);
      opts.prompt = strdup(argv[++i]);
    }
    else if (strcmp(argv[i], "-nb") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-nf") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-sb") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-sf") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-fn") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-m") == 0 && i + 1 < argc) i++;
    else if (strcmp(argv[i], "-w") == 0 && i + 1 < argc) i++;
  }

  read_items();
  setup_terminal();

  while (1) {
    if (needs_redraw) {
      draw();
      needs_redraw = 0;
    }
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(tty_fd, &fds);
    struct timeval tv = { .tv_sec = 0, .tv_usec = 10000 };
    if (select(tty_fd + 1, &fds, NULL, NULL, &tv) > 0) {
      handle_input();
    }
  }
  return 0;
}