commit 626ebd15fe0b810817d949e5785f3ffa7f04faed
parent 9d120485062d6cf0ce9075543f46000b984f7f23
Author: Samdal <samdal@protonmail.com>
Date: Thu, 29 Jun 2023 20:05:08 +0200
reformatting idk
Diffstat:
M | buffer.c | | | 1380 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | buffer.h | | | 147 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | extensions/syntax/gd.h | | | 146 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | extensions/syntax/handy_defines.h | | | 30 | +++++++++++++++--------------- |
M | extensions/syntax/syntax.h | | | 1049 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
M | se.c | | | 546 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | seek.c | | | 560 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | seek.h | | | 4 | ++-- |
M | utf8.c | | | 116 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | x.c | | | 2574 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | x.h | | | 74 | +++++++++++++++++++++++++++++++++++++------------------------------------- |
11 files changed, 3316 insertions(+), 3310 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -33,16 +33,16 @@ static int available_buffer_slots = 0;
static void
recursive_mkdir(char *path) {
- if (!path || !strlen(path))
- return;
- char *sep = strrchr(path, '/');
- if(sep) {
- *sep = '\0';
- recursive_mkdir(path);
- *sep = '/';
- }
- if(mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST)
- fprintf(stderr, "error while trying to create '%s'\n%s\n", path, strerror(errno));
+ if (!path || !strlen(path))
+ return;
+ char *sep = strrchr(path, '/');
+ if(sep) {
+ *sep = '\0';
+ recursive_mkdir(path);
+ *sep = '/';
+ }
+ if(mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST)
+ fprintf(stderr, "error while trying to create '%s'\n%s\n", path, strerror(errno));
}
@@ -51,79 +51,79 @@ static int open_seproj(struct file_buffer fb);
int
open_seproj(struct file_buffer fb)
{
- int first = -1;
+ int first = -1;
- char* path = file_path_get_path(fb.file_path);
- chdir(path);
- int offset = -1;
+ char* path = file_path_get_path(fb.file_path);
+ chdir(path);
+ int offset = -1;
- while((offset = fb_seek_char(&fb, offset+1, ' ')) >= 0)
- fb_change(&fb, "\n", 1, offset, 0);
+ while((offset = fb_seek_char(&fb, offset+1, ' ')) >= 0)
+ fb_change(&fb, "\n", 1, offset, 0);
- offset = -1;
- while((offset = fb_seek_char(&fb, offset+1, '\n')) >= 0) {
- char* line = fb_get_line_at_offset(&fb, offset);
- if (strlen(line) && !is_file_type(line, ".seproj")) {
- if (first < 0)
- first = fb_new_entry(line);
- else
- fb_new_entry(line);
+ offset = -1;
+ while((offset = fb_seek_char(&fb, offset+1, '\n')) >= 0) {
+ char* line = fb_get_line_at_offset(&fb, offset);
+ if (strlen(line) && !is_file_type(line, ".seproj")) {
+ if (first < 0)
+ first = fb_new_entry(line);
+ else
+ fb_new_entry(line);
+ }
+ free(line);
}
- free(line);
- }
- if (first < 0)
- first = fb_new_entry(NULL);
- writef_to_status_bar("opened project %s", path);
- free(path);
+ if (first < 0)
+ first = fb_new_entry(NULL);
+ writef_to_status_bar("opened project %s", path);
+ free(path);
- fb_destroy(&fb);
- return first;
+ fb_destroy(&fb);
+ return first;
}
void
fb_write_to_filepath(struct file_buffer* fb)
{
- if (!fb->file_path)
- return;
- soft_assert(fb->contents, return;);
- FILE* file = fopen(fb->file_path, "w");
- soft_assert(file, return;);
+ if (!fb->file_path)
+ return;
+ soft_assert(fb->contents, return;);
+ FILE* file = fopen(fb->file_path, "w");
+ soft_assert(file, return;);
- if (fb->mode & FB_UTF8_SIGNED)
- fwrite("\xEF\xBB\xBF", 1, 3, file);
- fwrite(fb->contents, sizeof(char), fb->len, file);
- writef_to_status_bar("saved buffer to %s", fb->file_path);
+ if (fb->mode & FB_UTF8_SIGNED)
+ fwrite("\xEF\xBB\xBF", 1, 3, file);
+ fwrite(fb->contents, sizeof(char), fb->len, file);
+ writef_to_status_bar("saved buffer to %s", fb->file_path);
- fclose(file);
- call_extension(fb_written_to_file, fb);
+ fclose(file);
+ call_extension(fb_written_to_file, fb);
}
int
destroy_fb_entry(struct window_split_node* node, struct window_split_node* root)
{
- // do not allow deletion of the lst file buffer
- int n = 0;
- for(; n < available_buffer_slots; n++)
- if (file_buffers[n].contents && n != node->wb.fb_index)
- break;
- if (n >= available_buffer_slots) {
- writef_to_status_bar("can't delete last buffer");
- return 0;
- }
+ // do not allow deletion of the lst file buffer
+ int n = 0;
+ for(; n < available_buffer_slots; n++)
+ if (file_buffers[n].contents && n != node->wb.fb_index)
+ break;
+ if (n >= available_buffer_slots) {
+ writef_to_status_bar("can't delete last buffer");
+ return 0;
+ }
- if (window_other_nodes_contain_fb(node, root)) {
- node->wb.fb_index++;
- node->wb = wb_new(node->wb.fb_index);
- writef_to_status_bar("swapped buffer");
- return 0;
- }
- fb_destroy(get_fb(&node->wb));
+ if (window_other_nodes_contain_fb(node, root)) {
+ node->wb.fb_index++;
+ node->wb = wb_new(node->wb.fb_index);
+ writef_to_status_bar("swapped buffer");
+ return 0;
+ }
+ fb_destroy(get_fb(&node->wb));
- node->wb = wb_new(node->wb.fb_index);
+ node->wb = wb_new(node->wb.fb_index);
- return 1;
+ return 1;
}
@@ -131,487 +131,487 @@ destroy_fb_entry(struct window_split_node* node, struct window_split_node* root)
struct file_buffer*
get_fb(struct window_buffer* wb)
{
- soft_assert(wb, wb = focused_window;);
- soft_assert(file_buffers, fb_new_entry(NULL););
+ soft_assert(wb, wb = focused_window;);
+ soft_assert(file_buffers, fb_new_entry(NULL););
- if (wb->fb_index < 0)
- wb->fb_index = available_buffer_slots-1;
- else if (wb->fb_index >= available_buffer_slots)
- wb->fb_index = 0;
+ if (wb->fb_index < 0)
+ wb->fb_index = available_buffer_slots-1;
+ else if (wb->fb_index >= available_buffer_slots)
+ wb->fb_index = 0;
- if (!file_buffers[wb->fb_index].contents) {
- for(int n = wb->fb_index; n < available_buffer_slots; n++) {
- if (file_buffers[n].contents) {
- wb->fb_index = n;
- return &file_buffers[n];
- }
- }
- for(int n = 0; n < available_buffer_slots; n++) {
- if (file_buffers[n].contents) {
- wb->fb_index = n;
- return &file_buffers[n];
- }
+ if (!file_buffers[wb->fb_index].contents) {
+ for(int n = wb->fb_index; n < available_buffer_slots; n++) {
+ if (file_buffers[n].contents) {
+ wb->fb_index = n;
+ return &file_buffers[n];
+ }
+ }
+ for(int n = 0; n < available_buffer_slots; n++) {
+ if (file_buffers[n].contents) {
+ wb->fb_index = n;
+ return &file_buffers[n];
+ }
+ }
+ } else {
+ soft_assert(file_buffers[wb->fb_index].contents, );
+ return &file_buffers[wb->fb_index];
}
- } else {
- soft_assert(file_buffers[wb->fb_index].contents, );
- return &file_buffers[wb->fb_index];
- }
- wb->fb_index = fb_new_entry(NULL);
- writef_to_status_bar("all buffers were somehow deleted, creating new one");
- status_bar_bg = warning_color;
- return get_fb(wb);
+ wb->fb_index = fb_new_entry(NULL);
+ writef_to_status_bar("all buffers were somehow deleted, creating new one");
+ status_bar_bg = warning_color;
+ return get_fb(wb);
}
int
fb_delete_selection(struct file_buffer* fb)
{
- if (fb->mode & FB_SELECTION_ON) {
- fb_remove_selection(fb);
- wb_move_cursor_to_selection_start(focused_window);
- fb->mode &= ~(FB_SELECTION_ON);
- return 1;
- }
- return 0;
+ if (fb->mode & FB_SELECTION_ON) {
+ fb_remove_selection(fb);
+ wb_move_cursor_to_selection_start(focused_window);
+ fb->mode &= ~(FB_SELECTION_ON);
+ return 1;
+ }
+ return 0;
}
struct file_buffer
fb_new(const char* file_path)
{
- struct file_buffer fb = {0};
- fb.file_path = xmalloc(PATH_MAX);
+ struct file_buffer fb = {0};
+ fb.file_path = xmalloc(PATH_MAX);
+
+ char* res = realpath(file_path, fb.file_path);
+ if (!res) {
+ char* path = file_path_get_path(file_path);
+ recursive_mkdir(path);
+ free(path);
+
+ FILE *new_file = fopen(file_path, "wb");
+ fclose(new_file);
+ realpath(file_path, fb.file_path);
+ remove(file_path);
+
+ writef_to_status_bar("opened new file %s", fb.file_path);
+ } else if (path_is_folder(fb.file_path)) {
+ int len = strlen(fb.file_path);
+ if (fb.file_path[len-1] != '/' && len < PATH_MAX-1) {
+ fb.file_path[len] = '/';
+ fb.file_path[len+1] = '\0';
+ }
+ } else {
+ FILE *file = fopen(fb.file_path, "rb");
+ if (file) {
+ fseek(file, 0L, SEEK_END);
+ long readsize = ftell(file);
+ rewind(file);
+
+ if (readsize > (long)1.048576e+7) {
+ fclose(file);
+ die("you are opening a huge file(>10MiB), not allowed");
+ return fb;
+ // TODO: don't crash
+ }
+
+ fb.len = readsize;
+ fb.capacity = readsize + 100;
+
+ fb.contents = xmalloc(fb.capacity);
+ fb.contents[0] = 0;
+
+ char bom[4] = {0};
+ fread(bom, 1, 3, file);
+ if (strcmp(bom, "\xEF\xBB\xBF"))
+ rewind(file);
+ else
+ fb.mode |= FB_UTF8_SIGNED;
+ fread(fb.contents, 1, readsize, file);
+ fclose(file);
+
+ fb.syntax_index = -1;
+ }
+ }
- char* res = realpath(file_path, fb.file_path);
- if (!res) {
- char* path = file_path_get_path(file_path);
- recursive_mkdir(path);
- free(path);
+ if (!fb.capacity)
+ fb.capacity = 100;
+ if (!fb.contents) {
+ fb.contents = xmalloc(fb.capacity);
+ memset(fb.contents, 0, fb.capacity);
+ }
+ fb.ub = xmalloc(sizeof(struct undo_buffer) * UNDO_BUFFERS_COUNT);
+ fb.search_term = xmalloc(SEARCH_TERM_MAX_LEN);
+ fb.non_blocking_search_term = xmalloc(SEARCH_TERM_MAX_LEN);
+ memset(fb.ub, 0, sizeof(struct undo_buffer) * UNDO_BUFFERS_COUNT);
+ memset(fb.search_term, 0, SEARCH_TERM_MAX_LEN);
+ memset(fb.non_blocking_search_term, 0, SEARCH_TERM_MAX_LEN);
+ fb.indent_len = default_indent_len;
+
+ // change line endings
+ int offset = 0;
+ while((offset = fb_seek_string(&fb, offset, "\r\n")) >= 0)
+ fb_remove(&fb, offset, 1, 1, 1);
+ offset = 0;
+ while((offset = fb_seek_char(&fb, offset, '\r')) >= 0)
+ fb_change(&fb, "\n", 1, offset, 1);
- FILE *new_file = fopen(file_path, "wb");
- fclose(new_file);
- realpath(file_path, fb.file_path);
- remove(file_path);
-
- writef_to_status_bar("opened new file %s", fb.file_path);
- } else if (path_is_folder(fb.file_path)) {
- int len = strlen(fb.file_path);
- if (fb.file_path[len-1] != '/' && len < PATH_MAX-1) {
- fb.file_path[len] = '/';
- fb.file_path[len+1] = '\0';
- }
- } else {
- FILE *file = fopen(fb.file_path, "rb");
- if (file) {
- fseek(file, 0L, SEEK_END);
- long readsize = ftell(file);
- rewind(file);
-
- if (readsize > (long)1.048576e+7) {
- fclose(file);
- die("you are opening a huge file(>10MiB), not allowed");
- return fb;
- // TODO: don't crash
- }
-
- fb.len = readsize;
- fb.capacity = readsize + 100;
-
- fb.contents = xmalloc(fb.capacity);
- fb.contents[0] = 0;
-
- char bom[4] = {0};
- fread(bom, 1, 3, file);
- if (strcmp(bom, "\xEF\xBB\xBF"))
- rewind(file);
- else
- fb.mode |= FB_UTF8_SIGNED;
- fread(fb.contents, 1, readsize, file);
- fclose(file);
-
- fb.syntax_index = -1;
- }
- }
-
- if (!fb.capacity)
- fb.capacity = 100;
- if (!fb.contents) {
- fb.contents = xmalloc(fb.capacity);
- memset(fb.contents, 0, fb.capacity);
- }
- fb.ub = xmalloc(sizeof(struct undo_buffer) * UNDO_BUFFERS_COUNT);
- fb.search_term = xmalloc(SEARCH_TERM_MAX_LEN);
- fb.non_blocking_search_term = xmalloc(SEARCH_TERM_MAX_LEN);
- memset(fb.ub, 0, sizeof(struct undo_buffer) * UNDO_BUFFERS_COUNT);
- memset(fb.search_term, 0, SEARCH_TERM_MAX_LEN);
- memset(fb.non_blocking_search_term, 0, SEARCH_TERM_MAX_LEN);
- fb.indent_len = default_indent_len;
-
- // change line endings
- int offset = 0;
- while((offset = fb_seek_string(&fb, offset, "\r\n")) >= 0)
- fb_remove(&fb, offset, 1, 1, 1);
- offset = 0;
- while((offset = fb_seek_char(&fb, offset, '\r')) >= 0)
- fb_change(&fb, "\n", 1, offset, 1);
-
- call_extension(fb_new_file_opened, &fb);
-
- call_extension(fb_contents_updated, &fb, 0, FB_CONTENT_INIT);
-
- if (res)
- writef_to_status_bar("new fb %s", fb.file_path);
- return fb;
+ call_extension(fb_new_file_opened, &fb);
+
+ call_extension(fb_contents_updated, &fb, 0, FB_CONTENT_INIT);
+
+ if (res)
+ writef_to_status_bar("new fb %s", fb.file_path);
+ return fb;
}
int
fb_new_entry(const char* file_path)
{
- static char full_path[PATH_MAX];
- if (!file_path)
- file_path = "./";
- soft_assert(strlen(file_path) < PATH_MAX, file_path = "./";);
-
- char* res = realpath(file_path, full_path);
-
- if (available_buffer_slots) {
- if (res) {
- for(int n = 0; n < available_buffer_slots; n++) {
- if (file_buffers[n].contents) {
- if (strcmp(file_buffers[n].file_path, full_path) == 0) {
- writef_to_status_bar("buffer exits");
- return n;
- }
+ static char full_path[PATH_MAX];
+ if (!file_path)
+ file_path = "./";
+ soft_assert(strlen(file_path) < PATH_MAX, file_path = "./";);
+
+ char* res = realpath(file_path, full_path);
+
+ if (available_buffer_slots) {
+ if (res) {
+ for(int n = 0; n < available_buffer_slots; n++) {
+ if (file_buffers[n].contents) {
+ if (strcmp(file_buffers[n].file_path, full_path) == 0) {
+ writef_to_status_bar("buffer exits");
+ return n;
+ }
+ }
+ }
+ } else {
+ strcpy(full_path, file_path);
}
- }
- } else {
- strcpy(full_path, file_path);
- }
- for(int n = 0; n < available_buffer_slots; n++) {
- if (!file_buffers[n].contents) {
- if (is_file_type(full_path, ".seproj"))
- return open_seproj(fb_new(full_path));
- file_buffers[n] = fb_new(full_path);
- return n;
- }
+ for(int n = 0; n < available_buffer_slots; n++) {
+ if (!file_buffers[n].contents) {
+ if (is_file_type(full_path, ".seproj"))
+ return open_seproj(fb_new(full_path));
+ file_buffers[n] = fb_new(full_path);
+ return n;
+ }
+ }
}
- }
- if (is_file_type(full_path, ".seproj"))
- return open_seproj(fb_new(full_path));
+ if (is_file_type(full_path, ".seproj"))
+ return open_seproj(fb_new(full_path));
- available_buffer_slots++;
- file_buffers = xrealloc(file_buffers, sizeof(struct file_buffer) * available_buffer_slots);
- file_buffers[available_buffer_slots-1] = fb_new(full_path);
+ available_buffer_slots++;
+ file_buffers = xrealloc(file_buffers, sizeof(struct file_buffer) * available_buffer_slots);
+ file_buffers[available_buffer_slots-1] = fb_new(full_path);
- return available_buffer_slots-1;
+ return available_buffer_slots-1;
}
void
fb_destroy(struct file_buffer* fb)
{
- free(fb->ub);
- free(fb->contents);
- free(fb->file_path);
- free(fb->search_term);
- free(fb->non_blocking_search_term);
- *fb = (struct file_buffer){0};
+ free(fb->ub);
+ free(fb->contents);
+ free(fb->file_path);
+ free(fb->search_term);
+ free(fb->non_blocking_search_term);
+ *fb = (struct file_buffer){0};
}
void
fb_insert(struct file_buffer* fb, const char* new_content, const int len, const int offset, int do_not_callback)
{
- soft_assert(fb, return;);
- soft_assert(fb->contents, fb->capacity = 0;);
- soft_assert(offset <= fb->len && offset >= 0,
- fprintf(stderr, "writing past fb%s\n", fb->file_path);
- return;
- );
+ soft_assert(fb, return;);
+ soft_assert(fb->contents, fb->capacity = 0;);
+ soft_assert(offset <= fb->len && offset >= 0,
+ fprintf(stderr, "writing past fb '%s'\n", fb->file_path);
+ return;
+ );
- if (fb->len + len >= fb->capacity) {
- fb->capacity = fb->len + len + 256;
- fb->contents = xrealloc(fb->contents, fb->capacity);
- }
- if (offset < fb->len)
- memmove(fb->contents+offset+len, fb->contents+offset, fb->len-offset);
- fb->len += len;
+ if (fb->len + len >= fb->capacity) {
+ fb->capacity = fb->len + len + 256;
+ fb->contents = xrealloc(fb->contents, fb->capacity);
+ }
+ if (offset < fb->len)
+ memmove(fb->contents+offset+len, fb->contents+offset, fb->len-offset);
+ fb->len += len;
- memcpy(fb->contents+offset, new_content, len);
- if (!do_not_callback)
- call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
+ memcpy(fb->contents+offset, new_content, len);
+ if (!do_not_callback)
+ call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
}
void
fb_change(struct file_buffer* fb, const char* new_content, const int len, const int offset, int do_not_callback)
{
- soft_assert(offset <= fb->len && offset >= 0, return;);
+ soft_assert(offset <= fb->len && offset >= 0, return;);
- if (offset + len > fb->len) {
- fb->len = offset + len;
- if (fb->len >= fb->capacity) {
- fb->capacity = fb->len + len + 256;
- fb->contents = xrealloc(fb->contents, fb->capacity);
+ if (offset + len > fb->len) {
+ fb->len = offset + len;
+ if (fb->len >= fb->capacity) {
+ fb->capacity = fb->len + len + 256;
+ fb->contents = xrealloc(fb->contents, fb->capacity);
+ }
}
- }
- memcpy(fb->contents+offset, new_content, len);
- if (!do_not_callback)
- call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
+ memcpy(fb->contents+offset, new_content, len);
+ if (!do_not_callback)
+ call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
}
int
fb_remove(struct file_buffer* fb, int offset, int len, int do_not_calculate_charsize, int do_not_callback)
{
- LIMIT(offset, 0, fb->len-1);
- if (len == 0) return 0;
- soft_assert(fb->contents, return 0;);
- soft_assert(offset + len <= fb->len, return 0;);
-
- int removed_len = 0;
- if (do_not_calculate_charsize) {
- removed_len = len;
- } else {
- while (len--) {
- int charsize = utf8_decode_buffer(fb->contents + offset, fb->len - offset, NULL);
- if (fb->len - charsize < 0)
- return 0;
- removed_len += charsize;
+ LIMIT(offset, 0, fb->len-1);
+ if (len == 0) return 0;
+ soft_assert(fb->contents, return 0;);
+ soft_assert(offset + len <= fb->len, return 0;);
+
+ int removed_len = 0;
+ if (do_not_calculate_charsize) {
+ removed_len = len;
+ } else {
+ while (len--) {
+ int charsize = utf8_decode_buffer(fb->contents + offset, fb->len - offset, NULL);
+ if (fb->len - charsize < 0)
+ return 0;
+ removed_len += charsize;
+ }
}
- }
- fb->len -= removed_len;
- memmove(fb->contents+offset, fb->contents+offset+removed_len, fb->len-offset);
- if (!do_not_callback)
- call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
- return removed_len;
+ fb->len -= removed_len;
+ memmove(fb->contents+offset, fb->contents+offset+removed_len, fb->len-offset);
+ if (!do_not_callback)
+ call_extension(fb_contents_updated, fb, offset, FB_CONTENT_NORMAL_EDIT);
+ return removed_len;
}
void
wb_copy_ub_to_current(struct window_buffer* wb)
{
- struct file_buffer* fb = get_fb(wb);
- struct undo_buffer* cub = &fb->ub[fb->current_undo_buffer];
+ struct file_buffer* fb = get_fb(wb);
+ struct undo_buffer* cub = &fb->ub[fb->current_undo_buffer];
- fb->contents = xrealloc(fb->contents, cub->capacity);
- memcpy(fb->contents, cub->contents, cub->capacity);
- fb->len = cub->len;
- fb->capacity = cub->capacity;
+ fb->contents = xrealloc(fb->contents, cub->capacity);
+ memcpy(fb->contents, cub->contents, cub->capacity);
+ fb->len = cub->len;
+ fb->capacity = cub->capacity;
- wb_move_to_offset(wb, cub->cursor_offset, CURSOR_SNAPPED);
- //TODO: remove y_scroll from undo buffer
- wb->y_scroll = cub->y_scroll;
+ wb_move_to_offset(wb, cub->cursor_offset, CURSOR_SNAPPED);
+ //TODO: remove y_scroll from undo buffer
+ wb->y_scroll = cub->y_scroll;
}
void
fb_undo(struct file_buffer* fb)
{
- if (fb->current_undo_buffer == 0) {
- writef_to_status_bar("end of undo buffer");
- return;
- }
- fb->current_undo_buffer--;
- fb->available_redo_buffers++;
+ if (fb->current_undo_buffer == 0) {
+ writef_to_status_bar("end of undo buffer");
+ return;
+ }
+ fb->current_undo_buffer--;
+ fb->available_redo_buffers++;
- wb_copy_ub_to_current(focused_window);
- writef_to_status_bar("undo");
+ wb_copy_ub_to_current(focused_window);
+ writef_to_status_bar("undo");
}
void
fb_redo(struct file_buffer* fb)
{
- if (fb->available_redo_buffers == 0) {
- writef_to_status_bar("end of redo buffer");
- return;
- }
- fb->available_redo_buffers--;
- fb->current_undo_buffer++;
+ if (fb->available_redo_buffers == 0) {
+ writef_to_status_bar("end of redo buffer");
+ return;
+ }
+ fb->available_redo_buffers--;
+ fb->current_undo_buffer++;
- wb_copy_ub_to_current(focused_window);
- writef_to_status_bar("redo");
+ wb_copy_ub_to_current(focused_window);
+ writef_to_status_bar("redo");
}
void
fb_add_to_undo(struct file_buffer* fb, int offset, enum buffer_content_reason reason)
{
- static time_t last_normal_edit;
- static int edits;
+ static time_t last_normal_edit;
+ static int edits;
- if (reason == FB_CONTENT_CURSOR_MOVE) {
- struct undo_buffer* cub = &fb->ub[fb->current_undo_buffer];
- cub->cursor_offset = offset;
- if (focused_window)
- cub->y_scroll = focused_window->y_scroll;
- else
- cub->y_scroll = 0;
- return;
- }
+ if (reason == FB_CONTENT_CURSOR_MOVE) {
+ struct undo_buffer* cub = &fb->ub[fb->current_undo_buffer];
+ cub->cursor_offset = offset;
+ if (focused_window)
+ cub->y_scroll = focused_window->y_scroll;
+ else
+ cub->y_scroll = 0;
+ return;
+ }
- if (reason == FB_CONTENT_NORMAL_EDIT) {
- time_t previous_time = last_normal_edit;
- last_normal_edit = time(NULL);
+ if (reason == FB_CONTENT_NORMAL_EDIT) {
+ time_t previous_time = last_normal_edit;
+ last_normal_edit = time(NULL);
- if (last_normal_edit - previous_time < 2 && edits < 30) {
- edits++;
- goto copy_undo_buffer;
+ if (last_normal_edit - previous_time < 2 && edits < 30) {
+ edits++;
+ goto copy_undo_buffer;
+ } else {
+ edits = 0;
+ }
+ } else if (reason == FB_CONTENT_INIT) {
+ goto copy_undo_buffer;
+ }
+
+ fb->available_redo_buffers = 0;
+ if (fb->current_undo_buffer == UNDO_BUFFERS_COUNT-1) {
+ char* begin_buffer = fb->ub[0].contents;
+ memmove(fb->ub, &(fb->ub[1]), (UNDO_BUFFERS_COUNT-1) * sizeof(struct undo_buffer));
+ fb->ub[fb->current_undo_buffer].contents = begin_buffer;
} else {
- edits = 0;
- }
- } else if (reason == FB_CONTENT_INIT) {
- goto copy_undo_buffer;
- }
-
- fb->available_redo_buffers = 0;
- if (fb->current_undo_buffer == UNDO_BUFFERS_COUNT-1) {
- char* begin_buffer = fb->ub[0].contents;
- memmove(fb->ub, &(fb->ub[1]), (UNDO_BUFFERS_COUNT-1) * sizeof(struct undo_buffer));
- fb->ub[fb->current_undo_buffer].contents = begin_buffer;
- } else {
- fb->current_undo_buffer++;
- }
+ fb->current_undo_buffer++;
+ }
copy_undo_buffer: ;
- struct undo_buffer* cub = fb->ub + fb->current_undo_buffer;
+ struct undo_buffer* cub = fb->ub + fb->current_undo_buffer;
- cub->contents = xrealloc(cub->contents, fb->capacity);
- memcpy(cub->contents, fb->contents, fb->capacity);
- cub->len = fb->len;
- cub->capacity = fb->capacity;
- cub->cursor_offset = offset;
- if (focused_window)
- cub->y_scroll = focused_window->y_scroll;
- else
- cub->y_scroll = 0;
+ cub->contents = xrealloc(cub->contents, fb->capacity);
+ memcpy(cub->contents, fb->contents, fb->capacity);
+ cub->len = fb->len;
+ cub->capacity = fb->capacity;
+ cub->cursor_offset = offset;
+ if (focused_window)
+ cub->y_scroll = focused_window->y_scroll;
+ else
+ cub->y_scroll = 0;
}
char*
fb_get_string_between_offsets(struct file_buffer* fb, int start, int end)
{
- int len = end - start;
+ int len = end - start;
- char* string = xmalloc(len + 1);
- memcpy(string, fb->contents+start, len);
- string[len] = 0;
- return string;
+ char* string = xmalloc(len + 1);
+ memcpy(string, fb->contents+start, len);
+ string[len] = 0;
+ return string;
}
char*
fb_get_selection(struct file_buffer* fb, int* selection_len)
{
- if (!(fb->mode & FB_SELECTION_ON))
- return NULL;
+ if (!(fb->mode & FB_SELECTION_ON))
+ return NULL;
- int start, end;
- if (fb_is_selection_start_top_left(fb)) {
- start = fb->s1o;
- end = fb->s2o+1;
- } else {
- start = fb->s2o;
- end = fb->s1o+1;
- }
- if (selection_len)
- *selection_len = end - start;
- return fb_get_string_between_offsets(fb, start, end);
+ int start, end;
+ if (fb_is_selection_start_top_left(fb)) {
+ start = fb->s1o;
+ end = fb->s2o+1;
+ } else {
+ start = fb->s2o;
+ end = fb->s1o+1;
+ }
+ if (selection_len)
+ *selection_len = end - start;
+ return fb_get_string_between_offsets(fb, start, end);
}
int
fb_is_selection_start_top_left(const struct file_buffer* fb)
{
- return (fb->s1o <= fb->s2o) ? 1 : 0;
+ return (fb->s1o <= fb->s2o) ? 1 : 0;
}
void
fb_remove_selection(struct file_buffer* buffer)
{
- if (!(buffer->mode & FB_SELECTION_ON))
- return;
+ if (!(buffer->mode & FB_SELECTION_ON))
+ return;
- int start, end, len;
- if (fb_is_selection_start_top_left(buffer)) {
- start = buffer->s1o;
- end = buffer->s2o+1;
- } else {
- start = buffer->s2o;
- end = buffer->s1o+1;
- }
- len = end - start;
- fb_remove(buffer, start, len, 1, 1);
- call_extension(fb_contents_updated, buffer, start, FB_CONTENT_BIG_CHANGE);
+ int start, end, len;
+ if (fb_is_selection_start_top_left(buffer)) {
+ start = buffer->s1o;
+ end = buffer->s2o+1;
+ } else {
+ start = buffer->s2o;
+ end = buffer->s1o+1;
+ }
+ len = end - start;
+ fb_remove(buffer, start, len, 1, 1);
+ call_extension(fb_contents_updated, buffer, start, FB_CONTENT_BIG_CHANGE);
}
char*
fb_get_line_at_offset(const struct file_buffer* fb, int offset)
{
- int start = fb_seek_char_backwards(fb, offset, '\n');
- if (start < 0) start = 0;
- int end = fb_seek_char(fb, offset, '\n');
- if (end < 0) end = fb->len-1;
+ int start = fb_seek_char_backwards(fb, offset, '\n');
+ if (start < 0) start = 0;
+ int end = fb_seek_char(fb, offset, '\n');
+ if (end < 0) end = fb->len-1;
- int len = end - start;
+ int len = end - start;
- char* res = xmalloc(len + 1);
- if (len > 0)
- memcpy(res, fb->contents+start, len);
- res[len] = 0;
- return res;
+ char* res = xmalloc(len + 1);
+ if (len > 0)
+ memcpy(res, fb->contents+start, len);
+ res[len] = 0;
+ return res;
}
void
fb_offset_to_xy(struct file_buffer* fb, int offset, int maxx, int y_scroll, int* cx, int* cy, int* xscroll)
{
- *cx = *cy = *xscroll = 0;
- soft_assert(fb, return;);
+ *cx = *cy = *xscroll = 0;
+ soft_assert(fb, return;);
- if (fb->len <= 0)
- return;
- LIMIT(offset, 0, fb->len);
-
- char* repl = fb->contents;
- char* last = repl + offset;
-
- char* new_repl;
- if (wrap_buffer && maxx > 0) {
- int yscroll = 0;
- while ((new_repl = memchr(repl, '\n', last - repl))) {
- if (++yscroll >= y_scroll)
- break;
- repl = new_repl+1;
- }
- *cy = yscroll - y_scroll;
- } else {
- while ((new_repl = memchr(repl, '\n', last - repl))) {
- repl = new_repl+1;
- *cy += 1;
+ if (fb->len <= 0)
+ return;
+ LIMIT(offset, 0, fb->len);
+
+ char* repl = fb->contents;
+ char* last = repl + offset;
+
+ char* new_repl;
+ if (wrap_buffer && maxx > 0) {
+ int yscroll = 0;
+ while ((new_repl = memchr(repl, '\n', last - repl))) {
+ if (++yscroll >= y_scroll)
+ break;
+ repl = new_repl+1;
+ }
+ *cy = yscroll - y_scroll;
+ } else {
+ while ((new_repl = memchr(repl, '\n', last - repl))) {
+ repl = new_repl+1;
+ *cy += 1;
+ }
+ *cy -= y_scroll;
}
- *cy -= y_scroll;
- }
- while (repl < last) {
- if (wrap_buffer && maxx > 0 && (*repl == '\n' || *cx >= maxx)) {
- *cy += 1;
- *cx = 0;
- repl++;
- continue;
- }
- if (*repl == '\t') {
- repl++;
- if (*cx <= 0) *cx += 1;
- while (*cx % tabspaces != 0) *cx += 1;
- *cx += 1;
- continue;
+ while (repl < last) {
+ if (wrap_buffer && maxx > 0 && (*repl == '\n' || *cx >= maxx)) {
+ *cy += 1;
+ *cx = 0;
+ repl++;
+ continue;
+ }
+ if (*repl == '\t') {
+ repl++;
+ if (*cx <= 0) *cx += 1;
+ while (*cx % tabspaces != 0) *cx += 1;
+ *cx += 1;
+ continue;
+ }
+ rune_t u;
+ repl += utf8_decode_buffer(repl, last - repl, &u);
+ *cx += wcwidth(u);
}
- rune_t u;
- repl += utf8_decode_buffer(repl, last - repl, &u);
- *cx += wcwidth(u);
- }
- // TODO: make customizable
- // -1 = wrap, >= 0 is padding or something like that
- const int padding = 3;
+ // TODO: make customizable
+ // -1 = wrap, >= 0 is padding or something like that
+ const int padding = 3;
- if ((*cx - maxx) + padding > 0)
- *xscroll = (*cx - maxx) + padding;
+ if ((*cx - maxx) + padding > 0)
+ *xscroll = (*cx - maxx) + padding;
}
////////////////////////////////////////////////
@@ -621,135 +621,135 @@ fb_offset_to_xy(struct file_buffer* fb, int offset, int maxx, int y_scroll, int*
struct window_buffer
wb_new(int fb_index)
{
- struct window_buffer wb = {0};
- wb.fb_index = fb_index;
- if (path_is_folder(get_fb(&wb)->file_path)) {
- wb.mode = WB_FILE_BROWSER;
- writef_to_status_bar("opened file browser %s", get_fb(&wb)->file_path);
- }
+ struct window_buffer wb = {0};
+ wb.fb_index = fb_index;
+ if (path_is_folder(get_fb(&wb)->file_path)) {
+ wb.mode = WB_FILE_BROWSER;
+ writef_to_status_bar("opened file browser %s", get_fb(&wb)->file_path);
+ }
- return wb;
+ return wb;
}
void
wb_move_on_line(struct window_buffer* wb, int amount, enum cursor_reason callback_reason)
{
- const struct file_buffer* fb = get_fb(wb);
- if (fb->len <= 0)
- return;
+ const struct file_buffer* fb = get_fb(wb);
+ if (fb->len <= 0)
+ return;
- if (amount < 0) {
- while (wb->cursor_offset > 0 && fb->contents[wb->cursor_offset - 1] != '\n' && amount < 0) {
- wb->cursor_offset--;
- if ((fb->contents[wb->cursor_offset] & 0xC0) == 0x80) // if byte starts with 0b10
- continue; // byte is UTF-8 extender
- amount++;
- }
- LIMIT(wb->cursor_offset, 0, fb->len);
- } else if (amount > 0) {
- for (int charsize = 0;
- wb->cursor_offset < fb->len && amount > 0 && fb->contents[wb->cursor_offset + charsize] != '\n';
- wb->cursor_offset += charsize, amount--) {
- rune_t u;
- charsize = utf8_decode_buffer(fb->contents + wb->cursor_offset, fb->len - wb->cursor_offset, &u);
- if (u != '\n' && u != '\t')
- if (wcwidth(u) <= 0)
- amount++;
- if (wb->cursor_offset + charsize > fb->len)
- break;
+ if (amount < 0) {
+ while (wb->cursor_offset > 0 && fb->contents[wb->cursor_offset - 1] != '\n' && amount < 0) {
+ wb->cursor_offset--;
+ if ((fb->contents[wb->cursor_offset] & 0xC0) == 0x80) // if byte starts with 0b10
+ continue; // byte is UTF-8 extender
+ amount++;
+ }
+ LIMIT(wb->cursor_offset, 0, fb->len);
+ } else if (amount > 0) {
+ for (int charsize = 0;
+ wb->cursor_offset < fb->len && amount > 0 && fb->contents[wb->cursor_offset + charsize] != '\n';
+ wb->cursor_offset += charsize, amount--) {
+ rune_t u;
+ charsize = utf8_decode_buffer(fb->contents + wb->cursor_offset, fb->len - wb->cursor_offset, &u);
+ if (u != '\n' && u != '\t')
+ if (wcwidth(u) <= 0)
+ amount++;
+ if (wb->cursor_offset + charsize > fb->len)
+ break;
+ }
}
- }
- if (callback_reason)
- call_extension(wb_cursor_movement, wb, callback_reason);
+ if (callback_reason)
+ call_extension(wb_cursor_movement, wb, callback_reason);
}
void
wb_move_offset_relative(struct window_buffer* wb, int amount, enum cursor_reason callback_reason)
{
- //NOTE: this does not check if the character on this offset is the start of a valid utf8 char
- const struct file_buffer* fb = get_fb((wb));
- if (fb->len <= 0)
- return;
- wb->cursor_offset += amount;
- LIMIT(wb->cursor_offset, 0, fb->len);
+ //NOTE: this does not check if the character on this offset is the start of a valid utf8 char
+ const struct file_buffer* fb = get_fb((wb));
+ if (fb->len <= 0)
+ return;
+ wb->cursor_offset += amount;
+ LIMIT(wb->cursor_offset, 0, fb->len);
- if (callback_reason)
- call_extension(wb_cursor_movement, wb, callback_reason);
+ if (callback_reason)
+ call_extension(wb_cursor_movement, wb, callback_reason);
}
void
wb_move_lines(struct window_buffer* wb, int amount, enum cursor_reason callback_reason)
{
- const struct file_buffer* fb = get_fb((wb));
- if (fb->len <= 0)
- return;
- int offset = wb->cursor_offset;
- if (amount > 0) {
- while (amount-- && offset >= 0) {
- int new_offset = fb_seek_char(fb, offset, '\n');
- if (new_offset < 0) {
- offset = fb->len;
- break;
- }
- offset = new_offset+1;
- }
- } else if (amount < 0) {
- while (amount++ && offset >= 0)
- offset = fb_seek_char_backwards(fb, offset, '\n')-1;
- }
- wb_move_to_offset(wb, offset, callback_reason);
+ const struct file_buffer* fb = get_fb((wb));
+ if (fb->len <= 0)
+ return;
+ int offset = wb->cursor_offset;
+ if (amount > 0) {
+ while (amount-- && offset >= 0) {
+ int new_offset = fb_seek_char(fb, offset, '\n');
+ if (new_offset < 0) {
+ offset = fb->len;
+ break;
+ }
+ offset = new_offset+1;
+ }
+ } else if (amount < 0) {
+ while (amount++ && offset >= 0)
+ offset = fb_seek_char_backwards(fb, offset, '\n')-1;
+ }
+ wb_move_to_offset(wb, offset, callback_reason);
}
void
wb_move_to_offset(struct window_buffer* wb, int offset, enum cursor_reason callback_reason)
{
- //NOTE: this does not check if the character on this offset is the start of a valid utf8 char
- const struct file_buffer* fb = get_fb((wb));
- if (fb->len <= 0)
- return;
- LIMIT(offset, 0, fb->len);
- wb->cursor_offset = offset;
+ //NOTE: this does not check if the character on this offset is the start of a valid utf8 char
+ const struct file_buffer* fb = get_fb((wb));
+ if (fb->len <= 0)
+ return;
+ LIMIT(offset, 0, fb->len);
+ wb->cursor_offset = offset;
- if (callback_reason)
- call_extension(wb_cursor_movement, wb, callback_reason);
+ if (callback_reason)
+ call_extension(wb_cursor_movement, wb, callback_reason);
}
void
wb_move_to_x(struct window_buffer* wb, int x, enum cursor_reason callback_reason)
{
- soft_assert(wb, return;);
- struct file_buffer* fb = get_fb(wb);
-
- int offset = fb_seek_char_backwards(fb, wb->cursor_offset, '\n');
- if (offset < 0)
- offset = 0;
- wb_move_to_offset(wb, offset, 0);
-
- int x_counter = 0;
-
- while (offset < fb->len) {
- if (fb->contents[offset] == '\t') {
- offset++;
- if (x_counter <= 0) x_counter += 1;
- while (x_counter % tabspaces != 0) x_counter += 1;
- x_counter += 1;
- continue;
- } else if (fb->contents[offset] == '\n') {
- break;
- }
- rune_t u = 0;
- int charsize = utf8_decode_buffer(fb->contents + offset, fb->len - offset, &u);
- x_counter += wcwidth(u);
- if (x_counter <= x) {
- offset += charsize;
- if (x_counter == x)
- break;
- } else {
- break;
+ soft_assert(wb, return;);
+ struct file_buffer* fb = get_fb(wb);
+
+ int offset = fb_seek_char_backwards(fb, wb->cursor_offset, '\n');
+ if (offset < 0)
+ offset = 0;
+ wb_move_to_offset(wb, offset, 0);
+
+ int x_counter = 0;
+
+ while (offset < fb->len) {
+ if (fb->contents[offset] == '\t') {
+ offset++;
+ if (x_counter <= 0) x_counter += 1;
+ while (x_counter % tabspaces != 0) x_counter += 1;
+ x_counter += 1;
+ continue;
+ } else if (fb->contents[offset] == '\n') {
+ break;
+ }
+ rune_t u = 0;
+ int charsize = utf8_decode_buffer(fb->contents + offset, fb->len - offset, &u);
+ x_counter += wcwidth(u);
+ if (x_counter <= x) {
+ offset += charsize;
+ if (x_counter == x)
+ break;
+ } else {
+ break;
+ }
}
- }
- wb_move_to_offset(wb, offset, callback_reason);
+ wb_move_to_offset(wb, offset, callback_reason);
}
////////////////////////////////////////////////
@@ -759,173 +759,173 @@ wb_move_to_x(struct window_buffer* wb, int x, enum cursor_reason callback_reason
static int
is_correct_mode(enum window_split_mode mode, enum move_directons move)
{
- if (move == MOVE_RIGHT || move == MOVE_LEFT)
- return (mode == WINDOW_HORISONTAL);
- if (move == MOVE_UP || move == MOVE_DOWN)
- return (mode == WINDOW_VERTICAL);
- return 0;
+ if (move == MOVE_RIGHT || move == MOVE_LEFT)
+ return (mode == WINDOW_HORISONTAL);
+ if (move == MOVE_UP || move == MOVE_DOWN)
+ return (mode == WINDOW_VERTICAL);
+ return 0;
}
void
window_node_split(struct window_split_node* parent, float ratio, enum window_split_mode mode)
{
- soft_assert(parent, return;);
- soft_assert(parent->mode == WINDOW_SINGULAR, return;);
- soft_assert(mode != WINDOW_SINGULAR, return;);
-
- if ((parent->maxx - parent->minx < MIN_WINDOW_SPLIT_SIZE_HORISONTAL && mode == WINDOW_HORISONTAL)
- || (parent->maxy - parent->miny < MIN_WINDOW_SPLIT_SIZE_VERTICAL && mode == WINDOW_VERTICAL))
- return;
-
- parent->node1 = xmalloc(sizeof(struct window_split_node));
- *parent->node1 = *parent;
- parent->node1->search = xmalloc(SEARCH_TERM_MAX_LEN);
- parent->node1->parent = parent;
- parent->node1->node1 = NULL;
- parent->node1->node2 = NULL;
-
-
- parent->node2 = xmalloc(sizeof(struct window_split_node));
- *parent->node2 = *parent;
- parent->node2->search = xmalloc(SEARCH_TERM_MAX_LEN);
- parent->node2->parent = parent;
- parent->node2->node1 = NULL;
- parent->node2->node2 = NULL;
-
- if (parent->mode == WINDOW_HORISONTAL) {
- // NOTE: if the window resizing is changed, change in draw tree function as well
- int middlex = ((float)(parent->maxx - parent->minx) * parent->ratio) + parent->minx;
- parent->node1->minx = parent->minx;
- parent->node1->miny = parent->miny;
- parent->node1->maxx = middlex;
- parent->node1->maxy = parent->maxy;
- parent->node2->minx = middlex+2;
- parent->node2->miny = parent->miny;
- parent->node2->maxx = parent->maxx;
- parent->node2->maxy = parent->maxy;
- } else if (parent->mode == WINDOW_VERTICAL) {
- // NOTE: if the window resizing is changed, change in draw tree function as well
- int middley = ((float)(parent->maxy - parent->miny) * parent->ratio) + parent->miny;
- parent->node1->minx = parent->minx;
- parent->node1->miny = parent->miny;
- parent->node1->maxx = parent->maxx;
- parent->node1->maxy = middley;
- parent->node2->minx = parent->miny;
- parent->node2->miny = middley;
- parent->node2->maxx = parent->maxx;
- parent->node2->maxy = parent->maxy;
- }
-
- parent->mode = mode;
- parent->ratio = ratio;
- parent->wb = (struct window_buffer){0};
+ soft_assert(parent, return;);
+ soft_assert(parent->mode == WINDOW_SINGULAR, return;);
+ soft_assert(mode != WINDOW_SINGULAR, return;);
+
+ if ((parent->maxx - parent->minx < MIN_WINDOW_SPLIT_SIZE_HORISONTAL && mode == WINDOW_HORISONTAL)
+ || (parent->maxy - parent->miny < MIN_WINDOW_SPLIT_SIZE_VERTICAL && mode == WINDOW_VERTICAL))
+ return;
+
+ parent->node1 = xmalloc(sizeof(struct window_split_node));
+ *parent->node1 = *parent;
+ parent->node1->search = xmalloc(SEARCH_TERM_MAX_LEN);
+ parent->node1->parent = parent;
+ parent->node1->node1 = NULL;
+ parent->node1->node2 = NULL;
+
+
+ parent->node2 = xmalloc(sizeof(struct window_split_node));
+ *parent->node2 = *parent;
+ parent->node2->search = xmalloc(SEARCH_TERM_MAX_LEN);
+ parent->node2->parent = parent;
+ parent->node2->node1 = NULL;
+ parent->node2->node2 = NULL;
+
+ if (parent->mode == WINDOW_HORISONTAL) {
+ // NOTE: if the window resizing is changed, change in draw tree function as well
+ int middlex = ((float)(parent->maxx - parent->minx) * parent->ratio) + parent->minx;
+ parent->node1->minx = parent->minx;
+ parent->node1->miny = parent->miny;
+ parent->node1->maxx = middlex;
+ parent->node1->maxy = parent->maxy;
+ parent->node2->minx = middlex+2;
+ parent->node2->miny = parent->miny;
+ parent->node2->maxx = parent->maxx;
+ parent->node2->maxy = parent->maxy;
+ } else if (parent->mode == WINDOW_VERTICAL) {
+ // NOTE: if the window resizing is changed, change in draw tree function as well
+ int middley = ((float)(parent->maxy - parent->miny) * parent->ratio) + parent->miny;
+ parent->node1->minx = parent->minx;
+ parent->node1->miny = parent->miny;
+ parent->node1->maxx = parent->maxx;
+ parent->node1->maxy = middley;
+ parent->node2->minx = parent->miny;
+ parent->node2->miny = middley;
+ parent->node2->maxx = parent->maxx;
+ parent->node2->maxy = parent->maxy;
+ }
+
+ parent->mode = mode;
+ parent->ratio = ratio;
+ parent->wb = (struct window_buffer){0};
}
struct window_split_node*
window_node_delete(struct window_split_node* node)
{
- if (!node->parent) {
- writef_to_status_bar("can't close root winodw");
- return node;
- }
- struct window_split_node* old = node;
- node = node->parent;
- struct window_split_node* other = (node->node1 == old) ? node->node2 : node->node1;
- free(old->search);
- free(old);
-
- struct window_split_node* parent = node->parent;
- *node = *other;
- if (other->mode != WINDOW_SINGULAR) {
- other->node1->parent = node;
- other->node2->parent = node;
- }
- free(other);
- node->parent = parent;
+ if (!node->parent) {
+ writef_to_status_bar("can't close root winodw");
+ return node;
+ }
+ struct window_split_node* old = node;
+ node = node->parent;
+ struct window_split_node* other = (node->node1 == old) ? node->node2 : node->node1;
+ free(old->search);
+ free(old);
+
+ struct window_split_node* parent = node->parent;
+ *node = *other;
+ if (other->mode != WINDOW_SINGULAR) {
+ other->node1->parent = node;
+ other->node2->parent = node;
+ }
+ free(other);
+ node->parent = parent;
- return node;
+ return node;
}
void
window_node_draw_tree_to_screen(struct window_split_node* root, int minx, int miny, int maxx, int maxy)
{
- soft_assert(root, return;);
-
- if (root->mode == WINDOW_SINGULAR) {
- LIMIT(maxx, 0, screen.col-1);
- LIMIT(maxy, 0, screen.row-1);
- LIMIT(minx, 0, maxx);
- LIMIT(miny, 0, maxy);
- root->minx = minx;
- root->miny = miny;
- root->maxx = maxx;
- root->maxy = maxy;
- if (root->wb.mode != 0) {
- int wn_custom_window_draw_callback_exists = 0;
- extension_callback_exists(wn_custom_window_draw, wn_custom_window_draw_callback_exists = 1;);
- soft_assert(wn_custom_window_draw_callback_exists, return;);
-
- call_extension(wn_custom_window_draw, root);
-
- return;
- } else {
- window_node_draw_to_screen(root);
- }
- } else if (root->mode == WINDOW_HORISONTAL) {
- // NOTE: if the window resizing is changed, change in split function as well
- int middlex = ((float)(maxx - minx) * root->ratio) + minx;
+ soft_assert(root, return;);
+
+ if (root->mode == WINDOW_SINGULAR) {
+ LIMIT(maxx, 0, screen.col-1);
+ LIMIT(maxy, 0, screen.row-1);
+ LIMIT(minx, 0, maxx);
+ LIMIT(miny, 0, maxy);
+ root->minx = minx;
+ root->miny = miny;
+ root->maxx = maxx;
+ root->maxy = maxy;
+ if (root->wb.mode != 0) {
+ int wn_custom_window_draw_callback_exists = 0;
+ extension_callback_exists(wn_custom_window_draw, wn_custom_window_draw_callback_exists = 1;);
+ soft_assert(wn_custom_window_draw_callback_exists, return;);
+
+ call_extension(wn_custom_window_draw, root);
+
+ return;
+ } else {
+ window_node_draw_to_screen(root);
+ }
+ } else if (root->mode == WINDOW_HORISONTAL) {
+ // NOTE: if the window resizing is changed, change in split function as well
+ int middlex = ((float)(maxx - minx) * root->ratio) + minx;
- // print seperator
- screen_set_region(middlex+1, miny, middlex+1, maxy, L'│');
+ // print seperator
+ screen_set_region(middlex+1, miny, middlex+1, maxy, L'│');
- window_node_draw_tree_to_screen(root->node1, minx, miny, middlex, maxy);
- window_node_draw_tree_to_screen(root->node2, middlex+2, miny, maxx, maxy);
+ window_node_draw_tree_to_screen(root->node1, minx, miny, middlex, maxy);
+ window_node_draw_tree_to_screen(root->node2, middlex+2, miny, maxx, maxy);
- for (int y = miny; y < maxy+1; y++)
- xdrawline(middlex+1, y, middlex+2);
- } else if (root->mode == WINDOW_VERTICAL) {
- // NOTE: if the window resizing is changed, change in split function as well
- int middley = ((float)(maxy - miny) * root->ratio) + miny;
+ for (int y = miny; y < maxy+1; y++)
+ xdrawline(middlex+1, y, middlex+2);
+ } else if (root->mode == WINDOW_VERTICAL) {
+ // NOTE: if the window resizing is changed, change in split function as well
+ int middley = ((float)(maxy - miny) * root->ratio) + miny;
- window_node_draw_tree_to_screen(root->node1, minx, miny, maxx, middley);
- window_node_draw_tree_to_screen(root->node2, minx, middley, maxx, maxy);
- }
+ window_node_draw_tree_to_screen(root->node1, minx, miny, maxx, middley);
+ window_node_draw_tree_to_screen(root->node2, minx, middley, maxx, maxy);
+ }
}
void
window_node_move_all_cursors_on_same_fb(struct window_split_node* root, struct window_split_node* excluded, int fb_index, int offset,
- void(movement)(struct window_buffer*, int, enum cursor_reason),
- int move, enum cursor_reason reason)
+ void(movement)(struct window_buffer*, int, enum cursor_reason),
+ int move, enum cursor_reason reason)
{
- if (root->mode == WINDOW_SINGULAR) {
- if (root->wb.fb_index == fb_index && root->wb.cursor_offset >= offset && root != excluded)
- movement(&root->wb, move, reason);
- } else {
- window_node_move_all_cursors_on_same_fb(root->node1, excluded, fb_index, offset, movement, move, reason);
- window_node_move_all_cursors_on_same_fb(root->node2, excluded, fb_index, offset, movement, move, reason);
- }
+ if (root->mode == WINDOW_SINGULAR) {
+ if (root->wb.fb_index == fb_index && root->wb.cursor_offset >= offset && root != excluded)
+ movement(&root->wb, move, reason);
+ } else {
+ window_node_move_all_cursors_on_same_fb(root->node1, excluded, fb_index, offset, movement, move, reason);
+ window_node_move_all_cursors_on_same_fb(root->node2, excluded, fb_index, offset, movement, move, reason);
+ }
}
void
window_node_move_all_yscrolls(struct window_split_node* root, struct window_split_node* excluded, int fb_index, int offset, int move)
{
- if (root->mode == WINDOW_SINGULAR) {
- if (root->wb.fb_index == fb_index && root->wb.cursor_offset >= offset && root != excluded)
- root->wb.y_scroll += move;
- } else {
- window_node_move_all_yscrolls(root->node1, excluded, fb_index, offset, move);
- window_node_move_all_yscrolls(root->node2, excluded, fb_index, offset, move);
- }
+ if (root->mode == WINDOW_SINGULAR) {
+ if (root->wb.fb_index == fb_index && root->wb.cursor_offset >= offset && root != excluded)
+ root->wb.y_scroll += move;
+ } else {
+ window_node_move_all_yscrolls(root->node1, excluded, fb_index, offset, move);
+ window_node_move_all_yscrolls(root->node2, excluded, fb_index, offset, move);
+ }
}
int
window_other_nodes_contain_fb(struct window_split_node* node, struct window_split_node* root)
{
- if (root->mode == WINDOW_SINGULAR)
- return (root->wb.fb_index == node->wb.fb_index && root != node);
+ if (root->mode == WINDOW_SINGULAR)
+ return (root->wb.fb_index == node->wb.fb_index && root != node);
- return (window_other_nodes_contain_fb(node, root->node1) ||
- window_other_nodes_contain_fb(node, root->node2));
+ return (window_other_nodes_contain_fb(node, root->node1) ||
+ window_other_nodes_contain_fb(node, root->node2));
}
// TODO: create a distance type function and use that instead (from the current cursor position)?
@@ -933,66 +933,66 @@ window_other_nodes_contain_fb(struct window_split_node* node, struct window_spli
struct window_split_node*
window_switch_to_window(struct window_split_node* node, enum move_directons move)
{
- soft_assert(node, return &root_node;);
- if (!node->parent) return node;
- soft_assert(node->mode == WINDOW_SINGULAR,
- while(node->mode != WINDOW_SINGULAR)
- node = node->node1;
- return node;
- );
- struct window_split_node* old_node = node;
-
- if (move == MOVE_RIGHT || move == MOVE_DOWN) {
- // traverse up the tree to the right
- for (; node->parent; node = node->parent) {
- if (is_correct_mode(node->parent->mode, move) && node->parent->node1 == node) {
- // traverse down until a screen is found
- node = node->parent->node2;
- while(node->mode != WINDOW_SINGULAR)
- node = node->node1;
-
- return node;
- }
- }
- } else if (move == MOVE_LEFT || move == MOVE_UP) {
- // traverse up the tree to the left
- for (; node->parent; node = node->parent) {
- if (is_correct_mode(node->parent->mode, move) && node->parent->node2 == node) {
- // traverse down until a screen is found
- node = node->parent->node1;
- while(node->mode != WINDOW_SINGULAR)
- node = node->node2;
-
- return node;
- }
+ soft_assert(node, return &root_node;);
+ if (!node->parent) return node;
+ soft_assert(node->mode == WINDOW_SINGULAR,
+ while(node->mode != WINDOW_SINGULAR)
+ node = node->node1;
+ return node;
+ );
+ struct window_split_node* old_node = node;
+
+ if (move == MOVE_RIGHT || move == MOVE_DOWN) {
+ // traverse up the tree to the right
+ for (; node->parent; node = node->parent) {
+ if (is_correct_mode(node->parent->mode, move) && node->parent->node1 == node) {
+ // traverse down until a screen is found
+ node = node->parent->node2;
+ while(node->mode != WINDOW_SINGULAR)
+ node = node->node1;
+
+ return node;
+ }
+ }
+ } else if (move == MOVE_LEFT || move == MOVE_UP) {
+ // traverse up the tree to the left
+ for (; node->parent; node = node->parent) {
+ if (is_correct_mode(node->parent->mode, move) && node->parent->node2 == node) {
+ // traverse down until a screen is found
+ node = node->parent->node1;
+ while(node->mode != WINDOW_SINGULAR)
+ node = node->node2;
+
+ return node;
+ }
+ }
}
- }
- return old_node;
+ return old_node;
}
void
window_node_resize(struct window_split_node* node, enum move_directons move, float amount)
{
- for (; node; node = node->parent) {
- if (is_correct_mode(node->mode, move)) {
- float amount = (move == MOVE_RIGHT || move == MOVE_LEFT) ? 0.1f : 0.05f;
- if (move == MOVE_RIGHT || move == MOVE_DOWN) amount = -amount;
- node->ratio -= amount;
- LIMIT(node->ratio, 0.001f, 0.95f);
- return;
+ for (; node; node = node->parent) {
+ if (is_correct_mode(node->mode, move)) {
+ float amount = (move == MOVE_RIGHT || move == MOVE_LEFT) ? 0.1f : 0.05f;
+ if (move == MOVE_RIGHT || move == MOVE_DOWN) amount = -amount;
+ node->ratio -= amount;
+ LIMIT(node->ratio, 0.001f, 0.95f);
+ return;
+ }
}
- }
}
void
window_node_resize_absolute(struct window_split_node* node, enum move_directons move, float amount)
{
- for (; node; node = node->parent) {
- if (is_correct_mode(node->mode, move)) {
- node->ratio = amount;
- LIMIT(node->ratio, 0.001f, 0.95f);
- return;
+ for (; node; node = node->parent) {
+ if (is_correct_mode(node->mode, move)) {
+ node->ratio = amount;
+ LIMIT(node->ratio, 0.001f, 0.95f);
+ return;
+ }
}
- }
}
diff --git a/buffer.h b/buffer.h
@@ -24,52 +24,57 @@ extern struct window_buffer* focused_window;
#define UNDO_BUFFERS_COUNT 128
struct undo_buffer {
- char* contents; // not null terminated
- int len, capacity;
- int cursor_offset;
- int y_scroll;
+ char* contents; // not null terminated
+ int len, capacity;
+ int cursor_offset;
+ int y_scroll;
};
enum buffer_flags {
- FB_SELECTION_ON = 1 << 0,
- FB_BLOCK_SELECT = 1 << 1,
- FB_LINE_SELECT = 1 << 2,
- FB_SELECT_MASK = (FB_SELECTION_ON | FB_BLOCK_SELECT | FB_LINE_SELECT),
- FB_SELECT_MODE_MASK = (FB_BLOCK_SELECT | FB_LINE_SELECT),
- FB_READ_ONLY = 1 << 3,
- FB_UTF8_SIGNED = 1 << 4,
- FB_SEARCH_BLOCKING = 1 << 5,
- FB_SEARCH_BLOCKING_IDLE = 1 << 6,
- FB_SEARCH_BLOCKING_MASK = (FB_SEARCH_BLOCKING | FB_SEARCH_BLOCKING_IDLE),
- FB_SEARCH_NON_BLOCKING = 1 << 7,
- FB_SEARCH_BLOCKING_BACKWARDS = 1 << 8,
- FB_SEARCH_NON_BLOCKING_BACKWARDS = 1 << 9,
+ FB_SELECTION_ON = 1 << 0,
+ FB_BLOCK_SELECT = 1 << 1,
+ FB_LINE_SELECT = 1 << 2,
+ FB_SELECT_MASK = (FB_SELECTION_ON | FB_BLOCK_SELECT | FB_LINE_SELECT),
+ FB_SELECT_MODE_MASK = (FB_BLOCK_SELECT | FB_LINE_SELECT),
+ FB_READ_ONLY = 1 << 3,
+ FB_UTF8_SIGNED = 1 << 4,
+ FB_SEARCH_BLOCKING = 1 << 5,
+ FB_SEARCH_BLOCKING_IDLE = 1 << 6,
+ FB_SEARCH_BLOCKING_MASK = (FB_SEARCH_BLOCKING | FB_SEARCH_BLOCKING_IDLE),
+ FB_SEARCH_NON_BLOCKING = 1 << 7,
+ FB_SEARCH_BLOCKING_BACKWARDS = 1 << 8,
+ FB_SEARCH_NON_BLOCKING_BACKWARDS = 1 << 9,
};
struct file_buffer {
- char* file_path;
- char* contents; // !! NOT NULL TERMINATED !!
- int len;
- int capacity;
- int mode; // buffer_flags
- struct undo_buffer* ub;
- // TODO: int file_buffer_len;
- int current_undo_buffer;
- int available_redo_buffers;
- int s1o, s2o; // selection start offset and end offset
- char* search_term;
- char* non_blocking_search_term;
- int syntax_index;
- unsigned int indent_len; // amount of spaces, if 0 tab is used
+ char* file_path;
+ char* contents; // !! NOT NULL TERMINATED !!
+ int len;
+ int capacity;
+ int mode; // buffer_flags
+ struct undo_buffer* ub;
+ int current_undo_buffer;
+ int available_redo_buffers;
+ int s1o, s2o; // selection start offset and end offset
+
+ // used for "ctrl+f" searches
+ char* search_term;
+ // used for vim-style f searches
+ char* non_blocking_search_term;
+
+ unsigned int indent_len; // amount of spaces, if 0 tab is used
+
+ // required by syntax.h, not used by anything else
+ int syntax_index;
};
enum buffer_content_reason {
- FB_CONTENT_DO_NOT_CALLBACK = 0,
- FB_CONTENT_OPERATION_ENDED,
- FB_CONTENT_NORMAL_EDIT,
- FB_CONTENT_BIG_CHANGE,
- FB_CONTENT_INIT,
- FB_CONTENT_CURSOR_MOVE,
+ FB_CONTENT_DO_NOT_CALLBACK = 0,
+ FB_CONTENT_OPERATION_ENDED,
+ FB_CONTENT_NORMAL_EDIT,
+ FB_CONTENT_BIG_CHANGE,
+ FB_CONTENT_INIT,
+ FB_CONTENT_CURSOR_MOVE,
};
struct file_buffer* get_fb(struct window_buffer* wb);
@@ -118,28 +123,28 @@ void fb_offset_to_xy(struct file_buffer* fb, int offset, int maxx, int y_scroll,
#define WB_MODES_DEFAULT_END 1
struct window_buffer {
- int y_scroll;
- int cursor_offset;
- int cursor_col;
-
- int fb_index; // index into an array storing file buffers
-
- ///////////////////////////////////
- // you may implement your own "modes"
- // it will run a callback where you can render your window
- // a callback allowing you to override the default input callback
- // is also provided
- // TODO:↑
- // see extensions/window_modes for other modes
- unsigned int mode; // WB_NORMAL = 0
+ int y_scroll;
+ int cursor_offset;
+ int cursor_col;
+
+ int fb_index; // index into an array storing file buffers
+
+ ///////////////////////////////////
+ // you may implement your own "modes"
+ // it will run a callback where you can render your window
+ // a callback allowing you to override the default input callback
+ // is also provided
+ // TODO:↑
+ // see extensions/window_modes for other modes
+ unsigned int mode; // WB_NORMAL = 0
};
enum cursor_reason {
- CURSOR_DO_NOT_CALLBACK = 0,
- CURSOR_COMMAND_MOVEMENT = 1,
- CURSOR_UP_DOWN_MOVEMENT,
- CURSOR_RIGHT_LEFT_MOVEMENT,
- CURSOR_SNAPPED,
+ CURSOR_DO_NOT_CALLBACK = 0,
+ CURSOR_COMMAND_MOVEMENT = 1,
+ CURSOR_UP_DOWN_MOVEMENT,
+ CURSOR_RIGHT_LEFT_MOVEMENT,
+ CURSOR_SNAPPED,
};
struct window_buffer wb_new(int buffer_index);
@@ -149,27 +154,27 @@ struct window_buffer wb_new(int buffer_index);
//
enum window_split_mode {
- WINDOW_SINGULAR,
- WINDOW_HORISONTAL,
- WINDOW_VERTICAL,
- WINDOW_FILE_BROWSER,
+ WINDOW_SINGULAR,
+ WINDOW_HORISONTAL,
+ WINDOW_VERTICAL,
+ WINDOW_FILE_BROWSER,
};
struct window_split_node {
- struct window_buffer wb;
- enum window_split_mode mode;
- float ratio;
- struct window_split_node *node1, *node2, *parent;
- int minx, miny, maxx, maxy; // position informatin from the last frame
- char* search;
- int selected;
+ struct window_buffer wb;
+ enum window_split_mode mode;
+ float ratio;
+ struct window_split_node *node1, *node2, *parent;
+ int minx, miny, maxx, maxy; // position informatin from the last frame
+ char* search;
+ int selected;
};
enum move_directons {
- MOVE_RIGHT,
- MOVE_LEFT,
- MOVE_UP,
- MOVE_DOWN,
+ MOVE_RIGHT,
+ MOVE_LEFT,
+ MOVE_UP,
+ MOVE_DOWN,
};
////////////////////////////////////////////////
diff --git a/extensions/syntax/gd.h b/extensions/syntax/gd.h
@@ -1,99 +1,99 @@
#include "handy_defines.h"
const struct syntax_scheme_entry gd_syntax[] = {
- // Coloring type arguments Color
+ // Coloring type arguments Color
- // strings
+ // strings
#ifdef string_color
- {COLOR_AROUND_TO_LINE, {"\"", "\""}, string_color},
- {COLOR_AROUND, {"\"\"\"", "\"\"\""}, string_color},
- {COLOR_AROUND_TO_LINE, {"'", "'"}, string_color},
- {COLOR_INSIDE_TO_LINE, {"$", "."}, string_color},
- {COLOR_INSIDE_TO_LINE, {"$", " "}, string_color},
- {COLOR_INSIDE_TO_LINE, {"$", "("}, string_color},
- {COLOR_INSIDE_TO_LINE, {"$", "["}, string_color},
- {COLOR_INSIDE_TO_LINE, {"$", "\n"}, string_color},
- {COLOR_STR, {"$"}, string_color},
+ {COLOR_AROUND_TO_LINE, {"\"", "\""}, string_color},
+ {COLOR_AROUND, {"\"\"\"", "\"\"\""}, string_color},
+ {COLOR_AROUND_TO_LINE, {"'", "'"}, string_color},
+ {COLOR_INSIDE_TO_LINE, {"$", "."}, string_color},
+ {COLOR_INSIDE_TO_LINE, {"$", " "}, string_color},
+ {COLOR_INSIDE_TO_LINE, {"$", "("}, string_color},
+ {COLOR_INSIDE_TO_LINE, {"$", "["}, string_color},
+ {COLOR_INSIDE_TO_LINE, {"$", "\n"}, string_color},
+ {COLOR_STR, {"$"}, string_color},
#endif
- // comments
+ // comments
#ifdef comment_color
- {COLOR_AROUND, {"#", "\n"}, comment_color},
+ {COLOR_AROUND, {"#", "\n"}, comment_color},
#endif
- // operators
+ // operators
#ifdef operator_color
- {COLOR_STR, {"!="}, normal_color},
- {COLOR_STR, {"!"}, operator_color},
+ {COLOR_STR, {"!="}, normal_color},
+ {COLOR_STR, {"!"}, operator_color},
#endif
- // constants
+ // constants
#ifdef constants_color
- {COLOR_UPPER_CASE_WORD, {0}, constants_color},
- {COLOR_WORD, {"PI"}, constants_color},
- {COLOR_WORD, {"TAU"}, constants_color},
- {COLOR_WORD, {"INF"}, constants_color},
- {COLOR_WORD, {"NAN"}, constants_color},
- {COLOR_WORD, {"null"}, constants_color},
- {COLOR_WORD, {"true"}, constants_color},
- {COLOR_WORD, {"false"}, constants_color},
- {COLOR_STR_AFTER_WORD, {"const"}, constants_color},
+ {COLOR_UPPER_CASE_WORD, {0}, constants_color},
+ {COLOR_WORD, {"PI"}, constants_color},
+ {COLOR_WORD, {"TAU"}, constants_color},
+ {COLOR_WORD, {"INF"}, constants_color},
+ {COLOR_WORD, {"NAN"}, constants_color},
+ {COLOR_WORD, {"null"}, constants_color},
+ {COLOR_WORD, {"true"}, constants_color},
+ {COLOR_WORD, {"false"}, constants_color},
+ {COLOR_STR_AFTER_WORD, {"const"}, constants_color},
#endif
- // keywords
+ // keywords
#ifdef keyword_color
- color_keyword("extends"), color_keyword("class_name"),
- color_keyword("var"), color_keyword("const"),
- color_keyword("enum"), color_keyword("func"),
- color_keyword("if"), color_keyword("else"),
- color_keyword("elif"), color_keyword("for"),
- color_keyword("while"), color_keyword("in"),
- color_keyword("return"), color_keyword("class"),
- color_keyword("pass"), color_keyword("continue"),
- color_keyword("break"), color_keyword("is"),
- color_keyword("as"), color_keyword("self"),
- color_keyword("tool"), color_keyword("signal"),
- color_keyword("static"), color_keyword("onready"),
- color_keyword("export"), color_keyword("setget"),
- color_keyword("breakpoint"), color_keyword("yield"),
- color_keyword("assert"), color_keyword("preload"),
- color_keyword("remote"), color_keyword("master"),
- color_keyword("puppet"), color_keyword("remotesync"),
- color_keyword("mastersync"), color_keyword("puppetsync"),
- color_keyword("and"), color_keyword("or"),
+ color_keyword("extends"), color_keyword("class_name"),
+ color_keyword("var"), color_keyword("const"),
+ color_keyword("enum"), color_keyword("func"),
+ color_keyword("if"), color_keyword("else"),
+ color_keyword("elif"), color_keyword("for"),
+ color_keyword("while"), color_keyword("in"),
+ color_keyword("return"), color_keyword("class"),
+ color_keyword("pass"), color_keyword("continue"),
+ color_keyword("break"), color_keyword("is"),
+ color_keyword("as"), color_keyword("self"),
+ color_keyword("tool"), color_keyword("signal"),
+ color_keyword("static"), color_keyword("onready"),
+ color_keyword("export"), color_keyword("setget"),
+ color_keyword("breakpoint"), color_keyword("yield"),
+ color_keyword("assert"), color_keyword("preload"),
+ color_keyword("remote"), color_keyword("master"),
+ color_keyword("puppet"), color_keyword("remotesync"),
+ color_keyword("mastersync"), color_keyword("puppetsync"),
+ color_keyword("and"), color_keyword("or"),
#endif
- // functions
+ // functions
#ifdef function_color
- {COLOR_WORD_INSIDE, {"func ", "("}, macro_color},
- {COLOR_WORD_INSIDE, {"class ", ":"}, macro_color},
- {COLOR_WORD_BEFORE_STR, {"("}, function_color},
+ {COLOR_WORD_INSIDE, {"func ", "("}, macro_color},
+ {COLOR_WORD_INSIDE, {"class ", ":"}, macro_color},
+ {COLOR_WORD_BEFORE_STR, {"("}, function_color},
#endif
- // types
+ // types
#ifdef type_color
- color_type("bool"), color_type("int"),
- color_type("float"), color_type("String"),
- color_type("Vector2"), color_type("Rect2"),
- color_type("Vector3"), color_type("Transform2D"),
- color_type("Plane"), color_type("Quat"),
- color_type("AABB"), color_type("Basis"),
- color_type("Transform"), color_type("Color"),
- color_type("NodePath"), color_type("RID"),
- color_type("Object"), color_type("Array"),
- color_type("PoolByteArray"), color_type("PoolIntArray"),
- color_type("PoolRealArray"), color_type("PoolStringArray"),
- color_type("PoolVector2Array"), color_type("PoolVector3Array"),
- color_type("PoolColorArray"), color_type("Dictionary"),
- color_type("Dictionary"), color_type("Node"),
- color_type("void"),
+ color_type("bool"), color_type("int"),
+ color_type("float"), color_type("String"),
+ color_type("Vector2"), color_type("Rect2"),
+ color_type("Vector3"), color_type("Transform2D"),
+ color_type("Plane"), color_type("Quat"),
+ color_type("AABB"), color_type("Basis"),
+ color_type("Transform"), color_type("Color"),
+ color_type("NodePath"), color_type("RID"),
+ color_type("Object"), color_type("Array"),
+ color_type("PoolByteArray"), color_type("PoolIntArray"),
+ color_type("PoolRealArray"), color_type("PoolStringArray"),
+ color_type("PoolVector2Array"), color_type("PoolVector3Array"),
+ color_type("PoolColorArray"), color_type("Dictionary"),
+ color_type("Dictionary"), color_type("Node"),
+ color_type("void"),
#endif
- // numbers
+ // numbers
#ifdef number_color
- color_numbers(),
+ color_numbers(),
#endif
};
#define gd_word_seperators default_word_seperators
const struct indent_scheme_entry gd_indent[] = {
- {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"return"}},
- {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"break"}},
- {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"continue"}},
- {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"pass"}},
- {INDENT_NEW, INDENT_LINE_ENDS_WITH_STR, -1, {":"}},
+ {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"return"}},
+ {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"break"}},
+ {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"continue"}},
+ {INDENT_REMOVE, INDENT_LINE_CONTAINS_WORD, -1, {"pass"}},
+ {INDENT_NEW, INDENT_LINE_ENDS_WITH_STR, -1, {":"}},
};
diff --git a/extensions/syntax/handy_defines.h b/extensions/syntax/handy_defines.h
@@ -8,25 +8,25 @@
#endif
#ifdef type_color
-#define color_type(_str) {COLOR_WORD,{_str}, type_color}
+#define color_type(_str) {COLOR_WORD,{_str}, type_color}
#endif
#ifdef number_color
-#define color_number(_num) \
- {COLOR_WORD_STARTING_WITH_STR, {_num}, number_color}, \
- {COLOR_WORD_ENDING_WITH_STR, {_num".f"},number_color}
+#define color_number(_num) \
+ {COLOR_WORD_STARTING_WITH_STR, {_num}, number_color}, \
+ {COLOR_WORD_ENDING_WITH_STR, {_num".f"},number_color}
#endif
-#define color_numbers() \
- color_number("0"), \
- color_number("1"), \
- color_number("2"), \
- color_number("3"), \
- color_number("4"), \
- color_number("5"), \
- color_number("6"), \
- color_number("7"), \
- color_number("8"), \
- color_number("9")
+#define color_numbers() \
+ color_number("0"), \
+ color_number("1"), \
+ color_number("2"), \
+ color_number("3"), \
+ color_number("4"), \
+ color_number("5"), \
+ color_number("6"), \
+ color_number("7"), \
+ color_number("8"), \
+ color_number("9")
#endif // HANDY_DEFINES_H_
diff --git a/extensions/syntax/syntax.h b/extensions/syntax/syntax.h
@@ -16,92 +16,92 @@ static int fb_set_syntax_scheme(struct file_buffer* fb);
static int apply_syntax(struct window_split_node* wn, const int offset_start, const int offset_end, uint8_t* move_buffer, const int move_buffer_len);
static const struct extension syntax_e = {
- .fb_new_file_opened = fb_set_syntax_scheme,
- .window_written_to_screen = apply_syntax
+ .fb_new_file_opened = fb_set_syntax_scheme,
+ .window_written_to_screen = apply_syntax
};
#define UPPER_CASE_WORD_MIN_LEN 3
enum syntax_scheme_mode {
- // needs two strings
- COLOR_AROUND,
- // needs two strings
- COLOR_AROUND_TO_LINE,
- // needs two strings
- COLOR_INSIDE,
- // needs two strings
- COLOR_INSIDE_TO_LINE,
- // needs two strings
- COLOR_WORD_INSIDE,
- // needs one string
- COLOR_WORD,
- // needs one string
- COLOR_WORD_ENDING_WITH_STR,
- // needs one string
- COLOR_WORD_STARTING_WITH_STR,
- // needs one string
- COLOR_STR,
- // needs two strings
- // colors word if string is found after it
- COLOR_WORD_STR,
- // needs one string
- // can be combined with others if this is first
- COLOR_STR_AFTER_WORD,
- // needs one string
- // "(" would color like this "not_colored colored("
- // "[" would color like this "not_colored colored ["
- COLOR_WORD_BEFORE_STR,
- // needs one string
- // "(" would color like this "colored not_colored("
- // "=" would color like this "colored not_colored ="
- COLOR_WORD_BEFORE_STR_STR,
- // no arguments needed
- COLOR_UPPER_CASE_WORD,
+ // needs two strings
+ COLOR_AROUND,
+ // needs two strings
+ COLOR_AROUND_TO_LINE,
+ // needs two strings
+ COLOR_INSIDE,
+ // needs two strings
+ COLOR_INSIDE_TO_LINE,
+ // needs two strings
+ COLOR_WORD_INSIDE,
+ // needs one string
+ COLOR_WORD,
+ // needs one string
+ COLOR_WORD_ENDING_WITH_STR,
+ // needs one string
+ COLOR_WORD_STARTING_WITH_STR,
+ // needs one string
+ COLOR_STR,
+ // needs two strings
+ // colors word if string is found after it
+ COLOR_WORD_STR,
+ // needs one string
+ // can be combined with others if this is first
+ COLOR_STR_AFTER_WORD,
+ // needs one string
+ // "(" would color like this "not_colored colored("
+ // "[" would color like this "not_colored colored ["
+ COLOR_WORD_BEFORE_STR,
+ // needs one string
+ // "(" would color like this "colored not_colored("
+ // "=" would color like this "colored not_colored ="
+ COLOR_WORD_BEFORE_STR_STR,
+ // no arguments needed
+ COLOR_UPPER_CASE_WORD,
};
struct syntax_scheme_entry {
- const enum syntax_scheme_mode mode;
- const struct delimiter arg;
- const struct glyph attr;
+ const enum syntax_scheme_mode mode;
+ const struct delimiter arg;
+ const struct glyph attr;
};
// TODO: INDENT_LINE_CONTAINS_STR_AND_STR
enum indent_scheme_mode {
- INDENT_LINE_ENDS_WITH_STR,
- INDENT_LINE_DOES_NOT_END_WITH_STR,
+ INDENT_LINE_ENDS_WITH_STR,
+ INDENT_LINE_DOES_NOT_END_WITH_STR,
- INDENT_LINE_CONTAINS_WORD,
- INDENT_LINE_ONLY_CONTAINS_STR,
- // neds two strings
- INDENT_LINE_CONTAINS_STR_MORE_THAN_STR,
+ INDENT_LINE_CONTAINS_WORD,
+ INDENT_LINE_ONLY_CONTAINS_STR,
+ // neds two strings
+ INDENT_LINE_CONTAINS_STR_MORE_THAN_STR,
};
enum indent_scheme_type {
- INDENT_REMOVE = -1,
- INDENT_KEEP_OPENER = 0,
- INDENT_NEW = 1,
+ INDENT_REMOVE = -1,
+ INDENT_KEEP_OPENER = 0,
+ INDENT_NEW = 1,
- INDENT_KEEP,
- // needs two strings, requires closer to be string 1 and opener to be string two
- INDENT_RETURN_TO_OPENER_BASE_INDENT,
+ INDENT_KEEP,
+ // needs two strings, requires closer to be string 1 and opener to be string two
+ INDENT_RETURN_TO_OPENER_BASE_INDENT,
};
struct indent_scheme_entry {
- const enum indent_scheme_type type;
- const enum indent_scheme_mode mode;
- const unsigned int line_offset;
- const struct delimiter arg;
+ const enum indent_scheme_type type;
+ const enum indent_scheme_mode mode;
+ const unsigned int line_offset;
+ const struct delimiter arg;
};
struct syntax_scheme {
- const char* file_ending;
- const char* word_seperators;
+ const char* file_ending;
+ const char* word_seperators;
- const struct syntax_scheme_entry* entries;
- const int entry_count;
+ const struct syntax_scheme_entry* entries;
+ const int entry_count;
- const struct indent_scheme_entry* indents;
- const int indent_count;
+ const struct indent_scheme_entry* indents;
+ const int indent_count;
};
@@ -116,530 +116,533 @@ static int get_line_relative_offset(struct file_buffer* fb, int offset, int cou
static const struct syntax_scheme*
fb_get_syntax_scheme(struct file_buffer* fb)
{
- return fb->syntax_index < 0 ? NULL : &syntax_schemes[fb->syntax_index];
+ return fb->syntax_index < 0 ? NULL : &syntax_schemes[fb->syntax_index];
}
static int
fb_set_syntax_scheme(struct file_buffer* fb)
{
- for (int i = 0; syntax_schemes[i].file_ending; i++)
- if (is_file_type(fb->file_path, syntax_schemes[i].file_ending))
- fb->syntax_index = i;
- return 0;
+ for (int i = 0; syntax_schemes[i].file_ending; i++)
+ if (is_file_type(fb->file_path, syntax_schemes[i].file_ending))
+ fb->syntax_index = i;
+ return 0;
}
static int
apply_syntax(struct window_split_node* wn, const int offset_start, const int offset_end, uint8_t* move_buffer, const int move_buffer_len)
{
- global_attr = default_attributes;
- struct window_buffer* wb = &wn->wb;
- struct file_buffer* fb = get_fb(wb);
- const struct syntax_scheme* cs = fb_get_syntax_scheme(fb);
- if (!cs)
- return 0;
-
- // clear state
- do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
-
- // search backwards to find multi-line syntax highlighting
- for (int i = 0; i < cs->entry_count; i++) {
- const struct syntax_scheme_entry cse = cs->entries[i];
- if (cse.mode == COLOR_AROUND || cse.mode == COLOR_INSIDE) {
- int offset = 0;
- int count = 0;
- int start_len = strlen(cse.arg.start);
- while((offset = fb_seek_string(fb, offset, cse.arg.start)) >= 0) {
- offset += start_len;
- if (offset >= offset_start)
- break;
- count++;
- }
-
- if (strcmp(cse.arg.start, cse.arg.end) != 0) {
- int end_len = strlen(cse.arg.end);
- offset = 0;
- while((offset = fb_seek_string(fb, offset, cse.arg.end)) >= 0) {
- offset += end_len;
- if (offset >= offset_start)
- break;
- count--;
+ global_attr = default_attributes;
+ struct window_buffer* wb = &wn->wb;
+ struct file_buffer* fb = get_fb(wb);
+ const struct syntax_scheme* cs = fb_get_syntax_scheme(fb);
+ if (!cs)
+ return 0;
+
+ // clear state
+ do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
+
+ // search backwards to find multi-line syntax highlighting
+ for (int i = 0; i < cs->entry_count; i++) {
+ const struct syntax_scheme_entry cse = cs->entries[i];
+ if (cse.mode == COLOR_AROUND || cse.mode == COLOR_INSIDE) {
+ int offset = 0;
+ int count = 0;
+ int start_len = strlen(cse.arg.start);
+ while((offset = fb_seek_string(fb, offset, cse.arg.start)) >= 0) {
+ offset += start_len;
+ if (offset >= offset_start)
+ break;
+ count++;
+ }
+
+ if (strcmp(cse.arg.start, cse.arg.end) != 0) {
+ int end_len = strlen(cse.arg.end);
+ offset = 0;
+ while((offset = fb_seek_string(fb, offset, cse.arg.end)) >= 0) {
+ offset += end_len;
+ if (offset >= offset_start)
+ break;
+ count--;
+ }
+ }
+ if (count > 0) {
+ offset = fb_seek_string_backwards(fb, offset_start, cse.arg.start);
+ do_syntax_scheme(fb, cs, offset);
+ break;
+ }
}
- }
- if (count > 0) {
- offset = fb_seek_string_backwards(fb, offset_start, cse.arg.start);
- do_syntax_scheme(fb, cs, offset);
- break;
- }
}
- }
-
- int x = wn->minx + move_buffer[0], y = wn->miny;
- int move_buffer_index = 0;
- int charsize = 1;
- for(int i = offset_start; i < offset_end && y < wn->maxy
- && move_buffer_index < move_buffer_len; i += charsize) {
- do_syntax_scheme(fb, cs, i);
- screen_set_attr(x, y)->fg = global_attr.fg;
- screen_set_attr(x, y)->bg = global_attr.bg;
-
- uint8_t amount = move_buffer[move_buffer_index];
- if (amount & (1<<7)) {
- x = wn->minx;
- y++;
- amount &= ~(1<<7);
+
+ int x = wn->minx + move_buffer[0], y = wn->miny;
+ int move_buffer_index = 0;
+ int charsize = 1;
+ for(int i = offset_start; i < offset_end && y < wn->maxy
+ && move_buffer_index < move_buffer_len; i += charsize) {
+ do_syntax_scheme(fb, cs, i);
+ screen_set_attr(x, y)->fg = global_attr.fg;
+ screen_set_attr(x, y)->bg = global_attr.bg;
+
+ uint8_t amount = move_buffer[move_buffer_index];
+ if (amount & (1<<7)) {
+ x = wn->minx;
+ y++;
+ amount &= ~(1<<7);
+ }
+ x += amount;
+
+ rune_t u;
+ charsize = utf8_decode_buffer(fb->contents + i, i - offset_start, &u);
+ if (charsize == 0)
+ charsize = 1;
+ move_buffer_index++;
}
- x += amount;
-
- rune_t u;
- charsize = utf8_decode_buffer(fb->contents + i, i - offset_start, &u);
- if (charsize == 0)
- charsize = 1;
- move_buffer_index++;
- }
-
- do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
- global_attr = default_attributes;
- return 0;
+
+ do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
+ global_attr = default_attributes;
+ return 0;
}
void
do_syntax_scheme(struct file_buffer* fb, const struct syntax_scheme* cs, int offset)
{
- static int end_at_whitespace = 0;
- static const char* end_condition;
- static int end_condition_len;
- static struct glyph next_word_attr;
- static int color_next_word = 0;
- static int around = 0;
-
- if (!fb || !cs) {
- // reset
- end_at_whitespace = 0;
- end_condition_len = 0;
- around = 0;
- color_next_word = 0;
- end_condition = NULL;
- global_attr = default_attributes;
- return;
- }
-
- char* buf = fb->contents;
- int buflen = fb->len;
-
- if (end_condition && !color_next_word) {
- if (buflen - offset <= end_condition_len)
- return;
- if (end_at_whitespace && buf[offset] == '\n') {
- // *_TO_LINE reached end of line
- end_condition_len = 0;
- end_condition = NULL;
- end_at_whitespace = 0;
- global_attr = default_attributes;
- } else if (fb_offset_starts_with(fb, offset, end_condition)) {
- if (isspace(end_condition[end_condition_len-1])) {
- end_condition_len--;
- if (end_condition_len <= 0)
- global_attr = default_attributes;
- }
- // if it's around not inside, don't reset color until later
- if (around)
+ static int end_at_whitespace = 0;
+ static const char* end_condition;
+ static int end_condition_len;
+ static struct glyph next_word_attr;
+ static int color_next_word = 0;
+ static int around = 0;
+
+ if (!fb || !cs) {
+ // reset
+ end_at_whitespace = 0;
+ end_condition_len = 0;
around = 0;
- else
+ color_next_word = 0;
+ end_condition = NULL;
global_attr = default_attributes;
-
- end_condition = NULL;
- end_at_whitespace = 0;
- }
- return;
- } else if (end_at_whitespace) {
- if (!fb_is_on_a_word(fb, offset, cs->word_seperators)) {
- end_at_whitespace = 0;
- global_attr = default_attributes;
- } else {
- return;
- }
- } else if (color_next_word) {
- // check if new word encountered
- if (!fb_is_on_a_word(fb, offset, cs->word_seperators))
- return;
- global_attr = next_word_attr;
- color_next_word = 0;
- end_at_whitespace = 1;
- return;
- } else if (end_condition_len > 0) {
- // wait for the word/sequence to finish
- // NOTE: does not work with utf8 chars
- // TODO: ???
- if (--end_condition_len <= 0)
- global_attr = default_attributes;
- else
- return;
- }
-
- for (int i = 0; i < cs->entry_count; i++) {
- struct syntax_scheme_entry entry = cs->entries[i];
- enum syntax_scheme_mode mode = entry.mode;
-
- if (mode == COLOR_UPPER_CASE_WORD) {
- if (!fb_is_start_of_a_word(fb, offset, cs->word_seperators))
- continue;
-
- int end_len = 0;
- while (offset + end_len < fb->len && !str_contains_char(cs->word_seperators, buf[offset + end_len])) {
- if (!isupper(buf[offset + end_len]) && buf[offset + end_len] != '_'
- && (!end_len || (buf[offset + end_len] < '0' || buf[offset + end_len] > '9')))
- goto not_upper_case;
- end_len++;
- }
- // upper case words must be longer than UPPER_CASE_WORD_MIN_LEN chars
- if (end_len < UPPER_CASE_WORD_MIN_LEN)
- continue;
-
- global_attr = entry.attr;
- end_condition_len = end_len;
- return;
-
- not_upper_case:
- continue;
+ return;
}
- int len = strlen(entry.arg.start);
-
- if (mode == COLOR_WORD_BEFORE_STR || mode == COLOR_WORD_BEFORE_STR_STR || mode == COLOR_WORD_ENDING_WITH_STR) {
- // check if this is a new word
- if (str_contains_char(cs->word_seperators, buf[offset])) continue;
-
- int offset_tmp = offset;
- // find new word twice if it's BEFORE_STR_STR
- int times = mode == COLOR_WORD_BEFORE_STR_STR ? 2 : 1;
- int first_word_len = 0;
- int first_time = 1;
- while (times--) {
- // seek end of word
- offset_tmp = fb_seek_word_end(fb, offset_tmp, cs->word_seperators);
- if (offset_tmp == offset && mode == COLOR_WORD_BEFORE_STR_STR)
- goto exit_word_before_str_str;
- if (first_time)
- first_word_len = offset_tmp - offset;
-
- if (mode != COLOR_WORD_ENDING_WITH_STR)
- offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
-
- first_time = 0;
- }
-
- if (mode == COLOR_WORD_ENDING_WITH_STR) {
- offset_tmp -= len;
- if (offset_tmp < 0)
- continue;
- }
- if (fb_offset_starts_with(fb, offset_tmp, entry.arg.start)) {
- global_attr = entry.attr;
- end_condition_len = first_word_len;
+ char* buf = fb->contents;
+ int buflen = fb->len;
+
+ if (end_condition && !color_next_word) {
+ if (buflen - offset <= end_condition_len)
+ return;
+ if (end_at_whitespace && buf[offset] == '\n') {
+ // *_TO_LINE reached end of line
+ end_condition_len = 0;
+ end_condition = NULL;
+ end_at_whitespace = 0;
+ global_attr = default_attributes;
+ } else if (fb_offset_starts_with(fb, offset, end_condition)) {
+ if (isspace(end_condition[end_condition_len-1])) {
+ end_condition_len--;
+ if (end_condition_len <= 0)
+ global_attr = default_attributes;
+ }
+ // if it's around not inside, don't reset color until later
+ if (around)
+ around = 0;
+ else
+ global_attr = default_attributes;
+
+ end_condition = NULL;
+ end_at_whitespace = 0;
+ }
return;
- }
- exit_word_before_str_str:
- continue;
+ } else if (end_at_whitespace) {
+ if (!fb_is_on_a_word(fb, offset, cs->word_seperators)) {
+ end_at_whitespace = 0;
+ global_attr = default_attributes;
+ } else {
+ return;
+ }
+ } else if (color_next_word) {
+ // check if new word encountered
+ if (!fb_is_on_a_word(fb, offset, cs->word_seperators))
+ return;
+ global_attr = next_word_attr;
+ color_next_word = 0;
+ end_at_whitespace = 1;
+ return;
+ } else if (end_condition_len > 0) {
+ // wait for the word/sequence to finish
+ // NOTE: does not work with utf8 chars
+ // TODO: ???
+ if (--end_condition_len <= 0)
+ global_attr = default_attributes;
+ else
+ return;
}
- if (mode == COLOR_INSIDE || mode == COLOR_INSIDE_TO_LINE || mode == COLOR_WORD_INSIDE) {
- if (offset - len < 0)
- continue;
- // check the if what's behind the cursor is the first string
- if (fb_offset_starts_with(fb, offset - len, entry.arg.start)) {
- if (offset < fb->len && fb_offset_starts_with(fb, offset, entry.arg.end))
- continue;
-
- if (mode == COLOR_WORD_INSIDE) {
- // verify that only one word exists inside
- int offset_tmp = offset;
- offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
- offset_tmp = fb_seek_whitespace(fb, offset_tmp);
- int offset_tmp1 = offset_tmp - strlen(entry.arg.end);
- offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
-
- if ((!fb_offset_starts_with(fb, offset_tmp, entry.arg.end)
- && !fb_offset_starts_with(fb, offset_tmp1, entry.arg.end))
- || offset_tmp1 - offset <= 1 || offset_tmp - offset <= 1)
- continue;
- } else if (mode == COLOR_INSIDE_TO_LINE) {
- if (fb_seek_char(fb, offset, '\n') < fb_seek_string(fb, offset, entry.arg.end))
+ for (int i = 0; i < cs->entry_count; i++) {
+ struct syntax_scheme_entry entry = cs->entries[i];
+ enum syntax_scheme_mode mode = entry.mode;
+
+ if (mode == COLOR_UPPER_CASE_WORD) {
+ if (!fb_is_start_of_a_word(fb, offset, cs->word_seperators))
+ continue;
+
+ int end_len = 0;
+ while (offset + end_len < fb->len && !str_contains_char(cs->word_seperators, buf[offset + end_len])) {
+ if (!isupper(buf[offset + end_len]) && buf[offset + end_len] != '_'
+ && (!end_len || (buf[offset + end_len] < '0' || buf[offset + end_len] > '9')))
+ goto not_upper_case;
+ end_len++;
+ }
+ // upper case words must be longer than UPPER_CASE_WORD_MIN_LEN chars
+ if (end_len < UPPER_CASE_WORD_MIN_LEN)
+ continue;
+
+ global_attr = entry.attr;
+ end_condition_len = end_len;
+ return;
+
+ not_upper_case:
continue;
}
+ int len = strlen(entry.arg.start);
+
+ if (mode == COLOR_WORD_BEFORE_STR || mode == COLOR_WORD_BEFORE_STR_STR || mode == COLOR_WORD_ENDING_WITH_STR) {
+ // check if this is a new word
+ if (str_contains_char(cs->word_seperators, buf[offset])) continue;
+
+ int offset_tmp = offset;
+ // find new word twice if it's BEFORE_STR_STR
+ int times = mode == COLOR_WORD_BEFORE_STR_STR ? 2 : 1;
+ int first_word_len = 0;
+ int first_time = 1;
+ while (times--) {
+ // seek end of word
+ offset_tmp = fb_seek_word_end(fb, offset_tmp, cs->word_seperators);
+ if (offset_tmp == offset && mode == COLOR_WORD_BEFORE_STR_STR)
+ goto exit_word_before_str_str;
+ if (first_time)
+ first_word_len = offset_tmp - offset;
+
+ if (mode != COLOR_WORD_ENDING_WITH_STR)
+ offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
+
+ first_time = 0;
+ }
+
+ if (mode == COLOR_WORD_ENDING_WITH_STR) {
+ offset_tmp -= len;
+ if (offset_tmp < 0)
+ continue;
+ }
+ if (fb_offset_starts_with(fb, offset_tmp, entry.arg.start)) {
+ global_attr = entry.attr;
+ end_condition_len = first_word_len;
+ return;
+ }
+ exit_word_before_str_str:
+ continue;
+ }
- end_condition = entry.arg.end;
- end_condition_len = strlen(entry.arg.end);
- global_attr = entry.attr;
- around = 0;
- return;
- }
- continue;
- }
+ if (mode == COLOR_INSIDE || mode == COLOR_INSIDE_TO_LINE || mode == COLOR_WORD_INSIDE) {
+ if (offset - len < 0)
+ continue;
+ // check the if what's behind the cursor is the first string
+ if (fb_offset_starts_with(fb, offset - len, entry.arg.start)) {
+ if (offset < fb->len && fb_offset_starts_with(fb, offset, entry.arg.end))
+ continue;
+
+ if (mode == COLOR_WORD_INSIDE) {
+ // verify that only one word exists inside
+ int offset_tmp = offset;
+ offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
+ offset_tmp = fb_seek_whitespace(fb, offset_tmp);
+ int offset_tmp1 = offset_tmp - strlen(entry.arg.end);
+ offset_tmp = fb_seek_not_whitespace(fb, offset_tmp);
+
+ if ((!fb_offset_starts_with(fb, offset_tmp, entry.arg.end)
+ && !fb_offset_starts_with(fb, offset_tmp1, entry.arg.end))
+ || offset_tmp1 - offset <= 1 || offset_tmp - offset <= 1)
+ continue;
+ } else if (mode == COLOR_INSIDE_TO_LINE) {
+ if (fb_seek_char(fb, offset, '\n') < fb_seek_string(fb, offset, entry.arg.end))
+ continue;
+ }
+
+
+ end_condition = entry.arg.end;
+ end_condition_len = strlen(entry.arg.end);
+ global_attr = entry.attr;
+ around = 0;
+ return;
+ }
+ continue;
+ }
- if ((mode == COLOR_AROUND || mode == COLOR_AROUND_TO_LINE) &&
- fb_offset_starts_with(fb, offset, entry.arg.start)) {
- end_condition = entry.arg.end;
- end_condition_len = strlen(entry.arg.end);
- around = 1;
- if (entry.mode == COLOR_AROUND_TO_LINE)
- end_at_whitespace = 1;
- global_attr = entry.attr;
- return;
+ if ((mode == COLOR_AROUND || mode == COLOR_AROUND_TO_LINE) &&
+ fb_offset_starts_with(fb, offset, entry.arg.start)) {
+ end_condition = entry.arg.end;
+ end_condition_len = strlen(entry.arg.end);
+ around = 1;
+ if (entry.mode == COLOR_AROUND_TO_LINE)
+ end_at_whitespace = 1;
+ global_attr = entry.attr;
+ return;
+ }
+ if (mode == COLOR_WORD || mode == COLOR_STR_AFTER_WORD ||
+ mode == COLOR_WORD_STR || mode == COLOR_WORD_STARTING_WITH_STR) {
+
+ // check if this is the start of a new word that matches word exactly(except for WORD_STARTING_WITH_STR)
+ if(!fb_offset_starts_with(fb, offset, entry.arg.start) ||
+ !fb_is_start_of_a_word(fb, offset, cs->word_seperators) ||
+ (fb_is_on_a_word(fb, offset + len, cs->word_seperators) && mode != COLOR_WORD_STARTING_WITH_STR))
+ continue;
+
+ if (mode == COLOR_WORD_STR) {
+ int offset_str = fb_seek_not_whitespace(fb, offset + len);
+
+ if (!fb_offset_starts_with(fb, offset_str, entry.arg.end))
+ continue;
+ end_condition_len = strlen(entry.arg.start);
+ } else {
+ end_at_whitespace = 1;
+ }
+ if (mode == COLOR_STR_AFTER_WORD) {
+ next_word_attr = entry.attr;
+ color_next_word = 1;
+ continue;
+ }
+ global_attr = entry.attr;
+ return;
+ }
+ if (mode == COLOR_STR) {
+ if (!fb_offset_starts_with(fb, offset, entry.arg.start))
+ continue;
+ end_condition_len = len;
+ global_attr = entry.attr;
+ return;
+ }
}
- if (mode == COLOR_WORD || mode == COLOR_STR_AFTER_WORD ||
- mode == COLOR_WORD_STR || mode == COLOR_WORD_STARTING_WITH_STR) {
-
- // check if this is the start of a new word that matches word exactly(except for WORD_STARTING_WITH_STR)
- if(!fb_offset_starts_with(fb, offset, entry.arg.start) ||
- !fb_is_start_of_a_word(fb, offset, cs->word_seperators) ||
- (fb_is_on_a_word(fb, offset + len, cs->word_seperators) && mode != COLOR_WORD_STARTING_WITH_STR))
- continue;
+}
- if (mode == COLOR_WORD_STR) {
- int offset_str = fb_seek_not_whitespace(fb, offset + len);
- if (!fb_offset_starts_with(fb, offset_str, entry.arg.end))
- continue;
- end_condition_len = strlen(entry.arg.start);
- } else {
- end_at_whitespace = 1;
- }
- if (mode == COLOR_STR_AFTER_WORD) {
- next_word_attr = entry.attr;
- color_next_word = 1;
- continue;
- }
- global_attr = entry.attr;
- return;
- }
- if (mode == COLOR_STR) {
- if (!fb_offset_starts_with(fb, offset, entry.arg.start))
- continue;
- end_condition_len = len;
- global_attr = entry.attr;
- return;
- }
- }
-}
+////////////////////////
+// Auto indent
+//
+//
-// TODO: make seperate plugin
-// also make the "syntax" member of file buffer not a thing
-// needs to be more dynamic
int
fb_auto_indent(struct file_buffer* fb, int offset)
{
- const struct syntax_scheme* cs = fb_get_syntax_scheme(fb);
- LIMIT(offset, 0, fb->len-1);
+ const struct syntax_scheme* cs = fb_get_syntax_scheme(fb);
+ LIMIT(offset, 0, fb->len-1);
+
+ int indent_diff = 0;
+ int indent_keep_x = -1;
+ int keep_pos = 0;
+
+ int get_line_offset;
+ char* get_line = NULL;
+
+ for (int i = 0; i < cs->indent_count; i++) {
+ const struct indent_scheme_entry indent = cs->indents[i];
+
+ get_line_offset = get_line_relative_offset(fb, offset, indent.line_offset);
+ if (get_line)
+ free(get_line);
+ get_line = fb_get_line_at_offset(fb, get_line_offset);
+
+ switch(indent.mode) {
+ int temp_offset, len;
+ char* res;
+ case INDENT_LINE_CONTAINS_WORD:
+ case INDENT_LINE_ONLY_CONTAINS_STR:
+ case INDENT_LINE_CONTAINS_STR_MORE_THAN_STR:
+ res = strstr(get_line, indent.arg.start);
+ if (!res)
+ continue;
+ if (INDENT_LINE_CONTAINS_WORD) {
+ if (res > get_line && !str_contains_char(cs->word_seperators, *(res-1)))
+ continue;
+ res += strlen(indent.arg.start);
+ if (*res && !str_contains_char(cs->word_seperators, *res))
+ continue;
+ } else if (INDENT_LINE_CONTAINS_STR_MORE_THAN_STR == indent.mode) {
+ char* start_last = get_line;
+ char* end_last = get_line;
+ for (int count = 0; count >= 0; ) {
+ if (start_last && (start_last = strstr(start_last, indent.arg.start))) {
+ start_last++;
+ count--;
+ } else {
+ goto indent_for_loop_continue;
+ }
+ if (end_last && (end_last = strstr(end_last, indent.arg.end))) {
+ end_last++;
+ count++;
+ }
+ }
+ } else if (indent.mode == INDENT_LINE_ONLY_CONTAINS_STR) {
+ int str_start = fb_seek_string_backwards(fb, get_line_offset, indent.arg.start);
+ int str_end = str_start + strlen(indent.arg.start);
+ int line_end = MIN(get_line_offset + 1, fb->len);
+ int line_start = MAX(fb_seek_char_backwards(fb, get_line_offset, '\n'), 0);
+ if (fb_seek_not_whitespace_backwards(fb, str_start-1) >= line_start ||
+ fb_seek_not_whitespace(fb, str_end+1) <= line_end)
+ continue;
+ }
+ if (indent.type == INDENT_KEEP_OPENER || indent.type == INDENT_RETURN_TO_OPENER_BASE_INDENT)
+ keep_pos = fb_seek_string_backwards(fb, get_line_offset, indent.arg.start);
+ goto set_indent_type;
+
+ case INDENT_LINE_ENDS_WITH_STR:
+ case INDENT_LINE_DOES_NOT_END_WITH_STR:
+ len = strlen(indent.arg.start);
+ temp_offset = fb_seek_not_whitespace_backwards(fb, get_line_offset) - len;
+ if (temp_offset < 0 ||
+ temp_offset < fb_seek_char_backwards(fb, get_line_offset, '\n'))
+ continue;
+ if (memcmp(fb->contents + get_line_offset, indent.arg.start, strlen(indent.arg.start)) == 0) {
+ if (indent.mode == INDENT_LINE_DOES_NOT_END_WITH_STR)
+ continue;
+ } else {
+ if (indent.mode == INDENT_LINE_ENDS_WITH_STR)
+ continue;
+ }
+ keep_pos = temp_offset;
+ goto set_indent_type;
+
+ set_indent_type:
+ if (indent.type == INDENT_KEEP_OPENER) {
+ if (indent_keep_x >= 0)
+ continue;
+ int tmp;
+ fb_offset_to_xy(fb, keep_pos, 0, 0, &indent_keep_x, &tmp, &tmp);
+ } else if (indent.type == INDENT_RETURN_TO_OPENER_BASE_INDENT) {
+ if (indent_keep_x >= 0)
+ continue;
+ int opener, closer;
+ if (!fb_get_delimiter(fb, keep_pos, indent.arg, NULL, &opener, &closer)) {
+ indent_keep_x = -1;
+ goto indent_for_loop_continue;
+ }
+ keep_pos = fb_seek_not_whitespace(fb, fb_seek_char_backwards(fb, opener, '\n'));
+ int tmp;
+ fb_offset_to_xy(fb, keep_pos, 0, 0, &indent_keep_x, &tmp, &tmp);
+ //TODO: why does this miss by one?
+ if (indent_keep_x > 0)
+ indent_keep_x--;
+ } else {
+ if (indent_diff)
+ continue;
+ indent_diff += indent.type;
+ }
+ }
+ indent_for_loop_continue:
+ continue;
+ }
- int indent_diff = 0;
- int indent_keep_x = -1;
- int keep_pos = 0;
+ if (get_line)
+ free(get_line);
- int get_line_offset;
- char* get_line = NULL;
+ int indents = 0, extra_spaces = 0;
- for (int i = 0; i < cs->indent_count; i++) {
- const struct indent_scheme_entry indent = cs->indents[i];
+ int prev_line_offset = fb_seek_char_backwards(fb, offset, '\n') - 1;
+ if (prev_line_offset < 0)
+ return 0;
+ char* prev_line = fb_get_line_at_offset(fb, prev_line_offset);
- get_line_offset = get_line_relative_offset(fb, offset, indent.line_offset);
- if (get_line)
- free(get_line);
- get_line = fb_get_line_at_offset(fb, get_line_offset);
-
- switch(indent.mode) {
- int temp_offset, len;
- char* res;
- case INDENT_LINE_CONTAINS_WORD:
- case INDENT_LINE_ONLY_CONTAINS_STR:
- case INDENT_LINE_CONTAINS_STR_MORE_THAN_STR:
- res = strstr(get_line, indent.arg.start);
- if (!res)
- continue;
- if (INDENT_LINE_CONTAINS_WORD) {
- if (res > get_line && !str_contains_char(cs->word_seperators, *(res-1)))
- continue;
- res += strlen(indent.arg.start);
- if (*res && !str_contains_char(cs->word_seperators, *res))
- continue;
- } else if (INDENT_LINE_CONTAINS_STR_MORE_THAN_STR == indent.mode) {
- char* start_last = get_line;
- char* end_last = get_line;
- for (int count = 0; count >= 0; ) {
- if (start_last && (start_last = strstr(start_last, indent.arg.start))) {
- start_last++;
- count--;
- } else {
- goto indent_for_loop_continue;
- }
- if (end_last && (end_last = strstr(end_last, indent.arg.end))) {
- end_last++;
- count++;
- }
- }
- } else if (indent.mode == INDENT_LINE_ONLY_CONTAINS_STR) {
- int str_start = fb_seek_string_backwards(fb, get_line_offset, indent.arg.start);
- int str_end = str_start + strlen(indent.arg.start);
- int line_end = MIN(get_line_offset + 1, fb->len);
- int line_start = MAX(fb_seek_char_backwards(fb, get_line_offset, '\n'), 0);
- if (fb_seek_not_whitespace_backwards(fb, str_start-1) >= line_start ||
- fb_seek_not_whitespace(fb, str_end+1) <= line_end)
- continue;
- }
- if (indent.type == INDENT_KEEP_OPENER || indent.type == INDENT_RETURN_TO_OPENER_BASE_INDENT)
- keep_pos = fb_seek_string_backwards(fb, get_line_offset, indent.arg.start);
- goto set_indent_type;
-
- case INDENT_LINE_ENDS_WITH_STR:
- case INDENT_LINE_DOES_NOT_END_WITH_STR:
- len = strlen(indent.arg.start);
- temp_offset = fb_seek_not_whitespace_backwards(fb, get_line_offset) - len;
- if (temp_offset < 0 ||
- temp_offset < fb_seek_char_backwards(fb, get_line_offset, '\n'))
- continue;
- if (memcmp(fb->contents + get_line_offset, indent.arg.start, strlen(indent.arg.start)) == 0) {
- if (indent.mode == INDENT_LINE_DOES_NOT_END_WITH_STR)
- continue;
- } else {
- if (indent.mode == INDENT_LINE_ENDS_WITH_STR)
- continue;
- }
- keep_pos = temp_offset;
- goto set_indent_type;
-
- set_indent_type:
- if (indent.type == INDENT_KEEP_OPENER) {
- if (indent_keep_x >= 0)
- continue;
- int tmp;
- fb_offset_to_xy(fb, keep_pos, 0, 0, &indent_keep_x, &tmp, &tmp);
- } else if (indent.type == INDENT_RETURN_TO_OPENER_BASE_INDENT) {
- if (indent_keep_x >= 0)
- continue;
- int opener, closer;
- if (!fb_get_delimiter(fb, keep_pos, indent.arg, NULL, &opener, &closer)) {
- indent_keep_x = -1;
- goto indent_for_loop_continue;
- }
- keep_pos = fb_seek_not_whitespace(fb, fb_seek_char_backwards(fb, opener, '\n'));
- int tmp;
- fb_offset_to_xy(fb, keep_pos, 0, 0, &indent_keep_x, &tmp, &tmp);
- //TODO: why does this miss by one?
- if (indent_keep_x > 0)
- indent_keep_x--;
- } else {
- if (indent_diff)
- continue;
- indent_diff += indent.type;
- }
+ if (indent_keep_x >= 0) {
+ whitespace_count_to_indent_amount(fb->indent_len, indent_keep_x, &indents, &extra_spaces);
+ } else {
+ whitespace_count_to_indent_amount(fb->indent_len, get_line_leading_whitespace_count(prev_line), &indents, &extra_spaces);
+ }
+ if (indent_diff != INDENT_KEEP) {
+ indents += indent_diff;
+ indents = MAX(indents, 0);
+ }
+
+ // remove the lines existing indent
+ int removed = 0;
+ int line_code_start = MIN(fb_seek_not_whitespace(fb, prev_line_offset + 1), fb_seek_char(fb, prev_line_offset + 1, '\n'));
+ if (line_code_start - (prev_line_offset) >= 1) {
+ removed = line_code_start - (prev_line_offset+1);
+ fb_remove(fb, prev_line_offset + 1, removed, 1, 1);
}
- indent_for_loop_continue:
- continue;
- }
- if (get_line)
- free(get_line);
+ if (indents + extra_spaces <= 0) {
+ free(prev_line);
+ return -removed;
+ }
- int indents = 0, extra_spaces = 0;
+ unsigned int indent_str_len = 0;
+ while(indents--)
+ indent_str_len += fb->indent_len ? fb->indent_len : 1;
+ char indent_str[indent_str_len + extra_spaces];
+
+ char space_tab = fb->indent_len > 0 ? ' ' : '\t';
+ int i = 0;
+ if (!fb->indent_len)
+ for (/* i = 0 */; i < indent_str_len; i++)
+ indent_str[i] = space_tab;
+ for (/* i = 0 or indent_str_len */ ; i < indent_str_len + extra_spaces; i++)
+ indent_str[i] = ' ';
+
+ fb_insert(fb, indent_str, indent_str_len + extra_spaces, prev_line_offset + 1, 0);
- int prev_line_offset = fb_seek_char_backwards(fb, offset, '\n') - 1;
- if (prev_line_offset < 0)
- return 0;
- char* prev_line = fb_get_line_at_offset(fb, prev_line_offset);
-
- if (indent_keep_x >= 0) {
- whitespace_count_to_indent_amount(fb->indent_len, indent_keep_x, &indents, &extra_spaces);
- } else {
- whitespace_count_to_indent_amount(fb->indent_len, get_line_leading_whitespace_count(prev_line), &indents, &extra_spaces);
- }
- if (indent_diff != INDENT_KEEP) {
- indents += indent_diff;
- indents = MAX(indents, 0);
- }
-
- // remove the lines existing indent
- int removed = 0;
- int line_code_start = MIN(fb_seek_not_whitespace(fb, prev_line_offset + 1), fb_seek_char(fb, prev_line_offset + 1, '\n'));
- if (line_code_start - (prev_line_offset) >= 1) {
- removed = line_code_start - (prev_line_offset+1);
- fb_remove(fb, prev_line_offset + 1, removed, 1, 1);
- }
-
- if (indents + extra_spaces <= 0) {
free(prev_line);
- return -removed;
- }
-
- unsigned int indent_str_len = 0;
- while(indents--)
- indent_str_len += fb->indent_len ? fb->indent_len : 1;
- char indent_str[indent_str_len + extra_spaces];
-
- char space_tab = fb->indent_len > 0 ? ' ' : '\t';
- int i = 0;
- if (!fb->indent_len)
- for (/* i = 0 */; i < indent_str_len; i++)
- indent_str[i] = space_tab;
- for (/* i = 0 or indent_str_len */ ; i < indent_str_len + extra_spaces; i++)
- indent_str[i] = ' ';
-
- fb_insert(fb, indent_str, indent_str_len + extra_spaces, prev_line_offset + 1, 0);
-
- free(prev_line);
- return indent_str_len + extra_spaces - removed;
+ return indent_str_len + extra_spaces - removed;
}
int get_line_leading_whitespace_count(const char* line)
{
- int count = 0;
- while(*line) {
- if (*line == ' ')
- count++;
- else if (*line == '\t')
- count += tabspaces - (count % tabspaces);
- else
- break;
- line++;
- }
- return count;
+ int count = 0;
+ while(*line) {
+ if (*line == ' ')
+ count++;
+ else if (*line == '\t')
+ count += tabspaces - (count % tabspaces);
+ else
+ break;
+ line++;
+ }
+ return count;
}
void
whitespace_count_to_indent_amount(int indent_len, int count, int* indent_count, int* extra_spaces)
{
- *indent_count = 0, *extra_spaces = 0;
- int space_count = indent_len > 0 ? indent_len : tabspaces;
- while(count >= space_count) {
- *indent_count += 1;
- count -= space_count;
- }
- *extra_spaces = count;
+ *indent_count = 0, *extra_spaces = 0;
+ int space_count = indent_len > 0 ? indent_len : tabspaces;
+ while(count >= space_count) {
+ *indent_count += 1;
+ count -= space_count;
+ }
+ *extra_spaces = count;
}
int
get_line_relative_offset(struct file_buffer* fb, int offset, int count)
{
- offset = fb_seek_char(fb, offset, '\n');
- if (offset < 0)
- offset = fb->len;
- if (count > 0) {
- while(count-- && offset >= 0)
- offset = fb_seek_char(fb, offset+1, '\n');
+ offset = fb_seek_char(fb, offset, '\n');
if (offset < 0)
- offset = fb->len;
- } else if (count < 0) {
- offset = fb_seek_char_backwards(fb, offset, '\n');
- while(count++ && offset >= 0)
- offset = fb_seek_char_backwards(fb, offset-1, '\n');
+ offset = fb->len;
+ if (count > 0) {
+ while(count-- && offset >= 0)
+ offset = fb_seek_char(fb, offset+1, '\n');
+ if (offset < 0)
+ offset = fb->len;
+ } else if (count < 0) {
+ offset = fb_seek_char_backwards(fb, offset, '\n');
+ while(count++ && offset >= 0)
+ offset = fb_seek_char_backwards(fb, offset-1, '\n');
+ if (offset < 0)
+ offset = 0;
+ }
+ offset = fb_seek_char(fb, offset, '\n');
+ if (offset > 0 && fb->contents[offset-1] != '\n')
+ offset--;
if (offset < 0)
- offset = 0;
- }
- offset = fb_seek_char(fb, offset, '\n');
- if (offset > 0 && fb->contents[offset-1] != '\n')
- offset--;
- if (offset < 0)
- offset = fb->len;
- return offset;
+ offset = fb->len;
+ return offset;
}
diff --git a/se.c b/se.c
@@ -18,8 +18,6 @@
#include "config.h"
#include "extension.h"
-// se.c globals
-
/////////////////////////////////////////////
// Internal functions
//
@@ -34,14 +32,14 @@ static void color_selection(struct glyph* letter);
int
writef_string(int y, int x1, int x2, const char* fmt, ...)
{
- char string[STATUS_BAR_MAX_LEN];
+ char string[STATUS_BAR_MAX_LEN];
- va_list args;
- va_start(args, fmt);
- vsnprintf(string, STATUS_BAR_MAX_LEN, fmt, args);
- va_end(args);
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(string, STATUS_BAR_MAX_LEN, fmt, args);
+ va_end(args);
- return write_string(string, y, x1, x2);
+ return write_string(string, y, x1, x2);
}
char status_bar_contents[STATUS_BAR_MAX_LEN] = {0};
@@ -50,327 +48,327 @@ uint32_t status_bar_bg;
void
writef_to_status_bar(const char* fmt, ...)
{
- if (fmt) {
- if (status_bar_bg == error_color ||
- status_bar_bg == warning_color ||
- status_bar_bg == ok_color)
- return;
-
- va_list args;
- va_start(args, fmt);
- vsnprintf(status_bar_contents, STATUS_BAR_MAX_LEN, fmt, args);
- va_end(args);
-
- status_bar_bg = alternate_bg_dark;
- return;
- }
+ if (fmt) {
+ if (status_bar_bg == error_color ||
+ status_bar_bg == warning_color ||
+ status_bar_bg == ok_color)
+ return;
+
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(status_bar_contents, STATUS_BAR_MAX_LEN, fmt, args);
+ va_end(args);
+
+ status_bar_bg = alternate_bg_dark;
+ return;
+ }
- global_attr = default_attributes;
- global_attr.bg = status_bar_bg;
+ global_attr = default_attributes;
+ global_attr.bg = status_bar_bg;
- status_bar_end = write_string(status_bar_contents, screen.row-1, 0, screen.col);
- screen_set_region(status_bar_end, screen.row-1, screen.col-1, screen.row-1, ' ');
+ status_bar_end = write_string(status_bar_contents, screen.row-1, 0, screen.col);
+ screen_set_region(status_bar_end, screen.row-1, screen.col-1, screen.row-1, ' ');
- global_attr = default_attributes;
+ global_attr = default_attributes;
}
void
draw_status_bar()
{
- writef_to_status_bar(NULL);
- xdrawline(0, screen.row-1, screen.col);
- draw_horisontal_line(screen.row-2, 0, screen.col-1);
- if (get_fb(focused_window)->mode & FB_SEARCH_BLOCKING)
- xdrawcursor(status_bar_end, screen.row-1, 1);
- status_bar_bg = alternate_bg_dark;
+ writef_to_status_bar(NULL);
+ xdrawline(0, screen.row-1, screen.col);
+ draw_horisontal_line(screen.row-2, 0, screen.col-1);
+ if (get_fb(focused_window)->mode & FB_SEARCH_BLOCKING)
+ xdrawcursor(status_bar_end, screen.row-1, 1);
+ status_bar_bg = alternate_bg_dark;
}
void
window_node_draw_to_screen(struct window_split_node* wn)
{
- struct window_buffer* wb = &wn->wb;
- struct file_buffer* fb = get_fb(wb);
- int minx = wn->minx, miny = wn->miny,
- maxx = wn->maxx, maxy = wn->maxy;
-
- LIMIT(wb->cursor_offset, 0, fb->len);
- screen_set_region(minx, miny, maxx, maxy, ' ');
- int focused = wb == focused_window && !(fb->mode & FB_SEARCH_BLOCKING);
-
- int x = minx, y = miny;
- global_attr = default_attributes;
-
- // force the screen in a place where the cursor is visable
- int ox, oy, xscroll;
- fb_offset_to_xy(fb, wb->cursor_offset, maxx - minx, wb->y_scroll, &ox, &oy, &xscroll);
- if (oy < 0) {
- wb->y_scroll += oy;
- } else {
- oy += miny - maxy+2;
- if (oy > 0)
- wb->y_scroll += oy;
- }
- if (wb->y_scroll < 0)
- wb->y_scroll = 0;
-
- if (wrap_buffer)
- xscroll = 0;
-
- // move to y_scroll
- char* repl = fb->contents;
- char* last = repl + fb->len;
- char* new_repl;
- int line = wb->y_scroll;
- while ((new_repl = memchr(repl, '\n', last - repl))) {
- if (--line < 0)
- break;
- else if (new_repl+1 < last)
- repl = new_repl+1;
- else
- return;
- }
- int offset_start = repl - fb->contents - 1;
- int cursor_x = 0, cursor_y = 0;
-
- // actually write to the screen
- int once = 0;
- int search_found = 0;
- int non_blocking_search_found = 0;
-
- // TODO: verify that last - repl is the same as offset_last - offset_start
- int move_buffer_len = last - repl + 2;
- uint8_t* move_buffer = xmalloc(move_buffer_len);
- memset(move_buffer, 0, move_buffer_len);
- move_buffer[0] = 0;
- int lastx = x, lasty = y;
- int move_buffer_index = 0;
-
- // TODO: write max string len of 127
- // TODO: make the write thing similar to syntax?
- char* new_line_start = NULL;
- call_extension(wb_new_line_draw, &new_line_start, wb, y - miny, maxy - y, minx, maxx, &global_attr);
- if (new_line_start) {
- struct glyph old_attr = global_attr;
- global_attr = default_attributes;
- x = write_string(new_line_start, y, minx, maxx+1);
- global_attr = old_attr;
- }
+ struct window_buffer* wb = &wn->wb;
+ struct file_buffer* fb = get_fb(wb);
+ int minx = wn->minx, miny = wn->miny,
+ maxx = wn->maxx, maxy = wn->maxy;
+
+ LIMIT(wb->cursor_offset, 0, fb->len);
+ screen_set_region(minx, miny, maxx, maxy, ' ');
+ int focused = wb == focused_window && !(fb->mode & FB_SEARCH_BLOCKING);
- int tmp = 0;
- call_extension(wb_write_status_bar, &tmp, NULL, 0, 0, 0, 0, NULL, NULL);
+ int x = minx, y = miny;
+ global_attr = default_attributes;
- for (int charsize = 1; repl < last && charsize; repl += charsize) {
- if (y > lasty) {
- move_buffer[move_buffer_index] = x - minx;
- move_buffer[move_buffer_index] |= 1<<7;
+ // force the screen in a place where the cursor is visable
+ int ox, oy, xscroll;
+ fb_offset_to_xy(fb, wb->cursor_offset, maxx - minx, wb->y_scroll, &ox, &oy, &xscroll);
+ if (oy < 0) {
+ wb->y_scroll += oy;
} else {
- move_buffer[move_buffer_index] = x - lastx;
+ oy += miny - maxy+2;
+ if (oy > 0)
+ wb->y_scroll += oy;
}
- move_buffer_index++;
- lastx = x, lasty = y;
-
- if (!once && repl - fb->contents >= wb->cursor_offset) {
- // if the buffer being drawn is focused, set the cursor position global
- once = 1;
- cursor_x = x - xscroll;
- cursor_y = y;
- LIMIT(cursor_x, minx, maxx);
- LIMIT(cursor_y, miny, maxy);
- }
-
- if (!wrap_buffer && x - xscroll > maxx && *repl != '\n') {
- charsize = 1;
- x++;
- continue;
+ if (wb->y_scroll < 0)
+ wb->y_scroll = 0;
+
+ if (wrap_buffer)
+ xscroll = 0;
+
+ // move to y_scroll
+ char* repl = fb->contents;
+ char* last = repl + fb->len;
+ char* new_repl;
+ int line = wb->y_scroll;
+ while ((new_repl = memchr(repl, '\n', last - repl))) {
+ if (--line < 0)
+ break;
+ else if (new_repl+1 < last)
+ repl = new_repl+1;
+ else
+ return;
}
-
- if (*repl == '\n' || (wrap_buffer && x >= maxx)) {
- x = minx;
- if (++y >= maxy-1)
- break;
- if (wrap_buffer && *repl != '\n')
- continue;
- charsize = 1;
- char* new_line_start = NULL;
- call_extension(wb_new_line_draw, &new_line_start, wb, y - miny, maxy - y, minx, maxx, &global_attr);
- if (new_line_start) {
+ int offset_start = repl - fb->contents - 1;
+ int cursor_x = 0, cursor_y = 0;
+
+ // actually write to the screen
+ int once = 0;
+ int search_found = 0;
+ int non_blocking_search_found = 0;
+
+ // TODO: verify that last - repl is the same as offset_last - offset_start
+ int move_buffer_len = last - repl + 2;
+ uint8_t* move_buffer = xmalloc(move_buffer_len);
+ memset(move_buffer, 0, move_buffer_len);
+ move_buffer[0] = 0;
+ int lastx = x, lasty = y;
+ int move_buffer_index = 0;
+
+ // TODO: write max string len of 127
+ // TODO: make the write thing similar to syntax?
+ char* new_line_start = NULL;
+ call_extension(wb_new_line_draw, &new_line_start, wb, y - miny, maxy - y, minx, maxx, &global_attr);
+ if (new_line_start) {
struct glyph old_attr = global_attr;
global_attr = default_attributes;
x = write_string(new_line_start, y, minx, maxx+1);
global_attr = old_attr;
- }
- continue;
- } else if (*repl == '\t') {
- charsize = 1;
- if ((x - minx) <= 0) {
- x += screen_set_char(' ', x - xscroll, y);
- if (x >= maxx)
- continue;
- }
- while ((x - minx) % tabspaces != 0 && x - xscroll <= maxx)
- x += screen_set_char(' ', x - xscroll, y);
-
- if (x - xscroll <= maxx)
- x += screen_set_char(' ', x, y);
- continue;
}
- rune_t u;
- charsize = utf8_decode_buffer(repl, last - repl, &u);
-
- int width;
- if (x - xscroll >= minx)
- width = screen_set_char(u, x - xscroll, y);
- else
- width = wcwidth(u);
-
- // drawing search highlight
- if (fb->mode & FB_SEARCH_BLOCKING_MASK) {
- if (!search_found && fb_offset_starts_with(fb, repl - fb->contents, fb->search_term))
- search_found = strlen(fb->search_term);
- if (search_found) {
- screen_set_attr(x - xscroll, y)->bg = highlight_color;
- screen_set_attr(x - xscroll, y)->fg = default_attributes.bg;
- search_found--;
- }
+ int tmp = 0;
+ call_extension(wb_write_status_bar, &tmp, NULL, 0, 0, 0, 0, NULL, NULL);
+
+ for (int charsize = 1; repl < last && charsize; repl += charsize) {
+ if (y > lasty) {
+ move_buffer[move_buffer_index] = x - minx;
+ move_buffer[move_buffer_index] |= 1<<7;
+ } else {
+ move_buffer[move_buffer_index] = x - lastx;
+ }
+ move_buffer_index++;
+ lastx = x, lasty = y;
+
+ if (!once && repl - fb->contents >= wb->cursor_offset) {
+ // if the buffer being drawn is focused, set the cursor position global
+ once = 1;
+ cursor_x = x - xscroll;
+ cursor_y = y;
+ LIMIT(cursor_x, minx, maxx);
+ LIMIT(cursor_y, miny, maxy);
+ }
+
+ if (!wrap_buffer && x - xscroll > maxx && *repl != '\n') {
+ charsize = 1;
+ x++;
+ continue;
+ }
+
+ if (*repl == '\n' || (wrap_buffer && x >= maxx)) {
+ x = minx;
+ if (++y >= maxy-1)
+ break;
+ if (wrap_buffer && *repl != '\n')
+ continue;
+ charsize = 1;
+ char* new_line_start = NULL;
+ call_extension(wb_new_line_draw, &new_line_start, wb, y - miny, maxy - y, minx, maxx, &global_attr);
+ if (new_line_start) {
+ struct glyph old_attr = global_attr;
+ global_attr = default_attributes;
+ x = write_string(new_line_start, y, minx, maxx+1);
+ global_attr = old_attr;
+ }
+ continue;
+ } else if (*repl == '\t') {
+ charsize = 1;
+ if ((x - minx) <= 0) {
+ x += screen_set_char(' ', x - xscroll, y);
+ if (x >= maxx)
+ continue;
+ }
+ while ((x - minx) % tabspaces != 0 && x - xscroll <= maxx)
+ x += screen_set_char(' ', x - xscroll, y);
+
+ if (x - xscroll <= maxx)
+ x += screen_set_char(' ', x, y);
+ continue;
+ }
+
+ rune_t u;
+ charsize = utf8_decode_buffer(repl, last - repl, &u);
+
+ int width;
+ if (x - xscroll >= minx)
+ width = screen_set_char(u, x - xscroll, y);
+ else
+ width = wcwidth(u);
+
+ // drawing search highlight
+ if (fb->mode & FB_SEARCH_BLOCKING_MASK) {
+ if (!search_found && fb_offset_starts_with(fb, repl - fb->contents, fb->search_term))
+ search_found = strlen(fb->search_term);
+ if (search_found) {
+ screen_set_attr(x - xscroll, y)->bg = highlight_color;
+ screen_set_attr(x - xscroll, y)->fg = default_attributes.bg;
+ search_found--;
+ }
+ }
+ if (fb->mode & FB_SEARCH_NON_BLOCKING) {
+ if (!non_blocking_search_found && fb_offset_starts_with(fb, repl - fb->contents, fb->non_blocking_search_term))
+ non_blocking_search_found = strlen(fb->search_term);
+ if (non_blocking_search_found) {
+ screen_set_attr(x - xscroll, y)->fg = highlight_color;
+ screen_set_attr(x - xscroll, y)->mode |= ATTR_UNDERLINE;
+ non_blocking_search_found--;
+ }
+ }
+
+ x += width;
}
- if (fb->mode & FB_SEARCH_NON_BLOCKING) {
- if (!non_blocking_search_found && fb_offset_starts_with(fb, repl - fb->contents, fb->non_blocking_search_term))
- non_blocking_search_found = strlen(fb->search_term);
- if (non_blocking_search_found) {
- screen_set_attr(x - xscroll, y)->fg = highlight_color;
- screen_set_attr(x - xscroll, y)->mode |= ATTR_UNDERLINE;
- non_blocking_search_found--;
- }
+ int offset_end = repl - fb->contents;
+ global_attr = default_attributes;
+
+ if (wb->cursor_offset >= fb->len) {
+ cursor_x = x - xscroll;
+ cursor_y = MIN(y, maxy);
}
- x += width;
- }
- int offset_end = repl - fb->contents;
- global_attr = default_attributes;
+ call_extension(window_written_to_screen, wn, offset_start, offset_end, move_buffer, move_buffer_len);
- if (wb->cursor_offset >= fb->len) {
- cursor_x = x - xscroll;
- cursor_y = MIN(y, maxy);
- }
+ int status_end = minx;
+ int write_again;
+ do {
+ write_again = 0;
+ char bar[LINE_MAX_LEN];
+ *bar = 0;
- call_extension(window_written_to_screen, wn, offset_start, offset_end, move_buffer, move_buffer_len);
+ call_extension(wb_write_status_bar, &write_again, wb, status_end, maxx+1, cursor_x - minx + xscroll, cursor_y - miny + wb->y_scroll, bar, &global_attr);
+ status_end = write_string(bar, maxy-1, status_end, maxx+1);
- int status_end = minx;
- int write_again;
- do {
- write_again = 0;
- char bar[LINE_MAX_LEN];
- *bar = 0;
+ global_attr = default_attributes;
+ } while (write_again);
- call_extension(wb_write_status_bar, &write_again, wb, status_end, maxx+1, cursor_x - minx + xscroll, cursor_y - miny + wb->y_scroll, bar, &global_attr);
- status_end = write_string(bar, maxy-1, status_end, maxx+1);
+ if (fb->mode & FB_SELECTION_ON) {
+ int y1, y2, tmp;
+ fb_offset_to_xy(fb, fb->s1o, 0, wb->y_scroll, &tmp, &y1, &tmp);
+ fb_offset_to_xy(fb, fb->s2o, 0, wb->y_scroll, &tmp, &y2, &tmp);
+ writef_string(maxy-1, status_end, maxx, " %dL", abs(y1-y2));
+ }
- global_attr = default_attributes;
- } while (write_again);
-
- if (fb->mode & FB_SELECTION_ON) {
- int y1, y2, tmp;
- fb_offset_to_xy(fb, fb->s1o, 0, wb->y_scroll, &tmp, &y1, &tmp);
- fb_offset_to_xy(fb, fb->s2o, 0, wb->y_scroll, &tmp, &y2, &tmp);
- writef_string(maxy-1, status_end, maxx, " %dL", abs(y1-y2));
- }
-
- if (focused) {
- for (int i = minx; i < maxx+1; i++) {
- if (!(fb->mode & FB_SELECTION_ON)) {
- if (screen_set_attr(i, cursor_y)->bg == default_attributes.bg)
- screen_set_attr(i, cursor_y)->bg = mouse_line_bg;
- }
- screen_set_attr(i, maxy-1)->bg = alternate_bg_bright;
+ if (focused) {
+ for (int i = minx; i < maxx+1; i++) {
+ if (!(fb->mode & FB_SELECTION_ON)) {
+ if (screen_set_attr(i, cursor_y)->bg == default_attributes.bg)
+ screen_set_attr(i, cursor_y)->bg = mouse_line_bg;
+ }
+ screen_set_attr(i, maxy-1)->bg = alternate_bg_bright;
+ }
}
- }
- wb_write_selection(wb, minx, miny, maxx, maxy);
- //do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
+ wb_write_selection(wb, minx, miny, maxx, maxy);
+ //do_syntax_scheme(NULL, &(struct syntax_scheme){0}, 0);
- for (int i = miny; i < maxy; i++)
- xdrawline(minx, i, maxx+1);
+ for (int i = miny; i < maxy; i++)
+ xdrawline(minx, i, maxx+1);
- draw_horisontal_line(maxy-1, minx, maxx);
+ draw_horisontal_line(maxy-1, minx, maxx);
- xdrawcursor(cursor_x, cursor_y, focused);
- free(move_buffer);
+ xdrawcursor(cursor_x, cursor_y, focused);
+ free(move_buffer);
}
int
write_string(const char* string, int y, int minx, int maxx)
{
- if (!string)
- return 0;
- LIMIT(maxx, 0, screen.col);
- LIMIT(minx, 0, maxx);
-
- int offset = 0;
- int len = strlen(string);
- while(minx < maxx && offset < len) {
- rune_t u;
- int charsize = utf8_decode_buffer(string + offset, len - offset, &u);
- offset += charsize;
- if (charsize == 1 && u <= 32)
- u = ' ';
- minx += screen_set_char(u, minx, y);
- }
- return minx;
+ if (!string)
+ return 0;
+ LIMIT(maxx, 0, screen.col);
+ LIMIT(minx, 0, maxx);
+
+ int offset = 0;
+ int len = strlen(string);
+ while(minx < maxx && offset < len) {
+ rune_t u;
+ int charsize = utf8_decode_buffer(string + offset, len - offset, &u);
+ offset += charsize;
+ if (charsize == 1 && u <= 32)
+ u = ' ';
+ minx += screen_set_char(u, minx, y);
+ }
+ return minx;
}
void
color_selection(struct glyph* letter)
{
- if (letter->bg == default_attributes.bg)
- letter->bg = selection_bg;
+ if (letter->bg == default_attributes.bg)
+ letter->bg = selection_bg;
}
void
wb_move_cursor_to_selection_start(struct window_buffer* wb)
{
- const struct file_buffer* fb = get_fb(wb);
- if (fb_is_selection_start_top_left(fb))
- wb_move_to_offset(wb, fb->s1o, CURSOR_SNAPPED);
- else
- wb_move_to_offset(wb, fb->s2o, CURSOR_SNAPPED);
+ const struct file_buffer* fb = get_fb(wb);
+ if (fb_is_selection_start_top_left(fb))
+ wb_move_to_offset(wb, fb->s1o, CURSOR_SNAPPED);
+ else
+ wb_move_to_offset(wb, fb->s2o, CURSOR_SNAPPED);
}
void
wb_write_selection(struct window_buffer* wb, int minx, int miny, int maxx, int maxy)
{
- soft_assert(wb, return;);
- struct file_buffer* fb = get_fb(wb);
-
- LIMIT(maxx, 0, screen.col-1);
- LIMIT(maxy, 0, screen.row-1);
- LIMIT(minx, 0, maxx);
- LIMIT(miny, 0, maxy);
-
- if (!(fb->mode & FB_SELECTION_ON))
- return;
-
- int x, y, x2, y2, tmp, xscroll;
- if (fb_is_selection_start_top_left(fb)) {
- fb_offset_to_xy(fb, fb->s1o, maxx - minx, wb->y_scroll, &x, &y, &tmp);
- fb_offset_to_xy(fb, fb->s2o, maxx - minx, wb->y_scroll, &x2, &y2, &xscroll);
- } else {
- fb_offset_to_xy(fb, fb->s2o, maxx - minx, wb->y_scroll, &x, &y, &xscroll);
- fb_offset_to_xy(fb, fb->s1o, maxx - minx, wb->y_scroll, &x2, &y2, &tmp);
- }
- x += minx, x2 += minx + 1;
- y += miny, y2 += miny;
- if (!wrap_buffer) {
- x -= xscroll;
- x2 -= xscroll;
- }
-
-
- for(; y < y2; y++) {
- for(; x <= maxx; x++)
- color_selection(screen_set_attr(x, y));
- x = 0;
- }
- for(; x < x2; x++)
- color_selection(screen_set_attr(x, y));
+ soft_assert(wb, return;);
+ struct file_buffer* fb = get_fb(wb);
+
+ LIMIT(maxx, 0, screen.col-1);
+ LIMIT(maxy, 0, screen.row-1);
+ LIMIT(minx, 0, maxx);
+ LIMIT(miny, 0, maxy);
+
+ if (!(fb->mode & FB_SELECTION_ON))
+ return;
+
+ int x, y, x2, y2, tmp, xscroll;
+ if (fb_is_selection_start_top_left(fb)) {
+ fb_offset_to_xy(fb, fb->s1o, maxx - minx, wb->y_scroll, &x, &y, &tmp);
+ fb_offset_to_xy(fb, fb->s2o, maxx - minx, wb->y_scroll, &x2, &y2, &xscroll);
+ } else {
+ fb_offset_to_xy(fb, fb->s2o, maxx - minx, wb->y_scroll, &x, &y, &xscroll);
+ fb_offset_to_xy(fb, fb->s1o, maxx - minx, wb->y_scroll, &x2, &y2, &tmp);
+ }
+ x += minx, x2 += minx + 1;
+ y += miny, y2 += miny;
+ if (!wrap_buffer) {
+ x -= xscroll;
+ x2 -= xscroll;
+ }
+
+
+ for(; y < y2; y++) {
+ for(; x <= maxx; x++)
+ color_selection(screen_set_attr(x, y));
+ x = 0;
+ }
+ for(; x < x2; x++)
+ color_selection(screen_set_attr(x, y));
}
diff --git a/seek.c b/seek.c
@@ -21,266 +21,266 @@
int
str_contains_char(const char* string, char check)
{
- return strchr(string, check) != NULL;
+ return strchr(string, check) != NULL;
}
inline int
is_file_type(const char* file_path, const char* file_type)
{
- int ftlen = strlen(file_type);
- int offset = strlen(file_path) - ftlen;
- if(offset >= 0 && memcmp(file_path + offset, file_type, ftlen) == 0)
- return 1;
- return 0;
+ int ftlen = strlen(file_type);
+ int offset = strlen(file_path) - ftlen;
+ if(offset >= 0 && memcmp(file_path + offset, file_type, ftlen) == 0)
+ return 1;
+ return 0;
}
char*
file_path_get_path(const char* path)
{
- soft_assert(path, path = "/";);
+ soft_assert(path, path = "/";);
- const char* folder_start = strrchr(path, '/');
- if (!folder_start)
- folder_start = path;
- else
- folder_start++;
- int folder_len = folder_start - path;
- char* folder = xmalloc(folder_len + 1);
+ const char* folder_start = strrchr(path, '/');
+ if (!folder_start)
+ folder_start = path;
+ else
+ folder_start++;
+ int folder_len = folder_start - path;
+ char* folder = xmalloc(folder_len + 1);
- memcpy(folder, path, folder_len);
- folder[folder_len] = '\0';
+ memcpy(folder, path, folder_len);
+ folder[folder_len] = '\0';
- return folder;
+ return folder;
}
inline int
path_is_folder(const char* path)
{
- struct stat statbuf;
- if (stat(path, &statbuf) != 0)
- return 0;
- return S_ISDIR(statbuf.st_mode);
+ struct stat statbuf;
+ if (stat(path, &statbuf) != 0)
+ return 0;
+ return S_ISDIR(statbuf.st_mode);
}
inline int
fb_seek_char(const struct file_buffer* fb, int offset, char byte)
{
- if (offset > fb->len) return -1;
- char* new_buf = memchr(fb->contents + offset, byte, fb->len - offset);
- if (!new_buf) return -1;
- return new_buf - fb->contents;
+ if (offset > fb->len) return -1;
+ char* new_buf = memchr(fb->contents + offset, byte, fb->len - offset);
+ if (!new_buf) return -1;
+ return new_buf - fb->contents;
}
inline int
fb_seek_char_backwards(const struct file_buffer* fb, int offset, char byte)
{
- BOUNDS_CHECK(offset, 0, fb->len-1);
- for (int n = offset-1; n >= 0; n--) {
- if (fb->contents[n] == byte) {
- return n+1;
+ BOUNDS_CHECK(offset, 0, fb->len-1);
+ for (int n = offset-1; n >= 0; n--) {
+ if (fb->contents[n] == byte) {
+ return n+1;
+ }
}
- }
- return -1;
+ return -1;
}
inline int
fb_seek_string(const struct file_buffer* fb, int offset, const char* string)
{
- BOUNDS_CHECK(offset, 0, fb->len-1);
- int str_len = strlen(string);
+ BOUNDS_CHECK(offset, 0, fb->len-1);
+ int str_len = strlen(string);
#if 0
- for (int n = offset; n < fb->len - str_len; n++)
- if (!memcmp(fb->contents + n, string, str_len))
- return n;
+ for (int n = offset; n < fb->len - str_len; n++)
+ if (!memcmp(fb->contents + n, string, str_len))
+ return n;
#else
- char* res = memmem(fb->contents + offset, fb->len - offset,
- string, str_len);
- if (res)
- return res - fb->contents;
+ char* res = memmem(fb->contents + offset, fb->len - offset,
+ string, str_len);
+ if (res)
+ return res - fb->contents;
#endif
- return -1;
+ return -1;
}
inline int
fb_seek_string_backwards(const struct file_buffer* fb, int offset, const char* string)
{
- int str_len = strlen(string);
- offset += str_len;
- BOUNDS_CHECK(offset, 0, fb->len-1);
-
- for (int n = offset - str_len; n >= 0; n--)
- if (!memcmp(fb->contents + n, string, str_len))
- return n;
- return -1;
+ int str_len = strlen(string);
+ offset += str_len;
+ BOUNDS_CHECK(offset, 0, fb->len-1);
+
+ for (int n = offset - str_len; n >= 0; n--)
+ if (!memcmp(fb->contents + n, string, str_len))
+ return n;
+ return -1;
}
inline int
wb_seek_string_wrap(const struct window_buffer* wb, int offset, const char* search)
{
- struct file_buffer* fb = get_fb(focused_window);
- if (*search == 0 || !fb_count_string_instances(fb, search, 0, NULL))
- return -1;
+ struct file_buffer* fb = get_fb(focused_window);
+ if (*search == 0 || !fb_count_string_instances(fb, search, 0, NULL))
+ return -1;
- int new_offset = fb_seek_string(fb, offset, search);
- if (new_offset < 0)
- new_offset = fb_seek_string(fb, 0, search);
+ int new_offset = fb_seek_string(fb, offset, search);
+ if (new_offset < 0)
+ new_offset = fb_seek_string(fb, 0, search);
- if (!(fb->mode & FB_SEARCH_BLOCKING))
- fb->mode |= FB_SEARCH_BLOCKING_IDLE;
- return new_offset;
+ if (!(fb->mode & FB_SEARCH_BLOCKING))
+ fb->mode |= FB_SEARCH_BLOCKING_IDLE;
+ return new_offset;
}
inline int
wb_seek_string_wrap_backwards(const struct window_buffer* wb, int offset, const char* search)
{
- struct file_buffer* fb = get_fb(focused_window);
- if (*search == 0 || !fb_count_string_instances(fb, search, 0, NULL))
- return -1;
+ struct file_buffer* fb = get_fb(focused_window);
+ if (*search == 0 || !fb_count_string_instances(fb, search, 0, NULL))
+ return -1;
- int new_offset = fb_seek_string_backwards(fb, offset, search);
- if (new_offset < 0)
- new_offset = fb_seek_string_backwards(fb, fb->len, search);
+ int new_offset = fb_seek_string_backwards(fb, offset, search);
+ if (new_offset < 0)
+ new_offset = fb_seek_string_backwards(fb, fb->len, search);
- if (!(fb->mode & FB_SEARCH_BLOCKING))
- fb->mode |= FB_SEARCH_BLOCKING_IDLE;
- return new_offset;
+ if (!(fb->mode & FB_SEARCH_BLOCKING))
+ fb->mode |= FB_SEARCH_BLOCKING_IDLE;
+ return new_offset;
}
int
fb_is_on_a_word(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- return !str_contains_char(word_seperators, fb->contents[offset]);
+ BOUNDS_CHECK(offset, 0, fb->len);
+ return !str_contains_char(word_seperators, fb->contents[offset]);
}
inline int
fb_is_start_of_a_word(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- return fb_is_on_a_word(fb, offset, word_seperators) &&
- (offset-1 <= 0 || str_contains_char(word_seperators, fb->contents[offset-1]));
+ BOUNDS_CHECK(offset, 0, fb->len);
+ return fb_is_on_a_word(fb, offset, word_seperators) &&
+ (offset-1 <= 0 || str_contains_char(word_seperators, fb->contents[offset-1]));
}
inline int
fb_is_on_word(const struct file_buffer* fb, int offset, const char* word_seperators, const char* word)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- int word_start = fb_seek_start_of_word_backwards(fb, offset, word_seperators);
- int word_len = strlen(word);
- if (word_start < offset - (word_len-1))
- return 0;
- return fb_offset_starts_with(fb, word_start, word) &&
- !fb_is_on_a_word(fb, word_start + word_len, word_seperators);
+ BOUNDS_CHECK(offset, 0, fb->len);
+ int word_start = fb_seek_start_of_word_backwards(fb, offset, word_seperators);
+ int word_len = strlen(word);
+ if (word_start < offset - (word_len-1))
+ return 0;
+ return fb_offset_starts_with(fb, word_start, word) &&
+ !fb_is_on_a_word(fb, word_start + word_len, word_seperators);
}
inline int
fb_offset_starts_with(const struct file_buffer* fb, int offset, const char* start)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- if (offset > 0 && fb->contents[offset-1] == '\\') return 0;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ if (offset > 0 && fb->contents[offset-1] == '\\') return 0;
- int len = strlen(start);
- int mlen = MIN(len, fb->len - offset);
- return memcmp(fb->contents + offset, start, mlen) == 0;
+ int len = strlen(start);
+ int mlen = MIN(len, fb->len - offset);
+ return memcmp(fb->contents + offset, start, mlen) == 0;
}
inline int
fb_seek_word(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- if (fb_is_on_a_word(fb, offset, word_seperators))
- offset = fb_seek_word_end(fb, offset, word_seperators);
- while (offset < fb->len && str_contains_char(word_seperators, fb->contents[offset])) offset++;
- return offset;
+ if (fb_is_on_a_word(fb, offset, word_seperators))
+ offset = fb_seek_word_end(fb, offset, word_seperators);
+ while (offset < fb->len && str_contains_char(word_seperators, fb->contents[offset])) offset++;
+ return offset;
}
inline int
fb_seek_word_end(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- if (!fb_is_on_a_word(fb, offset, word_seperators))
- offset = fb_seek_word(fb, offset, word_seperators);
- while (offset < fb->len && !str_contains_char(word_seperators, fb->contents[offset])) offset++;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ if (!fb_is_on_a_word(fb, offset, word_seperators))
+ offset = fb_seek_word(fb, offset, word_seperators);
+ while (offset < fb->len && !str_contains_char(word_seperators, fb->contents[offset])) offset++;
+ return offset;
}
inline int
fb_seek_word_backwards(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- if (!fb_is_on_a_word(fb, offset, word_seperators))
- while (offset > 0 && str_contains_char(word_seperators, fb->contents[offset])) offset--;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ if (!fb_is_on_a_word(fb, offset, word_seperators))
+ while (offset > 0 && str_contains_char(word_seperators, fb->contents[offset])) offset--;
+ return offset;
}
inline int
fb_seek_start_of_word_backwards(const struct file_buffer* fb, int offset, const char* word_seperators)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- if (!fb_is_on_a_word(fb, offset, word_seperators))
- while (offset > 0 && str_contains_char(word_seperators, fb->contents[offset])) offset--;
- while (offset > 0 && !str_contains_char(word_seperators, fb->contents[offset])) offset--;
- return offset+1;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ if (!fb_is_on_a_word(fb, offset, word_seperators))
+ while (offset > 0 && str_contains_char(word_seperators, fb->contents[offset])) offset--;
+ while (offset > 0 && !str_contains_char(word_seperators, fb->contents[offset])) offset--;
+ return offset+1;
}
inline int
fb_seek_whitespace(const struct file_buffer* fb, int offset)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- while (offset < fb->len && !isspace(fb->contents[offset])) offset++;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ while (offset < fb->len && !isspace(fb->contents[offset])) offset++;
+ return offset;
}
inline int
fb_seek_whitespace_backwards(const struct file_buffer* fb, int offset)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- while (offset > 0 && !isspace(fb->contents[offset])) offset--;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ while (offset > 0 && !isspace(fb->contents[offset])) offset--;
+ return offset;
}
inline int
fb_seek_not_whitespace(const struct file_buffer* fb, int offset)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- while (offset < fb->len && isspace(fb->contents[offset])) offset++;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ while (offset < fb->len && isspace(fb->contents[offset])) offset++;
+ return offset;
}
inline int
fb_seek_not_whitespace_backwards(const struct file_buffer* fb, int offset)
{
- BOUNDS_CHECK(offset, 0, fb->len);
- while (offset > 0 && isspace(fb->contents[offset])) offset--;
- return offset;
+ BOUNDS_CHECK(offset, 0, fb->len);
+ while (offset > 0 && isspace(fb->contents[offset])) offset--;
+ return offset;
}
inline int
fb_count_string_instances(const struct file_buffer* fb, const char* string, int offset, int* before_offset)
{
- int tmp;
- if (!before_offset)
- before_offset = &tmp;
- if (!string || *string == 0) {
- *before_offset = 0;
- return 0;
- }
-
- int pos = -1;
- int count = 0;
- int once = 1;
- while((pos = fb_seek_string(fb, pos+1, string)) >= 0) {
- if (pos > 0 && fb->contents[pos-2] == '\\')
- continue;
- if (once && pos > offset) {
- *before_offset = count;
- once = 0;
+ int tmp;
+ if (!before_offset)
+ before_offset = &tmp;
+ if (!string || *string == 0) {
+ *before_offset = 0;
+ return 0;
}
- count++;
- }
- if (once)
- *before_offset = count;
- return count;
+
+ int pos = -1;
+ int count = 0;
+ int once = 1;
+ while((pos = fb_seek_string(fb, pos+1, string)) >= 0) {
+ if (pos > 0 && fb->contents[pos-2] == '\\')
+ continue;
+ if (once && pos > offset) {
+ *before_offset = count;
+ once = 0;
+ }
+ count++;
+ }
+ if (once)
+ *before_offset = count;
+ return count;
}
/*
@@ -296,189 +296,189 @@ fb_count_string_instances(const struct file_buffer* fb, const char* string, int
int
fb_seek_string_not_escaped(const struct file_buffer* fb, int offset, const char* string)
{
- for (;;) {
- offset = fb_seek_string(fb, offset, string);
- if (offset >= 0 && fb->contents[offset-1] == '\\')
- offset++;
- else
- break;
- }
- return offset;
+ for (;;) {
+ offset = fb_seek_string(fb, offset, string);
+ if (offset >= 0 && fb->contents[offset-1] == '\\')
+ offset++;
+ else
+ break;
+ }
+ return offset;
}
inline int
fb_seek_string_backwards_not_escaped(const struct file_buffer* fb, int offset, const char* string)
{
- for (;;) {
- offset = fb_seek_string_backwards(fb, offset, string);
- if (offset >= 0 && fb->contents[offset-1] == '\\')
- offset--;
- else
- break;
- }
- return offset;
+ for (;;) {
+ offset = fb_seek_string_backwards(fb, offset, string);
+ if (offset >= 0 && fb->contents[offset-1] == '\\')
+ offset--;
+ else
+ break;
+ }
+ return offset;
}
inline static int
fb_get_delimiter_equal_start_end(const struct file_buffer* fb, int offset, const char* string, struct delimiter* ignore, int* start, int* end)
{
- int ignore_index = 0;
- int last_distance = 0;
-
- while (last_distance >= 0) {
- int d_res = INT32_MAX;
- int i = 0;
- if (ignore) {
- for (struct delimiter* ign = ignore; ign->start; ign++) {
- int d = fb_seek_string_not_escaped(fb, last_distance, ign->start);
- if (d < 0 || d > offset) {
- i++;
- continue;
+ int ignore_index = 0;
+ int last_distance = 0;
+
+ while (last_distance >= 0) {
+ int d_res = INT32_MAX;
+ int i = 0;
+ if (ignore) {
+ for (struct delimiter* ign = ignore; ign->start; ign++) {
+ int d = fb_seek_string_not_escaped(fb, last_distance, ign->start);
+ if (d < 0 || d > offset) {
+ i++;
+ continue;
+ }
+
+ if (d < d_res) {
+ d_res = d;
+ ignore_index = i;
+ }
+ i++;
+ }
}
-
- if (d < d_res) {
- d_res = d;
- ignore_index = i;
+ int str_d = fb_seek_string_not_escaped(fb, last_distance, string);
+
+ if ((str_d <= 0 || str_d > offset) && d_res == INT32_MAX)
+ return 0;
+
+ const char* end_str;
+ if (str_d >= 0 && str_d <= d_res) {
+ last_distance = str_d;
+ end_str = string;
+ *start = last_distance;
+ } else {
+ last_distance = d_res;
+ end_str = ignore[ignore_index].end;
}
- i++;
- }
- }
- int str_d = fb_seek_string_not_escaped(fb, last_distance, string);
-
- if ((str_d <= 0 || str_d > offset) && d_res == INT32_MAX)
- return 0;
-
- const char* end_str;
- if (str_d >= 0 && str_d <= d_res) {
- last_distance = str_d;
- end_str = string;
- *start = last_distance;
- } else {
- last_distance = d_res;
- end_str = ignore[ignore_index].end;
- }
- last_distance = fb_seek_string_not_escaped(fb, last_distance+1, end_str);
+ last_distance = fb_seek_string_not_escaped(fb, last_distance+1, end_str);
- if (end_str == string && last_distance > offset) {
- *end = last_distance;
- return 1;
+ if (end_str == string && last_distance > offset) {
+ *end = last_distance;
+ return 1;
+ }
+ if (last_distance >= 0)
+ last_distance++;
}
- if (last_distance >= 0)
- last_distance++;
- }
- return 0;
+ return 0;
}
inline static int
fb_get_matched_delimiter_end(const struct file_buffer* fb, int offset, struct delimiter d)
{
- int closers_left = 1;
- while (closers_left) {
- int next_open = fb_seek_string_not_escaped(fb, offset, d.start);
- int next_close = fb_seek_string_not_escaped(fb, offset, d.end);
-
- if (next_close < 0 || next_open < 0)
- return next_close;
-
- if (next_open < next_close) {
- closers_left++;
- offset = next_open+1;
- } else {
- closers_left--;
- offset = next_close;
- if (closers_left)
- offset++;
+ int closers_left = 1;
+ while (closers_left) {
+ int next_open = fb_seek_string_not_escaped(fb, offset, d.start);
+ int next_close = fb_seek_string_not_escaped(fb, offset, d.end);
+
+ if (next_close < 0 || next_open < 0)
+ return next_close;
+
+ if (next_open < next_close) {
+ closers_left++;
+ offset = next_open+1;
+ } else {
+ closers_left--;
+ offset = next_close;
+ if (closers_left)
+ offset++;
+ }
}
- }
- return offset;
+ return offset;
}
inline static int
fb_get_matched_delimiter_start(const struct file_buffer* fb, int offset, struct delimiter d)
{
- int openers_left = 1;
- while (openers_left) {
- int next_open = fb_seek_string_backwards_not_escaped(fb, offset, d.start);
- int next_close = fb_seek_string_backwards_not_escaped(fb, offset, d.end);
-
- if (next_close < 0 || next_open < 0)
- return next_open;
-
- if (next_open < next_close) {
- openers_left++;
- offset = next_open-1;
- } else {
- openers_left--;
- offset = next_open;
- if (openers_left)
- offset--;
+ int openers_left = 1;
+ while (openers_left) {
+ int next_open = fb_seek_string_backwards_not_escaped(fb, offset, d.start);
+ int next_close = fb_seek_string_backwards_not_escaped(fb, offset, d.end);
+
+ if (next_close < 0 || next_open < 0)
+ return next_open;
+
+ if (next_open < next_close) {
+ openers_left++;
+ offset = next_open-1;
+ } else {
+ openers_left--;
+ offset = next_open;
+ if (openers_left)
+ offset--;
+ }
}
- }
- return offset;
+ return offset;
}
inline int
fb_get_delimiter(const struct file_buffer* fb, int offset, struct delimiter d, struct delimiter* ignore, int* start, int* end)
{
- const char* start_word = d.start;
- const char* end_word = d.end;
-
- soft_assert(start, return 0;);
- soft_assert(end, return 0;);
- soft_assert(start_word, return 0;);
- soft_assert(end_word, return 0;);
-
- if (strcmp(start_word, end_word) == 0)
- return fb_get_delimiter_equal_start_end(fb, offset, start_word, ignore, start, end);
- int wanted_opener = fb_get_matched_delimiter_start(fb, offset, d);
-
- int ignore_index = 0;
- int last_distance = 0;
-
- while (last_distance >= 0) {
- int d_res = INT32_MAX;
- int i = 0;
- if (ignore) {
- for (struct delimiter* ign = ignore; ign->start; ign++) {
- int d = fb_seek_string_not_escaped(fb, last_distance, ign->start);
- if (d < 0 || d > offset) {
- i++;
- continue;
+ const char* start_word = d.start;
+ const char* end_word = d.end;
+
+ soft_assert(start, return 0;);
+ soft_assert(end, return 0;);
+ soft_assert(start_word, return 0;);
+ soft_assert(end_word, return 0;);
+
+ if (strcmp(start_word, end_word) == 0)
+ return fb_get_delimiter_equal_start_end(fb, offset, start_word, ignore, start, end);
+ int wanted_opener = fb_get_matched_delimiter_start(fb, offset, d);
+
+ int ignore_index = 0;
+ int last_distance = 0;
+
+ while (last_distance >= 0) {
+ int d_res = INT32_MAX;
+ int i = 0;
+ if (ignore) {
+ for (struct delimiter* ign = ignore; ign->start; ign++) {
+ int d = fb_seek_string_not_escaped(fb, last_distance, ign->start);
+ if (d < 0 || d > offset) {
+ i++;
+ continue;
+ }
+
+ if (d < d_res) {
+ d_res = d;
+ ignore_index = i;
+ }
+ i++;
+ }
}
+ int str_d = fb_seek_string_not_escaped(fb, last_distance, start_word);
- if (d < d_res) {
- d_res = d;
- ignore_index = i;
- }
- i++;
- }
- }
- int str_d = fb_seek_string_not_escaped(fb, last_distance, start_word);
+ if ((str_d <= 0 || str_d > offset) && d_res == INT32_MAX)
+ return 0;
- if ((str_d <= 0 || str_d > offset) && d_res == INT32_MAX)
- return 0;
+ if (str_d >= 0 && str_d <= d_res) {
+ if (str_d == wanted_opener) {
+ last_distance = str_d;
+ *start = last_distance;
- if (str_d >= 0 && str_d <= d_res) {
- if (str_d == wanted_opener) {
- last_distance = str_d;
- *start = last_distance;
+ last_distance = fb_get_matched_delimiter_end(fb, last_distance+1, d);
- last_distance = fb_get_matched_delimiter_end(fb, last_distance+1, d);
+ if (last_distance > offset) {
+ *end = last_distance;
+ return 1;
+ }
+ }
+ } else {
+ last_distance = d_res;
- if (last_distance > offset) {
- *end = last_distance;
- return 1;
+ last_distance = fb_seek_string_not_escaped(fb, last_distance+1, ignore[ignore_index].end);
}
- }
- } else {
- last_distance = d_res;
- last_distance = fb_seek_string_not_escaped(fb, last_distance+1, ignore[ignore_index].end);
+ if (last_distance >= 0)
+ last_distance++;
}
-
- if (last_distance >= 0)
- last_distance++;
- }
- return 0;
+ return 0;
}
diff --git a/seek.h b/seek.h
@@ -8,8 +8,8 @@
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
struct delimiter {
- char* start;
- char* end;
+ char* start;
+ char* end;
};
int str_contains_char(const char* string, char check);
diff --git a/utf8.c b/utf8.c
@@ -17,101 +17,101 @@ static size_t utf8_validate(rune_t *, size_t);
rune_t
utf8_decodebyte(char c, size_t *i)
{
- for (*i = 0; *i < LEN(utfmask); ++(*i))
- if (((uint8_t)c & utfmask[*i]) == utfbyte[*i])
- return (uint8_t)c & ~utfmask[*i];
- return 0;
+ for (*i = 0; *i < LEN(utfmask); ++(*i))
+ if (((uint8_t)c & utfmask[*i]) == utfbyte[*i])
+ return (uint8_t)c & ~utfmask[*i];
+ return 0;
}
size_t
utf8_encode(rune_t u, char *c)
{
- size_t len, i;
+ size_t len, i;
- len = utf8_validate(&u, 0);
- if (len > UTF_SIZ)
- return 0;
+ len = utf8_validate(&u, 0);
+ if (len > UTF_SIZ)
+ return 0;
- for (i = len - 1; i != 0; --i) {
- c[i] = utf8_encodebyte(u, 0);
- u >>= 6;
- }
- c[0] = utf8_encodebyte(u, len);
+ for (i = len - 1; i != 0; --i) {
+ c[i] = utf8_encodebyte(u, 0);
+ u >>= 6;
+ }
+ c[0] = utf8_encodebyte(u, len);
- return len;
+ return len;
}
char
utf8_encodebyte(rune_t u, size_t i)
{
- return utfbyte[i] | (u & ~utfmask[i]);
+ return utfbyte[i] | (u & ~utfmask[i]);
}
size_t
utf8_validate(rune_t *u, size_t i)
{
- const rune_t utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
- const rune_t utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+ const rune_t utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
+ const rune_t utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+ *u = UTF_INVALID;
+ for (i = 1; *u > utfmax[i]; ++i)
+ ;
- return i;
+ return i;
}
size_t
utf8_decode(const char *c, rune_t *u, size_t clen)
{
- size_t i, j, len, type;
- rune_t udecoded;
+ size_t i, j, len, type;
+ rune_t udecoded;
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8_decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8_decodebyte(c[i], &type);
- if (type != 0)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8_validate(u, len);
-
- return len;
+ *u = UTF_INVALID;
+ if (!clen)
+ return 0;
+ udecoded = utf8_decodebyte(c[0], &len);
+ if (!BETWEEN(len, 1, UTF_SIZ))
+ return 1;
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | utf8_decodebyte(c[i], &type);
+ if (type != 0)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ utf8_validate(u, len);
+
+ return len;
}
int
utf8_decode_buffer(const char* buffer, const int buflen, rune_t* u)
{
- if (!buflen) return 0;
+ if (!buflen) return 0;
- rune_t u_tmp;
- int charsize;
- if (!u)
- u = &u_tmp;
+ rune_t u_tmp;
+ int charsize;
+ if (!u)
+ u = &u_tmp;
- // process a complete utf8 char
- charsize = utf8_decode(buffer, u, buflen);
+ // process a complete utf8 char
+ charsize = utf8_decode(buffer, u, buflen);
- return charsize;
+ return charsize;
}
void
utf8_remove_string_end(char* string)
{
- char* end = string + strlen(string);
- if (end == string)
- return;
-
- do {
- end--;
- // if byte starts with 0b10, byte is an UTF-8 extender
- } while (end > string && (*end & 0xC0) == 0x80);
- *end = 0;
+ char* end = string + strlen(string);
+ if (end == string)
+ return;
+
+ do {
+ end--;
+ // if byte starts with 0b10, byte is an UTF-8 extender
+ } while (end > string && (*end & 0xC0) == 0x80);
+ *end = 0;
}
diff --git a/x.c b/x.c
@@ -31,15 +31,15 @@
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
-#define IS_SET(flag) ((win.mode & (flag)) != 0)
-#define TRUERED(x) (((x) & 0xff0000) >> 8)
-#define TRUEGREEN(x) (((x) & 0xff00))
-#define TRUEBLUE(x) (((x) & 0xff) << 8)
-#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
-#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
-#define IS_TRUECOL(x) (1 << 24 & (x))
-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
-#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
+#define IS_SET(flag) ((win.mode & (flag)) != 0)
+#define TRUERED(x) (((x) & 0xff0000) >> 8)
+#define TRUEGREEN(x) (((x) & 0xff00))
+#define TRUEBLUE(x) (((x) & 0xff) << 8)
+#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
+#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
+#define IS_TRUECOL(x) (1 << 24 & (x))
+#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
+#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
@@ -48,11 +48,11 @@
// Purely graphic info
typedef struct {
- int tw, th; // tty width and height
- int w, h; // window width and height
- int ch; // char height
- int cw; // char width
- int mode; // window state/mode flags
+ int tw, th; // tty width and height
+ int w, h; // window width and height
+ int ch; // char height
+ int cw; // char width
+ int mode; // window state/mode flags
} TermWindow;
extern TermWindow win;
@@ -61,56 +61,56 @@ typedef XftColor Color;
typedef XftGlyphFontSpec GlyphFontSpec;
typedef struct {
- Display *dpy;
- Colormap cmap;
- Window win;
- Drawable buf;
- GlyphFontSpec *specbuf; // font spec buffer used for rendering
- Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
- struct {
- XIM xim;
- XIC xic;
- XPoint spot;
- XVaNestedList spotlist;
- } ime;
- Draw draw;
- Visual *vis;
- XSetWindowAttributes attrs;
- int scr;
- int isfixed; // is fixed geometry?
- int l, t; // left and top offset
- int gm; // geometry mask
+ Display *dpy;
+ Colormap cmap;
+ Window win;
+ Drawable buf;
+ GlyphFontSpec *specbuf; // font spec buffer used for rendering
+ Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
+ struct {
+ XIM xim;
+ XIC xic;
+ XPoint spot;
+ XVaNestedList spotlist;
+ } ime;
+ Draw draw;
+ Visual *vis;
+ XSetWindowAttributes attrs;
+ int scr;
+ int isfixed; // is fixed geometry?
+ int l, t; // left and top offset
+ int gm; // geometry mask
} XWindow;
extern XWindow xw;
// Font structure
#define Font Font_
typedef struct {
- int height;
- int width;
- int ascent;
- int descent;
- int badslant;
- int badweight;
- short lbearing;
- short rbearing;
- XftFont *match;
- FcFontSet *set;
- FcPattern *pattern;
+ int height;
+ int width;
+ int ascent;
+ int descent;
+ int badslant;
+ int badweight;
+ short lbearing;
+ short rbearing;
+ XftFont *match;
+ FcFontSet *set;
+ FcPattern *pattern;
} Font;
// Font Ring Cache
enum {
- FRC_NORMAL,
- FRC_ITALIC,
- FRC_BOLD,
- FRC_ITALICBOLD
+ FRC_NORMAL,
+ FRC_ITALIC,
+ FRC_BOLD,
+ FRC_ITALICBOLD
};
typedef struct {
- XftFont *font;
- int flags;
- rune_t unicodep;
+ XftFont *font;
+ int flags;
+ rune_t unicodep;
} Fontcache;
extern Fontcache *frc;
@@ -118,10 +118,10 @@ extern int frclen;
// Drawing Context
typedef struct {
- Color *col;
- size_t collen;
- Font font, bfont, ifont, ibfont;
- GC gc;
+ Color *col;
+ size_t collen;
+ Font font, bfont, ifont, ibfont;
+ GC gc;
} DC;
extern DC dc;
@@ -164,17 +164,17 @@ static void resize(XEvent *);
static void focus(XEvent *);
static void (*handler[LASTEvent])(XEvent *) = {
- [KeyPress] = kpress,
- [ClientMessage] = cmessage,
- [ConfigureNotify] = resize,
- [VisibilityNotify] = visibility,
- [UnmapNotify] = unmap,
- [Expose] = expose,
- [FocusIn] = focus,
- [FocusOut] = focus,
- [PropertyNotify] = propnotify,
- [SelectionNotify] = selnotify,
- [SelectionRequest] = selrequest,
+ [KeyPress] = kpress,
+ [ClientMessage] = cmessage,
+ [ConfigureNotify] = resize,
+ [VisibilityNotify] = visibility,
+ [UnmapNotify] = unmap,
+ [Expose] = expose,
+ [FocusIn] = focus,
+ [FocusOut] = focus,
+ [PropertyNotify] = propnotify,
+ [SelectionNotify] = selnotify,
+ [SelectionRequest] = selrequest,
};
////////////////////////////////////////////////
@@ -206,111 +206,111 @@ double usedfontsize = 0;
void
screen_init(int col, int row)
{
- global_attr = default_attributes;
+ global_attr = default_attributes;
- screen.col = 0;
- screen.row = 0;
- screen.lines = NULL;
- screen_resize(col, row);
+ screen.col = 0;
+ screen.row = 0;
+ screen.lines = NULL;
+ screen_resize(col, row);
}
void
draw_horisontal_line(int y, int x1, int x2)
{
- if (y < 0 || y > screen.row ||
- x2 < x1 || x2 > screen.col ||
- x1 < 0 || x1 > x2-1)
- return;
-
- Color drawcol = dc.col[default_attributes.fg];
- XftDrawRect(xw.draw, &drawcol,
- border_px + x1 * win.cw, border_px + (y + 1) * win.ch - cursor_thickness,
- win.cw * (x2-x1+1), 1);
+ if (y < 0 || y > screen.row ||
+ x2 < x1 || x2 > screen.col ||
+ x1 < 0 || x1 > x2-1)
+ return;
+
+ Color drawcol = dc.col[default_attributes.fg];
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + x1 * win.cw, border_px + (y + 1) * win.ch - cursor_thickness,
+ win.cw * (x2-x1+1), 1);
}
void
set_clipboard_copy(char* buffer, int len)
{
- if (!buffer)
- return;
- if (copy_buffer)
- free(copy_buffer);
- copy_buffer = buffer;
- copy_len = len;
-
- Atom clipboard;
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
+ if (!buffer)
+ return;
+ if (copy_buffer)
+ free(copy_buffer);
+ copy_buffer = buffer;
+ copy_len = len;
+
+ Atom clipboard;
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
}
void
execute_clipbaord_event()
{
- Atom clipboard;
+ Atom clipboard;
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XConvertSelection(xw.dpy, clipboard, xtarget, clipboard,
- xw.win, CurrentTime);
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ XConvertSelection(xw.dpy, clipboard, xtarget, clipboard,
+ xw.win, CurrentTime);
}
int
screen_set_char(rune_t u, int x, int y)
{
- struct glyph attr = global_attr;
- if (y >= screen.row || x >= screen.col ||
- y < 0 || x < 0)
- return 1;
-
- if (u == 0)
- u = screen.lines[y][x].u;
- int width = wcwidth(u);
- if (width == -1)
- width = 1;
- else if (width > 1)
- attr.mode |= ATTR_WIDE;
-
- if (screen.lines[y][x].mode & ATTR_WIDE || attr.mode & ATTR_WIDE) {
- if (x+1 < screen.col) {
- screen.lines[y][x+1].u = ' ';
- screen.lines[y][x+1].mode |= ATTR_WDUMMY;
- }
- } else if (screen.lines[y][x].mode & ATTR_WDUMMY && x-1 >= 0) {
- screen.lines[y][x-1].u = ' ';
- screen.lines[y][x-1].mode &= ~ATTR_WIDE;
- }
-
- screen.lines[y][x] = attr;
- screen.lines[y][x].u = u;
-
- return width;
+ struct glyph attr = global_attr;
+ if (y >= screen.row || x >= screen.col ||
+ y < 0 || x < 0)
+ return 1;
+
+ if (u == 0)
+ u = screen.lines[y][x].u;
+ int width = wcwidth(u);
+ if (width == -1)
+ width = 1;
+ else if (width > 1)
+ attr.mode |= ATTR_WIDE;
+
+ if (screen.lines[y][x].mode & ATTR_WIDE || attr.mode & ATTR_WIDE) {
+ if (x+1 < screen.col) {
+ screen.lines[y][x+1].u = ' ';
+ screen.lines[y][x+1].mode |= ATTR_WDUMMY;
+ }
+ } else if (screen.lines[y][x].mode & ATTR_WDUMMY && x-1 >= 0) {
+ screen.lines[y][x-1].u = ' ';
+ screen.lines[y][x-1].mode &= ~ATTR_WIDE;
+ }
+
+ screen.lines[y][x] = attr;
+ screen.lines[y][x].u = u;
+
+ return width;
}
void*
xmalloc(size_t len)
{
- void *p;
- if (!(p = malloc(len)))
- die("malloc: error, reutrned NULL | errno: %s\n", strerror(errno));
- return p;
+ void *p;
+ if (!(p = malloc(len)))
+ die("malloc: error, reutrned NULL | errno: %s\n", strerror(errno));
+ return p;
}
void*
xrealloc(void *p, size_t len)
{
- if ((p = realloc(p, len)) == NULL)
- die("realloc: error, returned NULL | errno: %s\n", strerror(errno));
- return p;
+ if ((p = realloc(p, len)) == NULL)
+ die("realloc: error, returned NULL | errno: %s\n", strerror(errno));
+ return p;
}
void
die(const char *errstr, ...)
{
- va_list ap;
+ va_list ap;
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- assert(0);
+ va_start(ap, errstr);
+ vfprintf(stderr, errstr, ap);
+ va_end(ap);
+ assert(0);
}
////////////////////////////////////////////////
@@ -320,49 +320,49 @@ die(const char *errstr, ...)
struct glyph*
screen_set_attr(int x, int y)
{
- static struct glyph dummy;
- if (y >= screen.row || x >= screen.col ||
- y < 0 || x < 0)
- return &dummy;
+ static struct glyph dummy;
+ if (y >= screen.row || x >= screen.col ||
+ y < 0 || x < 0)
+ return &dummy;
- return &screen.lines[y][x];
+ return &screen.lines[y][x];
}
void
screen_set_region(int x1, int y1, int x2, int y2, rune_t u)
{
- for (int y = y1; y <= y2; y++)
- for (int x = x1; x <= x2; x++)
- screen_set_char(u, x, y);
+ for (int y = y1; y <= y2; y++)
+ for (int x = x1; x <= x2; x++)
+ screen_set_char(u, x, y);
}
void
screen_resize(int col, int row)
{
- if (col < 1 || row < 1) {
- fprintf(stderr,
- "tresize: error resizing to %dx%d\n", col, row);
- return;
- }
-
- // resize to new height
- for (int i = row; i < screen.row; i++)
- free(screen.lines[i]);
-
- screen.lines = xrealloc(screen.lines, row * sizeof(*screen.lines));
-
- for (int i = screen.row; i < row; i++)
- screen.lines[i] = NULL;
-
- // resize each row to new width, zero-pad if needed
- for (int i = 0; i < row; i++) {
- screen.lines[i] = xrealloc(screen.lines[i], col * sizeof(struct glyph));
- memset(screen.lines[i], 0, col * sizeof(struct glyph));
- }
-
- // update terminal size
- screen.col = col;
- screen.row = row;
+ if (col < 1 || row < 1) {
+ fprintf(stderr,
+ "tresize: error resizing to %dx%d\n", col, row);
+ return;
+ }
+
+ // resize to new height
+ for (int i = row; i < screen.row; i++)
+ free(screen.lines[i]);
+
+ screen.lines = xrealloc(screen.lines, row * sizeof(*screen.lines));
+
+ for (int i = screen.row; i < row; i++)
+ screen.lines[i] = NULL;
+
+ // resize each row to new width, zero-pad if needed
+ for (int i = 0; i < row; i++) {
+ screen.lines[i] = xrealloc(screen.lines[i], col * sizeof(struct glyph));
+ memset(screen.lines[i], 0, col * sizeof(struct glyph));
+ }
+
+ // update terminal size
+ screen.col = col;
+ screen.row = row;
}
@@ -371,250 +371,250 @@ screen_resize(int col, int row)
void
propnotify(XEvent *e)
{
- XPropertyEvent *xpev;
- Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
-
- xpev = &e->xproperty;
- if (xpev->state == PropertyNewValue &&
- (xpev->atom == XA_PRIMARY ||
- xpev->atom == clipboard)) {
- selnotify(e);
- }
+ XPropertyEvent *xpev;
+ Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+
+ xpev = &e->xproperty;
+ if (xpev->state == PropertyNewValue &&
+ (xpev->atom == XA_PRIMARY ||
+ xpev->atom == clipboard)) {
+ selnotify(e);
+ }
}
void
selnotify(XEvent *e)
{
- unsigned long nitems, ofs, rem;
- int format;
- uint8_t *data, *last, *repl;
- Atom type, incratom, property = None;
-
- incratom = XInternAtom(xw.dpy, "INCR", 0);
-
- ofs = 0;
- if (e->type == SelectionNotify)
- property = e->xselection.property;
- else if (e->type == PropertyNotify)
- property = e->xproperty.atom;
-
- if (property == None)
- return;
-
- do {
- if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
- BUFSIZ/4, False, AnyPropertyType,
- &type, &format, &nitems, &rem,
- &data)) {
- fprintf(stderr, "Clipboard allocation failed\n");
- return;
- }
-
- if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
- /*
- * If there is some PropertyNotify with no data, then
- * this is the signal of the selection owner that all
- * data has been transferred. We won't need to receive
- * PropertyNotify events anymore.
- */
- MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
- }
-
- if (type == incratom) {
- /*
- * Activate the PropertyNotify events so we receive
- * when the selection owner does send us the next
- * chunk of data.
- */
- MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
-
- // Deleting the property is the transfer start signal.
- XDeleteProperty(xw.dpy, xw.win, (int)property);
- continue;
- }
-
- // replace all '\r' with '\n'.
- repl = data;
- last = data + nitems * format / 8;
- while ((repl = memchr(repl, '\r', last - repl))) {
- *repl++ = '\n';
- }
-
- struct file_buffer* fb = get_fb(focused_window);
- if (fb->contents) {
- if (fb->mode & FB_SELECTION_ON) {
- fb_remove_selection(fb);
- wb_move_cursor_to_selection_start(focused_window);
- fb->mode &= ~(FB_SELECTION_ON);
- }
- call_extension(fb_paste, fb, (char*)data, nitems * format / 8);
- call_extension(fb_contents_updated, fb, focused_window->cursor_offset, FB_CONTENT_BIG_CHANGE);
- }
- XFree(data);
- /* number of 32-bit chunks returned */
- ofs += nitems * format / 32;
- } while (rem > 0);
-
- /*
- * Deleting the property again tells the selection owner to send the
- * next data chunk in the property.
- */
- XDeleteProperty(xw.dpy, xw.win, (int)property);
+ unsigned long nitems, ofs, rem;
+ int format;
+ uint8_t *data, *last, *repl;
+ Atom type, incratom, property = None;
+
+ incratom = XInternAtom(xw.dpy, "INCR", 0);
+
+ ofs = 0;
+ if (e->type == SelectionNotify)
+ property = e->xselection.property;
+ else if (e->type == PropertyNotify)
+ property = e->xproperty.atom;
+
+ if (property == None)
+ return;
+
+ do {
+ if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
+ BUFSIZ/4, False, AnyPropertyType,
+ &type, &format, &nitems, &rem,
+ &data)) {
+ fprintf(stderr, "Clipboard allocation failed\n");
+ return;
+ }
+
+ if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
+ /*
+ * If there is some PropertyNotify with no data, then
+ * this is the signal of the selection owner that all
+ * data has been transferred. We won't need to receive
+ * PropertyNotify events anymore.
+ */
+ MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+ }
+
+ if (type == incratom) {
+ /*
+ * Activate the PropertyNotify events so we receive
+ * when the selection owner does send us the next
+ * chunk of data.
+ */
+ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+
+ // Deleting the property is the transfer start signal.
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
+ continue;
+ }
+
+ // replace all '\r' with '\n'.
+ repl = data;
+ last = data + nitems * format / 8;
+ while ((repl = memchr(repl, '\r', last - repl))) {
+ *repl++ = '\n';
+ }
+
+ struct file_buffer* fb = get_fb(focused_window);
+ if (fb->contents) {
+ if (fb->mode & FB_SELECTION_ON) {
+ fb_remove_selection(fb);
+ wb_move_cursor_to_selection_start(focused_window);
+ fb->mode &= ~(FB_SELECTION_ON);
+ }
+ call_extension(fb_paste, fb, (char*)data, nitems * format / 8);
+ call_extension(fb_contents_updated, fb, focused_window->cursor_offset, FB_CONTENT_BIG_CHANGE);
+ }
+ XFree(data);
+ /* number of 32-bit chunks returned */
+ ofs += nitems * format / 32;
+ } while (rem > 0);
+
+ /*
+ * Deleting the property again tells the selection owner to send the
+ * next data chunk in the property.
+ */
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
}
void
selrequest(XEvent *e)
{
- XSelectionRequestEvent *xsre = (XSelectionRequestEvent *) e;
- XSelectionEvent xev = {0};
- Atom xa_targets, string, clipboard;
- char *seltext = NULL;
-
- xev.type = SelectionNotify;
- xev.requestor = xsre->requestor;
- xev.selection = xsre->selection;
- xev.target = xsre->target;
- xev.time = xsre->time;
- if (xsre->property == None)
- xsre->property = xsre->target;
-
- // reject
- xev.property = None;
-
- xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
- if (xsre->target == xa_targets) {
- // respond with the supported type
- string = xtarget;
- XChangeProperty(xsre->display, xsre->requestor, xsre->property,
- XA_ATOM, 32, PropModeReplace,
- (uint8_t *) &string, 1);
- xev.property = xsre->property;
- } else if (xsre->target == xtarget || xsre->target == XA_STRING) {
- /*
- * xith XA_STRING non ascii characters may be incorrect in the
- * requestor. It is not our problem, use utf8.
- */
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- int sel_len;
- if (xsre->selection == XA_PRIMARY) {
- seltext = fb_get_selection(get_fb(focused_window), &sel_len);
- } else if (xsre->selection == clipboard) {
- seltext = copy_buffer;
- sel_len = copy_len;
- } else {
- fprintf(stderr,
- "Unhandled clipboard selection 0x%lx\n",
- xsre->selection);
- return;
- }
- if (seltext) {
- XChangeProperty(xsre->display, xsre->requestor,
- xsre->property, xsre->target,
- 8, PropModeReplace,
- (uint8_t *)seltext, sel_len);
- xev.property = xsre->property;
- if (seltext != copy_buffer)
- free(seltext);
- }
- }
-
- // all done, send a notification to the listener
- if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
- fprintf(stderr, "Error sending SelectionNotify event\n");
+ XSelectionRequestEvent *xsre = (XSelectionRequestEvent *) e;
+ XSelectionEvent xev = {0};
+ Atom xa_targets, string, clipboard;
+ char *seltext = NULL;
+
+ xev.type = SelectionNotify;
+ xev.requestor = xsre->requestor;
+ xev.selection = xsre->selection;
+ xev.target = xsre->target;
+ xev.time = xsre->time;
+ if (xsre->property == None)
+ xsre->property = xsre->target;
+
+ // reject
+ xev.property = None;
+
+ xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
+ if (xsre->target == xa_targets) {
+ // respond with the supported type
+ string = xtarget;
+ XChangeProperty(xsre->display, xsre->requestor, xsre->property,
+ XA_ATOM, 32, PropModeReplace,
+ (uint8_t *) &string, 1);
+ xev.property = xsre->property;
+ } else if (xsre->target == xtarget || xsre->target == XA_STRING) {
+ /*
+ * xith XA_STRING non ascii characters may be incorrect in the
+ * requestor. It is not our problem, use utf8.
+ */
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ int sel_len;
+ if (xsre->selection == XA_PRIMARY) {
+ seltext = fb_get_selection(get_fb(focused_window), &sel_len);
+ } else if (xsre->selection == clipboard) {
+ seltext = copy_buffer;
+ sel_len = copy_len;
+ } else {
+ fprintf(stderr,
+ "Unhandled clipboard selection 0x%lx\n",
+ xsre->selection);
+ return;
+ }
+ if (seltext) {
+ XChangeProperty(xsre->display, xsre->requestor,
+ xsre->property, xsre->target,
+ 8, PropModeReplace,
+ (uint8_t *)seltext, sel_len);
+ xev.property = xsre->property;
+ if (seltext != copy_buffer)
+ free(seltext);
+ }
+ }
+
+ // all done, send a notification to the listener
+ if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
+ fprintf(stderr, "Error sending SelectionNotify event\n");
}
void
cresize(int width, int height)
{
- int col, row;
+ int col, row;
- if (width > 0)
- win.w = width;
- if (height > 0)
- win.h = height;
+ if (width > 0)
+ win.w = width;
+ if (height > 0)
+ win.h = height;
- col = (win.w - 2 * border_px) / win.cw;
- row = (win.h - 2 * border_px) / win.ch;
- col = MAX(1, col);
- row = MAX(1, row);
+ col = (win.w - 2 * border_px) / win.cw;
+ row = (win.h - 2 * border_px) / win.ch;
+ col = MAX(1, col);
+ row = MAX(1, row);
- screen_resize(col, row);
- xresize(col, row);
+ screen_resize(col, row);
+ xresize(col, row);
}
void
xresize(int col, int row)
{
- win.tw = col * win.cw;
- win.th = row * win.ch;
+ win.tw = col * win.cw;
+ win.th = row * win.ch;
- XFreePixmap(xw.dpy, xw.buf);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
- XftDrawChange(xw.draw, xw.buf);
- xclear(0, 0, win.w, win.h);
+ XFreePixmap(xw.dpy, xw.buf);
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
+ DefaultDepth(xw.dpy, xw.scr));
+ XftDrawChange(xw.draw, xw.buf);
+ xclear(0, 0, win.w, win.h);
- // resize to new width
- xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
+ // resize to new width
+ xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
}
int
xloadcolor(int i, const char *name, Color *ncolor)
{
- if (!name) {
- if (!(name = colors[i]))
- return 0;
- }
+ if (!name) {
+ if (!(name = colors[i]))
+ return 0;
+ }
- return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
+ return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
}
void
xloadcols(void)
{
- int i;
- static int loaded;
-
- if (loaded) {
- Color *cp;
- for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
- XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
- } else {
- i = 0;
- while (colors[i++])
- ;
- dc.collen = i;
- dc.col = xmalloc(dc.collen * sizeof(Color));
- loaded = 1;
- }
-
- for (i = 0; i < dc.collen; i++) {
- if (!xloadcolor(i, NULL, &dc.col[i])) {
- if (colors[i])
- die("could not allocate color '%s'\n", colors[i]);
- }
- }
+ int i;
+ static int loaded;
+
+ if (loaded) {
+ Color *cp;
+ for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+ } else {
+ i = 0;
+ while (colors[i++])
+ ;
+ dc.collen = i;
+ dc.col = xmalloc(dc.collen * sizeof(Color));
+ loaded = 1;
+ }
+
+ for (i = 0; i < dc.collen; i++) {
+ if (!xloadcolor(i, NULL, &dc.col[i])) {
+ if (colors[i])
+ die("could not allocate color '%s'\n", colors[i]);
+ }
+ }
}
int
xsetcolorname(int x, const char *name)
{
- Color ncolor;
+ Color ncolor;
- if (!BETWEEN(x, 0, dc.collen))
- return 1;
+ if (!BETWEEN(x, 0, dc.collen))
+ return 1;
- if (!xloadcolor(x, name, &ncolor))
- return 1;
+ if (!xloadcolor(x, name, &ncolor))
+ return 1;
- XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
- dc.col[x] = ncolor;
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
+ dc.col[x] = ncolor;
- return 0;
+ return 0;
}
@@ -622,754 +622,754 @@ xsetcolorname(int x, const char *name)
void
xclear(int x1, int y1, int x2, int y2)
{
- XftDrawRect(xw.draw, &dc.col[default_attributes.bg],
- x1, y1, x2-x1, y2-y1);
+ XftDrawRect(xw.draw, &dc.col[default_attributes.bg],
+ x1, y1, x2-x1, y2-y1);
}
void
xhints(void)
{
- XClassHint class = {"se", "se"};
- XWMHints wm = {.flags = InputHint, .input = 1};
- XSizeHints *sizeh;
-
- sizeh = XAllocSizeHints();
-
- sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
- sizeh->height = win.h;
- sizeh->width = win.w;
- sizeh->height_inc = win.ch;
- sizeh->width_inc = win.cw;
- sizeh->base_height = 2 * border_px;
- sizeh->base_width = 2 * border_px;
- sizeh->min_height = win.ch + 2 * border_px;
- sizeh->min_width = win.cw + 2 * border_px;
- if (xw.isfixed) {
- sizeh->flags |= PMaxSize;
- sizeh->min_width = sizeh->max_width = win.w;
- sizeh->min_height = sizeh->max_height = win.h;
- }
- if (xw.gm & (XValue|YValue)) {
- sizeh->flags |= USPosition | PWinGravity;
- sizeh->x = xw.l;
- sizeh->y = xw.t;
- sizeh->win_gravity = xgeommasktogravity(xw.gm);
- }
-
- XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm,
- &class);
- XFree(sizeh);
+ XClassHint class = {"se", "se"};
+ XWMHints wm = {.flags = InputHint, .input = 1};
+ XSizeHints *sizeh;
+
+ sizeh = XAllocSizeHints();
+
+ sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
+ sizeh->height = win.h;
+ sizeh->width = win.w;
+ sizeh->height_inc = win.ch;
+ sizeh->width_inc = win.cw;
+ sizeh->base_height = 2 * border_px;
+ sizeh->base_width = 2 * border_px;
+ sizeh->min_height = win.ch + 2 * border_px;
+ sizeh->min_width = win.cw + 2 * border_px;
+ if (xw.isfixed) {
+ sizeh->flags |= PMaxSize;
+ sizeh->min_width = sizeh->max_width = win.w;
+ sizeh->min_height = sizeh->max_height = win.h;
+ }
+ if (xw.gm & (XValue|YValue)) {
+ sizeh->flags |= USPosition | PWinGravity;
+ sizeh->x = xw.l;
+ sizeh->y = xw.t;
+ sizeh->win_gravity = xgeommasktogravity(xw.gm);
+ }
+
+ XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm,
+ &class);
+ XFree(sizeh);
}
int
xgeommasktogravity(int mask)
{
- switch (mask & (XNegative|YNegative)) {
- case 0:
- return NorthWestGravity;
- case XNegative:
- return NorthEastGravity;
- case YNegative:
- return SouthWestGravity;
- }
-
- return SouthEastGravity;
+ switch (mask & (XNegative|YNegative)) {
+ case 0:
+ return NorthWestGravity;
+ case XNegative:
+ return NorthEastGravity;
+ case YNegative:
+ return SouthWestGravity;
+ }
+
+ return SouthEastGravity;
}
int
xloadfont(Font *f, FcPattern *pattern)
{
- FcPattern *configured;
- FcPattern *match;
- FcResult result;
- XGlyphInfo extents;
- int wantattr, haveattr;
-
- /*
- * Manually configure instead of calling XftMatchFont
- * so that we can use the configured pattern for
- * "missing struct glyph" lookups.
- */
- configured = FcPatternDuplicate(pattern);
- if (!configured)
- return 1;
-
- FcConfigSubstitute(NULL, configured, FcMatchPattern);
- XftDefaultSubstitute(xw.dpy, xw.scr, configured);
-
- match = FcFontMatch(NULL, configured, &result);
- if (!match) {
- FcPatternDestroy(configured);
- return 1;
- }
-
- if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
- FcPatternDestroy(configured);
- FcPatternDestroy(match);
- return 1;
- }
-
- if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) ==
- XftResultMatch)) {
- /*
- * Check if xft was unable to find a font with the appropriate
- * slant but gave us one anyway. Try to mitigate.
- */
- if ((XftPatternGetInteger(f->match->pattern, "slant", 0,
- &haveattr) != XftResultMatch) || haveattr < wantattr) {
- f->badslant = 1;
- fputs("font slant does not match\n", stderr);
- }
- }
-
- if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) ==
- XftResultMatch)) {
- if ((XftPatternGetInteger(f->match->pattern, "weight", 0,
- &haveattr) != XftResultMatch) || haveattr != wantattr) {
- f->badweight = 1;
- fputs("font weight does not match\n", stderr);
- }
- }
-
- // Printable characters in ASCII, used to estimate the advance width of single wide characters.
- const char ascii_printable[] =
- " !\"#$%&'()*+,-./0123456789:;<=>?"
- "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
- "`abcdefghijklmnopqrstuvwxyz{|}~";
-
- XftTextExtentsUtf8(xw.dpy, f->match,
- (const FcChar8 *) ascii_printable,
- strlen(ascii_printable), &extents);
-
- f->set = NULL;
- f->pattern = configured;
-
- f->ascent = f->match->ascent;
- f->descent = f->match->descent;
- f->lbearing = 0;
- f->rbearing = f->match->max_advance_width;
-
- f->height = f->ascent + f->descent;
- f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
-
- return 0;
+ FcPattern *configured;
+ FcPattern *match;
+ FcResult result;
+ XGlyphInfo extents;
+ int wantattr, haveattr;
+
+ /*
+ * Manually configure instead of calling XftMatchFont
+ * so that we can use the configured pattern for
+ * "missing struct glyph" lookups.
+ */
+ configured = FcPatternDuplicate(pattern);
+ if (!configured)
+ return 1;
+
+ FcConfigSubstitute(NULL, configured, FcMatchPattern);
+ XftDefaultSubstitute(xw.dpy, xw.scr, configured);
+
+ match = FcFontMatch(NULL, configured, &result);
+ if (!match) {
+ FcPatternDestroy(configured);
+ return 1;
+ }
+
+ if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
+ FcPatternDestroy(configured);
+ FcPatternDestroy(match);
+ return 1;
+ }
+
+ if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) ==
+ XftResultMatch)) {
+ /*
+ * Check if xft was unable to find a font with the appropriate
+ * slant but gave us one anyway. Try to mitigate.
+ */
+ if ((XftPatternGetInteger(f->match->pattern, "slant", 0,
+ &haveattr) != XftResultMatch) || haveattr < wantattr) {
+ f->badslant = 1;
+ fputs("font slant does not match\n", stderr);
+ }
+ }
+
+ if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) ==
+ XftResultMatch)) {
+ if ((XftPatternGetInteger(f->match->pattern, "weight", 0,
+ &haveattr) != XftResultMatch) || haveattr != wantattr) {
+ f->badweight = 1;
+ fputs("font weight does not match\n", stderr);
+ }
+ }
+
+ // Printable characters in ASCII, used to estimate the advance width of single wide characters.
+ const char ascii_printable[] =
+ " !\"#$%&'()*+,-./0123456789:;<=>?"
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+ "`abcdefghijklmnopqrstuvwxyz{|}~";
+
+ XftTextExtentsUtf8(xw.dpy, f->match,
+ (const FcChar8 *) ascii_printable,
+ strlen(ascii_printable), &extents);
+
+ f->set = NULL;
+ f->pattern = configured;
+
+ f->ascent = f->match->ascent;
+ f->descent = f->match->descent;
+ f->lbearing = 0;
+ f->rbearing = f->match->max_advance_width;
+
+ f->height = f->ascent + f->descent;
+ f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
+
+ return 0;
}
void
xloadfonts(const char *fontstr, double fontsize)
{
- FcPattern *pattern;
- double fontval;
-
- if (fontstr[0] == '-')
- pattern = XftXlfdParse(fontstr, False, False);
- else
- pattern = FcNameParse((const FcChar8 *)fontstr);
-
- if (!pattern)
- die("can't open font %s\n", fontstr);
-
- if (fontsize > 1) {
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternDel(pattern, FC_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
- usedfontsize = fontsize;
- } else {
- if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
- FcResultMatch) {
- usedfontsize = fontval;
- } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
- FcResultMatch) {
- usedfontsize = -1;
- } else {
- /*
- * Default font size is 12, if none given. This is to
- * have a known usedfontsize value.
- */
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12);
- usedfontsize = 12;
- }
- defaultfontsize = usedfontsize;
- }
-
- if (xloadfont(&dc.font, pattern))
- die("can't open font %s\n", fontstr);
-
- if (usedfontsize < 0) {
- FcPatternGetDouble(dc.font.match->pattern,
- FC_PIXEL_SIZE, 0, &fontval);
- usedfontsize = fontval;
- if (fontsize == 0)
- defaultfontsize = fontval;
- }
-
- /* Setting character width and height. */
- win.cw = ceilf(dc.font.width * cw_scale);
- win.ch = ceilf(dc.font.height * ch_scale);
-
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
- if (xloadfont(&dc.ifont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDel(pattern, FC_WEIGHT);
- FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
- if (xloadfont(&dc.ibfont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
- if (xloadfont(&dc.bfont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDestroy(pattern);
+ FcPattern *pattern;
+ double fontval;
+
+ if (fontstr[0] == '-')
+ pattern = XftXlfdParse(fontstr, False, False);
+ else
+ pattern = FcNameParse((const FcChar8 *)fontstr);
+
+ if (!pattern)
+ die("can't open font %s\n", fontstr);
+
+ if (fontsize > 1) {
+ FcPatternDel(pattern, FC_PIXEL_SIZE);
+ FcPatternDel(pattern, FC_SIZE);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
+ usedfontsize = fontsize;
+ } else {
+ if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
+ FcResultMatch) {
+ usedfontsize = fontval;
+ } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
+ FcResultMatch) {
+ usedfontsize = -1;
+ } else {
+ /*
+ * Default font size is 12, if none given. This is to
+ * have a known usedfontsize value.
+ */
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12);
+ usedfontsize = 12;
+ }
+ defaultfontsize = usedfontsize;
+ }
+
+ if (xloadfont(&dc.font, pattern))
+ die("can't open font %s\n", fontstr);
+
+ if (usedfontsize < 0) {
+ FcPatternGetDouble(dc.font.match->pattern,
+ FC_PIXEL_SIZE, 0, &fontval);
+ usedfontsize = fontval;
+ if (fontsize == 0)
+ defaultfontsize = fontval;
+ }
+
+ /* Setting character width and height. */
+ win.cw = ceilf(dc.font.width * cw_scale);
+ win.ch = ceilf(dc.font.height * ch_scale);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ if (xloadfont(&dc.ifont, pattern))
+ die("can't open font %s\n", fontstr);
+
+ FcPatternDel(pattern, FC_WEIGHT);
+ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+ if (xloadfont(&dc.ibfont, pattern))
+ die("can't open font %s\n", fontstr);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
+ if (xloadfont(&dc.bfont, pattern))
+ die("can't open font %s\n", fontstr);
+
+ FcPatternDestroy(pattern);
}
int
ximopen(Display *dpy)
{
- XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
- XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
-
- xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
- if (xw.ime.xim == NULL)
- return 0;
-
- if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
- fprintf(stderr, "XSetIMValues: "
- "Could not set XNDestroyCallback.\n");
-
- xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
- NULL);
-
- if (xw.ime.xic == NULL) {
- xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
- XIMPreeditNothing | XIMStatusNothing,
- XNClientWindow, xw.win,
- XNDestroyCallback, &icdestroy,
- NULL);
- }
- if (xw.ime.xic == NULL)
- fprintf(stderr, "XCreateIC: Could not create input context.\n");
-
- return 1;
+ XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
+ XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
+
+ xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
+ if (xw.ime.xim == NULL)
+ return 0;
+
+ if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
+ fprintf(stderr, "XSetIMValues: "
+ "Could not set XNDestroyCallback.\n");
+
+ xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
+ NULL);
+
+ if (xw.ime.xic == NULL) {
+ xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
+ XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, xw.win,
+ XNDestroyCallback, &icdestroy,
+ NULL);
+ }
+ if (xw.ime.xic == NULL)
+ fprintf(stderr, "XCreateIC: Could not create input context.\n");
+
+ return 1;
}
void
ximinstantiate(Display *dpy, XPointer client, XPointer call)
{
- if (ximopen(dpy))
- XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
+ if (ximopen(dpy))
+ XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
+ ximinstantiate, NULL);
}
void
ximdestroy(XIM xim, XPointer client, XPointer call)
{
- xw.ime.xim = NULL;
- XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
- XFree(xw.ime.spotlist);
+ xw.ime.xim = NULL;
+ XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
+ ximinstantiate, NULL);
+ XFree(xw.ime.spotlist);
}
int
xicdestroy(XIC xim, XPointer client, XPointer call)
{
- xw.ime.xic = NULL;
- return 1;
+ xw.ime.xic = NULL;
+ return 1;
}
void
xinit(int cols, int rows)
{
- XGCValues gcvalues;
- Cursor cursor;
- Window parent;
- pid_t thispid = getpid();
- XColor xmousefg, xmousebg;
-
- if (!(xw.dpy = XOpenDisplay(NULL)))
- die("can't open display\n");
- xw.scr = XDefaultScreen(xw.dpy);
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
-
- /* font */
- if (!FcInit())
- die("could not init fontconfig.\n");
-
- xloadfonts(fontconfig, 0);
-
- /* colors */
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
- xloadcols();
-
- /* adjust fixed window geometry */
- win.w = 2 * border_px + cols * win.cw;
- win.h = 2 * border_px + rows * win.ch;
- if (xw.gm & XNegative)
- xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
- if (xw.gm & YNegative)
- xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2;
-
- /* Events */
- xw.attrs.background_pixel = dc.col[default_attributes.bg].pixel;
- xw.attrs.border_pixel = dc.col[default_attributes.bg].pixel;
- xw.attrs.bit_gravity = NorthWestGravity;
- xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
- | ExposureMask | VisibilityChangeMask | StructureNotifyMask
- | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
- xw.attrs.colormap = xw.cmap;
-
- parent = XRootWindow(xw.dpy, xw.scr);
- xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
- xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
- | CWEventMask | CWColormap, &xw.attrs);
-
- memset(&gcvalues, 0, sizeof(gcvalues));
- gcvalues.graphics_exposures = False;
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
- &gcvalues);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, dc.gc, dc.col[default_attributes.bg].pixel);
- XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
-
- /* font spec buffer */
- xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
-
- /* Xft rendering context */
- xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
-
- /* input methods */
- if (!ximopen(xw.dpy)) {
- XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
- }
-
- /* white cursor, black outline */
- cursor = XCreateFontCursor(xw.dpy, XC_xterm);
- XDefineCursor(xw.dpy, xw.win, cursor);
-
- if (XParseColor(xw.dpy, xw.cmap, colors[cursor_fg], &xmousefg) == 0) {
- xmousefg.red = 0xffff;
- xmousefg.green = 0xffff;
- xmousefg.blue = 0xffff;
- }
-
- if (XParseColor(xw.dpy, xw.cmap, colors[cursor_bg], &xmousebg) == 0) {
- xmousebg.red = 0x0000;
- xmousebg.green = 0x0000;
- xmousebg.blue = 0x0000;
- }
-
- XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
-
- xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
- xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
- xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
- xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
- XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
-
- xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
- XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
- PropModeReplace, (uint8_t *)&thispid, 1);
-
- win.mode = MODE_NUMLOCK;
- xsettitle(NULL);
- xhints();
- XMapWindow(xw.dpy, xw.win);
- XSync(xw.dpy, False);
-
- xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
- if (xtarget == None)
- xtarget = XA_STRING;
+ XGCValues gcvalues;
+ Cursor cursor;
+ Window parent;
+ pid_t thispid = getpid();
+ XColor xmousefg, xmousebg;
+
+ if (!(xw.dpy = XOpenDisplay(NULL)))
+ die("can't open display\n");
+ xw.scr = XDefaultScreen(xw.dpy);
+ xw.vis = XDefaultVisual(xw.dpy, xw.scr);
+
+ /* font */
+ if (!FcInit())
+ die("could not init fontconfig.\n");
+
+ xloadfonts(fontconfig, 0);
+
+ /* colors */
+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
+ xloadcols();
+
+ /* adjust fixed window geometry */
+ win.w = 2 * border_px + cols * win.cw;
+ win.h = 2 * border_px + rows * win.ch;
+ if (xw.gm & XNegative)
+ xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
+ if (xw.gm & YNegative)
+ xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2;
+
+ /* Events */
+ xw.attrs.background_pixel = dc.col[default_attributes.bg].pixel;
+ xw.attrs.border_pixel = dc.col[default_attributes.bg].pixel;
+ xw.attrs.bit_gravity = NorthWestGravity;
+ xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
+ | ExposureMask | VisibilityChangeMask | StructureNotifyMask
+ | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
+ xw.attrs.colormap = xw.cmap;
+
+ parent = XRootWindow(xw.dpy, xw.scr);
+ xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
+ win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
+ xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
+ | CWEventMask | CWColormap, &xw.attrs);
+
+ memset(&gcvalues, 0, sizeof(gcvalues));
+ gcvalues.graphics_exposures = False;
+ dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
+ &gcvalues);
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
+ DefaultDepth(xw.dpy, xw.scr));
+ XSetForeground(xw.dpy, dc.gc, dc.col[default_attributes.bg].pixel);
+ XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
+
+ /* font spec buffer */
+ xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
+
+ /* Xft rendering context */
+ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
+
+ /* input methods */
+ if (!ximopen(xw.dpy)) {
+ XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
+ ximinstantiate, NULL);
+ }
+
+ /* white cursor, black outline */
+ cursor = XCreateFontCursor(xw.dpy, XC_xterm);
+ XDefineCursor(xw.dpy, xw.win, cursor);
+
+ if (XParseColor(xw.dpy, xw.cmap, colors[cursor_fg], &xmousefg) == 0) {
+ xmousefg.red = 0xffff;
+ xmousefg.green = 0xffff;
+ xmousefg.blue = 0xffff;
+ }
+
+ if (XParseColor(xw.dpy, xw.cmap, colors[cursor_bg], &xmousebg) == 0) {
+ xmousebg.red = 0x0000;
+ xmousebg.green = 0x0000;
+ xmousebg.blue = 0x0000;
+ }
+
+ XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
+
+ xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
+ xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
+ xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
+ xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
+ XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
+
+ xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
+ XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
+ PropModeReplace, (uint8_t *)&thispid, 1);
+
+ win.mode = MODE_NUMLOCK;
+ xsettitle(NULL);
+ xhints();
+ XMapWindow(xw.dpy, xw.win);
+ XSync(xw.dpy, False);
+
+ xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
+ if (xtarget == None)
+ xtarget = XA_STRING;
}
int
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const struct glyph *glyphs, int len, int x, int y)
{
- float winx = border_px + x * win.cw, winy = border_px + y * win.ch, xp, yp;
- unsigned short mode, prevmode = USHRT_MAX;
- Font *font = &dc.font;
- int frcflags = FRC_NORMAL;
- float runewidth = win.cw;
- rune_t rune;
- FT_UInt glyphidx;
- FcResult fcres;
- FcPattern *fcpattern, *fontpattern;
- FcFontSet *fcsets[] = { NULL };
- FcCharSet *fccharset;
- int i, f, numspecs = 0;
-
- for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
- /* Fetch rune and mode for current struct glyph. */
- rune = glyphs[i].u;
- mode = glyphs[i].mode;
-
- /* Skip dummy wide-character spacing. */
- if (mode & ATTR_WDUMMY)
- continue;
-
- /* Determine font for struct glyph if different from previous struct glyph. */
- if (prevmode != mode) {
- prevmode = mode;
- font = &dc.font;
- frcflags = FRC_NORMAL;
- runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
- if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
- font = &dc.ibfont;
- frcflags = FRC_ITALICBOLD;
- } else if (mode & ATTR_ITALIC) {
- font = &dc.ifont;
- frcflags = FRC_ITALIC;
- } else if (mode & ATTR_BOLD) {
- font = &dc.bfont;
- frcflags = FRC_BOLD;
- }
- yp = winy + font->ascent;
- }
-
- /* Lookup character index with default font. */
- glyphidx = XftCharIndex(xw.dpy, font->match, rune);
- if (glyphidx) {
- specs[numspecs].font = font->match;
- specs[numspecs].glyph = glyphidx;
- specs[numspecs].x = (short)xp;
- specs[numspecs].y = (short)yp;
- xp += runewidth;
- numspecs++;
- continue;
- }
-
- /* Fallback on font cache, search the font cache for match. */
- for (f = 0; f < frclen; f++) {
- glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
- /* Everything correct. */
- if (glyphidx && frc[f].flags == frcflags)
- break;
- /* We got a default font for a not found struct glyph. */
- if (!glyphidx && frc[f].flags == frcflags
- && frc[f].unicodep == rune) {
- break;
- }
- }
-
- /* Nothing was found. Use fontconfig to find matching font. */
- if (f >= frclen) {
- if (!font->set)
- font->set = FcFontSort(0, font->pattern,
- 1, 0, &fcres);
- fcsets[0] = font->set;
-
- /*
- * Nothing was found in the cache. Now use
- * some dozen of Fontconfig calls to get the
- * font for one single character.
- *
- * Xft and fontconfig are design failures.
- */
- fcpattern = FcPatternDuplicate(font->pattern);
- fccharset = FcCharSetCreate();
-
- FcCharSetAddChar(fccharset, rune);
- FcPatternAddCharSet(fcpattern, FC_CHARSET,
- fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
-
- FcConfigSubstitute(0, fcpattern,
- FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
-
- fontpattern = FcFontSetMatch(0, fcsets, 1,
- fcpattern, &fcres);
-
- /* Allocate memory for the new cache entry. */
- if (frclen >= frccap) {
- frccap += 16;
- frc = xrealloc(frc, frccap * sizeof(Fontcache));
- }
-
- frc[frclen].font = XftFontOpenPattern(xw.dpy,
- fontpattern);
- if (!frc[frclen].font)
- die("XftFontOpenPattern failed seeking fallback font: %s\n",
- strerror(errno));
- frc[frclen].flags = frcflags;
- frc[frclen].unicodep = rune;
-
- glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
-
- f = frclen;
- frclen++;
-
- FcPatternDestroy(fcpattern);
- FcCharSetDestroy(fccharset);
- }
-
- specs[numspecs].font = frc[f].font;
- specs[numspecs].glyph = glyphidx;
- specs[numspecs].x = (short)xp;
- specs[numspecs].y = (short)yp;
- xp += runewidth;
- numspecs++;
- }
-
- return numspecs;
+ float winx = border_px + x * win.cw, winy = border_px + y * win.ch, xp, yp;
+ unsigned short mode, prevmode = USHRT_MAX;
+ Font *font = &dc.font;
+ int frcflags = FRC_NORMAL;
+ float runewidth = win.cw;
+ rune_t rune;
+ FT_UInt glyphidx;
+ FcResult fcres;
+ FcPattern *fcpattern, *fontpattern;
+ FcFontSet *fcsets[] = { NULL };
+ FcCharSet *fccharset;
+ int i, f, numspecs = 0;
+
+ for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
+ /* Fetch rune and mode for current struct glyph. */
+ rune = glyphs[i].u;
+ mode = glyphs[i].mode;
+
+ /* Skip dummy wide-character spacing. */
+ if (mode & ATTR_WDUMMY)
+ continue;
+
+ /* Determine font for struct glyph if different from previous struct glyph. */
+ if (prevmode != mode) {
+ prevmode = mode;
+ font = &dc.font;
+ frcflags = FRC_NORMAL;
+ runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
+ if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
+ font = &dc.ibfont;
+ frcflags = FRC_ITALICBOLD;
+ } else if (mode & ATTR_ITALIC) {
+ font = &dc.ifont;
+ frcflags = FRC_ITALIC;
+ } else if (mode & ATTR_BOLD) {
+ font = &dc.bfont;
+ frcflags = FRC_BOLD;
+ }
+ yp = winy + font->ascent;
+ }
+
+ /* Lookup character index with default font. */
+ glyphidx = XftCharIndex(xw.dpy, font->match, rune);
+ if (glyphidx) {
+ specs[numspecs].font = font->match;
+ specs[numspecs].glyph = glyphidx;
+ specs[numspecs].x = (short)xp;
+ specs[numspecs].y = (short)yp;
+ xp += runewidth;
+ numspecs++;
+ continue;
+ }
+
+ /* Fallback on font cache, search the font cache for match. */
+ for (f = 0; f < frclen; f++) {
+ glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
+ /* Everything correct. */
+ if (glyphidx && frc[f].flags == frcflags)
+ break;
+ /* We got a default font for a not found struct glyph. */
+ if (!glyphidx && frc[f].flags == frcflags
+ && frc[f].unicodep == rune) {
+ break;
+ }
+ }
+
+ /* Nothing was found. Use fontconfig to find matching font. */
+ if (f >= frclen) {
+ if (!font->set)
+ font->set = FcFontSort(0, font->pattern,
+ 1, 0, &fcres);
+ fcsets[0] = font->set;
+
+ /*
+ * Nothing was found in the cache. Now use
+ * some dozen of Fontconfig calls to get the
+ * font for one single character.
+ *
+ * Xft and fontconfig are design failures.
+ */
+ fcpattern = FcPatternDuplicate(font->pattern);
+ fccharset = FcCharSetCreate();
+
+ FcCharSetAddChar(fccharset, rune);
+ FcPatternAddCharSet(fcpattern, FC_CHARSET,
+ fccharset);
+ FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
+
+ FcConfigSubstitute(0, fcpattern,
+ FcMatchPattern);
+ FcDefaultSubstitute(fcpattern);
+
+ fontpattern = FcFontSetMatch(0, fcsets, 1,
+ fcpattern, &fcres);
+
+ /* Allocate memory for the new cache entry. */
+ if (frclen >= frccap) {
+ frccap += 16;
+ frc = xrealloc(frc, frccap * sizeof(Fontcache));
+ }
+
+ frc[frclen].font = XftFontOpenPattern(xw.dpy,
+ fontpattern);
+ if (!frc[frclen].font)
+ die("XftFontOpenPattern failed seeking fallback font: %s\n",
+ strerror(errno));
+ frc[frclen].flags = frcflags;
+ frc[frclen].unicodep = rune;
+
+ glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
+
+ f = frclen;
+ frclen++;
+
+ FcPatternDestroy(fcpattern);
+ FcCharSetDestroy(fccharset);
+ }
+
+ specs[numspecs].font = frc[f].font;
+ specs[numspecs].glyph = glyphidx;
+ specs[numspecs].x = (short)xp;
+ specs[numspecs].y = (short)yp;
+ xp += runewidth;
+ numspecs++;
+ }
+
+ return numspecs;
}
void
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, struct glyph base, int len, int x, int y)
{
- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
- int winx = border_px + x * win.cw, winy = border_px + y * win.ch,
- width = charlen * win.cw;
- Color *fg, *bg, *temp, revfg, truefg, truebg;
- XRenderColor colfg, colbg;
- XRectangle r;
-
- /* Fallback on color display for attributes not supported by the font */
- if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
- if (dc.ibfont.badslant || dc.ibfont.badweight)
- base.fg = default_attributes.fg;
- } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) ||
- (base.mode & ATTR_BOLD && dc.bfont.badweight)) {
- base.fg = default_attributes.fg;
- }
-
- if (IS_TRUECOL(base.fg)) {
- colfg.alpha = 0xffff;
- colfg.red = TRUERED(base.fg);
- colfg.green = TRUEGREEN(base.fg);
- colfg.blue = TRUEBLUE(base.fg);
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg);
- fg = &truefg;
- } else {
- fg = &dc.col[base.fg];
- }
-
- if (IS_TRUECOL(base.bg)) {
- colbg.alpha = 0xffff;
- colbg.green = TRUEGREEN(base.bg);
- colbg.red = TRUERED(base.bg);
- colbg.blue = TRUEBLUE(base.bg);
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg);
- bg = &truebg;
- } else {
- bg = &dc.col[base.bg];
- }
-
- /* Change basic system colors [0-7] to bright system colors [8-15] */
- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7))
- fg = &dc.col[base.fg + 8];
-
- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) {
- colfg.red = fg->color.red / 2;
- colfg.green = fg->color.green / 2;
- colfg.blue = fg->color.blue / 2;
- colfg.alpha = fg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
- fg = &revfg;
- }
-
- if (base.mode & ATTR_REVERSE) {
- temp = fg;
- fg = bg;
- bg = temp;
- }
-
- if (base.mode & ATTR_INVISIBLE)
- fg = bg;
-
- /* Intelligent cleaning up of the borders. */
- if (x == 0) {
- xclear(0, (y == 0)? 0 : winy, border_px,
- winy + win.ch +
- ((winy + win.ch >= border_px + win.th)? win.h : 0));
- }
- if (winx + width >= border_px + win.tw) {
- xclear(winx + width, (y == 0)? 0 : winy, win.w,
- ((winy + win.ch >= border_px + win.th)? win.h : (winy + win.ch)));
- }
- if (y == 0)
- xclear(winx, 0, winx + width, border_px);
- if (winy + win.ch >= border_px + win.th)
- xclear(winx, winy + win.ch, winx + width, win.h);
-
- /* Clean up the region we want to draw to. */
- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
-
- /* Set the clip region because Xft is sometimes dirty. */
- r.x = 0;
- r.y = 0;
- r.height = win.ch;
- r.width = width;
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
-
- /* Render the glyphs. */
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
-
- /* Render underline and strikethrough. */
- if (base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
- width, 1);
- }
-
- if (base.mode & ATTR_STRUCK) {
- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
- width, 1);
- }
-
- /* Reset clip to none. */
- XftDrawSetClip(xw.draw, 0);
+ int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
+ int winx = border_px + x * win.cw, winy = border_px + y * win.ch,
+ width = charlen * win.cw;
+ Color *fg, *bg, *temp, revfg, truefg, truebg;
+ XRenderColor colfg, colbg;
+ XRectangle r;
+
+ /* Fallback on color display for attributes not supported by the font */
+ if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
+ if (dc.ibfont.badslant || dc.ibfont.badweight)
+ base.fg = default_attributes.fg;
+ } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) ||
+ (base.mode & ATTR_BOLD && dc.bfont.badweight)) {
+ base.fg = default_attributes.fg;
+ }
+
+ if (IS_TRUECOL(base.fg)) {
+ colfg.alpha = 0xffff;
+ colfg.red = TRUERED(base.fg);
+ colfg.green = TRUEGREEN(base.fg);
+ colfg.blue = TRUEBLUE(base.fg);
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg);
+ fg = &truefg;
+ } else {
+ fg = &dc.col[base.fg];
+ }
+
+ if (IS_TRUECOL(base.bg)) {
+ colbg.alpha = 0xffff;
+ colbg.green = TRUEGREEN(base.bg);
+ colbg.red = TRUERED(base.bg);
+ colbg.blue = TRUEBLUE(base.bg);
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg);
+ bg = &truebg;
+ } else {
+ bg = &dc.col[base.bg];
+ }
+
+ /* Change basic system colors [0-7] to bright system colors [8-15] */
+ if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7))
+ fg = &dc.col[base.fg + 8];
+
+ if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) {
+ colfg.red = fg->color.red / 2;
+ colfg.green = fg->color.green / 2;
+ colfg.blue = fg->color.blue / 2;
+ colfg.alpha = fg->color.alpha;
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
+ fg = &revfg;
+ }
+
+ if (base.mode & ATTR_REVERSE) {
+ temp = fg;
+ fg = bg;
+ bg = temp;
+ }
+
+ if (base.mode & ATTR_INVISIBLE)
+ fg = bg;
+
+ /* Intelligent cleaning up of the borders. */
+ if (x == 0) {
+ xclear(0, (y == 0)? 0 : winy, border_px,
+ winy + win.ch +
+ ((winy + win.ch >= border_px + win.th)? win.h : 0));
+ }
+ if (winx + width >= border_px + win.tw) {
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
+ ((winy + win.ch >= border_px + win.th)? win.h : (winy + win.ch)));
+ }
+ if (y == 0)
+ xclear(winx, 0, winx + width, border_px);
+ if (winy + win.ch >= border_px + win.th)
+ xclear(winx, winy + win.ch, winx + width, win.h);
+
+ /* Clean up the region we want to draw to. */
+ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
+
+ /* Set the clip region because Xft is sometimes dirty. */
+ r.x = 0;
+ r.y = 0;
+ r.height = win.ch;
+ r.width = width;
+ XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
+
+ /* Render the glyphs. */
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+
+ /* Render underline and strikethrough. */
+ if (base.mode & ATTR_UNDERLINE) {
+ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
+ width, 1);
+ }
+
+ if (base.mode & ATTR_STRUCK) {
+ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
+ width, 1);
+ }
+
+ /* Reset clip to none. */
+ XftDrawSetClip(xw.draw, 0);
}
void
xdrawglyph(struct glyph g, int x, int y)
{
- int numspecs;
- XftGlyphFontSpec spec;
+ int numspecs;
+ XftGlyphFontSpec spec;
- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
- xdrawglyphfontspecs(&spec, g, numspecs, x, y);
+ numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y);
}
void
xdrawcursor(int cx, int cy, int focused)
{
- LIMIT(cx, 0, screen.col-1);
- LIMIT(cy, 0, screen.row-1);
- struct glyph g = screen.lines[cy][cx];
- if (IS_SET(MODE_HIDE)) return;
-
- g.mode &= ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
- g.fg = cursor_bg;
- g.bg = cursor_fg;
- Color drawcol = dc.col[g.bg];
-
- /* draw the new one */
- if (IS_SET(MODE_FOCUSED) && !(get_fb(focused_window)->mode & FB_SELECTION_ON) && focused) {
- switch (cursor_shape) {
- case 0: // Blinking Block
- case 1: // Blinking Block (Default)
- case 2: // Steady Block
- xdrawglyph(g, cx, cy);
- break;
- case 3: // Blinking Underline
- case 4: // Steady Underline
- XftDrawRect(xw.draw, &drawcol,
- border_px + cx * win.cw,
- border_px + (cy + 1) * win.ch - \
- cursor_thickness,
- win.cw, cursor_thickness);
- break;
- case 5: // Blinking bar
- case 6: // Steady bar
- XftDrawRect(xw.draw, &drawcol,
- border_px + cx * win.cw,
- border_px + cy * win.ch,
- cursor_thickness, win.ch);
- break;
- }
- } else {
- XftDrawRect(xw.draw, &drawcol,
- border_px + cx * win.cw,
- border_px + cy * win.ch,
- win.cw - 1, 1);
- XftDrawRect(xw.draw, &drawcol,
- border_px + cx * win.cw,
- border_px + cy * win.ch,
- 1, win.ch - 1);
- XftDrawRect(xw.draw, &drawcol,
- border_px + (cx + 1) * win.cw - 1,
- border_px + cy * win.ch,
- 1, win.ch - 1);
- XftDrawRect(xw.draw, &drawcol,
- border_px + cx * win.cw,
- border_px + (cy + 1) * win.ch - 1,
- win.cw, 1);
- }
+ LIMIT(cx, 0, screen.col-1);
+ LIMIT(cy, 0, screen.row-1);
+ struct glyph g = screen.lines[cy][cx];
+ if (IS_SET(MODE_HIDE)) return;
+
+ g.mode &= ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
+ g.fg = cursor_bg;
+ g.bg = cursor_fg;
+ Color drawcol = dc.col[g.bg];
+
+ /* draw the new one */
+ if (IS_SET(MODE_FOCUSED) && !(get_fb(focused_window)->mode & FB_SELECTION_ON) && focused) {
+ switch (cursor_shape) {
+ case 0: // Blinking Block
+ case 1: // Blinking Block (Default)
+ case 2: // Steady Block
+ xdrawglyph(g, cx, cy);
+ break;
+ case 3: // Blinking Underline
+ case 4: // Steady Underline
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + cx * win.cw,
+ border_px + (cy + 1) * win.ch - \
+ cursor_thickness,
+ win.cw, cursor_thickness);
+ break;
+ case 5: // Blinking bar
+ case 6: // Steady bar
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + cx * win.cw,
+ border_px + cy * win.ch,
+ cursor_thickness, win.ch);
+ break;
+ }
+ } else {
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + cx * win.cw,
+ border_px + cy * win.ch,
+ win.cw - 1, 1);
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + cx * win.cw,
+ border_px + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + (cx + 1) * win.cw - 1,
+ border_px + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+ border_px + cx * win.cw,
+ border_px + (cy + 1) * win.ch - 1,
+ win.cw, 1);
+ }
}
void
xseticontitle(char *p)
{
- XTextProperty prop;
- DEFAULT(p, "se");
-
- if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop) != Success)
- return;
- XSetWMIconName(xw.dpy, xw.win, &prop);
- XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname);
- XFree(prop.value);
+ XTextProperty prop;
+ DEFAULT(p, "se");
+
+ if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
+ &prop) != Success)
+ return;
+ XSetWMIconName(xw.dpy, xw.win, &prop);
+ XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname);
+ XFree(prop.value);
}
void
xsettitle(char *p)
{
- XTextProperty prop;
- DEFAULT(p, "se");
-
- if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop) != Success)
- return;
- XSetWMName(xw.dpy, xw.win, &prop);
- XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
- XFree(prop.value);
+ XTextProperty prop;
+ DEFAULT(p, "se");
+
+ if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
+ &prop) != Success)
+ return;
+ XSetWMName(xw.dpy, xw.win, &prop);
+ XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
+ XFree(prop.value);
}
void
xdrawline(int x1, int y1, int x2)
{
- LIMIT(y1, 0, screen.row);
- LIMIT(x2, 0, screen.col);
- LIMIT(x1, 0, x2);
- struct glyph* line = screen.lines[y1];
- int i, x, ox, numspecs;
- struct glyph base, new;
- XftGlyphFontSpec *specs = xw.specbuf;
-
- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
- i = ox = 0;
- for (x = x1; x < x2 && i < numspecs; x++) {
- new = line[x];
- if (new.mode & ATTR_WDUMMY)
- continue;
- if (i > 0 && ATTRCMP(base, new)) {
- xdrawglyphfontspecs(specs, base, i, ox, y1);
- specs += i;
- numspecs -= i;
- i = 0;
- }
- if (i == 0) {
- ox = x;
- base = new;
- }
- i++;
- }
- if (i > 0)
- xdrawglyphfontspecs(specs, base, i, ox, y1);
+ LIMIT(y1, 0, screen.row);
+ LIMIT(x2, 0, screen.col);
+ LIMIT(x1, 0, x2);
+ struct glyph* line = screen.lines[y1];
+ int i, x, ox, numspecs;
+ struct glyph base, new;
+ XftGlyphFontSpec *specs = xw.specbuf;
+
+ numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
+ i = ox = 0;
+ for (x = x1; x < x2 && i < numspecs; x++) {
+ new = line[x];
+ if (new.mode & ATTR_WDUMMY)
+ continue;
+ if (i > 0 && ATTRCMP(base, new)) {
+ xdrawglyphfontspecs(specs, base, i, ox, y1);
+ specs += i;
+ numspecs -= i;
+ i = 0;
+ }
+ if (i == 0) {
+ ox = x;
+ base = new;
+ }
+ i++;
+ }
+ if (i > 0)
+ xdrawglyphfontspecs(specs, base, i, ox, y1);
}
void xsetenv(void) {
- char buf[sizeof(long) * 8 + 1];
- snprintf(buf, sizeof(buf), "%lu", xw.win);
- setenv("WINDOWID", buf, 1);
+ char buf[sizeof(long) * 8 + 1];
+ snprintf(buf, sizeof(buf), "%lu", xw.win);
+ setenv("WINDOWID", buf, 1);
}
int xstartdraw(void) {return IS_SET(MODE_VISIBLE);}
void xfinishdraw(void) {
- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, win.h, 0, 0);
- XSetForeground(xw.dpy, dc.gc, dc.col[default_attributes.bg].pixel);
+ XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, win.h, 0, 0);
+ XSetForeground(xw.dpy, dc.gc, dc.col[default_attributes.bg].pixel);
}
void expose(XEvent *ev) {} // do nothing
void visibility(XEvent *ev) {
- XVisibilityEvent *e = &ev->xvisibility;
- MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
+ XVisibilityEvent *e = &ev->xvisibility;
+ MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
}
void unmap(XEvent *ev) {win.mode &= ~MODE_VISIBLE;}
@@ -1377,333 +1377,333 @@ void unmap(XEvent *ev) {win.mode &= ~MODE_VISIBLE;}
void
xsetpointermotion(int set)
{
- MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
+ MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
}
void xseturgency(int add) {
- XWMHints *h = XGetWMHints(xw.dpy, xw.win);
- MODBIT(h->flags, add, XUrgencyHint);
- XSetWMHints(xw.dpy, xw.win, h);
- XFree(h);
+ XWMHints *h = XGetWMHints(xw.dpy, xw.win);
+ MODBIT(h->flags, add, XUrgencyHint);
+ XSetWMHints(xw.dpy, xw.win, h);
+ XFree(h);
}
void
xunloadfonts(void)
{
- /* Free the loaded fonts in the font cache. */
- while (frclen > 0)
- XftFontClose(xw.dpy, frc[--frclen].font);
-
- xunloadfont(&dc.font);
- xunloadfont(&dc.bfont);
- xunloadfont(&dc.ifont);
- xunloadfont(&dc.ibfont);
+ /* Free the loaded fonts in the font cache. */
+ while (frclen > 0)
+ XftFontClose(xw.dpy, frc[--frclen].font);
+
+ xunloadfont(&dc.font);
+ xunloadfont(&dc.bfont);
+ xunloadfont(&dc.ifont);
+ xunloadfont(&dc.ibfont);
}
void
xunloadfont(Font *f)
{
- soft_assert(f, return;);
- soft_assert(f->match, return;);
- soft_assert(f->pattern, return;);
- XftFontClose(xw.dpy, f->match);
- FcPatternDestroy(f->pattern);
- if (f->set)
- FcFontSetDestroy(f->set);
+ soft_assert(f, return;);
+ soft_assert(f->match, return;);
+ soft_assert(f->pattern, return;);
+ XftFontClose(xw.dpy, f->match);
+ FcPatternDestroy(f->pattern);
+ if (f->set)
+ FcFontSetDestroy(f->set);
}
void
focus(XEvent *ev)
{
- XFocusChangeEvent *e = &ev->xfocus;
-
- if (e->mode == NotifyGrab)
- return;
-
- if (ev->type == FocusIn) {
- if (xw.ime.xic)
- XSetICFocus(xw.ime.xic);
- win.mode |= MODE_FOCUSED;
- xseturgency(0);
- } else {
- if (xw.ime.xic)
- XUnsetICFocus(xw.ime.xic);
- win.mode &= ~MODE_FOCUSED;
- }
+ XFocusChangeEvent *e = &ev->xfocus;
+
+ if (e->mode == NotifyGrab)
+ return;
+
+ if (ev->type == FocusIn) {
+ if (xw.ime.xic)
+ XSetICFocus(xw.ime.xic);
+ win.mode |= MODE_FOCUSED;
+ xseturgency(0);
+ } else {
+ if (xw.ime.xic)
+ XUnsetICFocus(xw.ime.xic);
+ win.mode &= ~MODE_FOCUSED;
+ }
}
int
match(unsigned int mask, unsigned int state) {
- const unsigned int ignoremod = Mod2Mask|XK_SWITCH_MOD;
- return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
+ const unsigned int ignoremod = Mod2Mask|XK_SWITCH_MOD;
+ return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
}
static void
search_term_string_insert(const char* buf, int buflen)
{
- static int first = 0;
-
- struct file_buffer* fb = get_fb(focused_window);
- if (!buf) {
- first = 1;
- return;
- }
- if (first) {
- *fb->search_term = 0;
- first = 0;
- }
- if (buf[0] >= 32 || buflen > 1) {
- int len = strlen(fb->search_term);
- if (len + buflen + 1 > SEARCH_TERM_MAX_LEN)
- return;
- memcpy(fb->search_term + len, buf, buflen);
- fb->search_term[len + buflen] = 0;
- if (fb->mode & FB_SEARCH_BLOCKING_BACKWARDS)
- focused_window->cursor_offset = fb_seek_string_backwards(fb, focused_window->cursor_offset, fb->search_term);
- else
- focused_window->cursor_offset = fb_seek_string(fb, focused_window->cursor_offset, fb->search_term);
- writef_to_status_bar("search: %s", fb->search_term);
- }
+ static int first = 0;
+
+ struct file_buffer* fb = get_fb(focused_window);
+ if (!buf) {
+ first = 1;
+ return;
+ }
+ if (first) {
+ *fb->search_term = 0;
+ first = 0;
+ }
+ if (buf[0] >= 32 || buflen > 1) {
+ int len = strlen(fb->search_term);
+ if (len + buflen + 1 > SEARCH_TERM_MAX_LEN)
+ return;
+ memcpy(fb->search_term + len, buf, buflen);
+ fb->search_term[len + buflen] = 0;
+ if (fb->mode & FB_SEARCH_BLOCKING_BACKWARDS)
+ focused_window->cursor_offset = fb_seek_string_backwards(fb, focused_window->cursor_offset, fb->search_term);
+ else
+ focused_window->cursor_offset = fb_seek_string(fb, focused_window->cursor_offset, fb->search_term);
+ writef_to_status_bar("search: %s", fb->search_term);
+ }
}
static int
search_term_actions(KeySym keysym, int modkey)
{
- static int first = 0;
- struct file_buffer* fb = get_fb(focused_window);
- if (keysym == XK_Return || keysym == XK_Escape) {
- int count = fb_count_string_instances(fb, fb->search_term, 0, NULL);
- if (!count) {
- fb->mode &= ~FB_SEARCH_BLOCKING_MASK;
- writef_to_status_bar("no resulrs for \"%s\"", fb->search_term);
- } else {
- fb->mode &= ~FB_SEARCH_BLOCKING;
- fb->mode &= ~FB_SEARCH_BLOCKING_BACKWARDS;
- fb->mode |= FB_SEARCH_BLOCKING_IDLE;
-
- writef_to_status_bar("%d results for \"%s\"", count, fb->search_term);
- if (fb->mode & FB_SEARCH_BLOCKING_BACKWARDS)
- focused_window->cursor_offset = fb_seek_string_backwards(fb, focused_window->cursor_offset, fb->search_term);
- else
- focused_window->cursor_offset = fb_seek_string(fb, focused_window->cursor_offset, fb->search_term);
- }
- first = 1;
- search_term_string_insert(NULL, 0);
- return 1;
- }
- if (keysym == XK_BackSpace) {
- if (first) {
- first = 0;
- *fb->search_term = 0;
- } else {
- utf8_remove_string_end(fb->search_term);
- focused_window->cursor_offset = wb_seek_string_wrap(focused_window, focused_window->cursor_offset, fb->search_term);
- }
- writef_to_status_bar("search: %s", fb->search_term);
- return 1;
- }
- first = 0;
- return 0;
+ static int first = 0;
+ struct file_buffer* fb = get_fb(focused_window);
+ if (keysym == XK_Return || keysym == XK_Escape) {
+ int count = fb_count_string_instances(fb, fb->search_term, 0, NULL);
+ if (!count) {
+ fb->mode &= ~FB_SEARCH_BLOCKING_MASK;
+ writef_to_status_bar("no resulrs for \"%s\"", fb->search_term);
+ } else {
+ fb->mode &= ~FB_SEARCH_BLOCKING;
+ fb->mode &= ~FB_SEARCH_BLOCKING_BACKWARDS;
+ fb->mode |= FB_SEARCH_BLOCKING_IDLE;
+
+ writef_to_status_bar("%d results for \"%s\"", count, fb->search_term);
+ if (fb->mode & FB_SEARCH_BLOCKING_BACKWARDS)
+ focused_window->cursor_offset = fb_seek_string_backwards(fb, focused_window->cursor_offset, fb->search_term);
+ else
+ focused_window->cursor_offset = fb_seek_string(fb, focused_window->cursor_offset, fb->search_term);
+ }
+ first = 1;
+ search_term_string_insert(NULL, 0);
+ return 1;
+ }
+ if (keysym == XK_BackSpace) {
+ if (first) {
+ first = 0;
+ *fb->search_term = 0;
+ } else {
+ utf8_remove_string_end(fb->search_term);
+ focused_window->cursor_offset = wb_seek_string_wrap(focused_window, focused_window->cursor_offset, fb->search_term);
+ }
+ writef_to_status_bar("search: %s", fb->search_term);
+ return 1;
+ }
+ first = 0;
+ return 0;
}
void
kpress(XEvent *ev)
{
- XKeyEvent *e = &ev->xkey;
- KeySym ksym;
- char buf[64];
- int len;
- rune_t c;
- Status status;
-
- if (IS_SET(MODE_KBDLOCK))
- return;
-
- if (xw.ime.xic)
- len = XmbLookupString(xw.ime.xic, e, buf, sizeof(buf), &ksym, &status);
- else
- len = XLookupString(e, buf, sizeof(buf), &ksym, NULL);
- if (len == 1 && e->state & Mod1Mask) {
- if (*buf < 0177) {
- c = *buf | 0x80;
- len = utf8_encode(c, buf);
- }
- }
-
- const struct file_buffer* fb = get_fb(focused_window);
- // keysym callback
- if (fb->mode & FB_SEARCH_BLOCKING) {
- if (search_term_actions(ksym, e->state))
- return;
- }
- if (fb->mode & FB_SEARCH_BLOCKING) {
- search_term_string_insert(buf, len);
- return;
- }
-
- if (focused_window->mode != WB_NORMAL) {
- int override = 0;
- call_extension(wn_custom_window_keypress_override, &override, focused_node, ksym, e->state, buf, len);
- if (override)
- return;
-
- int wn_custom_window_keypress_override_callback_exists = 0;
- extension_callback_exists(wn_custom_window_keypress_override, wn_custom_window_keypress_override_callback_exists = 1;);
- soft_assert(wn_custom_window_keypress_override_callback_exists, );
- }
-
- call_extension(keypress, ksym, e->state, buf, len);
+ XKeyEvent *e = &ev->xkey;
+ KeySym ksym;
+ char buf[64];
+ int len;
+ rune_t c;
+ Status status;
+
+ if (IS_SET(MODE_KBDLOCK))
+ return;
+
+ if (xw.ime.xic)
+ len = XmbLookupString(xw.ime.xic, e, buf, sizeof(buf), &ksym, &status);
+ else
+ len = XLookupString(e, buf, sizeof(buf), &ksym, NULL);
+ if (len == 1 && e->state & Mod1Mask) {
+ if (*buf < 0177) {
+ c = *buf | 0x80;
+ len = utf8_encode(c, buf);
+ }
+ }
+
+ const struct file_buffer* fb = get_fb(focused_window);
+ // keysym callback
+ if (fb->mode & FB_SEARCH_BLOCKING) {
+ if (search_term_actions(ksym, e->state))
+ return;
+ }
+ if (fb->mode & FB_SEARCH_BLOCKING) {
+ search_term_string_insert(buf, len);
+ return;
+ }
+
+ if (focused_window->mode != WB_NORMAL) {
+ int override = 0;
+ call_extension(wn_custom_window_keypress_override, &override, focused_node, ksym, e->state, buf, len);
+ if (override)
+ return;
+
+ int wn_custom_window_keypress_override_callback_exists = 0;
+ extension_callback_exists(wn_custom_window_keypress_override, wn_custom_window_keypress_override_callback_exists = 1;);
+ soft_assert(wn_custom_window_keypress_override_callback_exists, );
+ }
+
+ call_extension(keypress, ksym, e->state, buf, len);
}
void
cmessage(XEvent *e)
{
- // See xembed specs
- // http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
- if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) {
- if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) {
- win.mode |= MODE_FOCUSED;
- xseturgency(0);
- } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) {
- win.mode &= ~MODE_FOCUSED;
- }
- } else if (e->xclient.data.l[0] == xw.wmdeletewin) {
- exit(0);
- }
+ // See xembed specs
+ // http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
+ if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) {
+ if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) {
+ win.mode |= MODE_FOCUSED;
+ xseturgency(0);
+ } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) {
+ win.mode &= ~MODE_FOCUSED;
+ }
+ } else if (e->xclient.data.l[0] == xw.wmdeletewin) {
+ exit(0);
+ }
}
void
resize(XEvent *e)
{
- if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
- return;
+ if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
+ return;
- cresize(e->xconfigure.width, e->xconfigure.height);
- writef_to_status_bar("window resize: %d:%d", screen.col, screen.row);
+ cresize(e->xconfigure.width, e->xconfigure.height);
+ writef_to_status_bar("window resize: %d:%d", screen.col, screen.row);
}
void
run(void)
{
- XEvent ev;
- int w = win.w, h = win.h;
-
- // Waiting for window mapping
- do {
- XNextEvent(xw.dpy, &ev);
- /*
- * This XFilterEvent call is required because of XOpenIM. It
- * does filter out the key event and some client message for
- * the input method too.
- */
- if (XFilterEvent(&ev, None))
- continue;
- if (ev.type == ConfigureNotify) {
- w = ev.xconfigure.width;
- h = ev.xconfigure.height;
- }
- } while (ev.type != MapNotify);
-
- cresize(w, h);
-
- for (;;) {
- struct timespec ts_start;
-
- int xev = 0;
- while (XPending(xw.dpy)) {
- XNextEvent(xw.dpy, &ev);
- if (XFilterEvent(&ev, None))
- continue;
- if (handler[ev.type]) {
- clock_gettime(CLOCK_MONOTONIC, &ts_start);
- (handler[ev.type])(&ev);
- xev = 1;
- }
- }
-
- if (!xev) {
- nanosleep(&(struct timespec){.tv_nsec = 1e6}, NULL);
- continue;
- }
-
- screen_set_region(0, 0, screen.col-1, screen.row-1, ' ');
- if (screen.row-2 >= 0)
- window_node_draw_tree_to_screen(&root_node, 0, 0, screen.col-1, screen.row-1);
- draw_status_bar();
-
- xfinishdraw();
- XFlush(xw.dpy);
-
- struct timespec ts_end;
- clock_gettime(CLOCK_MONOTONIC, &ts_end);
- double dif = 0;
- dif = (ts_end.tv_sec - ts_start.tv_sec) * 1e6;
- dif += (ts_end.tv_nsec - ts_start.tv_nsec) * 1e-3;
- printf("%lf\n", dif);
- }
+ XEvent ev;
+ int w = win.w, h = win.h;
+
+ // Waiting for window mapping
+ do {
+ XNextEvent(xw.dpy, &ev);
+ /*
+ * This XFilterEvent call is required because of XOpenIM. It
+ * does filter out the key event and some client message for
+ * the input method too.
+ */
+ if (XFilterEvent(&ev, None))
+ continue;
+ if (ev.type == ConfigureNotify) {
+ w = ev.xconfigure.width;
+ h = ev.xconfigure.height;
+ }
+ } while (ev.type != MapNotify);
+
+ cresize(w, h);
+
+ for (;;) {
+ struct timespec ts_start;
+
+ int xev = 0;
+ while (XPending(xw.dpy)) {
+ XNextEvent(xw.dpy, &ev);
+ if (XFilterEvent(&ev, None))
+ continue;
+ if (handler[ev.type]) {
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
+ (handler[ev.type])(&ev);
+ xev = 1;
+ }
+ }
+
+ if (!xev) {
+ nanosleep(&(struct timespec){.tv_nsec = 1e6}, NULL);
+ continue;
+ }
+
+ screen_set_region(0, 0, screen.col-1, screen.row-1, ' ');
+ if (screen.row-2 >= 0)
+ window_node_draw_tree_to_screen(&root_node, 0, 0, screen.col-1, screen.row-1);
+ draw_status_bar();
+
+ xfinishdraw();
+ XFlush(xw.dpy);
+
+ struct timespec ts_end;
+ clock_gettime(CLOCK_MONOTONIC, &ts_end);
+ double dif = 0;
+ dif = (ts_end.tv_sec - ts_start.tv_sec) * 1e6;
+ dif += (ts_end.tv_nsec - ts_start.tv_nsec) * 1e-3;
+ printf("%lf\n", dif);
+ }
}
int
main(int argc, char *argv[])
{
- xw.l = xw.t = 0;
- xw.isfixed = False;
-
- setlocale(LC_CTYPE, "");
- XSetLocaleModifiers("");
- int cols = MAX(default_cols, 1);
- int rows = MAX(default_rows, 1);
- screen_init(cols, rows);
- xinit(cols, rows);
- xsetenv();
-
- if (argc <= 1) {
- *focused_window = wb_new(fb_new_entry(NULL));
- } else {
- int master_stack = 1;
- for (int i = 1; i < argc; i++) {
- if (*argv[i] == '-') {
- i++;
- } else {
- if (master_stack < 0) {
- window_node_split(focused_node, 0.5, WINDOW_HORISONTAL);
- master_stack = 0;
- } else if (master_stack > 0) {
- *focused_window = wb_new(fb_new_entry(argv[i]));
- master_stack = -1;
- continue;
- } else {
- window_node_split(focused_node, 0.5, WINDOW_VERTICAL);
- }
-
- if (focused_node->node2) {
- focused_node = focused_node->node2;
- focused_window = &focused_node->wb;
- if (!master_stack)
- *focused_window = wb_new(fb_new_entry(argv[i]));
- }
- master_stack = 0;
- }
- }
- }
-
- srand(time(NULL));
-
- // TODO: start screen extension
-
- if (extensions) {
- for (int i = 0; !extensions[i].end; i++) {
- if (extensions[i].e.init)
- extensions[i].e.init(&extensions[i].e);
- if (extensions[i].e.enable)
- extensions[i].e.enable();
- }
- }
-
- run();
-
- return 0;
+ xw.l = xw.t = 0;
+ xw.isfixed = False;
+
+ setlocale(LC_CTYPE, "");
+ XSetLocaleModifiers("");
+ int cols = MAX(default_cols, 1);
+ int rows = MAX(default_rows, 1);
+ screen_init(cols, rows);
+ xinit(cols, rows);
+ xsetenv();
+
+ if (argc <= 1) {
+ *focused_window = wb_new(fb_new_entry(NULL));
+ } else {
+ int master_stack = 1;
+ for (int i = 1; i < argc; i++) {
+ if (*argv[i] == '-') {
+ i++;
+ } else {
+ if (master_stack < 0) {
+ window_node_split(focused_node, 0.5, WINDOW_HORISONTAL);
+ master_stack = 0;
+ } else if (master_stack > 0) {
+ *focused_window = wb_new(fb_new_entry(argv[i]));
+ master_stack = -1;
+ continue;
+ } else {
+ window_node_split(focused_node, 0.5, WINDOW_VERTICAL);
+ }
+
+ if (focused_node->node2) {
+ focused_node = focused_node->node2;
+ focused_window = &focused_node->wb;
+ if (!master_stack)
+ *focused_window = wb_new(fb_new_entry(argv[i]));
+ }
+ master_stack = 0;
+ }
+ }
+ }
+
+ srand(time(NULL));
+
+ // TODO: start screen extension
+
+ if (extensions) {
+ for (int i = 0; !extensions[i].end; i++) {
+ if (extensions[i].e.init)
+ extensions[i].e.init(&extensions[i].e);
+ if (extensions[i].e.enable)
+ extensions[i].e.enable();
+ }
+ }
+
+ run();
+
+ return 0;
}
diff --git a/x.h b/x.h
@@ -25,31 +25,31 @@ void set_clipboard_copy(char* buffer, int len);
void execute_clipbaord_event();
enum glyph_attribute {
- ATTR_NULL = 0,
- ATTR_BOLD = 1 << 0,
- ATTR_FAINT = 1 << 1,
- ATTR_ITALIC = 1 << 2,
- ATTR_UNDERLINE = 1 << 3,
- ATTR_REVERSE = 1 << 5,
- ATTR_INVISIBLE = 1 << 6,
- ATTR_STRUCK = 1 << 7,
- ATTR_WIDE = 1 << 9,
- ATTR_WDUMMY = 1 << 10,
- ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
+ ATTR_NULL = 0,
+ ATTR_BOLD = 1 << 0,
+ ATTR_FAINT = 1 << 1,
+ ATTR_ITALIC = 1 << 2,
+ ATTR_UNDERLINE = 1 << 3,
+ ATTR_REVERSE = 1 << 5,
+ ATTR_INVISIBLE = 1 << 6,
+ ATTR_STRUCK = 1 << 7,
+ ATTR_WIDE = 1 << 9,
+ ATTR_WDUMMY = 1 << 10,
+ ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
struct glyph {
- rune_t u; // character code
- uint16_t mode; // attribute flags
- uint32_t fg; // foreground
- uint32_t bg; // background
+ rune_t u; // character code
+ uint16_t mode; // attribute flags
+ uint32_t fg; // foreground
+ uint32_t bg; // background
};
// Internal representation of the screen
struct screen {
- int row; // row count
- int col; // column count
- struct glyph** lines; // screen letters 2d array
+ int row; // row count
+ int col; // column count
+ struct glyph** lines; // screen letters 2d array
};
extern struct screen screen;
@@ -68,27 +68,27 @@ void die(const char *, ...);
// the va_args can be used to return; or any other stuff like that
// TODO: optionally crash the program for debugging
#define soft_assert(condition, ...) \
- do { \
- if(!(condition)) { \
- fprintf(stderr, "SOFT ASSERT ERROR: (%s) failed at %s %s():%d\n", #condition, __FILE__, __func__, __LINE__); \
- writef_to_status_bar("SOFT ASSERT ERROR: (%s) failed at %s %s():%d", #condition, __FILE__, __func__, __LINE__); \
- status_bar_bg = error_color; \
- __VA_ARGS__ \
- } \
- } while(0) \
+ do { \
+ if(!(condition)) { \
+ fprintf(stderr, "SOFT ASSERT ERROR: (%s) failed at %s %s():%d\n", #condition, __FILE__, __func__, __LINE__); \
+ writef_to_status_bar("SOFT ASSERT ERROR: (%s) failed at %s %s():%d", #condition, __FILE__, __func__, __LINE__); \
+ status_bar_bg = error_color; \
+ __VA_ARGS__ \
+ } \
+ } while(0) \
enum win_mode {
- MODE_VISIBLE = 1 << 0,
- MODE_FOCUSED = 1 << 1,
- MODE_APPKEYPAD = 1 << 2,
- MODE_KBDLOCK = 1 << 6,
- MODE_HIDE = 1 << 7,
- MODE_APPCURSOR = 1 << 8,
- MODE_MOUSESGR = 1 << 9,
- MODE_BLINK = 1 << 11,
- MODE_FBLINK = 1 << 12,
- MODE_BRCKTPASTE = 1 << 16,
- MODE_NUMLOCK = 1 << 17,
+ MODE_VISIBLE = 1 << 0,
+ MODE_FOCUSED = 1 << 1,
+ MODE_APPKEYPAD = 1 << 2,
+ MODE_KBDLOCK = 1 << 6,
+ MODE_HIDE = 1 << 7,
+ MODE_APPCURSOR = 1 << 8,
+ MODE_MOUSESGR = 1 << 9,
+ MODE_BLINK = 1 << 11,
+ MODE_FBLINK = 1 << 12,
+ MODE_BRCKTPASTE = 1 << 16,
+ MODE_NUMLOCK = 1 << 17,
};
#define MIN(a, b) ((a) < (b) ? (a) : (b))