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
49 changes: 49 additions & 0 deletions examples/deck-align/DECK_ALIGN.DATA
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- ---------------------------------------------------------------------------
-- Test deck for the "OPM Flow: Align Record Columns in Deck" command.
--
-- Open this file and run the command (Command Palette or editor right-click).
-- It follows the INCLUDE chain below and aligns the record tables in EVERY
-- reachable file in a single operation:
--
-- DECK_ALIGN.DATA (this file - WELSPECS table below)
-- +-- include/schedule.inc (WCONPROD / GCONPROD tables, via $INC alias)
-- +-- include/wells.inc (COMPDAT table, nested INCLUDE)
--
-- Every record table here is deliberately MIS-aligned so the effect of the
-- command is obvious. Running the command should leave each column lined up.
-- ---------------------------------------------------------------------------

RUNSPEC

DIMENS
10 10 3 /

OIL
WATER
GAS

-- PATHS alias used by the first INCLUDE below, to exercise alias resolution
-- while collecting the deck's include files.
PATHS
'INC' './include' /
/

GRID

DX
300*100 /

SCHEDULE

-- Misaligned record table in the ROOT file (should be aligned in place):
WELSPECS
'PROD1' 'G1' 1 1 1* 'OIL' /
'PROD2' 'G1' 10 10 1* 'OIL' /
'INJ1' 'G2' 5 5 1* 'WATER' /
/

-- INCLUDE via the $INC PATHS alias.
INCLUDE
'$INC/schedule.inc' /

END
23 changes: 23 additions & 0 deletions examples/deck-align/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Deck column-alignment example

A tiny, self-contained deck for exercising **OPM Flow: Align Record Columns in Deck**.

```
DECK_ALIGN.DATA root deck (WELSPECS table)
└─ include/schedule.inc WCONPROD / GCONPROD tables (INCLUDE via $INC alias)
└─ include/wells.inc COMPDAT table (nested INCLUDE)
```

## How to test

1. Open `DECK_ALIGN.DATA`.
2. Run **OPM Flow: Align Record Columns in Deck** (Command Palette or editor
right-click menu).
3. The command follows the `INCLUDE` chain — resolving the `$INC` `PATHS` alias
and the nested include — and aligns the record tables in all three files in a
single edit.

Every record table ships deliberately mis-aligned, so the effect is obvious. To
test the exclusion setting, add e.g. `"COMPDAT"` to
`opm-flow.formatting.alignColumnsExcludedKeywords` and confirm `wells.inc` is
left untouched.
17 changes: 17 additions & 0 deletions examples/deck-align/include/schedule.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Schedule include reached via the $INC PATHS alias from DECK_ALIGN.DATA.
-- Misaligned record tables below should be aligned by
-- "OPM Flow: Align Record Columns in Deck".

WCONPROD
'PROD1' 'OPEN' 'ORAT' 1000 4* 50 /
'PROD2' 'OPEN' 'ORAT' 800 4* 45 /
/

GCONPROD
'G1' 'ORAT' 5000 3* 'RATE' /
'G2' 'ORAT' 2500 3* 'RATE' /
/

-- Nested INCLUDE (relative to this file) - the collector recurses into it.
INCLUDE
'wells.inc' /
9 changes: 9 additions & 0 deletions examples/deck-align/include/wells.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Nested include reached from schedule.inc.
-- Misaligned COMPDAT table below should be aligned by
-- "OPM Flow: Align Record Columns in Deck".

COMPDAT
'PROD1' 1 1 1 1 'OPEN' 2* 0.5 /
'PROD2' 10 10 1 3 'OPEN' 2* 0.5 /
'INJ1' 5 5 1 2 'OPEN' 2* 0.5 /
/
39 changes: 33 additions & 6 deletions vscode-extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,15 @@ you can collapse whole sections at once or drill in one keyword at a time.

### Align Record Columns

Tidy up record blocks so every column lines up. Invoke **OPM Flow: Align Record Columns**
from the Command Palette or the editor right-click menu. With a selection it aligns only
the selected lines; without one it aligns the whole document.
Tidy up record blocks so every column lines up. Three levels are available from the
Command Palette or the editor right-click menu, depending on how much you want to touch:

- **OPM Flow: Align Record Columns in Record** — aligns only the record group under
the cursor.
- **OPM Flow: Align Record Columns in File** — aligns the whole current file, or just
the selected lines when there is a selection.
- **OPM Flow: Align Record Columns in Deck** — follows the `INCLUDE` chain and aligns
every reachable file (see below).

Groups of consecutive record lines (same token count) are reformatted in place:
strings left-aligned, integer columns right-aligned, and float columns aligned
Expand All @@ -229,8 +235,10 @@ up at the decimal point position). Keyword headers, comment lines, the closing
every data line above and below the comment is aligned against a single shared set
of column widths.

If a `--` comment line immediately precedes a record group, the columns are aligned
to the word positions in that comment, so the data lines up under the headings.
Comments are ignored when aligning: columns are positioned from the record data
alone, and any comment lines (whether above or within the group) are left exactly
as they are. A descriptive comment above a table is never mistaken for a column
heading.

Before:
```
Expand All @@ -252,13 +260,32 @@ MULTIPLY
/
```

#### Align across the whole deck

**OPM Flow: Align Record Columns in Deck** starts from the active document,
follows every `INCLUDE` (resolving `PATHS` aliases) recursively, and aligns the
record tables in all reachable files in one operation. It reports how many lines
and files were changed when it finishes.

When sweeping the whole deck, per-cell grid/region/solution arrays (`PORO`, `PERMX`,
`COORD`, `SATNUM`, …) and large tables (`VFPPROD`/`VFPINJ`) are skipped by default so
an `INCLUDE`d grid file is not silently rewritten and its deliberate fixed-width layout
is preserved. The **in Record** and **in File** commands do *not* apply these defaults —
when you align text you explicitly targeted, everything is aligned.

Add further keywords to skip via `opm-flow.formatting.alignColumnsExcludedKeywords`
(honoured by all three commands, and *added* to the deck defaults).

### Add Column Headers

Invoke **OPM Flow: Add Column Headers** from the Command Palette or the right-click menu
to insert a `--` comment above the record group with parameter names taken from the
keyword documentation, then align the records to those positions.

If a heading comment already exists it is updated in place. Running the command
Existing comments around the table are ignored, so a descriptive comment above the
data is never mistaken for a heading. If the line directly above the group is a
heading this command previously generated (its words are exactly the column names),
it is updated in place; otherwise a new heading line is inserted. Running the command
multiple times is idempotent.

