mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:janet-lang/janet
This commit is contained in:
		| @@ -2,6 +2,8 @@ | |||||||
| All notable changes to this project will be documented in this file. | All notable changes to this project will be documented in this file. | ||||||
|  |  | ||||||
| ## 1.23.1 - ??? | ## 1.23.1 - ??? | ||||||
|  | - Add better support for windows console in the default shell.c for autocompletion and | ||||||
|  |   other shell-like input features. | ||||||
| - Improve default error message from `assert`. | - Improve default error message from `assert`. | ||||||
| - Add the `tabseq` macro for simpler table comprehensions. | - Add the `tabseq` macro for simpler table comprehensions. | ||||||
| - Allow setting `(dyn :task-id)` in fibers to improve context in supervisor messages. Prior to | - Allow setting `(dyn :task-id)` in fibers to improve context in supervisor messages. Prior to | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -283,7 +283,7 @@ install: $(JANET_TARGET) $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) build/janet.pc | |||||||
| 	cp $(JANET_TARGET) '$(DESTDIR)$(BINDIR)/janet' | 	cp $(JANET_TARGET) '$(DESTDIR)$(BINDIR)/janet' | ||||||
| 	mkdir -p '$(DESTDIR)$(INCLUDEDIR)/janet' | 	mkdir -p '$(DESTDIR)$(INCLUDEDIR)/janet' | ||||||
| 	cp -r build/janet.h '$(DESTDIR)$(INCLUDEDIR)/janet' | 	cp -r build/janet.h '$(DESTDIR)$(INCLUDEDIR)/janet' | ||||||
| 	ln -sf -T ./janet/janet.h '$(DESTDIR)$(INCLUDEDIR)/janet.h' | 	ln -sf -T ./janet/janet.h '$(DESTDIR)$(INCLUDEDIR)/janet.h' || true #fixme bsd | ||||||
| 	mkdir -p '$(DESTDIR)$(JANET_PATH)' | 	mkdir -p '$(DESTDIR)$(JANET_PATH)' | ||||||
| 	mkdir -p '$(DESTDIR)$(LIBDIR)' | 	mkdir -p '$(DESTDIR)$(LIBDIR)' | ||||||
| 	if test $(UNAME) = Darwin ; then \ | 	if test $(UNAME) = Darwin ; then \ | ||||||
|   | |||||||
| @@ -76,6 +76,11 @@ | |||||||
|   [name & more] |   [name & more] | ||||||
|   ~(var ,name :private ,;more)) |   ~(var ,name :private ,;more)) | ||||||
|  |  | ||||||
|  | (defmacro toggle | ||||||
|  |   "Set a value to its boolean inverse. Same as `(set value (not value))`." | ||||||
|  |   [value] | ||||||
|  |   ~(set ,value (,not ,value))) | ||||||
|  |  | ||||||
| (defn defglobal | (defn defglobal | ||||||
|   "Dynamically create a global def." |   "Dynamically create a global def." | ||||||
|   [name value] |   [name value] | ||||||
| @@ -3020,7 +3025,7 @@ | |||||||
|        :italics ["*" "*"] |        :italics ["*" "*"] | ||||||
|        :bold ["**" "**"]})) |        :bold ["**" "**"]})) | ||||||
|   (def modes @{}) |   (def modes @{}) | ||||||
|   (defn toggle [mode] |   (defn toggle-mode [mode] | ||||||
|     (def active (get modes mode)) |     (def active (get modes mode)) | ||||||
|     (def delims (get delimiters mode)) |     (def delims (get delimiters mode)) | ||||||
|     (put modes mode (not active)) |     (put modes mode (not active)) | ||||||
| @@ -3130,7 +3135,7 @@ | |||||||
|     (def token @"") |     (def token @"") | ||||||
|     (var token-length 0) |     (var token-length 0) | ||||||
|     (defn delim [mode] |     (defn delim [mode] | ||||||
|       (def d (toggle mode)) |       (def d (toggle-mode mode)) | ||||||
|       (if-not has-color (+= token-length (length d))) |       (if-not has-color (+= token-length (length d))) | ||||||
|       (buffer/push token d)) |       (buffer/push token d)) | ||||||
|     (defn endtoken [] |     (defn endtoken [] | ||||||
| @@ -3141,16 +3146,18 @@ | |||||||
|       (def b (get line i)) |       (def b (get line i)) | ||||||
|       (cond |       (cond | ||||||
|         (or (= b (chr "\n")) (= b (chr " "))) (endtoken) |         (or (= b (chr "\n")) (= b (chr " "))) (endtoken) | ||||||
|         (= b (chr `\`)) (do |  | ||||||
|                           (++ token-length) |  | ||||||
|                           (buffer/push token (get line (++ i)))) |  | ||||||
|         (= b (chr "_")) (delim :underline) |  | ||||||
|         (= b (chr "`")) (delim :code) |         (= b (chr "`")) (delim :code) | ||||||
|         (= b (chr "*")) |         (not (modes :code)) (cond | ||||||
|         (if (= (chr "*") (get line (+ i 1))) |           (= b (chr `\`)) (do | ||||||
|           (do (++ i) |                             (++ token-length) | ||||||
|             (delim :bold)) |                             (buffer/push token (get line (++ i)))) | ||||||
|           (delim :italics)) |           (= b (chr "_")) (delim :underline) | ||||||
|  |           (= b (chr "*")) | ||||||
|  |             (if (= (chr "*") (get line (+ i 1))) | ||||||
|  |               (do (++ i) | ||||||
|  |                 (delim :bold)) | ||||||
|  |               (delim :italics)) | ||||||
|  |           (do (++ token-length) (buffer/push token b))) | ||||||
|         (do (++ token-length) (buffer/push token b)))) |         (do (++ token-length) (buffer/push token b)))) | ||||||
|     (endtoken) |     (endtoken) | ||||||
|     (tuple/slice tokens)) |     (tuple/slice tokens)) | ||||||
|   | |||||||
| @@ -348,7 +348,7 @@ int32_t janet_hash(Janet x) { | |||||||
|                 hash = (int32_t)((hilo << 16) | (hilo >> 16)); |                 hash = (int32_t)((hilo << 16) | (hilo >> 16)); | ||||||
|             } else { |             } else { | ||||||
|                 /* Assuming 4 byte pointer (or smaller) */ |                 /* Assuming 4 byte pointer (or smaller) */ | ||||||
|                 ptrdiff_t diff = ((char *)janet_unwrap_pointer(x) - (char *)0); |                 uintptr_t diff = janet_unwrap_pointer(x); | ||||||
|                 uint32_t hilo = (uint32_t) diff * 2654435769u; |                 uint32_t hilo = (uint32_t) diff * 2654435769u; | ||||||
|                 hash = (int32_t)((hilo << 16) | (hilo >> 16)); |                 hash = (int32_t)((hilo << 16) | (hilo >> 16)); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -87,8 +87,30 @@ static void simpleline(JanetBuffer *buffer) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Windows */ | /* State */ | ||||||
| #if defined(JANET_WINDOWS) || defined(JANET_SIMPLE_GETLINE) |  | ||||||
|  | #ifndef JANET_SIMPLE_GETLINE | ||||||
|  | /* static state */ | ||||||
|  | #define JANET_LINE_MAX 1024 | ||||||
|  | #define JANET_MATCH_MAX 256 | ||||||
|  | #define JANET_HISTORY_MAX 100 | ||||||
|  | static JANET_THREAD_LOCAL int gbl_israwmode = 0; | ||||||
|  | static JANET_THREAD_LOCAL const char *gbl_prompt = "> "; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_plen = 2; | ||||||
|  | static JANET_THREAD_LOCAL char gbl_buf[JANET_LINE_MAX]; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_len = 0; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_pos = 0; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_cols = 80; | ||||||
|  | static JANET_THREAD_LOCAL char *gbl_history[JANET_HISTORY_MAX]; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_history_count = 0; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_historyi = 0; | ||||||
|  | static JANET_THREAD_LOCAL JanetByteView gbl_matches[JANET_MATCH_MAX]; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_match_count = 0; | ||||||
|  | static JANET_THREAD_LOCAL int gbl_lines_below = 0; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /* Fallback */ | ||||||
|  | #if defined(JANET_SIMPLE_GETLINE) | ||||||
|  |  | ||||||
| void janet_line_init() { | void janet_line_init() { | ||||||
|     ; |     ; | ||||||
| @@ -105,6 +127,80 @@ void janet_line_get(const char *p, JanetBuffer *buffer) { | |||||||
|     simpleline(buffer); |     simpleline(buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Rich implementation */ | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | /* Windows */ | ||||||
|  | #ifdef _WIN32 | ||||||
|  |  | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <io.h> | ||||||
|  |  | ||||||
|  | static void setup_console_output(void) { | ||||||
|  |     /* Enable color console on windows 10 console and utf8 output and other processing */ | ||||||
|  |     HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
|  |     DWORD dwMode = 0; | ||||||
|  |     GetConsoleMode(hOut, &dwMode); | ||||||
|  |     dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; | ||||||
|  |     SetConsoleMode(hOut, dwMode); | ||||||
|  |     SetConsoleOutputCP(65001); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Ansi terminal raw mode */ | ||||||
|  | static int rawmode(void) { | ||||||
|  |     if (gbl_israwmode) return 0; | ||||||
|  |     HANDLE hOut = GetStdHandle(STD_INPUT_HANDLE); | ||||||
|  |     DWORD dwMode = 0; | ||||||
|  |     GetConsoleMode(hOut, &dwMode); | ||||||
|  |     dwMode &= ~ENABLE_LINE_INPUT; | ||||||
|  |     dwMode &= ~ENABLE_INSERT_MODE; | ||||||
|  |     dwMode &= ~ENABLE_ECHO_INPUT; | ||||||
|  |     dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; | ||||||
|  |     dwMode &= ~ENABLE_PROCESSED_INPUT; | ||||||
|  |     if (!SetConsoleMode(hOut, dwMode)) return 1; | ||||||
|  |     gbl_israwmode = 1; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Disable raw mode */ | ||||||
|  | static void norawmode(void) { | ||||||
|  |     if (!gbl_israwmode) return; | ||||||
|  |     HANDLE hOut = GetStdHandle(STD_INPUT_HANDLE); | ||||||
|  |     DWORD dwMode = 0; | ||||||
|  |     GetConsoleMode(hOut, &dwMode); | ||||||
|  |     dwMode |= ENABLE_LINE_INPUT; | ||||||
|  |     dwMode |= ENABLE_INSERT_MODE; | ||||||
|  |     dwMode |= ENABLE_ECHO_INPUT; | ||||||
|  |     dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT; | ||||||
|  |     dwMode |= ENABLE_PROCESSED_INPUT; | ||||||
|  |     SetConsoleMode(hOut, dwMode); | ||||||
|  |     gbl_israwmode = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static long write_console(const char *bytes, size_t n) { | ||||||
|  |     DWORD nwritten = 0; | ||||||
|  |     BOOL result = WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), bytes, (DWORD) n, &nwritten, NULL); | ||||||
|  |     if (!result) return -1; /* error */ | ||||||
|  |     return (long)nwritten; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static long read_console(char *into, size_t n) { | ||||||
|  |     DWORD numread; | ||||||
|  |     BOOL result = ReadConsole(GetStdHandle(STD_INPUT_HANDLE), into, (DWORD) n, &numread, NULL); | ||||||
|  |     if (!result) return -1; /* error */ | ||||||
|  |     return (long)numread; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int check_simpleline(JanetBuffer *buffer) { | ||||||
|  |     if (!_isatty(_fileno(stdin)) || rawmode()) { | ||||||
|  |         simpleline(buffer); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Posix */ | /* Posix */ | ||||||
| #else | #else | ||||||
|  |  | ||||||
| @@ -125,24 +221,7 @@ https://github.com/antirez/linenoise/blob/master/linenoise.c | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
|  |  | ||||||
| /* static state */ |  | ||||||
| #define JANET_LINE_MAX 1024 |  | ||||||
| #define JANET_MATCH_MAX 256 |  | ||||||
| #define JANET_HISTORY_MAX 100 |  | ||||||
| static JANET_THREAD_LOCAL int gbl_israwmode = 0; |  | ||||||
| static JANET_THREAD_LOCAL const char *gbl_prompt = "> "; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_plen = 2; |  | ||||||
| static JANET_THREAD_LOCAL char gbl_buf[JANET_LINE_MAX]; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_len = 0; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_pos = 0; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_cols = 80; |  | ||||||
| static JANET_THREAD_LOCAL char *gbl_history[JANET_HISTORY_MAX]; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_history_count = 0; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_historyi = 0; |  | ||||||
| static JANET_THREAD_LOCAL struct termios gbl_termios_start; | static JANET_THREAD_LOCAL struct termios gbl_termios_start; | ||||||
| static JANET_THREAD_LOCAL JanetByteView gbl_matches[JANET_MATCH_MAX]; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_match_count = 0; |  | ||||||
| static JANET_THREAD_LOCAL int gbl_lines_below = 0; |  | ||||||
|  |  | ||||||
| /* Unsupported terminal list from linenoise */ | /* Unsupported terminal list from linenoise */ | ||||||
| static const char *badterms[] = { | static const char *badterms[] = { | ||||||
| @@ -152,15 +231,6 @@ static const char *badterms[] = { | |||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static char *sdup(const char *s) { |  | ||||||
|     size_t len = strlen(s) + 1; |  | ||||||
|     char *mem = janet_malloc(len); |  | ||||||
|     if (!mem) { |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
|     return memcpy(mem, s, len); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* Ansi terminal raw mode */ | /* Ansi terminal raw mode */ | ||||||
| static int rawmode(void) { | static int rawmode(void) { | ||||||
|     struct termios t; |     struct termios t; | ||||||
| @@ -186,13 +256,53 @@ static void norawmode(void) { | |||||||
|         gbl_israwmode = 0; |         gbl_israwmode = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int checktermsupport() { | ||||||
|  |     const char *t = getenv("TERM"); | ||||||
|  |     int i; | ||||||
|  |     if (!t) return 1; | ||||||
|  |     for (i = 0; badterms[i]; i++) | ||||||
|  |         if (!strcmp(t, badterms[i])) return 0; | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static long write_console(char *bytes, size_t n) { | ||||||
|  |     return write(STDOUT_FILENO, bytes, n); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static long read_console(char *into, size_t n) { | ||||||
|  |     return read(STDIN_FILENO, into, n); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int check_simpleline(JanetBuffer *buffer) { | ||||||
|  |     if (!isatty(STDIN_FILENO) || !checktermsupport()) { | ||||||
|  |         simpleline(buffer); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     if (rawmode()) { | ||||||
|  |         simpleline(buffer); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static char *sdup(const char *s) { | ||||||
|  |     size_t len = strlen(s) + 1; | ||||||
|  |     char *mem = janet_malloc(len); | ||||||
|  |     if (!mem) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |     return memcpy(mem, s, len); | ||||||
|  | } | ||||||
|  |  | ||||||
| static int curpos(void) { | static int curpos(void) { | ||||||
|     char buf[32]; |     char buf[32]; | ||||||
|     int cols, rows; |     int cols, rows; | ||||||
|     unsigned int i = 0; |     unsigned int i = 0; | ||||||
|     if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1; |     if (write_console("\x1b[6n", 4) != 4) return -1; | ||||||
|     while (i < sizeof(buf) - 1) { |     while (i < sizeof(buf) - 1) { | ||||||
|         if (read(STDIN_FILENO, buf + i, 1) != 1) break; |         if (read_console(buf + i, 1) != 1) break; | ||||||
|         if (buf[i] == 'R') break; |         if (buf[i] == 'R') break; | ||||||
|         i++; |         i++; | ||||||
|     } |     } | ||||||
| @@ -203,18 +313,23 @@ static int curpos(void) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static int getcols(void) { | static int getcols(void) { | ||||||
|  | #ifdef _WIN32 | ||||||
|  |     CONSOLE_SCREEN_BUFFER_INFO csbi; | ||||||
|  |     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); | ||||||
|  |     return (int)(csbi.srWindow.Right - csbi.srWindow.Left + 1); | ||||||
|  | #else | ||||||
|     struct winsize ws; |     struct winsize ws; | ||||||
|     if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { |     if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { | ||||||
|         int start, cols; |         int start, cols; | ||||||
|         start = curpos(); |         start = curpos(); | ||||||
|         if (start == -1) goto failed; |         if (start == -1) goto failed; | ||||||
|         if (write(STDOUT_FILENO, "\x1b[999C", 6) != 6) goto failed; |         if (write_console("\x1b[999C", 6) != 6) goto failed; | ||||||
|         cols = curpos(); |         cols = curpos(); | ||||||
|         if (cols == -1) goto failed; |         if (cols == -1) goto failed; | ||||||
|         if (cols > start) { |         if (cols > start) { | ||||||
|             char seq[32]; |             char seq[32]; | ||||||
|             snprintf(seq, 32, "\x1b[%dD", cols - start); |             snprintf(seq, 32, "\x1b[%dD", cols - start); | ||||||
|             if (write(STDOUT_FILENO, seq, strlen(seq)) == -1) { |             if (write_console(seq, strlen(seq)) == -1) { | ||||||
|                 exit(1); |                 exit(1); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -224,10 +339,11 @@ static int getcols(void) { | |||||||
|     } |     } | ||||||
| failed: | failed: | ||||||
|     return 80; |     return 80; | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void clear(void) { | static void clear(void) { | ||||||
|     if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0) { |     if (write_console("\x1b[H\x1b[2J", 7) <= 0) { | ||||||
|         exit(1); |         exit(1); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -259,7 +375,7 @@ static void refresh(void) { | |||||||
|     /* Move cursor to original position. */ |     /* Move cursor to original position. */ | ||||||
|     snprintf(seq, 64, "\r\x1b[%dC", (int)(_pos + gbl_plen)); |     snprintf(seq, 64, "\r\x1b[%dC", (int)(_pos + gbl_plen)); | ||||||
|     janet_buffer_push_cstring(&b, seq); |     janet_buffer_push_cstring(&b, seq); | ||||||
|     if (write(STDOUT_FILENO, b.data, b.count) == -1) { |     if (write_console(b.data, b.count) == -1) { | ||||||
|         exit(1); |         exit(1); | ||||||
|     } |     } | ||||||
|     janet_buffer_deinit(&b); |     janet_buffer_deinit(&b); | ||||||
| @@ -285,7 +401,7 @@ static int insert(char c, int draw) { | |||||||
|                 if (gbl_plen + gbl_len < gbl_cols) { |                 if (gbl_plen + gbl_len < gbl_cols) { | ||||||
|                     /* Avoid a full update of the line in the |                     /* Avoid a full update of the line in the | ||||||
|                      * trivial case. */ |                      * trivial case. */ | ||||||
|                     if (write(STDOUT_FILENO, &c, 1) == -1) return -1; |                     if (write_console(&c, 1) == -1) return -1; | ||||||
|                 } else { |                 } else { | ||||||
|                     refresh(); |                     refresh(); | ||||||
|                 } |                 } | ||||||
| @@ -312,7 +428,7 @@ static void historymove(int delta) { | |||||||
|             gbl_historyi = gbl_history_count - 1; |             gbl_historyi = gbl_history_count - 1; | ||||||
|         } |         } | ||||||
|         strncpy(gbl_buf, gbl_history[gbl_historyi], JANET_LINE_MAX - 1); |         strncpy(gbl_buf, gbl_history[gbl_historyi], JANET_LINE_MAX - 1); | ||||||
|         gbl_pos = gbl_len = strlen(gbl_buf); |         gbl_pos = gbl_len = (int) strlen(gbl_buf); | ||||||
|         gbl_buf[gbl_len] = '\0'; |         gbl_buf[gbl_len] = '\0'; | ||||||
|  |  | ||||||
|         refresh(); |         refresh(); | ||||||
| @@ -527,6 +643,7 @@ static void check_specials(JanetByteView src) { | |||||||
|     check_cmatch(src, "unquote"); |     check_cmatch(src, "unquote"); | ||||||
|     check_cmatch(src, "var"); |     check_cmatch(src, "var"); | ||||||
|     check_cmatch(src, "while"); |     check_cmatch(src, "while"); | ||||||
|  |     check_cmatch(src, "upscope"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void resolve_format(JanetTable *entry) { | static void resolve_format(JanetTable *entry) { | ||||||
| @@ -740,14 +857,14 @@ static int line() { | |||||||
|  |  | ||||||
|     addhistory(); |     addhistory(); | ||||||
|  |  | ||||||
|     if (write(STDOUT_FILENO, gbl_prompt, gbl_plen) == -1) return -1; |     if (write_console(gbl_prompt, gbl_plen) == -1) return -1; | ||||||
|     for (;;) { |     for (;;) { | ||||||
|         char c; |         char c; | ||||||
|         char seq[3]; |         char seq[3]; | ||||||
|  |  | ||||||
|         int rc; |         int rc; | ||||||
|         do { |         do { | ||||||
|             rc = read(STDIN_FILENO, &c, 1); |             rc = read_console(&c, 1); | ||||||
|         } while (rc < 0 && errno == EINTR); |         } while (rc < 0 && errno == EINTR); | ||||||
|         if (rc <= 0) return -1; |         if (rc <= 0) return -1; | ||||||
|  |  | ||||||
| @@ -764,8 +881,13 @@ static int line() { | |||||||
|                 kleft(); |                 kleft(); | ||||||
|                 break; |                 break; | ||||||
|             case 3:     /* ctrl-c */ |             case 3:     /* ctrl-c */ | ||||||
|  |                 clearlines(); | ||||||
|                 norawmode(); |                 norawmode(); | ||||||
|  | #ifdef _WIN32 | ||||||
|  |                 ExitProcess(1); | ||||||
|  | #else | ||||||
|                 kill(getpid(), SIGINT); |                 kill(getpid(), SIGINT); | ||||||
|  | #endif | ||||||
|             /* fallthrough */ |             /* fallthrough */ | ||||||
|             case 17:    /* ctrl-q */ |             case 17:    /* ctrl-q */ | ||||||
|                 gbl_cancel_current_repl_form = 1; |                 gbl_cancel_current_repl_form = 1; | ||||||
| @@ -826,23 +948,25 @@ static int line() { | |||||||
|             case 23: /* ctrl-w */ |             case 23: /* ctrl-w */ | ||||||
|                 kbackspacew(); |                 kbackspacew(); | ||||||
|                 break; |                 break; | ||||||
|  | #ifndef _WIN32 | ||||||
|             case 26: /* ctrl-z */ |             case 26: /* ctrl-z */ | ||||||
|                 norawmode(); |                 norawmode(); | ||||||
|                 kill(getpid(), SIGSTOP); |                 kill(getpid(), SIGSTOP); | ||||||
|                 rawmode(); |                 rawmode(); | ||||||
|                 refresh(); |                 refresh(); | ||||||
|                 break; |                 break; | ||||||
|  | #endif | ||||||
|             case 27:    /* escape sequence */ |             case 27:    /* escape sequence */ | ||||||
|                 /* Read the next two bytes representing the escape sequence. |                 /* Read the next two bytes representing the escape sequence. | ||||||
|                  * Use two calls to handle slow terminals returning the two |                  * Use two calls to handle slow terminals returning the two | ||||||
|                  * chars at different times. */ |                  * chars at different times. */ | ||||||
|                 if (read(STDIN_FILENO, seq, 1) == -1) break; |                 if (read_console(seq, 1) == -1) break; | ||||||
|                 /* Esc[ = Control Sequence Introducer (CSI) */ |                 /* Esc[ = Control Sequence Introducer (CSI) */ | ||||||
|                 if (seq[0] == '[') { |                 if (seq[0] == '[') { | ||||||
|                     if (read(STDIN_FILENO, seq + 1, 1) == -1) break; |                     if (read_console(seq + 1, 1) == -1) break; | ||||||
|                     if (seq[1] >= '0' && seq[1] <= '9') { |                     if (seq[1] >= '0' && seq[1] <= '9') { | ||||||
|                         /* Extended escape, read additional byte. */ |                         /* Extended escape, read additional byte. */ | ||||||
|                         if (read(STDIN_FILENO, seq + 2, 1) == -1) break; |                         if (read_console(seq + 2, 1) == -1) break; | ||||||
|                         if (seq[2] == '~') { |                         if (seq[2] == '~') { | ||||||
|                             switch (seq[1]) { |                             switch (seq[1]) { | ||||||
|                                 case '1': /* Home */ |                                 case '1': /* Home */ | ||||||
| @@ -861,7 +985,7 @@ static int line() { | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } else if (seq[0] == 'O') { |                     } else if (seq[0] == 'O') { | ||||||
|                         if (read(STDIN_FILENO, seq + 1, 1) == -1) break; |                         if (read_console(seq + 1, 1) == -1) break; | ||||||
|                         switch (seq[1]) { |                         switch (seq[1]) { | ||||||
|                             default: |                             default: | ||||||
|                                 break; |                                 break; | ||||||
| @@ -944,28 +1068,12 @@ void janet_line_deinit() { | |||||||
|     gbl_historyi = 0; |     gbl_historyi = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int checktermsupport() { |  | ||||||
|     const char *t = getenv("TERM"); |  | ||||||
|     int i; |  | ||||||
|     if (!t) return 1; |  | ||||||
|     for (i = 0; badterms[i]; i++) |  | ||||||
|         if (!strcmp(t, badterms[i])) return 0; |  | ||||||
|     return 1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void janet_line_get(const char *p, JanetBuffer *buffer) { | void janet_line_get(const char *p, JanetBuffer *buffer) { | ||||||
|     gbl_prompt = p; |     gbl_prompt = p; | ||||||
|     buffer->count = 0; |     buffer->count = 0; | ||||||
|     gbl_historyi = 0; |     gbl_historyi = 0; | ||||||
|  |     if (check_simpleline(buffer)) return; | ||||||
|     FILE *out = janet_dynfile("err", stderr); |     FILE *out = janet_dynfile("err", stderr); | ||||||
|     if (!isatty(STDIN_FILENO) || !checktermsupport()) { |  | ||||||
|         simpleline(buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     if (rawmode()) { |  | ||||||
|         simpleline(buffer); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     if (line()) { |     if (line()) { | ||||||
|         norawmode(); |         norawmode(); | ||||||
|         fputc('\n', out); |         fputc('\n', out); | ||||||
| @@ -981,6 +1089,13 @@ void janet_line_get(const char *p, JanetBuffer *buffer) { | |||||||
|     replacehistory(); |     replacehistory(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void clear_at_exit(void) { | ||||||
|  |     if (!gbl_israwmode) { | ||||||
|  |         clearlines(); | ||||||
|  |         norawmode(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -993,18 +1108,11 @@ int main(int argc, char **argv) { | |||||||
|     JanetTable *env; |     JanetTable *env; | ||||||
|  |  | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
|     /* Enable color console on windows 10 console and utf8 output. */ |     setup_console_output(); | ||||||
|     HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); |  | ||||||
|     DWORD dwMode = 0; |  | ||||||
|     GetConsoleMode(hOut, &dwMode); |  | ||||||
|     dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; |  | ||||||
|     SetConsoleMode(hOut, dwMode); |  | ||||||
|     SetConsoleOutputCP(65001); |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if !defined(JANET_WINDOWS) && !defined(JANET_SIMPLE_GETLINE) | #if !defined(JANET_SIMPLE_GETLINE) | ||||||
|     /* Try and not leave the terminal in a bad state */ |     atexit(clear_at_exit); | ||||||
|     atexit(norawmode); |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if defined(JANET_PRF) | #if defined(JANET_PRF) | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								tools/format.sh
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								tools/format.sh
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose