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:
parent
7c71457fb1
commit
4837030ca1
@ -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>
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "support.h"
|
||||
#include "filetypes.h"
|
||||
#include "document.h"
|
||||
#include "editor.h"
|
||||
#include "ui_utils.h"
|
||||
#include "pluginmacros.h"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
225
src/symbols.c
225
src/symbols.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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(
|
||||
|
253
src/utils.c
253
src/utils.c
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user