From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: [ELPA] New package proposal: visual-path-abbrev.el Date: Sun, 03 Mar 2019 10:46:09 +0100 Message-ID: <874l8k47fi.fsf@gnu.org> References: <87tvglpmcx.fsf@gnu.org> <83k1hhh5mb.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="22339"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Mar 03 10:46:50 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1h0Nhq-0005iu-8I for ged-emacs-devel@m.gmane.org; Sun, 03 Mar 2019 10:46:50 +0100 Original-Received: from localhost ([127.0.0.1]:36507 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Nhp-0004V2-5f for ged-emacs-devel@m.gmane.org; Sun, 03 Mar 2019 04:46:49 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:33165) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Nhc-0004Un-Sw for emacs-devel@gnu.org; Sun, 03 Mar 2019 04:46:39 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:54813) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0NhY-00068I-Ge for emacs-devel@gnu.org; Sun, 03 Mar 2019 04:46:33 -0500 Original-Received: from auth2-smtp.messagingengine.com ([66.111.4.228]:47069) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.82) (envelope-from ) id 1h0NhW-0001Zz-FD; Sun, 03 Mar 2019 04:46:30 -0500 Original-Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailauth.nyi.internal (Postfix) with ESMTP id DA1FA211B7; Sun, 3 Mar 2019 04:46:29 -0500 (EST) Original-Received: from mailfrontend1 ([10.202.2.162]) by compute7.internal (MEProxy); Sun, 03 Mar 2019 04:46:29 -0500 X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedutddrvdelgddtkecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufhffjgfkfgggtgfgsehtqhertddtreejnecuhfhrohhmpefvrghsshhi lhhoucfjohhrnhcuoehtshguhhesghhnuhdrohhrgheqnecuffhomhgrihhnpehgnhhurd horhhgnecukfhppeelfedrvdefiedruddvledrhedvnecurfgrrhgrmhepmhgrihhlfhhr ohhmpehthhhorhhnodhmvghsmhhtphgruhhthhhpvghrshhonhgrlhhithihqdekieejfe ekjeekgedqieefhedvleekqdhtshguhheppehgnhhurdhorhhgsehfrghsthhmrghilhdr fhhmnecuvehluhhsthgvrhfuihiivgeptd X-ME-Proxy: Original-Received: from thinkpad-t440p (p5dec8134.dip0.t-ipconnect.de [93.236.129.52]) by mail.messagingengine.com (Postfix) with ESMTPA id 0F3B3E44D7; Sun, 3 Mar 2019 04:46:14 -0500 (EST) Mail-Followup-To: Eli Zaretskii , emacs-devel@gnu.org In-Reply-To: <83k1hhh5mb.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 02 Mar 2019 13:34:36 +0200") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 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" Xref: news.gmane.org gmane.emacs.devel:233793 Archived-At: Eli Zaretskii writes: > Your code seems to update the overlays in a function called from > post-command-hook, but post-command-hook runs before redisplay updates > the window due to last command. So you are using stale window-start > and window-end values, and if the last command scrolls some file names > into the view, those file names might not have overlays on them. > > I think the preferred method is to use jit-lock-register to register > your function; see e.g. glasses.el for how this can be done. Ok, here's a new version using that approach and basically it works. However, there's a problem with the conditional 'display spec which should in theory un-abbreviate the file name as soon as point enter's the overlay's region. Oftentimes that doesn't happen until I explicitly force a redisplay with C-l or M-x. Is there a good way to cope with that? Tassilo =20=20=20=20=20=20=20=20 --8<---------------cut here---------------start------------->8--- ;;; visual-file-name-abbrev.el --- Visually abbreviate file names -*- lexi= cal-binding: t; -*- ;; Copyright (C) 2019 Free Software Foundation, Inc ;; Author: Tassilo Horn ;; Keywords: TODO ;; Version: TODO ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; ;; This minor mode abbreviates the directory part of file names by using ;; overlays. For example, a longish path like ;; ;; /home/myuser/Documents/Letters/Personal-Family/Letter-to-John.tex ;; ;; will be displayed like this: ;; ;; /h=E2=80=A6/m=E2=80=A6/D=E2=80=A6/L=E2=80=A6/P=E2=80=A6-F=E2=80=A6/Let= ter-to-John.tex ;; ;; By default, the abbreviate display is disabled when point enters the ove= rlay ;; so that you can edit the file name normally. Also, abbreviated file nam= es ;; are only shown if the abbreviation as actually shorter as the original o= ne ;; (which depends on what you add as replacement). ;; ;; There's stuff to customize, just check `M-x customize-group RET ;; visual-file-name-abbrev RET'. ;;; Code: (require 'subr-x) (require 'seq) (defgroup visual-file-name-abbrev nil "Visually abbreviate the directory part of paths.") (defcustom visual-file-name-abbrev-regex (concat "\\(?:file://\\)?/?" "\\(?:[[:alnum:]@_.-]+/\\)+[[:alnum:]@_.-]*\\.\\w+") "Regexp matching paths.") (defcustom visual-file-name-abbrev-replace-regex "[.@]?[[:alnum:]]\\([[:alnum:]]+\\)[-_/.]" "Regexp which will be visually replaced in paths. All matches of this regexp's group number 1 in the paths matching `visual-file-name-abbrev-regex' will be replaced by `visual-file-name-abbrev-abbrev'.") (defcustom visual-file-name-abbrev-abbrev "=E2=80=A6" "String to be displayed instead of the match group 1 of `visual-file-name-abbrev-regex'.") (defun visual-file-name-abbrev--get-abbrev (path) (let ((file (file-name-nondirectory path)) (dir (file-name-directory path))) (concat (file-name-as-directory (replace-regexp-in-string visual-file-name-abbrev-replace-regex visual-file-name-abbrev-abbrev dir nil nil 1)) file))) (defsubst visual-file-name-abbrev--get-overlay (pos) (car (seq-filter (lambda (o) (overlay-get o 'visual-file-name-abbrev)) (overlays-at pos)))) (defun visual-file-name-abbrev--not-on-overlay-p (_buffer pos path abbrev) (when-let ((ol (visual-file-name-abbrev--get-overlay pos))) (or (< (point) (overlay-start ol)) (> (point) (overlay-end ol))))) (defun visual-file-name-abbrev--abbrev-shorter-p (_buffer _pos path abbrev) (< (string-width abbrev) (string-width path))) (defvar visual-file-name-abbrev-display-predicates (list #'visual-file-name-abbrev--not-on-overlay-p #'visual-file-name-abbrev--abbrev-shorter-p)) (defun visual-file-name-abbrev--display-p (buffer pos path abbrev) (seq-every-p (lambda (pred) (funcall pred buffer pos path abbrev)) visual-file-name-abbrev-display-predicates)) (defun visual-file-name-abbrev--delete-overlays (beg end) (dolist (ol (overlays-in beg end)) (when (overlay-get ol 'visual-file-name-abbrev) (delete-overlay ol)))) (defun visual-file-name-abbrev--place-overlays (start end) (goto-char start) (while (re-search-forward visual-file-name-abbrev-regex end t) (let* ((m-beg (match-beginning 0)) (m-end (match-end 0)) (path (match-string 0)) (abbrev (visual-file-name-abbrev--get-abbrev path)) (ol (or (when-let ((o (visual-file-name-abbrev--get-overlay m-beg))) (move-overlay o m-beg m-end) o) (make-overlay m-beg m-end nil t)))) (overlay-put ol 'visual-file-name-abbrev t) (overlay-put ol 'evaporate t) (overlay-put ol 'help-echo path) (overlay-put ol 'display `(when (visual-file-name-abbrev--display-p object buffer-position ,path ,abbrev) . ,abbrev))))) (defun visual-file-name-abbrev--jit-lock (beg end &optional _old-len) "Function registered for jit-lock." (let ((beg-line (save-excursion (goto-char beg) (line-beginning-position)= )) (end-line (save-excursion (goto-char end) (line-end-position)))) (visual-file-name-abbrev--place-overlays beg-line end-line))) (define-minor-mode visual-file-name-abbrev-mode "Visually abbreviate file paths." nil " VFNAbbr" nil (if visual-file-name-abbrev-mode (progn (jit-lock-register #'visual-file-name-abbrev--jit-lock) (visual-file-name-abbrev--jit-lock (window-start) (window-end))) (jit-lock-unregister #'visual-file-name-abbrev--jit-lock) (visual-file-name-abbrev--delete-overlays 1 (1+ (buffer-size))))) --8<---------------cut here---------------end--------------->8---