Start working on a more modern latex snippet system
This commit is contained in:
		
					parent
					
						
							
								b0ff2979ed
							
						
					
				
			
			
				commit
				
					
						a47be3adf9
					
				
			
		
					 5 changed files with 283 additions and 190 deletions
				
			
		home/features/neovim
|  | @ -7,7 +7,7 @@ vim.opt.conceallevel = 0 | |||
| 
 | ||||
| local abbreviations = { | ||||
|   -- Other fancy symvols | ||||
|   { "tmat", "^T" }, -- Tranpose of a matrix | ||||
|   { "tmat", "^T" }, -- Transpose of a matrix | ||||
|   { "cmat", "^*" }, -- Conjugate of a matrix | ||||
|   { "sneg", "^C" }, -- Set complement | ||||
|   { "ortco", "^\\bot" }, -- Orthogonal complement | ||||
|  | @ -79,7 +79,7 @@ local abbreviations = { | |||
| 
 | ||||
| local abolishAbbreviations = { | ||||
|   -- {{{ Special chars | ||||
|   -- System for writing special characters which need to also be easly | ||||
|   -- System for writing special characters which need to also be easily | ||||
|   -- accessible as {sub/super}scripts. | ||||
|   -- | ||||
|   -- The reason epsilon and lambda are separated out from everything else in | ||||
|  |  | |||
|  | @ -9,6 +9,15 @@ function M.setup() | |||
|   require("my.keymaps").setup() | ||||
|   require("my.lazy").setup() | ||||
|   tempest.configureMany(nix.post) | ||||
| 
 | ||||
|   vim.api.nvim_create_autocmd("FileType", { | ||||
|     pattern = "tex", | ||||
|     group = vim.api.nvim_create_augroup("luasnip-latex-snippets", {}), | ||||
|     once = true, | ||||
|     callback = function() | ||||
|       require("my.snippets.tex").setup() | ||||
|     end, | ||||
|   }) | ||||
| end | ||||
| 
 | ||||
| return M | ||||
|  |  | |||
							
								
								
									
										263
									
								
								home/features/neovim/config/lua/my/snippets/tex.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								home/features/neovim/config/lua/my/snippets/tex.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,263 @@ | |||
| local M = {} | ||||
| 
 | ||||
| local ls = require("luasnip") | ||||
| local extras = require("luasnip.extras") | ||||
| local conds = require("luasnip.extras.expand_conditions") | ||||
| local t = ls.text_node | ||||
| local i = ls.insert_node | ||||
| local d = ls.dynamic_node | ||||
| local f = ls.function_node | ||||
| local sn = ls.snippet_node | ||||
| local fmt = require("luasnip.extras.fmt").fmt | ||||
| local n = extras.nonempty | ||||
| 
 | ||||
| local autosnippets = {} | ||||
| 
 | ||||
| -- {{{ Helpers | ||||
| local function unlines(...) | ||||
|   return table.concat({ ... }, "\n") | ||||
| end | ||||
| 
 | ||||
| local function flatten(arr) | ||||
|   local result = {} | ||||
|   for _, subarray in ipairs(arr) do | ||||
|     if type(subarray) == "table" then | ||||
|       for _, value in ipairs(subarray) do | ||||
|         table.insert(result, value) | ||||
|       end | ||||
|     else | ||||
|       table.insert(result, subarray) | ||||
|     end | ||||
|   end | ||||
|   return result | ||||
| end | ||||
| 
 | ||||
| local function trig(name) | ||||
|   return { name = name, trig = name } | ||||
| end | ||||
| -- }}} | ||||
| -- {{{ Math mode detection | ||||
| -- Taken from: https://github.com/iurimateus/luasnip-latex-snippets.nvim/blob/main/lua/luasnip-latex-snippets/util/ts_utils.lua | ||||
| local MATH_NODES = { | ||||
|   displayed_equation = true, | ||||
|   inline_formula = true, | ||||
|   math_environment = true, | ||||
| } | ||||
| 
 | ||||
| local TEXT_NODES = { | ||||
|   text_mode = true, | ||||
|   label_definition = true, | ||||
|   label_reference = true, | ||||
| } | ||||
| 
 | ||||
| local function get_node_at_cursor() | ||||
|   local pos = vim.api.nvim_win_get_cursor(0) | ||||
|   -- Subtract one to account for 1-based row indexing in nvim_win_get_cursor | ||||
|   local row, col = pos[1] - 1, pos[2] | ||||
| 
 | ||||
|   local parser = vim.treesitter.get_parser(0, "latex") | ||||
|   if not parser then | ||||
|     return | ||||
|   end | ||||
| 
 | ||||
|   local root_tree = parser:parse({ row, col, row, col })[1] | ||||
|   local root = root_tree and root_tree:root() | ||||
|   if not root then | ||||
|     return | ||||
|   end | ||||
| 
 | ||||
|   return root:named_descendant_for_range(row, col, row, col) | ||||
| end | ||||
| 
 | ||||
| local function in_text(check_parent) | ||||
|   local node = get_node_at_cursor() | ||||
|   while node do | ||||
|     if node:type() == "text_mode" then | ||||
|       if check_parent then | ||||
|         -- For \text{} | ||||
|         local parent = node:parent() | ||||
|         if parent and MATH_NODES[parent:type()] then | ||||
|           return false | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       return true | ||||
|     elseif MATH_NODES[node:type()] then | ||||
|       return false | ||||
|     end | ||||
|     node = node:parent() | ||||
|   end | ||||
|   return true | ||||
| end | ||||
| 
 | ||||
| local function in_mathzone() | ||||
|   local node = get_node_at_cursor() | ||||
|   while node do | ||||
|     if TEXT_NODES[node:type()] then | ||||
|       return false | ||||
|     elseif MATH_NODES[node:type()] then | ||||
|       return true | ||||
|     end | ||||
|     node = node:parent() | ||||
|   end | ||||
|   return false | ||||
| end | ||||
| 
 | ||||
| local function not_math() | ||||
|   return in_text(true) | ||||
| end | ||||
| -- }}} | ||||
| -- {{{ Start of line & non-math | ||||
| local beginTextCondition = function(...) | ||||
|   return conds.line_begin(...) and not_math() | ||||
| end | ||||
| 
 | ||||
| local parseBeginText = ls.extend_decorator.apply(ls.parser.parse_snippet, { | ||||
|   condition = beginTextCondition, | ||||
| }) --[[@as function]] | ||||
| 
 | ||||
| local snipBeginText = ls.extend_decorator.apply(ls.snippet, { | ||||
|   condition = beginTextCondition, | ||||
| }) --[[@as function]] | ||||
| 
 | ||||
| local function env(name) | ||||
|   return "\\begin{" .. name .. "}\n\t$0\n\\end{" .. name .. "}" | ||||
| end | ||||
| 
 | ||||
| local function optional_square_bracket_arg(index, default) | ||||
|   return sn(index, { | ||||
|     n(1, "[", ""), | ||||
|     i(1, default), | ||||
|     n(1, "]", ""), | ||||
|   }) | ||||
| end | ||||
| 
 | ||||
| local function theorem_env(name, prefix) | ||||
|   return snipBeginText(trig(name), { | ||||
|     t("\\begin{" .. name .. "}"), | ||||
|     optional_square_bracket_arg(1), | ||||
|     n(2, "\\label{" .. prefix .. ":", ""), | ||||
|     i(2), | ||||
|     n(2, "}", ""), | ||||
|     t({ "", "\t" }), | ||||
|     i(0), | ||||
|     t({ "", "\\end{" .. name .. "}" }), | ||||
|   }) | ||||
| end | ||||
| 
 | ||||
| vim.list_extend(autosnippets, { | ||||
|   parseBeginText( | ||||
|     { trig = "begin", name = "Begin / end environment" }, | ||||
|     env("$1") | ||||
|   ), | ||||
|   -- {{{ Chapters / sections | ||||
|   parseBeginText(trig("chapter"), "\\chapter{$1}\n$0"), | ||||
|   parseBeginText(trig("section"), "\\section{$1}\n$0"), | ||||
|   parseBeginText(trig("subsection"), "\\subsection{$1}\n$0"), | ||||
|   parseBeginText(trig("subsubsection"), "\\subsubsection{$1}\n$0"), | ||||
|   -- }}} | ||||
|   -- {{{ Lists | ||||
|   parseBeginText({ trig = "item", name = "List item" }, "\\item"), | ||||
|   parseBeginText({ trig = "olist", name = "Ordered list" }, env("enumerate")), | ||||
|   parseBeginText({ trig = "ulist", name = "Unordered list" }, env("itemize")), | ||||
|   -- }}} | ||||
|   -- {{{ Theorem envs | ||||
|   theorem_env("theorem", "thm"), | ||||
|   theorem_env("lemma", "lem"), | ||||
|   theorem_env("exercise", "exe"), | ||||
|   theorem_env("definition", "def"), | ||||
|   theorem_env("corollary", "cor"), | ||||
|   theorem_env("example", "exa"), | ||||
|   snipBeginText(trig("proof"), { | ||||
|     t("\\begin{proof}"), | ||||
|     optional_square_bracket_arg(1), | ||||
|     t({ "", "\t" }), | ||||
|     i(0), | ||||
|     t({ "", "\\end{proof}" }), | ||||
|   }), | ||||
|   -- }}} | ||||
|   -- {{{ Special structures | ||||
|   parseBeginText( | ||||
|     { trig = "ciff", name = "If and only if cases" }, | ||||
|     unlines( | ||||
|       "\\begin{enumerate}", | ||||
|       "\t\\item[$\\implies$]$1", | ||||
|       "\t\\item[$\\impliedby$]$2", | ||||
|       "\\end{enumerate}", | ||||
|       "$0" | ||||
|     ) | ||||
|   ), | ||||
|   -- }}} | ||||
| }) | ||||
| -- }}} | ||||
| -- {{{ Non-math | ||||
| local parseText = ls.extend_decorator.apply(ls.parser.parse_snippet, { | ||||
|   condition = not_math, | ||||
| }) --[[@as function]] | ||||
| 
 | ||||
| local snipText = ls.extend_decorator.apply(ls.snippet, { | ||||
|   condition = not_math, | ||||
| }) --[[@as function]] | ||||
| 
 | ||||
| local function ref(name, prefix) | ||||
|   return { | ||||
|     parseText( | ||||
|       { trig = "r" .. name, name = name .. " reference" }, | ||||
|       "\\ref{" .. prefix .. ":$1}$0" | ||||
|     ), | ||||
|     parseText( | ||||
|       { trig = "pr" .. name, name = name .. " reference" }, | ||||
|       "(\\ref{" .. prefix .. ":$1})$0" | ||||
|     ), | ||||
|   } | ||||
| end | ||||
| 
 | ||||
| vim.list_extend( | ||||
|   autosnippets, | ||||
|   flatten({ | ||||
|     -- {{{ References | ||||
|     ref("theorem", "thm"), | ||||
|     ref("lemma", "lem"), | ||||
|     ref("exercise", "exe"), | ||||
|     ref("definition", "def"), | ||||
|     ref("corollary", "cor"), | ||||
|     ref("example", "exa"), | ||||
|     { | ||||
|       parseText({ trig = "ref", name = "reference" }, "\\ref{$1}$0"), | ||||
|       parseText({ trig = "pref", name = "reference" }, "(\\ref{$1})$0"), | ||||
|     }, | ||||
|     -- }}} | ||||
|     { | ||||
|       -- {{{ Misc | ||||
|       parseText(trig("quote"), "``$1''$0"), | ||||
|       parseText(trig("forcecr"), "{\\ \\\\\\\\}"), | ||||
|       -- }}} | ||||
|       -- {{{ Let ... | ||||
|       snipText( | ||||
|         { trig = "([Ll]et)", trigEngine = "pattern", name = "definition" }, | ||||
|         { | ||||
|           f(function(_, snip) | ||||
|             return snip.captures[1] | ||||
|           end), | ||||
|           t(" "), | ||||
|           sn(1, fmt("${} ≔ {}$", { i(1), i(2) })), | ||||
|         } | ||||
|       ), | ||||
|       -- }}} | ||||
|       -- {{{ Display / inline math | ||||
|       parseText({ trig = "dm", name = "display math" }, env("align*")), | ||||
|       parseText({ trig = "im", name = "inline math" }, "\\$$1\\$$0"), | ||||
|       -- }}} | ||||
|     }, | ||||
|   }) | ||||
| ) | ||||
| -- }}} | ||||
| 
 | ||||
| function M.setup() | ||||
|   ls.add_snippets("tex", autosnippets, { | ||||
|     type = "autosnippets", | ||||
|     default_priority = 0, | ||||
|   }) | ||||
| end | ||||
| 
 | ||||
| return M | ||||
|  | @ -846,20 +846,26 @@ let | |||
|         # {{{ luasnip | ||||
|         # snippeting engine | ||||
|         luasnip = | ||||
|           let reload = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()''; | ||||
|           let reloadVscode = /* lua */ ''require("luasnip.loaders.from_vscode").lazy_load()''; | ||||
|           in | ||||
|           { | ||||
|             package = "L3MON4D3/LuaSnip"; | ||||
|             version = "v2"; | ||||
| 
 | ||||
|             cond = blacklist "vscode"; | ||||
|             config = thunk reload; | ||||
|             config = thunk '' | ||||
|               require("luasnip").config.setup(${encode { | ||||
|                 enable_autosnippets = true; | ||||
|                 update_events = ["TextChanged" "TextChangedI"]; | ||||
|               }}) | ||||
|               ${reloadVscode} | ||||
|             ''; | ||||
| 
 | ||||
|             # {{{ Keybinds | ||||
|             keys = [ | ||||
|               { | ||||
|                 mapping = "<leader>rs"; | ||||
|                 action = thunk reload; | ||||
|                 action = thunk reloadVscode; | ||||
|                 desc = "[R]eload [s]nippets"; | ||||
|               } | ||||
|               { | ||||
|  |  | |||
|  | @ -1,13 +1,4 @@ | |||
| { | ||||
|   "Begin": { | ||||
|     "prefix": "begin", | ||||
|     "description": "Begin anything", | ||||
|     "body": [ | ||||
|       "\\begin{$1}", | ||||
|       "\t$0", | ||||
|       "\\end{$1}" | ||||
|     ] | ||||
|   }, | ||||
|   "Set": { | ||||
|     "prefix": "set", | ||||
|     "description": "Set I guess", | ||||
|  | @ -38,69 +29,6 @@ | |||
|     "description": "Inner product of a vector with itself", | ||||
|     "body": "\\dprod{$1}$0" | ||||
|   }, | ||||
|   "Lemma": { | ||||
|     "prefix": "lemma", | ||||
|     "description": "Create a lemma", | ||||
|     "body": [ | ||||
|       "\\begin{lemma}[$1]\\label{lem:$1}", | ||||
|       "\t$0", | ||||
|       "\\end{lemma}" | ||||
|     ] | ||||
|   }, | ||||
|   "Example*": { | ||||
|     "prefix": "example*", | ||||
|     "description": "Create an example*", | ||||
|     "body": [ | ||||
|       "\\begin{example*}", | ||||
|       "\t$0", | ||||
|       "\\end{example*}" | ||||
|     ] | ||||
|   }, | ||||
|   "Example": { | ||||
|     "prefix": "example", | ||||
|     "description": "Create an example", | ||||
|     "body": [ | ||||
|       "\\begin{example}[$1]\\label{exp:$1}", | ||||
|       "\t$0", | ||||
|       "\\end{example}" | ||||
|     ] | ||||
|   }, | ||||
|   "Theorem": { | ||||
|     "prefix": "theorem", | ||||
|     "description": "Create a theorem", | ||||
|     "body": [ | ||||
|       "\\begin{theorem}[$1]\\label{thm:$1}", | ||||
|       "\t$0", | ||||
|       "\\end{theorem}" | ||||
|     ] | ||||
|   }, | ||||
|   "Exercise": { | ||||
|     "prefix": "exercise", | ||||
|     "description": "Create a exercise", | ||||
|     "body": [ | ||||
|       "\\begin{exercise}[$1]\\label{exe:$1}", | ||||
|       "\t$0", | ||||
|       "\\end{exercise}" | ||||
|     ] | ||||
|   }, | ||||
|   "Definition": { | ||||
|     "prefix": "definition", | ||||
|     "description": "Create a definition", | ||||
|     "body": [ | ||||
|       "\\begin{definition}[$1]\\label{def:$1}", | ||||
|       "\t$0", | ||||
|       "\\end{definition}" | ||||
|     ] | ||||
|   }, | ||||
|   "Display math": { | ||||
|     "prefix": "dm", | ||||
|     "description": "Display math section", | ||||
|     "body": [ | ||||
|       "\\[", | ||||
|       "$0", | ||||
|       "\\]" | ||||
|     ] | ||||
|   }, | ||||
|   "Subscript": { | ||||
|     "prefix": "ss", | ||||
|     "description": "Subscript", | ||||
|  | @ -126,80 +54,6 @@ | |||
|     "description": "The set of Z/nZ", | ||||
|     "body": "\\mathbb{Z}/$1\\mathbb{Z}$0" | ||||
|   }, | ||||
|   "Section": { | ||||
|     "prefix": "section", | ||||
|     "description": "Add section", | ||||
|     "body": [ | ||||
|       "\\section{$1}", | ||||
|       "$0" | ||||
|     ] | ||||
|   }, | ||||
|   "Subsection": { | ||||
|     "prefix": "subsection", | ||||
|     "description": "Add subsection", | ||||
|     "body": [ | ||||
|       "\\subsection{$1}", | ||||
|       "$0" | ||||
|     ] | ||||
|   }, | ||||
|   "Subsubsection": { | ||||
|     "prefix": "subsubsection", | ||||
|     "description": "Add subsubsection", | ||||
|     "body": [ | ||||
|       "\\subsubsection{$1}", | ||||
|       "$0" | ||||
|     ] | ||||
|   }, | ||||
|   "Chapter": { | ||||
|     "prefix": "chapter", | ||||
|     "description": "Add chapter", | ||||
|     "body": [ | ||||
|       "\\chapter{$1}", | ||||
|       "$0" | ||||
|     ] | ||||
|   }, | ||||
|   "Proof": { | ||||
|     "prefix": "proof", | ||||
|     "description": "Create proof", | ||||
|     "body": [ | ||||
|       "\\begin{proof}", | ||||
|       "\t$0", | ||||
|       "\\end{proof}" | ||||
|     ] | ||||
|   }, | ||||
|   "Itemize": { | ||||
|     "prefix": "item", | ||||
|     "body": [ | ||||
|       "\\\\begin{itemize}", | ||||
|       "\t\\item $0", | ||||
|       "\\\\end{itemize}" | ||||
|     ], | ||||
|     "description": "Itemize env" | ||||
|   }, | ||||
|   "Enumerate": { | ||||
|     "prefix": "enum", | ||||
|     "body": [ | ||||
|       "\\\\begin{enumerate}", | ||||
|       "\t\\item $0", | ||||
|       "\\\\end{enumerate}" | ||||
|     ], | ||||
|     "description": "Enumerate env" | ||||
|   }, | ||||
|   "Reference definition": { | ||||
|     "prefix": "rdef", | ||||
|     "description": "Reference a definition", | ||||
|     "body": "\\ref{def:$1}$0" | ||||
|   }, | ||||
|   "Reference lemma": { | ||||
|     "prefix": "rlemma", | ||||
|     "description": "Reference a lemma", | ||||
|     "body": "\\ref{lem:$1}$0" | ||||
|   }, | ||||
|   "Reference theorem": { | ||||
|     "prefix": "rtheorem", | ||||
|     "description": "Reference a theorem", | ||||
|     "body": "\\ref{thm:$1}$0" | ||||
|   }, | ||||
|   "Sigma sum": { | ||||
|     "prefix": "bsum", | ||||
|     "description": "Create a sum using sigma notation", | ||||
|  | @ -260,34 +114,11 @@ | |||
|     "description": "Create a ln call", | ||||
|     "body": "\\ln($1)$0" | ||||
|   }, | ||||
|   "Aligned": { | ||||
|     "prefix": "aligned", | ||||
|     "description": "Create an aligned environment", | ||||
|     "body": [ | ||||
|       "\\begin{aligned}", | ||||
|       "\t$0", | ||||
|       "\\end{aligned}" | ||||
|     ] | ||||
|   }, | ||||
|   "Let": { | ||||
|     "prefix": "let", | ||||
|     "description": "Let something equal something else", | ||||
|     "body": "Let $$1 = $2$. $0" | ||||
|   }, | ||||
|   "Force newline": { | ||||
|     "prefix": "cr", | ||||
|     "description": "Force newline in math mode", | ||||
|     "body": "{\\ \\\\\\\\}" | ||||
|   }, | ||||
|   "Aligned display math": { | ||||
|     "prefix": "maligned", | ||||
|     "description": "Create an aligned display math environment", | ||||
|     "body": [ | ||||
|       "\\begin{align*}", | ||||
|       "\t$0", | ||||
|       "\\end{align*}" | ||||
|     ] | ||||
|   }, | ||||
|   "System of equations": { | ||||
|     "prefix": "eqsystem", | ||||
|     "description": "Create a system of equations", | ||||
|  | @ -358,21 +189,5 @@ | |||
|     "prefix": "integral", | ||||
|     "description": "Integral", | ||||
|     "body": "\\int $1 d${2:x}$0" | ||||
|   }, | ||||
|   "Iff cases": { | ||||
|     "prefix": "ciff", | ||||
|     "description": "Prove an equivalence in both directions", | ||||
|     "body": [ | ||||
|       "\\begin{enumerate}", | ||||
|       "\t\\item[$\\implies$]$1", | ||||
|       "\t\\item[$\\impliedby$]$2", | ||||
|       "\\end{enumerate}", | ||||
|       "$0" | ||||
|     ] | ||||
|   }, | ||||
|   "quote": { | ||||
|     "prefix": "quote", | ||||
|     "description": "Quote a bunch of text", | ||||
|     "body": "``$1''$0" | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue