Jean-Marc Lasgouttes schrieb:
Bernhard Roider <[EMAIL PROTECTED]> writes:

- it is wrong to define that in binding files, since these definitions
  are available to menus and toolbars too. I propose to move the
  definitions to their own file.
ok, then should we create another directory like "bind" or "ui"?

Either that, or just one file. I do not really know.
Do we want a default file that is always read? Do we want also a
user-defined file?

It could be two files
default.cmd
user.cmd

What do other think?

JMarc


The attached patch implements a CmdDef class and reading of *.cmd files similar to the *.bind files. There is no user interface yet.

bernhard
Index: src/CmdDef.cpp
===================================================================
--- src/CmdDef.cpp      (revision 0)
+++ src/CmdDef.cpp      (revision 0)
@@ -0,0 +1,202 @@
+/**
+ * \file CmdDef.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Bernhard Roider
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "CmdDef.h"
+
+#include "LyXAction.h"
+#include "debug.h"
+#include "Lexer.h"
+
+#include "support/filetools.h"
+#include "support/lstrings.h"
+
+using std::endl;
+using std::string;
+
+namespace lyx {
+
+using support::FileName;
+using support::i18nLibFileSearch;
+using support::trim;
+
+
+namespace {
+
+enum CmdDefTags {
+       BN_DEFFILE,
+       BN_DEFINE
+};
+
+keyword_item cmdDefTags[] = {
+       { "\\def_file", BN_DEFFILE },
+       { "\\define", BN_DEFINE }
+};
+
+}
+
+
+bool CmdDef::read(string const & def_file)
+{
+       const int cmdDefCount = sizeof(cmdDefTags) / sizeof(keyword_item);
+
+       Lexer lexrc(cmdDefTags, cmdDefCount);
+       if (lyxerr.debugging(Debug::PARSER))
+               lexrc.printTable(lyxerr);
+
+       FileName const tmp(i18nLibFileSearch("commands", def_file, "def"));
+       lexrc.setFile(tmp);
+       if (!lexrc.isOK()) {
+               lyxerr << "CmdDef::read: cannot open def file:"
+                      << tmp << endl;
+               return false;
+       }
+
+//     LYXERR(Debug::KBMAP) << "Reading def file:" << tmp << endl;
+
+       bool error = false;
+       while (lexrc.isOK()) {
+               switch (lexrc.lex()) {
+               case Lexer::LEX_UNDEF:
+                       lexrc.printError("Unknown tag `$$Token'");
+                       error = true;
+                       continue;
+               case Lexer::LEX_FEOF:
+                       continue;
+               case BN_DEFINE:
+               {
+                       string name, def;
+
+                       if (lexrc.next()) {
+                               name = lexrc.getString();
+                       } else {
+                               lexrc.printError("BN_DEFINE: Missing command 
name");
+                               error = true;
+                               break;
+                       }
+
+                       if (lexrc.next(true)) {
+                               def = lexrc.getString();
+                       } else {
+                               lexrc.printError("BN_DEFINE: missing command 
definition");
+                               error = true;
+                               break;
+                       }
+
+                       newCmdDefResult e = newCmdDef(name, def);
+                       switch (e) {
+                               case CmdDefNameEmpty:
+                                       lexrc.printError("BN_DEFINE: Command 
name is empty");
+                                       error = true;
+                                       break;
+                               case CmdDefExists:
+                                       lexrc.printError("BN_DEFINE: Command `" 
+ name + "' already defined");
+                                       error = true;
+                                       break;
+                               case CmdDefInvalid:
+                                       lexrc.printError("BN_DEFINE: Command 
definition for `" + name + "' is not valid");
+                                       error = true;
+                       }
+
+                       break;
+               }
+               case BN_DEFFILE:
+                       if (lexrc.next()) {
+                               string const tmp(lexrc.getString());
+                               error |= !read(tmp);
+                       } else {
+                               lexrc.printError("BN_DEFFILE: Missing file 
name");
+                               error = true;
+                               break;
+
+                       }
+                       break;
+               }
+       }
+
+       if (error)
+               lyxerr << "CmdDef::read: error while reading def file:"
+                      << tmp << endl;
+       return !error;
+}
+
+
+bool CmdDef::lock(string const & name, FuncRequest & func)
+{
+       if (cmdDefMap.empty())
+       {
+               func = FuncRequest::unknown;
+               return false;
+       }
+
+       string const name2 = trim(name);
+
+       CmdDefMap::const_iterator pos = cmdDefMap.find(name2);
+
+       if (pos == cmdDefMap.end()) 
+       {
+               func = FuncRequest::unknown;
+               return false;
+       }
+
+       if (pos->second->locked)
+       {
+               func = FuncRequest::noaction;
+               return false;
+       }
+
+       pos->second->locked = true;
+       func = pos->second->func;
+       return true;
+}
+
+
+void CmdDef::release(string const & name)
+{
+       if (cmdDefMap.empty()) 
+               return;
+
+       string const name2 = trim(name);
+
+       CmdDefMap::const_iterator pos = cmdDefMap.find(name2);
+
+       if (pos == cmdDefMap.end()) 
+               return;
+
+       pos->second->locked = false;
+}
+
+CmdDef::newCmdDefResult CmdDef::newCmdDef(string const & name, 
+                                                                               
  string const & def)
+{
+       string const name2 = trim(name);
+
+       if (name2.empty()) 
+               return CmdDefNameEmpty;
+
+       if (cmdDefMap.find(name) != cmdDefMap.end())
+               return CmdDefExists;
+
+       FuncRequest     func = lyxaction.lookupFunc(def);
+       if (func.action == LFUN_NOACTION ||
+               func.action == LFUN_UNKNOWN_ACTION) {
+                       return CmdDefInvalid;
+       }
+
+       boost::shared_ptr<CmdDefInfo> info;
+       info.reset(new CmdDefInfo(func));
+       cmdDefMap[name2] = info;
+
+       return CmdDefOk;
+}
+
+
+} // namespace lyx
Index: src/CmdDef.h
===================================================================
--- src/CmdDef.h        (revision 0)
+++ src/CmdDef.h        (revision 0)
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+/**
+ * \file CmdDef.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Bernhard Roider
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef CMDDEF_H
+#define CMDDEF_H
+
+#include "FuncRequest.h"
+
+#include "support/docstream.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include <vector>
+#include <deque>
+
+
+namespace lyx {
+
+/// Creates command definitions
+class CmdDef {
+private:
+       /// information for a definition
+       struct CmdDefInfo {
+               CmdDefInfo(FuncRequest const & f): func(f), locked(false) {}
+               /// the expanded FuncRequest
+               FuncRequest func;
+               /// to avoid recursive calls
+               bool locked;
+       };
+
+
+       /// type for map between a macro name and its info
+       typedef std::map<std::string, boost::shared_ptr<CmdDefInfo> > CmdDefMap;
+
+public:
+
+       /// Parse a def file
+       bool read(std::string const & def_file);
+
+       /**
+        * Look up a definition, lock it and return the
+        * associated action if it is not locked.
+        * @param name the name of the command
+        * @param func contains the action on success
+        * @return true if lock was successful
+        */
+       bool lock(std::string const & name, FuncRequest & func);
+
+       /// release a locked definition
+       void release(std::string const & name);
+
+private:
+
+       /// possible reasons for not allowed definitions
+       enum newCmdDefResult {
+               CmdDefOk,
+               CmdDefNameEmpty,
+               CmdDefInvalid,
+               CmdDefExists
+       };
+
+       /**
+        * Add a new command definition.
+        * @param name internal recursion level
+        */
+       newCmdDefResult newCmdDef(std::string const & name, 
+               std::string const & def);
+
+       ///
+       CmdDefMap cmdDefMap;
+};
+
+/// Implementation is in LyX.cpp
+extern CmdDef & theTopLevelCmdDef();
+
+
+} // namespace lyx
+
+#endif // CMDDEF_H
Index: src/frontends/qt4/GuiToolbar.cpp
===================================================================
--- src/frontends/qt4/GuiToolbar.cpp    (revision 20969)
+++ src/frontends/qt4/GuiToolbar.cpp    (working copy)
@@ -444,6 +444,9 @@
        case LFUN_MATH_BIGDELIM:
                fullname = find_png(to_utf8(f.argument()));
                break;
