Back to index

texmacs  1.0.7.15
tm_config.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_config.cpp
00004 * DESCRIPTION: Configuration routines for TeXmacs server
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "tm_config.hpp"
00013 #include "analyze.hpp"
00014 
00015 /******************************************************************************
00016 * Constructor and destructor
00017 ******************************************************************************/
00018 
00019 tm_config_rep::tm_config_rep ():
00020   var_suffix (" tab"), unvar_suffix (" S-tab") {}
00021 
00022 tm_config_rep::~tm_config_rep () {}
00023 
00024 /******************************************************************************
00025 * Setup TeXmacs fonts
00026 ******************************************************************************/
00027 
00028 void
00029 tm_config_rep::set_font_rules (scheme_tree rules) {
00030   int i, n= arity (rules);
00031   for (i=0; i<n; i++)
00032     if (arity (rules [i]) == 2) {
00033       tree l= (tree) rules[i][0];
00034       tree r= (tree) rules[i][1];
00035       font_rule (l, r);
00036     }  
00037 }
00038 
00039 /******************************************************************************
00040 * Latex and user commands
00041 ******************************************************************************/
00042 
00043 bool
00044 tm_config_rep::kbd_get_command (string which, string& help, command& cmd) {
00045   object im= call ("kbd-get-command", which);
00046   if (im == object (false)) return false;
00047   help= as_string (car (im));
00048   cmd = as_command (cdr (im));
00049   return true;
00050 }
00051 
00052 /******************************************************************************
00053 * Wildcards for keyboard bindings
00054 ******************************************************************************/
00055 
00056 static string
00057 apply_wildcards (string s, hashmap<string,tree> w) {
00058   int len, start, end, n= N(s);
00059   for (len=n; len>0; len--) {
00060     for (start=0; start <= (n-len); start++) {
00061       end= start+ len;
00062       if ((start>0) && (s[start-1] != ' ') && (s[start-1] != '-')) continue;
00063       if ((end<n) && (s[end-1] != ' ') && (s[end-1] != '-')) continue;
00064       string ss= s (start, end);
00065       if (s[end-1] == ' ') ss= s (start, end-1);
00066 
00067       // cout << "  " << ss << " => " << w[ss] << LF;
00068       if (w->contains (ss)) {
00069        tree t= w[ss];
00070        string rr= t[0]->label;
00071        bool lflag= (t[1]->label != "") || (start == 0);
00072        bool rflag= (t[2]->label != "") || (end == n);
00073        if (lflag && rflag) {
00074          if ((end<n) && (rr != "") && (rr[N(rr)-1] != '-')) rr= rr * " ";
00075          string r= s (0, start) * rr * s (end, n);
00076          return apply_wildcards (r, w);
00077        }
00078       }      
00079     }
00080   }
00081   return s;
00082 }
00083 
00084 void
00085 tm_config_rep::insert_kbd_wildcard (
00086   string key, string im, bool post, bool l, bool r)
00087 {
00088   //cout << "Wildcard " << key << " -> " << im << "\n";
00089   tree t= tuple (im,
00090                l? string ("*"): string (""),
00091                r? string ("*"): string (""));
00092   if (post) post_kbd_wildcards (key)= t;
00093   else pre_kbd_wildcards (key)= t;
00094 }
00095 
00096 /******************************************************************************
00097 * Variants
00098 ******************************************************************************/
00099 
00100 void
00101 tm_config_rep::set_variant_keys (string var, string unvar) {
00102   var_suffix= " " * var;
00103   unvar_suffix= " " * unvar;
00104 }
00105 
00106 #define rewrite_find_key_binding(s) \
00107   find_key_binding (apply_wildcards (s, post_kbd_wildcards))
00108 
00109 void
00110 tm_config_rep::variant_simplification (string& which) {
00111   if (ends (which, var_suffix)) {
00112     object obj= rewrite_find_key_binding (which);
00113     // cout << which << " => " << obj << LF;
00114     if (obj == object (false))
00115       while (ends (which, var_suffix))
00116        which= which (0, N(which) - N(var_suffix));
00117   }
00118   if (ends (which, unvar_suffix)) {
00119     if (ends (which, var_suffix * unvar_suffix))
00120       which= which (0, N(which) - N(var_suffix) - N(unvar_suffix));
00121     else {
00122       which= which (0, N(which) - N(unvar_suffix));
00123       while (true) {
00124        if (rewrite_find_key_binding (which * var_suffix) == object (false))
00125          break;
00126        which= which * var_suffix;
00127       }
00128     }
00129   }
00130 }
00131 
00132 /******************************************************************************
00133 * Server keyboard mappings and shorthands
00134 ******************************************************************************/
00135 
00136 object
00137 tm_config_rep::find_key_binding (string key) {
00138   return call ("kbd-find-key-binding", key);
00139 }
00140 
00141 string
00142 tm_config_rep::kbd_pre_rewrite (string s) {
00143   return apply_wildcards (s, pre_kbd_wildcards);
00144 }
00145 
00146 string
00147 tm_config_rep::kbd_post_rewrite (string s, bool var_flag) {
00148   if (var_flag) variant_simplification (s);
00149   return apply_wildcards (s, post_kbd_wildcards);
00150 }
00151 
00152 void
00153 tm_config_rep::get_keycomb (
00154   string& which, int& status, command& cmd, string& shorth, string& help)
00155 {
00156   string orig= which;
00157   if (DEBUG_KEYBOARD) cout << "        ] " << which;
00158   variant_simplification (which);
00159   if (DEBUG_KEYBOARD) cout << " -> " << which;
00160   string rew= apply_wildcards (which, post_kbd_wildcards);
00161   bool no_var= false;
00162   if (rew * var_suffix == orig) {
00163     no_var= true;
00164     rew= var_suffix (1, N(var_suffix));
00165   }
00166   if (rew * unvar_suffix == orig) {
00167     no_var= true;
00168     rew= unvar_suffix (1, N(unvar_suffix));
00169   }
00170   if (DEBUG_KEYBOARD) cout << " -> " << rew << LF;
00171   object obj= find_key_binding (rew);
00172   //cout << rew << " => " << obj << LF;
00173   //if (obj == object (false) || (orig != which && !is_string (car (obj)))) {
00174   if (obj == object (false)) {
00175     status= 0;
00176     cmd   = command ();
00177     shorth= copy (rew);
00178     help  = "";
00179   }
00180   else if (!is_string (car (obj))) {
00181     status= 1;
00182     cmd   = as_command (car (obj));
00183     shorth= copy (rew);
00184     help  = as_string (cadr (obj));
00185   }
00186   else {
00187     status= 2;
00188     cmd   = command ();
00189     shorth= as_string (car (obj));
00190     help  = as_string (cadr (obj));
00191   }
00192   if (no_var) status += 3;
00193 }
00194 
00195 /******************************************************************************
00196 * System dependent rendering of keyboard shortcuts
00197 ******************************************************************************/
00198 
00199 static tree
00200 localize (string s, bool mod_flag= false) {
00201   if (mod_flag) return tree (CONCAT, localize (s), "+");
00202   else return compound ("localize", s);
00203 }
00204 
00205 tree
00206 mathop (string s) {
00207   return compound ("math", compound ("op", s));
00208 }
00209 
00210 static void
00211 system_kbd_initialize (hashmap<string,tree>& h) {
00212   if (N(h) != 0);
00213   else if (use_macos_fonts ()) {
00214     h ("S-")= "<#21E7>";
00215     h ("C-")= "<#2303>";
00216     h ("A-")= "<#2325>";
00217     h ("M-")= "<#2318>";
00218     h ("H-")= localize ("Hyper");
00219     h ("windows")= localize ("Windows");
00220     h ("capslock")= "<#21EA>";
00221     h ("return")= "<#21A9>";
00222     h ("delete")= "<#2326>";
00223     h ("backspace")= "<#232B>";
00224     h ("clear")= "<#2327>";
00225     h ("escape")= "<#238B>";
00226     h ("space")= "Space";
00227     h ("var")= "<#21E5>";
00228     h ("tab")= "<#21E5>";
00229     h ("left")= "<#2190>";
00230     h ("right")= "<#2192>";
00231     h ("up")= "<#2191>";
00232     h ("down")= "<#2193>";
00233     h ("home")= "<#2196>";
00234     h ("end")= "<#2198>";
00235     h ("pageup")= "<#21DE>";
00236     h ("pagedown")= "<#21DF>";
00237     h ("<less>")= "<#3C>";
00238     h ("<gtr>")= "<#3E>";
00239   }
00240   else if (gui_is_qt ()) {
00241     h ("S-")= localize ("Shift", true);
00242     h ("C-")= localize ("Ctrl", true);
00243     h ("A-")= localize ("Alt", true);
00244     h ("M-")= localize ("Meta", true);
00245     h ("H-")= localize ("Hyper", true);
00246     h ("windows")= localize ("Windows");
00247     h ("capslock")= localize ("Capslock");
00248     h ("return")= localize ("Return");
00249     h ("delete")= localize ("Delete");
00250     h ("backspace")= localize ("Backspace");
00251     h ("escape")= localize ("Escape");
00252     h ("space")= localize ("Space");
00253     h ("var")= localize ("Tab");
00254     h ("tab")= localize ("Tab");
00255     h ("left")= mathop ("<leftarrow>");
00256     h ("right")= mathop ("<rightarrow>");
00257     h ("up")= mathop ("<uparrow>");
00258     h ("down")= mathop ("<downarrow>");
00259     h ("home")= localize ("Home");
00260     h ("end")= localize ("End");
00261     h ("pageup")= localize ("PageUp");
00262     h ("pagedown")= localize ("PageDown");
00263   }
00264   else {
00265     h ("S-")= "S-";
00266     h ("C-")= "C-";
00267     h ("A-")= "A-";
00268     h ("M-")= "M-";
00269     h ("H-")= "H-";
00270     h ("windows")= localize ("windows");
00271     h ("capslock")= localize ("capslock");
00272     h ("return")= localize ("return");
00273     h ("delete")= localize ("delete");
00274     h ("backspace")= localize ("backspace");
00275     h ("escape")= localize ("escape");
00276     h ("space")= localize ("space");
00277     h ("var")= localize ("tab");
00278     h ("tab")= localize ("tab");
00279     h ("left")= mathop ("<leftarrow>");
00280     h ("right")= mathop ("<rightarrow>");
00281     h ("up")= mathop ("<uparrow>");
00282     h ("down")= mathop ("<downarrow>");
00283     h ("home")= localize ("home");
00284     h ("end")= localize ("end");
00285     h ("pageup")= localize ("pageup");
00286     h ("pagedown")= localize ("pagedown");
00287   }
00288 }
00289 
00290 static tree
00291 kbd_render (tree t) {
00292   if (use_macos_fonts ())
00293     t= tree (WITH, "font", "apple-lucida", t);
00294   return compound ("render-key", t);
00295 }
00296 
00297 static string
00298 kbd_system_prevails (string s) {
00299   string laf= get_preference ("look and feel");
00300   bool   mac= os_macos () && (laf == "default" || laf == "macos");
00301   if (mac && starts (s, "A-")) {
00302     string ss= s (2, N(s));
00303     string r = "escape " * ss;
00304     if (starts (ss, "S-")) ss= ss (2, N(ss));
00305     if (N(ss) == 1) return r;
00306     else return s;
00307   }
00308   else return s;
00309 }
00310 
00311 tree
00312 tm_config_rep::kbd_system_rewrite (string s) {
00313   system_kbd_initialize (system_kbd_decode);
00314   int start= 0, i;
00315   for (i=0; i <= N(s); i++)
00316     if (i == N(s) || s[i] == ' ') {
00317       string ss= s (start, i);
00318       string rr= kbd_system_prevails (ss);
00319       if (rr != ss)
00320        return kbd_system_rewrite (s (0, start) * rr * s (i, N(s)));
00321       start= i+1;
00322     }
00323 
00324   tree k (CONCAT);
00325   tree r (CONCAT);
00326   start= i= 0;
00327   while (true)
00328     if (i == N(s) || s[i] == '-' || s[i] == ' ') {
00329       if (i < N(s) && s[i] == '-') i++;
00330       string ss= s (start, i);
00331       if (system_kbd_decode->contains (ss)) r << system_kbd_decode[ss];
00332       else if (N(ss) == 1 && (use_macos_fonts () || gui_is_qt ())) {
00333        if (is_locase (ss[0])) r << upcase_all (ss);
00334        else if (is_upcase (ss[0])) r << system_kbd_decode ("S-") << ss;
00335        else r << ss;
00336       }
00337       else r << ss;
00338       if (i == N(s) || s[i] == ' ') {
00339        k << kbd_render (simplify_concat (r));
00340        r= tree (CONCAT);
00341        if (i == N(s)) break;
00342        i++;
00343       }
00344       start= i;
00345     }
00346     else i++;
00347   return simplify_concat (k);
00348 }