static int get_completion_position(int* flag = NULL)
{
	const char* stop_token = "{}[]#()<>%:;.?*+-/^&∼!=,\\\"\'\t\n ";
	float xxx;
	GeanyDocument* doc = document_get_current();

	ScintillaObject* sci = doc->editor->sci;
	int cur_pos = sci_get_current_position(sci);
	if (cur_pos == 0) return 0;
	int cur_token_started_pos = 0;
	// g_print("char at (%d) %c ", sci_get_char_at(sci, cur_pos), sci_get_char_at(sci, cur_pos));
	for (int pos = cur_pos - 1; pos >= 0; pos--) {
		if (strchr(stop_token, sci_get_char_at(sci, pos))) {
			cur_token_started_pos = pos + 1;
			break;
		}
	}
	// g_print("cpos %d token %d", cur_pos, cur_token_started_pos);
	return cur_token_started_pos;
}
Beispiel #2
0
static void
define_format_line(ScintillaObject *sci, gint current_line)
{
	gint    length;
	gint    first_line;
	gint    first_end;
	gint    max = geany_data->editor_prefs->long_line_column;

	if(!inside_define(sci, current_line, FALSE))
		return;

	first_line = current_line;
	first_end = get_line_end(sci, first_line);
	for (first_end--; sci_get_char_at(sci, first_end - 1) == ' '; first_end--) {}
	SSM(sci, SCI_DELETERANGE, first_end, sci_get_line_end_position(sci, first_line) - first_end);
	length = first_end - get_indent_pos(sci, first_line) + sci_get_line_indentation(sci, first_line);
	for(; length < max - 1; length++, first_end++)
		sci_insert_text(sci, first_end, " ");
	sci_insert_text(sci, first_end, "\\");
}
Beispiel #3
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);
         }

      }
   }
Beispiel #4
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);
         }
      }
   }
Beispiel #5
0
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
					  gint page_nr, gpointer user_data)
{
	DocInfo *dinfo = user_data;
	GeanyEditor *editor;
	cairo_t *cr;
	gdouble width, height;
	gdouble x = 0.0, y = 0.0;
	/*gint layout_h;*/
	gint count;
	GString *str;

	if (dinfo == NULL || page_nr >= dinfo->n_pages)
		return;

	editor = dinfo->doc->editor;

	if (dinfo->n_pages > 0)
	{
		gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages;
		gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages);
		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction);
		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text);
		g_free(text);
	}

#ifdef GEANY_PRINT_DEBUG
	geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d",
		page_nr, dinfo->n_pages, dinfo->lines_per_page);
#endif

	str = g_string_sized_new(256);
	cr = gtk_print_context_get_cairo_context(context);
	width = gtk_print_context_get_width(context);
	height = gtk_print_context_get_height(context);

	cairo_set_source_rgb(cr, 0, 0, 0);
#ifdef GEANY_PRINT_DEBUG
	cairo_set_line_width(cr, 0.2);
	cairo_rectangle(cr, 0, 0, width, height);
	cairo_stroke(cr);
