sublime 做一個變數翻譯外掛
目標
中文寫一個變數名, 滑鼠移上去呼叫命令能將中文單詞翻譯成變數名,要求能選擇是大駝峰小駝峰還是下劃線
開始
Tools > Developer > New Plugin...
import sublime
import sublime_plugin
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.insert(edit, 0, "Hello, World!")
首先思路就是先能取到滑鼠所在的單詞.
由於 sublime 是支援多游標的, view.sel()
會返回陣列
for region in self.view.sel():
print(region)
ctrl+~
開啟控制檯, 輸入view.run_command('example')
看列印結果。
tip:
sublime外掛最終的命令名是取類名的每個單詞,然後用下劃線拼接,最後去掉`command`字元而來.
如果類名修改為 `TestCommand`, 那麼應該輸入`view.run_command('test')`
如果類名修改為 `TestDevCommand`, 那麼應該輸入`view.run_command('test_dev')`
拿到滑鼠所在的位置, 可以透過view.word(regin)
拿到整個單詞的位置
現在程式碼如下:
for region in self.view.sel():
pass
selection = self.view.word(region)
print(selection)
呼叫 API
sublime 中只能使用內建的模組,所以使用urllib
, API 如下:
urllib.request.urlopen(url, data)
注意: 如果是get
請求第二個引數不用填,填了就代表是post
請求, 對於get
我們自己去拼接url
關於第三方翻譯平臺,我使用的是百度,因為在vscode
中我也做了一個一摸一樣的外掛,所以 API 就拿來用了。
請求第三方翻譯平臺程式碼:
import hashlib
import json
from urllib import request,parse
def translateBaidu(self, q, fromq, to):
appid = '20200921000570318'
secret = 'GLMeRH02ZIQHOCIPlJhW'
salt = random.random()
sign = appid + q + str(salt) + secret
url = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
data = {
"q": q,
"appid": appid,
"from": fromq,
"to": to,
"salt": str(salt),
"sign": hashlib.md5(sign.encode('utf-8')).hexdigest()
}
encodeddata = parse.urlencode(data)
print(encodeddata)
req = request.Request(url + '?' + encodeddata)
r = request.urlopen(req)
print(r)
字串整合
拿到翻譯後差不多是這樣的:
Aa bb cc
我們需要根據空格分隔單詞,然後拼接成大小駝峰等樣子。
def big_hump(self, s):
arr = enumerate(s.split())
arr = map(lambda x: x[1][0].upper() + x[1][1:], arr)
res = ''.join(list(arr))
return res
# aaBbCc
def small_hump(self, s):
def s1(x):
if x[0] == 0:
return x[1][0].lower() + x[1][1:]
else:
return x[1][0].upper() + x[1][1:]
arr = enumerate(s.split())
arr = map(s1, arr)
res = ''.join(list(arr))
return res
def underscore_hump(self, s):
arr = enumerate(s.split())
arr = map(lambda x: x[1].lower(), arr)
res = '_'.join(list(arr))
return res
這裡可以看到我們們英語水平有待提高,這也正是做這款外掛的原因。
提供選擇
做出大小駝峰和下劃線三種樣式後,需要提供給使用者選擇,這裡呼叫這個 API 出個彈窗
view.show_popup_menu(list, done_func, index)
最後
因為 sublime 不像 vscode 身家硬, 外掛上傳隨便寫, sublime package control 外掛想要給別人用還得稽核,
以下是全部程式碼, 儲存到%appdata%\Sublime Text\Packages\User
下面就好
%appdata%\Sublime Text\Packages\User
直接複製到資源管理器開啟就行,?
import sublime
import sublime_plugin
import re
from urllib import request,parse
import random
import hashlib
import json
class TranslateCommand(sublime_plugin.TextCommand):
word_list = []
region = None
# 定義異常處理
def handlingExceptions(code):
codes = {
"52001": "請求超時,檢查網路後重試" ,
"52002": "系統錯誤, 檢視百度翻譯官網公告",
"52003": "請檢查appid或者服務是否開通",
"54000": "必填引數為空",
"54001": " 簽名錯誤",
"54003": "訪問頻率受限",
"54004": "賬戶餘額不足 ",
"54005": "長query請求頻繁, 請降低長query的傳送頻率,3s後再試 ",
"58000": "客戶端IP非法",
"58001": "語言不支援",
"58002": "服務當前已關閉, 請前往管理控制檯開啟服務",
"90107": "認證未透過或未生效",
}
def on_done(self, index):
if index != -1:
self.view.replace(self.editor, self.region, self.word_list[index])
def big_hump(self, s):
arr = enumerate(s.split())
arr = map(lambda x: x[1][0].upper() + x[1][1:], arr)
res = ''.join(list(arr))
return res
# aaBbCc
def small_hump(self, s):
def s1(x):
if x[0] == 0:
return x[1][0].lower() + x[1][1:]
else:
return x[1][0].upper() + x[1][1:]
arr = enumerate(s.split())
arr = map(s1, arr)
res = ''.join(list(arr))
return res
def underscore_hump(self, s):
arr = enumerate(s.split())
arr = map(lambda x: x[1].lower(), arr)
res = '_'.join(list(arr))
return res
# 呼叫翻譯API
def translateBaidu(self, q, fromq, to):
appid = '20200921000570318'
secret = 'GLMeRH02ZIQHOCIPlJhW'
salt = random.random()
sign = appid + q + str(salt) + secret
url = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
data = {
"q": q,
"appid": appid,
"from": fromq,
"to": to,
"salt": str(salt),
"sign": hashlib.md5(sign.encode('utf-8')).hexdigest()
}
encodeddata = parse.urlencode(data)
req = request.Request(url + '?' + encodeddata)
r = request.urlopen(req)
try:
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
data = data['trans_result'][0]['dst']
word_list = data.split()
arr = []
if len(word_list) > 0:
arr.append(self.small_hump(data))
arr.append(self.big_hump(data))
arr.append(self.underscore_hump(data))
else:
arr.append(data)
return arr
except(IndexError, IndentationError):
print('json解析異常')
def run(self, editor):
self.editor = editor
word_index = -1;
for region in self.view.sel():
word_index = region
if word_index != -1:
selection = self.view.word(word_index)
self.region = selection
word = self.view.substr(selection)
res = re.search('[\u4e00-\u9fa5]', word)
if res:
data = self.translateBaidu(word, 'zh', 'en')
self.word_list = data
self.view.show_popup_menu(data, self.on_done, 0)
pass
如果sublime報錯, 那應該python檔案縮排出毛病了, ctrl+P
呼叫一下命令
Indentation: Convert to Tabs
再到Preferences->Key Bindings
, 繫結快捷鍵
{
"keys": ["alt+n"],
"command": "translate"
}