inline-sql-toolkit 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3 - 2026-10-10
4
+
5
+ - Feature: a "# inline-sql: skip" comment excludes a specific SQL literal from formatting (as a trailing comment on the closing quote line or on a dedicated line directly preceding the literal).
6
+
3
7
  ## 0.5.2 - 2026-10-09
4
8
 
5
9
  - Fixed: with `inlineSql.format.commaPosition: "before"`, the rest of a
package/README.md CHANGED
@@ -246,6 +246,41 @@ order, or the candidate is skipped (`FORMATTER_FAILED`).
246
246
  A single-quoted literal stays on one line and keeps its leading and trailing
247
247
  spaces, because the string may be joined to other text at runtime.
248
248
 
249
+ ### Skipping a literal
250
+
251
+ To exclude a specific SQL literal from formatting, add an `# inline-sql: skip` pragma comment (case-insensitive, matched with `/\binline-sql:\s*skip(?![\w-])/i`). Other comments such as `# noqa: E501` or `# type: ignore` may share the same comment line.
252
+
253
+ You can place the pragma in either of two ways:
254
+
255
+ 1. **Trailing comment on the closing line**: on the line where the literal ends (the closing quote line).
256
+ ```python
257
+ q = "select a,b from t" # inline-sql: skip
258
+ q = """--sql
259
+ select a,
260
+ b
261
+ from t
262
+ """ # inline-sql: skip
263
+ ```
264
+ 2. **Dedicated comment line immediately preceding the literal**: on the line directly above where the literal starts, containing only whitespace followed by the `# inline-sql: skip` comment.
265
+ ```python
266
+ # inline-sql: skip
267
+ q = """--sql
268
+ ...
269
+ """
270
+ query = (
271
+ # inline-sql: skip
272
+ """--sql ..."""
273
+ )
274
+ ```
275
+
276
+ Notes on skipping behavior:
277
+
278
+ - On triple-quoted strings, any text after the opening quotes (such as `"""--sql # inline-sql: skip`) is part of the string body, not a Python comment, so a pragma placed there has no effect.
279
+ - A trailing comment on a preceding statement (e.g. `a = "select 1" # inline-sql: skip`) does not affect a literal starting on the next line (`b = "select 2"`). Dedicated comment lines must consist only of whitespace and the comment.
280
+ - Syntax highlighting is powered by TextMate grammar and is not affected by `# inline-sql: skip`. Only formatting excludes the literal.
281
+ - When running **Format at Cursor** on a skipped literal, the command reports `NO_SQL_CANDIDATE`.
282
+ - Both CLI `--check` and `--write` honor `# inline-sql: skip` with the exact same rules: skipped literals are never formatted, never reported on stderr as skipped candidates, and do not cause `--check` to fail.
283
+
249
284
  ## Trust, privacy, and offline behavior
250
285
 
251
286
  In an untrusted workspace the extension provides highlighting only. The three
@@ -268,7 +303,8 @@ over the network, passed to a shell/database, or executed. The bundled
268
303
  `INVALID_CONFIGURATION`, or `PROCESS_FAILED`).
269
304
  - **SQL looks different than expected:** formatting does not validate SQL or
270
305
  infer a dialect. Adjust the settings above and review the source-level
271
- candidate before applying the one-step edit.
306
+ candidate before applying the one-step edit, or exclude the literal with
307
+ `# inline-sql: skip`.
272
308
 
273
309
  For security reporting, see [SECURITY.md](SECURITY.md). For source-free bug
274
310
  reports and diagnostic reason codes, see [SUPPORT.md](SUPPORT.md). Licensing and
package/dist/cli.js CHANGED
@@ -808,6 +808,7 @@ function stringSurfaceAt(source, index) {
808
808
  }
809
809
  function scanSource(source) {
810
810
  const surfaces = [];
811
+ const comments = [];
811
812
  let unterminated = false;
812
813
  let index = 0;
813
814
  while (index < source.length) {
@@ -818,6 +819,7 @@ function scanSource(source) {
818
819
  }
819
820
  if (char === "#") {
820
821
  const end = source.indexOf("\n", index);
822
+ comments.push(new SourceSpan(index, end === -1 ? source.length : end));
821
823
  index = end === -1 ? source.length : end;
822
824
  continue;
823
825
  }
@@ -837,7 +839,7 @@ function scanSource(source) {
837
839
  }
838
840
  index++;
839
841
  }
840
- return { surfaces, unterminated };
842
+ return { surfaces, comments, unterminated };
841
843
  }
