Code Monkey home page Code Monkey logo

Comments (14)

occivink avatar occivink commented on June 18, 2024 2

Thanks for the input. I agree that placeholder support with good features is important. Conceptually I like the idea of using phantom-selection to iterate over them, but it kind of falls short in practice, since you can only iterate one-by-one and there's a good deal of context information that is lost. So I think there is some functionality that should be directly integrated into the extension.
Default text: should be easy
Placeholder order + grouping + iteration: should be ok
Mirroring: should be easy with multiple selections
Standard: unless there is a reason to deviate I guess that's a good syntax
Placeholders with variants: might be doable with menu

I didn't get some of the points (visual placeholder and zero placeholder) but it seems like there is enough to do already

from kakoune-snippets.

occivink avatar occivink commented on June 18, 2024 1

I've pushed a branch with some of these changes, it's not documented yet but some of these features should now be supported: default text, grouping, mirroring and the more standard syntax. For example the for-loop you've mentioned can be implemented as:

set window snippets 'for-loop' %{
snippets-insert %{for (int ${1:i}; $1 < $2; $1++) {
${indent}$0
}}}
set window snippets_auto_expand 'fl' 'for-loop'

There is also a placeholder highlighter that shows the next placeholders to be selected (using the face SnippetsNextPlaceholders) and all the others (using SnippetsOtherPlaceholders). It can be added like so

addhl global/ ranges snippets_placeholders

You can jump to the next placeholders using snippets-select-next-placeholders.

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

I didn't get some of the points (visual placeholder and zero placeholder) but it seems like there is enough to do already

Placeholders in stippets are count from first to last, where last. is the largest number or zero, e.g. $3 $1 $0 $9 we first jump on second placeholder, which is $1, then on $3, then on $9 and the last is $0. It is optional placeholder, but this way it makes it easy to make sure that last jump will always stay in the same place no matter how many placeholders you add while editing snippet.

For example:
Simple for loop for C/C++:

for (int ${1:i}; $1 < $2; $1++) {
    $3
}

Imagine we want to add more placeholders, since this loop doesn't really flexible:

for (${5|char,short,int,long|} ${1:i}; $1 ${2:<} $3; $1${4:++}) {
    $6
}

Notice that we didn't really want the last jump to change, but since we used $3 in the other place, we forced to increase the last placeholder number. We can fix this with:

for (${5|char,short,int,long|} ${1:i}; $1 ${2:<} $3; $1${4:++}) {
    $999
}

But this just indicates that there should be a proper way to do it. So Snippet creators thought about it and decided that $0 is always the last placeholder:

for (int ${1:i}; $1 < $2; $1++) {
    $0
}

This way we can add more placeholders and don't really care about the last one. It is less error prone, and more convenient:

for (${5|char,short,int,long|} ${1:i}; $1 ${2:<} $3; $1${4:++}) {
    $0
}

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

(visual placeholder)

This is bit tricky thing. VISUAL is a placeholder that is empty by default, but not empty when we yank something with snippet manager. Here's a gif from my Vim snippet plugin:
demo
Here's what happens here:
I have some variables int a; int b; int c;. I select those with Vim visual mode, and press Tab key. The selection is being cut to special place within my snippet manager. Next time
when I expand any snippet with ${VISUAL} placeholder in it, this placeholder will be replaced with contents that were cut previously. If we didn't cut anything, this placeholder works like regular empty placeholder $0. So ${VISUAL} is $0 if no selections were cut.

This is useful when we have bunch of defines and we want to wrap those and only those to some preprocessor if. You've shown this kind of functionality in the demo when placed include guards, so maybe this isn't necessary.

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

That's just amazing!

On other note, I'd like to discuss current snippet adding mechanism, as I find adding them via modifying option a bit wonky.

What do you think if snippets were defined in the separate files? I've used this practice, and I found it easier to maintain them this way. Emacs package named yasnippet folows same pattern here. All other snippet managers that I know use single file with lot's of snippet definitions inside.

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

It works!

set window snippets 'for-loop' %{
snippets-insert %{for (int ${1:i}; $1 < $2; $1++) {
${indent}$0
}}}
set window snippets_auto_expand 'fl' 'for-loop'

However upon jumping to i it is selected but not overwritten when I start typing.

