From 83e7f2b884915100318bb6a06eb5b59fd7e39354 Mon Sep 17 00:00:00 2001 From: Nicholas Wolverson Date: Sat, 31 Mar 2018 22:08:55 +0100 Subject: [PATCH] Add warning/build option on missing output dir --- src/LanguageServer/Console.ts | 2 +- src/LanguageServer/IdePurescript/Build.purs | 5 ++- src/LanguageServer/IdePurescript/Config.purs | 5 +++ src/LanguageServer/IdePurescript/Main.purs | 44 +++++++++++++------- src/LanguageServer/Window.js | 17 ++++++++ src/LanguageServer/Window.purs | 38 +++++++++++++++++ src/LanguageServer/Window.ts | 11 +++++ 7 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 src/LanguageServer/Window.js create mode 100644 src/LanguageServer/Window.purs create mode 100644 src/LanguageServer/Window.ts diff --git a/src/LanguageServer/Console.ts b/src/LanguageServer/Console.ts index 132498d..87203b5 100644 --- a/src/LanguageServer/Console.ts +++ b/src/LanguageServer/Console.ts @@ -3,4 +3,4 @@ import { IConnection } from 'vscode-languageserver'; export const log = (conn: IConnection) => (s: string) => () => conn.console.log(s); export const info = (conn: IConnection) => (s: string) => () => conn.console.info(s); export const warn = (conn: IConnection) => (s: string) => () => conn.console.warn(s); -export const error = (conn: IConnection) => (s: string) => () => conn.console.error(s); +export const error = (conn: IConnection) => (s: string) => () => conn.console.error(s); \ No newline at end of file diff --git a/src/LanguageServer/IdePurescript/Build.purs b/src/LanguageServer/IdePurescript/Build.purs index 7d2c4df..b94dca3 100644 --- a/src/LanguageServer/IdePurescript/Build.purs +++ b/src/LanguageServer/IdePurescript/Build.purs @@ -91,6 +91,9 @@ fullBuild logCb _ settings state _ = do loadAll port liftEff $ logCb Info "Reloaded modules" pure $ convertDiagnostics directory settings res.errors - _, _ -> do + _, Nothing -> do liftEff $ logCb Error "Error parsing build command" pure emptyDiagnostics + ServerState { port, conn, root }, _ -> do + liftEff $ logCb Error $ "Error running build: " <> show port <> " : " <> show root + pure emptyDiagnostics diff --git a/src/LanguageServer/IdePurescript/Config.purs b/src/LanguageServer/IdePurescript/Config.purs index 6ea1553..c37420b 100644 --- a/src/LanguageServer/IdePurescript/Config.purs +++ b/src/LanguageServer/IdePurescript/Config.purs @@ -91,9 +91,14 @@ fastRebuild = getBoolean "fastRebuild" true editorMode :: ConfigFn Boolean editorMode = getBoolean "editorMode" false +-- | Output directory - if specified, passed to purs, otherwise no argument is passed (purs default to 'output') outputDirectory :: ConfigFn (Maybe String) outputDirectory = getConfigMaybe readString "outputDirectory" +-- | Effective output directory (taking account of purs default) +effectiveOutputDirectory :: ConfigFn String +effectiveOutputDirectory = fromMaybe "output" <<< outputDirectory + polling :: ConfigFn Boolean polling = getBoolean "polling" false diff --git a/src/LanguageServer/IdePurescript/Main.purs b/src/LanguageServer/IdePurescript/Main.purs index fce2495..d81c60e 100644 --- a/src/LanguageServer/IdePurescript/Main.purs +++ b/src/LanguageServer/IdePurescript/Main.purs @@ -2,7 +2,7 @@ module LanguageServer.IdePurescript.Main where import Prelude -import Control.Monad.Aff (Aff, apathize, runAff) +import Control.Monad.Aff (Aff, apathize, forkAff, runAff) import Control.Monad.Eff (Eff) import Control.Monad.Eff.Class (liftEff) import Control.Monad.Eff.Ref (modifyRef, newRef, readRef, writeRef) @@ -41,6 +41,8 @@ import LanguageServer.Setup (InitParams(..), initConnection, initDocumentStore) import LanguageServer.TextDocument (getText, getUri) import LanguageServer.Types (Diagnostic, DocumentUri(..), FileChangeType(..), FileChangeTypeCode(..), FileEvent(..), Settings, TextDocumentIdentifier(..), intToFileChangeType) import LanguageServer.Uri (filenameToUri, uriToFilename) +import LanguageServer.Window (showWarningWithActions) +import Node.FS.Aff as FS import Node.Process (argv, cwd) import PscIde.Command (RebuildError(..)) @@ -105,20 +107,6 @@ main = do argv >>= \args -> log conn $ "Starting with args: " <> show args modifyRef state (over ServerState $ _ { root = toMaybe rootPath }) modifyRef state (over ServerState $ _ { conn = Just conn }) - - let onConfig = do - writeRef gotConfig true - c <- readRef config - when (Config.autoStartPscIde c) $ launchAffLog startPscIdeServer - - readRef gotConfig >>= (_ `when` onConfig) - - onDidChangeConfiguration conn $ \{settings} -> do - log conn "Got updated settings" - writeRef config settings - readRef gotConfig >>= \c -> when (not c) onConfig - - log conn "PureScript Language Server started" documents <- initDocumentStore conn @@ -235,3 +223,29 @@ main = do Nothing -> do liftEff $ error conn $ "Unknown command: " <> command pure noResult + + let onConfig = launchAffLog do + liftEff $ writeRef gotConfig true + c <- liftEff $ readRef config + when (Config.autoStartPscIde c) $ do + startPscIdeServer + let outputDir = Config.effectiveOutputDirectory c + exists <- FS.exists outputDir + liftEff $ log conn $ "Onconfig: " <> show exists + when (not exists) $ void $ forkAff do + let message = "Output directory does not exist at '" <> outputDir <> "'" + liftEff $ info conn message + let buildOption = "Build project" + action <- showWarningWithActions conn (message <> ". Ensure project is built, or check configuration of output directory and build command.") [ buildOption ] + when (action == Just buildOption) do + s <- liftEff $ readRef state + onBuild documents c s [] + + readRef gotConfig >>= (_ `when` onConfig) + + onDidChangeConfiguration conn $ \{settings} -> do + log conn "Got updated settings" + writeRef config settings + readRef gotConfig >>= \c -> when (not c) onConfig + + log conn "PureScript Language Server started" \ No newline at end of file diff --git a/src/LanguageServer/Window.js b/src/LanguageServer/Window.js new file mode 100644 index 0000000..6dd764b --- /dev/null +++ b/src/LanguageServer/Window.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.showError = function (conn) { return function (s) { return function () { return conn.window.showErrorMessage(s); }; }; }; +exports.showErrorWithActionsImpl = function (conn) { return function (s) { return function (actions) { return function () { + return (_a = conn.window).showErrorMessage.apply(_a, [s].concat(actions)); + var _a; +}; }; }; }; +exports.showWarning = function (conn) { return function (s) { return function () { return conn.window.showWarningMessage(s); }; }; }; +exports.showWarningWithActionsImpl = function (conn) { return function (s) { return function (actions) { return function () { + return (_a = conn.window).showWarningMessage.apply(_a, [s].concat(actions)); + var _a; +}; }; }; }; +exports.showInformation = function (conn) { return function (s) { return function () { return conn.window.showInformationMessage(s); }; }; }; +exports.showInformationWithActionsImpl = function (conn) { return function (s) { return function (actions) { return function () { + return (_a = conn.window).showInformationMessage.apply(_a, [s].concat(actions)); + var _a; +}; }; }; }; diff --git a/src/LanguageServer/Window.purs b/src/LanguageServer/Window.purs new file mode 100644 index 0000000..c9cb012 --- /dev/null +++ b/src/LanguageServer/Window.purs @@ -0,0 +1,38 @@ +module LanguageServer.Window (showError, showErrorWithActions, showWarning, showWarningWithActions, showInformation, showInformationWithActions) where + +import Prelude + +import Control.Monad.Aff (Aff) +import Control.Monad.Eff (Eff) +import Control.Promise (Promise) +import Control.Promise as Promise +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toMaybe) +import LanguageServer.Types (CONN, Connection) + +type MessageAction = { title :: String } + +foreign import showError :: forall eff. Connection -> String -> Eff (conn :: CONN | eff) Unit +foreign import showErrorWithActionsImpl :: forall eff. Connection -> String -> Array MessageAction-> Eff (conn :: CONN | eff) (Promise (Nullable MessageAction)) + +convertMessageAction :: Nullable MessageAction -> Maybe String +convertMessageAction act = _.title <$> toMaybe act + +showErrorWithActions :: forall eff. Connection -> String -> Array String -> Aff (conn :: CONN | eff) (Maybe String) +showErrorWithActions conn msg acts = + convertMessageAction <$> (Promise.toAffE $ showErrorWithActionsImpl conn msg (map (\title -> { title }) acts)) + +foreign import showWarning :: forall eff. Connection -> String -> Eff (conn :: CONN | eff) Unit +foreign import showWarningWithActionsImpl :: forall eff. Connection -> String -> Array MessageAction-> Eff (conn :: CONN | eff) (Promise (Nullable MessageAction)) + +showWarningWithActions :: forall eff. Connection -> String -> Array String -> Aff (conn :: CONN | eff) (Maybe String) +showWarningWithActions conn msg acts = + convertMessageAction <$> (Promise.toAffE $ showWarningWithActionsImpl conn msg (map (\title -> { title }) acts)) + + +foreign import showInformation :: forall eff. Connection -> String -> Eff (conn :: CONN | eff) Unit +foreign import showInformationWithActionsImpl :: forall eff. Connection -> String -> Array MessageAction-> Eff (conn :: CONN | eff) (Promise (Nullable MessageAction)) + +showInformationWithActions :: forall eff. Connection -> String -> Array String -> Aff (conn :: CONN | eff) (Maybe String) +showInformationWithActions conn msg acts = + convertMessageAction <$> (Promise.toAffE $ showInformationWithActionsImpl conn msg (map (\title -> { title }) acts)) diff --git a/src/LanguageServer/Window.ts b/src/LanguageServer/Window.ts new file mode 100644 index 0000000..cee1f14 --- /dev/null +++ b/src/LanguageServer/Window.ts @@ -0,0 +1,11 @@ +import { IConnection, MessageActionItem } from "vscode-languageserver/lib/main"; + +export const showError = (conn: IConnection) => (s: string) => () => conn.window.showErrorMessage(s); +export const showErrorWithActionsImpl = (conn: IConnection) => (s: string) => (actions: T[]) => () => conn.window.showErrorMessage(s, ...actions); + +export const showWarning = (conn: IConnection) => (s: string) => () => conn.window.showWarningMessage(s); +export const showWarningWithActionsImpl = (conn: IConnection) => (s: string) => (actions: T[]) => () => conn.window.showWarningMessage(s, ...actions); + +export const showInformation = (conn: IConnection) => (s: string) => () => conn.window.showInformationMessage(s); +export const showInformationWithActionsImpl = (conn: IConnection) => (s: string) => (actions: T[]) => () => conn.window.showInformationMessage(s, ...actions); +