lifepillar / vim-devel

The workbench for modern Vim development
7 stars 0 forks source link

Feedback on this proposal for packaging modern resources for plugin developers #1

Open lifepillar opened 1 year ago

lifepillar commented 1 year ago

Vim 9 script is becoming mature enough for production-level quality code. Many people are going to ditch legacy Vim script in favor of the new scripting language. Why not take this opportunity for a “reset” in development practices? Why not imagining, for instance, that Vim might eventually have a “standard library” built on top of Vim 9 script, which anyone can leverage to write plugins?

This repo is a proposal to build a centralized location where resources that help people develop Vim plugins are gathered. This includes both plugins that target plugin developers rather than end users, and libraries that can be imported by other plugins. An example of a library that might benefit many plugins is a collection of functions for manipulating paths that works transparently across different systems. But the possibilities are endless, of course.

I would like this to be a community effort, so my idea would be to open this repository to collaborators, and possibly move it outside my own GitHub account (I am not an expert on how do to anything like that, so suggestions are welcome).

If you have comments or questions, please provide your feedback below!

lifepillar commented 1 year ago

@habamax @lacygoill @neutaaaaan @romainl (rigorously in lexicographical ordering) Off the top of my head, you are some people I'd like to get some initial feedback from. Feel free to ping anyone else who might be interested. And feel free to criticize the project harshly 🙂

romainl commented 1 year ago

I have written a grand total of 0 (zero) lines of vim9script so, while I certainly appreciate being in that list, I don't feel that my opinion should count.

But I like to give my opinion so here it is: that's a damn good initiative.

habamax commented 1 year ago

Sounds like a good idea to me

lacygoill commented 1 year ago

FWIW, I don't think I will be able to contribute much (too many personal issues), but we'll see. That said, it sounds like a good initiative. I would be interested in:

Regarding the tooling:

Also, some people might be interested in a location where to discuss Vim9 script. CC @monkoose via https://github.com/lacygoill/vim9asm/issues/6#issuecomment-1241696959, as well as @errael and @bfrg. BTW, GitHub supports discussions.

lacygoill commented 1 year ago

Also, I wrote 2 Vim9 plugins which have not been merged but might help some devs. This one tries to be an interactive editor for highlight groups (I thought it could be useful to an author of a color scheme): gif

Press g? to get some help.

And this one tries to make it easier to find a help tag via an interactive popup menu (which can be searched with :help matchfuzzy()). Also works in markdown, man, and terminal buffers.

errael commented 1 year ago

I endorse enabling discussion. And including some comments about "well known" primary topics and subtopics; but not limited to those.

About libraries, testing them, deploying them. For the project (porting splice vimscript/python plugin to pure vim9script) I've been working on and off over the last year, I've got some things that could be in a library. I've got some testing built in to the files (after a conditional "finish" and with some kludges that adjust imports depending...); it's messy, would like to have separate area that imports and tests, with maybe some options (a global) that enables some hooks in the library under test.

I never did vimscript, only vim9script, and don't use plugins (started using two last year); my perspective is limited about the existing vim ecosystem. Some issues that come to mind.

errael commented 1 year ago

Here are two of the better documented library things I've got.

the most important function in log.vim

#
# Conditionally log to a file based on logging enabled and optional category.
# The message is split by "\n" and passed to writefile()
# Output example: "The log msg"
# Output example: "CATEGORY: The log msg"
# NOTE: category is checked with ignore case, output as upper case
#
#   - Log(msg: string [, category = ''[, stack = true[, command = '']]])
#   - Log(func(): string [, category = ''[, stack = true[, command = '']]])
#
# If optional stack is true, the stacktrace from where Log is called
# is output to the log.
#
# If optional command, the command is run using execute() and the command
# output is output to the log.
#

This

Log('Init() after buffers.InitHudBuffer()', '', true, ':ls')

produces

Init() after buffers.InitHudBuffer()
  stack:
    #splicelib/init.vim::Init[7]
    splice9Dev/splice.vim::SpliceInit9[10]
    function splice9Dev/splice.vim::Trampoline[6]
  command ':ls' output:
      1      "/tmp/hgmerge-zbfxaz7i/f00~base.txt" line 1
      2      "/tmp/hgmerge-zbfxaz7i/f00~local.txt" line 0
      3      "/tmp/hgmerge-zbfxaz7i/f00~other.txt" line 0
      4 #a + "f00.txt"                      line 1
      5 %a   "__Splice_HUD__"               line 1

the introductory comment in MapModesFilters.vim

#
# MapModeFilter(modes, pattern, exact = true, field = lhs)
# MapModeFilterFunc(modes, filter_func)
# MapModeFilterExpr(modes, filter_expr)
#
# Return mappings used in "modes" that match a pattern.
# Used with maplist()->filter() to return mappings involving argument "modes".
#       - "modes" one or more modes of interest.
#       - "pattern" matched against a field in the mapping-dict
#       - "exact" true means use '==', otherwise '=~',
#         for checking if mapping's "field" matches. Default is 'true'
#       - "field" from mapping-dict to match against defaults to 'lhs'.
#       - "filter_func" takes a mapping-dict as an arugment, returns
#         true if that mapping should be checked for matching modes.
#       - "filter_expr" like filter_func except the string is evaluated.
#         The string has "m" available as the mapping-dict.
#         true if that mapping should be checked for matching modes.
# An exception is thrown if modes contains an unkown/illegal mode.
#
# examples: 
#   Any mapping of 'K' used in '!' or ' ' modes
#   (this is all modes except 'l' and 't')
#       saved_maps = maplist()->filter(MapModeFilter('! ', 'K'))
#   Any mapping of 'K' used in 's' or 'c' modes
#       saved_maps = maplist()->filter(MapModeFilter('sc', 'K'))
#   Mappings that have "MultiMatch" in rhs (command), in "n" mode.
#       saved_maps = maplist()->filter(MapModeFilter(
#                                     'n', 'MultiMatch', false, 'rhs'))
#   Mappings of 'K' and rhs has "MultiMatch", in "n" modes.
#       saved_maps = maplist()->filter(MapModeFilterFunc(
#                       'n', (m) => m.lhs == 'K' && m.rhs =~ 'MultiMatch'))
#
# A MapModeFilter can also be used with a for loop
#       var filt = MapModeFilter('sc', 'K')
#       for m in maplist()
#           if filt(0, m)
#               # do stuff
#           endif
#       endfor
#
lifepillar commented 1 year ago

Thanks for your feedback! There are some very good points to address in your replies and very good suggestions. I have not much time right now for an extensive reply, but I have taken note!

My vision for this repo is a collection of Vim 9 script resources (in the form of plugins and libraries of Vim 9 classes and functions) to help people develop other plugins and libraries. As such, I don't see end-user plugins such as netrw as a good fit, but a library of network or file system classes/functions that could be used by a plugin such as netrw (and reused by others) would certainly be.

When I have time, I will write some contributor guidelines to have something more concrete to discuss. Style, conventions and best practices are something that will evolve as the repo grows, because packages are not widespread yet and Vim 9 script is pretty new, too.