Allow canceling lineedit with ctrl+c

develop
Pauli 2018-07-04 15:21:25 +03:00
parent ae5a1fad84
commit d1a3f1a738
9 changed files with 74 additions and 49 deletions

@ -423,13 +423,13 @@ namespace DFHack
int count;
if (enable_raw() == -1) return 0;
if(state == con_lineedit)
return -1;
return Console::FAILURE;
state = con_lineedit;
count = prompt_loop(lock,ch);
state = con_unclaimed;
disable_raw();
print("\n");
if(count != -1)
if(count > Console::FAILURE)
{
output = toLocaleMB(raw_buffer);
}
@ -441,9 +441,9 @@ namespace DFHack
struct termios raw;
if (!supported_terminal)
return -1;
return Console::FAILURE;
if (tcgetattr(STDIN_FILENO,&orig_termios) == -1)
return -1;
return Console::FAILURE;
raw = orig_termios; //modify the original mode
// input modes: no break, no CR to NL, no parity check, no strip char,
@ -465,7 +465,7 @@ namespace DFHack
raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0;// 1 byte, no timer
// put terminal in raw mode
if (tcsetattr(STDIN_FILENO, TCSADRAIN, &raw) < 0)
return -1;
return Console::FAILURE;
rawmode = 1;
return 0;
}
@ -518,7 +518,8 @@ namespace DFHack
* initially is just an empty string. */
const std::string empty;
history.add(empty);
if (::write(fd,prompt.c_str(),prompt.size()) == -1) return -1;
if (::write(fd,prompt.c_str(),prompt.size()) == -1)
return Console::FAILURE;
while(1)
{
unsigned char c;
@ -528,7 +529,7 @@ namespace DFHack
if(!read_char(c))
{
lock->lock();
return -2;
return Console::SHUTDOWN;
}
lock->lock();
/* Only autocomplete when the callback is set. It returns < 0 when
@ -561,8 +562,7 @@ namespace DFHack
history.remove();
return raw_buffer.size();
case 3: // ctrl-c
errno = EAGAIN;
return -1;
return Console::RETRY;
case 127: // backspace
case 8: // ctrl-h
if (raw_cursor > 0 && raw_buffer.size() > 0)
@ -577,7 +577,7 @@ namespace DFHack
if (!read_char(seq[0]))
{
lock->lock();
return -2;
return Console::SHUTDOWN;
}
lock->lock();
if (seq[0] == 'b')
@ -593,7 +593,7 @@ namespace DFHack
if (!read_char(seq[1]))
{
lock->lock();
return -2;
return Console::SHUTDOWN;
}
if (seq[1] == 'D')
{
@ -658,7 +658,7 @@ namespace DFHack
if(!read_char(seq2))
{
lock->lock();
return -2;
return Console::SHUTDOWN;
}
lock->lock();
if (seq[1] == '3' && seq2 == '~' )
@ -674,7 +674,7 @@ namespace DFHack
if (!read_char(seq3[0]) || !read_char(seq3[1]))
{
lock->lock();
return -2;
return Console::SHUTDOWN;
}
if (seq2 == ';')
{
@ -747,9 +747,9 @@ namespace DFHack
// character starting from the first bye already red
while ((sz = mbrtoc32(&c32,&mb[count-1],1, &state)) < 0) {
if (sz == -1 || sz == -3)
return -1; /* mbrtoc32 error (not valid utf-32 character */
return Console::FAILURE; /* mbrtoc32 error (not valid utf-32 character */
if(!read_char(c))
return -2;
return Console::SHUTDOWN;
mb[count++] = c;
}
if (raw_buffer.size() == size_t(raw_cursor))
@ -760,7 +760,8 @@ namespace DFHack
{
/* Avoid a full update of the line in the
* trivial case. */
if (::write(fd,mb,count) == -1) return -1;
if (::write(fd,mb,count) == -1)
return Console::FAILURE;
}
else
{
@ -888,7 +889,7 @@ void Console::add_text(color_value color, const std::string &text)
int Console::get_columns(void)
{
lock_guard <recursive_mutex> g(*wlock);
int ret = -1;
int ret = Console::FAILURE;
if(inited)
ret = d->get_columns();
return ret;
@ -897,7 +898,7 @@ int Console::get_columns(void)
int Console::get_rows(void)
{
lock_guard <recursive_mutex> g(*wlock);
int ret = -1;
int ret = Console::FAILURE;
if(inited)
ret = d->get_rows();
return ret;
@ -927,10 +928,10 @@ void Console::cursor(bool enable)
int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch)
{
lock_guard <recursive_mutex> g(*wlock);
int ret = -2;
int ret = Console::SHUTDOWN;
if(inited) {
ret = d->lineedit(prompt,output,wlock,ch);
if (ret == -2) {
if (ret == Console::SHUTDOWN) {
// kill the thing
if(d->rawmode)
d->disable_raw();

@ -287,7 +287,7 @@ namespace DFHack
lock->unlock();
if (ReadConsoleInputA(console_in, &rec, 1, &count) != 0) {
lock->lock();
return -2;
return Console::SHUTDOWN;
}
lock->lock();
if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown)
@ -382,7 +382,7 @@ namespace DFHack
state = con_lineedit;
this->prompt = prompt;
count = prompt_loop(lock, ch);
if(count != -1)
if(count > Console::FAILURE)
output = raw_buffer;
state = con_unclaimed;
print("\n");
@ -591,7 +591,7 @@ void Console::cursor(bool enable)
int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch)
{
wlock->lock();
int ret = -2;
int ret = Console::SHUTDOWN;
if(inited)
ret = d->lineedit(prompt,output,wlock,ch);
wlock->unlock();

@ -1421,13 +1421,15 @@ void fIOthread(void * iodata)
while (true)
{
string command = "";
int ret = con.lineedit("[DFHack]# ",command, main_history);
if(ret == -2)
int ret;
while ((ret = con.lineedit("[DFHack]# ",command, main_history))
== Console::RETRY);
if(ret == Console::SHUTDOWN)
{
cerr << "Console is shutting down properly." << endl;
return;
}
else if(ret == -1)
else if(ret == Console::FAILURE)
{
cerr << "Console caught an unspecified error." << endl;
continue;

@ -293,10 +293,13 @@ static int dfhack_lineedit_sync(lua_State *S, Console *pstream)
std::string ret;
int rv = pstream->lineedit(prompt, ret, hist);
if (rv == Console::RETRY)
rv = 0; /* return empty string to lua */
if (rv < 0)
{
lua_pushnil(S);
if (rv == -2)
if (rv == Console::SHUTDOWN)
lua_pushstring(S, "shutdown requested");
else
lua_pushstring(S, "input error");
@ -1061,9 +1064,9 @@ bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state,
prompt = ">> ";
std::string curline;
rv = con.lineedit(prompt,curline,hist);
if (rv < 0) {
rv = rv == -2 ? LUA_OK : LUA_ERRRUN;
while((rv = con.lineedit(prompt,curline,hist)) == Console::RETRY);
if (rv <= Console::FAILURE) {
rv = rv == Console::SHUTDOWN ? LUA_OK : LUA_ERRRUN;
break;
}
hist.add(curline);

@ -153,6 +153,12 @@ namespace DFHack
int get_rows(void);
/// beep. maybe?
//void beep (void);
//! \defgroup lineedit_return_values Possible errors from lineedit
//! \{
static constexpr int FAILURE = -1;
static constexpr int SHUTDOWN = -2;
static constexpr int RETRY = -3;
//! \}
/// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, CommandHistory & history );
bool isInited (void) { return inited; };

@ -237,8 +237,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range width <" << width << "> ";
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = con.lineedit(str.str(), command, hist))
== Console::RETRY);
if (rv <= Console::FAILURE)
return rv == Console::FAILURE ? CR_FAILURE : CR_FAILURE;
hist.add(command);
newWidth = command.empty() ? width : atoi(command.c_str());
} else {
@ -252,8 +254,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range height <" << height << "> ";
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = con.lineedit(str.str(), command, hist))
== Console::RETRY);
if (rv <= Console::FAILURE)
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
hist.add(command);
newHeight = command.empty() ? height : atoi(command.c_str());
} else {
@ -267,8 +271,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range z-levels <" << zLevels << "> ";
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = con.lineedit(str.str(), command, hist))
== Console::RETRY);
if (rv <= Console::FAILURE)
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
hist.add(command);
newZLevels = command.empty() ? zLevels : atoi(command.c_str());
} else {

@ -189,8 +189,10 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters)
print_prompt(str, cur_mode);
str << "# ";
int rv;
if((rv = out.lineedit(str.str(),input,liquids_hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = out.lineedit(str.str(),input,liquids_hist))
== Console::RETRY);
if (rv <= Console::FAILURE)
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
liquids_hist.add(input);
commands.clear();

@ -140,9 +140,10 @@ command_result mode (color_ostream &out_, vector <string> & parameters)
string selected;
input_again:
CommandHistory hist;
rv = out.lineedit("Enter new mode: ",selected, hist);
if(rv < 0 || selected == "c")
return rv == -2 ? CR_OK : CR_FAILURE;
while((rv = out.lineedit("Enter new mode: ",selected, hist))
== Console::RETRY);
if(rv <= Console::FAILURE || selected == "c")
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
const char * start = selected.c_str();
char * end = 0;
select = strtol(start, &end, 10);
@ -179,14 +180,16 @@ command_result mode (color_ostream &out_, vector <string> & parameters)
{
CommandHistory hist;
string selected;
rv = out.lineedit("Enter new game mode number (c for exit): ",selected, hist);
if(rv < 0 || selected == "c")
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = out.lineedit("Enter new game mode number (c for exit): ",selected, hist))
== Console::RETRY);
if(rv <= Console::FAILURE || selected == "c")
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
const char * start = selected.c_str();
gm.g_mode = (GameMode) strtol(start, 0, 10);
rv = out.lineedit("Enter new game type number (c for exit): ",selected, hist);
if(rv < 0 || selected == "c")
return rv == -2 ? CR_OK : CR_FAILURE;
while((rv = out.lineedit("Enter new game type number (c for exit): ",selected, hist))
== Console::RETRY);
if(rv <= Console::FAILURE || selected == "c")
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
start = selected.c_str();
gm.g_type = (GameType) strtol(start, 0, 10);
}

@ -986,8 +986,10 @@ command_result df_tiletypes (color_ostream &out_, vector <string> & parameters)
std::string input = "";
int rv = 0;
if ((rv = out.lineedit("tiletypes> ",input,tiletypes_hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
while ((rv = out.lineedit("tiletypes> ",input,tiletypes_hist))
== Console::RETRY);
if (rv <= Console::FAILURE)
return rv == Console::FAILURE ? CR_FAILURE : CR_OK;
tiletypes_hist.add(input);
commands.clear();