Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/qt/mAMainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ void mAMainWindow::newFile()
documentView->setTabWidget(ui->tabWidget);
QObject::connect(m_preferencesWindow, SIGNAL(preferencesChanged()),
documentView, SLOT(preferencesChanged()));
QObject::connect(documentView, SIGNAL(formatError(QString)),
statusBar(), SLOT(showMessage(QString)));

ui->tabWidget->addTab(documentView, QIcon(), "untitled");
ui->tabWidget->setCurrentIndex(ui->tabWidget->count()-1);
Expand Down Expand Up @@ -383,6 +385,8 @@ void mAMainWindow::openFile(const QString &path)

QObject::connect(m_preferencesWindow, SIGNAL(preferencesChanged()),
documentView, SLOT(preferencesChanged()));
QObject::connect(documentView, SIGNAL(formatError(QString)),
statusBar(), SLOT(showMessage(QString)));

ui->tabWidget->addTab(documentView, QIcon(), fileInfo.fileName());
ui->tabWidget->setCurrentIndex(ui->tabWidget->count()-1);
Expand Down Expand Up @@ -434,6 +438,8 @@ void mAMainWindow::openExample()
documentView->setTabWidget(ui->tabWidget);
QObject::connect(m_preferencesWindow, SIGNAL(preferencesChanged()),
documentView, SLOT(preferencesChanged()));
QObject::connect(documentView, SIGNAL(formatError(QString)),
statusBar(), SLOT(showMessage(QString)));
documentView->setReadOnly(true);

ui->tabWidget->addTab(documentView, QIcon(), fileInfo.fileName());
Expand Down Expand Up @@ -550,6 +556,7 @@ void mAMainWindow::tabSelected(int index)
ui->actionPaste->disconnect();
ui->actionSelect_All->disconnect();
ui->actionExport_as_WAV->disconnect();
ui->actionFormat_Code->disconnect();

if(currentView == NULL)
{
Expand All @@ -570,6 +577,7 @@ void mAMainWindow::tabSelected(int index)
connect(ui->actionPaste, SIGNAL(triggered()), currentView, SIGNAL(paste()));
connect(ui->actionSelect_All, SIGNAL(triggered()), currentView, SIGNAL(selectAll()));
connect(ui->actionExport_as_WAV, SIGNAL(triggered()), currentView, SLOT(exportAsWav()));
connect(ui->actionFormat_Code, SIGNAL(triggered()), currentView, SLOT(formatCode()));
}

#pragma mark
Expand Down
10 changes: 10 additions & 0 deletions src/qt/mAMainWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
<addaction name="separator"/>
<addaction name="actionSelect_All"/>
<addaction name="separator"/>
<addaction name="actionFormat_Code"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menuChucK">
Expand Down Expand Up @@ -280,6 +282,14 @@
<string>Alt+,</string>
</property>
</action>
<action name="actionFormat_Code">
<property name="text">
<string>Format Code</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+I</string>
</property>
</action>
<action name="actionAdd_Shred">
<property name="icon">
<iconset>
Expand Down
8 changes: 8 additions & 0 deletions src/qt/mAPreferencesWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ const QString mAPreferencesUseTabs = "/GUI/Editing/UsesTabs";
const QString mAPreferencesTabSize = "/GUI/Editing/TabSize";
const QString mAPreferencesShowLineNumbers = "/GUI/Editing/ShowLineNumbers";
const QString mAPreferencesWindowingStyle = "/GUI/Editing/WindowingStyle"; // 1.5.0.4 (ge) added
const QString mAPreferencesFormatterCommand = "/GUI/Editing/FormatterCommand";
const QString mAPreferencesFormatOnSave = "/GUI/Editing/FormatOnSave";

const QString mAPreferencesCurrentDirectory = "/Miscellaneous/CurrentDirectory";

Expand Down Expand Up @@ -190,6 +192,8 @@ void mAPreferencesWindow::configureDefaults()

ZSettings::setDefault(mAPreferencesUseTabs, false);
ZSettings::setDefault(mAPreferencesTabSize, 4);
ZSettings::setDefault(mAPreferencesFormatterCommand, "chuckfmt");
ZSettings::setDefault(mAPreferencesFormatOnSave, false);
// ZSettings::setDefault(mAPreferences)

ZSettings::setDefault(mAPreferencesEnableChuGins, true);
Expand Down Expand Up @@ -279,6 +283,8 @@ void mAPreferencesWindow::loadSettingsToGUI()

ui->editorUsesTabs->setChecked(settings.get(mAPreferencesUseTabs).toBool());
ui->tabWidth->setValue(settings.get(mAPreferencesTabSize).toInt());
ui->formatterCommand->setText(settings.get(mAPreferencesFormatterCommand).toString());
ui->formatOnSave->setChecked(settings.get(mAPreferencesFormatOnSave).toBool());

ui->enableChugins->setChecked(settings.get(mAPreferencesEnableChuGins).toBool());
ui->chuginsList->clear();
Expand Down Expand Up @@ -366,6 +372,8 @@ void mAPreferencesWindow::loadGUIToSettings()

