[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ktexteditor-devel
Subject:    Re: [PATCH] Teach katepart to understand emacs' "-*- coding: ... -*-"
From:       "Vladimir V. Perepelitsa" <inthrax () gmail ! com>
Date:       2008-08-30 13:02:51
Message-ID: 200808301702.51938.inthrax () gmail ! com
[Download RAW message or body]

On Friday 29 August 2008 10:57:51 Joseph Wenninger wrote:
> Are there limitations, where emacs looks for that line? Python uses the
> same way to define the  enoding of source files, but accepts it only in the
> first or the second source line, otherwise it is ignored. If emacs has the
> same limitations, that should be taken into account

As I understood from emacs sources
(lisp/international/mule.el: find-auto-coding):

At first it looks for string "coding:" in 1k head and 3k tail of file

Then if head doesn't contain \s*coding:\s*([^ ;]+) it looks for 
local variables section in tail, that looks like:
Local Variables:
  coding: cp1251
End:

Implementation of Local variables for me is hard (because of multiline), and 
differs from implementation of native kate vars.

Exploring of vim sources give, that vim vars may begin from vi:, vim:, of ex:, 
and have 2 different syntaxes ("set opt opt ...:" vs "opt:opt:...").
Additionally, "fileencoding" doesn't have required effect, but "encoding" has.

Finally, Iv'e made 2 additional methods:
readVariableLineVim and readVariableLineEmacs
readVariableLineEmacs called only on first 2 lines of source.

So, resulting patch is attached.

-- 
Vladimir Perepelitsa aka Mons Anderson
<inthrax@gmail.com> / #99779956

["kdelibs-3.5.9-katepart-emacs-vim-coding.patch" (text/x-diff)]

diff -U5 -r kdelibs-3.5.9/kate/part/katedocument.cpp kdelibs-3.5.9.mod/kate/part/katedocument.cpp
--- kdelibs-3.5.9/kate/part/katedocument.cpp	2007-10-08 13:51:56.000000000 +0400
+++ kdelibs-3.5.9.mod/kate/part/katedocument.cpp	2008-08-30 16:57:57.000000000 +0400
@@ -4592,10 +4592,29 @@
 QRegExp KateDocument::kvLine = QRegExp("kate:(.*)");
 QRegExp KateDocument::kvLineWildcard = QRegExp("kate-wildcard\\((.*)\\):(.*)");
 QRegExp KateDocument::kvLineMime = QRegExp("kate-mimetype\\((.*)\\):(.*)");
 QRegExp KateDocument::kvVar = QRegExp("([\\w\\-]+)\\s+([^;]+)");
 
+QRegExp KateDocument::kvLineEmacs = QRegExp("-\\*-\\s*(.+)\\s*-\\*-");
+QRegExp KateDocument::kvVarEmacs = QRegExp("\\s*([\\w\\-]+):\\s*([^ ;]+)\\s*");
+
+/*
+  Syntax for vim may be the following:
+    string begins from vim:, vi: or ex:
+    Next it may be "set opt opt opt:" with required terminating ':' and ret is ignored,
+    or "opt:opt:opt"
+  So we have 2 different patterns with different separators between vars:
+  whitespace in first case and colon in second
+  
+  In first case leading semicolon are not captured by kvLineVim
+  In second - captured for simpler pattern in kvVarVim
+*/
+QRegExp KateDocument::kvLineVimSet = QRegExp("\\s*(?:ex|vim?):set?\\s*((?:\\\\:|[^:])*):");
+QRegExp KateDocument::kvLineVimCol = QRegExp("\\s*(?:ex|vim?)(:\\s*.*)\\s*");
+QRegExp KateDocument::kvVarVimSet = QRegExp("([^=]+)=([^ ]+)\\s*");
+QRegExp KateDocument::kvVarVimCol = QRegExp(":\\s*([^=]+)=([^:]+)");
+
 void KateDocument::readVariables(bool onlyViewAndRenderer)
 {
   if (!onlyViewAndRenderer)
     m_config->configStart();
 
@@ -4607,16 +4626,28 @@
     v->renderer()->config()->configStart();
   }
   // read a number of lines in the top/bottom of the document
   for (uint i=0; i < kMin( 9U, numLines() ); ++i )
   {
+    // if first two lines, try to read emacs vars
+    if ( i<2 )
+      readVariableLineEmacs( textLine( i ), onlyViewAndRenderer );
+
+    // next, try to read vim's vars
+    readVariableLineVim( textLine( i ), onlyViewAndRenderer );
+
+    // self kate vars have highest priority, so read them after all
     readVariableLine( textLine( i ), onlyViewAndRenderer );
   }
   if ( numLines() > 10 )
   {
     for ( uint i = kMax(10U, numLines() - 10); i < numLines(); ++i )
     {
+      // next, try to read vim's vars
+      readVariableLineVim( textLine( i ), onlyViewAndRenderer );
+
+      // self kate vars have highest priority, so read them after all
       readVariableLine( textLine( i ), onlyViewAndRenderer );
     }
   }
 
   if (!onlyViewAndRenderer)
@@ -4627,10 +4658,85 @@
     v->config()->configEnd();
     v->renderer()->config()->configEnd();
   }
 }
 
