diff options
-rw-r--r-- | .editorconfig | 6 | ||||
-rw-r--r-- | buffer.c | 6 | ||||
-rw-r--r-- | config.c | 4 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | ted.c | 17 | ||||
-rw-r--r-- | test/editorconfig/.editorconfig | 18 | ||||
-rw-r--r-- | test/editorconfig/file.txt | 3 | ||||
-rw-r--r-- | test/editorconfig/gov.biz | 2 | ||||
-rw-r--r-- | test/editorconfig/r.dat | 2 | ||||
-rw-r--r-- | test/editorconfig/subdir/.editorconfig | 5 | ||||
-rw-r--r-- | test/editorconfig/subdir/a.biz | 3 | ||||
-rw-r--r-- | util.c | 12 | ||||
-rw-r--r-- | util.h | 2 |
13 files changed, 74 insertions, 9 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4931544 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +# https://editorconfig.org + +[*] +indent_style = tab +insert_final_newline = true +charset = utf-8 @@ -3239,8 +3239,10 @@ bool buffer_save(TextBuffer *buffer) { buffer->last_write_time = timespec_to_seconds(time_last_modified(buffer->path)); if (success) { buffer->undo_history_write_pos = arr_len(buffer->undo_history); - if (buffer->path && str_has_suffix(path_filename(buffer->path), "ted.cfg") - && buffer_settings(buffer)->auto_reload_config) { + const char *filename = path_filename(buffer->path); + if (buffer->path && + (str_has_suffix(filename, "ted.cfg") || streq(filename, ".editorconfig")) && + buffer_settings(buffer)->auto_reload_config) { ted_reload_configs(buffer->ted); } } @@ -1459,6 +1459,7 @@ static void config_read_editorconfig(Ted *ted, RcStr *path_rc) { } const int value_int = atoi(value); if (cfg && streq(key, "indent_style")) { + str_ascii_to_lowercase(value); if (streq(value, "tab")) config_set_bool(cfg, &setting_indent_with_spaces, false); else if (streq(value, "space")) @@ -1466,6 +1467,7 @@ static void config_read_editorconfig(Ted *ted, RcStr *path_rc) { } else if (cfg && (streq(key, "indent_size") || streq(key, "tab_width")) && value_int > 0 && value_int < 255) { config_set_u8(cfg, &setting_tab_width, (u8)value_int); } else if (cfg && streq(key, "end_of_line")) { + str_ascii_to_lowercase(value); if (streq(value, "lf")) { config_set_bool(cfg, &setting_crlf, false); config_set_bool(cfg, &setting_crlf_windows, false); @@ -1474,12 +1476,14 @@ static void config_read_editorconfig(Ted *ted, RcStr *path_rc) { } // who the fuck uses CR line endings in the 21st century?? } else if (cfg && streq(key, "insert_final_newline")) { + str_ascii_to_lowercase(value); if (streq(value, "true")) { config_set_bool(cfg, &setting_auto_add_newline, true); } else if (streq(value, "false")) { config_set_bool(cfg, &setting_auto_add_newline, false); } } else if (cfg && streq(key, "trim_trailing_whitespace")) { + str_ascii_to_lowercase(value); if (streq(value, "true")) { config_set_bool(cfg, &setting_remove_trailing_whitespace, true); } else if (streq(value, "false")) { @@ -1,8 +1,5 @@ /* TODO: -- .editorconfig (see https://editorconfig.org/) - - handle root = true - - reload configs when .editorconfig is saved - local .ted.cfg FUTURE FEATURES: - more tests @@ -238,6 +238,7 @@ static int applicable_configs_cmp(void *context, const void *av, const void *bv) void ted_compute_settings(Ted *ted, const char *path, Language language, Settings *settings) { settings_free(settings); + u32 root_editorconfig = 0; if (path && *path) { // check for .editorconfig char editorconfig[2048]; @@ -249,11 +250,27 @@ void ted_compute_settings(Ted *ted, const char *path, Language language, Setting config_read(ted, editorconfig, CONFIG_EDITORCONFIG); } } + + // find root editorconfig + for (u32 i = 0; i < arr_len(ted->all_configs); i++) { + Config *cfg = &ted->all_configs[i]; + if (cfg->format != CONFIG_EDITORCONFIG) continue; + if (!cfg->is_editorconfig_root) continue; + char dirname[4096]; + strbuf_cpy(dirname, rc_str(cfg->source, "")); + path_dirname(dirname); + if (str_has_path_prefix(path, dirname)) + root_editorconfig = max_u32(root_editorconfig, (u32)rc_str_len(cfg->source)); + } } u32 *applicable_configs = NULL; for (u32 i = 0; i < arr_len(ted->all_configs); i++) { Config *cfg = &ted->all_configs[i]; + if (cfg->format == CONFIG_EDITORCONFIG && rc_str_len(cfg->source) < root_editorconfig) { + // ignore this since there's a root .editorconfig closer to `path`. + continue; + } if (config_applies_to(cfg, path, language)) { arr_add(applicable_configs, i); } diff --git a/test/editorconfig/.editorconfig b/test/editorconfig/.editorconfig new file mode 100644 index 0000000..d97f36d --- /dev/null +++ b/test/editorconfig/.editorconfig @@ -0,0 +1,18 @@ +root = true +; yipee +# comments + +[*] +trim_TRAILING_whitespace=true +insert_final_newline=true +indent_sizE=16 +indent_style=Space +funkel = mitochondrion + +[*.biz] +# i love microsoft widnwso +end_of_linE = CRLF + +[*.txt] +indent_size = 4 +Indent_Style = tab diff --git a/test/editorconfig/file.txt b/test/editorconfig/file.txt new file mode 100644 index 0000000..21d9f41 --- /dev/null +++ b/test/editorconfig/file.txt @@ -0,0 +1,3 @@ + yep +here's a file + things diff --git a/test/editorconfig/gov.biz b/test/editorconfig/gov.biz new file mode 100644 index 0000000..60f6a24 --- /dev/null +++ b/test/editorconfig/gov.biz @@ -0,0 +1,2 @@ +MICROSOFT®
+ DISK OPERATING SYSTEM
diff --git a/test/editorconfig/r.dat b/test/editorconfig/r.dat new file mode 100644 index 0000000..43dda4a --- /dev/null +++ b/test/editorconfig/r.dat @@ -0,0 +1,2 @@ +ORDINARY FILE + FILE DATA HERE diff --git a/test/editorconfig/subdir/.editorconfig b/test/editorconfig/subdir/.editorconfig new file mode 100644 index 0000000..610d487 --- /dev/null +++ b/test/editorconfig/subdir/.editorconfig @@ -0,0 +1,5 @@ +; don't apply ../.editorconfig +root = true + +[*] +indent_size = 4 diff --git a/test/editorconfig/subdir/a.biz b/test/editorconfig/subdir/a.biz new file mode 100644 index 0000000..2c17b88 --- /dev/null +++ b/test/editorconfig/subdir/a.biz @@ -0,0 +1,3 @@ +yahoo + business + ventures @@ -54,10 +54,14 @@ void rc_str_decref(RcStr **pstr) { } } -const char *rc_str(RcStr *str, const char *default_value) { - if (!str) return default_value; - assert(str->ref_count > 0); - return str->str; +const char *rc_str(RcStr *s, const char *default_value) { + if (!s) return default_value; + assert(s->ref_count > 0); + return s->str; +} + +size_t rc_str_len(RcStr *s) { + return strlen(rc_str(s, "")); } bool is32_word(char32_t c) { @@ -63,6 +63,8 @@ RcStr *rc_str_copy(RcStr *str); void rc_str_decref(RcStr **str); /// get rc string with default value if `s == NULL` const char *rc_str(RcStr *s, const char *value_if_null); +/// length of string or 0 if `s == NULL` +size_t rc_str_len(RcStr *s); /// `isword` for 32-bit chars. bool is32_word(char32_t c); /// `isspace` for 32-bit chars. |