initial
This commit is contained in:
commit
baa0056244
352 changed files with 47928 additions and 0 deletions
168
docs/guide/extensions.md
Normal file
168
docs/guide/extensions.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# Extending the Host Editor
|
||||
|
||||
PowerShell Editor Services exposes a common extensibility model which allows
|
||||
you to write extension code in PowerShell that works across any editor that
|
||||
uses PowerShell Editor Services.
|
||||
|
||||
## API Overview
|
||||
|
||||
### Introducing `$psEditor`
|
||||
|
||||
The entry point for the PowerShell Editor Services extensibility model is the `$psEditor`
|
||||
object of the type @Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorObject. For
|
||||
those familiar with the PowerShell ISE's `$psISE` object, the `$psEditor` object is very
|
||||
similar. The primary difference is that this model has been generalized to work against
|
||||
any editor which leverages PowerShell Editor Services for its PowerShell editing experience.
|
||||
|
||||
> NOTE: For now the `$psEditor` object is limited as it has just been
|
||||
> introduced. If you have ideas for other useful APIs it could expose
|
||||
> please file an issue on our GitHub page.
|
||||
|
||||
This object gives access to all of the high-level services in the current
|
||||
editing session. For example, the @Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorObject.Workspace
|
||||
property gives access to the editor's workspace, allowing you to create or open files
|
||||
in the editor.
|
||||
|
||||
### Usage Examples
|
||||
|
||||
#### Opening a file in the editor
|
||||
|
||||
```powershell
|
||||
# Open the current user's profile for this editor
|
||||
$psEditor.Workspace.OpenFile($profile)
|
||||
```
|
||||
|
||||
#### Manipulating the user's active file buffer
|
||||
|
||||
```powershell
|
||||
# Insert new text replacing the user's current selection
|
||||
$context = $psEditor.GetEditorContext()
|
||||
$context.CurrentFile.InsertText("# All your script are belong to us", $context.SelectedRange)
|
||||
```
|
||||
|
||||
#### Setting the selection based on the cursor position
|
||||
|
||||
```powershell
|
||||
# Set the selection from their cursor position to the end of the same line
|
||||
$context = $psEditor.GetEditorContext()
|
||||
$context.SetSelection($context.CursorPosition, $context.CursorPosition.GetLineEnd())
|
||||
```
|
||||
|
||||
## Registering Editor Commands
|
||||
|
||||
The `$psEditor` object gives you the ability to write a script that can automate the
|
||||
host editor when run inside of it. However, you may not want to give a user a plain
|
||||
script that performs some operation. What if you'd prefer to add a new command to the
|
||||
editor which can execute your code when the user invokes it? The `Register-EditorCommand`
|
||||
cmdlet allows you to register either a function, cmdlet, or ScriptBlock as a
|
||||
command in the host editor.
|
||||
|
||||
### Registering a cmdlet or function command
|
||||
|
||||
```powershell
|
||||
function Invoke-MyCommand {
|
||||
Write-Output "My command's function was invoked!"
|
||||
}
|
||||
|
||||
Register-EditorCommand `
|
||||
-Name "MyModule.MyCommandWithFunction" `
|
||||
-DisplayName "My command with function" `
|
||||
-Function Invoke-MyCommand
|
||||
```
|
||||
|
||||
### Registering a script block command
|
||||
|
||||
```powershell
|
||||
Register-EditorCommand `
|
||||
-Name "MyModule.MyCommandWithScriptBlock" `
|
||||
-DisplayName "My command with script block" `
|
||||
-ScriptBlock { Write-Output "My command's script block was invoked!" }
|
||||
```
|
||||
|
||||
### The @Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext parameter
|
||||
|
||||
Your function, cmdlet, or ScriptBlock can optionally accept a single parameter
|
||||
of type @Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext which provides
|
||||
information about the state of the host editor at the time your command was
|
||||
invoked. With this object you can easily perform operations like manipulatin the
|
||||
state of the user's active editor buffer or changing the current selection.
|
||||
|
||||
The usual convention is that a `$context` parameter is added to your editor
|
||||
command's function. For now it is recommended that you fully specify the
|
||||
type of the @Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext object
|
||||
so that you get full IntelliSense on your context parameter.
|
||||
|
||||
Here is an example of using the `$context` parameter:
|
||||
|
||||
```powershell
|
||||
Register-EditorCommand `
|
||||
-Name "MyModule.MyEditorCommandWithContext" `
|
||||
-DisplayName "My command with context usage" `
|
||||
-ScriptBlock {
|
||||
param([Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext]$context)
|
||||
Write-Output "The user's cursor is on line $($context.CursorPosition.Line)!"
|
||||
}
|
||||
```
|
||||
|
||||
### Suppressing command output
|
||||
|
||||
If you would like for your editor command to run without its output being
|
||||
written to the user's console, you can use the `-SuppressOutput` switch
|
||||
parameter of the `Register-EditorCommand` cmdlet. We recommend that you
|
||||
use this parameter if your command does not need to write output to the
|
||||
user's console.
|
||||
|
||||
Regardless of whether the `-SuppressOutput` parameter is used, any errors
|
||||
that occur while running your editor command will be written to the user's
|
||||
console.
|
||||
|
||||
## Using Editor Commands
|
||||
|
||||
If you've registered an editor command, either through your own code or
|
||||
a module that you've installed, you can launch it using your editor's **Show
|
||||
additional commands from PowerShell modules** command. Running this command
|
||||
will cause a list of commands to be displayed.
|
||||
|
||||
In Visual Studio Code, press `Ctrl+Shift+P` to open the command palette. Type
|
||||
the characters `addi` until you see the following item and then press `Enter`:
|
||||
|
||||

|
||||
|
||||
The list that appears next will show all of the editor commands that have
|
||||
been registered with PowerShell code. Selecting one of them will cause its
|
||||
function or ScriptBlock to be executed.
|
||||
|
||||

|
||||
|
||||
Other editors should follow a similar pattern, exposing this command list through
|
||||
a "Show additional commands" item in the command palette.
|
||||
|
||||
> NOTE: In the future we hope to be able to register editor commands at the top level
|
||||
> so that these commands are easier to find and so that they also can be bound to
|
||||
> hotkeys for quick access.
|
||||
|
||||
## Shipping an Extension Module
|
||||
|
||||
You can easily ship a module containing editor commands which get registered
|
||||
if the module is loaded into an editor session. Assuming that you've exported
|
||||
a function or cmdlet named `Invoke-MyEditorCommand` in your module's psd1
|
||||
file, you can add this code at the very end of your module's psm1 file:
|
||||
|
||||
```powershell
|
||||
if ($psEditor) {
|
||||
Register-EditorCommand `
|
||||
-Name "MyModule.MyEditorCommand" `
|
||||
-DisplayName "My editor command" `
|
||||
-Function Invoke-MyEditorCommand `
|
||||
-SuppressOutput
|
||||
}
|
||||
```
|
||||
|
||||
The user will now be able to import your module in their host editor's profile and
|
||||
your editor command will be immediately available after the PowerShell extension
|
||||
in that editor starts up.
|
||||
|
||||
> NOTE: In the future we plan to provide an easy way for the user to opt-in
|
||||
> to the automatic loading of any editor command modules that they've installed
|
||||
> from the PowerShell Gallery. If this interests you, please let us know on
|
||||
> [this GitHub issue](https://github.com/PowerShell/PowerShellEditorServices/issues/215).
|
||||
166
docs/guide/getting_started.md
Normal file
166
docs/guide/getting_started.md
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
# Getting Started
|
||||
The PowerShell Editor Services project provides a Language Server Protocol (LSP)
|
||||
HTTP server that runs outside the editor. The server supplies rich editor
|
||||
functionality like code completion, syntax highlighting, and code annotation.
|
||||
This document will guide you through getting a minimal setup working with
|
||||
several editors.
|
||||
|
||||
## Editors
|
||||
1. [Neovim](#neovim)
|
||||
|
||||
## Neovim
|
||||
|
||||
### Install the Server
|
||||
Download and extract the PowerShell Editor Services server from the
|
||||
[releases page](https://github.com/PowerShell/PowerShellEditorServices/releases)
|
||||
into a directory of your choice. Remember the path that you extract the
|
||||
project into.
|
||||
```powershell
|
||||
$DownloadUrl = 'https://github.com/PowerShell/PowerShellEditorServices/releases/latest/download/PowerShellEditorServices.zip';
|
||||
$ZipPath = "$HOME/Desktop/PowerShellEditorServices.zip";
|
||||
$InstallPath = "$HOME/Desktop/PowerShellEditorServices";
|
||||
Invoke-WebRequest -Method 'GET' -Uri $DownloadUrl -OutFile $ZipPath;
|
||||
Expand-Archive -Path $ZipPath -DestinationPath $InstallPath;
|
||||
```
|
||||
|
||||
### Install Neovim's Quickstart LSP Configurations
|
||||
Neovim has a repository of quickstart LSP configurations for a number of
|
||||
languages, including PowerShell. Install the quickstart LSP configuration into
|
||||
one of the package directories inside `$XDG_CONFIG_HOME`. The path
|
||||
`$XDG_CONFIG_HOME` will vary depending on which operating system you are on:
|
||||
|
||||
| OS | Path |
|
||||
| ---------- | -------------------------- |
|
||||
| Windows | `$HOME/AppData/local/nvim` |
|
||||
| *nix/macOS | `$HOME/.config/nvim` |
|
||||
|
||||
The easiest way is to install the quickstart configuration is to clone the
|
||||
repository using git:
|
||||
```powershell
|
||||
git clone https://github.com/neovim/nvim-lspconfig.git "$HOME/AppData/local/nvim/pack/complete/start/nvim-lspconfig"
|
||||
```
|
||||
|
||||
Alternatively, you can extract the zip file into the same place:
|
||||
```powershell
|
||||
$DownloadUrl = 'https://github.com/neovim/nvim-lspconfig/archive/refs/heads/master.zip';
|
||||
$ZipPath = "$HOME/AppData/local/nvim/nvim-lspconfig.zip";
|
||||
$InstallPath = "$HOME/AppData/local/nvim/pack/complete/start/nvim-lspconfig";
|
||||
Invoke-WebRequest -Method 'GET' Uri $DownloadUrl -OutFile $ZipPath;
|
||||
Expand-Archive -Path $ZipPath -DestinationPath $InstallPath;
|
||||
```
|
||||
|
||||
> NOTE: If the corresponding neovim configuration and package directories have
|
||||
> not been created yet, create them before installing the quickstart LSP
|
||||
> configuration repository.
|
||||
|
||||
### Configure the Server
|
||||
|
||||
#### Setup Keybindings and Path Information
|
||||
Once the basic language configurations have been installed, add this to your
|
||||
`init.lua` located in `$XDG_CONFIG_HOME`:
|
||||
```lua
|
||||
local on_attach = function(client, bufnr)
|
||||
-- Enable completion triggered by <c-x><c-o>
|
||||
vim.api.nvim_set_option_value("omnifunc", "v:lua.vim.lsp.omnifunc", { buf = bufnr })
|
||||
|
||||
local bufopts = { noremap = true, silent = true, buffer = bufnr }
|
||||
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
|
||||
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
|
||||
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
|
||||
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
|
||||
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
|
||||
vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
|
||||
vim.keymap.set('n', '<Leader>ca', vim.lsp.buf.code_action, bufopts)
|
||||
vim.keymap.set('n', '<Leader>f', function() vim.lsp.buf.format { async = true } end, bufopts)
|
||||
vim.keymap.set('n', '<Leader>rn', vim.lsp.buf.rename, bufopts)
|
||||
vim.keymap.set('n', '<Leader>td', vim.lsp.buf.type_definition, bufopts)
|
||||
end
|
||||
|
||||
local home_directory = os.getenv('HOME')
|
||||
if home_directory == nil then
|
||||
home_directory = os.getenv('USERPROFILE')
|
||||
end
|
||||
|
||||
-- The bundle_path is where PowerShell Editor Services was installed
|
||||
local bundle_path = home_directory .. '/Desktop/PowerShellEditorServices'
|
||||
|
||||
require('lspconfig')['powershell_es'].setup {
|
||||
bundle_path = bundle_path,
|
||||
on_attach = on_attach
|
||||
}
|
||||
```
|
||||
|
||||
> NOTE: Be sure to set the bundle_path variable to the correct location,
|
||||
> otherwise the server will not know the path to start the server.
|
||||
|
||||
If you use an `init.vim` file, you may put the keybinding and path configuration
|
||||
in your `init.vim` with the `lua` heredoc syntax instead.
|
||||
```vim
|
||||
lua << EOF
|
||||
-- lua keybindings and path configuration here
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Theme Troubleshooting
|
||||
If you find that your colorscheme appears correctly for a second and then
|
||||
changes to not having full highlighting, you'll need to disable semantic
|
||||
highlighting.
|
||||
Add this line to the `on_attach` function.
|
||||
```lua
|
||||
client.server_capabilities.semanticTokensProvider = nil
|
||||
```
|
||||
|
||||
#### Configure Additional Settings
|
||||
To further configure the server, you can supply settings to the setup table.
|
||||
For example, you can set the code formatting preset to one true brace style
|
||||
(OTBS).
|
||||
```lua
|
||||
require('lspconfig')['powershell_es'].setup {
|
||||
bundle_path = bundle_path,
|
||||
on_attach = on_attach,
|
||||
settings = { powershell = { codeFormatting = { Preset = 'OTBS' } } }
|
||||
}
|
||||
```
|
||||
For a more complete list of options have a look at this schema:
|
||||
[nvim-lsp-installer powershell_es reference](https://github.com/williamboman/nvim-lsp-installer/blob/main/lua/nvim-lsp-installer/_generated/schemas/powershell_es.lua)
|
||||
|
||||
You can also set the bundled PSScriptAnalyzer's custom rule path like so:
|
||||
```lua
|
||||
local custom_settings_path = home_directory .. '/PSScriptAnalyzerSettings.psd1'
|
||||
require('lspconfig')['powershell_es'].setup {
|
||||
bundle_path = bundle_path,
|
||||
on_attach = on_attach,
|
||||
settings = { powershell = { scriptAnalysis = { settingsPath = custom_settings_path } } }
|
||||
}
|
||||
```
|
||||
|
||||
#### Autocomplete Brackets Troubleshooting
|
||||
If you're using `blink.cmp` and you're getting brackets when autocompleting
|
||||
cmdlet names, you'll need to add `{ "ps1", "psm1" }` to the blocked filetypes
|
||||
for both `kind_resolution` and `semantic_token_resolution` in the plugin's
|
||||
config file.
|
||||
|
||||
[Blink.cmp completion reference](https://cmp.saghen.dev/configuration/reference#completion-accept)
|
||||
|
||||
### Indentation
|
||||
|
||||
Vim/Neovim does not contain default `:h indentexpr` for filetype `ps1`.
|
||||
So you might notice indentation on newline is not behaving as expected for powershell files.
|
||||
Luckily powershell has similar syntax like C, so we can use `:h cindent` to fix the indentation problem.
|
||||
You can use the following snippet to either callback of an autocmd or ftplugin.
|
||||
|
||||
```lua
|
||||
--- ./nvim/lua/ftplugin/ps1.lua
|
||||
|
||||
-- disable indent from powershell treesitter parser
|
||||
-- because the parse isn't mature currently
|
||||
-- you can ignore this step if don't use treesitter
|
||||
if pcall(require, 'nvim-treesitter') then
|
||||
vim.schedule(function() vim.cmd([[TSBufDisable indent]]) end)
|
||||
end
|
||||
|
||||
vim.opt_local.cindent = true
|
||||
vim.opt_local.cinoptions:append { 'J1', '(1s', '+0' } -- see :h cino-J, cino-(, cino-+
|
||||
|
||||
vim.opt_local.iskeyword:remove { '-' } -- OPTIONALLY consider Verb-Noun as a whole word
|
||||
```
|
||||
37
docs/guide/introduction.md
Normal file
37
docs/guide/introduction.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Introduction
|
||||
|
||||
> NOTE: The user guide is currently under development and may be missing
|
||||
> important information. If you feel that a particular area is missing or
|
||||
> poorly explained, please feel free to file an issue at our [GitHub site](https://github.com/PowerShell/PowerShellEditorServices/issues)
|
||||
|
||||
PowerShell Editor Services is a tool that provides useful services to code
|
||||
editors that need a great PowerShell editing experience.
|
||||
|
||||
## The .NET API
|
||||
|
||||
The .NET API provides the complete set of services which can be used in
|
||||
code editors or any other type of application. The easiest way to get
|
||||
started with it is to add the [Microsoft.PowerShell.EditorServices](https://www.nuget.org/packages/Microsoft.PowerShell.EditorServices/)
|
||||
NuGet package to your C# project.
|
||||
|
||||
If you're a developer that would like to use PowerShell Editor Services in
|
||||
a .NET application, read the page titled [Using the .NET API](using_the_dotnet_api.md)
|
||||
to learn more.
|
||||
|
||||
## The Host Process
|
||||
|
||||
The host process provides a JSON-based API wrapper around the .NET APIs so
|
||||
that editors written in non-.NET languages can make use of its capabilities.
|
||||
In the future the host process will allow the use of network-based channels
|
||||
to enable all of the APIs to be accessed remotely.
|
||||
|
||||
If you're a developer that would like to integrate PowerShell Editor Services
|
||||
into your favorite editor, read the page titled [Using the Host Process](using_the_host_process.md)
|
||||
to learn more.
|
||||
|
||||
## Writing Extensions in PowerShell
|
||||
|
||||
If you're using an editor that leverages PowerShell Editor Services to provide
|
||||
PowerShell editing capabilities, you may be able to extend its behavior using
|
||||
our PowerShell-based editor extension API. Read the page titled [Extending the
|
||||
Host Editor](extensions.md) to learn more.
|
||||
4
docs/guide/toc.md
Normal file
4
docs/guide/toc.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# [Introduction](introduction.md)
|
||||
# [Using the .NET API](using_the_dotnet_api.md)
|
||||
# [Using the Host Process](using_the_host_process.md)
|
||||
# [Extending the Host Editor](extensions.md)
|
||||
1124
docs/guide/using_the_host_process.md
Normal file
1124
docs/guide/using_the_host_process.md
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue