From 2bb49a38c80d97c8d63fd1d414fcd59cd21f2895 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 12 Aug 2009 11:19:54 +0000 Subject: [PATCH] Support adding custom filetype files e.g. filetype.Foo.conf. (Only tested with empty file so far). Allow GeanyFiletype::extension to be NULL. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/custom-filetypes@4070 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- ChangeLog | 9 +++++++ src/dialogs.c | 5 ++-- src/document.c | 6 ++++- src/filetypes.c | 59 ++++++++++++++++++++++++++++++++++++++++++---- src/filetypes.h | 2 +- src/highlighting.c | 3 +++ src/symbols.c | 5 ++-- src/templates.c | 4 +++- 8 files changed, 80 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1b63efc..31c24d3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-08-12 Nick Treleaven + + * src/templates.c, src/highlighting.c, src/dialogs.c, src/filetypes.c, + src/filetypes.h, src/document.c, src/symbols.c: + Support adding custom filetype files e.g. filetype.Foo.conf. (Only + tested with empty file so far). + Allow GeanyFiletype::extension to be NULL. + + 2009-08-11 Nick Treleaven * src/highlighting.c: diff --git a/src/dialogs.c b/src/dialogs.c index e5c286df..1106f2da 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -88,7 +88,7 @@ on_file_open_dialog_response (GtkDialog *dialog, gboolean ro = (response == GEANY_RESPONSE_VIEW); /* View clicked */ /* ignore detect from file item */ - if (filetype_idx > 0 && filetype_idx < GEANY_MAX_BUILT_IN_FILETYPES) + if (filetype_idx > 0) ft = g_slist_nth_data(filetypes_by_title, filetype_idx); if (encoding_idx >= 0 && encoding_idx < GEANY_ENCODINGS_MAX) charset = encodings[encoding_idx].charset; @@ -511,8 +511,7 @@ static gboolean gtk_show_save_as(void) { gchar *fname = NULL; - if (doc->file_type != NULL && doc->file_type->id != GEANY_FILETYPES_NONE && - doc->file_type->extension != NULL) + if (doc->file_type != NULL && doc->file_type->extension != NULL) fname = g_strconcat(GEANY_STRING_UNTITLED, ".", doc->file_type->extension, NULL); else diff --git a/src/document.c b/src/document.c index 79309418..ed805c5b 100644 --- a/src/document.c +++ b/src/document.c @@ -1461,7 +1461,11 @@ static void replace_header_filename(GeanyDocument *doc) g_return_if_fail(doc != NULL); g_return_if_fail(doc->file_type != NULL); - filebase = g_strconcat(GEANY_STRING_UNTITLED, ".", (doc->file_type)->extension, NULL); + if (doc->file_type->extension) + filebase = g_strconcat(GEANY_STRING_UNTITLED, ".", doc->file_type->extension, NULL); + else + filebase = g_strdup(GEANY_STRING_UNTITLED); + filename = g_path_get_basename(doc->file_name); /* only search the first 3 lines */ diff --git a/src/filetypes.c b/src/filetypes.c index f8a30103..2c83c4a1 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -112,7 +112,7 @@ static void init_builtin_filetypes(void) ft->lang = -2; ft->name = g_strdup(_("None")); ft->title = g_strdup(_("None")); - ft->extension = g_strdup("*"); + ft->extension = NULL; ft->pattern = utils_strv_new("*", NULL); ft->comment_open = NULL; ft->comment_close = NULL; @@ -656,6 +656,51 @@ static void filetype_add(GeanyFiletype *ft) } +static void add_custom_filetype(const gchar *filename) +{ + gchar *fn = utils_strdupa(strstr(filename, ".") + 1); + gchar *dot = g_strrstr(fn, ".conf"); + GeanyFiletype *ft; + + g_return_if_fail(dot); + + *dot = 0x0; + + geany_debug("Adding filetype %s.", fn); + ft = filetype_new(); + ft->name = g_strdup(fn); + filetype_make_title(ft, TITLE_FILE); + ft->pattern = g_new0(gchar*, 1); + filetype_add(ft); +} + + +static void init_custom_filetypes(const gchar *path) +{ + GDir *dir; + + g_return_if_fail(path); + + dir = g_dir_open(path, 0, NULL); + if (dir == NULL) + return; + + while (1) + { + const gchar *filename = g_dir_read_name(dir); + + if (filename == NULL) + break; + + if (g_str_has_prefix(filename, "filetype.") && g_str_has_suffix(filename + 9, ".conf")) + { + add_custom_filetype(filename); + } + } + g_dir_close(dir); +} + + /* Create the filetypes array and fill it with the known filetypes. */ void filetypes_init_types() { @@ -679,6 +724,8 @@ void filetypes_init_types() { filetype_add(filetypes[ft_id]); } + init_custom_filetypes(app->datadir); + init_custom_filetypes(utils_build_path(app->configdir, GEANY_FILEDEFS_SUBDIR, NULL)); } @@ -745,16 +792,18 @@ static void create_set_filetype_menu(void) { GeanyFiletype *ft = node->data; - if (ft->id != GEANY_FILETYPES_NONE) + if (ft->group != GEANY_FILETYPE_GROUP_NONE) create_radio_menu_item(group_menus[ft->group], ft); + else + create_radio_menu_item(filetype_menu, ft); } - create_radio_menu_item(filetype_menu, filetypes[GEANY_FILETYPES_NONE]); } void filetypes_init() { filetypes_init_types(); + create_set_filetype_menu(); setup_config_file_menus(); } @@ -1284,9 +1333,9 @@ void filetypes_save_commands(void) { gchar *conf_prefix = g_strconcat(app->configdir, G_DIR_SEPARATOR_S GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S "filetypes.", NULL); - gint i; + guint i; - for (i = 1; i < GEANY_MAX_BUILT_IN_FILETYPES; i++) + for (i = 1; i < filetypes_array->len; i++) { struct build_programs *bp = filetypes[i]->programs; GKeyFile *config_home; diff --git a/src/filetypes.h b/src/filetypes.h index ea1c6357..ed59f7c1 100644 --- a/src/filetypes.h +++ b/src/filetypes.h @@ -125,7 +125,7 @@ struct GeanyFiletype langType lang; gchar *name; /**< Used as name for tagmanager. E.g. "C". */ gchar *title; /**< Shown in the file open dialog. E.g. "C source file". */ - gchar *extension; /**< Default file extension for new files. */ + gchar *extension; /**< Default file extension for new files, or @c NULL. */ gchar **pattern; /**< Array of filename-matching wildcard strings. */ gchar *context_action_cmd; gchar *comment_open; diff --git a/src/highlighting.c b/src/highlighting.c index 1ae5bf69..5bc0a6dc 100644 --- a/src/highlighting.c +++ b/src/highlighting.c @@ -3497,6 +3497,9 @@ static void styleset_ada(ScintillaObject *sci) /* Called by filetypes_load_config(). */ void highlighting_init_styles(gint filetype_idx, GKeyFile *config, GKeyFile *configh) { + if (filetype_idx >= GEANY_MAX_BUILT_IN_FILETYPES) + return; /* not supported yet */ + /* Clear old information if necessary - e.g. reloading config */ styleset_free(filetype_idx); diff --git a/src/symbols.c b/src/symbols.c index 39f41e9f..1f995314 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1487,15 +1487,16 @@ static GHashTable *init_user_tags(void) static void load_user_tags(filetype_id ft_id) { - static guchar tags_loaded[GEANY_MAX_BUILT_IN_FILETYPES] = {0}; + static guchar *tags_loaded = NULL; static GHashTable *lang_hash = NULL; GList *fnames; const GList *node; GeanyFiletype *ft = filetypes[ft_id]; g_return_if_fail(ft_id > 0); - g_return_if_fail(ft_id < GEANY_MAX_BUILT_IN_FILETYPES); + if (!tags_loaded) + tags_loaded = g_new0(guchar, filetypes_array->len); if (tags_loaded[ft_id]) return; tags_loaded[ft_id] = TRUE; /* prevent reloading */ diff --git a/src/templates.c b/src/templates.c index 8b8ea2a1..9f124c8f 100644 --- a/src/templates.c +++ b/src/templates.c @@ -240,6 +240,8 @@ static const gchar templates_filetype_latex[] = "\ "; static gchar *templates[GEANY_MAX_TEMPLATES]; + +/* TODO: remove filetype templates, use custom file templates instead. */ static gchar *ft_templates[GEANY_MAX_BUILT_IN_FILETYPES] = {NULL}; @@ -684,7 +686,7 @@ gchar *templates_get_template_fileheader(gint filetype_idx, const gchar *fname) if (fname == NULL) { - if (ft_id == GEANY_FILETYPES_NONE) + if (!ft->extension) shortname = g_strdup(GEANY_STRING_UNTITLED); else shortname = g_strconcat(GEANY_STRING_UNTITLED, ".", ft->extension, NULL);