isocline 1.0.9 → 1.1.0
raw patch · 14 files changed
+71/−35 lines, 14 filesdep ~bytestringdep ~textPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: bytestring, text
API changes (from Hackage documentation)
- System.Console.Isocline: instance GHC.Show.Show System.Console.Isocline.Completion
+ System.Console.Isocline: instance GHC.Internal.Show.Show System.Console.Isocline.Completion
Files
- haskell/System/Console/Isocline.hs +3/−1
- include/isocline.h +2/−2
- isocline.cabal +9/−9
- src/common.c +3/−3
- src/completers.c +11/−3
- src/completions.c +2/−1
- src/editline.c +5/−5
- src/editline_completion.c +2/−1
- src/editline_help.c +1/−1
- src/isocline.c +6/−1
- src/stringbuf.c +23/−6
- src/stringbuf.h +2/−0
- src/term.c +1/−1
- src/tty.h +1/−1
haskell/System/Console/Isocline.hs view
@@ -605,7 +605,9 @@ = let len = (fromIntegral clen :: Int) in if (len <= 0) then return (cbool False) else do s <- peekCStringLen (cstr,len) - return (if null s then (cbool False) else cbool (isInClass (head s))) + return (cbool (case s of + "" -> False + (c:_) -> isInClass c)) in do ic_make_charclassfun charClassFun
include/isocline.h view
@@ -44,8 +44,8 @@ /// The basic readline interface. /// \{ -/// Isocline version: 102 = 1.0.2.-#define IC_VERSION (104) +/// Isocline version: 110 = 1.1.0.+#define IC_VERSION (110) /// Read input from the user using rich editing abilities.
isocline.cabal view
@@ -1,14 +1,14 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.6.+-- This file has been generated from package.yaml by hpack version 0.39.1. -- -- see: https://github.com/sol/hpack name: isocline-version: 1.0.9+version: 1.1.0 synopsis: A portable alternative to GNU Readline description:  A Haskell wrapper around the [Isocline C library](https://github.com/daanx/isocline#readme) which can provide an alternative to GNU Readline. (The Isocline library is included whole and there are no runtime dependencies).- Please see the [readme](https://github.com/daanx/isocline/haskell#readme) on GitHub for more information.+ Please see the [readme](https://github.com/daanx/isocline#readme) on GitHub for more information. category: console homepage: https://github.com/daanx/isocline#readme bug-reports: https://github.com/daanx/isocline/issues@@ -67,8 +67,8 @@ src/isocline.c build-depends: base >=3.0 && <5- , bytestring- , text+ , bytestring >=0.9 && <2+ , text >=0.1 && <3 default-language: Haskell2010 executable example@@ -79,9 +79,9 @@ test build-depends: base >=3.0 && <5- , bytestring+ , bytestring >=0.9 && <2 , isocline- , text+ , text >=0.1 && <3 default-language: Haskell2010 test-suite test-example@@ -93,7 +93,7 @@ test build-depends: base >=3.0 && <5- , bytestring+ , bytestring >=0.9 && <2 , isocline- , text+ , text >=0.1 && <3 default-language: Haskell2010
src/common.c view
@@ -231,11 +231,11 @@ if (count != NULL) *count = 2; return (((c0 & 0x1F) << 6) | (s[1] & 0x3F)); }- // 3 bytes: reject overlong and surrogate halves+ // 3 byte encoding; reject overlong and utf-16 surrogate halves (0xD800 - 0xDFFF) else if (len >= 3 && ((c0 == 0xE0 && s[1] >= 0xA0 && s[1] <= 0xBF && utf8_is_cont(s[2])) ||- (c0 >= 0xE1 && c0 <= 0xEC && utf8_is_cont(s[1]) && utf8_is_cont(s[2])) - ))+ (c0 >= 0xE1 && c0 <= 0xEF && c0 != 0xED && utf8_is_cont(s[1]) && utf8_is_cont(s[2])) ||+ (c0 == 0xED && s[1] > 0x80 && s[1] <= 0x9F && utf8_is_cont(s[2])))) { if (count != NULL) *count = 3; return (((c0 & 0x0F) << 12) | ((unicode_t)(s[1] & 0x3F) << 6) | (s[2] & 0x3F));
src/completers.c view
@@ -23,6 +23,7 @@ typedef struct word_closure_s { long delete_before_adjust; void* prev_env;+ const char* postfix; // content after the cursor ic_completion_fun_t* prev_complete; } word_closure_t; @@ -31,7 +32,8 @@ static bool token_add_completion_ex(ic_env_t* env, void* closure, const char* replacement, const char* display, const char* help, long delete_before, long delete_after) { word_closure_t* wenv = (word_closure_t*)(closure); // call the previous completer with an adjusted delete-before- return (*wenv->prev_complete)(env, wenv->prev_env, replacement, display, help, wenv->delete_before_adjust + delete_before, delete_after);+ const long delete_after_adjust = (long)ic_count_end_overlap(replacement, wenv->postfix);+ return (*wenv->prev_complete)(env, wenv->prev_env, replacement, display, help, wenv->delete_before_adjust + delete_before, delete_after_adjust + delete_after); } @@ -61,6 +63,7 @@ wenv.delete_before_adjust = (long)(len - pos); wenv.prev_complete = cenv->complete; wenv.prev_env = cenv->env;+ wenv.postfix = cenv->input + cenv->cursor; cenv->complete = &token_add_completion_ex; cenv->closure = &wenv; @@ -77,6 +80,8 @@ // Quoted word completion (with escape characters) //------------------------------------------------------------- ++ // free variables for word completion typedef struct qword_closure_s { char escape_char;@@ -84,6 +89,7 @@ long delete_before_adjust; stringbuf_t* sbuf; void* prev_env;+ const char* postfix; // follows the current input position ic_is_char_class_fun_t* is_word_char; ic_completion_fun_t* prev_complete; } qword_closure_t;@@ -112,7 +118,8 @@ } } // and call the previous completion function- return (*wenv->prev_complete)( env, wenv->prev_env, sbuf_string(wenv->sbuf), display, help, wenv->delete_before_adjust + delete_before, delete_after ); + const long delete_after_adjust = (long)ic_count_end_overlap(sbuf_string(wenv->sbuf), wenv->postfix);+ return (*wenv->prev_complete)( env, wenv->prev_env, sbuf_string(wenv->sbuf), display, help, wenv->delete_before_adjust + delete_before, delete_after_adjust + delete_after ); } @@ -236,7 +243,8 @@ wenv.escape_char = escape_char; wenv.delete_before_adjust = (long)(len - pos); wenv.prev_complete = cenv->complete;- wenv.prev_env = cenv->env;+ wenv.prev_env = cenv->env;+ wenv.postfix = cenv->input + cenv->cursor; wenv.sbuf = sbuf_new(cenv->env->mem); if (wenv.sbuf == NULL) { mem_free(cenv->env->mem, word); return; } cenv->complete = &qword_add_completion_ex;
src/completions.c view
@@ -175,7 +175,7 @@ ssize_t n = cm->delete_before + cm->delete_after; if (ic_strlen(cm->replacement) == n && strncmp(sbuf_string_at(sbuf,start), cm->replacement, to_size_t(n)) == 0) { // no changes- return -1;+ return start + n; } else { sbuf_delete_from_to( sbuf, start, pos + cm->delete_after );@@ -244,6 +244,7 @@ memset(&cprefix,0,sizeof(cprefix)); cprefix.delete_before = delete_before; cprefix.replacement = prefix;+ cprefix.delete_after = ic_count_end_overlap(prefix, sbuf_string_at(sbuf, pos)); ssize_t newpos = completion_apply( &cprefix, sbuf, pos); if (newpos < 0) return newpos;
src/editline.c view
@@ -938,17 +938,17 @@ if (eb.pos == 0 && editor_pos_is_at_end(&eb)) break; // ctrl+D on empty quits with NULL edit_delete_char(env,&eb); // otherwise it is like delete } - else if (c == KEY_CTRL_C || c == KEY_EVENT_STOP) {- break; // ctrl+C or STOP event quits with NULL+ else if (c == KEY_EVENT_STOP) {+ break; // STOP event quits with NULL } else if (c == KEY_ESC) { if (eb.pos == 0 && editor_pos_is_at_end(&eb)) break; // ESC on empty input returns with empty input edit_delete_all(env,&eb); // otherwise delete the current input // edit_delete_line(env,&eb); // otherwise delete the current line }- else if (c == KEY_BELL /* ^G */) {+ else if (c == KEY_BELL /* ^G */ || c == KEY_CTRL_C) { edit_delete_all(env,&eb);- break; // ctrl+G cancels (and returns empty input)+ break; // ctrl+G or ctrl+c cancels (and returns empty input) } // Editing Operations@@ -1112,7 +1112,7 @@ // save result char* res; - if ((c == KEY_CTRL_D && sbuf_len(eb.input) == 0) || c == KEY_CTRL_C || c == KEY_EVENT_STOP) {+ if ((c == KEY_CTRL_D && sbuf_len(eb.input) == 0) || c == KEY_EVENT_STOP) { res = NULL; } else if (!tty_is_utf8(env->tty)) {
src/editline_completion.c view
@@ -261,8 +261,9 @@ if (!autotab) { term_beep(env->term); } } else if (count == 1) {+ ssize_t old_pos = eb->pos; // complete if only one match - if (edit_complete(env,eb,0 /*idx*/) && env->complete_autotab) {+ if (edit_complete(env,eb,0 /*idx*/) && env->complete_autotab && eb->pos > old_pos) { tty_code_pushback(env->tty,KEY_EVENT_AUTOTAB); } }
src/editline_help.c view
@@ -95,7 +95,7 @@ static const char* help_initial = "[ic-info]"- "Isocline v1.0, copyright (c) 2021 Daan Leijen.\n"+ "Isocline v1.1, copyright (c) 2021-2026 Daan Leijen.\n" "This is free software; you can redistribute it and/or\n" "modify it under the terms of the MIT License.\n" "See <[url]https://github.com/daanx/isocline[/url]> for further information.\n"
src/isocline.c view
@@ -13,7 +13,12 @@ // $ gcc -c src/isocline.c //------------------------------------------------------------- #if !defined(IC_SEPARATE_OBJS)-# define _CRT_SECURE_NO_WARNINGS // for msvc+# ifndef _CRT_NONSTDC_NO_WARNINGS+# define _CRT_NONSTDC_NO_WARNINGS // for msvc+# endif+# ifndef _CRT_SECURE_NO_WARNINGS+# define _CRT_SECURE_NO_WARNINGS // for msvc+# endif # define _XOPEN_SOURCE 700 // for wcwidth # define _DEFAULT_SOURCE // ensure usleep stays visible with _XOPEN_SOURCE >= 700 # include "attr.c"
src/stringbuf.c view
@@ -679,8 +679,9 @@ } ic_private stringbuf_t* sbuf_split_at( stringbuf_t* sb, ssize_t pos ) {+ if (pos < 0) return NULL; stringbuf_t* res = sbuf_new(sb->mem);- if (res==NULL || pos < 0) return NULL;+ if (res==NULL) return NULL; if (pos < sb->count) { sbuf_append_n(res, sb->buf + pos, sb->count - pos); sb->count = pos;@@ -889,6 +890,27 @@ return s; } +++static int ic_strncmp(const char* s1, const char* s2, ssize_t n) {+ return strncmp(s1, s2, to_size_t(n));+}++ic_private ssize_t ic_count_end_overlap(const char* s, const char* postfix) {+ if (s==NULL || postfix==NULL) return 0;+ const ssize_t slen = ic_strlen(s);+ for (ssize_t count = ic_strlen(postfix); count > 0; count--) {+ if (count <= slen) {+ if (ic_strncmp(&s[slen - count], postfix, count) == 0) {+ return count;+ }+ }+ }+ return 0;+}+++ //------------------------------------------------------------- // String helpers //-------------------------------------------------------------@@ -1000,11 +1022,6 @@ i += next; } return (long)(i - pos);-}---static int ic_strncmp(const char* s1, const char* s2, ssize_t n) {- return strncmp(s1, s2, to_size_t(n)); } // Convenience: Does this match the specified token?
src/stringbuf.h view
@@ -69,6 +69,8 @@ ic_private ssize_t sbuf_find_ws_word_start( stringbuf_t* sbuf, ssize_t pos ); ic_private ssize_t sbuf_find_ws_word_end( stringbuf_t* sbuf, ssize_t pos ); +ic_private ssize_t ic_count_end_overlap(const char* s, const char* postfix);+ // parse a decimal ic_private bool ic_atoz(const char* s, ssize_t* i); // parse two decimals separated by a semicolon
src/term.c view
@@ -1031,7 +1031,7 @@ #if __APPLE__ // otherwise use OSC 4 escape sequence query if (tty_start_raw(term->tty)) {- for(ssize_t i = 0; i < 16; i++) {+ for(int i = 0; i < 16; i++) { uint32_t color; if (!term_esc_query_color_raw(term, i, &color)) break; debug_msg("term ansi color %d: 0x%06x\n", i, color);
src/tty.h view
@@ -152,7 +152,7 @@ #define KEY_CTRL_END (WITH_CTRL(KEY_END)) #define KEY_CTRL_DEL (WITH_CTRL(KEY_DEL)) #define KEY_CTRL_PAGEUP (WITH_CTRL(KEY_PAGEUP))-#define KEY_CTRL_PAGEDOWN (WITH_CTRL(KEY_PAGEDOWN)))+#define KEY_CTRL_PAGEDOWN (WITH_CTRL(KEY_PAGEDOWN)) #define KEY_CTRL_INS (WITH_CTRL(KEY_INS)) #define KEY_SHIFT_TAB (WITH_SHIFT(KEY_TAB))