Simplifying snippets (if possible)?

Hey gang,

So I know kakoune-snippets has been the go-to snippet plugin for awhile, but I was wondering if there’s another way of doing snippets. Let’s me go through my thought process:

We have a folder called snippets in wherever your kakoune configuration is.

Each subfolder in the snippets folder is the name of a known filetype to kakoune (be one provided by default or one you’ve created).

Each snippet file is a simple text file, like so

# it's Lisp, sorry
(defun {1} ({2})
  ""
  {3})
  • Each {} denotes where you would like to “jump” to next, or rather how you want the position to be ordered in some register.
  • Keeping it to numbers could simplify things
  • The name of the file is the name of the snippet, the above example being like fun or something like that

When you’re typing a snippet name (fun in this case) and you press some key (say TAB like a lot of editors) after typing said snippet name or selecting it with b/B or similar, a function runs that steps through like this:

  • The current buffer filetype is X, and there’s a subfolder in snippets that corresponds to the buffer filetype
  • The current selected thing/thing behind the cursor/thing on the current line corresponds to a file in the subfolder in snippets.
  • We’ll inplace replace the current selected thing/thing behind the cursor with the contents of the file (excluding any comments, if any), using something with sed -i.
  • Each resulting position of each {} will be put into some register, hopefully can be done in order.
  • Each {} gets replaced with whitespace, again hopefully with using sed -i.
  • Cursor is moved to first registery item that corresponds to the position that {1} in the snippet was.
  • Snippet expansion is complete.

Few benefits:

  • replacing text is source to programs that are specifically built for that
    • could posibbly lead to better performance?
  • attempting to be more “barebones” from the start allows to maybe expand functionality
  • Snippet markers/positions are organizable by the user
  • Could allow for both expansion via TAB and other workflows

Few foreseeable problems:

  • sed isn’t platform agnostic, some flags/options are not the same on all OS platofrm
  • sed scripts are/can be simple and fast, but simplicity isn’t always what we need
  • awk is useful, but scripts can be overly complex and there’s not definitive or best performance way to solve the problem “replace text in file at line number with text from other file”
  • I have no idea how one would order snippet marker/positions into a register.

Thoughts?

1 Like

Alright just as some notes for anyone reading this, I’m beginning to slowly drive myself mad with sed.

So I’ve setup the the following files to do a test:

snippet-test.txt:

(defvar some-var "some text")

(defparameter *some-param* 12)

fun

(defun test-fn ()
  (princ "Some text"))

fun is the text we will replace with the contents of the following file snippet-test-snip.txt:

(defun {} ()
  ""
  {})

Now the absolutely insane part. The following kind of works:

sed -e '/^fun/r snippet-test-snip.txt' -e '/^fun/d'  snippet-test.txt

However, this isn’t inplace. I’m on MacOS, so with adding -i:

sed: -e: No such file or directory

Peachy. Can we do '/^fun/r snippet-test-snip.txt; /^fun/d'?

$ sed -i -e '/^fun/r snippet-test-snip.txt; /^fun/d'  snippet-test.txt
$ cat snippet-test.txt
(defvar some-var "some text")

(defparameter *some-param* 12)

fun

(defun test-fn ()
  (princ "Some text"))

Wonderful. Okay, let’s try a solution with awk:

$ awk 'NR==FNR{rep=(NR>1?rep RS:"") $0; next} {gsub(/^fun/,rep)}1' snippet-test-snip.txt snippet-test.txt
$ cat snippet-test.txt
(defvar some-var "some text")

(defparameter *some-param* 12)

(defun {} ()
  ""
  {})

(defun test-fn ()
  (princ "Some text"))

Hurray! Pity that I have no real clue how that awk command works, and even if I did it’s ugly. I hope it’s also portable. Now is the other step if replacing the {} with empty text, but that’s problem for another day.

1 Like