ТК перестает выводить подсказки при наборе текста при специфичном содержании модуля внешней обработки

vigor Закрыто

Есть процедура для Склонения (см. файл)
Если текст есть в модуле - то автоподсказка при наборе текста не происходит. Иначе - происходит
Ссылка скрыта

Версия 6.6.9453.37073 от 18 ноября 2025 г.
платформа 8.3.27.1589
Если перенести функцию в общий модуль - работает. Если сделать пустую обработку и поместить функцию в модуль - перестает работать.

Комментарии

bolsun
#1, 25 ноября 2025 00:33

Программа не может определить что документ - модуль на языке 1С, а не макет.
В первых 30000 символах нет ни одного специфического слова-признака и документ помечается на игнорирование.
Список этих слов
@"конецпроцедуры|endprocedure|конецфункции|endfunction|конецпопытки|endtry|конецесли|endif|конеццикла|enddo";


tormozit
#2, ред. 25 ноября 2025 07:48

(1) bolsun, Если это вся проверка, то она не достаточно гибка. Например в модуле первой может располагаться функция возвращающая текст запроса на 500+ строк и такой текст не пройде такую проверку. В адаптере я проверяю так

Если Истина
		И ТипДокумента <> "ОбычныйМодуль"
		И ТипДокумента <> "МодульФормы"
		И Найти(ТекстМодуля, Символы.ПС + "КонецФункции") = 0
		И Найти(ТекстМодуля, Символы.ПС + "КонецПроцедуры") = 0
		И Найти(ТекстМодуля, Символы.ПС + "EndFunction") = 0
		И Найти(ТекстМодуля, Символы.ПС + "EndProcedure") = 0
		// И Найти(ТекстМодуля, "|ВЫБРАТЬ") = 0
		// И Найти(ТекстМодуля, "|SELECT") = 0
	Тогда
		ПороговаяДлина = 30000; // для 4х Найти() - 2мс
		КонецМодуля = Прав(ТекстМодуля, ПороговаяДлина);
		Если СтрДлина(КонецМодуля) = ПороговаяДлина Тогда
			// Это текст НЕ на встроенном языке
			ЯзыкПрограммы = Неопределено;
		Иначе 
			ПороговаяДлина = 3000; // для 4х Найти() и 30000 символов - 2мс
			КонецМодуля = Прав(ТекстМодуля, ПороговаяДлина);
			Если Истина
				И Найти(ТекстМодуля, "//") = 0
				И Найти(ТекстМодуля, "КонецЕсли") = 0
				И Найти(ТекстМодуля, "EndIf") = 0
				И Найти(ТекстМодуля, "=") = 0
				И Найти(ТекстМодуля, ");") = 0
				И Найти(ТекстМодуля, "()") = 0
				И Найти(ТекстМодуля, "Перем ") = 0
				И Найти(ТекстМодуля, "|") = 0
				И Найти(ТекстМодуля, "&НаКлиенте") = 0
				И Найти(ТекстМодуля, "&НаСервере") = 0
				И Найти(ЗаголовокДокумента, ": Модуль") = 0
				И НРег(Лев(ТекстМодуля, 4)) <> "проц"
				И НРег(Лев(ТекстМодуля, 4)) <> "функ"
			Тогда
				// Это текст НЕ на встроенном языке
				ЯзыкПрограммы = Неопределено;
			ИначеЕсли ПроверятьЧтоЭтоОкноСообщений Тогда
				// Проверка на окно сообщений
				ПозицияКаретки1 = ТурбоКонф.ПолучитьПозициюКаретки();
				ТурбоКонф.КонтролАльтКлавиша(Клавиши.O);
				ТурбоКонф.Ждать(20);
				ПозицияКаретки2 = ТурбоКонф.ПолучитьПозициюКаретки(); 
				Если ПозицияКаретки1.X = ПозицияКаретки2.X И ПозицияКаретки1.Y = ПозицияКаретки2.Y Тогда
					// Теперь точно узнали что это окно сообщений
					ЯзыкПрограммы = Неопределено;
				Иначе
					ВернутьсяВПредыдущееМестоКонфигуратора();
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;


bolsun
#3, 25 ноября 2025 12:39

(2) tormozit,

Если это вся проверка, то она не достаточно гибка.

Это не вся проверка.


bolsun
#4, 25 ноября 2025 12:44

Я проверяю и на запросы и т.д., но в присланном примере в начале модуля огромный комментарий к первой функции.


bolsun
#5, 25 ноября 2025 12:44

(4) видимо нужно с конца модуля еще брать кусок на проверку.


tormozit
#6, ред. 25 ноября 2025 12:45

(5) bolsun, да, в (2) я это делаю


bolsun
#7, 25 ноября 2025 17:44

(2) tormozit, в твоем алгоритме я не вижу, что проверяется конец модуля, вижу что поиск идет по всему модулю, что не оптимально.

{Тест}: переменной 'КонецМодуля' присвоено значение, но оно никогда не используется

КонецМодуля = Прав(ТекстМодуля, ПороговаяДлина);
		Если СтрДлина(КонецМодуля) = ПороговаяДлина Тогда
			// Это текст НЕ на встроенном языке
			ЯзыкПрограммы = Неопределено;
		Иначе 
			ПороговаяДлина = 3000; // для 4х Найти() и 30000 символов - 2мс
			КонецМодуля = Прав(ТекстМодуля, ПороговаяДлина);
			Если Истина
				И Найти(ТекстМодуля, "//") = 0
				И Найти(ТекстМодуля, "КонецЕсли") = 0
				И Найти(ТекстМодуля, "EndIf") = 0
				И Найти(ТекстМодуля, "=") = 0
				И Найти(ТекстМодуля, ");") = 0
				И Найти(ТекстМодуля, "()") = 0
				И Найти(ТекстМодуля, "Перем ") = 0
				И Найти(ТекстМодуля, "|") = 0
				И Найти(ТекстМодуля, "&НаКлиенте") = 0
				И Найти(ТекстМодуля, "&НаСервере") = 0
				И Найти(ЗаголовокДокумента, ": Модуль") = 0
				И НРег(Лев(ТекстМодуля, 4)) <> "проц"
				И НРег(Лев(ТекстМодуля, 4)) <> "функ"


tormozit
#8, ред. 25 ноября 2025 21:41

(7) bolsun, да, ошибка по оптимальности. Должно быть

			КонецМодуля = Прав(ТекстМодуля, ПороговаяДлина);
			Если Истина
				И Найти(КонецМодуля, "//") = 0
				И Найти(КонецМодуля, "КонецЕсли") = 0
				И Найти(КонецМодуля, "EndIf") = 0
				И Найти(КонецМодуля, "=") = 0
				И Найти(КонецМодуля, ");") = 0
				И Найти(КонецМодуля, "()") = 0
				И Найти(КонецМодуля, "Перем ") = 0
				И Найти(КонецМодуля, "|") = 0
				И Найти(КонецМодуля, "&НаКлиенте") = 0
				И Найти(КонецМодуля, "&НаСервере") = 0
				И Найти(ЗаголовокДокумента, ": Модуль") = 0
				И НРег(Лев(ТекстМодуля, 4)) <> "проц"
				И НРег(Лев(ТекстМодуля, 4)) <> "функ"

Исправлю. Но в то время когда я активно тестировал эту проверку, я пришел к выводу, что конец модуля проверять эффективнее. Потом я ее видимо неаккуратно поправил.


bolsun
#9, ред. 25 ноября 2025 21:39

(8) tormozit, в этом условии есть еще сомнительные проверки. Например:

И Найти(КонецМодуля, "//") = 0  // средняя
И Найти(КонецМодуля, ");") = 0 // средняя
И Найти(КонецМодуля, "()") = 0 // ниже средней
И Найти(КонецМодуля, "=") = 0  // низкая
И НРег(Лев(КонецМодуля, 4)) <> "проц" // низкая при обрезанном тексте (для полного текста - высокая)
И НРег(Лев(КонецМодуля, 4)) <> "функ" // низкая при обрезанном тексте  (для полного текста - высокая)

Думаю наличие этих признаков не гарантирует с достаточной долей вероятности, что это язык 1С, особенно в условиях обрезки в неизвестном месте текста.


bolsun
#10, ред. 25 ноября 2025 21:55

(9) сколько тут можно найти совпадений

        /// <summary>
        ///  Функция для бла бла бла
        /// </summary>
        /// <value>Соответствие</value>
				function getWordAtPosition(clientX, clientY) 
				{							var element = document.elementFromPoint ? document.elementFromPoint(clientX, clientY) : null;
				if (!element) return '';
						// Замена для процедуры document.caretRangeFromPoint
						//tooltip.parentNode.removeChild(tooltip);
		input.select();


tormozit
#11, ред. 25 ноября 2025 21:49

(9) bolsun, про последние 2 сравнения с Лев() согласен. Их надо оставить с ТекстМодуля (исправил в (8)). Но уже не помню точно, в для какого случая их добавлял. Вероятно что то очень редкое.
Еще тут важно учесть, что мое условие негативное, т.е. оно позволяет с большой вероятность понять, что это НЕ язык 1С. Т.е. тут идет анализ от противного.


bolsun
#12, 25 ноября 2025 21:53

(11) tormozit, условия которые я перечислил вообще никак не помогают оценить вероятность, а остальные позволяют почти с максимальной вероятностью утверждать, что это язык 1С,


bolsun
#13, 25 ноября 2025 21:57

(12) но то что они определяют, с большой вероятностью, что это язык программирования - да и в условиях, того что мы находимся в конфигураторе 1С, то вероятность еще возрастает, но я бы не полагался на это.


bolsun
#14, ред. 25 ноября 2025 22:04

(11) в целом непонятно что хуже, НЕ срабатывать для документа с языком 1С, или срабатывать для документа НЕ с языком 1С. И то и то не очень.
Наверное второе хуже.


tormozit
#15, ред. 25 ноября 2025 22:07

Думаю все же стоит учесть что в начале модуля не так уж и редко бывают огромные комментарии или текст запроса. Поэтому

  1. Лучше анализировать конец модуля. Там и маркеры более избирательные и вероятность их встретить больше и вероятность большого комментария заметно меньше.
  2. Учесть возможность размещения в анализируемом фрагменте большого текстового литерала (текста запроса).

(14) Несомненно, что тут даже близко нет безвредного решения. Можно лишь немного снизить шансы вреда, но не избавиться от него. В моем условии перевес в сторону "чаще считать то это язык 1С".


bolsun
#16, ред. 25 ноября 2025 22:13

(15) tormozit, да, конец модуля анализировать желательно, но обрезать лучше тогда по началу строки и убрать сомнительные признаки, которые могут быть даже у какого-то Json или просто текста.

Если цель, что бы чаще срабатывать, чем не срабатывать, тогда да, но такие признаки как =, или скобки - такое себе даже в этом случае.


bolsun
#17, 25 ноября 2025 22:55

6.6.9461.1518

  • Улучшено определение наличие в документе кода на языке 1С.

https://disk.yandex.ru/d/XRPUNWQtrbwBUw


bolsun
#18, 26 ноября 2025 23:57

bolsun изменил статус на Закрыто


Для вставки изображения или файла, перетащите его в поле редактора или вставьте файл из буфера