#endif
	cairo_move_to(cr, 0, 0);

	pango_layout_set_width(dinfo->layout, width * PANGO_SCALE);
	pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT);
	pango_layout_set_ellipsize(dinfo->layout, FALSE);
	pango_layout_set_justify(dinfo->layout, FALSE);

	if (printing_prefs.print_page_header)
		add_page_header(dinfo, cr, width, page_nr);

	count = 0;	/* the actual line counter for the current page, might be different from
				 * dinfo->cur_line due to possible line breaks */
	while (count < dinfo->lines_per_page)
	{
		gchar c = 'a';
		gint style = -1;
		PangoAttrList *layout_attr;
		PangoAttribute *attr;
		gint colours[3] = { 0 };
		gboolean add_linenumber = TRUE;
		gboolean at_eol;

		while (count < dinfo->lines_per_page && c != '\0')
		{
			at_eol = FALSE;

			g_string_erase(str, 0, str->len); /* clear the string */

			/* line numbers */
			if (printing_prefs.print_line_numbers && add_linenumber)
			{
				/* if we had a wrapped line on the last page which needs to be continued, don't
				 * add a line number */
				if (dinfo->long_line)
				{
					add_linenumber = FALSE;
				}
				else
				{
					gchar *line_number = NULL;
					gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1);
					gchar *fill = g_strnfill(
						dinfo->max_line_number_margin - cur_line_number_margin - 1, ' ');

					line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1);
					g_string_append(str, line_number);
					dinfo->cur_line++; /* increase document line */
					add_linenumber = FALSE;
					style = STYLE_LINENUMBER;
					c = 'a'; /* dummy value */
					g_free(fill);
					g_free(line_number);
				}
			}
			/* data */
			else
			{
				style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				if (c == '\0' || style == -1)
				{	/* if c gets 0, we are probably out of document boundaries,
					 * so stop to break out of outer loop */
					count = dinfo->lines_per_page;
					break;
				}
				dinfo->cur_pos++;

				/* convert tabs to spaces which seems to be better than using Pango tabs */
				if (c == '\t')
				{
					gint tab_width = sci_get_tab_width(editor->sci);
					gchar *s = g_strnfill(tab_width, ' ');
					g_string_append(str, s);
					g_free(s);
				}
				/* don't add line breaks, they are handled manually below */
				else if (c == '\r' || c == '\n')
				{
					gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
					at_eol = TRUE;
					if (c == '\r' && c_next == '\n')
						dinfo->cur_pos++; /* skip LF part of CR/LF */
				}
				else
				{
					g_string_append_c(str, c); /* finally add the character */

					/* handle UTF-8: since we add char by char (better: byte by byte), we need to
					 * keep UTF-8 characters together(e.g. two bytes for one character)
					 * the input is always UTF-8 and c is signed, so all non-Ascii
					 * characters are less than 0 and consist of all bytes less than 0.
					 * style doesn't change since it is only one character with multiple bytes. */
					while (c < 0)
					{
						c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
						if (c < 0)
						{	/* only add the byte when it is part of the UTF-8 character
							 * otherwise we could add e.g. a '\n' and it won't be visible in the
							 * printed document */
							g_string_append_c(str, c);
							dinfo->cur_pos++;
						}
					}
				}
			}

			if (! at_eol)
			{
				/* set text */
				pango_layout_set_text(dinfo->layout, str->str, -1);
				/* attributes */
				layout_attr = pango_attr_list_new();
				/* foreground colour */
				get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* background colour */
				get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_background_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* bold text */
				if (dinfo->styles[style][BOLD])
				{
					attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
					ADD_ATTR(layout_attr, attr);
				}
				/* italic text */
				if (dinfo->styles[style][ITALIC])
				{
					attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
					ADD_ATTR(layout_attr, attr);
				}
				pango_layout_set_attributes(dinfo->layout, layout_attr);
				pango_layout_context_changed(dinfo->layout);
				pango_attr_list_unref(layout_attr);
			}

			cairo_get_current_point(cr, &x, &y);


			/* normal line break at eol character in document */
			if (at_eol)
			{
				/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
				/*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/
				cairo_move_to(cr, 0, y + dinfo->line_height);

				count++;
				/* we added a new document line so request a new line number */
				add_linenumber = TRUE;
			}
			else
			{
				gint x_offset = 0;
				/* maybe we need to force a line break because of too long line */
				if (x >= (width - dinfo->font_width))
				{
					/* don't start the line at horizontal origin because we need to skip the
					 * line number margin */
					if (printing_prefs.print_line_numbers)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
					}

					/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
					/*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/
					/* this is faster but not exactly the same as above */
					cairo_move_to(cr, x_offset, y + dinfo->line_height);
					cairo_get_current_point(cr, &x, &y);
					count++;
				}
				if (count < dinfo->lines_per_page)
				{
					/* str->len is counted in bytes not characters, so use g_utf8_strlen() */
					x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width);

					if (dinfo->long_line && count == 0)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
						dinfo->long_line = FALSE;
					}

					pango_cairo_show_layout(cr, dinfo->layout);
					cairo_move_to(cr, x + x_offset, y);
				}
				else
				/* we are on a wrapped line but we are out of lines on this page, so continue
				 * the current line on the next page and remember to continue in current line */
					dinfo->long_line = TRUE;
			}
		}
	}

	if (printing_prefs.print_line_numbers)
	{	/* print a thin line between the line number margin and the data */
		gint y_start = 0;

		if (printing_prefs.print_page_header)
			y_start = (dinfo->line_height * 3) - 2;	/* "- 2": to connect the line number line to
													 * the page header frame */

		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start);
		cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1,
			y + dinfo->line_height); /* y is last added line, we reuse it */
		cairo_stroke(cr);
	}

	if (printing_prefs.print_page_numbers)
	{
		gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1);
		pango_layout_set_markup(dinfo->layout, line, -1);
		pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER);
		cairo_move_to(cr, 0, height - dinfo->line_height);
		pango_cairo_show_layout(cr, dinfo->layout);
		g_free(line);