Example — cursor anywhere inside the `VFPIDIMS` record:
Expand Down
35 changes: 31 additions & 4 deletions vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,17 @@
"command": "opm-flow.generateKeywordReference",
"title": "OPM Flow: Generate Keyword Reference"
},
{
"command": "opm-flow.alignRecordColumnsRecord",
"title": "OPM Flow: Align Record Columns in Record"
},
{
"command": "opm-flow.alignRecordColumns",
"title": "OPM Flow: Align Record Columns"
"title": "OPM Flow: Align Record Columns in File"
},
{
"command": "opm-flow.alignRecordColumnsInDeck",
"title": "OPM Flow: Align Record Columns in Deck"
},
{
"command": "opm-flow.addColumnHeaders",
Expand All @@ -158,20 +166,30 @@
"menus": {
"editor/context": [
{
"command": "opm-flow.alignRecordColumns",
"command": "opm-flow.alignRecordColumnsRecord",
"when": "resourceLangId == opm-flow",
"group": "opmflow_1_format@1"
},
{
"command": "opm-flow.addColumnHeaders",
"command": "opm-flow.alignRecordColumns",
"when": "resourceLangId == opm-flow",
"group": "opmflow_1_format@2"
},
{
"command": "opm-flow.toggleLineComment",
"command": "opm-flow.alignRecordColumnsInDeck",
"when": "resourceLangId == opm-flow",
"group": "opmflow_1_format@3"
},
{
"command": "opm-flow.addColumnHeaders",
"when": "resourceLangId == opm-flow",
"group": "opmflow_1_format@4"
},
{
"command": "opm-flow.toggleLineComment",
"when": "resourceLangId == opm-flow",
"group": "opmflow_1_format@5"
},
{
"command": "opm-flow.openPrtFile",
"when": "resourceLangId == opm-flow && resourceExtname =~ /^\\.data$/i",
Expand Down Expand Up @@ -322,6 +340,15 @@
"default": [],
"markdownDescription": "Extra arguments passed to flow by **Run Simulation** (e.g. `--output-dir=...`, `--threads-per-process=4`). The deck file is supplied automatically.",
"scope": "resource"
},
"opm-flow.formatting.alignColumnsExcludedKeywords": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"description": "Extra keywords whose record tables are skipped by the Align Record Columns commands. Names are matched case-insensitively. The whole-deck command additionally skips a built-in set of per-cell grid/region/solution arrays (PORO, PERMX, COORD, SATNUM, …) and large tables (VFPPROD/VFPINJ) so INCLUDE'd grid files keep their fixed-width layout; the keywords listed here are added to that set. The in-Record and in-File commands apply only the keywords listed here.",
"scope": "resource"
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions vscode-extension/src/align-exclusions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS } from './align-exclusions';

describe('DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS', () => {
const set = new Set(DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS);

it('excludes the common per-cell grid/region/solution array keywords', () => {
for (const kw of ['COORD', 'ZCORN', 'PORO', 'PERMX', 'PERMZ', 'NTG',
'SATNUM', 'FIPNUM', 'EQLNUM', 'ACTNUM', 'PRESSURE',
'VFPPROD', 'VFPINJ']) {
expect(set.has(kw)).toBe(true);
}
});

it('does NOT exclude genuine record-table keywords', () => {
// These are real record tables users do want aligned.
for (const kw of ['WELSPECS', 'COMPDAT', 'WCONPROD', 'GCONPROD',
'SWOF', 'SGOF', 'PVTO', 'PVTW', 'WELSEGS']) {
expect(set.has(kw)).toBe(false);
}
});

it('lists every keyword in upper case', () => {
for (const kw of DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS) {
expect(kw).toBe(kw.toUpperCase());
}
});

it('contains no duplicates', () => {
expect(set.size).toBe(DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS.length);
});
});
39 changes: 39 additions & 0 deletions vscode-extension/src/align-exclusions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ---------------------------------------------------------------------------
// Keywords whose record bodies are skipped by the column-alignment commands
// by default.
//
// "Align Record Columns" is meant for record *tables* — rows of a handful of
// fields, one record per line (WELSPECS, COMPDAT, WCONPROD, SWOF, PVTO, …).
// It is NOT useful on per-cell grid/region/solution arrays (PORO, PERMX,
// COORD, SATNUM, …) or on large structured tables (VFPPROD/VFPINJ): those are
// long streams of numbers that authors lay out in fixed-width columns on
// purpose, and collapsing them to single-space separation both destroys that
// layout and produces tens of thousands of edits when run across a full deck.
//
// These defaults ship with the extension and are merged with the user's
// `opm-flow.formatting.alignColumnsExcludedKeywords` setting (union). Names are
// compared in upper case.
// ---------------------------------------------------------------------------

export const DEFAULT_ALIGN_COLUMNS_EXCLUDED_KEYWORDS: readonly string[] = [
// --- GRID: geometry ---
'COORD', 'ZCORN', 'COORDSYS',
'DX', 'DY', 'DZ', 'DXV', 'DYV', 'DZV', 'DRV', 'DTHETAV',
'TOPS', 'DEPTHZ',
// --- GRID: cell properties ---
'PORO', 'PORV', 'MINPV', 'MINPVV',
'PERMX', 'PERMY', 'PERMZ', 'PERMR', 'PERMTHT', 'PERMXY', 'PERMYZ', 'PERMZX',
'NTG',
'MULTX', 'MULTY', 'MULTZ', 'MULTX-', 'MULTY-', 'MULTZ-', 'MULTPV',
'TRANX', 'TRANY', 'TRANZ',
// --- REGIONS: per-cell region numbers ---
'SATNUM', 'IMBNUM', 'PVTNUM', 'EQLNUM', 'FIPNUM', 'ROCKNUM', 'MULTNUM',
'OPERNUM', 'FLUXNUM', 'EOSNUM', 'MISCNUM', 'ENDNUM',
'KRNUMX', 'KRNUMY', 'KRNUMZ', 'IMBNUMX', 'IMBNUMY', 'IMBNUMZ',
'ACTNUM',
// --- SOLUTION: per-cell initial conditions ---
'PRESSURE', 'SWAT', 'SGAS', 'SOIL', 'RS', 'RV', 'RVW', 'PBUB', 'PDEW',
'TEMPI',
// --- Large structured tables ---
'VFPPROD', 'VFPINJ',
];
Loading