Модуль «Клиент LSP»

Модуль предоставляет множество языковых функций, таких как дополнение кода, навигация по коду или поиск ссылок на основе протокола языкового сервера.

Как только модуль будет активирован на странице модулей, в диалоге настройки Kate появится новый раздел под названием «Клиент LSP».

Структура меню

Далее, в описании пунктов меню, также приводятся соответствующие команды (если таковые имеются). В документации этих команд доступны дополнительная информация и интерпретация (они могут варьироваться в зависимости от используемого языка программирования). Фраза «текущий символ» относится к символу, соответствующему текущей позиции курсора, как это определено языком и реализацией сервера.

Клиент LSPПерейти к определению

[textDocument/definition] Перейти к определению текущего символа.

Клиент LSPПерейти к объявлению

[textDocument/declaration] Перейти к объявлению текущего символа.

Клиент LSPПерейти к определению типа

[textDocument/typeDefinition] Перейти к определению типа текущего символа.

Клиент LSPНайти ссылки

[textDocument/references] Найти ссылки на текущий символ.

Клиент LSPНайти реализации

[textDocument/implementation] Найти реализации текущего символа.

Клиент LSPПодсветить

[textDocument/documentHighlight] Подсветить ссылки на текущий символ в текущем документе.

Клиент LSPНаведение

[textDocument/hover] Информация о текущем символе при наведении.

Клиент LSPФорматировать

[textDocument/formatting] [textDocument/rangeFormatting] Форматировать текущий документ или текущий выделенный фрагмент.

Клиент LSPПереименовать

[textDocument/rename] Переименовать текущий символ.

Клиент LSPБыстрое исправление

[textDocument/codeAction, workspace/executeCommand] Рассчитывает и применяет быстрое исправление для диагностики в текущей позиции (или строке).

Клиент LSPПоказывать документацию в списке автодополнения

Показывать документацию по выделенному объекту в списке автодополнения.

Клиент LSPВключить справку сигнатуры при автодополнении

Также показывать справку сигнатуры в списке автодополнения.

Клиент LSPВключать объявление в ссылках

Запрашивать включение объявления символа при запросе ссылок.

Клиент LSPДобавлять скобки при дополнении функций

Автоматически добавлять пару скобок после автоматического дополнения названия функции.

Клиент LSPПоказывать информацию при наведении

Показывать информацию при наведении (указателя мыши). Независимо от значения этого параметра, запрос этих данных всегда возможно инициировать вручную.

Клиент LSPФорматировать при наборе

[document/onTypeFormatting] Форматировать части документа при наборе определённых символов пользователем. Например, при наборе символа переноса строки возможно создать отступ или выполнить любое другое действие, определяемое сервером LSP. Сценарии расстановки отступов в редакторе могут пытаться сделать то же самое (в зависимости от режима расстановки), поэтому не рекомендуется включать оба соответствующих параметра одновременно.

Клиент LSPДобавочная синхронизация документа

Отправлять для обработки сервером отдельные части документа во время редактирования, а не весь документ (если на сервере предусмотрена поддержка такого режима обработки).

Клиент LSPПодсвечивать место перехода

Предоставить временный визуальный сигнал после выполнения перехода (к определению, объявлению и так далее).

Клиент LSPПоказывать уведомления о диагностике

[textDocument/publishDiagnostics] Обрабатывать и показывать уведомления о диагностике, отправляемые сервером.

Клиент LSPПоказывать подсветку диагностики

Добавить подсветку текста для диапазонов, указанных в диагностике.

Клиент LSPПоказывать отметки диагностики

Отмечать в документе строки, указанные в диагностике.

Клиент LSPПерейти на вкладку диагностики

Перейти на вкладку диагностики в панели модуля.

Клиент LSPЗакрыть все не относящиеся к диагностике вкладки

Закрыть все вкладки, не относящиеся к диагностике (например, ссылки), на панели модуля.

Клиент LSPПерезапустить сервер LSP

Перезапустить сервер LSP текущего документа.

Клиент LSPПерезапустить все серверы LSP

Остановить все серверы LSP и затем перезапустить их.

Поддержка перехода к идентификаторам

Клиент LSP Client позволяет перейти к любому идентификатору в проекте или текущем файле. Чтобы перейти к какому-либо идентификатору в файле, воспользуйтесь панелью «Клиент LSP: структура идентификаторов», расположенной в правой части окна Kate. В этой панели приводится список всех идентификаторов, обнаруженных сервером в текущем документе.

