favourites can be configured for different history files.
A-n moves to favourites if not in history.
config file can now have "doc:FOO" sections for docs that don't have
file names.
A bug in doc:EOL is fixed
Signed-off-by: NeilBrown <neil@brown.name>
decides. YES.
- [X] in xcb, find-file draws result a pixel high, then moves done
when cursor moves
-- [ ] favourites... I want some favourite documents that are easy to
+- [X] favourites... I want some favourite documents that are easy to
find, favourite directories, favourite make or shell commands.
Maybe that are found by moving "down" in history? Maybe alt-*
flags them?
"nm" already gets me to the email project quickly. Getting back
is not so easy.
Maybe some docs could be marked "project" and so be easy to find?
+ Maybe docs could be associated with a session, and are preferred
+ for select-new-document operations.
- [ ] path completion in shell command. If cannot find look for '/'
following punctuation (=) and try there.
- [ ] resolve shift-left vs shift_left distinction - add a "fixed" suffix?
I want. Maybe have a menu of choices to remind me
- [ ] Teach render-lines to pad spaces to left/right align text
- [ ] revise *Welcome* page
+- [ ] history doesn't restore initial default (or empty) string when
+ returning after excursion into history or favourites.
+- [ ] how can we save history-favourites back to a config file?
### Small
while ((ch = doc_next(f, m)) != WEOF &&
!is_eol(ch))
;
- rpt -= 1;
+ if (ch != WEOF)
+ rpt -= 1;
}
while (rpt < 0 && ch != WEOF) {
while ((ch = doc_prev(f, m)) != WEOF &&
!is_eol(ch))
;
- rpt += 1;
+ if (ch != WEOF)
+ rpt += 1;
}
- if (!one_more && is_eol(ch)) {
- if (RPT_NUM(ci) > 0)
- doc_prev(f, m);
- else if (RPT_NUM(ci) < 0)
- doc_next(f, m);
+ if (!one_more) {
+ if (is_eol(ch)) {
+ if (RPT_NUM(ci) > 0)
+ doc_prev(f, m);
+ else if (RPT_NUM(ci) < 0)
+ doc_next(f, m);
+ }
+ if (ch == WEOF) {
+ if (RPT_NUM(ci) > 0)
+ rpt -= 1;
+ else if (RPT_NUM(ci) < 0)
+ rpt += 1;
+ }
}
return rpt == 0 ? 1 : Efalse;
}
if (!val || !val[0])
return Enoarg;
/* Append the string to the attr. It attr doesn't
- * exists, string first char of val and use that.
+ * exists, strip first char of val and use that.
*/
old = attr_find(p->attrs, attr);
if (!old) {
struct pane *root safe;
struct trigger {
char *path safe;
+ enum {
+ TRIGGER_FILE,
+ TRIGGER_DOC,
+ } type;
struct attrset *attrs;
struct trigger *next;
} *triggers, *last_trigger;
};
-static void add_trigger(struct config_data *cd safe, char *path safe,
+static void add_trigger(struct config_data *cd safe, unsigned int type,
+ char *path safe,
char *name safe, char *val safe, int append)
{
struct trigger *t = cd->last_trigger;
return;
name += 10;
}
- if (!t || strcmp(t->path, path) != 0) {
+ if (!t || strcmp(t->path, path) != 0 || t->type != type) {
alloc(t, pane);
t->path = strdup(path);
t->next = NULL;
+ t->type = type;
if (cd->last_trigger)
cd->last_trigger->next = t;
else
attr_set_str(&t->attrs, name, val);
}
-static void config_file(char *path safe, struct pane *doc safe,
+static void config_file(char *path safe, unsigned int type,
+ struct pane *doc safe,
struct config_data *cd safe)
{
struct trigger *t;
for (t = cd->triggers; t; t = t->next)
- if (glob_match(t->path, path)) {
+ if (t->type == type && glob_match(t->path, path)) {
const char *val;
const char *k = "";
while ((k = attr_get_next_key(t->attrs, k, -1, &val)) != NULL) {
}
if (strstarts(section, "file:")) {
- add_trigger(cd, section+5, name, value, append);
+ add_trigger(cd, TRIGGER_FILE, section+5, name, value, append);
+ return;
+ }
+ if (strstarts(section, "doc:")) {
+ add_trigger(cd, TRIGGER_DOC, section+4, name, value, append);
return;
}
}
{
struct config_data *cd = container_of(ci->comm, struct config_data, appeared);
char *path = pane_attr_get(ci->focus, "filename");
- if (!path)
+ if (path) {
+ config_file(path, TRIGGER_FILE, ci->focus, cd);
return Efallthrough;
- config_file(path, ci->focus, cd);
+ }
+ path = pane_attr_get(ci->focus, "doc-name");
+ if (path) {
+ config_file(path, TRIGGER_DOC, ci->focus, cd);
+ return Efallthrough;
+ }
return Efallthrough;
}
* :A-s - sets next line as search start and repeats.
* :Enter - drops out of search mode
* Anything else drops out of search mode and repeats the command as normal
+ *
+ * For each history document a number of "favourites" can be registered.
+ * These are accessed by moving "down" from the start point rather than "up"
+ * for previous history items.
*/
#include <unistd.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <ctype.h>
char *prompt;
struct buf search;
int search_back;
+ int favourite;
struct si {
int i;
struct si *prev;
{
struct history_info *hi = ci->home->data;
const char *suffix = ksuffix(ci, "K:A-");
+ char attr[sizeof("doc:favourite-") + 12];
if (!hi->history)
return Enoarg;
- if (*suffix == 'p')
- call("doc:EOL", hi->history, -2);
- else
- call("doc:EOL", hi->history, 1, NULL, NULL, 1);
-
+ if (*suffix == 'p') {
+ if (hi->favourite > 0)
+ hi->favourite -= 1;
+ else
+ call("doc:EOL", hi->history, -2);
+ } else {
+ if (hi->favourite > 0)
+ hi->favourite += 1;
+ else if (call("doc:EOL", hi->history, 1, NULL, NULL, 1) < 0)
+ hi->favourite = 1;
+ }
+ while (hi->favourite > 0) {
+ char *f;
+ struct mark *m;
+ snprintf(attr, sizeof(attr)-1, "doc:favourite-%d",
+ hi->favourite);
+ f = pane_attr_get(hi->history, attr);
+ if (!f) {
+ hi->favourite -= 1;
+ continue;
+ }
+ call("doc:EOL", ci->focus, -1);
+ m = mark_at_point(ci->focus, NULL, MARK_UNGROUPED);
+ call("doc:EOL", ci->focus, 1, m);
+ call("Replace", ci->focus, 1, m, f);
+ mark_free(m);
+ return 1;
+ }
recall_line(ci->home, ci->focus, *suffix == 'n');
return 1;
}
+DEF_CMD(history_add_favourite)
+{
+ struct history_info *hi = ci->home->data;
+ char attr[sizeof("doc:favourite-") + 10];
+ int f;
+ char *l;
+
+ if (!hi->history)
+ return 1;
+ l = call_ret(strsave, "doc:get-str", ci->focus);
+ if (!l || !*l)
+ return 1;
+ for (f = 1; f < 100; f++) {
+ snprintf(attr, sizeof(attr)-1, "doc:favourite-%d", f);
+ if (pane_attr_get(hi->history, attr))
+ continue;
+ call("doc:set:", hi->history, 0, NULL, l, 0, NULL, attr);
+ call("Message:modal", ci->focus, 0, NULL, "Added as favourite");
+ break;
+ }
+ return 1;
+}
+
DEF_CMD(history_attach)
{
struct history_info *hi;
key_add(history_map, "K:A-n", &history_move);
key_add(history_map, "K:A-r", &history_search);
key_add(history_map, "K:A-s", &history_search);
+ key_add(history_map, "K:A-*", &history_add_favourite);
key_add_prefix(history_map, "K:History-search-", &history_search_again);
key_add_prefix(history_map, "K:History-search:",
&history_search_retry);