Compare commits
No commits in common. "41df652b4eea9557a3acc9c3dfbd9367f15fcb67" and "abdc9d4cce617a0252097f5014095f9ceff469b5" have entirely different histories.
41df652b4e
...
abdc9d4cce
10 changed files with 4 additions and 382 deletions
8
dub.json
8
dub.json
|
@ -9,10 +9,6 @@
|
||||||
"targetPath": "bin",
|
"targetPath": "bin",
|
||||||
"targetType": "executable",
|
"targetType": "executable",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commandr": "~>1.1.0",
|
"commandr": "~>1.1.0"
|
||||||
"ncurses": "~>1.0.0"
|
}
|
||||||
},
|
|
||||||
"libs": [
|
|
||||||
"formw"
|
|
||||||
]
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"fileVersion": 1,
|
"fileVersion": 1,
|
||||||
"versions": {
|
"versions": {
|
||||||
"commandr": "1.1.0",
|
"commandr": "1.1.0"
|
||||||
"ncurses": "1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,20 +11,12 @@ int main(string[] args)
|
||||||
.add(new Command("pipe", "Чтение выходных данных на примере ip"))
|
.add(new Command("pipe", "Чтение выходных данных на примере ip"))
|
||||||
.add(new Command("spinner", "Эмуляция статуса выполнения процесса"))
|
.add(new Command("spinner", "Эмуляция статуса выполнения процесса"))
|
||||||
)
|
)
|
||||||
.add(new Command("ncurses", "Использование библиотеки ncurses")
|
|
||||||
.add(new Command("menu", "Интерактивное консольное меню"))
|
|
||||||
.add(new Command("password", "Консольное окно для ввода пароля"))
|
|
||||||
)
|
|
||||||
.parse(args);
|
.parse(args);
|
||||||
|
|
||||||
argumets
|
argumets
|
||||||
.on("shell", (shell) { shell
|
.on("shell", (shell) { shell
|
||||||
.on("pipe", (pipe) { pipeShell(); })
|
.on("pipe", (pipe) { pipeShell(); })
|
||||||
.on("spinner", (loading) { spinnerShell(); });
|
.on("spinner", (loading) { spinnerShell(); });
|
||||||
})
|
|
||||||
.on("ncurses", (ncurses) { ncurses
|
|
||||||
.on("menu", (items) { menuNcurses(); })
|
|
||||||
.on("password", (password) { passwordNcurses(); });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
# Использование библиотеки ncurses
|
|
||||||
|
|
||||||
## items
|
|
||||||
|
|
||||||
Функция `itemsList` создаёт интерактивное консольное меню с использованием библиотеки `ncurses`. Инициализирует экран, отключает эхо ввода и курсор, задаёт цветовые пары для окна и фона. Отображает список из пяти пунктов в окне с красным фоном и белым текстом, позволяя пользователю перемещаться по пунктам клавишами `UP` и `DOWN`. Выделяет текущий пункт инверсией цвета. Завершает работу по нажатию `F2`. Использует модули `std.stdio`, `std.conv`, `std.string`, `deimos.ncurses`, `deimos.form` и `core.stdc.locale`.
|
|
||||||
|
|
||||||
## password
|
|
||||||
|
|
||||||
Функция `password` создаёт консольное окно для ввода пароля с использованием библиотеки `ncurses`. Инициализирует экран, отключает эхо, задаёт цветовые пары (синий фон, красное окно) и создаёт форму с двумя полями: статический текст "Введите пароль:" и поле ввода с поддержкой регулярного выражения для валидации символов. Введённые символы отображаются как звёздочки (`*`), сохраняются в строку `password`. Поддерживает обработку `Backspace` и завершение ввода по `Enter`. По завершении выводит введённый пароль. Использует модули `std.stdio`, `std.conv`, `std.string`, `deimos.ncurses`, `deimos.form`, `core.stdc.locale`.
|
|
|
@ -1,127 +0,0 @@
|
||||||
module examples.ncurses.menu;
|
|
||||||
|
|
||||||
import std.conv; // Импорт модуля для преобразования типов
|
|
||||||
import std.string; // Импорт модуля для работы со строками
|
|
||||||
import std.stdio; // Импорт модуля для ввода-вывода
|
|
||||||
import deimos.ncurses; // Импорт библиотеки ncurses для работы с терминалом
|
|
||||||
import deimos.form; // Импорт библиотеки форм ncurses (в данном коде не используется)
|
|
||||||
import core.stdc.locale; // Импорт для работы с локализацией
|
|
||||||
|
|
||||||
// Определение констант для цветовых пар
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
COLOR_WINDOW = 1, // Идентификатор цветовой пары для окна
|
|
||||||
COLOR_BACKGROUND = 2 // Идентификатор цветовой пары для фона
|
|
||||||
}
|
|
||||||
|
|
||||||
void menuNcurses()
|
|
||||||
{
|
|
||||||
// Установка локали для корректного отображения символов (например, кириллицы)
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
// Инициализация ncurses
|
|
||||||
initscr();
|
|
||||||
|
|
||||||
// Включение режима raw (сырой ввод, без обработки специальных символов)
|
|
||||||
raw();
|
|
||||||
|
|
||||||
// Отключение эха ввода (символы не отображаются при вводе)
|
|
||||||
noecho();
|
|
||||||
|
|
||||||
// Скрытие курсора
|
|
||||||
curs_set(0);
|
|
||||||
|
|
||||||
// Инициализация цветового режима
|
|
||||||
start_color();
|
|
||||||
|
|
||||||
// Определение цветовых пар: текст/фон
|
|
||||||
init_pair(COLOR_WINDOW, COLOR_WHITE, COLOR_RED); // Белый текст на красном фоне
|
|
||||||
init_pair(COLOR_BACKGROUND, COLOR_WHITE, COLOR_BLUE); // Белый текст на синем фоне
|
|
||||||
|
|
||||||
// Получение размеров терминала (высота и ширина)
|
|
||||||
int width, height;
|
|
||||||
getmaxyx(stdscr, height, width);
|
|
||||||
|
|
||||||
// Установка фона для основного окна (stdscr) с использованием цветовой пары COLOR_BACKGROUND
|
|
||||||
bkgd(COLOR_PAIR(COLOR_BACKGROUND));
|
|
||||||
|
|
||||||
// Обновление экрана для отображения изменений
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
// Создание нового окна размером 7x16, центрированного на экране
|
|
||||||
WINDOW* win = newwin(7, 16, height / 2 - 4, width / 2 - 8);
|
|
||||||
|
|
||||||
// Включение обработки специальных клавиш (например, стрелки) для окна
|
|
||||||
keypad(win, TRUE);
|
|
||||||
|
|
||||||
// Отрисовка рамки вокруг окна
|
|
||||||
box(win, 0, 0);
|
|
||||||
|
|
||||||
// Установка фона окна с использованием цветовой пары COLOR_WINDOW
|
|
||||||
wbkgd(win, COLOR_PAIR(COLOR_WINDOW));
|
|
||||||
|
|
||||||
// Обновление окна для отображения изменений
|
|
||||||
wrefresh(win);
|
|
||||||
|
|
||||||
// Массив пунктов меню
|
|
||||||
string[] items = [
|
|
||||||
"Пункт 1", "Пункт 2", "Пункт 3", "Пункт 4",
|
|
||||||
"Пункт 5"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Индекс текущего выбранного пункта меню
|
|
||||||
int current_item = 0;
|
|
||||||
|
|
||||||
// Количество пунктов меню, преобразованное в int
|
|
||||||
int count_items = items.length.to!int;
|
|
||||||
|
|
||||||
// Переменная для хранения введенной клавиши
|
|
||||||
int ch;
|
|
||||||
|
|
||||||
// Основной цикл обработки ввода
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Обработка нажатий клавиш
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case KEY_UP: // Нажата стрелка вверх
|
|
||||||
// Переход к предыдущему пункту меню с циклическим переключением
|
|
||||||
current_item = (current_item - 1 + count_items) % count_items;
|
|
||||||
break;
|
|
||||||
case KEY_DOWN: // Нажата стрелка вниз
|
|
||||||
// Переход к следующему пункту меню с циклическим переключением
|
|
||||||
current_item = (current_item + 1) % count_items;
|
|
||||||
break;
|
|
||||||
case 10: // Нажата клавиша Enter (код 10)
|
|
||||||
case KEY_ENTER: // Альтернативный код для Enter
|
|
||||||
// Пока ничего не делает (можно добавить обработку выбора)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Игнорирование других клавиш
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Отрисовка всех пунктов меню
|
|
||||||
foreach (i, item; items)
|
|
||||||
{
|
|
||||||
// Если текущий пункт выбран, включаем инверсию цвета
|
|
||||||
if (i == current_item)
|
|
||||||
{
|
|
||||||
wattron(win, A_REVERSE); // Включение атрибута инверсии
|
|
||||||
}
|
|
||||||
// Вывод пункта меню в окне на позиции (i+1, 4)
|
|
||||||
mvwprintw(win, i.to!int + 1, 4, item.toStringz);
|
|
||||||
|
|
||||||
// Отключение инверсии цвета после вывода
|
|
||||||
wattroff(win, A_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление окна для отображения изменений
|
|
||||||
wrefresh(win);
|
|
||||||
}
|
|
||||||
// Цикл продолжается, пока не нажата клавиша F2
|
|
||||||
while ((ch = wgetch(win)) != KEY_F(2));
|
|
||||||
|
|
||||||
// Завершение работы ncurses и очистка экрана
|
|
||||||
endwin();
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
module examples.ncurses;
|
|
||||||
|
|
||||||
public import examples.ncurses.menu;
|
|
||||||
public import examples.ncurses.password;
|
|
|
@ -1,215 +0,0 @@
|
||||||
module examples.ncurses.password;
|
|
||||||
|
|
||||||
import std.conv; // Импорт модуля для преобразования типов
|
|
||||||
import std.string; // Импорт модуля для работы со строками
|
|
||||||
import std.stdio; // Импорт модуля для ввода-вывода
|
|
||||||
import deimos.ncurses; // Импорт библиотеки ncurses для работы с терминалом
|
|
||||||
import deimos.form; // Импорт библиотеки форм ncurses для создания полей ввода
|
|
||||||
import core.stdc.locale; // Импорт для работы с локализацией
|
|
||||||
|
|
||||||
// Определение констант для цветовых пар
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
COLOR_WINDOW = 1, // Идентификатор цветовой пары для окна
|
|
||||||
COLOR_BACKGROUND = 2 // Идентификатор цветовой пары для фона
|
|
||||||
}
|
|
||||||
|
|
||||||
void passwordNcurses()
|
|
||||||
{
|
|
||||||
// Установка локали для корректного отображения символов (например, кириллицы)
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
// Инициализация ncurses
|
|
||||||
initscr();
|
|
||||||
|
|
||||||
// Включение режима raw (сырой ввод, без обработки специальных символов)
|
|
||||||
raw();
|
|
||||||
|
|
||||||
// Отключение эха ввода (символы не отображаются при вводе)
|
|
||||||
noecho();
|
|
||||||
|
|
||||||
// Установка видимости курсора (2 — полностью видимый курсор)
|
|
||||||
curs_set(2);
|
|
||||||
|
|
||||||
// Инициализация цветового режима
|
|
||||||
start_color();
|
|
||||||
|
|
||||||
// Определение цветовых пар: текст/фон
|
|
||||||
init_pair(COLOR_WINDOW, COLOR_WHITE, COLOR_RED); // Белый текст на красном фоне
|
|
||||||
init_pair(COLOR_BACKGROUND, COLOR_WHITE, COLOR_BLUE); // Белый текст на синем фоне
|
|
||||||
|
|
||||||
// Получение размеров терминала (высота и ширина)
|
|
||||||
int width, height;
|
|
||||||
getmaxyx(stdscr, height, width);
|
|
||||||
|
|
||||||
// Установка фона для основного окна (stdscr) с использованием цветовой пары COLOR_BACKGROUND
|
|
||||||
bkgd(COLOR_PAIR(COLOR_BACKGROUND));
|
|
||||||
|
|
||||||
// Обновление экрана для отображения изменений
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
// Создание нового окна размером 5x44, центрированного на экране
|
|
||||||
WINDOW* win = newwin(5, 44, height / 2 - 3, width / 2 - 22);
|
|
||||||
|
|
||||||
// Включение обработки специальных клавиш (например, Backspace) для окна
|
|
||||||
keypad(win, TRUE);
|
|
||||||
|
|
||||||
// Отрисовка рамки вокруг окна
|
|
||||||
box(win, 0, 0);
|
|
||||||
|
|
||||||
// Установка фона окна с использованием цветовой пары COLOR_WINDOW
|
|
||||||
wbkgd(win, COLOR_PAIR(COLOR_WINDOW));
|
|
||||||
|
|
||||||
// Обновление окна для отображения изменений
|
|
||||||
wrefresh(win);
|
|
||||||
|
|
||||||
// Создание массива полей формы (два поля: метка и поле ввода пароля)
|
|
||||||
FIELD*[3] fields;
|
|
||||||
|
|
||||||
// Поле для статической метки "Введите пароль:"
|
|
||||||
fields[0] = new_field(1, 16, 0, 2, 0, 0);
|
|
||||||
|
|
||||||
// Поле для ввода пароля
|
|
||||||
fields[1] = new_field(1, 20, 0, 18, 0, 0);
|
|
||||||
|
|
||||||
// Завершающий нулевой указатель для массива полей
|
|
||||||
fields[2] = null;
|
|
||||||
|
|
||||||
// Установка текста метки в первом поле
|
|
||||||
set_field_buffer(fields[0], 0, "Введите пароль:");
|
|
||||||
|
|
||||||
// Настройка первого поля: видимое, публичное, автопропуск (нельзя редактировать)
|
|
||||||
set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
|
|
||||||
|
|
||||||
// Установка типа второго поля: регулярное выражение для валидации ввода
|
|
||||||
// Разрешены буквы, цифры, некоторые символы и пробелы
|
|
||||||
set_field_type(fields[1], TYPE_REGEXP, `^\**[-0-9A-Za-zА-Яа-я*,./!?%&#:$^_=+@~\]* *$`.ptr);
|
|
||||||
|
|
||||||
// Настройка второго поля: видимое, публичное, редактируемое, активно
|
|
||||||
set_field_opts(fields[1], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);
|
|
||||||
|
|
||||||
// Установка фона для первого поля (цветовая пара COLOR_WINDOW)
|
|
||||||
set_field_back(fields[0], COLOR_PAIR(COLOR_WINDOW));
|
|
||||||
|
|
||||||
// Установка фона и подчеркивания для второго поля
|
|
||||||
set_field_back(fields[1], COLOR_PAIR(COLOR_WINDOW) | A_UNDERLINE);
|
|
||||||
|
|
||||||
// Создание формы на основе массива полей
|
|
||||||
FORM* form = new_form(cast(FIELD**) fields);
|
|
||||||
|
|
||||||
// Установка основного окна для формы
|
|
||||||
set_form_win(form, win);
|
|
||||||
|
|
||||||
// Установка подокна для формы (область внутри окна для ввода)
|
|
||||||
set_form_sub(form, derwin(win, 1, 38, 2, 2));
|
|
||||||
|
|
||||||
// Отображение формы на экране
|
|
||||||
post_form(form);
|
|
||||||
|
|
||||||
// Обновление окна для отображения изменений
|
|
||||||
wrefresh(win);
|
|
||||||
|
|
||||||
// Переменная для хранения введенного пароля (в формате dstring для поддержки Unicode)
|
|
||||||
dstring password;
|
|
||||||
|
|
||||||
// Флаг для выхода из цикла ввода
|
|
||||||
bool stop = false;
|
|
||||||
|
|
||||||
// Переменная для хранения статуса операций с формой
|
|
||||||
int status;
|
|
||||||
|
|
||||||
// Переменная для хранения введенного символа
|
|
||||||
dchar ch;
|
|
||||||
|
|
||||||
// Переменная для хранения результата ввода
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// Основной цикл обработки ввода
|
|
||||||
while (!stop)
|
|
||||||
{
|
|
||||||
// Получение символа или кода клавиши из окна
|
|
||||||
ret = wget_wch(win, &ch);
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case KEY_CODE_YES: // Обработка специальных клавиш (например, Backspace)
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case KEY_BACKSPACE: // Нажата клавиша Backspace
|
|
||||||
// Удаление предыдущего символа из формы
|
|
||||||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
|
||||||
// Удаление последнего символа из строки пароля, если она не пуста
|
|
||||||
if (password.length)
|
|
||||||
password = password[0 .. $ - 1];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Игнорирование других специальных клавиш
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OK: // Обработка обычных символов
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case KEY_BACKSPACE: // Нажата клавиша Backspace (альтернативный код)
|
|
||||||
// Удаление предыдущего символа из формы
|
|
||||||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
|
||||||
// Удаление последнего символа из строки пароля, если она не пуста
|
|
||||||
if (password.length)
|
|
||||||
password = password[0 .. $ - 1];
|
|
||||||
break;
|
|
||||||
case 32: // Пробел (игнорируется)
|
|
||||||
break;
|
|
||||||
case 10: // Нажата клавиша Enter
|
|
||||||
case KEY_ENTER: // Альтернативный код для Enter
|
|
||||||
// Установка флага для выхода из цикла
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
default: // Обработка введенного символа
|
|
||||||
// Отправка символа в форму
|
|
||||||
status = form_driver_w(form, OK, ch);
|
|
||||||
if (status == OK) // Если символ принят
|
|
||||||
{
|
|
||||||
// Валидация содержимого поля
|
|
||||||
status = form_driver_w(form, KEY_CODE_YES, REQ_VALIDATION);
|
|
||||||
if (status == OK) // Если валидация прошла успешно
|
|
||||||
{
|
|
||||||
// Добавление символа в строку пароля
|
|
||||||
password ~= ch.to!dchar;
|
|
||||||
// Удаление последнего введенного символа
|
|
||||||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
|
||||||
// Замена введенного символа на '*' для маскировки
|
|
||||||
form_driver_w(form, OK, '*'.to!int);
|
|
||||||
}
|
|
||||||
else // Если валидация не прошла
|
|
||||||
{
|
|
||||||
// Удаление последнего введенного символа
|
|
||||||
status = form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Игнорирование других случаев
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Снятие формы с экрана
|
|
||||||
unpost_form(form);
|
|
||||||
|
|
||||||
// Освобождение памяти, занятой формой
|
|
||||||
free_form(form);
|
|
||||||
|
|
||||||
// Освобождение памяти, занятой полями
|
|
||||||
free_field(fields[0]);
|
|
||||||
free_field(fields[1]);
|
|
||||||
|
|
||||||
// Завершение работы ncurses и очистка экрана
|
|
||||||
endwin();
|
|
||||||
|
|
||||||
// Вывод введенного пароля в консоль
|
|
||||||
writefln("Password: %s\n", password);
|
|
||||||
}
|
|
|
@ -2,4 +2,3 @@ module examples;
|
||||||
|
|
||||||
public import examples.version_;
|
public import examples.version_;
|
||||||
public import examples.shell;
|
public import examples.shell;
|
||||||
public import examples.ncurses;
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
# Запуск команд в shell
|
|
||||||
|
|
||||||
## pipe
|
|
||||||
|
|
||||||
Функция `pipeShell` выполняет команду `ping 8.8.8.8 -c 4`, перенаправляет её стандартный вывод в программу, читает его построчно и выводит в консоль. Обрабатывает возможные ошибки с помощью блока `try-catch`. Использует модули `std.process` и `std.stdio` для работы с процессами и вывода.
|
|
||||||
|
|
||||||
## spinner
|
|
||||||
|
|
||||||
Функция `spinnerShell` создаёт анимацию спиннера в консоли, используя брайлевские символы для имитации процесса обработки. Устанавливает обработчик сигнала `Ctrl+C` для корректного завершения с восстановлением курсора. Выполняет цикл с задержкой 100 мс, отображая вращающийся символ, и завершает выполнение с выводом "Done!". Использует модули `std.stdio`, `core.thread`, `core.time` и функции C для работы с сигналами и выводом.
|
|
|
@ -1,3 +1,3 @@
|
||||||
module examples.version_;
|
module examples.version_;
|
||||||
|
|
||||||
enum examplesVersion = "0.2.0";
|
enum examplesVersion = "0.1.0";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue