summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig6
-rw-r--r--buffer.c6
-rw-r--r--config.c4
-rw-r--r--main.c3
-rw-r--r--ted.c17
-rw-r--r--test/editorconfig/.editorconfig18
-rw-r--r--test/editorconfig/file.txt3
-rw-r--r--test/editorconfig/gov.biz2
-rw-r--r--test/editorconfig/r.dat2
-rw-r--r--test/editorconfig/subdir/.editorconfig5
-rw-r--r--test/editorconfig/subdir/a.biz3
-rw-r--r--util.c12
-rw-r--r--util.h2
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
diff --git a/buffer.c b/buffer.c
index 44992bc..497afa8 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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);
}
}
diff --git a/config.c b/config.c
index d6b3eca..abb6e34 100644
--- a/config.c
+++ b/config.c
@@ -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")) {
diff --git a/main.c b/main.c
index 9ee97e8..9fb732d 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/ted.c b/ted.c
index b704187..2d09574 100644
--- a/ted.c
+++ b/ted.c
@@ -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
diff --git a/util.c b/util.c
index 2e702e2..98c7dbc 100644
--- a/util.c
+++ b/util.c
@@ -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) {
diff --git a/util.h b/util.h
index 957dc07..479ea03 100644
--- a/util.h
+++ b/util.h
@@ -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.