commit bb5c6614eb171eef8c08474e0f949fe18ef4b230 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Fri May 19 11:12:51 2017 +0300 * lisp/replace.el (query-replace-regexp-eval): Doc fix. diff --git a/lisp/replace.el b/lisp/replace.el index 477cc9c305..64dfe7da22 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -464,8 +464,8 @@ reference `replace-count' to get the number of replacements already made. If the result of TO-EXPR is not a string, it is converted to one using `prin1-to-string' with the NOESCAPE argument (which see). -For convenience, when entering TO-EXPR interactively, you can use `\\&' or -`\\0' to stand for whatever matched the whole of REGEXP, and `\\N' (where +For convenience, when entering TO-EXPR interactively, you can use `\\&' +to stand for whatever matched the whole of REGEXP, and `\\N' (where N is a digit) to stand for whatever matched the Nth `\\(...\\)' (1-based) in REGEXP. commit 7c951fd51832badb09055a8e177f8ec358cbbdcf Author: Paul Eggert Date: Fri May 19 00:11:48 2017 -0700 Attempt to work around macOS vfork bug Problem reported by YAMAMOTO Mitsuharu in: http://lists.gnu.org/archive/html/emacs-devel/2017-05/msg00342.html This is related to the fix for Bug#26397. * src/callproc.c (call_process_cleanup, call_process) [!MSDOS]: Report internal error if wait_for_termination fails. * src/sysdep.c (get_child_status): Return -1 if waitpid is buggy, instead of aborting. (wait_for_termination): Return bool success value. All callers changed. diff --git a/src/callproc.c b/src/callproc.c index e967e45d03..7c85eed835 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -202,10 +202,11 @@ call_process_cleanup (Lisp_Object buffer) message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); /* This will quit on C-g. */ - wait_for_termination (synch_process_pid, 0, 1); - + bool wait_ok = wait_for_termination (synch_process_pid, NULL, true); synch_process_pid = 0; - message1 ("Waiting for process to die...done"); + message1 (wait_ok + ? "Waiting for process to die...done" + : "Waiting for process to die...internal error"); } #endif /* !MSDOS */ } @@ -866,9 +867,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, make_number (total_read)); } + bool wait_ok = true; #ifndef MSDOS /* Wait for it to terminate, unless it already has. */ - wait_for_termination (pid, &status, fd0 < 0); + wait_ok = wait_for_termination (pid, &status, fd0 < 0); #endif /* Don't kill any children that the subprocess may have left behind @@ -878,6 +880,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, SAFE_FREE (); unbind_to (count, Qnil); + if (!wait_ok) + return build_unibyte_string ("internal error"); + if (WIFSIGNALED (status)) { const char *signame; diff --git a/src/sysdep.c b/src/sysdep.c index ac6eed0e58..70f4a9dd7e 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -368,8 +368,8 @@ init_baud_rate (int fd) Use waitpid-style OPTIONS when waiting. If INTERRUPTIBLE, this function is interruptible by a signal. - Return CHILD if successful, 0 if no status is available; - the latter is possible only when options & NOHANG. */ + Return CHILD if successful, 0 if no status is available, and a + negative value (setting errno) if waitpid is buggy. */ static pid_t get_child_status (pid_t child, int *status, int options, bool interruptible) { @@ -392,13 +392,14 @@ get_child_status (pid_t child, int *status, int options, bool interruptible) pid = waitpid (child, status, options); if (0 <= pid) break; - - /* Check that CHILD is a child process that has not been reaped, - and that STATUS and OPTIONS are valid. Otherwise abort, - as continuing after this internal error could cause Emacs to - become confused and kill innocent-victim processes. */ if (errno != EINTR) - emacs_abort (); + { + /* Most likely, waitpid is buggy and the operating system + lost track of the child somehow. Return -1 and let the + caller try to figure things out. Possibly the bug could + cause Emacs to kill the wrong process. Oh well. */ + return pid; + } } /* If successful and status is requested, tell wait_reading_process_output @@ -413,11 +414,13 @@ get_child_status (pid_t child, int *status, int options, bool interruptible) CHILD must be a child process that has not been reaped. If STATUS is non-null, store the waitpid-style exit status into *STATUS and tell wait_reading_process_output that it needs to look around. - If INTERRUPTIBLE, this function is interruptible by a signal. */ -void + If INTERRUPTIBLE, this function is interruptible by a signal. + Return true if successful, false (setting errno) if CHILD cannot be + waited for because waitpid is buggy. */ +bool wait_for_termination (pid_t child, int *status, bool interruptible) { - get_child_status (child, status, 0, interruptible); + return 0 <= get_child_status (child, status, 0, interruptible); } /* Report whether the subprocess with process id CHILD has changed status. diff --git a/src/syswait.h b/src/syswait.h index 846a975b24..055562ae48 100644 --- a/src/syswait.h +++ b/src/syswait.h @@ -56,7 +56,7 @@ along with GNU Emacs. If not, see . */ #endif /* Defined in sysdep.c. */ -extern void wait_for_termination (pid_t, int *, bool); +extern bool wait_for_termination (pid_t, int *, bool); extern pid_t child_status_changed (pid_t, int *, int); #endif /* EMACS_SYSWAIT_H */ commit df9bec3b39b12b33db8f5a97d86797f6636e5e7d Author: Eli Zaretskii Date: Fri May 19 10:01:23 2017 +0300 Adjust defcustom form for 'auto-hscroll-mode' * lisp/cus-start.el (standard) : Adjust the defcustom form. Suggested by Stephen Berman . diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 117b23debe..e11f749556 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -556,7 +556,15 @@ since it could result in memory overflow and make Emacs crash." (const :tag "Text-image-horiz" :value text-image-horiz) (const :tag "System default" :value nil)) "24.1") (tool-bar-max-label-size frames integer "24.1") - (auto-hscroll-mode scrolling boolean "21.1") + (auto-hscroll-mode scrolling + (choice + (const :tag "Don't scroll automatically" + :value nil) + (const :tag "Scroll the entire window" + :value t) + (const :tag "Scroll only the current line" + :value 'current-line)) + "26.1") (void-text-area-pointer cursor (choice (const :tag "Standard (text pointer)" :value nil) commit 7e3e51f4e288379be6a8731b739b63b9386940f7 Author: Paul Eggert Date: Thu May 18 20:40:42 2017 -0700 Fix DARWIN_OS_CASE_SENSITIVE_FIXME==2 false alarm * src/fileio.c (file_name_case_insensitive_p): Don’t compile the (DARWIN_OS_CASE_SENSITIVE_FIXME == 2) code unless DARWIN_OS_CASE_SENSITIVE_FIXME is 2. Problem reported by Philipp Stephani in: http://lists.gnu.org/archive/html/emacs-devel/2017-05/msg00495.html diff --git a/src/fileio.c b/src/fileio.c index acbf76e0d8..e5e350542f 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2294,10 +2294,14 @@ file_name_case_insensitive_p (const char *filename) & VOL_CAP_FMT_CASE_SENSITIVE); } } - else if (DARWIN_OS_CASE_SENSITIVE_FIXME == 2) +# if DARWIN_OS_CASE_SENSITIVE_FIXME == 2 { /* The following is based on - http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. */ + http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00010.html. + It is normally not even compiled, since it runs afoul of + static checking. See: + http://lists.gnu.org/archive/html/emacs-devel/2017-05/msg00495.html + */ struct attrlist alist; unsigned char buffer[sizeof (vol_capabilities_attr_t) + sizeof (size_t)]; @@ -2309,6 +2313,7 @@ file_name_case_insensitive_p (const char *filename) vol_capabilities_attr_t *vcaps = buffer; return !(vcaps->capabilities[0] & VOL_CAP_FMT_CASE_SENSITIVE); } +# endif #endif /* DARWIN_OS */ #if defined CYGWIN || defined DOS_NT commit af4ac3dc852647e5ea41be5ffc387be591978aee Author: Paul Eggert Date: Thu May 18 20:27:11 2017 -0700 Port --enable-gcc-warnings to clang 3.9.1 * configure.ac (WERROR_CFLAGS): Omit -Wdouble-promotion if clang. Problem reported by Philipp Stephani in: http://lists.gnu.org/archive/html/emacs-devel/2017-05/msg00495.html diff --git a/configure.ac b/configure.ac index 34b75a768b..03542a6b1c 100644 --- a/configure.ac +++ b/configure.ac @@ -963,6 +963,7 @@ AS_IF([test $gl_gcc_warnings = no], if test $emacs_cv_clang = yes; then nw="$nw -Wcast-align" + nw="$nw -Wdouble-promotion" fi # This causes too much noise in the MinGW build commit 9647430ae8744bd4dee29f1269b74f65c09274d2 Author: Paul Eggert Date: Thu May 18 20:02:42 2017 -0700 Clean up compiler warning in emacs-module.c * src/emacs-module.c (MODULE_SETJMP_1): Use the local var instead of leaving it unused, to pacify picky compilers. (module_reset_handlerlist): Now takes a dummy pointer to a struct handler *, instead of a dummy pointer to an int. All uses changed. diff --git a/src/emacs-module.c b/src/emacs-module.c index cd025a1396..5aa8a88174 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -109,7 +109,7 @@ static void module_handle_throw (emacs_env *, Lisp_Object); static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object); static void module_non_local_exit_throw_1 (emacs_env *, Lisp_Object, Lisp_Object); static void module_out_of_memory (emacs_env *); -static void module_reset_handlerlist (const int *); +static void module_reset_handlerlist (struct handler *const *); /* We used to return NULL when emacs_value was a different type from Lisp_Object, but nowadays we just use Qnil instead. Although they @@ -160,17 +160,18 @@ static emacs_value const module_nil = 0; /* TODO: Make backtraces work if this macros is used. */ -#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \ +#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c0, c) \ if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \ return retval; \ - struct handler *c = push_handler_nosignal (Qt, handlertype); \ - if (!c) \ + struct handler *c0 = push_handler_nosignal (Qt, handlertype); \ + if (!c0) \ { \ module_out_of_memory (env); \ return retval; \ } \ verify (module_has_cleanup); \ - int dummy __attribute__ ((cleanup (module_reset_handlerlist))); \ + struct handler *c __attribute__ ((cleanup (module_reset_handlerlist))) \ + = c0; \ if (sys_setjmp (c->jmp)) \ { \ (handlerfunc) (env, c->val); \ @@ -919,7 +920,7 @@ finalize_environment (struct emacs_env_private *env) code in eval.c for details. The macros below arrange for this function to be called automatically. DUMMY is ignored. */ static void -module_reset_handlerlist (const int *dummy) +module_reset_handlerlist (struct handler *const *dummy) { handlerlist = handlerlist->next; } commit e41030971f37375b9bb16c248f3b5d8d12064743 Author: Philipp Stephani Date: Thu May 18 19:15:26 2017 -0700 Clean up some compiler warnings * src/sysdep.c (system_process_attributes) [DARWIN_OS]: Remove unused locals. diff --git a/src/sysdep.c b/src/sysdep.c index 91b2a5cb94..ac6eed0e58 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -3707,14 +3707,9 @@ Lisp_Object system_process_attributes (Lisp_Object pid) { int proc_id; - int pagesize = getpagesize (); - unsigned long npages; - int fscale; struct passwd *pw; struct group *gr; char *ttyname; - size_t len; - char args[MAXPATHLEN]; struct timeval starttime; struct timespec t, now; struct rusage *rusage; commit 064b92d6e5a80f5435e2d941ec400ff9bd63d127 Author: Eli Zaretskii Date: Thu May 18 23:18:29 2017 +0300 Support hscrolling only the current line * src/xdisp.c (hscrolling_current_line_p): New function. (init_iterator): If auto-hscrolling just the current line, don't increment the iterator's first_visible_x and last_visible_x variables. (hscroll_window_tree): Recompute window's hscroll when moving vertically to another screen line. (redisplay_window): If we are hscrolling only the current line, disable the optimizations that rely on the current matrix being up-to-date. (display_line): Accept an additional argument CURSOR_VPOS, the vertical position of the current screen line which might need hscrolling; all callers changed. Compute first_visible_x and last_visible_x specially when auto-hscrolling current line, by repeating the calculation that is done in init_iterator in other modes. (syms_of_xdisp) : No longer boolean, it can now accept a 3rd value 'current-line, to turn on the mode where only the current line is hscrolled. * etc/NEWS: Mention the new auto-hscroll-mode value. diff --git a/etc/NEWS b/etc/NEWS index 6851dc9a0e..4121c44b0c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -357,6 +357,12 @@ you may set this variable to nil. (Behind the scenes, there is now a new mode line construct, '%C', which operates exactly as '%c' does except that it counts from one.) +** New single-line horizontal scrolling mode. +The 'auto-hscroll-mode' variable can now have a new special value, +'current-line', which causes only the line where the cursor is +displayed to be horizontally scrolled when lines are truncated on +display and point moves outside the left or right window margin. + +++ ** Two new user options 'list-matching-lines-jump-to-current-line' and 'list-matching-lines-current-line-face' to show highlighted the current diff --git a/src/xdisp.c b/src/xdisp.c index cdea20993c..96bc1a5e03 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -832,7 +832,7 @@ static bool cursor_row_fully_visible_p (struct window *, bool, bool); static bool update_menu_bar (struct frame *, bool, bool); static bool try_window_reusing_current_matrix (struct window *); static int try_window_id (struct window *); -static bool display_line (struct it *); +static bool display_line (struct it *, int); static int display_mode_lines (struct window *); static int display_mode_line (struct window *, enum face_id, Lisp_Object); static int display_mode_element (struct it *, int, int, int, Lisp_Object, @@ -2513,6 +2513,14 @@ adjust_window_ends (struct window *w, struct glyph_row *row, bool current) = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix); } +static bool +hscrolling_current_line_p (struct window *w) +{ + return (!w->suspend_auto_hscroll + && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents), + Qcurrent_line)); +} + /*********************************************************************** Lisp form evaluation ***********************************************************************/ @@ -2882,8 +2890,11 @@ init_iterator (struct it *it, struct window *w, } else { - it->first_visible_x - = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); + if (hscrolling_current_line_p (w)) + it->first_visible_x = 0; + else + it->first_visible_x = + window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f); it->last_visible_x = (it->first_visible_x + window_box_width (w, TEXT_AREA)); @@ -13031,6 +13042,7 @@ hscroll_window_tree (Lisp_Object window) cursor_row = bottom_row - 1; } bool row_r2l_p = cursor_row->reversed_p; + bool hscl = hscrolling_current_line_p (w); text_area_width = window_box_width (w, TEXT_AREA); @@ -13081,7 +13093,13 @@ hscroll_window_tree (Lisp_Object window) && cursor_row->truncated_on_right_p && w->cursor.x <= h_margin) || (w->hscroll - && (w->cursor.x >= text_area_width - h_margin)))))) + && (w->cursor.x >= text_area_width - h_margin)))) + /* This last condition is needed when moving + vertically from an hscrolled line to a short line + that doesn't need to be hscrolled. If we omit + this condition, the line from which we move will + remain hscrolled. */ + || (hscl && w->hscroll && !cursor_row->truncated_on_left_p))) { struct it it; ptrdiff_t hscroll; @@ -13101,6 +13119,9 @@ hscroll_window_tree (Lisp_Object window) /* Move iterator to pt starting at cursor_row->start in a line with infinite width. */ init_to_row_start (&it, w, cursor_row); + if (hscl) + it.first_visible_x = window_hscroll_limited (w, it.f) + * FRAME_COLUMN_WIDTH (it.f); it.last_visible_x = INFINITY; move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); /* If the line ends in an overlay string with a newline, @@ -13112,6 +13133,9 @@ hscroll_window_tree (Lisp_Object window) if (it.method == GET_FROM_STRING && pt > 1) { init_to_row_start (&it, w, cursor_row); + if (hscl) + it.first_visible_x = (window_hscroll_limited (w, it.f) + * FRAME_COLUMN_WIDTH (it.f)); move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS); } current_buffer = saved_current_buffer; @@ -13153,7 +13177,12 @@ hscroll_window_tree (Lisp_Object window) /* Don't prevent redisplay optimizations if hscroll hasn't changed, as it will unnecessarily slow down redisplay. */ - if (w->hscroll != hscroll) + if (w->hscroll != hscroll + /* When hscrolling only the current line, we need to + report hscroll even if its value is equal to the + previous one, because the new line might need a + different value. */ + || (hscl && w->last_cursor_vpos != w->cursor.vpos)) { struct buffer *b = XBUFFER (w->contents); b->prevent_redisplay_optimizations_p = true; @@ -13921,7 +13950,7 @@ redisplay_internal (void) it.vpos = this_line_vpos; it.current_y = this_line_y; it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos); - display_line (&it); + display_line (&it, -1); /* If line contains point, is not continued, and ends at same distance from eob as before, we win. */ @@ -16431,7 +16460,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) = (w->window_end_valid && !current_buffer->clip_changed && !current_buffer->prevent_redisplay_optimizations_p - && !window_outdated (w)); + && !window_outdated (w) + && !hscrolling_current_line_p (w)); /* Run the window-text-change-functions if it is possible that the text on the screen has changed @@ -17408,6 +17438,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) struct it it; struct glyph_row *last_text_row = NULL; struct frame *f = XFRAME (w->frame); + int cursor_vpos = w->cursor.vpos; /* Make POS the new window start. */ set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos)); @@ -17423,7 +17454,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) /* Display all lines of W. */ while (it.current_y < it.last_visible_y) { - if (display_line (&it)) + if (display_line (&it, cursor_vpos)) last_text_row = it.glyph_row - 1; if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE)) return 0; @@ -17599,7 +17630,7 @@ try_window_reusing_current_matrix (struct window *w) break; it.glyph_row->reversed_p = false; - if (display_line (&it)) + if (display_line (&it, -1)) last_text_row = it.glyph_row - 1; } @@ -17778,7 +17809,7 @@ try_window_reusing_current_matrix (struct window *w) w->cursor.vpos = -1; last_text_row = NULL; while (it.current_y < it.last_visible_y && !f->fonts_changed) - if (display_line (&it)) + if (display_line (&it, w->cursor.vpos)) last_text_row = it.glyph_row - 1; /* If point is in a reused row, adjust y and vpos of the cursor @@ -18634,7 +18665,7 @@ try_window_id (struct window *w) && (first_unchanged_at_end_row == NULL || IT_CHARPOS (it) < stop_pos)) { - if (display_line (&it)) + if (display_line (&it, -1)) last_text_row = it.glyph_row - 1; } @@ -18900,7 +18931,7 @@ try_window_id (struct window *w) displayed invalid in the current matrix by setting their enabled_p flag to false. */ SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false); - if (display_line (&it)) + if (display_line (&it, w->cursor.vpos)) last_text_row_at_end = it.glyph_row - 1; } } @@ -20618,10 +20649,11 @@ find_row_edges (struct it *it, struct glyph_row *row, IT->w from text at the current position of IT. See dispextern.h for an overview of struct it. Value is true if IT->glyph_row displays text, as opposed to a line displaying ZV - only. */ + only. CURSOR_VPOS is the window-relative vertical position of + the glyph row displaying the cursor, or -1 if unknown. */ static bool -display_line (struct it *it) +display_line (struct it *it, int cursor_vpos) { struct glyph_row *row = it->glyph_row; Lisp_Object overlay_arrow_string; @@ -20639,6 +20671,8 @@ display_line (struct it *it) ptrdiff_t min_pos = ZV + 1, max_pos = 0; ptrdiff_t min_bpos UNINIT, max_bpos UNINIT; bool pending_handle_line_prefix = false; + int first_visible_x = it->first_visible_x; + int last_visible_x = it->last_visible_x; /* We always start displaying at hpos zero even if hscrolled. */ eassert (it->hpos == 0 && it->current_x == 0); @@ -20668,26 +20702,38 @@ display_line (struct it *it) recenter_overlay_lists but the first will be pretty cheap. */ recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); + /* If we are going to display the cursor's line, account for the + hscroll of that line. */ + if (cursor_vpos >= 0 && it->vpos == cursor_vpos + && hscrolling_current_line_p (it->w)) + { + int x_incr = + window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); + + first_visible_x += x_incr; + last_visible_x += x_incr; + } + /* Move over display elements that are not visible because we are - hscrolled. This may stop at an x-position < IT->first_visible_x + hscrolled. This may stop at an x-position < first_visible_x if the first glyph is partially visible or if we hit a line end. */ - if (it->current_x < it->first_visible_x) + if (it->current_x < first_visible_x) { enum move_it_result move_result; this_line_min_pos = row->start.pos; - move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x, + move_result = move_it_in_display_line_to (it, ZV, first_visible_x, MOVE_TO_POS | MOVE_TO_X); /* If we are under a large hscroll, move_it_in_display_line_to could hit the end of the line without reaching - it->first_visible_x. Pretend that we did reach it. This is + first_visible_x. Pretend that we did reach it. This is especially important on a TTY, where we will call extend_face_to_end_of_line, which needs to know how many blank glyphs to produce. */ - if (it->current_x < it->first_visible_x + if (it->current_x < first_visible_x && (move_result == MOVE_NEWLINE_OR_CR || move_result == MOVE_POS_MATCH_OR_ZV)) - it->current_x = it->first_visible_x; + it->current_x = first_visible_x; /* Record the smallest positions seen while we moved over display elements that are not visible. This is needed by @@ -20881,7 +20927,7 @@ display_line (struct it *it) if (/* Not a newline. */ nglyphs > 0 /* Glyphs produced fit entirely in the line. */ - && it->current_x < it->last_visible_x) + && it->current_x < last_visible_x) { it->hpos += nglyphs; row->ascent = max (row->ascent, it->max_ascent); @@ -20891,13 +20937,13 @@ display_line (struct it *it) it->max_phys_ascent + it->max_phys_descent); row->extra_line_spacing = max (row->extra_line_spacing, it->max_extra_line_spacing); - if (it->current_x - it->pixel_width < it->first_visible_x + if (it->current_x - it->pixel_width < first_visible_x /* In R2L rows, we arrange in extend_face_to_end_of_line to add a right offset to the line, by a suitable change to the stretch glyph that is the leftmost glyph of the line. */ && !row->reversed_p) - row->x = x - it->first_visible_x; + row->x = x - first_visible_x; /* Record the maximum and minimum buffer positions seen so far in glyphs that will be displayed by this row. */ if (it->bidi_p) @@ -20922,9 +20968,9 @@ display_line (struct it *it) if (/* Lines are continued. */ it->line_wrap != TRUNCATE && (/* Glyph doesn't fit on the line. */ - new_x > it->last_visible_x + new_x > last_visible_x /* Or it fits exactly on a window system frame. */ - || (new_x == it->last_visible_x + || (new_x == last_visible_x && FRAME_WINDOW_P (it->f) && (row->reversed_p ? WINDOW_LEFT_FRINGE_WIDTH (it->w) @@ -20933,7 +20979,7 @@ display_line (struct it *it) /* End of a continued line. */ if (it->hpos == 0 - || (new_x == it->last_visible_x + || (new_x == last_visible_x && FRAME_WINDOW_P (it->f) && (row->reversed_p ? WINDOW_LEFT_FRINGE_WIDTH (it->w) @@ -21076,10 +21122,10 @@ display_line (struct it *it) ? WINDOW_LEFT_FRINGE_WIDTH (it->w) : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0) produce_special_glyphs (it, IT_CONTINUATION); - it->continuation_lines_width += it->last_visible_x; + it->continuation_lines_width += last_visible_x; row->ends_in_middle_of_char_p = true; row->continued_p = true; - glyph->pixel_width = it->last_visible_x - x; + glyph->pixel_width = last_visible_x - x; it->starts_in_middle_of_char_p = true; if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0) @@ -21123,7 +21169,7 @@ display_line (struct it *it) break; } - else if (new_x > it->first_visible_x) + else if (new_x > first_visible_x) { /* Increment number of glyphs actually displayed. */ ++it->hpos; @@ -21134,14 +21180,14 @@ display_line (struct it *it) if (it->bidi_p) RECORD_MAX_MIN_POS (it); - if (x < it->first_visible_x && !row->reversed_p) + if (x < first_visible_x && !row->reversed_p) /* Glyph is partially visible, i.e. row starts at negative X position. Don't do that in R2L rows, where we arrange to add a right offset to the line in extend_face_to_end_of_line, by a suitable change to the stretch glyph that is the leftmost glyph of the line. */ - row->x = x - it->first_visible_x; + row->x = x - first_visible_x; /* When the last glyph of an R2L row only fits partially on the line, we need to set row->x to a negative offset, so that the leftmost glyph is @@ -21149,12 +21195,12 @@ display_line (struct it *it) going to produce the truncation glyph, this will be taken care of in produce_special_glyphs. */ if (row->reversed_p - && new_x > it->last_visible_x + && new_x > last_visible_x && !(it->line_wrap == TRUNCATE && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) { eassert (FRAME_WINDOW_P (it->f)); - row->x = it->last_visible_x - new_x; + row->x = last_visible_x - new_x; } } else @@ -21164,7 +21210,7 @@ display_line (struct it *it) move_it_in_display_line at the start of this function, unless the text display area of the window is empty. */ - eassert (it->first_visible_x <= it->last_visible_x); + eassert (first_visible_x <= last_visible_x); } } /* Even if this display element produced no glyphs at all, @@ -21233,8 +21279,8 @@ display_line (struct it *it) ? WINDOW_LEFT_FRINGE_WIDTH (it->w) : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) || it->what == IT_IMAGE)) - ? (it->current_x >= it->last_visible_x) - : (it->current_x > it->last_visible_x))) + ? (it->current_x >= last_visible_x) + : (it->current_x > last_visible_x))) { /* Maybe add truncation glyphs. */ if (!FRAME_WINDOW_P (it->f) @@ -21268,7 +21314,7 @@ display_line (struct it *it) /* produce_special_glyphs overwrites the last glyph, so we don't want that if we want to keep that last glyph, which means it's an image. */ - if (it->current_x > it->last_visible_x) + if (it->current_x > last_visible_x) { it->current_x = x_before; if (!FRAME_WINDOW_P (it->f)) @@ -21329,7 +21375,7 @@ display_line (struct it *it) /* If line is not empty and hscrolled, maybe insert truncation glyphs at the left window margin. */ - if (it->first_visible_x + if (first_visible_x && IT_CHARPOS (*it) != CHARPOS (row->start.pos)) { if (!FRAME_WINDOW_P (it->f) @@ -31906,12 +31952,15 @@ If a frame's ON-STATE has no entry in this list, the frame's other specifications determine how to blink the cursor off. */); Vblink_cursor_alist = Qnil; - DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p, + DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling, doc: /* Allow or disallow automatic horizontal scrolling of windows. -If non-nil, windows are automatically scrolled horizontally to make -point visible. */); - automatic_hscrolling_p = true; +The value `current-line' means the line displaying point in each window +is automatically scrolled horizontally to make point visible. +Any other non-nil value means all the lines in a window are automatically +scrolled horizontally to make point visible. */); + automatic_hscrolling = Qt; DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode"); + DEFSYM (Qcurrent_line, "current-line"); DEFVAR_INT ("hscroll-margin", hscroll_margin, doc: /* How many columns away from the window edge point is allowed to get commit f6816a659c61d26d2d3328f34e43280b4ae1cf09 Author: Eli Zaretskii Date: Thu May 18 22:54:35 2017 +0300 Fix last change in line-move-finish * lisp/simple.el (line-move-finish): Fix last change. This corrects a regression in C-n and C-p when lines are truncated, introduced by the change in 2017-05-10. diff --git a/lisp/simple.el b/lisp/simple.el index dfa30372dd..7f13df5006 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -6399,7 +6399,8 @@ If NOERROR, don't signal an error if we can't move that many lines." (point)))) ;; Move to the desired column. - (if line-move-visual + (if (and line-move-visual + (not (or truncate-lines truncate-partial-width-windows))) ;; Under line-move-visual, goal-column should be ;; interpreted in units of the frame's canonical character ;; width, which is exactly what vertical-motion does. commit 8deef1d6a7bf620abf4219b6471883381b817724 Author: Simen Heggestøyl Date: Thu May 18 17:59:56 2017 +0200 Expand docstring for CSS mode * lisp/textmodes/css-mode.el (css-completion-at-point, css-mode): Expand docstrings. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 165e5deb63..458ed9f8bb 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1350,7 +1350,8 @@ a list of completions." (defun css-completion-at-point () "Complete current symbol at point. Currently supports completion of CSS properties, property values, -pseudo-elements, pseudo-classes, at-rules, and bang-rules." +pseudo-elements, pseudo-classes, at-rules, bang-rules, and HTML +tags, classes and IDs." (or (css--complete-bang-rule) (css--complete-property-value) (css--complete-pseudo-element-or-class) @@ -1377,7 +1378,22 @@ pseudo-elements, pseudo-classes, at-rules, and bang-rules." ;;;###autoload (define-derived-mode css-mode prog-mode "CSS" - "Major mode to edit Cascading Style Sheets." + "Major mode to edit Cascading Style Sheets (CSS). +\\ +This mode provides syntax highlighting, indentation, completion, +and documentation lookup for CSS. + +Use `\\[complete-symbol]' to complete CSS properties, property values, +pseudo-elements, pseudo-classes, at-rules, bang-rules, and HTML +tags, classes and IDs. Completion candidates for HTML class +names and IDs are found by looking through open HTML mode +buffers. + +Use `\\[info-lookup-symbol]' to look up documentation of CSS properties, at-rules, +pseudo-classes, and pseudo-elements on the Mozilla Developer +Network (MDN). + +\\{css-mode-map}" (setq-local font-lock-defaults css-font-lock-defaults) (setq-local comment-start "/*") (setq-local comment-start-skip "/\\*+[ \t]*")