ambiente de depuração LUA (a)


QQ: 282397369

devido

Este ano, eu lançar o script e encontrou LUA pode realmente resolver um grande problema e, juntamente com C ++, sem costura sensação, lidar com uma variedade de negócios muito mais fácil.
Com mais lentamente encontrados alguns infelizes. O maior problema é que o script não faz processo de compilação, todos os problemas têm que esperar até que tempo de execução para ser mostrado, resultando processo de depuração script é relativamente ineficiente.
Em seguida, fazer uma IDE, dar o seu próprio uso.

edição básica

IDE primeiro tem um editor. O uso direto de open source Scintilla pode ser. mecanismo de mensagens combinado, é bastante fácil. O trabalho principal é copiada, ou é cópia, em linha Soso lá. Aqui estão alguns conteúdos breve

LUA determinação

		SendEditor(SCI_SETLEXER, SCLEX_LUA);
		SendEditor(SCI_STYLESETFONT, SCE_LUA_IDENTIFIER, (sptr_t)"Courier New");
		SendEditor(SCI_STYLESETSIZE, SCE_LUA_IDENTIFIER, fontSize);

		SendEditor(SCI_STYLESETFONT, SCE_LUA_COMMENTLINE, (sptr_t)"Courier New");
		SendEditor(SCI_STYLESETSIZE, SCE_LUA_COMMENTLINE, fontSize);
		SendEditor(SCI_STYLESETFONT, SCE_LUA_WORD, (sptr_t)"Courier New");
		SendEditor(SCI_STYLESETSIZE, SCE_LUA_WORD, fontSize);
		SendEditor(SCI_STYLESETFONT, SCE_LUA_LITERALSTRING, (sptr_t)"Courier New");
		SendEditor(SCI_STYLESETSIZE, SCE_LUA_LITERALSTRING, fontSize);
		SendEditor(SCI_STYLESETFONT, SCE_LUA_COMMENTDOC, (sptr_t)"Courier New");
		SendEditor(SCI_STYLESETSIZE, SCE_LUA_COMMENTDOC, fontSize);

		SendEditor(SCI_STYLESETITALIC, SCE_LUA_COMMENTLINE, true);  
		SendEditor(SCI_STYLESETITALIC, SCE_LUA_LITERALSTRING, true); 
		SendEditor(SCI_STYLESETITALIC, SCE_LUA_IDENTIFIER, true); 
		SendEditor(SCI_STYLESETITALIC, SCE_LUA_COMMENTDOC, true); 

		SendEditor(SCI_STYLESETBOLD, SCE_LUA_IDENTIFIER, TRUE); 
		SendEditor(SCI_STYLESETBOLD, SCE_LUA_WORD, TRUE); 

		SendEditor(SCI_STYLESETFORE, SCI_SETCODEPAGE, CP_UTF8);

		SendEditor(SCI_SETKEYWORDS, 0, (sptr_t)"and break do else elseif end false for function if in local nil not or repeat return then true until while");

		SendEditor(SCI_STYLESETFORE, SCE_LUA_COMMENTLINE, clGreen);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_COMMENTDOC, clGreen);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_NUMBER, clBlue);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_CHARACTER, clRed);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_OPERATOR, clGreen);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_LITERALSTRING, clGreen);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_IDENTIFIER, clPurple);
		SendEditor(SCI_STYLESETFORE, SCE_LUA_WORD, clBlue);

		SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);
		SendEditor(SCI_SETTABWIDTH, 4); // TAB宽度由默认的8改为4
		SendEditor(SCI_SETCARETLINEBACK, RGB(226, 217, 232));
		SendEditor(SCI_SETSELBACK, true, RGB(0x9f,0xbb,0xe8) );

dobramento de código

