From 2bacbf6257f7b5abf833cdeaa7e28cb7a327df5b Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Claes=20N=C3=A4st=C3=A9n?= <me@pekdon.net>
Date: Sun, 1 Feb 2009 16:53:51 +0100
Subject: [PATCH] Start on fish (Friendly Interactive SHell) support.
This code seems to be working good enough to give commands with fish,
however the prompt display is somewhat broken but that happens with bash
as well.
---
src/subshell.c | 32 ++++++++++++++++++++++++++------
1 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/subshell.c b/src/subshell.c
index 99cf28c..155413b 100644
a
|
b
|
static pid_t subshell_pid = 1; /* The subshell's process ID */ |
127 | 127 | static char subshell_cwd[MC_MAXPATHLEN+1]; /* One extra char for final '\n' */ |
128 | 128 | |
129 | 129 | /* Subshell type (gleaned from the SHELL environment variable, if available) */ |
130 | | static enum {BASH, TCSH, ZSH} subshell_type; |
| 130 | static enum {BASH, TCSH, ZSH, FISH} subshell_type; |
131 | 131 | |
132 | 132 | /* Flag to indicate whether the subshell is ready for next command */ |
133 | 133 | static int subshell_ready; |
… |
… |
init_subshell_child (const char *pty_name) |
251 | 251 | /* TODO: Find a way to pass initfile to TCSH and ZSH */ |
252 | 252 | case TCSH: |
253 | 253 | case ZSH: |
| 254 | case FISH: |
254 | 255 | break; |
255 | 256 | |
256 | 257 | default: |
… |
… |
init_subshell_child (const char *pty_name) |
295 | 296 | execl (shell, "zsh", "-Z", "-g", (char *) NULL); |
296 | 297 | |
297 | 298 | break; |
| 299 | case FISH: |
| 300 | execl (shell, "fish", (char *) NULL); |
| 301 | break; |
| 302 | |
298 | 303 | } |
299 | 304 | |
300 | 305 | /* If we get this far, everything failed miserably */ |
… |
… |
init_subshell (void) |
388 | 393 | subshell_type = TCSH; |
389 | 394 | else if (strstr (shell, "/bash") || getenv ("BASH")) |
390 | 395 | subshell_type = BASH; |
| 396 | else if (strstr (shell, "/fish")) |
| 397 | subshell_type = FISH; |
391 | 398 | else { |
392 | 399 | use_subshell = FALSE; |
393 | 400 | return; |
… |
… |
init_subshell (void) |
485 | 492 | "alias precmd 'echo $cwd:q >>%s;kill -STOP $$'\n", |
486 | 493 | tcsh_fifo); |
487 | 494 | break; |
| 495 | case FISH: |
| 496 | g_snprintf (precmd, sizeof (precmd), |
| 497 | "function fish_prompt ; pwd>&%d;kill -STOP %%self; end\n", |
| 498 | subshell_pipe[WRITE], subshell_pipe[WRITE]); |
| 499 | break; |
| 500 | |
488 | 501 | } |
489 | 502 | write_all (subshell_pty, precmd, strlen (precmd)); |
490 | 503 | |
… |
… |
static char * |
700 | 713 | subshell_name_quote (const char *s) |
701 | 714 | { |
702 | 715 | char *ret, *d; |
703 | | const char quote_cmd_start[] = "\"`printf \"%b\" '"; |
704 | | const char quote_cmd_end[] = "'`\""; |
| 716 | const char *quote_cmd_start, *quote_cmd_end; |
| 717 | |
| 718 | if (subshell_type == FISH) { |
| 719 | quote_cmd_start = "(printf \"%b\" '"; |
| 720 | quote_cmd_end = "')"; |
| 721 | } else { |
| 722 | quote_cmd_start = "\"`printf \"%b\" '"; |
| 723 | quote_cmd_end = "'`\""; |
| 724 | } |
705 | 725 | |
706 | 726 | /* Factor 5 because we need \, 0 and 3 other digits per character. */ |
707 | | d = ret = g_malloc (1 + (5 * strlen (s)) + (sizeof(quote_cmd_start) - 1) |
708 | | + (sizeof(quote_cmd_end) - 1)); |
| 727 | d = ret = g_malloc (1 + (5 * strlen (s)) + (strlen(quote_cmd_start)) |
| 728 | + (strlen(quote_cmd_end))); |
709 | 729 | if (!d) |
710 | 730 | return NULL; |
711 | 731 | |
… |
… |
subshell_name_quote (const char *s) |
717 | 737 | |
718 | 738 | /* Copy the beginning of the command to the buffer */ |
719 | 739 | strcpy (d, quote_cmd_start); |
720 | | d += sizeof(quote_cmd_start) - 1; |
| 740 | d += strlen(quote_cmd_start); |
721 | 741 | |
722 | 742 | /* |
723 | 743 | * Print every character except digits and letters as a backslash-escape |