summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-09-14 19:15:09 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-09-14 19:15:09 +0000
commit635e76eb4ca63a30b7bf79c530d3f6dbba83f676 (patch)
treeb31929b743d1316eeec5a475ac37017b83535115 /src
parentb59ad6a174b49a049fd6789cbeb54dc40fd85fa1 (diff)
prompt: rework tu support arrows and completion cycling
Diffstat (limited to 'src')
-rw-r--r--src/completion.hh3
-rw-r--r--src/main.cc73
2 files changed, 60 insertions, 16 deletions
diff --git a/src/completion.hh b/src/completion.hh
index 497fa54f..2607879f 100644
--- a/src/completion.hh
+++ b/src/completion.hh
@@ -15,6 +15,9 @@ struct Completions
size_t start;
size_t end;
+ Completions()
+ : start(0), end(0) {}
+
Completions(size_t start, size_t end)
: start(start), end(end) {}
};
diff --git a/src/main.cc b/src/main.cc
index 3f65c18f..4f71abdb 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -106,6 +106,12 @@ std::string prompt(const std::string& text,
clrtoeol();
std::string result;
+ size_t cursor_pos = 0;
+
+ Completions completions;
+ int current_completion = -1;
+ std::string text_before_completion;
+
while(true)
{
char c = getch();
@@ -113,36 +119,71 @@ std::string prompt(const std::string& text,
{
case '\r':
return result;
+ case 4:
+ if (cursor_pos > 0)
+ --cursor_pos;
+ break;
+ case 5:
+ if (cursor_pos < result.length())
+ ++cursor_pos;
+ break;
case 7:
- if (not result.empty())
+ if (cursor_pos != 0)
{
- move(max_y - 1, text.length() + result.length() - 1);
- addch(' ');
- result.resize(result.length() - 1);
- move(max_y - 1, text.length() + result.length());
- refresh();
+ result = result.substr(0, cursor_pos - 1)
+ + result.substr(cursor_pos, std::string::npos);
+
+ --cursor_pos;
}
+
+ current_completion = -1;
break;
case 27:
throw prompt_aborted();
case '\t':
{
- Completions completions = completer(result, result.length());
- if (not completions.candidates.empty())
+ if (current_completion == -1)
+ {
+ completions = completer(result, result.length());
+ if (completions.candidates.empty())
+ break;
+
+ text_before_completion = result.substr(completions.start,
+ completions.end - completions.start);
+ }
+ ++current_completion;
+
+ std::string completion;
+ if (current_completion >= completions.candidates.size())
{
- const std::string& completion = completions.candidates[0];
- move(max_y-1, text.length());
- result = result.substr(0, completions.start) + completion;
- addstr(result.c_str());
- refresh();
+ if (current_completion == completions.candidates.size() and
+ std::find(completions.candidates.begin(), completions.candidates.end(), text_before_completion) == completions.candidates.end())
+ completion = text_before_completion;
+ else
+ {
+ current_completion = 0;
+ completion = completions.candidates[0];
+ }
}
+ else
+ completion = completions.candidates[current_completion];
+
+ move(max_y-1, text.length());
+ result = result.substr(0, completions.start) + completion;
+ cursor_pos = completions.start + completion.length();
break;
}
default:
- result += c;
- addch(c);
- refresh();
+ current_completion = -1;
+ result = result.substr(0, cursor_pos) + c + result.substr(cursor_pos, std::string::npos);
+ ++cursor_pos;
}
+
+ move(max_y - 1, text.length());
+ clrtoeol();
+ addstr(result.c_str());
+ move(max_y - 1, text.length() + cursor_pos);
+ refresh();
}
return result;
}