Skip to content

Commit d0d260f

Browse files
fix(ui): flatten multiline commands and enforce strict width truncation
- Replaces newlines with spaces in suggestions to prevent box deformation. - Implements multiline detection with `...` indicators. - Enforces an aggressive terminal width safety limit to prevent line wrapping. - Optimizes rendering math for perfect border alignment.
1 parent ffdd1d7 commit d0d260f

File tree

3 files changed

+83
-45
lines changed

3 files changed

+83
-45
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build
22
.vscode
33
benchmark*.md
4-
benchmark*.png
4+
benchmark*.png
5+
man_inst.sh

install.sh

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,68 @@
1-
#!/usr/bin/env zsh
1+
set -e
22

3-
DAEMON_NAME="bsh-daemon"
3+
REPO="joshikarthikey/bsh"
44
INSTALL_DIR="$HOME/.bsh"
5-
BIN_PATH="$INSTALL_DIR/bin"
6-
ZSH_INIT_FILE="scripts/bsh_init.zsh"
75
ZSHRC_PATH="$HOME/.zshrc"
86

9-
echo "Preparing BSH installation..."
10-
mkdir -p "$BIN_PATH"
11-
mkdir -p "$INSTALL_DIR/scripts"
7+
VERSION="${BSH_VERSION:-latest}"
128

13-
echo "Building C++ background daemon..."
14-
if ! command -v cmake &> /dev/null; then
15-
echo "Error: CMake is required but not found. Please install CMake."
9+
GREEN='\033[0;32m'
10+
BLUE='\033[0;34m'
11+
RED='\033[0;31m'
12+
NC='\033[0m'
13+
14+
echo -e "${BLUE}=== Installing BSH (Better Shell History) ===${NC}"
15+
16+
OS="$(uname -s)"
17+
ARCH="$(uname -m)"
18+
19+
if [ "$OS" = "Linux" ] && [ "$ARCH" = "x86_64" ]; then
20+
TARGET="bsh-linux-x86_64"
21+
elif [ "$OS" = "Darwin" ] && [ "$ARCH" = "arm64" ]; then
22+
TARGET="bsh-macos-arm64"
23+
elif [ "$OS" = "Darwin" ] && [ "$ARCH" = "x86_64" ]; then
24+
TARGET="bsh-macos-x86_64"
25+
else
26+
echo -e "${RED}Error: Unsupported OS or Architecture ($OS $ARCH)${NC}"
27+
echo "Currently, BSH provides pre-compiled binaries for Linux (x86_64) and macOS (x86_64, arm64)."
1628
exit 1
1729
fi
1830

19-
rm -rf build
20-
cmake -B build -G Ninja
21-
cmake --build build --target "$DAEMON_NAME"
31+
echo -e "Detected platform: ${GREEN}$TARGET${NC}"
2232

23-
if [[ $? -ne 0 ]]; then
24-
echo "Error: C++ compilation failed. Aborting."
25-
exit 1
33+
if [ "$VERSION" = "latest" ]; then
34+
DOWNLOAD_URL="https://github.com/$REPO/releases/latest/download/${TARGET}.tar.gz"
35+
echo "Downloading latest release from GitHub..."
36+
else
37+
DOWNLOAD_URL="https://github.com/$REPO/releases/download/${VERSION}/${TARGET}.tar.gz"
38+
echo "Downloading release ${VERSION} from GitHub..."
2639
fi
2740

28-
echo "Installing binaries and scripts..."
41+
mkdir -p "$INSTALL_DIR"
2942

30-
cp "build/$DAEMON_NAME" "$BIN_PATH/$DAEMON_NAME"
43+
if ! curl -sSL "$DOWNLOAD_URL" | tar -xz -C "$INSTALL_DIR"; then
44+
echo -e "${RED}Error: Failed to download or extract the release.${NC}"
45+
echo "URL attempted: $DOWNLOAD_URL"
46+
echo "Please check your internet connection or verify that the version exists."
47+
exit 1
48+
fi
3149

32-
cp "$ZSH_INIT_FILE" "$INSTALL_DIR/scripts/"
50+
chmod +x "$INSTALL_DIR/bin/bsh-daemon"
3351

3452
pkill bsh-daemon || true
3553

36-
echo "Updating $ZSHRC_PATH..."
54+
echo -e "Updating $ZSHRC_PATH..."
3755

