diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 2.1.0.2
+
+* Exported functions and commands now can have the same name.
+
 # 2.1.0.0
 
 * Autocommands now take an additional parameter of type `Synchronous`, allowing
diff --git a/library/Neovim/API/TH.hs b/library/Neovim/API/TH.hs
--- a/library/Neovim/API/TH.hs
+++ b/library/Neovim/API/TH.hs
@@ -391,7 +391,7 @@
 command :: String -> Name -> Q Exp
 command [] _ = error "Empty names are not allowed for exported commands."
 command customFunctionName@(c:_) functionName
-    | (not . isUpper) c = error $ "Custom command name must start with a capiatl letter: " <> show customFunctionName
+    | (not . isUpper) c = error $ "Custom command name must start with a capital letter: " <> show customFunctionName
     | otherwise = do
         (argTypes, fun) <- functionImplementation functionName
         -- See :help :command-nargs for what the result strings mean
diff --git a/library/Neovim/Context/Internal.hs b/library/Neovim/Context/Internal.hs
--- a/library/Neovim/Context/Internal.hs
+++ b/library/Neovim/Context/Internal.hs
@@ -168,12 +168,12 @@
 -- a thread that reads from a 'TQueue'. (NB: persistent currently means, that
 -- state is stored for as long as the plugin provider is running and not
 -- restarted.)
-type FunctionMap = Map FunctionName FunctionMapEntry
+type FunctionMap = Map NvimMethod FunctionMapEntry
 
 
 -- | Create a new function map from the given list of 'FunctionMapEntry' values.
 mkFunctionMap :: [FunctionMapEntry] -> FunctionMap
-mkFunctionMap = Map.fromList . map (\e -> (name (fst e), e))
+mkFunctionMap = Map.fromList . map (\e -> (nvimMethod (fst e), e))
 
 
 -- | A wrapper for a reader value that contains extra fields required to
@@ -238,10 +238,10 @@
         :: (FunctionalityDescription
             -> ([Object] -> Neovim env Object)
             -> TQueue SomeMessage
-            -> TVar (Map FunctionName ([Object] -> Neovim env Object))
+            -> TVar (Map NvimMethod ([Object] -> Neovim env Object))
             -> Neovim env (Maybe FunctionMapEntry))
         -> TQueue SomeMessage
-        -> TVar (Map FunctionName ([Object] -> Neovim env Object))
+        -> TVar (Map NvimMethod ([Object] -> Neovim env Object))
         -> PluginSettings env
 
 
diff --git a/library/Neovim/Plugin.hs b/library/Neovim/Plugin.hs
--- a/library/Neovim/Plugin.hs
+++ b/library/Neovim/Plugin.hs
@@ -81,7 +81,7 @@
 -- Note that this does not have any effect on the side of /nvim-hs/.
 registerWithNeovim :: FunctionalityDescription -> Neovim anyEnv Bool
 registerWithNeovim = \case
-    Function (F functionName) s -> do
+    func@(Function (F functionName) s) -> do
         pName <- getProviderName
         let (defineFunction, host) = either
                 (\n -> ("remote#define#FunctionOnHost", toObject n))
@@ -98,10 +98,10 @@
 
         flip catch reportError $ do
           void $ vim_call_function defineFunction $
-            host +: functionName +: s +: functionName +: (Map.empty :: Dictionary) +: []
+            host +: nvimMethodName (nvimMethod func) +: s +: functionName +: (Map.empty :: Dictionary) +: []
           logSuccess
 
-    Command (F functionName) copts -> do
+    cmd@(Command (F functionName) copts) -> do
         let sync = case getCommandOptions copts of
                     -- This works because CommandOptions are sorted and CmdSync is
                     -- the smallest element in the sorting
@@ -123,7 +123,7 @@
                 return True
         flip catch reportError $ do
           void $ vim_call_function defineFunction $
-            host +: functionName +: sync +: functionName +: copts +: []
+            host +: nvimMethodName (nvimMethod cmd) +: sync +: functionName +: copts +: []
           logSuccess
 
     Autocmd acmdType (F functionName) sync opts -> do
@@ -212,7 +212,7 @@
     funMap <- Internal.asks' Internal.globalFunctionMap
     liftIO . atomically $ do
         m <- takeTMVar funMap
-        putTMVar funMap $ Map.insert ((name . fst) e) e m
+        putTMVar funMap $ Map.insert ((nvimMethod . fst) e) e m
     liftIO . debugM logger $ "Added function to global function map." ++ show (fst e)
 
 registerPlugin
