Skip to content

support selection range lsp feature #2565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
54c693e
add selection range support
Jan 5, 2022
4567bf8
add the whole import area as a selection step
Jan 15, 2022
660c641
add selection range plugin to all project files
Jan 16, 2022
ef5ff8d
Merge branch 'master' into feat/selection-range
Jan 16, 2022
3e39bfc
merge type signature with value definition
Jan 19, 2022
f88461f
Merge branch 'master' into feat/selection-range
Jan 19, 2022
a240561
support ghc 9
Jan 20, 2022
9c536ad
fix it for ghc-9.0
Jan 20, 2022
d081f7e
Merge branch 'master' into feat/selection-range
Jan 20, 2022
dfe02ae
remove unnecessary import
Jan 20, 2022
836f680
reformat GhcIde.hs
Jan 20, 2022
0894399
selection range: make it easier to understand
Jan 21, 2022
1a7d0f5
selection range: improve error handling
Jan 21, 2022
83f6201
update lsp-types to 1.4.0.1
Jan 21, 2022
0a96413
Merge branch 'master' into feat/selection-range
Jan 22, 2022
48a4709
add selection range to doc
Jan 22, 2022
bd7fcfd
fix comment for findSelectionRangesByPositions
Jan 22, 2022
a7ce386
remove a use of partial function
Jan 22, 2022
23ea08e
update author & maintainer
Jan 22, 2022
4d75549
Merge branch 'master' into feat/selection-range
Jan 22, 2022
cd5d8bc
use foldlM1 instead of foldl1
Jan 23, 2022
2d3c3ec
Merge branch 'master' into feat/selection-range
Jan 23, 2022
8e975df
add testdata to cabal file
Jan 23, 2022
94d45b6
update performace tips and log level
Jan 23, 2022
965b5dd
Merge branch 'master' into feat/selection-range
Jan 23, 2022
85b36be
Merge branch 'master' into feat/selection-range
pepeiborra Jan 24, 2022
72112bc
update lsp-types in nix
Jan 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/hackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
"hls-refine-imports-plugin", "hls-retrie-plugin",
"hls-splice-plugin", "hls-tactics-plugin",
"hls-call-hierarchy-plugin", "hls-alternate-number-format-plugin",
"hls-qualify-imported-names-plugin",
"hls-qualify-imported-names-plugin", "hls-selection-range-plugin",
"haskell-language-server"]
ghc: [ "9.0.2"
, "8.10.7"
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ jobs:
name: Test hls-qualify-imported-names-plugin test suite
run: cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS" || cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-qualify-imported-names-plugin --test-options="$TEST_OPTS"

- if: matrix.test
name: Test hls-selection-range-plugin test suite
run: cabal test hls-selection-range-plugin --test-options="$TEST_OPTS" || cabal test hls-selection-range-plugin --test-options="$TEST_OPTS" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-selection-range-plugin --test-options="$TEST_OPTS"

test_post_job:
if: always()
runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion cabal-ghc90.project
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ packages:
./plugins/hls-ormolu-plugin
./plugins/hls-call-hierarchy-plugin
./plugins/hls-alternate-number-format-plugin
./plugins/hls-selection-range-plugin

tests: true

Expand All @@ -35,7 +36,7 @@ package *

write-ghc-environment-files: never

index-state: 2022-01-11T22:05:45Z
index-state: 2022-01-21T11:23:29Z

constraints:
-- These plugins don't work on GHC9 yet
Expand Down
3 changes: 2 additions & 1 deletion cabal-ghc921.project
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ packages:
./plugins/hls-ormolu-plugin
./plugins/hls-call-hierarchy-plugin
./plugins/hls-alternate-number-format-plugin
./plugins/hls-selection-range-plugin

with-compiler: ghc-9.2.1

Expand All @@ -37,7 +38,7 @@ package *

write-ghc-environment-files: never

index-state: 2022-01-11T22:05:45Z
index-state: 2022-01-21T11:23:29Z

constraints:
-- These plugins don't build/work on GHC92 yet
Expand Down
3 changes: 2 additions & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ packages:
./plugins/hls-call-hierarchy-plugin
./plugins/hls-alternate-number-format-plugin
./plugins/hls-qualify-imported-names-plugin
./plugins/hls-selection-range-plugin

-- Standard location for temporary packages needed for particular environments
-- For example it is used in the project gitlab mirror to help in the MAcOS M1 build script
Expand All @@ -40,7 +41,7 @@ package *

write-ghc-environment-files: never

index-state: 2022-01-11T22:05:45Z
index-state: 2022-01-21T11:23:29Z

constraints:
hyphenation +embed
Expand Down
11 changes: 9 additions & 2 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Many of these are standard LSP features, but a lot of special features are provi
| [Highlight references](#highlight-references) | `textDocument/documentHighlight` |
| [Code actions](#code-actions) | `textDocument/codeAction` |
| [Code lenses](#code-lenses) | `textDocument/codeLens` |
| [Selection range](#selection-range) | `textDocument/selectionRange` |

The individual sections below also identify which [HLS plugin](./what-is-hls.md#hls-plugins) is responsible for providing the given functionality, which is useful if you want to raise an issue report or contribute!
Additionally, not all plugins are supported on all versions of GHC, see the [GHC version support page](supported-versions.md) for details.
Expand Down Expand Up @@ -141,7 +142,7 @@ Code action kind: `quickfix`
Rewrites imported names to be qualified.

![Qualify Imported Names Demo](../plugins/hls-qualify-imported-names-plugin/qualify-imported-names-demo.gif)

For usage see the ![readme](../plugins/hls-qualify-imported-names-plugin/README.md).

### Refine import
Expand Down Expand Up @@ -239,6 +240,13 @@ Shows module name matching file path, and applies it with a click.

![Module Name Demo](https://user-images.githubusercontent.com/54035/110860755-78ad8680-82bd-11eb-9845-9ea4b1cc1f76.gif)

## Selection range
Provided by: `hls-selection-range-plugin`

Provides haskell specific
[shrink/expand selection](https://code.visualstudio.com/docs/editor/codebasics#shrinkexpand-selection)
support.

## Missing features

The following features are supported by the LSP specification but not implemented in HLS.
Expand All @@ -251,7 +259,6 @@ Contributions welcome!
| Jump to implementation | Unclear if useful | `textDocument/implementation` |
| Renaming | [Parital implementation](https://github.com/haskell/haskell-language-server/issues/2193) | `textDocument/rename`, `textDocument/prepareRename` |
| Folding | Unimplemented | `textDocument/foldingRange` |
| Selection range | Unimplemented | `textDocument/selectionRange` |
| Semantic tokens | Unimplemented | `textDocument/semanticTokens` |
| Linked editing | Unimplemented | `textDocument/linkedEditingRange` |
| Document links | Unimplemented | `textDocument/documentLink` |
Expand Down
1 change: 1 addition & 0 deletions docs/supported-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ As such, the functionality provided by those plugins is not available in HLS whe
| `hls-splice-plugin` | 9.2 |
| `hls-stylish-haskell-plugin` | 9.0, 9.2 |
| `hls-tactics-plugin` | 9.2 |
| `hls-selection-range-plugin` | |

### Using deprecated GHC versions

Expand Down
7 changes: 7 additions & 0 deletions exe/Plugins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ import Ide.Plugin.Splice as Splice
import Ide.Plugin.AlternateNumberFormat as AlternateNumberFormat
#endif

#if selectionRange
import Ide.Plugin.SelectionRange as SelectionRange
#endif

-- formatters

#if floskell
Expand Down Expand Up @@ -167,6 +171,9 @@ idePlugins includeExamples = pluginDescToIdePlugins allPlugins
#endif
#if alternateNumberFormat
AlternateNumberFormat.descriptor "alternateNumberFormat" :
#endif
#if selectionRange
SelectionRange.descriptor "selectionRange" :
#endif
-- The ghcide descriptors should come last so that the notification handlers
-- (which restart the Shake build) run after everything else
Expand Down
8 changes: 4 additions & 4 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake_hackage/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
flake = false;
};
lsp-types = {
url = "https://hackage.haskell.org/package/lsp-types-1.4.0.0/lsp-types-1.4.0.0.tar.gz";
url = "https://hackage.haskell.org/package/lsp-types-1.4.0.1/lsp-types-1.4.0.1.tar.gz";
flake = false;
};
lsp-test = {
Expand Down
2 changes: 1 addition & 1 deletion ghcide/ghcide.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ library
lens,
list-t,
hiedb == 0.4.1.*,
lsp-types ^>= 1.4.0.0,
lsp-types ^>= 1.4.0.1,
lsp ^>= 1.4.0.0 ,
monoid-subclasses,
mtl,
Expand Down
101 changes: 72 additions & 29 deletions ghcide/src/Development/IDE/GHC/Compat.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ module Development.IDE.GHC.Compat(

nodeInfo',
getNodeIds,
nodeInfoFromSource,
isAnnotationInNodeInfo,
mkAstNode,
combineRealSrcSpans,

isQualifiedImport,
GhcVersion(..),
Expand Down Expand Up @@ -67,71 +71,75 @@ module Development.IDE.GHC.Compat(
runPp,
) where

import GHC hiding (HasSrcSpan, ModLocation, getLoc,
lookupName, RealSrcSpan)
import Development.IDE.GHC.Compat.Core
import Development.IDE.GHC.Compat.Env
import Development.IDE.GHC.Compat.ExactPrint
import Development.IDE.GHC.Compat.Iface
import Development.IDE.GHC.Compat.Logger
import Development.IDE.GHC.Compat.Outputable
import Development.IDE.GHC.Compat.Parser
import Development.IDE.GHC.Compat.Plugins
import Development.IDE.GHC.Compat.Units
import Development.IDE.GHC.Compat.Util
import Development.IDE.GHC.Compat.Core
import Development.IDE.GHC.Compat.Env
import Development.IDE.GHC.Compat.ExactPrint
import Development.IDE.GHC.Compat.Iface
import Development.IDE.GHC.Compat.Logger
import Development.IDE.GHC.Compat.Outputable
import Development.IDE.GHC.Compat.Parser
import Development.IDE.GHC.Compat.Plugins
import Development.IDE.GHC.Compat.Units
import Development.IDE.GHC.Compat.Util
import GHC hiding (HasSrcSpan,
ModLocation,
RealSrcSpan, getLoc,
lookupName)

#if MIN_VERSION_ghc(9,0,0)
import GHC.Data.StringBuffer
import GHC.Driver.Session hiding (ExposePackage)
import GHC.Driver.Session hiding (ExposePackage)
import qualified GHC.Types.SrcLoc as SrcLoc
import GHC.Utils.Error
#if MIN_VERSION_ghc(9,2,0)
import Data.Bifunctor
import GHC.Unit.Module.ModSummary
import GHC.Driver.Env as Env
import GHC.Driver.Env as Env
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.ModSummary
#else
import GHC.Driver.Types
#endif
import GHC.Iface.Env
import GHC.Iface.Make (mkIfaceExports)
import qualified GHC.SysTools.Tasks as SysTools
import qualified GHC.Types.Avail as Avail
import GHC.Iface.Make (mkIfaceExports)
import qualified GHC.SysTools.Tasks as SysTools
import qualified GHC.Types.Avail as Avail
#else
import DynFlags hiding (ExposePackage)
import HscTypes
import MkIface hiding (writeIfaceFile)
import qualified Avail
import DynFlags hiding (ExposePackage)
import HscTypes
import MkIface hiding (writeIfaceFile)

#if MIN_VERSION_ghc(8,8,0)
import StringBuffer (hPutStringBuffer)
import StringBuffer (hPutStringBuffer)
#endif
import qualified SysTools

#if !MIN_VERSION_ghc(8,8,0)
import SrcLoc (RealLocated)
import qualified EnumSet
import SrcLoc (RealLocated)

import Foreign.ForeignPtr
import System.IO
#endif
#endif

import Compat.HieAst (enrichHie)
import Compat.HieAst (enrichHie)
import Compat.HieBin
import Compat.HieTypes
import Compat.HieUtils
import qualified Data.ByteString as BS
import qualified Data.ByteString as BS
import Data.IORef

import qualified Data.Map as Map
import Data.List (foldl')
import Data.List (foldl')
import qualified Data.Map as Map
import qualified Data.Set as Set

#if MIN_VERSION_ghc(9,0,0)
import qualified Data.Set as S
import qualified Data.Set as S
#endif

#if !MIN_VERSION_ghc(8,10,0)
import Bag (unitBag)
import Bag (unitBag)
#endif

#if !MIN_VERSION_ghc(9,2,0)
Expand Down Expand Up @@ -334,6 +342,13 @@ nodeInfo' = nodeInfo
-- unhelpfulSpanFS = id
#endif

nodeInfoFromSource :: HieAST a -> Maybe (NodeInfo a)
#if MIN_VERSION_ghc(9,0,0)
nodeInfoFromSource = Map.lookup SourceInfo . getSourcedNodeInfo . sourcedNodeInfo
#else
nodeInfoFromSource = Just . nodeInfo
#endif

data GhcVersion
= GHC86
| GHC88
Expand Down Expand Up @@ -373,3 +388,31 @@ runPp =
#else
const SysTools.runPp
#endif

isAnnotationInNodeInfo :: (FastString, FastString) -> NodeInfo a -> Bool
#if MIN_VERSION_ghc(9,2,0)
isAnnotationInNodeInfo (ctor, typ) = Set.member (NodeAnnotation ctor typ) . nodeAnnotations
#else
isAnnotationInNodeInfo p = Set.member p . nodeAnnotations
#endif

mkAstNode :: NodeInfo a -> Span -> [HieAST a] -> HieAST a
#if MIN_VERSION_ghc(9,0,0)
mkAstNode n = Node (SourcedNodeInfo $ Map.singleton GeneratedInfo n)
#else
mkAstNode = Node
#endif

combineRealSrcSpans :: RealSrcSpan -> RealSrcSpan -> RealSrcSpan
#if MIN_VERSION_ghc(9,2,0)
combineRealSrcSpans = SrcLoc.combineRealSrcSpans
#else
combineRealSrcSpans span1 span2
= mkRealSrcSpan (mkRealSrcLoc file line_start col_start) (mkRealSrcLoc file line_end col_end)
where
(line_start, col_start) = min (srcSpanStartLine span1, srcSpanStartCol span1)
(srcSpanStartLine span2, srcSpanStartCol span2)
(line_end, col_end) = max (srcSpanEndLine span1, srcSpanEndCol span1)
(srcSpanEndLine span2, srcSpanEndCol span2)
file = srcSpanFile span1
#endif
11 changes: 11 additions & 0 deletions haskell-language-server.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ flag qualifyImportedNames
default: True
manual: True

flag selectionRange
description: Enable selectionRange plugin
default: True
manual: True

-- formatters

flag floskell
Expand Down Expand Up @@ -283,6 +288,11 @@ common qualifyImportedNames
build-depends: hls-qualify-imported-names-plugin ^>=1.0.0.0
cpp-options: -DqualifyImportedNames

common selectionRange
if flag(selectionRange)
build-depends: hls-selection-range-plugin ^>=1.0.0.0
cpp-options: -DselectionRange

-- formatters

common floskell
Expand Down Expand Up @@ -332,6 +342,7 @@ executable haskell-language-server
, splice
, alternateNumberFormat
, qualifyImportedNames
, selectionRange
, floskell
, fourmolu
, ormolu
Expand Down
Loading