3856
INIT_LINE="source $INSTALL_DIR/scripts/bsh_init.zsh"
3957

40-
if ! grep -q "$INIT_LINE" "$ZSHRC_PATH"; then
41-
echo "\n# BSH History Integration (Added by install.sh)" >> "$ZSHRC_PATH"
42-
echo "$INIT_LINE" >> "$ZSHRC_PATH"
43-
echo "Success! Please run 'source $ZSHRC_PATH' or restart your terminal."
58+
if [ -f "$ZSHRC_PATH" ] && grep -q "$INIT_LINE" "$ZSHRC_PATH"; then
59+
echo "Note: BSH initialization is already present in your .zshrc."
4460
else
45-
echo "Note: BSH initialization already found in $ZSHRC_PATH. Skipping update."
46-
fi
61+
echo -e "\n# BSH History Integration" >> "$ZSHRC_PATH"
62+
echo "$INIT_LINE" >> "$ZSHRC_PATH"
63+
echo -e "${GREEN}Added BSH hook to your .zshrc!${NC}"
64+
fi
65+
66+
echo -e "\n${BLUE}=== Installation Complete! ===${NC}"
67+
echo -e "To start using BSH, either restart your terminal or run:"
68+
echo -e " ${GREEN}source ~/.zshrc${NC}\n"

src/daemon.cpp

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -213,37 +213,52 @@ int main(int argc, char* argv[]) {
213213
}
214214

215215
for (const auto& r : results) {
216-
response += r.cmd + "\n";
216+
std::string flat_cmd = r.cmd;
217+
std::replace(flat_cmd.begin(), flat_cmd.end(), '\n', ' ');
218+
std::replace(flat_cmd.begin(), flat_cmd.end(), '\r', ' ');
219+
response += flat_cmd + "\n";
217220
}
218221
response += "##BOX##\n";
219-
222+
223+
220224
std::vector<std::string> display_lines;
221-
size_t max_len = utf8_length(header_text);
222-
int safe_limit = term_width - 7;
223-
if (safe_limit < 10) safe_limit = 10;
225+
226+
int safe_limit = term_width - 6;
227+
if (safe_limit < 20) safe_limit = 20;
228+
229+
size_t max_content = utf8_length(header_text);
224230

225231
for (size_t i = 0; i < results.size(); ++i) {
226-
std::string line = std::to_string(i + 1) + ": " + results[i].cmd;
227-
if (utf8_length(line) > (size_t)safe_limit) {
228-
line = truncate_utf8(line, safe_limit - 3) + "...";
232+
std::string prefix = std::to_string(i + 1) + ": ";
233+
std::string cmd_text = results[i].cmd;
234+
235+
size_t first_nl = cmd_text.find_first_of("\n\r");
236+
if (first_nl != std::string::npos) {
237+
cmd_text = cmd_text.substr(0, first_nl) + "...";
238+
}
239+
240+
if (utf8_length(prefix + cmd_text) > (size_t)safe_limit) {
241+
cmd_text = truncate_utf8(cmd_text, safe_limit - utf8_length(prefix) - 3) + "...";
229242
}
230-
line = " " + line;
231-
size_t len = utf8_length(line);
232-
if (len > max_len) max_len = len;
233-
display_lines.push_back(line);
243+
244+
std::string full_line = prefix + cmd_text;
245+
size_t len = utf8_length(full_line);
246+
if (len > max_content) max_content = len;
247+
display_lines.push_back(full_line);
234248
}
235249

236-
max_len += 4;
250+
size_t total_width = max_content + 2;
237251

238-
std::string top_border = "\n" + pad_right("" + header_text, max_len + 1, "") + "\n";
239-
response += top_border;
252+
response += "\n";
253+
std::string top = "" + header_text;
254+
response += pad_right(top, total_width + 1, "") + "\n";
240255

241256
for (const auto& dl : display_lines) {
242-
response += "" + pad_right(dl, max_len, " ") + "\n";
257+
std::string row = " " + dl;
258+
response += "" + pad_right(row, total_width, " ") + "\n";
243259
}
244260

245-
std::string bottom_border = pad_right("", max_len + 1, "") + "\n";
246-
response += bottom_border;
261+
response += "" + pad_right("", total_width, "") + "\n";
247262
}
248263

249264
else if (command == "RECORD" && args.size() >= 6) {

0 commit comments

Comments
 (0)