From 0c9d72c17ce23ebbf96ab18329fb5b4418f1e9a7 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 23 Feb 2021 14:34:47 -0500 Subject: various tag bugfixes --- config.c | 1 - tags.c | 59 +++++++++++++++++++++++++++++++++++++++-------------------- ted.h | 2 +- ui.c | 3 ++- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/config.c b/config.c index efba92e..9eedbf1 100644 --- a/config.c +++ b/config.c @@ -202,7 +202,6 @@ void config_read(Ted *ted, char const *filename) { }; OptionString const options_string[] = { {"build-default-command", settings->build_default_command, sizeof settings->build_default_command}, - {"tags-filename", settings->tags_filename, sizeof settings->tags_filename}, }; FILE *fp = fopen(filename, "rb"); diff --git a/tags.c b/tags.c index 5fe192e..4412533 100644 --- a/tags.c +++ b/tags.c @@ -1,4 +1,21 @@ -static char const TED_ERR_NO_TAGS[] = "No tags file. Try running ctags."; +static char const *tags_filename(Ted *ted) { + change_directory(ted->cwd); + char const *filename = "tags"; + strbuf_printf(ted->tags_dir, "."); + if (!fs_file_exists(filename)) { + filename = "../tags"; + strbuf_printf(ted->tags_dir, ".."); + if (!fs_file_exists(filename)) { + filename = "../../tags"; + strbuf_printf(ted->tags_dir, "../.."); + if (!fs_file_exists(filename)) { + ted_seterr(ted, "No tags file. Try running ctags."); + filename = NULL; + } + } + } + return filename; +} static int tag_try(FILE *fp, char const *tag) { if (ftell(fp) != 0) { @@ -26,14 +43,11 @@ static int tag_try(FILE *fp, char const *tag) { // returns true if the tag exists. bool tag_goto(Ted *ted, char const *tag) { - change_directory(ted->cwd); - Settings const *settings = &ted->settings; - char const *tags_filename = settings->tags_filename; - FILE *file = fopen(tags_filename, "rb"); - if (!file) { - ted_seterr(ted, TED_ERR_NO_TAGS); - return false; - } + char const *tags_name = tags_filename(ted); + if (!tags_name) return false; + FILE *file = fopen(tags_name, "rb"); + if (!file) return false; + fseek(file, 0, SEEK_END); size_t file_size = (size_t)ftell(file); // binary search for tag in file @@ -93,9 +107,10 @@ bool tag_goto(Ted *ted, char const *tag) { address_end[-2] = '\0'; } assert(streq(name, tag)); - char path[TED_PATH_MAX]; - ted_full_path(ted, filename, path, sizeof path); - if (ted_open_file(ted, path)) { + char path[TED_PATH_MAX], full_path[TED_PATH_MAX]; + strbuf_printf(path, "%s/%s", ted->tags_dir, filename); + ted_full_path(ted, path, full_path, sizeof full_path); + if (ted_open_file(ted, full_path)) { TextBuffer *buffer = ted->active_buffer; int line_number = atoi(address); if (line_number > 0) { @@ -165,22 +180,26 @@ bool tag_goto(Ted *ted, char const *tag) { static void tag_selector_open(Ted *ted) { // read tags file and extract tag names - FILE *fp = fopen("tags", "r"); + char const *filename = tags_filename(ted); + if (!filename) return; + FILE *file = fopen(filename, "rb"); + if (!file) return; + arr_clear(ted->tag_selector_entries); - if (fp) { + if (file) { char line[1024]; - while (fgets(line, sizeof line, fp)) { - size_t len = strcspn(line, "\t"); - arr_add(ted->tag_selector_entries, strn_dup(line, len)); + while (fgets(line, sizeof line, file)) { + if (line[0] != '!') { // tag metadata is formatted as tag names beginning with ! + size_t len = strcspn(line, "\t"); + arr_add(ted->tag_selector_entries, strn_dup(line, len)); + } } ted->active_buffer = &ted->line_buffer; buffer_select_all(ted->active_buffer); ted->tag_selector.cursor = 0; - fclose(fp); - } else { - ted_seterr(ted, TED_ERR_NO_TAGS); + fclose(file); } } diff --git a/ted.h b/ted.h index 18c8d15..0b7445b 100644 --- a/ted.h +++ b/ted.h @@ -79,7 +79,6 @@ typedef struct { u8 padding; u8 scrolloff; char build_default_command[256]; - char tags_filename[128]; // [i] = comma-separated string of file extensions for language i, or NULL for none char *language_extensions[LANG_COUNT]; } Settings; @@ -291,6 +290,7 @@ typedef struct Ted { char home[TED_PATH_MAX]; char cwd[TED_PATH_MAX]; // current working directory char build_dir[TED_PATH_MAX]; // directory where we run the build command + char tags_dir[TED_PATH_MAX]; // where we are reading tags from bool nodes_used[TED_MAX_NODES]; Node nodes[TED_MAX_NODES]; bool buffers_used[TED_MAX_BUFFERS]; diff --git a/ui.c b/ui.c index d2f0d23..45ea056 100644 --- a/ui.c +++ b/ui.c @@ -311,9 +311,10 @@ static Status file_selector_cd_(Ted const *ted, FileSelector *fs, char const *pa // go to the directory `path`. make sure `path` only contains path separators like PATH_SEPARATOR, not any // other members of ALL_PATH_SEPARATORS // returns false if this path doesn't exist or isn't a directory -static bool file_selector_cd(Ted const *ted, FileSelector *fs, char const *path) { +static bool file_selector_cd(Ted *ted, FileSelector *fs, char const *path) { fs->sel.cursor = 0; fs->sel.scroll = 0; + buffer_clear(&ted->line_buffer); return file_selector_cd_(ted, fs, path, 0); } -- cgit v1.2.3