static gboolean is_commented_multiline (IAnjutaEditor *editor, IAnjutaIterable *start, IAnjutaIterable *end) { gchar *text; gboolean is_commented = TRUE; text = ianjuta_editor_get_text (editor, start, end, NULL); while (is_commented && !g_str_has_prefix (text, "/*")) { if (!ianjuta_iterable_previous (start, NULL)) is_commented = FALSE; g_free (text); text = ianjuta_editor_get_text (editor, start, end, NULL); if (g_str_has_prefix (text, "*/")) is_commented = FALSE; } while (is_commented && !g_str_has_suffix (text, "*/")) { if (!ianjuta_iterable_next (end, NULL)) is_commented = FALSE; g_free (text); text = ianjuta_editor_get_text (editor, start, end, NULL); if (g_str_has_suffix (text, "/*")) is_commented = FALSE; } g_free (text); return is_commented; }
void cpp_java_indentation_changed (IAnjutaEditor *editor, IAnjutaIterable *position, gboolean added, gint length, gint lines, const gchar *text, IndentCPlugin* plugin) { /* If autoindent is enabled*/ if (plugin->smart_indentation) { if (g_settings_get_boolean (plugin->settings, PREF_BRACE_AUTOCOMPLETION)) { if (!added && length == 1 && (*text == '[' || *text == '(')) { IAnjutaIterable *next; gchar *next_char; next = ianjuta_iterable_clone (position, NULL); ianjuta_iterable_next (next, NULL); next_char = ianjuta_editor_get_text (editor, position, next, NULL); if ((*text == '[' && *next_char == ']') || (*text == '(' && *next_char == ')')) erase_editor_blocked (editor, position, next, plugin); } } } }
static gboolean match_keyword (MacroPlugin * plugin, GtkTreeIter * iter, const gchar *keyword) { gchar *name; gint offset = 0; gtk_tree_model_get(macro_db_get_model(plugin->macro_db), iter, MACRO_NAME, &name, -1); if ( name && strcmp(keyword, name) == 0) { gchar* text = macro_db_get_macro(plugin, plugin->macro_db, iter, &offset); if (plugin->current_editor != NULL && text != NULL) { gint i; IAnjutaIterable *pos = ianjuta_editor_get_position (IANJUTA_EDITOR(plugin->current_editor), NULL); ianjuta_editor_insert (IANJUTA_EDITOR (plugin->current_editor), pos, text, -1, NULL); for (i = 0; i < offset; i++) ianjuta_iterable_next (pos, NULL); ianjuta_editor_goto_position (IANJUTA_EDITOR(plugin->current_editor), pos, NULL); g_free(text); g_object_unref (pos); } return TRUE; } return FALSE; }
/* Check if iter is inside string. Begining of string * is not counted as inside. */ static gboolean is_iter_inside_string (IAnjutaIterable *iter) { IAnjutaEditorAttribute attrib; attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL); /* Check if we are *inside* string. Begining * of string does not count as inside. */ if (attrib == IANJUTA_EDITOR_STRING) { /* Peek previous attrib and see what it was */ if (ianjuta_iterable_previous (iter, NULL)) { attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL); if (attrib == IANJUTA_EDITOR_STRING) { /* We are inside string */ return TRUE; } else { /* The string just began, not inside. * Restore iter from the peek */ ianjuta_iterable_next (iter, NULL); } } /* else, there is no previous and so we can't be inside string */ } return FALSE; }
/** * parser_cxx_assist_create_calltips: * @iter: List of symbols * @merge: list of calltips to merge or NULL * * Create a list of Calltips (string) from a list of symbols * * A newly allocated GList* with newly allocated strings */ static GList* parser_cxx_assist_create_calltips (IAnjutaIterable* iter, GList* merge) { GList* tips = merge; if (iter) { do { IAnjutaSymbol* symbol = IANJUTA_SYMBOL (iter); const gchar* name = ianjuta_symbol_get_string ( symbol,IANJUTA_SYMBOL_FIELD_NAME, NULL); if (name != NULL) { const gchar* args = ianjuta_symbol_get_string ( symbol, IANJUTA_SYMBOL_FIELD_SIGNATURE, NULL); const gchar* rettype = ianjuta_symbol_get_string ( symbol, IANJUTA_SYMBOL_FIELD_RETURNTYPE, NULL); gchar* print_args; gchar* separator; gchar* white_name; gint white_count = 0; if (!rettype) rettype = ""; else white_count += strlen(rettype) + 1; white_count += strlen(name) + 1; white_name = g_strnfill (white_count, ' '); separator = g_strjoin (NULL, ", \n", white_name, NULL); gchar** argv; if (!args) args = "()"; argv = g_strsplit (args, ",", -1); print_args = g_strjoinv (separator, argv); gchar* tip = g_strdup_printf ("%s %s %s", rettype, name, print_args); if (!g_list_find_custom (tips, tip, (GCompareFunc) strcmp)) tips = g_list_append (tips, tip); g_strfreev (argv); g_free (print_args); g_free (separator); g_free (white_name); } else break; } while (ianjuta_iterable_next (iter, NULL)); } return tips; }
static void update_type_list (AnjutaShell *shell, IAnjutaIterable *iter, const gchar *name) { gchar *list = NULL; GValue value = {0,}; if (iter) { ianjuta_iterable_first (iter, NULL); if (ianjuta_iterable_get_length (iter, NULL) > 0) { GString *s = g_string_sized_new(ianjuta_iterable_get_length (iter, NULL) * 10); do { IAnjutaSymbol *symbol = IANJUTA_SYMBOL (iter); const gchar *sname = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL); g_string_append(s, sname); g_string_append_c(s, ' '); } while (ianjuta_iterable_next (iter, NULL)); list = g_string_free(s, FALSE); } } anjuta_shell_get_value (shell, name, &value, NULL); if (G_VALUE_HOLDS_STRING(&value)) { const gchar *value_list = g_value_get_string (&value); if (list == NULL) { anjuta_shell_remove_value (shell, name, NULL); } else if (strcmp (list, value_list) == 0) { g_free (list); } else { g_value_take_string (&value, list); anjuta_shell_add_value (shell, name, &value, NULL); } } else { if (list != NULL) { g_value_init (&value, G_TYPE_STRING); g_value_take_string (&value, list); anjuta_shell_add_value (shell, name, &value, NULL); } } if (G_IS_VALUE (&value)) g_value_unset (&value); }
static gboolean glade_widget_member_of_scope (gchar *widget_name, IAnjutaIterable *members) { do { IAnjutaSymbol *symbol = IANJUTA_SYMBOL (members); gchar *member_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL); /* Checks if member already exists... */ if (g_strcmp0 (member_name, widget_name) == 0) { return TRUE; } } while (ianjuta_iterable_next (members, NULL)); return FALSE; }
/** * parser_cxx_assist_add_completions_from_symbols: * @assist: self * @symbols: Symbol iteration * * Add completions to the completions cache from @symbols. * */ static void parser_cxx_assist_add_completions_from_symbols (ParserCxxAssist* assist, IAnjutaIterable* symbols) { if (!symbols) return; do { IAnjutaSymbol* symbol = IANJUTA_SYMBOL (symbols); IAnjutaEditorAssistProposal* proposal = parser_cxx_assist_proposal_new (symbol); anjuta_completion_add_item (assist->priv->completion_cache, proposal); } while (ianjuta_iterable_next (symbols, NULL)); }
static gboolean line_is_preprocessor (IAnjutaEditor *editor, IAnjutaIterable *iter) { gboolean is_preprocessor = FALSE; IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL); if (skip_iter_to_previous_logical_line (editor, new_iter)) { /* Forward the newline char and point to line begin of next line */ gchar ch; ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); skip_iter_to_newline_tail (new_iter, ch); ianjuta_iterable_next (new_iter, NULL); } /* else, line is already pointed at first char of the line */ do { gchar ch; ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); if (ch == '#') { is_preprocessor = TRUE; break; } if (iter_is_newline (new_iter, ch) || !isspace (ch)) break; } while (ianjuta_iterable_next (new_iter, NULL)); g_object_unref (new_iter); return is_preprocessor; }
/* Returns TRUE if iter was moved */ static gboolean skip_iter_to_newline_tail (IAnjutaIterable *iter, gchar ch) { gboolean ret_val = FALSE; if (ch == '\r') { /* Possibly at head */ if (ianjuta_iterable_previous (iter, NULL)) { ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL); if (ch != '\n') /* Already at tail, undo iter */ ianjuta_iterable_next (iter, NULL); else /* Correctly at tail */ ret_val = TRUE; } } return ret_val; }
static void on_cls_inherit_update (IAnjutaSymbolQuery *query, IAnjutaIterable *iter, AnjutaClassInheritance *plugin) { IAnjutaSymbol *symbol; ClsNode *cls_node; GError *err = NULL; /* Mark all nodes for deletion. Selectively, they will be unmarked below */ g_hash_table_foreach (plugin->nodes, (GHFunc) on_cls_node_mark_for_deletion, NULL); if (!iter) { DEBUG_PRINT ("%s", "cls_inherit_update_graph (): search returned no items."); goto cleanup; } ianjuta_iterable_first (iter, NULL); if (ianjuta_iterable_get_length (iter, NULL) <= 0) { g_object_unref (iter); goto cleanup; } do { gint klass_id; IAnjutaIterable *parents; /* a symbol representing a class */ symbol = IANJUTA_SYMBOL (iter); /* get parents of the current class */ parents = ianjuta_symbol_query_search_class_parents (plugin->query_parents, symbol, &err); if (err) { g_warning ("Class parents query failed: %s", err->message); g_error_free (err); err = NULL; } /* if no parents are found then continue */ if (parents == NULL || ianjuta_iterable_get_length (parents, NULL) <= 0) { /*DEBUG_PRINT ("ClassInheritance: no parents found for class %s", ianjuta_symbol_get_name (symbol, NULL));*/ continue; } if ((klass_id = ianjuta_symbol_get_int (symbol, IANJUTA_SYMBOL_FIELD_ID, NULL)) <= 0) { /*DEBUG_PRINT ("%s", "ClassInheritance: klass_id cannot be <= 0");*/ continue; } cls_node = g_hash_table_lookup (plugin->nodes, GINT_TO_POINTER (klass_id)); if (!cls_node) { cls_node = cls_inherit_create_node (plugin, symbol); g_hash_table_insert (plugin->nodes, GINT_TO_POINTER (klass_id), cls_node); } cls_node->marked_for_deletion = FALSE; /* Get parents */ do { gint parent_id; ClsNode *parent_node; IAnjutaSymbol *parent_symbol; parent_symbol = IANJUTA_SYMBOL (parents); parent_id = ianjuta_symbol_get_int (parent_symbol, IANJUTA_SYMBOL_FIELD_ID, NULL); parent_node = g_hash_table_lookup (plugin->nodes, GINT_TO_POINTER (parent_id)); if (!parent_node) { parent_node = cls_inherit_create_node (plugin, parent_symbol); g_hash_table_insert (plugin->nodes, GINT_TO_POINTER (parent_id), parent_node); } parent_node->marked_for_deletion = FALSE; cls_node_add_edge (parent_node, cls_node); } while (ianjuta_iterable_next (parents, NULL) == TRUE); g_object_unref (parents); } while (ianjuta_iterable_next (iter, NULL) == TRUE); cleanup: /* Delete all marked nodes that did not get unmarked above. */ g_hash_table_foreach_remove (plugin->nodes, (GHRFunc) on_cls_node_delete_marked, NULL); cls_inherit_draw (plugin); }
void cpp_java_indentation_char_added (IAnjutaEditor *editor, IAnjutaIterable *insert_pos, gchar ch, IndentCPlugin *plugin) { IAnjutaEditorAttribute attrib; IAnjutaIterable *iter; gboolean should_auto_indent = FALSE; iter = ianjuta_iterable_clone (insert_pos, NULL); /* If autoindent is enabled*/ if (plugin->smart_indentation) { /* DEBUG_PRINT ("Char added at position %d: '%c'", insert_pos, ch); */ if (iter_is_newline (iter, ch)) { skip_iter_to_newline_head (iter, ch); /* All newline entries means enable indenting */ should_auto_indent = TRUE; } else if (ch == '{' || ch == '}' || ch == '#') { /* Indent only when it's the first non-white space char in the line */ /* Don't bother if we are inside string */ attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL); if (attrib != IANJUTA_EDITOR_STRING) { /* Iterate backwards till the begining of the line and disable * indenting if any non-white space char is encountered */ /* Begin by assuming it should be indented */ should_auto_indent = TRUE; while (ianjuta_iterable_previous (iter, NULL)) { ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL); //DEBUG_PRINT ("Looking at char '%c'", ch); /* Break on begining of line (== end of previous line) */ if (iter_is_newline (iter, ch)) { skip_iter_to_newline_head (iter, ch); break; } /* If a non-white space char is encountered, disabled indenting */ if (!isspace (ch)) { should_auto_indent = FALSE; break; } } } } if (should_auto_indent) { gint insert_line; gint line_indent; gint parenthesis_indentation; ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL); insert_line = ianjuta_editor_get_lineno (editor, NULL); line_indent = get_line_auto_indentation (plugin, editor, insert_line, &parenthesis_indentation); set_line_indentation (plugin, editor, insert_line, line_indent, parenthesis_indentation); ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL); } } if (g_settings_get_boolean (plugin->settings, PREF_BRACE_AUTOCOMPLETION)) { if (ch == '[' || ch == '(') { gchar *prev_char, *next_char; IAnjutaIterable *previous, *next, *next_end; previous = ianjuta_iterable_clone (iter, NULL); ianjuta_iterable_previous (previous, NULL); prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL); next = ianjuta_iterable_clone (iter, NULL); ianjuta_iterable_next (next, NULL); next_end = ianjuta_iterable_clone (next, NULL); ianjuta_iterable_next (next_end, NULL); next_char = ianjuta_editor_get_text (editor, next, next_end, NULL); /* If the previous char is a ' we don't have to autocomplete, also we only autocomplete if the next character is white-space a closing bracket, "," or ";" */ if (*prev_char != '\'' && (g_ascii_isspace(*next_char) || is_closing_bracket (*next_char) || *next_char == ',' || *next_char == ';'|| *next_char == '\0')) { ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL); ianjuta_iterable_next (iter, NULL); switch (ch) { case '[': insert_editor_blocked (editor, iter, "]", plugin); break; case '(': insert_editor_blocked (editor, iter, ")", plugin); break; default: break; } ianjuta_editor_goto_position (editor, iter, NULL); ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL); } g_object_unref (previous); } else if (ch == '"' || ch == '\'') { gchar *prev_char; IAnjutaIterable *previous; previous = ianjuta_iterable_clone (iter, NULL); ianjuta_iterable_previous (previous, NULL); prev_char = ianjuta_editor_get_text (editor, previous, iter, NULL); /* First iter*/ ianjuta_iterable_next (iter, NULL); /* * If the character is " we have to decide if we need insert * another " or we have to skip the character */ if (ch == '"' || ch == '\'') { /* * Now we have to detect if we want to manage " as a char */ if (*prev_char != '\'' && *prev_char != '\\') { gchar *c; if (ch == '"') c = g_strdup ("\""); else c = g_strdup ("'"); ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT (editor), NULL); insert_editor_blocked (editor, iter, c, plugin); ianjuta_editor_goto_position (editor, iter, NULL); ianjuta_document_end_undo_action (IANJUTA_DOCUMENT (editor), NULL); g_free (c); } g_object_unref (previous); g_object_unref (iter); return; } g_object_unref (previous); } } g_object_unref (iter); }
/* incomplete_statement: * 1 == COMPLETE STATEMENT * 0 == INCOMPLETE STATEMENT * -1 == UNKNOWN */ static gint get_line_indentation_base (IndentCPlugin *plugin, IAnjutaEditor *editor, gint line_num, gint *incomplete_statement, gint *parenthesis_indentation, gboolean *colon_indent) { IAnjutaIterable *iter; gchar point_ch; gint line_indent = 0; gint extra_indent = 0; gboolean looking_at_just_next_line = TRUE; gboolean current_line_is_preprocessor = FALSE; gboolean current_line_is_continuation = FALSE; gboolean line_checked_for_comment = FALSE; /* Determine whether or not to add multi-line comment asterisks */ const gchar *comment_continued = " * "; IAnjutaIterable *line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL); IAnjutaIterable *line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL); *incomplete_statement = -1; *parenthesis_indentation = 0; if (line_num <= 1) return 0; /* DEBUG_PRINT ("In %s()", __FUNCTION__); */ iter = ianjuta_editor_get_line_begin_position (editor, line_num, NULL); current_line_is_preprocessor = line_is_preprocessor (editor, iter); current_line_is_continuation = line_is_continuation (editor, iter); /* DEBUG_PRINT ("Current line is preprocessor = %d", current_line_is_preprocessor); DEBUG_PRINT ("Current line is continuation = %d", current_line_is_continuation); */ /* line_indent = get_line_indentation (editor, line_num - 1); */ if (current_line_is_preprocessor && current_line_is_continuation) { /* Continuation of preprocessor line -- just maintain indentation */ g_object_unref (iter); return get_line_indentation (editor, line_num - 1); } else if (current_line_is_preprocessor) { /* Preprocessor line -- indentation should be 0 */ g_object_unref (iter); return 0; } while (ianjuta_iterable_previous (iter, NULL)) { /* Skip strings */ IAnjutaEditorAttribute attrib = ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (iter), NULL); if (attrib == IANJUTA_EDITOR_STRING) continue; point_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL); /* DEBUG_PRINT("point_ch = %c", point_ch); */ /* Check for line comment comment */ if (!line_checked_for_comment && !isspace(point_ch)) { gboolean comment = FALSE; IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL); do { gchar c; /* Skip strings */ if (ianjuta_editor_cell_get_attribute (IANJUTA_EDITOR_CELL (new_iter), NULL) == IANJUTA_EDITOR_STRING) continue; c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); if (iter_is_newline (new_iter, c)) { line_checked_for_comment = TRUE; break; } if (c == '/') { IAnjutaIterable* tmp_iter = ianjuta_iterable_clone (new_iter, NULL); if (!ianjuta_iterable_previous (tmp_iter, NULL)) { g_object_unref (tmp_iter); break; } c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (tmp_iter), 0, NULL); if (c == '/') { /* is a line comment, skip until begin of comment */ comment = TRUE; g_object_unref (tmp_iter); break; } g_object_unref (tmp_iter); } } while (ianjuta_iterable_previous (new_iter, NULL)); if (comment) { ianjuta_iterable_assign (iter, new_iter, NULL); ianjuta_iterable_previous (iter, NULL); g_object_unref (new_iter); continue; } g_object_unref (new_iter); } /* Check if we are inside a comment */ if (point_ch == '/' || point_ch == '*') { gboolean comment = FALSE; gboolean comment_end = FALSE; IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL); do { gchar c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(new_iter), 0, NULL); if (!comment_end && iter_is_newline (new_iter, c)) { break; } if (c == '*') { IAnjutaIterable* prev = ianjuta_iterable_clone (new_iter, NULL); IAnjutaIterable* next = ianjuta_iterable_clone (new_iter, NULL); ianjuta_iterable_previous (prev, NULL); ianjuta_iterable_next (next, NULL); gchar prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0, NULL); gchar next_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (next), 0, NULL); if (prev_c == '/') { /* starts comment */ comment = TRUE; if (!comment_end) { extra_indent++; /* If a multiline comment is continuing, check the next line and insert " * " * only if it does not already exist there. The purpose of this fix is to avoid * extra " * " on auto-indent. */ if ((g_settings_get_boolean (plugin->settings, PREF_COMMENT_LEADING_ASTERISK)) && (ianjuta_iterable_compare (line_end, line_begin, NULL)) == 0) { ianjuta_editor_insert (editor, line_begin, comment_continued, -1, NULL); } /* In the middle of a comment we can't know * if the statement is incomplete */ *incomplete_statement = -1; /* ":" have to be ignored inside comments */ if (*colon_indent) { *colon_indent = FALSE; extra_indent -= INDENT_SIZE; } } g_object_unref (prev); g_object_unref (next); break; } else if (next_c == '/') { /* ends comment: */ comment_end = TRUE; g_object_unref (prev); g_object_unref (next); continue; } /* Possibly continued comment */ else if (isspace(prev_c)) { gboolean possible_comment = FALSE; while (ianjuta_iterable_previous (prev, NULL)) { prev_c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (prev), 0, NULL); if (!isspace(prev_c)) break; if (iter_is_newline (prev, prev_c)) { possible_comment = TRUE; break; } } if (possible_comment) { ianjuta_iterable_assign (new_iter, prev, NULL); g_object_unref (prev); g_object_unref (next); continue; } } g_object_unref (prev); g_object_unref (next); } } while (ianjuta_iterable_previous (new_iter, NULL)); if (comment) { ianjuta_iterable_assign (iter, new_iter, NULL); ianjuta_iterable_previous (iter, NULL); g_object_unref (new_iter); continue; } g_object_unref (new_iter); } if (point_ch == ')' || point_ch == ']' || point_ch == '}') { gint line_saved; line_saved = ianjuta_editor_get_line_from_position (editor, iter, NULL); /* If we encounter a block-end before anything else, the * statement could hardly be incomplte. */ if (point_ch == '}' && *incomplete_statement == -1) *incomplete_statement = 0; /* If at level 0 indentation, encoutered a * block end, don't bother going further */ if (point_ch == '}' && get_line_indentation (editor, line_saved) <= 0) { line_indent = 0; line_indent += extra_indent; break; } /* Find matching brace and continue */ if (!anjuta_util_jump_to_matching_brace (iter, point_ch, -1)) { line_indent = get_line_indentation (editor, line_saved); line_indent += extra_indent; break; } } else if (point_ch == '{') { gint line_for_indent = ianjuta_editor_get_line_from_position (editor, iter, NULL); line_indent = get_line_indentation (editor, line_for_indent); /* Increase line indentation */ line_indent += INDENT_SIZE; line_indent += extra_indent; /* If we encounter a block-start before anything else, the * statement could hardly be incomplte. */ if (point_ch == '{' && *incomplete_statement == -1) *incomplete_statement = 0; break; } else if (point_ch == '(' || point_ch == '[') { line_indent = 0; if (g_settings_get_boolean (plugin->settings, PREF_INDENT_PARENTHESIS_LINEUP)) { while (ianjuta_iterable_previous (iter, NULL)) { gchar dummy_ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL); if (iter_is_newline (iter, dummy_ch)) { skip_iter_to_newline_head (iter, dummy_ch); break; } if (dummy_ch == '\t') line_indent += TAB_SIZE; else (*parenthesis_indentation)++; } (*parenthesis_indentation)++; line_indent += extra_indent; } else { gint line_for_indent = ianjuta_editor_get_line_from_position (editor, iter, NULL); line_indent = get_line_indentation (editor, line_for_indent); line_indent += extra_indent; (*parenthesis_indentation) += g_settings_get_int (plugin->settings, PREF_INDENT_PARENTHESIS_SIZE); } /* Although statement is incomplete at this point, we don't * set it to incomplete and just leave it to unknown to avaoid * increating indentation for it, because incomplete braces, * overrides any existing indentation */ *incomplete_statement = -1; break; } else if (point_ch == ';' || point_ch == ',') { /* If we encounter statement-end before any non-whitespace * char, the statement is complete. */ if (*incomplete_statement == -1) *incomplete_statement = 0; } else if (point_ch == ':' && *colon_indent == FALSE) { /* This is a forward reference, all lines below should have * increased indentation until the next statement has * a ':' * If current line indentation is zero, that we don't indent */ IAnjutaIterable* new_iter = ianjuta_iterable_clone (iter, NULL); IAnjutaIterable* line_begin; gboolean indent = FALSE; gchar c; /* Is the last non-whitespace in line */ while (ianjuta_iterable_next (new_iter, NULL)) { c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); if (!isspace(c)) break; if (iter_is_newline (new_iter, c)) { indent = TRUE; break; } } line_begin = ianjuta_editor_get_line_begin_position(editor, ianjuta_editor_get_line_from_position(editor, iter, NULL), NULL); c = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_begin), 0, NULL); if (indent) { *colon_indent = TRUE; if (*incomplete_statement == -1) *incomplete_statement = 0; } if (indent && isspace(c)) { extra_indent += INDENT_SIZE; } g_object_unref (new_iter); g_object_unref (line_begin); } else if (iter_is_newline (iter, point_ch)) { skip_iter_to_newline_head (iter, point_ch); /* We just crossed a line boundary. Skip any preprocessor lines, * and ensure that line_indent is updated with correct real * previous non-preprocessor line. */ if (skip_preprocessor_lines (editor, iter) && looking_at_just_next_line) { /* gint line = ianjuta_editor_get_line_from_position (editor, iter, NULL); line_indent = get_line_indentation (editor, line); */ } looking_at_just_next_line = FALSE; line_checked_for_comment = FALSE; } else if (!isspace (point_ch)) { /* If we encounter any non-whitespace char before any of the * statement-complete indicators, the statement is basically * incomplete */ if (*incomplete_statement == -1) *incomplete_statement = 1; } } if (!line_indent && extra_indent) { line_indent += extra_indent; } g_object_unref (iter); return line_indent; }
static gint set_line_indentation (IndentCPlugin *plugin, IAnjutaEditor *editor, gint line_num, gint indentation, gint parenthesis_indentation) { IAnjutaIterable *line_begin, *line_end, *indent_position; IAnjutaIterable *current_pos; gint carat_offset, nchars = 0; gchar *old_indent_string = NULL, *indent_string = NULL; /* DEBUG_PRINT ("In %s()", __FUNCTION__); */ line_begin = ianjuta_editor_get_line_begin_position (editor, line_num, NULL); line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL); /* DEBUG_PRINT ("line begin = %d, line end = %d, current_pos = %d", line_begin, line_end, current_pos); */ indent_position = ianjuta_iterable_clone (line_begin, NULL); if (ianjuta_iterable_compare (line_end, line_begin, NULL) > 0) { gchar *idx; gchar *line_string = ianjuta_editor_get_text (editor, line_begin, line_end, NULL); //DEBUG_PRINT ("line_string = '%s'", line_string); if (line_string) { idx = line_string; /* Find first non-white space */ while (*idx != '\0' && isspace (*idx)) { idx = g_utf8_find_next_char (idx, NULL); ianjuta_iterable_next (indent_position, NULL); } g_free (line_string); } } /* Indent iter defined at this point, Identify how much is current * position is beyound this point. We need to restore it later after * indentation */ current_pos = ianjuta_editor_get_position (editor, NULL); carat_offset = ianjuta_iterable_diff (indent_position, current_pos, NULL); //DEBUG_PRINT ("carat offset is = %d", carat_offset); /* Set new indentation */ if ((indentation + parenthesis_indentation) > 0) { indent_string = get_line_indentation_string (plugin, editor, indentation, parenthesis_indentation); nchars = indent_string ? g_utf8_strlen (indent_string, -1) : 0; /* Only indent if there is something to indent with */ if (indent_string) { /* Get existing indentation */ if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0) { old_indent_string = ianjuta_editor_get_text (editor, line_begin, indent_position, NULL); //DEBUG_PRINT ("old_indent_string = '%s'", old_indent_string); } /* Only indent if there was no indentation before or old * indentation string was different from the new indent string */ if (old_indent_string == NULL || strcmp (old_indent_string, indent_string) != 0) { /* Remove the old indentation string, if there is any */ if (old_indent_string) ianjuta_editor_erase (editor, line_begin, indent_position, NULL); /* Insert the new indentation string */ ianjuta_editor_insert (editor, line_begin, indent_string, -1, NULL); } } } /* If indentation == 0, we really didn't enter the previous code block, * but we may need to clear existing indentation. */ if ((indentation + parenthesis_indentation) == 0) { /* Get existing indentation */ if (ianjuta_iterable_compare (indent_position, line_begin, NULL) > 0) { old_indent_string = ianjuta_editor_get_text (editor, line_begin, indent_position, NULL); } if (old_indent_string) ianjuta_editor_erase (editor, line_begin, indent_position, NULL); } /* Restore current position */ if (carat_offset >= 0) { /* If the cursor was not before the first non-space character in * the line, restore it's position after indentation. */ gint i; IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL); for (i = 0; i < nchars + carat_offset; i++) ianjuta_iterable_next (pos, NULL); ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL); ianjuta_editor_goto_position (editor, pos, NULL); ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL); g_object_unref (pos); } else /* cursor_offset < 0 */ { /* If the cursor was somewhere in the old indentation spaces, * home the cursor to first non-space character in the line (or * end of line if there is no non-space characters in the line. */ gint i; IAnjutaIterable *pos = ianjuta_editor_get_line_begin_position (editor, line_num, NULL); for (i = 0; i < nchars; i++) ianjuta_iterable_next (pos, NULL); ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL); ianjuta_editor_goto_position (editor, pos, NULL); ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL); g_object_unref (pos); } g_object_unref (current_pos); g_object_unref (indent_position); g_object_unref (line_begin); g_object_unref (line_end); g_free (old_indent_string); g_free (indent_string); return nchars; }
/* Skips to the end-of-line of previous non-preprocessor line. Any multiple * preprocessor lines are skipped. If current * line is not preprocessor line, nothing happens. If there is no previous * non-preprocessor line (we are at first line of the document which happens * to be preprocessor line), iter is set to the first character in the * document. It returns TRUE if the line is preprocessor line, otherwise * FALSE. */ static gboolean skip_preprocessor_lines (IAnjutaEditor *editor, IAnjutaIterable *iter) { gboolean line_found = FALSE; gboolean preprocessor_found = FALSE; IAnjutaIterable *new_iter = ianjuta_iterable_clone (iter, NULL); do { gboolean is_preprocessor = FALSE; if (skip_iter_to_previous_logical_line (editor, new_iter)) { gchar ch; ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); skip_iter_to_newline_tail (new_iter, ch); ianjuta_iterable_next (new_iter, NULL); } do { gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (new_iter), 0, NULL); if (ch == '#') { is_preprocessor = TRUE; /* DEBUG_PRINT ("Line %d is preprocessor line .. Skipping", ianjuta_editor_get_line_from_position (editor, new_iter, NULL)); */ break; } if (iter_is_newline (new_iter, ch) || !isspace (ch)) { skip_iter_to_newline_tail (new_iter, ch); break; } } while (ianjuta_iterable_next (new_iter, NULL)); if (is_preprocessor) { line_found = skip_iter_to_previous_line (editor, new_iter); ianjuta_iterable_assign (iter, new_iter, NULL); preprocessor_found = TRUE; } else { /* DEBUG_PRINT ("Line %d is *not* preprocessor line .. Breaking", ianjuta_editor_get_line_from_position (editor, new_iter, NULL)); */ break; } } while (line_found); g_object_unref (new_iter); return preprocessor_found; }
/** * parser_cxx_assist_parse_expression: * @assist: self, * @iter: current cursor position * @start_iter: return location for the start of the completion * * Returns: An iter of a list of IAnjutaSymbols or NULL */ static IAnjutaIterable* parser_cxx_assist_parse_expression (ParserCxxAssist* assist, IAnjutaIterable* iter, IAnjutaIterable** start_iter) { IAnjutaEditor* editor = IANJUTA_EDITOR (assist->priv->iassist); IAnjutaIterable* res = NULL; IAnjutaIterable* cur_pos = ianjuta_iterable_clone (iter, NULL); gboolean op_start = FALSE; gboolean ref_start = FALSE; gchar* stmt = NULL; /* Cursor points after the current characters, move back */ ianjuta_iterable_previous (cur_pos, NULL); /* Search for a operator in the current line */ do { gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL(cur_pos), 0, NULL); if (parser_cxx_assist_is_expression_separator(ch, FALSE, iter)) { break; } if (ch == '.' || (op_start && ch == '-') || (ref_start && ch == ':')) { /* Found an operator, get the statement and the pre_word */ IAnjutaIterable* pre_word_start = ianjuta_iterable_clone (cur_pos, NULL); IAnjutaIterable* pre_word_end = ianjuta_iterable_clone (iter, NULL); IAnjutaIterable* stmt_end = ianjuta_iterable_clone (pre_word_start, NULL); /* we need to pass to the parser all the statement included the last * operator, being it "." or "->" or "::" * Increase the end bound of the statement. */ ianjuta_iterable_next (stmt_end, NULL); if (op_start == TRUE || ref_start == TRUE) ianjuta_iterable_next (stmt_end, NULL); /* Move one character forward so we have the start of the pre_word * and not the last operator */ ianjuta_iterable_next (pre_word_start, NULL); /* If this is a two character operator, skip the second character */ if (op_start) { ianjuta_iterable_next (pre_word_start, NULL); } parser_cxx_assist_update_pre_word (assist, ianjuta_editor_get_text ( editor, pre_word_start, pre_word_end, NULL)); /* Try to get the name of the variable */ while (ianjuta_iterable_previous (cur_pos, NULL)) { gchar word_ch = ianjuta_editor_cell_get_char ( IANJUTA_EDITOR_CELL(cur_pos), 0, NULL); if (parser_cxx_assist_is_expression_separator(word_ch, FALSE, cur_pos)) break; } ianjuta_iterable_next (cur_pos, NULL); stmt = ianjuta_editor_get_text (editor, cur_pos, stmt_end, NULL); *start_iter = pre_word_start; g_object_unref (stmt_end); g_object_unref (pre_word_end); break; } else if (ch == '>') op_start = TRUE; else if (ch == ':') ref_start = TRUE; else { op_start = FALSE; ref_start = FALSE; } } while (ianjuta_iterable_previous (cur_pos, NULL)); if (stmt) { gint lineno; gchar *above_text; IAnjutaIterable* start; if (!assist->priv->editor_filename) { g_free (stmt); return NULL; } start = ianjuta_editor_get_start_position (editor, NULL); above_text = ianjuta_editor_get_text (editor, start, iter, NULL); g_object_unref (start); lineno = ianjuta_editor_get_lineno (editor, NULL); /* the parser works even for the "Gtk::" like expressions, so it * shouldn't be created a specific case to handle this. */ res = engine_parser_process_expression (stmt, above_text, assist->priv->editor_filename, lineno); g_free (stmt); } g_object_unref (cur_pos); return res; }
gboolean cls_node_expand (ClsNode *cls_node, ClsNodeExpansionType expansion_type) { Agsym_t *sym; GString *label; gint max_label_items = 0; gint real_items_length = 0; gint var_order = -1000; gint method_order = 0; IAnjutaSymbol *node_sym; IAnjutaIterable *iter; GError *err = NULL; if (cls_node->expansion_status == expansion_type || expansion_type == CLS_NODE_COLLAPSED) return FALSE; node_sym = IANJUTA_SYMBOL (ianjuta_symbol_query_search_id (cls_node->plugin->query_id, cls_node->klass_id, &err)); if (err) { g_warning ("Symbol ID query failed: %s", err->message); g_error_free (err); err = NULL; } if (!node_sym) return FALSE; if (!(sym = agfindattr(cls_node->graph->proto->n, "shape"))) sym = agnodeattr(cls_node->graph, "shape", ""); agxset (cls_node->agnode, sym->index, "record"); if (!(sym = agfindattr(cls_node->graph->proto->n, "label"))) sym = agnodeattr(cls_node->graph, "label", ""); label = g_string_new (""); g_string_printf (label, "{%s", cls_node->sym_name); /* get members from the passed symbol node */ iter = ianjuta_symbol_query_search_members (cls_node->plugin->query_members, node_sym, &err); if (err) { g_warning ("Class members query failed: %s", err->message); g_error_free (err); err = NULL; } real_items_length = ianjuta_iterable_get_length (iter, NULL); /* set the max number of items to draw */ if (real_items_length <= NODE_HALF_DISPLAY_ELEM_NUM || expansion_type == CLS_NODE_FULL_EXPANDED) { max_label_items = real_items_length; cls_node->expansion_status = CLS_NODE_FULL_EXPANDED; } else { max_label_items = NODE_HALF_DISPLAY_ELEM_NUM; cls_node->expansion_status = CLS_NODE_SEMI_EXPANDED; } g_hash_table_remove_all (cls_node->members); if (iter && real_items_length > 0) { gint i = 0; /* First member variables */ do { const gchar *name, *args, *type_name; IAnjutaSymbol *symbol; GdkPixbuf *icon; symbol = IANJUTA_SYMBOL (iter); name = g_strdup (ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL)); args = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_SIGNATURE, NULL); icon = (GdkPixbuf*) ianjuta_symbol_get_icon (symbol, NULL); if (!args) /* Member variables */ { ClsNodeItem *cls_item = g_new0 (ClsNodeItem, 1); type_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_TYPE_NAME, NULL); cls_item->cls_node = cls_node; cls_item->label = g_strconcat (name, " : ", type_name, NULL); cls_item->order = var_order++; if (icon) g_object_ref (icon); cls_item->icon = icon; g_hash_table_insert (cls_node->members, g_strdup (cls_item->label), cls_item); g_string_append_printf (label, "|%s", cls_item->label); /* Setup file and line */ cls_item->type_name = g_strdup (type_name); cls_item->line = ianjuta_symbol_get_int (symbol, IANJUTA_SYMBOL_FIELD_FILE_POS, NULL); cls_item->file = ianjuta_symbol_get_file (symbol, NULL); } else /* Member methods */ { ClsNodeItem *cls_item; gchar *method_key = g_strconcat (name, args, NULL); cls_item = g_hash_table_lookup (cls_node->members, method_key); if (cls_item) /* We found an entry for this method */ { IAnjutaSymbolType sym_type = ianjuta_symbol_get_sym_type (symbol, NULL); if (!(sym_type & IANJUTA_SYMBOL_TYPE_PROTOTYPE)) { /* This one is method, so take this one instead */ g_free (cls_item->args); cls_item->args = g_strdup (args); if (cls_item->file) g_object_unref (cls_item->file); cls_item->file = NULL; /* Setup file and line */ cls_item->line = ianjuta_symbol_get_int (symbol, IANJUTA_SYMBOL_FIELD_FILE_POS, NULL); cls_item->file = ianjuta_symbol_get_file (symbol, NULL); } } else /* We did not find a member entry, create a new one */ { ClsNodeItem *cls_item = g_new0 (ClsNodeItem, 1); type_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_RETURNTYPE, NULL); cls_item->cls_node = cls_node; if (type_name) { if (strlen (args) > 2) cls_item->label = g_strconcat (name, "(...)", " : ", type_name, NULL); else cls_item->label = g_strconcat (name, "()", " : ", type_name, NULL); } else { if (strlen (args) > 2) cls_item->label = g_strconcat (name, "(...)", NULL); else cls_item->label = g_strconcat (name, "()", NULL); } cls_item->args = g_strdup (args); cls_item->type_name = g_strdup (type_name); cls_item->order = method_order++; if (icon) g_object_ref (icon); cls_item->icon = icon; g_string_append_printf (label, "|%s", cls_item->label); g_hash_table_insert (cls_node->members, method_key, cls_item); /* Setup file and line */ cls_item->line = ianjuta_symbol_get_int (symbol, IANJUTA_SYMBOL_FIELD_FILE_POS, NULL); cls_item->file = ianjuta_symbol_get_file (symbol, NULL); } } i++; } while (ianjuta_iterable_next (iter, NULL) && i < max_label_items); } if (iter) g_object_unref (iter); if (cls_node->expansion_status == CLS_NODE_SEMI_EXPANDED && real_items_length > NODE_HALF_DISPLAY_ELEM_NUM) { g_string_append_printf (label, "|%s", NODE_SHOW_ALL_MEMBERS_STR); } g_string_append_printf (label, "}"); agxset(cls_node->agnode, sym->index, label->str); /* set the margin for icons */ if (!(sym = agfindattr(cls_node->graph->proto->n, "margin"))) sym = agnodeattr(cls_node->graph, "margin", "0.11,0.055"); agxset(cls_node->agnode, sym->index, "0.3,0.03"); g_string_free (label, TRUE); return TRUE; }
static gint get_line_auto_indentation (IndentCPlugin *plugin, IAnjutaEditor *editor, gint line, gint *parenthesis_indentation) { IAnjutaIterable *iter; IAnjutaIterable *end_iter; gint line_indent = 0; gint incomplete_statement = -1; gboolean colon_indent = FALSE; g_return_val_if_fail (line > 0, 0); /* be sure to set a default if we're in the first line otherwise * the pointer'll be left hanging with no value. */ *parenthesis_indentation = 0; if (line == 1) /* First line */ { return 0; } else { IAnjutaIterable* begin = ianjuta_editor_get_line_begin_position (editor, line -1 , NULL); IAnjutaIterable* end = ianjuta_editor_get_line_end_position (editor, line -1 , NULL); if (spaces_only (editor, begin, end)) { set_line_indentation (plugin, editor, line -1, 0, 0); } g_object_unref (begin); g_object_unref (end); } iter = ianjuta_editor_get_line_begin_position (editor, line, NULL); if (is_iter_inside_string (iter)) { line_indent = get_line_indentation (editor, line - 1); } else { line_indent = get_line_indentation_base (plugin, editor, line, &incomplete_statement, parenthesis_indentation, &colon_indent); } if (colon_indent) { /* If the last non-whitespace character in the line is ":" then * we remove the extra colon_indent */ end_iter = ianjuta_editor_get_line_end_position (editor, line, NULL); gchar ch; while (ianjuta_iterable_previous (end_iter, NULL)) { ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (end_iter), 0, NULL); if (ch == ':') { line_indent -= INDENT_SIZE; break; } if (!isspace(ch) || iter_is_newline (end_iter, ch)) break; } g_object_unref (end_iter); } /* Determine what the first non-white char in the line is */ do { gchar ch; /* Check if we are *inside* comment or string. Begining of comment * or string does not count as inside. If inside, just align with * previous indentation. */ if (is_iter_inside_string (iter)) { line_indent = get_line_indentation (editor, line - 1); break; } ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter), 0, NULL); if (iter_is_newline (iter, ch)) { skip_iter_to_newline_tail (iter, ch); /* First levels are excused from incomplete statement indent */ if (incomplete_statement == 1 && line_indent > 0) line_indent += INDENT_SIZE; break; } if (ch == '{') { if (line_indent > 0) { /* The first level braces are excused from brace indentation */ /* DEBUG_PRINT ("Increasing indent level from %d to %d", line_indent, line_indent + BRACE_INDENT); */ line_indent += BRACE_INDENT; /* It looks ugly to add extra indent after case: so remove that */ if (colon_indent) line_indent -= INDENT_SIZE; } break; } else if (ch == '}') { ianjuta_iterable_previous (iter, NULL); if (anjuta_util_jump_to_matching_brace (iter, ch, -1)) { gint line = ianjuta_editor_get_line_from_position (editor, iter, NULL); line_indent = get_line_indentation (editor, line); } break; } else if (ch == '#') { line_indent = 0; *parenthesis_indentation = 0; } else if (!isspace (ch)) { /* First levels are excused from incomplete statement indent */ if (incomplete_statement == 1 && line_indent > 0) line_indent += INDENT_SIZE; break; } } while (ianjuta_iterable_next (iter, NULL)); g_object_unref (iter); return line_indent; }