JED Macro: keywords.sl

## keywords.sl

A set of macros to make lists of keywords for language modes more manageable.

Create keyword lists to be used in define_keywords_n. You can add keywords to the keyword lists in multiple steps. Keywords are separated by whitespace. You can mix words of different sizes. The sort order of keywords is not important.

Very helpful when you define syntaxes for similar languages or language variants. (SQL: sql92, postgresql, mysql, oracle, mssql; some keywords are the same in all variants, but some are dbms-specific)

### Installation

Put the file somewhere on your `jed_library_path`. See the example below.

### Remark

Use of this system is slower than use of `define_keywords_n` calls, but the difference might be noticeable only when first using a mode in a session. You can also use `write_keywords` to prepare a list of `define_keywords_n` calls.

### Examples of use

Example 1: A "simple" mode with simple set of keywords

     % ----- file: simplemode.sl -----
     require("keywords");

     define simple_mode(mode)
     {
        K = keywords->new_keyword_list();
        keywords->add_keywords(K, "if then else while do until");
        keywords->add_keywords(K, "cos sin tan acos asin atan");
        keywords->sort_keywords(K);
        keywords->strlow_keywords(K);
        keywords->define_keywords(K, "simple", 0);

        set_mode("simple", 2 | 8);
        use_syntax_table ("simple");
     }

If the mode is case-insensitive (`set_syntax_flags`, flag 0x01), all the keywords must be in lower-case. We can obtain this by calling `keywords->strlow_keywords(K)`.

Example 2: Prepare define_keywords_n calls for "simple" mode and write them into buffer "temp_buffer":

     % ----- file: prep_simplemode.sl -----
     require("keywords");

     K = keywords->new_keyword_list();
     keywords->add_keywords(K, "if then else while do until");
     keywords->add_keywords(K, "cos sin tan acos asin atan");
     keywords->sort_keywords(K);

     write_keywords(K, "simple", 0, "temp_buffer");

Example 3: SLang mode with 2 alternative color sets.

Notice: keyword-set might also be extended using runhooks ("xxx_define_keyword_hook").

     % ----- file: slangmode.sl -----
     require("keywords");

     % size and order of keywords in a string are irrelevant

     static variable kwds_control =
        "if else loop do while for _for foreach using forever switch case " +
        "orelse andelse break return continue";
     static variable kwds_struct  = "define variable struct typedef public private static";
     static variable kwds_logic   = "or and not xor";
     static variable kwds_math    = "chs mod shl shr sqr mul2 sign";
     static variable kwds_stack   = "pop exch";
     static variable kwds_block   = "EXIT_BLOCK ERROR_BLOCK EXECUTE_ERROR_BLOCK";
     static variable kwds_other   = "NULL __tmp";

     define create_mode(mode)
     {
        variable mode;
        !if (keywords->check_language(mode))
        {
           variable K;
           % CreateSyntaxTable();

           K = keywords->new_keyword_list();
           keywords->add_keywords(K, kwds_control);
           keywords->add_keywords(K, kwds_struct);
           keywords->add_keywords(K, kwds_logic);
           % runhooks("slang_define_keyword_hook", K, 0); %% User could add more keywords!
           keywords->sort_keywords(K);
           keywords->define_keywords(K, mode, 0);

           K = keywords->new_keyword_list();
           keywords->add_keywords(K, kwds_math);
           keywords->add_keywords(K, kwds_stack);
           if (mode == "SLANG")
           {
              keywords->add_keywords(K, kwds_block);
              keywords->add_keywords(K, kwds_other);
           }
           % runhooks("slang_define_keyword_hook", K, 1);
           keywords->sort_keywords(K);
           keywords->define_keywords(K, mode, 1);

           if (mode == "SLANG2")
           {
              K = keywords->new_keyword_list();
              keywords->add_keywords(K, kwds_block);
              keywords->add_keywords(K, kwds_other);
              % runhooks("slang_define_keyword_hook", K, 2);
              keywords->sort_keywords(K);
              keywords->define_keywords(K, mode, 2);
           }

           keywords->add_language(mode);
        }

        set_mode("SLang", 2 | 8);
        c_mode_common ();
        use_syntax_table (mode);
        mode_set_mode_info ("SLang", "fold_info", "%{{{\r%}}}\r\r");
        run_mode_hooks("slang_mode_hook");
     }

     define slang_mode ()  { create_mode ("SLANG", 0); }
     define slang2_mode () { create_mode ("SLANG2", 1); }