+       case LFUN_CALL:
+               fullname = libFileSearch("images", to_utf8(f.argument()), 
"png").absFilename();
+               break;
        default:
                string const name = lyxaction.getActionName(f.action);
                string png_name = name;
Index: src/FuncRequest.cpp
===================================================================
--- src/FuncRequest.cpp (revision 20969)
+++ src/FuncRequest.cpp (working copy)
@@ -24,6 +24,8 @@
 
 namespace lyx {
 
+FuncRequest const FuncRequest::unknown(LFUN_UNKNOWN_ACTION);
+FuncRequest const FuncRequest::noaction(LFUN_NOACTION);
 
 FuncRequest::FuncRequest(Origin o)
        : action(LFUN_NOACTION), origin(o), x(0), y(0),
Index: src/FuncRequest.h
===================================================================
--- src/FuncRequest.h   (revision 20969)
+++ src/FuncRequest.h   (working copy)
@@ -67,6 +67,10 @@
        /// access the whole argument
        docstring const & argument() const { return argument_; }
 
+       /// 
+       static FuncRequest const unknown;
+       /// 
+       static FuncRequest const noaction;
 public:  // should be private
        /// the action
        kb_action action;
Index: src/lfuns.h
===================================================================
--- src/lfuns.h (revision 20969)
+++ src/lfuns.h (working copy)
@@ -404,6 +404,8 @@
        LFUN_MASTER_BUFFER_VIEW,         // Tommaso, 20070920
        LFUN_MASTER_BUFFER_UPDATE,       // Tommaso, 20070920
        LFUN_INFO_INSERT,                // bpeng, 20071007
+       // 295
+       LFUN_CALL,                       // broider, 20071002
 
        LFUN_LASTACTION                  // end of the table
 };
