diff --git a/lib/Proteome/Data/ActiveProject.hs b/lib/Proteome/Data/ActiveProject.hs
--- a/lib/Proteome/Data/ActiveProject.hs
+++ b/lib/Proteome/Data/ActiveProject.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE RecordWildCards #-}
@@ -15,13 +14,15 @@
 import Neovim.Classes (NvimObject(..), Dictionary)
 import Proteome.Data.Project(
   ProjectName,
-  ProjectType
+  ProjectType,
+  ProjectLang
   )
 
 data ActiveProject =
   ActiveProject {
     name :: ProjectName,
-    tpe :: ProjectType
+    tpe :: ProjectType,
+    lang :: Maybe ProjectLang
   }
   deriving (Eq, Show, Generic, NFData)
 
@@ -30,6 +31,7 @@
     (toObject :: Dictionary -> Object) . Map.fromList $
     [
       ("name", toObject name),
-      ("tpe", toObject tpe)
+      ("tpe", toObject tpe),
+      ("lang", toObject lang)
     ]
   fromObject _ = Left "ActiveProject is write-only"
diff --git a/lib/Proteome/Plugin.hs b/lib/Proteome/Plugin.hs
--- a/lib/Proteome/Plugin.hs
+++ b/lib/Proteome/Plugin.hs
@@ -13,6 +13,7 @@
   function,
   function',
   command,
+  command',
   autocmd,
   Neovim,
   StartupConfig,
@@ -30,6 +31,7 @@
 import Proteome.Tags (proTags)
 import Proteome.Save (proSave)
 import Proteome.BufEnter (bufEnter)
+import Proteome.Project.Activate (proNext, proPrev)
 
 plugin' :: Ribosome (TVar Env) -> Plugin (Ribosome (TVar Env))
 plugin' env =
