diff --git a/ChangeLog b/ChangeLog index 37ad8605e9..b452b8fb5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,13 @@ src/editor.h: Fix building editor.c, using GeanyEditor* instead of GeanyDocument* (most global editor functions still need conversion though). + * src/utils.c, src/utils.h, src/treeviews.c, src/callbacks.c, + src/notebook.c, src/keyfile.c, src/filetypes.c, src/document.c, + src/editor.c, src/symbols.c, src/symbols.h, src/ui_utils.c, + plugins/vcdiff.c, plugins/htmlchars.c, plugins/classbuilder.c: + Fix compilation. + Move utils_get_current_function() to symbols.c. + Move utils_replace_filename() to document.c. 2008-07-07 Nick Treleaven diff --git a/plugins/classbuilder.c b/plugins/classbuilder.c index b33b9a8e2d..c72f35fa05 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" diff --git a/plugins/htmlchars.c b/plugins/htmlchars.c index 828c2b5e0b..d56b32bd74 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" diff --git a/plugins/vcdiff.c b/plugins/vcdiff.c index f591badc5f..e68160366c 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" diff --git a/src/callbacks.c b/src/callbacks.c index 56dd76833e..57a74d5808 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -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; } } @@ -1288,9 +1288,9 @@ 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); + line = symbols_get_current_function(doc, &cur_tag); pos = sci_get_position_from_line(doc->editor->scintilla, line - 1); text = templates_get_template_function(doc->file_type->id, cur_tag); @@ -1707,7 +1707,7 @@ on_menu_increase_indent1_activate (GtkMenuItem *menuitem, line = sci_get_line_from_position(doc->editor->scintilla, old_pos); ind_pos = sci_get_line_indent_position(doc->editor->scintilla, 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->editor->scintilla, ind_pos, TRUE); @@ -1736,7 +1736,7 @@ on_menu_decrease_indent1_activate (GtkMenuItem *menuitem, old_pos = sci_get_current_position(doc->editor->scintilla); line = sci_get_line_from_position(doc->editor->scintilla, old_pos); ind_pos = sci_get_line_indent_position(doc->editor->scintilla, line); - 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; if (ind_pos == sci_get_position_from_line(doc->editor->scintilla, line)) @@ -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 49f10aa3cc..74cdffc2ce 100644 --- a/src/document.c +++ b/src/document.c @@ -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); @@ -324,13 +324,14 @@ void document_apply_update_prefs(GeanyDocument *doc) static void init_doc_struct(GeanyDocument *new_doc) { Document *full_doc = DOCUMENT(new_doc); + GeanyEditor *editor = new_doc->editor; memset(full_doc, 0, sizeof(Document)); 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; + editor->auto_indent = (editor_prefs.indent_mode != INDENT_NONE); + editor->line_wrapping = editor_prefs.line_wrapping; new_doc->readonly = FALSE; new_doc->file_name = NULL; new_doc->file_type = NULL; @@ -338,8 +339,8 @@ static void init_doc_struct(GeanyDocument *new_doc) new_doc->encoding = NULL; new_doc->has_bom = FALSE; new_doc->editor->scintilla = NULL; - new_doc->scroll_percent = -1.0F; - new_doc->line_breaking = FALSE; + editor->scroll_percent = -1.0F; + editor->line_breaking = FALSE; new_doc->mtime = 0; new_doc->changed = FALSE; new_doc->last_check = time(NULL); @@ -502,7 +503,7 @@ gboolean document_remove_page(guint page_num) doc->encoding = NULL; doc->has_bom = FALSE; doc->tm_file = NULL; - doc->scroll_percent = -1.0F; + doc->editor->scroll_percent = -1.0F; document_undo_clear(doc); if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)) == 0) { @@ -857,25 +858,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->editor->scintilla, cl_options.goto_line - 1, TRUE); - doc->scroll_percent = 0.5F; + sci_goto_line(editor->scintilla, 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->editor->scintilla, pos, FALSE); - doc->scroll_percent = 0.5F; + sci_set_current_position(editor->scintilla, 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->editor->scintilla); - sci_set_current_position(doc->editor->scintilla, cur_pos + cl_options.goto_column, FALSE); - doc->scroll_percent = 0.5F; + gint cur_pos = sci_get_current_position(editor->scintilla); + sci_set_current_position(editor->scintilla, cur_pos + cl_options.goto_column, FALSE); + editor->scroll_percent = 0.5F; cl_options.goto_column = -1; } } @@ -985,7 +986,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename 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; } } @@ -1032,7 +1033,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename sci_set_line_numbers(doc->editor->scintilla, 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) { @@ -1057,7 +1058,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->editor, doc->use_tabs); /* resetup sci */ + editor_set_use_tabs(doc->editor, doc->editor->use_tabs); /* resetup sci */ else set_indentation(doc); @@ -1215,6 +1216,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->scintilla, 3); + ttf.lpstrText = (gchar*)filebase; + + if (sci_find_text(doc->editor->scintilla, SCFIND_MATCHCASE, &ttf) != -1) + { + sci_target_start(doc->editor->scintilla, ttf.chrgText.cpMin); + sci_target_end(doc->editor->scintilla, ttf.chrgText.cpMax); + sci_target_replace(doc->editor->scintilla, filename, FALSE); + } + + g_free(filebase); + g_free(filename); +} + + /* * Save the %document, detecting the filetype. * @@ -1249,7 +1278,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) @@ -1582,7 +1611,7 @@ gint document_find_text(GeanyDocument *doc, const gchar *text, gint flags, gbool sci_ensure_line_is_visible(doc->editor->scintilla, sci_get_line_from_position(doc->editor->scintilla, search_pos)); if (scroll) - doc->scroll_percent = 0.3F; + doc->editor->scroll_percent = 0.3F; } else { @@ -2394,11 +2423,11 @@ GeanyDocument *document_clone(GeanyDocument *old_doc, const gchar *utf8_filename 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->editor->scintilla, doc->line_wrapping); + sci_set_lines_wrapped(doc->editor->scintilla, doc->editor->line_wrapping); sci_set_readonly(doc->editor->scintilla, doc->readonly); ui_document_show_hide(doc); diff --git a/src/editor.c b/src/editor.c index 36b5b6dffd..cae79ef321 100644 --- a/src/editor.c +++ b/src/editor.c @@ -3501,7 +3501,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); } diff --git a/src/filetypes.c b/src/filetypes.c index 98cb59e8a6..1b4eed17b9 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" diff --git a/src/keyfile.c b/src/keyfile.c index 74d71a79a8..f0b5318d89 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -148,9 +148,9 @@ static gchar *get_session_file_string(GeanyDocument *doc) 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; } @@ -888,11 +888,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->editor, use_tabs); editor_set_line_wrapping(doc->editor, line_wrapping); - doc->auto_indent = auto_indent; + doc->editor->auto_indent = auto_indent; ret = TRUE; } } diff --git a/src/notebook.c b/src/notebook.c index cb72af7091..6b0007f61f 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" diff --git a/src/symbols.c b/src/symbols.c index ece5e31c1c..1099d74faf 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 = @@ -1227,3 +1229,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->scintilla); + fold_level = sci_get_fold_level(doc->editor->scintilla, 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->scintilla, tag_line); + fold_level = sci_get_fold_level(doc->editor->scintilla, tag_line); + } while (tag_line >= 0 && + (fold_level & SC_FOLDLEVELNUMBERMASK) != fn_fold); + + if (tag_line >= 0) + { + if (sci_get_lexer(doc->editor->scintilla) == SCLEX_CPP) + cur_tag = parse_cpp_function_at_line(doc->editor->scintilla, tag_line); + else + cur_tag = parse_function_at_line(doc->editor->scintilla, 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 db3f3ead46..192d16fcbb 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/treeviews.c b/src/treeviews.c index 05dec21504..4de5b62a0f 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" diff --git a/src/ui_utils.c b/src/ui_utils.c index 25ebae19af..0b663c50ec 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; @@ -166,7 +167,7 @@ void ui_update_statusbar(GeanyDocument *doc, gint pos) (sci_get_overtype(doc->editor->scintilla) ? _("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); @@ -699,17 +700,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( diff --git a/src/utils.c b/src/utils.c index f3b4fc0a46..0fee1b31e4 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->editor->scintilla); - fold_level = sci_get_fold_level(doc->editor->scintilla, 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->scintilla, tag_line); - fold_level = sci_get_fold_level(doc->editor->scintilla, tag_line); - } while (tag_line >= 0 && - (fold_level & SC_FOLDLEVELNUMBERMASK) != fn_fold); - - if (tag_line >= 0) - { - if (sci_get_lexer(doc->editor->scintilla) == SCLEX_CPP) - cur_tag = parse_cpp_function_at_line(doc->editor->scintilla, tag_line); - else - cur_tag = parse_function_at_line(doc->editor->scintilla, 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->editor->scintilla, 3); - ttf.lpstrText = (gchar*)filebase; - - if (sci_find_text(doc->editor->scintilla, SCFIND_MATCHCASE, &ttf) != -1) - { - sci_target_start(doc->editor->scintilla, ttf.chrgText.cpMin); - sci_target_end(doc->editor->scintilla, ttf.chrgText.cpMax); - sci_target_replace(doc->editor->scintilla, 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 b5c3ee9e1a..c5d3521b51 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);