22 #include "kateluaindentscript.h"
23 #include "katedocument.h"
26 #include <sys/types.h>
31 #include <tqfileinfo.h>
32 #include <kstandarddirs.h>
34 #include <tdeconfig.h>
35 #include <tdeglobal.h>
45 #define ONCHARSTR "kateonchar"
46 #define ONNEWLINESTR "kateonnewline"
48 #define katelua_registerFunc(n,f,t) \
49 (lua_pushstring(m_interpreter, n), \
50 lua_pushcfunction(m_interpreter, f), \
51 lua_settable(m_interpreter, t))
53 #define katelua_registerNumConst(n,v,t) \
54 (lua_pushstring(m_interpreter, n), \
55 lua_pushnumber(m_interpreter, v), \
56 lua_settable(m_interpreter, t))
59 static KateDocument *katelua_doc;
66 typedef struct KATELUA_FUNCTIONS {
71 static int katelua_katedebug(lua_State *L) {
73 for (
int i=1;i<=n;i++) {
75 else if (lua_isstring(L,i))
kdDebug()<<lua_tostring(L,i)<<
endl;
76 else if (lua_isboolean(L,i))
kdDebug()<<(bool)lua_toboolean(L,i)<<
endl;
77 else if (lua_isnumber(L,i))
kdDebug()<<lua_tonumber(L,i)<<
endl;
78 else kdDebug()<<
"Invalid type for katedebug:"<<lua_type(L,i)<<
endl;
83 static int katelua_indenter_register(lua_State *L) {
86 lua_pushstring(L,i18n(
"indenter.register requires 2 parameters (event id, function to call)").utf8().data());
89 if ( (!lua_isfunction(L,2)) || (!lua_isnumber(L,1)))
94 lua_pushstring(L,i18n(
"indenter.register requires 2 parameters (event id (number), function to call (function))").utf8().data());
97 switch ((
int)lua_tonumber(L,1))
100 lua_pushstring(L,ONCHARSTR);
101 lua_pushstring(L,ONCHARSTR);
104 lua_pushstring(L,ONNEWLINESTR);
105 lua_pushstring(L,ONNEWLINESTR);
108 lua_pushstring(L,i18n(
"indenter.register:invalid event id").utf8().data());
111 lua_gettable(L,LUA_REGISTRYINDEX);
112 if (!lua_isnil(L,lua_gettop(L))) {
113 lua_pushstring(L,i18n(
"indenter.register:there is already a function set for given").utf8().data());
118 lua_settable(L,LUA_REGISTRYINDEX);
119 kdDebug()<<
"katelua_indenter_register: Success"<<
endl;
124 static int katelua_document_textline(lua_State *L) {
125 if (lua_gettop(L)!=1) {
126 lua_pushstring(L,i18n(
"document.textLine:One parameter (line number) required").utf8().data());
129 if (!lua_isnumber(L,1)) {
130 lua_pushstring(L,i18n(
"document.textLine:One parameter (line number) required (number)").utf8().data());
133 lua_pushstring(L,katelua_doc->textLine((uint)lua_tonumber(L,1)).utf8().data());
137 static int katelua_document_removeText(lua_State *L) {
138 if (lua_gettop(L)!=4) {
139 lua_pushstring(L,i18n(
"document.removeText:Four parameters needed (start line, start col,end line, end col)").utf8().data());
142 if ((!lua_isnumber(L,1)) || (!lua_isnumber(L,2)) ||(!lua_isnumber(L,3)) || (!lua_isnumber(L,4))) {
143 lua_pushstring(L,i18n(
"document.removeText:Four parameters needed (start line, start col,end line, end col) (4x number)").utf8().data());
146 lua_pushboolean(L,katelua_doc->removeText((uint)lua_tonumber(L,1),(uint)lua_tonumber(L,2),(uint)lua_tonumber(L,3),(uint)lua_tonumber(L,4)));
150 static int katelua_document_insertText(lua_State *L) {
151 if (lua_gettop(L)!=3) {
152 lua_pushstring(L,i18n(
"document.insertText:Three parameters needed (line,col,text)").utf8().data());
155 if ((!lua_isnumber(L,1)) || (!lua_isnumber(L,2)) ||(!lua_isstring(L,3)) ) {
156 lua_pushstring(L,i18n(
"document.insertText:Three parameters needed (line,col,text) (number,number,string)").utf8().data());
159 lua_pushboolean(L,katelua_doc->insertText((uint)lua_tonumber(L,1),(uint)lua_tonumber(L,2),TQString::fromUtf8(lua_tostring(L,3))));
163 static int katelua_view_cursorline(lua_State *L) {
164 lua_pushnumber(L,katelua_view->cursorLine());
167 static int katelua_view_cursorcolumn(lua_State *L) {
168 lua_pushnumber(L,katelua_view->cursorColumn());
171 static int katelua_view_cursorposition(lua_State *L) {
172 lua_pushnumber(L,katelua_view->cursorLine());
173 lua_pushnumber(L,katelua_view->cursorColumn());
177 static int katelua_view_setcursorpositionreal(lua_State *L) {
181 static const struct KATELUA_FUNCTIONS katelua_documenttable[4]= {
182 {
"textLine",katelua_document_textline},
183 {
"removeText",katelua_document_removeText},
184 {
"insertText",katelua_document_insertText},
188 static const struct KATELUA_FUNCTIONS katelua_viewtable[5]= {
189 {
"cursorLine",katelua_view_cursorline},
190 {
"cursorColumn",katelua_view_cursorcolumn},
191 {
"cursorPosition",katelua_view_cursorposition},
192 {
"setCursorPositionReal",katelua_view_setcursorpositionreal},
196 static void kateregistertable(lua_State* m_interpreter,
const KATELUA_FUNCTIONS funcs[],
char * tablename) {
197 lua_newtable(m_interpreter);
198 int table=lua_gettop(m_interpreter);
199 for (uint i=0;funcs[i].name!=0;i++)
201 katelua_registerFunc(funcs[i].name,funcs[i].func,table);
204 lua_pushstring(m_interpreter,tablename);
205 lua_pushvalue(m_interpreter,table);
206 lua_settable(m_interpreter,LUA_GLOBALSINDEX);
207 lua_pop(m_interpreter,1);
215 KateLUAIndentScriptImpl::KateLUAIndentScriptImpl(
const TQString& internalName,
216 const TQString &filePath,
const TQString &niceName,
217 const TQString ©right,
double version):
218 KateIndentScriptImplAbstract(internalName,filePath,niceName,copyright,
version),m_interpreter(0)
223 KateLUAIndentScriptImpl::~KateLUAIndentScriptImpl()
228 void KateLUAIndentScriptImpl::decRef()
230 KateIndentScriptImplAbstract::decRef();
237 void KateLUAIndentScriptImpl::deleteInterpreter()
241 lua_close(m_interpreter);
246 bool KateLUAIndentScriptImpl::setupInterpreter(TQString &errorMsg)
248 if (m_interpreter)
return true;
249 m_interpreter=lua_open();
253 errorMsg=i18n(
"LUA interpreter could not be initialized");
256 luaopen_base(m_interpreter);
257 luaopen_string( m_interpreter );
258 luaopen_table( m_interpreter );
259 luaopen_math( m_interpreter );
260 luaopen_io( m_interpreter );
261 luaopen_debug( m_interpreter );
265 lua_newtable(m_interpreter);
266 int indentertable=lua_gettop(m_interpreter);
267 katelua_registerFunc(
"register",katelua_indenter_register,indentertable);
268 katelua_registerNumConst(
"OnChar",ONCHAR,indentertable);
269 katelua_registerNumConst(
"OnNewline",ONNEWLINE,indentertable);
270 lua_pushstring(m_interpreter,
"indenter");
271 lua_pushvalue(m_interpreter,indentertable);
272 lua_settable(m_interpreter,LUA_GLOBALSINDEX);
273 lua_pop(m_interpreter,1);
276 katelua_registerFunc(
"katedebug",katelua_katedebug,LUA_GLOBALSINDEX);
279 kateregistertable(m_interpreter,katelua_documenttable,
"document");
281 kateregistertable(m_interpreter,katelua_viewtable,
"view");
284 lua_pushstring(m_interpreter,
"dofile");
285 lua_gettable(m_interpreter,LUA_GLOBALSINDEX);
286 TQCString fn=TQFile::encodeName(filePath());
287 lua_pushstring(m_interpreter,fn.data());
288 int execresult=lua_pcall(m_interpreter,1,1,0);
290 kdDebug()<<
"Lua script has been loaded successfully. Lua interpreter version:"<<lua_version()<<
endl;
293 errorMsg=i18n(
"Lua indenting script had errors: %1").arg(lua_tostring(m_interpreter,lua_gettop(m_interpreter)));
302 bool KateLUAIndentScriptImpl::processChar(
Kate::View *view, TQChar c, TQString &errorMsg )
304 if (!setupInterpreter(errorMsg))
return false;
305 katelua_doc=((KateView*)view)->doc();
307 int oldtop=lua_gettop(m_interpreter);
308 lua_pushstring(m_interpreter,ONCHARSTR);
309 lua_gettable(m_interpreter,LUA_REGISTRYINDEX);
311 if (!lua_isnil(m_interpreter,lua_gettop(m_interpreter)))
313 lua_pushstring(m_interpreter,TQString(c).utf8().data());
314 if (lua_pcall(m_interpreter,1,0,0)!=0)
316 errorMsg=i18n(
"Lua indenting script had errors: %1").arg(lua_tostring(m_interpreter,lua_gettop(m_interpreter)));
321 lua_settop(m_interpreter,oldtop);
327 if (!setupInterpreter(errorMsg))
return false;
331 bool KateLUAIndentScriptImpl::processNewline(
class Kate::View *view,
const KateDocCursor &begin,
bool needcontinue, TQString &errorMsg )
333 if (!setupInterpreter(errorMsg))
return false;
334 katelua_doc=((KateView*)view)->doc();
336 int oldtop=lua_gettop(m_interpreter);
337 lua_pushstring(m_interpreter,ONNEWLINESTR);
338 lua_gettable(m_interpreter,LUA_REGISTRYINDEX);
340 if (!lua_isnil(m_interpreter,lua_gettop(m_interpreter)))
342 if (lua_pcall(m_interpreter,0,0,0)!=0)
344 errorMsg=i18n(
"Lua indenting script had errors: %1").arg(lua_tostring(m_interpreter,lua_gettop(m_interpreter)));
349 lua_settop(m_interpreter,oldtop);
355 KateLUAIndentScriptManager::KateLUAIndentScriptManager():KateIndentScriptManagerAbstract()
360 KateLUAIndentScriptManager::~KateLUAIndentScriptManager ()
364 void KateLUAIndentScriptManager::collectScripts (
bool force)
367 if (!m_scripts.isEmpty())
370 kdDebug()<<
"================================================="<<
endl<<
"Trying to find Lua scripts"<<
endl
371 <<
"================================================="<<
endl;
374 TDEConfig config(
"katepartluaindentscriptrc",
false,
false);
377 config.setGroup (
"General");
378 if (config.readNumEntry (
"Version") > config.readNumEntry (
"CachedVersion"))
380 config.writeEntry (
"CachedVersion", config.readNumEntry (
"Version"));
389 for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
392 TQString Group=
"Cache "+ *it;
395 config.setGroup(Group);
399 memset (&sbuf, 0,
sizeof(sbuf));
400 stat(TQFile::encodeName(*it), &sbuf);
404 if (!force && config.hasGroup(Group) && (sbuf.st_mtime == config.readNumEntry(
"lastModified")))
406 config.setGroup(Group);
407 TQString filePath=*it;
408 TQString internalName=config.readEntry(
"internlName",
"KATE-ERROR");
409 if (internalName==
"KATE-ERROR") readnew=
true;
412 TQString niceName=config.readEntry(
"niceName",internalName);
413 TQString copyright=config.readEntry(
"copyright",i18n(
"(Unknown)"));
414 double version=config.readDoubleNumEntry(
"version",0.0);
415 KateLUAIndentScriptImpl *s=
new KateLUAIndentScriptImpl(
416 internalName,filePath,niceName,copyright,version);
417 m_scripts.insert (internalName, s);
425 if (m_scripts[fi.baseName()])
428 TQString internalName=fi.baseName();
429 TQString filePath=*it;
430 TQString niceName=internalName;
431 TQString copyright=i18n(
"(Unknown)");
433 parseScriptHeader(filePath,&niceName,©right,&version);
435 config.setGroup(Group);
436 config.writeEntry(
"lastModified",sbuf.st_mtime);
437 config.writeEntry(
"internalName",internalName);
438 config.writeEntry(
"niceName",niceName);
439 config.writeEntry(
"copyright",copyright);
440 config.writeEntry(
"version",version);
441 KateLUAIndentScriptImpl *s=
new KateLUAIndentScriptImpl(
442 internalName,filePath,niceName,copyright,version);
443 m_scripts.insert (internalName, s);
451 KateIndentScript KateLUAIndentScriptManager::script(
const TQString &scriptname) {
452 KateLUAIndentScriptImpl *s=m_scripts[scriptname];
454 return KateIndentScript(s);
457 void KateLUAIndentScriptManager::parseScriptHeader(
const TQString &filePath,
458 TQString *niceName,TQString *copyright,
double *version)
461 TQFile f(TQFile::encodeName(filePath));
462 if (!f.open(IO_ReadOnly) ) {
463 kdDebug(13050)<<
"Header could not be parsed, because file could not be opened"<<
endl;
467 st.setEncoding (TQTextStream::UnicodeUTF8);
468 if (!st.readLine().upper().startsWith(
"/**KATE")) {
474 kdDebug(13050)<<
"Parsing indent script header"<<
endl;
475 enum {NOTHING=0,COPYRIGHT=1} currentState=NOTHING;
477 TQString tmpblockdata=
"";
478 TQRegExp endExpr(
"[\\s\\t]*\\*\\*\\/[\\s\\t]*$");
479 TQRegExp keyValue(
"[\\s\\t]*\\*\\s*(.+):(.*)$");
480 TQRegExp blockContent(
"[\\s\\t]*\\*(.*)$");
481 while ((line=st.readLine())!=TQString::null) {
482 if (endExpr.exactMatch(line)) {
484 if (currentState==NOTHING)
break;
485 if (currentState==COPYRIGHT) {
486 *copyright=tmpblockdata;
491 if (currentState==NOTHING)
493 if (keyValue.exactMatch(line)) {
494 TQStringList sl=keyValue.capturedTexts();
496 kdDebug(13050)<<
"key-length:"<<sl[1].length()<<
endl<<
"value-length:"<<sl[2].length()<<
endl;
498 TQString value=sl[2];
499 if (key==
"NAME") (*niceName)=value.stripWhiteSpace();
500 else if (key==
"VERSION") (*version)=value.stripWhiteSpace().toDouble(0);
501 else if (key==
"COPYRIGHT")
504 if (value.stripWhiteSpace().length()>0) tmpblockdata=value;
505 currentState=COPYRIGHT;
509 if (blockContent.exactMatch(line))
511 TQString bl=blockContent.capturedTexts()[1];
515 (*copyright)=tmpblockdata;
517 currentState=NOTHING;
518 }
else tmpblockdata=tmpblockdata+
"\n"+bl;
Cursor class with a pointer to its document.
The Kate::View text editor interface.
static TDEStandardDirs * dirs()
TQStringList findAllResources(const char *type, const TQString &filter=TQString::null, bool recursive=false, bool unique=false) const
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)
TQString name(StdAccel id)