Esempio n. 1
0
/* Returns the line number of the previous marker that matches marker_mask, or -1.
 * marker_mask is a bitor of 1 << marker_index. (See MarkerHandleSet::MarkValue()).
 * Note: If there is a marker on the line, it returns the same line. */
gint sci_marker_previous(ScintillaObject *sci, gint line, gint marker_mask, gboolean wrap)
{
	gint marker_line;

	marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) line, marker_mask);
	if (wrap && marker_line == -1)
	{
		gint len = sci_get_length(sci);
		gint last_line = sci_get_line_from_position(sci, len - 1);

		marker_line = (gint) SSM(sci, SCI_MARKERPREVIOUS, (uptr_t) last_line, marker_mask);
	}
	return marker_line;
}
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);
}
Esempio n. 3
0
static gboolean
improve_indent(
	ScintillaObject *sci,
	GeanyEditor     *editor,
	gint             pos)
{
	gint ch, ch_next;
	gint line;
	gint indent, indent_width;
	gint end_pos;
	if (!ac_info->improved_cbracket_indent)
		return AC_CONTINUE_ACTION;
	ch = char_at(sci, pos - 1);
	if (ch != '{')
		return AC_CONTINUE_ACTION;
	/* if curly bracket completion is enabled - just make indents
	 * but ensure that second "}" exists. If disabled - make indent
	 * and complete second curly bracket */
	ch_next = char_at(sci, pos);
	if (ac_info->cbracket && ch_next != '}')
		return AC_CONTINUE_ACTION;
	line = sci_get_line_from_position(sci, pos);
	indent = sci_get_line_indentation(sci, line);
	indent_width = editor_get_indent_prefs(editor)->width;
	sci_start_undo_action(sci);
	if (ac_info->cbracket)
		SSM(sci, SCI_ADDTEXT, 2, (sptr_t)"\n\n");
	else
		SSM(sci, SCI_ADDTEXT, 3, (sptr_t)"\n\n}");
	if (ac_info->whitesmiths_style)
	{
		sci_set_line_indentation(sci, line,     indent);
		sci_set_line_indentation(sci, line + 1, indent);
		sci_set_line_indentation(sci, line + 2, indent);
	}
	else
	{
		sci_set_line_indentation(sci, line + 1, indent + indent_width);
		sci_set_line_indentation(sci, line + 2, indent);
	}
	/* move to the end of added line */
	end_pos = sci_get_line_end_position(sci, line + 1);
	sci_set_current_position(sci, end_pos, TRUE);
	sci_end_undo_action(sci);
	/* do not alow internal auto-indenter to do the work */
	return AC_STOP_ACTION;
}
Esempio n. 4
0
static PyObject *
Scintilla_get_line_from_position(Scintilla *self, PyObject *args, PyObject *kwargs)
{
	gint line, pos;
	static gchar *kwlist[] = { "pos", NULL };

	SCI_RET_IF_FAIL(self);

	if (PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &pos))
	{
		if (pos == -1)
			pos = sci_get_current_position(self->sci);
		line = sci_get_line_from_position(self->sci, pos);
		return Py_BuildValue("i", line);
	}

	Py_RETURN_NONE;
}
Esempio n. 5
0
static gboolean on_editor_notify(G_GNUC_UNUSED GObject *obj, GeanyEditor *editor,
	SCNotification *nt, G_GNUC_UNUSED gpointer gdata)
{
	GeanyDocument *doc = editor->document;

	if (nt->nmhdr.code == SCN_MODIFIED && nt->linesAdded && utils_source_document(doc))
	{
		gboolean active = debug_state() != DS_INACTIVE;
		ScintillaObject *sci = editor->sci;
		gint start = sci_get_line_from_position(sci, nt->position);

		if (active)
			threads_delta(sci, doc->real_path, start, nt->linesAdded);

		breaks_delta(sci, doc->real_path, start, nt->linesAdded, active);
	}

	return FALSE;
}
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);
}
Esempio n. 7
0
static void check_on_text_changed(GeanyDocument *doc, gint position, gint lines_added)
{
    gint line_number;
    gint line_count;

    /* Iterating over all lines which changed as indicated by lines_added. lines_added is 0
     * if only a lines has changed, in this case set it to 1. Otherwise, iterating over all
     * new lines makes spell checking work for pasted text. */
    line_count = MAX(1, lines_added);

    line_number = sci_get_line_from_position(doc->editor->sci, position);
    /* TODO: storing these information in the global check_line_data struct isn't that good.
     * The data gets overwritten when a new line is inserted and so there is a chance that thep
     * previous line is not checked to the end. One solution could be to simple maintain a list
     * of line numbers which needs to be checked and do this is the timeout handler. */
    check_line_data.doc = doc;
    check_line_data.line_number = line_number;
    check_line_data.line_count = line_count;

    /* check only once in a while */
    if (! need_delay())
        check_lines(NULL);
}
Esempio n. 8
0
/* if type == -1 then we will try to autodetect the type */
void glatex_insert_environment(const gchar *environment, gint type)
{
	GeanyDocument *doc = NULL;

	doc = document_get_current();

	/* Only do anything if it is realy needed to */
	if (doc != NULL && environment != NULL)
	{
		if (sci_has_selection(doc->editor->sci))
		{
			gchar *selection  = NULL;
			gchar *replacement = NULL;
			selection = sci_get_selection_contents(doc->editor->sci);

			sci_start_undo_action(doc->editor->sci);
			if (utils_str_equal(environment, "block") == TRUE)
			{
				replacement = g_strconcat("\\begin{", environment, "}{}\n",
							  selection, "\n\\end{", environment, "}\n", NULL);
			}
			else
			{
				replacement = g_strconcat("\\begin{", environment, "}\n",
							  selection, "\n\\end{", environment, "}\n", NULL);
			}
			sci_replace_sel(doc->editor->sci, replacement);
			sci_end_undo_action(doc->editor->sci);
			g_free(selection);
			g_free(replacement);

		}
		else
		{
			gint indent, pos;
			GString *tmpstring = NULL;
			gchar *tmp = NULL;
			static const GeanyIndentPrefs *indention_prefs = NULL;

			if (type == -1)
			{
				gint i;

				/* First, we check whether we have a known list over here
				 * an reset type to fit new value*/
				for (i = 0; i < GLATEX_LIST_END; i++)
				{
					if (utils_str_equal(glatex_list_environments[i], environment) == TRUE)
					{
						type = GLATEX_ENVIRONMENT_TYPE_LIST;
						break;
					}
				}
			}
			pos = sci_get_current_position(doc->editor->sci);

			sci_start_undo_action(doc->editor->sci);

			tmpstring = g_string_new("\\begin{");
			g_string_append(tmpstring, environment);

			if (utils_str_equal(environment, "block") == TRUE)
			{
				g_string_append(tmpstring, "}{}");
			}
			else
			{
				g_string_append(tmpstring, "}");
			}
			g_string_append(tmpstring, "\n");


			if (type == GLATEX_ENVIRONMENT_TYPE_LIST)
			{
				g_string_append(tmpstring, "\t\\item ");
			}

			tmp = g_string_free(tmpstring, FALSE);
			glatex_insert_string(tmp, TRUE);
			g_free(tmp);

			indent = sci_get_line_indentation(doc->editor->sci,
				sci_get_line_from_position(doc->editor->sci, pos));

			tmp = g_strdup_printf("\n\\end{%s}", environment);
			glatex_insert_string(tmp, FALSE);
			g_free(tmp);

			indention_prefs = editor_get_indent_prefs(doc->editor);
			if (type == GLATEX_ENVIRONMENT_TYPE_LIST)
			{
				sci_set_line_indentation(doc->editor->sci,
					sci_get_current_line(doc->editor->sci),
					indent + indention_prefs->width);
			}
			sci_set_line_indentation(doc->editor->sci,
				sci_get_current_line(doc->editor->sci) + 1, indent);
			sci_end_undo_action(doc->editor->sci);
		}
	}
}
Esempio n. 9
0
/*
 * 	Occures on notify from editor.
 * 	Handles margin click to set/remove breakpoint 
 */
