aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris <[email protected]>2014-04-12 12:24:17 -0700
committerGlenn Morris <[email protected]>2014-04-12 12:24:17 -0700
commite0af409500d5f44b34a6e8d971f0c7abe1d747fe (patch)
treeda8c3218399660418391a9bc35d955aa4ff07c73 /src
parent3197074e49162f96a6eb33ca45fbbfddcf1ae01a (diff)
parent5121b6923beb2fb62b179b4a95b07f9feb969f3d (diff)
Merge from emacs-24; up to 2014-04-07T20:54:[email protected]
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog13
-rw-r--r--src/indent.c11
-rw-r--r--src/w32.c9
-rw-r--r--src/xdisp.c23
4 files changed, 47 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 927b001034..30852b3ae5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2014-04-12 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (move_it_by_lines): If a large portion of buffer text is
+ covered by a display string that ends in a newline, and that cases
+ going back by DVPOS lines to hit the search limit, lift the limit
+ and go back until DVPOS is reached. (Bug#17244)
+
+ * indent.c (Fvertical_motion): Handle correctly the case when the
+ display string is preceded by an empty line.
+
+ * w32.c (sys_umask) <WRITE_USER>: Remove redundant constant, and
+ use S_IWRITE instead.
+
2014-04-11 Glenn Morris <[email protected]>
* keyboard.c (Fopen_dribble_file): Make file private. (Bug#17187)
diff --git a/src/indent.c b/src/indent.c
index 683d44841b..dc86251892 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2051,8 +2051,15 @@ whether or not it is currently displayed in some window. */)
string, move_it_to will overshoot it, while vertical-motion
wants to put the cursor _before_ the display string. So in
that case, we move to buffer position before the display
- string, and avoid overshooting. */
- move_it_to (&it, disp_string_at_start_p ? PT - 1 : PT,
+ string, and avoid overshooting. But if the position before
+ the display string is a newline, we don't do this, because
+ otherwise we will end up in a screen line that is one too
+ far back. */
+ move_it_to (&it,
+ (!disp_string_at_start_p
+ || FETCH_BYTE (IT_BYTEPOS (it)) == '\n')
+ ? PT
+ : PT - 1,
-1, -1, -1, MOVE_TO_POS);
/* IT may move too far if truncate-lines is on and PT lies
diff --git a/src/w32.c b/src/w32.c
index ca7d1869b6..371cae9cb9 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -5353,11 +5353,6 @@ utime (const char *name, struct utimbuf *times)
return 0;
}
-/* Emacs expects us to support the traditional octal form of the mode
- bits, which is not what msvcrt.dll wants. */
-
-#define WRITE_USER 00200
-
int
sys_umask (int mode)
{
@@ -5369,14 +5364,14 @@ sys_umask (int mode)
at all. */
/* FIXME: if the GROUP and OTHER bits are reset, we should use ACLs
to prevent access by other users on NTFS. */
- if ((mode & WRITE_USER) != 0)
+ if ((mode & S_IWRITE) != 0)
arg |= S_IWRITE;
retval = _umask (arg);
/* Merge into the return value the bits they've set the last time,
which msvcrt.dll ignores and never returns. Emacs insists on its
notion of mask being identical to what we return. */
- retval |= (current_mask & ~WRITE_USER);
+ retval |= (current_mask & ~S_IWRITE);
current_mask = mode;
return retval;
diff --git a/src/xdisp.c b/src/xdisp.c
index 3431a7bad2..067d9f6ac0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9511,6 +9511,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
ptrdiff_t start_charpos, i;
int nchars_per_row
= (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
+ bool hit_pos_limit = false;
ptrdiff_t pos_limit;
/* Start at the beginning of the screen line containing IT's
@@ -9527,8 +9528,11 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
pos_limit = BEGV;
else
pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
+
for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
back_to_previous_visible_line_start (it);
+ if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
+ hit_pos_limit = true;
reseat (it, it->current.pos, 1);
/* Move further back if we end up in a string or an image. */
@@ -9572,6 +9576,25 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
else
bidi_unshelve_cache (it2data, 1);
}
+ else if (hit_pos_limit && pos_limit > BEGV
+ && dvpos < 0 && it2.vpos < -dvpos)
+ {
+ /* If we hit the limit, but still didn't make it far enough
+ back, that means there's a display string with a newline
+ covering a large chunk of text, and that caused
+ back_to_previous_visible_line_start try to go too far.
+ Punish those who commit such atrocities by going back
+ until we've reached DVPOS, after lifting the limit, which
+ could make it slow for very long lines. "If it hurts,
+ don't do that!" */
+ dvpos += it2.vpos;
+ RESTORE_IT (it, it, it2data);
+ for (i = -dvpos; i > 0; --i)
+ {
+ back_to_previous_visible_line_start (it);
+ it->vpos--;
+ }
+ }
else
RESTORE_IT (it, it, it2data);
}