NoteZ_技术博客 NoteZ_技术博客
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)

NoteZ_技术博客

前端界的小学生
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)
  • Web技术

  • Git笔记

  • Linux文档

  • Markdown

  • Nginx文档

  • Npm笔记

  • 技术文档

  • 其他文档

    • 解决 bash_wget 未找到命令的解决办法
    • CentOS7 常见问题应对,如何升级make和gcc版本
    • CodeMirror代码编辑器实现自定义提示功能增强版(支持搜索、调用接口查询提示内容)
      • 方式一
      • 方式二
    • CSS 滚动条样式
    • d3 svg 基本图形绘制
    • d3.js中update,enter,exit的概念
    • dat.gui 基本使用方法
    • echarts 使用案例(demo)
    • jsplumb 中文基础教程
    • Linux服务器(centos7)使用LibreOffice将Word转换PDF文档出现中文乱码或方格解决方法
    • npm install 报错 npm ERR code UNABLE_TO_VERIFY_LEAF_SIGNATURE npm ERR errno UNABLE_TO_VERIFY_LEA 解决
    • Npm 清除缓存
    • Npm设置淘宝镜像
    • NPS内网穿透安装方法
    • ThreeJs 基础入门
    • unable to verify the first certificate 原因及解决方法
    • vue 安装node-sass报错解决方案(缺少python2.7支持)
    • windows下安装 stable-diffusion-webui 步骤
    • yarn的安装与使用
    • 关于微信支付 WeixinJSBridge.invoke 、 wx.chooseWXPay使用方法
    • 内网穿透的几款工具汇总
    • 前端使用 swd-deploy 自动化部署项目到服务器
    • 常用工具集(utils.js)
    • 开源项目大杂烩
    • 微信小程序-APP生命周期与运行机制总结
    • 微信小程序踩坑之布局适配单位(rpx、px、vw、vh)
    • 服务器常用的状态码
    • 解决google浏览器翻译无法使用的问题
    • 解决使用 Gitalk 登录授权报错的问题
    • 解决在使用 stable-diffusion-webui 时,安装 gfpgan 失败的方案(windows下的操作)
    • 通过 js 进行 shapefile 文件解析渲染方法
    • 部署脚本 deploy.sh
    • Tauri打包慢或者报错问题解决方法
    • Ubuntu和Nginx搭配Certbot配置SSL证书https访问网站
    • Centos下yum无法正常使用
    • Linux 系统下通过 Let‘s Encrypt 生成免费 https 证书的步骤
    • Mongo 风格的查询对象映射到 SQL 查询的 Node.js 库 json-sql
    • CentOS7安装与卸载anaconda3基础步骤
  • 前端开发
  • 其他文档
NoteZ
2019-07-11
目录

CodeMirror代码编辑器实现自定义提示功能增强版(支持搜索、调用接口查询提示内容)

本文提供了一种解决上述两个问题的实现方式,不同的主要是handleShowHint这个方法,修改了一些提示逻辑。

# 方式一

具体代码如下:

