Skip to content

Commit 4a09b10

Browse files
committed
Adds incl_suffixes in the settings
1 parent 9b39a3d commit 4a09b10

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Adds Go To Definition for `include` statements
1010
- Adds intrinsic support for `OpenACC` version 3.1
1111
- Adds sphinx autogenerated documentation
12+
- Adds `incl_suffixes` as a configuration option
1213

1314
### Changes
1415

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ All command line options are also available through the **options** file as well
157157
- `max_line_length` Maximum line length (default: none)
158158
- `max_comment_line_length` Maximum comment line length (default:
159159
none)
160+
- `incl_suffixes` Add more Fortran extensions to be parsed by the server
160161

161162
## Additional settings
162163

fortls/langserver.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# TODO: make FORTRAN_EXT_REGEX be able to update from user input extensions
21
# TODO: enable jsonc C-style comments
32
from __future__ import annotations
43

@@ -9,6 +8,7 @@
98
import traceback
109
from multiprocessing import Pool
1110
from pathlib import Path
11+
from typing import Pattern
1212

1313
# Local modules
1414
from fortls.constants import (
@@ -52,11 +52,11 @@
5252
LOGICAL_REGEX,
5353
NUMBER_REGEX,
5454
SQ_STRING_REGEX,
55+
src_file_exts,
5556
)
5657

5758
log = logging.getLogger(__name__)
5859
# Global regexes
59-
FORTRAN_EXT_REGEX = re.compile(r"\.F(77|90|95|03|08|OR|PP)?$", re.I)
6060
# TODO: I think this can be replaced by fortls.regex_patterns type & class
6161
TYPE_DEF_REGEX = re.compile(r"[ ]*(TYPE|CLASS)[ ]*\([a-z0-9_ ]*$", re.I)
6262
# TODO: I think this can be replaced by fortls.regex_patterns
@@ -94,13 +94,15 @@ def __init__(self, conn, debug_log=False, settings={}):
9494
self.link_version = 0
9595
self.source_dirs = set()
9696
self.excl_paths = set()
97-
self.excl_suffixes = []
97+
self.incl_suffixes: list[str] = []
98+
self.excl_suffixes: list[str] = []
9899
self.post_messages = []
99100
self.pp_suffixes = None
100101
self.pp_defs = {}
101102
self.include_dirs = []
102103
self.streaming = True
103104
self.debug_log = debug_log
105+
self.FORTRAN_SRC_EXT_REGEX: Pattern[str] = src_file_exts()
104106
# Intrinsic (re-loaded during initialize)
105107
(
106108
self.statements,
@@ -1491,6 +1493,9 @@ def __load_config_file_dirs(self, config_dict) -> None:
14911493
self.source_dirs = {i for i in self.source_dirs if i not in self.excl_paths}
14921494

14931495
def __load_config_file_general(self, config_dict) -> None:
1496+
self.incl_suffixes = config_dict.get("incl_suffixes", [])
1497+
# Update the source file REGEX
1498+
self.FORTRAN_SRC_EXT_REGEX = src_file_exts(self.incl_suffixes)
14941499
self.excl_suffixes = config_dict.get("excl_suffixes", [])
14951500
self.lowercase_intrinsics = config_dict.get(
14961501
"lowercase_intrinsics", self.lowercase_intrinsics
@@ -1535,7 +1540,7 @@ def __add_source_dirs(self) -> None:
15351540
self.source_dirs = set()
15361541
for root, dirs, files in os.walk(self.root_path):
15371542
# Match not found
1538-
if not list(filter(FORTRAN_EXT_REGEX.search, files)):
1543+
if not list(filter(self.FORTRAN_SRC_EXT_REGEX.search, files)):
15391544
continue
15401545
if root not in self.source_dirs and root not in self.excl_paths:
15411546
self.source_dirs.add(str(Path(root).resolve()))
@@ -1563,7 +1568,7 @@ def __get_source_files(self) -> list[str]:
15631568
if not os.path.isfile(p):
15641569
continue
15651570
# File extension must match supported extensions
1566-
if not FORTRAN_EXT_REGEX.search(f):
1571+
if not self.FORTRAN_SRC_EXT_REGEX.search(f):
15671572
continue
15681573
# File cannot be in excluded paths/files
15691574
if p in self.excl_paths:

fortls/regex_patterns.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
from __future__ import annotations
2+
13
import re
4+
from typing import Pattern
25

36
USE_REGEX = re.compile(
47
r"[ ]*USE([, ]+(?:INTRINSIC|NON_INTRINSIC))?[ :]+(\w*)([, ]+ONLY[ :]+)?",
@@ -125,3 +128,32 @@
125128
CLASS_VAR_REGEX = re.compile(r"(TYPE|CLASS)[ ]*\(", re.I)
126129
DEF_KIND_REGEX = re.compile(r"([a-z]*)[ ]*\((?:KIND|LEN)?[ =]*([a-z_]\w*)", re.I)
127130
OBJBREAK_REGEX = re.compile(r"[\/\-(.,+*<>=$: ]", re.I)
131+
132+
133+
def src_file_exts(input_exts: list[str] = []) -> Pattern[str]:
134+
"""Create a REGEX for which file extensions the Language Server should parse
135+
Default extensions are
136+
F F03 F05 F08 F18 F77 F90 F95 FOR FPP f f03 f05 f08 f18 f77 f90 f95 for fpp
137+
138+
Parameters
139+
----------
140+
input_exts : list[str], optional
141+
Additional Fortran, by default []
142+
143+
Returns
144+
-------
145+
Pattern[str]
146+
A compiled regular expression, by default
147+
'.(F|F03|F05|F08|F18|F77|F90|F95|FOR|FPP|f|f03|f05|f08|f18|f77|f90|f95|for|fpp)?'
148+
"""
149+
EXTS = ["", "77", "90", "95", "03", "05", "08", "18", "OR", "PP"]
150+
FORTRAN_FILE_EXTS = []
151+
for e in EXTS:
152+
FORTRAN_FILE_EXTS.extend([f"F{e}".upper(), f"f{e}".lower()])
153+
# Add the custom extensions for the server to parse
154+
for e in input_exts:
155+
if e.startswith("."):
156+
FORTRAN_FILE_EXTS.append(e.replace(".", ""))
157+
# Cast into a set to ensure uniqueness of extensions & sort for consistency
158+
# Create a regular expression from this
159+
return re.compile(fr"\.({'|'.join(sorted(set(FORTRAN_FILE_EXTS)))})?$")

test/test_source/pp/.pp_conf.json

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
{
2-
"lowercase_intrinsics": true,
3-
"use_signature_help": true,
4-
"variable_hover": true,
5-
"hover_signature": true,
6-
"enable_code_actions": true,
7-
"include_dirs": [
8-
"include"
9-
],
10-
"pp_suffixes": [
11-
".h",
12-
".F90"
13-
]
14-
15-
}
2+
"lowercase_intrinsics": true,
3+
"use_signature_help": true,
4+
"variable_hover": true,
5+
"hover_signature": true,
6+
"enable_code_actions": true,
7+
"incl_suffixes": [".h"],
8+
"include_dirs": ["include"]
9+
}

0 commit comments

Comments
 (0)