Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions include/isocline.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,17 @@ struct ic_completion_env_s;
/// A completion environment
typedef struct ic_completion_env_s ic_completion_env_t;

/// A comparator function passed to qsort in order to sort the completions menu.
typedef int (ic_sorter_fun_t)(const void* a, const void* b);

/// Set the function used for sorting the completion menu entries. Accepts NULL
/// to avoid sorting at all, e.g. if the user needs complex sorting that would
/// already be done on the application side.
/// @param sorter The sorter function
/// The initial sorter uses case insensitive shortlex.
void ic_set_default_sorter( ic_sorter_fun_t* sorter);


/// A completion callback that is called by isocline when tab is pressed.
/// It is passed a completion environment (containing the current input and the current cursor position),
/// the current input up-to the cursor (`prefix`)
Expand Down
13 changes: 10 additions & 3 deletions src/completions.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,22 @@ struct completions_s {
ic_completer_fun_t* completer;
void* completer_arg;
ssize_t completer_max;
ic_sorter_fun_t* sorter;
ssize_t count;
ssize_t len;
completion_t* elems;
alloc_t* mem;
};

static void default_filename_completer( ic_completion_env_t* cenv, const char* prefix );
static int default_ishortlex_sorter(const void* p1, const void* p2);

ic_private completions_t* completions_new(alloc_t* mem) {
completions_t* cms = mem_zalloc_tp(mem, completions_t);
if (cms == NULL) return NULL;
cms->mem = mem;
cms->completer = &default_filename_completer;
cms->sorter = &default_ishortlex_sorter;
return cms;
}

Expand Down Expand Up @@ -193,17 +196,21 @@ ic_private ssize_t completions_apply( completions_t* cms, ssize_t index, stringb
return completion_apply( cm, sbuf, pos );
}

ic_public void ic_set_default_sorter(ic_sorter_fun_t* sorter) {
ic_env_t* env = ic_get_env(); if (env == NULL) return;
env->completions->sorter = sorter;
}

static int completion_compare(const void* p1, const void* p2) {
static int default_ishortlex_sorter(const void* p1, const void* p2) {
if (p1 == NULL || p2 == NULL) return 0;
const completion_t* cm1 = (const completion_t*)p1;
const completion_t* cm2 = (const completion_t*)p2;
return ic_stricmp(cm1->replacement, cm2->replacement);
}

ic_private void completions_sort(completions_t* cms) {
if (cms->count <= 0) return;
qsort(cms->elems, to_size_t(cms->count), sizeof(cms->elems[0]), &completion_compare);
if (cms->count <= 0 || cms->sorter == NULL) return;
qsort(cms->elems, to_size_t(cms->count), sizeof(cms->elems[0]), cms->sorter);
}

#define IC_MAX_PREFIX (256)
Expand Down
3 changes: 3 additions & 0 deletions test/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ int main(int argc, char** argv)
// enable syntax highlighting with a highlight function
ic_set_default_highlighter(highlighter, NULL);

// completion menu sorting is enabled by default (case insensitive shortlex)
// ic_set_default_sorter(NULL);

// try to auto complete after a completion as long as the completion is unique
ic_enable_auto_tab(true );

Expand Down