Skip to content

Commit

Permalink
Lua code editors indentation (#7890)
Browse files Browse the repository at this point in the history
* It's not possible to indent lines even if they are empty
* Tab does not indent the entire line anymore, instead it adds a tab at the caret position
* String declarations are autoclosed now
* Auto-indentation for function, while, if statements.
* When pressing Enter, the new line will keep the indentation from the previous line
  • Loading branch information
blancoberg authored Dec 2, 2024
1 parent f6274e6 commit ab8acad
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 19 deletions.
4 changes: 0 additions & 4 deletions src/common/LuaSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,6 @@ Surge::LuaSupport::SGLD::~SGLD()
{
std::cout << "Guarded stack leak: [" << label << "] exit=" << nt << " enter=" << top
<< std::endl;
for (int i = nt; i >= top; i--)
{
std::cout << " " << i << " -> " << lua_typename(L, lua_type(L, i)) << std::endl;
}
}
#endif
}
Expand Down
1 change: 0 additions & 1 deletion src/common/dsp/WavetableScriptEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ struct LuaWTEvaluator::Details
lua_getglobal(L, "init");
if (!lua_isfunction(L, -1))
{
lua_pop(L, -1);
makeEmptyState(true);
}
else
Expand Down
136 changes: 135 additions & 1 deletion src/surge-xt/gui/overlays/LuaEditors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "widgets/MenuCustomComponents.h"
#include <fmt/core.h>
#include "widgets/OscillatorWaveformDisplay.h"
#include <regex>

namespace Surge
{
Expand All @@ -61,6 +62,62 @@ struct SurgeCodeEditorComponent : public juce::CodeEditorComponent
c = c->getParentComponent();
}
}

// Handles auto indentation

void handleReturnKey() override
{

auto pos = this->getCaretPos();
auto txt = pos.getLineText();
int tabs = 0;

for (int i = 0; i < txt.length(); i++)
{
if (txt.substring(i, i + 1) == " ")
{
tabs++;
}
else if (txt.substring(i, i + 1) == "\t")
{
tabs += this->getTabSize();
}
else
{
bool indent = false;
auto trimmedTxt = txt.trim();

if (txt.substring(i, i + 8) == "function")
{

indent = true;
}
else if (txt.substring(i, i + 2) == "if" &&
trimmedTxt.substring(trimmedTxt.length() - 4, trimmedTxt.length()) ==
"then")
{
indent = true;
}
else if (trimmedTxt.substring(0, 4) == "else")
{
indent = true;
}
else if (trimmedTxt.substring(trimmedTxt.length() - 2, trimmedTxt.length()) ==
"do" ||
trimmedTxt.substring(0, 5) == "while")
{
indent = true;
}

tabs += indent == true ? this->getTabSize() : 0;

break;
}
}

this->insertTextAtCaret("\n");
this->insertTextAtCaret(std::string(tabs, ' '));
}
};

struct EditorColors
Expand Down Expand Up @@ -164,7 +221,7 @@ bool CodeEditorContainerWithApply::keyPressed(const juce::KeyPress &key, juce::C
}
else
{
mainEditor->indentSelection();
mainEditor->insertTabAtCaret();
}

return true;
Expand Down Expand Up @@ -225,12 +282,87 @@ bool CodeEditorContainerWithApply::keyPressed(const juce::KeyPress &key, juce::C

return true;
}
// search
else if (key.getModifiers().isCommandDown() && keyCode == 70)
{
/*
search for characters and use getCharacterBounds to get its screen position
*/
return true;
}

// handle string completion

else if (keyCode == 50)
{
return this->autoCompleteStringDeclaration("\"");
}
else if (keyCode == 39)
{
return this->autoCompleteStringDeclaration("'");
}
else
{
return Component::keyPressed(key);
}
}

void CodeEditorContainerWithApply::removeStringTrailsFromDocument()
{

/*
this needs some work as the caret position gets all screwed up after clean up
*/

/*
auto caretPos = mainEditor->getCaretPos();
std::string s = mainEditor->getDocument().getAllContent().toStdString();
std::regex pattern("[ \t]+$");
std::string replacement = "";
std::string result = std::regex_replace(s, pattern, replacement);
mainEditor->getDocument().replaceAllContent(result);
mainEditor->moveCaretTo(caretPos, false);
*/
}

