famevim: make <C-.> etc work in mappings

This commit is contained in:
hjk
2010-05-07 17:32:46 +02:00
parent fe9ab6d76a
commit 462b78713d

View File

@@ -326,7 +326,7 @@ public:
explicit Input(QChar x) explicit Input(QChar x)
: m_key(x.unicode()), m_xkey(x.unicode()), m_modifiers(0), m_text(x) {} : m_key(x.unicode()), m_xkey(x.unicode()), m_modifiers(0), m_text(x) {}
Input(int k, int m, QString t) Input(int k, int m, const QString &t)
: m_key(k), m_modifiers(m), m_text(t) : m_key(k), m_modifiers(m), m_text(t)
{ {
// m_xkey is only a cache. // m_xkey is only a cache.
@@ -360,13 +360,21 @@ public:
bool operator==(const Input &a) const bool operator==(const Input &a) const
{ {
return a.m_key == m_key && m_text == a.m_text; return a.m_key == m_key && a.m_modifiers == m_modifiers
&& m_text == a.m_text;
} }
bool operator!=(const Input &a) const { return !operator==(a); }
QString text() const { return m_text; } QString text() const { return m_text; }
int key() const { return m_key; } int key() const { return m_key; }
QDebug dump(QDebug ts) const
{
return ts << m_key << '-' << m_modifiers << '-'
<< quoteUnprintable(m_text);
}
private: private:
int m_key; int m_key;
int m_xkey; int m_xkey;
@@ -374,15 +382,48 @@ private:
QString m_text; QString m_text;
}; };
QDebug &operator<<(QDebug &ts, const Input &input) QDebug operator<<(QDebug ts, const Input &input) { return input.dump(ts); }
class Inputs : public QVector<Input>
{ {
return ts << input.text() << input.key(); public:
Inputs() {}
explicit Inputs(const QString &str) { parseFrom(str); }
void parseFrom(const QString &str);
};
void Inputs::parseFrom(const QString &str)
{
const int n = str.size();
for (int i = 0; i < n; ++i) {
uint c0 = str.at(i).unicode(), c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0;
if (i + 1 < n)
c1 = str.at(i + 1).unicode();
if (i + 2 < n)
c2 = str.at(i + 2).unicode();
if (i + 3 < n)
c3 = str.at(i + 3).unicode();
if (i + 4 < n)
c4 = str.at(i + 4).unicode();
if (i + 5 < n)
c5 = str.at(i + 5).unicode();
if (c0 == '<') {
if ((c1 == 'C' || c1 == 'c') && c2 == '-' && c4 == '>') {
uint c = (c3 < 90 ? c3 : c3 - 32);
append(Input(c, Qt::ControlModifier, QString(QChar(c - 64))));
i += 4;
} else {
append(Input(QLatin1Char(c0)));
}
} else {
append(Input(QLatin1Char(c0)));
}
}
} }
typedef QVector<Input> Inputs;
// Mappings for a specific mode. // Mappings for a specific mode.
class ModeMapping : private QList<QPair<Inputs, Inputs> > class ModeMapping : public QList<QPair<Inputs, Inputs> >
{ {
public: public:
ModeMapping() { test(); } ModeMapping() { test(); }
@@ -412,24 +453,24 @@ public:
} }
} }
// Returns 'false' if more input input is needed to decide whether a // Returns 'false' if more input is needed to decide whether a mapping
// mapping needs to be applied. If a decision can be made, return 'true', // needs to be applied. If a decision can be made, return 'true',
// and replace *input with the mapped data. // and replace *input with the mapped data.
bool mappingDone(Inputs *input) const bool mappingDone(Inputs *inputs) const
{ {
Q_UNUSED(input);
// FIXME: inefficient. // FIXME: inefficient.
for (int i = 0; i != size(); ++i) { for (int i = 0; i != size(); ++i) {
const Inputs &haystack = at(i).first;
// A mapping // A mapping
if (startsWith(at(i).first, *input)) { if (startsWith(haystack, *inputs)) {
if (at(i).first.size() != input->size()) if (haystack.size() != inputs->size())
return false; // This can be extended. return false; // This can be extended.
// Actual mapping. // Actual mapping.
*input = at(i).second; *inputs = at(i).second;
return true; return true;
} }
} }
// No extensible mapping found. Use input as-is. // No extensible mapping found. Use inputs as-is.
return true; return true;
} }
@@ -440,7 +481,7 @@ private:
if (needle.size() > haystack.size()) if (needle.size() > haystack.size())
return false; return false;
for (int i = 0; i != needle.size(); ++i) { for (int i = 0; i != needle.size(); ++i) {
if (needle.at(i).text() != haystack.at(i).text()) if (needle.at(i) != haystack.at(i))
return false; return false;
} }
return true; return true;
@@ -764,7 +805,7 @@ public:
} }
// Input. // Input.
QVector<Input> pendingInput; Inputs pendingInput;
int inputTimer; int inputTimer;
// Repetition. // Repetition.
@@ -1017,6 +1058,7 @@ void FakeVimHandler::Private::restoreWidget(int tabSize)
EventResult FakeVimHandler::Private::handleKey(const Input &input) EventResult FakeVimHandler::Private::handleKey(const Input &input)
{ {
KEY_DEBUG("HANDLE INPUT: " << input);
if (m_mode == ExMode) if (m_mode == ExMode)
return handleExMode(input); return handleExMode(input);
if (m_subsubmode == SearchSubSubMode) if (m_subsubmode == SearchSubSubMode)
@@ -2821,12 +2863,13 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const QString &line)
bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map
{ {
int pos1 = line.indexOf(QLatin1Char(' ')); const int pos1 = line.indexOf(QLatin1Char(' '));
if (pos1 == -1) const int pos2 = line.indexOf(QLatin1Char(' '), pos1 + 1);
return false; if (pos1 == -1 || pos2 == -1) {
int pos2 = line.indexOf(QLatin1Char(' '), pos1 + 1); // FIXME: Dump mappings here.
if (pos2 == -1) qDebug() << g.mappings;
return false; return true;;
}
QByteArray modes; QByteArray modes;
enum Type { Map, Noremap, Unmap } type; enum Type { Map, Noremap, Unmap } type;
@@ -2872,8 +2915,7 @@ bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map
QString lhs = line.mid(pos1 + 1, pos2 - pos1 - 1); QString lhs = line.mid(pos1 + 1, pos2 - pos1 - 1);
QString rhs = line.mid(pos2 + 1); QString rhs = line.mid(pos2 + 1);
Inputs key; Inputs key;
foreach (QChar c, lhs) key.parseFrom(lhs);
key.append(Input(c));
//qDebug() << "MAPPING: " << modes << lhs << rhs; //qDebug() << "MAPPING: " << modes << lhs << rhs;
switch (type) { switch (type) {
case Unmap: case Unmap:
@@ -2885,9 +2927,7 @@ bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map
rhs = rhs; // FIXME: expand rhs. rhs = rhs; // FIXME: expand rhs.
// Fall through. // Fall through.
case Noremap: { case Noremap: {
Inputs inputs; Inputs inputs(rhs);
foreach (QChar c, rhs)
inputs.append(Input(c));
foreach (char c, modes) foreach (char c, modes)
g.mappings[c].insert(key, inputs); g.mappings[c].insert(key, inputs);
break; break;