Skip to content

Commit

Permalink
Detect HTML embedded filetypes from the current line
Browse files Browse the repository at this point in the history
When using the commenting features (ex. toggle line commentation),
detect the the type of comments for the filetype of the line with
the caret rather than using the filetype of the current document.

Filetype is determined by the Scintilla state/style at the
beginning of the line where the caret is.

This does not fix the existing bug where using the commenting
features on lines with things like `<script>` will result in an
HTML-style comment to be wrapped around it and also where using
the commenting feature on a line with something like `<?php`
will not only wrap it in an HTML-style comment but it also won't
be able to uncomment the line.

This closes bug ID 2863829[1] and 3127598[2].

[1] https://sourceforge.net/tracker/?func=detail&aid=2863829&group_id=153444&atid=787791
[2] https://sourceforge.net/tracker/?func=detail&aid=3127598&group_id=153444&atid=787791
  • Loading branch information
codebrainz committed Oct 13, 2011
1 parent cbadf17 commit 4fb9629
Showing 1 changed file with 69 additions and 28 deletions.
97 changes: 69 additions & 28 deletions src/editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ static gsize count_indent_size(GeanyEditor *editor, const gchar *base_indent);
static const gchar *snippets_find_completion_by_name(const gchar *type, const gchar *name);
static void snippets_make_replacements(GeanyEditor *editor, GString *pattern);
static gssize replace_cursor_markers(GeanyEditor *editor, GString *pattern);
static GeanyFiletype *editor_get_filetype_at_current_pos(GeanyEditor *editor);


void editor_snippets_free(void)
Expand Down Expand Up @@ -2711,17 +2712,74 @@ static gsize count_indent_size(GeanyEditor *editor, const gchar *base_indent)
}


/* Handles special cases where HTML is embedded in another language or
* another language is embedded in HTML */
static GeanyFiletype *editor_get_filetype_at_current_pos(GeanyEditor *editor)
{
gint style, line_start;
GeanyFiletype *current_ft;

g_return_val_if_fail(editor != NULL, NULL);
g_return_val_if_fail(editor->document->file_type != NULL, NULL);

current_ft = editor->document->file_type;
line_start = sci_get_position_from_line(editor->sci, sci_get_current_line(editor->sci));
style = sci_get_style_at(editor->sci, line_start);

/* Handle PHP filetype with embedded HTML */
if (current_ft->id == GEANY_FILETYPES_PHP && ! is_style_php(style))
current_ft = filetypes[GEANY_FILETYPES_HTML];

/* Handle languages embedded in HTML */
if (current_ft->id == GEANY_FILETYPES_HTML)
{
/* Embedded JS */
if (style >= SCE_HJ_DEFAULT && style <= SCE_HJ_REGEX)
current_ft = filetypes[GEANY_FILETYPES_JS];
/* ASP JS */
else if (style >= SCE_HJA_DEFAULT && style <= SCE_HJA_REGEX)
current_ft = filetypes[GEANY_FILETYPES_JS];
/* Embedded VB */
else if (style >= SCE_HB_DEFAULT && style <= SCE_HB_STRINGEOL)
current_ft = filetypes[GEANY_FILETYPES_BASIC];
/* ASP VB */
else if (style >= SCE_HBA_DEFAULT && style <= SCE_HBA_STRINGEOL)
current_ft = filetypes[GEANY_FILETYPES_BASIC];
/* Embedded Python */
else if (style >= SCE_HP_DEFAULT && style <= SCE_HP_IDENTIFIER)
current_ft = filetypes[GEANY_FILETYPES_PYTHON];
/* ASP Python */
else if (style >= SCE_HPA_DEFAULT && style <= SCE_HPA_IDENTIFIER)
current_ft = filetypes[GEANY_FILETYPES_PYTHON];
/* Embedded PHP */
else if ((style >= SCE_HPHP_DEFAULT && style <= SCE_HPHP_OPERATOR) ||
style == SCE_HPHP_COMPLEX_VARIABLE)
{
current_ft = filetypes[GEANY_FILETYPES_PHP];
}
}

/* Ensure the filetype's config is loaded */
filetypes_load_config(current_ft->id, FALSE);

return current_ft;
}


