Com*_*non 0 vim editor atom-editor
我正在处理几个大型的fortran代码文件,我遇到了一个棘手的问题,我想让内联注释全行注释.一行一行手动完成是荒谬的.除了字符串之外,感叹号后面的所有字符都是注释,并被编译器忽略.
那就是改变
x = 9 !initialize x
Run Code Online (Sandbox Code Playgroud)
至
x = 9
!initialize x
Run Code Online (Sandbox Code Playgroud)
如果它可以通过Fortran或实现,那将是很好的!.
代码示例 vim
subroutine sample_photon(e0,zz,sgam,ierr)
use EBL_fit
use constants
use user_variables, only : ethr,model
use internal, only : debug
implicit none
integer ierr,nrej,nrejmax,nrenorm
real(kind=8) e0,zz,sgam,de,emin,emin0 &
,etrans1,etrans2,aw1,aw2,aw3,gb,gb0,gbmax,gbnorm,rrr,gnorm1,gnorm2,gnorm3
real(kind=8) psran,sigpair,w_EBL_density
de=4.d0*e0
emin0=ame**2/e0 ! minimal required energy for EBL photon
if (emin0.ge.eirmax) then ! wrong kinematics
!!! write(*,*)'photon:',emin0,eirmax,e0
ierr=1
return
end if
nrej=0
nrejmax=3000 ! user-defined limit on the N of rejections
nrenorm=0
gbmax=0.d0
gbnorm=2.5d0 ! normalization factor for rejection
etrans1=1.d-6 ! parameters for 'proposal function'
etrans2=eirmin*(1.d0+zz)**1.25
! partial weights for different energy intervals for 'proposal function
! sample emin (= sgam/de) according to the 'proposal function';
! define 'rejection function' ( gb = f(emin) / f_proposal(emin) )
sgam=emin*de ! c.m. energy for gamma-gamma interaction
gb=w_EBL_density(emin,zz)*sigpair(sgam)*emin/gb0
! if (gb.gt.1.d0.and.nrenorm.eq.0) write(*,*)'sample_cmb(photon): gb=' &
! ,gb,nrenorm,emin,emin0,emin0/etrans2 !/1.d3
if (psran().gt.gb) then ! rejection
nrej=nrej+1 ! total number of rejections for current sampling
gbmax=max(gbmax,gb) ! maximal value for rejection function
if(nrej.gt.nrejmax)then ! too many rejections
if(gbmax.le.0.d0)then ! wrong kinematics
write(*,*)'photon: gbmax=0!!!'
ierr=1
return
else
! write(*,*)'nrej(gamma)>nrejmax',nrej,emin0/etrans2,nrenorm,e0/1.d12,gbmax
gbnorm=gbnorm*gbmax*2.d0 ! change normalization for the rejection function
gbmax=0.d0
nrenorm=nrenorm+1
nrej=0
endif
endif
goto 1 ! new try
end if
end subroutine sample_photon
Run Code Online (Sandbox Code Playgroud)
让我们逐步构建它,并从一个简单的替换开始,该替换将newline(\r)添加到任何注释前缀序列(!):
:%substitute/!\+.*$/\r&/
Run Code Online (Sandbox Code Playgroud)
这留下了尾随空格.我们也可以匹配它,并使用捕获组(\(...\))进行实际评论.这会删除空格:
:%substitute/\s*\(!\+.*$\)/\r\1/
Run Code Online (Sandbox Code Playgroud)
但它仍然匹配一行开头的注释,并在前面引入了一个额外的空行.我们可以添加一个lookbehind断言,该行不能以a开头!,但现在变得丑陋:
:%substitute/^\%(^[^!].*\)\@=.*\zs\s*\(!\+.*$\)/\r\1/
Run Code Online (Sandbox Code Playgroud)
相反,使用另一个Vim命令:global(或其倒置的姐妹:vglobal)更容易只匹配不是以开头的行!,然后应用:substitute那里:
:%vglobal/^!/substitute/\s*\(!\+.*$\)/\r\1/
Run Code Online (Sandbox Code Playgroud)
最后的要求是应保留字符串中的感叹号.这将添加另一个正则表达式,并将其集成到整体匹配中将非常困难,并且可能只是大约完成.幸运的是,通过语法高亮,Vim已经知道什么是Fortran字符串!
我的PatternsOnText插件有(其中包括)a :SubstituteIf/ :SubstituteUnlesscombo,只有在条件为真/假时才能进行替换.它依赖的库提供了一个包装器synIdAttr(),可以很容易地为Fortran字符串定义一个谓词:
function! IsFortranString()
return ingo#syntaxitem#IsOnSyntax(getpos('.'), '^fortranString')
endfunction
Run Code Online (Sandbox Code Playgroud)
然后,我们只需要更换:substitute与:SubstituteUnless+谓语:
:%vglobal/^!/SubstituteUnless/\s*\(!\+.*$\)/\r\1/ IsFortranString()
Run Code Online (Sandbox Code Playgroud)
没有插件(使用:help sub-replace-special和synstack()/ synIdAttr())也可以实现相同,但它会更复杂.