842
844
  function scanFstringFields(source, contentSpan) {
843
845
  const fields = [];
@@ -919,6 +921,7 @@ function fstringKind(prefix) {
919
921
  }
920
922
 
921
923
  // src/python-analysis/literals.ts
924
+ var SKIP_PRAGMA = /\binline-sql:\s*skip(?![\w-])/i;
922
925
  function onlyWhitespace(text) {
923
926
  return /^[\s]*$/.test(text);
924
927
  }
@@ -941,7 +944,25 @@ function isConcatenated(source, surfaces, index) {
941
944
  }
942
945
  function analyzeDocument(source) {
943
946
  const sourceMap = SourceMap.fromText(source);
944
- const { surfaces, unterminated } = scanSource(source);
947
+ const { surfaces, comments, unterminated } = scanSource(source);
948
+ const trailingPragmas = /* @__PURE__ */ new Set();
949
+ const ownLinePragmas = /* @__PURE__ */ new Set();
950
+ for (const span of comments) {
951
+ const commentText2 = source.slice(span.start, span.end);
952
+ if (!SKIP_PRAGMA.test(commentText2)) continue;
953
+ const line = sourceMap.vscodeFromOffset(span.start).line;
954
+ const lineStartOffset = sourceMap.offsetFromVscode(line, 0);
955
+ const prefix = source.slice(lineStartOffset, span.start);
956
+ if (/^[ \t]*$/.test(prefix)) {
957
+ ownLinePragmas.add(line);
958
+ } else {
959
+ trailingPragmas.add(line);
960
+ }
961
+ }
962
+ const skipPragmaLines = {
963
+ trailing: trailingPragmas,
964
+ ownLine: ownLinePragmas
965
+ };
945
966
  const supported = [];
946
967
  const unsupported = [];
947
968
  surfaces.forEach((surface, index) => {
@@ -1005,7 +1026,8 @@ function analyzeDocument(source) {
1005
1026
  sourceMap,
1006
1027
  unterminated,
1007
1028
  supported: [...supported].sort((left, right) => left.span.start - right.span.start),
1008
- unsupported: [...unsupported].sort((left, right) => left.span.start - right.span.start)
1029
+ unsupported: [...unsupported].sort((left, right) => left.span.start - right.span.start),
1030
+ skipPragmaLines
1009
1031
  };
1010
1032
  }
1011
1033
 
@@ -2211,6 +2233,12 @@ var MAX_CANDIDATE_BYTES = 1024 * 1024;
2211
2233
  var MAX_CANDIDATES = 1e3;
2212
2234
  var ResourceLimitError = class extends Error {
2213
2235
  };
2236
+ function isSkippedByPragma(literal, analysis) {
2237
+ const startLine = analysis.sourceMap.vscodeFromOffset(literal.span.start).line;
2238
+ const endLine = analysis.sourceMap.vscodeFromOffset(literal.span.end).line;
2239
+ const { trailing, ownLine } = analysis.skipPragmaLines;
2240
+ return ownLine.has(startLine - 1) || trailing.has(endLine) || ownLine.has(endLine);
2241
+ }
2214
2242
  function discover(analysis) {
2215
2243
  const literals = [
2216
2244
  ...analysis.supported,
@@ -2219,7 +2247,7 @@ function discover(analysis) {
2219
2247
  const units = literals.map((literal) => ({
2220
2248
  literal,
2221
2249
  detection: detectSql(literal, analysis.sourceMap)
2222
- })).filter((unit) => unit.detection.matched);
2250
+ })).filter((unit) => unit.detection.matched && !isSkippedByPragma(unit.literal, analysis));
2223
2251
  return [...units].sort((left, right) => left.literal.span.start - right.literal.span.start);
2224
2252
  }
2225
2253
  function selectUnits(units, target, sourceMap) {
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/hidenobunagai/inline-sql-toolkit/issues"
13
13
  },
14
- "version": "0.5.2",
14
+ "version": "0.5.3",
15
15
  "icon": "icon.png",
16
16
  "type": "module",
17
17
  "bin": {