aboutsummaryrefslogtreecommitdiff
path: root/pkg/prompt
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/prompt')
-rw-r--r--pkg/prompt/buffer.go66
-rw-r--r--pkg/prompt/login.go65
-rw-r--r--pkg/prompt/main.go46
3 files changed, 177 insertions, 0 deletions
diff --git a/pkg/prompt/buffer.go b/pkg/prompt/buffer.go
new file mode 100644
index 0000000..03aca43
--- /dev/null
+++ b/pkg/prompt/buffer.go
@@ -0,0 +1,66 @@
+/*******************************************************************************
+*
+* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
+*
+* This program is free software: you can redistribute it and/or modify it under
+* the terms of the GNU General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with
+* this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*******************************************************************************/
+
+package prompt
+
+import "bytes"
+
+//LineBuffer wraps bytes.Buffer that measures the length of the displayed text
+//(minus ANSI escape sequences).
+type LineBuffer struct {
+ buffer bytes.Buffer
+ length int
+}
+
+//Bytes returns the complete string (including non-printable characters) in the
+//buffer.
+func (b *LineBuffer) Bytes() []byte {
+ return b.buffer.Bytes()
+}
+
+//Length returns the number of printable characters in the buffer.
+func (b *LineBuffer) Length() int {
+ return b.length
+}
+
+//Write implements the io.Writer interface. Use this only for printable
+//characters.
+func (b *LineBuffer) Write(buf []byte) (n int, err error) {
+ n, err = b.buffer.Write(buf)
+ b.length += n
+ return
+}
+
+//WriteNonprintable works like Write, but bytes written do not count towards
+//Length().
+func (b *LineBuffer) WriteNonprintable(buf []byte) (int, error) {
+ return b.buffer.Write(buf)
+}
+
+//WriteWithColor writes a colored printable string. The color is given as the
+//semicolon-separated list of arguments to the ANSI escape sequence SGR, e.g.
+//"1;41" for bold with red background.
+func (b *LineBuffer) WriteWithColor(text, color string) {
+ if color == "0" {
+ b.Write([]byte(text))
+ } else {
+ b.WriteNonprintable([]byte("\x1B[" + color + "m"))
+ b.Write([]byte(text))
+ b.WriteNonprintable([]byte("\x1B[0m"))
+ }
+}
diff --git a/pkg/prompt/login.go b/pkg/prompt/login.go
new file mode 100644
index 0000000..b5fcebd
--- /dev/null
+++ b/pkg/prompt/login.go
@@ -0,0 +1,65 @@
+/*******************************************************************************
+*
+* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
+*
+* This program is free software: you can redistribute it and/or modify it under
+* the terms of the GNU General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with
+* this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*******************************************************************************/
+
+package prompt
+
+import "os"
+
+//#include <sys/types.h>
+//#include <pwd.h>
+import "C"
+
+func addLogin(buf *LineBuffer) {
+ //show user name
+ userName := getUserName()
+ commonUser := getenvOrDefault("PRETTYPROMPT_COMMONUSER", "stefan")
+ if commonUser != userName {
+ color := "0"
+ if userName == "root" {
+ color = "1;41"
+ }
+ buf.WriteWithColor(userName, color)
+ buf.Write([]byte("@"))
+ }
+
+ //show hostname
+ hostname, err := os.Hostname()
+ if err != nil {
+ handleError(err)
+ hostname = "<unknown>"
+ }
+ buf.WriteWithColor(
+ getenvOrDefault("PRETTYPROMPT_HOSTCOLOR", "0;33"),
+ hostname,
+ )
+ buf.Write([]byte(" "))
+}
+
+func getUserName() string {
+ //try to find username via getpwuid(getuid())
+ pw, err := C.getpwuid(C.__uid_t(os.Getuid()))
+ if err == nil {
+ return C.GoString(pw.pw_name)
+ }
+ //fallback to $USER, if set
+ if name := os.Getenv("USER"); name != "" {
+ return name
+ }
+ handleError(err)
+ return "<unknown>"
+}
diff --git a/pkg/prompt/main.go b/pkg/prompt/main.go
new file mode 100644
index 0000000..6b4764a
--- /dev/null
+++ b/pkg/prompt/main.go
@@ -0,0 +1,46 @@
+/*******************************************************************************
+*
+* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
+*
+* This program is free software: you can redistribute it and/or modify it under
+* the terms of the GNU General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with
+* this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*******************************************************************************/
+
+package prompt
+
+import "os"
+
+//Exec executes the prettyprompt applet and returns an exit code (0 for
+//success, >0 for error).
+func Exec() int {
+ var buf LineBuffer
+ addLogin(&buf)
+
+ os.Stdout.Write(buf.Bytes())
+ os.Stdout.Write([]byte("\n"))
+ return 0
+}
+
+func getenvOrDefault(key, defaultValue string) (value string) {
+ value = os.Getenv(key)
+ if value == "" {
+ value = defaultValue
+ }
+ return
+}
+
+func handleError(err error) {
+ if err != nil {
+ os.Stderr.Write([]byte("\x1B[1;31mPrompt error: " + err.Error() + "\x1B[0m\n"))
+ }
+}