Changes in / [a1622091:272f88f0] in mainline


Ignore:
Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    ra1622091 r272f88f0  
    3838#include <vfs/vfs.h>
    3939#include <errno.h>
     40#include <assert.h>
    4041#include <bool.h>
    4142
     
    4748#include "exec.h"
    4849
     50#define HISTORY_LEN 10
     51
    4952typedef struct {
    5053        wchar_t buffer[INPUT_MAX];
     
    5356        int nc;
    5457        int pos;
     58
     59        char *history[1 + HISTORY_LEN];
     60        int hnum;
     61        int hpos;
    5562} tinput_t;
    56 
    57 typedef enum {
    58         seek_cell,
    59         seek_max
    60 } seek_dist_t;
    6163
    6264typedef enum {
     
    130132}
    131133
     134static char *tinput_get_str(tinput_t *ti)
     135{
     136        char *str;
     137
     138        str = malloc(STR_BOUNDS(ti->nc) + 1);
     139        if (str == NULL)
     140                return NULL;
     141
     142        wstr_nstr(str, ti->buffer, STR_BOUNDS(ti->nc) + 1);
     143
     144        return str;
     145}
     146
    132147static void tinput_position_caret(tinput_t *ti)
    133148{
     
    183198}
    184199
    185 static void tinput_seek(tinput_t *ti, seek_dir_t dir, seek_dist_t dist)
    186 {
    187         switch (dist) {
    188         case seek_cell:
    189                 ti->pos += dir;
    190                 break;
    191         case seek_max:
    192                 if (dir == seek_backward)
    193                         ti->pos = 0;
    194                 else
    195                         ti->pos = ti->nc;
    196                 break;
    197         }
    198                
    199         if (ti->pos < 0) ti->pos = 0;
    200         if (ti->pos > ti->nc) ti->pos = ti->nc;
    201 
    202         tinput_position_caret(ti);
     200static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir)
     201{
     202        if (dir == seek_forward) {
     203                if (ti->pos < ti->nc)
     204                        ti->pos += 1;
     205        } else {
     206                if (ti->pos > 0)
     207                        ti->pos -= 1;
     208        }
     209
     210        tinput_position_caret(ti);
     211}
     212
     213static void tinput_seek_word(tinput_t *ti, seek_dir_t dir)
     214{
     215        if (dir == seek_forward) {
     216                if (ti->pos == ti->nc)
     217                        return;
     218
     219                while (1) {
     220                        ti->pos += 1;
     221
     222                        if (ti->pos == ti->nc)
     223                                break;
     224
     225                        if (ti->buffer[ti->pos - 1] == ' ' &&
     226                            ti->buffer[ti->pos] != ' ')
     227                                break;
     228                }
     229        } else {
     230                if (ti->pos == 0)
     231                        return;
     232
     233                while (1) {
     234                        ti->pos -= 1;
     235
     236                        if (ti->pos == 0)
     237                                break;
     238
     239                        if (ti->buffer[ti->pos - 1] == ' ' &&
     240                            ti->buffer[ti->pos] != ' ')
     241                                break;
     242                }
     243
     244        }
     245
     246        tinput_position_caret(ti);
     247}
     248
     249static void tinput_seek_max(tinput_t *ti, seek_dir_t dir)
     250{
     251        if (dir == seek_backward)
     252                ti->pos = 0;
     253        else
     254                ti->pos = ti->nc;
     255
     256        tinput_position_caret(ti);
     257}
     258
     259static void tinput_history_insert(tinput_t *ti, char *str)
     260{
     261        int i;
     262
     263        if (ti->hnum < HISTORY_LEN) {
     264                ti->hnum += 1;
     265        } else {
     266                if (ti->history[HISTORY_LEN] != NULL)
     267                        free(ti->history[HISTORY_LEN]);
     268        }
     269
     270        for (i = ti->hnum; i > 1; --i)
     271                ti->history[i] = ti->history[i - 1];
     272
     273        ti->history[1] = str_dup(str);
     274
     275        if (ti->history[0] != NULL) {
     276                free(ti->history[0]);
     277                ti->history[0] = NULL;
     278        }
     279}
     280
     281static void tinput_set_str(tinput_t *ti, char *str)
     282{
     283        str_to_wstr(ti->buffer, INPUT_MAX, str);
     284        ti->nc = wstr_length(ti->buffer);
     285        ti->pos = ti->nc;
     286}
     287
     288static void tinput_history_seek(tinput_t *ti, int offs)
     289{
     290        int pad;
     291
     292        if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum)
     293                return;
     294
     295        if (ti->history[ti->hpos] != NULL) {
     296                free(ti->history[ti->hpos]);
     297                ti->history[ti->hpos] = NULL;
     298        }
     299
     300        ti->history[ti->hpos] = tinput_get_str(ti);
     301        ti->hpos += offs;
     302
     303        pad = ti->nc - str_length(ti->history[ti->hpos]);
     304        if (pad < 0) pad = 0;
     305
     306        tinput_set_str(ti, ti->history[ti->hpos]);
     307        tinput_display_tail(ti, 0, pad);
     308        tinput_position_caret(ti);
     309}
     310
     311static void tinput_init(tinput_t *ti)
     312{
     313        ti->hnum = 0;
     314        ti->hpos = 0;
     315        ti->history[0] = NULL;
    203316}
    204317
     
    226339                        continue;
    227340
    228                 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) != 0)
    229                         continue;
    230 
    231                 switch(ev.key) {
    232                 case KC_ENTER:
    233                 case KC_NENTER:
    234                         goto done;
    235                 case KC_BACKSPACE:
    236                         tinput_backspace(ti);
    237                         break;
    238                 case KC_DELETE:
    239                         tinput_delete(ti);
    240                         break;
    241                 case KC_LEFT:
    242                         tinput_seek(ti, seek_backward, seek_cell);
    243                         break;
    244                 case KC_RIGHT:
    245                         tinput_seek(ti, seek_forward, seek_cell);
    246 
    247                         break;
    248                 case KC_HOME:
    249                         tinput_seek(ti, seek_backward, seek_max);
    250                         break;
    251                 case KC_END:
    252                         tinput_seek(ti, seek_forward, seek_max);
    253                         break;
     341                if ((ev.mods & KM_CTRL) != 0 &&
     342                    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
     343                        switch (ev.key) {
     344                        case KC_LEFT:
     345                                tinput_seek_word(ti, seek_backward);
     346                                break;
     347                        case KC_RIGHT:
     348                                tinput_seek_word(ti, seek_forward);
     349                                break;
     350                        }
    254351                }
     352
     353                if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     354                        switch (ev.key) {
     355                        case KC_ENTER:
     356                        case KC_NENTER:
     357                                goto done;
     358                        case KC_BACKSPACE:
     359                                tinput_backspace(ti);
     360                                break;
     361                        case KC_DELETE:
     362                                tinput_delete(ti);
     363                                break;
     364                        case KC_LEFT:
     365                                tinput_seek_cell(ti, seek_backward);
     366                                break;
     367                        case KC_RIGHT:
     368                                tinput_seek_cell(ti, seek_forward);
     369                                break;
     370                        case KC_HOME:
     371                                tinput_seek_max(ti, seek_backward);
     372                                break;
     373                        case KC_END:
     374                                tinput_seek_max(ti, seek_forward);
     375                                break;
     376                        case KC_UP:
     377                                tinput_history_seek(ti, +1);
     378                                break;
     379                        case KC_DOWN:
     380                                tinput_history_seek(ti, -1);
     381                                break;
     382                        }
     383                }
     384
    255385                if (ev.c >= ' ') {
    256386                        tinput_insert_char(ti, ev.c);
     
    261391        putchar('\n');
    262392
    263         ti->buffer[ti->nc] = '\0';
    264         str = malloc(STR_BOUNDS(ti->nc) + 1);
    265         if (str == NULL)
    266                 return NULL;
    267 
    268         wstr_nstr(str, ti->buffer, STR_BOUNDS(ti->nc) + 1);
     393        str = tinput_get_str(ti);
     394        if (str_cmp(str, "") != 0)
     395                tinput_history_insert(ti, str);
     396
     397        ti->hpos = 0;
    269398
    270399        return str;
     
    292421        return;
    293422}
     423
     424void input_init(void)
     425{
     426        tinput_init(&tinput);
     427}
  • uspace/app/bdsh/input.h

    ra1622091 r272f88f0  
    88extern void get_input(cliuser_t *);
    99extern int tok_input(cliuser_t *);
     10extern void input_init(void);
    1011
    1112#endif
  • uspace/app/bdsh/scli.c

    ra1622091 r272f88f0  
    6464        usr->prompt = (char *) NULL;
    6565        usr->lasterr = 0;
     66
     67        input_init();
     68
    6669        return (int) cli_set_prompt(usr);
    6770}
  • uspace/lib/libc/generic/string.c

    ra1622091 r272f88f0  
    583583}
    584584
     585/** Convert string to wide string.
     586 *
     587 * Convert string @a src to wide string. The output is written to the
     588 * buffer specified by @a dest and @a size, which must have non-zero
     589 * size. The output will always be null-terminated.
     590 *
     591 * @param dest  Destination buffer.
     592 * @param dlen  Length of destination buffer (number of wchars).
     593 * @param src   Source string.
     594 */
     595void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     596{
     597        size_t offset;
     598        size_t di;
     599        wchar_t c;
     600
     601        assert(dlen > 0);
     602
     603        offset = 0;
     604        di = 0;
     605
     606        do {
     607                if (di >= dlen - 1)
     608                        break;
     609
     610                c = str_decode(src, &offset, STR_NO_LIMIT);
     611                dest[di++] = c;
     612        } while (c != '\0');
     613
     614        dest[dlen - 1] = '\0';
     615}
     616
    585617/** Find first occurence of character in string.
    586618 *
  • uspace/lib/libc/include/string.h

    ra1622091 r272f88f0  
    7474
    7575extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
     76extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
    7677
    7778extern char *str_chr(const char *str, wchar_t ch);
Note: See TracChangeset for help on using the changeset viewer.