vim node plugin

VIM 플러그인을 node로 작성하는 방법에 대해 간단히 리포트한다. 기본적으로 지원하는 플러그인은 vimscript, python정도로 보이는데 작은 기능을 추가하려고하는데 언어까지 배우기는 뭐해서 방법을 찾아봤다. 플러그인의 기능을까지라고 할 수 있을진 모르겠지만 node를 통해 간단한 작업은 할 수 있다.

OSX를 기준으로 작성되었고 neovim을 사용하고 있다. 홈 디렉토리 안에 .vimrc파일이 설정일텐데 neovim에서는 .config/nvim/init.vim파일이 그 역할을 대신한다. 여튼 설정 파일을 열고 다음과 같이 추가해준다.

코드가 우아하진 않고 공유차원이 그러려니…

1
2
3
4
5
6
7
8
9
10
11
12
13
function CallNode(...) 
execute '%! node -e "require(\"$HOME/.config/node-connector\")[\"' . a:1 . '\"][\"' . a:2 . '\"]()"'
endfunction

function CallNodeWithEcho(...)
echom system('node -e "require(\"$HOME/.config/node-connector\")[\"' . a:1 . '\"][\"' . a:2 . '\"](\"' . a:3 . '\")"')
endfunction

nmap ,fj :<C-U>call CallNode("format", "json")<CR>
nmap ,fx :<C-U>call CallNode("format", "xml")<CR>
nmap ,trk :<C-U>call CallNodeWithEcho("translate", "en", getline("."))<CR>
nmap ,tre :<C-U>call CallNodeWithEcho("translate", "ko", getline("."))<CR>
nmap ,trj :<C-U>call CallNodeWithEcho("translate", "ja", getline("."))<CR>

CallNodeCallNodeWithEcho 함수가 있는데 후자는 결과 값을 VIM의 status bar에 표시해주는 역할을 한다.

아래 다섯개의 함수를 정의했는데 역할은 순서대로 다음과 같다.

  • formating json
  • formating xml
  • 영어로 번역
  • 한국어로 번역
  • 일본어로 번역

함수의 정의를 보면 알겠지만 단순히 node 스크립트를 로딩해서 실행하는 것이다.

$HOME/.config/node-connector node script를 로드하므로 이 파일을 작성해줘야한다.

node-connector.js

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
var pd = require('pretty-data').pd;
module.exports = {
format: {
json: function() {
let i = process.stdin, d = '';
i.resume();
i.setEncoding('utf8');
i.on('data', function(data) { d += data; });
i.on('end', function() {
try {
console.log(JSON.stringify(JSON.parse(d), null, 4));
} catch(ex) {
console.log(d);
}
});
},
xml: function() {
let i = process.stdin, d = '';
i.resume();
i.setEncoding('utf8');
i.on('data', function(data) { d += data; });
i.on('end', function() {
try {
console.log(pd.xml(d));
} catch(ex) {
console.log(d);
}
});
}
},
translate: {
en: function(text) {
this.tr('en', text);
},
ja: function(text) {
this.tr('ja', text);
},
ko: function(text) {
this.tr('ko', text);
},
tr: function(source, text) {
var https = require('https');

var client_id = ''; //TODO: use yours
var client_secret = ''; //TODO: use yours
var host = 'openapi.naver.com';
var port = 443;
var uri = '/v1/language/translate';

var data = require('querystring').stringify({
source: source,
target: source !== 'ko' ? 'ko' : 'en',
text: text
});

var options = {
host: host,
port: port,
path: uri,
method: 'POST',
headers: {
'X-Naver-Client-Id':client_id,
'X-Naver-Client-Secret': client_secret,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};

var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log(JSON.parse(chunk).message.result.translatedText);
});
});
req.write(data);
req.end();
}
}
};

번역 api를 서비스로 네이버 개발자용을 쓰고 있어서 이 부분은 각자 발급해서 본인 것을 쓰면 된다.

이제 문장이 있는 줄에서 영어로 번역을 원한다면 ,trk를 누르면 된다. json파일을 포맷팅하고 싶다면 ,fj 이런식이다. 오류가 발생하면 그대로 원본글 그대로를 보여주게 해놓았다.

더 참조가 필요하다면 필자의 셋업을 참조하도록한다. 보통 난 노트북을 새로 셋업할때 git을 깔고 처음으로 설정을 클론뜨도록 해두었다. vim은 터미널 환경의 반이니까.

https://github.com/deptno/.config

코드를 넘어