сделать стартовой  |  добавить в избранное

   SciTE - редактор кода для программистов

Архив SciTE-форума


Автор: frs, Отправлено:14:05 22-09-2008
Имхо, тебе нужен smartcomment.lua из предыдущих версий SciTE (к сожалению в текущей инкарнации smartcomment убита/поломана поддержка языков не поддерживающих блочных комментариев), только придётся перенастроить его с Ctrl+Q на Shift+Tab
Автор: Tipulatoid, Отправлено:14:20 22-09-2008
frs
Сейчас попробовал Ctrl+Q - работает как надо на файлах с расширением au3! Спасибо за наводку
Автор: BioInfo, Отправлено:15:10 22-09-2008
frs
smartcomment не дружит с xComment, если используете smartcomment, то xComment нужно отключить.
Или имеются ввиду какие то другие баги?
Автор: frs, Отправлено:15:49 22-09-2008
Ничего не включал и ничего не выключал. В дефолтной установке у меня не работает комментирование блоков текста в vbs в текущей (1.76) версии сборки - в output окошке выдается надпись - "! Отсутствуют параметры comment.stream.start.vb и comment.stream.end.vb". Видимо надо или починять или скрещивать скрипты или ставить в зависимость от лексера.
В предыдущем посте был не прав, не обратил внимания, что комментера - два. Т.е. поддержка языков без блочных комментариев сломана в xComment, а не в smartcomment.

Добавлено:
Кстати про AutoIt, стоило бы посмотреть сборку http://www.autoitscript.com/autoit3/scite/ и взять оттуда, то, что покажется интересным
Автор: vladvro, Отправлено:16:22 22-09-2008
frs

Цитата:
у меня не работает комментирование блоков текста в vbs в текущей (1.76) версии сборки - в output окошке выдается надпись - "! Отсутствуют параметры comment.stream.start.vb и comment.stream.end.vb".

у меня нормально работает, ставит и снимает комментирование, как со строки, так и с блока текста.
есть только небольшая особенность в скрипте XComment, он различает потоковый и блочный комментарии, если есть выделение и курсор не в начале строки, то считается, что пользователь хочет сделать потоковое комментирование, для которого требуется задание параметров comment.stream.start... и comment.stream.end... для лексера
Автор: frs, Отправлено:17:00 22-09-2008
Ну, вот это мне и не кажется нормальным, пусть закомментирует блок построчно или с позиции курсора или все строки на которых есть выделение (хорошо бы опцию выбора), а выдача ошибки и заставление меня пролистывать несколько экранов вверх-вниз, чтобы захватить начала строк имхо ненормально. Причем выделения конца строки ему тоже недостаточно, курсор должен попасть в начало следующей строки, чтобы скрипт заработал.

Цитата:
считается, что пользователь хочет сделать потоковое комментирование
так я не против, пусть в языках не имеющих операторов блочного комментирования делается альтернативное построчное комментирование.
Автор: mozers, Отправлено:17:45 22-09-2008
frs
Фича xComment в том, что и для блочного и для потокового комментирования используется один и тот же шорткат.
А поскольку это- совершенно разное комментирование, скрипт должен как то понимать, какой комментарий желает сделать пользователь - блочный или потоковый.
Как ему это понять??? - Только с помощью того КАК пользователь выделил текст.
Как же иначе то ???

Добавлено:

Цитата:
пусть в языках не имеющих операторов блочного комментирования делается альтернативное построчное комментирование.
Говоря другими словами, если параметры comment.stream.start... и comment.stream.end не заданы не выводить предупреждение об их отсутствии, а комментировать построчно, невзирая на вид выделения.
Я правильно понял мысль?
Если нет возражений - можно и так сделать...



Автор: frs, Отправлено:18:09 22-09-2008
Если начало выделения находится в начале строки, а окончание выделения находится в конце строки (перед символами перевода строки, а не после них), то имхо это всё равно должен быть блок а не поток.
угу, т.к. ожидаемой работы не делается, а от сообщения мне никакой пользы
Автор: mozers, Отправлено:22:18 22-09-2008
Скрипт xComment.lua модифицирован по предложению frs
Чтобы пользоваться было удобно, прочтите комментарии в скрипте!

Автор: frs, Отправлено:04:44 23-09-2008
Спасибочки!
---------------------------
Вот написал Indenter, для форматирования кода отступами в зависимости от уровня фолдинга в лексере. В процессе испытаний пришлось внести поправкм на разные лексеры. Коротенькие испытания проводил на cpp, pascal, lua, vbs, au3
итого лучший фолдинг у *.au3, в pascal и lua пришлось внести поправки, фолдинг vb-лексера - полный отстой, реагирует только на начальные пробелы-табуляции, имхо требуется полное переписывание лексера. cpp - пошел вне конкурся в силу своей простоты. Схема испытаний - выделяем код и убиваем все отступы многократными Shift-Tab, затем применяем скрипт.

Indenter.lua : [more]
Код:
--[[
Indenter.lua
Authors: frs
version 0.0.1
Форматирование кода отступами основанное на уровнях фолдинга с поправками на конкретные реализации лексеров
Code indenting code based on folding level with correctins for some definite lexers
]]

