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: [ELPA] New package proposal: visual-path-abbrev.el Date: Sat, 02 Mar 2019 12:05:50 +0100 Message-ID: <87tvglpmcx.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="94470"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Mar 02 12:06:09 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 1h02T2-000OK0-SA for ged-emacs-devel@m.gmane.org; Sat, 02 Mar 2019 12:06:09 +0100 Original-Received: from localhost ([127.0.0.1]:52678 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h02T1-0000X6-Hg for ged-emacs-devel@m.gmane.org; Sat, 02 Mar 2019 06:06:07 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:34616) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h02Sp-0000Wy-VK for emacs-devel@gnu.org; Sat, 02 Mar 2019 06:05:57 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:39166) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h02Sp-0006AG-Q4 for emacs-devel@gnu.org; Sat, 02 Mar 2019 06:05:55 -0500 Original-Received: from auth2-smtp.messagingengine.com ([66.111.4.228]:49775) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.82) (envelope-from ) id 1h02So-0001Bn-K2 for emacs-devel@gnu.org; Sat, 02 Mar 2019 06:05:55 -0500 Original-Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailauth.nyi.internal (Postfix) with ESMTP id B876221B13 for ; Sat, 2 Mar 2019 06:05:53 -0500 (EST) Original-Received: from mailfrontend1 ([10.202.2.162]) by compute7.internal (MEProxy); Sat, 02 Mar 2019 06:05:53 -0500 X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedutddrvdejgddvgecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkfgfgggtgfesthhqredttd erjeenucfhrhhomhepvfgrshhsihhlohcujfhorhhnuceothhsughhsehgnhhurdhorhhg qeenucffohhmrghinhepghhnuhdrohhrghenucfkphepleefrddvfeeirdduvdelrdehvd enucfrrghrrghmpehmrghilhhfrhhomhepthhhohhrnhdomhgvshhmthhprghuthhhphgv rhhsohhnrghlihhthidqkeeijeefkeejkeegqdeifeehvdelkedqthhsughhpeepghhnuh drohhrghesfhgrshhtmhgrihhlrdhfmhenucevlhhushhtvghrufhiiigvpedt 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 A1D1CE4582 for ; Sat, 2 Mar 2019 06:05:52 -0500 (EST) 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:233756 Archived-At: Hi all, I've just written a small minor mode which abbreviates file paths visually by using overlays. When point enters such an overlay, the path is shown normally again. I wrote it mostly because at work our java code has a very deeply nested package structure which forced me to make my emacs frame running Magit (listing all modified files) wider than I like it in normal use. This package has been written over the last few hours and has no home yet. If that sounds good, I'd like to add it to ELPA (and just to ELPA). Also, suggestions for the code are welcome. Especially, there are two known problems: - Sometimes when scrolling fast and then stopping, only parts of the visible buffer portion got the overlays applied. You can try triggering that problem by enabling the mode in a *grep* buffer and then scrolling a long way. =20=20 - When lines are wrapped around and line-move-visual is t, the mode can make the line short enough so that it doesn't wrap anymore. But still next-line moves point to where it would belong if the mode were not active, i.e., point jumps to somewhere on the same line. =20=20 Bye, Tassilo --8<---------------cut here---------------start------------->8--- ;;; visual-path-abbrev.el --- Visually abbreviate paths -*- lexical-bindin= g: 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 file paths by usi= ng ;; 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 path normally. Also, abbreviated path are only ;; shown if the abbreviation as actually shorter as the original path (which ;; depends on what you add as replacement). ;; ;; There's stuff to customize, just check `M-x customize-group RET ;; visual-path-abbrev RET'. ;;; Code: (require 'seq) (defgroup visual-path-abbrev nil "Visually abbreviate the directory part of paths.") (defcustom visual-path-abbrev-regex (concat "\\(?:file://\\)?/?" "\\(?:[[:alnum:]@_.-]+/\\)+[[:alnum:]@_.-]*\\.\\w+") "Regexp matching paths.") (defcustom visual-path-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-path-abbrev-regex' will be replaced by `visual-path-abbrev-abbrev'.") (defcustom visual-path-abbrev-abbrev "=E2=80=A6" "String to be displayed instead of the match group 1 of `visual-path-abbrev-regex'.") (defun visual-path-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-path-abbrev-replace-regex visual-path-abbrev-abbrev dir nil nil 1)) file))) (defun visual-path-abbrev--not-on-overlay-p (_buffer pos path abbrev) (when-let ((ol (car (seq-filter (lambda (o) (overlay-get o 'visual-path-abbrev)) (overlays-at pos))))) (or (< (point) (overlay-start ol)) (> (point) (overlay-end ol))))) (defun visual-path-abbrev--abbrev-shorter-p (_buffer _pos path abbrev) (< (string-width abbrev) (string-width path))) (defvar visual-path-abbrev-display-predicates (list #'visual-path-abbrev--not-on-overlay-p #'visual-path-abbrev--abbrev-shorter-p)) (defun visual-path-abbrev--display-p (buffer pos path abbrev) (seq-every-p (lambda (pred) (funcall pred buffer pos path abbrev)) visual-path-abbrev-display-predicates)) (defun visual-path-abbrev--delete-overlays (beg end) (dolist (ol (overlays-in beg end)) (when (overlay-get ol 'visual-path-abbrev) (delete-overlay ol)))) (defun visual-path-abbrev--place-overlays (&rest _ignored) (save-excursion (let ((ws (window-start)) (we (window-end))) (visual-path-abbrev--delete-overlays ws we) (goto-char ws) (while (re-search-forward visual-path-abbrev-regex we t) (let* ((beg (match-beginning 0)) (end (match-end 0)) (path (match-string 0)) (ol (make-overlay beg end nil t)) (abbrev (visual-path-abbrev--get-abbrev path))) (overlay-put ol 'visual-path-abbrev t) (overlay-put ol 'display `(when (visual-path-abbrev--display-p object buffer-position ,path ,abbrev) . ,abbrev)) (overlay-put ol 'help-echo path)))))) (define-minor-mode visual-path-abbrev-mode "Visually abbreviate file paths." nil " VPAbbr" nil (if visual-path-abbrev-mode (progn (add-hook 'post-command-hook #'visual-path-abbrev--place-overlays t t) (visual-path-abbrev--place-overlays)) (remove-hook 'post-command-hook #'visual-path-abbrev--place-overlays t) (visual-path-abbrev--delete-overlays 1 (1+ (buffer-size))))) --8<---------------cut here---------------end--------------->8---