LINUX.ORG.RU
Ответ на: комментарий от qrck

Проблема только в том, что в случае linux-а бэкап конфигурации - бесполезен. В случае если приходится переходить на новое устройство в связи с утратой старого, вы же все равно поставите новую версию вашего любимого дистриба, а там как всегда - куча конфигов уже совершенно другого формата, часть вообще уже другими методами реализуется, итп, итп. Так что кроме файла .vimrc - больше уже ничего и не применимо в новой системе.


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

dvrts ★★★
() автор топика
Последнее исправление: dvrts (всего исправлений: 1)
Ответ на: комментарий от dvrts

Ну а я и не говорил о том, что бы бэкапить весь /etc. Но даже конфиги в домашних каталогах - далеко не всегда сходу применимы в новой версии. У меня по этой причине постоянно лежали в Linux-е каталоги в ~ : ~/oldhome, ~/oldhome/oldhome, итп. Каждый переезд - ручками переносятся все конфиги и файлы, а что остается - оставляется «на всякий случай».

qrck ★★
()
Ответ на: комментарий от MiniRoboDancer

удобную навигацию по проекту, в котором больше чем 2-3 тысячи файлов, и нужно постоянно по коду перемешаться туда-сюда?

NERDTree и вкладок мало? Я пилил довольно большой проект (FBReaderJ), как-то неудобств не испытывал.

Вот этого кстати тоже не уверен что хватит. Т.к. когда файлов больше 2-3 тысяч - часто просто не помнишь как именно назывался файл, где он находился. Помнишь часть имени или даже часть имени объекта, объявленном в том файле, тогда Ctrl+T/Ctrl+Shift+T, и по остаткам имени файла или объекта ReSharper все найдет.

развернуть LINQ выражение в for-цикл

Автоматизируемо.

Обещанные примеры, покажите как вот нижеприведенное автоматизировать в vim-е. На самом деле LINQ в for - это относительно простая задача пожалуй. А вот обратное - будет посложнее. Тем не менее, ReSharper любые из нижеприведенных конвертаций делает в обе стороны легко. Покажите как это можно автоматизировать в vim?

Пример 1:

var l = new string[10];
var res = false;

for (int i=0; i<l.Length; ++i)
{
	if (string.Compare(l[i], "something", StringComparison.OrdinalIgnoreCase) == 0)
	{
		res = true;
		break;
	}
}

легко конвертируется ReSharper-ом в 2 нажатия клавиши (Alt+Enter,Enter) в/из:

var l = new string[10];
var res = l.Any(t => string.Compare(t, "something", StringComparison.OrdinalIgnoreCase) == 0);

Пример 2:

var l = new int[10];
var res = 0;

for (int i=0; i<l.Length; ++i)
	res = res * 10 + l[i];

легко конвертируется полностью автоматически в/из:

var l = new int[10];
var res = l.Aggregate(0, (current,t) => current*10 + t));

Пример 3:

var l = new int[10];
var res = 0;

for (int i=0; i<l.Length; ++i)
{
	if (l[i] == 10)
		++ res;
}

легко конвертируется полностью автоматически в/из:

var l = new int[10];
var res = l.Count(0, t => t==10);

Пример 4, немного из другой оперы, но тоже - фиг это сделаться скриптом не понимающим семантики, конвертация LINQ запроса из канонической формы в «Method Chain» и обратно. Надо сказать оно легко переваривает куда более сложные запросы, с кучей вложенных join-ов, итп.

var l = new int[10];
var r = new int[10];

var q = from x in l where x > 10 join y from r on x equals y select x + y;

легко конвертируется полностью автоматически в/из:

var q = l.Where(x => x > 10).Join(r, x => x, y => y, (x,y) => x+y);

Т.е. что я хочу сказать - эта фиговина, ReSharper, не только понимает синтаксис языка, но и понимает что код делает. Все вышеприведенные примеры - сильно упрощенные примеры, для того что-бы показать концепцию так сказать. Может оно и куда более сложные вещи преобразовывать, но даже эти примеры - будут не по зубам скриптам на awk/sed/bash/perl.

В общем жду ответа - как это автоматизировать в vim.

qrck ★★
()
Последнее исправление: qrck (всего исправлений: 1)
Ответ на: комментарий от qrck

компенсируете

Это почему это?

бэкап конфигурации - бесполезен

Об этом я упоминал.

вы же все равно поставите новую версию вашего любимого дистриба

Не факт, что другую и что того же дистрибутива.

куча конфигов уже совершенно другого формата

Они и за время работы дистрибутива меняются, если это не законсервированное говно мамонта с бэкпортируемыми security-патчами типа RHEL и Debian Stable.

больше уже ничего и не применимо в новой системе

4.2 Многие вещи не меняются десятки лет и не ломают обратную совместимость. И это не только демоны и консольные мастодонты, но и вполне себе графика, прикладуха, среды...

