Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
uses: actions/checkout@v4
with:
node-version: 18.13.0
ref: ${{ github.ref }}
- name: Setup Node.js
uses: actions/setup-node@v4
- name: Install dependencies
run: npm install
- name: Build package
run: npm run build
- name: Run headless test
uses: GabrielBB/xvfb-action@v1.0
uses: coactions/setup-xvfb@v1
with:
run: npm test
22 changes: 10 additions & 12 deletions .github/workflows/publish-extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,33 @@ name: "Publish to Marketplace"
on:
workflow_run:
workflows: ["CI"]
types:
- completed
types: [completed]
branches: [master]

jobs:
cd:
if: >
${{ github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'master' }}
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout to branch
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- name: Setup node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: "Bump version"
uses: 'phips28/gh-action-bump-version@master'
uses: "phips28/gh-action-bump-version@master"
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
with:
minor-wording: 'MINOR'
major-wording: 'MAJOR'
patch-wording: 'PATCH,FIX'
rc-wording: 'RELEASE'
minor-wording: "MINOR"
major-wording: "MAJOR"
patch-wording: "PATCH,FIX"
rc-wording: "RELEASE"

- name: Install packages
run: npm ci
Expand Down
8 changes: 8 additions & 0 deletions content.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ abc中文💖
Hello, World!
12345!@#$%
Test123!
'She said, "Hello"'
"My name's Minalike"
"He said, 'It's a trap!'"
'She exclaimed, \"Wow!\"'
"'Double' and 'single' quotes"
No quotes at all
'It's'
"My name's %20 Minalike!"
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@
"title": "Random Case",
"category": "String Manipulation",
"command": "string-manipulation.randomCase"
},
{
"title": "Swap Quotes",
"category": "String Manipulation",
"command": "string-manipulation.swapQuotes"
}
],
"submenus": [
Expand Down Expand Up @@ -329,6 +334,10 @@
{
"command": "string-manipulation.randomCase",
"group": "7_modification"
},
{
"command": "string-manipulation.swapQuotes",
"group": "7_modification"
}
]
}
Expand Down
29 changes: 13 additions & 16 deletions src/commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as vscode from "vscode";
import * as underscore from "underscore.string";
import { swapQuotes } from "./commands/swap_quotes";
const apStyleTitleCase = require("ap-style-title-case");
const chicagoStyleTitleCase = require("chicago-capitalize");
const slugify = require("@sindresorhus/slugify");
Expand Down Expand Up @@ -39,6 +40,14 @@ const randomCase = (input: string): string => {
return result;
};

const snake = (str: string) =>
underscore
.underscored(str)
.replace(/([A-Z])[^A-Z]/g, " $1")
.replace(/[^a-z0-9]+/gi, " ")
.trim()
.replace(/\s/gi, "_");

export type StringFunction = (
str: string,
multiselectData?: MultiSelectData
Expand All @@ -53,7 +62,7 @@ const commandNameFunctionMap: { [key: string]: CommandFunction } = {
classify: defaultFunction("classify"),
clean: defaultFunction("clean"),
cleanDiacritics: defaultFunction("cleanDiacritics"),
underscored: defaultFunction("underscored"),
underscored: snake,
dasherize: defaultFunction("dasherize"),
humanize: defaultFunction("humanize"),
reverse: defaultFunction("reverse"),
Expand All @@ -64,21 +73,8 @@ const commandNameFunctionMap: { [key: string]: CommandFunction } = {
underscore.camelize(/[a-z]/.test(str) ? str : str.toLowerCase()),
slugify: slugify,
swapCase: defaultFunction("swapCase"),
snake: (str: string) =>
underscore
.underscored(str)
.replace(/([A-Z])[^A-Z]/g, " $1")
.replace(/[^a-z]+/gi, " ")
.trim()
.replace(/\s/gi, "_"),
screamingSnake: (str: string) =>
underscore
.underscored(str)
.replace(/([A-Z])[^A-Z]/g, " $1")
.replace(/[^a-z]+/gi, " ")
.trim()
.replace(/\s/gi, "_")
.toUpperCase(),
snake,
screamingSnake: (str: string) => snake(str).toUpperCase(),
titleizeApStyle: apStyleTitleCase,
titleizeChicagoStyle: chicagoStyleTitleCase,
truncate: (n: number) => defaultFunction("truncate", n),
Expand All @@ -101,6 +97,7 @@ const commandNameFunctionMap: { [key: string]: CommandFunction } = {
.map((x) => `\\u${x.charCodeAt(0).toString(16).padStart(4, "0")}`)
.join(""),
randomCase,
swapQuotes,
};

const numberFunctionNames = [
Expand Down
52 changes: 52 additions & 0 deletions src/commands/swap_quotes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export const swapQuotes = (str: string): string => {
const singleQuote = "'";
const doubleQuote = '"';

// Check if the string is at least two characters and starts and ends with the same quote
if (str.length < 2) {
return str; // Return as is if not properly quoted
}

const firstChar = str[0];
const lastChar = str[str.length - 1];

if (
(firstChar !== singleQuote && firstChar !== doubleQuote) ||
firstChar !== lastChar
) {
// Not properly quoted, return as is
return str;
}

const originalQuote = firstChar;
const newQuote = originalQuote === singleQuote ? doubleQuote : singleQuote;
let content = str.slice(1, -1);

// Swap inner quotes
content = content.replace(/['"]/g, (match, offset) => {
// Determine if the quote is part of an apostrophe
const prevChar = content[offset - 1];
const nextChar = content[offset + 1];
const isApostrophe =
match === "'" &&
/[a-zA-Z]/.test(prevChar || "") &&
/[a-zA-Z]/.test(nextChar || "");

if (isApostrophe) {
// Handle apostrophe based on the desired output
if (newQuote === singleQuote) {
// Escape apostrophe when outer quote is single quote
return "\\'";
} else {
// Keep apostrophe as is when outer quote is double quote
return match;
}
} else {
// Swap the quote
return match === originalQuote ? newQuote : originalQuote;
}
});

// Return the new string with swapped quotes
return newQuote + content + newQuote;
};
Loading
Loading