Задать вопрос
@Drovosek01

Почему в VSCode часто ломается подсветка синтаксиса и как это исправить?

Все чаще в VSCode сталкиваюсь с тем, что в нем ломается подсветка синтаксиса в файлах, где больше "5 строк кода"...

В основном пишу shell-скрипты и C++ код в macOS.

Вот из последних файлов, с которым я работал, код скрипта такой:
скрипт

#!/bin/bash

# Функция для парсинга Mach-O Universal header
get_fat_info() {
    local FILE="$1"
    local QUERY_TYPE=""
    local QUERY_ARCH=""
    local HEX_MODE=0

    # Парсим аргументы
    shift 1  # Удаляем первый аргумент (FILE)
    for arg in "$@"; do
        case "$arg" in
            --offset|--size|--align)
                QUERY_TYPE="$arg"
                ;;
            --hex)
                HEX_MODE=1
                ;;
            *)
                if [ -n "$QUERY_TYPE" ] && [ -z "$QUERY_ARCH" ]; then
                    QUERY_ARCH="$arg"
                fi
                ;;
        esac
    done

    # Проверяем, что файл передан
    [ -z "$FILE" ] && { echo "Usage: get_fat_info <file> [--offset|--size|--align <arch>] [--hex]"; return 1; }

    # --- Читаем magic ---
    local MAGIC=$(xxd -s 0 -l 4 -p "$FILE")

    case "$MAGIC" in
        # cafebabe) IS64=0; echo "Fat binary (32-bit header)" ;;
        # cafebabf) IS64=1; echo "Fat binary (64-bit header)" ;;
        cafebabe) local IS64=0 ;;
        cafebabf) local IS64=1 ;;
        *)
            echo "Not a fat/universal binary (magic: 0x$MAGIC)" >&2
            return 1
            ;;
    esac

    # --- Количество архитектур ---
    local NFAT=$(( 16#$(xxd -s 4 -l 4 -p "$FILE") ))

    # --- Размер одной записи ---
    [ $IS64 -eq 1 ] && local ENTRY=32 || local ENTRY=20

    for (( i=0; i<NFAT; i++ )); do
        local BASE=$(( 8 + i * ENTRY ))

        local CPU=$(( 16#$(xxd -s $BASE -l 4 -p "$FILE") ))
        local SUB=$(( 16#$(xxd -s $((BASE+4)) -l 4 -p "$FILE") ))

        if [ $IS64 -eq 1 ]; then
            local OFF=$((  16#$(xxd -s $((BASE+8))  -l 8 -p "$FILE") ))
            local SZ=$((   16#$(xxd -s $((BASE+16)) -l 8 -p "$FILE") ))
            local ALIGN=$((16#$(xxd -s $((BASE+24)) -l 4 -p "$FILE") ))
        else
            local OFF=$((  16#$(xxd -s $((BASE+8))  -l 4 -p "$FILE") ))
            local SZ=$((   16#$(xxd -s $((BASE+12)) -l 4 -p "$FILE") ))
            local ALIGN=$((16#$(xxd -s $((BASE+16)) -l 4 -p "$FILE") ))
        fi

        # --- Определяем имя архитектуры ---
        local ARCH="unknown"
        case $CPU in
            7)        ARCH="i386"    ;;
            12)       ARCH="arm"     ;;
            16777223) ARCH="x86_64"  ;;   # 0x01000007
            16777228)                        # 0x0100000C
                if [ $(( SUB & 0x00FFFFFF )) -eq 2 ]; then
                    ARCH="arm64e"
                else
                    ARCH="arm64"
                fi ;;
        esac

        # Если запрошен конкретный параметр для конкретной архитектуры
        if [ -n "$QUERY_TYPE" ] && [ -n "$QUERY_ARCH" ]; then
            if [ "$ARCH" = "$QUERY_ARCH" ]; then
                case "$QUERY_TYPE" in
                    --offset)
                        if [ $HEX_MODE -eq 1 ]; then
                            printf "0x%x\n" "$OFF"
                        else
                            echo "$OFF"
                        fi
                        return 0
                        ;;
                    --size)
                        if [ $HEX_MODE -eq 1 ]; then
                            printf "0x%x\n" "$SZ"
                        else
                            echo "$SZ"
                        fi
                        return 0
                        ;;
                    --align)
                        if [ $HEX_MODE -eq 1 ]; then
                            printf "0x%x\n" "$ALIGN"
                        else
                            echo "$ALIGN"
                        fi
                        return 0
                        ;;
                esac
            fi
        else
            # Стандартный вывод
            printf "  %-8s  cputype=0x%08x  subtype=0x%08x\n" "$ARCH" "$CPU" "$SUB"
            if [ $HEX_MODE -eq 1 ]; then
                printf "            offset = 0x%x\n" "$OFF"
                printf "            size   = 0x%x\n" "$SZ"
                printf "            align  = 2^%d = %d bytes\n" "$ALIGN" "$(( 1 << ALIGN ))"
            else
                printf "            offset = %10d  (0x%x)\n" "$OFF" "$OFF"
                printf "            size   = %10d  (0x%x)\n" "$SZ"  "$SZ"
                printf "            align  = 2^%d = %d bytes\n" "$ALIGN" "$(( 1 << ALIGN ))"
            fi
            echo ""
        fi
    done

    # Если запрошенный параметр не найден
    if [ -n "$QUERY_TYPE" ] && [ -n "$QUERY_ARCH" ]; then
        echo "Architecture '$QUERY_ARCH' not found or parameter '$QUERY_TYPE' is invalid." >&2
        return 1
    fi
}

# Вызов функции, если скрипт запущен напрямую
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    get_fat_info "$@"
fi


Но за ~15 строк до конца файла подсветка синтаксиса становится "однотонной", то есть перестает выполнять свою функцию:
скриншот
4512618b2cf35d625e17a26ffb69e4e9.png

Хотя в Subilme Text и на Github - все нормально с подсветкой
Это можно посмотреть в моем issue, например - github.com/microsoft/vscode/issues/326547

Почему так и как это исправить?
  • Вопрос задан
  • 62 просмотра
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    1C-программист: расширенный курс
    18 месяцев
    Далее
  • Академия Эдюсон
    Python-разработчик + ИИ
    9 месяцев
    Далее
  • ProductStar × РБК
    Профессия DevOps-инженер + ИИ
    5 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 2
VoidVolker
@VoidVolker
Dark side eye. А у нас печеньки! А у вас?
Тут даже на скриншоте видно, что ломается на "$(( .. ))" и дальше стандартный парсер shellscript просто не видит конца подстроки. Очевидно, что он не поддерживает этот синтаксис. Просто поставьте плагин для подсветки синтаксиса именно баша. Ибо стандартов оболочек много всяких, а реализаций ещё больше. И везде свои фичи есть.
Ответ написан
opium
@opium
Просто люблю качественно работать
это не размер файла и не косяк скрипта. У vscode в родной баш-грамматике баг на такой смешанной вложенности $(( )), как в твоём 16#$(xxd -s $((BASE+8))...) — теряет состояние подсветки. В Sublime и на гитхабе грамматика другая, потому там нормально. Better Shell Syntax поэтому и помог. Без плагина — вынеси внутренний $(( )) в отдельную переменную, тройную вложенность родная подсветка не разжуёт.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы