如何让Vim像Visual Studio一样突出显示C++语法错误?

25

是否有可能让 gVim 实时高亮显示 C++ 语法错误(就像 Visual Studio 中的红色波浪线)?

2个回答

27

简短回答:可以,但无法像 IDE 那样流畅/立即。

长回答:虽然 IDE 内置了对一组(通常非常有限的)编程语言的支持(和解析器等),但 Vim 是一款通用编辑器,因此必须依赖外部工具进行语法检查。内置方法是执行 :make 并在快速修复列表中收到(语法或编译器)错误列表。有一些插件可以自动化这个过程;其中一个非常受欢迎的是Syntastic,支持多种语言。

但由于 Vim 必须调用外部可执行文件,并且几乎没有异步运行任务的支持,所以在看到错误之前会有更多的延迟。如果您不能没有 IDE 的功能,那么根据它们的优势使用两者都可以:Vim 用于超高效的文本编辑,IDE 用于代码导航、调试和编译。


-1

VIM多年来一直是我的选择,但当我意识到Sublime Text 3编辑器的实用性和易于扩展功能时,我转而使用它。

现在,我在Sublime Text中进行编辑并编译同一应用程序。我制作了一个语法高亮显示器,以更好地显示错误,并且如果您点击错误,则会将您带到发生错误的位置。

按照以下步骤,C++编程将比以前更加简单。

因此,在安装sublime_text并运行一次后,您将得到一个文件夹~/HOME/.config/sublime-text-3/。如果您不熟悉sublime_text,则可以将修改添加到此文件夹中~/HOME/.config/sublime-text-3/Packages/User。从现在开始,让我们称这个文件夹为$SUBLIME_CONFIG_DIR。在这里我要向您展示如何添加一个C ++构建系统以及如何对输出进行语法高亮

设置构建系统

通过将名为c++build.sublime-build的文件添加到$SUBLIME_CONFIG_DIR中,创建您的构建系统,并具有以下内容:

{
  "shell" : true,
  "cmd": ["make $file_base_name"],
  "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
  "selector": "source.c++",
  "working_dir": "${file_path}",
  "syntax" : "Packages/User/c++output.tmLanguage"
}

我将解释每一行的作用。 1. "shell":true 简单地表示 sublime 应该在调用文件时运行一个 shell 命令。 2. 当调用 build 时,cmd 将被执行。您可以使用 g++ 或其他任何东西代替 make。我在这里放置的构建配置是一个起点,您可以修改它并使其按照您的意愿进行操作。 3. selector 告诉 sublime 哪些文件将自动使用此构建(在本例中为所有 c++ 文件)。 4. workig_dir 我将其设置为当前目录,以使它更容易。 5. syntax 当您构建文件时,输出将显示为纯文本,没有语法高亮。在这里,我将使用 C++output.tmLanguage 文件,稍后我将解释如何使用它来获得更好的突出显示输出,以便更轻松地进行调试。 6. file_regex 匹配输出中的错误行,如果有错误,并且您双击错误,则会将您带到相应的文件。

添加新语法

添加新的语法高亮器到 Sublime Text 有多种方式。你可以使用 JSON 并将其转换为 PList,也可以直接使用 PList。为了简单起见,只需将以下内容复制到名为 c++output.tmLanguage 的文件中。在应用程序启动时,Sublime Text 会自动选择 tmLanguage 文件来对文件进行高亮显示。

内容应该如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>fileTypes</key>
  <array>
    <string>ssraw</string>
  </array>
  <key>name</key>
  <string>Mazanin</string>
  <key>patterns</key>
  <array>
    <dict>
      <key>match</key>
      <string>\b(error)\b</string>
      <key>name</key>
      <string>invalid.illegal</string>
    </dict>
    <dict>
      <key>match</key>
      <string>(warning|instantiation|note|required|candidate)</string>
      <key>name</key>
      <string>markup.quote</string>
    </dict>
    <dict>
      <key>match</key>
      <string>^.*:[0-9]+</string>
      <key>name</key>
      <string>support.variable.mazanin</string>
    </dict>
    <dict>
      <key>begin</key>
      <string>\[</string>
      <key>beginCaptures</key>
      <dict>
        <key>0</key>
        <dict>
          <key>name</key>
          <string>punctuation.definition.mazanin</string>
        </dict>
      </dict>
      <key>end</key>
      <string>\]</string>
      <key>endCaptures</key>
      <dict>
        <key>0</key>
        <dict>
          <key>name</key>
          <string>punctuation.definition.mazanin</string>
        </dict>
      </dict>
      <key>name</key>
      <string>comment.mazanin</string>
      <key>patterns</key>
      <array>
        <dict>
          <key>match</key>
          <string>\\.</string>
          <key>name</key>
          <string>source.mazanin</string>
        </dict>
      </array>
    </dict>
    <dict>
      <key>begin</key>
      <string>\(</string>
      <key>beginCaptures</key>
      <dict>
        <key>0</key>
        <dict>
          <key>name</key>
          <string>punctuation.definition.mazanin</string>
        </dict>
      </dict>
      <key>end</key>
      <string>\)</string>
      <key>endCaptures</key>
      <dict>
        <key>0</key>
        <dict>
          <key>name</key>
          <string>punctuation.definition.mazanin</string>
        </dict>
      </dict>
      <key>name</key>
      <string>storage.mazanin</string>
      <key>patterns</key>
      <array>
        <dict>
          <key>match</key>
          <string>\\.</string>
          <key>name</key>
          <string>source.mazanin</string>
        </dict>
      </array>
    </dict>
  </array>
  <key>scopeName</key>
  <string>source.cerr</string>
  <key>uuid</key>
  <string>ca03e751-04ef-4330-9a6b-9b99aae1c418</string>
