Syntax highlighting and comment
This commit is contained in:
+84
-10
@@ -9,25 +9,46 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern struct editorConfig E;
|
||||
|
||||
char *file_completion(const char *path) {
|
||||
/**
|
||||
* @file input.c
|
||||
* @brief Input handling module for the Beluga text editor
|
||||
* @details Manages user input processing, key bindings, cursor movement, and file path completion
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Returns the first file completion match for the given path
|
||||
* @details Searches the directory containing the given path prefix and returns
|
||||
* the first file or directory entry that matches the filename prefix.
|
||||
* Appends a trailing slash for directory entries.
|
||||
* @param path The file path to complete (can be relative or absolute)
|
||||
* @return Pointer to the completed file path (dynamically allocated), or NULL if:
|
||||
* - path ends with '/' (already a directory)
|
||||
* - no matching entries found
|
||||
* - directory cannot be opened
|
||||
* @note Caller is responsible for freeing the returned string
|
||||
* @note Uses static buffer internally; may return stale pointers across calls
|
||||
*/
|
||||
const char *file_completion(const char *path) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char directory[128];
|
||||
char predict[128];
|
||||
const char *last_slash;
|
||||
int predict_len = 0;
|
||||
size_t dir_len;
|
||||
|
||||
// path is a directory
|
||||
if (path[strlen(path) - 1] == '/') {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Find dir name
|
||||
char *last_slash = strrchr(path, '/');
|
||||
last_slash = strrchr(path, '/');
|
||||
if (last_slash) {
|
||||
size_t dir_len = last_slash - path + 1; // length of dir_path
|
||||
dir_len = last_slash - path + 1; // length of dir_path
|
||||
strncpy(directory, path, dir_len);
|
||||
predict_len = strlen(path) - dir_len - 1;
|
||||
strncpy(predict, last_slash + 1, predict_len);
|
||||
@@ -44,13 +65,16 @@ char *file_completion(const char *path) {
|
||||
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (strncmp(entry->d_name, predict, predict_len) == 0) {
|
||||
static char full_path[128];
|
||||
static char full_path[512];
|
||||
snprintf(full_path, sizeof(full_path), "%s%s", directory, entry->d_name);
|
||||
|
||||
struct stat st;
|
||||
if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
strcat(full_path, "/"); // add slash for directories
|
||||
}
|
||||
closedir(dir);
|
||||
dir = NULL;
|
||||
free(entry);
|
||||
|
||||
return strdup(full_path);
|
||||
}
|
||||
@@ -59,13 +83,24 @@ char *file_completion(const char *path) {
|
||||
// Cleanup when no more entries
|
||||
closedir(dir);
|
||||
dir = NULL;
|
||||
free(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn char * editorPrompt(struct editorConfig *E, char *prompt, char bPathMode)
|
||||
* \brief Return user input in a prompt when enter is hit. */
|
||||
|
||||
* @brief Displays an interactive prompt and returns user input
|
||||
* @details Allows the user to enter text in a prompt with optional path completion
|
||||
* via Tab key. Supports backspace, delete, and escape key handling. Dynamically
|
||||
* allocates memory for the input buffer.
|
||||
* @param prompt The prompt message format string (printf-style)
|
||||
* @param placeHolder Initial text to display in the input buffer
|
||||
* @param bPathMode If non-zero, enables Tab key file path completion
|
||||
* @return Pointer to the user-entered text (dynamically allocated), or NULL if:
|
||||
* - User pressed ESC to cancel
|
||||
* - Input buffer is empty when Enter is pressed
|
||||
* @note Caller is responsible for freeing the returned string
|
||||
* @note Uses editorReadKey() for input and editorRefreshScreen() for display
|
||||
*/
|
||||
char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
size_t buf_size = 128;
|
||||
char *buf = malloc(buf_size);
|
||||
@@ -106,7 +141,9 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
}
|
||||
memset(buf, 0, 128);
|
||||
buf_len = 0;
|
||||
strcpy(buf, file_completion(path));
|
||||
char * buf_complete = (char *) file_completion(path);
|
||||
strcpy(buf, buf_complete);
|
||||
free(buf_complete);
|
||||
buf_len = strlen(buf);
|
||||
buf[buf_len] = '\0';
|
||||
|
||||
@@ -121,6 +158,17 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a key code to its string representation
|
||||
* @details Translates raw key codes (including special keys, control keys,
|
||||
* and regular characters) into human-readable string formats suitable for
|
||||
* display and keybinding configuration.
|
||||
* @param key The key code to convert
|
||||
* @return Pointer to static buffer containing the string representation.
|
||||
* Examples: "ENTER", "ARROW-UP", "CTRL-a", "TAB", "DELETE", etc.
|
||||
* @note Returns pointer to static buffer; string is overwritten on next call
|
||||
* @note Non-printable characters are formatted as "KEY-<number>"
|
||||
*/
|
||||
char *key_to_string(int key) {
|
||||
static char key_str[32];
|
||||
|
||||
@@ -187,6 +235,15 @@ char *key_to_string(int key) {
|
||||
return key_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Moves the cursor based on arrow key input
|
||||
* @details Updates cursor position (E.cursor_x, E.cursor_y) based on the given
|
||||
* key direction. Handles line wrapping and boundary conditions. Prevents cursor
|
||||
* from exceeding line lengths.
|
||||
* @param key The arrow key code (ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT)
|
||||
* @return 1 if cursor movement was valid, 0 if cursor was constrained to line boundary
|
||||
* @note Updates global editor state E
|
||||
*/
|
||||
int editorMoveCursor(int key) {
|
||||
erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
|
||||
int row_len;
|
||||
@@ -228,6 +285,15 @@ int editorMoveCursor(int key) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Executes the command bound to a key sequence
|
||||
* @details Searches the keybinding table for a matching key sequence and
|
||||
* prefix state, then evaluates the associated Lisp command.
|
||||
* @param key_sequence The string representation of the key sequence
|
||||
* @return 1 if a matching keybinding was found and executed, 0 otherwise
|
||||
* @note Updates global editor state E (prefix_state)
|
||||
* @note Uses Lisp interpreter to evaluate bound commands
|
||||
*/
|
||||
int executeKeyBind(char *key_sequence) {
|
||||
int i;
|
||||
int previous_state = 0;
|
||||
@@ -235,7 +301,7 @@ int executeKeyBind(char *key_sequence) {
|
||||
for (i = 0; i < E.number_of_keybinds; ++i) {
|
||||
if (!strcmp(key_sequence, E.key_binds[i].key_sequence)) {
|
||||
if (E.prefix_state != E.key_binds[i].prefix_id) {
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
previous_state = E.prefix_state;
|
||||
// It's a symbol, create a function call
|
||||
@@ -249,6 +315,14 @@ int executeKeyBind(char *key_sequence) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes a single keypress from the user
|
||||
* @details Reads a key, checks if it matches any registered keybinding,
|
||||
* and either executes the bound command or inserts the character. Resets
|
||||
* the quit buffer counter on successful key processing.
|
||||
* @note Updates global editor state E
|
||||
* @note Calls editorReadKey() to get input and editorInsertChar() for unbound keys
|
||||
*/
|
||||
void editorProcessKeypress() {
|
||||
int c = editorReadKey();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user