ни в какой версии

Так если версии в корне разные?

на порядки

Ну это Вы загнули... Тем более, всё от подхода к парсингу зависит, если не следовать тупо правилам построения грамматик, а задействовать смекалку, многие вещи можно заметно упростить.

эти скрипты должны будут включать в себя половину компилятора

С конкретными синтаксическими конструкциями работать несложно, другой вопрос, что сырой парсер может запнуться на сложных вложенных конструкциях (простейший пример — экранированная кавычка внутри строки), но ReSharper тоже 100%-ной гарантии для синтаксических изворотов не даёт, хоть он и хорошо оттестирован, а поправить его быстро, ещё и без сырцов, не получится — тут-то и окажется, что после многолетнего опыта юзания плагина умение «низкоуровневого» редактирования кода атрофировалось.

речь не идет о стандартной библиотеке

Так и я не о ней.

какие именно методы у того или иного класса, но общее понятие имеешь - что класс умеет

И об этом писал — без документации можно незаметно вляпаться в баг. Знание названия метода и типов параметров ещё ни о чём не говорит, особенно если либа производительная и в неё нет классообёрток для булей и интов на каждый чих.

штук 6

Разве не 11? И тут ситуация противоположна предыдущему пункту: если оверлоадов дофига, то они сделаны на все интуитивно понятные случаи и с ними сложно прогадать.

с «someMethod()» на «object.someMethod()»

:m,ns/someMethod()/object.someMethod()/g справится. И сделать команду, которая автоматом начало-конец класса определяет, если они внезапно не в разных файлах, тоже просто.

заменить прямой доступ к вынесенным полям на вызов getter/setter-ов

Аналогично.

автоматические преобразования циклов в linq

linqpad есть и отдельной утилитой. Причём, внезапно, бесплатно, в отличие от плагина для студии.

MiniRoboDancer ★☆
()
Ответ на: комментарий от qrck

Помнишь часть имени

По окну NerdTREE спокойно можно искать. Если имя встречается только в содержимом — есть интегрированный в Vim аналог grep, который автоматом загружает в текущий буфер первый найденный файл и позволяет быстро переключаться к другим результатам. Не вижу проблемы.

Пример 1:
Пример 2:
Пример 3:
Пример 4:

С LINQPad мы уже разобрались, давайте дальше.

MiniRoboDancer ★☆
()
Ответ на: комментарий от MiniRoboDancer

Ну это Вы загнули... Тем более, всё от подхода к парсингу зависит, если не следовать тупо правилам построения грамматик, а задействовать смекалку, многие вещи можно заметно упростить.

Не говорите того, о чем не имеете представления. Парсинг C++ - это вещь, которая не по зубам даже компиляторам (до сих пор afaik нет ни одного компилятора с полной поддержкой C++11)

И об этом писал — без документации можно незаметно вляпаться в баг. Знание названия метода и типов параметров ещё ни о чём не говорит, особенно если либа производительная и в неё нет классообёрток для булей и интов на каждый чих.

Однако когда IDE может в 1 нажатие клавиши показать brief документации - это в разы ускоряет разработку.

на сложных вложенных конструкциях (простейший пример — экранированная кавычка внутри строки),

По вашему это предел синтаксической сложности??? Познакомьтесь с шаблонами C++ и с тем, как их например в boost используют.

:m,ns/someMethod()/object.someMethod()/g справится. И сделать команду, которая автоматом начало-конец класса определяет, если они внезапно не в разных файлах, тоже просто.

Опять мимо. Не справится, т.к. в методы с таким-же именем могут быть и у других классов, инстансы которых используются внутри текущего класса. Так что ваш рег-эксп только испортит код. Первое упрощение будет заменить это на :m,ns/\<someMethod()/object.someMethod()/g - но в общем случае это не будет работать все равно. Не говоря уже о том, что вместо того, что-бы нажать пару клавишь мыши, нужно будет написать regexp для каждого члена класса, переносимого в делегат, а их может быть штук 20 - 20 regexp-ов.

linqpad есть и отдельной утилитой. Причём, внезапно, бесплатно, в отличие от плагина для студии.

Во первых не бесплатно (http://www.linqpad.net/Purchase.aspx - бесплатная версия довольно убога, а Premium стоит $75), во вторых оно этого не умеет (AFAIK, или покажите где написано что оно это умеет вещи вроде примеров выше), в третьих вы обещали мне это в vim а не отдельной утилитой.

qrck ★★
()
Ответ на: комментарий от qrck

которая не по зубам даже компиляторам

То, что оно ещё нигде не реализовано, не значит, что оно нереализуемо и там кошмартрындец.

IDE может в 1 нажатие клавиши показать brief документации

Это и Vim может.

это предел

Я же написал — простейший пример. Читать умеете?

шаблонами C++

А там в чём проблема распарсить и растыкать?

у других классов

Тады точку перед именем надо проверять.

нужно будет написать regexp для каждого члена класса

Тады опять скриптуха, каждый выбрать и заменить.

бесплатная версия довольно убога

В Premium ничего полезного для CLI нету.

в vim а не отдельной утилитой

Дык это и есть интеграция в Vim — выделенный текст передаётся вызыванной команде и заменяется ею, юниксвей во все поля.

MiniRoboDancer ★☆
()
Ответ на: комментарий от MiniRoboDancer

То, что оно ещё нигде не реализовано, не значит, что оно нереализуемо и там кошмартрындец.

А вы попробуйте сами написать парсер для C++ кода, на досуге, ради интереса. Парсер C99 кода - подозреваю что любой студент изучающий грамматики осилит за лето. Синтаксис C++11, или даже C++03 - это штука с тысячами правил и тысячами-же особенностей их применения. Начиная банально с того, что стандарт языка C++11 насчитывает порядка 1300 страниц. Стандарт языка C99, если из него выкинуть описание стандартной библиотеки (которая непосредственно к синтаксису языка не имеет отношения) - останется 170 страниц. Выходит как раз на 1 порядок больше в плане описания. Сложность парсинга скорее всего будет более чем на 1 порядок выше, т.к. зависимость тут не линейная.

Это и Vim может.

Конфиг .vimrc в студию, что-бы оно мне показывало контекстно-зависимо документацию по методам, в зависимости от класса объекта, а еще бы умело понимать декларации вида

var a = createObjectA();
a.callSomeMethod();

и правильно переходить с «callSomeMethod» на документацию на метод именно того класса, что создается методом createObjectA(), а ни каким другим.

А там в чём проблема распарсить и растыкать?

«Вперед и с песней», когда напишете парсер для С++ шаблонов - приходите.

Тады точку перед именем надо проверять.

А так-же не забываем что может быть код написан как:

    getSomething(). 
         callSomething(). 
            callSomethingElse().
               printResult(); 

Ок, следующим вы скажете «тогда надо проверять игнорируя переносы строки»

тогда как вам это:

    getSomething() ->
         callSomething() -> 
            callSomethingElse() ->
               printResult(); 

Ок, добавляем еще проверку на '->' вместе с точкой, таков будет ваш следующий ответ, очевидно, тогда как вам это:

    this.getSomething(); 

или (C++)

    this->getSomething(); 

(такое часто встречается в повседневной жизни, хотя в случае с C# ReSharper всегда настойчиво предлагает от этого избавиться) - тут уже как ни проверяй точку, нужно знать еще что «а если точка и this, тогда надо тоже выносить». И таких примеров можно придумать много - всегда найдется заковырка синтаксиса, на которой в итоге споткнется скрипт самодельный, если он не разрабатывался с реализацией полного парсинга всего синтаксиса языка.

Дык это и есть интеграция в Vim — выделенный текст передаётся вызыванной команде и заменяется ею, юниксвей во все поля.

ОК, допустим так. Но как быть с примерами 1-4 выше приведенными - сливаетесь?

qrck ★★
()
Ответ на: комментарий от MiniRoboDancer

ЗЫ про синтаксис C++:

Сможете вы например по вот этому коду сказать, что это такое?:

x * y(z);

Ответ: не можете, т.к. в зависимости от контекста это может означать совершенно разные вещи:

int main() {
    int x, y(int), z;
    x * y(z);
}

vs

int main() {
    struct x { x(int) {} } *z;
    x * y(z);
}
qrck ★★
()
15 февраля 2015 г.
Ответ на: комментарий от qrck

с тысячами правил и тысячами-же особенностей их применения

Вот только для каждого конкретного метода рефакторинга все эти тысячи нафиг не нужны. При их систематизации совпадающие, конечно, желательно вынести в общую «библиотеку», но это не проблема.

в зависимости от класса объекта

YCM с расширениями для конкретных языков нечто подобное умеет, прикрутить к нему вместо дополнения документацию — и впердё.

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

Багрепорт -> фикс -> PROFIT. В чём проблема? Всякие рупы с вотерфолами, предполагающие детальную предварительную проработку продукта, уходят в прошлое, а академичность в успешной разработке ПО — вообще единичные случаи. Тем более, сами же говорите, что даже крупные продукты до сих пор все тонкости синтаксиса не покрыли.

Но как быть с примерами 1-4 выше приведенными

Скормить, прогнать и заменить.

MiniRoboDancer ★☆
()
Ответ на: комментарий от qrck

wut?

Какой чёткий, лаконичный, а главное, обстоятельный ответ! После такого не остаётся ничего иного, как молча слиться.

MiniRoboDancer ★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.