handleShowHint() {
  const {modelData, modelPointsAttributes} = this.props.configureStore;
  const modelDataList = modelData.map(item => (item.modelId));
  const codeMirrorInstance = this.codeEditorRef.getCodeMirrorInstance();
  const cur = this.codeEditor.getCursor();
  const curLine = this.codeEditor.getLine(cur.line);
  const end = cur.ch;
  const start = end;
  let list = [];
  // 根据不同情况给list赋值,默认为[],即不显示提示框。
  const cursorTwoCharactersBefore = `${curLine.charAt(start - 2)}${curLine.charAt(start - 1)}`;
  if (cursorTwoCharactersBefore === '${') {
    list = modelDataList;
  } else if (cursorTwoCharactersBefore === '::') {
    const lastIndex = curLine.lastIndexOf('${', start);
    const modelId = curLine.substring(lastIndex + 2, start - 2);
    if (modelPointsAttributes[modelId]) {
      list = modelPointsAttributes[modelId];
    } else {
      list = [];
      this.props.configureStore.getModelPointsAttributes(modelId, this.handleHint);
    }
  } else {
    const lastStartIndex = curLine.lastIndexOf('${', start);
    const lastEndIndex = curLine.lastIndexOf('}', start);
    const lastColonIndex = curLine.lastIndexOf('::', start);
 
    if (start > lastStartIndex && (start <= lastColonIndex || lastColonIndex < lastStartIndex)) {
      const modelId = curLine.substring(lastStartIndex + 2, start);
      list = modelDataList.filter(item => (item.indexOf(modelId) !== -1));
      // eslint-disable-next-line
      return {list, from: codeMirrorInstance.Pos(cur.line, lastStartIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
    } else if (start > lastStartIndex && start > lastColonIndex && (start <= lastEndIndex || (lastEndIndex < lastColonIndex && lastEndIndex < lastStartIndex))) {
      const modelId = curLine.substring(lastStartIndex + 2, lastColonIndex);
      const pointAttrId = curLine.substring(lastColonIndex + 2, start);
      if (modelPointsAttributes[modelId]) {
        list = modelPointsAttributes[modelId].filter(item => (item.indexOf(pointAttrId) !== -1));
        // eslint-disable-next-line
        return {list, from: codeMirrorInstance.Pos(cur.line, lastColonIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
      }
    }
  }
  // eslint-disable-next-line
  return {list, from: codeMirrorInstance.Pos(cur.line, start), to: codeMirrorInstance.Pos(cur.line, end)};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

实现中使用如下代码请求所选模型下点:

this.props.configureStore.getModelPointsAttributes(modelId, this.handleHint);
1

具体实现在mobx的store中,不再贴相应代码。

注意

需要注意的是:我在项目里使用了mobx管理state,发请求的位置在store中,不在组件内,所以通过回调函数的形式当接口数据成功返回后调用this.handleHint来进行提示;

需要注意提供正确的提示框的位置,类似于下边的形式:

{list, from: codeMirrorInstance.Pos(cur.line, lastColonIndex + 2), to: codeMirrorInstance.Pos(cur.line, end)};
1

codemirror提供了一种基于Promise的异步提示方式,因为我发请求的操作不在组件里,所以没有使用,在可以的情况下,Promise的实现应该会更合适。

# 方式二

或者新建mode,为了方便,所以使用zzzz

(function(mod) {
	if (typeof exports == "object" && typeof module == "object") // CommonJS
		mod(require("../../lib/codemirror"));
	else if (typeof define == "function" && define.amd) // AMD
		define(["../../lib/codemirror"], mod);
	else // Plain browser env
		mod(CodeMirror);
})(function(CodeMirror) {
	"use strict";

	CodeMirror.defineMode("zzzz", function(config, parserConfig) {
		var jsonldMode = parserConfig.jsonld;
		var isOperatorChar = /[+\-*&%=<>!?|~^@]/;

		function parseWords(str) {
			var obj = {},
				words = str.split(" ");
			for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
			return obj;
		}

		// 关键字
		var keywords = parseWords("s ss sss");

		var type, content;

		function ret(tp, style, cont) {
			type = tp;
			content = cont;
			return style;
		}

		function tokenBase(stream, state) {
			var beforeParams = state.beforeParams;
			state.beforeParams = false;
			var ch = stream.next();

			if (ch == '"' || ch == "'") {
				state.tokenize = tokenString(ch);
				return state.tokenize(stream, state);
			} else if (ch == "." && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
				return ret("number", "number");
			} else if (ch == '[') {
				stream.skipTo(']');
				stream.eat(']');
				return ret("string", "string");
			} else if (/\d/.test(ch)) {
				stream.eatWhile(/[\w\.]/);
				return "number";
			} else {
				stream.eatWhile(/[\w\$_{}\xa1-\uffff]/);
				var word = stream.current();
				if (keywords && keywords.propertyIsEnumerable(word)) {
					state.beforeParams = true;
					return "keyword";
				}

				return null;
			}
		}

		function tokenString(quote) {
			return function(stream, state) {
				var escaped = false,
					next;
				if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)) {
					state.tokenize = tokenBase;
					return ret("jsonld-keyword", "meta");
				}
				while ((next = stream.next()) != null) {
					if (next == quote && !escaped) break;
					escaped = !escaped && next == "\\";
				}
				if (!escaped) state.tokenize = tokenBase;
				return ret("string", "string");
			};
		}

		return {
			startState: function() {
				return {
					tokenize: tokenBase,
					beforeParams: false,
					inParams: false
				};
			},
			token: function(stream, state) {
				if (stream.eatSpace()) return null;
				return state.tokenize(stream, state);
			}
		};

	});

	CodeMirror.registerHelper("hint", "zzzz", function(cm) {
		//自动补全
		var hintList = ['s', 'ss', 'sss'];

		var cur = cm.getCursor(),
			token = cm.getTokenAt(cur);
		var start = token.start,
			end = cur.ch
		var str = token.string

		var list = hintList.filter(function(item) {
			return item.indexOf(str) === 0
		})

		if (list.length) return {
			list: list,
			from: CodeMirror.Pos(cur.line, start),
			to: CodeMirror.Pos(cur.line, end)
		};
	});

	CodeMirror.defineMIME("text/x-zzzz", "zzzz");

});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#代码编辑#Code
上次更新: 2024/01/30, 00:35:17
CentOS7 常见问题应对,如何升级make和gcc版本
CSS 滚动条样式

← CentOS7 常见问题应对,如何升级make和gcc版本 CSS 滚动条样式→

最近更新
01
Gitea数据备份与还原
03-10
02
Linux 中使用 rsync 同步文件目录教程
03-10
03
Linux 使用 rsync 互相传输同步文件的简单步骤
03-08
更多文章>
Theme by Vdoing | Copyright © 2019-2025 NoteZ,All rights reserved | 冀ICP备2021027292号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式