@@ -220,11 +220,11 @@
     -> FunctionalityDescription
     -> ([Object] -> Neovim env Object)
     -> TQueue SomeMessage
-    -> TVar (Map FunctionName ([Object] -> Neovim env Object))
+    -> TVar (Map NvimMethod ([Object] -> Neovim env Object))
     -> Neovim env (Maybe FunctionMapEntry)
 registerPlugin reg d f q tm = registerWithNeovim d >>= \case
     True -> do
-        let n = name d
+        let n = nvimMethod d
             e = (d, Stateful q)
         liftIO . atomically . modifyTVar tm $ Map.insert n f
         reg e
@@ -305,25 +305,27 @@
 
 
     listeningThread :: TQueue SomeMessage
-                    -> TVar (Map FunctionName ([Object] -> Neovim env Object))
+                    -> TVar (Map NvimMethod ([Object] -> Neovim env Object))
                     -> Neovim env ()
     listeningThread q route = do
         msg <- readSomeMessage q
 
-        forM_ (fromMessage msg) $ \req@Request{..} -> do
+        forM_ (fromMessage msg) $ \req@(Request fun@(F methodName) _ args) -> do
+            let method = NvimMethod methodName
             route' <- liftIO $ readTVarIO route
-            forM_ (Map.lookup reqMethod route') $ \f -> do
+            forM_ (Map.lookup method route') $ \f -> do
                 respond req . either Left id =<< race
-                    (timeoutAndLog 10 reqMethod)
-                    (executeFunction f reqArgs)
+                    (timeoutAndLog 10 fun)
+                    (executeFunction f args)
 
-        forM_ (fromMessage msg) $ \Notification{..} -> do
+        forM_ (fromMessage msg) $ \(Notification fun@(F methodName) args) -> do
+            let method = NvimMethod methodName
             route' <- liftIO $ readTVarIO route
-            forM_ (Map.lookup notMethod route') $ \f ->
+            forM_ (Map.lookup method route') $ \f ->
                 void . async $ do
                     result <- either Left id <$> race
-                        (timeoutAndLog 600 notMethod)
-                        (executeFunction f notArgs)
+                        (timeoutAndLog 600 fun)
+                        (executeFunction f args)
                     case result of
                       Left message ->
                           nvim_err_writeln message
diff --git a/library/Neovim/Plugin/Classes.hs b/library/Neovim/Plugin/Classes.hs
--- a/library/Neovim/Plugin/Classes.hs
+++ b/library/Neovim/Plugin/Classes.hs
@@ -14,6 +14,7 @@
 module Neovim.Plugin.Classes (
     FunctionalityDescription(..),
     FunctionName(..),
+    NvimMethod(..),
     Synchronous(..),
     CommandOption(..),
     CommandOptions,
@@ -426,7 +427,7 @@
 
 
 instance NvimObject AutocmdOptions where
-    toObject (AutocmdOptions{..}) =
+    toObject AutocmdOptions{..} =
         (toObject :: Dictionary -> Object) . Map.fromList $
             [ ("pattern", toObject acmdPattern)
             , ("nested", toObject acmdNested)
@@ -436,9 +437,22 @@
     fromObject o = throwError  $
         "Did not expect to receive an AutocmdOptions object: " <+> viaShow o
 
+newtype NvimMethod =
+  NvimMethod { nvimMethodName :: ByteString }
+  deriving (Eq, Ord, Show, Read, Generic)
+
+
+instance NFData NvimMethod
+
+
+instance Pretty NvimMethod where
+    pretty (NvimMethod n) = pretty $ decodeUtf8 n
+
+
 -- | Conveniennce class to extract a name from some value.
 class HasFunctionName a where
     name :: a -> FunctionName
+    nvimMethod :: a -> NvimMethod
 
 
 instance HasFunctionName FunctionalityDescription where
@@ -447,3 +461,7 @@
         Command   n _ -> n
         Autocmd _ n _ _ -> n
 
+    nvimMethod = \case
+        Function (F n) _ -> NvimMethod $ n <> ":function"
+        Command (F n) _ -> NvimMethod $ n <> ":command"
+        Autocmd _ (F n) _ _ -> NvimMethod n
diff --git a/library/Neovim/Plugin/Internal.hs b/library/Neovim/Plugin/Internal.hs
--- a/library/Neovim/Plugin/Internal.hs
+++ b/library/Neovim/Plugin/Internal.hs
@@ -43,6 +43,7 @@
 
 instance HasFunctionName (ExportedFunctionality env) where
     name = name . getDescription
+    nvimMethod = nvimMethod . getDescription
 
 
 -- | This data type contains meta information for the plugin manager.
diff --git a/library/Neovim/RPC/SocketReader.hs b/library/Neovim/RPC/SocketReader.hs
--- a/library/Neovim/RPC/SocketReader.hs
+++ b/library/Neovim/RPC/SocketReader.hs
@@ -22,6 +22,7 @@
 import           Neovim.Plugin.Classes      (CommandArguments (..),
                                              CommandOption (..),
                                              FunctionName (..),
+                                             NvimMethod (..),
                                              FunctionalityDescription (..),
                                              getCommandOptions)
 import           Neovim.Plugin.IPC.Classes
@@ -105,7 +106,7 @@
 -- function call identifier.
 handleRequestOrNotification :: Maybe Int64 -> FunctionName -> [Object]
                             -> ConduitT a Void SocketHandler ()
-handleRequestOrNotification requestId functionToCall params = do
+handleRequestOrNotification requestId functionToCall@(F functionName) params = do
     cfg <- lift Internal.ask'
     void . liftIO . async $ race logTimeout (handle cfg)
     return ()
@@ -114,7 +115,7 @@
     lookupFunction
         :: TMVar Internal.FunctionMap
         -> STM (Maybe (FunctionalityDescription, Internal.FunctionType))
-    lookupFunction funMap = Map.lookup functionToCall <$> readTMVar funMap
+    lookupFunction funMap = Map.lookup (NvimMethod functionName) <$> readTMVar funMap
 
     logTimeout :: IO ()
     logTimeout = do
diff --git a/nvim-hs.cabal b/nvim-hs.cabal
--- a/nvim-hs.cabal
+++ b/nvim-hs.cabal
@@ -1,5 +1,5 @@
 name:                nvim-hs
-version:             2.1.0.0
+version:             2.1.0.2
 synopsis:            Haskell plugin backend for neovim
 description:
   This package provides a plugin provider for neovim. It allows you to write
diff --git a/test-suite/Neovim/API/THSpec.hs b/test-suite/Neovim/API/THSpec.hs
--- a/test-suite/Neovim/API/THSpec.hs
+++ b/test-suite/Neovim/API/THSpec.hs
@@ -18,8 +18,6 @@
 import           Test.Hspec
 import           Test.QuickCheck
 
-import           Control.Applicative
-
 call :: ([Object] -> Neovim () Object) -> [Object]
      -> IO Object
 call f args = do
@@ -73,7 +71,7 @@
 
 
   describe "generating a command from the two argument test function" $ do
-      let EF (Command fname _, testFun) = $(command' 'testFunction2) []
+      let EF (Command fname _, _) = $(command' 'testFunction2) []
       it "should capitalize the first character" $
         fname `shouldBe` (F "TestFunction2")
 
@@ -111,7 +109,7 @@
     it "should capitalize the first letter" $
         cname `shouldBe` (F "TestCommandOptArgument")
 
-    it "should return \"defalt\" when passed no argument" $ do
+    it "should return \"default\" when passed no argument" $ do
         call testFun [defCmdArgs] `shouldReturn` toObject ("default" :: String)
 
     it "should return what is passed otherwise" . property $ do
diff --git a/test-suite/Neovim/Plugin/ClassesSpec.hs b/test-suite/Neovim/Plugin/ClassesSpec.hs
--- a/test-suite/Neovim/Plugin/ClassesSpec.hs
+++ b/test-suite/Neovim/Plugin/ClassesSpec.hs
@@ -39,7 +39,7 @@
             2 -> return $ CmdNargs ""
             3 -> CmdRange <$> elements [CurrentLine, WholeFile, RangeCount 1]
             4 -> CmdCount <$> arbitrary
-            5 -> return CmdBang
+            _ -> return CmdBang
         return $ RCO o
 
 
diff --git a/test-suite/Neovim/RPC/SocketReaderSpec.hs b/test-suite/Neovim/RPC/SocketReaderSpec.hs
--- a/test-suite/Neovim/RPC/SocketReaderSpec.hs
+++ b/test-suite/Neovim/RPC/SocketReaderSpec.hs
@@ -4,11 +4,9 @@
 
 import           Neovim
 import           Neovim.Plugin.Classes
-import           Neovim.RPC.Common
 import           Neovim.RPC.SocketReader (parseParams)
 
 import           Test.Hspec
-import           Test.QuickCheck
 
 spec :: Spec
 spec = do