bool CodeEditorContainerWithApply::autoCompleteStringDeclaration(juce::String str)
{

auto pos = mainEditor->getCaretPos();
auto txt = pos.getLineText();

int ApostrCount = 0;

for (int i = 0; i < txt.length(); i++)
{
if (txt.substring(i, i + 1) == str)
ApostrCount++;
}

// Close string
if (ApostrCount % 2 == 0)
{

if (txt.substring(pos.getIndexInLine(), pos.getIndexInLine() + 1) != str)
{
mainEditor->insertTextAtCaret(str + str);
mainEditor->moveCaretLeft(false, false);
}

else
{
mainEditor->moveCaretRight(false, false);
}
}
else
{
mainEditor->insertTextAtCaret(str);
}
return true;
// sdfsd
}

void CodeEditorContainerWithApply::paint(juce::Graphics &g) { g.fillAll(juce::Colours::black); }

struct ExpandingFormulaDebugger : public juce::Component, public Surge::GUI::SkinConsumingComponent
Expand Down Expand Up @@ -799,6 +931,7 @@ void FormulaModulatorEditor::onSkinChanged()

void FormulaModulatorEditor::applyCode()
{
removeStringTrailsFromDocument();
editor->undoManager()->pushFormula(scene, lfo_id, *formulastorage);
formulastorage->setFormula(mainDocument->getAllContent().toStdString());
storage->getPatch().isDirty = true;
Expand Down Expand Up @@ -1849,6 +1982,7 @@ void WavetableScriptEditor::setupEvaluator()

void WavetableScriptEditor::applyCode()
{
removeStringTrailsFromDocument();
osc->wavetable_formula = mainDocument->getAllContent().toStdString();
osc->wavetable_formula_res_base = controlArea->resolutionN->getIntValue();
osc->wavetable_formula_nframes = controlArea->framesN->getIntValue();
Expand Down
2 changes: 2 additions & 0 deletions src/surge-xt/gui/overlays/LuaEditors.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class CodeEditorContainerWithApply : public OverlayComponent,
void buttonClicked(juce::Button *button) override;
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
void codeDocumentTextInserted(const juce::String &newText, int insertIndex) override;
void removeStringTrailsFromDocument();
bool autoCompleteStringDeclaration(juce::String str);
bool keyPressed(const juce::KeyPress &key, Component *originatingComponent) override;

virtual void setApplyEnabled(bool) {}
Expand Down
13 changes: 0 additions & 13 deletions src/surge-xt/gui/widgets/OscillatorWaveformDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,6 @@ void OscillatorWaveformDisplay::populateMenu(juce::PopupMenu &contextMenu, int s

// Change this to 0 to disable WTSE component, to disable for release: change value, test, and push
#define INCLUDE_WT_SCRIPTING_EDITOR 1
#if HAS_LUA
#if INCLUDE_WT_SCRIPTING_EDITOR
contextMenu.addSeparator();

Expand All @@ -612,7 +611,6 @@ void OscillatorWaveformDisplay::populateMenu(juce::PopupMenu &contextMenu, int s

contextMenu.addItem(Surge::GUI::toOSCase("Wavetable Script Editor..."), owts);
contextMenu.addSeparator();
#endif
#endif

// add this option only if we have any wavetables in the list
Expand Down Expand Up @@ -729,17 +727,6 @@ void OscillatorWaveformDisplay::createWTMenuItems(juce::PopupMenu &contextMenu,
contextMenu.addItem(
Surge::GUI::toOSCase(fmt::format("Frame Length: {} samples", oscdata->wt.size)),
true, false, nullptr);

#if HAS_LUA
contextMenu.addSeparator();
contextMenu.addItem(Surge::GUI::toOSCase("Wavetable Script Editor..."),
[w = juce::Component::SafePointer(this)]() {
if (!w)
return;
if (w->sge)
w->sge->showOverlay(SurgeGUIEditor::WTSCRIPT_EDITOR);
});
#endif
}
}
}
Expand Down

0 comments on commit ab8acad

Please sign in to comment.