示例#1
0
文件: console.c 项目: aylusltd/gretl
static gchar *console_get_current_line (GtkTextBuffer *buf,
					GtkTextIter *iter)
{
    GtkTextIter start, end;

    start = end = *iter;
    gtk_text_iter_set_line_index(&start, 2);
    gtk_text_iter_forward_to_line_end(&end);

    return gtk_text_buffer_get_text(buf, &start, &end, FALSE);
}
示例#2
0
/* vers=0: right == NOOPS*/
static void doc_shift_selection( Tdocument *doc, gboolean vers ) {
	GtkTextIter itstart, itend;
	if ( gtk_text_buffer_get_selection_bounds( doc->buffer, &itstart, &itend ) ) {
		GtkTextMark * end;

		doc_unbind_signals( doc );
		doc_unre_new_group( doc );
		/* we have a selection, now we loop trough the characters, and for every newline
		we add or remove a tab, we set the end with a mark */
		end = gtk_text_buffer_create_mark( doc->buffer, NULL, &itend, TRUE );
		/* set to: the fist char of the fist line */
		if ( gtk_text_iter_get_line_offset( &itstart ) > 0 ) {
			gtk_text_iter_set_line_index( &itstart, 0 );
		}
		/* remove one line from current selection for each step*/
		while ( gtk_text_iter_compare( &itstart, &itend ) < 0 ) {
			GtkTextMark * cur;
			cur = gtk_text_buffer_create_mark( doc->buffer, NULL, &itstart, TRUE );
			if ( vers ) {
				itend = itstart;
				gtk_text_iter_forward_chars( &itend, 1 );
				gchar *buf = gtk_text_buffer_get_text( doc->buffer, &itstart, &itend, FALSE );
				if ( !strstr( buf, "\n" ) ) {
					gint offsetstart, offsetend;
					offsetstart = gtk_text_iter_get_offset( &itstart );
					offsetend = gtk_text_iter_get_offset( &itend );
					gtk_text_buffer_delete( doc->buffer, &itstart, &itend );
					doc_unre_add( doc, buf, offsetstart, offsetend, UndoDelete );
				}
				g_free( buf );
			}
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itstart, cur );
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itend, end );
			gtk_text_buffer_delete_mark( doc->buffer, cur );
			/* forward one more line */
			gtk_text_iter_forward_line( &itstart );
		}
		gtk_text_buffer_delete_mark( doc->buffer, end );
		doc_bind_signals( doc );
		doc_set_modified( doc, 1 );
	} else {
		/* there is no selection, work on the current line */
		GtkTextIter iter;
		gtk_text_buffer_get_iter_at_mark( doc->buffer, &iter, gtk_text_buffer_get_insert( doc->buffer ) );
		if ( vers ) {
			GtkTextIter itend;
			gtk_text_iter_set_line_offset( &iter, 0 );
			itend = iter;
			gtk_text_iter_forward_chars( &itend, 1 );
			gtk_text_buffer_delete( doc->buffer, &iter, &itend );
		}
	}
}
示例#3
0
/* original version taken from bluefish's (doc_indent_selection) */
gint func_indent( GtkWidget *widget, GdkEventKey *kevent, Tbfwin *bfwin, gint opt) {
	Tdocument *doc = bfwin->current_document;
	if (!doc) return 0;

	gint unindent = opt & FUNC_VALUE_0;

	GtkTextIter itstart, itend;
	if ( gtk_text_buffer_get_selection_bounds( doc->buffer, &itstart, &itend ) ) {
		GtkTextMark * end;
		doc_unbind_signals( doc );
		doc_unre_new_group( doc );
		/* we have a selection, now we loop trough the characters, and for every newline
		we add or remove a tab, we set the end with a mark */
		end = gtk_text_buffer_create_mark( doc->buffer, NULL, &itend, TRUE );
		if ( gtk_text_iter_get_line_offset( &itstart ) > 0 ) {
			gtk_text_iter_set_line_index( &itstart, 0 );
		}
		while ( gtk_text_iter_compare( &itstart, &itend ) < 0 ) {
			GtkTextMark * cur;
			cur = gtk_text_buffer_create_mark( doc->buffer, NULL, &itstart, TRUE );
			if ( unindent ) {
				/* when unindenting we try to set itend to the end of the indenting step
				which might be a tab or 'tabsize' spaces, then we delete that part */
				gboolean cont = TRUE;
				gchar *buf = NULL;
				gunichar cchar = gtk_text_iter_get_char( &itstart );
				if ( cchar == 9 ) { /* 9 is ascii for tab */
					itend = itstart;
					cont = gtk_text_iter_forward_char( &itend );
					buf = g_strdup( "\t" );
				} else if ( cchar == 32 ) { /* 32 is ascii for space */
					gint i = 0;
					itend = itstart;
					gtk_text_iter_forward_chars( &itend, main_v->props.editor_tab_width );
					buf = gtk_text_buffer_get_text( doc->buffer, &itstart, &itend, FALSE );
					DEBUG_MSG( "func_indent: tab_width=%d, strlen(buf)=%d, buf='%s'\n", main_v->props.editor_tab_width, strlen( buf ), buf );
					while ( cont && buf[ i ] != '\0' ) {
						cont = ( buf[ i ] == ' ' );
						DEBUG_MSG( "func_indent: buf[%d]='%c'\n", i, buf[ i ] );
						i++;
					}
					if ( !cont ) {
						g_free ( buf );
					}
				} else {
					cont = FALSE;
				}
				if ( cont ) {
					gint offsetstart, offsetend;
					offsetstart = gtk_text_iter_get_offset( &itstart );
					offsetend = gtk_text_iter_get_offset( &itend );
					gtk_text_buffer_delete( doc->buffer, &itstart, &itend );
					doc_unre_add( doc, buf, offsetstart, offsetend, UndoDelete );
					g_free ( buf );
				}
			} else { /* indent */
				gint offsetstart = gtk_text_iter_get_offset( &itstart );
				gchar *indentstring;
				gint indentlen;
				if ( main_v->props.view_bars & MODE_INDENT_WITH_SPACES ) {
					indentstring = bf_str_repeat( " ", main_v->props.editor_tab_width );
					indentlen = main_v->props.editor_tab_width;
				} else {
					indentstring = g_strdup( "\t" );
					indentlen = 1;
				}
				gtk_text_buffer_insert( doc->buffer, &itstart, indentstring, indentlen );
				doc_unre_add( doc, indentstring, offsetstart, offsetstart + indentlen, UndoInsert );
				g_free( indentstring );
			}
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itstart, cur );
			gtk_text_buffer_get_iter_at_mark( doc->buffer, &itend, end );
			gtk_text_buffer_delete_mark( doc->buffer, cur );
			gtk_text_iter_forward_line( &itstart );
			DEBUG_MSG( "func_indent: itstart at %d, itend at %d\n", gtk_text_iter_get_offset( &itstart ), gtk_text_iter_get_offset( &itend ) );
		}
		gtk_text_buffer_delete_mark( doc->buffer, end );
		doc_bind_signals( doc );
		doc_set_modified( doc, 1 );
	} else {
		/* there is no selection, work on the current line */
		GtkTextIter iter;
		gtk_text_buffer_get_iter_at_mark( doc->buffer, &iter, gtk_text_buffer_get_insert( doc->buffer ) );
		gtk_text_iter_set_line_offset( &iter, 0 );
		if ( unindent ) {
			gint deletelen = 0;
			gchar *tmpstr, *tmp2str;
			GtkTextIter itend = iter;
			gtk_text_iter_forward_chars( &itend, main_v->props.editor_tab_width );
			tmpstr = gtk_text_buffer_get_text( doc->buffer, &iter, &itend, FALSE );
			tmp2str = bf_str_repeat( " ", main_v->props.editor_tab_width );
			if ( tmpstr[ 0 ] == '\t' ) {
				deletelen = 1;
			} else if ( tmpstr && strncmp( tmpstr, tmp2str, main_v->props.editor_tab_width ) == 0 ) {
				deletelen = main_v->props.editor_tab_width;
			}
			g_free( tmpstr );
			g_free( tmp2str );
			if ( deletelen ) {
				itend = iter;
				gtk_text_iter_forward_chars( &itend, deletelen );
				gtk_text_buffer_delete( doc->buffer, &iter, &itend );
			}
		} else { /* indent */
			gchar *indentstring;
			gint indentlen;
			if ( main_v->props.view_bars & MODE_INDENT_WITH_SPACES ) {
				indentstring = bf_str_repeat( " ", main_v->props.editor_tab_width );
				indentlen = main_v->props.editor_tab_width;
			} else {
				indentstring = g_strdup( "\t" );
				indentlen = 1;
			}
			gtk_text_buffer_insert( doc->buffer, &iter, indentstring, indentlen );
			g_free( indentstring );
		}
	}
	return 1;
}
示例#4
0
文件: console.c 项目: aylusltd/gretl
static gint console_key_handler (GtkWidget *cview, GdkEventKey *event, 
				 gpointer p)
{
    guint keyval = event->keyval;
    guint upkey = gdk_keyval_to_upper(keyval);
    GtkTextIter ins, end;
    GtkTextBuffer *buf;
    GtkTextMark *mark;
    gint ctrl = 0;

#ifdef MAC_NATIVE
    if (cmd_key(event)) {
	if (upkey == GDK_C || upkey == GDK_X) {
	    /* allow regular copy/cut behavior */
	    return FALSE;
	}
    }	
#endif

    if (event->state & GDK_CONTROL_MASK) {
	if (keyval == GDK_Control_L || keyval == GDK_Control_R) {
	    return FALSE;
	} else if (upkey == GDK_C || upkey == GDK_X) {
	    /* allow regular copy/cut behavior */
	    return FALSE;
	} else {
	    ctrl = 1;
	}
    }

    buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(cview));

    /* first find out where the insertion point and end are */
    mark = gtk_text_buffer_get_insert(buf);
    gtk_text_buffer_get_iter_at_mark(buf, &ins, mark);
    gtk_text_buffer_get_end_iter(buf, &end);

    /* if the insertion point is not on the last line, move it */
    if (gtk_text_iter_get_line(&ins) != gtk_text_iter_get_line(&end)) {
	gtk_text_buffer_place_cursor(buf, &end);
	gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(cview), TRUE);
	gtk_text_buffer_get_end_iter(buf, &ins);
    }

    if (keyval == GDK_Home && (event->state & GDK_SHIFT_MASK)) {
	/* "select to start of line" */
	GtkTextIter start = ins;

	gtk_text_iter_set_line_index(&start, 2);	
	gtk_text_buffer_select_range(buf, &start, &ins);
	return TRUE;
    }

    if (IS_BACKKEY(keyval)) {
	/* if we're at the start of the input line, block backspacing */
	if (gtk_text_iter_get_line_index(&ins) < 3) {
	    return TRUE;
	}
    } else if (keyval == GDK_Home || (ctrl && upkey == GDK_A)) {
	/* go to start of typing area */
	gtk_text_iter_set_line_index(&ins, 2);	
	gtk_text_buffer_place_cursor(buf, &ins);
	return TRUE;
    } 

    /* At this point 'ins' indicates the insertion point and
       'end' points to the end of the current line of input,
       These may or may not be the same thing.
    */

    if (keyval == GDK_Return) {
	/* execute the command, unless backslash-continuation 
	   is happening */
	ExecState *state;
	gchar *thisline;
	int contd = 0, err = 0;

	state = g_object_get_data(G_OBJECT(cview), "ExecState");
	thisline = console_get_current_line(buf, &ins);

	if (thisline != NULL) {
	    g_strstrip(thisline);
	    contd = command_continues(state->line, thisline, &err);
	    g_free(thisline);
	}

	if (err) {
	    gui_errmsg(err);
	} else if (contd) {
	    console_insert_prompt(buf, &end, "\n> ");
	    console_scroll_to_end(cview, buf, &end);
	} else {
	    /* request execution of the completed command */
	    command_entered = 1;
	}

	event->keyval = GDK_End;
	return FALSE;
    }

    if (keyval == GDK_Up || keyval == GDK_Down) {
	/* up/down arrows: navigate the command history */
	GtkTextIter start = ins;
	const char *histline;

	if (hpos == hlines && keyval == GDK_Up) {
	    g_free(hist0);
	    hist0 = console_get_current_line(buf, &ins);
	}

	histline = fetch_history_line(keyval);

	if (histline != NULL || keyval == GDK_Down) {
	    gtk_text_iter_set_line_index(&start, 2);
	    gtk_text_buffer_delete(buf, &start, &end);
	    if (histline != NULL) {
		gtk_text_buffer_insert(buf, &start, histline, -1);
	    } else if (hpos == hlines && hist0 != NULL) {
		gtk_text_buffer_insert(buf, &start, hist0, -1);
	    }
	}

	return TRUE;
    }

    if (keyval == GDK_Tab) {
	/* tab completion for gretl commands, variable names */
	return console_complete_word(buf, &ins);
    } 

    return FALSE;
}