Le 25/07/2022 à 12:59, Kornel Benko a écrit :
We could stay with the current patch. It is good enough for what you
want to do, isn't it?

Yes, it is.

I could not resist. Try this one, please.

JMarc

From f0d8efec3ec11a3a1d8ab61b864720122f7f1c17 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Wed, 27 Jul 2022 11:52:50 +0200
Subject: [PATCH] Allow to unbind without specifying the lfun

When unbinding a shortcut, it may happen that the exact definition of
the request is not known. A typical example it Tab, which is bound to
a complex command sequence.

In this case it is convenient to use the syntax
\unbind "Tab" "*"

To make this word, the special "*" value is translated to the
FuncRequest::unknown lfun and this value is considered specially in
several places.
---
 src/KeyMap.cpp                | 52 +++++++++++++++++++----------------
 src/frontends/qt/GuiPrefs.cpp | 10 +++----
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/src/KeyMap.cpp b/src/KeyMap.cpp
index f469da5c44..b4a87d227c 100644
--- a/src/KeyMap.cpp
+++ b/src/KeyMap.cpp
@@ -160,29 +160,30 @@ void KeyMap::unbind(KeySequence * seq, FuncRequest const & func, unsigned int r)
 	KeyModifier const mod2 = seq->modifiers[r].second;
 
 	// check if key is already there
+	vector <Table::iterator> removes;
 	Table::iterator end = table.end();
-	Table::iterator remove = end;
 	for (Table::iterator it = table.begin(); it != end; ++it) {
 		if (code == it->code
 		    && mod1 == it->mod.first
 		    && mod2 == it->mod.second) {
 			// remove
 			if (r + 1 == seq->length()) {
-				if (it->func == func) {
-					remove = it;
+				if (it->func == func || func == FuncRequest::unknown) {
+					removes.push_back(it);
 					if (it->prefixes)
 						it->prefixes.reset();
 				}
 			} else if (it->prefixes) {
 				it->prefixes->unbind(seq, func, r + 1);
 				if (it->prefixes->empty())
-					remove = it;
+					removes.push_back(it);
 				return;
 			}
 		}
 	}
-	if (remove != end)
-		table.erase(remove);
+
+	for (unsigned i = removes.size(); i > 0; --i)
+		table.erase(removes[i-1]);
 }
 
 
@@ -333,7 +334,7 @@ KeyMap::ReturnValues KeyMap::readWithoutConv(FileName const & bind_file, KeyMap
 			string cmd = lexrc.getString();
 
 			FuncRequest func = lyxaction.lookupFunc(cmd);
-			if (func.action() == LFUN_UNKNOWN_ACTION) {
+			if (func == FuncRequest::unknown) {
 				lexrc.printError("BN_BIND: Unknown LyX function `$$Token'");
 				error = true;
 				break;
@@ -357,13 +358,16 @@ KeyMap::ReturnValues KeyMap::readWithoutConv(FileName const & bind_file, KeyMap
 				break;
 			}
 			string cmd = lexrc.getString();
-
-			FuncRequest func = lyxaction.lookupFunc(cmd);
-			if (func.action() == LFUN_UNKNOWN_ACTION) {
-				lexrc.printError("BN_UNBIND: Unknown LyX"
-						 " function `$$Token'");
-				error = true;
-				break;
+			FuncRequest func;
+			if (cmd == "*")
+				func = FuncRequest::unknown;
+			else {
+				func = lyxaction.lookupFunc(cmd);
+				if (func == FuncRequest::unknown) {
+					lexrc.printError("BN_UNBIND: Unknown LyX function `$$Token'");
+					error = true;
+					break;
+				}
 			}
 
 			if (unbind_map)
@@ -409,17 +413,17 @@ void KeyMap::write(string const & bind_file, bool append, bool unbind) const
 		   << "Format " << LFUN_FORMAT << "\n\n";
 
 	string tag = unbind ? "\\unbind" : "\\bind";
-	BindingList const list = listBindings(false);
-	BindingList::const_iterator it = list.begin();
-	BindingList::const_iterator it_end = list.end();
-	for (; it != it_end; ++it) {
-		FuncCode action = it->request.action();
-		string arg = to_utf8(it->request.argument());
-
-		string const cmd = lyxaction.getActionName(action)
-			+ (arg.empty() ? string() : " " + arg) ;
+	for (auto const & bnd : listBindings(false)) {
+		FuncCode const action = bnd.request.action();
+		string const arg = to_utf8(bnd.request.argument());
+
+		string cmd;
+		if (unbind && bnd.request == FuncRequest::unknown)
+			cmd = "*";
+		else
+			cmd = lyxaction.getActionName(action) + (arg.empty() ? string() : " " + arg);
 		os << tag << " \""
-		   << to_utf8(it->sequence.print(KeySequence::BindFile))
+		   << to_utf8(bnd.sequence.print(KeySequence::BindFile))
 		   << "\" " << Lexer::quoteString(cmd)
 		   << "\n";
 	}
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index 2b6b9cd1cb..31da12936f 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -3087,10 +3087,10 @@ QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
 	QTreeWidgetItem * newItem = nullptr;
 	// for unbind items, try to find an existing item in the system bind list
 	if (tag == KeyMap::UserUnbind) {
-		QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
-			Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
+		QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(shortcut,
+			Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
 		for (auto const & item : items) {
-			if (item->text(1) == shortcut) {
+			if (item->text(0) == lfun_name || lfun == FuncRequest::unknown) {
 				newItem = item;
 				break;
 			}
@@ -3125,10 +3125,10 @@ QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
 			// this should not happen
 			newItem = new QTreeWidgetItem(shortcutsTW);
 		}
+		newItem->setText(0, lfun_name);
+		newItem->setText(1, shortcut);
 	}
 
-	newItem->setText(0, lfun_name);
-	newItem->setText(1, shortcut);
 	// record BindFile representation to recover KeySequence when needed.
 	newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
 	setItemType(newItem, tag);
-- 
2.25.1

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to