Skip to content

Commit 67062c4

Browse files
committed
refactor and improvement
1 parent 4552da3 commit 67062c4

File tree

6 files changed

+40
-39
lines changed

6 files changed

+40
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
99
- fix typo
1010
- use absolute path for GHCi
1111
- add activation event (in a stack project)
12+
- change behavior of `Load GHCi` when not in a Haskell file
1213

1314
## [0.1.2]
1415

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ Required: `ghc` and `stack`.
1717

1818
The following configurations are available:
1919

20-
* `runner2.stackPath`: path for `stack` executable (default `stack`)
20+
* `runner2.stackPath`: path for stack executable (default `stack`)
2121
* `runner2.stackRepl`: use `stack repl` instead of `ghci`, you may like to turn it on in stack projects (default `false`)
22-
* `runner2.stackRun`: show `stack run` button (default `false`)
23-
24-
> You need to reload the extension after updating config
22+
* `runner2.stackRun`: show "Stack Run" button, *reload required* (default `false`)
2523

2624
## Release Notes
2725

src/config.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ export function getConfig(): Config {
1212
function getConfOption<T>(name: string, def: T): T {
1313
return option.option<T>(config.get(name)).orelse(def);
1414
}
15-
16-
let stack = getConfOption<string>("runner2.stackPath", "stack");
17-
let repl = getConfOption<boolean>("runner2.stackRepl", false);
15+
let stack = getConfOption("runner2.stackPath", "stack");
16+
let repl = getConfOption("runner2.stackRepl", false);
1817
return {
1918
stackPath: stack,
2019
ghciTool: repl ? (stack + " repl") : "ghci",
21-
enableStackRun: getConfOption<boolean>("runner2.stackRun", false)
20+
enableStackRun: getConfOption("runner2.stackRun", false)
2221
};
2322
}

src/extension.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,60 +6,52 @@ import * as conf from './config';
66
import * as util from './util';
77

88
// configuration
9-
const config = conf.getConfig();
10-
9+
var config: conf.Config = conf.getConfig();
10+
// current terminal
1111
var terminal: option.Option<vscode.Terminal> = option.none();
1212

13-
// this method is called when your extension is activated
14-
// your extension is activated the very first time the command is executed
13+
// I'm not sure if we can do `async` here
1514
export async function activate(context: vscode.ExtensionContext) {
1615
// setup terminal
1716
vscode.window.onDidChangeActiveTerminal(e => { terminal = option.option(e); });
17+
// update config
18+
vscode.workspace.onDidChangeConfiguration(e => { config = conf.getConfig(); });
1819

1920
// check stack project
2021
let stackproj = (await vscode.workspace.findFiles("stack.yaml")).length > 0;
2122

2223
// GHCi command
2324
let ghci = vscode.commands.registerCommand("runner2.ghci", () => {
24-
let doc = option.option(vscode.window.activeTextEditor).map(e => e.document);
25-
let filename = doc
26-
.flatmap(d => util.isHaskell(d) ? option.some(d) : option.none<vscode.TextDocument>())
25+
let filename = option.option(vscode.window.activeTextEditor)
26+
.map(e => e.document)
27+
.flatmap(d => option.filterOption(util.isHaskell, d))
2728
.map(s => `\"${s.fileName}\"`);
2829
// currently at GHCi
2930
if (terminal.map(t => t.name).contains("GHCi")) {
3031
filename.map(f => terminal.unwrap().sendText(stackproj ? ":r" : (":l " + f)));
3132
} else {
32-
filename.map(f => {
33-
let t = vscode.window.createTerminal("GHCi");
34-
t.sendText(config.ghciTool + " " + (stackproj ? "" : f));
35-
t.show();
36-
});
33+
let term = vscode.window.createTerminal("GHCi");
34+
term.sendText(config.ghciTool + " " + (stackproj ? "" : filename.orelse("")));
35+
term.show();
3736
}
3837
});
3938
context.subscriptions.push(ghci);
4039

4140
// stack project commands
42-
context.subscriptions.push(vscode.commands.registerCommand(
43-
"runner2.stacktest", util.simplTerm("Stack Test", config.stackPath + " test")));
44-
context.subscriptions.push(vscode.commands.registerCommand(
45-
"runner2.stackbuild", util.simplTerm("Stack Build", config.stackPath + " build")));
46-
context.subscriptions.push(vscode.commands.registerCommand(
47-
"runner2.stackrun", util.simplTerm("Stack Run", config.stackPath + " run")));
41+
util.registerSimplTerm(context, "runner2.stacktest", "Stack Test", config.stackPath + " test");
42+
util.registerSimplTerm(context, "runner2.stackbuild", "Stack Build", config.stackPath + " build");
43+
util.registerSimplTerm(context, "runner2.stackrun", "Stack Run", config.stackPath + " run");
4844

4945
// button setup
50-
context.subscriptions.push(util.statButton("Load GHCi", "runner2.ghci"));
46+
util.resgisterStatButton(context, "Load GHCi", "runner2.ghci");
5147
// button for stack project
5248
if (stackproj) {
53-
context.subscriptions.push(
54-
util.statButton("Stack Build", "runner2.stackbuild"),
55-
util.statButton("Stack Test", "runner2.stacktest")
56-
);
49+
util.resgisterStatButton(context, "Stack Build", "runner2.stackbuild");
50+
util.resgisterStatButton(context, "Stack Test", "runner2.stacktest");
5751
if (config.enableStackRun) {
58-
context.subscriptions.push(
59-
util.statButton("Stack Run", "runner2.stackrun"));
52+
util.resgisterStatButton(context, "Stack Run", "runner2.stackrun");
6053
}
6154
}
62-
6355
}
6456

6557
// this method is called when your extension is deactivated

src/option.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Some<T> implements Option<T> {
2929
}
3030
}
3131

32+
// note: it should be Option[Nothing] instead of Option[Any]
3233
class None implements Option<any> {
3334
isEmpty: boolean;
3435
constructor() {
@@ -64,3 +65,7 @@ export function some<T>(u: T): Option<T> {
6465
export function none<T>(): Option<T> {
6566
return new None;
6667
}
68+
69+
export function filterOption<T>(p: (v: T) => Boolean, v: T): Option<T> {
70+
return p(v) ? new Some(v) : new None;
71+
}

src/util.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import * as vscode from 'vscode';
22

33
// create status bar button
4-
export function statButton(name: string, command: string, align = vscode.StatusBarAlignment.Left, priority = 10) {
4+
export function resgisterStatButton(
5+
context: vscode.ExtensionContext,
6+
name: string,
7+
command: string,
8+
align = vscode.StatusBarAlignment.Left,
9+
priority = 10) {
10+
511
let stat = vscode.window.createStatusBarItem(align, priority);
612
stat.text = name;
713
stat.command = command;
814
stat.show();
9-
return stat;
15+
context.subscriptions.push(stat);
1016
}
1117

1218
// create a terminal and send command
13-
export function simplTerm(name: string, cmd: string) {
14-
return () => {
19+
export function registerSimplTerm(context: vscode.ExtensionContext, command: string, name: string, cmd: string) {
20+
context.subscriptions.push(vscode.commands.registerCommand(command, () => {
1521
let t = vscode.window.createTerminal(name);
1622
t.sendText(cmd);
1723
t.show();
18-
};
24+
}));
1925
}
2026

2127
// is a haskell file

0 commit comments

Comments
 (0)