Настройка структуры идентификаторов клиента LSP

По умолчанию все идентификаторы упорядочены по порядку в документе, но также возможно выполнить сортировку по алфавиту. Для этого следует щёлкнуть по панели правой кнопкой мыши и выбрать пункт «Сортировать по алфавиту».

По умолчанию панель отображает идентификаторы в виде дерева, но с помощью контекстного меню также возможно представить их в виде списка.

Поддержка глобального перехода к идентификаторам

Чтобы перейти к любому идентификатору в проекте, следует открыть диалог перехода с помощью комбинации клавиш Ctrl+Alt+p. При открытии диалог пуст, но по мере набора текста пользователем будут появляться соответствующие идентификаторы. Качество совпадений, а также возможности фильтрации зависят от используемого сервера. Например, clangd поддерживает неточную фильтрацию, а какой-либо другой сервер может не поддерживать эту возможность.

Другие возможности

Поддерживается команда переключения заголовка источника clangd. Чтобы переключить заголовок источника в проекте C или C++ следует либо выбрать пункт контекстного меню «Переключить заголовок источника», либо нажать клавишу F12.

Для быстрого перехода к идентификатору возможно навести указатель мыши на символ и затем использовать комбинацию Ctrl + левая кнопка мыши.

Настройка

На странице настройки модуля возможно установить стандартные значения некоторых перечисленных выше элементов меню. На этой странице также имеется поле, в котором возможно указать путь к файлу конфигурации сервера. Это файл JSON, который позволяет указать сервер LSP для запуска (и последующего обмена данными с помощью stdin/stdout). Для удобства включена конфигурация по умолчанию (она доступна на странице настройки модуля). Чтобы сделать дальнейшие пояснения доступнее, здесь приводится фрагмент этой конфигурации:

{
    "servers": {
        "bibtex": {
            "use": "latex",
            "highlightingModeRegex": "^BibTeX$"
        },
        "c": {
            "command": ["clangd", "-log=error", "--background-index"],
            "commandDebug": ["clangd", "-log=verbose", "--background-index"],
            "url": "https://clang.llvm.org/extra/clangd/",
            "highlightingModeRegex": "^(C|ANSI C89|Objective-C)$"
        },
        "cpp": {
            "use": "c",
            "highlightingModeRegex": "^(C\\+\\+|ISO C\\+\\+|Objective-C\\+\\+)$"
        },
        "d": {
            "command": ["dls", "--stdio"],
            "url": "https://github.com/d-language-server/dls",
            "highlightingModeRegex": "^D$"
        },
        "fortran": {
            "command": ["fortls"],
            "rootIndicationFileNames": [".fortls"],
            "url": "https://github.com/hansec/fortran-language-server",
            "highlightingModeRegex": "^Fortran.*$"
        },
        "javascript": {
            "command": ["typescript-language-server", "--stdio"],
            "rootIndicationFileNames": ["package.json", "package-lock.json"],
            "url": "https://github.com/theia-ide/typescript-language-server",
            "highlightingModeRegex": "^JavaScript.*$",
            "documentLanguageId": false
        },
        "latex": {
            "command": ["texlab"],
            "url": "https://texlab.netlify.com/",
            "highlightingModeRegex": "^LaTeX$"
        },
        "go": {
            "command": ["go-langserver"],
            "commandDebug": ["go-langserver", "-trace"],
            "url": "https://github.com/sourcegraph/go-langserver",
            "highlightingModeRegex": "^Go$"
        },
        "python": {
            "command": ["python3", "-m", "pyls", "--check-parent-process"],
            "url": "https://github.com/palantir/python-language-server",
            "highlightingModeRegex": "^Python$"
        },
        "rust": {
            "command": ["rls"],
            "path": ["%{ENV:HOME}/.cargo/bin", "%{ENV:USERPROFILE}/.cargo/bin"],
            "rootIndicationFileNames": ["Cargo.lock", "Cargo.toml"],
            "url": "https://github.com/rust-lang/rls",
            "highlightingModeRegex": "^Rust$"
        },
        "ocaml": {
            "command": ["ocamlmerlin-lsp"],
            "url": "https://github.com/ocaml/merlin",
            "highlightingModeRegex": "^Objective Caml.*$"
        }
    }
}

