export shortcuts as spreadsheet

Years ago I added code to do this in my personal build. I cleaned up the code, added a GUI and added a TXT option as well as CSV output.
The Preferences dialog for Keyboard sports two new buttons:
keys.png
The text output looks like:
asTXT.png
and the CSV opens in Excel as:
asCSV.png
(note–I have sized the columns appropriately above)
Putting each qualifier in a separate column allow one to sort the spreadsheet on multiple columns to easily see which key combos are used/available.

The new code adds the two buttons (if anyone is interested I will post the code but it is very simple) and adds a new wxArrayString (to save additional roundtrips through the name demangler and translation) to srcprefsKeyConfigPrefs.h:

class KeyConfigPrefs:public PrefsPanel 
{
   [...]
 private:
   [...]
   //efm5 start
   void OnPrintText2File(wxCommandEvent & WXevent);
   void OnPrintCSV2File(wxCommandEvent & WXevent);
   void Print2File(bool pCSV = false);
   wxArrayString mLabels;
   //efm5 end
   [...]
};

mLabels is built in srcprefsKeyConfigPrefs.cpp in the function void KeyConfigPrefs::RepopulateBindingsList():

void KeyConfigPrefs::RepopulateBindingsList()
{
   mLabels.Clear();//efm5
[...]
      wxString label;

      // Labels for undo and redo change according to the last command
      // which can be undone/redone, so give them a special check in order
      // not to confuse users
      if (name == wxT("Undo")) {
         label = _("Undo");
      }
      else if (name == wxT("Redo")) {
         label = _("Redo");
      }
      else {
         label = mManager->GetPrefixedLabelFromName(name);
      }

      label = wxMenuItem::GetLabelFromText(label.BeforeFirst(wxT('t')));
      mLabels.Add(label);//efm5
[...]
}

The code which responds to the new buttons may be added at the very end of srcprefsKeyConfigPrefs.cpp and is:

void KeyConfigPrefs::OnPrintText2File(wxCommandEvent & WXUNUSED(WXevent)) {
   Print2File();
}

void KeyConfigPrefs::OnPrintCSV2File(wxCommandEvent & WXUNUSED(WXevent)) {
   Print2File(true);
}

void KeyConfigPrefs::Print2File(bool pCSV) {
   size_t numberOfKeys = mLabels.Count();
   size_t numberOfShortcuts = mKeys.Count();
   if (numberOfKeys != numberOfShortcuts) {
      wxMessageBox(_("Error--the number of items does not equal the number of shortcuts!"));
      return;
   }
   //todo efm5 add default folder to prefs
   wxString fileType = wxT(".csv");
   if (!pCSV) 
      fileType = wxT(".txt");
   wxString outputFile = wxEmptyString;
   wxString outputFolder = wxEmptyString;
   wxString previousDirectory = gPrefs->Read(wxT("/Directories/Print2FileDir"), wxEmptyString);
   wxFileDialog * filePickerDialog = new wxFileDialog(((wxWindow *)this), _("Output File"), previousDirectory, wxEmptyString, fileType);
   if (filePickerDialog) {
      if (filePickerDialog->ShowModal() == wxID_OK) {
         outputFile = filePickerDialog->GetPath();
         wxFileName fileName(outputFile);
         outputFolder = fileName.GetPath();
      }
      delete filePickerDialog;
   }
   if (!outputFile.IsEmpty()) {
      wxFFile textFile(outputFile, wxT("w"));
      wxString label(_(","));
      if (!pCSV) {
         label = (wxT("  "));
         label.append(_("SHORTCUT:"));
         label.append(wxT("  "));
      }
      wxString unassigned(_("Unassigned"));
      bool wroteOK = false;
      size_t wroteNewLine = 0;
      for (size_t i = 0; i < numberOfKeys; i++) {
         wroteOK = textFile.Write(mLabels.Item(i));
         if (wroteOK) wroteOK = textFile.Write(label);
         if (wroteOK) {
            if (mKeys.Item(i).IsEmpty() && !pCSV)
               wroteOK = textFile.Write(unassigned);
            else {
               if (pCSV) {
                  wxString extendedKey(wxEmptyString);
                  bool hasQualifier = false;
                  if (mKeys.Item(i).Contains(wxT("Alt"))) {
                     extendedKey.Append(wxT("Alt"));
                     hasQualifier = true;
                  }
                  extendedKey.Append(wxT(","));
                  if (mKeys.Item(i).Contains(wxT("Ctrl"))) {
                     extendedKey.Append(wxT("Ctrl"));
                     hasQualifier = true;
                  }
                  extendedKey.Append(wxT(","));
                  if (mKeys.Item(i).Contains(wxT("Shift"))) {
                     extendedKey.Append(wxT("Shift"));
                     hasQualifier = true;
                  }
                  extendedKey.Append(wxT(","));
                  if (hasQualifier)
                     extendedKey.Append(mKeys.Item(i).AfterLast('+'));
                  else
                     extendedKey.Append(mKeys.Item(i));
                  wroteOK = textFile.Write(extendedKey);
               }
               else
                  wroteOK = textFile.Write(mKeys.Item(i));
            }
         }
         if (wroteOK) wroteOK = textFile.Write(wxT("n"));
         if (!wroteOK) {
            wxMessageBox(_("Write Error--writing shortcuts to file!"));
            return;
         }
      }
      gPrefs->Write(wxT("/Directories/Print2FileDir"), outputFolder);
   }
}

That looks like a very useful tool, especially for beginners that may frequently wish to look up shortcuts, or for users that are customising their shortcuts (though for one reason or another there’s not many new patches being committed at the moment).