[IDE tool] alignment of comments

Working on new editor enhancements?
AZJIO
Addict
Addict
Posts: 2154
Joined: Sun May 14, 2017 1:48 am

[IDE tool] alignment of comments

Post by AZJIO »

Download
Image
The source text is indented incorrectly.

Code: Select all

			; 			Debug Text$
;- GUI
			;- GUI
; 			Debug Text$
Comments after alignment

Code: Select all

; AZJIO
; https://www.purebasic.fr/english/viewtopic.php?t=83781

EnableExplicit

; AZJIO (вариант из AutoIt3, а по ссылке есть упрощённые варианты)
; https://www.purebasic.fr/english/viewtopic.php?t=80994
Procedure.s TmpFile(DirName$ = "", Prefix$ = "~", Ext$ = ".tmp", RandomLength = 7)
	Protected TmpName$

	If RandomLength < 4 Or RandomLength > 130
		RandomLength = 7
	EndIf
	If Not Asc(DirName$) Or FileSize(DirName$) = -1
		DirName$ = GetTemporaryDirectory()
	EndIf

	If Not CheckFilename(Prefix$)
		Prefix$ = "~"
	EndIf
	If Not CheckFilename(Ext$)
		Ext$ = ".tmp"
	EndIf

	If Right(DirName$, 1) <> #PS$
		DirName$ + #PS$
	EndIf
	If Asc(Ext$) And Left(Ext$, 1) <> "."
		Ext$ = "." + Ext$
	EndIf

	Repeat
		TmpName$ = ""
		While Len(TmpName$) < RandomLength
			TmpName$ + Chr(Random(122, 97))
		Wend
		TmpName$ = DirName$ + Prefix$ + TmpName$ + Ext$
	Until FileSize(TmpName$) = -1

	ProcedureReturn TmpName$
EndProcedure


; https://www.purebasic.fr/english/viewtopic.php?t=79183
Procedure.s RTrimChar(String$, TrimChar$ = #CRLF$ + #TAB$ + #FF$ + #VT$ + " ")
	Protected Len2, Blen, i
	Protected *jc0, *c.Character, *jc.Character

	Len2 = Len(String$)
	Blen = StringByteLength(String$)

	If Not Asc(String$)
		ProcedureReturn ""
	EndIf

	*c   = @String$ + Blen - SizeOf(Character)
	*jc0 = @TrimChar$

	For i = Len2 To 1 Step - 1
		*jc = *jc0

		While *jc\c
			If *c\c = *jc\c
				*c\c = 0
				Break
			EndIf
			*jc + SizeOf(Character)
		Wend

		If *c\c
			Break
		EndIf
		*c - SizeOf(Character)
	Next

	ProcedureReturn String$
EndProcedure


; https://www.purebasic.fr/english/viewtopic.php?t=79183
Procedure.s LTrimChar(String$, TrimChar$ = #CRLF$ + #TAB$ + #FF$ + #VT$ + " ")
	Protected *jc0, *c.Character, *jc.Character

	If Not Asc(String$)
		ProcedureReturn ""
	EndIf

	*c   = @String$
	*jc0 = @TrimChar$

	While *c\c
		*jc = *jc0

		While *jc\c
			If *c\c = *jc\c
				*c\c = 0
				Break
			EndIf
			*jc + SizeOf(Character)
		Wend

		If *c\c
			String$ = PeekS(*c)
			Break
		EndIf
		*c + SizeOf(Character)
	Wend

	ProcedureReturn String$
EndProcedure


Procedure GetString(InputFile$, OutputFile$)
	Protected flgOpnQt, c, tilda, flgSpace, flgStart, tmp$
	Protected id_file, id_file2, Format, Text$, *c.Character, *c0.Character
	; MessageRequester("", InputFile$))

	id_file = ReadFile(#PB_Any, InputFile$)
	If Not IsFile(id_file)
		MessageRequester("Error", "Error opening source file" + #CRLF$ + #CRLF$ + InputFile$)
		ProcedureReturn
	EndIf

	id_file2 = CreateFile(#PB_Any, OutputFile$)
	If Not IsFile(id_file2)
		CloseFile(id_file)
		MessageRequester("Error", "Error creating file" + #CRLF$ + #CRLF$ + OutputFile$)
		ProcedureReturn
	EndIf

	If id_file And id_file2
		Format = ReadStringFormat(id_file)
		WriteStringFormat(id_file2, #PB_UTF8)
		While Not Eof(id_file)
			Text$ = ReadString(id_file, Format) ; читаем построчно, так легче анализировать
			Text$ = RTrimChar(Text$, #TAB$ + " ") ; убираем табы и пробелы в конце строки
			; Debug Text$
			*c       = @Text$
			flgStart = 1
			flgSpace = 0
			flgOpnQt = 0 ; сбросили флаг
			While *c\c
				Select *c\c
					Case '!' ; если ASM код, то тупо пропускаем эту строку
						If flgOpnQt = 0 ; если кавычка не открыта, то
							Break
						EndIf
						
					Case 39 ; ' ' апостроф
						If flgOpnQt = 0 ; если кавычка не открыта, то
							*c + SizeOf(Character)
							If *c\c = 0 : Break : EndIf
							If *c\c = 39
								*c + SizeOf(Character)
								Continue
							EndIf
							Repeat
								*c + SizeOf(Character)
							Until *c\c = 0 Or *c\c = 39 ; идём до конца строки или до заканчивающегося апострофа
							If *c\c = 0 : Break : EndIf ; выпрыг, если конец строки или апостроф в ненадлежащем месте.
						EndIf
						
					Case '"' ; кавычка
						If tilda
							Select tilda
								Case 1, 3
									tilda = 2
									*c + SizeOf(Character)
									Continue
								Case 2
									; пришли к завершающей кавычке и срабатывает ниже условие flgOpnQt, так как нет Continue по тексту
									tilda = 0
							EndSelect
						EndIf

						If flgOpnQt
							; Попалась последняя кавычка, закрывающаяывающая
							flgOpnQt = 0
						Else
							; Попалась первая кавычка, открывающаяывающая
							flgOpnQt = 1
						EndIf
					Case '\'
						; этот механизм чисто для проверки экранированных кавычек после тильдытильды
						; двойная проверка флагов изменяет поведение при дублировании кавычкиавычки
						Select tilda
							Case 2
								tilda = 3
							Case 3
								tilda = 2
						EndSelect
					Case ';'

						If flgStart ; начало строки
							flgStart = 0
							*c0      = *c
							; *c\c = ' '
							*c + SizeOf(Character)
							flgSpace + 1
							While *c\c
								If *c\c = ' ' Or *c\c = #TAB
									flgSpace + 1
								Else
									; как только пошёл текст, то переставляеместавляем
									If flgSpace = < 3
										Break 2 ; ничего не делаем, комментарий начался нормально "; "
									EndIf
									*c0\c = #TAB
									*c0 + SizeOf(Character)
									*c0\c = #TAB
									*c - SizeOf(Character)
									*c\c = ' '
									*c - SizeOf(Character)
									*c\c = ';'
									Break 2
								EndIf
								*c + SizeOf(Character)
							Wend
						Else
							If flgOpnQt = 0 ; если нет открытой кавычки, значит пошли комментарии до конца строки
								*c + SizeOf(Character)
								While *c\c
									Select *c\c
										Case ' '
											If flgSpace = 0
												flgSpace + 1
											ElseIf flgSpace = 1
												*c0 = *c
												flgSpace = 1
											ElseIf flgSpace = -1
												*c0\c = *c\c
											EndIf
										Case #TAB
											If flgSpace = 0
												flgSpace + 1
												*c\c = ' '
											ElseIf flgSpace = 1
												*c0 = *c
												flgSpace = 2
											ElseIf flgSpace = -1
												*c0\c = *c\c
											EndIf
										Default
											If flgSpace = 0 And *c\c = '-'
												tmp$ = LTrimChar(Text$, #TAB$ + " ")
												If Asc(tmp$) = ';'
													Text$ = tmp$
													Break 2
												EndIf
											EndIf
											If flgSpace = 0 Or flgSpace = 1
												Break 2 ; ничего не делаем, комментарий начался нормально
											EndIf
											flgSpace = -1
											*c0\c = *c\c
									EndSelect
									If flgSpace = -1
										*c0 + SizeOf(Character)
									EndIf
									*c + SizeOf(Character)
								Wend
								If flgSpace = -1
									*c0\c = 0 ; если перезаписывали комментарий сдвигая к началу, то надо завершить его нулём
								EndIf
								Break
							EndIf
						EndIf
					Case '~'
						If flgOpnQt = 0 ; если комментарий не открыт, то начинаем считать что открылись тильда-данные
							*c + SizeOf(Character)
							If *c\c = '"'
								flgOpnQt = 1 ; режим открытия кавычки, начинаем ждать закрывающую (кроме начальной и экранированных)
								tilda = 1	 ; включаем флаг запуска тильды
							EndIf
							*c - SizeOf(Character)
						EndIf
				EndSelect
				*c + SizeOf(Character)
				flgStart = 0
			Wend
			WriteStringN(id_file2, Text$)
		Wend
		CloseFile(id_file)
		CloseFile(id_file2)
	EndIf

EndProcedure

Global Start, InputFile$, OutputFile$, Rewrite, NotSuccess


; 	Добавляем параметоры ком строки чтобы использовать как инструмент
If CountProgramParameters()
	InputFile$ = ProgramParameter(0)
	If Not (Asc(InputFile$) And FileSize(InputFile$) > 3 And Left(GetExtensionPart(InputFile$), 2) = "pb")
		InputFile$ = ""
	EndIf
EndIf

If Not Asc(InputFile$)
	InputFile$ = OpenFileRequester("Select PB File", "", "*.pb*|*.pb*|All Files|*.*", 0)
EndIf

If Asc(InputFile$)
	If MessageRequester("Overwrite?", "Overwrite current file? (otherwise to a file with _alingComm suffix)",
	                    #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
		OutputFile$ = TmpFile()
		Rewrite     = 1
	Else
		Start       = 1
		OutputFile$ = GetPathPart(InputFile$) + GetFilePart(InputFile$, #PB_FileSystem_NoExtension) + "_alingComm." + GetExtensionPart(InputFile$)
	EndIf

	GetString(InputFile$, OutputFile$)

	If Start
		RunProgram(OutputFile$)
	Else
		If DeleteFile(InputFile$)
			If Not RenameFile(OutputFile$, InputFile$)
				NotSuccess = 1
			EndIf
		EndIf
		If NotSuccess
			MessageRequester("", "Failed to update file")
		EndIf
	EndIf
EndIf
[code]