【问题标题】:Using Vim, how can I make CSS rules into one liners?使用 Vim,我怎样才能将 CSS 规则变成一个衬里?
【发布时间】:2009-09-14 17:19:03
【问题描述】:

我想想出一个 Vim 替换命令来转换多行 CSS 规则,比如这个:

#main {
      padding: 0;
      margin: 10px auto;
}

压缩成单行规则,如下所示:

#main {padding:0;margin:10px auto;}

我有大量的 CSS 规则占用了太多行,我无法确定要使用的 :%s/ 命令。

【问题讨论】:

  • +1 感谢您的提问。从 rampion 的回答中学到了很多!
  • 请看一下我在回答below 中提出的命令。欢迎对答案发表评论!

标签: css regex vim replace


【解决方案1】:

这是一个单行:

:%s/{\_.\{-}}/\=substitute(submatch(0), '\n', '', 'g')/

\_. 匹配任何字符,包括换行符,而\{-}* 的非贪婪版本,因此{\_.\{-}} 匹配一对匹配的大括号之间的所有内容,包括大括号。

\= 允许您替换 vim 表达式的结果,我们在这里使用 substitute() 函数从匹配的文本(submatch(0))中删除所有换行符 '\n'

逆向(将单行版本转换为多行版本)也可以作为单行来完成:

:%s/{\_.\{-}}/\=substitute(submatch(0), '[{;]', '\0\r', 'g')/

【讨论】:

  • 非常感谢。这太棒了。反之,如何将一堆单行 CSS 规则转换成多行格式?
  • 你不需要玩 \= 来做反向操作。一个简单的 :%s/[{;]/&\r/g | gg=G 绰绰有余。
【解决方案2】:

如果您位于规则的开头或结尾,V%J 会将其合并为一行:

  • 转到开始(或结束)大括号
  • 点击V进入可视模式
  • 点击% 匹配另一个大括号,选择整个规则
  • 点击J加入行列

【讨论】:

  • 这不是 vi 方式,而是 vim 方式
  • 谢谢,这真的很酷。现在我对视觉模式有了更好的理解。
  • 好吧,soulmerge,首先我想说vim 方式,但后来它 vi 方式,即使这个特定命令与普通@987654327 不兼容@(我什至不确定是不是)。
  • 它与普通的vi 不兼容。但是问题被标记为vim,我猜绝大多数人通常使用vim,所以答案应该是有用的。
  • 不过,这一次只能修复一个块。使用 :%s 将修复整个文件。
【解决方案3】:

试试这样的:

:%s/{\n/{/g :%s/;\n/;/g :%s/{\s+/{/g :%s/;\s+/;/g

这会在打开大括号和分号('{' 和 ';')后删除换行符,然后删除连接行之间的额外空格。

【讨论】:

    【解决方案4】:

    如果要更改文件,请转到rampion's solution

    如果您不想(或不能)更改文件,您可以使用自定义折叠,因为它允许选择显示折叠文本的内容和方式。例如:

    " {rtp}/fold/css-fold.vim
    " [-- local settings --]               {{{1
    setlocal foldexpr=CssFold(v:lnum)
    setlocal foldtext=CssFoldText()
    
    let b:width1 = 20
    let b:width2 = 15
    
    nnoremap <buffer> + :let b:width2+=1<cr><c-l>
    nnoremap <buffer> - :let b:width2-=1<cr><c-l>
    
    " [-- global definitions --]           {{{1
    if exists('*CssFold')
      setlocal foldmethod=expr
      " finish
    endif
    
    function! CssFold(lnum)
      let cline = getline(a:lnum)
      if     cline =~ '{\s*$'
          return 'a1'
      elseif cline =~ '}\s*$'
          return 's1'
      else
          return '='
      endif
    endfunction
    
    function! s:Complete(txt, width)
      let length = strlen(a:txt)
      if length > a:width
          return a:txt
      endif
      return a:txt . repeat(' ', a:width - length)
    endfunction
    
    function! CssFoldText()
      let lnum = v:foldstart
      let txt = s:Complete(getline(lnum), b:width1)
      let lnum += 1
      while lnum < v:foldend
          let add = s:Complete(substitute(getline(lnum), '^\s*\(\S\+\)\s*:\s*\(.\{-}\)\s*;\s*$', '\1: \2;', ''), b:width2)
          if add !~ '^\s*$'
              let txt .= ' ' . add
          endif
    
          let lnum += 1
      endwhile
      return txt. '}'
    endfunction
    

    我将字段的排序留作练习。提示:获取列表中 v:foldstart+1 和 v:voldend 之间的所有行,对列表进行排序,构建字符串,仅此而已。

    【讨论】:

      【解决方案5】:

      我不会直接回答这个问题,而是建议您重新考虑您的需求。我认为你的“坏”例子实际上是更好的例子。它更具可读性,更易于修改和推理。良好的缩进不仅在编程语言中非常重要,在 CSS 和 HTML 中也是如此。

      您提到 CSS 规则“占用了太多行”。如果您担心文件大小,您应该考虑使用 CSS 和 JS 压缩器,例如 YUI Compressor,而不是降低代码的可读性。

      【讨论】:

      • 这是一场宗教辩论。一些开发人员更喜欢一个衬里中的 css 规则,因为它可以更快/更容易地扫描和查找选择器。其他人更喜欢多行,因为当你比较时更容易看到发生了什么变化。
      【解决方案6】:

      进行这种转换的一种简便方法是运行以下命令 短命令:

      :g/{/,/}/j
      

      【讨论】:

        【解决方案7】:

        转到文件的第一行,并使用命令gqG 通过格式化程序运行整个文件。假设非空行的运行应该在整个文件中折叠。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-12-26
          • 2021-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-30
          • 2023-02-05
          相关资源
          最近更新 更多