├── .editorconfig ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .no-sublime-package ├── Context.sublime-menu ├── Default.sublime-keymap ├── GDL-dark.sublime-color-scheme ├── GDL-light.sublime-color-scheme ├── GDL.py ├── GDL.sublime-settings ├── GDL.sublime-syntax ├── LICENSE ├── Main.sublime-menu ├── Messages ├── install.txt ├── v2.0.0.txt ├── v2.0.1.txt ├── v2.0.2.txt ├── v2.1.0.txt ├── v2.2.0.txt ├── v3.0.0.txt ├── v3.1.0.txt ├── v3.1.1.txt ├── v3.2.0.txt ├── v3.2.2.txt ├── v3.2.3.txt ├── v3.2.4.txt ├── v3.4.0.txt ├── v3.4.1.txt ├── v3.4.2.txt ├── v3.4.3.txt ├── v3.4.4.txt └── v3.4.5.txt ├── Preferences ├── Comments.tmPreferences ├── Completion Rules.tmPreferences ├── GDL.sublime-completions ├── Miscellaneous.tmPreferences ├── Symbol Index Global.tmPreferences └── Symbol Index.tmPreferences ├── README.md ├── Snippets ├── 2D-Script.sublime-snippet ├── 3D-Script.sublime-snippet ├── DynHotspotLinear.sublime-snippet ├── Master-Script.sublime-snippet ├── Modpar.sublime-snippet ├── Param-Angle.sublime-snippet ├── Param-Array.sublime-snippet ├── Param-BMat.sublime-snippet ├── Param-Bool.sublime-snippet ├── Param-Dict.sublime-snippet ├── Param-FillPattern.sublime-snippet ├── Param-Hidden.sublime-snippet ├── Param-Integer.sublime-snippet ├── Param-Length.sublime-snippet ├── Param-LineType.sublime-snippet ├── Param-Pen.sublime-snippet ├── Param-Profile.sublime-snippet ├── Param-Real.sublime-snippet ├── Param-Seperator.sublime-snippet ├── Param-String.sublime-snippet ├── Param-Surface.sublime-snippet ├── Param-Title.sublime-snippet ├── Parameter-Script.sublime-snippet ├── Subroutine.sublime-snippet ├── UI-Script.sublime-snippet ├── commentline.sublime-snippet ├── endmarker.sublime-snippet └── eps.sublime-snippet ├── _logging.py ├── demo-code.gdl ├── img └── gdlst-logo.png └── messages.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig for https://github.com/runxel/GDL-sublime 2 | # see docs at https://EditorConfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_style = tab 9 | indent_size = 4 10 | 11 | [*.py] 12 | 13 | [syntax_test_gdl] 14 | indent_style = space 15 | 16 | [*.{sublime-syntax,yaml}] 17 | indent_style = space 18 | indent_size = 2 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: runxel 4 | patreon: runxel 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: runxel 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Something's broken? 4 | title: '' 5 | labels: bug? 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Bug description** 11 | 12 | 13 | **To reproduce** 14 | 15 | 16 | **Expected behavior** 17 | 18 | 19 | **My system:** 20 | - OS: [e.g. MacOS] 21 | 22 | **Additional context** 23 | 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea 4 | title: '' 5 | labels: request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem?** 11 | 12 | 13 | **Describe the solution you'd like** 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gitignore 2 | 3 | *.cache 4 | *.pyc 5 | .Bridge* 6 | ._* 7 | .DS_Store 8 | .fseventsd 9 | .TemporaryItems 10 | .Trashes 11 | .Spotlight-V100 12 | Thumbs.db 13 | package-metadata.json 14 | 15 | # project specific 16 | *.sublime-workspace 17 | *.sublime-project 18 | syntax_test_* 19 | *.org 20 | GDLDev.sublime-settings 21 | -------------------------------------------------------------------------------- /.no-sublime-package: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runxel/GDL-sublime/dd7a8362e86f3ac5a659f2afc0f795e11eaa27f0/.no-sublime-package -------------------------------------------------------------------------------- /Context.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { "caption": "-", "id": "gdl-sep-top"}, 3 | { 4 | "id": "gdl", 5 | "caption": "GDL (convert)", 6 | "children": 7 | [ 8 | { 9 | "caption": "Convert to script [gsm –> hsf/gdl]", 10 | "command": "hsf_build" 11 | }, 12 | { 13 | "caption": "Build GSM from HSF [hsf/gdl –> gsm]", 14 | "command": "libpart_build" 15 | } 16 | ] 17 | }, 18 | { "caption": "-", "id": "gdl-sep-bottom"} 19 | ] -------------------------------------------------------------------------------- /Default.sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | // Convert to script (gsm -> hsf/gdl) 3 | { "keys": ["ctrl+shift+h"], "command": "hsf_build" }, 4 | // Build GSM from HSF (hsf/gdl -> gsm) 5 | { "keys": ["ctrl+shift+alt+g"], "command": "libpart_build", "context":[{"key":"selector", "operator":"equal", "operand":"source.gdl"}] }, 6 | // autopair backticks for localized strings (``) 7 | { "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`$0`"}, "context": 8 | [ 9 | { "key": "selector", "operator": "equal", "operand": "source.gdl"}, 10 | { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, 11 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true } 12 | ] 13 | }, 14 | ] 15 | -------------------------------------------------------------------------------- /GDL-dark.sublime-color-scheme: -------------------------------------------------------------------------------- 1 | { 2 | /* visit https://github.com/runxel/GDL-sublime */ 3 | "name": "GDL-dark", 4 | /* .sublime-color-scheme Version for ST3 */ 5 | "author": "Lucas Becker", 6 | /* runxel–>@github.com */ 7 | "variables": 8 | { 9 | "background": "#2A2827", 10 | "foreground": "#E5E5E5", 11 | "caret": "#3FEDD8", 12 | "invisibles": "#48493F", 13 | "lineHilight": "#535647", 14 | "dark": "#22221C", 15 | 16 | "coral": "#FF7979", 17 | "darkred": "#BB3D3D", 18 | "oldpink": "#D2999A", 19 | "peach": "#FAC49F", 20 | "mustard": "#DFB76A", 21 | "gold": "#FAC863", 22 | "lightgreen": "#AAFFAA", 23 | "darkgreen": "#39AB73", 24 | "forestgreen": "#117A65", 25 | "dodgerblue": "#1F95D9", 26 | "greyblue": "#657b83", 27 | "lightblue": "#8BB6D9", 28 | "cyan": "#3FEDD8", 29 | "violet": "#6F5BA8", 30 | "purple": "#AE4977", 31 | "brown": "#8C7342", 32 | "grey": "#686a5b" 33 | }, 34 | "globals": 35 | { 36 | "background": "var(background)", 37 | "foreground": "var(foreground)", 38 | "line_highlight": "var(lineHilight)", 39 | "gutter": "var(background)", 40 | "minimap_border": "var(dark)", 41 | 42 | "caret": "var(caret)", 43 | "invisibles": "var(invisibles)", 44 | 45 | "highlight": "var(gold)", 46 | "find_highlight": "var(gold)", 47 | "find_highlight_foreground": "var(background)", 48 | 49 | "guide": "#42473a", 50 | "active_guide": "#e1cc83", 51 | "stack_guide": "#655e53", 52 | 53 | "selection": "color(var(background) blend(var(dark) 5%))", 54 | "selection_border": "var(gold)", 55 | "inactive_selection": "color(var(background) blend(var(dark) 45%))", 56 | 57 | "shadow": "color(var(background) blend(#000 75%))", 58 | "shadow_width": "4" 59 | }, 60 | "rules": 61 | [ 62 | { 63 | "name": "Comment", 64 | "scope": "comment", 65 | "foreground": "var(grey)" 66 | }, 67 | { 68 | "name": "Foreground", 69 | "scope": "keyword.operator.class, constant.other", 70 | "foreground": "#d7e6dc" 71 | }, 72 | { 73 | "name": "Support Variables", 74 | "scope": "support.other.variable", 75 | "foreground": "var(oldpink)" 76 | }, 77 | { 78 | "name": "Support Variable Shadow", 79 | "scope": "support.other.variable.shadow.gdl", 80 | "font_style": "italic" 81 | }, 82 | { 83 | "name": "Support Class", 84 | "scope": "support.type", 85 | "foreground": "var(gold)" 86 | }, 87 | { 88 | "name": "Subroutines", 89 | "scope": "entity.name.function, punctuation.section.function", 90 | "foreground": "#40bdbd", 91 | "background": "color(var(foreground) alpha(0.13))", 92 | "font_style": "bold" 93 | }, 94 | { 95 | "name": "Jump labels", 96 | "scope": "variable.function.gdl", 97 | "foreground": "#389C9C" 98 | }, 99 | { 100 | "name": "Constant numeric", 101 | "scope": "constant.numeric", 102 | "foreground": "var(peach)" 103 | }, 104 | { 105 | "name": "Constant (lang)", 106 | "scope": "constant.language", 107 | "foreground": "#f79e60" 108 | }, 109 | { 110 | "name": "String", 111 | "scope": "string", 112 | "foreground": "#d7dd9b" 113 | }, 114 | { 115 | "name": "Escape chars", 116 | "scope": "constant.character.escape", 117 | "foreground": "#d7dd9b", 118 | "background": "#875593" 119 | }, 120 | { 121 | "name": "String placeholders", 122 | "scope": "constant.other.placeholder", 123 | "foreground": "#d7dd9b", 124 | "background": "#34495e" 125 | }, 126 | { 127 | "name": "Autotext", 128 | "scope": "constant.other.autotext", 129 | "foreground": "#93BD50", 130 | "background": "#243341" 131 | }, 132 | { 133 | "name": "Operators", 134 | "scope": "keyword.operator, constant.other.color", 135 | "foreground": "var(cyan)" 136 | }, 137 | { 138 | "name": "Function Methods", 139 | "scope": "keyword.other.special-method, punctuation.section.arguments", 140 | "foreground": "var(lightblue)" 141 | }, 142 | { 143 | "name": "Brackets", 144 | "scope": "punctuation.section.group", 145 | "foreground": "var(greyblue)" 146 | }, 147 | { 148 | "name": "Keyword, Storage", 149 | "scope": "keyword, storage.type, punctuation.section.range", 150 | "foreground": "var(coral)" 151 | }, 152 | { 153 | "name": "Invalid", 154 | "scope": "invalid", 155 | "foreground": "#d7e7db", 156 | "background": "#f86161" 157 | }, 158 | { 159 | "name": "Deprecated", 160 | "scope": "invalid.deprecated", 161 | "foreground": "#d7e7db", 162 | "background": "color(#cc9ad8 alpha(0.7))" 163 | }, 164 | { 165 | "name": "Deprecated Globals", 166 | "scope": "keyword.globals.deprecated.gdl", 167 | "foreground": "#d7e7db", 168 | "background": "color(#cc9ad8 alpha(0.7))" 169 | }, 170 | { 171 | "name": "Storage Function", 172 | "scope": "storage.type.function", 173 | "foreground": "#8ad341", 174 | "font_style": "italic" 175 | }, 176 | { 177 | "name": "Globals", 178 | "scope": "keyword.globals", 179 | "foreground": "var(darkgreen)" 180 | }, 181 | { 182 | "name": "Keyword control", 183 | "scope": "keyword.control", 184 | "foreground": "var(violet)", 185 | "background": "color(var(dark) blend(var(violet) 90%))" 186 | }, 187 | { 188 | "name": "Argument", 189 | "scope": "meta.function-call.arguments", 190 | "foreground": "#dbca95" 191 | }, 192 | { 193 | "name": "Optional and Special Parameters", 194 | "scope": "keyword.optionalparameters, meta.parameters", 195 | "foreground": "var(lightgreen)" 196 | }, 197 | { 198 | "name": "Transform", 199 | "scope": "keyword.transform", 200 | "foreground": "var(darkred)", 201 | "font_style": "italic" 202 | }, 203 | { 204 | "name": "Hotedits", 205 | "scope": "keyword.hotedits", 206 | "foreground": "color(var(coral) alpha(0.8))" 207 | }, 208 | { 209 | "name": "Buffer", 210 | "scope": "keyword.buffer, punctuation.section.buffer", 211 | "foreground": "var(dodgerblue)" 212 | }, 213 | { 214 | "name": "inline Line continuation", 215 | "scope": "punctuation.separator.continuation", 216 | "background": "color(var(dodgerblue) alpha(0.7))" 217 | }, 218 | { 219 | "name": "Array", 220 | "scope": "entity.name.array", 221 | "foreground": "" /*#dfb76a*/ 222 | }, 223 | { 224 | "name": "Array brackets", 225 | "scope": "punctuation.section.array", 226 | "foreground": "var(brown)" 227 | }, 228 | { 229 | "name": "Ident Keywords", 230 | "scope": "storage.type.ident-keyword.gdl", 231 | "foreground": "var(mustard)", 232 | "font_style": "italic" 233 | }, 234 | { 235 | "name": "Open Calls", 236 | "scope": "keyword.extern, keyword.addon", 237 | "foreground": "var(purple)" 238 | } 239 | ] 240 | } -------------------------------------------------------------------------------- /GDL-light.sublime-color-scheme: -------------------------------------------------------------------------------- 1 | { 2 | /* visit https://github.com/runxel/GDL-sublime */ 3 | "name": "GDL-light", 4 | /* .sublime-color-scheme Version for ST3 */ 5 | "author": "Lucas Becker", 6 | /* runxel @ github.com */ 7 | "variables": 8 | { 9 | "background": "#EEEEEE", 10 | "foreground": "#5F6A6A", 11 | "caret": "#8B8B8B", 12 | "invisibles": "#B9BAAF", 13 | "lineHilight": "#DEDFD9", 14 | "dark": "#22221C", 15 | 16 | "coral": "#EF5350", 17 | "darkred": "#BB3D3D", 18 | "oldpink": "#D2999A", 19 | "peach": "#FF8A65", 20 | "mustard": "#DFB76A", 21 | "gold": "#F5B041", 22 | "wheat": "#999966", 23 | "lightgreen": "#66CC33", 24 | "darkgreen": "#39AB73", 25 | "forestgreen": "#117A65", 26 | "dodgerblue": "#42A5F5", 27 | "lightblue": "#8BB6D9", 28 | "darkblue": "#1976d2", 29 | "greyblue": "#657b83", 30 | "violet": "#6F5BA8", 31 | "purple": "#AE4977", 32 | "brown": "#8C7342", 33 | "grey": "#B6B7AE" 34 | }, 35 | "globals": 36 | { 37 | "background": "var(background)", 38 | "foreground": "var(foreground)", 39 | "line_highlight": "var(lineHilight)", 40 | "gutter": "var(background)", 41 | "minimap_border": "var(dark)", 42 | 43 | "caret": "var(caret)", 44 | "invisibles": "var(invisibles)", 45 | 46 | "highlight": "var(coral)", 47 | "find_highlight": "var(coral)", 48 | "find_highlight_foreground": "var(background)", 49 | 50 | "guide": "#42473a", 51 | "active_guide": "#e1cc83", 52 | "stack_guide": "#655e53", 53 | 54 | "selection": "#dcddd9", 55 | "selection_border": "var(dark)", 56 | "inactive_selection": "color(var(background) blend(var(dark) 65%))", 57 | "selection_corner_style": "square", 58 | 59 | "shadow": "color(var(background) blend(#000 45%))", 60 | "shadow_width": "4" 61 | }, 62 | "rules": 63 | [ 64 | { 65 | "name": "Comment", 66 | "scope": "comment", 67 | "foreground": "var(grey)" 68 | }, 69 | { 70 | "name": "Foreground", 71 | "scope": "keyword.operator.class, constant.other", 72 | "foreground": "#d7e6dc" 73 | }, 74 | { 75 | "name": "Support Variables", 76 | "scope": "support.other.variable", 77 | "foreground": "var(oldpink)" 78 | }, 79 | { 80 | "name": "Support Variable Shadow", 81 | "scope": "support.other.variable.shadow.gdl", 82 | "font_style": "italic" 83 | }, 84 | { 85 | "name": "Support Class", 86 | "scope": "support.type", 87 | "foreground": "var(gold)" 88 | }, 89 | { 90 | "name": "Subroutines", 91 | "scope": "entity.name.function, punctuation.section.function", 92 | "foreground": "#40bdbd", 93 | "background": "color(var(foreground) alpha(0.13))", 94 | "font_style": "bold" 95 | }, 96 | { 97 | "name": "Jump labels", 98 | "scope": "variable.function.gdl", 99 | "foreground": "#389C9C" 100 | }, 101 | { 102 | "name": "Constant numeric", 103 | "scope": "constant.numeric", 104 | "foreground": "var(peach)" 105 | }, 106 | { 107 | "name": "Constant (lang)", 108 | "scope": "constant.language", 109 | "foreground": "#f79e60" 110 | }, 111 | { 112 | "name": "String", 113 | "scope": "string", 114 | "foreground": "var(wheat)" 115 | }, 116 | { 117 | "name": "Escape chars", 118 | "scope": "constant.character.escape", 119 | "foreground": "#d7dd9b", 120 | "background": "color(#875593 alpha(0.5))" 121 | }, 122 | { 123 | "name": "String placeholders", 124 | "scope": "constant.other.placeholder", 125 | "foreground": "#d7dd9b", 126 | "background": "color(#34495e alpha(0.7))" 127 | }, 128 | { 129 | "name": "Autotext", 130 | "scope": "constant.other.autotext", 131 | "foreground": "color(#006633 alpha(0.7))", 132 | "background": "color(#243341 alpha(0.12))" 133 | }, 134 | { 135 | "name": "Operators", 136 | "scope": "keyword.operator, constant.other.color", 137 | "foreground": "var(dodgerblue)" 138 | }, 139 | { 140 | "name": "Function Methods", 141 | "scope": "keyword.other.special-method, punctuation.section.arguments", 142 | "foreground": "var(lightblue)" 143 | }, 144 | { 145 | "name": "Brackets", 146 | "scope": "punctuation.section.group", 147 | "foreground": "var(greyblue)" 148 | }, 149 | { 150 | "name": "Keyword, Storage", 151 | "scope": "keyword, storage.type, punctuation.section.range", 152 | "foreground": "var(coral)" 153 | }, 154 | { 155 | "name": "Invalid", 156 | "scope": "invalid", 157 | "foreground": "#d7e7db", 158 | "background": "#f86161" 159 | }, 160 | { 161 | "name": "Deprecated", 162 | "scope": "invalid.deprecated", 163 | "foreground": "#d7e7db", 164 | "background": "color(#cc9ad8 alpha(0.7))" 165 | }, 166 | { 167 | "name": "Deprecated Globals", 168 | "scope": "keyword.globals.deprecated.gdl", 169 | "foreground": "#d7e7db", 170 | "background": "color(#cc9ad8 alpha(0.7))" 171 | }, 172 | { 173 | "name": "Storage Function", 174 | "scope": "storage.type.function", 175 | "foreground": "#8ad341", 176 | "font_style": "italic" 177 | }, 178 | { 179 | "name": "Globals", 180 | "scope": "keyword.globals", 181 | "foreground": "var(darkgreen)" 182 | }, 183 | { 184 | "name": "Keyword control", 185 | "scope": "keyword.control", 186 | "foreground": "var(violet)", 187 | "background": "color(var(violet) alpha(0.15))" 188 | }, 189 | { 190 | "name": "Argument", 191 | "scope": "meta.function-call.arguments", 192 | "foreground": "#dbca95" 193 | }, 194 | { 195 | "name": "Optional and Special Parameters", 196 | "scope": "keyword.optionalparameters, meta.parameters", 197 | "foreground": "var(lightgreen)" 198 | }, 199 | { 200 | "name": "Transform", 201 | "scope": "keyword.transform", 202 | "foreground": "var(darkred)", 203 | "font_style": "italic" 204 | }, 205 | { 206 | "name": "Hotedits", 207 | "scope": "keyword.hotedits", 208 | "foreground": "color(var(coral) alpha(0.8))" 209 | }, 210 | { 211 | "name": "Buffer", 212 | "scope": "keyword.buffer, punctuation.section.buffer", 213 | "foreground": "var(darkblue)" 214 | }, 215 | { 216 | "name": "inline Line continuation", 217 | "scope": "punctuation.separator.continuation", 218 | "background": "color(var(dodgerblue) alpha(0.25))" 219 | }, 220 | { 221 | "name": "Array", 222 | "scope": "entity.name.array", 223 | "foreground": "" /*#dfb76a*/ 224 | }, 225 | { 226 | "name": "Array brackets", 227 | "scope": "punctuation.section.array", 228 | "foreground": "var(brown)" 229 | }, 230 | { 231 | "name": "Ident Keywords", 232 | "scope": "storage.type.ident-keyword.gdl", 233 | "foreground": "var(mustard)", 234 | "font_style": "italic" 235 | }, 236 | { 237 | "name": "Open Calls", 238 | "scope": "keyword.extern, keyword.addon", 239 | "foreground": "var(purple)" 240 | } 241 | ] 242 | } -------------------------------------------------------------------------------- /GDL.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import sublime 5 | import sublime_plugin 6 | import sys 7 | import logging 8 | 9 | log = logging.getLogger(__name__) 10 | 11 | PACKAGE_SETTINGS = "GDL.sublime-settings" 12 | DEFAULT_AC_PATH = "C:/Program Files/GRAPHISOFT/ARCHICAD 23" 13 | DEFAULT_AC_PATH_MAC = "/Applications/GRAPHISOFT/AC23/ARCHICAD 23.app" 14 | 15 | def save_all_files(): 16 | """ Saves all files open in Sublime. 17 | Mimics the 'save on build' behavior of Sublime Text. 18 | """ 19 | for window in sublime.windows(): 20 | for view in window.views(): 21 | if view.file_name() and view.is_dirty(): 22 | view.run_command("save") 23 | 24 | def get_project_settings(view, request, *args): 25 | """ Returns the requested parameters from the `.sublime-project` file. 26 | If the the very parameter does not exist this method return an empty string. 27 | TODO: migrate all other functions to this one 28 | """ 29 | project_data = view.window().project_data() 30 | 31 | if not project_data: 32 | err("You must create a project first! (Project > Save Project As...)") 33 | return 34 | 35 | project_settings = project_data.get(request, "") 36 | 37 | return project_settings 38 | 39 | def get_project_data(view, invoke): 40 | """ Gets the data of the .sublime-project file. 41 | Returns additional arguments for the commandline operation, 42 | if the user has set any. 43 | """ 44 | # invoke options: 'to-hsf' / 'to-gsm' / 'proj_gsm_path' 45 | project_data = view.window().project_data() 46 | if not project_data: 47 | err("You must create a project first! (Project > Save Project As...)") 48 | return 49 | 50 | project_settings = project_data.get('cmdargs', {}) 51 | if type(project_settings) is dict: 52 | # check if dict is empty 53 | if bool(project_settings): 54 | return project_settings.get(invoke, "") 55 | else: 56 | # dict is empty, which means user hasn't set any cmdargs 57 | return "" 58 | else: 59 | err() 60 | return 61 | 62 | def get_project_subroot(view): 63 | """ Gets the data of the .sublime-project file. 64 | Returns a relative path, if set. 65 | (Useful, if you have many subfolders and want to assign 66 | a new root, where all the objects are in.) 67 | """ 68 | project_data = view.window().project_data() 69 | sub_root_setting = project_data.get('root', "") 70 | return sub_root_setting 71 | 72 | def get_ac_path(view, pckgset): 73 | """ Returns a path to a certain Archicad version, either from project file or the global settings. 74 | (Former is useful if one is developing for different Archicad versions and 75 | they want to use the appropiate LP Converter version.) 76 | """ 77 | proj_ac_path = get_project_settings(view, "AC_path") 78 | 79 | if not proj_ac_path: 80 | ac_path = str(pckgset.get("AC_path", DEFAULT_AC_PATH)) 81 | else: 82 | ac_path = proj_ac_path 83 | 84 | return ac_path 85 | 86 | def err(text): 87 | """ Gives us a ST error message. """ 88 | if not text: # None or empty 89 | text = "Sorry. Something went wrong." 90 | sublime.error_message(text) 91 | 92 | def is_dir(*args): 93 | """ Takes arguments and determines if the resulting path is a directory. """ 94 | try: 95 | is_dir = os.path.isdir(os.path.join(*args)) 96 | except: 97 | is_dir = False 98 | return is_dir 99 | 100 | def is_file(*args): 101 | """ Takes arguments and determines if the resulting path is a file. """ 102 | try: 103 | is_file = os.path.isfile(os.path.join(*args)) 104 | except: 105 | is_file = False 106 | return is_file 107 | 108 | def splitall(path): 109 | """ Returns all parts of a path as a list. """ 110 | allparts = [] 111 | while 1: 112 | parts = os.path.split(path) 113 | if parts[0] == path: # sentinel for absolute paths 114 | allparts.insert(0, parts[0]) 115 | break 116 | elif parts[1] == path: # sentinel for relative paths 117 | allparts.insert(0, parts[1]) 118 | break 119 | else: 120 | path = parts[0] 121 | allparts.insert(0, parts[1]) 122 | return allparts 123 | 124 | 125 | class GdlOnSave(sublime_plugin.EventListener): 126 | """ Establishes an event listener, which gets active when the user saves a GDL file. 127 | If the appropiate setting is set, a GSM will be built automatically. 128 | """ 129 | def on_post_save_async(self, view): 130 | # check if the project has the setting 131 | if view.window().project_data().get("convert_on_save", False): 132 | # only get active when the user edited a GDL file 133 | if view.match_selector(0, "source.gdl"): 134 | view.window().run_command('libpart_build', {"on_post_save_state": True}) 135 | 136 | 137 | ############################################################################ 138 | class Builder(sublime_plugin.WindowCommand): 139 | def run(self, *args, **kwargs): 140 | self.view = self.window.active_view() 141 | self.pckg_settings = sublime.load_settings(PACKAGE_SETTINGS) 142 | 143 | # get the path to the LP_XML_Converter right 144 | self.AC_path = get_ac_path(self.view, self.pckg_settings) 145 | 146 | self.lp_conv_path = self.check_system() 147 | self.converter = os.path.join(self.AC_path, self.lp_conv_path) 148 | 149 | if self.view.settings().get("auto_save", True): 150 | save_all_files() 151 | 152 | if self.on_post_save_state: 153 | # if coming from the on_post_save event listener we can directly proceed without selection 154 | self.delegator() 155 | else: 156 | self.selection_process() 157 | 158 | def selection_process(self): 159 | # determine if there is a sub root folder being set in the project settings 160 | self.sub_root_path = get_project_subroot(self.view) 161 | if self.sub_root_path: # empty str are falsy 162 | self.has_subroot = True 163 | _debug_subroot = self.sub_root_path 164 | else: 165 | self.has_subroot = False 166 | _debug_subroot = "" 167 | log.debug("Sub-Root Path is: {}".format(_debug_subroot)) 168 | 169 | if len(self.window.folders()) > 1: 170 | err("You can't use the GDL-Sublime plugin as a menu command in a multi root environment.\n" 171 | "Please try the 'convert_on_save' setting instead.\n" 172 | "Alternatively you might be able to rearrange your folder structure to use the 'sub root' setting.") 173 | return 174 | 175 | if len(self.window.folders()) > 1 and self.sub_root_path: 176 | # this means there are multiple folders linked into ST 177 | # there would be an ambiguity for which of the folders the `root` feature should apply 178 | err("You can not use the 'root' setting in a multiroot environment.\n" 179 | "Maybe try the 'convert_on_save' setting.") 180 | return 181 | if len(self.window.folders()) > 1: 182 | self.has_multi_root = True 183 | else: 184 | self.has_multi_root = False 185 | 186 | self.project_abs_basepath = self.window.folders() 187 | 188 | # get the list of folders which could be part of a conversion 189 | self.folders = self.get_folders() 190 | log.debug("Folders prior to selection: {}".format(self.folders)) 191 | 192 | if len(self.folders) <= 0: 193 | err("GDL build command error: Please open a project, or.\n" 194 | "make sure all folders and files are named properly.\n" 195 | "If in doubt consult the README.") 196 | elif len(self.folders) == 1: 197 | self.has_multiple_folders = False 198 | self.working_dir = self.folders[0] 199 | self.delegator() 200 | else: 201 | self.has_multiple_folders = True 202 | self.pick_working_dir(self.folders) 203 | 204 | def check_system(self): 205 | """ Returns the path to the LP_XML converter. 206 | """ 207 | if sys.platform.startswith('darwin'): # OSX 208 | self.os_win = False 209 | return "Contents/MacOS/LP_XMLConverter.app/Contents/MacOS/LP_XMLConverter" 210 | elif sys.platform.startswith('win'): # Windows 211 | self.os_win = True 212 | return "LP_XMLConverter.exe" 213 | else: 214 | err("GDL build error: Your OS is not supported.") 215 | return 216 | 217 | def get_folders(self): 218 | """ Retrieves all subfolders of the working directory and returns 219 | a subset which includes all valid items as a list. 220 | """ 221 | if self.has_subroot: 222 | abs_path_with_subroot = os.path.join(self.project_abs_basepath[0], self.sub_root_path) 223 | # first let's check if user has linked to a object folder directly 224 | # we can answer that by checking if there is an appropiate GSM or folder directly in the directory 225 | rootbase = os.path.basename(os.path.normpath(abs_path_with_subroot)) 226 | if is_dir(abs_path_with_subroot, rootbase) or is_file(abs_path_with_subroot, rootbase +'.gsm'): 227 | folders = [abs_path_with_subroot] 228 | else: 229 | folders = self.valid_subfolders(abs_path_with_subroot) 230 | else: 231 | # get all the current firstlevel subfolders 232 | if self.has_multi_root: 233 | folders = [] 234 | for folder in self.project_abs_basepath: 235 | folders.append(self.valid_subfolders(folder)) 236 | 237 | else: # no multiroot, no subroot 238 | # check if this the project is just a plain structure with just one single object inside (either HSF or GSM) 239 | basepath = self.project_abs_basepath[0] 240 | basename = os.path.basename(os.path.normpath(basepath)) 241 | if is_dir(basepath, basename) or is_file(basepath, basename +'.gsm'): 242 | folders = self.project_abs_basepath # return list 243 | else: 244 | folders = self.valid_subfolders(basepath) 245 | 246 | return folders 247 | 248 | def valid_subfolders(self, basepath): 249 | """ Returns a list of all subfolders, checked for being not empty by looking for HSF/GSM inside. """ 250 | folders = [fldr for fldr in os.listdir(basepath) if ( 251 | is_dir(basepath, fldr) and ( 252 | is_dir(basepath, fldr, fldr) \ 253 | or is_file(basepath, fldr, fldr +'.gsm')))] 254 | return folders 255 | 256 | def pick_working_dir(self, folders): 257 | """ Gets called if there are multiple folders in the project. 258 | """ 259 | if self.has_multi_root: 260 | # list comprehension because multiroot has a nested structure 261 | # i.e. [[one, two], [three, four]] 262 | folderNames = [x for l in folders for x in l] 263 | else: 264 | folderNames = [] 265 | for folder in folders: 266 | index = folder.rfind('/') + 1 267 | if index > 0: 268 | folderNames.append(folder[index:]) 269 | else: 270 | folderNames.append(folder) 271 | 272 | # self.select will be called once with the indices (mapped from the folders) 273 | self.show_quick_panel(folderNames, self.select) 274 | 275 | def select(self, select): 276 | if self.has_multi_root: 277 | # now we have to resolve the problem of the flat `select` index 278 | # vs. the nested structure of a multi root 279 | folders = [x for l in self.folders for x in l] 280 | else: 281 | folders = self.folders 282 | 283 | if select < 0: # will be -1 if panel was cancelled 284 | return 285 | self.working_dir = folders[select] 286 | self.delegator() # go on here 287 | 288 | def show_quick_panel(self, options, done): 289 | """ Shows the Sublime Text quick panel with the invoked options. """ 290 | # Sublime Text 3 requires a short timeout between quick panels 291 | sublime.set_timeout(lambda: self.window.show_quick_panel(options, done), 10) 292 | 293 | def normpath(self, path): 294 | """ Normalize a pathname by collapsing redundant separators. 295 | On Windows, it converts forward slashes to backward slashes. 296 | Returns the object as an quote encapsulated string (as needed for the CLI). 297 | """ 298 | return '"{}"'.format(os.path.normpath(path)) 299 | 300 | def delegator(self): 301 | """ Delegates back to the specific calling class. 302 | Also makes the `working_dir` path absolut. 303 | """ 304 | try: 305 | if not self.on_post_save_state: 306 | if self.has_subroot: 307 | # join with new root 308 | self.working_dir = os.path.join(self.sub_root_path, self.working_dir) 309 | # make absolut path, since relative paths might introduce errors 310 | self.working_dir = os.path.join(self.project_abs_basepath[0], self.working_dir) 311 | else: # we are coming from the on_post_save event listener 312 | self.working_dir = os.path.join(*splitall(self.active_file_path)[:-2]) 313 | except Exception as e: 314 | raise e 315 | 316 | log.debug("Working Dir: {}".format(self.working_dir)) 317 | 318 | # this delegates back to the calling class. 319 | self.on_done_proj() 320 | 321 | 322 | ############################################################################ 323 | class HsfBuildCommand(Builder): 324 | """ Converts a GSM into human readable GDL scripts via the LP_XMLConverter. """ 325 | # go to 326 | # http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-lp_xmlconverter-tool 327 | # for detailed information 328 | 329 | def run(self, *args, **kwargs): 330 | """ Sublime Text will call this function. 331 | We will run the parent class "Builder" first. 332 | That will give us all the parameters we need. 333 | """ 334 | self.on_post_save_state = False 335 | super().run(self) 336 | 337 | def on_done_proj(self): 338 | # we're coming from super().delegator() 339 | # own function because quick panel is async 340 | self.find_gsm() 341 | 342 | def find_gsm(self): 343 | self.files = [] 344 | log.debug(self.working_dir) 345 | # r=root, d=directories, f=files 346 | for r, d, f in os.walk(self.working_dir): 347 | for file in f: 348 | # casefolding because the user might have all caps extension 349 | # https://docs.python.org/3/library/stdtypes.html#str.casefold 350 | folded = str.casefold(file) 351 | if folded.endswith('.gsm'): 352 | self.files.append(os.path.join(r, file)) 353 | 354 | if len(self.files) <= 0: 355 | err("GDL build error: No GSM found.") 356 | elif len(self.files) > 1: 357 | self.show_quick_panel(self.files, self.select_gsm) 358 | else: 359 | self.file_to_convert = self.files[0] 360 | self.on_done_file() # go on here 361 | 362 | def on_done_file(self): 363 | self.cmdargs = get_project_data(self.view, 'to-hsf') 364 | self.run_hsf() 365 | 366 | def select_gsm(self, select): 367 | if select < 0: 368 | return 369 | self.file_to_convert = self.files[select] 370 | self.on_done_file() # go on here 371 | 372 | def run_hsf(self, ): 373 | """ Invokes the LP_XML converter. 374 | """ 375 | # normpath all to just be sure the CLI will take them without complain 376 | self.converter = super().normpath(self.converter) 377 | self.file_to_convert = super().normpath(self.file_to_convert) 378 | self.working_dir = super().normpath(self.working_dir) 379 | 380 | cmd = [self.converter, "libpart2hsf", self.cmdargs, self.file_to_convert, self.working_dir] # cmd, source, dest 381 | cmd = list(filter(None, cmd)) # filters out the empty cmdargs. otherwise Macs get hiccups. sigh. 382 | cmd = " ".join(cmd) 383 | 384 | #log.debug("GDL Command run: " + " ".join(cmd)) # gets logged automatically by ST 385 | execCMD = {"shell_cmd": cmd} 386 | 387 | self.window.run_command("exec", execCMD) 388 | 389 | ############################################################################ 390 | class LibpartBuildCommand(Builder): 391 | """ Builds a GSM from the GDL scripts in the project. """ 392 | 393 | def run(self, *args, **kwargs): 394 | """ Sublime Text will call this function. """ 395 | # if this function however is called from the on_post_save event listener 396 | # then we want to bypass the selection part 397 | self.active_file_path = sublime.active_window().active_view().file_name() 398 | if 'on_post_save_state' in kwargs: 399 | log.debug("This command is called on post save.") 400 | log.debug("Current active file is: {}".format(self.active_file_path)) 401 | self.on_post_save_state = kwargs.get('on_post_save_state') 402 | else: 403 | self.on_post_save_state = False 404 | 405 | super().run(self) 406 | 407 | def on_done_proj(self): 408 | # we're coming from super().delegator() 409 | # own function because quick panel is async 410 | self.find_hsf() 411 | 412 | def find_hsf(self): 413 | """ Finds all possible folders for converting to GSM. 414 | """ 415 | if self.on_post_save_state: 416 | self.folder_to_convert = self.working_dir 417 | else: 418 | if len(self.folders) <= 0: 419 | err("GDL build error: No HSF found.") 420 | 421 | # this assumes the user follows the scheme to have a subfolder of the same name 422 | last_part_of_path = os.path.basename(os.path.normpath(self.working_dir)) 423 | 424 | self.folder_to_convert = os.path.join(self.working_dir, last_part_of_path) 425 | self.on_done_file() # go on here 426 | 427 | def on_done_file(self): 428 | """ Path handling for GSM output. 429 | """ 430 | self.global_gsm_path = str(self.pckg_settings.get("global_gsm_path", "")) 431 | self.proj_gsm_path = get_project_data(self.view, 'proj_gsm_path') 432 | 433 | output_path = "" 434 | if self.proj_gsm_path: # project based path takes precedence 435 | if self.proj_gsm_path != "default": 436 | # only set the path if its not 'default' which mimics the standard behavior 437 | # TODO implement path check here 438 | output_path = self.proj_gsm_path 439 | elif self.global_gsm_path: # otherwise take global path, if set 440 | output_path = self.global_gsm_path 441 | 442 | if not output_path: 443 | # default path => not global or proj path is set, or proj path says 'default' 444 | output_path = os.path.dirname(self.folder_to_convert) 445 | 446 | gsm_name = os.path.basename(os.path.normpath(self.folder_to_convert)) + ".gsm" 447 | self.gsm_path = os.path.join(output_path, gsm_name) 448 | 449 | self.cmdargs = get_project_data(self.view, 'to-gsm') 450 | 451 | self.run_libpart() 452 | 453 | def run_libpart(self): 454 | """ Invokes the LP_XML converter. 455 | """ 456 | self.converter = super().normpath(self.converter) 457 | self.folder_to_convert = super().normpath(self.folder_to_convert) 458 | self.gsm_path = super().normpath(self.gsm_path) 459 | 460 | cmd = [self.converter, "hsf2libpart", self.cmdargs, self.folder_to_convert, self.gsm_path] # cmd, source, dest 461 | cmd = list(filter(None, cmd)) # filters out the empty cmdargs. otherwise Macs get hiccups. sigh. 462 | # if you use `cmd` instead of `shell_cmd` you will get the infamous [Winerror 5] 463 | # see: https://forum.sublimetext.com/t/winerror-5-access-is-denied/ 464 | # however, for `shell_cmd` to work we need to pass a string, not a list (!) 465 | cmd = " ".join(cmd) 466 | 467 | # log.debug("GDL Command run: " + cmd) 468 | execCMD = {"shell_cmd": cmd} 469 | 470 | self.window.run_command("exec", execCMD) 471 | 472 | -------------------------------------------------------------------------------- /GDL.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // By default the light color scheme is used. 3 | // You can select either GDL-dark or GDL-light 4 | // or put a relative path to your own scheme here. 5 | "color_scheme": "${packages}/GDL/GDL-light.sublime-color-scheme", 6 | 7 | // set the syntax automatically for all .gdl files 8 | "extensions": ["gdl"], 9 | 10 | "rulers": [80,120], 11 | 12 | // Path to the current Archicad, where the LP_XMLConverter resides. 13 | // example Win: 14 | "AC_path": "C:/Program Files/GRAPHISOFT/ARCHICAD 23", 15 | // example Mac: 16 | // "/Applications/GRAPHISOFT/AC23/ARCHICAD 23.app" 17 | 18 | // If you specify a path here all conversions from HSF to GSM 19 | // will go into this place. This is helpful if you want to deploy 20 | // into a central library already linked in Archicad. 21 | "global_gsm_path": "", 22 | } -------------------------------------------------------------------------------- /GDL.sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # See the DOCS: http://www.sublimetext.com/docs/3/syntax.html 4 | # See the REPO: https://github.com/runxel/GDL-sublime 5 | author: Lucas Becker mail@wilu.be 6 | name: GDL 7 | file_extensions: gdl 8 | scope: source.gdl 9 | 10 | variables: 11 | escaped_byte: '\\(n|t|\\)?' 12 | units: '(e|(m|c|d)?m|f(f|d)?i|d(f|i)|pt|sq(mm?|cm|f|i)|d(d|ms)|gr|rad|surv|(ga)?l|cu((c|m)?m|f|i|y))' 13 | subroutine_name: ([0-9]+|(")[a-z_0-9]+(")) 14 | function_names: |- 15 | (NOT|ABS|CEIL|INT|FRA|ROUND_INT|SGN|ACS|ASN|ATN|COS|SIN|TAN|EXP|LGT|LOG|SQR|MAX|MIN|RND 16 | |STR\{2\}|STR|SPLIT|STW|STRLEN|STRSTR|STRSUB|STRTOUPPER|STRTOLOWER|VARDIM[12]|BITTEST|BITSET 17 | |REQ((UEST)(\{[2-4]\})?)?|IND|NTR|VARTYPE|(HAS|REMOVE)KEY) 18 | addon_function_names: ((INIT|CLOSE)ADDONSCOPE|(CALL|PREPARE)FUNCTION) 19 | identifier_continue: '[[:alnum:]_]' 20 | identifier: '\b[[:alpha:]_]{{identifier_continue}}*\b' 21 | 22 | 23 | contexts: 24 | main: 25 | - include: arrays 26 | - include: global 27 | - include: hots 28 | - include: transform 29 | - include: methods 30 | - include: attributes 31 | - include: buffer 32 | - include: buffer-in 33 | - include: func 34 | - include: gdl-globals 35 | - include: optional 36 | - include: easyparams 37 | - include: expression-common # needs to be last bc of brackets 38 | - include: dotted-names 39 | - include: generic-names 40 | 41 | # Included in all contexts by default: 42 | # except where - meta_include_prototype: false 43 | prototype: 44 | - include: comments 45 | 46 | ################ General ################## 47 | 48 | comments: 49 | - match: '!' 50 | scope: punctuation.definition.comment.gdl 51 | push: 52 | - meta_scope: comment.line.gdl 53 | - match: $\n? 54 | pop: true 55 | 56 | global: 57 | - include: subs 58 | - include: operators 59 | - include: operators-word 60 | - include: operators-logical 61 | - include: escaped-byte 62 | - include: string 63 | - include: line-continuation 64 | - include: statements 65 | - include: controls 66 | 67 | ############### Subroutines ################# 68 | subs: 69 | - match: (?i)(?<=^){{subroutine_name}}(?=:($|\s)) 70 | scope: entity.name.function.gdl 71 | push: 72 | - match: ':' 73 | scope: punctuation.section.function.begin.gdl 74 | pop: true 75 | 76 | 77 | ############################################# 78 | operators: 79 | - match: \+|\-|\^|\*|\/|=|(<|>)=?|<>|\# 80 | scope: keyword.operator.gdl 81 | 82 | operators-word: 83 | - match: (?i)\b(MOD|AND|OR|EXOR)\b 84 | scope: keyword.operator.word.gdl 85 | 86 | operators-logical: 87 | - match: (%|&|\||@) 88 | scope: keyword.operator.logical.gdl 89 | 90 | escaped-byte: 91 | - match: '{{escaped_byte}}' 92 | scope: constant.character.escape.gdl 93 | 94 | string: 95 | # strings should not be affected by comments 96 | - match: '"' 97 | scope: punctuation.definition.string.begin.gdl 98 | push: 99 | - meta_include_prototype: false 100 | - meta_scope: string.quoted.double.gdl 101 | - match: '"' 102 | scope: punctuation.definition.string.end.gdl 103 | pop: true 104 | - include: escaped-byte 105 | - include: string_placeholder 106 | - include: request-param-deprecated 107 | - include: request-param 108 | - include: autotext 109 | - include: optional 110 | - include: easyparams 111 | - match: "'" 112 | scope: punctuation.definition.string.begin.localized.gdl 113 | push: 114 | - meta_include_prototype: false 115 | - meta_scope: string.quoted.single.gdl 116 | - match: "'" 117 | scope: punctuation.definition.string.end.localized.gdl 118 | pop: true 119 | - include: escaped-byte 120 | - include: string_placeholder 121 | - include: request-param-deprecated 122 | - include: request-param 123 | - include: autotext 124 | - include: optional 125 | - match: "`" 126 | scope: punctuation.definition.string.begin.localized.gdl 127 | push: 128 | - meta_include_prototype: false 129 | - meta_scope: string.quoted.single.gdl 130 | - match: "`" 131 | scope: punctuation.definition.string.end.localized.gdl 132 | pop: true 133 | - include: escaped-byte 134 | - include: string_placeholder 135 | - include: request-param-deprecated 136 | - include: request-param 137 | - include: autotext 138 | - include: optional 139 | 140 | string_placeholder: 141 | - match: |- 142 | (?x)% # always begins with % 143 | ((\#|~|\*|\^|\+|-|\s)* # atleast one marker 144 | (\d+)? # might have number with... 145 | (\.)? # ...decimal point 146 | (\d+) # at least one number 147 | {{units}}? # unitmarker possible 148 | |{{units}} # unit alone 149 | |(~|\.|n|s))? # possible without number and unit 150 | scope: constant.other.placeholder.gdl 151 | 152 | autotext: 153 | - match: |- 154 | (?ix)(<( 155 | project(name|number|status)|dateOfIssue| 156 | site(fullAddress|address[1-3]|city|state|postcode|country)| 157 | keywords|notes| 158 | (architect(name|position|company|fullAddress|address[1-3]|city|state|postcode|country|email|phone|fax|web)| 159 | cadTechnician| 160 | (client(name|company|fullAddress|address[1-3]|city|state|postcode|country|email|phone|fax))| 161 | (short|long)date)|time|lastSaved(at|by)| 162 | (file(name|path)|layout(name|ID|number)|subset(name|ID)|drawing(name|ID|scale)|originalScale|magnification|renovationFilter| 163 | marker(sheet|drawing)number(90|110)?|backRefSheetNumber)(_R)?| 164 | numOfLayouts|change(ID|description)| 165 | revisionID|(current)?issue(ID|description|date|dby)|currentRevisionID 166 | )>) 167 | scope: constant.other.autotext.gdl 168 | 169 | line-continuation: 170 | - match: (?<=\s)(:) 171 | scope: punctuation.separator.continuation.inline.gdl 172 | 173 | statements: 174 | - match: \b(true|false)\b 175 | scope: constant.language.gdl 176 | 177 | - match: (?i)\b(\!NOCONTOUR|BAS|BOX|CONT|FILLA|FILTER|GDLBIN|HIP_ROOFS|(LIN|NOD)(E)?|ORIGO|PARS|PAUSE|PLOTMAKER|PLOTTER|RECT_|SFLINE|TET(RA)?|TRI|UI_(CANCEL|OK)|VOCA|WALL_)\b 178 | scope: invalid.deprecated.gdl 179 | 180 | controls: 181 | - match: (?i)(?<=^|\s)((END)?GROUP)\b 182 | scope: keyword.control.group.gdl 183 | 184 | - match: (?i)(?<=^|\s)(GOTO|RETURN|EXIT|BREAKPOINT|END)\b 185 | scope: keyword.control.flow.gdl 186 | 187 | - match: (?i)(?<=^|\s)GOSUB 188 | scope: keyword.control.flow.gdl 189 | push: 190 | - meta_scope: meta.function-call.gdl 191 | - match: (?i)({{subroutine_name}}) 192 | scope: variable.function.gdl 193 | pop: true 194 | - include: main 195 | - match: (?i)\b(\w+)\b 196 | scope: variable.gdl 197 | pop: true 198 | 199 | - match: (?i)(?<=^|\s)(FOR|TO|NEXT|DO|(END)?WHILE|REPEAT|UNTIL)\b 200 | scope: keyword.control.flow.gdl 201 | 202 | - match: (?i)(?<=^|\s)((END)?IF|THEN|ELSE)\b 203 | scope: keyword.control.conditional.gdl 204 | 205 | number: 206 | # handles integer and decimal numbers 207 | - match: |- 208 | \b(?x: 209 | -? # an optional minus 210 | (?: 211 | 0 # a zero 212 | | # ...or... 213 | [1-9] # a 1-9 character 214 | \d* # followed by zero or more digits 215 | ) 216 | (?: 217 | (?: 218 | \. # a period 219 | \d+ # followed by one or more digits 220 | )? 221 | (?: 222 | [eE] # an e character 223 | [+-]? # followed by optional +/- 224 | \d+ # followed by one or more digits 225 | )? # exponent optional 226 | )? # decimal portion optional 227 | ) 228 | scope: constant.numeric.gdl 229 | 230 | expression-common: 231 | - include: number 232 | - match: \( 233 | scope: punctuation.section.group.begin.gdl 234 | push: 235 | - meta_scope: meta.group.gdl 236 | - match: \) 237 | scope: punctuation.section.group.end.gdl 238 | pop: true 239 | - match: ',' 240 | scope: punctuation.separator.gdl 241 | - include: main 242 | - match: \) 243 | scope: invalid.illegal.stray.brace.round.gdl 244 | - match: \] 245 | scope: invalid.illegal.stray.brace.square.gdl 246 | - match: \} 247 | scope: invalid.illegal.stray.brace.curly.gdl 248 | 249 | dotted-names: 250 | - match: '(\.)(?={{identifier}})' 251 | captures: 252 | 1: punctuation.accessor.dot.gdl 253 | push: 254 | - include: arrays 255 | - include: generic-names 256 | - match: '' 257 | pop: true 258 | 259 | generic-names: 260 | - match: '{{identifier}}' 261 | scope: meta.generic-name.gdl 262 | 263 | ################ Hotspots ################## 264 | hots: 265 | - match: (?i)\b(HOTSPOT[2]?|HOTLINE[2]?|HOTARC[2]?)\b 266 | scope: keyword.hotedits.gdl 267 | 268 | ################ Transform ################## 269 | transform: 270 | - match: (?i)\b(ADD[2XYZ]?|ROT[2XYZ]?|MUL[2XYZ]?|XFORM|DEL(\sTOP)?)\b 271 | scope: keyword.transform.gdl 272 | 273 | ################ METHODS ################## 274 | methods: 275 | - include: methods-2d 276 | - include: methods-3d 277 | 278 | ################ 2D ################# 279 | methods-2d: 280 | - match: (?i)(?<=^|\s)((LINE|RECT|ARC|CIRCLE|WALLLINE[2]?|WALLARC)2|SPLINE2[A]?|(PICTURE|WALLHOLE|WALLBLOCK)2(\{2\})?|POLY2(_?(A|B(\{[2-6]\})?)?))(?=$|\s) 281 | scope: keyword.shape.2D.gdl 282 | 283 | - match: (?i)(?<=^|\s)((TEXT|RICHTEXT)2)(?=$|\s) 284 | scope: keyword.text.2D.text.gdl 285 | 286 | ################ 3D ################# 287 | methods-3d: 288 | - match: (?i)(?<=^|\s)(BLOCK|BRICK|CYLIND|CONE|SPHERE|ELLIPS|ELBOW|ARMC|ARME)(?=$|\s) 289 | scope: keyword.shape.3D.basic.gdl 290 | 291 | - match: (?i)(?<=^|\s)((PLANE|POLY)(_?)|ARC|CIRCLE|LIN_|RECT)(?=$|\s) 292 | scope: keyword.shape.3D.planar.gdl 293 | 294 | - match: (?i)(?<=^|\s)(SLAB(_?)|CSLAB_|CROOF_(\{[2-4]\})?|[CB]WALL_|XWALL_(\{[23]\})?|BEAM|MESH|POLYROOF(\{[2-4]\})?)(?=$|\s) 295 | scope: keyword.shape.3D.complex.gdl 296 | 297 | - match: (?i)(?<=^|\s)(BASE|BODY|COOR(\{[23]\})?|EDGE|PGON(\{[23]\})?|PIPG|TEVE|VECT|VERT(\{2\})?)(?=$|\s) 298 | scope: keyword.shape.3D.primitive.gdl 299 | 300 | - match: (?i)(?<=^|\s)(POINTCLOUD)(?=$|\s) 301 | scope: keyword.shape.3D.pointcloud.gdl 302 | 303 | - match: (?i)(?<=^|\s)(PRISM_?|[BFH]PRISM_|[CS]PRISM_(\{[234]\})?)(?=$|\s) 304 | scope: keyword.shape.3D.prisms.gdl 305 | 306 | - match: (?i)(?<=^|\s)(PYRAMID|RULED(\{2\}|SEGMENTED(\{2\})?)?|EXTRUDE|SWEEP|TUBE([A]|\{2\})?|MASS(\{2\})?|COONS(\{2\})?|REVOLVE(\{[2-5]\})?|(EXTRUDED|REVOLVED|RULED)SHELL(\{[23]\})?|REVOLVEDSHELLANGULAR(\{[23]\})?)(?=$|\s) 307 | scope: keyword.shape.3D.poly.gdl 308 | 309 | - match: (?i)(?<=^|\s)(CUT(PLANE(\{[2-4]\})?|POLY[A]?|FORM(\{2\})?|SHAPE|END)|WALL(HOLE|NICHE))(?=$|\s) 310 | scope: keyword.shape.3D.cut.gdl 311 | 312 | - match: (?i)(?<=^|\b)((place|kill)group|(add|isect|sub)group(\{[23]\})?|sweepgroup(\{[2-5]\})?|isectlines|creategroupwithmaterial)(?=$|\s|\() 313 | scope: keyword.shape.3D.seo.gdl 314 | 315 | - match: (?i)(?<=^|\s)(TEXT|RICHTEXT)(?=$|\s) 316 | scope: keyword.shape.3D.text.gdl 317 | 318 | - match: (?i)(?<=^|\s)(LIGHT|PICTURE|BINARY)(?=$|\s) 319 | scope: keyword.shape.3D.other.gdl 320 | 321 | - match: (?i)(?<=^|\s)(NURBS(CURVE[23]D|(SUR)?FACE|VERT|EDGE|TRIM(SINGULAR)?|LUMP|BODY))(?=$|\s) 322 | scope: keyword.shape.nurbs.gdl 323 | 324 | - match: (?i)(?<=^|\s)(FRAGMENT[2]?|PROJECT2(\{[2-4]\})?|DRAWING(2|3(\{[2-3]\})?))(?=$|\s) 325 | scope: keyword.symbol.gdl 326 | 327 | ############### Attributes ################# 328 | attributes: 329 | - include: ident-keyword 330 | - include: attribute-set 331 | - include: attribute 332 | - include: model 333 | - include: shadow 334 | - include: nongeo 335 | 336 | ident-keyword: 337 | - match: (?i)(?<=^|\s)(LET|DIM|DICT)(\b) 338 | scope: storage.type.ident-keyword.gdl 339 | 340 | attribute-set: 341 | - match: (?i)\b(DEFINE|SET|BASED_ON)\b 342 | scope: storage.type.function.gdl 343 | 344 | attribute: 345 | - match: |- 346 | (?ix)\b(PEN|RESOL|RADIUS|TOLER|MODEL|SHADOW|DRAWINDEX|LINE_(TYPE|PROPERTY)| 347 | |SYMBOL_(LINE|FILL)|FILL[A]?|(SOLID|EMPTY|TRANSLUCENT|IMAGE|(LINEAR|RADIAL)_GRADIENT)_FILL| 348 | |FILLTYPES_MASK|(BUILDING_)?MATERIAL|TEXTURE|STYLE(\{2\})?|(END)?PARAGRAPH| 349 | |TEXTBLOCK_?|ADDITIONAL_DATA|SECT_(FILL|ATTRS(\{2\})?)) 350 | (?=$|\s) 351 | scope: support.type.attribute.gdl 352 | 353 | model: 354 | - match: (?i)\b(SOLID|SURFACE|WIRE)\b 355 | scope: support.other.variable.model.gdl 356 | 357 | shadow: 358 | - match: (?i)\b(ON|OFF|AUTO)\b 359 | scope: support.other.variable.shadow.gdl 360 | 361 | range: 362 | - match: (?i)\b(RANGE)(?=\s) 363 | scope: keyword.nongeo.parameters.range.gdl 364 | 365 | nongeo: 366 | - match: (?i)\b(VALUES(\{2\})?|STEP|(RETURNED_)?PARAMETERS|LOCK|HIDEPARAMETER|PARVALUE_DESCRIPTION|(PROFILE|FILL)TYPES_MASK)(?=$|\s) 367 | scope: keyword.nongeo.parameters.gdl 368 | 369 | - include: range 370 | - match: (?i)(?<=RANGE)\s(\(|\[) 371 | scope: punctuation.section.range.left-delimiter.gdl 372 | push: 373 | - meta_scope: meta.section-range.gdl 374 | - match: (\)|\]) 375 | scope: punctuation.section.range.right-delimiter.gdl 376 | pop: true 377 | - match: ',' 378 | scope: punctuation.separator.arguments.gdl 379 | - include: main 380 | 381 | - match: (?i)\b(CUSTOM)\b 382 | scope: support.other.variable.parameters.custom.gdl 383 | 384 | - match: (?i)(?<=hideparameter\s)(\s*all)\b 385 | scope: support.other.variable.parameters.all.gdl 386 | 387 | - match: (?i)\b(UI_(Next|Prev|Function|Link))\b 388 | scope: support.other.variable.ui.gdl 389 | 390 | - match: (?i)\b((REF\s+)?(COMPONENT|DESCRIPTOR)|BINARYPROP|DATABASE_SET|POSITION|REF_(COMPONENT|DESCRIPTOR)|(SURFACE|VOLUME)3D|DRAWING[2]?)\b 391 | scope: keyword.nongeo.properties.gdl 392 | 393 | - match: |- 394 | (?ix)\b(UI_(dialog|(current_)?page|button|pict(_button)?|separator|groupbox|style|outfield|tooltip|listfield| 395 | infield(\{[2-4]\})?| 396 | ((pict_)?radiobutton|pict_pushcheckbutton|listitem|colorpicker|slider|textstyle_infield|custom_popup_(infield|listitem))(\{[2]\})?)) 397 | (?=$|\s) 398 | scope: keyword.nongeo.ui.gdl 399 | 400 | - match: (?i)\b(MIGRATIONWARNING|NEWPARAMETER|SETMIGRATIONGUID|DELETED_PAR_VALUE|STORED_PAR_VALUE)\b 401 | scope: keyword.nongeo.migration.gdl 402 | 403 | - match: (?i)\b(PRINT|OUTPUT|CLOSE|CALL|FILE_DEPENDENCE)\b 404 | scope: keyword.extern.gdl 405 | 406 | - match: (?i)\b({{addon_function_names}})\b 407 | scope: keyword.addon.gdl 408 | 409 | - match: (?i)((OPEN|INPUT)\s?(?=\()) 410 | captures: 411 | 2: keyword.extern.gdl 412 | push: 413 | - match: \( 414 | scope: punctuation.section.arguments.begin.gdl 415 | set: 416 | - match: \) 417 | scope: punctuation.section.arguments.end.gdl 418 | pop: true 419 | - match: ',' 420 | scope: punctuation.separator.arguments.gdl 421 | - include: func 422 | - include: operators 423 | - include: expression-common 424 | - include: string 425 | - include: arrays 426 | 427 | ############### Params ################# 428 | optional: 429 | - match: (?i)\b([ABCDEFG]|ZZYZX|(ac|gs|ifc|ROOM|FM)_\w+)\b 430 | scope: keyword.optionalparameters.fixed.gdl 431 | 432 | easyparams: 433 | - match: (?i)\b((x|y|z)_\w+)\b 434 | scope: meta.parameters.length.gdl 435 | - match: (?i)\b((i|int)_\w+)\b 436 | scope: meta.parameters.integer.gdl 437 | - match: (?i)\b((f|float|real)_\w+)\b 438 | scope: meta.parameters.float.gdl 439 | - match: (?i)\b(ang_\w+)\b 440 | scope: meta.parameters.angle.gdl 441 | - match: (?i)\b((b|bool)_\w+)\b 442 | scope: meta.parameters.bool.gdl 443 | - match: (?i)\b(str_\w+)\b 444 | scope: meta.parameters.string.gdl 445 | - match: (?i)\b(fill_\w+)\b 446 | scope: meta.parameters.fill.gdl 447 | - match: (?i)\b(mat_\w+)\b 448 | scope: meta.parameters.material.gdl 449 | - match: (?i)\b(pen_\w+)\b 450 | scope: meta.parameters.pen.gdl 451 | - match: (?i)\b((lt|line)_\w+)\b 452 | scope: meta.parameters.linetype.gdl 453 | - match: (?i)\b(bm_\w+)\b 454 | scope: meta.parameters.bmat.gdl 455 | - match: (?i)\b(prof_\w+)\b 456 | scope: meta.parameters.profile.gdl 457 | - match: (?i)\b(dict_\w+)\b 458 | scope: meta.parameters.dict.gdl 459 | - match: (?i)\b(g_\w+)\b 460 | scope: meta.parameters.flag.gdl 461 | - match: (?i)\b(id(x)?_\w+)\b 462 | scope: meta.parameters.index.gdl 463 | 464 | ############### GDL globals ################# 465 | gdl-globals: 466 | - include: gdl-global-param 467 | - include: request-param 468 | - include: request-param-deprecated 469 | - include: globals-deprecated 470 | - match: (?i)\b(APPLICATION_QUERY|LIBRARYGLOBAL)\b 471 | scope: keyword.request.gdl 472 | 473 | gdl-global-param: 474 | - match: |- 475 | (?ix)\b(GLOB_(SCRIPT_TYPE|CONTEXT|SCALE|DRAWING_BGD_PEN|MODPAR_NAME|WORLD_ORIGO_OFFSET_[XY] 476 | |FRAME_NR|(FIRST|LAST)_FRAME|(EYE|TARG)POS_[XYZ]|SUN_A(ZIMUTH|LTITUDE)|UI_BUTTON_ID|CUTPLANES_INFO 477 | |STRUCTURE_DISPLAY|VIEW_TYPE|(PREVIEW|FEEDBACK|SEO_TOOL|DIAGNOSTICS)_MODE)) 478 | \b 479 | scope: keyword.globals.general.gdl 480 | 481 | - match: (?i)\b(GLOB_([HC]STORY_(ELEV|HEIGHT)|CH_STORY_DIST))\b 482 | scope: keyword.globals.story.gdl 483 | 484 | - match: (?i)\b(GLOB_(LAYER|ID|INT(GU)?ID|ELEVATION|ELEM_TYPE))\b 485 | scope: keyword.globals.elementparameters.gdl 486 | 487 | - match: (?i)\b(SYMB_((LINETYPE|FILL(_PEN)?)|(FBGD|SECT|VIEW)+_PEN|MAT|POS_[XYZ]|ROTANGLE|MIRRORED|[ABZ]+_SIZE))\b 488 | scope: keyword.globals.objectparameters.gdl 489 | 490 | - match: |- 491 | (?ix)\b(WIDO_(REVEAL_(ON|SIDE)|SILL(_HEIGHT)?|(R|OPR)SIDE_SILL_HEIGHT|(RIGHT|LEFT)_JAMB|(THRES|HEAD)_DEPTH|((R|OPR)SIDE_)?HEAD_HEIGHT 492 | |(FRAME|SUBFL)_THICKNESS|POSITION|ORIENTATION|MARKER_TXT|PREFIX|CUSTOM_MARKER|ORIG_DIST|PWALL_INSET|(N_)?(R|OPR)SIDE_(WIDTH|HEIGHT|SURF)|VOLUME|GROSS_(SURFACE|VOLUME))) 493 | \b 494 | scope: keyword.globals.window.gdl 495 | 496 | - match: |- 497 | (?ix)\b(LABEL_ 498 | (Position|Custom_Arrow|Arrow((Head)?_Pen|_LINETYPE) 499 | |Font_(Name|Style(2)?) 500 | |Text_(Size|(BG_)?Pen|Align|Leading|Width_Fact|Wrap|Charspace_Fact) 501 | |Wrap_Text|Charspace_Fact|Frame_(On|Offset) 502 | |Anchor_Pos|Rotangle|Always_Readable 503 | |Has_Pointer 504 | |Assoc_Elem_(Orientation|Geometry) 505 | ))\b 506 | scope: keyword.globals.label.gdl 507 | 508 | - match: |- 509 | (?ix)(?<=^|\s|\+|\-|\^|\*|\*\*|\/|\=|<|>|<\=|>\=|<>|\#) 510 | (WALL_((INTGU)?ID|RESOL|((START|END)_)?THICKNESS|INCL|((MIN|MAX)_)?HEIGHT|MAT_(A|B|EDGE)|LINETYPE|FILL(_PEN)? 511 | |(COMPS|BMAT)_NAME|SKINS_(PARAMS|NUMBER|BMAT_NAMES)|BMAT|(SECT|VIEW|FBGD)_PEN|DIRECTION|POSITION|(LENGTH|(GROSS_)?SURFACE)_[AB](_CON)?|CENTER_LENGTH|AREA|PERIMETER 512 | |EDGE_SURF|GROSS_VOLUME|VOLUME(_[AB])?(_CON)?|(DOORS|WINDS|HOLES|COLUMNS)_NR|(DOORS|WINDS)_SURF|HOLES_(SURF(_[AB])?|VOLUME)|(WINDS|DOORS)_WID|CROSSSECTION_TYPE 513 | |SKIN_((MIN|MAX)_HEIGHT|THICKNESS)_(A|B)|(INSU|AIR)_THICKNESS|Texture_Wrap 514 | |Flipped))\b 515 | scope: keyword.globals.wall.gdl 516 | 517 | - match: |- 518 | (?ix)\b(COLU_(CORE(_(X|Y|FILL(_PEN)?|FBGD_PEN|((GROSS|TOP|BOT)_)?SURF|(GROSS_)?VOL|GROSS_TOPBOT_SURF|BMAT(_NAME)?))? 519 | |VENEER_(FILL(_PEN)?|FBGD_PEN|WIDTH|VOL|(TOP_|BOT_)?SURF|GROSS_((TOPBOT_)?SURF|VOL)|BMAT(_NAME)?)|((MIN|MAX)_)?HEIGHT|DIM[12]|MAT|LINETYPE|(SECT|VIEW)_PEN 520 | |PERIMETER|AREA|(GROSS_)?VOLUME|CROSSSECTION_TYPE|PROFILE_NAME|SEGMENT_(INDEX|INFO))) 521 | \b 522 | scope: keyword.globals.column.gdl 523 | 524 | - match: |- 525 | (?ix)\b(BEAM_( 526 | Thickness|Height|Refline_Offset|Priority 527 | |Mat_(Right|Left|Top|Bottom|End) 528 | |Bmat(_Name)?|(Outline|Axes)_Linetype 529 | |Fill(_Pen)?|(Sect|FBGD)_Pen 530 | |Direction|Position|Length_(Right|Left) 531 | |(Right|Left|Top|Bottom|End)_Surf 532 | |Volume(_Con)? 533 | |Hole(s_(Nr|Surf|Volume)|_Edge_Surf) 534 | |Crosssection_Type|Profile_Name 535 | |Segment_(Index|Info) 536 | |Elevation_(Top|Bottom))) 537 | (?=$|\s) 538 | scope: keyword.globals.beam.gdl 539 | 540 | - match: |- 541 | (?ix)\b(SLAB_(THICKNESS|MAT_(TOP|EDGE|BOTT)|LINETYPE|FILL(_PEN)?|ELEVATION_(TOP|BOTTOM)|BMAT(_NAME)?|(FBGD|SECT|VIEW)+_PEN|COMPS_NAME|SKINS_(NUMBER|PARAMS|BMAT_NAMES) 542 | |PERIMETER|(GROSS_)?(TOP|BOT|EDGE)_SURF|(TOP|BOT)_SURF_CON|VOLUME(_CON)?|GROSS_VOLUME|GROSS_((TOP|BOT|EDGE)_SURF|VOLUME)_WITH_HOLES|SEGMENTS_NR|HOLES_(NR|AREA|PRM))) 543 | \b 544 | scope: keyword.globals.slab.gdl 545 | 546 | - match: |- 547 | (?ix)\b(ROOF_(THICKNESS|ANGLE|MAT_(TOP|EDGE|BOTT)|LINETYPE|FILL(_PEN)?|BMAT(_NAME)?|(FBGD|SECT|VIEW)+_PEN|COMPS_NAME|SKINS_(NUMBER|PARAMS|BMAT_NAMES) 548 | |(GROSS_)?(TOP|BOTTOM|EDGE)_SURF|(TOP|BOTTOM)_SURF_CON|PERIMETER|VOLUME(_CON)?|GROSS_VOLUME|SEGMENTS_NR|HOLES_(NR|AREA|PRM)|CONTOUR_AREA|INSU_THICKNESS 549 | |RIDGE|VALLEY|GABLE|HIP|EAVES|PEAK|(SIDE|END)_WALL|TRANSITION_(DOME|HOLLOW))) 550 | \b 551 | scope: keyword.globals.roof.gdl 552 | 553 | - match: (?i)\b(FILL_(Linetype|Fill(_Pen|_Category)?|Pen|Bmat(_Name)?|FBGD_Pen|Surf|Perimeter|Segment_Nr|Holes_(Nr|Area|Prm)))\b 554 | scope: keyword.globals.fill.gdl 555 | 556 | - match: (?i)\b(MESH_((LINE)?TYPE|BASE_OFFSET|(USEREDGE|TRIEDGE|SECT|VIEW)_PEN|MAT_(TOP|EDGE|BOTT)|FILL(_PEN)?|BMAT(_NAME)?|FBGD_PEN|(TOP|EDGE|BOTTOM)_SURF|PERIMETER|VOLUME|SEGMENTS_NR|HOLES_(NR|AREA|PRM)))\b 557 | scope: keyword.globals.mesh.gdl 558 | 559 | - match: |- 560 | (?ix)\b(STAIR_( 561 | Area|Volume|Height|Walkline_Length 562 | |Default_(Width|Going_Depth|Riser_Height|Tread_Thickness) 563 | |Nr_of_(Risers|treads)(_in_Flights)? 564 | |Landing_Number|Stair_Gradient 565 | |Rule_(Limits|Flags) 566 | |(Start|End)_with_Riser 567 | |(Tread|Riser|Nosing)_Exist 568 | |Breakmark_Geometry 569 | ))\b 570 | scope: keyword.globals.stair.general.gdl 571 | 572 | - match: (?i)\b(TREAD_((FRONT_)?AREA|VOLUME|STEP_INDEX|ELEVATION|GOING|THICKNESS|BMATS|(LOWER|UPPER)_RISER_(THICKNESS|HEIGHT|SLANT_ANGLE)|NOSING(_METHOD|_BY_SLANTING)?)|STAIR_TREAD_(GEOMETRY|FLAGS))\b 573 | scope: keyword.globals.stair.tread.gdl 574 | 575 | - match: (?i)\b(RISER_(FRONT_AREA|VOLUME|STEP_INDEX|WIDTH|HEIGHT|THICKNESS|BMATS|CUT|SLANT_ANGLE)|STAIR_RISER_GEOMETRY)\b 576 | scope: keyword.globals.stair.riser.gdl 577 | 578 | - match: (?i)\b(STRUCTURE_(3DLENGTH|VOLUME|WIDTH|HEIGHT|THICKNESS)|STAIR_(STRUCTURE_(GEOMETRY|FLAGS|CONN_(OFFSETS|FLAGS))|STRINGER_PATH_OFFSET))\b 579 | scope: keyword.globals.stair.structure.gdl 580 | 581 | - match: |- 582 | (?ix)\b(STAIR2D_( 583 | (Full|Lower|Middle|Upper)_((TPolygon|RPolyline|Walkline)_(Geom|Flags)|Boundary_Geom) 584 | |Full_SPoly(gon|line)_(Geom|Flags) 585 | |Breakmark_(Geom|Flags|Angle) 586 | |(Ext_(TPolygon|RPOlyline)|Drain_TPolygon|Polylines)_(Geom|Flags) 587 | |(Struct|Monolith)_Attributes 588 | |Layout_Types|Description_Position 589 | |Currstory_Location|Visibility|Customdisplay 590 | ))\b 591 | scope: keyword.globals.stair.2D.gdl 592 | 593 | - match: |- 594 | (?ix)\b( 595 | RAILING_( 596 | Height|(3D|Horizontal_)Length|Volume 597 | |Nr_of_(Segments|Posts|Balusters|Panels|Rails)) 598 | |RAIL_Disconnected_Cuts) 599 | \b 600 | scope: keyword.globals.railing.general.gdl 601 | 602 | - match: |- 603 | (?ix)(RAIL(_(CONNECTING_POSTS(_NUM)?|TYPE|POLYLINE_GEOMETRY|SEGMENT_FLAGS|CUTS|COMPONENTS|SLANT_ANGLE)|ING(_REFLINE_DISTANCE|PANEL_(TYPE|(UNCUT_)?GEOMETRY|FLAGS|SIDE_OFFSETS 604 | |(SLANT|SKEW)_ANGLE)|POST_(TYPE|TOP_COORD|(SEGMENT_)?CUTS)|END_DIRECTION_AND_ANGLE))) 605 | \b 606 | scope: keyword.globals.railing.3D.gdl 607 | 608 | - match: (?i)\b(RAIL2D_((FULL|LOWER|MIDDLE|UPPER)_((POLY(LINE|GON)_(GEOM|FLAGS))|VISIBILITY)|CUSTOMDISPLAY)|RAILPOST2D_VISIBILITY)\b 609 | scope: keyword.globals.railing.2D.gdl 610 | 611 | - match: |- 612 | (?ix)\b( 613 | (CWALL_( 614 | ID 615 | |(((Contour|Mainaxis|Secaxis|Custom)_)?Frames_)?Length 616 | |Surf(_Boundary)?|Panels_(Surf(_([Nsew]|NE|NW|SE|SW))?|Nr) 617 | |Height|Slant_Angle|Thickness|Pattern_Angle)) 618 | |(CWJunc|CWAcc)_Type 619 | |CW_Boundary_Placement 620 | )\b 621 | scope: keyword.globals.facade.general.gdl 622 | 623 | - match: |- 624 | (?ix)\b(CWFRAME_( 625 | Type|Class|Position|Direction 626 | |Width|Depth|Length|Mat 627 | |(Top|Bottom)_Cut(type|plane|polyline) 628 | ))\b 629 | scope: keyword.globals.facade.profile.gdl 630 | 631 | - match: (?i)\b(CWPANEL_(TYPE|CLASS|(VERTICAL|HORIZONTAL)_DIRECTION|(NOMINAL_)?(WIDTH|HEIGHT)|THICKNESS|(GROSS_|NOMINAL_)?SURF|PERIMETER|MAT_(OUTER|INNER|CUT)|FUNCTION|ORIENTATION))\b 632 | scope: keyword.globals.facade.panel.gdl 633 | 634 | - match: |- 635 | (?ix)\b(SHELLBASE_(THICKNESS|MAT_(REFERENCE|EDGE|OPPOSITE)|LINETYPE|FILL(_PEN)?|FBGD_PEN|(COMPS|BMAT)_NAME|BMAT|SKINS_(NUMBER|PARAMS|BMAT_NAMES)|(SECT|VIEW)_PEN 636 | |(COND_|GROSS_)?(REFERENCE|OPPOSITE)_SURF|(GROSS_)?EDGE_SURF|PERIMETER|(GROSS_|COND_)?VOLUME|HOLES_(NR|SURF|PRM)|OPENINGS_(NR|SURF)|INSU_THICKNESS 637 | |RIDGE|VALLEY|GABLE|HIP|EAVES|PEAK|(END|SIDE)_WALL|TRANSITION_(DOME|HOLLOW))) 638 | \b 639 | scope: keyword.globals.shell.gdl 640 | 641 | - match: (?i)\b(OPENING_(SYMBOL_(DISPLAY|BOUNDINGBOX|GEOMETRY)|POLYGON|HEIGHT|WIDTH|(HEADER|CENTER|SILL)HEIGHT_VALUES))\b 642 | scope: keyword.globals.opening.gdl 643 | 644 | - match: (?i)\b(MORPH_(LINETYPE|FILL(_PEN)?|BMAT(_NAME)?|FBGD_PEN|SECT_LINETYPE|(SECT|VIEW)_PEN|SOLID|MAT_DEFAULT|(CASTS|RECEIVES)_SHADOW|SURFACE|VOLUME|FLOOR_PERIMETER))\b 645 | scope: keyword.globals.morph.gdl 646 | 647 | - match: (?i)\b(LIGHT_(ON|RED|GREEN|BLUE|INTENSITY))\b 648 | scope: keyword.globals.light.gdl 649 | 650 | - match: |- 651 | (?ix)\b( 652 | GDL_WallZ_(Length|Surf|(Doors|Winds)_(Surf|Width)) 653 | |(From|To)_Guid 654 | |Skyl_(Marker_Txt|Opening_(Surf|Volume|Height|Width)|(Header|Sill)_Height|Rotangle) 655 | |Marker_Head_(Rot_Mode|Angle) 656 | |GLOB_Fill_Index_(Background|Solid) 657 | )\b 658 | scope: keyword.globals.misc.gdl 659 | 660 | - match: (?i)\b(GLOB_MVO_(Stair_Floor_Plan_(Opt|Comp)|Railing_Plan_Comp|CW(Frame|Panel|Junct|Acc)_Detlevel))\b 661 | scope: keyword.globals.mvo.gdl 662 | 663 | - match: (?i)\b((GLOB_((Issue|Change)_Scheme))|Layout_((Revision|Change)_History|Current(Version|Revision)_Open))\b 664 | scope: keyword.globals.layout.gdl 665 | 666 | - match: (?i)\b(GLOB_(PROJECT_((LONG|LAT|ALT)ITUDE|DATE)|NORTH_DIR))\b 667 | scope: keyword.globals.project.gdl 668 | 669 | - match: (?i)\b(GLOB_USER_([1-9]|[1][0-9]|20))\b 670 | scope: keyword.globals.user.gdl 671 | 672 | request-param: 673 | - match: |- 674 | (?ix)\b( 675 | (Blue|Red|Green)_of_(Pen|Material) 676 | |RGB_Of_(Material|Pen) 677 | |GDL_Version|Model_Size|Pen_of_RGB 678 | |Program(_Info)?|(Serial|Configuration)_Number 679 | |Ancestry_Info 680 | |(Angular_(Length_)?|Area_|Radial_|Sill_Height_)Dimension 681 | |(Assocel|Matching)_Properties 682 | |Assoclp_(Name|Parvalue(_with_Description)?) 683 | |Calc_(Angle|Area|Length|Volume)_Unit 684 | |Clean_Intersections|Custom_Auto_Label 685 | |Datetime 686 | |(Elevation|Level|Linear)_Dimension 687 | |Fontnames_List|Height_of_Style 688 | |Home(_Story(_of_Opening)?|DB_Info) 689 | |Story(_Info)? 690 | |ID_of_Main|Full_ID_of_Parent 691 | |Name_of_(Fill|Line_Type|Listed|Macro|Main|Material|Plan|Program|Style|Building_Material|Profile) 692 | |Class_of_Fill 693 | |Reference_Level_Data 694 | |(Style|Textblock)_Info 695 | |Floor_Plan_Option|View_Rotangle 696 | |Window_(Door_(Dimension|Show_Dim|Zone_Relev(_of_Owner)?)|Show_Dim) 697 | |Door_Show_Dim 698 | |Zone_Relations_of_Owner 699 | |Working_(Angle|Length)_Unit|Zone_(Category|Colus_Area|Relations) 700 | |(Building_)?Material_Info|Component_(Projected_Area|Volume) 701 | |(Component_Ids|((Component_)?(Property_Value(s)?|Properties)))_Of_Parent|Property_Name 702 | |(Profile_(Components|Default_(Boundingbox|Geometry)|Component_Info)) 703 | |((Model|Layout)_(length|text_size)_unit) 704 | |Autotext_List|Sum_with_rounding 705 | |Document_Feature 706 | )\b 707 | scope: keyword.globals.request.gdl 708 | 709 | request-param-deprecated: 710 | - match: |- 711 | (?ix)\b(Constr_Fills_Display|Internal_Id)\b 712 | scope: keyword.globals.deprecated.gdl 713 | 714 | globals-deprecated: 715 | - match: (?i)\b([A-Z](_\b|~)) 716 | scope: keyword.globals.deprecated.gdl 717 | 718 | ################# Buffer ################## 719 | buffer-out: 720 | - match: (?i)\b(GET|USE)\b 721 | scope: keyword.buffer.gdl 722 | 723 | buffer: 724 | - include: buffer-out 725 | - match: (?i)(?<=(GET|USE))\s?\( 726 | scope: punctuation.section.buffer.begin.gdl 727 | push: 728 | - meta_scope: meta.buffer.gdl 729 | - match: \) 730 | scope: punctuation.section.buffer.end.gdl 731 | pop: true 732 | - include: main 733 | 734 | buffer-in: 735 | # now buffer coms without () 736 | - match: (?i)(\b)(PUT|NSP)(\b) 737 | scope: keyword.buffer.gdl 738 | 739 | ############### FUNCTIONS ################# 740 | func: 741 | - include: functions 742 | - include: functions-special 743 | 744 | functions: 745 | - match: (?ix)(({{function_names}})\s?(?=\()) 746 | captures: 747 | 2: keyword.other.special-method.functions.gdl 748 | push: 749 | - match: \( 750 | scope: punctuation.section.arguments.begin.gdl 751 | set: 752 | - match: \) 753 | scope: punctuation.section.arguments.end.gdl 754 | pop: true 755 | - match: ',' 756 | scope: punctuation.separator.arguments.gdl 757 | - include: main 758 | 759 | functions-special: 760 | - match: (?i)(\b)(PI)(\b) 761 | scope: keyword.other.special-method.functions.gdl 762 | 763 | ################### Item Access ###################### 764 | arrays: 765 | - include: gdl-global-param 766 | - match: (?i)(?=\[) 767 | push: 768 | - match: \[ 769 | scope: punctuation.section.array.begin.gdl 770 | set: 771 | - meta_scope: section.array.gdl 772 | - match: \] 773 | scope: punctuation.section.array.end.gdl 774 | set: after-array 775 | - include: func 776 | - include: operators 777 | - include: expression-common 778 | - include: easyparams 779 | - include: string 780 | - include: arrays 781 | 782 | after-array: 783 | - match: \[ 784 | scope: punctuation.section.array.begin.gdl 785 | set: # we want only one possible bracket 786 | - meta_scope: section.array.gdl 787 | - match: \] 788 | scope: punctuation.section.array.end.gdl 789 | pop: true 790 | - include: func 791 | - include: operators 792 | - include: expression-common 793 | - include: easyparams 794 | - include: string 795 | - match: '' # if no second bracket pop out 796 | pop: true 797 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 Lucas Becker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Tools", 4 | "mnemonic": "T", 5 | "id": "tools", 6 | "children": 7 | [ 8 | { 9 | "caption": "GDL", 10 | "mnemonic": "G", 11 | "id": "gdlmenu", 12 | "children": 13 | [ 14 | { 15 | "caption": "Convert to script [gsm –> hsf/gdl]", 16 | "command": "hsf_build", 17 | "mnemonic": "h", 18 | }, 19 | { 20 | "caption": "Build GSM from HSF [hsf/gdl –> gsm]", 21 | "command": "libpart_build", 22 | "mnemonic": "g", 23 | } 24 | ], 25 | } 26 | ] 27 | }, 28 | { 29 | "id": "preferences", 30 | "children": 31 | [ 32 | { 33 | "caption": "Package Settings", 34 | "mnemonic": "P", 35 | "id": "package-settings", 36 | "children": 37 | [ 38 | { 39 | "caption": "GDL", 40 | "children": 41 | [ 42 | { 43 | "caption": "Settings", 44 | "command": "edit_settings", 45 | "args": { 46 | "base_file": "${packages}/GDL/GDL.sublime-settings", 47 | "default": "{\n$0\n}\n" 48 | } 49 | }, 50 | { 51 | "caption": "Demo code", 52 | "command": "open_file", 53 | "args": { 54 | "file": "${packages}/GDL/demo-code.gdl", 55 | } 56 | }, 57 | { "caption": "-" }, 58 | { 59 | "caption": "Github", 60 | "command": "open_url", 61 | "args": { 62 | "url": "https://github.com/runxel/GDL-sublime" 63 | } 64 | } 65 | ] 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | ] 72 | -------------------------------------------------------------------------------- /Messages/install.txt: -------------------------------------------------------------------------------- 1 |  2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | Thanks for installing the 10 | GDL Sublime Text package! 11 | ------------------------- 12 | 13 | 14 | How to use 15 | ========================= 16 | 17 | From now you can just select `GDL` from the code-language menu in the bottom right corner of Sublime Text. It will be automatically applied to any open files with the `.gdl` extension. 18 | 19 | This package comes with 2 pre-designed color schemes. 20 | Per default the light theme will be selected. 21 | If you prefer – like me – a dark coding environment, you can change this in the settings. 22 | Go to `Preferences > Package Settings > GDL > Settings`. 23 | Put your settings into the right pane and you're good to go! 24 | 25 | Whenever possible, use the "project" feature of Sublime Text, so you can benefit from automatic libpart conversion (via the "LP_XMLConverter") – which means avoiding the pain of copy & pasting every piece of code back into ARCHICAD. 26 | 27 | Don't forget to set up your Package Settings! 28 | 29 | ========================= 30 | Happy coding! 31 | -------------------------------------------------------------------------------- /Messages/v2.0.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 2.0.0 15 | 16 | ************************* 17 | 18 | 19 | ¿ What's new ? 20 | ************************* 21 | 22 | • Version 2.0 was completly rewritten 23 | from scratch 24 | • From v2 on the GDL plugin will require 25 | ST build 3084 or newer 26 | • v2 uses the then new introduced sublime-syntax 27 | (instead of .tmLanguage) 28 | • other cool stuff as described below 29 | 30 | _____Features_____ 31 | • "GoTo Definition" works with subroutines! press F12 to get to the matching subroutine fast 32 | • bracket mismatching 33 | • escape chars (\t, \n) in strings highlighting 34 | • string placeholder (like found in STR()) 35 | • more robust and versatile 36 | • the scopes are refined and follow the new style guide 37 | • more love for the light theme ♥ -------------------------------------------------------------------------------- /Messages/v2.0.1.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 2.0.1 15 | 16 | ************************* 17 | 18 | • String placheholder got 19 | styled incorrect sometimes, 20 | this is now fixed 21 | -------------------------------------------------------------------------------- /Messages/v2.0.2.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 2.0.2 15 | 16 | ************************* 17 | 18 | • some styling errors with 19 | GLOBALS got fixed -------------------------------------------------------------------------------- /Messages/v2.1.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 2.1.0 15 | 16 | ************************* 17 | 18 | • some styling errors with 19 | GOSUBS fixed 20 | • auto completion is now 21 | all lower caps, see 22 | issue #9 on github -------------------------------------------------------------------------------- /Messages/v2.2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 2.2.0 15 | 16 | ************************* 17 | 18 | • compatibility with 19 | upcoming Archicad 22 20 | -------------------------------------------------------------------------------- /Messages/v3.0.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.0.0 15 | 16 | ************************* 17 | 18 | • makes use of the new gsm to hsf 19 | (and vice-versa) workflow [using the LP_XMLConverter] 20 | • new menu for conversion can be found 21 | under `Tools > GDL`, and also as a 22 | RMB context menu 23 | • compatibility with 24 | upcoming Archicad 23 25 | · introduced dicts 26 | • uses now .sublime-color-scheme 27 | files instead of .thTheme 28 | • other workflow related 29 | refinements 30 | • some globals didn't got styled 31 | this is now fixed 32 | -------------------------------------------------------------------------------- /Messages/v3.1.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.1.0 15 | 16 | ************************* 17 | 18 | • New Package Setting: 19 | `global_gsm_path` 20 | You can now define a global default path where any 21 | GSMs should be deployed to. 22 | This is useful if you have a central library 23 | already linked in Archicad. 24 | (Thanks to Ben Cohen, http://www.4dlibrary.com.au/, 25 | for the suggestion.) 26 | 27 | • New Project Setting: 28 | `proj_gsm_path` 29 | You can also set a conversion path on project basis. 30 | This overrides the default (which is project root) 31 | and *also* the new `global_gsm_path` from the 32 | package setting! 33 | Instead of putting a path we can also write `default` 34 | which mimics the standard behavior (building the GSM 35 | right next to the HSF). 36 | 37 | Note: There's no path checking implemented at the moment! 38 | You have to take care by yourself that you're allowed to 39 | write at the paths accordingly. -------------------------------------------------------------------------------- /Messages/v3.1.1.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.1.1 15 | 16 | ************************* 17 | 18 | • Some AC23 key words were missing. 19 | This is fixed. 20 | See also: http://gdl.graphisoft.com/new-features-guide/new-gdl-features-in-archicad-23 -------------------------------------------------------------------------------- /Messages/v3.2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.2.0 15 | 16 | ************************* 17 | 18 | • Parameters with special prefixes like 19 | `i_` (for integer) or `b_` (for booleans) 20 | are now highlighted like the optional 21 | parameters (e.g. `ac_` or `gs_`) 22 | • There is a new option you can set in the 23 | `.sublime-project` file: 24 | If you have nested folders you can set a 25 | new "root" (where your HSFs are) via 26 | ``` 27 | { 28 | "root": "nested/folder" 29 | } 30 | ``` -------------------------------------------------------------------------------- /Messages/v3.2.2.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.2.2 15 | 16 | ************************* 17 | 18 | • Parameters are now also detected 19 | inside of strings. 20 | e.g. `UI_INFIELD "b_test"` -------------------------------------------------------------------------------- /Messages/v3.2.3.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.2.3 15 | 16 | ************************* 17 | 18 | • Converting to HSF didn't 19 | worked properly with the 20 | new "root" feature – 21 | this is now fixed -------------------------------------------------------------------------------- /Messages/v3.2.4.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.2.4 15 | 16 | ************************* 17 | 18 | • Issues with HSF -> GSM 19 | conversion resolved, when 20 | used with the new 'root' 21 | feature. -------------------------------------------------------------------------------- /Messages/v3.4.0.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.0 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | # changed 21 | • Global params (green) now get recognized when used as an array. 22 | • Params weren't recognized when used in an array. 23 | • The way GDL-S looks for HSF and GSMs is greatly improved. 24 | 25 | # added 26 | • New project settings: With `convert_on_save` set to true a GSM will automatically be built if you edited and saved a GDL file. 27 | • Backticks (`) get auto matched now, if the respective ST setting is enabled by the user. 28 | • Snippets for the parameter list in `libpartdata.xml` were added. [^1] 29 | 30 | # fixed 31 | • In certain circumstances the GSM Build command could fail. 32 | • If the user had file extensions being ALLCAPS the conversion failed. 33 | 34 | # removed 35 | • Multiroot environments are error prone and support (which was instable before already) for it has been removed. It might return at a later point however. 36 | 37 | 38 | --- 39 | [^1] Thanks to this comment: https://forum.sublimetext.com/t/cannot-insert-cdata-into-a-snippet/5188/10?u=runxel -------------------------------------------------------------------------------- /Messages/v3.4.1.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.1 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | There was some hiccup because the release numbers got jumbled around. My bad. This should be fixed now. 21 | 22 | # fixed 23 | • The plugin exited with an error message when the user had a plain structure with just one object in the folder. This is fixed. 24 | -------------------------------------------------------------------------------- /Messages/v3.4.2.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.2 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | # fixed 21 | • Some Snippets didn't work as expected. 22 | 23 | # added 24 | • You can now set a custom "AC_path" per project inside your .sublime-project file. This will overwrite the central path from the sublime-settings. The custom Path is useful when you're doing work for different versions of Archicad. 25 | (Please remember: Only Archicad versions from 23 and up are able to write HSF) 26 | • Snippet for an Array inside a Parameter -------------------------------------------------------------------------------- /Messages/v3.4.3.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.3 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | # fixed 21 | • The LP_XMLConverter wasn't found under certain circumstances in 3.4.2. -------------------------------------------------------------------------------- /Messages/v3.4.4.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.4 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | # fixed 21 | • Building of GSM/HSF could fail silently on Macs, if no sublime-project was made 22 | 23 | # added 24 | • More "request param strings" are getting recognized now. 25 | 26 | # changed 27 | • The color scheme was missing a color for deprecated globals and deprecated request params. Both are getting highlighted now. 28 | • Some completion rules got better descriptive variable names. 29 | • Typing `else` manually will now decrease the indent of the current line. -------------------------------------------------------------------------------- /Messages/v3.4.5.txt: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██╗ 3 | ██╔════╝ ██╔══██╗██║ 4 | ██║ ███╗██║ ██║██║ 5 | ██║ ██║██║ ██║██║ 6 | ╚██████╔╝██████╔╝███████╗ 7 | ╚═════╝ ╚═════╝ ╚══════╝ 8 | 9 | GDL Sublime Text package 10 | has successfully updated 11 | 12 | ************************* 13 | 14 | VERSION 3.4.5 15 | 16 | ************************* 17 | 18 | CHANGELOG: 19 | 20 | # fixed 21 | • `ui_function` and `ui_link` didn't got highlighted 22 | • Single quotes ('') can now be used inside localized strings (``) 23 | 24 | # added 25 | • A few missing Globals. GDL-Sublime should now recognize all 835 possible Globals and Requests. 26 | • `all` behind a `hideparameter` is now highlighted. 27 | 28 | # changed 29 | • Arrays inside arrays are now allowed `foo[bar[1]]` 30 | -------------------------------------------------------------------------------- /Preferences/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | name 5 | Comments 6 | scope 7 | source.gdl 8 | settings 9 | 10 | shellVariables 11 | 12 | 13 | name 14 | TM_COMMENT_START 15 | value 16 | ! 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Preferences/Completion Rules.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | source.gdl 6 | settings 7 | 8 | cancelCompletion 9 | (?i)(\s*(Return|Endwhile|Next|Gosub)) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Preferences/GDL.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.gdl", 3 | "completions": [ 4 | /* only Globals are all upper case 5 | (like mentioned in the official GS docs) 6 | */ 7 | 8 | /* A A A A A A A A A A A A A A A A A A A A A A A A A A A */ 9 | { "trigger": "abs", "contents": "abs(${1:x})" }, 10 | { "trigger": "acs", "contents": "acs(${1:x})" }, 11 | { "trigger": "add", "contents": "add ${1:x}, ${2:y}, ${3:z}" }, 12 | { "trigger": "add2", "contents": "add2 ${1:x}, ${2:y}" }, 13 | { "trigger": "addgroup", "contents": "addgroup (\"${1:g_expr1}\", \"${2:g_expr2}\")" }, 14 | { "trigger": "addgroup{2}", "contents": "addgroup{2} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialId}, ${5:materialColor})" }, 15 | { "trigger": "addgroup{3}", "contents": "addgroup{3} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialId}, ${5:materialColor})" }, 16 | "additional_data", 17 | { "trigger": "addX", "contents": "addx ${1:x}" }, 18 | { "trigger": "addY", "contents": "addy ${1:y}" }, 19 | { "trigger": "addZ", "contents": "addz ${1:z}" }, 20 | "all", 21 | "and", 22 | { "trigger": "application_query", "contents": "application_query (${1:values})" }, 23 | { "trigger": "arc", "contents": "arc ${1:r}, ${2:alpha}, ${3:beta}" }, 24 | { "trigger": "arc2", "contents": "arc2 ${1:x}, ${2:y}, ${3:r}, ${4:alpha}, ${5:beta}" }, 25 | { "trigger": "armc", "contents": "armc ${1:r1}, ${2:r2}, ${3:l}, ${4:h}, ${5:d}, ${6:alpha}" }, 26 | { "trigger": "arme", "contents": "arme ${1:l}, ${2:r1}, ${3:r2}, ${4:h}, ${5:d}" }, 27 | { "trigger": "asn", "contents": "asn(${1:x})" }, 28 | { "trigger": "atn", "contents": "atn(${1:x})" }, 29 | "auto", 30 | 31 | /* B B B B B B B B B B B B B B B B B B B B B B B B B B B */ 32 | "base", 33 | "beam", 34 | "beams", 35 | { "trigger": "binary", "contents": "binary(${1:mode})" }, 36 | "binaryprop", 37 | { "trigger": "bitset", "contents": "bitset(${1:x}, ${2:b})" }, 38 | { "trigger": "bittest", "contents": "bittest(${1:x}, ${2:b})" }, 39 | { "trigger": "block", "contents": "block ${1:width}, ${2:depth}, ${3:height}" }, 40 | { "trigger": "body", "contents": "body ${1:status}" }, 41 | "bprism_", 42 | "breakpoint", 43 | { "trigger": "brick", "contents": "brick ${1:width}, ${2:depth}, ${3:height}" }, 44 | "bwall_", 45 | 46 | /* C C C C C C C C C C C C C C C C C C C C C C C C C C C */ 47 | "call", 48 | { "trigger": "ceil", "contents": "ceil(${1:x})" }, 49 | { "trigger": "circle", "contents": "circle ${1:r}" }, 50 | { "trigger": "circle2", "contents": "circle2 ${1:x}, ${2:y}, ${3:r}" }, 51 | { "trigger": "close", "contents": "close ${1:channel}" }, 52 | "columns", 53 | "component", 54 | { "trigger": "cone", "contents": "cone ${1:height}, ${2:rad_bottom}, ${3:rad_top}, ${4:angle_bottom}, ${5:angle_top}" }, 55 | "coons", 56 | "coor{3}", 57 | { "trigger": "cos", "contents": "cos(${1:x})" }, 58 | { "trigger": "Create Group with Material", "contents": "creategroupwithmaterial (\"${1:g_expr}\", ${2:replace directive}, ${3:pen}, ${4:material})" }, 59 | "cprism_", 60 | "cprism_{2}", 61 | "cprism_{3}", 62 | "cprism_{4}", 63 | "croof_", 64 | "croof_{2}", 65 | "croof_{3}", 66 | "cslab_", 67 | "custom", 68 | "cutform", 69 | "cutform{2}", 70 | { "trigger": "cutplane", "contents": "cutplane ${1:angle}" }, 71 | "cutplane{3}", 72 | "cutpoly", 73 | "cutpolya", 74 | "cutshape", 75 | "cwall_", 76 | { "trigger": "cylind", "contents": "cylind ${1:h}, ${2:r}" }, 77 | 78 | /* D D D D D D D D D D D D D D D D D D D D D D D D D D D */ 79 | "database_set", 80 | "define empty_fill", 81 | "define fill", 82 | "define image_fill", 83 | "define line_type", 84 | "define linear_gradient_fill", 85 | "define material", 86 | "define material based_on", 87 | "define radial_gradient_fill", 88 | "define solid_fill", 89 | "define style", 90 | "define style{2}", 91 | "define symbol_fill", 92 | "define symbol_line", 93 | "define texture", 94 | "define translucent_fill", 95 | { "trigger": "del", "contents": "del ${1:n}" }, 96 | { "trigger": "deleted_par_value", "contents": "deleted_par_value (${1:oldparname}, ${1:outputvalue})" }, 97 | { "trigger": "descriptor", "contents": "descriptor ${1:name}" }, 98 | "dialog", 99 | { "trigger": "dict", "contents": "dict ${1:dictname}" }, 100 | "dim", 101 | "doors", 102 | { "trigger": "drawindex", "contents": "drawindex ${1:number: 10 20 30 40 50}" }, 103 | "drawing", 104 | "drawing2", 105 | "drawing3", 106 | "drawing3{2}", 107 | "drawing3{3}", 108 | 109 | /* E E E E E E E E E E E E E E E E E E E E E E E E E E E */ 110 | { "trigger": "edge", "contents": "edge ${1:vert1}, ${2:vert2}, ${3:pgon1}, ${4:pgon2}, ${5:status}" }, 111 | { "trigger": "elbow", "contents": "elbow ${1:radius_of_elbow}, ${2:angle}, ${3:radius_of_cross-section}" }, 112 | { "trigger": "ellips", "contents": "ellips ${1:h}, ${2:r}" }, 113 | "else", 114 | "end", 115 | "endgroup", 116 | "exit", 117 | "exor", 118 | { "trigger": "exp", "contents": "exp(${1:x})" }, 119 | "extrude", 120 | "extrudedshell", 121 | "extrudedshell{2}", 122 | "extrudedshell{3}", 123 | 124 | /* F F F F F F F F F F F F F F F F F F F F F F F F F F F */ 125 | { "trigger": "file_dependence", "contents": "file_dependence \"${1:name}\"" }, 126 | { "trigger": "fill", "contents": "fill ${1:name or index}" }, 127 | "filltypes_mask", 128 | { "trigger": "for … to … step … next", "contents": "for ${1:variable} = ${2:initial_value} to ${3:end_value} step ${4:step_value}\n\t${5:!statement}\nnext ${1:variable}\n" }, 129 | "fprism_", 130 | { "trigger": "fra", "contents": "fra(${1:x})" }, 131 | { "trigger": "fragment2", "contents": "fragment2 ${1:index}, ${2:use_current_attributes_flag}" }, 132 | "fullpath", 133 | 134 | /* G G G G G G G G G G G G G G G G G G G G G G G G G G G */ 135 | "GLOB_CONTEXT", 136 | "GLOB_CSTORY_ELEV", 137 | "GLOB_CSTORY_HEIGHT", 138 | "GLOB_CH_STORY_DIST", 139 | "GLOB_ELEVATION", 140 | "GLOB_EYEPOS_X", 141 | "GLOB_EYEPOS_Y", 142 | "GLOB_EYEPOS_Z", 143 | "GLOB_FEEDBACK_MODE", 144 | "GLOB_FIRST_FRAME", 145 | "GLOB_FRAME_NR", 146 | "GLOB_HSTORY_ELEV", 147 | "GLOB_HSTORY_HEIGHT", 148 | "GLOB_LAST_FRAME", 149 | "GLOB_MODPAR_NAME", 150 | "GLOB_NORTH_DIR", 151 | "GLOB_PREVIEW_MODE", 152 | "GLOB_SEO_TOOL_MODE", 153 | "GLOB_SCALE", 154 | "GLOB_SCRIPT_TYPE", 155 | "GLOB_TARGPOS_X", 156 | "GLOB_TARGPOS_Y", 157 | "GLOB_TARGPOS_Z", 158 | "GLOB_VIEW_TYPE", 159 | { "trigger": "gosub", "contents": "gosub ${1:number or \"text\"}" }, 160 | "goto", 161 | { "trigger": "group", "contents": "group \"${1:name}\"\n\t${2:!statment}\nendgroup\n" }, 162 | 163 | /* H H H H H H H H H H H H H H H H H H H H H H H H H H H */ 164 | "hatches", 165 | { "trigger": "haskey", "contents": "haskey(${1:dictionary.key})" }, 166 | { "trigger": "hideparameter", "contents": "hideparameter \"${1:name}\"" }, 167 | { "trigger": "hotarc", "contents": "hotarc ${1:r}, ${2:alpha}, ${3:beta}, ${4:unID}" }, 168 | { "trigger": "hotarc2", "contents": "hotarc2 ${1:x}, ${2:y}, ${3:r}, ${4:startangle}, ${5:endangle}, ${6:unID}" }, 169 | { "trigger": "hotline", "contents": "hotline ${1:x1}, ${2:y1}, ${3:z1}, ${4:x2}, ${5:y2}, ${6:z2}, ${7:unID}" }, 170 | { "trigger": "hotline2", "contents": "hotline2 ${1:x1}, ${2:y1}, ${3:x2}, ${5:y2}, ${6:unID}" }, 171 | { "trigger": "hotspot", "contents": "hotspot ${1:x}, ${2:y}, ${3:z}, ${4:unID}" }, 172 | { "trigger": "hotspot2", "contents": "hotspot2 ${1:x}, ${2:y}, ${3:unID}" }, 173 | "hprism_", 174 | 175 | /* I I I I I I I I I I I I I I I I I I I I I I I I I I I */ 176 | { "trigger": "if … then … else", "contents": "if ${1:condition} then\n\t${2:! statement1}\nelse\n\t${3:! statement2}\nendif\n" }, 177 | { "trigger": "if … then", "contents": "if ${1:condition} then\n\t${2:! statement}\nendif\n" }, 178 | { "trigger": "if … then gosub", "contents": "if ${1:condition} then\n\tgosub ${2:number or \"text\"}\nendif\n" }, 179 | { "trigger": "ind", "contents": "ind(${1:type}, ${2:name})" }, 180 | "initaddonscope input", 181 | { "trigger": "input", "contents": "input (${1:channel}, ${2:recordID}, ${3:fieldID}, ${4:variable})" }, 182 | { "trigger": "int", "contents": "int(${1:x})" }, 183 | { "trigger": "isectgroup", "contents": "isectgroup (\"${1:g_expr1}\", \"${2:g_expr2}\")" }, 184 | { "trigger": "isectgroup{2}", "contents": "isectgroup{2} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialId}, ${5:materialColor})" }, 185 | { "trigger": "isectgroup{3}", "contents": "isectgroup{3} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialId}, ${5:materialColor})" }, 186 | { "trigger": "isectlines", "contents": "isectlines (\"${1:g_expr1}\", \"${2:g_expr2}\")" }, 187 | 188 | /* K K K K K K K K K K K K K K K K K K K K K K K K K K K */ 189 | { "trigger": "killgroup", "contents": "killgroup \"${1:g_expr}\"" }, 190 | 191 | /* L L L L L L L L L L L L L L L L L L L L L L L L L L L */ 192 | { "trigger": "Label (subroutine) … RETURN", "contents": "${1:Label integer or \"name\"}:\n\t${2:! do your thing}\nreturn\n" }, 193 | { "trigger": "lgt", "contents": "lgt(${1:x})" }, 194 | { "trigger": "libraryglobal", "contents": "libraryglobal (${1:object_name}, ${2:parameter}, ${3:value})" }, 195 | { "trigger": "light", "contents": "light ${1:red}, ${2:green}, ${3:blue}, ${4:shadow},\n\t\t${5:radius}, ${6:alpha}, ${7:beta}, ${8:angle_falloff},\n\t\t${9:distance1}, ${10:distance2}, ${11:distance_falloff}" }, 196 | "lights", 197 | { "trigger": "lin_", "contents": "lin_ ${1:x1}, ${2:y1}, ${3:z1}, ${4:x2}, ${5:y2}, ${6:z2}" }, 198 | { "trigger": "line_property", "contents": "line_property ${1:expr}" }, 199 | { "trigger": "line_type", "contents": "line_type ${1:name or index}" }, 200 | { "trigger": "line2", "contents": "line2 ${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}" }, 201 | { "trigger": "lock", "contents": "lock \"${1:name}\"" }, 202 | { "trigger": "log", "contents": "log(${1:x})" }, 203 | 204 | /* M M M M M M M M M M M M M M M M M M M M M M M M M M M */ 205 | "mass", 206 | "mass{2}", 207 | { "trigger": "material", "contents": "material ${1:name or index}" }, 208 | { "trigger": "building_material", "contents": "building_material ${1:name or index}" }, 209 | { "trigger": "max", "contents": "max(${1:x1}, ${2:x2})" }, 210 | "mesh", 211 | "meshes", 212 | "migrationwarning", 213 | { "trigger": "min", "contents": "min(${1:x1}, ${2:x2})" }, 214 | "mode", 215 | "model", 216 | { "trigger": "mul", "contents": "mul ${1:mx}, ${2:my}, ${3:mz}" }, 217 | { "trigger": "mul2", "contents": "mul2 ${1:mx}, ${2:my}" }, 218 | { "trigger": "mulx", "contents": "mulx ${1:mx}" }, 219 | { "trigger": "muly", "contents": "muly ${1:my}" }, 220 | { "trigger": "mulz", "contents": "mulz ${1:mz}" }, 221 | 222 | /* N N N N N N N N N N N N N N N N N N N N N N N N N N N */ 223 | { "trigger": "newparameter", "contents": "newparameter ${1:name}, ${2:type}" }, 224 | { "trigger": "not", "contents": "not(${1:x})" }, 225 | "nsp", 226 | { "trigger": "ntr", "contents": "ntr()" }, 227 | 228 | /* O O O O O O O O O O O O O O O O O O O O O O O O O O O */ 229 | "objects", 230 | { "trigger": "open", "contents": "open (${1:filter}, ${2:filename}, ${3:parameter})" }, 231 | { "trigger": "output", "contents": "output ${1:channel}, ${2:recordID}, ${3:fieldID}, ${4:expression}" }, 232 | 233 | /* P P P P P P P P P P P P P P P P P P P P P P P P P P P */ 234 | { "trigger": "paragraph", "contents": "paragraph ${1:values}\nendparagraph" }, 235 | "parameters", 236 | { "trigger": "parvalue_description", "contents": "parvalue_description (${1:parname})" }, 237 | { "trigger": "pen", "contents": "pen ${1:n}" }, 238 | { "trigger": "pgon", "contents": "pgon ${1:n}, ${2:vect}, ${3:status}, ${4:edge1}, ${5:edge2}" }, 239 | { "trigger": "pgon{2}", "contents": "pgon{2} ${1:n}, ${2:vect}, ${3:status}, ${4:wrap}, ${5:edge_or_wrap1}" }, 240 | { "trigger": "pgon{3}", "contents": "pgon{3} ${1:n}, ${2:vect}, ${3:status}, ${4:wrap_method}, ${5:wrap_flags}, ${6:edge_or_wrap1}" }, 241 | { "trigger": "picture", "contents": "picture ${1:expression}, ${2:a}, ${3:b}, ${4:mask}" }, 242 | { "trigger": "picture2", "contents": "picture2 ${1:expression}, ${2:a}, ${3:b}, ${4:mask}" }, 243 | { "trigger": "picture2{2}", "contents": "picture2{2} ${1:expression}, ${2:a}, ${3:b}, ${4:mask}" }, 244 | "pipg", 245 | "pitched_roofs", 246 | { "trigger": "placegroup", "contents": "placegroup ${1:g_expr}" }, 247 | { "trigger": "plane", "contents": "plane ${1:n}, ${2:x1}, ${3:y1}, ${4:z1}" }, 248 | { "trigger": "plane_", "contents": "plane_ ${1:n}, ${2:x1}, ${3:y1}, ${4:z1}, ${4:s1}" }, 249 | { "trigger": "pointcloud", "contents": "pointcloud \"${1:data_file_name}\"" }, 250 | "poly", 251 | "poly_", 252 | "poly2", 253 | "poly2_", 254 | "poly2_a", 255 | "poly2_b", 256 | "poly2_b{2}", 257 | "poly2_b{3}", 258 | "poly2_b{4}", 259 | "poly2_b{5}", 260 | "poly2_b{6}", 261 | "polyroof", 262 | "polyroof{3}", 263 | { "trigger": "position", "contents": "position ${1:position_keyword}" }, 264 | { "trigger": "preparefunction", "contents": "preparefunction ${1:channel}, ${2:function_name}, ${3:expression1}" }, 265 | { "trigger": "print", "contents": "print ${1:expression}" }, 266 | "prism", 267 | "prism_", 268 | "profiletypes_mask", 269 | { "trigger": "project2", "contents": "project2 ${1:projection_code}, ${2:angle}, ${3:method}" }, 270 | { "trigger": "project2{2}", "contents": "project2{2} ${1:projection_code}, ${2:angle}, ${3:method}" }, 271 | { "trigger": "project2{3}", "contents": "project2{3} ${1:projection_code}, ${2:angle}, ${3:method}, ${4:parts}" }, 272 | "project2{4}", 273 | { "trigger": "put", "contents": "put ${1:expression}" }, 274 | "pyramid", 275 | 276 | /* R R R R R R R R R R R R R R R R R R R R R R R R R R R */ 277 | { "trigger": "radius", "contents": "radius ${1:radius_min}, ${2:radius_max}" }, 278 | "range", 279 | { "trigger": "rect", "contents": "rect ${1:a}, ${2:b}" }, 280 | { "trigger": "rect2", "contents": "rect2 ${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}" }, 281 | { "trigger": "ref component", "contents": "ref component ${1:code}" }, 282 | { "trigger": "ref descriptor", "contents": "ref descriptor ${1:code}" }, 283 | { "trigger": "removekey", "contents": "removekey(${1:dictionary.key})" }, 284 | { "trigger": "repeat … until", "contents": "repeat\n\t${2:! do something}\nuntil ${3:condition}" }, 285 | { "trigger": "req", "contents": "req(${1:parameter_string})" }, 286 | { "trigger": "request", "contents": "request(${1:question_name}, ${2:name})" }, 287 | { "trigger": "request{2}", "contents": "request{2}(${1:question_name}, ${2:name_or_index}, ${3:name})" }, 288 | { "trigger": "request{3}", "contents": "request{3}(${1:question_name}, ${2:name_or_index_array})" }, 289 | { "trigger": "request{4}", "contents": "request{4}(${1:question_name}, ${2:name_or_index}, ${3:index}, ${4:name})" }, 290 | { "trigger": "resol", "contents": "resol ${1:n}" }, 291 | "return", 292 | "returned_parameters", 293 | "revolve", 294 | "revolve{2}", 295 | "revolve{3}", 296 | "revolve{4}", 297 | "revolve{5}", 298 | "revolvedshell", 299 | "revolvedshell{2}", 300 | "revolvedshell{3}", 301 | "revolvedshellangular", 302 | "revolvedshellangular{2}", 303 | "revolvedshellangular{3}", 304 | { "trigger": "richtext", "contents": "richtext ${1:x}, ${2:y}, ${3:height}, ${4:0}, \"${5:textblock_name}\"" }, 305 | { "trigger": "richtext2", "contents": "richtext2 ${1:x}, ${2:y}, \"${3:textblock_name}\"" }, 306 | { "trigger": "rnd", "contents": "rnd(${1:x})" }, 307 | "rooms", 308 | { "trigger": "rot", "contents": "rot ${1:x}, ${2:y}, ${3:z}, ${4:alpha}" }, 309 | { "trigger": "rot2", "contents": "rot2 ${1:alpha}" }, 310 | { "trigger": "rotX", "contents": "rotx ${1:alphaX}" }, 311 | { "trigger": "rotY", "contents": "roty ${1:alphaY}" }, 312 | { "trigger": "rotZ", "contents": "rotz ${1:alphaZ}" }, 313 | { "trigger": "round_int", "contents": "round_int(${1:x})" }, 314 | "ruled", 315 | "ruled{2}", 316 | "ruledsegmented", 317 | "ruledshell", 318 | "ruledshell{2}", 319 | "ruledshell{3}", 320 | 321 | /* S S S S S S S S S S S S S S S S S S S S S S S S S S S */ 322 | { "trigger": "sect_attrs", "contents": "sect_attrs ${1:fill}, ${2:fill_background_pen}, ${3:fill_pen}, ${4:contour_pen}" }, 323 | { "trigger": "sect_attrs{2}", "contents": "sect_attrs{2} ${1:contour_pen}" }, 324 | { "trigger": "sect_fill", "contents": "sect_fill ${1:fill}, ${2:fill_background_pen}, ${3:fill_pen}, ${4:contour_pen}" }, 325 | "separator", 326 | { "trigger": "Set Migration GUID", "contents": "setmigrationguid ${1:guid}" }, 327 | { "trigger": "sgn", "contents": "sgn(${1:x})" }, 328 | { "trigger": "shadow", "contents": "shadow ${1:casting}" }, 329 | { "trigger": "sin", "contents": "sin(${1:x})" }, 330 | "slab", 331 | "slab_", 332 | "solid", 333 | { "trigger": "sphere", "contents": "sphere ${1:r}" }, 334 | "spline2", 335 | "spline2A", 336 | { "trigger": "split", "contents": "split(${1:string}, ${2:format}, ${3:variable1})" }, 337 | "sprism_", 338 | "sprism_{2}", 339 | "sprism_{3}", 340 | "sprism_{4}", 341 | { "trigger": "sqr", "contents": "sqr(${1:x})" }, 342 | "step", 343 | { "trigger": "stored_par_value", "contents": "stored_par_value (${1:oldparname}, ${1:outputvalue})" }, 344 | { "trigger": "str", "contents": "str(${1:numeric_expression}, ${2:length}, ${3:fractions})" }, 345 | { "trigger": "str{2}", "contents": "str{2}(${1:format_string}, ${2:numeric_expression})" }, 346 | { "trigger": "strlen", "contents": "strlen(${1:string_expression})" }, 347 | { "trigger": "strstr", "contents": "strstr(${1:base_string}, ${2:string_to_look_for})" }, 348 | { "trigger": "strsub", "contents": "strsub(${1:string_expression}, ${2:start_pos}, ${3:char_number})" }, 349 | { "trigger": "str to lower", "contents": "strtolower(${1:string_expression})" }, 350 | { "trigger": "STR TO UPPER", "contents": "strtoupper(${1:string_expression})" }, 351 | { "trigger": "stw", "contents": "stw(${1:string_expression})" }, 352 | { "trigger": "style", "contents": "style ${1:name or index}" }, 353 | { "trigger": "subgroup", "contents": "subgroup (\"${1:g_expr1}\", \"${2:g_expr2}\")" }, 354 | { "trigger": "subgroup{2}", "contents": "subgroup{2} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialID}, ${5:materialColor})" }, 355 | { "trigger": "subgroup{3}", "contents": "subgroup{3} (\"${1:g_expr1}\", \"${2:g_expr2}\", ${3:edgeColor}, ${4:materialID}, ${5:materialColor})" }, 356 | "surface", 357 | "surface3d", 358 | "SMYB_MAT", 359 | "SYMB_MIRRORED", 360 | "SYMB_ROTANGLE", 361 | "SYMB_POS_X", 362 | "SYMB_POS_Y", 363 | "SYMB_POS_Z", 364 | "SYMB_VIEW_PEN", 365 | "sweep", 366 | { "trigger": "sweepgroup", "contents": "sweepgroup (\"${1:g_expr}\", ${2:x}, ${3:y}, ${4:z})" }, 367 | { "trigger": "sweepgroup{2}", "contents": "sweepgroup{2} (\"${1:g_expr}\", ${2:x}, ${3:y}, ${4:z})" }, 368 | { "trigger": "sweepgroup{3}", "contents": "sweepgroup{3} (\"${1:g_expr}\", ${2:x}, ${3:y}, ${4:z}, ${5:edgeColor}, ${6:materialID}, ${7:materialColor}, ${8:method})" }, 369 | { "trigger": "sweepgroup{4}", "contents": "sweepgroup{4} (\"${1:g_expr}\", ${2:x}, ${3:y}, ${4:z}, ${5:edgeColor}, ${6:materialID}, ${7:materialColor}, ${8:method}, ${9:status})" }, 370 | 371 | /* T T T T T T T T T T T T T T T T T T T T T T T T T T T */ 372 | { "trigger": "tan", "contents": "tan(${1:x})" }, 373 | { "trigger": "teve", "contents": "teve ${1:x}, ${2:y}, ${3:z}, ${4:u}, ${5:v}" }, 374 | { "trigger": "text", "contents": "text ${1:d}, ${2:0}, ${3:expression}" }, 375 | { "trigger": "text2", "contents": "text2 ${1:x}, ${2:y}, ${3:expression}" }, 376 | { "trigger": "textblock", "contents": "textblock \"${1:name}\" ${2:width}, ${3:anchor}, ${4:angle}, ${5:width_factor}, ${6:charspace_factor}, ${7:fixed_height},\n\t\t\"${8:paragraph_name}\"" }, 377 | { "trigger": "toler", "contents": "toler ${1:digit}" }, 378 | "tube", 379 | "tubea", 380 | "tube{2}", 381 | 382 | /* U U U U U U U U U U U U U U U U U U U U U U U U U U U */ 383 | { "trigger": "ui_button", "contents": "ui_button ${1:type}, ${2:text}, ${3:x}, ${4:y}, ${5:width}, ${6:height}, ${7:id}" }, 384 | "ui_cancel", 385 | { "trigger": "ui_colorpicker", "contents": "ui_colorpicker \"${1:redParamName}\", \"${2:greenParamName}\", \"${3:blueParamName}\", ${4:x}, ${5:y}, ${6:width}, ${6:height}" }, 386 | { "trigger": "ui_colorpicker{2}", "contents": "ui_colorpicker{2} ${1:redParamName}, ${2:greenParamName}, ${3:blueParamName}, ${4:x}, ${5:y}, ${6:width}, ${6:height}" }, 387 | { "trigger": "ui_current_page", "contents": "ui_current_page ${1:index}" }, 388 | { "trigger": "ui_custom_popup_infield", "contents": "ui_custom_popup_infield \"${1:name}\", ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 389 | { "trigger": "ui_custom_popup_infield{2}", "contents": "ui_custom_popup_infield{2} ${1:name}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 390 | { "trigger": "ui_custom_popup_listitem", "contents": "ui_custom_popup_listitem ${1:itemID}, ${2:fieldID}, \"${3:name}\", ${4:childFlag}, ${5:image}, ${6:paramDesc}" }, 391 | { "trigger": "ui_custom_popup_listitem{2}", "contents": "ui_custom_popup_listitem{2} ${1:itemID}, ${2:fieldID}, ${3:name}, ${4:childFlag}, ${5:image}, ${6:paramDesc}" }, 392 | { "trigger": "ui_dialog", "contents": "ui_dialog ${1:title}" }, 393 | "ui_function", 394 | { "trigger": "ui_groupbox", "contents": "ui_groupbox ${1:text}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 395 | { "trigger": "ui_infield", "contents": "ui_infield \"${1:name}\", ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 396 | { "trigger": "ui_infield{2}", "contents": "ui_infield{2} ${1:name}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 397 | { "trigger": "ui_infield{3}", "contents": "ui_infield{3} ${1:name}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 398 | { "trigger": "ui_infield{4}", "contents": "ui_infield{4} \"${1:name}\", ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 399 | "ui_link", 400 | { "trigger": "ui_listfield", "contents": "ui_listfield ${1:fieldID}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 401 | { "trigger": "ui_listitem", "contents": "ui_listitem ${1:itemdID}, ${2:fieldID}, \"${3:name}\"" }, 402 | { "trigger": "ui_listitem{2}", "contents": "ui_listitem{2} ${1:itemdID}, ${2:fieldID}, \"${3:name}\"" }, 403 | "ui_next", 404 | "ui_ok", 405 | { "trigger": "ui_outfield", "contents": "ui_outfield ${1:expression}, ${2:x}, ${3:y}, ${4:width}, ${5:height}, ${6:flags}" }, 406 | { "trigger": "ui_page", "contents": "ui_page ${1:page_number}" }, 407 | { "trigger": "ui_pict", "contents": "ui_pict ${1:expression}, ${2:x}, ${3:y}, ${4:width}, ${5:height}" }, 408 | { "trigger": "ui_pict_button", "contents": "ui_pict_button ${1:type}, ${2:text}, ${3:picture_reference}, ${4:x}, ${5:y}, ${6:width}, ${7:height}" }, 409 | { "trigger": "ui_pict_pushcheckbutton", "contents": "ui_pict_pushcheckbutton ${1:name}, ${2:text}, ${3:picture_reference}, ${4:frame_flag}, ${5:x}, ${6:y}, ${7:width}, ${8:height}" }, 410 | { "trigger": "ui_pict_pushcheckbutton{2}", "contents": "ui_pict_pushcheckbutton{2} \"${1:name}\", ${2:text}, ${3:picture_reference}, ${4:frame_flag}, ${5:x}, ${6:y}, ${7:width}, ${8:height}" }, 411 | { "trigger": "ui_radiobutton", "contents": "ui_radiobutton ${1:name}, ${2:value}, ${3:text}, ${4:x}, ${5:y}, ${6:width}, ${7:height}" }, 412 | { "trigger": "ui_radiobutton{2}", "contents": "ui_radiobutton{2} \"${1:name}\", ${2:value}, ${3:text}, ${4:x}, ${5:y}, ${6:width}, ${7:height}" }, 413 | "ui_prev", 414 | { "trigger": "ui_separator", "contents": "ui_separator ${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}" }, 415 | { "trigger": "ui_slider", "contents": "ui_slider \"${1:name}\", ${2:x0}, ${3:y0}, ${4:width}, ${5:height}" }, 416 | { "trigger": "ui_slider{2}", "contents": "ui_slider{2} ${1:name}, ${2:x0}, ${3:y0}, ${4:width}, ${5:height}" }, 417 | { "trigger": "ui_style", "contents": "ui_style ${1:fontsize}, ${2:face_code}" }, 418 | { "trigger": "ui_textstyle_infield", "contents": "ui_textstyle_infield ${1:name}, ${2:faceCodeMask}, ${3:x}, ${4:y}, ${5:button width}, ${6:button height}" }, 419 | { "trigger": "ui_textstyle_infield{2}", "contents": "ui_textstyle_infield{2} \"${1:name}\", ${2:faceCodeMask}, ${3:x}, ${4:y}, ${5:button width}, ${6:button height}" }, 420 | { "trigger": "ui_tooltip", "contents": "ui_tooltip ${1:tooltiptext}" }, 421 | "until", 422 | "use", 423 | 424 | /* V V V V V V V V V V V V V V V V V V V V V V V V V V V */ 425 | { "trigger": "values", "contents": "values \"${1:parameter_name}\"" }, 426 | { "trigger": "values{2}", "contents": "values{2} \"${1:parameter_name}\"" }, 427 | { "trigger": "vardim1", "contents": "vardim1(${1:expression})" }, 428 | { "trigger": "vardim2", "contents": "vardim2(${1:expression})" }, 429 | { "trigger": "vartype", "contents": "vartype(${1:expression})" }, 430 | { "trigger": "vect", "contents": "vect ${1:x}, ${2:y}, ${3:z}" }, 431 | { "trigger": "vert", "contents": "vert ${1:x}, ${2:y}, ${3:z}, ${4:hard}" }, 432 | "volume3d", 433 | 434 | /* W W W W W W W W W W W W W W W W W W W W W W W W W W W */ 435 | { "trigger": "wallarc2", "contents": "wallarc2 ${1:x}, ${2:y}, ${3:r}, ${4:alpha}, ${5:beta}" }, 436 | "wallblock2", 437 | "wallblock2{2}", 438 | "WALL_FILL", 439 | "WALL_FILL_PEN", 440 | "WALL_HEIGHT", 441 | "wallhole", 442 | "wallhole2", 443 | "wallhole2{2}", 444 | { "trigger": "wallline2", "contents": "wallline2 ${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}" }, 445 | "WALL_MAT_A", 446 | "WALL_MAT_B", 447 | "WALL_MAT_EDGE", 448 | "wallniche", 449 | "WALL_THICKNESS", 450 | "walls", 451 | "WALL_RESOL", 452 | "WALL_SECT_PEN", 453 | { "trigger": "while … do", "contents": "while ${1:condition} do\n\t${2:! statement}\nendwhile" }, 454 | "WIDO_FRAME_THICKNESS", 455 | "WIDO_HEAD_DEPTH", 456 | "WIDO_ORIG_DIST", 457 | "WIDO_POSITION", 458 | "WIDO_REVEAL_SIDE", 459 | "WIDO_RIGHT_JAMB", 460 | "WIDO_SILL", 461 | "WIDO_THRES_DEPTH", 462 | "windows", 463 | "wire", 464 | 465 | /* XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ */ 466 | { "trigger": "xform", "contents": "xform ${1:1}, ${2:0}, ${3:0}, ${4:0},\n\t\t${5:0}, ${6:1}, ${7:0}, ${8:0},\n\t\t${9:0}, ${10:0}, ${11:1}, ${12:0}" }, 467 | "xwall_", 468 | "xwall_{2}", 469 | "xwall_{3}", 470 | 471 | "zzyzx" 472 | ] 473 | } -------------------------------------------------------------------------------- /Preferences/Miscellaneous.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | name 5 | Miscellaneous 6 | scope 7 | source.gdl 8 | settings 9 | 10 | decreaseIndentPattern 11 | (?i)(^\s*(End|Endif|Else|Return|Next|Endwhile|Until|Endgroup)) 12 | increaseIndentPattern 13 | (?i)(^\s*(If)\b.*\sThen$)|(^\s*(Else)\s*$)|(^\s*(For|Do|While|Repeat|Group)\b.*$)|(([0-9]+|(")[a-z_]+(")):) 14 | shellVariables 15 | 16 | 17 | name 18 | TM_COMMENT_START 19 | value 20 | ! 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Preferences/Symbol Index Global.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | name 5 | Symbol List - Variables 6 | scope 7 | source.gdl entity.name.function 8 | settings 9 | 10 | showInIndexedSymbolList 11 | 1 12 | symbolIndexTransformation 13 | s/"(\w+)"/$1/; 14 | 15 | 16 | -------------------------------------------------------------------------------- /Preferences/Symbol Index.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | name 5 | Symbol List - Variables 6 | scope 7 | source.gdl entity.name.function 8 | settings 9 | 10 | showInSymbolList 11 | 1 12 | symbolTransformation 13 | s/"(\w+)"/$1/; 14 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | # [GDL-sublime](https://github.com/runxel/GDL-sublime) 6 | 7 | > A bundle to make GDL available in [Sublime Text](http://www.sublimetext.com/). 8 | 9 | [![Version](https://img.shields.io/github/release/runxel/GDL-sublime.svg?style=flat-square)](https://github.com/runxel/GDL-sublime/releases/latest) 10 | [![Downloads](https://img.shields.io/packagecontrol/dt/GDL?logo=sublime%20text&style=flat-square)](https://packagecontrol.io/packages/GDL) 11 | [![Discord](https://img.shields.io/discord/700328186642432040?color=738ad6&label=Join%20the%20Discord%20server&logo=discord&logoColor=ffffff)](https://discord.gg/6R4a5qQ) 12 | 13 |
14 | 15 | --- 16 | 17 | # What is GDL? 18 | GDL means 'Geometric Description Language'. [ArchiCAD](http://www.graphisoft.com/) uses it to define a library part. 19 | 20 | Many ArchiCAD users are making their own library parts, sell them or even publish them for free on sites like [BIMComponents](https://bimcomponents.com/), while others just want to modify the provided ones. But they are all tied to the – unfortunately horrible – built-in object editor which is stuck in the 80's or so. It doesn't even have line numbers! 21 | 22 | But salvation is here! 23 | The purpose of this package is to give you the chance to comfortably write code in[Sublime Text](https://www.sublimetext.com/). 24 | 25 | This package provides the whole thing: from **syntax highlighting** (with a well aligned **color schemes**) to **auto completion**, **global goto**, **snippets**, and last but not least a **build system** for your scripts. 26 | 27 | ## Installation 28 | 29 | ### Using Sublime Package Control 30 | :white_check_mark: _recommended_ 31 | If you are using [Sublime Package Control](http://wbond.net/sublime_packages/package_control), you can easily install the bundle via the `Sublime Text -> Preferences > Package Control: Install Package` menu item. 32 | 33 | ### Using Git 34 | :robot: Alternatively you can install the bundle and keep up to date by cloning the repo directly into your `Packages` directory in the Sublime Text application settings area. 35 | 36 | Go to your Sublime Text `Packages` directory and clone the repository using the command below: 37 | `git clone https://github.com/runxel/GDL-sublime "GDL"` 38 | 39 | ### Download Manually 40 | :arrow_down: _not recommended – you won't get updates!_ :rotating_light: 41 | - Download the files using the GitHub .zip download option 42 | - Unzip the files and rename the folder to 'GDL' 43 | - Copy the folder to your Sublime Text `Packages` directory i.e. 44 | - Windows `C:\Users\\AppData\Roaming\Sublime Text 3\Packages\GDL` 45 | - OS X: `~/Library/Application Support/Sublime Text 3/Packages/GDL` 46 | 47 | ## Usage 48 | From now on you can select `GDL` as the current language in the bottom right corner of ST and enjoy all the benefits. For files with the `.gdl` extension it will be automatically active. 49 | For the coloring (meaning the proper highlighting) there are two choices. By default a light color scheme will be applied. 50 | I personly like the dark coloring more, providing fatigue-proof coding. To change the use of a color scheme go to `Preferences > Package Settings > GDL > Settings`. 51 | 52 | Copy _one_ of these into the file on the right and save: 53 | 54 | #### **Dark:** 55 | ```json 56 | { 57 | "color_scheme": "Packages/GDL/GDL-dark.sublime-color-scheme" 58 | } 59 | ``` 60 | 61 | ![dark color scheme](https://i.imgur.com/OEurk9A.png) 62 | 63 | 64 | #### **Light:** 65 | ```json 66 | { 67 | "color_scheme": "Packages/GDL/GDL-light.sublime-color-scheme" 68 | } 69 | ``` 70 | 71 | ![light color scheme](https://i.imgur.com/OQx2IF2.png) 72 | 73 | 74 | #### Don't like the themes? 75 | You can edit the `.sublime-color-scheme` files directly – they are nothing else than `.json` files basically. But remember to copy your own color scheme into the `User` folder! Otherwise an update would overwrite your changes. (Of course you then need to point Sublime Text to your new color scheme like above.) 76 | 77 | ### GoTo, Auto completion, Snippets 78 | The "Goto" feature of Sublime Text is pretty powerful. To gain full access you must use [Sublime projects](#workflow). If you e.g. quickly want to got to a subroutine place your cursor into the name and press F12. You will then jump directly to the definition. 79 | Auto completion takes place automatically, if you're typing. You can force auto completion via ctrl + space. 80 | I have included some example snippets. Try it out by typing in: `comline` and then press TAB ↹. 81 | Voilá! There's a divider. 82 | `! ---------------------------------------------------------------------- !` 83 | 84 | I hardly encourage you to modify and extend the snippets, so they will suit your needs. 85 | You will find all the shipped snippets in the `Snippets` folder. 86 | 87 | ## Workflow 88 | With the advent of ARCHICAD 23 we don't longer need third-party apps like [GDLnucleus](http://www.opengdl.org/Default.aspx?tabid=9748) for a Sublime Text driven workflow. The **LP_XMLConverter**, which is part of every Archicad installation, can now convert `.gsm` directly into subsequent `.gdl` scripts and vice-versa. This means an end to the abundant copy & pasting orgy of the past. 89 | 90 | To use this feature you first need to set the path to where your ARCHICAD is installed. Open the package settings again and copy the respective item from the left to the right pane. Change the path accordingly. 91 | 92 | Afterwards drag and drop a folder with your 'gsm' (I recommend different folders for different gsm's) into Sublime Text and then create a Sublime project via `Project > Save Project As…`. Other benefits are a better working 'goto', 'auto completion', and the possibility to fast switch between different coding sessions on various gsm's. All the files inside the folder you just dragged into Sublime Text will be visible in the sidebar, and can also easily be accessed via the quick open palette. 93 | For all the possible ways to structure your folders see [below](#structure) 94 | 95 | You can now use the the two conversion options in `Tools > GDL`. For a quick access both items are reachable via a right mouse click on the editor pane. There are also key bindings on each. 96 | The default for `Convert to script (gsm → hsf/gdl)` is ctrl+shift+H. `Build GSM from HSF (hsf/gdl → gsm)` has ctrl+shift+alt+G assigned OOTB. Of course these can be adjusted to your taste. 97 | 98 | ### Places 99 | If you convert between [HSF](http://gdl.graphisoft.com/tips-and-tricks/hsf-source-format) and GSM the default place will be next to each other. However you can define a _global default path_ (see [example](#syntax-settings-example) below) where any GSMs should be deployed to. This is useful if you have a central library already linked in Archicad. 100 | Of course you can overwrite this behavior by having a path on _project basis_. This can be set by opening the corresponding `.sublime-project` file and adding: 101 | 102 | ```json 103 | { 104 | "cmdargs": 105 | { 106 | "proj_gsm_path": "C:/Users/runxel/gsm-dev" 107 | } 108 | } 109 | ``` 110 | 111 | If you substitute the path with `"default"` you can mimic the standard behavior: the GSM will be built next to the HSF. This is useful if you have set a global path in the package settings. Remember: **Project settings override global settings**. 112 | 113 | Note: There's no path checking implemented at the moment! You have to take care by yourself that you're allowed to write at the paths accordingly. 114 | 115 | #### Structure 116 | Let's have a look on how you can organize your folder structure! 117 | (Please note: the names are just examples.) 118 | 119 | The basic structure looks like this: 120 | ``` 121 | 122 | ├─ example object\.. # <- this is the HSF; the folder with the script parts 123 | └─ example object.gsm 124 | ``` 125 | Simple, right? 126 | 127 | But what if you deploy a nested folder structure, like below? In this case you can make use of the 'sub root' feature, which let's you dig into a nested structure (can be arbitrarily deep, but keep in mind you might run in the hard 255 path character limit of Windows). 128 | ``` 129 | 130 | ├─ .editorconfig 131 | ├─ README.md 132 | ├─ docs\.. 133 | ├─ images\.. 134 | └─ Objects\ 135 | ├─ Object-1\.. 136 | ├─ Object-2\.. 137 | └─ Object-3\ ## be sure that the outer AND 138 | ├─ Object-3\ ## the inner folder AND also 139 | │ └─ (all scripts) 140 | └─ Object-3.gsm ## the .gsm share exactly the same name! 141 | ``` 142 | What you can do is to declare a new 'root'. 143 | All you need to do is to put the following statement into your `.sublime-project` file: 144 | ```jsonc 145 | { 146 | "root": "Objects" 147 | // for deeper nesting use forward slashes: "Objects/deeper" 148 | } 149 | ``` 150 | You could even point to one of the objects directly to circumvent the selection dialog. 151 | 152 | Another and very comfortable way is to tell GDL-Sublime it should convert the current GDL being edited everytime you save the GDL: 153 | ```jsonc 154 | { 155 | "convert_on_save": true 156 | } 157 | ``` 158 | 159 | _Note: Multi root environments are not supported at the moment._ 160 | 161 | 162 | 163 | ### Syntax Settings Example: 164 | ```json 165 | { 166 | "AC_path": "C:/Program Files/GRAPHISOFT/ARCHICAD 23", 167 | "color_scheme": "Packages/GDL/GDL-dark.sublime-color-scheme", 168 | "global_gsm_path": "D:/office/aclibrary" 169 | } 170 | ``` 171 | 172 | The `AC_path` can be overwritten in your `.sublime-project` file. 173 | 174 | 192 | 193 | ## Support 194 | Does this plugin help you in your daily work, or you just want to say thanks? 195 | Countless hours went into the development of GDL-Sublime. 196 | Please consider donating to sustain working on this plugin! 197 | 198 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Y8Y5VOOM) 199 | 200 | 201 | -------------------------------------------------------------------------------- /Snippets/2D-Script.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | 2d 7 | 2D script comment block 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /Snippets/3D-Script.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | 3d 7 | 3D script comment block 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /Snippets/DynHotspotLinear.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | linh 8 | Dynamic Linear 2D Hotspot 9 | source.gdl 10 | 11 | -------------------------------------------------------------------------------- /Snippets/Master-Script.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | master 7 | Master script comment block 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /Snippets/Modpar.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | modpar 8 | IF GLOB_MODPAR_NAME ... 9 | source.gdl 10 | -------------------------------------------------------------------------------- /Snippets/Param-Angle.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | angle 9 | Angle (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Array.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | ${1:0} 5 | 6 | ]]> 7 | array 8 | Array inside a Param (Paramlist) 9 | text.xml 10 | -------------------------------------------------------------------------------- /Snippets/Param-BMat.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | bmat 9 | BMat (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Bool.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | bool 9 | Bool (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Dict.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ]]> 11 | dict 12 | Dict (Paramlist) 13 | text.xml 14 | -------------------------------------------------------------------------------- /Snippets/Param-FillPattern.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:64} 6 | 7 | ]]> 8 | fill 9 | FillPattern (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Hidden.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ]]> 7 | hidden 8 | Item is hidden (Paramlist) 9 | text.xml 10 | -------------------------------------------------------------------------------- /Snippets/Param-Integer.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | integer 9 | Integer (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Length.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | length 9 | Length (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-LineType.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:1} 6 | 7 | ]]> 8 | linetype 9 | LineType (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Pen.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:1} 6 | 7 | ]]> 8 | pen 9 | Pen (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Profile.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | profile 9 | Profile (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Real.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | real 9 | Real (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Seperator.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ]]> 7 | seperator 8 | Seperator (Paramlist) 9 | text.xml 10 | -------------------------------------------------------------------------------- /Snippets/Param-String.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | ]]> 8 | string 9 | String (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Surface.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ${3:0} 6 | 7 | ]]> 8 | surface 9 | Surface (Paramlist) 10 | text.xml 11 | -------------------------------------------------------------------------------- /Snippets/Param-Title.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | <Description><![CDATA["${2:title name}"]]${-1}></Description> 8 | 9 | ]]> 10 | title 11 | Title Block (Paramlist) 12 | text.xml 13 | -------------------------------------------------------------------------------- /Snippets/Parameter-Script.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | param 7 | Parameter script comment block 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /Snippets/Subroutine.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 9 | sub 10 | source.gdl 11 | 12 | -------------------------------------------------------------------------------- /Snippets/UI-Script.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | ui 7 | UI script comment block 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /Snippets/commentline.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | comline 6 | source.gdl 7 | 8 | 9 | -------------------------------------------------------------------------------- /Snippets/endmarker.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | end 9 | Big endmarker 10 | source.gdl 11 | 12 | -------------------------------------------------------------------------------- /Snippets/eps.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | eps 7 | eps = 0.0001 8 | source.gdl 9 | 10 | -------------------------------------------------------------------------------- /_logging.py: -------------------------------------------------------------------------------- 1 | # logger based on 2 | # Python docs 3 | 4 | import logging 5 | import sublime 6 | 7 | # usage in other files in package: 8 | # log = logging.getLogger(__name__) 9 | 10 | DEFAULT_LOG_LEVEL = logging.WARNING 11 | DEFAULT_LOG_LEVEL_NAME = logging.getLevelName(DEFAULT_LOG_LEVEL) 12 | EVENT_LEVEL = logging.INFO 13 | 14 | package_logger = logging.getLogger(__package__) 15 | handler = logging.StreamHandler() 16 | formatter = logging.Formatter(fmt="[{name}] {levelname}: {message}", style='{') 17 | handler.setFormatter(formatter) 18 | package_logger.addHandler(handler) 19 | package_logger.setLevel(DEFAULT_LOG_LEVEL) 20 | 21 | logger = logging.getLogger(__name__) 22 | 23 | 24 | def _settings(): 25 | # current log level setting is stored in here 26 | return sublime.load_settings("GDLDev.sublime-settings") 27 | 28 | 29 | def plugin_loaded(): 30 | def on_settings_reload(): 31 | cur_log_level = package_logger.getEffectiveLevel() 32 | cur_log_level_name = logging.getLevelName(cur_log_level) 33 | new_log_level_name = _settings().get('log_level', DEFAULT_LOG_LEVEL_NAME).upper() 34 | new_log_level = getattr(logging, new_log_level_name, DEFAULT_LOG_LEVEL) 35 | 36 | if new_log_level_name != cur_log_level_name: 37 | if cur_log_level > EVENT_LEVEL and new_log_level <= EVENT_LEVEL: 38 | # Only set level before emitting log event if it would not be seen otherwise 39 | package_logger.setLevel(new_log_level) 40 | logger.log(EVENT_LEVEL, 41 | "Changing log level from %r to %r", 42 | cur_log_level_name, new_log_level_name) 43 | package_logger.setLevel(new_log_level) # Just set it again to be sure 44 | 45 | _settings().add_on_change(__name__, on_settings_reload) 46 | on_settings_reload() # trigger on inital settings load, too 47 | 48 | 49 | def plugin_unloaded(): 50 | _settings().clear_on_change(__name__) 51 | package_logger.removeHandler(handler) -------------------------------------------------------------------------------- /demo-code.gdl: -------------------------------------------------------------------------------- 1 | ! GDL-Sublime | MIT License | Lucas Becker | 2 | ! DEMO CODE FOR SYNTAX HIGHLIGHTING 3 | ! it serves no other purpose than showing styling 4 | 5 | values "part" 4, range (5, 10], step 0.5, custom 6 | if not(gs_gutter) then lock "part" 7 | 8 | dim stHangerPos[6] 9 | dict eps 10 | eps.angle = ACS( 2*PI - len) 11 | 12 | hotspot2 0, B/2, unID :unID = unID+1 13 | CALL "m_DSProfiles" 14 | 15 | pen mypen 16 | mul2 1, COS(ac_wall_ang) 17 | add2 0, -tempWidth 18 | rot2 W~ 19 | poly2_b{2} NSP/3, 1+2+4+64, gs_fill_pen, gs_back_pen, 20 | A, 0, 0, 21 | USE(NSP) 22 | del 2 23 | 24 | if GLOB_MODPAR_NAME = "OffsetLength" then 25 | posX = 0.8e10 26 | FM_Type = 11 27 | else 28 | gosub "myFunc" 29 | endif 30 | 31 | shadow off 32 | string = STR("%.3m", number) 33 | 34 | LIN ! is deprecated dude 35 | 36 | ! ------------------------------------------------------- ! 37 | "myFunc": 38 | define style "Text" txtstyle, ntxt*j, txtpt, 0 39 | REQUEST("Height_of_style", "Text", height) 40 | esc = "It Has Escape\nChars and autotext !" 41 | return 42 | -------------------------------------------------------------------------------- /img/gdlst-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runxel/GDL-sublime/dd7a8362e86f3ac5a659f2afc0f795e11eaa27f0/img/gdlst-logo.png -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "install": "Messages/install.txt", 3 | "v2.0.0": "Messages/v2.0.0.txt", 4 | "v2.0.1": "Messages/v2.0.1.txt", 5 | "v2.0.2": "Messages/v2.0.2.txt", 6 | "v2.1.0": "Messages/v2.1.0.txt", 7 | "v2.2.0": "Messages/v2.2.0.txt", 8 | "v3.0.0": "Messages/v3.0.0.txt", 9 | "v3.1.0": "Messages/v3.1.0.txt", 10 | "v3.1.1": "Messages/v3.1.1.txt", 11 | "v3.2.0": "Messages/v3.2.0.txt", 12 | "v3.2.2": "Messages/v3.2.2.txt", 13 | "v3.2.3": "Messages/v3.2.3.txt", 14 | "v3.2.4": "Messages/v3.2.4.txt", 15 | "v3.4.0": "Messages/v3.4.0.txt", 16 | "v3.4.1": "Messages/v3.4.1.txt", 17 | "v3.4.2": "Messages/v3.4.2.txt", 18 | "v3.4.3": "Messages/v3.4.3.txt", 19 | "v3.4.4": "Messages/v3.4.4.txt", 20 | "v3.4.5": "Messages/v3.4.5.txt", 21 | } 22 | --------------------------------------------------------------------------------