├── .github ├── dependabot.yml └── workflows │ └── ci.yaml ├── .gitignore ├── README.md ├── flake.lock ├── flake.nix └── zzz-to-char.el /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | types: 8 | - opened 9 | - synchronize 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: cachix/install-nix-action@v31 16 | - run: nix build 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *-autoloads.el 2 | *.elc 3 | *~ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zzz to Char 2 | 3 | [![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.txt) 4 | [![MELPA](https://melpa.org/packages/zzz-to-char-badge.svg)](https://melpa.org/#/zzz-to-char) 5 | [![CI](https://github.com/mrkkrp/zzz-to-char/actions/workflows/ci.yaml/badge.svg)](https://github.com/mrkkrp/zzz-to-char/actions/workflows/ci.yaml) 6 | 7 | This package provides two new commands: `zzz-to-char` and `zzz-up-to-char` 8 | which work like the built-ins `zap-to-char` and `zap-up-to-char`, but allow 9 | the user to quickly select the exact character they want to zzz to. The 10 | commands work like the built-ins when there is only one occurrence of the 11 | target character, excepting that they automatically work in the backward 12 | direction, too. One can specify how many characters to scan from each side 13 | of the point, see `zzz-to-char-reach`. 14 | 15 | ## Installation 16 | 17 | The package is available via MELPA, so you can just type `M-x 18 | package-install RET zzz-to-char RET`. 19 | 20 | If you would like to install the package manually, download or clone it and 21 | put on Emacs' `load-path`. Then you can require it in your init file like 22 | this: 23 | 24 | ```emacs-lisp 25 | (require 'zzz-to-char) 26 | ``` 27 | 28 | ## Usage 29 | 30 | Just bind `zzz-to-char` or `zzz-to-char-up-to-char` (depends on your taste, 31 | the latter doesn't include the target char into the killed text): 32 | 33 | ```emacs-lisp 34 | (global-set-key (kbd "M-z") #'zzz-to-char) 35 | ``` 36 | 37 | ## License 38 | 39 | Copyright © 2015–present Mark Karpov 40 | 41 | Distributed under GNU GPL, version 3. 42 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "emacs-package-flake": { 4 | "inputs": { 5 | "flake-utils": "flake-utils", 6 | "nixpkgs": "nixpkgs" 7 | }, 8 | "locked": { 9 | "lastModified": 1686064298, 10 | "narHash": "sha256-AmhZ5UPCdEyUuYCKuNuga59YDNJmyyjImYc/J5wo4vE=", 11 | "owner": "mrkkrp", 12 | "repo": "emacs-package-flake", 13 | "rev": "ffeea4f1aa7d32eb09e53772e183f73ebda72cfd", 14 | "type": "github" 15 | }, 16 | "original": { 17 | "owner": "mrkkrp", 18 | "repo": "emacs-package-flake", 19 | "type": "github" 20 | } 21 | }, 22 | "flake-utils": { 23 | "inputs": { 24 | "systems": "systems" 25 | }, 26 | "locked": { 27 | "lastModified": 1685518550, 28 | "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", 29 | "owner": "numtide", 30 | "repo": "flake-utils", 31 | "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", 32 | "type": "github" 33 | }, 34 | "original": { 35 | "owner": "numtide", 36 | "repo": "flake-utils", 37 | "type": "github" 38 | } 39 | }, 40 | "nixpkgs": { 41 | "locked": { 42 | "lastModified": 1685931219, 43 | "narHash": "sha256-8EWeOZ6LKQfgAjB/USffUSELPRjw88A+xTcXnOUvO5M=", 44 | "owner": "NixOS", 45 | "repo": "nixpkgs", 46 | "rev": "7409480d5c8584a1a83c422530419efe4afb0d19", 47 | "type": "github" 48 | }, 49 | "original": { 50 | "id": "nixpkgs", 51 | "ref": "nixos-unstable", 52 | "type": "indirect" 53 | } 54 | }, 55 | "root": { 56 | "inputs": { 57 | "emacs-package-flake": "emacs-package-flake" 58 | } 59 | }, 60 | "systems": { 61 | "locked": { 62 | "lastModified": 1681028828, 63 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 64 | "owner": "nix-systems", 65 | "repo": "default", 66 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "nix-systems", 71 | "repo": "default", 72 | "type": "github" 73 | } 74 | } 75 | }, 76 | "root": "root", 77 | "version": 7 78 | } 79 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | emacs-package-flake.url = "github:mrkkrp/emacs-package-flake"; 4 | }; 5 | outputs = { self, emacs-package-flake }: 6 | emacs-package-flake.lib.mkOutputs { 7 | name = "zzz-to-char"; 8 | srcDir = ./.; 9 | deps = ["avy"]; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /zzz-to-char.el: -------------------------------------------------------------------------------- 1 | ;;; zzz-to-char.el --- Fancy version of `zap-to-char' command -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Copyright © 2015–present Mark Karpov 4 | ;; 5 | ;; Author: Mark Karpov 6 | ;; URL: https://github.com/mrkkrp/zzz-to-char 7 | ;; Version: 1.0.0 8 | ;; Package-Requires: ((emacs "24.4") (avy "0.3.0")) 9 | ;; Keywords: convenience 10 | ;; 11 | ;; This file is not part of GNU Emacs. 12 | ;; 13 | ;; This program is free software: you can redistribute it and/or modify it 14 | ;; under the terms of the GNU General Public License as published by the 15 | ;; Free Software Foundation, either version 3 of the License, or (at your 16 | ;; option) any later version. 17 | ;; 18 | ;; This program is distributed in the hope that it will be useful, but 19 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 21 | ;; Public License for more details. 22 | ;; 23 | ;; You should have received a copy of the GNU General Public License along 24 | ;; with this program. If not, see . 25 | 26 | ;;; Commentary: 27 | 28 | ;; This package provides two new commands: `zzz-to-char' and 29 | ;; `zzz-up-to-char' which work like the built-ins `zap-to-char' and 30 | ;; `zap-up-to-char', but allow the user to quickly select the exact 31 | ;; character they want to zzz to. The commands work like the built-ins when 32 | ;; there is only one occurrence of the target character, excepting that they 33 | ;; automatically work in the backward direction, too. One can specify how 34 | ;; many characters to scan from each side of the point, see 35 | ;; `zzz-to-char-reach'. 36 | 37 | ;;; Code: 38 | 39 | (require 'avy) 40 | (require 'cl-lib) 41 | 42 | (defgroup zzz-to-char nil 43 | "A fancy version of `zap-to-char' command." 44 | :group 'convenience 45 | :tag "Zzz to char" 46 | :prefix "zzz-to-char-" 47 | :link '(url-link :tag "GitHub" "https://github.com/mrkkrp/zzz-to-char")) 48 | 49 | (defcustom zzz-to-char-reach 80 50 | "Number of characters to scan on each side of the point." 51 | :tag "How many characters to scan" 52 | :type 'integer) 53 | 54 | (defun zzz-to-char--base (char n-shift) 55 | "Kill text between the point and the character CHAR. 56 | 57 | Boundary of text to kill that doesn't coincide with point 58 | position can be shifted with help of the N-SHIFT argument. 59 | 60 | This is an internal function, see also `zzz-to-char' and 61 | `zzz-up-to-char'." 62 | (let ((p (point)) 63 | (avy-all-windows nil)) 64 | (avy-with zzz-to-char 65 | (avy-jump 66 | (if (= 13 char) 67 | "\n" 68 | (regexp-quote (string char))) 69 | :window-flip nil 70 | :beg (max (- p zzz-to-char-reach) 71 | (point-min)) 72 | :end (min (+ p zzz-to-char-reach) 73 | (point-max)) 74 | :pred (lambda () (> (abs (- p (point))) n-shift)))) 75 | (let ((n (point))) 76 | (when (/= n p) 77 | (cl-destructuring-bind (beg . end) 78 | (if (> n p) 79 | (cons p (- (1+ n) n-shift)) 80 | (cons (+ n n-shift) p)) 81 | (goto-char end) 82 | (kill-region beg end)))))) 83 | 84 | ;;;###autoload 85 | (defun zzz-to-char (char) 86 | "Kill text between the point and the character CHAR. 87 | 88 | This command is similar to `zap-to-char', it kills the target 89 | character too." 90 | (interactive (list (read-char "Zzz to: " t))) 91 | (zzz-to-char--base char 0)) 92 | 93 | ;;;###autoload 94 | (defun zzz-to-char-up-to-char (char) 95 | "Kill text between the point and the character CHAR. 96 | 97 | This command is similar to `zap-up-to-char', it doesn't kill the 98 | target character." 99 | (interactive (list (read-char "Zzz up to: " t))) 100 | (zzz-to-char--base char 1)) 101 | 102 | (provide 'zzz-to-char) 103 | 104 | ;;; zzz-to-char.el ends here 105 | --------------------------------------------------------------------------------