Yiが定義する型の紹介 - Haskell Advent Calendar 2016 - 4日目

Posted on 2016/12/02
Tags: AdventCalendar, Haskell

 ドーモ、fix関数の簡約が「いい感じにやる」といった理解しかできないあいやです。
この記事はHaskell Advent Calendar 2016 4日目の記事です。

私何もあげられるものないから、yiの型書くよ!

 この記事ではYi型とyiエディタの区別をするために、yiエディタのことは「yi」と呼称します :)

Yiにコントリビュートしつつ解釈したものなので、間違ってたらごめんなさい ;(

instanceの定義は省略します。

目次

動作

 yiの動的な影響を及ぼす操作を記述することができます。
キーバインドに設定される動作にもなったりします。


newtype EditorM a = EditorM { fromEditorM :: ReaderT Config (State Editor) a }
    deriving (Monad, Applicative, MonadState Editor, MonadReader Config, Functor, Typeable)

 yiの状態と動作を持ちますが、IOは持ちません。
ReaderTとStateにより、Configの読み込みとEditorへの変更を行います。
例えば、現在保持しているバッファの一覧、バッファの追加などを取得したりできます。
(設定の読み込みと状態の変更)

withEditor :: MonadEditor m => EditorM a -> m a関数でYiMに変換できたりします。


newtype YiM a =  YiM { runYiM :: ReaderT Yi IO a } 
    deriving (Monad, Applicative, MonadReader Yi, MonadBase IO, Typeable, Functor)

 yiの状態と動作を持ちますが、IOを含むので何でもできます。 liftBaseすればそのままIOモナドになるので。
MonadState EditorになっていることとYiConfigを持っていることで、 やはりこちらもEditorMと同じことを行えます。
でもできるだけEditorMを使った方がいい :(

状態


data Config = Config
  { startFrontEnd :: UIBoot
  , configUI :: UIConfig
  , startActions :: [Action]
  , initialActions :: [Action]
  , defaultKm :: KeymapSet
  , configInputPreprocess :: P Event Event
  , modeTable :: [AnyMode]
  , debugMode :: Bool
  , configRegionStyle :: RegionStyle
  , configKillringAccumulate :: Bool
  , configCheckExternalChangesObsessively :: Bool
  , bufferUpdateHandler :: [[Update] -> BufferM ()]
  , layoutManagers :: [AnyLayoutManager]
  , configVars :: ConfigState.DynamicState
  }

 yi上のキーマッピング情報などの、yi起動以前に設定した情報を表します。
例えば、initialActionsでctagsなどのタグ情報を読み込む方法を設定しておいたりします。


data Editor = Editor
  { bufferStack     :: !(NonEmpty BufferRef)
  , buffers         :: !(Map BufferRef FBuffer)
  , refSupply       :: !Int
  , tabs_           :: !(PointedList Tab)
  , dynamic         :: !DynamicState.DynamicState
  , statusLines     :: !Statuses
  , maxStatusHeight :: !Int
  , killring        :: !Killring
  , currentRegex    :: !(Maybe SearchExp)
  , searchDirection :: !Direction
  , pendingEvents   :: ![Event]
  , onCloseActions  :: !(Map BufferRef (EditorM ()))
  } deriving Typeable

 動的な状態を保持します。
UIに実際に表示されているタブやバッファ、検索中の単語(もとい表現)と検索状態などを保持します。


data Yi = Yi
  { yiUi          :: UI Editor
  , yiInput       :: [Event] -> IO ()
  , yiOutput      :: IsRefreshNeeded -> [Action] -> IO ()
  , yiConfig      :: Config
  , yiVar         :: MVar YiVar
  } deriving Typeable

 動的な状態を保持します。 他の状態用の型とは違って、外界へのアクセスを許されているっぽい。

バッファ


data BufferId = MemBuffer Text
              | FileBuffer FilePath
              deriving (Show, Eq, Ord)

あるバッファの種別です。
Attributesという形でFBufferから保持されます。


data FBuffer = forall syntax. FBuffer
  { bmode  :: !(Mode syntax)
  , rawbuf :: !(BufferImpl syntax)
  , attributes :: !Attributes
  } deriving Typeable

 具体的なバッファの値を指します。
BufferImplとAttributesを統合して保持します。
BufferRefから参照されます。

 これはEditorbuffersから取得できます。


data BufferImpl syntax = FBufferData
  { mem         :: !YiString
  , marks       :: !Marks
  , markNames   :: !(Map String Mark)
  , hlCache     :: !(HLState syntax)
  , overlays    :: !(Set Overlay)
  , dirtyOffset :: !Point
  } deriving Typeable

 バッファ内のテキストやハイライトを値でを保持します。


newtype BufferRef = BufferRef Int
    deriving (Eq, Ord, Typeable, Binary, Num)
instance Show BufferRef

 バッファの参照を持ちます。
バッファの具体的な内容は持ちません。

こんな感じで

 yiが出来る。 (雑)



この記事はこちらから修正リクエストを送ることができます。
Yiが定義する型の紹介 - Haskell Advent Calendar 2016 - 4日目 - github
ゴミ箱ボタンの左にある、鉛筆ボタンを押してね!