Property settings for individual files

82 views
Skip to first unread message

Neil Hodgson

unread,
Mar 13, 2022, 10:17:24 PM3/13/22
to scite-i...@googlegroups.com
SciTE currently provides various domains for settings in properties files: global, user, project and directory. Some settings are made over all files that match a pattern or for files that use a particular lexer. Many settings can not currently be defined for individual files.

Lexilla’s testing system uses SciTE.properties files to define the settings to apply to each file under test. Since SciTE also uses these files, its easy to try different settings, see the result visually in SciTE and check whether it passes automated tests.

When a lexer defines a property, like the Markdown lexer’s ‘lexer.markdown.header.eolfill’, there should be tests for all valid values (0 and 1) for that property. The testing system currently requires the 0 and 1 tests to be in separate directories so that both values can be tried. It would be better to allow properties to be defined for individual files and so avoid the extra directories. This should also be added to SciTE to continue to use common SciTE.properties files.

It turns out that it is possible to support per-file settings inside SciTE.properties with a small change to SciTE. “if” tests in SciTE properties are evaluated when reading files, so setting the “FileNameExt” in the properties before reading the file allows selection statements using the existing “if” and “$(=“ features like:

if $(= $(FileNameExt);AllStyles.md)
lexer.markdown.header.eolfill=1

This works for the local (per-directory) SciTE.properties file but would also work for the optional project (per directory-tree) SciTEDirectory.properties file. It does not work for the user and global properties which may be large so are assumed to rarely change. Re-reading and re-evaluating the global and user properties may take some time so doing so on every buffer switch should be avoided.

There could be pattern matching to match multiple files (“Bug*.md”) and simpler syntax such as

match Bug1216.md
lexer.markdown.header.eolfill=1

Or, the EditorConfig (SciTE supports EditorConfig) inspired

[HeaderEOLFill_1.md]
lexer.markdown.header.eolfill=1

There is a Lexilla issue for better property setting at
https://github.com/ScintillaOrg/lexilla/issues/62

Proposal for SciTE:
(1) Insert FilePath, FileDir, FileName, FileExt, and FileNameExt into propsDirectory before reading directory or local properties so they can be used in “if” tests.
(2) Add a “match” expression that is similar to “if” but implicitly tests the file name.
(3) Support basic patterns with ‘*’ in “match”.
These may be added piece by piece over time.

Neil

Neil Hodgson

unread,
Mar 16, 2022, 3:17:00 AM3/16/22
to scite-interest
An initial commit adds file path properties (FilePath, FileDir, FileName, FileExt, FileNameExt) to the directories property set so they can be tested inside directory and local properties files. This change may cause problems for other features so look out for regressions and report them.

This feature allows per-file and per-extension settings like:

if $(= $(FileNameExt);RegenerateSource.py)
style.python.5=fore:#D08000,bold

# Perl code in retro mode using punched cards
if $(= $(FileExt);pl)
edge.mode=1
edge.column=77
edge.colour=#F0C000

For Lexilla, this works for FileNameExt only in TestLexers.

A shorter syntax may be implemented in the future.

While I like the ‘match’ keyword, the [bracketed] matcher also suggests a single line form when only setting a single property:

lexer.markdown.header.eolfill[AllStyles.md]=1
edge.column[*.{cobol,fortran}]=80

Some minor updates were made to SciTE EditorConfig pattern matching code to implement numeric ranges like {10..25} https://editorconfig-specification.readthedocs.io/#glob-expressions. This pattern matcher may be reused for the ‘match’ keyword.

Changes available from the repositories
git clone https://github.com/ScintillaOrg/lexilla
hg clone http://hg.code.sf.net/p/scintilla/scite
or from
https://www.scintilla.org/scite.zip Source
https://www.scintilla.org/wscite.zip Windows executable (64-bit)

Neil

Neil Hodgson

unread,
Mar 23, 2022, 1:41:07 AM3/23/22
to scite-interest
A complete version of this feature is now committed.

> An initial commit adds file path properties (FilePath, FileDir, FileName, FileExt, FileNameExt)

There is now also RelativePath which is the path from the directory properties file directory to the current file. If there is a directory properties file in the directory above lexilla, scintilla, and scite, then there may be RelativePath values like lexilla/lexers/LexAda.cxx (on Unix) or scintilla\win32\PlatWin.cxx (on Win32) - paths have local directory separators so they are easier to pass to local applications.

> There could be pattern matching to match multiple files (“Bug*.md”) and simpler syntax such as
>
> match Bug1216.md
> lexer.markdown.header.eolfill=1

This has now been implemented with a pattern matcher with many features similar to EditorConfig. Multi-character ‘*’ and single character ‘?’ wildcards work as does ‘**’ that allows ‘/‘; [set], [!set], and [a-z] sets; {a,b} alternates; and {10..19} numeric sequences. If a match fails with the relative path then its tried again with just the file name. Match expressions use ‘/‘ to separate directories even on Win32 as this allows files to be more easily shared between Unix and Win32 and ‘\’ is used for quoting special characters.

match **/Lex*.cxx
colour.code.comment.line=fore:#70B060

match scintilla/gtk/*.{h,cxx,c}
lexer.cpp.escape.sequence=1

match *.cpp
styling.within.preprocessor=1

https://editorconfig.org

There are some aspects that could change in the future.

On Win32 and macOS, the relative path and pattern are lower-cased before matching. However, these systems are case-preserving and most developers stick to particular cases in file names so it may be better to perform case-sensitive matches or provide an option. There is no attempt to perform Unicode normalization so there could be match failures for accented characters that are not in the file system’s normalization form.

Trailing spaces are removed from match expressions (so use [ ] if necessary) and there should be exactly one space between “match” and the expression. Backslash quoting (match x\{a}\[2].tex) should only work on the top-level of the match expression but this hasn’t been tested much.

This feature makes directory (or project) properties files more useful and it may be time to default them on (properties.directory.enable=1). Enabling directory properties has a runtime cost as whenever a file becomes current, a directory properties file is sought in each parent directory up to the root directory, stopping when found.
Reply all
Reply to author
Forward
0 new messages