commit - 6b80b8fe2cc0cb093599c913eb911d403fa51cd5
commit + e7b982f4e861abb8fc0e18b12312d9b42add0da0
blob - dc7261e95b645d1344ea53c52b40114a74bbcec4
blob + 975edd75c7fe89c41633f24ed3fe632564fb42ba
--- ChangeLog
+++ ChangeLog
+2021-07-14 Omar Polo <op@omarpolo.com>
+
+ * cmd.c (cmd_previous_completion): add previous-completion
+ (cmd_next_completion): add next-completion
+ (cmd_insert_current_candidate): add insert-current-candidate
+
+ * minibuffer.c (enter_minibuffer): support completions in minibuffer
+
2021-07-13 Omar Polo <op@omarpolo.com>
* pages.c: advertise B and F instead of C-M-b/C-M-f.
blob - 3c700286dfa06f282179020891c070f993c8960e
blob + b6ad63b2028b48b6fb393297b57713bd943c5252
--- cmd.c
+++ cmd.c
if (ministate.hist_cur != NULL)
buffer->current_line->line = ministate.hist_cur->h;
}
+
+void
+cmd_previous_completion(struct buffer *buffer)
+{
+ if (in_minibuffer != MB_COMPREAD)
+ return;
+
+ buffer = &ministate.compl.buffer;
+
+ if (buffer->current_line != NULL)
+ buffer->current_line->parent->type = LINE_COMPL;
+
+ forward_line(buffer, -1);
+
+ if (buffer->current_line != NULL)
+ buffer->current_line->parent->type = LINE_COMPL_CURRENT;
+}
+
+void
+cmd_next_completion(struct buffer *buffer)
+{
+ if (in_minibuffer != MB_COMPREAD)
+ return;
+
+ buffer = &ministate.compl.buffer;
+
+ if (buffer->current_line != NULL)
+ buffer->current_line->parent->type = LINE_COMPL;
+
+ forward_line(buffer, +1);
+
+ if (buffer->current_line != NULL)
+ buffer->current_line->parent->type = LINE_COMPL_CURRENT;
+}
+
+void
+cmd_insert_current_candidate(struct buffer *buffer)
+{
+ struct vline *vl;
+
+ if (in_minibuffer != MB_COMPREAD)
+ return;
+
+ buffer = &ministate.compl.buffer;
+ if ((vl = buffer->current_line) == NULL)
+ return;
+
+ minibuffer_taint_hist();
+ strlcpy(ministate.buf, vl->parent->line, sizeof(ministate.buf));
+ ministate.buffer.cpoff = utf8_cplen(ministate.buf);
+}
blob - 3d74f7ac5de86741073d2bd73b382a3eff8ea6c1
blob + aefb7449c00ddc4a6c2a3df0770ae08df7cb1cf8
--- cmd.h
+++ cmd.h
CMD(cmd_mini_complete_and_exit);
CMD(cmd_mini_previous_history_element);
CMD(cmd_mini_next_history_element);
+
+CMD(cmd_previous_completion);
+CMD(cmd_next_completion);
+CMD(cmd_insert_current_candidate);
blob - 0e2930df2dcc09b3a90e40d8b4abb8ebe09390eb
blob + c365fe9e8145518418848b82d609e6fb127b4286
--- defaults.c
+++ defaults.c
[LINE_PRE_START] = { "```", " " },
[LINE_PRE_CONTENT] = { "", "" },
[LINE_PRE_END] = { "```", "```" },
+
+ [LINE_COMPL] = {"", ""},
+ [LINE_COMPL_CURRENT] = {"", ""},
};
struct line_face line_faces[] = {
.pair = PPEND,
.trail_pair = PPEND_TRAIL,
},
+
+ /* minibuffer */
+ [LINE_COMPL] = {
+ .prfx_pair = PCOMPL_PRFX,
+ .pair = PCOMPL,
+ .trail_pair = PCOMPL_TRAIL,
+ },
+ [LINE_COMPL_CURRENT] = {
+ .prfx_pair = PCOMPL_CURR_PRFX,
+ .pair = PCOMPL_CURR,
+ .trail_pair = PCOMPL_CURR_TRAIL,
+ },
};
struct tab_face tab_face = {
{"pre.start", LINE_PRE_START},
{"pre", LINE_PRE_CONTENT},
{"pre.end", LINE_PRE_END},
+
+ /* minibuffer */
+ {"compl", LINE_COMPL},
+ {"compl.current", LINE_COMPL_CURRENT}
};
static struct mapping *
minibuffer_set_key("M-n", cmd_mini_next_history_element);
minibuffer_set_key("<up>", cmd_mini_previous_history_element);
minibuffer_set_key("<down>", cmd_mini_next_history_element);
+
+ minibuffer_set_key("C-p", cmd_previous_completion);
+ minibuffer_set_key("C-n", cmd_next_completion);
+ minibuffer_set_key("tab", cmd_insert_current_candidate);
}
void
line_faces[LINE_LINK].fg = COLOR_BLUE;
+ line_faces[LINE_COMPL_CURRENT].prfx_bg = COLOR_CYAN;
+ line_faces[LINE_COMPL_CURRENT].bg = COLOR_CYAN;
+ line_faces[LINE_COMPL_CURRENT].trail_bg = COLOR_CYAN;
+
load_default_keys();
}
blob - 00e7a2d4e24e1f49fbd241b3dacfecb83efeb8f1
blob + b48c7b920e5bc6656de8541757ee2a10396b029a
--- minibuffer.c
+++ minibuffer.c
recompute_completions(int add)
{
struct line *l;
+ struct vline *vl;
+ struct buffer *b;
if (in_minibuffer != MB_COMPREAD)
return;
- TAILQ_FOREACH(l, &ministate.compl.buffer.page.head, lines) {
+ b = &ministate.compl.buffer;
+ TAILQ_FOREACH(l, &b->page.head, lines) {
+ l->type = LINE_COMPL;
if (add && l->flags & L_HIDDEN)
continue;
if (strstr(l->line, ministate.buf) != NULL)
else
l->flags |= L_HIDDEN;
}
+
+ if (b->current_line == NULL)
+ b->current_line = TAILQ_FIRST(&b->head);
+ b->current_line = adjust_line(b->current_line, b);
+ vl = b->current_line;
+ if (vl != NULL)
+ vl->parent->type = LINE_COMPL_CURRENT;
}
static void
exit_minibuffer();
minibuffer_hist_save_entry();
read_cb(ministate.buf, read_data);
-}
-
-/*
- * Just like erase_buffer, but don't call free(l->line);
- */
-static inline void
-erase_compl_buffer(struct buffer *buffer)
-{
- struct line *l, *lt;
-
- empty_vlist(buffer);
-
- TAILQ_FOREACH_SAFE(l, &buffer->page.head, lines, lt) {
- TAILQ_REMOVE(&buffer->page.head, l, lines);
- /* don't free l->line! */
- free(l);
- }
}
/*
if ((l = calloc(1, sizeof(*l))) == NULL)
abort();
- l->type = LINE_TEXT;
- l->line = s;
+ l->type = LINE_COMPL;
+ if ((l->line = strdup(s)) == NULL)
+ abort();
if (TAILQ_EMPTY(&p->head))
TAILQ_INSERT_HEAD(&p->head, l, lines);
else
TAILQ_INSERT_TAIL(&p->head, l, lines);
}
+
+ if ((l = TAILQ_FIRST(&p->head)) != NULL)
+ l->type = LINE_COMPL_CURRENT;
}
void
if (in_minibuffer == MB_COMPREAD) {
ui_schedule_redraw();
- erase_compl_buffer(&ministate.compl.buffer);
-
ministate.compl.fn = complfn;
ministate.compl.data = compldata;
populate_compl_buffer(complfn, compldata);
void
exit_minibuffer(void)
{
- if (in_minibuffer == MB_COMPREAD)
+ if (in_minibuffer == MB_COMPREAD) {
+ erase_buffer(&ministate.compl.buffer);
ui_schedule_redraw();
+ }
in_minibuffer = 0;
base_map = &global_map;
blob - 6094d777443a6653c4f61e751dbf4bb4c9409bbd
blob + f0fc7fb45a971d6dedbec80dfd427aa1793b9ba6
--- telescope.1
+++ telescope.1
mini-previous-history-element
.It <down>
mini-next-history-element
+.It C-p
+previous-completion
+.It C-n
+next-completion
+.It tab
+insert-current-candidate
.El
.Sh INTERACTIVE COMMANDS
Follows the documentation for the interactive commands.
Move point one character forward.
.It Ic forward-paragraph
Move point one paragraph forward.
+.It Ic insert-current-candidate
+Copy the current selection text as minibuffer input.
.It Ic move-beginning-of-line
Move point at the beginning of the current (visual) line.
.It Ic move-end-of-line
Move point at the end of the current (visual) line.
.It Ic next-button
Move point to the next link.
+.It Ic next-completion
+Select the next completion.
.It Ic next-heading
Move point to the next heading.
.It Ic next-line
Move point to the next (visual) line, in the same column if possible.
.It Ic previous-button
Move point to the previous link.
+.It Ic previous-completion
+Select the previous completion.
.It Ic previous-heading
Move point to the previous heading.
.It Ic previous-line
blob - 567cad0aab1a5abd4a3fe1246211bc6238ee54b7
blob + 8debbe52919cb97db7f39fdfc2c43aac905d1ade
--- telescope.h
+++ telescope.h
};
enum line_type {
+ /* text/gemini */
LINE_TEXT,
LINE_LINK,
LINE_TITLE_1,
LINE_PRE_START,
LINE_PRE_CONTENT,
LINE_PRE_END,
+
+ /* minibuffer */
+ LINE_COMPL,
+ LINE_COMPL_CURRENT,
};
/* for lines: mark as hidden */
};
struct vline {
- const struct line *parent;
+ struct line *parent;
char *line;
int flags;
TAILQ_ENTRY(vline) vlines;
void erase_buffer(struct buffer *);
void empty_linelist(struct buffer*);
void empty_vlist(struct buffer*);
+int wrap_one(struct buffer *, const char *, struct line *, size_t);
int wrap_text(struct buffer*, const char*, struct line*, size_t);
int hardwrap_text(struct buffer*, struct line*, size_t);
blob - 540de79098f2017095d3d728b08ede7f01a69e79
blob + 52085730d675a0341c4c2f132d477c2585cb95c5
--- ui.c
+++ ui.c
pre_width = width;
hardwrap_text(buffer, l, pre_width);
break;
+ case LINE_COMPL:
+ case LINE_COMPL_CURRENT:
+ /*
+ * TODO: should be width, but will break the
+ * rendering. Fix when unlocking completions
+ * buffer from olivetti-mode.
+ */
+ wrap_one(buffer, prfx, l, MIN(fill_column, width));
}
if (top_orig == l && buffer->top_line == NULL) {
* until the end of the buffer; if a visible line is not found, search
* backward. Return NULL if no viable line was found.
*/
-static inline struct vline *
+struct vline *
adjust_line(struct vline *vl, struct buffer *buffer)
{
struct vline *t;
buffer->top_line = TAILQ_NEXT(buffer->top_line, vlines);
}
- goto again;
+ if (vl != NULL)
+ goto again;
}
buffer->last_line_off = buffer->line_off;
blob - 909ba81917a545d6a5e0a29aaad82c3b3ee8f1f8
blob + e93980071fcbb4244679e7aaf91b2010dd57f27d
--- ui.h
+++ ui.h
PPEND_PRFX,
PPEND_TRAIL,
+ PCOMPL_PRFX,
+ PCOMPL,
+ PCOMPL_TRAIL,
+
+ PCOMPL_CURR_PRFX,
+ PCOMPL_CURR,
+ PCOMPL_CURR_TRAIL,
+
PMODELINE,
PMINIBUF,
void lu_self_insert(void);
void lu_select(void);
void bp_select(void);
+struct vline *adjust_line(struct vline *, struct buffer *);
void vmessage(const char *, va_list);
void message(const char *, ...) __attribute__((format(printf, 1, 2)));
void start_loading_anim(struct tab *);
blob - 04dcedda1c3892437218f86acbe39043880f7986
blob + 33405b9289543ae349b444af2c524cc0a12e068d
--- wrap.c
+++ wrap.c
}
/*
+ * Similar to wrap_text, but emit only o vline.
+ */
+int
+wrap_one(struct buffer *buffer, const char *prfx, struct line *l, size_t width)
+{
+ struct vline *vl, *t;
+
+ /*
+ * be lazy: call wrap_text and then discard the continuations.
+ */
+
+ if (!wrap_text(buffer, prfx, l, width))
+ return 0;
+
+ TAILQ_FOREACH_SAFE(vl, &buffer->head, vlines, t) {
+ if (vl->flags & L_CONTINUATION) {
+ TAILQ_REMOVE(&buffer->head, vl, vlines);
+ free(vl->line);
+ free(vl);
+ }
+ }
+
+ return 1;
+}
+
+/*
* Build a list of visual line by wrapping the given line, assuming
* that when printed will have a leading prefix prfx.
*/