' вывод строки (нужен для вывода строки в статусбар)
' параметры:
' pwsText - указатель на строку
' iRows - номер строки
' iPos - позиция в строке
' iCursorPosAfter - позиция курсора после вывода строки
sub DrawInitFind(pwsText as Wstring ptr , iRows as Long , iPos as Long , iCursorPosAfter as Long = 0)
	
	ClearLine(iRows) ' очистка нужной строки
	
	' если надо установить курсор после вывода
	if iCursorPosAfter then
		
		' получим длину
		dim as Long iTempLen = GetLenStringWithTab(pwsText , iTabSpace)
		
		' если курсор за пределами строки
		if iCursorPosAfter > iTempLen then
			
			' курсор на самый конец строки
			iCursorPosAfter = iTempLen+1
			
		EndIf
		
		'выводим строку
		DrawInPos(pwsText,"", iRows , iPos , (pObj.iColorBackGround shl 4) or pObj.iColorStatusBar , iRows , iCursorPosAfter)
		
	else
		
		'выводим строку
		DrawInPos(pwsText,"", iRows , iPos , (pObj.iColorBackGround shl 4) or pObj.iColorStatusBar)
		
	EndIf
	
End Sub

' процедура вывода о неудачном выделении памяти
sub DrawErrorMemory()
	
	ClearLine(pObj.iHeightRows) ' очистка последней строки
	
	' выводим подсказку
	DrawInPos( 0 , "Error allocated memory! Tip: close the editor! Press any key..." , pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorStatusBar)
	
	GetAnyKey()
	
End Sub

' вывод отдельной строки по координатам и с возможностью цвета
' применяется для побочного текста (вывод файлов , каких-то строк) , где не требуется скорость
' параметры:
' pwsbuf - строка для вывода
' sBuffer - строка для вывода , но в однобайтовой кодировке
' iRow - строка на экране для вывода
' iPos - позиция в экранной строке
' iColor - цвет
' iRowAfter - строка курсора после печати
'iPosAfter - позиция курсора после печати 
sub DrawInPos(pwsbuf as wstring ptr , sBuffer as string , iRow as Long = 0 , iPos as Long = 0 , iColor as long = -1 ,_
iRowAfter as Long  = 0 , iPosAfter as Long = 0)
	
	#ifdef __UNIX_SYSTEM__
		
		dim as string sBuf ' буфер для строки
		
		if pwsbuf then ' если передана юникод строка
			
			sBuf = Unicodetoutf8(pwsbuf) ' преобразуем строку в UTF8
			
		else
			
			sBuf = sBuffer ' присваиваем как есть однобайтовую строку
			
		EndIf
		
		dim as string sBefore ' начальная позиция для вывода
		
		if iRow then ' если позиция для курсора задана
			
			sBefore = !"\027[" & iRow & ";" & iPos & "H"
			
		EndIf
		
		dim as string sColor ' цвет
		
		if iColor <> -1 then ' если нужно указать цвет
			
			dim as Byte bg = (iColor and &hF0) shr 4 , fg = iColor and &hF
			
			if bg then
				
				sColor = !"\27[" & iDimConsoleColors(bg)+10 & ";" & iDimConsoleColors(fg) & "m" ' указываем цвет
				
			else
				
				sColor = !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(fg) & "m" ' указываем цвет
				
			EndIf
			
		EndIf
		
		dim as string sAfter ' установка курсора после печати строки
		
		if iRowAfter then ' если строка указана
			
			sAfter = !"\027[" & iRowAfter & ";" & iPosAfter & "H" ' задаем параметр курсора 
			
		EndIf
		
		printf ("%s" , sColor & sBefore & sBuf & sAfter & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & "m") ' выводим получившуюся строку на экран
		fflush(stdout)	
	#endif
	
	#ifdef __FB_WIN32__
		
		dim as wstring ptr pTempPointer
		
		dim as Short shColor = (pObj.iColorBackGround shl 4) or pObj.iColorText
		
		if iColor <> -1 then ' если нужно указать цвет
			
			shColor = iColor ' сохраняем его
			
		EndIf
		
		if pwsbuf then ' если передана юникод строка
			
			pTempPointer = ReplaceTabToSpace(pwsbuf , iTabSpace) ' заменим TAB на пробел
			
		else
			
			dim as wstring ptr pTempWstrEnc = ASCIITOUTF(sBuffer , w32CP_ACP) ' преобразуем ASCII в unicode
			
			if pTempWstrEnc = 0 then exit sub
			
			pTempPointer = ReplaceTabToSpace(pTempWstrEnc , iTabSpace) ' заменим TAB на пробел
			
			deallocate(pTempWstrEnc)
			
		EndIf
		
		if pTempPointer then
			
			' координаты для вывода строки
			dim as w32COORD cdPos = type(iPos-1,iRow-1)
			
			' длина строки
			dim as Long iLen = len(*pTempPointer)
			
			' длина строки аттрибутов
			dim as Long iLenAttr = GetLenStringWithTab(pTempPointer , iTabSpace)
			
			dim as long iBytesWritten ' буфер , нужен для функции WriteConsoleOutputCharacter
			
			' буфер для атрибута цвета
			redim as short iAttr(iLenAttr)  
			
			for i as Long = 0 to iLenAttr
				
				'заносим в буфер атрибут цвета
				iAttr(i) = shColor
				
			Next
			
			' определяем атрибут цвета
			w32WriteConsoleOutputAttribute(pTConsole.hNewStdOut , @iAttr(0) , iLenAttr , cdPos , @iBytesWritten)			
			
			#ifdef Win9x
				' преобразуем в кодировку консоли
				dim as string sOem = UTFTOASCII(pTempPointer , w32CP_OEM)
				
				' выводим номер строки
				w32WriteConsoleOutputCharacter(pTConsole.hNewStdOut, strptr(sOem) , iLen, cdPos, @iBytesWritten)			
			#else
				
				' выводим номер строки
				w32WriteConsoleOutputCharacter(pTConsole.hNewStdOut, pTempPointer , iLen, cdPos, @iBytesWritten)
			#endif
			if iRowAfter then ' если установка позиции указана в параметрах процедуры
				
				' установим курсор на нужную позицию
				w32SetConsoleCursorPosition(pTConsole.hNewStdOut, type(iPosAfter-1 , iRowAfter-1))
				
			else
				
				' указатель сместим на длину строки
				cdPos.X+=iLenAttr
				
				' установим курсор на нужную позицию
				w32SetConsoleCursorPosition(pTConsole.hNewStdOut, cdPos)
				
			EndIf
			
			deallocate(pTempPointer)
			
		endif
		
	#EndIf
	
	#ifdef __FB_DOS__
		
		Dim as Short shColor = (pObj.iColorBackGround shl 4) or pObj.iColorText
		
		if iColor <> -1 then ' если нужно указать цвет
			
			shColor = iColor ' сохраняем его
			
		EndIf
		
		dim as wstring ptr pWstrTempTabs
		
		if pwsbuf then ' если передана юникод строка
			
			' заменим TAB на пробелы
			pWstrTempTabs = ReplaceTabToSpace(pwsbuf, iTabSpace)
			
		else
			
			' заменим TAB на пробелы
			pWstrTempTabs = ReplaceTabToSpace(strptr(sBuffer), iTabSpace)
			
		EndIf
		
		if pWstrTempTabs then
			
			' получим дескриптор на память
			dim as short videomem = __dpmi_segment_to_descriptor(&hb800)
			
			' приведем к индексам экрана DOS
			iPos-=1
			iRow-=1
			
			' выводим в цикле каждый символ и его цвет
			for i as Long = 0 to len(*pWstrTempTabs)-1
				
				_farpokeb(videomem, (iRow * pObj.iWidthSimbols + iPos) * 2, (*pWstrTempTabs)[i])
				
				_farpokeb(videomem, (iRow * pObj.iWidthSimbols + iPos) * 2 + 1, shColor)
				
				iPos+=1
				
			Next
			
			deallocate(pWstrTempTabs) ' удалим буфер
			
			if iRowAfter then ' если установка позиции указана в параметрах процедуры
				
				' установим курсор на нужную позицию
				locate iRowAfter , iPosAfter
				
			else
				
				' установим курсор по умолчанию сразу после напечатанной строки
				locate iRow+1 , iPos+1
				
			EndIf
			
		endif
		
	#EndIf
	
End Sub

