Исправление ошибки в TSynCompletion при пустом списке предложений
Проблема с компонентом автодополнения в Lazarus
В мае 2025 года пользователь Ñuño_Martínez обнаружил критическую ошибку в компоненте TSynCompletion из пакета SynEdit в Lazarus 3.5. Ошибка проявляется при следующих условиях:
Открывается окно автодополнения (по нажатию Shift+Space)
Вводится текст, не имеющий совпадений (список предложений становится пустым)
Нажимается Space или Enter
Возникает исключение, приводящее к зависанию программы
Как отметил разработчик Martin_fr, это действительно баг, связанный с обработкой пустого списка предложений. Проблема кроется в устаревшем коде компонента, который требует глубокого ревью.
Анализ проблемы
Основная проблема заключается в том, что код ожидает значение позиции -1 для пустого списка, но некоторые части компонента явно предотвращают это. В результате возникает несоответствие в логике работы.
Как показал анализ кода в syncompletion.pas, проверка Position >= 0 выполняется до проверки на пустой список, что может привести к исключению.
Решение от разработчиков
Martin_fr предложил патч, который изменяет порядок проверок:
if (ItemList.Count = 0) then
Cancel(Sender)
else
if Position>=0 then begin
// Обработка выбранного элемента
end;
Это решение было протестировано Ñuño_Martínez и подтверждено как рабочее. Позже патч был включен в версию Lazarus 4.99.
Альтернативное решение
Если вы не можете обновить Lazarus до версии с исправлением, можно реализовать временное решение на уровне своего приложения:
procedure TForm1.SynCompletion1CodeCompletion(var Value: string;
SourceValue: string; var SourceStart, SourceEnd: TPoint;
KeyChar: TUTF8Char; Shift: TShiftState);
begin
if SynCompletion1.ItemList.Count = 0 then
begin
SynCompletion1.CancelCompletion;
Exit;
end;
// Ваш стандартный обработчик автодополнения
end;
Рекомендации для разработчиков
Обновление компонентов: Всегда используйте последние версии SynEdit и Lazarus, где исправлены известные ошибки.
Обработка исключений: Добавляйте обработчики исключений для критических операций:
procedure TForm1.SynCompletion1Execute(Sender: TObject);
begin
try
// Ваш код
except
on E: Exception do
begin
SynCompletion1.CancelCompletion;
// Дополнительная обработка ошибки
end;
end;
end;
Тестирование граничных условий: Всегда проверяйте работу автодополнения с:
Пустым списком предложений
Одним элементом в списке
Максимальным количеством элементов
Заключение
Ошибка в TSynCompletion - хороший пример того, как важно правильно обрабатывать граничные условия. Предложенное исправление меняет порядок проверок, что делает компонент более устойчивым. Для разработчиков, использующих автодополнение в своих проектах, рекомендуется либо применить официальный патч, либо реализовать временное решение до обновления компонентов.
Если вы столкнулись с подобной проблемой, не забывайте сообщать о багах в официальный трекер Lazarus, чтобы помочь улучшить качество этого замечательного инструмента для разработки на Pascal.
Исправление ошибки зависания компонента автодополнения TSynCompletion в Lazarus при работе с пустым списком предложений.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS