/* Remove Whitespace Lines */ gint rmwhspln(ScintillaObject *sci, gint line_num, gint end_line_num) { gint indent; /* indent position */ gint changed = 0; /* number of lines removed */ while(line_num <= end_line_num) /* loop through lines */ { indent = scintilla_send_message(sci, SCI_GETLINEINDENTPOSITION, line_num, 0); /* check if the posn of indentation is also the end of line posn */ if(indent - sci_get_position_from_line(sci, line_num) == sci_get_line_end_position (sci, line_num) - sci_get_position_from_line(sci, line_num)) { scintilla_send_message(sci, SCI_DELETERANGE, sci_get_position_from_line(sci, line_num), sci_get_line_length(sci, line_num)); line_num--; end_line_num--; changed++; } line_num++; } /* return the number of lines deleted */ return -changed; }
/* Remove Empty Lines */ gint rmemtyln(ScintillaObject *sci, gint line_num, gint end_line_num) { gint changed = 0; /* number of lines removed */ while(line_num <= end_line_num) /* loop through lines */ { /* check if the first posn of the line is also the end of line posn */ if(sci_get_position_from_line(sci, line_num) == sci_get_line_end_position (sci, line_num)) { scintilla_send_message(sci, SCI_DELETERANGE, sci_get_position_from_line(sci, line_num), sci_get_line_length(sci, line_num)); line_num--; end_line_num--; changed++; } line_num++; } /* return the number of lines deleted */ return -changed; }
gint sc_speller_process_line(GeanyDocument *doc, gint line_number) { gint pos_start, pos_end; gint wstart, wend; gint suggestions_found = 0; gint wordchars_len; gchar *wordchars; g_return_val_if_fail(sc_speller_dict != NULL, 0); g_return_val_if_fail(doc != NULL, 0); /* add ' (single quote) temporarily to wordchars * to be able to check for "doesn't", "isn't" and similar */ wordchars_len = scintilla_send_message(doc->editor->sci, SCI_GETWORDCHARS, 0, 0); wordchars = g_malloc0(wordchars_len + 2); /* 2 = temporarily added "'" and "\0" */ scintilla_send_message(doc->editor->sci, SCI_GETWORDCHARS, 0, (sptr_t)wordchars); if (! strchr(wordchars, '\'')) { /* temporarily add "'" to the wordchars */ wordchars[wordchars_len] = '\''; scintilla_send_message(doc->editor->sci, SCI_SETWORDCHARS, 0, (sptr_t)wordchars); } pos_start = sci_get_position_from_line(doc->editor->sci, line_number); pos_end = sci_get_position_from_line(doc->editor->sci, line_number + 1); while (pos_start < pos_end) { gchar *word; wstart = scintilla_send_message(doc->editor->sci, SCI_WORDSTARTPOSITION, pos_start, TRUE); wend = scintilla_send_message(doc->editor->sci, SCI_WORDENDPOSITION, wstart, FALSE); if (wstart == wend) break; word = sci_get_contents_range(doc->editor->sci, wstart, wend); suggestions_found += sc_speller_check_word(doc, line_number, word, wstart, wend); pos_start = wend + 1; g_free(word); } /* reset wordchars for the current document */ wordchars[wordchars_len] = '\0'; scintilla_send_message(doc->editor->sci, SCI_SETWORDCHARS, 0, (sptr_t)wordchars); g_free(wordchars); return suggestions_found; }
static void reindent (GeanyDocument *doc, GrindIndenter *indenter) { if (DOC_VALID (doc)) { int start; int end; ScintillaObject *sci = doc->editor->sci; if (sci_has_selection (sci)) { start = sci_get_line_from_position (sci, sci_get_selection_start (sci)); end = sci_get_line_from_position (sci, sci_get_selection_end (sci)); } else { start = 0; end = sci_get_line_count (sci); } if (start != end) { g_debug ("Using indenter \"%s\" by \"%s\"", grind_indenter_get_name (indenter), grind_indenter_get_author (indenter)); sci_start_undo_action (sci); if (grind_indenter_indent (indenter, doc, sci_get_position_from_line (sci, start), sci_get_line_end_position (sci, end))) { msgwin_status_add ("Reindented \"%s\"", DOC_FILENAME (doc)); } sci_end_undo_action (sci); } } }
static void delete_line(ScintillaObject *sci, gint line) { gint start = sci_get_position_from_line(sci, line); gint len = sci_get_line_length(sci, line); SSM(sci, SCI_DELETERANGE, start, len); }
static void on_comments_function_activate(GtkMenuItem *menuitem, gpointer user_data) { GeanyDocument *doc = document_get_current(); gchar *text; const gchar *cur_tag = NULL; gint line = -1, pos = 0; if (doc == NULL || doc->file_type == NULL) { ui_set_statusbar(FALSE, _("Please set the filetype for the current file before using this function.")); return; } /* symbols_get_current_function returns -1 on failure, so sci_get_position_from_line * returns the current position, so it should be safe */ line = symbols_get_current_function(doc, &cur_tag); pos = sci_get_position_from_line(doc->editor->sci, line); text = templates_get_template_function(doc, cur_tag); sci_start_undo_action(doc->editor->sci); sci_insert_text(doc->editor->sci, pos, text); sci_end_undo_action(doc->editor->sci); g_free(text); }
/** * Adds old file position and new file position to the navqueue, then goes to the new position. * * @param old_doc The document of the previous position, if set as invalid (@c NULL) then no old * position is set * @param new_doc The document of the new position, must be valid. * @param line the line number of the new position. It is counted with 1 as the first line, not 0. * * @return @c TRUE if the cursor has changed the position to @a line or @c FALSE otherwise. **/ gboolean navqueue_goto_line(GeanyDocument *old_doc, GeanyDocument *new_doc, gint line) { gint pos; g_return_val_if_fail(new_doc != NULL, FALSE); g_return_val_if_fail(line >= 1, FALSE); pos = sci_get_position_from_line(new_doc->editor->sci, line - 1); /* first add old file position */ if (old_doc != NULL && old_doc->file_name) { gint cur_pos = sci_get_current_position(old_doc->editor->sci); add_new_position(old_doc->file_name, cur_pos); } /* now add new file position */ if (new_doc->file_name) { add_new_position(new_doc->file_name, pos); } return editor_goto_pos(new_doc->editor, pos, TRUE); }
static void goto_file_line_cb(const gchar * filename, const gchar * line, const gchar * reason) { gint pos; gint page; GeanyDocument *doc; gint line_num = gdbio_atoi((gchar *) line) - 1; if (reason) { msgwin_compiler_add(COLOR_BLUE, "%s", reason); } doc = document_open_file(filename, FALSE, NULL, NULL); if (!(doc && doc->is_valid)) { return; } page = gtk_notebook_page_num(NOTEBOOK, GTK_WIDGET(doc->editor->sci)); gtk_notebook_set_current_page(NOTEBOOK, page); pos = sci_get_position_from_line(doc->editor->sci, line_num); sci_ensure_line_is_visible(doc->editor->sci, line_num); while (gtk_events_pending()) { gtk_main_iteration(); } sci_set_current_position(doc->editor->sci, pos, TRUE); gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); gtk_window_present(GTK_WINDOW(geany->main_widgets->window)); }
gint sc_speller_process_line(GeanyDocument *doc, gint line_number, const gchar *line) { gint pos_start, pos_end; gint wstart, wend; GString *str; gint suggestions_found = 0; gchar c; g_return_val_if_fail(sc_speller_dict != NULL, 0); g_return_val_if_fail(doc != NULL, 0); g_return_val_if_fail(line != NULL, 0); str = g_string_sized_new(256); pos_start = sci_get_position_from_line(doc->editor->sci, line_number); pos_end = sci_get_position_from_line(doc->editor->sci, line_number + 1); while (pos_start < pos_end) { wstart = scintilla_send_message(doc->editor->sci, SCI_WORDSTARTPOSITION, pos_start, TRUE); wend = scintilla_send_message(doc->editor->sci, SCI_WORDENDPOSITION, wstart, FALSE); if (wstart == wend) break; c = sci_get_char_at(doc->editor->sci, wstart); /* hopefully it's enough to check for these both */ if (ispunct(c) || isspace(c)) { pos_start++; continue; } /* ensure the string has enough allocated memory */ if (str->len < (guint)(wend - wstart)) g_string_set_size(str, wend - wstart); sci_get_text_range(doc->editor->sci, wstart, wend, str->str); suggestions_found += sc_speller_check_word(doc, line_number, str->str, wstart, wend); pos_start = wend + 1; } g_string_free(str, TRUE); return suggestions_found; }
static void indicator_clear_on_line(GeanyDocument *doc, gint line_number) { gint start_pos, length; g_return_if_fail(doc != NULL); start_pos = sci_get_position_from_line(doc->editor->sci, line_number); length = sci_get_line_length(doc->editor->sci, line_number); sci_indicator_set(doc->editor->sci, GEANY_INDICATOR_ERROR); sci_indicator_clear(doc->editor->sci, start_pos, length); }
static void findMatchingOpeningTag(ScintillaObject *sci, gchar *tagName, gint openingBracket) { gint pos; gint openingTagsCount = 0; gint closingTagsCount = 1; for(pos=openingBracket; pos>0; pos--) { /* are we inside tag? */ gint lineNumber = sci_get_line_from_position(sci, pos); gint lineStart = sci_get_position_from_line(sci, lineNumber); gint matchingOpeningBracket = findBracket(sci, pos, lineStart, '<', '\0', FALSE); gint matchingClosingBracket = findBracket(sci, pos, lineStart, '>', '\0', FALSE); if(-1 != matchingOpeningBracket && -1 != matchingClosingBracket && (matchingClosingBracket > matchingOpeningBracket)) { /* we are inside of some tag. Let us check what tag*/ gboolean isMatchingTagOpening = is_tag_opening(sci, matchingOpeningBracket); gchar *matchingTagName = get_tag_name(sci, matchingOpeningBracket, matchingClosingBracket, isMatchingTagOpening); if(matchingTagName && strcmp(tagName, matchingTagName) == 0) { if(TRUE == isMatchingTagOpening) openingTagsCount++; else closingTagsCount++; } pos = matchingOpeningBracket+1; g_free(matchingTagName); } /* Speed up search: if findBracket returns -1, that means start of line * is reached. There is no need to go through the same positions again. * Jump to the start of line */ else if(-1 == matchingOpeningBracket || -1 == matchingClosingBracket) { pos = lineStart; continue; } if(openingTagsCount == closingTagsCount) { /* matching tag is found */ highlightedBrackets[2] = matchingOpeningBracket; highlightedBrackets[3] = matchingClosingBracket; highlight_matching_pair(sci); return; } } highlight_tag(sci, highlightedBrackets[0], highlightedBrackets[1], NONMATCHING_PAIR_COLOR); }
static void findMatchingClosingTag(ScintillaObject *sci, gchar *tagName, gint closingBracket) { gint pos; gint linesInDocument = sci_get_line_count(sci); gint endOfDocument = sci_get_position_from_line(sci, linesInDocument); gint openingTagsCount = 1; gint closingTagsCount = 0; for(pos=closingBracket; pos<endOfDocument; pos++) { /* are we inside tag? */ gint lineNumber = sci_get_line_from_position(sci, pos); gint lineEnd = sci_get_line_end_position(sci, lineNumber); gint matchingOpeningBracket = findBracket(sci, pos, lineEnd, '<', '\0', TRUE); gint matchingClosingBracket = findBracket(sci, pos, lineEnd, '>', '\0', TRUE); if(-1 != matchingOpeningBracket && -1 != matchingClosingBracket && (matchingClosingBracket > matchingOpeningBracket)) { /* we are inside of some tag. Let us check what tag*/ gboolean isMatchingTagOpening = is_tag_opening(sci, matchingOpeningBracket); gchar *matchingTagName = get_tag_name(sci, matchingOpeningBracket, matchingClosingBracket, isMatchingTagOpening); if(matchingTagName && strcmp(tagName, matchingTagName) == 0) { if(TRUE == isMatchingTagOpening) openingTagsCount++; else closingTagsCount++; } pos = matchingClosingBracket; g_free(matchingTagName); } if(openingTagsCount == closingTagsCount) { /* matching tag is found */ highlightedBrackets[2] = matchingOpeningBracket; highlightedBrackets[3] = matchingClosingBracket; highlight_matching_pair(sci); return; } } highlight_tag(sci, highlightedBrackets[0], highlightedBrackets[1], NONMATCHING_PAIR_COLOR); }
static PyObject * ZenEditor_get_current_line_range(ZenEditor *self, PyObject *args) { PyObject *result; gint line, line_start, line_end; ScintillaObject *sci; print_called(); py_return_none_if_null(sci = ZenEditor_get_scintilla(self)); line = sci_get_current_line(sci); line_start = sci_get_position_from_line(sci, line); line_end = sci_get_line_end_position(sci, line); result = Py_BuildValue("ii", line_start, line_end); return result; }
static PyObject * Scintilla_get_position_from_line(Scintilla *self, PyObject *args, PyObject *kwargs) { gint line = -1, pos; static gchar *kwlist[] = { "line", NULL }; SCI_RET_IF_FAIL(self); if (PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &line)) { if (line == -1) line = sci_get_current_line(self->sci); pos = sci_get_position_from_line(self->sci, line); return Py_BuildValue("i", pos); } Py_RETURN_NONE; }
static void send_complete(GeanyEditor* editor, int flag) { if (completion_framework == NULL) { return; } if (!is_completion_file_now()) { return; } int pos = get_completion_position(); if (pos == 0) { return; } // nothing to complete int line = sci_get_line_from_position(editor->sci, pos); int ls_pos = sci_get_position_from_line(editor->sci, line); int byte_line_len = pos - ls_pos; if (byte_line_len < 0) { return; } char* content = sci_get_contents(editor->sci, sci_get_length(editor->sci) + 1 + 1); content[sci_get_length(editor->sci)] = ' '; // replace null -> virtual space for clang content[sci_get_length(editor->sci)] = '\0'; // TODO clang's col is byte? character? completion_framework->complete_async(editor->document->file_name, content, line + 1, byte_line_len + 1); edit_tracker.valid = true; edit_tracker.start_pos = pos; edit_tracker.text.clear(); if (pos != sci_get_current_position(editor->sci)) { int len = sci_get_current_position(editor->sci) - pos; edit_tracker.text.append(content + pos, len); } g_free(content); }
static void run_tag_highlighter(ScintillaObject *sci) { gint position = sci_get_current_position(sci); gint lineNumber = sci_get_current_line(sci); gint lineStart = sci_get_position_from_line(sci, lineNumber); gint lineEnd = sci_get_line_end_position(sci, lineNumber); gint openingBracket = findBracket(sci, position, lineStart, '<', '>', FALSE); gint closingBracket = findBracket(sci, position, lineEnd, '>', '<', TRUE); int i; if(-1 == openingBracket || -1 == closingBracket) { clear_previous_highlighting(sci, highlightedBrackets[0], highlightedBrackets[1]); clear_previous_highlighting(sci, highlightedBrackets[2], highlightedBrackets[3]); for(i=0; i<3; i++) highlightedBrackets[i] = 0; return; } /* If the cursor jumps from one tag into another, clear * previous highlighted tags*/ if(openingBracket != highlightedBrackets[0] || closingBracket != highlightedBrackets[1]) { clear_previous_highlighting(sci, highlightedBrackets[0], highlightedBrackets[1]); clear_previous_highlighting(sci, highlightedBrackets[2], highlightedBrackets[3]); } /* Don't run search on empty brackets <> */ if (closingBracket - openingBracket > 1) { highlightedBrackets[0] = openingBracket; highlightedBrackets[1] = closingBracket; findMatchingTag(sci, openingBracket, closingBracket); } }
static void insert_numbers(gboolean *cancel) { /* editor */ ScintillaObject *sci = document_get_current()->editor->sci; gint xinsert = sci_point_x_from_position(sci, start_pos); gint xend = sci_point_x_from_position(sci, end_pos); gint *line_pos = g_new(gint, end_line - start_line + 1); gint line, i; /* generator */ gint64 start = start_value; gint64 value; unsigned count = 0; size_t prefix_len = 0; int plus = 0, minus; size_t length, lend; char pad, aax; gchar *buffer; if (xend < xinsert) xinsert = xend; ui_progress_bar_start(_("Counting...")); /* lines shorter than the current selection are skipped */ for (line = start_line, i = 0; line <= end_line; line++, i++) { if (sci_point_x_from_position(sci, scintilla_send_message(sci, SCI_GETLINEENDPOSITION, line, 0)) >= xinsert) { line_pos[i] = sci_get_pos_at_line_sel_start(sci, line) - sci_get_position_from_line(sci, line); count++; } else line_pos[i] = -1; if (cancel && i % 2500 == 0) { update_display(); if (*cancel) { ui_progress_bar_stop(); g_free(line_pos); return; } } } switch (base_value * base_prefix) { case 8 : prefix_len = 1; break; case 16 : prefix_len = 2; break; case 10 : plus++; } value = start + (count - 1) * step_value; minus = start < 0 || value < 0; lend = plus || (pad_zeros ? minus : value < 0); while (value /= base_value) lend++; value = start; length = plus || (pad_zeros ? minus : value < 0); while (value /= base_value) length++; length = prefix_len + (length > lend ? length : lend) + 1; buffer = g_new(gchar, length + 1); buffer[length] = '\0'; pad = pad_zeros ? '0' : ' '; aax = (lower_case ? 'a' : 'A') - 10; gtk_progress_bar_set_text(GTK_PROGRESS_BAR(geany->main_widgets->progressbar), _("Preparing...")); update_display(); sci_start_undo_action(sci); sci_replace_sel(sci, ""); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(geany->main_widgets->progressbar), _("Inserting...")); for (line = start_line, i = 0; line <= end_line; line++, i++) { gchar *beg, *end; gint insert_pos; if (line_pos[i] < 0) continue; beg = buffer; end = buffer + length; value = ABS(start); do { unsigned digit = value % base_value; *--end = digit + (digit < 10 ? '0' : aax); } while (value /= base_value); if (pad_zeros) { if (start < 0) *beg++ = '-'; else if (plus) *beg++ = '+'; else if (minus) *beg++ = ' '; memcpy(beg, "0x", prefix_len); beg += prefix_len; } else { if (start < 0) *--end = '-'; else if (plus) *--end = '+'; end -= prefix_len; memcpy(end, "0x", prefix_len); } memset(beg, pad, end - beg); insert_pos = sci_get_position_from_line(sci, line) + line_pos[i]; sci_insert_text(sci, insert_pos, buffer); start += step_value; if (cancel && i % 1000 == 0) { update_display(); if (*cancel) { scintilla_send_message(sci, SCI_GOTOPOS, insert_pos + length, 0); break; } } } sci_end_undo_action(sci); g_free(buffer); g_free(line_pos); ui_progress_bar_stop(); }
static void shift_left_cb(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer gdata){ gchar *txt; gchar *txt_i; gchar char_before; gint txt_len; gint startpos; gint endpos; gint startline; gint endline; gint line_iter; gint linepos; gint linelen; gint startcol; gint endcol; gint i; gint n_spaces; gchar *spaces; ScintillaObject *sci; /* get a pointer to the scintilla object */ sci = document_get_current()->editor->sci; if (sci_has_selection(sci)){ startpos = sci_get_selection_start(sci); endpos = sci_get_selection_end(sci); /* sanity check -- we dont care which way the block was selected */ if(startpos > endpos){ i = endpos; endpos = startpos; startpos = i; } startline = sci_get_line_from_position(sci, startpos); /* Setting also start point for 1st line */ linepos = sci_get_position_from_line(sci, startline); endline = sci_get_line_from_position(sci, endpos); /* normal mode */ if(startline == endline){ /* get the text in question */ txt_len = endpos - startpos; txt_i = g_malloc(txt_len + 1); txt = g_malloc(txt_len + 2); sci_get_selected_text(sci, txt_i); char_before = sci_get_char_at(sci, startpos - 1); /* set up new text buf */ (void) g_sprintf(txt, "%s%c", txt_i, char_before); /* start undo */ sci_start_undo_action(sci); /* put the new text in */ sci_set_selection_start(sci, startpos - 1); sci_replace_sel(sci, txt); /* select the right bit again */ sci_set_selection_start(sci, startpos - 1); sci_set_selection_end(sci, endpos - 1); /* end undo */ sci_end_undo_action(sci); g_free(txt); g_free(txt_i); } /* rectangle mode (we hope!) */ else{ startcol = sci_get_col_from_position(sci, startpos); endcol = sci_get_col_from_position(sci, endpos); /* return early for the trivial case */ if(startcol == 0 || startcol == endcol){ return; } /* start undo */ sci_start_undo_action(sci); for(line_iter = startline; line_iter <= endline; line_iter++){ linepos = sci_get_position_from_line(sci, line_iter); linelen = sci_get_line_length(sci, line_iter); /* do we need to do something */ if(linelen >= startcol - 1 ){ /* if between the two columns */ /* pad to the end first */ if(linelen <= endcol){ /* bung in some spaces -- sorry, I dont like tabs */ n_spaces = endcol - linelen + 1; spaces = g_malloc(sizeof(gchar) * (n_spaces + 1)); for(i = 0; i < n_spaces; i++){ spaces[i] = ' '; } spaces[i] = '\0'; sci_insert_text(sci, linepos + linelen - 1, spaces); g_free(spaces); } /* now move the text itself */ sci_set_selection_mode(sci, 0); sci_set_selection_start(sci, linepos + startcol); sci_set_selection_end(sci, linepos + endcol); txt_len = sci_get_selected_text_length(sci); txt_i = g_malloc(txt_len + 1); txt = g_malloc(txt_len + 2); sci_get_selected_text(sci, txt_i); char_before = sci_get_char_at(sci, linepos + startcol - 1); /* set up new text buf */ (void) g_sprintf(txt, "%s%c", txt_i, char_before); /* put the new text in */ sci_set_selection_start(sci, linepos + startcol - 1); sci_replace_sel(sci, txt); g_free(txt); g_free(txt_i); } } /* put the selection box back */ /* here we rely upon the last result of linepos */ sci_set_selection_mode(sci, 1); sci_set_selection_start(sci, startpos - 1); sci_set_selection_end(sci, linepos + endcol - 1); /* end undo action */ sci_end_undo_action(sci); } } }
static void shift_right_cb(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer gdata){ gchar *txt; gchar *txt_i; gchar char_after; gint txt_len; gint startpos; gint endpos; gint startline; gint endline; gint line_iter; gint linepos; gint linelen; gint startcol; gint endcol; gint i; ScintillaObject *sci; /* get a pointer to the scintilla object */ sci = document_get_current()->editor->sci; if (sci_has_selection(sci)){ startpos = sci_get_selection_start(sci); endpos = sci_get_selection_end(sci); /* sanity check -- we dont care which way the block was selected */ if(startpos > endpos){ i = endpos; endpos = startpos; startpos = i; } startline = sci_get_line_from_position(sci, startpos); linepos = sci_get_position_from_line(sci, startline); endline = sci_get_line_from_position(sci, endpos); /* normal mode */ if(startline == endline){ /* get the text in question */ txt_len = endpos - startpos; txt_i = g_malloc(txt_len + 1); txt = g_malloc(txt_len + 2); sci_get_selected_text(sci, txt_i); char_after = sci_get_char_at(sci, endpos); /* set up new text buf */ (void) g_sprintf(txt, "%c%s", char_after, txt_i); /* start undo */ sci_start_undo_action(sci); /* put the new text in */ sci_set_selection_end(sci, endpos + 1); sci_replace_sel(sci, txt); /* select the right bit again */ sci_set_selection_start(sci, startpos + 1); sci_set_selection_end(sci, endpos + 1); /* end undo */ sci_end_undo_action(sci); g_free(txt); g_free(txt_i); } /* rectangle mode (we hope!) */ else{ startcol = sci_get_col_from_position(sci, startpos); endcol = sci_get_col_from_position(sci, endpos); /* start undo */ sci_start_undo_action(sci); for(line_iter = startline; line_iter <= endline; line_iter++){ linepos = sci_get_position_from_line(sci, line_iter); linelen = sci_get_line_length(sci, line_iter); /* do we need to do something */ if(linelen >= startcol - 1 ){ /* if between the two columns or at the end */ /* add in a space */ if(linelen <= endcol || linelen - 1 == endcol){ txt = g_malloc(sizeof(gchar) * 2); sprintf(txt, " "); sci_insert_text(sci, linepos + startcol, txt); g_free(txt); } else{ /* move the text itself */ sci_set_selection_mode(sci, 0); sci_set_selection_start(sci, linepos + startcol); sci_set_selection_end(sci, linepos + endcol); txt_len = sci_get_selected_text_length(sci); txt_i = g_malloc(txt_len + 1); txt = g_malloc(txt_len + 2); sci_get_selected_text(sci, txt_i); char_after = sci_get_char_at(sci, linepos + endcol); /* set up new text buf */ (void) g_sprintf(txt, "%c%s", char_after, txt_i); /* put the new text in */ sci_set_selection_end(sci, linepos + endcol + 1); sci_replace_sel(sci, txt); g_free(txt); g_free(txt_i); } } } /* put the selection box back */ /* here we rely upon the last result of linepos */ sci_set_selection_mode(sci, 1); sci_set_selection_start(sci, startpos + 1); sci_set_selection_end(sci, linepos + endcol + 1); /* end undo action */ sci_end_undo_action(sci); } } }
/* Set the cursor line without scrolling the view. * Use sci_goto_line() to also scroll. */ void sci_set_current_line(ScintillaObject *sci, gint line) { gint pos = sci_get_position_from_line(sci, line); sci_set_current_position(sci, pos, FALSE); }
static void do_format(GeanyDocument *doc, bool entire_doc, bool autof) { GString *formatted; ScintillaObject *sci; size_t offset = 0, length = 0, sci_len; size_t cursor_pos, old_first_line, new_first_line, line_delta; const char *sci_buf; bool changed = true; bool was_changed; if (doc == NULL) doc = document_get_current(); if (!DOC_VALID(doc)) { g_warning("Cannot format with no documents open"); return; } sci = doc->editor->sci; was_changed = doc->changed; // FIXME: instead of failing, ask user to save the document once if (!doc->real_path) { g_warning("Cannot format document that's never been saved"); return; } if (!entire_doc) { if (sci_has_selection(sci)) { // format selection offset = sci_get_selection_start(sci); length = sci_get_selection_end(sci) - offset; } else { // format current line size_t cur_line = sci_get_current_line(sci); offset = sci_get_position_from_line(sci, cur_line); length = sci_get_line_end_position(sci, cur_line) - offset; } } else { // format entire document offset = 0; length = sci_get_length(sci); } cursor_pos = sci_get_current_position(sci); sci_len = sci_get_length(sci); sci_buf = (const char *)scintilla_send_message(sci, SCI_GETCHARACTERPOINTER, 0, 0); formatted = fmt_clang_format(doc->file_name, sci_buf, sci_len, &cursor_pos, offset, length, false); // FIXME: handle better if (formatted == NULL) return; if (!autof) { changed = (formatted->len != sci_len) || (g_strcmp0(formatted->str, sci_buf) != 0); } old_first_line = scintilla_send_message(sci, SCI_GETFIRSTVISIBLELINE, 0, 0); // Replace document text and move cursor to new position scintilla_send_message(sci, SCI_BEGINUNDOACTION, 0, 0); scintilla_send_message(sci, SCI_CLEARALL, 0, 0); scintilla_send_message(sci, SCI_ADDTEXT, formatted->len, (sptr_t)formatted->str); scintilla_send_message(sci, SCI_GOTOPOS, cursor_pos, 0); new_first_line = scintilla_send_message(sci, SCI_GETFIRSTVISIBLELINE, 0, 0); line_delta = new_first_line - old_first_line; scintilla_send_message(sci, SCI_LINESCROLL, 0, -line_delta); scintilla_send_message(sci, SCI_ENDUNDOACTION, 0, 0); document_set_text_changed(doc, (was_changed || changed)); g_string_free(formatted, true); }