summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaoran S. Diao (刁浩然) <0@hairydiode.xyz>2025-09-12 22:33:39 -0700
committerHaoran S. Diao (刁浩然) <0@hairydiode.xyz>2025-09-12 22:33:39 -0700
commit9a6954f9720784bc79668bcc6456f6a3f6a0c5a1 (patch)
treec605b3dab85848841a779bc8b0f864d67464ab6f
parent9f80defcd51d2c429de55e1209dfa8f6fd22bc69 (diff)
Made it so pressing escape twice sends an escape to the IM, fixed the status
line persisting even on exit. Refactored main process exit
-rw-r--r--escape.h9
-rw-r--r--im.h7
-rw-r--r--ptyim.c40
3 files changed, 37 insertions, 19 deletions
diff --git a/escape.h b/escape.h
index 8b5f0dd..d7c54a4 100644
--- a/escape.h
+++ b/escape.h
@@ -31,6 +31,8 @@ enum esc_state {
DECSC,
DECRC,
NORMAL,
+ //escape followed by an escape, has to be user generated
+ DOUBLE_ESC,
};
//global stdin -> pty ESC state
enum esc_state in_state = NORMAL;
@@ -54,6 +56,7 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat
case C1:
case DECSC:
case DECRC:
+ case DOUBLE_ESC:
//all the sequences that have ended don't have an end
//and default to normal
case NORMAL:
@@ -91,8 +94,12 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat
}
else if (c == '8') {
state = DECSC;
+ }
+ else if (c == 0x1B) {
+ state = DOUBLE_ESC;
//deformed escape sequence
- } else {
+ }
+ else {
state = NORMAL;
}
break;
diff --git a/im.h b/im.h
index d92191c..47ae538 100644
--- a/im.h
+++ b/im.h
@@ -16,10 +16,10 @@
//the one you desire
#define BACKSPACE_KEY 0x7F
#define BACKSPACE_KEY_2 0x08
-//setting it to the actual escape character interferes with arrow keys and
-//whatnot
-//#define ESCAPE_KEY 0x1B
+//the literal escape char is only fed into the im if it is pressed twice, see
+//escape.h
#define ESCAPE_KEY '`'
+#define ESCAPE_KEY_2 0x1B
//Vertical Tab Ctrl+K
#define TOGGLE_KEY 0x0B
#define IM_KEY_RANGE_LEN 3
@@ -146,6 +146,7 @@ int update_im_state(char input, char * output) {
if (im_buffer_pos > 0) {
switch (input) {
//escape, cancels
+ case ESCAPE_KEY_2:
case ESCAPE_KEY:
clear_im_buffer();
return 0;
diff --git a/ptyim.c b/ptyim.c
index 34fdbec..eedffd3 100644
--- a/ptyim.c
+++ b/ptyim.c
@@ -16,12 +16,6 @@
#define WRITE_BUFFER_LEN 128
//determines if the master process is running
int running = 1;
-//hook for when the pty child process dies
-void childhook(int a) {
- running = 0;
- //this way it exists even if the loop is waiting for 1 last read char
- _exit(0);
-}
//pty master and slave fd
int pty_slave = -1;
int pty_master = -1;
@@ -45,6 +39,9 @@ void winchhook(int a) {
ioctl(pty_slave, TIOCSWINSZ, &sz);
}
+//child process pids
+pid_t shell_pid;
+pid_t om_pid;
//return 0 on success, -1 on error
//sets the global vars pty_master and pty_slave
int make_pty() {
@@ -88,6 +85,24 @@ void condition_stdin() {
void restore_stdin() {
tcsetattr(STDIN_FILENO,TCSANOW,&stdin_termio_bk);
}
+//main thread exit
+void exit_main() {
+ //kill shell , can not be blocked
+ kill(shell_pid, SIGKILL);
+ //exit, only the master process should reach this point
+ close(pty_master);
+ close(pty_slave);
+ restore_stdin();
+ //clears the screen so the im statusline goes away
+ write(STDIN_FILENO,"\033[2J", 4);
+ _exit(0);
+}
+//hook for when the pty child process dies
+void childhook(int a) {
+ running = 0;
+ //this way it exists even if the loop is waiting for 1 last read char
+ exit_main();
+}
int main (int argc, char * argv[], char * envp[]) {
condition_stdin();
if (make_pty() != 0) {
@@ -98,7 +113,7 @@ int main (int argc, char * argv[], char * envp[]) {
//resize interrupt handler
winchhook(0);
//forks for running bash
- pid_t shell_pid = fork();
+ shell_pid = fork();
if (shell_pid == 0) {
//shell child process
//set self to be session leader
@@ -137,7 +152,7 @@ int main (int argc, char * argv[], char * envp[]) {
} else {
//forks for read and write, master process handles im, child
//process just handles transfering pty output to stdout
- pid_t om_pid = fork();
+ om_pid = fork();
if (om_pid == 0) {
//sets the name for cleaner ps output
prctl(PR_SET_NAME, "ptyim om thread");
@@ -179,7 +194,7 @@ int main (int argc, char * argv[], char * envp[]) {
fprintf(stderr, "%c: %d\n", read_buffer[0],in_state);
//skips if the char was anything but
//normal
- if (in_state == NORMAL) {
+ if (in_state == NORMAL || in_state ==DOUBLE_ESC) {
//feeds the input char into the im state machine
char input_buffer[IM_TABLE_ENTRY_LEN+1] = {0};
int im_chars = update_im_state(read_buffer[0],
@@ -203,11 +218,6 @@ int main (int argc, char * argv[], char * envp[]) {
kill(om_pid, SIGKILL);
}
}
- //kill shell , can not be blocked
- kill(shell_pid, SIGKILL);
- //exit, only the master process should reach this point
- close(pty_master);
- close(pty_slave);
- restore_stdin();
+ exit_main();
return 0;
}