[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs qe.h qeconfig.h bufed.c TODO.org charset...
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs qe.h qeconfig.h bufed.c TODO.org charset... |
Date: |
Mon, 17 Apr 2017 14:14:15 -0400 (EDT) |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 17/04/17 14:14:15
Modified files:
. : qe.h qeconfig.h bufed.c TODO.org charset.c
latex-mode.c search.c shell.c extras.c qe.c
Log message:
syntax: improve minibuffer and popup handling
- remove static state for minibuffer handling, use mode specific state
attached
to the buffer.
- remove static pointer for the popup last active window. Use new
target_window member in EditState.
- remove EditState.minibuf, replaced by WF_MINIBUF flag in
EditState.flags
- rename minibuffer commands for consistency
- remove unused global variable debug_flags
- prevent search from minibuffer
- fix toggle-full-screen refresh bug. C-x f is bound to
toggle-full-screen
and could be typed by mistake for C-x C-f, switching to full screen
mode
but with a refresh delay. This caused confusing behavior interpreted
as a
layout bug.
- make charset_ucs2le, charset_ucs2be, charset_ucs4le, charset_ucs4be
local
in charset.c
- make edit_detach() and edit_attach() local in qe.c
- redraw status and diag messages in edit_display(). This caused
display
bugs in x11 as asynchronous messages were erased by minibuffer window
refresh.
- display status messages in diag area (bottom right screen corner) if
minibuffer is active.
- force put_status message update if message starts with !
- force complete_refresh if window was resized or layout was changed
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.251&r2=1.252
http://cvs.savannah.gnu.org/viewcvs/qemacs/qeconfig.h?cvsroot=qemacs&r1=1.66&r2=1.67
http://cvs.savannah.gnu.org/viewcvs/qemacs/bufed.c?cvsroot=qemacs&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/qemacs/TODO.org?cvsroot=qemacs&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/qemacs/charset.c?cvsroot=qemacs&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/qemacs/latex-mode.c?cvsroot=qemacs&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/qemacs/search.c?cvsroot=qemacs&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.126&r2=1.127
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.68&r2=1.69
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.269&r2=1.270
Patches:
Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.251
retrieving revision 1.252
diff -u -b -r1.251 -r1.252
--- qe.h 16 Apr 2017 21:51:20 -0000 1.251
+++ qe.h 17 Apr 2017 18:14:15 -0000 1.252
@@ -147,8 +147,6 @@
extern const char str_version[];
extern const char str_credits[];
-extern int debug_flags;
-
/* low level I/O events */
void set_read_handler(int fd, void (*cb)(void *opaque), void *opaque);
void set_write_handler(int fd, void (*cb)(void *opaque), void *opaque);
@@ -725,8 +723,6 @@
extern struct QECharset charset_8859_1;
extern struct QECharset charset_utf8;
extern struct QECharset charset_vt100; /* used for the tty output */
-extern struct QECharset charset_ucs2le, charset_ucs2be;
-extern struct QECharset charset_ucs4le, charset_ucs4be;
extern struct QECharset charset_mac_roman;
typedef enum EOLType {
@@ -1340,7 +1336,6 @@
* if end of file displayed */
int y_disp; /* virtual position of the displayed text */
int x_disp[2]; /* position for LTR and RTL text resp. */
- int minibuf; /* true if single line editing */
int dump_width; /* width in binary, hex and unihex modes */
int hex_mode; /* true if we are currently editing hexa */
int unihex_mode; /* true if unihex editing (width of hex char dump) */
@@ -1374,6 +1369,7 @@
EditBuffer *last_buffer; /* for predict_switch_to_buffer */
ISearchState *isearch_state; /* active search to colorize matches */
+ EditState *target_window; /* for minibuf, popleft and popup windows */
/* mode specific info */
ModeDef *mode;
@@ -1412,6 +1408,7 @@
#define WF_RSEPARATOR 0x0004 /* right window separator */
#define WF_POPLEFT 0x0008 /* left side window */
#define WF_HIDDEN 0x0010 /* hidden window, used for temporary changes */
+#define WF_MINIBUF 0x0020 /* true if single line editing */
#define WF_FILELIST 0x1000 /* window is interactive file list */
OWNED char *prompt; /* optional window prompt, utf8 */
@@ -1946,7 +1943,7 @@
void register_completion(const char *name, CompletionFunc completion_func);
void put_status(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
void put_error(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
-void minibuffer_edit(const char *input, const char *prompt,
+void minibuffer_edit(EditState *e, const char *input, const char *prompt,
StringArray *hist, CompletionFunc completion_func,
void (*cb)(void *opaque, char *buf), void *opaque);
void command_completion(CompleteState *cp);
@@ -1995,7 +1992,6 @@
void edit_close(EditState **sp);
EditState *edit_new(EditBuffer *b,
int x1, int y1, int width, int height, int flags);
-void edit_detach(EditState *s);
EditBuffer *check_buffer(EditBuffer **sp);
EditState *check_window(EditState **sp);
int get_glyph_width(QEditScreen *screen, EditState *s, QETermStyle style, int
c);
@@ -2184,15 +2180,14 @@
const char *key_bind);
void qe_save_macros(EditState *s, EditBuffer *b);
-void edit_attach(EditState *s, EditState *e);
#define COMPLETION_TAB 0
#define COMPLETION_SPACE 1
#define COMPLETION_OTHER 2
-void do_completion(EditState *s, int type);
-void do_completion_space(EditState *s);
-void do_electric_filename(EditState *s, int key);
+void do_minibuffer_complete(EditState *s, int type);
+void do_minibuffer_complete_space(EditState *s);
+void do_minibuffer_electric(EditState *s, int key);
void minibuf_complete_scroll_up_down(EditState *s, int dir);
-void do_history(EditState *s, int dir);
+void do_minibuffer_history(EditState *s, int dir);
void do_minibuffer_get_binary(EditState *s);
void do_minibuffer_exit(EditState *s, int fabort);
void do_popup_exit(EditState *s);
Index: qeconfig.h
===================================================================
RCS file: /sources/qemacs/qemacs/qeconfig.h,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -b -r1.66 -r1.67
--- qeconfig.h 15 Apr 2017 13:10:53 -0000 1.66
+++ qeconfig.h 17 Apr 2017 18:14:15 -0000 1.67
@@ -285,9 +285,10 @@
/*---------------- Help ----------------*/
+ CMD0( KEY_CTRLH('d'), KEY_NONE,
+ "doctor", do_doctor)
CMD0( KEY_CTRLH('c'), KEY_CTRLH('k'),
"describe-key-briefly", do_describe_key_briefly)
-
CMD0( KEY_CTRLH(KEY_CTRL('h')), KEY_F1,
"help-for-help", do_help_for_help)
@@ -336,8 +337,6 @@
"exit-qemacs", do_exit_qemacs, ESi, "ui")
CMD0( KEY_CTRL('l'), KEY_NONE,
"refresh", do_refresh_complete)
- CMD0( KEY_NONE, KEY_NONE,
- "doctor", do_doctor)
CMD0( KEY_CTRLX('u'), KEY_CTRL('_'),
"undo", do_undo)
CMD0( KEY_CTRLX('r'), KEY_CTRLX(KEY_CTRL('_')),
@@ -421,23 +420,23 @@
"*" "kiui")
CMD1( KEY_RET, KEY_NONE,
"minibuffer-exit", do_minibuffer_exit, 0)
- CMD1( KEY_CTRL('g'), KEY_NONE,
+ CMD1( KEY_CTRL('g'), KEY_CTRLX(KEY_CTRL('g')),
"minibuffer-abort", do_minibuffer_exit, 1)
CMD1( KEY_CTRL('i'), KEY_NONE,
- "minibuffer-complete", do_completion, COMPLETION_TAB)
+ "minibuffer-complete", do_minibuffer_complete, COMPLETION_TAB)
/* should take numeric prefix to specify word size */
CMD0( KEY_META('='), KEY_NONE,
"minibuffer-get-binary", do_minibuffer_get_binary)
CMD0( ' ', KEY_NONE,
- "minibuffer-complete-space", do_completion_space)
+ "minibuffer-complete-space", do_minibuffer_complete_space)
CMD1( KEY_CTRL('p'), KEY_UP,
- "minibuffer-previous-history-element", do_history, -1)
+ "minibuffer-previous-history-element", do_minibuffer_history, -1)
CMD1( KEY_CTRL('n'), KEY_DOWN,
- "minibuffer-next-history-element", do_history, 1)
+ "minibuffer-next-history-element", do_minibuffer_history, 1)
CMD3( '/', KEY_NONE,
- "minibuffer-electric-slash", do_electric_filename, ESi, '/', "*v")
+ "minibuffer-electric-slash", do_minibuffer_electric, ESi, '/', "*v")
CMD3( '~', KEY_NONE,
- "minibuffer-electric-tilde", do_electric_filename, ESi, '~', "*v")
+ "minibuffer-electric-tilde", do_minibuffer_electric, ESi, '~', "*v")
CMD_DEF_END,
};
Index: bufed.c
===================================================================
RCS file: /sources/qemacs/qemacs/bufed.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- bufed.c 26 Mar 2017 15:57:24 -0000 1.44
+++ bufed.c 17 Apr 2017 18:14:15 -0000 1.45
@@ -273,7 +273,7 @@
int i;
/* ignore command from the minibuffer and popups */
- if (s->minibuf || (s->flags & WF_POPUP))
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return;
if (s->flags & WF_POPLEFT) {
Index: TODO.org
===================================================================
RCS file: /sources/qemacs/qemacs/TODO.org,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- TODO.org 15 Apr 2017 13:10:53 -0000 1.35
+++ TODO.org 17 Apr 2017 18:14:15 -0000 1.36
@@ -1,13 +1,12 @@
; TODO list for qemacs
;
; Author: Charles Gordon
-; Updated: 2017-04-11
+; Updated: 2017-04-17
* Recent bugs and ideas
-** display: fix window split bug
** basic: backspace delete hacking tabs
-** basic: prevent search inside minibuf
+** display: minibuffer and popup windows should be in a separate lists
** display: save display-width in binary and hex modes upon window change
** display: default display-width of 0 is automatic, other values are shared
between binary and hex modes
** display: hex-mode should optionally display chunks of 2, 4 or 8 bytes in
big or little endian order
@@ -132,7 +131,6 @@
count-matches, delete-matching-lines (might need recursive edit)
** search: add regex support
** search: hex-mode search strings should mix hex ut8 strings and ASCII
control char names
-** search: make isearch bindings for minibuffer
** search: handle word and case toggles matches in query-replace
** session: register session store functions
** session: save previous answers, ...
Index: charset.c
===================================================================
RCS file: /sources/qemacs/qemacs/charset.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- charset.c 16 Apr 2017 21:51:19 -0000 1.49
+++ charset.c 17 Apr 2017 18:14:15 -0000 1.50
@@ -558,6 +558,8 @@
/********************************************************/
/* UCS2/UCS4 */
+extern struct QECharset charset_ucs2le, charset_ucs2be;
+
static int probe_ucs2le(qe__unused__ QECharset *charset, const u8 *buf, int
size)
{
const uint32_t magic = (1U << '\b') | (1U << '\t') | (1U << '\f') |
@@ -833,6 +835,8 @@
2, 0, 0, 10, 0, 0, table_none, NULL, NULL,
};
+extern struct QECharset charset_ucs4le, charset_ucs4be;
+
static int probe_ucs4le(qe__unused__ QECharset *charset, const u8 *buf, int
size)
{
const uint32_t magic = (1U << '\b') | (1U << '\t') | (1U << '\f') |
Index: latex-mode.c
===================================================================
RCS file: /sources/qemacs/qemacs/latex-mode.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- latex-mode.c 23 Dec 2016 09:51:40 -0000 1.55
+++ latex-mode.c 17 Apr 2017 18:14:15 -0000 1.56
@@ -314,7 +314,7 @@
if (func->ask) {
char prompt[128];
snprintf(prompt, sizeof(prompt), "%s command: ", func->name);
- minibuffer_edit(buf, prompt, &func->history,
+ minibuffer_edit(e, buf, prompt, &func->history,
NULL /* completion */,
latex_cmd_run, func);
} else {
Index: search.c
===================================================================
RCS file: /sources/qemacs/qemacs/search.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- search.c 3 Apr 2017 08:33:57 -0000 1.13
+++ search.c 17 Apr 2017 18:14:15 -0000 1.14
@@ -529,6 +529,10 @@
EditState *e;
int flags = SEARCH_FLAG_SMARTCASE;
+ /* prevent search from minibuffer */
+ if (s->flags & WF_MINIBUF)
+ return;
+
/* stop displaying search matches on last window */
e = check_window(&is->s);
if (e) {
@@ -800,6 +804,10 @@
{
QueryReplaceState *is;
+ /* prevent replace from minibuffer */
+ if (s->flags & WF_MINIBUF)
+ return;
+
if (s->b->flags & BF_READONLY)
return;
Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -b -r1.126 -r1.127
--- shell.c 15 Apr 2017 09:39:02 -0000 1.126
+++ shell.c 17 Apr 2017 18:14:15 -0000 1.127
@@ -1669,7 +1669,7 @@
ShellState *shs;
EditBuffer *b = NULL;
- if (s->flags & WF_POPUP)
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return;
if (s->flags & WF_POPLEFT) {
Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- extras.c 16 Apr 2017 21:51:20 -0000 1.68
+++ extras.c 17 Apr 2017 18:14:15 -0000 1.69
@@ -1427,11 +1427,12 @@
eb_printf(b1, "%*s: %d, %d\n", w, "xleft, ytop", s->xleft, s->ytop);
eb_printf(b1, "%*s: %d, %d\n", w, "width, height", s->width, s->height);
eb_printf(b1, "%*s: %d, %d, %d, %d\n", w, "x1, y1, x2, y2", s->x1, s->y1,
s->x2, s->y2);
- eb_printf(b1, "%*s: %#x%s%s%s%s%s%s\n", w, "flags", s->flags,
+ eb_printf(b1, "%*s: %#x%s%s%s%s%s%s%s\n", w, "flags", s->flags,
(s->flags & WF_POPUP) ? " POPUP" : "",
(s->flags & WF_MODELINE) ? " MODELINE" : "",
(s->flags & WF_RSEPARATOR) ? " RSEPARATOR" : "",
(s->flags & WF_POPLEFT) ? " POPLEFT" : "",
+ (s->flags & WF_MINIBUF) ? " MINIBUF" : "",
(s->flags & WF_HIDDEN) ? " HIDDEN" : "",
(s->flags & WF_FILELIST) ? " FILELIST" : "");
eb_printf(b1, "%*s: %d\n", w, "offset", s->offset);
@@ -1439,7 +1440,6 @@
eb_printf(b1, "%*s: %d\n", w, "offset_bottom", s->offset_bottom);
eb_printf(b1, "%*s: %d\n", w, "y_disp", s->y_disp);
eb_printf(b1, "%*s: %d, %d\n", w, "x_disp[]", s->x_disp[0], s->x_disp[1]);
- eb_printf(b1, "%*s: %d\n", w, "minibuf", s->minibuf);
eb_printf(b1, "%*s: %d\n", w, "dump_width", s->dump_width);
eb_printf(b1, "%*s: %d\n", w, "hex_mode", s->hex_mode);
eb_printf(b1, "%*s: %d\n", w, "unihex_mode", s->unihex_mode);
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.269
retrieving revision 1.270
diff -u -b -r1.269 -r1.270
--- qe.c 16 Apr 2017 21:51:20 -0000 1.269
+++ qe.c 17 Apr 2017 18:14:15 -0000 1.270
@@ -42,8 +42,6 @@
char name[32];
} HistoryEntry;
-int debug_flags;
-
#ifdef CONFIG_INIT_CALLS
static int (*qe__initcall_first)(void) qe__init_call = NULL;
static void (*qe__exitcall_first)(void) qe__exit_call = NULL;
@@ -1032,6 +1030,7 @@
if (s->b->flags & BF_PREVIEW) {
EditState *e = find_window(s, KEY_LEFT, NULL);
if (e && (e->flags & WF_FILELIST)
+ && s->qe_state->active_window == s
&& dir < 0 && eb_at_bol(s->b, s->offset)) {
s->qe_state->active_window = e;
return;
@@ -1622,7 +1621,7 @@
struct QuoteKeyArgument *qa = opaque;
EditState *s = qa->s;
- put_status(s, "");
+ put_status(s, ""); /* erase "Quote: " message */
if (!s)
return;
@@ -2982,6 +2981,7 @@
else
s->flags |= WF_MODELINE;
qs->hide_status = qs->is_full_screen;
+ do_refresh(s);
}
void do_toggle_mode_line(EditState *s)
@@ -4150,7 +4150,7 @@
ds->style = sbuf[char_index];
}
c = eb_nextc(s->b, offset, &offset);
- if (c == '\n' && !s->minibuf) {
+ if (c == '\n' && !(s->flags & WF_MINIBUF)) {
display_eol(ds, offset0, offset);
break;
}
@@ -4680,7 +4680,7 @@
pstrcat(prompt, sizeof(prompt), es->default_input);
pstrcat(prompt, sizeof(prompt), ") ");
}
- minibuffer_edit(def_input, prompt,
+ minibuffer_edit(s, def_input, prompt,
get_history(history),
find_completion(completion_name),
arg_edit_cb, es);
@@ -4831,7 +4831,7 @@
void edit_display(QEmacsState *qs)
{
EditState *s;
- int has_popups;
+ int has_popups, has_minibuf;
int start_time, elapsed_time;
start_time = get_clock_ms();
@@ -4845,16 +4845,20 @@
/* count popups */
/* CG: maybe a separate list for popups? */
has_popups = 0;
+ has_minibuf = 0;
for (s = qs->first_window; s != NULL; s = s->next_window) {
if (s->flags & WF_POPUP) {
- has_popups = 1;
+ has_popups++;
+ }
+ if (s->flags & WF_MINIBUF) {
+ has_minibuf++;
}
}
/* refresh normal windows and minibuf with popup kludge */
for (s = qs->first_window; s != NULL; s = s->next_window) {
if (!(s->flags & WF_POPUP) &&
- (s->minibuf || !has_popups || qs->complete_refresh)) {
+ ((s->flags & WF_MINIBUF) || !has_popups || qs->complete_refresh)) {
window_display(s);
}
}
@@ -4869,6 +4873,24 @@
}
}
+ /* Redraw status and diag messages */
+ if (*qs->status_shadow || *qs->diag_shadow) {
+ int width = qs->screen->width;
+ int height = qs->status_height;
+ int x = 0, y = qs->screen->height - height;
+
+ if (*qs->status_shadow && !has_minibuf) {
+ print_at_byte(qs->screen, x, y, width, height,
+ qs->status_shadow, QE_STYLE_STATUS);
+ }
+ if (*qs->diag_shadow) {
+ int w = strlen(qs->diag_shadow) + 1;
+ w *= get_glyph_width(qs->screen, NULL, QE_STYLE_STATUS, '0');
+ print_at_byte(qs->screen, x + width - w, y, w, height,
+ qs->diag_shadow, QE_STYLE_STATUS);
+ }
+ }
+
elapsed_time = get_clock_ms() - start_time;
if (elapsed_time >= 100)
put_status(s, "|edit_display: %dms", elapsed_time);
@@ -5151,6 +5173,7 @@
CmdDef *d;
char buf1[128];
buf_t outbuf, *out;
+ int len;
if (qs->defining_macro && !qs->executing_macro) {
macro_add_key(key);
@@ -5176,10 +5199,8 @@
c->keys[c->nb_keys++] = key;
s = qs->active_window;
- if (!s->minibuf) {
- put_status(s, " ");
+ put_status(s, " "); /* Erase pending keystrokes and message */
dpy_flush(&global_screen);
- }
/* Special case for escape: we transform it as meta so
that unix users are happy ! */
@@ -5287,11 +5308,8 @@
}
next:
/* display key pressed */
- if (!s->minibuf) {
- int len;
-
len = strlen(c->buf);
- if (len >= 1)
+ if (len > 0)
c->buf[len-1] = ' ';
/* Should print argument if any in a more readable way */
out = buf_attach(&outbuf, c->buf, sizeof(c->buf), len);
@@ -5299,7 +5317,6 @@
buf_put_byte(out, '-');
put_status(s, "~%s", c->buf);
dpy_flush(&global_screen);
- }
}
/* Print a utf-8 encoded buffer as unicode */
@@ -5368,26 +5385,35 @@
eb_format_message(qs, "*errors*", buf);
}
-void put_status(qe__unused__ EditState *s, const char *fmt, ...)
+void put_status(EditState *s, const char *fmt, ...)
{
- /* CG: s is not used and may be NULL! */
- QEmacsState *qs = &qe_state;
+ /* XXX: s may be NULL! */
+ QEmacsState *qs = s ? s->qe_state : &qe_state;
char buf[MAX_SCREEN_WIDTH];
const char *p;
va_list ap;
int silent = 0;
int diag = 0;
+ int force = 0;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
+ if (qs->active_window && (qs->active_window->flags & WF_MINIBUF)) {
+ /* display status messages in diag area if minibuffer is active */
+ diag = 1;
+ }
+
for (p = buf;; p++) {
if (*p == '|') {
diag = 1;
} else
if (*p == '~') {
silent = 1;
+ } else
+ if (*p == '!') {
+ force = 1;
} else {
break;
}
@@ -5396,31 +5422,30 @@
if (!qs->screen->dpy.dpy_probe) {
eb_format_message(qs, "*errors*", p);
} else {
+ int width = qs->screen->width;
+ int height = qs->status_height;
+ int x = 0, y = qs->screen->height - height;
+
if (diag) {
- if (!strequal(p, qs->diag_shadow)) {
+ if (force || !strequal(p, qs->diag_shadow)) {
/* right align display and overwrite last diag message */
int w = strlen(qs->diag_shadow);
w = snprintf(qs->diag_shadow, sizeof(qs->diag_shadow),
"%*s", w, p) + 1;
w *= get_glyph_width(qs->screen, NULL, QE_STYLE_STATUS, '0');
- print_at_byte(qs->screen,
- qs->screen->width - w,
- qs->screen->height - qs->status_height,
- qs->screen->width - w, qs->status_height,
+ print_at_byte(qs->screen, x + width - w, y, w, height,
qs->diag_shadow, QE_STYLE_STATUS);
pstrcpy(qs->diag_shadow, sizeof(qs->diag_shadow), p);
}
} else {
- if (!strequal(p, qs->status_shadow)) {
- print_at_byte(qs->screen,
- 0, qs->screen->height - qs->status_height,
- qs->screen->width, qs->status_height,
+ if (force || !strequal(p, qs->status_shadow)) {
+ print_at_byte(qs->screen, x, y, width, height,
p, QE_STYLE_STATUS);
pstrcpy(qs->status_shadow, sizeof(qs->status_shadow), p);
}
}
skip_spaces(&p);
- if (!silent && *buf)
+ if (!silent && *p)
eb_format_message(qs, "*messages*", buf);
}
}
@@ -5507,6 +5532,60 @@
}
}
+/* detach the window from the window tree. */
+static void edit_detach(EditState *s)
+{
+ QEmacsState *qs = s->qe_state;
+ EditState **ep;
+
+ /* unlink the window from the frame */
+ for (ep = &qs->first_window; *ep;) {
+ if ((*ep)->target_window == s) {
+ (*ep)->target_window = NULL;
+ }
+ if (*ep == s) {
+ *ep = s->next_window;
+ s->next_window = NULL;
+ } else {
+ ep = &(*ep)->next_window;
+ }
+ }
+ /* if window was active, activate target window or default window */
+ if (qs->active_window == s) {
+ if (s->target_window)
+ qs->active_window = s->target_window;
+ else
+ qs->active_window = qs->first_window;
+ }
+}
+
+/* move a window before another one */
+static void edit_attach(EditState *s, EditState *e)
+{
+ QEmacsState *qs = s->qe_state;
+ EditState **ep;
+
+ if (s != e) {
+ /* Detach the window from the frame */
+ for (ep = &qs->first_window; *ep; ep = &(*ep)->next_window) {
+ if (*ep == s) {
+ *ep = s->next_window;
+ s->next_window = NULL;
+ break;
+ }
+ }
+ /* Re-attach the window before `e` */
+ for (ep = &qs->first_window; *ep; ep = &(*ep)->next_window) {
+ if (*ep == e)
+ break;
+ }
+ s->next_window = *ep;
+ *ep = s;
+ if (qs->active_window == NULL)
+ qs->active_window = s;
+ }
+}
+
/* compute the client area from the window position */
static void compute_client_area(EditState *s)
{
@@ -5570,43 +5649,6 @@
return s;
}
-/* detach the window from the window tree. */
-void edit_detach(EditState *s)
-{
- QEmacsState *qs = s->qe_state;
- EditState **ep;
-
- for (ep = &qs->first_window; *ep; ep = &(*ep)->next_window) {
- if (*ep == s) {
- *ep = s->next_window;
- s->next_window = NULL;
- break;
- }
- }
- if (qs->active_window == s)
- qs->active_window = qs->first_window;
-}
-
-/* move a window before another one */
-void edit_attach(EditState *s, EditState *e)
-{
- QEmacsState *qs = s->qe_state;
- EditState *active_window = qs->active_window;
- EditState **ep;
-
- if (s != e) {
- edit_detach(s);
-
- for (ep = &qs->first_window; *ep; ep = &(*ep)->next_window) {
- if (*ep == e)
- break;
- }
- s->next_window = *ep;
- *ep = s;
- qs->active_window = active_window ? active_window : s;
- }
-}
-
/* Close the edit window.
* Save the window state to the buffer for later retrieval.
* If it is active, find another window to activate.
@@ -5768,25 +5810,27 @@
/* mini buffer stuff */
-struct MinibufState {
+typedef struct MinibufState {
+ QEModeData base;
+
void (*cb)(void *opaque, char *buf);
void *opaque;
- EditState *saved_active;
- EditState *completion_popup_window;
+ EditState *completion_popup_window; /* XXX: should have a popup_window
member */
CompletionFunc completion_function;
StringArray *history;
int history_index;
int history_saved_offset;
-};
+} MinibufState;
static ModeDef minibuffer_mode;
-/* XXX: should be opaque mode data */
-static struct MinibufState minibuffer;
+static inline MinibufState *minibuffer_get_state(EditState *e, int status) {
+ return qe_get_buffer_mode_data(e->b, &minibuffer_mode, status ? e : NULL);
+}
-void do_completion(EditState *s, int type)
+void do_minibuffer_complete(EditState *s, int type)
{
QEmacsState *qs = s->qe_state;
int count, i, match_len, c;
@@ -5795,8 +5839,12 @@
EditState *e;
EditBuffer *b;
int w, h, h1, w1;
+ MinibufState *mb;
- if (!minibuffer.completion_function)
+ if ((mb = minibuffer_get_state(s, 1)) == NULL)
+ return;
+
+ if (!mb->completion_function)
return;
/* Remove highlighted selection. */
@@ -5810,18 +5858,18 @@
*/
/* check completion window */
- check_window(&minibuffer.completion_popup_window);
- if (minibuffer.completion_popup_window
+ check_window(&mb->completion_popup_window);
+ if (mb->completion_popup_window
&& type == COMPLETION_TAB
&& qs->last_cmd_func == qs->this_cmd_func) {
/* toggle cpmpletion popup on TAB */
- edit_close(&minibuffer.completion_popup_window);
+ edit_close(&mb->completion_popup_window);
do_refresh(s);
return;
}
- complete_start(&cs, s, check_window(&minibuffer.saved_active));
- (*minibuffer.completion_function)(&cs);
+ complete_start(&cs, s, s->target_window);
+ (*mb->completion_function)(&cs);
count = cs.cs.nb_items;
outputs = cs.cs.items;
#if 0
@@ -5862,7 +5910,7 @@
if (count > 1) {
/* if more than one match, then display them in a new popup
buffer */
- if (!minibuffer.completion_popup_window) {
+ if (!mb->completion_popup_window) {
b = eb_new("*completion*",
BF_SYSTEM | BF_UTF8 | BF_TRANSIENT | BF_STYLE1);
b->default_mode = &list_mode;
@@ -5871,19 +5919,20 @@
w = (w1 * 3) / 4;
h = (h1 * 3) / 4;
e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP);
+ e->target_window = s;
+ mb->completion_popup_window = e;
do_refresh(e);
- minibuffer.completion_popup_window = e;
}
} else
if (count == 0 || type != COMPLETION_OTHER) {
/* close the popup when minibuf contents matches nothing */
- edit_close(&minibuffer.completion_popup_window);
+ edit_close(&mb->completion_popup_window);
do_refresh(s);
}
}
- if (minibuffer.completion_popup_window) {
+ if (mb->completion_popup_window) {
/* modify the list with the current matches */
- e = minibuffer.completion_popup_window;
+ e = mb->completion_popup_window;
b = e->b;
qsort(outputs, count, sizeof(StringItem *), completion_sort_func);
b->flags &= ~BF_READONLY;
@@ -5914,11 +5963,12 @@
return 1;
}
-void do_electric_filename(EditState *s, int key)
+void do_minibuffer_electric(EditState *s, int key)
{
int c, offset, stop;
+ MinibufState *mb = minibuffer_get_state(s, 0);
- if (minibuffer.completion_function == file_completion) {
+ if (mb && mb->completion_function == file_completion) {
stop = s->offset;
c = eb_prevc(s->b, s->offset, &offset);
if (c == '/') {
@@ -5934,42 +5984,48 @@
}
/* space does completion only if a completion method is defined */
-void do_completion_space(EditState *s)
+void do_minibuffer_complete_space(EditState *s)
{
QEmacsState *qs = s->qe_state;
+ MinibufState *mb = minibuffer_get_state(s, 0);
- if (!minibuffer.completion_function) {
+ if (!mb || !mb->completion_function) {
do_char(s, ' ', 1);
} else
- if (minibuffer.completion_popup_window && qs->last_cmd_func ==
qs->this_cmd_func) {
+ if (check_window(&mb->completion_popup_window)
+ && qs->last_cmd_func == qs->this_cmd_func) {
/* page through the list */
// XXX: should close the popup at the bottom of the list
- do_scroll_up_down(minibuffer.completion_popup_window, 2);
+ do_scroll_up_down(mb->completion_popup_window, 2);
} else {
- do_completion(s, COMPLETION_SPACE);
+ do_minibuffer_complete(s, COMPLETION_SPACE);
}
}
static void do_minibuffer_char(EditState *s, int key, int argval)
{
+ MinibufState *mb = minibuffer_get_state(s, 0);
+
do_char(s, key, argval);
- if (minibuffer.completion_popup_window) {
+ if (mb && check_window(&mb->completion_popup_window)) {
/* automatic filtering of completion list */
// XXX: should prevent auto-completion
- do_completion(s, COMPLETION_OTHER);
+ do_minibuffer_complete(s, COMPLETION_OTHER);
}
}
/* scroll in completion popup */
void minibuf_complete_scroll_up_down(qe__unused__ EditState *s, int dir)
{
- if (minibuffer.completion_popup_window) {
- minibuffer.completion_popup_window->force_highlight = 1;
- do_scroll_up_down(minibuffer.completion_popup_window, dir);
+ MinibufState *mb = minibuffer_get_state(s, 0);
+
+ if (mb && check_window(&mb->completion_popup_window)) {
+ mb->completion_popup_window->force_highlight = 1;
+ do_scroll_up_down(mb->completion_popup_window, dir);
}
}
-static void set_minibuffer_str(EditState *s, const char *str)
+static void minibuf_set_str(EditState *s, const char *str)
{
int len;
@@ -6002,38 +6058,45 @@
return &p->history;
}
-void do_history(EditState *s, int dir)
+void do_minibuffer_history(EditState *s, int dir)
{
QEmacsState *qs = s->qe_state;
- StringArray *hist = minibuffer.history;
+ MinibufState *mb;
+ StringArray *hist;
int index;
char *str;
char buf[1024];
+ if ((mb = minibuffer_get_state(s, 0)) == NULL)
+ return;
+
/* if completion visible, move in it */
- if (minibuffer.completion_popup_window) {
- minibuffer.completion_popup_window->force_highlight = 1;
- do_up_down(minibuffer.completion_popup_window, dir);
+ if (check_window(&mb->completion_popup_window)) {
+ mb->completion_popup_window->force_highlight = 1;
+ do_up_down(mb->completion_popup_window, dir);
return;
}
+ hist = mb->history;
if (!hist)
return;
- index = minibuffer.history_index + dir;
+
+ index = mb->history_index + dir;
if (index < 0 || index >= hist->nb_items)
return;
- if (qs->last_cmd_func != (CmdFunc)do_history) {
+
+ if (qs->last_cmd_func != (CmdFunc)do_minibuffer_history) {
/* save currently edited line */
eb_get_contents(s->b, buf, sizeof(buf));
set_string(hist, hist->nb_items - 1, buf, 0);
- minibuffer.history_saved_offset = s->offset;
+ mb->history_saved_offset = s->offset;
}
/* insert history text */
- minibuffer.history_index = index;
+ mb->history_index = index;
str = hist->items[index]->str;
- set_minibuffer_str(s, str);
+ minibuf_set_str(s, str);
if (index == hist->nb_items - 1) {
- s->offset = minibuffer.history_saved_offset;
+ s->offset = mb->history_saved_offset;
}
}
@@ -6041,9 +6104,8 @@
{
unsigned long offset;
- if (minibuffer.saved_active) {
- eb_read(minibuffer.saved_active->b,
- minibuffer.saved_active->offset,
+ if (s->target_window) {
+ eb_read(s->target_window->b, s->target_window->offset,
&offset, sizeof(offset));
eb_printf(s->b, "%lu", offset);
}
@@ -6051,13 +6113,20 @@
void do_minibuffer_exit(EditState *s, int do_abort)
{
- QEmacsState *qs = s->qe_state;
- StringArray *hist = minibuffer.history;
+ char buf[4096], *retstr;
+ MinibufState *mb;
+ StringArray *hist;
+ EditState *cw;
+ EditState *target;
void (*cb)(void *opaque, char *buf);
void *opaque;
- char buf[4096], *retstr;
- EditState *cw = minibuffer.completion_popup_window;
+ if ((mb = minibuffer_get_state(s, 1)) == NULL)
+ return;
+
+ cw = check_window(&mb->completion_popup_window);
+
+ if (!do_abort) {
/* if completion is activated, then select current file only if
the selection is highlighted */
if (cw && cw->force_highlight) {
@@ -6066,19 +6135,14 @@
len = eb_fgets(cw->b, buf, sizeof(buf), list_get_offset(cw), &offset);
buf[len] = '\0'; /* strip the trailing newline if any */
if (len > 0) {
- set_minibuffer_str(s, buf + 1);
- }
+ minibuf_set_str(s, buf + 1);
}
-
- /* remove completion popup if present */
- /* CG: assuming minibuffer.completion_popup_window != s */
- if (cw) {
- edit_close(&minibuffer.completion_popup_window);
- cw = NULL;
- do_refresh(s);
}
eb_get_contents(s->b, buf, sizeof(buf));
+
+ /* Append response to history list */
+ hist = mb->history;
if (hist && hist->nb_items > 0) {
/* if null string, do not insert in history */
hist->nb_items--;
@@ -6086,100 +6150,124 @@
if (buf[0] != '\0')
add_string(hist, buf, 0);
}
+ }
- s->b->flags |= BF_TRANSIENT;
- /* Close the minibuffer window */
- edit_close(&s);
+ /* remove completion popup if present */
+ if (cw) {
+ edit_close(&mb->completion_popup_window);
+ cw = NULL;
+ do_refresh(s);
+ }
- /* restore active window */
- qs->active_window = check_window(&minibuffer.saved_active);
- minibuffer.saved_active = NULL;
-
- /* force status update */
- //pstrcpy(qs->status_shadow, sizeof(qs->status_shadow), " ");
- if (do_abort)
- put_status(NULL, "Canceled.");
- else
- put_status(NULL, "");
+ cb = mb->cb;
+ opaque = mb->opaque;
+ target = s->target_window;
+ mb->cb = NULL;
+ mb->opaque = NULL;
- /* call the callback */
- cb = minibuffer.cb;
- opaque = minibuffer.opaque;
- minibuffer.cb = NULL;
- minibuffer.opaque = NULL;
+ /* Close the minibuffer window */
+ s->b->flags |= BF_TRANSIENT;
+ edit_close(&s);
+ /* Force status update and call the callback */
if (do_abort) {
- cb(opaque, NULL);
+ put_status(target, "!Canceled.");
+ (*cb)(opaque, NULL);
} else {
+ put_status(target, "!");
retstr = qe_strdup(buf);
- cb(opaque, retstr);
+ (*cb)(opaque, retstr);
}
}
/* Start minibuffer editing. When editing is finished, the callback is
called with an allocated string. If the string is null, it means
editing was aborted. */
-void minibuffer_edit(const char *input, const char *prompt,
+void minibuffer_edit(EditState *e, const char *input, const char *prompt,
StringArray *hist, CompletionFunc completion_func,
void (*cb)(void *opaque, char *buf), void *opaque)
{
-
- EditState *s;
QEmacsState *qs = &qe_state;
+ MinibufState *mb;
+ EditState *s;
EditBuffer *b;
int len;
/* check if already in minibuffer editing */
- if (minibuffer.cb) {
- put_status(NULL, "Already editing in minibuffer");
+ if (e->flags & WF_MINIBUF) {
+ put_status(NULL, "|Already editing in minibuffer");
cb(opaque, NULL);
return;
}
- minibuffer.cb = cb;
- minibuffer.opaque = opaque;
-
b = eb_new("*minibuf*", BF_SYSTEM | BF_SAVELOG | BF_UTF8);
b->default_mode = &minibuffer_mode;
s = edit_new(b, 0, qs->screen->height - qs->status_height,
- qs->screen->width, qs->status_height, 0);
- /* Should insert at end of window list */
- /* XXX: should qe_free previous value? */
+ qs->screen->width, qs->status_height, WF_MINIBUF);
+ s->target_window = e;
s->prompt = qe_strdup(prompt);
- s->minibuf = 1;
s->bidir = 0;
s->default_style = QE_STYLE_MINIBUF;
s->wrap = WRAP_TRUNCATE;
/* add default input */
if (input) {
- /* XXX: should insert utf-8? */
+ /* Default input should already be encoded as utf-8 */
len = strlen(input);
eb_write(b, 0, (u8 *)input, len);
s->offset = len;
}
- minibuffer.saved_active = qs->active_window;
- qs->active_window = s;
-
- minibuffer.completion_popup_window = NULL;
- minibuffer.completion_function = completion_func;
- minibuffer.history = hist;
- minibuffer.history_saved_offset = 0;
+ mb = minibuffer_get_state(s, 0);
+ if (mb) {
+ mb->completion_popup_window = NULL;
+ mb->completion_function = completion_func;
+ mb->history = hist;
+ mb->history_saved_offset = 0;
if (hist) {
- minibuffer.history_index = hist->nb_items;
+ mb->history_index = hist->nb_items;
add_string(hist, "", 0);
}
+ mb->cb = cb;
+ mb->opaque = opaque;
+ qs->active_window = s;
+ }
+}
+
+static void minibuffer_mode_free(EditBuffer *b, void *state)
+{
+ /* If minibuffer is destroyed, call callback with NULL pointer */
+ MinibufState *mb = state;
+ void (*cb)(void *opaque, char *buf);
+ void *opaque;
+
+ if (!mb)
+ return;
+
+ if (check_window(&mb->completion_popup_window))
+ edit_close(&mb->completion_popup_window);
+
+ cb = mb->cb;
+ opaque = mb->opaque;
+ mb->cb = NULL;
+ mb->opaque = NULL;
+
+ if (cb) {
+ put_status(NULL, "!Abort.");
+ (*cb)(opaque, NULL);
+ }
}
void minibuffer_init(void)
{
- /* minibuf mode inherits from text mode */
+ /* populate and register minibuffer mode and commands */
memcpy(&minibuffer_mode, &text_mode, sizeof(ModeDef));
minibuffer_mode.name = "minibuffer";
minibuffer_mode.mode_name = NULL;
minibuffer_mode.mode_probe = NULL;
+ minibuffer_mode.buffer_instance_size = sizeof(MinibufState);
+ minibuffer_mode.mode_free = minibuffer_mode_free;
minibuffer_mode.scroll_up_down = minibuf_complete_scroll_up_down;
qe_register_mode(&minibuffer_mode, MODEF_NOCMD | MODEF_VIEW);
qe_register_cmd_table(minibuffer_commands, &minibuffer_mode);
@@ -6189,9 +6277,6 @@
static ModeDef popup_mode;
-/* XXX: incorrect to save it. Should use window target member */
-static EditState *popup_saved_active;
-
/* Verify that window still exists, return argument or NULL,
* update handle if window is invalid.
*/
@@ -6216,9 +6301,6 @@
s->b->flags |= BF_TRANSIENT;
edit_close(&s);
- qs->active_window = check_window(&popup_saved_active);
- popup_saved_active = NULL;
-
do_refresh(qs->active_window);
}
}
@@ -6226,7 +6308,7 @@
/* show a popup on a readonly buffer */
EditState *show_popup(EditState *s, EditBuffer *b)
{
- QEmacsState *qs = &qe_state;
+ QEmacsState *qs = s->qe_state;
EditState *e;
int w, h, w1, h1;
@@ -6240,11 +6322,10 @@
w = (w1 * 4) / 5;
h = (h1 * 3) / 4;
+ b->default_mode = &popup_mode;
e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP);
- edit_set_mode(e, &popup_mode);
e->wrap = WRAP_TRUNCATE;
-
- popup_saved_active = qs->active_window;
+ e->target_window = s;
qs->active_window = e;
do_refresh(e);
return e;
@@ -6271,7 +6352,7 @@
for (e = qs->first_window; e != NULL; e = e_next) {
e_next = e->next_window;
- if (e->minibuf)
+ if (e->flags & WF_MINIBUF)
continue;
if (e->x2 <= width) {
edit_close(&e);
@@ -6298,7 +6379,7 @@
* non regular window layouts
*/
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (e->minibuf)
+ if (e->flags & WF_MINIBUF)
continue;
if (e->y1 < s->y2 && e->y2 > s->y1) {
/* horizontal overlap */
@@ -6350,6 +6431,9 @@
{
EditBuffer *b;
+ if (s->flags & WF_MINIBUF)
+ return;
+
/* XXX: Default buffer charset should be selectable */
b = eb_find_new(bufname, BF_SAVELOG | BF_UTF8);
if (b)
@@ -6392,7 +6476,7 @@
if (!force && b->modified && b->filename[0] != '\0') {
snprintf(buf, sizeof(buf),
"Buffer %s modified; kill anyway? (yes or no) ", bufname);
- minibuffer_edit(NULL, buf, NULL, NULL,
+ minibuffer_edit(s, NULL, buf, NULL, NULL,
kill_buffer_confirm_cb, b);
} else {
qe_kill_buffer(b);
@@ -6650,15 +6734,15 @@
}
static EditState *qe_find_target_window(EditState *s, int activate) {
+ QEmacsState *qs = s->qe_state;
EditState *e;
/* Find the target window for some commands run from the dired window */
if (s->flags & WF_POPUP) {
- e = check_window(&popup_saved_active);
- popup_saved_active = NULL;
+ e = check_window(&s->target_window);
if (e) {
- if (activate && s->qe_state->active_window == s)
- s->qe_state->active_window = e;
+ if (activate && qs->active_window == s)
+ qs->active_window = e;
}
s->b->flags |= BF_TRANSIENT;
edit_close(&s);
@@ -6666,11 +6750,11 @@
do_refresh(s);
}
#ifndef CONFIG_TINY
- if ((s->flags & WF_POPLEFT) && s->x1 == 0) {
+ if (s && (s->flags & WF_POPLEFT) && s->x1 == 0) {
e = find_window(s, KEY_RIGHT, NULL);
if (e) {
- if (activate && s->qe_state->active_window == s)
- s->qe_state->active_window = e;
+ if (activate && qs->active_window == s)
+ qs->active_window = e;
s = e;
}
}
@@ -6685,7 +6769,7 @@
*/
void do_set_next_mode(EditState *s, int dir)
{
- if (s->flags & WF_POPUP)
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return;
/* next-mode from the dired window applies to the target window */
@@ -6700,8 +6784,22 @@
ModeDef *modes[32];
int scores[32];
int i, nb, found;
- EditBuffer *b = s->b;
+ EditBuffer *b;
+ if (s->flags & WF_MINIBUF)
+ return;
+
+#ifndef CONFIG_TINY
+ /* Find target window for POPLEFT pane */
+ if ((s->flags & WF_POPLEFT) && s->x1 == 0) {
+ EditState *e = find_window(s, KEY_RIGHT, NULL);
+ if (e) {
+ s = e;
+ }
+ }
+#endif
+
+ b = s->b;
size = eb_read(b, 0, buf, sizeof(buf) - 1);
buf[size] = '\0';
@@ -6754,7 +6852,7 @@
}
#endif
- if (s->flags & WF_POPUP)
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return - 1;
if (lflags & LF_SPLIT_WINDOW) {
@@ -7086,6 +7184,7 @@
/* analyse next buffer and ask question if needed */
static void quit_examine_buffers(QuitState *is)
{
+ QEmacsState *qs = &qe_state;
EditBuffer *b;
while (is->b != NULL) {
@@ -7094,8 +7193,8 @@
switch (is->state) {
case QS_ASK:
/* XXX: display cursor */
- put_status(NULL, "Save file %s? (y, n, !, ., q) ",
- b->filename);
+ put_status(qs->active_window,
+ "Save file %s? (y, n, !, ., q) ", b->filename);
dpy_flush(&global_screen);
/* will wait for a key */
return;
@@ -7113,15 +7212,15 @@
/* now asks for confirmation or exit directly */
if (is->modified) {
- minibuffer_edit(NULL, "Modified buffers exist; exit anyway? (yes or
no) ",
- NULL, NULL,
- quit_confirm_cb, NULL);
+ minibuffer_edit(qs->active_window,
+ NULL, "Modified buffers exist; exit anyway? (yes or
no) ",
+ NULL, NULL, quit_confirm_cb, NULL);
edit_display(&qe_state);
dpy_flush(&global_screen);
} else {
#ifndef CONFIG_TINY
if (use_session_file)
- do_save_session(qe_state.active_window, 0);
+ do_save_session(qs->active_window, 0);
#endif
qe_free(&is);
url_exit();
@@ -7223,10 +7322,10 @@
}
/* refresh the screen, s1 can be any edit window */
-void do_refresh(qe__unused__ EditState *s1)
+void do_refresh(EditState *s1)
{
/* CG: s1 may be NULL */
- QEmacsState *qs = &qe_state;
+ QEmacsState *qs = s1 ? s1->qe_state : &qe_state;
EditState *e;
int new_status_height, new_mode_line_height, content_height;
int width, height, resized;
@@ -7251,6 +7350,11 @@
if (!qs->hide_status)
content_height -= new_status_height;
+ /* Prevent potential division overflow */
+ width = max(1, width);
+ height = max(1, height);
+ content_height = max(1, content_height);
+
resized = 0;
/* see if resize is necessary */
@@ -7262,14 +7366,16 @@
/* do the resize */
resized = 1;
+ qs->complete_refresh = 1;
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (e->minibuf) {
+ if (e->flags & WF_MINIBUF) {
/* first resize minibuffer if present */
e->x1 = 0;
e->y1 = content_height;
e->x2 = width;
e->y2 = height;
- } else if (qs->height == 0) {
+ } else
+ if (qs->height == 0 || qs->width == 0 || qs->content_height == 0) {
/* needed only to init the window size for the first time */
e->x1 = 0;
e->y1 = 0;
@@ -7357,11 +7463,11 @@
count = 0;
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (!e->minibuf && !(e->flags & WF_POPUP))
+ if (!(e->flags & (WF_POPUP | WF_MINIBUF)))
count++;
}
/* cannot close minibuf or if single window */
- if ((s->minibuf || count <= 1) && !force)
+ if (((s->flags & WF_MINIBUF) || count <= 1) && !force)
return;
if (!(s->flags & WF_POPUP)) {
@@ -7376,7 +7482,7 @@
for (pass = 0; pass < 2; pass++) {
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (e->minibuf || e == s || (e->flags & WF_POPUP))
+ if (e == s || (e->flags & (WF_POPUP | WF_MINIBUF)))
continue;
if (x1 == e->x2 && y1 == e->y1 && y2 >= e->y2) {
@@ -7422,14 +7528,21 @@
void do_delete_other_windows(EditState *s, int all)
{
QEmacsState *qs = s->qe_state;
- EditState *e, *e1;
+ EditState *e;
- if (s->minibuf || (s->flags & WF_POPUP))
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return;
- for (e = qs->first_window; e != NULL; e = e1) {
- e1 = e->next_window;
- if (!e->minibuf && e != s)
+ for (;;) {
+ for (e = qs->first_window; e != NULL; e = e->next_window) {
+ if (!(e->flags & WF_MINIBUF) && e != s)
+ break;
+ }
+ if (e == NULL)
+ break;
+ /* rescan after closing a window because another window could
+ * be closed as a side effect
+ */
edit_close(&e);
}
if (all) {
@@ -7474,7 +7587,7 @@
int x, y;
/* cannot split minibuf or popup */
- if (s->minibuf || (s->flags & WF_POPUP))
+ if (s->flags & (WF_POPUP | WF_MINIBUF))
return;
/* This will clone mode and mode data to the newly created window */
@@ -7733,7 +7846,7 @@
return;
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (e->minibuf || e == s)
+ if ((e->flags & WF_MINIBUF) || e == s)
continue;
window_get_min_size(e, &min_w, &min_h);
if (e->y1 == s->y2) {
@@ -7758,7 +7871,7 @@
/* now everything is OK, we can resize all windows */
for (e = qs->first_window; e != NULL; e = e->next_window) {
- if (e->minibuf || e == s)
+ if ((e->flags & WF_MINIBUF) || e == s)
continue;
if (e->y1 == s->y2)
e->y1 += delta_y;
@@ -8172,6 +8285,7 @@
qs->active_window = e;
parse_config_file(e, buf);
}
+ if (check_window(&saved))
qs->active_window = saved;
}
@@ -8743,7 +8857,6 @@
qs->ec.function = NULL;
}
-
#ifdef CONFIG_WIN32
int main1(int argc, char **argv)
#else
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs qe.h qeconfig.h bufed.c TODO.org charset...,
Charlie Gordon <=