Coverage for sources/mimeogram/edit.py: 42%
32 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-16 03:28 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-16 03:28 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21''' System editor interaction. '''
24from __future__ import annotations
26from . import __
29_scribe = __.produce_scribe( __name__ )
32def discover_editor( ) -> __.cabc.Callable[ [ str ], str ]:
33 ''' Discovers editor and returns executor function. '''
34 from shutil import which
35 from subprocess import run # nosec B404
36 editor = (
37 __.os.environ.get( 'VISUAL' )
38 or __.os.environ.get( 'EDITOR' )
39 # TODO: Better default for Windows.
40 or 'nano' )
41 # TODO: Platform-specific list.
42 for editor_ in ( editor, 'nano' ):
43 if which( editor_ ):
44 editor = editor_
45 break
46 else: editor = ''
48 if editor:
50 # TODO? async
51 def editor_executor( filename: str ) -> str:
52 ''' Executes editor with file. '''
53 run( ( editor, filename ), check = True ) # nosec B603
54 with open( filename, 'r', encoding = 'utf-8' ) as stream:
55 return stream.read( )
57 return editor_executor
59 from .exceptions import ProgramAbsenceError
60 raise ProgramAbsenceError( 'editor' )
63def edit_content(
64 content: str = '', *,
65 suffix: str = '.md',
66 editor_discoverer: __.cabc.Callable[
67 [ ], __.cabc.Callable[ [ str ], str ] ] = discover_editor,
68) -> str:
69 ''' Edits content via discovered editor. '''
70 from .exceptions import EditorFailure, ProgramAbsenceError
71 try: editor = editor_discoverer( )
72 except ProgramAbsenceError:
73 _scribe.exception( "Could not find editor program." )
74 return content
75 import tempfile
76 with tempfile.NamedTemporaryFile( mode = 'r+', suffix = suffix ) as tmp:
77 tmp.write( content )
78 tmp.flush( )
79 try: return editor( tmp.name )
80 except Exception as exc: raise EditorFailure( cause = exc ) from exc