blob: 96d7ce4c9ea6a89175600fa641d167af8b219792 [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001#
2# Copyright (C) 2008 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Sarah Owenscecd1d82012-11-01 22:59:27 -070016from __future__ import print_function
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070017import os
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070018import re
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070019import sys
20import subprocess
21import tempfile
22
23from error import EditorError
Renaud Paquay010fed72016-11-11 14:25:29 -080024import platform_utils
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070025
26class Editor(object):
27 """Manages the user's preferred text editor."""
28
29 _editor = None
30 globalConfig = None
31
32 @classmethod
33 def _GetEditor(cls):
34 if cls._editor is None:
35 cls._editor = cls._SelectEditor()
36 return cls._editor
37
38 @classmethod
39 def _SelectEditor(cls):
40 e = os.getenv('GIT_EDITOR')
41 if e:
42 return e
43
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070044 if cls.globalConfig:
45 e = cls.globalConfig.GetString('core.editor')
46 if e:
47 return e
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070048
49 e = os.getenv('VISUAL')
50 if e:
51 return e
52
53 e = os.getenv('EDITOR')
54 if e:
55 return e
56
57 if os.getenv('TERM') == 'dumb':
Sarah Owenscecd1d82012-11-01 22:59:27 -070058 print(
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070059"""No editor specified in GIT_EDITOR, core.editor, VISUAL or EDITOR.
60Tried to fall back to vi but terminal is dumb. Please configure at
Sarah Owenscecd1d82012-11-01 22:59:27 -070061least one of these before using this command.""", file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070062 sys.exit(1)
63
64 return 'vi'
65
66 @classmethod
67 def EditString(cls, data):
68 """Opens an editor to edit the given content.
69
70 Args:
71 data : the text to edit
Sarah Owenscecd1d82012-11-01 22:59:27 -070072
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070073 Returns:
74 new value of edited text; None if editing did not succeed
75 """
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070076 editor = cls._GetEditor()
77 if editor == ':':
78 return data
79
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070080 fd, path = tempfile.mkstemp()
81 try:
82 os.write(fd, data)
83 os.close(fd)
84 fd = None
85
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070086 if re.compile("^.*[$ \t'].*$").match(editor):
Patrick Dubroyb715b142010-07-29 17:10:47 -070087 args = [editor + ' "$@"', 'sh']
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070088 shell = True
89 else:
90 args = [editor]
91 shell = False
92 args.append(path)
93
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070094 try:
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070095 rc = subprocess.Popen(args, shell=shell).wait()
Sarah Owensa5be53f2012-09-09 15:37:57 -070096 except OSError as e:
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070097 raise EditorError('editor failed, %s: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070098 % (str(e), editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070099 if rc != 0:
100 raise EditorError('editor failed with exit status %d: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -0700101 % (rc, editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700102
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700103 fd2 = open(path)
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700104 try:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700105 return fd2.read()
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700106 finally:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700107 fd2.close()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700108 finally:
109 if fd:
110 os.close(fd)
Renaud Paquay010fed72016-11-11 14:25:29 -0800111 platform_utils.remove(path)