Commit 452c5a19 authored by Daniel Mensinger's avatar Daniel Mensinger

clangFormat: Added preview samples

parent 10358c19
Pipeline #6830 passed with stage
in 49 minutes and 25 seconds
......@@ -6,6 +6,7 @@ include_directories(${CLANG_INCLUDE_DIRS} "${CMAKE_CURRENT_BINARY_DIR}")
set(kdevclangformat_SRCS
cf_itemlist.cpp
cf_plugin.cpp
cf_preview.cpp
cf_settings.cpp
cf_stringlist.cpp
)
......
......@@ -18,6 +18,7 @@
*/
#include "cf_plugin.h"
#include "cf_preview.h"
#include "cf_settings.h"
#include "debug.h"
......@@ -190,6 +191,9 @@ QString ClangFormatPlugin::formatSourceWithStyle(SourceFormatterStyle style, con
// LLVM uses string REFERENCES ==> always keep the original string around on the stack
string filename = url.fileName().toStdString();
if (filename.empty()) {
filename = "<stdin>";
}
tooling::Range codeRange(left.size(), center.size());
auto replacements = format::reformat(cfStyle, code, { codeRange }, filename);
......@@ -263,11 +267,9 @@ ISourceFormatter::Indentation ClangFormatPlugin::indentation(const QUrl& url) co
return indent;
}
QString ClangFormatPlugin::previewText(const SourceFormatterStyle& style, const QMimeType& mime) const
QString ClangFormatPlugin::previewText(const SourceFormatterStyle&, const QMimeType& mime) const
{
(void)style;
(void)mime;
return QString();
return QLatin1String(getPreviewText(QLatin1String("base"), mimeType2Lang(mime)));
}
#include "cf_plugin.moc"
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "cf_preview.h"
#include "cf_plugin.h"
#include <QMimeType>
#include <QString>
const static char CPP_BASE[] = R";;;(
// Indentation
#define foobar(A)\
{Foo();Bar();}
#define anotherFoo(B)\
return Bar()
namespace Bar
{
class Foo
{
public:
Foo();
virtual ~Foo();
};
void bar ( int foo )
{
int a = 0; // Comment 0
int bbb = 4; // Comment 1
int *c = &bbb; // Comment 2
std::string tempString = "Hello World"; // Comment 3
switch ( foo ) {
case 1:
a+=1;
break;
case 2: {
a += 2;
break;
}
case 3:
a += 3;
bbb -= 1;
tempString = "";
break;
}
if ( isFoo ) {
bar();
} else {
anotherBar();
}
}
int foo() {
while ( isFoo )
{
// ...
goto error;
/* .... */
error:
//...
}}
}
fooArray[]= { red,
green,
darkblue
};
fooFunction ( barArg1,
barArg2,
barArg3 );
struct foo {
int bar() {}
};
// Formatting
void func()
{
if ( isFoo ( a,b ) )
bar ( a,b );
if ( isFoo )
a=bar ( ( b-c ) *a,*d-- );
if ( isFoo ( a,b ) )
bar ( a, b );
if ( isFoo ) {return;}
if ( isFoo ) {
isFoo=false;
cat << isFoo <<endl;
}
if ( isFoo ) DoBar();
if ( isFoo ) {
bar();
} else if ( isBar() ) {
annotherBar();
}
int var = 1;
int *ptr = &var;
int& ref = i;
QList<int>::const_iterator it = list.begin();
}
namespace A
{
namespace B
{
class someClass
{
void foo()
{
if ( true ) {
func();
} else {
// bla
}
}
};
}
}
);;;";
static const char* CPP_INDENT = R";;;(
namespace A {
namespace B {
class Foo {
public:
Foo() = default;
inline int getInt() const { return val; }
void setInt(int i);
int calculate();
private:
int val = 0;
};
void Foo::setInt(int i) { val = i; }
int Foo::calculate() {
val += 2;
while (val < 10) {
val += 3;
}
if (val > 100) {
val -= 90;
}
if (val > 50) {
val -= 20;
} else if (val > 60) {
val -= 30;
} else {
val++;
}
switch (val) {
case 1:
case 2:
val = 3;
break;
case 5:
val = val * val;
val -= 10;
val /= 2;
case 6: {
return val;
}
case 7: {
int b = val + 10;
val += b;
--val;
}
}
return val;
}
}
}
);;;";
static const char* CPP_ALIGN = R";;;(
#define BAR(a, b, c) \
a += b + c;\
b += a + c;\
c += a + b;
int foo() {
int a = 42; // Comment about a
int bbb = 1; // Comment about bbb
unsigned int cccccc = 666; // Comment about cccccc
BAR(a, bbb, cccccc);
return a + bbb;
}
);;;";
static const char* CPP_PADDING = R";;;(
#include <vector>
class Foo {};
class Bar : public Foo {
Bar() : Foo() {}
};
int foo(int a, int b) {
int bbb = a + b;
std::vector<int>{1, 2, 3, 4, 5};
int abc[4]; // Comment
for (int &i : abc) {
i = 0;
}
if (bbb < 0) {
bbb *= -1;
}
return (int)bbb;
}
);;;";
static const char* OBJC_BASE = R";;;(
// Indentation
#import <objc/Object.h>
#define foobar(A)\
{Foo();Bar();}
#define anotherFoo(B)\
return Bar()
@interface Foo : Bar
{
@private
id Baz;
}
- ( void ) init;
- ( NSString* ) description;
@property ( retain ) id Baz;
@end
@interface Foo ( Bar )
- ( void ) bar: ( int ) foo;
@end
@implementation Foo ( Bar )
- ( void ) bar: ( int ) foo
{
int a = 0; // Comment 0
int bbb = 4; // Comment 1
int *c = &bbb; // Comment 2
std::string tempString = "Hello World"; // Comment 3
switch ( foo ) {
case 1:
a += 1;
break;
case 2: {
a += 2;
break;
}
case 3:
a += 3;
bbb -= 1;
tempString = "";
break;
}
if ( isFoo ) {
bar();
} else {
[anotherBar withFoo:self];
}
}
@end
int foo()
while ( isFoo )
{
// ...
goto error;
/* .... */
error:
//...
}
fooArray[] = { red,
green,
darkblue
};
fooFunction ( barArg1,
barArg2,
barArg3 );
struct foo {
int bar() {}
};
// Formatting
void func()
{
if ( isFoo ( a,b ) )
bar ( a,b );
if ( isFoo )
a=bar ( ( b-c ) *a,*d-- );
if ( isFoo ( a,b ) )
bar ( a, b );
if ( isFoo ) {
isFoo=false;
cat << isFoo <<endl;
}
if ( isFoo ) DoBar();
if ( isFoo ) {
bar();
} else if ( isBar() ) {
annotherBar();
}
int var = 1;
int *ptr = &var;
}
@implementation someClass
+ ( someClass* ) someClassWithFoo: ( int ) foo
{
someClass *this;
if ( foo ) {
this = [[someClass alloc] initWith:foo];
} else {
// bla
}
return self;
}
@end
);;;";
// Helper functions for the compile time string hash
const size_t FNV1A_BASE = 2166136261;
const size_t FNV1A_PRIME = 16777619;
constexpr size_t fnv1aHash(const char* data, size_t n)
{
size_t hash = FNV1A_BASE;
for (size_t i = 0; i < n; ++i) {
hash ^= static_cast<size_t>(data[i]);
hash *= FNV1A_PRIME;
}
return hash;
}
inline size_t fnv1aHash(const QString& data)
{
std::string str = data.toStdString();
return fnv1aHash(str.c_str(), str.size());
}
constexpr size_t operator"" _h(char const* data, size_t n)
{
return fnv1aHash(data, n);
}
using Language = clang::format::FormatStyle::LanguageKind;
const char* getPreviewText(const QString& tabHint, Language lang)
{
switch (lang) {
case Language::LK_ObjC:
switch (fnv1aHash(tabHint)) {
case "base"_h:
return OBJC_BASE;
default:
return OBJC_BASE;
}
break;
case Language::LK_Cpp:
default:
switch (fnv1aHash(tabHint)) {
case "ind"_h:
case "break"_h:
case "brace"_h:
return CPP_INDENT;
case "align"_h:
return CPP_ALIGN;
case "space"_h:
return CPP_PADDING;
case "base"_h:
return CPP_BASE;
default:
return CPP_BASE;
}
break;
}
return CPP_BASE;
}
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include <clang/Format/Format.h>
class QString;
const char *getPreviewText(const QString &tabHint, clang::format::FormatStyle::LanguageKind lang);
......@@ -26,10 +26,12 @@
#include <QFileDialog>
#include <QInputDialog>
#include <QSignalBlocker>
#include <QTabBar>
#include <QVBoxLayout>
#include "cf_entries.h"
#include "cf_plugin.h"
#include "cf_preview.h"
#include "debug.h"
#include "ui_cf_settings.h"
......@@ -141,8 +143,9 @@ void CFSettingsWidget::preset()
void CFSettingsWidget::reformatPreview()
{
// TODO implement
qCDebug(CLANG_FORMAT) << "Preview reformat triggered";
QString tabHint = m_ui->c_tabs->tabBar()->tabData(m_ui->c_tabs->currentIndex()).toString();
emit previewTextChanged(QLatin1String(getPreviewText(tabHint, m_lang)));
}
void CFSettingsWidget::tabIndexChanged()
......
......@@ -20,7 +20,7 @@
#include "gen_cfg.h"
// Make regex work
std::regex operator"" _r(const char* x, size_t)
inline std::regex operator"" _r(const char* x, size_t)
{
return std::regex(x);
}
......
......@@ -346,7 +346,14 @@ string buildLayout(const string& tabWVar, const TabMap& tabs)
fp << endl;
fp << "// Add tabs" << endl;
for (auto const& i : CFG.sections) {
fp << tabWVar << "->addTab(" << tabs.at(i.id).scroll() << ",i18n(\""<< tabs.at(i.id).title <<"\"));" << endl;
fp << tabWVar << "->addTab(" << tabs.at(i.id).scroll() << ",i18n(\"" << tabs.at(i.id).title << "\"));" << endl;
}
fp << endl;
fp << "// Set tab data" << endl;
for (auto const& i : CFG.sections) {
fp << tabWVar << "->tabBar()->setTabData(" << tabWVar << "->indexOf(" << tabs.at(i.id).scroll()
<< "), QStringLiteral(\"" << i.id << "\"));" << endl;
}
fp << endl;
......
......@@ -18,6 +18,7 @@
*/
#include "gen_model.h"
#include "gen_helpers.h"
#include <iomanip>
#include <iostream>
#include <regex>
......@@ -25,6 +26,11 @@
using namespace std;
inline std::regex operator"" _r(const char* x, size_t)
{
return std::regex(x);
}
std::string toStr(DataType t)
{
switch (t) {
......@@ -51,13 +57,18 @@ std::string toStr(DataType t)
std::string richTextDescription(std::string desc)
{
regex beginCode("\\\\code(\\{[^\\}]*\\})?");
regex endCode("\\\\endcode");
regex shortCode("``([^`]+)``");
desc = regex_replace(desc, endCode, "</code>");
desc = regex_replace(desc, beginCode, "<code>");
desc = regex_replace(desc, shortCode, "<tt>$1</tt>");
vector<pair<regex, string>> regMap = {
{ "&"_r, "&amp;" },
{ "<"_r, "&lt;" },
{ ">"_r, "&gt;" },
{ "\\\\endcode"_r, "</code>" },
{ "\\\\code(\\{[^\\}]*\\})?"_r, "<code>" },
{ "``([^`]+)``"_r, "<tt>$1</tt>" },
};
for (auto const& i : regMap) {
desc = regex_replace(desc, i.first, i.second);
}
return "<p style='white-space:pre'>" + desc + "</p>";
}
......
Markdown is supported
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