Skip to content

Commit 2e4f21d

Browse files
committed
Refactor: Centralize Git logic in GitManager and implement real-time updates
- Introduce [GitManager](cci:2://file:///Users/max/dev/anycode/anycode-backend/src/git.rs:59:0-62:1) to centralize all Git operations and status caching - Refactor `git_handler` to delegate operations to [GitManager](cci:2://file:///Users/max/dev/anycode/anycode-backend/src/git.rs:59:0-62:1) via [AppState](cci:2://file:///Users/max/dev/anycode/anycode-backend/src/app_state.rs:16:0-24:1) - Implement push-based `git:status-update` events triggered by file watcher - Add robust `.gitignore` and `.git/` directory checking in watcher - Update frontend to listen for real-time git status updates - Remove obsolete `git_watcher` module - Polish `ChangesPanel` UI (revert button styles)
1 parent 607c18f commit 2e4f21d

10 files changed

Lines changed: 563 additions & 358 deletions

File tree

about_ru.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Технический обзор проекта anycode
2+
3+
**anycode** — это высокопроизводительная веб-IDE, предназначенная для написания, редактирования и управления кодом прямо в браузере. Проект создан с упором на скорость и поддерживает широкий спектр языков программирования.
4+
5+
## Технологический стек
6+
7+
### Бэкенд (Rust)
8+
9+
- **Tokio**: Асинхронный рантайм, являющийся стандартом для написания производительных сетевых приложений на Rust.
10+
- **Axum**: Минималистичный и мощный веб-фреймворк, используемый для маршрутизации HTTP-запросов.
11+
- **Socketioxide**: Реализация сервера `Socket.IO`, обеспечивающая надежную двунаправленную связь с клиентом в реальном времени.
12+
- **LSP-types**: Набор структур данных для удобной работы с протоколом LSP.
13+
14+
### Фронтенд (TypeScript/React)
15+
16+
- **React & TypeScript**: Основа для создания интерактивного и строго типизированного пользовательского интерфейса.
17+
- **Vite**: Современный сборщик, обеспечивающий практически мгновенную горячую перезагрузку модулей (HMR) и быструю сборку проекта.
18+
- **PNPM**: Эффективный менеджер пакетов, идеально подходящий для монорепозиториев благодаря своей системе хранения пакетов.
19+
20+
## Архитектура и взаимодействие компонентов
21+
22+
Проект имеет монорепозиторную архитектуру, управляемую с помощью `pnpm workspaces`. Это позволяет централизованно управлять зависимостями и упрощает взаимодействие между пакетами.
23+
24+
- `anycode-backend/` (Rust): Серверная часть, которая служит мостом между веб-интерфейсом и локальной системой пользователя. Фронтенд общается с бэкендом через **WebSockets** (с использованием `Socket.IO`), отправляя запросы на чтение/запись файлов, поиск, запуск терминала и взаимодействие с LSP.
25+
- `anycode-base/`: "Движок" редактора. Этот пакет не зависит от UI-фреймворков и содержит всю основную логику:
26+
- Управление состоянием редактора (текст, курсор, выделение).
27+
- Интеграция с `web-tree-sitter` для парсинга кода в реальном времени.
28+
- Реализация виртуализированного рендеринга для отображения только видимой части файла, что обеспечивает высокую производительность при работе с большими объемами кода.
29+
- `anycode-react/`: React-компонент, который оборачивает `anycode-base` и предоставляет ему React-контекст, управляя его жизненным циклом и событиями.
30+
- `anycode/`: Основное приложение, которое собирает все части вместе. Оно использует `anycode-react` для отображения редактора, а также реализует остальные элементы интерфейса (файловый менеджер, терминал) и логику их взаимодействия с бэкендом.
31+
32+
## Ключевые функции: детальный обзор
33+
34+
### Движок редактора
35+
36+
Ядро `anycode` — это собственный движок, построенный на базе `anycode-base`. Его ключевые особенности:
37+
- **Парсинг с помощью Tree-sitter**: Вместо использования простых регулярных выражений, редактор строит полное синтаксическое дерево (AST) кода. Это позволяет реализовать точную и быструю подсветку синтаксиса, а также является основой для более сложных функций анализа кода.
38+
- **Управление текстом**: Для эффективной работы с текстом используется библиотека `vscode-textbuffer`, которая оптимизирована для частых вставок и удалений, характерных для текстовых редакторов.
39+
40+
### Виртуализация рендеринга: как это работает
41+
42+
Ключ к производительности редактора при работе с большими файлами — это техника виртуализации. Вместо того чтобы наивно отображать тысячи DOM-узлов для каждой строки, `anycode` гарантирует, что в DOM всегда находится лишь небольшое, постоянное количество элементов.
43+
44+
1. **Viewport (Окно просмотра)**: Основная идея — рендерить только те строки, которые физически видны пользователю. Эта видимая область называется "viewport". Количество отображаемых строк вычисляется на основе высоты viewport и высоты одной строки. Например, если высота окна 800px, а высота строки 20px, в DOM будет находиться всего около 40 элементов строк плюс небольшой буфер.
45+
46+
2. **Spacers (Распорки)**: Чтобы полоса прокрутки браузера отражала реальный размер файла (а не только размер видимой части), используются два вспомогательных элемента-"распорки" (`div`):
47+
- **Верхний спейсер**: Располагается над видимыми строками. Его высота равна суммарной высоте всех строк, находящихся *выше* viewport.
48+
- **Нижний спейсер**: Располагается под видимыми строками. Его высота равна суммарной высоте всех строк *ниже* viewport.
49+
Эти спейсеры "растягивают" контейнер до полного размера файла, обеспечивая корректное поведение скроллбара.
50+
51+
3. **Динамическое обновление при скролле**: При прокрутке происходит следующее:
52+
- **Прокрутка вниз**: Строки, уходящие за верхнюю границу viewport, удаляются из DOM. На их место внизу добавляются новые строки, которые должны стать видимыми. При этом высота верхнего спейсера увеличивается, а нижнего — уменьшается.
53+
- **Прокрутка вверх**: Процесс обратный: строки, уходящие за нижнюю границу, удаляются, а сверху добавляются новые. Высота верхнего спейсера уменьшается, а нижнего — увеличивается.
54+
55+
Этот механизм гарантирует, что независимо от размера файла (будь то 100 строк или 100 тысяч строк), количество DOM-элементов остается постоянным, что и обеспечивает высочайшую производительность и отзывчивость интерфейса.
56+
57+
### Рендеринг и редактирование кода
58+
59+
Производительность редактора достигается за счет комбинации нескольких техник:
60+
61+
- **Высокоэффективное редактирование**: Процесс внесения изменений происходит в несколько этапов, каждый из которых максимально оптимизирован:
62+
1. **Обновление модели текста**: Изменение (вставка или удаление символа) сначала применяется к структуре данных в `vscode-textbuffer`.
63+
2. **Инкрементальный парсинг**: Далее информация об изменении передается в `tree-sitter`. Ключевое преимущество `tree-sitter` в том, что он является **инкрементальным парсером**. Ему не нужно заново анализировать весь файл. Он перестраивает только ту часть синтаксического дерева, которая была затронута изменением. Этот процесс занимает доли миллисекунд даже для очень больших файлов.
64+
3. **Обновление кеша и перерисовка**: После обновления дерева пересчитывается информация для подсветки затронутых строк. Эти данные обновляются в кеше строк, и редактор точечно обновляет только измененные DOM-элементы.
65+
66+
Благодаря такому подходу, где на каждом шаге избегается полная переобработка данных, редактирование кода ощущается мгновенным. В результате применения этих оптимизаций, таких как виртуализация, кеширование и инкрементальный парсинг, достигается исключительно плавное взаимодействие с редактором: курсор, выделение и скроллинг работают нативно, без задержек.
67+
68+
### Интеграция с Language Server Protocol (LSP)
69+
70+
Бэкенд на Rust выступает в роли клиента для различных языковых серверов (например, `rust-analyzer` для Rust, `gopls` для Go).
71+
1. Фронтенд отправляет информацию о действиях пользователя (например, наведение мыши на символ) на бэкенд.
72+
2. Бэкенд перенаправляет этот запрос соответствующему языковому серверу по стандартному протоколу LSP.
73+
3. Получив ответ (например, информацию о типе или документацию), бэкенд отправляет его обратно на фронтенд, который отображает подсказку.
74+
75+
### Встроенный терминал
76+
77+
Интегрированный терминал — это комбинация двух технологий:
78+
- **`Xterm.js`** на фронтенде: Мощная библиотека для эмуляции терминала в браузере, которая отвечает за рендеринг текста, обработку ввода и поддержку таких функций, как цвета и стили.
79+
- **`portable-pty`** на бэкенде: Rust-библиотека, которая создает на сервере настоящий псевдотерминал (pty) и подключает к нему системную оболочку (например, `bash` или `zsh`). Весь ввод и вывод из этой оболочки передается на фронтенд через WebSockets.

anycode-backend/src/app_state.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::code::Code;
44
use crate::config::Config;
55
use crate::lsp::LspManager;
66
use crate::acp::AcpManager;
7+
use crate::git::GitManager;
78
use socketioxide::{extract::{SocketRef, State}};
89
use std::collections::HashSet;
910
use tokio_util::sync::CancellationToken;
@@ -18,6 +19,7 @@ pub struct AppState {
1819
pub file2code: Arc<Mutex<HashMap<String, Code>>>,
1920
pub lsp_manager: Arc<Mutex<LspManager>>,
2021
pub acp_manager: Arc<Mutex<AcpManager>>,
22+
pub git_manager: Arc<Mutex<GitManager>>,
2123
pub socket2data: Arc<Mutex<HashMap<String, SocketData>>>,
2224
pub terminals: Arc<Mutex<HashMap<String, TerminalData>>>,
2325
}

0 commit comments

Comments
 (0)