Skip to content

Commit 4fa09e7

Browse files
committed
Handle errors
1 parent 67230a4 commit 4fa09e7

File tree

5 files changed

+53
-19
lines changed

5 files changed

+53
-19
lines changed

Sources/Vim/Vim.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,51 @@
11
import VimInterface
22

3+
enum VimError: Error {
4+
case invalidCall(String)
5+
}
6+
37
public struct Vim {
48
public static var current: Current {
59
return Current()
610
}
711

812
/// Run a vim command
9-
@discardableResult public static func command(_ cmd: String) -> VimValue? {
13+
@discardableResult public static func command(_ cmd: String) throws -> VimValue {
1014
var value: VimValue?
1115
cmd.withCString { cStr in
12-
//FIXME: handle error propagation
1316
if let result = swiftvim_command(
1417
UnsafeMutablePointer(mutating: cStr)) {
1518
value = VimValue(result)
1619
}
1720
}
18-
return value
21+
if let value = value {
22+
return value
23+
}
24+
throw getCallError(context: cmd)
1925
}
2026

2127
/// Evaluate an expression
22-
@discardableResult public static func eval(_ cmd: String) -> VimValue? {
28+
@discardableResult public static func eval(_ cmd: String) throws -> VimValue {
2329
var value: VimValue?
2430
cmd.withCString { cStr in
25-
//FIXME: handle error propagation
2631
if let result = swiftvim_eval(
2732
UnsafeMutablePointer(mutating: cStr)) {
2833
value = VimValue(result)
2934
}
3035
}
31-
return value
36+
if let value = value {
37+
return value
38+
}
39+
throw getCallError(context: cmd)
40+
}
41+
42+
private static func getCallError(context: String) -> VimError {
43+
if let error = swiftvim_get_error() {
44+
if let base = swiftvim_asstring(error) {
45+
return VimError.invalidCall(String(cString: base) + " - " + context)
46+
}
47+
}
48+
return VimError.invalidCall(context)
3249
}
3350
}
3451

Sources/VimInterface/include/VimInterface/swiftvim.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,6 @@ void *_Nullable swiftvim_call_impl(void *_Nonnull func, void *_Nullable arg1, vo
4747
void swiftvim_initialize();
4848
void swiftvim_finalize();
4949

50+
void *_Nullable swiftvim_get_error();
51+
52+

Sources/VimInterface/swiftvim_lib.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,17 @@ VIM_INTEN void swiftvim_finalize() {
319319
Py_Finalize();
320320
}
321321

322+
323+
VIM_INTEN void *_Nullable swiftvim_get_error() {
324+
if (PyErr_Occurred()) {
325+
PyObject *type, *value, *traceback;
326+
PyErr_Fetch(&type, &value, &traceback);
327+
if (value) {
328+
return value;
329+
} else {
330+
return type;
331+
}
332+
}
333+
return NULL;
334+
}
335+

Sources/VimKit/VimExtensions.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,27 @@ extension Vim {
2929
}
3030

3131
public static func set(variable: String, value: VimScriptConvertible) {
32-
command("let \(variable) = \(value.toVimScript())")
32+
_ = try? command("let \(variable) = \(value.toVimScript())")
3333
}
3434

3535
public static func get(variable: String) -> VimValue? {
36-
return eval(variable)
36+
return try? eval(variable)
3737
}
3838

3939
public static func get(_ variable: String) -> VimValue? {
40-
return eval(variable)
40+
return try? eval(variable)
4141
}
4242

4343
public static func get(_ variable: String) -> Bool {
44-
return eval(variable)?.asBool() ?? false
44+
return (try? eval(variable))?.asBool() ?? false
4545
}
4646

4747
public static func get(_ variable: String) -> Int {
48-
return eval(variable)?.asInt() ?? 0
48+
return (try? eval(variable))?.asInt() ?? 0
4949
}
5050

5151
public static func get(_ variable: String) -> String {
52-
return eval(variable)?.asString() ?? ""
52+
return (try? eval(variable))?.asString() ?? ""
5353
}
5454

5555
/// Returns the 0-based current line and 0-based current column

Tests/VimKitTests/VimValueTest.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,30 @@ class VimValueTests: XCTestCase {
3636

3737
func testEvalString() {
3838
swiftvim_initialize()
39-
let result = Vim.eval("VALUE")!
39+
let result = try! Vim.eval("VALUE")
4040
XCTAssertEqual(result.asString(), "VALUE")
4141
swiftvim_finalize()
4242
}
4343

4444
func testCommandNone() {
4545
swiftvim_initialize()
46-
let result = Vim.command("VALUE")!
46+
let result = try! Vim.command("VALUE")
4747
XCTAssertNil(result.asString())
4848
swiftvim_finalize()
4949
}
5050

5151
func testEvalInt() {
5252
swiftvim_initialize()
5353
mutateRuntime("eval", lambda: "lambda value : int(value)")
54-
let result = Vim.eval("2")!
54+
let result = try! Vim.eval("2")
5555
XCTAssertEqual(result.asInt(), 2)
5656
swiftvim_finalize()
5757
}
5858

5959
func testEvalList() {
6060
swiftvim_initialize()
6161
mutateRuntime("eval", lambda: "lambda value : [1, 2]")
62-
let result = Vim.eval("")!
62+
let result = try! Vim.eval("")
6363
let list = result.asList()!
6464
XCTAssertEqual(list.count, 2)
6565
XCTAssertEqual(list[0].asInt(), 1)
@@ -72,7 +72,7 @@ class VimValueTests: XCTestCase {
7272
func testListCollectionUsage() {
7373
swiftvim_initialize()
7474
mutateRuntime("eval", lambda: "lambda value : [1, 2]")
75-
let result = Vim.eval("")!
75+
let result = try! Vim.eval("")
7676
let list = result.asList()!
7777
/// Smoke test we can do collectiony things.
7878
let incremented = list.map { $0.asInt()! + 1 }
@@ -83,7 +83,7 @@ class VimValueTests: XCTestCase {
8383
func testEvalDict() {
8484
swiftvim_initialize()
8585
mutateRuntime("eval", lambda: "lambda value : dict(a=42, b='a')")
86-
let result = Vim.eval("")!
86+
let result = try! Vim.eval("")
8787
let dict = result.asDictionary()!
8888
let aVal = dict["a"]!
8989
XCTAssertEqual(aVal.asInt()!, 42)
@@ -96,7 +96,7 @@ class VimValueTests: XCTestCase {
9696
func testDictCollectionUsage() {
9797
swiftvim_initialize()
9898
mutateRuntime("eval", lambda: "lambda value : dict(a=42, b='a')")
99-
let result = Vim.eval("")!
99+
let result = try! Vim.eval("")
100100
let dict = result.asDictionary()!
101101
XCTAssertEqual(dict.keys.count, 2)
102102
XCTAssertEqual(dict.values.count, 2)

0 commit comments

Comments
 (0)