Skip to content

Commit 34d4e60

Browse files
authored
Merge pull request #233 from flagarde/read
Read multi-byte if available
2 parents 010970e + 661c22b commit 34d4e60

File tree

18 files changed

+578
-430
lines changed

18 files changed

+578
-430
lines changed

CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ if (CPPTERMINAL_BUILD_EXAMPLES)
4343
add_subdirectory(examples)
4444
endif()
4545

46-
if (CPPTERMINAL_ENABLE_INSTALL)
47-
include(install)
48-
install_library()
49-
endif()
50-
5146
if(MSVC)
5247
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_OLD})
5348
endif()

cmake/install.cmake

Lines changed: 0 additions & 15 deletions
This file was deleted.

cpp-terminal/CMakeLists.txt

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,30 @@ configure_file(version.hpp.in version.hpp)
44
add_subdirectory(platforms)
55

66
# create and configure library target
7-
add_library(cpp-terminal base.cpp prompt.cpp window.cpp input.cpp terminal.cpp color.cpp options.cpp)
7+
8+
add_library(cpp-terminal base.cpp prompt.cpp window.cpp input.cpp terminal.cpp color.cpp key.cpp event.cpp options.cpp)
89
target_link_libraries(cpp-terminal PRIVATE Warnings::Warnings cpp-terminal::cpp-terminal-platforms)
910
target_compile_options(cpp-terminal PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
1011
target_include_directories(cpp-terminal PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}> $<INSTALL_INTERFACE:include>)
1112