settings.set(mAPreferencesUseTabs, ui->editorUsesTabs->isChecked());
settings.set(mAPreferencesTabSize, ui->tabWidth->value());
settings.set(mAPreferencesFormatterCommand, ui->formatterCommand->text());
settings.set(mAPreferencesFormatOnSave, ui->formatOnSave->isChecked());

settings.set(mAPreferencesEnableChuGins, ui->enableChugins->isChecked());
QStringList paths;
Expand Down
2 changes: 2 additions & 0 deletions src/qt/mAPreferencesWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ extern const QString mAPreferencesUseTabs;
extern const QString mAPreferencesTabSize;
extern const QString mAPreferencesShowLineNumbers;
extern const QString mAPreferencesWindowingStyle;
extern const QString mAPreferencesFormatterCommand;
extern const QString mAPreferencesFormatOnSave;

extern const QString mAPreferencesCurrentDirectory;

Expand Down
21 changes: 21 additions & 0 deletions src/qt/mAPreferencesWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,27 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_formatter">
<item>
<widget class="QLabel" name="label_formatter">
<property name="text">
<string>Formatter command:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="formatterCommand"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="formatOnSave">
<property name="text">
<string>Format on save</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
Expand Down
89 changes: 89 additions & 0 deletions src/qt/madocumentview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,12 @@ void mADocumentView::save()

if(file != NULL)
{
// format-on-save: formatCode() is idempotent (no-op on already-formatted
// or on formatter error) so we can unconditionally call it when enabled
ZSettings settings;
if(settings.get(mAPreferencesFormatOnSave).toBool())
formatCode();

file->open(QIODevice::WriteOnly | QIODevice::Truncate);
ui->textEdit->write(file);
file->flush();
Expand Down Expand Up @@ -439,6 +445,11 @@ void mADocumentView::saveAs()

if(file != NULL)
{
// format-on-save: see save() for rationale
ZSettings settings;
if(settings.get(mAPreferencesFormatOnSave).toBool())
formatCode();

file->open(QIODevice::WriteOnly | QIODevice::Truncate);
ui->textEdit->write(file);
file->flush();
Expand Down Expand Up @@ -590,3 +601,81 @@ void mADocumentView::remove()
}
}


void mADocumentView::formatCode()
{
QString input = ui->textEdit->text();
if(input.isEmpty()) return;

int line = 0, col = 0;
ui->textEdit->getCursorPosition(&line, &col);
int firstVisible = ui->textEdit->firstVisibleLine();

ZSettings settings;
QString command = settings.get(mAPreferencesFormatterCommand, "chuckfmt").toString().trimmed();
if(command.isEmpty())
{
emit formatError("formatter command is empty (set it in Preferences)");
return;
}

QString bin = which(command);
if(bin.isEmpty())
{
if(command == "chuckfmt")
emit formatError("chuckfmt not found in PATH -- install from https://github.com/aik2mlj/chuckfmt");
else
emit formatError(QString("formatter not found: %1").arg(command));
return;
}

// contract is stdin->stdout with no args, so any formatter works; do not
// pass the file path. do NOT set MergedChannels either -- stderr must stay
// separate so error text never contaminates the replacement buffer
QProcess process;
process.start(bin, QStringList());
if(!process.waitForStarted(3000))
{
emit formatError(QString("failed to start %1").arg(command));
return;
}
process.write(input.toUtf8());
process.closeWriteChannel();

// soft upper bound; chuckfmt typically returns in <100ms
if(!process.waitForFinished(10000))
{
process.kill();
emit formatError("formatter timed out");
return;
}

if(process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0)
{
QByteArray err = process.readAllStandardError();
QString msg = QString::fromUtf8(err).trimmed();
if(msg.isEmpty()) msg = QString("%1 exited with code %2").arg(command).arg(process.exitCode());
emit formatError(QString("formatter failed: %1").arg(msg));
return;
}

QByteArray out = process.readAllStandardOutput();
QString formatted = QString::fromUtf8(out);

// skip the buffer replace when nothing changed so the modified flag
// doesn't get flipped on an already-formatted document
if(formatted == input) return;

// selectAll+replaceSelectedText (not setText) preserves undo history,
// and the begin/endUndoAction wrap makes one Ctrl+Z revert the whole format
ui->textEdit->beginUndoAction();
ui->textEdit->selectAll(true);
ui->textEdit->replaceSelectedText(formatted);
ui->textEdit->endUndoAction();

int newLineCount = ui->textEdit->lines();
int restoredLine = qMin(line, newLineCount - 1);
ui->textEdit->setCursorPosition(restoredLine, col);
ui->textEdit->setFirstVisibleLine(qMin(firstVisible, newLineCount - 1));
}

2 changes: 2 additions & 0 deletions src/qt/madocumentview.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public slots:
void readOnlySaveDialogClicked(QAbstractButton *button);
void preferencesChanged();
void exportAsWav();
void formatCode();

signals:
void undo();
Expand All @@ -86,6 +87,7 @@ public slots:
void copy();
void paste();
void selectAll();
void formatError(const QString &message);

protected:
void showEvent( QShowEvent * event );
Expand Down