Обратите внимание, что каждая запись «command» может быть массивом или строкой (в этом случае она будет поделена на записи массива). Кроме того, также учитывается запись верхнего уровня «global» (рядом с записью «server»); подробнее об этом далее. Поиск указанного исполняемого файла выполняется обычным способом, то есть с помощью переменной PATH. Если исполняемый файл установлен в каком-либо нестандартном расположении, может потребоваться развернуть соответствующий путь. В расположении, которое хранится в обычной переменной PATH, можно воспользоваться (символической)ссылкой или сценарием-обёрткой. Как показано выше, также можно указать «path» (расположение, в котором будет выполнен поиск после стандартных мест).

Во всех записях «command», «root» и «path» будет выполняться расширение переменных.

Инструкцией «highlightingModeRegex» можно воспользоваться для привязки режима подсветки, который используется Kate, к идентификатору языка сервера. Если регулярное выражение не указано, используется сам идентификатор языка. Если запись «documentLanguageId» установлена в значение «false», идентификатор языка не предоставляется серверу при открытии документа. Это может подойти для серверов, которые определяют тип документа точнее, чем способ на основе режима Kate.

Кроме того, каждый объект записи сервера может также иметь запись «initializationOptions», данные которой передаются серверу как часть метода «initialize». Если такая запись присутствует, данные записи «settings» будут переданы серверу с помощью уведомления «workspace/didChangeConfiguration». Как «completionTriggerCharacters», так и «signatureTriggerCharacters» можно указать как объект JSON со строковыми участниками «exclude» и/или «include». Они будут использоваться, соответственно, для исключения или добавления символов в соответствующий набор переключателей, который предоставляется сервером.

Применяются различные этапы переопределения и слияния.

  • Пользовательская конфигурация (загруженная из файла) переопределяет (внутреннюю) конфигурацию по умолчанию

  • Запись «lspclient» в конфигурации проекта .kateproject переопределяет предыдущие записи

  • Полученная в результате обработки запись «global» используется как дополнение (не переопределение) любой из записей сервера

Для каждой комбинации (root, servertype) используется один экземпляр сервера. Если значение «root» указано как абсолютный путь, оно используется без обработки. В противном случае оно считается указанным относительно «projectBase» (как определено в модуле проектов), если это применимо, или иным образом связанным с каталогом документа. Если значение не указано и «rootIndicationFileNames» представляет собой массив имён файлов, то выбирается родительский каталог текущего документа, содержащий такой файл. Альтернативный вариант (если не указано значение «root» и «rootIndicationFilePatterns» представляет собой массив шаблонов имён файлов) — выбирается родительский каталог текущего документа, соответствующий шаблону имени файла. Последний резервный вариант для «root» — домашний каталог пользователя. Полученное в результате такой обработки значение «root» определяет, требуется ли для документа отдельный экземпляр сервера. Если такой экземпляр нужен, значение «root» будет передано как rootUri/rootPath.

Рекомендуется не указывать значение root, так как оно не так важно для сервера (хотя ситуации могут быть разными). Если экземпляров сервера будет немного, они будут работать эффективнее и обеспечивать «более широкое» поле зрения, чем в случае использования многих отдельных экземпляров сервера.

Как упоминалось ранее, в некоторых записях выполняется расширение переменных. Использование этой возможности в сочетании со «сценарием-обёрткой» позволяет гибко подстроиться к самым разным обстоятельствам. Например, рассмотрим сценарий разработки Python, состоящий из нескольких проектов (например, репозиториев git), каждый из которых имеет свою виртуальную среду. При использовании стандартной конфигурации у сервера языка Python не будет информации о виртуальной среде. Но это можно исправить следующим образом. Сначала следует ввести следующий текст в поле «Параметры сервера пользователя» модуля клиента LSP:

{
        "servers":
        {
                "python":
                {
                        "command": ["pylsp_in_env", "%{Project:NativePath}"],
                        "root": "."
                }
        }
}

Корневая запись выше относится к каталогу проекта и обеспечивает запуск отдельного языкового сервера для каждого проекта (что необходимо в этом случае, так как каждый проект имеет собственную уникальную виртуальную среду).

pylsp_in_env — это небольшой «сценарий-обёртка», который следует поместить в PATH со следующим (требует редактирования) содержимым:

