Viết plugin cho sublime text 3
Bài đăng này đã không được cập nhật trong 4 năm
SublimeText chắc không còn quá xa lạ với mọi người. Hôm nay mình sẽ hướng dẫn mọi người cách viết 1 plugin cho sublime text và có thể share cho người khác dùng chung.
Dĩ nhiên, thì sublime text của bạn phải có package control.
Sublime text được viết bằng C++ và Python, nên plugin của nó đương nhiên cũng sẽ được viết bằng Python, nhưng mình là 1 đứa mù tịt về Python, nên có vì sai sót mong mọi người bỏ qua.
Làm quen với 1 plugin mới
Cách tạo 1 plugin mới:
Tools > Developer > New Plugin
Khi đó, sẽ có 1 file được tạo ra:
import sublime
import sublime_plugin
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.insert(edit, 0, "Hello, World!")
- 2 dòng import này gần như là mặc định và giúp ta sử dụng method liên quan , bạn có thể xem thêm ở API Reference
- class name sẽ có dạng
Tên class + Command
sublime_plugin.TextCommand
chính là class sẽ được kế thừa, giúp chúng ra dùng được các method của class này(mình đoán là thế).def run(self, edit)
, nếu bạn muốn thực thi class này, thì sẽ cần 1 hàmrun
, các tham số đầu vào tùy thuộc xem class bạn kế thừa sẽ cần những gì, nhưng chắc chắn luôn cóself
- nội dung của method, trong ví dụ, thì sẽ là thêm text
Hello, World!
, vào vị trí đầu tiên của tab sublime bạn đang mở.
Khi lưu file, bạn sẽ thấy file được lưu tại /home/hatd/.config/sublime-text-3/Packages/User
, đặt 1 tên tùy thích.
Để thực thi class ExampleCommand
, bạn bấm
ctrl + `
sau đó gõ view.run_command("example")
, (example
chính là tên class đã nói ở trên, được chuyển từ camelcase sang snakecase và bỏ chữ Command), enter. Bạn sẽ thấy Hello, World!
được thêm vào vị trí đầu tiên của tab sublime mà bạn đang mở.
Trên đây là ví dụ lý thuyết về tạo mới và chạy 1 plugin. Còn giờ sẽ đi vào thực tế.
Ý tưởng
Dùng phím tắt, để lấy permanent link của dòng code mà con trỏ chuột đang trỏ vào, với branch là develop.
Giải quyết ý tưởng
Bình thường, để dẫn link của 1 dòng code, ví dụ https://github.com/hatd/MoreGit/blob/master/more_git_commands.py#L7
,chắc hẳn là bạn sẽ làm như sau:
- vào project trên github
- tìm đến file
- click vào số line trước dòng code
- copy url trên thanh address của trình duyệt
Khá là mất công.
Để giải quyết vấn đề này thì khá đơn giản:
tạo 1 url có dạng:
project_github_url + "/blob/develop/" + file_name + "#L" + dòng_của_con_trỏ_chuột
và cho vào clipboard
Thực hành
1. Tạo folder project và push lên github
(Viết 1 plugin và share cho người khác dùng được, thì khá là cool đúng không)
Bạn cần tạo 1 project(mình đặt là MoreGit
) trong folder mà bạn hay làm việc, init git và push lên github như bình thường.
Chuột phải vào project folder, chọn Make Link
(mình dùng ubuntu, còn ở hđh khác thì mình không chắc), sẽ tạo cho bạn 1 folder tên là Link to MoreGit
. Copy folder này vào /home/hatd/.config/sublime-text-3/Packages
. Và bây giờ, bạn chỉ cần code với folder MoreGit
, thì tự động plugin sẽ được load.
2. Code
Lần lượt tạo các file sau:
package-metadata.json
để package installer biết được project của bạn là 1 plugin để install hoặc update, thì cần file này.
{"platforms": ["linux"], "version": "1.0.3", "description": "More git", "url": "https://github.com", "dependencies": [], "sublime_text": ">=3211"}
ở đây chắc chỉ cần chú ý đến platforms: các hđh mà plugin hỗ trợ(sẽ nói ở đoạn sau), sublime_text: version của sublime mà plugin hỗ trợ, vì version thấp quá sẽ cần code phức tạp hơn
MoreGit.sublime-settings
Đây là file setting của plugin
{
"remote_name": "origin"
}
Vì 1 project có thể add nhiều remote, nên sẽ cần phải dùng 1 remote chính cho prject_github_url
. Remote name mặc định mình để là origin
more_git_commands.py
Đây sẽ là file chưa code
# tùy vào các method mình muốn mà sẽ import các module/library khác nhau
import os
import sublime
import sublime_plugin
import subprocess
import re
class CopyGitCommand(sublime_plugin.TextCommand):
def run(self, edit):
# lấy ra được đường dẫn đến file đang mở ở active tab của sublime
# sẽ có dạng /home/hatd/MoreGit/folder1/folder2/file_name
file_name = self.view.file_name()
# lấy được đường dẫn đến file
# /home/hatd/MoreGit/folder1/folder2/
dir_path = os.path.dirname(file_name)
# hash này là option dùng cho subprocess, sẽ nói ở dưới
kwargs = {}
kwargs["stdout"] = subprocess.PIPE
kwargs["cwd"] = dir_path
# lấy ra remote name được đặt trong setting
settings = sublime.load_settings("MoreGit.sublime-settings")
remote_name = settings.get("remote_name")
# subprocess là 1 lib của python, giúp ta chạy các câu lệnh giống như trên terminal
# https://docs.python.org/3/library/subprocess.html
# câu lệnh git config --get remote.remote_name.url sẽ giúp lấy được url đang đặt cho remote_name
# kwargs["stdout"] = subprocess.PIPE sẽ giúp đầu ra của câu lệnh .Popen giống như trên terminal
# kwargs["cwd"] = dir_path, subprocess sẽ luôn chạy ở thư mục ~/, nên bạn cần chỉ cho nó thư mục cần chạy, vì lệnh git phải chạy trong thư mục có init git đúng không?
remote = subprocess.Popen(["git", "config", "--get", "remote." + remote_name + ".url"], **kwargs).stdout.read()
if remote:
# self.view.sel() sẽ giúp bạn lấy ra list các vùng mà bạn đang chọn(sublime có tính năng chọn 1 vùng, xong bấm ctrl để chọn tiếp vùng khác ý)
# mình sẽ lấy ra vùng đầu tiên
current_selection = self.view.sel()[0]
# lấy ra row đầu tiên và row cuối cùng của vùng đang được chọn
(row_begin,_) = self.view.rowcol(current_selection.begin())
(row_end,_) = self.view.rowcol(current_selection.end())
# vì remote có thể là dùng http url, hoặc ssh, nên mình cần phải regex đoạn này, để tạo ra được url https://github.com/hatd/MoreGit
remote_url = re.sub("^git@.*:", "https://github.com/", remote.decode("utf-8")[:-5])
# câu lệnh git rev-parse --show-toplevel sẽ cho ra kết quả /home/hatd/MoreGit
top_level = subprocess.Popen(["git", "rev-parse", "--show-toplevel"], **kwargs).stdout.read().decode("utf-8")[:-1]
# giờ chỉ là việc replace, nối text bình thường
link = file_name.replace(top_level, remote_url + "/blob/develop")
link = link + "#L" + str(row_begin + 1)
# đoạn sẽ là lấy link theo block, nếu như bạn đang chọn 1 đoạn code, chứ không phải 1 dòng code
if row_begin != row_end:
link = link + "-" + str(row_end + 1)
# dòng này sẽ gắn url vào clipboard, và bạn có thể ctrl+v để parse url ra
sublime.set_clipboard(link)
else:
print("Please setting remote repo!!! Preference > Package Settings > MoreGit > Settings")
Main.sublime-menu
File này giúp bạn thêm option vào menu. Có khá nhiều loại menu, ở những vị trí khác nhau, bạn có thể tham khảo available_menus
Ở đây mình chỉ dùng Main menu (cái menu ở trên cùng)
[
{
"id": "preferences",
"children":
[
{
"caption": "Package Settings",
"mnemonic": "P",
"id": "package-settings",
"children":
[
{
"caption": "MoreGit",
"children":
[
{
"command": "edit_settings",
"args": {
"base_file": "${packages}/MoreGit/MoreGit.sublime-settings",
"default": "// Settings in here override those in \"MoreGit.sublime-settings\"\n\n{\n\t$0\n}\n",
},
"caption": "Settings"
},
{ "caption": "-" },
{
"caption": "Key Bindings",
"command": "edit_settings",
"args": {
"base_file": "${packages}/MoreGit/Default (${platform}).sublime-keymap",
"default": "// Key Bindings - User\n[\n\t$0\n]\n"
}
},
{ "caption": "-" },
{
"command": "open_file",
"args": {
"file": "${packages}/MoreGit/README.md",
},
"caption": "Help"
},
]
}
]
}
]
}
]
Bạn có thể tùy chọn các menu của riêng mình, nhưng ở đây mình chỉ muốn
Preferences > Package Settings > MoreGit
và có 2 option là:
-
Chỉnh sửa setting: là chỉnh sửa
remote_name
mặc định trong fileMoreGit.sublime-settings
. -
Chỉnh sửa phím tắt sẽ nói ở file tiếp theo
Để chỉnh sửa, thì chỉ cần copy nội dung ở base_file bên trái, dán sang bên phải, xong thay các giá trị mà các bạn muốn
Default (Linux).sublime-keymap
File này chứa các phím tắt dùng cho plugin của bạn
Ở đây, mình chỉ support cho linux, nên chỉ có 1 file này, nếu các bạn muốn cho nhiều hđh khác thì có thể tạo thêm Default (Mac).sublime-keymap
, Default (Window).sublime-keymap
, hoặc muốn cho tất cả, thì chỉ cần Default.sublime-keymap
[
{ "keys": ["alt+c"], "command": "copy_git" }
]
Mình gán phím alt + c
, với command copy_git
(đây chính là class name của mình, được chuyển từ camelcase sang snakecase).
Vậy là xong, giờ bạn chỉ cần trỏ chuột(hoặc chọn 1 block code), alt+c
để copy url của dòng code đó, và parse vào đâu đó.
3. Chia sẻ cho người khác dùng chung
Hãy push tất cả đống file vừa rồi lên github, và copy lấy url của project(https://github.com/hatd/MoreGit) và chia sẻ link cho bạn bè.
Và cách để sử dụng link đấy là:
- Thêm repository:
Ctrl+Shift+P
, tìmPackage Control: Add Repository
, parse url https://github.com/hatd/MoreGit và enter - Install package:
Ctrl+Shift+P
, tìmPackage Control: Install Package
, tìmMoreGit
và enter
Đấy là cách chia sẻ lên github, còn để public lên packageinstall.io như nào thì mình cũng chưa kịp tìm hiểu.
Qua bài viết này, mong các bạn có thể tạo được plugin cho riêng mình.
All rights reserved