summaryrefslogtreecommitdiff
path: root/src/buffer.h
blob: 141c1eae24183464692b2a256cb0f4a8274ef37d (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
120
121
122
123
124
125
126
127
128
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#include "command.h"
#include "text.h"

struct keymap;
struct reactor;
struct command_list;

struct margin {
  uint32_t left;
  uint32_t right;
  uint32_t top;
  uint32_t bottom;
};

typedef struct margin (*update_hook_cb)(struct buffer *buffer,
                                        struct command_list *commands,
                                        uint32_t width, uint32_t height,
                                        uint64_t frame_time, void *userdata);

struct update_hook {
  update_hook_cb callback;
  void *userdata;
};

struct update_hooks {
  struct update_hook hooks[32];
  uint32_t nhooks;
};

struct modeline {
  uint8_t *buffer;
};

struct buffer {
  const char *name;
  const char *filename;

  struct text *text;

  uint32_t dot_line;
  uint32_t dot_col;

  // local keymaps
  struct keymap *keymaps;
  uint32_t nkeymaps;
  uint32_t nkeymaps_max;

  uint32_t scroll_line;
  uint32_t scroll_col;

  struct update_hooks update_hooks;
};

struct buffer buffer_create(const char *name, bool modeline);
void buffer_destroy(struct buffer *buffer);

uint32_t buffer_keymaps(struct buffer *buffer, struct keymap **keymaps_out);
void buffer_add_keymap(struct buffer *buffer, struct keymap *keymap);

int buffer_add_text(struct buffer *buffer, uint8_t *text, uint32_t nbytes);
void buffer_clear(struct buffer *buffer);
bool buffer_is_empty(struct buffer *buffer);

void buffer_kill_line(struct buffer *buffer);
void buffer_forward_delete_char(struct buffer *buffer);
void buffer_backward_delete_char(struct buffer *buffer);
void buffer_backward_char(struct buffer *buffer);
void buffer_forward_char(struct buffer *buffer);
void buffer_backward_line(struct buffer *buffer);
void buffer_forward_line(struct buffer *buffer);
void buffer_end_of_line(struct buffer *buffer);
void buffer_beginning_of_line(struct buffer *buffer);
void buffer_newline(struct buffer *buffer);

void buffer_relative_dot_pos(struct buffer *buffer, uint32_t *relline,
                             uint32_t *relcol);

uint32_t buffer_add_update_hook(struct buffer *buffer, update_hook_cb hook,
                                void *userdata);

struct buffer buffer_from_file(const char *filename, struct reactor *reactor);
void buffer_to_file(struct buffer *buffer);

void buffer_update(struct buffer *buffer, uint32_t width, uint32_t height,
                   struct command_list *commands, uint64_t frame_time);

struct margin buffer_modeline_hook(struct buffer *buffer,
                                   struct command_list *commands,
                                   uint32_t width, uint32_t height,
                                   uint64_t frame_time, void *userdata);

// commands
#define BUFFER_WRAPCMD(fn)                                                     \
  static int32_t fn##_cmd(struct command_ctx ctx, int argc,                    \
                          const char *argv[]) {                                \
    fn(ctx.current_buffer);                                                    \
    return 0;                                                                  \
  }

BUFFER_WRAPCMD(buffer_kill_line);
BUFFER_WRAPCMD(buffer_forward_delete_char);
BUFFER_WRAPCMD(buffer_backward_delete_char);
BUFFER_WRAPCMD(buffer_backward_char);
BUFFER_WRAPCMD(buffer_forward_char);
BUFFER_WRAPCMD(buffer_backward_line);
BUFFER_WRAPCMD(buffer_forward_line);
BUFFER_WRAPCMD(buffer_end_of_line);
BUFFER_WRAPCMD(buffer_beginning_of_line);
BUFFER_WRAPCMD(buffer_newline)
BUFFER_WRAPCMD(buffer_to_file);

static struct command BUFFER_COMMANDS[] = {
    {.name = "kill-line", .fn = buffer_kill_line_cmd},
    {.name = "delete-char", .fn = buffer_forward_delete_char_cmd},
    {.name = "backward-delete-char", .fn = buffer_backward_delete_char_cmd},
    {.name = "backward-char", .fn = buffer_backward_char_cmd},
    {.name = "forward-char", .fn = buffer_forward_char_cmd},
    {.name = "backward-line", .fn = buffer_backward_line_cmd},
    {.name = "forward-line", .fn = buffer_forward_line_cmd},
    {.name = "end-of-line", .fn = buffer_end_of_line_cmd},
    {.name = "beginning-of-line", .fn = buffer_beginning_of_line_cmd},
    {.name = "newline", .fn = buffer_newline_cmd},
    {.name = "buffer-write-to-file", .fn = buffer_to_file_cmd},
};