From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Keith David Bershatsky Newsgroups: gmane.emacs.devel Subject: Re: How to obtain x/y/hpos/vpos at eol -- excluding overlay 'after-string. Date: Tue, 05 Apr 2016 10:37:44 -0700 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 (generated by - "") Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1459877899 11033 80.91.229.3 (5 Apr 2016 17:38:19 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 5 Apr 2016 17:38:19 +0000 (UTC) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Apr 05 19:38:11 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1anUva-00018k-Bv for ged-emacs-devel@m.gmane.org; Tue, 05 Apr 2016 19:38:10 +0200 Original-Received: from localhost ([::1]:38563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anUvZ-0008HN-Md for ged-emacs-devel@m.gmane.org; Tue, 05 Apr 2016 13:38:09 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33713) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anUvJ-0008HE-0L for emacs-devel@gnu.org; Tue, 05 Apr 2016 13:37:54 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1anUvH-0008Fh-7W for emacs-devel@gnu.org; Tue, 05 Apr 2016 13:37:52 -0400 Original-Received: from cobb.liquidweb.com ([50.28.13.150]:37398) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1anUvB-0008Ep-Ve; Tue, 05 Apr 2016 13:37:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lawlist.com; s=default; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Cc:To:From:Message-ID:Date; bh=w4SI6LXQvfDJ2f+bRiNnDeNhH/nPUa0VFGsDHVRIiOI=; b=UjjopfDr/tuiD9gokixgMWWRUV3/mOB1FF+OckTTRxnvtb2mez+RPeIK9sceLFIV91FMvXokKtw0nZ6rmjNQNvbfsrV+7L/b0OJANvN5cpp3rXmt3rrwrDrRjHCqxVV6; Original-Received: from cpe-45-48-239-195.socal.res.rr.com ([45.48.239.195]:49778 helo=server.private.localhost) by cobb.liquidweb.com with esmtp (Exim 4.82) (envelope-from ) id 1anUv9-0003bS-1K; Tue, 05 Apr 2016 13:37:43 -0400 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - cobb.liquidweb.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lawlist.com X-Get-Message-Sender-Via: cobb.liquidweb.com: acl_c_relayhosts_text_entry: lawlist|lawlist.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 50.28.13.150 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:202750 Archived-At: There two (2) major roadblocks that I have encountered with multiple cursors: PROBLEM # 1: `mc_x_y_hpos_vpos` needs to be modified to exclude overlays from the calculation so that placement and removal of fake cursors can be correctly achieved. Any assistance in modifying this function to exclude overlays from the calculation would be greatly appreciated. /* The mission critical function used by multiple cursors to extract coordinates. */ Lisp_Object mc_x_y_hpos_vpos (struct window *w, EMACS_INT posint, EMACS_INT start, EMACS_INT end) { struct it it; void *itdata = bidi_shelve_cache (); struct text_pos pt, pos; int x, y, hpos, vpos; if (posint >= start && posint <= end) { SET_TEXT_POS_FROM_MARKER (pt, w->start); start_display (&it, w, pt); move_it_to (&it, posint, -1, -1, -1, MOVE_TO_POS); pos = it.current.pos; x = it.current_x; y = it.current_y; hpos = it.hpos; vpos = it.vpos; bidi_unshelve_cache (itdata, false); } else { x = -1; y = -1; hpos = -1; vpos = -1; } return listn (CONSTYPE_PURE, 4, make_number (x), make_number (y), make_number (hpos), make_number (vpos)); } PROBLEM # 2: When no scrolling occurs, the cache of previously laid multiple cursors is sufficient to remove them. When scrolling occurs (less than a full screen) -- e.g., previous/next-line or scroll-up/down -- the multiple cursors become moving targets. In that scenario, the previously recorded x/y/hpos/vpos will not suffice. I tried something elaborate to calculate the differential of `y` and `vpos` based on scrolling; however, that didn't work. Either my calculations are way off, or I do not understand what is happening when scrolling occurs. My idea was that I could add or subtract the differential from the stored values in the cache to pinpoint the new locations for the previously laid multiple cursors whenever scrolling occurred. LEGEND: * `start`: window-start. * `end`: window-end. * `prev`: value from the prior command loop. * `opoint`: original point. * `y_diff`: differential of `y` coordinate between command loops. * `vpos_diff: differential of `vpos` between command loops. if ((!NILP (BVAR (current_buffer, mc_list)) || w->mc_cache) && !MINI_WINDOW_P (w)) { Lisp_Object x_y_hpos_vpos_list; EMACS_INT start = CHARPOS (startp); EMACS_INT end = BUF_Z (buffer) - w->window_end_pos; if (w->mc.set_start_end) { if (w->mc.start) { w->mc.prev_start = w->mc.start; x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, w->mc.prev_start, start, end); w->mc.prev_start_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.prev_start_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.prev_start_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.prev_start_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); } else { w->mc.prev_start = -1; w->mc.prev_start_x = -1; w->mc.prev_start_y = -1; w->mc.prev_start_hpos = -1; w->mc.prev_start_vpos = -1; } if (w->mc.end) { w->mc.prev_end = w->mc.end; /* eob IS visible]. Excludes a situation when last visible line at bottom of window contains eob. */ if (w->mc.prev_end == end) { x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, w->mc.prev_end, start, end); w->mc.prev_end_x = w->mc.end_x; w->mc.prev_end_y = w->mc.end_y; w->mc.prev_end_hpos = w->mc.end_hpos; w->mc.prev_end_vpos = w->mc.end_vpos; } /* eob is NOT visible. Excludes a situation when last visible line at bottom of window contains eob. **/ else { x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, w->mc.prev_end, start, end); w->mc.prev_end_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.prev_end_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.prev_end_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.prev_end_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); } } else { w->mc.prev_end = -1; w->mc.prev_end_x = -1; w->mc.prev_end_y = -1; w->mc.prev_end_hpos = -1; w->mc.prev_end_vpos = -1; } if (w->mc.opoint) { w->mc.prev_opoint = w->mc.opoint; w->mc.prev_opoint_x = w->mc.opoint_x; w->mc.prev_opoint_y = w->mc.opoint_y; w->mc.prev_opoint_hpos = w->mc.opoint_hpos; w->mc.prev_opoint_vpos = w->mc.opoint_vpos; } /* FIXME -- the X and HPOS will always be wrong if point is at an overlay after-string. */ w->mc.opoint = PT; x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, w->mc.opoint, start, end); w->mc.opoint_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.opoint_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.opoint_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.opoint_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); w->mc.start = start; x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, start, start, end); w->mc.start_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.start_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.start_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.start_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); w->mc.end = end; x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, end, start, end); w->mc.end_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.end_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.end_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.end_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); /* Start remains the same. */ if (w->mc.prev_start_vpos == w->mc.start_vpos || w->mc.prev_end < w->mc.start) { w->mc.y_diff = 0; w->mc.vpos_diff = 0; } /* Screen moved ▼ -- e.g., `previous-line', `scroll-down'. */ else if (w->mc.prev_start_vpos > 0) { w->mc.y_diff = (w->mc.prev_start_y - w->mc.start_y) * -1; w->mc.vpos_diff = (w->mc.prev_start_vpos - w->mc.start_vpos) * -1; } /* Screen moved ▲ (eob NOT visible) -- e.g., `next-line', `scroll-up'. */ else if (w->mc.end_vpos > w->mc.prev_end_vpos && w->mc.prev_end != -1) { w->mc.y_diff = w->mc.end_y - w->mc.prev_end_y; w->mc.vpos_diff = w->mc.end_vpos - w->mc.prev_end_vpos; } /* Screen moved ▲ (eob IS visible) -- e.g., `next-line', `scroll-up'. */ else if (w->mc.end_vpos < w->mc.prev_end_vpos && w->mc.prev_end != -1) { w->mc.y_diff = w->mc.prev_end_y - w->mc.end_y; w->mc.vpos_diff = w->mc.prev_end_vpos - w->mc.end_vpos; } /* Screen moved ▲ (eob just became visible) -- e.g., `next-line', `scroll-up'. Absent subtracting 1 from w->mc.prev_end, that point and the new w->mc.end are on the same line and it appears that nothing has changed -- w->mc.prev_end is on the far left of the line and w->mc.end is on the far right of the line. */ else if (w->mc.end_vpos == w->mc.prev_end_vpos) { x_y_hpos_vpos_list = mc_x_y_hpos_vpos (w, w->mc.prev_end - 1, start, end); w->mc.prev_end_x = XINT (Fnth (make_number (0), x_y_hpos_vpos_list)); w->mc.prev_end_y = XINT (Fnth (make_number (1), x_y_hpos_vpos_list)); w->mc.prev_end_hpos = XINT (Fnth (make_number (2), x_y_hpos_vpos_list)); w->mc.prev_end_vpos = XINT (Fnth (make_number (3), x_y_hpos_vpos_list)); w->mc.y_diff = w->mc.end_y - w->mc.prev_end_y; w->mc.vpos_diff = w->mc.end_vpos - w->mc.prev_end_vpos; } /* `mc-list` has just been initialized -- previous start/end are set to -1. */ else if (w->mc.prev_end == -1) { w->mc.y_diff = 0; w->mc.vpos_diff = 0; } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; At Tue, 05 Apr 2016 18:08:09 +0300, Eli Zaretskii wrote: > > * * * > > This is indeed about something you do in C. However, I don't > understand why you try using posn-at-point, which is a Lisp API, for a > job you need to do in C. On the C level, you have access to a more > elaborate information, e.g. you can examine the object at point and do > something when it is an overlay string. > > I must admit I still don't see clearly why you need screen coordinates > corresponding to a buffer position, in the multiple-curses scenario. > Isn't it your code that positions those cursors in the first place? > If so, why do you need to find out where those cursors are, if your > code did the positioning?