Fix compilation.

Move utils_get_current_function() to symbols.c.
Move utils_replace_filename() to document.c.


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/editor-struct@2766 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2008-07-08 16:30:37 +00:00
parent 7c71457fb1
commit 4837030ca1
16 changed files with 309 additions and 296 deletions

View File

@ -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 <nick(dot)treleaven(at)btinternet(dot)com>

View File

@ -30,6 +30,7 @@
#include "support.h"
#include "filetypes.h"
#include "document.h"
#include "editor.h"
#include "ui_utils.h"
#include "pluginmacros.h"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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"

View File

@ -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;
}
}

View File

@ -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"

View File

@ -28,6 +28,7 @@
* matching filetype is first loaded.
*/
#include "SciLexer.h"
#include "geany.h"
#include <ctype.h>
@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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(

View File

@ -25,7 +25,6 @@
* General utility functions, non-GTK related.
*/
#include "SciLexer.h"
#include "geany.h"
#include <stdlib.h>
@ -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);

View File

@ -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);