diff --git a/ChangeLog b/ChangeLog index a3d3fe216..403a6142f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2008-07-15 Nick Treleaven + + * src/build.c, src/utils.c, src/utils.h, src/keybindings.c, + src/printing.c, src/tools.c, src/prefs.c, src/navqueue.c, + src/plugindata.h, src/treeviews.c, src/msgwindow.c, src/callbacks.c, + src/notebook.c, src/keyfile.c, src/filetypes.c, src/search.c, + src/document.c, src/document.h, src/main.c, src/editor.c, + src/symbols.c, src/editor.h, src/symbols.h, src/ui_utils.c, + plugins/export.c, plugins/vcdiff.c, plugins/htmlchars.c, + plugins/classbuilder.c: + Merge the editor-struct branch: + Note: this breaks the plugin API for editor-related document fields + and functions. + Split new GeanyEditor struct type from GeanyDocument fields sci, + line_wrapping, auto_indent, scroll_percent, use_tabs, line_breaking. + GeanyEditor::document allows access back to document fields. + Add GeanyDocument::editor field; this is only valid when the + document is valid, and NULL otherwise. This means any checks for + doc->editor->scintilla != NULL will segfault for invalid + documents - check against doc->is_valid or doc->editor != NULL + instead. + Change plugin API EditorFuncs to use GeanyEditor pointers. + Make editor_set_font() take a pango-style font string, and use a + GeanyEditor pointer. + Use GeanyEditor* instead of GeanyDocument* in editor.c (most global + editor functions still need conversion though, but this may be done + gradually or as required). + Move utils_get_current_function() to symbols.c. + Move utils_replace_filename() to document.c. + + 2008-07-14 Enrico Tröger * data/filetype_extensions.conf, data/filetypes.f77, diff --git a/plugins/classbuilder.c b/plugins/classbuilder.c index 1d4c8c9ef..84ed7dad5 100644 --- a/plugins/classbuilder.c +++ b/plugins/classbuilder.c @@ -30,6 +30,7 @@ #include "support.h" #include "filetypes.h" #include "document.h" +#include "editor.h" #include "ui_utils.h" #include "pluginmacros.h" @@ -732,7 +733,7 @@ static void cc_dlg_on_create_class(CreateClassDialog *cc_dlg) { text = get_template_class_source(class_info); doc = p_document->new_file(class_info->source, NULL, NULL); - p_sci->set_text(doc->sci, text); + p_sci->set_text(doc->editor->sci, text); g_free(text); } @@ -740,7 +741,7 @@ static void cc_dlg_on_create_class(CreateClassDialog *cc_dlg) { text = get_template_class_header(class_info); doc = p_document->new_file(class_info->header, NULL, NULL); - p_sci->set_text(doc->sci, text); + p_sci->set_text(doc->editor->sci, text); g_free(text); } diff --git a/plugins/export.c b/plugins/export.c index c0124492d..1f95b6df9 100644 --- a/plugins/export.c +++ b/plugins/export.c @@ -357,25 +357,25 @@ static void write_latex_file(GeanyDocument *doc, const gchar *filename, gboolean GString *body; GString *cmds; GString *latex; - gint style_max = pow(2, p_sci->send_message(doc->sci, SCI_GETSTYLEBITS, 0, 0)); + gint style_max = pow(2, p_sci->send_message(doc->editor->sci, SCI_GETSTYLEBITS, 0, 0)); /* first read all styles from Scintilla */ for (i = 0; i < style_max; i++) { - styles[i][FORE] = p_sci->send_message(doc->sci, SCI_STYLEGETFORE, i, 0); - styles[i][BACK] = p_sci->send_message(doc->sci, SCI_STYLEGETBACK, i, 0); - styles[i][BOLD] = p_sci->send_message(doc->sci, SCI_STYLEGETBOLD, i, 0); - styles[i][ITALIC] = p_sci->send_message(doc->sci, SCI_STYLEGETITALIC, i, 0); + styles[i][FORE] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETFORE, i, 0); + styles[i][BACK] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETBACK, i, 0); + styles[i][BOLD] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETBOLD, i, 0); + styles[i][ITALIC] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETITALIC, i, 0); styles[i][USED] = 0; } /* read the document and write the LaTeX code */ body = g_string_new(""); - for (i = 0; i < p_sci->get_length(doc->sci); i++) + for (i = 0; i < p_sci->get_length(doc->editor->sci); i++) { - style = p_sci->get_style_at(doc->sci, i); - c = p_sci->get_char_at(doc->sci, i); - c_next = p_sci->get_char_at(doc->sci, i + 1); + style = p_sci->get_style_at(doc->editor->sci, i); + c = p_sci->get_char_at(doc->editor->sci, i); + c_next = p_sci->get_char_at(doc->editor->sci, i + 1); if (style != old_style || ! block_open) { @@ -564,15 +564,15 @@ static void write_html_file(GeanyDocument *doc, const gchar *filename, gboolean GString *body; GString *css; GString *html; - gint style_max = pow(2, p_sci->send_message(doc->sci, SCI_GETSTYLEBITS, 0, 0)); + gint style_max = pow(2, p_sci->send_message(doc->editor->sci, SCI_GETSTYLEBITS, 0, 0)); /* first read all styles from Scintilla */ for (i = 0; i < style_max; i++) { - styles[i][FORE] = ROTATE_RGB(p_sci->send_message(doc->sci, SCI_STYLEGETFORE, i, 0)); - styles[i][BACK] = ROTATE_RGB(p_sci->send_message(doc->sci, SCI_STYLEGETBACK, i, 0)); - styles[i][BOLD] = p_sci->send_message(doc->sci, SCI_STYLEGETBOLD, i, 0); - styles[i][ITALIC] = p_sci->send_message(doc->sci, SCI_STYLEGETITALIC, i, 0); + styles[i][FORE] = ROTATE_RGB(p_sci->send_message(doc->editor->sci, SCI_STYLEGETFORE, i, 0)); + styles[i][BACK] = ROTATE_RGB(p_sci->send_message(doc->editor->sci, SCI_STYLEGETBACK, i, 0)); + styles[i][BOLD] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETBOLD, i, 0); + styles[i][ITALIC] = p_sci->send_message(doc->editor->sci, SCI_STYLEGETITALIC, i, 0); styles[i][USED] = 0; } @@ -581,18 +581,18 @@ static void write_html_file(GeanyDocument *doc, const gchar *filename, gboolean font_name = pango_font_description_get_family(font_desc); /*font_size = pango_font_description_get_size(font_desc) / PANGO_SCALE;*/ /* take the zoom level also into account */ - font_size = p_sci->send_message(doc->sci, SCI_STYLEGETSIZE, 0, 0); + font_size = p_sci->send_message(doc->editor->sci, SCI_STYLEGETSIZE, 0, 0); if (use_zoom) - font_size += p_sci->send_message(doc->sci, SCI_GETZOOM, 0, 0); + font_size += p_sci->send_message(doc->editor->sci, SCI_GETZOOM, 0, 0); /* read the document and write the HTML body */ body = g_string_new(""); - for (i = 0; i < p_sci->get_length(doc->sci); i++) + for (i = 0; i < p_sci->get_length(doc->editor->sci); i++) { - style = p_sci->get_style_at(doc->sci, i); - c = p_sci->get_char_at(doc->sci, i); + style = p_sci->get_style_at(doc->editor->sci, i); + c = p_sci->get_char_at(doc->editor->sci, i); /* p_sci->get_char_at() takes care of index boundaries and return 0 if i is too high */ - c_next = p_sci->get_char_at(doc->sci, i + 1); + c_next = p_sci->get_char_at(doc->editor->sci, i + 1); if ((style != old_style || ! span_open) && ! isspace(c)) { diff --git a/plugins/htmlchars.c b/plugins/htmlchars.c index d244ad672..9e2073f4f 100644 --- a/plugins/htmlchars.c +++ b/plugins/htmlchars.c @@ -28,6 +28,7 @@ #include "support.h" #include "plugindata.h" #include "document.h" +#include "editor.h" #include "keybindings.h" #include "ui_utils.h" #include "utils.h" @@ -445,12 +446,12 @@ static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter) if (doc != NULL) { gchar *str; - gint pos = p_sci->get_current_position(doc->sci); + gint pos = p_sci->get_current_position(doc->editor->sci); gtk_tree_model_get(model, iter, COLUMN_HTML_NAME, &str, -1); if (NZV(str)) { - p_sci->insert_text(doc->sci, pos, str); + p_sci->insert_text(doc->editor->sci, pos, str); g_free(str); result = TRUE; } diff --git a/plugins/vcdiff.c b/plugins/vcdiff.c index deda77806..b636dc466 100644 --- a/plugins/vcdiff.c +++ b/plugins/vcdiff.c @@ -33,6 +33,7 @@ #include "support.h" #include "plugindata.h" #include "document.h" +#include "editor.h" #include "filetypes.h" #include "utils.h" #include "project.h" @@ -284,9 +285,9 @@ static void show_output(const gchar *std_output, const gchar *utf8_name_prefix, } else { - p_sci->set_text(doc->sci, text); + p_sci->set_text(doc->editor->sci, text); book = GTK_NOTEBOOK(geany->main_widgets->notebook); - page = gtk_notebook_page_num(book, GTK_WIDGET(doc->sci)); + page = gtk_notebook_page_num(book, GTK_WIDGET(doc->editor->sci)); gtk_notebook_set_current_page(book, page); p_document->set_text_changed(doc, FALSE); } diff --git a/src/build.c b/src/build.c index d8f286d5c..9ed560a8c 100644 --- a/src/build.c +++ b/src/build.c @@ -380,7 +380,8 @@ static void clear_errors(GeanyDocument *doc) { case GBO_COMPILE: case GBO_MAKE_OBJECT: - editor_clear_indicators(doc); + g_return_if_fail(doc); + editor_clear_indicators(doc->editor); break; case GBO_BUILD: @@ -392,7 +393,7 @@ static void clear_errors(GeanyDocument *doc) for (i = 0; i < documents_array->len; i++) { if (documents[i]->is_valid) - editor_clear_indicators(documents[i]); + editor_clear_indicators(documents[i]->editor); } break; } @@ -858,7 +859,8 @@ static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data) { GeanyDocument *doc = document_find_by_filename(filename); - editor_set_indicator_on_line(doc, line - 1); /* will check valid idx */ + if (doc) + editor_set_indicator_on_line(doc->editor, line - 1); color = COLOR_RED; /* error message parsed on the line */ } g_free(filename); diff --git a/src/callbacks.c b/src/callbacks.c index 4bc7d4e50..5bb1df6b1 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -112,7 +112,7 @@ static void verify_click_pos(GeanyDocument *doc) { if (insert_callback_from_menu) { - editor_info.click_pos = sci_get_current_position(doc->sci); + editor_info.click_pos = sci_get_current_position(doc->editor->sci); insert_callback_from_menu = FALSE; } } @@ -305,7 +305,7 @@ on_cut1_activate (GtkMenuItem *menuitem, gtk_editable_cut_clipboard(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw) && doc != NULL) - sci_cut(doc->sci); + sci_cut(doc->editor->sci); else if (GTK_IS_TEXT_VIEW(focusw)) { @@ -327,7 +327,7 @@ on_copy1_activate (GtkMenuItem *menuitem, gtk_editable_copy_clipboard(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw) && doc != NULL) - sci_copy(doc->sci); + sci_copy(doc->editor->sci); else if (GTK_IS_TEXT_VIEW(focusw)) { @@ -360,12 +360,12 @@ on_paste1_activate (GtkMenuItem *menuitem, gchar *content = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_NONE)); if (content != NULL) { - sci_replace_sel(doc->sci, content); + sci_replace_sel(doc->editor->sci, content); g_free(content); } } #else - sci_paste(doc->sci); + sci_paste(doc->editor->sci); #endif } else @@ -390,7 +390,7 @@ on_delete1_activate (GtkMenuItem *menuitem, gtk_editable_delete_selection(GTK_EDITABLE(focusw)); else if (IS_SCINTILLA(focusw) && doc != NULL) - sci_clear(doc->sci); + sci_clear(doc->editor->sci); else if (GTK_IS_TEXT_VIEW(focusw)) { @@ -658,9 +658,9 @@ on_zoom_in1_activate (GtkMenuItem *menuitem, if (doc != NULL) { if (done++ % 3 == 0) - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, - (sci_get_zoom(doc->sci) / 2)); - sci_zoom_in(doc->sci); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, + (sci_get_zoom(doc->editor->sci) / 2)); + sci_zoom_in(doc->editor->sci); } } @@ -672,9 +672,9 @@ on_zoom_out1_activate (GtkMenuItem *menuitem, GeanyDocument *doc = document_get_current(); if (doc != NULL) { - if (sci_get_zoom(doc->sci) == 0) - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); - sci_zoom_out(doc->sci); + if (sci_get_zoom(doc->editor->sci) == 0) + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); + sci_zoom_out(doc->editor->sci); } } @@ -686,8 +686,8 @@ on_normal_size1_activate (GtkMenuItem *menuitem, GeanyDocument *doc = document_get_current(); if (doc != NULL) { - sci_zoom_off(doc->sci); - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); + sci_zoom_off(doc->editor->sci); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); } } @@ -779,8 +779,8 @@ on_crlf_activate (GtkMenuItem *menuitem, { GeanyDocument *doc = document_get_current(); if (ignore_callback || doc == NULL) return; - sci_convert_eols(doc->sci, SC_EOL_CRLF); - sci_set_eol_mode(doc->sci, SC_EOL_CRLF); + sci_convert_eols(doc->editor->sci, SC_EOL_CRLF); + sci_set_eol_mode(doc->editor->sci, SC_EOL_CRLF); } @@ -790,8 +790,8 @@ on_lf_activate (GtkMenuItem *menuitem, { GeanyDocument *doc = document_get_current(); if (ignore_callback || doc == NULL) return; - sci_convert_eols(doc->sci, SC_EOL_LF); - sci_set_eol_mode(doc->sci, SC_EOL_LF); + sci_convert_eols(doc->editor->sci, SC_EOL_LF); + sci_set_eol_mode(doc->editor->sci, SC_EOL_LF); } @@ -801,8 +801,8 @@ on_cr_activate (GtkMenuItem *menuitem, { GeanyDocument *doc = document_get_current(); if (ignore_callback || doc == NULL) return; - sci_convert_eols(doc->sci, SC_EOL_CR); - sci_set_eol_mode(doc->sci, SC_EOL_CR); + sci_convert_eols(doc->editor->sci, SC_EOL_CR); + sci_set_eol_mode(doc->editor->sci, SC_EOL_CR); } @@ -863,7 +863,7 @@ void on_toggle_case1_activate(GtkMenuItem *menuitem, gpointer user_data) if (doc == NULL) return; - sci = doc->sci; + sci = doc->editor->sci; if (! sci_can_copy(sci)) { keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_WORD); @@ -969,7 +969,7 @@ on_line_wrapping1_toggled (GtkCheckMenuItem *checkmenuitem, { GeanyDocument *doc = document_get_current(); if (doc != NULL) - editor_set_line_wrapping(doc, ! doc->line_wrapping); + editor_set_line_wrapping(doc->editor, ! doc->editor->line_wrapping); } } @@ -984,7 +984,7 @@ on_set_file_readonly1_toggled (GtkCheckMenuItem *checkmenuitem, if (doc == NULL) return; doc->readonly = ! doc->readonly; - sci_set_readonly(doc->sci, doc->readonly); + sci_set_readonly(doc->editor->sci, doc->readonly); ui_update_tab_status(doc); ui_update_statusbar(doc, -1); } @@ -999,7 +999,7 @@ on_use_auto_indentation1_toggled (GtkCheckMenuItem *checkmenuitem, { GeanyDocument *doc = document_get_current(); if (doc != NULL) - doc->auto_indent = ! doc->auto_indent; + doc->editor->auto_indent = ! doc->editor->auto_indent; } } @@ -1015,10 +1015,10 @@ on_find_usage1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - if (sci_can_copy(doc->sci)) + if (sci_can_copy(doc->editor->sci)) { /* take selected text if there is a selection */ - search_text = g_malloc(sci_get_selected_text_length(doc->sci) + 1); - sci_get_selected_text(doc->sci, search_text); + search_text = g_malloc(sci_get_selected_text_length(doc->editor->sci) + 1); + sci_get_selected_text(doc->editor->sci, search_text); flags = SCFIND_MATCHCASE; } else @@ -1042,7 +1042,7 @@ on_goto_tag_activate (GtkMenuItem *menuitem, g_return_if_fail(doc != NULL); - sci_set_current_position(doc->sci, editor_info.click_pos, FALSE); + sci_set_current_position(doc->editor->sci, editor_info.click_pos, FALSE); symbols_goto_tag(editor_info.current_word, definition); } @@ -1066,8 +1066,8 @@ on_show_color_chooser1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - pos = sci_get_current_position(doc->sci); - editor_find_current_word(doc->sci, pos, colour, sizeof colour, GEANY_WORDCHARS"#"); + pos = sci_get_current_position(doc->editor->sci); + editor_find_current_word(doc->editor->sci, pos, colour, sizeof colour, GEANY_WORDCHARS"#"); tools_color_chooser(colour); } @@ -1101,7 +1101,7 @@ static void find_again(gboolean change_direction) change_direction ? forward : !forward, FALSE, NULL); if (result > -1) - editor_display_current_line(doc, 0.3F); + editor_display_current_line(doc->editor, 0.3F); set_search_bar_background((result > -1) ? TRUE : FALSE); } @@ -1186,13 +1186,13 @@ on_goto_line_dialog_response (GtkDialog *dialog, GeanyDocument *doc = document_get_current(); gint line = strtol(gtk_entry_get_text(GTK_ENTRY(user_data)), NULL, 10); - if (doc != NULL && line > 0 && line <= sci_get_line_count(doc->sci)) + if (doc != NULL && line > 0 && line <= sci_get_line_count(doc->editor->sci)) { gint pos; line--; /* the user counts lines from 1, we begin at 0 so bring the user line to our one */ - pos = sci_get_position_from_line(doc->sci, line); - editor_goto_pos(doc, pos, TRUE); + pos = sci_get_position_from_line(doc->editor->sci, line); + editor_goto_pos(doc->editor, pos, TRUE); } else { @@ -1288,14 +1288,14 @@ on_comments_function_activate (GtkMenuItem *menuitem, return; } - /* utils_get_current_function returns -1 on failure, so sci_get_position_from_line + /* symbols_get_current_function returns -1 on failure, so sci_get_position_from_line * returns the current position, so it should be safe */ - line = utils_get_current_function(doc, &cur_tag); - pos = sci_get_position_from_line(doc->sci, line - 1); + line = symbols_get_current_function(doc, &cur_tag); + pos = sci_get_position_from_line(doc->editor->sci, line - 1); text = templates_get_template_function(doc->file_type->id, cur_tag); - sci_insert_text(doc->sci, pos, text); + sci_insert_text(doc->editor->sci, pos, text); g_free(text); } @@ -1333,7 +1333,7 @@ on_comments_gpl_activate (GtkMenuItem *menuitem, verify_click_pos(doc); /* make sure that the click_pos is valid */ - sci_insert_text(doc->sci, editor_info.click_pos, text); + sci_insert_text(doc->editor->sci, editor_info.click_pos, text); g_free(text); } @@ -1353,7 +1353,7 @@ on_comments_bsd_activate (GtkMenuItem *menuitem, verify_click_pos(doc); /* make sure that the click_pos is valid */ - sci_insert_text(doc->sci, editor_info.click_pos, text); + sci_insert_text(doc->editor->sci, editor_info.click_pos, text); g_free(text); } @@ -1370,10 +1370,10 @@ on_comments_changelog_activate (GtkMenuItem *menuitem, return; text = templates_get_template_changelog(); - sci_insert_text(doc->sci, 0, text); + sci_insert_text(doc->editor->sci, 0, text); /* sets the cursor to the right position to type the changelog text, * the template has 21 chars + length of name and email */ - sci_goto_pos(doc->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE); + sci_goto_pos(doc->editor->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE); g_free(text); } @@ -1394,8 +1394,8 @@ on_comments_fileheader_activate (GtkMenuItem *menuitem, fname = doc->file_name; text = templates_get_template_fileheader(FILETYPE_ID(ft), fname); - sci_insert_text(doc->sci, 0, text); - sci_goto_pos(doc->sci, 0, FALSE); + sci_insert_text(doc->editor->sci, 0, text); + sci_goto_pos(doc->editor->sci, 0, FALSE); g_free(text); } @@ -1456,8 +1456,8 @@ on_insert_date_activate (GtkMenuItem *menuitem, { verify_click_pos(doc); /* make sure that the click_pos is valid */ - sci_insert_text(doc->sci, editor_info.click_pos, time_str); - sci_goto_pos(doc->sci, editor_info.click_pos + strlen(time_str), FALSE); + sci_insert_text(doc->editor->sci, editor_info.click_pos, time_str); + sci_goto_pos(doc->editor->sci, editor_info.click_pos + strlen(time_str), FALSE); } else { @@ -1490,10 +1490,10 @@ on_insert_include_activate (GtkMenuItem *menuitem, text = g_strconcat("#include <", user_data, ">\n", NULL); } - sci_insert_text(doc->sci, editor_info.click_pos, text); + sci_insert_text(doc->editor->sci, editor_info.click_pos, text); g_free(text); if (pos >= 0) - sci_goto_pos(doc->sci, pos, FALSE); + sci_goto_pos(doc->editor->sci, pos, FALSE); } @@ -1548,7 +1548,7 @@ on_menu_remove_indicators1_activate (GtkMenuItem *menuitem, GeanyDocument *doc = document_get_current(); if (doc != NULL) - editor_clear_indicators(doc); + editor_clear_indicators(doc->editor); } @@ -1591,7 +1591,7 @@ on_menu_select_all1_activate (GtkMenuItem *menuitem, GeanyDocument *doc = document_get_current(); if (doc != NULL) - sci_select_all(doc->sci); + sci_select_all(doc->editor->sci); } @@ -1695,24 +1695,24 @@ on_menu_increase_indent1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - if (sci_get_lines_selected(doc->sci) > 1) + if (sci_get_lines_selected(doc->editor->sci) > 1) { - sci_cmd(doc->sci, SCI_TAB); + sci_cmd(doc->editor->sci, SCI_TAB); } else { gint line, ind_pos, old_pos, new_pos, step; - old_pos = sci_get_current_position(doc->sci); - line = sci_get_line_from_position(doc->sci, old_pos); - ind_pos = sci_get_line_indent_position(doc->sci, line); + old_pos = sci_get_current_position(doc->editor->sci); + line = sci_get_line_from_position(doc->editor->sci, old_pos); + ind_pos = sci_get_line_indent_position(doc->editor->sci, line); /* when using tabs increase cur pos by 1, when using space increase it by tab_width */ - step = (doc->use_tabs) ? 1 : editor_prefs.tab_width; + step = (doc->editor->use_tabs) ? 1 : editor_prefs.tab_width; new_pos = (old_pos > ind_pos) ? old_pos + step : old_pos; - sci_set_current_position(doc->sci, ind_pos, TRUE); - sci_cmd(doc->sci, SCI_TAB); - sci_set_current_position(doc->sci, new_pos, TRUE); + sci_set_current_position(doc->editor->sci, ind_pos, TRUE); + sci_cmd(doc->editor->sci, SCI_TAB); + sci_set_current_position(doc->editor->sci, new_pos, TRUE); } } @@ -1725,31 +1725,31 @@ on_menu_decrease_indent1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - if (sci_get_lines_selected(doc->sci) > 1) + if (sci_get_lines_selected(doc->editor->sci) > 1) { - sci_cmd(doc->sci, SCI_BACKTAB); + sci_cmd(doc->editor->sci, SCI_BACKTAB); } else { gint line, ind_pos, old_pos, new_pos, step, indent; - old_pos = sci_get_current_position(doc->sci); - line = sci_get_line_from_position(doc->sci, old_pos); - ind_pos = sci_get_line_indent_position(doc->sci, line); - step = (doc->use_tabs) ? 1 : editor_prefs.tab_width; + old_pos = sci_get_current_position(doc->editor->sci); + line = sci_get_line_from_position(doc->editor->sci, old_pos); + ind_pos = sci_get_line_indent_position(doc->editor->sci, line); + step = (doc->editor->use_tabs) ? 1 : editor_prefs.tab_width; new_pos = (old_pos >= ind_pos) ? old_pos - step : old_pos; - if (ind_pos == sci_get_position_from_line(doc->sci, line)) + if (ind_pos == sci_get_position_from_line(doc->editor->sci, line)) return; - sci_set_current_position(doc->sci, ind_pos, TRUE); - indent = sci_get_line_indentation(doc->sci, line); + sci_set_current_position(doc->editor->sci, ind_pos, TRUE); + indent = sci_get_line_indentation(doc->editor->sci, line); indent -= editor_prefs.tab_width; if (indent < 0) indent = 0; - sci_set_line_indentation(doc->sci, line, indent); + sci_set_line_indentation(doc->editor->sci, line, indent); - sci_set_current_position(doc->sci, new_pos, TRUE); + sci_set_current_position(doc->editor->sci, new_pos, TRUE); } } @@ -1923,8 +1923,8 @@ on_remove_markers1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - sci_marker_delete_all(doc->sci, 0); /* delete the yellow tag marker */ - sci_marker_delete_all(doc->sci, 1); /* delete user markers */ + sci_marker_delete_all(doc->editor->sci, 0); /* delete the yellow tag marker */ + sci_marker_delete_all(doc->editor->sci, 1); /* delete user markers */ } @@ -1947,10 +1947,10 @@ on_context_action1_activate (GtkMenuItem *menuitem, if (doc == NULL) return; - if (sci_can_copy(doc->sci)) + if (sci_can_copy(doc->editor->sci)) { /* take selected text if there is a selection */ - word = g_malloc(sci_get_selected_text_length(doc->sci) + 1); - sci_get_selected_text(doc->sci, word); + word = g_malloc(sci_get_selected_text_length(doc->editor->sci) + 1); + sci_get_selected_text(doc->editor->sci, word); } else { @@ -2074,7 +2074,7 @@ on_tabs1_activate (GtkMenuItem *menuitem, if (doc == NULL || ignore_callback) return; - editor_set_use_tabs(doc, TRUE); + editor_set_use_tabs(doc->editor, TRUE); ui_update_statusbar(doc, -1); } @@ -2088,7 +2088,7 @@ on_spaces1_activate (GtkMenuItem *menuitem, if (doc == NULL || ignore_callback) return; - editor_set_use_tabs(doc, FALSE); + editor_set_use_tabs(doc->editor, FALSE); ui_update_statusbar(doc, -1); } @@ -2153,7 +2153,7 @@ on_line_breaking1_activate (GtkMenuItem *menuitem, doc = document_get_current(); g_return_if_fail(doc != NULL); - doc->line_breaking = !doc->line_breaking; + doc->editor->line_breaking = !doc->editor->line_breaking; } void diff --git a/src/document.c b/src/document.c index 99808ff6b..e4cb499ce 100644 --- a/src/document.c +++ b/src/document.c @@ -192,7 +192,7 @@ GeanyDocument *document_find_by_sci(ScintillaObject *sci) for (i = 0; i < documents_array->len; i++) { - if (documents[i]->is_valid && documents[i]->sci == sci) + if (documents[i]->is_valid && documents[i]->editor->sci == sci) return documents[i]; } return NULL; @@ -206,7 +206,7 @@ gint document_get_notebook_page(GeanyDocument *doc) return -1; return gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), - GTK_WIDGET(doc->sci)); + GTK_WIDGET(doc->editor->sci)); } @@ -296,7 +296,7 @@ void document_apply_update_prefs(GeanyDocument *doc) g_return_if_fail(doc != NULL); - sci = doc->sci; + sci = doc->editor->sci; sci_set_mark_long_lines(sci, editor_prefs.long_line_type, editor_prefs.long_line_column, editor_prefs.long_line_color); @@ -311,7 +311,7 @@ void document_apply_update_prefs(GeanyDocument *doc) sci_set_folding_margin_visible(sci, editor_prefs.folding); - doc->auto_indent = (editor_prefs.indent_mode != INDENT_NONE); + doc->editor->auto_indent = (editor_prefs.indent_mode != INDENT_NONE); sci_assign_cmdkey(sci, SCK_HOME, editor_prefs.smart_home_key ? SCI_VCHOMEWRAP : SCI_HOMEWRAP); @@ -329,17 +329,13 @@ static void init_doc_struct(GeanyDocument *new_doc) new_doc->is_valid = FALSE; new_doc->has_tags = FALSE; - new_doc->auto_indent = (editor_prefs.indent_mode != INDENT_NONE); - new_doc->line_wrapping = editor_prefs.line_wrapping; new_doc->readonly = FALSE; new_doc->file_name = NULL; new_doc->file_type = NULL; new_doc->tm_file = NULL; new_doc->encoding = NULL; new_doc->has_bom = FALSE; - new_doc->sci = NULL; - new_doc->scroll_percent = -1.0F; - new_doc->line_breaking = FALSE; + new_doc->editor = NULL; new_doc->mtime = 0; new_doc->changed = FALSE; new_doc->last_check = time(NULL); @@ -362,7 +358,7 @@ static gint document_get_new_idx(void) for (i = 0; i < documents_array->len; i++) { - if (documents[i]->sci == NULL) + if (documents[i]->editor == NULL) { return (gint) i; } @@ -380,7 +376,7 @@ static void queue_colourise(GeanyDocument *doc) * document), we need to force a redraw, so the expose event is triggered. * This ensures we don't start colourising before all documents are opened/saved, * only once the editor is drawn. */ - gtk_widget_queue_draw(GTK_WIDGET(doc->sci)); + gtk_widget_queue_draw(GTK_WIDGET(doc->editor->sci)); } @@ -388,8 +384,6 @@ static void queue_colourise(GeanyDocument *doc) * @return The index of the created document */ static GeanyDocument *document_create(const gchar *utf8_filename) { - PangoFontDescription *pfd; - gchar *fname; GeanyDocument *this; gint new_idx; gint cur_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)); @@ -416,16 +410,10 @@ static GeanyDocument *document_create(const gchar *utf8_filename) this->file_name = g_strdup(utf8_filename); - this->sci = editor_create_new_sci(this); + this->editor = editor_create(this); document_apply_update_prefs(this); - pfd = pango_font_description_from_string(interface_prefs.editor_font); - fname = g_strdup_printf("!%s", pango_font_description_get_family(pfd)); - editor_set_font(this, fname, pango_font_description_get_size(pfd) / PANGO_SCALE); - pango_font_description_free(pfd); - g_free(fname); - treeviews_openfiles_add(this); /* sets this->iter */ notebook_new_tab(this); @@ -494,15 +482,16 @@ gboolean document_remove_page(guint page_num) g_free(doc->real_path); tm_workspace_remove_object(doc->tm_file, TRUE, TRUE); + g_free(doc->editor); + doc->editor = NULL; + doc->is_valid = FALSE; - doc->sci = NULL; doc->file_name = NULL; doc->real_path = NULL; doc->file_type = NULL; doc->encoding = NULL; doc->has_bom = FALSE; doc->tm_file = NULL; - doc->scroll_percent = -1.0F; document_undo_clear(doc); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) == 0) { @@ -557,21 +546,21 @@ GeanyDocument *document_new_file(const gchar *filename, GeanyFiletype *ft, const g_assert(doc != NULL); - sci_set_undo_collection(doc->sci, FALSE); /* avoid creation of an undo action */ + sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */ if (text) - sci_set_text(doc->sci, text); + sci_set_text(doc->editor->sci, text); else - sci_clear_all(doc->sci); + sci_clear_all(doc->editor->sci); - sci_set_eol_mode(doc->sci, file_prefs.default_eol_character); + sci_set_eol_mode(doc->editor->sci, file_prefs.default_eol_character); /* convert the eol chars in the template text in case they are different from * from file_prefs.default_eol */ if (text != NULL) - sci_convert_eols(doc->sci, file_prefs.default_eol_character); + sci_convert_eols(doc->editor->sci, file_prefs.default_eol_character); - editor_set_use_tabs(doc, editor_prefs.use_tabs); - sci_set_undo_collection(doc->sci, TRUE); - sci_empty_undo_buffer(doc->sci); + editor_set_use_tabs(doc->editor, editor_prefs.use_tabs); + sci_set_undo_collection(doc->editor->sci, TRUE); + sci_empty_undo_buffer(doc->editor->sci); doc->mtime = time(NULL); @@ -585,18 +574,18 @@ GeanyDocument *document_new_file(const gchar *filename, GeanyFiletype *ft, const document_set_filetype(doc, ft); /* also clears taglist */ if (ft == NULL) - highlighting_set_styles(doc->sci, GEANY_FILETYPES_NONE); + highlighting_set_styles(doc->editor->sci, GEANY_FILETYPES_NONE); ui_set_window_title(doc); build_menu_update(doc); document_update_tag_list(doc, FALSE); document_set_text_changed(doc, FALSE); ui_document_show_hide(doc); /* update the document menu */ - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); - sci_goto_pos(doc->sci, 0, TRUE); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); + sci_goto_pos(doc->editor->sci, 0, TRUE); /* "the" SCI signal (connect after initial setup(i.e. adding text)) */ - g_signal_connect((GtkWidget*) doc->sci, "sci-notify", G_CALLBACK(on_editor_notification), doc); + g_signal_connect((GtkWidget*) doc->editor->sci, "sci-notify", G_CALLBACK(on_editor_notification), doc); if (geany_object) { @@ -857,25 +846,25 @@ static gboolean load_text_file(const gchar *locale_filename, const gchar *utf8_f /* Sets the cursor position on opening a file. First it sets the line when cl_options.goto_line * is set, otherwise it sets the line when pos is greater than zero and finally it sets the column * if cl_options.goto_column is set. */ -static void set_cursor_position(GeanyDocument *doc, gint pos) +static void set_cursor_position(GeanyEditor *editor, gint pos) { if (cl_options.goto_line >= 0) { /* goto line which was specified on command line and then undefine the line */ - sci_goto_line(doc->sci, cl_options.goto_line - 1, TRUE); - doc->scroll_percent = 0.5F; + sci_goto_line(editor->sci, cl_options.goto_line - 1, TRUE); + editor->scroll_percent = 0.5F; cl_options.goto_line = -1; } else if (pos > 0) { - sci_set_current_position(doc->sci, pos, FALSE); - doc->scroll_percent = 0.5F; + sci_set_current_position(editor->sci, pos, FALSE); + editor->scroll_percent = 0.5F; } if (cl_options.goto_column >= 0) { /* goto column which was specified on command line and then undefine the column */ - gint cur_pos = sci_get_current_position(doc->sci); - sci_set_current_position(doc->sci, cur_pos + cl_options.goto_column, FALSE); - doc->scroll_percent = 0.5F; + gint cur_pos = sci_get_current_position(editor->sci); + sci_set_current_position(editor->sci, cur_pos + cl_options.goto_column, FALSE); + editor->scroll_percent = 0.5F; cl_options.goto_column = -1; } } @@ -917,20 +906,20 @@ static void set_indentation(GeanyDocument *doc) { /* force using tabs for indentation for Makefiles */ if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_MAKE) - editor_set_use_tabs(doc, TRUE); + editor_set_use_tabs(doc->editor, TRUE); /* force using spaces for indentation for Fortran 77 */ else if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_F77) - editor_set_use_tabs(doc, FALSE); + editor_set_use_tabs(doc->editor, FALSE); else if (! editor_prefs.detect_tab_mode) - editor_set_use_tabs(doc, editor_prefs.use_tabs); + editor_set_use_tabs(doc->editor, editor_prefs.use_tabs); else { /* detect & set tabs/spaces */ - gboolean use_tabs = detect_use_tabs(doc->sci); + gboolean use_tabs = detect_use_tabs(doc->editor->sci); if (use_tabs != editor_prefs.use_tabs) ui_set_statusbar(TRUE, _("Setting %s indentation mode."), (use_tabs) ? _("Tabs") : _("Spaces")); - editor_set_use_tabs(doc, use_tabs); + editor_set_use_tabs(doc->editor, use_tabs); } } @@ -984,11 +973,11 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename ui_add_recent_file(utf8_filename); /* either add or reorder recent item */ gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), - (GtkWidget*) doc->sci)); + (GtkWidget*) doc->editor->sci)); g_free(utf8_filename); g_free(locale_filename); document_check_disk_status(doc, TRUE); /* force a file changed check */ - set_cursor_position(doc, pos); + set_cursor_position(doc->editor, pos); return doc; } } @@ -1007,20 +996,20 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename if (! reload) doc = document_create(utf8_filename); g_return_val_if_fail(doc != NULL, NULL); /* really should not happen */ - sci_set_undo_collection(doc->sci, FALSE); /* avoid creation of an undo action */ - sci_empty_undo_buffer(doc->sci); + sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */ + sci_empty_undo_buffer(doc->editor->sci); /* add the text to the ScintillaObject */ - sci_set_readonly(doc->sci, FALSE); /* to allow replacing text */ - sci_set_text(doc->sci, filedata.data); /* NULL terminated data */ + sci_set_readonly(doc->editor->sci, FALSE); /* to allow replacing text */ + sci_set_text(doc->editor->sci, filedata.data); /* NULL terminated data */ queue_colourise(doc); /* Ensure the document gets colourised. */ /* detect & set line endings */ editor_mode = utils_get_line_endings(filedata.data, filedata.len); - sci_set_eol_mode(doc->sci, editor_mode); + sci_set_eol_mode(doc->editor->sci, editor_mode); g_free(filedata.data); - sci_set_undo_collection(doc->sci, TRUE); + sci_set_undo_collection(doc->editor->sci, TRUE); doc->mtime = filedata.mtime; /* get the modification time from file and keep it */ g_free(doc->encoding); /* if reloading, free old encoding */ @@ -1029,13 +1018,13 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename store_saved_encoding(doc); /* store the opened encoding for undo/redo */ doc->readonly = readonly || filedata.readonly; - sci_set_readonly(doc->sci, doc->readonly); + sci_set_readonly(doc->editor->sci, doc->readonly); /* update line number margin width */ - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); /* set the cursor position according to pos, cl_options.goto_line and cl_options.goto_column */ - set_cursor_position(doc, pos); + set_cursor_position(doc->editor, pos); if (! reload) { @@ -1044,7 +1033,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename doc->real_path = get_real_path_from_utf8(doc->file_name); /* "the" SCI signal (connect after initial setup(i.e. adding text)) */ - g_signal_connect((GtkWidget*) doc->sci, "sci-notify", + g_signal_connect((GtkWidget*) doc->editor->sci, "sci-notify", G_CALLBACK(on_editor_notification), doc); use_ft = (ft != NULL) ? ft : filetypes_detect_from_file(doc); @@ -1060,7 +1049,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename /* set indentation settings after setting the filetype */ if (reload) - editor_set_use_tabs(doc, doc->use_tabs); /* resetup sci */ + editor_set_use_tabs(doc->editor, doc->editor->use_tabs); /* resetup sci */ else set_indentation(doc); @@ -1163,7 +1152,7 @@ gboolean document_reload_file(GeanyDocument *doc, const gchar *forced_enc) return FALSE; /* try to set the cursor to the position before reloading */ - pos = sci_get_current_position(doc->sci); + pos = sci_get_current_position(doc->editor->sci); new_doc = document_open_file_full(doc, NULL, pos, doc->readonly, doc->file_type, forced_enc); return (new_doc != NULL); @@ -1200,8 +1189,8 @@ static void get_line_column_from_pos(GeanyDocument *doc, guint byte_pos, gint *l gint line_start; /* for some reason we can use byte count instead of character count here */ - *line = sci_get_line_from_position(doc->sci, byte_pos); - line_start = sci_get_position_from_line(doc->sci, *line); + *line = sci_get_line_from_position(doc->editor->sci, byte_pos); + line_start = sci_get_position_from_line(doc->editor->sci, *line); /* get the column in the line */ *column = byte_pos - line_start; @@ -1209,7 +1198,7 @@ static void get_line_column_from_pos(GeanyDocument *doc, guint byte_pos, gint *l * skip one byte(i++) and decrease the column number which is based on byte count */ for (i = line_start; i < (line_start + *column); i++) { - if (sci_get_char_at(doc->sci, i) < 0) + if (sci_get_char_at(doc->editor->sci, i) < 0) { (*column)--; i++; @@ -1218,6 +1207,34 @@ static void get_line_column_from_pos(GeanyDocument *doc, guint byte_pos, gint *l } +static void replace_header_filename(GeanyDocument *doc) +{ + gchar *filebase; + gchar *filename; + struct TextToFind ttf; + + if (doc == NULL || doc->file_type == NULL) return; + + filebase = g_strconcat(GEANY_STRING_UNTITLED, ".", (doc->file_type)->extension, NULL); + filename = g_path_get_basename(doc->file_name); + + /* only search the first 3 lines */ + ttf.chrg.cpMin = 0; + ttf.chrg.cpMax = sci_get_position_from_line(doc->editor->sci, 3); + ttf.lpstrText = (gchar*)filebase; + + if (sci_find_text(doc->editor->sci, SCFIND_MATCHCASE, &ttf) != -1) + { + sci_target_start(doc->editor->sci, ttf.chrgText.cpMin); + sci_target_end(doc->editor->sci, ttf.chrgText.cpMax); + sci_target_replace(doc->editor->sci, filename, FALSE); + } + + g_free(filebase); + g_free(filename); +} + + /* * Save the %document, detecting the filetype. * @@ -1252,7 +1269,7 @@ gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname) ignore_callback = FALSE; } } - utils_replace_filename(doc); + replace_header_filename(doc); ret = document_save_file(doc, TRUE); if (ret) @@ -1291,7 +1308,7 @@ _("An error occurred while converting the file from UTF-8 in \"%s\". The file re /* don't read over the doc length */ gint max_len = MIN((gint)bytes_read + 6, (gint)*len - 1); context = g_malloc(7); /* read 6 bytes from Sci + '\0' */ - sci_get_text_range(doc->sci, bytes_read, max_len, context); + sci_get_text_range(doc->editor->sci, bytes_read, max_len, context); /* take only one valid Unicode character from the context and discard the leftover */ unic = g_utf8_get_char_validated(context, -1); @@ -1396,7 +1413,7 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force) if (file_prefs.final_new_line) editor_ensure_final_newline(doc); - len = sci_get_length(doc->sci) + 1; + len = sci_get_length(doc->editor->sci) + 1; if (doc->has_bom && encodings_is_unicode_charset(doc->encoding)) { /* always write a UTF-8 BOM because in this moment the text itself is still in UTF-8 * encoding, it will be converted to doc->encoding below and this conversion @@ -1405,13 +1422,13 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force) data[0] = (gchar) 0xef; data[1] = (gchar) 0xbb; data[2] = (gchar) 0xbf; - sci_get_text(doc->sci, len, data + 3); + sci_get_text(doc->editor->sci, len, data + 3); len += 3; } else { data = (gchar*) g_malloc(len); - sci_get_text(doc->sci, len, data); + sci_get_text(doc->editor->sci, len, data); } /* save in original encoding, skip when it is already UTF-8 or has the encoding "None" */ @@ -1456,8 +1473,8 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force) /* set line numbers again, to reset the margin width, if * there are more lines than before */ - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); - sci_set_savepoint(doc->sci); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); + sci_set_savepoint(doc->editor->sci); /* stat the file to get the timestamp, otherwise on Windows the actual * timestamp can be ahead of time(NULL) */ @@ -1501,38 +1518,38 @@ gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gint fl if (! *text) return TRUE; - start_pos = (inc) ? sci_get_selection_start(doc->sci) : - sci_get_selection_end(doc->sci); /* equal if no selection */ + start_pos = (inc) ? sci_get_selection_start(doc->editor->sci) : + sci_get_selection_end(doc->editor->sci); /* equal if no selection */ /* search cursor to end */ ttf.chrg.cpMin = start_pos; - ttf.chrg.cpMax = sci_get_length(doc->sci); + ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)text; - search_pos = sci_find_text(doc->sci, flags, &ttf); + search_pos = sci_find_text(doc->editor->sci, flags, &ttf); /* if no match, search start to cursor */ if (search_pos == -1) { ttf.chrg.cpMin = 0; ttf.chrg.cpMax = start_pos + strlen(text); - search_pos = sci_find_text(doc->sci, flags, &ttf); + search_pos = sci_find_text(doc->editor->sci, flags, &ttf); } if (search_pos != -1) { - gint line = sci_get_line_from_position(doc->sci, ttf.chrgText.cpMin); + gint line = sci_get_line_from_position(doc->editor->sci, ttf.chrgText.cpMin); /* unfold maybe folded results */ - sci_ensure_line_is_visible(doc->sci, line); + sci_ensure_line_is_visible(doc->editor->sci, line); - sci_set_selection_start(doc->sci, ttf.chrgText.cpMin); - sci_set_selection_end(doc->sci, ttf.chrgText.cpMax); + sci_set_selection_start(doc->editor->sci, ttf.chrgText.cpMin); + sci_set_selection_end(doc->editor->sci, ttf.chrgText.cpMax); - if (! editor_line_in_view(doc->sci, line)) + if (! editor_line_in_view(doc->editor->sci, line)) { /* we need to force scrolling in case the cursor is outside of the current visible area * GeanyDocument::scroll_percent doesn't work because sci isn't always updated * while searching */ - editor_scroll_to_line(doc->sci, -1, 0.3F); + editor_scroll_to_line(doc->editor->sci, -1, 0.3F); } return TRUE; } @@ -1543,7 +1560,7 @@ gboolean document_search_bar_find(GeanyDocument *doc, const gchar *text, gint fl ui_set_statusbar(FALSE, _("\"%s\" was not found."), text); } utils_beep(); - sci_goto_pos(doc->sci, start_pos, FALSE); /* clear selection */ + sci_goto_pos(doc->editor->sci, start_pos, FALSE); /* clear selection */ return FALSE; } } @@ -1563,33 +1580,33 @@ gint document_find_text(GeanyDocument *doc, const gchar *text, gint flags, gbool if (flags & SCFIND_REGEXP) search_backwards = FALSE; - selection_start = sci_get_selection_start(doc->sci); - selection_end = sci_get_selection_end(doc->sci); + selection_start = sci_get_selection_start(doc->editor->sci); + selection_end = sci_get_selection_end(doc->editor->sci); if ((selection_end - selection_start) > 0) { /* there's a selection so go to the end */ if (search_backwards) - sci_goto_pos(doc->sci, selection_start, TRUE); + sci_goto_pos(doc->editor->sci, selection_start, TRUE); else - sci_goto_pos(doc->sci, selection_end, TRUE); + sci_goto_pos(doc->editor->sci, selection_end, TRUE); } - sci_set_search_anchor(doc->sci); + sci_set_search_anchor(doc->editor->sci); if (search_backwards) - search_pos = sci_search_prev(doc->sci, flags, text); + search_pos = sci_search_prev(doc->editor->sci, flags, text); else - search_pos = sci_search_next(doc->sci, flags, text); + search_pos = sci_search_next(doc->editor->sci, flags, text); if (search_pos != -1) { /* unfold maybe folded results */ - sci_ensure_line_is_visible(doc->sci, - sci_get_line_from_position(doc->sci, search_pos)); + sci_ensure_line_is_visible(doc->editor->sci, + sci_get_line_from_position(doc->editor->sci, search_pos)); if (scroll) - doc->scroll_percent = 0.3F; + doc->editor->scroll_percent = 0.3F; } else { - gint sci_len = sci_get_length(doc->sci); + gint sci_len = sci_get_length(doc->editor->sci); /* if we just searched the whole text, give up searching. */ if ((selection_end == 0 && ! search_backwards) || @@ -1607,11 +1624,11 @@ gint document_find_text(GeanyDocument *doc, const gchar *text, gint flags, gbool { gint ret; - sci_set_current_position(doc->sci, (search_backwards) ? sci_len : 0, FALSE); + sci_set_current_position(doc->editor->sci, (search_backwards) ? sci_len : 0, FALSE); ret = document_find_text(doc, text, flags, search_backwards, scroll, parent); if (ret == -1) { /* return to original cursor position if not found */ - sci_set_current_position(doc->sci, selection_start, FALSE); + sci_set_current_position(doc->editor->sci, selection_start, FALSE); } return ret; } @@ -1634,8 +1651,8 @@ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gch if (flags & SCFIND_REGEXP) search_backwards = FALSE; - selection_start = sci_get_selection_start(doc->sci); - selection_end = sci_get_selection_end(doc->sci); + selection_start = sci_get_selection_start(doc->editor->sci); + selection_end = sci_get_selection_end(doc->editor->sci); if (selection_end == selection_start) { /* no selection so just find the next match */ @@ -1645,9 +1662,9 @@ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gch /* there's a selection so go to the start before finding to search through it * this ensures there is a match */ if (search_backwards) - sci_goto_pos(doc->sci, selection_end, TRUE); + sci_goto_pos(doc->editor->sci, selection_end, TRUE); else - sci_goto_pos(doc->sci, selection_start, TRUE); + sci_goto_pos(doc->editor->sci, selection_start, TRUE); search_pos = document_find_text(doc, find_text, flags, search_backwards, TRUE, NULL); /* return if the original selected text did not match (at the start of the selection) */ @@ -1658,11 +1675,11 @@ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gch { gint replace_len; /* search next/prev will select matching text, which we use to set the replace target */ - sci_target_from_selection(doc->sci); - replace_len = sci_target_replace(doc->sci, replace_text, flags & SCFIND_REGEXP); + sci_target_from_selection(doc->editor->sci); + replace_len = sci_target_replace(doc->editor->sci, replace_text, flags & SCFIND_REGEXP); /* select the replacement - find text will skip past the selected text */ - sci_set_selection_start(doc->sci, search_pos); - sci_set_selection_end(doc->sci, search_pos + replace_len); + sci_set_selection_start(doc->editor->sci, search_pos); + sci_set_selection_end(doc->editor->sci, search_pos + replace_len); } else { @@ -1727,7 +1744,7 @@ document_replace_range(GeanyDocument *doc, const gchar *find_text, const gchar * g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, 0); if (! *find_text || doc->readonly) return 0; - sci = doc->sci; + sci = doc->editor->sci; sci_start_undo_action(sci); ttf.chrg.cpMin = start; @@ -1801,8 +1818,8 @@ void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gcha g_return_if_fail(doc != NULL && find_text != NULL && replace_text != NULL); if (! *find_text) return; - selection_start = sci_get_selection_start(doc->sci); - selection_end = sci_get_selection_end(doc->sci); + selection_start = sci_get_selection_start(doc->editor->sci); + selection_end = sci_get_selection_end(doc->editor->sci); /* do we have a selection? */ if ((selection_end - selection_start) == 0) { @@ -1810,24 +1827,24 @@ void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gcha return; } - selection_mode = sci_get_selection_mode(doc->sci); - selected_lines = sci_get_lines_selected(doc->sci); + selection_mode = sci_get_selection_mode(doc->editor->sci); + selected_lines = sci_get_lines_selected(doc->editor->sci); /* handle rectangle, multi line selections (it doesn't matter on a single line) */ if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1) { gint first_line, line; - sci_start_undo_action(doc->sci); + sci_start_undo_action(doc->editor->sci); - first_line = sci_get_line_from_position(doc->sci, selection_start); + first_line = sci_get_line_from_position(doc->editor->sci, selection_start); /* Find the last line with chars selected (not EOL char) */ - last_line = sci_get_line_from_position(doc->sci, + last_line = sci_get_line_from_position(doc->editor->sci, selection_end - editor_get_eol_char_len(doc)); last_line = MAX(first_line, last_line); for (line = first_line; line < (first_line + selected_lines); line++) { - gint line_start = sci_get_pos_at_line_sel_start(doc->sci, line); - gint line_end = sci_get_pos_at_line_sel_end(doc->sci, line); + gint line_start = sci_get_pos_at_line_sel_start(doc->editor->sci, line); + gint line_end = sci_get_pos_at_line_sel_end(doc->editor->sci, line); /* skip line if there is no selection */ if (line_start != INVALID_POSITION) @@ -1842,11 +1859,11 @@ void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gcha replaced = TRUE; /* this gets the greatest column within the selection after replacing */ max_column = MAX(max_column, - new_sel_end - sci_get_position_from_line(doc->sci, line)); + new_sel_end - sci_get_position_from_line(doc->editor->sci, line)); } } } - sci_end_undo_action(doc->sci); + sci_end_undo_action(doc->editor->sci); } else /* handle normal line selection */ { @@ -1862,26 +1879,26 @@ void document_replace_sel(GeanyDocument *doc, const gchar *find_text, const gcha if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1) { /* now we can scroll to the selection and destroy it because we rebuild it later */ - /*sci_goto_pos(doc->sci, selection_start, FALSE);*/ + /*sci_goto_pos(doc->editor->sci, selection_start, FALSE);*/ /* Note: the selection will be wrapped to last_line + 1 if max_column is greater than * the highest column on the last line. The wrapped selection is completely different * from the original one, so skip the selection at all */ /* TODO is there a better way to handle the wrapped selection? */ - if ((sci_get_line_length(doc->sci, last_line) - 1) >= max_column) + if ((sci_get_line_length(doc->editor->sci, last_line) - 1) >= max_column) { /* for keeping and adjusting the selection in multi line rectangle selection we * need the last line of the original selection and the greatest column number after * replacing and set the selection end to the last line at the greatest column */ - sci_set_selection_start(doc->sci, selection_start); - sci_set_selection_end(doc->sci, - sci_get_position_from_line(doc->sci, last_line) + max_column); - sci_set_selection_mode(doc->sci, selection_mode); + sci_set_selection_start(doc->editor->sci, selection_start); + sci_set_selection_end(doc->editor->sci, + sci_get_position_from_line(doc->editor->sci, last_line) + max_column); + sci_set_selection_mode(doc->editor->sci, selection_mode); } } else { - sci_set_selection_start(doc->sci, selection_start); - sci_set_selection_end(doc->sci, selection_end); + sci_set_selection_start(doc->editor->sci, selection_start); + sci_set_selection_end(doc->editor->sci, selection_end); } } else /* no replacements */ @@ -1899,7 +1916,7 @@ gboolean document_replace_all(GeanyDocument *doc, const gchar *find_text, const g_return_val_if_fail(doc != NULL && find_text != NULL && replace_text != NULL, FALSE); if (! *find_text) return FALSE; - len = sci_get_length(doc->sci); + len = sci_get_length(doc->editor->sci); count = document_replace_range( doc, find_text, replace_text, flags, 0, len, TRUE, NULL); @@ -2002,7 +2019,7 @@ static gboolean update_type_keywords(GeanyDocument *doc, gint lang) gboolean ret = FALSE; guint n; const GString *s; - ScintillaObject *sci = doc ? doc->sci : NULL; + ScintillaObject *sci = doc ? doc->editor->sci : NULL; if (sci != NULL && editor_lexer_get_type_keyword_idx(sci_get_lexer(sci)) == -1) return FALSE; @@ -2022,10 +2039,9 @@ static gboolean update_type_keywords(GeanyDocument *doc, gint lang) for (n = 0; n < documents_array->len; n++) { - ScintillaObject *wid = documents[n]->sci; - - if (wid) + if (documents[n]->is_valid) { + ScintillaObject *wid = documents[n]->editor->sci; gint keyword_idx = editor_lexer_get_type_keyword_idx(sci_get_lexer(wid)); if (keyword_idx > 0) @@ -2066,7 +2082,7 @@ void document_set_filetype(GeanyDocument *doc, GeanyFiletype *type) tm_workspace_remove_object(doc->tm_file, TRUE, TRUE); doc->tm_file = NULL; } - highlighting_set_styles(doc->sci, type->id); + highlighting_set_styles(doc->editor->sci, type->id); build_menu_update(doc); queue_colourise(doc); } @@ -2142,7 +2158,7 @@ void document_undo_clear(GeanyDocument *doc) } fdoc->redo_actions = NULL; - if (! main_status.quitting && doc->sci != NULL) + if (! main_status.quitting && doc->editor != NULL) document_set_text_changed(doc, FALSE); /*geany_debug("%s: new undo stack height: %d, new redo stack height: %d", __func__, @@ -2179,7 +2195,7 @@ gboolean document_can_undo(GeanyDocument *doc) if (doc == NULL) return FALSE; - if (g_trash_stack_height(&fdoc->undo_actions) > 0 || sci_can_undo(doc->sci)) + if (g_trash_stack_height(&fdoc->undo_actions) > 0 || sci_can_undo(doc->editor->sci)) return TRUE; else return FALSE; @@ -2191,7 +2207,7 @@ static void update_changed_state(GeanyDocument *doc) Document *fdoc = DOCUMENT(doc); doc->changed = - (sci_is_modified(doc->sci) || + (sci_is_modified(doc->editor->sci) || doc->has_bom != fdoc->saved_encoding.has_bom || ! utils_str_equal(doc->encoding, fdoc->saved_encoding.encoding)); document_set_text_changed(doc, doc->changed); @@ -2212,7 +2228,7 @@ void document_undo(GeanyDocument *doc) { /* fallback, should not be necessary */ geany_debug("%s: fallback used", __func__); - sci_undo(doc->sci); + sci_undo(doc->editor->sci); } else { @@ -2222,7 +2238,7 @@ void document_undo(GeanyDocument *doc) { document_redo_add(doc, UNDO_SCINTILLA, NULL); - sci_undo(doc->sci); + sci_undo(doc->editor->sci); break; } case UNDO_BOM: @@ -2266,7 +2282,7 @@ gboolean document_can_redo(GeanyDocument *doc) if (doc == NULL) return FALSE; - if (g_trash_stack_height(&fdoc->redo_actions) > 0 || sci_can_redo(doc->sci)) + if (g_trash_stack_height(&fdoc->redo_actions) > 0 || sci_can_redo(doc->editor->sci)) return TRUE; else return FALSE; @@ -2287,7 +2303,7 @@ void document_redo(GeanyDocument *doc) { /* fallback, should not be necessary */ geany_debug("%s: fallback used", __func__); - sci_redo(doc->sci); + sci_redo(doc->editor->sci); } else { @@ -2297,7 +2313,7 @@ void document_redo(GeanyDocument *doc) { document_undo_add(doc, UNDO_SCINTILLA, NULL); - sci_redo(doc->sci); + sci_redo(doc->editor->sci); break; } case UNDO_BOM: @@ -2389,20 +2405,20 @@ GeanyDocument *document_clone(GeanyDocument *old_doc, const gchar *utf8_filename gchar *text; GeanyDocument *doc; - len = sci_get_length(old_doc->sci) + 1; + len = sci_get_length(old_doc->editor->sci) + 1; text = (gchar*) g_malloc(len); - sci_get_text(old_doc->sci, len, text); + sci_get_text(old_doc->editor->sci, len, text); /* use old file type (or maybe NULL for auto detect would be better?) */ doc = document_new_file(utf8_filename, old_doc->file_type, text); g_free(text); /* copy file properties */ - doc->line_wrapping = old_doc->line_wrapping; + doc->editor->line_wrapping = old_doc->editor->line_wrapping; doc->readonly = old_doc->readonly; doc->has_bom = old_doc->has_bom; document_set_encoding(doc, old_doc->encoding); - sci_set_lines_wrapped(doc->sci, doc->line_wrapping); - sci_set_readonly(doc->sci, doc->readonly); + sci_set_lines_wrapped(doc->editor->sci, doc->editor->line_wrapping); + sci_set_readonly(doc->editor->sci, doc->readonly); ui_document_show_hide(doc); return doc; diff --git a/src/document.h b/src/document.h index fadff690b..017e34886 100644 --- a/src/document.h +++ b/src/document.h @@ -82,30 +82,20 @@ struct GeanyDocument gchar *encoding; /** Internally used flag to indicate whether the file of this %document has a byte-order-mark. */ gboolean has_bom; + struct GeanyEditor *editor; /**< The editor associated with the document. */ /** The filetype for this %document, it's only a reference to one of the elements of the global * filetypes array. */ GeanyFiletype *file_type; /** TMWorkObject object for this %document. */ TMWorkObject *tm_file; - /** The Scintilla object for this %document. */ - ScintillaObject *sci; /** Whether this %document is read-only. */ gboolean readonly; /** Whether this %document has been changed since it was last saved. */ gboolean changed; - /** %Document-specific line wrapping setting. */ - gboolean line_wrapping; - /** %Document-specific indentation setting. */ - gboolean auto_indent; - /** Percentage to scroll view by on paint, if positive. */ - gfloat scroll_percent; /** Time of the last disk check. */ time_t last_check; /** Modification time of this %document on disk. */ time_t mtime; - /** %Document-specific indentation setting. */ - gboolean use_tabs; - gboolean line_breaking; /**< Whether to split long lines as you type. */ /** The link-dereferenced, locale-encoded file name. * If non-NULL, this indicates the file once existed on disk (not just as an * unsaved document with a filename set). diff --git a/src/editor.c b/src/editor.c index aba446153..84d9e2925 100644 --- a/src/editor.c +++ b/src/editor.c @@ -72,13 +72,13 @@ static struct static gchar indent[100]; -static void on_new_line_added(GeanyDocument *doc); -static gboolean handle_xml(GeanyDocument *doc, gchar ch); -static void get_indent(GeanyDocument *doc, gint pos, gboolean use_this_line); -static void auto_multiline(GeanyDocument *doc, gint pos); +static void on_new_line_added(GeanyEditor *editor); +static gboolean handle_xml(GeanyEditor *editor, gchar ch); +static void get_indent(GeanyEditor *editor, gint pos, gboolean use_this_line); +static void auto_multiline(GeanyEditor *editor, gint pos); static gboolean is_comment(gint lexer, gint prev_style, gint style); static void auto_close_bracket(ScintillaObject *sci, gint pos, gchar c); -static void editor_auto_table(GeanyDocument *doc, gint pos); +static void auto_table(GeanyEditor *editor, gint pos); @@ -181,20 +181,20 @@ on_editor_button_press_event (GtkWidget *widget, if (doc == NULL) return FALSE; - editor_info.click_pos = sci_get_position_from_xy(doc->sci, (gint)event->x, (gint)event->y, FALSE); + editor_info.click_pos = sci_get_position_from_xy(doc->editor->sci, (gint)event->x, (gint)event->y, FALSE); if (event->button == 1) { if (GDK_BUTTON_PRESS == event->type && editor_prefs.disable_dnd) { - gint ss = sci_get_selection_start(doc->sci); - sci_set_selection_end(doc->sci, ss); + gint ss = sci_get_selection_start(doc->editor->sci); + sci_set_selection_end(doc->editor->sci, ss); } return document_check_disk_status(doc, FALSE); } if (event->button == 3) { - editor_find_current_word(doc->sci, editor_info.click_pos, + editor_find_current_word(doc->editor->sci, editor_info.click_pos, current_word, sizeof current_word, NULL); ui_update_popup_goto_items((current_word[0] != '\0') ? TRUE : FALSE); @@ -265,7 +265,7 @@ static void on_margin_click(ScintillaObject *sci, SCNotification *nt) gint line = sci_get_line_from_position(sci, nt->position); gboolean set = sci_is_marker_set_at_line(sci, line, 1); - /*sci_marker_delete_all(doc->sci, 1);*/ + /*sci_marker_delete_all(doc->editor->sci, 1);*/ sci_set_marker_at_line(sci, line, ! set, 1); /* toggle the marker */ } /* left click on the folding margin to toggle folding state of current line */ @@ -276,27 +276,27 @@ static void on_margin_click(ScintillaObject *sci, SCNotification *nt) } -static void on_update_ui(GeanyDocument *doc, G_GNUC_UNUSED SCNotification *nt) +static void on_update_ui(GeanyEditor *editor, G_GNUC_UNUSED SCNotification *nt) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); /* undo / redo menu update */ - ui_update_popup_reundo_items(doc); + ui_update_popup_reundo_items(editor->document); /* brace highlighting */ editor_highlight_braces(sci, pos); - ui_update_statusbar(doc, pos); + ui_update_statusbar(editor->document, pos); /* Visible lines are only laid out accurately once [SCN_UPDATEUI] is sent, * so we need to only call sci_scroll_to_line here, because the document * may have line wrapping and folding enabled. * http://scintilla.sourceforge.net/ScintillaDoc.html#LineWrapping */ - if (doc->scroll_percent > 0.0F) + if (editor->scroll_percent > 0.0F) { - editor_scroll_to_line(sci, -1, doc->scroll_percent); - doc->scroll_percent = -1.0F; /* disable further scrolling */ + editor_scroll_to_line(sci, -1, editor->scroll_percent); + editor->scroll_percent = -1.0F; /* disable further scrolling */ } #if 0 /** experimental code for inverting selections */ @@ -315,12 +315,12 @@ static void on_update_ui(GeanyDocument *doc, G_GNUC_UNUSED SCNotification *nt) } -static void check_line_breaking(GeanyDocument *doc, gint pos, gchar c) +static void check_line_breaking(GeanyEditor *editor, gint pos, gchar c) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint line, lstart; - if (!doc->line_breaking) + if (!editor->line_breaking) return; if (c == GDK_space) @@ -341,7 +341,7 @@ static void check_line_breaking(GeanyDocument *doc, gint pos, gchar c) if (c == GDK_space) { gint col, len, diff; - const gchar *eol = editor_get_eol_char(doc); + const gchar *eol = editor_get_eol_char(editor->document); /* break the line after the space */ sci_insert_text(sci, pos + 1, eol); @@ -358,7 +358,7 @@ static void check_line_breaking(GeanyDocument *doc, gint pos, gchar c) pos = sci_get_position_from_line(sci, line); sci_set_current_position(sci, pos, FALSE); /* add indentation, comment multilines, etc */ - on_new_line_added(doc); + on_new_line_added(editor); /* correct cursor position (might not be at line end) */ pos = sci_get_position_from_line(sci, line); @@ -370,9 +370,9 @@ static void check_line_breaking(GeanyDocument *doc, gint pos, gchar c) } -static void on_char_added(GeanyDocument *doc, SCNotification *nt) +static void on_char_added(GeanyEditor *editor, SCNotification *nt) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); switch (nt->ch) @@ -380,23 +380,23 @@ static void on_char_added(GeanyDocument *doc, SCNotification *nt) case '\r': { /* simple indentation (only for CR format) */ if (sci_get_eol_mode(sci) == SC_EOL_CR) - on_new_line_added(doc); + on_new_line_added(editor); break; } case '\n': { /* simple indentation (for CR/LF and LF format) */ - on_new_line_added(doc); + on_new_line_added(editor); break; } case '>': case '/': { /* close xml-tags */ - handle_xml(doc, nt->ch); + handle_xml(editor, nt->ch); break; } case '(': { /* show calltips */ - editor_show_calltip(doc, --pos); + editor_show_calltip(editor->document, --pos); break; } case ')': @@ -418,19 +418,20 @@ static void on_char_added(GeanyDocument *doc, SCNotification *nt) if (sci_get_lexer(sci) == SCLEX_LATEX) { auto_close_bracket(sci, pos, nt->ch); /* Tex auto-closing */ - editor_show_calltip(doc, --pos); + editor_show_calltip(editor->document, --pos); } break; } case '}': { /* closing bracket handling */ - if (doc->auto_indent) - editor_close_block(doc, pos - 1); + if (editor->auto_indent) + editor_close_block(editor->document, pos - 1); break; } - default: editor_start_auto_complete(doc, pos, FALSE); + default: + editor_start_auto_complete(editor->document, pos, FALSE); } - check_line_breaking(doc, pos, nt->ch); + check_line_breaking(editor, pos, nt->ch); } @@ -567,14 +568,15 @@ static gboolean reshow_calltip(gpointer data) /* callback func called by all editors when a signal arises */ -void on_editor_notification(GtkWidget *editor, gint scn, gpointer lscn, gpointer user_data) +void on_editor_notification(GtkWidget *widget, gint scn, gpointer lscn, gpointer user_data) { SCNotification *nt; ScintillaObject *sci; - GeanyDocument *doc; + GeanyDocument *doc = user_data; + GeanyEditor *editor; - doc = user_data; - sci = doc->sci; + editor = doc->editor; + sci = editor->sci; nt = lscn; switch (nt->nmhdr.code) @@ -599,7 +601,7 @@ void on_editor_notification(GtkWidget *editor, gint scn, gpointer lscn, gpointer break; case SCN_UPDATEUI: - on_update_ui(doc, nt); + on_update_ui(editor, nt); break; case SCN_MODIFIED: @@ -617,7 +619,7 @@ void on_editor_notification(GtkWidget *editor, gint scn, gpointer lscn, gpointer break; } case SCN_CHARADDED: - on_char_added(doc, nt); + on_char_added(editor, nt); break; case SCN_USERLISTSELECTION: @@ -722,53 +724,54 @@ get_whitespace(gint width, gboolean use_tabs) } -static void check_python_indent(GeanyDocument *doc, gint pos) +static void check_python_indent(GeanyEditor *editor, gint pos) { - gint last_char = pos - editor_get_eol_char_len(doc) - 1; + ScintillaObject *sci = editor->sci; + gint last_char = pos - editor_get_eol_char_len(editor->document) - 1; /* add extra indentation for Python after colon */ - if (sci_get_char_at(doc->sci, last_char) == ':' && - sci_get_style_at(doc->sci, last_char) == SCE_P_OPERATOR) + if (sci_get_char_at(sci, last_char) == ':' && + sci_get_style_at(sci, last_char) == SCE_P_OPERATOR) { /* creates and inserts one tabulator sign or * whitespace of the amount of the tab width */ - gchar *text = get_whitespace(editor_prefs.tab_width, doc->use_tabs); - sci_add_text(doc->sci, text); + gchar *text = get_whitespace(editor_prefs.tab_width, editor->use_tabs); + sci_add_text(sci, text); g_free(text); } } -static void on_new_line_added(GeanyDocument *doc) +static void on_new_line_added(GeanyEditor *editor) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint pos = sci_get_current_position(sci); gint line = sci_get_current_line(sci); /* simple indentation */ - if (doc->auto_indent) + if (editor->auto_indent) { - get_indent(doc, pos, FALSE); + get_indent(editor, pos, FALSE); sci_add_text(sci, indent); if (editor_prefs.indent_mode > INDENT_BASIC && - FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_PYTHON) - check_python_indent(doc, pos); + FILETYPE_ID(editor->document->file_type) == GEANY_FILETYPES_PYTHON) + check_python_indent(editor, pos); } if (editor_prefs.auto_continue_multiline) { /* " * " auto completion in multiline C/C++/D/Java comments */ - auto_multiline(doc, pos); + auto_multiline(editor, pos); } if (editor_prefs.complete_snippets) { - editor_auto_latex(doc, pos); + editor_auto_latex(editor->document, pos); } if (editor_prefs.newline_strip) { /* strip the trailing spaces on the previous line */ - editor_strip_line_trailing_spaces(doc, line - 1); + editor_strip_line_trailing_spaces(editor->document, line - 1); } } @@ -815,9 +818,9 @@ static void do_indent(gchar *buf, gsize len, guint *idx, gboolean use_tabs) /* "use_this_line" to auto-indent only if it is a real new line * and ignore the case of editor_close_block */ -static void get_indent(GeanyDocument *doc, gint pos, gboolean use_this_line) +static void get_indent(GeanyEditor *editor, gint pos, gboolean use_this_line) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; guint i, len, j = 0; gint prev_line; gchar *linebuf; @@ -846,7 +849,7 @@ static void get_indent(GeanyDocument *doc, gint pos, gboolean use_this_line) * " { return bless({}, shift); }" (Perl) */ if (linebuf[i] == '{' && i == (len - 1)) { - do_indent(indent, sizeof(indent), &j, doc->use_tabs); + do_indent(indent, sizeof(indent), &j, editor->use_tabs); break; } else @@ -859,7 +862,7 @@ static void get_indent(GeanyDocument *doc, gint pos, gboolean use_this_line) * e.g. for (...) { */ if (linebuf[k] == '{') { - do_indent(indent, sizeof(indent), &j, doc->use_tabs); + do_indent(indent, sizeof(indent), &j, editor->use_tabs); } break; } @@ -940,7 +943,7 @@ void editor_close_block(GeanyDocument *doc, gint pos) if (doc == NULL || doc->file_type == NULL) return; - sci = doc->sci; + sci = doc->editor->sci; if (! lexer_has_braces(sci)) return; @@ -972,7 +975,7 @@ void editor_close_block(GeanyDocument *doc, gint pos) { gint line_start; - get_indent(doc, start_brace, TRUE); + get_indent(doc->editor, start_brace, TRUE); text = g_strconcat(indent, "}", NULL); line_start = sci_get_position_from_line(sci, line); sci_set_anchor(sci, line_start); @@ -1199,7 +1202,7 @@ gboolean editor_show_calltip(GeanyDocument *doc, gint pos) if (doc == NULL || doc->file_type == NULL) return FALSE; - sci = doc->sci; + sci = doc->editor->sci; lexer = SSM(sci, SCI_GETLEXER, 0, 0); @@ -1283,7 +1286,7 @@ autocomplete_tags(GeanyDocument *doc, const gchar *root, gsize rootlen) if (doc == NULL || doc->file_type == NULL) return FALSE; - sci = doc->sci; + sci = doc->editor->sci; tags = tm_workspace_find(root, tm_tag_max_t, attrs, TRUE, doc->file_type->lang); if (NULL != tags && tags->len > 0) @@ -1337,7 +1340,7 @@ gboolean editor_start_auto_complete(GeanyDocument *doc, gint pos, gboolean force doc == NULL || doc->file_type == NULL) return FALSE; - sci = doc->sci; + sci = doc->editor->sci; ft = doc->file_type; line = sci_get_line_from_position(sci, pos); @@ -1398,10 +1401,11 @@ void editor_auto_latex(GeanyDocument *doc, gint pos) if (doc == NULL || doc->file_type == NULL) return; - sci = doc->sci; + sci = doc->editor->sci; if (sci_get_char_at(sci, pos - 2) == '}') { + GeanyEditor *editor = doc->editor; gchar *eol, *buf, *construct; gchar env[50]; gint line = sci_get_line_from_position(sci, pos - 2); @@ -1452,8 +1456,8 @@ void editor_auto_latex(GeanyDocument *doc, gint pos) } /* get the indentation */ - if (doc->auto_indent) - get_indent(doc, pos, TRUE); + if (editor->auto_indent) + get_indent(editor, pos, TRUE); eol = g_strconcat(editor_get_eol_char(doc), indent, NULL); construct = g_strdup_printf("%s\\end%s{%s}", eol, full_cmd, env); @@ -1539,16 +1543,16 @@ static gchar *snippets_replace_wildcards(GeanyDocument *doc, gchar *text) } -static gboolean snippets_complete_constructs(GeanyDocument *doc, gint pos, const gchar *word) +static gboolean snippets_complete_constructs(GeanyEditor *editor, gint pos, const gchar *word) { gchar *str; gchar *pattern; gchar *lindent; gchar *whitespace; gint step, str_len; - gint ft_id = FILETYPE_ID(doc->file_type); + gint ft_id = FILETYPE_ID(editor->document->file_type); GHashTable *specials; - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; str = g_strdup(word); g_strstrip(str); @@ -1560,9 +1564,9 @@ static gboolean snippets_complete_constructs(GeanyDocument *doc, gint pos, const return FALSE; } - get_indent(doc, pos, TRUE); - lindent = g_strconcat(editor_get_eol_char(doc), indent, NULL); - whitespace = get_whitespace(editor_prefs.tab_width, doc->use_tabs); + get_indent(editor, pos, TRUE); + lindent = g_strconcat(editor_get_eol_char(editor->document), indent, NULL); + whitespace = get_whitespace(editor_prefs.tab_width, editor->use_tabs); /* remove the typed word, it will be added again by the used auto completion * (not really necessary but this makes the auto completion more flexible, @@ -1591,7 +1595,7 @@ static gboolean snippets_complete_constructs(GeanyDocument *doc, gint pos, const pattern = utils_str_replace(pattern, "%ws%", whitespace); /* replace any %template% wildcards */ - pattern = snippets_replace_wildcards(doc, pattern); + pattern = snippets_replace_wildcards(editor->document, pattern); /* find the %cursor% pos (has to be done after all other operations) */ step = utils_strpos(pattern, "%cursor%"); @@ -1639,7 +1643,7 @@ gboolean editor_complete_snippet(GeanyDocument *doc, gint pos) if (doc == NULL) return FALSE; - sci = doc->sci; + sci = doc->editor->sci; /* return if we are editing an existing line (chars on right of cursor) */ if (! editor_prefs.complete_snippets_whilst_editing && ! at_eol(sci, pos)) return FALSE; @@ -1654,7 +1658,7 @@ gboolean editor_complete_snippet(GeanyDocument *doc, gint pos) if (! isspace(sci_get_char_at(sci, pos - 1))) /* pos points to the line end char so use pos -1 */ { sci_start_undo_action(sci); /* needed because we insert a space separately from construct */ - result = snippets_complete_constructs(doc, pos, current_word); + result = snippets_complete_constructs(doc->editor, pos, current_word); sci_end_undo_action(sci); if (result) SSM(sci, SCI_CANCEL, 0, 0); /* cancel any autocompletion list, etc */ @@ -1679,9 +1683,9 @@ void editor_show_macro_list(ScintillaObject *sci) } -static void insert_closing_tag(GeanyDocument *doc, gint pos, gchar ch, const gchar *tag_name) +static void insert_closing_tag(GeanyEditor *editor, gint pos, gchar ch, const gchar *tag_name) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gchar *to_insert = NULL; if (ch == '/') @@ -1702,7 +1706,7 @@ static void insert_closing_tag(GeanyDocument *doc, gint pos, gchar ch, const gch { SSM(sci, SCI_SETSEL, pos, pos); if (utils_str_equal(tag_name, "table")) - editor_auto_table(doc, pos); + auto_table(editor, pos); } sci_end_undo_action(sci); g_free(to_insert); @@ -1715,9 +1719,9 @@ static void insert_closing_tag(GeanyDocument *doc, gint pos, gchar ch, const gch * @param ch The character we are dealing with, currently only works with the '>' character * @return True if handled, false otherwise */ -static gboolean handle_xml(GeanyDocument *doc, gchar ch) +static gboolean handle_xml(GeanyEditor *editor, gchar ch) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint lexer = SSM(sci, SCI_GETLEXER, 0, 0); gint pos, min; gchar *str_found, sel[512]; @@ -1731,7 +1735,7 @@ static gboolean handle_xml(GeanyDocument *doc, gchar ch) pos = sci_get_current_position(sci); /* return if we are in PHP but not in a string or outside of tags */ - if (doc->file_type->id == GEANY_FILETYPES_PHP) + if (editor->document->file_type->id == GEANY_FILETYPES_PHP) { gint style = sci_get_style_at(sci, pos); if (style != SCE_HPHP_SIMPLESTRING && style != SCE_HPHP_HSTRING && @@ -1774,7 +1778,7 @@ static gboolean handle_xml(GeanyDocument *doc, gchar ch) } else if (NZV(str_found)) { - insert_closing_tag(doc, pos, ch, str_found); + insert_closing_tag(editor, pos, ch, str_found); result = TRUE; } g_free(str_found); @@ -1782,15 +1786,15 @@ static gboolean handle_xml(GeanyDocument *doc, gchar ch) } -static void editor_auto_table(GeanyDocument *doc, gint pos) +static void auto_table(GeanyEditor *editor, gint pos) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gchar *table; gint indent_pos; if (SSM(sci, SCI_GETLEXER, 0, 0) != SCLEX_HTML) return; - get_indent(doc, pos, TRUE); + get_indent(editor, pos, TRUE); indent_pos = sci_get_line_indent_position(sci, sci_get_line_from_position(sci, pos)); if ((pos - 7) != indent_pos) /* 7 == strlen("") */ { @@ -1829,9 +1833,9 @@ static void real_comment_multiline(GeanyDocument *doc, gint line_start, gint las str_end = g_strdup_printf("%s%s", doc->file_type->comment_close, eol); /* insert the comment strings */ - sci_insert_text(doc->sci, line_start, str_begin); - line_len = sci_get_position_from_line(doc->sci, last_line + 2); - sci_insert_text(doc->sci, line_len, str_end); + sci_insert_text(doc->editor->sci, line_start, str_begin); + line_len = sci_get_position_from_line(doc->editor->sci, last_line + 2); + sci_insert_text(doc->editor->sci, line_len, str_end); g_free(str_begin); g_free(str_end); @@ -1849,28 +1853,28 @@ static void real_uncomment_multiline(GeanyDocument *doc) /* remove comment open chars */ pos = document_find_text(doc, doc->file_type->comment_open, 0, TRUE, FALSE, NULL); - SSM(doc->sci, SCI_DELETEBACK, 0, 0); + SSM(doc->editor->sci, SCI_DELETEBACK, 0, 0); /* check whether the line is empty and can be deleted */ - line = sci_get_line_from_position(doc->sci, pos); - len = sci_get_line_length(doc->sci, line); - linebuf = sci_get_line(doc->sci, line); + line = sci_get_line_from_position(doc->editor->sci, pos); + len = sci_get_line_length(doc->editor->sci, line); + linebuf = sci_get_line(doc->editor->sci, line); x = 0; while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; - if (x == len) SSM(doc->sci, SCI_LINEDELETE, 0, 0); + if (x == len) SSM(doc->editor->sci, SCI_LINEDELETE, 0, 0); g_free(linebuf); /* remove comment close chars */ pos = document_find_text(doc, doc->file_type->comment_close, 0, FALSE, FALSE, NULL); - SSM(doc->sci, SCI_DELETEBACK, 0, 0); + SSM(doc->editor->sci, SCI_DELETEBACK, 0, 0); /* check whether the line is empty and can be deleted */ - line = sci_get_line_from_position(doc->sci, pos); - len = sci_get_line_length(doc->sci, line); - linebuf = sci_get_line(doc->sci, line); + line = sci_get_line_from_position(doc->editor->sci, pos); + len = sci_get_line_length(doc->editor->sci, line); + linebuf = sci_get_line(doc->editor->sci, line); x = 0; while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; - if (x == len) SSM(doc->sci, SCI_LINEDELETE, 0, 0); + if (x == len) SSM(doc->editor->sci, SCI_LINEDELETE, 0, 0); g_free(linebuf); } @@ -1894,29 +1898,29 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) if (line < 0) { /* use selection or current line */ - sel_start = sci_get_selection_start(doc->sci); - sel_end = sci_get_selection_end(doc->sci); + sel_start = sci_get_selection_start(doc->editor->sci); + sel_end = sci_get_selection_end(doc->editor->sci); - first_line = sci_get_line_from_position(doc->sci, sel_start); + first_line = sci_get_line_from_position(doc->editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ - last_line = sci_get_line_from_position(doc->sci, + last_line = sci_get_line_from_position(doc->editor->sci, sel_end - editor_get_eol_char_len(doc)); last_line = MAX(first_line, last_line); } else { first_line = last_line = line; - sel_start = sel_end = sci_get_position_from_line(doc->sci, line); + sel_start = sel_end = sci_get_position_from_line(doc->editor->sci, line); } ft = doc->file_type; /* detection of HTML vs PHP code, if non-PHP set filetype to XML */ - line_start = sci_get_position_from_line(doc->sci, first_line); + line_start = sci_get_position_from_line(doc->editor->sci, first_line); if (ft->id == GEANY_FILETYPES_PHP) { - if (sci_get_style_at(doc->sci, line_start) < 118 || - sci_get_style_at(doc->sci, line_start) > 127) + if (sci_get_style_at(doc->editor->sci, line_start) < 118 || + sci_get_style_at(doc->editor->sci, line_start) > 127) ft = filetypes[GEANY_FILETYPES_XML]; } @@ -1929,20 +1933,20 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) if (co_len == 0) return 0; - SSM(doc->sci, SCI_BEGINUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_BEGINUNDOACTION, 0, 0); for (i = first_line; (i <= last_line) && (! break_loop); i++) { gint buf_len; - line_start = sci_get_position_from_line(doc->sci, i); - line_len = sci_get_line_length(doc->sci, i); + line_start = sci_get_position_from_line(doc->editor->sci, i); + line_len = sci_get_line_length(doc->editor->sci, i); x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len - 1); if (buf_len <= 0) continue; - sci_get_text_range(doc->sci, line_start, line_start + buf_len, sel); + sci_get_text_range(doc->editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; @@ -1971,15 +1975,15 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) continue; } - SSM(doc->sci, SCI_SETSEL, line_start + x, line_start + x + co_len); - sci_replace_sel(doc->sci, ""); + SSM(doc->editor->sci, SCI_SETSEL, line_start + x, line_start + x + co_len); + sci_replace_sel(doc->editor->sci, ""); count++; } /* use multi line comment */ else { gint style_comment; - gint lexer = SSM(doc->sci, SCI_GETLEXER, 0, 0); + gint lexer = SSM(doc->editor->sci, SCI_GETLEXER, 0, 0); /* process only lines which are already comments */ switch (lexer) @@ -1987,8 +1991,8 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) case SCLEX_XML: case SCLEX_HTML: { - if (sci_get_style_at(doc->sci, line_start) >= 118 && - sci_get_style_at(doc->sci, line_start) <= 127) + if (sci_get_style_at(doc->editor->sci, line_start) >= 118 && + sci_get_style_at(doc->editor->sci, line_start) <= 127) style_comment = SCE_HPHP_COMMENT; else style_comment = SCE_H_COMMENT; break; @@ -1999,7 +2003,7 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) case SCLEX_D: style_comment = SCE_D_COMMENT; break; default: style_comment = SCE_C_COMMENT; } - if (sci_get_style_at(doc->sci, line_start + x) == style_comment) + if (sci_get_style_at(doc->editor->sci, line_start + x) == style_comment) { real_uncomment_multiline(doc); count = 1; @@ -2011,7 +2015,7 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) } } } - SSM(doc->sci, SCI_ENDUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_ENDUNDOACTION, 0, 0); /* restore selection if there is one * but don't touch the selection if caller is editor_do_comment_toggle */ @@ -2019,14 +2023,14 @@ gint editor_do_uncomment(GeanyDocument *doc, gint line, gboolean toggle) { if (single_line) { - sci_set_selection_start(doc->sci, sel_start - co_len); - sci_set_selection_end(doc->sci, sel_end - (count * co_len)); + sci_set_selection_start(doc->editor->sci, sel_start - co_len); + sci_set_selection_end(doc->editor->sci, sel_end - (count * co_len)); } else { gint eol_len = editor_get_eol_char_len(doc); - sci_set_selection_start(doc->sci, sel_start - co_len - eol_len); - sci_set_selection_end(doc->sci, sel_end - co_len - eol_len); + sci_set_selection_start(doc->editor->sci, sel_start - co_len - eol_len); + sci_set_selection_end(doc->editor->sci, sel_end - co_len - eol_len); } } @@ -2050,24 +2054,24 @@ void editor_do_comment_toggle(GeanyDocument *doc) if (doc == NULL || doc->file_type == NULL) return; - sel_start = sci_get_selection_start(doc->sci); - sel_end = sci_get_selection_end(doc->sci); + sel_start = sci_get_selection_start(doc->editor->sci); + sel_end = sci_get_selection_end(doc->editor->sci); ft = doc->file_type; - first_line = sci_get_line_from_position(doc->sci, - sci_get_selection_start(doc->sci)); + first_line = sci_get_line_from_position(doc->editor->sci, + sci_get_selection_start(doc->editor->sci)); /* Find the last line with chars selected (not EOL char) */ - last_line = sci_get_line_from_position(doc->sci, - sci_get_selection_end(doc->sci) - editor_get_eol_char_len(doc)); + last_line = sci_get_line_from_position(doc->editor->sci, + sci_get_selection_end(doc->editor->sci) - editor_get_eol_char_len(doc)); 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(doc->sci, first_line); + first_line_start = sci_get_position_from_line(doc->editor->sci, first_line); if (ft->id == GEANY_FILETYPES_PHP) { - if (sci_get_style_at(doc->sci, first_line_start) < 118 || - sci_get_style_at(doc->sci, first_line_start) > 127) + if (sci_get_style_at(doc->editor->sci, first_line_start) < 118 || + sci_get_style_at(doc->editor->sci, first_line_start) > 127) ft = filetypes[GEANY_FILETYPES_XML]; } @@ -2080,20 +2084,20 @@ void editor_do_comment_toggle(GeanyDocument *doc) if (co_len == 0) return; - SSM(doc->sci, SCI_BEGINUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_BEGINUNDOACTION, 0, 0); for (i = first_line; (i <= last_line) && (! break_loop); i++) { gint buf_len; - line_start = sci_get_position_from_line(doc->sci, i); - line_len = sci_get_line_length(doc->sci, i); + line_start = sci_get_position_from_line(doc->editor->sci, i); + line_len = sci_get_line_length(doc->editor->sci, i); x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len - 1); if (buf_len < 0) continue; - sci_get_text_range(doc->sci, line_start, line_start + buf_len, sel); + sci_get_text_range(doc->editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; @@ -2127,7 +2131,7 @@ void editor_do_comment_toggle(GeanyDocument *doc) else { gint style_comment; - gint lexer = SSM(doc->sci, SCI_GETLEXER, 0, 0); + gint lexer = SSM(doc->editor->sci, SCI_GETLEXER, 0, 0); /* skip lines which are already comments */ switch (lexer) @@ -2135,8 +2139,8 @@ void editor_do_comment_toggle(GeanyDocument *doc) case SCLEX_XML: case SCLEX_HTML: { - if (sci_get_style_at(doc->sci, line_start) >= 118 && - sci_get_style_at(doc->sci, line_start) <= 127) + if (sci_get_style_at(doc->editor->sci, line_start) >= 118 && + sci_get_style_at(doc->editor->sci, line_start) <= 127) style_comment = SCE_HPHP_COMMENT; else style_comment = SCE_H_COMMENT; break; @@ -2149,7 +2153,7 @@ void editor_do_comment_toggle(GeanyDocument *doc) case SCLEX_PERL: style_comment = SCE_PL_POD; break; default: style_comment = SCE_C_COMMENT; } - if (sci_get_style_at(doc->sci, line_start + x) == style_comment) + if (sci_get_style_at(doc->editor->sci, line_start + x) == style_comment) { real_uncomment_multiline(doc); count_uncommented++; @@ -2166,7 +2170,7 @@ void editor_do_comment_toggle(GeanyDocument *doc) } } - SSM(doc->sci, SCI_ENDUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_ENDUNDOACTION, 0, 0); co_len += tm_len; @@ -2178,12 +2182,12 @@ void editor_do_comment_toggle(GeanyDocument *doc) gint a = (first_line_was_comment) ? - co_len : co_len; /* don't modify sel_start when the selection starts within indentation */ - get_indent(doc, sel_start, TRUE); + get_indent(doc->editor, sel_start, TRUE); if ((sel_start - first_line_start) <= (gint) strlen(indent)) a = 0; - sci_set_selection_start(doc->sci, sel_start + a); - sci_set_selection_end(doc->sci, sel_end + + sci_set_selection_start(doc->editor->sci, sel_start + a); + sci_set_selection_end(doc->editor->sci, sel_end + (count_commented * co_len) - (count_uncommented * co_len)); } else @@ -2191,19 +2195,19 @@ void editor_do_comment_toggle(GeanyDocument *doc) gint eol_len = editor_get_eol_char_len(doc); if (count_uncommented > 0) { - sci_set_selection_start(doc->sci, sel_start - co_len - eol_len); - sci_set_selection_end(doc->sci, sel_end - co_len - eol_len); + sci_set_selection_start(doc->editor->sci, sel_start - co_len - eol_len); + sci_set_selection_end(doc->editor->sci, sel_end - co_len - eol_len); } else { - sci_set_selection_start(doc->sci, sel_start + co_len + eol_len); - sci_set_selection_end(doc->sci, sel_end + co_len + eol_len); + sci_set_selection_start(doc->editor->sci, sel_start + co_len + eol_len); + sci_set_selection_end(doc->editor->sci, sel_end + co_len + eol_len); } } } else if (count_uncommented > 0) { - sci_set_current_position(doc->sci, sel_start - co_len, TRUE); + sci_set_current_position(doc->editor->sci, sel_start - co_len, TRUE); } } @@ -2223,29 +2227,29 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines if (line < 0) { /* use selection or current line */ - sel_start = sci_get_selection_start(doc->sci); - sel_end = sci_get_selection_end(doc->sci); + sel_start = sci_get_selection_start(doc->editor->sci); + sel_end = sci_get_selection_end(doc->editor->sci); - first_line = sci_get_line_from_position(doc->sci, sel_start); + first_line = sci_get_line_from_position(doc->editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ - last_line = sci_get_line_from_position(doc->sci, + last_line = sci_get_line_from_position(doc->editor->sci, sel_end - editor_get_eol_char_len(doc)); last_line = MAX(first_line, last_line); } else { first_line = last_line = line; - sel_start = sel_end = sci_get_position_from_line(doc->sci, line); + sel_start = sel_end = sci_get_position_from_line(doc->editor->sci, line); } ft = doc->file_type; /* detection of HTML vs PHP code, if non-PHP set filetype to XML */ - line_start = sci_get_position_from_line(doc->sci, first_line); + line_start = sci_get_position_from_line(doc->editor->sci, first_line); if (ft->id == GEANY_FILETYPES_PHP) { - if (sci_get_style_at(doc->sci, line_start) < 118 || - sci_get_style_at(doc->sci, line_start) > 127) + if (sci_get_style_at(doc->editor->sci, line_start) < 118 || + sci_get_style_at(doc->editor->sci, line_start) > 127) ft = filetypes[GEANY_FILETYPES_XML]; } @@ -2258,20 +2262,20 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines if (co_len == 0) return; - SSM(doc->sci, SCI_BEGINUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_BEGINUNDOACTION, 0, 0); for (i = first_line; (i <= last_line) && (! break_loop); i++) { gint buf_len; - line_start = sci_get_position_from_line(doc->sci, i); - line_len = sci_get_line_length(doc->sci, i); + line_start = sci_get_position_from_line(doc->editor->sci, i); + line_len = sci_get_line_length(doc->editor->sci, i); x = 0; buf_len = MIN((gint)sizeof(sel) - 1, line_len - 1); if (buf_len < 0) continue; - sci_get_text_range(doc->sci, line_start, line_start + buf_len, sel); + sci_get_text_range(doc->editor->sci, line_start, line_start + buf_len, sel); sel[buf_len] = '\0'; while (isspace(sel[x])) x++; @@ -2291,17 +2295,17 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines if (toggle) { gchar *text = g_strconcat(co, GEANY_TOGGLE_MARK, NULL); - sci_insert_text(doc->sci, start, text); + sci_insert_text(doc->editor->sci, start, text); g_free(text); } else - sci_insert_text(doc->sci, start, co); + sci_insert_text(doc->editor->sci, start, co); } /* use multi line comment */ else { gint style_comment; - gint lexer = SSM(doc->sci, SCI_GETLEXER, 0, 0); + gint lexer = SSM(doc->editor->sci, SCI_GETLEXER, 0, 0); /* skip lines which are already comments */ switch (lexer) @@ -2309,8 +2313,8 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines case SCLEX_XML: case SCLEX_HTML: { - if (sci_get_style_at(doc->sci, line_start) >= 118 && - sci_get_style_at(doc->sci, line_start) <= 127) + if (sci_get_style_at(doc->editor->sci, line_start) >= 118 && + sci_get_style_at(doc->editor->sci, line_start) <= 127) style_comment = SCE_HPHP_COMMENT; else style_comment = SCE_H_COMMENT; break; @@ -2321,7 +2325,7 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines case SCLEX_D: style_comment = SCE_D_COMMENT; break; default: style_comment = SCE_C_COMMENT; } - if (sci_get_style_at(doc->sci, line_start + x) == style_comment) continue; + if (sci_get_style_at(doc->editor->sci, line_start + x) == style_comment) continue; real_comment_multiline(doc, line_start, last_line); @@ -2331,7 +2335,7 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines } } } - SSM(doc->sci, SCI_ENDUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_ENDUNDOACTION, 0, 0); /* restore selection if there is one * but don't touch the selection if caller is editor_do_comment_toggle */ @@ -2339,14 +2343,14 @@ void editor_do_comment(GeanyDocument *doc, gint line, gboolean allow_empty_lines { if (single_line) { - sci_set_selection_start(doc->sci, sel_start + co_len); - sci_set_selection_end(doc->sci, sel_end + ((i - first_line) * co_len)); + sci_set_selection_start(doc->editor->sci, sel_start + co_len); + sci_set_selection_end(doc->editor->sci, sel_end + ((i - first_line) * co_len)); } else { gint eol_len = editor_get_eol_char_len(doc); - sci_set_selection_start(doc->sci, sel_start + co_len + eol_len); - sci_set_selection_end(doc->sci, sel_end + co_len + eol_len); + sci_set_selection_start(doc->editor->sci, sel_start + co_len + eol_len); + sci_set_selection_end(doc->editor->sci, sel_end + co_len + eol_len); } } } @@ -2386,10 +2390,11 @@ static gboolean is_doc_comment_char(gchar c, gint lexer) } -static void auto_multiline(GeanyDocument *doc, gint pos) +static void auto_multiline(GeanyEditor *editor, gint pos) { - ScintillaObject *sci = doc->sci; - gint style = SSM(sci, SCI_GETSTYLEAT, pos - 1 - editor_get_eol_char_len(doc), 0); + ScintillaObject *sci = editor->sci; + gint eol_len = editor_get_eol_char_len(editor->document); + gint style = SSM(sci, SCI_GETSTYLEAT, pos - 1 - eol_len, 0); gint lexer = SSM(sci, SCI_GETLEXER, 0, 0); if ((lexer == SCLEX_CPP && (style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC)) || @@ -2667,22 +2672,25 @@ void editor_insert_multiline_comment(GeanyDocument *doc) gint line; gint pos; gboolean have_multiline_comment = FALSE; + GeanyEditor *editor; if (doc == NULL || doc->file_type == NULL || doc->file_type->comment_open == NULL) return; + editor = doc->editor; if (doc->file_type->comment_close != NULL && strlen(doc->file_type->comment_close) > 0) have_multiline_comment = TRUE; /* insert three lines one line above of the current position */ - line = sci_get_line_from_position(doc->sci, editor_info.click_pos); - pos = sci_get_position_from_line(doc->sci, line); + line = sci_get_line_from_position(editor->sci, editor_info.click_pos); + pos = sci_get_position_from_line(editor->sci, line); /* use the indent on the current line but only when comment indentation is used * and we don't have multi line comment characters */ - if (doc->auto_indent && ! have_multiline_comment && doc->file_type->comment_use_indent) + if (editor->auto_indent && + ! have_multiline_comment && doc->file_type->comment_use_indent) { - get_indent(doc, editor_info.click_pos, TRUE); + get_indent(editor, editor_info.click_pos, TRUE); text = g_strdup_printf("%s\n%s\n%s\n", indent, indent, indent); text_len = strlen(text); } @@ -2691,13 +2699,13 @@ void editor_insert_multiline_comment(GeanyDocument *doc) text = g_strdup("\n\n\n"); text_len = 3; } - sci_insert_text(doc->sci, pos, text); + sci_insert_text(editor->sci, pos, text); g_free(text); /* select the inserted lines for commenting */ - sci_set_selection_start(doc->sci, pos); - sci_set_selection_end(doc->sci, pos + text_len); + sci_set_selection_start(editor->sci, pos); + sci_set_selection_end(editor->sci, pos + text_len); editor_do_comment(doc, -1, TRUE, FALSE); @@ -2710,9 +2718,9 @@ void editor_insert_multiline_comment(GeanyDocument *doc) else pos += strlen(indent); - sci_set_current_position(doc->sci, pos, TRUE); + sci_set_current_position(editor->sci, pos, TRUE); /* reset the selection */ - sci_set_anchor(doc->sci, pos); + sci_set_anchor(editor->sci, pos); } @@ -2742,11 +2750,11 @@ void editor_scroll_to_line(ScintillaObject *sci, gint line, gfloat percent_of_vi } -void editor_insert_alternative_whitespace(GeanyDocument *doc) +void editor_insert_alternative_whitespace(GeanyEditor *editor) { - /* creates and inserts one tabulator sign or whitespace of the amount of the tab width */ - gchar *text = get_whitespace(editor_prefs.tab_width, ! doc->use_tabs); - sci_add_text(doc->sci, text); + /* creates and inserts one tab or whitespace of the amount of the tab width */ + gchar *text = get_whitespace(editor_prefs.tab_width, ! editor->use_tabs); + sci_add_text(editor->sci, text); g_free(text); } @@ -2887,18 +2895,18 @@ static void smart_line_indentation(GeanyDocument *doc, gint first_line, gint las { /* skip the first line or if the indentation of the previous and current line are equal */ if (i == 0 || - SSM(doc->sci, SCI_GETLINEINDENTATION, i - 1, 0) == - SSM(doc->sci, SCI_GETLINEINDENTATION, i, 0)) + SSM(doc->editor->sci, SCI_GETLINEINDENTATION, i - 1, 0) == + SSM(doc->editor->sci, SCI_GETLINEINDENTATION, i, 0)) continue; - sel_start = SSM(doc->sci, SCI_POSITIONFROMLINE, i, 0); - sel_end = SSM(doc->sci, SCI_GETLINEINDENTPOSITION, i, 0); + sel_start = SSM(doc->editor->sci, SCI_POSITIONFROMLINE, i, 0); + sel_end = SSM(doc->editor->sci, SCI_GETLINEINDENTPOSITION, i, 0); if (sel_start < sel_end) { - SSM(doc->sci, SCI_SETSEL, sel_start, sel_end); - sci_replace_sel(doc->sci, ""); + SSM(doc->editor->sci, SCI_SETSEL, sel_start, sel_end); + sci_replace_sel(doc->editor->sci, ""); } - sci_insert_text(doc->sci, sel_start, indent); + sci_insert_text(doc->editor->sci, sel_start, indent); } } @@ -2912,7 +2920,7 @@ void editor_smart_line_indentation(GeanyDocument *doc, gint pos) g_return_if_fail(doc != NULL); - sci = doc->sci; + sci = doc->editor->sci; first_sel_start = sci_get_selection_start(sci); first_sel_end = sci_get_selection_end(sci); @@ -2929,7 +2937,7 @@ void editor_smart_line_indentation(GeanyDocument *doc, gint pos) /* get previous line and use it for get_indent to use that line * (otherwise it would fail on a line only containing "{" in advanced indentation mode) */ - get_indent(doc, sci_get_position_from_line(sci, first_line - 1), TRUE); + get_indent(doc->editor, sci_get_position_from_line(sci, first_line - 1), TRUE); smart_line_indentation(doc, first_line, last_line); @@ -2960,33 +2968,33 @@ void editor_indentation_by_one_space(GeanyDocument *doc, gint pos, gboolean decr g_return_if_fail(doc != NULL); - sel_start = sci_get_selection_start(doc->sci); - sel_end = sci_get_selection_end(doc->sci); + sel_start = sci_get_selection_start(doc->editor->sci); + sel_end = sci_get_selection_end(doc->editor->sci); - first_line = sci_get_line_from_position(doc->sci, sel_start); + first_line = sci_get_line_from_position(doc->editor->sci, sel_start); /* Find the last line with chars selected (not EOL char) */ - last_line = sci_get_line_from_position(doc->sci, sel_end - editor_get_eol_char_len(doc)); + last_line = sci_get_line_from_position(doc->editor->sci, sel_end - editor_get_eol_char_len(doc)); last_line = MAX(first_line, last_line); if (pos == -1) pos = sel_start; - SSM(doc->sci, SCI_BEGINUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_BEGINUNDOACTION, 0, 0); for (i = first_line; i <= last_line; i++) { - indentation_end = SSM(doc->sci, SCI_GETLINEINDENTPOSITION, i, 0); + indentation_end = SSM(doc->editor->sci, SCI_GETLINEINDENTPOSITION, i, 0); if (decrease) { - line_start = SSM(doc->sci, SCI_POSITIONFROMLINE, i, 0); + line_start = SSM(doc->editor->sci, SCI_POSITIONFROMLINE, i, 0); /* searching backwards for a space to remove */ - while (sci_get_char_at(doc->sci, indentation_end) != ' ' && indentation_end > line_start) + while (sci_get_char_at(doc->editor->sci, indentation_end) != ' ' && indentation_end > line_start) indentation_end--; - if (sci_get_char_at(doc->sci, indentation_end) == ' ') + if (sci_get_char_at(doc->editor->sci, indentation_end) == ' ') { - SSM(doc->sci, SCI_SETSEL, indentation_end, indentation_end + 1); - sci_replace_sel(doc->sci, ""); + SSM(doc->editor->sci, SCI_SETSEL, indentation_end, indentation_end + 1); + sci_replace_sel(doc->editor->sci, ""); count--; if (i == first_line) first_line_offset = -1; @@ -2994,7 +3002,7 @@ void editor_indentation_by_one_space(GeanyDocument *doc, gint pos, gboolean decr } else { - sci_insert_text(doc->sci, indentation_end, " "); + sci_insert_text(doc->editor->sci, indentation_end, " "); count++; if (i == first_line) first_line_offset = 1; @@ -3007,15 +3015,15 @@ void editor_indentation_by_one_space(GeanyDocument *doc, gint pos, gboolean decr gint start = sel_start + first_line_offset; if (first_line_offset < 0) start = MAX(sel_start + first_line_offset, - SSM(doc->sci, SCI_POSITIONFROMLINE, first_line, 0)); + SSM(doc->editor->sci, SCI_POSITIONFROMLINE, first_line, 0)); - sci_set_selection_start(doc->sci, start); - sci_set_selection_end(doc->sci, sel_end + count); + sci_set_selection_start(doc->editor->sci, start); + sci_set_selection_end(doc->editor->sci, sel_end + count); } else - sci_set_current_position(doc->sci, pos + count, FALSE); + sci_set_current_position(doc->editor->sci, pos + count, FALSE); - SSM(doc->sci, SCI_ENDUNDOACTION, 0, 0); + SSM(doc->editor->sci, SCI_ENDUNDOACTION, 0, 0); } @@ -3035,18 +3043,18 @@ gchar *editor_get_default_selection(GeanyDocument *doc, gboolean use_current_wor if (doc == NULL) return NULL; - if (sci_get_lines_selected(doc->sci) == 1) + if (sci_get_lines_selected(doc->editor->sci) == 1) { - gint len = sci_get_selected_text_length(doc->sci); + gint len = sci_get_selected_text_length(doc->editor->sci); s = g_malloc(len + 1); - sci_get_selected_text(doc->sci, s); + sci_get_selected_text(doc->editor->sci, s); } - else if (sci_get_lines_selected(doc->sci) == 0 && use_current_word) + else if (sci_get_lines_selected(doc->editor->sci) == 0 && use_current_word) { /* use the word at current cursor position */ gchar word[GEANY_MAX_WORD_LENGTH]; - editor_find_current_word(doc->sci, -1, word, sizeof(word), wordchars); + editor_find_current_word(doc->editor->sci, -1, word, sizeof(word), wordchars); if (word[0] != '\0') s = g_strdup(word); } @@ -3076,70 +3084,70 @@ gboolean editor_line_in_view(ScintillaObject *sci, gint line) /* If the current line is outside the current view window, scroll the line * so it appears at percent_of_view. */ -void editor_display_current_line(GeanyDocument *doc, gfloat percent_of_view) +void editor_display_current_line(GeanyEditor *editor, gfloat percent_of_view) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = editor->sci; gint line = sci_get_current_line(sci); /* unfold maybe folded results */ - sci_ensure_line_is_visible(doc->sci, line); + sci_ensure_line_is_visible(editor->sci, line); /* scroll the line if it's off screen */ if (! editor_line_in_view(sci, line)) - doc->scroll_percent = percent_of_view; + editor->scroll_percent = percent_of_view; } /** - * Deletes all currently set indicators in the @a document. + * Deletes all currently set indicators in the @a editor window. * Error indicators (red squiggly underlines) and usual line markers are removed. * - * @param doc The document to operate on. + * @param editor The editor to operate on. **/ -void editor_clear_indicators(GeanyDocument *doc) +void editor_clear_indicators(GeanyEditor *editor) { glong last_pos; - g_return_if_fail(doc != NULL); + g_return_if_fail(editor != NULL); - last_pos = sci_get_length(doc->sci); + last_pos = sci_get_length(editor->sci); if (last_pos > 0) { - sci_start_styling(doc->sci, 0, INDIC2_MASK); - sci_set_styling(doc->sci, last_pos, 0); + sci_start_styling(editor->sci, 0, INDIC2_MASK); + sci_set_styling(editor->sci, last_pos, 0); } - sci_marker_delete_all(doc->sci, 0); /* remove the yellow error line marker */ + sci_marker_delete_all(editor->sci, 0); /* remove the yellow error line marker */ } /** - * This is a convenience function for document_set_indicator(). It sets an error indicator + * This is a convenience function for editor_set_indicator(). It sets an error indicator * (red squiggly underline) on the whole given line. * Whitespace at the start and the end of the line is not marked. * - * @param doc The document to operate on. + * @param editor The editor to operate on. * @param line The line number which should be marked. **/ -void editor_set_indicator_on_line(GeanyDocument *doc, gint line) +void editor_set_indicator_on_line(GeanyEditor *editor, gint line) { gint start, end; guint i = 0, len; gchar *linebuf; - if (doc == NULL) + if (editor == NULL) return; - start = sci_get_position_from_line(doc->sci, line); - end = sci_get_position_from_line(doc->sci, line + 1); + start = sci_get_position_from_line(editor->sci, line); + end = sci_get_position_from_line(editor->sci, line + 1); /* skip blank lines */ if ((start + 1) == end || - sci_get_line_length(doc->sci, line) == editor_get_eol_char_len(doc)) + sci_get_line_length(editor->sci, line) == editor_get_eol_char_len(editor->document)) return; /* don't set the indicator on whitespace */ len = end - start; - linebuf = sci_get_line(doc->sci, line); + linebuf = sci_get_line(editor->sci, line); while (isspace(linebuf[i])) i++; while (len > 1 && len > i && isspace(linebuf[len-1])) @@ -3149,7 +3157,7 @@ void editor_set_indicator_on_line(GeanyDocument *doc, gint line) } g_free(linebuf); - editor_set_indicator(doc, start + i, end); + editor_set_indicator(editor, start + i, end); } @@ -3158,23 +3166,23 @@ void editor_set_indicator_on_line(GeanyDocument *doc, gint line) * No error checking or whitespace removal is performed, this should be done by the calling * function if necessary. * - * @param doc The document to operate on. + * @param editor The editor to operate on. * @param start The starting position for the marker. * @param end The ending position for the marker. **/ -void editor_set_indicator(GeanyDocument *doc, gint start, gint end) +void editor_set_indicator(GeanyEditor *editor, gint start, gint end) { gint current_mask; - if (doc == NULL || start >= end) + if (editor == NULL || start >= end) return; - current_mask = sci_get_style_at(doc->sci, start); + current_mask = sci_get_style_at(editor->sci, start); current_mask &= INDICS_MASK; current_mask |= INDIC2_MASK; - sci_start_styling(doc->sci, start, INDIC2_MASK); - sci_set_styling(doc->sci, end - start, current_mask); + sci_start_styling(editor->sci, start, INDIC2_MASK); + sci_set_styling(editor->sci, end - start, current_mask); } @@ -3184,26 +3192,26 @@ void editor_insert_color(GeanyDocument *doc, const gchar *colour) { g_return_if_fail(doc != NULL); - if (sci_can_copy(doc->sci)) + if (sci_can_copy(doc->editor->sci)) { - gint start = sci_get_selection_start(doc->sci); + gint start = sci_get_selection_start(doc->editor->sci); const gchar *replacement = colour; - if (sci_get_char_at(doc->sci, start) == '0' && - sci_get_char_at(doc->sci, start + 1) == 'x') + if (sci_get_char_at(doc->editor->sci, start) == '0' && + sci_get_char_at(doc->editor->sci, start + 1) == 'x') { - sci_set_selection_start(doc->sci, start + 2); - sci_set_selection_end(doc->sci, start + 8); + sci_set_selection_start(doc->editor->sci, start + 2); + sci_set_selection_end(doc->editor->sci, start + 8); replacement++; /* skip the leading "0x" */ } - else if (sci_get_char_at(doc->sci, start - 1) == '#') + else if (sci_get_char_at(doc->editor->sci, start - 1) == '#') { /* double clicking something like #00ffff may only select 00ffff because of wordchars */ replacement++; /* so skip the '#' to only replace the colour value */ } - sci_replace_sel(doc->sci, replacement); + sci_replace_sel(doc->editor->sci, replacement); } else - sci_add_text(doc->sci, colour); + sci_add_text(doc->editor->sci, colour); } @@ -3212,7 +3220,7 @@ const gchar *editor_get_eol_char_name(GeanyDocument *doc) if (doc == NULL) return ""; - switch (sci_get_eol_mode(doc->sci)) + switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CRLF: return _("Win (CRLF)"); break; case SC_EOL_CR: return _("Mac (CR)"); break; @@ -3227,7 +3235,7 @@ gint editor_get_eol_char_len(GeanyDocument *doc) if (doc == NULL) return 0; - switch (sci_get_eol_mode(doc->sci)) + switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CRLF: return 2; break; default: return 1; break; @@ -3241,7 +3249,7 @@ const gchar *editor_get_eol_char(GeanyDocument *doc) if (doc == NULL) return ""; - switch (sci_get_eol_mode(doc->sci)) + switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CRLF: return "\r\n"; break; case SC_EOL_CR: return "\r"; break; @@ -3256,19 +3264,19 @@ static void fold_all(GeanyDocument *doc, gboolean want_fold) if (doc == NULL || ! editor_prefs.folding) return; - lines = sci_get_line_count(doc->sci); - first = sci_get_first_visible_line(doc->sci); + lines = sci_get_line_count(doc->editor->sci); + first = sci_get_first_visible_line(doc->editor->sci); for (i = 0; i < lines; i++) { - gint level = sci_get_fold_level(doc->sci, i); + gint level = sci_get_fold_level(doc->editor->sci, i); if (level & SC_FOLDLEVELHEADERFLAG) { - if (sci_get_fold_expanded(doc->sci, i) == want_fold) - sci_toggle_fold(doc->sci, i); + if (sci_get_fold_expanded(doc->editor->sci, i) == want_fold) + sci_toggle_fold(doc->editor->sci, i); } } - editor_scroll_to_line(doc->sci, first, 0.0F); + editor_scroll_to_line(doc->editor->sci, first, 0.0F); } @@ -3294,31 +3302,31 @@ void editor_replace_tabs(GeanyDocument *doc) if (doc == NULL) return; - sci_start_undo_action(doc->sci); - tab_len = sci_get_tab_width(doc->sci); + sci_start_undo_action(doc->editor->sci); + tab_len = sci_get_tab_width(doc->editor->sci); ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = sci_get_length(doc->sci); + ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar*) "\t"; while (TRUE) { - search_pos = sci_find_text(doc->sci, SCFIND_MATCHCASE, &ttf); + search_pos = sci_find_text(doc->editor->sci, SCFIND_MATCHCASE, &ttf); if (search_pos == -1) break; - pos_in_line = sci_get_col_from_position(doc->sci,search_pos); + pos_in_line = sci_get_col_from_position(doc->editor->sci,search_pos); current_tab_true_length = tab_len - (pos_in_line % tab_len); tab_str = g_strnfill(current_tab_true_length, ' '); - sci_target_start(doc->sci, search_pos); - sci_target_end(doc->sci, search_pos + 1); - sci_target_replace(doc->sci, tab_str, FALSE); + sci_target_start(doc->editor->sci, search_pos); + sci_target_end(doc->editor->sci, search_pos + 1); + sci_target_replace(doc->editor->sci, tab_str, FALSE); /* next search starts after replacement */ ttf.chrg.cpMin = search_pos + current_tab_true_length - 1; /* update end of range now text has changed */ ttf.chrg.cpMax += current_tab_true_length - 1; g_free(tab_str); } - sci_end_undo_action(doc->sci); + sci_end_undo_action(doc->editor->sci); } @@ -3334,7 +3342,7 @@ void editor_replace_spaces(GeanyDocument *doc) return; if (tab_len_f < 0.0) - tab_len_f = sci_get_tab_width(doc->sci); + tab_len_f = sci_get_tab_width(doc->editor->sci); if (! dialogs_show_input_numeric( _("Enter Tab Width"), @@ -3345,79 +3353,79 @@ void editor_replace_spaces(GeanyDocument *doc) } tab_len = (gint) tab_len_f; - sci_start_undo_action(doc->sci); + sci_start_undo_action(doc->editor->sci); ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = sci_get_length(doc->sci); + ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = g_strnfill(tab_len, ' '); while (TRUE) { - search_pos = sci_find_text(doc->sci, SCFIND_MATCHCASE, &ttf); + search_pos = sci_find_text(doc->editor->sci, SCFIND_MATCHCASE, &ttf); if (search_pos == -1) break; - sci_target_start(doc->sci, search_pos); - sci_target_end(doc->sci, search_pos + tab_len); - sci_target_replace(doc->sci, "\t", FALSE); + sci_target_start(doc->editor->sci, search_pos); + sci_target_end(doc->editor->sci, search_pos + tab_len); + sci_target_replace(doc->editor->sci, "\t", FALSE); ttf.chrg.cpMin = search_pos; /* update end of range now text has changed */ ttf.chrg.cpMax -= tab_len - 1; } - sci_end_undo_action(doc->sci); + sci_end_undo_action(doc->editor->sci); g_free(ttf.lpstrText); } void editor_strip_line_trailing_spaces(GeanyDocument *doc, gint line) { - gint line_start = sci_get_position_from_line(doc->sci, line); - gint line_end = sci_get_line_end_position(doc->sci, line); + gint line_start = sci_get_position_from_line(doc->editor->sci, line); + gint line_end = sci_get_line_end_position(doc->editor->sci, line); gint i = line_end - 1; - gchar ch = sci_get_char_at(doc->sci, i); + gchar ch = sci_get_char_at(doc->editor->sci, i); while ((i >= line_start) && ((ch == ' ') || (ch == '\t'))) { i--; - ch = sci_get_char_at(doc->sci, i); + ch = sci_get_char_at(doc->editor->sci, i); } if (i < (line_end-1)) { - sci_target_start(doc->sci, i + 1); - sci_target_end(doc->sci, line_end); - sci_target_replace(doc->sci, "", FALSE); + sci_target_start(doc->editor->sci, i + 1); + sci_target_end(doc->editor->sci, line_end); + sci_target_replace(doc->editor->sci, "", FALSE); } } void editor_strip_trailing_spaces(GeanyDocument *doc) { - gint max_lines = sci_get_line_count(doc->sci); + gint max_lines = sci_get_line_count(doc->editor->sci); gint line; - sci_start_undo_action(doc->sci); + sci_start_undo_action(doc->editor->sci); for (line = 0; line < max_lines; line++) { editor_strip_line_trailing_spaces(doc, line); } - sci_end_undo_action(doc->sci); + sci_end_undo_action(doc->editor->sci); } void editor_ensure_final_newline(GeanyDocument *doc) { - gint max_lines = sci_get_line_count(doc->sci); + gint max_lines = sci_get_line_count(doc->editor->sci); gboolean append_newline = (max_lines == 1); - gint end_document = sci_get_position_from_line(doc->sci, max_lines); + gint end_document = sci_get_position_from_line(doc->editor->sci, max_lines); if (max_lines > 1) { - append_newline = end_document > sci_get_position_from_line(doc->sci, max_lines - 1); + append_newline = end_document > sci_get_position_from_line(doc->editor->sci, max_lines - 1); } if (append_newline) { const gchar *eol = "\n"; - switch (sci_get_eol_mode(doc->sci)) + switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CRLF: eol = "\r\n"; @@ -3426,69 +3434,82 @@ void editor_ensure_final_newline(GeanyDocument *doc) eol = "\r"; break; } - sci_insert_text(doc->sci, end_document, eol); + sci_insert_text(doc->editor->sci, end_document, eol); } } -void editor_set_font(GeanyDocument *doc, const gchar *font_name, gint size) +void editor_set_font(GeanyEditor *editor, const gchar *font) { - gint style; + gint style, size; + gchar *font_name; + PangoFontDescription *pfd; + + g_return_if_fail(editor); + + pfd = pango_font_description_from_string(font); + size = pango_font_description_get_size(pfd) / PANGO_SCALE; + font_name = g_strdup_printf("!%s", pango_font_description_get_family(pfd)); + pango_font_description_free(pfd); for (style = 0; style <= 127; style++) - sci_set_font(doc->sci, style, font_name, size); + sci_set_font(editor->sci, style, font_name, size); + /* line number and braces */ - sci_set_font(doc->sci, STYLE_LINENUMBER, font_name, size); - sci_set_font(doc->sci, STYLE_BRACELIGHT, font_name, size); - sci_set_font(doc->sci, STYLE_BRACEBAD, font_name, size); + sci_set_font(editor->sci, STYLE_LINENUMBER, font_name, size); + sci_set_font(editor->sci, STYLE_BRACELIGHT, font_name, size); + sci_set_font(editor->sci, STYLE_BRACEBAD, font_name, size); + g_free(font_name); + /* zoom to 100% to prevent confusion */ - sci_zoom_off(doc->sci); + sci_zoom_off(editor->sci); } -void editor_set_line_wrapping(GeanyDocument *doc, gboolean wrap) +void editor_set_line_wrapping(GeanyEditor *editor, gboolean wrap) { - g_return_if_fail(doc != NULL); + g_return_if_fail(editor != NULL); - doc->line_wrapping = wrap; - sci_set_lines_wrapped(doc->sci, wrap); + editor->line_wrapping = wrap; + sci_set_lines_wrapped(editor->sci, wrap); } -void editor_set_use_tabs(GeanyDocument *doc, gboolean use_tabs) +void editor_set_use_tabs(GeanyEditor *editor, gboolean use_tabs) { - g_return_if_fail(doc != NULL); + g_return_if_fail(editor != NULL); - doc->use_tabs = use_tabs; - sci_set_use_tabs(doc->sci, use_tabs); + editor->use_tabs = use_tabs; + sci_set_use_tabs(editor->sci, use_tabs); /* remove indent spaces on backspace, if using spaces to indent */ - SSM(doc->sci, SCI_SETBACKSPACEUNINDENTS, ! use_tabs, 0); + SSM(editor->sci, SCI_SETBACKSPACEUNINDENTS, ! use_tabs, 0); } /* Move to position @a pos, switching to the document if necessary, * setting a marker if @a mark is set. */ -gboolean editor_goto_pos(GeanyDocument *doc, gint pos, gboolean mark) +gboolean editor_goto_pos(GeanyEditor *editor, gint pos, gboolean mark) { gint page_num; - if (doc == NULL || pos < 0) + g_return_val_if_fail(editor, FALSE); + if (pos < 0) return FALSE; if (mark) { - gint line = sci_get_line_from_position(doc->sci, pos); + gint line = sci_get_line_from_position(editor->sci, pos); /* mark the tag with the yellow arrow */ - sci_marker_delete_all(doc->sci, 0); - sci_set_marker_at_line(doc->sci, line, TRUE, 0); + sci_marker_delete_all(editor->sci, 0); + sci_set_marker_at_line(editor->sci, line, TRUE, 0); } - sci_goto_pos(doc->sci, pos, TRUE); - doc->scroll_percent = 0.25F; + sci_goto_pos(editor->sci, pos, TRUE); + editor->scroll_percent = 0.25F; /* finally switch to the page */ - page_num = gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), GTK_WIDGET(doc->sci)); + page_num = gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), GTK_WIDGET(editor->sci)); gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), page_num); return TRUE; @@ -3503,7 +3524,7 @@ on_editor_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer user_d if (event->state & GDK_MOD1_MASK) { GeanyDocument *doc = user_data; - sci_cmd(doc->sci, (event->direction == GDK_SCROLL_DOWN) ? SCI_PAGEDOWN : SCI_PAGEUP); + sci_cmd(doc->editor->sci, (event->direction == GDK_SCROLL_DOWN) ? SCI_PAGEDOWN : SCI_PAGEUP); return TRUE; } @@ -3517,7 +3538,7 @@ static void editor_colourise(ScintillaObject *sci) /* now that the current document is colourised, fold points are now accurate, * so force an update of the current function/tag. */ - utils_get_current_function(NULL, NULL); + symbols_get_current_function(NULL, NULL); ui_update_statusbar(NULL, -1); } @@ -3529,7 +3550,7 @@ static gboolean on_editor_expose_event(GtkWidget *widget, GdkEventExpose *event, if (DOCUMENT(doc)->colourise_needed) { - editor_colourise(doc->sci); + editor_colourise(doc->editor->sci); DOCUMENT(doc)->colourise_needed = FALSE; } return FALSE; /* propagate event */ @@ -3570,7 +3591,7 @@ static void setup_sci_keys(ScintillaObject *sci) /* Create new editor widget (scintilla). * @note The @c "sci-notify" signal is connected separately. */ -ScintillaObject *editor_create_new_sci(GeanyDocument *doc) +static ScintillaObject *create_new_sci(GeanyDocument *doc) { ScintillaObject *sci; @@ -3613,3 +3634,19 @@ ScintillaObject *editor_create_new_sci(GeanyDocument *doc) } +GeanyEditor *editor_create(GeanyDocument *doc) +{ + GeanyEditor *editor = g_new0(GeanyEditor, 1); + + editor->document = doc; + + editor->auto_indent = (editor_prefs.indent_mode != INDENT_NONE); + editor->line_wrapping = editor_prefs.line_wrapping; + editor->scroll_percent = -1.0F; + editor->line_breaking = FALSE; + + editor->sci = create_new_sci(doc); + editor_set_font(editor, interface_prefs.editor_font); + return editor; +} + diff --git a/src/editor.h b/src/editor.h index 0d6803f56..b381409c9 100644 --- a/src/editor.h +++ b/src/editor.h @@ -99,6 +99,21 @@ typedef struct GeanyEditorPrefs extern GeanyEditorPrefs editor_prefs; +/** Editor-owned fields for each document. */ +typedef struct GeanyEditor +{ + GeanyDocument *document; /**< The document associated with the editor. */ + ScintillaObject *sci; /**< The Scintilla editor @c GtkWidget. */ + gboolean line_wrapping; /**< @c TRUE if line wrapping is enabled. */ + gboolean auto_indent; /**< @c TRUE if auto-indentation is enabled. */ + /** Percentage to scroll view by on paint, if positive. */ + gfloat scroll_percent; + gboolean use_tabs; /**< @c TRUE if tabs are used for indentation. */ + gboolean line_breaking; /**< Whether to split long lines as you type. */ +} +GeanyEditor; + + typedef struct { gchar *current_word; /* holds word under the mouse or keyboard cursor */ @@ -110,7 +125,7 @@ extern EditorInfo editor_info; -ScintillaObject *editor_create_new_sci(GeanyDocument *doc); +GeanyEditor *editor_create(GeanyDocument *doc); void on_editor_notification(GtkWidget* editor, gint scn, gpointer lscn, gpointer user_data); @@ -140,7 +155,7 @@ gint editor_lexer_get_type_keyword_idx(gint lexer); void editor_insert_multiline_comment(GeanyDocument *doc); -void editor_insert_alternative_whitespace(GeanyDocument *doc); +void editor_insert_alternative_whitespace(GeanyEditor *editor); void editor_smart_line_indentation(GeanyDocument *doc, gint pos); @@ -150,7 +165,7 @@ gboolean editor_line_in_view(ScintillaObject *sci, gint line); void editor_scroll_to_line(ScintillaObject *sci, gint line, gfloat percent_of_view); -void editor_display_current_line(GeanyDocument *doc, gfloat percent_of_view); +void editor_display_current_line(GeanyEditor *editor, gfloat percent_of_view); void editor_finalize(void); @@ -171,13 +186,13 @@ void editor_select_lines(ScintillaObject *sci, gboolean extra_line); void editor_select_paragraph(ScintillaObject *sci); -void editor_set_indicator_on_line(GeanyDocument *doc, gint line); +void editor_set_indicator_on_line(GeanyEditor *editor, gint line); -void editor_set_indicator(GeanyDocument *doc, gint start, gint end); +void editor_set_indicator(GeanyEditor *editor, gint start, gint end); -void editor_clear_indicators(GeanyDocument *doc); +void editor_clear_indicators(GeanyEditor *editor); -void editor_set_font(GeanyDocument *doc, const gchar *font_name, gint size); +void editor_set_font(GeanyEditor *editor, const gchar *font); const gchar *editor_get_eol_char_name(GeanyDocument *doc); @@ -201,10 +216,10 @@ void editor_ensure_final_newline(GeanyDocument *doc); void editor_insert_color(GeanyDocument *doc, const gchar *colour); -void editor_set_use_tabs(GeanyDocument *doc, gboolean use_tabs); +void editor_set_use_tabs(GeanyEditor *editor, gboolean use_tabs); -void editor_set_line_wrapping(GeanyDocument *doc, gboolean wrap); +void editor_set_line_wrapping(GeanyEditor *editor, gboolean wrap); -gboolean editor_goto_pos(GeanyDocument *doc, gint pos, gboolean mark); +gboolean editor_goto_pos(GeanyEditor *editor, gint pos, gboolean mark); #endif diff --git a/src/filetypes.c b/src/filetypes.c index 9842453af..c338e5ec1 100644 --- a/src/filetypes.c +++ b/src/filetypes.c @@ -34,6 +34,7 @@ #include "support.h" #include "templates.h" #include "document.h" +#include "editor.h" #include "msgwindow.h" #include "utils.h" #include "sciwrappers.h" @@ -674,7 +675,7 @@ GeanyFiletype *filetypes_detect_from_file(GeanyDocument *doc) if (doc == NULL) return filetypes[GEANY_FILETYPES_NONE]; - line = sci_get_line(doc->sci, 0); + line = sci_get_line(doc->editor->sci, 0); ft = filetypes_detect_from_file_internal(doc->file_name, line); g_free(line); return ft; diff --git a/src/keybindings.c b/src/keybindings.c index ac9b75915..a5f5916bc 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -816,9 +816,9 @@ static gboolean check_snippet_completion(guint keyval, guint state) GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* keybinding only valid when scintilla widget has focus */ - if (doc != NULL && focusw == GTK_WIDGET(doc->sci)) + if (doc != NULL && focusw == GTK_WIDGET(doc->editor->sci)) { - ScintillaObject *sci = doc->sci; + ScintillaObject *sci = doc->editor->sci; gint pos = sci_get_current_position(sci); if (editor_prefs.complete_snippets) @@ -1174,9 +1174,9 @@ static gboolean check_current_word(void) if (doc == NULL) return FALSE; - pos = sci_get_current_position(doc->sci); + pos = sci_get_current_position(doc->editor->sci); - editor_find_current_word(doc->sci, pos, + editor_find_current_word(doc->editor->sci, pos, editor_info.current_word, GEANY_MAX_WORD_LENGTH, NULL); if (*editor_info.current_word == 0) @@ -1209,7 +1209,7 @@ static void cb_func_switch_action(guint key_id) { GeanyDocument *doc = document_get_current(); if (doc != NULL) - gtk_widget_grab_focus(GTK_WIDGET(doc->sci)); + gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); break; } case GEANY_KEYS_FOCUS_SCRIBBLE: @@ -1284,7 +1284,7 @@ static void cb_func_move_tab(guint key_id) if (doc == NULL) return; - sci = GTK_WIDGET(doc->sci); + sci = GTK_WIDGET(doc->editor->sci); switch (key_id) { @@ -1329,15 +1329,15 @@ static void goto_matching_brace(GeanyDocument *doc) if (doc == NULL) return; - pos = sci_get_current_position(doc->sci); - if (! utils_isbrace(sci_get_char_at(doc->sci, pos), TRUE)) + pos = sci_get_current_position(doc->editor->sci); + if (! utils_isbrace(sci_get_char_at(doc->editor->sci, pos), TRUE)) pos--; /* set pos to the brace */ - new_pos = sci_find_bracematch(doc->sci, pos); + new_pos = sci_find_bracematch(doc->editor->sci, pos); if (new_pos != -1) { /* set the cursor at the brace */ - sci_set_current_position(doc->sci, new_pos, FALSE); - editor_display_current_line(doc, 0.5F); + sci_set_current_position(doc->editor->sci, new_pos, FALSE); + editor_display_current_line(doc->editor, 0.5F); } } @@ -1361,10 +1361,10 @@ static void cb_func_clipboard(guint key_id) on_paste1_activate(NULL, NULL); break; case GEANY_KEYS_CLIPBOARD_COPYLINE: - sci_cmd(doc->sci, SCI_LINECOPY); + sci_cmd(doc->editor->sci, SCI_LINECOPY); break; case GEANY_KEYS_CLIPBOARD_CUTLINE: - sci_cmd(doc->sci, SCI_LINECUT); + sci_cmd(doc->editor->sci, SCI_LINECUT); break; } } @@ -1379,7 +1379,7 @@ static void cb_func_goto_action(guint key_id) if (doc == NULL) return; - cur_line = sci_get_current_line(doc->sci); + cur_line = sci_get_current_line(doc->editor->sci); switch (key_id) { @@ -1397,30 +1397,30 @@ static void cb_func_goto_action(guint key_id) return; case GEANY_KEYS_GOTO_TOGGLEMARKER: { - gboolean set = sci_is_marker_set_at_line(doc->sci, cur_line, 1); + gboolean set = sci_is_marker_set_at_line(doc->editor->sci, cur_line, 1); - sci_set_marker_at_line(doc->sci, cur_line, ! set, 1); + sci_set_marker_at_line(doc->editor->sci, cur_line, ! set, 1); return; } case GEANY_KEYS_GOTO_NEXTMARKER: { - gint mline = sci_marker_next(doc->sci, cur_line + 1, 1 << 1, TRUE); + gint mline = sci_marker_next(doc->editor->sci, cur_line + 1, 1 << 1, TRUE); if (mline != -1) { - sci_set_current_line(doc->sci, mline); - editor_display_current_line(doc, 0.5F); + sci_set_current_line(doc->editor->sci, mline); + editor_display_current_line(doc->editor, 0.5F); } return; } case GEANY_KEYS_GOTO_PREVIOUSMARKER: { - gint mline = sci_marker_previous(doc->sci, cur_line - 1, 1 << 1, TRUE); + gint mline = sci_marker_previous(doc->editor->sci, cur_line - 1, 1 << 1, TRUE); if (mline != -1) { - sci_set_current_line(doc->sci, mline); - editor_display_current_line(doc, 0.5F); + sci_set_current_line(doc->editor->sci, mline); + editor_display_current_line(doc->editor, 0.5F); } return; } @@ -1434,7 +1434,7 @@ static void cb_func_goto_action(guint key_id) return; } /* only check editor-sensitive keybindings when editor has focus */ - if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->sci)) + if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->editor->sci)) { ignore_keybinding = TRUE; return; @@ -1442,10 +1442,10 @@ static void cb_func_goto_action(guint key_id) switch (key_id) { case GEANY_KEYS_GOTO_LINESTART: - sci_cmd(doc->sci, editor_prefs.smart_home_key ? SCI_VCHOME : SCI_HOME); + sci_cmd(doc->editor->sci, editor_prefs.smart_home_key ? SCI_VCHOME : SCI_HOME); break; case GEANY_KEYS_GOTO_LINEEND: - sci_cmd(doc->sci, SCI_LINEEND); + sci_cmd(doc->editor->sci, SCI_LINEEND); break; } } @@ -1479,7 +1479,7 @@ static void cb_func_editor_action(guint key_id) GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* edit keybindings only valid when scintilla widget has focus */ - if (doc == NULL || focusw != GTK_WIDGET(doc->sci)) + if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return; switch (key_id) @@ -1491,31 +1491,31 @@ static void cb_func_editor_action(guint key_id) on_redo1_activate(NULL, NULL); break; case GEANY_KEYS_EDITOR_SCROLLTOLINE: - editor_scroll_to_line(doc->sci, -1, 0.5F); + editor_scroll_to_line(doc->editor->sci, -1, 0.5F); break; case GEANY_KEYS_EDITOR_SCROLLLINEUP: - sci_cmd(doc->sci, SCI_LINESCROLLUP); + sci_cmd(doc->editor->sci, SCI_LINESCROLLUP); break; case GEANY_KEYS_EDITOR_SCROLLLINEDOWN: - sci_cmd(doc->sci, SCI_LINESCROLLDOWN); + sci_cmd(doc->editor->sci, SCI_LINESCROLLDOWN); break; case GEANY_KEYS_EDITOR_DUPLICATELINE: - duplicate_lines(doc->sci); + duplicate_lines(doc->editor->sci); break; case GEANY_KEYS_EDITOR_DELETELINE: - delete_lines(doc->sci); + delete_lines(doc->editor->sci); break; case GEANY_KEYS_EDITOR_TRANSPOSELINE: - sci_cmd(doc->sci, SCI_LINETRANSPOSE); + sci_cmd(doc->editor->sci, SCI_LINETRANSPOSE); break; case GEANY_KEYS_EDITOR_AUTOCOMPLETE: - editor_start_auto_complete(doc, sci_get_current_position(doc->sci), TRUE); + editor_start_auto_complete(doc, sci_get_current_position(doc->editor->sci), TRUE); break; case GEANY_KEYS_EDITOR_CALLTIP: editor_show_calltip(doc, -1); break; case GEANY_KEYS_EDITOR_MACROLIST: - editor_show_macro_list(doc->sci); + editor_show_macro_list(doc->editor->sci); break; case GEANY_KEYS_EDITOR_CONTEXTACTION: if (check_current_word()) @@ -1530,10 +1530,10 @@ static void cb_func_editor_action(guint key_id) switch (kb->key) { case GDK_space: - sci_add_text(doc->sci, " "); + sci_add_text(doc->editor->sci, " "); break; case GDK_Tab: - sci_cmd(doc->sci, SCI_TAB); + sci_cmd(doc->editor->sci, SCI_TAB); break; default: break; @@ -1551,7 +1551,7 @@ static void cb_func_format_action(guint key_id) GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* keybindings only valid when scintilla widget has focus */ - if (doc == NULL || focusw != GTK_WIDGET(doc->sci)) + if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return; switch (key_id) @@ -1616,7 +1616,7 @@ static void cb_func_select_action(guint key_id) } /* keybindings only valid when scintilla widget has focus */ - if (doc == NULL || focusw != GTK_WIDGET(doc->sci)) + if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return; switch (key_id) @@ -1625,13 +1625,13 @@ static void cb_func_select_action(guint key_id) on_menu_select_all1_activate(NULL, NULL); break; case GEANY_KEYS_SELECT_WORD: - editor_select_word(doc->sci); + editor_select_word(doc->editor->sci); break; case GEANY_KEYS_SELECT_LINE: - editor_select_lines(doc->sci, FALSE); + editor_select_lines(doc->editor->sci, FALSE); break; case GEANY_KEYS_SELECT_PARAGRAPH: - editor_select_paragraph(doc->sci); + editor_select_paragraph(doc->editor->sci); break; } } @@ -1669,8 +1669,8 @@ static void cb_func_document_action(guint key_id) case GEANY_KEYS_DOCUMENT_TOGGLEFOLD: if (editor_prefs.folding) { - gint line = sci_get_current_line(doc->sci); - sci_toggle_fold(doc->sci, line); + gint line = sci_get_current_line(doc->editor->sci); + sci_toggle_fold(doc->editor->sci, line); break; } } @@ -1684,12 +1684,12 @@ static void cb_func_insert_action(guint key_id) GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); /* keybindings only valid when scintilla widget has focus */ - if (doc == NULL || focusw != GTK_WIDGET(doc->sci)) return; + if (doc == NULL || focusw != GTK_WIDGET(doc->editor->sci)) return; switch (key_id) { case GEANY_KEYS_INSERT_ALTWHITESPACE: - editor_insert_alternative_whitespace(doc); + editor_insert_alternative_whitespace(doc->editor); break; case GEANY_KEYS_INSERT_DATE: gtk_menu_item_activate(GTK_MENU_ITEM(lookup_widget(main_widgets.window, "insert_date_custom1"))); diff --git a/src/keyfile.c b/src/keyfile.c index b11a8a57e..640bfb8a8 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -144,13 +144,13 @@ static gchar *get_session_file_string(GeanyDocument *doc) ft = filetypes[GEANY_FILETYPES_NONE]; fname = g_strdup_printf("%d;%s;%d;%d;%d;%d;%d;%s;", - sci_get_current_position(doc->sci), + sci_get_current_position(doc->editor->sci), ft->name, doc->readonly, encodings_get_idx_from_charset(doc->encoding), - doc->use_tabs, - doc->auto_indent, - doc->line_wrapping, + doc->editor->use_tabs, + doc->editor->auto_indent, + doc->editor->line_wrapping, doc->file_name); return fname; } @@ -894,11 +894,11 @@ static gboolean open_session_file(gchar **tmp) (enc_idx >= 0 && enc_idx < GEANY_ENCODINGS_MAX) ? encodings[enc_idx].charset : NULL); - if (DOC_VALID(doc)) + if (doc) { - editor_set_use_tabs(doc, use_tabs); - editor_set_line_wrapping(doc, line_wrapping); - doc->auto_indent = auto_indent; + editor_set_use_tabs(doc->editor, use_tabs); + editor_set_line_wrapping(doc->editor, line_wrapping); + doc->editor->auto_indent = auto_indent; ret = TRUE; } } diff --git a/src/main.c b/src/main.c index 6ddd0448c..5af0ddd0c 100644 --- a/src/main.c +++ b/src/main.c @@ -910,7 +910,7 @@ gint main(gint argc, gchar **argv) ui_save_buttons_toggle(FALSE); doc = document_get_current(); - gtk_widget_grab_focus(GTK_WIDGET(doc->sci)); + gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); treeviews_select_openfiles_item(doc); build_menu_update(doc); treeviews_update_tag_list(doc, FALSE); diff --git a/src/msgwindow.c b/src/msgwindow.c index 51ae2ed1f..48358af11 100644 --- a/src/msgwindow.c +++ b/src/msgwindow.c @@ -603,7 +603,7 @@ gboolean msgwin_goto_compiler_file_line() if (doc != NULL) { if (! doc->changed) /* if modified, line may be wrong */ - editor_set_indicator_on_line(doc, line - 1); + editor_set_indicator_on_line(doc->editor, line - 1); ret = navqueue_goto_line(old_doc, doc, line); } diff --git a/src/navqueue.c b/src/navqueue.c index bd9fcf308..90ed5e4bd 100644 --- a/src/navqueue.c +++ b/src/navqueue.c @@ -151,12 +151,12 @@ gboolean navqueue_goto_line(GeanyDocument *old_doc, GeanyDocument *new_doc, gint g_return_val_if_fail(new_doc != NULL, FALSE); g_return_val_if_fail(line >= 1, FALSE); - pos = sci_get_position_from_line(new_doc->sci, line - 1); + pos = sci_get_position_from_line(new_doc->editor->sci, line - 1); /* first add old file position */ if (old_doc != NULL && old_doc->file_name) { - gint cur_pos = sci_get_current_position(old_doc->sci); + gint cur_pos = sci_get_current_position(old_doc->editor->sci); add_new_position(old_doc->file_name, cur_pos); } @@ -167,7 +167,7 @@ gboolean navqueue_goto_line(GeanyDocument *old_doc, GeanyDocument *new_doc, gint add_new_position(new_doc->file_name, pos); } - return editor_goto_pos(new_doc, pos, TRUE); + return editor_goto_pos(new_doc->editor, pos, TRUE); } @@ -178,7 +178,7 @@ static gboolean goto_file_pos(const gchar *file, gint pos) if (doc == NULL) return FALSE; - return editor_goto_pos(doc, pos, TRUE); + return editor_goto_pos(doc->editor, pos, TRUE); } diff --git a/src/notebook.c b/src/notebook.c index 8945093e1..d215c83a0 100644 --- a/src/notebook.c +++ b/src/notebook.c @@ -28,6 +28,7 @@ #include "geany.h" #include "notebook.h" #include "document.h" +#include "editor.h" #include "documentprivate.h" #include "ui_utils.h" #include "treeviews.h" @@ -84,7 +85,7 @@ static void focus_sci(GtkWidget *widget, gpointer user_data) if (doc == NULL) return; - gtk_widget_grab_focus(GTK_WIDGET(doc->sci)); + gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); } @@ -327,7 +328,7 @@ gint notebook_new_tab(GeanyDocument *this) g_return_val_if_fail(this != NULL, -1); - page = GTK_WIDGET(this->sci); + page = GTK_WIDGET(this->editor->sci); title = g_path_get_basename(DOC_FILENAME(this)); fdoc->tab_label = gtk_label_new(title); diff --git a/src/plugindata.h b/src/plugindata.h index 3fee729a6..f77d78ad8 100644 --- a/src/plugindata.h +++ b/src/plugindata.h @@ -36,12 +36,12 @@ /* The API version should be incremented whenever any plugin data types below are * modified or appended to. */ -static const gint api_version = 77; +static const gint api_version = 78; /* The ABI version should be incremented whenever existing fields in the plugin * data types below have to be changed or reordered. It should stay the same if fields * are only appended, as this doesn't affect existing fields. */ -static const gint abi_version = 41; +static const gint abi_version = 42; /** Check the plugin can be loaded by Geany. * This performs runtime checks that try to ensure: @@ -425,12 +425,16 @@ typedef struct NavQueueFuncs NavQueueFuncs; +struct GeanyEditor; + /* See editor.h */ typedef struct EditorFuncs { - void (*set_indicator) (struct GeanyDocument *doc, gint start, gint end); - void (*set_indicator_on_line) (struct GeanyDocument *doc, gint line); - void (*clear_indicators) (struct GeanyDocument *doc); + void (*set_indicator) (struct GeanyEditor *editor, gint start, gint end); + void (*set_indicator_on_line) (struct GeanyEditor *editor, gint line); + void (*clear_indicators) (struct GeanyEditor *editor); + /* Remember to convert any GeanyDocument or ScintillaObject pointers in any + * appended functions to GeanyEditor pointers. */ } EditorFuncs; diff --git a/src/prefs.c b/src/prefs.c index 690b28599..65a4ab6f7 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -869,7 +869,7 @@ on_prefs_button_clicked(GtkDialog *dialog, gint response, gpointer user_data) for (i = 0; i < documents_array->len; i++) { if (documents[i]->is_valid) - editor_set_use_tabs(documents[i], editor_prefs.use_tabs); + editor_set_use_tabs(documents[i]->editor, editor_prefs.use_tabs); } } } diff --git a/src/printing.c b/src/printing.c index 54033b597..ae1b736ba 100644 --- a/src/printing.c +++ b/src/printing.c @@ -213,7 +213,7 @@ static gint get_page_count(GtkPrintContext *context, DocInfo *dinfo) gint lines = 1; gint line_width; - line_buf = sci_get_line(dinfo->doc->sci, j); + line_buf = sci_get_line(dinfo->doc->editor->sci, j); line_width = (g_utf8_strlen(line_buf, -1) + 1) * dinfo->font_width; if (line_width > width) lines = ceil(line_width / width); @@ -418,7 +418,7 @@ static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, desc = pango_font_description_from_string(interface_prefs.editor_font); /* init dinfo fields */ - dinfo->lines = sci_get_line_count(dinfo->doc->sci); + dinfo->lines = sci_get_line_count(dinfo->doc->editor->sci); dinfo->lines_per_page = 0; dinfo->cur_line = 0; dinfo->cur_pos = 0; @@ -434,7 +434,7 @@ static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, dinfo->n_pages = get_page_count(context, dinfo); /* read all styles from Scintilla */ - style_max = pow(2, scintilla_send_message(dinfo->doc->sci, SCI_GETSTYLEBITS, 0, 0)); + style_max = pow(2, scintilla_send_message(dinfo->doc->editor->sci, SCI_GETSTYLEBITS, 0, 0)); /* if the lexer uses only the first 32 styles(style bits = 5), * we need to add the pre-defined styles */ if (style_max == 32) @@ -442,21 +442,21 @@ static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, for (i = 0; i < style_max; i++) { dinfo->styles[i][FORE] = ROTATE_RGB(scintilla_send_message( - dinfo->doc->sci, SCI_STYLEGETFORE, i, 0)); + dinfo->doc->editor->sci, SCI_STYLEGETFORE, i, 0)); if (i == STYLE_LINENUMBER) { /* ignore background colour for line number margin to avoid trouble with wrapped lines */ dinfo->styles[STYLE_LINENUMBER][BACK] = ROTATE_RGB(scintilla_send_message( - dinfo->doc->sci, SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); + dinfo->doc->editor->sci, SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); } else { dinfo->styles[i][BACK] = ROTATE_RGB(scintilla_send_message( - dinfo->doc->sci, SCI_STYLEGETBACK, i, 0)); + dinfo->doc->editor->sci, SCI_STYLEGETBACK, i, 0)); } dinfo->styles[i][BOLD] = - scintilla_send_message(dinfo->doc->sci, SCI_STYLEGETBOLD, i, 0); + scintilla_send_message(dinfo->doc->editor->sci, SCI_STYLEGETBOLD, i, 0); dinfo->styles[i][ITALIC] = - scintilla_send_message(dinfo->doc->sci, SCI_STYLEGETITALIC, i, 0); + scintilla_send_message(dinfo->doc->editor->sci, SCI_STYLEGETITALIC, i, 0); } if (dinfo->n_pages >= 0) @@ -550,8 +550,8 @@ static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, /* data */ else { - style = sci_get_style_at(dinfo->doc->sci, dinfo->cur_pos); - c = sci_get_char_at(dinfo->doc->sci, dinfo->cur_pos); + style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos); + c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c == '\0' || style == -1) { /* if c gets 0, we are probably out of document boundaries, * so stop to break out of outer loop */ @@ -570,7 +570,7 @@ static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, /* don't add line breaks, they are handled manually below */ else if (c == '\r' || c == '\n') { - gchar c_next = sci_get_char_at(dinfo->doc->sci, dinfo->cur_pos); + gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); at_eol = TRUE; if (c == '\r' && c_next == '\n') dinfo->cur_pos++; /* skip LF part of CR/LF */ @@ -586,7 +586,7 @@ static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, * style doesn't change since it is only one character with multiple bytes. */ while (c < 0) { - c = sci_get_char_at(dinfo->doc->sci, dinfo->cur_pos); + c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c < 0) { /* only add the byte when it is part of the UTF-8 character * otherwise we could add e.g. a '\n' and it won't be visible in the diff --git a/src/search.c b/src/search.c index 9de64e01a..3e2dbbcd3 100644 --- a/src/search.c +++ b/src/search.c @@ -256,7 +256,7 @@ void search_find_selection(GeanyDocument *doc, gboolean search_backwards) setup_find_next(s); /* allow find next/prev */ if (document_find_text(doc, s, 0, search_backwards, FALSE, NULL) > -1) - editor_display_current_line(doc, 0.3F); + editor_display_current_line(doc->editor, 0.3F); g_free(s); } } @@ -807,15 +807,15 @@ static gint search_mark(GeanyDocument *doc, const gchar *search_text, gint flags g_return_val_if_fail(doc != NULL, 0); ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = sci_get_length(doc->sci); + ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)search_text; while (1) { - pos = sci_find_text(doc->sci, flags, &ttf); + pos = sci_find_text(doc->editor->sci, flags, &ttf); if (pos == -1) break; - line = sci_get_line_from_position(doc->sci, pos); - sci_set_marker_at_line(doc->sci, line, TRUE, 1); + line = sci_get_line_from_position(doc->editor->sci, pos); + sci_set_marker_at_line(doc->editor->sci, line, TRUE, 1); ttf.chrg.cpMin = ttf.chrgText.cpMax + 1; count++; @@ -1367,13 +1367,13 @@ static gint find_document_usage(GeanyDocument *doc, const gchar *search_text, gi short_file_name = g_path_get_basename(DOC_FILENAME(doc)); ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = sci_get_length(doc->sci); + ttf.chrg.cpMax = sci_get_length(doc->editor->sci); ttf.lpstrText = (gchar *)search_text; while (1) { gint pos, line, start, find_len; - pos = sci_find_text(doc->sci, flags, &ttf); + pos = sci_find_text(doc->editor->sci, flags, &ttf); if (pos == -1) break; /* no more matches */ find_len = ttf.chrgText.cpMax - ttf.chrgText.cpMin; @@ -1381,8 +1381,8 @@ static gint find_document_usage(GeanyDocument *doc, const gchar *search_text, gi break; /* Ignore regex ^ or $ */ count++; - line = sci_get_line_from_position(doc->sci, pos); - buffer = sci_get_line(doc->sci, line); + line = sci_get_line_from_position(doc->editor->sci, pos); + buffer = sci_get_line(doc->editor->sci, line); msgwin_msg_add_fmt(COLOR_BLACK, line + 1, doc, "%s:%d : %s", short_file_name, line + 1, g_strstrip(buffer)); g_free(buffer); diff --git a/src/symbols.c b/src/symbols.c index 00e81f40b..672ce14e7 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -28,6 +28,7 @@ * matching filetype is first loaded. */ +#include "SciLexer.h" #include "geany.h" #include @@ -48,6 +49,7 @@ #include "navqueue.h" #include "ui_utils.h" #include "editor.h" +#include "sciwrappers.h" const guint TM_GLOBAL_TYPE_MASK = @@ -1228,3 +1230,226 @@ gboolean symbols_goto_tag(const gchar *name, gboolean definition) } +/* This could perhaps be improved to check for #if, class etc. */ +static gint get_function_fold_number(GeanyDocument *doc) +{ + /* for Java the functions are always one fold level above the class scope */ + if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_JAVA) + return SC_FOLDLEVELBASE + 1; + else + return SC_FOLDLEVELBASE; +} + + +/* Should be used only with symbols_get_current_function. */ +static gboolean current_function_changed(GeanyDocument *doc, gint cur_line, gint fold_level) +{ + static gint old_line = -2; + static GeanyDocument *old_doc = NULL; + static gint old_fold_num = -1; + const gint fold_num = fold_level & SC_FOLDLEVELNUMBERMASK; + gboolean ret; + + /* check if the cached line and file index have changed since last time: */ + if (doc == NULL || doc != old_doc) + ret = TRUE; + else + if (cur_line == old_line) + ret = FALSE; + else + { + /* if the line has only changed by 1 */ + if (abs(cur_line - old_line) == 1) + { + const gint fn_fold = + get_function_fold_number(doc); + /* It's the same function if the fold number hasn't changed, or both the new + * and old fold numbers are above the function fold number. */ + gboolean same = + fold_num == old_fold_num || + (old_fold_num > fn_fold && fold_num > fn_fold); + + ret = ! same; + } + else ret = TRUE; + } + + /* record current line and file index for next time */ + old_line = cur_line; + old_doc = doc; + old_fold_num = fold_num; + return ret; +} + + +/* Parse the function name up to 2 lines before tag_line. + * C++ like syntax should be parsed by parse_cpp_function_at_line, otherwise the return + * type or argument names can be confused with the function name. */ +static gchar *parse_function_at_line(ScintillaObject *sci, gint tag_line) +{ + gint start, end, max_pos; + gchar *cur_tag; + gint fn_style; + + switch (sci_get_lexer(sci)) + { + case SCLEX_RUBY: fn_style = SCE_RB_DEFNAME; break; + case SCLEX_PYTHON: fn_style = SCE_P_DEFNAME; break; + default: fn_style = SCE_C_IDENTIFIER; /* several lexers use SCE_C_IDENTIFIER */ + } + start = sci_get_position_from_line(sci, tag_line - 2); + max_pos = sci_get_position_from_line(sci, tag_line + 1); + while (sci_get_style_at(sci, start) != fn_style + && start < max_pos) start++; + + end = start; + while (sci_get_style_at(sci, end) == fn_style + && end < max_pos) end++; + + if (start == end) return NULL; + cur_tag = g_malloc(end - start + 1); + sci_get_text_range(sci, start, end, cur_tag); + return cur_tag; +} + + +/* Parse the function name */ +static gchar *parse_cpp_function_at_line(ScintillaObject *sci, gint tag_line) +{ + gint start, end, first_pos, max_pos; + gint tmp; + gchar c; + gchar *cur_tag; + + first_pos = end = sci_get_position_from_line(sci, tag_line); + max_pos = sci_get_position_from_line(sci, tag_line + 1); + tmp = 0; + /* goto the begin of function body */ + while (end < max_pos && + (tmp = sci_get_char_at(sci, end)) != '{' && + tmp != 0) end++; + if (tmp == 0) end --; + + /* go back to the end of function identifier */ + while (end > 0 && end > first_pos - 500 && + (tmp = sci_get_char_at(sci, end)) != '(' && + tmp != 0) end--; + end--; + if (end < 0) end = 0; + + /* skip whitespaces between identifier and ( */ + while (end > 0 && isspace(sci_get_char_at(sci, end))) end--; + + start = end; + c = 0; + /* Use tmp to find SCE_C_IDENTIFIER or SCE_C_GLOBALCLASS chars */ + while (start >= 0 && ((tmp = sci_get_style_at(sci, start)) == SCE_C_IDENTIFIER + || tmp == SCE_C_GLOBALCLASS + || (c = sci_get_char_at(sci, start)) == '~' + || c == ':')) + start--; + if (start != 0 && start < end) start++; /* correct for last non-matching char */ + + if (start == end) return NULL; + cur_tag = g_malloc(end - start + 2); + sci_get_text_range(sci, start, end + 1, cur_tag); + return cur_tag; +} + + +/* Sets *tagname to point at the current function or tag name. + * If doc is NULL, reset the cached current tag data to ensure it will be reparsed on the next + * call to this function. + * Returns: line number of the current tag, or -1 if unknown. */ +gint symbols_get_current_function(GeanyDocument *doc, const gchar **tagname) +{ + static gint tag_line = -1; + static gchar *cur_tag = NULL; + gint line; + gint fold_level; + TMWorkObject *tm_file; + + if (doc == NULL) /* reset current function */ + { + current_function_changed(NULL, -1, -1); + g_free(cur_tag); + cur_tag = g_strdup(_("unknown")); + if (tagname != NULL) + *tagname = cur_tag; + tag_line = -1; + return tag_line; + } + + line = sci_get_current_line(doc->editor->sci); + fold_level = sci_get_fold_level(doc->editor->sci, line); + /* check if the cached line and file index have changed since last time: */ + if (! current_function_changed(doc, line, fold_level)) + { + /* we can assume same current function as before */ + *tagname = cur_tag; + return tag_line; + } + g_free(cur_tag); /* free the old tag, it will be replaced. */ + + /* if line is at base fold level, we're not in a function */ + if ((fold_level & SC_FOLDLEVELNUMBERMASK) == SC_FOLDLEVELBASE) + { + cur_tag = g_strdup(_("unknown")); + *tagname = cur_tag; + tag_line = -1; + return tag_line; + } + tm_file = doc->tm_file; + + /* if the document has no changes, get the previous function name from TM */ + if(! doc->changed && tm_file != NULL && tm_file->tags_array != NULL) + { + const TMTag *tag = (const TMTag*) tm_get_current_function(tm_file->tags_array, line); + + if (tag != NULL) + { + gchar *tmp; + tmp = tag->atts.entry.scope; + cur_tag = tmp ? g_strconcat(tmp, "::", tag->name, NULL) : g_strdup(tag->name); + *tagname = cur_tag; + tag_line = tag->atts.entry.line; + return tag_line; + } + } + + /* parse the current function name here because TM line numbers may have changed, + * and it would take too long to reparse the whole file. */ + if (doc->file_type != NULL && doc->file_type->id != GEANY_FILETYPES_NONE) + { + const gint fn_fold = get_function_fold_number(doc); + + tag_line = line; + do /* find the top level fold point */ + { + tag_line = sci_get_fold_parent(doc->editor->sci, tag_line); + fold_level = sci_get_fold_level(doc->editor->sci, tag_line); + } while (tag_line >= 0 && + (fold_level & SC_FOLDLEVELNUMBERMASK) != fn_fold); + + if (tag_line >= 0) + { + if (sci_get_lexer(doc->editor->sci) == SCLEX_CPP) + cur_tag = parse_cpp_function_at_line(doc->editor->sci, tag_line); + else + cur_tag = parse_function_at_line(doc->editor->sci, tag_line); + + if (cur_tag != NULL) + { + *tagname = cur_tag; + return tag_line; + } + } + } + + cur_tag = g_strdup(_("unknown")); + *tagname = cur_tag; + tag_line = -1; + return tag_line; +} + + diff --git a/src/symbols.h b/src/symbols.h index db3f3ead4..192d16fcb 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -57,4 +57,6 @@ void symbols_show_load_tags_dialog(void); gboolean symbols_goto_tag(const gchar *name, gboolean definition); +gint symbols_get_current_function(GeanyDocument *doc, const gchar **tagname); + #endif diff --git a/src/tools.c b/src/tools.c index c1d5f71a5..6a8cc7e0b 100644 --- a/src/tools.c +++ b/src/tools.c @@ -173,7 +173,7 @@ static gboolean cc_replace_sel_cb(gpointer user_data) if (! cc_error_occurred && cc_buffer != NULL) { /* Command completed successfully */ - sci_replace_sel(doc->sci, cc_buffer->str); + sci_replace_sel(doc->editor->sci, cc_buffer->str); g_string_free(cc_buffer, TRUE); cc_buffer = NULL; } @@ -238,7 +238,7 @@ void tools_execute_custom_command(GeanyDocument *doc, const gchar *command) g_return_if_fail(doc != NULL && command != NULL); - if (! sci_can_copy(doc->sci)) + if (! sci_can_copy(doc->editor->sci)) return; argv = g_strsplit(command, " ", -1); @@ -263,9 +263,9 @@ void tools_execute_custom_command(GeanyDocument *doc, const gchar *command) FALSE, cc_iofunc_err, (gpointer)command); /* get selection */ - len = sci_get_selected_text_length(doc->sci); + len = sci_get_selected_text_length(doc->editor->sci); sel = g_malloc0(len + 1); - sci_get_selected_text(doc->sci, sel); + sci_get_selected_text(doc->editor->sci, sel); /* write data to the command */ remaining = len - 1; @@ -404,7 +404,7 @@ static void cc_on_custom_command_menu_activate(GtkMenuItem *menuitem, gpointer u if (doc == NULL) return; - enable = sci_can_copy(doc->sci) && (ui_prefs.custom_commands != NULL); + enable = sci_can_copy(doc->editor->sci) && (ui_prefs.custom_commands != NULL); children = gtk_container_get_children(GTK_CONTAINER(user_data)); len = g_list_length(children); @@ -616,16 +616,16 @@ void tools_word_count(void) vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog)); gtk_widget_set_name(dialog, "GeanyDialog"); - if (sci_can_copy(doc->sci)) + if (sci_can_copy(doc->editor->sci)) { - text = g_malloc0(sci_get_selected_text_length(doc->sci) + 1); - sci_get_selected_text(doc->sci, text); + text = g_malloc0(sci_get_selected_text_length(doc->editor->sci) + 1); + sci_get_selected_text(doc->editor->sci, text); range = _("selection"); } else { - text = g_malloc(sci_get_length(doc->sci) + 1); - sci_get_text(doc->sci, sci_get_length(doc->sci) + 1 , text); + text = g_malloc(sci_get_length(doc->editor->sci) + 1); + sci_get_text(doc->editor->sci, sci_get_length(doc->editor->sci) + 1 , text); range = _("whole document"); } word_count(text, &chars, &lines, &words); diff --git a/src/treeviews.c b/src/treeviews.c index fe57564a3..9f945abd7 100644 --- a/src/treeviews.c +++ b/src/treeviews.c @@ -32,6 +32,7 @@ #include "callbacks.h" #include "treeviews.h" #include "document.h" +#include "editor.h" #include "documentprivate.h" #include "filetypes.h" #include "utils.h" @@ -577,7 +578,7 @@ static gboolean change_focus(gpointer data) if (DOC_VALID(doc)) { GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); - GtkWidget *sci = GTK_WIDGET(doc->sci); + GtkWidget *sci = GTK_WIDGET(doc->editor->sci); if (focusw == tv.tree_openfiles) gtk_widget_grab_focus(sci); @@ -598,7 +599,7 @@ static void on_openfiles_tree_selection_changed(GtkTreeSelection *selection, gpo gtk_tree_model_get(model, &iter, 1, &doc, -1); gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(main_widgets.notebook), - (GtkWidget*) doc->sci)); + (GtkWidget*) doc->editor->sci)); g_idle_add((GSourceFunc) change_focus, doc); } } diff --git a/src/ui_utils.c b/src/ui_utils.c index e9d4b6c59..1e5a60ea1 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -46,6 +46,7 @@ #include "project.h" #include "editor.h" #include "plugins.h" +#include "symbols.h" GeanyInterfacePrefs interface_prefs; @@ -143,30 +144,30 @@ void ui_update_statusbar(GeanyDocument *doc, gint pos) if (stats_str == NULL) stats_str = g_string_sized_new(120); - if (pos == -1) pos = sci_get_current_position(doc->sci); - line = sci_get_line_from_position(doc->sci, pos); + if (pos == -1) pos = sci_get_current_position(doc->editor->sci); + line = sci_get_line_from_position(doc->editor->sci, pos); /* Add temporary fix for sci infinite loop in Document::GetColumn(int) * when current pos is beyond document end (can occur when removing * blocks of selected lines especially esp. brace sections near end of file). */ - if (pos <= sci_get_length(doc->sci)) - col = sci_get_col_from_position(doc->sci, pos); + if (pos <= sci_get_length(doc->editor->sci)) + col = sci_get_col_from_position(doc->editor->sci, pos); else col = 0; /* Status bar statistics: col = column, sel = selection. */ g_string_printf(stats_str, _("line: %d\t col: %d\t sel: %d\t "), (line + 1), col, - sci_get_selected_text_length(doc->sci) - 1); + sci_get_selected_text_length(doc->editor->sci) - 1); g_string_append(stats_str, /* RO = read-only */ (doc->readonly) ? _("RO ") : /* OVR = overwrite/overtype, INS = insert */ - (sci_get_overtype(doc->sci) ? _("OVR") : _("INS"))); + (sci_get_overtype(doc->editor->sci) ? _("OVR") : _("INS"))); g_string_append(stats_str, sp); g_string_append(stats_str, - (doc->use_tabs) ? _("TAB") : _("SP ")); /* SP = space */ + (doc->editor->use_tabs) ? _("TAB") : _("SP ")); /* SP = space */ g_string_append(stats_str, sp); g_string_append_printf(stats_str, _("mode: %s"), editor_get_eol_char_name(doc)); @@ -185,7 +186,7 @@ void ui_update_statusbar(GeanyDocument *doc, gint pos) g_string_append(stats_str, sp); } - utils_get_current_function(doc, &cur_tag); + symbols_get_current_function(doc, &cur_tag); g_string_append_printf(stats_str, _("scope: %s"), cur_tag); @@ -249,11 +250,9 @@ void ui_set_window_title(GeanyDocument *doc) void ui_set_editor_font(const gchar *font_name) { guint i; - gint size; - gchar *fname; - PangoFontDescription *font_desc; g_return_if_fail(font_name != NULL); + /* do nothing if font has not changed */ if (interface_prefs.editor_font != NULL) if (strcmp(font_name, interface_prefs.editor_font) == 0) return; @@ -261,23 +260,16 @@ void ui_set_editor_font(const gchar *font_name) g_free(interface_prefs.editor_font); interface_prefs.editor_font = g_strdup(font_name); - font_desc = pango_font_description_from_string(interface_prefs.editor_font); - - fname = g_strdup_printf("!%s", pango_font_description_get_family(font_desc)); - size = pango_font_description_get_size(font_desc) / PANGO_SCALE; - /* We copy the current style, and update the font in all open tabs. */ - for(i = 0; i < documents_array->len; i++) + for (i = 0; i < documents_array->len; i++) { - if (documents[i]->sci) + if (documents[i]->editor) { - editor_set_font(documents[i], fname, size); + editor_set_font(documents[i]->editor, interface_prefs.editor_font); } } - pango_font_description_free(font_desc); ui_set_statusbar(TRUE, _("Font updated (%s)."), interface_prefs.editor_font); - g_free(fname); } @@ -329,7 +321,7 @@ void ui_update_popup_copy_items(GeanyDocument *doc) if (doc == NULL) enable = FALSE; else - enable = sci_can_copy(doc->sci); + enable = sci_can_copy(doc->editor->sci); for (i = 0; i < G_N_ELEMENTS(ui_widgets.popup_copy_items); i++) gtk_widget_set_sensitive(ui_widgets.popup_copy_items[i], enable); @@ -351,7 +343,7 @@ void ui_update_menu_copy_items(GeanyDocument *doc) GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window)); if (IS_SCINTILLA(focusw)) - enable = (doc == NULL) ? FALSE : sci_can_copy(doc->sci); + enable = (doc == NULL) ? FALSE : sci_can_copy(doc->editor->sci); else if (GTK_IS_EDITABLE(focusw)) enable = gtk_editable_get_selection_bounds(GTK_EDITABLE(focusw), NULL, NULL); @@ -699,17 +691,17 @@ void ui_document_show_hide(GeanyDocument *doc) gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(lookup_widget(main_widgets.window, "menu_line_wrapping1")), - doc->line_wrapping); + doc->editor->line_wrapping); gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(lookup_widget(main_widgets.window, "line_breaking1")), - doc->line_breaking); + doc->editor->line_breaking); item = lookup_widget(main_widgets.window, "menu_use_auto_indentation1"); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), doc->auto_indent); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), doc->editor->auto_indent); gtk_widget_set_sensitive(item, editor_prefs.indent_mode != INDENT_NONE); - item = lookup_widget(main_widgets.window, doc->use_tabs ? "tabs1" : "spaces1"); + item = lookup_widget(main_widgets.window, doc->editor->use_tabs ? "tabs1" : "spaces1"); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); gtk_check_menu_item_set_active( @@ -720,7 +712,7 @@ void ui_document_show_hide(GeanyDocument *doc) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), doc->has_bom); gtk_widget_set_sensitive(item, encodings_is_unicode_charset(doc->encoding)); - switch (sci_get_eol_mode(doc->sci)) + switch (sci_get_eol_mode(doc->editor->sci)) { case SC_EOL_CR: widget_name = "cr"; break; case SC_EOL_LF: widget_name = "lf"; break; @@ -1072,7 +1064,7 @@ void ui_show_markers_margin(void) for(i = 0; i < max; i++) { doc = document_get_from_page(i); - sci_set_symbol_margin(doc->sci, editor_prefs.show_markers_margin); + sci_set_symbol_margin(doc->editor->sci, editor_prefs.show_markers_margin); } } @@ -1085,7 +1077,7 @@ void ui_show_linenumber_margin(void) for(i = 0; i < max; i++) { doc = document_get_from_page(i); - sci_set_line_numbers(doc->sci, editor_prefs.show_linenumber_margin, 0); + sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0); } } diff --git a/src/utils.c b/src/utils.c index 39579914a..0fee1b31e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -25,7 +25,6 @@ * General utility functions, non-GTK related. */ -#include "SciLexer.h" #include "geany.h" #include @@ -49,7 +48,6 @@ #include "support.h" #include "document.h" #include "filetypes.h" -#include "sciwrappers.h" #include "dialogs.h" #include "win32.h" #include "project.h" @@ -286,229 +284,6 @@ gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag) } -/* This could perhaps be improved to check for #if, class etc. */ -static gint get_function_fold_number(GeanyDocument *doc) -{ - /* for Java the functions are always one fold level above the class scope */ - if (FILETYPE_ID(doc->file_type) == GEANY_FILETYPES_JAVA) - return SC_FOLDLEVELBASE + 1; - else - return SC_FOLDLEVELBASE; -} - - -/* Should be used only with utils_get_current_function. */ -static gboolean current_function_changed(GeanyDocument *doc, gint cur_line, gint fold_level) -{ - static gint old_line = -2; - static GeanyDocument *old_doc = NULL; - static gint old_fold_num = -1; - const gint fold_num = fold_level & SC_FOLDLEVELNUMBERMASK; - gboolean ret; - - /* check if the cached line and file index have changed since last time: */ - if (doc == NULL || doc != old_doc) - ret = TRUE; - else - if (cur_line == old_line) - ret = FALSE; - else - { - /* if the line has only changed by 1 */ - if (abs(cur_line - old_line) == 1) - { - const gint fn_fold = - get_function_fold_number(doc); - /* It's the same function if the fold number hasn't changed, or both the new - * and old fold numbers are above the function fold number. */ - gboolean same = - fold_num == old_fold_num || - (old_fold_num > fn_fold && fold_num > fn_fold); - - ret = ! same; - } - else ret = TRUE; - } - - /* record current line and file index for next time */ - old_line = cur_line; - old_doc = doc; - old_fold_num = fold_num; - return ret; -} - - -/* Parse the function name up to 2 lines before tag_line. - * C++ like syntax should be parsed by parse_cpp_function_at_line, otherwise the return - * type or argument names can be confused with the function name. */ -static gchar *parse_function_at_line(ScintillaObject *sci, gint tag_line) -{ - gint start, end, max_pos; - gchar *cur_tag; - gint fn_style; - - switch (sci_get_lexer(sci)) - { - case SCLEX_RUBY: fn_style = SCE_RB_DEFNAME; break; - case SCLEX_PYTHON: fn_style = SCE_P_DEFNAME; break; - default: fn_style = SCE_C_IDENTIFIER; /* several lexers use SCE_C_IDENTIFIER */ - } - start = sci_get_position_from_line(sci, tag_line - 2); - max_pos = sci_get_position_from_line(sci, tag_line + 1); - while (sci_get_style_at(sci, start) != fn_style - && start < max_pos) start++; - - end = start; - while (sci_get_style_at(sci, end) == fn_style - && end < max_pos) end++; - - if (start == end) return NULL; - cur_tag = g_malloc(end - start + 1); - sci_get_text_range(sci, start, end, cur_tag); - return cur_tag; -} - - -/* Parse the function name */ -static gchar *parse_cpp_function_at_line(ScintillaObject *sci, gint tag_line) -{ - gint start, end, first_pos, max_pos; - gint tmp; - gchar c; - gchar *cur_tag; - - first_pos = end = sci_get_position_from_line(sci, tag_line); - max_pos = sci_get_position_from_line(sci, tag_line + 1); - tmp = 0; - /* goto the begin of function body */ - while (end < max_pos && - (tmp = sci_get_char_at(sci, end)) != '{' && - tmp != 0) end++; - if (tmp == 0) end --; - - /* go back to the end of function identifier */ - while (end > 0 && end > first_pos - 500 && - (tmp = sci_get_char_at(sci, end)) != '(' && - tmp != 0) end--; - end--; - if (end < 0) end = 0; - - /* skip whitespaces between identifier and ( */ - while (end > 0 && isspace(sci_get_char_at(sci, end))) end--; - - start = end; - c = 0; - /* Use tmp to find SCE_C_IDENTIFIER or SCE_C_GLOBALCLASS chars */ - while (start >= 0 && ((tmp = sci_get_style_at(sci, start)) == SCE_C_IDENTIFIER - || tmp == SCE_C_GLOBALCLASS - || (c = sci_get_char_at(sci, start)) == '~' - || c == ':')) - start--; - if (start != 0 && start < end) start++; /* correct for last non-matching char */ - - if (start == end) return NULL; - cur_tag = g_malloc(end - start + 2); - sci_get_text_range(sci, start, end + 1, cur_tag); - return cur_tag; -} - - -/* Sets *tagname to point at the current function or tag name. - * If doc is NULL, reset the cached current tag data to ensure it will be reparsed on the next - * call to this function. - * Returns: line number of the current tag, or -1 if unknown. */ -gint utils_get_current_function(GeanyDocument *doc, const gchar **tagname) -{ - static gint tag_line = -1; - static gchar *cur_tag = NULL; - gint line; - gint fold_level; - TMWorkObject *tm_file; - - if (doc == NULL) /* reset current function */ - { - current_function_changed(NULL, -1, -1); - g_free(cur_tag); - cur_tag = g_strdup(_("unknown")); - if (tagname != NULL) - *tagname = cur_tag; - tag_line = -1; - return tag_line; - } - - line = sci_get_current_line(doc->sci); - fold_level = sci_get_fold_level(doc->sci, line); - /* check if the cached line and file index have changed since last time: */ - if (! current_function_changed(doc, line, fold_level)) - { - /* we can assume same current function as before */ - *tagname = cur_tag; - return tag_line; - } - g_free(cur_tag); /* free the old tag, it will be replaced. */ - - /* if line is at base fold level, we're not in a function */ - if ((fold_level & SC_FOLDLEVELNUMBERMASK) == SC_FOLDLEVELBASE) - { - cur_tag = g_strdup(_("unknown")); - *tagname = cur_tag; - tag_line = -1; - return tag_line; - } - tm_file = doc->tm_file; - - /* if the document has no changes, get the previous function name from TM */ - if(! doc->changed && tm_file != NULL && tm_file->tags_array != NULL) - { - const TMTag *tag = (const TMTag*) tm_get_current_function(tm_file->tags_array, line); - - if (tag != NULL) - { - gchar *tmp; - tmp = tag->atts.entry.scope; - cur_tag = tmp ? g_strconcat(tmp, "::", tag->name, NULL) : g_strdup(tag->name); - *tagname = cur_tag; - tag_line = tag->atts.entry.line; - return tag_line; - } - } - - /* parse the current function name here because TM line numbers may have changed, - * and it would take too long to reparse the whole file. */ - if (doc->file_type != NULL && doc->file_type->id != GEANY_FILETYPES_NONE) - { - const gint fn_fold = get_function_fold_number(doc); - - tag_line = line; - do /* find the top level fold point */ - { - tag_line = sci_get_fold_parent(doc->sci, tag_line); - fold_level = sci_get_fold_level(doc->sci, tag_line); - } while (tag_line >= 0 && - (fold_level & SC_FOLDLEVELNUMBERMASK) != fn_fold); - - if (tag_line >= 0) - { - if (sci_get_lexer(doc->sci) == SCLEX_CPP) - cur_tag = parse_cpp_function_at_line(doc->sci, tag_line); - else - cur_tag = parse_function_at_line(doc->sci, tag_line); - - if (cur_tag != NULL) - { - *tagname = cur_tag; - return tag_line; - } - } - } - - cur_tag = g_strdup(_("unknown")); - *tagname = cur_tag; - tag_line = -1; - return tag_line; -} - - const gchar *utils_get_eol_name(gint eol_mode) { switch (eol_mode) @@ -950,34 +725,6 @@ gchar *utils_get_setting_string(GKeyFile *config, const gchar *section, const gc } -void utils_replace_filename(GeanyDocument *doc) -{ - gchar *filebase; - gchar *filename; - struct TextToFind ttf; - - if (doc == NULL || doc->file_type == NULL) return; - - filebase = g_strconcat(GEANY_STRING_UNTITLED, ".", (doc->file_type)->extension, NULL); - filename = g_path_get_basename(doc->file_name); - - /* only search the first 3 lines */ - ttf.chrg.cpMin = 0; - ttf.chrg.cpMax = sci_get_position_from_line(doc->sci, 3); - ttf.lpstrText = (gchar*)filebase; - - if (sci_find_text(doc->sci, SCFIND_MATCHCASE, &ttf) != -1) - { - sci_target_start(doc->sci, ttf.chrgText.cpMin); - sci_target_end(doc->sci, ttf.chrgText.cpMax); - sci_target_replace(doc->sci, filename, FALSE); - } - - g_free(filebase); - g_free(filename); -} - - gchar *utils_get_hex_from_color(GdkColor *color) { gchar *buffer = g_malloc0(9); diff --git a/src/utils.h b/src/utils.h index b5c3ee9e1..c5d3521b5 100644 --- a/src/utils.h +++ b/src/utils.h @@ -58,8 +58,6 @@ gint utils_write_file(const gchar *filename, const gchar *text); gchar *utils_find_open_xml_tag(const gchar sel[], gint size, gboolean check_tag); -gint utils_get_current_function(GeanyDocument *doc, const gchar **tagname); - const gchar *utils_get_eol_name(gint eol_mode); gboolean utils_atob(const gchar *str); @@ -94,8 +92,6 @@ gint utils_get_setting_integer(GKeyFile *config, const gchar *section, const gch gchar *utils_get_setting_string(GKeyFile *config, const gchar *section, const gchar *key, const gchar *default_value); -void utils_replace_filename(GeanyDocument *doc); - gchar *utils_get_hex_from_color(GdkColor *color); const gchar *utils_get_default_dir_utf8(void);