phoityne 0.0.2.0 → 0.0.3.0
raw patch · 8 files changed
+146/−46 lines, 8 files
Files
- Changelog.md +11/−2
- app/Main.hs +0/−1
- app/Phoityne/IO/CUI/GHCiControl.hs +30/−8
- app/Phoityne/IO/GUI/Control.hs +40/−13
- app/Phoityne/IO/GUI/GTK/Interface.hs +18/−6
- app/Phoityne/IO/GUI/GTK/TextEditor.hs +39/−10
- conf/Phoityne.glade +7/−5
- phoityne.cabal +1/−1
Changelog.md view
@@ -1,7 +1,16 @@+20160201 phoityne-0.0.3.0++ * [Fix] phoityne終了時にghciを停止するように修正した。+ * [Fix] break検知(Stopped at)のパーサを修正した。+ * [Fix] ghci起動時にビルドを実行しないように修正した。+ * [Fix] 新規追加ファイルをスタートアップに選択できるように修正した。+ * [Add] タイトルにプロジェクトフォルダパスを表示するように変更した。+ * [Add] ghci起動/終了のショートカットキーを追加した。(F8, Shift+F8)+ 20160101 phoityne-0.0.2.0 - * [Add] 参照先情報を取得する機能を追加した(:info)- * [Add] ファイル保存時にghci上でファイルをロードする機能を追加した+ * [Add] 参照先情報を取得する機能を追加した(:info)。+ * [Add] ファイル保存時にghci上でファイルをロードする機能を追加した。 * [Add] print source file path on statusbar. 20151223 phoityne-0.0.1.1
app/Main.hs view
@@ -9,7 +9,6 @@ -- システム import System.Exit - -- | -- メイン --
app/Phoityne/IO/CUI/GHCiControl.hs view
@@ -18,6 +18,7 @@ import System.IO import System.Exit import System.Log.Logger +import qualified Control.Exception as E import qualified Data.List as L -- | @@ -43,12 +44,13 @@ -- -- run :: String -> [String] -> Maybe FilePath -> IO ExternalCommandData -run cmd opts curDir = do +run cmd opts curDir = flip E.catches handlers $ do (stdInReadHandle, stdInWriteHandle) <- createPipe (outReadHandle, outWriteHandle) <- createPipe - hSetBuffering stdInReadHandle NoBuffering+ --hSetBuffering stdInReadHandle $ BlockBuffering Nothing -- NoBuffering+ hSetBuffering stdInReadHandle NoBuffering hSetBuffering stdInWriteHandle NoBuffering hSetBuffering outReadHandle NoBuffering@@ -67,13 +69,23 @@ return $ ExternalCommandData (Just stdInWriteHandle) (Just outReadHandle) (Just outReadHandle) (Just ghciProc) + where+ handlers = [ E.Handler someExcept ]+ someExcept (e :: E.SomeException) = do+ criticalM _LOG_NAME ("waitExit:" ++ show e)+ return $ ExternalCommandData Nothing Nothing Nothing Nothing -- | -- -- waitExit :: ExternalCommandData -> IO ExitCode -waitExit (ExternalCommandData _ _ _ (Just ghciProc)) = do +waitExit (ExternalCommandData _ _ _ (Just ghciProc)) = flip E.catches handlers $ do waitForProcess ghciProc + where+ handlers = [ E.Handler someExcept ]+ someExcept (e :: E.SomeException) = do+ criticalM _LOG_NAME ("waitExit:" ++ show e)+ return $ ExitFailure 2 waitExit _ = do criticalM _LOG_NAME "waitExit" return $ ExitFailure 2 @@ -83,9 +95,13 @@ -- -- writeLine :: ExternalCommandData -> String -> IO () -writeLine (ExternalCommandData (Just ghciIn) _ _ _) cmd = hIsOpen ghciIn >>= \case+writeLine (ExternalCommandData (Just ghciIn) _ _ _) cmd = flip E.catches handlers $ hIsOpen ghciIn >>= \case False -> criticalM _LOG_NAME "[writeLine] handle not open."- True -> debugM _LOG_NAME ("[writeLine]" ++ cmd) >> hPutStrLn ghciIn cmd + True -> debugM _LOG_NAME ("[writeLine]" ++ cmd) >> hPutStrLn ghciIn cmd+ where+ handlers = [ E.Handler someExcept ]+ someExcept (e :: E.SomeException) = criticalM _LOG_NAME ("writeLine:" ++ show e)+ writeLine _ _ = criticalM _LOG_NAME "[writeLine] handle is nothing." @@ -93,7 +109,7 @@ -- -- readWhile :: ExternalCommandData -> (String -> Bool) -> IO String -readWhile (ExternalCommandData _ (Just ghciOut) _ _) proc = go [] +readWhile (ExternalCommandData _ (Just ghciOut) _ _) proc = flip E.catches handlers $ go [] where go acc = hIsEOF ghciOut >>= \case True -> return acc@@ -101,8 +117,11 @@ c <- hGetChar ghciOut let acc' = acc ++ [c] if proc acc' then go acc' - else return acc' + else return acc' + handlers = [ E.Handler someExcept ]+ someExcept (e :: E.SomeException) = criticalM _LOG_NAME ("readWhile:" ++ show e) >> return "" + readWhile _ _ = criticalM _LOG_NAME "readWhile" >> return "" @@ -110,7 +129,7 @@ -- -- readLineWhileIO :: ExternalCommandData -> ([String] -> IO Bool) -> IO [String] -readLineWhileIO (ExternalCommandData _ (Just ghciOut) _ _) proc = go [] +readLineWhileIO (ExternalCommandData _ (Just ghciOut) _ _) proc = flip E.catches handlers $ go [] where go acc = hIsEOF ghciOut >>= \case True -> return acc@@ -120,6 +139,9 @@ proc acc' >>= \case True -> go acc' False -> return acc' ++ handlers = [ E.Handler someExcept ]+ someExcept (e :: E.SomeException) = criticalM _LOG_NAME ("readLineWhileIO:" ++ show e) >> return [] readLineWhileIO _ _ = criticalM _LOG_NAME "readLineWhileIO" >> return []
app/Phoityne/IO/GUI/Control.hs view
@@ -37,11 +37,10 @@ import qualified Data.Text.Encoding as TE import qualified Text.StringTemplate as TPL - -- | -- -- -type NoteMap = Map.Map IF.NodeData IF.TextEditorData +type NoteMap = Map.Map IF.NodeData IF.TextEditorData -- | -- @@ -175,15 +174,16 @@ breakStore <- IF.createBreakPointListStore bindingStore <- IF.createBindingListStore traceStore <- IF.createTraceDataListStore - searchResultStore <- IF.createSearchResultListStore - treeStore <- loadFolderForest _PROJECT_ROOT_MODULE_NAME paths >>= IF.createTreeStore+ searchResultStore <- IF.createSearchResultListStore+ treeNodes@(T.Node rootNode _) <- loadFolderForest _PROJECT_ROOT_MODULE_NAME paths + treeStore <- IF.createTreeStore treeNodes -- GUI共有データの作成 mvarGUI <- newMVar $ defaultMVarGUIData builder breakStore treeStore bindingStore traceStore searchResultStore autoRun -- イベントハンドラの登録- IF.setupMainWindow builder- (mainWindowCloseEventHanlder)+ IF.setupMainWindow builder ("Phoityne [" ++ (IF.getPathFromNodeData rootNode) ++ "]")+ (mainWindowCloseEventHanlder mvarGUI cmdData) (mainWindowKeyPressEventHandler mvarGUI cmdData) IF.setupToolButton builder @@ -245,9 +245,17 @@ -- | -- -- -mainWindowCloseEventHanlder :: IF.MainWindowCloseEventHandler -mainWindowCloseEventHanlder = infoM _LOG_NAME "See you again." +mainWindowCloseEventHanlder :: MVar MVarGUIData -> DebugCommandData -> IF.MainWindowCloseEventHandler +mainWindowCloseEventHanlder mvarGUI cmdDat = do+ guiData <- readMVar mvarGUI + let builder = widgetStoreMVarGUIData guiData + isGhciStarted <- IF.isGHCiStarted builder++ when isGhciStarted $ toolBTstopGHCiHandler mvarGUI cmdDat++ infoM _LOG_NAME "See you again." + -- | -- -- @@ -315,7 +323,26 @@ toolBTbuildHandler mvarGUI cmdDat return True + +mainWindowKeyPressEventHandler mvarGUI cmdDat "F8" isShift _ = do + guiData <- readMVar mvarGUI + let builder = widgetStoreMVarGUIData guiData ++ IF.isBuildStart builder >>= \case+ True -> IF.putStrStatusBar builder "ghci unavailable. Currently build running." >> return True+ False -> do+ isGHCiStart <- IF.isGHCiStarted builder + withStart builder isGHCiStart isShift+ return True + + where + withStart _ True True = toolBTstopGHCiHandler mvarGUI cmdDat + withStart builder True False = IF.putStrStatusBar builder "ghci has already been started." + withStart builder False True = IF.putStrStatusBar builder "ghci has already been stopped." + withStart _ False False = toolBTstartGHCiHandler mvarGUI cmdDat++ mainWindowKeyPressEventHandler mvarGUI cmdDat "F10" _ _ = do guiData <- takeMVar mvarGUI let builder = widgetStoreMVarGUIData guiData @@ -698,7 +725,7 @@ putMVar mvarGUI guiData{buildMsgMVarGUIData = []} IF.changeTBsOnBuildStart builder - --IF.clearConsole builder + IF.clearConsole builder appendBuildMsg mvarGUI "start stack build.\n" buildStart @@ -730,7 +757,7 @@ putMVar mvarGUI guiData{ buildMsgMVarGUIData = [] } - mapM_ (IF.putStrConsole builder) curMsg+ mapM_ (IF.putStrLnConsole builder) curMsg return doNotDelHandle @@ -1040,7 +1067,7 @@ where getFileTreeNodeData :: Maybe IF.NodeData -> Maybe String -> Maybe IF.NodeData getFileTreeNodeData (Just (IF.FolderNodeData modName _ path)) (Just name) = - Just $ IF.FileNodeData (getModName modName (snd (normName name))) (fst (normName name)) (path </> (fst (normName name))) + Just $ IF.FileNodeData (getModName modName (snd (normName name))) ("<span foreground='black'>"++(fst (normName name))++"</span>") (path </> (fst (normName name))) getFileTreeNodeData _ _ = Nothing normName name @@ -1212,7 +1239,7 @@ let builder = widgetStoreMVarGUIData guiData store = folderTreeMVarGUIData guiData curStartupDat = startupNodeDataMVarGUIData guiData - + IF.getSelectedFolderTreeNodeData builder store >>= \case Nothing -> errorM _LOG_NAME "[folderTreeStartupAction]invalid node data." Just nodeDat -> do@@ -1681,7 +1708,7 @@ getStoppedTextRangeData = parse parser "getStoppedTextRangeData" where parser = do- _ <- manyTill anyChar (string "Stopped at ")+ _ <- manyTill anyChar (try (string "Stopped at ")) parseHighlightTextRange -- |
app/Phoityne/IO/GUI/GTK/Interface.hs view
@@ -169,17 +169,24 @@ -- type MainWindowCloseEventHandler = IO () type MainWindowKeyPressEventHandler = String -> Bool -> Bool -> IO Bool ++-- | +-- +-- setupMainWindow :: Builder+ -> String -> MainWindowCloseEventHandler -> MainWindowKeyPressEventHandler -> IO () -setupMainWindow builder closeEvt keyEvt = do +setupMainWindow builder title closeEvt keyEvt = do settings <- fromJust <$> settingsGetDefault settingsSetStringProperty settings "gtk-font-name" _FONT_DESC "" settingsSetStringProperty settings "gtk-menu-bar-accel" "" "" window <- builderGetObject builder castToWindow _WINDOW_NAME ++ set window [windowTitle := title] on window deleteEvent $ mainWindowCloseEventHandler window closeEvt on window keyPressEvent $ mainWindowKeyPressEventHandler window keyEvt @@ -191,8 +198,6 @@ panedSetPosition codePaned 350 note <- builderGetObject builder castToNotebook _NAME_CODE_NOTE- -- statusBar <- builderGetObject builder castToStatusbar _NAME_STATUS_BAR- -- contId <- statusbarGetContextId statusBar "source_file_path" on note switchPage $ switchPageEventHandler note builder return ()@@ -241,18 +246,25 @@ isBuildStart :: Builder -> IO Bool isBuildStart builder = do bt <- builderGetObject builder castToToolButton _NAME_TOOL_BT_BUILD - widgetGetSensitive bt >>= return . not+ isBuild <- widgetGetSensitive bt + bt <- builderGetObject builder castToToolButton _NAME_TOOL_BT_STOP_GHCI + isGHCiStop <- widgetGetSensitive bt + bt <- builderGetObject builder castToToolButton _NAME_TOOL_BT_START_GHCI+ isGHCiStart <- widgetGetSensitive bt ++ return $ (False == isBuild) && (True == isGHCiStop) && (False == isGHCiStart)+ -- | -- -- switchPageEventHandler :: Notebook -> Builder -> Int -> IO () switchPageEventHandler note builder pageId = do path <- notebookGetNthPage note pageId >>= \case- Nothing -> return "[ERROR] texit editor not found."+ Nothing -> return "[ERROR] text editor not found." Just child -> notebookGetMenuLabelText note child >>= \case- Nothing -> return "[ERROR] texit editor not found."+ Nothing -> return "[ERROR] text editor not found." Just a -> return a putStrStatusBar builder path
app/Phoityne/IO/GUI/GTK/TextEditor.hs view
@@ -17,7 +17,6 @@ , setupCodeNote , activateCodeNote , highLightBreakPoint ---, offLightBreakPoint , addBreakPointTagAtLine , isCurrentTextEditor , getCodeViewContent @@ -225,7 +224,7 @@ textViewSetBorderWindowSize lineTextView TextWindowBottom 5 --textViewSetBorderWindowSize lineTextView TextWindowLeft 10 --textViewSetBorderWindowSize lineTextView TextWindowRight 5 - textViewSetEditable lineTextView True + textViewSetEditable lineTextView False textViewSetCursorVisible lineTextView False textViewSetJustification lineTextView JustifyRight @@ -353,8 +352,11 @@ let codeTextView = codeTextEditorData wid codeBuf <- textViewGetBuffer codeTextView iter <- textBufferGetIterAtLine codeBuf lineNo- _ <- textViewScrollToIter codeTextView iter 0.0 (Just (0.0, 0.5)) + isLineVisible wid lineNo >>= \case+ True -> return ()+ False -> textViewScrollToIter codeTextView iter 0.0 (Just (0.0, 0.5)) >> return ()+ widgetGrabFocus codeTextView -- |@@ -731,13 +733,15 @@ -- -- setCursorOnTextEditor :: TextEditorData -> Int -> Int -> IO ()-setCursorOnTextEditor (TextEditorData _ codeView _ _) lineNo colNo = do- buf <- textViewGetBuffer codeView- iter <- textBufferGetIterAtLineOffset buf lineNo colNo- textBufferPlaceCursor buf iter- mark <- textBufferGetInsert buf- textViewScrollToMark codeView mark 0.0 (Just (0.0, 0.5))-+setCursorOnTextEditor ed@(TextEditorData _ codeView _ _) lineNo colNo = isLineVisible ed lineNo >>= \case+ True -> return ()+ False -> do+ buf <- textViewGetBuffer codeView+ iter <- textBufferGetIterAtLineOffset buf lineNo colNo+ textBufferPlaceCursor buf iter+ mark <- textBufferGetInsert buf+ textViewScrollToMark codeView mark 0.0 (Just (0.0, 0.5))+ -- | -- --@@ -768,4 +772,29 @@ (startIter, endIter) <- textBufferGetSelectionBounds buf textBufferGetText buf startIter endIter False False -> return ""++-- | +-- +-- +getCurrentVisibleLines :: TextEditorData -> IO (Int, Int)+getCurrentVisibleLines (TextEditorData _ codeView _ _) = do+ (Rectangle _ startY _ h) <- textViewGetVisibleRect codeView++ (iter, _) <- textViewGetLineAtY codeView startY+ startNo <- textIterGetLine iter++ (iter, _) <- textViewGetLineAtY codeView (startY + h)+ endNo <- textIterGetLine iter++ return (startNo, endNo)+++-- | +-- +-- +isLineVisible :: TextEditorData -> Int -> IO Bool+isLineVisible editor lineNo = do+ (startNo, endNo) <- getCurrentVisibleLines editor+ return $ (startNo < lineNo) && (lineNo < endNo)+
conf/Phoityne.glade view
@@ -62,6 +62,7 @@ <object class="GtkDialog" id="ReplaceDialog"> <property name="can_focus">False</property> <property name="border_width">5</property>+ <property name="title" translatable="yes">Replace</property> <property name="window_position">center-always</property> <property name="icon">h.ico</property> <property name="type_hint">dialog</property>@@ -199,6 +200,7 @@ <object class="GtkDialog" id="SearchDialog"> <property name="can_focus">False</property> <property name="border_width">5</property>+ <property name="title" translatable="yes">Search</property> <property name="window_position">center-always</property> <property name="icon">h.ico</property> <property name="type_hint">dialog</property>@@ -449,7 +451,7 @@ <property name="visible">True</property> <property name="sensitive">False</property> <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Save All(Ctrl+s)</property>+ <property name="tooltip_text" translatable="yes">Save All(Ctrl+S)</property> <property name="is_important">True</property> <property name="label" translatable="yes">SaveLabel</property> <property name="use_underline">True</property>@@ -490,7 +492,7 @@ <object class="GtkToolButton" id="StartGHCiBT"> <property name="visible">True</property> <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Start GHCi</property>+ <property name="tooltip_text" translatable="yes">Start GHCi(F8)</property> <property name="is_important">True</property> <property name="label" translatable="yes">StartGHCiLabel</property> <property name="use_underline">True</property>@@ -505,7 +507,7 @@ <object class="GtkToolButton" id="StopGHCiBT"> <property name="visible">True</property> <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Stop GHCi</property>+ <property name="tooltip_text" translatable="yes">Stop GHCi(Shift+F8)</property> <property name="is_important">True</property> <property name="label" translatable="yes">StopGHCiLabel</property> <property name="use_underline">True</property>@@ -659,7 +661,7 @@ <property name="is_important">True</property> <property name="label" translatable="yes">BlockCommentLabel</property> <property name="use_underline">True</property>- <property name="stock_id">gtk-select-all</property>+ <property name="stock_id">gtk-justify-right</property> </object> <packing> <property name="expand">False</property>@@ -674,7 +676,7 @@ <property name="is_important">True</property> <property name="label" translatable="yes">BlockUnCommentLabel</property> <property name="use_underline">True</property>- <property name="stock_id">gtk-justify-center</property>+ <property name="stock_id">gtk-justify-left</property> </object> <packing> <property name="expand">False</property>
phoityne.cabal view
@@ -1,5 +1,5 @@ name: phoityne-version: 0.0.2.0+version: 0.0.3.0 synopsis: ghci debug viewer with simple editor. description: Phoityne is a ghci debug viewer with simple editor. license: BSD3