How to Instruct an AI Agent for People Who'd Rather Not Type

I'm a slow typist, so when programming I really need the autocomplete feature, to avoid typing a lot and making typos. When applying AI to my work, a major limitation is that the prompt input box of agent software lacks an autocomplete feature. That means when I want the assistant to fix this function or that function, I have to type out the full function or variable names, or copy them from elsewhere, instead of just typing the first 2-3 characters and pressing Tab as I do when working purely in a code editor. That's why I've always looked for a way to bring the code editor into my AI agent workflow, leveraging the editor's advantages, and I've found a workable approach.

Before discussing this method, I should reveal that the autocomplete need has already been partially solved by some command-line agents. For example, in Crush, Crush lets you call an external text editor to enter the prompt (with the shortcut Ctrl + o):

Crush-using-external-editor

Then I just need to configure the code editor as Helix to leverage its autocomplete of previously typed words, saving typing effort. In this case, Helix is detached from the project's source code context, so it can only suggest previously typed words, not functions or variables in the source code.


Cách chỉ dẫn trợ lý AI dành cho người ngại đánh chữ

Mình là người gõ chữ chậm nên khi lập trình, mình rất cần tính năng autocomplete, để khỏi phải gõ nhiều và gõ nhầm. Khi áp dụng AI vào công việc, có một hạn chế lớn là khung nhập prompt của các phần mềm agent không có tính năng autocomplete. Nghĩa là khi mình muốn trợ lý sửa hàm này hàm kia, mình phải gõ đầy đủ tên hàm tên biến, hoặc copy chúng từ bên ngoài vào, thay vì chỉ cần gõ 2-3 chữ đầu rồi bấm Tab như cách làm việc thuần tuý trên code editor. Vì vậy mình vẫn luôn tìm cách để có thể lôi được code editor vào quy trình làm việc với agent AI, tận dụng lợi thế của code editor và đã tìm được phương án tạm ổn.

Trước khi bàn đến phương pháp này thì cũng xin hé lộ là nhu cầu autocomplete cũng đã được giải quyết phần nào với một số agent ở chế độ dòng lệnh. Ví dụ trên Crush, Crush cho phép gọi text editor bên ngoài để nhập prompt (với phím tắt Ctrl + o):

Crush-using-external-editor

Khi đó mình chỉ cần cấu hình chọn code editor là Helix để tận dụng tính năng autocomplete một từ đã nhập trước đó để đỡ công gõ. Trong trường hợp này thì Helix bị tách ra khỏi ngữ cảnh source code của dự án nên nó chỉ gợi ý được từ đã nhập chứ không gợi ý được hàm biến trong source code.


Define UI comprising keyboard Shortcut in Blueprint for modern GTK apps

In previous posts, "Define UI comprising Dropdown in Blueprint for modern GTK apps" and "Define UI comprising ListView in Blueprint for modern GTK apps", I presented how to use list widgets in Blueprint. Now we look at a different, but more compact topic, the keyboard shortcut.

In a desktop app, the user is expected to do a lot of work with the keyboard alone, not always reaching for the mouse. So a good app should have many keyboard shortcuts. For example, a Ctrl+V to paste, a Ctrl+S to save, an F1 to show help, etc. Most GUI toolkits have built-in support for this. GTK is no exception. There are two ways to assign a keyboard shortcut to an action in GTK 4:

  • The simplest one is the application's accelerator, set via gtk_application_set_accels_for_action(). You define the action on the application (with the app. prefix), then call that function with a list of accelerator strings. But this is not declarative, you have to write code.
  • A more flexible way is to use a Gtk.ShortcutController, to which you add one or more Gtk.Shortcut objects. Each Shortcut binds a trigger (a key combination) to an action. This is what we will learn in this post, because it is declarative and we can describe the shortcut in the Blueprint file alongside the rest of the UI.


API tỉnh thành có dữ liệu chính thức sau đợt sát nhập

Tháng 7/2025, chính quyền có sự thay đổi mạnh về cấu trúc đơn vị hành chính, khi hủy bỏ cấp huyện và sáp nhập tỉnh với tỉnh, xã với xã. Tuy nhiên bảng mã cho các xã sau sát nhập vẫn chưa có chính thức sau nhiều tháng trời, chỉ tồn tại trong văn bản "Dự thảo". Cách đây mấy ngày, thì mình phát hiện dữ liệu đó đã được công bố chính thức trên website của Cục Thống kê nên đã cập nhật luôn thư viện vietnam-provincesAPI Tỉnh thành Việt Nam.

Đợt sát nhập tỉnh thành này có vẻ cũng bao gồm cả việc tổ chức lại bộ máy hành chính Trung ương. Lần trước, cơ quan cung cấp dữ liệu bảng mã tỉnh thành là Tổng cục Thống kê", hoạt động tại tên miền gso.gov.vn, nhưng nay cơ quan đó là "Cục Thống kê", hoạt động tại tên miền nso.gov.vn.