dobrável código agora programado é uma obrigação, com os números de linha exibida torna-se um padrão simples

	SendEditor(SCI_SETMARGINTYPEN, 0, SC_MARGIN_NUMBER);
	SendEditor(SCI_SETMARGINWIDTHN, 0, 40);
	SendEditor(SCI_SETMARGINSENSITIVEN, 0, TRUE); //响应鼠标消息
	SendEditor(SCI_SETPROPERTY,(sptr_t)"fold",(sptr_t)"1");
	SendEditor(SCI_SETPROPERTY,(sptr_t)"fold.compact",(sptr_t)"0");  // 这个一定要关掉!!!否则折叠样式会有问题!!!

	SCN_UPDATEUI;
	SendEditor(SCI_SETMARGINTYPEN, 		MARGIN_FOLD_INDEX, SC_MARGIN_SYMBOL);	
	SendEditor(SCI_SETMARGINMASKN, 		MARGIN_FOLD_INDEX, SC_MASK_FOLDERS); 	
	SendEditor(SCI_SETMARGINWIDTHN, 	MARGIN_FOLD_INDEX, 11); 			 
    SendEditor(SCI_SETMARGINSENSITIVEN, MARGIN_FOLD_INDEX, TRUE); 

    SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEROPEN, (sptr_t)minus_xpm);
	SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEREND, (sptr_t)plus_xpm);
	SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEROPENMID, (sptr_t)minus_xpm);

	SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE);
	SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
	SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE);

    SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERSUB, 0xa0a0a0);
    SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERMIDTAIL, 0xa0a0a0);
	SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERTAIL, 0xa0a0a0);

	SendEditor(SCI_SETFOLDFLAGS, 16|4, 0);

efeito ilustração simples

Com base no exposto, você quase pode ver os efeitos.
Aqui Insert Picture Descrição
Isso tem algum fundamento.

Pontos de interrupção

funções de quebra jogando a maior parte do dia, com Margem como os resultados do teste não ter saído. Estamos prontos para desistir.
Acabou por abandonar o uso da margem de conseguir, e por isso têm tempo, então Margem
mas a funcionalidade ainda é procurado. Em seguida, vestiu-se. A PaintBox colocado diretamente no editor do lado esquerdo, um pouco para tentar, realmente tem o efeito de

	FPaintBox_Assert = new TPaintBox(this);
	FPaintBox_Assert->Parent = this;
	FPaintBox_Assert->Width = 15;
	FPaintBox_Assert->Align = alLeft;
	FPaintBox_Assert->OnPaint = OnPaintBox_Assert;
	FPaintBox_Assert->OnMouseUp = OnPaintBox_MouseUp;

Em seguida, adicione o processamento de eventos correspondente, de fato, é desenhada com o interruptor.

Obtém o número da linha

analisar cuidadosamente os documentos, você pode obter o número da linha atual, mas eu quero são exibidas na parte superior da tela e na parte inferior do número da linha, tentou muitos métodos e mensagens, sem sucesso.
Então, reconhecimento de caracteres ele. Afinal, OpenCV também teve um tempo tão longo. O reconhecimento de caracteres deve ser o mais simples, impressão padrão, padrão digital, fazê-lo funcionar envergonhado.

TStrings * __fastcall TCbwSynEditor::GetLineNumbers() {
	cv::Mat mat = CvHelper::MatFromHWND(hEditor, TRect(0, 0, 40, FPaintBox_Assert->Height - 25));
	CbwXmlNode * result = new CbwXmlNode("number");
	GlobalQuickOcr->OcrNumber(mat, L"Scintilla", true);
	result->Assign(GlobalQuickOcr->OcrPositionNode);
	TStrings * lines = new TStringList;
	for(int i = 0; i < result->ElementNumber; ++i) {
		UnicodeString text = result->Elements(i)->AttributeValueByName(L"text");
		UnicodeString id = THelper::String::GetRegMatchAt(text, L"\\d+");
		if(id.Length())
			lines->Add(id.ToInt());
	}
	delete result;
	return lines;
}

Toggle Breakpoint

O principal evento em PaintBox clique processo, com o seu evento MouseUp direto.

void __fastcall TCbwSynEditor::OnPaintBox_MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
	int textHeight = GetTextHeight();
	int row = Y / textHeight;
	TStrings * lines = GetLineNumbers();
	if(IS_IN_RANGE(row, 0, lines->Count - 2)) {
		int destLine = lines->Strings[row].ToInt();
		int nextLine = lines->Strings[row + 1].ToInt();
		if(nextLine == destLine + 1) {
			ToggleBreakpoint(destLine);
			FPaintBox_Assert->Repaint();
		}
		else
			SendEditor(SCI_TOGGLEFOLD, destLine, 0);
	}
	delete lines;
}

