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; }
static void toggle_comment_multiline (IAnjutaEditor *editor, IAnjutaIterable *start, IAnjutaIterable *end) { IAnjutaIterable *start_copy, *end_copy; gchar *text; gboolean is_commented; start_copy = ianjuta_iterable_clone (start, NULL); end_copy = ianjuta_iterable_clone (end, NULL); is_commented = is_commented_multiline (editor, start_copy, end_copy); text = ianjuta_editor_get_text (editor, start_copy, end_copy, NULL); if (is_commented) { ianjuta_editor_erase (editor, start_copy, end_copy, NULL); ianjuta_editor_insert (editor, start_copy, text + 2, (strlen (text) - 4), NULL); } else { ianjuta_editor_insert (editor, end, "*/", -1, NULL); ianjuta_editor_insert (editor, start, "/*", -1, NULL); } g_object_unref (start_copy); g_object_unref (end_copy); g_free (text); }
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 gchar * get_editor_line (IAnjutaEditor *editor, gint line) { IAnjutaIterable *start; IAnjutaIterable *end; gchar *content = NULL; if (line < 0) { gint last; end = ianjuta_editor_get_end_position(editor, NULL); last = ianjuta_editor_get_line_from_position (editor, end, NULL); line = last + line; g_object_unref (end); } if (line > 0) { start = ianjuta_editor_get_line_begin_position (editor, line, NULL); end = ianjuta_editor_get_line_end_position (editor, line, NULL); content = ianjuta_editor_get_text (editor, start, end, NULL); g_object_unref (start); g_object_unref (end); } return content; }
static gchar* get_text_between (IAnjutaEditor *editor, gchar *prefix, gchar *suffix) { IAnjutaEditorCell *search_start = IANJUTA_EDITOR_CELL ( ianjuta_editor_get_start_position (editor, NULL)); IAnjutaEditorCell *search_end = IANJUTA_EDITOR_CELL ( ianjuta_editor_get_end_position (editor, NULL)); IAnjutaEditorCell *result_start; IAnjutaEditorCell *result_end = NULL; IAnjutaEditorCell *prefix_end; IAnjutaEditorCell *suffix_start; ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor), prefix, FALSE, search_start, search_end, &result_start, &result_end, NULL); if (!result_end) return NULL; g_object_unref (result_start); prefix_end = result_end; ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor), suffix, FALSE, result_end, search_end, &result_start, &result_end, NULL); suffix_start = result_start; if (!result_end) return NULL; g_object_unref (result_end); return ianjuta_editor_get_text (editor, prefix_end, suffix_start, NULL); }
static gboolean spaces_only (IAnjutaEditor* editor, IAnjutaIterable* begin, IAnjutaIterable* end) { gboolean empty = TRUE; gchar* idx; gchar* text = ianjuta_editor_get_text (editor, begin, end, NULL); if (text == NULL) return TRUE; for (idx = text; *idx != '\0'; idx++) { if (!isspace(*idx)) { empty = FALSE; break; } } g_free(text); return empty; }
/** * 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; }
static void toggle_comment_singleline (CppJavaPlugin *plugin, IAnjutaEditor *editor, gint line) { IAnjutaIterable *begin, *end, *begin_copy, *end_copy; gchar *text, *text_stripped, **text_diff = NULL; begin = ianjuta_editor_get_line_begin_position (editor, line, NULL); end = ianjuta_editor_get_line_end_position (editor, line, NULL); begin_copy = ianjuta_iterable_clone (begin, NULL); end_copy = ianjuta_iterable_clone (end, NULL); if (is_commented_multiline (editor, begin_copy, end_copy)) { toggle_comment_multiline (editor, begin_copy, end_copy); g_object_unref (begin); g_object_unref (end); g_object_unref (begin_copy); g_object_unref (end_copy); return; } g_object_unref (begin_copy); g_object_unref (end_copy); text = ianjuta_editor_get_text (editor, begin, end, NULL); text_stripped = g_strstrip (g_strdup (text)); text_diff = g_strsplit (text, text_stripped, 2); if (plugin->current_language && (g_str_equal (plugin->current_language, "C"))) { if (g_str_has_prefix (text_stripped, "/*") && g_str_has_suffix (text_stripped, "*/")) { ianjuta_editor_erase (editor, begin, end, NULL); ianjuta_editor_insert (editor, begin, text_stripped + 2, (strlen (text_stripped) - 4), NULL); if (text_diff != NULL) ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL); } else { ianjuta_editor_insert (editor, end, "*/", -1, NULL); ianjuta_editor_insert (editor, begin, "/*", -1, NULL); } } else { if (g_str_has_prefix (text_stripped, "//")) { ianjuta_editor_erase (editor, begin, end, NULL); ianjuta_editor_insert (editor, begin, text_stripped + 2, -1, NULL); if (text_diff != NULL) ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL); } else { ianjuta_editor_insert (editor, begin, "//", -1, NULL); } } g_object_unref (begin); g_object_unref (end); g_free (text); g_free (text_stripped); g_strfreev (text_diff); }
/* Search string in editor, return TRUE and matching part as start and * end editor cell */ static gboolean editor_search (IAnjutaEditor *editor, const gchar *search_text, gboolean case_sensitive, gboolean search_forward, gboolean regex_mode, IAnjutaEditorCell* search_start, IAnjutaEditorCell* search_end, IAnjutaEditorCell** result_start, IAnjutaEditorCell** result_end) { gboolean found; if (regex_mode) { gint start_pos; gint end_pos; gchar *text_to_search; text_to_search = ianjuta_editor_get_text (editor, IANJUTA_ITERABLE (search_start), IANJUTA_ITERABLE (search_end), NULL); found = search_regex_in_text (search_text, text_to_search, search_forward, &start_pos, &end_pos); start_pos += ianjuta_iterable_get_position(IANJUTA_ITERABLE (search_start), NULL); end_pos += ianjuta_iterable_get_position(IANJUTA_ITERABLE (search_start), NULL); if (found && start_pos >= 0) { *result_start = IANJUTA_EDITOR_CELL (ianjuta_editor_get_start_position (editor, NULL)); *result_end = IANJUTA_EDITOR_CELL (ianjuta_editor_get_start_position (editor, NULL)); if (!ianjuta_iterable_set_position(IANJUTA_ITERABLE(*result_start), start_pos, NULL) || !ianjuta_iterable_set_position(IANJUTA_ITERABLE(*result_end), end_pos, NULL)) { g_object_unref(*result_start); g_object_unref(*result_end); found = FALSE; } } g_free(text_to_search); } else { if (search_forward) { found = ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor), search_text, case_sensitive, search_start, search_end, result_start, result_end, NULL); } else { found = ianjuta_editor_search_backward (IANJUTA_EDITOR_SEARCH (editor), search_text, case_sensitive, search_end, search_start, result_start, result_end, NULL); } } return found; }
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; }
static gint get_line_indentation (IAnjutaEditor *editor, gint line_num) { IAnjutaIterable *line_begin, *line_end; gchar *line_string, *idx; gint line_indent = 0, left_braces = 0, right_braces = 0; gchar ch; line_end = ianjuta_editor_get_line_end_position (editor, line_num, NULL); /* Find first right brace going backwards from end of current line that is before a closing bracket */ while (ianjuta_iterable_previous (line_end, NULL)) { ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_end), 0, NULL); if (ch == ')') { right_braces++; break; } else if (ch =='}') break; } /* Find the line which contains the left brace matching the right brace we found */ if (right_braces > 0) { while (ianjuta_iterable_previous (line_end, NULL) && right_braces > left_braces) { ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (line_end), 0, NULL); if (ch == ')') right_braces++; else if (ch == '(') left_braces++; } line_num = ianjuta_editor_get_line_from_position (editor, line_end, NULL); } g_object_unref (line_end); 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 ("%s: line begin = %d, line end = %d", __FUNCTION__, line_begin, line_end); */ if (ianjuta_iterable_compare (line_begin, line_end, NULL) == 0) { g_object_unref (line_begin); g_object_unref (line_end); return 0; } line_string = ianjuta_editor_get_text (editor, line_begin, line_end, NULL); g_object_unref (line_begin); g_object_unref (line_end); /* DEBUG_PRINT ("line_string = '%s'", line_string); */ if (!line_string) return 0; idx = line_string; /* Find first non-white space */ while (*idx != '\0' && isspace (*idx)) { if (*idx == '\t') line_indent += TAB_SIZE; else line_indent++; idx++; /* Since we are looking for first non-space char, simple * increment of the utf8 chars would do */ } g_free (line_string); return line_indent; }
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); }