Now we need one small thing:
map some key, Tab for example, to call snippets-select-next-placeholders while we inside snippet. This is tricky part really. I did it this way in my snippet manager, but it wasn't really reliable:

  1. On expand remember snippet starting line and amount of lines
  2. Tab key pressed. Check if we inside snippet range of lines
  • true - jump to next
  • false - act as tab key acts accordingly to user configurations
  1. Check if snippet grew since last jump, and go to 1.

Also it would be nice to have backward jumping too, since user may mess up some placeholder.

from kakoune-snippets.

occivink avatar occivink commented on June 18, 2024

However upon jumping to i it is selected but not overwritten when I start typing.

Ah I didn't realize that was expected. I suppose it's in line with how other editors work with selections, but it might be difficult to do properly here. Maybe with an InsertKey hook, but I'm not convinced we should do this.

to call snippets-select-next-placeholders while we inside snippet

What do you think of unmapping as soon as the last placeholder is reached? That would be easy to implement.

Also it would be nice to have backward jumping too, since user may mess up some placeholder.

Yeah I think I need to change that, currently I completely discard the previous placeholders but it would be easy to keep them and expose another command.

What do you think if snippets were defined in the separate files?

Do you have some documentation of how that works in other plugins? Exposing an option is more kakoune-esque so I tend to prefer it, but maybe we could expose some higher-level feature that sets hooks and options depending on the snippets directory structure.

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

Maybe with an InsertKey hook, but I'm not convinced we should do this.

Well, In my opinion this is must have, since it is expected, and all snippet managers work this way. Maybe this small plugin can give a clue how to implement this: replace.kak

What do you think of unmapping as soon as the last placeholder is reached? That would be easy to implement.

I've used this practice, but if so we need ability to jump directly to the last placeholder to prevent situations when user leaves snippet, and pressing, say, Tab, brings him back to snippet body.

Yeah I think I need to change that, currently I completely discard the previous placeholders but it would be easy to keep them and expose another command.

There's also a question related to this: what if I want to expand switch snippet for C, and expand case snippet inside - will the ability to jump back to switch snippet lost, or snippets could be nested?

Do you have some documentation of how that works in other plugins? Exposing an option is more kakoune-esque so I tend to prefer it, but maybe we could expose some higher-level feature that sets hooks and options depending on the snippets directory structure.

In terms of kakoune we could use cat command to yank snippet body to the currently edited file.

I've used this pattern, a directory named snippets with subdirectories for filetypes, named accordingly to supported filetypes: cpp, scheme, etc. In those dirs were separate files named accordingly to key sequence that triggers them, for example snippets/cpp/for will expand when I type for and it will be different snippet from snippets/java/for, depending on a filetype.

Other snippet managers do it the same way, but they define a snippets directory, and a filetype.snippets files inside:

snippets/
  c.snippets
  cpp.snippets
  java.snippets

but this way we can't jus cat separate files, and parser is needed.

You should check several popular snippet solutions, like UltiSnips, snipmate, yasnippet, and VS Code has amazing snippet support.

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

Also, when I've did my snippet manager for Vim, I've implemented a mechanism for Tab key. It checked previously entered text and if it is a trigger for snippet, it expanded it. Otherwise it worked as normal Tab key. Any plans on this one?

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

Ah I didn't realize that was expected. I suppose it's in line with how other editors work with selections, but it might be difficult to do properly here. Maybe with an InsertKey hook, but I'm not convinced we should do this.

One way to handle this is to switch to normal mode after every jump, allowing user to press c, a, or any other key. This will go along with Kakoune philosophy, but will be very, very annoying. As annoying as current way that we start in insert mode and text is inserted inside multiple character selection.

The other way is to create commands for appending inside insert mode, and clear selection if arbitrary key were pressed. For example:

Define Alt+a to snippets-append. So after jump the only thing we need to check is this:
Alt-a ? snippets-append : snippets-discard-default-text

from kakoune-snippets.

occivink avatar occivink commented on June 18, 2024

Would you mind creating separate issues for the different topics, so that they can be tracked and the discussion can be more focused?

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

from kakoune-snippets.

andreyorst avatar andreyorst commented on June 18, 2024

@occivink I think I've finished with this. Should this issue be closed?

from kakoune-snippets.

occivink avatar occivink commented on June 18, 2024

Thanks a lot. Yeah I think it's served its purpose

from kakoune-snippets.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.