' Вывод всех перечисляемых файлов
' параметры:
' iIndex - индекс списка , с которого нужно выводить
' iFoldersCount - кол-во папок в списке
sub DrawRowsExamineFiles(Byref iIndex as Long , iFoldersCount as Long)
	
	if pObjFB.pListDir.GetSize() then ' если список не пустой
		
		dim as Long iColor = pObj.iColorText ' установим цвет
		
		if iIndex+1 > pObjFB.pListDir.GetSize() then ' если индекс за пределами кол-ва элементов списка
			
			iIndex = pObjFB.pListDir.GetSize() - 1 ' индекс будет равен кол-ву элементов списка
			
		EndIf
		
		' если при пролистывании индекс больше кол-ва строк в последней странице пролистывания
		if (pObjFB.pListDir.GetSize()+4 > pObj.iHeightRows) andalso _
		(pObjFB.pListDir.GetSize() - pObj.iHeightRows + 3 < iIndex) then
			
			' индекс ставим на самое начало вывода (чтобы строка с индексом была вверху)
			iIndex = pObjFB.pListDir.GetSize() - pObj.iHeightRows + 3
			
			' если кол-во строк меньше чем кол-во строк на экране
		elseif pObjFB.pListDir.GetSize()+3 < pObj.iHeightRows then
			
			' индекс на самое начало
			iIndex = 0
			
		EndIf
		
		dim as Long iTempIndex = iIndex ' сохраним индекс
		
		dim as Long iStartRow = 2 ' первая строка для вывода
		
		if iIndex then ' ' если возможна прокрутка вверх
			
			' на первой строке выведем маркер прокрутки
			DrawInPos(0,"++++", 1 , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
			
		else
			
			' на первой строке уберем маркер прокрутки
			DrawInPos(0,"    ", 1 , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
			
		EndIf
		
		' выведем строки на экране от 2 до пред-предпоследней строки 
		for i as Long = iStartRow to pObj.iHeightRows-2
			
			' если текущий индекс в пределах списка
			if iTempIndex < pObjFB.pListDir.GetSize() then
				
				' если строка по текущему индексу является папкой 
				if iTempIndex < iFoldersCount then
					
					iColor = (pObj.iColorBackGround shl 4) or pObj.iColorFolders ' определим нужный цвет
					
				else ' если строка по текущему индексу является файлом
					
					iColor = (pObj.iColorBackGround shl 4) or pObj.iColorFiles ' определим нужный цвет
					
				EndIf
				
				' если длина строки из списка меньше длины экранной строки
				if pObjFB.pListDir.GetValueLenIndex(iTempIndex) < pObj.iWidthSimbols then
					
					' выводим строку , остальное заполняем пробелами
					DrawInPos(*(pObjFB.pListDir.GetValueIndex(iTempIndex)) & wspace(pObj.iWidthSimbols - len(*(pObjFB.pListDir.GetValueIndex(iTempIndex)))) ,"", i , 1 , iColor)
					
				else ' если длина строки из списка не меньше длины экранной строки
					
					' выводим строку
					DrawInPos(*(pObjFB.pListDir.GetValueIndex(iTempIndex)),"", i , 1 , iColor)
					
				EndIf
				
				iTempIndex+=1 ' увеличим индекс для списка
				
			else ' если текущий индекс уже не в пределах списка
				
				' просто остальное заполняем пробелами
				DrawInPos(wspace(pObj.iWidthSimbols),"", i , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorText)
				
			EndIf
			
		Next
		
		' если возможна прокрутка вниз
		if iIndex + (pObj.iHeightRows-3) < pObjFB.pListDir.GetSize() then
			' выведем маркер прокрутки
			DrawInPos(0 , "++++" , pObj.iHeightRows-1 , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
			
		else
			' уберем маркер прокрутки
			DrawInPos(0 , "    " , pObj.iHeightRows-1 , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
			
		EndIf
		
	else ' если список пустой
		
		' цикл по кол-ву строк - 1
		for i as Long = 1 to pObj.iHeightRows-1
			
			' выводим только пробелы
			DrawInPos(wspace(pObj.iWidthSimbols) , "" , i , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorText)
			
		Next
		
	endif
	
End Sub

' рисование вводимой файловой строки
' параметры:
' pwsCurentDir - указатель на строку
' iCursor - позиция курсора после рисования строки
' iScroll - с какой позиции рисовать строку (на сколько строка прокручена влево)
sub DrawRowFileCommand(pwsCurentDir as wstring ptr , iCursor as Long , iScroll as long = 0)
	
	dim as Long iSpaces ' сколько пустых символов надо до конца экранной строки
	
	dim as Long iStart ' позиция с которой отрисуется строка
	
	dim as Long iCount ' кол-во символов в рисуемой строке
	
	dim as Long jScroll ' складываемый скролл
	
	if iScroll > 0 then ' если строка прокручена
		
		' цикл для определения стартовой позиции в строке
		' эта позиция используется в функции MID 
		do 
			
			' увеличиваем скроллинг виртуально
			jScroll+=GetWidthSymbol((*pwsCurentDir)[iStart])
			
			iStart+=1 ' увеличиваем стартовую позицию
			
		loop while jScroll <= iScroll ' пока не достигнем ширины скроллинга
		
	else ' строка не прокручена
		
		iStart=1 ' стартовая позиция с начала строки
		
	EndIf
	
	dim as Long iTotal ' складываемая виртуальная длина символов от позиции старта до ширины экрана
	
	' цикл для подсчета кол-ва символов в строке после стартовой точки iStart
	' нужна для функции MID
	for i as Long = iStart-1 to len(*pwsCurentDir)-1
		
		iTotal+= GetWidthSymbol((*pwsCurentDir)[i]) ' суммируем общую виртуальную длину
		
		if iTotal > pObj.iWidthSimbols then ' если достигли ширины знакомест экрана
			
			exit for ' выходим
			
		EndIf
		
		iCount += 1 ' суммируем кол-во символов в строке
		
	Next
	
	' получим кол-во пробелов , если длина строки меньше длины знакомест экрана
	iSpaces = pObj.iWidthSimbols - iTotal
	
	' выводим строку
	DrawInPos(mid(*pwsCurentDir , iStart , iCount) & wspace(iSpaces) , "" , _
	pObj.iHeightRows , 1 ,(pObj.iColorBackGround shl 4) or pObj.iColorText , pObj.iHeightRows , iCursor)
	
End Sub

#ifdef __UNIX_SYSTEM__ ' для линукса будем выводить с помощью Printf весь буфер за раз (так быстрее)
	
	' Рисование в консоли всего ( номеров строк , связного списка со строками , и пр.)
	' параметр:
	' iFlagNoDrawStatusBar (0 - рисовать статусбар ; 1 - не рисовать статусбар)
	sub DrawRowsEditor(iFlagNoDrawStatusBar as Long = 0)
		
		dim as Long iStart = pObj.iStartRowInWindow ' первая видимая строка
		
		dim as Long iEnd = iStart + pObj.iHeightRows-2 ' последняя видимая строка минус две строки (для статусбара и одна пустая)
		
		if iStart < 1 then iStart = 1 ' на всякий случай не допускаем начальную строку меньше 1
		
		if iEnd < iStart then iEnd = iStart ' на всякий случай не допускаем последнюю строку меньше начальной
		
		dim as string sGlobalBuf = !"\027[1;1H\027[?25l" ' ставим начальные координаты вывода и отключаем курсор
		
		dim as long iRow = 2 ' координата Y для вывода (запишем 2 строку , поскольку в sGlobalBuf уже записана 1)
		
		dim as Long iStartRow ' начальная строка выделения
		
		dim as Long iEndRow ' конечная строка выделения
		
		dim as Long iStartPos ' начальная позиция в строке выделения
		
		dim as Long iEndPos ' конечная позиция в строке выделения
		
		dim as Long iEndPosWithoutTabs ' реальная конечная позиция в строке выделения
		
		dim as Long iStartMarker ' начальная позиция маркера
		
		dim as Long iEndMarker ' конечная позиция маркера
		
		dim as Long iPosLocate = 0 ' счетчик для экранной координаты Y
		
		if pObj.iMarkerSelectionStart then ' если установлен начальный маркер выделения
			
			iStartMarker = pObj.iMarkerSelectionStart ' сохраняем позицию начального маркера во временный буфер
			
			iEndMarker = GetPosition() ' ' сохраняем позицию конечного маркера во временный буфер из текущей позиции
			
			iF iStartMarker > iEndMarker THEN ' если позиция начального маркера больше позиции конечного маркера
				
				swap iStartMarker , iEndMarker ' меняем местами значения
				
			EndIf
			' получаем начальную строку и начальную позицию в этой строке для выделения
			GetRowsAndPosFromPosition(iStartMarker , iStartRow , iStartPos , iStartPos)
			' получаем конечную строку и конечную позицию в этой строке для выделения
			GetRowsAndPosFromPosition(iEndMarker , iEndRow , iEndPosWithoutTabs , iEndPos)
			
		endif
		
		' выводим номера строк и сами строки в цикле
		for i as Long = iStart to iEnd
			
			dim as wstring ptr pWstr = pObj.pList.GetValueIndex(i-1) ' получаем указатель на строку из связного списка 
			
			iPosLocate +=1 ' увеличиваем координату Y
			
			if pWstr then ' если указатель не пустой
				
				' заменим TAB на пробелы
				dim as wstring ptr pWstrTempTabs = ReplaceTabToSpace(pWstr,iTabSpace)
				
				if pWstrTempTabs then
					
					dim as Long iLen_pWstrTempTabs = len(*pWstrTempTabs)
					
					' добавляем в буфер номера строк (подсвечены)
					sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorNumbersFore) & "m" & _
					right(string(pObj.iLenghtNumbers , "0") & i & " " , pObj.iLenghtNumbers + 1) & _
					!"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m"
					
					if pObj.iMarkerSelectionStart then ' если установлен начальный маркер выделения
						
						dim as Long iGlobalLocateY = iStart+iPosLocate-1 ' номер текущей строки во всем тексте (счетчик)
						
						if iGlobalLocateY = iStartRow then ' если выделение начинается на этой строке
							
							if iStartRow = iEndRow then ' если выделение заканчивается на этой строке
								
								dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
								
								dim as Long iCountDrawBg ' кол-во символов для выделения
								
								dim as Long iWLastAdd ' добавочная ширина знакоместа для последнего символа
								
								if GetWidthSymbol((*pWstr)[iEndPosWithoutTabs-1]) = 2 then
									
									iWLastAdd = 1
									
								EndIf
								
								iCountDrawBg = (iEndPos+iWLastAdd)-iStartPos+1 ' получаем кол-во символов для выделения
								
								' Длины строк. Когда выделение только на одной строке , то 
								' в начальной строке выделения может быть до трех буферов:
								' не выделенный , выделенный , не выделенный
								dim as Long iLen0 , iLen1 , iLen2
								
								' получаем длину первого буфера (не выделенного)
								iLen0 = iStartPos - pObj.iScrollWidth
								
								' если длина 1 буфера не умещается в экран , то 
								' обрезаем длину до максимального кол-ва символов экрана
								if iLen0 > iCountSymbols then iLen0 = iCountSymbols
								
								' если длина первого буфера больше нуля (положительное число)
								if iLen0 > 0 then
									
									' получаем буфер для данной строки
									dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstrTempTabs)
									
									if pObj.iFlagHighlight then ' если подсветка включена
										
										' добавляем строку с данными в буфер из временного буфера с подсветкой
										execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
										
									else
										
										' добавляем строку с данными в буфер из временного буфера с цветом текста
										sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
										
									EndIf
									
									iLen1 = iCountDrawBg ' длину второго буфера ставим по числу символов выделения
									
								else
									
									' iLen в данном случае - отрицательное число или ноль
									
									' длину второго буфера ставим по числу символов выделения , за минусом ilen0
									iLen1 = iCountDrawBg+iLen0
									
									' прибавляем стартовую позицию для выделения
									iStartPos-=iLen0
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen0 = 0
									
								EndIf
								
								if iLen0 < iCountSymbols then ' если длина первого буфера не заняла весь экран
									
									' если длина второго буфера больше оставшегося
									' экранного пространства
									if iLen1 > iCountSymbols - iLen0 then 
										
										ilen1 = iCountSymbols - iLen0 ' обрезаем размер второго буфера
										
									EndIf
									
								else
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen1 = 0
									
								EndIf
								
								' если длина второго буфера больше нуля (положительное число)
								if iLen1 > 0 then
									
									' получаем буфер для данной строки
									dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , iStartPos , iLen1 , 0 , iLen_pWstrTempTabs)
									
									' добавляем строку с данными в буфер и подсвечиваем нужным цветом
									sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & ";" & _
									iDimConsoleColors(pObj.iColorSelection)+10 & "m" & sTemp & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & "m"
									
								EndIf
								
								ilen2 = iCountSymbols - (iLen0+iLen1) ' вычисляем длину третьего буфера
								
								if iLen0+iLen1 < iCountSymbols then ' если осталось экранное место для символов
									
									' если длина третьего буфера вместе с другими буферами выходит за пределы экрана 
									if iLen2 > iCountSymbols - (iLen0+iLen1) then
										
										' обрезаем длину третьего буфера
										ilen2 = iCountSymbols - (iLen0+iLen1)
										
									EndIf
									
								else
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen2 = 0
									
								EndIf
								
								' если длина третьего буфера больше нуля (положительное число)
								if iLen2 > 0 then
									
									' получаем буфер для данной строки
									dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , iStartPos+iLen1 , iLen2 , 0 , iLen_pWstrTempTabs)
									
									if pObj.iFlagHighlight then ' если подсветка включена
										
										' добавляем строку с данными в буфер из временного буфера с подсветкой
										execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
										
									else
										
										' добавляем строку с данными в буфер из временного буфера с цветом текста
										sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
										
									EndIf
									
								endif
								
								' складываем длины всех строк
								iLen0 += iLen1+iLen2
								
								' если длина общей строки меньше длины экранного буфера по ширине 
								if iLen0+pObj.iLenghtNumbers+1 < pObj.iWidthSimbols then
									
									' заполняем остальную часть пробелами
									sGlobalBuf &= space(pObj.iWidthSimbols-(iLen0+pObj.iLenghtNumbers+1))
									
								EndIf
								
							else ' если выделение не заканчивается на этой строке
								
								dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
								
								' Длины строк. Когда выделение на разных строках , то 
								' в начальной строке выделения может быть до двух буферов:
								' не выделенный , выделенный
								dim as Long iLen0 , iLen1
								
								iLen0 = iStartPos - pObj.iScrollWidth ' получаем длину первого (не выделенного) буфера
								
								' если длина первого (не выделенного) буфера больше экранной длины , то обрезаем
								if iLen0 > iCountSymbols then iLen0 = iCountSymbols
								
								' если длина первого буфера больше нуля (положительное число)
								if iLen0 > 0 then
									
									' получаем буфер для данной строки
									dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstrTempTabs)
									
									if pObj.iFlagHighlight then ' если подсветка включена
										
										' добавляем строку с данными в буфер из временного буфера с подсветкой
										execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
										
									else
										
										' добавляем строку с данными в буфер из временного буфера с цветом текста
										sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
										
									EndIf
									
								else
									
									' прибавляем стартовую позицию для выделения
									iStartPos-=iLen0
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen0 = 0
									
								EndIf
								
								iLen1 = iCountSymbols - iLen0 ' получаем длину второго (выделенного) буфера
								
								if iLen0 < iCountSymbols then ' если длина первого буфера не заняла весь экран
									
									' получаем буфер для данной строки
									dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , iStartPos , iLen1 , 0 , iLen_pWstrTempTabs)
									
									' добавляем строку с данными в буфер и подсвечиваем нужным цветом
									sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & ";" & _
									iDimConsoleColors(pObj.iColorSelection)+10 & "m" & sTemp
									
								EndIf
								
								' складываем длины всех строк
								iLen0 += iLen1
								
								' если длина строки меньше длины экранного буфера по ширине 
								if iLen0+pObj.iLenghtNumbers+1 < pObj.iWidthSimbols then
									
									' заполняем остальную часть пробелами
									sGlobalBuf &= space(pObj.iWidthSimbols-(iLen0+pObj.iLenghtNumbers+1))
									
								EndIf
								
							endif
							
						elseif iGlobalLocateY = iEndRow then ' если выделение заканчивается на этой строке
							
							dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
							
							' Длины строк. Когда выделение на последней выделяемой строке , то 
							' в конечной строке выделения может быть до двух буферов:
							' выделенный , не выделенный
							dim as Long iLen0 , iLen1
							
							dim as Long iWLastAdd ' добавочная ширина знакоместа для последнего символа
							
							if GetWidthSymbol((*pWstr)[iEndPosWithoutTabs-1]) = 2 then
								
								iWLastAdd = 1
								
							EndIf
							
							' получаем длину первого (выделенного) буфера
							iLen0 = iEndPos-pObj.iScrollWidth+1+iWLastAdd
							
							' если длина выходит за пределы экрана , то обрезаем
							if iLen0 > iCountSymbols then iLen0 = iCountSymbols
							
							' если длина первого буфера больше нуля (положительное число)
							if iLen0 > 0 then
								
								' получаем буфер для данной строки
								dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstrTempTabs)
								
								' добавляем строку с данными в буфер и подсвечиваем нужным цветом
								sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & ";" & _
								iDimConsoleColors(pObj.iColorSelection)+10 & "m" & sTemp & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & "m"
								
							else
								
								' длину ставим нулевой на тот случай , если по каким-то причинам
								' число окажется отрицательным
								iLen0 = 0
								
							EndIf
							
							' получаем длину второго (не выделенного) буфера
							iLen1 = iCountSymbols - iLen0
							
							' если длина первого (выделенного) буфера не заняла весь экран
							if iLen0 < iCountSymbols then
								
								' получаем буфер для данной строки
								dim as string sTemp = GetPartStringForDraw(pWstrTempTabs , iEndPos+1+iWLastAdd , iLen1 , 0 , iLen_pWstrTempTabs)
								
								if pObj.iFlagHighlight then ' если подсветка включена
									
									' добавляем строку с данными в буфер из временного буфера с подсветкой
									execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
									
								else
									
									' добавляем строку с данными в буфер из временного буфера с цветом текста
									sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
									
								EndIf
								
							EndIf
							
							' складываем длины всех строк
							iLen0 += iLen1
							
							' если длина строки меньше длины экранного буфера по ширине 
							if iLen0+pObj.iLenghtNumbers+1 < pObj.iWidthSimbols then
								
								' заполняем остальную часть пробелами
								sGlobalBuf &= space(pObj.iWidthSimbols-(iLen0+pObj.iLenghtNumbers+1))
								
							EndIf
							
							' если выделение находится в рамках выделения , 
							' но не на начальной строке выделения и не на конечной строке выделения 
						elseif 	iGlobalLocateY > iStartRow andalso iGlobalLocateY < iEndRow then
							
							' получим предварительную длину
							dim as Long iLen0 = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1)
							
							' получаем буфер для данной строки
							dim as string sTemp = GetPartStringForDraw(pWstrTempTabs  , pObj.iScrollWidth , iLen0 , 1 , iLen_pWstrTempTabs)
							
							' добавляем строку с данными в буфер и подсвечиваем нужным цветом
							sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & ";" & _
							iDimConsoleColors(pObj.iColorSelection)+10 & "m" & sTemp & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & "m"
							
						else ' все остальные строки не в рамках выделения
							
							' получим предварительную длину
							dim as Long iLen0 = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1)
							
							' получаем буфер для данной строки
							dim as string sTemp = GetPartStringForDraw(pWstrTempTabs  , pObj.iScrollWidth , iLen0 , 1 , iLen_pWstrTempTabs)
							
							if pObj.iFlagHighlight then ' если подсветка включена
								
								' добавляем строку с данными в буфер из временного буфера с подсветкой
								execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
								
							else
								
								' добавляем строку с данными в буфер из временного буфера с цветом текста
								sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
								
							EndIf
							
						EndIf
						
					else ' если выделения текста нет
						
						' получим предварительную длину
						dim as Long iLen0 = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1)
						
						' получаем буфер для данной строки
						dim as string sTemp = GetPartStringForDraw(pWstrTempTabs  , pObj.iScrollWidth , iLen0 , 1 , iLen_pWstrTempTabs)
						
						if pObj.iFlagHighlight then ' если подсветка включена
							
							' добавляем строку с данными в буфер из временного буфера с подсветкой
							execute_highlight(*pWstrTempTabs , strptr(sTemp) , i , sGlobalBuf)
							
						else
							
							' добавляем строку с данными в буфер из временного буфера с цветом текста
							sGlobalBuf &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorText) & "m" & sTemp
							
						EndIf
						
					EndIf
					
					' удаляем буфер с пробелами
					if pWstrTempTabs then deallocate(pWstrTempTabs)
					
				endif
				
			else ' если указатель пустой 
				
				sGlobalBuf &= sPace(pObj.iWidthSimbols) ' просто заполняем пробелами
				
			EndIf
			
			' переносим координату вывода Y на следующую строку
			sGlobalBuf &= !"\027["& iRow &";1H"
			
			iRow+=1 ' увеличиваем координату Y
			
		Next
		
		if iFlagNoDrawStatusBar = 0 then ' если рисовать статусбар
			
			dim as string sMarker ' маркер для вывода в статус строке
			
			dim as string sInsert ' режим insert или overtype
			
			if pObj.iMarkerSelectionStart then ' если включено выделение
				
				' заносим в буфер размер выделенных байт
				sMarker = "[" & iEndMarker-iStartMarker+1 & "]"
				
			EndIf
			
			if pObj.iInsertMode then ' если включен режим Insert
				
				sInsert = "  *Ins Mode*  " ' режим вставки
				
			else
				
				sInsert = "  *Ovr Mode*  " ' режим замены
				
			EndIf
			
			' заносим во временный буфер строку с позициями (статусбара)
			dim as string sTemp = " Pos: " & GetPosition() & "  Column: " & pObj.iCurentPosInRow & " " & sMarker & sInsert
			
			sTemp &= pObjFB.szEncoding
			
			' дополняем строку пробелами до конца строки
			sTemp &= space(pObj.iWidthSimbols-(len(sTemp)))
			
			' заносим в буфер координату и строку статусбара , а так же 
			' заносим информацию о включении курсора и отображении его в нужных координатах
			sGlobalBuf &= !"\027[" & pObj.iHeightRows &";1H" & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & iDimConsoleColors(pObj.iColorStatusBar) & "m" & _
			sTemp & _
			!"\027[" & pObj.iCurentCursorRowInWindow & ";" & pObj.iCurentCursorPosInWindow &"H" & _
			!"\027[?25h"
			
		else ' если не нужно рисовать статусбар
			
			' только установим курсор и включим его
			sGlobalBuf &= !"\027[" & pObj.iCurentCursorRowInWindow & ";" & pObj.iCurentCursorPosInWindow &"H" & _
			!"\027[?25h"
			
		endif
		
		printf(!"%s" , sGlobalBuf) ' выводим на экран весь буфер одной командой
		fflush(stdout)
		pCopy
		
	End Sub
	
