Ignore:
File:
1 edited

Legend:

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

    rda2bd08 r19528516  
    3838#include <vfs/vfs.h>
    3939#include <errno.h>
    40 #include <assert.h>
    4140#include <bool.h>
    4241
     
    4847#include "exec.h"
    4948
    50 #define HISTORY_LEN 10
    51 
    5249typedef struct {
    5350        wchar_t buffer[INPUT_MAX];
     
    5653        int nc;
    5754        int pos;
    58 
    59         char *history[1 + HISTORY_LEN];
    60         int hnum;
    61         int hpos;
    6255} tinput_t;
     56
     57typedef enum {
     58        seek_cell,
     59        seek_max
     60} seek_dist_t;
    6361
    6462typedef enum {
     
    132130}
    133131
    134 static 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 
    147132static void tinput_position_caret(tinput_t *ti)
    148133{
     
    198183}
    199184
    200 static 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         }
     185static 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;
    209201
    210202        tinput_position_caret(ti);
    211 }
    212 
    213 static 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 
    249 static 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 
    259 static 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 
    281 static 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 
    288 static 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 
    311 static void tinput_init(tinput_t *ti)
    312 {
    313         ti->hnum = 0;
    314         ti->hpos = 0;
    315         ti->history[0] = NULL;
    316203}
    317204
     
    339226                        continue;
    340227
    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                         }
     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;
    351254                }
    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 
    385255                if (ev.c >= ' ') {
    386256                        tinput_insert_char(ti, ev.c);
     
    391261        putchar('\n');
    392262
    393         str = tinput_get_str(ti);
    394         if (str_cmp(str, "") != 0)
    395                 tinput_history_insert(ti, str);
    396 
    397         ti->hpos = 0;
     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);
    398269
    399270        return str;
     
    421292        return;
    422293}
    423 
    424 void input_init(void)
    425 {
    426         tinput_init(&tinput);
    427 }
Note: See TracChangeset for help on using the changeset viewer.