1213
set_target_properties(cpp-terminal PROPERTIES
13-
PUBLIC_HEADER "${CMAKE_CURRENT_BINARY_DIR}/version.hpp;${CMAKE_CURRENT_SOURCE_DIR}/tty.hpp;${CMAKE_CURRENT_SOURCE_DIR}/terminal.hpp;${CMAKE_CURRENT_SOURCE_DIR}/base.hpp;${CMAKE_CURRENT_SOURCE_DIR}/prompt.hpp;${CMAKE_CURRENT_SOURCE_DIR}/window.hpp"
14-
PRIVATE_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/platforms/conversion.hpp;${CMAKE_CURRENT_SOURCE_DIR}/platforms/macros.hpp")
14+
PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/options.hpp;${CMAKE_CURRENT_SOURCE_DIR}/event.hpp;${CMAKE_CURRENT_SOURCE_DIR}/key.hpp;${CMAKE_CURRENT_SOURCE_DIR}/tty.hpp;${CMAKE_CURRENT_SOURCE_DIR}/terminal.hpp;${CMAKE_CURRENT_SOURCE_DIR}/base.hpp;${CMAKE_CURRENT_SOURCE_DIR}/prompt.hpp;${CMAKE_CURRENT_SOURCE_DIR}/window.hpp;${CMAKE_CURRENT_BINARY_DIR}/version.hpp"
15+
PRIVATE_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/platforms/conversion.hpp;${CMAKE_CURRENT_SOURCE_DIR}/platforms/macros.hpp")
1516

1617
add_library(cpp-terminal::cpp-terminal ALIAS cpp-terminal)
18+
19+
# Install
20+
if (CPPTERMINAL_ENABLE_INSTALL)
21+
include(GNUInstallDirs)
22+
include(CMakePackageConfigHelpers)
23+
configure_package_config_file("${PROJECT_SOURCE_DIR}/cmake/cpp-terminalConfig.cmake.in" "${PROJECT_BINARY_DIR}/cmake/cpp-terminalConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cpp-terminal")
24+
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/cpp-terminalConfigVersion.cmake" COMPATIBILITY AnyNewerVersion)
25+
install(TARGETS cpp-terminal cpp-terminal-platforms cpp-terminalWarnings EXPORT cpp-terminalTargets
26+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
27+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
28+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
29+
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cpp-terminal"
30+
PRIVATE_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cpp-terminal/platforms")
31+
install(EXPORT cpp-terminalTargets FILE cpp-terminalTargets.cmake NAMESPACE cpp-terminal:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cpp-terminal")
32+
install(FILES "${PROJECT_BINARY_DIR}/cmake/cpp-terminalConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cpp-terminalConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cpp-terminal")
33+
endif()

cpp-terminal/base.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ std::pair<std::size_t, std::size_t> Term::cursor_position()
3030
std::cout << cursor_position_report() << std::flush;
3131
// read input buffer
3232
std::string buf;
33-
char c{'\0'};
33+
Term::Key c;
3434
do {
35-
while(!Platform::read_raw(&c))
35+
while((c = Platform::read_raw()).empty())
3636
;
37-
buf.push_back(c);
38-
} while(c != 'R');
37+
buf.push_back(static_cast<char>(c));
38+
} while(static_cast<char>(c) != 'R');
3939

4040
bool found{false};
4141
std::size_t row{0};

cpp-terminal/event.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include "cpp-terminal/event.hpp"
2+
3+
bool Term::Event::empty()
4+
{
5+
if(m_Type == Type::Empty) return true;
6+
else
7+
return false;
8+
}
9+
10+
Term::Event::Event(const Term::Key& key) : m_Type(Type::Key), m_Key(key) {}
11+
12+
Term::Event::Type Term::Event::type() { return m_Type; }
13+
14+
Term::Event::Event(const std::string& str) : m_Type(Type::CopyPaste), m_str(str) { parse(); }
15+
16+
void Term::Event::parse()
17+
{
18+
if(m_str.size() == 1)
19+
{
20+
m_Type = Type::Key;
21+
m_Key = static_cast<Term::Key::Value>(m_str[0]);
22+
m_str.clear();
23+
}
24+
else if(m_str.size() <= 5)
25+
{
26+
//https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
27+
// CSI = ESC[ SS3 = ESCO
28+
/*
29+
* Key Normal Application
30+
* -------------+----------+-------------
31+
* Cursor Up | CSI A | SS3 A
32+
* Cursor Down | CSI B | SS3 B
33+
* Cursor Right | CSI C | SS3 C
34+
* Cursor Left | CSI D | SS3 D
35+
* -------------+----------+-------------
36+
* Key Normal/Application
37+
* -------------+--------------------
38+
* Cursor Up | ESC A
39+
* Cursor Down | ESC B
40+
* Cursor Right | ESC C
41+
* Cursor Left | ESC D
42+
* -------------+--------------------
43+
*/
44+
if(m_str == "\033OA" || m_str == "\033[A" || m_str == "\033A") m_Key = Term::Key::Value::ARROW_UP;
45+
else if(m_str == "\033OB" || m_str == "\033[B" || m_str == "\033B")
46+
m_Key = Term::Key::Value::ARROW_DOWN;
47+
else if(m_str == "\033OC" || m_str == "\033[C" || m_str == "\033C")
48+
m_Key = Term::Key::Value::ARROW_RIGHT;
49+
else if(m_str == "\033OD" || m_str == "\033[D" || m_str == "\033D")
50+
m_Key = Term::Key::Value::ARROW_LEFT;
51+
/*
52+
* Key Normal Application
53+
* ---------+----------+-------------
54+
* Home | CSI H | SS3 H
55+
* End | CSI F | SS3 F
56+
* ---------+----------+-------------
57+
*/
58+
else if(m_str == "\033OH" || m_str == "\033[H")
59+
m_Key = Term::Key::Value::HOME;
60+
else if(m_str == "\033OF" || m_str == "\033[F")
61+
m_Key = Term::Key::Value::END;
62+
/*
63+
* Key Escape Sequence
64+
* ---------+-----------------
65+
* F1 | SS3 P
66+
* F2 | SS3 Q
67+
* F3 | SS3 R
68+
* F4 | SS3 S
69+
* F1 | CSI 1 1 ~
70+
* F2 | CSI 1 2 ~
71+
* F3 | CSI 1 3 ~
72+
* F4 | CSI 1 4 ~
73+
* F5 | CSI 1 5 ~
74+
* F6 | CSI 1 7 ~
75+
* F7 | CSI 1 8 ~
76+
* F8 | CSI 1 9 ~
77+
* F9 | CSI 2 0 ~
78+
* F10 | CSI 2 1 ~
79+
* F11 | CSI 2 3 ~
80+
* F12 | CSI 2 4 ~
81+
* ---------+-----------------
82+
*/
83+
else if(m_str == "\033OP" || m_str == "\033[11~")
84+
m_Key = Term::Key::Value::F1;
85+
else if(m_str == "\033OQ" || m_str == "\033[12~")
86+
m_Key = Term::Key::Value::F2;
87+
else if(m_str == "\033OR" || m_str == "\033[13~")
88+
m_Key = Term::Key::Value::F3;
89+
else if(m_str == "\033OS" || m_str == "\033[14~")
90+
m_Key = Term::Key::Value::F4;
91+
else if(m_str == "\033[15~")
92+
m_Key = Term::Key::Value::F5;
93+
else if(m_str == "\033[17~")
94+
m_Key = Term::Key::Value::F6;
95+
else if(m_str == "\033[18~")
96+
m_Key = Term::Key::Value::F7;
97+
else if(m_str == "\033[19~")
98+
m_Key = Term::Key::Value::F8;
99+
else if(m_str == "\033[20~")
100+
m_Key = Term::Key::Value::F9;
101+
else if(m_str == "\033[21~")
102+
m_Key = Term::Key::Value::F10;
103+
else if(m_str == "\033[23~")
104+
m_Key = Term::Key::Value::F11;
105+
else if(m_str == "\033[24~")
106+
m_Key = Term::Key::Value::F12;
107+
/*
108+
* Key Normal Application
109+
* ---------+----------+-------------
110+
* Insert | CSI 2 ~ | CSI 2 ~
111+
* Delete | CSI 3 ~ | CSI 3 ~
112+
* Home | CSI 1 ~ | CSI 1 ~
113+
* End | CSI 4 ~ | CSI 4 ~
114+
* PageUp | CSI 5 ~ | CSI 5 ~
115+
* PageDown | CSI 6 ~ | CSI 6 ~
116+
* ---------+----------+-------------
117+
*/
118+
else if(m_str == "\033[2~")
119+
m_Key = Term::Key::Value::INSERT;
120+
else if(m_str == "\033[3~")
121+
m_Key = Term::Key::Value::DEL;
122+
else if(m_str == "\033[1~")
123+
m_Key = Term::Key::Value::HOME;
124+
else if(m_str == "\033[4~")
125+
m_Key = Term::Key::Value::END;
126+
else if(m_str == "\033[5~")
127+
m_Key = Term::Key::Value::PAGE_UP;
128+
else if(m_str == "\033[6~")
129+
m_Key = Term::Key::Value::PAGE_DOWN;
130+
/*
131+
* Key Escape Sequence
132+
* ---------+-----------------
133+
* F13 | CSI 2 5 ~
134+
* F14 | CSI 2 6 ~
135+
* F15 | CSI 2 8 ~
136+
* F16 | CSI 2 9 ~
137+
* F17 | CSI 3 1 ~
138+
* F18 | CSI 3 2 ~
139+
* F19 | CSI 3 3 ~
140+
* F20 | CSI 3 4 ~
141+
* ---------+-----------------
142+
*/
143+
else if(m_str == "\033[25~")
144+
m_Key = Term::Key::Value::F13;
145+
else if(m_str == "\033[26~")
146+
m_Key = Term::Key::Value::F14;
147+
else if(m_str == "\033[28~")
148+
m_Key = Term::Key::Value::F15;
149+
else if(m_str == "\033[29~")
150+
m_Key = Term::Key::Value::F16;
151+
else if(m_str == "\033[31~")
152+
m_Key = Term::Key::Value::F17;
153+
else if(m_str == "\033[32~")
154+
m_Key = Term::Key::Value::F18;
155+
else if(m_str == "\033[33~")
156+
m_Key = Term::Key::Value::F19;
157+
else if(m_str == "\033[34~")
158+
m_Key = Term::Key::Value::F20;
159+
if(!m_Key.empty()) m_Type = Type::Key;
160+
m_str.clear();
161+
}
162+
else { m_Type = Type::CopyPaste; }
163+
}
164+
165+
Term::Event::operator Term::Key()
166+
{
167+
if(m_Type == Type::Key) return m_Key;
168+
else
169+
return Key();
170+
}

cpp-terminal/event.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
#include "cpp-terminal/key.hpp"
4+
5+
#include <cstdint>
6+
#include <string>
7+
8+
namespace Term
9+
{
10+
11+
class Event
12+
{
13+
public:
14+
enum class Type
15+
{
16+
Empty,
17+
Key,
18+
CopyPaste,
19+
};
20+
Event() = default;
21+
Event(const std::string&);
22+
Event(const Term::Key&);
23+
bool empty();
24+
Type type();
25+
26+
operator Term::Key();
27+
Key getKey() { return m_Key; }
28+
29+
private:
30+
void parse();
31+
std::string m_str;
32+
Key m_Key{Key::Value::NO_KEY};
33+
Type m_Type{Type::Empty};
34+
};
35+
36+
} // namespace Term

0 commit comments

Comments
 (0)