插件市场
/
插件详情
CloudStudio-GitBlame
CloudStudio GitBlame 插件,显示某一行上一次提交信息
codingide / cs-plugin-gitblame
(6 人评分)
评分

Cloud Studio Git Blame 插件

插件功能

这是一个轻量级的 Git Blame 插件,当光标移动到某一行的时候会显示改行代码上一次的提交信息,包括提交人、邮箱、提交信息以及时间。

图片

实现原理

在编辑器被激活时需要获取到文件的所有 git blame,调用 git 模块下的 gitBlame 即可。但因为这是针对具体某一行的操作,所以还需要获取到编辑器被激活时光标所在的行。

class GitBlameManager extends Manager {
  constructor() {
    super();
  }

  pluginWillmount() {
    editor.registerActiveEditorChangeHandler(this.handleEditorActive);
  }

  // gitBlame 返回一个 Promise,使用 async function
  handleEditorActive = async ({ uri, editor }) => {
    this.filePath = uri;
    this.activeEditor = editor;
    // 根据文件路径获取 CS 文件系统的 Filenode,若不存在,则返回
    const fileNode = file.getFileNode(uri);
    if (!fileNode) return;

    if (fileNode.isSynced) {
      // 获取所有 gitBlame
      const blames = await git.gitBlame(uri);
      // 获取编辑器光标位置 { lineNumber: number, column: number }
      const position = editor.getPosition();
    }
  }
}

gitBlame 只会返回上一次提交的所有 commitId (短 Id),要获取提交的信息,还要根据这个 commitId 获取文件指定 ref 的 logs,具体来说就是调用 git.gitFileLogs({ filePath: uri, ref: commitId })

同时需要在光标每次改变时获取新的光标所在行上一次提交信息,也就是说光标位置被改变时,要重复进行上述的逻辑。

// 清除上一次遗留的事件
if (this.disposable) {
  this.disposable.dispose();
}
// 监听光标改变事件
this.disposable = editor.onDidChangeCursorPosition((e) => {
  const { position: { lineNumber } } = e;
  if (lineNumber !== this.activeLineNumber) {
    this.activeLineNumber = lineNumber;
    this.applyLineCommitDecorations();
  }
});

我们编写一个方法 this.applyLineCommitDecorations 来做这件事。同时将 uri,当前行以及 gitBlame 等信息缓存下来。

/** 省略部分代码 */
// 因为要获取文件指定 ref 的 logs 同样使用 async function
applyLineCommitDecorations = async () => {
  const fileLogs = await git.gitFileLogs({ filePath: this.filePath, ref: blame.shortName });

  // gitFileLogs 可以指定 ref 为某次 commitId,这样可以获取到从指定的提交到最早的提交的一个区间,而我们需要的就是第一条记录,就是我们指定的这条 commit 信息
  if (fileLogs[0]) {
    const { author: { name, emailAddress, when }, message, date } = fileLogs[0];
    // 根据提交记录拼接出要在编辑器显示的字段
    const blameMessage = `${name}-${emailAddress}, ${date.toLocaleDateString()}-${date.toLocaleTimeString()}·${message}`;
    // 拼接出编辑器装饰块的 css 类名
    const className = `cs-gitblame-${fileLogs[0].id}-${this.activeLineNumber}-${when}`;
    // 获取编辑器的文本模型
    const textModel = this.activeEditor.getModel();
    // 获取当前被激活行的最大列宽,因为我们将在行尾插入提交信息
    const lineMaxColumn = textModel.getLineMaxColumn(this.activeLineNumber);

    // 使用两个帮助函数在页面中插入一个 style 标签,同时写入装饰块的样式信息
    addStyleRule(multiline`.${className}::after {
      content: "${blameMessage}";
      font-style: normal;
      font-weight: normal;
      background-color: rgba(0, 0, 0, 0);
      color: rgba(153, 153, 153, 0.35);
      text-decoration: none;
      margin-left: 50px;
    }`);

    const tmpDecorations = this.oldDecorations;
    // 第一个参数用于清除旧的装饰块
    this.oldDecorations = this.activeEditor.deltaDecorations(
      tmpDecorations || [],
      [
        {
          // 这表示当前行的范围
          range: new monaco.Range(
            this.activeLineNumber,
            lineMaxColumn,
            this.activeLineNumber,
            lineMaxColumn,
          ),
          options: {
            // afterContentClassName 表示装饰块会被插入在行尾,实际上这个行尾由 range 决定
            afterContentClassName: className,
          },
        },
      ],
    );
  }
}

参考资料

<!-- TODO -->

分类
Git 功能增强
更多信息
版本0.0.1
发布时间2018/11/14 14:29
分享给好友
使用微信扫描二维码
然后分享给好友
用户评价
暂无评价
联系我们
电话
400-930-9163
腾讯云开发者平台由腾讯云及 CODING 共同运营,目前由 CODING 团队提供运营服务。