#else
	
	' вывод строки по координатам (применяется для вывода текста редактора)
	' вызывается только из DrawRowsEditor для более быстрого рисования без лишних манипуляций
	' pwsBuf - указатель на буфер строки
	' pColors - массив цветов
	' iRow - строка на экране
	' iPos - позиция в строке
	sub DrawLine(pwsBuf as wstring ptr , pColors as short ptr , iRow as Long ,  iPos as long )
		
		if pwsBuf andalso pColors then ' если валидные указатели
			
			#ifdef __FB_WIN32__
				
				' координаты для вывода строки
				dim as w32COORD cdPos = type(iPos-1,iRow-1)
				
				' длина строки
				dim as Long iLen = len(*pwsBuf)
				
				' длина строки аттрибутов
				dim as Long iLenAttr = GetLenStringWithTab(*pwsBuf , iTabSpace)
				
				dim as long iBytesWritten ' буфер , нужен для функции WriteConsoleOutputCharacter
				
				' определяем атрибут цвета
				w32WriteConsoleOutputAttribute(pTConsole.hNewStdOut , pColors , iLenAttr , cdPos , @iBytesWritten)
				
				#ifdef Win9x
					' преобразуем в кодировку консоли
					dim as string sOem = UTFTOASCII(pwsBuf , w32CP_OEM)
					
					' выводим номер строки
					w32WriteConsoleOutputCharacter(pTConsole.hNewStdOut, strptr(sOem) , iLen, cdPos, @iBytesWritten)
				#else
					
					' выводим номер строки
					w32WriteConsoleOutputCharacter(pTConsole.hNewStdOut, pwsBuf , iLen, cdPos, @iBytesWritten)
					
				#endif
			#else
				
				' получим дескриптор на память
				dim as short videomem = __dpmi_segment_to_descriptor(&hb800)
				
				' приведем к индексам экрана DOS
				iPos-=1
				iRow-=1
				
				' выводим в цикле каждый символ и его цвет
				for i as Long = 0 to len(*pwsBuf)-1
					
					_farpokeb(videomem, (iRow * pObj.iWidthSimbols + iPos) * 2, (*pwsBuf)[i])
					
					_farpokeb(videomem, (iRow * pObj.iWidthSimbols + iPos) * 2 + 1, pColors[i])
					
					iPos+=1
					
				Next
				
			#endif
			
		EndIf
		
	End Sub
	
	' Рисование в консоли всего ( номеров строк , связного списка со строками , и пр.)
	' параметр:
	' iFlagNoDrawStatusBar (0 - рисовать статусбар ; 1 - не рисовать статусбар)
	sub DrawRowsEditor(iFlagNoDrawStatusBar as Long = 0)
		
		dim as Long iStart = pObj.iStartRowInWindow ' первая видимая строка
		
		dim as Long iEnd = iStart + pObj.iHeightRows-2 ' последняя видимая строка минус две строки (для статусбара и одна пустая)
		
		dim as Long iStartRow ' начальная строка выделения
		
		dim as Long iEndRow ' конечная строка выделения
		
		dim as Long iStartPos ' начальная позиция в строке выделения
		
		dim as Long iEndPos ' конечная позиция в строке выделения
		
		dim as Long iEndPosWithoutTabs ' реальная конечная позиция в строке выделения
		
		dim as Long iStartMarker ' начальная позиция маркера
		
		dim as Long iEndMarker ' конечная позиция маркера
		
		dim as Long iPosLocate = 0 ' счетчик для экранной координаты Y
		
		'CursorOnOff(0) ' выключим курсор
		
		if iStart < 1 then iStart = 1 ' на всякий случай не допускаем начальную строку меньше 1
		
		if iEnd < iStart then iEnd = iStart ' на всякий случай не допускаем последнюю строку меньше начальной
		
		if pObj.iMarkerSelectionStart then ' если установлен начальный маркер выделения
			
			iStartMarker = pObj.iMarkerSelectionStart ' сохраняем позицию начального маркера во временный буфер
			
			iEndMarker = GetPosition() ' ' сохраняем позицию конечного маркера во временный буфер из текущей позиции
			
			iF iStartMarker > iEndMarker THEN ' если позиция начального маркера больше позиции конечного маркера
				
				swap iStartMarker , iEndMarker ' меняем местами значения
				
			EndIf
			' получаем начальную строку и начальную позицию в этой строке для выделения
			GetRowsAndPosFromPosition(iStartMarker , iStartRow , iStartPos , iStartPos)
			' получаем конечную строку и конечную позицию в этой строке для выделения
			GetRowsAndPosFromPosition(iEndMarker , iEndRow , iEndPosWithoutTabs , iEndPos)
			
		endif
		
		' выводим номера строк и сами строки в цикле
		for i as Long = iStart to iEnd
			
			iPosLocate +=1 ' увеличиваем координату Y
			#ifdef __FB_WIN32__
			if bReDrawRows(i - pObj.iStartRowInWindow) = 1 orelse bRepaintAnyway then
			#endif
			dim as Long iVirtualCursor ' курсор для смещения позиции в массиве pColorsAttr
			
			dim as wstring ptr pWstrOrig = pObj.pList.GetValueIndex(i-1) ' получаем указатель на строку из связного списка 
			
			dim as wstring ptr pTempLineString  = callocate((pObj.iWidthSimbols+1)*sizeof(wstring)) ' буфер для строки
			
			if pTempLineString = 0 then
				
				DrawErrorMemory() ' выводим ошибку памяти
				
				exit sub
				
			EndIf
			
			dim as byte bMHil(1 to 9) = {-1,-1,-1,-1,-1,-1,-1,-1,-1} ' массив координат выделений
			
			redim pColorsAttr(pObj.iWidthSimbols) as short ' массив цветов символов
			
			if pWstrOrig then ' если указатель не пустой
				
				dim as wstring ptr pWstr = ReplaceTabToSpace(pWstrOrig , iTabSpace) ' заменим TAB на пробел
				
				if pWstr then
					
					dim as Long iLen_pWstr = len(*pWstr) ' получим длину строки
					
					' добавляем строку с номерами строк
					*pTempLineString = wstr(right(string(pObj.iLenghtNumbers , "0") & i & " " , pObj.iLenghtNumbers + 1))
					
					iVirtualCursor = len(*pTempLineString) ' смещение сразу после номеров строк
					
					' добавляем цвета для номеров строк в цикле
					for i as Long = 0 to iVirtualCursor-1
						
						pColorsAttr(i) = (pObj.iColorBackGround shl 4) or pObj.iColorNumbersFore
						
					Next
					
					if pObj.iMarkerSelectionStart then ' если установлен начальный маркер выделения
						
						dim as Long iGlobalLocateY = iStart+iPosLocate-1 ' номер текущей строки во всем тексте (счетчик)
						
						if iGlobalLocateY = iStartRow then ' если выделение начинается на этой строке
							
							if iStartRow = iEndRow then ' если выделение заканчивается на этой строке
								
								dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
								
								dim as Long iCountDrawBg ' кол-во символов для выделения
								
								dim as Long iWLastAdd ' добавочная ширина знакоместа для последнего символа
								
								if GetWidthSymbol((*pWstrOrig)[iEndPosWithoutTabs-1]) = 2 then
									
									iWLastAdd = 1
									
								EndIf
								
								iCountDrawBg = (iEndPos+iWLastAdd)-iStartPos+1 ' получаем кол-во символов для выделения
								
								' Длины строк. Когда выделение только на одной строке , то 
								' в начальной строке выделения может быть до трех буферов:
								' не выделенный , выделенный , не выделенный
								dim as Long iLen0 , iLen1 , iLen2
								
								' получаем длину первого буфера (не выделенного)
								iLen0 = iStartPos - pObj.iScrollWidth
								
								' если длина 1 буфера не умещается в экран , то 
								' обрезаем длину до максимального кол-ва символов экрана
								if iLen0 > iCountSymbols then iLen0 = iCountSymbols
								
								' если длина первого буфера больше нуля (положительное число)
								if iLen0 > 0 then
									
									' получаем буфер для данной строки
									dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstr)
									
									if pTemp then ' если указатель валидный
										
										*pTempLineString &= *pTemp ' добавим строку в общий буфер
										
										deallocate(pTemp) ' освободим память
										
									EndIf
									
									' получим длину с учетом табуляций и пр. символов с различными знакоместами
									dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
									
									' сохраним цвет и координаты для первого буфера
									bMHil(1) = iVirtualCursor
									bMHil(2) = iLenT-1
									bMHil(3) = (pObj.iColorBackGround shl 4) or pObj.iColorText
									
									' смещение сразу после первого буфера
									iVirtualCursor = iLenT
									
									iLen1 = iCountDrawBg ' длину второго буфера ставим по числу символов выделения
									
								else
									
									' iLen в данном случае - отрицательное число или ноль
									
									' длину второго буфера ставим по числу символов выделения , за минусом ilen0
									iLen1 = iCountDrawBg+iLen0
									
									' прибавляем стартовую позицию для выделения
									iStartPos-=iLen0
									
									' длину ставим нулевой
									iLen0 = 0								
									
								EndIf
								
								if iLen0 < iCountSymbols then ' если длина первого буфера не заняла весь экран
									
									' если длина второго буфера больше оставшегося
									' экранного пространства
									if iLen1 > iCountSymbols - iLen0 then 
										
										ilen1 = iCountSymbols - iLen0 ' обрезаем размер второго буфера
										
									EndIf
									
								else
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen1 = 0
									
								EndIf
								
								' если длина второго буфера больше нуля (положительное число)
								if iLen1 > 0 then
									
									' получаем буфер для данной строки
									dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , iStartPos , iLen1 , 0 , iLen_pWstr)
									
									if pTemp then ' если указатель валидный
										
										*pTempLineString &= *pTemp ' добавим строку в общий буфер
										
										deallocate(pTemp) ' освободим память
										
									EndIf
									
									' получим длину с учетом табуляций и пр. символов с различными знакоместами 
									dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
									
									' сохраним цвет и координаты для второго буфера
									bMHil(4) = iVirtualCursor
									bMHil(5) = iLenT-1
									bMHil(6) = (pObj.iColorSelection shl 4) or pObj.iColorText
									
									' смещение сразу после второго буфера
									iVirtualCursor = iLenT
									
								EndIf
								
								ilen2 = iCountSymbols - (iLen0+iLen1) ' вычисляем длину третьего буфера
								
								if iLen0+iLen1 < iCountSymbols then ' если осталось экранное место для символов
									
									' если длина третьего буфера вместе с другими буферами выходит за пределы экрана 
									if iLen2 > iCountSymbols - (iLen0+iLen1) then
										
										' обрезаем длину третьего буфера
										ilen2 = iCountSymbols - (iLen0+iLen1)
										
									EndIf
									
								else
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen2 = 0
									
								EndIf
								
								' если длина третьего буфера больше нуля (положительное число)
								if iLen2 > 0 then
									
									' получаем буфер для данной строки
									dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , iStartPos+iLen1 , iLen2 , 0 , iLen_pWstr)
									
									if pTemp then ' если указатель валидный
										
										*pTempLineString &= *pTemp ' добавим строку в общий буфер
										
										deallocate(pTemp) ' освободим память
										
									EndIf
									
									' получим длину с учетом табуляций и пр. символов с различными знакоместами 
									dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
									
									' если длина общей строки меньше кол-ва символов экрана
									if iLenT < pObj.iWidthSimbols then
										
										' добавим пробелов в строку
										*pTempLineString &= wspace(pObj.iWidthSimbols-iLenT)
										
									EndIf
									
									' сохраним цвет и координаты для третьего буфера
									bMHil(7) = iVirtualCursor
									bMHil(8) = GetLenStringWithTab(*pTempLineString , iTabSpace)-1
									bMHil(9) = (pObj.iColorBackGround shl 4) or pObj.iColorText
									
								endif
								
								if pObj.iFlagHighlight then ' если включена подсветка
									
									' подсвечиваем текст
									execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1)  , i , @pColorsAttr(0) , pObj.iLenghtNumbers + 1)
									
									' если что-то было выделено
									if bMHil(4) <> -1 andalso bMHil(5) <> -1 then
										
										' установим цвет для выделенных символов в цикле
										for j as Long = bMHil(4) to bMHil(5)
											
											pColorsAttr(j) = bMHil(6)
											
										Next
										
									endif
									
								else ' если подсветка не включена
									
									' если цвета установлены для первого буфера
									if bMHil(1) <> -1 andalso bMHil(2) <> -1 then
										
										' установим цвет для не выделенных символов в цикле
										for j as Long = bMHil(1) to bMHil(2)
											
											pColorsAttr(j) = bMHil(3)
											
										Next
										
									endif
									
									' если цвета установлены для второго буфера (выделенный)
									if bMHil(4) <> -1 andalso bMHil(5) <> -1 then
										
										' установим цвет для выделенных символов в цикле
										for j as Long = bMHil(4) to bMHil(5)
											
											pColorsAttr(j) = bMHil(6)
											
										Next
										
									endif
									
									' если цвета установлены для третьего буфера
									if bMHil(7) <> -1 andalso bMHil(8) <> -1 then
										
										' установим цвет для не выделенных символов в цикле
										for j as Long = bMHil(7) to bMHil(8)
											
											pColorsAttr(j) = bMHil(9)
											
										Next
										
									endif
									
								EndIf
								
							else ' если выделение не заканчивается на этой строке
								
								dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
								
								' Длины строк. Когда выделение на разных строках , то 
								' в начальной строке выделения может быть до двух буферов:
								' не выделенный , выделенный
								dim as Long iLen0 , iLen1
								
								iLen0 = iStartPos - pObj.iScrollWidth ' получаем длину первого (не выделенного) буфера
								
								' если длина первого (не выделенного) буфера больше экранной длины , то обрезаем
								if iLen0 > iCountSymbols then iLen0 = iCountSymbols
								
								' если длина первого буфера больше нуля (положительное число)
								if iLen0 > 0 then
									
									' получаем буфер для данной строки
									dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstr)
									
									if pTemp then ' если указатель валидный
										
										*pTempLineString &= *pTemp ' добавим строку в общий буфер
										
										deallocate(pTemp) ' освободим память
										
									EndIf
									
									' получим длину с учетом табуляций и пр. символов с различными знакоместами 
									dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
									
									' сохраним цвет и координаты для первого буфера
									bMHil(1) = iVirtualCursor
									bMHil(2) = iLenT-1
									bMHil(3) = (pObj.iColorBackGround shl 4) or pObj.iColorText
									
									' смещение сразу после первого буфера
									iVirtualCursor = iLenT
									
								else
									
									' прибавляем стартовую позицию для выделения
									iStartPos-=iLen0
									
									' длину ставим нулевой на тот случай , если по каким-то причинам
									' число окажется отрицательным
									iLen0 = 0
									
								EndIf
								
								iLen1 = iCountSymbols - iLen0 ' получаем длину второго (выделенного) буфера
								
								if iLen0 < iCountSymbols then ' если длина первого буфера не заняла весь экран
									
									' получаем буфер для данной строки
									dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , iStartPos , iLen1 , 0 , iLen_pWstr)
									
									if pTemp then ' если указатель валидный
										
										*pTempLineString &= *pTemp ' добавим строку в общий буфер
										
										deallocate(pTemp) ' освободим память
										
									EndIf
									
									' получим длину с учетом табуляций и пр. символов с различными знакоместами 
									dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
									
									' если длина общей строки меньше кол-ва символов экрана
									if iLenT < pObj.iWidthSimbols then
										
										' добавим пробелов
										*pTempLineString &= wspace(pObj.iWidthSimbols-iLenT)
										
									EndIf
									
									' сохраним цвет и координаты для второго буфера
									bMHil(4) = iVirtualCursor
									bMHil(5) = GetLenStringWithTab(*pTempLineString , iTabSpace)-1
									bMHil(6) = (pObj.iColorSelection shl 4) or pObj.iColorText
									
								EndIf
								
								if pObj.iFlagHighlight then ' если подсветка включена
									
									' подсвечиваем текст
									execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1)  , i , @pColorsAttr(0) , pObj.iLenghtNumbers + 1)
									
									' если что-то было выделено
									if bMHil(4) <> -1 andalso bMHil(5) <> -1 then
										
										' подсвечиваем символы для выделенных символов
										for j as Long = bMHil(4) to bMHil(5)
											
											pColorsAttr(j) = bMHil(6)
											
										Next
										
									endif
									
								else ' если подсветка не включена
									
									' если цвета установлены для не выделенного буфера
									if bMHil(1) <> -1 andalso bMHil(2) <> -1 then
										
										' подсветим цвета для не выделенного буфера
										for j as Long = bMHil(1) to bMHil(2)
											
											pColorsAttr(j) = bMHil(3)
											
										Next
										
									endif
									
									' если цвета установлены для выделенного буфера
									if bMHil(4) <> -1 andalso bMHil(5) <> -1 then
										
										' подсветим цвета для выделенного буфера
										for j as Long = bMHil(4) to bMHil(5)
											
											pColorsAttr(j) = bMHil(6)
											
										Next
										
									endif
									
								EndIf
								
							endif
							
						elseif iGlobalLocateY = iEndRow then ' если выделение заканчивается на этой строке
							
							dim as Long iCountSymbols = pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) ' кол-во символов на экране
							
							' Длины строк. Когда выделение на последней выделяемой строке , то 
							' в конечной строке выделения может быть до двух буферов:
							' выделенный , не выделенный
							dim as Long iLen0 , iLen1
							
							dim as Long iWLastAdd ' добавочная ширина знакоместа для последнего символа
							
							if GetWidthSymbol((*pWstrOrig)[iEndPosWithoutTabs-1]) = 2 then
								
								iWLastAdd = 1
								
							EndIf
							
							' получаем длину первого (выделенного) буфера
							iLen0 = iEndPos-pObj.iScrollWidth+1+iWLastAdd
							
							' если длина выходит за пределы экрана , то обрезаем
							if iLen0 > iCountSymbols then iLen0 = iCountSymbols
							
							' если длина первого буфера больше нуля (положительное число)
							if iLen0 > 0 then
								
								' получаем буфер для данной строки
								dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , iLen0 , 0 , iLen_pWstr)
								
								if pTemp then ' если указатель валидный
									
									*pTempLineString &= *pTemp ' добавим строку в общий буфер
									
									deallocate(pTemp) ' освободим память
									
								EndIf
								
								' получим длину с учетом табуляций и пр. символов с различными знакоместами 
								dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
								
								' сохраним цвет и координаты для первого буфера
								bMHil(1) = iVirtualCursor
								bMHil(2) = iLenT-1
								bMHil(3) = (pObj.iColorSelection shl 4) or pObj.iColorText
								
								' смещение сразу после первого буфера
								iVirtualCursor = iLenT
								
							else
								
								' длину ставим нулевой на тот случай , если по каким-то причинам
								' число окажется отрицательным
								iLen0 = 0
								
							EndIf
							
							' получаем длину второго (не выделенного) буфера
							iLen1 = iCountSymbols - iLen0
							
							' если длина первого (выделенного) буфера не заняла весь экран
							if iLen0 < iCountSymbols then
								
								' получаем буфер для данной строки
								dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , iEndPos+1+iWLastAdd , iLen1 , 0 , iLen_pWstr)
								
								if pTemp then ' если указатель валидный
									
									*pTempLineString &= *pTemp ' добавим строку в общий буфер
									
									deallocate(pTemp) ' освободим память
									
								EndIf
								
								' получим длину с учетом табуляций и пр. символов с различными знакоместами 
								dim as Long iLenT = GetLenStringWithTab(*pTempLineString , iTabSpace)
								
								' если длина общей строки меньше кол-ва символов экрана
								if iLenT < pObj.iWidthSimbols then
									
									' добавим пробелов
									*pTempLineString &= wspace(pObj.iWidthSimbols-iLenT)
									
								EndIf
								
								' сохраним цвет и координаты для второго буфера
								bMHil(4) = iVirtualCursor
								bMHil(5) = GetLenStringWithTab(*pTempLineString , iTabSpace)-1
								bMHil(6) = (pObj.iColorBackGround shl 4) or pObj.iColorText
								
							EndIf
							
							if pObj.iFlagHighlight then ' если подсветка включена
								
								' подсвечиваем текст
								execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1)  , i , @pColorsAttr(0) , pObj.iLenghtNumbers + 1)
								
								' если символы выделены
								if bMHil(1) <> -1 andalso bMHil(2) <> -1 then
									
									' подсветим символы выделения
									for j as Long = bMHil(1) to bMHil(2)
										
										pColorsAttr(j) = bMHil(3)
										
									Next
									
								endif
								
							else ' если подсветка не включена 
								
								' если установлены цвета для выделенного буфера
								if bMHil(1) <> -1 andalso bMHil(2) <> -1 then
									
									' подсветим символы для выделенного буфера
									for j as Long = bMHil(1) to bMHil(2)
										
										pColorsAttr(j) = bMHil(3)
										
									Next
									
								endif
								
								' если установлены цвета для не выделенного буфера
								if bMHil(4) <> -1 andalso bMHil(5) <> -1 then
									
									' подсветим символы для не выделенного буфера
									for j as Long = bMHil(4) to bMHil(5)
										
										pColorsAttr(j) = bMHil(6)
										
									Next
									
								endif
								
							EndIf
							
							' если выделение находится в рамках выделения , 
							' но не на начальной строке выделения и не на конечной строке выделения 
						elseif 	iGlobalLocateY > iStartRow andalso iGlobalLocateY < iEndRow then
							
							' получаем буфер для данной строки
							dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) , 1 , iLen_pWstr)
							
							if pTemp then ' если указатель валидный
								
								*pTempLineString &= *pTemp ' добавим строку в общий буфер
								
								deallocate(pTemp) ' освободим память
								
							EndIf
							
							if pObj.iFlagHighlight then ' если подсветка включена
								
								' подсветим текст
								execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1)  , i , @pColorsAttr(0) , pObj.iLenghtNumbers + 1)
								
							endif
							
							' добавляем цвета для выделения в цикле
							for j as Long = iVirtualCursor to GetLenStringWithTab(*pTempLineString , iTabSpace)-1
								
								pColorsAttr(j) = (pObj.iColorSelection shl 4) or pObj.iColorText
								
							Next
							
						else ' все остальные строки не в рамках выделения
							
							' получаем буфер для данной строки
							dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) , 1 , iLen_pWstr)
							
							if pTemp then ' если указатель валидный
								
								*pTempLineString &= *pTemp ' добавим строку в общий буфер
								
								deallocate(pTemp) ' освободим память
								
							EndIf
							
							if pObj.iFlagHighlight then ' если подсветка включена
								
								' подсветим текст
								execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1)  , i , @pColorsAttr(0) , pObj.iLenghtNumbers + 1)
								
							else ' если подсветка не включена
								
								' добавляем цвета в цикле
								for j as Long = iVirtualCursor to GetLenStringWithTab(*pTempLineString , iTabSpace)-1
									
									pColorsAttr(j) = (pObj.iColorBackGround shl 4) or pObj.iColorText
									
								Next
								
							endif
							
						EndIf
						
					else ' если выделения текста нет
						
						' получаем буфер для данной строки
						dim as wstring ptr pTemp = GetPartStringForDraw(pWstr , pObj.iScrollWidth , pObj.iWidthSimbols - (pObj.iLenghtNumbers + 1) , 1 , iLen_pWstr)
						
						if pTemp then ' если указатель валидный
							
							*pTempLineString &= *pTemp ' добавим строку в общий буфер
							
							deallocate(pTemp) ' освободим память
							
						EndIf
						
						if pObj.iFlagHighlight then ' если подсветка включена
							
							' подсветим текст
							execute_highlight( pWstr , pTempLineString+(pObj.iLenghtNumbers + 1) , i , @pColorsAttr(0) , iVirtualCursor)
							
						else ' если подсветка не включена
							
							' добавляем цвета в цикле
							for j as Long = iVirtualCursor to GetLenStringWithTab(*pTempLineString , iTabSpace)-1
								
								pColorsAttr(j) = (pObj.iColorBackGround shl 4) or pObj.iColorText
								
							Next
							
						EndIf
						
					EndIf
					
					deallocate(pWstr) ' освободим буфер
					
				endif
				
			else ' если по каким-то причинам указатель пустой
				
				' заполним пробелами
				*pTempLineString = wspace(pObj.iWidthSimbols)
				
				' добавляем цвета в цикле
				for j as Long = 0 to len(*pTempLineString)-1
					
					pColorsAttr(j) = (pObj.iColorBackGround shl 4) or pObj.iColorText
					
				Next
				
			EndIf
			
			#ifdef __FB_WIN32__
				'В Windows жутко медленная консоль и при перерисовке строк мерцание,
				'поэтому такие ухищрения в виде рисования только нужных строк и даже отдельных символов
				' если строка подходит или надо рисовать в любом случае
				if bReDrawRows(i - pObj.iStartRowInWindow) = 1 orelse bRepaintAnyway then
					
					if bLeftOrRightMove(0) then ' если нужно рисовать только "пару" символов
						
						dim as Long iPos , iIndex = 1  , iPrevIndex , j
						
						' буфер выделяем побольше , на тот случай , если кому в голову вбредет поставить большую табуляцию
						dim as wstring*30 wsTemp 
						
						For i as long = 0 to len(*pTempLineString)-1 ' цикл по длине строки
							
							if bLeftOrRightMove(0) = 1 then ' если курсор сдвигался влево
								
								if iIndex = pObj.iCurentCursorPosInWindow then ' если индекс знакомест равен текущей позиции на экране
									
									'присвоим символ в буфер
									wsTemp[0] = (*pTempLineString)[i]
									
									' цикл пока не достигнем следующей позиции
									while j < bLeftOrRightMove(1)
										
										j+=1
										
										if (*pTempLineString)[i+j] = 32 then ' если пробел
											
											'присвоим символ в буфер
											wsTemp[j] = 32
											
										else
											
											'присвоим символ в буфер
											wsTemp[j] = (*pTempLineString)[i+j]
											
											exit while ' завершим цикл
											
										EndIf
										
									Wend
									
									iPos = pObj.iCurentCursorPosInWindow ' стартовая позиция для рисования
									
									exit for ' выходим из цикла
									
								EndIf
								
							else
								
								' если индекс знакомест равен прошлой позиции на экране
								if iIndex = pObj.iCurentCursorPosInWindow - bLeftOrRightMove(1) andalso wsTemp[0] = 0 then 
									
									'присвоим символ в буфер
									wsTemp[0] = (*pTempLineString)[i]
									
									iPrevIndex = iIndex ' сохраним индекс
									
								elseif iIndex = pObj.iCurentCursorPosInWindow then ' если индекс знакомест равен текущей позиции на экране
									
									j+=1
									
									'присвоим символ в буфер
									wsTemp[j] = (*pTempLineString)[i]
									
									iPos = pObj.iCurentCursorPosInWindow - bLeftOrRightMove(1) ' стартовая позиция для рисования
									
									iIndex = iPrevIndex ' индекс равен сохраненному
									
									exit for
									
								elseif iIndex > pObj.iCurentCursorPosInWindow - bLeftOrRightMove(1) then ' символы в промежутке между позициями (пробелы)
									
									j+=1
									
									'присвоим символ в буфер
									wsTemp[j] = (*pTempLineString)[i]
									
								EndIf
								
							EndIf
							
							if GetWidthSymbol((*pTempLineString)[i]) = 2 then ' если символ с 2-мя знакоместами
								
								iIndex+=2 ' увеличим индекс знакомест на 2
								
							else
								
								iIndex+=1 ' увеличим индекс знакомест на 1
								
							EndIf
							
						Next
						
						' рисуем "пару" букв
						DrawLine( @wsTemp , @pColorsAttr(iIndex-1) , iPosLocate , iPos)
						
					else
						' рисуем всю строку
						DrawLine(pTempLineString , @pColorsAttr(0) , iPosLocate , 1)
					EndIf
					
				EndIf
			#else
				' в DOS рисуем каждую строку без условий
				'потому что в DOS нет проблем с мерцанием
				DrawLine(pTempLineString , @pColorsAttr(0) , iPosLocate , 1)
			#endif
			
			' освободим буфер
			if pTempLineString then deallocate(pTempLineString)
			
			pTempLineString = 0
			#ifdef __FB_WIN32__
			endif
			#endif
		Next
		
		if iFlagNoDrawStatusBar = 0 orelse bFlagNoRePaintStatusBar = 0 then ' если рисовать и обновлять статусбар
			
			redim pColorsAttr(pObj.iWidthSimbols) as short
			
			dim as string sMarker ' маркер для вывода в статус строке
			
			dim as string sInsert ' режим insert или overtype
			
			if pObj.iMarkerSelectionStart then ' если включено выделение
				
				' заносим в буфер размер выделенных байт
				sMarker = "[" & iEndMarker-iStartMarker+1 & "]"
				
			EndIf
			
			if pObj.iInsertMode then ' если включен режим Insert
				
				sInsert = "  *Ins Mode*  " ' режим вставки
				
			else
				
				sInsert = "  *Ovr Mode*  " ' режим замены
				
			EndIf
			
			' соберем строку для статусбара
			dim as string sTemp = " Pos: " & GetPosition() & "  Column: " & pObj.iCurentPosInRow & " " & sMarker & sInsert & pObjFB.szEncoding
			
			' выделим память для юникод представления строки sTemp
			dim as wstring ptr pwsTemp = callocate((pObj.iWidthSimbols+1)*sizeof(wstring))
			
			if pwsTemp then
				
				' копируем строку в буфер юникода
				*pwsTemp = wstr(left(sTemp , pObj.iWidthSimbols))
				
				' длина строки *pwsTemp
				dim as long iLen = len(*pwsTemp)
				
				' если длина меньше длины кол-ва символов на экране
				if iLen < pObj.iWidthSimbols then
					
					' добавим пробелов
					*pwsTemp &= wspace(pObj.iWidthSimbols - iLen)
					
				EndIf
				
				' добавляем цвета в цикле для статусбара
				for j as Long = 0 to len(*pwsTemp)-1
					
					pColorsAttr(j) = (pObj.iColorBackGround shl 4) or pObj.iColorStatusBar
					
				Next
				
				' рисуем строку статусбара
				DrawLine(pwsTemp , @pColorsAttr(0) , pObj.iHeightRows , 1)
				
				' освободим память
				deallocate(pwsTemp)
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		endif
		
		' установим курсор на нужную позицию
		#ifdef __FB_WIN32__
			w32SetConsoleCursorPosition(pTConsole.hNewStdOut, type(pObj.iCurentCursorPosInWindow-1 , pObj.iCurentCursorRowInWindow-1))
			'CursorOnOff(1) ' включим курсор
			bRepaintAnyway = 0
		#else
			locate(pObj.iCurentCursorRowInWindow , pObj.iCurentCursorPosInWindow , 1)
			pcopy
		#endif
		bFlagNoRePaintStatusBar = 0 ' сбросим флаг запрета обновления StatusBar
		bLeftOrRightMove(0) = 0 ' сбрасываем флаг движения курсора
	End Sub
	
