static gchar *
get_word (GtkSourceCompletionProvider *provider,
          GtkTextIter                 *iter)
{
   GtkTextIter *end;
   gboolean moved = FALSE;
   gunichar c;
   gchar *word;

   end = gtk_text_iter_copy(iter);

   do {
      if (!gtk_text_iter_backward_char(iter)) {
         break;
      }
      c = gtk_text_iter_get_char(iter);
      moved = TRUE;
   } while (!is_stop_char(c));

   if (moved && !gtk_text_iter_is_start(iter)) {
      gtk_text_iter_forward_char(iter);
   }

   word = g_strstrip(gtk_text_iter_get_text(iter, end));

   gtk_text_iter_free(end);

   return word;
}
Exemplo n.º 2
0
/* 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;
	}
}
Exemplo n.º 3
0
static gchar *
smie_gtk_source_buffer_backward_token (gpointer data)
{
  smie_gtk_source_buffer_context_t *context = data;
  GtkTextIter iter, start_iter;

  if (gtk_text_iter_is_start (&context->iter))
    return NULL;

  /* Skip comments and whitespaces.  */
  gtk_text_iter_backward_char (&context->iter);
  while (!gtk_text_iter_is_start (&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_backward_char (&context->iter);

  gtk_text_iter_assign (&iter, &context->iter);
  if (gtk_source_buffer_iter_has_context_class (context->buffer,
						&context->iter,
						"string"))
    {
      /* Read a string literal.  */
      while (!gtk_text_iter_is_start (&context->iter)
	     && gtk_source_buffer_iter_has_context_class (context->buffer,
							  &context->iter,
							  "string"))
	gtk_text_iter_backward_char (&context->iter);
    }
  else if (g_unichar_ispunct (gtk_text_iter_get_char (&context->iter)))
    {
      /* Read a punctuation.  */
      while (!gtk_text_iter_is_start (&context->iter)
	     && g_unichar_ispunct (gtk_text_iter_get_char (&context->iter)))
	gtk_text_iter_backward_char (&context->iter);
    }
  else
    {
      /* Read a normal token.  */
      while (!gtk_text_iter_is_start (&context->iter)
	     && !(gtk_source_buffer_iter_has_context_class (context->buffer,
							    &context->iter,
							    "comment")
		  || gtk_source_buffer_iter_has_context_class (context->buffer,
							       &context->iter,
							       "string")
		  || g_unichar_ispunct (gtk_text_iter_get_char (&context->iter))
		  || g_unichar_isspace (gtk_text_iter_get_char (&context->iter))))
	gtk_text_iter_backward_char (&context->iter);
    }

  gtk_text_iter_assign (&start_iter, &context->iter);
  if (!gtk_text_iter_is_start (&start_iter))
    gtk_text_iter_forward_char (&start_iter);
  gtk_text_iter_forward_char (&iter);
  return gtk_text_iter_get_slice (&start_iter, &iter);
}
Exemplo n.º 4
0
/* 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;
		}
	}
}
Exemplo n.º 5
0
static gboolean
smie_gtk_source_buffer_backward_comment (gpointer data)
{
  smie_gtk_source_buffer_context_t *context = data;
  GtkTextIter end_iter;

  gtk_text_iter_assign (&end_iter, &context->iter);
  while (!gtk_text_iter_is_start (&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_backward_char (&context->iter))
    ;
  return !gtk_text_iter_equal (&context->iter, &end_iter);
}
Exemplo n.º 6
0
static gboolean
smie_gtk_source_buffer_is_start (gpointer data)
{
  smie_gtk_source_buffer_context_t *context = data;
  return gtk_text_iter_is_start (&context->iter);
}
Exemplo n.º 7
0
static gssize
xedit_document_input_stream_read (GInputStream  *stream,
				  void          *buffer,
				  gsize          count,
				  GCancellable  *cancellable,
				  GError       **error)
{
	XeditDocumentInputStream *dstream;
	GtkTextIter iter;
	gssize space_left, read, n;

	dstream = XEDIT_DOCUMENT_INPUT_STREAM (stream);

	if (count < 6)
	{
		g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
				     "Not enougth space in destination");
		return -1;
	}

	if (g_cancellable_set_error_if_cancelled (cancellable, error))
		return -1;

	/* Initialize the mark to the first char in the text buffer */
	if (!dstream->priv->is_initialized)
	{
		gtk_text_buffer_get_start_iter (dstream->priv->buffer, &iter);
		dstream->priv->pos = gtk_text_buffer_create_mark (dstream->priv->buffer,
								 NULL,
								 &iter,
								 FALSE);

		dstream->priv->is_initialized = TRUE;
	}

	space_left = count;
	read = 0;

	do
	{
		n = read_line (dstream, buffer + read, space_left);
		read += n;
		space_left -= n;
	} while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0);

	/* Make sure that non-empty files are always terminated with \n (see bug #95676).
	 * Note that we strip the trailing \n when loading the file */
	gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer,
					  &iter,
					  dstream->priv->pos);

	if (gtk_text_iter_is_end (&iter) &&
	    !gtk_text_iter_is_start (&iter))
	{
		gssize newline_size;

		newline_size = get_new_line_size (dstream);

		if (space_left >= newline_size &&
		    !dstream->priv->newline_added)
		{
			const gchar *newline;

			newline = get_new_line (dstream);

			memcpy (buffer + read, newline, newline_size);

			read += newline_size;
			dstream->priv->newline_added = TRUE;
		}
	}

	return read;
}
Exemplo n.º 8
0
/**
 * gail_text_util_get_text:
 * @textutil: A #GailTextUtil
 * @layout: A gpointer which is a PangoLayout, a GtkTreeView of NULL
 * @function: An enumeration specifying whether to return the text before, at, or
 *   after the offset.
 * @boundary_type: The boundary type.
 * @offset: The offset of the text in the GailTextUtil 
 * @start_offset: Address of location in which the start offset is returned
 * @end_offset: Address of location in which the end offset is returned
 *
 * This function gets the requested substring from the text in the GtkTextUtil.
 * The layout is used only for getting the text on a line. The value is NULL 
 * for a GtkTextView which is not wrapped, is a GtkTextView for a GtkTextView 
 * which is wrapped and is a PangoLayout otherwise.
 *
 * Returns: the substring requested
 **/
gchar*
gail_text_util_get_text (GailTextUtil    *textutil,
                         gpointer        layout,
                         GailOffsetType  function,
                         AtkTextBoundary boundary_type,
                         gint            offset,
                         gint            *start_offset,
                         gint            *end_offset)
{
  GtkTextIter start, end;
  gint line_number;
  GtkTextBuffer *buffer;

  g_return_val_if_fail (GAIL_IS_TEXT_UTIL (textutil), NULL);

  buffer = textutil->buffer;
  if (buffer == NULL)
    {
      *start_offset = 0;
      *end_offset = 0;
      return NULL;
    }

  if (!gtk_text_buffer_get_char_count (buffer))
    {
      *start_offset = 0;
      *end_offset = 0;
      return g_strdup ("");
    }
  gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);

    
  end = start;

  switch (function)
    {
    case GAIL_BEFORE_OFFSET:
      switch (boundary_type)
        {
        case ATK_TEXT_BOUNDARY_CHAR:
          gtk_text_iter_backward_char(&start);
          break;
        case ATK_TEXT_BOUNDARY_WORD_START:
          if (!gtk_text_iter_starts_word (&start))
            gtk_text_iter_backward_word_start (&start);
          end = start;
          gtk_text_iter_backward_word_start(&start);
          break;
        case ATK_TEXT_BOUNDARY_WORD_END:
          if (gtk_text_iter_inside_word (&start) &&
              !gtk_text_iter_starts_word (&start))
            gtk_text_iter_backward_word_start (&start);
          while (!gtk_text_iter_ends_word (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          end = start;
          gtk_text_iter_backward_word_start(&start);
          while (!gtk_text_iter_ends_word (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          break;
        case ATK_TEXT_BOUNDARY_SENTENCE_START:
          if (!gtk_text_iter_starts_sentence (&start))
            gtk_text_iter_backward_sentence_start (&start);
          end = start;
          gtk_text_iter_backward_sentence_start (&start);
          break;
        case ATK_TEXT_BOUNDARY_SENTENCE_END:
          if (gtk_text_iter_inside_sentence (&start) &&
              !gtk_text_iter_starts_sentence (&start))
            gtk_text_iter_backward_sentence_start (&start);
          while (!gtk_text_iter_ends_sentence (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          end = start;
          gtk_text_iter_backward_sentence_start (&start);
          while (!gtk_text_iter_ends_sentence (&start))
            {
              if (!gtk_text_iter_backward_char (&start))
                break;
            }
          break;
        case ATK_TEXT_BOUNDARY_LINE_START:
          if (layout == NULL)
            {
              line_number = gtk_text_iter_get_line (&start);
              if (line_number == 0)
                {
                  gtk_text_buffer_get_iter_at_offset (buffer,
                    &start, 0);
                }
              else
                {
                  gtk_text_iter_backward_line (&start);
                  gtk_text_iter_forward_line (&start);
                }
              end = start;
              gtk_text_iter_backward_line (&start);
            }
          else if GTK_IS_TEXT_VIEW (layout)
            {
              GtkTextView *view = GTK_TEXT_VIEW (layout);

              gtk_text_view_backward_display_line_start (view, &start);
              end = start;
              gtk_text_view_backward_display_line (view, &start);
            }
          else if (PANGO_IS_LAYOUT (layout))
            get_pango_text_offsets (PANGO_LAYOUT (layout),
                                    buffer,
                                    function,
                                    boundary_type,
                                    offset,
                                    start_offset,
                                    end_offset,
                                    &start,
                                    &end);
          break;
        case ATK_TEXT_BOUNDARY_LINE_END:
          if (layout == NULL)
            {
              line_number = gtk_text_iter_get_line (&start);
              if (line_number == 0)
                {
                  gtk_text_buffer_get_iter_at_offset (buffer,
                    &start, 0);
                  end = start;
                }
              else
                {
                  gtk_text_iter_backward_line (&start);
                  end = start;
                  while (!gtk_text_iter_ends_line (&start))
                    {
                      if (!gtk_text_iter_backward_char (&start))
                        break;
                    }
                  gtk_text_iter_forward_to_line_end (&end);
                }
            }
          else if GTK_IS_TEXT_VIEW (layout)
            {
              GtkTextView *view = GTK_TEXT_VIEW (layout);

              gtk_text_view_backward_display_line_start (view, &start);
              if (!gtk_text_iter_is_start (&start))
                {
                  gtk_text_view_backward_display_line (view, &start);
                  end = start;
                  if (!gtk_text_iter_is_start (&start))
                    {
                      gtk_text_view_backward_display_line (view, &start);
                      gtk_text_view_forward_display_line_end (view, &start);
                    }
                  gtk_text_view_forward_display_line_end (view, &end);
                } 
              else
                {
                  end = start;
                }
            }
          else if (PANGO_IS_LAYOUT (layout))
            get_pango_text_offsets (PANGO_LAYOUT (layout),
                                    buffer,
                                    function,
                                    boundary_type,
                                    offset,
                                    start_offset,
                                    end_offset,
                                    &start,
                                    &end);
          break;
        }
Exemplo n.º 9
0
Arquivo: editor.c Projeto: ueno/c-smie
static gboolean
editor_application_window_key_press_event (GtkWidget *widget,
					   GdkEventKey *event)
{
  EditorApplicationWindow *window = EDITOR_APPLICATION_WINDOW (widget);
  if (event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_Tab)
    {
      GtkTextMark *mark;
      smie_gtk_source_buffer_context_t context;
      gint indent, current_indent;
      GtkTextIter iter, start_iter, end_iter;

      memset (&context, 0, sizeof (smie_gtk_source_buffer_context_t));
      context.buffer = window->buffer;
      mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (window->buffer));
      gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (window->buffer),
					&iter,
					mark);
      gtk_text_iter_assign (&context.iter, &iter);
      indent = smie_indenter_calculate (window->indenter, &context);
      if (indent < 0)
	{
	  g_printf ("indent: undetermined\n");
	  return TRUE;
	}
      else
	g_printf ("indent: %d\n", indent);

      /* Point START_ITER to the beginning of the line.  */
      gtk_text_iter_assign (&start_iter, &iter);
      while (!gtk_text_iter_is_start (&start_iter)
	     && !gtk_text_iter_starts_line (&start_iter)
	     && gtk_text_iter_backward_char (&start_iter))
	;

      /* Point END_ITER to the end of the indent and count the offset.  */
      gtk_text_iter_assign (&end_iter, &start_iter);
      current_indent = 0;
      while (!gtk_text_iter_is_end (&end_iter)
	     && !gtk_text_iter_ends_line (&end_iter)
	     && g_unichar_isspace (gtk_text_iter_get_char (&end_iter))
	     && gtk_text_iter_forward_char (&end_iter))
	current_indent++;

      /* Replace the current indent if it doesn't match the computed one.  */
      if (indent < current_indent)
	{
	  gtk_text_iter_forward_chars (&start_iter, indent);
	  gtk_text_buffer_delete (GTK_TEXT_BUFFER (window->buffer),
				  &start_iter, &end_iter);
	}
      else if (indent > current_indent)
	{
	  gchar *text = g_new0 (gchar, indent - current_indent);
	  memset (text, ' ', indent * sizeof (gchar));
	  gtk_text_buffer_insert (GTK_TEXT_BUFFER (window->buffer),
				  &start_iter,
				  text,
				  indent - current_indent);
	  g_free (text);
	}
      return TRUE;
    }
  return GTK_WIDGET_CLASS (editor_application_window_parent_class)->key_press_event (widget, event);
}
Exemplo n.º 10
0
gdouble get_selection_font_size(GtkTextBuffer *text_buffer, GtkTextView *text_view)
{
	// Local variables
	GtkTextIter				end_iter;
	gfloat					font_size;			// Used for calculating the font size of a character
	gint					font_size_int;		// Used for retrieving the size of a character in a text layer
	gfloat					iter_size;			// The size of the present character
	GtkTextAttributes		*text_attributes;	// Pointer to the attributes for a text layer character
	GtkTextIter				first_iter;


	// Retrieve the selection start and end iters
	gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(text_buffer), &first_iter, &end_iter);

	// If the start iter is not at the start of the text buffer, we move it back one character to get an accurate value
	if (FALSE == gtk_text_iter_is_start(&first_iter))
	{
		gtk_text_iter_backward_char(&first_iter);
	}

	// Unless the start and end iters are at the same place, move the end iter back one so we
	// get an accurate value
	if (FALSE == gtk_text_iter_equal(&first_iter, &end_iter))
	{
		gtk_text_iter_backward_char(&end_iter);
	}

	// Determine the font size at the selection start iter
	text_attributes = gtk_text_view_get_default_attributes(GTK_TEXT_VIEW(text_view));
	gtk_text_iter_get_attributes(&first_iter, text_attributes);
	font_size_int = pango_font_description_get_size(text_attributes->font);
	font_size_int *= 10;
	font_size = roundf(((gfloat) font_size_int) / PANGO_SCALE);
	font_size /= 10;

	// Step through the text buffer character by character,
	// checking if the font size has changed
	while (FALSE == gtk_text_iter_equal(&first_iter, &end_iter))
	{
		// Move forward one iter
		gtk_text_iter_forward_char(&first_iter);

		// Get the font size at this new iter
		text_attributes = gtk_text_view_get_default_attributes(GTK_TEXT_VIEW(text_view));
		gtk_text_iter_get_attributes(&first_iter, text_attributes);
		font_size_int = pango_font_description_get_size(text_attributes->font);
		font_size_int *= 10;
		iter_size = roundf(((gfloat) font_size_int) / PANGO_SCALE);
		iter_size /= 10;

		// If the font size value is different to the original size,
		// then we short circuit the loop and return -1.0
		if (font_size != iter_size)
		{
			return -1.0;
		}
	}

	// We've reached the end of the selection, and the selection font size
	// has been the same the whole way.  We return that font size.
	return font_size;
}