| | | | |
Компоненты для подсветки синтаксиса. Новый взгляд. | Полный текст материала
Другие публикации автора: Максим Парфентьев
Цитата или краткий комментарий: «... Среди читателей найдется немало таких, кто с самого
начала попытается заявить о том, что существует, наконец, SynEdit, который поддерживает любой существующий на сегодняшний день синтаксис...
Как говорится, зачем изобретать велосипед? Все это так. Кроме нескольких нюансов. ...» |
Важно:- Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
- Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
- При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
- Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.
Добавить свое мнение.
[Подсвеченный синтаксис]
Отслеживать это обсуждение
Всего сообщений: 4214-10-2018 03:32Хороший компонент. Но почему нет нумерации строк на жёлобе?
Кто поможет доработать процедуру?...:
procedure TMPCustomSyntaxMemo.DrawLineNums;
var
I, H: Integer;
S: string;
begin
H:= 0;
Font.Name:= 'Courier New';
Font.Size:= 10;
Font.Color:= clBlue;
Brush.Color:= clBtnFace;
for I:= 1 to Lines.Count-1 do
begin
Canvas.TextOut((GutterWidth div 2)-4, H, IntToStr(i));
H:= H+16;
end;
end;
В этом случае строки пронумеровываются, но неправильно. Как это реализовать? |
|
17-06-2014 16:16Неплохо было бы сделать что-то аналогичное KeyStrokes в SynEdit'e. Я например там с легкостью добавил возможность комментирования кода как в 2005-ом
http://progfromdelphi.com/ |
|
26-06-2006 01:32Хорошая бочка меда... но все-таки добавлю свою ложку дегтя.
Возможно, я выкачал устаревшую версию компонента, но...
1. Свойство Color не сохраняется в dfm файле.
2. Вызов Lines.Clear не очищает текст.
3. Невозможно набирать текст "с нуля", т.к. идет отсылка к несуществующей 0-й строке.
4. Не поддерживаются вложенные секции, если их последние строки совпадают, т.е., например, при попытке выделить секции областей видимости (private... published) слово end должно закрыть последнюю из них и секцию соответствующего класса. На практике -- облом-с.
5. В базовых классах VCL существуют динамические методы, реализующие вызов обработчиков событий (DoEnter, DoExit и др.). При этом их можно перекрыть, если требуется добавить свой функционал к вызову обработчика. В данном компоненте их нет, что усложняет работу. Например, если я хочу создавать секции "на лету", то, насколько я понял, данный функционал нужно добавить к событию Attributes.OnUserToken. При этом нужно оставить его обработчик за пользователем. Как быть? И здесь же второй подвопрос: Где нужно отлавливать токены tokParenBeg и tokParenEnd, т.к. для них этот обработчик не вызывается.
PS. Я смог исправить код, относящийся к секциям и диспетчеризации события но с остальным разбираться было некогда.
С уважением. |
|
23-06-2006 08:52Всем привет, компонент класный, единственное чего бы я добавил так это возможность сворачивать begin end, и еще можно ли интегрировать в среду D7 данный SynEdit? если можно то как? |
|
21-06-2006 07:57
07-06-2006 03:51Есть еще один недочет.
Поддерживается только односимвольный индикатор шестнадцатиричного числа.
Т.е. $ из паскаля работает нормально, но если попытаться его поменять в настроечном файле на 0x из С - работать не будет.
Лечится, как обычно, заменой кода.
Что менять:
procedure ProcessHexValue(var Pos: Integer);
var WordBeg: Integer;
begin
WordBeg := Pos;
repeat
Inc(Pos);
until (Pos > Length(Line)) or not (Line[Pos] in HexChars);
AddToken(WordBeg, Pos - WordBeg, tokHexValue);
end;
Почему не работает:
Отсчет начинаем на первого символа числа - т.е. с индикатора:
WordBeg := Pos;
Проскакиваем индикатор, при первом же заходе в цикл:
Inc(Pos);
Проверяем наличие "инородных символов":
... not (Line[Pos] in HexChars) ...
Естественно, что при нотации C тут же натыкаемся на x, который не входит в набор HexChars
На что менять:
procedure ProcessHexValue(var Pos: Integer);
var WordBeg: Integer;
begin
WordBeg := Pos;
Pos:=Pos+Length(PA.LiteralHexPrefix);
while (Pos <= Length(Line)) and (Line[Pos] in HexChars) do
Inc(Pos);
AddToken(WordBeg, Pos - WordBeg, tokHexValue);
end;
Цикл изменен, чтобы не делать предварительный сдвиг счетчика на единицу назад, который тут же в теле цикла ивеличится на 1, и вернет нас в нужное положение.
Проверено.
Работатет, даже если в качестве индикатора использовать HEX: (это только для примера - показывает, что даже 4х символьный индикатор будет работать)
В остальном отличнейший компонент!
Не знаю пригодится ли он мне на практике, но следан настолько хорошо, что хочется сделать какой-нибудь редактор =)
С уважением, |
|
27-05-2006 01:262MaxProof
Тогда понятно почему Майк Лишке (http://www.soft-gems.net) в своём UCE использовал фиксированную ширину для всех символов. Правда тот компонент тоже еще в стадии разработки (или вообще заморожен).
Вы, кстати, не собираетесь плотнее заняться своим компонентом, в том плане что официальный релиз и пр.?
А то у вас действительно отличная реализация. :)
На счет юникода я ещё обязательно разбирусь, когда будет свободное время. Но там много чего основано на Char. Еще проблема в том, что к widestring нельзя обращаться как к массиву, т.е. s[i]. |
|
25-05-2006 07:46сообщение от автора материала 2 neutral
Проблема возникнет здесь:
TCharWidths = array [Boolean] of array [Char] of Byte;
(TUnitSyntaxMemo, строка ~76)
При задании или смене шрифта производится расчет длины каждого символа для ускорения вычисления координат текста (символа) внутри компонента. Как это будет выглядеть при WideStrings, пока непонятно. Можно, конечно, применить расчет ширины на лету, но сколько потребуется для этого времени? |
|
24-05-2006 07:15Я себе это так представляю:
нужно переписать TMPSynMemoStrings как наследник от TTntStringList (unicode аналог TStringList) и заменить все "string" в модуле на "widestring". Проанализировать то, что нужно переписать в механизме работы компонента мне сложно. Единственное, что ясно - это нужно в PaintTokens() заменить метод TextOut на юникод аналог. В модуле Windows есть такая функция под названием ExtTextOutW.
Жду ваших комментариев по этому поводу. |
|
24-05-2006 06:16Спасибо за прекрасный компонент. И правда впечатляет. У меня правда довольно специфичный вопрос: возможна ли переработка этого компонента для поддержки Unicode? В том плане что достаточно ли просто заменить все "string" на "widestring" и "char" на "widechar" или нужны какие-то особые решения?
Если так, то интересны ваши соображения. |
|
10-04-2006 07:42сообщение от автора материала Еще таблетка.
Показания: при перемещении горизонтального ScrollBar-а курсор может выехать в зону гуттера.
Изменить процедуру ShowCaret;
procedure TMPCustomSyntaxMemo.ShowCaret;
var n, ScreenRow: Integer;
Cp: TPoint;
begin
if (Lines.UpdateCount = 0)
and Lines.IsValidLineIndex(Range.PosY)
and IsLineVisible(Range.PosY, @ScreenRow) then begin
n := CharPosToPixOffset(Range.PosX, Range.PosY);
Cp := PixOffsetToWndOffsetEx(n, ScreenRow);
with TextRowRect[ScreenRow] do
if InRange(Cp.X, Left, Right - 1) then begin
Windows.SetCaretPos(Cp.X, Cp.Y);
Windows.ShowCaret(Handle);
fCaretVisible := True;
end;
end;
end;
|
|
19-03-2006 13:13сообщение от автора материала Извиняюсь за молчание
Глюк #1: курсор залезает вниз на скроллбар. Сам не понимаю, что я хотел сказать в закомментированном
участке текста. Таблетка:
// ClientLines() Возвращает количество строк текста, умещающихся в окне редактора
function TMPCustomSyntaxMemo.ClientLines: Integer;
begin
with TextRowRect[-1] do
{ DONE -oMax Proof -c19.03.2006 : Ошибка. Должно быть видно только целое число строк текста }
Result := (Bottom - Top {+ fCharHeight - 1}) div fCharHeight;
end;
Глюк #2: При выделении мышью области в конце текста возможно спонтанное перемещение вертикального
сколлбара в нулевое положение и обратно. Лекарство см. ниже
// MouseMove() Движение мыши - отработка изменения выделения
procedure TMPCustomSyntaxMemo.MouseMove(Shift: TShiftState; X, Y: Integer);
var Col, Row: Integer;
begin
// Управление выделением
if fDown and (Shift = [ssLeft]) then begin
// происходят изменения только если сменилась позиция
{ DONE -oMax Proof -c19.03.2006 :
WndOffsetToPixOffset может вернуть Row <= 0 для
специальных районов (выше текста, ниже текста, скрытый текст)
и т. д. Эта ситуация никак не обрабатывалась. }
WndOffsetToPixOffset(Point(X, Y), Col, Row, False);
// получаем номер строки
Row := FindVisibleRow(OffsetY, Row, True);
// получаем номер столбца в строке
Col := PixOffsetToCharPos(Col, Row);
if (Col <> Range.PosX) or (Row <> Range.PosY) then begin
Range.Enlarge(Row - Range.PosY, True);
Range.Enlarge(Col - Range.PosX);
end;
end else
...
Благодарю за внимание!
С Уважением, Max Proof
|
|
29-12-2005 09:36почему-то моё сообщение не подписалось... и ещё один глюк заметил:
когда курсор находится где-нибудь в тексте, а над курсором есть свёрнутые блоки (секции), то при нажатии Ctrl+вверх, курсор перескакивет в начало файла |
|
29-12-2005 09:30Компонент классный, остаётся пожелать успехов в доработке, а именно:
1. У меня при скроллинге - мигающий курсор залезает на Gutter и на Scrollbars. Кстати, последние как-то неуклюже смотрятся, всё-таки привычнее когда в углу, на пересечении скроллбаров - пустой квадратик... при отсутствии строки статуса за него можно хвататься мышкой и изменять размеры окна.
2. Возвращаясь к гуттеру. Неплохо добавить обработчик OnPaint, чтобы можно было реализовать прорисовку таких вещей: номер строки, иконку брек-поинта и проч. (пока рисуются только закладки).
3. Секции, а точнее иконки для управления секциями (+ и -) рисуются на гуттере, а если вспомнить любой xml-редактор, то эти кнопки могут находится в любом месте (прям в тексте). Ещё, в Delphi 2005 (2006), щёлкая 2 раза на голубую рамку с многоточием - секция автоматически раскрывается. Или предлагаю добавить обработчик на клики и дв.клики от мышки по тексту (без удержания Ctrl).
4. Объединяя пункты 3. и 4. - можно добавить пользовательский обработчик OnPaintLine (или OnDrawRow).
5. Всё-таки прокрутка средней кнопкой мыши мне крайне не понравилась... нужно предоставить пользователю возможность выбора.
6. По поводу схем (или цветовых шаблонов). Есть такой плагин для Far'а, называется Colorer. Мне очень нравится как там сделано определение таких схем (в стиле xml, а точнее - hrc), причем при изменении файла определения, Colorer автоматически перегружает этот файл, и подсветка срабатывает динамически.
7. Когда я жму Ctrl и навожу указатель мыши на слова:
то в рамку обводятся слова вместе с символами (т.е. ожидалось так: 'DEFINE', а получилось так: '{$DEFINE').
8. По поводу выделения. В Делфи, если я начинаю выделять с "пустого места", то само выделение рисуется от начала (или с конца) первого символа. В этом компоненте выделение рисуется именно с того места, откуда оно начато. С одной стороны - так привычнее для обывателя, с другой - рассеивает внимание, мне Дельфийский вариант больше нравится.
9. По поводу комментариев.
Для однострочных комментариев сдалана подсветка с начала комментария (с символов //) до последнего символа на этой строке, как и в Делфи. А для меня логичнее подсвечивать до конца строки, т.е. не до последнего символа, а до самого края редактора (ИМХО, конечно).
Для многострочных комментариев - аналогично.
10. Заметил багу, привожу конкретный текст:
для этого текста последняя строка не подсвечивается как комментарий.
11. Для пропорциональных шрифтов - нужно что-то делать с позицией курсора: при перемещении вверх-вниз он остаётся на своей позииции, а позиция задаётся в символах. Так, если у меня на одной строке много пробелов, а на другой - "широкие символы" (Ш, W), то курсор начинает скакать влвево-вправо.
Вот вроде и всё...
Единственное, повторюсь, если этот компонент научить читать .hrc файлы, так как это делает Colorer, то цены ему бы не было.
А вообще компонента очень полезна, готов принять участие в тестировании и разработке доп. функций.Сообщение не подписано |
|
19-10-2005 01:54Редактор сам не мелькает а вот CodeExplorer мелькает немилосердно при каждом изменении текста.
Кроме того в CodeExplorer-е при нажитии на процедуру не всегда курсор в редакторе устанавливается на неё, в большинстве случаев со второго раза |
|
31-08-2005 05:09сообщение от автора материала 2 MegaVolt
перемешение на небольшое расстояние вызывало большое перемещение самого текста..
Спасибо за идею. Реализация её очень проста, но стоит добавить ещё некоторый параметр-коэффициент панорамирования и вынести его в свойства компонента. Принято. |
|
31-08-2005 05:02?! Сам сижу на Celeron A 1GHz, Ram 128M и т.д. Колесо летает. Я к этому сам очень придирчив. Не понятно. Я возможно неправильно выразился. Отрисовывается всё быстро но за полную прокрутку колёсика (пальцем сверху донизу) в окне происходит сдвиг всего на 4 строчки :( Это похоже связано с различиями в драйверах мыши. Например аналогичный глюк есть в StringGrid а в ListView всё работает так как нужно.
Вопрос - тормозит ли панорамирование (нажатое колесо мыши) и общие параметры системы, если можно.Панорамирование работает нормально. Хотя я бы сделал масштаб не 1:1 а несколько больший чтобы перемешение на небольшое расстояние вызывало большое перемещение самого текста.
Параметры машины P3-666, 512MB, GF5200, mouse Genius. |
|
31-08-2005 03:59сообщение от автора материала 2 MegaVolt (2)
В догонку
Можно поюзать procedure TMPCustomSyntaxMemo.WMMouseWheel(var Message: TMessage); в модуле UnitSyntaxMemo и попробовать поменять приращения строк (+-1) и символов (+-4). В будущем вытащу эти параметры в published свойства.
|
|
31-08-2005 03:54сообщение от автора материала 2 MegaVolt
Только вот прокрутка колёсиком у меня работает очень уж медленно :(
?! Сам сижу на Celeron A 1GHz, Ram 128M и т.д. Колесо летает. Я к этому сам очень придирчив. Не понятно.
Вопрос - тормозит ли панорамирование (нажатое колесо мыши) и общие параметры системы, если можно.
Спасибо.
PS. На остальные вопросы (Castalia и поиск/замена)чуть позже, ладно? А то работы навалили, блин..;) (©Масяня) |
|
31-08-2005 03:38Класс. Мне понравилось :)
особенно понравилась возможность сворачивание синтаксических блоков в кучу :)))
Только вот прокрутка колёсиком у меня работает очень уж медленно :( |
|
30-08-2005 13:36Извините за невнимательность - про Форт я нашел. |
|
29-08-2005 16:03Разрешите пару вопросов.
1. Сам когда-то очень "болел" фортом и, просто интересно, при чем здесь упоминание о форт-машине?
2. Не сталкивался на практике с такими блочными редакторами - как там с поиском и заменой? |
|
29-08-2005 11:36
29-08-2005 11:27Castalia - это эксперт IDE Delphi. Добавляет некоторые полезные возможности в среду, в том числе и возможность выделение синтаксических блоков в коде. Такая же возможность присутствует также, например, в CodeRush от EagleSoftware. (Хотя, ИМХО, первый эксперт глюкавый, второй - слишком "тяжеловесный").
Что касается стиля выравнивания в Delphi, то сугубо ИМХО лучшим экспертом в этом деле есть DelForEx - выравнивает код в соответствии со стандартыми (неофициальными) Borland (к тому же поставляется фриваре с исходниками).
Что касается выделения операторных блоков, то допустим, что выравнивание правильно произведено в соответствии с некоторым стилем, где явно выделены токены блоков ... ;-)
Также интересно мнение (в частности, MaxProof, а в общем - всех) о выделении блоков цветом входящих в него строк, например,
http://creonet.cdu.edu.ua/cgi-bin/forumtalk.py?id=3&num=1
сообщение Kirill от 2003-07-03 23:29:00
В конечном счете выделение разных блоков относится к вторичной нотации языка и вовсе необязательно. Тем не менее, в некоторых ситуациях, оно очень помогает (например, при первичном обучении алгоритмике/программированию), так как фактически вскрывает для "исследователя кода программы" семантическую [системную]структуру алгоритма. А в некоторых случаях и помогает избежать тех же семантических ошибок (например, при использовании Python'a - попробуйте-ка определите на глаз разницу в один пробел, тем более, если в редакторе шрифт не моноширинный (как предлагается в компоненте - предмете сего обсуждения) ). Т.е. - выделение семантических групп иногда очень даже хорошо. Потому - хочется ;o) |
|
29-08-2005 01:42сообщение от автора материала Михаил Тронин
мне нравится, как это в Castalia сделано..
Что такое Castalia ? |
|
28-08-2005 15:59По поводу выделения операторных скобок - мне нравится, как это в Castalia сделано. Не зависит от стиля форматирования, разноцветные линии... |
|
25-08-2005 13:49сообщение от автора материала 2 AK
Ссылку посмотрел. Прикольно. А главное - красиво. Это достаточно просто реализовать в редакторах, которые форматируют исходный код в процессе его написания. Пример - тот же VBA в Ворде. Но в Delphi ситуация иная, и просто так, нахрапом, тут не справиться. Существует, у каждого программера, наконец, свой стиль оформления кода - например, мне нравится оставлять begin в той же строке, что и условие блока, т.е.
while n > 0 do begin
...
.
Для другого - ближе
while n > 0 do
begin
...
Можно, конечно, выровнять ситуацию, и создать токены tokBlockBegin..tokBlockEnd, но что Вы будете делать в случае
while HaveDoIt() do
if Length(s) > 7 do
try
case s[i] of
'a': ;
...
else
DoSomething();
end
finally
FreeAndNil(..)
end;
По крайней мере, это не задача компонента - это можно возложить на редактор кода, заточенного под конкретный синтаксис. От компонента нужно только прерывание OnDrawRow(..). А вот над этим уже стоит подумать.. |
|
25-08-2005 09:03Хорошая реализация.
А нельзя ли в редакторе кода отображать блоки операторов (ограниченные операторными скобками) вертикальными линиями? (Например, как в http://www.ms-inc.net/kpl.aspx ) |
|
25-08-2005 01:47сообщение от автора материала 2 Смирнов Дима
Насчет Форт-машины. Достоинства её в том, что она, во-первых, очень проста (один модуль в 4000 строк) и невелика по размерам (dll, 120k), а во-вторых, при грамотно написанных словах, способна выполнять команды скрипта, близком по написанию к естественному английскому (да и русскому) языку. Например OpenFile c:\test.txt
Я её использовал в двух случаях - как скриптовую машину и как инструмент отката - при выполнении действий пользователя формируются команды Undo и Redo на языке скрипта - и, таким образом, получается: 1). экономия памяти (сохраняются только команды типа string) и 2). возможна запись истории действий (как в фотошопе, напр.) - в том числе и в файл, что подразумевает возможность "сквозного" отката даже при выходе-входе из программы.
Но, боюсь, это уже другая тема. Если интересно - напишу подробнее. |
|
24-08-2005 22:05Хотелось бы услышать о форт машине. Где и как она используется? |
|
24-08-2005 06:56Хорошо бы это интегрировалось в среду разработки. А то так надоело когда неработает Find Declaration. |
|
24-08-2005 02:36сообщение от автора материала 2 Sega-Zero
.. возможность комментирования кода как в D2005..
Я так понял, это позволяет закомментировать некоторый участок кода? А в чем проблема - в TMPSynMemoRange пишем что-то типа
procedure TMPSynMemoRange.CommentBlock;
begin
with fRichMemo do begin
Lines.BeginUpdate;
Lines[StartY] := '(*' + Lines[StartY];
Lines[EndY] := Lines[EndY] + '*)';
Lines.EndUpdate;
end;
end;
Другое дело, что может это следует делать редактору, а не самому компоненту. Ведь есть public свойство Range: TMPSynMemoRange; |
|
24-08-2005 02:27сообщение от автора материала 2 Алексей Кузнецов
..отображать текст с несколькими шрифтами одновременно..
Нет. При смене шрифта редактора, производится замер каждого символа шрифта и сохранение его в таблице размеров (TMPCustomSyntaxMemo.CalcScreenParams;). Это позволяет ускорить процесс прорисовки и расчета положения слов. Теоретически возможно добавить в список параметров токена специальный шрифт и рассчитывать размеры символов на лету. Но для редактора кода, мне кажется, это излишне.
Но, если помучиться, что-нибудь получится :)
PS Предыдущее послание не подписано, но оно моё. Извиняюсь. |
|
24-08-2005 02:202 GEO
Непонятно, как из одного вытекает другое.
Одно из другого не вытекает, а дополняет. Поскольку анализ типа слова выполняется на лету, необходим быстрый доступ к словам.
Можно ли отнести к зарезервированным словам, допустим, index, кторый находится в описании свойства (property) класса?
Почему нет? Можно переписать OnParseWord:
procedure TFormMain.UserToken(Sender: TObject; Word: string; Pos, Line: Integer; var Token: TToken);
var n: Integer;
begin
if fDelphiKeyWords.Find(LowerCase(Word), n) then
Token := TToken(fDelphiKeyWords.Objects[n]);
case Token of
tokIndex: with Memo.Lines.Parser[Line] do
if (Count = 0) or (Tokens[0].stToken <> tokProperty) then
Token := tokText;
end;
end;
Разумеется, надо заранее определить tokIndex=tokUser-11. Аналогично c tokMessage - проверка по tokProcedure.
Сообщение не подписано |
|
23-08-2005 22:26Вопрос автору: можно ли с помощью вашего компонента отображать текст с несколькими шрифтами одновременно? А еще бы мне бы очень пригодилась поддержка верхних и нижних индексов. |
|
23-08-2005 12:18Кстати говоря, неплохо было бы сделать что-то аналогичное KeyStrokes в SynEdit'e. Я например там с легкостью добавил возможность комментирования кода как в D2005 - Ctrl+/ |
|
23-08-2005 10:30Не совсем понял, используется ли контекстно-свободная грамматика или можно реализовать контекстно-зависимые? Нашел по этому поводу только один абзац. С одной стороны, вроде бы:
Например, можно определить, когда заданное слово, являющееся именем пользовательской процедуры, используется в другой процедуре, а когда оно описывается или декларируется, и, таким образом, как-либо это подчеркнуть.
Но в начале этого абзаца читаем:
Непосредственный (мгновенный - не требует вычислений) доступ к каждому слову текста.
Непонятно, как из одного вытекает другое. Дело в том, что в Delphi есть слова, использование которых зрезервировано только в определенном контексте. Это такие слова, как, напрмер, index или message, которые имеют служебный смысл только в определении классов. А во всех остальных случаях могут использоваться совершенно свободно. Именно понимание этого момента затормозило меня в работе над проектом, который упоминал Sega-Zero. Я понял, что малой кровью тут не отделаешься, что проект (как он задумывался, окажется намного сложнее.
А как с этим обстоит дело у Вас? Можно ли отнести к зарезервированным словам, допустим, index, кторый находится в описании свойства (property) класса? |
|
23-08-2005 09:58сообщение от автора материала Еще по поводу отступов
// Сдвигает выделенные строки вправо
procedure TMPSynMemoRange.MakeIndent;
var i: Integer;
begin
if StartY <> EndY then begin
fRichMemo.Lines.BeginUpdate;
for i := StartY to EndY do
fRichMemo.Lines[i] := ' ' + fRichMemo.Lines[i];
fRichMemo.Lines.EndUpdate;
end;
end;
procedure TMPCustomSyntaxMemo.KeyDown(var Key: Word; Shift: TShiftState);
...
ORD('I'):
if [ssCtrl, ssShift] = Shift then
fRange.MakeIndent;
...
Аналогично с Ctrl+Shift+U
Никаких проблем :) |
|
23-08-2005 09:25сообщение от автора материала Критика насчет отступов принимается. Нет, пока не реализованы. Честно говоря - забыл. |
|
23-08-2005 08:52А что, отступы строк (Ctrl+Shift+u/i) не реализованы? |
|
23-08-2005 06:37сообщение от автора материала В этом компоненте можно реализовать какой-угодно синтаксис. Пример дан для Паскалевского синтаксиса (см. файл Delphi.syn) , т.к. мы в Королевстве Delphi.
Упор, тем не менее, сделан на ДИНАМИЧЕСКУЮ реализацию синтаксиса. А при этом Вы сам себе хозяин. |
|
23-08-2005 05:54Поразительно! Совсем недавно я начал заниматься совершенно таким же проектом, основанным на SynEdit'e! Уважаемый Geo не даст соврать:)
Интересна реализация сворачивания кода. Я нашел другой проект, где также реализуется сворачивание кода: http://sf.net/projects/mystix/
Но там затачивается на разные языки, я так понял, этот компонент только для паскалевского синтаксиса?
Поговорите с Geo, он вам предложит очень хорошую мысль, которая мне понравилась, и только из-за нее я взялся за реализацию. Сейчас, по причине нехватки времени, я забросил проект, но могу предложить свои услуги, если хотите:) |
|
|
|