Qual a altura do texto GetTextHeight é alcançado, o sentimento no momento da edição, deve ser consistente. Primeiro tentou fazê-lo, não sei é correto, mas eu era o suficiente para o.

int __fastcall TCbwSynEditor::GetTextHeight() {
	int result = SendEditor(SCI_TEXTHEIGHT, 1);
	return result;
}

Para compatibilidade com projectos de acompanhamento, ou seja, multi-arquivo, uma estrutura de design simples:

typedef struct tagBreakPoints {
	UnicodeString fileName;
	vector<int> lineNumbers;
} TBreakPoints;

Agora que a operação de comutação é principalmente o processo de atualização para memória de dados

void __fastcall TCbwSynEditor::ToggleBreakpoint(int lineNumber) {
	TBreakPoints * destItems = NULL;
	CBW_ITERATOR(vector<TBreakPoints *>, FBreakpoints) {
		if((*it)->fileName == FFileName)
			destItems = *it;
	}
	if(!destItems) {
		destItems = new TBreakPoints;
		destItems->fileName = FFileName;
		FBreakpoints.push_back(destItems);
	}

	int index = -1;
	CBW_ITERATOR(vector<int>, destItems->lineNumbers) {
		if(*it == lineNumber) {
			index = it - destItems->lineNumbers.begin();
			break;
		}
	}
	if(index == -1)
		destItems->lineNumbers.push_back(lineNumber);
	else
		destItems->lineNumbers.erase(destItems->lineNumbers.begin() + index);
	THelper::Debug::AddLog(THelper::FormatString(L"切换第 %d 行 -> %s",
		lineNumber, GetBreakpointHint()), clBlue);
}

pedaço pontos de interrupção na esquerda mostra.

exibição breakpoints

Não procure aparência profissional, para resolver quaisquer problemas.
Quando exibido, tendo em conta a dobradura do código, ele precisa oferecer um pequeno-se, se a quebra de linha é exibido, use o ponto vermelho, se a quebra de linha é dobrado, em seguida, um ponto escuro.

void __fastcall TCbwSynEditor::OnPaintBox_Assert(TObject* Sender) {
	THelper::Graphics::FillCanvas(FPaintBox_Assert->Canvas, TColor(0xFFEFEF), TColor(0xFFEFEF));
	TCanvas * canvas = FPaintBox_Assert->Canvas;
	canvas->Rectangle(0, 0, FPaintBox_Assert->Width, FPaintBox_Assert->Height);

	int textHeight = GetTextHeight();
	int radius = (std::min(FPaintBox_Assert->Width, textHeight) - 5) / 2;

	TStrings * lines = GetLineNumbers();
	for(int i = 0; i < lines->Count; ++i) {
		int destLineNumber = lines->Strings[i].ToInt();
		TColor color = clBlack;
		if(IsBreakpoint(destLineNumber))
			color = clRed;
		else if(i < lines->Count - 1) {
			int nextLineNumber = lines->Strings[i + 1].ToInt();
			if( (nextLineNumber > destLineNumber + 1) && ContainBreakPoint(destLineNumber, nextLineNumber))
				color = TColor(0x0000D0);
		}
		if(color != clBlack) {
			THelper::Graphics::FillCanvas(FPaintBox_Assert->Canvas, color, color);
			canvas->Ellipse(FPaintBox_Assert->Width / 2 - radius,
							i * textHeight + textHeight / 2 - radius,
							FPaintBox_Assert->Width / 2 + radius,
							i * textHeight + textHeight / 2 + radius);
		}
	}
	delete lines;
}

exibição breakpoints

Aqui Insert Picture Descrição
Preliminar alcançar os resultados desejados.
Próxima reprocessamento recursos de depuração, tais como a operação de uma etapa e assim por diante. Necessidade de olhar sobre a coleta de Internet, ver quanto tempo ele pode ser resolvido.

Lançado nove artigos originais · ganhou elogios 2 · Visualizações 548

Acho que você gosta

Origin blog.csdn.net/drgraph/article/details/104446365
Recomendado
Clasificación