hansec / fortran-language-server Goto Github PK
View Code? Open in Web Editor NEWFortran Language Server for the Language Server Protocol
License: MIT License
Fortran Language Server for the Language Server Protocol
License: MIT License
A deferred-length allocatable string of characters is not recognized, i.e., there is no suggestion for some_string
after using the following declaration:
character(:), allocatable :: some_string
The feature is part of the standard since Fortran 2003 but there seems to be relatively little documentation on it. I don't know of any other way of declaring it.
For Fortran code with preprocessing #ifdef
tags, false alarm such as sth. declared twice
will be issued.
Say for the following snippet, which is correct:
#ifdef nc
INTEGER, PARAMETER:: MaxNumberOfGrids=90000 !Max no. grids !TS changed to 90000 for large-scale simulation based on netCDF IO
#else
INTEGER, PARAMETER:: MaxNumberOfGrids=2000 !Max no. grids !HCW changed to 2000 from 10000 so prog can run on windows (2GB lim)
#endif
fortls
will give error information in the diagnostics panel:
Variable "MaxNumberOfGrids" declared twice in scope
Variable definitions are not detected when no space is present between the variable type and colon separators. Reported in ide-fortran issue 8. Examples below.
integer(4):: var1 ! Detected correctly
integer :: var2 ! Detected correctly
integer:: var3 ! Not detected
Consider this:
! please don't delete this subroutine
subroutine example()
implicit none
end subroutine
fortls seems to think everything starting from 't delete
is a string, even though the quote is inside a comment.
Hi,
consider the following example:
subroutine example()
implicit none
real(8), dimension(6), parameter :: eye3 = [1d0, 0d0, 0d0, 0d0, 1d0, 1d0]
end subroutine
This yields two warnings saying "Variable 0d0 declared twice in scope".
Oddly enough, there have to be at least three zeros in the array to trigger the warning.
Also, it doesn't get triggered for the ones.
Typically, a natural language is used when commenting code and symbol names are seldom used, so having autocomplete pop up for every word can get a bit annoying/distracting.
Could there be a setting to "disable autocomplete in comments"?
In a module, if you have something like:
MODULE MYMODULE
.... stuff ....
PRIVATE ! Here a comment to say all the stuff is private
PUBLIC MYSUB ! Here a comment tell MYOTHERSUB is private
CONTAINS
....
the visibility as default to private is not seen because the line starts with some spaces (fixed format) and then you have the error that all the words is the comments are tokenize as elements to be marked as public. The attached patch fixes this two issues by stripping the line before the visibility match and removing the inline comment before tokenizing to detect what is public/private.
0001-Correctly-detect-the-visibility-in-fixed-format-case.patch.txt
And do not worry, you can keep enjoying your vacations, I have installed the language server with python setup.py develop
so I can use my patched version for the moment...
It would be great if autocomplete could also suggest to me names from modules I haven't yet use
d.
On selecting this suggestion, the use-only statement for this name would then be added automatically.
Preferred order in the autocomplete should be:
I'm not sure off the top of my head if this is possible with LSP, I will try to do some research when I have a bit of time. Just putting the idea here in case anyone wants to think about it.
Parsing fails with visibility statements and other definitions in unnamed programs or #include
files when no enclosing scope is present but is required for valid Fortran, example below.
USE test_mod ! Throws error (needs enclosing scope)
type t_test ! Throws error on following visibility statement (needs enclosing scope)
integer i
end type t_test
INTERFACE ! Does not throw error but needs enclosing scope
SUBROUTINE test_sub()
END SUBROUTINE test_sub
END INTERFACE
public :: t_test ! Throws error when matching to definition
I just tried this package, and I got a parser error on https://github.com/chemfiles/chemfiles.f03/blob/29ecc3f0830c82172ab27bb9b7ae94a5b5eb1083/src/generated/cenums.f90.
Here is the debug output of the parser:
$ fortls --debug_parser --debug_filepath src/generated/cenums.f90
Testing parser
File = "src/generated/cenums.f90"
Detected format: free
=========
Parser Output
=========
Traceback (most recent call last):
File "/home/guillaume/.local/bin/fortls", line 11, in <module>
sys.exit(main())
File "/home/guillaume/.local/lib/python2.7/site-packages/fortls/__init__.py", line 77, in main
ast_new = process_file(contents_split, True, fixed_flag, True)
File "/home/guillaume/.local/lib/python2.7/site-packages/fortls/parse_fortran.py", line 456, in process_file
file_obj.add_variable(new_var)
File "/home/guillaume/.local/lib/python2.7/site-packages/fortls/objects.py", line 592, in add_variable
self.current_scope.add_child(new_var)
AttributeError: 'NoneType' object has no attribute 'add_child'
The file is not compilable on it's own, but must be included in another file, so that might be the origin of the issue.
When a visibility statement is present without a top level scope the parser fails, such as in an #include
file. Example below.
INTEGER(4) :: isvis
REAL(8) :: notvis
PRIVATE notvis
Currently, submodules are not supported by the language server. Adding initial functional support requires two things:
module points
type :: point
real :: x, y
end type point
interface
module function point_dist(a, b) result(distance)
type(point), intent(in) :: a, b
real :: distance
end function point_dist
end interface
end module points
submodule (points) points_a
contains
module function point_dist
distance = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
end function point_dist
end submodule points_a
Steps to reproduce in Atom:
Happens with incremental synchronization both on and off.
Fortls breaks and does not generate outline if you specify non-existing directories for mod_dirs in .fortls file. I encountered the problem synchronizing code with git between two computers, on which my library has different locations (relatively to the root folder).
Is it possible to neglect non-existent directories (so I can specify dirs for both machnies) or should I gitignore .fortls and prepare different ones for every machnie? Another solution would be possibility to specify absolute, not relative localization.
Greetings!
In langserver.py have extended the try catch block in def init_file(file path) to also include the two with statements. This handles utf-8 decoding errors in the PY3K relevant code:
`def init_file(filepath):
#
try:
if PY3K:
with open(filepath, 'r', encoding="utf-8") as fhandle:
contents = re.sub(r'\t', r' ', fhandle.read())
contents_split = contents.splitlines()
else:
with open(filepath, 'r') as fhandle:
contents = re.sub(r'\t', r' ', fhandle.read())
contents_split = contents.splitlines()
#
fixed_flag = detect_fixed_format(contents_split)
ast_new = process_file(contents_split, True, filepath, fixed_flag)
except:
return None
else:
# Construct new file object and add to workspace
tmp_obj = {
"contents": contents_split,
"ast": ast_new,
"fixed": fixed_flag
}
return tmp_obj`
I do not have a detailed understanding of FORMAT statements, but I have noticed that the / in the Format statement below affects syntax coloring in both Atom and VSCode, so I assume it might be a problem with fortran-language-server.
WRITE (out,1031) IMEGA,FFX,BREMS,(DX0(I),I=1,N1)
1031 FORMAT (1X,I4,' FFX,BREMS,DX0:',6(2X,1PE15.8), &
:,100(/,54X,4(2X,1PE15.8))) ! problem is / in this line
After the /, which is used to mark eor to start a new line of output, all of the fortran keywords like CALL, WRITE, SUBROUTINE, etc are colored incorrectly. This is in both VSCode and Atom.
Sorry, I am brand new to Atom and don't have the fls debugger output to send along with this report; I hope the above is enough to track down the problem.
I am about to begin work on a Fortran Language server for Visual Studio code. I wanted to know if your service works for VS code, so I can just fork it and move on from there.
Thank you.
Fahiz
All compilers provide the omp_lib
module when compiling with OpenMP support enabled, so fortls
should not search for a corresponding module file in the project directory.
So, similar to #2, below code gives a "not found" error:
#ifdef _OPENMP
use omp_lib
#endif
Often, we add comments above a function declaration to describe what it does, similarly to JavaDoc:
! This is an example subroutine. Call it whenever you want.
subroutine example()
implicit none
end subroutine
Could this be included in the hover text?
Sometimes, there may be multiple lines, like this:
! generuje modifikaci deform pro prvek CBAR na zatizeni PLOAD1
!
! vstupy:
! x ... generovane rezy - reletivni souradnice
! p ... linie zatizeni [px1,py1, ... ,py2,pz2]
! l ... delka prvku
! st ... transformacni matice prvku z lokalu do globalu
! cc ... smykove konstanty
! A,Iy,Iz,It ... prurezove charakteristiky
!
! vystupy:
! u ... matice u(length(x),[ux uy uz rx ry rz]) v globalnim SS elementu
pure function CBarDeformPload1(x, p, S, cc, L, A, Iy, Iz, It, E, G) result(u)
(sorry for the Czech). In this case, I would only include the top N (N=10?) lines.
I've also seen people put the comment below the declaration:
subroutine example2()
! This is a description of what example2() does
implicit none
although I'm not sure if this should be considered, it's not very common and personally, I would try to discourage it as it goes against patterns used in most other languages.
Fortran programs do not need to be enclosed in the PROGRAM
directive. When this directive is not present the parser fails due to the lack of an enclosing scope.
Example code:
INTEGER :: i
WRITE(*,*)i
END
BRIEF: the language server fails to detect the "block" structure.
VERSION: 0.6.2
example file:
program blockTest
implicit none
real, parameter :: x=1.1
block
integer, parameter :: x=2
end block
end program blockTest
The language server raises an error "Variable "x" declared twice in this scope".
Currently the language server supports 'only' a manually generated configuration file
for communicating the file hierarchy. With CMake it's possible to generate a compilation database with contains all flags, directories, etc. for
a given file. It would be nice for CMake user to add the reading of this database.
Add snippet support for common fortran blocks (if
, do
, etc.) and scope declarations (module
, subroutine
, etc.).
examples ($0 denotes cursor position)
if($0)then
end if
module $0
end module $0
Just having "go to definition" thanks to fortls is great!
However, if variable_hover was improved, that would be even better!
In this example:
subroutine test()
implicit none
real(8), dimension(3, 3) :: A
real(8), dimension(3, 3) :: B ! this is the matrix i'm going to transpose
A = transpose(B)
end subroutine
when I hover over B, could I get:
like this:
real(8), dimension(3, 3) ! this is the matrix i'm going to transpose
?
Hi,
Thanks for the module. I have a large f95 project - everything seems to parse fine except for one file (which works in the project). I'd appreciate any ideas - I've tried paring it down, removing intrinsic functions, removing comments, shortening var names, and renaming the file to a shorter name, but it still bombs.
Parsing failed for file "/Users/rab25/projects/noaa/asos/src/fortran/main/common/utils/StringConversionUtils.f95"
Fortran (fortls) /Users/rab25/projects/noaa/asos/
Here's the input/output for debug (seems to run through debug fine):
Ryans-MacBook-Pro:~ rab25$ python3 /Users/rab25/.atom/packages/autocomplete-fortran/python/parse_fortran.py -d --files=/Users/rab25/projects/noaa/asos/src/fortran/main/common/utils/StringConversionUtils.f95
module StringConversionUtils !!! MODULE statement(23)
Found visiblity statement, /Users/rab25/projects/noaa/asos/src/fortran/main/common/utils/StringConversionUtils.f95:28, private :: string_conversion_real, string_conversion_int, string_conversion_complex
Found visiblity statement, /Users/rab25/projects/noaa/asos/src/fortran/main/common/utils/StringConversionUtils.f95:29, private :: string_conversion_logical, string_conversion_int_1d, string_conversion_int_2d
interface string_conversion !!! INTERFACE statement(39)
module procedure string_conversion_real !!! INTERFACE-PRO statement(40)
module procedure string_conversion_int !!! INTERFACE-PRO statement(41)
module procedure string_conversion_complex !!! INTERFACE-PRO statement(42)
module procedure string_conversion_logical !!! INTERFACE-PRO statement(43)
module procedure string_conversion_int_1d !!! INTERFACE-PRO statement(44)
module procedure string_conversion_int_2d !!! INTERFACE-PRO statement(45)
end interface string_conversion !!! END scope(46)
function string_conversion_real(val) result (str) !!! FUNCTION statement(54)
real :: val !!! VARIABLE statement(55)
character(len=200) :: str !!! VARIABLE statement(56)
end function string_conversion_real !!! END scope(61)
function string_conversion_int(val) result (str) !!! FUNCTION statement(64)
integer :: val !!! VARIABLE statement(65)
character(len=200) :: str !!! VARIABLE statement(66)
end function string_conversion_int !!! END scope(71)
function string_conversion_complex(val) result (str) !!! FUNCTION statement(74)
complex :: val !!! VARIABLE statement(75)
character(len=200) :: str !!! VARIABLE statement(76)
end function string_conversion_complex !!! END scope(81)
function string_conversion_logical(val) result (str) !!! FUNCTION statement(84)
logical :: val !!! VARIABLE statement(85)
character(len=5) :: str !!! VARIABLE statement(86)
end function string_conversion_logical !!! END scope(94)
function string_conversion_int_1d(val) result (str) !!! FUNCTION statement(97)
integer, dimension(:) :: val !!! VARIABLE statement(98)
character(len=200) :: str !!! VARIABLE statement(99)
end function string_conversion_int_1d !!! END scope(104)
function string_conversion_int_2d(val) result (str) !!! FUNCTION statement(107)
integer, dimension(:,:) :: val !!! VARIABLE statement(108)
character(len=200) :: str !!! VARIABLE statement(109)
end function string_conversion_int_2d !!! END scope(114)
end module StringConversionUtils !!! END scope(116)
{"objs":{"stringconversionutils":{"name":"StringConversionUtils","type":1,"desc":"MODULE","fbound":[23,116],"mem":["string_conversion","string_conversion_real","string_conversion_int","string_conversion_complex","string_conversion_logical","string_conversion_int_1d","string_conversion_int_2d"]},"stringconversionutils::string_conversion_real":{"name":"string_conversion_real","type":3,"desc":"CHARACTER(len=200)","fbound":[54,61],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion_int":{"name":"string_conversion_int","type":3,"desc":"CHARACTER(len=200)","fbound":[64,71],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion_complex":{"name":"string_conversion_complex","type":3,"desc":"CHARACTER(len=200)","fbound":[74,81],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion_logical":{"name":"string_conversion_logical","type":3,"desc":"CHARACTER(len=5)","fbound":[84,94],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion_int_1d":{"name":"string_conversion_int_1d","type":3,"desc":"CHARACTER(len=200)","fbound":[97,104],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion_int_2d":{"name":"string_conversion_int_2d","type":3,"desc":"CHARACTER(len=200)","fbound":[107,114],"mem":["val","str"],"args":"val"},"stringconversionutils::string_conversion":{"name":"string_conversion","type":7,"fbound":[39,46],"mem":["string_conversion_real","string_conversion_int","string_conversion_complex","string_conversion_logical","string_conversion_int_1d","string_conversion_int_2d"]},"stringconversionutils::string_conversion_real::val":{"name":"val","type":6,"fdef":55,"desc":"REAL"},"stringconversionutils::string_conversion_real::str":{"name":"str","type":6,"fdef":56,"desc":"CHARACTER(len=200)"},"stringconversionutils::string_conversion_int::val":{"name":"val","type":6,"fdef":65,"desc":"INTEGER"},"stringconversionutils::string_conversion_int::str":{"name":"str","type":6,"fdef":66,"desc":"CHARACTER(len=200)"},"stringconversionutils::string_conversion_complex::val":{"name":"val","type":6,"fdef":75,"desc":"COMPLEX"},"stringconversionutils::string_conversion_complex::str":{"name":"str","type":6,"fdef":76,"desc":"CHARACTER(len=200)"},"stringconversionutils::string_conversion_logical::val":{"name":"val","type":6,"fdef":85,"desc":"LOGICAL"},"stringconversionutils::string_conversion_logical::str":{"name":"str","type":6,"fdef":86,"desc":"CHARACTER(len=5)"},"stringconversionutils::string_conversion_int_1d::val":{"name":"val","type":6,"fdef":98,"desc":"INTEGER","mods":[21]},"stringconversionutils::string_conversion_int_1d::str":{"name":"str","type":6,"fdef":99,"desc":"CHARACTER(len=200)"},"stringconversionutils::string_conversion_int_2d::val":{"name":"val","type":6,"fdef":108,"desc":"INTEGER","mods":[22]},"stringconversionutils::string_conversion_int_2d::str":{"name":"str","type":6,"fdef":109,"desc":"CHARACTER(len=200)"}},"scopes":["stringconversionutils","stringconversionutils::string_conversion_real","stringconversionutils::string_conversion_int","stringconversionutils::string_conversion_complex","stringconversionutils::string_conversion_logical","stringconversionutils::string_conversion_int_1d","stringconversionutils::string_conversion_int_2d"]}
Here's the code:
!> @brief Provides functionality for writing log messages of different importance
!! levels to a specified log file and standard out.
!!
!! @details Allowed levels are FATAL, ERROR, WARN, INFO, DEBUG, or TRACE. All log messages
!! will be printed with a timestamp (local time), log level indicator, and the
!! specified message. Log levels allow a developer to limit the messages printed
!! to the log without having to comment them out in the code. For instance, DEBUG
!! messages can be included in the code but only enabled when troubleshooting is
!! required.
!!
!! @copyright
!! THIS SOFTWARE AND ITS DOCUMENTATION ARE CONSIDERED TO BE IN THE PUBLIC
!! DOMAIN AND THUS ARE AVAILABLE FOR UNRESTRICTED PUBLIC USE. THEY ARE
!! FURNISHED "AS IS." THE AUTHORS, THE UNITED STATES GOVERNMENT, ITS
!! INSTRUMENTALITIES, OFFICERS, EMPLOYEES, AND AGENTS MAKE NO WARRANTY,
!! EXPRESS OR IMPLIED, AS TO THE USEFULNESS OF THE SOFTWARE AND
!! DOCUMENTATION FOR ANY PURPOSE. THEY ASSUME NO RESPONSIBILITY (1) FOR
!! THE USE OF THE SOFTWARE AND DOCUMENTATION; OR (2) TO PROVIDE TECHNICAL
!! SUPPORT TO USERS.
!!
!! @author Diana Kantor
!! Modified for use in TaskAPI by Ryan Berkheimer
module StringConversionUtils
implicit none
! Setting helper methods to private
private :: string_conversion_real, string_conversion_int, string_conversion_complex
private :: string_conversion_logical, string_conversion_int_1d, string_conversion_int_2d
!> Converts a non-string to a string, so that a user can
!! easily append a non-string into a log message without
!! having to use complicated string formatting.
!! <br/>
!! ex. `call log_info("This number, "//log_string(my_real)//", will print to the log."))`
!!
!! @param val The value to be converted to a string.
!! @return A string representation of the val passed in.
interface string_conversion
module procedure string_conversion_real
module procedure string_conversion_int
module procedure string_conversion_complex
module procedure string_conversion_logical
module procedure string_conversion_int_1d
module procedure string_conversion_int_2d
end interface string_conversion
contains
!> Converts a real to a string
!! @todo preserve the number of decimal places
function string_conversion_real(val) result (str)
real :: val
character(len=200) :: str
write(str,*) val
str = trim(adjustl(str))
return
end function string_conversion_real
!> Converts an integer to a string
function string_conversion_int(val) result (str)
integer :: val
character(len=200) :: str
write(str,*) val
str = trim(adjustl(str))
return
end function string_conversion_int
!> Converts a complex number to a string
function string_conversion_complex(val) result (str)
complex :: val
character(len=200) :: str
write(str,*) val
str = trim(adjustl(str))
return
end function string_conversion_complex
!> Converts a logical to a string
function string_conversion_logical(val) result (str)
logical :: val
character(len=5) :: str
if(val) then
str = 'True'
else
str = 'False'
endif
return
end function string_conversion_logical
!> Converts a 1-D integer array to a string
function string_conversion_int_1d(val) result (str)
integer, dimension(:) :: val
character(len=200) :: str
write(str,*) val
str = trim(adjustl(str))
return
end function string_conversion_int_1d
!> Converts a 2-D integer array to a string
function string_conversion_int_2d(val) result (str)
integer, dimension(:,:) :: val
character(len=200) :: str
write(str,*) val
str = trim(adjustl(str))
return
end function string_conversion_int_2d
end module StringConversionUtils
Generic type-bound procedures do not seem to appear in auto-complete.
For example,
ELEMENTAL LOGICAL FUNCTION is_not_in(this_set, value)
CLASS(small_set), INTENT(IN) :: this_set
INTEGER(i4), INTENT(IN) :: value
INTEGER(i4) :: i
is_not_in = .TRUE.
DO i = 1, this_set%size
IF (this_set%storage(i) == value) THEN
is_not_in = .FALSE.
ENDIF
ENDDO
END FUNCTION is_not_in
All variables appear to be viewed as in the MODULE scope rather than the FUNCTION scope.
Hi,
I've been able to get the settings for (Neo)vim for the Fortran Language Server using
LanguageClient
let g:LanguageClient_serverCommands = {
\ 'fortran': ['fortls', '--symbol_skip_mem', '--incrmental_sync', '--autocomplete_no_prefix']
\ }
Is it possible to add them to the Wiki/ Readme? Btw. I think that 'incrmental_sync' should be named
'incremental_sync' or? Atleast the help/ vscode repository both state that way.
When declaring a generic procedure interface, the generic interface having the same name as one of the contained procedures can trigger a Variable declared twice in scope
error from fortls
. I thought this may just be incorrect fortran (it definitely seems bad and confusing) but gfortran -c test.f03
compiles without errors and doesn't complain even with -Wall
specified (crayftn
also has no issues), so I think it must be acceptable. Not a massive issue as it doesn't cause parsing to fail, but detecting this specific case and demoting to a warning might be useful for agreement with the compiler.
module m_test
interface test_proc
module procedure test_proc
end interface test_proc
contains
subroutine test_proc( )
end subroutine test_proc
end module m_test
Hi,
this works
use myModule, only: [typing here offers me suggestions from myModule]
but this doesn't
use myModule, only : [typing here doesn't offer me anything]
Intel Fortran swallows the latter without complaining and I've also seen it in numerous slides/pieces of code.
I don't know, however, whether this is documented syntax. (Can you point me to the right location, so I can check next time before bothering you?)
Below function definition is valid Fortran.
module demo
contains
function func(i)
integer, intent(in) :: i
integer :: func
func = 2*i
end function func
end module demo
fortls
complains:
Variable "func" masks variable in parent scope
Installation with pip as instructed returns:
Processing ./fortran-language-server-0.3.4.tar.gz
Collecting future (from fortran-language-server==0.3.4)
Could not fetch URL https://pypi.python.org/simple/future/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661) - skipping
Could not find a version that satisfies the requirement future (from fortran-language-server==0.3.4) (from versions: )
No matching distribution found for future (from fortran-language-server==0.3.4)
Hopefully the above means something to someone
I have python 2.7.14 installed
Thanks, in anticipation
You can find the patch. It is is pretty simple, when the masking is detected, the information about the parent is added to the error list to be used in the related information of the error message. This allows direct access to the reference from with Visual Studio Code as shown on the attached screenshot.
I have a feature request for a persistent save of the file index on disk.
From my work with cquery at work I appreciate its feature for
storing the file index on a specified directory on exit. This enabled for 'faster' start up times of the server
for larger projects. Currently I'm doing just some small projects in Fortran as a hobby, but I can
imagine that with a large code base the startup of the server can take a significantly amount of time.
cquery-initialization-options stores a .json
file for each indexed file for inspection
or in a more binary format for faster startup times.
The first approach seem to be a nice feature for debugging purposes as well from my point of view.
First of all, thanks getting this started! In combination with your ide-fortran
package for Atom, we are getting the first free, usable, and not hopelessly cluttered IDE for Fortran for non-Windows systems!
Trying this combination, I came across some minor problems. Below is one:
The use of intrinsic modules, such as
use, intrinsic :: ieee_exceptions
gives a Module "" not found in project
error.
On windows VSCode passes URIs with the :
character escaped as %3A
for incremental change requests. This causes the change request to fail. See issue #1 for vscode-fortran-ls.
I'm happy to announce that I created a package for Emacs support for the language server.
You can find it on lsp-fortran. I had help from @yyoncho regarding
some debugging, so thank you again for helping me out.
Currently I'll try to get it on Melpa put that may take a while and I will report when
that's occurred.
Could you add a mention of the package in the README.md?
Dear Chris,
first of all thanks for developing and maintaining the language server and the atom ide for Fortran.
I'm frequently using the Fortran 2008 submodule construction in my code and am experiencing an issue with the outline feature of the atom ide which appears to be related to the language server. A frequently appearing part of my code looks like this
module test
implicit none
type test_type
integer :: i
end type test_type
interface test_submodule
module subroutine test_routine(L_input)
integer,intent(inout) :: L_input
end subroutine test_routine
end interface test_submodule
contains
subroutine test_routine_2()
! some code
end subroutine test_routine_2
end module test
The outline is just displaying the defined type correctly but neither the interface nor the subroutines defined in the main module. Instead the symbol for module appears. When I replace module subroutine in the interface with just subroutine everything is displayed correctly. I assume that the language server (or the ide) just detects the module statement instead of processing the whole module subroutine statement.
Thanks for looking into this!
Best,
Marco
When passing an array via on-the-fly construction using the [data_type:: a,b,c]
syntax to a function or subroutine, the tooltip gets confused. Each comma used in the array constructor skips to the next suggested function parameter. In the example picture below, the tooltip shows parameter b
, even though we are still in the array constructor of argument a
.
Dear Chris,
is it possible to recognize and highlight declarations by looking for ::
? I use library which defines it's own variable types and in that case highlighting fails. But if I use any attribute, than at least ::
is colored fine.
Test code:
program test
implicit none
integer :: a
real :: b
Vec :: vector
Vec, intent(in) :: vector_in
end program test
Below example compiles and works fine and should be valid Fortran.
program demo
character(len=*), parameter :: hhmmss = "i2.2,':',i2.2,':',i2.2"
character(len=*), parameter :: myformat = '(A,' // hhmmss // ')'
print myformat, 'Current time: ', 12, 5, 59
end program demo
fortls
raises an error in line 2:
Variable "':'" declared twice inside scope
I realise this is a non-standard extension, however, it's quite wide-spread and I prefer it to the percent symbol, simply because of much better readability.
type mytype
integer :: member1
integer :: member2
end type
type(mytype) :: mytypeInstance
mytypeInstance%member1 ! go to definition works fine here
mytypeInstance.member2 ! this is not recognised properly
It should at least be an option for people who have grown accustomed to this syntax.
Exactly what it sounds like. All but a few of the autocompletes (snippets included) come out lower case no matter what.
Hey,
i am in the process of setting up my FORTRAN IDE in Atom. Unfortunately the fortls seems not be running in my case. I installed Python37 and the fortran-language server with pip. In Atom i set the path of the executable to ..\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\fortls_init_.py. When I am adding the test_source no and opening the outline dialog I am getting the error msg 'No outline available' although a popup is indicating that fortls is running before. Do I miss smth?
Python 37
Fortranlanguageserver 9.2 (via pip)
atom-ide-ui 0.13.0
ide-fortran 0.30
language-fortran 2.1.7
Lines starting with the characters "block" are misidentified as block statements, causing issues with unclosed scopes and other problems. Reported by @unpairedbracket. See example code below.
SUBROUTINE foo()
INTEGER :: bar,blockVar
blockVar = bar + 1
END SUBROUTINE foo
Dear Chris,
thank you for the fortls and ide-fortran.
I run into a problem with non-english letters used in a code. When I modify a line containing special characters from my native language, which I use in comments, fortls gives me the following error:
Change request failed for file "<here is path to a file>": Could not apply change
Any idea if this can be repaired?
Greetings!
Hello there. I found that fortls might be unable to find and load external modules under Windows. After doing some simple debugging, I discovered the problem is in the langserver.path_from_uri function. While in Unix-like systems the last slash in “file:///“ denotes file system root, in Windows it will make the system fail to recognize the correct diver letter “invalid driver letter: /C:”. A simple fix would be adding a system detection (if os.name==“nt”) and do uri.split(“file:///“, 1) if it comes out to be Windows.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.