#!/bin/bash
cd $1
# запустить сервер (python-lsp-server) в виртуальной среде
# (т.е. с заданными переменными виртуальной среды)
# поэтому источником будет виртуальная среда
source XYZ
# сервер и аргументы могут быть разными
exec myserver

Это только один из примеров более общего шаблона, с которым может быть немного удобнее работать (описание доступно в разделе Среда выполнения ниже).

Конфигурация сервера LSP

Каждый сервер LSP имеет свой собственный способ настройки; для конфигурации могут использоваться средства, специфичные для языка или инструмента, например, tox.ini (в том числе для python), .clang-format для форматирования в стиле C++. Такая конфигурация затем может также использоваться другими (отличными от LSP) инструментами (такими как tox или clang-format). Кроме того, некоторые серверы LSP загружают конфигурацию из пользовательских файлов (например, .ccls). Более того, настраиваемая конфигурация сервера также может быть передана с помощью LSP (протокол): смотрите вышеупомянутые записи «initializationOptions» и «settings» в конфигурации сервера.

Поскольку применяются различные уровни переопределения и слияния, в приведённом далее примере определённые пользователем параметры конфигурации клиента корректируют некоторые из параметров конфигурации python-language-server.

{
    "servers": {
        "python": {
            "settings": {
                "pyls": {
                    "plugins": {
                        "pylint": {
                            "enable": true
                        }
                    }
                }
            }
        }
    }
}

К сожалению, конфигурация сервера LSP зачастую не очень хорошо документирована, поэтому только изучение исходного кода позволяет найти способы настройки и набор доступных параметров конфигурации. В частности, сервер из приведённого выше примера поддерживает намного больше параметров в «settings». Ознакомьтесь с документацией другого клиента LSP, содержащей примеры серверов других языков и соответствующие параметры настройки, которые возможно легко и просто преобразовать в конфигурацию JSON, которая описана в этом руководстве.

Форматирование при сохранении сервера LSP

Можно включить «форматирование при сохранении» в диалоге настройки параметров LSP.

Подавление диагностики сервера LSP

Иногда диагностические данные могут оказаться не слишком полезны. Диагностика может быть лишней, особенно если диагностических сообщений слишком много (часто однотипных). В некоторых случаях поток сообщений можно скорректировать по языку программирования (на сервере). Например, механизм настройки clangd позволяет корректировать некоторые аспекты диагностики. Тем не менее, способ корректировки не всегда очевиден, а также желаемая корректировка может быть невозможна из-за ограничений сервера или внутренней ошибки.

Поэтому в модуле предусмотрена поддержка подавления диагностических сообщений (она похожа, например, на подавление valgrind). Самую тонкую настройку возможно выполнить с помощью ключа «suppressions» в (объединённой) конфигурации JSON.

{
    "servers": {
        "c": {
            "suppressions": {
                "rulename": ["filename", "foo"],
                "clang_pointer": ["", "clang-tidy", "clear_pointer"],
            }
        }
    }
}

Каждое (корректное) правило имеет произвольное имя и определяется массивом длины 2 или 3, в котором указано регулярное выражение для установления соответствия (полного) имени файла, регулярное выражение для установления соответствия диагностического текста и необязательное регулярное выражение для установления соответствия (диапазона исходного кода) текста, к которому применяется диагностика.

Помимо вышеупомянутой тонкой настройки, в контекстном меню на вкладке диагностики также предусмотрено добавление и удаление подавлений, которые точно соответствуют определённому диагностическому тексту (либо глобально (любой файл), либо локально (конкретный рассматриваемый файл)). Эти подавления хранятся и загружаются из конфигурации сеанса.

Устранение неполадок сервера LSP

Одно дело описать настройку (нестандартного) сервера LSP для какого-либо языка программирования, другое же — сделать так, чтобы сервер работал без каких-либо проблем. К счастью, обычно сервер работает именно так. Впрочем, иногда могут возникать сложности из-за случайно допущенных неточностей в параметрах настройки или более серьёзных проблем с самим сервером. Второй вариант может проявлять себя в виде сообщения о неудачных попытках запустить сервер, которое появляется на вкладке вывода данных Kate. Следует учитывать, что такие сообщения представляют собой лишь сообщения верхнего уровня или хода обработки, а не подробные диагностические сообщения, а также могут не содержать данных о том, что фактически является другим процессом (сервер LSP).

