diff --git a/.gitmodules b/.gitmodules index 7c8a7724..c347ff33 100644 --- a/.gitmodules +++ b/.gitmodules @@ -260,3 +260,6 @@ [submodule "assets/syntaxes/02_Extra/vscode-wgsl"] path = assets/syntaxes/02_Extra/vscode-wgsl url = https://github.com/PolyMeilex/vscode-wgsl.git +[submodule "assets/syntaxes/02_Extra/Prolog"] + path = assets/syntaxes/02_Extra/Prolog + url = https://github.com/alnkpa/sublimeprolog diff --git a/CHANGELOG.md b/CHANGELOG.md index 28e56e34..256fece9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ - Added auto detect syntax for `.jsonc` #2795 (@mxaddict) - Added auto detect syntax for `.aws/{config,credentials}` #2795 (@mxaddict) - Add syntax mapping for Wireguard config #2874 (@cyqsimon) +- Add Prolog syntax, see #2848 (@laalsaas) ## Themes diff --git a/assets/syntaxes/02_Extra/Prolog b/assets/syntaxes/02_Extra/Prolog new file mode 160000 index 00000000..9e8e142e --- /dev/null +++ b/assets/syntaxes/02_Extra/Prolog @@ -0,0 +1 @@ +Subproject commit 9e8e142e55557465511338d5b26ca585cb729310 diff --git a/assets/syntaxes/02_Extra/Prolog.sublime-syntax b/assets/syntaxes/02_Extra/Prolog.sublime-syntax new file mode 100644 index 00000000..3867d12a --- /dev/null +++ b/assets/syntaxes/02_Extra/Prolog.sublime-syntax @@ -0,0 +1,137 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: SWI-Prolog +comment: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +file_extensions: + - pro + - prolog + - swiplrc +scope: source.prolog +contexts: + main: + - include: comments + - match: (?<=:-)\s* + push: + - meta_scope: meta.clause.body.prolog + - match: (\.) + captures: + 1: keyword.control.clause.bodyend.prolog + pop: true + - include: comments + - include: builtin + - include: controlandkeywords + - include: atom + - include: variable + - include: constants + - match: . + scope: meta.clause.body.prolog + - match: '^\s*([a-z][a-zA-Z0-9_]*)(\(?)(?=.*:-.*)' + captures: + 1: entity.name.function.clause.prolog + 2: punctuation.definition.parameters.begin + push: + - meta_scope: meta.clause.head.prolog + - match: ((\)?))\s*(:-) + captures: + 1: punctuation.definition.parameters.end + 3: keyword.control.clause.bodybegin.prolog + pop: true + - include: atom + - include: variable + - include: constants + - match: '^\s*([a-z][a-zA-Z0-9_]*)(\(?)(?=.*-->.*)' + captures: + 1: entity.name.function.dcg.prolog + 2: punctuation.definition.parameters.begin + push: + - meta_scope: meta.dcg.head.prolog + - match: ((\)?))\s*(-->) + captures: + 1: punctuation.definition.parameters.end + 3: keyword.control.dcg.bodybegin.prolog + pop: true + - include: atom + - include: variable + - include: constants + - match: (?<=-->)\s* + push: + - meta_scope: meta.dcg.body.prolog + - match: (\.) + captures: + 1: keyword.control.dcg.bodyend.prolog + pop: true + - include: comments + - include: controlandkeywords + - include: atom + - include: variable + - include: constants + - match: . + scope: meta.dcg.body.prolog + - match: '^\s*([a-zA-Z][a-zA-Z0-9_]*)(\(?)(?!.*(:-|-->).*)' + captures: + 1: entity.name.function.fact.prolog + 2: punctuation.definition.parameters.begin + push: + - meta_scope: meta.fact.prolog + - match: ((\)?))\s*(\.)(?!\d+) + captures: + 1: punctuation.definition.parameters.end + 3: keyword.control.fact.end.prolog + pop: true + - include: atom + - include: variable + - include: constants + atom: + - match: '(?) + captures: + 1: keyword.control.if.prolog + push: + - meta_scope: meta.if.prolog + - match: (;) + captures: + 1: keyword.control.else.prolog + pop: true + - include: main + - include: builtin + - include: comments + - include: atom + - include: variable + - match: . + scope: meta.if.body.prolog + - match: "!" + scope: keyword.control.cut.prolog + - match: (\s(is)\s)|=:=|=?\\?=|\\\+|@?>|@?=?<|\+|\*|\- + scope: keyword.operator.prolog + variable: + - match: "(? *Developer* -> - *New Syntax from XXX.tmLanguage...*. Save the new file in the `assets/syntaxes` folder. + *New Syntax from XXX.tmLanguage...*. Alternatively, you can use the + [Sublime Syntax Convertor](https://github.com/aziz/SublimeSyntaxConvertor). + Save the new file in the `assets/syntaxes` folder. If only `.tmLanguage.json` or `.tmLanguage.yml` file is available, use [PackageDev](https://packagecontrol.io/packages/PackageDev) to convert it to `.tmLanguage.plist` format and then rename the converted file to `.tmLanguage` file. diff --git a/src/assets/build_assets/acknowledgements.rs b/src/assets/build_assets/acknowledgements.rs index c4fde919..4697604b 100644 --- a/src/assets/build_assets/acknowledgements.rs +++ b/src/assets/build_assets/acknowledgements.rs @@ -95,6 +95,9 @@ fn include_license_in_acknowledgments(license_text: &str) -> bool { // Apache 2.0 "Apache License Version 2.0, January 2004 http://www.apache.org/licenses/", "Licensed under the Apache License, Version 2.0 (the \"License\");", + + // MPL + "Mozilla Public License, version 2.0", ]; license_contains_marker(license_text, &markers) diff --git a/tests/syntax-tests/highlighted/Prolog/test.pro b/tests/syntax-tests/highlighted/Prolog/test.pro new file mode 100644 index 00000000..e39573f3 --- /dev/null +++ b/tests/syntax-tests/highlighted/Prolog/test.pro @@ -0,0 +1,34 @@ +% A formulation of Einstein's Riddle (aka Zebra Puzzle) in Prolog (specifically, SWI-Prolog - see http://www.swi-prolog.org/) as appeared on Life International magazine 17/12/1962 +% Source: https://en.wikipedia.org/wiki/Zebra_Puzzle + +% Modelling the problem: +% - Each house is represented by the predicate house/5 +% - The five houses are modelled as a(n) (ordered) list of house(Color, Nationality, Pet, Beverage, Cigaret) in the variable Houses +% - The predicate solve/2 for solving the riddle is of the form solve(WaterDrinker, ZebraOwner) where WaterDrinker is the nationality of the person who drinks water and ZebraOwner the nationality of the person owning a zebra as a pet + +% Expected solution: if the problem is modelled correctly by this program then the only solution set should be: +% WaterDrinker = norwegian, ZebraOwner = japanese. + +% adjacent/3 - A helper function for expressing the "directly next to" relation in a list +% adjacent(A, B, List) means that either A is directly left of B in List or A is directly right of B in List +adjacent(A, B, List) :- nextto(A, B, List); nextto(B, A, List). + +% solve/2 - The main predicate for solving the puzzle +solve(WaterDrinker, ZebraOwner) :- +  length(Houses, 5),                                                          % 1. There are five houses. +  member(house(red, english, _, _, _), Houses),                               % 2. The Englishman lives in the red house. +  member(house(_, spanish, dog, _, _), Houses),                               % 3. The Spaniard owns the dog. +  member(house(green, _, _, coffee, _), Houses),                              % 4. Coffee is drunk in the green house. +  member(house(_, ukrainian, _, tea, _), Houses),                             % 5. The Ukrainian drinks tea. +  nextto(house(ivory, _, _, _, _), house(green, _, _, _, _), Houses),         % 6. The green house is immediately to the right of the ivory house. +  member(house(_, _, snail, _, old_gold), Houses),                            % 7. The Old Gold smoker owns snails. +  member(house(yellow, _, _, _, kools), Houses),                              % 8. Kools are smoked in the yellow house. +  nth1(3, Houses, house(_, _, _, milk, _)),                                   % 9. Milk is drunk in the middle house. +  nth1(1, Houses, house(_, norwegian, _, _, _)),                              % 10. The Norwegian lives in the first house. +  adjacent(house(_, _, _, _, chesterfields), house(_, _, fox, _, _), Houses), % 11. The man who smokes Chesterfields lives in the house next to the man with the fox. +  adjacent(house(_, _, _, _, kools), house(_, _, horse, _, _), Houses),       % 12. Kools are smoked in the house next to the house where the horse is kept. +  member(house(_, _, _, orange_juice, lucky_strike), Houses),                 % 13. The Lucky Strike smoker drinks orange juice. +  member(house(_, japanese, _, _, parliaments), Houses),                      % 14. The Japanese smokes Parliaments. +  adjacent(house(_, norwegian, _, _, _), house(blue, _, _, _, _), Houses),    % 15. The Norwegian lives next to the blue house +  member(house(_, WaterDrinker, _, water, _), Houses),                        % Who (WaterDrinker) drinks water? +  member(house(_, ZebraOwner, zebra, _, _), Houses). % Who (ZebraOwner) owns the zebra? diff --git a/tests/syntax-tests/source/Prolog/test.pro b/tests/syntax-tests/source/Prolog/test.pro new file mode 100644 index 00000000..145adebd --- /dev/null +++ b/tests/syntax-tests/source/Prolog/test.pro @@ -0,0 +1,34 @@ +% A formulation of Einstein's Riddle (aka Zebra Puzzle) in Prolog (specifically, SWI-Prolog - see http://www.swi-prolog.org/) as appeared on Life International magazine 17/12/1962 +% Source: https://en.wikipedia.org/wiki/Zebra_Puzzle + +% Modelling the problem: +% - Each house is represented by the predicate house/5 +% - The five houses are modelled as a(n) (ordered) list of house(Color, Nationality, Pet, Beverage, Cigaret) in the variable Houses +% - The predicate solve/2 for solving the riddle is of the form solve(WaterDrinker, ZebraOwner) where WaterDrinker is the nationality of the person who drinks water and ZebraOwner the nationality of the person owning a zebra as a pet + +% Expected solution: if the problem is modelled correctly by this program then the only solution set should be: +% WaterDrinker = norwegian, ZebraOwner = japanese. + +% adjacent/3 - A helper function for expressing the "directly next to" relation in a list +% adjacent(A, B, List) means that either A is directly left of B in List or A is directly right of B in List +adjacent(A, B, List) :- nextto(A, B, List); nextto(B, A, List). + +% solve/2 - The main predicate for solving the puzzle +solve(WaterDrinker, ZebraOwner) :- + length(Houses, 5), % 1. There are five houses. + member(house(red, english, _, _, _), Houses), % 2. The Englishman lives in the red house. + member(house(_, spanish, dog, _, _), Houses), % 3. The Spaniard owns the dog. + member(house(green, _, _, coffee, _), Houses), % 4. Coffee is drunk in the green house. + member(house(_, ukrainian, _, tea, _), Houses), % 5. The Ukrainian drinks tea. + nextto(house(ivory, _, _, _, _), house(green, _, _, _, _), Houses), % 6. The green house is immediately to the right of the ivory house. + member(house(_, _, snail, _, old_gold), Houses), % 7. The Old Gold smoker owns snails. + member(house(yellow, _, _, _, kools), Houses), % 8. Kools are smoked in the yellow house. + nth1(3, Houses, house(_, _, _, milk, _)), % 9. Milk is drunk in the middle house. + nth1(1, Houses, house(_, norwegian, _, _, _)), % 10. The Norwegian lives in the first house. + adjacent(house(_, _, _, _, chesterfields), house(_, _, fox, _, _), Houses), % 11. The man who smokes Chesterfields lives in the house next to the man with the fox. + adjacent(house(_, _, _, _, kools), house(_, _, horse, _, _), Houses), % 12. Kools are smoked in the house next to the house where the horse is kept. + member(house(_, _, _, orange_juice, lucky_strike), Houses), % 13. The Lucky Strike smoker drinks orange juice. + member(house(_, japanese, _, _, parliaments), Houses), % 14. The Japanese smokes Parliaments. + adjacent(house(_, norwegian, _, _, _), house(blue, _, _, _, _), Houses), % 15. The Norwegian lives next to the blue house + member(house(_, WaterDrinker, _, water, _), Houses), % Who (WaterDrinker) drinks water? + member(house(_, ZebraOwner, zebra, _, _), Houses). % Who (ZebraOwner) owns the zebra?