#ifdef GEANY_PRINT_DEBUG
		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height));
		cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height));
		cairo_stroke(cr);
#endif
	}
	g_string_free(str, TRUE);
}
Beispiel #6
0
static char sci_text_get_char(ScintillaObject* sci, unsigned int i) {
  return (i >= sci_get_length(sci)) ? 0 : sci_get_char_at(sci, i);
}
/* Searches tag brackets.
 * direction variable shows sets search direction:
 * TRUE  - to the right
 * FALSE - to the left
 * from the current cursor position to the start of the line.
 */
static gint findBracket(ScintillaObject *sci, gint position, gint endOfSearchPos,
                        gchar searchedBracket, gchar breakBracket, gboolean direction)
{
    gint foundBracket = -1;
    gint pos;

    if(TRUE == direction)
    {
        /* search to the right */
        for(pos=position; pos<=endOfSearchPos; pos++)
        {
            gchar charAtCurPosition = sci_get_char_at(sci, pos);
            gchar charAtPrevPosition = sci_get_char_at(sci, pos-1);
            gchar charAtNextPosition = sci_get_char_at(sci, pos+1);

            if(charAtCurPosition == searchedBracket) {
                if ('>' == searchedBracket) {
                    if (('-' == charAtPrevPosition) || ('?' == charAtPrevPosition))
                        continue;
                } else if ('<' == searchedBracket) {
                    if ('?' == charAtNextPosition)
                        continue;
                }
                foundBracket = pos;
                break;
            } else if(charAtCurPosition == breakBracket) {
                if ('<' == breakBracket) {
                    if ('?' == charAtNextPosition)
                        continue;
                }
                break;
            }
        }
    }
    else
    {
        /* search to the left */
        for(pos=position-1; pos>=endOfSearchPos; pos--)
        {
            gchar charAtCurPosition = sci_get_char_at(sci, pos);
            gchar charAtPrevPosition = sci_get_char_at(sci, pos+1);
            gchar charAtNextPosition = sci_get_char_at(sci, pos-1);

            if(charAtCurPosition == searchedBracket)
            {
                if ('<' == searchedBracket) {
                    if ('?' == charAtPrevPosition)
                        continue;
                } else if ('>' == searchedBracket) {
                    if (('-' == charAtNextPosition) || ('?' == charAtNextPosition))
                        continue;
                }
                foundBracket = pos;
                break;
            } else if(charAtCurPosition == breakBracket) {
                if ('>' == breakBracket) {
                    if (('-' == charAtNextPosition) || ('?' == charAtNextPosition))
                        continue;
                }
                break;
            }
        }
    }

    return foundBracket;
}
Beispiel #8
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;
}
Beispiel #9
0
static gchar
char_at(ScintillaObject *sci, gint pos)
{
	return sci_get_char_at(sci, pos);
}