Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Oberon
Перезагрузить страницу Подсветка синтаксиса в BlackBox собственными руками
Ответ
 
Опции темы Опции просмотра
  (#31 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 03.12.2004, 18:59

Кстати, если почитать хелп, то окажется что солидная часть функциональности приведенного тут сканера уже реализована в стандартном TextMappers.Scanner.
Ответить с цитированием
  (#32 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 03.12.2004, 18:59

Кстати, если почитать хелп, то окажется что солидная часть функциональности приведенного тут сканера уже реализована в стандартном TextMappers.Scanner.
Ответить с цитированием
  (#33 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 25.01.2005, 15:10

УРА!!!!!!!!!! ЗАРАБОТАЛО!!!!!!!!!!!!!!! Раскрыл секрет как надо сделать свое собственное View!!!!!

Раньше проблема была в том, что сохраняя свое View мы обрекаем пользователя на то, что он не сможет его открыть не имея подсистемы Master (а еще CompileThis из-за этого не работал). Так вот, оказывается свое View можно вовсе не сохранять! У вьюхи есть метод:
Цитата:
PROCEDURE (s: Store) ExternalizeAs- (VAR s1: Store), NEW, EMPTY

Before a store's Externalize procedure is called, its ExternalizeAs procedure is called, which gives the store the opportunity to denote another store that should be externalized in its place (a "proxy"). It is also possible to set s1 to NIL, which means that the store should not be externalized at all. This is used e.g. for compiler error markers, which are never stored.
ExternalizeAs ist called locally.

Pre
s1 = s guaranteed
в нем, мы тупо берем и говорим, чтобы экстернализации подвергалась вовсе не наша собственная "плохая" View, а обернутая:
Код:
PROCEDURE (v: View) ExternalizeAs- (VAR s1: Stores.Store);
BEGIN s1 := v.inner
END ExternalizeAs;
Вот и все. Проблемы решены. Работаем с автоподсветкой, а сохраняемся как обычный документ.


Вот исходник:

Master/Mod/Views.odc
Код:
MODULE MasterViews;

    IMPORT Files, Dialog, Stores, Models, Views, Controllers, Properties, StdLog, 
    TextModels, TextViews, TextMappers, Converters,
    MasterColors;

    TYPE
  View* = POINTER TO RECORD (Views.View)
      inner: TextViews.View;
      colorizing, needRefresh: BOOLEAN;
  END;

    PROCEDURE (v: View) Internalize- (VAR rd: Stores.Reader);
    BEGIN HALT(20)
    END Internalize;

    PROCEDURE (v: View) Externalize- (VAR wr: Stores.Writer);
    BEGIN HALT(21)
    END Externalize;

    PROCEDURE (v: View) ExternalizeAs- (VAR s1: Stores.Store);
    BEGIN s1 := v.inner
    END ExternalizeAs;

    PROCEDURE (v: View) CopyFromModelView- (source: Views.View; model: Models.Model);
    BEGIN
  WITH source: View DO
      IF model = NIL THEN
    v.inner := Views.CopyOf(source.inner, Views.deep)(TextViews.View)
      ELSE
    v.inner := Views.CopyWithNewModel(source.inner, model)(TextViews.View)
      END
  END
    END CopyFromModelView;

    PROCEDURE (v: View) ThisModel* (): Models.Model;
    BEGIN RETURN v.inner.ThisModel()
    END ThisModel;

    PROCEDURE (v: View) InitContext* (context: Models.Context);
    BEGIN v.InitContext^(context); v.inner.InitContext(context)
    END InitContext;

    PROCEDURE (v: View) Neutralize*;
    BEGIN v.inner.Neutralize
    END Neutralize;

    (* GetNewFrame: wrapper uses standard frame *)
    (* GetBackground: wrapper has no intrinsic background color *)

    PROCEDURE (v: View) Restore* (f: Views.Frame; l, t, r, b: INTEGER);
    BEGIN Views.InstallFrame(f, v.inner, 0, 0, 0, TRUE)    (* create and install wrapped view's frame *)
    END Restore;

    (* RestoreMarks: wrapper has no intrinsic marks, wrapped view's RestoreMarks is called by framework *)
    (* HandleModelMsg: framework performs message propagation *)
    (* HandleViewMsg: framework performs message propagation *)
    
    PROCEDURE (v: View) Colorize, NEW;
    BEGIN
  IF ~v.colorizing THEN
      v.colorizing := TRUE;
      MasterColors.ColorizeText(v.inner.ThisModel()(TextModels.Model));
      v.colorizing := FALSE
  END
    END Colorize;

    PROCEDURE (v: View) HandleCtrlMsg* (f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View);
    BEGIN
  WITH
      | msg: Controllers.EditMsg DO v.Colorize(); v.needRefresh := TRUE
      | msg: Controllers.TickMsg DO IF v.needRefresh THEN v.needRefresh := FALSE; v.Colorize() END
  ELSE
  END;
  focus := v.inner
    END HandleCtrlMsg;

    PROCEDURE (v: View) HandlePropMsg- (VAR msg: Properties.Message);
    BEGIN Views.HandlePropMsg(v.inner, msg)
    END HandlePropMsg;

    PROCEDURE NewView* (text: TextModels.Model): View;
  VAR  v: View;
    BEGIN NEW(v); v.inner := TextViews.dir.New(text); Stores.Join(v, v.inner); v.Colorize();
  RETURN v
    END NewView;
    
    PROCEDURE NewModule (): TextModels.Model;
    VAR text: TextModels.Model; f: TextMappers.Formatter;
    BEGIN
  text := TextModels.dir.New();
  f.ConnectTo(text);
  f.WriteString('MODULE;'); f.WriteLn();
  f.WriteLn();
  f.WriteTab(); f.WriteString('IMPORT StdLog;'); f.WriteLn();
  f.WriteLn();
  f.WriteLn();
  f.WriteString('END .'); f.WriteLn(); f.WriteLn();
  f.WriteLn(); f.WriteLn(); f.WriteLn(); f.WriteLn();
  RETURN text;
    END NewModule;
    
    PROCEDURE OpenNewView*;
    BEGIN Views.OpenView(NewView(NewModule()))
    END OpenNewView;
    
    PROCEDURE OpenOldView*;
  VAR loc: Files.Locator; name: Files.Name; conv: Converters.Converter; v: Views.View;
    BEGIN
  loc := NIL; name := ""; conv := NIL; v := Views.Old(Views.ask, loc, name, conv);
  IF (v # NIL) & (v IS TextViews.View) THEN
      Views.Open(NewView(v(TextViews.View).ThisModel()), loc, name, conv)
  END
    END OpenOldView;
  
END MasterViews.

Master/Rsrc/Menus.odc
Код:
MENU "Master"
    "Подсветить синтаксис в активном документе"    "^F9"    "MasterColors.Colorize"    "TextCmds.FocusGuard"
    SEPARATOR
    "Создать новый документ и открыть его в редакторе с автоподсветкой синтаксиса"    ""    "MasterViews.OpenNewView"    ""
    "Открыть существующий документ в редакторе с автоподсветкой синтаксиса"    ""    "MasterViews.OpenOldView"    ""    
END
Ответить с цитированием
  (#34 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 25.01.2005, 18:01

Цитата:
Originally posted by S.Yu.Gubanov
[b]УРА!!!!!!!!!! ЗАРАБОТАЛО!!!!!!!!!!!!!!! ...
Теперь осталось только победить мерцание возникающее при скролинге колесиком мыши большого документа.
Ответить с цитированием
  (#35 (permalink)) Старый
Alexander Shiryaev Alexander Shiryaev вне форума
Новичок
 
Сообщений: 8
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 04.01.2005
По умолчанию 25.01.2005, 22:09

А как-нибудь можно сделать, чтобы текст раскрашивался при наборе?
Ответить с цитированием
Ads.
  (#36 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 26.01.2005, 13:34

Цитата:
Originally posted by Alexander Shiryaev
[b]А как-нибудь можно сделать, чтобы текст раскрашивался при наборе?
Именно это я и сделал. В предыдущем сообщении приводится исходный код модуля специального визуализатора (View), который является оберткой над стандартным текстовым визуализатором (TextViews). Но, в тоже время, сохраняется он как обычный TextViews.View (так что потом его можно открывать как любой другой обычный документ).

Открывать этот раскрашивающий визуализатор надо вызвая подпрограмму: MasterViews.OpenNewView

Открывать в этом раскрашивающем визуализаторе старый сохраненный обычный документ надо вызывая подпрограмму: MasterViews.OpenOldView

Исходный код модулей раскрашивающих текст, я приводил ранее.

P. S.
Можно скачать уже готовенькое отсюда: "http://www.rsdn.ru/File/30795/Master 26-01-2005.rar" 38.7Kb
Распаковать в каталог BlackBox под названием Master; перезапустить его или просто сделать Info -> Update Menus; появится меню подсистемы МАСТЕР.
Ответить с цитированием
Ads
  (#37 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 31.01.2005, 14:07

Обнаружил еще одну проблему связанную с использованием самодельного wrapped-view вместо стандартного TextViews.View.

Дело в следующем.
Если в программе есть ошибка, то как правило, рано или поздно, случается трап (system trap). При этом открывается новое окно, в котором содержится список вызовов процедур (весь стек вызовов, вместе со всеми значениями их локальных переменных), причем каждое имя в этом списке есть гиперссылка на соответствующую позицию в исходном коде (если он есть). Так вот, если вдруг исходник модуля открыт в самодельной wrapped-view, то при попытке перейти по указанным гиперссылкам возникает еще один трап - гиперссылки не работают (они хотят чтобы тип того видения был в точности TextViews.View, а не какой-то другой).
Ответить с цитированием
  (#38 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 01.02.2005, 12:25

Выложил свежую версию подсистемы Master.

http://www.rsdn.ru/File/30795/Master.zip
размер 40.1 Kb

В дальнейшем, обновления планирую выкладывать там же, заменяя один файл Master.zip на другой, более свежий.
Ответить с цитированием
  (#39 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 01.02.2005, 12:25

Выложил свежую версию подсистемы Master.

http://www.rsdn.ru/File/30795/Master.zip
размер 40.1 Kb

В дальнейшем, обновления планирую выкладывать там же, заменяя один файл Master.zip на другой, более свежий.
Ответить с цитированием
  (#40 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 01.02.2005, 12:25

Выложил свежую версию подсистемы Master.

http://www.rsdn.ru/File/30795/Master.zip
размер 40.1 Kb

В дальнейшем, обновления планирую выкладывать там же, заменяя один файл Master.zip на другой, более свежий.
Ответить с цитированием
  (#41 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 01.02.2005, 12:25

Выложил свежую версию подсистемы Master.

http://www.rsdn.ru/File/30795/Master.zip
размер 40.1 Kb

В дальнейшем, обновления планирую выкладывать там же, заменяя один файл Master.zip на другой, более свежий.
Ответить с цитированием
  (#42 (permalink)) Старый
Takun Takun вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 18.05.2005
По умолчанию 18.05.2005, 22:06

Цитата:
Originally posted by S.Yu.Gubanov
[b]Выложил свежую версию подсистемы Master.
Поскольку обновлений давно не видно, рискну предложить небольшой патч (модуль MasterViews):
Код:
    PROCEDURE (v: View) HandleCtrlMsg* (f: Views.Frame; VAR msg: Controllers.Message; 
  VAR focus: Views.View);
  VAR script: Stores.Operation;
      scrlMsg: Controllers.ScrollMsg;    
    BEGIN
  WITH
      | msg: Controllers.EditMsg DO 
    v.needRefresh :=v.needRefresh OR 
    (msg.op IN {Controllers.cut, Controllers.paste}) OR
    (
        (msg.op = Controllers.pasteChar) &
    ~ (
      (ORD(msg.char) IN {10H .. 1FH}) OR
      (Controllers.modify IN msg.modifiers)    
        )    
    )
      | msg: Controllers.TickMsg DO IF v.needRefresh THEN 
        v.needRefresh := FALSE; 
        Views.BeginModification(Views.invisible, v.inner);
        v.Colorize();
        Views.EndModification(Views.invisible, v.inner)
    END
      | msg: Controllers.WheelMsg DO msg.done := TRUE;
      scrlMsg.op := msg.op; scrlMsg.vertical := TRUE;
      v.inner.HandleCtrlMsg(f,scrlMsg,focus)
  ELSE
  END;
  focus := v.inner; (* v.inner.HandleCtrlMsg(f, msg, focus); *)
    END HandleCtrlMsg;
Убирается мерцание при мышиной прокрутке, раскраска не попадает в список отменяемых действий, корректно работают некоторые операции с текстом (напримет выделение при помощи Шифта и стрелок курсора)
Ответить с цитированием
  (#43 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 29.05.2005, 15:53

Цитата:
Originally posted by Takun
[b]...раскраска не попадает в список отменяемых...
Да, на это много памяти тратилось (чтоб запомнить что было изменено, а что нет). Так что это на столько полезно, что Views.BeginModification / Views.EndModification надо внести еще и в процедуру MasterColors.Colorize


MasterColors.Colorize
Код:
PROCEDURE Colorize* ();
  VAR controller: TextControllers.Controller; 
  caret: INTEGER;
BEGIN
  controller := TextControllers.Focus(); 
  IF controller # NIL THEN 
    Views.BeginModification(Views.notUndoable, controller.view);
    Views.BeginModification(Views.invisible, controller.view);
    (* BEGIN modify *)
    caret := controller.CaretPos();
    ColorizeText(controller.text);
    controller.SetCaret(caret);
    (* END modify *)
    Views.EndModification(Views.invisible, controller.view);
    Views.EndModification(Views.notUndoable, controller.view);
  END
END Colorize;
--------------------------

Заметил следующую особенность. Если вызвать раскраску активного документа находясь в его начале, то раскраска выполнится практически мгновенно. Зато если переместиться в конец большого документа и вызвать раскраску, то она будет выполняться невыносимо долго. Такое ощущение, что BlackBox этот документ целиком перерисовывает в процессе перекраски много раз и тем больше чем ближе к концу документа мы находимся.
Ответить с цитированием
  (#44 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 31.05.2005, 10:59

Ошибку нашел в модуле MasterColorScanner в процедуре Scanner.EndPrev.
Там раньше стояло "self.end := self.reader.Pos() - 1", потом мне указали на то, что последний символ документа не раскрашивается. Я не долго думая написал "self.end := self.reader.Pos()" и последний символ раскрашиваться стал. Но зато, как до меня только вчера дошло, весь текст при повторном вызове раскраски стал перекрашиваться целиком заново, а такого быть не должно - повторный вызов раскраски должен ничего не делать (осуществляться мгновенно).

Вот как должно быть:
Код:
PROCEDURE (self: Scanner) EndPrev (attr: TextModels.Attributes), NEW;
BEGIN
  IF self.attr # attr THEN
    self.attr := attr;    
    IF ~self.reader.eot THEN 
      self.end := self.reader.Pos() - 1
    ELSE
      self.end := self.reader.Pos() 
    END;
    self.eos := TRUE;
  END;
END EndPrev;
Тут и повторная раскраска идет мгновенно (ведь основное время тратится именно на раскраску, а вовсе не на вычисления) и последний символ документа раскрашивается.
Ответить с цитированием
  (#45 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию 31.05.2005, 11:21

Обновил с учетом последних сообщений:

http://www.rsdn.ru:80/File/30795/Master.zip
Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подсветка синтаксиса как реализовать Exmap .NET 3 04.10.2008 20:50
NVIDIA и ATi должны обладать собственными фабриками для войны с Intel ORTODOX О производителях 0 25.04.2008 13:51
Подсветка синтаксиса на форуме Mnior Prolog 12 06.11.2006 18:31
Меню BlackBox как в нем исправить ошибки delpher Oberon 12 25.02.2006 12:43
Подсветка синтаксиса wils0n Eclipse 2 16.12.2005 18:36
Минимальная программа на BlackBox sacred1972 Oberon 1 17.11.2005 13:58
Как создать EXE файл в BlackBox ais Oberon 8 01.08.2005 05:48
Проблемы с DirectInput + VS 6.0 и собственными модулями(ООП) Мелкий Программирование графики 1 22.07.2005 12:22
подсветка Smarty-синтаксиса kost PHP 2 12.06.2005 13:12
Как получить BlackBox PROnya Oberon 12 22.02.2005 07:21
Подсветка синтаксиса в слитном тексте Начинающий Visual C++ 0 30.04.2004 22:58
BlackBox под Linux где найти в интернете Anonymous Oberon 3 13.04.2003 04:46



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов