char-menu-0.1.1/0000755000175000017500000000000013107503344013222 5ustar dogslegdogslegchar-menu-0.1.1/char-menu.el0000644000175000017500000001144513107503344015430 0ustar dogslegdogsleg;;; char-menu.el --- Create your own menu for fast insertion of arbitrary symbols -*- lexical-binding: t; -*- ;; ;; Copyright © 2016–2017 Mark Karpov ;; ;; Author: Mark Karpov ;; URL: https://github.com/mrkkrp/char-menu ;; Version: 0.1.1 ;; Package-Requires: ((emacs "24.3") (avy-menu "0.1")) ;; Keywords: convenience, editing ;; ;; This file is not part of GNU Emacs. ;; ;; This program 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. ;; ;; This program 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 this program. If not, see . ;;; Commentary: ;; This package allows to insert arbitrary symbols in Emacs in a very ;; efficient and straightforward way. Whether you ever need to insert only ;; a couple of proper punctuation symbols or you're a Unicode geek who likes ;; all sorts of arrows and fancy math symbols, this package may be of some ;; use. ;; ;; Features: ;; ;; * it allows you organize all symbols you ever need into a hierarchy you ;; define; ;; ;; * in that tree-like structure most frequently used commands will require ;; only one key-press, while others may get dedicated section (for ;; example, “arrows”) so you first select that section and then you choose ;; a symbol in it; ;; ;; * it makes sense to have paired characters in that menu, like “” (and for ;; that matter arbitrary combinations of symbols); ;; ;; * however insertion of paired characters will place the point between ;; them; ;; ;; * …and if you insert paired characters while some text is selected, they ;; will wrap it. ;;; Code: (require 'avy-menu) (require 'cl-lib) (defgroup char-menu nil "A menu for efficient insertion of arbitrary symbols." :group 'convenience :tag "Char Menu" :prefix "char-menu-" :link '(url-link :tag "GitHub" "https://github.com/mrkkrp/char-menu")) (defcustom char-menu '("—" "‘’" "“”" "…") "The char menu. This is a list containing either menu items directly as strings, or sub-menus as lists where the first element is sub-menu header and the rest is menu items. Usually every insertable menu item is one character long, but paired characters will have additional support for insertion and wrapping of selected text." :tag "The menu to show" :type '(repeat (choice (string :tag "Symbol to insert") (cons :tag "Sub-menu" (string :tag "Sub-menu header") (repeat (string :tag "Symbol to insert")))))) ;;;###autoload (defun char-menu (&optional menu header) "Display the given MENU and insert selected item, if any. See information about format of the menu in documentation of `char-menu'. If no argument is supplied, menu from that variable will be used. Note that MENU should not be empty, or error will be signalled. HEADER, if supplied, will be appended to the default menu header." (interactive) (let ((menu (or menu char-menu))) (unless menu (error "Cannot display empty menu")) (let ((selection (avy-menu "*char-menu*" (cons (concat "Character Menu" (when header (format " | %s" header))) (list (cons "Pane" (mapcar #'char-menu--make-item menu))))))) (if (consp selection) (cl-destructuring-bind (header . sub-menu) selection (char-menu sub-menu header)) (char-menu--insert selection))))) (defun char-menu--make-item (item) "Format ITEM in the way suiteable for use with `avy-menu'." (cons (if (consp item) (car item) item) item)) (defun char-menu--insert (str) "Insert STR at point handling special cases like paired characters." (let ((p (char-menu--pairp str))) (if (and p mark-active) (let ((beg (region-beginning)) (end (1+ (region-end)))) (goto-char beg) (insert (elt str 0)) (goto-char end) (insert (elt str 1))) (insert str) (when p (backward-char 1))))) (defun char-menu--pairp (str) "Select STR representing paired character sequence." (and (= (length str) 2) (cl-every (lambda (x) (memq (get-char-code-property x 'general-category) '(Pi Pf))) str))) (provide 'char-menu) ;;; char-menu.el ends here char-menu-0.1.1/README.md0000644000175000017500000001323113107503344014501 0ustar dogslegdogsleg# Char Menu [![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.txt) [![MELPA](https://melpa.org/packages/char-menu-badge.svg)](https://melpa.org/#/char-menu) [![Build Status](https://travis-ci.org/mrkkrp/char-menu.svg?branch=master)](https://travis-ci.org/mrkkrp/char-menu) * [Various methods to insert a Unicode symbol in Emacs](#various-methods-to-insert-a-unicode-symbol-in-emacs) * [Installation](#installation) * [Usage](#usage) * [Example of configuration](#example-of-configuration) * [Visual appearance of the menu](#visual-appearance-of-the-menu) * [License](#license) This package allows to insert arbitrary symbols in Emacs in a very efficient and straightforward way. Whether you ever need to insert only a couple of proper punctuation symbols or you're a Unicode geek who likes all sorts of arrows and fancy math symbols, this package may be of some use. Features: * it allows you organize all symbols you ever need into a hierarchy you define; * in that tree-like structure most frequently used commands will require only one key-press, while others may get dedicated section (for example, “arrows”) so you first select that section and then you choose a symbol in it; * it makes sense to have paired characters in that menu, like `“”` (and for that matter arbitrary combinations of symbols); * however insertion of paired characters will place the point between them; * …and if you insert paired characters while some text is selected, they will wrap it. ## Various methods to insert a Unicode symbol in Emacs Let's skip copying characters from file or web-page—it's just too inefficient. One method to insert arbitrary characters is to use `key-translation-map`, like this: ```emacs-lisp (define-key key-translation-map (kbd " p") (kbd "φ")) ``` The main problem here is that if you have many such things, they are hard to remember, and this approach is not very good at organizing symbols into categories. The same with built-in key bindings like C-x 8 …—something I always had trouble using, they are also hard to type. Another approach is to use `abbrev-mode`. I don't like that mode because you need to keep it enabled and chances are even if you normally don't need the word “alpha”, it does not mean that you want always replace it with the “α” symbol. I like to be able to explicitly control when I want “alpha” and when I want “α”. Inserting a character by its name is done with the `insert-char` command, but it cannot be used heavily because even with auto-completion it takes too long to type full name of a character. Also, we usually don't want all characters available, but a certain subset of them that is highly useful. ## Installation For manual installation simply put the package on your `load-path` and then add the following at the top of file where you would like to use the package: ```emacs-lisp (require 'char-menu) ``` However, the simplest method to install the package is with MELPA: M-x package-install char-menu RET. ## Usage Normally, there are only two things that you need to do: 1. Set the variable `char-menu`. 2. Bind the command `char-menu`. The variable `char-menu` can be customized via the “customize” interface (M-x customize-group char-menu RET) or set with `setq`. That variable should be bound to a list where every element is either a string to insert or a sub-menu, which is represented as a list where the first element is the header of the sub-menu and the rest is its items. Place most frequently needed characters at the beginning of the list. Other characters can be organized in categories: “Arrows”, “Greek letters”, “Math symbols”, whatever. It's best to keep the number of menu items less then 10, because then you will be able to choose a character using a single key press on home row. You don't need to think about key bindings—the package assigns them for you. Usually you want to insert a single character, but there is a need for paired punctuation like “this” or «this». Just put these characters together and they will be inserted with point (cursor) between them. Wrapping of selected text is also supported. As for binding of `char-menu` command, it should be as easy as: ```emacs-lisp (global-set-key (kbd " SPC") #'char-menu) ``` Of course you can choose a different key combination to assign for this. ## Example of configuration The default configuration is quite basic: ```emacs-lisp ("—" "‘’" "“”" "…") ``` As an example of something more sophisticated, try this: ```emacs-lisp ("—" "‘’" "“”" "…" "«»" "–" ("Typography" "•" "©" "†" "‡" "°" "·" "§" "№" "★") ("Math" "≈" "≡" "≠" "∞" "×" "±" "∓" "÷" "√") ("Arrows" "←" "→" "↑" "↓" "⇐" "⇒" "⇑" "⇓") ("Greek" "α" "β" "Y" "δ" "ε" "ζ" "η" "θ" "ι" "κ" "λ" "μ" "ν" "ξ" "ο" "π" "ρ" "σ" "τ" "υ" "φ" "χ" "ψ" "ω")) ``` Except for Greek letters that are a bit too numerous, all characters here can be accessed in one or two key strokes. Given that there is always a visual clue before you and all the characters you need to type are on the home row (thanks to Avy), this method of input is quite efficient. ## Visual appearance of the menu Just like [`ace-popup-menu`](https://github.com/mrkkrp/ace-popup-menu), the package is built on top of [`avy-menu`](https://github.com/mrkkrp/avy-menu), which implements this handy Avy-powered popup menu. To control appearance of the menu, invoke M-x customize-group avy-menu RET. ## License Copyright © 2016–2017 Mark Karpov Distributed under GNU GPL, version 3. char-menu-0.1.1/.travis.yml0000644000175000017500000000160613107503344015336 0ustar dogslegdogslegenv: matrix: - EMACS=emacs24 - EMACS=emacs-snapshot matrix: allow_failures: - env: EMACS=emacs-snapshot before_install: - git submodule --quiet update --init --recursive install: - if [ "$EMACS" = 'emacs24' ]; then sudo add-apt-repository -y ppa:cassou/emacs && sudo apt-get -qq update && sudo apt-get -qq -f install && sudo apt-get -qq install emacs24 emacs24-el; fi - if [ "$EMACS" = 'emacs-snapshot' ]; then sudo add-apt-repository -y ppa:ubuntu-elisp/ppa && sudo apt-get -qq update && sudo apt-get -qq -f install && sudo apt-get -qq install emacs-snapshot && sudo apt-get -qq install emacs-snapshot-el; fi - curl -fsSkL https://raw.github.com/cask/cask/master/go | python - export PATH="/home/travis/.cask/bin:$PATH" - cask install script: - cask build notifications: email: false char-menu-0.1.1/Cask0000644000175000017500000000014313107503344014024 0ustar dogslegdogsleg(source gnu) (source melpa) (package-file "char-menu.el") (development (depends-on "avy-menu"))