### Trivial
-= [ ] :Cx-< and :Cx-> to shift view left and right and disable wrap
+- [X] :Cx-< and :Cx-> to shift view left and right and disable wrap
- [ ] Unify edlib_timing and pane_too_long ??
- [X] If an email part doesn't end with newline, last character is swallowed.
- [X] What is rule for doc:content? Does the mark move and get passed
- [ ] sort the command names for command-completion?
Currently lines are inserted into buffer. I need to store in
an array first, then qsort()
+- [ ] Do I want a 'truncated' marker at start/end of line when not
+ wrapping, and does the '\' go away properly when I start shifting.
+- [ ] change shift left/right to work in characters rather than pixels
- [ ] filename completion should ignore uninteresting files like ".o"
Maybe use .gitignore, or have config module understand that.
- [ ] maybe alt-, does c-x` if that is the recent search?
N2_undo, /* Last command was 'undo' too */
N2_close_others,/* Last command was close-other, just a 1 can repeat */
N2_runmacro, /* Last command was CX-e, just an 'e' can repeat */
+ N2_shift, /* Laset command was CX-< or CX-> */
};
static inline int N2(const struct cmd_info *ci safe)
{
return 1;
}
+DEF_CMD(emacs_shift)
+{
+ int rpt = ci->num;
+ int shift;
+
+ shift = pane_attr_get_int(ci->focus, "shift-left", -1);
+ if (strcmp(ci->key, "K:CX->") == 0 || strcmp(ci->key, "K->") == 0)
+ rpt = -rpt;
+ if (rpt == NO_NUMERIC) {
+ if (shift < 0)
+ shift = 0;
+ else
+ shift += 8;
+ } else if (rpt == -NO_NUMERIC) {
+ if (shift >= 8)
+ shift -= 8;
+ else if (shift > 0)
+ shift = 0;
+ else
+ shift = -1;
+ } else if (rpt >= 0) {
+ if (shift < 0)
+ shift = 0;
+ shift += rpt;
+ } else {
+ if (shift > 0 && shift + rpt < 0)
+ shift = 0;
+ else
+ shift += rpt;
+ }
+ if (shift < 0)
+ attr_set_str(&ci->focus->attrs, "shift-left", "");
+ else
+ attr_set_int(&ci->focus->attrs, "shift-left", shift);
+ call("view:changed", ci->focus);
+ call("Mode:set-num2", ci->focus, N2_shift);
+ call("Message:modal", ci->focus, 0, NULL, "Type < or > to shift again");
+ return 1;
+}
+
+DEF_CMD(emacs_shift_again)
+{
+ if (N2(ci) != N2_shift)
+ return emacs_insert_func(ci);
+ else
+ return emacs_shift_func(ci);
+}
+
DEF_CMD(emacs_curs_pos)
{
struct mark *c;
key_add(m, "K:CX-=", &emacs_curs_pos);
key_add(m, "K:A-=", &emacs_word_count);
+ key_add(m, "K:CX-<", &emacs_shift);
+ key_add(m, "K:CX->", &emacs_shift);
+ key_add(m, "K-<", &emacs_shift_again);
+ key_add(m, "K->", &emacs_shift_again);
+
key_add(m, "K:C-S", &emacs_start_search);
key_add(m, "K:C-R", &emacs_start_search);
key_add(m, "K:A-%", &emacs_start_search);
short i_moved; /* I moved cursor, so don't clear
* target
*/
- int do_wrap;
+ short do_wrap;
+ short shift_locked;
short shift_left;
short shift_left_last_refresh;
struct mark *header;
* call_render_line() will have created 'end' if it didn't exist.
*/
- rl->shift_left = 0;
+ if (!rl->shift_locked)
+ rl->shift_left = 0;
/* ->cy is top of cursor, we want to measure from bottom */
if (start->mdata) {
curs_width = pane_attr_get_int(
start->mdata, "curs_width", 1);
- while (!rl->do_wrap && curs_width > 0 &&
+ while (!rl->do_wrap && !rl->shift_locked && curs_width > 0 &&
hp->cx + curs_width >= p->w) {
int shift = 8 * curs_width;
if (shift > hp->cx)
if (ci->str && strcmp(ci->str, "shift_left") == 0) {
char ret[10];
- if (rl->do_wrap)
+ if (rl->do_wrap && !rl->shift_locked)
return comm_call(ci->comm2, "cb", ci->focus,
0, NULL, "-1");
snprintf(ret, sizeof(ret), "%d", rl->shift_left);
/* This loop is fragile and sometimes spins. So ensure we
* never loop more than 1000 times.
*/
- if (pm && !rl->do_wrap && shifts++ < 1000) {
+ if (pm && !rl->do_wrap && !rl->shift_locked && shifts++ < 1000) {
int prefix_len;
int curs_width;
/* Need to check if side-shift is needed on cursor line */
bool refresh_all = False;
char *hdr;
char *a;
+ int shift;
a = pane_attr_get(focus, "render-wrap");
if (rl->do_wrap != (!a || strcmp(a, "yes") ==0)) {
refresh_all = True;
}
+ shift = pane_attr_get_int(focus, "shift-left", -1);
+ if (shift >= 0) {
+ if (rl->shift_left != shift)
+ refresh_all = True;
+
+ rl->shift_left = shift;
+ rl->shift_locked = 1;
+ } else {
+ if (rl->shift_locked)
+ refresh_all = True;
+ rl->shift_locked = 0;
+ }
+ if (refresh_all) {
+ struct mark *v;
+ for (v = vmark_first(focus, rl->typenum, p);
+ (v && v->mdata) ; v = vmark_next(v))
+ pane_damaged(v->mdata, DAMAGED_REFRESH);
+ }
+
rl->margin = pane_attr_get_int(focus, "render-vmargin", 0);
if (rl->margin >= p->h/2)
rl->margin = p->h/2;