static void real_comment_multiline(GeanyEditor *editor, gint line_start, gint last_line)
{
const gchar *eol;
gchar *str_begin, *str_end, *co, *cc;
gint line_len;
GeanyFiletype *ft;

g_return_if_fail(editor != NULL && editor->document->file_type != NULL);

ft = editor_get_filetype_at_current_pos(editor);

eol = editor_get_eol_char(editor);
co = editor->document->file_type->comment_open;
cc = editor->document->file_type->comment_close;
co = ft->comment_open;
cc = ft->comment_close;
str_begin = g_strdup_printf("%s%s", (co != NULL) ? co : "", eol);
str_end = g_strdup_printf("%s%s", (cc != NULL) ? cc : "", eol);

Expand All @@ -2741,12 +2799,15 @@ static void real_uncomment_multiline(GeanyEditor *editor)
gint pos, line, len, x;
gchar *linebuf;
GeanyDocument *doc;
GeanyFiletype *ft;

g_return_if_fail(editor != NULL && editor->document->file_type != NULL);
doc = editor->document;

ft = editor_get_filetype_at_current_pos(editor);

/* remove comment open chars */
pos = document_find_text(doc, doc->file_type->comment_open, NULL, 0, TRUE, FALSE, NULL);
pos = document_find_text(doc, ft->comment_open, NULL, 0, TRUE, FALSE, NULL);
SSM(editor->sci, SCI_DELETEBACK, 0, 0);

/* check whether the line is empty and can be deleted */
Expand All @@ -2759,7 +2820,7 @@ static void real_uncomment_multiline(GeanyEditor *editor)
g_free(linebuf);

/* remove comment close chars */
pos = document_find_text(doc, doc->file_type->comment_close, NULL, 0, FALSE, FALSE, NULL);
pos = document_find_text(doc, ft->comment_close, NULL, 0, FALSE, FALSE, NULL);
SSM(editor->sci, SCI_DELETEBACK, 0, 0);

/* check whether the line is empty and can be deleted */
Expand Down Expand Up @@ -2837,17 +2898,9 @@ gint editor_do_uncomment(GeanyEditor *editor, gint line, gboolean toggle)
sel_start = sel_end = sci_get_position_from_line(editor->sci, line);
}

ft = editor->document->file_type;
ft = editor_get_filetype_at_current_pos(editor);
eol_char_len = editor_get_eol_char_len(editor);

/* detection of HTML vs PHP code, if non-PHP set filetype to XML */
line_start = sci_get_position_from_line(editor->sci, first_line);
if (ft->id == GEANY_FILETYPES_PHP)
{
if (! is_style_php(sci_get_style_at(editor->sci, line_start)))
ft = filetypes[GEANY_FILETYPES_XML];
}

co = ft->comment_single;
if (NZV(co))
cc = NULL;
Expand Down Expand Up @@ -2968,7 +3021,6 @@ void editor_do_comment_toggle(GeanyEditor *editor)
sel_start = sci_get_selection_start(editor->sci);
sel_end = sci_get_selection_end(editor->sci);

ft = editor->document->file_type;
eol_char_len = editor_get_eol_char_len(editor);

first_line = sci_get_line_from_position(editor->sci,
Expand All @@ -2978,13 +3030,9 @@ void editor_do_comment_toggle(GeanyEditor *editor)
sci_get_selection_end(editor->sci) - editor_get_eol_char_len(editor));
last_line = MAX(first_line, last_line);

/* detection of HTML vs PHP code, if non-PHP set filetype to XML */
first_line_start = sci_get_position_from_line(editor->sci, first_line);
if (ft->id == GEANY_FILETYPES_PHP)
{
if (! is_style_php(sci_get_style_at(editor->sci, first_line_start)))
ft = filetypes[GEANY_FILETYPES_XML];
}

ft = editor_get_filetype_at_current_pos(editor);

co = ft->comment_single;
if (NZV(co))
Expand Down Expand Up @@ -3145,16 +3193,9 @@ void editor_do_comment(GeanyEditor *editor, gint line, gboolean allow_empty_line
sel_start = sel_end = sci_get_position_from_line(editor->sci, line);
}

ft = editor->document->file_type;
eol_char_len = editor_get_eol_char_len(editor);

/* detection of HTML vs PHP code, if non-PHP set filetype to XML */
line_start = sci_get_position_from_line(editor->sci, first_line);
if (ft->id == GEANY_FILETYPES_PHP)
{
if (! is_style_php(sci_get_style_at(editor->sci, line_start)))
ft = filetypes[GEANY_FILETYPES_XML];
}
ft = editor_get_filetype_at_current_pos(editor);

co = ft->comment_single;
if (NZV(co))
Expand Down

0 comments on commit 4fb9629

Please sign in to comment.