Index: src/LyX.cpp
===================================================================
--- src/LyX.cpp (revision 20969)
+++ src/LyX.cpp (working copy)
@@ -29,6 +29,7 @@
 #include "Format.h"
 #include "gettext.h"
 #include "KeyMap.h"
+#include "CmdDef.h"
 #include "Language.h"
 #include "Session.h"
 #include "Color.h"
@@ -169,6 +170,8 @@
        ///
        boost::scoped_ptr<KeyMap> toplevel_keymap_;
        ///
+       boost::scoped_ptr<CmdDef> toplevel_cmddef_;
+       ///
        boost::scoped_ptr<Server> lyx_server_;
        ///
        boost::scoped_ptr<ServerSocket> lyx_socket_;
@@ -320,6 +323,13 @@
 }
 
 
+CmdDef & LyX::topLevelCmdDef()
+{
+       BOOST_ASSERT(pimpl_->toplevel_cmddef_.get());
+       return *pimpl_->toplevel_cmddef_.get();
+}
+
+
 Converters & LyX::converters()
 {
        return pimpl_->converters_;
@@ -966,6 +976,10 @@
        // Set the language defined by the user.
        //setGuiLanguage(lyxrc.gui_language);
 
+       // Set up command definitions
+       pimpl_->toplevel_cmddef_.reset(new CmdDef);
+       pimpl_->toplevel_cmddef_->read(lyxrc.def_file);
+
        // Set up bindings
        pimpl_->toplevel_keymap_.reset(new KeyMap);
        defaultKeyBindings(pimpl_->toplevel_keymap_.get());
Index: src/LyX.h
===================================================================
--- src/LyX.h   (revision 20969)
+++ src/LyX.h   (working copy)
@@ -38,6 +38,7 @@
 class Movers;
 class Session;
 class KeyMap;
+class CmdDef;
 
 extern bool use_gui;
 
@@ -87,6 +88,9 @@
        KeyMap const & topLevelKeymap() const;
 
        ///
+       CmdDef & topLevelCmdDef();
+
+       ///
        Converters & converters();
        Converters & systemConverters();
 
Index: src/LyXAction.cpp
===================================================================
--- src/LyXAction.cpp   (revision 20969)
+++ src/LyXAction.cpp   (working copy)
@@ -144,6 +144,7 @@
                { LFUN_COMMAND_EXECUTE, "command-execute", NoBuffer },
                { LFUN_COMMAND_PREFIX, "command-prefix", NoBuffer },
                { LFUN_COMMAND_SEQUENCE, "command-sequence", NoBuffer },
+               { LFUN_CALL, "call", NoBuffer | ReadOnly},
                { LFUN_COPY, "copy", ReadOnly },
                { LFUN_CUT, "cut", Noop },
                { LFUN_DATE_INSERT, "date-insert", Noop },
Index: src/LyXFunc.cpp
===================================================================
--- src/LyXFunc.cpp     (revision 20969)
+++ src/LyXFunc.cpp     (working copy)
@@ -28,6 +28,7 @@
 #include "BufferList.h"
 #include "BufferParams.h"
 #include "BufferView.h"
+#include "CmdDef.h"
 #include "Color.h"
 #include "Cursor.h"
 #include "CutAndPaste.h"
@@ -669,8 +670,25 @@
                FuncRequest func(lyxaction.lookupFunc(firstcmd));
                func.origin = cmd.origin;
                flag = getStatus(func);
+               break;
        }
 
