Exemple #1
0
/*
 * A special insert used as the undo of delete char (C-d or DEL)
 * this is where the char is inserted at the point and the cursor
 * is NOT moved on 1 char.  This MUST be a seperate function so that
 *   INSERT + BACKSPACE are matching undo pairs
 *   INSERT_AT + DELETE are matching undo pairs
 * Note: This function is only ever called by execute_undo to undo a DEL.
 */
void insert_at()
{
	char_t the_char[2]; /* the inserted char plus a null */
	assert(curbp->b_gap <= curbp->b_egap);

	if (curbp->b_gap == curbp->b_egap && !growgap(curbp, CHUNK))
		return;
	curbp->b_point = movegap(curbp, curbp->b_point);


	/* overwrite if mid line, not EOL or EOF, CR will insert as normal */
	if ((curbp->b_flags & B_OVERWRITE) && *input != '\r' && *(ptr(curbp, curbp->b_point)) != '\n' && curbp->b_point < pos(curbp,curbp->b_ebuf) ) {
		*(ptr(curbp, curbp->b_point)) = *input;
		if (curbp->b_point < pos(curbp, curbp->b_ebuf))
			++curbp->b_point;
		/* FIXME - overwite mode not handled properly for undo yet */
	} else {
		the_char[0] = *input == '\r' ? '\n' : *input;
		the_char[1] = '\0'; /* null terminate */
		*curbp->b_gap++ = the_char[0];
		curbp->b_point = pos(curbp, curbp->b_egap);
		curbp->b_point--; /* move point back to where it was before, should always be safe */
		/* the point is set so that and undo will DELETE the char */
		add_undo(curbp, UNDO_T_INSAT, curbp->b_point, the_char, NULL);
	}

	add_mode(curbp, B_MODIFIED);
}
Exemple #2
0
/* Copy text from the cutbuffer into the current filestruct. */
void do_uncut_text(void)
{
    assert(openfile->current != NULL && openfile->current->data != NULL);

    /* If the cutbuffer is empty, get out. */
    if (cutbuffer == NULL)
	return;

    add_undo(PASTE);

    /* Add a copy of the text in the cutbuffer to the current filestruct
     * at the current cursor position. */
    copy_from_filestruct(cutbuffer);

    update_undo(PASTE);

    /* Set the current place we want to where the text from the
     * cutbuffer ends. */
    openfile->placewewant = xplustabs();

    /* Mark the file as modified. */
    set_modified();

    /* Update the screen. */
    edit_refresh_needed = TRUE;

#ifndef DISABLE_COLOR
    reset_multis(openfile->current, FALSE);
#endif

#ifdef DEBUG
    dump_filestruct_reverse();
#endif
}
Exemple #3
0
/* Move text from the current filestruct into the cutbuffer. */
void do_cut_text_void(void)
{
#ifndef NANO_TINY
    add_undo(CUT);
#endif
    do_cut_text(FALSE, FALSE);
#ifndef NANO_TINY
    update_undo(CUT);
#endif
}
Exemple #4
0
Fichier : cut.c Projet : ris21/yoda
/* Move text from the current linestruct into the cutbuffer. */
void do_cut_text_void(void)
{
#ifndef NANO_TINY
    add_undo(CUT);
#endif
    do_cut_text(
#ifndef NANO_TINY
	FALSE, FALSE, FALSE
#endif
	);
}
Exemple #5
0
void backspace()
{
	char_t the_char[7]; /* the deleted char, allow 6 unsigned chars plus a null */
	int n = prev_utf8_char_size();

	curbp->b_point = movegap(curbp, curbp->b_point);

	if (curbp->b_buf < (curbp->b_gap - (n - 1)) ) {
		curbp->b_gap -= n; /* increase start of gap by size of char */
		add_mode(curbp, B_MODIFIED);

		/* record the backspaced chars in the undo structure */
		memcpy(the_char, curbp->b_gap, n);
		the_char[n] = '\0'; /* null terminate, the backspaced char(s) */
		curbp->b_point = pos(curbp, curbp->b_egap);
		//debug("point after bs = %ld\n", curbp->b_point);
		add_undo(curbp, UNDO_T_BACKSPACE, curbp->b_point, the_char, NULL);
	}

	curbp->b_point = pos(curbp, curbp->b_egap);
}
Exemple #6
0
Fichier : cut.c Projet : ris21/yoda
/* Cut from the current cursor position to the end of the file. */
void do_cut_till_eof(void)
{
    add_undo(CUT_EOF);
    do_cut_text(FALSE, TRUE, FALSE);
}
Exemple #7
0
/* Step through each replace word and prompt user before replacing.
 * Parameters real_current and real_current_x are needed in order to
 * allow the cursor position to be updated when a word before the cursor
 * is replaced by a shorter word.
 *
 * needle is the string to seek.  We replace it with answer.  Return -1
 * if needle isn't found, else the number of replacements performed.  If
 * canceled isn't NULL, set it to TRUE if we canceled. */