</dict>
</plist>

记得将上面的uuid(字符串)替换为唯一的uuid。但是如何获得一个呢?打开Sublime控制台,输入以下内容:

import uuid
uuid.uuid4()

现在你基本上完成了。打开你的C++文件,在其上调用构建,你应该能够看到错误被突出显示并且可以点击,如下所示(我使用Dawn主题)。

This is the sample output for a simple program that fails with the error line wrapped

我个人更喜欢将输出错误的行包装起来并快速展开,因此我在$SUBLIME_CONFIG_DIR/Default (Linux).sublime-keymap中添加了这个快捷键映射:

[
  {
    "keys": ["ctrl+shift+l"], "command": "toggle_setting", "args": {"setting": "word_wrap"}
  }
]

现在,如果您按下ctrl+shift+l,您可以轻松地包装/取消包装输出。在大多数情况下,当错误很长且信息不太有用时,这更加有用。没有包装的上面的示例将如下所示:

With the error lines not wrapped

使用YAML

您也可以使用YAML来描述语法高亮规则,这样更加简洁且易于修改。但是,在Sublime中使用YAML语言前,您需要安装PackageDev。将以下文件放置在$ HOME /.config/sublime-text-3/Packages/User中,并用Sublime打开它。按F7键,即可生成语法文件。

# [PackageDev] target_format: plist, ext: tmLanguage
---
name: C++ Error Output
scopeName: source.boo
fileTypes: [boo]
uuid: 45319b4d-90f8-4ff1-9a66-c56ed5c408a4

patterns:
- include: '#pars'
- include: '#bracs'
- include: '#anglebracs'
- include: '#quotes'
- include: '#curlies'
- match: \b((e|E)rror)\b
  name: invalid.illegal
- match: (warning|instantiation|note|required|candidate)
  name: markup.quote
- match: ^[^\:\s]*(?=:)
  name: support.variable
- match: (?<=:)[0-9]+
  name: keyword.control

repository:
  bracs:
    name: markup.quote
    begin: \[
    beginCaptures:
      '0': {name: keyword}
    end: \]
    endCaptures:
      '0': {name: keyword}
    patterns:
    - include: $self
    - include: anglebracs
    - include: pars
  pars:
    name: variable.parameter
    begin: \(
    beginCaptures:
      '0': {name: keyword}
    end: (\)|$)
    endCaptures:
      '0': {name: keyword}
    patterns:
    - include: $self
    - include: anglebracs
  anglebracs:
    name: markup.raw
    begin: (?<!<)\<(?!\<)
    beginCaptures:
      '0': {name: keyword}
    end: \>
    endCaptures:
      '0': {name: keyword}
    patterns:
    - include: $self
    - include: pars
  quotes:
    name: markup.heading
    begin: 
    beginCaptures:
      '0': {name: keyword}
    end: 
    endCaptures:
      '0': {name: keyword}
    patterns:
    - include: $self
    - include: anglebracs
    - include: pars
    - include: bracs
  curlies:
    name: markup.list
    begin: \{
    beginCaptures:
      '0': {name: keyword}
    end: \}
    endCaptures:
      '0': {name: keyword}
    patterns:
    - include: $self
    - include: anglebracs
    - include: pars
    - include: bracs
...

你可以在这里找到颜色名称列表。


36
这并没有回答问题,问题是关于Vim的。 - Michael Younkin
1
虽然这个回答很有教育意义,但我同意它根本没有回答问题。 - THC
vim 提供类似的构建和错误高亮显示。 - edwinc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接