gboolean on_editor_notify(
	GObject *object, GeanyEditor *editor,
	SCNotification *nt, gpointer data)
{
	if (!editor->document->real_path)
	{
		/* no other way to handle removing a file from outside of geany */
		markers_remove_all(editor->document);
	}
	
	switch (nt->nmhdr.code)
	{
		case SCN_MARGINCLICK:
		{
			char* file;
			int line;
			break_state bs;

			if (!editor->document->real_path || 1 != nt->margin)
				break;
			
			file = editor->document->file_name;
			line = sci_get_line_from_position(editor->sci, nt->position) + 1;

			bs = breaks_get_state(file, line);
			if (BS_NOT_SET == bs)
				breaks_add(file, line, NULL, TRUE, 0);
			else if (BS_ENABLED == bs)
				breaks_remove(file, line);
			else if (BS_DISABLED == bs)
				breaks_switch(file, line);
			
			scintilla_send_message(editor->sci, SCI_SETFOCUS, TRUE, 0);
			
			return TRUE;
		}
		case SCN_DWELLSTART:
		{
			GString *word;

			if (DBS_STOPPED != debug_get_state ())
				break;

			/* get a word under the cursor */
			word = get_word_at_position(editor->sci, nt->position);
			if (word->len)
			{
				gchar *calltip = debug_get_calltip_for_expression(word->str);
				if (calltip)
				{
					leave_signal = g_signal_connect(G_OBJECT(editor->sci), "leave-notify-event", G_CALLBACK(on_mouse_leave), NULL);
					scintilla_send_message (editor->sci, SCI_CALLTIPSHOW, nt->position, (long)calltip);
				}
			}
				
			g_string_free(word, TRUE);
			
			break;
		}
		case SCN_DWELLEND:
		{
			if (DBS_STOPPED != debug_get_state ())
				break;

			if (scintilla_send_message (editor->sci, SCI_CALLTIPACTIVE, 0, 0))
			{
				g_signal_handler_disconnect(G_OBJECT(editor->sci), leave_signal);
				scintilla_send_message (editor->sci, SCI_CALLTIPCANCEL, 0, 0);
			}
			break;
		}
		case SCN_MODIFYATTEMPTRO:
		{
			dialogs_show_msgbox(GTK_MESSAGE_INFO, _("To edit source files stop debugging session"));
			break;
		}
		case SCN_MODIFIED:
		{
			if(((SC_MOD_INSERTTEXT & nt->modificationType) || (SC_MOD_DELETETEXT && nt->modificationType)) && editor->document->file_name && nt->linesAdded)
			{
				int line = sci_get_line_from_position(editor->sci, nt->position) + 1;

				GList *breaks = breaks_get_for_document(editor->document->file_name);
				if (breaks)
				{
					GList *iter = breaks;
					while (iter)
					{
						breakpoint *bp = (breakpoint*)iter->data;

						if (nt->linesAdded > 0 && bp->line >= line)
						{
							breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded);
							bptree_update_breakpoint(bp);
						}
						else if (nt->linesAdded < 0 && bp->line >= line)
						{
							if (bp->line < line - nt->linesAdded)
							{
								breaks_remove(bp->file, bp->line);
							}
							else
							{
								breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded);
								bptree_update_breakpoint(bp);
							}
						}
						iter = iter->next;
					}
					
					config_set_debug_changed();

					g_list_free(breaks);
				}
			}
			break;
		}
	}

	return FALSE;
}
Esempio n. 10
0
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);
         }

      }
   }
