Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Optional) support for nested selectors #61

Open
maxnordlund opened this issue Jul 21, 2018 · 4 comments
Open

(Optional) support for nested selectors #61

maxnordlund opened this issue Jul 21, 2018 · 4 comments
Labels

Comments

@maxnordlund
Copy link

maxnordlund commented Jul 21, 2018

First off, thanks for writing this plugin, it's amazing. It supports pretty much everything I throw at it save nesting.

I know you have removed support for SCSS in #53, but I was wondering you would consider adding support for nested selctors? This may be behind some sort of flag/option, let g:css3_nesting = 1, but would be very useful none then less.

The nesting I'm referring to is not the full-blown one from SASS/SCSS/LESS but rather the proposal linked above. So something like:

article section {
    & h1, & h2, & h3
    & h4, & h5 & h6 {
        &:target {
            font-weight: bolder;
        }
    }
}

But note that & has to prefix every selector, so no .disabled & or .&-disabled. That's about it. I tried to do it myself, but Vim's syntax files are might confusing, and I was hoping you might be able to help.

For reference I'm using https://preset-env.cssdb.org/ with https://github.com/jonathantneal/postcss-nesting enabled.

What do you think?

@hail2u
Copy link
Owner

hail2u commented Jul 21, 2018

Honestly, I’m very interested in css-nesting spec. However, I do not have a plan to support specs not listed in CSS WG. Because this list is CSS (or CSS3). A CSS-ish file that depends on PostCSS plugin is not CSS.

If you create a standalone plugin that supports css-nesting spec for filetype postcss, you can use with :set filetype css.postcss. This is a suggested way to support such syntax in Vim, I think.

@maxnordlund
Copy link
Author

Sorry for the late reply, but here it goes: That makes sense, but I'm not familiar with Vim syntax files. I tried to read through NeoVim's builtin one for CSS, SCSS and SASS but didn't get how they make it work.

Could you give some pointers on how to do this?

@hail2u hail2u added the feature label Aug 7, 2018
@hail2u
Copy link
Owner

hail2u commented Aug 7, 2018

The mustache Vim syntax uses html.mustache or html.handlebars for extending HTML syntax. This is a good example, I think.

@maxnordlund
Copy link
Author

So I finally got around to do this, and after some tinkering (and much confusion) I got this:

" Copied from cssDefinition contains in css.vim syntax file
syntax cluster postcssSelector contains=cssTagName,cssAttributeSelector,cssClassName,cssIdentifier,cssAtRule,cssAttrRegion,css.*Prop
syntax cluster postcssProperties contains=cssValue.*,cssColor,cssURL,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor,cssHacks,cssNoise

" Add the nesting operator, and the compund selectors (which for some reason
" didn't work without this)
syntax match postcssNestedSelector "&"
syntax cluster postcssSelector add=postcssNestedSelector,cssSelectorOp

" This is based on @media rule, which also has nested CSS declerations
syntax region postcssNesting matchgroup=cssSelectorOp start="&" matchgroup=cssBraces end=/\ze{/ skipwhite skipnl contains=@postcssSelector nextgroup=cssDefinition

" Overriding the bultin in definition means all references are kept. For
" example, all @-rules that have nested stuff does this.
syntax region cssDefinition transparent matchgroup=cssBraces start="{" end="}" contains=@postcssProperties,@postcssSelector,cssComment,postcssNesting fold

" Highlight the nesting operator like the other compund selectors
highlight default link postcssNestedSelector cssSelectorOp

From what I can tell it does the right thing, tested with:

@media (max-width: 900px) {
  h1 {
    font-size: 2rem;
  }
}

& .foo {
  font: serif;

  & .bar[lang=sv] + main {
    font: serif;

    & .baz {
      font: serif;
    }
  }
}

form,
.testing ~ span {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

  @media (max-width: 900px) {
    .spam {
      display: grid;
    }

    @media (max-width: 900px) {
      .spam {
        display: grid;
      }
    }
  }

  & .card[foo=bar],
  & + .tag ~ div {
    max-height: 200px;
  }
}

What do you think? What else is needed to make this production ready?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants