blob: 62afbb9176765432df8fbebf24347475816d25c8 [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
16import os
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070017import re
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070018import sys
19import subprocess
20import tempfile
21
22from error import EditorError
23
24class Editor(object):
25 """Manages the user's preferred text editor."""
26
27 _editor = None
28 globalConfig = None
29
30 @classmethod
31 def _GetEditor(cls):
32 if cls._editor is None:
33 cls._editor = cls._SelectEditor()
34 return cls._editor
35
36 @classmethod
37 def _SelectEditor(cls):
38 e = os.getenv('GIT_EDITOR')
39 if e:
40 return e
41
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070042 if cls.globalConfig:
43 e = cls.globalConfig.GetString('core.editor')
44 if e:
45 return e
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070046
47 e = os.getenv('VISUAL')
48 if e:
49 return e
50
51 e = os.getenv('EDITOR')
52 if e:
53 return e
54
55 if os.getenv('TERM') == 'dumb':
56 print >>sys.stderr,\
57"""No editor specified in GIT_EDITOR, core.editor, VISUAL or EDITOR.
58Tried to fall back to vi but terminal is dumb. Please configure at
59least one of these before using this command."""
60 sys.exit(1)
61
62 return 'vi'
63
64 @classmethod
65 def EditString(cls, data):
66 """Opens an editor to edit the given content.
67
68 Args:
69 data : the text to edit
70
71 Returns:
72 new value of edited text; None if editing did not succeed
73 """
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070074 editor = cls._GetEditor()
75 if editor == ':':
76 return data
77
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070078 fd, path = tempfile.mkstemp()
79 try:
80 os.write(fd, data)
81 os.close(fd)
82 fd = None
83
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070084 if re.compile("^.*[$ \t'].*$").match(editor):
Patrick Dubroyb715b142010-07-29 17:10:47 -070085 args = [editor + ' "$@"', 'sh']
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070086 shell = True
87 else:
88 args = [editor]
89 shell = False
90 args.append(path)
91
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070092 try:
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070093 rc = subprocess.Popen(args, shell=shell).wait()
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070094 except OSError, e:
95 raise EditorError('editor failed, %s: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070096 % (str(e), editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -070097 if rc != 0:
98 raise EditorError('editor failed with exit status %d: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070099 % (rc, editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700100
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700101 fd2 = open(path)
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700102 try:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700103 return fd2.read()
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700104 finally:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700105 fd2.close()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700106 finally:
107 if fd:
108 os.close(fd)
109 os.remove(path)