├── .github └── workflows │ ├── autolog.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── README-KO.md ├── README.md ├── after └── plugin │ └── cmp-tw2css.lua ├── lua └── cmp-tw2css │ ├── generate.lua │ ├── init.lua │ ├── items.lua │ └── tw.json └── stylua.toml /.github/workflows/autolog.yml: -------------------------------------------------------------------------------- 1 | name: Autolog 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | workflow_call: 8 | 9 | jobs: 10 | generate-changelog: 11 | name: Generate Changelog 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | 18 | - name: Changelog 19 | uses: ardalanamini/auto-changelog@v3 20 | id: changelog 21 | with: 22 | github-token: ${{ secrets.GITHUB_TOKEN }} 23 | commit-types: | 24 | breaking: Breaking Changes 25 | feat: New Features 26 | fix: Bug Fixes 27 | revert: Reverts 28 | perf: Performance Improvements 29 | refactor: Refactors 30 | deps: Dependencies 31 | docs: Documentation Changes 32 | style: Code Style Changes 33 | build: Build System 34 | ci: Continuous Integration 35 | test: Tests 36 | chore: Chores 37 | other: Other Changes 38 | default-commit-type: Default Type 39 | mention-authors: false 40 | mention-new-contributors: false 41 | include-compare: false 42 | semver: false 43 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]+.[0-9]+.[0-9]+*' 7 | 8 | jobs: 9 | autolog: 10 | uses: ./.github/workflows/autolog.yml 11 | 12 | release: 13 | name: Create Release 14 | 15 | concurrency: github-release 16 | 17 | environment: 18 | name: release 19 | url: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }} 20 | 21 | runs-on: ubuntu-latest 22 | 23 | needs: 24 | - autolog 25 | 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@v3 29 | 30 | - name: Changelog 31 | uses: ardalanamini/auto-changelog@master 32 | id: changelog 33 | 34 | - name: Create Release 35 | uses: softprops/action-gh-release@v1 36 | with: 37 | body: | 38 | ${{ steps.changelog.outputs.changelog }} 39 | prerelease: ${{ steps.changelog.outputs.prerelease }} 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.CHANGELOG_TOKEN }} 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Joohoon Cha 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-KO.md: -------------------------------------------------------------------------------- 1 | # cmp-tw2css 2 | 3 | `cmp-tw2css`는 [`nvim-cmp`](https://github.com/hrsh7th/nvim-cmp) 엔진을 사용하여 [tailwindcss](https://tailwindcss.com) 클래스를 css 코드로 완성해주는 플러그인입니다. 4 | Neovim에 내장된 treesitter 라이브러리를 이용하여 파일 내의 css 코드 블록 여부를 확인하고 그에 따라 자동 완성 소스를 로드합니다. 5 | 6 | ## 기본 설정하기 7 | 8 | ### 플러그인을 설치하기 전에... 9 | 10 | `cmp-tw2css`는 `nvim-cmp` 엔진을 통해 코드를 제공합니다. 플러그인 사용을 위해서는 `nvim-cmp`가 neovim에 설치된 상태여야 합니다. `nvim-cmp`를 설치하는 방법은 [nvim-cmp Github repo](https://github.com/hrsh7th/nvim-cmp)를 참고해주세요. 11 | 12 | `cmp-tw2css`는 버전 1.0.0부터 css 파서(parser)를 이용하여 커서가 css 코드 블록 안에 있는지 확인합니다. 따라서 이 기능을 이용하기 위해서는 css 파서를 필요로 합니다. 더 자세한 내용은 [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)에서 찾을 수 있습니다. 13 | 14 | ### 설치 방법 15 | 16 | 선호하는 플러그인 매니저를 사용하여 간편하게 설치할 수 있습니다. 이 페이지의 예시는 가장 대중적으로 사용되는 [`packer.nvim`](https://github.com/wbthomason/packer.nvim)를 통해 설치하는 방법을 서술하고 있습니다. 17 | 18 | ```lua 19 | use({ 20 | "hrsh7th/nvim-cmp", 21 | requires = { 22 | "jcha0713/cmp-tw2css", 23 | }, 24 | }) 25 | ``` 26 | 27 | `packer.nvim`을 통해 설치가 끝난 후에는 다음의 설정값을 `nvim-cmp`에 추가해주어야 합니다. 28 | 29 | ```lua 30 | require('cmp').setup { 31 | -- ... 32 | sources = { 33 | { name = 'cmp-tw2css' }, 34 | -- other sources ... 35 | }, 36 | -- ... 37 | } 38 | ``` 39 | 40 | ## 어떻게 사용하나요? 41 | 42 | 여기까지 설치를 무사히 완료했다면 `cmp-tw2css` 사용은 쉽습니다. CSS 블록을 포함하고 있는 파일을 열고 원하는 tailwindcss 클래스를 입력하면 CSS 코드로 변환이 가능합니다. 43 | 44 | ### 예시 45 | 46 |  47 | 48 | - `*.css`: 49 | 50 | ```css 51 | body { 52 | /* flex -> display: flex; */ 53 | /* p-6 -> padding: 1.5rem; */ 54 | /* ... */ 55 | } 56 | ``` 57 | 58 | - `*.html`: 59 | 60 | ```html 61 | 62 | 63 |
64 | 69 | 70 | 71 | 72 | 73 | 74 | ``` 75 | 76 | ## 변수 설정 77 | 78 | ```lua 79 | require('cmp-tw2css').setup({ ... }) 80 | ``` 81 | 82 | ### `fallback` 83 | 84 | **type**: `boolean` 85 | **default**: `true` 86 | 87 | ```lua 88 | { 89 | fallback = true 90 | } 91 | ``` 92 | 93 | treesitter 파서가 없을 때 자동 완성 소스를 로드할지 말지 정합니다. `true`로 설정하는 경우에는 css 파서 없이도 소스를 로드하지만 커서 위치에 관계없이 모든 상황에서 소스를 불러오게 됩니다. `false`로 설정하면 css 파서가 없는 상황에서는 완성 소스를 불러오지 않습니다. 94 | 95 | ## 사용 전에 알아야 할 주의 사항 96 | 97 | `cmp-tw2css`는 tailwindcss 공식 문서를 스크래핑하여 만든 파일을 통해 완성 소스를 제공합니다. 따라서 공식 문서에 내용이 추가되거나 제외되는 부분을 바로 반영하기가 힘듭니다. 또한 미리 만들어진 파일을 통해 제공되는 소스이기 때문에 사용자가 원하는대로 값을 수정하는 게 불가능합니다. Tailwindcss 문서가 제공하는 내용과 다른 부분을 찾게 된다면 언제든지 issue를 생성해주세요. 98 | 99 | 추가적으로 같은 줄에 `:`이 두 번 이상 나올 경우 완성 소스를 로드하지 못하는 한계가 있으며 입력하는 css 코드가 두 줄 이상일 경우에 탭을 자동으로 삽입하지 않는 소소한 단점이 있습니다. 100 | 101 | ## 추가될 기능들 102 | 103 | - [x] 커서가 css 코드 블록 안에 있을 때만 소스를 로드하기 104 | - [x] treesitter 기능을 사용자가 제어할 수 있게 하기 105 | - [x] 완성 소스를 고를 때 documentation 보여주기 106 | - [ ] LSP를 이용하여 웹 스크래핑 없이 소스 제공하기 107 | 108 | ## 참고한 프로젝트 109 | 110 | - [`cmp-emoji`](https://github.com/hrsh7th/cmp-emoji) 111 | - [`cmp-npm`](https://github.com/David-Kunz/cmp-npm) 112 | - [`nvim-treesitter`](https://github.com/nvim-treesitter/nvim-treesitter) 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cmp-tw2css 2 | 3 | - [한국어 문서 읽으러 가기](README-KO.md) 4 | 5 | A source for [`nvim-cmp`](https://github.com/hrsh7th/nvim-cmp) to convert [tailwindcss](https://tailwindcss.com) classes to pure css codes. 6 | It uses treesitter to find out whether any css code block exists in the code and loads the completion source. 7 | 8 | ## Setup 9 | 10 | ### Prerequisites: 11 | 12 | `cmp-tw2css` uses `nvim-cmp` to provide the code. You first need to have `nvim-cmp` installed in your neovim. To install `nvim-cmp`, please visit the [nvim-cmp Github repo](https://github.com/hrsh7th/nvim-cmp). 13 | 14 | Since version 1.0.0, `cmp-tw2css` uses css parser to detect if the cursor is inside the css code block. To fully use this feature, you need to install the css parser through `nvim-treesitter`. For more information, please refer to [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter). 15 | 16 | ### Installation 17 | 18 | To install `cmp-tw2css`, I recommend using [`packer.nvim`](https://github.com/wbthomason/packer.nvim). 19 | 20 | ```lua 21 | use({ 22 | "hrsh7th/nvim-cmp", 23 | requires = { 24 | "jcha0713/cmp-tw2css", 25 | }, 26 | }) 27 | ``` 28 | 29 | And to add source, go to `nvim-cmp` configuration and add the following 30 | 31 | ```lua 32 | require('cmp').setup { 33 | -- ... 34 | sources = { 35 | { name = 'cmp-tw2css' }, 36 | -- other sources ... 37 | }, 38 | -- ... 39 | } 40 | ``` 41 | 42 | ## Usage 43 | 44 | Using `cmp-tw2css` is simple. Open any file that contains css code blocks and start typing tailwindcss classes that you want to convert into css codes. 45 | 46 | ### Example 47 | 48 |  49 | 50 | - `*.css`: 51 | 52 | ```css 53 | body { 54 | /* flex -> display: flex; */ 55 | /* p-6 -> padding: 1.5rem; */ 56 | /* ... */ 57 | } 58 | ``` 59 | 60 | - `*.html`: 61 | 62 | ```html 63 | 64 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | ``` 77 | 78 | ## Configuration 79 | 80 | ```lua 81 | require('cmp-tw2css').setup({ ... }) 82 | ``` 83 | 84 | ### `fallback` 85 | 86 | **type**: `boolean` 87 | **default**: `true` 88 | 89 | ```lua 90 | { 91 | fallback = true 92 | } 93 | ``` 94 | 95 | Determines whether to load the completion items when there is no treesitter parser. If this is set to `true`, you are allowing `cmp-tw2css` to load the completion items regardless of your cursor position. If it is set to `false`, then it simply does not load anything when there is no css parser. 96 | 97 | ## Limitation 98 | 99 | There are a number of limitations to `cmp-tw2css`. First, the source of this plugin is a result of web scraping. This means that you might find some items are missing while using. If this happens to you, please let me know by submitting an issue so that I can update the source accordingly. Another downside is that it can't be dynamically generated and only provides the code from the official website. 100 | 101 | Currently `cmp-tw2css` does not automatically add tabs for the additional lines when the insert text is more than one line. And also when there are more than one colon(`:`) in a line, `cmp-tw2css` cannot properly load its completion source. 102 | 103 | ## Roadmap 104 | 105 | - [x] Load the source only when the cursor is inside the code block 106 | - [x] Provide ways to configure with treesitter 107 | - [x] Show documentation when selecting an item 108 | - [ ] Provide the completion source using LSP functionality 109 | 110 | ## Credit 111 | 112 | - [`cmp-emoji`](https://github.com/hrsh7th/cmp-emoji) 113 | - [`cmp-npm`](https://github.com/David-Kunz/cmp-npm) 114 | - [`nvim-treesitter`](https://github.com/nvim-treesitter/nvim-treesitter) 115 | -------------------------------------------------------------------------------- /after/plugin/cmp-tw2css.lua: -------------------------------------------------------------------------------- 1 | local ok, cmp = pcall(require, "cmp") 2 | if ok then 3 | cmp.register_source("cmp-tw2css", require("cmp-tw2css").new()) 4 | end 5 | -------------------------------------------------------------------------------- /lua/cmp-tw2css/generate.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M._read = function(path) 4 | return vim.fn.json_decode(vim.fn.readfile(path)) 5 | end 6 | 7 | M._write = function(path, data) 8 | local writer = io.open(path, "w") 9 | writer:write(data) 10 | io.close(writer) 11 | end 12 | 13 | M.to_item = function(key, value) 14 | return ( 15 | "{ word = '%s', label = '%s', insertText = [[%s]], filterText = '%s', detail = [[%s]] };\n" 16 | ):format(key, key, value, key, value) 17 | end 18 | 19 | M.update = function() 20 | -- load json file 21 | local classTable = vim.fn.json_decode( 22 | vim.fn.readfile(vim.fn.expand("%:p:h") .. "/tw.json") 23 | ) 24 | 25 | local items = "" 26 | for key, value in pairs(classTable) do 27 | items = items .. M.to_item(key, value) 28 | end 29 | M._write("./items.lua", ("return function() return {\n%s} end"):format(items)) 30 | end 31 | 32 | M.update() 33 | 34 | return M 35 | -------------------------------------------------------------------------------- /lua/cmp-tw2css/init.lua: -------------------------------------------------------------------------------- 1 | local source = {} 2 | local opt = { 3 | fallback = true, 4 | } 5 | 6 | ---@class cmp-tw2css.source 7 | ---@field public is_sorted boolean 8 | ---@field public items table