Bug 135844 - [PATCH] Enhance highlighting IncludeRules to allow 'foo##bar'-style inclusions
Summary: [PATCH] Enhance highlighting IncludeRules to allow 'foo##bar'-style inclusions
Status: CLOSED FIXED
Alias: None
Product: kate
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR wishlist
Target Milestone: ---
Assignee: Matthew Woehlke
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-17 23:17 UTC by Matthew Woehlke
Modified: 2007-05-09 00:09 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Patch, take 2 (4.58 KB, patch)
2006-10-19 00:46 UTC, Matthew Woehlke
Details
Patch for /trunk, doesn't work for e.g. PHP HL (4.77 KB, patch)
2006-11-01 17:08 UTC, Christoph Cullmann
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Woehlke 2006-10-17 23:17:36 UTC
Version:            (using KDE KDE 3.5.5)
Installed from:    Compiled From Sources
OS:                Linux

The following (trivial!) patch adds support for including contexts other than the root from external highlighters (via 'IncludeRules context##highlighter'). Oddly enough, context resolution already handles this case if KateHighlighting::addToContextList recognizes it correctly.

===
diff -ur orig/kdelibs-3.5.5/kate/part/katehighlight.cpp kdelibs-3.5.5/kate/part/katehighlight.cpp
--- orig/kdelibs-3.5.5/kate/part/katehighlight.cpp	2006-07-22 03:16:36.000000000 -0500
+++ kdelibs-3.5.5/kate/part/katehighlight.cpp	2006-10-17 15:19:05.573601049 -0500
@@ -2745,31 +2745,34 @@
         QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
         QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
         bool includeAttrib = IS_TRUE( incAttrib );
-        // only context refernces of type NAME and ##Name are allowed
+        // only context refernces of type Name, ##Name, and Subname##Name are allowed
         if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
         {
+          int incCtxi = incCtx.find("##");
           //#stay, #pop is not interesting here
-          if (!incCtx.startsWith("#"))
-          {
-            // a local reference -> just initialize the include rule structure
-            incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
-            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
-          }
-          else
+          if (incCtxi >= 0)
           {
+            QString incSet = incCtx.mid(incCtxi + 2);
+
             //a cross highlighting reference
-            kdDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
+            kdDebug(13010)<<"Cross highlight reference <IncludeRules \"" << incCtx << "\">"<<endl;
+            kdDebug(13010)<<"Included rule set is \"" << incSet << "\""<<endl;
             KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),"",includeAttrib);

             //use the same way to determine cross hl file references as other items do
-            if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
-              embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
+            if (!embeddedHls.contains(incSet))
+              embeddedHls.insert(incSet,KateEmbeddedHlInfo());

-            unresolvedContextReferences.insert(&(ir->incCtx),
-                incCtx.right(incCtx.length()-2));
+            unresolvedContextReferences.insert(&(ir->incCtx), incSet);

             includeRules.append(ir);
           }
+          else
+          {
+            // a local reference -> just initialize the include rule structure
+            incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
+            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
+          }
         }

         continue;
===

This resolves one cause of bug #135783.
Comment 1 Matthew Woehlke 2006-10-19 00:46:30 UTC
Created attachment 18181 [details]
Patch, take 2

The first patch doesn't quite suffice, as resolving multiple external contexts
does not work correctly. This new patch resolves this issue by bypassing
resolution done in makeContextList() and forcing handleKateHlIncludeRules() to
do the work for 'Name##Name'-style contexts.
Comment 2 Dominik Haumann 2006-10-19 08:22:05 UTC
KDE 3.5.x is in feature freeze. Cullmann? ;)
Comment 3 Joseph Wenninger 2006-10-19 11:32:55 UTC
I'd say KDE4. But let the maintainer decide ;-)
Comment 4 Christoph Cullmann 2006-11-01 16:27:23 UTC
I am for KDE 4, too, don't like to introduce such stuff that late in the 3.5.x series, better have it in SVN-Trunk now for KDE4, to have it tested long enough before release...

Will try to incooperate the patch into trunk-
Comment 5 Christoph Cullmann 2006-11-01 17:08:22 UTC
Hmm, the second patch does lead to infinite loop on turning on e.g. the php hl, if I port it over to KDE4, will attach the new patch, perhaps somebody has time to look for this issue.
Comment 6 Christoph Cullmann 2006-11-01 17:08:59 UTC
Created attachment 18357 [details]
Patch for /trunk, doesn't work for e.g. PHP HL
Comment 7 Anders Lund 2006-11-01 17:15:35 UTC
For Documentation purposes:

Could you tell me what happens when I use it? I mean, if I include something 
like ##javascript#regex, it includes only the rules in that context, + rules 
in contexts jumped to (recursively)?

-anders
Comment 8 Matthew Woehlke 2006-11-01 21:12:50 UTC
The trunk patch is OK by me; I checked that it is mine with "modernization".

By "infinite loops", do you mean the issue described in bug #135783? Do you know more specifically what the problem with PHP is? I don't see a problem using my original 'patch, take 2' with KDE 3.5.5.
Comment 9 Matthew Woehlke 2006-11-01 21:18:52 UTC
Anders:

I think you understand correctly. The point of the patch is to allow inclusion of a context other than context0 from an external hl.

See http://lists.kde.org/?l=kwrite-devel&m=116121343530607&w=2 for a real-world example. I think that explains things better than I could here, short of rehashing what I already said there.
Comment 10 Christoph Cullmann 2007-03-28 07:01:54 UTC
Seems ok for 3.5 and /trunk I guess. But if you commit it to one of this two places, please port it to the other. As it won't have drawbacks for any user not using it, should have no regressions for our normal highlightings. We should only document it for /trunk...
Comment 11 Matthew Woehlke 2007-03-29 16:36:38 UTC
Ok, thanks. For /trunk, what was the issue with the port you did?
Comment 12 Christoph Cullmann 2007-03-30 18:39:29 UTC
endless loop, better port it again yourself from scratch, perhaps I have made a evil fault ;)
Comment 13 Matthew Woehlke 2007-03-30 19:13:51 UTC
Maybe, although I thought I checked your port pretty closely and didn't see anything wrong. Maybe something else (new/changed in KDE4) is interacting. Anyway, getting a KDE4 environment set up is on my to-do list now, this will go on there as the first thing to look at (followed by selection improvements if no one else has ported them already).

(Chris, since I've got your approval to go ahead and get this in, I hope you don't mind if I reassign to me.)
Comment 14 Matthew Woehlke 2007-04-17 18:26:23 UTC
SVN commit 655056 by mwoehlke:

CCBUG: 135844
Add support for 'foo##bar' style inclusion of external subcontexts to IncludeRules.


 M  +36 -23    katehighlight.cpp  


--- branches/KDE/3.5/kdelibs/kate/part/katehighlight.cpp #655055:655056
@@ -2359,11 +2359,11 @@
     }
   }
 
-  else if ( tmpLineEndContext.startsWith("##"))
+  else if ( tmpLineEndContext.contains("##"))
   {
-    QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
+    QString tmp=tmpLineEndContext.mid(tmpLineEndContext.find("##")+2);
     if (!embeddedHls.contains(tmp))  embeddedHls.insert(tmp,KateEmbeddedHlInfo());
-    unres=tmp;
+    unres=tmpLineEndContext;
     context=0;
   }
 
@@ -2453,17 +2453,25 @@
 
 
   // at this point all needed highlighing (sub)definitions are loaded. It's time
-  // to resolve cross file  references (if there are any )
+  // to resolve cross file  references (if there are any)
   kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
 
   //optimize this a littlebit
   for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
     unresIt!=unresolvedContextReferences.end();++unresIt)
   {
-    //try to find the context0 id for a given unresolvedReference
-    KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
-    if (hlIt!=embeddedHls.end())
-      *(unresIt.key())=hlIt.data().context0;
+    QString incCtx = unresIt.data();
+    kdDebug(13010)<<"Context "<<incCtx<<" is unresolved"<<endl;
+    // only resolve '##Name' contexts here; handleKateHlIncludeRules() can figure
+    // out 'Name##Name'-style inclusions, but we screw it up
+    if (incCtx.endsWith(":")) {
+      kdDebug(13010)<<"Looking up context0 for ruleset "<<incCtx<<endl;
+      incCtx = incCtx.left(incCtx.length()-1);
+      //try to find the context0 id for a given unresolvedReference
+      KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(incCtx);
+      if (hlIt!=embeddedHls.end())
+        *(unresIt.key())=hlIt.data().context0;
+    }
   }
 
   // eventually handle KateHlIncludeRules items, if they exist.