Обычный способ диагностики заключается в том, чтобы добавить к команде запуска (языкового сервера) один или несколько флагов; это включает (дополнительное) журналирование (в какой-либо файл или стандартный поток ошибок), если оно не выполняется по умолчанию. Если затем запустить Kate из командной строки, возможно, получится узнать о проблеме больше.

Информацию также можно получить, изучив обмен данными между клиентом LSP Kate и сервером LSP. Опять же, на последнем обычно есть средства трассировки. Клиент LSP также предоставляет дополнительную трассировку отладки (в stderr) при вызове Kate с должным образом экспортированной переменной среды LSPCLIENT_DEBUG=1.

Настройка среды выполнения

Приведённый выше пример виртуальной среды python — лишь один из вариантов «среды выполнения», работающей отличным и отдельным от обычной среды основной системы образом. Этого можно достичь с помощью различных параметров переменных (например, virtualenv) или настройки (s)chroot (переключения на другой каталог в качестве нового корня), контейнера (например, podman, docker) или ssh-сеанса к другой основной системе. В каждом из этих случаев «другая среда» определяется «префиксом выполнения». Это означает, что в этой другой среде программу можно вызвать/запустить с помощью «префикса» (программа и аргументы), добавленного к предполагаемому вызову. Например, podman exec -i containername или ssh user@host.

В частности, как было сделано в приведённом ранее примере virtualenv, можно запустить сервер LSP в такой отдельной среде (например, контейнер со всеми необходимыми проекту зависимостями). «Ручной» подход, описание которого приведено выше, имеет следующий недостаток: выполняется замена стандартной командной строки LSP, её потом необходимо указать и продублировать ещё раз в сценарии-обёртке. Кроме того, в некоторых других вышеупомянутых примерах «путь к пространству имён» основной системы (как он виден редактору) может отличаться от соответствующего для среды. Чтобы решить эти вопросы более системно (а не просто с помощью «индивидуального» подхода), можно дополнить конфигурацию.

Например, в конфигурации .kateproject можно указать следующее. Очевидно, что «фиктивные» комментарии включать не следует.

{
    // это также может быть массив объектов
    "exec": {
        "hostname": "foobar"
        // команда также может быть массивом строк
        "prefix": "podman exec -i foobarcontainer",
        "mapRemoteRoot": true,
        "pathMappings": [
            // возможна любая из следующих форм
            // также существует более автоматизированная альтернатива, подробнее о ней далее/ниже
            [ "/dir/on/host", "/mounted/in/container" ]
            { "localRoot": "/local/dir", "remoteRoot": "/remote/dir" }
        ]
    },
    "lspclient": {
        "servers": {
            "python": {
                // это устанавливает соответствие или выполняет объединение для объекта выше
                "exec": { "hostname": "foobar" },
                // ограничивает этот сервер корневым каталогом этого проекта,
                // чтобы он не использовался для других проектов, которые могут быть открыты
                // (для других серверов уже могут использоваться определённые корневые каталоги, но для python это обычно не так)
                "root": "."
            },
            "c": {
                // как выше
                "exec": { "hostname": "foobar" },
                "root": "."
            }
        }
    }
}

Как работает приведённый выше код? Как уже говорилось, часть с lspclient из этого кода добавляется в глобальную конфигурацию, поэтому будет найден раздел exec (для указанных языков). Поиск другого объекта (который указывает соответствующий hostname) выполняется либо в разделе exec, либо в разделе lspclient, и соответствующий объект служит основой для объединения. В результате командная строка сервера LSP (для C и python) будет добавлена к указанному (с подстановкой переменных) префиксу и, следовательно, он будет запускаться в указанном контейнере. Конечно, контейнер уже должен быть создан, корректно запущен и снабжён надлежащими серверами LSP. Может возникнуть соблазн использовать раздел global (внутри lspclient.) Это также может сработать, но тогда все серверы LSP будут запускаться с этим префиксом, включая серверы для, например, Markdown, Bash-сценариев или JSON. Более вероятно, что в основной системе всё это есть (если используется). Поэтому, как всегда, всё зависит от конкретных параметров настройки.