local sel_text = editor:GetSelText()
if sel_text == '' then
line_start = 0
line_end = editor.LineCount-1
else
line_start = props["SelectionStartLine"] - 1
line_end = props["SelectionEndLine"] - 2
end
-- значения по умолчанию для непрописанных лексеров
use_outdents=false
outdent_last_line=true

-- списки слов для убавления отступа, по мере испытаний будут правится
-- возможно стоит их внести в properties соответствующих языков
-- к началу слов добавлено подчеркивания для снятия конфликтов
-- я плохо знаю lua, возможно кто-нибудь напишет более простую конструкцию хранения списка и проверки наличия в нем слова
outdents={_end=1,_else=1,_next=1,_wend=1,_elseif=1} -- список слов по умолчанию
if lex== "pascal" then outdents={_end=1,_except=1} end -- список для паскаля
-- добавьте списки для других языков если требуется

lex=editor.LexerLanguage

if lex=="lua" or lex== "pascal" then use_outdents=true end
if
lex=="au3" then outdent_last_line=false end
if
lex~="python" then -- не вмешиваемся в отступы питона
editor:BeginUndoAction()

tb=4 -- ручное задание размера табуляций и индентов
editor.TabWidth=tb
--tb=editor.TabWidth -- автоматическое задание табуляций и индентов
editor.TabIndents=tb
editor.Indent=tb

ind=0
ind=editor.FoldLevel[no][[/no]line_start]
ind=math.fmod (ind, 1024)
for line_num = line_start, line_end do
local
line = editor:GetLine(line_num)
if line ~= nil and line ~="" then
ind_next=editor.FoldLevel[no][[/no]line_num+1]
ind_next=math.fmod (ind_next, 1024)
if use_outdents then
-- убавления отступа для слов из списка
if outdents["_"..string.gsub(line,"^%s*(%w*)(.*)","%1")]==1 then ind=ind-1 end
end
if
outdent_last_line then
-- убавления отступа в последней строке блока фолдинга
if ind_next<ind then ind=ind-1 end
end
editor.LineIndentation[no][[/no]line_num]=tb*ind
else
editor.LineIndentation[no][[/no]line_num]=0
end
ind=ind_next
end
editor:EndUndoAction()
end
[/more]
Автор: mozers, Отправлено:21:23 23-09-2008
frs
Хорошая идея - расставлять отступы, беря инфу из фолдинга
Мне кажется что скрипт можно было бы дополнить другими условностями форматирования... BioInfo тут как то выкладывал код...
Так, глядишь и явится на свет универсальный и гибко настраиваемый "облагораживатель" (или как его BioInfo назвал "форматтер") кода для любого языка программирования...
А я до сих пор, для приведения в приличный вид vbs скриптов, вставляю их в VBA-шный Excel-евский редактор...
Автор: frs, Отправлено:01:52 24-09-2008
Переписал блок фолдинга VB лексера на основе лексера au3, извиняюсь, что не удалил закомментированный мусор, т.к. на C я до этого не писал, возможно, что-то потребуется восстановить.
Блок раскрасски не трогал, может кто-нибуди пофиксит баг с непрокрашиванием последнего слова в файле, если после него идёт <eof>, моих знаний не хватило на поиск данного фикса в других лексерах.
LexVB.cxx : [more]
Код:
// Scintilla source code edit control
/** @file
LexVB.cxx
** Lexer for Visual Basic and VBScript.
**/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace
Scintilla;
#endif

// Internal state, highlighted as number
#define SCE_B_FILENUMBER SCE_B_DEFAULT+100


/*static bool IsVBComment(Accessor &styler, int pos, int len) {
return len > 0 && styler[pos] == '\'';
}*/

static inline bool
IsTypeCharacter(int ch) {
return
ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
}

// Extended to accept accented characters
static inline bool
IsAWordChar(int ch) {
return
ch >= 0x80 ||
(
isalnum(ch) || ch == '.' || ch == '_');
}

static inline bool
IsAWordStart(int ch) {
return
ch >= 0x80 ||
(
isalpha(ch) || ch == '_');
}

static inline bool
IsANumberChar(int ch) {
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
return (ch < 0x80) &&
(
isdigit(ch) || toupper(ch) == 'E' ||
ch == '.' || ch == '-' || ch == '+');
}

static void
ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) {

WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];

styler.StartAt(startPos);

int
visibleChars = 0;
int
fileNbDigits = 0;

// Do not leak onto next line
if (
initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
initStyle = SCE_B_DEFAULT;
}

StyleContext sc(startPos, length, initStyle, styler);