Define UI comprising ListView in Blueprint for modern GTK apps

In a previous post, "Define UI comprising Dropdown in Blueprint for modern GTK apps", I presented how to use DropDown in Blueprint. Now we go with a bit more complex example, with ListView widget.

This is the UI where ListView is used, in my CoBang app:

WiFi list

It shows a list of WiFi network config, for which user will pick to generate QR code. The list is accompanied with a search box, via which user will type part of Wi-Fi name to narrow down the list, to quickly find the needed Wi-Fi network.


Define UI comprising Dropdown in Blueprint for modern GTK apps

GTK is one of the GUI toolkits for building Linux desktop apps, notable for its modern visual look, and with some advanced developer experience features, like Inspector.

But one of the things that is still old-fashioned is its support for declarative UI. GTK allows developer to describe the UI separately from application code, but the language is XML which is too verbose, comparing to QT's QML or Slint. Fortunately, there is an new language, Blueprint, to describe UI for GTK app, which brings the same taste of QML, Slint to the table. But Blueprint is still young, not integrated to GTK yet (the files written in Blueprint must be compiled to Gtk.Builder XML) and the documentation is not rich enough.

This post shows you how to use Dropdown or other list widgets (like ListView, GridView) in Blueprint. The example use case and code is drawn from my application, CoBang.

List widgets follow Model-View-Controller pattern, to dislay a list of data with dynamic length. The widget is not used alone, but with other non-display components from GTK library:

...

Điểm mới của Python 3.14: Chế độ free-threading

Một điểm mới khác, khá quan trọng, của Python 3.14, nhưng không "đập vào mắt người dùng" là chế độ "free-threading". Đây là chế độ mà CPython tắt "Global Interpreter Lock" (GIL), một loại khóa trước đây dùng để ngăn chặn nhiều thread cùng truy cập, sửa đổi dữ liệu thuộc kiểu riêng của CPython. Nay với chế độ "free-threading" thì các thread được chạy song song thoải mái hơn (tốc độ xử lý của ứng dụng đa luồng cũng tăng lên).

Nếu bạn viết code Python, không cần phải quan tâm vì ở mức độ này không nhìn thấy GIL. Chỉ khi bạn viết extension cho Python bằng ngôn ngữ biên dịch (C, C++, Rust) thì mới phải động vào GIL. Khi CPython gỡ bỏ GIL, tương tự như ngã tư bỏ đi cảnh sát đứng phân luồng, thì tác giả các extension này phải tự đảm bảo code mình là thread-safe, tự áp dụng các phương tiện, chiêu thức khác để tránh code mình bị crash, deadlock trong môi trường đa luồng. Điều này lại là cơ hội tỏa sáng cho các extension viết bằng Rust. Một trong các điểm "ăn tiền" của Rust là "fearless concurrency". Rust có các luật kiểm tra ownership, lifetime chặt chẽ, có các phương tiện dành cho lập trình đa luồng giúp bạn tránh tối đa các lỗi hay gặp, khó mò trong lập trình đa luồng.

Free-threading

Mình có một extension, viết bằng Rust, để làm cho nó tương thích với "free-threading" thì cực kỳ dễ, chỉ cần khai báo gil_used = false, vì vốn từ đầu nó đã chạy mà không cần "xin" GIL rồi.

...

Lustre / Gleam: How to create modal popup

Modal dialog is a often used UI element, but in web tech, developers used to spend quite much effort to implement it, before the introduction of CSS frameworks like Bootstrap. It was tricky to position the dialog in the center of the window, to blur the content behind it. It was tricky to let user close the popup by clicking outside it.

It is until the HTML standard introduces the native <dialog> element. Now developers can create a modal popup with ease, except if their users are using Safari, which often lags behind the modern web features. Put Safari aside, now we see how to create the native modal popup in Lustre framework (Gleam language).

My use case is the post compose form of this blog. The original content is in Markdown. The form has a "Preview" button so that if I click it, a modal popup appears and loads the rendered HTML of that Markdown code.

Form

...

Khi một ngôn ngữ lập trình không có lệnh `return`

Từ khóa return quá quen thuộc khi nó có mặt trong hầu như mọi ngôn ngữ lập trình, không chỉ được dùng ở cuối hàm như một lẽ thường, nó còn được dùng ở giữa hàm khi cần dừng chạy hàm sớm khi gặp điều kiện nào đó, ví dụ:

async def process_mqtt_message(
    topic: str, payload: bytes, pg_session: AsyncSession, red: Redis[str]
) -> ActuatorProcessResult | NodeProcessResult | None:
    if m := REGEX_TOPIC_SN_ACTUATOR_STATUS.match(topic):
...