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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ doc/html/
*_stub.h
*.lock
history.txt
isocline.debug.txt
isocline.debug.txt
.gdb_history
history*
src/cscope.out
test/example_rc.c
4 changes: 4 additions & 0 deletions include/isocline.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ const char* ic_get_prompt_marker(void);
/// Get the current continuation prompt marker.
const char* ic_get_continuation_prompt_marker(void);

/// Disable or enable printing marker on a separate line (disabled by default).
/// Returns the previous setting.
bool ic_enable_twoline_prompt(bool enable);

/// Disable or enable multi-line input (enabled by default).
/// Returns the previous setting.
bool ic_enable_multiline( bool enable );
Expand Down
19 changes: 11 additions & 8 deletions src/editline.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ static bool editor_pos_is_at_end(editor_t* eb ) {
// Row/Column width and positioning
//-------------------------------------------------------------


static void edit_get_prompt_width( ic_env_t* env, editor_t* eb, bool in_extra, ssize_t* promptw, ssize_t* cpromptw ) {
static void edit_get_prompt_width( ic_env_t* env, editor_t* eb, bool in_extra, ssize_t* promptw, ssize_t* cpromptw) {
if (in_extra) {
*promptw = 0;
*cpromptw = 0;
Expand All @@ -137,7 +136,8 @@ static void edit_get_prompt_width( ic_env_t* env, editor_t* eb, bool in_extra, s
ssize_t textw = bbcode_column_width(env->bbcode, eb->prompt_text);
ssize_t markerw = bbcode_column_width(env->bbcode, env->prompt_marker);
ssize_t cmarkerw = bbcode_column_width(env->bbcode, env->cprompt_marker);
*promptw = markerw + textw;
*promptw = markerw;
if (!env->twoline_prompt) *promptw += textw;
*cpromptw = (env->no_multiline_indent || *promptw < cmarkerw ? cmarkerw : *promptw);
}
}
Expand All @@ -163,20 +163,22 @@ static bool edit_pos_is_at_row_end( ic_env_t* env, editor_t* eb ) {
return rc.last_on_row;
}

static void edit_write_prompt( ic_env_t* env, editor_t* eb, ssize_t row, bool in_extra ) {
static void edit_write_prompt( ic_env_t* env, editor_t* eb, ssize_t row, bool in_extra, bool marker_only) {
if (in_extra) return;
if (!env->twoline_prompt) marker_only = false;
bbcode_style_open(env->bbcode, "ic-prompt");
if (row==0) {
if (!marker_only && row==0) {
// regular prompt text
bbcode_print( env->bbcode, eb->prompt_text );
if (env->twoline_prompt) term_writeln(env->term,"");
}
else if (!env->no_multiline_indent) {
// multiline continuation indentation
// todo: cache prompt widths
ssize_t textw = bbcode_column_width(env->bbcode, eb->prompt_text );
ssize_t markerw = bbcode_column_width(env->bbcode, env->prompt_marker);
ssize_t cmarkerw = bbcode_column_width(env->bbcode, env->cprompt_marker);
if (cmarkerw < markerw + textw) {
if (!marker_only && cmarkerw < markerw + textw) {
term_write_repeat(env->term, " ", markerw + textw - cmarkerw );
}
}
Expand Down Expand Up @@ -212,7 +214,7 @@ static bool edit_refresh_rows_iter(
if (row > info->last_row) return true; // should not occur

// term_clear_line(term);
edit_write_prompt(info->env, info->eb, row, info->in_extra);
edit_write_prompt(info->env, info->eb, row, info->in_extra, true);

//' write output
if (info->attrs == NULL || (info->env->no_highlight && info->env->no_bracematch)) {
Expand Down Expand Up @@ -387,6 +389,7 @@ static void edit_clear(ic_env_t* env, editor_t* eb ) {
static void edit_clear_screen(ic_env_t* env, editor_t* eb ) {
ssize_t cur_rows = eb->cur_rows;
eb->cur_rows = term_get_height(env->term) - 1;
if (env->twoline_prompt) eb->cur_rows--;
edit_clear(env,eb);
eb->cur_rows = cur_rows;
edit_refresh(env,eb);
Expand Down Expand Up @@ -873,7 +876,7 @@ static char* edit_line( ic_env_t* env, const char* prompt_text )
}

// show prompt
edit_write_prompt(env, &eb, 0, false);
edit_write_prompt(env, &eb, 0, false, false);

// always a history entry for the current input
history_push(env->history, "");
Expand Down
2 changes: 1 addition & 1 deletion src/editline_completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static void edit_completion_menu(ic_env_t* env, editor_t* eb, bool more_availabl
rowcol_t rc;
edit_get_rowcol(env,eb,&rc);
edit_clear(env,eb);
edit_write_prompt(env,eb,0,false);
edit_write_prompt(env,eb,0,false, true);
term_writeln(env->term, "");
for(ssize_t i = 0; i < count; i++) {
const char* display = completions_get_display(env->completions, i, NULL);
Expand Down
53 changes: 27 additions & 26 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,34 @@
//-------------------------------------------------------------

struct ic_env_s {
alloc_t* mem; // potential custom allocator
ic_env_t* next; // next environment (used for proper deallocation)
term_t* term; // terminal
tty_t* tty; // keyboard (NULL if stdin is a pipe, file, etc)
completions_t* completions; // current completions
history_t* history; // edit history
bbcode_t* bbcode; // print with bbcodes
const char* prompt_marker; // the prompt marker (defaults to "> ")
const char* cprompt_marker; // prompt marker for continuation lines (defaults to `prompt_marker`)
ic_highlight_fun_t* highlighter; // highlight callback
void* highlighter_arg; // user state for the highlighter.
const char* match_braces; // matching braces, e.g "()[]{}"
const char* auto_braces; // auto insertion braces, e.g "()[]{}\"\"''"
char multiline_eol; // character used for multiline input ("\") (set to 0 to disable)
bool initialized; // are we initialized?
bool noedit; // is rich editing possible (tty != NULL)
bool singleline_only; // allow only single line editing?
bool complete_nopreview; // do not show completion preview for each selection in the completion menu?
bool complete_autotab; // try to keep completing after a completion?
alloc_t* mem; // potential custom allocator
ic_env_t* next; // next environment (used for proper deallocation)
term_t* term; // terminal
tty_t* tty; // keyboard (NULL if stdin is a pipe, file, etc)
completions_t* completions; // current completions
history_t* history; // edit history
bbcode_t* bbcode; // print with bbcodes
const char* prompt_marker; // the prompt marker (defaults to "> ")
const char* cprompt_marker; // prompt marker for continuation lines (defaults to `prompt_marker`)
ic_highlight_fun_t* highlighter; // highlight callback
void* highlighter_arg; // user state for the highlighter.
const char* match_braces; // matching braces, e.g "()[]{}"
const char* auto_braces; // auto insertion braces, e.g "()[]{}\"\"''"
char multiline_eol; // character used for multiline input ("\") (set to 0 to disable)
bool initialized; // are we initialized?
bool noedit; // is rich editing possible (tty != NULL)
bool twoline_prompt; // print marker on a separate line
bool singleline_only; // allow only single line editing?
bool complete_nopreview; // do not show completion preview for each selection in the completion menu?
bool complete_autotab; // try to keep completing after a completion?
bool no_multiline_indent; // indent continuation lines to line up under the initial prompt
bool no_help; // show short help line for history search etc.
bool no_hint; // allow hinting?
bool no_highlight; // enable highlighting?
bool no_bracematch; // enable brace matching?
bool no_autobrace; // enable automatic brace insertion?
bool no_lscolors; // use LSCOLORS/LS_COLORS to colorize file name completions?
long hint_delay; // delay before displaying a hint in milliseconds
bool no_help; // show short help line for history search etc.
bool no_hint; // allow hinting?
bool no_highlight; // enable highlighting?
bool no_bracematch; // enable brace matching?
bool no_autobrace; // enable automatic brace insertion?
bool no_lscolors; // use LSCOLORS/LS_COLORS to colorize file name completions?
long hint_delay; // delay before displaying a hint in milliseconds
};

ic_private char* ic_editline(ic_env_t* env, const char* prompt_text);
Expand Down
7 changes: 7 additions & 0 deletions src/isocline.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ ic_public void ic_set_prompt_marker( const char* prompt_marker, const char* cpro
set_prompt_marker(env, prompt_marker, cprompt_marker);
}

ic_public bool ic_enable_twoline_prompt( bool enable ) {
ic_env_t* env = ic_get_env(); if (env==NULL) return false;
bool prev = env->twoline_prompt;
env->twoline_prompt = enable;
return !prev;
}

ic_public bool ic_enable_multiline( bool enable ) {
ic_env_t* env = ic_get_env(); if (env==NULL) return false;
bool prev = env->singleline_only;
Expand Down
3 changes: 3 additions & 0 deletions test/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ int main()
// inline hinting is enabled by default
// ic_enable_hint(false);

// enable printing prompt and marker on separate lines
ic_enable_twoline_prompt(true);

// run until empty input
char* input;
while((input = ic_readline("isoclinε")) != NULL) // ctrl-d returns NULL (as well as errors)
Expand Down