Fix and unify getting open/close/single comment markers

Add filetype_get_comment_open_close() to get appropriate start and end
comment markers from a filetype, and use it everywhere these markers
are fetched.

This fixes a crash in editor_insert_multiline_comment() if only single
comments are available (closes #3449635).
This commit is contained in:
Colomban Wendling 2011-12-04 00:16:31 +01:00
parent 903e69b388
commit c69b8eea23
4 changed files with 71 additions and 52 deletions

View File

@ -2768,7 +2768,8 @@ static GeanyFiletype *editor_get_filetype_at_current_pos(GeanyEditor *editor)
static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint last_line) static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint last_line)
{ {
const gchar *eol; const gchar *eol;
gchar *str_begin, *str_end, *co, *cc; gchar *str_begin, *str_end;
const gchar *co, *cc;
gint line_len; gint line_len;
GeanyFiletype *ft; GeanyFiletype *ft;
@ -2777,8 +2778,8 @@ static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint la
ft = editor_get_filetype_at_current_pos(editor); ft = editor_get_filetype_at_current_pos(editor);
eol = editor_get_eol_char(editor); eol = editor_get_eol_char(editor);
co = ft->comment_open; if (! filetype_get_comment_open_close(ft, FALSE, &co, &cc))
cc = ft->comment_close; g_return_if_reached();
str_begin = g_strdup_printf("%s%s", (co != NULL) ? co : "", eol); str_begin = g_strdup_printf("%s%s", (co != NULL) ? co : "", eol);
str_end = g_strdup_printf("%s%s", (cc != NULL) ? cc : "", eol); str_end = g_strdup_printf("%s%s", (cc != NULL) ? cc : "", eol);
@ -2799,14 +2800,17 @@ static void real_uncomment_multiline(GeanyEditor *editor)
gchar *linebuf; gchar *linebuf;
GeanyDocument *doc; GeanyDocument *doc;
GeanyFiletype *ft; GeanyFiletype *ft;
const gchar *co, *cc;
g_return_if_fail(editor != NULL && editor->document->file_type != NULL); g_return_if_fail(editor != NULL && editor->document->file_type != NULL);
doc = editor->document; doc = editor->document;
ft = editor_get_filetype_at_current_pos(editor); ft = editor_get_filetype_at_current_pos(editor);
if (! filetype_get_comment_open_close(ft, FALSE, &co, &cc))
g_return_if_reached();
/* remove comment open chars */ /* remove comment open chars */
pos = document_find_text(doc, ft->comment_open, NULL, 0, TRUE, FALSE, NULL); pos = document_find_text(doc, co, NULL, 0, TRUE, FALSE, NULL);
SSM(editor->sci, SCI_DELETEBACK, 0, 0); SSM(editor->sci, SCI_DELETEBACK, 0, 0);
/* check whether the line is empty and can be deleted */ /* check whether the line is empty and can be deleted */
@ -2819,7 +2823,7 @@ static void real_uncomment_multiline(GeanyEditor *editor)
g_free(linebuf); g_free(linebuf);
/* remove comment close chars */ /* remove comment close chars */
pos = document_find_text(doc, ft->comment_close, NULL, 0, FALSE, FALSE, NULL); pos = document_find_text(doc, cc, NULL, 0, FALSE, FALSE, NULL);
SSM(editor->sci, SCI_DELETEBACK, 0, 0); SSM(editor->sci, SCI_DELETEBACK, 0, 0);
/* check whether the line is empty and can be deleted */ /* check whether the line is empty and can be deleted */
@ -2874,7 +2878,8 @@ gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle)
gint sel_start, sel_end; gint sel_start, sel_end;
gint count = 0; gint count = 0;
gsize co_len; gsize co_len;
gchar sel[256], *co, *cc; gchar sel[256];
const gchar *co, *cc;
gboolean single_line = FALSE; gboolean single_line = FALSE;
GeanyFiletype *ft; GeanyFiletype *ft;
@ -2900,16 +2905,8 @@ gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle)
ft = editor_get_filetype_at_current_pos(editor); ft = editor_get_filetype_at_current_pos(editor);
eol_char_len = editor_get_eol_char_len(editor); eol_char_len = editor_get_eol_char_len(editor);
co = ft->comment_single; if (! filetype_get_comment_open_close(ft, TRUE, &co, &cc))
if (NZV(co)) return 0;
cc = NULL;
else
{
co = ft->comment_open;
cc = ft->comment_close;
if (co == NULL)
return 0;
}
co_len = strlen(co); co_len = strlen(co);
if (co_len == 0) if (co_len == 0)
@ -3007,7 +3004,8 @@ void editor_do_comment_toggle(GeanyEditor *editor)
gint x, i, line_start, line_len, first_line_start; gint x, i, line_start, line_len, first_line_start;
gint sel_start, sel_end; gint sel_start, sel_end;
gint count_commented = 0, count_uncommented = 0; gint count_commented = 0, count_uncommented = 0;
gchar sel[256], *co, *cc; gchar sel[256];
const gchar *co, *cc;
gboolean break_loop = FALSE, single_line = FALSE; gboolean break_loop = FALSE, single_line = FALSE;
gboolean first_line_was_comment = FALSE; gboolean first_line_was_comment = FALSE;
gsize co_len; gsize co_len;
@ -3032,16 +3030,8 @@ void editor_do_comment_toggle(GeanyEditor *editor)
ft = editor_get_filetype_at_current_pos(editor); ft = editor_get_filetype_at_current_pos(editor);
co = ft->comment_single; if (! filetype_get_comment_open_close(ft, TRUE, &co, &cc))
if (NZV(co)) return;
cc = NULL;
else
{
co = ft->comment_open;
cc = ft->comment_close;
if (co == NULL)
return;
}
co_len = strlen(co); co_len = strlen(co);
if (co_len == 0) if (co_len == 0)
@ -3168,7 +3158,8 @@ void editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_line
gint first_line, last_line, eol_char_len; gint first_line, last_line, eol_char_len;
gint x, i, line_start, line_len; gint x, i, line_start, line_len;
gint sel_start, sel_end, co_len; gint sel_start, sel_end, co_len;
gchar sel[256], *co, *cc; gchar sel[256];
const gchar *co, *cc;
gboolean break_loop = FALSE, single_line = FALSE; gboolean break_loop = FALSE, single_line = FALSE;
GeanyFiletype *ft; GeanyFiletype *ft;
@ -3195,16 +3186,8 @@ void editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_line
ft = editor_get_filetype_at_current_pos(editor); ft = editor_get_filetype_at_current_pos(editor);
co = ft->comment_single; if (! filetype_get_comment_open_close(ft, TRUE, &co, &cc))
if (NZV(co)) return;
cc = NULL;
else
{
co = ft->comment_open;
cc = ft->comment_close;
if (co == NULL)
return;
}
co_len = strlen(co); co_len = strlen(co);
if (co_len == 0) if (co_len == 0)
@ -3232,7 +3215,7 @@ void editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_line
if (allow_empty_lines || (x < line_len && sel[x] != '\0')) if (allow_empty_lines || (x < line_len && sel[x] != '\0'))
{ {
/* use single line comment */ /* use single line comment */
if (cc == NULL || cc[0] == '\0') if (! NZV(cc))
{ {
gint start = line_start; gint start = line_start;
single_line = TRUE; single_line = TRUE;
@ -3493,18 +3476,19 @@ void editor_insert_multiline_comment(GeanyEditor *editor)
gint pos; gint pos;
gboolean have_multiline_comment = FALSE; gboolean have_multiline_comment = FALSE;
GeanyDocument *doc; GeanyDocument *doc;
const gchar *co, *cc;
g_return_if_fail(editor != NULL && editor->document->file_type != NULL && g_return_if_fail(editor != NULL && editor->document->file_type != NULL);
(editor->document->file_type->comment_open != NULL ||
editor->document->file_type->comment_single != NULL)); if (! filetype_get_comment_open_close(editor->document->file_type, FALSE, &co, &cc))
g_return_if_reached();
if (NZV(cc))
have_multiline_comment = TRUE;
sci_start_undo_action(editor->sci); sci_start_undo_action(editor->sci);
doc = editor->document; doc = editor->document;
if (NZV(doc->file_type->comment_close))
have_multiline_comment = TRUE;
/* insert three lines one line above of the current position */ /* insert three lines one line above of the current position */
line = sci_get_line_from_position(editor->sci, editor_info.click_pos); line = sci_get_line_from_position(editor->sci, editor_info.click_pos);
pos = sci_get_position_from_line(editor->sci, line); pos = sci_get_position_from_line(editor->sci, line);
@ -3533,7 +3517,7 @@ void editor_insert_multiline_comment(GeanyEditor *editor)
editor_do_comment(editor, -1, TRUE, FALSE); editor_do_comment(editor, -1, TRUE, FALSE);
/* set the current position to the start of the first inserted line */ /* set the current position to the start of the first inserted line */
pos += strlen(doc->file_type->comment_open); pos += strlen(co);
/* on multi line comment jump to the next line, otherwise add the length of added indentation */ /* on multi line comment jump to the next line, otherwise add the length of added indentation */
if (have_multiline_comment) if (have_multiline_comment)

View File

@ -1791,3 +1791,40 @@ const gchar *filetypes_get_display_name(GeanyFiletype *ft)
{ {
return ft->id == GEANY_FILETYPES_NONE ? _("None") : ft->name; return ft->id == GEANY_FILETYPES_NONE ? _("None") : ft->name;
} }
/* gets comment_open/comment_close/comment_single strings from the filetype
* @param single_first: whether single comment is preferred if both available
* returns true if at least comment_open is set, false otherwise */
gboolean filetype_get_comment_open_close(const GeanyFiletype *ft, gboolean single_first,
const gchar **co, const gchar **cc)
{
g_return_val_if_fail(ft != NULL, FALSE);
g_return_val_if_fail(co != NULL, FALSE);
g_return_val_if_fail(cc != NULL, FALSE);
if (single_first)
{
*co = ft->comment_single;
if (NZV(*co))
*cc = NULL;
else
{
*co = ft->comment_open;
*cc = ft->comment_close;
}
}
else
{
*co = ft->comment_open;
if (NZV(*co))
*cc = ft->comment_close;
else
{
*co = ft->comment_single;
*cc = NULL;
}
}
return NZV(*co);
}

View File

@ -209,4 +209,7 @@ gboolean filetype_has_tags(GeanyFiletype *ft);
gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message, gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message,
gchar **filename, gint *line); gchar **filename, gint *line);
gboolean filetype_get_comment_open_close(const GeanyFiletype *ft, gboolean single_first,
const gchar **co, const gchar **cc);
#endif #endif

View File

@ -364,12 +364,7 @@ static void make_comment_block(GString *comment_text, gint filetype_idx, guint i
template_eol_mode = utils_get_line_endings(comment_text->str, comment_text->len); template_eol_mode = utils_get_line_endings(comment_text->str, comment_text->len);
template_eol_char = utils_get_eol_char(template_eol_mode); template_eol_char = utils_get_eol_char(template_eol_mode);
co = ft->comment_open; filetype_get_comment_open_close(ft, FALSE, &co, &cc);
cc = NULL;
if (NZV(co))
cc = ft->comment_close;
else
co = ft->comment_single;
if (NZV(co)) if (NZV(co))
{ {
if (NZV(cc)) if (NZV(cc))