alecAbstraction Layer for Escape Codes |
git clone git://git.dimitrijedobrota.com/alec.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | 22c370f54016fa15ea40033194db9ba0e5894acd |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Fri, 29 Dec 2023 18:21:25 +0000 |
Inital commit, proof of conept
Diffstat:A | .clang-format | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | .gitignore | | | ++ |
A | CMakeLists.txt | | | +++++++++++++++++++ |
A | demo/CMakeLists.txt | | | ++++++++ |
A | demo/demo.cpp | | | ++++++++++++++++++++++++ |
A | src/CMakeLists.txt | | | +++++++++++++ |
A | src/alec.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 files changed, 445 insertions(+), 0 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -0,0 +1,216 @@
---
Language: Cpp
# BasedOnStyle: Microsoft
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: true
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 110
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 1000
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RequiresClausePosition: OwnLine
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
build
.cache
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.25.2)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(
Alec
VERSION 0.0.1
DESCRIPTION "Abstraction Layer for Escape Codes"
HOMEPAGE_URL https://git.dimitrijedobrota.com/alec.git
LANGUAGES CXX
)
enable_testing()
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_subdirectory(src)
add_subdirectory(demo)
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
@@ -0,0 +1,8 @@
add_executable(demo demo.cpp)
target_link_libraries(demo alec)
set_target_properties(demo PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
diff --git a/demo/demo.cpp b/demo/demo.cpp
@@ -0,0 +1,24 @@
#include "alec.hpp"
#include <iostream>
int main(void) {
std::cout << ALEC::ABUF_SHOW << ALEC::CURSOR_HIDE;
std::cout << ALEC::CURSOR_POSITION(1, 1) << ALEC::FOREGROUND(91) << "HELLO!\n";
std::cout << ALEC::CURSOR_DOWN(3);
std::cout << ALEC::FOREGROUND(30) << ALEC::BACKGROUND(196) << "WORLD!\n";
std::cout << ALEC::BACKGROUND(ALEC::DEFAULT) << "testing 1...\n" << ALEC::FOREGROUND(ALEC::DEFAULT);
std::cout << ALEC::DECOR_SET(ALEC::INVERSE) << "testing 2...\n" << ALEC::DECOR_RESET(ALEC::INVERSE);
std::cout << ALEC::CURSOR_UP(5) << "Hello there!" << ALEC::CURSOR_SAVE;
std::cout << ALEC::CURSOR_DOWN(10) << "General Kenobi!";
std::cout << ALEC::CURSOR_POSITION(10, 40) << "no pain no gain" << ALEC::CURSOR_LOAD;
getchar();
std::cout << ALEC::CURSOR_SHOW << ALEC::ABUF_HIDE;
return 0;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -0,0 +1,13 @@
add_library(alec INTERFACE)
target_include_directories(alec INTERFACE .)
set_target_properties(alec PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER alec.hpp
)
install(TARGETS alec
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include
)
diff --git a/src/alec.hpp b/src/alec.hpp
@@ -0,0 +1,163 @@
#ifndef ALEC_ALEC_H
#define ALEC_ALEC_H
#include <format>
#include <iostream>
namespace ALEC {
enum CTRL {
BELL = 0x07,
BS = 0x08,
HT = 0x09,
LF = 0x0A,
VT = 0x0B,
FF = 0x0C,
CR = 0x0D,
ESC = 0x1B,
DEL = 0x7F,
};
enum COLOR {
BLACK = 0,
RED = 1,
GREEN = 2,
YELLOW = 3,
BLUE = 4,
MAGENTA = 5,
CYAN = 6,
WHITE = 7,
DEFAULT = 9,
};
enum DECOR {
RESET = 0,
BOLD = 1,
DIM = 2,
ITALIC = 3,
UNDERLINE = 4,
BLINK = 5,
INVERSE = 7,
HIDE = 8,
STRIKE = 9,
};
template <typename... Args> class CMD {
public:
constexpr CMD(const char c) : c(c) {}
constexpr std::string operator()(Args... args) const {
return std::format(fmt, (char)CTRL::ESC, args..., c);
}
private:
const char c;
static constexpr auto arr = []() {
constexpr std::size_t len = sizeof...(Args) * 3 + 4;
std::array<char, len + 1> arr = {'{', '}', '['};
for (std::size_t i = 3; i < len - 1; i += 3) {
arr[i] = '{', arr[i + 1] = '}', arr[i + 2] = ';';
}
arr[len - 2] = '{', arr[len - 1] = '}', arr[len] = 0;
return arr;
}();
static constexpr auto fmt = std::string_view(arr.data(), arr.size() - 1);
};
static constexpr const CMD<int> CURSOR_UP('A');
static constexpr const CMD<int> CURSOR_DOWN('B');
static constexpr const CMD<int> CURSOR_FRWD('C');
static constexpr const CMD<int> CURSOR_BACK('D');
static constexpr const CMD<int> CURSOR_LINE_NEXT('E');
static constexpr const CMD<int> CURSOR_LINE_PREV('F');
static constexpr const CMD<int> CURSOR_COLUMN('G');
static constexpr const CMD<int> ERASE_DISPLAY('J');
static constexpr const CMD<int> ERASE_LINE('K');
static constexpr const CMD<int> SCROLL_UP('S');
static constexpr const CMD<int> SCROLL_DOWN('T');
static constexpr const CMD<int, int> CURSOR_POSITION('H');
// palet colors
static constexpr auto FOREGROUND(COLOR color) {
static constexpr const CMD<int> bootstrap('m');
return bootstrap(30 + color);
}
static constexpr auto BACKGROUND(COLOR color) {
static constexpr const CMD<int> bootstrap('m');
return bootstrap(40 + color);
}
// 256-color palette
static constexpr auto FOREGROUND(int idx) {
static constexpr const CMD<int, int, int> bootstrap('m');
return bootstrap(38, 5, idx);
}
static constexpr auto BACKGROUND(int idx) {
static constexpr const CMD<int, int, int> bootstrap('m');
return bootstrap(48, 5, idx);
}
// RGB colors
static constexpr auto FOREGROUND(int r, int g, int b) {
static constexpr const CMD<int, int, int, int, int> bootstrap('m');
return bootstrap(38, 5, r, g, b);
}
static constexpr auto BACKGROUND(int r, int g, int b) {
static constexpr const CMD<int, int, int, int, int> bootstrap('m');
return bootstrap(48, 5, r, g, b);
}
// Set/Reset text decorators
static constexpr auto DECOR_SET(DECOR decor) {
static constexpr const CMD<int> bootstrap('m');
return bootstrap(static_cast<int>(decor));
}
static constexpr auto DECOR_RESET(DECOR decor) {
static constexpr const CMD<int> bootstrap('m');
return bootstrap(static_cast<int>(decor) + 20);
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &CURSOR_SAVE(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<>('s')();
return bos << sequence;
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &CURSOR_LOAD(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<>('u')();
return bos << sequence;
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &CURSOR_SHOW(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<const char *>('h')("?25");
return bos << sequence;
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &CURSOR_HIDE(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<const char *>('l')("?25");
return bos << sequence;
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &ABUF_SHOW(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<const char *>('h')("?1049");
return bos << sequence;
}
template <class CharT, class Traits>
static constexpr std::basic_ostream<CharT, Traits> &ABUF_HIDE(std::basic_ostream<CharT, Traits> &bos) {
static auto sequence = CMD<const char *>('l')("?1049");
return bos << sequence;
}
} // namespace ALEC
#endif