updated for version 7.0118
diff --git a/src/message.c b/src/message.c
index 81c0a8e..ed12d8c 100644
--- a/src/message.c
+++ b/src/message.c
@@ -929,7 +929,8 @@
c = K_IGNORE;
}
#endif
- if (p_more && !p_cp && (c == 'b' || c == 'k' || c == 'u'))
+ if (p_more && !p_cp && (c == 'b' || c == 'k' || c == 'u'
+ || c == 'g' || c == K_UP))
{
/* scroll back to show older messages */
do_more_prompt(c);
@@ -2057,6 +2058,8 @@
static msgchunk_T *msg_sb_start __ARGS((msgchunk_T *mps));
static msgchunk_T *disp_sb_line __ARGS((int row, msgchunk_T *smp));
+static int do_clear_sb_text = FALSE; /* clear text on next msg */
+
/*
* Store part of a printed message for displaying when scrolling back.
*/
@@ -2070,6 +2073,12 @@
{
msgchunk_T *mp;
+ if (do_clear_sb_text)
+ {
+ clear_sb_text();
+ do_clear_sb_text = FALSE;
+ }
+
if (s > *sb_str)
{
mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str)));
@@ -2102,6 +2111,15 @@
}
/*
+ * Finished showing messages, clear the scroll-back text on the next message.
+ */
+ void
+may_clear_sb_text()
+{
+ do_clear_sb_text = TRUE;
+}
+
+/*
* Clear any text remembered for scrolling back.
* Called when redrawing the screen.
*/
@@ -2120,6 +2138,26 @@
}
/*
+ * "g<" command.
+ */
+ void
+show_sb_text()
+{
+ msgchunk_T *mp;
+
+ /* Only show somethign if there is more than one line, otherwise it looks
+ * weird, typing a command without output results in one line. */
+ mp = msg_sb_start(last_msgchunk);
+ if (mp == NULL || mp->sb_prev == NULL)
+ vim_beep();
+ else
+ {
+ do_more_prompt('G');
+ wait_return(FALSE);
+ }
+}
+
+/*
* Move to the start of screen line in already displayed text.
*/
static msgchunk_T *
@@ -2273,7 +2311,8 @@
/*
* Show the more-prompt and handle the user response.
* This takes care of scrolling back and displaying previously displayed text.
- * When at hit-enter prompt "typed_char" is the already typed character.
+ * When at hit-enter prompt "typed_char" is the already typed character,
+ * otherwise it's NUL.
* Returns TRUE when jumping ahead to "confirm_msg_tail".
*/
static int
@@ -2291,11 +2330,21 @@
msgchunk_T *mp;
int i;
+ if (typed_char == 'G')
+ {
+ /* "g<": Find first line on the last page. */
+ mp_last = msg_sb_start(last_msgchunk);
+ for (i = 0; i < Rows - 2 && mp_last != NULL
+ && mp_last->sb_prev != NULL; ++i)
+ mp_last = msg_sb_start(mp_last->sb_prev);
+ }
+
State = ASKMORE;
#ifdef FEAT_MOUSE
setmouse();
#endif
- msg_moremsg(FALSE);
+ if (typed_char == NUL)
+ msg_moremsg(FALSE);
for (;;)
{
/*
@@ -2363,6 +2412,15 @@
scroll = Rows - 1;
break;
+ case 'g': /* all the way back to the start */
+ scroll = -999999;
+ break;
+
+ case 'G': /* all the way to the end */
+ scroll = 999999;
+ lines_left = 999999;
+ break;
+
case ':': /* start new command line */
#ifdef FEAT_CON_DIALOG
if (!confirm_msg_used)
@@ -2444,14 +2502,12 @@
if (scroll == -1 && screen_ins_lines(0, 0, 1,
(int)Rows, NULL) == OK)
{
- /* clear last line, display line at top */
- screen_fill((int)Rows - 1, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
+ /* display line at top */
(void)disp_sb_line(0, mp);
}
else
{
- /* redisplay */
+ /* redisplay all lines */
screenclear();
for (i = 0; i < Rows - 1; ++i)
mp = disp_sb_line(i, mp);
@@ -2466,6 +2522,7 @@
{
/* scroll up, display line at bottom */
msg_scroll_up();
+ ++msg_scrolled;
screen_fill((int)Rows - 2, (int)Rows - 1, 0,
(int)Columns, ' ', ' ', 0);
mp_last = disp_sb_line((int)Rows - 2, mp_last);
@@ -2473,9 +2530,11 @@
}
}
- if (scroll <= 0)
+ if (scroll < 0 || (scroll == 0 && mp_last != NULL))
{
/* displayed the requested text, more prompt again */
+ screen_fill((int)Rows - 1, (int)Rows, 0,
+ (int)Columns, ' ', ' ', 0);
msg_moremsg(FALSE);
continue;
}
diff --git a/src/normal.c b/src/normal.c
index 5f78f33..6279a6b 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -7564,6 +7564,10 @@
break;
#endif
+ case '<':
+ show_sb_text();
+ break;
+
/*
* "gg": Goto the first line in file. With a count it goes to
* that line number like for "G". -- webb
diff --git a/src/spell.c b/src/spell.c
index 52b7b4a..a66ff61 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -672,6 +672,9 @@
# define SPELL_TOUPPER(c) ((c) < 256 ? spelltab.st_upper[c] : (c))
# define SPELL_ISUPPER(c) ((c) < 256 ? spelltab.st_isu[c] : FALSE)
#else
+# if defined(HAVE_WCHAR_H)
+# include <wchar.h> /* for towupper() and towlower() */
+# endif
/* Multi-byte implementation. For Unicode we can call utf_*(), but don't do
* that for ASCII, because we don't want to use 'casemap' here. Otherwise use
* the "w" library function for characters above 255 if available. */
@@ -3147,7 +3150,7 @@
static char_u *get_pfxlist __ARGS((afffile_T *affile, char_u *afflist, sblock_T **blp));
static int store_aff_word __ARGS((char_u *word, spellinfo_T *spin, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int comb, int flags, char_u *pfxlist));
static int spell_read_wordfile __ARGS((char_u *fname, spellinfo_T *spin));
-static void *getroom __ARGS((sblock_T **blp, size_t len));
+static void *getroom __ARGS((sblock_T **blp, size_t len, int align));
static char_u *getroom_save __ARGS((sblock_T **blp, char_u *s));
static void free_blocks __ARGS((sblock_T *bl));
static wordnode_T *wordtree_alloc __ARGS((sblock_T **blp));
@@ -3240,7 +3243,7 @@
/*
* Allocate and init the afffile_T structure.
*/
- aff = (afffile_T *)getroom(&spin->si_blocks, sizeof(afffile_T));
+ aff = (afffile_T *)getroom(&spin->si_blocks, sizeof(afffile_T), TRUE);
if (aff == NULL)
return NULL;
hash_init(&aff->af_pref);
@@ -3368,7 +3371,7 @@
/* New affix letter. */
cur_aff = (affheader_T *)getroom(&spin->si_blocks,
- sizeof(affheader_T));
+ sizeof(affheader_T), TRUE);
if (cur_aff == NULL)
break;
cur_aff->ah_key[0] = *items[1]; /* TODO: multi-byte? */
@@ -3428,7 +3431,7 @@
/* New item for an affix letter. */
--aff_todo;
aff_entry = (affentry_T *)getroom(&spin->si_blocks,
- sizeof(affentry_T));
+ sizeof(affentry_T), TRUE);
if (aff_entry == NULL)
break;
aff_entry->ae_rare = rare;
@@ -4003,7 +4006,7 @@
}
}
if (round == 1 && cnt > 0)
- res = getroom(blp, cnt + 1);
+ res = getroom(blp, cnt + 1, FALSE);
if (res == NULL)
break;
}
@@ -4379,13 +4382,20 @@
* Returns NULL when out of memory.
*/
static void *
-getroom(blp, len)
+getroom(blp, len, align)
sblock_T **blp;
- size_t len; /* length needed */
+ size_t len; /* length needed */
+ int align; /* align for pointer */
{
char_u *p;
sblock_T *bl = *blp;
+ if (align && bl != NULL)
+ /* Round size up for alignment. On some systems structures need to be
+ * aligned to the size of a pointer (e.g., SPARC). */
+ bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
+ & ~(sizeof(char *) - 1);
+
if (bl == NULL || bl->sb_used + len > SBLOCKSIZE)
{
/* Allocate a block of memory. This is not freed until much later. */
@@ -4413,7 +4423,7 @@
{
char_u *sc;
- sc = (char_u *)getroom(blp, STRLEN(s) + 1);
+ sc = (char_u *)getroom(blp, STRLEN(s) + 1, FALSE);
if (sc != NULL)
STRCPY(sc, s);
return sc;
@@ -4444,7 +4454,7 @@
wordtree_alloc(blp)
sblock_T **blp;
{
- return (wordnode_T *)getroom(blp, sizeof(wordnode_T));
+ return (wordnode_T *)getroom(blp, sizeof(wordnode_T), TRUE);
}
/*
@@ -4541,7 +4551,7 @@
|| node->wn_prefixID != prefixID)))
{
/* Allocate a new node. */
- np = (wordnode_T *)getroom(blp, sizeof(wordnode_T));
+ np = (wordnode_T *)getroom(blp, sizeof(wordnode_T), TRUE);
if (np == NULL)
return FAIL;
np->wn_byte = word[i];