+void KateDocument::readVariableLineEmacs( QString t, bool onlyViewAndRenderer )
+{
+  // simple check first, no regex
+  if (t.find("-*-") < 0)
+    return;
+
+  QString s;
+
+  if ( kvLineEmacs.search( t ) > -1 )
+  {
+    s = kvLineEmacs.cap(1);
+
+    kdDebug (13020) << "normal variable line emacs: matched: " << s << endl;
+  }
+  else
+  {
+    return;
+  }
+
+  int p( 0 );
+
+  QString  var, val;
+  while ( (p = kvVarEmacs.search( s, p )) > -1 )
+  {
+    p += kvVarEmacs.matchedLength();
+    var = kvVarEmacs.cap( 1 );
+    val = kvVarEmacs.cap( 2 ).stripWhiteSpace();
+
+    if ( var == "coding" )
+        m_config->setEncoding( val );
+  }
+}
+
+void KateDocument::readVariableLineVim( QString t, bool onlyViewAndRenderer )
+{
+  // simple check first, no regex
+  if (t.find("vim:") < 0 && t.find("vi:") < 0 && t.find("ex:") < 0)
+    return;
+
+  QString s;
+  QRegExp kvVarVim;
+
+  if ( kvLineVimSet.search( t ) > -1 )
+  {
+    s = kvLineVimSet.cap(1);
+    kvVarVim = kvVarVimSet;
+
+    kdDebug (13020) << "normal variable line vim set: matched: " << s << endl;
+  }
+  else if ( kvLineVimCol.search( t ) > -1 )
+  {
+    s = kvLineVimCol.cap(1);
+    kvVarVim = kvVarVimCol;
+
+    kdDebug (13020) << "normal variable line vim col: matched: " << s << endl;
+  }
+  else
+  {
+    return;
+  }
+
+  int p( 0 );
+
+  QString  var, val;
+  while ( (p = kvVarVim.search( s, p )) > -1 )
+  {
+    p += kvVarVim.matchedLength();
+    var = kvVarVim.cap( 1 );
+    val = kvVarVim.cap( 2 ).stripWhiteSpace();
+
+    if ( var == "encoding" )
+        m_config->setEncoding( val );
+  }
+}
+
 void KateDocument::readVariableLine( QString t, bool onlyViewAndRenderer )
 {
   // simple check first, no regex
   // no kate inside, no vars, simple...
   if (t.find("kate") < 0)
diff -U5 -r kdelibs-3.5.9/kate/part/katedocument.h kdelibs-3.5.9.mod/kate/part/katedocument.h
--- kdelibs-3.5.9/kate/part/katedocument.h	2007-10-08 13:51:55.000000000 +0400
+++ kdelibs-3.5.9.mod/kate/part/katedocument.h	2008-08-29 18:32:44.000000000 +0400
@@ -973,10 +973,18 @@
       Reads and applies the variables in a single line
       TODO registered variables gets saved in a [map]
     */
     void readVariableLine( QString t, bool onlyViewAndRenderer = false );
     /**
+      Sets a view variable in all the views (emacs syntax).
+    */
+    void readVariableLineEmacs( QString t, bool onlyViewAndRenderer = false );
+    /**
+      Sets a view variable in all the views (vim syntax).
+    */
+    void readVariableLineVim( QString t, bool onlyViewAndRenderer = false );
+    /**
       Sets a view variable in all the views.
     */
     void setViewVariable( QString var, QString val );
     /**
       @return weather a string value could be converted
@@ -1002,10 +1010,18 @@
     static QRegExp kvLine;
     static QRegExp kvLineWildcard;
     static QRegExp kvLineMime;
     static QRegExp kvVar;
 
+    static QRegExp kvLineEmacs;
+    static QRegExp kvVarEmacs;
+
+    static QRegExp kvLineVimSet;
+    static QRegExp kvLineVimCol;
+    static QRegExp kvVarVimSet;
+    static QRegExp kvVarVimCol;
+
     KIO::TransferJob *m_job;
     KTempFile *m_tempFile;
 
   // TemplateInterface
   public:


_______________________________________________
KTextEditor-Devel mailing list
KTextEditor-Devel@kde.org
https://mail.kde.org/mailman/listinfo/ktexteditor-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic