Exemplo n.º 1
0
static int linenoisePrompt(int id, char *buf, size_t buflen, const char *prompt)
{
	size_t plen = strlen(prompt);
	size_t pos = 0;
	size_t len = 0;
	size_t cols = TERM_COLS;
	int history_index = 0;

	buf[0] = '\0';
	buflen--; /* Make sure there is always space for the nulterm */

	/* The latest history entry is always our current buffer, that
	 * initially is just an empty string. */
	linenoise_internal_addhistory( id, "", LINENOISE_PUSH_EMPTY );

	term_putstr( prompt, plen );
	while(1) {
		int c;

		c = term_getch( TERM_INPUT_WAIT );

		switch(c) {
		case KC_ENTER:
		case KC_CTRL_C:
		case KC_CTRL_Z:
			history_lengths[ id ] --;
			free( histories[ id ][history_lengths[ id ]] );
			if( c == KC_CTRL_C )
				return LINENOISE_CTRL_C;
			else if( c == KC_CTRL_Z )
				return -1;
			return len;

		case KC_BACKSPACE:
			if (pos > 0 && len > 0) {
				memmove(buf+pos-1,buf+pos,len-pos);
				pos--;
				len--;
				buf[len] = '\0';
				refreshLine(prompt,buf,len,pos,cols);
			}
			break;

		case KC_CTRL_T:    /* ctrl-t */
			// bogdanm: this seems to be rather useless and also a bit buggy,
			// so it's not enabled
			/*            if (pos > 0 && pos < len) {
			                int aux = buf[pos-1];
			                buf[pos-1] = buf[pos];
			                buf[pos] = aux;
			                if (pos != len-1) pos++;
			                refreshLine(prompt,buf,len,pos,cols);
			            }*/
			break;

		case KC_LEFT:
			/* left arrow */
			if (pos > 0) {
				pos--;
				refreshLine(prompt,buf,len,pos,cols);
			}
			break;

		case KC_RIGHT:
			/* right arrow */
			if (pos != len) {
				pos++;
				refreshLine(prompt,buf,len,pos,cols);
			}
			break;

		case KC_UP:
		case KC_DOWN:
			/* up and down arrow: history */
			if (history_lengths[ id ] > 1) {
				/* Update the current history entry before to
				 * overwrite it with tne next one. */
				free(histories[ id ][history_lengths[ id ]-1-history_index]);
				histories[ id ][history_lengths[ id ]-1-history_index] = strdup(buf);
				/* Show the new entry */
				history_index += (c == KC_UP) ? 1 : -1;
				if (history_index < 0) {
					history_index = 0;
					break;
				} else if (history_index >= history_lengths[ id ]) {
					history_index = history_lengths[ id ]-1;
					break;
				}
				strncpy(buf,histories[ id ][history_lengths[ id ]-1-history_index],buflen);
				buf[buflen] = '\0';
				len = pos = strlen(buf);
				refreshLine(prompt,buf,len,pos,cols);
			}
			break;

		case KC_DEL:
			/* delete */
			if (len > 0 && pos < len) {
				memmove(buf+pos,buf+pos+1,len-pos-1);
				len--;
				buf[len] = '\0';
				refreshLine(prompt,buf,len,pos,cols);
			}
			break;

		case KC_HOME: /* Ctrl+a, go to the start of the line */
			pos = 0;
			refreshLine(prompt,buf,len,pos,cols);
			break;

		case KC_END: /* ctrl+e, go to the end of the line */
			pos = len;
			refreshLine(prompt,buf,len,pos,cols);
			break;

		case KC_CTRL_U: /* Ctrl+u, delete the whole line. */
			buf[0] = '\0';
			pos = len = 0;
			refreshLine(prompt,buf,len,pos,cols);
			break;

		case KC_CTRL_K: /* Ctrl+k, delete from current to end of line. */
			buf[pos] = '\0';
			len = pos;
			refreshLine(prompt,buf,len,pos,cols);
			break;

		default:
			if( isprint( c ) && len < buflen ) {
				if(len == pos) {
					buf[pos] = c;
					pos++;
					len++;
					buf[len] = '\0';
					if (plen+len < cols) {
						/* Avoid a full update of the line in the
						 * trivial case. */
						term_putch( c );
					} else {
						refreshLine(prompt,buf,len,pos,cols);
					}
				} else {
					memmove(buf+pos+1,buf+pos,len-pos);
					buf[pos] = c;
					len++;
					pos++;
					buf[len] = '\0';
					refreshLine(prompt,buf,len,pos,cols);
				}
			}
			break;
		}
	}

	return len;
}
Exemplo n.º 2
0
int linenoise_addhistory( int id, const char *line )
{
	return linenoise_internal_addhistory( id, line, LINENOISE_DONT_PUSH_EMPTY );
}
Exemplo n.º 3
0
//--------------------------------------------------------------------
int linenoisePrompt(int id, char *buf, int buflen, const char *prompt)
{
    size_t plen = strlen(prompt);
    size_t pos = 0;
    size_t len = 0;
    size_t cols = term_num_cols;
    int history_index = 0;
    int c;
    int ins = 1;
    
    buf[0] = '\0';
    buflen--;		// Make sure there is always space for the nulterm

    // The latest history entry is always our current buffer, that initially is just an empty string.
    linenoise_internal_addhistory( id, "", LINENOISE_PUSH_EMPTY );
    
    term_putstr( prompt, plen );
    term_curs(0);
    while(1) {

        c = term_getch(TERM_INPUT_WAIT);
        if (c < 0) continue;
        
        switch(c) 
        {
          case KC_ENTER:
            history_lengths[ id ] --;
            free( histories[ id ][history_lengths[ id ]] );

			return len;
            break;

         case KC_CTRL_D:
         	if (len == 0) return LINENOISE_CTRL_D;
         	break;

         case KC_CTRL_C:
         	 len = 0;
         	 pos = 0;
             buf[len] = '\0';
             refreshLine(prompt,buf,len,pos,cols);
             break;

         case KC_BACKSPACE:
            if (pos > 0 && len > 0) {
              memmove(buf+pos-1,buf+pos,len-pos);
              pos--;
              len--;
              buf[len] = '\0';
              refreshLine(prompt,buf,len,pos,cols);
            }
            break;
             
         case KC_INS:
        	ins ^= 1;
            if (ins) term_curs(0);
            else  term_curs(4);
            break;

         case KC_CTRL_T:
            // bogdanm: this seems to be rather useless and also a bit buggy,
            // so it's not enabled
        	/*
            if (pos > 0 && pos < len) {
                int aux = buf[pos-1];
                buf[pos-1] = buf[pos];
                buf[pos] = aux;
                if (pos != len-1) pos++;
                refreshLine(prompt,buf,len,pos,cols);
            }
            */
            break;
            
        case KC_LEFT:
            // left arrow
            if (pos > 0) 
            {
              pos--;
              refreshLine(prompt,buf,len,pos,cols);
            }
            break;
                
        case KC_RIGHT:
            // right arrow
            if (pos != len) 
            {
              pos++;
              refreshLine(prompt,buf,len,pos,cols);
            }
            break;
                
       case KC_UP:
       case KC_DOWN:
            // up and down arrow: history
            if (history_lengths[ id ] > 1) {
              // Update the current history entry before to overwrite it with tne next one.
              free(histories[ id ][history_lengths[ id ]-1-history_index]);
              histories[ id ][history_lengths[ id ]-1-history_index] = strdup(buf);

              // Show the new entry
              history_index += (c == KC_UP) ? 1 : -1;
              if (history_index < 0) {
                history_index = 0;
                break;
              }
              else if (history_index >= history_lengths[ id ]) {
                history_index = history_lengths[ id ]-1;
                break;
              }
              strncpy(buf, histories[ id ][history_lengths[ id ]-1-history_index], buflen);
              buf[buflen] = '\0';
              if ((strlen(buf) > 7) && (strstr(buf, "return ")) == buf) {
            	memmove(buf+1, buf+7, strlen(buf)-6);
            	buf[0] = '=';
              }
              len = pos = strlen(buf);
              refreshLine(prompt,buf,len,pos,cols);
            }
            break;
        case KC_DEL:           
            // delete
            if (len > 0 && pos < len) 
            {
              memmove(buf+pos,buf+pos+1,len-pos-1);
              len--;
              buf[len] = '\0';
              refreshLine(prompt,buf,len,pos,cols);
            }    
            break;
            
        case KC_HOME:
        	// Ctrl+a, go to the start of the line
            pos = 0;
            refreshLine(prompt,buf,len,pos,cols);
            break;
            
        case KC_END:
        	// ctrl+e, go to the end of the line
            pos = len;
            refreshLine(prompt,buf,len,pos,cols);
            break;
            
        case KC_CTRL_U:
        	// Ctrl+u, delete the whole line.
            buf[0] = '\0';
            pos = len = 0;
            refreshLine(prompt,buf,len,pos,cols);
            break;
            
        case KC_CTRL_K:
        	// Ctrl+k, delete from current to end of line.
            buf[pos] = '\0';
            len = pos;
            refreshLine(prompt,buf,len,pos,cols);
            break;
                        
        default:
            if( isprint( c ) && len < buflen )
            {
              if(len == pos) 
              {
                buf[pos] = c;
                pos++;
                len++;
                buf[len] = '\0';
                if (plen+len < cols) {
                  // Avoid a full update of the line in the trivial case.
                  term_putch( c );
                } 
                else {
                  refreshLine(prompt,buf,len,pos,cols);
                }
              } 
              else {
            	if (ins) {
					memmove(buf+pos+1,buf+pos,len-pos);
					buf[pos] = c;
					len++;
					pos++;
					buf[len] = '\0';
            	}
            	else {
					buf[pos] = c;
					pos++;
            	}
                refreshLine(prompt,buf,len,pos,cols);
              }
            }
            break;            
        }
    }

    return len;
}