@@ -2527,7 +2535,7 @@
         // It would be good to look here somehow, if the result is valid
       }
     }
-    else ++it; //nothing to do, already resolved (by the cross defintion reference resolver
+    else ++it; //nothing to do, already resolved (by the cross defintion reference resolver)
   }
 
   // now that all KateHlIncludeRule items should be valid and completely resolved,
@@ -2745,31 +2753,36 @@
         QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
         QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
         bool includeAttrib = IS_TRUE( incAttrib );
-        // only context refernces of type NAME and ##Name are allowed
+        // only context refernces of type Name, ##Name, and Subname##Name are allowed
         if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
         {
+          int incCtxi = incCtx.find("##");
           //#stay, #pop is not interesting here
-          if (!incCtx.startsWith("#"))
+          if (incCtxi >= 0)
           {
-            // a local reference -> just initialize the include rule structure
-            incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
-            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
-          }
-          else
-          {
+            QString incSet = incCtx.mid(incCtxi + 2);
+            QString incCtxN = incSet + ":" + incCtx.left(incCtxi);
+
             //a cross highlighting reference
-            kdDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
-            KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),"",includeAttrib);
+            kdDebug(13010)<<"Cross highlight reference <IncludeRules>, context "<<incCtxN<<endl;
+            KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtxN,includeAttrib);
 
             //use the same way to determine cross hl file references as other items do
-            if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
-              embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
+            if (!embeddedHls.contains(incSet))
+              embeddedHls.insert(incSet,KateEmbeddedHlInfo());
+            else
+              kdDebug(13010)<<"Skipping embeddedHls.insert for "<<incCtxN<<endl;
 
-            unresolvedContextReferences.insert(&(ir->incCtx),
-                incCtx.right(incCtx.length()-2));
+            unresolvedContextReferences.insert(&(ir->incCtx), incCtxN);
 
             includeRules.append(ir);
           }
+          else
+          {
+            // a local reference -> just initialize the include rule structure
+            incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
+            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
+          }
         }
 
         continue;
Comment 15 Matthew Woehlke 2007-04-17 19:49:11 UTC
SVN commit 655086 by mwoehlke:

BUG: 135844
Add support for 'foo##bar' style inclusion of external subcontexts to IncludeRules.


 M  +42 -25    katehighlight.cpp  


--- trunk/KDE/kdelibs/kate/part/katehighlight.cpp #655085:655086
@@ -2408,6 +2408,7 @@
     QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
     if (!embeddedHls.contains(tmp))  embeddedHls.insert(tmp,KateEmbeddedHlInfo());
     unres=tmp;
+    kdDebug(13010) << "unres = " << unres << endl;
     context=0;
   }
 
@@ -2498,17 +2499,27 @@
 
 
   // at this point all needed highlighing (sub)definitions are loaded. It's time
-  // to resolve cross file  references (if there are any )
+  // to resolve cross file  references (if there are any)
   kDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
 
   //optimize this a littlebit
   for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
-    unresIt!=unresolvedContextReferences.end();++unresIt)
+       unresIt != unresolvedContextReferences.end();
+       ++unresIt)
   {
-    //try to find the context0 id for a given unresolvedReference
-    KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.value());
-    if (hlIt!=embeddedHls.end())
-      *(unresIt.key())=hlIt.value().context0;
+    QString incCtx = unresIt.value();
+    kDebug(13010) << "Context " <<incCtx << " is unresolved" << endl;
+
+    // only resolve '##Name' contexts here; handleKateHlIncludeRules() can figure
+    // out 'Name##Name'-style inclusions, but we screw it up
+    if (incCtx.endsWith(":")) {
+      kDebug(13010)<<"Looking up context0 for ruleset "<<incCtx<<endl;
+      incCtx = incCtx.left(incCtx.length()-1);
+      //try to find the context0 id for a given unresolvedReference
+      KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(incCtx);
+      if (hlIt!=embeddedHls.end())
+        *(unresIt.key())=hlIt.value().context0;
+    }
   }
 
   // eventually handle KateHlIncludeRules items, if they exist.
@@ -2572,7 +2583,7 @@
         // It would be good to look here somehow, if the result is valid
       }
     }
-    else ++it; //nothing to do, already resolved (by the cross defintion reference resolver
+    else ++it; //nothing to do, already resolved (by the cross defintion reference resolver)
   }
 
   // now that all KateHlIncludeRule items should be valid and completely resolved,
