window handling, bufed/dired: fixed bugs, simplified code
- make show_popup(b) return the window - pass an extra window argument to find_window() as a default return value - add check_buffer(EditBuffer **sp) to validate a buffer pointer - changed eb_find_window(): find a different window attached to a given buffer - removed edit_find(), use eb_find_window() instead - change edit_attach(): take window before which to move arg window, use NULL to append at the end. If qs->active_window is NULL, set it to the first window - add buffer flags BF_IS_LOG and BF_IS_STYLE - create style buffers with a meaningful name - create log buffers with a meaningful name - add window flag WF_POPLEFT for dired interactive buffers - no longer create process buffer and find files in dired pop left pane - remember last buffer upon switch_to_buffer for predict_switch_to_buffer() - rename do_file1() as extern qe_load_file() and make it return success status - prevent do_find_file_other_window() from splitting window if too shallow - fix window fusion algorithm when deleting left pane with split right pane - prevent delete-other-windows() from minibuf and poups - use mode structure as signature for bufed-mode, shell-mode - make list-buffers open an interactive popup window - toggle full buffer list with '.'
This commit is contained in:
parent
e2fa870ad9
commit
bccfbef8a0
6 changed files with 280 additions and 259 deletions
133
bufed.c
133
bufed.c
|
|
@ -22,16 +22,17 @@
|
|||
#include "qe.h"
|
||||
|
||||
enum {
|
||||
BUFED_ALL_VISIBLE = 1
|
||||
BUFED_HIDE_SYSTEM = 0,
|
||||
BUFED_ALL_VISIBLE = 1,
|
||||
};
|
||||
|
||||
static int bufed_signature;
|
||||
|
||||
typedef struct BufedState {
|
||||
void *signature;
|
||||
StringArray items;
|
||||
ModeDef *signature;
|
||||
int flags;
|
||||
int last_index;
|
||||
EditState *cur_window;
|
||||
EditBuffer *cur_buffer;
|
||||
EditBuffer *last_buffer;
|
||||
StringArray items;
|
||||
} BufedState;
|
||||
|
||||
static ModeDef bufed_mode;
|
||||
|
|
@ -40,7 +41,7 @@ static BufedState *bufed_get_state(EditState *s, int status)
|
|||
{
|
||||
BufedState *bs = s->b->priv_data;
|
||||
|
||||
if (bs && bs->signature == &bufed_signature)
|
||||
if (bs && bs->signature == &bufed_mode)
|
||||
return bs;
|
||||
|
||||
if (status)
|
||||
|
|
@ -90,6 +91,12 @@ static void build_bufed_list(EditState *s)
|
|||
char path[MAX_FILENAME_SIZE];
|
||||
const char *mode_name;
|
||||
|
||||
if (b1->flags & BF_IS_LOG) {
|
||||
mode_name = "log";
|
||||
} else
|
||||
if (b1->flags & BF_IS_STYLE) {
|
||||
mode_name = "style";
|
||||
} else
|
||||
if (b1->saved_mode) {
|
||||
mode_name = b1->saved_mode->name;
|
||||
} else
|
||||
|
|
@ -102,8 +109,8 @@ static void build_bufed_list(EditState *s)
|
|||
mode_name = "none";
|
||||
}
|
||||
|
||||
eb_printf(b, " %10d %c %-8s %-8s %s",
|
||||
b1->total_size, " 1234567"[b1->style_bytes & 7],
|
||||
eb_printf(b, " %10d %1.0d %-8s %-8s %s",
|
||||
b1->total_size, b1->style_bytes & 7,
|
||||
b1->charset->name, mode_name,
|
||||
make_user_path(path, sizeof(path), b1->filename));
|
||||
}
|
||||
|
|
@ -131,39 +138,36 @@ static EditBuffer *bufed_get_buffer(EditState *s)
|
|||
static void bufed_select(EditState *s, int temp)
|
||||
{
|
||||
BufedState *bs;
|
||||
StringItem *item;
|
||||
EditBuffer *b;
|
||||
EditBuffer *b, *last_buffer;
|
||||
EditState *e;
|
||||
int index;
|
||||
|
||||
if (!(bs = bufed_get_state(s, 1)))
|
||||
return;
|
||||
|
||||
index = list_get_pos(s);
|
||||
if (index < 0 || index >= bs->items.nb_items)
|
||||
return;
|
||||
if (temp < 0) {
|
||||
b = check_buffer(&bs->cur_buffer);
|
||||
last_buffer = check_buffer(&bs->last_buffer);
|
||||
} else {
|
||||
index = list_get_pos(s);
|
||||
if (index < 0 || index >= bs->items.nb_items)
|
||||
return;
|
||||
|
||||
if (temp && index == bs->last_index)
|
||||
return;
|
||||
|
||||
item = bs->items.items[index];
|
||||
b = eb_find(item->str);
|
||||
if (!b)
|
||||
return;
|
||||
e = find_window(s, KEY_RIGHT);
|
||||
if (temp) {
|
||||
if (e) {
|
||||
bs->last_index = index;
|
||||
switch_to_buffer(e, b);
|
||||
}
|
||||
return;
|
||||
b = eb_find(bs->items.items[index]->str);
|
||||
last_buffer = bs->cur_buffer;
|
||||
}
|
||||
if (e) {
|
||||
e = check_window(&bs->cur_window);
|
||||
if (e && b) {
|
||||
switch_to_buffer(e, b);
|
||||
e->last_buffer = last_buffer;
|
||||
}
|
||||
if (temp <= 0) {
|
||||
/* delete bufed window */
|
||||
do_delete_window(s, 1);
|
||||
switch_to_buffer(e, b);
|
||||
if (e)
|
||||
e->qe_state->active_window = e;
|
||||
} else {
|
||||
switch_to_buffer(s, b);
|
||||
do_refresh_complete(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,31 +222,38 @@ static void bufed_kill_buffer(EditState *s)
|
|||
/* show a list of buffers */
|
||||
static void do_list_buffers(EditState *s, int argval)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
BufedState *bs;
|
||||
EditBuffer *b, *b0;
|
||||
EditState *e, *e1;
|
||||
int width, i;
|
||||
EditBuffer *b;
|
||||
EditState *e;
|
||||
int i;
|
||||
|
||||
/* remember current buffer for target positioning, because
|
||||
* s may be destroyed by insert_window_left
|
||||
* CG: remove this kludge once we have delayed EditState free
|
||||
*/
|
||||
b = b0 = s->b;
|
||||
/* ignore command from the minibuffer and popups */
|
||||
if (s->minibuf || (s->flags & WF_POPUP))
|
||||
return;
|
||||
|
||||
if ((bs = bufed_get_state(s, 0)) == NULL) {
|
||||
/* XXX: must close this buffer when destroying window: add a
|
||||
special buffer flag to tell this */
|
||||
b = eb_scratch("*bufed*", BF_READONLY | BF_SYSTEM | BF_UTF8);
|
||||
if (s->flags & WF_POPLEFT) {
|
||||
/* avoid messing with the dired pane */
|
||||
s = find_window(s, KEY_RIGHT, s);
|
||||
s->qe_state->active_window = s;
|
||||
}
|
||||
|
||||
width = qs->width / 5;
|
||||
e = insert_window_left(b, width, WF_MODELINE);
|
||||
b = eb_scratch("*bufed*", BF_READONLY | BF_SYSTEM | BF_UTF8);
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
e = show_popup(b);
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
edit_set_mode(e, &bufed_mode);
|
||||
|
||||
if (!(bs = bufed_get_state(e, 1)))
|
||||
return;
|
||||
|
||||
bs->cur_window = s;
|
||||
bs->cur_buffer = s->b;
|
||||
bs->last_buffer = s->last_buffer;
|
||||
|
||||
if (argval == NO_ARG) {
|
||||
bs->flags &= ~BUFED_ALL_VISIBLE;
|
||||
} else {
|
||||
|
|
@ -250,20 +261,13 @@ static void do_list_buffers(EditState *s, int argval)
|
|||
}
|
||||
build_bufed_list(e);
|
||||
|
||||
e1 = find_window(e, KEY_RIGHT);
|
||||
if (e1)
|
||||
b0 = e1->b;
|
||||
|
||||
/* if active buffer is found, go directly on it */
|
||||
for (i = 0; i < bs->items.nb_items; i++) {
|
||||
if (strequal(bs->items.items[i]->str, b0->name)) {
|
||||
if (strequal(bs->items.items[i]->str, s->b->name)) {
|
||||
e->offset = eb_goto_pos(e->b, i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* modify active window */
|
||||
qs->active_window = e;
|
||||
}
|
||||
|
||||
static void bufed_clear_modified(EditState *s)
|
||||
|
|
@ -309,14 +313,15 @@ static void bufed_display_hook(EditState *s)
|
|||
if (s->offset && s->offset == s->b->total_size)
|
||||
do_up_down(s, -1);
|
||||
|
||||
bufed_select(s, 1);
|
||||
if (s->flags & WF_POPUP)
|
||||
bufed_select(s, 1);
|
||||
}
|
||||
|
||||
static int bufed_mode_probe(ModeDef *mode, ModeProbeData *p)
|
||||
{
|
||||
if (p->b->priv_data) {
|
||||
BufedState *bs = p->b->priv_data;
|
||||
if (bs->signature == &bufed_signature)
|
||||
if (bs->signature == &bufed_mode)
|
||||
return 95;
|
||||
else
|
||||
return 0;
|
||||
|
|
@ -328,7 +333,7 @@ static void bufed_close(EditBuffer *b)
|
|||
{
|
||||
BufedState *bs = b->priv_data;
|
||||
|
||||
if (bs && bs->signature == &bufed_signature) {
|
||||
if (bs && bs->signature == &bufed_mode) {
|
||||
free_strings(&bs->items);
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +351,7 @@ static int bufed_mode_init(EditState *s, EditBuffer *b, int flags)
|
|||
if (s) {
|
||||
if (s->b->priv_data) {
|
||||
bs = s->b->priv_data;
|
||||
if (bs->signature != &bufed_signature)
|
||||
if (bs->signature != &bufed_mode)
|
||||
return -1;
|
||||
} else {
|
||||
/* XXX: should be allocated by buffer_load API */
|
||||
|
|
@ -354,8 +359,7 @@ static int bufed_mode_init(EditState *s, EditBuffer *b, int flags)
|
|||
if (!bs)
|
||||
return -1;
|
||||
|
||||
bs->signature = &bufed_signature;
|
||||
bs->last_index = -1;
|
||||
bs->signature = &bufed_mode;
|
||||
s->b->priv_data = bs;
|
||||
s->b->close = bufed_close;
|
||||
}
|
||||
|
|
@ -365,11 +369,11 @@ static int bufed_mode_init(EditState *s, EditBuffer *b, int flags)
|
|||
|
||||
/* specific bufed commands */
|
||||
static CmdDef bufed_commands[] = {
|
||||
CMD1( KEY_RET, KEY_RIGHT,
|
||||
CMD1( KEY_RET, KEY_NONE,
|
||||
"bufed-select", bufed_select, 0)
|
||||
/* bufed-abort should restore previous buffer in right-window */
|
||||
CMD1( KEY_CTRL('g'), KEY_NONE,
|
||||
"bufed-abort", do_delete_window, 0)
|
||||
CMD1( KEY_CTRL('g'), KEY_CTRLX(KEY_CTRL('g')),
|
||||
"bufed-abort", bufed_select, -1)
|
||||
CMD1( ' ', KEY_CTRL('t'),
|
||||
"bufed-toggle-selection", list_toggle_selection, 1)
|
||||
CMD1( KEY_DEL, KEY_NONE,
|
||||
|
|
@ -379,7 +383,7 @@ static CmdDef bufed_commands[] = {
|
|||
"bufed-clear-modified", bufed_clear_modified)
|
||||
CMD0( '%', KEY_NONE,
|
||||
"bufed-toggle-read-only", bufed_toggle_read_only)
|
||||
CMD1( 'a', KEY_NONE,
|
||||
CMD1( 'a', '.',
|
||||
"bufed-toggle-all-visible", bufed_refresh, 1)
|
||||
CMD1( 'n', KEY_CTRL('n'), /* KEY_DOWN */
|
||||
"bufed-next-line", do_up_down, 1)
|
||||
|
|
@ -406,7 +410,6 @@ static int bufed_init(void)
|
|||
bufed_mode.name = "bufed";
|
||||
bufed_mode.mode_probe = bufed_mode_probe;
|
||||
bufed_mode.mode_init = bufed_mode_init;
|
||||
/* CG: not a good idea, display hook has side effect on layout */
|
||||
bufed_mode.display_hook = bufed_display_hook;
|
||||
|
||||
/* first register mode */
|
||||
|
|
|
|||
39
buffer.c
39
buffer.c
|
|
@ -395,6 +395,21 @@ int eb_insert(EditBuffer *b, int offset, const void *buf, int size)
|
|||
return size;
|
||||
}
|
||||
|
||||
/* Verify that window still exists, return argument or NULL,
|
||||
* update handle if window is invalid.
|
||||
*/
|
||||
EditBuffer *check_buffer(EditBuffer **sp)
|
||||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
EditBuffer *b;
|
||||
|
||||
for (b = qs->first_buffer; b != NULL; b = b->next) {
|
||||
if (b == *sp)
|
||||
return b;
|
||||
}
|
||||
return *sp = NULL;
|
||||
}
|
||||
|
||||
/* We must have : 0 <= offset <= b->total_size,
|
||||
* return actual number of bytes removed.
|
||||
*/
|
||||
|
|
@ -663,19 +678,17 @@ EditBuffer *eb_find_file(const char *filename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the next window showing a given buffer */
|
||||
EditState *eb_find_window(EditBuffer *b, EditState *e)
|
||||
/* Find a window attached to a given buffer, different from s */
|
||||
EditState *eb_find_window(EditBuffer *b, EditState *s)
|
||||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
EditState *e;
|
||||
|
||||
for (e = e ? e->next_window : qs->first_window;
|
||||
e != NULL;
|
||||
e = e->next_window)
|
||||
{
|
||||
if (e->b == b)
|
||||
return e;
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e != s && e->b == b)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
void eb_trace_bytes(const void *buf, int size, int state)
|
||||
|
|
@ -800,7 +813,9 @@ int eb_create_style_buffer(EditBuffer *b, int flags)
|
|||
if (b->b_styles) {
|
||||
return 0;
|
||||
} else {
|
||||
b->b_styles = eb_new("*", BF_SYSTEM | BF_RAW);
|
||||
char name[MAX_BUFFERNAME_SIZE];
|
||||
snprintf(name, sizeof(name), "*S<%s>", b->name);
|
||||
b->b_styles = eb_new(name, BF_SYSTEM | BF_IS_STYLE | BF_RAW);
|
||||
b->flags |= flags & BF_STYLES;
|
||||
b->style_shift = ((flags & BF_STYLES) / BF_STYLE1) - 1;
|
||||
b->style_bytes = 1 << b->style_shift;
|
||||
|
|
@ -904,8 +919,8 @@ static void eb_addlog(EditBuffer *b, enum LogOperation op,
|
|||
* should not be a problem since this log buffer is never
|
||||
* referenced by name.
|
||||
*/
|
||||
snprintf(buf, sizeof(buf), "*log <%s>*", b->name);
|
||||
b->log_buffer = eb_new(buf, BF_SYSTEM | BF_RAW);
|
||||
snprintf(buf, sizeof(buf), "*L<%s>", b->name);
|
||||
b->log_buffer = eb_new(buf, BF_SYSTEM | BF_IS_LOG | BF_RAW);
|
||||
if (!b->log_buffer)
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
12
dired.c
12
dired.c
|
|
@ -854,7 +854,7 @@ static void dired_select(EditState *s)
|
|||
} else
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* do explore files pointed to by symlinks */
|
||||
e = find_window(s, KEY_RIGHT);
|
||||
e = find_window(s, KEY_RIGHT, NULL);
|
||||
if (e) {
|
||||
#if 1
|
||||
s->qe_state->active_window = e;
|
||||
|
|
@ -874,8 +874,9 @@ static void dired_view_file(EditState *s, const char *filename)
|
|||
{
|
||||
EditBuffer *b;
|
||||
EditState *e;
|
||||
int rc;
|
||||
|
||||
e = find_window(s, KEY_RIGHT);
|
||||
e = find_window(s, KEY_RIGHT, NULL);
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
|
|
@ -890,10 +891,6 @@ static void dired_view_file(EditState *s, const char *filename)
|
|||
* new buffer as BF_PREVIEW, to trigger paging mode and so that it
|
||||
* will get freed if closed.
|
||||
*/
|
||||
#if 1
|
||||
/* XXX: need a way to verify that file was correctly loaded */
|
||||
do_find_file(e, filename, BF_PREVIEW);
|
||||
#else
|
||||
rc = qe_load_file(e, filename, 0, 0, BF_PREVIEW);
|
||||
if (rc >= 0) {
|
||||
/* disable wrapping to get nicer display */
|
||||
|
|
@ -904,7 +901,6 @@ static void dired_view_file(EditState *s, const char *filename)
|
|||
/* if file failed to load, show a scratch buffer */
|
||||
switch_to_buffer(e, eb_new("*scratch*", BF_SAVELOG | BF_UTF8 | BF_PREVIEW));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dired_execute(EditState *s)
|
||||
|
|
@ -920,7 +916,7 @@ static void dired_parent(EditState *s)
|
|||
char filename[MAX_FILENAME_SIZE];
|
||||
|
||||
if (s->b->flags & BF_PREVIEW) {
|
||||
EditState *e = find_window(s, KEY_LEFT);
|
||||
EditState *e = find_window(s, KEY_LEFT, NULL);
|
||||
if (e && (e->b->flags & BF_DIRED)) {
|
||||
s->qe_state->active_window = e;
|
||||
return;
|
||||
|
|
|
|||
291
qe.c
291
qe.c
|
|
@ -958,7 +958,7 @@ void do_left_right(EditState *s, int dir)
|
|||
{
|
||||
#ifndef CONFIG_TINY
|
||||
if (s->b->flags & BF_PREVIEW) {
|
||||
EditState *e = find_window(s, KEY_LEFT);
|
||||
EditState *e = find_window(s, KEY_LEFT, NULL);
|
||||
if (e && (e->b->flags & BF_DIRED)
|
||||
&& dir < 0 && eb_at_bol(s->b, s->offset)) {
|
||||
s->qe_state->active_window = e;
|
||||
|
|
@ -4900,7 +4900,6 @@ EditState *find_file_window(const char *filename)
|
|||
|
||||
void switch_to_buffer(EditState *s, EditBuffer *b)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditBuffer *b1;
|
||||
EditState *e;
|
||||
ModeSavedData *saved_data;
|
||||
|
|
@ -4916,10 +4915,7 @@ void switch_to_buffer(EditState *s, EditBuffer *b)
|
|||
b1 = s->b;
|
||||
if (b1) {
|
||||
/* save mode data if no other window uses the buffer */
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e != s && e->b == b1)
|
||||
break;
|
||||
}
|
||||
e = eb_find_window(b1, s);
|
||||
if (e) {
|
||||
/* no need to save mode data */
|
||||
/* CG: bogus! e and s might have different modes */
|
||||
|
|
@ -4940,6 +4936,9 @@ void switch_to_buffer(EditState *s, EditBuffer *b)
|
|||
edit_set_mode(s, NULL);
|
||||
if (b1->flags & BF_TRANSIENT) {
|
||||
eb_free(&b1);
|
||||
} else {
|
||||
/* save buffer for predict_switch_to_buffer */
|
||||
s->last_buffer = s->b;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4947,12 +4946,8 @@ void switch_to_buffer(EditState *s, EditBuffer *b)
|
|||
s->b = b;
|
||||
|
||||
if (b) {
|
||||
/* try to restore saved data from another window or from the
|
||||
buffer saved data */
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e != s && e->b == b)
|
||||
break;
|
||||
}
|
||||
/* Try to get window mode and data from another window */
|
||||
e = eb_find_window(b, s);
|
||||
if (e) {
|
||||
mode = e->mode;
|
||||
saved_data = generic_mode_save_data(e);
|
||||
|
|
@ -5016,6 +5011,7 @@ EditState *edit_new(EditBuffer *b,
|
|||
s = qe_mallocz(EditState);
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
s->qe_state = qs;
|
||||
s->screen = qs->screen;
|
||||
s->x1 = x1;
|
||||
|
|
@ -5024,30 +5020,15 @@ EditState *edit_new(EditBuffer *b,
|
|||
s->y2 = y1 + height;
|
||||
s->flags = flags;
|
||||
compute_client_area(s);
|
||||
|
||||
/* link window in window list */
|
||||
s->next_window = qs->first_window;
|
||||
/* CG: should append window to end of list, esp. for popups */
|
||||
qs->first_window = s;
|
||||
if (!qs->active_window)
|
||||
qs->active_window = s;
|
||||
edit_attach(s, qs->first_window);
|
||||
|
||||
/* restore saved window settings, set mode */
|
||||
switch_to_buffer(s, b);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* find a window with a given buffer if any. */
|
||||
EditState *edit_find(EditBuffer *b)
|
||||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
EditState *e;
|
||||
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e->b == b)
|
||||
break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/* detach the window from the window tree. */
|
||||
void edit_detach(EditState *s)
|
||||
{
|
||||
|
|
@ -5065,11 +5046,24 @@ void edit_detach(EditState *s)
|
|||
qs->active_window = qs->first_window;
|
||||
}
|
||||
|
||||
/* attach the window to the window list. */
|
||||
void edit_attach(EditState *s, EditState **ep)
|
||||
/* move a window before another one */
|
||||
void edit_attach(EditState *s, EditState *e)
|
||||
{
|
||||
s->next_window = *ep;
|
||||
*ep = s;
|
||||
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 = e;
|
||||
*ep = s;
|
||||
qs->active_window = active_window ? active_window : s;
|
||||
}
|
||||
}
|
||||
|
||||
/* close the edit window. If it is active, find another active
|
||||
|
|
@ -5079,26 +5073,10 @@ void edit_close(EditState **sp)
|
|||
{
|
||||
if (*sp) {
|
||||
EditState *s = *sp;
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditState **ps;
|
||||
|
||||
/* save current state for later window reattachment */
|
||||
switch_to_buffer(s, NULL);
|
||||
|
||||
/* detach from window list */
|
||||
ps = &qs->first_window;
|
||||
while (*ps != NULL) {
|
||||
if (*ps == s) {
|
||||
*ps = s->next_window;
|
||||
break;
|
||||
}
|
||||
ps = &(*ps)->next_window;
|
||||
}
|
||||
|
||||
/* if active window, select another active window */
|
||||
if (qs->active_window == s)
|
||||
qs->active_window = qs->first_window;
|
||||
|
||||
edit_detach(s);
|
||||
qe_free(&s->mode_data);
|
||||
qe_free(&s->prompt);
|
||||
qe_free(&s->line_shadow);
|
||||
|
|
@ -5671,15 +5649,15 @@ void do_less_exit(EditState *s)
|
|||
}
|
||||
|
||||
/* show a popup on a readonly buffer */
|
||||
void show_popup(EditBuffer *b)
|
||||
EditState *show_popup(EditBuffer *b)
|
||||
{
|
||||
EditState *s;
|
||||
QEmacsState *qs = &qe_state;
|
||||
EditState *s = qs->active_window;
|
||||
int w, h, w1, h1;
|
||||
|
||||
/* Prevent recursion */
|
||||
if (qs->active_window && qs->active_window->b == b)
|
||||
return;
|
||||
if (s && s->b == b)
|
||||
return s;
|
||||
|
||||
/* XXX: generic function to open popup ? */
|
||||
w1 = qs->screen->width;
|
||||
|
|
@ -5694,6 +5672,7 @@ void show_popup(EditBuffer *b)
|
|||
popup_saved_active = qs->active_window;
|
||||
qs->active_window = s;
|
||||
do_refresh(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void less_init(void)
|
||||
|
|
@ -5728,13 +5707,13 @@ EditState *insert_window_left(EditBuffer *b, int width, int flags)
|
|||
}
|
||||
|
||||
e_new = edit_new(b, 0, 0, width, qs->height - qs->status_height,
|
||||
flags | WF_RSEPARATOR);
|
||||
do_refresh(qs->first_window);
|
||||
flags | WF_POPLEFT | WF_RSEPARATOR);
|
||||
do_refresh(e_new);
|
||||
return e_new;
|
||||
}
|
||||
|
||||
/* return a window on the side of window 's' */
|
||||
EditState *find_window(EditState *s, int key)
|
||||
EditState *find_window(EditState *s, int key, EditState *def)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditState *e;
|
||||
|
|
@ -5760,41 +5739,35 @@ EditState *find_window(EditState *s, int key)
|
|||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return def;
|
||||
}
|
||||
|
||||
void do_find_window(EditState *s, int key)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditState *e;
|
||||
|
||||
e = find_window(s, key);
|
||||
if (e)
|
||||
qs->active_window = e;
|
||||
s->qe_state->active_window = find_window(s, key, s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* give a good guess to the user for the next buffer */
|
||||
/* Give a good guess to the user for the next buffer */
|
||||
static EditBuffer *predict_switch_to_buffer(EditState *s)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditState *e;
|
||||
EditBuffer *b;
|
||||
|
||||
/* try and switch to the last buffer attached to the window */
|
||||
b = check_buffer(&s->last_buffer);
|
||||
if (b)
|
||||
return b;
|
||||
|
||||
/* else try and switch to a buffer not shown in any window */
|
||||
for (b = qs->first_buffer; b != NULL; b = b->next) {
|
||||
if (!(b->flags & BF_SYSTEM)) {
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e->b == b)
|
||||
break;
|
||||
}
|
||||
if (!e)
|
||||
goto found;
|
||||
if (!eb_find_window(b, NULL))
|
||||
return b;
|
||||
}
|
||||
}
|
||||
/* select current buffer if none found */
|
||||
b = s->b;
|
||||
found:
|
||||
return b;
|
||||
/* otherwise select current buffer. */
|
||||
return s->b;
|
||||
}
|
||||
|
||||
void do_switch_to_buffer(EditState *s, const char *bufname)
|
||||
|
|
@ -5857,7 +5830,10 @@ void kill_buffer_noconfirm(EditBuffer *b)
|
|||
EditState *e;
|
||||
EditBuffer *b1;
|
||||
|
||||
// FIXME: used to delete windows containing the buffer ???
|
||||
/* Emacs makes any window showing the killed buffer switch to
|
||||
* another buffer.
|
||||
* An alternative is to delete windows showing the buffer.
|
||||
*/
|
||||
|
||||
/* find a new buffer to switch to */
|
||||
for (b1 = qs->first_buffer; b1 != NULL; b1 = b1->next) {
|
||||
|
|
@ -6045,15 +6021,20 @@ void do_set_next_mode(EditState *s, int dir)
|
|||
modes[found]->name, scores[found]);
|
||||
}
|
||||
|
||||
/* Should take bits from enumeration instead of booleans */
|
||||
static void do_load1(EditState *s, const char *filename1,
|
||||
int kill_buffer, int load_resource, int bflags)
|
||||
/* Load a file and attach buffer to window `s`.
|
||||
* Return -1 if loading failed.
|
||||
* Return 0 if file or resource was already loaded,
|
||||
* Return 1 if file or resource was newly loaded,
|
||||
* Return 2 if buffer was created for a new file.
|
||||
* Should take bits from enumeration instead of booleans.
|
||||
*/
|
||||
int qe_load_file(EditState *s, const char *filename1,
|
||||
int kill_buffer, int load_resource, int bflags)
|
||||
{
|
||||
u8 buf[4097];
|
||||
char filename[MAX_FILENAME_SIZE];
|
||||
int st_mode, buf_size;
|
||||
int st_mode, buf_size, mode_score;
|
||||
ModeDef *selected_mode;
|
||||
int mode_score;
|
||||
EditBuffer *b;
|
||||
EditBufferDataType *bdt;
|
||||
FILE *f;
|
||||
|
|
@ -6061,46 +6042,47 @@ static void do_load1(EditState *s, const char *filename1,
|
|||
EOLType eol_type = EOL_UNIX;
|
||||
QECharset *charset = &charset_utf8;
|
||||
|
||||
#ifndef CONFIG_TINY
|
||||
/* avoid messing with the dired pane */
|
||||
if ((s->flags & WF_POPLEFT) && s->x1 == 0) {
|
||||
EditState *e = find_window(s, KEY_RIGHT, NULL);
|
||||
if (e) {
|
||||
if (s->qe_state->active_window == s)
|
||||
s->qe_state->active_window = e;
|
||||
s = e;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (load_resource) {
|
||||
if (find_resource_file(filename, sizeof(filename), filename1)) {
|
||||
/* XXX: issue error message? */
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* compute full name */
|
||||
canonicalize_absolute_path(filename, sizeof(filename), filename1);
|
||||
}
|
||||
|
||||
///* If file already shown in window, switch to that */
|
||||
//s1 = find_file_window(filename);
|
||||
//if (s1 != NULL) {
|
||||
// qs->active_window = s1;
|
||||
// return;
|
||||
//}
|
||||
|
||||
///* Split window if window large enough and not empty */
|
||||
//if (other_window && s->height > 10 && s->b->total_size > 0) {
|
||||
// do_split_window(s, 0, 0);
|
||||
// s = qs->active_window;
|
||||
//}
|
||||
|
||||
if (kill_buffer && s->b) {
|
||||
/* CG: this behaviour is not correct */
|
||||
/* CG: should have a direct primitive */
|
||||
do_kill_buffer(s, s->b->name);
|
||||
}
|
||||
|
||||
/* If file already loaded in existing buffer, switch to that */
|
||||
b = eb_find_file(filename);
|
||||
if (b != NULL) {
|
||||
switch_to_buffer(s, b);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We are going to try and load a new file: potentially delete the
|
||||
* current buffer if requested.
|
||||
*/
|
||||
if (kill_buffer && s->b && !s->b->modified) {
|
||||
s->b->flags |= BF_TRANSIENT;
|
||||
}
|
||||
|
||||
/* Create new buffer with unique name from filename */
|
||||
b = eb_new("", BF_SAVELOG | bflags);
|
||||
eb_set_filename(b, filename);
|
||||
|
||||
/* XXX: should actually initialize SAVED_DATA area in new buffer */
|
||||
s->offset = 0;
|
||||
/* XXX: Should test for full width and WRAP_TRUNCATE if not */
|
||||
s->wrap = WRAP_LINE; /* default mode may override this */
|
||||
|
|
@ -6128,7 +6110,7 @@ static void do_load1(EditState *s, const char *filename1,
|
|||
if (b->data_type == &raw_data_type)
|
||||
put_status(s, "(New file)");
|
||||
do_load_qerc(s, s->b->filename);
|
||||
return;
|
||||
return 2;
|
||||
} else {
|
||||
b->st_mode = st_mode = st.st_mode;
|
||||
buf_size = 0;
|
||||
|
|
@ -6179,7 +6161,7 @@ static void do_load1(EditState *s, const char *filename1,
|
|||
|
||||
/* XXX: invalid place */
|
||||
edit_invalidate(s);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fail:
|
||||
|
|
@ -6187,6 +6169,7 @@ static void do_load1(EditState *s, const char *filename1,
|
|||
|
||||
put_status(s, "Could not open '%s': %s",
|
||||
filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -6224,25 +6207,28 @@ static void load_completion_cb(void *opaque, int err)
|
|||
|
||||
void do_find_file(EditState *s, const char *filename, int bflags)
|
||||
{
|
||||
do_load1(s, filename, 0, 0, bflags);
|
||||
qe_load_file(s, filename, 0, 0, bflags);
|
||||
}
|
||||
|
||||
void do_find_file_other_window(EditState *s, const char *filename, int bflags)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
|
||||
do_split_window(s, 0);
|
||||
do_load1(qs->active_window, filename, 0, 0, bflags);
|
||||
/* Split window if window large enough and not empty */
|
||||
/* XXX: should check s->height units */
|
||||
if (s->height > 10 && s->b->total_size > 0) {
|
||||
do_split_window(s, 0);
|
||||
s = s->qe_state->active_window;
|
||||
}
|
||||
qe_load_file(s, filename, 0, 0, bflags);
|
||||
}
|
||||
|
||||
void do_find_alternate_file(EditState *s, const char *filename, int bflags)
|
||||
{
|
||||
do_load1(s, filename, 1, 0, bflags);
|
||||
qe_load_file(s, filename, 1, 0, bflags);
|
||||
}
|
||||
|
||||
void do_load_file_from_path(EditState *s, const char *filename, int bflags)
|
||||
{
|
||||
do_load1(s, filename, 0, 1, bflags);
|
||||
qe_load_file(s, filename, 0, 1, bflags);
|
||||
}
|
||||
|
||||
void do_insert_file(EditState *s, const char *filename)
|
||||
|
|
@ -6608,9 +6594,8 @@ void do_previous_window(EditState *s)
|
|||
void do_delete_window(EditState *s, int force)
|
||||
{
|
||||
QEmacsState *qs = s->qe_state;
|
||||
EditState *e;
|
||||
int count, x1, y1, x2, y2;
|
||||
int ex1, ey1, ex2, ey2;
|
||||
EditState *e, *e1 = NULL;
|
||||
int count, pass, x1, y1, x2, y2;
|
||||
|
||||
count = 0;
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
|
|
@ -6622,47 +6607,53 @@ void do_delete_window(EditState *s, int force)
|
|||
return;
|
||||
|
||||
if (!(s->flags & WF_POPUP)) {
|
||||
/* try to merge the window with one adjacent window. If none
|
||||
found, just leave a hole */
|
||||
/* Try to merge the window with adjacent windows.
|
||||
* If this cannot be done, just leave a hole and force full
|
||||
* redisplay.
|
||||
*/
|
||||
x1 = s->x1;
|
||||
x2 = s->x2;
|
||||
y1 = s->y1;
|
||||
y2 = s->y2;
|
||||
|
||||
for (e = qs->first_window; e != NULL; e = e->next_window) {
|
||||
if (e->minibuf || e == s)
|
||||
continue;
|
||||
ex1 = e->x1;
|
||||
ex2 = e->x2;
|
||||
ey1 = e->y1;
|
||||
ey2 = e->y2;
|
||||
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))
|
||||
continue;
|
||||
|
||||
if (x1 == ex2 && y1 == ey1 && y2 == ey2) {
|
||||
/* left border */
|
||||
e->x2 = x2;
|
||||
break;
|
||||
} else
|
||||
if (x2 == ex1 && y1 == ey1 && y2 == ey2) {
|
||||
/* right border */
|
||||
e->x1 = x1;
|
||||
break;
|
||||
} else
|
||||
if (y1 == ey2 && x1 == ex1 && x2 == ex2) {
|
||||
/* top border */
|
||||
e->y2 = y2;
|
||||
break;
|
||||
} else
|
||||
if (y2 == ey1 && x1 == ex1 && x2 == ex2) {
|
||||
/* bottom border */
|
||||
e->y1 = y1;
|
||||
break;
|
||||
if (x1 == e->x2 && y1 == e->y1 && y2 >= e->y2) {
|
||||
/* partial vertical split along the left border */
|
||||
e->x2 = x2;
|
||||
y1 = e->y2;
|
||||
} else
|
||||
if (x2 == e->x1 && y1 == e->y1 && y2 >= e->y2) {
|
||||
/* partial vertical split along the right border */
|
||||
e->x1 = x1;
|
||||
y1 = e->y2;
|
||||
} else
|
||||
if (y1 == e->y2 && x1 == e->x1 && x2 >= e->x2) {
|
||||
/* partial horizontal split along the top border */
|
||||
e->y2 = y2;
|
||||
x1 = e->x2;
|
||||
} else
|
||||
if (y2 == e->y1 && x1 == e->x1 && x2 >= e->x2) {
|
||||
/* partial horizontal split along bottom border */
|
||||
e->y1 = y1;
|
||||
x1 = e->x2;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
compute_client_area(e1 = e);
|
||||
}
|
||||
if (x1 == x2 || y1 == y2)
|
||||
break;
|
||||
}
|
||||
if (e)
|
||||
compute_client_area(e);
|
||||
if (x1 != x2 && y1 != y2)
|
||||
qs->complete_refresh = 1;
|
||||
}
|
||||
if (qs->active_window == s)
|
||||
qs->active_window = e ? e : qs->first_window;
|
||||
qs->active_window = e1 ? e1 : qs->first_window;
|
||||
|
||||
edit_close(&s);
|
||||
if (qs->first_window)
|
||||
do_refresh(qs->first_window);
|
||||
|
|
@ -6673,6 +6664,9 @@ void do_delete_other_windows(EditState *s)
|
|||
QEmacsState *qs = s->qe_state;
|
||||
EditState *e, *e1;
|
||||
|
||||
if (s->minibuf || (s->flags & WF_POPUP))
|
||||
return;
|
||||
|
||||
for (e = qs->first_window; e != NULL; e = e1) {
|
||||
e1 = e->next_window;
|
||||
if (!e->minibuf && e != s)
|
||||
|
|
@ -6718,8 +6712,7 @@ void do_split_window(EditState *s, int horiz)
|
|||
s->y2 = y;
|
||||
}
|
||||
/* insert in the window list after current window */
|
||||
edit_detach(e);
|
||||
edit_attach(e, &s->next_window);
|
||||
edit_attach(e, s->next_window);
|
||||
|
||||
if (qs->flag_split_window_change_focus)
|
||||
qs->active_window = e;
|
||||
|
|
|
|||
23
qe.h
23
qe.h
|
|
@ -859,6 +859,8 @@ typedef struct EditBufferDataType {
|
|||
#define BF_STYLE1 0x1000 /* buffer has 1 byte styles */
|
||||
#define BF_STYLE2 0x2000 /* buffer has 2 byte styles */
|
||||
#define BF_STYLE4 0x3000 /* buffer has 4 byte styles */
|
||||
#define BF_IS_STYLE 0x4000 /* buffer is a styles buffer */
|
||||
#define BF_IS_LOG 0x8000 /* buffer is a log buffer */
|
||||
|
||||
struct EditBuffer {
|
||||
OWNED Page *page_table;
|
||||
|
|
@ -927,9 +929,9 @@ struct EditBuffer {
|
|||
/* CG: should instead keep a pointer to last window using this
|
||||
* buffer, even if no longer on screen
|
||||
*/
|
||||
struct ModeDef *default_mode;
|
||||
struct ModeDef *saved_mode;
|
||||
OWNED struct ModeSavedData *saved_data;
|
||||
ModeDef *default_mode;
|
||||
ModeDef *saved_mode;
|
||||
OWNED ModeSavedData *saved_data;
|
||||
|
||||
/* default mode stuff when buffer is detached from window */
|
||||
int offset;
|
||||
|
|
@ -1171,6 +1173,8 @@ struct EditState {
|
|||
|
||||
EditBuffer *b;
|
||||
|
||||
EditBuffer *last_buffer; /* for predict_switch_to_buffer */
|
||||
|
||||
/* mode specific info */
|
||||
ModeDef *mode;
|
||||
void *mode_data; /* mode private data */
|
||||
|
|
@ -1205,6 +1209,7 @@ struct EditState {
|
|||
#define WF_POPUP 0x0001 /* popup window (with borders) */
|
||||
#define WF_MODELINE 0x0002 /* mode line must be displayed */
|
||||
#define WF_RSEPARATOR 0x0004 /* right window separator */
|
||||
#define WF_POPLEFT 0x0008 /* left side window */
|
||||
|
||||
OWNED char *prompt; /* optional window prompt, utf8, owned by the window */
|
||||
//const char *mode_line;
|
||||
|
|
@ -1751,15 +1756,19 @@ static inline int is_user_input_pending(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* file loading */
|
||||
int qe_load_file(EditState *s, const char *filename1,
|
||||
int kill_buffer, int load_resource, int bflags);
|
||||
|
||||
/* config file support */
|
||||
void do_load_config_file(EditState *e, const char *file);
|
||||
void do_load_qerc(EditState *e, const char *file);
|
||||
|
||||
/* popup / low level window handling */
|
||||
void show_popup(EditBuffer *b);
|
||||
EditState *show_popup(EditBuffer *b);
|
||||
int check_read_only(EditState *s);
|
||||
EditState *insert_window_left(EditBuffer *b, int width, int flags);
|
||||
EditState *find_window(EditState *s, int key);
|
||||
EditState *find_window(EditState *s, int key, EditState *def);
|
||||
void do_find_window(EditState *s, int key);
|
||||
|
||||
/* window handling */
|
||||
|
|
@ -1767,8 +1776,8 @@ 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);
|
||||
EditState *edit_find(EditBuffer *b);
|
||||
void do_refresh(EditState *s);
|
||||
// should take direction argument
|
||||
void do_other_window(EditState *s);
|
||||
|
|
@ -1939,7 +1948,7 @@ void do_call_macro(EditState *s);
|
|||
void do_execute_macro_keys(EditState *s, const char *keys);
|
||||
void do_define_kbd_macro(EditState *s, const char *name, const char *keys,
|
||||
const char *key_bind);
|
||||
void edit_attach(EditState *s, EditState **ep);
|
||||
void edit_attach(EditState *s, EditState *e);
|
||||
void do_completion(EditState *s);
|
||||
void do_completion_space(EditState *s);
|
||||
void do_electric_filename(EditState *s, int key);
|
||||
|
|
|
|||
35
shell.c
35
shell.c
|
|
@ -52,10 +52,8 @@ enum TTYState {
|
|||
TTY_STATE_STRING,
|
||||
};
|
||||
|
||||
static int shell_signature;
|
||||
|
||||
typedef struct ShellState {
|
||||
void *signature;
|
||||
ModeDef *signature;
|
||||
/* buffer state */
|
||||
int pty_fd;
|
||||
int pid; /* -1 if not launched */
|
||||
|
|
@ -659,7 +657,7 @@ static ShellState *shell_get_state(EditState *e, int status)
|
|||
{
|
||||
ShellState *s = e->b->priv_data;
|
||||
|
||||
if (s && s->signature == &shell_signature)
|
||||
if (s && s->signature == &shell_mode)
|
||||
return s;
|
||||
|
||||
if (status)
|
||||
|
|
@ -687,7 +685,7 @@ static void shell_key(void *opaque, int key)
|
|||
const char *p;
|
||||
int len;
|
||||
|
||||
if (!s || s->signature != &shell_signature)
|
||||
if (!s || s->signature != &shell_mode)
|
||||
return;
|
||||
|
||||
if (key == KEY_CTRL('o')) {
|
||||
|
|
@ -1244,7 +1242,7 @@ static void shell_read_cb(void *opaque)
|
|||
unsigned char buf[16 * 1024];
|
||||
int len, i;
|
||||
|
||||
if (!s || s->signature != &shell_signature)
|
||||
if (!s || s->signature != &shell_mode)
|
||||
return;
|
||||
|
||||
qs = s->qe_state;
|
||||
|
|
@ -1279,7 +1277,7 @@ static void shell_close(EditBuffer *b)
|
|||
ShellState *s = b->priv_data;
|
||||
int status;
|
||||
|
||||
if (!s || s->signature != &shell_signature)
|
||||
if (!s || s->signature != &shell_mode)
|
||||
return;
|
||||
|
||||
eb_free_callback(b, eb_offset_callback, &s->cur_offset);
|
||||
|
|
@ -1317,7 +1315,7 @@ static void shell_pid_cb(void *opaque, int status)
|
|||
EditState *e;
|
||||
char buf[1024];
|
||||
|
||||
if (!s || s->signature != &shell_signature)
|
||||
if (!s || s->signature != &shell_mode)
|
||||
return;
|
||||
|
||||
b = s->b;
|
||||
|
|
@ -1395,7 +1393,7 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, const char *bufname,
|
|||
b = b0;
|
||||
if (b) {
|
||||
s = b->priv_data;
|
||||
if (s && s->signature != &shell_signature)
|
||||
if (s && s->signature != &shell_mode)
|
||||
return NULL;
|
||||
if (shell_flags & SF_COLOR)
|
||||
eb_create_style_buffer(b, BF_STYLE2);
|
||||
|
|
@ -1426,7 +1424,7 @@ EditBuffer *new_shell_buffer(EditBuffer *b0, const char *bufname,
|
|||
eb_free(&b);
|
||||
return NULL;
|
||||
}
|
||||
s->signature = &shell_signature;
|
||||
s->signature = &shell_mode;
|
||||
b->priv_data = s;
|
||||
b->close = shell_close;
|
||||
/* Track cursor with edge effect */
|
||||
|
|
@ -1466,7 +1464,7 @@ static EditBuffer *try_show_buffer(EditState *s, const char *bufname)
|
|||
|
||||
b = eb_find(bufname);
|
||||
if (b) {
|
||||
e = edit_find(b);
|
||||
e = eb_find_window(b, NULL);
|
||||
if (e)
|
||||
qs->active_window = e;
|
||||
else
|
||||
|
|
@ -1480,26 +1478,33 @@ static void do_shell(EditState *s, int force)
|
|||
ShellState *shs;
|
||||
EditBuffer *b = NULL;
|
||||
|
||||
if (s->flags & WF_POPLEFT) {
|
||||
/* avoid messing with the dired pane */
|
||||
s = find_window(s, KEY_RIGHT, s);
|
||||
s->qe_state->active_window = s;
|
||||
}
|
||||
|
||||
/* CG: Should prompt for buffer name if arg:
|
||||
* find a syntax for optional string argument w/ prompt
|
||||
*/
|
||||
/* find shell buffer if any */
|
||||
if (!force || force == NO_ARG) {
|
||||
/* XXX: if current buffer is a shell buffer without a process,
|
||||
* restart shell process.
|
||||
* restart shell process in it.
|
||||
*/
|
||||
b = s->b;
|
||||
shs = b->priv_data;
|
||||
if (strstart(b->name, "*shell*", NULL)
|
||||
&& shs && shs->signature == &shell_signature) {
|
||||
&& shs && shs->signature == &shell_mode) {
|
||||
if (shs->pid >= 0)
|
||||
return;
|
||||
} else {
|
||||
/* XXX: should find the last used shell buffer */
|
||||
b = try_show_buffer(s, "*shell*");
|
||||
if (b) {
|
||||
shs = b->priv_data;
|
||||
if (shs) {
|
||||
if (shs->signature != &shell_signature) {
|
||||
if (shs->signature != &shell_mode) {
|
||||
b = NULL;
|
||||
} else
|
||||
if (shs->pid >= 0)
|
||||
|
|
@ -1960,7 +1965,7 @@ static int shell_mode_probe(ModeDef *mode, ModeProbeData *p)
|
|||
{
|
||||
if (p->b && p->b->priv_data) {
|
||||
ShellState *s = p->b->priv_data;
|
||||
if (s->signature == &shell_signature) {
|
||||
if (s->signature == &shell_mode) {
|
||||
if (s->shell_flags & SF_INTERACTIVE)
|
||||
return 100;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue