Jak skopiować jakiś tekst z jednego otwartego pliku do drugiego?

Dodaj w .vimrc:

if has("unix")
  nmap xr   :r $HOME/.vimxfer<CR>
  nmap xw   :'a,.w! $HOME/.vimxfer<CR>
  vmap xr   c<esc>:r $HOME/.vimxfer<CR>
  vmap xw   :w! $HOME/.vimxfer<CR>
else
  nmap xr   :r ~/.vimxfer<CR>
  nmap xw   :'a,.w! ~/.vimxfer<CR>
  vmap xr   c<esc>:r ~/.vimxfer<CR>
  vmap xw   :w! ~/.vimxfer<CR>
endif

Teraz, po zaznaczeniu tekstu, wciśnij ‘xw’ aby go zapisać, przejdź do pliku gdzie chcesz dany tekst wstawić, i wciśnij ‘xr’.

Teoretycznie, można używać po prostu kopiowania (yank) za pomocą komendy ‘y’, ale ma ona istotne ograniczenia:

  • pozwala na skopiowanie maksymalnie 50 linii
  • żeby działało, trzeba otworzyć plik z którego chcesz skopiować treść, zamknąć go, otworzyć drugi, wkleić (czy też operacje na buforachw jednym oknie etc. Metoda z ‘xr’ i ‘xw’ pozwala na przenoszenie treści pomiędzy zupełnie różnymi oknami (korzysta z zewnętrznego pliku).

Jak zmienić tekst/słowo/linię na pisane WIELKIMI literami lub na pisane małymi literami? Służy do tego komenda ‘U’ lub ‘u’.

Aby zmienić całą linię na pisaną wielkimi literami: gUU

Aby zmienić całą linię na pisaną małymi literami: guu

Aby zmienić słowo na pisane wielkimi literami: gUaw

Aby zmienić słowo na pisane małymi literami: guaw

Aby zmienić linię na pisaną duzymi literami poczynając od miejsca w którym stoi kursor: gU$

Etc…

Vim ułatwia też zamienianie wielkości liter z małych na duże i odwrotnie - służy do tego znak tyldy (~). Aby zmienić znak na którym stoi kursor, wystarczy wcisnąć tyldę. Aby zamienić wielkość liter na trzech najbliższych znakach, wciskamy: 3~. Reszta - j.w.

Wszystkie polecenie wykonujemy w trybie komend.


W wielu edytorach tekstu mamy możliwość zaznaczenia pewnej linii, i skoku do niej w dowolnym momencie. Vim także posiada taką możliwość.

Oznaczanie linii (mark) wykonuje się poprzez komendę (zaskakujące) ‘mark’ lub w skrócie ‘m’. W linii, której chcesz zaznaczyć, wyjdź do trybu poleceń (<Esc>:), wprowadź ‘mX’, gdzie X jest kolejną małą literą alfabetu (nazwą naszego oznaczenia). Teraz, zeby znaleźć się w oznaczonej linii, w trybie komend wciskamy ‘X (najpierw apostrof, a później nazwę oznaczenia do którego chcemy przejść. A jeśli chcemy się przenieść dodkładnie do miejsca naszego oznaczenia (oznaczona kolumna) wprowadzamy `X (gdzie ` jest znakiem nad tyldą “~”, a X - nazwą oznaczenia).


Stanąłem dziś przed takim dylematem: chciałem utworzyć listę obiektów (każdy obiekt to konkretny wpis w bazie danych). No OK, samo utworzenie listy to niewielki problem. Problemem jest to, że w całej aplikacji używam dość zaawansowanych “ułatwiaczy”: przeładowywanie __isset(), __unset(), __set() i __get(). Np. mam obiekt $p, instancję klasy Post. Ma on różne własności, np tytuł (Post::$title), treść (Post::$body). Dostęp do nich jest za pomocą przeładowanych metod __set() i __get(), co pozwala mi na zautomatyzowanie kilku rzeczy - jak na przykład niewidoczną dla programisty zamianę znaków nowej linii na HTMLowe znaczniki <br />. Ale ja nie o tym miałem…

Chciałem zachować naturalność rozwiązań także w klasie agregującej obiekty Post. Czyli potraktować de facto obiektu agregatu (który ma kilka zadań, jak np utworzenie tej listy obiektów) jako tablicy. Tworząc instancję klasy, chcę mu zapodać: utwórz listę wpisów z kategorii o ID = 2, obiektów ma być 30. No i z tego korzystać. Mogę oczywiście dać sobie dostęp do jednej z własności tegoż obiektu-agregatu, która będzie tablicą i zawierać w sobie będzie wszystkie pobrane wpisy. Ale czy wspominałem coś o naturalności rozwiązań? :)

PHP 5 dostarcza nam coś, co nazywa się SPL, czyli Standard PHP Library. Jedną z klas (a konkretnie intefejsów) modułu SPL jest ArrayAccess.

Aby tego użyć, należy zadeklarować klasę jako implementującą z tego interfejsu:

class Aggregate implements ArrayAccess {}

A w niej trzeba zaimplementować 4 metody: offsetExists($offset), offsetGet($offset), offsetSet($offset, $value), offsetUnset($offset).

Przykład tego, jak powinna wyglądać cała klasa:

class Aggregate implements ArrayAccess
{
    private $data = array();

    public function __construct($array=null)
    {
        if (!is_null($array)) {
            $this->data = $array;
        }
    }

    public function offsetExists($offset)
    {
        return array_key_exists($offset, $this->data);
    }

    public function offsetGet($offset)
    {
        return $this->data[$offset];
    }

    public function offsetSet($offset, $value)
    {
        $this->data[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        unset($this->data[$offset]);
    }
}

Do tego przydałby się prosty sposób na sprawdzenie liczby obiektów które są na liście (kazaliśmy pobrać 30, ale to jest ilość maksymalna - w bazie danych może być ich mniej). Wykonamy to poprzez interfejs Countable i metodę count(). Nagłówek naszej klasy zmieniamy na taki:

class Aggregate implements ArrayAccess, Countable

I dodajemy metodę count():

    public function count()
    {
        return count($this->data);
    }

Żeby poczuć się jakbyśmy pracowali z prawdziwą tablicą, brakuje nam jeszcze możliwości iteracji po poszczególnych elementach tablicy. Do tego trzeba zaimplementować interfejs Iterator. Do listy implementowanych interfejsów dodajemy Iterator:

class Aggregate implements ArrayAccess, Countable, Iterator

I implementujemy jego metody:

    public function current()
    {
        return current($this->data);
    }

    public function key()
    {
        return key($this->data);
    }

    public function next()
    {
        return next($this->data);
    }

    public function rewind()
    {
        return reset($this->data);
    }

    public function valid()
    {
        return current($this->data);
    }

Od tego momentu możemy każdą instancję klasy Aggregate traktować jak tablicę. Pobieramy dowolny element tak jak z normalnej tablicy: $aggregate[2], tak samo zmieniać jego zawartosć: $aggregate[2] = ’something’;, iterować za pomocą foreach() {}, usuwać elementy za pomocą unset() etc. Jedyne czego nie osiągnęłem, ale też specjalnie nie próbowałem, to dodawać elementów za pomocą notacji []. Ale myślę że w większości zastosowań nie jest to potrzebne.

Cała, działająca klasa wraz z przykładem użycia: urzenia.net/wp-content/class_aggregate.php.

UPDATE:
Udoskonalona wersja klasy, odporna na błąd z metody valid (), a także pozwalająca na dodawanie kolejnych elementów tablicy PHPowym idiomem $aggregate[] = ‘wartosc’ znajduje się pod adresem: urzenia.net/wp-content/class_aggregate_new.php.


Używam w moim .vimrc opcji zawijania długich linii (ale nie łamania ich). Przechodzenie w tym trybie między poszczególnymi liniami jest traktowane dosłownie: jeśli zawinięta linia zajmuje na ekranie 5 linii, przejście do następnej jest traktowane jako przejście za najbliższy znak końca linii (czyli wizualnie 5 linii). Przechodzenie między liniami tak jak w programach Windowsowych (czyli po jednej ‘wizualnej’ linii) rozwiązuje się poprzez wciśnięcie kolejno: gj (linia niżej) lub gk (linia wyżej). Aby kazać tak zachowywac się kursorom, możemy do naszego .vimrc wstawić:

nnoremap <Down> gj
nnoremap <Up> gk
vnoremap <Down> gj
vnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk

Czemu używam Linuksa, czyli usuwanie skrótu z pulpitu w 7 prostych krokach.

BTW, jakby ktoś nie wiedział co znaczy Vista:

V
Viruses
I
Infections
S
Spyware
T
Trojans
A
Adware

Od jakiegoś czasu, w sumie już ładnych kilka tygodni, próbowałem używać (t.j. używałem) Eclipse do tworzenia kodu PHP, jak i do ogólnego zarządzania projektem. Na początku było to dość przyjemne. Prosty dostęp do wszystkich plików projektu, praca na zakładkach, podpowiadanie kodu… Ale po kilku tygodniach, powiedziałem sobie: DOŚĆ. Nie będę się dłużej męczył…

Co mi przeszkadza? Po kolei:

podpowiadanie kodu
Jest do bani. Odwołuję się do obiektu $tpl->, a on popowiada mi metody i własności wszystkich obiektów w całym projekcie! Do dupy z takim podpowiadaniem kodu. Wole zajrzeć do definicji klasy i sprawdzić jak się dana metody/własność nazywała, o ile nie pamiętam. De facto wyszło tak, że w ogóle z tej opcji (tj. podpowiadania kodu) nie korzystałem.
zakładki
Fajnie, że pokazuje na górze (lub jeśli ktoś tak woli, to na dole) listę otwartych i edytowanych plików. Przy otwartych dwóch lub trzech jest super. Ale po otworzeniu kilkunastu plików, praca z nimi to sajgon. Na liście na górze pojawiają się tylko ostatnio edytowane, pozostałe są ukryte, ciężko mi się między nimi przełączać za pomocą klawiatury (skrót klawiszowy znam, gorzej że musiałbym pamiętać w jakiej kolejności je ostatnio edytowałem żeby to miało sens).
folding (zawijanie) kodu
Działa tylko dla funkcji, metod i klas. Nie działa dla normalnych bloków kodu, jak ciała warunków, pętli etc. Nie można też ręcznie zdefiniować zwinięcia, żeby ukryć ten fragment kodu który mnie w danej chwili nie interesuje. Nie można też zaznaczyć kilku zwiniętych funkcji, skopiować/wyciąć i wkleić gdzie indziej - kopiuje się tylko pokazywana na ekranie część, a o co zwinięte nie jest uwzględniane. Nie dość tego, bo to jak na razie mały pikuś: pracowałem dziś, i nagle z pliku znikło mi kilkanaście metod! Szukałem przez chwilę, w końcu się wystraszyłem że niechcący skasowałem je… Ale system cały czas działa. Co się okazało? Eclipse zapomniał je wyświetlić.. Dopiero jak wyszukałem wszystkie wystąpienia słowa function w pliku, to okazało się że te definicje są, tylko nie są wyświetlane. Dosłownie. Nawet liczba linii w pliku była pokazywana mniejsza, tak jakby tych definicji de facto tam nie było. Koszmar.
siermiężność
Java jak to java. Do demonów szybkości nie należy. Co tu więcej pisać…
trochę innych
tutaj wchodzi kiepska obsługa SVN, mała liczba zapamiętywanych poziomów undo (zwiększanie parametru w opcjach niewiele daje), problemy z zapamiętaniem przez Eclipse że chcę używać 2 spacji jako wcięć (namiętnie używa znaków tabulacji, o długości 4 lub 8 znaków, zależy od jego nastroju) etc. W sumie: środowisko jest do dupy.

Żeby nie było nieporozumień: używam (-łem) Eclipse w najnowszej wersji, z najnowszą wersją PHP Eclipse, z najnowszą wersją Javy, wszystko ściągnięte ze stron twórców - bynajmniej nie są to własne spieprzone kompilaty, czy też jakieś niedopracowania developerów mojego distro. Po prostu, to środowisko może się nadaje do Javy, ale do PHP niezbyt.

Nie da się ukryć, że jak na razie najlepszym dla mnie edytorem jest Vim, szczególnie od momentu wprowadzenia możliwości pracy z zakładkami/kartami. Brakuje mi w nim tylko brak osługi projektów. Ale może jest do niego jakiś plugin, który by to zgrabnie umożliwiał. Będę musiał poszukać. I go przeprosić…


Mało kto wie, że funkcji z pakietu ob_* można użyć na przykład do konwersji z jednego kodowania do drugiego (np. strona de facto zapisana w ISO-8859-2 może pójść do przeglądarki jako UTF-8), albo do automatycznej kompresji za pomocą gzip, o ile przeglądarka wspiera tą metodę.

Do zmiany strony kodowej, oprócz funkcji z pakietu ob_* potrzebujemy rozszerzenia albo iconv, albo mb. Najpierw trzeba zdefiniować, z jakiego kodowania chcemy “tłumaczyć”:

iconv_set_encoding('internal_encoding', $enc_from); //jeśli korzystamy z iconv
mb_internal_encoding($enc_from); //jeśli korzystamy z mbstring

gdzie $enc_from może być np. “ISO-8859-2″ (lista obsługiwanych kodowań na stronie PHP (dla mbstring) lub na stronie biblioteki iconv (dla iconv).

Nastepnym krokiem jest zdefiniowanie kodowania wyjściowego:

iconv_set_encoding('output_encoding', $enc_to); //dla iconv
mb_http_output($enc_to); //dla mbstring

gdzie $enc_to w naszym przykładzie to “UTF-8″.

Teraz pozostaje tylko na początku strony wstawić instrukcję uruchamiającą buforowanie wyjścia:

ob_start('ob_iconv_handler'); //w przypadku iconv
ob_start('mb_output_handler'); //gdy używamy mbstring

I już możemy się cieszyć zmienionym kodowaniem danej strony :)

Uruchomienie kompresji jest równie proste, trzeba tylko pamiętać aby był załadowany moduł zlib. Samo uruchomienie kompresji to podanie funkcji ob_start() odpowiedniego parametru:

ob_start('ob_gzhandler');

Za pomocą instrukcji ini_set() możemy ustawić także stopień kompresji:

ini_set('zlib.compresss_level', $comp_level);

gdzie $comp_level jest to liczba całkowita z zakresu od 0 do 9 (domyślnie 6).

Pozostaje jeszcze tylko jeden problem: jak połączyć razem konwersję z jednego kodowania na drugie wraz z kompresją? Proszę:

ob_start(array('ob_gzhandler', 'ob_iconv_handler'));

Ważna powyżej jest kolejność parametrów podawanych w tablicy: gdy podasz je w odwrotnej kolejności, nie będzie działać kompresja.


Strona 1 z 2