blob: b761eb57261e39181242466b1f394178687c0250 [file] [log] [blame]
Mike Frysingerf6013762019-06-13 02:30:51 -04001# -*- coding:utf-8 -*-
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07002#
3# Copyright (C) 2008 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Sarah Owenscecd1d82012-11-01 22:59:27 -070017from __future__ import print_function
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070018import os
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070019import re
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070020import sys
21import subprocess
22import tempfile
23
24from error import EditorError
Renaud Paquay010fed72016-11-11 14:25:29 -080025import platform_utils
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070026
27class Editor(object):
28 """Manages the user's preferred text editor."""
29
30 _editor = None
31 globalConfig = None
32
33 @classmethod
34 def _GetEditor(cls):
35 if cls._editor is None:
36 cls._editor = cls._SelectEditor()
37 return cls._editor
38
39 @classmethod
40 def _SelectEditor(cls):
41 e = os.getenv('GIT_EDITOR')
42 if e:
43 return e
44
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070045 if cls.globalConfig:
46 e = cls.globalConfig.GetString('core.editor')
47 if e:
48 return e
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070049
50 e = os.getenv('VISUAL')
51 if e:
52 return e
53
54 e = os.getenv('EDITOR')
55 if e:
56 return e
57
58 if os.getenv('TERM') == 'dumb':
Sarah Owenscecd1d82012-11-01 22:59:27 -070059 print(
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070060"""No editor specified in GIT_EDITOR, core.editor, VISUAL or EDITOR.
61Tried to fall back to vi but terminal is dumb. Please configure at
Sarah Owenscecd1d82012-11-01 22:59:27 -070062least one of these before using this command.""", file=sys.stderr)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070063 sys.exit(1)
64
65 return 'vi'
66
67 @classmethod
68 def EditString(cls, data):
69 """Opens an editor to edit the given content.
70
71 Args:
72 data : the text to edit
Sarah Owenscecd1d82012-11-01 22:59:27 -070073
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070074 Returns:
75 new value of edited text; None if editing did not succeed
76 """
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070077 editor = cls._GetEditor()
78 if editor == ':':
79 return data
80
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070081 fd, path = tempfile.mkstemp()
82 try:
83 os.write(fd, data)
84 os.close(fd)
85 fd = None
86
Renaud Paquaycd892a32016-11-03 15:59:05 -070087 if platform_utils.isWindows():
88 # Split on spaces, respecting quoted strings
89 import shlex
90 args = shlex.split(editor)
91 shell = False
92 elif re.compile("^.*[$ \t'].*$").match(editor):
Patrick Dubroyb715b142010-07-29 17:10:47 -070093 args = [editor + ' "$@"', 'sh']
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -070094 shell = True
95 else:
96 args = [editor]
97 shell = False
98 args.append(path)
99
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700100 try:
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -0700101 rc = subprocess.Popen(args, shell=shell).wait()
Sarah Owensa5be53f2012-09-09 15:37:57 -0700102 except OSError as e:
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700103 raise EditorError('editor failed, %s: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -0700104 % (str(e), editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700105 if rc != 0:
106 raise EditorError('editor failed with exit status %d: %s %s'
Shawn O. Pearce1dcb58a2009-07-02 12:45:47 -0700107 % (rc, editor, path))
Shawn O. Pearce54fccd72009-06-24 07:09:51 -0700108
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700109 fd2 = open(path)
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700110 try:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700111 return fd2.read()
Shawn O. Pearce76ca9f82009-04-18 14:48:03 -0700112 finally:
Shawn O. Pearcea8421a12009-04-18 16:57:46 -0700113 fd2.close()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700114 finally:
115 if fd:
116 os.close(fd)
Renaud Paquay010fed72016-11-11 14:25:29 -0800117 platform_utils.remove(path)