120
static const gchar templates_filetype_none[] = "";
122
static const gchar templates_filetype_c[] = "{fileheader}\n\n\
123
#include <stdio.h>\n\
125
int main(int argc, char** argv)\n\
132
static const gchar templates_filetype_cpp[] = "{fileheader}\n\n\
133
#include <iostream>\n\
135
int main(int argc, char** argv)\n\
142
static const gchar templates_filetype_d[] = "{fileheader}\n\n\
145
int main(char[][] args)\n\
152
static const gchar templates_filetype_php[] = "\
156
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\
157
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
158
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n\
161
<title>{untitled}</title>\n\
162
<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\n\
163
<meta name=\"generator\" content=\"{geanyversion}\" />\n\
172
static const gchar templates_filetype_html[] = "{fileheader}\n\
173
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\
174
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
175
<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n\
178
<title>{untitled}</title>\n\
179
<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\n\
180
<meta name=\"generator\" content=\"{geanyversion}\" />\n\
189
static const gchar templates_filetype_pascal[] = "{fileheader}\n\n\
190
program {untitled};\n\
201
static const gchar templates_filetype_java[] = "{fileheader}\n\n\
202
public class {untitled} {\n\
204
public static void main (String args[]) {\
211
static const gchar templates_filetype_ruby[] = "{fileheader}\n\n\
221
static const gchar templates_filetype_python[] = "#!/usr/bin/env python\n\
222
# -*- coding: utf-8 -*-\n#\n\
229
if __name__ == '__main__':\n\
233
static const gchar templates_filetype_latex[] = "\
234
\\documentclass[a4paper]{article}\n\
235
\\usepackage[T1]{fontenc}\n\
236
\\usepackage[utf8]{inputenc}\n\
237
\\usepackage{lmodern}\n\
238
\\usepackage{babel}\n\
244
123
static gchar *templates[GEANY_MAX_TEMPLATES];
125
/* We should probably remove filetype templates support soon - users can use custom
126
* file templates instead. */
245
127
static gchar *ft_templates[GEANY_MAX_BUILT_IN_FILETYPES] = {NULL};
130
static void replace_static_values(GString *text);
131
static gchar *get_template_fileheader(GeanyFiletype *ft);
133
/* called by templates_replace_common */
134
static void templates_replace_default_dates(GString *text);
135
static void templates_replace_command(GString *text, const gchar *file_name,
136
const gchar *file_type, const gchar *func_name);
248
139
/* some simple macros to reduce code size and make the code readable */
249
140
#define TEMPLATES_GET_FILENAME(shortname) \
250
141
g_strconcat(app->configdir, \
341
237
gchar *shortname = g_strconcat("filetype.", ext, NULL);
342
238
gchar *fname = TEMPLATES_GET_FILENAME(shortname);
346
case GEANY_FILETYPES_NONE:
347
create_template_file_if_necessary(fname, templates_filetype_none);
349
case GEANY_FILETYPES_C:
350
create_template_file_if_necessary(fname, templates_filetype_c);
352
case GEANY_FILETYPES_CPP:
353
create_template_file_if_necessary(fname, templates_filetype_cpp);
355
case GEANY_FILETYPES_D:
356
create_template_file_if_necessary(fname, templates_filetype_d);
358
case GEANY_FILETYPES_JAVA:
359
create_template_file_if_necessary(fname, templates_filetype_java);
361
case GEANY_FILETYPES_PASCAL:
362
create_template_file_if_necessary(fname, templates_filetype_pascal);
364
case GEANY_FILETYPES_PHP:
365
create_template_file_if_necessary(fname, templates_filetype_php);
367
case GEANY_FILETYPES_HTML:
368
create_template_file_if_necessary(fname, templates_filetype_html);
370
case GEANY_FILETYPES_RUBY:
371
create_template_file_if_necessary(fname, templates_filetype_ruby);
373
case GEANY_FILETYPES_PYTHON:
374
create_template_file_if_necessary(fname, templates_filetype_python);
376
case GEANY_FILETYPES_LATEX:
377
create_template_file_if_necessary(fname, templates_filetype_latex);
381
240
TEMPLATES_READ_FILE(fname, &ft_templates[ft_id]);
382
241
ft_templates[ft_id] = replace_all(ft_templates[ft_id], year, date, datetime);
403
/* template items for the new file menu */
404
static void create_new_menu_items(GtkWidget *toolbar_new_file_menu)
261
/* TODO: remove filetype template support after 0.19 */
262
static gboolean create_new_filetype_items(void)
265
gboolean ret = FALSE;
266
GtkWidget *menu = NULL;
408
268
foreach_slist(node, filetypes_by_title)
410
270
GeanyFiletype *ft = node->data;
411
GtkWidget *tmp_menu, *tmp_button;
412
const gchar *label = ft->title;
414
if (ft_templates[ft->id] == NULL)
273
if (ft->id >= GEANY_MAX_BUILT_IN_FILETYPES || ft_templates[ft->id] == NULL)
417
tmp_menu = gtk_menu_item_new_with_label(label);
418
gtk_widget_show(tmp_menu);
419
gtk_container_add(GTK_CONTAINER(new_with_template_menu), tmp_menu);
420
g_signal_connect(tmp_menu, "activate", G_CALLBACK(on_new_with_template), ft);
422
tmp_button = gtk_menu_item_new_with_label(label);
423
gtk_widget_show(tmp_button);
424
gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), tmp_button);
425
g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_template), ft);
278
item = gtk_menu_item_new_with_label(_("Old"));
279
menu = gtk_menu_new();
280
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
281
gtk_widget_show_all(item);
282
gtk_container_add(GTK_CONTAINER(new_with_template_menu), item);
284
item = gtk_menu_item_new_with_label(ft->title);
285
gtk_widget_show(item);
286
gtk_container_add(GTK_CONTAINER(menu), item);
287
g_signal_connect(item, "activate", G_CALLBACK(on_new_with_filetype_template), ft);
294
void templates_replace_common(GString *template, const gchar *fname,
295
GeanyFiletype *ft, const gchar *func_name)
302
shortname = g_strdup(GEANY_STRING_UNTITLED);
304
shortname = g_strconcat(GEANY_STRING_UNTITLED, ".", ft->extension, NULL);
307
shortname = g_path_get_basename(fname);
309
templates_replace_valist(template,
310
"{filename}", shortname,
311
"{project}", app->project ? app->project->name : "",
312
"{description}", app->project ? app->project->description : "",
316
templates_replace_default_dates(template);
317
templates_replace_command(template, fname, ft->name, func_name);
318
/* Bug: command results could have {ob} {cb} strings in! */
319
/* replace braces last */
320
templates_replace_valist(template,
438
335
if (content != NULL)
440
337
gchar *file_header;
441
gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
442
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
443
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
445
339
template = g_string_new(content);
447
file_header = templates_get_template_fileheader(FILETYPE_ID(ft), doc_filename);
448
templates_replace_all(template, year, date, datetime);
449
utils_string_replace_all(template, "{filename}", doc_filename);
450
utils_string_replace_all(template, "{fileheader}", file_header);
341
file_header = get_template_fileheader(ft);
342
templates_replace_valist(template,
343
"{fileheader}", file_header,
345
templates_replace_common(template, doc_filename, ft, NULL);
452
utils_free_pointers(5, year, date, datetime, file_header, content, NULL);
347
utils_free_pointers(2, file_header, content, NULL);
348
return g_string_free(template, FALSE);
454
return g_string_free(template, FALSE);
461
357
gchar *fname = ui_menu_item_get_text(menuitem);
462
358
GeanyFiletype *ft;
464
gchar *extension = strrchr(fname, '.'); /* easy way to get the file extension */
360
const gchar *extension = strrchr(fname, '.'); /* easy way to get the file extension */
465
361
gchar *new_filename = g_strconcat(GEANY_STRING_UNTITLED, extension, NULL);
467
364
ft = filetypes_detect_from_extension(fname);
468
365
setptr(fname, utils_get_locale_from_utf8(fname));
469
367
/* fname is just the basename from the menu item, so prepend the custom files path */
470
setptr(fname, g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_TEMPLATES_SUBDIR,
471
"files", fname, NULL));
472
template = get_template_from_file(fname, new_filename, ft);
368
path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_TEMPLATES_SUBDIR,
369
"files", fname, NULL);
370
template = get_template_from_file(path, new_filename, ft);
373
/* try the system path */
375
path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_TEMPLATES_SUBDIR,
376
"files", fname, NULL);
377
template = get_template_from_file(path, new_filename, ft);
380
document_new_file(new_filename, ft, template);
383
setptr(fname, utils_get_utf8_from_locale(fname));
384
ui_set_statusbar(TRUE, _("Could not find file '%s'."), fname);
388
g_free(new_filename);
475
document_new_file(new_filename, ft, template);
477
g_free(new_filename);
481
static void add_file_item(gpointer data, gpointer user_data)
393
static void add_file_item(const gchar *fname, GtkWidget *menu)
483
GtkWidget *tmp_menu, *tmp_button;
484
GtkWidget *toolbar_new_file_menu = user_data;
395
GtkWidget *tmp_button;
487
g_return_if_fail(data);
489
label = utils_get_utf8_from_locale(data);
491
tmp_menu = gtk_menu_item_new_with_label(label);
492
gtk_widget_show(tmp_menu);
493
gtk_container_add(GTK_CONTAINER(new_with_template_menu), tmp_menu);
494
g_signal_connect(tmp_menu, "activate", G_CALLBACK(on_new_with_file_template), NULL);
398
g_return_if_fail(fname);
399
g_return_if_fail(menu);
401
label = utils_get_utf8_from_locale(fname);
496
403
tmp_button = gtk_menu_item_new_with_label(label);
497
404
gtk_widget_show(tmp_button);
498
gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), tmp_button);
405
gtk_container_add(GTK_CONTAINER(menu), tmp_button);
499
406
g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_file_template), NULL);
505
static gint compare_filenames_by_filetype(gconstpointer a, gconstpointer b)
507
GeanyFiletype *ft_a = filetypes_detect_from_extension(a);
508
GeanyFiletype *ft_b = filetypes_detect_from_extension(b);
510
/* sort by filetype name first */
511
if (G_LIKELY(ft_a != ft_b))
513
/* None filetypes should come first */
514
if (G_UNLIKELY(ft_a->id == GEANY_FILETYPES_NONE))
516
if (G_UNLIKELY(ft_b->id == GEANY_FILETYPES_NONE))
519
return utils_str_casecmp(ft_a->name, ft_b->name);
521
return utils_str_casecmp(a, b);
525
static gboolean add_custom_template_items(GtkWidget *toolbar_new_file_menu)
527
gchar *path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_TEMPLATES_SUBDIR,
529
GSList *list = utils_get_file_list(path, NULL, NULL);
533
utils_mkdir(path, FALSE);
536
list = g_slist_sort(list, compare_filenames_by_filetype);
537
g_slist_foreach(list, add_file_item, toolbar_new_file_menu);
538
g_slist_foreach(list, (GFunc) g_free, NULL);
412
static gboolean add_custom_template_items(void)
414
GSList *list = utils_get_config_files(GEANY_TEMPLATES_SUBDIR G_DIR_SEPARATOR_S "files");
417
foreach_slist(node, list)
419
gchar *fname = node->data;
421
add_file_item(fname, new_with_template_menu);
539
424
g_slist_free(list);
545
static void create_file_template_menus(void)
429
static void create_file_template_menu(void)
547
GtkWidget *sep1, *sep2 = NULL;
548
GtkWidget *toolbar_new_file_menu = NULL;
550
new_with_template_menu = ui_lookup_widget(main_widgets.window, "menu_new_with_template1_menu");
551
toolbar_new_file_menu = gtk_menu_new();
552
/* we hold our own ref on the menu in case it is not used in the toolbar */
553
g_object_ref(toolbar_new_file_menu);
555
create_new_menu_items(toolbar_new_file_menu);
557
sep1 = gtk_separator_menu_item_new();
558
gtk_container_add(GTK_CONTAINER(new_with_template_menu), sep1);
559
sep2 = gtk_separator_menu_item_new();
560
gtk_container_add(GTK_CONTAINER(toolbar_new_file_menu), sep2);
562
if (add_custom_template_items(toolbar_new_file_menu))
564
gtk_widget_show(sep1);
565
gtk_widget_show(sep2);
431
GtkWidget *sep = NULL;
433
new_with_template_menu = gtk_menu_new();
435
if (add_custom_template_items())
437
sep = gtk_separator_menu_item_new();
438
gtk_container_add(GTK_CONTAINER(new_with_template_menu), sep);
440
if (create_new_filetype_items() && sep)
442
gtk_widget_show(sep);
444
/* unless the file menu is showing, menu should be in the toolbar widget */
568
445
geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION(
569
toolbar_get_action_by_name("New")), toolbar_new_file_menu);
446
toolbar_get_action_by_name("New")), new_with_template_menu);
450
static void on_file_menu_show(GtkWidget *item)
452
geany_menu_button_action_set_menu(
453
GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")), NULL);
454
item = ui_lookup_widget(main_widgets.window, "menu_new_with_template1");
455
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), new_with_template_menu);
459
static void on_file_menu_hide(GtkWidget *item)
461
item = ui_lookup_widget(main_widgets.window, "menu_new_with_template1");
462
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), NULL);
463
geany_menu_button_action_set_menu(
464
GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")), new_with_template_menu);
468
/* reload templates if any file in the templates path is saved */
469
static void on_document_save(G_GNUC_UNUSED GObject *object, GeanyDocument *doc)
471
const gchar *path = utils_build_path(app->configdir, GEANY_TEMPLATES_SUBDIR, NULL);
473
g_return_if_fail(NZV(doc->real_path));
475
if (strncmp(doc->real_path, path, strlen(path)) == 0)
477
/* reload templates */
478
templates_free_templates();
484
/* warning: also called when reloading template settings */
573
485
void templates_init(void)
575
487
gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
576
488
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
577
489
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
490
static gboolean init_done = FALSE;
579
492
init_general_templates(year, date, datetime);
580
493
init_ft_templates(year, date, datetime);
667
gchar *templates_get_template_licence(gint filetype_idx, gint licence_type)
669
if (licence_type != GEANY_TEMPLATE_GPL && licence_type != GEANY_TEMPLATE_BSD)
672
return make_comment_block(templates[licence_type], filetype_idx, 8);
597
gchar *templates_get_template_licence(GeanyDocument *doc, gint licence_type)
600
gchar *result = NULL;
602
g_return_val_if_fail(doc != NULL, NULL);
603
g_return_val_if_fail(licence_type == GEANY_TEMPLATE_GPL || licence_type == GEANY_TEMPLATE_BSD, NULL);
605
template = g_string_new(templates[licence_type]);
606
replace_static_values(template);
607
templates_replace_default_dates(template);
608
templates_replace_command(template, DOC_FILENAME(doc), doc->file_type->name, NULL);
610
result = make_comment_block(template->str, FILETYPE_ID(doc->file_type), 8);
612
g_string_free(template, TRUE);
618
static gchar *get_template_fileheader(GeanyFiletype *ft)
620
GString *template = g_string_new(templates[GEANY_TEMPLATE_FILEHEADER]);
623
filetypes_load_config(ft->id, FALSE); /* load any user extension setting */
625
templates_replace_valist(template,
626
"{gpl}", templates[GEANY_TEMPLATE_GPL],
627
"{bsd}", templates[GEANY_TEMPLATE_BSD],
630
/* we don't replace other wildcards here otherwise they would get done twice for files */
631
result = make_comment_block(template->str, ft->id, 8);
632
g_string_free(template, TRUE);
637
/* TODO change the signature to take a GeanyDocument? this would break plugin API/ABI */
676
638
gchar *templates_get_template_fileheader(gint filetype_idx, const gchar *fname)
678
gchar *template = g_strdup(templates[GEANY_TEMPLATE_FILEHEADER]);
681
gchar *date = utils_get_date_time(template_prefs.datetime_format, NULL);
682
filetype_id ft_id = filetype_idx;
683
GeanyFiletype *ft = filetypes[ft_id];
685
filetypes_load_config(ft_id, FALSE); /* load any user extension setting */
689
if (ft_id == GEANY_FILETYPES_NONE)
690
shortname = g_strdup(GEANY_STRING_UNTITLED);
692
shortname = g_strconcat(GEANY_STRING_UNTITLED, ".", ft->extension, NULL);
695
shortname = g_path_get_basename(fname);
697
utils_str_replace_all(&template, "{filename}", shortname);
698
utils_str_replace_all(&template, "{gpl}", templates[GEANY_TEMPLATE_GPL]);
699
utils_str_replace_all(&template, "{bsd}", templates[GEANY_TEMPLATE_BSD]);
700
utils_str_replace_all(&template, "{datetime}", date);
702
result = make_comment_block(template, ft_id, 8);
711
static gchar *get_file_template(GeanyFiletype *ft)
713
filetype_id ft_id = FILETYPE_ID(ft);
715
return g_strdup(ft_templates[ft_id]);
640
GeanyFiletype *ft = filetypes[filetype_idx];
641
gchar *str = get_template_fileheader(ft);
642
GString *template = g_string_new(str);
645
templates_replace_common(template, fname, ft, NULL);
646
return g_string_free(template, FALSE);
719
650
gchar *templates_get_template_new_file(GeanyFiletype *ft)
721
gchar *ft_template = NULL;
652
GString *ft_template;
722
653
gchar *file_header = NULL;
655
g_return_val_if_fail(ft != NULL, NULL);
656
g_return_val_if_fail(ft->id < GEANY_MAX_BUILT_IN_FILETYPES, NULL);
658
ft_template = g_string_new(ft_templates[ft->id]);
724
659
if (FILETYPE_ID(ft) == GEANY_FILETYPES_NONE)
725
return get_file_template(ft);
661
replace_static_values(ft_template);
664
{ /* file template only used for new files */
665
file_header = get_template_fileheader(ft);
666
templates_replace_valist(ft_template, "{fileheader}", file_header, NULL);
668
templates_replace_common(ft_template, NULL, ft, NULL);
727
file_header = templates_get_template_fileheader(ft->id, NULL); /* file template only used for new files */
728
ft_template = get_file_template(ft);
729
utils_str_replace_all(&ft_template, "{fileheader}", file_header);
730
670
g_free(file_header);
735
gchar *templates_get_template_generic(gint template)
737
return g_strdup(templates[template]);
741
gchar *templates_get_template_function(gint filetype_idx, const gchar *func_name)
743
gchar *template = g_strdup(templates[GEANY_TEMPLATE_FUNCTION]);
744
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
745
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
671
return g_string_free(ft_template, FALSE);
675
gchar *templates_get_template_function(GeanyDocument *doc, const gchar *func_name)
748
utils_str_replace_all(&template, "{date}", date);
749
utils_str_replace_all(&template, "{datetime}", datetime);
750
utils_str_replace_all(&template, "{functionname}", (func_name) ? func_name : "");
752
result = make_comment_block(template, filetype_idx, 3);
680
func_name = (func_name != NULL) ? func_name : "";
681
text = g_string_new(templates[GEANY_TEMPLATE_FUNCTION]);
683
templates_replace_valist(text, "{functionname}", func_name, NULL);
684
templates_replace_default_dates(text);
685
templates_replace_command(text, DOC_FILENAME(doc), doc->file_type->name, func_name);
687
result = make_comment_block(text->str, doc->file_type->id, 3);
689
g_string_free(text, TRUE);
761
gchar *templates_get_template_changelog(void)
694
gchar *templates_get_template_changelog(GeanyDocument *doc)
763
gchar *date = utils_get_date_time(template_prefs.datetime_format, NULL);
764
gchar *result = g_strdup(templates[GEANY_TEMPLATE_CHANGELOG]);
766
utils_str_replace_all(&result, "{date}", date);
696
GString *result = g_string_new(templates[GEANY_TEMPLATE_CHANGELOG]);
697
const gchar *file_type_name = (doc != NULL) ? doc->file_type->name : "";
699
replace_static_values(result);
700
templates_replace_default_dates(result);
701
templates_replace_command(result, DOC_FILENAME(doc), file_type_name, NULL);
703
return g_string_free(result, FALSE);
786
723
g_free(ft_templates[i]);
788
725
/* destroy "New with template" sub menu items (in case we want to reload the templates) */
789
children = gtk_container_get_children(GTK_CONTAINER(toolbar_new_file_menu));
790
foreach_list(item, children)
792
gtk_widget_destroy(GTK_WIDGET(item->data));
794
g_object_unref(toolbar_new_file_menu);
795
726
children = gtk_container_get_children(GTK_CONTAINER(new_with_template_menu));
796
727
foreach_list(item, children)
798
729
gtk_widget_destroy(GTK_WIDGET(item->data));
731
g_list_free(children);
733
g_object_unref(new_with_template_menu);
734
new_with_template_menu = NULL;
803
void templates_replace_all(GString *text, const gchar *year, const gchar *date,
804
const gchar *datetime)
738
static void replace_static_values(GString *text)
806
utils_string_replace_all(text, "{year}", year);
807
utils_string_replace_all(text, "{date}", date);
808
utils_string_replace_all(text, "{datetime}", datetime);
809
740
utils_string_replace_all(text, "{version}", template_prefs.version);
810
741
utils_string_replace_all(text, "{initial}", template_prefs.initials);
811
742
utils_string_replace_all(text, "{developer}", template_prefs.developer);
815
746
utils_string_replace_all(text, "{geanyversion}", "Geany " VERSION);
750
/* Replaces all static template wildcards (version, mail, company, name, ...)
751
* plus those wildcard, value pairs which are passed, e.g.
753
* templates_replace_valist(text, "{some_wildcard}", "some value",
754
* "{another_wildcard}", "another value", NULL);
756
* The argument list must be terminated with NULL. */
757
void templates_replace_valist(GString *text, const gchar *first_wildcard, ...)
760
const gchar *key, *value;
762
g_return_if_fail(text != NULL);
764
va_start(args, first_wildcard);
766
key = first_wildcard;
767
value = va_arg(args, gchar*);
771
utils_string_replace_all(text, key, value);
773
key = va_arg(args, gchar*);
774
if (key == NULL || text == NULL)
776
value = va_arg(args, gchar*);
780
replace_static_values(text);
784
static void templates_replace_default_dates(GString *text)
786
gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
787
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
788
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
790
g_return_if_fail(text != NULL);
792
templates_replace_valist(text,
795
"{datetime}", datetime,
798
utils_free_pointers(3, year, date, datetime, NULL);
802
static gchar *run_command(const gchar *command, const gchar *file_name,
803
const gchar *file_type, const gchar *func_name)
805
gchar *result = NULL;
808
if (g_shell_parse_argv(command, NULL, &argv, NULL))
810
GError *error = NULL;
813
file_name = (file_name != NULL) ? file_name : "";
814
file_type = (file_type != NULL) ? file_type : "";
815
func_name = (func_name != NULL) ? func_name : "";
817
env = utils_copy_environment(NULL,
818
"GEANY_FILENAME", file_name,
819
"GEANY_FILETYPE", file_type,
820
"GEANY_FUNCNAME", func_name,
822
if (! utils_spawn_sync(NULL, argv, env, G_SPAWN_SEARCH_PATH,
823
NULL, NULL, &result, NULL, NULL, &error))
825
g_warning("templates_replace_command: %s", error->message);
836
static void templates_replace_command(GString *text, const gchar *file_name,
837
const gchar *file_type, const gchar *func_name)
840
gchar *wildcard = NULL;
844
g_return_if_fail(text != NULL);
846
while ((match = strstr(text->str, "{command:")) != NULL)
849
while (*match != '}' && *match != '\0')
852
wildcard = g_strndup(cmd, match - cmd + 1);
853
cmd = g_strndup(wildcard + 9, strlen(wildcard) - 10);
855
result = run_command(cmd, file_name, file_type, func_name);
858
utils_string_replace_first(text, wildcard, result);
862
utils_string_replace_first(text, wildcard, "");