You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by mc...@apache.org on 2026/09/05 20:04:55 UTC

(hop) branch main updated: issue #2683 : Naming Scheme metadata (#7735)

This is an automated email from the ASF dual-hosted git repository.

mattcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new cffafa7bf7 issue #2683 : Naming Scheme metadata (#7735)
cffafa7bf7 is described below

commit cffafa7bf7b62045938c003c63656d72c9636c3e
Author: Matt Casters <ma...@gmail.com>
AuthorDate: Sat Sep 5 22:04:48 2026 +0200

    issue #2683 : Naming Scheme metadata (#7735)
    
    * issue #2683 : Naming Scheme metadata and TableView apply toolbar
    
    Add a Naming Scheme metadata type with a pure naming engine and a
    TableView toolbar action to normalize Hop field names (spaces to
    underscores/dashes, camelCase, PascalCase, etc.). Types for database
    tables/columns and files/folders are reserved for follow-up surfaces.
    
    * issue #2683 spotless
    
    * issue #2683 : apply naming schemes from name fields, plugin kinds, and hop naming-check
    
    Add CTRL-SHIFT-N and an N indicator on name widgets (binary-compatible Text siblings),
    a General scheme fallback, and Get Fields auto-apply.
    
    Promote naming-scheme kinds to a plugin type so plugins such as hop-data-vault can
    register dv-hub / dv-satellite / dm-dimension without changing Hop's enum. Annotate
    transform, action, pipeline, workflow, and stock metadata names. Validate by applying
    the matching scheme; fail when the string would change.
    
    hop naming-check is the CI surface (text/json, --require-scheme). Pipeline and
    workflow Verify report the same errors.
    
    * issue #2683 : complete naming scheme widgets for files, folders, and variables
    
    Bring the first version of Naming Schemes to a usable completeness pass:
    path-aware file/folder apply, annotated FILENAME/FOLDER widgets, space
    separator and capitalize-first-word, N-indicator dialog (create a scheme
    when none exists), and Save As / popular file and variable surfaces.
---
 assemblies/debug/pom.xml                           |   6 +
 assemblies/plugins/pom.xml                         |   6 +
 .../org/apache/hop/core/HopClientEnvironment.java  |   1 +
 .../hop/core/config/plugin/ConfigPlugin.java       |   1 +
 .../org/apache/hop/core/database/DatabaseMeta.java |   1 +
 .../hop/core/extension/HopExtensionPoint.java      |   1 +
 .../apache/hop/core/gui/plugin/GuiElements.java    |  35 +++
 .../hop/core/gui/plugin/GuiWidgetElement.java      |   8 +
 .../apache/hop/core/naming/INamingSchemeType.java  |  31 ++
 .../NamingSchemeKind.java}                         |  28 +-
 .../apache/hop/core/naming/NamingSchemeKinds.java  |  58 ++++
 .../NamingSchemeTypePlugin.java}                   |  20 +-
 .../core/naming/NamingSchemeTypePluginType.java    | 102 +++++++
 .../hop/metadata/api/HopMetadataProperty.java      |   7 +
 .../hop/metadata/api/HopMetadataPropertyType.java  |   3 +
 .../plugin/GuiElementsNamingSchemeTypeTest.java    |  78 +++++
 .../naming-scheme-csv-input-after.png              | Bin 0 -> 96500 bytes
 .../naming-scheme-csv-input-before.png             | Bin 0 -> 97812 bytes
 .../images/metadata-types/naming-scheme-editor.png | Bin 0 -> 81159 bytes
 .../naming-scheme-indicator-and-tooltip.png        | Bin 0 -> 41019 bytes
 .../metadata-types/naming-scheme-indicator.png     | Bin 0 -> 847 bytes
 docs/hop-user-manual/modules/ROOT/nav.adoc         |   1 +
 .../modules/ROOT/pages/hop-gui/shortcuts.adoc      |  14 +-
 .../modules/ROOT/pages/metadata-types/index.adoc   |   1 +
 .../ROOT/pages/metadata-types/naming-scheme.adoc   | 165 ++++++++++
 .../modules/ROOT/pages/protips/index.adoc          |   3 +
 .../java/org/apache/hop/core/HopEnvironment.java   |   1 +
 .../java/org/apache/hop/pipeline/PipelineMeta.java |   1 +
 .../hop/pipeline/transform/TransformMeta.java      |   4 +-
 .../java/org/apache/hop/server/HopServerMeta.java  |   1 +
 .../apache/hop/workflow/CheckActionsExtension.java |  48 +++
 .../java/org/apache/hop/workflow/WorkflowMeta.java |   7 +
 .../org/apache/hop/workflow/action/ActionBase.java |   4 +-
 .../ActionAddResultFilenamesDialog.java            |   5 +-
 .../columnsexist/ActionColumnsExistDialog.java     |   5 +-
 .../actions/copyfiles/ActionCopyFilesDialog.java   |   3 +
 .../ActionCopyMoveResultFilenamesDialog.java       |   5 +-
 .../actions/createfile/ActionCreateFileDialog.java |   5 +-
 .../createfolder/ActionCreateFolderDialog.java     |   5 +-
 .../actions/deletefile/ActionDeleteFileDialog.java |   5 +-
 .../deletefiles/ActionDeleteFilesDialog.java       |   2 +
 .../deletefolders/ActionDeleteFoldersDialog.java   |   2 +
 .../ActionEvalTableContentDialog.java              |   5 +-
 .../filecompare/ActionFileCompareDialog.java       |   9 +-
 .../actions/fileexists/ActionFileExistsDialog.java |   5 +-
 .../actions/filesexist/ActionFilesExistDialog.java |   2 +
 .../folderisempty/ActionFolderIsEmptyDialog.java   |   5 +-
 .../folderscompare/ActionFoldersCompareDialog.java |   9 +-
 .../workflow/actions/http/ActionHttpDialog.java    |   5 +-
 .../actions/movefiles/ActionMoveFilesDialog.java   |   5 +-
 .../setvariables/ActionSetVariablesDialog.java     |   6 +-
 .../tableexists/ActionTableExistsDialog.java       |   5 +-
 .../workflow/actions/unzip/ActionUnZipDialog.java  |   5 +-
 .../waitforfile/ActionWaitForFileDialog.java       |   5 +-
 .../actions/waitforsql/ActionWaitForSqlDialog.java |   5 +-
 .../writetofile/ActionWriteToFileDialog.java       |   5 +-
 .../actions/zipfile/ActionZipFileDialog.java       |   5 +-
 .../accessoutput/AccessOutputDialog.java           |   5 +-
 .../cratedbbulkloader/CrateDBBulkLoaderDialog.java |   5 +-
 .../dorisbulkloader/DorisBulkLoaderDialog.java     |   5 +-
 .../monetdbbulkloader/MonetDbBulkLoaderDialog.java |   5 +-
 .../mssqlbulkload/ActionMssqlBulkLoadDialog.java   |   9 +-
 .../mysqlbulkloader/MySqlBulkLoaderDialog.java     |   5 +-
 .../mysqlbulkfile/ActionMysqlBulkFileDialog.java   |   5 +-
 .../mysqlbulkload/ActionMysqlBulkLoadDialog.java   |   9 +-
 .../orabulkloader/OraBulkLoaderDialog.java         |   5 +-
 .../pgbulkloader/PGBulkLoaderDialog.java           |   5 +-
 .../bulkloader/SnowflakeBulkLoaderDialog.java      |   5 +-
 .../transforms/terafast/TeraFastDialog.java        |   2 +
 .../bulkloader/VerticaBulkLoaderDialog.java        |   5 +-
 .../hop/beam/metadata/FileDefinitionEditor.java    |   9 +-
 .../hop/spark/metadata/SparkCatalogEditor.java     |   9 +-
 .../spark/transforms/io/SparkFileInputDialog.java  |   9 +-
 .../spark/transforms/io/SparkFileOutputDialog.java |   9 +-
 .../hop/spark/transforms/sql/SparkSqlDialog.java   |   9 +-
 .../table/SparkLakeTableInputDialog.java           |   9 +-
 .../table/SparkLakeTableMaintenanceDialog.java     |  10 +-
 .../table/SparkLakeTableMergeDialog.java           |   9 +-
 .../table/SparkLakeTableOutputDialog.java          |   9 +-
 .../mail/metadata/MailServerConnectionEditor.java  |   8 +-
 .../actions/getpop/ActionGetPOPDialog.java         |   5 +-
 plugins/misc/{ => naming}/pom.xml                  |  28 +-
 plugins/misc/naming/src/assembly/assembly.xml      |  35 +++
 .../apache/hop/naming/command/HopNamingCheck.java  | 296 ++++++++++++++++++
 .../org/apache/hop/naming/engine/NamingEngine.java | 290 ++++++++++++++++++
 .../naming/engine/NamingSchemeCheckRemarks.java    |  85 ++++++
 .../hop/naming/engine/NamingSchemeValidator.java   |  95 ++++++
 .../hop/naming/engine/NamingSchemeWalker.java      | 191 ++++++++++++
 .../hop/naming/gui/NamingSchemeColumnApplier.java  |  96 ++++++
 .../gui/NamingSchemePipelineCheckExtension.java    |  50 +++
 .../hop/naming/gui/NamingSchemeShortcut.java       | 340 +++++++++++++++++++++
 .../gui/NamingSchemeWorkflowCheckExtension.java    |  48 +++
 .../naming/gui/TableViewNamingToolbarButton.java   | 194 ++++++++++++
 .../hop/naming/metadata/NamingCaseStyle.java       |  81 +++++
 .../apache/hop/naming/metadata/NamingScheme.java   | 262 ++++++++++++++++
 .../hop/naming/metadata/NamingSchemeEditor.java    | 253 +++++++++++++++
 .../hop/naming/metadata/NamingSchemeSelector.java  | 111 +++++++
 .../hop/naming/metadata/NamingSchemeType.java      | 160 ++++++++++
 .../hop/naming/metadata/NamingWordSeparator.java   |  86 ++++++
 .../hop/naming/type/BuiltinNamingSchemeType.java   |  37 +++
 .../hop/naming/type/NamingSchemeTypePlugins.java   |  64 ++++
 plugins/misc/naming/src/main/resources/naming.svg  |   6 +
 .../naming/gui/messages/messages_en_US.properties  |  31 ++
 .../metadata/messages/messages_en_US.properties    |  65 ++++
 .../apache/hop/naming/engine/NamingEngineTest.java | 212 +++++++++++++
 .../naming/engine/NamingSchemeValidatorTest.java   | 168 ++++++++++
 .../hop/naming/gui/NamingSchemeShortcutTest.java   |  96 ++++++
 .../naming/metadata/NamingSchemeSelectorTest.java  | 102 +++++++
 .../naming/type/BuiltinNamingSchemeTypeTest.java   |  39 +++
 plugins/misc/pom.xml                               |   1 +
 .../config/ProjectsNamingOptionPlugin.java         |  27 ++
 .../environment/LifecycleEnvironmentDialog.java    |   9 +-
 .../hop/projects/gui/ProjectConfigDialog.java      |  11 +-
 .../apache/hop/projects/project/ProjectDialog.java |  12 +-
 .../pipeline/meta/PipelineLogEditor.java           |   8 +-
 .../reflection/probe/meta/PipelineProbeEditor.java |   8 +-
 .../reflection/reader/meta/LogReaderEditor.java    |   9 +-
 .../workflow/meta/WorkflowLogEditor.java           |   8 +-
 .../hop/metadata/rest/RestConnectionEditor.java    |   7 +-
 .../metadata/SchemaDefinitionEditor.java           |   9 +-
 .../datasetinput/DataSetInputDialog.java           |   8 +-
 .../org/apache/hop/ui/testing/DataSetEditor.java   |   7 +-
 .../hop/ui/testing/PipelineUnitTestEditor.java     |   7 +-
 .../transforms/avrodecode/AvroDecodeDialog.java    |   2 +
 .../transforms/avrooutput/AvroOutputDialog.java    |   5 +-
 .../bulkloader/RedshiftBulkLoaderDialog.java       |   5 +-
 .../apache/hop/vfs/s3/metadata/S3MetaEditor.java   |   8 +-
 .../metadatatype/AzureMetadataTypeEditor.java      |   7 +-
 .../metadata/CassandraConnectionEditor.java        |   9 +-
 .../SSTableOutputDialog.java                       |   5 +-
 .../metadata/DatabricksConnectionEditor.java       |   9 +-
 .../metadata/DatabricksVfsConnectionEditor.java    |   9 +-
 .../databricks/ActionDatabricksJobRunDialog.java   |   8 +-
 .../databricks/ActionDatabricksJobWaitDialog.java  |   8 +-
 .../hop/vfs/ftp/metadata/FtpConnectionEditor.java  |   7 +-
 .../GoogleStorageMetadataTypeEditor.java           |   7 +-
 .../hop/vfs/minio/metadata/MinioMetaEditor.java    |   9 +-
 .../mongo/metadata/MongoDbConnectionEditor.java    |   9 +-
 .../mongodbinput/MongoDbInputDialog.java           |   2 +
 .../hop/workflow/actions/mql/ActionMqlDialog.java  |   8 +-
 .../apache/hop/neo4j/model/GraphModelEditor.java   |   8 +-
 .../hop/neo4j/shared/NeoConnectionEditor.java      |   8 +-
 .../transforms/input/ParquetInputDialog.java       |   6 +-
 .../transforms/output/ParquetOutputDialog.java     |   6 +-
 .../hop/redis/metadata/RedisConnectionEditor.java  |   9 +-
 .../salesforce/SalesforceConnectionEditor.java     |   7 +-
 .../salesforceinput/SalesforceInputDialog.java     |   2 +
 .../vfs/sftp/metadata/SftpConnectionEditor.java    |   7 +-
 .../webdav/metadata/WebDavConnectionEditor.java    |   7 +-
 .../transforms/addsequence/AddSequenceDialog.java  |   7 +-
 .../analyticquery/AnalyticQueryDialog.java         |   2 +
 .../transforms/calculator/CalculatorDialog.java    |   2 +
 .../columnexists/ColumnExistsDialog.java           |   5 +-
 .../combinationlookup/CombinationLookupDialog.java |  22 +-
 .../concatfields/ConcatFieldsDialog.java           |   5 +-
 .../transforms/constant/ConstantDialog.java        |   2 +
 .../databaselookup/DatabaseLookupDialog.java       |  10 +-
 .../transforms/datagrid/DataGridDialog.java        |   2 +
 .../pipeline/transforms/delete/DeleteDialog.java   |  10 +-
 .../detectlastrow/DetectLastRowDialog.java         |   5 +-
 .../dimensionlookup/DimensionLookupDialog.java     |  22 +-
 .../transforms/excelinput/ExcelInputDialog.java    |   6 +
 .../excelwriter/ExcelWriterTransformDialog.java    |   5 +-
 .../transforms/flattener/FlattenerDialog.java      |   2 +
 .../pipeline/transforms/formula/FormulaDialog.java |   2 +
 .../getfilenames/GetFileNamesDialog.java           |   5 +-
 .../gettablenames/GetTableNamesDialog.java         |   7 +-
 .../transforms/getvariable/GetVariableDialog.java  |   2 +
 .../pipeline/transforms/groupby/GroupByDialog.java |   2 +
 .../insertupdate/InsertUpdateDialog.java           |  11 +-
 .../pipeline/transforms/janino/JaninoDialog.java   |   2 +
 .../UserDefinedJavaClassDialog.java                |   2 +
 .../transforms/javascript/ScriptValuesDialog.java  |   3 +
 .../transforms/jms/consumer/JmsConsumerDialog.java |  10 +-
 .../transforms/jms/producer/JmsProducerDialog.java |  10 +-
 .../transforms/jms/shared/JmsConnectionEditor.java |   8 +-
 .../transforms/jsoninput/JsonInputDialog.java      |   6 +-
 .../transforms/jsonoutput/JsonOutputDialog.java    |   5 +-
 .../internals/ui/TransformNameComposite.java       |  11 +-
 .../transforms/input/MappingInputDialog.java       |   2 +
 .../transforms/memgroupby/MemoryGroupByDialog.java |   2 +
 .../transforms/normaliser/NormaliserDialog.java    |   2 +
 .../transforms/odata/ODataInputDialog.java         |  10 +-
 .../transforms/randomvalue/RandomValueDialog.java  |   2 +
 .../transforms/regexeval/RegexEvalDialog.java      |   2 +
 .../replacestring/ReplaceStringDialog.java         |   2 +
 .../rowgenerator/RowGeneratorDialog.java           |   2 +
 .../selectvalues/SelectValuesDialog.java           |   3 +
 .../transforms/setvariable/SetVariableDialog.java  |   2 +
 .../splitfieldtorows/SplitFieldToRowsDialog.java   |   5 +-
 .../apache/hop/splunk/SplunkConnectionEditor.java  |   8 +-
 .../sqlfileoutput/SQLFileOutputDialog.java         |   9 +-
 .../streamlookup/StreamLookupDialog.java           |   2 +
 .../transforms/stringcut/StringCutDialog.java      |   2 +
 .../SynchronizeAfterMergeDialog.java               |   7 +-
 .../transforms/systemdata/SystemDataDialog.java    |   2 +
 .../transforms/tableoutput/TableOutputDialog.java  |  10 +-
 .../transforms/csvinput/CsvInputDialog.java        |  48 ++-
 .../pipeline/transforms/csvinput/CsvInputMeta.java |   9 +
 .../fileinput/text/TextFileInputDialog.java        |  48 ++-
 .../fileinput/text/TextFileInputMeta.java          |   9 +
 .../textfileoutput/TextFileOutputDialog.java       |   5 +-
 .../csvinput/messages/messages_en_US.properties    |   2 +
 .../text/messages/messages_en_US.properties        |   2 +
 .../hop/pipeline/transforms/tika/TikaDialog.java   |   5 +-
 .../pipeline/transforms/update/UpdateDialog.java   |  11 +-
 .../transforms/valuemapper/ValueMapperDialog.java  |   8 +-
 .../xml/getxmldata/GetXmlDataDialog.java           |   6 +-
 .../transforms/xml/xmloutput/XmlOutputDialog.java  |   6 +-
 .../transforms/yamlinput/YamlInputDialog.java      |   6 +-
 .../hop/ui/core/database/DatabaseMetaEditor.java   |   8 +-
 .../core/dialog/HopDescribedVariablesDialog.java   |   2 +
 .../hop/ui/core/gui/GuiCompositeWidgets.java       |  28 +-
 .../org/apache/hop/ui/core/gui/GuiResource.java    |  15 +
 .../hop/ui/core/metadata/MetadataEditor.java       |  38 +++
 .../hop/ui/core/metadata/MetadataManager.java      |  18 +-
 .../variables/resolver/VariableResolverEditor.java |   8 +-
 .../apache/hop/ui/core/vfs/HopVfsFileDialog.java   |  15 +-
 .../org/apache/hop/ui/core/widget/ColumnInfo.java  |   6 +
 .../org/apache/hop/ui/core/widget/ComboVar.java    | 137 ++++++++-
 .../ui/core/widget/INamingSchemeColumnApplier.java |  37 +++
 .../hop/ui/core/widget/ITextWidgetShortcut.java    |  43 +++
 .../apache/hop/ui/core/widget/LabelComboVar.java   |  10 +
 .../apache/hop/ui/core/widget/LabelTextVar.java    |  10 +
 .../hop/ui/core/widget/MetaSelectionLine.java      |  32 ++
 .../widget/NamingSchemeColumnApplierRegistry.java  |  70 +++++
 .../hop/ui/core/widget/NamingSchemeTypes.java      |  43 +++
 .../ui/core/widget/NamingSchemeWidgetSupport.java  | 104 +++++++
 .../org/apache/hop/ui/core/widget/TableView.java   | 162 +++++++++-
 .../org/apache/hop/ui/core/widget/TextVar.java     | 172 ++++++++++-
 .../apache/hop/ui/core/widget/TextVarButton.java   |  25 +-
 .../ui/core/widget/TextWidgetShortcutContext.java  |  46 +++
 .../core/widget/TextWidgetShortcutKeyAdapter.java  |  90 ++++++
 .../ui/core/widget/TextWidgetShortcutRegistry.java |  57 ++++
 .../datastream/metadata/DataStreamMetaEditor.java  |   8 +-
 .../ui/execution/ExecutionInfoLocationEditor.java  |   8 +-
 .../profiling/ExecutionDataProfileEditor.java      |   8 +-
 .../perspective/explorer/ExplorerPerspective.java  |   6 +
 .../perspective/metadata/MetadataPerspective.java  |   4 +
 .../hop/ui/partition/PartitionSchemaEditor.java    |   8 +-
 .../config/PipelineRunConfigurationEditor.java     |  24 +-
 .../hop/ui/pipeline/dialog/PipelineDialog.java     |   8 +-
 .../ui/pipeline/transform/BaseTransformDialog.java |  35 ++-
 .../common/IGetFieldsCapableTransformDialog.java   |  14 +
 .../transforms/injector/InjectorDialog.java        |  12 +-
 .../apache/hop/ui/server/HopServerMetaEditor.java  |   8 +-
 .../hop/ui/workflow/action/ActionDialog.java       |  32 +-
 .../hop/ui/workflow/actions/ActionBaseDialog.java  |   6 +-
 .../config/WorkflowRunConfigurationEditor.java     |  24 +-
 .../hop/ui/workflow/dialog/WorkflowDialog.java     |   9 +-
 .../hop/ui/www/async/AsyncWebServiceEditor.java    |   8 +-
 .../hop/ui/www/service/WebServiceEditor.java       |   8 +-
 .../core/widget/messages/messages_en_US.properties |   1 +
 ui/src/main/resources/ui/images/naming.svg         |   8 +
 .../widget/TextWidgetShortcutRegistryTest.java     |  56 ++++
 .../BaseTransformDialogBinaryCompatTest.java       |  44 +++
 256 files changed, 6287 insertions(+), 408 deletions(-)

diff --git a/assemblies/debug/pom.xml b/assemblies/debug/pom.xml
index d87ba26f14..681a4451f3 100644
--- a/assemblies/debug/pom.xml
+++ b/assemblies/debug/pom.xml
@@ -361,6 +361,12 @@
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.hop</groupId>
+            <artifactId>hop-misc-naming</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>org.apache.hop</groupId>
             <artifactId>hop-misc-projects</artifactId>
diff --git a/assemblies/plugins/pom.xml b/assemblies/plugins/pom.xml
index 977fcfedf3..3b815f5aa6 100644
--- a/assemblies/plugins/pom.xml
+++ b/assemblies/plugins/pom.xml
@@ -654,6 +654,12 @@
             <version>${project.version}</version>
             <type>zip</type>
         </dependency>
+        <dependency>
+            <groupId>org.apache.hop</groupId>
+            <artifactId>hop-misc-naming</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
         <dependency>
             <groupId>org.apache.hop</groupId>
             <artifactId>hop-misc-passwords</artifactId>