ssize_t do_replace_loop(
#ifndef DISABLE_SPELLER
	bool whole_word_only,
#endif
	bool *canceled, const linestruct *real_current, size_t
	*real_current_x, const char *needle)
{
    ssize_t numreplaced = -1;
    size_t match_len;
    bool replaceall = FALSE;
#ifndef NANO_TINY
    bool old_mark_set = openfile->mark_set;
    linestruct *top, *bot;
    size_t top_x, bot_x;
    bool right_side_up = FALSE;
	/* TRUE if (mark_begin, mark_begin_x) is the top of the mark,
	 * FALSE if (current, current_x) is. */

    if (old_mark_set) {
	/* If the mark is on, frame the region, and turn the mark off. */
	mark_order((const linestruct **)&top, &top_x,
	    (const linestruct **)&bot, &bot_x, &right_side_up);
	openfile->mark_set = FALSE;

	/* Start either at the top or the bottom of the marked region. */
	if (!ISSET(BACKWARDS_SEARCH)) {
	    openfile->current = top;
	    openfile->current_x = (top_x == 0 ? 0 : top_x - 1);
	} else {
	    openfile->current = bot;
	    openfile->current_x = bot_x;
	}
    }
#endif /* !NANO_TINY */

    if (canceled != NULL)
	*canceled = FALSE;

    findnextstr_wrap_reset();
    while (findnextstr(
#ifndef DISABLE_SPELLER
	whole_word_only,
#endif
	real_current, *real_current_x, needle, &match_len)) {
	int i = 0;

#ifndef NANO_TINY
	if (old_mark_set) {
	    /* When we've found an occurrence outside of the marked region,
	     * stop the fanfare. */
	    if (openfile->current->lineno > bot->lineno ||
		openfile->current->lineno < top->lineno ||
		(openfile->current == bot && openfile->current_x > bot_x) ||
		(openfile->current == top && openfile->current_x < top_x))
		break;
	}
#endif

	/* Indicate that we found the search string. */
	if (numreplaced == -1)
	    numreplaced = 0;

	if (!replaceall) {
	    size_t xpt = xplustabs();
	    char *exp_word = display_string(openfile->current->data,
		xpt, strnlenpt(openfile->current->data,
		openfile->current_x + match_len) - xpt, FALSE);

	    edit_refresh();

	    curs_set(0);

	    do_replace_highlight(TRUE, exp_word);

	    /* TRANSLATORS: This is a prompt. */
	    i = do_yesno_prompt(TRUE, _("Replace this instance?"));

	    do_replace_highlight(FALSE, exp_word);

	    free(exp_word);

	    curs_set(1);

	    if (i == -1) {	/* We canceled the replace. */
		if (canceled != NULL)
		    *canceled = TRUE;
		break;
	    }
	}

	if (i > 0 || replaceall) {	/* Yes, replace it!!!! */
	    char *copy;
	    size_t length_change;

#ifndef NANO_TINY
	    add_undo(REPLACE);
#endif
	    if (i == 2)
		replaceall = TRUE;

	    copy = replace_line(needle);

	    length_change = strlen(copy) - strlen(openfile->current->data);

#ifndef NANO_TINY
	    /* If the mark was on and (mark_begin, mark_begin_x) was the
	     * top of it, don't change mark_begin_x. */
	    if (!old_mark_set || !right_side_up) {
		/* Keep mark_begin_x in sync with the text changes. */
		if (openfile->current == openfile->mark_begin &&
			openfile->mark_begin_x > openfile->current_x) {
		    if (openfile->mark_begin_x < openfile->current_x +
			match_len)
			openfile->mark_begin_x = openfile->current_x;
		    else
			openfile->mark_begin_x += length_change;
		    bot_x = openfile->mark_begin_x;
		}
	    }

	    /* If the mark was on and (current, current_x) was the top
	     * of it, don't change real_current_x. */
	    if (!old_mark_set || right_side_up) {
#endif
		/* Keep real_current_x in sync with the text changes. */
		if (openfile->current == real_current &&
			openfile->current_x <= *real_current_x) {
		    if (*real_current_x < openfile->current_x + match_len)
			*real_current_x = openfile->current_x + match_len;
		    *real_current_x += length_change;
#ifndef NANO_TINY
		    bot_x = *real_current_x;
		}
#endif
	    }

	    /* Set the cursor at the last character of the replacement
	     * text, so searching will resume after the replacement
	     * text.  Note that current_x might be set to (size_t)-1
	     * here. */
#ifndef NANO_TINY
	    if (!ISSET(BACKWARDS_SEARCH))
#endif
		openfile->current_x += match_len + length_change - 1;

	    /* Clean up. */
	    openfile->totsize += mbstrlen(copy) -
		mbstrlen(openfile->current->data);
	    free(openfile->current->data);
	    openfile->current->data = copy;

#ifndef DISABLE_COLOR
	    /* Reset the precalculated multiline-regex hints only when
	     * the first replacement has been made. */
	    if (numreplaced == 0)
		reset_multis(openfile->current, TRUE);
#endif

	    if (!replaceall) {
#ifndef DISABLE_COLOR
		/* If color syntaxes are available and turned on, we
		 * need to call edit_refresh(). */
		if (openfile->colorstrings != NULL &&
			!ISSET(NO_COLOR_SYNTAX))
		    edit_refresh();
		else
#endif
		    update_line(openfile->current, openfile->current_x);
	    }

	    set_modified();
	    numreplaced++;
	}
    }

    if (numreplaced == -1)
	not_found_msg(needle);

#ifndef NANO_TINY
    if (old_mark_set)
	openfile->mark_set = TRUE;
#endif

    /* If the NO_NEWLINES flag isn't set, and text has been added to the
     * magicline, make a new magicline. */
    if (!ISSET(NO_NEWLINES) && openfile->filebot->data[0] != '\0')
	new_magicline();

    return numreplaced;
}
Exemple #8
0
/* Move text from the current filestruct into the cutbuffer. */
void do_cut_text_void(void)
{
    add_undo(CUT);
    do_cut_text(FALSE, FALSE, FALSE);
}
Exemple #9
0
static bool sokoban_loop(void)
{
    char new_spot;
    bool moved = true;
    int i = 0, button = 0, lastbutton = 0;
    short r = 0, c = 0;

    current_info.level.level = 1;

    load_level();
    update_screen();

    while (1) {
        moved = true;

        r = current_info.player.row;
        c = current_info.player.col;

        button = rb->button_get(true);

        add_undo(button);

        switch(button)
        {
        case BUTTON_OFF:
            /* get out of here */
            return PLUGIN_OK;

        case SOKOBAN_UNDO:
#ifdef SOKOBAN_UNDO_PRE
            if (lastbutton != SOKOBAN_UNDO_PRE)
                break;
#else       /* repeat can't work here for Ondio */
        case SOKOBAN_UNDO | BUTTON_REPEAT:
#endif
            /* this is UNDO */
            undo();
            rb->lcd_clear_display();
            update_screen();
            moved = false;
            break;

        case SOKOBAN_LEVEL_UP:
        case SOKOBAN_LEVEL_UP | BUTTON_REPEAT:
            /* increase level */
            init_undo();
            current_info.level.boxes_to_go=0;
            moved = true;
            break;

        case SOKOBAN_LEVEL_DOWN:
        case SOKOBAN_LEVEL_DOWN | BUTTON_REPEAT:
            /* previous level */
            init_undo();
            if (current_info.level.level > 1)
                current_info.level.level--;

            draw_level();
            moved = false;
            break;

        case SOKOBAN_LEVEL_REPEAT:
        case SOKOBAN_LEVEL_REPEAT | BUTTON_REPEAT:
            /* same level */
            init_undo();
            draw_level();
            moved = false;
            break;

        case BUTTON_LEFT:
            switch(current_info.board[r][c-1])
            {
            case ' ': /* if it is a blank spot */
            case '.': /* if it is a home spot */
                new_spot = current_info.board[r][c-1];
                current_info.board[r][c-1] = '@';
                current_info.board[r][c] = current_info.player.spot;
                current_info.player.spot = new_spot;
                break;

            case '$':
                switch(current_info.board[r][c-2])
                {
                case ' ': /* going from blank to blank */
                    current_info.board[r][c-2] = current_info.board[r][c-1];
                    current_info.board[r][c-1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    break;

                case '.': /* going from a blank to home */
                    current_info.board[r][c-2] = '%';
                    current_info.board[r][c-1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    current_info.level.boxes_to_go--;
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            case '%':
                switch(current_info.board[r][c-2]) {
                case ' ': /* we are going from a home to a blank */
                    current_info.board[r][c-2] = '$';
                    current_info.board[r][c-1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    current_info.level.boxes_to_go++;
                    break;

                case '.': /* if we are going from a home to home */
                    current_info.board[r][c-2] = '%';
                    current_info.board[r][c-1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            default:
                moved = false;
                break;
            }

            if (moved)
                current_info.player.col--;
            break;

        case BUTTON_RIGHT: /* if it is a blank spot */
            switch(current_info.board[r][c+1]) {
            case ' ':
            case '.': /* if it is a home spot */
                new_spot = current_info.board[r][c+1];
                current_info.board[r][c+1] = '@';
                current_info.board[r][c] = current_info.player.spot;
                current_info.player.spot = new_spot;
                break;

            case '$':
                switch(current_info.board[r][c+2]) {
                case ' ': /* going from blank to blank */
                    current_info.board[r][c+2] = current_info.board[r][c+1];
                    current_info.board[r][c+1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    break;

                case '.': /* going from a blank to home */
                    current_info.board[r][c+2] = '%';
                    current_info.board[r][c+1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    current_info.level.boxes_to_go--;
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            case '%':
                switch(current_info.board[r][c+2]) {
                case ' ': /* going from a home to a blank */
                    current_info.board[r][c+2] = '$';
                    current_info.board[r][c+1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    current_info.level.boxes_to_go++;
                    break;

                case '.':
                    current_info.board[r][c+2] = '%';
                    current_info.board[r][c+1] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            default:
                moved = false;
                break;
            }

            if (moved)
                current_info.player.col++;
            break;

        case BUTTON_UP:
            switch(current_info.board[r-1][c]) {
            case ' ': /* if it is a blank spot */
            case '.': /* if it is a home spot */
                new_spot = current_info.board[r-1][c];
                current_info.board[r-1][c] = '@';
                current_info.board[r][c] = current_info.player.spot;
                current_info.player.spot = new_spot;
                break;

            case '$':
                switch(current_info.board[r-2][c]) {
                case ' ': /* going from blank to blank */
                    current_info.board[r-2][c] = current_info.board[r-1][c];
                    current_info.board[r-1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    break;

                case '.': /* going from a blank to home */
                    current_info.board[r-2][c] = '%';
                    current_info.board[r-1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    current_info.level.boxes_to_go--;
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            case '%':
                switch(current_info.board[r-2][c]) {
                case ' ': /* we are going from a home to a blank */
                    current_info.board[r-2][c] = '$';
                    current_info.board[r-1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    current_info.level.boxes_to_go++;
                    break;

                case '.': /* if we are going from a home to home */
                    current_info.board[r-2][c] = '%';
                    current_info.board[r-1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            default:
                moved = false;
                break;
            }

            if (moved)
                current_info.player.row--;
            break;

        case BUTTON_DOWN:
            switch(current_info.board[r+1][c]) {
            case ' ': /* if it is a blank spot */
            case '.': /* if it is a home spot */
                new_spot = current_info.board[r+1][c];
                current_info.board[r+1][c] = '@';
                current_info.board[r][c] = current_info.player.spot;
                current_info.player.spot = new_spot;
                break;

            case '$':
                switch(current_info.board[r+2][c]) {
                case ' ': /* going from blank to blank */
                    current_info.board[r+2][c] = current_info.board[r+1][c];
                    current_info.board[r+1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    break;

                case '.': /* going from a blank to home */
                    current_info.board[r+2][c] = '%';
                    current_info.board[r+1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = ' ';
                    current_info.level.boxes_to_go--;
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            case '%':
                switch(current_info.board[r+2][c]) {
                case ' ': /* going from a home to a blank */
                    current_info.board[r+2][c] = '$';
                    current_info.board[r+1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    current_info.level.boxes_to_go++;
                    break;

                case '.': /* going from a home to home */
                    current_info.board[r+2][c] = '%';
                    current_info.board[r+1][c] = current_info.board[r][c];
                    current_info.board[r][c] = current_info.player.spot;
                    current_info.player.spot = '.';
                    break;

                default:
                    moved = false;
                    break;
                }
                break;

            default:
                moved = false;
                break;
            }

            if (moved)
                current_info.player.row++;
            break;

        default:
            if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
                return PLUGIN_USB_CONNECTED;

            moved = false;
            break;
        }

        if (button != BUTTON_NONE)
            lastbutton = button;

        if (moved) {
            current_info.level.moves++;
            rb->lcd_clear_display();
            update_screen();
        }

        /* We have completed this level */
        if (current_info.level.boxes_to_go == 0) {
            current_info.level.level++;

            /* clear undo stats */
            init_undo();

            rb->lcd_clear_display();

            if (current_info.level.level > current_info.max_level) {
                rb->lcd_putsxy(10, 20, "You WIN!!");

                rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
                for (i = 0; i < 30000 ; i++) {
                    rb->lcd_fillrect(0, 0, 111, 63);
                    rb->lcd_update();

                    button = rb->button_get(false);
                    if (button && ((button & BUTTON_REL) != BUTTON_REL))
                        break;
                }
                rb->lcd_set_drawmode(DRMODE_SOLID);

                return PLUGIN_OK;
            }

            load_level();
            update_screen();
        }

    } /* end while */

    return PLUGIN_OK;
}