diff --git a/HexChat.hs b/HexChat.hs
--- a/HexChat.hs
+++ b/HexChat.hs
@@ -76,7 +76,7 @@
 --
 -- The type parameter signifies the return type of the initializer and has no special meaning otherwise, you can specialize it to anything you want.
 --
--- If you need to pass a lot of data to the deinitializer you could simply let @a ~ IO ()@ and @'modDeinit' = id@, such as in the following:
+-- If you need to pass a lot of data to the deinitializer you could simply let @a ~ 'IO' ()@ and @'modDeinit' = 'id'@, such as in the following:
 --
 -- @
 -- info = 'modInfo'
diff --git a/hexchat.cabal b/hexchat.cabal
--- a/hexchat.cabal
+++ b/hexchat.cabal
@@ -1,5 +1,5 @@
 name:                hexchat
-version:             0.0.1.0
+version:             0.0.2.0
 synopsis:            Haskell scripting interface for HexChat
 description:
  This package builds a shared object ready for loading into HexChat, that will compile and interpret scripts written in Haskell; and also a Haskell library that said scripts should import and use to interface with HexChat.
@@ -10,8 +10,13 @@
  .
  For instructions on how to write a script, see the 'HexChat' module.
  .
- Currently the plugin only understands the classic @/load@, @/unload@, @/reload@ commands.
+ The plugin understands the classic @/load@, @/unload@, @/reload@ commands, as well as:
  .
+ > /hs load <filename>
+ > /hs unload <filename>
+ > /hs reload <filename>
+ > /hs list
+ .
  To automatically load the plugin symlink or copy @~\/.cabal\/lib\/libhexchat-haskell.so@ (or @\/usr\/local\/lib\/libhexchat-haskell.so@) to @~\/.config\/hexchat\/addons\/@ (or @\/usr\/lib\/hexchat\/plugins\/@).
 license:             MIT
 license-file:        LICENSE
@@ -35,5 +40,5 @@
   c-sources:           plugin/plugin.c
   other-modules:       HexChat.Linker, Paths_hexchat
   other-extensions:    CApiFFI
-  build-depends:       base >=4.10 && <4.11, deepseq >= 1.0 && < 1.5, ghc-prim >=0.5 && <0.6, ghc-paths >=0.1 && <0.2, ghc >= 8.0 && < 8.3, ghci >= 8.0 && < 8.3, hexchat == 0.0.0.0
+  build-depends:       base >=4.10 && <4.11, deepseq >= 1.0 && < 1.5, ghc-prim >=0.5 && <0.6, ghc-paths >=0.1 && <0.2, ghc >= 8.0 && < 8.3, ghci >= 8.0 && < 8.3, hexchat == 0.0.2.0
   default-language:    Haskell2010
diff --git a/plugin/HexChat/Linker.hs b/plugin/HexChat/Linker.hs
--- a/plugin/HexChat/Linker.hs
+++ b/plugin/HexChat/Linker.hs
@@ -95,7 +95,7 @@
 			return True
 
 unloadScript :: Bool -> String -> Ghc Bool
-unloadScript sup file = reportException (return True) $ do
+unloadScript sup file = reportException (return False) $ do
 	mf <- liftIO $ find (\s -> scriptFile s == file) <$> readIORef scripts
 	case mf of
 		Nothing -> if sup then return False else liftIO $ evaluate $ error "No such script"
@@ -110,25 +110,59 @@
 	I.pluginguiRemove plugin $ scriptHandle s
 	finally (modDeinit (scriptInfo s) (scriptNonce s)) $ I.unhookHandle $ scriptHandle s
 
-commandLoad, commandUnload, commandReload :: [String] -> [String] -> Ghc Eat
-commandLoad w we = do
-	let (_:file:_) = w
+commandLoad, commandUnload, commandReload, commandHs :: [String] -> [String] -> Ghc Eat
+commandLoad _ (_:file:_) = do
 	b <- loadScript True file
 	return (if b then EatAll else EatNone)
+commandLoad _ _ = return EatNone
 
-commandUnload w we = do
-	let (_:file:_) = w
+commandUnload _ (_:file:_) = do
 	b <- unloadScript True file
 	return (if b then EatAll else EatNone)
+commandUnload _ _ = return EatNone
 
-commandReload w we = do
-	let (_:file:_) = w
+commandReload _ (_:file:_) = do
 	b <- unloadScript True file
 	if not b then return EatNone
 		else do
 			loadScript False file
 			return EatAll
+commandReload _ _ = return EatNone
 
+commandHsHelp :: String
+commandHsHelp =
+	"Usage: /hs load <filename>\n" ++
+	"           unload <filename>\n" ++
+	"           reload <filename>\n" ++
+	"           list\n"
+
+commandHs (_:"load":_) (_:_:file:_) = do
+	loadScript False file
+	return EatAll
+commandHs (_:"unload":_) (_:_:file:_) = do
+	unloadScript False file
+	return EatAll
+commandHs (_:"reload":_) (_:_:file:_) = do
+	b <- unloadScript False file
+	if not b then return EatAll
+		else do
+			loadScript False file
+			return EatAll
+commandHs (_:"list":_) _ = liftIO $ do
+	ss <- readIORef scripts
+	mapM print $ zipWith4 (\n v f d -> n ++ "  " ++ v ++ "  " ++ f ++ "  " ++ d)
+		(pad $ "Name" : map (modName . scriptInfo) ss)
+		(pad $ "Version" : map (modVersion . scriptInfo) ss)
+		(pad $ "Filename" : map scriptFile ss)
+		("Description" : map (modDescription . scriptInfo) ss)
+	return EatAll
+	where
+		pad xs = let len = maximum $ map length xs
+			in map (\x -> x ++ replicate (len - length x) ' ') xs
+commandHs _ _ = do
+	liftIO $ print commandHsHelp
+	return EatAll
+
 foreign export ccall plugin_init :: I.Plugin_Init
 foreign export ccall plugin_deinit :: I.Plugin_Deinit
 
@@ -143,9 +177,10 @@
 plugin_init plugin pname pdesc pver arg = reportException (return 0) $ do
 	I.initStaticData plugin
 
+	let versionStr = showVersion version ++ "/" ++ cProjectVersion
 	name <- newCString "Haskell"
-	desc <- newCString "Haskell scripting plugin"
-	ver <- newCString $ showVersion version ++ "/" ++ cProjectVersion
+	desc <- newCString "Haskell scripting interface"
+	ver <- newCString versionStr
 	modifyIORef borrowedStrings ([name, desc, ver] ++)
 
 	poke pname name
@@ -161,6 +196,9 @@
 			hookCommand "load" pri_NORM "" $ \w we -> reflectGhc (commandLoad w we) s
 			hookCommand "unload" pri_NORM "" $ \w we -> reflectGhc (commandUnload w we) s
 			hookCommand "reload" pri_NORM "" $ \w we -> reflectGhc (commandReload w we) s
+			hookCommand "hs" pri_NORM commandHsHelp $ \w we -> reflectGhc (commandHs w we) s
+
+			print $ "Haskell interface (" ++ versionStr ++ ") loaded"
 
 		return 1
 
