From 6423936957a96bfb923eb94e8101e0abd17f7bb3 Mon Sep 17 00:00:00 2001 From: Tomas Rivera Date: Tue, 28 Apr 2026 11:52:08 +0200 Subject: [PATCH] tried to code a syllabe counter into neovim --- README.md | 12 ++- hosts/laptop/home.nix | 1 + modules/home-manager/neovim.nix | 20 ++-- modules/scripts/syllabes.nix | 174 ++++++++++++++++++++++++++++++++ 4 files changed, 196 insertions(+), 11 deletions(-) create mode 100644 modules/scripts/syllabes.nix diff --git a/README.md b/README.md index d6b0be4..e73792e 100644 --- a/README.md +++ b/README.md @@ -183,11 +183,11 @@ If you **don’t have the physical macropad**, the table below shows which keybi | `§` | Cheatsheet | | `1` | Open fold | | `2` | Close fold | -| `e1` | Previous error | -| `e2` | Next error | -| `e3` | See error message | -| `e4` | See list of errors | -| `e5` | Show correction | +| `e4` | Previous error | +| `e5` | Next error | +| `e1` | See error message | +| `e3` | See list of errors | +| `e2` | Show correction | | `e` | Stop grammar LSP | | `f1` | Telescope files | | `f2` | Telescope grep | @@ -199,6 +199,8 @@ If you **don’t have the physical macropad**, the table below shows which keybi | `g4` | Go to implementation | | `g5` | Show references | | `` | Launch runner (terminal) | +| `r1` | Run fugit | +| `t` | Count syllabes (french) | All moving macros with ``, `g`, and the recording with `q` are disabled. --- diff --git a/hosts/laptop/home.nix b/hosts/laptop/home.nix index a3a32cf..fde7526 100755 --- a/hosts/laptop/home.nix +++ b/hosts/laptop/home.nix @@ -80,6 +80,7 @@ (pkgs.callPackage ../../modules/scripts/manix.nix {}) (pkgs.callPackage ../../modules/scripts/man.nix {}) (pkgs.callPackage ../../modules/scripts/trimmer.nix {}) + (pkgs.callPackage ../../modules/scripts/syllabes.nix {}) # python script to get number of syllabes in french (pkgs.callPackage ../../hostsModules/laptop/qt/qtbatticon.nix {}) #pkgs pkgs.gruvbox-gtk-theme diff --git a/modules/home-manager/neovim.nix b/modules/home-manager/neovim.nix index 9902d11..2d0c205 100644 --- a/modules/home-manager/neovim.nix +++ b/modules/home-manager/neovim.nix @@ -249,11 +249,11 @@ local capabilities = require('cmp_nvim_lsp').default_capabilities() -- Diagnostics - vim.keymap.set("n", "e1", function() vim.diagnostic.jump({ prev=true, count = 1 }) end, { desc = "Previous diagnostic" }) - vim.keymap.set("n", "e2", function() vim.diagnostic.jump({ prev=false, count = 1 }) end, { desc = "Next diagnostic" }) - vim.keymap.set("n", "e3", vim.diagnostic.open_float, { desc = "Show diagnostic" }) - vim.keymap.set("n", "e4", vim.diagnostic.setloclist, { desc = "Diagnostic list" }) - vim.keymap.set("n", "e5", vim.lsp.buf.code_action, { desc = "Show correction" }) + vim.keymap.set("n", "e4", function() vim.diagnostic.jump({ prev=true, count = 1 }) end, { desc = "Previous diagnostic" }) + vim.keymap.set("n", "e5", function() vim.diagnostic.jump({ prev=false, count = 1 }) end, { desc = "Next diagnostic" }) + vim.keymap.set("n", "e1", vim.diagnostic.open_float, { desc = "Show diagnostic" }) + vim.keymap.set("n", "e3", vim.diagnostic.setloclist, { desc = "Diagnostic list" }) + vim.keymap.set("n", "e2", vim.lsp.buf.code_action, { desc = "Show correction" }) vim.keymap.set("n", "e", function() local clients = vim.lsp.get_clients({ name = "ltex" }) @@ -364,7 +364,8 @@ "maldoror", "evariste", "galois", - "arno" + "arno", + "dessacrer", }, }, }, @@ -480,6 +481,13 @@ --================== vim.keymap.set('n', 'r1', 'Fugit2', { desc = 'Open git helper' }) + vim.keymap.set("n", "t", function() + local line = vim.api.nvim_get_current_line() + + local result = vim.fn.system({ "custom-syllabes" }, line) + + print(vim.trim(result)) + end, { desc = "Count syllables (current line)" }) -- ========================= -- telescope -- ======================= diff --git a/modules/scripts/syllabes.nix b/modules/scripts/syllabes.nix new file mode 100644 index 0000000..bf0a76d --- /dev/null +++ b/modules/scripts/syllabes.nix @@ -0,0 +1,174 @@ +/* old version +{ pkgs, python3Packages, ... }: + +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ + python3Packages.pyphen + ]; +} '' +import sys +import pyphen + +dic = pyphen.Pyphen(lang="fr") + +text = sys.stdin.read().strip() + +chunks = [] +total = 0 + +for w in text.split(): + hyphenated = dic.inserted(w) + parts = hyphenated.split("-") + chunks.append("/".join(parts)) + total += len(parts) + +print(f"{total} ({'/'.join(chunks)})") +''*/ +/* used IPA but had a deprecated dependency +{ pkgs, python3Packages, ... }: + +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ + python3Packages.epitran + python3Packages.setuptools + ]; +} '' +import sys +import epitran +import re + +epi = epitran.Epitran("fra-Latn") + + +def count_syllables_ipa(ipa): + return len(re.findall(r"[aeiouyɑɛœɔ̃ɑ̃ɛ̃œ̃]", ipa)) + + +text = sys.stdin.read().strip() + +total = 0 +chunks = [] + +for word in text.split(): + ipa = epi.transliterate(word) + syllables = count_syllables_ipa(ipa) + + total += syllables + chunks.append(f"{word}/{ipa}") + +print(f"{total} ({' | '.join(chunks)})") +''*/ +{ pkgs, ... }: + +let + lexique = pkgs.fetchurl { + url = "http://www.lexique.org/databases/Lexique383/Lexique383.tsv"; + sha256 = "sha256-Y3ujenZ6ZmecSDcdZz7OUMv1QbSaTkDlmJY9Tz+85Ss="; + }; + +in +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ pkgs.python3Packages.pandas ]; +} '' +import os +import sys +import pandas as pd +import re + +# ---------------------------- +# Load Lexique383 +# ---------------------------- +LEX_PATH = os.environ.get( + "LEXIQUE_PATH", + "${lexique}" +) + +df = pd.read_csv(LEX_PATH, sep="\t", low_memory=False) + +lex = dict(zip(df["ortho"].str.lower(), df["phon"])) + + +# ---------------------------- +# phoneme-based syllabification +# ---------------------------- + +VOWELS = set([ + "a", "e", "ɛ", "ə", "i", "o", "ɔ", "u", "y", + "ɑ̃", "ɛ̃", "ɔ̃", "œ̃" +]) + + +def is_vowel(ph): + return any(v in ph for v in VOWELS) + + +def syllabify_phonemes(phonemes): + syllables = [] + cur = "" + + for p in phonemes: + cur += p + + if is_vowel(p): + syllables.append(cur) + cur = "" + + if cur and syllables: + syllables[-1] += cur + elif cur: + syllables.append(cur) + + return syllables + + +# ---------------------------- +# poetic adjustment (basic) +# ---------------------------- + +def apply_rules(word, phon, syllables): + # e muet at end (very rough heuristic) + if phon.endswith("ə") or phon.endswith("e"): + if len(syllables) > 1: + syllables = syllables[:-1] + return syllables + + +# ---------------------------- +# main counter +# ---------------------------- + +def count_word(word): + w = re.sub(r"[^a-zàâçéèêëîïôûùœæ']", "", word.lower()) + if not w: + return 0, [] + + phon = lex.get(w) + if not phon: + # fallback heuristic + syls = re.findall(r"[aeiouyàâéèêëîïôûùœæ]+", w) + return len(syls), syls + + phonemes = phon.split() + syls = syllabify_phonemes(phonemes) + syls = apply_rules(w, phon, syls) + + return len(syls), syls + + +def main(): + text = sys.stdin.read().strip() + total = 0 + out = [] + + for w in text.split(): + c, syls = count_word(w) + total += c + if syls: + out.append("/".join(syls)) + + print(f"{total} ({' '.join(out)})") + + +if __name__ == "__main__": + main() +''