@@ -44,6 +46,8 @@
       $(command "ProAdd" 'proAddCmd) [CmdBang],
       $(function' 'proSave) Async,
       $(function' 'proTags) Async,
+      $(command' 'proNext) [],
+      $(command' 'proPrev) [],
       $(function' 'proReadConfig) Sync,
       $(autocmd 'bufEnter) "BufEnter" def
     ]
diff --git a/lib/Proteome/Project/Activate.hs b/lib/Proteome/Project/Activate.hs
--- a/lib/Proteome/Project/Activate.hs
+++ b/lib/Proteome/Project/Activate.hs
@@ -11,7 +11,7 @@
 import Control.Monad.IO.Class (liftIO)
 import Data.Maybe (fromMaybe)
 import System.Directory (doesDirectoryExist)
-import Neovim (vim_command')
+import Neovim (vim_command', CommandArguments, Neovim)
 import Ribosome.Config.Setting (updateSetting)
 import Ribosome.Data.Ribo (Ribo)
 import qualified Ribosome.Data.Ribo as Ribo (modify)
@@ -20,6 +20,7 @@
   ProjectMetadata(DirProject, VirtualProject),
   ProjectType(ProjectType),
   ProjectRoot(ProjectRoot),
+  ProjectName(ProjectName),
   )
 import Proteome.Data.ActiveProject (ActiveProject(ActiveProject))
 import Proteome.Data.Proteome (Proteome)
@@ -28,8 +29,8 @@
 import qualified Proteome.Settings as S (active)
 
 activeProject :: Project -> ActiveProject
-activeProject (Project (DirProject name _ tpe) _ _ _) = ActiveProject name (fromMaybe (ProjectType "none") tpe)
-activeProject (Project (VirtualProject name) _ _ _) = ActiveProject name (ProjectType "virtual")
+activeProject (Project (DirProject name _ tpe) _ lang _) = ActiveProject name (fromMaybe (ProjectType "none") tpe) lang
+activeProject (Project (VirtualProject name) _ lang _) = ActiveProject name (ProjectType "virtual") lang
 
 activateDirProject :: ProjectMetadata -> Ribo e ()
 activateDirProject (DirProject _ (ProjectRoot root) _) = do
@@ -42,10 +43,20 @@
   updateSetting S.active $ activeProject project
   activateDirProject (meta project)
 
+describeProject :: ProjectMetadata -> String
+describeProject (DirProject (ProjectName name) _ (Just (ProjectType tpe))) = tpe ++ "/" ++ name
+describeProject (DirProject (ProjectName name) _ Nothing) = name
+describeProject (VirtualProject (ProjectName name)) = name
+
+echoProjectActivation :: Project -> Neovim e ()
+echoProjectActivation pro =
+  vim_command' $ "echo 'activated project " ++ describeProject (meta pro) ++ "'"
+
 activateCurrentProject :: Proteome ()
 activateCurrentProject = do
   pro <- currentProject
   mapM_ activateProject pro
+  mapM_ echoProjectActivation pro
 
 setProjectIndex :: Int -> Proteome ()
 setProjectIndex index = do
@@ -63,12 +74,12 @@
   setProjectIndex index
   activateCurrentProject
 
-proPrev :: Proteome ()
-proPrev = do
+proPrev :: CommandArguments -> Proteome ()
+proPrev _ = do
   cycleProjectIndex (subtract 1)
   activateCurrentProject
 
-proNext :: Proteome ()
-proNext = do
+proNext :: CommandArguments -> Proteome ()
+proNext _ = do
   cycleProjectIndex (+1)
   activateCurrentProject
diff --git a/lib/Proteome/Project/Resolve.hs b/lib/Proteome/Project/Resolve.hs
--- a/lib/Proteome/Project/Resolve.hs
+++ b/lib/Proteome/Project/Resolve.hs
@@ -10,7 +10,7 @@
 import Control.Monad.IO.Class (liftIO)
 import Data.List (find)
 import Data.List.Utils (uniq)
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, isJust)
 import Data.Map.Strict ((!?), Map)
 import Safe (headMay)
 import System.Directory (doesDirectoryExist)
@@ -134,7 +134,7 @@
   IO Project
 resolveProject baseDirs explicit config root name tpe = do
   byType <- traverse (resolveByType baseDirs explicit root name) tpe
-  byName <- resolveByName baseDirs name
+  byName <- if isJust root then return Nothing else resolveByName baseDirs name
   let byNameOrVirtual = fromMaybe (virtualProject name) byName
   let byTypeOrName = fromMaybe byNameOrVirtual (join byType)
   let byRoot = root >>= resolveByRoot explicit
diff --git a/proteome.cabal b/proteome.cabal
--- a/proteome.cabal
+++ b/proteome.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.0.
+-- This file has been generated from package.yaml by hpack version 0.31.1.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: e9f2d71e222d4ffaa6e98b7cfdc7739cb4d796152685b6e2b1374b3c4124f5f2
+-- hash: c3e7f6db57fad18e70d0da04208bd17251306cc48e211187ce7e297bf9bf8016
 
 name:           proteome
-version:        0.3.13.0
+version:        0.3.14.0
 synopsis:       neovim project manager
 description:    Please see the README on GitHub at <https://github.com/tek/proteome-hs>
 category:       Neovim
diff --git a/test/u/CycleSpec.hs b/test/u/CycleSpec.hs
--- a/test/u/CycleSpec.hs
+++ b/test/u/CycleSpec.hs
@@ -5,6 +5,8 @@
 ) where
 
 import Control.Monad.IO.Class (liftIO)
+import Data.Default.Class (Default(def))
+import Data.Foldable (traverse_)
 import System.FilePath ((</>))
 import Neovim (Neovim)
 import Test.Framework
@@ -37,15 +39,9 @@
   proAdd $ AddOptions fn tp False
   proAdd $ AddOptions cn tp False
   assertDir prot
-  proNext
-  assertDir flag
-  proNext
-  assertDir cil
-  proNext
-  assertDir prot
-  proNext
-  assertDir flag
-  proPrev
+  let checkNext n = proNext def >> assertDir n
+  traverse_ checkNext [flag, cil, prot, flag]
+  proPrev def
   assertDir prot
 
 test_next :: IO ()
