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:
parent
903e69b388
commit
c69b8eea23
76
src/editor.c
76
src/editor.c
@ -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)
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user