static void forward_chars_with_skipping (GtkTextIter *iter, gint count, gboolean skip_invisible, gboolean skip_nontext, gboolean skip_decomp) { gint i; g_return_if_fail (count >= 0); i = count; while (i > 0) { gboolean ignored = FALSE; if (skip_nontext && gtk_text_iter_get_char (iter) == GTK_TEXT_UNKNOWN_CHAR) ignored = TRUE; if (!ignored && skip_invisible && /* _gtk_text_btree_char_is_invisible (iter)*/ FALSE) ignored = TRUE; if (!ignored && skip_decomp) { /* being UTF8 correct sucks; this accounts for extra offsets coming from canonical decompositions of UTF8 characters (e.g. accented characters) which g_utf8_normalize() performs */ gunichar *decomp; gsize decomp_len; decomp = g_unicode_canonical_decomposition ( gtk_text_iter_get_char (iter), &decomp_len); i -= (decomp_len - 1); g_free (decomp); } gtk_text_iter_forward_char (iter); if (!ignored) --i; } }
//========================================================================== char GUI_edi_RdChr (MemObj *mo, int offset) { //========================================================================== /// \code /// read char near cursor; /// offset 0 = char right of cursor /// offset -1 = char left of cursor /// returns '\0' for out-of-file-positions. /// returns -1 for a multibyte-character /// \endcode GtkTextMark *mk1; GtkTextIter it1; gboolean b1; long uc; // char c1; // printf("GUI_edi_RdChr |%c| %d\n",c1,cpos); // set GUI_ed1_view GUI_ed1_buff if(mo) { // for internal call: mo=NULL if(GUI_ed1_decode(mo)) return -1; } // get mark at CurPos mk1 = gtk_text_buffer_get_mark (GUI_ed1_buff, "insert"); // iter at CurPos gtk_text_buffer_get_iter_at_mark (GUI_ed1_buff, &it1, mk1); // move iter back if(offset < 0) { b1 = gtk_text_iter_backward_chars (&it1, -offset); // false if left of 1. char; returns Null !. if(b1 == FALSE) return '\0'; } // move iter forw if(offset > 0) { b1 = gtk_text_iter_forward_chars (&it1, offset); // false if left of 1. char; returns Null !. if(b1 == FALSE) return '\0'; } // get unicode-char at curpos uc = gtk_text_iter_get_char (&it1); if((uc > 127)||(uc < 0)) return -1; // printf("ex GUI_edi_RdChr |%ld|\n",uc); return uc; }
static gunichar text_iter_peek_prev_char (const GtkTextIter *location) { GtkTextIter iter = *location; if (gtk_text_iter_backward_char (&iter)) return gtk_text_iter_get_char (&iter); return 0; }
static gboolean gtkspell_text_iter_backward_word_start(GtkTextIter *i) { GtkTextIter iter; if (!gtk_text_iter_backward_word_start(i)) return FALSE; iter = *i; if (gtk_text_iter_backward_char(&iter)) { if (gtk_text_iter_get_char(&iter) == '\'') { if (gtk_text_iter_backward_char(&iter)) { if (g_unichar_isalpha(gtk_text_iter_get_char(&iter))) { return (gtk_text_iter_backward_word_start(i)); } } } } return TRUE; }
static gchar *compute_indentation(GtkTextBuffer *buffer, GtkTextIter *iter, gint line) { GtkTextIter start_iter, end_iter; gunichar ch; gtk_text_buffer_get_iter_at_line(buffer, &start_iter, line); end_iter = start_iter; ch = gtk_text_iter_get_char(&end_iter); while (g_unichar_isspace(ch) && ch != '\n') { if (!gtk_text_iter_forward_char(&end_iter)) break; ch = gtk_text_iter_get_char(&end_iter); } if (gtk_text_iter_equal(&start_iter, &end_iter)) return NULL; if (iter && gtk_text_iter_compare(iter, &end_iter) < 0) return gtk_text_iter_get_text(&start_iter, iter); return gtk_text_iter_get_text(&start_iter, &end_iter); }
/* Symmetric of iter_forward_full_word_end(). */ void _gtk_source_iter_backward_full_word_start (GtkTextIter *iter) { GtkTextIter pos; GtkTextIter prev; gboolean non_blank_found = FALSE; pos = *iter; while (!gtk_text_iter_is_start (&pos)) { prev = pos; gtk_text_iter_backward_visible_cursor_position (&prev); if (!g_unichar_isspace (gtk_text_iter_get_char (&prev))) { break; } pos = prev; } while (!gtk_text_iter_is_start (&pos)) { prev = pos; gtk_text_iter_backward_visible_cursor_position (&prev); if (g_unichar_isspace (gtk_text_iter_get_char (&prev))) { break; } non_blank_found = TRUE; pos = prev; } if (non_blank_found) { *iter = pos; } }
static inline gboolean is__text_iter_apostrophe_or_dash (const GtkTextIter *iter) { gunichar ch; ch = gtk_text_iter_get_char (iter); return (ch == '-' || ch == '\'' || ch == GSPELL_MODIFIER_LETTER_APOSTROPHE || ch == GSPELL_RIGHT_SINGLE_QUOTATION_MARK); }
gboolean mousepad_util_iter_forward_text_start (GtkTextIter *iter) { g_return_val_if_fail (!mousepad_util_iter_inside_word (iter), FALSE); /* keep until we hit text or a line end */ while (g_unichar_isspace (gtk_text_iter_get_char (iter))) if (gtk_text_iter_ends_line (iter) || !gtk_text_iter_forward_char (iter)) break; return TRUE; }
gchar *ide_xml_get_element_name (const GtkTextIter *start, const GtkTextIter *end) { GtkTextIter curr; GtkTextIter begin = *start; g_return_val_if_fail (ide_xml_in_element (start) && gtk_text_iter_get_char (start) == '<', NULL); g_return_val_if_fail (ide_xml_in_element (start) && gtk_text_iter_get_char (end) == '>', NULL); g_return_val_if_fail (gtk_text_iter_compare (start, end) < 0, FALSE); /* * We need to move pass by the start '<' and closing '/' char of the element */ while (gtk_text_iter_get_char (&begin) == '<' || gtk_text_iter_get_char (&begin) == '/') gtk_text_iter_forward_char (&begin); /* Comments and elements starting with ? do not have a name */ if (gtk_text_iter_get_char (&begin) == '!' || gtk_text_iter_get_char (&begin) == '?') return NULL; curr = begin; /* * Find the end of the element name by iterating over it until we find * a '/' or '>' or ' ' char */ if (gtk_text_iter_forward_find_char (&curr, find_end_element_char, NULL, end) && gtk_text_iter_compare (&begin,&curr) < 0) return gtk_text_iter_get_slice (&begin, &curr); return NULL; }
static void smartquotes_delete_cb(GtkTextBuffer *buffer, GtkTextIter *i1, GtkTextIter *i2) { gunichar c; GtkTextIter i = *i1; while (gtk_text_iter_in_range(&i, i1, i2)) { c = gtk_text_iter_get_char(&i); if (count_quotes(c)) { smartquotes_begin(buffer); break; } gtk_text_iter_forward_char(&i); } }
/* Format->Uncomment Selection */ void action_uncomment_selection(GtkAction *action, I7Document *document) { GtkTextBuffer *buffer = GTK_TEXT_BUFFER(i7_document_get_buffer(document)); GtkTextIter start, end; if(!gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) return; /* Find first [ from the beginning of the selection, then the last ] between there and the end of the selection */ if(gtk_text_iter_get_char(&start) != '[' && !gtk_text_iter_forward_find_char(&start, char_equals, GUINT_TO_POINTER('['), &end)) return; gtk_text_iter_backward_char(&end); if(gtk_text_iter_get_char(&end) != ']' && !gtk_text_iter_backward_find_char(&end, char_equals, GUINT_TO_POINTER(']'), &start)) return; gtk_text_iter_forward_char(&end); gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE); /* Treat it as one single undo action */ gtk_text_buffer_begin_user_action(buffer); /* Delete the comment and re-insert it without brackets */ gtk_text_buffer_delete(buffer, &start, &end); gchar *newtext = g_strndup(text + 1, strlen(text) - 2); GtkTextMark *tempmark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE); gtk_text_buffer_insert(buffer, &end, newtext, -1); gtk_text_buffer_end_user_action(buffer); g_free(text); g_free(newtext); /* Select only the uncommented text again */ gtk_text_buffer_get_iter_at_mark(buffer, &start, tempmark); gtk_text_buffer_select_range(buffer, &start, &end); gtk_text_buffer_delete_mark(buffer, tempmark); }
static gchar * get_word_at_iter (GscProviderDevhelp *devhelp, GtkTextIter *iter) { GtkTextIter start = *iter; gint line = gtk_text_iter_get_line (iter); gboolean went_back = TRUE; GtkTextMark *mark; if (!gtk_text_iter_backward_char (&start)) { return NULL; } while (went_back && line == gtk_text_iter_get_line (&start) && is_word_char (gtk_text_iter_get_char (&start))) { went_back = gtk_text_iter_backward_char (&start); } if (went_back) { gtk_text_iter_forward_char (&start); } if (gtk_text_iter_equal (iter, &start)) { return NULL; } mark = gtk_text_buffer_get_mark (gtk_text_iter_get_buffer (iter), MARK_NAME); if (mark) { gtk_text_buffer_move_mark (gtk_text_iter_get_buffer (iter), mark, &start); } else { mark = gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (iter), MARK_NAME, &start, TRUE); } return gtk_text_iter_get_text (&start, iter); }
static gboolean mousepad_util_iter_word_characters (const GtkTextIter *iter) { gunichar c; /* get the characters */ c = gtk_text_iter_get_char (iter); /* character we'd like to see in a word */ if (g_unichar_isalnum (c) || c == '_') return TRUE; return FALSE; }
static void ide_source_view_movements_paragraph_start (Movement *mv) { _ide_vim_iter_backward_paragraph_start (&mv->insert); if (mv->exclusive) { while (g_unichar_isspace (gtk_text_iter_get_char (&mv->insert))) { if (!gtk_text_iter_forward_char (&mv->insert)) break; } } }
//後方向の空白をまとめて消去する int delete_hungry_forward(void) { gunichar c; GtkTextIter start, end; gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buffer), &start, gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer))); end = start; c = gtk_text_iter_get_char(&end); if (c != ' ' && c != '\t') return 0; while (1) { if (!gtk_text_iter_forward_char(&end)) break; c = gtk_text_iter_get_char(&end); if (c != ' ' && c != '\t') break; } gtk_text_buffer_delete(GTK_TEXT_BUFFER(buffer), &start, &end); return 1; }
static gchar * ide_xml_indenter_indent (IdeXmlIndenter *xml, GtkTextIter *begin, GtkTextIter *end, gint *cursor_offset) { GtkTextIter match_begin; GString *str; guint offset; g_return_val_if_fail (IDE_IS_XML_INDENTER (xml), NULL); g_return_val_if_fail (begin, NULL); g_return_val_if_fail (end, NULL); str = g_string_new (NULL); if (text_iter_backward_to_element_start (begin, &match_begin)) { offset = gtk_text_iter_get_line_offset (&match_begin); build_indent (xml, offset + xml->indent_width, &match_begin, str); /* * If immediately after our cursor is a closing tag, we will move it to * a line after our indent line. */ if ('<' == gtk_text_iter_get_char (end) && '/' == text_iter_peek_next_char (end)) { GString *str2; str2 = g_string_new (NULL); build_indent (xml, offset, &match_begin, str2); g_string_append (str, "\n"); g_string_append (str, str2->str); *cursor_offset = -str2->len - 1; g_string_free (str2, TRUE); } IDE_GOTO (cleanup); } /* do nothing */ cleanup: return g_string_free (str, (str->len == 0)); }
gboolean gtk_source_completion_words_utils_backward_word_start (GtkTextIter *iter, CharacterCheck valid, CharacterCheck valid_start, gpointer data) { GtkTextIter prev = *iter; /* Go backward as long as there are word characters */ while (TRUE) { /* Starting a line is good */ if (gtk_text_iter_starts_line (&prev)) { break; } gtk_text_iter_backward_char (&prev); /* Check if the previous character is a valid word character */ if (!valid (gtk_text_iter_get_char (&prev), data)) { break; } *iter = prev; } if (!valid (gtk_text_iter_get_char (iter), data)) { return FALSE; } /* Go forward with while !valid_start */ return valid_start (gtk_text_iter_get_char (iter), data); }
/*###############indentation management############*/ static gchar * _compute_line_indentation (GtkTextView *view, GtkTextIter *cur) { GtkTextIter start; GtkTextIter end; gunichar ch; gint line; line = gtk_text_iter_get_line (cur); gtk_text_buffer_get_iter_at_line (gtk_text_view_get_buffer (view), &start, line); end = start; ch = gtk_text_iter_get_char (&end); while (g_unichar_isspace (ch) && (ch != '\n') && (ch != '\r') && (gtk_text_iter_compare (&end, cur) < 0)) { if (!gtk_text_iter_forward_char (&end)) break; ch = gtk_text_iter_get_char (&end); } if (gtk_text_iter_equal (&start, &end)) return NULL; return gtk_text_iter_get_slice (&start, &end); }
gboolean _gtk_source_iter_starts_extra_natural_word (const GtkTextIter *iter, gboolean visible) { gboolean starts_word; GtkTextIter prev; starts_word = gtk_text_iter_starts_word (iter); prev = *iter; if (!backward_cursor_position (&prev, visible)) { return starts_word || gtk_text_iter_get_char (iter) == '_'; } if (starts_word) { return gtk_text_iter_get_char (&prev) != '_'; } return (gtk_text_iter_get_char (iter) == '_' && gtk_text_iter_get_char (&prev) != '_' && !gtk_text_iter_ends_word (iter)); }
static gboolean gtkspell_text_iter_forward_word_end(GtkTextIter *i) { GtkTextIter iter; /* heuristic: * if we're on an singlequote/apostrophe and * if the next letter is alphanumeric, * this is an apostrophe. */ if (!gtk_text_iter_forward_word_end(i)) return FALSE; if (gtk_text_iter_get_char(i) != '\'') return TRUE; iter = *i; if (gtk_text_iter_forward_char(&iter)) { if (g_unichar_isalpha(gtk_text_iter_get_char(&iter))) { return (gtk_text_iter_forward_word_end(i)); } } return TRUE; }
/* Symmetric of iter_forward_extra_natural_word_end(). */ void _gtk_source_iter_backward_extra_natural_word_start (GtkTextIter *iter) { GtkTextIter prev_word_start = *iter; GtkTextIter prev_underscore_start = *iter; GtkTextIter *limit = NULL; gboolean found; if (gtk_text_iter_backward_visible_word_start (&prev_word_start)) { limit = &prev_word_start; } found = gtk_text_iter_backward_search (iter, "_", GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, &prev_underscore_start, NULL, limit); if (found) { *iter = prev_underscore_start; } else { *iter = prev_word_start; } while (!gtk_text_iter_is_start (iter)) { GtkTextIter prev = *iter; gtk_text_iter_backward_visible_cursor_position (&prev); if (gtk_text_iter_get_char (&prev) == '_') { *iter = prev; } else if (gtk_text_iter_ends_word (iter)) { gtk_text_iter_backward_visible_word_start (iter); } else { break; } } }
static gboolean smie_gtk_source_buffer_forward_comment (gpointer data) { smie_gtk_source_buffer_context_t *context = data; GtkTextIter start_iter; gtk_text_iter_assign (&start_iter, &context->iter); while (!gtk_text_iter_is_end (&context->iter) && (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || g_unichar_isspace (gtk_text_iter_get_char (&context->iter))) && gtk_text_iter_forward_char (&context->iter)) ; return !gtk_text_iter_equal (&context->iter, &start_iter); }
static gboolean find_whitepace_region (const GtkTextIter *center, GtkTextIter *start, GtkTextIter *end) { *start = *center; *end = *center; if (gtk_text_iter_backward_find_char (start, is_not_whitespace, NULL, NULL)) gtk_text_iter_forward_char (start); /* we want the first whitespace... */ if (is_whitespace (gtk_text_iter_get_char (end), NULL)) gtk_text_iter_forward_find_char (end, is_not_whitespace, NULL, NULL); return ! gtk_text_iter_equal (start, end); }
static void ide_source_view_movements_first_nonspace_char (Movement *mv) { gunichar ch; if (gtk_text_iter_get_line_offset (&mv->insert) != 0) gtk_text_iter_set_line_offset (&mv->insert, 0); while (!gtk_text_iter_ends_line (&mv->insert) && (ch = gtk_text_iter_get_char (&mv->insert)) && g_unichar_isspace (ch)) gtk_text_iter_forward_char (&mv->insert); if (!mv->exclusive && !gtk_text_iter_ends_line (&mv->insert)) gtk_text_iter_forward_char (&mv->insert); }
gboolean mousepad_util_iter_backward_text_start (GtkTextIter *iter) { GtkTextIter prev = *iter; g_return_val_if_fail (!mousepad_util_iter_inside_word (iter), FALSE); while (!gtk_text_iter_starts_line (&prev) && gtk_text_iter_backward_char (&prev)) { if (g_unichar_isspace (gtk_text_iter_get_char (&prev))) *iter = prev; else break; } return TRUE; }
/* Extends the definition of a natural-language word used by Pango. The * underscore is added to the possible characters of a natural-language word. */ void _gtk_source_iter_forward_extra_natural_word_end (GtkTextIter *iter) { GtkTextIter next_word_end = *iter; GtkTextIter next_underscore_end = *iter; GtkTextIter *limit = NULL; gboolean found; if (gtk_text_iter_forward_visible_word_end (&next_word_end)) { limit = &next_word_end; } found = gtk_text_iter_forward_search (iter, "_", GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &next_underscore_end, limit); if (found) { *iter = next_underscore_end; } else { *iter = next_word_end; } while (TRUE) { if (gtk_text_iter_get_char (iter) == '_') { gtk_text_iter_forward_visible_cursor_position (iter); } else if (gtk_text_iter_starts_word (iter)) { gtk_text_iter_forward_visible_word_end (iter); } else { break; } } }
static gchar * ide_indenter_mimic_source_view (GtkTextView *text_view, GtkTextIter *begin, GtkTextIter *end, gint *cursor_offset, GdkEventKey *event) { GtkTextIter copy_begin; GtkTextIter copy_end; gchar *ret; IDE_ENTRY; g_assert (GTK_IS_TEXT_VIEW (text_view)); g_assert (begin != NULL); g_assert (end != NULL); g_assert (cursor_offset != NULL); g_assert (event != NULL); *cursor_offset = 0; *begin = *end; if (event->keyval != GDK_KEY_Return && event->keyval != GDK_KEY_KP_Enter) IDE_RETURN (NULL); copy_begin = *end; /* We might already be at the beginning of the file */ if (!gtk_text_iter_backward_char (©_begin)) IDE_RETURN (NULL); gtk_text_iter_set_line_offset (©_begin, 0); copy_end = copy_begin; while (g_unichar_isspace (gtk_text_iter_get_char (©_end))) { if (gtk_text_iter_ends_line (©_end) || !gtk_text_iter_forward_char (©_end)) break; } ret = gtk_text_iter_get_slice (©_begin, ©_end); IDE_RETURN (ret); }
static gint get_buffer_range_indent (GtkTextBuffer *buffer, gint line, gboolean to_spaces) { GtkTextIter iter; gint indent = 0; gtk_text_buffer_get_iter_at_line (buffer, &iter, line); while (!gtk_text_iter_ends_line (&iter) && g_unichar_isspace(gtk_text_iter_get_char (&iter))) { gtk_text_iter_forward_char (&iter); ++indent; } return indent; }
static void ide_source_view_movements_nth_line (Movement *mv) { GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (mv->self)); if (mv->count < 1) gtk_text_buffer_get_end_iter (buffer, &mv->insert); else gtk_text_iter_set_line (&mv->insert, mv->count - 1); gtk_text_iter_set_line_offset (&mv->insert, 0); while (!gtk_text_iter_ends_line (&mv->insert) && g_unichar_isspace (gtk_text_iter_get_char (&mv->insert))) if (!gtk_text_iter_forward_char (&mv->insert)) break; }
static void ide_source_view_movements_previous_full_word_start (Movement *mv) { GtkTextIter copy; copy = mv->insert; _ide_source_iter_backward_full_word_start (&mv->insert); /* * Vim treats an empty line as a word. */ if (gtk_text_iter_backward_char (©)) if (gtk_text_iter_get_char (©) == '\n') mv->insert = copy; if (!mv->exclusive && !gtk_text_iter_ends_line (&mv->insert)) gtk_text_iter_forward_char (&mv->insert); }