diff --git a/core/src/main/java/org/apache/hop/core/HopClientEnvironment.java b/core/src/main/java/org/apache/hop/core/HopClientEnvironment.java
index 57f9fa0755..586634e9c8 100644
--- a/core/src/main/java/org/apache/hop/core/HopClientEnvironment.java
+++ b/core/src/main/java/org/apache/hop/core/HopClientEnvironment.java
@@ -79,6 +79,7 @@ public class HopClientEnvironment {
     init(
         List.of(
             LoggingPluginType.getInstance(),
+            org.apache.hop.core.naming.NamingSchemeTypePluginType.getInstance(),
             ValueMetaPluginType.getInstance(),
             DatabasePluginType.getInstance(),
             DatabaseTypeRulesPluginType.getInstance(),
diff --git a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java b/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
index 494358994a..a20bd8d808 100644
--- a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
+++ b/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
@@ -35,6 +35,7 @@ public @interface ConfigPlugin {
   String CATEGORY_SERVER = "server";
   String CATEGORY_DOC = "doc";
   String CATEGORY_PYTHON = "python";
+  String CATEGORY_NAMING = "naming";
 
   String id();
 
diff --git a/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java b/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
index 51c8903d14..6c1d0a4347 100644
--- a/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
+++ b/core/src/main/java/org/apache/hop/core/database/DatabaseMeta.java
@@ -72,6 +72,7 @@ import org.apache.hop.metadata.api.IHopMetadataProvider;
     documentationUrl = "/metadata-types/rdbms-connection.html",
     hopMetadataPropertyType = HopMetadataPropertyType.RDBMS_CONNECTION,
     supportsGlobalReplace = true)
+@org.apache.hop.core.naming.NamingSchemeKind("hop-metadata")
 public class DatabaseMeta extends HopMetadataBase implements Cloneable, IHopMetadata {
   private static final Class<?> PKG = Database.class;
 
diff --git a/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java b/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java
index 2fe5e9de5b..8a6271b4ae 100644
--- a/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java
+++ b/core/src/main/java/org/apache/hop/core/extension/HopExtensionPoint.java
@@ -105,6 +105,7 @@ public enum HopExtensionPoint {
   AfterCheckTransforms("After a set of transforms has been checked for warnings/errors."),
   BeforeCheckTransform("Right before a transform is about to be verified."),
   AfterCheckTransform("After a transform has been checked for warnings/errors."),
+  AfterCheckActions("After a set of workflow actions has been checked for warnings/errors."),
 
   HopServerInit("Right before the Hop server starts"),
   HopServerStartup("Right after the Hop server has started and is fully functional"),
diff --git a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiElements.java b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiElements.java
index abcd042192..b9e0877963 100644
--- a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiElements.java
+++ b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiElements.java
@@ -24,7 +24,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.naming.NamingSchemeKinds;
 import org.apache.hop.core.util.StringUtil;
+import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.IHopMetadata;
 
 /** This represents a list of GUI elements under a certain heading or ID */
@@ -84,6 +86,8 @@ public class GuiElements extends BaseGuiElements implements Comparable<GuiElemen
   private String groupImage;
   private GuiWidgetGroupType groupType;
 
+  private String namingSchemeType;
+
   public GuiElements() {
     children = new ArrayList<>();
     groupType = GuiWidgetGroupType.NONE;
@@ -122,6 +126,7 @@ public class GuiElements extends BaseGuiElements implements Comparable<GuiElemen
     this.typeFilename = guiElement.typeFilename();
     this.metadata = guiElement.metadata();
     this.buttonMethod = null;
+    this.namingSchemeType = resolveNamingSchemeType(guiElement, field);
     copyGroup(guiElement, fieldPackageName, field.getDeclaringClass());
   }
 
@@ -164,9 +169,31 @@ public class GuiElements extends BaseGuiElements implements Comparable<GuiElemen
     this.metadata = guiElement.metadata();
     this.classLoader = classLoader;
     this.buttonMethod = method;
+    this.namingSchemeType = resolveNamingSchemeType(guiElement, null);
     copyGroup(guiElement, methodPackageName, method.getDeclaringClass());
   }
 
+  static String resolveNamingSchemeType(GuiWidgetElement guiElement, Field field) {
+    if (guiElement != null && StringUtils.isNotEmpty(guiElement.namingSchemeType())) {
+      return guiElement.namingSchemeType();
+    }
+    if (field != null) {
+      HopMetadataProperty property = field.getAnnotation(HopMetadataProperty.class);
+      if (property != null && StringUtils.isNotEmpty(property.namingSchemeType())) {
+        return property.namingSchemeType();
+      }
+    }
+    if (guiElement != null) {
+      if (guiElement.type() == GuiElementType.FILENAME) {
+        return NamingSchemeKinds.FILE;
+      }
+      if (guiElement.type() == GuiElementType.FOLDER) {
+        return NamingSchemeKinds.FOLDER;
+      }
+    }
+    return "";
+  }
+
   private void copyGroup(GuiWidgetElement guiElement, String i18nPackage, Class<?> resourceClass) {
     this.group = getTranslation(guiElement.group(), i18nPackage, resourceClass);
     this.groupOrder = guiElement.groupOrder();
@@ -667,4 +694,12 @@ public class GuiElements extends BaseGuiElements implements Comparable<GuiElemen
   public boolean hasGroup() {
     return StringUtils.isNotEmpty(group);
   }
+
+  public String getNamingSchemeType() {
+    return namingSchemeType;
+  }
+
+  public void setNamingSchemeType(String namingSchemeType) {
+    this.namingSchemeType = namingSchemeType;
+  }
 }
diff --git a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiWidgetElement.java b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiWidgetElement.java
index 15bf4ed8e7..7aff598edb 100644
--- a/core/src/main/java/org/apache/hop/core/gui/plugin/GuiWidgetElement.java
+++ b/core/src/main/java/org/apache/hop/core/gui/plugin/GuiWidgetElement.java
@@ -145,6 +145,14 @@ public @interface GuiWidgetElement {
    */
   Class<? extends IHopMetadata> metadata() default IHopMetadata.class;
 
+  /**
+   * Optional naming-scheme type code for this widget ({@code file}, {@code folder}, {@code
+   * hop-variable}, …). Empty means: infer {@code file}/{@code folder} from {@link
+   * GuiElementType#FILENAME}/{@link GuiElementType#FOLDER}, otherwise the widget is not a name
+   * field. Does not replace {@link #type()}.
+   */
+  String namingSchemeType() default "";
+
   /**
    * Layout bucket inside the {@link #parentId()} tree. Empty (the default) keeps the widget on the
    * flat form. When any sibling has a group, widgets are shown in that container ({@link
diff --git a/core/src/main/java/org/apache/hop/core/naming/INamingSchemeType.java b/core/src/main/java/org/apache/hop/core/naming/INamingSchemeType.java
new file mode 100644
index 0000000000..40ca185c0d
--- /dev/null
+++ b/core/src/main/java/org/apache/hop/core/naming/INamingSchemeType.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.core.naming;
+
+/**
+ * A kind of identifier that a {@code NamingScheme} can target (Hop field, transform, Data Vault
+ * hub, …). Implemented as a plugin so other plugins can add kinds without changing Hop core.
+ */
+public interface INamingSchemeType {
+
+  /** Stable code stored on schemes and annotations ({@code hop-field}, {@code dv-hub}). */
+  String getCode();
+
+  /** Human-readable label for combo boxes. */
+  String getName();
+}
diff --git a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeKind.java
similarity index 61%
copy from core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
copy to core/src/main/java/org/apache/hop/core/naming/NamingSchemeKind.java
index 494358994a..27ce7f1a15 100644
--- a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
+++ b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeKind.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *       http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,30 +15,22 @@
  * limitations under the License.
  */
 
-package org.apache.hop.core.config.plugin;
+package org.apache.hop.core.naming;
 
-import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-/** This annotation signals to the plugin system that the class is a configuration plugin. */
-@Documented
+/**
+ * Declares the naming-scheme kind of this type's identity {@code name} (including an inherited
+ * {@code HopMetadataBase.name}). Field-level {@code @HopMetadataProperty(namingSchemeType=...)}
+ * wins when both are present.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
-public @interface ConfigPlugin {
-  String CATEGORY_CONFIG = "config";
-  String CATEGORY_RUN = "run";
-  String CATEGORY_SEARCH = "search";
-  String CATEGORY_IMPORT = "import";
-  String CATEGORY_SERVER = "server";
-  String CATEGORY_DOC = "doc";
-  String CATEGORY_PYTHON = "python";
-
-  String id();
-
-  String description() default "";
+public @interface NamingSchemeKind {
 
-  String category() default CATEGORY_CONFIG;
+  /** Type code such as {@code hop-transform} or {@code dv-hub}. */
+  String value();
 }
diff --git a/core/src/main/java/org/apache/hop/core/naming/NamingSchemeKinds.java b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeKinds.java
new file mode 100644
index 0000000000..92d58308f9
--- /dev/null
+++ b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeKinds.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.core.naming;
+
+import org.apache.commons.lang3.StringUtils;
+
+/** Helpers for {@link NamingSchemeKind} and field-level naming type codes. */
+public final class NamingSchemeKinds {
+
+  public static final String FILE = "file";
+  public static final String FOLDER = "folder";
+
+  private NamingSchemeKinds() {
+    // utility
+  }
+
+  public static boolean isFile(String kind) {
+    return FILE.equalsIgnoreCase(kind);
+  }
+
+  public static boolean isFolder(String kind) {
+    return FOLDER.equalsIgnoreCase(kind);
+  }
+
+  /**
+   * @param type a class (may be null)
+   * @return the first {@link NamingSchemeKind} on the class or a superclass, or null
+   */
+  public static String kindOf(Class<?> type) {
+    if (type == null) {
+      return null;
+    }
+    Class<?> cursor = type;
+    while (cursor != null && cursor != Object.class) {
+      NamingSchemeKind kind = cursor.getAnnotation(NamingSchemeKind.class);
+      if (kind != null && StringUtils.isNotEmpty(kind.value())) {
+        return kind.value();
+      }
+      cursor = cursor.getSuperclass();
+    }
+    return null;
+  }
+}
diff --git a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePlugin.java
similarity index 67%
copy from core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
copy to core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePlugin.java
index 494358994a..0522ccd0e6 100644
--- a/core/src/main/java/org/apache/hop/core/config/plugin/ConfigPlugin.java
+++ b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePlugin.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *       http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.hop.core.config.plugin;
+package org.apache.hop.core.naming;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -23,22 +23,16 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-/** This annotation signals to the plugin system that the class is a configuration plugin. */
+/** Marks an {@link INamingSchemeType} implementation for the plugin registry. */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
-public @interface ConfigPlugin {
-  String CATEGORY_CONFIG = "config";
-  String CATEGORY_RUN = "run";
-  String CATEGORY_SEARCH = "search";
-  String CATEGORY_IMPORT = "import";
-  String CATEGORY_SERVER = "server";
-  String CATEGORY_DOC = "doc";
-  String CATEGORY_PYTHON = "python";
+public @interface NamingSchemeTypePlugin {
 
+  /** Plugin id and type code (for example {@code hop-field} or {@code dv-hub}). */
   String id();
 
-  String description() default "";
+  String name();
 
-  String category() default CATEGORY_CONFIG;
+  String description() default "";
 }
diff --git a/core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePluginType.java b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePluginType.java
new file mode 100644
index 0000000000..8fd8f08fd1
--- /dev/null
+++ b/core/src/main/java/org/apache/hop/core/naming/NamingSchemeTypePluginType.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.core.naming;
+
+import java.util.Map;
+import org.apache.hop.core.plugins.BasePluginType;
+import org.apache.hop.core.plugins.PluginAnnotationType;
+import org.apache.hop.core.plugins.PluginMainClassType;
+
+@PluginMainClassType(INamingSchemeType.class)
+@PluginAnnotationType(NamingSchemeTypePlugin.class)
+public class NamingSchemeTypePluginType extends BasePluginType<NamingSchemeTypePlugin> {
+
+  private static NamingSchemeTypePluginType pluginType;
+
+  private NamingSchemeTypePluginType() {
+    super(NamingSchemeTypePlugin.class, "NAMING_SCHEME_TYPE", "NamingSchemeType");
+  }
+
+  public static NamingSchemeTypePluginType getInstance() {
+    if (pluginType == null) {
+      pluginType = new NamingSchemeTypePluginType();
+    }
+    return pluginType;
+  }
+
+  @Override
+  protected String extractCategory(NamingSchemeTypePlugin annotation) {
+    return "";
+  }
+
+  @Override
+  protected String extractID(NamingSchemeTypePlugin annotation) {
+    return annotation.id();
+  }
+
+  @Override
+  protected String extractName(NamingSchemeTypePlugin annotation) {
+    return annotation.name();
+  }
+
+  @Override
+  protected String extractDesc(NamingSchemeTypePlugin annotation) {
+    return annotation.description();
+  }
+
+  @Override
+  protected String extractImageFile(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+
+  @Override
+  protected boolean extractSeparateClassLoader(NamingSchemeTypePlugin annotation) {
+    return false;
+  }
+
+  @Override
+  protected void addExtraClasses(
+      Map<Class<?>, String> classMap, Class<?> clazz, NamingSchemeTypePlugin annotation) {
+    // Do nothing
+  }
+
+  @Override
+  protected String extractDocumentationUrl(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+
+  @Override
+  protected String extractCasesUrl(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+
+  @Override
+  protected String extractForumUrl(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+
+  @Override
+  protected String extractSuggestion(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+
+  @Override
+  protected String extractClassLoaderGroup(NamingSchemeTypePlugin annotation) {
+    return null;
+  }
+}
diff --git a/core/src/main/java/org/apache/hop/metadata/api/HopMetadataProperty.java b/core/src/main/java/org/apache/hop/metadata/api/HopMetadataProperty.java
index 469ccb0524..ee086e720e 100644
--- a/core/src/main/java/org/apache/hop/metadata/api/HopMetadataProperty.java
+++ b/core/src/main/java/org/apache/hop/metadata/api/HopMetadataProperty.java
@@ -169,6 +169,13 @@ public @interface HopMetadataProperty {
    */
   HopMetadataPropertyType hopMetadataPropertyType() default HopMetadataPropertyType.NONE;
 
+  /**
+   * Optional naming-scheme type code for this String field ({@code hop-field}, {@code
+   * hop-transform}, {@code dv-hub}, …). Empty means the field is not a name to validate. Does not
+   * replace {@link #hopMetadataPropertyType()}.
+   */
+  String namingSchemeType() default "";
+
   /**
    * When serializing common objects sometimes we don't want to serialize every field. In this
    * scenario you can specify the fields to serialize.
diff --git a/core/src/main/java/org/apache/hop/metadata/api/HopMetadataPropertyType.java b/core/src/main/java/org/apache/hop/metadata/api/HopMetadataPropertyType.java
index feb5234b69..a9cd6a1953 100644
--- a/core/src/main/java/org/apache/hop/metadata/api/HopMetadataPropertyType.java
+++ b/core/src/main/java/org/apache/hop/metadata/api/HopMetadataPropertyType.java
@@ -106,6 +106,9 @@ public enum HopMetadataPropertyType {
   // STATIC SCHEMA
   STATIC_SCHEMA_DEFINITION,
 
+  // NAMING
+  NAMING_SCHEME,
+
   // VFS
   VFS_GCP_CONNECTION,
   VFS_AZURE_CONNECTION,
diff --git a/core/src/test/java/org/apache/hop/core/gui/plugin/GuiElementsNamingSchemeTypeTest.java b/core/src/test/java/org/apache/hop/core/gui/plugin/GuiElementsNamingSchemeTypeTest.java
new file mode 100644
index 0000000000..336c81bd9c
--- /dev/null
+++ b/core/src/test/java/org/apache/hop/core/gui/plugin/GuiElementsNamingSchemeTypeTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.core.gui.plugin;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.lang.reflect.Field;
+import org.apache.hop.core.naming.NamingSchemeKinds;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+import org.junit.jupiter.api.Test;
+
+class GuiElementsNamingSchemeTypeTest {
+
+  static class Sample {
+    @GuiWidgetElement(id = "file", type = GuiElementType.FILENAME, parentId = "p", label = "File")
+    String file;
+
+    @GuiWidgetElement(id = "folder", type = GuiElementType.FOLDER, parentId = "p", label = "Folder")
+    String folder;
+
+    @GuiWidgetElement(
+        id = "explicit",
+        type = GuiElementType.TEXT,
+        parentId = "p",
+        label = "Var",
+        namingSchemeType = "hop-variable")
+    String explicit;
+
+    @GuiWidgetElement(id = "fromMeta", type = GuiElementType.TEXT, parentId = "p", label = "Meta")
+    @HopMetadataProperty(namingSchemeType = "hop-field")
+    String fromMeta;
+
+    @GuiWidgetElement(id = "plain", type = GuiElementType.TEXT, parentId = "p", label = "Plain")
+    String plain;
+  }
+
+  @Test
+  void infersFileAndFolderFromElementType() throws Exception {
+    assertEquals(NamingSchemeKinds.FILE, elements("file").getNamingSchemeType());
+    assertEquals(NamingSchemeKinds.FOLDER, elements("folder").getNamingSchemeType());
+  }
+
+  @Test
+  void explicitAnnotationWins() throws Exception {
+    assertEquals("hop-variable", elements("explicit").getNamingSchemeType());
+  }
+
+  @Test
+  void copiesFromHopMetadataProperty() throws Exception {
+    assertEquals("hop-field", elements("fromMeta").getNamingSchemeType());
+  }
+
+  @Test
+  void plainTextIsNotANameField() throws Exception {
+    assertEquals("", elements("plain").getNamingSchemeType());
+  }
+
+  private static GuiElements elements(String fieldName) throws Exception {
+    Field field = Sample.class.getDeclaredField(fieldName);
+    GuiWidgetElement annotation = field.getAnnotation(GuiWidgetElement.class);
+    return new GuiElements(annotation, field);
+  }
+}
diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-after.png b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-after.png
new file mode 100644
index 0000000000..a5fbdbc0cc
Binary files /dev/null and b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-after.png differ
diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-before.png b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-before.png
new file mode 100644
index 0000000000..e7013eb85d
Binary files /dev/null and b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-csv-input-before.png differ
diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-editor.png b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-editor.png
new file mode 100644
index 0000000000..54f90eedb2
Binary files /dev/null and b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-editor.png differ
diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator-and-tooltip.png b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator-and-tooltip.png
new file mode 100644
index 0000000000..9c79417fca
Binary files /dev/null and b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator-and-tooltip.png differ
diff --git a/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator.png b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator.png
new file mode 100644
index 0000000000..b33d024826
Binary files /dev/null and b/docs/hop-user-manual/modules/ROOT/assets/images/metadata-types/naming-scheme-indicator.png differ
diff --git a/docs/hop-user-manual/modules/ROOT/nav.adoc b/docs/hop-user-manual/modules/ROOT/nav.adoc
index 494256b995..a5c3b57ce9 100644
--- a/docs/hop-user-manual/modules/ROOT/nav.adoc
+++ b/docs/hop-user-manual/modules/ROOT/nav.adoc
@@ -525,6 +525,7 @@ under the License.
 *** xref:metadata-types/variable-resolver/openbao-variable-resolver.adoc[OpenBAO variable resolver]
 *** xref:metadata-types/variable-resolver/pipeline-variable-resolver.adoc[Pipeline variable resolver]
 ** xref:metadata-types/static-schema-definition.adoc[Static Schema Definition]
+** xref:metadata-types/naming-scheme.adoc[Naming Scheme]
 ** xref:hop-server/web-service.adoc[Web Service]
 ** xref:metadata-types/webdav-connection.adoc[WebDAV Connection]
 ** xref:metadata-types/workflow-log.adoc[Workflow Log]
diff --git a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/shortcuts.adoc b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/shortcuts.adoc
index a41adcf959..52bad2eeff 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/hop-gui/shortcuts.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/hop-gui/shortcuts.adoc
@@ -20,4 +20,16 @@ under the License.
 
 = Hop Shortcuts
 
-Shortcuts can now be found inside the application itself, In the setting perspective there is a tab named Keyboard Shortcuts that will give you an overview of the shortcuts and where to use them.
+Most shortcuts can be found inside the application itself. In the Settings perspective there is a tab named Keyboard Shortcuts that lists global chords and where to use them.
+
+Widget-local shortcuts (they apply to the focused field, not the whole window) are not listed there:
+
+[options="header"]
+|===
+|Shortcut|Where|What it does
+|`CTRL-SPACE`|`TextVar` / `ComboVar` that accept variables|Insert a `${variable}`
+|`CTRL-SPACE`|Name fields that do *not* accept variables (transform/action/metadata names)|Apply a xref:metadata-types/naming-scheme.adoc[Naming Scheme] of the matching type
+|`CTRL-SHIFT-N`|Any name field, field-name cell, table name, file/folder field, or F2 tree rename|List and apply a Naming Scheme. Replaces the current identifier (values that contain `${...}` are left unchanged)
+|===
+
+See xref:metadata-types/naming-scheme.adoc[Naming Scheme] for the *N* indicator, types, and the TableView bulk toolbar.
diff --git a/docs/hop-user-manual/modules/ROOT/pages/metadata-types/index.adoc b/docs/hop-user-manual/modules/ROOT/pages/metadata-types/index.adoc
index 1225ff7ca8..fb05c35040 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/metadata-types/index.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/metadata-types/index.adoc
@@ -51,6 +51,7 @@ xref:metadata-types/data-stream/data-stream.adoc[Data Stream]: A Data Stream can
 * xref:metadata-types/mongodb-connection.adoc[MongoDB Connection]: Describes a MongoDB connection
 * xref:metadata-types/mail-server-connection.adoc[Mail Server Connection]: Describes a mail server connection
 * xref:metadata-types/minio-connection.adoc[Minio (S3) Connection]: Connect to one or more S3 endpoints using a Minio client
+* xref:metadata-types/naming-scheme.adoc[Naming Scheme]: Reusable rules to normalize Hop field names, database identifiers, and file or folder names
 * xref:metadata-types/webdav-connection.adoc[WebDAV Connection]: Named WebDAV or WebDAV-over-HTTPS endpoint used as a VFS scheme in file paths
 * xref:metadata-types/neo4j/neo4j-connection.adoc[Neo4j Connection]: A shared connection to a Neo4j server
 * xref:metadata-types/neo4j/neo4j-graphmodel.adoc[Neo4j Graph Model]: Description of the nodes, relationships, indexes, ... of a Neo4j graph
diff --git a/docs/hop-user-manual/modules/ROOT/pages/metadata-types/naming-scheme.adoc b/docs/hop-user-manual/modules/ROOT/pages/metadata-types/naming-scheme.adoc
new file mode 100644
index 0000000000..6b20e7e13e
--- /dev/null
+++ b/docs/hop-user-manual/modules/ROOT/pages/metadata-types/naming-scheme.adoc
@@ -0,0 +1,165 @@
+////
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+////
+:imagesdir: ../../assets/images/
+:page-pagination:
+:description: A Naming Scheme defines reusable rules to normalize Hop field names, database identifiers, and file or folder names.
+
+= Naming Scheme
+
+== Description
+
+A *Naming Scheme* describes how free-form names should be turned into consistent identifiers.
+Typical uses include cleaning field names that arrive with spaces (for example `Order ID` → `order_id`), normalizing file or folder names, and applying a shared project convention (snake_case, camelCase, PascalCase, and so on).
+
+Naming Schemes are managed as project metadata. Apply one without adding buttons to every dialog:
+
+* **N indicator** -- widgets that accept a naming scheme show a small *N* on the right (same diamond plate as `$` for variables and `#` for expanded integers). Click *N* to open the matching scheme in a dialog. If several schemes of that type exist, pick one first. If none exist, Hop creates a new scheme of that type and opens it.
+* **Keyboard shortcut** -- `CTRL-SHIFT-N` on a name field (transform/action name, field cell, table name, file name, …) lists schemes of the matching type and replaces the current identifier. When the field does *not* accept variables, `CTRL-SPACE` does the same thing.
+* **TableView toolbar** -- **Apply a Naming Scheme to a column** still rewrites a whole column at once (with undo).
+
+image:metadata-types/naming-scheme-indicator.png[Naming Scheme N indicator]
+
+If only one scheme of the required type exists, apply and open both skip the picker.
+
+A *General* scheme is offered on every name field that does not have a scheme of its own type. Create one General scheme (for example lower-case + underscore) and it covers transform names, field names, tables, and files. Add a type-specific scheme only when that kind of name needs different rules; when such a scheme exists, General is no longer listed for that type.
+
+== Get Fields
+
+CSV File Input and Text File Input have an optional *Naming scheme* field. When you click *Get Fields*, discovered names are rewritten with that scheme.
+
+If the field is empty, Get Fields still auto-applies when exactly one matching scheme exists (a type-specific hop-field scheme, or a General scheme). The same automatic apply runs after Get Fields in other dialogs that fill annotated name columns (Excel, Parquet, Select Values, and so on).
+
+NOTE: Transform, action, pipeline, workflow and metadata name fields use the shortcut with *variable insertion disabled* -- they stay identifiers, not `'${...}'` expressions. They still show *N*, not `$`.
+
+Annotated *filename* and *folder* widgets (run configurations, execution information locations, and so on) show *N* automatically. Filename widgets still accept variables (`CTRL-SPACE`); `CTRL-SHIFT-N` rewrites the last path segment only.
+
+Variable *names* (project described variables, pipeline and workflow parameters, Set Variables) use the *Hop variable names* type. Values that already contain `'${...}'` are left unchanged.
+
+== Options
+
+image:metadata-types/naming-scheme-editor.png[Naming Scheme editor, width="75%"]
+
+The screenshot above shows a scheme named `lowercase-dashes`: lower case words joined with dashes, so `Order ID` previews as `order-id`.
+
+[options="header"]
+|===
+|Option|Description
+|Name|Unique metadata name of this scheme.
+|Description|Optional free-text description.
+|Type|Target kind. *General* applies to every name field unless a scheme of the widget's specific type exists (Hop field, transform, action, pipeline, workflow, metadata, variable, database table, database column, file, or folder). *File* schemes rewrite only the last path segment and keep the parent folder and the file extension (`/data/Order ID.csv` → `/data/order_id.csv`). *Folder* schemes rewrite the last segment and keep the parent path (and a trailing slash).
+|Case style|`As is`, `Lower case`, `Upper case`, `camelCase`, or `PascalCase`.
+|Word separator|How words are joined when not using camel/Pascal case: none, underscore (`_`), dash (`-`), or space.
+|Capitalize first word|When enabled, uppercase the first character of the first word. Typical for transform and action names with a space separator (`Table input`).
+|Extra delimiters|Additional characters treated as word boundaries (beyond spaces, `_`, `-`, and camelCase edges).
+|Remove special characters|When enabled, strip non letter/digit characters from each word.
+|Collapse repeated separators|When enabled, collapse repeated separators such as `__` to a single separator.
+|Trim leading/trailing separators|When enabled, remove separators at the start or end of the result.
+|Prefix / Suffix|Optional strings prepended or appended after the transform.
+|Preview input / output|Live sample showing how the current options transform a name.
+|===
+
+== Examples
+
+[options="header"]
+|===
+|Input|Case style|Word separator|Result
+|`Order ID`|Lower case|Underscore (`_`)|`order_id`
+|`Order ID`|As is|Underscore (`_`)|`Order_ID`
+|`Order ID`|camelCase|_|`orderId`
+|`Order ID`|PascalCase|_|`OrderId`
+|`order-id`|Upper case|Underscore (`_`)|`ORDER_ID`
+|`Order ID`|Lower case|Dash (`-`)|`order-id`
+|`read_customers`|Lower case|Space|`read customers`
+|`read_customers` (capitalize first word)|Lower case|Space|`Read customers`
+|`/data/Order ID.csv` (file type)|Lower case|Underscore (`_`)|`/data/order_id.csv`
+|`/data/My Folder/` (folder type)|Lower case|Underscore (`_`)|`/data/my_folder/`
+|===
+
+== Applying from a name field
+
+The screenshot below shows an action name field with the *N* indicator. Hover it for the shortcut reminder; click it to open the scheme in a dialog.
+
+image:metadata-types/naming-scheme-indicator-and-tooltip.png[Action name field with Naming Scheme indicator and tooltip, width="90%"]
+
+. Create at least one Naming Scheme in the Metadata perspective (pick the type that matches the field).
+. Focus a name widget -- transform name, action name, a field-name cell, a table name, a file or folder path, a variable or parameter name, …
+. Press `CTRL-SHIFT-N` (or `CTRL-SPACE` on name fields that do not accept variables).
+. If several schemes of that type exist, pick one. The list shows a live preview (`Order ID → order_id`).
+. The current identifier is replaced. Values that already contain `${...}` are left unchanged.
+
+To review or change the rules instead of applying them, click the *N* indicator. That opens the scheme in a dialog (or a picker when more than one scheme matches the field type). It does not open another tab in the metadata perspective. If no scheme of that type (and no General scheme) exists yet, Hop creates one of the matching type and opens it for you to save.
+
+The same shortcut works on *F2* inline rename in the Metadata and File Explorer trees (metadata names, file names, and folder names). There is no *N* indicator on those tiny tree editors -- press `CTRL-SHIFT-N` after F2.
+
+== Applying from TableView
+
+. Open a transform or dialog that shows a field list (or any other editable table).
+. Ensure table toolbars are visible (Hop Gui options).
+. Click the **Apply a Naming Scheme to a column** toolbar icon (label / tag icon on the TableView toolbar).
+. Select the column to rename if the table has more than one name column.
+. Select a Naming Scheme of the matching type.
+. Confirm — values in non-empty rows are updated. Use the table Undo action if needed.
+
+TIP: `CTRL-SHIFT-N` on a focused cell applies the scheme to that cell only. The toolbar is the bulk action.
+
+=== Example: CSV File Input fields
+
+The following example uses the `lowercase-dashes` scheme on the **Name** column of a xref:pipeline/transforms/csvinput.adoc[CSV File Input] field list.
+
+*Before* — mixed styles (`ID`, `FirstName`, `birth_date`, `stateCode`, …):
+
+image:metadata-types/naming-scheme-csv-input-before.png[CSV File Input fields before applying a Naming Scheme, width="90%"]
+
+*After* — consistent lower-case names with dashes (`id`, `first-name`, `birth-date`, `state-code`, …):
+
+image:metadata-types/naming-scheme-csv-input-after.png[CSV File Input fields after applying the lowercase-dashes Naming Scheme, width="90%"]
+
+== Types as plugins
+
+The *Type* combo lists every registered naming-scheme kind. Built-in kinds include General, Hop field/transform/action/pipeline/workflow/metadata/variable, database table/column, file, and folder.
+
+Other plugins can add kinds without changing Hop. For example hop-data-vault can register `dv-hub`, `dv-satellite`, `dv-link`, `dm-dimension`, `dm-fact`, and so on. Create one Naming Scheme metadata object per kind (or one General scheme). Use one scheme per type in a project so CI has a single expected spelling.
+
+== Checking names in CI
+
+A name is valid when applying the matching scheme leaves the string unchanged. Empty values, `<null>`, and values that contain `${...}` are skipped.
+
+The same check runs in Hop Gui *Verify this pipeline* / *Verify this workflow* (errors only) and from the command line:
+
+----
+hop naming-check --project my-project
+hop naming-check --path /path/to/project --format json --require-scheme
+hop naming-check --type hop-field,hop-transform
+----
+
+* Exit `0` when there are no errors.
+* Exit `1` when at least one name would be rewritten (or when `--require-scheme` is set and a type has no scheme).
+* Exit `2` on unexpected failure (file load issues are warnings).
+* `--format json` prints one object per finding for GitHub Actions or other reporters.
+
+Example GitHub Actions step after Hop is on `PATH` and the project is checked out:
+
+----
+- name: Check naming schemes
+  run: hop naming-check --project my-project --require-scheme
+----
+
+Create one *General* scheme (or one scheme per type) in the project's metadata. There is no `--fix` flag: rewriting committed pipelines is a separate, explicit action.
+
+== Related
+
+* GitHub issue https://github.com/apache/hop/issues/2683[#2683] — field name cleanup / naming toolbar
diff --git a/docs/hop-user-manual/modules/ROOT/pages/protips/index.adoc b/docs/hop-user-manual/modules/ROOT/pages/protips/index.adoc
index f0d540f4ec..9a933b6645 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/protips/index.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/protips/index.adoc
@@ -38,6 +38,9 @@ include::../snippets/variables/hop-windows-shell-encoding.adoc[]
 
 == Keyboard Shortcuts and Mouse actions
 
+CTRL-SHIFT-N::
+On a name field (transform/action name, field-name cell, table name, file name, metadata name, or F2 rename), apply a xref:metadata-types/naming-scheme.adoc[Naming Scheme] of the matching type. Click the tiny *N* next to the field to open the scheme instead.
+
 CTRL-K::
 In any table view in a Hop dialog, select one or more lines and use `CTRL-K` to remove all lines but your selection
 
diff --git a/engine/src/main/java/org/apache/hop/core/HopEnvironment.java b/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
index 6a522811f7..a93b493c30 100644
--- a/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
+++ b/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
@@ -101,6 +101,7 @@ public class HopEnvironment {
         ExecutionInfoLocationPluginType.getInstance(),
         LineageSinkPluginType.getInstance(),
         HopCommandPluginType.getInstance(),
+        org.apache.hop.core.naming.NamingSchemeTypePluginType.getInstance(),
         DataStreamPluginType.getInstance());
   }
 
diff --git a/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java b/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
index fdd91de3b9..70a57b1902 100644
--- a/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
+++ b/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
@@ -100,6 +100,7 @@ import org.w3c.dom.Node;
  * This class defines information about a pipeline and offers methods to save and load it from XML
  * as well as methods to alter a pipeline by adding/removing databases, transforms, hops, etc.
  */
+@org.apache.hop.core.naming.NamingSchemeKind("hop-pipeline")
 public class PipelineMeta extends AbstractMeta
     implements IXml,
         Comparator<PipelineMeta>,
diff --git a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
index fe38032ecd..af3004ec2c 100644
--- a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
+++ b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformMeta.java
@@ -60,6 +60,7 @@ import org.w3c.dom.Node;
 /** This class contains everything that is needed to define a transform. */
 @Getter
 @Setter
+@org.apache.hop.core.naming.NamingSchemeKind("hop-transform")
 public class TransformMeta
     implements Cloneable,
         Comparable<TransformMeta>,
@@ -93,7 +94,8 @@ public class TransformMeta
   @HopMetadataProperty(key = "type")
   private String transformPluginId; // --> transform plugin id
 
-  @HopMetadataProperty private String name;
+  @HopMetadataProperty(namingSchemeType = "hop-transform")
+  private String name;
 
   @HopMetadataProperty(inline = true)
   private ITransformMeta transform;
diff --git a/engine/src/main/java/org/apache/hop/server/HopServerMeta.java b/engine/src/main/java/org/apache/hop/server/HopServerMeta.java
index 661d2e32a8..0f19130c78 100644
--- a/engine/src/main/java/org/apache/hop/server/HopServerMeta.java
+++ b/engine/src/main/java/org/apache/hop/server/HopServerMeta.java
@@ -53,6 +53,7 @@ import org.w3c.dom.Node;
     documentationUrl = "/metadata-types/hop-server.html",
     hopMetadataPropertyType = HopMetadataPropertyType.SERVER_DEFINITION,
     supportsGlobalReplace = true)
+@org.apache.hop.core.naming.NamingSchemeKind("hop-metadata")
 public class HopServerMeta extends HopMetadataBase implements Cloneable, IXml, IHopMetadata {
   public static final String STRING_HOP_SERVER = "Hop Server";
   public static final String XML_TAG = "hop-server";
diff --git a/engine/src/main/java/org/apache/hop/workflow/CheckActionsExtension.java b/engine/src/main/java/org/apache/hop/workflow/CheckActionsExtension.java
new file mode 100644
index 0000000000..b4897c4271
--- /dev/null
+++ b/engine/src/main/java/org/apache/hop/workflow/CheckActionsExtension.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.workflow;
+
+import java.util.List;
+import lombok.Getter;
+import org.apache.hop.core.ICheckResult;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.workflow.action.ActionMeta;
+
+/** Payload for {@code AfterCheckActions}. */
+@Getter
+public class CheckActionsExtension {
+  private final List<ICheckResult> remarks;
+  private final IVariables variables;
+  private final WorkflowMeta workflowMeta;
+  private final List<ActionMeta> actions;
+  private final IHopMetadataProvider metadataProvider;
+
+  public CheckActionsExtension(
+      List<ICheckResult> remarks,
+      IVariables variables,
+      WorkflowMeta workflowMeta,
+      List<ActionMeta> actions,
+      IHopMetadataProvider metadataProvider) {
+    this.remarks = remarks;
+    this.variables = variables;
+    this.workflowMeta = workflowMeta;
+    this.actions = actions;
+    this.metadataProvider = metadataProvider;
+  }
+}
diff --git a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
index 82ab7eb53c..70a4fc3a26 100644
--- a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
+++ b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
@@ -84,6 +84,7 @@ import org.w3c.dom.Node;
  */
 @Getter
 @Setter
+@org.apache.hop.core.naming.NamingSchemeKind("hop-workflow")
 public class WorkflowMeta extends AbstractMeta
     implements Cloneable, Comparable<WorkflowMeta>, IXml, IResourceExport, IHasFilename {
   public static final String WORKFLOW_EXTENSION = ".hwf";
@@ -1601,6 +1602,12 @@ public class WorkflowMeta extends AbstractMeta
         monitor.worked(worked++);
       }
 
+      ExtensionPointHandler.callExtensionPoint(
+          LogChannel.GENERAL,
+          variables,
+          HopExtensionPoint.AfterCheckActions.id,
+          new CheckActionsExtension(remarks, variables, this, actions, metadataProvider));
+
       monitor.done();
     } catch (Exception e) {
       throw new HopRuntimeException("Error checking workflow", e);
diff --git a/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java b/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
index 0c6ec7f344..e84ed03699 100644
--- a/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
+++ b/engine/src/main/java/org/apache/hop/workflow/action/ActionBase.java
@@ -76,6 +76,7 @@ import org.w3c.dom.Node;
  */
 @Getter
 @Setter
+@org.apache.hop.core.naming.NamingSchemeKind("hop-action")
 public abstract class ActionBase
     implements IAction,
         Cloneable,
@@ -87,7 +88,8 @@ public abstract class ActionBase
         IDialogEditable {
 
   /** The name of the action */
-  @HopMetadataProperty private String name;
+  @HopMetadataProperty(namingSchemeType = "hop-action")
+  private String name;
 
   /** The description of the action */
   @HopMetadataProperty private String description;
diff --git a/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenamesDialog.java b/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenamesDialog.java
index 2701588ffd..168ab388c2 100644
--- a/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenamesDialog.java
+++ b/plugins/actions/addresultfilenames/src/main/java/org/apache/hop/workflow/actions/addresultfilenames/ActionAddResultFilenamesDialog.java
@@ -26,6 +26,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -241,7 +242,9 @@ public class ActionAddResultFilenamesDialog extends ActionDialog {
     fdbaFilename.top = new FormAttachment(wgSettings, margin);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExistDialog.java b/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExistDialog.java
index eede576b14..2e6e5f69b4 100644
--- a/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExistDialog.java
+++ b/plugins/actions/columnsexist/src/main/java/org/apache/hop/workflow/actions/columnsexist/ActionColumnsExistDialog.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -152,7 +153,9 @@ public class ActionColumnsExistDialog extends ActionDialog {
         });
 
     // Table name
-    wTablename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTablename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTablename);
     wTablename.addModifyListener(lsMod);
     FormData fdTablename = new FormData();
diff --git a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
index 9d60bfe1a6..5a4f39f647 100644
--- a/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
+++ b/plugins/actions/copyfiles/src/main/java/org/apache/hop/workflow/actions/copyfiles/ActionCopyFilesDialog.java
@@ -27,6 +27,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -248,6 +249,7 @@ public class ActionCopyFilesDialog extends ActionDialog {
         };
 
     colinf[0].setUsingVariables(true);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.FOLDER);
     colinf[0].setToolTip(
         BaseMessages.getString(PKG, "ActionCopyFiles.Fields.SourceFileFolder.Tooltip"));
     colinf[0].setTextVarButtonSelectionListener(getFileSelectionAdapter());
@@ -256,6 +258,7 @@ public class ActionCopyFilesDialog extends ActionDialog {
     colinf[1].setToolTip(BaseMessages.getString(PKG, "ActionCopyFiles.Fields.Wildcard.Tooltip"));
 
     colinf[2].setUsingVariables(true);
+    colinf[2].setNamingSchemeType(NamingSchemeTypes.FOLDER);
     colinf[2].setToolTip(
         BaseMessages.getString(PKG, "ActionCopyFiles.Fields.DestinationFileFolder.Tooltip"));
     colinf[2].setTextVarButtonSelectionListener(getFileSelectionAdapter());
diff --git a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
index 64112b2cd3..6b0142b9fc 100644
--- a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
+++ b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
@@ -24,6 +24,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -168,7 +169,9 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdbFolderName.top = new FormAttachment(wAction, 0);
     wbFolderName.setLayoutData(fdbFolderName);
 
-    wFolderName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFolderName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wFolderName);
     wFolderName.addModifyListener(lsMod);
     FormData fdFolderName = new FormData();
diff --git a/plugins/actions/createfile/src/main/java/org/apache/hop/workflow/actions/createfile/ActionCreateFileDialog.java b/plugins/actions/createfile/src/main/java/org/apache/hop/workflow/actions/createfile/ActionCreateFileDialog.java
index 9f1c469dd1..5ea4b3c5ec 100644
--- a/plugins/actions/createfile/src/main/java/org/apache/hop/workflow/actions/createfile/ActionCreateFileDialog.java
+++ b/plugins/actions/createfile/src/main/java/org/apache/hop/workflow/actions/createfile/ActionCreateFileDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -88,7 +89,9 @@ public class ActionCreateFileDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addListener(SWT.Modify, lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolderDialog.java b/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolderDialog.java
index 94b23e06f1..0e0fea7c4b 100644
--- a/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolderDialog.java
+++ b/plugins/actions/createfolder/src/main/java/org/apache/hop/workflow/actions/createfolder/ActionCreateFolderDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -85,7 +86,9 @@ public class ActionCreateFolderDialog extends ActionDialog {
     fdbFoldername.top = new FormAttachment(wlFoldername, 0, SWT.CENTER);
     wbFoldername.setLayoutData(fdbFoldername);
 
-    wFoldername = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFoldername =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wFoldername);
     wFoldername.addModifyListener(lsMod);
     FormData fdFoldername = new FormData();
diff --git a/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFileDialog.java b/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFileDialog.java
index 66921743db..52177839ea 100644
--- a/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFileDialog.java
+++ b/plugins/actions/deletefile/src/main/java/org/apache/hop/workflow/actions/deletefile/ActionDeleteFileDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -89,7 +90,9 @@ public class ActionDeleteFileDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFilesDialog.java b/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFilesDialog.java
index 66d83afd48..badcd6ad23 100644
--- a/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFilesDialog.java
+++ b/plugins/actions/deletefiles/src/main/java/org/apache/hop/workflow/actions/deletefiles/ActionDeleteFilesDialog.java
@@ -30,6 +30,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -170,6 +171,7 @@ public class ActionDeleteFilesDialog extends ActionDialog {
         };
 
     colinf[0].setUsingVariables(true);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.FILE);
     colinf[0].setToolTip(BaseMessages.getString(PKG, "ActionDeleteFiles.Fields.Column"));
     colinf[0].setTextVarButtonSelectionListener(getFileSelectionAdapter());
     colinf[1].setUsingVariables(true);
diff --git a/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFoldersDialog.java b/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFoldersDialog.java
index 5db7b08a9f..4fda69b06c 100644
--- a/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFoldersDialog.java
+++ b/plugins/actions/deletefolders/src/main/java/org/apache/hop/workflow/actions/deletefolders/ActionDeleteFoldersDialog.java
@@ -26,6 +26,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ColumnsResizer;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -214,6 +215,7 @@ public class ActionDeleteFoldersDialog extends ActionDialog {
         };
 
     colinf[0].setUsingVariables(true);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.FOLDER);
     colinf[0].setToolTip(BaseMessages.getString(PKG, "ActionDeleteFolders.Fields.Column"));
     colinf[0].setTextVarButtonSelectionListener(
         new SelectionAdapter() {
diff --git a/plugins/actions/evaluatetablecontent/src/main/java/org/apache/hop/workflow/actions/evaluatetablecontent/ActionEvalTableContentDialog.java b/plugins/actions/evaluatetablecontent/src/main/java/org/apache/hop/workflow/actions/evaluatetablecontent/ActionEvalTableContentDialog.java
index bea65b9c93..e7a0def265 100644
--- a/plugins/actions/evaluatetablecontent/src/main/java/org/apache/hop/workflow/actions/evaluatetablecontent/ActionEvalTableContentDialog.java
+++ b/plugins/actions/evaluatetablecontent/src/main/java/org/apache/hop/workflow/actions/evaluatetablecontent/ActionEvalTableContentDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.database.dialog.DatabaseExplorerDialog;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TextComposite;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -175,7 +176,9 @@ public class ActionEvalTableContentDialog extends ActionDialog {
           }
         });
 
-    wTableName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTableName);
     wTableName.setToolTipText(
         BaseMessages.getString(PKG, "ActionEvalTableContent.TableName.Tooltip"));
diff --git a/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompareDialog.java b/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompareDialog.java
index b14e66ee54..d1165bf615 100644
--- a/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompareDialog.java
+++ b/plugins/actions/filecompare/src/main/java/org/apache/hop/workflow/actions/filecompare/ActionFileCompareDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -87,7 +88,9 @@ public class ActionFileCompareDialog extends ActionDialog {
     fdbFilename1.right = new FormAttachment(100, -margin);
     fdbFilename1.top = new FormAttachment(wlFilename1, 0, SWT.CENTER);
     wbFilename1.setLayoutData(fdbFilename1);
-    wFilename1 = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename1 =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename1);
     wFilename1.addModifyListener(lsMod);
     FormData fdFilename1 = new FormData();
@@ -122,7 +125,9 @@ public class ActionFileCompareDialog extends ActionDialog {
     fdbFilename2.right = new FormAttachment(100, -margin);
     fdbFilename2.top = new FormAttachment(wlFilename2, 0, SWT.CENTER);
     wbFilename2.setLayoutData(fdbFilename2);
-    wFilename2 = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename2 =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename2);
     wFilename2.addModifyListener(lsMod);
     FormData fdFilename2 = new FormData();
diff --git a/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExistsDialog.java b/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExistsDialog.java
index 6deb7667e0..5320eb73be 100644
--- a/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExistsDialog.java
+++ b/plugins/actions/fileexists/src/main/java/org/apache/hop/workflow/actions/fileexists/ActionFileExistsDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -93,7 +94,9 @@ public class ActionFileExistsDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExistDialog.java b/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExistDialog.java
index 539ce79d5c..cd7aa3fac1 100644
--- a/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExistDialog.java
+++ b/plugins/actions/filesexist/src/main/java/org/apache/hop/workflow/actions/filesexist/ActionFilesExistDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ColumnsResizer;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -112,6 +113,7 @@ public class ActionFilesExistDialog extends ActionDialog {
         };
 
     columns[0].setUsingVariables(true);
+    columns[0].setNamingSchemeType(NamingSchemeTypes.FILE);
     columns[0].setToolTip(BaseMessages.getString(PKG, "ActionFilesExist.Fields.Column"));
     columns[0].setTextVarButtonSelectionListener(getFileSelectionAdapter());
     columns[1].setUsingVariables(true);
diff --git a/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmptyDialog.java b/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmptyDialog.java
index f82f2d24aa..891a1a5fc5 100644
--- a/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmptyDialog.java
+++ b/plugins/actions/folderisempty/src/main/java/org/apache/hop/workflow/actions/folderisempty/ActionFolderIsEmptyDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -90,7 +91,9 @@ public class ActionFolderIsEmptyDialog extends ActionDialog {
     fdbFoldername.top = new FormAttachment(wlFoldername, 0, SWT.CENTER);
     wbFoldername.setLayoutData(fdbFoldername);
 
-    wFoldername = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFoldername =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wFoldername);
     wFoldername.addModifyListener(lsMod);
     FormData fdFoldername = new FormData();
diff --git a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
index 6de1d50546..28f41f579b 100644
--- a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
+++ b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -292,7 +293,9 @@ public class ActionFoldersCompareDialog extends ActionDialog {
     fdbFilename1.top = new FormAttachment(wSettings, margin);
     wbFilename1.setLayoutData(fdbFilename1);
 
-    wFilename1 = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename1 =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wFilename1);
     wFilename1.addModifyListener(lsMod);
     FormData fdFilename1 = new FormData();
@@ -346,7 +349,9 @@ public class ActionFoldersCompareDialog extends ActionDialog {
     fdbFilename2.top = new FormAttachment(wFilename1, margin);
     wbFilename2.setLayoutData(fdbFilename2);
 
-    wFilename2 = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename2 =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wFilename2);
     wFilename2.addModifyListener(lsMod);
     FormData fdFilename2 = new FormData();
diff --git a/plugins/actions/http/src/main/java/org/apache/hop/workflow/actions/http/ActionHttpDialog.java b/plugins/actions/http/src/main/java/org/apache/hop/workflow/actions/http/ActionHttpDialog.java
index 71b66f1b58..37716d48a8 100644
--- a/plugins/actions/http/src/main/java/org/apache/hop/workflow/actions/http/ActionHttpDialog.java
+++ b/plugins/actions/http/src/main/java/org/apache/hop/workflow/actions/http/ActionHttpDialog.java
@@ -30,6 +30,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -471,7 +472,9 @@ public class ActionHttpDialog extends ActionDialog {
     fdbTargetFile.top = new FormAttachment(0, margin);
     wbTargetFile.setLayoutData(fdbTargetFile);
 
-    wTargetFile = new TextVar(variables, wTargetFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTargetFile =
+        new TextVar(variables, wTargetFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wTargetFile);
     wTargetFile.setToolTipText(BaseMessages.getString(PKG, "ActionHTTP.TargetFile.Tooltip"));
     wTargetFile.addModifyListener(lsMod);
diff --git a/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFilesDialog.java b/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFilesDialog.java
index a4db1a7d99..51ba13bec5 100644
--- a/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFilesDialog.java
+++ b/plugins/actions/movefiles/src/main/java/org/apache/hop/workflow/actions/movefiles/ActionMoveFilesDialog.java
@@ -31,6 +31,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -654,7 +655,9 @@ public class ActionMoveFilesDialog extends ActionDialog {
     fdbDestinationFolder.top = new FormAttachment(wDestinationFile, 0);
     wbDestinationFolder.setLayoutData(fdbDestinationFolder);
 
-    wDestinationFolder = new TextVar(variables, wMoveToGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wDestinationFolder =
+        new TextVar(variables, wMoveToGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wDestinationFolder);
     wDestinationFolder.addModifyListener(lsMod);
     FormData fdDestinationFolder = new FormData();
diff --git a/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariablesDialog.java b/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariablesDialog.java
index c0fd48400a..02dd93557b 100644
--- a/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariablesDialog.java
+++ b/plugins/actions/setvariables/src/main/java/org/apache/hop/workflow/actions/setvariables/ActionSetVariablesDialog.java
@@ -27,6 +27,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -98,7 +99,9 @@ public class ActionSetVariablesDialog extends ActionDialog {
     fdlFilename.right = new FormAttachment(middle, -margin);
     fdlFilename.top = new FormAttachment(0, margin);
     wlFilename.setLayoutData(fdlFilename);
-    wFilename = new TextVar(variables, gFilename, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, gFilename, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
@@ -200,6 +203,7 @@ public class ActionSetVariablesDialog extends ActionDialog {
           false),
     };
     colinf[0].setUsingVariables(true);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_VARIABLE);
     colinf[1].setUsingVariables(true);
 
     wFields =
diff --git a/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExistsDialog.java b/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExistsDialog.java
index f84f70064d..f5ef2acbab 100644
--- a/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExistsDialog.java
+++ b/plugins/actions/tableexists/src/main/java/org/apache/hop/workflow/actions/tableexists/ActionTableExistsDialog.java
@@ -31,6 +31,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -128,7 +129,9 @@ public class ActionTableExistsDialog extends ActionDialog {
     wbTable.setLayoutData(fdbTable);
     wbTable.addListener(SWT.Selection, e -> getTableName());
 
-    wTablename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTablename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTablename);
     wTablename.addModifyListener(lsMod);
     FormData fdTablename = new FormData();
diff --git a/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZipDialog.java b/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZipDialog.java
index a9e3945487..0d771bcc83 100644
--- a/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZipDialog.java
+++ b/plugins/actions/unzip/src/main/java/org/apache/hop/workflow/actions/unzip/ActionUnZipDialog.java
@@ -26,6 +26,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -227,7 +228,9 @@ public class ActionUnZipDialog extends ActionDialog {
     fdbZipFilename.top = new FormAttachment(wlArgsPrevious, margin);
     wbZipFilename.setLayoutData(fdbZipFilename);
 
-    wZipFilename = new TextVar(variables, wSource, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wZipFilename =
+        new TextVar(variables, wSource, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wZipFilename);
     wZipFilename.addModifyListener(lsMod);
     FormData fdZipFilename = new FormData();
diff --git a/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFileDialog.java b/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFileDialog.java
index 6da4d85d8e..d77ed0e1e2 100644
--- a/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFileDialog.java
+++ b/plugins/actions/waitforfile/src/main/java/org/apache/hop/workflow/actions/waitforfile/ActionWaitForFileDialog.java
@@ -24,6 +24,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -120,7 +121,9 @@ public class ActionWaitForFileDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSqlDialog.java b/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSqlDialog.java
index df06338c5d..47e7ba70e4 100644
--- a/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSqlDialog.java
+++ b/plugins/actions/waitforsql/src/main/java/org/apache/hop/workflow/actions/waitforsql/ActionWaitForSqlDialog.java
@@ -36,6 +36,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.SQLStyledTextComp;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -189,7 +190,9 @@ public class ActionWaitForSqlDialog extends ActionDialog {
           }
         });
 
-    wTableName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTableName);
     wTableName.setToolTipText(BaseMessages.getString(PKG, "ActionWaitForSQL.Tablename.Tooltip"));
     wTableName.addModifyListener(lsMod);
diff --git a/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFileDialog.java b/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFileDialog.java
index c3b8e342f5..b852bbc6dd 100644
--- a/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFileDialog.java
+++ b/plugins/actions/writetofile/src/main/java/org/apache/hop/workflow/actions/writetofile/ActionWriteToFileDialog.java
@@ -27,6 +27,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -117,7 +118,9 @@ public class ActionWriteToFileDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(0, margin);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFileDialog.java b/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFileDialog.java
index 59c83facec..6e0e7a4438 100644
--- a/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFileDialog.java
+++ b/plugins/actions/zipfile/src/main/java/org/apache/hop/workflow/actions/zipfile/ActionZipFileDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -365,7 +366,9 @@ public class ActionZipFileDialog extends ActionDialog {
     fdbZipFilename.right = new FormAttachment(100, 0);
     fdbZipFilename.top = new FormAttachment(wSourceFiles, 0);
     wbZipFilename.setLayoutData(fdbZipFilename);
-    wZipFilename = new TextVar(variables, wZipFile, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wZipFilename =
+        new TextVar(variables, wZipFile, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wZipFilename);
     wZipFilename.addModifyListener(lsMod);
     FormData fdZipFilename = new FormData();
diff --git a/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputDialog.java b/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputDialog.java
index 37c713e6c4..b92d8f83b5 100644
--- a/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputDialog.java
+++ b/plugins/databases/access/src/main/java/org/apache/hop/pipeline/transforms/accessoutput/AccessOutputDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -214,7 +215,9 @@ public class AccessOutputDialog extends BaseTransformDialog {
     fdbTablename.top = new FormAttachment(wWaitFirstRowToCreateFile, margin);
     wbbTableName.setLayoutData(fdbTablename);
 
-    wTableName = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableName =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     wTableName.setToolTipText(
         BaseMessages.getString(PKG, "AccessOutputDialog.TargetTable.Tooltip"));
     PropsUi.setLook(wTableName);
diff --git a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java
index 9100fbc57e..15f0c9d762 100644
--- a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java
+++ b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java
@@ -52,6 +52,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -217,7 +218,9 @@ public class CrateDBBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(lastControl, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java b/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java
index ad5ed3e1a9..dc2c386532 100644
--- a/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java
+++ b/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java
@@ -40,6 +40,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -194,7 +195,9 @@ public class DorisBulkLoaderDialog extends BaseTransformDialog {
     fdlTableName.right = new FormAttachment(middle, -margin);
     fdlTableName.top = new FormAttachment(wDatabaseName, margin);
     wlTableName.setLayoutData(fdlTableName);
-    wTableName = new TextVar(variables, gConnections, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableName =
+        new TextVar(variables, gConnections, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     wTableName.setToolTipText(
         BaseMessages.getString(PKG, "DorisBulkLoaderDialog.TableName.Tooltip"));
     PropsUi.setLook(wTableName);
diff --git a/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java b/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java
index 70e33816c2..1153c12b6d 100644
--- a/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java
+++ b/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java
@@ -46,6 +46,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -265,7 +266,9 @@ public class MonetDbBulkLoaderDialog extends BaseTransformDialog {
     PropsUi.setLook(wbTable);
     wbTable.setText(BaseMessages.getString(PKG, "MonetDBBulkLoaderDialog.Browse.Button"));
 
-    wTable = new TextVar(variables, wGeneralSettingsComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wGeneralSettingsComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/databases/mssqlnative/src/main/java/org/apache/hop/workflow/actions/mssqlbulkload/ActionMssqlBulkLoadDialog.java b/plugins/databases/mssqlnative/src/main/java/org/apache/hop/workflow/actions/mssqlbulkload/ActionMssqlBulkLoadDialog.java
index b5137d9bb1..54333afa1f 100644
--- a/plugins/databases/mssqlnative/src/main/java/org/apache/hop/workflow/actions/mssqlbulkload/ActionMssqlBulkLoadDialog.java
+++ b/plugins/databases/mssqlnative/src/main/java/org/apache/hop/workflow/actions/mssqlbulkload/ActionMssqlBulkLoadDialog.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -231,7 +232,9 @@ public class ActionMssqlBulkLoadDialog extends ActionDialog {
           }
         });
 
-    wTablename = new TextVar(variables, wConnectionGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTablename =
+        new TextVar(variables, wConnectionGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTablename);
     wTablename.setToolTipText(BaseMessages.getString(PKG, "ActionMssqlBulkLoad.Tablename.Tooltip"));
     wTablename.addModifyListener(lsMod);
@@ -308,7 +311,9 @@ public class ActionMssqlBulkLoadDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wConnectionGroup, 0);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wDataFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wDataFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.setToolTipText(BaseMessages.getString(PKG, "ActionMssqlBulkLoad.Filename.Tooltip"));
     wFilename.addModifyListener(lsMod);
diff --git a/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java b/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java
index c26115c501..a969f0f3b5 100644
--- a/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java
+++ b/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java
@@ -50,6 +50,7 @@ import org.apache.hop.ui.core.dialog.ShowMessageDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -214,7 +215,9 @@ public class MySqlBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.right = new FormAttachment(100, 0);
     fdbTable.top = new FormAttachment(wlTable, 0, SWT.CENTER);
     wbTable.setLayoutData(fdbTable);
-    wTable = new TextVar(variables, wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkfile/ActionMysqlBulkFileDialog.java b/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkfile/ActionMysqlBulkFileDialog.java
index c240f8f614..83cf94a130 100644
--- a/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkfile/ActionMysqlBulkFileDialog.java
+++ b/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkfile/ActionMysqlBulkFileDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -160,7 +161,9 @@ public class ActionMysqlBulkFileDialog extends ActionDialog {
           }
         });
 
-    wTableName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTableName);
     wTableName.setToolTipText(BaseMessages.getString(PKG, "ActionMysqlBulkFile.TableName.Tooltip"));
     FormData fdTablename = new FormData();
diff --git a/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkload/ActionMysqlBulkLoadDialog.java b/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkload/ActionMysqlBulkLoadDialog.java
index f0ffd311e9..75130740c1 100644
--- a/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkload/ActionMysqlBulkLoadDialog.java
+++ b/plugins/databases/mysql/src/main/java/org/apache/hop/workflow/actions/mysqlbulkload/ActionMysqlBulkLoadDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
@@ -164,7 +165,9 @@ public class ActionMysqlBulkLoadDialog extends ActionDialog {
           }
         });
 
-    wTablename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTablename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTablename);
     wTablename.addModifyListener(lsMod);
     FormData fdTablename = new FormData();
@@ -192,7 +195,9 @@ public class ActionMysqlBulkLoadDialog extends ActionDialog {
     fdbFilename.top = new FormAttachment(wTablename, 0);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java b/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java
index 242dd1c5ef..3fb8c51347 100644
--- a/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java
+++ b/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java
@@ -49,6 +49,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -262,7 +263,9 @@ public class OraBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.right = new FormAttachment(100, 0);
     fdbTable.top = new FormAttachment(wbSchema, margin);
     wbTable.setLayoutData(fdbTable);
-    wTable = new TextVar(variables, wBulkLoaderComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wBulkLoaderComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
diff --git a/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java b/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java
index 4ed6a24455..abf24ef136 100644
--- a/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java
+++ b/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java
@@ -46,6 +46,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -187,7 +188,9 @@ public class PGBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.right = new FormAttachment(100, 0);
     fdbTable.top = new FormAttachment(wSchema, margin);
     wbTable.setLayoutData(fdbTable);
-    wTable = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java
index b8c6601dda..fe062f8adf 100644
--- a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java
+++ b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java
@@ -52,6 +52,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -379,7 +380,9 @@ public class SnowflakeBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wbSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, wLoaderComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wLoaderComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     FormData fdTable = new FormData();
diff --git a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java
index 90da761e69..0b8b0eb198 100644
--- a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java
+++ b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java
@@ -40,6 +40,7 @@ import org.apache.hop.ui.core.dialog.EnterMappingDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PluginWidgetFactory;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -615,6 +616,7 @@ public class TeraFastDialog extends BaseTransformDialog {
     wlTable.setLayoutData(factory.createLabelLayoutData(topControl));
 
     this.wTable = factory.createSingleTextVarLeft();
+    this.wTable.enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(this.wTable);
     this.wTable.setLayoutData(factory.createControlLayoutData(topControl));
 
diff --git a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java
index a7945e9477..88c45dc5c4 100644
--- a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java
+++ b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java
@@ -51,6 +51,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -230,7 +231,9 @@ public class VerticaBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/engines/beam/src/main/java/org/apache/hop/beam/metadata/FileDefinitionEditor.java b/plugins/engines/beam/src/main/java/org/apache/hop/beam/metadata/FileDefinitionEditor.java
index c42421da60..014396ebbc 100644
--- a/plugins/engines/beam/src/main/java/org/apache/hop/beam/metadata/FileDefinitionEditor.java
+++ b/plugins/engines/beam/src/main/java/org/apache/hop/beam/metadata/FileDefinitionEditor.java
@@ -25,7 +25,9 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -42,7 +44,7 @@ public class FileDefinitionEditor extends MetadataEditor<FileDefinition> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private Text wSeparator;
   private Text wEnclosure;
@@ -72,7 +74,9 @@ public class FileDefinitionEditor extends MetadataEditor<FileDefinition> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
@@ -176,6 +180,7 @@ public class FileDefinitionEditor extends MetadataEditor<FileDefinition> {
               false,
               false),
         };
+    columnInfos[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/metadata/SparkCatalogEditor.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/metadata/SparkCatalogEditor.java
index c15e970f9c..3103f5a694 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/metadata/SparkCatalogEditor.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/metadata/SparkCatalogEditor.java
@@ -26,6 +26,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.gui.IGuiPluginCompositeButtonsListener;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -34,7 +36,6 @@ import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "Editor for Spark catalog metadata")
 public class SparkCatalogEditor extends MetadataEditor<SparkCatalog> {
@@ -43,7 +44,7 @@ public class SparkCatalogEditor extends MetadataEditor<SparkCatalog> {
 
   public static final String GUI_WIDGETS_PARENT_ID = "SparkCatalogEditor-GuiWidgetsParent";
 
-  private Text wName;
+  private TextVar wName;
   private Composite wWidgetsComposite;
   private GuiCompositeWidgets guiCompositeWidgets;
 
@@ -74,7 +75,9 @@ public class SparkCatalogEditor extends MetadataEditor<SparkCatalog> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileInputDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileInputDialog.java
index 21b47f1ec0..9d5b07b81d 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileInputDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileInputDialog.java
@@ -95,15 +95,14 @@ public class SparkFileInputDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     wFilePath = labeledTextVar(lsMod, middle, margin, last, "SparkFileInputDialog.FilePath");
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileOutputDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileOutputDialog.java
index ce6e042ef2..8b6f029e43 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileOutputDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/io/SparkFileOutputDialog.java
@@ -89,15 +89,14 @@ public class SparkFileOutputDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     last = labeledTextVar(lsMod, middle, margin, last, "SparkFileOutputDialog.FilePath");
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/sql/SparkSqlDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/sql/SparkSqlDialog.java
index 2d69734e71..23a837366b 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/sql/SparkSqlDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/sql/SparkSqlDialog.java
@@ -83,15 +83,14 @@ public class SparkSqlDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(e -> input.setChanged());
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(e -> input.setChanged());
     Control last = wTransformName;
 
     Label wlSql = new Label(shell, SWT.LEFT);
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableInputDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableInputDialog.java
index d1ecbd73bd..d6b2a1d65c 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableInputDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableInputDialog.java
@@ -98,15 +98,14 @@ public class SparkLakeTableInputDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     last = labeledCombo(lsMod, middle, margin, last, "SparkLakeTableInputDialog.Format", true);
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMaintenanceDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMaintenanceDialog.java
index 414ac7194e..8fce987c9d 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMaintenanceDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMaintenanceDialog.java
@@ -38,7 +38,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 public class SparkLakeTableMaintenanceDialog extends BaseTransformDialog {
   private static final Class<?> PKG = SparkLakeTableMaintenanceMeta.class;
@@ -93,15 +92,14 @@ public class SparkLakeTableMaintenanceDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     last = labeledCombo(lsMod, middle, margin, last, "SparkLakeTableMaintenanceDialog.Format");
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMergeDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMergeDialog.java
index e3a6ff9e02..6768b4a98d 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMergeDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableMergeDialog.java
@@ -92,15 +92,14 @@ public class SparkLakeTableMergeDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     last = labeledCombo(lsMod, middle, margin, last, "SparkLakeTableMergeDialog.Format");
diff --git a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableOutputDialog.java b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableOutputDialog.java
index a2da24a4cb..bbe24a6245 100644
--- a/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableOutputDialog.java
+++ b/plugins/engines/spark/src/main/java/org/apache/hop/spark/transforms/table/SparkLakeTableOutputDialog.java
@@ -91,15 +91,14 @@ public class SparkLakeTableOutputDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
     Control last = wTransformName;
 
     last = labeledCombo(lsMod, middle, margin, last, "SparkLakeTableOutputDialog.Format");
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/metadata/MailServerConnectionEditor.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/metadata/MailServerConnectionEditor.java
index 7829e0b357..a8be534a5f 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/metadata/MailServerConnectionEditor.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/metadata/MailServerConnectionEditor.java
@@ -27,6 +27,7 @@ import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.LabelTextVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -38,14 +39,13 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 public class MailServerConnectionEditor extends MetadataEditor<MailServerConnection> {
   private static final Class<?> PKG = MailServerConnectionEditor.class;
 
   private IVariables variables;
 
-  private Text wName;
+  private TextVar wName;
 
   private TextVar wServerHost;
 
@@ -97,7 +97,9 @@ public class MailServerConnectionEditor extends MetadataEditor<MailServerConnect
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOPDialog.java b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOPDialog.java
index 77635df189..263548fcaf 100644
--- a/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOPDialog.java
+++ b/plugins/misc/mail/src/main/java/org/apache/hop/mail/workflow/actions/getpop/ActionGetPOPDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -496,7 +497,9 @@ public class ActionGetPOPDialog extends ActionDialog {
     wbDirectory.addListener(
         SWT.Selection, e -> BaseDialog.presentDirectoryDialog(shell, wOutputDirectory, variables));
 
-    wOutputDirectory = new TextVar(variables, wTargetFolder, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wOutputDirectory =
+        new TextVar(variables, wTargetFolder, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wOutputDirectory);
     wOutputDirectory.setToolTipText(
         BaseMessages.getString(PKG, "ActionGetPOP.OutputDirectory.Tooltip"));
diff --git a/plugins/misc/pom.xml b/plugins/misc/naming/pom.xml
similarity index 62%
copy from plugins/misc/pom.xml
copy to plugins/misc/naming/pom.xml
index 769a470002..ee6b32223d 100644
--- a/plugins/misc/pom.xml
+++ b/plugins/misc/naming/pom.xml
@@ -14,37 +14,19 @@
   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
+  ~
   -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
         <groupId>org.apache.hop</groupId>
-        <artifactId>hop-plugins</artifactId>
+        <artifactId>hop-plugins-misc</artifactId>
         <version>2.20.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>hop-plugins-misc</artifactId>
-    <packaging>pom</packaging>
-    <name>Hop Plugins Miscellaneous</name>
-
-    <modules>
-        <module>debug</module>
-        <module>documentation</module>
-        <module>execution-database</module>
-        <module>git</module>
-        <module>import</module>
-        <module>lint</module>
-        <module>mail</module>
-        <module>marketplace</module>
-        <module>passwords</module>
-        <module>projects</module>
-        <module>py4j</module>
-        <module>reflection</module>
-        <module>rest</module>
-        <module>setup</module>
-        <module>static-schema</module>
-        <module>testing</module>
-    </modules>
+    <artifactId>hop-misc-naming</artifactId>
+    <packaging>jar</packaging>
+    <name>Hop Naming Scheme</name>
 
 </project>
diff --git a/plugins/misc/naming/src/assembly/assembly.xml b/plugins/misc/naming/src/assembly/assembly.xml
new file mode 100644
index 0000000000..3bb294e56e
--- /dev/null
+++ b/plugins/misc/naming/src/assembly/assembly.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
+    <id>hop-misc-naming</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <baseDirectory>.</baseDirectory>
+    <dependencySets>
+        <dependencySet>
+            <includes>
+                <include>org.apache.hop:hop-misc-naming:jar</include>
+            </includes>
+            <outputDirectory>lib/core</outputDirectory>
+        </dependencySet>
+    </dependencySets>
+</assembly>
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/command/HopNamingCheck.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/command/HopNamingCheck.java
new file mode 100644
index 0000000000..0ea6f09b46
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/command/HopNamingCheck.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.command;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSelector;
+import org.apache.hop.core.Const;
+import org.apache.hop.core.HopVersionProvider;
+import org.apache.hop.core.config.plugin.ConfigPlugin;
+import org.apache.hop.core.config.plugin.IConfigOptions;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.logging.LogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.core.vfs.HopVfs;
+import org.apache.hop.hop.Hop;
+import org.apache.hop.hop.plugin.HopCommand;
+import org.apache.hop.hop.plugin.IHopCommand;
+import org.apache.hop.metadata.api.IHasHopMetadataProvider;
+import org.apache.hop.metadata.api.IHopMetadata;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.serializer.multi.MultiMetadataProvider;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Finding;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Severity;
+import org.apache.hop.naming.engine.NamingSchemeWalker;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.workflow.WorkflowMeta;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Getter
+@Setter
+@HopCommand(id = "naming-check", description = "Validate names against Naming Schemes")
+@Command(
+    versionProvider = HopVersionProvider.class,
+    mixinStandardHelpOptions = true,
+    description = "Validate names against project Naming Schemes")
+public class HopNamingCheck implements Runnable, IHopCommand, IHasHopMetadataProvider {
+
+  @Option(
+      names = {"-v", "--version"},
+      versionHelp = true,
+      description = "Print version information and exit")
+  private boolean versionRequested;
+
+  @Option(
+      names = {"-p", "--path"},
+      description = "Folder to scan for .hpl and .hwf files (defaults to PROJECT_HOME or cwd)")
+  private String path;
+
+  @Option(
+      names = {"-t", "--type"},
+      description = "Comma-separated naming type codes to check (default: all)")
+  private String types;
+
+  @Option(
+      names = {"--require-scheme"},
+      description = "Treat missing schemes as errors instead of warnings")
+  private boolean requireScheme;
+
+  @Option(
+      names = {"--format"},
+      description = "Output format: text or json (default: text)")
+  private String format = "text";
+
+  private CommandLine cmd;
+  private IVariables variables;
+  private MultiMetadataProvider metadataProvider;
+
+  @Override
+  public void initialize(
+      CommandLine cmd, IVariables variables, MultiMetadataProvider metadataProvider)
+      throws HopException {
+    this.cmd = cmd;
+    this.variables = variables;
+    this.metadataProvider = metadataProvider;
+    Hop.addMixinPlugins(cmd, ConfigPlugin.CATEGORY_NAMING);
+  }
+
+  @Override
+  public void run() {
+    try {
+      System.setProperty(Const.HOP_PLATFORM_RUNTIME, "NAMING_CHECK");
+      ILogChannel log = new LogChannel("hop-naming-check");
+      ((LogChannel) log).setSimplified(true);
+
+      for (Object mixin : cmd.getMixins().values()) {
+        if (mixin instanceof IConfigOptions options) {
+          options.handleOption(log, this, variables);
+        }
+      }
+
+      List<NamingScheme> schemes = loadSchemes();
+      Set<String> typeFilter = parseTypes();
+      List<Finding> findings = new ArrayList<>();
+
+      String scanRoot = resolveScanRoot();
+      scanPipelinesAndWorkflows(scanRoot, schemes, typeFilter, findings);
+      scanMetadata(schemes, typeFilter, findings);
+
+      printFindings(findings);
+      int errors = 0;
+      int warnings = 0;
+      for (Finding finding : findings) {
+        if (finding.getSeverity() == Severity.ERROR
+            || (requireScheme && finding.getSeverity() == Severity.WARNING)) {
+          errors++;
+        } else {
+          warnings++;
+        }
+      }
+      if (!"json".equalsIgnoreCase(format)) {
+        System.out.println("Naming check: " + errors + " error(s), " + warnings + " warning(s)");
+      }
+      System.exit(errors > 0 ? 1 : 0);
+    } catch (Exception e) {
+      System.err.println(Const.getStackTracker(e));
+      System.exit(2);
+    }
+  }
+
+  private List<NamingScheme> loadSchemes() throws HopException {
+    if (metadataProvider == null) {
+      return List.of();
+    }
+    return metadataProvider.getSerializer(NamingScheme.class).loadAll();
+  }
+
+  private Set<String> parseTypes() {
+    Set<String> filter = new HashSet<>();
+    if (StringUtils.isNotEmpty(types)) {
+      Arrays.stream(types.split(","))
+          .map(String::trim)
+          .filter(StringUtils::isNotEmpty)
+          .forEach(filter::add);
+    }
+    return filter;
+  }
+
+  private String resolveScanRoot() {
+    if (StringUtils.isNotEmpty(path)) {
+      return variables.resolve(path);
+    }
+    String home = variables.getVariable("PROJECT_HOME");
+    if (StringUtils.isEmpty(home)) {
+      home = variables.getVariable(Const.HOP_METADATA_FOLDER);
+    }
+    if (StringUtils.isEmpty(home)) {
+      home = ".";
+    }
+    return variables.resolve(home);
+  }
+
+  private void scanPipelinesAndWorkflows(
+      String root, List<NamingScheme> schemes, Set<String> typeFilter, List<Finding> findings)
+      throws Exception {
+    FileObject folder = HopVfs.getFileObject(root);
+    if (!folder.exists()) {
+      return;
+    }
+    FileObject[] files =
+        folder.findFiles(
+            new FileSelector() {
+              @Override
+              public boolean includeFile(FileSelectInfo fileInfo) {
+                String name = fileInfo.getFile().getName().getBaseName().toLowerCase();
+                return name.endsWith(".hpl") || name.endsWith(".hwf");
+              }
+
+              @Override
+              public boolean traverseDescendents(FileSelectInfo fileInfo) {
+                return true;
+              }
+            });
+    if (files == null) {
+      return;
+    }
+    for (FileObject file : files) {
+      String filename = HopVfs.getFilename(file);
+      try {
+        if (filename.toLowerCase().endsWith(".hpl")) {
+          PipelineMeta pipeline = new PipelineMeta(filename, metadataProvider, variables);
+          findings.addAll(NamingSchemeWalker.walk(pipeline, filename, schemes, typeFilter));
+        } else {
+          WorkflowMeta workflow = new WorkflowMeta(variables, filename, metadataProvider);
+          findings.addAll(NamingSchemeWalker.walk(workflow, filename, schemes, typeFilter));
+        }
+      } catch (Exception e) {
+        Finding load = new Finding();
+        load.setLocation(filename);
+        load.setFieldPath("");
+        load.setSeverity(Severity.WARNING);
+        load.setMessage("Could not load file: " + e.getMessage());
+        findings.add(load);
+      }
+    }
+  }
+
+  private void scanMetadata(
+      List<NamingScheme> schemes, Set<String> typeFilter, List<Finding> findings)
+      throws HopException {
+    if (metadataProvider == null) {
+      return;
+    }
+    for (Class<IHopMetadata> clazz : metadataProvider.getMetadataClasses()) {
+      if (NamingScheme.class.isAssignableFrom(clazz)) {
+        continue;
+      }
+      IHopMetadataProvider provider = metadataProvider;
+      for (IHopMetadata object : provider.getSerializer(clazz).loadAll()) {
+        String location = "metadata/" + clazz.getSimpleName() + "/" + object.getName();
+        findings.addAll(NamingSchemeWalker.walk(object, location, schemes, typeFilter));
+      }
+    }
+  }
+
+  private void printFindings(List<Finding> findings) {
+    if ("json".equalsIgnoreCase(format)) {
+      System.out.println("[");
+      for (int i = 0; i < findings.size(); i++) {
+        Finding f = findings.get(i);
+        System.out.print(
+            "  {\"severity\":\""
+                + f.getSeverity()
+                + "\",\"location\":"
+                + json(f.getLocation())
+                + ",\"field\":"
+                + json(f.getFieldPath())
+                + ",\"type\":"
+                + json(f.getTypeCode())
+                + ",\"scheme\":"
+                + json(f.getSchemeName())
+                + ",\"actual\":"
+                + json(f.getActual())
+                + ",\"expected\":"
+                + json(f.getExpected())
+                + ",\"message\":"
+                + json(f.getMessage())
+                + "}");
+        System.out.println(i < findings.size() - 1 ? "," : "");
+      }
+      System.out.println("]");
+      return;
+    }
+    for (Finding f : findings) {
+      System.out.println(
+          f.getSeverity()
+              + " "
+              + Const.NVL(f.getLocation(), "")
+              + " "
+              + Const.NVL(f.getFieldPath(), "")
+              + " : "
+              + f.getMessage());
+    }
+  }
+
+  private static String json(String value) {
+    if (value == null) {
+      return "null";
+    }
+    return "\""
+        + value
+            .replace("\\", "\\\\")
+            .replace("\"", "\\\"")
+            .replace("\n", "\\n")
+            .replace("\r", "\\r")
+            .replace("\t", "\\t")
+        + "\"";
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingEngine.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingEngine.java
new file mode 100644
index 0000000000..49cfdf923f
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingEngine.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.naming.NamingSchemeKinds;
+import org.apache.hop.naming.metadata.NamingCaseStyle;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingWordSeparator;
+
+/**
+ * Pure string transform that applies a {@link NamingScheme} to an input name. No UI or metadata
+ * provider dependencies — safe to unit-test and reuse from transforms later.
+ */
+public final class NamingEngine {
+
+  private NamingEngine() {
+    // utility
+  }
+
+  /**
+   * Names that must not be rewritten: empty, table null markers, and values that already contain a
+   * variable expression.
+   */
+  public static boolean shouldSkip(String value) {
+    if (StringUtils.isEmpty(value) || "<null>".equals(value)) {
+      return true;
+    }
+    return value.contains("${");
+  }
+
+  /**
+   * Apply the scheme as an identifier. Prefer {@link #apply(NamingScheme, String, String)} when the
+   * widget kind is known so file/folder paths keep their parent and (for files) extension.
+   */
+  public static String apply(NamingScheme scheme, String input) {
+    return apply(scheme, input, scheme != null ? scheme.getType() : null);
+  }
+
+  /**
+   * Apply the scheme using {@code kind} to decide path handling. {@code kind} is the widget/field
+   * type ({@code file}, {@code folder}, {@code hop-field}, …), not necessarily the scheme's own
+   * type — a General scheme on a file widget still rewrites only the last path segment.
+   */
+  public static String apply(NamingScheme scheme, String input, String kind) {
+    if (input == null) {
+      return null;
+    }
+    if (input.isEmpty()) {
+      return input;
+    }
+
+    NamingScheme effective = scheme != null ? scheme : new NamingScheme();
+    if (NamingSchemeKinds.isFile(kind)) {
+      return applyToLastSegment(effective, input, true);
+    }
+    if (NamingSchemeKinds.isFolder(kind)) {
+      return applyToLastSegment(effective, input, false);
+    }
+    return applyToIdentifier(effective, input);
+  }
+
+  private static String applyToLastSegment(
+      NamingScheme scheme, String input, boolean preserveExtension) {
+    boolean trailingSlash = input.endsWith("/") || input.endsWith("\\");
+    String working = trailingSlash ? input.substring(0, input.length() - 1) : input;
+    if (working.isEmpty()) {
+      return input;
+    }
+
+    int lastSep = Math.max(working.lastIndexOf('/'), working.lastIndexOf('\\'));
+    String parent = lastSep >= 0 ? working.substring(0, lastSep + 1) : "";
+    String segment = lastSep >= 0 ? working.substring(lastSep + 1) : working;
+    String extension = "";
+    if (preserveExtension) {
+      int dot = segment.lastIndexOf('.');
+      if (dot > 0) {
+        extension = segment.substring(dot);
+        segment = segment.substring(0, dot);
+      }
+    }
+    if (segment.isEmpty()) {
+      return input;
+    }
+
+    String rewritten = applyToIdentifier(scheme, segment);
+    String slash = trailingSlash ? String.valueOf(input.charAt(input.length() - 1)) : "";
+    return parent + rewritten + extension + slash;
+  }
+
+  private static String applyToIdentifier(NamingScheme effective, String input) {
+    NamingCaseStyle caseStyle = NamingCaseStyle.fromCode(effective.getCaseStyle());
+    NamingWordSeparator wordSeparator = NamingWordSeparator.fromCode(effective.getWordSeparator());
+
+    List<String> words = splitWords(input, effective.getExtraDelimiters());
+    if (effective.isRemoveSpecialCharacters()) {
+      words = removeSpecialCharacters(words);
+    }
+    if (words.isEmpty()) {
+      return applyAffixes(effective, "");
+    }
+
+    String joined = joinWords(words, caseStyle, wordSeparator);
+    joined = postProcessSeparators(joined, wordSeparator, effective);
+    if (effective.isCapitalizeFirstWord()) {
+      joined = capitalizeFirstWord(joined);
+    }
+    return applyAffixes(effective, joined);
+  }
+
+  /** Uppercase the first character of {@code value} (the start of the first word). */
+  static String capitalizeFirstWord(String value) {
+    if (value.isEmpty()) {
+      return value;
+    }
+    char first = value.charAt(0);
+    char upper = Character.toUpperCase(first);
+    if (first == upper) {
+      return value;
+    }
+    return upper + value.substring(1);
+  }
+
+  static List<String> splitWords(String input, String extraDelimiters) {
+    String prepared = insertCamelCaseBoundaries(input.trim());
+    StringBuilder delimiters = new StringBuilder(" \t\n\r_-");
+    if (StringUtils.isNotEmpty(extraDelimiters)) {
+      delimiters.append(extraDelimiters);
+    }
+
+    List<String> words = new ArrayList<>();
+    StringBuilder current = new StringBuilder();
+    for (int i = 0; i < prepared.length(); i++) {
+      char c = prepared.charAt(i);
+      if (delimiters.indexOf(String.valueOf(c)) >= 0) {
+        if (!current.isEmpty()) {
+          words.add(current.toString());
+          current.setLength(0);
+        }
+      } else {
+        current.append(c);
+      }
+    }
+    if (!current.isEmpty()) {
+      words.add(current.toString());
+    }
+    return words;
+  }
+
+  /**
+   * Insert spaces at camelCase and letter/digit boundaries so later delimiter splitting sees
+   * separate words. Acronyms: {@code XMLParser} → {@code XML Parser}.
+   */
+  static String insertCamelCaseBoundaries(String input) {
+    if (input.length() < 2) {
+      return input;
+    }
+    StringBuilder sb = new StringBuilder(input.length() + 8);
+    for (int i = 0; i < input.length(); i++) {
+      char c = input.charAt(i);
+      if (i > 0) {
+        char prev = input.charAt(i - 1);
+        char next = i + 1 < input.length() ? input.charAt(i + 1) : 0;
+        boolean lowerThenUpper = Character.isLowerCase(prev) && Character.isUpperCase(c);
+        boolean acronymBoundary =
+            Character.isUpperCase(prev)
+                && Character.isUpperCase(c)
+                && next != 0
+                && Character.isLowerCase(next);
+        boolean letterDigit =
+            (Character.isLetter(prev) && Character.isDigit(c))
+                || (Character.isDigit(prev) && Character.isLetter(c));
+        if (lowerThenUpper || acronymBoundary || letterDigit) {
+          sb.append(' ');
+        }
+      }
+      sb.append(c);
+    }
+    return sb.toString();
+  }
+
+  private static List<String> removeSpecialCharacters(List<String> words) {
+    List<String> cleaned = new ArrayList<>();
+    for (String word : words) {
+      StringBuilder sb = new StringBuilder(word.length());
+      for (int i = 0; i < word.length(); i++) {
+        char c = word.charAt(i);
+        if (Character.isLetterOrDigit(c)) {
+          sb.append(c);
+        }
+      }
+      if (!sb.isEmpty()) {
+        cleaned.add(sb.toString());
+      }
+    }
+    return cleaned;
+  }
+
+  private static String joinWords(
+      List<String> words, NamingCaseStyle caseStyle, NamingWordSeparator wordSeparator) {
+    if (caseStyle == NamingCaseStyle.CAMEL || caseStyle == NamingCaseStyle.PASCAL) {
+      return joinCamel(words, caseStyle == NamingCaseStyle.PASCAL);
+    }
+
+    String sep = wordSeparator.getValue();
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < words.size(); i++) {
+      if (i > 0 && !sep.isEmpty()) {
+        sb.append(sep);
+      }
+      sb.append(applyCaseToWord(words.get(i), caseStyle));
+    }
+    return sb.toString();
+  }
+
+  private static String joinCamel(List<String> words, boolean pascal) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < words.size(); i++) {
+      String word = words.get(i);
+      if (word.isEmpty()) {
+        continue;
+      }
+      String lower = word.toLowerCase(Locale.ROOT);
+      if (i == 0 && !pascal) {
+        sb.append(lower);
+      } else {
+        sb.append(Character.toUpperCase(lower.charAt(0)));
+        if (lower.length() > 1) {
+          sb.append(lower.substring(1));
+        }
+      }
+    }
+    return sb.toString();
+  }
+
+  private static String applyCaseToWord(String word, NamingCaseStyle caseStyle) {
+    return switch (caseStyle) {
+      case LOWER -> word.toLowerCase(Locale.ROOT);
+      case UPPER -> word.toUpperCase(Locale.ROOT);
+      default -> word; // AS_IS
+    };
+  }
+
+  private static String postProcessSeparators(
+      String joined, NamingWordSeparator wordSeparator, NamingScheme scheme) {
+    String result = joined;
+    String sep = wordSeparator.getValue();
+    if (StringUtils.isNotEmpty(sep)) {
+      if (scheme.isCollapseRepeatedSeparators()) {
+        String doubled = sep + sep;
+        while (result.contains(doubled)) {
+          result = result.replace(doubled, sep);
+        }
+      }
+      if (scheme.isTrimEdgeSeparators()) {
+        while (result.startsWith(sep)) {
+          result = result.substring(sep.length());
+        }
+        while (result.endsWith(sep)) {
+          result = result.substring(0, result.length() - sep.length());
+        }
+      }
+    }
+    return result;
+  }
+
+  private static String applyAffixes(NamingScheme scheme, String value) {
+    String prefix = StringUtils.defaultString(scheme.getPrefix());
+    String suffix = StringUtils.defaultString(scheme.getSuffix());
+    return prefix + value + suffix;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeCheckRemarks.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeCheckRemarks.java
new file mode 100644
index 0000000000..fede11733a
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeCheckRemarks.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import java.util.List;
+import org.apache.hop.core.CheckResult;
+import org.apache.hop.core.Const;
+import org.apache.hop.core.ICheckResult;
+import org.apache.hop.core.ICheckResultSource;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Finding;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Severity;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.workflow.WorkflowMeta;
+import org.apache.hop.workflow.action.ActionMeta;
+import org.apache.hop.workflow.action.IAction;
+
+/** Adds naming-scheme Verify remarks using the same walker as {@code hop naming-check}. */
+public final class NamingSchemeCheckRemarks {
+
+  private NamingSchemeCheckRemarks() {
+    // utility
+  }
+
+  public static void addRemarks(
+      Object root, String location, List<ICheckResult> remarks, IHopMetadataProvider provider) {
+    if (root == null || remarks == null || provider == null) {
+      return;
+    }
+    try {
+      List<NamingScheme> schemes = provider.getSerializer(NamingScheme.class).loadAll();
+      if (schemes == null || schemes.isEmpty()) {
+        return;
+      }
+      for (Finding finding : NamingSchemeWalker.walk(root, location, schemes, null)) {
+        if (finding.getSeverity() != Severity.ERROR) {
+          continue;
+        }
+        remarks.add(
+            new CheckResult(
+                ICheckResult.TYPE_RESULT_ERROR, finding.getMessage(), sourceOf(root, finding)));
+      }
+    } catch (Exception e) {
+      // Verify must still complete when naming metadata is unavailable
+    }
+  }
+
+  private static ICheckResultSource sourceOf(Object root, Finding finding) {
+    String type = Const.NVL(finding.getTypeCode(), "");
+    String actual = finding.getActual();
+    if ("hop-transform".equals(type) && root instanceof PipelineMeta pipeline) {
+      TransformMeta transform = pipeline.findTransform(actual);
+      if (transform != null) {
+        return transform;
+      }
+    }
+    if ("hop-action".equals(type) && root instanceof WorkflowMeta workflow) {
+      ActionMeta actionMeta = workflow.findAction(actual);
+      if (actionMeta != null) {
+        IAction action = actionMeta.getAction();
+        if (action instanceof ICheckResultSource source) {
+          return source;
+        }
+      }
+    }
+    return root instanceof ICheckResultSource source ? source : null;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeValidator.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeValidator.java
new file mode 100644
index 0000000000..a289523c74
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeValidator.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Getter;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeSelector;
+
+/** Fixed-point check: a name is valid when applying the scheme does not change it. */
+public final class NamingSchemeValidator {
+
+  private NamingSchemeValidator() {
+    // utility
+  }
+
+  /**
+   * @param value current name
+   * @param typeCode naming kind code
+   * @param schemes all project schemes
+   * @return empty if valid or skipped; otherwise one finding per scheme that would rewrite
+   */
+  public static List<Finding> validate(
+      String value, String typeCode, Iterable<NamingScheme> schemes) {
+    List<Finding> findings = new ArrayList<>();
+    if (NamingEngine.shouldSkip(value)) {
+      return findings;
+    }
+    List<NamingScheme> applicable = NamingSchemeSelector.matching(schemes, typeCode);
+    if (applicable.isEmpty()) {
+      Finding none = new Finding();
+      none.severity = Severity.WARNING;
+      none.typeCode = typeCode;
+      none.actual = value;
+      none.message = "No naming scheme of type '" + typeCode + "' (and no General scheme)";
+      findings.add(none);
+      return findings;
+    }
+    for (NamingScheme scheme : applicable) {
+      String expected = NamingEngine.apply(scheme, value, typeCode);
+      if (expected != null && !expected.equals(value)) {
+        Finding finding = new Finding();
+        finding.severity = Severity.ERROR;
+        finding.typeCode = typeCode;
+        finding.schemeName = scheme.getName();
+        finding.actual = value;
+        finding.expected = expected;
+        finding.message =
+            "Name '"
+                + value
+                + "' does not match scheme '"
+                + scheme.getName()
+                + "' (expected '"
+                + expected
+                + "')";
+        findings.add(finding);
+      }
+    }
+    return findings;
+  }
+
+  public enum Severity {
+    WARNING,
+    ERROR
+  }
+
+  @Getter
+  @lombok.Setter
+  public static class Finding {
+    private Severity severity = Severity.ERROR;
+    private String location;
+    private String fieldPath;
+    private String typeCode;
+    private String schemeName;
+    private String actual;
+    private String expected;
+    private String message;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeWalker.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeWalker.java
new file mode 100644
index 0000000000..a51d5c20b7
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/engine/NamingSchemeWalker.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.naming.NamingSchemeKinds;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+import org.apache.hop.metadata.api.IHasName;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Finding;
+import org.apache.hop.naming.metadata.NamingScheme;
+
+/** Walks {@code @HopMetadataProperty} graphs and validates annotated names. */
+public final class NamingSchemeWalker {
+
+  private NamingSchemeWalker() {
+    // utility
+  }
+
+  public static List<Finding> walk(
+      Object root, String location, Iterable<NamingScheme> schemes, Set<String> typeFilter) {
+    List<Finding> out = new ArrayList<>();
+    visit(root, location, "", schemes, typeFilter, out, new IdentityHashMap<>());
+    return out;
+  }
+
+  private static void visit(
+      Object node,
+      String location,
+      String path,
+      Iterable<NamingScheme> schemes,
+      Set<String> typeFilter,
+      List<Finding> out,
+      IdentityHashMap<Object, Boolean> seen) {
+    if (node == null
+        || node.getClass().isPrimitive()
+        || node instanceof Number
+        || node instanceof Boolean) {
+      return;
+    }
+    if (node instanceof String || node instanceof Enum || node instanceof Class) {
+      return;
+    }
+    if (seen.put(node, Boolean.TRUE) != null) {
+      return;
+    }
+
+    String identityKind = identityKind(node);
+    if (StringUtils.isNotEmpty(identityKind)) {
+      String identity = identityName(node);
+      if (identity != null) {
+        collect(location, join(path, "name"), identityKind, identity, schemes, typeFilter, out);
+      }
+    }
+
+    if (node instanceof Collection<?> collection) {
+      int i = 0;
+      for (Object item : collection) {
+        visit(item, location, path + "[" + i++ + "]", schemes, typeFilter, out, seen);
+      }
+      return;
+    }
+    if (node instanceof Map<?, ?> map) {
+      for (Map.Entry<?, ?> entry : map.entrySet()) {
+        visit(
+            entry.getValue(),
+            location,
+            path + "[" + entry.getKey() + "]",
+            schemes,
+            typeFilter,
+            out,
+            seen);
+      }
+      return;
+    }
+    if (node.getClass().isArray()) {
+      if (node.getClass().getComponentType().isPrimitive()) {
+        return;
+      }
+      Object[] array = (Object[]) node;
+      for (int i = 0; i < array.length; i++) {
+        visit(array[i], location, path + "[" + i + "]", schemes, typeFilter, out, seen);
+      }
+      return;
+    }
+
+    Class<?> type = node.getClass();
+    while (type != null && type != Object.class) {
+      for (Field field : type.getDeclaredFields()) {
+        HopMetadataProperty prop = field.getAnnotation(HopMetadataProperty.class);
+        if (prop == null) {
+          continue;
+        }
+        Object value;
+        try {
+          field.setAccessible(true);
+          value = field.get(node);
+        } catch (Exception e) {
+          continue;
+        }
+        String fieldKind = prop.namingSchemeType();
+        if (StringUtils.isNotEmpty(fieldKind)
+            && value instanceof String string
+            && !"name".equals(field.getName())) {
+          collect(
+              location, join(path, field.getName()), fieldKind, string, schemes, typeFilter, out);
+        }
+        if (value != null && !(value instanceof String)) {
+          visit(value, location, join(path, field.getName()), schemes, typeFilter, out, seen);
+        }
+      }
+      type = type.getSuperclass();
+    }
+  }
+
+  private static void collect(
+      String location,
+      String fieldPath,
+      String typeCode,
+      String value,
+      Iterable<NamingScheme> schemes,
+      Set<String> typeFilter,
+      List<Finding> out) {
+    if (typeFilter != null && !typeFilter.isEmpty() && !typeFilter.contains(typeCode)) {
+      return;
+    }
+    for (Finding finding : NamingSchemeValidator.validate(value, typeCode, schemes)) {
+      finding.setLocation(location);
+      finding.setFieldPath(fieldPath);
+      out.add(finding);
+    }
+  }
+
+  /** Field-level {@code namingSchemeType} on {@code name} wins over {@link NamingSchemeKinds}. */
+  private static String identityKind(Object node) {
+    Class<?> type = node.getClass();
+    while (type != null && type != Object.class) {
+      try {
+        java.lang.reflect.Field nameField = type.getDeclaredField("name");
+        HopMetadataProperty prop = nameField.getAnnotation(HopMetadataProperty.class);
+        if (prop != null && StringUtils.isNotEmpty(prop.namingSchemeType())) {
+          return prop.namingSchemeType();
+        }
+      } catch (NoSuchFieldException ignored) {
+        // look on superclass
+      }
+      type = type.getSuperclass();
+    }
+    return NamingSchemeKinds.kindOf(node.getClass());
+  }
+
+  private static String identityName(Object node) {
+    if (node instanceof IHasName named) {
+      return named.getName();
+    }
+    try {
+      Object value = node.getClass().getMethod("getName").invoke(node);
+      return value instanceof String string ? string : null;
+    } catch (Exception e) {
+      return null;
+    }
+  }
+
+  private static String join(String path, String name) {
+    if (StringUtils.isEmpty(path)) {
+      return name;
+    }
+    return path + "/" + name;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeColumnApplier.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeColumnApplier.java
new file mode 100644
index 0000000000..b0c54526a7
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeColumnApplier.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.naming.engine.NamingEngine;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeSelector;
+import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.INamingSchemeColumnApplier;
+import org.apache.hop.ui.core.widget.TableView;
+import org.eclipse.swt.widgets.TableItem;
+
+/** Applies a naming scheme to TableView columns that declared a naming type (Get Fields). */
+public final class NamingSchemeColumnApplier implements INamingSchemeColumnApplier {
+
+  static final NamingSchemeColumnApplier INSTANCE = new NamingSchemeColumnApplier();
+
+  private NamingSchemeColumnApplier() {
+    // singleton used from HopGuiStart
+  }
+
+  @Override
+  public void applyAnnotatedColumns(
+      TableView tableView, IHopMetadataProvider provider, String schemeName) {
+    if (tableView == null || tableView.isDisposed() || provider == null) {
+      return;
+    }
+    ColumnInfo[] columns = tableView.getColumns();
+    if (columns == null || columns.length == 0) {
+      return;
+    }
+    try {
+      IHopMetadataSerializer<NamingScheme> serializer = provider.getSerializer(NamingScheme.class);
+      List<NamingScheme> all = serializer.loadAll();
+      int offset = tableView.hasIndexColumn() ? 1 : 0;
+      for (int i = 0; i < columns.length; i++) {
+        String typeCode = columns[i].getNamingSchemeType();
+        if (StringUtils.isEmpty(typeCode)) {
+          continue;
+        }
+        NamingScheme scheme = NamingSchemeSelector.resolve(all, typeCode, schemeName);
+        if (scheme == null) {
+          continue;
+        }
+        applyColumn(tableView, i + offset, scheme, typeCode);
+      }
+    } catch (Exception e) {
+      // Get Fields should still succeed when metadata is unavailable
+    }
+  }
+
+  private static void applyColumn(
+      TableView tableView, int colNr, NamingScheme scheme, String typeCode) {
+    List<TableItem> items = tableView.getNonEmptyItems();
+    if (items.isEmpty()) {
+      return;
+    }
+    int[] rowIndices = new int[items.size()];
+    String[] newValues = new String[items.size()];
+    boolean changed = false;
+    for (int i = 0; i < items.size(); i++) {
+      TableItem item = items.get(i);
+      rowIndices[i] = tableView.getTable().indexOf(item);
+      String current = item.getText(colNr);
+      if (NamingSchemeShortcut.shouldSkip(current)) {
+        newValues[i] = current;
+      } else {
+        String rewritten = NamingEngine.apply(scheme, current, typeCode);
+        newValues[i] = rewritten != null ? rewritten : current;
+        changed |= !current.equals(newValues[i]);
+      }
+    }
+    if (changed) {
+      tableView.applyColumnValues(colNr, rowIndices, newValues);
+    }
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemePipelineCheckExtension.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemePipelineCheckExtension.java
new file mode 100644
index 0000000000..1856642f35
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemePipelineCheckExtension.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import org.apache.hop.core.Const;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.extension.ExtensionPoint;
+import org.apache.hop.core.extension.IExtensionPoint;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.naming.engine.NamingSchemeCheckRemarks;
+import org.apache.hop.pipeline.CheckTransformsExtension;
+import org.apache.hop.pipeline.PipelineMeta;
+
+/** Adds naming-scheme errors to pipeline Verify (same rules as {@code hop naming-check}). */
+@ExtensionPoint(
+    id = "NamingSchemeAfterCheckTransforms",
+    description = "Add naming-scheme remarks after pipeline verify",
+    extensionPointId = "AfterCheckTransforms")
+public class NamingSchemePipelineCheckExtension
+    implements IExtensionPoint<CheckTransformsExtension> {
+
+  @Override
+  public void callExtensionPoint(
+      ILogChannel log, IVariables variables, CheckTransformsExtension extension)
+      throws HopException {
+    if (extension == null || extension.getPipelineMeta() == null) {
+      return;
+    }
+    PipelineMeta pipeline = extension.getPipelineMeta();
+    String location = Const.NVL(pipeline.getFilename(), Const.NVL(pipeline.getName(), "pipeline"));
+    NamingSchemeCheckRemarks.addRemarks(
+        pipeline, location, extension.getRemarks(), extension.getMetadataProvider());
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeShortcut.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeShortcut.java
new file mode 100644
index 0000000000..604823f46a
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeShortcut.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.extension.ExtensionPoint;
+import org.apache.hop.core.extension.IExtensionPoint;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.naming.engine.NamingEngine;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeSelector;
+import org.apache.hop.naming.metadata.NamingSchemeType;
+import org.apache.hop.naming.metadata.NamingWordSeparator;
+import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
+import org.apache.hop.ui.core.dialog.ErrorDialog;
+import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.ITextWidgetShortcut;
+import org.apache.hop.ui.core.widget.NamingSchemeColumnApplierRegistry;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.OsHelper;
+import org.apache.hop.ui.core.widget.TextWidgetShortcutContext;
+import org.apache.hop.ui.core.widget.TextWidgetShortcutRegistry;
+import org.apache.hop.ui.hopgui.HopGui;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Registers the naming-scheme keyboard shortcut (CTRL-SHIFT-N, and CTRL-SPACE when variables are
+ * disabled) on Hop Gui start.
+ */
+@ExtensionPoint(
+    id = "NamingSchemeShortcutRegister",
+    description = "Register the TextVar naming-scheme shortcut",
+    extensionPointId = "HopGuiStart")
+public class NamingSchemeShortcut implements IExtensionPoint, ITextWidgetShortcut {
+
+  private static final Class<?> PKG = NamingSchemeShortcut.class;
+
+  static final NamingSchemeShortcut INSTANCE = new NamingSchemeShortcut();
+
+  /** Last scheme name chosen per type code. */
+  private final Map<String, String> lastUsedByType = new ConcurrentHashMap<>();
+
+  @Override
+  public void callExtensionPoint(ILogChannel log, IVariables variables, Object hopGui)
+      throws HopException {
+    TextWidgetShortcutRegistry.getInstance().register(INSTANCE);
+    NamingSchemeColumnApplierRegistry.getInstance().register(NamingSchemeColumnApplier.INSTANCE);
+  }
+
+  @Override
+  public boolean isHotKey(KeyEvent event, boolean variablesEnabled) {
+    if (isApplyShortcut(event)) {
+      return true;
+    }
+    return !variablesEnabled && isControlSpace(event);
+  }
+
+  @Override
+  public void apply(TextWidgetShortcutContext context) {
+    if (context == null || context.getGetText() == null || context.getSetText() == null) {
+      return;
+    }
+    String current = context.getGetText().get();
+    if (shouldSkip(current)) {
+      return;
+    }
+
+    String typeCode = context.getNamingSchemeType();
+    if (StringUtils.isEmpty(typeCode)) {
+      return;
+    }
+    Shell shell = context.getShell();
+    if (shell == null || shell.isDisposed()) {
+      return;
+    }
+
+    try {
+      List<NamingScheme> schemes = loadSchemes(typeCode);
+      if (schemes.isEmpty()) {
+        return;
+      }
+
+      NamingScheme chosen = pickScheme(shell, schemes, typeCode, current);
+      if (chosen == null) {
+        return;
+      }
+      rememberLastUsed(typeCode, chosen.getName());
+      String rewritten = NamingEngine.apply(chosen, current, typeCode);
+      if (rewritten != null && !rewritten.equals(current)) {
+        context.getSetText().accept(rewritten);
+      }
+    } catch (Exception e) {
+      new ErrorDialog(
+          shell,
+          BaseMessages.getString(PKG, "Naming.Error.Title"),
+          BaseMessages.getString(PKG, "Naming.Error.Message"),
+          e);
+    }
+  }
+
+  @Override
+  public void onIndicatorClick(TextWidgetShortcutContext context) {
+    if (context == null) {
+      return;
+    }
+    Shell shell = context.getShell();
+    if (shell == null || shell.isDisposed()) {
+      return;
+    }
+    String typeCode = context.getNamingSchemeType();
+    if (StringUtils.isEmpty(typeCode)) {
+      return;
+    }
+    try {
+      IVariables vars =
+          context.getVariables() != null
+              ? context.getVariables()
+              : HopGui.getInstance().getVariables();
+      MetadataManager<NamingScheme> manager =
+          new MetadataManager<>(
+              vars, HopGui.getInstance().getMetadataProvider(), NamingScheme.class, shell);
+      List<NamingScheme> schemes = loadSchemes(typeCode);
+      if (schemes.isEmpty()) {
+        createAndEditScheme(manager, typeCode);
+        return;
+      }
+      NamingScheme chosen = pickSchemeToOpen(shell, schemes, typeCode);
+      if (chosen == null) {
+        return;
+      }
+      rememberLastUsed(typeCode, chosen.getName());
+      manager.editMetadataInDialog(chosen.getName());
+    } catch (Exception e) {
+      new ErrorDialog(
+          shell,
+          BaseMessages.getString(PKG, "Naming.Error.Title"),
+          BaseMessages.getString(PKG, "Naming.Error.Message"),
+          e);
+    }
+  }
+
+  /**
+   * Skip empty cells, table null markers, and values that already contain a variable expression so
+   * NamingEngine cannot chew {@code ${...}}.
+   */
+  private void createAndEditScheme(MetadataManager<NamingScheme> manager, String typeCode)
+      throws Exception {
+    IHopMetadataSerializer<NamingScheme> serializer =
+        HopGui.getInstance().getMetadataProvider().getSerializer(NamingScheme.class);
+    NamingScheme created = newSchemeForType(typeCode);
+    created.setName(
+        uniqueSchemeName(NamingSchemeType.displayFromCode(typeCode), serializer.listObjectNames()));
+    NamingScheme saved = manager.newMetadata(created);
+    if (saved != null) {
+      rememberLastUsed(typeCode, saved.getName());
+    }
+  }
+
+  /**
+   * New scheme of {@code typeCode}. Transform and action schemes default to lower case, space
+   * separator, and capitalize first word.
+   */
+  static NamingScheme newSchemeForType(String typeCode) {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setType(typeCode);
+    if (NamingSchemeTypes.HOP_TRANSFORM.equals(typeCode)
+        || NamingSchemeTypes.HOP_ACTION.equals(typeCode)) {
+      scheme.setWordSeparator(NamingWordSeparator.SPACE.getCode());
+      scheme.setCapitalizeFirstWord(true);
+    }
+    return scheme;
+  }
+
+  static String uniqueSchemeName(String preferred, Iterable<String> existing) {
+    String base = StringUtils.isNotEmpty(preferred) ? preferred : "Naming Scheme";
+    Set<String> taken = new HashSet<>();
+    if (existing != null) {
+      for (String name : existing) {
+        if (name != null) {
+          taken.add(name);
+        }
+      }
+    }
+    if (!taken.contains(base)) {
+      return base;
+    }
+    int n = 2;
+    String candidate;
+    do {
+      candidate = base + " " + n++;
+    } while (taken.contains(candidate));
+    return candidate;
+  }
+
+  /** ConcurrentHashMap rejects null keys and values. */
+  void rememberLastUsed(String typeCode, String schemeName) {
+    if (StringUtils.isEmpty(typeCode) || StringUtils.isEmpty(schemeName)) {
+      return;
+    }
+    lastUsedByType.put(typeCode, schemeName);
+  }
+
+  static boolean shouldSkip(String value) {
+    return NamingEngine.shouldSkip(value);
+  }
+
+  static boolean isApplyShortcut(KeyEvent event) {
+    if (event == null) {
+      return false;
+    }
+    boolean control = (event.stateMask & SWT.CONTROL) != 0;
+    boolean shift = (event.stateMask & SWT.SHIFT) != 0;
+    boolean alt = (event.stateMask & SWT.ALT) != 0;
+    if (!control || !shift || alt) {
+      return false;
+    }
+    if (OsHelper.isMac()) {
+      return event.keyCode == 'n' || event.keyCode == 'N';
+    }
+    return Character.toLowerCase(event.character) == 'n'
+        || event.keyCode == 'n'
+        || event.keyCode == 'N';
+  }
+
+  static boolean isControlSpace(KeyEvent event) {
+    if (event == null) {
+      return false;
+    }
+    if ("zh".equals(System.getProperty("user.language"))) {
+      return event.character == ' '
+          && ((event.stateMask & SWT.CONTROL) != 0)
+          && ((event.stateMask & SWT.ALT) != 0);
+    }
+    if (OsHelper.isMac()) {
+      return event.keyCode == 32
+          && ((event.stateMask & SWT.CONTROL) != 0)
+          && ((event.stateMask & SWT.ALT) == 0);
+    }
+    return event.character == ' '
+        && ((event.stateMask & SWT.CONTROL) != 0)
+        && ((event.stateMask & SWT.ALT) == 0);
+  }
+
+  private List<NamingScheme> loadSchemes(String typeCode) throws Exception {
+    IHopMetadataSerializer<NamingScheme> serializer =
+        HopGui.getInstance().getMetadataProvider().getSerializer(NamingScheme.class);
+    return NamingSchemeSelector.matching(serializer.loadAll(), typeCode);
+  }
+
+  private NamingScheme pickScheme(
+      Shell shell, List<NamingScheme> schemes, String typeCode, String input) {
+    if (schemes.size() == 1) {
+      return schemes.get(0);
+    }
+
+    String[] labels = new String[schemes.size()];
+    int preselect = 0;
+    String last = lastUsedByType.get(typeCode);
+    for (int i = 0; i < schemes.size(); i++) {
+      NamingScheme scheme = schemes.get(i);
+      String preview = NamingEngine.apply(scheme, input, typeCode);
+      labels[i] = scheme.getName() + "  →  " + preview;
+      if (last != null && last.equals(scheme.getName())) {
+        preselect = i;
+      }
+    }
+
+    EnterSelectionDialog dialog =
+        new EnterSelectionDialog(
+            shell,
+            labels,
+            BaseMessages.getString(PKG, "Naming.SchemeSelection.Title"),
+            BaseMessages.getString(PKG, "Naming.Shortcut.Message"));
+    dialog.setSelectedNrs(new int[] {preselect});
+    if (dialog.open() == null) {
+      return null;
+    }
+    int index = dialog.getSelectionNr();
+    if (index < 0 || index >= schemes.size()) {
+      return null;
+    }
+    return schemes.get(index);
+  }
+
+  private NamingScheme pickSchemeToOpen(Shell shell, List<NamingScheme> schemes, String typeCode) {
+    if (schemes.size() == 1) {
+      return schemes.get(0);
+    }
+    String[] names = new String[schemes.size()];
+    int preselect = 0;
+    String last = lastUsedByType.get(typeCode);
+    for (int i = 0; i < schemes.size(); i++) {
+      names[i] = schemes.get(i).getName();
+      if (last != null && last.equals(names[i])) {
+        preselect = i;
+      }
+    }
+    EnterSelectionDialog dialog =
+        new EnterSelectionDialog(
+            shell,
+            names,
+            BaseMessages.getString(PKG, "Naming.Open.Title"),
+            BaseMessages.getString(PKG, "Naming.Open.Message"));
+    dialog.setSelectedNrs(new int[] {preselect});
+    if (dialog.open() == null) {
+      return null;
+    }
+    int index = dialog.getSelectionNr();
+    if (index < 0 || index >= schemes.size()) {
+      return null;
+    }
+    return schemes.get(index);
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeWorkflowCheckExtension.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeWorkflowCheckExtension.java
new file mode 100644
index 0000000000..3a4c1d8889
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/NamingSchemeWorkflowCheckExtension.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import org.apache.hop.core.Const;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.extension.ExtensionPoint;
+import org.apache.hop.core.extension.IExtensionPoint;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.naming.engine.NamingSchemeCheckRemarks;
+import org.apache.hop.workflow.CheckActionsExtension;
+import org.apache.hop.workflow.WorkflowMeta;
+
+/** Adds naming-scheme errors to workflow Verify (same rules as {@code hop naming-check}). */
+@ExtensionPoint(
+    id = "NamingSchemeAfterCheckActions",
+    description = "Add naming-scheme remarks after workflow verify",
+    extensionPointId = "AfterCheckActions")
+public class NamingSchemeWorkflowCheckExtension implements IExtensionPoint<CheckActionsExtension> {
+
+  @Override
+  public void callExtensionPoint(
+      ILogChannel log, IVariables variables, CheckActionsExtension extension) throws HopException {
+    if (extension == null || extension.getWorkflowMeta() == null) {
+      return;
+    }
+    WorkflowMeta workflow = extension.getWorkflowMeta();
+    String location = Const.NVL(workflow.getFilename(), Const.NVL(workflow.getName(), "workflow"));
+    NamingSchemeCheckRemarks.addRemarks(
+        workflow, location, extension.getRemarks(), extension.getMetadataProvider());
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/TableViewNamingToolbarButton.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/TableViewNamingToolbarButton.java
new file mode 100644
index 0000000000..f2f188c957
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/gui/TableViewNamingToolbarButton.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.gui.plugin.GuiPlugin;
+import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElement;
+import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElementFilter;
+import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.metadata.api.IHopMetadataSerializer;
+import org.apache.hop.naming.engine.NamingEngine;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeSelector;
+import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
+import org.apache.hop.ui.core.dialog.ErrorDialog;
+import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TableView;
+import org.apache.hop.ui.hopgui.HopGui;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * TableView toolbar action that applies a {@link NamingScheme} to a chosen column. Columns that
+ * declared a naming type are preferred; otherwise any column can be rewritten with hop-field
+ * schemes (issue #2683).
+ */
+@GuiPlugin
+public class TableViewNamingToolbarButton {
+
+  private static final Class<?> PKG = TableViewNamingToolbarButton.class;
+
+  public static final String ID_TOOLBAR_APPLY_NAMING =
+      "tableview-toolbar-30100-apply-naming-scheme";
+
+  @GuiToolbarElement(
+      root = TableView.ID_TOOLBAR,
+      id = ID_TOOLBAR_APPLY_NAMING,
+      toolTip = "i18n::Naming.Toolbar.Apply.ToolTip",
+      separator = true,
+      image = "naming.svg")
+  public static void applyNamingScheme(TableView tableView) {
+    if (tableView == null || tableView.isDisposed() || tableView.isReadonly()) {
+      return;
+    }
+
+    Shell shell = tableView.getShell();
+    ColumnInfo[] columns = tableView.getColumns();
+    if (columns == null || columns.length == 0) {
+      return;
+    }
+
+    try {
+      List<Integer> eligible = new ArrayList<>();
+      for (int i = 0; i < columns.length; i++) {
+        if (StringUtils.isNotEmpty(columns[i].getNamingSchemeType())) {
+          eligible.add(i);
+        }
+      }
+      // Unannotated tables keep the original "any column + hop-field" behavior.
+      boolean annotated = !eligible.isEmpty();
+      if (!annotated) {
+        for (int i = 0; i < columns.length; i++) {
+          eligible.add(i);
+        }
+      }
+
+      int columnIndex;
+      if (eligible.size() == 1) {
+        columnIndex = eligible.get(0);
+      } else {
+        String[] columnNames = new String[eligible.size()];
+        for (int i = 0; i < eligible.size(); i++) {
+          columnNames[i] = columns[eligible.get(i)].getName();
+        }
+        EnterSelectionDialog columnDialog =
+            new EnterSelectionDialog(
+                shell,
+                columnNames,
+                BaseMessages.getString(PKG, "Naming.ColumnSelection.Title"),
+                BaseMessages.getString(PKG, "Naming.ColumnSelection.Message"));
+        columnDialog.setSelectedNrs(new int[] {0});
+        if (columnDialog.open() == null) {
+          return;
+        }
+        int pick = columnDialog.getSelectionNr();
+        if (pick < 0 || pick >= eligible.size()) {
+          return;
+        }
+        columnIndex = eligible.get(pick);
+      }
+
+      // TableItem column 0 is "#"; data columns start at 1
+      int tableColNr = columnIndex + 1;
+      String typeCode =
+          annotated ? columns[columnIndex].getNamingSchemeType() : NamingSchemeTypes.HOP_FIELD;
+
+      IHopMetadataSerializer<NamingScheme> serializer =
+          HopGui.getInstance().getMetadataProvider().getSerializer(NamingScheme.class);
+      List<NamingScheme> fieldSchemes =
+          NamingSchemeSelector.matching(serializer.loadAll(), typeCode);
+      if (fieldSchemes.isEmpty()) {
+        MessageBox box = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
+        box.setText(BaseMessages.getString(PKG, "Naming.NoSchemes.Title"));
+        box.setMessage(BaseMessages.getString(PKG, "Naming.NoSchemes.Message"));
+        box.open();
+        return;
+      }
+
+      NamingScheme scheme;
+      if (fieldSchemes.size() == 1) {
+        scheme = fieldSchemes.get(0);
+      } else {
+        String[] schemeNames = new String[fieldSchemes.size()];
+        for (int i = 0; i < fieldSchemes.size(); i++) {
+          schemeNames[i] = fieldSchemes.get(i).getName();
+        }
+        EnterSelectionDialog schemeDialog =
+            new EnterSelectionDialog(
+                shell,
+                schemeNames,
+                BaseMessages.getString(PKG, "Naming.SchemeSelection.Title"),
+                BaseMessages.getString(PKG, "Naming.SchemeSelection.Message"));
+        if (schemeDialog.open() == null) {
+          return;
+        }
+        int schemeIndex = schemeDialog.getSelectionNr();
+        if (schemeIndex < 0 || schemeIndex >= fieldSchemes.size()) {
+          return;
+        }
+        scheme = fieldSchemes.get(schemeIndex);
+      }
+
+      List<TableItem> items = tableView.getNonEmptyItems();
+      if (items.isEmpty()) {
+        return;
+      }
+
+      int[] rowIndices = new int[items.size()];
+      String[] newValues = new String[items.size()];
+      for (int i = 0; i < items.size(); i++) {
+        TableItem item = items.get(i);
+        rowIndices[i] = tableView.getTable().indexOf(item);
+        String current = item.getText(tableColNr);
+        if (NamingSchemeShortcut.shouldSkip(current)) {
+          newValues[i] = current;
+        } else {
+          newValues[i] = NamingEngine.apply(scheme, current, typeCode);
+        }
+      }
+
+      tableView.applyColumnValues(tableColNr, rowIndices, newValues);
+    } catch (Exception e) {
+      new ErrorDialog(
+          shell,
+          BaseMessages.getString(PKG, "Naming.Error.Title"),
+          BaseMessages.getString(PKG, "Naming.Error.Message"),
+          e);
+    }
+  }
+
+  @GuiToolbarElementFilter(parentId = TableView.ID_TOOLBAR)
+  public static boolean showApplyNaming(String itemId, Object guiPluginInstance) {
+    if (!ID_TOOLBAR_APPLY_NAMING.equals(itemId)) {
+      return true;
+    }
+    try {
+      IHopMetadataSerializer<NamingScheme> serializer =
+          HopGui.getInstance().getMetadataProvider().getSerializer(NamingScheme.class);
+      return !serializer.listObjectNames().isEmpty();
+    } catch (Exception e) {
+      return false;
+    }
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingCaseStyle.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingCaseStyle.java
new file mode 100644
index 0000000000..0a6f3e7272
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingCaseStyle.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.i18n.BaseMessages;
+
+/** Case transformation applied when joining name words. */
+public enum NamingCaseStyle {
+  AS_IS("as-is", "NamingCaseStyle.AsIs"),
+  LOWER("lower", "NamingCaseStyle.Lower"),
+  UPPER("upper", "NamingCaseStyle.Upper"),
+  CAMEL("camel", "NamingCaseStyle.Camel"),
+  PASCAL("pascal", "NamingCaseStyle.Pascal");
+
+  private static final Class<?> PKG = NamingScheme.class;
+
+  private final String code;
+  private final String i18nKey;
+
+  NamingCaseStyle(String code, String i18nKey) {
+    this.code = code;
+    this.i18nKey = i18nKey;
+  }
+
+  public String getCode() {
+    return code;
+  }
+
+  public String getLabel() {
+    return BaseMessages.getString(PKG, i18nKey);
+  }
+
+  public static NamingCaseStyle fromCode(String code) {
+    if (StringUtils.isEmpty(code)) {
+      return LOWER;
+    }
+    for (NamingCaseStyle style : values()) {
+      if (style.code.equalsIgnoreCase(code.trim())) {
+        return style;
+      }
+    }
+    return LOWER;
+  }
+
+  public static String[] getLabels() {
+    NamingCaseStyle[] values = values();
+    String[] labels = new String[values.length];
+    for (int i = 0; i < values.length; i++) {
+      labels[i] = values[i].getLabel();
+    }
+    return labels;
+  }
+
+  public static NamingCaseStyle fromLabel(String label) {
+    if (StringUtils.isEmpty(label)) {
+      return LOWER;
+    }
+    for (NamingCaseStyle style : values()) {
+      if (style.getLabel().equals(label) || style.code.equalsIgnoreCase(label.trim())) {
+        return style;
+      }
+    }
+    return LOWER;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingScheme.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingScheme.java
new file mode 100644
index 0000000000..8ec02f2015
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingScheme.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.hop.core.gui.plugin.GuiElementType;
+import org.apache.hop.core.gui.plugin.GuiPlugin;
+import org.apache.hop.core.gui.plugin.GuiWidgetElement;
+import org.apache.hop.core.gui.plugin.GuiWidgetGroupType;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.metadata.api.HopMetadata;
+import org.apache.hop.metadata.api.HopMetadataBase;
+import org.apache.hop.metadata.api.HopMetadataCategory;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+import org.apache.hop.metadata.api.HopMetadataPropertyType;
+import org.apache.hop.metadata.api.IHopMetadata;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
+
+/**
+ * Reusable naming rules for identifiers such as Hop field names, transform/action names, database
+ * tables/columns, and file/folder names. Apply with CTRL-SHIFT-N on a TextVar (or related widget),
+ * via the TableView toolbar, or programmatically with {@link
+ * org.apache.hop.naming.engine.NamingEngine}.
+ */
+@Getter
+@Setter
+@GuiPlugin(description = "Naming Scheme editor widgets")
+@HopMetadata(
+    key = "naming-scheme",
+    name = "i18n::NamingScheme.Name",
+    description = "i18n::NamingScheme.Description",
+    image = "naming.svg",
+    category = HopMetadataCategory.DATA_DEFINITION,
+    documentationUrl = "/metadata-types/naming-scheme.html",
+    hopMetadataPropertyType = HopMetadataPropertyType.NAMING_SCHEME)
+public class NamingScheme extends HopMetadataBase implements Serializable, IHopMetadata {
+
+  public static final String GUI_PLUGIN_ELEMENT_PARENT_ID = "NamingSchemeEditor";
+  public static final String WIDGET_DESCRIPTION = "description";
+  public static final String WIDGET_TYPE = "type";
+  public static final String WIDGET_CASE_STYLE = "caseStyle";
+  public static final String WIDGET_WORD_SEPARATOR = "wordSeparator";
+  public static final String WIDGET_CAPITALIZE_FIRST_WORD = "capitalizeFirstWord";
+  public static final String WIDGET_EXTRA_DELIMITERS = "extraDelimiters";
+  public static final String WIDGET_REMOVE_SPECIAL = "removeSpecialCharacters";
+  public static final String WIDGET_COLLAPSE_SEPARATORS = "collapseRepeatedSeparators";
+  public static final String WIDGET_TRIM_EDGES = "trimEdgeSeparators";
+  public static final String WIDGET_PREFIX = "prefix";
+  public static final String WIDGET_SUFFIX = "suffix";
+
+  private static final String GROUP_SCHEME = "i18n::NamingSchemeEditor.Group.Scheme";
+  private static final String GROUP_ORDER = "10";
+
+  @GuiWidgetElement(
+      id = WIDGET_DESCRIPTION,
+      order = "0100",
+      type = GuiElementType.TEXT,
+      label = "i18n::NamingSchemeEditor.Description.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String description;
+
+  /** Target kind code: {@link NamingSchemeType} (default {@code general}). */
+  @GuiWidgetElement(
+      id = WIDGET_TYPE,
+      order = "0200",
+      type = GuiElementType.COMBO,
+      label = "i18n::NamingSchemeEditor.Type.Label",
+      toolTip = "i18n::NamingSchemeEditor.Type.Tooltip",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      comboValuesMethod = "getTypeLabels",
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String type;
+
+  /** Case style code: {@link NamingCaseStyle}. */
+  @GuiWidgetElement(
+      id = WIDGET_CASE_STYLE,
+      order = "0300",
+      type = GuiElementType.COMBO,
+      label = "i18n::NamingSchemeEditor.CaseStyle.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      comboValuesMethod = "getCaseStyleLabels",
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String caseStyle;
+
+  /** Word separator code: {@link NamingWordSeparator}. */
+  @GuiWidgetElement(
+      id = WIDGET_WORD_SEPARATOR,
+      order = "0400",
+      type = GuiElementType.COMBO,
+      label = "i18n::NamingSchemeEditor.WordSeparator.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      comboValuesMethod = "getWordSeparatorLabels",
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String wordSeparator;
+
+  /**
+   * Uppercase the first character of the first word after joining. Typical for transform and action
+   * names with a space separator ({@code Table input}).
+   */
+  @GuiWidgetElement(
+      id = WIDGET_CAPITALIZE_FIRST_WORD,
+      order = "0450",
+      type = GuiElementType.CHECKBOX,
+      label = "i18n::NamingSchemeEditor.CapitalizeFirstWord.Label",
+      toolTip = "i18n::NamingSchemeEditor.CapitalizeFirstWord.Tooltip",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private boolean capitalizeFirstWord;
+
+  /**
+   * Extra characters treated as word boundaries in addition to whitespace, underscore, dash and
+   * camelCase edges (for example {@code .#}).
+   */
+  @GuiWidgetElement(
+      id = WIDGET_EXTRA_DELIMITERS,
+      order = "0500",
+      type = GuiElementType.TEXT,
+      label = "i18n::NamingSchemeEditor.ExtraDelimiters.Label",
+      toolTip = "i18n::NamingSchemeEditor.ExtraDelimiters.Tooltip",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String extraDelimiters;
+
+  /** Strip characters that are not letters or digits from each word. */
+  @GuiWidgetElement(
+      id = WIDGET_REMOVE_SPECIAL,
+      order = "0600",
+      type = GuiElementType.CHECKBOX,
+      label = "i18n::NamingSchemeEditor.RemoveSpecialCharacters.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private boolean removeSpecialCharacters;
+
+  /** Collapse repeated word separators (for example {@code __} → {@code _}). */
+  @GuiWidgetElement(
+      id = WIDGET_COLLAPSE_SEPARATORS,
+      order = "0700",
+      type = GuiElementType.CHECKBOX,
+      label = "i18n::NamingSchemeEditor.CollapseSeparators.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private boolean collapseRepeatedSeparators;
+
+  /** Remove leading/trailing word separators from the result. */
+  @GuiWidgetElement(
+      id = WIDGET_TRIM_EDGES,
+      order = "0800",
+      type = GuiElementType.CHECKBOX,
+      label = "i18n::NamingSchemeEditor.TrimEdgeSeparators.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private boolean trimEdgeSeparators;
+
+  @GuiWidgetElement(
+      id = WIDGET_PREFIX,
+      order = "0900",
+      type = GuiElementType.TEXT,
+      label = "i18n::NamingSchemeEditor.Prefix.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String prefix;
+
+  @GuiWidgetElement(
+      id = WIDGET_SUFFIX,
+      order = "1000",
+      type = GuiElementType.TEXT,
+      label = "i18n::NamingSchemeEditor.Suffix.Label",
+      parentId = GUI_PLUGIN_ELEMENT_PARENT_ID,
+      variables = false,
+      groupType = GuiWidgetGroupType.TABS,
+      group = GROUP_SCHEME,
+      groupOrder = GROUP_ORDER)
+  @HopMetadataProperty
+  private String suffix;
+
+  public NamingScheme() {
+    this.type = NamingSchemeType.GENERAL.getCode();
+    this.caseStyle = NamingCaseStyle.LOWER.getCode();
+    this.wordSeparator = NamingWordSeparator.UNDERSCORE.getCode();
+    this.capitalizeFirstWord = false;
+    this.extraDelimiters = "";
+    this.removeSpecialCharacters = true;
+    this.collapseRepeatedSeparators = true;
+    this.trimEdgeSeparators = true;
+    this.prefix = "";
+    this.suffix = "";
+  }
+
+  public NamingScheme(String name) {
+    this();
+    this.name = name;
+  }
+
+  public List<String> getTypeLabels(ILogChannel log, IHopMetadataProvider metadataProvider) {
+    return Arrays.asList(NamingSchemeType.getPluginLabels());
+  }
+
+  public List<String> getCaseStyleLabels(ILogChannel log, IHopMetadataProvider metadataProvider) {
+    return Arrays.asList(NamingCaseStyle.getLabels());
+  }
+
+  public List<String> getWordSeparatorLabels(
+      ILogChannel log, IHopMetadataProvider metadataProvider) {
+    return Arrays.asList(NamingWordSeparator.getLabels());
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeEditor.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeEditor.java
new file mode 100644
index 0000000000..139315fcc2
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeEditor.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import org.apache.hop.core.Const;
+import org.apache.hop.core.naming.NamingSchemeKinds;
+import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.naming.engine.NamingEngine;
+import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
+import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
+import org.apache.hop.ui.core.metadata.MetadataEditor;
+import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.TextVar;
+import org.apache.hop.ui.hopgui.HopGui;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class NamingSchemeEditor extends MetadataEditor<NamingScheme> {
+
+  private static final Class<?> PKG = NamingScheme.class;
+  private static final String PREVIEW_USER_EDITED = "userEdited";
+
+  private TextVar wName;
+  private GuiCompositeWidgets widgets;
+  private Composite widgetsParent;
+  private Text wPreviewInput;
+  private Text wPreviewOutput;
+
+  public NamingSchemeEditor(
+      HopGui hopGui, MetadataManager<NamingScheme> manager, NamingScheme metadata) {
+    super(hopGui, manager, metadata);
+  }
+
+  @Override
+  public void createControl(Composite parent) {
+    PropsUi props = PropsUi.getInstance();
+    int middle = props.getMiddlePct();
+    int margin = PropsUi.getMargin() + 2;
+
+    wName =
+        createNameField(
+            parent, BaseMessages.getString(PKG, "NamingSchemeEditor.Name.Label"), middle, margin);
+    wName.addModifyListener(e -> setChanged());
+
+    widgets = new GuiCompositeWidgets(hopGui.getVariables());
+    widgets.registerExtraGroup(
+        BaseMessages.getString(PKG, "NamingSchemeEditor.Group.Preview"),
+        "20",
+        null,
+        this::addPreview);
+    widgets.setWidgetsListener(
+        new GuiCompositeWidgetsAdapter() {
+          @Override
+          public void widgetsPopulated(GuiCompositeWidgets compositeWidgets) {
+            updatePreview();
+          }
+
+          @Override
+          public void widgetModified(
+              GuiCompositeWidgets compositeWidgets, Control changedWidget, String widgetId) {
+            setChanged();
+            if (NamingScheme.WIDGET_TYPE.equals(widgetId)) {
+              maybeResetPreviewSample();
+            }
+            updatePreview();
+          }
+        });
+    widgetsParent = parent;
+    widgets.createCompositeWidgets(
+        getMetadata(), null, parent, NamingScheme.GUI_PLUGIN_ELEMENT_PARENT_ID, wName);
+    setWidgetsContent();
+  }
+
+  private void addPreview(Composite parent) {
+    PropsUi props = PropsUi.getInstance();
+    int middle = props.getMiddlePct();
+    int margin = PropsUi.getMargin();
+
+    Label wlPreviewInput = new Label(parent, SWT.RIGHT);
+    PropsUi.setLook(wlPreviewInput);
+    wlPreviewInput.setText(BaseMessages.getString(PKG, "NamingSchemeEditor.PreviewInput.Label"));
+    FormData fdlPreviewInput = new FormData();
+    fdlPreviewInput.top = new FormAttachment(0, margin);
+    fdlPreviewInput.left = new FormAttachment(0, 0);
+    fdlPreviewInput.right = new FormAttachment(middle, -margin);
+    wlPreviewInput.setLayoutData(fdlPreviewInput);
+    wPreviewInput = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    PropsUi.setLook(wPreviewInput);
+    wPreviewInput.setText(defaultPreviewSample(getMetadata().getType()));
+    FormData fdPreviewInput = new FormData();
+    fdPreviewInput.top = new FormAttachment(wlPreviewInput, 0, SWT.CENTER);
+    fdPreviewInput.left = new FormAttachment(middle, 0);
+    fdPreviewInput.right = new FormAttachment(100, 0);
+    wPreviewInput.setLayoutData(fdPreviewInput);
+    wPreviewInput.addModifyListener(
+        e -> {
+          wPreviewInput.setData(PREVIEW_USER_EDITED, Boolean.TRUE);
+          updatePreview();
+        });
+
+    Label wlPreviewOutput = new Label(parent, SWT.RIGHT);
+    PropsUi.setLook(wlPreviewOutput);
+    wlPreviewOutput.setText(BaseMessages.getString(PKG, "NamingSchemeEditor.PreviewOutput.Label"));
+    FormData fdlPreviewOutput = new FormData();
+    fdlPreviewOutput.top = new FormAttachment(wPreviewInput, margin);
+    fdlPreviewOutput.left = new FormAttachment(0, 0);
+    fdlPreviewOutput.right = new FormAttachment(middle, -margin);
+    wlPreviewOutput.setLayoutData(fdlPreviewOutput);
+    wPreviewOutput = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER | SWT.READ_ONLY);
+    PropsUi.setLook(wPreviewOutput);
+    FormData fdPreviewOutput = new FormData();
+    fdPreviewOutput.top = new FormAttachment(wlPreviewOutput, 0, SWT.CENTER);
+    fdPreviewOutput.left = new FormAttachment(middle, 0);
+    fdPreviewOutput.right = new FormAttachment(100, 0);
+    wPreviewOutput.setLayoutData(fdPreviewOutput);
+  }
+
+  private void maybeResetPreviewSample() {
+    if (wPreviewInput == null || wPreviewInput.isDisposed()) {
+      return;
+    }
+    if (Boolean.TRUE.equals(wPreviewInput.getData(PREVIEW_USER_EDITED))) {
+      return;
+    }
+    wPreviewInput.setText(defaultPreviewSample(currentKindCode()));
+    wPreviewInput.setData(PREVIEW_USER_EDITED, Boolean.FALSE);
+  }
+
+  private static String defaultPreviewSample(String kind) {
+    if (NamingSchemeKinds.isFile(kind)) {
+      return "/data/Order ID.csv";
+    }
+    if (NamingSchemeKinds.isFolder(kind)) {
+      return "/data/My Folder";
+    }
+    return "Order ID";
+  }
+
+  private String currentKindCode() {
+    String display = widgetText(NamingScheme.WIDGET_TYPE);
+    if (display.isEmpty()) {
+      return Const.NVL(getMetadata().getType(), NamingSchemeType.GENERAL.getCode());
+    }
+    return NamingSchemeType.codeFromDisplay(display);
+  }
+
+  private String widgetText(String widgetId) {
+    if (widgets == null) {
+      return "";
+    }
+    Control control = widgets.getWidgetsMap().get(widgetId);
+    if (control instanceof Text text) {
+      return text.getText();
+    }
+    if (control instanceof TextVar textVar) {
+      return textVar.getText();
+    }
+    if (control instanceof Combo combo) {
+      return combo.getText();
+    }
+    if (control instanceof ComboVar comboVar) {
+      return comboVar.getText();
+    }
+    return "";
+  }
+
+  private void updatePreview() {
+    if (wPreviewOutput == null || wPreviewOutput.isDisposed()) {
+      return;
+    }
+    NamingScheme preview = new NamingScheme();
+    fillSchemeFromWidgets(preview);
+    String input = wPreviewInput != null ? wPreviewInput.getText() : "";
+    wPreviewOutput.setText(Const.NVL(NamingEngine.apply(preview, input, preview.getType()), ""));
+  }
+
+  private void fillSchemeFromWidgets(NamingScheme scheme) {
+    if (wName != null && !wName.isDisposed()) {
+      scheme.setName(wName.getText());
+    }
+    if (widgets != null) {
+      widgets.getWidgetsContents(scheme, NamingScheme.GUI_PLUGIN_ELEMENT_PARENT_ID);
+      convertDisplaysToCodes(scheme);
+    }
+  }
+
+  private static void convertDisplaysToCodes(NamingScheme scheme) {
+    scheme.setType(NamingSchemeType.codeFromDisplay(scheme.getType()));
+    scheme.setCaseStyle(NamingCaseStyle.fromLabel(scheme.getCaseStyle()).getCode());
+    scheme.setWordSeparator(NamingWordSeparator.fromLabel(scheme.getWordSeparator()).getCode());
+  }
+
+  @Override
+  public void setWidgetsContent() {
+    NamingScheme scheme = getMetadata();
+    if (wName != null && !wName.isDisposed()) {
+      wName.setText(Const.NVL(scheme.getName(), ""));
+    }
+    if (widgets == null || widgetsParent == null) {
+      return;
+    }
+    String type = scheme.getType();
+    String caseStyle = scheme.getCaseStyle();
+    String wordSeparator = scheme.getWordSeparator();
+    scheme.setType(NamingSchemeType.displayFromCode(type));
+    scheme.setCaseStyle(NamingCaseStyle.fromCode(caseStyle).getLabel());
+    scheme.setWordSeparator(NamingWordSeparator.fromCode(wordSeparator).getLabel());
+    try {
+      widgets.setWidgetsContents(scheme, widgetsParent, NamingScheme.GUI_PLUGIN_ELEMENT_PARENT_ID);
+    } finally {
+      scheme.setType(type);
+      scheme.setCaseStyle(caseStyle);
+      scheme.setWordSeparator(wordSeparator);
+    }
+    updatePreview();
+  }
+
+  @Override
+  public void getWidgetsContent(NamingScheme scheme) {
+    fillSchemeFromWidgets(scheme);
+  }
+
+  @Override
+  public boolean setFocus() {
+    if (wName == null || wName.isDisposed()) {
+      return false;
+    }
+    return wName.setFocus();
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeSelector.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeSelector.java
new file mode 100644
index 0000000000..f014d64b0b
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeSelector.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Picks naming schemes for a widget type. Type-specific schemes win; {@link
+ * NamingSchemeType#GENERAL} is used only when none of the requested type exist.
+ */
+public final class NamingSchemeSelector {
+
+  private NamingSchemeSelector() {
+    // utility
+  }
+
+  /**
+   * @param schemes all stored schemes (may be null)
+   * @param requested the widget's naming type (null treated as {@link NamingSchemeType#HOP_FIELD})
+   * @return matching schemes, never null
+   */
+  public static List<NamingScheme> matching(
+      Iterable<NamingScheme> schemes, NamingSchemeType requested) {
+    return matching(
+        schemes, requested != null ? requested.getCode() : NamingSchemeType.HOP_FIELD.getCode());
+  }
+
+  /**
+   * Same as {@link #matching(Iterable, NamingSchemeType)} but compares type <em>codes</em> so
+   * plugin kinds (for example {@code dv-hub}) work without an enum constant.
+   */
+  public static List<NamingScheme> matching(Iterable<NamingScheme> schemes, String requestedCode) {
+    String type =
+        StringUtils.isNotEmpty(requestedCode)
+            ? requestedCode.trim()
+            : NamingSchemeType.HOP_FIELD.getCode();
+    List<NamingScheme> specific = new ArrayList<>();
+    List<NamingScheme> general = new ArrayList<>();
+    if (schemes == null) {
+      return specific;
+    }
+    for (NamingScheme scheme : schemes) {
+      if (scheme == null) {
+        continue;
+      }
+      String schemeType = StringUtils.trimToEmpty(scheme.getType());
+      if (type.equalsIgnoreCase(schemeType)) {
+        specific.add(scheme);
+      } else if (NamingSchemeType.GENERAL.getCode().equalsIgnoreCase(schemeType)) {
+        general.add(scheme);
+      }
+    }
+    if (NamingSchemeType.GENERAL.getCode().equalsIgnoreCase(type) || !specific.isEmpty()) {
+      return specific;
+    }
+    return general;
+  }
+
+  /**
+   * Resolve the scheme to apply automatically. An explicit name wins; otherwise the unique match
+   * from {@link #matching(Iterable, NamingSchemeType)} is used.
+   *
+   * @param schemes all stored schemes
+   * @param requested widget type
+   * @param explicitName optional scheme name
+   * @return the scheme to apply, or null when none / ambiguous
+   */
+  public static NamingScheme resolve(
+      Iterable<NamingScheme> schemes, NamingSchemeType requested, String explicitName) {
+    if (schemes == null) {
+      return null;
+    }
+    if (StringUtils.isNotBlank(explicitName)) {
+      String wanted = explicitName.trim();
+      for (NamingScheme scheme : schemes) {
+        if (scheme != null && wanted.equals(scheme.getName())) {
+          return scheme;
+        }
+      }
+      return null;
+    }
+    List<NamingScheme> match = matching(schemes, requested);
+    return match.size() == 1 ? match.get(0) : null;
+  }
+
+  public static NamingScheme resolve(
+      Iterable<NamingScheme> schemes, String requestedCode, String explicitName) {
+    if (StringUtils.isNotBlank(explicitName)) {
+      return resolve(schemes, NamingSchemeType.HOP_FIELD, explicitName);
+    }
+    List<NamingScheme> match = matching(schemes, requestedCode);
+    return match.size() == 1 ? match.get(0) : null;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeType.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeType.java
new file mode 100644
index 0000000000..b2d7cda572
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingSchemeType.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.naming.NamingSchemeTypePluginType;
+import org.apache.hop.core.plugins.IPlugin;
+import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.i18n.BaseMessages;
+
+/**
+ * Target kind for a {@link NamingScheme}. Stored as a stable string code on the metadata element.
+ */
+public enum NamingSchemeType {
+  GENERAL("general", "NamingSchemeType.General"),
+  HOP_FIELD("hop-field", "NamingSchemeType.HopField"),
+  HOP_TRANSFORM("hop-transform", "NamingSchemeType.HopTransform"),
+  HOP_ACTION("hop-action", "NamingSchemeType.HopAction"),
+  HOP_PIPELINE("hop-pipeline", "NamingSchemeType.HopPipeline"),
+  HOP_WORKFLOW("hop-workflow", "NamingSchemeType.HopWorkflow"),
+  HOP_METADATA("hop-metadata", "NamingSchemeType.HopMetadata"),
+  HOP_VARIABLE("hop-variable", "NamingSchemeType.HopVariable"),
+  DATABASE_TABLE("database-table", "NamingSchemeType.DatabaseTable"),
+  DATABASE_COLUMN("database-column", "NamingSchemeType.DatabaseColumn"),
+  FILE("file", "NamingSchemeType.File"),
+  FOLDER("folder", "NamingSchemeType.Folder");
+
+  private static final Class<?> PKG = NamingScheme.class;
+
+  private final String code;
+  private final String i18nKey;
+
+  NamingSchemeType(String code, String i18nKey) {
+    this.code = code;
+    this.i18nKey = i18nKey;
+  }
+
+  public String getCode() {
+    return code;
+  }
+
+  public String getLabel() {
+    return BaseMessages.getString(PKG, i18nKey);
+  }
+
+  /**
+   * Map a known built-in code to an enum constant. Unknown plugin codes (for example {@code
+   * dv-hub}) are <em>not</em> coerced to {@link #HOP_FIELD} for matching — use {@link
+   * NamingSchemeSelector#matching(Iterable, String)} with the raw code instead. This method still
+   * returns {@link #HOP_FIELD} for unknown values so existing enum callers keep compiling.
+   */
+  public static NamingSchemeType fromCode(String code) {
+    if (StringUtils.isEmpty(code)) {
+      return HOP_FIELD;
+    }
+    for (NamingSchemeType type : values()) {
+      if (type.code.equalsIgnoreCase(code.trim())) {
+        return type;
+      }
+    }
+    return HOP_FIELD;
+  }
+
+  public static String[] getCodes() {
+    NamingSchemeType[] values = values();
+    String[] codes = new String[values.length];
+    for (int i = 0; i < values.length; i++) {
+      codes[i] = values[i].code;
+    }
+    return codes;
+  }
+
+  public static String[] getLabels() {
+    NamingSchemeType[] values = values();
+    String[] labels = new String[values.length];
+    for (int i = 0; i < values.length; i++) {
+      labels[i] = values[i].getLabel();
+    }
+    return labels;
+  }
+
+  public static String[] getPluginLabels() {
+    List<IPlugin> plugins = pluginTypes();
+    if (plugins.isEmpty()) {
+      return getLabels();
+    }
+    plugins.sort(
+        Comparator.comparing((IPlugin p) -> !"general".equalsIgnoreCase(p.getIds()[0]))
+            .thenComparing(IPlugin::getName, String.CASE_INSENSITIVE_ORDER));
+    String[] labels = new String[plugins.size()];
+    for (int i = 0; i < plugins.size(); i++) {
+      labels[i] = plugins.get(i).getName();
+    }
+    return labels;
+  }
+
+  public static String codeFromDisplay(String display) {
+    if (StringUtils.isEmpty(display)) {
+      return GENERAL.getCode();
+    }
+    for (IPlugin plugin : pluginTypes()) {
+      if (display.equals(plugin.getName()) || display.equalsIgnoreCase(plugin.getIds()[0])) {
+        return plugin.getIds()[0];
+      }
+    }
+    return fromLabel(display).getCode();
+  }
+
+  public static String displayFromCode(String code) {
+    if (StringUtils.isEmpty(code)) {
+      return GENERAL.getLabel();
+    }
+    for (IPlugin plugin : pluginTypes()) {
+      if (code.equalsIgnoreCase(plugin.getIds()[0])) {
+        return plugin.getName();
+      }
+    }
+    NamingSchemeType type = fromCode(code);
+    return type.getCode().equalsIgnoreCase(code) ? type.getLabel() : code;
+  }
+
+  private static List<IPlugin> pluginTypes() {
+    try {
+      return new ArrayList<>(
+          PluginRegistry.getInstance().getPlugins(NamingSchemeTypePluginType.class));
+    } catch (Exception e) {
+      return List.of();
+    }
+  }
+
+  public static NamingSchemeType fromLabel(String label) {
+    if (StringUtils.isEmpty(label)) {
+      return HOP_FIELD;
+    }
+    for (NamingSchemeType type : values()) {
+      if (type.getLabel().equals(label) || type.code.equalsIgnoreCase(label.trim())) {
+        return type;
+      }
+    }
+    return HOP_FIELD;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingWordSeparator.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingWordSeparator.java
new file mode 100644
index 0000000000..645e2e75f0
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/metadata/NamingWordSeparator.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.i18n.BaseMessages;
+
+/** Character used to join words after splitting (ignored for camelCase / PascalCase styles). */
+public enum NamingWordSeparator {
+  EMPTY("empty", "", "NamingWordSeparator.Empty"),
+  UNDERSCORE("underscore", "_", "NamingWordSeparator.Underscore"),
+  DASH("dash", "-", "NamingWordSeparator.Dash"),
+  SPACE("space", " ", "NamingWordSeparator.Space");
+
+  private static final Class<?> PKG = NamingScheme.class;
+
+  private final String code;
+  private final String value;
+  private final String i18nKey;
+
+  NamingWordSeparator(String code, String value, String i18nKey) {
+    this.code = code;
+    this.value = value;
+    this.i18nKey = i18nKey;
+  }
+
+  public String getCode() {
+    return code;
+  }
+
+  public String getValue() {
+    return value;
+  }
+
+  public String getLabel() {
+    return BaseMessages.getString(PKG, i18nKey);
+  }
+
+  public static NamingWordSeparator fromCode(String code) {
+    if (StringUtils.isEmpty(code)) {
+      return UNDERSCORE;
+    }
+    for (NamingWordSeparator sep : values()) {
+      if (sep.code.equalsIgnoreCase(code.trim())) {
+        return sep;
+      }
+    }
+    return UNDERSCORE;
+  }
+
+  public static String[] getLabels() {
+    NamingWordSeparator[] values = values();
+    String[] labels = new String[values.length];
+    for (int i = 0; i < values.length; i++) {
+      labels[i] = values[i].getLabel();
+    }
+    return labels;
+  }
+
+  public static NamingWordSeparator fromLabel(String label) {
+    if (StringUtils.isEmpty(label)) {
+      return UNDERSCORE;
+    }
+    for (NamingWordSeparator sep : values()) {
+      if (sep.getLabel().equals(label) || sep.code.equalsIgnoreCase(label.trim())) {
+        return sep;
+      }
+    }
+    return UNDERSCORE;
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/BuiltinNamingSchemeType.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/BuiltinNamingSchemeType.java
new file mode 100644
index 0000000000..4fa7d045df
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/BuiltinNamingSchemeType.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.type;
+
+import org.apache.hop.core.naming.INamingSchemeType;
+import org.apache.hop.core.naming.NamingSchemeTypePlugin;
+
+/** Shared implementation: code and label come from {@link NamingSchemeTypePlugin}. */
+public abstract class BuiltinNamingSchemeType implements INamingSchemeType {
+
+  @Override
+  public String getCode() {
+    NamingSchemeTypePlugin plugin = getClass().getAnnotation(NamingSchemeTypePlugin.class);
+    return plugin != null ? plugin.id() : "";
+  }
+
+  @Override
+  public String getName() {
+    NamingSchemeTypePlugin plugin = getClass().getAnnotation(NamingSchemeTypePlugin.class);
+    return plugin != null ? plugin.name() : getCode();
+  }
+}
diff --git a/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/NamingSchemeTypePlugins.java b/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/NamingSchemeTypePlugins.java
new file mode 100644
index 0000000000..6987a9d03e
--- /dev/null
+++ b/plugins/misc/naming/src/main/java/org/apache/hop/naming/type/NamingSchemeTypePlugins.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.type;
+
+import org.apache.hop.core.naming.NamingSchemeTypePlugin;
+
+/** Built-in naming-scheme kinds shipped with Hop. */
+public final class NamingSchemeTypePlugins {
+
+  private NamingSchemeTypePlugins() {
+    // holder
+  }
+
+  @NamingSchemeTypePlugin(id = "general", name = "General")
+  public static final class General extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-field", name = "Hop field names")
+  public static final class HopField extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-transform", name = "Hop transform names")
+  public static final class HopTransform extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-action", name = "Hop action names")
+  public static final class HopAction extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-pipeline", name = "Hop pipeline names")
+  public static final class HopPipeline extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-workflow", name = "Hop workflow names")
+  public static final class HopWorkflow extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-metadata", name = "Hop metadata names")
+  public static final class HopMetadata extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "hop-variable", name = "Hop variable names")
+  public static final class HopVariable extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "database-table", name = "Database tables")
+  public static final class DatabaseTable extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "database-column", name = "Database columns")
+  public static final class DatabaseColumn extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "file", name = "Files")
+  public static final class File extends BuiltinNamingSchemeType {}
+
+  @NamingSchemeTypePlugin(id = "folder", name = "Folders")
+  public static final class Folder extends BuiltinNamingSchemeType {}
+}
diff --git a/plugins/misc/naming/src/main/resources/naming.svg b/plugins/misc/naming/src/main/resources/naming.svg
new file mode 100644
index 0000000000..8c693fbbf0
--- /dev/null
+++ b/plugins/misc/naming/src/main/resources/naming.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+  <!-- Tag / label style icon for naming schemes -->
+  <path fill="#0F3B5A" d="M16,17H5V7H16L19.55,12M17.63,5.84C17.27,5.33 16.67,5 16,5H5A2,2 0 0,0 3,7V17A2,2 0 0,0 5,19H16C16.67,19 17.27,18.66 17.63,18.15L22,12L17.63,5.84Z"/>
+  <circle fill="#FFFFFF" cx="7.5" cy="12" r="1.5"/>
+</svg>
diff --git a/plugins/misc/naming/src/main/resources/org/apache/hop/naming/gui/messages/messages_en_US.properties b/plugins/misc/naming/src/main/resources/org/apache/hop/naming/gui/messages/messages_en_US.properties
new file mode 100644
index 0000000000..381adca859
--- /dev/null
+++ b/plugins/misc/naming/src/main/resources/org/apache/hop/naming/gui/messages/messages_en_US.properties
@@ -0,0 +1,31 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+Naming.Toolbar.Apply.ToolTip=Apply a Naming Scheme to a column (CTRL-SHIFT-N on a name field or cell)
+Naming.ColumnSelection.Title=Select column
+Naming.ColumnSelection.Message=Select the column whose values should be renamed
+Naming.SchemeSelection.Title=Select Naming Scheme
+Naming.SchemeSelection.Message=Select the Naming Scheme to apply (type\: Hop field names)
+Naming.Shortcut.Message=Select the Naming Scheme to apply to the current name
+Naming.Open.Title=Open Naming Scheme
+Naming.Open.Message=Select the Naming Scheme to open
+Naming.NoSchemes.Title=No Naming Schemes
+Naming.NoSchemes.Message=There are no Naming Scheme metadata elements of the required type.\nCreate one in the Metadata perspective first.
+Naming.Error.Title=Error
+Naming.Error.Message=Error applying Naming Scheme
diff --git a/plugins/misc/naming/src/main/resources/org/apache/hop/naming/metadata/messages/messages_en_US.properties b/plugins/misc/naming/src/main/resources/org/apache/hop/naming/metadata/messages/messages_en_US.properties
new file mode 100644
index 0000000000..5b647e9a06
--- /dev/null
+++ b/plugins/misc/naming/src/main/resources/org/apache/hop/naming/metadata/messages/messages_en_US.properties
@@ -0,0 +1,65 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+NamingScheme.Name=Naming Scheme
+NamingScheme.Description=Reusable rules to normalize names. A General scheme applies to every name field unless a type-specific scheme exists.
+
+NamingSchemeEditor.Name.Label=Name
+NamingSchemeEditor.Description.Label=Description
+NamingSchemeEditor.Type.Label=Type
+NamingSchemeEditor.Type.Tooltip=Target kind. General applies to every name field unless a type-specific scheme exists.
+NamingSchemeEditor.CaseStyle.Label=Case style
+NamingSchemeEditor.WordSeparator.Label=Word separator
+NamingSchemeEditor.CapitalizeFirstWord.Label=Capitalize first word
+NamingSchemeEditor.CapitalizeFirstWord.Tooltip=Uppercase the first character of the first word. Typical for transform and action names with a space separator (Table input).
+NamingSchemeEditor.ExtraDelimiters.Label=Extra delimiters
+NamingSchemeEditor.ExtraDelimiters.Tooltip=Additional characters treated as word boundaries (beyond spaces, '_' and '-').
+NamingSchemeEditor.RemoveSpecialCharacters.Label=Remove special characters
+NamingSchemeEditor.CollapseSeparators.Label=Collapse repeated separators
+NamingSchemeEditor.TrimEdgeSeparators.Label=Trim leading/trailing separators
+NamingSchemeEditor.Prefix.Label=Prefix
+NamingSchemeEditor.Suffix.Label=Suffix
+NamingSchemeEditor.PreviewInput.Label=Preview input
+NamingSchemeEditor.PreviewOutput.Label=Preview output
+NamingSchemeEditor.Group.Scheme=Scheme
+NamingSchemeEditor.Group.Preview=Preview
+
+NamingSchemeType.General=General
+NamingSchemeType.HopField=Hop field names
+NamingSchemeType.HopTransform=Hop transform names
+NamingSchemeType.HopAction=Hop action names
+NamingSchemeType.HopPipeline=Hop pipeline names
+NamingSchemeType.HopWorkflow=Hop workflow names
+NamingSchemeType.HopMetadata=Hop metadata names
+NamingSchemeType.HopVariable=Hop variable names
+NamingSchemeType.DatabaseTable=Database tables
+NamingSchemeType.DatabaseColumn=Database columns
+NamingSchemeType.File=Files
+NamingSchemeType.Folder=Folders
+
+NamingCaseStyle.AsIs=As is
+NamingCaseStyle.Lower=Lower case
+NamingCaseStyle.Upper=Upper case
+NamingCaseStyle.Camel=camelCase
+NamingCaseStyle.Pascal=PascalCase
+
+NamingWordSeparator.Empty=None (empty)
+NamingWordSeparator.Underscore=Underscore (_)
+NamingWordSeparator.Dash=Dash (-)
+NamingWordSeparator.Space=Space
diff --git a/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingEngineTest.java b/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingEngineTest.java
new file mode 100644
index 0000000000..97445b312b
--- /dev/null
+++ b/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingEngineTest.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.naming.metadata.NamingCaseStyle;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingWordSeparator;
+import org.junit.jupiter.api.Test;
+
+class NamingEngineTest {
+
+  @Test
+  void nullAndEmpty() {
+    NamingScheme scheme = lowerUnderscore();
+    assertNull(NamingEngine.apply(scheme, null));
+    assertEquals("", NamingEngine.apply(scheme, ""));
+  }
+
+  @Test
+  void orderIdLowerUnderscore() {
+    assertEquals("order_id", NamingEngine.apply(lowerUnderscore(), "Order ID"));
+  }
+
+  @Test
+  void orderIdAsIsUnderscore() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.AS_IS.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.UNDERSCORE.getCode());
+    scheme.setRemoveSpecialCharacters(false);
+    assertEquals("Order_ID", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void orderIdCamel() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.CAMEL.getCode());
+    scheme.setRemoveSpecialCharacters(false);
+    assertEquals("orderId", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void orderIdPascal() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.PASCAL.getCode());
+    scheme.setRemoveSpecialCharacters(false);
+    assertEquals("OrderId", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void snakeToCamel() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.CAMEL.getCode());
+    assertEquals("orderId", NamingEngine.apply(scheme, "order_id"));
+  }
+
+  @Test
+  void kebabToUpperSnake() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.UPPER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.UNDERSCORE.getCode());
+    assertEquals("ORDER_ID", NamingEngine.apply(scheme, "order-id"));
+  }
+
+  @Test
+  void collapseAndTrimWhitespace() {
+    assertEquals("foo_bar", NamingEngine.apply(lowerUnderscore(), "  foo   bar  "));
+  }
+
+  @Test
+  void removeSpecialCharacters() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setRemoveSpecialCharacters(true);
+    scheme.setExtraDelimiters("#");
+    assertEquals("field_name", NamingEngine.apply(scheme, "field#name!"));
+  }
+
+  @Test
+  void dashSeparator() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.LOWER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.DASH.getCode());
+    assertEquals("order-id", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void spaceSeparator() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.LOWER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.SPACE.getCode());
+    assertEquals("order id", NamingEngine.apply(scheme, "Order ID"));
+    assertEquals("read customers", NamingEngine.apply(scheme, "read_customers"));
+  }
+
+  @Test
+  void capitalizeFirstWordWithSpace() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.LOWER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.SPACE.getCode());
+    scheme.setCapitalizeFirstWord(true);
+    assertEquals("Table input", NamingEngine.apply(scheme, "table_input"));
+    assertEquals("Read customers", NamingEngine.apply(scheme, "read_customers"));
+    assertEquals("Order id", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void capitalizeFirstWordLeavesAlreadyCapital() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.AS_IS.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.SPACE.getCode());
+    scheme.setRemoveSpecialCharacters(false);
+    scheme.setCapitalizeFirstWord(true);
+    assertEquals("Table Input", NamingEngine.apply(scheme, "Table Input"));
+  }
+
+  @Test
+  void prefixAndSuffix() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setPrefix("fld_");
+    scheme.setSuffix("_x");
+    assertEquals("fld_order_id_x", NamingEngine.apply(scheme, "Order ID"));
+  }
+
+  @Test
+  void camelCaseInputSplit() {
+    NamingScheme scheme = lowerUnderscore();
+    assertEquals("order_id", NamingEngine.apply(scheme, "orderId"));
+  }
+
+  @Test
+  void nullSchemeUsesDefaults() {
+    assertEquals("order_id", NamingEngine.apply(null, "Order ID"));
+  }
+
+  @Test
+  void fileKeepsParentAndExtension() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setType("file");
+    assertEquals("/data/order_id.csv", NamingEngine.apply(scheme, "/data/Order ID.csv", "file"));
+    assertEquals(
+        "s3://bucket/dir/my_file.csv",
+        NamingEngine.apply(scheme, "s3://bucket/dir/My File.csv", "file"));
+    assertEquals(
+        "C:\\data\\order_id.csv", NamingEngine.apply(scheme, "C:\\data\\Order ID.csv", "file"));
+    assertEquals("order_id.csv", NamingEngine.apply(scheme, "Order ID.csv", "file"));
+  }
+
+  @Test
+  void fileGeneralSchemeStillUsesKind() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setType("general");
+    assertEquals("/data/order_id.csv", NamingEngine.apply(scheme, "/data/Order ID.csv", "file"));
+  }
+
+  @Test
+  void fileDoesNotSplitLeadingDot() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setRemoveSpecialCharacters(false);
+    assertEquals("/data/.htaccess", NamingEngine.apply(scheme, "/data/.htaccess", "file"));
+  }
+
+  @Test
+  void folderKeepsParentAndTrailingSlash() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setType("folder");
+    assertEquals("/data/my_folder", NamingEngine.apply(scheme, "/data/My Folder", "folder"));
+    assertEquals("/data/my_folder/", NamingEngine.apply(scheme, "/data/My Folder/", "folder"));
+    assertEquals("my_folder", NamingEngine.apply(scheme, "My Folder", "folder"));
+  }
+
+  @Test
+  void folderDoesNotSplitExtension() {
+    NamingScheme scheme = lowerUnderscore();
+    scheme.setRemoveSpecialCharacters(false);
+    assertEquals("/data/my.folder", NamingEngine.apply(scheme, "/data/My.Folder", "folder"));
+  }
+
+  @Test
+  void shouldSkipVariables() {
+    assertTrue(NamingEngine.shouldSkip("${PROJECT_HOME}/Order ID.csv"));
+    assertFalse(NamingEngine.shouldSkip("/data/Order ID.csv"));
+  }
+
+  private static NamingScheme lowerUnderscore() {
+    NamingScheme scheme = new NamingScheme();
+    scheme.setCaseStyle(NamingCaseStyle.LOWER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.UNDERSCORE.getCode());
+    scheme.setRemoveSpecialCharacters(true);
+    scheme.setCollapseRepeatedSeparators(true);
+    scheme.setTrimEdgeSeparators(true);
+    return scheme;
+  }
+}
diff --git a/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingSchemeValidatorTest.java b/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingSchemeValidatorTest.java
new file mode 100644
index 0000000000..f00f46d9bd
--- /dev/null
+++ b/plugins/misc/naming/src/test/java/org/apache/hop/naming/engine/NamingSchemeValidatorTest.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.engine;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Finding;
+import org.apache.hop.naming.engine.NamingSchemeValidator.Severity;
+import org.apache.hop.naming.metadata.NamingCaseStyle;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeType;
+import org.apache.hop.naming.metadata.NamingWordSeparator;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.Test;
+
+class NamingSchemeValidatorTest {
+
+  @Test
+  void skipVariablesAndEmpty() {
+    NamingScheme scheme = snake("fields");
+    assertTrue(NamingSchemeValidator.validate("${VAR}", "hop-field", List.of(scheme)).isEmpty());
+    assertTrue(NamingSchemeValidator.validate("", "hop-field", List.of(scheme)).isEmpty());
+  }
+
+  @Test
+  void warningWhenNoScheme() {
+    List<Finding> findings = NamingSchemeValidator.validate("Order ID", "hop-field", List.of());
+    assertEquals(1, findings.size());
+    assertEquals(Severity.WARNING, findings.get(0).getSeverity());
+  }
+
+  @Test
+  void errorWhenNameWouldChange() {
+    NamingScheme scheme = snake("fields");
+    List<Finding> findings =
+        NamingSchemeValidator.validate("Order ID", "hop-field", List.of(scheme));
+    assertEquals(1, findings.size());
+    assertEquals(Severity.ERROR, findings.get(0).getSeverity());
+    assertEquals("order_id", findings.get(0).getExpected());
+  }
+
+  @Test
+  void okWhenAlreadyNormalized() {
+    NamingScheme scheme = snake("fields");
+    assertTrue(NamingSchemeValidator.validate("order_id", "hop-field", List.of(scheme)).isEmpty());
+  }
+
+  @Test
+  void walkerFindsTransformName() {
+    NamingScheme scheme = snake("fields");
+    scheme.setType(NamingSchemeType.HOP_TRANSFORM.getCode());
+    TransformMeta transform = new TransformMeta();
+    transform.setName("Read Customers");
+    List<Finding> findings = NamingSchemeWalker.walk(transform, "test.hpl", List.of(scheme), null);
+    assertEquals(1, findings.size());
+    assertEquals("Read Customers", findings.get(0).getActual());
+    assertEquals("read_customers", findings.get(0).getExpected());
+    assertEquals("name", findings.get(0).getFieldPath());
+  }
+
+  @Test
+  void walkerDoesNotDoubleCountTransformName() {
+    NamingScheme scheme = snake("fields");
+    scheme.setType(NamingSchemeType.HOP_TRANSFORM.getCode());
+    TransformMeta transform = new TransformMeta();
+    transform.setName("Read Customers");
+    List<Finding> findings = NamingSchemeWalker.walk(transform, "test.hpl", List.of(scheme), null);
+    assertEquals(1, findings.size());
+  }
+
+  @Test
+  void generalSchemeValidatesPluginKind() {
+    NamingScheme general = snake("all");
+    general.setType(NamingSchemeType.GENERAL.getCode());
+    List<Finding> findings =
+        NamingSchemeValidator.validate("Read Customers", "dv-hub", List.of(general));
+    assertEquals(1, findings.size());
+    assertEquals(Severity.ERROR, findings.get(0).getSeverity());
+    assertEquals("read_customers", findings.get(0).getExpected());
+  }
+
+  @Test
+  void multipleSchemesFailIfAnyWouldRewrite() {
+    NamingScheme snake = snake("snake");
+    NamingScheme dash = snake("dash");
+    dash.setWordSeparator(org.apache.hop.naming.metadata.NamingWordSeparator.DASH.getCode());
+    List<Finding> findings =
+        NamingSchemeValidator.validate("order_id", "hop-field", List.of(snake, dash));
+    assertEquals(1, findings.size());
+    assertEquals("order-id", findings.get(0).getExpected());
+  }
+
+  @Test
+  void walkerUsesClassLevelKind() {
+    NamingScheme scheme = snake("meta");
+    scheme.setType(NamingSchemeType.HOP_METADATA.getCode());
+    Kinded named = new Kinded();
+    named.name = "My Connection";
+    List<Finding> findings = NamingSchemeWalker.walk(named, "metadata", List.of(scheme), null);
+    assertEquals(1, findings.size());
+    assertEquals("my_connection", findings.get(0).getExpected());
+    assertEquals("hop-metadata", findings.get(0).getTypeCode());
+  }
+
+  @Test
+  void walkerFindsTransformInsidePipeline() {
+    NamingScheme scheme = snake("fields");
+    scheme.setType(NamingSchemeType.HOP_TRANSFORM.getCode());
+    PipelineMeta pipeline = new PipelineMeta();
+    pipeline.setName("my_pipeline");
+    TransformMeta transform = new TransformMeta();
+    transform.setName("Read Customers");
+    pipeline.addTransform(transform);
+    List<Finding> findings =
+        NamingSchemeWalker.walk(
+            pipeline, "test.hpl", List.of(scheme), java.util.Set.of("hop-transform"));
+    assertEquals(1, findings.size());
+    assertEquals("Read Customers", findings.get(0).getActual());
+    assertEquals("read_customers", findings.get(0).getExpected());
+  }
+
+  @Test
+  void walkerHonorsTypeFilter() {
+    NamingScheme scheme = snake("fields");
+    scheme.setType(NamingSchemeType.HOP_TRANSFORM.getCode());
+    TransformMeta transform = new TransformMeta();
+    transform.setName("Read Customers");
+    List<Finding> findings =
+        NamingSchemeWalker.walk(
+            transform, "test.hpl", List.of(scheme), java.util.Set.of("hop-field"));
+    assertTrue(findings.isEmpty());
+  }
+
+  @org.apache.hop.core.naming.NamingSchemeKind("hop-metadata")
+  private static final class Kinded {
+    private String name;
+
+    public String getName() {
+      return name;
+    }
+  }
+
+  private static NamingScheme snake(String name) {
+    NamingScheme scheme = new NamingScheme(name);
+    scheme.setType(NamingSchemeType.HOP_FIELD.getCode());
+    scheme.setCaseStyle(NamingCaseStyle.LOWER.getCode());
+    scheme.setWordSeparator(NamingWordSeparator.UNDERSCORE.getCode());
+    return scheme;
+  }
+}
diff --git a/plugins/misc/naming/src/test/java/org/apache/hop/naming/gui/NamingSchemeShortcutTest.java b/plugins/misc/naming/src/test/java/org/apache/hop/naming/gui/NamingSchemeShortcutTest.java
new file mode 100644
index 0000000000..a7d53566d4
--- /dev/null
+++ b/plugins/misc/naming/src/test/java/org/apache/hop/naming/gui/NamingSchemeShortcutTest.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.gui;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.apache.hop.naming.metadata.NamingScheme;
+import org.apache.hop.naming.metadata.NamingSchemeType;
+import org.apache.hop.naming.metadata.NamingWordSeparator;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.junit.jupiter.api.Test;
+
+class NamingSchemeShortcutTest {
+
+  @Test
+  void skipEmptyNullMarkerAndVariables() {
+    assertTrue(NamingSchemeShortcut.shouldSkip(null));
+    assertTrue(NamingSchemeShortcut.shouldSkip(""));
+    assertTrue(NamingSchemeShortcut.shouldSkip("<null>"));
+    assertTrue(NamingSchemeShortcut.shouldSkip("${TABLE_NAME}"));
+    assertTrue(NamingSchemeShortcut.shouldSkip("prefix_${VAR}_suffix"));
+    assertFalse(NamingSchemeShortcut.shouldSkip("Order ID"));
+  }
+
+  @Test
+  void rememberLastUsedIgnoresNulls() {
+    NamingSchemeShortcut shortcut = NamingSchemeShortcut.INSTANCE;
+    shortcut.rememberLastUsed(null, "scheme");
+    shortcut.rememberLastUsed("file", null);
+    shortcut.rememberLastUsed("", "scheme");
+    shortcut.rememberLastUsed("file", "scheme");
+  }
+
+  @Test
+  void newSchemeForTypeSetsActionDefaults() {
+    NamingScheme scheme = NamingSchemeShortcut.newSchemeForType(NamingSchemeTypes.HOP_ACTION);
+    assertEquals(NamingSchemeTypes.HOP_ACTION, scheme.getType());
+    assertEquals(NamingWordSeparator.SPACE.getCode(), scheme.getWordSeparator());
+    assertTrue(scheme.isCapitalizeFirstWord());
+  }
+
+  @Test
+  void newSchemeForTypeKeepsFieldDefaults() {
+    NamingScheme scheme = NamingSchemeShortcut.newSchemeForType(NamingSchemeTypes.HOP_FIELD);
+    assertEquals(NamingSchemeTypes.HOP_FIELD, scheme.getType());
+    assertEquals(NamingWordSeparator.UNDERSCORE.getCode(), scheme.getWordSeparator());
+    assertFalse(scheme.isCapitalizeFirstWord());
+  }
+
+  @Test
+  void uniqueSchemeNameAddsSuffixWhenTaken() {
+    assertEquals(
+        "Hop action names", NamingSchemeShortcut.uniqueSchemeName("Hop action names", List.of()));
+    assertEquals(
+        "Hop action names 2",
+        NamingSchemeShortcut.uniqueSchemeName("Hop action names", List.of("Hop action names")));
+    assertEquals(
+        "Hop action names 3",
+        NamingSchemeShortcut.uniqueSchemeName(
+            "Hop action names", List.of("Hop action names", "Hop action names 2")));
+  }
+
+  @Test
+  void typeCodesMatchUiConstants() {
+    assertEquals(NamingSchemeTypes.GENERAL, NamingSchemeType.GENERAL.getCode());
+    assertEquals(NamingSchemeTypes.HOP_FIELD, NamingSchemeType.HOP_FIELD.getCode());
+    assertEquals(NamingSchemeTypes.HOP_TRANSFORM, NamingSchemeType.HOP_TRANSFORM.getCode());
+    assertEquals(NamingSchemeTypes.HOP_ACTION, NamingSchemeType.HOP_ACTION.getCode());
+    assertEquals(NamingSchemeTypes.HOP_PIPELINE, NamingSchemeType.HOP_PIPELINE.getCode());
+    assertEquals(NamingSchemeTypes.HOP_WORKFLOW, NamingSchemeType.HOP_WORKFLOW.getCode());
+    assertEquals(NamingSchemeTypes.HOP_METADATA, NamingSchemeType.HOP_METADATA.getCode());
+    assertEquals(NamingSchemeTypes.HOP_VARIABLE, NamingSchemeType.HOP_VARIABLE.getCode());
+    assertEquals(NamingSchemeTypes.DATABASE_TABLE, NamingSchemeType.DATABASE_TABLE.getCode());
+    assertEquals(NamingSchemeTypes.DATABASE_COLUMN, NamingSchemeType.DATABASE_COLUMN.getCode());
+    assertEquals(NamingSchemeTypes.FILE, NamingSchemeType.FILE.getCode());
+    assertEquals(NamingSchemeTypes.FOLDER, NamingSchemeType.FOLDER.getCode());
+  }
+}
diff --git a/plugins/misc/naming/src/test/java/org/apache/hop/naming/metadata/NamingSchemeSelectorTest.java b/plugins/misc/naming/src/test/java/org/apache/hop/naming/metadata/NamingSchemeSelectorTest.java
new file mode 100644
index 0000000000..6795b55f73
--- /dev/null
+++ b/plugins/misc/naming/src/test/java/org/apache/hop/naming/metadata/NamingSchemeSelectorTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.metadata;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class NamingSchemeSelectorTest {
+
+  @Test
+  void typeSpecificSchemesHideGeneral() {
+    NamingScheme general = scheme("all-snake", NamingSchemeType.GENERAL);
+    NamingScheme field = scheme("field-snake", NamingSchemeType.HOP_FIELD);
+    List<NamingScheme> picked =
+        NamingSchemeSelector.matching(List.of(general, field), NamingSchemeType.HOP_FIELD);
+    assertEquals(1, picked.size());
+    assertEquals("field-snake", picked.get(0).getName());
+  }
+
+  @Test
+  void generalIsUsedWhenNoSpecificSchemeExists() {
+    NamingScheme general = scheme("all-snake", NamingSchemeType.GENERAL);
+    NamingScheme table = scheme("table-upper", NamingSchemeType.DATABASE_TABLE);
+    List<NamingScheme> picked =
+        NamingSchemeSelector.matching(List.of(general, table), NamingSchemeType.HOP_TRANSFORM);
+    assertEquals(1, picked.size());
+    assertEquals("all-snake", picked.get(0).getName());
+  }
+
+  @Test
+  void emptyWhenNeitherSpecificNorGeneralExists() {
+    NamingScheme table = scheme("table-upper", NamingSchemeType.DATABASE_TABLE);
+    assertTrue(NamingSchemeSelector.matching(List.of(table), NamingSchemeType.HOP_FIELD).isEmpty());
+  }
+
+  @Test
+  void explicitNameWinsOverType() {
+    NamingScheme general = scheme("all-snake", NamingSchemeType.GENERAL);
+    NamingScheme field = scheme("field-snake", NamingSchemeType.HOP_FIELD);
+    NamingScheme picked =
+        NamingSchemeSelector.resolve(
+            List.of(general, field), NamingSchemeType.HOP_FIELD, "all-snake");
+    assertEquals("all-snake", picked.getName());
+  }
+
+  @Test
+  void uniqueMatchIsResolvedWithoutExplicitName() {
+    NamingScheme general = scheme("all-snake", NamingSchemeType.GENERAL);
+    NamingScheme picked =
+        NamingSchemeSelector.resolve(List.of(general), NamingSchemeType.HOP_FIELD, null);
+    assertEquals("all-snake", picked.getName());
+  }
+
+  @Test
+  void requestingGeneralReturnsOnlyGeneralSchemes() {
+    NamingScheme general = scheme("all-snake", NamingSchemeType.GENERAL);
+    NamingScheme field = scheme("field-snake", NamingSchemeType.HOP_FIELD);
+    List<NamingScheme> picked =
+        NamingSchemeSelector.matching(List.of(general, field), NamingSchemeType.GENERAL);
+    assertEquals(1, picked.size());
+    assertEquals("all-snake", picked.get(0).getName());
+  }
+
+  @Test
+  void pluginKindDoesNotBecomeHopField() {
+    NamingScheme field = scheme("field-snake", NamingSchemeType.HOP_FIELD);
+    NamingScheme hub = new NamingScheme("hub-snake");
+    hub.setType("dv-hub");
+    List<NamingScheme> picked = NamingSchemeSelector.matching(List.of(field, hub), "dv-hub");
+    assertEquals(1, picked.size());
+    assertEquals("hub-snake", picked.get(0).getName());
+  }
+
+  @Test
+  void displayFromCodeKeepsUnknownPluginCodes() {
+    assertEquals("dv-hub", NamingSchemeType.displayFromCode("dv-hub"));
+  }
+
+  private static NamingScheme scheme(String name, NamingSchemeType type) {
+    NamingScheme scheme = new NamingScheme(name);
+    scheme.setType(type.getCode());
+    return scheme;
+  }
+}
diff --git a/plugins/misc/naming/src/test/java/org/apache/hop/naming/type/BuiltinNamingSchemeTypeTest.java b/plugins/misc/naming/src/test/java/org/apache/hop/naming/type/BuiltinNamingSchemeTypeTest.java
new file mode 100644
index 0000000000..36d9ea9b8a
--- /dev/null
+++ b/plugins/misc/naming/src/test/java/org/apache/hop/naming/type/BuiltinNamingSchemeTypeTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.naming.type;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class BuiltinNamingSchemeTypeTest {
+
+  @Test
+  void annotationSuppliesCodeAndName() {
+    NamingSchemeTypePlugins.HopTransform type = new NamingSchemeTypePlugins.HopTransform();
+    assertEquals("hop-transform", type.getCode());
+    assertEquals("Hop transform names", type.getName());
+  }
+
+  @Test
+  void generalPluginIsPresent() {
+    NamingSchemeTypePlugins.General type = new NamingSchemeTypePlugins.General();
+    assertEquals("general", type.getCode());
+    assertEquals("General", type.getName());
+  }
+}
diff --git a/plugins/misc/pom.xml b/plugins/misc/pom.xml
index 769a470002..ede14cded8 100644
--- a/plugins/misc/pom.xml
+++ b/plugins/misc/pom.xml
@@ -37,6 +37,7 @@
         <module>lint</module>
         <module>mail</module>
         <module>marketplace</module>
+        <module>naming</module>
         <module>passwords</module>
         <module>projects</module>
         <module>py4j</module>
diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsNamingOptionPlugin.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsNamingOptionPlugin.java
new file mode 100644
index 0000000000..c205e072b1
--- /dev/null
+++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/config/ProjectsNamingOptionPlugin.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.projects.config;
+
+import org.apache.hop.core.config.plugin.ConfigPlugin;
+import org.apache.hop.core.config.plugin.IConfigOptions;
+
+@ConfigPlugin(
+    id = "ProjectsNamingOptionPlugin",
+    description = "Project and Environment configuration options for hop naming-check",
+    category = ConfigPlugin.CATEGORY_NAMING)
+public class ProjectsNamingOptionPlugin extends ProjectsOptionPlugin implements IConfigOptions {}
diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
index b8da81d5c5..8c820c1c0c 100644
--- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
+++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/environment/LifecycleEnvironmentDialog.java
@@ -48,7 +48,9 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.apache.hop.ui.util.HelpUtils;
@@ -79,7 +81,7 @@ public class LifecycleEnvironmentDialog extends Dialog {
   private Shell shell;
   private final PropsUi props;
 
-  private Text wName;
+  private TextVar wName;
   private Combo wPurpose;
   private Combo wProject;
   private Text wCanvasText;
@@ -227,7 +229,9 @@ public class LifecycleEnvironmentDialog extends Dialog {
     fdlName.right = new FormAttachment(middle, 0);
     fdlName.top = new FormAttachment(0, margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT);
+    wName =
+        new TextVar(variables, comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.left = new FormAttachment(middle, margin);
@@ -352,6 +356,7 @@ public class LifecycleEnvironmentDialog extends Dialog {
               false),
         };
     columnInfo[0].setUsingVariables(true);
+    columnInfo[0].setNamingSchemeType(NamingSchemeTypes.FILE);
 
     wConfigFiles =
         new TableView(
diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectConfigDialog.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectConfigDialog.java
index e60739e903..848c4c30d2 100644
--- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectConfigDialog.java
+++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/gui/ProjectConfigDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -58,7 +59,7 @@ public class ProjectConfigDialog extends Dialog {
   private final String originalName;
 
   private Shell shell;
-  private Text wName;
+  private TextVar wName;
   private TextVar wHome;
   private TextVar wConfigFile;
   private ComboVar wGroup;
@@ -117,7 +118,9 @@ public class ProjectConfigDialog extends Dialog {
     fdlName.right = new FormAttachment(middle, 0);
     fdlName.top = new FormAttachment(0, margin * 2);
     wlName.setLayoutData(fdlName);
-    wName = new Text(shell, SWT.SINGLE | SWT.BORDER);
+    wName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.left = new FormAttachment(middle, margin);
@@ -143,7 +146,9 @@ public class ProjectConfigDialog extends Dialog {
     wbHome.setLayoutData(fdbHome);
     wbHome.addListener(
         SWT.Selection, e -> BaseDialog.presentDirectoryDialog(shell, wHome, variables));
-    wHome = new TextVar(variables, shell, SWT.SINGLE | SWT.BORDER);
+    wHome =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wHome);
     FormData fdHome = new FormData();
     fdHome.left = new FormAttachment(middle, margin);
diff --git a/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java b/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
index 5388ca0f8a..17abc6b8ea 100644
--- a/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
+++ b/plugins/misc/projects/src/main/java/org/apache/hop/projects/project/ProjectDialog.java
@@ -47,6 +47,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -81,7 +82,7 @@ public class ProjectDialog extends Dialog {
   private Shell shell;
   private final PropsUi props;
 
-  private Text wName;
+  private TextVar wName;
   private TextVar wHome;
   private Button wReadOnly;
   private ComboVar wParentProject;
@@ -236,7 +237,9 @@ public class ProjectDialog extends Dialog {
     fdlName.right = new FormAttachment(middle, 0);
     fdlName.top = new FormAttachment(0, margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT);
+    wName =
+        new TextVar(variables, comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.left = new FormAttachment(middle, margin);
@@ -261,7 +264,9 @@ public class ProjectDialog extends Dialog {
     fdbHome.top = new FormAttachment(wlHome, 0, SWT.CENTER);
     wbHome.setLayoutData(fdbHome);
     wbHome.addListener(SWT.Selection, this::browseHomeFolder);
-    wHome = new TextVar(variables, comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT);
+    wHome =
+        new TextVar(variables, comp, SWT.SINGLE | SWT.BORDER | SWT.LEFT)
+            .enableNamingSchemes(NamingSchemeTypes.FOLDER);
     PropsUi.setLook(wHome);
     FormData fdHome = new FormData();
     fdHome.left = new FormAttachment(middle, margin);
@@ -599,6 +604,7 @@ public class ProjectDialog extends Dialog {
               false),
         };
     columnInfo[0].setUsingVariables(true);
+    columnInfo[0].setNamingSchemeType(NamingSchemeTypes.HOP_VARIABLE);
     columnInfo[1].setUsingVariables(true);
 
     wVariables =
diff --git a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/pipeline/meta/PipelineLogEditor.java b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/pipeline/meta/PipelineLogEditor.java
index 37de386fa0..140b073aaa 100644
--- a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/pipeline/meta/PipelineLogEditor.java
+++ b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/pipeline/meta/PipelineLogEditor.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -50,7 +51,6 @@ import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * Editor that allows you to change Pipeline Log metadata
@@ -60,7 +60,7 @@ import org.eclipse.swt.widgets.Text;
 public class PipelineLogEditor extends MetadataEditor<PipelineLog> {
   private static final Class<?> PKG = PipelineLogEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Button wEnabled;
   private Button wLoggingParentsOnly;
   private Button wFailParentOnLoggingFailure;
@@ -103,7 +103,9 @@ public class PipelineLogEditor extends MetadataEditor<PipelineLog> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/probe/meta/PipelineProbeEditor.java b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/probe/meta/PipelineProbeEditor.java
index b0dd2d03b5..90351d1078 100644
--- a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/probe/meta/PipelineProbeEditor.java
+++ b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/probe/meta/PipelineProbeEditor.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -47,7 +48,6 @@ import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * Editor that allows you to change Pipeline Probe metadata
@@ -57,7 +57,7 @@ import org.eclipse.swt.widgets.Text;
 public class PipelineProbeEditor extends MetadataEditor<PipelineProbe> {
   private static final Class<?> PKG = PipelineProbeEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Button wEnabled;
   private TextVar wFilename;
   private TableView wSources;
@@ -92,7 +92,9 @@ public class PipelineProbeEditor extends MetadataEditor<PipelineProbe> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/reader/meta/LogReaderEditor.java b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/reader/meta/LogReaderEditor.java
index 561f3694b6..6316aad517 100644
--- a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/reader/meta/LogReaderEditor.java
+++ b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/reader/meta/LogReaderEditor.java
@@ -24,6 +24,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -32,7 +34,6 @@ import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 /*
 
@@ -47,7 +48,7 @@ public class LogReaderEditor extends MetadataEditor<LogReader> {
   private final LogReader hopDocumentation;
   private final LogReader workingDocumentation;
 
-  private Text wName;
+  private TextVar wName;
   private Composite wPluginSpecificComp;
   private GuiCompositeWidgets guiCompositeWidgets;
 
@@ -83,7 +84,9 @@ public class LogReaderEditor extends MetadataEditor<LogReader> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/workflow/meta/WorkflowLogEditor.java b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/workflow/meta/WorkflowLogEditor.java
index 505981b399..45811b75d2 100644
--- a/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/workflow/meta/WorkflowLogEditor.java
+++ b/plugins/misc/reflection/src/main/java/org/apache/hop/reflection/workflow/meta/WorkflowLogEditor.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -50,7 +51,6 @@ import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * Editor that allows you to change Workflow Log metadata
@@ -60,7 +60,7 @@ import org.eclipse.swt.widgets.Text;
 public class WorkflowLogEditor extends MetadataEditor<WorkflowLog> {
   private static final Class<?> PKG = WorkflowLogEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Button wEnabled;
   private Button wLoggingParentsOnly;
   private Button wFailParentOnLoggingFailure;
@@ -103,7 +103,9 @@ public class WorkflowLogEditor extends MetadataEditor<WorkflowLog> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnectionEditor.java b/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnectionEditor.java
index c4b5e52993..ba68100091 100644
--- a/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnectionEditor.java
+++ b/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnectionEditor.java
@@ -37,6 +37,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -84,7 +85,7 @@ public class RestConnectionEditor extends MetadataEditor<RestConnection> {
   public static final String BEARER = "Bearer";
   public static final String OAUTH2 = "OAuth 2";
 
-  private Text wName;
+  private TextVar wName;
 
   private TextVar wBaseUrl;
   private TextVar wTestUrl;
@@ -188,7 +189,9 @@ public class RestConnectionEditor extends MetadataEditor<RestConnection> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/misc/static-schema/src/main/java/org/apache/hop/staticschema/metadata/SchemaDefinitionEditor.java b/plugins/misc/static-schema/src/main/java/org/apache/hop/staticschema/metadata/SchemaDefinitionEditor.java
index 05437ea0f3..7d74432bbe 100644
--- a/plugins/misc/static-schema/src/main/java/org/apache/hop/staticschema/metadata/SchemaDefinitionEditor.java
+++ b/plugins/misc/static-schema/src/main/java/org/apache/hop/staticschema/metadata/SchemaDefinitionEditor.java
@@ -27,7 +27,9 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -44,7 +46,7 @@ public class SchemaDefinitionEditor extends MetadataEditor<SchemaDefinition> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private Text wSeparator;
   private Text wEnclosure;
@@ -74,7 +76,9 @@ public class SchemaDefinitionEditor extends MetadataEditor<SchemaDefinition> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
@@ -207,6 +211,7 @@ public class SchemaDefinitionEditor extends MetadataEditor<SchemaDefinition> {
               ValueMetaString.roundingTypeDesc,
               true),
         };
+    columnInfos[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/misc/testing/src/main/java/org/apache/hop/testing/transforms/datasetinput/DataSetInputDialog.java b/plugins/misc/testing/src/main/java/org/apache/hop/testing/transforms/datasetinput/DataSetInputDialog.java
index b72384f359..69c57a2a53 100644
--- a/plugins/misc/testing/src/main/java/org/apache/hop/testing/transforms/datasetinput/DataSetInputDialog.java
+++ b/plugins/misc/testing/src/main/java/org/apache/hop/testing/transforms/datasetinput/DataSetInputDialog.java
@@ -37,7 +37,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 public class DataSetInputDialog extends BaseTransformDialog {
   private static final Class<?> PKG = DataSetInputDialog.class;
@@ -84,14 +83,13 @@ public class DataSetInputDialog extends BaseTransformDialog {
     fdlTransformName.right = new FormAttachment(middle, -margin);
     fdlTransformName.top = new FormAttachment(0, margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(0, margin);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
     Control lastControl = wTransformName;
 
     wDataSetName =
diff --git a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/DataSetEditor.java b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/DataSetEditor.java
index e9053b135f..f2350a4b3c 100644
--- a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/DataSetEditor.java
+++ b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/DataSetEditor.java
@@ -38,6 +38,7 @@ import org.apache.hop.ui.core.dialog.ShowRowsDialog;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -55,7 +56,7 @@ public class DataSetEditor extends MetadataEditor<DataSet> {
   private static final Class<?> PKG = DataSetEditor.class;
   public static final String CONST_ERROR = "Error";
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private Text wBaseFilename;
   private TextVar wFolderName;
@@ -91,7 +92,9 @@ public class DataSetEditor extends MetadataEditor<DataSet> {
     fdlName.left = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlName);
 
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 5);
diff --git a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
index 4fcb94271d..487ae88c4c 100644
--- a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
+++ b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
@@ -39,6 +39,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -62,7 +63,7 @@ import org.eclipse.swt.widgets.Text;
 public class PipelineUnitTestEditor extends MetadataEditor<PipelineUnitTest> {
   private static final Class<?> PKG = PipelineUnitTestEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private Combo wTestType;
   private Text wPipelineFilename;
@@ -150,7 +151,9 @@ public class PipelineUnitTestEditor extends MetadataEditor<PipelineUnitTest> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(0, margin);
diff --git a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrodecode/AvroDecodeDialog.java b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrodecode/AvroDecodeDialog.java
index 49e1c56ec0..a0930555a5 100644
--- a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrodecode/AvroDecodeDialog.java
+++ b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrodecode/AvroDecodeDialog.java
@@ -50,6 +50,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -150,6 +151,7 @@ public class AvroDecodeDialog extends BaseTransformDialog {
               false,
               false)
         };
+    fieldsColumns[2].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java
index 412feb30bb..43a29b7cc5 100644
--- a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java
+++ b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java
@@ -39,6 +39,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageDialogWithToggle;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -186,7 +187,9 @@ public class AvroOutputDialog extends BaseTransformDialog {
     fdbFilename.top = new FormAttachment(wOutputType, margin);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     FormData fdFilename = new FormData();
     fdFilename.left = new FormAttachment(middle, 0);
diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java
index ed0c25291d..a72e79ad33 100644
--- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java
+++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java
@@ -53,6 +53,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -220,7 +221,9 @@ public class RedshiftBulkLoaderDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(lastControl, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsMod);
     wTable.addFocusListener(lsFocusLost);
diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/vfs/s3/metadata/S3MetaEditor.java b/plugins/tech/aws/src/main/java/org/apache/hop/vfs/s3/metadata/S3MetaEditor.java
index 800cb10973..29e699df47 100644
--- a/plugins/tech/aws/src/main/java/org/apache/hop/vfs/s3/metadata/S3MetaEditor.java
+++ b/plugins/tech/aws/src/main/java/org/apache/hop/vfs/s3/metadata/S3MetaEditor.java
@@ -25,6 +25,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
@@ -36,7 +37,6 @@ import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "Editor for S3 connection metadata")
 public class S3MetaEditor extends MetadataEditor<S3Meta> {
@@ -50,7 +50,7 @@ public class S3MetaEditor extends MetadataEditor<S3Meta> {
   private int middle;
   private int margin;
 
-  private Text wName;
+  private TextVar wName;
   private TextVar wDescription;
   private Combo wRegion;
   private TextVar wPartSize;
@@ -110,7 +110,9 @@ public class S3MetaEditor extends MetadataEditor<S3Meta> {
     fdlName.top = new FormAttachment(0, 0);
     fdlName.left = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, margin);
diff --git a/plugins/tech/azure/src/main/java/org/apache/hop/vfs/azure/metadatatype/AzureMetadataTypeEditor.java b/plugins/tech/azure/src/main/java/org/apache/hop/vfs/azure/metadatatype/AzureMetadataTypeEditor.java
index 46a9b0094a..a42b2a00d1 100644
--- a/plugins/tech/azure/src/main/java/org/apache/hop/vfs/azure/metadatatype/AzureMetadataTypeEditor.java
+++ b/plugins/tech/azure/src/main/java/org/apache/hop/vfs/azure/metadatatype/AzureMetadataTypeEditor.java
@@ -24,6 +24,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -41,7 +42,7 @@ public class AzureMetadataTypeEditor extends MetadataEditor<AzureMetadataType> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private TextVar wStorageAccountName;
   private ComboVar wAuthenticationType;
@@ -76,7 +77,9 @@ public class AzureMetadataTypeEditor extends MetadataEditor<AzureMetadataType> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/cassandra/src/main/java/org/apache/hop/databases/cassandra/metadata/CassandraConnectionEditor.java b/plugins/tech/cassandra/src/main/java/org/apache/hop/databases/cassandra/metadata/CassandraConnectionEditor.java
index 30c42c1298..aa16debd59 100644
--- a/plugins/tech/cassandra/src/main/java/org/apache/hop/databases/cassandra/metadata/CassandraConnectionEditor.java
+++ b/plugins/tech/cassandra/src/main/java/org/apache/hop/databases/cassandra/metadata/CassandraConnectionEditor.java
@@ -31,6 +31,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.workflow.actions.execcql.ExecCql;
 import org.eclipse.swt.SWT;
@@ -40,7 +42,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 public class CassandraConnectionEditor extends MetadataEditor<CassandraConnection> {
 
@@ -48,7 +49,7 @@ public class CassandraConnectionEditor extends MetadataEditor<CassandraConnectio
   public static final String CONST_ERROR = "Error";
 
   private Composite parent;
-  private Text wName;
+  private TextVar wName;
   private GuiCompositeWidgets widgets;
 
   public CassandraConnectionEditor(
@@ -75,7 +76,9 @@ public class CassandraConnectionEditor extends MetadataEditor<CassandraConnectio
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/cassandra/src/main/java/org/apache/hop/pipeline/transforms/cassandrasstableoutput/SSTableOutputDialog.java b/plugins/tech/cassandra/src/main/java/org/apache/hop/pipeline/transforms/cassandrasstableoutput/SSTableOutputDialog.java
index d78474f10d..d505e60ca9 100644
--- a/plugins/tech/cassandra/src/main/java/org/apache/hop/pipeline/transforms/cassandrasstableoutput/SSTableOutputDialog.java
+++ b/plugins/tech/cassandra/src/main/java/org/apache/hop/pipeline/transforms/cassandrasstableoutput/SSTableOutputDialog.java
@@ -29,6 +29,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -205,7 +206,9 @@ public class SSTableOutputDialog extends BaseTransformDialog {
     fd.right = new FormAttachment(middle, -margin);
     wlTable.setLayoutData(fd);
 
-    wTable = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(e -> wTable.setToolTipText(variables.resolve(wTable.getText())));
     fd = new FormData();
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/databricks/metadata/DatabricksConnectionEditor.java b/plugins/tech/databricks/src/main/java/org/apache/hop/databricks/metadata/DatabricksConnectionEditor.java
index c71499ac9f..6803561f92 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/databricks/metadata/DatabricksConnectionEditor.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/databricks/metadata/DatabricksConnectionEditor.java
@@ -29,6 +29,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -38,7 +40,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "Editor for Databricks workspace connection metadata")
 public class DatabricksConnectionEditor extends MetadataEditor<DatabricksConnection> {
@@ -47,7 +48,7 @@ public class DatabricksConnectionEditor extends MetadataEditor<DatabricksConnect
 
   public static final String GUI_WIDGETS_PARENT_ID = "DatabricksConnectionEditor-GuiWidgetsParent";
 
-  private Text wName;
+  private TextVar wName;
   private Composite wWidgetsComposite;
   private GuiCompositeWidgets guiCompositeWidgets;
 
@@ -78,7 +79,9 @@ public class DatabricksConnectionEditor extends MetadataEditor<DatabricksConnect
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/vfs/databricks/metadata/DatabricksVfsConnectionEditor.java b/plugins/tech/databricks/src/main/java/org/apache/hop/vfs/databricks/metadata/DatabricksVfsConnectionEditor.java
index faa824caa6..1f791f3698 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/vfs/databricks/metadata/DatabricksVfsConnectionEditor.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/vfs/databricks/metadata/DatabricksVfsConnectionEditor.java
@@ -32,6 +32,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -41,7 +43,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "Editor for Databricks Volumes / Workspace VFS metadata")
 public class DatabricksVfsConnectionEditor extends MetadataEditor<DatabricksVfsConnection> {
@@ -51,7 +52,7 @@ public class DatabricksVfsConnectionEditor extends MetadataEditor<DatabricksVfsC
   public static final String GUI_WIDGETS_PARENT_ID =
       "DatabricksVfsConnectionEditor-GuiWidgetsParent";
 
-  private Text wName;
+  private TextVar wName;
   private Composite wWidgetsComposite;
   private GuiCompositeWidgets guiCompositeWidgets;
 
@@ -84,7 +85,9 @@ public class DatabricksVfsConnectionEditor extends MetadataEditor<DatabricksVfsC
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRunDialog.java b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRunDialog.java
index fe5ee71cc2..a53dcc5405 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRunDialog.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobRunDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.pipeline.HopPipelineFileType;
@@ -50,7 +51,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 /** Dialog for {@link ActionDatabricksJobRun}. */
 public class ActionDatabricksJobRunDialog extends ActionDialog {
@@ -59,7 +59,7 @@ public class ActionDatabricksJobRunDialog extends ActionDialog {
   private ActionDatabricksJobRun action;
   private boolean changed;
 
-  private Text wName;
+  private TextVar wName;
   private MetaSelectionLine<DatabricksConnection> wConnection;
   private CCombo wRunMode;
   private TextVar wJobId;
@@ -143,7 +143,9 @@ public class ActionDatabricksJobRunDialog extends ActionDialog {
     fdlName.right = new FormAttachment(middle, -margin);
     fdlName.top = new FormAttachment(0, margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_ACTION);
     PropsUi.setLook(wName);
     wName.addModifyListener(lsMod);
     FormData fdName = new FormData();
diff --git a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWaitDialog.java b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWaitDialog.java
index 1b63b02ca5..72c7d93577 100644
--- a/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWaitDialog.java
+++ b/plugins/tech/databricks/src/main/java/org/apache/hop/workflow/actions/databricks/ActionDatabricksJobWaitDialog.java
@@ -26,6 +26,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.apache.hop.ui.workflow.action.ActionDialog;
@@ -41,7 +42,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 /** Dialog for {@link ActionDatabricksJobWait}. */
 public class ActionDatabricksJobWaitDialog extends ActionDialog {
@@ -50,7 +50,7 @@ public class ActionDatabricksJobWaitDialog extends ActionDialog {
   private ActionDatabricksJobWait action;
   private boolean changed;
 
-  private Text wName;
+  private TextVar wName;
   private MetaSelectionLine<DatabricksConnection> wConnection;
   private TextVar wRunId;
   private TextVar wTimeout;
@@ -107,7 +107,9 @@ public class ActionDatabricksJobWaitDialog extends ActionDialog {
     fdlName.right = new FormAttachment(middle, -margin);
     fdlName.top = new FormAttachment(0, margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_ACTION);
     PropsUi.setLook(wName);
     wName.addModifyListener(lsMod);
     FormData fdName = new FormData();
diff --git a/plugins/tech/ftp/src/main/java/org/apache/hop/vfs/ftp/metadata/FtpConnectionEditor.java b/plugins/tech/ftp/src/main/java/org/apache/hop/vfs/ftp/metadata/FtpConnectionEditor.java
index f8604f56d6..d5698698ab 100644
--- a/plugins/tech/ftp/src/main/java/org/apache/hop/vfs/ftp/metadata/FtpConnectionEditor.java
+++ b/plugins/tech/ftp/src/main/java/org/apache/hop/vfs/ftp/metadata/FtpConnectionEditor.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -62,7 +63,7 @@ public class FtpConnectionEditor extends MetadataEditor<FtpConnection> {
   private final int middle;
   private final int margin;
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
 
   private CCombo wSecurityMode;
@@ -120,7 +121,9 @@ public class FtpConnectionEditor extends MetadataEditor<FtpConnection> {
   public void createControl(Composite parent) {
     IVariables variables = manager.getVariables();
 
-    wName = addTextLine(parent, null, "FtpConnectionEditor.Name.Label");
+    wName =
+        addTextVarLine(variables, parent, null, "FtpConnectionEditor.Name.Label")
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     wDescription = addTextLine(parent, wName, "FtpConnectionEditor.Description.Label");
 
     Button wTest = new Button(parent, SWT.PUSH);
diff --git a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/metadatatype/GoogleStorageMetadataTypeEditor.java b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/metadatatype/GoogleStorageMetadataTypeEditor.java
index dc4bfbb513..99337e7ce2 100644
--- a/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/metadatatype/GoogleStorageMetadataTypeEditor.java
+++ b/plugins/tech/google/src/main/java/org/apache/hop/vfs/gs/metadatatype/GoogleStorageMetadataTypeEditor.java
@@ -26,6 +26,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
@@ -43,7 +44,7 @@ public class GoogleStorageMetadataTypeEditor extends MetadataEditor<GoogleStorag
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private TextVar wStorageAccountKey;
   private Combo wStorageCredentialType;
@@ -74,7 +75,9 @@ public class GoogleStorageMetadataTypeEditor extends MetadataEditor<GoogleStorag
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/minio/src/main/java/org/apache/hop/vfs/minio/metadata/MinioMetaEditor.java b/plugins/tech/minio/src/main/java/org/apache/hop/vfs/minio/metadata/MinioMetaEditor.java
index 8807d777e9..3f73564be4 100644
--- a/plugins/tech/minio/src/main/java/org/apache/hop/vfs/minio/metadata/MinioMetaEditor.java
+++ b/plugins/tech/minio/src/main/java/org/apache/hop/vfs/minio/metadata/MinioMetaEditor.java
@@ -26,6 +26,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -34,7 +36,6 @@ import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "This is the editor for Minio connection metadata")
 public class MinioMetaEditor extends MetadataEditor<MinioMeta> {
@@ -45,7 +46,7 @@ public class MinioMetaEditor extends MetadataEditor<MinioMeta> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Composite wWidgetsComposite;
   private GuiCompositeWidgets guiCompositeWidgets;
 
@@ -79,7 +80,9 @@ public class MinioMetaEditor extends MetadataEditor<MinioMeta> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/mongo/metadata/MongoDbConnectionEditor.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/mongo/metadata/MongoDbConnectionEditor.java
index 3f4629c83a..b37615829b 100644
--- a/plugins/tech/mongodb/src/main/java/org/apache/hop/mongo/metadata/MongoDbConnectionEditor.java
+++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/mongo/metadata/MongoDbConnectionEditor.java
@@ -35,6 +35,8 @@ import org.apache.hop.ui.core.metadata.IMetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
@@ -43,7 +45,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 public class MongoDbConnectionEditor extends MetadataEditor<MongoDbConnection>
     implements IMetadataEditor<MongoDbConnection> {
@@ -51,7 +52,7 @@ public class MongoDbConnectionEditor extends MetadataEditor<MongoDbConnection>
   public static final String PARENT_WIDGET_ID = "MongoDbConnectionEditor.Widgets.ParentId";
 
   private Composite parent;
-  private Text wName;
+  private TextVar wName;
   private GuiCompositeWidgets widgets;
 
   public MongoDbConnectionEditor(
@@ -77,7 +78,9 @@ public class MongoDbConnectionEditor extends MetadataEditor<MongoDbConnection>
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputDialog.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputDialog.java
index d2bd08b814..1ba36089e1 100644
--- a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputDialog.java
+++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbinput/MongoDbInputDialog.java
@@ -48,6 +48,7 @@ import org.apache.hop.ui.core.dialog.ShowMessageDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -402,6 +403,7 @@ public class MongoDbInputDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     colinf[2].setComboValues(ValueMetaFactory.getAllValueMetaNames());
     colinf[4].setReadOnly(true);
diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMqlDialog.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMqlDialog.java
index 79eeb9f818..caa37f74a2 100644
--- a/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMqlDialog.java
+++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/workflow/actions/mql/ActionMqlDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TextComposite;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -43,7 +44,6 @@ import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * This dialog allows you to edit the MongoDB QL action settings. (select the connection and the
@@ -52,7 +52,7 @@ import org.eclipse.swt.widgets.Text;
 public class ActionMqlDialog extends ActionDialog {
   private static final Class<?> PKG = ActionMql.class;
 
-  private Text wName;
+  private TextVar wName;
 
   private MetaSelectionLine<MongoDbConnection> wConnection;
 
@@ -117,7 +117,9 @@ public class ActionMqlDialog extends ActionDialog {
     fdlName.right = new FormAttachment(middle, -margin);
     fdlName.top = new FormAttachment(0, margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_ACTION);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.left = new FormAttachment(middle, 0);
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/model/GraphModelEditor.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/model/GraphModelEditor.java
index 27765e8650..a3c454518f 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/model/GraphModelEditor.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/model/GraphModelEditor.java
@@ -52,7 +52,9 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.pipeline.HopGuiPipelineGraph;
 import org.apache.hop.ui.hopgui.perspective.metadata.MetadataPerspective;
@@ -100,7 +102,7 @@ public class GraphModelEditor extends MetadataEditor<GraphModel> {
 
   // Model fields
   private Text wModelDescription;
-  private Text wModelName;
+  private TextVar wModelName;
 
   // Node fields
   private List wNodesList;
@@ -377,7 +379,9 @@ public class GraphModelEditor extends MetadataEditor<GraphModel> {
     fdlModelName.right = new FormAttachment(middle, 0);
     fdlModelName.top = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlModelName);
-    wModelName = new Text(wModelComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wModelName =
+        new TextVar(hopGui.getVariables(), wModelComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wModelName);
     FormData fdModelName = new FormData();
     fdModelName.left = new FormAttachment(middle, margin);
diff --git a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/shared/NeoConnectionEditor.java b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/shared/NeoConnectionEditor.java
index eb188a83cf..0b85216aba 100644
--- a/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/shared/NeoConnectionEditor.java
+++ b/plugins/tech/neo4j/src/main/java/org/apache/hop/neo4j/shared/NeoConnectionEditor.java
@@ -29,6 +29,7 @@ import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.CheckBoxVar;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -48,7 +49,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 /** Dialog that allows you to edit the settings of a Neo4j connection */
 public class NeoConnectionEditor extends MetadataEditor<NeoConnection> {
@@ -58,7 +58,7 @@ public class NeoConnectionEditor extends MetadataEditor<NeoConnection> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private Label wlAutomatic;
   private CheckBoxVar wAutomatic;
   private TextVar wProtocol;
@@ -115,7 +115,9 @@ public class NeoConnectionEditor extends MetadataEditor<NeoConnection> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/input/ParquetInputDialog.java b/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/input/ParquetInputDialog.java
index 67969a3b7d..873b6ee87c 100644
--- a/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/input/ParquetInputDialog.java
+++ b/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/input/ParquetInputDialog.java
@@ -27,6 +27,7 @@ import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -95,7 +96,9 @@ public class ParquetInputDialog extends BaseTransformDialog {
     fdlMetaFilename.right = new FormAttachment(middle, -margin);
     fdlMetaFilename.top = new FormAttachment(lastControl, margin);
     wlMetaFilename.setLayoutData(fdlMetaFilename);
-    wMetaFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wMetaFilename =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wMetaFilename);
     FormData fdMetaFilename = new FormData();
     fdMetaFilename.left = new FormAttachment(middle, 0);
@@ -161,6 +164,7 @@ public class ParquetInputDialog extends BaseTransformDialog {
               true,
               false),
         };
+    columns[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     wFields =
         new TableView(
             variables, shell, SWT.BORDER, columns, input.getFields().size(), false, null, props);
diff --git a/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/output/ParquetOutputDialog.java b/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/output/ParquetOutputDialog.java
index 91869d3b39..47b21e7e4f 100644
--- a/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/output/ParquetOutputDialog.java
+++ b/plugins/tech/parquet/src/main/java/org/apache/hop/parquet/transforms/output/ParquetOutputDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -112,7 +113,9 @@ public class ParquetOutputDialog extends BaseTransformDialog {
     fdlFilenameBase.top = new FormAttachment(0, margin);
     fdlFilenameBase.right = new FormAttachment(middle, -margin);
     wlFilenameBase.setLayoutData(fdlFilenameBase);
-    wFilenameBase = new TextVar(variables, wFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilenameBase =
+        new TextVar(variables, wFileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilenameBase);
     FormData fdFilenameBase = new FormData();
     fdFilenameBase.left = new FormAttachment(middle, 0);
@@ -531,6 +534,7 @@ public class ParquetOutputDialog extends BaseTransformDialog {
               false,
               false),
         };
+    columns[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     wFields =
         new TableView(
             variables, shell, SWT.BORDER, columns, input.getFields().size(), false, null, props);
diff --git a/plugins/tech/redis/src/main/java/org/apache/hop/redis/metadata/RedisConnectionEditor.java b/plugins/tech/redis/src/main/java/org/apache/hop/redis/metadata/RedisConnectionEditor.java
index aff5d290ae..94c8543936 100644
--- a/plugins/tech/redis/src/main/java/org/apache/hop/redis/metadata/RedisConnectionEditor.java
+++ b/plugins/tech/redis/src/main/java/org/apache/hop/redis/metadata/RedisConnectionEditor.java
@@ -29,6 +29,8 @@ import org.apache.hop.ui.core.gui.GuiCompositeWidgets;
 import org.apache.hop.ui.core.gui.GuiCompositeWidgetsAdapter;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
@@ -43,7 +45,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 /** redis connection editor */
 @SuppressWarnings("java:S2160")
@@ -58,7 +59,7 @@ public class RedisConnectionEditor extends MetadataEditor<RedisConnection> {
   public static final String POOL_WIDGET_ID = "RedisConnectionEditor.Pool.ParentId";
 
   private Composite parent;
-  private Text wName;
+  private TextVar wName;
   private GuiCompositeWidgets connectionWidgets;
   private GuiCompositeWidgets poolWidgets;
   private Group gConnection;
@@ -87,7 +88,9 @@ public class RedisConnectionEditor extends MetadataEditor<RedisConnection> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/metadata/salesforce/SalesforceConnectionEditor.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/metadata/salesforce/SalesforceConnectionEditor.java
index ed61d4cd48..b584544def 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/metadata/salesforce/SalesforceConnectionEditor.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/metadata/salesforce/SalesforceConnectionEditor.java
@@ -39,6 +39,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.LabelTextVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -59,7 +60,7 @@ import org.eclipse.swt.widgets.Text;
 public class SalesforceConnectionEditor extends MetadataEditor<SalesforceConnection> {
   private static final Class<?> PKG = SalesforceConnectionEditor.class;
 
-  private Text wName;
+  private TextVar wName;
 
   // Authentication Type
   private Label wlAuthType;
@@ -124,7 +125,9 @@ public class SalesforceConnectionEditor extends MetadataEditor<SalesforceConnect
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputDialog.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputDialog.java
index 8f117e1306..e65523b713 100644
--- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputDialog.java
+++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinput/SalesforceInputDialog.java
@@ -52,6 +52,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.LabelTextVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -1292,6 +1293,7 @@ public class SalesforceInputDialog extends SalesforceTransformDialog {
         };
 
     columns[0].setUsingVariables(true);
+    columns[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     columns[0].setToolTip(
         BaseMessages.getString(PKG, "SalesforceInputDialog.FieldsTable.Name.Column.Tooltip"));
     columns[1].setUsingVariables(true);
diff --git a/plugins/tech/sftp/src/main/java/org/apache/hop/vfs/sftp/metadata/SftpConnectionEditor.java b/plugins/tech/sftp/src/main/java/org/apache/hop/vfs/sftp/metadata/SftpConnectionEditor.java
index b5d5809dd0..ee7bdf0b61 100644
--- a/plugins/tech/sftp/src/main/java/org/apache/hop/vfs/sftp/metadata/SftpConnectionEditor.java
+++ b/plugins/tech/sftp/src/main/java/org/apache/hop/vfs/sftp/metadata/SftpConnectionEditor.java
@@ -31,6 +31,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -57,7 +58,7 @@ public class SftpConnectionEditor extends MetadataEditor<SftpConnection> {
   private final int middle;
   private final int margin;
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
 
   private TextVar wServerName;
@@ -98,7 +99,9 @@ public class SftpConnectionEditor extends MetadataEditor<SftpConnection> {
   public void createControl(Composite parent) {
     IVariables variables = manager.getVariables();
 
-    wName = addTextLine(parent, null, "SftpConnectionEditor.Name.Label");
+    wName =
+        addTextVarLine(variables, parent, null, "SftpConnectionEditor.Name.Label")
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     wDescription = addTextLine(parent, wName, "SftpConnectionEditor.Description.Label");
 
     Button wTest = new Button(parent, SWT.PUSH);
diff --git a/plugins/tech/webdav/src/main/java/org/apache/hop/vfs/webdav/metadata/WebDavConnectionEditor.java b/plugins/tech/webdav/src/main/java/org/apache/hop/vfs/webdav/metadata/WebDavConnectionEditor.java
index 3f74627921..a83eb5dea9 100644
--- a/plugins/tech/webdav/src/main/java/org/apache/hop/vfs/webdav/metadata/WebDavConnectionEditor.java
+++ b/plugins/tech/webdav/src/main/java/org/apache/hop/vfs/webdav/metadata/WebDavConnectionEditor.java
@@ -24,6 +24,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -41,7 +42,7 @@ public class WebDavConnectionEditor extends MetadataEditor<WebDavConnection> {
 
   private static final Class<?> PKG = WebDavConnectionEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private TextVar wRootUrl;
   private TextVar wUsername;
@@ -70,7 +71,9 @@ public class WebDavConnectionEditor extends MetadataEditor<WebDavConnection> {
     fdlName.left = new FormAttachment(0, 0);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceDialog.java b/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceDialog.java
index 1269420838..22f6a971f5 100644
--- a/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceDialog.java
+++ b/plugins/transforms/addsequence/src/main/java/org/apache/hop/pipeline/transforms/addsequence/AddSequenceDialog.java
@@ -30,6 +30,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -52,7 +53,7 @@ import org.eclipse.swt.widgets.Text;
 public class AddSequenceDialog extends BaseTransformDialog {
   private static final Class<?> PKG = AddSequenceMeta.class;
 
-  private Text wValuename;
+  private TextVar wValuename;
 
   private Button wUseDatabase;
 
@@ -128,7 +129,9 @@ public class AddSequenceDialog extends BaseTransformDialog {
     fdlValuename.top = new FormAttachment(0, margin);
     fdlValuename.right = new FormAttachment(middle, -margin);
     wlValuename.setLayoutData(fdlValuename);
-    wValuename = new Text(wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wValuename =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_FIELD);
     wValuename.setText("");
     PropsUi.setLook(wValuename);
     wValuename.addModifyListener(lsMod);
diff --git a/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java b/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java
index 9fd216bc56..ea390984d0 100644
--- a/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java
+++ b/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageDialogWithToggle;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -136,6 +137,7 @@ public class AnalyticQueryDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "AnalyticQueryDialog.ColumnInfo.Name"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciReturn[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "AnalyticQueryDialog.ColumnInfo.Subject"),
diff --git a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
index 580ec0beb2..540a6a028d 100644
--- a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
+++ b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -162,6 +163,7 @@ public class CalculatorDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     colinf[1].setSelectionAdapter(
         new SelectionAdapter() {
diff --git a/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsDialog.java b/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsDialog.java
index d6fe8aec6d..3f1730d5c5 100644
--- a/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsDialog.java
+++ b/plugins/transforms/columnexists/src/main/java/org/apache/hop/pipeline/transforms/columnexists/ColumnExistsDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -179,7 +180,9 @@ public class ColumnExistsDialog extends BaseTransformDialog {
           }
         });
 
-    wTablenameText = new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTablenameText =
+        new TextVar(variables, wContent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     wTablenameText.setToolTipText(
         BaseMessages.getString(PKG, "ColumnExistsDialog.TablenameTextField.Tooltip"));
     PropsUi.setLook(wTablenameText);
diff --git a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java
index ce66e7e3ed..8ce1da40df 100644
--- a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java
+++ b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java
@@ -42,6 +42,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -79,7 +80,7 @@ public class CombinationLookupDialog extends BaseTransformDialog {
 
   private Button wPreloadCache;
 
-  private Text wTk;
+  private TextVar wTk;
 
   private Label wlAutoinc;
   private Button wAutoinc;
@@ -98,7 +99,7 @@ public class CombinationLookupDialog extends BaseTransformDialog {
   private TableView wKey;
 
   private Label wlHashfield;
-  private Text wHashfield;
+  private TextVar wHashfield;
 
   private Text wLastUpdateField;
 
@@ -174,7 +175,9 @@ public class CombinationLookupDialog extends BaseTransformDialog {
     fdbSchema.right = new FormAttachment(100, 0);
     wbSchema.setLayoutData(fdbSchema);
 
-    wSchema = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     wSchema.addModifyListener(lsTableMod);
     FormData fdSchema = new FormData();
@@ -201,7 +204,9 @@ public class CombinationLookupDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wbSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
@@ -287,6 +292,7 @@ public class CombinationLookupDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciKey[0]);
     wKey =
         new TableView(
@@ -326,7 +332,9 @@ public class CombinationLookupDialog extends BaseTransformDialog {
     fdlHashfield.right = new FormAttachment(middle, -margin);
     fdlHashfield.bottom = new FormAttachment(wLastUpdateField, -margin);
     wlHashfield.setLayoutData(fdlHashfield);
-    wHashfield = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wHashfield =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_COLUMN);
     PropsUi.setLook(wHashfield);
     wHashfield.addModifyListener(lsMod);
     FormData fdHashfield = new FormData();
@@ -482,7 +490,9 @@ public class CombinationLookupDialog extends BaseTransformDialog {
     fdlTk.right = new FormAttachment(middle, -margin);
     fdlTk.bottom = new FormAttachment(gTechGroup, -margin);
     wlTk.setLayoutData(fdlTk);
-    wTk = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTk =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_COLUMN);
     PropsUi.setLook(wTk);
     FormData fdTk = new FormData();
     fdTk.left = new FormAttachment(middle, 0);
diff --git a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java
index ab17c15b07..70190a90e8 100644
--- a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java
+++ b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java
@@ -37,6 +37,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -117,7 +118,9 @@ public class ConcatFieldsDialog extends BaseTransformDialog {
     PropsUi.setLook(wlTargetFieldName);
     wlTargetFieldName.setLayoutData(
         FormDataBuilder.builder().top(lastControl, margin).left().right(middle, -margin).build());
-    wTargetFieldName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTargetFieldName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.HOP_FIELD);
     PropsUi.setLook(wTargetFieldName);
     wTargetFieldName.setLayoutData(
         FormDataBuilder.builder()
diff --git a/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantDialog.java b/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantDialog.java
index e5510cbb0f..276bca6aca 100644
--- a/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantDialog.java
+++ b/plugins/transforms/constant/src/main/java/org/apache/hop/pipeline/transforms/constant/ConstantDialog.java
@@ -29,6 +29,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.BaseMessageDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -81,6 +82,7 @@ public class ConstantDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "ConstantDialog.Name.Column"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colinf[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "ConstantDialog.Type.Column"),
diff --git a/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupDialog.java b/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupDialog.java
index bfe89319d5..602abac31d 100644
--- a/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupDialog.java
+++ b/plugins/transforms/databaselookup/src/main/java/org/apache/hop/pipeline/transforms/databaselookup/DatabaseLookupDialog.java
@@ -44,6 +44,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ColumnsResizer;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -259,7 +260,9 @@ public class DatabaseLookupDialog extends BaseTransformDialog {
     fdbSchema.right = new FormAttachment(100, 0);
     wbSchema.setLayoutData(fdbSchema);
 
-    wSchema = new TextVar(variables, fieldGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, fieldGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     wSchema.addModifyListener(lsTableMod);
     FormData fdSchema = new FormData();
@@ -286,7 +289,9 @@ public class DatabaseLookupDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wbSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, fieldGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, fieldGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
@@ -488,6 +493,7 @@ public class DatabaseLookupDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "DatabaseLookupDialog.ColumnInfo.Newname"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciReturn[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     ciReturn[2] =
         new ColumnInfo(
diff --git a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
index d45b84e511..98f655a356 100644
--- a/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
+++ b/plugins/transforms/datagrid/src/main/java/org/apache/hop/pipeline/transforms/datagrid/DataGridDialog.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.EnterTextDialog;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -146,6 +147,7 @@ public class DataGridDialog extends BaseTransformDialog {
               BaseMessages.getString(PKG, SYSTEM_COMBO_YES),
               BaseMessages.getString(PKG, "System.Combo.No")),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java
index 53dc7a2ec9..1db88a42a4 100644
--- a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java
+++ b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java
@@ -43,6 +43,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -198,7 +199,9 @@ public class DeleteDialog extends BaseTransformDialog {
     wbSchema.setLayoutData(fdbSchema);
     wbSchema.addListener(SWT.Selection, e -> getSchemaNames());
 
-    wSchema = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     wSchema.addModifyListener(lsTableMod);
     FormData fdSchema = new FormData();
@@ -226,7 +229,9 @@ public class DeleteDialog extends BaseTransformDialog {
     wbTable.setLayoutData(fdbTable);
     wbTable.addListener(SWT.Selection, e -> getTableName());
 
-    wTable = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
@@ -331,6 +336,7 @@ public class DeleteDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciKey[0]);
     wKey =
         new TableView(
diff --git a/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowDialog.java b/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowDialog.java
index 8c63e8096a..d7ae321c8a 100644
--- a/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowDialog.java
+++ b/plugins/transforms/detectlastrow/src/main/java/org/apache/hop/pipeline/transforms/detectlastrow/DetectLastRowDialog.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -67,7 +68,9 @@ public class DetectLastRowDialog extends BaseTransformDialog {
     fdlResult.top = new FormAttachment(wSpacer, margin);
     wlResult.setLayoutData(fdlResult);
 
-    wResult = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wResult =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.HOP_FIELD);
     wResult.setToolTipText(BaseMessages.getString(PKG, "DetectLastRowDialog.ResultField.Tooltip"));
     PropsUi.setLook(wResult);
     wResult.addModifyListener(lsMod);
diff --git a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java
index 8fc5a31a20..70f272dde9 100644
--- a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java
+++ b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java
@@ -60,6 +60,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -114,7 +115,7 @@ public class DimensionLookupDialog extends BaseTransformDialog {
   private Combo wTk;
 
   private Label wlTkRename;
-  private Text wTkRename;
+  private TextVar wTkRename;
 
   private Button wTkAutoIncrement;
   private Button wTkUuid;
@@ -125,7 +126,7 @@ public class DimensionLookupDialog extends BaseTransformDialog {
   private Text wSeq;
 
   private Button wTkFieldButton;
-  private Text wTkField;
+  private TextVar wTkField;
 
   private Button wDisableUnknownUpdate;
   private Button wShowUnknownTk;
@@ -315,7 +316,9 @@ public class DimensionLookupDialog extends BaseTransformDialog {
     wbSchema.setLayoutData(fdbSchema);
     wbSchema.addListener(SWT.Selection, e -> getSchemaNames());
 
-    wSchema = new TextVar(variables, wPhysicalComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, wPhysicalComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     FormData fdSchema = new FormData();
     fdSchema.left = new FormAttachment(middle, 0);
@@ -342,7 +345,9 @@ public class DimensionLookupDialog extends BaseTransformDialog {
     wbTable.setLayoutData(fdbTable);
     wbTable.addListener(SWT.Selection, e -> getTableName());
 
-    wTable = new TextVar(variables, wPhysicalComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wPhysicalComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     FormData fdTable = new FormData();
     fdTable.left = new FormAttachment(middle, 0);
@@ -563,7 +568,9 @@ public class DimensionLookupDialog extends BaseTransformDialog {
     fdlTkRename.top = new FormAttachment(wlTk, 0, SWT.CENTER);
     wlTkRename.setLayoutData(fdlTkRename);
 
-    wTkRename = new Text(wTechnicalKeyComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTkRename =
+        new TextVar(variables, wTechnicalKeyComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_FIELD);
     PropsUi.setLook(wTkRename);
     FormData fdTkRename = new FormData();
     fdTkRename.left = new FormAttachment(wlTkRename, margin);
@@ -658,7 +665,9 @@ public class DimensionLookupDialog extends BaseTransformDialog {
     wTkFieldButton.setText(BaseMessages.getString(PKG, "DimensionLookupDialog.TkField.Label"));
     wTkFieldButton.addListener(SWT.Selection, e -> setTkType(FIELD));
 
-    wTkField = new Text(gTechGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTkField =
+        new TextVar(variables, gTechGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_FIELD);
     PropsUi.setLook(wTkField);
     FormData fdTkField = new FormData();
     fdTkField.left = new FormAttachment(wTkFieldButton, margin);
@@ -803,6 +812,7 @@ public class DimensionLookupDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    fieldColumns[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     fieldColumns[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "DimensionLookupDialog.ColumnInfo.StreamField"),
diff --git a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputDialog.java b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputDialog.java
index 1ed3c03996..3b2cdfe8cc 100644
--- a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputDialog.java
+++ b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelinput/ExcelInputDialog.java
@@ -65,6 +65,8 @@ import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeColumnApplierRegistry;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -416,6 +418,7 @@ public class ExcelInputDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_TEXT_BUTTON,
             false);
     colinfo[0].setUsingVariables(true);
+    colinfo[0].setNamingSchemeType(NamingSchemeTypes.FILE);
     colinfo[0].setTextVarButtonSelectionListener(getFileSelectionAdapter());
     colinfo[1] =
         new ColumnInfo(
@@ -857,6 +860,7 @@ public class ExcelInputDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT)
         };
 
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colinf[5].setToolTip(BaseMessages.getString(PKG, "ExcelInputDialog.Repeat.Tooltip"));
 
     wFields =
@@ -1798,6 +1802,8 @@ public class ExcelInputDialog extends BaseTransformDialog {
       wFields.removeEmptyRows();
       wFields.setRowNums();
       wFields.optWidth(true);
+      NamingSchemeColumnApplierRegistry.getInstance()
+          .applyAnnotatedColumns(wFields, metadataProvider, null);
     } else {
       MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING);
       mb.setMessage(
diff --git a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java
index 3f30743788..21839cf841 100644
--- a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java
+++ b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java
@@ -46,6 +46,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
@@ -252,7 +253,9 @@ public class ExcelWriterTransformDialog extends BaseTransformDialog {
     fdbFilename.top = new FormAttachment(0, 0);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, fileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, fileGroup, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     wFilename.setToolTipText(BaseMessages.getString(PKG, "ExcelWriterDialog.Filename.Tooltip"));
diff --git a/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerDialog.java b/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerDialog.java
index c7a8d0cf4f..bcd1bb4d8d 100644
--- a/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerDialog.java
+++ b/plugins/transforms/flattener/src/main/java/org/apache/hop/pipeline/transforms/flattener/FlattenerDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -113,6 +114,7 @@ public class FlattenerDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "FlattenerDialog.ColumnInfo.TargetField"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java
index d6b5c6b96e..1991b09794 100644
--- a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java
+++ b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -127,6 +128,7 @@ public class FormulaDialog extends BaseTransformDialog {
               BaseMessages.getString(PKG, SYSTEM_COMBO_YES),
               BaseMessages.getString(PKG, "System.Combo.No")),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesDialog.java b/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesDialog.java
index a6a259b5ab..622aadd0b0 100644
--- a/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesDialog.java
+++ b/plugins/transforms/getfilenames/src/main/java/org/apache/hop/pipeline/transforms/getfilenames/GetFileNamesDialog.java
@@ -41,6 +41,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -310,7 +311,9 @@ public class GetFileNamesDialog extends BaseTransformDialog {
     wbaFilename.setLayoutData(
         new FormDataBuilder().top(wlFilename, 0, SWT.CENTER).right(wbbFilename, -margin).result());
 
-    wFilename = new TextVar(variables, group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, group, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     wFilename.setLayoutData(
diff --git a/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesDialog.java b/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesDialog.java
index 2a192b5d23..db0c363e24 100644
--- a/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesDialog.java
+++ b/plugins/transforms/gettablenames/src/main/java/org/apache/hop/pipeline/transforms/gettablenames/GetTableNamesDialog.java
@@ -36,6 +36,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -59,7 +60,7 @@ public class GetTableNamesDialog extends BaseTransformDialog {
 
   private MetaSelectionLine<DatabaseMeta> wConnection;
 
-  private Text wTableNameField;
+  private TextVar wTableNameField;
   private Text wSqlCreationField;
   private Button wIncludeTable;
   private Button wIncludeSchema;
@@ -411,7 +412,9 @@ public class GetTableNamesDialog extends BaseTransformDialog {
     fdlTableNameField.right = new FormAttachment(middle, -margin);
     fdlTableNameField.top = new FormAttachment(wSettings, margin);
     wlTableNameField.setLayoutData(fdlTableNameField);
-    wTableNameField = new Text(wOutputFields, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTableNameField =
+        new TextVar(variables, wOutputFields, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_FIELD);
     wTableNameField.setToolTipText(
         BaseMessages.getString(PKG, "GetTableNamesDialog.TableNameFieldName.Tooltip"));
     PropsUi.setLook(wTableNameField);
diff --git a/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableDialog.java b/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableDialog.java
index 7ac38d8743..56ef5ef9e1 100644
--- a/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableDialog.java
+++ b/plugins/transforms/getvariable/src/main/java/org/apache/hop/pipeline/transforms/getvariable/GetVariableDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.EnterTextDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -130,6 +131,7 @@ public class GetVariableDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_CCOMBO,
               IValueMeta.TrimType.getDescriptions()),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     colinf[1].setToolTip(BaseMessages.getString(PKG, "GetVariableDialog.VariableColumn.Tooltip"));
     colinf[1].setUsingVariables(true);
diff --git a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java
index a8670f9a25..79755122ec 100644
--- a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java
+++ b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageDialogWithToggle;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -320,6 +321,7 @@ public class GroupByDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "GroupByDialog.ColumnInfo.Name"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciReturn[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "GroupByDialog.ColumnInfo.Subject"),
diff --git a/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateDialog.java b/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateDialog.java
index 99d54e82f7..2e14b0a8cd 100644
--- a/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateDialog.java
+++ b/plugins/transforms/insertupdate/src/main/java/org/apache/hop/pipeline/transforms/insertupdate/InsertUpdateDialog.java
@@ -50,6 +50,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -175,7 +176,9 @@ public class InsertUpdateDialog extends BaseTransformDialog {
     wbSchema.addListener(SWT.Selection, e -> getSchemaName());
     PropsUi.setLook(wbSchema);
 
-    wSchema = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     wSchema.addModifyListener(lsTableMod);
     wSchema.setLayoutData(
         new FormDataBuilder()
@@ -198,7 +201,9 @@ public class InsertUpdateDialog extends BaseTransformDialog {
     wbTable.addListener(SWT.Selection, e -> getTableName());
     PropsUi.setLook(wbTable);
 
-    wTable = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     wTable.addModifyListener(lsTableMod);
     wTable.setLayoutData(
         new FormDataBuilder()
@@ -270,6 +275,7 @@ public class InsertUpdateDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     ciKey[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "InsertUpdateDialog.ColumnInfo.Comparator"),
@@ -355,6 +361,7 @@ public class InsertUpdateDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     ciReturn[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "InsertUpdateDialog.ColumnInfo.StreamField"),
diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
index 67c837f26a..5e6ff80ee9 100644
--- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
+++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
@@ -37,6 +37,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -141,6 +142,7 @@ public class JaninoDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_CCOMBO,
               new String[] {}),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
index 94d7056bee..bb58a9bc13 100644
--- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
+++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java
@@ -61,6 +61,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.HopTree;
 import org.apache.hop.ui.core.widget.JavaStyledTextComp;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -589,6 +590,7 @@ public class UserDefinedJavaClassDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java
index 8063715920..ebaf272c09 100644
--- a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java
+++ b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java
@@ -54,6 +54,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.HopTree;
 import org.apache.hop.ui.core.widget.JavaScriptStyledTextComp;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -399,6 +400,8 @@ public class ScriptValuesDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_CCOMBO,
               YES_NO_COMBO),
         };
+    colInfos[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
+    colInfos[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/consumer/JmsConsumerDialog.java b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/consumer/JmsConsumerDialog.java
index 6b60cb9dc0..4984d413fd 100644
--- a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/consumer/JmsConsumerDialog.java
+++ b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/consumer/JmsConsumerDialog.java
@@ -36,7 +36,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 public class JmsConsumerDialog extends BaseTransformDialog {
   private static final Class<?> PKG = JmsConsumerMeta.class;
@@ -92,15 +91,14 @@ public class JmsConsumerDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(e -> input.setChanged());
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(e -> input.setChanged());
     Control last = wTransformName;
 
     wConnection =
diff --git a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/producer/JmsProducerDialog.java b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/producer/JmsProducerDialog.java
index b8e7538e01..150ef2ac4a 100644
--- a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/producer/JmsProducerDialog.java
+++ b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/producer/JmsProducerDialog.java
@@ -39,7 +39,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
 
 public class JmsProducerDialog extends BaseTransformDialog {
   private static final Class<?> PKG = JmsProducerMeta.class;
@@ -88,15 +87,14 @@ public class JmsProducerDialog extends BaseTransformDialog {
     fdlTransformName.top = new FormAttachment(0, margin);
     fdlTransformName.right = new FormAttachment(middle, -margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(e -> input.setChanged());
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(wlTransformName, 0, SWT.CENTER);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(e -> input.setChanged());
     Control last = wTransformName;
 
     wConnection =
diff --git a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/shared/JmsConnectionEditor.java b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/shared/JmsConnectionEditor.java
index 8e9bed38af..59b2dcf79f 100644
--- a/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/shared/JmsConnectionEditor.java
+++ b/plugins/transforms/jms/src/main/java/org/apache/hop/pipeline/transforms/jms/shared/JmsConnectionEditor.java
@@ -23,6 +23,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -34,14 +35,13 @@ import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 @GuiPlugin(description = "Editor for JMS connection metadata")
 public class JmsConnectionEditor extends MetadataEditor<JmsConnection> {
 
   private static final Class<?> PKG = JmsConnection.class;
 
-  private Text wName;
+  private TextVar wName;
   private CCombo wMode;
   private TextVar wBrokerUrl;
   private TextVar wInitialContextFactory;
@@ -82,7 +82,9 @@ public class JmsConnectionEditor extends MetadataEditor<JmsConnection> {
     fdlName.top = new FormAttachment(0, margin);
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.left = new FormAttachment(middle, 0);
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputDialog.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputDialog.java
index 4f737f02e2..c6bd71c94f 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputDialog.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsoninput/JsonInputDialog.java
@@ -56,6 +56,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -402,6 +403,7 @@ public class JsonInputDialog extends BaseTransformDialog {
               true),
         };
 
+    colInfos[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colInfos[0].setUsingVariables(true);
     colInfos[0].setToolTip(
         BaseMessages.getString(PKG, "JsonInputDialog.FieldsTable.Name.Column.Tooltip"));
@@ -952,7 +954,9 @@ public class JsonInputDialog extends BaseTransformDialog {
     fdbaFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java
index 3aaffbbd0c..9af39d37d9 100644
--- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java
+++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java
@@ -38,6 +38,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -309,7 +310,9 @@ public class JsonOutputDialog extends BaseTransformDialog {
                 },
                 true));
 
-    wFilename = new TextVar(variables, wFileName, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileName, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/transforms/languagemodelchat/src/main/java/org/apache/hop/pipeline/transforms/languagemodelchat/internals/ui/TransformNameComposite.java b/plugins/transforms/languagemodelchat/src/main/java/org/apache/hop/pipeline/transforms/languagemodelchat/internals/ui/TransformNameComposite.java
index 2316261398..a4f877e7ac 100644
--- a/plugins/transforms/languagemodelchat/src/main/java/org/apache/hop/pipeline/transforms/languagemodelchat/internals/ui/TransformNameComposite.java
+++ b/plugins/transforms/languagemodelchat/src/main/java/org/apache/hop/pipeline/transforms/languagemodelchat/internals/ui/TransformNameComposite.java
@@ -29,15 +29,16 @@ import static org.eclipse.swt.SWT.SINGLE;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hop.pipeline.transform.ITransformMeta;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 public class TransformNameComposite implements IDialogComposite {
   private final Label label;
-  private final Text inputField;
+  private final TextVar inputField;
   private final ITransformMeta meta;
   private final Control control;
   private final CompositeParameters parameters;
@@ -48,7 +49,9 @@ public class TransformNameComposite implements IDialogComposite {
 
     // Transform Name label
     this.label = new Label(parameters.shell(), RIGHT);
-    this.inputField = new Text(parameters.shell(), SINGLE | LEFT | BORDER);
+    this.inputField =
+        new TextVar(parameters.variables(), parameters.shell(), SINGLE | LEFT | BORDER)
+            .asNameField(NamingSchemeTypes.HOP_TRANSFORM);
 
     setLook(label);
     setLook(inputField);
@@ -86,7 +89,7 @@ public class TransformNameComposite implements IDialogComposite {
     return label;
   }
 
-  public Text getInputField() {
+  public TextVar getInputField() {
     return inputField;
   }
 
diff --git a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputDialog.java b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputDialog.java
index 7e340a2e3b..38040786fd 100644
--- a/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputDialog.java
+++ b/plugins/transforms/mapping/src/main/java/org/apache/hop/pipeline/transforms/input/MappingInputDialog.java
@@ -26,6 +26,7 @@ import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -92,6 +93,7 @@ public class MappingInputDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false)
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java
index 3806f4d40c..5bf7ef6b0d 100644
--- a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java
+++ b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -176,6 +177,7 @@ public class MemoryGroupByDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "MemoryGroupByDialog.ColumnInfo.Name"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciReturn[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "MemoryGroupByDialog.ColumnInfo.Subject"),
diff --git a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java
index 81295d1a31..65ef335092 100644
--- a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java
+++ b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java
@@ -31,6 +31,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -123,6 +124,7 @@ public class NormaliserDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "NormaliserDialog.ColumnInfo.NewField"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    colinf[2].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputDialog.java b/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputDialog.java
index 19ee61a774..1a2b7f9217 100644
--- a/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputDialog.java
+++ b/plugins/transforms/odata/src/main/java/org/apache/hop/pipeline/transforms/odata/ODataInputDialog.java
@@ -56,7 +56,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 public class ODataInputDialog extends BaseTransformDialog {
   private static final Class<?> PKG = ODataInputMeta.class;
@@ -113,15 +112,14 @@ public class ODataInputDialog extends BaseTransformDialog {
     fdlTransformName.right = new FormAttachment(middle, -margin);
     fdlTransformName.top = new FormAttachment(0, margin);
     wlTransformName.setLayoutData(fdlTransformName);
-    wTransformName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    wTransformName.setText(transformName);
-    PropsUi.setLook(wTransformName);
-    wTransformName.addModifyListener(lsMod);
     fdTransformName = new FormData();
     fdTransformName.left = new FormAttachment(middle, 0);
     fdTransformName.top = new FormAttachment(0, margin);
     fdTransformName.right = new FormAttachment(100, 0);
-    wTransformName.setLayoutData(fdTransformName);
+    createTransformNameControl(shell, fdTransformName);
+    wTransformName.setText(transformName);
+    PropsUi.setLook(wTransformName);
+    wTransformName.addModifyListener(lsMod);
 
     // Button bar at the bottom
     wOk = new Button(shell, SWT.PUSH);
diff --git a/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueDialog.java b/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueDialog.java
index 85821ffa2c..cea65ff8c4 100644
--- a/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueDialog.java
+++ b/plugins/transforms/randomvalue/src/main/java/org/apache/hop/pipeline/transforms/randomvalue/RandomValueDialog.java
@@ -25,6 +25,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -103,6 +104,7 @@ public class RandomValueDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false)
         };
+    columns[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     columns[1].setSelectionAdapter(
         new SelectionAdapter() {
           @Override
diff --git a/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalDialog.java b/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalDialog.java
index 0680952c73..7baf0fc0b7 100644
--- a/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalDialog.java
+++ b/plugins/transforms/regexeval/src/main/java/org/apache/hop/pipeline/transforms/regexeval/RegexEvalDialog.java
@@ -35,6 +35,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ColumnsResizer;
 import org.apache.hop.ui.core.widget.LabelTextVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.StyledTextComp;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextComposite;
@@ -362,6 +363,7 @@ public class RegexEvalDialog extends BaseTransformDialog {
               ValueMetaBase.trimTypeDesc,
               true),
         };
+    columnInfo[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java
index 99ea66bea7..a9ebf630a8 100644
--- a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java
+++ b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java
@@ -33,6 +33,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -100,6 +101,7 @@ public class ReplaceStringDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "ReplaceStringDialog.ColumnInfo.OutStreamField"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciKey[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciKey[2] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "ReplaceStringDialog.ColumnInfo.useRegEx"),
diff --git a/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorDialog.java b/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorDialog.java
index 8569706bbd..beebb1afed 100644
--- a/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorDialog.java
+++ b/plugins/transforms/rowgenerator/src/main/java/org/apache/hop/pipeline/transforms/rowgenerator/RowGeneratorDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.EnterTextDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -234,6 +235,7 @@ public class RowGeneratorDialog extends BaseTransformDialog {
               BaseMessages.getString(PKG, CONST_SYSTEM_COMBO_YES),
               BaseMessages.getString(PKG, "System.Combo.No"))
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colinf[0].setToolTip(BaseMessages.getString(PKG, "System.Column.Name.Tooltip"));
     colinf[1].setToolTip(BaseMessages.getString(PKG, "System.Column.Type.Tooltip"));
     colinf[2].setToolTip(BaseMessages.getString(PKG, "System.Column.Format.Tooltip"));
diff --git a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java
index a1d72584ba..9fbb68fd29 100644
--- a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java
+++ b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java
@@ -46,6 +46,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -201,6 +202,7 @@ public class SelectValuesDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "SelectValuesDialog.ColumnInfo.RenameTo"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    colinf[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colinf[2] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "SelectValuesDialog.ColumnInfo.Length"),
@@ -420,6 +422,7 @@ public class SelectValuesDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_CCOMBO,
               ValueMetaBase.roundingTypeDesc),
         };
+    colmeta[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colmeta[5].setToolTip(
         BaseMessages.getString(PKG, "SelectValuesDialog.ColumnInfo.Storage.Tooltip"));
     fieldColumns.add(colmeta[0]);
diff --git a/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java b/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java
index 812e3990f4..95b8f0e56a 100644
--- a/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java
+++ b/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java
@@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageDialogWithToggle;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -112,6 +113,7 @@ public class SetVariableDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "SetVariableDialog.Fields.Column.VariableName"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    colinf[1].setNamingSchemeType(NamingSchemeTypes.HOP_VARIABLE);
     colinf[2] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "SetVariableDialog.Fields.Column.VariableType"),
diff --git a/plugins/transforms/splitfieldtorows/src/main/java/org/apache/hop/pipeline/transforms/splitfieldtorows/SplitFieldToRowsDialog.java b/plugins/transforms/splitfieldtorows/src/main/java/org/apache/hop/pipeline/transforms/splitfieldtorows/SplitFieldToRowsDialog.java
index 505fdaff5b..4a031fd62f 100644
--- a/plugins/transforms/splitfieldtorows/src/main/java/org/apache/hop/pipeline/transforms/splitfieldtorows/SplitFieldToRowsDialog.java
+++ b/plugins/transforms/splitfieldtorows/src/main/java/org/apache/hop/pipeline/transforms/splitfieldtorows/SplitFieldToRowsDialog.java
@@ -25,6 +25,7 @@ import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.widget.ComboVar;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener;
@@ -175,7 +176,9 @@ public class SplitFieldToRowsDialog extends BaseTransformDialog {
     fdlValName.right = new FormAttachment(middle, -margin);
     fdlValName.top = new FormAttachment(wDelimiterIsRegex, margin);
     wlValName.setLayoutData(fdlValName);
-    wValName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wValName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.HOP_FIELD);
     wValName.setText("");
     PropsUi.setLook(wValName);
     wValName.addModifyListener(lsMod);
diff --git a/plugins/transforms/splunk/src/main/java/org/apache/hop/splunk/SplunkConnectionEditor.java b/plugins/transforms/splunk/src/main/java/org/apache/hop/splunk/SplunkConnectionEditor.java
index d1f7a3ca69..de86b4e5d4 100644
--- a/plugins/transforms/splunk/src/main/java/org/apache/hop/splunk/SplunkConnectionEditor.java
+++ b/plugins/transforms/splunk/src/main/java/org/apache/hop/splunk/SplunkConnectionEditor.java
@@ -26,6 +26,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.PasswordTextVar;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -36,7 +37,6 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 
 /**
  * Dialog that allows you to edit the settings of a Splunk connection
@@ -49,7 +49,7 @@ public class SplunkConnectionEditor extends MetadataEditor<SplunkConnection> {
 
   // Connection properties
   //
-  private Text wName;
+  private TextVar wName;
   private TextVar wHostname;
   private TextVar wPort;
   private TextVar wUsername;
@@ -75,7 +75,9 @@ public class SplunkConnectionEditor extends MetadataEditor<SplunkConnection> {
     fdlName.left = new FormAttachment(0, 0); // First one in the left top corner
     fdlName.right = new FormAttachment(middle, -margin);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
diff --git a/plugins/transforms/sqlfileoutput/src/main/java/org/apache/hop/pipeline/transforms/sqlfileoutput/SQLFileOutputDialog.java b/plugins/transforms/sqlfileoutput/src/main/java/org/apache/hop/pipeline/transforms/sqlfileoutput/SQLFileOutputDialog.java
index 4cdd62b867..1e91e244bc 100644
--- a/plugins/transforms/sqlfileoutput/src/main/java/org/apache/hop/pipeline/transforms/sqlfileoutput/SQLFileOutputDialog.java
+++ b/plugins/transforms/sqlfileoutput/src/main/java/org/apache/hop/pipeline/transforms/sqlfileoutput/SQLFileOutputDialog.java
@@ -40,6 +40,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -208,7 +209,9 @@ public class SQLFileOutputDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, wGConnection, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wGConnection, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.setToolTipText(BaseMessages.getString(PKG, "SQLFileOutputDialog.TargetTable.Tooltip"));
     wTable.addModifyListener(lsMod);
@@ -342,7 +345,9 @@ public class SQLFileOutputDialog extends BaseTransformDialog {
     fdbFilename.top = new FormAttachment(wStartNewLine, 0);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wFileName, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileName, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupDialog.java b/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupDialog.java
index edcd57ec76..47cabe5bb9 100644
--- a/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupDialog.java
+++ b/plugins/transforms/streamlookup/src/main/java/org/apache/hop/pipeline/transforms/streamlookup/StreamLookupDialog.java
@@ -39,6 +39,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -274,6 +275,7 @@ public class StreamLookupDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "StreamLookupDialog.ColumnInfo.NewName"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    ciReturn[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciReturn[2] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "StreamLookupDialog.ColumnInfo.Default"),
diff --git a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java
index 5108657a7f..2320df6993 100644
--- a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java
+++ b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -106,6 +107,7 @@ public class StringCutDialog extends BaseTransformDialog {
             false);
 
     ciKey[2].setUsingVariables(true);
+    ciKey[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     ciKey[1].setToolTip(
         BaseMessages.getString(PKG, "StringCutDialog.ColumnInfo.OutStreamField.Tooltip"));
     ciKey[3].setUsingVariables(true);
diff --git a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java
index caa84753c3..7e12fb1888 100644
--- a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java
+++ b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java
@@ -49,6 +49,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -387,6 +388,7 @@ public class SynchronizeAfterMergeDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             "Y",
             "N");
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciReturn[0]);
     wReturn =
         new TableView(
@@ -506,6 +508,7 @@ public class SynchronizeAfterMergeDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciKey[0]);
     wKey =
         new TableView(
@@ -599,7 +602,9 @@ public class SynchronizeAfterMergeDialog extends BaseTransformDialog {
     wbTable.setLayoutData(fdbTable);
     wbTable.addListener(SWT.Selection, e -> getTableName());
 
-    wTable = new TextVar(variables, wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wGeneralComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
diff --git a/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataDialog.java b/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataDialog.java
index d4349075dd..a1181ff0bb 100644
--- a/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataDialog.java
+++ b/plugins/transforms/systemdata/src/main/java/org/apache/hop/pipeline/transforms/systemdata/SystemDataDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.EnterTextDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -88,6 +89,7 @@ public class SystemDataDialog extends BaseTransformDialog {
             BaseMessages.getString(PKG, "SystemDataDialog.NameColumn.Column"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
+    viewColumns[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     viewColumns[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "SystemDataDialog.TypeColumn.Column"),
diff --git a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java
index f9383558fe..5a81ff3cbb 100644
--- a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java
+++ b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java
@@ -53,6 +53,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -251,7 +252,9 @@ public class TableOutputDialog extends BaseTransformDialog {
     fdbSchema.right = new FormAttachment(100, 0);
     wbSchema.setLayoutData(fdbSchema);
 
-    wSchema = new TextVar(variables, wContentComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, wContentComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     wSchema.addModifyListener(lsTableMod);
     FormData fdSchema = new FormData();
@@ -278,7 +281,9 @@ public class TableOutputDialog extends BaseTransformDialog {
     fdbTable.top = new FormAttachment(wbSchema, margin);
     wbTable.setLayoutData(fdbTable);
 
-    wTable = new TextVar(variables, wContentComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, wContentComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
@@ -886,6 +891,7 @@ public class TableOutputDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciFields[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     ciFields[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "TableOutputDialog.ColumnInfo.StreamField"),
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputDialog.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputDialog.java
index d98e76e2b2..0191d14b99 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputDialog.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputDialog.java
@@ -63,6 +63,8 @@ import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeColumnApplierRegistry;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -124,6 +126,7 @@ public class CsvInputDialog extends BaseTransformDialog
   private AtomicBoolean previewBusy;
 
   private MetaSelectionLine<SchemaDefinition> wSchemaDefinition;
+  private MetaSelectionLine wNamingScheme;
   private Button wIgnoreFields;
 
   public CsvInputDialog(
@@ -247,7 +250,9 @@ public class CsvInputDialog extends BaseTransformDialog
       fdlFilename.left = new FormAttachment(0, 0);
       fdlFilename.right = new FormAttachment(middle, -margin);
       wlFilename.setLayoutData(fdlFilename);
-      wFilename = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+      wFilename =
+          new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+              .enableNamingSchemes(NamingSchemeTypes.FILE);
       PropsUi.setLook(wFilename);
       wFilename.addModifyListener(lsMod);
       FormData fdFilename = new FormData();
@@ -516,6 +521,30 @@ public class CsvInputDialog extends BaseTransformDialog
     wSchemaDefinition.addSelectionListener(lsSelection);
     lastControl = wSchemaDefinition;
 
+    wNamingScheme =
+        MetaSelectionLine.forMetadataKey(
+            variables,
+            metadataProvider,
+            shell,
+            SWT.NONE,
+            "naming-scheme",
+            BaseMessages.getString(PKG, "CsvInputDialog.NamingScheme.Label"),
+            BaseMessages.getString(PKG, "CsvInputDialog.NamingScheme.Tooltip"));
+    if (wNamingScheme != null) {
+      PropsUi.setLook(wNamingScheme);
+      FormData fdNamingScheme = new FormData();
+      fdNamingScheme.left = new FormAttachment(0, 0);
+      fdNamingScheme.top = new FormAttachment(lastControl, margin);
+      fdNamingScheme.right = new FormAttachment(100, 0);
+      wNamingScheme.setLayoutData(fdNamingScheme);
+      try {
+        wNamingScheme.fillItems();
+      } catch (Exception e) {
+        log.logError("Error getting naming scheme items", e);
+      }
+      lastControl = wNamingScheme;
+    }
+
     // Ignore manual schema
     //
     Label wlIgnoreFields = new Label(shell, SWT.RIGHT);
@@ -580,6 +609,7 @@ public class CsvInputDialog extends BaseTransformDialog
               ColumnInfo.COLUMN_TYPE_CCOMBO,
               ValueMetaBase.trimTypeDesc),
         };
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(variables, shell, SWT.FULL_SELECTION | SWT.MULTI, colinf, 1, lsMod, props);
@@ -742,10 +772,20 @@ public class CsvInputDialog extends BaseTransformDialog
         wFields.removeEmptyRows();
         wFields.setRowNums();
         wFields.optWidth(true);
+        NamingSchemeColumnApplierRegistry.getInstance()
+            .applyAnnotatedColumns(wFields, metadataProvider, getNamingSchemeName());
       }
     }
   }
 
+  @Override
+  public String getNamingSchemeName() {
+    if (wNamingScheme != null && !wNamingScheme.isDisposed()) {
+      return wNamingScheme.getText();
+    }
+    return inputMeta.getNamingScheme();
+  }
+
   protected void setFlags() {
     // In case there are newlines in fields, we can't load data in parallel
     //
@@ -812,6 +852,9 @@ public class CsvInputDialog extends BaseTransformDialog
     wAddResult.setSelection(inputMeta.isAddResult());
     wEncoding.setText(Const.NVL(inputMeta.getEncoding(), ""));
     wSchemaDefinition.setText(Const.NVL(inputMeta.getSchemaDefinition(), ""));
+    if (wNamingScheme != null) {
+      wNamingScheme.setText(Const.NVL(inputMeta.getNamingScheme(), ""));
+    }
     wIgnoreFields.setSelection(inputMeta.isIgnoreFields());
 
     final List<String> fieldName = newFieldNames == null ? new ArrayList() : newFieldNames;
@@ -867,6 +910,9 @@ public class CsvInputDialog extends BaseTransformDialog
     inputMeta.setNewlinePossibleInFields(wNewlinePossible.getSelection());
     inputMeta.setEncoding(wEncoding.getText());
     inputMeta.setSchemaDefinition(wSchemaDefinition.getText());
+    if (wNamingScheme != null) {
+      inputMeta.setNamingScheme(wNamingScheme.getText());
+    }
     inputMeta.setIgnoreFields(wIgnoreFields.getSelection());
 
     inputMeta.getInputFields().clear();
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
index 36df6ca5f8..bf9efdfe6d 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/csvinput/CsvInputMeta.java
@@ -174,6 +174,15 @@ public class CsvInputMeta extends BaseTransformMeta<CsvInput, CsvInputData>
       injectionKeyDescription = "CsvInputMeta.Injection.IGNORE_FIELDS")
   public boolean ignoreFields;
 
+  /**
+   * Optional Naming Scheme applied to discovered field names when using Get Fields. Empty means
+   * auto-apply only when a unique matching scheme exists.
+   */
+  @HopMetadataProperty(
+      key = "namingScheme",
+      hopMetadataPropertyType = HopMetadataPropertyType.NAMING_SCHEME)
+  private String namingScheme;
+
   @HopMetadataProperty(
       key = "field",
       groupKey = "fields",
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputDialog.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputDialog.java
index 9de080fc20..bba43343f6 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputDialog.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputDialog.java
@@ -74,6 +74,7 @@ import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -132,6 +133,7 @@ public class TextFileInputDialog extends BaseTransformDialog
   private Button wAccFilenames;
 
   private MetaSelectionLine<SchemaDefinition> wSchemaDefinition;
+  private MetaSelectionLine wNamingScheme;
 
   private Label wlPassThruFields;
   private Button wPassThruFields;
@@ -593,7 +595,9 @@ public class TextFileInputDialog extends BaseTransformDialog
     fdbaFilename.top = new FormAttachment(0, 0);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
@@ -2010,6 +2014,31 @@ public class TextFileInputDialog extends BaseTransformDialog
 
     wSchemaDefinition.addSelectionListener(lsSelection);
 
+    wNamingScheme =
+        MetaSelectionLine.forMetadataKey(
+            variables,
+            metadataProvider,
+            wFieldsComp,
+            SWT.NONE,
+            "naming-scheme",
+            BaseMessages.getString(PKG, "TextFileInputDialog.NamingScheme.Label"),
+            BaseMessages.getString(PKG, "TextFileInputDialog.NamingScheme.Tooltip"));
+    Control namingAnchor = wSchemaDefinition;
+    if (wNamingScheme != null) {
+      PropsUi.setLook(wNamingScheme);
+      FormData fdNamingScheme = new FormData();
+      fdNamingScheme.left = new FormAttachment(0, 0);
+      fdNamingScheme.top = new FormAttachment(wSchemaDefinition, margin);
+      fdNamingScheme.right = new FormAttachment(100, 0);
+      wNamingScheme.setLayoutData(fdNamingScheme);
+      try {
+        wNamingScheme.fillItems();
+      } catch (Exception e) {
+        log.logError("Error getting naming scheme items", e);
+      }
+      namingAnchor = wNamingScheme;
+    }
+
     // Ignore manual schema
     //
     Label wlIgnoreFields = new Label(wFieldsComp, SWT.RIGHT);
@@ -2019,7 +2048,7 @@ public class TextFileInputDialog extends BaseTransformDialog
     FormData fdlIgnoreFields = new FormData();
     fdlIgnoreFields.left = new FormAttachment(0, 0);
     fdlIgnoreFields.right = new FormAttachment(middle, -margin);
-    fdlIgnoreFields.top = new FormAttachment(wSchemaDefinition, margin);
+    fdlIgnoreFields.top = new FormAttachment(namingAnchor, margin);
     wlIgnoreFields.setLayoutData(fdlIgnoreFields);
     wIgnoreFields = new Button(wFieldsComp, SWT.CHECK | SWT.LEFT);
     PropsUi.setLook(wIgnoreFields);
@@ -2103,6 +2132,7 @@ public class TextFileInputDialog extends BaseTransformDialog
               },
               true)
         };
+    colInfos[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     colInfos[12].setToolTip(
         BaseMessages.getString(PKG, "TextFileInputDialog.RepeatColumn.Tooltip"));
@@ -2314,6 +2344,9 @@ public class TextFileInputDialog extends BaseTransformDialog
     wAccField.setText(Const.NVL(meta.getFileInput().getAcceptingField(), ""));
     wAccTransform.setText(Const.NVL(meta.getAcceptingTransformName(), ""));
     wSchemaDefinition.setText(Const.NVL(meta.getSchemaDefinition(), ""));
+    if (wNamingScheme != null) {
+      wNamingScheme.setText(Const.NVL(meta.getNamingScheme(), ""));
+    }
     wIgnoreFields.setSelection(meta.isIgnoreFields());
 
     // Apply the ignore fields state (fill from schema and disable/enable controls)
@@ -2573,6 +2606,9 @@ public class TextFileInputDialog extends BaseTransformDialog
     meta.getContent().setLength(wLength.getText());
 
     meta.setSchemaDefinition(wSchemaDefinition.getText());
+    if (wNamingScheme != null) {
+      meta.setNamingScheme(wNamingScheme.getText());
+    }
     meta.setIgnoreFields(wIgnoreFields.getSelection());
 
     meta.getFileInput().getInputFiles().clear();
@@ -3323,6 +3359,14 @@ public class TextFileInputDialog extends BaseTransformDialog
     return this.wFields;
   }
 
+  @Override
+  public String getNamingSchemeName() {
+    if (wNamingScheme != null && !wNamingScheme.isDisposed()) {
+      return wNamingScheme.getText();
+    }
+    return input.getNamingScheme();
+  }
+
   @Override
   public Shell getShell() {
     return this.shell;
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
index 067563555b..ecb6db27a8 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/fileinput/text/TextFileInputMeta.java
@@ -397,6 +397,15 @@ public class TextFileInputMeta
       injectionKeyDescription = "TextFileInput.Injection.IGNORE_FIELDS")
   private boolean ignoreFields;
 
+  /**
+   * Optional Naming Scheme applied to discovered field names when using Get Fields. Empty means
+   * auto-apply only when a unique matching scheme exists.
+   */
+  @HopMetadataProperty(
+      key = "namingScheme",
+      hopMetadataPropertyType = HopMetadataPropertyType.NAMING_SCHEME)
+  private String namingScheme;
+
   @HopMetadataProperty(inline = true)
   protected BaseFileInputAdditionalFields additionalOutputFields;
 
diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java
index de6322785a..2e0a2ef428 100644
--- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java
+++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java
@@ -47,6 +47,7 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -219,7 +220,9 @@ public class TextFileOutputDialog extends BaseTransformDialog {
     fdbFilename.top = new FormAttachment(0, 0);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
diff --git a/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/csvinput/messages/messages_en_US.properties b/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/csvinput/messages/messages_en_US.properties
index 45c4ed2435..bece27ba92 100644
--- a/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/csvinput/messages/messages_en_US.properties
+++ b/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/csvinput/messages/messages_en_US.properties
@@ -62,6 +62,8 @@ CsvInputDialog.RowNumField.Label=The row number field name (optional)
 CsvInputDialog.RunningInParallel.Label=Running in parallel?
 CsvInputDialog.SchemaDefinition.Label=Schema definition
 CsvInputDialog.SchemaDefinition.Tooltip=Select the schema definition you want to apply to incoming/outgoing rows
+CsvInputDialog.NamingScheme.Label=Naming scheme
+CsvInputDialog.NamingScheme.Tooltip=Optional Naming Scheme applied to field names when you click Get Fields. If empty, a unique matching scheme (or a General scheme) is applied automatically.
 CsvInputDialog.Shell.Title=CSV file input
 CsvInputDialog.TransformName.Label=Transform name 
 CsvInputDialog.TrimTypeColumn.Column=Trim type
diff --git a/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/fileinput/text/messages/messages_en_US.properties b/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/fileinput/text/messages/messages_en_US.properties
index 0ec923aee0..51c2c40f82 100644
--- a/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/fileinput/text/messages/messages_en_US.properties
+++ b/plugins/transforms/textfile/src/main/resources/org/apache/hop/pipeline/transforms/fileinput/text/messages/messages_en_US.properties
@@ -293,6 +293,8 @@ TextFileInputDialog.ScanResults.DialogMessage=Result\:
 TextFileInputDialog.ScanResults.DialogTitle=Scan results
 TextFileInputDialog.SchemaDefinition.Label=Schema definition
 TextFileInputDialog.SchemaDefinition.Tooltip=Select the schema definition you want to apply to incoming/outgoing rows
+TextFileInputDialog.NamingScheme.Label=Naming scheme
+TextFileInputDialog.NamingScheme.Tooltip=Optional Naming Scheme applied to field names when you click Get Fields. If empty, a unique matching scheme (or a General scheme) is applied automatically.
 TextFileInputDialog.Separator.Label=Separator
 TextFileInputDialog.ShortFileFieldName.Label=Short filename field
 TextFileInputDialog.ShowFiles.Button=&Show filename(s)...
diff --git a/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaDialog.java b/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaDialog.java
index e0652f0ad6..956cd950fe 100755
--- a/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaDialog.java
+++ b/plugins/transforms/tika/src/main/java/org/apache/hop/pipeline/transforms/tika/TikaDialog.java
@@ -41,6 +41,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -262,7 +263,9 @@ public class TikaDialog extends BaseTransformDialog {
     fdbaFilename.top = new FormAttachment(wOutputField, margin);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     FormData fdFilename = new FormData();
     fdFilename.left = new FormAttachment(middle, 0);
diff --git a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java
index 5eedac20c1..fe90b53217 100644
--- a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java
+++ b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java
@@ -47,6 +47,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -217,7 +218,9 @@ public class UpdateDialog extends BaseTransformDialog {
     wbSchema.setLayoutData(fdbSchema);
     wbSchema.addListener(SWT.Selection, e -> getSchemaNames());
 
-    wSchema = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wSchema =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wSchema);
     wSchema.addModifyListener(lsTableMod);
     FormData fdSchema = new FormData();
@@ -245,7 +248,9 @@ public class UpdateDialog extends BaseTransformDialog {
     wbTable.setLayoutData(fdbTable);
     wbTable.addListener(SWT.Selection, e -> getTableName());
 
-    wTable = new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTable =
+        new TextVar(variables, composite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.DATABASE_TABLE);
     PropsUi.setLook(wTable);
     wTable.addModifyListener(lsTableMod);
     FormData fdTable = new FormData();
@@ -422,6 +427,7 @@ public class UpdateDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciKey[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciKey[0]);
     wKey =
         new TableView(
@@ -477,6 +483,7 @@ public class UpdateDialog extends BaseTransformDialog {
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             new String[] {""},
             false);
+    ciReturn[0].setNamingSchemeType(NamingSchemeTypes.DATABASE_COLUMN);
     tableFieldColumns.add(ciReturn[0]);
     wReturn =
         new TableView(
diff --git a/plugins/transforms/valuemapper/src/main/java/org/apache/hop/pipeline/transforms/valuemapper/ValueMapperDialog.java b/plugins/transforms/valuemapper/src/main/java/org/apache/hop/pipeline/transforms/valuemapper/ValueMapperDialog.java
index 5701f5c764..447c4e764f 100644
--- a/plugins/transforms/valuemapper/src/main/java/org/apache/hop/pipeline/transforms/valuemapper/ValueMapperDialog.java
+++ b/plugins/transforms/valuemapper/src/main/java/org/apache/hop/pipeline/transforms/valuemapper/ValueMapperDialog.java
@@ -29,6 +29,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -45,14 +46,13 @@ import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 
 public class ValueMapperDialog extends BaseTransformDialog {
   private static final Class<?> PKG = ValueMapperMeta.class;
 
   private CCombo wFieldName;
 
-  private Text wTargetFieldName;
+  private TextVar wTargetFieldName;
 
   private TextVar wNonMatchDefault;
 
@@ -128,7 +128,9 @@ public class ValueMapperDialog extends BaseTransformDialog {
     fdlTargetFieldname.right = new FormAttachment(middle, -margin);
     fdlTargetFieldname.top = new FormAttachment(wFieldName, margin);
     wlTargetFieldname.setLayoutData(fdlTargetFieldname);
-    wTargetFieldName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wTargetFieldName =
+        new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_FIELD);
     PropsUi.setLook(wTargetFieldName);
     FormData fdTargetFieldname = new FormData();
     fdTargetFieldname.left = new FormAttachment(middle, 0);
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
index 4a7058065d..8aab157052 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
@@ -52,6 +52,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -390,7 +391,9 @@ public class GetXmlDataDialog extends BaseTransformDialog {
     fdbaFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(modLs);
     FormData fdFilename = new FormData();
@@ -1006,6 +1009,7 @@ public class GetXmlDataDialog extends BaseTransformDialog {
         };
 
     colinf[0].setUsingVariables(true);
+    colinf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colinf[0].setToolTip(
         BaseMessages.getString(PKG, "GetXMLDataDialog.FieldsTable.Name.Column.Tooltip"));
     colinf[1].setUsingVariables(true);
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java
index a288323166..0dbdd02fcb 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java
@@ -38,6 +38,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.BackgroundThreadFacade;
@@ -143,7 +144,9 @@ public class XmlOutputDialog extends BaseTransformDialog {
     fdbFilename.top = new FormAttachment(0, margin);
     wbFilename.setLayoutData(fdbFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
@@ -649,6 +652,7 @@ public class XmlOutputDialog extends BaseTransformDialog {
               ColumnInfo.COLUMN_TYPE_TEXT,
               false)
         };
+    columnInfos[1].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
 
     wFields =
         new TableView(
diff --git a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
index 057634a7ca..63fbfa391e 100644
--- a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
+++ b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
@@ -41,6 +41,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.dialog.PreviewRowsDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog;
@@ -305,7 +306,9 @@ public class YamlInputDialog extends BaseTransformDialog {
     fdbaFilename.top = new FormAttachment(wOutputField, margin);
     wbaFilename.setLayoutData(fdbaFilename);
 
-    wFilename = new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(NamingSchemeTypes.FILE);
     PropsUi.setLook(wFilename);
     wFilename.addModifyListener(lsMod);
     FormData fdFilename = new FormData();
@@ -733,6 +736,7 @@ public class YamlInputDialog extends BaseTransformDialog {
         };
 
     colInf[0].setUsingVariables(true);
+    colInf[0].setNamingSchemeType(NamingSchemeTypes.HOP_FIELD);
     colInf[0].setToolTip(
         BaseMessages.getString(PKG, "YamlInputDialog.FieldsTable.Name.Column.Tooltip"));
     colInf[1].setUsingVariables(true);
diff --git a/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
index ed222657f7..d9b56307da 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseMetaEditor.java
@@ -60,6 +60,7 @@ import org.apache.hop.ui.core.gui.IGuiPluginCompositeWidgetsListener;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -79,7 +80,6 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
 import org.jspecify.annotations.Nullable;
@@ -95,7 +95,7 @@ public class DatabaseMetaEditor extends MetadataEditor<DatabaseMeta> {
   private CTabFolder wTabFolder;
 
   private Composite wGeneralComp;
-  private Text wName;
+  private TextVar wName;
   private Combo wConnectionType;
   private Label wDriverInfo;
   private Button wbDownloadDriver;
@@ -215,7 +215,9 @@ public class DatabaseMetaEditor extends MetadataEditor<DatabaseMeta> {
     fdlName.left = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlName);
 
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, margin);
diff --git a/ui/src/main/java/org/apache/hop/ui/core/dialog/HopDescribedVariablesDialog.java b/ui/src/main/java/org/apache/hop/ui/core/dialog/HopDescribedVariablesDialog.java
index d89f5e48b1..b3eafc3fb2 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/dialog/HopDescribedVariablesDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/dialog/HopDescribedVariablesDialog.java
@@ -29,6 +29,7 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.ColumnInfo;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -135,6 +136,7 @@ public class HopDescribedVariablesDialog extends Dialog {
           false,
           false),
     };
+    columns[0].setNamingSchemeType(NamingSchemeTypes.HOP_VARIABLE);
     columns[2].setDisabledListener(rowNr -> false);
 
     // Fields between the label and the buttons
diff --git a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
index 6e6b1e6f0e..c46aca3f06 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
@@ -691,9 +691,15 @@ public class GuiCompositeWidgets {
         comboItems = new String[] {};
       }
     }
-    if (guiElements.isVariablesEnabled()) {
+    boolean namingEnabled =
+        StringUtils.isNotEmpty(guiElements.getNamingSchemeType()) && !guiElements.isPassword();
+    if (guiElements.isVariablesEnabled() || namingEnabled) {
       ComboVar comboVar = new ComboVar(variables, parent, SWT.BORDER | SWT.SINGLE | SWT.LEFT);
       PropsUi.setLook(comboVar);
+      if (!guiElements.isVariablesEnabled()) {
+        comboVar.setVariablesEnabled(false);
+      }
+      enableNamingIfPresent(comboVar, guiElements);
       widgetsMap.put(guiElements.getId(), comboVar);
       comboVar.setItems(comboItems);
       control = comboVar;
@@ -1002,7 +1008,9 @@ public class GuiCompositeWidgets {
       style = SWT.BORDER | SWT.SINGLE | SWT.LEFT;
     }
 
-    if (guiElements.isVariablesEnabled()) {
+    boolean namingEnabled =
+        StringUtils.isNotEmpty(guiElements.getNamingSchemeType()) && !guiElements.isPassword();
+    if (guiElements.isVariablesEnabled() || namingEnabled) {
       if (!multiLine && guiElements.isPassword()) {
         String toolTip =
             StringUtils.isNotEmpty(guiElements.getToolTip()) ? guiElements.getToolTip() : null;
@@ -1017,6 +1025,10 @@ public class GuiCompositeWidgets {
       } else {
         TextVar textVar = new TextVar(variables, parent, style);
         PropsUi.setLook(textVar);
+        if (!guiElements.isVariablesEnabled()) {
+          textVar.setVariablesEnabled(false);
+        }
+        enableNamingIfPresent(textVar, guiElements);
         widgetsMap.put(guiElements.getId(), textVar);
         addModifyListener(textVar.getTextWidget(), guiElements.getId());
         control = textVar;
@@ -1085,6 +1097,18 @@ public class GuiCompositeWidgets {
     return control;
   }
 
+  private void enableNamingIfPresent(Control control, GuiElements guiElements) {
+    String type = guiElements.getNamingSchemeType();
+    if (StringUtils.isEmpty(type) || guiElements.isPassword()) {
+      return;
+    }
+    if (control instanceof TextVar textVar) {
+      textVar.enableNamingSchemes(type);
+    } else if (control instanceof ComboVar comboVar) {
+      comboVar.enableNamingSchemes(type);
+    }
+  }
+
   public ITypeFilename instantiateTypeFilename(GuiElements guiElements) {
     Class<? extends ITypeFilename> typeFilenameClass = guiElements.getTypeFilename();
     if (typeFilenameClass == null) {
diff --git a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
index 7ed36b3d36..eb835fc51f 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
@@ -146,6 +146,7 @@ public class GuiResource {
   private SwtUniversalImage imageDeprecated;
   private SwtUniversalImage imageVariable;
   private SwtUniversalImage imageHash;
+  private SwtUniversalImage imageNaming;
   private SwtUniversalImage imagePipeline;
   private SwtUniversalImage imagePipelineDisabled;
   private SwtUniversalImage imagePipelineError;
@@ -461,6 +462,7 @@ public class GuiResource {
     imageMissing.dispose();
     imageVariable.dispose();
     imageHash.dispose();
+    imageNaming.dispose();
     imagePipeline.dispose();
     imagePipelineDisabled.dispose();
     imagePipelineError.dispose();
@@ -868,6 +870,7 @@ public class GuiResource {
         SwtSvgImageUtil.getImageAsResource(display, "ui/images/false-disabled.svg");
     imageVariable = SwtSvgImageUtil.getImageAsResource(display, "ui/images/variable.svg");
     imageHash = SwtSvgImageUtil.getImageAsResource(display, "ui/images/hash.svg");
+    imageNaming = SwtSvgImageUtil.getImageAsResource(display, "ui/images/naming.svg");
     imageFile = SwtSvgImageUtil.getImageAsResource(display, "ui/images/file.svg");
     imageFolder = SwtSvgImageUtil.getImageAsResource(display, "ui/images/folder.svg");
     imagePartitionSchema =
@@ -1261,6 +1264,18 @@ public class GuiResource {
     return getZoomedImaged(imageHash, display, 12, 12);
   }
 
+  /**
+   * @return the naming-scheme indicator image at standard small icon size
+   */
+  public Image getImageNaming() {
+    return getZoomedImaged(imageNaming, display, ConstUi.SMALL_ICON_SIZE, ConstUi.SMALL_ICON_SIZE);
+  }
+
+  /** Mini N icon for TextVar naming-scheme shortcut indicator (matches variable mini). */
+  public Image getImageNamingMini() {
+    return getZoomedImaged(imageNaming, display, 12, 12);
+  }
+
   public Image getImagePipeline() {
     return getZoomedImaged(
         imagePipeline, display, ConstUi.SMALL_ICON_SIZE, ConstUi.SMALL_ICON_SIZE);
diff --git a/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataEditor.java b/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataEditor.java
index 638dd946cd..2eeda72a39 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataEditor.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataEditor.java
@@ -38,19 +38,25 @@ import org.apache.hop.metadata.api.IHopMetadata;
 import org.apache.hop.metadata.api.IHopMetadataSerializer;
 import org.apache.hop.metadata.plugin.MetadataPluginType;
 import org.apache.hop.ui.core.ConstUi;
+import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.bus.HopGuiEvents;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.security.HopSecurityUi;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.perspective.metadata.MetadataPerspective;
 import org.apache.hop.ui.util.HelpUtils;
 import org.apache.hop.ui.util.SwtSvgImageUtil;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
 /** Abstract implementation of all metadata editors. */
@@ -141,6 +147,38 @@ public abstract class MetadataEditor<T extends IHopMetadata> extends MetadataFil
     return null;
   }
 
+  /**
+   * Name line with the naming-scheme shortcut and variable insertion disabled. Place at the top of
+   * the editor (attached to the parent).
+   *
+   * @param parent editor composite
+   * @param label localized name-field label
+   * @param middle form middle percentage
+   * @param margin form margin
+   * @return the name widget
+   */
+  protected TextVar createNameField(Composite parent, String label, int middle, int margin) {
+    Label wlName = new Label(parent, SWT.RIGHT);
+    PropsUi.setLook(wlName);
+    wlName.setText(label);
+    FormData fdlName = new FormData();
+    fdlName.top = new FormAttachment(0, margin);
+    fdlName.left = new FormAttachment(0, 0);
+    fdlName.right = new FormAttachment(middle, -margin);
+    wlName.setLayoutData(fdlName);
+
+    TextVar name =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
+    PropsUi.setLook(name);
+    FormData fdName = new FormData();
+    fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
+    fdName.left = new FormAttachment(middle, 0);
+    fdName.right = new FormAttachment(100, 0);
+    name.setLayoutData(fdName);
+    return name;
+  }
+
   protected Button createHelpButton(final Shell shell) {
     HopMetadata annotation = manager.getManagedClass().getAnnotation(HopMetadata.class);
     IPlugin plugin =
diff --git a/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataManager.java b/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataManager.java
index b7d421b116..a7939d92c7 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataManager.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/metadata/MetadataManager.java
@@ -162,6 +162,21 @@ public class MetadataManager<T extends IHopMetadata> {
    * @return True, if anything was changed
    */
   public boolean editMetadata(String elementName) {
+    return editMetadata(elementName, false);
+  }
+
+  /**
+   * Edit an element in a modal dialog even when the metadata perspective is active. Use this when
+   * the caller is already editing something else (for example the naming-scheme N indicator).
+   *
+   * @param elementName The name of the element to edit
+   * @return True if anything was changed
+   */
+  public boolean editMetadataInDialog(String elementName) {
+    return editMetadata(elementName, true);
+  }
+
+  private boolean editMetadata(String elementName, boolean forceDialog) {
 
     if (StringUtils.isEmpty(elementName)) {
       return false;
@@ -189,9 +204,10 @@ public class MetadataManager<T extends IHopMetadata> {
 
       // Open this element in the metadata perspective if that one is active. The perspective is
       // absent when it is switched off in disabledGuiElements.xml, and we fall back to the dialog.
+      // Callers already editing another object pass forceDialog so we do not steal a tab.
       //
       MetadataPerspective perspective = HopGui.getMetadataPerspective();
-      if (perspective != null && perspective.isActive()) {
+      if (!forceDialog && perspective != null && perspective.isActive()) {
         perspective.addEditor(editor);
         return false;
       } else {
diff --git a/ui/src/main/java/org/apache/hop/ui/core/variables/resolver/VariableResolverEditor.java b/ui/src/main/java/org/apache/hop/ui/core/variables/resolver/VariableResolverEditor.java
index dee712743d..c6e54800da 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/variables/resolver/VariableResolverEditor.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/variables/resolver/VariableResolverEditor.java
@@ -41,6 +41,8 @@ import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.IGuiPluginCompositeWidgetsListener;
 import org.apache.hop.ui.core.metadata.MetadataEditor;
 import org.apache.hop.ui.core.metadata.MetadataManager;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.perspective.metadata.MetadataPerspective;
 import org.apache.hop.ui.util.HelpUtils;
@@ -66,7 +68,7 @@ import org.eclipse.swt.widgets.ToolItem;
 public class VariableResolverEditor extends MetadataEditor<VariableResolver> {
   private static final Class<?> PKG = VariableResolverEditor.class;
 
-  private Text wName;
+  private TextVar wName;
   private Text wDescription;
   private Combo wResolverType;
 
@@ -109,7 +111,9 @@ public class VariableResolverEditor extends MetadataEditor<VariableResolver> {
     fdlName.top = new FormAttachment(0, 0);
     fdlName.left = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlName);
-    wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wName =
+        new TextVar(hopGui.getVariables(), parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .asNameField(NamingSchemeTypes.HOP_METADATA);
     PropsUi.setLook(wName);
     FormData fdName = new FormData();
     fdName.top = new FormAttachment(wlName, margin);
diff --git a/ui/src/main/java/org/apache/hop/ui/core/vfs/HopVfsFileDialog.java b/ui/src/main/java/org/apache/hop/ui/core/vfs/HopVfsFileDialog.java
index 7aa2d4bc09..eb72f750f2 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/vfs/HopVfsFileDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/vfs/HopVfsFileDialog.java
@@ -65,6 +65,8 @@ import org.apache.hop.ui.core.gui.HopNamespace;
 import org.apache.hop.ui.core.gui.IToolbarContainer;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.core.widget.HopTree;
+import org.apache.hop.ui.core.widget.NamingSchemeTypes;
+import org.apache.hop.ui.core.widget.NamingSchemeWidgetSupport;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.core.widget.TreeUtil;
 import org.apache.hop.ui.hopgui.HopGui;
@@ -354,7 +356,10 @@ public class HopVfsFileDialog implements IFileDialog, IDirectoryDialog {
         navigateToolBarContainer, NAVIGATE_TOOLBAR_PARENT_ID);
     navigateToolBar.pack();
 
-    wFilename = new TextVar(variables, navigateComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    wFilename =
+        new TextVar(variables, navigateComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER)
+            .enableNamingSchemes(
+                browsingDirectories ? NamingSchemeTypes.FOLDER : NamingSchemeTypes.FILE);
     wFilename.addListener(SWT.DefaultSelection, e -> enteredFilenameOrFolder());
     wFilename.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
     PropsUi.setLook(wFilename);
@@ -1733,6 +1738,14 @@ public class HopVfsFileDialog implements IFileDialog, IDirectoryDialog {
       // The control that will be the editor must be a child of the Tree
       Text renameText = new Text(wBrowser, SWT.BORDER);
       renameText.setText(file.getName().getBaseName());
+      try {
+        NamingSchemeWidgetSupport.attachShortcut(
+            renameText,
+            variables,
+            file.isFolder() ? NamingSchemeTypes.FOLDER : NamingSchemeTypes.FILE);
+      } catch (Exception ignored) {
+        // folder check can fail on some VFS types; shortcut is optional
+      }
       renameText.addListener(SWT.FocusOut, event -> renameText.dispose());
       renameText.addListener(
           SWT.KeyUp,
diff --git a/ui/src/main/java/org/apache/hop/ui/core/widget/ColumnInfo.java b/ui/src/main/java/org/apache/hop/ui/core/widget/ColumnInfo.java
index 9c75e86935..672172ec72 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/widget/ColumnInfo.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/widget/ColumnInfo.java
@@ -66,6 +66,12 @@ public class ColumnInfo {
 
   @Getter @Setter private boolean usingVariables;
 
+  /**
+   * Optional {@link NamingSchemeTypes} code. When set, TableView uses a TextVar/ComboVar editor
+   * (variables still follow {@link #usingVariables}) and offers the naming-scheme shortcut.
+   */
+  @Getter @Setter private String namingSchemeType;
+
   @Getter @Setter private boolean passwordField;
 
   @Getter @Setter private IComboValuesSelectionListener comboValuesSelectionListener;
diff --git a/ui/src/main/java/org/apache/hop/ui/core/widget/ComboVar.java b/ui/src/main/java/org/apache/hop/ui/core/widget/ComboVar.java
index ccbb779611..17705f57fc 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/widget/ComboVar.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/widget/ComboVar.java
@@ -34,6 +34,7 @@ import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 
@@ -57,9 +58,15 @@ public class ComboVar extends Composite {
 
   private CCombo wCombo;
   private Label wlImage;
+  private Label wNamingImage;
+  private FormData fdCombo;
 
   private ModifyListener modifyListenerTooltipText;
 
+  private boolean variablesEnabled = true;
+  private String namingSchemeType;
+  private boolean namingShortcutAttached;
+
   public ComboVar(IVariables variables, Composite composite, int flags) {
     this(variables, composite, flags, null, null, null);
   }
@@ -113,7 +120,7 @@ public class ComboVar extends Composite {
     PropsUi.setLook(wCombo);
     modifyListenerTooltipText = getModifyListenerTooltipText(wCombo);
     wCombo.addModifyListener(modifyListenerTooltipText);
-    FormData fdCombo = new FormData();
+    fdCombo = new FormData();
     fdCombo.top = new FormAttachment(0, 0);
     fdCombo.left = new FormAttachment(0, 0);
     fdCombo.right = new FormAttachment(wlImage, 0);
@@ -125,6 +132,131 @@ public class ComboVar extends Composite {
     wCombo.addKeyListener(controlSpaceKeyAdapter);
   }
 
+  /**
+   * Enable or disable variable support. When disabled the {@code $} indicator is hidden and
+   * CTRL-SPACE no longer opens the variable popup.
+   *
+   * @param enabled true to keep the default variable behavior
+   * @return this widget for chaining
+   */
+  public ComboVar setVariablesEnabled(boolean enabled) {
+    this.variablesEnabled = enabled;
+    if (wlImage != null && !wlImage.isDisposed()) {
+      wlImage.setVisible(enabled);
+    }
+    if (wCombo != null && !wCombo.isDisposed() && controlSpaceKeyAdapter != null) {
+      wCombo.removeKeyListener(controlSpaceKeyAdapter);
+      if (enabled) {
+        wCombo.addKeyListener(controlSpaceKeyAdapter);
+      }
+    }
+    relayoutCombo();
+    return this;
+  }
+
+  public boolean isVariablesEnabled() {
+    return variablesEnabled;
+  }
+
+  /**
+   * Opt this field into naming-scheme shortcuts. {@code type} is a {@link NamingSchemeTypes} code.
+   *
+   * @param type scheme type code
+   * @return this widget for chaining
+   */
+  public ComboVar enableNamingSchemes(String type) {
+    this.namingSchemeType = type;
+    attachNamingShortcut();
+    if (wNamingImage == null && wCombo != null && !wCombo.isDisposed()) {
+      wNamingImage = new Label(this, SWT.NONE);
+      PropsUi.setLook(wNamingImage);
+      wNamingImage.setImage(GuiResource.getInstance().getImageNamingMini());
+      wNamingImage.setToolTipText(BaseMessages.getString(PKG, "TextVar.tooltip.NamingScheme"));
+      FormData fdlNaming = new FormData();
+      fdlNaming.top = new FormAttachment(0, 0);
+      wNamingImage.setLayoutData(fdlNaming);
+      TextWidgetShortcutKeyAdapter.attachIndicatorClick(
+          wNamingImage,
+          () ->
+              TextWidgetShortcutContext.builder()
+                  .control(wCombo)
+                  .variables(variables)
+                  .getText(this::getText)
+                  .setText(this::setText)
+                  .namingSchemeType(namingSchemeType)
+                  .variablesEnabled(variablesEnabled)
+                  .build());
+    }
+    relayoutCombo();
+    return this;
+  }
+
+  public ComboVar asNameField(String type) {
+    setVariablesEnabled(false);
+    return enableNamingSchemes(type);
+  }
+
+  public String getNamingSchemeType() {
... 2148 lines suppressed ...