Exemplo n.º 1
0
/* @history_funcs{"go"} */
static JSBool
history_go(JSContext *ctx, unsigned int argc, jsval *rval)
{
	struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
	struct document_view *doc_view = interpreter->vs->doc_view;
	struct session *ses = doc_view->session;
	jsval *argv = JS_ARGV(ctx, rval);
	int index;
	struct location *loc;

	if (argc != 1)
		return JS_TRUE;

	index  = atol(jsval_to_string(ctx, &argv[0]));

	for (loc = cur_loc(ses);
	     loc != (struct location *) &ses->history.history;
	     loc = index > 0 ? loc->next : loc->prev) {
		if (!index) {
			go_history(ses, loc);
			break;
		}

		index += index > 0 ? -1 : 1;
	}

	JS_SET_RVAL(ctx, rval, JSVAL_NULL);
	return 2;
}
Exemplo n.º 2
0
std::string cmd_handler::readline(const std::string & prompt)
{
    char c;
    char arrow[2];

    const char del[] = "\b \b";
    auto clear_line = [del](int count)
                      {
                          for (int i = 0; i < count; i++)
                          {
                               if (write(STDOUT_FILENO, &del, 3) < 0)
                               {
                                   std::cerr << "write: " << strerror(errno) << std::endl;
                               }
                          }
                      };
    history_iter_ = history_.end();
    std::string line, word;
    struct termios tty, tty_change;
    tcgetattr(STDIN_FILENO, &tty);
    tty_change = tty;
    tty_change.c_lflag &= ~ICANON;
    tty_change.c_lflag &= ~ECHO;

    tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty_change);
    if (write(STDOUT_FILENO, prompt.data(), prompt.size()) < 0)
    {
        std::cerr << "write: " << strerror(errno) << std::endl;
    }
    auto dir = direction_none;
    size_t current_size = 0;
    std::string value;
    while(true)
    {
        if (read(STDIN_FILENO, &c, 1) < 0)
        {
            std::cerr << "read: " << strerror(errno) << std::endl;
        }
        if (std::iscntrl(c))
        {
            switch(c)
            {
                case '\033':
                    current_size = line.size();
                    // eat the rest of the input
                    if (read(STDIN_FILENO, &arrow, 2) < 0)
                    {
                        std::cerr << "read: " << strerror(errno) << std::endl;
                    }
                    if (arrow[1] == 'A')
                    {
                        dir = direction_back;
                    }
                    else if (arrow[1] == 'B')
                    {
                        dir = direction_forward;
                    }
                    if (dir != direction_none && go_history(dir, line))
                    {
                        clear_line(current_size);
                        if (write(STDOUT_FILENO, line.data(), line.size()) < 0)
                        {
                            std::cerr << "write: " << strerror(errno) << std::endl;
                        }
                        dir = direction_none;
                        current_size = 0;
                    }
                    break;
                case '\n':
                    tcsetattr(STDIN_FILENO, TCSANOW, &tty);
                    std::cout << std::endl;
                    if (line.empty() && !history_.empty())
                    {
                        value = history_.back();
                    }
                    else
                    {
                        value = rtrim(ltrim(line));
                    }

                    if (log_.is_open())
                    {
                        log_ << prompt << value << std::endl;
                    }
                    return value;
                case '\b':
                case 127:
                    if (!line.empty())
                    {
                        line.erase(line.end()-1, line.end());
                        if (write(STDOUT_FILENO, &del, 3) < 0)
                        {
                            std::cerr << "write: " << strerror(errno) << std::endl;
                        }
                    }
                    break;
                case '\t':
                    // TODO : tab complete
                    break;
            }
        }
        else
        {
            if (write(STDOUT_FILENO, &c, 1) < 0)
            {
                std::cerr << "write: " << strerror(errno) << std::endl;
            }
            if (std::iswspace(c))
            {
                if (!word.empty())
                {
                    word.clear();
                }
            }
            else
            {
                word.push_back(c);
            }
            line.push_back(c);
        }
    }
}