+       case LFUN_CALL: {
+               FuncRequest func;
+               std::string name(to_utf8(cmd.argument()));
+               if (LyX::ref().topLevelCmdDef().lock(name, func)) {
+                       func.origin = cmd.origin;
+                       flag = getStatus(func);
+                       LyX::ref().topLevelCmdDef().release(name);
+               } else {
+                       // catch recursion or unknown command definiton
+                       // all operations until the recursion or unknown 
command 
+                       // definiton occures are performed, so set the state to 
enabled
+                       enable = true;
+               }
+               break;
+       }
+
        case LFUN_BUFFER_NEW:
        case LFUN_BUFFER_NEW_TEMPLATE:
        case LFUN_WORD_FIND_FORWARD:
@@ -1605,6 +1623,28 @@
                        break;
                }
 
+               case LFUN_CALL: {
+                       FuncRequest func;
+                       if (LyX::ref().topLevelCmdDef().lock(argument, func)) {
+                               func.origin = cmd.origin;
+                               dispatch(func);
+                               LyX::ref().topLevelCmdDef().release(argument);
+                       } else {
+                               if (func.action == LFUN_UNKNOWN_ACTION) {
+                                       // unknown command definition
+                                       lyxerr << "Warning: unknown command 
definition `"
+                                                  << argument << "'"
+                                                  << endl;
+                               } else {
+                                       // recursion detected
+                                       lyxerr << "Warning: Recursion in the 
command definition `"
+                                                  << argument << "' detected"
+                                                  << endl;
+                               }
+                       }
+                       break;
+               }
+
                case LFUN_PREFERENCES_SAVE: {
                        lyxrc.write(makeAbsPath("preferences",
                                                
package().user_support().absFilename()),
Index: src/LyXRC.cpp
===================================================================
--- src/LyXRC.cpp       (revision 20969)
+++ src/LyXRC.cpp       (working copy)
@@ -84,6 +84,7 @@
        { "\\custom_export_command", LyXRC::RC_CUSTOM_EXPORT_COMMAND },
        { "\\custom_export_format", LyXRC::RC_CUSTOM_EXPORT_FORMAT },
        { "\\date_insert_format", LyXRC::RC_DATE_INSERT_FORMAT },
+       { "\\def_file", LyXRC::RC_DEFFILE },
        { "\\default_language", LyXRC::RC_DEFAULT_LANGUAGE },
        { "\\default_papersize", LyXRC::RC_DEFAULT_PAPERSIZE },
        { "\\dialogs_iconify_with_main", LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN },
@@ -189,6 +190,7 @@
 
 void LyXRC::setDefaults() {
        bind_file = "cua";
+       def_file = "default";
        ui_file = "default";
        // Get printer from the environment. If fail, use default "",
        // assuming that everything is set up correctly.
@@ -370,6 +372,12 @@
                        }
                        break;
 
+               case RC_DEFFILE:
+                       if (lexrc.next()) {
+                               def_file = os::internal_path(lexrc.getString());
+                       }
+                       break;
+
                case RC_UIFILE:
                        if (lexrc.next()) {
                                ui_file = os::internal_path(lexrc.getString());
@@ -1226,7 +1234,7 @@
                   << "###          LyX, The Document Processor\n"
                   << "###\n"
                   << "###          Copyright 1995 Matthias Ettrich\n"
-                  << "###          Copyright 1995-2001 The LyX Team.\n"
+                  << "###          Copyright 1995-2007 The LyX Team.\n"
                   << "###\n"
                   << "### 
========================================================\n"
                   << "\n"
@@ -1252,6 +1260,15 @@
                if (tag != RC_LAST)
                        break;
 
+       case RC_DEFFILE:
+               if (ignore_system_lyxrc ||
+                   def_file != system_lyxrc.def_file) {
+                       string const path = os::external_path(def_file);
+                       os << "\\def_file \"" << path << "\"\n";
+               }
+               if (tag != RC_LAST)
+                       break;
+
                //
                // Misc Section
                //
Index: src/LyXRC.h
===================================================================
--- src/LyXRC.h (revision 20969)
+++ src/LyXRC.h (working copy)
@@ -58,6 +58,7 @@
                RC_CUSTOM_EXPORT_COMMAND,
                RC_CUSTOM_EXPORT_FORMAT,
                RC_DATE_INSERT_FORMAT,
+               RC_DEFFILE,
                RC_DEFAULT_LANGUAGE,
                RC_DEFAULT_PAPERSIZE,
                RC_DIALOGS_ICONIFY_WITH_MAIN,
@@ -171,6 +172,8 @@
        ///
        std::string bind_file;
        ///
+       std::string def_file;
+       ///
        std::string ui_file;
        ///
        std::string printer;
Index: src/Makefile.am
===================================================================
--- src/Makefile.am     (revision 20969)
+++ src/Makefile.am     (working copy)
@@ -100,6 +100,8 @@
        Changes.h \
        Chktex.cpp \
        Chktex.h \
+       CmdDef.cpp \
+       CmdDef.h \
        Color.cpp \
        Color.h \
        config.h.in \
Index: lib/commands/default.def
===================================================================
--- lib/commands/default.def    (revision 0)
+++ lib/commands/default.def    (revision 0)
@@ -0,0 +1,20 @@
+# -*- text -*-
+
+# file default.def
+# This file is part of LyX, the document processor.
+# Licence details can be found in the file COPYING.
+
+# author Bernhard Roider
+
+# Full author contact details are available in file CREDITS.
+
+# This is the default command definition file.
+
+# DO NOT CHANGE THIS DEFAULT COMMAND DEFINITION FILE! It will be replaced
+# with every new install of LyX and your changes will be lost.
+# Instead, customize a copy of this file placed in
+# ~/.lyx/commands/default.bind
+#
+# Happy tuning!
+
+\define "InlineErtInsert" "command-sequence inset-insert ert 1; char-backward"

Reply via email to