Index: compile_rules_graph.py
==================================================================
--- compile_rules_graph.py
+++ compile_rules_graph.py
@@ -44,12 +44,12 @@
     sCode = re.sub(r"\b(select|exclude|define|definefrom|rewrite|addmorph|setmeta)[(][\\]-(\d+)", 'g_\\1(lToken[nLastToken-\\2+1]', sCode)
     sCode = re.sub(r"\b(tagbefore|tagafter)[(][\\](\d+)", 'g_\\1(lToken[nTokenOffset+\\2], dTags', sCode)
     sCode = re.sub(r"\b(tagbefore|tagafter)[(][\\]-(\d+)", 'g_\\1(lToken[nLastToken-\\2+1], dTags', sCode)
     sCode = re.sub(r"\bspace[(][\\](\d+)", 'g_space(lToken[nTokenOffset+\\1], lToken[nTokenOffset+\\1+1]', sCode)
     sCode = re.sub(r"\bspace[(][\\]-(\d+)", 'g_space(lToken[nLastToken-\\1+1], lToken[nLastToken-\\1+2]', sCode)
-    sCode = re.sub(r"\banalyse_with_next[(][\\](\d+)", 'g_merged_analyse(lToken[nTokenOffset+\\1], lToken[nTokenOffset+\\1+1]', sCode)
-    sCode = re.sub(r"\banalyse_with_next[(][\\]-(\d+)", 'g_merged_analyse(lToken[nLastToken-\\1+1], lToken[nLastToken-\\1+2]', sCode)
+    sCode = re.sub(r"\bmorph2[(][\\](\d+)", 'g_morph2(lToken[nTokenOffset+\\1], lToken[nTokenOffset+\\1+1]', sCode)
+    sCode = re.sub(r"\bmorph2[(][\\]-(\d+)", 'g_morph2(lToken[nLastToken-\\1+1], lToken[nLastToken-\\1+2]', sCode)
     sCode = re.sub(r"\b(morph0?|tag|meta|value)\(>1", 'g_\\1(lToken[nLastToken+1]', sCode)                      # next token
     sCode = re.sub(r"\b(morph0?|tag|meta|value)\(<1", 'g_\\1(lToken[nTokenOffset]', sCode)                      # previous token
     sCode = re.sub(r"\b(morph0?|tag|meta|value)\(>(\d+)", 'g_\\1(g_token(lToken, nLastToken+\\2)', sCode)       # next token
     sCode = re.sub(r"\b(morph0?|tag|meta|value)\(<(\d+)", 'g_\\1(g_token(lToken, nTokenOffset+1-\\2)', sCode)   # previous token
     sCode = re.sub(r"\bspace[(](>1)", 'g_space(lToken[nLastToken+1], g_token(lToken, nLastToken+2)', sCode)     # next token

Index: gc_core/js/lang_core/gc_functions.js
==================================================================
--- gc_core/js/lang_core/gc_functions.js
+++ gc_core/js/lang_core/gc_functions.js
@@ -267,11 +267,11 @@
     }
     // search sPattern
     return lMorph.some(sMorph  =>  (sMorph.search(sPattern) !== -1));
 }
 
-function g_merged_analyse (oToken1, oToken2, cMerger, sPattern, sNegPattern="", bSetMorph=true) {
+function g_morph2 (oToken1, oToken2, cMerger, sPattern, sNegPattern="", bSetMorph=true) {
     // merge two token values, return True if <sNegPattern> not in morphologies and <sPattern> in morphologies (disambiguation off)
     let lMorph = gc_engine.oSpellChecker.getMorph(oToken1["sValue"] + cMerger + oToken2["sValue"]);
     if (lMorph.length == 0) {
         return false;
     }

Index: gc_core/py/lang_core/gc_functions.py
==================================================================
--- gc_core/py/lang_core/gc_functions.py
+++ gc_core/py/lang_core/gc_functions.py
@@ -221,11 +221,11 @@
     # search sPattern
     zPattern = re.compile(sPattern)
     return any(zPattern.search(sMorph)  for sMorph in lMorph)
 
 
-def g_merged_analyse (dToken1, dToken2, cMerger, sPattern, sNegPattern="", bSetMorph=True):
+def g_morph2 (dToken1, dToken2, cMerger, sPattern, sNegPattern="", bSetMorph=True):
     "merge two token values, return True if <sNegPattern> not in morphologies and <sPattern> in morphologies (disambiguation off)"
     lMorph = _oSpellChecker.getMorph(dToken1["sValue"] + cMerger + dToken2["sValue"])
     if not lMorph:
         return False
     # check negative condition

Index: gc_lang/fr/rules.grx
==================================================================
--- gc_lang/fr/rules.grx
+++ gc_lang/fr/rules.grx
@@ -2766,11 +2766,11 @@
     Mai 68
         <<- ~>> ␣
         <<- =>> define(\1, ":MP:m:i")
 
     ~^[A-ZÀÂÉÈÊÎÔ].  ~^[A-ZÀÂÉÈÊÎÔ].
-        <<- analyse_with_next(\1, " ", ":") ~>> ␣
+        <<- morph2(\1, " ", ":") ~>> ␣
         <<- __else__ and morph(\1, ":M") and morph(\2, ":V", ":[GM]") =>> define(\2, ":M2")
 
     Me  ~^[A-ZÀÂÉÈÊÎÔ].
         <<- =>> define(\1, ":T")
         <<- ~1>> *
@@ -5085,32 +5085,32 @@
 TEST: l’{{israélo belge}}
 
 
 __tu_préfixe_xxxo__
     [macro|magnéto|micro|paléo|rétro|rhino|stéréo]  *WORD
-        <<- /tu/ analyse_with_next(\1, "-", ":")
+        <<- /tu/ morph2(\1, "-", ":")
         ->> \1-\2                                                                                   && S’il s’agit d’un seul mot, il manque un trait d’union.
 
     [électro|ferro|hydro|labio|médico|nano|néo|neuro|physico|politico|sino|socio]  *WORD
-        <<- /tu/ space(\1, 1, 1) and (morph(\2, ":N") or analyse_with_next(\1, "-", ":"))
+        <<- /tu/ space(\1, 1, 1) and (morph(\2, ":N") or morph2(\1, "-", ":"))
         ->> \1-\2                                                                                   && S’il s’agit d’un seul mot, il manque un trait d’union.
 
 TEST: {{ferro électrique}}                              ->> ferro-électrique
 TEST: {{rétro ingénierie}}.                             ->> rétro-ingénierie
 
 
 __tu_préfixe_divers__
     [anti|auto|arrière|avant|demi|extra|intra|multi|post]  *WORD
-        <<- /tu/ morph(<1, ":D|<start>|>,") and analyse_with_next(\1, "-", ":")
+        <<- /tu/ morph(<1, ":D|<start>|>,") and morph2(\1, "-", ":")
         ->> \1-\2                                                                                   && Il manque probablement un trait d’union.
 
     [non|sans]  *WORD
-        <<- /tu/ morph(<1, ":D") and analyse_with_next(\1, "-", ":")
+        <<- /tu/ morph(<1, ":D") and morph2(\1, "-", ":")
         ->> \1-\2                                                                                   && Il manque probablement un trait d’union.
 
     sous  *WORD
-        <<- /tu/ not(\2 == "forme" and value(>1, "|de|d’|")) and morph(<1, ":D") and analyse_with_next(\1, "-", ":")
+        <<- /tu/ not(\2 == "forme" and value(>1, "|de|d’|")) and morph(<1, ":D") and morph2(\1, "-", ":")
         ->> \1-\2                                                                                   && Il manque probablement un trait d’union.
 
 TEST: il a pris une balle dans l’{{arrière train}}.
 TEST: Ce {{sans gêne}} mérite une bonne leçon
 TEST: une {{sous culture}} passée de mode
@@ -5136,24 +5136,24 @@
 TEST: la {{pseudo taxe}} carbone
 
 
 __tu_mots_composés_verbe_nom__
     [contre|entre]  *WORD
-        <<- /tu/ not morph(\2, ":[GYB]") and morph(<1, ":(?:D|V0e)|<start>|>,") and analyse_with_next(\1, "-", ":N")
+        <<- /tu/ not morph(\2, ":[GYB]") and morph(<1, ":(?:D|V0e)|<start>|>,") and morph2(\1, "-", ":N")
         ->> \1-\2                                                                                   && Il manque probablement un trait d’union.
 
     [m’|t’|s’] entre *WORD
-        <<- /tu/ morph(\3, ":V") and analyse_with_next(\2, "-", ":V")
+        <<- /tu/ morph(\3, ":V") and morph2(\2, "-", ":V")
         -2:3>> \2-\3                                                                                && Il manque probablement un trait d’union.
 
     nous nous entre ~on[ts]$
     vous vous entre ~e[zr]$
-        <<- /tu/ morph(\4, ":V") and analyse_with_next(\3, "-", ":V") and not morph(<1, ":R")
+        <<- /tu/ morph(\4, ":V") and morph2(\3, "-", ":V") and not morph(<1, ":R")
         -3:4>> \3-\4                                                                                && Il manque probablement un trait d’union.
 
     [attrape|garde|porte|brise|cache|casse|chauffe|coupe|cure|croque|essuie|lance|lave|lève|marque|pare|passe|perce|pèse|porte|poste|pousse|presse|protège|ramasse|serre|taille|tire|tourne|traîne|traine|vide]  *WORD
-        <<- /tu/ morph(<1, ":(?:D|V0e)|<start>|>,") and analyse_with_next(\1, "-", ":N")
+        <<- /tu/ morph(<1, ":(?:D|V0e)|<start>|>,") and morph2(\1, "-", ":N")
         ->> \1-\2                                                                                   && Il manque probablement un trait d’union.
 
 TEST: c’est le {{contre exemple}} parfait
 TEST: une {{entre voie}}
 TEST: s’{{entre regarder}}

Index: misc/grammalecte.sublime-syntax
==================================================================
--- misc/grammalecte.sublime-syntax
+++ misc/grammalecte.sublime-syntax
@@ -58,11 +58,11 @@
       scope: keyword.python
 
     - match: '\b(?:True|False|None)\b'
       scope: constant.language
 
-    - match: '\b(?:spell|morph(?:VC|)|stem|tag|value|space|textarea0?\w*|before0?\w*|after0?\w*|word|option|define(?:from|)|select|exclude|setmeta|analyse|tag(?:after|before)|apposition|is[A-Z]\w+|agreement|rewrite|checkD\w+|getD\w+|has[A-Z]\w+|sugg[A-Z]\w+|switch[A-Z]\w+|ceOrCet|formatN\w+|mbUnit)\b'
+    - match: '\b(?:spell|morph(?:VC|0|2|)|stem|tag|value|space|textarea0?\w*|before0?\w*|after0?\w*|word|option|define(?:from|)|select|exclude|setmeta|analyse|tag(?:after|before)|apposition|is[A-Z]\w+|agreement|rewrite|checkD\w+|getD\w+|has[A-Z]\w+|sugg[A-Z]\w+|switch[A-Z]\w+|ceOrCet|formatN\w+|mbUnit)\b'
       scope: entity.name.function
 
     - match: '\b(?:replace|endswith|startswith|search|upper|lower|capitalize|strip|rstrip|is(?:alpha|upper|lower|digit|title))\b'
       scope: support.function