@@ -2792,31 +2803,37 @@
         QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
         QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
         bool includeAttrib = IS_TRUE( incAttrib );
-        // only context refernces of type NAME and ##Name are allowed
+
+        // only context refernces of type Name, ##Name, and Subname##Name are allowed
         if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
         {
-          //#stay, #pop is not interesting here
-          if (!incCtx.startsWith("#"))
-          {
-            // a local reference -> just initialize the include rule structure
-            incCtx=buildPrefix+incCtx.simplified();
-            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
-          }
-          else
-          {
-            //a cross highlighting reference
-            kDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
-            KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),"",includeAttrib);
+           int incCtxi = incCtx.indexOf ("##");
+           //#stay, #pop is not interesting here
+           if (incCtxi >= 0)
+           {
+             QString incSet = incCtx.mid(incCtxi + 2);
+             QString incCtxN = incSet + ":" + incCtx.left(incCtxi);
 
-            //use the same way to determine cross hl file references as other items do
-            if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
-              embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
+             //a cross highlighting reference
+             kDebug(13010)<<"Cross highlight reference <IncludeRules>, context "<<incCtxN<<endl;
+             KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtxN,includeAttrib);
 
-            unresolvedContextReferences.insert(&(ir->incCtx),
-                incCtx.right(incCtx.length()-2));
+             //use the same way to determine cross hl file references as other items do
+             if (!embeddedHls.contains(incSet))
+               embeddedHls.insert(incSet,KateEmbeddedHlInfo());
+             else
+               kDebug(13010)<<"Skipping embeddedHls.insert for "<<incCtxN<<endl;
 
+            unresolvedContextReferences.insert(&(ir->incCtx), incCtxN);
+
             includeRules.append(ir);
           }
+          else
+          {
+            // a local reference -> just initialize the include rule structure
+            incCtx=buildPrefix+incCtx.simplified ();
+            includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
+          }
         }
 
         continue;
Comment 16 Matthew Woehlke 2007-05-04 23:00:12 UTC
SVN commit 661206 by mwoehlke:

CCBUG: 135844
CCBUG: 144599
Try to recognize 'foo##bar' contexts in regular context redirects, i.e. in places that are not IncludeRules. This mostly but not entirely works, see bug 145052 and the FIXME added.


 M  +5 -2      katehighlight.cpp  


--- branches/KDE/3.5/kdelibs/kate/part/katehighlight.cpp #661205:661206
@@ -2367,9 +2367,12 @@
 
   else if ( tmpLineEndContext.contains("##"))
   {
-    QString tmp=tmpLineEndContext.mid(tmpLineEndContext.find("##")+2);
+    int o = tmpLineEndContext.find("##");
+    // FIXME at least with 'foo##bar'-style contexts the rules are picked up
+    // but the default attribute is not
+    QString tmp=tmpLineEndContext.mid(o+2);
     if (!embeddedHls.contains(tmp))  embeddedHls.insert(tmp,KateEmbeddedHlInfo());
-    unres=tmpLineEndContext;
+    unres=tmp+':'+tmpLineEndContext.left(o);
     context=0;
   }
 
Comment 17 Matthew Woehlke 2007-05-09 00:09:29 UTC
(forgot to CCBUG this...)
SVN commit 662625 by mwoehlke:

Try to recognize 'foo##bar' contexts in regular context redirects, i.e. in places that are not IncludeRules. This mostly but not entirely works, see bug 145052 and the FIXME added.


 M  +6 -3      katehighlight.cpp  


--- trunk/KDE/kdelibs/kate/part/syntax/katehighlight.cpp #662624:662625 @@ -2403,11 +2403,14 @@
    * handle the remaining string, this might be a ##contextname
    * or a normal contextname....
    */
-  if ( tmpLineEndContext.startsWith("##"))
+  if ( tmpLineEndContext.contains("##"))
   {
-    QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
+    int o = tmpLineEndContext.indexOf("##");
+    // FIXME at least with 'foo##bar'-style contexts the rules are picked up
+    // but the default attribute is not
+    QString tmp=tmpLineEndContext.mid(o+2);
     if (!embeddedHls.contains(tmp))  embeddedHls.insert(tmp,KateEmbeddedHlInfo());
-    unres=tmp;
+    unres=tmp+':'+tmpLineEndContext.left(o);
     kDebug(13010) << "unres = " << unres << endl;
     context=0;
   }