├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── LICENSE.md ├── README.md ├── fortran.configuration.json ├── images └── icon.png ├── modern.configuration.json ├── package.json ├── snippets └── fortran.json ├── src ├── documentSymbolProvider.ts └── extension.ts ├── syntaxes ├── fortran.tmLanguage └── modern.tmLanguage ├── test ├── extension.test.ts └── index.ts ├── tsconfig.json └── vsc-extension-quickstart.md /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outDir": "${workspaceRoot}\\out\\src", 14 | "preLaunchTask": "npm" 15 | }, 16 | { 17 | "name": "Launch Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outDir": "${workspaceRoot}\\out\\test", 25 | "preLaunchTask": "npm" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version 10 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | typings/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Xavier Hahn 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fortran for Visual Studio Code 2 | 3 | An extension for VS Code which provides support for the Fortran language. 4 | 5 | Supports: 6 | * Syntax highlighting 7 | * Code snippets 8 | 9 | ## Usage 10 | ### Install the extension in VS Code 11 | * Open the command palette using `Ctrl+Shift+P` 12 | * Type `ext install Fortran` in the command palette 13 | 14 | ### Select Fortran as a language 15 | * On the bottom-right corner, click on the *select language mode* button, if you have created a new file it should display *Plain Text* 16 | * Select *Fortran* in the list of languages. 17 | 18 | Alternatively, saving the file with a `.f90` extension, will allow VS Code to understand that it is a FORTRAN file, and automatically select the language correctly. 19 | 20 | ### Using snippets 21 | * Bring-up the *autocomplete* menu by hitting the `Ctrl+Shift` key combination 22 | * Select the snippet that you want to use in the list 23 | * Use `tab` to navigate trough the snippet's variables 24 | 25 | ### Remark 26 | Code snippets and syntax highlighting were imported from the [TextMate bundle](https://github.com/textmate/fortran.tmbundle). 27 | -------------------------------------------------------------------------------- /fortran.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "c" 5 | }, 6 | // symbols used as brackets 7 | "brackets": [ 8 | ["(", ")"] 9 | ] 10 | } -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gimly/vscode-fortran/0d14746e6e6d1f8e25f41177bc6151de2161a9bf/images/icon.png -------------------------------------------------------------------------------- /modern.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "!" 5 | }, 6 | // symbols used as brackets 7 | "brackets": [ 8 | ["(", ")"] 9 | ] 10 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fortran", 3 | "displayName": "fortran", 4 | "description": "An extension for VS Code which provides support for the Fortran language.", 5 | "version": "0.2.0", 6 | "publisher": "Gimly81", 7 | "license": "SEE LICENSE IN LICENSE.md", 8 | "engines": { 9 | "vscode": "^1.16.0" 10 | }, 11 | "categories": [ 12 | "Languages", 13 | "Snippets" 14 | ], 15 | "homepage": "https://github.com/Gimly/vscode-fortran/blob/master/README.md", 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/Gimly/vscode-fortran.git" 19 | }, 20 | "activationEvents": [ 21 | "onLanguage:fortran-modern" 22 | ], 23 | "main": "./out/src/extension", 24 | "icon": "images/icon.png", 25 | "bugs": "https://github.com/Gimly/vscode-fortran/issues", 26 | "contributes": { 27 | "languages": [ 28 | { 29 | "id": "fortran", 30 | "aliases": [ 31 | "Fortran - Punchcard", 32 | "fortran" 33 | ], 34 | "extensions": [ 35 | ".f", 36 | ".F", 37 | ".f77", 38 | ".F77", 39 | ".for", 40 | ".FOR", 41 | ".fpp", 42 | ".FPP" 43 | ], 44 | "configuration": "./fortran.configuration.json" 45 | }, 46 | { 47 | "id": "fortran-modern", 48 | "aliases": [ 49 | "Fortran - Modern" 50 | ], 51 | "extensions": [ 52 | ".f90", 53 | ".F90", 54 | ".f95", 55 | ".F95", 56 | ".f03", 57 | ".F03", 58 | ".f08", 59 | ".F08" 60 | ], 61 | "configuration": "./modern.configuration.json" 62 | } 63 | ], 64 | "grammars": [ 65 | { 66 | "language": "fortran-modern", 67 | "scopeName": "source.fortran.modern", 68 | "path": "./syntaxes/modern.tmLanguage" 69 | }, 70 | { 71 | "language": "fortran", 72 | "scopeName": "source.fortran", 73 | "path": "./syntaxes/fortran.tmLanguage" 74 | } 75 | ], 76 | "snippets": [ 77 | { 78 | "language": "fortran-modern", 79 | "path": "./snippets/fortran.json" 80 | } 81 | ] 82 | }, 83 | "scripts": { 84 | "vscode:prepublish": "npm run compile", 85 | "compile": "tsc -p ./", 86 | "watch": "tsc -watch -p ./", 87 | "postinstall": "node ./node_modules/vscode/bin/install", 88 | "test": "npm run compile && node ./node_modules/vscode/bin/test" 89 | }, 90 | "devDependencies": { 91 | "typescript": "^2.5.3", 92 | "vscode": "^1.1.5", 93 | "@types/node": "^7.0.43", 94 | "@types/mocha": "^2.2.42" 95 | } 96 | } -------------------------------------------------------------------------------- /snippets/fortran.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": { 3 | "prefix": "all", 4 | "body": "all(${1:mask}${2:, dim=${3:1}})", 5 | "description": "all", 6 | "scope": "source.fortran" 7 | }, 8 | "alloc": { 9 | "prefix": "alloc", 10 | "body": [ 11 | "allocate(${1:array}, stat=${2:err})", 12 | "if ($2 /= 0) print *, \"$1: Allocation request denied\"", 13 | "", 14 | "if (allocated($1)) deallocate($1, stat=$2)", 15 | "if ($2 /= 0) print *, \"$1: Deallocation request denied\"" 16 | ], 17 | "description": "Allocate and Deallocate array", 18 | "scope": "source.fortran" 19 | }, 20 | "al": { 21 | "body": [ 22 | "allocate(${1:array}, stat=${2:err})", 23 | "if ($2 /= 0) print *, \"$1: Allocation request denied\"" 24 | ], 25 | "prefix": "al", 26 | "description": "Allocate Array" 27 | }, 28 | "and": { 29 | "prefix": "and", 30 | "body": ".and.", 31 | "description": "And", 32 | "scope": "source.fortran" 33 | }, 34 | "any": { 35 | "prefix": "any", 36 | "body": "any(${1:mask}${2:, dim=${3:1}})", 37 | "description": "any", 38 | "scope": "source.fortran" 39 | }, 40 | "case": { 41 | "prefix": "case", 42 | "body": "case ${1:default}\r\n\t$0", 43 | "description": "case", 44 | "scope": "source.fortran" 45 | }, 46 | "char": { 47 | "prefix": "char", 48 | "body": "character(len=$1${2:, kind=$3})${4:, ${5:attributes}} :: ${6:name}", 49 | "description": "Character", 50 | "scope": "source.fortran" 51 | }, 52 | "close": { 53 | "prefix": "close", 54 | "body": "close(unit=${1:iounit}, iostat=${2:ios}${3:, status=\"delete\"})\r\nif ( $2 /= 0 ) stop \"Error closing file unit $1\"\r\n", 55 | "description": "Close File", 56 | "scope": "source.fortran" 57 | }, 58 | "count": { 59 | "prefix": "count", 60 | "body": "count(${1:mask}${2:, dim=${3:1}})", 61 | "description": "count", 62 | "scope": "source.fortran" 63 | }, 64 | "typ": { 65 | "prefix": "typ", 66 | "body": "type(${1:type name})${2:, ${3:attributes}} :: ${4:name}", 67 | "description": "Custom Type", 68 | "scope": "source.fortran" 69 | }, 70 | "cy": { 71 | "prefix": "cy", 72 | "body": "cycle", 73 | "description": "cycle", 74 | "scope": "source.fortran" 75 | }, 76 | "data": { 77 | "prefix": "data", 78 | "body": "data ${1:variable} / ${2:data} /", 79 | "description": "data", 80 | "scope": "source.fortran" 81 | }, 82 | "deal": { 83 | "prefix": "deal", 84 | "body": "if (allocated($1)) deallocate(${1:array}, stat=${2:err})\r\nif ($2 /= 0) print *, \"$1: Deallocation request denied$0\"", 85 | "description": "Deallocate Array", 86 | "scope": "source.fortran" 87 | }, 88 | "dow": { 89 | "prefix": "dow", 90 | "body": "do while ( ${1:condition} )\r\n\t$0\r\nend do", 91 | "description": "do while", 92 | "scope": "source.fortran" 93 | }, 94 | "do": { 95 | "prefix": "do", 96 | "body": "do${1: ${2:i} = ${3:1}, ${4:100}, ${5:1}}\r\n\t$0\r\nend do", 97 | "description": "do", 98 | "scope": "source.fortran" 99 | }, 100 | "dot": { 101 | "prefix": "dot", 102 | "body": "dot_product($1,$2)", 103 | "description": "Dot Product of Vectors", 104 | "scope": "source.fortran" 105 | }, 106 | "elif": { 107 | "prefix": "elif", 108 | "body": "elseif ( ${1:condition} ) then\r\n\t", 109 | "description": "elseif", 110 | "scope": "source.fortran" 111 | }, 112 | "eq": { 113 | "prefix": "eq", 114 | "body": ".eq.", 115 | "description": "Equal", 116 | "scope": "source.fortran" 117 | }, 118 | "eqv": { 119 | "prefix": "eqv", 120 | "body": ".eqv.", 121 | "description": "Equality", 122 | "scope": "source.fortran" 123 | }, 124 | "for": { 125 | "prefix": "for", 126 | "body": "forall (${1:i=1:100}${2:, mask})\r\n\t$0\r\nend forall", 127 | "description": "forall", 128 | "scope": "source.fortran.modern" 129 | }, 130 | "fun": { 131 | "prefix": "fun", 132 | "body": [ 133 | "function ${1:name}(${2:input}) result(${3:output})", 134 | "\t${4:argument type}, intent(${5:inout}) :: $2", 135 | "\t${6:function type} :: $3", 136 | "\t$0", 137 | "end function $1" 138 | ], 139 | "description": "function", 140 | "scope": "source.fortran" 141 | }, 142 | "ge": { 143 | "prefix": "ge", 144 | "body": ".ge.", 145 | "description": "Greater or Equal", 146 | "scope": "source.fortran" 147 | }, 148 | "gt": { 149 | "prefix": "gt", 150 | "body": ".gt.", 151 | "description": "Greater Than", 152 | "scope": "source.fortran" 153 | }, 154 | "if": { 155 | "prefix": "if", 156 | "body": "if ( ${1:condition} ) ", 157 | "description": "if (single line)", 158 | "scope": "source.fortran" 159 | }, 160 | "if1": { 161 | "prefix": "if", 162 | "body": "if ( ${1:condition} ) then\r\n\t$0\r\nend if", 163 | "description": "if", 164 | "scope": "source.fortran" 165 | }, 166 | "imp": { 167 | "prefix": "imp", 168 | "body": "implicit none\r\n", 169 | "description": "implicit none", 170 | "scope": "source.fortran" 171 | }, 172 | "ido": { 173 | "prefix": "ido", 174 | "body": "(${1:i}, $1 = ${2:1}, ${3:100}, ${4:1})$0", 175 | "description": "Implied do", 176 | "scope": "source.fortran" 177 | }, 178 | "maxloc": { 179 | "prefix": "maxloc", 180 | "body": "maxloc(${1:source}${2:, mask=${3:($1>0)}})", 181 | "description": "Index of Maximum", 182 | "scope": "source.fortran" 183 | }, 184 | "minloc": { 185 | "prefix": "minloc", 186 | "body": "minloc(${1:source}${2:, mask=${3:$1>0}})", 187 | "description": "Index of Minimum", 188 | "scope": "source.fortran" 189 | }, 190 | "open": { 191 | "prefix": "open", 192 | "body": "open(unit=${1:iounit}, file=${2:name}, iostat=${3:ios}, status=\"${4:old}\", action=\"${5:read}\")\r\nif ( $3 /= 0 ) stop \"Error opening file ${2/[\\\"\\'](.*)[\\\"\\']/$1/}\"\r\n", 193 | "description": "Input File", 194 | "scope": "source.fortran" 195 | }, 196 | "inq": { 197 | "prefix": "inq", 198 | "body": "inquire(file=${1:filename}, opened=${2:ioopen}, exists=${3:ioexist}, number=${4:iounit})", 199 | "description": "Inquire (by Filename)", 200 | "scope": "source.fortran" 201 | }, 202 | "inq1": { 203 | "prefix": "inq", 204 | "body": "inquire(unit=${1:iounit}, opened=${2:ioopen}, name=${3:filename}, action=${4:ioaction})", 205 | "description": "Inquire (by Unit)", 206 | "scope": "source.fortran" 207 | }, 208 | "int": { 209 | "prefix": "int", 210 | "body": "integer${1:(${2:kind})}${3:, ${4:attributes}} :: ${5:name}", 211 | "description": "Integer", 212 | "scope": "source.fortran" 213 | }, 214 | "interf": { 215 | "prefix": "interf", 216 | "body": "interface ${1:name}\r\n\t$0\r\nend interface ! $1", 217 | "description": "interface", 218 | "scope": "source.fortran" 219 | }, 220 | "le": { 221 | "prefix": "le", 222 | "body": ".le.", 223 | "description": "Less or Equal", 224 | "scope": "source.fortran" 225 | }, 226 | "lt": { 227 | "prefix": "lt", 228 | "body": ".lt.", 229 | "description": "Less Than", 230 | "scope": "source.fortran" 231 | }, 232 | "log": { 233 | "prefix": "log", 234 | "body": "logical${1:(${2:kind})}${3:, ${4:attributes}} :: ${5:name}", 235 | "description": "Logical", 236 | "scope": "source.fortran" 237 | }, 238 | "lbound": { 239 | "prefix": "lbound", 240 | "body": "lbound(${1:source}${2:, dim=${3:1}})", 241 | "description": "Lower Bound", 242 | "scope": "source.fortran" 243 | }, 244 | "mat": { 245 | "prefix": "mat", 246 | "body": "matmul($1,$2)", 247 | "description": "Matrix Multiplication", 248 | "scope": "source.fortran" 249 | }, 250 | "max": { 251 | "prefix": "max", 252 | "body": "max($1, $2${, $3:...})$0", 253 | "description": "max", 254 | "scope": "source.fortran" 255 | }, 256 | "maxval": { 257 | "prefix": "maxval", 258 | "body": "maxval(${1:source}${2:, dim=${3:1}}${4:, mask=${5:($1>0)}})", 259 | "description": "Maximum Value", 260 | "scope": "source.fortran" 261 | }, 262 | "merge": { 263 | "prefix": "merge", 264 | "body": "merge(${1:source}, ${2:alternative}, mask=(${2:$1>0}))", 265 | "description": "merge", 266 | "scope": "source.fortran" 267 | }, 268 | "min": { 269 | "prefix": "min", 270 | "body": "min($1, $2${, $3:...})$0", 271 | "description": "min", 272 | "scope": "source.fortran" 273 | }, 274 | "minval": { 275 | "prefix": "minval", 276 | "body": "minval(${1:source}${2:, dim=${3:1}}${4:, mask=${5:($1>0)}})", 277 | "description": "Minimum Value", 278 | "scope": "source.fortran" 279 | }, 280 | "mp": { 281 | "prefix": "mp", 282 | "body": "module procedure ${0:name}", 283 | "description": "module procedure", 284 | "scope": "source.fortran" 285 | }, 286 | "mod": { 287 | "prefix": "mod", 288 | "body": "module ${1:name}\r\n\r\n\timplicit none\r\n\t$0\r\n\r\nend module $1\r\n", 289 | "description": "module", 290 | "scope": "source.fortran" 291 | }, 292 | "neqv": { 293 | "prefix": "neqv", 294 | "body": ".neqv.", 295 | "description": "Non-Equality", 296 | "scope": "source.fortran" 297 | }, 298 | "not": { 299 | "prefix": "not", 300 | "body": ".not.", 301 | "description": "Not", 302 | "scope": "source.fortran" 303 | }, 304 | "open1": { 305 | "prefix": "open", 306 | "body": "open(unit=${1:iounit}, file=${2:name}, iostat=${3:ios}, &\r\n status=\"${4:old/new/replace/scratch/unknown}\", action=\"${5:read/write/readwrite}\", access=\"${7:sequential/direct}\"${7/(direct)$|.*/(?1:, recl=)/}$0)\r\nif ( $3 /= 0 ) stop \"Error opening file ${2/[\\\"\\'](.*)[\\\"\\']/$1/}\"", 307 | "description": "Open File", 308 | "scope": "source.fortran" 309 | }, 310 | "or": { 311 | "prefix": "or", 312 | "body": ".or.", 313 | "description": "Or", 314 | "scope": "source.fortran" 315 | }, 316 | "open2": { 317 | "prefix": "open", 318 | "body": "open(unit=${1:iounit}, file=${2:name}, iostat=${3:ios}, status=\"${4:new}\", action=\"${5:write}\")\r\nif ( $3 /= 0 ) stop \"Error opening file ${2/[\\\"\\'](.*)[\\\"\\']/$1/}\"\r\n", 319 | "description": "Output File", 320 | "scope": "source.fortran" 321 | }, 322 | "pack": { 323 | "prefix": "pack", 324 | "body": "pack(${1:array}, mask=(${2:$1>0})${3:, vector=${4:destination vector}})", 325 | "description": "pack", 326 | "scope": "source.fortran" 327 | }, 328 | "pr": { 329 | "prefix": "pr", 330 | "body": "print*, ", 331 | "description": "Quick Print", 332 | "scope": "source.fortran" 333 | }, 334 | "prod": { 335 | "prefix": "prod", 336 | "body": "product(${1:source}${2:, dim=${3:1}}${4:, mask=${5:($1>0)}})", 337 | "description": "Product of Elements", 338 | "scope": "source.fortran" 339 | }, 340 | "prog": { 341 | "prefix": "prog", 342 | "body": "program ${1:name}\r\n\r\n\timplicit none\r\n\t$0\r\n\r\nend program $1\r\n", 343 | "description": "program", 344 | "scope": "source.fortran" 345 | }, 346 | "c": { 347 | "prefix": "c", 348 | "body": "character(len=*) :: ", 349 | "description": "Quick Character", 350 | "scope": "source.fortran" 351 | }, 352 | "t": { 353 | "prefix": "t", 354 | "body": "type(${1:type name}) :: ", 355 | "description": "Quick Custom Type", 356 | "scope": "source.fortran" 357 | }, 358 | "i": { 359 | "prefix": "i", 360 | "body": "integer :: ", 361 | "description": "Quick Integer", 362 | "scope": "source.fortran" 363 | }, 364 | "l": { 365 | "prefix": "l", 366 | "body": "logical :: ", 367 | "description": "Quick Logical", 368 | "scope": "source.fortran" 369 | }, 370 | "op": { 371 | "prefix": "op", 372 | "body": "open(unit=${1:iounit}, file=${2:name}, iostat=${3:ios})\r\nif ( $3 /= 0 ) stop \"Error opening file ${2/[\\\"\\'](.*)[\\\"\\']/$1/}\"", 373 | "description": "Quick Open", 374 | "scope": "source.fortran" 375 | }, 376 | "re": { 377 | "prefix": "re", 378 | "body": "read*, ", 379 | "description": "Quick Read", 380 | "scope": "source.fortran" 381 | }, 382 | "r": { 383 | "prefix": "r", 384 | "body": "real :: ", 385 | "description": "Quick Real", 386 | "scope": "source.fortran" 387 | }, 388 | "wr": { 389 | "prefix": "wr", 390 | "body": "write(unit=${1:iounit}, fmt=*) ${0:variables}\r\n", 391 | "description": "Quick Write", 392 | "scope": "source.fortran" 393 | }, 394 | "rn": { 395 | "prefix": "rn", 396 | "body": "call random_number($0)", 397 | "description": "Random Number", 398 | "scope": "source.fortran" 399 | }, 400 | "rs": { 401 | "prefix": "rs", 402 | "body": "call random_seed(${1:size=${2:}}${3:put=(/$4/)})", 403 | "description": "Random Seed", 404 | "scope": "source.fortran" 405 | }, 406 | "read": { 407 | "prefix": "read", 408 | "body": "read(unit=${1:iounit}, fmt=\"(${2:format string})\", iostat=${3:istat}, advance='NO', size=${4:number of characters}) ${5:variables}\r\nif ( $3 /= 0 ) stop \"Read error in file unit $1\"\r\n", 409 | "description": "Read (Non Advancing Mode)", 410 | "scope": "source.fortran" 411 | }, 412 | "read1": { 413 | "prefix": "read", 414 | "body": "read(unit=${1:iounit}, fmt=\"(${2:format string})\", iostat=${3:istat}) ${4:variables}\r\nif ( $3 /= 0 ) stop \"Read error in file unit $1\"\r\n", 415 | "description": "Read", 416 | "scope": "source.fortran" 417 | }, 418 | "rea": { 419 | "prefix": "rea", 420 | "body": "real${1:(${2:kind})}${3:, ${4:attributes}} :: ${5:name}", 421 | "description": "Real", 422 | "scope": "source.fortran" 423 | }, 424 | "resh": { 425 | "prefix": "resh", 426 | "body": "reshape(${1:source}${2:, shape=(/$3/)}${4:, pad=(/$5/)}${6:, order=(/${7:2,1}/)})", 427 | "description": "reshape", 428 | "scope": "source.fortran" 429 | }, 430 | "open3": { 431 | "prefix": "open", 432 | "body": "open(unit=${1:iounit}, iostat=${3:ios}, status=\"${4:scratch}\", action=\"${5:readwrite}\")\r\nif ( $3 /= 0 ) stop \"Error opening scratch file on unit $1\"\r\n", 433 | "description": "Scratch File", 434 | "scope": "source.fortran" 435 | }, 436 | "sel": { 437 | "prefix": "sel", 438 | "body": "select case ($1:variable)\r\n\tcase ($2:values)\r\n\t\t$0\r\nend select", 439 | "description": "select case", 440 | "scope": "source.fortran" 441 | }, 442 | "size": { 443 | "prefix": "size", 444 | "body": "size(${1:source}${2:, dim=${3:1}})", 445 | "description": "Size", 446 | "scope": "source.fortran" 447 | }, 448 | "spread": { 449 | "prefix": "spread", 450 | "body": "spread(${1:source}, dim=${2:1}, ncopies=$3)", 451 | "description": "spread", 452 | "scope": "source.fortran" 453 | }, 454 | "stop": { 455 | "prefix": "stop", 456 | "body": "stop \"${1:message}\"", 457 | "description": "stop", 458 | "scope": "source.fortran" 459 | }, 460 | "sub": { 461 | "prefix": "sub", 462 | "body": "subroutine ${1:name}\r\n\t${2:argument type}, intent(${3:inout}) :: ${1/\\w+\\((.*)\\)|.*/$1/}\r\n\t$0\r\nend subroutine ${1/(\\w+).*/$1/}", 463 | "description": "subroutine", 464 | "scope": "source.fortran" 465 | }, 466 | "sum": { 467 | "prefix": "sum", 468 | "body": "sum(${1:source}${2:, dim=${3:1}}${4:, mask=${5:($1>0)}})", 469 | "description": "Sum of Elements", 470 | "scope": "source.fortran" 471 | }, 472 | "type": { 473 | "prefix": "type", 474 | "body": "type ${1:type name}\r\n\t$0\r\nend type $1", 475 | "description": "Type Definition", 476 | "scope": "source.fortran" 477 | }, 478 | "unpack": { 479 | "prefix": "unpack", 480 | "body": "unpack(${1:vector}, mask=(${2:$1>0}), field=${3:destination array})", 481 | "description": "unpack", 482 | "scope": "source.fortran" 483 | }, 484 | "ubound": { 485 | "prefix": "ubound", 486 | "body": "ubound(${1:source}${2:, dim=${3:1}})", 487 | "description": "Upper Bound", 488 | "scope": "source.fortran" 489 | }, 490 | "wh": { 491 | "prefix": "wh", 492 | "body": "where ( $1 ${2:==} $3 ) ", 493 | "description": "where (single line)", 494 | "scope": "source.fortran" 495 | }, 496 | "whe": { 497 | "prefix": "whe", 498 | "body": "where ( $1 ${2:==} $3 )\r\n\t$0\r\nend where", 499 | "description": "where", 500 | "scope": "source.fortran" 501 | }, 502 | "write": { 503 | "prefix": "write", 504 | "body": "write(unit=${1:iounit}, fmt=\"(${2:format string})\", iostat=${3:ios}${4:, advance='NO'}) ${5:variables}\r\nif ( $3 /= 0 ) stop \"Write error in file unit $1\"\r\n", 505 | "description": "Write", 506 | "scope": "source.fortran" 507 | }, 508 | "F": { 509 | "prefix": "F", 510 | "body": ".FALSE.", 511 | "description": ".FALSE.", 512 | "scope": "source.fortran" 513 | }, 514 | "T": { 515 | "prefix": "T", 516 | "body": ".TRUE.", 517 | "description": ".TRUE.", 518 | "scope": "source.fortran" 519 | } 520 | } -------------------------------------------------------------------------------- /src/documentSymbolProvider.ts: -------------------------------------------------------------------------------- 1 | import vscode = require('vscode'); 2 | 3 | export class FortranDocumentSymbolProvider implements vscode.DocumentSymbolProvider { 4 | 5 | public provideDocumentSymbols( 6 | document: vscode.TextDocument, 7 | token: vscode.CancellationToken): vscode.SymbolInformation[] { 8 | 9 | const functionRegex = /^(?:pure|PURE|recursive|RECURSIVE)?\s+(?:function|FUNCTION)\s+(?:\w+)\s*(?:\(\w+\s*(?:,\s*\w+\s*)*\))(?:\s+(?:result|RESULT)(?:\(\w+\s*(?:,\s*\w+\s*)*\)))?$/; 10 | 11 | const result: vscode.SymbolInformation[] = []; 12 | 13 | for (let line = 0; line < document.lineCount; line++) { 14 | const { text } = document.lineAt(line); 15 | 16 | if (functionRegex.test(text)) { 17 | result.push( 18 | new vscode.SymbolInformation( 19 | text, 20 | vscode.SymbolKind.Function, 21 | '', 22 | new vscode.Location(document.uri, new vscode.Position(line, 0)) 23 | )); 24 | } 25 | } 26 | 27 | return result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | import * as vscode from 'vscode'; 4 | import { FortranDocumentSymbolProvider } from './documentSymbolProvider'; 5 | 6 | // this method is called when your extension is activated 7 | // your extension is activated the very first time the command is executed 8 | export function activate(context: vscode.ExtensionContext) { 9 | 10 | // Use the console to output diagnostic information (console.log) and errors (console.error) 11 | // This line of code will only be executed once when your extension is activated 12 | console.log('Congratulations, your extension "fortran" is now active!'); 13 | 14 | context.subscriptions.push( 15 | vscode.languages.registerDocumentSymbolProvider( 16 | 'fortran-modern', new FortranDocumentSymbolProvider() 17 | ) 18 | ); 19 | } -------------------------------------------------------------------------------- /syntaxes/fortran.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | ?i: has to be added everywhere because fortran is case insensitive; NB: order of matching matters 7 | fileTypes 8 | 9 | f 10 | F 11 | f77 12 | F77 13 | for 14 | FOR 15 | fpp 16 | FPP 17 | 18 | name 19 | Fortran - Punchcard 20 | patterns 21 | 22 | 23 | include 24 | #preprocessor-rule-enabled 25 | 26 | 27 | include 28 | #preprocessor-rule-disabled 29 | 30 | 31 | include 32 | #preprocessor-rule-other 33 | 34 | 35 | comment 36 | built-in constants 37 | match 38 | (?i:(r8|r4|\.TRUE\.|\.FALSE\.)) 39 | name 40 | constant.language.fortran 41 | 42 | 43 | comment 44 | numbers 45 | match 46 | \b[\+\-]?[0-9]+\.?[0-9a-zA-Z_]*\b 47 | name 48 | constant.numeric.fortran 49 | 50 | 51 | begin 52 | (?x: # extended mode 53 | ^ 54 | \s* # start of line and possibly some space 55 | ([a-zA-Z\(\)]*)(?<!end) # 1: possibly some type specification but not the word end 56 | \s* # possibly some space 57 | (?i:(function|subroutine))\b # 2: function or subroutine 58 | \s+ # some space 59 | ([A-Za-z_][A-Za-z0-9_]*) # 3: name 60 | ) 61 | beginCaptures 62 | 63 | 1 64 | 65 | name 66 | storage.type.fortran 67 | 68 | 2 69 | 70 | name 71 | storage.type.function.fortran 72 | 73 | 3 74 | 75 | name 76 | entity.name.function.fortran 77 | 78 | 79 | comment 80 | First line of function/subroutine definition 81 | end 82 | (?x: # extended mode 83 | ((?i:end)) # 1: the word end 84 | ( # followed by 85 | $ # end of line 86 | | # or 87 | \s* # possibly some space 88 | (?i:(function|subroutine)) # 2: function or subroutine 89 | ((\s+[A-Za-z_][A-Za-z0-9_]*)?) # 3: possibly the name 90 | ) 91 | ) 92 | endCaptures 93 | 94 | 1 95 | 96 | name 97 | keyword.other.fortran 98 | 99 | 3 100 | 101 | name 102 | storage.type.function.fortran 103 | 104 | 4 105 | 106 | name 107 | entity.name.function.end.fortran 108 | 109 | 110 | name 111 | meta.function.fortran 112 | patterns 113 | 114 | 115 | begin 116 | \G\s*(\() 117 | beginCaptures 118 | 119 | 1 120 | 121 | name 122 | punctuation.definition.parameters.begin.fortran 123 | 124 | 125 | end 126 | \) 127 | endCaptures 128 | 129 | 0 130 | 131 | name 132 | punctuation.definition.parameters.end.fortran 133 | 134 | 135 | patterns 136 | 137 | 138 | captures 139 | 140 | 1 141 | 142 | name 143 | variable.parameter.fortran 144 | 145 | 2 146 | 147 | name 148 | punctuation.separator.arguments.fortan 149 | 150 | 151 | match 152 | ([^\s),]*)\s*(,)? 153 | 154 | 155 | 156 | 157 | include 158 | $self 159 | 160 | 161 | include 162 | source.fortran.modern 163 | 164 | 165 | 166 | 167 | begin 168 | \b(?i:(integer|real|double\s+precision|complex|logical|character))\b(?=.*::) 169 | beginCaptures 170 | 171 | 1 172 | 173 | name 174 | storage.type.fortran 175 | 176 | 177 | comment 178 | Line of type specification 179 | end 180 | (?=!)|$ 181 | name 182 | meta.specification.fortran 183 | patterns 184 | 185 | 186 | include 187 | $self 188 | 189 | 190 | 191 | 192 | comment 193 | statements controling the flow of the program 194 | match 195 | \b(?i:(go\s*to|assign|to|if|then|else|elseif|end\s*if|continue|stop|pause|do|end\s*do|while|cycle))\b 196 | name 197 | keyword.control.fortran 198 | 199 | 200 | comment 201 | programming units 202 | match 203 | \b(?i:(program|end\s+program|entry|block\s+data|call|return|contains|include))\b 204 | name 205 | keyword.control.programming-units.fortran 206 | 207 | 208 | comment 209 | i/o statements 210 | match 211 | \b(?i:(open|close|read|write|print|inquire|backspace|endfile|format))\b 212 | name 213 | keyword.control.io.fortran 214 | 215 | 216 | comment 217 | operators 218 | match 219 | ((?<!\=)\=(?!\=)|\-|\+|\/\/|\/|(?!^)\*|::) 220 | name 221 | keyword.operator.fortran 222 | 223 | 224 | comment 225 | logical operators 226 | match 227 | (?i:(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)) 228 | name 229 | keyword.operator.logical.fortran 230 | 231 | 232 | comment 233 | argument related intrisics 234 | match 235 | \b(?i:(present)(?=\()) 236 | name 237 | keyword.other.instrisic.argument.fortran 238 | 239 | 240 | comment 241 | numeric intrisics 242 | match 243 | \b(?i:(abs|aimag|aint|anint|cmplx|conjg|dble|dim|dprod|int|max|min|mod|nint|real|sign|digits|epsilon|huge|maxexponent|minexponent|precision|radix|range|tiny)(?=\()) 244 | name 245 | keyword.other.instrisic.numeric.fortran 246 | 247 | 248 | comment 249 | character string intrinsics 250 | match 251 | \b(?i:(achar|adjustl|adjustr|char|iachar|ichar|index|len_trim|repeat|scan|string|trim|verify|len)(?=\()) 252 | name 253 | keyword.other.instrisic.string.fortran 254 | 255 | 256 | comment 257 | mathematical intrisics 258 | match 259 | \b(?i:(((acos|asin|atan|atan2|cos|cosh|exp|log|log10|sin|sinh|sqrt|tan|tanh)(?=\())|(random_number|random_seed)))\b 260 | name 261 | keyword.other.instrisic.math.fortran 262 | 263 | 264 | comment 265 | data kind intrinsics 266 | match 267 | \b(?i:(kind|selected_int_kind|selected_real_kind|transfer)(?=\()) 268 | name 269 | keyword.other.instrisic.data.fortran 270 | 271 | 272 | comment 273 | logical intrinsics 274 | match 275 | \b(?i:(logical)(?=\()) 276 | name 277 | keyword.other.instrisic.logical.fortran 278 | 279 | 280 | comment 281 | bit operations intrinsics 282 | match 283 | \b(?i:(((bit_size|btest|iand|ibclr|ibits|ibset|ieor|ior|ishift|ishiftc|not)(?=\())|mvbits))\b 284 | name 285 | keyword.other.instrisic.bit.fortran 286 | 287 | 288 | comment 289 | floating point intrinsics 290 | match 291 | \b(?i:(exponent|fraction|nearest|rrspacing|scale|set_exponent|spacing)(?=\()) 292 | name 293 | keyword.other.instrisic.floating-point.fortran 294 | 295 | 296 | comment 297 | matrix/vector/array intrisics 298 | match 299 | \b(?i:(((dot_product|sum|matmul|transpose|all|any|count|maxval|minval|maxloc|minloc|product|sum|lbound|ubound|shape|size|merge|pack|unpack|reshape|spread|cshift|eoshift)(?=\())|(where|elsewhere|end\s*where)))\b 300 | name 301 | keyword.other.instrisic.array.fortran 302 | 303 | 304 | comment 305 | other intrisics 306 | match 307 | \b(?i:(((dtime)(?=\())|(date_and_time|system_clock)))\b 308 | name 309 | keyword.other.instrisic.fortran 310 | 311 | 312 | comment 313 | data specification 314 | match 315 | \b(?i:(integer|real|double\s+precision|complex|logical|character|block\sdata|operator|assignment))\b 316 | name 317 | storage.type.fortran 318 | 319 | 320 | comment 321 | data type attributes 322 | match 323 | \b(?i:(dimension|common|equivalence|parameter|external|intrinsic|save|data|implicit\s*none|implicit|intent|in|out|inout))\b 324 | name 325 | storage.modifier.fortran 326 | 327 | 328 | applyEndPatternLast 329 | 1 330 | begin 331 | ' 332 | beginCaptures 333 | 334 | 0 335 | 336 | name 337 | punctuation.definition.string.begin.fortran 338 | 339 | 340 | comment 341 | String 342 | end 343 | ' 344 | endCaptures 345 | 346 | 0 347 | 348 | name 349 | punctuation.definition.string.end.fortran 350 | 351 | 352 | name 353 | string.quoted.single.fortran 354 | patterns 355 | 356 | 357 | match 358 | '' 359 | name 360 | constant.character.escape.apostrophe.fortran 361 | 362 | 363 | 364 | 365 | applyEndPatternLast 366 | 1 367 | begin 368 | " 369 | beginCaptures 370 | 371 | 0 372 | 373 | name 374 | punctuation.definition.string.begin.fortran 375 | 376 | 377 | comment 378 | String 379 | end 380 | " 381 | endCaptures 382 | 383 | 0 384 | 385 | name 386 | punctuation.definition.string.end.fortran 387 | 388 | 389 | name 390 | string.quoted.double.fortran 391 | patterns 392 | 393 | 394 | match 395 | "" 396 | name 397 | constant.character.escape.quote.fortran 398 | 399 | 400 | 401 | 402 | begin 403 | ^[Cc](?=\b|[Cc]) 404 | beginCaptures 405 | 406 | 0 407 | 408 | name 409 | punctuation.definition.comment.fortran 410 | 411 | 412 | end 413 | $\n? 414 | name 415 | comment.line.c.fortran 416 | patterns 417 | 418 | 419 | match 420 | \\\s*\n 421 | 422 | 423 | 424 | 425 | begin 426 | ^\* 427 | beginCaptures 428 | 429 | 0 430 | 431 | name 432 | punctuation.definition.comment.fortran 433 | 434 | 435 | end 436 | $\n? 437 | name 438 | comment.line.asterisk.fortran 439 | patterns 440 | 441 | 442 | match 443 | \\\s*\n 444 | 445 | 446 | 447 | 448 | begin 449 | ^\s*#\s*(error|warning)\b 450 | captures 451 | 452 | 1 453 | 454 | name 455 | keyword.control.import.error.fortran 456 | 457 | 458 | end 459 | $\n? 460 | name 461 | meta.preprocessor.diagnostic.fortran 462 | patterns 463 | 464 | 465 | match 466 | (?>\\\s*\n) 467 | name 468 | punctuation.separator.continuation.fortran 469 | 470 | 471 | 472 | 473 | begin 474 | ^\s*#\s*(include|import)\b\s+ 475 | captures 476 | 477 | 1 478 | 479 | name 480 | keyword.control.import.include.fortran 481 | 482 | 483 | end 484 | (?=(?://|/\*))|$\n? 485 | name 486 | meta.preprocessor.fortran.include 487 | patterns 488 | 489 | 490 | match 491 | (?>\\\s*\n) 492 | name 493 | punctuation.separator.continuation.fortran 494 | 495 | 496 | begin 497 | " 498 | beginCaptures 499 | 500 | 0 501 | 502 | name 503 | punctuation.definition.string.begin.fortran 504 | 505 | 506 | end 507 | " 508 | endCaptures 509 | 510 | 0 511 | 512 | name 513 | punctuation.definition.string.end.fortran 514 | 515 | 516 | name 517 | string.quoted.double.include.fortran 518 | 519 | 520 | begin 521 | < 522 | beginCaptures 523 | 524 | 0 525 | 526 | name 527 | punctuation.definition.string.begin.fortran 528 | 529 | 530 | end 531 | > 532 | endCaptures 533 | 534 | 0 535 | 536 | name 537 | punctuation.definition.string.end.fortran 538 | 539 | 540 | name 541 | string.quoted.other.lt-gt.include.fortran 542 | 543 | 544 | 545 | 546 | include 547 | #pragma-mark 548 | 549 | 550 | begin 551 | ^\s*#\s*(define|defined|elif|else|if|ifdef|ifndef|line|pragma|undef)\b 552 | captures 553 | 554 | 1 555 | 556 | name 557 | keyword.control.import.fortran 558 | 559 | 560 | end 561 | (?=(?://|/\*))|$\n? 562 | name 563 | meta.preprocessor.fortran 564 | patterns 565 | 566 | 567 | match 568 | (?>\\\s*\n) 569 | name 570 | punctuation.separator.continuation.fortran 571 | 572 | 573 | 574 | 575 | repository 576 | 577 | disabled 578 | 579 | begin 580 | ^\s*#\s*if(n?def)?\b.*$ 581 | comment 582 | eat nested preprocessor if(def)s 583 | end 584 | ^\s*#\s*endif\b.*$ 585 | patterns 586 | 587 | 588 | include 589 | #disabled 590 | 591 | 592 | include 593 | #pragma-mark 594 | 595 | 596 | 597 | pragma-mark 598 | 599 | captures 600 | 601 | 1 602 | 603 | name 604 | meta.preprocessor.fortran 605 | 606 | 2 607 | 608 | name 609 | keyword.control.import.pragma.fortran 610 | 611 | 3 612 | 613 | name 614 | meta.toc-list.pragma-mark.fortran 615 | 616 | 617 | match 618 | ^\s*(#\s*(pragma\s+mark)\s+(.*)) 619 | name 620 | meta.section 621 | 622 | preprocessor-rule-disabled 623 | 624 | begin 625 | ^\s*(#(if)\s+(0)\b).* 626 | captures 627 | 628 | 1 629 | 630 | name 631 | meta.preprocessor.fortran 632 | 633 | 2 634 | 635 | name 636 | keyword.control.import.if.fortran 637 | 638 | 3 639 | 640 | name 641 | constant.numeric.preprocessor.fortran 642 | 643 | 644 | end 645 | ^\s*(#\s*(endif)\b) 646 | patterns 647 | 648 | 649 | begin 650 | ^\s*(#\s*(else)\b) 651 | captures 652 | 653 | 1 654 | 655 | name 656 | meta.preprocessor.fortran 657 | 658 | 2 659 | 660 | name 661 | keyword.control.import.else.fortran 662 | 663 | 664 | end 665 | (?=^\s*#\s*endif\b.*$) 666 | patterns 667 | 668 | 669 | include 670 | $base 671 | 672 | 673 | 674 | 675 | begin 676 | 677 | end 678 | (?=^\s*#\s*(else|endif)\b.*$) 679 | name 680 | comment.block.preprocessor.if-branch 681 | patterns 682 | 683 | 684 | include 685 | #disabled 686 | 687 | 688 | include 689 | #pragma-mark 690 | 691 | 692 | 693 | 694 | 695 | preprocessor-rule-enabled 696 | 697 | begin 698 | ^\s*(#(if)\s+(0*1)\b) 699 | captures 700 | 701 | 1 702 | 703 | name 704 | meta.preprocessor.fortran 705 | 706 | 2 707 | 708 | name 709 | keyword.control.import.if.fortran 710 | 711 | 3 712 | 713 | name 714 | constant.numeric.preprocessor.fortran 715 | 716 | 717 | end 718 | ^\s*(#\s*(endif)\b) 719 | patterns 720 | 721 | 722 | begin 723 | ^\s*(#\s*(else)\b).* 724 | captures 725 | 726 | 1 727 | 728 | name 729 | meta.preprocessor.fortran 730 | 731 | 2 732 | 733 | name 734 | keyword.control.import.else.fortran 735 | 736 | 737 | contentName 738 | comment.block.preprocessor.else-branch 739 | end 740 | (?=^\s*#\s*endif\b.*$) 741 | patterns 742 | 743 | 744 | include 745 | #disabled 746 | 747 | 748 | include 749 | #pragma-mark 750 | 751 | 752 | 753 | 754 | begin 755 | 756 | end 757 | (?=^\s*#\s*(else|endif)\b.*$) 758 | patterns 759 | 760 | 761 | include 762 | $base 763 | 764 | 765 | 766 | 767 | 768 | preprocessor-rule-other 769 | 770 | begin 771 | ^\s*(#\s*(if(n?def)?)\b.*?(?:(?=(?://|/\*))|$)) 772 | captures 773 | 774 | 1 775 | 776 | name 777 | meta.preprocessor.fortran 778 | 779 | 2 780 | 781 | name 782 | keyword.control.import.fortran 783 | 784 | 785 | end 786 | ^\s*(#\s*(endif)\b).*$ 787 | patterns 788 | 789 | 790 | include 791 | $base 792 | 793 | 794 | 795 | 796 | scopeName 797 | source.fortran 798 | uuid 799 | 45253F88-F7CC-49C5-9C32-F3FADD2AB579 800 | 801 | 802 | -------------------------------------------------------------------------------- /syntaxes/modern.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | Specificities of Fortran >= 90 7 | fileTypes 8 | 9 | f90 10 | F90 11 | f95 12 | F95 13 | f03 14 | F03 15 | f08 16 | F08 17 | 18 | firstLineMatch 19 | (?i)-[*]- mode: f90 -[*]- 20 | keyEquivalent 21 | ^~F 22 | name 23 | Fortran - Modern 24 | patterns 25 | 26 | 27 | include 28 | source.fortran 29 | 30 | 31 | begin 32 | (?x: # extended mode 33 | ^ 34 | \s* # start of line and possibly some space 35 | (?i:(interface)) # 1: word interface 36 | \s+ # some space 37 | (?i:(operator|assignment)) # 2: the words operator or assignment 38 | \( # opening parenthesis 39 | ((\.[a-zA-Z0-9_]+\.)|[\+\-\=\/\*]+) # 3: an operator 40 | 41 | \) # closing parenthesis 42 | ) 43 | beginCaptures 44 | 45 | 1 46 | 47 | name 48 | storage.type.function.fortran 49 | 50 | 2 51 | 52 | name 53 | storage.type.fortran 54 | 55 | 3 56 | 57 | name 58 | keyword.operator.fortran 59 | 60 | 61 | comment 62 | Interface declaration of operator/assignments 63 | end 64 | (?x: 65 | ((?i:end)) # 1: the word end 66 | \s* # possibly some space 67 | ((?i:interface)?) # 2: possibly interface 68 | ) 69 | endCaptures 70 | 71 | 1 72 | 73 | name 74 | keyword.other.fortran 75 | 76 | 2 77 | 78 | name 79 | storage.type.function.fortran 80 | 81 | 82 | name 83 | meta.function.interface.operator.fortran.modern 84 | patterns 85 | 86 | 87 | include 88 | $self 89 | 90 | 91 | 92 | 93 | begin 94 | (?x: # extended mode 95 | ^ 96 | \s* # start of line and possibly some space 97 | (?i:(interface)) # 1: word interface 98 | \s+ # some space 99 | ([A-Za-z_][A-Za-z0-9_]*) # 1: name 100 | ) 101 | beginCaptures 102 | 103 | 1 104 | 105 | name 106 | storage.type.function.fortran 107 | 108 | 2 109 | 110 | name 111 | entity.name.function.fortran 112 | 113 | 114 | comment 115 | Interface declaration of function/subroutines 116 | end 117 | (?x: # extended mode 118 | ((?i:end)) # 1: the word end 119 | \s* # possibly some space 120 | ((?i:interface)?) # 2: possibly interface 121 | ) 122 | endCaptures 123 | 124 | 1 125 | 126 | name 127 | keyword.other.fortran 128 | 129 | 2 130 | 131 | name 132 | storage.type.function.fortran 133 | 134 | 135 | name 136 | meta.function.interface.fortran.modern 137 | patterns 138 | 139 | 140 | include 141 | $self 142 | 143 | 144 | 145 | 146 | begin 147 | (?x: # extended mode 148 | ^\s* # begining of line and some space 149 | (?i:(type)) # 1: word type 150 | \s+ # some space 151 | ([a-zA-Z_][a-zA-Z0-9_]*) # 2: type name 152 | ) 153 | beginCaptures 154 | 155 | 1 156 | 157 | name 158 | storage.type.fortran.modern 159 | 160 | 2 161 | 162 | name 163 | entity.name.type.fortran.modern 164 | 165 | 166 | comment 167 | Type definition 168 | end 169 | (?x: 170 | ((?i:end)) # 1: the word end 171 | \s* # possibly some space 172 | (?i:(type))? # 2: possibly the word type 173 | (\s+[A-Za-z_][A-Za-z0-9_]*)? # 3: possibly the name 174 | ) 175 | endCaptures 176 | 177 | 1 178 | 179 | name 180 | keyword.other.fortran 181 | 182 | 2 183 | 184 | name 185 | storage.type.fortran.modern 186 | 187 | 3 188 | 189 | name 190 | entity.name.type.end.fortran.modern 191 | 192 | 193 | name 194 | meta.type-definition.fortran.modern 195 | patterns 196 | 197 | 198 | include 199 | $self 200 | 201 | 202 | 203 | 204 | begin 205 | (^[ \t]+)?(?=!-) 206 | beginCaptures 207 | 208 | 1 209 | 210 | name 211 | punctuation.whitespace.comment.leading.ruby 212 | 213 | 214 | end 215 | (?!\G) 216 | patterns 217 | 218 | 219 | begin 220 | !- 221 | beginCaptures 222 | 223 | 0 224 | 225 | name 226 | punctuation.definition.comment.fortran 227 | 228 | 229 | end 230 | \n 231 | name 232 | comment.line.exclamation.mark.fortran.modern 233 | patterns 234 | 235 | 236 | match 237 | \\\s*\n 238 | 239 | 240 | 241 | 242 | 243 | 244 | begin 245 | (^[ \t]+)?(?=!) 246 | beginCaptures 247 | 248 | 1 249 | 250 | name 251 | punctuation.whitespace.comment.leading.ruby 252 | 253 | 254 | end 255 | (?!\G) 256 | patterns 257 | 258 | 259 | begin 260 | ! 261 | beginCaptures 262 | 263 | 0 264 | 265 | name 266 | punctuation.definition.comment.fortran 267 | 268 | 269 | end 270 | \n 271 | name 272 | comment.line.exclamation.fortran.modern 273 | patterns 274 | 275 | 276 | match 277 | \\\s*\n 278 | 279 | 280 | 281 | 282 | 283 | 284 | comment 285 | statements controling the flow of the program 286 | match 287 | \b(?i:(select\s+case|case(\s+default)?|end\s+select|use|(end\s+)?forall))\b 288 | name 289 | keyword.control.fortran.modern 290 | 291 | 292 | comment 293 | input/output instrinsics 294 | match 295 | \b(?i:(access|action|advance|append|apostrophe|asis|blank|delete|delim|direct|end|eor|err|exist|file|fmt|form|formatted|iolength|iostat|keep|name|named|nextrec|new|nml|no|null|number|old|opened|pad|position|quote|read|readwrite|rec|recl|replace|scratch|sequential|size|status|undefined|unformatted|unit|unknown|write|yes|zero|namelist)(?=\()) 296 | name 297 | keyword.control.io.fortran.modern 298 | 299 | 300 | comment 301 | logical operators in symbolic format 302 | match 303 | \b(\=\=|\/\=|\>\=|\>|\<|\<\=)\b 304 | name 305 | keyword.operator.logical.fortran.modern 306 | 307 | 308 | comment 309 | operators 310 | match 311 | (\%|\=\>) 312 | name 313 | keyword.operator.fortran.modern 314 | 315 | 316 | comment 317 | numeric instrinsics 318 | match 319 | \b(?i:(ceiling|floor|modulo)(?=\()) 320 | name 321 | keyword.other.instrinsic.numeric.fortran.modern 322 | 323 | 324 | comment 325 | matrix/vector/array instrinsics 326 | match 327 | \b(?i:(allocate|allocated|deallocate)(?=\()) 328 | name 329 | keyword.other.instrinsic.array.fortran.modern 330 | 331 | 332 | comment 333 | pointer instrinsics 334 | match 335 | \b(?i:(associated)(?=\()) 336 | name 337 | keyword.other.instrinsic.pointer.fortran.modern 338 | 339 | 340 | comment 341 | programming units 342 | match 343 | \b(?i:((end\s*)?(interface|procedure|module)))\b 344 | name 345 | keyword.other.programming-units.fortran.modern 346 | 347 | 348 | begin 349 | \b(?i:(type(?=\s*\()))\b(?=.*::) 350 | beginCaptures 351 | 352 | 1 353 | 354 | name 355 | storage.type.fortran.modern 356 | 357 | 358 | comment 359 | Line of type specification 360 | end 361 | (?=!)|$ 362 | name 363 | meta.specification.fortran.modern 364 | patterns 365 | 366 | 367 | include 368 | $base 369 | 370 | 371 | 372 | 373 | match 374 | \b(?i:(type(?=\s*\()))\b 375 | name 376 | storage.type.fortran.modern 377 | 378 | 379 | match 380 | \b(?i:(optional|recursive|pointer|allocatable|target|private|public))\b 381 | name 382 | storage.modifier.fortran.modern 383 | 384 | 385 | scopeName 386 | source.fortran.modern 387 | uuid 388 | 016CA1B6-8351-4B17-9215-29C275D5D973 389 | 390 | 391 | -------------------------------------------------------------------------------- /test/extension.test.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | 6 | // The module 'assert' provides assertion methods from node 7 | import * as assert from 'assert'; 8 | 9 | // You can import and use all API from the 'vscode' module 10 | // as well as import your extension to test it 11 | import * as vscode from 'vscode'; 12 | import * as myExtension from '../src/extension'; 13 | 14 | // Defines a Mocha test suite to group tests of similar kind together 15 | suite("Extension Tests", () => { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", () => { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "." 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your first VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * press `F5` to open a new window with your extension loaded 16 | * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` 17 | * set breakpoints in your code inside `src/extension.ts` to debug your extension 18 | * find output from your extension in the debug console 19 | 20 | ## Make changes 21 | * you can relaunch the extension from the debug toolbar after changing code in `src/extension.ts` 22 | * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes 23 | 24 | ## Explore the API 25 | * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` 26 | 27 | ## Run tests 28 | * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` 29 | * press `F5` to run the tests in a new window with your extension loaded 30 | * see the output of the test result in the debug console 31 | * make changes to `test/extension.test.ts` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.ts` 33 | * you can create folders inside the `test` folder to structure your tests any way you want --------------------------------------------------------------------------------