Skip to content

Commit 1c9fd55

Browse files
committed
Fix formatting (etc) issue with multi-byte characters
A character that is multiple UTF-8 code units that got split across multiple 'data' events was converted into replacement characters due to Buffer.toString being called on the chunks individually. Instead collect all chunks and call toString after joining them. purescript-node/purescript-node-streams#37
1 parent 8c29275 commit 1c9fd55

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

src/IdePurescript/Build.purs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module IdePurescript.Build where
22

33
import Prelude
4+
45
import Control.Monad.Error.Class (throwError)
56
import Data.Array (intercalate, uncons, (:))
67
import Data.Array as Array
@@ -20,6 +21,8 @@ import Foreign.Object as Object
2021
import IdePurescript.Exec (findBins, getPathVar)
2122
import IdePurescript.PscErrors (PscResult(..), parsePscOutput)
2223
import IdePurescript.PscIdeServer (ErrorLevel(..), Notify)
24+
import Node.Buffer (Buffer)
25+
import Node.Buffer as Buffer
2326
import Node.ChildProcess (ChildProcess)
2427
import Node.ChildProcess as CP
2528
import Node.Encoding as Encoding
@@ -95,19 +98,19 @@ build logCb buildOptions@{ command: Command cmd args } = do
9598
Just cp -> do
9699
logCb Info $ "Running build command: " <> intercalate " " (cmd : args)
97100
CP.onError cp (cb <<< Left <<< CP.toStandardError)
98-
errOutput <- Ref.new ""
99-
outOutput <- Ref.new ""
101+
errOutput <- Ref.new []
102+
outOutput <- Ref.new []
100103
let
101-
res :: Ref String -> String -> Effect Unit
102-
res r s = Ref.modify_ (_ <> s) r
103-
catchException err $ S.onDataString (CP.stderr cp) Encoding.UTF8 (res errOutput)
104-
catchException err $ S.onDataString (CP.stdout cp) Encoding.UTF8 (res outOutput)
104+
res :: Ref (Array Buffer) -> Buffer -> Effect Unit
105+
res r s = Ref.modify_ (_ `Array.snoc` s) r
106+
catchException err $ S.onData (CP.stderr cp) (res errOutput)
107+
catchException err $ S.onData (CP.stdout cp) (res outOutput)
105108
CP.onClose cp
106109
( \exit -> case exit of
107110
CP.Normally n
108111
| n == 0 || n == 1 -> do
109-
pursError <- Ref.read (errOutput)
110-
pursOutput <- Ref.read (outOutput)
112+
pursError <- Ref.read errOutput >>= Buffer.concat >>= Buffer.toString Encoding.UTF8
113+
pursOutput <- Ref.read outOutput >>= Buffer.concat >>= Buffer.toString Encoding.UTF8
111114
let
112115
lines = split (Pattern "\n") $ pursError <> pursOutput
113116
{ yes: json, no: toLog } = Array.partition (\s -> indexOf (Pattern "{\"") s == Just 0) lines

src/LanguageServer/IdePurescript/Formatting.purs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module LanguageServer.IdePurescript.Formatting
55

66
import Prelude
77

8+
import Data.Array as Array
89
import Data.Either (Either(..))
910
import Data.Foldable (length)
1011
import Data.Maybe (Maybe(..))
@@ -25,6 +26,8 @@ import LanguageServer.Protocol.DocumentStore (getDocument)
2526
import LanguageServer.Protocol.Handlers (DocumentFormattingParams)
2627
import LanguageServer.Protocol.TextDocument (getText)
2728
import LanguageServer.Protocol.Types (DocumentStore, Position(..), Range(..), Settings, TextDocumentIdentifier(..), TextEdit(..))
29+
import Node.Buffer (Buffer)
30+
import Node.Buffer as Buffer
2831
import Node.ChildProcess as CP
2932
import Node.Encoding (Encoding(..))
3033
import Node.Encoding as Encoding
@@ -51,14 +54,14 @@ poseCommand = Command "prettier" [ "--parser", "purescript" ]
5154

5255
-- TODO for NoFormatter don't provide formatting provider
5356
format :: Notify -> Settings -> ServerState -> Formatter -> String -> Aff String
54-
format logCb settings state formatter text = do
57+
format _logCb settings state formatter text = do
5558
let
5659
command = case formatter of
5760
Purty -> purtyCommand
5861
PursTidy -> pursTidyCommand
5962
Pose -> poseCommand
6063
NoFormatter -> Command "echo" [] -- Not possible
61-
Command cmd _ = command
64+
Command _cmd _ = command
6265
case state of
6366
ServerState { root: Just directory } -> do
6467
makeAff
@@ -68,16 +71,17 @@ format logCb settings state formatter text = do
6871
err = cb <<< Left
6972
cp <- spawn { command, directory, useNpmDir: Config.addNpmPath settings }
7073
CP.onError cp (err <<< CP.toStandardError)
71-
result <- Ref.new ""
74+
result <- Ref.new []
75+
7276
let
73-
res :: String -> Effect Unit
74-
res s = Ref.modify_ (_ <> s) result
77+
res :: Buffer -> Effect Unit
78+
res s = Ref.modify_ (_ `Array.snoc` s) result
7579
catchException err $ S.onDataString (CP.stderr cp) Encoding.UTF8 $ err <<< error
76-
catchException err $ S.onDataString (CP.stdout cp) Encoding.UTF8 res
80+
catchException err $ S.onData (CP.stdout cp) res
7781
CP.onClose cp \exit -> case exit of
7882
CP.Normally n
79-
| n == 0 || n == 1 ->
80-
Ref.read result >>= succ
83+
| n == 0 || n == 1 ->
84+
Ref.read result >>= Buffer.concat >>= Buffer.toString Encoding.UTF8 >>= succ
8185
_ -> do
8286
let Command cmd _ = command
8387
err $ error $ cmd <> " process exited abnormally"

0 commit comments

Comments
 (0)