From a31f78d54e45e51ed8f1c241fbcb0167a25fef03 Mon Sep 17 00:00:00 2001 From: Krunal Pamkar Date: Wed, 2 Feb 2022 11:15:41 +0530 Subject: [PATCH] Added a snippet-helper --- doc/init.txt | 85 ++++++++++++++++++++++++++++++++++++++++++++++-- fnl/init.fnl | 2 ++ fnl/snippets.fnl | 63 +++++++++++++++++++++++++++++++++++ fnl/utils.fnl | 12 +++++++ 4 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 fnl/snippets.fnl diff --git a/doc/init.txt b/doc/init.txt index 0934e37..414531a 100644 --- a/doc/init.txt +++ b/doc/init.txt @@ -8,7 +8,9 @@ CONTENTS *doom-toc* 3. Filesystem |doom-fs| 4. Modules |doom-modules| 5. Keybindings |doom-keybindings| -6. Caveats |doom-caveats| +6. Snippets |doom-snippets| +7. Treesitter |doom-treesitter| +8. Caveats |doom-caveats| ========================================================================== INTRODUCTION *doom-introduction* @@ -20,6 +22,9 @@ This distribution has been inspired by doom-nvim and doom-emacs both. You should check them out in order to get a feel of how this distro would fare for you. +Please read through the ENTIRE documentation in order to understand and use +doom efficiently. + ========================================================================== PHILOSOPHY *doom-philosophy* @@ -95,6 +100,9 @@ These are the system modules: 13. `vim-help` Some keybindings for easier editing in vim help files. Planning to add more features +14. `snippets` + Enable easy snippet creation for doom. You can think of the good ol' + YASnippet days now. *doom-user-fs* Doom encourages the usage of `fennel` and `lua` both for configuring the @@ -1433,7 +1441,80 @@ vim-vsnip: :key-attribs "expr" :noremap false :modes "i" - :help "Snippet jump to next field" + :help "Snippet jump to next field"} + + +============================================================================== +SNIPPETS *doom-snippets* +This section explains snippet creation in doom-evim. + +Doom-evim uses vim-vsnip. As it turns out, it is not easily possible to simply +copy paste into a JSON and not throw errors. Therefore, in the spirit of +YASnippet, doom provides some keybindings to make this task easy for you. + +Simply press: + `&ns` (for split window) + `&nv` (for vsplit window) + +This will [v]split your current window. Now enter your snippet in the same +manner as you would in vscode or emacs and press `gx`. + +Pressing `gx` will prompt you for the name, prefix and description of the +snippet. Once you are done entering all that, voila! Your snippet has been +registered. + +There are other convenient keybindings too: + `&es `Edit a filetype snippets list json in a split window + `&ev `Edit a filetype snippets list json in a vsplit window + +============================================================================== +TREESITTER *doom-treesitter* + +This section only covers some of the additional features that users can use +and not even be aware of it. Doom ships with +`nvim-treesitter-textobjects`which make it easy to select nodes and do other +operations. + +Doom creates some textobjects of its own. If you want to see the potential of +this, try using the textobjects with an REPL. + +Textobjects mappings: +> + {:ib "@block.inner" + :ab "@block.outer" + + :iC "@call.inner" + :aC "@call.outer" + + :ic "@class.inner" + :ac "@class.outer" + + "a;" "@comment.outer" + + :iF "@conditional.inner" + :aF "@conditional.outer" + + :if "@function.inner" + :af "@function.outer" + + :il "@loop.inner" + :al "@loop.outer" + + :ip "@parameter.inner" + :ap "@parameter.outer"} + +Other mappings: + `]m` Go to the start of next function + `]]` Go to the start of the next class + + `]M` Go to the end of next function + `][` Go to the end of next class + + `[m` Go to the start of previous function + `[[` Go to the start of previous class + + `[M` Go to the end of previous function + `[]` Go to the end of previous class ============================================================================== CAVEATS *doom-caveats* diff --git a/fnl/init.fnl b/fnl/init.fnl index df755dd..ecfd7cc 100644 --- a/fnl/init.fnl +++ b/fnl/init.fnl @@ -80,6 +80,8 @@ (when doom.default_help_keybindings (utils.try-require :vim-help :DOOM)) +(utils.try-require :snippets :DOOM) + ; Register help ; Register all help-groups in (let [wk (require :which-key)] diff --git a/fnl/snippets.fnl b/fnl/snippets.fnl new file mode 100644 index 0000000..7c4470f --- /dev/null +++ b/fnl/snippets.fnl @@ -0,0 +1,63 @@ +(module snippets + {autoload {utils utils + core aniseed.core}}) + +; All the user snippets will go in ~/.local/share/nvim/user-snippets/ +(set vim.g.vsnip_snippet_dir (utils.datap "user-snippets")) + +; Open a new split/vsplit window and set buffer props +(utils.define-key {:keys "&ns" + :exec (fn [] + (let [current-ft vim.bo.filetype] + (vim.cmd ":split _new_snippet | :wincmd k") + (set vim.bo.buftype "nofile") + (set vim.bo.buflisted false) + (set vim.bo.filetype current-ft)))}) + +(utils.define-key {:keys "&nv" + :exec (fn [] + (let [current-ft vim.bo.filetype] + (vim.cmd ":vsplit _new_snippet | :wincmd k") + (set vim.bo.buftype "nofile") + (set vim.bo.buflisted false) + (set vim.bo.filetype current-ft)))}) + +; Get the string from the buffer and save the snippet +(utils.define-key {:keys "gx" + :key-attribs "buffer" + :patterns "_new_snippet" + :events "BufEnter" + :exec (fn [] + (let [s (utils.buffer-string (vim.call :winbufnr 0) [0 -1] false)] + (if (and (= 1 (length s)) + (= (. s 1) "")) + false + (let [name (utils.get-user-input "Snippet name > " #(~= $1 "") true) + dest-dir (utils.datap "user-snippets") + fname (utils.datap "user-snippets" (.. vim.bo.filetype ".json")) + prefix (utils.get-user-input "Snippet prefix > " #(~= $1 "") true) + json {}] + + (tset json name {:prefix [prefix] :body s}) + + (when (not (utils.path-exists dest-dir)) + (utils.sh (.. "mkdir " dest-dir))) + + (if (not (utils.path-exists fname)) + (core.spit fname (vim.call :json_encode json)) + (let [_file (core.slurp fname) + file (if (not (string.match _file "[{}]")) + {} + _file) + current-json (vim.call :json_decode (core.slurp fname)) + new-json (vim.tbl_extend :force current-json json)] + (core.spit fname (vim.call :json_encode new-json))))))))}) + +; Some keybindings for vsnip +(utils.define-keys [{:keys "&ev" + :exec ":VsnipOpenVsplit" + :help "Open a snippets json in vsplit"} + + {:keys "&es" + :exec ":VsnipOpenSplit" + :help "Open a snippets json in split"}]) diff --git a/fnl/utils.fnl b/fnl/utils.fnl index 8364eaa..18cc2e3 100644 --- a/fnl/utils.fnl +++ b/fnl/utils.fnl @@ -619,3 +619,15 @@ (- size 2)) new-font (.. font ":h" new)] (set vim.go.guifont new-font))) + +; Get user input +(defn get-user-input [prompt validate loop] + (let [_first-input (vim.call :input prompt) + _first-input (str.trim _first-input)] + (if (= _first-input "") + (get-user-input prompt validate loop) + (let [is-valid (validate _first-input)] + (if is-valid + _first-input + (if loop + (get-user-input prompt validate true)))))))