92 lines
2.4 KiB
C
Raw Normal View History

2025-01-04 08:40:31 +01:00
// Written by retoor@molodetz.nl
2025-03-16 07:36:13 +01:00
// This source code provides command-line input functionalities with autocomplete and history features using the readline library. It allows users to complete commands and manage input history.
2025-01-04 08:40:31 +01:00
// External includes:
// - <readline/readline.h>
// - <readline/history.h>
2025-03-21 03:22:19 +01:00
// - <glob.h>
2025-01-04 08:40:31 +01:00
// MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction.
2025-01-04 06:00:03 +01:00
#include <readline/readline.h>
#include <readline/history.h>
2025-01-27 19:06:59 +01:00
#include <string.h>
#include <stdbool.h>
2025-03-21 03:22:19 +01:00
#include <glob.h>
2025-01-04 06:00:03 +01:00
2025-03-03 09:39:19 +01:00
#define HISTORY_FILE ".r_history"
2025-01-04 06:00:03 +01:00
2025-01-04 08:40:31 +01:00
bool line_initialized = false;
2025-01-04 06:00:03 +01:00
2025-01-04 08:40:31 +01:00
char* line_command_generator(const char* text, int state) {
2025-03-21 03:22:19 +01:00
static int list_index, len = 0;
2025-01-04 08:40:31 +01:00
const char* commands[] = {"help", "exit", "list", "review", "refactor", "obfuscate", NULL};
2025-01-04 06:00:03 +01:00
if (!state) {
list_index = 0;
len = strlen(text);
}
while (commands[list_index]) {
2025-01-04 08:40:31 +01:00
const char* command = commands[list_index++];
2025-01-04 06:00:03 +01:00
if (strncmp(command, text, len) == 0) {
2025-01-04 08:40:31 +01:00
return strdup(command);
2025-01-04 06:00:03 +01:00
}
}
2025-01-04 08:40:31 +01:00
return NULL;
2025-01-04 06:00:03 +01:00
}
2025-03-21 03:22:19 +01:00
char* line_file_generator(const char* text, int state) {
static int list_index;
glob_t glob_result;
char pattern[1024];
if (!state) {
list_index = 0;
snprintf(pattern, sizeof(pattern), "%s*", text); // Create a pattern for glob
glob(pattern, GLOB_NOSORT, NULL, &glob_result);
}
if (list_index < glob_result.gl_pathc) {
return strdup(glob_result.gl_pathv[list_index++]);
}
globfree(&glob_result);
return NULL;
}
2025-01-04 08:40:31 +01:00
char** line_command_completion(const char* text, int start, int end) {
2025-01-04 06:00:03 +01:00
rl_attempted_completion_over = 1;
2025-03-21 03:22:19 +01:00
// Check if the input is a file path
if (start > 0 && text[0] != ' ') {
return rl_completion_matches(text, line_file_generator);
}
2025-01-04 06:00:03 +01:00
return rl_completion_matches(text, line_command_generator);
}
2025-01-04 08:40:31 +01:00
void line_init() {
if (!line_initialized) {
2025-01-04 06:00:03 +01:00
rl_attempted_completion_function = line_command_completion;
line_initialized = true;
2025-01-04 08:40:31 +01:00
read_history(HISTORY_FILE);
2025-01-04 06:00:03 +01:00
}
}
2025-01-04 08:40:31 +01:00
char* line_read(char* prefix) {
char* data = readline(prefix);
if (!(data && *data)) {
2025-03-16 07:36:13 +01:00
free(data);
2025-01-04 06:00:03 +01:00
return NULL;
}
return data;
}
2025-01-04 08:40:31 +01:00
void line_add_history(char* data) {
2025-01-04 06:00:03 +01:00
add_history(data);
write_history(HISTORY_FILE);
2025-03-21 03:22:19 +01:00
}