VimまたはEmacsの経験が不足しているため、Cuaシミュレーションのみが適しています。 ホットキーはほとんどありませんが、私にはよく知られています。 それで、私はそれから始めて、自分のために設定を書くことに決めました。
通常のグラフィックエディターでは、メニューを使用する便利な方法のように思えます。 Altキーを押すと、メニューが開き、各要素に下線付きの文字が表示されます。この要素をクリックして選択します。
したがって、すべてのコマンドを一度に記憶する必要はありませんが、メニューを覗いて徐々に使い始めることができます。
私はYiで似たようなものを台無しにすることにしました。
簡単なホットキーを設定します
最初に、Yiの仕組みを理解する必要があります。 これを理解する最も簡単な方法は、 Cuaなどの既製のバインダーを見ることです。 これは切り捨てられており、VimおよびEmacsのアナログバインダーよりもはるかに原始的ですが、私たちの目的(独自の記述)のために-それだけです。
まず、ホットキーの一般的な定義方法に注目しましょう。 これはメイン関数で見ることができます。
keymap :: KeymapSet keymap = portableKeymap ctrl -- | Introduce a keymap that is compatible with both windows and osx, -- by parameterising the event modifier required for commands portableKeymap :: (Event -> Event) -> KeymapSet portableKeymap cmd = modelessKeymapSet $ selfInsertKeymap <|> move <|> select <|> rect <|> other cmd
さまざまなバインドオプションは、<|>演算子を使用して結合されます。 他のコマンドをさらに見てみましょう:
other cmd = choice [ spec KBS ?>>! deleteSel bdeleteB, spec KDel ?>>! deleteSel (deleteN 1), spec KEnter ?>>! replaceSel "\n", cmd (char 'q') ?>>! askQuitEditor, cmd (char 'f') ?>> isearchKeymap Forward, cmd (char 'x') ?>>! cut, cmd (char 'c') ?>>! copy, cmd (char 'v') ?>>! paste, cmd (spec KIns) ?>>! copy, shift (spec KIns) ?>>! paste, cmd (char 'z') ?>>! undoB, cmd (char 'y') ?>>! redoB, cmd (char 's') ?>>! fwriteE, cmd (char 'o') ?>>! findFile, cmd (char '/') ?>>! withModeB modeToggleCommentSelection, cmd (char ']') ?>>! autoIndentB IncreaseOnly, cmd (char '[') ?>>! autoIndentB DecreaseOnly ]
ご覧のとおり、左側にキーボードショートカット、右側にアクションがあります。 つまり cmd(char 'c')を押すと(デフォルトではcmdはctrlです)-コピーが取得され、そのコードも簡単です。
これらの定義を自分にコピーし、何らかのメニューを作成するために編集を開始することにしました。
メニューの作り方
メニューの実装方法を決定するには、モジュールのドキュメントに移動する必要があります 。 すべてが非常に便利に構成されており、 Yi.MiniBufferモジュールが目を引きます。 どうやら、これが必要なものです。 機能があります
spawnMinibufferE :: String -> KeymapEndo -> EditorM BufferRef
表示されたテキストと、キーへのバインディングを公開する関数を受け入れます。 つまり 必要なもの。 行にメニュー項目を表示し、バインダーではキーによるメニュー項目の選択をキャッチします。
まず、メニューの説明に便利なタイプを作成します。 メニューは項目のリストで構成され、各項目はサブメニューを開くか、何らかのアクションです。 だから私たちは書く:
-- | Menu type Menu = [MenuItem] -- | Menu utem data MenuItem = MenuAction String (MenuContext -> Char -> Keymap) | SubMenu String Menu -- | Menu action context data MenuContext = MenuContext { parentBuffer :: BufferRef }
SubMenuバリアントにはタイトルとサブメニューが含まれ、MenuActionバリアントにはタイトルと必要なバインダーを作成する関数が含まれます。
MenuContextはアクションに転送される特定のコンテキストです(これまでのところ、メニューが呼び出されたソースバッファーのみがあり、保存ボタンを実装するために必要でした)。Charは、メニューを呼び出す必要のあるクリックによるボタンです。
型は再帰的であるため、単純に畳み込みを定義して、後でそれを使用してメニューを開始できます。
-- | Fold menu item foldItem :: (String -> (MenuContext -> Char -> Keymap) -> a) -> (String -> [a] -> a) -> MenuItem -> a foldItem mA sM (MenuAction title act) = mA title act foldItem mA sM (SubMenu title sm) = sM title (map (foldItem mA sM) sm) -- | Fold menu foldMenu :: (String -> (MenuContext -> Char -> Keymap) -> a) -> (String -> [a] -> a) -> Menu -> [a] foldMenu mA sM = map (foldItem mA sM)
また、メニュー項目をより便利に作成する関数も必要です。 SubMenuは簡単に作成でき、SubMenuは「ファイル」です...しかし、MenuActionは使いにくいです。 したがって、アクションを実行するいくつかの関数を定義します(右側の場合と同じですか?>>!バインダー内)。 それらのうちの2つのコードを提供します。
-- | Action on item action_ :: (YiAction ax, Show x) => String -> a -> MenuItem action_ title act = action title (const act) -- | Action on item with context action :: (YiAction ax, Show x) => String -> (MenuContext -> a) -> MenuItem action title act = MenuAction title act' where act' ctx c = char c ?>>! (do withEditor closeBufferAndWindowE runAction $ makeAction (act ctx))
ここで、適切なボタン(char c)をクリックするとメニューを閉じ、必要なアクションを呼び出すMenuItemを作成します。
最後に、メニュー表示機能を作成します。
-- | Start menu action startMenu :: Menu -> EditorM () startMenu m = do -- , ctx <- fmap MenuContext (gets currentBuffer) startMenu' ctx m where -- , (, ) startMenu' ctx = showMenu . foldMenu onItem onSub where showMenu :: [(String, Maybe Keymap)] -> EditorM () -- — , showMenu is = void $ spawnMinibufferE menuItems (const (subMap is)) where menuItems = (intercalate " " (map fst is)) -- — -- + , onItem title act = (title, fmap (act ctx) (menuEvent title)) where -- — -- + , onSub title is = (title, fmap subMenu (menuEvent title)) where -- 'c' subMenu c = char c ?>>! closeBufferAndWindowE >> showMenu is -- Esc, subMap is = choice $ closeMenu : mapMaybe snd is where closeMenu = spec KEsc ?>>! closeBufferAndWindowE
完全なコードはこちらにあります 。
メニューを作成する
これで、何らかのメニューを作成して、ボタンにリンクする価値があり、確認を開始できます。
最初に、私はYiのさまざまなモジュールを見ながら出会ったものを詰め込んだ、大きくて緑豊かなメニューを書きました。 たとえば、[表示-Windows]サブメニューに頻繁に移動することに気付いたとき、このメニューを別のホットキーに配置することにしました。
これで、長いVWSの組み合わせだけでなく、Ctrl-W-Sだけでウィンドウを分割できます。
Windowsのメインメニューとサブメニューのコードは次のとおりです。
-- | Main menu mainMenu :: Menu mainMenu = [ menu "File" [ action_ "Quit" askQuitEditor, action "Save" (fwriteBufferE . parentBuffer)], menu "Edit" [ action_ "Auto complete" wordComplete, action_ "Completion" completeWordB], menu "Tools" [ menu "Ghci" ghciMenu], menu "View" [ menu "Windows" windowsMenu, menu "Tabs" tabsMenu, menu "Buffers" buffersMenu, menu "Layout" [ action_ "Next" layoutManagersNextE, action_ "Previous" layoutManagersPreviousE]]] -- | Windows menu windowsMenu :: Menu windowsMenu = [ action_ "Next" nextWinE, action_ "Previous" prevWinE, action_ "Split" splitE, action_ "sWap" swapWinWithFirstE, action_ "Close" tryCloseE, action_ "cLose-all-but-this" closeOtherE]
ここでメニュー全体を見ることができます 。
結果
さまざまな組み合わせのメインメニューとサブメニューを規定しています。
私たちはそれを使用しています!
まとめ
実装後、ある種の組み込みの単純なオートコンプリート、次にGHCiインタープリターをねじ込みました。 次のステップは、hlintツール(コードを分析し、標準関数の使用によってコードを置き換えることができる場所、余分なものが記述されている場所など)です。
すべてのコードはGitHubで入手できます 。
更新する
3つの関数
actionB
、
actionE
および
actionY
。 ただし、
runAction . makeAction
に置き換えることができます
runAction . makeAction
runAction . makeAction
単一のアクションのために修正