NewLang Project
Yet another programm language
Loading...
Searching...
No Matches
autocomplete.h
Go to the documentation of this file.
1/*
2 * Copyleft DieTime/CLI-Autocomplete is licensed under the MIT License
3 * Base source code: https://github.com/DieTime/CLI-Autocomplete
4 */
5
6/*
7 * MIT License
8 * Copyright (c) 2020 Denis Glazkov
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in all
18 * copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29
30#ifndef AUTOCOMPLETE_H
31#define AUTOCOMPLETE_H
32
33#ifdef _MSC_VER
34#ifndef _CRT_SECURE_NO_WARNINGS
35#define _CRT_SECURE_NO_WARNINGS
36#endif
37#endif
38
39#include <pch.h>
40
41#define MAX_OF(x, y) (((x) > (y)) ? (x) : (y))
42
43#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN64)
44#ifndef OS_WINDOWS
45#define OS_WINDOWS
46
47#include <windows.h>
48#include <conio.h>
49#include <stdint.h>
50#endif
51#elif defined(__APPLE__) || defined(__unix__) || defined(__unix) || defined(unix) || defined(__linux__)
52#ifndef OS_UNIX
53#define OS_UNIX
54
55#include <termios.h>
56#include <unistd.h>
57#include <sys/ioctl.h>
58#endif
59#else
60#error Unknown environment!
61#endif
62
63#if defined(OS_WINDOWS)
64#define KEY_ENTER 13
65#define KEY_BACKSPACE 8
66#define KEY_LEFT 75
67#define KEY_RIGHT 77
68#define KEY_UP 72
69#define KEY_DOWN 80
70#define KEY_DEL 83
71#define CTRL_C 3
72#define KEY_HOME 71
73#define KEY_END 70
74#define KEY_ESC 27
75#define SPECIAL_SEQ 0
76#define SPECIAL_SEQ_2 224
77#define COLOR_TYPE uint16_t
78#define DEFAULT_TITLE_COLOR 160
79#define DEFAULT_PREDICT_COLOR 8
80#define DEFAULT_MAIN_COLOR 7
81#elif defined(OS_UNIX)
82#define KEY_ENTER 10
83#define KEY_BACKSPACE 127
84#define KEY_LEFT 68
85#define KEY_RIGHT 67
86#define KEY_UP 65
87#define KEY_DOWN 66
88#define KEY_DEL 51
89#define KEY_HOME 72
90#define KEY_END 70
91#define KEY_DEL_AFTER 126
92#define KEY_ESC 27
93#define SPECIAL_SEQ 27
94#define SPECIAL_SEQ_2 91
95#define COLOR_TYPE const char *
96#define DEFAULT_TITLE_COLOR "0;30;102"
97#define DEFAULT_PREDICT_COLOR "90"
98#define DEFAULT_MAIN_COLOR "0"
99#endif
100#define KEY_SPACE 32
101#define KEY_TAB 9
102
103
112inline int is_ignore_key(int ch);
113
123inline int contain_chars(const char* str, const char* chars);
124
131inline short terminal_width();
132
139inline void color_print(const char* text, COLOR_TYPE color);
140
145inline void clear_line();
146
152inline void set_cursor_x(short x);
153
160inline short get_cursor_y();
161
162#if defined(OS_UNIX)
169inline int _getch();
170#endif
171
172
173
174inline int is_ignore_key(int ch) {
175 int ignore_keys[] =
176#if defined(OS_WINDOWS)
177 {1, 2, 19, 24, 26};
178#elif defined(OS_UNIX)
179 {
180 1, 2, 4, 24
181 };
182#endif
183
184 // Calculate length of ignore keys array
185 unsigned len = sizeof (ignore_keys) / sizeof (int);
186
187 // Check if character is ignore key
188 for (unsigned i = 0; i < len; i++) {
189 if (ch == ignore_keys[i]) {
190 return 1;
191 }
192 }
193
194 return 0;
195}
196
197
198inline int contain_chars(const char* str, const char* chars) {
199 // Checking for given characters in a string
200 for (unsigned i = 0; str[i] != '\0'; i++) {
201 for (unsigned j = 0; chars[j] != '\0'; j++) {
202 if (str[i] == chars[j]) {
203 return 1;
204 }
205 }
206 }
207
208 return 0;
209}
210
211inline void color_print(const char* text, COLOR_TYPE color) {
212#if defined(OS_WINDOWS)
213 HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
214 if (h_console == NULL) {
215 fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
216 exit(1);
217 }
218
219// CONSOLE_SCREEN_BUFFER_INFO console_info;
220// COLOR_TYPE backup;
221//
222// // Save current attributes
223// if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) {
224// fprintf(stderr, "[ERROR] Couldn't get terminal info\n");
225// exit(1);
226// }
227// backup = console_info.wAttributes;
228//
229// // Print colored text
230// if (SetConsoleTextAttribute(h_console, color) == 0) {
231// fprintf(stderr, "[ERROR] Couldn't set terminal color\n");
232// exit(1);
233// }
234
235 printf("%s", text);
236
237// // Restore original color
238// if (SetConsoleTextAttribute(h_console, backup) == 0) {
239// fprintf(stderr, "[ERROR] Couldn't reset terminal color\n");
240// exit(1);
241// }
242 _flushall();
243#elif defined(OS_UNIX)
244 //Set new terminal color
245 printf("\033[");
246 printf("%s", color);
247 printf("m");
248
249 // Print colored text
250 printf("%s", text);
251
252 //Resets the text to default color
253 printf("\033[0m");
254 fflush(stdout);
255#endif
256}
257
258#if defined(OS_UNIX)
259
260inline int _getch() {
261 int character;
262 struct termios old_attr, new_attr;
263
264 // Backup terminal attributes
265 if (tcgetattr(STDIN_FILENO, &old_attr) == -1) {
266 fprintf(stderr, "[ERROR] Couldn't get terminal attributes\n");
267 exit(1);
268 }
269
270 // Disable echo
271 new_attr = old_attr;
272 new_attr.c_lflag &= ~(ICANON | ECHO);
273
274 // new_attr.c_lflag &= ~ISIG;
275 // new_attr.c_cc[VMIN] = 0;
276 // new_attr.c_cc[VTIME] = 0;
277
278 if (tcsetattr(STDIN_FILENO, TCSANOW, &new_attr) == -1) {
279 fprintf(stderr, "[ERROR] Couldn't set terminal attributes\n");
280 exit(1);
281 }
282
283 // Get input character
284 character = getchar();
285
286// LOG_DEBUG("%d", character);
287
288 // Restore terminal attributes
289 if (tcsetattr(STDIN_FILENO, TCSANOW, &old_attr) == -1) {
290 fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n");
291 exit(1);
292 }
293
294 return character;
295}
296#endif
297
298inline short terminal_width() {
299#if defined(OS_WINDOWS)
300 // Handle current terminal
301 HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
302 if (h_console == NULL) {
303 fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
304 exit(1);
305 }
306
307 // Get current attributes
308 CONSOLE_SCREEN_BUFFER_INFO console_info;
309 if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) {
310 fprintf(stderr, "[ERROR] Couldn't get terminal info\n");
311 exit(1);
312 }
313
314 // Return current width
315 return console_info.dwSize.X;
316#elif defined(OS_UNIX)
317 struct winsize t_size;
318
319 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &t_size) == -1) {
320 fprintf(stderr, "[ERROR] Couldn't get terminal info\n");
321 exit(1);
322 }
323
324 return (short) t_size.ws_col;
325#endif
326}
327
328inline void clear_line() {
329#if defined(OS_WINDOWS)
330 // Get current terminal width
331 short width = terminal_width();
332 if (width < 1) {
333 fprintf(stderr, "[ERROR] Size of terminal is too small\n");
334 exit(1);
335 }
336
337 // Create long empty string
338 char* empty = (char*) malloc(sizeof (char) * width);
339 memset(empty, ' ', width);
340 empty[width - 1] = '\0';
341
342 // Clear line
343 printf("\r%s\r", empty);
344
345 // Free line
346 free(empty);
347#elif defined(OS_UNIX)
348 printf("\033[2K\r");
349#endif
350}
351
352inline void set_cursor_x(short x) {
353#if defined(OS_WINDOWS)
354 HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
355 if (h_console == NULL) {
356 fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
357 exit(1);
358 }
359
360 // Create position
361 COORD xy;
362 xy.X = x - 1;
363 xy.Y = get_cursor_y();
364
365 // Set cursor position
366 if (SetConsoleCursorPosition(h_console, xy) == 0) {
367 fprintf(stderr, "[ERROR] Couldn't set terminal cursor position\n");
368 exit(1);
369 }
370#elif defined(OS_UNIX)
371 printf("\033[%d;%dH", get_cursor_y(), x);
372#endif
373}
374
375inline short get_cursor_y() {
376#if defined(OS_WINDOWS)
377 HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
378 if (h_console == NULL) {
379 fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
380 exit(1);
381 }
382
383 // Get terminal info
384 CONSOLE_SCREEN_BUFFER_INFO console_info;
385 if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) {
386 fprintf(stderr, "[ERROR] Couldn't get terminal Y position\n");
387 exit(1);
388 }
389
390 // Return Y position
391 return console_info.dwCursorPosition.Y;
392#elif defined(OS_UNIX)
393 struct termios old_attr, new_attr;
394 char ch, buf[30] = {0};
395 int i = 0, pow = 1, y = 0;
396
397 // Backup terminal attributes
398 if (tcgetattr(STDIN_FILENO, &new_attr) == -1) {
399 fprintf(stderr, "[ERROR] Couldn't get terminal attributes\n");
400 exit(1);
401 }
402
403 // Disable echo
404 old_attr = new_attr;
405 old_attr.c_lflag &= ~(ICANON | ECHO);
406 if (tcsetattr(STDIN_FILENO, TCSANOW, &old_attr) == -1) {
407 fprintf(stderr, "[ERROR] Couldn't set terminal attributes\n");
408 exit(1);
409 }
410
411 // Get info about cursor
412 if (write(STDOUT_FILENO, "\033[6n", 4) != 4) {
413 fprintf(stderr, "[ERROR] Couldn't get cursor information\n");
414 exit(1);
415 }
416
417 // Get ^[[{this};1R value
418
419 for (ch = 0; ch != 'R'; i++) {
420 if (read(STDIN_FILENO, &ch, 1) != 1) {
421 fprintf(stderr, "[ERROR] Couldn't read cursor information");
422 exit(1);
423 }
424 buf[i] = ch;
425 }
426
427 i -= 2;
428 while (buf[i] != ';') {
429 i -= 1;
430 }
431
432 i -= 1;
433 while (buf[i] != '[') {
434 y = y + (buf[i] - '0') * pow;
435 pow *= 10;
436 i -= 1;
437 }
438
439 // Reset attributes
440 if (tcsetattr(0, TCSANOW, &new_attr) == -1) {
441 fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n");
442 exit(1);
443 }
444
445 return (short) y;
446#endif
447}
448
449#endif //AUTOCOMPLETE_H
void clear_line()
void color_print(const char *text, COLOR_TYPE color)
void set_cursor_x(short x)
short get_cursor_y()
int contain_chars(const char *str, const char *chars)
short terminal_width()
int is_ignore_key(int ch)