diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index d84f269..80953ac 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,54 +1,272 @@ -name: Gitea Actions Demo -run-name: ${{ gitea.actor }} is testing out Gitea Actions πŸš€ -on: [push] +name: Build and Release +on: + push: + branches: + - master + - main + workflow_dispatch: # Π ΡƒΡ‡Π½ΠΎΠΉ запуск jobs: - Explore-Gitea-Actions: + build: runs-on: tcl-tk-builder steps: - - name: Build the DEB-packages + - name: ΠšΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ run: | - git clone ${{ vars.main_url }}${{ gitea.repository }} - pwd - cd projman/debian - ./build-deb-projman.sh - cd ../openbsd - ./build-package-bsd.sh - cd ../../ - curl --user ${{secrets.USER}}:${{secrets.API_TOKEN}} --upload-file "$(ls -1| grep projman | grep -E 'deb$')" ${{vars.main_url}}api/packages/${{vars.user}}/debian/pool/bookworm/main/upload - - run: echo "This job's status is ${{ job.status }}." - - - name: Create release - run: | - # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ€Π΅Π»ΠΈΠ· Ρ‡Π΅Ρ€Π΅Π· API - curl -X POST \ - -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ - -H "Content-Type: application/json" \ - -d '{ - "tag_name": "'"${{ gitea.ref_name }}"'", - "name": "Release '"${{ gitea.ref_name }}"'", - "body": "Automated release for '"${{ gitea.ref_name }}"'", - "draft": false, - "prerelease": false - }' \ - "${{vars.main_url}}/api/v1/repos/${{ gitea.repository }}/releases" - - - name: Get release ID - id: release_info - run: | - response=$(curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ - "${{vars.main_url}}/api/v1/repos/${{ gitea.repository }}/releases/tags/${{ gitea.ref_name }}") + git clone "${{ vars.main_url }}${{ gitea.repository }}.git" . - echo "id=$(echo $response | jq -r '.id')" >> $GITHUB_OUTPUT - - - name: Upload Linux package + - name: ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ вСрсии + id: get_version run: | - curl --user "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ - --upload-file "$(ls -1| grep projman | grep -E 'deb$')" \ - "${{vars.main_url}}/api/v1/repos/${{ gitea.repository }}/releases/${{ steps.release_info.outputs.id }}/assets?name=$(ls -1| grep projman | grep -E 'deb$')" + VERSION=$(grep "Version" projman.tcl | head -1 | grep -o '[0-9.]\+[a-zA-Z0-9]*' || echo "1.0.0") + RELEASE=$(grep "# Release" projman.tcl | tail -1 | awk '{print $NF}' || echo "$(date +%Y%m%d)") + + # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ имя Ρ‚Π΅Π³Π° + TAG="v${VERSION}" + echo "TAG=$TAG" >> $GITEA_ENV + echo "VERSION=$VERSION" >> $GITEA_ENV + echo "RELEASE=$RELEASE" >> $GITEA_ENV + + echo "Π’Π΅Π³: $TAG" + echo "ВСрсия: $VERSION" + echo "РСвизия: $RELEASE" - - name: Upload OpenBSD package + - name: ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования Ρ‚Π΅Π³Π° + id: check_tag run: | - curl --user "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ - --upload-file "$(ls -1| grep projman | grep -E 'tgz$')" \ - "${{vars.main_url}}/api/v1/repos/${{ gitea.repository }}/releases/${{ steps.release_info.outputs.id }}/assets?name=$(ls -1| grep projman | grep -E 'tgz$')" + echo "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Ρ‚Π΅Π³: $TAG" + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ сСрвСрС + if git ls-remote --tags origin "$TAG" 2>/dev/null | grep -q "$TAG"; then + echo "Π’Π΅Π³ $TAG ΡƒΠΆΠ΅ сущСствуСт Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ сСрвСрС" + echo "TAG_EXISTS_REMOTE=true" >> $GITEA_ENV + else + echo "Π’Π΅Π³ $TAG Π½Π΅ сущСствуСт Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ сСрвСрС" + echo "TAG_EXISTS_REMOTE=false" >> $GITEA_ENV + fi + + - name: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ‚Π΅Π³Π° (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли Π½Π΅ сущСствуСт) + if: env.TAG_EXISTS_REMOTE == 'false' + run: | + echo "Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ Ρ‚Π΅Π³: $TAG" + git config user.email "svk@nuk-svk.ru" + git config user.name "svk" + + # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ‚Π΅Π³ локально + git tag -a "$TAG" -m "Release $TAG - $RELEASE" + + # НастраиваСм URL для push + git remote set-url origin "https://${{ secrets.USER }}:${{ secrets.API_TOKEN }}@git.nuk-svk.ru/${{ gitea.repository }}.git" + + # ΠŸΡƒΡˆΠΈΠΌ Ρ‚Π΅Π³ Π½Π° сСрвСр + git push origin "$TAG" + + - name: Π‘Π±ΠΎΡ€ΠΊΠ° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² + run: | + echo "=== Π‘Π±ΠΎΡ€ΠΊΠ° DEB ΠΏΠ°ΠΊΠ΅Ρ‚Π° ===" + cd debian && ./build-deb-projman.sh + + echo "=== Π‘Π±ΠΎΡ€ΠΊΠ° OpenBSD ΠΏΠ°ΠΊΠ΅Ρ‚Π° ===" + cd ../openbsd && ./build-package-bsd.sh + + echo "=== Π‘Π±ΠΎΡ€ΠΊΠ° RPM ΠΏΠ°ΠΊΠ΅Ρ‚Π° ===" + cd ../redhat && ./build-rpm.sh + + echo "=== Π‘ΠΎΠ±Ρ€Π°Π½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ===" + find . -maxdepth 1 -name "projman*" -type f | xargs ls -la 2>/dev/null || echo "Π€Π°ΠΉΠ»Ρ‹ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Ρ‹" + + - name: ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования Ρ€Π΅Π»ΠΈΠ·Π° + id: check_release + run: | + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, сущСствуСт Π»ΠΈ ΡƒΠΆΠ΅ Ρ€Π΅Π»ΠΈΠ· для этого Ρ‚Π΅Π³Π° + RESPONSE=$(curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/tags/$TAG" || echo "{}") + + echo "ΠžΡ‚Π²Π΅Ρ‚ API ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅Π»ΠΈΠ·Π°: $RESPONSE" + + # ИзвлСкаСм id Ρ€Π΅Π»ΠΈΠ·Π° - ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ id Π² JSON + if echo "$RESPONSE" | grep -q '"id"'; then + # ИзвлСкаСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ id (id Ρ€Π΅Π»ΠΈΠ·Π°), ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ id Π°Π²Ρ‚ΠΎΡ€Π° + # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ awk для Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ извлСчСния + REL_ID=$(echo "$RESPONSE" | awk -F'"id":' '{print $2}' | awk -F',' '{print $1}' | head -1 | tr -d ' ') + echo "Π Π΅Π»ΠΈΠ· ΡƒΠΆΠ΅ сущСствуСт. ID: $REL_ID" + echo "RELEASE_EXISTS=true" >> $GITEA_ENV + + # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ ΠΈ сохраняСм REL_ID Π² Ρ„Π°ΠΉΠ» + echo -n "$REL_ID" | tr -d '\n' > /tmp/rel_id.txt + else + echo "Π Π΅Π»ΠΈΠ· Π½Π΅ сущСствуСт" + echo "RELEASE_EXISTS=false" >> $GITEA_ENV + echo -n "" > /tmp/rel_id.txt + fi + + - name: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π»ΠΈΠ·Π° + id: create_release + run: | + # Π§ΠΈΡ‚Π°Π΅ΠΌ REL_ID ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ΠΈ ΠΎΡ‡ΠΈΡ‰Π°Π΅ΠΌ ΠΎΡ‚ Π»ΠΈΡˆΠ½ΠΈΡ… символов + REL_ID=$(cat /tmp/rel_id.txt 2>/dev/null | tr -d '\n\r ' || echo "") + + echo "=== Π Π°Π±ΠΎΡ‚Π° с Ρ€Π΅Π»ΠΈΠ·ΠΎΠΌ для Ρ‚Π΅Π³Π° $TAG ===" + echo "RELEASE_EXISTS: $RELEASE_EXISTS" + echo "REL_ID: '$REL_ID'" + + RELEASE_BODY="## Projman $VERSION + + **РСвизия:** $RELEASE + **Π”Π°Ρ‚Π° сборки:** $(date) + **ΠšΠΎΠΌΠΌΠΈΡ‚:** $(git rev-parse --short HEAD)" + + + # Π­ΠΊΡ€Π°Π½ΠΈΡ€ΡƒΠ΅ΠΌ пСрСносы строк для JSON + ESCAPED_BODY=$(echo "$RELEASE_BODY" | sed ':a;N;$!ba;s/\n/\\n/g') + + if [ "$RELEASE_EXISTS" = "true" ] && [ -n "$REL_ID" ]; then + echo "ОбновляСм ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π»ΠΈΠ· ID: $REL_ID" + + # ОбновляСм ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π»ΠΈΠ· + RESPONSE=$(curl -s -X PATCH \ + -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Projman '"$VERSION"'", + "body": "'"$ESCAPED_BODY"'", + "draft": false, + "prerelease": false + }' \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID") + + echo "ΠžΡ‚Π²Π΅Ρ‚ обновлСния Ρ€Π΅Π»ΠΈΠ·Π°: $RESPONSE" + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚ + if echo "$RESPONSE" | grep -q '"id"'; then + echo "Π Π΅Π»ΠΈΠ· ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½" + else + echo "ΠžΠ¨Π˜Π‘ΠšΠ: НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ€Π΅Π»ΠΈΠ·" + echo "ΠžΡ‚Π²Π΅Ρ‚: $RESPONSE" + exit 1 + fi + + else + echo "Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅Π»ΠΈΠ·" + + # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅Π»ΠΈΠ· + RESPONSE=$(curl -s -X POST \ + -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d '{ + "tag_name": "'"$TAG"'", + "name": "Projman '"$VERSION"'", + "body": "'"$ESCAPED_BODY"'", + "draft": false, + "prerelease": false + }' \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases") + + echo "ΠžΡ‚Π²Π΅Ρ‚ создания Ρ€Π΅Π»ΠΈΠ·Π°: $RESPONSE" + + # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ID Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ€Π΅Π»ΠΈΠ·Π° + NEW_REL_ID=$(echo "$RESPONSE" | awk -F'"id":' '{print $2}' | awk -F',' '{print $1}' | head -1 | tr -d ' ') + if [ -n "$NEW_REL_ID" ]; then + echo "Новый ID Ρ€Π΅Π»ΠΈΠ·Π°: $NEW_REL_ID" + echo -n "$NEW_REL_ID" > /tmp/rel_id.txt + else + echo "ΠžΠ¨Π˜Π‘ΠšΠ: НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ID Ρ€Π΅Π»ΠΈΠ·Π° ΠΈΠ· ΠΎΡ‚Π²Π΅Ρ‚Π°" + echo "ΠžΡ‚Π²Π΅Ρ‚: $RESPONSE" + echo -n "" > /tmp/rel_id.txt + exit 1 + fi + fi + + - name: Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Ρ€Π΅Π»ΠΈΠ· + run: | + # Π§ΠΈΡ‚Π°Π΅ΠΌ REL_ID ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ΠΈ ΠΎΡ‡ΠΈΡ‰Π°Π΅ΠΌ + REL_ID=$(cat /tmp/rel_id.txt 2>/dev/null | tr -d '\n\r ' || echo "") + + if [ -z "$REL_ID" ]; then + echo "НСт ID Ρ€Π΅Π»ΠΈΠ·Π°, пропускаСм Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Ρ„Π°ΠΉΠ»ΠΎΠ²" + exit 0 + fi + + echo "=== Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Ρ€Π΅Π»ΠΈΠ· ===" + echo "ID Ρ€Π΅Π»ΠΈΠ·Π° для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ: $REL_ID" + + # Находим всС Ρ„Π°ΠΉΠ»Ρ‹ projman + FILES=$(find ../ -maxdepth 1 \( -name "*projman*deb" -o -name "*projman*tgz" -o -name "*projman*rpm" \) -type f) + if [ -z "$FILES" ]; then + echo "НСт Ρ„Π°ΠΉΠ»ΠΎΠ² projman для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ" + exit 0 + fi + + echo "НайдСны Ρ„Π°ΠΉΠ»Ρ‹:" + echo "$FILES" + + # Π‘Π½Π°Ρ‡Π°Π»Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ассСты + echo "=== ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ассСты ===" + curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID/assets" | \ + jq -r '.[].name' 2>/dev/null || echo "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список ассСтов" + + # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ„Π°ΠΉΠ» + for FILE in $FILES; do + FILENAME=$(basename "$FILE") + echo "Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ: $FILENAME" + + # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ endpoint для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ассСтов + UPLOAD_URL="${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID/assets" + + echo "URL Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ: $UPLOAD_URL?name=$FILENAME" + + # Π—Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Ρ„Π°ΠΉΠ» + RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" \ + --user "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + -H "Content-Type: application/octet-stream" \ + -X POST \ + --data-binary @"$FILE" \ + "$UPLOAD_URL?name=$FILENAME") + + HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS:" | cut -d':' -f2) + API_RESPONSE=$(echo "$RESPONSE" | grep -v "HTTP_STATUS:") + + echo "Бтатус: $HTTP_STATUS" + echo "ΠžΡ‚Π²Π΅Ρ‚ API: $API_RESPONSE" + + if [ "$HTTP_STATUS" = "201" ] || [ "$HTTP_STATUS" = "200" ]; then + echo "Π€Π°ΠΉΠ» Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½: $FILENAME" + else + echo "ΠžΠ¨Π˜Π‘ΠšΠ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ: $FILENAME" + echo "Π”Π΅Ρ‚Π°Π»ΠΈ: $API_RESPONSE" + fi + + echo "---" + done + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ список ассСтов + echo "=== Π˜Ρ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ список ассСтов ===" + curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID/assets" | \ + jq -r '.[] | "\(.name) - \(.browser_download_url)"' 2>/dev/null || \ + curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID/assets" | \ + grep -o '"name":"[^"]*"' | cut -d'"' -f4 + + - name: Ѐинализация + run: | + # Π§ΠΈΡ‚Π°Π΅ΠΌ REL_ID ΠΈΠ· Ρ„Π°ΠΉΠ»Π° + REL_ID=$(cat /tmp/rel_id.txt 2>/dev/null | tr -d '\n\r ' || echo "") + + echo "=== Π‘Π±ΠΎΡ€ΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° ===" + echo "Π’Π΅Π³: $TAG" + echo "ВСрсия: $VERSION" + echo "РСвизия: $RELEASE" + echo "ID Ρ€Π΅Π»ΠΈΠ·Π°: $REL_ID" + + if [ -n "$REL_ID" ]; then + echo "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Ρ„Π°ΠΉΠ»Ρ‹ Π² Ρ€Π΅Π»ΠΈΠ·Π΅..." + curl -s -u "${{ secrets.USER }}:${{ secrets.API_TOKEN }}" \ + "${{ vars.main_url }}api/v1/repos/${{ gitea.repository }}/releases/$REL_ID/assets" | \ + grep -o '"name":"[^"]*"' | cut -d'"' -f4 || echo "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список Ρ„Π°ΠΉΠ»ΠΎΠ²" + else + echo "Π Π΅Π»ΠΈΠ· Π½Π΅ Π±Ρ‹Π» создан ΠΈΠ»ΠΈ ID Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½" + fi + + echo "Π‘ΠΎΠ±Ρ€Π°Π½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹:" + find ../ -maxdepth 1 \( -name "*projman*deb" -o -name "*projman*tgz" -o -name "*projman*rpm"\) -type f | xargs ls -la 2>/dev/null || echo "Π€Π°ΠΉΠ»Ρ‹ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Ρ‹" diff --git a/CHANGELOG b/CHANGELOG index 024df15..dcc39b6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ + projman (2.0.0-beta1) stable; urgency=medium * Π‘Π΄Π΅Π»Π°Π½ Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΠΎ запросу. diff --git a/README.md b/README.md index bacf2bc..20e2633 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Highlightning and source code navigation: * Markdown * YAML (Ansible support) * Lua +* C Highlightning: @@ -158,6 +159,29 @@ Or type "projman" into terminal, Or choose the name of the program "Projman" on - Alt-S - Split the edited window horizontally - Alt-K - Open folder +### Work with external tools +ProjMan allows you to connect any external tools to the editor. To do this, you need to add an entry to the file ~/.config/projman/tools.ini. + +Calling an external program is available through the main and pop-up menus. To transfer the parameters, write the appropriate template in the file. + - %s - template for substituting selected text in the editor + - %f - template for substituting selected file\(s\) in the file tree + +When adding multiple %f templates, the corresponding number of files allocated in the tree will be substituted. + +``` +[TkDIFF] +commandString=tkdiff %f %f +description=TkDiff is a Tcl/Tk front-end to diff +icon= +shortCut= + +[VisualRegexp] +commandString=tkregexp "%s" +description=A graphical front-end to write/debug regular expression +icon= +shortCut= +``` + ## Credits Sergey Kalinin - author diff --git a/changelog-gen.tcl b/changelog-gen.tcl index 78a6c0d..f1406f7 100755 --- a/changelog-gen.tcl +++ b/changelog-gen.tcl @@ -106,14 +106,14 @@ proc ReadGitLog {} { } } -proc StoreProjectInfo {timeStamp} { +proc StoreProjectInfo {timeStamp changelogFormat} { global dir args - set cfgFile [open [file join $dir(cfg) $args(--project-name).conf] "w+"] + set cfgFile [open [file join $dir(cfg) $args(--project-name).$changelogFormat.conf] "w+"] puts $cfgFile "# set args(--project-version) \"$args(--project-version)\"" puts $cfgFile "# set args(--project-release) \"$args(--project-release)\"" puts $cfgFile "set lastCommitTimeStamp \"$timeStamp\"" puts $cfgFile "set lastCommitTimeStampSec [clock scan $timeStamp]" - close $cfgFile + close $cfgFile } @@ -141,37 +141,77 @@ proc GenerateChangelogDEB {} { set timeStamp [clock format [clock scan $timeStamp] -format {%a, %e %b %Y %H:%M:%S %z}] # puts "> $commiter" if {$index == 0} { - puts "$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n" + # puts "$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n" append outText "$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n\n" set commiter [lindex $record 2] - StoreProjectInfo $timeStamp + StoreProjectInfo $timeStamp "deb" # puts "\n \[ [string trim $commiter] \]" } # puts ">> $commiter" if {$commiter ne [lindex $record 2]} { - puts "\n -- [string trim $commiter] <$email> $timeStamp" + # puts "\n -- [string trim $commiter] <$email> $timeStamp" append outText "\n -- [string trim $commiter] <$email> $timeStamp\n" - puts "\n$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n" + # puts "\n$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n" append outText "\n$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n\n" set commiter [lindex $record 2] # puts "\n \[ [string trim $commiter] \]" } set commitTex [lindex $record 4] - puts " * $commitTex" + # puts " * $commitTex" append outText " * $commitTex\n" } - puts "\n -- [string trim $commiter] <$email> $timeStamp" + # puts "\n -- [string trim $commiter] <$email> $timeStamp" append outText "\n -- [string trim $commiter] <$email> $timeStamp\n" return $outText } proc GenerateChangelogRPM {} { - puts "GenerateChangelogRPM" - + global args + # puts "GenerateChangelogRPM" + set lastCommitTimeStamp "" + set commiter "" + set commitText "" + # ReadGitLog + set lst [lsort -integer -index 0 [ReadGitLog]] + # puts $lst + # exit + set outText "" + foreach l $lst { + set index [lindex $l 0] + set line [lindex $l 1] + # puts "$index - $line" + set record [split $line ","] + set timeStamp [string trim [lindex $record 1]] + set email [string trim [lindex $record 3]] + if {$lastCommitTimeStamp eq ""} { + set lastCommitTimeStamp [string trim [lindex $record 1]] + } + set timeStampForStore [clock format [clock scan $timeStamp] -format {%a, %e %b %Y %H:%M:%S %z}] + set timeStamp [clock format [clock scan $timeStamp] -format {%a %b %e %Y}] + if {$index == 0} { + set commiter [lindex $record 2] + append outText "* $timeStamp [string trim $commiter] <$email> $args(--project-version)-$args(--project-release)\n" + StoreProjectInfo $timeStampForStore "rpm" + } + if {$commiter ne [lindex $record 2]} { + append outText "\n" + append outText "* $timeStamp [string trim $commiter] <$email> $args(--project-version)-$args(--project-release)\n" + set commiter [lindex $record 2] + } + + set commitTex [lindex $record 4] + # puts " * $commitTex" + append outText " - $commitTex\n" + + } + # puts "\n -- [string trim $commiter] <$email> $timeStamp" + # append outText "\n -- [string trim $commiter] <$email> $timeStamp\n" + return $outText } + proc GenerateChangelogTXT {} { global args set lastCommitTimeStamp "" @@ -189,14 +229,15 @@ proc GenerateChangelogTXT {} { if {$lastCommitTimeStamp eq ""} { set lastCommitTimeStamp [string trim [lindex $record 1]] } - set timeStamp [clock format [clock scan $timeStamp] -format {%a, %e %b %Y %H:%M:%S %z}] + # * Mon Nov 28 2022 Sergey Kalinin 2.0.0 + set timeStamp [clock format [clock scan $timeStamp] -format {%a %b %e %Y %H:%M:%S %z}] # puts "> $commiter" if {$index == 0} { append outText "$args(--project-name) ($args(--project-version)-$args(--project-release))\n" set commiter [lindex $record 2] puts "\n[string trim $commiter] <$email> $timeStamp" append outText "\n[string trim $commiter] <$email> $timeStamp\n" - StoreProjectInfo $timeStamp + StoreProjectInfo $timeStamp "txt" } if {$commiter ne [lindex $record 2]} { puts "\n[string trim $commiter] <$email> $timeStamp" @@ -254,6 +295,68 @@ proc StoreChangeLog {outText} { } else { set outFile [open $args(--out-file) "w+"] puts $outFile $outText + puts $outText + close $outFile + } +} + +proc StoreChangeLogRPM {outText} { + global args + if [file exists $args(--out-file)] { + file copy -force $args(--out-file) "$args(--out-file).tmp" + + set fh [open $args(--out-file) r] + set lines [split [read $fh] "\n"] + close $fh + + set result [list] + set inserted false + + foreach line $lines { + lappend result $line + + if {!$inserted && $line eq "%changelog"} { + lappend result $outText + set inserted true + } + } + + set fh [open $args(--out-file) w] + puts $fh [join $result "\n"] + close $fh + } +} + +proc StoreChangeLogRPM_ {outText} { + global args + + puts "Changelog generator write a file $args(--out-file)" + + if [file exists $args(--out-file)] { + file copy -force $args(--out-file) "$args(--out-file).tmp" + + set origOutFile [open "$args(--out-file).tmp" "r"] + set origText [read $origOutFile] + close $origOutFile + + set outFile [open $args(--out-file) "w"] + puts $outFile $outText + puts $outFile $origText + close $outFile + + if [info exists args(--last)] { + set outFile [open $args(--out-file) "r+"] + puts $outFile $outText + close $outFile + } else { + set outFile [open $args(--out-file) "w+"] + puts $outFile $outText + close $outFile + } + } else { + set outFile [open $args(--out-file) "w+"] + puts $outFile $outText + puts $outText close $outFile } } @@ -311,26 +414,43 @@ if ![info exists args(--project-release)] { exit } -if [file exists [file join $dir(cfg) $args(--project-name).conf]] { - source [file join $dir(cfg) $args(--project-name).conf] -} +puts "Running chngelog generator with folowing options:\n" foreach arg [array names args] { - puts "$arg $args($arg)" + puts "\t$arg $args($arg)" } if [info exists args(--deb)] { + if [file exists [file join $dir(cfg) $args(--project-name).deb.conf]] { + source [file join $dir(cfg) $args(--project-name).deb.conf] + } set outText [GenerateChangelogDEB] if [info exists args(--out-file)] { StoreChangeLog $outText + } else { + puts $outText } } if [info exists args(--rpm)] { - GenerateChangelogRPM + if [file exists [file join $dir(cfg) $args(--project-name).rpm.conf]] { + source [file join $dir(cfg) $args(--project-name).rpm.conf] + } + set outText [GenerateChangelogRPM] + # puts $outText + if [info exists args(--out-file)] { + StoreChangeLogRPM $outText + } else { + puts $outText + } } if [info exists args(--txt)] { + if [file exists [file join $dir(cfg) $args(--project-name).txt.conf]] { + source [file join $dir(cfg) $args(--project-name).txt.conf] + } set outText [GenerateChangelogTXT] if [info exists args(--out-file)] { StoreChangeLog $outText + } else { + puts $outText } } diff --git a/debian/build-deb-projman.sh b/debian/build-deb-projman.sh index d332154..0cb4911 100755 --- a/debian/build-deb-projman.sh +++ b/debian/build-deb-projman.sh @@ -11,6 +11,7 @@ sed -i "/# Build:.*/c$TXT" projman.tcl cp projman.tcl projman cp changelog-gen.tcl changelog-gen +cp tkregexp.tcl tkregexp ./changelog-gen.tcl --project-name projman --project-version ${VERSION} --project-release ${RELEASE} --out-file debian/changelog --deb --last @@ -25,5 +26,5 @@ dpkg-buildpackage -d #cp ../projman_${VERSION}-${RELEASE}_amd64.deb /files/ -rm -v projman changelog-gen +rm -v projman changelog-gen tkregexp rm -r -v debian/{projman,.debhelper} diff --git a/debian/changelog b/debian/changelog index 52aad62..88dcecf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,43 @@ +projman (2.0.0-beta4) stable; urgency=medium + + * Π”ΠΎΠ±Π°Π²ΠΈΠ» экранированиС '*' Π² ΠΈΠΌΠ΅Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для поиска. + * ΠŸΠΎΠ΄ΠΊΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» рСгулярки для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π‘. + * Π˜ΡΠΈΠΏΡ€Π°Π²ΠΈΠ» Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ ΠΏΡ€ΠΈ отпускании ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ Π½Π° крСстик. + * Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΊΠΎΠ½ΠΊΠΈ для 'c' ΠΈ 'h'. Π”ΠΎΠ±Π°Π²ΠΈΠ» сочитаниС Alt-R Π² русской раскладкС + * Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Π‘ подсвСтка + * Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² + * ΠžΡ‚ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» сборку Ρ€ΠΏΠΌ + * Π”ΠΎΠ±Π°Π²ΠΈΠ» сборку rpm. Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» changelog-ΠΈ + + -- svk Fri, 6 Feb 2026 14:07:53 +0300 + +projman (2.0.0-beta3) stable; urgency=medium + + * changelog-gen: сдСлал Π²Ρ‹Π²ΠΎΠ΄ измСнСния Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ rpm.spec + * Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» смСну рСгистра Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… Π²ΠΊΠ»Π°Π΄ΠΎΠΊ + * Π”ΠΎΠ±Π°Π²ΠΈΠ» Π΄ΠΈΠ°Π»ΠΎΠ³ вмСню "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ" + * Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ FileOper::SaveFile + * ВынСс ΠΊΠΎΠ΄ связанный с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ подсказок ΠΏΡ€ΠΈ Π²Π²ΠΎΠ΄Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ. + * Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ со списком ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΠ· Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΎΠΊΠ½Π°. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρ‚Π°ΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· списка стрСлками ΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎ Enter. Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ клавиш Π’Π²Π΅Ρ€Ρ… Π’Π½ΠΈΠ· Π’Π²ΠΎΠ΄ ΠžΡ‚ΠΌΠ΅Π½Π° Π² ΠΎΠΊΠ½Π΅ со списком Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ². + + -- svk Thu, 29 Jan 2026 14:22:55 +0300 + +projman (2.0.0-beta2) stable; urgency=medium + + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ (bind) сочСтания клавиш ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π² настройках инструмСнтов. + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° динамичСская гСнСрация мСню 'Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹'. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΠΎΠ²Ρ‹Π΅ внСшниС инструмСнты доступны сразу послС сохранСния Ρ„Π°ΠΉΠ»Π° настроСк tools.ini Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅. + * Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка с Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° Π² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ получСния Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ тСкста. + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ настроСк Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов. И ΠΏΡƒΠ½ΠΊΡ‚ Π² мСню 'Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹'->'Настройки' + * Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ошибки с запуском Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ. + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅ΠΉ Π΄ΠΎ Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Ρƒ. + * Π‘Π΄Π΅Π»Π°Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° шаблонов ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки ΠΈ запуск Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов. + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½ tkregexp для установки Π² /usr/bin + * Начало Ρ€Π°Π±ΠΎΡ‚Ρ‹ с внСшними инструмСнтами: - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ созданиС ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² + * Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ скрипт сборки бсд-ΠΏΠ°ΠΊΠ΅Ρ‚Π° + * Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° сборка ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² для openbsd + + -- svk Tue, 27 Jan 2026 16:44:48 +0300 + projman (2.0.0-beta1) stable; urgency=medium * Π‘Π΄Π΅Π»Π°Π½ Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΠΎ запросу. @@ -468,3 +508,5 @@ projman (2.0.0-alfa0) stable; urgency=medium + + diff --git a/debian/install b/debian/install index 954b959..621a7cb 100644 --- a/debian/install +++ b/debian/install @@ -1,5 +1,6 @@ projman /usr/bin/ changelog-gen /usr/bin/ +tkregexp /usr/bin lib/*.tcl /usr/share/projman/lib lib/msgs/* /usr/share/projman/lib/msgs theme /usr/share/projman/ diff --git a/lib/editor.tcl b/lib/editor.tcl index 7e585ee..1be5bf2 100644 --- a/lib/editor.tcl +++ b/lib/editor.tcl @@ -16,7 +16,7 @@ namespace eval Editor { $node.frmText.t configure -$optionName $value } } - + # Comment one string or selected string proc Comment {txt fileType} { global lexers cfgVariables @@ -363,15 +363,24 @@ namespace eval Editor { } } - proc SelectionGet {txt} { - variable selectionText + proc SelectionGet {{txt ""}} { + global nbEditor + variable selectionText "" + if {$txt eq ""} { + DebugPuts "Editor::SelectionGet: [focus]" + set txt [focus] + if {![string match -nocase "*text*" $txt]} { + return "" + } + } set selBegin [lindex [$txt tag ranges sel] 0] set selEnd [lindex [$txt tag ranges sel] 1] if {$selBegin ne "" && $selEnd ne ""} { set selectionText [$txt get $selBegin $selEnd] } + return $selectionText } - + proc SelectionHighlight {txt} { variable selectionText $txt tag remove lightSelected 1.0 end @@ -393,236 +402,16 @@ namespace eval Editor { } } - proc VarHelperKey { widget K A } { - set win .varhelper - # if { [winfo exists $win] == 0 } { return } - set ind [$win.lBox curselection] - # puts ">>>>>>>>>>>> VarHelperBind <<<<<<<<<<<<<<<<" - - switch -- $K { - Prior { - set up [expr [$win.lBox index active] - [$win.lBox cget -height]] - if { $up < 0 } { set up 0 } - $win.lBox activate $up - $win.lBox selection clear 0 end - $win.lBox selection set $up $up - } - Next { - set down [expr [$win.lBox index active] + [$win.lBox cget -height]] - if { $down >= [$win.lBox index end] } { set down end } - $win.lBox activate $down - $win.lBox selection clear 0 end - $win.lBox selection set $down $down - } - Up { - set up [expr [$win.lBox index active] - 1] - if { $up < 0 } { set up 0 } - $win.lBox activate $up - $win.lBox selection clear 0 end - $win.lBox selection set $up $up - } - Down { - set down [expr [$win.lBox index active] + 1] - if { $down >= [$win.lBox index end] } { set down end } - $win.lBox activate $down - $win.lBox selection clear 0 end - $win.lBox selection set $down $down - } - Return { - $widget delete "insert - 1 chars wordstart" "insert wordend - 1 chars" - $widget insert "insert" [$win.lBox get [$win.lBox curselection]] - # eval [bind VarHelperBind ] - Editor::VarHelperEscape $widget - } - default { - $widget insert "insert" $A - # eval [bind VarHelperBind ] - Editor::VarHelperEscape $widget - } - } - } ;# proc auto_completition_key - proc VarHelperEscape {w} { - # puts ">>>>>>>>>>>> VarHelperEscape <<<<<<<<<<<<<<<<" - # bindtags $w [list [winfo parent $w] $w Text sysAfter all] - bindtags $w [list [winfo toplevel $w] $w Ctext sysAfter all] - catch { destroy .varhelper } - DebugPuts [bindtags $w] - DebugPuts [bind $w] - } - proc VarHelper {x y w word wordType} { - global editors lexers variables - variable txt - variable win - # set txt $w.frmText.t - # Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° открытия Π΄ΠΈΠ°Π»ΠΎΠ³Π° Ссли Π·Π°ΠΏΡƒΡ‰Π΅Π½ Π΄Ρ€ΡƒΠ³ΠΎΠΉ - set txt $w - # set win .varhelper - # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Ссли Π΅ΡΡ‚ΡŒ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ появлСниС Π΄ΠΈΠ°Π»ΠΎΠ³Π° - if {[$txt tag ranges sel] != ""} { - DebugPuts "You have selected text [$txt tag ranges sel]" - return - } - # puts "$x $y $w $word $wordType" - set fileType [dict get $editors $txt fileType] - - if {[dict exists $editors $txt variableList] != 0} { - set varList [dict get $editors $txt variableList] - # puts $varList - } - if {[dict exists $editors $txt procedureList] != 0} { - set procList [dict get $editors $txt procedureList] - } - # puts $procList - # puts ">>>>>>>[dict get $lexers $fileType commands]" - if {[dict exists $lexers $fileType commands] !=0} { - foreach i [dict get $lexers $fileType commands] { - # puts $i - lappend procList $i - } - } - - # if {[dict exists $editors $txt variableList] == 0 && [dict exists $editors $txt procedureList] == 0} { - # return - # } - set findedVars "" - switch -- $wordType { - vars { - foreach i [lsearch -nocase -all $varList $word*] { - # puts [lindex $varList $i] - set item [lindex [lindex $varList $i] 0] - # puts $item - if {[lsearch $findedVars $item] eq "-1"} { - lappend findedVars $item - # puts $item - } - } - } - procedure { - foreach i [lsearch -nocase -all $procList $word*] { - # puts [lindex $varList $i] - set item [lindex [lindex $procList $i] 0] - # puts $item - if {[lsearch $findedVars $item] eq "-1"} { - lappend findedVars $item - # puts $item - } - } - } - default { - foreach i [lsearch -nocase -all $varList $word*] { - # puts [lindex $varList $i] - set item [lindex [lindex $varList $i] 0] - # puts $item - if {[lsearch $findedVars $item] eq "-1"} { - lappend findedVars $item - # puts $item - } - } - foreach i [lsearch -nocase -all $procList $word*] { - # puts [lindex $varList $i] - set item [lindex [lindex $procList $i] 0] - # puts $item - if {[lsearch $findedVars $item] eq "-1"} { - lappend findedVars $item - # puts $item - } - } - } - } - # unset item - # bindtags $txt [list VarHelperBind [winfo toplevel $txt] $txt Ctext sysAfter all] - # bindtags $txt.t [list VarHelperBind [winfo parent $txt.t] $txt.t Text sysAfter all] - # bind VarHelperBind "Editor::VarHelperEscape $txt.t; break" - # # bindtags $txt.t {[list [winfo parent $txt.t] $txt.t Text sysAfter all]}; - # # bindtags $txt {[list [winfo toplevel $txt] $txt Ctext sysAfter all]}; - # # catch { destroy .varhelper }" - # bind VarHelperBind {Editor::VarHelperKey %W %K %A; break} - # - if {$findedVars eq ""} { + proc ReleaseKey {k txt fileType} { + global cfgVariables lexers returnProcessed + # Если Return ΡƒΠΆΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ Π² SelectFromList, пропускаСм + # puts "$returnProcessed $k" + if {$k eq "Return" && [info exists returnProcessed]} { + unset returnProcessed return } - # puts $findedVars - VarHelperDialog $x $y $w $word $findedVars - - } - - proc VarHelperDialog {x y w word findedVars} { - global editors lexers variables - variable txt - variable win - # puts ">>>>>>>>>>>>>$x $y $w $word $findedVars" - # set txt $w.frmText.t - # Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° открытия Π΄ΠΈΠ°Π»ΠΎΠ³Π° Ссли Π·Π°ΠΏΡƒΡ‰Π΅Π½ Π΄Ρ€ΡƒΠ³ΠΎΠΉ - # if [winfo exists .findVariables] { - # return - # } - # if { [winfo exists $win] } { destroy $win } - set txt $w - set win .varhelper - # if {$findedVars eq ""} { - # return - # } - toplevel $win - wm transient $win . - wm overrideredirect $win 1 - - listbox $win.lBox -width 30 -border 0 - pack $win.lBox -expand true -fill y -side left - - foreach { item } $findedVars { - $win.lBox insert end $item - } - - catch { $win.lBox activate 0 ; $win.lBox selection set 0 0 } - - if { [set height [llength $findedVars]] > 10 } { set height 10 } - $win.lBox configure -height $height - - # focus $win.lBox - - bind $win { - destroy $Editor::win - focus -force $Editor::txt.t - break - } - bind $win.lBox { - destroy $Editor::win - focus -force $Editor::txt.t - break - } - bind VarHelperBind { - $Editor::txt delete "insert - 1 chars wordstart" "insert wordend - 1 chars" - $Editor::txt insert "insert" [.varhelper.lBox get [.varhelper.lBox curselection]] - # eval [bind VarHelperBind ] - Editor::VarHelperEscape $Editor::txt - break - } - - # ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠΌ расстояниС Π΄ΠΎ края экрана (основного ΠΎΠΊΠ½Π°) ΠΈ Ссли - # ΠΎΠ½ΠΎ мСньшС Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠΊΠ½Π° со списком Ρ‚ΠΎ сдвигаСм Π΅Π³ΠΎ Π²Π²Π΅Ρ€Ρ… - set winGeomY [winfo reqheight $win] - set winGeomX [winfo reqwidth $win] - - set topHeight [winfo height .] - set topWidth [winfo width .] - set topLeftUpperX [winfo x .] - set topLeftUpperY [winfo y .] - set topRightLowerX [expr $topLeftUpperX + $topWidth] - set topRightLowerY [expr $topLeftUpperY + $topHeight] - - if {[expr [expr $x + $winGeomX] > $topRightLowerX]} { - set x [expr $x - $winGeomX] - } - if {[expr [expr $y + $winGeomY] > $topRightLowerY]} { - set y [expr $y - $winGeomY] - } - - wm geom $win +$x+$y - } - - proc ReleaseKey {k txt fileType} { - global cfgVariables lexers + # set pos [$txt index insert] set lineNum [lindex [split $pos "."] 0] set posNum [lindex [split $pos "."] 1] @@ -636,8 +425,53 @@ namespace eval Editor { unset lpos $txt tag remove lightSelected 1.0 end - if { [winfo exists .varhelper] } { destroy .varhelper } - # puts $k + # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π²Π²ΠΎΠ΄Π° для ΠΏΠΎΠΊΠ°Π·Π° ΠΎΠΊΠ½Π° с подсказками. + # if { [winfo exists .varhelper] } { destroy .varhelper } + # Π€Π»Π°Π³, Π½ΡƒΠΆΠ½ΠΎ Π»ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ список + set showNewList 1 + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΎΠΊΠ½ΠΎ списка + if {[winfo exists .varhelper]} { + # ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ, какая клавиша ΠΎΡ‚ΠΏΡƒΡ‰Π΅Π½Π° + switch -- $k { + Up - Down { + # Π‘Ρ‚Ρ€Π΅Π»ΠΊΠΈ - ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ списком, ΠΎΠΊΠ½ΠΎ остаСтся + # НЕ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ список + set showNewList 0 + return + } + Return { + # Enter - Π²Ρ‹Π±Π΅Ρ€Π΅Ρ‚ элСмСнт, ΠΎΠΊΠ½ΠΎ закроСтся Π² SelectFromList + # НЕ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ список + set showNewList 0 + return + } + Escape { + # Escape - Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΎΠΊΠ½ΠΎ + destroy .varhelper + set ::Helper::listActive 0 + Helper::VarHelperBindingsRestore $txt + # НЕ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ список + set showNewList 0 + return + } + Control_L - Control_R - Alt_L - Alt_R - Shift_L - Shift_R { + # ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ - ΠΎΠΊΠ½ΠΎ остаСтся + # НЕ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ список + set showNewList 0 + return + } + default { + # Π›ΡŽΠ±Π°Ρ другая клавиша (Π±ΡƒΠΊΠ²Ρ‹, Ρ†ΠΈΡ„Ρ€Ρ‹, ΠΏΡ€ΠΎΠ±Π΅Π», Tab ΠΈ Ρ‚.Π΄.) + # Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠΊΠ½ΠΎ списка, Π½ΠΎ ΠŸΠžΠšΠΠ—Π«Π’ΠΠ•Πœ Π½ΠΎΠ²Ρ‹ΠΉ список + destroy .varhelper + set ::Helper::listActive 0 + Helper::VarHelperBindingsRestore $txt + # showNewList остаСтся = 1 (ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ список) + } + } + } + switch $k { Return { regexp {^(\s*)} [$txt get [expr $lineNum - 1].0 [expr $lineNum - 1].end] -> spaceStart @@ -681,10 +515,68 @@ namespace eval Editor { if {$cfgVariables(variableHelper) eq "true"} { if {[dict exists $lexers $fileType variableSymbol] != 0} { set varSymbol [dict get $lexers $fileType variableSymbol] - set lastSymbol [string last $varSymbol [$txt get $lineNum.0 $pos]] + set lineText [$txt get $lineNum.0 $pos] + # # Π˜Ρ‰Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ рСгулярного выраТСния + # # ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ ΠΈΡ‰Π΅Ρ‚ $ Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΈΠ΄Π΅Ρ‚ имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ И курсор сразу послС ΠΈΠΌΠ΅Π½ΠΈ + # if {[regexp "(\\$)(\[a-zA-Z_:\]\[a-zA-Z0-9_:\]*)\$" $lineText -> symbol varName]} { + # # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹ΠΉ $ - это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π°Ρ‡Π°Π»ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ + # # (Π° Π½Π΅ Ρ‡Π°ΡΡ‚ΡŒ строки ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ символа) + # DebugPuts "Found variable: $symbol$varName" + # + # # Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°: ΠΏΠ΅Ρ€Π΅Π΄ $ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ слэша (экранированиС) + # set posOfVarSymbol [string last $varSymbol $lineText] + # if {$posOfVarSymbol > 0} { + # set charBefore [string index $lineText [expr {$posOfVarSymbol - 1}]] + # if {$charBefore eq "\\"} { + # DebugPuts "Dollar sign is escaped, skipping" + # return + # } + # } + # Helper::VarHelper $box_x $box_y $txt $varName vars + # } + DebugPuts "Line text: '$lineText'" + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π΅ΡΡ‚ΡŒ Π»ΠΈ $ Π² строкС + set lastSymbol [string last $varSymbol $lineText] if {$lastSymbol ne "-1"} { - set word [string trim [$txt get $lineNum.[expr $lastSymbol + 1] $pos]] - Editor::VarHelper $box_x $box_y $txt $word vars + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ экранированиС + if {$lastSymbol > 0} { + set charBefore [string index $lineText [expr {$lastSymbol - 1}]] + if {$charBefore eq "\\"} { + DebugPuts "Dollar sign is escaped, skipping" + return + } + } + # Π‘Π΅Ρ€Π΅ΠΌ тСкст послС $ + set afterDollar [string range $lineText [expr {$lastSymbol + 1}] end] + DebugPuts "Text after $varSymbol: '$afterDollar'" + # Если послС $ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅Ρ‚ (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ Π²Π²Π΅Π»ΠΈ $) - ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ всС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ + if {$afterDollar eq ""} { + DebugPuts "Just typed $varSymbol, showing all variables" + Helper::VarHelper $box_x $box_y $txt "" vars + return + } + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π²Π²Π΅Π΄Π΅Π½ΠΎ послС $ + if {[regexp {^([a-zA-Z_:][a-zA-Z0-9_:]*)?$} $afterDollar -> varName]} { + # Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ 1: regexp с ΠΊΠΎΠ½Ρ†ΠΎΠΌ строки - курсор сразу послС (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ) ΠΈΠΌΠ΅Π½ΠΈ + DebugPuts "Cursor after variable name (or $varSymbol only): '$varName'" + Helper::VarHelper $box_x $box_y $txt $varName vars + } elseif {[regexp {^([a-zA-Z_:][a-zA-Z0-9_:]*)} $afterDollar -> varName]} { + # Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ 2: Π΅ΡΡ‚ΡŒ имя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π½ΠΎ курсор Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ сразу послС + DebugPuts "Found variable name: '$varName'" + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ курсора + set varEndPos [expr {[string length $varName] + 1}] ; # +1 для $ + + if {$varEndPos == [string length $lineText]} { + # ΠšΡƒΡ€ΡΠΎΡ€ сразу послС ΠΈΠΌΠ΅Π½ΠΈ + Helper::VarHelper $box_x $box_y $txt $varName vars + } else { + DebugPuts "Cursor not immediately after variable name, skipping" + } + } else { + # ПослС $ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ нСдопустимоС (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ†ΠΈΡ„Ρ€Π°, скобка ΠΈ Ρ‚.Π΄.) + DebugPuts "Invalid characters after $varSymbol" + } } } else { set ind [$txt search -backwards -regexp {\W} $pos {insert linestart}] @@ -696,8 +588,9 @@ namespace eval Editor { # set ind [$txt search -backwards -regexp {^} $pos {insert linestart}] set word [$txt get {insert linestart} $pos] } + DebugPuts "> Extracted word: '$word'" if {$word ne ""} { - Editor::VarHelper $box_x $box_y $txt $word {} + Helper::VarHelper $box_x $box_y $txt $word {} } } } @@ -713,7 +606,7 @@ namespace eval Editor { set word [$txt get {insert linestart} $pos] } if {$word ne ""} { - Editor::VarHelper $box_x $box_y $txt $word procedure + Helper::VarHelper $box_x $box_y $txt $word procedure } } } @@ -788,7 +681,7 @@ namespace eval Editor { bind $txt "Editor::SelectionPaste $txt" bind $txt "SearchVariable $txt; break" bind $txt "SearchVariable $txt; break" - bind $txt "ImageBase64Encode $txt" + bind $txt "ImageBase64Encode" bind $txt "ImageBase64Encode $txt" bind $txt "Editor::InsertTabular $txt" bind $txt "Editor::DeleteTabular $txt" @@ -801,7 +694,7 @@ namespace eval Editor { bind $txt <> "SetModifiedFlag $w $nb auto" bind $txt "Editor::SearchBrackets %W" bind $txt "Editor::SearchBrackets %W" - bind $txt "catch {Editor::GoToFunction $txt}" + bind $txt "catch {Editor::GoToFunction $txt}; break" bind $txt "catch {Editor::GoToFunction $txt}; break" bind $txt {Redo; break} bind $txt "catch {Editor::GoToFunction $txt}; break" @@ -809,6 +702,7 @@ namespace eval Editor { bind $txt "$txt delete {insert wordstart} {insert wordend}" bind $txt "$txt delete {insert wordstart} {insert wordend}" bind $txt "$txt delete {insert linestart} {insert lineend + 1char}" + bind $txt "$txt delete {insert linestart} {insert lineend + 1char}" bind $txt "$txt delete {insert linestart} {insert lineend + 1char}" bind $txt "$txt delete {insert linestart} {insert lineend + 1char}" bind $txt "$txt delete {insert linestart} insert" @@ -852,6 +746,8 @@ namespace eval Editor { } bind $txt "Editor::SplitEditorForExecute $w $fileType $nb " bind $txt "Editor::SplitEditorForExecute $w $fileType $nb " + # bind $txt FileOper::Close + # bind $txt "FileOper::Close saveas" # bind $txt.t "Editor::ReleaseKey %K $txt.t $fileType" # bind $txt.t "Editor::PressKey %K $txt.t" @@ -981,9 +877,15 @@ namespace eval Editor { for {set lineNumber 0} {$lineNumber <= [$txt count -lines 0.0 end]} {incr lineNumber} { set line [$txt get $lineNumber.0 $lineNumber.end] # Π’Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ (Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, классы ΠΈ Ρ‚.Π΄.) + # DebugPuts "Editor::RedaStructure: file type $fileType" + if {[dict exists $lexers $fileType procRegexpCommand] != 0 } { + # regexp -nocase -all -line -- {^\s*(?:(\w+)\s+)+(\w+)\s*\((.*?)\)\s*(?:;|\{)} $line match returns procName params + # regexp -nocase -all -line -lineanchor -linestop -- {^\s*(?:(\w+)\s+)+(\w+)\s*\((.*?)(,|\))} $line match v1 v2 v3 v4 if {[eval [dict get $lexers $fileType procRegexpCommand]]} { + DebugPuts "Editor::RedaStructure: regexp = [dict get $lexers $fileType procRegexpCommand]" set procName_ [string trim $procName] + DebugPuts "Editor::RedaStructure: find the proc $procName_" if {$treeItemName ne ""} { Tree::InsertItem $tree $treeItemName $procName_ "procedure" "$procName_ ($params)" } diff --git a/lib/files.tcl b/lib/files.tcl index fe4383b..4d301ed 100644 --- a/lib/files.tcl +++ b/lib/files.tcl @@ -364,7 +364,7 @@ namespace eval FileOper { set nbEditorWindow "[lindex $str 0].[lindex $str 1].[lindex $str 2]" # puts "FileOper::Save: current window $nbEditorWindow" } - # puts "FileOper::Save: $nbEditorWindow" + set nbEditorItem [$nbEditorWindow select] DebugPuts "Saved editor text: $nbEditorItem" if [string match "*untitled*" $nbEditorItem] { @@ -382,7 +382,14 @@ namespace eval FileOper { set treeItem "file::[string range $nbEditorItem [expr [string last "." $nbEditorItem] +1] end ]" set filePath [Tree::GetItemID $tree $treeItem] } + if {![winfo exists $nbEditorItem.frmText.t]} { + DebugPuts "winfo exists $nbEditorWindow.frmText.t equal [winfo exists $nbEditorWindow.frmText.t]" + return + } set editedText [$nbEditorItem.frmText.t get 0.0 end] + if {$type eq "saveas"} {set filePath [FileOper::SaveDialog]} + if {$filePath eq "cancel"} {return} + DebugPuts "FileOper::Save $filePath" set f [open $filePath "w+"] puts -nonewline $f $editedText # puts "$f was saved" @@ -391,7 +398,13 @@ namespace eval FileOper { if {[file tail $filePath] eq "projman.ini"} { Config::read $dir(cfg) } - if [string match "*untitled*" $nbEditorItem] { + if {[file tail $filePath] eq "tools.ini"} { + Tools::Read $dir(cfg) + Tools::CheckVariables + Tools::GetMenu .popup.tools + Tools::GetMenu .frmMenu.mnuTools.m + } + if {[string match "*untitled*" $nbEditorItem] || $type eq "saveas"} { FileOper::Close if {$type ne "close"} { FileOper::Edit $filePath @@ -621,5 +634,29 @@ namespace eval FileOper { # set selEnd [lindex [$txt tag ranges sel] 1] # puts [$txt get [$txt tag ranges sel]] # } - + + proc SaveDialog {} { + global env project activeProject + if [info exists activeProject] { + set dir $activeProject + } else { + set dir $env(HOME) + } + set fileName [tk_getSaveFile -initialdir $dir -filetypes $::types -parent .] + if {$fileName eq ""} {return "cancel"} + set fullPath [file join $dir $fileName] + set file [string range $fullPath [expr [string last "/" $fullPath]+1] end] + DebugPuts "FileOper::SaveDialog $fileName $fullPath" + regsub -all "." $file "_" node + set dir [file dirname $fullPath] + set file [file tail $fullPath] + set name [file rootname $file] + set ext [string range [file extension $file] 1 end] + if {$fullPath != ""} { + # puts $fullPath + return $fullPath + } else { + return + } + } } diff --git a/lib/gui.tcl b/lib/gui.tcl index 3f26659..6e0351e 100644 --- a/lib/gui.tcl +++ b/lib/gui.tcl @@ -135,7 +135,11 @@ GetEditMenu [menu .frmMenu.mnuEdit.m] ttk::menubutton .frmMenu.mnuView -text [::msgcat::mc "View"] -menu .frmMenu.mnuView.m GetViewMenu [menu .frmMenu.mnuView.m] -pack .frmMenu.mnuFile .frmMenu.mnuEdit .frmMenu.mnuView -side left +ttk::menubutton .frmMenu.mnuTools -text [::msgcat::mc "Tools"] -menu .frmMenu.mnuTools.m +Tools::GetMenu [menu .frmMenu.mnuTools.m] + + +pack .frmMenu.mnuFile .frmMenu.mnuEdit .frmMenu.mnuView .frmMenu.mnuTools -side left ttk::menubutton .frmMenu.mnuHelp -text [::msgcat::mc "Help"] -menu .frmMenu.mnuHelp.m GetHelpMenu [menu .frmMenu.mnuHelp.m] @@ -151,6 +155,9 @@ GetFileMenu .popup.file menu .popup.view .popup add cascade -label [::msgcat::mc "View"] -menu .popup.view GetViewMenu .popup.view +menu .popup.tools +.popup add cascade -label [::msgcat::mc "Tools"] -menu .popup.tools +Tools::GetMenu .popup.tools set frmTool [ttk::frame .frmBody.frmTool] ttk::panedwindow .frmBody.panel -orient horizontal -style TPanedwindow @@ -230,7 +237,7 @@ ttk::style layout TNotebook.Tab { } bind TNotebook "catch {NB::PressTab %W %x %y}\;[bind TNotebook ];break" # bind <> "NB::PressTab %W %x %y" -bind TNotebook "NB::PressTab %W %x %y" +# bind TNotebook "NB::PressTab %W %x %y" # bind TNotebook FileOper::Close # bind . "NB::NextTab $nbEditor" bind . "NB::NextTab $nbEditor 1" diff --git a/lib/helper.tcl b/lib/helper.tcl new file mode 100644 index 0000000..64346f8 --- /dev/null +++ b/lib/helper.tcl @@ -0,0 +1,339 @@ +namespace eval Helper { + variable ::originalBindings {} + # Π€Π»Π°Π³, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ, Ρ‡Ρ‚ΠΎ ΠΎΠΊΠ½ΠΎ со списком Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ + variable ::listActive 0 + # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ для отслСТивания ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Π²Π²ΠΎΠ΄Π° (Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ список Π±Π΅Π· нСобходимости) + variable ::previousInput "" + + proc VarHelperKey { widget K A } { + set win .varhelper + DebugPuts "Helper::VarHelperKey: K=$K, A='$A'" + + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, сущСствуСт Π»ΠΈ ΠΎΠΊΠ½ΠΎ списка + if {![winfo exists $win]} { + DebugPuts "Window doesn't exist, restoring bindings" + Helper::VarHelperBindingsRestore $widget + set ::listActive 0 + return + } + + switch -- $K { + { + DebugPuts "Processing Up arrow" + # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π²Ρ‹Π±ΠΎΡ€ Π²Π²Π΅Ρ€Ρ… + set current [$win.lBox curselection] + DebugPuts "Current selection: $current" + + if {$current ne "" && $current > 0} { + $win.lBox selection clear 0 end + $win.lBox selection set [expr {$current - 1}] + $win.lBox activate [expr {$current - 1}] + $win.lBox see [expr {$current - 1}] + } elseif {[$win.lBox size] > 0} { + # Если Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π²Ρ‹Π±Ρ€Π°Π½ΠΎ, Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ послСдний элСмСнт + set last [expr {[$win.lBox size] - 1}] + $win.lBox selection clear 0 end + $win.lBox selection set $last + $win.lBox activate $last + $win.lBox see $last + } + return -code break + } + { + DebugPuts "Processing Down arrow" + # ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π²Ρ‹Π±ΠΎΡ€ Π²Π½ΠΈΠ· + set current [$win.lBox curselection] + set size [$win.lBox size] + DebugPuts "Current selection: $current, size: $size" + + if {$current ne "" && $current < $size - 1} { + $win.lBox selection clear 0 end + $win.lBox selection set [expr {$current + 1}] + $win.lBox activate [expr {$current + 1}] + $win.lBox see [expr {$current + 1}] + } elseif {$size > 0} { + # Если Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π²Ρ‹Π±Ρ€Π°Π½ΠΎ, Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт + $win.lBox selection clear 0 end + $win.lBox selection set 0 + $win.lBox activate 0 + $win.lBox see 0 + } + return -code break + } + { + DebugPuts "Processing Return" + Helper::SelectFromList $widget + return -code break + } + { + DebugPuts "Processing Escape" + # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΠΊΠ½ΠΎ списка + wm withdraw $win + set ::listActive 0 + Helper::VarHelperBindingsRestore $widget + set ::previousInput "" + focus $widget + return -code break + } + default { + DebugPuts "Default case for K=$K, A='$A'" + # Для ΠΏΠ΅Ρ‡Π°Ρ‚Π½Ρ‹Ρ… символов + if {$A ne ""} { + DebugPuts "Inserting character '$A' and restoring bindings" + # ВосстанавливаСм привязки ΠΏΠ΅Ρ€Π΅Π΄ вставкой + Helper::VarHelperBindingsRestore $widget + # ВставляСм символ + $widget insert "insert" $A + } + return -code break + } + } + } + + proc VarHelper {x y w word wordType} { + global editors lexers variables + variable txt + variable win + + DebugPuts "=== VarHelper called: word='$word', wordType='$wordType' ===" + + set txt $w + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Ссли Π΅ΡΡ‚ΡŒ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ появлСниС Π΄ΠΈΠ°Π»ΠΎΠ³Π° + if {[$txt tag ranges sel] != ""} { + DebugPuts "You have selected text [$txt tag ranges sel]" + return + } + + set fileType [dict get $editors $txt fileType] + + if {[dict exists $editors $txt variableList] != 0} { + set varList [dict get $editors $txt variableList] + } else { + set varList {} + } + if {[dict exists $editors $txt procedureList] != 0} { + set procList [dict get $editors $txt procedureList] + } else { + set procList {} + } + + if {[dict exists $lexers $fileType commands] != 0} { + foreach i [dict get $lexers $fileType commands] { + lappend procList $i + } + } + + set findedVars "" + switch -- $wordType { + vars { + foreach i [lsearch -nocase -all $varList $word*] { + set item [lindex [lindex $varList $i] 0] + if {[lsearch $findedVars $item] eq "-1"} { + lappend findedVars $item + } + } + } + procedure { + foreach i [lsearch -nocase -all $procList $word*] { + set item [lindex [lindex $procList $i] 0] + if {[lsearch $findedVars $item] eq "-1"} { + lappend findedVars $item + } + } + } + default { + foreach i [lsearch -nocase -all $varList $word*] { + set item [lindex [lindex $varList $i] 0] + if {[lsearch $findedVars $item] eq "-1"} { + lappend findedVars $item + } + } + foreach i [lsearch -nocase -all $procList $word*] { + set item [lindex [lindex $procList $i] 0] + if {[lsearch $findedVars $item] eq "-1"} { + lappend findedVars $item + } + } + } + } + + DebugPuts "Found [llength $findedVars] items: $findedVars" + + if {$findedVars eq ""} { + DebugPuts "No items found, returning" + return + } + + VarHelperDialog $x $y $w $word $findedVars + } + + proc VarHelperDialog {x y w word findedVars} { + variable txt + variable win + + set txt $w + set win .varhelper + + DebugPuts "VarHelperDialog called with [llength $findedVars] items" + + # Если ΠΎΠΊΠ½ΠΎ ΡƒΠΆΠ΅ сущСствуСт, ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ + if {[winfo exists $win]} { + DebugPuts "Window already exists, destroying it" + destroy $win + Helper::VarHelperBindingsRestore $txt + } + + toplevel $win + wm transient $win . + wm overrideredirect $win 1 + + listbox $win.lBox -width 30 -border 0 + pack $win.lBox -expand true -fill y -side left + + foreach item $findedVars { + $win.lBox insert end $item + } + + DebugPuts "Listbox created with [llength $findedVars] items" + + # Π’Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт + if {[llength $findedVars] > 0} { + $win.lBox selection set 0 + $win.lBox activate 0 + } + + if {[set height [llength $findedVars]] > 10} { + set height 10 + } + $win.lBox configure -height $height + + Helper::VarHelperBindingsSetup $w + + # ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠ° для закрытия ΠΎΠΊΠ½Π° списка + bind $win [list apply {{win txt} { + set ::listActive 0 + Helper::VarHelperBindingsRestore $txt + set ::previousInput "" + }} $win $txt.t] + + # ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ расстояниС Π΄ΠΎ края экрана (основного ΠΎΠΊΠ½Π°) ΠΈ Ссли + # ΠΎΠ½ΠΎ мСньшС Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠΊΠ½Π° со списком Ρ‚ΠΎ сдвигаСм Π΅Π³ΠΎ Π²Π²Π΅Ρ€Ρ… + set winGeomY [winfo reqheight $win] + set winGeomX [winfo reqwidth $win] + + set topHeight [winfo height .] + set topWidth [winfo width .] + set topLeftUpperX [winfo x .] + set topLeftUpperY [winfo y .] + set topRightLowerX [expr $topLeftUpperX + $topWidth] + set topRightLowerY [expr $topLeftUpperY + $topHeight] + + if {[expr $x + $winGeomX] > $topRightLowerX} { + set x [expr $x - $winGeomX] + } + if {[expr $y + $winGeomY] > $topRightLowerY} { + set y [expr $y - $winGeomY] + } + set ::listActive 1 + DebugPuts "Showing window at +$x+$y" + wm geom $win +$x+$y + } + + proc VarHelperBindingsSetup {txt} { + DebugPuts "Setting up bindings for $txt" + + # БбрасываСм сохранСнныС привязки + set ::originalBindings {} + + # Бписок событий для ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Π° + set events { } + + # БохраняСм ΠΈ замСняСм привязки + foreach event $events { + # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ привязку + set original [bind $txt $event] + DebugPuts " Saving binding for $event: '$original'" + + # БохраняСм ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» + lappend ::originalBindings [list $event $original] + + # УстанавливаСм Π½ΠΎΠ²ΡƒΡŽ привязку + bind $txt $event [list Helper::VarHelperKey $txt $event %A] + } + } + + # ВосстановлСниС ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… привязок + proc VarHelperBindingsRestore {txt} { + DebugPuts "Restoring bindings for $txt" + DebugPuts "Have [llength $::originalBindings] bindings to restore" + + if {![info exists ::originalBindings]} { + DebugPuts " No original bindings stored" + # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ наши привязки + foreach event { } { + bind $txt $event {} + } + return + } + + # ВосстанавливаСм ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ привязки + foreach binding $::originalBindings { + set event [lindex $binding 0] + set command [lindex $binding 1] + DebugPuts " Restoring $event: '$command'" + + if {$command eq ""} { + bind $txt $event {} + } else { + bind $txt $event $command + } + } + + # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ сохранСнныС привязки + set ::originalBindings {} + } + + proc SelectFromList {txt} { + global returnProcessed editors lexers + set win .varhelper + # puts "[dict get $editors $txt fileType]" + # puts "[dict get $lexers [dict get $editors $txt fileType] variableSymbol]" + + if {![winfo exists $win]} { + return + } + set selected [$win.lBox curselection] + if {$selected ne ""} { + set text [string trim [$win.lBox get $selected]] + # DebugPuts "[dict exists $lexers [dict get $editors $txt fileType] variableSymbol]" + if [dict exists $lexers [dict get $editors $txt fileType] variableSymbol] { + set varSymbol [dict get $lexers [dict get $editors $txt fileType] variableSymbol] + } else { + set varSymbol "" + } + # ΠžΠΏΠ΅Ρ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ Ρ‡Ρ‚ΠΎ символ ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ вставки Ρ€Π°Π²Π΅Π½ символу ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ· настроСк lexers + # Ссли Ρ€Π°Π²Π΅Π½ Ρ‚ΠΎ вставляСм Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ΅ ΠΈΠ· списка сразу Π·Π° Π½ΠΈΠΌ + # Ссли Π½Π΅Ρ‚ Ρ‚ΠΎ удаляСм Π²Π²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ тСкст Π΄ΠΎ этого символа ΠΈ вставляСм Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ΅ ΠΈΠ· списка + if {[$txt get "insert - 1 char" "insert"] eq $varSymbol} { + $txt insert "insert" $text + } else { + $txt delete "insert - 1 chars wordstart" "insert wordend - 1 chars" + $txt insert "insert" $text + } + # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΠΊΠ½ΠΎ + destroy $win + set ::listActive 0 + Helper::VarHelperBindingsRestore $txt + set ::previousInput "" + + # УстанавливаСм Ρ„Π»Π°Π³, Ρ‡Ρ‚ΠΎ Return ΡƒΠΆΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ + set returnProcessed 1 + # after 10 {catch {unset returnProcessed}} + + focus $txt.t + } + } + proc DebugPuts {msg} { + puts "DEBUG: $msg" + } +} diff --git a/lib/highlight.tcl b/lib/highlight.tcl index 1f146de..0dc2a05 100644 --- a/lib/highlight.tcl +++ b/lib/highlight.tcl @@ -210,5 +210,24 @@ namespace eval Highlight {} { ctext::addHighlightClass $txt compile_errors #ff5050 {error Error ERROR invalid undefined cannot} ctext::addHighlightClassForRegexp $txt url lightblue {\w+://\w.+\w+} } - + proc C {txt} { + global lexers + ctext::addHighlightClassForRegexp $txt flags orange {-+[a-zA-Z\-_]+} + ctext::addHighlightClassForRegexp $txt arrows orange {(->)|(-<)} + ctext::addHighlightClass $txt stackControl #19a2a6 [dict get $lexers C commands] + ctext::addHighlightClass $txt types #7187d5 {string int int16 int32 int64 float bool byte size_t void char uint32_t uint32} + ctext::addHighlightClassWithOnlyCharStart $txt vars #4471ca "\&" + ctext::addHighlightClassWithOnlyCharStart $txt vars #4471ca "\*" + # ctext::addHighlightClassForRegexp $txt vars_extended #4471ca {\$\{[a-zA-Z0-9\_\-:\./\$\{\}]+\}} + ctext::addHighlightClass $txt variable_funcs gold {var type struct} + ctext::addHighlightClassForSpecialChars $txt brackets green {[]{}()} + ctext::addHighlightClassForRegexp $txt paths lightblue {\.[a-zA-Z0-9\_\-]+} + ctext::addHighlightClassForRegexp $txt comments #666666 {(//|/\*)[^\n\r]*} + ctext::addHighlightClassForSpecialChars $txt qoute #b84a0c {"'`} + ctext::addHighlightClass $txt bool #3e803b {nil false true NULL TRUE FALSE} + ctext::addHighlightClassForRegexp $txt qoute #b84a0c {("|'|`).*?("|'|`)} + ctext::addHighlightClassForRegexp $txt macros #f88ffb {#\w+} + ctext::addHighlightClassForRegexp $txt include #68ceff {<[\w./_-]+?>} + } + proc H {txt} {Highlight::C $txt} } diff --git a/lib/image_library.tcl b/lib/image_library.tcl index fd4f186..bd3ac6d 100644 --- a/lib/image_library.tcl +++ b/lib/image_library.tcl @@ -1947,3 +1947,24 @@ image create photo settings_24x24 -data { 3W5MPksIPgdckHTF1XAMeCrpRXAexPT6yYSddEj6eKSJJmk3IcFGqWby51AbSvpeqr+KPjcKC7GT hfgXbteIc85F7RUAAAAASUVORK5CYII= } +image create photo c_16x12 -data { + iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAAXNSR0IB2cksfwAAAARnQU1BAACx + jwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dE + APgAjwD7QQHXygAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+oCBg8YOxzsqLgAAABWSURB + VCjPY2AgATDCGFeLi/+jS2r39jJiKIYp1O7tZUDSjKGBCYdtyCbCbWTB5T6oiShOYyHWT7icgRPg + VHy1uPg/eggRY/J/YsMZRR0jLlNweZI2AAAzbhnP2WkKCAAAAABJRU5ErkJggg== +} +image create photo h_16x12 -data { + iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAAXNSR0IB2cksfwAAAARnQU1BAACx + jwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dE + AAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+oCBg8iNd79W8YAAABJSURB + VCjPY2AgB1wtLv5/tbj4Pz41TKQYSJJiRmRnYFOg3dvLSLTJyIawYDEJWSGM+Z+BgYGRCY/zGOkX + GkwMFID/UExIjDAAAEu2FECKwea9AAAAAElFTkSuQmCC +} +image create photo cpp_16x12 -data { + iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAMAAABIK2QJAAAAAXNSR0IB2cksfwAAAARnQU1BAACx + jwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAA9QTFRF + AAAAzAAAAAAA////////6rs+vwAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsT + AAALEwEAmpwYAAAAB3RJTUUH6gIGDxU21/OqSAAAADVJREFUCNd9jUEOACAIw7D7/58VmNF4sAco + CbCIm5FsBTwsd+kmgVQu87p3OLfg/9AJJPFhAjDkAJmwKBolAAAAAElFTkSuQmCC +} diff --git a/lib/imgviewer.tcl b/lib/imgviewer.tcl index 436cf66..6c143c1 100644 --- a/lib/imgviewer.tcl +++ b/lib/imgviewer.tcl @@ -19,7 +19,7 @@ proc ImageViewer {f w node} { #$w.scrwin setwidget $w.scrwin.f openImg $f $w.f.c $node } - + proc openImg {fn w node} { global im1 factor set im1 [image create photo -file $fn] diff --git a/lib/lexers.tcl b/lib/lexers.tcl index 6c58248..6342fca 100644 --- a/lib/lexers.tcl +++ b/lib/lexers.tcl @@ -104,5 +104,28 @@ dict set lexers LUA procFindString {function\s*?PROCNAME} dict set lexers LUA procRegexpCommand {regexp -nocase -all -- {^(local|)\s*?(function)\s([a-zA-Z0-9\-_:]+?)\s+\((.+?)\)} $line match v1 keyWord procName params} dict set lexers LUA varRegexpCommand {regexp -nocase -all -- {^(\s*?)([a-zA-Z0-9\-_\.]+)\s+=\s+(.+?)(\s*$|--)} $line match indent varName varValue lineEnd} +#-------------------------------------------------- +# C +dict set lexers C commentSymbol {//} +dict set lexers C commentMultilineSymbolBegin {/*} +dict set lexers C commentMultilineSymbolEnd {*/} +dict set lexers C procFindString {(\w+)\s+(PROCNAME)\s*\((.*?)(,|\))(\W|$)} +dict set lexers C procRegexpCommand {regexp -nocase -all -line -- {^(?:(\w+)\s+)+(\*\w+|\w+)\s*\((.*?)(,|\))} $line match returns procName params v4} +# dict set lexers C procRegexpCommand {regexp -nocase -all -- {\s*?func\s*?(\(\w+\s*?\**?\w+\)|)\s*?(\w+)\((.*?)\)\s+?([a-zA-Z0-9\{\}\[\]\(\)-_.]*?|)\s*?\{} $line match linkName procName params returns} +# dict set lexers C varRegexpCommand {regexp -nocase -all -line -- {^\s*?var\s+([a-zA-Z0-9\-_$]+)\s+(.+?)(\s*$)} $line match varName varType lineEnd} +dict set lexers C commands {auto break case const continue default do else enum extern for goto if inline int long register restrict return signed sizeof static struct switch typedef typeof typeof_unqual union unsigned void volatile while} + +#-------------------------------------------------- +# H +dict set lexers H commentSymbol {//} +dict set lexers H commentMultilineSymbolBegin {/*} +dict set lexers H commentMultilineSymbolEnd {*/} +# dict set lexers C procFindString {^\s*(?:(\w+)\s+)+(PROCNAME)\s*\((.*?)(,|\))} +dict set lexers H procFindString {^\s*(?:(\w+)\s+)+(PROCNAME)\s*\((.*?)(,|\))} +dict set lexers H procRegexpCommand {regexp -nocase -all -line -- {^(?:(\w+)\s+)+(\*\w+|\w+)\s*\((.*?)(,|\))} $line match returns procName params v4} +# dict set lexers C procRegexpCommand {regexp -nocase -all -- {\s*?func\s*?(\(\w+\s*?\**?\w+\)|)\s*?(\w+)\((.*?)\)\s+?([a-zA-Z0-9\{\}\[\]\(\)-_.]*?|)\s*?\{} $line match linkName procName params returns} +# dict set lexers C varRegexpCommand {regexp -nocase -all -line -- {^\s*?var\s+([a-zA-Z0-9\-_$]+)\s+(.+?)(\s*$)} $line match varName varType lineEnd} +dict set lexers H commands {auto break case const continue default do else enum extern for goto if inline int long register restrict return signed sizeof static struct switch typedef typeof typeof_unqual union unsigned void volatile while} + # ------------------------------------------------- dict set lexers ALL varDirectory {variables vars group_vars host_vars defaults} diff --git a/lib/menu.tcl b/lib/menu.tcl index 92643ea..4526087 100644 --- a/lib/menu.tcl +++ b/lib/menu.tcl @@ -20,6 +20,7 @@ proc GetFileMenu {m} { } $m add command -label [::msgcat::mc "Save file"] -command {FileOper::Save}\ -accelerator "Ctrl+S" + $m add command -label [::msgcat::mc "Save as"] -command {FileOper::Save saveas} $m add command -label [::msgcat::mc "Close file"] -command {FileOper::Close}\ -accelerator "Ctrl+w" $m add command -label [::msgcat::mc "Close all"] -command {FileOper::CloseAll} diff --git a/lib/msgs/en.msg b/lib/msgs/en.msg index 1840432..72cadfe 100644 --- a/lib/msgs/en.msg +++ b/lib/msgs/en.msg @@ -174,6 +174,7 @@ ::msgcat::mcset en "Title normal" ::msgcat::mcset en "Title modify" ::msgcat::mcset en "Toolbar" +::msgcat::mcset en "Tools" ::msgcat::mcset en "Undo" ::msgcat::mcset en "Update" ::msgcat::mcset en "Variables" @@ -185,4 +186,3 @@ ::msgcat::mcset en "Work dir" - diff --git a/lib/msgs/ru.msg b/lib/msgs/ru.msg index bff7471..0991f34 100644 --- a/lib/msgs/ru.msg +++ b/lib/msgs/ru.msg @@ -214,6 +214,7 @@ ::msgcat::mcset ru "Title normal" "Π€Π°ΠΉΠ» Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ" ::msgcat::mcset ru "Title modify" "Π€Π°ΠΉΠ» ΠΈΠ·ΠΌΠ΅Π½Π΅Π½" ::msgcat::mcset ru "Toolbar" "ПанСль инструмСнтов" +::msgcat::mcset ru "Tools" "Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹" ::msgcat::mcset ru "User name" "Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ" ::msgcat::mcset ru "Undo" "ΠžΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ" ::msgcat::mcset ru "Update" "ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ" diff --git a/lib/notebook.tcl b/lib/notebook.tcl index 91cd555..5157520 100644 --- a/lib/notebook.tcl +++ b/lib/notebook.tcl @@ -13,6 +13,7 @@ namespace eval NB { proc InsertItem {nb item type} { switch $type { file { + set titleFileName [file tail $item] set item [string tolower $item] regsub -all {\.|/|\\|\s|:} $item "_" itemName # puts "$item -> $itemName" @@ -21,7 +22,7 @@ namespace eval NB { } else { set fm [ttk::frame $nb.$itemName] pack $fm -side top -expand true -fill both - $nb add $fm -text [file tail $item];# -image close_12x12 -compound right + $nb add $fm -text $titleFileName;# -image close_12x12 -compound right $nb select $fm } } @@ -32,7 +33,7 @@ namespace eval NB { set fm [ttk::frame $nb.$item] pack $fm -side top -expand true -fill both $nb add $fm -text Git;# -image close_12x12 -compound right - $nb select $fm + $nb select $fm } } # puts "NB item - $fm" diff --git a/lib/tools.tcl b/lib/tools.tcl new file mode 100644 index 0000000..0051bff --- /dev/null +++ b/lib/tools.tcl @@ -0,0 +1,220 @@ +################################################################## +# tools.tcl - this file implements the logic of working +# with external tools. +################################################################## +# svk, 01/2026 +################################################################## + +namespace eval Tools {} { + variable toolsINISections + variable toolsVariables +} + +set ::toolsDefault "\[VisualRegexp\] +commandString=tkregexp \"%s\" +description=A graphical front-end to write/debug regular expression +icon= +shortCut= +\[TkDIFF\] +commandString=tkdiff %f %f +description=TkDiff is a Tcl/Tk front-end to diff +icon= +shortCut= +" +# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° настроСк Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов +proc Tools::Create {dir} { + set toolsFile [open [file join $dir tools.ini] "w+"] + puts $toolsFile $::toolsDefault + close $toolsFile +} + +proc Tools::Read {dir} { + set ::toolsVariables "" + set toolsFile [ini::open [file join $dir tools.ini] "r"] + foreach section [ini::sections $toolsFile] { + foreach key [ini::keys $toolsFile $section] { + lappend ::toolsINIsections($section) $key + dict set ::toolsVariables $section $key [ini::value $toolsFile $section $key] + DebugPuts "Tools::Read: $toolsFile $section $key = [ini::value $toolsFile $section $key]" + } + } + ini::close $toolsFile +} + +proc Tools::Write {dir} { + set toolsFile [ini::open [file join $dir tools.ini] "w"] + foreach section [array names ::toolsINIsections] { + dict for {key value} [dict get $::toolsVariables $section] { + DebugPuts "Tools::write: $section $key = $value" + # ini::set $toolsFile $section $key [dict get $::toolsVariables $section $key] + ini::set $toolsFile $section $key $value + } + } + ini::commit $toolsFile + ini::close $toolsFile +} + +# Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€ΠΌΠ΅Π½Π½ΠΎΠΉ Π² список +# Ссли отсутствуСт нуТная сСкция Ρ‚ΠΎ ΠΎΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π°. +proc Tools::AddVariable {key value section} { + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, сущСствуСт Π»ΠΈ ΡƒΠΆΠ΅ такая пСрСмСнная + if {[info exists ::toolsVariables($key)]} { + DebugPuts "The variable '$key' already exists: " + return 0 + } + # ДобавляСм Π² массив ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… + # set ::toolsVariables($key) $value + dict set ::toolsVariables $section $key $value + # ДобавляСм Π² список ΠΊΠ»ΡŽΡ‡Π΅ΠΉ сСкции + if {[dict exists $::toolsVariables $key]} { + # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π½Π΅Ρ‚ Π»ΠΈ ΡƒΠΆΠ΅ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° Π² сСкции + if {[lsearch -exact $::toolsINIsections($section) $key] == -1} { + lappend ::toolsINIsections($section) $key + } + } else { + set ::toolsINIsections($section) [list $key] + } + DebugPuts "Tools::AddVariable: The variable '$key' has been added to the '$section' array 'toolsVariables' with value '$value'" + + return 1 +} + +# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π² tools.ini Π½Π° основС "эталонного" списка +# ΠΈ выставляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ссли Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π½Π΅Ρ‚ +proc Tools::CheckVariables {} { + set valList [split $::toolsDefault "\n"] + foreach item $valList { + if {[regexp -nocase -all -- {\[(\w+)\]} $item -> v1]} { + set section $v1 + } + if {[regexp {^([^=]+)=(.*)$} $item -> key value]} { + # puts "$section $key $value >> [dict get $::toolsVariables $section $key]" + # if {[dict get $::toolsVariables $section $key] eq ""} + if ![dict exists $::toolsVariables $section $key] { + DebugPuts "Error in Tools::CheckVariables: variable $section $key not found" + Tools::AddVariable "$key" "$value" "$section" + # DebugPuts "Tools::CheckVariables: The variable toolsVariables $key setting to default value \"$value\"" + } + } + } + foreach id [dict keys $::toolsVariables] { + DebugPuts "Tools::CheckVariables: config parameters for $id [dict get $::toolsVariables $id]!" + } + # DebugPuts "toolsVariables dict keys: [dict keys $::toolsVariables]" +} + +proc Tools::GetMenu {m} { + global cfgVariables toolsVariables + set count [$m index end] + if {$count != "none"} { + for {set i $count} {$i >= 0} {incr i -1} { + $m delete $i + } + } + foreach toolName [dict keys $toolsVariables] { + dict for {key value} [dict get $toolsVariables $toolName] { + DebugPuts "GetToolsMenu $key $value" + if {$key eq "commandString"} { + set cmd "$value" + } + if {$key eq "shortCut"} { + set shortCut "$value" + } + } + if {[info exists cmd] == 1 && $cmd ne ""} { + if {[info exists shortCut] == 1 && $shortCut ne ""} { + $m add command -label $toolName -accelerator $shortCut -command [list Tools::Execute "$toolName"] + bind . <$shortCut> "[list Tools::Execute "$toolName"]; break" + } else { + $m add command -label $toolName -command [list Tools::Execute "$toolName"] + } + } + } + $m add separator + $m add command -label "[::msgcat::mc "Settings"]" -command Tools::Settings +} + +proc Tools::CommandPathSettings {command} { + global tcl_platform + if [file exists $command] {return $command} + + if {$tcl_platform(platform) eq "windows"} { + set cmd "where $command)" + } else { + set cmd "which $command" + } + DebugPuts [catch {exec {*}$cmd} toolsPath] + DebugPuts "executor_path $toolsPath" + if {[catch {exec {*}$cmd} toolsPath]} { + DebugPuts "Tools::CommandPathSettings: ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° $command Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° Π² систСмС" + return "" + } + set fullPath [string trim $toolsPath] + set firstPath [lindex [split $toolsPath "\n"] 0] + + DebugPuts "Tools::CommandPathSettings: executable path $fullPath" + return $fullPath +} + +proc Tools::Execute {toolName} { + global cfgVariables toolsVariables tree + if ![dict exists $::toolsVariables $toolName commandString] { + DebugPuts "Tools::Execute: command for $toolName not found" + return + } else { + set command [dict get $::toolsVariables $toolName commandString] + DebugPuts "Tools::Execute: command for $toolName as $command" + } + # 7. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π½Π° Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ Π² систСмС ΠΈ ΠΏΠΎΠ΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ + # Ссли Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³Π΅ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ. + # ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π²Π½Π΅ΡˆΠ³Π½ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π² систСмС + set cmd [lindex [split $command " "] 0] + if [file exists $cmd] { + set fullCommand $command + } else { + set fullPathToExec [Tools::CommandPathSettings "$cmd"] + set fullCommand [lreplace [split $command " "] 0 0 $fullPathToExec] + } + if {$fullPathToExec eq ""} { + DebugPuts "Tools::Execute: $command not found" + return + } else { + DebugPuts "Tools::Execute: $fullPathToExec, $fullCommand" + } + # 2. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Π²Ρ‹Π΄Π΅Π»Π΅Π½ Π»ΠΈ тСкст Π² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ + # 5. ЗамСняСм %s Π½Π° Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ тСкст + set selectedText [Editor::SelectionGet] + if {$selectedText ne ""} { + regsub -all "%s" $fullCommand "$selectedText" fullCommand + DebugPuts "Tools::Execute: selected text \"$selectedText\", command \"$fullCommand\"" + } + + # 1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ„Π°ΠΉΠ» + # 3. ΠžΠΏΠ΅Ρ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ сколько Ρ„Π°ΠΉΠ»ΠΎΠ² Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΎ Π² Π΄Π΅Ρ€Π΅Π²Π΅ + # 4. ЗамСняСм Π·Π½Π°ΠΊ %f Π½Π° имя Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Ρ„Π°ΠΉΠ»Π° (Ρ„Π°ΠΉΠ»ΠΎΠ²) + # regsub -all "%f" $command "$filePath" fullCommand + set filesList [Tree::GetSelectedItemValues $tree] + if {$filesList ne ""} { + foreach file $filesList { + # Если большС Π½Π΅Ρ‚ %f для Π·Π°ΠΌΠ΅Π½Ρ‹, Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΠΌ ΠΈΠ· Ρ†ΠΈΠΊΠ»Π° + if {![string match "*%f*" $fullCommand]} break + set fullCommand [regsub {%f} $fullCommand $file] + } + } + + # 6. ЗамСняСм %d Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³(ΠΈ), Ссли ΠΎΠ½ Π²Ρ‹Π΄Π΅Π»Π΅Π½ Π² Π΄Π΅Ρ€Π΅Π²Π΅, + # ΠΈ Ссли Π½Π΅ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΎ Ρ‚ΠΎ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ Π² Π΄Π΅Ρ€Π΅Π²Π΅ + DebugPuts "Tools::Execute: $fullCommand" + + set pipe [open "|$fullCommand" "r"] + fileevent $pipe readable + fconfigure $pipe -buffering none -blocking no +} + +# ΠŸΡ€Π°Π²ΠΊΠ° Ρ„Π°ΠΉΠ»Π° настроСк +proc Tools::Settings {} { + global dir + + FileOper::Edit [file join $dir(cfg) tools.ini] + # Config::read $dir(cfg) +} diff --git a/lib/tree.tcl b/lib/tree.tcl index 920c63a..37ff5e8 100644 --- a/lib/tree.tcl +++ b/lib/tree.tcl @@ -99,6 +99,7 @@ namespace eval Tree { proc PressItem {tree} { global nbEditor lexers editors activeProject set id [$tree selection] + if {[llength $id] > 1} {return} $tree tag remove selected $tree item $id -tags selected SetActiveProject [GetItemID $tree [GetUpperItem $tree $id]] @@ -131,8 +132,10 @@ namespace eval Tree { $nbEditor select $nbItem set txt $nbItem.frmText.t set findString [dict get $lexers [dict get $editors $txt fileType] procFindString] + DebugPuts "Tree::PressItem: $findString\n values: $values" + regsub -all {\*} $values {\\*} values regsub -all {PROCNAME} $findString $values str - + DebugPuts "Tree::PressItem: $str" Editor::FindFunction $txt "$str" } } @@ -160,5 +163,12 @@ namespace eval Tree { GetUpperItem $tree $parent } } - + + proc GetSelectedItemValues {tree} { + set valuesList "" + foreach itemID [$tree selection] { + lappend valuesList [GetItemID $tree $itemID] + } + return $valuesList + } } diff --git a/openbsd/build-package-bsd.sh b/openbsd/build-package-bsd.sh index 7f32f8d..78c1f95 100755 --- a/openbsd/build-package-bsd.sh +++ b/openbsd/build-package-bsd.sh @@ -49,7 +49,6 @@ cat > ${WORK_DIR}/${PKG_FULLNAME}/+CONTENTS << EOF @depend devel/tklib:tklib-*:tcl-* @comment Editor for Tcl/Tk and other languages. @arch amd64 -@wantlib pthread @ignore @cwd /usr/local EOF @@ -78,7 +77,7 @@ Supported languages for highlighting and navigation: Tcl/Tk, GO, Perl, Python, Ruby, Shell (BASH), Markdown, YAML (Ansible), Lua. EOF -(cd ${WORK_DIR} && tar -czf ../../../${PKG_FULLNAME}.tgz ${PKG_FULLNAME}/) +(cd ${WORK_DIR}/${PKG_FULLNAME}/ && pwd && ls -1 && tar -czf ../../../../${PKG_FULLNAME}.tgz .) echo "Package created: ${PKG_FULLNAME}.tgz" diff --git a/projman.tcl b/projman.tcl index 18ad1ef..89e5360 100755 --- a/projman.tcl +++ b/projman.tcl @@ -9,8 +9,8 @@ exec wish8.6 "$0" -- "$@" # Home page: https://nuk-svk.ru ###################################################### # Version: 2.0.0 -# Release: beta1 -# Build: 22012026174911 +# Release: beta4 +# Build: 12022026115443 ###################################################### # ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ, Ρ€Π΅Π»ΠΈΠ· ΠΈ Ρ‚.Π΄. @@ -114,13 +114,22 @@ foreach modFile [lsort [glob -nocomplain [file join $dir(theme) *]]] { } -# Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³, Ссли ΠΎΠ½ отсутствуСт, Ρ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹ΠΉ -if {[file exists [file join $dir(cfg) projman.ini]] ==0} { +# Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³, Ссли ΠΎΠ½ отсутствуСт ΠΈΠ»ΠΈ пустой, Ρ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹ΠΉ +if {[file exists [file join $dir(cfg) projman.ini]] == 0 || [file size [file join $dir(cfg) projman.ini]] == 0} { Config::create $dir(cfg) } Config::read $dir(cfg) Config::CheckVariables +# Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ½Ρ„ΠΈΠ³ для инстурмСнтов, Ссли ΠΎΠ½ отсутствуСт ΠΈΠ»ΠΈ пустой, Ρ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹ΠΉ +if {[file exists [file join $dir(cfg) tools.ini]] == 0 || [file size [file join $dir(cfg) tools.ini]] == 0} { + Tools::Create $dir(cfg) +} +# Π§ΠΈΡ‚Π°Π΅ΠΌ настройки для Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов +Tools::Read $dir(cfg) +Tools::CheckVariables +Tools::Write $dir(cfg) + ::msgcat::mclocale $cfgVariables(locale) if [::msgcat::mcload [file join $dir(lib) msgs]] { diff --git a/redhat/build-rpm.sh b/redhat/build-rpm.sh index 9457944..d57c5d7 100755 --- a/redhat/build-rpm.sh +++ b/redhat/build-rpm.sh @@ -18,6 +18,8 @@ cp projman.tcl projman sed -i "s+^set\ dir(lib)+set\ dir(lib)\ /usr/share/projman/lib ;#+g" projman sed -i "s+\[pwd\]+/usr/share/projman+g" projman +./changelog-gen.tcl --project-name projman --project-version ${VERSION} --project-release ${RELEASE} --out-file redhat/projman.spec --rpm --last + CUR_DIR=$(pwd) cd ../ @@ -31,12 +33,12 @@ cp redhat/projman.spec ${RPM_BUILD_DIR}/SPECS/projman.spec sed -i "s/.*Version:.*/Version:\t${VERSION}/" ${RPM_BUILD_DIR}/SPECS/projman.spec sed -i "s/.*Release:.*/Release:\t${RELEASE}/" ${RPM_BUILD_DIR}/SPECS/projman.spec -rpmbuild -ba "${RPM_BUILD_DIR}/SPECS/projman.spec" +fakeroot rpmbuild -ba "${RPM_BUILD_DIR}/SPECS/projman.spec" -# cp ${RPM_BUILD_DIR}/RPMS/noarch/projman-${VERSION}-${RELEASE}.noarch.rpm /files/ -# cp ${RPM_BUILD_DIR}/SRPMS/projman-${VERSION}-${RELEASE}.src.rpm /files/ +cp ${RPM_BUILD_DIR}/RPMS/noarch/projman-${VERSION}-${RELEASE}.noarch.rpm ../ +cp ${RPM_BUILD_DIR}/SRPMS/projman-${VERSION}-${RELEASE}.src.rpm ../ rm -v projman rm -r -v ${RPM_BUILD_DIR}/SPECS/projman.spec rm -r -v ${RPM_BUILD_DIR}/SOURCES/projman-${VERSION}-${RELEASE}.tar.gz -rm -r -v ${RPM_BUILD_DIR}/BUILD/projman +#rm -r -v ${RPM_BUILD_DIR}/BUILD/projman diff --git a/redhat/projman.spec b/redhat/projman.spec index 66a878a..1865e89 100644 --- a/redhat/projman.spec +++ b/redhat/projman.spec @@ -6,7 +6,7 @@ License: GPL Group: Development/Tcl Url: https://nuk-svk.ru BuildArch: noarch -Source: %name-%version-%release.tar.gz +Source: %{name}-%{version}-%{release}.tar.gz Requires: tcl, tk, tklib, tcllib %description @@ -16,40 +16,224 @@ This a editor for programming in TCL/Tk (and other language). It includes a file Π˜Π½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Π°Ρ срСда для программирования Π½Π° Tcl/Tk. Π’ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя - ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ², ΠΏΠΎΠ»Π½ΠΎΡ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€, систСму Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ„Π°ΠΉΠ»Π°ΠΌ ΠΈ структурС Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ΅. %prep -%setup -n %name +%setup -n %{name} %build +# ΠŸΡƒΡΡ‚Π°Ρ сСкция, Ссли сборка Π½Π΅ трСбуСтся %install -mkdir -p $RPM_BUILD_ROOT%_bindir -mkdir -p $RPM_BUILD_ROOT%_datadir/%name/lib/msgs -mkdir -p $RPM_BUILD_ROOT%_datadir/%name/theme -mkdir -p $RPM_BUILD_ROOT%{_datarootdir}/applications +# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ +mkdir -p %{buildroot}%{_bindir} +mkdir -p %{buildroot}%{_datadir}/%{name}/lib/msgs +mkdir -p %{buildroot}%{_datadir}/%{name}/theme +mkdir -p %{buildroot}%{_datadir}/applications +mkdir -p %{buildroot}%{_iconsdir}/hicolor/48x48/apps -install -p -m755 projman $RPM_BUILD_ROOT%_bindir/%name -install -p -m755 tkregexp.tcl $RPM_BUILD_ROOT%_bindir/tkregexp +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ исполняСмыС Ρ„Π°ΠΉΠ»Ρ‹ +install -p -m755 projman %{buildroot}%{_bindir}/%{name} +install -p -m755 tkregexp.tcl %{buildroot}%{_bindir}/tkregexp +install -p -m755 changelog-gen.tcl %{buildroot}%{_bindir}/changeloggen -# install -p -m644 *.tcl $RPM_BUILD_ROOT%_datadir/%name/ -install -p -m644 lib/*.tcl $RPM_BUILD_ROOT%_datadir/%name/lib/ -install -p -m644 lib/msgs/*.* $RPM_BUILD_ROOT%_datadir/%name/lib/msgs/ -install -p -m644 theme/*.tcl $RPM_BUILD_ROOT%_datadir/%name/theme -install -p -m644 projman.desktop $RPM_BUILD_ROOT%{_datarootdir}/applications +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ рСсурсы +install -p -m644 lib/*.tcl %{buildroot}%{_datadir}/%{name}/lib/ +install -p -m644 lib/msgs/*.* %{buildroot}%{_datadir}/%{name}/lib/msgs/ +install -p -m644 theme/*.tcl %{buildroot}%{_datadir}/%{name}/theme +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ .desktop Ρ„Π°ΠΉΠ» +install -p -m644 projman.desktop %{buildroot}%{_datadir}/applications/ + +# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΈΠΊΠΎΠ½ΠΊΡƒ Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ мСсто +install -p -m644 projman.png %{buildroot}%{_iconsdir}/hicolor/48x48/apps/projman.png + +# ОбновляСм кэш ΠΈΠΊΠΎΠ½ΠΎΠΊ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ для Debian) %post -%update_menus +if [ $1 -eq 1 ] ; then + if [ -x /usr/bin/gtk-update-icon-cache ]; then + /usr/bin/gtk-update-icon-cache -q %{_iconsdir}/hicolor || : + fi +fi %postun -%clean_menus +if [ $1 -eq 0 ] ; then + if [ -x /usr/bin/gtk-update-icon-cache ]; then + /usr/bin/gtk-update-icon-cache -q %{_iconsdir}/hicolor || : + fi +fi %files -%doc INSTALL CHANGELOG TODO LICENSE README.md -%_bindir/%name -%_bindir/tkregexp -%_datarootdir/applications/%name.desktop -%_datadir/%name - +%doc CHANGELOG TODO LICENSE README.md +%{_bindir}/%{name} +%{_bindir}/tkregexp +%{_bindir}/changeloggen +%{_datadir}/applications/projman.desktop +%{_datadir}/%{name} +%{_iconsdir}/hicolor/48x48/apps/projman.png %changelog -* Mon Nov 28 2022 Sergey Kalinin 2.0.0 - - Initial release +* Thu Feb 12 2026 svk 2.0.0-beta4 + - Π”ΠΎΠ±Π°Π²ΠΈΠ» экранированиС '*' Π² ΠΈΠΌΠ΅Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для поиска. + - ΠŸΠΎΠ΄ΠΊΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» рСгулярки для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π‘. + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ ΠΏΡ€ΠΈ отпускании ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΌΡ‹ΡˆΠΈ ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ Π½Π° крСстик. + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΊΠΎΠ½ΠΊΠΈ для 'c' ΠΈ 'h'. Π”ΠΎΠ±Π°Π²ΠΈΠ» сочитаниС Alt-R Π² русской раскладкС + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Π‘ (подсвСтка) + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² + +* Fri Feb 6 2026 svk 2.0.0-beta3 + - ΠžΡ‚ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» сборку Ρ€ΠΏΠΌ + +* Fri Feb 6 2026 svk 2.0.0-beta3 + - Π”ΠΎΠ±Π°Π²ΠΈΠ» сборку rpm. Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» changelog-ΠΈ + +* Fri Feb 6 2026 svk 2.0.0-beta3 + - changelog-gen: сдСлал Π²Ρ‹Π²ΠΎΠ΄ измСнСния Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ rpm.spec + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» смСну рСгистра Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… Π²ΠΊΠ»Π°Π΄ΠΎΠΊ + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ FileOper::SaveFile + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Π΄ΠΈΠ°Π»ΠΎΠ³ 'Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ' + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ символа ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» Ρ€Π°Π±ΠΎΡ‚Ρƒ со списком ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΠ· Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΎΠΊΠ½Π°. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρ‚Π°ΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· списка стрСлками ΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎ Enter. + - ВынСс ΠΊΠΎΠ΄ связанный с ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ подсказок ΠΏΡ€ΠΈ Π²Π²ΠΎΠ΄Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ. Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» Π½Π΅Π΄ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΏΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° ΠΈΠ· списка ΠΈ вставкС Π΅Π³ΠΎ Π² тСкст. Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ клавиш Π’Π²Π΅Ρ€ Π’Π½ΠΈΠ· Π’Π²ΠΎΠ΄ ΠžΡ‚ΠΌΠ΅Π½Π° Π² ΠΎΠΊΠ½Π΅ со списком Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ². + +* Tue Jan 27 2026 svk 2.0.0-beta2 + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ (bind) сочСтания клавишь ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π² настройках инструмСнтов. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° динамичСская гСнСрация мСню 'Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹'. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΠΎΠ²Ρ‹Π΅ внСшниС инструмСнты доступны сразу послС сохранСния Ρ„Π°ΠΉΠ»Π° настроСк tools.ini Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅. + - 2-я Π±Π΅Ρ‚Π° + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка с Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° Π² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ получСния Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ тСкста. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ настроСк Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов. И ΠΏΡƒΠ½ΠΊΡ‚ Π² мСню 'Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹'->'Настройки' + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ошибки с запуском Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅ΠΉ Π΄ΠΎ Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Ρƒ. + - Π‘Π΄Π΅Π»Π°Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° шаблонов ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки ΠΈ запуск Π²Π½Π΅ΡˆΠ½ΠΈΡ… инструмСнтов. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ tkregexp для установки Π² /usr/bin + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° сборка ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² для openbsd + +* Wed Jan 21 2026 svk 2.0.0-beta1 + - Π‘Π΄Π΅Π»Π°Π½ Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΠΎ запросу. ΠŸΠ΅Ρ€Π΅Π΄Π΅Π»ΠΊΠ° ΠΊΠΎΠ΄Π°. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ наличия ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ + - Π”ΠΎΠ±Π°Π²ΠΈΠ» фокус Π²Π²ΠΎΠ΄Π° Π½Π° 'Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»' Ссли ΠΎΠ½ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π²ΠΎ Π²ΠΊΠ»Π°Π΄ΠΊΠ΅ (ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ). + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» вставку ΠΊΠ°Π²Ρ‹Ρ‡Π΅ΠΊ ΠΏΡ€ΠΈ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠΈ тСкста + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ сигналов Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ процСссу. + - УмСньшил Π²ΡΠΏΠ»Ρ‹Π²Π°ΡŽΡ‰Π΅Π΅ мСню: вынСс мСнюшки Π€Π°ΠΉΠ» ΠΈ Π’ΠΈΠ΄ Π² подмСню. + - ИзмСнил ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Π² Ρ€Π΅ΠΏΡƒ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ сочСтании клавиш Control-y (ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠ΅ послСднСго дСйствия) + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ Ρ„Π»Π°Π³ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»Π° + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° ΠΈ сохранСниС Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΈ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠΈ экрана. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ настройки ΠΏΡƒΡ‚Π΅ΠΉ ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌ для выполнСния Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠΌΠ°Π΅Π³ΠΎ Ρ‚ΠΈΠΏΠ°. И использованиС этих настроСк ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ„Π°ΠΉΠ»Π°. + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Π²Ρ‹Π²ΠΎΠ΄ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ вСрсиях tcl ΠΈ tk + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Π²Ρ‹Π²ΠΎΠ΄ Π½ΠΎΠΌΠ΅Ρ€Π° вСрсии tcl/tl Π² О ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» сохранСниС ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ сохранСнии Ρ„Π°ΠΉΠ» Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ ΠΏΠΎΠ΄ Π½ΠΎΠ²Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Img. И ΠΏΠΎΠΏΡ€Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ + - ΠŸΠ΅Ρ€Π΅Π΄Π΅Π»Π°Π» сигналы ΠΈ сочСтния + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ фокуса Π²Π²ΠΎΠ΄Π° Π½Π° ΠΏΡ€Π΅ΠΆΠ½Π΅Π΅ ΠΎΠΊΠ½ΠΎ послС закрытия Π΄ΠΈΠ°Π»ΠΎΠ³Π° выполнСния. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° сигналов для закрытия Π·Π°ΠΏΡƒΡ‰Π΅Π½Π½ΠΎΠ³ΠΎ процСсса + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Π΄ΠΈΠ°Π»ΠΎΠ³ настроСк + - Π”ΠΎΠ±Π°Π²ΠΈΠ» псСвдо-Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Π΄ΠΈΠ°Π»ΠΎΠ³ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΡ‚ тСкстовых + - ΠŸΠΎΠΏΡ€Π°Π²ΠΈΠ» Ρ‚Π΅ΠΌΡƒ оформлСния + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° Π² windows + - УмСньшил колдичСство Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌΠΎΠΉ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚ΠΈ Π΄ΠΎ git Π² зависимости ΠΎΡ‚ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹. + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ созданиС Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ созданиС Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ. Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π½ΠΎΠΌΠ΅Ρ€Π° вСрсий Π² Π²Ρ‹Π·ΠΎΠ² tclsh8.6 ΠΈ wish8.6. Π£Π±Ρ€Π°Π½Π° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΠΈΡ‚ΡŒ Π½Π° Threads. + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ структуры ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΈΠ· мСню 'ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Π½Π΅Π΄Π°Π²Π½Π΅Π΅' + - Bugfix release + - Bug fix with varhelper + - Added the "Open Recent" menu. The "recentlyEditedFolders" option in the configuration file contains a list of recently opened directories. The procedures for working with this list have also been added. + - ΠšΠΎΡΠΌΠ΅Ρ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ измСнСния. + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ ошибки ΠΏΡ€ΠΈ вставкС ΠΊΠ°Π²Ρ‹Ρ‡Π΅ΠΊ + - changelog-gen.tcl: Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° гСнСрация тСкстового ΠΆΡƒΡ€Π½Π°Π»Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ + - build-deb-projman.sh: Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° гСнСрация changelog ΠΈΠ· git log + - changelog-gen.tcl: Π’Ρ‹Π²ΠΎΠ΄ Π² Ρ„Π°ΠΉΠ» вынСсСн Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ + - changelog-gen.tcl: Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ созданиС Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ Π²Ρ‹Π²ΠΎΠ΄ Π² Ρ„Π°ΠΉΠ». + - changelog-gen.tcl: Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΎΠΏΡ†ΠΈΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ запуск changelog-gen ΠΏΡ€ΠΈ сборкС ΠΏΠ°ΠΊΠ΅Ρ‚Π° + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ чстСниС ΠΆΡƒΡ€Π½Π°Π»Π° начиная с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π΄Π°Ρ‚Ρ‹ + - ГСнСрация списка ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ для debian ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΌΡƒ Π²ΠΈΠ΄Ρƒ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ фокус ΠΏΡ€ΠΈ создании Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. #3 + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ Π·Π°ΠΌΠ΅Π½Π° Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ поискС + - Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π» Π±Π°Π·ΠΎΠ²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΆΡƒΡ€Π½Π°Π»Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΈΠΊΠΎΠ½ΠΊΠ° для jinja template + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» остатки слияния Π²Π΅Ρ‚ΠΎΠΊ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ. + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ путями (~/ ./ ../) + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка ΠΏΡ€ΠΈ создании Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΏΠΈΠΊΡ‚ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Ρ„Π°ΠΉΠ»ΠΎΠ² + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ Files::CloseAll ('Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ всё') + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Lua + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° (рас)коммСнтирования + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ (Congig::Write) + - Π”ΠΎΠ±Π°Π²ΠΈΠ» раскраски Π² ruby + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ многострочных ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π² + - Π’ Ruby lexer Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ поиск ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠ΄Π΅. + - НСмного почистил. Π”ΠΎΠ±Π°Π²Π»Π΅Π½ поиск ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΠΎ ΠΏΠΈΡ‚ΠΎΠ½ΡŒΠΈΠΌ исходникам (lexer) + - ИзмСнСния Π² подсвСткС для INI + - Π”ΠΎΠ±Π°Π²ΠΈΠ» подсвСтку для Desktop ΠΈ Spec Ρ„Π°ΠΉΠ»ΠΎΠ² + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Π²Ρ‹Π²ΠΎΠ΄ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„Ρ‹ Π² ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» подсвСтку ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π² Π² TCL + - ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° подсвСтка ΠΈ навигация ΠΏΠΎ HTML. Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° подсвСтка XML + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΊΠΎΠ½ΠΊΡƒ для ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΊΠΎΠ½ΠΊΠΈ для perl + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° подсвСтка ΠΈ навигация ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ для Ruby + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ сохранСниС сСссии Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ (ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΏΠ°ΠΏΠΊΠΈ ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΡ€ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ запускС) + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° новая сСкция UserSession + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ошибки ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»Π° + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° INI-Ρ„Π°ΠΉΠ»ΠΎΠ² (подсвСтка + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° perl + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΊΠΎΠ³Π½ΠΊΡƒ для Ρ„Π°ΠΉΠ»ΠΎΠ² git + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΈΠΊΠΎΠ½ΠΊΠΈ для ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ сСртификатов. ИзмСнСн поиск ΠΈΠΊΠΎΠ½ΠΊΠΈ (Π²ΠΎΡ‰Π·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π΅Π΅Ρ€ΡŒ с Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ) + - Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π΄Π²ΡƒΡ…ΠΏΠ°Π½Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ (Π²Π΅Ρ€Ρ‚ΠΈΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅) + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ansible.cfg + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΡŽ ΠΊΠ½ΠΎΠΏΠΊΠΈ 'Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ€Π΅ΠΏΡƒ' Ссли Π½Π΅ Π²Ρ‹Π±Ρ€Π°Π½ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ (Π½Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°/ΠΏΠ°ΠΏΠΊΠΈ) + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ git init ΠΈ git config (Π·Π°Ρ‡Π°Ρ‚ΠΎΠΊ). ИзмСнСн Π΄ΠΈΠ°Π»ΠΎΠ³ клонирования рСпозитория (Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΊΠ½ΠΎΠΏΠΊΠ° Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ) + - Π˜ΡΠΏΡ€Π°Π²ΠΈΠ» ΠΎΡˆΠΈΠ±ΠΊΡƒ git ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»Π° ΠΈΠ»ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Ссли Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π½Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ (Π½Π΅Ρ‚ .git ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°) + - Π”ΠΎΠ±Π°Π²ΠΈΠ» скриты сборки rpm + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠ±Ρ€Π°ΠΌΠ»Π΅Π½ΠΈΠ΅ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ тСкста ΠΏΡ€ΠΈΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ '_' Π² markdown + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ подсвСтки + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° markdown (подсвСтка + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка с Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΏΠ°ΠΏΠΊΠΈ + - ΠŸΠ΅Ρ€Π΅Π΄Π΅Π»Π°Π½Π° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° опрСдСлСния Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π²Π΅Ρ‚ΠΊΠΈ git. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² Π΄Π²ΡƒΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… (ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°Ρ…/ΠΏΠ°ΠΏΠΊΠ°Ρ…) + - Π”ΠΎΠ΄Π΅Π»Π°Π½ Π²ΠΈΠ΄ Π΄ΠΈΠ°Π»ΠΎΠ³Π° поиска ΠΏΠΎ Ρ„Π°ΠΉΠ»Π°ΠΌ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ поиск ΠΈΠΌΠ΅Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Π΄ΠΈΠ°Π»ΠΎΠ³ клонирования рСпозитория + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈΠ΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Git ΠΏΠΎ Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ соотв. ΠΊΠ½ΠΎΠΏΠΊΠΈ Π² ΠΏΠ°Π½Π΅Π»ΠΈ инструмСнтов + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ ΠΏΡƒΠ½ΠΊΡ‚ 'Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ всё' + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ соотвСтствиС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π² Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ ΠΈ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ этого Ρ„Π°ΠΉΠ»Π° Π² Π΄Π΅Ρ€Π΅Π²Π΅ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ отобраТСния ΠΏΠ°Π½Π΅Π»ΠΈ (Π»Π΅Π²ΠΎ/ΠΏΡ€Π°Π²ΠΎ) Π² Π±Π΅Π· пСрСзапуска ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. + - Π£ΠΊΡ€Π°ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π° интСрфСйса - РСакция Π½Π° Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ Π² ΠΏΠ°Π½Π΅Π»ΠΈ инструмСнтов Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ зависит ΠΎΡ‚ контСкста + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ отобраТСния МСню + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ строки Π² Π±ΡƒΡ„Π΅Ρ€ ΠΏΠΎ Atl+Y + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° ошибка с ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΠΏΠ°Π½Π΅Π»ΠΈ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΈ исправлСны Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ отобраТСния мСню + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ statusBarShow - ΠΏΠΎΠΊΠ°Π· строки статуса + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π²Ρ‹Π·ΠΎΠ²Π° Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ просто строка + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Π²Ρ‹Π²ΠΎΠ΄ сообщСний ΠΎΠ± ошибкС Π² Π΄ΠΈΠ°Π»ΠΎΠ³Π΅ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ обновлСния списка Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π΄Π΅Ρ€Π΅Π²Π΅ + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ сообщСния + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° Git::Reset (git reset _file_) Π½Π° ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π² Π΄ΠΈΠ°Π»ΠΎΠ³Π΅. Для ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ 'git add' + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΊΠ½ΠΎΠΏΠΊΠ° ОбновлСниС Π² Π΄ΠΈΠ°Π»ΠΎΠ³ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Git + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ поиска наимСнования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ + - Ѐиксы Π΄ΠΈΠ°Π»ΠΎΠ³Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Git (Ρ€Π°Π±ΠΎΡ‚Π° с Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Π² списках) + - Ѐиксы ΠΈ тСсты Ρ€Π°Π±ΠΎΡ‚Ρ‹ с git + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π²Ρ‹Π±ΠΎΡ€Π°Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π΄ΠΈΠ°Π»ΠΎΠ³Π΅ Git + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ€Π΅Π³. выраТСния чтСния Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ git status + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ Ρ€Π΅Π³. Π²Ρ‹ΠΏΡ€Π°ΠΆΠ΅Π½ΠΈΠ΅ опрСдСлСния mime Ρ‚ΠΈΠΏΠ° Ρ„Π°ΠΉΠ»Π° + - Π”ΠΎΠ±Π°Π²ΠΈΠ» очистку тСкстовых ΠΏΠΎΠ»Π΅ΠΉ ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΊΠΎΠΌΠΌΠΈΡ‚ + - Π˜ΡΠΏΡ€Π°Π²Ρ€Π΅Π»Π΄Π΅Π½ΠΈΠ΅ Git::Commit (индСксация всСх Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅) + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΡ глюков + - Π£ΠΊΡ€Π°ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π° строки статуса + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ просмотрщик ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ + - Π”ΠΎΠ±Π°Π²ΠΈΠ» Ρ€Π°ΠΌΠΊΡƒ ΠΊΠΎΠ½Ρƒ Π²Π²ΠΎΠ΄Π° Π½ΠΎΠΌΠ΅Ρ€Π° + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Π΄ΠΈΠ°Π»ΠΎΠ³ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π° ΠΏΠΎ Π½ΠΎΠΌΠ΅Ρ€Ρƒ строки Ctrl-G + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Ρ„Π°ΠΉΠ»Π° + - Π”ΠΎΠ±Π°Π²ΠΈΠ» ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² сборки ΠΏΠ°ΠΊΠ΅Ρ‚Π° + - Новая сборка + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° подсвСтка ΠΈΠΌΠ΅Π½ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π²Ρ‹Π²ΠΎΠ΄Π΅ git show + - НСбольшиС ΠΏΡ€Π°Π²ΠΊΠΈ Π² подсказках ΠΏΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ + - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π° подсвСтка SHELL ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π° YAML Ρ„Π°ΠΉΠ»Π°Ρ… (ansible + + +