#endif

' просто очистка одной строки на экране
' параметр:
' iRow - номер экранной строки
sub ClearLine(iRow as Long)
	
	'  очистим строку пробелами
	DrawInPos(0 , space(pObj.iWidthSimbols) , iRow , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorText , iRow , 1)
	
End Sub

' диалог вывода информации о кодировках при открытии или сохрании файла
' параметр: 
' iFlagSave - (0 - загрузка ; 1 - сохранение)
sub DrawEncoding(iFlagSave as Long)
	
	' очистим 1 строку
	ClearLine(pObj.iHeightRows)
	
	if iFlagSave then ' если подсказка нужна для сохранения файла
		
		' выведем подсказку
		#ifdef __FB_WIN32__
			DrawInPos(0,"Select Encoding (0 - ASCII ; 1 - UTF8 ; 2 - UTF8(BOM) ; 3 - UTF16)", pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		#else
			#ifdef __UNIX_SYSTEM__
				DrawInPos(0,"Select Encoding (0 - UTF8 ; 1 - UTF8(BOM) ; 2 - UTF32)", pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
			#EndIf
		#EndIf
		
		
	else ' если подсказка нужна для открытия файла
		
		' выведем подсказку
		#ifdef __FB_WIN32__
			DrawInPos(0,"Select Encoding (0 - ASCII ; 1 - UTF8)", pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		#EndIf
		
	EndIf
	
End Sub

' диалог вывода информации о существовании файла
sub DrawFileExists()
	
	' очистим последнюю строку
	ClearLine(pObj.iHeightRows)
	
	' выведем подсказку
	DrawInPos(0,"File exists, overwrite? (0 - No ; 1 - Yes)", pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
	
End Sub

#ifdef __UNIX_SYSTEM__
	
	' вспомогательная процедура для посветки на линуксе
	sub execute_highlight2(psz as zstring ptr , iRowNumber as Long , sBufLinux as string , iColorPrevSymbol as long = 0)
		
		dim as long iBeginWord = -1 ' начало потенциально выделяемого слова
		
		dim as Byte bFlagQuote , bFlagSingleK , bFlagMkEnable ' флаги для кавычек,однострочного и многострочного комментария 
		
		if psz = 0 then exit sub
		
		dim as Long iLenPsz = len(*psz)
		
		dim as long iLenPszMinusOneSymbol = iLenPsz-1
		
		DIM AS bYTE PTR pBytes = callocate(iLenPsz+1) ' выделим память для хранения цветов каждого символа
		
		if pBytes = 0 then
			
			DrawErrorMemory() ' выводим ошибку памяти
			
			exit sub
			
		EndIf
		
		' цикл по числу символов/байт
		for i as long  = 0 to iLenPszMinusOneSymbol
			
			if iCountMultiComments then ' если в тексте есть многострочные комментарии
				
				' цикл по кол-ву многострочных комментариев
				for j as long = 0 to ubound(pMultiComment)
					
					if pMultiComment(j).iBeginRow <> -1 then ' если что-то заполнено
						
						' если текущая строка находится в рамках данных массива комментариев
						if iRowNumber >= pMultiComment(j).iBeginRow andalso iRowNumber <= pMultiComment(j).iEndRow then
							
							' если один из случаев совпадает
							'1) если комментарий умещается на одной строке
							' остальные ниже случаи для многострочных комментариев
							'2) если комментарий на последней строке
							'3) если комментарий на строке , которая между первой и последней строкой
							'4) если комментарий на первой строке
							if (pMultiComment(j).iBeginRow = pMultiComment(j).iEndRow andalso i >=pMultiComment(j).iBeginPos andalso i <=pMultiComment(j).iEndPos) orelse _
							(pMultiComment(j).iBeginRow <> pMultiComment(j).iEndRow) andalso (iRowNumber = pMultiComment(j).iEndRow andalso i <=pMultiComment(j).iEndPos) orelse _
							((iRowNumber < pMultiComment(j).iEndRow) andalso (iRowNumber > pMultiComment(j).iBeginRow)) orelse _
							((pMultiComment(j).iBeginRow <> pMultiComment(j).iEndRow) andalso (iRowNumber = pMultiComment(j).iBeginRow) andalso (i >=pMultiComment(j).iBeginPos)) then				
								
								' сохраним цвет для символа комментария
								pBytes[i] = iDimConsoleColors(pObj.iColorComments)
								
								' активируем флаг , что мы подсвечиваем комментарий
								bFlagMkEnable = 1
								
								' выходим из цикла
								exit for
								
							EndIf
							
						EndIf
						
					endif
					
				Next
				
			endif
			
			' если мы подсветили комментарий
			if bFlagMkEnable then
				
				' обнулим флаг
				bFlagMkEnable = 0
				
				' на начало цикла
				continue for
				
			else ' если это не комментарий
				
				' ставим цвет текста по умолчанию
				pBytes[i] = iDimConsoleColors(pObj.iColorText)
				
			EndIf
			
			select case (*psz)[i]
					
				Case 48 to 57 , 65 to 90 , 35 , 95 , 97 to 122 ' числа , буквы , _ #
					
					' если начало нового слова , нет кавычек , нет комментариев
					if iBeginWord = -1 andalso bFlagQuote = 0 andalso bFlagSingleK = 0 then
						
						iBeginWord = i ' сохраним индекс начала слова
						
					EndIf
					
					if i = iLenPszMinusOneSymbol then ' если дошли до конца строки
						
						' если не подсвечиваются кавычки , комментарии и потенциально в ключевом слове что-то есть
						if bFlagQuote = 0 andalso bFlagSingleK = 0 andalso iBeginWord <> -1 then
							
							' получим слово
							dim as string sTemp = mid(*psz , iBeginWord+1)
							
							sTemp = lcase(sTemp) ' слово в нижний регистр
							
							' если длина слова не нулевая
							if len(sTemp) > 1 then
								
								' цикл по кол-ву ключевых слов 
								for j as Long = 0 to Ubound(szKeyWords)
									
									' если совпало с ключевым словом
									if sTemp[0] = (szKeyWords(j))[0] andalso sTemp = szKeyWords(j) then
										
										' цикл по кол-ву символов в слове
										for j as Long = iBeginWord to i
											
											' сохраним цвет для ключевого слова
											pBytes[j] = iDimConsoleColors(pObj.iColorKeyWords)
											
										Next
										
										' выходим из цикла , так как слово найдено
										exit for
										
									EndIf
									
								Next
								
							endif
							
						EndIf
						
					EndIf
					
				case 34 ' если кавычка
					
					if bFlagSingleK = 0 then ' если она не в комментарии
						
						if bFlagQuote = 0 then ' если это не завершающая кавычка
							
							bFlagQuote = 1 ' ставим флаг , что текщая кавычка и следующие символы в кавычках
							
						else ' это завершающая кавычка
							
							' сохраним цвет для кавычки
							pBytes[i] = iDimConsoleColors(pObj.iColorStrings)
							
							' обнуляем флаг
							bFlagQuote = 0
							
						endif
						
					EndIf
					
				case 39  ' если однострочный комментарий
					
					' если нет кавычек и комментарий еще не установлен
					if bFlagQuote = 0 then
						
						bFlagSingleK = 1 ' ставим флаг начала комментария 
						
					endif
					
				case else ' все остальные символы
					
					' если не подсвечиваются кавычки , комментарии и потенциально в ключевом слове что-то есть
					if bFlagQuote = 0 andalso bFlagSingleK = 0 andalso iBeginWord <> -1 then
						
						' получим слово
						dim as string sTemp = mid(*psz , iBeginWord+1 , i-iBeginWord)
						
						sTemp = lcase(sTemp) ' слово в нижний регистр
						
						' если длина слова не нулевая
						if len(sTemp) > 1 then
							
							' цикл по кол-ву ключевых слов 
							for j as Long = 0 to Ubound(szKeyWords)
								
								' если совпало с ключевым словом
								if sTemp[0] = (szKeyWords(j))[0] andalso sTemp = szKeyWords(j) then
									
									' цикл по кол-ву символов в слове
									for j as Long = iBeginWord to i-1
										
										' сохраним цвет для ключевого слова
										pBytes[j] = iDimConsoleColors(pObj.iColorKeyWords)
										
									Next
									
									' выходим из цикла , так как слово найдено
									exit for
									
								EndIf
								
							Next
							
						endif
						
						' установим , что слово еще не наполнено из символов
						iBeginWord = -1
						
					EndIf
					
			End Select
			
			if bFlagQuote then ' если флаг установки кавычек установлен
				
				' сохраним цвет для символа как строку
				pBytes[i] = iDimConsoleColors(pObj.iColorStrings)
				
			elseif bFlagSingleK then ' если флаг установки комментариев установлен
				
				' сохраним цвет для символа как комментарий
				pBytes[i] = iDimConsoleColors(pObj.iColorComments)
				
			EndIf
			
		Next
		
		' получим цвет первого символа
		dim as Byte bCurent = pBytes[0]
		
		' запишем в буфер первый символ с подсветкой
		dim as string sTemp = !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & bCurent & "m"
		
		' цикл по всем символам
		for i as Long = 0 to iLenPsz-1
			
			' если предыдущий и текущий цвета символов не сопадают
			if bCurent <> pBytes[i] then
				
				' сохраним текущий цвет
				bCurent = pBytes[i]
				
				' запишем в буфер новый цвет
				sTemp &= !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & ";" & bCurent & "m"
				
			EndIf
			
			' будем записывать символы в буфер только с определенного символа
			if iColorPrevSymbol <= i then
				
				sTemp &= chr((*psz)[i])
				
			endif
			
		Next
		
		sBufLinux &= sTemp & !"\27[" & iDimConsoleColors(pObj.iColorBackGround)+10 & "m" ' запишем в общий буфер
		
		deallocate(pBytes) ' освободим память для массива цветов
		
	End sub
	
	' процедура для посветки на линуксе
	sub execute_highlight(pwsFull as wstring ptr  , psz as zstring ptr , iRowNumber as Long , sBufLinux as string)
		
		dim as long iColorPrevSymbol ' символ с которого начнется записывание буфера с подсветкой
		
		if pObj.iScrollWidth > 1 then ' если был скроллинг
			
			dim as Long iCountSymbols ' кол-во символов с двумя знакоместами
			
			' определим в цикле сколько символов с двумя знакоместами
			for i as Long  = 0 to pObj.iScrollWidth - 2
				
				if GetWidthSymbol((*pwsFull)[i]) = 2 then
					
					iCountSymbols +=1
					
				EndIf
				
			Next
			
			' получим строку вместе со спрятанными символами за скроллингом
			dim as string sFull = mid(*pwsFull , 1 , pObj.iScrollWidth - 1 - iCountSymbols) & *psz
			
			' получим символ с которого реально начнется подсвечиваемая строка 
			iColorPrevSymbol = len(sFull)-len(*psz)
			
			' переходим на подсветку
			execute_highlight2(strptr(sFull) , iRowNumber-1 , sBufLinux , iColorPrevSymbol)
			
		else ' скроллинга не было , строку отправим как есть
			
			' переходим на подсветку
			execute_highlight2(psz , iRowNumber-1 , sBufLinux , iColorPrevSymbol)
			
		EndIf
		
	End sub
	
#else
	
	sub execute_highlight2(pws as Wstring ptr , iRowNumber as Long , iColorPrevSymbol as long = 0 , pColors as short ptr , iIndexColors as Long)
		
		dim as long iBeginWord = -1 ' начало потенциально выделяемого слова
		
		dim as Byte bFlagQuote , bFlagSingleK , bFlagMkEnable ' флаги для кавычек,однострочного и многострочного комментария
		
		if pws = 0 then exit sub ' если указатель не валидный , выходим из процедуры
		
		Dim as Long iLenPws = len(*pws) ' длина строки
		
		' смещение для массива pColors
		dim as Long iVirt = iIndexColors
		
		' цикл по числу символов/байт
		for i as long  = 0 to iLenPws-1
			
			dim as Long iColorCurent = pObj.iColorText ' цвет по умолчанию (цвет текста)
			
			if iCountMultiComments then ' если в тексте есть многострочные комментарии
				
				' цикл по кол-ву многострочных комментариев
				for j as long = 0 to iCountMultiComments-1
					
					if pMultiComment(j).iBeginRow <> -1 then ' если что-то заполнено
						
						' если текущая строка находится в рамках данных массива комментариев
						if iRowNumber >= pMultiComment(j).iBeginRow andalso iRowNumber <= pMultiComment(j).iEndRow then
							
							' если один из случаев совпадает
							'1) если комментарий умещается на одной строке
							' остальные ниже случаи для многострочных комментариев
							'2) если комментарий на последней строке
							'3) если комментарий на строке , которая между первой и последней строкой
							'4) если комментарий на первой строке
							if (pMultiComment(j).iBeginRow = pMultiComment(j).iEndRow andalso i >=pMultiComment(j).iBeginPos andalso i <=pMultiComment(j).iEndPos) orelse _
							(pMultiComment(j).iBeginRow <> pMultiComment(j).iEndRow) andalso (iRowNumber = pMultiComment(j).iEndRow andalso i <=pMultiComment(j).iEndPos) orelse _
							((iRowNumber < pMultiComment(j).iEndRow) andalso (iRowNumber > pMultiComment(j).iBeginRow)) orelse _
							((pMultiComment(j).iBeginRow <> pMultiComment(j).iEndRow) andalso (iRowNumber = pMultiComment(j).iBeginRow) andalso (i >=pMultiComment(j).iBeginPos)) then				
								
								' сохраним цвет для символа комментария
								iColorCurent = pObj.iColorComments
								
								' активируем флаг , что мы подсвечиваем комментарий
								bFlagMkEnable = 1
								
								' сбрасываем другие флаги
								bFlagQuote = 0
								bFlagSingleK = 0
								
								if iBeginWord <> -1 then ' если слово для подсветки было набрано
									
									' цикл по кол-ву символов в слове
									for iIndex as Long = iBeginWord to i-1
										
										' будем записывать символы в буфер только с определенного символа
										if iColorPrevSymbol <= iIndex then
											
											if GetWidthSymbol((*pws)[iIndex]) = 1 then
												
												pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
												
												iVirt+=1 ' увеличим смещение
												
											else
												
												pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
												
												pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
												
												iVirt+=2 ' увеличим смещение
												
											endif
											
										endif
										
									Next
									
									iBeginWord = -1 ' установим , что слово еще не наполнено из символов
									
								EndIf
								
								' будем записывать символы в буфер только с определенного символа
								if iColorPrevSymbol <= i then
									
									if GetWidthSymbol((*pws)[i]) = 1 then
										
										pColors[iVirt] = (pObj.iColorBackGround shl 4) or iColorCurent ' цвет комментариев
										
										iVirt+=1 ' увеличим смещение
										
									else
										
										pColors[iVirt] = (pObj.iColorBackGround shl 4) or iColorCurent ' цвет комментариев
										
										pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or iColorCurent ' цвет комментариев
										
										iVirt+=2 ' увеличим смещение
										
									endif
									
								endif
								
							EndIf
							
							' выходим из цикла
							exit for
							
						EndIf
						
					endif
					
				Next
				
				' если мы подсветили комментарий
				if bFlagMkEnable then
					
					' обнулим флаг
					bFlagMkEnable = 0
					
					' на начало цикла
					continue for
					
				EndIf
				
			endif
			
			select case (*pws)[i]
					
				Case 48 to 57 , 65 to 90 , 35 , 95 , 97 to 122 ' числа , буквы , _ #
					
					' если начало нового слова , нет кавычек , нет комментариев
					if iBeginWord = -1 andalso bFlagQuote = 0 andalso bFlagSingleK = 0 then
						
						iBeginWord = i ' сохраним индекс начала слова
						
					EndIf
					
				case 34 ' если кавычка
					
					if bFlagSingleK = 0 then ' если она не в комментарии
						
						if bFlagQuote = 0 then ' если это не завершающая кавычка
							
							bFlagQuote = 1 ' ставим флаг , что текщая кавычка и следующие символы в кавычках
							
						else ' это завершающая кавычка
							
							' сохраним цвет для кавычки
							iColorCurent = pObj.iColorStrings
							
							' обнуляем флаг
							bFlagQuote = 0
							
						endif
						
					EndIf
					
				case 39  ' если однострочный комментарий
					
					' если нет кавычек и комментарий еще не установлен
					if bFlagQuote = 0 then
						
						bFlagSingleK = 1 ' ставим флаг начала комментария 
						
					endif
					
				case else ' все остальные символы
					
					' если не подсвечиваются кавычки , комментарии и потенциально в ключевом слове что-то есть
					if bFlagQuote = 0 andalso bFlagSingleK = 0 andalso iBeginWord <> -1 then
						
						dim as Byte bFindedFlag ' флаг , если слово для подсветки будет найдено
						
						' получим слово
						dim as string sTemp = lcase(mid(*pws , iBeginWord+1 , i-iBeginWord))
						
						' если длина слова не нулевая
						if len(sTemp) > 1 then
							
							' цикл по кол-ву ключевых слов
							for j as Long = 0 to Ubound(szKeyWords)
								
								' если совпало с ключевым словом
								if sTemp[0] = (szKeyWords(j))[0] andalso sTemp = szKeyWords(j) then
									
									bFindedFlag = 1 ' активируем флаг , что слово будет подсвечено
									
									' цикл по кол-ву символов в слове
									for iIndex as Long = iBeginWord to i-1
										
										' будем записывать символы в буфер только с определенного символа
										if iColorPrevSymbol <= iIndex then
											
											if GetWidthSymbol((*pws)[iIndex]) = 1 then
												
												pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorKeyWords ' цвет подсветки
												
												iVirt+=1 ' увеличим смещение
												
											else
												
												pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorKeyWords ' цвет подсветки
												
												pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or pObj.iColorKeyWords ' цвет подсветки
												
												iVirt+=2 ' увеличим смещение
												
											endif
											
										endif
										
									Next
									
									' выходим из цикла , так как слово найдено
									exit for
									
								EndIf
								
							Next
							
						endif
						
						' если слово не было подсвечено
						if bFindedFlag = 0 andalso len(sTemp) then
							
							' цикл по кол-ву символов в слове
							for iIndex as Long = iBeginWord to i-1
								
								' будем записывать символы в буфер только с определенного символа
								if iColorPrevSymbol <= iIndex then
									
									if GetWidthSymbol((*pws)[iIndex]) = 1 then
										
										pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
										
										iVirt+=1 ' увеличим смещение
										
									else
										
										pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
										
										pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
										
										iVirt+=2 ' увеличим смещение
										
									endif
									
								endif
								
							Next
							
						endif
						
						' установим , что слово еще не наполнено из символов
						iBeginWord = -1
						
					EndIf
					
			End Select
			
			if bFlagQuote then ' если флаг установки кавычек установлен
				
				' сохраним цвет для символа как строку
				iColorCurent = pObj.iColorStrings
				
			elseif bFlagSingleK then ' если флаг установки комментариев установлен
				
				' сохраним цвет для символа как комментарий
				iColorCurent = pObj.iColorComments
				
			EndIf
			
			' будем записывать символы в буфер только с определенного символа
			if iColorPrevSymbol <= i then
				
				if iBeginWord = -1 then ' если слово для подсветки не набрано
					
					if GetWidthSymbol((*pws)[i]) = 1 then ' если символ с одним знакоместом
						
						pColors[iVirt] = (pObj.iColorBackGround shl 4) or iColorCurent ' запишем сохраненный цвет
						
						iVirt+=1 ' увеличим смещение
						
					else
						
						pColors[iVirt] = (pObj.iColorBackGround shl 4) or iColorCurent ' запишем сохраненный цвет
						
						pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or iColorCurent ' запишем сохраненный цвет
						
						iVirt+=2 ' увеличим смещение
						
					endif
					
					' если слово для подсветки набрано , но конец экрана
					' подсвечивать его не будем , потому что это может быть только часть слова
				elseif i = iLenPws-1 andalso iBeginWord <> -1 then
					
					' получим слово
					dim as string sTemp = lcase(mid(*pws , iBeginWord+1 , i-iBeginWord+1))
					
					' если длина слова не нулевая
					if len(sTemp) then
						
						' цикл по кол-ву символов в слове
						for iIndex as Long = iBeginWord to i
							
							' будем записывать символы в буфер только с определенного символа
							if iColorPrevSymbol <= iIndex then
								
								if GetWidthSymbol((*pws)[iIndex]) = 1 then ' если символ с одним знакоместом
									
									pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
									
									iVirt+=1 ' увеличим смещение
									
								else
									
									pColors[iVirt] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
									
									pColors[iVirt+1] = (pObj.iColorBackGround shl 4) or pObj.iColorText ' цвет будет как цвет обычного текста
									
									iVirt+=2 ' увеличим смещение
									
								endif
								
							endif
							
						Next                            
						
					endif
					
				endif
				
			endif
			
		Next
		
	End sub
	
	' процедура для посветки
	sub execute_highlight(pwsFull as wstring ptr  , pws as Wstring ptr , iRowNumber as Long , pColors as short ptr , iIndexColors as Long)
		
		dim as long iColorPrevSymbol ' символ с которого начнется записывание буфера с подсветкой
		
		if pObj.iScrollWidth > 1 then ' если был скроллинг
			
			dim as Long iLenPws = len(*pws)
			
			dim as Long iCountSymbols ' кол-во символов с двумя знакоместами
			
			' определим в цикле сколько символов с двумя знакоместами
			for i as Long  = 0 to pObj.iScrollWidth - 2
				
				if GetWidthSymbol((*pwsFull)[i]) = 2 then
					
					iCountSymbols +=1
					
				EndIf
				
			Next
			
			dim as wstring ptr pTemp = callocate((pObj.iScrollWidth-iCountSymbols+iLenPws) *sizeof(wstring))
			
			if pTemp then
				
				' получим строку вместе со спрятанными символами за скроллингом
				*pTemp = mid(*pwsFull , 1 , pObj.iScrollWidth - 1 - iCountSymbols) & *pws
				
				' получим символ с которого реально начнется подсвечиваемая строка 
				iColorPrevSymbol = len(*pTemp)-iLenPws
				
				' переходим на подсветку
				execute_highlight2(pTemp , iRowNumber-1 , iColorPrevSymbol, pColors , iIndexColors)
				
				deallocate(pTemp)
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		else ' скроллинга не было , строку отправим как есть
			
			' переходим на подсветку
			execute_highlight2(pws , iRowNumber-1 , iColorPrevSymbol, pColors , iIndexColors)
			
		EndIf
		
	End sub
	
#endif

' установка флагов отрисовки для строк
sub SetDrawsRowsFlags(iRow1 as Long , iRow2 as Long)
	
	#ifdef __FB_WIN32__
		Redim as byte bReDrawRows(pObj.iHeightRows-1) ' пересоздадим массив
		if iRow1 = -1 then ' если 1 параметр -1
			for i as Long = 0 to pObj.iHeightRows-2
				bReDrawRows(i) = 1 ' все строки для отрисовки
			next
		elseif iRow2 = -1 then ' если 2 параметр -1 , то ничего не рисуем
		else
			' 2 строки, заданные в параметре рисуем
			bReDrawRows(iRow1) = 1
			bReDrawRows(iRow2) = 1
		endif
	#EndIf
	
End Sub