Esempio n. 11
0
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);
         }
      }
   }
Esempio n. 12
0
void sc_speller_check_document(GeanyDocument *doc)
{
	gchar *line;
	gint i;
	gint first_line, last_line;
	gchar *dict_string = NULL;
	gint suggestions_found = 0;

	g_return_if_fail(sc_speller_dict != NULL);
	g_return_if_fail(doc != NULL);

	ui_progress_bar_start(_("Checking"));

	enchant_dict_describe(sc_speller_dict, dict_describe, &dict_string);

	if (sci_has_selection(doc->editor->sci))
	{
		first_line = sci_get_line_from_position(
			doc->editor->sci, sci_get_selection_start(doc->editor->sci));
		last_line = sci_get_line_from_position(
			doc->editor->sci, sci_get_selection_end(doc->editor->sci));

		if (sc_info->use_msgwin)
			msgwin_msg_add(COLOR_BLUE, -1, NULL,
				_("Checking file \"%s\" (lines %d to %d using %s):"),
				DOC_FILENAME(doc), first_line + 1, last_line + 1, dict_string);
		g_message("Checking file \"%s\" (lines %d to %d using %s):",
			DOC_FILENAME(doc), first_line + 1, last_line + 1, dict_string);
	}
	else
	{
		first_line = 0;
		last_line = sci_get_line_count(doc->editor->sci);
		if (sc_info->use_msgwin)
			msgwin_msg_add(COLOR_BLUE, -1, NULL, _("Checking file \"%s\" (using %s):"),
				DOC_FILENAME(doc), dict_string);
		g_message("Checking file \"%s\" (using %s):", DOC_FILENAME(doc), dict_string);
	}
	g_free(dict_string);

	if (first_line == last_line)
	{
		line = sci_get_selection_contents(doc->editor->sci);
		suggestions_found += sc_speller_process_line(doc, first_line, line);
		g_free(line);
	}
	else
	{
		for (i = first_line; i < last_line; i++)
		{
			line = sci_get_line(doc->editor->sci, i);

			suggestions_found += sc_speller_process_line(doc, i, line);

			/* process other GTK events to keep the GUI being responsive */
			while (g_main_context_iteration(NULL, FALSE));

			g_free(line);
		}
	}
	if (suggestions_found == 0 && sc_info->use_msgwin)
		msgwin_msg_add(COLOR_BLUE, -1, NULL, _("The checked text is spelled correctly."));

	ui_progress_bar_stop();
}
Esempio n. 13
0
static gboolean
editor_notify_cb(GObject *object, GeanyEditor *editor, SCNotification *nt, gpointer data)
{
	gint i = 0, val;
	gint old_position = 0;
	gint old_lposition = 0;
	gint old_line = 0;
	gint pos;
	if(NULL == editor || NULL == editor->sci)
		return FALSE;
	if(nt->nmhdr.code == SCN_CHARADDED)
	{
		if('\n' == nt->ch)
			define_format_newline(editor->sci);
	}
	if(nt->nmhdr.code == SCN_UPDATEUI)
	{
		if(g_array_index(lines_stack, gint, 0))
		{
			/* save current position */
			old_line = sci_get_current_line(editor->sci);
			old_lposition = sci_get_line_end_position(editor->sci, old_line) - sci_get_line_length(editor->sci, old_line);
			old_position = sci_get_current_position(editor->sci);
			sci_start_undo_action(editor->sci);
		}
		while((val = g_array_index(lines_stack, gint, i)))
		{
			i++;
			define_format_line(editor->sci, val - 1);
			dprintf("Removed from stack: %d\n", val);
		}
		if(i > 0)
		{
			sci_end_undo_action(editor->sci);
			g_array_remove_range(lines_stack, 0, i);
			/* restore current position */
			pos = sci_get_line_end_position(editor->sci, old_line) - sci_get_line_length(editor->sci, old_line);
			sci_set_current_position(editor->sci, old_position + pos - old_lposition, FALSE);
		}
	}
	if(nt->nmhdr.code == SCN_MODIFIED)
	{
		if(nt->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT))
		{
			if(nt->modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))
				return FALSE;
			gint line = sci_get_line_from_position(editor->sci, nt->position) + 1;
			if(sci_get_char_at(editor->sci, get_line_end(editor->sci, line - 1) - 1) == '\\')
			{
				gboolean found = FALSE;
				while((val = g_array_index(lines_stack, gint, i)))
				{
					if(val == line)
					{
						found = TRUE;
						break;
					}
					i++;
				}
				if(!found)
				{
					dprintf("Added line: %d\n", line);
					g_array_append_val(lines_stack, line);
				}
			}
		}
	}
	return FALSE;
}
Esempio n. 14
0
static gboolean
handle_backspace(
	AutocloseUserData *data,
	ScintillaObject   *sci,
	gchar              ch,
	gchar             *ch_left,
	gchar             *ch_right,
	GdkEventKey       *event,
	gint               indent_width)
{
	gint pos = sci_get_current_position(sci);
	gint end_pos;
	gint line_start, line_end, line;
	gint i;
	if (!ac_info->delete_pairing_brace)
		return AC_CONTINUE_ACTION;
	ch = char_at(sci, pos - 1);

	if (!check_chars(sci, ch, ch_left, ch_right))
		return AC_CONTINUE_ACTION;

	if (event->state & GDK_SHIFT_MASK)
	{
		if ((ch_left[0] == ch || ch_right[0] == ch) &&
				ac_info->bcksp_remove_pair)
		{
			end_pos = sci_find_matching_brace(sci, pos - 1);
			if (-1 == end_pos)
				return AC_CONTINUE_ACTION;
			sci_start_undo_action(sci);
			line_start = sci_get_line_from_position(sci, pos);
			line_end = sci_get_line_from_position(sci, end_pos);
			SSM(sci, SCI_DELETERANGE, end_pos, 1);
			if (end_pos < pos)
				pos--;
			SSM(sci, SCI_DELETERANGE, pos - 1, 1);
			/* remove indentation magick */
			if (char_is_curly_bracket(ch))
			{
				if (line_start == line_end)
					goto final;
				if (line_start > line_end)
				{
					line = line_end;
					line_end = line_start;
					line_start = line;
				}
				if (blank_line(sci, line_start))
				{
					delete_line(sci, line_start);
					line_end--;
				}
				else
					line_start++;
				if (blank_line(sci, line_end))
					delete_line(sci, line_end);
				line_end--;
				/* unindent */
				for (i = line_start; i <= line_end; i++)
				{
					unindent_line(sci, i, indent_width);
				}
			}
final:
			sci_end_undo_action(sci);
			return AC_STOP_ACTION;
		}