Тем не менее, сервер LSP теперь может отслеживать другие (сетевые) пути, которые отличаются от локальных путей, отображаемых и используемых редактором. Указанные pathMappings используются для преобразования туда-обратно в рамках обмена данными с сервером LSP. Конечно, это делается по возможности. Очевидно, что не у всех локальных путей есть сетевые аналоги, но отсутствующие пути не будут видимы (серверу) и не создадут проблем. Тем не менее, верно и обратное: (сетевой) сервер теперь может видеть и делать ссылки в «сетевом корневом каталоге», которые не представлены в локальной системе простым/явным образом. При включении mapRemoteRoot сетевой корневой каталог неявно привязывается к «локальному URL-адресу» exec://foobar/, который затем обрабатывается простым и понятным протоколом KIO (протокол системы ввода-вывода среды KDE). Последний, по сути, использует (например) podman exec -i foobarcontainer cat somefile" для копирования с сетевого компьютера на локальный (и другие подобные варианты с использованием утилит из набора coreutils). Достаточно сказать, что это решение не предназначается для использования в качестве основного и не претендует на производительность, но позволяет быстро получить файл по ссылке и с лёгкостью загрузить его в редактор.

Теперь очевидно, что упрощённый вариант приведённой выше конфигурации (без hostname или pathMappings) можно использовать для обработки virtualenv без дублирования командной строки сервера (в сценарии-обёртке).

Следующее может быть не слишком очевидно, поэтому здесь приводится прямое описание.

  • Как hostname, так и фактический prefix определяют среду выполнения (первый — по имени, второй — по содержимому). В экземпляре процесса редактора тот же самый hostname не должен быть связан с другим prefix, так как это приводит к неопределённому поведению (без необходимости в диагностике).

  • Оба значения, prefix и pathMappings, подлежат расширению переменных (в редакторе) (но с учётом предыдущей записи).

  • Во время выполнения также задаются некоторые переменные среды, с помощью чего можно (тонко) настроить поведение средства запуска с префиксом (но ещё раз обратите внимание на первый пункт). В частности, KATE_EXEC_PLUGIN устанавливается в значение lspclient, а KATE_EXEC_SERVER — в значение идентификатора сервера (например, python).

  • В частности, KATE_EXEC_INSPECT также имеет значение 1. Это сообщает «средству запуска с префиксом», что получатель (модуль Kate) принимает некоторые данные вне диапазона/протокола. Таким образом, средство запуска может использовать некоторые возможности для определения привязок путей (например, podman inspect) и передать эту информацию в подходящем формате. Затем это будет удалено из потока, который в остальном соответствует протоколу LSP, и использовано для расширения заданной привязки путей. Это может быть альтернативой явной привязке ресурсов (снова дублирование определения контейнера). Конкретно, вместо этого затем можно было бы использовать вышеприведённый фрагмент;

    {
        // ...
        "exec": {
            "hostname": "foobar"
            // нежелательный повтор имени, но вспомогательный сценарий понятен и прост
            "prefix": "exec_inspect.sh foobarcontainer podman exec -i foobarcontainer",
            "mapRemoteRoot": true,
            "pathMappings": []
        }
        // ...
    }
    

И последнее по порядку, но не по значимости: что, если подход с «резервным KIO» не считается подходящим? На практике зачастую можно «подключить» сетевой корневой каталог к локальной файловой системе и затем указать последнюю в pathMappings. Для начала, широко известная файловая система sshfs (fuse) может подключить (действительно) сетевую систему к локальной. Если используется контейнер (podman/docker), большинство конфигураций (драйвера файловой системы) поддерживают следующий трюк;

$ rootdir=/proc/`podman inspect --format '{{.State.Pid}}' containername`/root
# некоторые символьные ссылки могут приводить к проблемам, ниже приводится альтернатива
$ sudo mount --bind $rootdir /somewhere/containername

Если это не сработает, можно воспользоваться sshfs или его вариантом для подключения корневого каталога сетевого ресурса или контейнера;

# смотрите соответствующие man-страницы; для обычного (незашифрованного) протокола обработки файлов достаточно sftp-server
$ socat 'exec:podman exec -i containername /usr/lib/openssh/sftp-server'
   'exec:sshfs -o transform_symlinks -o passive \:/ /somewhere/containername'
# ...
$ fusermount -u /somewhere/containername

Обратите внимание, что такое подключение сетевого корневого каталога к основной файловой системе, скорее всего, потребуется указывать вручную и в явном виде в разделе pathMappings (за исключением случаев, когда используется интеллектуальное средство запуска с префиксом, которое организовывает всё это автоматически).