• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • part
katejscript.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
3  Copyright (C) 2005 Joseph Wenninger <jowenn@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "katejscript.h"
21 
22 #include "katedocument.h"
23 #include "kateview.h"
24 #include "katefactory.h"
25 #include "kateconfig.h"
26 #include "kateautoindent.h"
27 #include "katehighlight.h"
28 #include "katetextline.h"
29 
30 #include "kateindentscriptabstracts.h"
31 
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 
36 #include <kdebug.h>
37 #include <kstandarddirs.h>
38 #include <tdelocale.h>
39 #include <tdemessagebox.h>
40 #include <tdeconfig.h>
41 
42 #include <kjs/function_object.h>
43 #include <kjs/interpreter.h>
44 #include <kjs/lookup.h>
45 
46 #include <tqfile.h>
47 #include <tqfileinfo.h>
48 #include <tqpopupmenu.h>
49 #include <tqregexp.h>
50 #include <tqtextstream.h>
51 
52 
53 namespace KJS {
54 
55 // taken from tdehtml
56 // therefor thx to:
57 // Copyright (C) 1999-2003 Harri Porten (porten@kde.org)
58 // Copyright (C) 2001-2003 David Faure (faure@kde.org)
59 // Copyright (C) 2003 Apple Computer, Inc.
60 
61 UString::UString(const TQString &d)
62 {
63  unsigned int len = d.length();
64  UChar *dat = new UChar[len];
65  memcpy(dat, d.unicode(), len * sizeof(UChar));
66  rep = UString::Rep::create(dat, len);
67 }
68 
69 TQString UString::qstring() const
70 {
71  return TQString((TQChar*) data(), size());
72 }
73 
74 TQConstString UString::qconststring() const
75 {
76  return TQConstString((TQChar*) data(), size());
77 }
78 
79 //BEGIN global methods
80 class KateJSGlobalFunctions : public ObjectImp
81 {
82  public:
83  KateJSGlobalFunctions(int i, int length);
84  virtual bool implementsCall() const { return true; }
85  virtual Value call(ExecState *exec, Object &thisObj, const List &args);
86 
87  enum {
88  Debug
89  };
90 
91  private:
92  int id;
93 };
94 KateJSGlobalFunctions::KateJSGlobalFunctions(int i, int length) : ObjectImp(), id(i)
95 {
96  putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
97 }
98 Value KateJSGlobalFunctions::call(ExecState *exec, Object &/*thisObj*/, const List &args)
99 {
100  switch (id) {
101  case Debug:
102  tqDebug("Kate (KJS Scripting): %s", args[0].toString(exec).ascii());
103  return Undefined();
104  default:
105  break;
106  }
107 
108  return Undefined();
109 }
110 //END global methods
111 
112 } // namespace KJS
113 
114 //BEGIN JS API STUFF
115 
116 class KateJSGlobal : public KJS::ObjectImp {
117 public:
118  virtual KJS::UString className() const { return "global"; }
119 };
120 
121 class KateJSDocument : public KJS::ObjectImp
122 {
123  public:
124  KateJSDocument (KJS::ExecState *exec, KateDocument *_doc);
125 
126  KJS::Value get( KJS::ExecState *exec, const KJS::Identifier &propertyName) const;
127 
128  KJS::Value getValueProperty(KJS::ExecState *exec, int token) const;
129 
130  void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value& value, int attr = KJS::None);
131 
132  void putValueProperty(KJS::ExecState *exec, int token, const KJS::Value& value, int attr);
133 
134  const KJS::ClassInfo* classInfo() const { return &info; }
135 
136  enum { FullText,
137  Text,
138  TextLine,
139  Lines,
140  Length,
141  LineLength,
142  SetText,
143  Clear,
144  InsertText,
145  RemoveText,
146  InsertLine,
147  RemoveLine,
148  EditBegin,
149  EditEnd,
150  IndentWidth,
151  IndentMode,
152  SpaceIndent,
153  MixedIndent,
154  HighlightMode,
155  IsInWord,
156  CanBreakAt,
157  CanComment,
158  CommentMarker,
159  CommentStart,
160  CommentEnd,
161  Attribute
162  };
163 
164  public:
165  KateDocument *doc;
166 
167  static const KJS::ClassInfo info;
168 };
169 
170 class KateJSView : public KJS::ObjectImp
171 {
172  public:
173  KateJSView (KJS::ExecState *exec, KateView *_view);
174 
175  KJS::Value get( KJS::ExecState *exec, const KJS::Identifier &propertyName) const;
176 
177  KJS::Value getValueProperty(KJS::ExecState *exec, int token) const;
178 
179  void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value& value, int attr = KJS::None);
180 
181  void putValueProperty(KJS::ExecState *exec, int token, const KJS::Value& value, int attr);
182 
183  const KJS::ClassInfo* classInfo() const { return &info; }
184 
185  enum { CursorLine,
186  CursorColumn,
187  CursorColumnReal,
188  SetCursorPosition,
189  SetCursorPositionReal,
190  Selection,
191  HasSelection,
192  SetSelection,
193  RemoveSelectedText,
194  SelectAll,
195  ClearSelection,
196  SelStartLine,
197  SelStartCol,
198  SelEndLine,
199  SelEndCol
200  };
201 
202  public:
203  KateView *view;
204 
205  static const KJS::ClassInfo info;
206 };
207 
208 class KateJSIndenter : public KJS::ObjectImp
209 {
210  public:
211  KateJSIndenter (KJS::ExecState *exec);
212  /*
213  KJS::Value get( KJS::ExecState *exec, const KJS::Identifier &propertyName) const;
214 
215  KJS::Value getValueProperty(KJS::ExecState *exec, int token) const;
216 
217  void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value& value, int attr = KJS::None);
218 
219  void putValueProperty(KJS::ExecState *exec, int token, const KJS::Value& value, int attr);
220  */
221  const KJS::ClassInfo* classInfo() const { return &info; }
222 
223  enum { OnChar,
224  OnLine,
225  OnNewline,
226  Dummy
227  };
228 
229  public:
230 
231  static const KJS::ClassInfo info;
232 };
233 
234 #include "katejscript.lut.h"
235 
236 //END
237 
238 KateJScript::KateJScript ()
239  : m_global (new KJS::Object (new KateJSGlobal ()))
240  , m_interpreter (new KJS::Interpreter (*m_global))
241  , m_document (new KJS::Object(wrapDocument(m_interpreter->globalExec(), 0)))
242  , m_view (new KJS::Object (wrapView(m_interpreter->globalExec(), 0)))
243 {
244  // put some stuff into env., this should stay for all executions, as we keep external
245  // references to the inserted KJS::Objects, this should avoid any garbage collection
246  m_interpreter->globalObject().put(m_interpreter->globalExec(), "document", *m_document);
247  m_interpreter->globalObject().put(m_interpreter->globalExec(), "view", *m_view);
248  m_interpreter->globalObject().put(m_interpreter->globalExec(), "debug",
249  KJS::Object(new KateJSGlobalFunctions(KateJSGlobalFunctions::Debug,1)));
250 }
251 
252 KateJScript::~KateJScript ()
253 {
254  delete m_view;
255  delete m_document;
256  delete m_interpreter;
257  delete m_global;
258 }
259 
260 KJS::ObjectImp *KateJScript::wrapDocument (KJS::ExecState *exec, KateDocument *doc)
261 {
262  return new KateJSDocument(exec, doc);
263 }
264 
265 KJS::ObjectImp *KateJScript::wrapView (KJS::ExecState *exec, KateView *view)
266 {
267  return new KateJSView(exec, view);
268 }
269 
270 bool KateJScript::execute (KateView *view, const TQString &script, TQString &errorMsg)
271 {
272  // no view, no fun
273  if (!view)
274  {
275  errorMsg = i18n("Could not access view");
276  return false;
277  }
278 
279  // init doc & view with new pointers!
280  static_cast<KateJSDocument *>( m_document->imp() )->doc = view->doc();
281  static_cast<KateJSView *>( m_view->imp() )->view = view;
282 
283  // run the script for real
284  KJS::Completion comp (m_interpreter->evaluate(script));
285 
286  if (comp.complType() == KJS::Throw)
287  {
288  KJS::ExecState *exec = m_interpreter->globalExec();
289 
290  KJS::Value exVal = comp.value();
291 
292  char *msg = exVal.toString(exec).ascii();
293 
294  int lineno = -1;
295 
296  if (exVal.type() == KJS::ObjectType)
297  {
298  KJS::Value lineVal = KJS::Object::dynamicCast(exVal).get(exec,"line");
299 
300  if (lineVal.type() == KJS::NumberType)
301  lineno = int(lineVal.toNumber(exec));
302  }
303 
304  errorMsg = i18n("Exception, line %1: %2").arg(lineno).arg(msg);
305  return false;
306  }
307 
308  return true;
309 }
310 
311 //BEGIN KateJSDocument
312 
313 // -------------------------------------------------------------------------
314 /* Source for KateJSDocumentProtoTable.
315 @begin KateJSDocumentProtoTable 21
316 #
317 # edit interface stuff + editBegin/End, this is nice start
318 #
319  textFull KateJSDocument::FullText DontDelete|Function 0
320  textRange KateJSDocument::Text DontDelete|Function 4
321  textLine KateJSDocument::TextLine DontDelete|Function 1
322  lines KateJSDocument::Lines DontDelete|Function 0
323  length KateJSDocument::Length DontDelete|Function 0
324  lineLength KateJSDocument::LineLength DontDelete|Function 1
325  setText KateJSDocument::SetText DontDelete|Function 1
326  clear KateJSDocument::Clear DontDelete|Function 0
327  insertText KateJSDocument::InsertText DontDelete|Function 3
328  removeText KateJSDocument::RemoveText DontDelete|Function 4
329  insertLine KateJSDocument::InsertLine DontDelete|Function 2
330  removeLine KateJSDocument::RemoveLine DontDelete|Function 1
331  editBegin KateJSDocument::EditBegin DontDelete|Function 0
332  editEnd KateJSDocument::EditEnd DontDelete|Function 0
333 #
334 # methods from highlight (and around)
335 #
336  isInWord KateJSDocument::IsInWord DontDelete|Function 2
337  canBreakAt KateJSDocument::CanBreakAt DontDelete|Function 2
338  canComment KateJSDocument::CanComment DontDelete|Function 2
339  commentMarker KateJSDocument::CommentMarker DontDelete|Function 1
340  commentStart KateJSDocument::CommentStart DontDelete|Function 1
341  commentEnd KateJSDocument::CommentEnd DontDelete|Function 1
342  attribute KateJSDocument::Attribute DontDelete|Function 2
343 @end
344 
345 @begin KateJSDocumentTable 6
346 #
347 # Configuration properties
348 #
349  indentWidth KateJSDocument::IndentWidth DontDelete|ReadOnly
350  indentMode KateJSDocument::IndentMode DontDelete|ReadOnly
351  spaceIndent KateJSDocument::SpaceIndent DontDelete|ReadOnly
352  mixedIndent KateJSDocument::MixedIndent DontDelete|ReadOnly
353  highlightMode KateJSDocument::HighlightMode DontDelete|ReadOnly
354 @end
355 */
356 
357 DEFINE_PROTOTYPE("KateJSDocument",KateJSDocumentProto)
358 IMPLEMENT_PROTOFUNC(KateJSDocumentProtoFunc)
359 IMPLEMENT_PROTOTYPE(KateJSDocumentProto,KateJSDocumentProtoFunc)
360 
361 const KJS::ClassInfo KateJSDocument::info = { "KateJSDocument", 0, 0, 0 };
362 
363 KJS::Value KJS::KateJSDocumentProtoFunc::call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args)
364 {
365  KJS_CHECK_THIS( KateJSDocument, thisObj );
366 
367  KateDocument *doc = static_cast<KateJSDocument *>( thisObj.imp() )->doc;
368 
369  if (!doc)
370  return KJS::Undefined();
371 
372  switch (id)
373  {
374  case KateJSDocument::FullText:
375  return KJS::String (doc->text());
376 
377  case KateJSDocument::Text:
378  return KJS::String (doc->text(args[0].toUInt32(exec), args[1].toUInt32(exec), args[2].toUInt32(exec), args[3].toUInt32(exec)));
379 
380  case KateJSDocument::TextLine:
381  return KJS::String (doc->textLine (args[0].toUInt32(exec)));
382 
383  case KateJSDocument::Lines:
384  return KJS::Number (doc->numLines());
385 
386  case KateJSDocument::Length:
387  return KJS::Number (doc->length());
388 
389  case KateJSDocument::LineLength:
390  return KJS::Number (doc->lineLength(args[0].toUInt32(exec)));
391 
392  case KateJSDocument::SetText:
393  return KJS::Boolean (doc->setText(args[0].toString(exec).qstring()));
394 
395  case KateJSDocument::Clear:
396  return KJS::Boolean (doc->clear());
397 
398  case KateJSDocument::InsertText:
399  return KJS::Boolean (doc->insertText (args[0].toUInt32(exec), args[1].toUInt32(exec), args[2].toString(exec).qstring()));
400 
401  case KateJSDocument::RemoveText:
402  return KJS::Boolean (doc->removeText(args[0].toUInt32(exec), args[1].toUInt32(exec), args[2].toUInt32(exec), args[3].toUInt32(exec)));
403 
404  case KateJSDocument::InsertLine:
405  return KJS::Boolean (doc->insertLine (args[0].toUInt32(exec), args[1].toString(exec).qstring()));
406 
407  case KateJSDocument::RemoveLine:
408  return KJS::Boolean (doc->removeLine (args[0].toUInt32(exec)));
409 
410  case KateJSDocument::EditBegin:
411  doc->editBegin();
412  return KJS::Null ();
413 
414  case KateJSDocument::EditEnd:
415  doc->editEnd ();
416  return KJS::Null ();
417 
418  case KateJSDocument::IsInWord:
419  return KJS::Boolean( doc->highlight()->isInWord( args[0].toString(exec).qstring().at(0), args[1].toUInt32(exec) ) );
420 
421  case KateJSDocument::CanBreakAt:
422  return KJS::Boolean( doc->highlight()->canBreakAt( args[0].toString(exec).qstring().at(0), args[1].toUInt32(exec) ) );
423 
424  case KateJSDocument::CanComment:
425  return KJS::Boolean( doc->highlight()->canComment( args[0].toUInt32(exec), args[1].toUInt32(exec) ) );
426 
427  case KateJSDocument::CommentMarker:
428  return KJS::String( doc->highlight()->getCommentSingleLineStart( args[0].toUInt32(exec) ) );
429 
430  case KateJSDocument::CommentStart:
431  return KJS::String( doc->highlight()->getCommentStart( args[0].toUInt32(exec) ) );
432 
433  case KateJSDocument::CommentEnd:
434  return KJS::String( doc->highlight()->getCommentEnd( args[0].toUInt32(exec) ) );
435 
436  case KateJSDocument::Attribute:
437  return KJS::Number( doc->kateTextLine(args[0].toUInt32(exec))->attribute(args[1].toUInt32(exec)) );
438  }
439 
440  return KJS::Undefined();
441 }
442 
443 KJS::Value KateJSDocument::get( KJS::ExecState *exec, const KJS::Identifier &propertyName) const
444 {
445  return KJS::lookupGetValue<KateJSDocument,KJS::ObjectImp>(exec, propertyName, &KateJSDocumentTable, this );
446 }
447 
448 KJS::Value KateJSDocument::getValueProperty(KJS::ExecState *exec, int token) const
449 {
450  if (!doc)
451  return KJS::Undefined ();
452 
453  switch (token) {
454  case KateJSDocument::IndentWidth:
455  return KJS::Number( doc->config()->indentationWidth() );
456 
457  case KateJSDocument::IndentMode:
458  return KJS::String( KateAutoIndent::modeName( doc->config()->indentationMode() ) );
459 
460  case KateJSDocument::SpaceIndent:
461  return KJS::Boolean( doc->config()->configFlags() & KateDocumentConfig::cfSpaceIndent );
462 
463  case KateJSDocument::MixedIndent:
464  return KJS::Boolean( doc->config()->configFlags() & KateDocumentConfig::cfMixedIndent );
465 
466  case KateJSDocument::HighlightMode:
467  return KJS::String( doc->hlModeName( doc->hlMode() ) );
468  }
469 
470  return KJS::Undefined ();
471 }
472 
473 void KateJSDocument::put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value& value, int attr)
474 {
475  KJS::lookupPut<KateJSDocument,KJS::ObjectImp>(exec, propertyName, value, attr, &KateJSDocumentTable, this );
476 }
477 
478 void KateJSDocument::putValueProperty(KJS::ExecState *exec, int token, const KJS::Value& value, int attr)
479 {
480  if (!doc)
481  return;
482 }
483 
484 KateJSDocument::KateJSDocument (KJS::ExecState *exec, KateDocument *_doc)
485  : KJS::ObjectImp (KateJSDocumentProto::self(exec))
486  , doc (_doc)
487 {
488 }
489 
490 //END
491 
492 //BEGIN KateJSView
493 
494 // -------------------------------------------------------------------------
495 /* Source for KateJSViewProtoTable.
496 @begin KateJSViewProtoTable 14
497  cursorLine KateJSView::CursorLine DontDelete|Function 0
498  cursorColumn KateJSView::CursorColumn DontDelete|Function 0
499  cursorColumnReal KateJSView::CursorColumnReal DontDelete|Function 0
500  setCursorPosition KateJSView::SetCursorPosition DontDelete|Function 2
501  setCursorPositionReal KateJSView::SetCursorPositionReal DontDelete|Function 2
502  selection KateJSView::Selection DontDelete|Function 0
503  hasSelection KateJSView::HasSelection DontDelete|Function 0
504  setSelection KateJSView::SetSelection DontDelete|Function 4
505  removeSelectedText KateJSView::RemoveSelectedText DontDelete|Function 0
506  selectAll KateJSView::SelectAll DontDelete|Function 0
507  clearSelection KateJSView::ClearSelection DontDelete|Function 0
508 @end
509 */
510 
511 /* Source for KateJSViewTable.
512 @begin KateJSViewTable 5
513  selectionStartLine KateJSView::SelStartLine DontDelete|ReadOnly
514  selectionStartColumn KateJSView::SelStartCol DontDelete|ReadOnly
515  selectionEndLine KateJSView::SelEndLine DontDelete|ReadOnly
516  selectionEndColumn KateJSView::SelEndCol DontDelete|ReadOnly
517 @end
518 */
519 
520 DEFINE_PROTOTYPE("KateJSView",KateJSViewProto)
521 IMPLEMENT_PROTOFUNC(KateJSViewProtoFunc)
522 IMPLEMENT_PROTOTYPE(KateJSViewProto,KateJSViewProtoFunc)
523 
524 const KJS::ClassInfo KateJSView::info = { "KateJSView", 0, &KateJSViewTable, 0 };
525 
526 KJS::Value KJS::KateJSViewProtoFunc::call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args)
527 {
528  KJS_CHECK_THIS( KateJSView, thisObj );
529 
530  KateView *view = static_cast<KateJSView *>( thisObj.imp() )->view;
531 
532  if (!view)
533  return KJS::Undefined();
534 
535  switch (id)
536  {
537  case KateJSView::CursorLine:
538  return KJS::Number (view->cursorLine());
539 
540  case KateJSView::CursorColumn:
541  return KJS::Number (view->cursorColumn());
542 
543  case KateJSView::CursorColumnReal:
544  return KJS::Number (view->cursorColumnReal());
545 
546  case KateJSView::SetCursorPosition:
547  return KJS::Boolean( view->setCursorPosition( args[0].toUInt32(exec), args[1].toUInt32(exec) ) );
548 
549  case KateJSView::SetCursorPositionReal:
550  return KJS::Boolean( view->setCursorPositionReal( args[0].toUInt32(exec), args[1].toUInt32(exec) ) );
551 
552  // SelectionInterface goes in the view, in anticipation of the future
553  case KateJSView::Selection:
554  return KJS::String( view->selection() );
555 
556  case KateJSView::HasSelection:
557  return KJS::Boolean( view->hasSelection() );
558 
559  case KateJSView::SetSelection:
560  return KJS::Boolean( view->setSelection(args[0].toUInt32(exec),
561  args[1].toUInt32(exec),
562  args[2].toUInt32(exec),
563  args[3].toUInt32(exec)) );
564 
565  case KateJSView::RemoveSelectedText:
566  return KJS::Boolean( view->removeSelectedText() );
567 
568  case KateJSView::SelectAll:
569  return KJS::Boolean( view->selectAll() );
570 
571  case KateJSView::ClearSelection:
572  return KJS::Boolean( view->clearSelection() );
573  }
574 
575  return KJS::Undefined();
576 }
577 
578 KateJSView::KateJSView (KJS::ExecState *exec, KateView *_view)
579  : KJS::ObjectImp (KateJSViewProto::self(exec))
580  , view (_view)
581 {
582 }
583 
584 KJS::Value KateJSView::get( KJS::ExecState *exec, const KJS::Identifier &propertyName) const
585 {
586  return KJS::lookupGetValue<KateJSView,KJS::ObjectImp>(exec, propertyName, &KateJSViewTable, this );
587 }
588 
589 KJS::Value KateJSView::getValueProperty(KJS::ExecState *exec, int token) const
590 {
591  if (!view)
592  return KJS::Undefined ();
593 
594  switch (token) {
595  case KateJSView::SelStartLine:
596  return KJS::Number( view->selStartLine() );
597 
598  case KateJSView::SelStartCol:
599  return KJS::Number( view->selStartCol() );
600 
601  case KateJSView::SelEndLine:
602  return KJS::Number( view->selEndLine() );
603 
604  case KateJSView::SelEndCol:
605  return KJS::Number( view->selEndCol() );
606  }
607 
608  return KJS::Undefined ();
609 }
610 
611 void KateJSView::put(KJS::ExecState *exec, const KJS::Identifier &propertyName, const KJS::Value& value, int attr)
612 {
613  KJS::lookupPut<KateJSView,KJS::ObjectImp>(exec, propertyName, value, attr, &KateJSViewTable, this );
614 }
615 
616 void KateJSView::putValueProperty(KJS::ExecState *exec, int token, const KJS::Value& value, int attr)
617 {
618  if (!view)
619  return;
620 
621 
622 }
623 
624 //END
625 
626 //BEGIN KateJScriptManager
627 
628 KateJScriptManager::KateJScriptManager ()
629 {
630  m_scripts.setAutoDelete (true);
631  collectScripts ();
632 }
633 
634 KateJScriptManager::~KateJScriptManager ()
635 {
636 }
637 
638 void KateJScriptManager::collectScripts (bool force)
639 {
640 // If there's something in myModeList the Mode List was already built so, don't do it again
641  if (!m_scripts.isEmpty())
642  return;
643 
644  // We'll store the scripts list in this config
645  TDEConfig config("katepartjscriptrc", false, false);
646 
647  // figure out if the kate install is too new
648  config.setGroup ("General");
649  if (config.readNumEntry ("Version") > config.readNumEntry ("CachedVersion"))
650  {
651  config.writeEntry ("CachedVersion", config.readNumEntry ("Version"));
652  force = true;
653  }
654 
655  // Let's get a list of all the .js files
656  TQStringList list = TDEGlobal::dirs()->findAllResources("data","katepart/scripts/*.js",false,true);
657 
658  // Let's iterate through the list and build the Mode List
659  for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
660  {
661  // Each file has a group called:
662  TQString Group="Cache "+ *it;
663 
664  // Let's go to this group
665  config.setGroup(Group);
666 
667  // stat the file
668  struct stat sbuf;
669  memset (&sbuf, 0, sizeof(sbuf));
670  stat(TQFile::encodeName(*it), &sbuf);
671 
672  // If the group exist and we're not forced to read the .js file, let's build myModeList for katepartjscriptrc
673  if (!force && config.hasGroup(Group) && (sbuf.st_mtime == config.readNumEntry("lastModified")))
674  {
675  }
676  else
677  {
678  kdDebug (13050) << "add script: " << *it << endl;
679 
680  TQString desktopFile = (*it).left((*it).length()-2).append ("desktop");
681 
682  kdDebug (13050) << "add script (desktop file): " << desktopFile << endl;
683 
684  TQFileInfo dfi (desktopFile);
685 
686  if (dfi.exists())
687  {
688  TDEConfig df (desktopFile, true, false);
689  df.setDesktopGroup ();
690 
691  // get cmdname, fallback to baseName, if it is empty, therefor not use the tdeconfig fallback
692  TQString cmdname = df.readEntry ("X-Kate-Command");
693  if (cmdname.isEmpty())
694  {
695  TQFileInfo fi (*it);
696  cmdname = fi.baseName();
697  }
698 
699  if (m_scripts[cmdname])
700  continue;
701 
702  KateJScriptManager::Script *s = new KateJScriptManager::Script ();
703 
704  s->name = cmdname;
705  s->filename = *it;
706  s->desktopFileExists = true;
707 
708  m_scripts.insert (s->name, s);
709  }
710  else // no desktop file around, fall back to scriptfilename == commandname
711  {
712  kdDebug (13050) << "add script: fallback, no desktop file around!" << endl;
713 
714  TQFileInfo fi (*it);
715 
716  if (m_scripts[fi.baseName()])
717  continue;
718 
719  KateJScriptManager::Script *s = new KateJScriptManager::Script ();
720 
721  s->name = fi.baseName();
722  s->filename = *it;
723  s->desktopFileExists = false;
724 
725  m_scripts.insert (s->name, s);
726  }
727  }
728  }
729 
730  // Syncronize with the file katepartjscriptrc
731  config.sync();
732 }
733 
734 bool KateJScriptManager::exec( Kate::View *view, const TQString &_cmd, TQString &errorMsg )
735 {
736  // cast it hardcore, we know that it is really a kateview :)
737  KateView *v = (KateView*) view;
738 
739  if ( !v )
740  {
741  errorMsg = i18n("Could not access view");
742  return false;
743  }
744 
745  //create a list of args
746  TQStringList args( TQStringList::split( TQRegExp("\\s+"), _cmd ) );
747  TQString cmd ( args.first() );
748  args.remove( args.first() );
749 
750  kdDebug(13050) << "try to exec: " << cmd << endl;
751 
752  if (!m_scripts[cmd])
753  {
754  errorMsg = i18n("Command not found");
755  return false;
756  }
757 
758  TQFile file (m_scripts[cmd]->filename);
759 
760  if ( !file.open( IO_ReadOnly ) )
761  {
762  errorMsg = i18n("JavaScript file not found");
763  return false;
764  }
765 
766  TQTextStream stream( &file );
767  stream.setEncoding (TQTextStream::UnicodeUTF8);
768 
769  TQString source = stream.read ();
770 
771  file.close();
772 
773  return KateFactory::self()->jscript()->execute(v, source, errorMsg);
774 }
775 
776 bool KateJScriptManager::help( Kate::View *, const TQString &cmd, TQString &msg )
777 {
778  if (!m_scripts[cmd] || !m_scripts[cmd]->desktopFileExists)
779  return false;
780 
781  TDEConfig df (m_scripts[cmd]->desktopFilename(), true, false);
782  df.setDesktopGroup ();
783 
784  msg = df.readEntry ("X-Kate-Help");
785 
786  if (msg.isEmpty())
787  return false;
788 
789  return true;
790 }
791 
792 TQStringList KateJScriptManager::cmds()
793 {
794  TQStringList l;
795 
796  TQDictIterator<KateJScriptManager::Script> it( m_scripts );
797  for( ; it.current(); ++it )
798  l << it.current()->name;
799 
800  return l;
801 }
802 
803 //END
804 
805 
806 
807 
808 //BEGIN KateJSIndenter
809 
810 // -------------------------------------------------------------------------
811 /* Source for KateJSIndenterProtoTable.
812 @begin KateJSIndenterProtoTable 1
813  Dummy KateJSIndenter::Dummy DontDelete
814 @end
815 */
816 
817 /* Source for KateJSIndenterTable.
818 @begin KateJSIndenterTable 3
819  onchar KateJSIndenter::OnChar DontDelete
820  onnewline KateJSIndenter::OnNewline DontDelete
821  online KateJSIndenter::OnLine DontDelete
822 
823 @end
824 */
825 
826 KateJSIndenter::KateJSIndenter (KJS::ExecState *exec)
827  : KJS::ObjectImp (KateJSViewProto::self(exec))
828 {
829 }
830 
831 DEFINE_PROTOTYPE("KateJSIndenter",KateJSIndenterProto)
832 IMPLEMENT_PROTOFUNC(KateJSIndenterProtoFunc)
833 IMPLEMENT_PROTOTYPE(KateJSIndenterProto,KateJSIndenterProtoFunc)
834 
835 const KJS::ClassInfo KateJSIndenter::info = { "KateJSIndenter", 0, &KateJSIndenterTable, 0 };
836 
837 KJS::Value KJS::KateJSIndenterProtoFunc::call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args)
838 {
839  KJS_CHECK_THIS( KateJSIndenter, thisObj );
840 
841  return KJS::Undefined();
842 }
843 
844 //END
845 
846 //BEGIN KateIndentJScriptImpl
847 KateIndentJScriptImpl::KateIndentJScriptImpl(const TQString& internalName,
848  const TQString &filePath, const TQString &niceName,
849  const TQString &copyright, double version):
850  KateIndentScriptImplAbstract(internalName,filePath,niceName,copyright,version),m_interpreter(0),m_indenter(0)
851 {
852 }
853 
854 
855 KateIndentJScriptImpl::~KateIndentJScriptImpl()
856 {
857  deleteInterpreter();
858 }
859 
860 void KateIndentJScriptImpl::decRef()
861 {
862  KateIndentScriptImplAbstract::decRef();
863  if (refCount()==0)
864  {
865  deleteInterpreter();
866  }
867 }
868 
869 void KateIndentJScriptImpl::deleteInterpreter()
870 {
871  m_docWrapper=0;
872  m_viewWrapper=0;
873  delete m_indenter;
874  m_indenter=0;
875  delete m_interpreter;
876  m_interpreter=0;
877 }
878 
879 bool KateIndentJScriptImpl::setupInterpreter(TQString &errorMsg)
880 {
881  if (!m_interpreter)
882  {
883  kdDebug(13050)<<"Setting up interpreter"<<endl;
884  m_interpreter=new KJS::Interpreter(KJS::Object(new KateJSGlobal()));
885  m_docWrapper=new KateJSDocument(m_interpreter->globalExec(),0);
886  m_viewWrapper=new KateJSView(m_interpreter->globalExec(),0);
887  m_indenter=new KJS::Object(new KateJSIndenter(m_interpreter->globalExec()));
888  m_interpreter->globalObject().put(m_interpreter->globalExec(),"document",KJS::Object(m_docWrapper),KJS::DontDelete | KJS::ReadOnly);
889  m_interpreter->globalObject().put(m_interpreter->globalExec(),"view",KJS::Object(m_viewWrapper),KJS::DontDelete | KJS::ReadOnly);
890  m_interpreter->globalObject().put(m_interpreter->globalExec(),"debug", KJS::Object(new
891  KateJSGlobalFunctions(KateJSGlobalFunctions::Debug,1)));
892  m_interpreter->globalObject().put(m_interpreter->globalExec(),"indenter",*m_indenter,KJS::DontDelete | KJS::ReadOnly);
893  TQFile file (filePath());
894 
895  if ( !file.open( IO_ReadOnly ) )
896  {
897  errorMsg = i18n("JavaScript file not found");
898  deleteInterpreter();
899  return false;
900  }
901 
902  TQTextStream stream( &file );
903  stream.setEncoding (TQTextStream::UnicodeUTF8);
904 
905  TQString source = stream.read ();
906 
907  file.close();
908 
909  KJS::Completion comp (m_interpreter->evaluate(source));
910  if (comp.complType() == KJS::Throw)
911  {
912  KJS::ExecState *exec = m_interpreter->globalExec();
913 
914  KJS::Value exVal = comp.value();
915 
916  char *msg = exVal.toString(exec).ascii();
917 
918  int lineno = -1;
919 
920  if (exVal.type() == KJS::ObjectType)
921  {
922  KJS::Value lineVal = KJS::Object::dynamicCast(exVal).get(exec,"line");
923 
924  if (lineVal.type() == KJS::NumberType)
925  lineno = int(lineVal.toNumber(exec));
926  }
927 
928  errorMsg = i18n("Exception, line %1: %2").arg(lineno).arg(msg);
929  deleteInterpreter();
930  return false;
931  } else {
932  return true;
933  }
934  } else return true;
935 }
936 
937 
938 inline static bool KateIndentJScriptCall(Kate::View *view, TQString &errorMsg, KateJSDocument *docWrapper, KateJSView *viewWrapper,
939  KJS::Interpreter *interpreter, KJS::Object lookupobj,const KJS::Identifier& func,KJS::List params)
940 {
941  // no view, no fun
942  if (!view)
943  {
944  errorMsg = i18n("Could not access view");
945  return false;
946  }
947 
948  KateView *v=(KateView*)view;
949 
950  KJS::Object o=lookupobj.get(interpreter->globalExec(),func).toObject(interpreter->globalExec());
951  if (interpreter->globalExec()->hadException())
952  {
953  errorMsg=interpreter->globalExec()->exception().toString(interpreter->globalExec()).qstring();
954  kdDebug(13050)<<"Exception(1):"<<errorMsg<<endl;
955  interpreter->globalExec()->clearException();
956  return false;
957  }
958 
959  // init doc & view with new pointers!
960  docWrapper->doc = v->doc();
961  viewWrapper->view = v;
962 
963  /*kdDebug(13050)<<"Call Object:"<<o.toString(interpreter->globalExec()).ascii()<<endl;*/
964  o.call(interpreter->globalExec(),interpreter->globalObject(),params);
965  if (interpreter->globalExec()->hadException())
966  {
967  errorMsg=interpreter->globalExec()->exception().toString(interpreter->globalExec()).ascii();
968  kdDebug(13050)<<"Exception(2):"<<errorMsg<<endl;
969  interpreter->globalExec()->clearException();
970  return false;
971  }
972  return true;
973 }
974 
975 bool KateIndentJScriptImpl::processChar(Kate::View *view, TQChar c, TQString &errorMsg )
976 {
977 
978  kdDebug(13050)<<"KateIndentJScriptImpl::processChar"<<endl;
979  if (!setupInterpreter(errorMsg)) return false;
980  KJS::List params;
981  params.append(KJS::String(TQString(c)));
982  return KateIndentJScriptCall(view,errorMsg,m_docWrapper,m_viewWrapper,m_interpreter,*m_indenter,KJS::Identifier("onchar"),params);
983 }
984 
985 bool KateIndentJScriptImpl::processLine(Kate::View *view, const KateDocCursor &line, TQString &errorMsg )
986 {
987  kdDebug(13050)<<"KateIndentJScriptImpl::processLine"<<endl;
988  if (!setupInterpreter(errorMsg)) return false;
989  return KateIndentJScriptCall(view,errorMsg,m_docWrapper,m_viewWrapper,m_interpreter,*m_indenter,KJS::Identifier("online"),KJS::List());
990 }
991 
992 bool KateIndentJScriptImpl::processNewline( class Kate::View *view, const KateDocCursor &begin, bool needcontinue, TQString &errorMsg )
993 {
994  kdDebug(13050)<<"KateIndentJScriptImpl::processNewline"<<endl;
995  if (!setupInterpreter(errorMsg)) return false;
996  return KateIndentJScriptCall(view,errorMsg,m_docWrapper,m_viewWrapper,m_interpreter,*m_indenter,KJS::Identifier("onnewline"),KJS::List());
997 }
998 //END
999 
1000 //BEGIN KateIndentJScriptManager
1001 KateIndentJScriptManager::KateIndentJScriptManager():KateIndentScriptManagerAbstract()
1002 {
1003  m_scripts.setAutoDelete (true);
1004  collectScripts ();
1005 }
1006 
1007 KateIndentJScriptManager::~KateIndentJScriptManager ()
1008 {
1009 }
1010 
1011 void KateIndentJScriptManager::collectScripts (bool force)
1012 {
1013 // If there's something in myModeList the Mode List was already built so, don't do it again
1014  if (!m_scripts.isEmpty())
1015  return;
1016 
1017 
1018  // We'll store the scripts list in this config
1019  TDEConfig config("katepartindentjscriptrc", false, false);
1020 #if 0
1021  // figure out if the kate install is too new
1022  config.setGroup ("General");
1023  if (config.readNumEntry ("Version") > config.readNumEntry ("CachedVersion"))
1024  {
1025  config.writeEntry ("CachedVersion", config.readNumEntry ("Version"));
1026  force = true;
1027  }
1028 #endif
1029 
1030  // Let's get a list of all the .js files
1031  TQStringList list = TDEGlobal::dirs()->findAllResources("data","katepart/scripts/indent/*.js",false,true);
1032 
1033  // Let's iterate through the list and build the Mode List
1034  for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
1035  {
1036  // Each file has a group ed:
1037  TQString Group="Cache "+ *it;
1038 
1039  // Let's go to this group
1040  config.setGroup(Group);
1041 
1042  // stat the file
1043  struct stat sbuf;
1044  memset (&sbuf, 0, sizeof(sbuf));
1045  stat(TQFile::encodeName(*it), &sbuf);
1046 
1047  // If the group exist and we're not forced to read the .js file, let's build myModeList for katepartjscriptrc
1048  bool readnew=false;
1049  if (!force && config.hasGroup(Group) && (sbuf.st_mtime == config.readNumEntry("lastModified")))
1050  {
1051  config.setGroup(Group);
1052  TQString filePath=*it;
1053  TQString internalName=config.readEntry("internlName","KATE-ERROR");
1054  if (internalName=="KATE-ERROR") readnew=true;
1055  else
1056  {
1057  TQString niceName=config.readEntry("niceName",internalName);
1058  TQString copyright=config.readEntry("copyright",i18n("(Unknown)"));
1059  double version=config.readDoubleNumEntry("version",0.0);
1060  KateIndentJScriptImpl *s=new KateIndentJScriptImpl(
1061  internalName,filePath,niceName,copyright,version);
1062  m_scripts.insert (internalName, s);
1063  }
1064  }
1065  else readnew=true;
1066  if (readnew)
1067  {
1068  TQFileInfo fi (*it);
1069 
1070  if (m_scripts[fi.baseName()])
1071  continue;
1072 
1073  TQString internalName=fi.baseName();
1074  TQString filePath=*it;
1075  TQString niceName=internalName;
1076  TQString copyright=i18n("(Unknown)");
1077  double version=0.0;
1078  parseScriptHeader(filePath,&niceName,&copyright,&version);
1079  /*save the information for retrieval*/
1080  config.setGroup(Group);
1081  config.writeEntry("lastModified",sbuf.st_mtime);
1082  config.writeEntry("internalName",internalName);
1083  config.writeEntry("niceName",niceName);
1084  config.writeEntry("copyright",copyright);
1085  config.writeEntry("version",version);
1086  KateIndentJScriptImpl *s=new KateIndentJScriptImpl(
1087  internalName,filePath,niceName,copyright,version);
1088  m_scripts.insert (internalName, s);
1089  }
1090  }
1091 
1092  // Syncronize with the file katepartjscriptrc
1093  config.sync();
1094 }
1095 
1096 KateIndentScript KateIndentJScriptManager::script(const TQString &scriptname) {
1097  KateIndentJScriptImpl *s=m_scripts[scriptname];
1098  kdDebug(13050)<<scriptname<<"=="<<s<<endl;
1099  return KateIndentScript(s);
1100 }
1101 
1102 void KateIndentJScriptManager::parseScriptHeader(const TQString &filePath,
1103  TQString *niceName,TQString *copyright,double *version)
1104 {
1105  TQFile f(TQFile::encodeName(filePath));
1106  if (!f.open(IO_ReadOnly) ) {
1107  kdDebug(13050)<<"Header could not be parsed, because file could not be opened"<<endl;
1108  return;
1109  }
1110  TQTextStream st(&f);
1111  st.setEncoding (TQTextStream::UnicodeUTF8);
1112  if (!st.readLine().upper().startsWith("/**KATE")) {
1113  kdDebug(13050)<<"No header found"<<endl;
1114  f.close();
1115  return;
1116  }
1117  // here the real parsing begins
1118  kdDebug(13050)<<"Parsing indent script header"<<endl;
1119  enum {NOTHING=0,COPYRIGHT=1} currentState=NOTHING;
1120  TQString line;
1121  TQString tmpblockdata="";
1122  TQRegExp endExpr("[\\s\\t]*\\*\\*\\/[\\s\\t]*$");
1123  TQRegExp keyValue("[\\s\\t]*\\*\\s*(.+):(.*)$");
1124  TQRegExp blockContent("[\\s\\t]*\\*(.*)$");
1125  while ((line=st.readLine())!=TQString::null) {
1126  if (endExpr.exactMatch(line)) {
1127  kdDebug(13050)<<"end of config block"<<endl;
1128  if (currentState==NOTHING) break;
1129  if (currentState==COPYRIGHT) {
1130  *copyright=tmpblockdata;
1131  break;
1132  }
1133  Q_ASSERT(0);
1134  }
1135  if (currentState==NOTHING)
1136  {
1137  if (keyValue.exactMatch(line)) {
1138  TQStringList sl=keyValue.capturedTexts();
1139  kdDebug(13050)<<"key:"<<sl[1]<<endl<<"value:"<<sl[2]<<endl;
1140  kdDebug(13050)<<"key-length:"<<sl[1].length()<<endl<<"value-length:"<<sl[2].length()<<endl;
1141  TQString key=sl[1];
1142  TQString value=sl[2];
1143  if (key=="NAME") (*niceName)=value.stripWhiteSpace();
1144  else if (key=="VERSION") (*version)=value.stripWhiteSpace().toDouble(0);
1145  else if (key=="COPYRIGHT")
1146  {
1147  tmpblockdata="";
1148  if (value.stripWhiteSpace().length()>0) tmpblockdata=value;
1149  currentState=COPYRIGHT;
1150  } else kdDebug(13050)<<"ignoring key"<<endl;
1151  }
1152  } else {
1153  if (blockContent.exactMatch(line))
1154  {
1155  TQString bl=blockContent.capturedTexts()[1];
1156  //kdDebug(13050)<<"block content line:"<<bl<<endl<<bl.length()<<" "<<bl.isEmpty()<<endl;
1157  if (bl.isEmpty())
1158  {
1159  (*copyright)=tmpblockdata;
1160  kdDebug(13050)<<"Copyright block:"<<endl<<(*copyright)<<endl;
1161  currentState=NOTHING;
1162  } else tmpblockdata=tmpblockdata+"\n"+bl;
1163  }
1164  }
1165  }
1166  f.close();
1167 }
1168 //END
TDEConfig
KateDocCursor
Cursor class with a pointer to its document.
Definition: katecursor.h:92
KateJScript::wrapDocument
KJS::ObjectImp * wrapDocument(KJS::ExecState *exec, KateDocument *doc)
creates a JS wrapper object for given KateDocument
Definition: katejscript.cpp:260
TDEStdAccel::key
int key(StdAccel) KDE_DEPRECATED
KateJScript::m_global
KJS::Object * m_global
global object of interpreter
Definition: katejscript.h:96
KateJScript::execute
bool execute(KateView *view, const TQString &script, TQString &errorMsg)
execute given script the script will get the doc and view exposed via document and view object in glo...
Definition: katejscript.cpp:270
Kate::View
The Kate::View text editor interface.
Definition: view.h:42
kdDebug
kdbgstream kdDebug(int area=0)
TDEGlobal::dirs
static TDEStandardDirs * dirs()
tdelocale.h
TDEStandardDirs::findAllResources
TQStringList findAllResources(const char *type, const TQString &filter=TQString::null, bool recursive=false, bool unique=false) const
KateJScript::m_view
KJS::Object * m_view
object for view
Definition: katejscript.h:111
KateJScript::KateJScript
KateJScript()
generate new global interpreter for part scripting
Definition: katejscript.cpp:238
KateAutoIndent::modeName
static TQString modeName(uint mode)
Return the mode name given the mode.
Definition: kateautoindent.cpp:74
KJS
Cool, this is all we need here.
Definition: katejscript.cpp:53
KateJScript::m_interpreter
KJS::Interpreter * m_interpreter
js interpreter
Definition: katejscript.h:101
KStdAction::Clear
KDE::version
unsigned int version()
endl
kndbgstream & endl(kndbgstream &s)
KateJScript::m_document
KJS::Object * m_document
object for document
Definition: katejscript.h:106
KateJScript::wrapView
KJS::ObjectImp * wrapView(KJS::ExecState *exec, KateView *view)
creates a JS wrapper object for given KateView
Definition: katejscript.cpp:265
KateJScript::~KateJScript
virtual ~KateJScript()
be destructive
Definition: katejscript.cpp:252

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kate by doxygen 1.8.8
This website is maintained by Timothy Pearson.