是否有一种有效的方法来编辑代码以使内联注释成为一个完整的注释

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)

Ing*_*kat 6

让我们逐步构建它,并从一个简单的替换开始,该替换将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-specialsynstack()/ synIdAttr())也可以实现相同,但它会更复杂.