Unverified Commit 1fd7f15a authored by Nightfox's avatar Nightfox
Browse files

Added support for block and line commenting for selected text

parent e17a254c
......@@ -4,3 +4,4 @@ tmp
build
.vs
.DS_Store
.vscode
......@@ -15,7 +15,9 @@ The tool was originally conceived and implemented after the Revision 2014 demosc
- F5 or Ctrl-R: recompile shader
- F11 or Ctrl/Cmd-f: hide shader overlay
- Alt-F4 or Shift+Escape: exbobolate your planet
- Ctrl/Cmd + /: comment or uncomment the selected lines of code
- Ctrl/Cmd + / or Ctrl/Cmd + K: comment or uncomment the selected lines of code
- /: when text is selected, comment or uncomment every selected line
- Shift + 8: when text is selected, perform a block comment between selected code
## Requirements
On Windows, both DirectX 9 and 11 are supported.
......
......@@ -386,28 +386,73 @@ void ShaderEditor::FineTickerCancel( TickReason )
}
void ShaderEditor::CommentSelection()
// Comment or uncomment the selected text in the code editor.
// Returns true if an action was performed
bool ShaderEditor::CommentSelection(CommentType commentType)
{
int selectionStartPosition = WndProc(SCI_GETSELECTIONSTART, 0, 0);
int selectionEndPosition = WndProc(SCI_GETSELECTIONEND, 0, 0);
int firstSelectedLine = WndProc(SCI_LINEFROMPOSITION, selectionStartPosition, 0);
int lastSelectedLine = WndProc(SCI_LINEFROMPOSITION, selectionEndPosition, 0);
for (int line = firstSelectedLine; line <= lastSelectedLine; line++) {
int lineStartPosition = WndProc(SCI_POSITIONFROMLINE, line, 0);
char firstCharacterOFLine = WndProc(SCI_GETCHARAT, lineStartPosition, 0);
if (firstCharacterOFLine == '/') {
// We are uncommenting this line
CommentMode commentMode;
switch (commentType) {
case ctLinesSelectedOnly:
// If no lines are selected then do nothing
if (selectionStartPosition == selectionEndPosition) return false;
case ctLinesAll:
// Perform line (un)commenting "//"
for (int line = firstSelectedLine; line <= lastSelectedLine; line++) {
int lineStartPosition = WndProc(SCI_POSITIONFROMLINE, line, 0);
char firstCharacterOfLine = WndProc(SCI_GETCHARAT, lineStartPosition, 0);
commentMode = firstCharacterOfLine == '/' ? cmUncomment : cmComment;
if (commentMode == cmComment) {
WndProc(SCI_INSERTTEXT, lineStartPosition, reinterpret_cast<sptr_t>("//"));
}
else {
WndProc(SCI_DELETERANGE, lineStartPosition, 2);
}
}
else {
// We are commenting this line
WndProc(SCI_INSERTTEXT, lineStartPosition, reinterpret_cast<sptr_t>("//"));
return true;
case ctBlock:
// If no lines are selected then do nothing
if (selectionStartPosition == selectionEndPosition) return false;
// Perform block (un)commenting between selection start and end of selected text (*/ /*)
commentMode = cmComment;
int beginningSelectionOffset;
int endSelectionOffset;
for (beginningSelectionOffset = -2; beginningSelectionOffset <= 0; beginningSelectionOffset++) {
char characterAtOffset = WndProc(SCI_GETCHARAT, selectionStartPosition + beginningSelectionOffset, 0);
char secondCharacterFromOffset = WndProc(SCI_GETCHARAT, selectionStartPosition + beginningSelectionOffset + 1, 0);
if (characterAtOffset == '/' && secondCharacterFromOffset == '*') {
// We have found a "/*" at the beginning of selection. Looks like we are going to uncomment a block but let's check for a "*/" at the end to make sure.
for (endSelectionOffset = -2; endSelectionOffset <= 0; endSelectionOffset++) {
characterAtOffset = WndProc(SCI_GETCHARAT, selectionEndPosition + endSelectionOffset, 0);
secondCharacterFromOffset = WndProc(SCI_GETCHARAT, selectionEndPosition + endSelectionOffset + 1, 0);
if (characterAtOffset == '*' && secondCharacterFromOffset == '/') {
commentMode = cmUncomment;
break;
}
}
break;
}
}
if (commentMode == cmComment) {
char characterAtOffset = WndProc(SCI_GETCHARAT, selectionStartPosition, 0);
WndProc(SCI_INSERTTEXT, selectionStartPosition, reinterpret_cast<sptr_t>("/*"));
WndProc(SCI_INSERTTEXT, selectionEndPosition + 2, reinterpret_cast<sptr_t>("*/"));
}
else if (commentMode == cmUncomment) {
WndProc(SCI_DELETERANGE, selectionStartPosition + beginningSelectionOffset, 2);
WndProc(SCI_DELETERANGE, selectionEndPosition + endSelectionOffset - 2, 2);
}
return true;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Indentation handling
......
......@@ -54,6 +54,12 @@ enum AutoIndentationType {
aitSmart
};
enum CommentType {
ctLinesSelectedOnly,
ctLinesAll,
ctBlock
};
struct SHADEREDITOR_OPTIONS {
std::string sFontPath;
int nFontSize;
......@@ -121,7 +127,7 @@ public:
void SetReadOnly( bool );
Scintilla::Font * GetTextFont();
void CommentSelection();
bool CommentSelection(CommentType);
private:
enum IndentationStatus {
......@@ -130,6 +136,11 @@ private:
isBlockEnd, // indentation end indicator such as "}" or VB "end"
isKeyWordStart // Keywords that cause indentation
};
enum CommentMode {
cmComment,
cmUncomment
};
int GetLineLength(int line);
int GetCurrentLineNumber();
......
......@@ -388,9 +388,21 @@ int main(int argc, const char *argv[])
mDebugOutput.SetText( szError );
}
}
else if (!Renderer::keyEventBuffer[i].ctrl && Renderer::keyEventBuffer[i].scanCode == '/')
{
bool clearKeyEventBuffer = mShaderEditor.CommentSelection(ctLinesSelectedOnly);
if (clearKeyEventBuffer)
Renderer::keyEventBufferCount = 0;
}
else if (Renderer::keyEventBuffer[i].shift && Renderer::keyEventBuffer[i].scanCode == '*')
{
bool clearKeyEventBuffer = mShaderEditor.CommentSelection(ctBlock);
if (clearKeyEventBuffer)
Renderer::keyEventBufferCount = 0;
}
else if (Renderer::keyEventBuffer[i].ctrl && (Renderer::keyEventBuffer[i].scanCode == '/' || Renderer::keyEventBuffer[i].scanCode == 'k')) // Ctrl/Cmd Slash (/) or Ctrl/Cmd-k
{
mShaderEditor.CommentSelection();
mShaderEditor.CommentSelection(ctLinesAll);
}
else if (Renderer::keyEventBuffer[i].scanCode == 292 || (Renderer::keyEventBuffer[i].ctrl && Renderer::keyEventBuffer[i].scanCode == 'f')) // F11 or Ctrl/Cmd-f
{
......
......@@ -476,6 +476,7 @@ namespace Renderer
// case GLFW_KEY_RSUPER: sciKey = SCK_RWIN; break;
case GLFW_KEY_MENU: sciKey = SCK_MENU; break;
case GLFW_KEY_SLASH: sciKey = '/'; break;
case GLFW_KEY_8: sciKey = '*'; break;
// case GLFW_KEY_ASTERISK: sciKey = '`'; break;
// case GLFW_KEY_LEFTBRACKET: sciKey = '['; break;
// case GLFW_KEY_BACKSLASH: sciKey = '\\'; break;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment