From 11ecfb6cc14ef8a981967e081fd80ae5278233be Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 16 May 2023 11:34:46 +0300 Subject: [PATCH 1/7] docs: update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0929afb..bd6cb6c 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ To get started, [install](#-installation) the plugin via your favorite package m
Click to unfold the full list of options with their default values -> **Note**: The options are also available in Neovim by calling `:h text-transform.options` +> **Note**: The options are also available in Neovim by calling `:h TextTransform.options` ```lua require("text-transform").setup({ From 7f842fbfe373e8c8aefcd427ad3f5b67ea5d0bf8 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 16 May 2023 11:35:34 +0300 Subject: [PATCH 2/7] build: update develop workflow names --- .github/workflows/develop.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index d046165..fdb53df 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -1,10 +1,10 @@ -name: Release +name: Dev Release on: push: - branches: [develop] + branches: [ develop ] pull_request: - types: [opened, synchronize] + types: [ opened, synchronize ] concurrency: group: github.head_ref @@ -43,7 +43,7 @@ jobs: - name: check docs diff run: exit $(git status --porcelain doc | wc -l | tr -d " ") release: - name: release + name: dev-release if: ${{ github.ref == 'refs/heads/develop' }} permissions: write-all needs: From 52b155f43fa749ab5fc94d9449424676f8c6d90d Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 16 May 2023 14:18:42 +0300 Subject: [PATCH 3/7] docs: Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index bd6cb6c..ba4c2c7 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ Transform the current word or selection between multiple case types. Need to easily replace myVar with my_var or vice versa? This plugin is for you! +- Works on current word in **Normal Mode** +- Works on selection in **Visual Mode** + | Transformation | Example Inputs | Output | | -------------- | --------------------------- | -------- | | `camelCase` | `my_var`, `my-var`, `MyVar` | `myVar` | From 36651b5aec5bfc28bacf235f0b57921a0e305d09 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 16 May 2023 14:34:07 +0300 Subject: [PATCH 4/7] build: add precommit target --- .editorconfig | 3 +++ Makefile | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/.editorconfig b/.editorconfig index 1a5c53f..6182cf0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,3 +8,6 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false +[Makefile] +indent_style = tab + diff --git a/Makefile b/Makefile index 33820ec..230a401 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,8 @@ test: deps: @mkdir -p deps git clone --depth 1 https://github.com/echasnovski/mini.nvim deps/mini.nvim + echo "#!/usr/bin/env bash\n\nmake precommit" > .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit # installs deps before running tests, useful for the CI. test-ci: deps test @@ -32,3 +34,15 @@ lint: # setup setup: ./scripts/setup.sh + +# precommit +precommit: + stylua . + git add . + make lint + # make test + make documentation + git add doc + +clean: + rm -rf deps From baa38828e49ef8aeeb500c71c1c6d5949ffa15b0 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Tue, 16 May 2023 14:52:19 +0300 Subject: [PATCH 5/7] build: remove setup script --- Makefile | 4 --- scripts/setup.sh | 79 ------------------------------------------------ 2 files changed, 83 deletions(-) delete mode 100755 scripts/setup.sh diff --git a/Makefile b/Makefile index 230a401..1f62076 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,6 @@ documentation-ci: deps documentation lint: stylua . -# setup -setup: - ./scripts/setup.sh - # precommit precommit: stylua . diff --git a/scripts/setup.sh b/scripts/setup.sh deleted file mode 100755 index 7f9a59b..0000000 --- a/scripts/setup.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash - -USAGE="\033[0;37m[INFO] - usage: USERNAME=my-github-username PLUGIN_NAME=my-awesome-plugin REPOSITORY_NAME=my-awesome-plugin.nvim make setup\n\033[0m" - -echo -e "$USAGE" - -if [[ -z "$USERNAME" ]]; then - echo -e "\t> No USERNAME provided, what's your GitHub/GitLab username?" - read -r USERNAME -fi - -if [[ -z "$REPOSITORY_NAME" ]]; then - REPOSITORY_NAME=$(basename -s .git "$(git config --get remote.origin.url)") - - read -rp $'\t> No REPOSITORY_NAME provided, is \033[1;32m'"$REPOSITORY_NAME"$'\033[0m good? [Y/n]\n' yn - case $yn in - [Yy]* );; - [Nn]* ) - echo -e "\t> Enter your repository name" - read -r REPOSITORY_NAME - ;; - * ) - echo -e "$USAGE" - exit 1;; - esac -fi - -if [[ -z "$PLUGIN_NAME" ]]; then - DEFAULT_REPOSITORY_NAME=$(echo "$REPOSITORY_NAME" | sed -e "s/\.nvim//") - read -rp $'\t> No PLUGIN_NAME provided, defaulting to \033[1;32m'"$DEFAULT_REPOSITORY_NAME"$'\033[0m, continue? [Y/n]\n' yn - case $yn in - [Yy]* ) - PLUGIN_NAME=$DEFAULT_REPOSITORY_NAME - ;; - [Nn]* ) - echo -e "\t> Enter your plugin name" - read -r PLUGIN_NAME - ;; - * ) - echo -e "$USAGE" - exit 1;; - esac -fi - -echo -e "Username: \033[1;32m$USERNAME\033[0m\nRepository: \033[1;32m$REPOSITORY_NAME\033[0m\nPlugin: \033[1;32m$PLUGIN_NAME\033[0m\n\n\tRenaming placeholder files..." - -rm -rf doc -mv plugin/your-plugin-name.lua "plugin/$PLUGIN_NAME.lua" -mv lua/your-plugin-name "lua/$PLUGIN_NAME" -mv README_TEMPLATE.md README.md - -echo -e "\tReplacing placeholder names..." - -PASCAL_CASE_PLUGIN_NAME=$(echo "$PLUGIN_NAME" | perl -pe 's/(^|-)./uc($&)/ge;s/-//g') - -grep -rl "YourPluginName" .github/ plugin/ tests/ lua/ | xargs sed -i "" -e "s/YourPluginName/$PASCAL_CASE_PLUGIN_NAME/g" -grep -rl "your-plugin-name" README.md .github/ plugin/ tests/ lua/ | xargs sed -i "" -e "s/your-plugin-name/$PLUGIN_NAME/g" -grep -rl "YOUR_GITHUB_USERNAME" README.md .github/ | xargs sed -i "" -e "s/YOUR_GITHUB_USERNAME/$USERNAME/g" -grep -rl "YOUR_REPOSITORY_NAME" README.md .github/ | xargs sed -i "" -e "s/YOUR_REPOSITORY_NAME/$REPOSITORY_NAME/g" - -echo -e "\n\033[1;32mOK.\033[0m" - -echo -e "\tFetching dependencies (tests and documentation generator)..." - -make deps - -echo -e "\n\033[1;32mOK.\033[0m" - -echo -e "\tGenerating docs..." - -make documentation - -echo -e "\n\033[1;32mOK.\033[0m" - -echo -e "\tRunning tests..." - -make test - -echo -e "\n\033[1;32mOK.\033[0m" From 4bc66d375b8a98450a5656ee796ea65b0bc29112 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Wed, 17 May 2023 09:55:01 +0300 Subject: [PATCH 6/7] build: fix & run tests on ci --- .github/workflows/develop.yml | 37 ++++++- .github/workflows/main.yml | 51 +++++----- lua/text-transform/config.lua | 14 ++- lua/text-transform/init.lua | 161 ++++++++++++++++++++++++++++++ plugin/text-transform.lua | 182 ---------------------------------- 5 files changed, 231 insertions(+), 214 deletions(-) diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index fdb53df..de77b90 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -2,9 +2,9 @@ name: Dev Release on: push: - branches: [ develop ] + branches: [develop] pull_request: - types: [ opened, synchronize ] + types: [opened, synchronize] concurrency: group: github.head_ref @@ -42,13 +42,42 @@ jobs: - name: check docs diff run: exit $(git status --porcelain doc | wc -l | tr -d " ") + tests: + needs: + - lint + - documentation + runs-on: ubuntu-latest + timeout-minutes: 2 + strategy: + matrix: + neovim_version: ['v0.7.2', 'v0.8.3', 'v0.9.0', 'nightly'] + + steps: + - uses: actions/checkout@v3 + + - run: date +%F > todays-date + + - name: restore cache for today's nightly. + uses: actions/cache@v3 + with: + path: _neovim + key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }} + + - name: setup neovim + uses: rhysd/action-setup-vim@v1 + with: + neovim: true + version: ${{ matrix.neovim_version }} + + - name: run tests + run: make test-ci + release: name: dev-release if: ${{ github.ref == 'refs/heads/develop' }} permissions: write-all needs: - - lint - - documentation + - tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 43a5ef9..853e080 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,43 +43,42 @@ jobs: - name: check docs diff run: exit $(git status --porcelain doc | wc -l | tr -d " ") - # tests: - # needs: - # - lint - # - documentation - # runs-on: ubuntu-latest - # timeout-minutes: 2 - # strategy: - # matrix: - # neovim_version: ['v0.7.2', 'v0.8.3', 'v0.9.0', 'nightly'] + tests: + needs: + - lint + - documentation + runs-on: ubuntu-latest + timeout-minutes: 2 + strategy: + matrix: + neovim_version: ['v0.7.2', 'v0.8.3', 'v0.9.0', 'nightly'] - # steps: - # - uses: actions/checkout@v3 + steps: + - uses: actions/checkout@v3 - # - run: date +%F > todays-date + - run: date +%F > todays-date - # - name: restore cache for today's nightly. - # uses: actions/cache@v3 - # with: - # path: _neovim - # key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }} + - name: restore cache for today's nightly. + uses: actions/cache@v3 + with: + path: _neovim + key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }} - # - name: setup neovim - # uses: rhysd/action-setup-vim@v1 - # with: - # neovim: true - # version: ${{ matrix.neovim_version }} + - name: setup neovim + uses: rhysd/action-setup-vim@v1 + with: + neovim: true + version: ${{ matrix.neovim_version }} - # - name: run tests - # run: make test-ci + - name: run tests + run: make test-ci release: name: release if: ${{ github.ref == 'refs/heads/master' }} permissions: write-all needs: - - lint - - documentation + - tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/lua/text-transform/config.lua b/lua/text-transform/config.lua index 80bde78..3133859 100644 --- a/lua/text-transform/config.lua +++ b/lua/text-transform/config.lua @@ -26,6 +26,18 @@ function TextTransform.setup(options) TextTransform.options = vim.tbl_deep_extend("keep", options, TextTransform.options) + if vim.api.nvim_get_vvar("vim_did_enter") == 0 then + vim.defer_fn(function() + TextTransform._setup() + end, 0) + else + TextTransform._setup() + end + + return TextTransform.options +end + +function TextTransform._setup() local map = { ["&camelCase"] = "TextTransform.camel_case", ["&snake_case"] = "TextTransform.snake_case", @@ -55,8 +67,6 @@ function TextTransform.setup(options) "popup TransformsSelection", { silent = true } ) - - return TextTransform.options end return TextTransform diff --git a/lua/text-transform/init.lua b/lua/text-transform/init.lua index c9253ee..498eebb 100644 --- a/lua/text-transform/init.lua +++ b/lua/text-transform/init.lua @@ -36,6 +36,167 @@ function TextTransform.setup(opts) _G.TextTransform.config = require("text-transform.config").setup(opts) end +function TextTransform.into_words(str) + local words = {} + local word = "" + + local previous_is_upper = false + for i = 1, #str do + local char = str:sub(i, i) + -- split on uppercase letters + if char:match("%u") and not previous_is_upper then + if word ~= "" then + table.insert(words, word) + end + previous_is_upper = true + word = char + -- split on underscores, hyphens, and spaces + elseif char:match("[%_%-%s]") then + if word ~= "" then + table.insert(words, word) + previous_is_upper = false + end + word = "" + else + word = word .. char + previous_is_upper = char:match("%u") + end + end + if word ~= "" then + table.insert(words, word) + previous_is_upper = false + end + return words +end + +function TextTransform.camel_case(string) + local words = TextTransform.into_words(string) + local camel_case = "" + for i, word in ipairs(words) do + if i == 1 then + camel_case = camel_case .. word:lower() + else + camel_case = camel_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + end + end + return camel_case +end + +function TextTransform.snake_case(string) + local words = TextTransform.into_words(string) + local snake_case = "" + for i, word in ipairs(words) do + if i == 1 then + snake_case = snake_case .. word:lower() + else + snake_case = snake_case .. "_" .. word:lower() + end + end + return snake_case +end + +function TextTransform.pascal_case(string) + local words = TextTransform.into_words(string) + local pascal_case = "" + for _, word in ipairs(words) do + pascal_case = pascal_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + end + return pascal_case +end + +function TextTransform.kebab_case(string) + local words = TextTransform.into_words(string) + local kebab_case = "" + for i, word in ipairs(words) do + if i == 1 then + kebab_case = kebab_case .. word:lower() + else + kebab_case = kebab_case .. "-" .. word:lower() + end + end + return kebab_case +end + +function TextTransform.dot_case(string) + local words = TextTransform.into_words(string) + local dot_case = "" + for i, word in ipairs(words) do + if i == 1 then + dot_case = dot_case .. word:lower() + else + dot_case = dot_case .. "." .. word:lower() + end + end + return dot_case +end + +function TextTransform.title_case(string) + local words = TextTransform.into_words(string) + local title_case = "" + for i, word in ipairs(words) do + title_case = title_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + if i ~= #words then + title_case = title_case .. " " + end + end + return title_case +end + +function TextTransform.const_case(string) + local words = TextTransform.into_words(string) + local const_case = "" + for i, word in ipairs(words) do + if i == 1 then + const_case = const_case .. word:upper() + else + const_case = const_case .. "_" .. word:upper() + end + end + return const_case +end + +function TextTransform.replace_selection(transform) + -- get the current visual selection, and transform the line, only replacing the selected text itself + local _, start_line, start_col = unpack(vim.fn.getpos("'<")) + local _, end_line, end_col = unpack(vim.fn.getpos("'>")) + -- print(vim.inspect(vim.fn.getpos("'<")), vim.inspect(vim.fn.getpos("'>")), + -- start_line, start_col, end_line, end_col) + local lines = vim.fn.getline(start_line, end_line) + -- print(vim.inspect(lines)) + + -- transform all included lines + local transformed = "" + + if #lines == 1 then + transformed = lines[1]:sub(1, start_col - 1) + .. transform(lines[1]:sub(start_col, end_col)) + .. lines[1]:sub(end_col + 1) + else + transformed = lines[1]:sub(1, start_col - 1) .. transform(lines[1]:sub(start_col)) .. "\n" + for i = 2, #lines - 1 do + transformed = transformed .. transform(lines[i]) .. "\n" + end + transformed = transformed + .. transform(lines[#lines]:sub(1, end_col)) + .. lines[#lines]:sub(end_col + 1) + end + + -- replace the lines with the transformed lines + vim.fn.setline(start_line, transformed) + for i = start_line + 1, end_line do + vim.fn.setline(i, "") + end + + -- move the cursor to the end of the transformed text + vim.fn.cursor(end_line, end_col) +end + +function TextTransform.replace_word(transform) + local word = vim.fn.expand("") + local transformed = transform(word) + vim.cmd("normal ciw" .. transformed) +end + _G.TextTransform = TextTransform return _G.TextTransform diff --git a/plugin/text-transform.lua b/plugin/text-transform.lua index 95028b4..0234a74 100644 --- a/plugin/text-transform.lua +++ b/plugin/text-transform.lua @@ -4,185 +4,3 @@ if _G.TextTransformLoaded then end _G.TextTransformLoaded = true - -function TextTransform.into_words(str) - local words = {} - local word = "" - - local previous_is_upper = false - for i = 1, #str do - local char = str:sub(i, i) - -- split on uppercase letters - if char:match("%u") and not previous_is_upper then - if word ~= "" then - table.insert(words, word) - end - previous_is_upper = true - word = char - -- split on underscores, hyphens, and spaces - elseif char:match("[%_%-%s]") then - if word ~= "" then - table.insert(words, word) - previous_is_upper = false - end - word = "" - else - word = word .. char - previous_is_upper = char:match("%u") - end - end - if word ~= "" then - table.insert(words, word) - previous_is_upper = false - end - return words -end - -function TextTransform.camel_case(string) - local words = TextTransform.into_words(string) - local camel_case = "" - for i, word in ipairs(words) do - if i == 1 then - camel_case = camel_case .. word:lower() - else - camel_case = camel_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - end - end - return camel_case -end - -function TextTransform.snake_case(string) - local words = TextTransform.into_words(string) - local snake_case = "" - for i, word in ipairs(words) do - if i == 1 then - snake_case = snake_case .. word:lower() - else - snake_case = snake_case .. "_" .. word:lower() - end - end - return snake_case -end - -function TextTransform.pascal_case(string) - local words = TextTransform.into_words(string) - local pascal_case = "" - for _, word in ipairs(words) do - pascal_case = pascal_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - end - return pascal_case -end - -function TextTransform.kebab_case(string) - local words = TextTransform.into_words(string) - local kebab_case = "" - for i, word in ipairs(words) do - if i == 1 then - kebab_case = kebab_case .. word:lower() - else - kebab_case = kebab_case .. "-" .. word:lower() - end - end - return kebab_case -end - -function TextTransform.dot_case(string) - local words = TextTransform.into_words(string) - local dot_case = "" - for i, word in ipairs(words) do - if i == 1 then - dot_case = dot_case .. word:lower() - else - dot_case = dot_case .. "." .. word:lower() - end - end - return dot_case -end - -function TextTransform.title_case(string) - local words = TextTransform.into_words(string) - local title_case = "" - for i, word in ipairs(words) do - title_case = title_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - if i ~= #words then - title_case = title_case .. " " - end - end - return title_case -end - -function TextTransform.const_case(string) - local words = TextTransform.into_words(string) - local const_case = "" - for i, word in ipairs(words) do - if i == 1 then - const_case = const_case .. word:upper() - else - const_case = const_case .. "_" .. word:upper() - end - end - return const_case -end - -function TextTransform.replace_selection(transform) - -- get the current visual selection, and transform the line, only replacing the selected text itself - local _, start_line, start_col = unpack(vim.fn.getpos("'<")) - local _, end_line, end_col = unpack(vim.fn.getpos("'>")) - -- print(vim.inspect(vim.fn.getpos("'<")), vim.inspect(vim.fn.getpos("'>")), - -- start_line, start_col, end_line, end_col) - local lines = vim.fn.getline(start_line, end_line) - -- print(vim.inspect(lines)) - - -- transform all included lines - local transformed = "" - - if #lines == 1 then - transformed = lines[1]:sub(1, start_col - 1) - .. transform(lines[1]:sub(start_col, end_col)) - .. lines[1]:sub(end_col + 1) - else - transformed = lines[1]:sub(1, start_col - 1) .. transform(lines[1]:sub(start_col)) .. "\n" - for i = 2, #lines - 1 do - transformed = transformed .. transform(lines[i]) .. "\n" - end - transformed = transformed - .. transform(lines[#lines]:sub(1, end_col)) - .. lines[#lines]:sub(end_col + 1) - end - - -- replace the lines with the transformed lines - vim.fn.setline(start_line, transformed) - for i = start_line + 1, end_line do - vim.fn.setline(i, "") - end - - -- move the cursor to the end of the transformed text - vim.fn.cursor(end_line, end_col) -end - -function TextTransform.replace_word(transform) - local word = vim.fn.expand("") - local transformed = transform(word) - vim.cmd("normal ciw" .. transformed) -end - -local should_test = false - -if should_test then - local map = { - ["CamelCase"] = TextTransform.camel_case, - ["SnakeCase"] = TextTransform.snake_case, - ["PascalCase"] = TextTransform.pascal_case, - ["KebabCase"] = TextTransform.kebab_case, - ["DotCase"] = TextTransform.dot_case, - ["TitleCase"] = TextTransform.title_case, - ["ConstCase"] = TextTransform.title_case, - } - - for k, tst in pairs(map) do - print(k .. ": " .. "hello_world" .. " => " .. tst("hello_world")) - print(k .. ": " .. "HELLO_WORLD" .. " => " .. tst("HELLO_WORLD")) - print(k .. ": " .. "HelloWorld" .. " => " .. tst("HelloWorld")) - print(k .. ": " .. "Hello-World" .. " => " .. tst("Hello-World")) - end -end From 79f9da24679ebdcf79dd2c26d94fe74c8f4ce8c8 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Wed, 17 May 2023 10:13:15 +0300 Subject: [PATCH 7/7] refactor: move func defs to main.lua and re-export in init.lua --- lua/text-transform/init.lua | 169 +++--------------------------------- lua/text-transform/main.lua | 161 ++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 159 deletions(-) diff --git a/lua/text-transform/init.lua b/lua/text-transform/init.lua index 498eebb..e358f17 100644 --- a/lua/text-transform/init.lua +++ b/lua/text-transform/init.lua @@ -36,166 +36,17 @@ function TextTransform.setup(opts) _G.TextTransform.config = require("text-transform.config").setup(opts) end -function TextTransform.into_words(str) - local words = {} - local word = "" +TextTransform.into_words = M.into_words +TextTransform.replace_word = M.replace_word +TextTransform.replace_selection = M.replace_selection - local previous_is_upper = false - for i = 1, #str do - local char = str:sub(i, i) - -- split on uppercase letters - if char:match("%u") and not previous_is_upper then - if word ~= "" then - table.insert(words, word) - end - previous_is_upper = true - word = char - -- split on underscores, hyphens, and spaces - elseif char:match("[%_%-%s]") then - if word ~= "" then - table.insert(words, word) - previous_is_upper = false - end - word = "" - else - word = word .. char - previous_is_upper = char:match("%u") - end - end - if word ~= "" then - table.insert(words, word) - previous_is_upper = false - end - return words -end - -function TextTransform.camel_case(string) - local words = TextTransform.into_words(string) - local camel_case = "" - for i, word in ipairs(words) do - if i == 1 then - camel_case = camel_case .. word:lower() - else - camel_case = camel_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - end - end - return camel_case -end - -function TextTransform.snake_case(string) - local words = TextTransform.into_words(string) - local snake_case = "" - for i, word in ipairs(words) do - if i == 1 then - snake_case = snake_case .. word:lower() - else - snake_case = snake_case .. "_" .. word:lower() - end - end - return snake_case -end - -function TextTransform.pascal_case(string) - local words = TextTransform.into_words(string) - local pascal_case = "" - for _, word in ipairs(words) do - pascal_case = pascal_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - end - return pascal_case -end - -function TextTransform.kebab_case(string) - local words = TextTransform.into_words(string) - local kebab_case = "" - for i, word in ipairs(words) do - if i == 1 then - kebab_case = kebab_case .. word:lower() - else - kebab_case = kebab_case .. "-" .. word:lower() - end - end - return kebab_case -end - -function TextTransform.dot_case(string) - local words = TextTransform.into_words(string) - local dot_case = "" - for i, word in ipairs(words) do - if i == 1 then - dot_case = dot_case .. word:lower() - else - dot_case = dot_case .. "." .. word:lower() - end - end - return dot_case -end - -function TextTransform.title_case(string) - local words = TextTransform.into_words(string) - local title_case = "" - for i, word in ipairs(words) do - title_case = title_case .. word:sub(1, 1):upper() .. word:sub(2):lower() - if i ~= #words then - title_case = title_case .. " " - end - end - return title_case -end - -function TextTransform.const_case(string) - local words = TextTransform.into_words(string) - local const_case = "" - for i, word in ipairs(words) do - if i == 1 then - const_case = const_case .. word:upper() - else - const_case = const_case .. "_" .. word:upper() - end - end - return const_case -end - -function TextTransform.replace_selection(transform) - -- get the current visual selection, and transform the line, only replacing the selected text itself - local _, start_line, start_col = unpack(vim.fn.getpos("'<")) - local _, end_line, end_col = unpack(vim.fn.getpos("'>")) - -- print(vim.inspect(vim.fn.getpos("'<")), vim.inspect(vim.fn.getpos("'>")), - -- start_line, start_col, end_line, end_col) - local lines = vim.fn.getline(start_line, end_line) - -- print(vim.inspect(lines)) - - -- transform all included lines - local transformed = "" - - if #lines == 1 then - transformed = lines[1]:sub(1, start_col - 1) - .. transform(lines[1]:sub(start_col, end_col)) - .. lines[1]:sub(end_col + 1) - else - transformed = lines[1]:sub(1, start_col - 1) .. transform(lines[1]:sub(start_col)) .. "\n" - for i = 2, #lines - 1 do - transformed = transformed .. transform(lines[i]) .. "\n" - end - transformed = transformed - .. transform(lines[#lines]:sub(1, end_col)) - .. lines[#lines]:sub(end_col + 1) - end - - -- replace the lines with the transformed lines - vim.fn.setline(start_line, transformed) - for i = start_line + 1, end_line do - vim.fn.setline(i, "") - end - - -- move the cursor to the end of the transformed text - vim.fn.cursor(end_line, end_col) -end - -function TextTransform.replace_word(transform) - local word = vim.fn.expand("") - local transformed = transform(word) - vim.cmd("normal ciw" .. transformed) -end +TextTransform.camel_case = M.camel_case +TextTransform.snake_case = M.snake_case +TextTransform.pascal_case = M.pascal_case +TextTransform.kebab_case = M.kebab_case +TextTransform.dot_case = M.dot_case +TextTransform.title_case = M.title_case +TextTransform.const_case = M.const_case _G.TextTransform = TextTransform diff --git a/lua/text-transform/main.lua b/lua/text-transform/main.lua index d31cd41..3d8664c 100644 --- a/lua/text-transform/main.lua +++ b/lua/text-transform/main.lua @@ -46,4 +46,165 @@ function TextTransform.disable() return S end +function TextTransform.into_words(str) + local words = {} + local word = "" + + local previous_is_upper = false + for i = 1, #str do + local char = str:sub(i, i) + -- split on uppercase letters + if char:match("%u") and not previous_is_upper then + if word ~= "" then + table.insert(words, word) + end + previous_is_upper = true + word = char + -- split on underscores, hyphens, and spaces + elseif char:match("[%_%-%s]") then + if word ~= "" then + table.insert(words, word) + previous_is_upper = false + end + word = "" + else + word = word .. char + previous_is_upper = char:match("%u") + end + end + if word ~= "" then + table.insert(words, word) + previous_is_upper = false + end + return words +end + +function TextTransform.camel_case(string) + local words = TextTransform.into_words(string) + local camel_case = "" + for i, word in ipairs(words) do + if i == 1 then + camel_case = camel_case .. word:lower() + else + camel_case = camel_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + end + end + return camel_case +end + +function TextTransform.snake_case(string) + local words = TextTransform.into_words(string) + local snake_case = "" + for i, word in ipairs(words) do + if i == 1 then + snake_case = snake_case .. word:lower() + else + snake_case = snake_case .. "_" .. word:lower() + end + end + return snake_case +end + +function TextTransform.pascal_case(string) + local words = TextTransform.into_words(string) + local pascal_case = "" + for _, word in ipairs(words) do + pascal_case = pascal_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + end + return pascal_case +end + +function TextTransform.kebab_case(string) + local words = TextTransform.into_words(string) + local kebab_case = "" + for i, word in ipairs(words) do + if i == 1 then + kebab_case = kebab_case .. word:lower() + else + kebab_case = kebab_case .. "-" .. word:lower() + end + end + return kebab_case +end + +function TextTransform.dot_case(string) + local words = TextTransform.into_words(string) + local dot_case = "" + for i, word in ipairs(words) do + if i == 1 then + dot_case = dot_case .. word:lower() + else + dot_case = dot_case .. "." .. word:lower() + end + end + return dot_case +end + +function TextTransform.title_case(string) + local words = TextTransform.into_words(string) + local title_case = "" + for i, word in ipairs(words) do + title_case = title_case .. word:sub(1, 1):upper() .. word:sub(2):lower() + if i ~= #words then + title_case = title_case .. " " + end + end + return title_case +end + +function TextTransform.const_case(string) + local words = TextTransform.into_words(string) + local const_case = "" + for i, word in ipairs(words) do + if i == 1 then + const_case = const_case .. word:upper() + else + const_case = const_case .. "_" .. word:upper() + end + end + return const_case +end + +function TextTransform.replace_selection(transform) + -- get the current visual selection, and transform the line, only replacing the selected text itself + local _, start_line, start_col = unpack(vim.fn.getpos("'<")) + local _, end_line, end_col = unpack(vim.fn.getpos("'>")) + -- print(vim.inspect(vim.fn.getpos("'<")), vim.inspect(vim.fn.getpos("'>")), + -- start_line, start_col, end_line, end_col) + local lines = vim.fn.getline(start_line, end_line) + -- print(vim.inspect(lines)) + + -- transform all included lines + local transformed = "" + + if #lines == 1 then + transformed = lines[1]:sub(1, start_col - 1) + .. transform(lines[1]:sub(start_col, end_col)) + .. lines[1]:sub(end_col + 1) + else + transformed = lines[1]:sub(1, start_col - 1) .. transform(lines[1]:sub(start_col)) .. "\n" + for i = 2, #lines - 1 do + transformed = transformed .. transform(lines[i]) .. "\n" + end + transformed = transformed + .. transform(lines[#lines]:sub(1, end_col)) + .. lines[#lines]:sub(end_col + 1) + end + + -- replace the lines with the transformed lines + vim.fn.setline(start_line, transformed) + for i = start_line + 1, end_line do + vim.fn.setline(i, "") + end + + -- move the cursor to the end of the transformed text + vim.fn.cursor(end_line, end_col) +end + +function TextTransform.replace_word(transform) + local word = vim.fn.expand("") + local transformed = transform(word) + vim.cmd("normal ciw" .. transformed) +end + return TextTransform