█▀▀▀█▀▀▀█▀▀▀█▀▀▀█▀▀▀▀▀▀▀█▀▀▀█▀▀▀█▀▀▀▀▀▀▀█▀▀▀▀█▀▀█ █▀▀▀▀█▀▀█▀▀▀█▀▀▀█▀▀▀▀▀█▀▀▀▀▀▀▀█ █ █ █ █ █ ▄▄ █ █ █ ▄▄▄▄█ █ █ █ █ █ █ █▄▄ ▄▄█ ▄ ▄ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ███ ███ █ █ █ █ █ █▀▀▀▀ █ █████ █ █ ▀▀▀▀█ █ █ █ █ ██▄ ▄██▀▀ ▀▀█ █ █ █ █▄▄▄█▄▄▄█▄▄▄▄▄▄▄█▄▄▄█████▄▄▄█▄▄▄█▄▄▄▄▄▄▄█▄▄█▄▄▄▄█ ██ █▄▄█▄▄▄▄████▄████▄▄▄▄▄█▄▄█▄█▄▄█
A Neovim plugin for showing TeX-style hyphenation breakpoints in text.
Table of Contents
- Shows hyphenation suggestions for the word under the cursor.
- Uses Knuth-Liang hyphenation patterns, the same family of patterns used by TeX.
- Ships with built-in
en-usanden-gbsupport. - Supports user-supplied TeX Live-style pattern files.
- Uses inline virtual text to show hints without modifying the buffer.
- Lazily loads core Lua modules and language pattern tables on first use.
- Works in any text buffer; LaTeX editing is the primary motivation.
hyphen.nvim can be used in any text buffer, but its primary motivation is LaTeX editing. When a rendered PDF contains an overfull line or an awkward line break, manual discretionary hyphenation can be useful.
For example, when the cursor is on hyphenation, the plugin can show breakpoints equivalent to:
hy-phen-ation
hyphen.nvim currently only shows breakpoints; it does not insert text automatically.
- Neovim 0.10 or newer. Required for
virt_text_pos = "inline". - No TeX Live installation is required for built-in
en-usanden-gbsupport. - TeX Live-style
.pat.txtand.hyp.txtfiles are only needed for custom languages or custom pattern sources.
Install hyphen.nvim with your preferred Neovim plugin manager.
hyphen.nvim uses plugin-manager-agnostic command-level lazy loading: startup only registers lightweight command callbacks, while the core Lua modules and language pattern tables are loaded on first use.
Show hyphenation hints for the word under the cursor:
:HyphenShowShow hints using a specific language:
:HyphenShow en-gbClear active hints:
:HyphenClearBy default, hints are cleared on CursorMoved, InsertEnter, and TextChanged. You can change this through clear_event.
Default configuration:
require("hyphen").setup({
clear_event = {"CursorMoved", "InsertEnter", "TextChanged"},
pattern_dir = {},
lang = "en-us",
leftmin = 2,
rightmin = 3,
separator = "-",
})pattern_dir accepts either a single directory:
require("hyphen").setup({
pattern_dir = "/path/to/dir",
})or a list of directories:
require("hyphen").setup({
pattern_dir = {
"/path/to/dir1",
"/path/to/dir2",
},
})Despite the singular name, pattern_dir may be a string or a list.
Built-in languages:
en-usen-gb
Custom pattern directories should contain files named like this:
hyph-<lang>.pat.txt
hyph-<lang>.hyp.txt
The .hyp.txt file is optional.
Pattern lookup order:
- Built-in Lua module:
hyphen.lang.<lang> - Directories listed in
pattern_dir
pattern_dir is only consulted when no built-in Lua module exists for the requested language.
You can convert TeX Live-style text pattern files into Lua modules with:
:HyphenConvert <lang> <dir>Example:
:HyphenConvert en-us /path/to/patternsConverted pattern files may have licenses independent of hyphen.nvim. If you redistribute generated lang/<lang>.lua files, preserve the original pattern notices.
| Command | Description |
|---|---|
:HyphenShow [lang] |
Show hyphenation hints for the word under the cursor. |
:HyphenClear |
Manually clear active hyphenation hints. |
:HyphenConvert <lang> <dir> |
Convert TeX Live-style pattern files into a Lua language module. |
local hyphen = require("hyphen")| Function | Description |
|---|---|
hyphen.setup(opts) |
Configure the plugin. |
hyphen.position(word, opts) |
Return 1-indexed hyphenation positions. |
hyphen.hyphenate(word, opts) |
Return the word with separators inserted. |
hyphen.show(opts) |
Show virtual text hints for the word under the cursor. |
hyphen.clear() |
Clear active hints in the current buffer. |
Examples:
require("hyphen").position("hyphenation")
-- returns { 2, 6 }
require("hyphen").hyphenate("hyphenation")
-- returns "hy-phen-ation"- Word detection is currently ASCII/English-centric.
- The plugin does not automatically insert text yet, including LaTeX discretionary hyphens (
\-). - The plugin does not automatically detect LaTeX language settings from
babelorpolyglossiayet. - Built-in pattern data is currently limited to
en-usanden-gb.
Distributed under the MulanPSL-2.0 license. See LICENSE for details.
Bundled hyphenation pattern data has independent copyright and license notices in lua/hyphen/lang/.
Why MulanPSL-2.0?
The Mulan Permissive Software License v2 (MulanPSL-2.0) may be less familiar than more widely used licenses. To provide clarity and context, the following table (cited from Choose a License) compares key aspects of MulanPSL v2 with popular licenses including Apache-2.0, BSD-3-Clause, and MIT.
| License | Commercial Use | Distribution | Modification | Patent Use | Private Use | Disclose Source | License and Copyright Notice | Network Use is Distribution | Same License | State Changes | Liability | Trademark Use | Warranty |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Apache-2.0 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔵 | 🔵 | 🔴 | 🔴 | 🔴 | |||
| BSD-3-Clause | 🟢 | 🟢 | 🟢 | 🟢 | 🔵 | 🔴 | 🔴 | ||||||
| MIT | 🟢 | 🟢 | 🟢 | 🟢 | 🔵 | 🔴 | 🔴 | ||||||
| MulanPSL-2.0 | 🟢 | 🟢 | 🟢 | 🟢 | 🟢 | 🔵 | 🔴 | 🔴 | 🔴 |
The drafter of the MulanPSL-2.0 license addressed similar concerns in this comment:
Thank you for raising this issue. Please allow me to explain. (I'm the one responsible for drafting MulanPSL-2.0 and getting it approved by OSI.)
Actually at the beginning we just say in the license, english and chinese version have the same legal effect (because we carefully translated the two versions word by word, sentence by sentence). However, the OSI community suggested that IN CASE, in case there is a conflict between the two languages, we should indicate which language prevails.
However, I must say, there is a tiny chance (close to zero) that this circumstance will happen. On the one hand, many people (including technical experts and lawyers) did careful proofreading between english version and chinese version; on the other hand, MulanPSL-2.0 is such a loose license that really doesn't have constrains, what conflict will you expect? We worry about conflict because we worry about legal risk that may bring, but since the legal terms are so loose we hardly see a risk.