Make ANSI sequence not chopped midway
This commit is contained in:
parent
4b16733d22
commit
d3ab344b23
1 changed files with 83 additions and 16 deletions
95
ccc.c
95
ccc.c
|
@ -24,8 +24,6 @@
|
||||||
void handle_sigwinch();
|
void handle_sigwinch();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void show_help();
|
void show_help();
|
||||||
int read_key();
|
|
||||||
void resize_dimensions();
|
|
||||||
char *check_trash_dir();
|
char *check_trash_dir();
|
||||||
void change_dir(const char *buf, int selection, int ftype);
|
void change_dir(const char *buf, int selection, int ftype);
|
||||||
void mkdir_p(const char *destdir);
|
void mkdir_p(const char *destdir);
|
||||||
|
@ -49,6 +47,7 @@ void create_file();
|
||||||
void delete_files();
|
void delete_files();
|
||||||
void wpprintw(const char *fmt, ...);
|
void wpprintw(const char *fmt, ...);
|
||||||
void move_cursor(int row, int col);
|
void move_cursor(int row, int col);
|
||||||
|
int read_key();
|
||||||
int get_window_size(int *row, int *col);
|
int get_window_size(int *row, int *col);
|
||||||
void bprintf(const char *fmt, ...);
|
void bprintf(const char *fmt, ...);
|
||||||
|
|
||||||
|
@ -820,6 +819,49 @@ void list_files()
|
||||||
show_file_content();
|
show_file_content();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t get_effective_length(const char *str)
|
||||||
|
{
|
||||||
|
size_t length = 0;
|
||||||
|
bool in_ansi_sequence = false;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
if (*str == '\033') {
|
||||||
|
in_ansi_sequence = true;
|
||||||
|
} else if (in_ansi_sequence && *str == 'm') {
|
||||||
|
in_ansi_sequence = false;
|
||||||
|
} else if (!in_ansi_sequence) {
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_chunk(const char *str, size_t start, size_t end)
|
||||||
|
{
|
||||||
|
bool in_ansi_sequence = false;
|
||||||
|
size_t printed_length = 0;
|
||||||
|
|
||||||
|
for (size_t i = start; i < end; i++) {
|
||||||
|
if (str[i] == '\033') {
|
||||||
|
in_ansi_sequence = true;
|
||||||
|
}
|
||||||
|
if (in_ansi_sequence) {
|
||||||
|
putchar(str[i]);
|
||||||
|
if (str[i] == 'm') {
|
||||||
|
in_ansi_sequence = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
putchar(str[i]);
|
||||||
|
printed_length++;
|
||||||
|
if (printed_length >= (end - start)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get file content into buffer and show it to preview window
|
* Get file content into buffer and show it to preview window
|
||||||
*/
|
*/
|
||||||
|
@ -892,22 +934,47 @@ void show_file_content()
|
||||||
FILE *stream = fdopen(pipe_fd[0], "r");
|
FILE *stream = fdopen(pipe_fd[0], "r");
|
||||||
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) {
|
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) {
|
||||||
buffer[strcspn(buffer, "\n")] = 0;
|
buffer[strcspn(buffer, "\n")] = 0;
|
||||||
size_t len = strlen(buffer);
|
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
/* Print each line in chunks of `half_width` */
|
if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) {
|
||||||
while (len > 0 && row <= rows - 1) {
|
move_cursor(row++, half_width);
|
||||||
|
putchar('\n');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Length without ANSI codes */
|
||||||
|
size_t effective_len = get_effective_length(buffer);
|
||||||
|
size_t offset = 0;
|
||||||
|
while (effective_len > 0 && row <= rows - 1) {
|
||||||
move_cursor(row++, half_width);
|
move_cursor(row++, half_width);
|
||||||
|
|
||||||
/* Using all the window space on the right */
|
/* Calculate the chunk size based on effective length */
|
||||||
if (len > (cols - half_width)) {
|
size_t chunk_size = (effective_len > (cols - half_width)) ? (cols - half_width) : effective_len;
|
||||||
printf("%.*s\n", cols - half_width, buffer + offset);
|
|
||||||
offset += (cols - half_width);
|
/* Find the actual end position in the string to avoid cutting ANSI sequences */
|
||||||
len -= (cols - half_width);
|
size_t actual_end = offset;
|
||||||
} else {
|
size_t visible_count = 0;
|
||||||
printf("%s\n", buffer + offset);
|
bool in_ansi_sequence = false;
|
||||||
break;
|
|
||||||
|
while (visible_count < chunk_size && buffer[actual_end] != '\0') {
|
||||||
|
if (buffer[actual_end] == '\033') {
|
||||||
|
in_ansi_sequence = true;
|
||||||
}
|
}
|
||||||
|
if (!in_ansi_sequence) {
|
||||||
|
visible_count++;
|
||||||
|
}
|
||||||
|
if (in_ansi_sequence && buffer[actual_end] == 'm') {
|
||||||
|
in_ansi_sequence = false;
|
||||||
|
}
|
||||||
|
actual_end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the chunk from `offset` to `actual_end` */
|
||||||
|
print_chunk(buffer, offset, actual_end);
|
||||||
|
|
||||||
|
/* Update offsets based on the effective length and ANSI-aware chunk */
|
||||||
|
offset = actual_end;
|
||||||
|
effective_len -= chunk_size;
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
|
|
Loading…
Reference in a new issue