59 lines
2.9 KiB
Markdown
59 lines
2.9 KiB
Markdown
# Справка по интересным моментам в коде
|
||
## Функция получения версии `python` в `lsp.lua`
|
||
|
||
```lua
|
||
local function get_python_version()
|
||
local handle = io.popen("python --version 2>&1") -- Redirect stderr to stdout
|
||
if handle then
|
||
local result = handle:read("*a")
|
||
handle:close()
|
||
-- Check if the output contains a version number
|
||
local version = result:match("Python (%d+%.%d+%.%d+)")
|
||
if version then
|
||
return version
|
||
end
|
||
end
|
||
|
||
handle = io.popen("python3 --version 2>&1") -- Redirect stderr to stdout
|
||
if handle then
|
||
local result = handle:read("*a")
|
||
handle:close()
|
||
-- Check if the output contains a version number
|
||
local version = result:match("Python (%d+%.%d+%.%d+)")
|
||
if version then
|
||
return version
|
||
end
|
||
end
|
||
-- TODO: Add some exception handling if python not installed on user machine
|
||
return "Python 0.0.0"
|
||
end
|
||
```
|
||
Что тут есть примечательного:
|
||
- Получение данных, выполняя команду в shell оболочке системы с помощью
|
||
`io.popen`. *Важно*: Данная функция может работать не во всех ОС
|
||
- Функция выполняет команду, указанную в аргументе, и возвращает *файловый
|
||
дескриптор*, который можно использовать для чтения вывода команды (или
|
||
записи в нее)
|
||
|
||
Разберем флоу подробнее:
|
||
Если про `python --version` - все понятно, то вот:
|
||
```lua
|
||
2>&1
|
||
```
|
||
Уже надо прояснить:
|
||
- В UNIX-подобных системах есть три стандартных потока - `stdin` = 0; `stdout` = 1;
|
||
`strerr` = 2;
|
||
- По умолчанию `io.popen` передает только вывод `stdout` в handle, поэтому для обработки
|
||
ошибок, надо дополнительно захватывать поток `stderr`
|
||
- `2>&1` означает, что мы хотим перенаправить поток ошибок 2 в стандартный вывод 1;
|
||
- Это нужно для того, чтобы захватить не только вывод команды, но и возможные ошибки
|
||
(например если питон не установлен);
|
||
- `>&` - оператор перенаправления потоков.
|
||
|
||
Дополнительно:
|
||
`*a` внутри `read` - конструкция формата чтения файловых объектов в `Lua`. Они
|
||
указывают - как именно стоит читать данные из файла или потока. Помимо `a` есть
|
||
еще:
|
||
- `*a` - читать все содержимое
|
||
- `*l` - читать строку
|
||
- `*n` - читать число.
|