Add window-swap-states on C-x / to transpose windows (#29)

This commit is contained in:
Charlie Gordon 2024-05-20 00:29:23 +02:00 • committed by GitHub
commit b38d95345f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 9 deletions

21
TODO.md
View file

@ -2,6 +2,27 @@
# QEmacs TODO list
## Current work
* S-TAB -> untabify
* TAB and S-TAB with selected block -> indent, unindent block
* `C-x (` should restart macro learning mode
* should implement a maximum macro length and abort macro learning mode if reached
* should keep modified status when undoing past a buffer save command
* should swap buffer names in `compare-files`
* check file time and length when selecting a different buffer or running any command on the current buffer:
- if a macro is running, stop it
- prompt the user for (r) read, (i) ignore, (k) keep, (c) compare
- if not modified since save, read in separate buffer and compare.
- if difference before window start, mark and/or point, try and resync
- if modified, modified version should be kept in a separate buffer.
* add commands:
- `enlarge-window` on `C-x ^`
- `enlarge-window-horizontally` on `C-x }`
- `shrink-window` on `C-x &`
- `shrink-window-horizontally` on `C-x {`
- `resize-window` on `C-x +` (interactive resizing using `up`, `down`, `left` and `right`.)
## Documentation / Support
* improve **README.md**

88
qe.c
View file

@ -8507,27 +8507,52 @@ void do_refresh_complete(EditState *s)
}
}
void do_other_window(EditState *s)
static EditState *get_next_window(EditState *s)
{
QEmacsState *qs = s->qe_state;
if (s->next_window)
return s->next_window;
else
return qs->first_window;
}
static EditState *get_previous_window(EditState *s)
{
QEmacsState *qs = s->qe_state;
EditState *e;
e = s->next_window;
if (!e)
e = qs->first_window;
qs->active_window = e;
for (e = qs->first_window; e->next_window; e = e->next_window) {
if (e->next_window == s)
break;
}
return e;
}
static EditState **get_window_link(EditState *s)
{
QEmacsState *qs = s->qe_state;
EditState **ep = &qs->first_window;
for (;;) {
if (*ep == s)
return ep;
if (*ep == NULL)
break;
ep = &(*ep)->next_window;
}
return NULL;
}
void do_other_window(EditState *s)
{
QEmacsState *qs = s->qe_state;
qs->active_window = get_next_window(s);
}
void do_previous_window(EditState *s)
{
QEmacsState *qs = s->qe_state;
EditState *e;
for (e = qs->first_window; e->next_window != NULL; e = e->next_window) {
if (e->next_window == s)
break;
}
qs->active_window = e;
qs->active_window = get_previous_window(s);
}
/* Delete a window and try to resize other windows so that it gets
@ -8711,6 +8736,45 @@ void do_split_window(EditState *s, int prop, int side_by_side)
qs->active_window = e;
}
void do_window_swap_states(EditState *s)
{
QEmacsState *qs = s->qe_state;
uint8_t buffer[offsetof(EditState, flags) - offsetof(EditState, xleft)];
int mask = WF_POPUP | WF_MINIBUF | WF_HIDDEN | WF_POPLEFT | WF_FILELIST;
int flags;
EditState *e, *tmp, **elink, **slink;
if (s->flags & mask)
return;
/* find another suitable window */
for (e = s;;) {
e = get_previous_window(e);
if (e == s)
return;
if (!(e->flags & mask))
break;
}
/* swapping window positions and focus */
memcpy(buffer, &s->xleft, sizeof buffer);
memcpy(&s->xleft, &e->xleft, sizeof buffer);
memcpy(&e->xleft, buffer, sizeof buffer);
flags = (e->flags ^ s->flags) & (WF_RSEPARATOR | WF_MODELINE);
e->flags ^= flags;
s->flags ^= flags;
elink = get_window_link(e);
slink = get_window_link(s);
if (elink && slink) {
/* swap the windows in the list */
*elink = s;
*slink = e;
tmp = e->next_window;
e->next_window = s->next_window;
s->next_window = tmp;
}
do_refresh(s);
qs->active_window = e;
}
#ifndef CONFIG_TINY
void do_create_window(EditState *s, const char *filename, const char *layout)
{

1
qe.h
View file

@ -1395,6 +1395,7 @@ void do_refresh(EditState *s);
// should take direction argument
void do_other_window(EditState *s);
void do_previous_window(EditState *s);
void do_window_swap_states(EditState *s);
void do_delete_window(EditState *s, int force);
#define SW_STACKED 0
#define SW_SIDE_BY_SIDE 1

View file

@ -332,6 +332,9 @@ static const CmdDef basic_commands[] = {
CMD0( "previous-window", "C-x p",
"Move the focus to the previous window",
do_previous_window)
CMD0( "window-swap-states", "C-x /",
"Swap the states of the current and next windows",
do_window_swap_states)
#ifndef CONFIG_TINY
CMD1( "center-cursor", "M-C-l",
"Center the window contents at point",