示例#1
0
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    PromptBuf *prt = self->promptbuf;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    /* BACKSPACE key: Remove one character from line */
    if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (prt->pos > 0) {
            del_char_buf_bck(prt->line, &prt->pos, &prt->len);
            wmove(self->window, y, x-1);    /* not necessary but fixes a display glitch */
            prt->scroll = false;
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (prt->pos != prt->len) {
            del_char_buf_frnt(prt->line, &prt->pos, &prt->len);
            prt->scroll = false;
        } else {
            beep();
        }
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (prt->pos > 0) {
            wmove(self->window, prt->orig_y, X_OFST);
            wclrtobot(self->window);
            discard_buf(prt->line, &prt->pos, &prt->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (prt->len != prt->pos)
            kill_buf(prt->line, &prt->pos, &prt->len);
        else
            beep();
    }

    else if (key == KEY_HOME || key == T_KEY_C_A) {  /* HOME/C-a key: Move cursor to start of line */
        if (prt->pos != 0)
            prt->pos = 0;
    }

    else if (key == KEY_END || key == T_KEY_C_E) {   /* END/C-e key: move cursor to end of line */
        if (prt->pos != prt->len)
            prt->pos = prt->len;
    }

    else if (key == KEY_LEFT) {
        if (prt->pos > 0)
            --prt->pos;
        else
            beep();
    } 

    else if (key == KEY_RIGHT) {
        if (prt->pos < prt->len)
            ++prt->pos;
        else 
            beep();
    } 

    else if (key == KEY_UP) {     /* fetches previous item in history */
        wmove(self->window, prt->orig_y, X_OFST);
        fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, prt->hst_tot,
                        &prt->hst_pos, LN_HIST_MV_UP);

        /* adjust line y origin appropriately when window scrolls down */
        if (prt->at_bottom && prt->len >= x2 - X_OFST) {
            int px2 = prt->len >= x2 ? x2 : x2 - X_OFST;
            int p_ofst = px2 != x2 ? 0 : X_OFST;

            if (px2 <= 0)
                return;

            int k = prt->orig_y + ((prt->len + p_ofst) / px2);

            if (k >= y2) {
                wprintw(self->window, "\n");
                --prt->orig_y;
            }
        }
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        wmove(self->window, prt->orig_y, X_OFST);
        fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, prt->hst_tot,
                        &prt->hst_pos, LN_HIST_MV_DWN);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (prt->len > 1 && prt->line[0] == '/') {
            if (complete_line(prt->line, &prt->pos, &prt->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS,
                              MAX_CMDNAME_SIZE) == -1) 
                beep();
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {
        if (prt->len < (MAX_STR_SIZE-1)) {
            add_char_to_buf(prt->line, &prt->pos, &prt->len, key);
            prt->scroll = true;
        }
    }
    /* RETURN key: execute command */
    else if (key == '\n') {
        wprintw(self->window, "\n");
        uint8_t line[MAX_STR_SIZE];

        if (wcs_to_mbs_buf(line, prt->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(prt->line, prt->len, prt->ln_history, &prt->hst_tot, &prt->hst_pos);

        execute(self->window, self, m, line, GLOBAL_COMMAND_MODE);
        reset_buf(prt->line, &prt->pos, &prt->len);
    }
}
示例#2
0
文件: prompt.c 项目: Kuronogard/toxic
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(ctx->history, y, x);
    getmaxyx(ctx->history, y2, x2);

    /* this is buggy */
    //if (key == T_KEY_ESC) {   /* ESC key: Toggle history scroll mode */
    //    bool scroll = ctx->hst->scroll_mode ? false : true;
    //    line_info_toggle_scroll(self, scroll);
    //}

    /* If we're in scroll mode ignore rest of function */
    if (ctx->hst->scroll_mode) {
        line_info_onKey(self, key);
        return;
    }

    /* BACKSPACE key: Remove one character from line */
    if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
            wmove(ctx->history, y, x-1);    /* not necessary but fixes a display glitch */
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (ctx->pos != ctx->len) {
            del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (ctx->pos > 0) {
            wmove(ctx->history, ctx->orig_y, X_OFST);
            wclrtobot(ctx->history);
            discard_buf(ctx->line, &ctx->pos, &ctx->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (ctx->len != ctx->pos)
            kill_buf(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == KEY_HOME || key == T_KEY_C_A) {  /* HOME/C-a key: Move cursor to start of line */
        if (ctx->pos != 0)
            ctx->pos = 0;
    }

    else if (key == KEY_END || key == T_KEY_C_E) {   /* END/C-e key: move cursor to end of line */
        if (ctx->pos != ctx->len)
            ctx->pos = ctx->len;
    }

    else if (key == KEY_LEFT) {
        if (ctx->pos > 0)
            --ctx->pos;
        else
            beep();
    } 

    else if (key == KEY_RIGHT) {
        if (ctx->pos < ctx->len)
            ++ctx->pos;
        else 
            beep();
    } 

    else if (key == KEY_UP) {     /* fetches previous item in history */
        wmove(ctx->history, ctx->orig_y, X_OFST);
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, MOVE_UP);

        /* adjust line y origin appropriately when window scrolls down */
        if (ctx->at_bottom && ctx->len >= x2 - X_OFST) {
            int px2 = ctx->len >= x2 ? x2 : x2 - X_OFST;
            int p_ofst = px2 != x2 ? 0 : X_OFST;

            if (px2 <= 0)
                return;

            int k = ctx->orig_y + ((ctx->len + p_ofst) / px2);

            if (k >= y2) {
                --ctx->orig_y;
            }
        }
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        wmove(ctx->history, ctx->orig_y, X_OFST);
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, MOVE_DOWN);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            if (complete_line(ctx->line, &ctx->pos, &ctx->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS,
                              MAX_CMDNAME_SIZE) == -1) 
                beep();
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {
        if (ctx->len < (MAX_STR_SIZE-1)) {
            add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
        }
    }
    /* RETURN key: execute command */
    else if (key == '\n') {
        wprintw(ctx->history, "\n");
        uint8_t line[MAX_STR_SIZE] = {0};

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);

        line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0);
        execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
        reset_buf(ctx->line, &ctx->pos, &ctx->len);
    }
}
示例#3
0
文件: chat.c 项目: alevy/toxic
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = self->chatwin;
    StatusBar *statusbar = self->stb;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);
    int cur_len = 0;

    if (key == 0x107 || key == 0x8 || key == 0x7f) {  /* BACKSPACE key: Remove character behind pos */
        if (ctx->pos > 0) {
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
            del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);

            if (x == 0)
                wmove(self->window, y-1, x2 - cur_len);
            else
                wmove(self->window, y, x - cur_len);
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (ctx->pos != ctx->len)
            del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (ctx->pos > 0) {
            discard_buf(ctx->line, &ctx->pos, &ctx->len);
            wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (ctx->pos != ctx->len)
            kill_buf(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == KEY_HOME) {    /* HOME key: Move cursor to beginning of line */
        if (ctx->pos > 0) {
            ctx->pos = 0;
            wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        }
    } 

    else if (key == KEY_END) {     /* END key: move cursor to end of line */
        if (ctx->pos != ctx->len) {
            ctx->pos = ctx->len;
            mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT-1)*x2)), y2, x2);
        }
    }

    else if (key == KEY_LEFT) {
        if (ctx->pos > 0) {
            --ctx->pos;
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));

            if (x == 0)
                wmove(self->window, y-1, x2 - cur_len);
            else
                wmove(self->window, y, x - cur_len);
        } else {
            beep();
        }
    } 

    else if (key == KEY_RIGHT) {
        if (ctx->pos < ctx->len) {
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
            ++ctx->pos;

            if (x == x2-1)
                wmove(self->window, y+1, 0);
            else
                wmove(self->window, y, x + cur_len);
        } else {
            beep();
        }
    } 

    else if (key == KEY_UP) {    /* fetches previous item in history */
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, LN_HIST_MV_UP);
        mv_curs_end(self->window, ctx->len, y2, x2);
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, LN_HIST_MV_DWN);
        mv_curs_end(self->window, ctx->len, y2, x2);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, chat_cmd_list, AC_NUM_CHAT_COMMANDS,
                                     MAX_CMDNAME_SIZE);

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int ofst = (x + diff - 1) - (x2 - 1);
                    wmove(self->window, y+1, ofst);
                } else {
                    wmove(self->window, y, x+diff);
                }
            } else {
                beep();
            }
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {   /* prevents buffer overflows and strange behaviour when cursor goes past the window */
        if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
            add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);

            if (x == x2-1)
                wmove(self->window, y+1, 0);
            else
                wmove(self->window, y, x + MAX(1, wcwidth(key)));
        }
    }
    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        uint8_t line[MAX_STR_SIZE];

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);
        bool close_win = false;

        if (!string_is_empty(line))
            add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);

        if (line[0] == '/') {
            if (close_win = !strcmp(line, "/close")) {
                int f_num = self->num;
                delwin(ctx->linewin);
                delwin(statusbar->topline);
                del_window(self);
                disable_chatwin(f_num);
            } else if (strncmp(line, "/me ", strlen("/me ")) == 0)
                send_action(self, ctx, m, line + strlen("/me "));
              else
                execute(ctx->history, self, m, line, CHAT_COMMAND_MODE);
        } else if (!string_is_empty(line)) {
            uint8_t selfname[TOX_MAX_NAME_LENGTH];
            tox_get_self_name(m, selfname, TOX_MAX_NAME_LENGTH);

            print_time(ctx->history);
            wattron(ctx->history, COLOR_PAIR(GREEN));
            wprintw(ctx->history, "%s: ", selfname);
            wattroff(ctx->history, COLOR_PAIR(GREEN));

            if (line[0] == '>') {
                wattron(ctx->history, COLOR_PAIR(GREEN));
                wprintw(ctx->history, "%s\n", line);
                wattroff(ctx->history, COLOR_PAIR(GREEN));
            } else
                wprintw(ctx->history, "%s\n", line);

            if (!statusbar->is_online || tox_send_message(m, self->num, line, strlen(line) + 1) == 0) {
                wattron(ctx->history, COLOR_PAIR(RED));
                wprintw(ctx->history, " * Failed to send message.\n");
                wattroff(ctx->history, COLOR_PAIR(RED));
            }
        }

        if (close_win) {
            free(ctx);
            free(statusbar);
        } else {
            reset_buf(ctx->line, &ctx->pos, &ctx->len);
        }
    }
}
示例#4
0
文件: block.c 项目: ab25cq/xyzsh
BOOL sCommand_add_command_without_command_name(sCommand* self, sCommand* command, char* sname, int sline)
{
    int i;
    for(i=1; i<command->mArgsNum; i++) {
        if(command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV) {
            sBuf buf;
            memset(&buf, 0, sizeof(sBuf));
            buf.mBuf = MALLOC(64);
            buf.mBuf[0] = 0;
            buf.mSize = 64;

            char* p = command->mArgs[i];
            while(*p) {
                if(*p == PARSER_MAGIC_NUMBER_ENV) {
                    p++;

                    char buf2[128];
                    char* p2 = buf2;
                    while(*p != PARSER_MAGIC_NUMBER_ENV) {
                        *p2++ = *p++;
                    }
                    p++;
                    *p2 = 0;

                    int num = atoi(buf2) + self->mEnvsNum;
                    snprintf(buf2, 128, "%d", num);

                    add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV);
                    add_str_to_buf(&buf, buf2, strlen(buf2));
                    add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV);
                }
                else {
                    add_char_to_buf(&buf, *p++);
                }
            }
            if(!sCommand_add_arg(self, MANAGED buf.mBuf, command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED_HEAD, command->mArgsFlags[i] & XYZSH_ARGUMENT_GLOB, command->mArgsFlags[i] & XYZSH_ARGUMENT_OPTION, sname, sline))
            {
                return FALSE;
            }
        }
        else {
            char* arg = STRDUP(command->mArgs[i]);
            if(!sCommand_add_arg(self, MANAGED arg, command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED_HEAD, command->mArgsFlags[i] & XYZSH_ARGUMENT_GLOB, command->mArgsFlags[i] & XYZSH_ARGUMENT_OPTION, sname, sline))
            {
                return FALSE;
            }
        }
    }
    for(i=0; i<command->mEnvsNum; i++) {
        sEnv* env = command->mEnvs + i;

        if(env->mFlags & ENV_FLAGS_KIND_ENV) {
            if(!sCommand_add_env(self, MANAGED STRDUP(env->mName), MANAGED STRDUP(env->mInitValue), MANAGED STRDUP(env->mKey), env->mFlags & ENV_FLAGS_KEY_ENV, env->mFlags & ENV_FLAGS_KEY_QUOTED_STRING, sname, sline))
            {
                return FALSE;
            }
        }
        else {
            if(!sCommand_add_env_block(self, env->mBlock, env->mLineField, sname, sline)) {
                return FALSE;
            }
        }
    }
    for(i=0; i<command->mBlocksNum; i++) {
        sObject* block = block_clone_on_stack(command->mBlocks[i], T_BLOCK);
        if(!sCommand_add_block(self, block, sname, sline)) {
            return FALSE;
        }
    }
    for(i=0; i<command->mRedirectsNum; i++) {
        int flags = command->mRedirects[i];
        if(flags & REDIRECT_ENV) {
            sBuf buf;
            memset(&buf, 0, sizeof(sBuf));
            buf.mBuf = MALLOC(64);
            buf.mBuf[0] = 0;
            buf.mSize = 64;

            char* p = command->mRedirectsFileNames[i];
            while(*p) {
                if(*p == PARSER_MAGIC_NUMBER_ENV) {
                    p++;

                    char buf2[128];
                    char* p2 = buf2;
                    while(*p != PARSER_MAGIC_NUMBER_ENV) {
                        *p2++ = *p++;
                    }
                    p++;
                    *p2 = 0;

                    int num = atoi(buf2) + self->mEnvsNum;
                    snprintf(buf2, 128, "%d", num);

                    add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV);
                    add_str_to_buf(&buf, buf2, strlen(buf2));
                    add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV);
                }
                else {
                    add_char_to_buf(&buf, *p++);
                }
            }
            if(!sCommand_add_redirect(self, MANAGED buf.mBuf, flags & REDIRECT_ENV, flags & REDIRECT_QUOTED, flags & REDIRECT_GLOB, flags & REDIRECT_KIND, sname, sline)) 
            {
                return FALSE;
            }
        }
        else {
            if(!sCommand_add_redirect(self, MANAGED STRDUP(command->mRedirectsFileNames[i]), flags & REDIRECT_ENV, flags & REDIRECT_QUOTED, flags & REDIRECT_GLOB, flags & REDIRECT_KIND, sname, sline))
            {
                return FALSE;
            }
        }
    }

    return TRUE;
}