for (;
sc.More(); sc.Forward()) {

if (
sc.state == SCE_B_OPERATOR) {
sc.SetState(SCE_B_DEFAULT);
}
else if (
sc.state == SCE_B_IDENTIFIER) {
if (!
IsAWordChar(sc.ch)) {
// In Basic (except VBScript), a variable name or a function name
// can end with a special character indicating the type of the value
// held or returned.
bool skipType = false;
if (!
vbScriptSyntax && IsTypeCharacter(sc.ch)) {
sc.Forward(); // Skip it
skipType = true;
}
if (
sc.ch == ']') {
sc.Forward();
}
char
s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (
skipType) {
s[no][[/no]strlen(s) - 1] = '\0';
}
if (
strcmp(s, "rem") == 0) {
sc.ChangeState(SCE_B_COMMENT);
}
else {
if (
keywords.InList(s)) {
sc.ChangeState(SCE_B_KEYWORD);
}
else if (
keywords2.InList(s)) {
sc.ChangeState(SCE_B_KEYWORD2);
}
else if (
keywords3.InList(s)) {
sc.ChangeState(SCE_B_KEYWORD3);
}
else if (
keywords4.InList(s)) {
sc.ChangeState(SCE_B_KEYWORD4);
//!-start-[VBLexerImprovement]
} else if (keywordlists[4]->len) {
for (int
wl = 4; wl < KEYWORDSET_MAX; wl++) {
if (
keywordlists[wl]->InList(s)) {
sc.ChangeState(SCE_B_KEYWORD4 + wl - 3);
break;
}
}
//!-end-[VBLexerImprovement]
} // Else, it is really an identifier...
sc.SetState(SCE_B_DEFAULT);
}
}
}
else if (
sc.state == SCE_B_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign char
// Also accepts A-F for hex. numbers
if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
sc.SetState(SCE_B_DEFAULT);
}
}
else if (
sc.state == SCE_B_STRING) {
// VB doubles quotes to preserve them, so just end this string
// state now as a following quote will start again
if (sc.ch == '\"') {
if (
sc.chNext == '\"') {
sc.Forward();
}
else {
if (
tolower(sc.chNext) == 'c') {
sc.Forward();
}
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
else if (
sc.atLineEnd) {
visibleChars = 0;
sc.ChangeState(SCE_B_STRINGEOL);
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
else if (
sc.state == SCE_B_COMMENT) {
if (
sc.atLineEnd) {
visibleChars = 0;
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
else if (
sc.state == SCE_B_PREPROCESSOR) {
if (
sc.atLineEnd) {
visibleChars = 0;
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
else if (
sc.state == SCE_B_FILENUMBER) {
if (
IsADigit(sc.ch)) {
fileNbDigits++;
if (
fileNbDigits > 3) {
sc.ChangeState(SCE_B_DATE);
}
}
else if (
sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
// Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
// Too bad if date is format #27, Oct, 2003# or something like that...
// Use regular number state
sc.ChangeState(SCE_B_NUMBER);
sc.SetState(SCE_B_DEFAULT);
}
else if (
sc.ch == '#') {
sc.ChangeState(SCE_B_DATE);
sc.ForwardSetState(SCE_B_DEFAULT);
}
else {
sc.ChangeState(SCE_B_DATE);
}
if (
sc.state != SCE_B_FILENUMBER) {
fileNbDigits = 0;
}
}
else if (
sc.state == SCE_B_DATE) {
if (
sc.atLineEnd) {
visibleChars = 0;
sc.ChangeState(SCE_B_STRINGEOL);
sc.ForwardSetState(SCE_B_DEFAULT);
}
else if (
sc.ch == '#') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
}

if (
sc.state == SCE_B_DEFAULT) {
if (
sc.ch == '\'') {
sc.SetState(SCE_B_COMMENT);
}
else if (
sc.ch == '\"') {
sc.SetState(SCE_B_STRING);
}
else if (
sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_B_PREPROCESSOR);
}
else if (
sc.ch == '#') {
// It can be a date literal, ending with #, or a file number, from 1 to 511
// The date literal depends on the locale, so anything can go between #'s.
// Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
// So we set the FILENUMBER state, and switch to DATE if it isn't a file number
sc.SetState(SCE_B_FILENUMBER);
}
else if (
sc.ch == '&' && tolower(sc.chNext) == 'h') {
// Hexadecimal number
sc.SetState(SCE_B_NUMBER);
sc.Forward();
}
else if (
sc.ch == '&' && tolower(sc.chNext) == 'o') {
// Octal number
sc.SetState(SCE_B_NUMBER);
sc.Forward();
}
else if (
IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_B_NUMBER);
}
else if (
IsAWordStart(sc.ch) || (sc.ch == '[')) {
sc.SetState(SCE_B_IDENTIFIER);
}
else if (
isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
sc.SetState(SCE_B_OPERATOR);
}
}

if (
sc.atLineEnd) {
visibleChars = 0;
}
if (!
IsASpace(sc.ch)) {
visibleChars++;
}
}
sc.Complete();
}


static bool
IsStreamCommentStyle(int style) {
return
style == SCE_B_COMMENT;
}

//
// Routine to find first none space on the current line and return its Style
// needed for comment lines not starting on pos 1
static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
{
int
nsPos = styler.LineStart(szLine);
int
nePos = styler.LineStart(szLine+1) - 1;
while (
isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
{
nsPos++; // skip to next char

} // End While
return styler.StyleAt(nsPos);

}
// GetStyleFirstWord()

//
// Routine to check the last "none comment" character on a line to see if its a continuation
//
static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{
int
nsPos = styler.LineStart(szLine);
int
nePos = styler.LineStart(szLine+1) - 2;
//int stylech = styler.StyleAt(nsPos);
while (
nsPos < nePos)
{
//stylech = styler.StyleAt(nePos);
int stylech = styler.StyleAt(nsPos);
if (!(
stylech == SCE_B_COMMENT)) {
char
ch = styler.SafeGetCharAt(nePos);
if (!
isspacechar(ch)) {
if (
ch == '_')
return true;
else
return false
;
}
}
nePos--; // skip to next char
} // End While
return false;
}
// IsContinuationLine()

static void FoldVBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
int
endPos = startPos + length;

//***
// get settings from the config files for folding comments and preprocessor lines
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool
foldInComment = styler.GetPropertyInt("fold.comment") == 2;
bool
foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool
foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
//***


// Backtrack to previous line in case need to fix its fold status
int
lineCurrent = styler.GetLine(startPos);
if (
startPos > 0) {
if (
lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
//============from au3
// vars for style of previous/current/next lines
int style = GetStyleFirstWord(lineCurrent,styler);
int
stylePrev = 0;
// find the first previous line without continuation character at the end
while ((
lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
(
lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
if (
lineCurrent > 0) {
stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
}
// vars for getting first word to check for keywords
bool FirstWordStart = false;
bool
FirstWordEnd = false;
char
szKeyword[11]="";
int
szKeywordlen = 0;
char
szThen[5]="";
int
szThenlen = 0;
bool
ThenFoundLast = false;
// var for indentlevel
int levelCurrent = SC_FOLDLEVELBASE;
if (
lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int
levelNext = levelCurrent;
//
int visibleChars = 0;
char
chNext = styler.SafeGetCharAt(startPos);
char
chPrev = ' ';
//
for (int
i = startPos; i < endPos; i++) {
char
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (
IsAWordChar(ch)) {
visibleChars++;
}
// get the syle for the current character neede to check in comment
int stylech = styler.StyleAt(i);
// get first word for the line for indent check max 9 characters
if (FirstWordStart && (!(FirstWordEnd))) {
if (!
IsAWordChar(ch)) {
FirstWordEnd = true;
szKeyword[szKeywordlen] = '\0';
}
else {
if (
szKeywordlen < 10) {
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
}
}
}
// start the capture of the first word
if (!(FirstWordStart)) {
if (
IsAWordChar(ch) || IsAWordStart(ch) || ch == '\'') {
FirstWordStart = true;
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
}
}
// only process this logic when not in comment section
if (!(stylech == SCE_B_COMMENT)) {
if (
ThenFoundLast) {
if (
IsAWordChar(ch)) {
ThenFoundLast = false;
}
}
// find out if the word "then" is the last on a "if" line
if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
if (
szThenlen == 4) {
szThen[0] = szThen[1];
szThen[1] = szThen[2];
szThen[2] = szThen[3];
szThen[3] = static_cast<char>(tolower(ch));
if (
strcmp(szThen,"then") == 0 ) {
ThenFoundLast = true;
}
}
else {
szThen[szThenlen++] = static_cast<char>(tolower(ch));
if (
szThenlen == 5) {
szThen[4] = '\0';
}
}
}
}
// End of Line found so process the information
if ((
ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
// **************************
// Folding logic for Keywords
// **************************
// if a keyword is found on the current line and the line doesn't end with _ (continuation)
// and we are not inside a commentblock.
if (szKeywordlen > 0 && (!(chPrev == '_')) &&
((!(
IsStreamCommentStyle(style)) || foldInComment)) ) {
szKeyword[szKeywordlen] = '\0';
// only fold "if" last keyword is "then" (else its a one line if)
if (
strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
levelNext++;
}
// create new fold for these words
if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
strcmp(szKeyword,"function") == 0 || strcmp(szKeyword,"while") == 0||
strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"sub") == 0 ) {
levelNext++;
}
// create double Fold for select&switch because Case will subtract one of the current level
//if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
if (strcmp(szKeyword,"select") == 0) {
levelNext++;
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"end") == 0 || strcmp(szKeyword,"next") == 0 ||
strcmp(szKeyword,"until") == 0 ||
strcmp(szKeyword,"loop") == 0 || strcmp(szKeyword,"wend") == 0){
levelNext--;
levelCurrent--;
}
// end the fold for these words before the current line and Start new fold
if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
strcmp(szKeyword,"elseif") == 0 ) {
levelCurrent--;
}
// end the double fold for this word before the current line
/*if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
levelNext--;
levelNext--;
levelCurrent--;
levelCurrent--;
}*/
// end the fold for these words on the current line
/*if (strcmp(szKeyword,"#endregion") == 0 ) {
levelNext--;
}*/
}
// Preprocessor and Comment folding
int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
// *************************************
// Folding logic for preprocessor blocks
// *************************************
// process preprosessor line
if (foldpreprocessor && style == SCE_B_PREPROCESSOR) {
if (!(
stylePrev == SCE_B_PREPROCESSOR) && (styleNext == SCE_B_PREPROCESSOR)) {
levelNext++;
}
// fold till the last line for normal comment lines
else if (stylePrev == SCE_B_PREPROCESSOR && !(styleNext == SCE_B_PREPROCESSOR)) {
levelNext--;
}
}
// *********************************
// Folding logic for Comment blocks
// *********************************
if (foldComment && IsStreamCommentStyle(style)) {
// Start of a comment block
if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
levelNext++;
}
// fold till the last line for normal comment lines
else if (IsStreamCommentStyle(stylePrev)
&& !(
styleNext == SCE_B_COMMENT)
&&
stylePrev == SCE_B_COMMENT
&& style == SCE_B_COMMENT) {
levelNext--;
}
// fold till the one but last line for Blockcomment lines
/*else if (IsStreamCommentStyle(stylePrev)
// && !(styleNext == SCE_B_COMMENTBLOCK)
// && style == SCE_B_COMMENTBLOCK
)
{
levelNext--;
levelCurrent--;
}*/
}

int levelUse = levelCurrent;
int
lev = levelUse | levelNext << 16;
if (
visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (
levelUse < levelNext) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (
lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
// reset values for the next line
lineCurrent++;
stylePrev = style;
style = styleNext;
levelCurrent = levelNext;
visibleChars = 0;
// if the last character is an Underscore then don't reset since the line continues on the next line.
if (!(
chPrev == '_')) {
szKeywordlen = 0;
szThenlen = 0;
FirstWordStart = false;
FirstWordEnd = false;
ThenFoundLast = false;
}
}
// save the last processed character
if (!isspacechar(ch)) {
chPrev = ch;
visibleChars++;
}
}
//===========old=================
/*int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
char chNext = styler[no][[/no]startPos];
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);

if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
// Line after is blank so check the next - maybe should continue further?
int spaceFlags2 = 0;
int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
}
}
indentCurrent = indentNext;
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
}
}*/
}

static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false);
}

static void
ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
}

static const char * const
vbWordListDesc[] = {
"Keywords",
"user1",
"user2",
"user3",
0
};

LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);

[/more]

Сответственно поправил Indenter, т.к. VB фолдинг теперь функционирует нормально, + поправил индентацию блоков комментариев. Повесил его себе на Shift+Ctrl+P (как в привычном мне SmartIndenter для VB/VBA) и счастлив

Indenter.lua : [more]
Код:
--[[
Indenter.lua
Authors: frs
version 0.0.2
Форматирование кода отступами основанное на уровнях фолдинга с поправками на конкретные реализации лексеров
Code indenting code based on folding level with correctins for some definite lexers
]]

local sel_text = editor:GetSelText()
if sel_text == '' then
line_start = 0
line_end = editor.LineCount-1
else
line_start = props["SelectionStartLine"] - 1
line_end = props["SelectionEndLine"] - 2
end
-- значения по умолчанию для непрописанных лексеров
use_outdents=false
outdent_last_line=true

-- списки слов для убавления отступа, по мере испытаний будут правится
-- возможно стоит их внести в properties соответствующих языков
-- к началу слов добавлено подчеркивания для снятия конфликтов
-- я плохо знаю lua, возможно кто-нибудь напишет более простую конструкцию хранения списка и проверки наличия в нем слова
outdents={_end=1,_else=1,_next=1,_wend=1,_elseif=1,_then=1} -- список слов по умолчанию
if lex== "pascal" then outdents={_end=1,_except=1} end -- список для паскаля
-- добавьте списки для других языков если требуется

lex=editor.LexerLanguage

if lex=="lua" or lex== "pascal" then use_outdents=true end
if
lex=="au3" or lex=="vb" or lex=="vbscript" then outdent_last_line=false end
if
lex~="python" then -- не вмешиваемся в отступы питона
editor:BeginUndoAction()

tb=4 -- ручное задание размера табуляций и индентов
editor.TabWidth=tb
--tb=editor.TabWidth -- автоматическое задание табуляций и индентов
editor.TabIndents=tb
editor.Indent=tb

ind=0
ind=editor.FoldLevel[no][[/no]line_start]
ind=math.fmod (ind, 1024)
for line_num = line_start, line_end do
local
line = editor:GetLine(line_num)
if line ~= nil and line ~="" then
ind_next=editor.FoldLevel[no][[/no]line_num+1]
ind_next=math.fmod (ind_next, 1024)
-- trace((line_num+1).." \t- "..editor.FoldLevel[no][[/no]line_num].." - "..ind.."\n")
if use_outdents then
-- убавление отступа для слов из списка
if outdents["_"..string.gsub(line,"^%s*(%w*)(.*)","%1")]==1 then ind=ind-1 end
end
if
outdent_last_line then
-- убавление отступа в последней строке блока фолдинга
if ind_next<ind then ind=ind-1 end
end
comm=editor.StyleAt[editor.LineIndentPosition[no][[/no]line_num]]
if comm==1 and comm_prev==1 then ind=ind-1 end-- комментарий
comm_prev=comm
editor.LineIndentation[no][[/no]line_num]=tb*ind
else
editor.LineIndentation[no][[/no]line_num]=0
end
ind=ind_next
end
editor:EndUndoAction()
end
[/more]


Цитата:
Так, глядишь и явится на свет универсальный и гибко настраиваемый "облагораживатель" (или как его BioInfo назвал "форматтер") кода для любого языка программирования...
Ну, он уже почти универсален (при условии нормального фолдинга для конкретного языка в SciTE), а вот за гибкую настраиваемость я пока не возьмусь.
в ToDo можно ещё занести приведение регистра написания слов к определенному виду. Для регистрозависимых языков это приведёт к убавлению ошибок, независимым придаст дополнительной красивости. Слова можно просто взять из keywords в properties соответствующего языка.

Добавлено:
скомпилированный лексер с поддержкой vb-фолдинга, для тех кому лень компилить, а попробовать хочется
Автор: frs, Отправлено:17:22 24-09-2008
На данный момент в VB фолдинге неправильно работают блоки Select Case, не работает фолдинг функций с приставками типа Private, Public... но всё равно лучше, чем то, что было. Работа пока продолжается.
Автор: vladvro, Отправлено:17:39 24-09-2008
frs

Цитата:
На данный момент в VB фолдинге неправильно работают блоки Select Case, не работает фолдинг функций с приставками типа Private, Public... но всё равно лучше, чем то, что было. Работа пока продолжается.

Работа приветсвуется
Но на мой взгляд пока работает не лучше, вот пример, где с новым алгоритмом результат хуже
modProcedures.bas : [more]
Код:
Attribute VB_Name = "modProcedures"
Option Explicit

'*************************************************************************************************** ****
'* Private Constants
'*******************************************************************************************************

Private Const
mucModuleName = "modProcedures"

Private Const
REG_KEY_OPEN = "OPEN"
Private Const
REG_KEY_PRINT = "PRINT"

Private Const
B64ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Private Const
HTTP_HEAD_AUTHORISATION_BASIC As String = "Authorization: Basic "


'*************************************************************************************************** ****
'* Private Class Members
'*******************************************************************************************************

Private
msLastError As String


'*************************************************************************************************** ****
'* Public Enumerations
'*******************************************************************************************************

Public Enum SNLinkType
ltFileSystem = 1
ltLinkHTTP = 2
ltLinkVoyager = 3
ltLinkSAPNetSAPIDB = 4
ltLinkSAPNetSAPIDP = 5
ltLinkSAPNetForm = 5
ltLinkSAPNetDownload = 6
ltLinkSAPNetIRON = 7
End Enum

Public Enum
EnSpecialObjectHandling
sohEdit = -1
sohDisplay = -2
sohPrint = -3
sohDisplaySource = -4
End Enum


'*************************************************************************************************** ****
'* Public Data Types
'*******************************************************************************************************


'*******************************************************************************************************
'* Private Windows API Declarations
'*******************************************************************************************************

Declare Function
GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Private Declare Function
CoCreateGuid Lib "ole32" _
(ByRef GUID As Byte) As Long

Private Type
OPENFILENAME
lStructSize As Long ' Filled with UDT size
hWndOwner As Long ' Tied to Owner
hInstance As Long ' Ignored (used only by templates)
lpstrFilter As String ' Tied to Filter
lpstrCustomFilter As String ' Ignored (exercise for reader)
nMaxCustFilter As Long ' Ignored (exercise for reader)
nFilterIndex As Long ' Tied to FilterIndex
lpstrFile As String ' Tied to FileName
nMaxFile As Long ' Handled internally
lpstrFileTitle As String ' Tied to FileTitle
nMaxFileTitle As Long ' Handled internally
lpstrInitialDir As String ' Tied to InitDir
lpstrTitle As String ' Tied to DlgTitle
Flags As Long ' Tied to Flags
nFileOffset As Integer ' Ignored (exercise for reader)
nFileExtension As Integer ' Ignored (exercise for reader)
lpstrDefExt As String ' Tied to DefaultExt
lCustData As Long ' Ignored (needed for hooks)
lpfnHook As Long ' Ignored (good luck with hooks)
lpTemplateName As Long ' Ignored (good luck with templates)
End Type

Type
SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
' Optional fields
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type


Private Declare Function
GetOpenFileName Lib "COMDLG32" _
Alias "GetOpenFileNameA" (file As OPENFILENAME) As Long

Declare Function
RegQueryValue Lib "advapi32.dll" Alias "RegQueryValueA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpValue As String, lpcbValue As Long) As Long

Declare Function
RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long

Declare Function
RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long


'*************************************************************************************************** ****
'* private variables
'*******************************************************************************************************

Private mstrMenuEntryOpen As String 'default display entry
Private mstrMenuEntryPrint As String 'default print entry


Public Function AddDir(dir1 As String, dir2 As String) As String
On Error Resume Next

If Len
(
dir1) > 0 And Len(dir2) > 0 Then
If
Right$(dir1, 1) = "\" And Left$(dir2, 1) = "\" Then
AddDir = Left$(dir1, Len(dir1) - 1) + dir2
ElseIf Right$(dir1, 1) = "\" Or Left$(dir2, 1) = "\" Then
AddDir = dir1 + dir2
Else
AddDir = dir1 & "\" & dir2
End If
Else
AddDir = dir1 + dir2
End If
End Function

Public Function
GetTempDir() As String
Dim
sRet As String, c As Long
sRet = String(cMaxPath, 0)
c = GetTempPath(cMaxPath, sRet)
If
c <> 0 Then
GetTempDir = Left$(sRet, c)
End If
End Function

Function
VBGetOpenFileName(FileName As String, _
Optional FileTitle As String, _
Optional FileMustExist As Boolean = True, _
Optional MultiSelect As Boolean = False, _
Optional ReadOnly As Boolean = False, _
Optional HideReadOnly As Boolean = False, _
Optional filter As String = "All (*.*)| *.*", _
Optional FilterIndex As Long = 1, _
Optional InitDir As String, _
Optional DlgTitle As String, _
Optional DefaultExt As String, _
Optional Owner As Long = -1, _
Optional Flags As Long = 0) As Boolean

Dim
opfile As OPENFILENAME, s As String, afFlags As Long
With
opfile
.lStructSize = Len(opfile)

' Add in specific flags and strip out non-VB flags
.Flags = (-FileMustExist * OFN_FILEMUSTEXIST) Or _
(-MultiSelect * OFN_ALLOWMULTISELECT) Or _
(-ReadOnly * OFN_READONLY) Or _
(-HideReadOnly * OFN_HIDEREADONLY) Or _
(Flags And CLng(Not (OFN_ENABLEHOOK Or _
OFN_ENABLETEMPLATE)))
' Owner can take handle of owning window
If Owner <> -1 Then .hWndOwner = Owner
' InitDir can take initial directory string
.
lpstrInitialDir = InitDir
' DefaultExt can take default extension
.
lpstrDefExt = DefaultExt
' DlgTitle can take dialog box title
.
lpstrTitle = DlgTitle

' To make Windows-style filter, replace | and : with nulls
Dim
ch As String, i As Integer
For
i = 1 To Len(filter)
ch = Mid$(filter, i, 1)
If
ch = "|" Or ch = ":" Then
s = s & vbNullChar
Else
s = s & ch
End If
Next
' Put double null at end
s = s & vbNullChar & vbNullChar
.lpstrFilter = s
.nFilterIndex = FilterIndex

' Pad file and file title buffers to maximum path
s = FileName & String$(cMaxPath - Len(FileName), 0)
.
lpstrFile = s
.nMaxFile = cMaxPath
s = FileTitle & String$(cMaxFile - Len(FileTitle), 0)
.
lpstrFileTitle = s
.nMaxFileTitle = cMaxFile
' All other fields set to zero

If
GetOpenFileName(opfile) Then
VBGetOpenFileName = True
FileName = StrZToStr(.lpstrFile)
FileTitle = StrZToStr(.lpstrFileTitle)
Flags = .Flags
' Return the filter index
FilterIndex = .nFilterIndex
' Look up the filter the user selected and return that
filter = FilterLookup(.lpstrFilter, FilterIndex)
If (.
Flags And OFN_READONLY) Then ReadOnly = True
Else
VBGetOpenFileName = False
FileName = sEmpty
FileTitle = sEmpty
Flags = 0
FilterIndex = -1
filter = sEmpty
End If
End With
End Function

Private Function
StrZToStr(s As String) As String
StrZToStr = Left$(s, lstrlen(s))
End Function

Private Function
FilterLookup(ByVal sFilters As String, ByVal iCur As Long) As String
Dim
iStart As Long, iEnd As Long, s As String
iStart = 1
If
sFilters = sEmpty Then Exit Function
Do
' Cut out both parts marked by null character
iEnd = InStr(iStart, sFilters, vbNullChar)
If
iEnd = 0 Then Exit Function
iEnd = InStr(iEnd + 1, sFilters, vbNullChar)
If
iEnd Then
s = Mid$(sFilters, iStart, iEnd - iStart)
Else
s = Mid$(sFilters, iStart)
End If
iStart = iEnd + 1
If
iCur = 1 Then
FilterLookup = s
Exit Function
End If
iCur = iCur - 1
Loop While
iCur
End Function
[/more]
Автор: frs, Отправлено:19:19 24-09-2008
Вы имеете в виду фолдинг? В старом лексере он практически отсутствует, реагирует, только на расставленные вручную отступы, но никак не на код и его операторы. Выделите весь код и убейте отступы несколько раз нажав Shift+Tab - фолдинг исчез.
Новый глючит и спотыкается и неправильно работает, но хоть как-то работает.
Хотя для преформатированного кода, наверно, пока лучше оставаться на старом лексере.

Посмотрел образец, буду добавлять отступы для enum и type, авось потом ещё чего-нибудь вспомним.
Поддержка ":" ещё требуется

зы Как лучше, каждый раз закидывать сюда свежий код? свежий SciLexer.dll? всё вместе? править исходный пост или постить новые сообщения?
Автор: LittleMeN, Отправлено:10:12 25-09-2008
Здраствуте, у меня проблемка - немогу зарегистрировать SciTE Helper через regsvr32 изза висты - можт у меня пальцы кривые можт ещё што я непонимаю....

regsvr32 <путь>SciTE.dll - даже при запуске с правами админа результатов дает не много...

запуск скрипта Setup.vbs равно как и установка интеграции через редактор результатов не дает...

правда - мне не принципиален Helper - если есть другие варианты сохранять скрипты в UTF-8 подскажите кто знает как это сделать?!?!?

помогите кто уже поборол эту проблемку!
Автор: mozers, Отправлено:11:52 25-09-2008
LittleMeN
Цитата:
немогу зарегистрировать SciTE Helper
Возможно что отсутствует msvbvm50.dll (подробности)

Цитата:
если есть другие варианты сохранять скрипты в UTF-8 подскажите кто знает как это сделать?!?!?
Выделяем текст, копируем в буфер, переключаем кодировку через меню Файл/Кодировка, вставляем текст из буфера, сохраняем. Кто то это дело даже автоматизировал

frs
Цитата:
зы Как лучше, каждый раз закидывать сюда свежий код? свежий SciLexer.dll? всё вместе? править исходный пост или постить новые сообщения?
Самым правильным было бы подключится к SVN...

Автор: vladvro, Отправлено:14:34 25-09-2008
frs

Цитата:
Новый глючит и спотыкается и неправильно работает, но хоть как-то работает.
Хотя для преформатированного кода, наверно, пока лучше оставаться на старом лексере.

предлагаю сделать новый код опциональным, т.е. добавить новую опцию в настройки редактора, в зависимости от которой будет использоваться либо новый, либо старый алгоритм.

Цитата:
зы Как лучше, каждый раз закидывать сюда свежий код? ...

Уважаемый mozers ответил совершенно верно, лучше присоединиться к проекту и использовать SVN.
И дальнейшее обсуждения изменений кода перенести в соседнюю тему
Автор: Bolenic, Отправлено:01:49 26-09-2008
Подскажите, как сделать в SciTE-е следующее.

Есть текстовый файл такого содержания:
(всего несколько сотен строк)

...
agrxxx@xxxdomen.ua 1
albyyy@yyydomen.com 1
alczzz@zzzdomen.ru 2
...


Нужно "одним махом" привести его к виду:

...
agrxxx@xxxdomen.ua
albyyy@yyydomen.com
alczzz@zzzdomen.ru
...

Прим.
Все цифры отступают на один пробел,
но некоторые - на какой-то "длинный" пробел.
Теоретически, цифры могут быть одно-дву-трёхзначными.

Автор: LittleMeN, Отправлено:08:58 26-09-2008
Изпользуй замену - с регулярными выражениями



1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17 / 18 / 19 / 20 / 21 / 22 / 23 / 24 / 25 / 26 / 27 / 28 / 29 / 30 / 31 / 32 / 33 / 34 / 35 / 36 / 37 / 38 / 39 / 40 / 41 / 42 / 43 / 44 / 45 / 46 / 47 / 48 / 49 / 50 / 51 / 52 / 53 / 54 / 55 / 56 / 57 / 58 / 59 / 60 / 61 / 62 / 63 / 64 / 65 / 66 / 67 / 68 / 69 / 70 / 71 / 72 / 73 / 74 / 75 / 76 / 77 / 78 / 79 / 80 / 81 / 82 / 83 / 84 / 85 / 86 / 87 / 88 / 89 / 90 / 91 / 92 / 93 / 94 / 95 / 96 / 97 / 98 / 99 / 100 / 101 / 102 / 103 / 104 / 105 / 106 / 107 / 108 / 109 / 110 / 111 / 112 / 113 / 114 / 115 / 116 / 117 / 118 / 119 / 120 / 121 / 122 / 123 / 124 / 125 / 126 / 127 / 128 / 129 / 130 / 131 / 132 / 133 / 134 / 135 / 136 / 137 / 138 / 139 / 140 / 141 / 142 / 143 / 144 / 145 / 146 / 147 / 148 / 149 / 150 / 151 / 152 / 153 / 154 / 155 / 156 / 157 / 158 / 159 / 160 / 161 / 162 / 163 / 164 / 165 / 166 / 167 / 168 / 169 / 170 / 171 / 172 / 173 / 174 / 175 / 176 / 177 / 178 / 179 / 180 / 181 / 182 / 183 / 184 / 185 / 186 / 187 / 188 / 189 / 190 / 191 / 192 / 193 / 194 / 195 / 196 / 197 / 198 / 199 / 200 / 201 / 202 / 203 / 204 / 205 / 206 / 207 / 208 / 209 / 210 / 211 / 212 / 213 /
SciTE © 2004 - 2011